]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
drm/i915: remove loop in Ironlake interrupt handler
authorZou Nan hai <Nanhai.zou@intel.com>
Fri, 15 Jan 2010 02:29:06 +0000 (10:29 +0800)
committerGreg Kroah-Hartman <gregkh@suse.de>
Fri, 22 Jan 2010 23:18:03 +0000 (15:18 -0800)
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 <Nanhai.zou@intel.com>
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
Signed-off-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/gpu/drm/i915/i915_irq.c

index aa7fd82aa6eb343afa3fdb4b7088104f311f00d9..7d1357e54eef8c7c718df0b1c8f779ca18447f52 100644 (file)
@@ -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);