[Intel-gfx] [PATCH] drm/i915: Cancel outstanding modeset workers before suspend
Chris Wilson
chris at chris-wilson.co.uk
Tue Aug 6 14:24:02 CEST 2013
Upon resume we will do a complete restoration of the mode and so reset
all tasks, but during suspend (and unload) we need to make sure that no
workers run concurrently with our suspend code. Or worse just after.
The issue was first raised whilst tackling a suspend issue with Takashi
Iwai (http://lists.freedesktop.org/archives/intel-gfx/2012-April/016738.html)
and then it was independently rediscovered by Chuanshen Lui.
v2: Rebase for the lost year.
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
Cc: Takashi Iwai <tiwai at suse.de>
Cc: "Liu, Chuansheng" <chuansheng.liu at intel.com>
---
drivers/gpu/drm/i915/i915_drv.h | 1 +
drivers/gpu/drm/i915/intel_display.c | 21 ++++++++++++++++-----
2 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 64b5d55..cb2c59d 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -2130,6 +2130,7 @@ extern void intel_modeset_init_hw(struct drm_device *dev);
extern void intel_modeset_suspend_hw(struct drm_device *dev);
extern void intel_modeset_init(struct drm_device *dev);
extern void intel_modeset_gem_init(struct drm_device *dev);
+extern void intel_modeset_quiesce(struct drm_device *dev);
extern void intel_modeset_cleanup(struct drm_device *dev);
extern int intel_modeset_vga_set_state(struct drm_device *dev, bool state);
extern void intel_modeset_setup_hw_state(struct drm_device *dev,
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 7c7325e..0584480 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -9891,6 +9891,7 @@ void intel_modeset_init_hw(struct drm_device *dev)
void intel_modeset_suspend_hw(struct drm_device *dev)
{
+ intel_modeset_quiesce(dev);
intel_suspend_hw(dev);
}
@@ -10324,9 +10325,19 @@ void intel_modeset_gem_init(struct drm_device *dev)
intel_modeset_setup_hw_state(dev, false);
}
-void intel_modeset_cleanup(struct drm_device *dev)
+void intel_modeset_quiesce(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
+
+ cancel_work_sync(&dev_priv->hotplug_work);
+ cancel_work_sync(&dev_priv->rps.work);
+
+ /* catch all required for dev_priv->wq */
+ flush_scheduled_work();
+}
+
+void intel_modeset_cleanup(struct drm_device *dev)
+{
struct drm_crtc *crtc;
struct intel_crtc *intel_crtc;
@@ -10336,7 +10347,10 @@ void intel_modeset_cleanup(struct drm_device *dev)
* experience fancy races otherwise.
*/
drm_irq_uninstall(dev);
- cancel_work_sync(&dev_priv->hotplug_work);
+
+ /* flush any delayed tasks or pending work */
+ intel_modeset_quiesce(dev);
+
/*
* Due to the hpd irq storm handling the hotplug work can re-arm the
* poll handlers. Hence disable polling after hpd handling is shut down.
@@ -10364,9 +10378,6 @@ void intel_modeset_cleanup(struct drm_device *dev)
mutex_unlock(&dev->struct_mutex);
- /* flush any delayed tasks or pending work */
- flush_scheduled_work();
-
/* destroy backlight, if any, before the connectors */
intel_panel_destroy_backlight(dev);
--
1.8.4.rc1
More information about the Intel-gfx
mailing list