Commit e1d1ea54 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'fbdev-v4.15' of git://github.com/bzolnier/linux

Pull fbdev updates from Bartlomiej Zolnierkiewicz:
 "There is nothing really major here (though removal of the dead igafb
  driver stands out in diffstat).

  Summary:

   - convert timers to use timer_setup() (Kees Cook, Thierry Reding)

   - fix panels support on iMX boards in mxsfb driver (Stefan Agner)

   - fix timeout on EDID read in udlfb driver (Ladislav Michl)

   - add missing modes to fix out of bounds access in controlfb driver
     (Geert Uytterhoeven)

   - update initialisation paths in sa1100fb driver to be more robust
     (Russell King)

   - fix error handling path of ->probe method in au1200fb driver
     (Christophe JAILLET)

   - fix handling of cases when either panel or crt is defined in
     sm501fb driver (Sudip Mukherjee, Colin Ian King)

   - add ability to the Goldfish FB driver to be recognized by OS via DT
     (Aleksandar Markovic)

   - structures constifications (Bhumika Goyal)

   - misc fixes (Allen Pais, Gustavo A. R. Silva, Dan Carpenter)

   - misc cleanups (Colin Ian King, Himanshu Jha, Markus Elfring)

   - remove dead igafb driver"

* tag 'fbdev-v4.15' of git://github.com/bzolnier/linux: (42 commits)
  OMAPFB: prevent buffer underflow in omapfb_parse_vram_param()
  video: fbdev: sm501fb: fix potential null pointer dereference on fbi
  fbcon: Initialize ops->info early
  video: fbdev: Convert timers to use timer_setup()
  video: fbdev: pxa3xx_gcu: Convert timers to use timer_setup()
  fbdev: controlfb: Add missing modes to fix out of bounds access
  video: fbdev: sis_main: mark expected switch fall-throughs
  video: fbdev: cirrusfb: mark expected switch fall-throughs
  video: fbdev: aty: radeon_pm: mark expected switch fall-throughs
  video: fbdev: sm501fb: mark expected switch fall-through in sm501fb_blank_crt
  video: fbdev: intelfb: remove redundant variables
  video/fbdev/dnfb: Use common error handling code in dnfb_probe()
  sm501fb: suspend and resume fb if it exists
  sm501fb: unregister framebuffer only if registered
  sm501fb: deallocate colormap only if allocated
  video: goldfishfb: Add support for device tree bindings
  Documentation: Add device tree binding for Goldfish FB driver
  video: udlfb: Fix read EDID timeout
  video: fbdev: remove dead igafb driver
  video: fbdev: mxsfb: fix pixelclock polarity
  ...
