diff mbox

[v5,5/7] drm: switch to sysfb_evict_conflicts()

Message ID 20160902082245.7119-6-dh.herrmann@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

David Herrmann Sept. 2, 2016, 8:22 a.m. UTC
Switch over all DRM drivers to use the new sysfb_evict_conflicts()
infrastructure. The only non-trivial conversion is i915, since it does not
make use of the generic PCI resources, but assembles the apertures via
intel ggtt queries.

Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
---
 drivers/gpu/drm/Kconfig                  |  1 +
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c  | 24 +----------
 drivers/gpu/drm/bochs/bochs_drv.c        | 19 +--------
 drivers/gpu/drm/i915/i915_drv.c          | 73 ++++++--------------------------
 drivers/gpu/drm/mgag200/mgag200_drv.c    | 27 +++---------
 drivers/gpu/drm/mgag200/mgag200_main.c   |  9 ----
 drivers/gpu/drm/nouveau/nouveau_drm.c    | 33 +++------------
 drivers/gpu/drm/radeon/radeon_drv.c      | 24 +----------
 drivers/gpu/drm/sun4i/sun4i_drv.c        | 24 +++--------
 drivers/gpu/drm/vc4/vc4_drv.c            | 25 +++--------
 drivers/gpu/drm/virtio/virtgpu_drm_bus.c | 24 +----------
 11 files changed, 44 insertions(+), 239 deletions(-)

Comments

Noralf Trønnes Sept. 3, 2016, 12:13 p.m. UTC | #1
Den 02.09.2016 10:22, skrev David Herrmann:
> Switch over all DRM drivers to use the new sysfb_evict_conflicts()
> infrastructure. The only non-trivial conversion is i915, since it does not
> make use of the generic PCI resources, but assembles the apertures via
> intel ggtt queries.
>
> Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
> ---

This doesn't apply now with Daniel's wrapper added:
drm_fb_helper_remove_conflicting_framebuffers().

Noralf.

