summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2013-06-27 11:44:59 (GMT)
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-07-01 09:14:55 (GMT)
commit6005ce42433df3f69de99d7e730383a6adb852ef (patch)
tree6e57d18f44d5a929c76013d0c62aa9c8253843e9 /drivers/gpu/drm/i915
parent4bc9d4301573403c578e545b34dceac61891f39c (diff)
downloadlinux-fsl-qoriq-6005ce42433df3f69de99d7e730383a6adb852ef.tar.xz
drm/i915: close tiny race in the ilk pcu even interrupt setup
By the time we write DEIER in the postinstall hook the interrupt handler could run any time. And it does modify DEIER to handle interrupts. Hence the DEIER read-modify-write cycle for enabling the PCU event source is racy. Close this races the same way we handle vblank interrupts: Unconditionally enable the interrupt in the IER register, but conditionally mask it in IMR. The later poses no such race since the interrupt handler does not touch DEIMR. Also update the comment, the clearing has already happened unconditionally above. v2: Actually shove the updated comment into the right train^W commit, as spotted by Paulo. Cc: Paulo Zanoni <przanoni@gmail.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 61cd879..bff9abd 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2725,7 +2725,8 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
/* should always can generate irq */
I915_WRITE(DEIIR, I915_READ(DEIIR));
I915_WRITE(DEIMR, dev_priv->irq_mask);
- I915_WRITE(DEIER, display_mask | DE_PIPEA_VBLANK | DE_PIPEB_VBLANK);
+ I915_WRITE(DEIER, display_mask |
+ DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT);
POSTING_READ(DEIER);
dev_priv->gt_irq_mask = ~0;
@@ -2747,11 +2748,9 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
ibx_irq_postinstall(dev);
if (IS_IRONLAKE_M(dev)) {
- /* Clear & enable PCU event interrupts */
- I915_WRITE(DEIIR, DE_PCU_EVENT);
- I915_WRITE(DEIER, I915_READ(DEIER) | DE_PCU_EVENT);
-
- /* spinlocking not required here for correctness since interrupt
+ /* Enable PCU event interrupts
+ *
+ * spinlocking not required here for correctness since interrupt
* setup is guaranteed to run in single-threaded context. But we
* need it to make the assert_spin_locked happy. */
spin_lock_irqsave(&dev_priv->irq_lock, irqflags);