parents c633e898 5f215d25
Android Goldfish framebuffer
Android Goldfish framebuffer device used by Android emulator.
Required properties:
- compatible : should contain "google,goldfish-fb"
- reg : <registers mapping>
- interrupts : <interrupt mapping>
Example:
display-controller@1f008000 {
compatible = "google,goldfish-fb";
interrupts = <0x10>;
reg = <0x1f008000 0x100>;
};
......@@ -905,16 +905,6 @@ config FB_LEO
This is the frame buffer device driver for the SBUS-based Sun ZX
(leo) frame buffer cards.
config FB_IGA
bool "IGA 168x display support"
depends on (FB = y) && SPARC32
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
help
This is the framebuffer device for the INTERGRAPHICS 1680 and
successor frame buffer cards.
config FB_XVR500
bool "Sun XVR-500 3DLABS Wildcat support"
depends on (FB = y) && PCI && SPARC64
......
......@@ -65,7 +65,6 @@ obj-$(CONFIG_FB_HGA) += hgafb.o
obj-$(CONFIG_FB_XVR500) += sunxvr500.o
obj-$(CONFIG_FB_XVR2500) += sunxvr2500.o
obj-$(CONFIG_FB_XVR1000) += sunxvr1000.o
obj-$(CONFIG_FB_IGA) += igafb.o
obj-$(CONFIG_FB_APOLLO) += dnfb.o
obj-$(CONFIG_FB_Q40) += q40fb.o
obj-$(CONFIG_FB_TGA) += tgafb.o
......
......@@ -2272,10 +2272,10 @@ static void aty_bl_exit(struct backlight_device *bd)
static void aty_calc_mem_refresh(struct atyfb_par *par, int xclk)
{
const int ragepro_tbl[] = {
static const int ragepro_tbl[] = {
44, 50, 55, 66, 75, 80, 100
};
const int ragexl_tbl[] = {
static const int ragexl_tbl[] = {
50, 66, 75, 83, 90, 95, 100, 105,
110, 115, 120, 125, 133, 143, 166
};
......
......@@ -1454,9 +1454,9 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg
/*
* Timer function for delayed LVDS panel power up/down
*/
static void radeon_lvds_timer_func(unsigned long data)
static void radeon_lvds_timer_func(struct timer_list *t)
{
struct radeonfb_info *rinfo = (struct radeonfb_info *)data;
struct radeonfb_info *rinfo = from_timer(rinfo, t, lvds_timer);
radeon_engine_idle();
......@@ -1534,7 +1534,7 @@ void radeon_write_mode (struct radeonfb_info *rinfo, struct radeon_regs *mode,
static void radeon_calc_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *regs,
unsigned long freq)
{
const struct {
static const struct {
int divider;
int bitvalue;
} *post_div,
......@@ -2291,9 +2291,7 @@ static int radeonfb_pci_register(struct pci_dev *pdev,
rinfo->pdev = pdev;
spin_lock_init(&rinfo->reg_lock);
init_timer(&rinfo->lvds_timer);
rinfo->lvds_timer.function = radeon_lvds_timer_func;
rinfo->lvds_timer.data = (unsigned long)rinfo;
timer_setup(&rinfo->lvds_timer, radeon_lvds_timer_func, 0);
c1 = ent->device >> 8;
c2 = ent->device & 0xff;
......
......@@ -1208,9 +1208,11 @@ static void radeon_pm_enable_dll_m10(struct radeonfb_info *rinfo)
case 1:
if (mc & 0x4)
break;
/* fall through */
case 2:
dll_sleep_mask |= MDLL_R300_RDCK__MRDCKB_SLEEP;
dll_reset_mask |= MDLL_R300_RDCK__MRDCKB_RESET;
/* fall through */
case 0:
dll_sleep_mask |= MDLL_R300_RDCK__MRDCKA_SLEEP;
dll_reset_mask |= MDLL_R300_RDCK__MRDCKA_RESET;
......@@ -1219,6 +1221,7 @@ static void radeon_pm_enable_dll_m10(struct radeonfb_info *rinfo)
case 1:
if (!(mc & 0x4))
break;
/* fall through */
case 2:
dll_sleep_mask |= MDLL_R300_RDCK__MRDCKD_SLEEP;
dll_reset_mask |= MDLL_R300_RDCK__MRDCKD_RESET;
......
......@@ -1518,7 +1518,7 @@ static irqreturn_t au1200fb_handle_irq(int irq, void* dev_id)
static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
{
struct fb_info *fbi = fbdev->fb_info;
int bpp;
int bpp, ret;
fbi->fbops = &au1200fb_fb_ops;
......@@ -1546,15 +1546,14 @@ static int au1200fb_init_fbinfo(struct au1200fb_device *fbdev)
}
fbi->pseudo_palette = kcalloc(16, sizeof(u32), GFP_KERNEL);
if (!fbi->pseudo_palette) {
if (!fbi->pseudo_palette)
return -ENOMEM;
}
if (fb_alloc_cmap(&fbi->cmap, AU1200_LCD_NBR_PALETTE_ENTRIES, 0) < 0) {
ret = fb_alloc_cmap(&fbi->cmap, AU1200_LCD_NBR_PALETTE_ENTRIES, 0);
if (ret < 0) {
print_err("Fail to allocate colormap (%d entries)",
AU1200_LCD_NBR_PALETTE_ENTRIES);
kfree(fbi->pseudo_palette);
return -EFAULT;
AU1200_LCD_NBR_PALETTE_ENTRIES);
return ret;
}
strncpy(fbi->fix.id, "AU1200", sizeof(fbi->fix.id));
......@@ -1668,10 +1667,6 @@ static int au1200fb_drv_probe(struct platform_device *dev)
printk(DRIVER_NAME ": Panel %d %s\n", panel_index, panel->name);
printk(DRIVER_NAME ": Win %d %s\n", window_index, win->name);
/* shut gcc up */
ret = 0;
fbdev = NULL;
for (plane = 0; plane < device_count; ++plane) {
bpp = winbpp(win->w[plane].mode_winctrl1);
if (win->w[plane].xres == 0)
......@@ -1681,8 +1676,10 @@ static int au1200fb_drv_probe(struct platform_device *dev)
fbi = framebuffer_alloc(sizeof(struct au1200fb_device),
&dev->dev);
if (!fbi)
if (!fbi) {
ret = -ENOMEM;
goto failed;
}
_au1200fb_infos[plane] = fbi;
fbdev = fbi->par;
......@@ -1701,7 +1698,8 @@ static int au1200fb_drv_probe(struct platform_device *dev)
if (!fbdev->fb_mem) {
print_err("fail to allocate frambuffer (size: %dK))",
fbdev->fb_len / 1024);
return -ENOMEM;
ret = -ENOMEM;
goto failed;
}
/*
......@@ -1718,7 +1716,8 @@ static int au1200fb_drv_probe(struct platform_device *dev)
print_dbg("phys=0x%08x, size=%dK", fbdev->fb_phys, fbdev->fb_len / 1024);
/* Init FB data */
if ((ret = au1200fb_init_fbinfo(fbdev)) < 0)
ret = au1200fb_init_fbinfo(fbdev);
if (ret < 0)
goto failed;
/* Register new framebuffer */
......@@ -1758,21 +1757,26 @@ static int au1200fb_drv_probe(struct platform_device *dev)
return 0;
failed:
/* NOTE: This only does the current plane/window that failed; others are still active */
if (fbi) {
for (plane = 0; plane < device_count; ++plane) {
fbi = _au1200fb_infos[plane];
if (!fbi)
break;
/* Clean up all probe data */
unregister_framebuffer(fbi);
if (fbi->cmap.len != 0)
fb_dealloc_cmap(&fbi->cmap);
kfree(fbi->pseudo_palette);
framebuffer_release(fbi);
_au1200fb_infos[plane] = NULL;
}
if (plane == 0)
free_irq(AU1200_LCD_INT, (void*)dev);
return ret;
}
static int au1200fb_drv_remove(struct platform_device *dev)
{
struct au1200fb_platdata *pd = platform_get_drvdata(dev);
struct au1200fb_device *fbdev;
struct fb_info *fbi;
int plane;
......@@ -1781,7 +1785,6 @@ static int au1200fb_drv_remove(struct platform_device *dev)
for (plane = 0; plane < device_count; ++plane) {
fbi = _au1200fb_infos[plane];
fbdev = fbi->par;
/* Clean up all probe data */
unregister_framebuffer(fbi);
......
......@@ -1477,10 +1477,12 @@ static void init_vgachip(struct fb_info *info)
mdelay(100);
/* mode */
vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
case BT_GD5480: /* fall through */
/* fall through */
case BT_GD5480:
/* from Klaus' NetBSD driver: */
vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
case BT_ALPINE: /* fall through */
/* fall through */
case BT_ALPINE:
/* put blitter into 542x compat */
vga_wgfx(cinfo->regbase, CL_GR33, 0x00);
break;
......
......@@ -141,5 +141,7 @@ static struct max_cmodes control_mac_modes[] = {
{{ 1, 2}}, /* 1152x870, 75Hz */
{{ 0, 1}}, /* 1280x960, 75Hz */
{{ 0, 1}}, /* 1280x1024, 75Hz */
{{ 1, 2}}, /* 1152x768, 60Hz */
{{ 0, 1}}, /* 1600x1024, 60Hz */
};
......@@ -395,10 +395,10 @@ static void fb_flashcursor(struct work_struct *work)
console_unlock();
}
static void cursor_timer_handler(unsigned long dev_addr)
static void cursor_timer_handler(struct timer_list *t)
{
struct fb_info *info = (struct fb_info *) dev_addr;
struct fbcon_ops *ops = info->fbcon_par;
struct fbcon_ops *ops = from_timer(ops, t, cursor_timer);
struct fb_info *info = ops->info;
queue_work(system_power_efficient_wq, &info->queue);
mod_timer(&ops->cursor_timer, jiffies + ops->cur_blink_jiffies);
......@@ -414,8 +414,7 @@ static void fbcon_add_cursor_timer(struct fb_info *info)
if (!info->queue.func)
INIT_WORK(&info->queue, fb_flashcursor);
setup_timer(&ops->cursor_timer, cursor_timer_handler,
(unsigned long) info);
timer_setup(&ops->cursor_timer, cursor_timer_handler, 0);
mod_timer(&ops->cursor_timer, jiffies + ops->cur_blink_jiffies);
ops->flags |= FBCON_FLAGS_CURSOR_TIMER;
}
......@@ -714,6 +713,7 @@ static int con2fb_acquire_newinfo(struct vc_data *vc, struct fb_info *info,
if (!err) {
ops->cur_blink_jiffies = HZ / 5;
ops->info = info;
info->fbcon_par = ops;
if (vc)
......@@ -962,6 +962,7 @@ static const char *fbcon_startup(void)
ops->graphics = 1;
ops->cur_rotate = -1;
ops->cur_blink_jiffies = HZ / 5;
ops->info = info;
info->fbcon_par = ops;
if (initial_rotation != -1)
p->con_rotate = initial_rotation;
......
......@@ -69,6 +69,7 @@ struct fbcon_ops {
struct timer_list cursor_timer; /* Cursor timer */
struct fb_cursor cursor_state;
struct display *p;
struct fb_info *info;
int currcon; /* Current VC. */
int cur_blink_jiffies;
int cursor_flash;
......
......@@ -115,7 +115,7 @@ static struct fb_ops dn_fb_ops = {
.fb_imageblit = cfb_imageblit,
};
struct fb_var_screeninfo dnfb_var = {
static const struct fb_var_screeninfo dnfb_var = {
.xres = 1280,
.yres = 1024,
.xres_virtual = 2048,
......@@ -242,16 +242,13 @@ static int dnfb_probe(struct platform_device *dev)
info->screen_base = (u_char *) info->fix.smem_start;
err = fb_alloc_cmap(&info->cmap, 2, 0);
if (err < 0) {
framebuffer_release(info);
return err;
}
if (err < 0)
goto release_framebuffer;
err = register_framebuffer(info);
if (err < 0) {
fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
return err;
goto release_framebuffer;
}
platform_set_drvdata(dev, info);
......@@ -265,6 +262,10 @@ static int dnfb_probe(struct platform_device *dev)
printk("apollo frame buffer alive and kicking !\n");
return err;
release_framebuffer:
framebuffer_release(info);
return err;
}
static struct platform_driver dnfb_driver = {
......
......@@ -304,12 +304,18 @@ static int goldfish_fb_remove(struct platform_device *pdev)
return 0;
}
static const struct of_device_id goldfish_fb_of_match[] = {
{ .compatible = "google,goldfish-fb", },
{},
};
MODULE_DEVICE_TABLE(of, goldfish_fb_of_match);
static struct platform_driver goldfish_fb_driver = {
.probe = goldfish_fb_probe,
.remove = goldfish_fb_remove,
.driver = {
.name = "goldfish_fb"
.name = "goldfish_fb",
.of_match_table = goldfish_fb_of_match,
}
};
......
This diff is collapsed.
......@@ -937,15 +937,11 @@ static int calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2,
{
u32 m1, m2, n, p1, p2, n1, testm;
u32 f_vco, p, p_best = 0, m, f_out = 0;
u32 err_max, err_target, err_best = 10000000;
u32 n_best = 0, m_best = 0, f_best, f_err;
u32 err_best = 10000000;
u32 n_best = 0, m_best = 0, f_err;
u32 p_min, p_max, p_inc, div_max;
struct pll_min_max *pll = &plls[index];
/* Accept 0.5% difference, but aim for 0.1% */
err_max = 5 * clock / 1000;
err_target = clock / 1000;
DBG_MSG("Clock is %d\n", clock);
div_max = pll->max_vco / clock;
......@@ -992,7 +988,6 @@ static int calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2,
m_best = testm;
n_best = n;
p_best = p;
f_best = f_out;
err_best = f_err;
}
}
......
......@@ -2056,7 +2056,7 @@ static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dumm
minfo = kzalloc(sizeof(*minfo), GFP_KERNEL);
if (!minfo)
return -1;
return -ENOMEM;
minfo->pcidev = pdev;
minfo->dead = 0;
......
......@@ -150,7 +150,7 @@
#define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */
#define MXSFB_SYNC_DATA_ENABLE_HIGH_ACT (1 << 6)
#define MXSFB_SYNC_DOTCLK_FALLING_ACT (1 << 7) /* negtive edge sampling */
#define MXSFB_SYNC_DOTCLK_FALLING_ACT (1 << 7) /* negative edge sampling */
enum mxsfb_devtype {
MXSFB_V3,
......@@ -788,7 +788,16 @@ static int mxsfb_init_fbinfo_dt(struct mxsfb_info *host,
if (vm.flags & DISPLAY_FLAGS_DE_HIGH)
host->sync |= MXSFB_SYNC_DATA_ENABLE_HIGH_ACT;
if (vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
/*
* The PIXDATA flags of the display_flags enum are controller
* centric, e.g. NEGEDGE means drive data on negative edge.
* However, the drivers flag is display centric: Sample the
* data on negative (falling) edge. Therefore, check for the
* POSEDGE flag:
* drive on positive edge => sample on negative edge
*/
if (vm.flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
host->sync |= MXSFB_SYNC_DOTCLK_FALLING_ACT;
put_display_node:
......
......@@ -474,7 +474,7 @@ static void auto_update_complete(void *data)
jiffies + HWA742_AUTO_UPDATE_TIME);
}
static void hwa742_update_window_auto(unsigned long arg)
static void hwa742_update_window_auto(struct timer_list *unused)
{
LIST_HEAD(req_list);
struct hwa742_request *last;
......@@ -1002,9 +1002,7 @@ static int hwa742_init(struct omapfb_device *fbdev, int ext_mode,
hwa742.auto_update_window.height = fbdev->panel->y_res;
hwa742.auto_update_window.format = 0;
init_timer(&hwa742.auto_update_timer);
hwa742.auto_update_timer.function = hwa742_update_window_auto;
hwa742.auto_update_timer.data = 0;
timer_setup(&hwa742.auto_update_timer, hwa742_update_window_auto, 0);
hwa742.prev_color_mode = -1;
hwa742.prev_flags = 0;
......
......@@ -3988,7 +3988,7 @@ static void dsi_update_screen_dispc(struct platform_device *dsidev)
}
#ifdef DSI_CATCH_MISSING_TE
static void dsi_te_timeout(unsigned long arg)
static void dsi_te_timeout(struct timer_list *unused)
{
DSSERR("TE not received for 250ms!\n");
}
......@@ -5298,9 +5298,7 @@ static int dsi_bind(struct device *dev, struct device *master, void *data)
dsi_framedone_timeout_work_callback);
#ifdef DSI_CATCH_MISSING_TE
init_timer(&dsi->te_timer);
dsi->te_timer.function = dsi_te_timeout;
dsi->te_timer.data = 0;
timer_setup(&dsi->te_timer, dsi_te_timeout, 0);
#endif
res = platform_get_resource_byname(dsidev, IORESOURCE_MEM, "proto");
......
......@@ -1477,7 +1477,7 @@ static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size,
static int omapfb_parse_vram_param(const char *param, int max_entries,
unsigned long *sizes, unsigned long *paddrs)
{
int fbnum;
unsigned int fbnum;
unsigned long size;
unsigned long paddr = 0;
char *p, *start;
......
......@@ -512,28 +512,26 @@ pxa3xx_gcu_mmap(struct file *file, struct vm_area_struct *vma)
#ifdef PXA3XX_GCU_DEBUG_TIMER
static struct timer_list pxa3xx_gcu_debug_timer;
static struct pxa3xx_gcu_priv *debug_timer_priv;
static void pxa3xx_gcu_debug_timedout(unsigned long ptr)
static void pxa3xx_gcu_debug_timedout(struct timer_list *unused)
{
struct pxa3xx_gcu_priv *priv = (struct pxa3xx_gcu_priv *) ptr;
struct pxa3xx_gcu_priv *priv = debug_timer_priv;
QERROR("Timer DUMP");
/* init the timer structure */
init_timer(&pxa3xx_gcu_debug_timer);
pxa3xx_gcu_debug_timer.function = pxa3xx_gcu_debug_timedout;
pxa3xx_gcu_debug_timer.data = ptr;
pxa3xx_gcu_debug_timer.expires = jiffies + 5*HZ; /* one second */
add_timer(&pxa3xx_gcu_debug_timer);
mod_timer(&pxa3xx_gcu_debug_timer, jiffies + 5 * HZ);
}
static void pxa3xx_gcu_init_debug_timer(void)
static void pxa3xx_gcu_init_debug_timer(struct pxa3xx_gcu_priv *priv)
{
pxa3xx_gcu_debug_timedout((unsigned long) &pxa3xx_gcu_debug_timer);
/* init the timer structure */
debug_timer_priv = priv;
timer_setup(&pxa3xx_gcu_debug_timer, pxa3xx_gcu_debug_timedout, 0);
pxa3xx_gcu_debug_timedout(NULL);
}
#else
static inline void pxa3xx_gcu_init_debug_timer(void) {}
static inline void pxa3xx_gcu_init_debug_timer(struct pxa3xx_gcu_priv *priv) {}
#endif
static int
......@@ -670,7 +668,7 @@ static int pxa3xx_gcu_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, priv);
priv->resource_mem = r;
pxa3xx_gcu_reset(priv);
pxa3xx_gcu_init_debug_timer();
pxa3xx_gcu_init_debug_timer(priv);
dev_info(dev, "registered @0x%p, DMA 0x%p (%d bytes), IRQ %d\n",
(void *) r->start, (void *) priv->shared_phys,
......
......@@ -323,13 +323,11 @@ sa1100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
* according to the RGB bitfield information.
*/
if (regno < 16) {
u32 *pal = fbi->fb.pseudo_palette;
val = chan_to_field(red, &fbi->fb.var.red);
val |= chan_to_field(green, &fbi->fb.var.green);
val |= chan_to_field(blue, &fbi->fb.var.blue);
pal[regno] = val;
fbi->pseudo_palette[regno] = val;
ret = 0;
}
break;
......@@ -1132,12 +1130,10 @@ static struct sa1100fb_info *sa1100fb_init_fbinfo(struct device *dev)
struct sa1100fb_info *fbi;
unsigned i;
fbi = kmalloc(sizeof(struct sa1100fb_info) + sizeof(u32) * 16,
GFP_KERNEL);
fbi = devm_kzalloc(dev, sizeof(struct sa1100fb_info), GFP_KERNEL);
if (!fbi)
return NULL;
memset(fbi, 0, sizeof(struct sa1100fb_info));
fbi->dev = dev;
strcpy(fbi->fb.fix.id, SA1100_NAME);
......@@ -1159,7 +1155,7 @@ static struct sa1100fb_info *sa1100fb_init_fbinfo(struct device *dev)
fbi->fb.fbops = &sa1100fb_ops;
fbi->fb.flags = FBINFO_DEFAULT;
fbi->fb.monspecs = monspecs;
fbi->fb.pseudo_palette = (fbi + 1);
fbi->fb.pseudo_palette = fbi->pseudo_palette;
fbi->rgb[RGB_4] = &rgb_4;
fbi->rgb[RGB_8] = &rgb_8;
......@@ -1218,48 +1214,42 @@ static int sa1100fb_probe(struct platform_device *pdev)
return -EINVAL;
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
irq = platform_get_irq(pdev, 0);
if (irq < 0 || !res)
if (irq < 0)
return -EINVAL;
if (!request_mem_region(res->start, resource_size(res), "LCD"))
return -EBUSY;
fbi = sa1100fb_init_fbinfo(&pdev->dev);
ret = -ENOMEM;
if (!fbi)
goto failed;
fbi->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(fbi->clk)) {
ret = PTR_ERR(fbi->clk);
fbi->clk = NULL;
goto failed;
}
return -ENOMEM;
fbi->base = ioremap(res->start, resource_size(res));
if (!fbi->base)
goto failed;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
fbi->base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(fbi->base))
return PTR_ERR(fbi->base);
/* Initialize video memory */
ret = sa1100fb_map_video_memory(fbi);
if (ret)
goto failed;
fbi->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(fbi->clk))
return PTR_ERR(fbi->clk);
ret = request_irq(irq, sa1100fb_handle_irq, 0, "LCD", fbi);
ret = devm_request_irq(&pdev->dev, irq, sa1100fb_handle_irq, 0,
"LCD", fbi);
if (ret) {
dev_err(&pdev->dev, "request_irq failed: %d\n", ret);
goto failed;
return ret;
}
if (machine_is_shannon()) {
ret = gpio_request_one(SHANNON_GPIO_DISP_EN,
ret = devm_gpio_request_one(&pdev->dev, SHANNON_GPIO_DISP_EN,
GPIOF_OUT_INIT_LOW, "display enable");
if (ret)
goto err_free_irq;
return ret;
}
/* Initialize video memory */
ret = sa1100fb_map_video_memory(fbi);
if (ret)
return ret;
/*
* This makes sure that our colour bitfield
* descriptors are correctly initialised.
......@@ -1269,8 +1259,11 @@ static int sa1100fb_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, fbi);
ret = register_framebuffer(&fbi->fb);
if (ret < 0)
goto err_reg_fb;
if (ret < 0) {
dma_free_wc(fbi->dev, fbi->map_size, fbi->map_cpu,
fbi->map_dma);
return ret;
}