>   drivers/gpu/drm/Kconfig                  |  1 +
>   drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c  | 24 +----------
>   drivers/gpu/drm/bochs/bochs_drv.c        | 19 +--------
>   drivers/gpu/drm/i915/i915_drv.c          | 73 ++++++--------------------------
>   drivers/gpu/drm/mgag200/mgag200_drv.c    | 27 +++---------
>   drivers/gpu/drm/mgag200/mgag200_main.c   |  9 ----
>   drivers/gpu/drm/nouveau/nouveau_drm.c    | 33 +++------------
>   drivers/gpu/drm/radeon/radeon_drv.c      | 24 +----------
>   drivers/gpu/drm/sun4i/sun4i_drv.c        | 24 +++--------
>   drivers/gpu/drm/vc4/vc4_drv.c            | 25 +++--------
>   drivers/gpu/drm/virtio/virtgpu_drm_bus.c | 24 +----------
>   11 files changed, 44 insertions(+), 239 deletions(-)
>
> diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
> index fc35731..f27f9b5 100644
> --- a/drivers/gpu/drm/Kconfig
> +++ b/drivers/gpu/drm/Kconfig
> @@ -12,6 +12,7 @@ menuconfig DRM
>   	select I2C
>   	select I2C_ALGOBIT
>   	select DMA_SHARED_BUFFER
> +	select SYSFB
>   	help
>   	  Kernel-level support for the Direct Rendering Infrastructure (DRI)
>   	  introduced in XFree86 4.0. If you say Y here, you need to select
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> index 9aa533c..a1e67da 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
> @@ -38,6 +38,7 @@
>   #include <linux/console.h>
>   #include <linux/module.h>
>   #include <linux/pm_runtime.h>
> +#include <linux/sysfb.h>
>   #include <linux/vga_switcheroo.h>
>   #include "drm_crtc_helper.h"
>   
> @@ -326,27 +327,6 @@ MODULE_DEVICE_TABLE(pci, pciidlist);
>   
>   static struct drm_driver kms_driver;
>   
> -static int amdgpu_kick_out_firmware_fb(struct pci_dev *pdev)
> -{
> -	struct apertures_struct *ap;
> -	bool primary = false;
> -
> -	ap = alloc_apertures(1);
> -	if (!ap)
> -		return -ENOMEM;
> -
> -	ap->ranges[0].base = pci_resource_start(pdev, 0);
> -	ap->ranges[0].size = pci_resource_len(pdev, 0);
> -
> -#ifdef CONFIG_X86
> -	primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
> -#endif
> -	remove_conflicting_framebuffers(ap, "amdgpudrmfb", primary);
> -	kfree(ap);
> -
> -	return 0;
> -}
> -
>   static int amdgpu_pci_probe(struct pci_dev *pdev,
>   			    const struct pci_device_id *ent)
>   {
> @@ -368,7 +348,7 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
>   		return ret;
>   
>   	/* Get rid of things like offb */
> -	ret = amdgpu_kick_out_firmware_fb(pdev);
> +	ret = sysfb_evict_conflicts_pci(pdev);
>   	if (ret)
>   		return ret;
>   
> diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c
> index abace82..99c4ea3 100644
> --- a/drivers/gpu/drm/bochs/bochs_drv.c
> +++ b/drivers/gpu/drm/bochs/bochs_drv.c
> @@ -8,6 +8,7 @@
>   #include <linux/mm.h>
>   #include <linux/module.h>
>   #include <linux/slab.h>
> +#include <linux/sysfb.h>
>   
>   #include "bochs.h"
>   
> @@ -143,28 +144,12 @@ static const struct dev_pm_ops bochs_pm_ops = {
>   /* ---------------------------------------------------------------------- */
>   /* pci interface                                                          */
>   
> -static int bochs_kick_out_firmware_fb(struct pci_dev *pdev)
> -{
> -	struct apertures_struct *ap;
> -
> -	ap = alloc_apertures(1);
> -	if (!ap)
> -		return -ENOMEM;
> -
> -	ap->ranges[0].base = pci_resource_start(pdev, 0);
> -	ap->ranges[0].size = pci_resource_len(pdev, 0);
> -	remove_conflicting_framebuffers(ap, "bochsdrmfb", false);
> -	kfree(ap);
> -
> -	return 0;
> -}
> -
>   static int bochs_pci_probe(struct pci_dev *pdev,
>   			   const struct pci_device_id *ent)
>   {
>   	int ret;
>   
> -	ret = bochs_kick_out_firmware_fb(pdev);
> +	ret = sysfb_evict_conflicts_pci(pdev);
>   	if (ret)
>   		return ret;
>   
> diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
> index 95ddd56..4d6a65dd 100644
> --- a/drivers/gpu/drm/i915/i915_drv.c
> +++ b/drivers/gpu/drm/i915/i915_drv.c
> @@ -36,6 +36,7 @@
>   #include <linux/pm_runtime.h>
>   #include <linux/pnp.h>
>   #include <linux/slab.h>
> +#include <linux/sysfb.h>
>   #include <linux/vgaarb.h>
>   #include <linux/vga_switcheroo.h>
>   #include <linux/vt.h>
> @@ -687,70 +688,32 @@ out:
>   	return ret;
>   }
>   
> -#if IS_ENABLED(CONFIG_FB)
>   static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
>   {
> -	struct apertures_struct *ap;
> +	struct sysfb_evict_ctx ctx = {};
>   	struct pci_dev *pdev = dev_priv->drm.pdev;
>   	struct i915_ggtt *ggtt = &dev_priv->ggtt;
> -	bool primary;
>   	int ret;
>   
> -	ap = alloc_apertures(1);
> -	if (!ap)
> -		return -ENOMEM;
> -
> -	ap->ranges[0].base = ggtt->mappable_base;
> -	ap->ranges[0].size = ggtt->mappable_end;
> -
> -	primary =
> -		pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
> -
> -	ret = remove_conflicting_framebuffers(ap, "inteldrmfb", primary);
> -
> -	kfree(ap);
> -
> -	return ret;
> -}
> -#else
> -static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
> -{
> -	return 0;
> -}
> -#endif
> +	ctx.flags = SYSFB_EVICT_PLATFORM |
> +		    SYSFB_EVICT_FBDEV |
> +		    SYSFB_EVICT_VGACON;
>   
> -#if !defined(CONFIG_VGA_CONSOLE)
> -static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
> -{
> -	return 0;
> -}
> -#elif !defined(CONFIG_DUMMY_CONSOLE)
> -static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
> -{
> -	return -ENODEV;
> -}
> -#else
> -static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
> -{
> -	int ret = 0;
> +	ctx.ap = alloc_apertures(1);
> +	if (!ctx.ap)
> +		return -ENOMEM;
>   
> -	DRM_INFO("Replacing VGA console driver\n");
> +	ctx.ap->ranges[0].base = ggtt->mappable_base;
> +	ctx.ap->ranges[0].size = ggtt->mappable_end;
>   
> -	console_lock();
> -	if (con_is_bound(&vga_con))
> -		ret = do_take_over_console(&dummy_con, 0, MAX_NR_CONSOLES - 1, 1);
> -	if (ret == 0) {
> -		ret = do_unregister_con_driver(&vga_con);
> +	if (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)
> +		ctx.flags |= SYSFB_EVICT_VBE;
>   
> -		/* Ignore "already unregistered". */
> -		if (ret == -ENODEV)
> -			ret = 0;
> -	}
> -	console_unlock();
> +	ret = sysfb_evict_conflicts(&ctx);
>   
> +	kfree(ctx.ap);
>   	return ret;
>   }
> -#endif
>   
>   static void intel_init_dpio(struct drm_i915_private *dev_priv)
>   {
> @@ -1032,20 +995,12 @@ static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
>   		goto out_ggtt;
>   	}
>   
> -	/* WARNING: Apparently we must kick fbdev drivers before vgacon,
> -	 * otherwise the vga fbdev driver falls over. */
>   	ret = i915_kick_out_firmware_fb(dev_priv);
>   	if (ret) {
>   		DRM_ERROR("failed to remove conflicting framebuffer drivers\n");
>   		goto out_ggtt;
>   	}
>   
> -	ret = i915_kick_out_vgacon(dev_priv);
> -	if (ret) {
> -		DRM_ERROR("failed to remove conflicting VGA console\n");
> -		goto out_ggtt;
> -	}
> -
>   	pci_set_master(dev->pdev);
>   
>   	/* overlay on gen2 is broken and can't address above 1G */
> diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
> index 2b4b125..f30105b 100644
> --- a/drivers/gpu/drm/mgag200/mgag200_drv.c
> +++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
> @@ -10,6 +10,7 @@
>    */
>   #include <linux/module.h>
>   #include <linux/console.h>
> +#include <linux/sysfb.h>
>   #include <drm/drmP.h>
>   
>   #include "mgag200_drv.h"
> @@ -41,29 +42,13 @@ static const struct pci_device_id pciidlist[] = {
>   
>   MODULE_DEVICE_TABLE(pci, pciidlist);
>   
> -static void mgag200_kick_out_firmware_fb(struct pci_dev *pdev)
> -{
> -	struct apertures_struct *ap;
> -	bool primary = false;
> -
> -	ap = alloc_apertures(1);
> -	if (!ap)
> -		return;
> -
> -	ap->ranges[0].base = pci_resource_start(pdev, 0);
> -	ap->ranges[0].size = pci_resource_len(pdev, 0);
> -
> -#ifdef CONFIG_X86
> -	primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
> -#endif
> -	remove_conflicting_framebuffers(ap, "mgag200drmfb", primary);
> -	kfree(ap);
> -}
> -
> -
>   static int mga_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>   {
> -	mgag200_kick_out_firmware_fb(pdev);
> +	int ret;
> +
> +	ret = sysfb_evict_conflicts_pci(pdev);
> +	if (ret < 0)
> +		return ret;
>   
>   	return drm_get_pci_dev(pdev, ent, &driver);
>   }
> diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c
> index 13798b3..4723407 100644
> --- a/drivers/gpu/drm/mgag200/mgag200_main.c
> +++ b/drivers/gpu/drm/mgag200/mgag200_main.c
> @@ -124,20 +124,11 @@ static int mga_probe_vram(struct mga_device *mdev, void __iomem *mem)
>   static int mga_vram_init(struct mga_device *mdev)
>   {
>   	void __iomem *mem;
> -	struct apertures_struct *aper = alloc_apertures(1);
> -	if (!aper)
> -		return -ENOMEM;
>   
>   	/* BAR 0 is VRAM */
>   	mdev->mc.vram_base = pci_resource_start(mdev->dev->pdev, 0);
>   	mdev->mc.vram_window = pci_resource_len(mdev->dev->pdev, 0);
>   
> -	aper->ranges[0].base = mdev->mc.vram_base;
> -	aper->ranges[0].size = mdev->mc.vram_window;
> -
> -	remove_conflicting_framebuffers(aper, "mgafb", true);
> -	kfree(aper);
> -
>   	if (!devm_request_mem_region(mdev->dev->dev, mdev->mc.vram_base, mdev->mc.vram_window,
>   				"mgadrmfb_vram")) {
>   		DRM_ERROR("can't reserve VRAM\n");
> diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
> index 66c1280..193e833 100644
> --- a/drivers/gpu/drm/nouveau/nouveau_drm.c
> +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
> @@ -27,6 +27,7 @@
>   #include <linux/module.h>
>   #include <linux/pci.h>
>   #include <linux/pm_runtime.h>
> +#include <linux/sysfb.h>
>   #include <linux/vga_switcheroo.h>
>   
>   #include "drmP.h"
> @@ -310,8 +311,6 @@ static int nouveau_drm_probe(struct pci_dev *pdev,
>   			     const struct pci_device_id *pent)
>   {
>   	struct nvkm_device *device;
> -	struct apertures_struct *aper;
> -	bool boot = false;
>   	int ret;
>   
>   	if (vga_switcheroo_client_probe_defer(pdev))
> @@ -326,34 +325,12 @@ static int nouveau_drm_probe(struct pci_dev *pdev,
>   
>   	nvkm_device_del(&device);
>   
> -	/* Remove conflicting drivers (vesafb, efifb etc). */
> -	aper = alloc_apertures(3);
> -	if (!aper)
> -		return -ENOMEM;
> -
> -	aper->ranges[0].base = pci_resource_start(pdev, 1);
> -	aper->ranges[0].size = pci_resource_len(pdev, 1);
> -	aper->count = 1;
> -
> -	if (pci_resource_len(pdev, 2)) {
> -		aper->ranges[aper->count].base = pci_resource_start(pdev, 2);
> -		aper->ranges[aper->count].size = pci_resource_len(pdev, 2);
> -		aper->count++;
> -	}
> -
> -	if (pci_resource_len(pdev, 3)) {
> -		aper->ranges[aper->count].base = pci_resource_start(pdev, 3);
> -		aper->ranges[aper->count].size = pci_resource_len(pdev, 3);
> -		aper->count++;
> +	if (nouveau_modeset != 2) {
> +		ret = sysfb_evict_conflicts_pci(pdev);
> +		if (ret < 0)
> +			return ret;
>   	}
>   
> -#ifdef CONFIG_X86
> -	boot = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
> -#endif
> -	if (nouveau_modeset != 2)
> -		remove_conflicting_framebuffers(aper, "nouveaufb", boot);
> -	kfree(aper);
> -
>   	ret = nvkm_device_pci_new(pdev, nouveau_config, nouveau_debug,
>   				  true, true, ~0ULL, &device);
>   	if (ret)
> diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
> index c01a7c6..a0c11bd 100644
> --- a/drivers/gpu/drm/radeon/radeon_drv.c
> +++ b/drivers/gpu/drm/radeon/radeon_drv.c
> @@ -37,6 +37,7 @@
>   #include <linux/console.h>
>   #include <linux/module.h>
>   #include <linux/pm_runtime.h>
> +#include <linux/sysfb.h>
>   #include <linux/vga_switcheroo.h>
>   #include <drm/drm_gem.h>
>   
> @@ -309,27 +310,6 @@ MODULE_DEVICE_TABLE(pci, pciidlist);
>   
>   static struct drm_driver kms_driver;
>   
> -static int radeon_kick_out_firmware_fb(struct pci_dev *pdev)
> -{
> -	struct apertures_struct *ap;
> -	bool primary = false;
> -
> -	ap = alloc_apertures(1);
> -	if (!ap)
> -		return -ENOMEM;
> -
> -	ap->ranges[0].base = pci_resource_start(pdev, 0);
> -	ap->ranges[0].size = pci_resource_len(pdev, 0);
> -
> -#ifdef CONFIG_X86
> -	primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
> -#endif
> -	remove_conflicting_framebuffers(ap, "radeondrmfb", primary);
> -	kfree(ap);
> -
> -	return 0;
> -}
> -
>   static int radeon_pci_probe(struct pci_dev *pdev,
>   			    const struct pci_device_id *ent)
>   {
> @@ -347,7 +327,7 @@ static int radeon_pci_probe(struct pci_dev *pdev,
>   		return -EPROBE_DEFER;
>   
>   	/* Get rid of things like offb */
> -	ret = radeon_kick_out_firmware_fb(pdev);
> +	ret = sysfb_evict_conflicts_pci(pdev);
>   	if (ret)
>   		return ret;
>   
> diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
> index 7092daa..ac388b5 100644
> --- a/drivers/gpu/drm/sun4i/sun4i_drv.c
> +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
> @@ -12,6 +12,7 @@
>   
>   #include <linux/component.h>
>   #include <linux/of_graph.h>
> +#include <linux/sysfb.h>
>   
>   #include <drm/drmP.h>
>   #include <drm/drm_crtc_helper.h>
> @@ -97,28 +98,16 @@ static struct drm_driver sun4i_drv_driver = {
>   	.disable_vblank		= sun4i_drv_disable_vblank,
>   };
>   
> -static void sun4i_remove_framebuffers(void)
> -{
> -	struct apertures_struct *ap;
> -
> -	ap = alloc_apertures(1);
> -	if (!ap)
> -		return;
> -
> -	/* The framebuffer can be located anywhere in RAM */
> -	ap->ranges[0].base = 0;
> -	ap->ranges[0].size = ~0;
> -
> -	remove_conflicting_framebuffers(ap, "sun4i-drm-fb", false);
> -	kfree(ap);
> -}
> -
>   static int sun4i_drv_bind(struct device *dev)
>   {
>   	struct drm_device *drm;
>   	struct sun4i_drv *drv;
>   	int ret;
>   
> +	ret = sysfb_evict_conflicts_firmware();
> +	if (ret < 0)
> +		return ret;
> +
>   	drm = drm_dev_alloc(&sun4i_drv_driver, dev);
>   	if (!drm)
>   		return -ENOMEM;
> @@ -156,9 +145,6 @@ static int sun4i_drv_bind(struct device *dev)
>   	}
>   	drm->irq_enabled = true;
>   
> -	/* Remove early framebuffers (ie. simplefb) */
> -	sun4i_remove_framebuffers();
> -
>   	/* Create our framebuffer */
>   	drv->fbdev = sun4i_framebuffer_init(drm);
>   	if (IS_ERR(drv->fbdev)) {
> diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
> index 8b42d31..679e65a 100644
> --- a/drivers/gpu/drm/vc4/vc4_drv.c
> +++ b/drivers/gpu/drm/vc4/vc4_drv.c
> @@ -15,6 +15,7 @@
>   #include <linux/of_platform.h>
>   #include <linux/platform_device.h>
>   #include <linux/pm_runtime.h>
> +#include <linux/sysfb.h>
>   #include "drm_fb_cma_helper.h"
>   
>   #include "uapi/drm/vc4_drm.h"
> @@ -200,24 +201,6 @@ static void vc4_match_add_drivers(struct device *dev,
>   	}
>   }
>   
> -static void vc4_kick_out_firmware_fb(void)
> -{
> -	struct apertures_struct *ap;
> -
> -	ap = alloc_apertures(1);
> -	if (!ap)
> -		return;
> -
> -	/* Since VC4 is a UMA device, the simplefb node may have been
> -	 * located anywhere in memory.
> -	 */
> -	ap->ranges[0].base = 0;
> -	ap->ranges[0].size = ~0;
> -
> -	remove_conflicting_framebuffers(ap, "vc4drmfb", false);
> -	kfree(ap);
> -}
> -
>   static int vc4_drm_bind(struct device *dev)
>   {
>   	struct platform_device *pdev = to_platform_device(dev);
> @@ -225,6 +208,10 @@ static int vc4_drm_bind(struct device *dev)
>   	struct vc4_dev *vc4;
>   	int ret = 0;
>   
> +	ret = sysfb_evict_conflicts_firmware();
> +	if (ret < 0)
> +		return ret;
> +
>   	dev->coherent_dma_mask = DMA_BIT_MASK(32);
>   
>   	vc4 = devm_kzalloc(dev, sizeof(*vc4), GFP_KERNEL);
> @@ -248,8 +235,6 @@ static int vc4_drm_bind(struct device *dev)
>   	if (ret)
>   		goto gem_destroy;
>   
> -	vc4_kick_out_firmware_fb();
> -
>   	ret = drm_dev_register(drm, 0);
>   	if (ret < 0)
>   		goto unbind_all;
> diff --git a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c b/drivers/gpu/drm/virtio/virtgpu_drm_bus.c
> index 7f0e93f87..d6a8a94 100644
> --- a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c
> +++ b/drivers/gpu/drm/virtio/virtgpu_drm_bus.c
> @@ -24,29 +24,10 @@
>    */
>   
>   #include <linux/pci.h>
> +#include <linux/sysfb.h>
>   
>   #include "virtgpu_drv.h"
>   
> -static void virtio_pci_kick_out_firmware_fb(struct pci_dev *pci_dev)
> -{
> -	struct apertures_struct *ap;
> -	bool primary;
> -
> -	ap = alloc_apertures(1);
> -	if (!ap)
> -		return;
> -
> -	ap->ranges[0].base = pci_resource_start(pci_dev, 0);
> -	ap->ranges[0].size = pci_resource_len(pci_dev, 0);
> -
> -	primary = pci_dev->resource[PCI_ROM_RESOURCE].flags
> -		& IORESOURCE_ROM_SHADOW;
> -
> -	remove_conflicting_framebuffers(ap, "virtiodrmfb", primary);
> -
> -	kfree(ap);
> -}
> -
>   int drm_virtio_init(struct drm_driver *driver, struct virtio_device *vdev)
>   {
>   	struct drm_device *dev;
> @@ -65,8 +46,7 @@ int drm_virtio_init(struct drm_driver *driver, struct virtio_device *vdev)
>   		DRM_INFO("pci: %s detected\n",
>   			 vga ? "virtio-vga" : "virtio-gpu-pci");
>   		dev->pdev = pdev;
> -		if (vga)
> -			virtio_pci_kick_out_firmware_fb(pdev);
> +		sysfb_evict_conflicts_pci(pdev);
>   	}
>   
>   	ret = drm_dev_register(dev, 0);
diff mbox

Patch

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index fc35731..f27f9b5 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -12,6 +12,7 @@  menuconfig DRM
 	select I2C
 	select I2C_ALGOBIT
 	select DMA_SHARED_BUFFER
+	select SYSFB
 	help
 	  Kernel-level support for the Direct Rendering Infrastructure (DRI)
 	  introduced in XFree86 4.0. If you say Y here, you need to select
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index 9aa533c..a1e67da 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -38,6 +38,7 @@ 
 #include <linux/console.h>
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
+#include <linux/sysfb.h>
 #include <linux/vga_switcheroo.h>
 #include "drm_crtc_helper.h"
 
@@ -326,27 +327,6 @@  MODULE_DEVICE_TABLE(pci, pciidlist);
 
 static struct drm_driver kms_driver;
 
-static int amdgpu_kick_out_firmware_fb(struct pci_dev *pdev)
-{
-	struct apertures_struct *ap;
-	bool primary = false;
-
-	ap = alloc_apertures(1);
-	if (!ap)
-		return -ENOMEM;
-
-	ap->ranges[0].base = pci_resource_start(pdev, 0);
-	ap->ranges[0].size = pci_resource_len(pdev, 0);
-
-#ifdef CONFIG_X86
-	primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
-#endif
-	remove_conflicting_framebuffers(ap, "amdgpudrmfb", primary);
-	kfree(ap);
-
-	return 0;
-}
-
 static int amdgpu_pci_probe(struct pci_dev *pdev,
 			    const struct pci_device_id *ent)
 {
@@ -368,7 +348,7 @@  static int amdgpu_pci_probe(struct pci_dev *pdev,
 		return ret;
 
 	/* Get rid of things like offb */
-	ret = amdgpu_kick_out_firmware_fb(pdev);
+	ret = sysfb_evict_conflicts_pci(pdev);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c
index abace82..99c4ea3 100644
--- a/drivers/gpu/drm/bochs/bochs_drv.c
+++ b/drivers/gpu/drm/bochs/bochs_drv.c
@@ -8,6 +8,7 @@ 
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/sysfb.h>
 
 #include "bochs.h"
 
@@ -143,28 +144,12 @@  static const struct dev_pm_ops bochs_pm_ops = {
 /* ---------------------------------------------------------------------- */
 /* pci interface                                                          */
 
-static int bochs_kick_out_firmware_fb(struct pci_dev *pdev)
-{
-	struct apertures_struct *ap;
-
-	ap = alloc_apertures(1);
-	if (!ap)
-		return -ENOMEM;
-
-	ap->ranges[0].base = pci_resource_start(pdev, 0);
-	ap->ranges[0].size = pci_resource_len(pdev, 0);
-	remove_conflicting_framebuffers(ap, "bochsdrmfb", false);
-	kfree(ap);
-
-	return 0;
-}
-
 static int bochs_pci_probe(struct pci_dev *pdev,
 			   const struct pci_device_id *ent)
 {
 	int ret;
 
-	ret = bochs_kick_out_firmware_fb(pdev);
+	ret = sysfb_evict_conflicts_pci(pdev);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 95ddd56..4d6a65dd 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -36,6 +36,7 @@ 
 #include <linux/pm_runtime.h>
 #include <linux/pnp.h>
 #include <linux/slab.h>
+#include <linux/sysfb.h>
 #include <linux/vgaarb.h>
 #include <linux/vga_switcheroo.h>
 #include <linux/vt.h>
@@ -687,70 +688,32 @@  out:
 	return ret;
 }
 
-#if IS_ENABLED(CONFIG_FB)
 static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
 {
-	struct apertures_struct *ap;
+	struct sysfb_evict_ctx ctx = {};
 	struct pci_dev *pdev = dev_priv->drm.pdev;
 	struct i915_ggtt *ggtt = &dev_priv->ggtt;
-	bool primary;
 	int ret;
 
-	ap = alloc_apertures(1);
-	if (!ap)
-		return -ENOMEM;
-
-	ap->ranges[0].base = ggtt->mappable_base;
-	ap->ranges[0].size = ggtt->mappable_end;
-
-	primary =
-		pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
-
-	ret = remove_conflicting_framebuffers(ap, "inteldrmfb", primary);
-
-	kfree(ap);
-
-	return ret;
-}
-#else
-static int i915_kick_out_firmware_fb(struct drm_i915_private *dev_priv)
-{
-	return 0;
-}
-#endif
+	ctx.flags = SYSFB_EVICT_PLATFORM |
+		    SYSFB_EVICT_FBDEV |
+		    SYSFB_EVICT_VGACON;
 
-#if !defined(CONFIG_VGA_CONSOLE)
-static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
-{
-	return 0;
-}
-#elif !defined(CONFIG_DUMMY_CONSOLE)
-static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
-{
-	return -ENODEV;
-}
-#else
-static int i915_kick_out_vgacon(struct drm_i915_private *dev_priv)
-{
-	int ret = 0;
+	ctx.ap = alloc_apertures(1);
+	if (!ctx.ap)
+		return -ENOMEM;
 
-	DRM_INFO("Replacing VGA console driver\n");
+	ctx.ap->ranges[0].base = ggtt->mappable_base;
+	ctx.ap->ranges[0].size = ggtt->mappable_end;
 
-	console_lock();
-	if (con_is_bound(&vga_con))
-		ret = do_take_over_console(&dummy_con, 0, MAX_NR_CONSOLES - 1, 1);
-	if (ret == 0) {
-		ret = do_unregister_con_driver(&vga_con);
+	if (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)
+		ctx.flags |= SYSFB_EVICT_VBE;
 
-		/* Ignore "already unregistered". */
-		if (ret == -ENODEV)
-			ret = 0;
-	}
-	console_unlock();
+	ret = sysfb_evict_conflicts(&ctx);
 
+	kfree(ctx.ap);
 	return ret;
 }
-#endif
 
 static void intel_init_dpio(struct drm_i915_private *dev_priv)
 {
@@ -1032,20 +995,12 @@  static int i915_driver_init_hw(struct drm_i915_private *dev_priv)
 		goto out_ggtt;
 	}
 
-	/* WARNING: Apparently we must kick fbdev drivers before vgacon,
-	 * otherwise the vga fbdev driver falls over. */
 	ret = i915_kick_out_firmware_fb(dev_priv);
 	if (ret) {
 		DRM_ERROR("failed to remove conflicting framebuffer drivers\n");
 		goto out_ggtt;
 	}
 
-	ret = i915_kick_out_vgacon(dev_priv);
-	if (ret) {
-		DRM_ERROR("failed to remove conflicting VGA console\n");
-		goto out_ggtt;
-	}
-
 	pci_set_master(dev->pdev);
 
 	/* overlay on gen2 is broken and can't address above 1G */
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
index 2b4b125..f30105b 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -10,6 +10,7 @@ 
  */
 #include <linux/module.h>
 #include <linux/console.h>
+#include <linux/sysfb.h>
 #include <drm/drmP.h>
 
 #include "mgag200_drv.h"
@@ -41,29 +42,13 @@  static const struct pci_device_id pciidlist[] = {
 
 MODULE_DEVICE_TABLE(pci, pciidlist);
 
-static void mgag200_kick_out_firmware_fb(struct pci_dev *pdev)
-{
-	struct apertures_struct *ap;
-	bool primary = false;
-
-	ap = alloc_apertures(1);
-	if (!ap)
-		return;
-
-	ap->ranges[0].base = pci_resource_start(pdev, 0);
-	ap->ranges[0].size = pci_resource_len(pdev, 0);
-
-#ifdef CONFIG_X86
-	primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
-#endif
-	remove_conflicting_framebuffers(ap, "mgag200drmfb", primary);
-	kfree(ap);
-}
-
-
 static int mga_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-	mgag200_kick_out_firmware_fb(pdev);
+	int ret;
+
+	ret = sysfb_evict_conflicts_pci(pdev);
+	if (ret < 0)
+		return ret;
 
 	return drm_get_pci_dev(pdev, ent, &driver);
 }
diff --git a/drivers/gpu/drm/mgag200/mgag200_main.c b/drivers/gpu/drm/mgag200/mgag200_main.c
index 13798b3..4723407 100644
--- a/drivers/gpu/drm/mgag200/mgag200_main.c
+++ b/drivers/gpu/drm/mgag200/mgag200_main.c
@@ -124,20 +124,11 @@  static int mga_probe_vram(struct mga_device *mdev, void __iomem *mem)
 static int mga_vram_init(struct mga_device *mdev)
 {
 	void __iomem *mem;
-	struct apertures_struct *aper = alloc_apertures(1);
-	if (!aper)
-		return -ENOMEM;
 
 	/* BAR 0 is VRAM */
 	mdev->mc.vram_base = pci_resource_start(mdev->dev->pdev, 0);
 	mdev->mc.vram_window = pci_resource_len(mdev->dev->pdev, 0);
 
-	aper->ranges[0].base = mdev->mc.vram_base;
-	aper->ranges[0].size = mdev->mc.vram_window;
-
-	remove_conflicting_framebuffers(aper, "mgafb", true);
-	kfree(aper);
-
 	if (!devm_request_mem_region(mdev->dev->dev, mdev->mc.vram_base, mdev->mc.vram_window,
 				"mgadrmfb_vram")) {
 		DRM_ERROR("can't reserve VRAM\n");
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 66c1280..193e833 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -27,6 +27,7 @@ 
 #include <linux/module.h>
 #include <linux/pci.h>
 #include <linux/pm_runtime.h>
+#include <linux/sysfb.h>
 #include <linux/vga_switcheroo.h>
 
 #include "drmP.h"
@@ -310,8 +311,6 @@  static int nouveau_drm_probe(struct pci_dev *pdev,
 			     const struct pci_device_id *pent)
 {
 	struct nvkm_device *device;
-	struct apertures_struct *aper;
-	bool boot = false;
 	int ret;
 
 	if (vga_switcheroo_client_probe_defer(pdev))
@@ -326,34 +325,12 @@  static int nouveau_drm_probe(struct pci_dev *pdev,
 
 	nvkm_device_del(&device);
 
-	/* Remove conflicting drivers (vesafb, efifb etc). */
-	aper = alloc_apertures(3);
-	if (!aper)
-		return -ENOMEM;
-
-	aper->ranges[0].base = pci_resource_start(pdev, 1);
-	aper->ranges[0].size = pci_resource_len(pdev, 1);
-	aper->count = 1;
-
-	if (pci_resource_len(pdev, 2)) {
-		aper->ranges[aper->count].base = pci_resource_start(pdev, 2);
-		aper->ranges[aper->count].size = pci_resource_len(pdev, 2);
-		aper->count++;
-	}
-
-	if (pci_resource_len(pdev, 3)) {
-		aper->ranges[aper->count].base = pci_resource_start(pdev, 3);
-		aper->ranges[aper->count].size = pci_resource_len(pdev, 3);
-		aper->count++;
+	if (nouveau_modeset != 2) {
+		ret = sysfb_evict_conflicts_pci(pdev);
+		if (ret < 0)
+			return ret;
 	}
 
-#ifdef CONFIG_X86
-	boot = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
-#endif
-	if (nouveau_modeset != 2)
-		remove_conflicting_framebuffers(aper, "nouveaufb", boot);
-	kfree(aper);
-
 	ret = nvkm_device_pci_new(pdev, nouveau_config, nouveau_debug,
 				  true, true, ~0ULL, &device);
 	if (ret)
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index c01a7c6..a0c11bd 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -37,6 +37,7 @@ 
 #include <linux/console.h>
 #include <linux/module.h>
 #include <linux/pm_runtime.h>
+#include <linux/sysfb.h>
 #include <linux/vga_switcheroo.h>
 #include <drm/drm_gem.h>
 
@@ -309,27 +310,6 @@  MODULE_DEVICE_TABLE(pci, pciidlist);
 
 static struct drm_driver kms_driver;
 
-static int radeon_kick_out_firmware_fb(struct pci_dev *pdev)
-{
-	struct apertures_struct *ap;
-	bool primary = false;
-
-	ap = alloc_apertures(1);
-	if (!ap)
-		return -ENOMEM;
-
-	ap->ranges[0].base = pci_resource_start(pdev, 0);
-	ap->ranges[0].size = pci_resource_len(pdev, 0);
-
-#ifdef CONFIG_X86
-	primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW;
-#endif
-	remove_conflicting_framebuffers(ap, "radeondrmfb", primary);
-	kfree(ap);
-
-	return 0;
-}
-
 static int radeon_pci_probe(struct pci_dev *pdev,
 			    const struct pci_device_id *ent)
 {
@@ -347,7 +327,7 @@  static int radeon_pci_probe(struct pci_dev *pdev,
 		return -EPROBE_DEFER;
 
 	/* Get rid of things like offb */
-	ret = radeon_kick_out_firmware_fb(pdev);
+	ret = sysfb_evict_conflicts_pci(pdev);
 	if (ret)
 		return ret;
 
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index 7092daa..ac388b5 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -12,6 +12,7 @@ 
 
 #include <linux/component.h>
 #include <linux/of_graph.h>
+#include <linux/sysfb.h>
 
 #include <drm/drmP.h>
 #include <drm/drm_crtc_helper.h>
@@ -97,28 +98,16 @@  static struct drm_driver sun4i_drv_driver = {
 	.disable_vblank		= sun4i_drv_disable_vblank,
 };
 
-static void sun4i_remove_framebuffers(void)
-{
-	struct apertures_struct *ap;
-
-	ap = alloc_apertures(1);
-	if (!ap)
-		return;
-
-	/* The framebuffer can be located anywhere in RAM */
-	ap->ranges[0].base = 0;
-	ap->ranges[0].size = ~0;
-
-	remove_conflicting_framebuffers(ap, "sun4i-drm-fb", false);
-	kfree(ap);
-}
-
 static int sun4i_drv_bind(struct device *dev)
 {
 	struct drm_device *drm;
 	struct sun4i_drv *drv;
 	int ret;
 
+	ret = sysfb_evict_conflicts_firmware();
+	if (ret < 0)
+		return ret;
+
 	drm = drm_dev_alloc(&sun4i_drv_driver, dev);
 	if (!drm)
 		return -ENOMEM;
@@ -156,9 +145,6 @@  static int sun4i_drv_bind(struct device *dev)
 	}
 	drm->irq_enabled = true;
 
-	/* Remove early framebuffers (ie. simplefb) */
-	sun4i_remove_framebuffers();
-
 	/* Create our framebuffer */
 	drv->fbdev = sun4i_framebuffer_init(drm);
 	if (IS_ERR(drv->fbdev)) {
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index 8b42d31..679e65a 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -15,6 +15,7 @@ 
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
+#include <linux/sysfb.h>
 #include "drm_fb_cma_helper.h"
 
 #include "uapi/drm/vc4_drm.h"
@@ -200,24 +201,6 @@  static void vc4_match_add_drivers(struct device *dev,
 	}
 }
 
-static void vc4_kick_out_firmware_fb(void)
-{
-	struct apertures_struct *ap;
-
-	ap = alloc_apertures(1);
-	if (!ap)
-		return;
-
-	/* Since VC4 is a UMA device, the simplefb node may have been
-	 * located anywhere in memory.
-	 */
-	ap->ranges[0].base = 0;
-	ap->ranges[0].size = ~0;
-
-	remove_conflicting_framebuffers(ap, "vc4drmfb", false);
-	kfree(ap);
-}
-
 static int vc4_drm_bind(struct device *dev)
 {
 	struct platform_device *pdev = to_platform_device(dev);
@@ -225,6 +208,10 @@  static int vc4_drm_bind(struct device *dev)
 	struct vc4_dev *vc4;
 	int ret = 0;
 
+	ret = sysfb_evict_conflicts_firmware();
+	if (ret < 0)
+		return ret;
+
 	dev->coherent_dma_mask = DMA_BIT_MASK(32);
 
 	vc4 = devm_kzalloc(dev, sizeof(*vc4), GFP_KERNEL);
@@ -248,8 +235,6 @@  static int vc4_drm_bind(struct device *dev)
 	if (ret)
 		goto gem_destroy;
 
-	vc4_kick_out_firmware_fb();
-
 	ret = drm_dev_register(drm, 0);
 	if (ret < 0)
 		goto unbind_all;
diff --git a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c b/drivers/gpu/drm/virtio/virtgpu_drm_bus.c
index 7f0e93f87..d6a8a94 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c
+++ b/drivers/gpu/drm/virtio/virtgpu_drm_bus.c
@@ -24,29 +24,10 @@ 
  */
 
 #include <linux/pci.h>
+#include <linux/sysfb.h>
 
 #include "virtgpu_drv.h"
 
-static void virtio_pci_kick_out_firmware_fb(struct pci_dev *pci_dev)
-{
-	struct apertures_struct *ap;
-	bool primary;
-
-	ap = alloc_apertures(1);
-	if (!ap)
-		return;
-
-	ap->ranges[0].base = pci_resource_start(pci_dev, 0);
-	ap->ranges[0].size = pci_resource_len(pci_dev, 0);
-
-	primary = pci_dev->resource[PCI_ROM_RESOURCE].flags
-		& IORESOURCE_ROM_SHADOW;
-
-	remove_conflicting_framebuffers(ap, "virtiodrmfb", primary);
-
-	kfree(ap);
-}
-
 int drm_virtio_init(struct drm_driver *driver, struct virtio_device *vdev)
 {
 	struct drm_device *dev;
@@ -65,8 +46,7 @@  int drm_virtio_init(struct drm_driver *driver, struct virtio_device *vdev)
 		DRM_INFO("pci: %s detected\n",
 			 vga ? "virtio-vga" : "virtio-gpu-pci");
 		dev->pdev = pdev;
-		if (vga)
-			virtio_pci_kick_out_firmware_fb(pdev);
+		sysfb_evict_conflicts_pci(pdev);
 	}
 
 	ret = drm_dev_register(dev, 0);