This way all changes to SDEIMR all go through the same function, with the exception of the (single-threaded) setup/teardown code. For paranoia again add an assert_spin_locked. Signed-off-by: Daniel Vetter <daniel.vetter at ffwll.ch> --- drivers/gpu/drm/i915/i915_irq.c | 42 +++++++++++++++++++++++------------------ 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 95e15cd..c2b4b09 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -177,6 +177,20 @@ static void ivybridge_set_fifo_underrun_reporting(struct drm_device *dev, } } +static void ibx_display_interrupt_update(struct drm_i915_private *dev_priv, + uint32_t interrupt_mask, + uint32_t enabled_irq_mask) +{ + uint32_t sdeimr = I915_READ(SDEIMR); + sdeimr &= ~interrupt_mask; + sdeimr |= ~enabled_irq_mask; + + assert_spin_locked(&dev_priv->irq_lock); + + I915_WRITE(SDEIMR, sdeimr); + POSTING_READ(SDEIMR); +} + static void ibx_set_fifo_underrun_reporting(struct intel_crtc *crtc, bool enable) { @@ -185,12 +199,8 @@ static void ibx_set_fifo_underrun_reporting(struct intel_crtc *crtc, uint32_t bit = (crtc->pipe == PIPE_A) ? SDE_TRANSA_FIFO_UNDER : SDE_TRANSB_FIFO_UNDER; - if (enable) - I915_WRITE(SDEIMR, I915_READ(SDEIMR) & ~bit); - else - I915_WRITE(SDEIMR, I915_READ(SDEIMR) | bit); - - POSTING_READ(SDEIMR); + ibx_display_interrupt_update(dev_priv, bit, + enable ? bit : 0); } static void cpt_set_fifo_underrun_reporting(struct drm_device *dev, @@ -206,13 +216,10 @@ static void cpt_set_fifo_underrun_reporting(struct drm_device *dev, I915_WRITE(SERR_INT, SERR_INT_TRANS_A_FIFO_UNDERRUN | SERR_INT_TRANS_B_FIFO_UNDERRUN | SERR_INT_TRANS_C_FIFO_UNDERRUN); - - I915_WRITE(SDEIMR, I915_READ(SDEIMR) & ~SDE_ERROR_CPT); - } else { - I915_WRITE(SDEIMR, I915_READ(SDEIMR) | SDE_ERROR_CPT); } - POSTING_READ(SDEIMR); + ibx_display_interrupt_update(dev_priv, SDE_ERROR_CPT, + enable ? SDE_ERROR_CPT : 0); } /** @@ -2585,22 +2592,21 @@ static void ibx_hpd_irq_setup(struct drm_device *dev) drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; struct drm_mode_config *mode_config = &dev->mode_config; struct intel_encoder *intel_encoder; - u32 mask = ~I915_READ(SDEIMR); - u32 hotplug; + u32 hotplug_irqs, hotplug, enabled_irqs = 0; if (HAS_PCH_IBX(dev)) { - mask &= ~SDE_HOTPLUG_MASK; + hotplug_irqs = SDE_HOTPLUG_MASK; list_for_each_entry(intel_encoder, &mode_config->encoder_list, base.head) if (dev_priv->hpd_stats[intel_encoder->hpd_pin].hpd_mark == HPD_ENABLED) - mask |= hpd_ibx[intel_encoder->hpd_pin]; + enabled_irqs |= hpd_ibx[intel_encoder->hpd_pin]; } else { - mask &= ~SDE_HOTPLUG_MASK_CPT; + hotplug_irqs = SDE_HOTPLUG_MASK_CPT; list_for_each_entry(intel_encoder, &mode_config->encoder_list, base.head) if (dev_priv->hpd_stats[intel_encoder->hpd_pin].hpd_mark == HPD_ENABLED) - mask |= hpd_cpt[intel_encoder->hpd_pin]; + enabled_irqs |= hpd_cpt[intel_encoder->hpd_pin]; } - I915_WRITE(SDEIMR, ~mask); + ibx_display_interrupt_update(dev_priv, hotplug_irqs, enabled_irqs); /* * Enable digital hotplug on the PCH, and configure the DP short pulse -- 1.8.1.4