summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorOwain Ainsworth <oga@cvs.openbsd.org>2009-04-03 13:38:54 +0000
committerOwain Ainsworth <oga@cvs.openbsd.org>2009-04-03 13:38:54 +0000
commita84c159815376bb2b69d2df5063b974d6c626565 (patch)
treec713b978e48134ea49c12cbd1b919e7a92366285 /sys/dev
parent7e0af9f024b4ab30d5d74b804005fa8bb3efc49a (diff)
Final irq_lock piece. Switch inteldrm over like radeomdrm and the rest.
We already have a lock protecting the irq registers, so extend it trivially so it protects user interrupts too. Switch irq handler to purely local handler. Finally remove an extra test in i915_wait_irq() since we won't sleep even without that if the test will pass. irq_lock and handler_wrap may now die. Coming soon.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/drm/i915_irq.c22
1 files changed, 6 insertions, 16 deletions
diff --git a/sys/dev/pci/drm/i915_irq.c b/sys/dev/pci/drm/i915_irq.c
index b141c2a90fe..8b6526b5f79 100644
--- a/sys/dev/pci/drm/i915_irq.c
+++ b/sys/dev/pci/drm/i915_irq.c
@@ -201,6 +201,9 @@ i915_driver_irq_handler(DRM_IRQ_ARGS)
drm_i915_private_t *dev_priv = (drm_i915_private_t *)dev->dev_private;
u_int32_t iir, pipea_stats = 0, pipeb_stats = 0;
+ /*
+ * lock is to protect from writes to PIPESTAT and IMR from other cores.
+ */
mtx_enter(&dev_priv->user_irq_lock);
atomic_inc(&dev_priv->irq_received);
iir = I915_READ(IIR);
@@ -223,7 +226,6 @@ i915_driver_irq_handler(DRM_IRQ_ARGS)
I915_WRITE(IIR, iir);
(void)I915_READ(IIR); /* Flush posted writes */
- mtx_leave(&dev_priv->user_irq_lock);
if (dev_priv->sarea_priv != NULL)
dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
@@ -231,6 +233,7 @@ i915_driver_irq_handler(DRM_IRQ_ARGS)
if (iir & I915_USER_INTERRUPT) {
wakeup(dev_priv);
}
+ mtx_leave(&dev_priv->user_irq_lock);
if (pipea_stats & I915_VBLANK_INTERRUPT_STATUS)
drm_handle_vblank(dev, i915_get_plane(dev, 0));
@@ -289,24 +292,11 @@ i915_wait_irq(struct drm_device *dev, int irq_nr)
DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr,
READ_BREADCRUMB(dev_priv));
- if (READ_BREADCRUMB(dev_priv) >= irq_nr) {
- if (dev_priv->sarea_priv != NULL) {
- dev_priv->sarea_priv->last_dispatch =
- READ_BREADCRUMB(dev_priv);
- }
- return (0);
- }
-
i915_user_irq_get(dev);
- DRM_WAIT_ON(ret, dev_priv, &dev->irq_lock, 3 * hz, "i915wt",
+ DRM_WAIT_ON(ret, dev_priv, &dev_priv->user_irq_lock, 3 * hz, "i915wt",
READ_BREADCRUMB(dev_priv) >= irq_nr);
i915_user_irq_put(dev);
- if (ret == EBUSY) {
- DRM_ERROR("EBUSY -- rec: %d emitted: %d\n",
- READ_BREADCRUMB(dev_priv), (int)dev_priv->counter);
- }
-
if (dev_priv->sarea_priv != NULL)
dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
return (ret);
@@ -414,7 +404,7 @@ i915_driver_irq_install(struct drm_device *dev)
(void)I915_READ(IER);
dev_priv->irqh = pci_intr_establish(dev_priv->pc, dev_priv->ih, IPL_BIO,
- drm_irq_handler_wrap, dev, dev_priv->dev.dv_xname);
+ i915_driver_irq_handler, dev, dev_priv->dev.dv_xname);
if (dev_priv->irqh == NULL)
return (ENOENT);