diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2010-11-02 19:57:28 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-12-03 00:11:29 -0500 |
commit | 8f8a54482b008714ccfad15f4592b3802b80d479 (patch) | |
tree | a9e1d6baf0b3d918c741d07550a85fbffc8bbdeb /drivers/gpu/drm/nouveau/nouveau_irq.c | |
parent | a169f09b96306cc353ffe0e1bc4bc0e1e9492281 (diff) |
drm/nouveau: allow irq handlers to be installed by engine-specific code
Lets start to clean up this mess!
Reviewed-by: Francisco Jerez <currojerez@riseup.net>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_irq.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_irq.c | 34 |
1 files changed, 33 insertions, 1 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index f3ae74ef3318..819bc3dd89e0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c | |||
@@ -1216,8 +1216,9 @@ nouveau_irq_handler(DRM_IRQ_ARGS) | |||
1216 | { | 1216 | { |
1217 | struct drm_device *dev = (struct drm_device *)arg; | 1217 | struct drm_device *dev = (struct drm_device *)arg; |
1218 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 1218 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
1219 | uint32_t status; | ||
1220 | unsigned long flags; | 1219 | unsigned long flags; |
1220 | u32 status; | ||
1221 | int i; | ||
1221 | 1222 | ||
1222 | status = nv_rd32(dev, NV03_PMC_INTR_0); | 1223 | status = nv_rd32(dev, NV03_PMC_INTR_0); |
1223 | if (!status) | 1224 | if (!status) |
@@ -1267,6 +1268,14 @@ nouveau_irq_handler(DRM_IRQ_ARGS) | |||
1267 | NV_PMC_INTR_0_NV50_I2C_PENDING); | 1268 | NV_PMC_INTR_0_NV50_I2C_PENDING); |
1268 | } | 1269 | } |
1269 | 1270 | ||
1271 | for (i = 0; i < 32 && status; i++) { | ||
1272 | if (!(status & (1 << i)) || !dev_priv->irq_handler[i]) | ||
1273 | continue; | ||
1274 | |||
1275 | dev_priv->irq_handler[i](dev); | ||
1276 | status &= ~(1 << i); | ||
1277 | } | ||
1278 | |||
1270 | if (status) | 1279 | if (status) |
1271 | NV_ERROR(dev, "Unhandled PMC INTR status bits 0x%08x\n", status); | 1280 | NV_ERROR(dev, "Unhandled PMC INTR status bits 0x%08x\n", status); |
1272 | 1281 | ||
@@ -1304,3 +1313,26 @@ nouveau_irq_fini(struct drm_device *dev) | |||
1304 | if (dev_priv->msi_enabled) | 1313 | if (dev_priv->msi_enabled) |
1305 | pci_disable_msi(dev->pdev); | 1314 | pci_disable_msi(dev->pdev); |
1306 | } | 1315 | } |
1316 | |||
1317 | void | ||
1318 | nouveau_irq_register(struct drm_device *dev, int status_bit, | ||
1319 | void (*handler)(struct drm_device *)) | ||
1320 | { | ||
1321 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
1322 | unsigned long flags; | ||
1323 | |||
1324 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); | ||
1325 | dev_priv->irq_handler[status_bit] = handler; | ||
1326 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); | ||
1327 | } | ||
1328 | |||
1329 | void | ||
1330 | nouveau_irq_unregister(struct drm_device *dev, int status_bit) | ||
1331 | { | ||
1332 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
1333 | unsigned long flags; | ||
1334 | |||
1335 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); | ||
1336 | dev_priv->irq_handler[status_bit] = NULL; | ||
1337 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); | ||
1338 | } | ||