diff options
Diffstat (limited to 'drivers/video/aperture.c')
-rw-r--r-- | drivers/video/aperture.c | 69 |
1 files changed, 39 insertions, 30 deletions
diff --git a/drivers/video/aperture.c b/drivers/video/aperture.c index 538f2d40acda..9e6bcc03a1a4 100644 --- a/drivers/video/aperture.c +++ b/drivers/video/aperture.c @@ -2,15 +2,17 @@ #include <linux/aperture.h> #include <linux/device.h> -#include <linux/fb.h> /* for old fbdev helpers */ #include <linux/list.h> #include <linux/mutex.h> #include <linux/pci.h> #include <linux/platform_device.h> #include <linux/slab.h> +#include <linux/sysfb.h> #include <linux/types.h> #include <linux/vgaarb.h> +#include <video/vga.h> + /** * DOC: overview * @@ -283,26 +285,27 @@ static void aperture_detach_devices(resource_size_t base, resource_size_t size) int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t size, bool primary, const char *name) { -#if IS_REACHABLE(CONFIG_FB) - struct apertures_struct *a; - int ret; - - a = alloc_apertures(1); - if (!a) - return -ENOMEM; - - a->ranges[0].base = base; - a->ranges[0].size = size; - - ret = remove_conflicting_framebuffers(a, name, primary); - kfree(a); - - if (ret) - return ret; -#endif + /* + * If a driver asked to unregister a platform device registered by + * sysfb, then can be assumed that this is a driver for a display + * that is set up by the system firmware and has a generic driver. + * + * Drivers for devices that don't have a generic driver will never + * ask for this, so let's assume that a real driver for the display + * was already probed and prevent sysfb to register devices later. + */ + sysfb_disable(); aperture_detach_devices(base, size); + /* + * If this is the primary adapter, there could be a VGA device + * that consumes the VGA framebuffer I/O range. Remove this device + * as well. + */ + if (primary) + aperture_detach_devices(VGA_FB_PHYS_BASE, VGA_FB_PHYS_SIZE); + return 0; } EXPORT_SYMBOL(aperture_remove_conflicting_devices); @@ -321,30 +324,36 @@ EXPORT_SYMBOL(aperture_remove_conflicting_devices); */ int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *name) { + bool primary = false; resource_size_t base, size; int bar, ret; - /* - * WARNING: Apparently we must kick fbdev drivers before vgacon, - * otherwise the vga fbdev driver falls over. - */ -#if IS_REACHABLE(CONFIG_FB) - ret = remove_conflicting_pci_framebuffers(pdev, name); - if (ret) - return ret; +#ifdef CONFIG_X86 + primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; #endif - ret = vga_remove_vgacon(pdev); - if (ret) - return ret; for (bar = 0; bar < PCI_STD_NUM_BARS; ++bar) { if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) continue; + base = pci_resource_start(pdev, bar); size = pci_resource_len(pdev, bar); - aperture_detach_devices(base, size); + ret = aperture_remove_conflicting_devices(base, size, primary, name); + if (ret) + break; } + if (ret) + return ret; + + /* + * WARNING: Apparently we must kick fbdev drivers before vgacon, + * otherwise the vga fbdev driver falls over. + */ + ret = vga_remove_vgacon(pdev); + if (ret) + return ret; + return 0; } |