diff options
Diffstat (limited to 'drivers/video/aperture.c')
| -rw-r--r-- | drivers/video/aperture.c | 77 |
1 files changed, 47 insertions, 30 deletions
diff --git a/drivers/video/aperture.c b/drivers/video/aperture.c index 41e77de1ea82..2b5a1e666e9b 100644 --- a/drivers/video/aperture.c +++ b/drivers/video/aperture.c @@ -20,7 +20,7 @@ * driver can be active at any given time. Many systems load a generic * graphics drivers, such as EFI-GOP or VESA, early during the boot process. * During later boot stages, they replace the generic driver with a dedicated, - * hardware-specific driver. To take over the device the dedicated driver + * hardware-specific driver. To take over the device, the dedicated driver * first has to remove the generic driver. Aperture functions manage * ownership of framebuffer memory and hand-over between drivers. * @@ -43,7 +43,7 @@ * base = mem->start; * size = resource_size(mem); * - * ret = aperture_remove_conflicting_devices(base, size, false, "example"); + * ret = aperture_remove_conflicting_devices(base, size, "example"); * if (ret) * return ret; * @@ -76,7 +76,7 @@ * generic EFI or VESA drivers, have to register themselves as owners of their * framebuffer apertures. Ownership of the framebuffer memory is achieved * by calling devm_aperture_acquire_for_platform_device(). If successful, the - * driveris the owner of the framebuffer range. The function fails if the + * driver is the owner of the framebuffer range. The function fails if the * framebuffer is already owned by another driver. See below for an example. * * .. code-block:: c @@ -126,7 +126,7 @@ * et al for the registered framebuffer range, the aperture helpers call * platform_device_unregister() and the generic driver unloads itself. The * generic driver also has to provide a remove function to make this work. - * Once hot unplugged fro mhardware, it may not access the device's + * Once hot unplugged from hardware, it may not access the device's * registers, framebuffer memory, ROM, etc afterwards. */ @@ -203,7 +203,7 @@ static void aperture_detach_platform_device(struct device *dev) /* * Remove the device from the device hierarchy. This is the right thing - * to do for firmware-based DRM drivers, such as EFI, VESA or VGA. After + * to do for firmware-based fb drivers, such as EFI, VESA or VGA. After * the new driver takes over the hardware, the firmware device's state * will be lost. * @@ -274,7 +274,6 @@ static void aperture_detach_devices(resource_size_t base, resource_size_t size) * aperture_remove_conflicting_devices - remove devices in the given range * @base: the aperture's base address in physical memory * @size: aperture size in bytes - * @primary: also kick vga16fb if present; only relevant for VGA devices * @name: a descriptive name of the requesting driver * * This function removes devices that own apertures within @base and @size. @@ -283,7 +282,7 @@ static void aperture_detach_devices(resource_size_t base, resource_size_t size) * 0 on success, or a negative errno code otherwise */ int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t size, - bool primary, const char *name) + const char *name) { /* * If a driver asked to unregister a platform device registered by @@ -294,23 +293,46 @@ int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t si * 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(); + sysfb_disable(NULL); 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); /** + * __aperture_remove_legacy_vga_devices - remove legacy VGA devices of a PCI devices + * @pdev: PCI device + * + * This function removes VGA devices provided by @pdev, such as a VGA + * framebuffer or a console. This is useful if you have a VGA-compatible + * PCI graphics device with framebuffers in non-BAR locations. Drivers + * should acquire ownership of those memory areas and afterwards call + * this helper to release remaining VGA devices. + * + * If your hardware has its framebuffers accessible via PCI BARS, use + * aperture_remove_conflicting_pci_devices() instead. The function will + * release any VGA devices automatically. + * + * WARNING: Apparently we must remove graphics drivers before calling + * this helper. Otherwise the vga fbdev driver falls over if + * we have vgacon configured. + * + * Returns: + * 0 on success, or a negative errno code otherwise + */ +int __aperture_remove_legacy_vga_devices(struct pci_dev *pdev) +{ + /* VGA framebuffer */ + aperture_detach_devices(VGA_FB_PHYS_BASE, VGA_FB_PHYS_SIZE); + + /* VGA textmode console */ + return vga_remove_vgacon(pdev); +} +EXPORT_SYMBOL(__aperture_remove_legacy_vga_devices); + +/** * aperture_remove_conflicting_pci_devices - remove existing framebuffers for PCI devices * @pdev: PCI device * @name: a descriptive name of the requesting driver @@ -324,13 +346,10 @@ 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; + int bar, ret = 0; -#ifdef CONFIG_X86 - primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; -#endif + sysfb_disable(&pdev->dev); for (bar = 0; bar < PCI_STD_NUM_BARS; ++bar) { if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) @@ -338,20 +357,18 @@ int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *na base = pci_resource_start(pdev, bar); size = pci_resource_len(pdev, bar); - ret = aperture_remove_conflicting_devices(base, size, primary, name); - if (ret) - return ret; + aperture_detach_devices(base, size); } /* - * WARNING: Apparently we must kick fbdev drivers before vgacon, - * otherwise the vga fbdev driver falls over. + * 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. */ - ret = vga_remove_vgacon(pdev); - if (ret) - return ret; + if (pdev == vga_default_device()) + ret = __aperture_remove_legacy_vga_devices(pdev); - return 0; + return ret; } EXPORT_SYMBOL(aperture_remove_conflicting_pci_devices); |
