From: Zou Nan hai Date: Fri, 15 Jan 2010 02:29:06 +0000 (+0800) Subject: drm/i915: remove loop in Ironlake interrupt handler X-Git-Tag: v2.6.32.5~26 X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=8a9c3f5c34a93fd4635aa739810280c4752eaa6e;p=karo-tx-linux.git drm/i915: remove loop in Ironlake interrupt handler commit c7c85101afd0cb8ce497456d12ee1cad4aad152f 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: Zou Nan hai Signed-off-by: Zhenyu Wang Signed-off-by: Eric Anholt Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index aa7fd82aa6eb..7d1357e54eef 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -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; int ret = IRQ_NONE; u32 de_iir, gt_iir, de_ier; - u32 new_de_iir, new_gt_iir; struct drm_i915_master_private *master_priv; /* disable master interrupt before clearing iir */ @@ -266,35 +265,29 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev) de_iir = I915_READ(DEIIR); gt_iir = I915_READ(GTIIR); - for (;;) { - if (de_iir == 0 && gt_iir == 0) - 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 (de_iir == 0 && gt_iir == 0) + goto done; - if (dev->primary->master) { - master_priv = dev->primary->master->driver_priv; - if (master_priv->sarea_priv) - master_priv->sarea_priv->last_dispatch = - READ_BREADCRUMB(dev_priv); - } + ret = IRQ_HANDLED; - if (gt_iir & GT_USER_INTERRUPT) { - 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); - } + if (dev->primary->master) { + master_priv = dev->primary->master->driver_priv; + if (master_priv->sarea_priv) + master_priv->sarea_priv->last_dispatch = + READ_BREADCRUMB(dev_priv); + } - de_iir = new_de_iir; - gt_iir = new_gt_iir; + if (gt_iir & GT_USER_INTERRUPT) { + 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); (void)I915_READ(DEIER);