Commit 8a9c3f5c authored by Zou Nan hai's avatar Zou Nan hai Committed by Greg Kroah-Hartman

drm/i915: remove loop in Ironlake interrupt handler

commit c7c85101 upstream.

On Ironlake, there is an interrupt master control bit. With the bit
disabled before clearing IIR, we do not need to handle extra interrupt
in a loop. This patch removes the loop in Ironlake interrupt handler.
It fixed irq lost issue on some Ironlake platforms.
Signed-off-by: default avatarZou Nan hai <Nanhai.zou@intel.com>
Signed-off-by: default avatarZhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: default avatarEric Anholt <eric@anholt.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 4334ab76
...@@ -255,7 +255,6 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev) ...@@ -255,7 +255,6 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
int ret = IRQ_NONE; int ret = IRQ_NONE;
u32 de_iir, gt_iir, de_ier; u32 de_iir, gt_iir, de_ier;
u32 new_de_iir, new_gt_iir;
struct drm_i915_master_private *master_priv; struct drm_i915_master_private *master_priv;
/* disable master interrupt before clearing iir */ /* disable master interrupt before clearing iir */
...@@ -266,35 +265,29 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev) ...@@ -266,35 +265,29 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev)
de_iir = I915_READ(DEIIR); de_iir = I915_READ(DEIIR);
gt_iir = I915_READ(GTIIR); gt_iir = I915_READ(GTIIR);
for (;;) { if (de_iir == 0 && gt_iir == 0)
if (de_iir == 0 && gt_iir == 0) goto done;
break;
ret = IRQ_HANDLED;
I915_WRITE(DEIIR, de_iir);
new_de_iir = I915_READ(DEIIR);
I915_WRITE(GTIIR, gt_iir);
new_gt_iir = I915_READ(GTIIR);
if (dev->primary->master) { ret = IRQ_HANDLED;
master_priv = dev->primary->master->driver_priv;
if (master_priv->sarea_priv)
master_priv->sarea_priv->last_dispatch =
READ_BREADCRUMB(dev_priv);
}
if (gt_iir & GT_USER_INTERRUPT) { if (dev->primary->master) {
u32 seqno = i915_get_gem_seqno(dev); master_priv = dev->primary->master->driver_priv;
dev_priv->mm.irq_gem_seqno = seqno; if (master_priv->sarea_priv)
trace_i915_gem_request_complete(dev, seqno); master_priv->sarea_priv->last_dispatch =
DRM_WAKEUP(&dev_priv->irq_queue); READ_BREADCRUMB(dev_priv);
} }
de_iir = new_de_iir; if (gt_iir & GT_USER_INTERRUPT) {
gt_iir = new_gt_iir; u32 seqno = i915_get_gem_seqno(dev);
dev_priv->mm.irq_gem_seqno = seqno;
trace_i915_gem_request_complete(dev, seqno);
DRM_WAKEUP(&dev_priv->irq_queue);
} }
I915_WRITE(GTIIR, gt_iir);
I915_WRITE(DEIIR, de_iir);
done:
I915_WRITE(DEIER, de_ier); I915_WRITE(DEIER, de_ier);
(void)I915_READ(DEIER); (void)I915_READ(DEIER);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment