diff options
author | Marco La Porta <marco-laporta@tiscali.it> | 2009-02-11 16:04:20 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-02-11 17:25:34 -0500 |
commit | 067f1293cc5916f8d88b602beeb8787d58515608 (patch) | |
tree | 1077d6997716b33ab203ff206e5b7df09ed57d70 /drivers/video | |
parent | 57f63bc8fe79e6598e7253f10f53f58c9fdc57be (diff) |
lxfb: properly alloc cmap in all cases and don't leak the memory
We weren't properly allocating the cmap for depths greater than 8bpp,
which caused pain for things like DirectFB. Also, we never freed the cmap
memory upon module unload..
[dilinger@debian.org: dropped unnecessary code and clean up patch]
[dilinger@debian.org: add error checking and handling]
Signed-off-by: Andres Salomon <dilinger@debian.org>
Cc: Jordan Crouse <jordan@cosmicpenguin.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video')
-rw-r--r-- | drivers/video/geode/lxfb_core.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/drivers/video/geode/lxfb_core.c b/drivers/video/geode/lxfb_core.c index b965ecdbc604..889cbe39e580 100644 --- a/drivers/video/geode/lxfb_core.c +++ b/drivers/video/geode/lxfb_core.c | |||
@@ -278,13 +278,10 @@ static int lxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
278 | 278 | ||
279 | static int lxfb_set_par(struct fb_info *info) | 279 | static int lxfb_set_par(struct fb_info *info) |
280 | { | 280 | { |
281 | if (info->var.bits_per_pixel > 8) { | 281 | if (info->var.bits_per_pixel > 8) |
282 | info->fix.visual = FB_VISUAL_TRUECOLOR; | 282 | info->fix.visual = FB_VISUAL_TRUECOLOR; |
283 | fb_dealloc_cmap(&info->cmap); | 283 | else |
284 | } else { | ||
285 | info->fix.visual = FB_VISUAL_PSEUDOCOLOR; | 284 | info->fix.visual = FB_VISUAL_PSEUDOCOLOR; |
286 | fb_alloc_cmap(&info->cmap, 1<<info->var.bits_per_pixel, 0); | ||
287 | } | ||
288 | 285 | ||
289 | info->fix.line_length = lx_get_pitch(info->var.xres, | 286 | info->fix.line_length = lx_get_pitch(info->var.xres, |
290 | info->var.bits_per_pixel); | 287 | info->var.bits_per_pixel); |
@@ -451,6 +448,11 @@ static struct fb_info * __init lxfb_init_fbinfo(struct device *dev) | |||
451 | 448 | ||
452 | info->pseudo_palette = (void *)par + sizeof(struct lxfb_par); | 449 | info->pseudo_palette = (void *)par + sizeof(struct lxfb_par); |
453 | 450 | ||
451 | if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { | ||
452 | framebuffer_release(info); | ||
453 | return NULL; | ||
454 | } | ||
455 | |||
454 | info->var.grayscale = 0; | 456 | info->var.grayscale = 0; |
455 | 457 | ||
456 | return info; | 458 | return info; |
@@ -579,8 +581,10 @@ err: | |||
579 | pci_release_region(pdev, 3); | 581 | pci_release_region(pdev, 3); |
580 | } | 582 | } |
581 | 583 | ||
582 | if (info) | 584 | if (info) { |
585 | fb_dealloc_cmap(&info->cmap); | ||
583 | framebuffer_release(info); | 586 | framebuffer_release(info); |
587 | } | ||
584 | 588 | ||
585 | return ret; | 589 | return ret; |
586 | } | 590 | } |
@@ -604,6 +608,7 @@ static void lxfb_remove(struct pci_dev *pdev) | |||
604 | iounmap(par->vp_regs); | 608 | iounmap(par->vp_regs); |
605 | pci_release_region(pdev, 3); | 609 | pci_release_region(pdev, 3); |
606 | 610 | ||
611 | fb_dealloc_cmap(&info->cmap); | ||
607 | pci_set_drvdata(pdev, NULL); | 612 | pci_set_drvdata(pdev, NULL); |
608 | framebuffer_release(info); | 613 | framebuffer_release(info); |
609 | } | 614 | } |