aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c3
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c27
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h7
3 files changed, 34 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index e67080729746..530cf90d13b0 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -1329,6 +1329,8 @@ static int i915_load_modeset_init(struct drm_device *dev)
1329 1329
1330 intel_modeset_gem_init(dev); 1330 intel_modeset_gem_init(dev);
1331 1331
1332 INIT_WORK(&dev_priv->console_resume_work, intel_console_resume);
1333
1332 ret = drm_irq_install(dev); 1334 ret = drm_irq_install(dev);
1333 if (ret) 1335 if (ret)
1334 goto cleanup_gem; 1336 goto cleanup_gem;
@@ -1723,6 +1725,7 @@ int i915_driver_unload(struct drm_device *dev)
1723 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 1725 if (drm_core_check_feature(dev, DRIVER_MODESET)) {
1724 intel_fbdev_fini(dev); 1726 intel_fbdev_fini(dev);
1725 intel_modeset_cleanup(dev); 1727 intel_modeset_cleanup(dev);
1728 cancel_work_sync(&dev_priv->console_resume_work);
1726 1729
1727 /* 1730 /*
1728 * free the memory space allocated for the child device 1731 * free the memory space allocated for the child device
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index a08e9cafb7f2..cfd8920537c5 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -523,6 +523,18 @@ int i915_suspend(struct drm_device *dev, pm_message_t state)
523 return 0; 523 return 0;
524} 524}
525 525
526void intel_console_resume(struct work_struct *work)
527{
528 struct drm_i915_private *dev_priv =
529 container_of(work, struct drm_i915_private,
530 console_resume_work);
531 struct drm_device *dev = dev_priv->dev;
532
533 console_lock();
534 intel_fbdev_set_suspend(dev, 0);
535 console_unlock();
536}
537
526static int i915_drm_thaw(struct drm_device *dev) 538static int i915_drm_thaw(struct drm_device *dev)
527{ 539{
528 struct drm_i915_private *dev_priv = dev->dev_private; 540 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -559,9 +571,18 @@ static int i915_drm_thaw(struct drm_device *dev)
559 571
560 dev_priv->modeset_on_lid = 0; 572 dev_priv->modeset_on_lid = 0;
561 573
562 console_lock(); 574 /*
563 intel_fbdev_set_suspend(dev, 0); 575 * The console lock can be pretty contented on resume due
564 console_unlock(); 576 * to all the printk activity. Try to keep it out of the hot
577 * path of resume if possible.
578 */
579 if (console_trylock()) {
580 intel_fbdev_set_suspend(dev, 0);
581 console_unlock();
582 } else {
583 schedule_work(&dev_priv->console_resume_work);
584 }
585
565 return error; 586 return error;
566} 587}
567 588
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 135b9db55279..f8fa63deb92c 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -887,6 +887,12 @@ typedef struct drm_i915_private {
887 /* list of fbdev register on this device */ 887 /* list of fbdev register on this device */
888 struct intel_fbdev *fbdev; 888 struct intel_fbdev *fbdev;
889 889
890 /*
891 * The console may be contended at resume, but we don't
892 * want it to block on it.
893 */
894 struct work_struct console_resume_work;
895
890 struct backlight_device *backlight; 896 struct backlight_device *backlight;
891 897
892 struct drm_property *broadcast_rgb_property; 898 struct drm_property *broadcast_rgb_property;
@@ -1273,6 +1279,7 @@ extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv);
1273extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv); 1279extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv);
1274extern void i915_update_gfx_val(struct drm_i915_private *dev_priv); 1280extern void i915_update_gfx_val(struct drm_i915_private *dev_priv);
1275 1281
1282extern void intel_console_resume(struct work_struct *work);
1276 1283
1277/* i915_irq.c */ 1284/* i915_irq.c */
1278void i915_hangcheck_elapsed(unsigned long data); 1285void i915_hangcheck_elapsed(unsigned long data);