diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 11:14:52 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-05-21 11:14:52 -0700 |
commit | 59534f7298c5e28aaa64e6ed550e247f64ee72ae (patch) | |
tree | b9fef7756abf897d9e1b10950cdf10bf6dfe5cb7 /drivers/video/fbmem.c | |
parent | ac3ee84c604502240122c47b52f0542ec8774f15 (diff) | |
parent | b486787ee4797d6e42a9bd3a6f079385ad0f4472 (diff) | |
download | linux-stable-59534f7298c5e28aaa64e6ed550e247f64ee72ae.tar.gz linux-stable-59534f7298c5e28aaa64e6ed550e247f64ee72ae.tar.bz2 linux-stable-59534f7298c5e28aaa64e6ed550e247f64ee72ae.zip |
Merge branch 'drm-for-2.6.35' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-for-2.6.35' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6: (207 commits)
drm/radeon/kms/pm/r600: select the mid clock mode for single head low profile
drm/radeon: fix power supply kconfig interaction.
drm/radeon/kms: record object that have been list reserved
drm/radeon: AGP memory is only I/O if the aperture can be mapped by the CPU.
drm/radeon/kms: don't default display priority to high on rs4xx
drm/edid: fix typo in 1600x1200@75 mode
drm/nouveau: fix i2c-related init table handlers
drm/nouveau: support init table i2c device identifier 0x81
drm/nouveau: ensure we've parsed i2c table entry for INIT_*I2C* handlers
drm/nouveau: display error message for any failed init table opcode
drm/nouveau: fix init table handlers to return proper error codes
drm/nv50: support fractional feedback divider on newer chips
drm/nv50: fix monitor detection on certain chipsets
drm/nv50: store full dcb i2c entry from vbios
drm/nv50: fix suspend/resume with DP outputs
drm/nv50: output calculated crtc pll when debugging on
drm/nouveau: dump pll limits entries when debugging is on
drm/nouveau: bios parser fixes for eDP boards
drm/nouveau: fix a nouveau_bo dereference after it's been destroyed
drm/nv40: remove some completed ctxprog TODOs
...
Diffstat (limited to 'drivers/video/fbmem.c')
-rw-r--r-- | drivers/video/fbmem.c | 74 |
1 files changed, 56 insertions, 18 deletions
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index a15b44e9c003..e08b7b5cb326 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -1468,16 +1468,67 @@ static int fb_check_foreignness(struct fb_info *fi) return 0; } -static bool fb_do_apertures_overlap(struct fb_info *gen, struct fb_info *hw) +static bool apertures_overlap(struct aperture *gen, struct aperture *hw) { /* is the generic aperture base the same as the HW one */ - if (gen->aperture_base == hw->aperture_base) + if (gen->base == hw->base) return true; /* is the generic aperture base inside the hw base->hw base+size */ - if (gen->aperture_base > hw->aperture_base && gen->aperture_base <= hw->aperture_base + hw->aperture_size) + if (gen->base > hw->base && gen->base <= hw->base + hw->size) return true; return false; } + +static bool fb_do_apertures_overlap(struct apertures_struct *gena, + struct apertures_struct *hwa) +{ + int i, j; + if (!hwa || !gena) + return false; + + for (i = 0; i < hwa->count; ++i) { + struct aperture *h = &hwa->ranges[i]; + for (j = 0; j < gena->count; ++j) { + struct aperture *g = &gena->ranges[j]; + printk(KERN_DEBUG "checking generic (%llx %llx) vs hw (%llx %llx)\n", + g->base, g->size, h->base, h->size); + if (apertures_overlap(g, h)) + return true; + } + } + + return false; +} + +#define VGA_FB_PHYS 0xA0000 +void remove_conflicting_framebuffers(struct apertures_struct *a, + const char *name, bool primary) +{ + int i; + + /* check all firmware fbs and kick off if the base addr overlaps */ + for (i = 0 ; i < FB_MAX; i++) { + struct apertures_struct *gen_aper; + if (!registered_fb[i]) + continue; + + if (!(registered_fb[i]->flags & FBINFO_MISC_FIRMWARE)) + continue; + + gen_aper = registered_fb[i]->apertures; + if (fb_do_apertures_overlap(gen_aper, a) || + (primary && gen_aper && gen_aper->count && + gen_aper->ranges[0].base == VGA_FB_PHYS)) { + + printk(KERN_ERR "fb: conflicting fb hw usage " + "%s vs %s - removing generic driver\n", + name, registered_fb[i]->fix.id); + unregister_framebuffer(registered_fb[i]); + } + } +} +EXPORT_SYMBOL(remove_conflicting_framebuffers); + /** * register_framebuffer - registers a frame buffer device * @fb_info: frame buffer info structure @@ -1501,21 +1552,8 @@ register_framebuffer(struct fb_info *fb_info) if (fb_check_foreignness(fb_info)) return -ENOSYS; - /* check all firmware fbs and kick off if the base addr overlaps */ - for (i = 0 ; i < FB_MAX; i++) { - if (!registered_fb[i]) - continue; - - if (registered_fb[i]->flags & FBINFO_MISC_FIRMWARE) { - if (fb_do_apertures_overlap(registered_fb[i], fb_info)) { - printk(KERN_ERR "fb: conflicting fb hw usage " - "%s vs %s - removing generic driver\n", - fb_info->fix.id, - registered_fb[i]->fix.id); - unregister_framebuffer(registered_fb[i]); - } - } - } + remove_conflicting_framebuffers(fb_info->apertures, fb_info->fix.id, + fb_is_primary_device(fb_info)); num_registered_fb++; for (i = 0 ; i < FB_MAX; i++) |