drm/vmwgfx: Don't use drm_irq_[un]install
authorThomas Hellstrom <thellstrom@vmware.com>
Thu, 24 Aug 2017 06:06:27 +0000 (08:06 +0200)
committerSinclair Yeh <syeh@vmware.com>
Mon, 28 Aug 2017 15:40:40 +0000 (17:40 +0200)
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 <thellstrom@vmware.com>
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
drivers/gpu/drm/vmwgfx/vmwgfx_irq.c

index 8be26509a9aa3aac3179ecbb2224dcef90821090..e84fee3ec4f333d48519c91ba690770cb5633f17 100644 (file)
@@ -36,7 +36,6 @@
 #include <drm/ttm/ttm_module.h>
 #include <linux/dma_remapping.h>
 
-#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,
index 4b948fba9eec274b794a0546fec0179b3de1cadf..5e7e8a3df7c38afc0c7af94ef3e368abed2a6e7a 100644 (file)
@@ -41,6 +41,7 @@
 #include <drm/ttm/ttm_module.h>
 #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);
index 0c7e1723292c0db7a200ff1b7fd3f3f7c580c9a4..9b519c4b4ec28e699140c6f05295e277cdae89a3 100644 (file)
@@ -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;
 }