aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
authorZou Nan hai <Nanhai.zou@intel.com>2010-01-15 10:29:06 +0800
committerGreg Kroah-Hartman <gregkh@suse.de>2010-01-22 15:18:03 -0800
commit8a9c3f5c34a93fd4635aa739810280c4752eaa6e (patch)
treee65e820b62066a63d63927bb022175bba10c8033 /drivers/gpu
parent4334ab76da3dc18a531948882ff6247764d96ea8 (diff)
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 <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>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c43
1 files changed, 18 insertions, 25 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index aa7fd82aa6e..7d1357e54ee 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);