diff options
author | Owain Ainsworth <oga@cvs.openbsd.org> | 2009-04-03 13:38:54 +0000 |
---|---|---|
committer | Owain Ainsworth <oga@cvs.openbsd.org> | 2009-04-03 13:38:54 +0000 |
commit | a84c159815376bb2b69d2df5063b974d6c626565 (patch) | |
tree | c713b978e48134ea49c12cbd1b919e7a92366285 /sys/dev | |
parent | 7e0af9f024b4ab30d5d74b804005fa8bb3efc49a (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.c | 22 |
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); |