1*11d79c47SEmmanuel Vadot // SPDX-License-Identifier: MIT 2*11d79c47SEmmanuel Vadot 3*11d79c47SEmmanuel Vadot #include <linux/aperture.h> 4*11d79c47SEmmanuel Vadot #include <linux/device.h> 5*11d79c47SEmmanuel Vadot #include <linux/list.h> 6*11d79c47SEmmanuel Vadot #include <linux/mutex.h> 7*11d79c47SEmmanuel Vadot #include <linux/pci.h> 8*11d79c47SEmmanuel Vadot #include <linux/platform_device.h> 9*11d79c47SEmmanuel Vadot #include <linux/slab.h> 10*11d79c47SEmmanuel Vadot #include <linux/sysfb.h> 11*11d79c47SEmmanuel Vadot #include <linux/types.h> 12*11d79c47SEmmanuel Vadot #include <linux/vgaarb.h> 13*11d79c47SEmmanuel Vadot 14*11d79c47SEmmanuel Vadot #include <video/vga.h> 15*11d79c47SEmmanuel Vadot 16*11d79c47SEmmanuel Vadot /** 17*11d79c47SEmmanuel Vadot * DOC: overview 18*11d79c47SEmmanuel Vadot * 19*11d79c47SEmmanuel Vadot * A graphics device might be supported by different drivers, but only one 20*11d79c47SEmmanuel Vadot * driver can be active at any given time. Many systems load a generic 21*11d79c47SEmmanuel Vadot * graphics drivers, such as EFI-GOP or VESA, early during the boot process. 22*11d79c47SEmmanuel Vadot * During later boot stages, they replace the generic driver with a dedicated, 23*11d79c47SEmmanuel Vadot * hardware-specific driver. To take over the device the dedicated driver 24*11d79c47SEmmanuel Vadot * first has to remove the generic driver. Aperture functions manage 25*11d79c47SEmmanuel Vadot * ownership of framebuffer memory and hand-over between drivers. 26*11d79c47SEmmanuel Vadot * 27*11d79c47SEmmanuel Vadot * Graphics drivers should call aperture_remove_conflicting_devices() 28*11d79c47SEmmanuel Vadot * at the top of their probe function. The function removes any generic 29*11d79c47SEmmanuel Vadot * driver that is currently associated with the given framebuffer memory. 30*11d79c47SEmmanuel Vadot * An example for a graphics device on the platform bus is shown below. 31*11d79c47SEmmanuel Vadot * 32*11d79c47SEmmanuel Vadot * .. code-block:: c 33*11d79c47SEmmanuel Vadot * 34*11d79c47SEmmanuel Vadot * static int example_probe(struct platform_device *pdev) 35*11d79c47SEmmanuel Vadot * { 36*11d79c47SEmmanuel Vadot * struct resource *mem; 37*11d79c47SEmmanuel Vadot * resource_size_t base, size; 38*11d79c47SEmmanuel Vadot * int ret; 39*11d79c47SEmmanuel Vadot * 40*11d79c47SEmmanuel Vadot * mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 41*11d79c47SEmmanuel Vadot * if (!mem) 42*11d79c47SEmmanuel Vadot * return -ENODEV; 43*11d79c47SEmmanuel Vadot * base = mem->start; 44*11d79c47SEmmanuel Vadot * size = resource_size(mem); 45*11d79c47SEmmanuel Vadot * 46*11d79c47SEmmanuel Vadot * ret = aperture_remove_conflicting_devices(base, size, false, "example"); 47*11d79c47SEmmanuel Vadot * if (ret) 48*11d79c47SEmmanuel Vadot * return ret; 49*11d79c47SEmmanuel Vadot * 50*11d79c47SEmmanuel Vadot * // Initialize the hardware 51*11d79c47SEmmanuel Vadot * ... 52*11d79c47SEmmanuel Vadot * 53*11d79c47SEmmanuel Vadot * return 0; 54*11d79c47SEmmanuel Vadot * } 55*11d79c47SEmmanuel Vadot * 56*11d79c47SEmmanuel Vadot * static const struct platform_driver example_driver = { 57*11d79c47SEmmanuel Vadot * .probe = example_probe, 58*11d79c47SEmmanuel Vadot * ... 59*11d79c47SEmmanuel Vadot * }; 60*11d79c47SEmmanuel Vadot * 61*11d79c47SEmmanuel Vadot * The given example reads the platform device's I/O-memory range from the 62*11d79c47SEmmanuel Vadot * device instance. An active framebuffer will be located within this range. 63*11d79c47SEmmanuel Vadot * The call to aperture_remove_conflicting_devices() releases drivers that 64*11d79c47SEmmanuel Vadot * have previously claimed ownership of the range and are currently driving 65*11d79c47SEmmanuel Vadot * output on the framebuffer. If successful, the new driver can take over 66*11d79c47SEmmanuel Vadot * the device. 67*11d79c47SEmmanuel Vadot * 68*11d79c47SEmmanuel Vadot * While the given example uses a platform device, the aperture helpers work 69*11d79c47SEmmanuel Vadot * with every bus that has an addressable framebuffer. In the case of PCI, 70*11d79c47SEmmanuel Vadot * device drivers can also call aperture_remove_conflicting_pci_devices() and 71*11d79c47SEmmanuel Vadot * let the function detect the apertures automatically. Device drivers without 72*11d79c47SEmmanuel Vadot * knowledge of the framebuffer's location can call 73*11d79c47SEmmanuel Vadot * aperture_remove_all_conflicting_devices(), which removes all known devices. 74*11d79c47SEmmanuel Vadot * 75*11d79c47SEmmanuel Vadot * Drivers that are susceptible to being removed by other drivers, such as 76*11d79c47SEmmanuel Vadot * generic EFI or VESA drivers, have to register themselves as owners of their 77*11d79c47SEmmanuel Vadot * framebuffer apertures. Ownership of the framebuffer memory is achieved 78*11d79c47SEmmanuel Vadot * by calling devm_aperture_acquire_for_platform_device(). If successful, the 79*11d79c47SEmmanuel Vadot * driveris the owner of the framebuffer range. The function fails if the 80*11d79c47SEmmanuel Vadot * framebuffer is already owned by another driver. See below for an example. 81*11d79c47SEmmanuel Vadot * 82*11d79c47SEmmanuel Vadot * .. code-block:: c 83*11d79c47SEmmanuel Vadot * 84*11d79c47SEmmanuel Vadot * static int generic_probe(struct platform_device *pdev) 85*11d79c47SEmmanuel Vadot * { 86*11d79c47SEmmanuel Vadot * struct resource *mem; 87*11d79c47SEmmanuel Vadot * resource_size_t base, size; 88*11d79c47SEmmanuel Vadot * 89*11d79c47SEmmanuel Vadot * mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 90*11d79c47SEmmanuel Vadot * if (!mem) 91*11d79c47SEmmanuel Vadot * return -ENODEV; 92*11d79c47SEmmanuel Vadot * base = mem->start; 93*11d79c47SEmmanuel Vadot * size = resource_size(mem); 94*11d79c47SEmmanuel Vadot * 95*11d79c47SEmmanuel Vadot * ret = devm_aperture_acquire_for_platform_device(pdev, base, size); 96*11d79c47SEmmanuel Vadot * if (ret) 97*11d79c47SEmmanuel Vadot * return ret; 98*11d79c47SEmmanuel Vadot * 99*11d79c47SEmmanuel Vadot * // Initialize the hardware 100*11d79c47SEmmanuel Vadot * ... 101*11d79c47SEmmanuel Vadot * 102*11d79c47SEmmanuel Vadot * return 0; 103*11d79c47SEmmanuel Vadot * } 104*11d79c47SEmmanuel Vadot * 105*11d79c47SEmmanuel Vadot * static int generic_remove(struct platform_device *) 106*11d79c47SEmmanuel Vadot * { 107*11d79c47SEmmanuel Vadot * // Hot-unplug the device 108*11d79c47SEmmanuel Vadot * ... 109*11d79c47SEmmanuel Vadot * 110*11d79c47SEmmanuel Vadot * return 0; 111*11d79c47SEmmanuel Vadot * } 112*11d79c47SEmmanuel Vadot * 113*11d79c47SEmmanuel Vadot * static const struct platform_driver generic_driver = { 114*11d79c47SEmmanuel Vadot * .probe = generic_probe, 115*11d79c47SEmmanuel Vadot * .remove = generic_remove, 116*11d79c47SEmmanuel Vadot * ... 117*11d79c47SEmmanuel Vadot * }; 118*11d79c47SEmmanuel Vadot * 119*11d79c47SEmmanuel Vadot * The similar to the previous example, the generic driver claims ownership 120*11d79c47SEmmanuel Vadot * of the framebuffer memory from its probe function. This will fail if the 121*11d79c47SEmmanuel Vadot * memory range, or parts of it, is already owned by another driver. 122*11d79c47SEmmanuel Vadot * 123*11d79c47SEmmanuel Vadot * If successful, the generic driver is now subject to forced removal by 124*11d79c47SEmmanuel Vadot * another driver. This only works for platform drivers that support hot 125*11d79c47SEmmanuel Vadot * unplugging. When a driver calls aperture_remove_conflicting_devices() 126*11d79c47SEmmanuel Vadot * et al for the registered framebuffer range, the aperture helpers call 127*11d79c47SEmmanuel Vadot * platform_device_unregister() and the generic driver unloads itself. The 128*11d79c47SEmmanuel Vadot * generic driver also has to provide a remove function to make this work. 129*11d79c47SEmmanuel Vadot * Once hot unplugged fro mhardware, it may not access the device's 130*11d79c47SEmmanuel Vadot * registers, framebuffer memory, ROM, etc afterwards. 131*11d79c47SEmmanuel Vadot */ 132*11d79c47SEmmanuel Vadot 133*11d79c47SEmmanuel Vadot struct aperture_range { 134*11d79c47SEmmanuel Vadot struct device *dev; 135*11d79c47SEmmanuel Vadot resource_size_t base; 136*11d79c47SEmmanuel Vadot resource_size_t size; 137*11d79c47SEmmanuel Vadot struct list_head lh; 138*11d79c47SEmmanuel Vadot void (*detach)(struct device *dev); 139*11d79c47SEmmanuel Vadot }; 140*11d79c47SEmmanuel Vadot 141*11d79c47SEmmanuel Vadot static LIST_HEAD(apertures); 142*11d79c47SEmmanuel Vadot static DEFINE_MUTEX(apertures_lock); 143*11d79c47SEmmanuel Vadot 144*11d79c47SEmmanuel Vadot static bool overlap(resource_size_t base1, resource_size_t end1, 145*11d79c47SEmmanuel Vadot resource_size_t base2, resource_size_t end2) 146*11d79c47SEmmanuel Vadot { 147*11d79c47SEmmanuel Vadot return (base1 < end2) && (end1 > base2); 148*11d79c47SEmmanuel Vadot } 149*11d79c47SEmmanuel Vadot 150*11d79c47SEmmanuel Vadot static void devm_aperture_acquire_release(void *data) 151*11d79c47SEmmanuel Vadot { 152*11d79c47SEmmanuel Vadot struct aperture_range *ap = data; 153*11d79c47SEmmanuel Vadot bool detached = !ap->dev; 154*11d79c47SEmmanuel Vadot 155*11d79c47SEmmanuel Vadot if (detached) 156*11d79c47SEmmanuel Vadot return; 157*11d79c47SEmmanuel Vadot 158*11d79c47SEmmanuel Vadot mutex_lock(&apertures_lock); 159*11d79c47SEmmanuel Vadot list_del(&ap->lh); 160*11d79c47SEmmanuel Vadot mutex_unlock(&apertures_lock); 161*11d79c47SEmmanuel Vadot } 162*11d79c47SEmmanuel Vadot 163*11d79c47SEmmanuel Vadot static int devm_aperture_acquire(struct device *dev, 164*11d79c47SEmmanuel Vadot resource_size_t base, resource_size_t size, 165*11d79c47SEmmanuel Vadot void (*detach)(struct device *)) 166*11d79c47SEmmanuel Vadot { 167*11d79c47SEmmanuel Vadot size_t end = base + size; 168*11d79c47SEmmanuel Vadot struct list_head *pos; 169*11d79c47SEmmanuel Vadot struct aperture_range *ap; 170*11d79c47SEmmanuel Vadot 171*11d79c47SEmmanuel Vadot mutex_lock(&apertures_lock); 172*11d79c47SEmmanuel Vadot 173*11d79c47SEmmanuel Vadot list_for_each(pos, &apertures) { 174*11d79c47SEmmanuel Vadot ap = container_of(pos, struct aperture_range, lh); 175*11d79c47SEmmanuel Vadot if (overlap(base, end, ap->base, ap->base + ap->size)) { 176*11d79c47SEmmanuel Vadot mutex_unlock(&apertures_lock); 177*11d79c47SEmmanuel Vadot return -EBUSY; 178*11d79c47SEmmanuel Vadot } 179*11d79c47SEmmanuel Vadot } 180*11d79c47SEmmanuel Vadot 181*11d79c47SEmmanuel Vadot ap = devm_kzalloc(dev, sizeof(*ap), GFP_KERNEL); 182*11d79c47SEmmanuel Vadot if (!ap) { 183*11d79c47SEmmanuel Vadot mutex_unlock(&apertures_lock); 184*11d79c47SEmmanuel Vadot return -ENOMEM; 185*11d79c47SEmmanuel Vadot } 186*11d79c47SEmmanuel Vadot 187*11d79c47SEmmanuel Vadot ap->dev = dev; 188*11d79c47SEmmanuel Vadot ap->base = base; 189*11d79c47SEmmanuel Vadot ap->size = size; 190*11d79c47SEmmanuel Vadot ap->detach = detach; 191*11d79c47SEmmanuel Vadot INIT_LIST_HEAD(&ap->lh); 192*11d79c47SEmmanuel Vadot 193*11d79c47SEmmanuel Vadot list_add(&ap->lh, &apertures); 194*11d79c47SEmmanuel Vadot 195*11d79c47SEmmanuel Vadot mutex_unlock(&apertures_lock); 196*11d79c47SEmmanuel Vadot 197*11d79c47SEmmanuel Vadot return devm_add_action_or_reset(dev, devm_aperture_acquire_release, ap); 198*11d79c47SEmmanuel Vadot } 199*11d79c47SEmmanuel Vadot 200*11d79c47SEmmanuel Vadot static void aperture_detach_platform_device(struct device *dev) 201*11d79c47SEmmanuel Vadot { 202*11d79c47SEmmanuel Vadot struct platform_device *pdev = to_platform_device(dev); 203*11d79c47SEmmanuel Vadot 204*11d79c47SEmmanuel Vadot /* 205*11d79c47SEmmanuel Vadot * Remove the device from the device hierarchy. This is the right thing 206*11d79c47SEmmanuel Vadot * to do for firmware-based DRM drivers, such as EFI, VESA or VGA. After 207*11d79c47SEmmanuel Vadot * the new driver takes over the hardware, the firmware device's state 208*11d79c47SEmmanuel Vadot * will be lost. 209*11d79c47SEmmanuel Vadot * 210*11d79c47SEmmanuel Vadot * For non-platform devices, a new callback would be required. 211*11d79c47SEmmanuel Vadot * 212*11d79c47SEmmanuel Vadot * If the aperture helpers ever need to handle native drivers, this call 213*11d79c47SEmmanuel Vadot * would only have to unplug the DRM device, so that the hardware device 214*11d79c47SEmmanuel Vadot * stays around after detachment. 215*11d79c47SEmmanuel Vadot */ 216*11d79c47SEmmanuel Vadot platform_device_unregister(pdev); 217*11d79c47SEmmanuel Vadot } 218*11d79c47SEmmanuel Vadot 219*11d79c47SEmmanuel Vadot /** 220*11d79c47SEmmanuel Vadot * devm_aperture_acquire_for_platform_device - Acquires ownership of an aperture 221*11d79c47SEmmanuel Vadot * on behalf of a platform device. 222*11d79c47SEmmanuel Vadot * @pdev: the platform device to own the aperture 223*11d79c47SEmmanuel Vadot * @base: the aperture's byte offset in physical memory 224*11d79c47SEmmanuel Vadot * @size: the aperture size in bytes 225*11d79c47SEmmanuel Vadot * 226*11d79c47SEmmanuel Vadot * Installs the given device as the new owner of the aperture. The function 227*11d79c47SEmmanuel Vadot * expects the aperture to be provided by a platform device. If another 228*11d79c47SEmmanuel Vadot * driver takes over ownership of the aperture, aperture helpers will then 229*11d79c47SEmmanuel Vadot * unregister the platform device automatically. All acquired apertures are 230*11d79c47SEmmanuel Vadot * released automatically when the underlying device goes away. 231*11d79c47SEmmanuel Vadot * 232*11d79c47SEmmanuel Vadot * The function fails if the aperture, or parts of it, is currently 233*11d79c47SEmmanuel Vadot * owned by another device. To evict current owners, callers should use 234*11d79c47SEmmanuel Vadot * remove_conflicting_devices() et al. before calling this function. 235*11d79c47SEmmanuel Vadot * 236*11d79c47SEmmanuel Vadot * Returns: 237*11d79c47SEmmanuel Vadot * 0 on success, or a negative errno value otherwise. 238*11d79c47SEmmanuel Vadot */ 239*11d79c47SEmmanuel Vadot int devm_aperture_acquire_for_platform_device(struct platform_device *pdev, 240*11d79c47SEmmanuel Vadot resource_size_t base, 241*11d79c47SEmmanuel Vadot resource_size_t size) 242*11d79c47SEmmanuel Vadot { 243*11d79c47SEmmanuel Vadot return devm_aperture_acquire(&pdev->dev, base, size, aperture_detach_platform_device); 244*11d79c47SEmmanuel Vadot } 245*11d79c47SEmmanuel Vadot EXPORT_SYMBOL(devm_aperture_acquire_for_platform_device); 246*11d79c47SEmmanuel Vadot 247*11d79c47SEmmanuel Vadot static void aperture_detach_devices(resource_size_t base, resource_size_t size) 248*11d79c47SEmmanuel Vadot { 249*11d79c47SEmmanuel Vadot resource_size_t end = base + size; 250*11d79c47SEmmanuel Vadot struct list_head *pos, *n; 251*11d79c47SEmmanuel Vadot 252*11d79c47SEmmanuel Vadot mutex_lock(&apertures_lock); 253*11d79c47SEmmanuel Vadot 254*11d79c47SEmmanuel Vadot list_for_each_safe(pos, n, &apertures) { 255*11d79c47SEmmanuel Vadot struct aperture_range *ap = container_of(pos, struct aperture_range, lh); 256*11d79c47SEmmanuel Vadot struct device *dev = ap->dev; 257*11d79c47SEmmanuel Vadot 258*11d79c47SEmmanuel Vadot if (WARN_ON_ONCE(!dev)) 259*11d79c47SEmmanuel Vadot continue; 260*11d79c47SEmmanuel Vadot 261*11d79c47SEmmanuel Vadot if (!overlap(base, end, ap->base, ap->base + ap->size)) 262*11d79c47SEmmanuel Vadot continue; 263*11d79c47SEmmanuel Vadot 264*11d79c47SEmmanuel Vadot ap->dev = NULL; /* detach from device */ 265*11d79c47SEmmanuel Vadot list_del(&ap->lh); 266*11d79c47SEmmanuel Vadot 267*11d79c47SEmmanuel Vadot ap->detach(dev); 268*11d79c47SEmmanuel Vadot } 269*11d79c47SEmmanuel Vadot 270*11d79c47SEmmanuel Vadot mutex_unlock(&apertures_lock); 271*11d79c47SEmmanuel Vadot } 272*11d79c47SEmmanuel Vadot 273*11d79c47SEmmanuel Vadot /** 274*11d79c47SEmmanuel Vadot * aperture_remove_conflicting_devices - remove devices in the given range 275*11d79c47SEmmanuel Vadot * @base: the aperture's base address in physical memory 276*11d79c47SEmmanuel Vadot * @size: aperture size in bytes 277*11d79c47SEmmanuel Vadot * @primary: also kick vga16fb if present; only relevant for VGA devices 278*11d79c47SEmmanuel Vadot * @name: a descriptive name of the requesting driver 279*11d79c47SEmmanuel Vadot * 280*11d79c47SEmmanuel Vadot * This function removes devices that own apertures within @base and @size. 281*11d79c47SEmmanuel Vadot * 282*11d79c47SEmmanuel Vadot * Returns: 283*11d79c47SEmmanuel Vadot * 0 on success, or a negative errno code otherwise 284*11d79c47SEmmanuel Vadot */ 285*11d79c47SEmmanuel Vadot int aperture_remove_conflicting_devices(resource_size_t base, resource_size_t size, 286*11d79c47SEmmanuel Vadot bool primary, const char *name) 287*11d79c47SEmmanuel Vadot { 288*11d79c47SEmmanuel Vadot /* 289*11d79c47SEmmanuel Vadot * If a driver asked to unregister a platform device registered by 290*11d79c47SEmmanuel Vadot * sysfb, then can be assumed that this is a driver for a display 291*11d79c47SEmmanuel Vadot * that is set up by the system firmware and has a generic driver. 292*11d79c47SEmmanuel Vadot * 293*11d79c47SEmmanuel Vadot * Drivers for devices that don't have a generic driver will never 294*11d79c47SEmmanuel Vadot * ask for this, so let's assume that a real driver for the display 295*11d79c47SEmmanuel Vadot * was already probed and prevent sysfb to register devices later. 296*11d79c47SEmmanuel Vadot */ 297*11d79c47SEmmanuel Vadot #ifdef __linux__ 298*11d79c47SEmmanuel Vadot sysfb_disable(); 299*11d79c47SEmmanuel Vadot #endif 300*11d79c47SEmmanuel Vadot 301*11d79c47SEmmanuel Vadot aperture_detach_devices(base, size); 302*11d79c47SEmmanuel Vadot 303*11d79c47SEmmanuel Vadot /* 304*11d79c47SEmmanuel Vadot * If this is the primary adapter, there could be a VGA device 305*11d79c47SEmmanuel Vadot * that consumes the VGA framebuffer I/O range. Remove this device 306*11d79c47SEmmanuel Vadot * as well. 307*11d79c47SEmmanuel Vadot */ 308*11d79c47SEmmanuel Vadot if (primary) 309*11d79c47SEmmanuel Vadot aperture_detach_devices(VGA_FB_PHYS_BASE, VGA_FB_PHYS_SIZE); 310*11d79c47SEmmanuel Vadot 311*11d79c47SEmmanuel Vadot return 0; 312*11d79c47SEmmanuel Vadot } 313*11d79c47SEmmanuel Vadot EXPORT_SYMBOL(aperture_remove_conflicting_devices); 314*11d79c47SEmmanuel Vadot 315*11d79c47SEmmanuel Vadot /** 316*11d79c47SEmmanuel Vadot * aperture_remove_conflicting_pci_devices - remove existing framebuffers for PCI devices 317*11d79c47SEmmanuel Vadot * @pdev: PCI device 318*11d79c47SEmmanuel Vadot * @name: a descriptive name of the requesting driver 319*11d79c47SEmmanuel Vadot * 320*11d79c47SEmmanuel Vadot * This function removes devices that own apertures within any of @pdev's 321*11d79c47SEmmanuel Vadot * memory bars. The function assumes that PCI device with shadowed ROM 322*11d79c47SEmmanuel Vadot * drives a primary display and therefore kicks out vga16fb as well. 323*11d79c47SEmmanuel Vadot * 324*11d79c47SEmmanuel Vadot * Returns: 325*11d79c47SEmmanuel Vadot * 0 on success, or a negative errno code otherwise 326*11d79c47SEmmanuel Vadot */ 327*11d79c47SEmmanuel Vadot int aperture_remove_conflicting_pci_devices(struct pci_dev *pdev, const char *name) 328*11d79c47SEmmanuel Vadot { 329*11d79c47SEmmanuel Vadot bool primary = false; 330*11d79c47SEmmanuel Vadot resource_size_t base, size; 331*11d79c47SEmmanuel Vadot int bar, ret; 332*11d79c47SEmmanuel Vadot 333*11d79c47SEmmanuel Vadot #ifdef CONFIG_X86 334*11d79c47SEmmanuel Vadot #ifdef __linux__ 335*11d79c47SEmmanuel Vadot primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; 336*11d79c47SEmmanuel Vadot #elif defined(__FreeBSD__) 337*11d79c47SEmmanuel Vadot primary = NULL; 338*11d79c47SEmmanuel Vadot #endif 339*11d79c47SEmmanuel Vadot #endif 340*11d79c47SEmmanuel Vadot 341*11d79c47SEmmanuel Vadot for (bar = 0; bar < PCI_STD_NUM_BARS; ++bar) { 342*11d79c47SEmmanuel Vadot if (!(pci_resource_flags(pdev, bar) & IORESOURCE_MEM)) 343*11d79c47SEmmanuel Vadot continue; 344*11d79c47SEmmanuel Vadot 345*11d79c47SEmmanuel Vadot base = pci_resource_start(pdev, bar); 346*11d79c47SEmmanuel Vadot size = pci_resource_len(pdev, bar); 347*11d79c47SEmmanuel Vadot ret = aperture_remove_conflicting_devices(base, size, primary, name); 348*11d79c47SEmmanuel Vadot if (ret) 349*11d79c47SEmmanuel Vadot return ret; 350*11d79c47SEmmanuel Vadot } 351*11d79c47SEmmanuel Vadot 352*11d79c47SEmmanuel Vadot /* 353*11d79c47SEmmanuel Vadot * WARNING: Apparently we must kick fbdev drivers before vgacon, 354*11d79c47SEmmanuel Vadot * otherwise the vga fbdev driver falls over. 355*11d79c47SEmmanuel Vadot */ 356*11d79c47SEmmanuel Vadot #ifdef __linux__ 357*11d79c47SEmmanuel Vadot ret = vga_remove_vgacon(pdev); 358*11d79c47SEmmanuel Vadot if (ret) 359*11d79c47SEmmanuel Vadot return ret; 360*11d79c47SEmmanuel Vadot #endif 361*11d79c47SEmmanuel Vadot 362*11d79c47SEmmanuel Vadot return 0; 363*11d79c47SEmmanuel Vadot 364*11d79c47SEmmanuel Vadot } 365*11d79c47SEmmanuel Vadot EXPORT_SYMBOL(aperture_remove_conflicting_pci_devices); 366