Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c7c85101 authored by Zou Nan hai's avatar Zou Nan hai Committed by Eric Anholt
Browse files

drm/i915: remove loop in Ironlake interrupt handler



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.

Cc: Stable Team <stable@kernel.org>
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>
parent b9241ea3
Loading
Loading
Loading
Loading
+29 −39
Original line number Diff line number Diff line
@@ -274,7 +274,6 @@ irqreturn_t ironlake_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, pch_iir;
	u32 new_de_iir, new_gt_iir, new_pch_iir;
	struct drm_i915_master_private *master_priv;

	/* disable master interrupt before clearing iir  */
@@ -286,21 +285,11 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev)
	gt_iir = I915_READ(GTIIR);
	pch_iir = I915_READ(SDEIIR);

	for (;;) {
	if (de_iir == 0 && gt_iir == 0 && pch_iir == 0)
			break;
		goto done;

	ret = IRQ_HANDLED;

		/* should clear PCH hotplug event before clear CPU irq */
		I915_WRITE(SDEIIR, pch_iir);
		new_pch_iir = I915_READ(SDEIIR);

		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) {
		master_priv = dev->primary->master->driver_priv;
		if (master_priv->sarea_priv)
@@ -326,11 +315,12 @@ irqreturn_t ironlake_irq_handler(struct drm_device *dev)
		queue_work(dev_priv->wq, &dev_priv->hotplug_work);
	}

		de_iir = new_de_iir;
		gt_iir = new_gt_iir;
		pch_iir = new_pch_iir;
	}
	/* should clear PCH hotplug event before clear CPU irq */
	I915_WRITE(SDEIIR, pch_iir);
	I915_WRITE(GTIIR, gt_iir);
	I915_WRITE(DEIIR, de_iir);

done:
	I915_WRITE(DEIER, de_ier);
	(void)I915_READ(DEIER);