|
@@ -523,6 +523,18 @@ int i915_suspend(struct drm_device *dev, pm_message_t state)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+void intel_console_resume(struct work_struct *work)
|
|
|
+{
|
|
|
+ struct drm_i915_private *dev_priv =
|
|
|
+ container_of(work, struct drm_i915_private,
|
|
|
+ console_resume_work);
|
|
|
+ struct drm_device *dev = dev_priv->dev;
|
|
|
+
|
|
|
+ console_lock();
|
|
|
+ intel_fbdev_set_suspend(dev, 0);
|
|
|
+ console_unlock();
|
|
|
+}
|
|
|
+
|
|
|
static int i915_drm_thaw(struct drm_device *dev)
|
|
|
{
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
@@ -559,9 +571,18 @@ static int i915_drm_thaw(struct drm_device *dev)
|
|
|
|
|
|
dev_priv->modeset_on_lid = 0;
|
|
|
|
|
|
- console_lock();
|
|
|
- intel_fbdev_set_suspend(dev, 0);
|
|
|
- console_unlock();
|
|
|
+ /*
|
|
|
+ * The console lock can be pretty contented on resume due
|
|
|
+ * to all the printk activity. Try to keep it out of the hot
|
|
|
+ * path of resume if possible.
|
|
|
+ */
|
|
|
+ if (console_trylock()) {
|
|
|
+ intel_fbdev_set_suspend(dev, 0);
|
|
|
+ console_unlock();
|
|
|
+ } else {
|
|
|
+ schedule_work(&dev_priv->console_resume_work);
|
|
|
+ }
|
|
|
+
|
|
|
return error;
|
|
|
}
|
|
|
|