summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/i915/intel_pm.c
diff options
context:
space:
mode:
authorImre Deak <imre.deak@intel.com>2014-11-19 15:30:04 +0200
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-11-19 15:03:23 +0100
commitd4d70aa5960a7fbf3d887663f144c324a10619ba (patch)
tree834e941576feea0a00a2fc13a927c69a66dbe621 /drivers/gpu/drm/i915/intel_pm.c
parent3cc134e3ee09055d5a87193fc7eb0ecf4a59eaa1 (diff)
downloadlwn-d4d70aa5960a7fbf3d887663f144c324a10619ba.tar.gz
lwn-d4d70aa5960a7fbf3d887663f144c324a10619ba.zip
drm/i915: sanitize rps irq disabling
When disabling the RPS interrupts there is a tricky dependency between the thread disabling the interrupts, the RPS interrupt handler and the corresponding RPS work. The RPS work can reenable the interrupts, so there is no straightforward order in the disabling thread to (1) make sure that any RPS work is flushed and to (2) disable all RPS interrupts. Currently this is solved by masking the interrupts using two separate mask registers (first level display IMR and PM IMR) and doing the disabling when all first level interrupts are disabled. This works, but the requirement to run with all first level interrupts disabled is unnecessary making the suspend / unload time ordering of RPS disabling wrt. other unitialization steps difficult and error prone. Removing this restriction allows us to disable RPS early during suspend / unload and forget about it for the rest of the sequence. By adding a more explicit method for avoiding the above race, it also becomes easier to prove its correctness. Finally currently we can hit the WARN in snb_update_pm_irq(), when a final RPS work runs with the first level interrupts already disabled. This won't lead to any problem (due to the separate interrupt masks), but with the change in this and the next patch we can get rid of the WARN, while leaving it in place for other scenarios. To address the above points, add a new RPS interrupts_enabled flag and use this during RPS disabling to avoid requeuing the RPS work and reenabling of the RPS interrupts. Since the interrupt disabling happens now in intel_suspend_gt_powersave(), we will disable RPS interrupts explicitly during suspend (and not just through the first level mask), but there is no problem doing so, it's also more consistent and allows us to unify more of the RPS disabling during suspend and unload time in the next patch. v2/v3: - rebase on patch "drm/i915: move rps irq disable one level up" in the patchset Signed-off-by: Imre Deak <imre.deak@intel.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/intel_pm.c')
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index c5b2636093b1..96a948a18833 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -6186,9 +6186,17 @@ void intel_suspend_gt_powersave(struct drm_device *dev)
/* Interrupts should be disabled already to avoid re-arming. */
WARN_ON(intel_irqs_enabled(dev_priv));
+ if (INTEL_INFO(dev)->gen < 6)
+ return;
+
flush_delayed_work(&dev_priv->rps.delayed_resume_work);
- cancel_work_sync(&dev_priv->rps.work);
+ /*
+ * TODO: disable RPS interrupts on GEN9+ too once RPS support
+ * is added for it.
+ */
+ if (INTEL_INFO(dev)->gen < 9)
+ gen6_disable_rps_interrupts(dev);
/* Force GPU to min freq during suspend */
gen6_rps_idle(dev_priv);
@@ -6217,13 +6225,6 @@ void intel_disable_gt_powersave(struct drm_device *dev)
else
gen6_disable_rps(dev);
- /*
- * TODO: disable RPS interrupts on GEN9+ too once RPS support
- * is added for it.
- */
- if (INTEL_INFO(dev)->gen < 9)
- gen6_disable_rps_interrupts(dev);
-
dev_priv->rps.enabled = false;
mutex_unlock(&dev_priv->rps.hw_lock);
}