aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_irq.c
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2008-07-29 15:10:39 -0400
committerDave Airlie <airlied@linux.ie>2008-10-17 17:10:10 -0400
commited4cb4142b242d8090d3811d5eb4abf6aa985bc8 (patch)
tree5d19db6ffec95b18654bbde820ae8ff8995f856e /drivers/gpu/drm/drm_irq.c
parent585fb111348f7cdc30c6a1b903987612ddeafb23 (diff)
i915: Add support for MSI and interrupt mitigation.
Previous attempts at interrupt mitigation had been foiled by i915_wait_irq's failure to update the sarea seqno value when the status page indicated that the seqno had already been passed. MSI support has been seen to cut CPU costs by up to 40% in some workloads by avoiding other expensive interrupt handlers for frequent graphics interrupts. Signed-off-by: Eric Anholt <eric@anholt.net> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/drm_irq.c')
-rw-r--r--drivers/gpu/drm/drm_irq.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 53f0e5af1cc8..61ed5158f783 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -63,7 +63,7 @@ int drm_irq_by_busid(struct drm_device *dev, void *data,
63 p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn)) 63 p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn))
64 return -EINVAL; 64 return -EINVAL;
65 65
66 p->irq = dev->irq; 66 p->irq = dev->pdev->irq;
67 67
68 DRM_DEBUG("%d:%d:%d => IRQ %d\n", p->busnum, p->devnum, p->funcnum, 68 DRM_DEBUG("%d:%d:%d => IRQ %d\n", p->busnum, p->devnum, p->funcnum,
69 p->irq); 69 p->irq);
@@ -89,7 +89,7 @@ static int drm_irq_install(struct drm_device * dev)
89 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) 89 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
90 return -EINVAL; 90 return -EINVAL;
91 91
92 if (dev->irq == 0) 92 if (dev->pdev->irq == 0)
93 return -EINVAL; 93 return -EINVAL;
94 94
95 mutex_lock(&dev->struct_mutex); 95 mutex_lock(&dev->struct_mutex);
@@ -107,7 +107,7 @@ static int drm_irq_install(struct drm_device * dev)
107 dev->irq_enabled = 1; 107 dev->irq_enabled = 1;
108 mutex_unlock(&dev->struct_mutex); 108 mutex_unlock(&dev->struct_mutex);
109 109
110 DRM_DEBUG("irq=%d\n", dev->irq); 110 DRM_DEBUG("irq=%d\n", dev->pdev->irq);
111 111
112 if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) { 112 if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) {
113 init_waitqueue_head(&dev->vbl_queue); 113 init_waitqueue_head(&dev->vbl_queue);
@@ -127,8 +127,12 @@ static int drm_irq_install(struct drm_device * dev)
127 if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED)) 127 if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
128 sh_flags = IRQF_SHARED; 128 sh_flags = IRQF_SHARED;
129 129
130 ret = request_irq(dev->irq, dev->driver->irq_handler, 130 ret = request_irq(dev->pdev->irq, dev->driver->irq_handler,
131 sh_flags, dev->devname, dev); 131 sh_flags, dev->devname, dev);
132 /* Expose the device irq number to drivers that want to export it for
133 * whatever reason.
134 */
135 dev->irq = dev->pdev->irq;
132 if (ret < 0) { 136 if (ret < 0) {
133 mutex_lock(&dev->struct_mutex); 137 mutex_lock(&dev->struct_mutex);
134 dev->irq_enabled = 0; 138 dev->irq_enabled = 0;
@@ -164,11 +168,11 @@ int drm_irq_uninstall(struct drm_device * dev)
164 if (!irq_enabled) 168 if (!irq_enabled)
165 return -EINVAL; 169 return -EINVAL;
166 170
167 DRM_DEBUG("irq=%d\n", dev->irq); 171 DRM_DEBUG("irq=%d\n", dev->pdev->irq);
168 172
169 dev->driver->irq_uninstall(dev); 173 dev->driver->irq_uninstall(dev);
170 174
171 free_irq(dev->irq, dev); 175 free_irq(dev->pdev->irq, dev);
172 176
173 dev->locked_tasklet_func = NULL; 177 dev->locked_tasklet_func = NULL;
174 178
@@ -201,7 +205,7 @@ int drm_control(struct drm_device *dev, void *data,
201 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ)) 205 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
202 return 0; 206 return 0;
203 if (dev->if_version < DRM_IF_VERSION(1, 2) && 207 if (dev->if_version < DRM_IF_VERSION(1, 2) &&
204 ctl->irq != dev->irq) 208 ctl->irq != dev->pdev->irq)
205 return -EINVAL; 209 return -EINVAL;
206 return drm_irq_install(dev); 210 return drm_irq_install(dev);
207 case DRM_UNINST_HANDLER: 211 case DRM_UNINST_HANDLER:
@@ -239,7 +243,7 @@ int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *file_pr
239 int ret = 0; 243 int ret = 0;
240 unsigned int flags, seq; 244 unsigned int flags, seq;
241 245
242 if ((!dev->irq) || (!dev->irq_enabled)) 246 if ((!dev->pdev->irq) || (!dev->irq_enabled))
243 return -EINVAL; 247 return -EINVAL;
244 248
245 if (vblwait->request.type & 249 if (vblwait->request.type &