From 835aeefd6ec303240efcaeb7ebe27ce232669ca9 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 24 Aug 2017 08:06:27 +0200 Subject: [PATCH] drm/vmwgfx: Don't use drm_irq_[un]install We're not allowed to change the upstream version of the drm_irq_install function to be able to incorporate threaded irqs. So roll our own irq install- and uninstall functions instead of relying on the drm core ones. Signed-off-by: Thomas Hellstrom --- drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | 11 ++----- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 5 ++-- drivers/gpu/drm/vmwgfx/vmwgfx_irq.c | 45 ++++++++++++++++++++++------- 3 files changed, 40 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 8be26509a9aa3..e84fee3ec4f33 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -36,7 +36,6 @@ #include #include -#define VMWGFX_DRIVER_NAME "vmwgfx" #define VMWGFX_DRIVER_DESC "Linux drm driver for VMware graphics devices" #define VMWGFX_CHIP_SVGAII 0 #define VMW_FB_RESERVATION 0 @@ -825,7 +824,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) } if (dev_priv->capabilities & SVGA_CAP_IRQMASK) { - ret = drm_irq_install(dev, dev->pdev->irq); + ret = vmw_irq_install(dev, dev->pdev->irq); if (ret != 0) { DRM_ERROR("Failed installing irq: %d\n", ret); goto out_no_irq; @@ -937,7 +936,7 @@ out_no_bdev: vmw_fence_manager_takedown(dev_priv->fman); out_no_fman: if (dev_priv->capabilities & SVGA_CAP_IRQMASK) - drm_irq_uninstall(dev_priv->dev); + vmw_irq_uninstall(dev_priv->dev); out_no_irq: if (dev_priv->stealth) pci_release_region(dev->pdev, 2); @@ -990,7 +989,7 @@ static void vmw_driver_unload(struct drm_device *dev) vmw_release_device_late(dev_priv); vmw_fence_manager_takedown(dev_priv->fman); if (dev_priv->capabilities & SVGA_CAP_IRQMASK) - drm_irq_uninstall(dev_priv->dev); + vmw_irq_uninstall(dev_priv->dev); if (dev_priv->stealth) pci_release_region(dev->pdev, 2); else @@ -1516,10 +1515,6 @@ static struct drm_driver driver = { .load = vmw_driver_load, .unload = vmw_driver_unload, .lastclose = vmw_lastclose, - .irq_preinstall = vmw_irq_preinstall, - .irq_postinstall = vmw_irq_postinstall, - .irq_uninstall = vmw_irq_uninstall, - .irq_handler = vmw_irq_handler, .get_vblank_counter = vmw_get_vblank_counter, .enable_vblank = vmw_enable_vblank, .disable_vblank = vmw_disable_vblank, diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 4b948fba9eec2..5e7e8a3df7c38 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -41,6 +41,7 @@ #include #include "vmwgfx_fence.h" +#define VMWGFX_DRIVER_NAME "vmwgfx" #define VMWGFX_DRIVER_DATE "20170607" #define VMWGFX_DRIVER_MAJOR 2 #define VMWGFX_DRIVER_MINOR 13 @@ -847,12 +848,10 @@ extern int vmw_validate_single_buffer(struct vmw_private *dev_priv, * IRQs and wating - vmwgfx_irq.c */ -extern irqreturn_t vmw_irq_handler(int irq, void *arg); extern int vmw_wait_seqno(struct vmw_private *dev_priv, bool lazy, uint32_t seqno, bool interruptible, unsigned long timeout); -extern void vmw_irq_preinstall(struct drm_device *dev); -extern int vmw_irq_postinstall(struct drm_device *dev); +extern int vmw_irq_install(struct drm_device *dev, int irq); extern void vmw_irq_uninstall(struct drm_device *dev); extern bool vmw_seqno_passed(struct vmw_private *dev_priv, uint32_t seqno); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c index 0c7e1723292c0..9b519c4b4ec28 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_irq.c @@ -30,7 +30,7 @@ #define VMW_FENCE_WRAP (1 << 24) -irqreturn_t vmw_irq_handler(int irq, void *arg) +static irqreturn_t vmw_irq_handler(int irq, void *arg) { struct drm_device *dev = (struct drm_device *)arg; struct vmw_private *dev_priv = vmw_priv(dev); @@ -281,23 +281,15 @@ int vmw_wait_seqno(struct vmw_private *dev_priv, return ret; } -void vmw_irq_preinstall(struct drm_device *dev) +static void vmw_irq_preinstall(struct drm_device *dev) { struct vmw_private *dev_priv = vmw_priv(dev); uint32_t status; - if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK)) - return; - status = inl(dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); outl(status, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); } -int vmw_irq_postinstall(struct drm_device *dev) -{ - return 0; -} - void vmw_irq_uninstall(struct drm_device *dev) { struct vmw_private *dev_priv = vmw_priv(dev); @@ -306,8 +298,41 @@ void vmw_irq_uninstall(struct drm_device *dev) if (!(dev_priv->capabilities & SVGA_CAP_IRQMASK)) return; + if (!dev->irq_enabled) + return; + vmw_write(dev_priv, SVGA_REG_IRQMASK, 0); status = inl(dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); outl(status, dev_priv->io_start + VMWGFX_IRQSTATUS_PORT); + + dev->irq_enabled = false; + free_irq(dev->irq, dev); +} + +/** + * vmw_irq_install - Install the irq handlers + * + * @dev: Pointer to the drm device. + * @irq: The irq number. + * Return: Zero if successful. Negative number otherwise. + */ +int vmw_irq_install(struct drm_device *dev, int irq) +{ + int ret; + + if (dev->irq_enabled) + return -EBUSY; + + vmw_irq_preinstall(dev); + + ret = request_threaded_irq(irq, vmw_irq_handler, NULL, + IRQF_SHARED, VMWGFX_DRIVER_NAME, dev); + if (ret < 0) + return ret; + + dev->irq_enabled = true; + dev->irq = irq; + + return ret; } -- 2.39.5