0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 #include <linux/export.h>
0056 #include <linux/interrupt.h> /* For task queue support */
0057 #include <linux/pci.h>
0058 #include <linux/vgaarb.h>
0059
0060 #include <drm/drm.h>
0061 #include <drm/drm_device.h>
0062 #include <drm/drm_drv.h>
0063 #include <drm/drm_legacy.h>
0064 #include <drm/drm_print.h>
0065 #include <drm/drm_vblank.h>
0066
0067 #include "drm_internal.h"
0068
0069 static int drm_legacy_irq_install(struct drm_device *dev, int irq)
0070 {
0071 int ret;
0072 unsigned long sh_flags = 0;
0073
0074 if (irq == 0)
0075 return -EINVAL;
0076
0077 if (dev->irq_enabled)
0078 return -EBUSY;
0079 dev->irq_enabled = true;
0080
0081 DRM_DEBUG("irq=%d\n", irq);
0082
0083
0084 if (dev->driver->irq_preinstall)
0085 dev->driver->irq_preinstall(dev);
0086
0087
0088 if (dev_is_pci(dev->dev))
0089 sh_flags = IRQF_SHARED;
0090
0091 ret = request_irq(irq, dev->driver->irq_handler,
0092 sh_flags, dev->driver->name, dev);
0093
0094 if (ret < 0) {
0095 dev->irq_enabled = false;
0096 return ret;
0097 }
0098
0099
0100 if (dev->driver->irq_postinstall)
0101 ret = dev->driver->irq_postinstall(dev);
0102
0103 if (ret < 0) {
0104 dev->irq_enabled = false;
0105 if (drm_core_check_feature(dev, DRIVER_LEGACY))
0106 vga_client_unregister(to_pci_dev(dev->dev));
0107 free_irq(irq, dev);
0108 } else {
0109 dev->irq = irq;
0110 }
0111
0112 return ret;
0113 }
0114
0115 int drm_legacy_irq_uninstall(struct drm_device *dev)
0116 {
0117 unsigned long irqflags;
0118 bool irq_enabled;
0119 int i;
0120
0121 irq_enabled = dev->irq_enabled;
0122 dev->irq_enabled = false;
0123
0124
0125
0126
0127
0128
0129
0130 if (drm_dev_has_vblank(dev)) {
0131 spin_lock_irqsave(&dev->vbl_lock, irqflags);
0132 for (i = 0; i < dev->num_crtcs; i++) {
0133 struct drm_vblank_crtc *vblank = &dev->vblank[i];
0134
0135 if (!vblank->enabled)
0136 continue;
0137
0138 WARN_ON(drm_core_check_feature(dev, DRIVER_MODESET));
0139
0140 drm_vblank_disable_and_save(dev, i);
0141 wake_up(&vblank->queue);
0142 }
0143 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
0144 }
0145
0146 if (!irq_enabled)
0147 return -EINVAL;
0148
0149 DRM_DEBUG("irq=%d\n", dev->irq);
0150
0151 if (drm_core_check_feature(dev, DRIVER_LEGACY))
0152 vga_client_unregister(to_pci_dev(dev->dev));
0153
0154 if (dev->driver->irq_uninstall)
0155 dev->driver->irq_uninstall(dev);
0156
0157 free_irq(dev->irq, dev);
0158
0159 return 0;
0160 }
0161 EXPORT_SYMBOL(drm_legacy_irq_uninstall);
0162
0163 int drm_legacy_irq_control(struct drm_device *dev, void *data,
0164 struct drm_file *file_priv)
0165 {
0166 struct drm_control *ctl = data;
0167 int ret = 0, irq;
0168 struct pci_dev *pdev;
0169
0170
0171
0172
0173
0174 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
0175 return 0;
0176 if (!drm_core_check_feature(dev, DRIVER_LEGACY))
0177 return 0;
0178
0179 if (WARN_ON(!dev_is_pci(dev->dev)))
0180 return -EINVAL;
0181
0182 switch (ctl->func) {
0183 case DRM_INST_HANDLER:
0184 pdev = to_pci_dev(dev->dev);
0185 irq = pdev->irq;
0186
0187 if (dev->if_version < DRM_IF_VERSION(1, 2) &&
0188 ctl->irq != irq)
0189 return -EINVAL;
0190 mutex_lock(&dev->struct_mutex);
0191 ret = drm_legacy_irq_install(dev, irq);
0192 mutex_unlock(&dev->struct_mutex);
0193
0194 return ret;
0195 case DRM_UNINST_HANDLER:
0196 mutex_lock(&dev->struct_mutex);
0197 ret = drm_legacy_irq_uninstall(dev);
0198 mutex_unlock(&dev->struct_mutex);
0199
0200 return ret;
0201 default:
0202 return -EINVAL;
0203 }
0204 }