[PATCH 35/38] bsw-irq

Chris Wilson chris at chris-wilson.co.uk
Wed Sep 13 13:02:38 UTC 2017


---
 drivers/gpu/drm/i915/i915_irq.c | 52 ++++++++++++++++++++++++-----------------
 1 file changed, 30 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index e1d503b7352e..d58fa40e922e 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1703,16 +1703,17 @@ static void gen9_guc_irq_handler(struct drm_i915_private *dev_priv, u32 gt_iir)
 	}
 }
 
-static void valleyview_pipestat_irq_ack(struct drm_i915_private *dev_priv,
+static bool valleyview_pipestat_irq_ack(struct drm_i915_private *dev_priv,
 					u32 iir, u32 pipe_stats[I915_MAX_PIPES])
 {
+	bool handled = false;
 	int pipe;
 
 	spin_lock(&dev_priv->irq_lock);
 
 	if (!dev_priv->display_irqs_enabled) {
 		spin_unlock(&dev_priv->irq_lock);
-		return;
+		return false;
 	}
 
 	for_each_pipe(dev_priv, pipe) {
@@ -1757,8 +1758,12 @@ static void valleyview_pipestat_irq_ack(struct drm_i915_private *dev_priv,
 		if (pipe_stats[pipe] & (PIPE_FIFO_UNDERRUN_STATUS |
 					PIPESTAT_INT_STATUS_MASK))
 			I915_WRITE(reg, pipe_stats[pipe]);
+
+		handled = true;
 	}
 	spin_unlock(&dev_priv->irq_lock);
+
+	return handled;
 }
 
 static void valleyview_pipestat_irq_handler(struct drm_i915_private *dev_priv,
@@ -1927,6 +1932,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
 		u32 pipe_stats[I915_MAX_PIPES] = {};
 		u32 hotplug_status = 0;
 		u32 ier = 0;
+		bool has_pipe_stats = false;
 
 		master_ctl = I915_READ(GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL;
 		iir = I915_READ(VLV_IIR);
@@ -1950,40 +1956,42 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
 		 * bits this time around.
 		 */
 		I915_WRITE(GEN8_MASTER_IRQ, 0);
-		ier = I915_READ(VLV_IER);
-		I915_WRITE(VLV_IER, 0);
 
-		gen8_gt_irq_ack(dev_priv, master_ctl, gt_iir);
+		if (iir) {
+			ier = I915_READ(VLV_IER);
+			I915_WRITE(VLV_IER, 0);
 
-		if (iir & I915_DISPLAY_PORT_INTERRUPT)
-			hotplug_status = i9xx_hpd_irq_ack(dev_priv);
+			if (iir & I915_DISPLAY_PORT_INTERRUPT)
+				hotplug_status = i9xx_hpd_irq_ack(dev_priv);
 
-		/* Call regardless, as some status bits might not be
-		 * signalled in iir */
-		valleyview_pipestat_irq_ack(dev_priv, iir, pipe_stats);
+			if (iir & (I915_LPE_PIPE_A_INTERRUPT |
+				   I915_LPE_PIPE_B_INTERRUPT |
+				   I915_LPE_PIPE_C_INTERRUPT))
+				intel_lpe_audio_irq_handler(dev_priv);
 
-		if (iir & (I915_LPE_PIPE_A_INTERRUPT |
-			   I915_LPE_PIPE_B_INTERRUPT |
-			   I915_LPE_PIPE_C_INTERRUPT))
-			intel_lpe_audio_irq_handler(dev_priv);
+			/* Call regardless, as some status bits might not be
+			 * signalled in iir */
+			has_pipe_stats = 
+				valleyview_pipestat_irq_ack(dev_priv, iir, pipe_stats);
 
-		/*
-		 * VLV_IIR is single buffered, and reflects the level
-		 * from PIPESTAT/PORT_HOTPLUG_STAT, hence clear it last.
-		 */
-		if (iir)
+			/*
+			 * VLV_IIR is single buffered, and reflects the level
+			 * from PIPESTAT/PORT_HOTPLUG_STAT, hence clear it last.
+			 */
 			I915_WRITE(VLV_IIR, iir);
+			I915_WRITE(VLV_IER, ier);
+		}
 
-		I915_WRITE(VLV_IER, ier);
+		gen8_gt_irq_ack(dev_priv, master_ctl, gt_iir);
 		I915_WRITE(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL);
-		POSTING_READ(GEN8_MASTER_IRQ);
 
 		gen8_gt_irq_handler(dev_priv, master_ctl, gt_iir);
 
 		if (hotplug_status)
 			i9xx_hpd_irq_handler(dev_priv, hotplug_status);
 
-		valleyview_pipestat_irq_handler(dev_priv, pipe_stats);
+		if (has_pipe_stats)
+			valleyview_pipestat_irq_handler(dev_priv, pipe_stats);
 	} while (0);
 
 	enable_rpm_wakeref_asserts(dev_priv);
-- 
2.14.1



More information about the Intel-gfx-trybot mailing list