drm/irq: track the irq installed in drm_irq_install in dev->irq
[deliverable/linux.git] / drivers / gpu / drm / drm_irq.c
index c2676b5908d9f6edbcf4dd8d9fb126cfb93cd5ab..7cf407bbfed562cab82e53bf2301cc593a5a9253 100644 (file)
  */
 #define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000
 
-/**
- * Get interrupt from bus id.
- *
- * \param inode device inode.
- * \param file_priv DRM file private.
- * \param cmd command.
- * \param arg user argument, pointing to a drm_irq_busid structure.
- * \return zero on success or a negative number on failure.
- *
- * Finds the PCI device with the specified bus id and gets its IRQ number.
- * This IOCTL is deprecated, and will now return EINVAL for any busid not equal
- * to that of the device that this DRM instance attached to.
- */
-int drm_irq_by_busid(struct drm_device *dev, void *data,
-                    struct drm_file *file_priv)
-{
-       struct drm_irq_busid *p = data;
-
-       if (!dev->driver->bus->irq_by_busid)
-               return -EINVAL;
-
-       if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
-               return -EINVAL;
-
-       return dev->driver->bus->irq_by_busid(dev, p);
-}
-
 /*
  * Clear vblank timestamp buffer for a crtc.
  */
@@ -260,6 +233,11 @@ static void drm_irq_vgaarb_nokms(void *cookie, bool state)
        }
 }
 
+static inline int drm_dev_to_irq(struct drm_device *dev)
+{
+       return dev->driver->bus->get_irq(dev);
+}
+
 /**
  * Install IRQ handler.
  *
@@ -271,32 +249,27 @@ static void drm_irq_vgaarb_nokms(void *cookie, bool state)
  */
 int drm_irq_install(struct drm_device *dev)
 {
-       int ret;
+       int ret, irq;
        unsigned long sh_flags = 0;
        char *irqname;
 
+       irq = drm_dev_to_irq(dev);
+
        if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
                return -EINVAL;
 
-       if (drm_dev_to_irq(dev) == 0)
+       if (irq == 0)
                return -EINVAL;
 
-       mutex_lock(&dev->struct_mutex);
-
        /* Driver must have been initialized */
-       if (!dev->dev_private) {
-               mutex_unlock(&dev->struct_mutex);
+       if (!dev->dev_private)
                return -EINVAL;
-       }
 
-       if (dev->irq_enabled) {
-               mutex_unlock(&dev->struct_mutex);
+       if (dev->irq_enabled)
                return -EBUSY;
-       }
        dev->irq_enabled = true;
-       mutex_unlock(&dev->struct_mutex);
 
-       DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev));
+       DRM_DEBUG("irq=%d\n", irq);
 
        /* Before installing handler */
        if (dev->driver->irq_preinstall)
@@ -311,13 +284,11 @@ int drm_irq_install(struct drm_device *dev)
        else
                irqname = dev->driver->name;
 
-       ret = request_irq(drm_dev_to_irq(dev), dev->driver->irq_handler,
+       ret = request_irq(irq, dev->driver->irq_handler,
                          sh_flags, irqname, dev);
 
        if (ret < 0) {
-               mutex_lock(&dev->struct_mutex);
                dev->irq_enabled = false;
-               mutex_unlock(&dev->struct_mutex);
                return ret;
        }
 
@@ -329,12 +300,12 @@ int drm_irq_install(struct drm_device *dev)
                ret = dev->driver->irq_postinstall(dev);
 
        if (ret < 0) {
-               mutex_lock(&dev->struct_mutex);
                dev->irq_enabled = false;
-               mutex_unlock(&dev->struct_mutex);
                if (!drm_core_check_feature(dev, DRIVER_MODESET))
                        vga_client_register(dev->pdev, NULL, NULL, NULL);
-               free_irq(drm_dev_to_irq(dev), dev);
+               free_irq(irq, dev);
+       } else {
+               dev->irq = irq;
        }
 
        return ret;
@@ -357,10 +328,8 @@ int drm_irq_uninstall(struct drm_device *dev)
        if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
                return -EINVAL;
 
-       mutex_lock(&dev->struct_mutex);
        irq_enabled = dev->irq_enabled;
        dev->irq_enabled = false;
-       mutex_unlock(&dev->struct_mutex);
 
        /*
         * Wake up any waiters so they don't hang.
@@ -379,7 +348,7 @@ int drm_irq_uninstall(struct drm_device *dev)
        if (!irq_enabled)
                return -EINVAL;
 
-       DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev));
+       DRM_DEBUG("irq=%d\n", dev->irq);
 
        if (!drm_core_check_feature(dev, DRIVER_MODESET))
                vga_client_register(dev->pdev, NULL, NULL, NULL);
@@ -387,7 +356,7 @@ int drm_irq_uninstall(struct drm_device *dev)
        if (dev->driver->irq_uninstall)
                dev->driver->irq_uninstall(dev);
 
-       free_irq(drm_dev_to_irq(dev), dev);
+       free_irq(dev->irq, dev);
 
        return 0;
 }
@@ -408,28 +377,36 @@ int drm_control(struct drm_device *dev, void *data,
                struct drm_file *file_priv)
 {
        struct drm_control *ctl = data;
+       int ret = 0;
 
        /* if we haven't irq we fallback for compatibility reasons -
         * this used to be a separate function in drm_dma.h
         */
 
+       if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
+               return 0;
+       if (drm_core_check_feature(dev, DRIVER_MODESET))
+               return 0;
+       /* UMS was only ever support on pci devices. */
+       if (WARN_ON(!dev->pdev))
+               return -EINVAL;
 
        switch (ctl->func) {
        case DRM_INST_HANDLER:
-               if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
-                       return 0;
-               if (drm_core_check_feature(dev, DRIVER_MODESET))
-                       return 0;
                if (dev->if_version < DRM_IF_VERSION(1, 2) &&
                    ctl->irq != drm_dev_to_irq(dev))
                        return -EINVAL;
-               return drm_irq_install(dev);
+               mutex_lock(&dev->struct_mutex);
+               ret = drm_irq_install(dev);
+               mutex_unlock(&dev->struct_mutex);
+
+               return ret;
        case DRM_UNINST_HANDLER:
-               if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
-                       return 0;
-               if (drm_core_check_feature(dev, DRIVER_MODESET))
-                       return 0;
-               return drm_irq_uninstall(dev);
+               mutex_lock(&dev->struct_mutex);
+               ret = drm_irq_uninstall(dev);
+               mutex_unlock(&dev->struct_mutex);
+
+               return ret;
        default:
                return -EINVAL;
        }
@@ -1160,9 +1137,8 @@ int drm_wait_vblank(struct drm_device *dev, void *data,
        int ret;
        unsigned int flags, seq, crtc, high_crtc;
 
-       if (drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
-               if ((!drm_dev_to_irq(dev)) || (!dev->irq_enabled))
-                       return -EINVAL;
+       if (!dev->irq_enabled)
+               return -EINVAL;
 
        if (vblwait->request.type & _DRM_VBLANK_SIGNAL)
                return -EINVAL;
This page took 0.029313 seconds and 5 git commands to generate.