aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index d6bd0d7a7486..61cd87999df3 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -86,6 +86,8 @@ static void i915_hpd_irq_setup(struct drm_device *dev);
86static void 86static void
87ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask) 87ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
88{ 88{
89 assert_spin_locked(&dev_priv->irq_lock);
90
89 if ((dev_priv->irq_mask & mask) != 0) { 91 if ((dev_priv->irq_mask & mask) != 0) {
90 dev_priv->irq_mask &= ~mask; 92 dev_priv->irq_mask &= ~mask;
91 I915_WRITE(DEIMR, dev_priv->irq_mask); 93 I915_WRITE(DEIMR, dev_priv->irq_mask);
@@ -96,6 +98,8 @@ ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
96static void 98static void
97ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask) 99ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
98{ 100{
101 assert_spin_locked(&dev_priv->irq_lock);
102
99 if ((dev_priv->irq_mask & mask) != mask) { 103 if ((dev_priv->irq_mask & mask) != mask) {
100 dev_priv->irq_mask |= mask; 104 dev_priv->irq_mask |= mask;
101 I915_WRITE(DEIMR, dev_priv->irq_mask); 105 I915_WRITE(DEIMR, dev_priv->irq_mask);
@@ -109,6 +113,8 @@ static bool ivb_can_enable_err_int(struct drm_device *dev)
109 struct intel_crtc *crtc; 113 struct intel_crtc *crtc;
110 enum pipe pipe; 114 enum pipe pipe;
111 115
116 assert_spin_locked(&dev_priv->irq_lock);
117
112 for_each_pipe(pipe) { 118 for_each_pipe(pipe) {
113 crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); 119 crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
114 120
@@ -1217,8 +1223,11 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg)
1217 /* On Haswell, also mask ERR_INT because we don't want to risk 1223 /* On Haswell, also mask ERR_INT because we don't want to risk
1218 * generating "unclaimed register" interrupts from inside the interrupt 1224 * generating "unclaimed register" interrupts from inside the interrupt
1219 * handler. */ 1225 * handler. */
1220 if (IS_HASWELL(dev)) 1226 if (IS_HASWELL(dev)) {
1227 spin_lock(&dev_priv->irq_lock);
1221 ironlake_disable_display_irq(dev_priv, DE_ERR_INT_IVB); 1228 ironlake_disable_display_irq(dev_priv, DE_ERR_INT_IVB);
1229 spin_unlock(&dev_priv->irq_lock);
1230 }
1222 1231
1223 gt_iir = I915_READ(GTIIR); 1232 gt_iir = I915_READ(GTIIR);
1224 if (gt_iir) { 1233 if (gt_iir) {
@@ -1271,8 +1280,12 @@ static irqreturn_t ivybridge_irq_handler(int irq, void *arg)
1271 ret = IRQ_HANDLED; 1280 ret = IRQ_HANDLED;
1272 } 1281 }
1273 1282
1274 if (IS_HASWELL(dev) && ivb_can_enable_err_int(dev)) 1283 if (IS_HASWELL(dev)) {
1275 ironlake_enable_display_irq(dev_priv, DE_ERR_INT_IVB); 1284 spin_lock(&dev_priv->irq_lock);
1285 if (ivb_can_enable_err_int(dev))
1286 ironlake_enable_display_irq(dev_priv, DE_ERR_INT_IVB);
1287 spin_unlock(&dev_priv->irq_lock);
1288 }
1276 1289
1277 I915_WRITE(DEIER, de_ier); 1290 I915_WRITE(DEIER, de_ier);
1278 POSTING_READ(DEIER); 1291 POSTING_READ(DEIER);
@@ -2697,6 +2710,8 @@ static void ibx_irq_postinstall(struct drm_device *dev)
2697 2710
2698static int ironlake_irq_postinstall(struct drm_device *dev) 2711static int ironlake_irq_postinstall(struct drm_device *dev)
2699{ 2712{
2713 unsigned long irqflags;
2714
2700 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; 2715 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
2701 /* enable kind of interrupts always enabled */ 2716 /* enable kind of interrupts always enabled */
2702 u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | 2717 u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
@@ -2735,7 +2750,13 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
2735 /* Clear & enable PCU event interrupts */ 2750 /* Clear & enable PCU event interrupts */
2736 I915_WRITE(DEIIR, DE_PCU_EVENT); 2751 I915_WRITE(DEIIR, DE_PCU_EVENT);
2737 I915_WRITE(DEIER, I915_READ(DEIER) | DE_PCU_EVENT); 2752 I915_WRITE(DEIER, I915_READ(DEIER) | DE_PCU_EVENT);
2753
2754 /* spinlocking not required here for correctness since interrupt
2755 * setup is guaranteed to run in single-threaded context. But we
2756 * need it to make the assert_spin_locked happy. */
2757 spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
2738 ironlake_enable_display_irq(dev_priv, DE_PCU_EVENT); 2758 ironlake_enable_display_irq(dev_priv, DE_PCU_EVENT);
2759 spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);
2739 } 2760 }
2740 2761
2741 return 0; 2762 return 0;