aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/efifb.c5
-rw-r--r--drivers/video/fbmem.c31
-rw-r--r--drivers/video/vesafb.c15
3 files changed, 49 insertions, 2 deletions
diff --git a/drivers/video/efifb.c b/drivers/video/efifb.c
index 8dea2bc92705..eb12182b2059 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/efifb.c
@@ -280,6 +280,9 @@ static int __init efifb_probe(struct platform_device *dev)
280 info->pseudo_palette = info->par; 280 info->pseudo_palette = info->par;
281 info->par = NULL; 281 info->par = NULL;
282 282
283 info->aperture_base = efifb_fix.smem_start;
284 info->aperture_size = size_total;
285
283 info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len); 286 info->screen_base = ioremap(efifb_fix.smem_start, efifb_fix.smem_len);
284 if (!info->screen_base) { 287 if (!info->screen_base) {
285 printk(KERN_ERR "efifb: abort, cannot ioremap video memory " 288 printk(KERN_ERR "efifb: abort, cannot ioremap video memory "
@@ -337,7 +340,7 @@ static int __init efifb_probe(struct platform_device *dev)
337 info->fbops = &efifb_ops; 340 info->fbops = &efifb_ops;
338 info->var = efifb_defined; 341 info->var = efifb_defined;
339 info->fix = efifb_fix; 342 info->fix = efifb_fix;
340 info->flags = FBINFO_FLAG_DEFAULT; 343 info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE;
341 344
342 if ((err = fb_alloc_cmap(&info->cmap, 256, 0)) < 0) { 345 if ((err = fb_alloc_cmap(&info->cmap, 256, 0)) < 0) {
343 printk(KERN_ERR "efifb: cannot allocate colormap\n"); 346 printk(KERN_ERR "efifb: cannot allocate colormap\n");
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index d412a1ddc12f..f8a09bf8d0cd 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1462,6 +1462,16 @@ static int fb_check_foreignness(struct fb_info *fi)
1462 return 0; 1462 return 0;
1463} 1463}
1464 1464
1465static bool fb_do_apertures_overlap(struct fb_info *gen, struct fb_info *hw)
1466{
1467 /* is the generic aperture base the same as the HW one */
1468 if (gen->aperture_base == hw->aperture_base)
1469 return true;
1470 /* is the generic aperture base inside the hw base->hw base+size */
1471 if (gen->aperture_base > hw->aperture_base && gen->aperture_base <= hw->aperture_base + hw->aperture_size)
1472 return true;
1473 return false;
1474}
1465/** 1475/**
1466 * register_framebuffer - registers a frame buffer device 1476 * register_framebuffer - registers a frame buffer device
1467 * @fb_info: frame buffer info structure 1477 * @fb_info: frame buffer info structure
@@ -1485,6 +1495,23 @@ register_framebuffer(struct fb_info *fb_info)
1485 if (fb_check_foreignness(fb_info)) 1495 if (fb_check_foreignness(fb_info))
1486 return -ENOSYS; 1496 return -ENOSYS;
1487 1497
1498 /* check all firmware fbs and kick off if the base addr overlaps */
1499 for (i = 0 ; i < FB_MAX; i++) {
1500 if (!registered_fb[i])
1501 continue;
1502
1503 if (registered_fb[i]->flags & FBINFO_MISC_FIRMWARE) {
1504 if (fb_do_apertures_overlap(registered_fb[i], fb_info)) {
1505 printk(KERN_ERR "fb: conflicting fb hw usage "
1506 "%s vs %s - removing generic driver\n",
1507 fb_info->fix.id,
1508 registered_fb[i]->fix.id);
1509 unregister_framebuffer(registered_fb[i]);
1510 break;
1511 }
1512 }
1513 }
1514
1488 num_registered_fb++; 1515 num_registered_fb++;
1489 for (i = 0 ; i < FB_MAX; i++) 1516 for (i = 0 ; i < FB_MAX; i++)
1490 if (!registered_fb[i]) 1517 if (!registered_fb[i])
@@ -1586,6 +1613,10 @@ unregister_framebuffer(struct fb_info *fb_info)
1586 device_destroy(fb_class, MKDEV(FB_MAJOR, i)); 1613 device_destroy(fb_class, MKDEV(FB_MAJOR, i));
1587 event.info = fb_info; 1614 event.info = fb_info;
1588 fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); 1615 fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event);
1616
1617 /* this may free fb info */
1618 if (fb_info->fbops->fb_destroy)
1619 fb_info->fbops->fb_destroy(fb_info);
1589done: 1620done:
1590 return ret; 1621 return ret;
1591} 1622}
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index d6856f43d241..bd37ee1f6a25 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -174,8 +174,17 @@ static int vesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
174 return err; 174 return err;
175} 175}
176 176
177static void vesafb_destroy(struct fb_info *info)
178{
179 if (info->screen_base)
180 iounmap(info->screen_base);
181 release_mem_region(info->aperture_base, info->aperture_size);
182 framebuffer_release(info);
183}
184
177static struct fb_ops vesafb_ops = { 185static struct fb_ops vesafb_ops = {
178 .owner = THIS_MODULE, 186 .owner = THIS_MODULE,
187 .fb_destroy = vesafb_destroy,
179 .fb_setcolreg = vesafb_setcolreg, 188 .fb_setcolreg = vesafb_setcolreg,
180 .fb_pan_display = vesafb_pan_display, 189 .fb_pan_display = vesafb_pan_display,
181 .fb_fillrect = cfb_fillrect, 190 .fb_fillrect = cfb_fillrect,
@@ -286,6 +295,10 @@ static int __init vesafb_probe(struct platform_device *dev)
286 info->pseudo_palette = info->par; 295 info->pseudo_palette = info->par;
287 info->par = NULL; 296 info->par = NULL;
288 297
298 /* set vesafb aperture size for generic probing */
299 info->aperture_base = screen_info.lfb_base;
300 info->aperture_size = size_total;
301
289 info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len); 302 info->screen_base = ioremap(vesafb_fix.smem_start, vesafb_fix.smem_len);
290 if (!info->screen_base) { 303 if (!info->screen_base) {
291 printk(KERN_ERR 304 printk(KERN_ERR
@@ -437,7 +450,7 @@ static int __init vesafb_probe(struct platform_device *dev)
437 info->fbops = &vesafb_ops; 450 info->fbops = &vesafb_ops;
438 info->var = vesafb_defined; 451 info->var = vesafb_defined;
439 info->fix = vesafb_fix; 452 info->fix = vesafb_fix;
440 info->flags = FBINFO_FLAG_DEFAULT | 453 info->flags = FBINFO_FLAG_DEFAULT | FBINFO_MISC_FIRMWARE |
441 (ypan ? FBINFO_HWACCEL_YPAN : 0); 454 (ypan ? FBINFO_HWACCEL_YPAN : 0);
442 455
443 if (!ypan) 456 if (!ypan)