Commit 24210071 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'fbdev-fixes-for-linus' of...

Merge branch 'fbdev-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-3.x

* 'fbdev-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lethal/fbdev-3.x:
  video: Fix use-after-free by vga16fb on rmmod
  video: Convert vmalloc/memset to vzalloc
  efifb: Disallow manual bind and unbind
  efifb: Fix mismatched request/release_mem_region
  efifb: Enable write-combining
  drivers/video/pxa168fb.c: add missing clk_put
  drivers/video/imxfb.c: add missing clk_put
  fbdev: bf537-lq035: add missing blacklight properties type
  savagefb: Use panel CVT mode as default
  fbdev: sh_mobile_lcdcfb: Fix up fallout from MERAM changes.
parents 83973451 a50d28de
...@@ -515,11 +515,10 @@ static int __devinit arcfb_probe(struct platform_device *dev) ...@@ -515,11 +515,10 @@ static int __devinit arcfb_probe(struct platform_device *dev)
/* We need a flat backing store for the Arc's /* We need a flat backing store for the Arc's
less-flat actual paged framebuffer */ less-flat actual paged framebuffer */
if (!(videomemory = vmalloc(videomemorysize))) videomemory = vzalloc(videomemorysize);
if (!videomemory)
return retval; return retval;
memset(videomemory, 0, videomemorysize);
info = framebuffer_alloc(sizeof(struct arcfb_par), &dev->dev); info = framebuffer_alloc(sizeof(struct arcfb_par), &dev->dev);
if (!info) if (!info)
goto err; goto err;
......
...@@ -789,6 +789,7 @@ static int __devinit bfin_lq035_probe(struct platform_device *pdev) ...@@ -789,6 +789,7 @@ static int __devinit bfin_lq035_probe(struct platform_device *pdev)
i2c_add_driver(&ad5280_driver); i2c_add_driver(&ad5280_driver);
memset(&props, 0, sizeof(props)); memset(&props, 0, sizeof(props));
props.type = BACKLIGHT_RAW;
props.max_brightness = MAX_BRIGHENESS; props.max_brightness = MAX_BRIGHENESS;
bl_dev = backlight_device_register("bf537-bl", NULL, NULL, bl_dev = backlight_device_register("bf537-bl", NULL, NULL,
&bfin_lq035fb_bl_ops, &props); &bfin_lq035fb_bl_ops, &props);
......
...@@ -1101,12 +1101,10 @@ static int __devinit broadsheetfb_probe(struct platform_device *dev) ...@@ -1101,12 +1101,10 @@ static int __devinit broadsheetfb_probe(struct platform_device *dev)
videomemorysize = roundup((dpyw*dpyh), PAGE_SIZE); videomemorysize = roundup((dpyw*dpyh), PAGE_SIZE);
videomemory = vmalloc(videomemorysize); videomemory = vzalloc(videomemorysize);
if (!videomemory) if (!videomemory)
goto err_fb_rel; goto err_fb_rel;
memset(videomemory, 0, videomemorysize);
info->screen_base = (char *)videomemory; info->screen_base = (char *)videomemory;
info->fbops = &broadsheetfb_ops; info->fbops = &broadsheetfb_ops;
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#include <linux/pci.h> #include <linux/pci.h>
#include <video/vga.h> #include <video/vga.h>
static bool request_mem_succeeded = false;
static struct fb_var_screeninfo efifb_defined __devinitdata = { static struct fb_var_screeninfo efifb_defined __devinitdata = {
.activate = FB_ACTIVATE_NOW, .activate = FB_ACTIVATE_NOW,
.height = -1, .height = -1,
...@@ -281,7 +283,9 @@ static void efifb_destroy(struct fb_info *info) ...@@ -281,7 +283,9 @@ static void efifb_destroy(struct fb_info *info)
{ {
if (info->screen_base) if (info->screen_base)
iounmap(info->screen_base); iounmap(info->screen_base);
release_mem_region(info->apertures->ranges[0].base, info->apertures->ranges[0].size); if (request_mem_succeeded)
release_mem_region(info->apertures->ranges[0].base,
info->apertures->ranges[0].size);
framebuffer_release(info); framebuffer_release(info);
} }
...@@ -326,14 +330,13 @@ static int __init efifb_setup(char *options) ...@@ -326,14 +330,13 @@ static int __init efifb_setup(char *options)
return 0; return 0;
} }
static int __devinit efifb_probe(struct platform_device *dev) static int __init efifb_probe(struct platform_device *dev)
{ {
struct fb_info *info; struct fb_info *info;
int err; int err;
unsigned int size_vmode; unsigned int size_vmode;
unsigned int size_remap; unsigned int size_remap;
unsigned int size_total; unsigned int size_total;
int request_succeeded = 0;
if (!screen_info.lfb_depth) if (!screen_info.lfb_depth)
screen_info.lfb_depth = 32; screen_info.lfb_depth = 32;
...@@ -387,7 +390,7 @@ static int __devinit efifb_probe(struct platform_device *dev) ...@@ -387,7 +390,7 @@ static int __devinit efifb_probe(struct platform_device *dev)
efifb_fix.smem_len = size_remap; efifb_fix.smem_len = size_remap;
if (request_mem_region(efifb_fix.smem_start, size_remap, "efifb")) { if (request_mem_region(efifb_fix.smem_start, size_remap, "efifb")) {
request_succeeded = 1; request_mem_succeeded = true;
} else { } else {
/* We cannot make this fatal. Sometimes this comes from magic /* We cannot make this fatal. Sometimes this comes from magic
spaces our resource handlers simply don't know about */ spaces our resource handlers simply don't know about */
...@@ -413,7 +416,7 @@ static int __devinit efifb_probe(struct platform_device *dev) ...@@ -413,7 +416,7 @@ static int __devinit efifb_probe(struct platform_device *dev)
info->apertures->ranges[0].base = efifb_fix.smem_start; info->apertures->ranges[0].base = efifb_fix.smem_start;
info->apertures->ranges[0].size = size_remap; info->apertures->ranges[0].size = size_remap;
info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len); info->screen_base = ioremap_wc(efifb_fix.smem_start, efifb_fix.smem_len);
if (!info->screen_base) { if (!info->screen_base) {
printk(KERN_ERR "efifb: abort, cannot ioremap video memory " printk(KERN_ERR "efifb: abort, cannot ioremap video memory "
"0x%x @ 0x%lx\n", "0x%x @ 0x%lx\n",
...@@ -491,13 +494,12 @@ static int __devinit efifb_probe(struct platform_device *dev) ...@@ -491,13 +494,12 @@ static int __devinit efifb_probe(struct platform_device *dev)
err_release_fb: err_release_fb:
framebuffer_release(info); framebuffer_release(info);
err_release_mem: err_release_mem:
if (request_succeeded) if (request_mem_succeeded)
release_mem_region(efifb_fix.smem_start, size_total); release_mem_region(efifb_fix.smem_start, size_total);
return err; return err;
} }
static struct platform_driver efifb_driver = { static struct platform_driver efifb_driver = {
.probe = efifb_probe,
.driver = { .driver = {
.name = "efifb", .name = "efifb",
}, },
...@@ -528,13 +530,21 @@ static int __init efifb_init(void) ...@@ -528,13 +530,21 @@ static int __init efifb_init(void)
if (!screen_info.lfb_linelength) if (!screen_info.lfb_linelength)
return -ENODEV; return -ENODEV;
ret = platform_driver_register(&efifb_driver); ret = platform_device_register(&efifb_device);
if (ret)
return ret;
if (!ret) { /*
ret = platform_device_register(&efifb_device); * This is not just an optimization. We will interfere
if (ret) * with a real driver if we get reprobed, so don't allow
platform_driver_unregister(&efifb_driver); * it.
*/
ret = platform_driver_probe(&efifb_driver, efifb_probe);
if (ret) {
platform_device_unregister(&efifb_driver);
return ret;
} }
return ret; return ret;
} }
module_init(efifb_init); module_init(efifb_init);
......
...@@ -231,11 +231,10 @@ static int __devinit hecubafb_probe(struct platform_device *dev) ...@@ -231,11 +231,10 @@ static int __devinit hecubafb_probe(struct platform_device *dev)
videomemorysize = (DPY_W*DPY_H)/8; videomemorysize = (DPY_W*DPY_H)/8;
if (!(videomemory = vmalloc(videomemorysize))) videomemory = vzalloc(videomemorysize);
if (!videomemory)
return retval; return retval;
memset(videomemory, 0, videomemorysize);
info = framebuffer_alloc(sizeof(struct hecubafb_par), &dev->dev); info = framebuffer_alloc(sizeof(struct hecubafb_par), &dev->dev);
if (!info) if (!info)
goto err_fballoc; goto err_fballoc;
......
...@@ -856,10 +856,10 @@ static int __init imxfb_probe(struct platform_device *pdev) ...@@ -856,10 +856,10 @@ static int __init imxfb_probe(struct platform_device *pdev)
dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu, dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu,
fbi->map_dma); fbi->map_dma);
failed_map: failed_map:
clk_put(fbi->clk);
failed_getclock:
iounmap(fbi->regs); iounmap(fbi->regs);
failed_ioremap: failed_ioremap:
clk_put(fbi->clk);
failed_getclock:
release_mem_region(res->start, resource_size(res)); release_mem_region(res->start, resource_size(res));
failed_req: failed_req:
kfree(info->pseudo_palette); kfree(info->pseudo_palette);
......
...@@ -628,12 +628,10 @@ static int __devinit metronomefb_probe(struct platform_device *dev) ...@@ -628,12 +628,10 @@ static int __devinit metronomefb_probe(struct platform_device *dev)
/* we need to add a spare page because our csum caching scheme walks /* we need to add a spare page because our csum caching scheme walks
* to the end of the page */ * to the end of the page */
videomemorysize = PAGE_SIZE + (fw * fh); videomemorysize = PAGE_SIZE + (fw * fh);
videomemory = vmalloc(videomemorysize); videomemory = vzalloc(videomemorysize);
if (!videomemory) if (!videomemory)
goto err_fb_rel; goto err_fb_rel;
memset(videomemory, 0, videomemorysize);
info->screen_base = (char __force __iomem *)videomemory; info->screen_base = (char __force __iomem *)videomemory;
info->fbops = &metronomefb_ops; info->fbops = &metronomefb_ops;
......
...@@ -1128,3 +1128,4 @@ EXPORT_SYMBOL(fb_find_best_mode); ...@@ -1128,3 +1128,4 @@ EXPORT_SYMBOL(fb_find_best_mode);
EXPORT_SYMBOL(fb_find_nearest_mode); EXPORT_SYMBOL(fb_find_nearest_mode);
EXPORT_SYMBOL(fb_videomode_to_modelist); EXPORT_SYMBOL(fb_videomode_to_modelist);
EXPORT_SYMBOL(fb_find_mode); EXPORT_SYMBOL(fb_find_mode);
EXPORT_SYMBOL(fb_find_mode_cvt);
...@@ -623,19 +623,21 @@ static int __devinit pxa168fb_probe(struct platform_device *pdev) ...@@ -623,19 +623,21 @@ static int __devinit pxa168fb_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) { if (res == NULL) {
dev_err(&pdev->dev, "no IO memory defined\n"); dev_err(&pdev->dev, "no IO memory defined\n");
return -ENOENT; ret = -ENOENT;
goto failed_put_clk;
} }
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) { if (irq < 0) {
dev_err(&pdev->dev, "no IRQ defined\n"); dev_err(&pdev->dev, "no IRQ defined\n");
return -ENOENT; ret = -ENOENT;
goto failed_put_clk;
} }
info = framebuffer_alloc(sizeof(struct pxa168fb_info), &pdev->dev); info = framebuffer_alloc(sizeof(struct pxa168fb_info), &pdev->dev);
if (info == NULL) { if (info == NULL) {
clk_put(clk); ret = -ENOMEM;
return -ENOMEM; goto failed_put_clk;
} }
/* Initialize private data */ /* Initialize private data */
...@@ -671,7 +673,7 @@ static int __devinit pxa168fb_probe(struct platform_device *pdev) ...@@ -671,7 +673,7 @@ static int __devinit pxa168fb_probe(struct platform_device *pdev)
fbi->reg_base = ioremap_nocache(res->start, resource_size(res)); fbi->reg_base = ioremap_nocache(res->start, resource_size(res));
if (fbi->reg_base == NULL) { if (fbi->reg_base == NULL) {
ret = -ENOMEM; ret = -ENOMEM;
goto failed; goto failed_free_info;
} }
/* /*
...@@ -683,7 +685,7 @@ static int __devinit pxa168fb_probe(struct platform_device *pdev) ...@@ -683,7 +685,7 @@ static int __devinit pxa168fb_probe(struct platform_device *pdev)
&fbi->fb_start_dma, GFP_KERNEL); &fbi->fb_start_dma, GFP_KERNEL);
if (info->screen_base == NULL) { if (info->screen_base == NULL) {
ret = -ENOMEM; ret = -ENOMEM;
goto failed; goto failed_free_info;
} }
info->fix.smem_start = (unsigned long)fbi->fb_start_dma; info->fix.smem_start = (unsigned long)fbi->fb_start_dma;
...@@ -772,8 +774,9 @@ static int __devinit pxa168fb_probe(struct platform_device *pdev) ...@@ -772,8 +774,9 @@ static int __devinit pxa168fb_probe(struct platform_device *pdev)
failed_free_fbmem: failed_free_fbmem:
dma_free_coherent(fbi->dev, info->fix.smem_len, dma_free_coherent(fbi->dev, info->fix.smem_len,
info->screen_base, fbi->fb_start_dma); info->screen_base, fbi->fb_start_dma);
failed: failed_free_info:
kfree(info); kfree(info);
failed_put_clk:
clk_put(clk); clk_put(clk);
dev_err(&pdev->dev, "frame buffer device init failed with %d\n", ret); dev_err(&pdev->dev, "frame buffer device init failed with %d\n", ret);
......
...@@ -2237,6 +2237,22 @@ static int __devinit savagefb_probe(struct pci_dev* dev, ...@@ -2237,6 +2237,22 @@ static int __devinit savagefb_probe(struct pci_dev* dev,
&info->modelist); &info->modelist);
#endif #endif
info->var = savagefb_var800x600x8; info->var = savagefb_var800x600x8;
/* if a panel was detected, default to a CVT mode instead */
if (par->SavagePanelWidth) {
struct fb_videomode cvt_mode;
memset(&cvt_mode, 0, sizeof(cvt_mode));
cvt_mode.xres = par->SavagePanelWidth;
cvt_mode.yres = par->SavagePanelHeight;
cvt_mode.refresh = 60;
/* FIXME: if we know there is only the panel
* we can enable reduced blanking as well */
if (fb_find_mode_cvt(&cvt_mode, 0, 0))
printk(KERN_WARNING "No CVT mode found for panel\n");
else if (fb_find_mode(&info->var, info, NULL, NULL, 0,
&cvt_mode, 0) != 3)
info->var = savagefb_var800x600x8;
}
if (mode_option) { if (mode_option) {
fb_find_mode(&info->var, info, mode_option, fb_find_mode(&info->var, info, mode_option,
......
...@@ -470,7 +470,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) ...@@ -470,7 +470,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
unsigned long tmp; unsigned long tmp;
int bpp = 0; int bpp = 0;
unsigned long ldddsr; unsigned long ldddsr;
int k, m; int k, m, ret;
/* enable clocks before accessing the hardware */ /* enable clocks before accessing the hardware */
for (k = 0; k < ARRAY_SIZE(priv->ch); k++) { for (k = 0; k < ARRAY_SIZE(priv->ch); k++) {
...@@ -540,7 +540,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv) ...@@ -540,7 +540,7 @@ static int sh_mobile_lcdc_start(struct sh_mobile_lcdc_priv *priv)
board_cfg = &ch->cfg.board_cfg; board_cfg = &ch->cfg.board_cfg;
if (board_cfg->setup_sys) { if (board_cfg->setup_sys) {
int ret = board_cfg->setup_sys(board_cfg->board_data, ret = board_cfg->setup_sys(board_cfg->board_data,
ch, &sh_mobile_lcdc_sys_bus_ops); ch, &sh_mobile_lcdc_sys_bus_ops);
if (ret) if (ret)
return ret; return ret;
......
...@@ -1265,9 +1265,11 @@ static void vga16fb_imageblit(struct fb_info *info, const struct fb_image *image ...@@ -1265,9 +1265,11 @@ static void vga16fb_imageblit(struct fb_info *info, const struct fb_image *image
static void vga16fb_destroy(struct fb_info *info) static void vga16fb_destroy(struct fb_info *info)
{ {
struct platform_device *dev = container_of(info->device, struct platform_device, dev);
iounmap(info->screen_base); iounmap(info->screen_base);
fb_dealloc_cmap(&info->cmap); fb_dealloc_cmap(&info->cmap);
/* XXX unshare VGA regions */ /* XXX unshare VGA regions */
platform_set_drvdata(dev, NULL);
framebuffer_release(info); framebuffer_release(info);
} }
......
...@@ -395,10 +395,9 @@ static int __devinit xenfb_probe(struct xenbus_device *dev, ...@@ -395,10 +395,9 @@ static int __devinit xenfb_probe(struct xenbus_device *dev,
spin_lock_init(&info->dirty_lock); spin_lock_init(&info->dirty_lock);
spin_lock_init(&info->resize_lock); spin_lock_init(&info->resize_lock);
info->fb = vmalloc(fb_size); info->fb = vzalloc(fb_size);
if (info->fb == NULL) if (info->fb == NULL)
goto error_nomem; goto error_nomem;
memset(info->fb, 0, fb_size);
info->nr_pages = (fb_size + PAGE_SIZE - 1) >> PAGE_SHIFT; info->nr_pages = (fb_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment