aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2012-11-02 14:13:59 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-11-11 17:51:40 -0500
commit073f34d9d49bdbadbea8198ddc3fbb7e736a94dd (patch)
tree6239b1055003f01aa92624fa4873f45376be5cf2
parenta4da4fa4e55a8cea7fe603e7564e72db97b77a89 (diff)
drm/i915: don't block resume on fb console resume v2
The console lock can be contended, so rather than prevent other drivers after us from being held up, queue the console suspend into the global work queue that can happen anytime. I've measured this to take around 200ms on my T420. Combined with the ring freq/turbo change, we should save almost 1/2 a second on resume. v2: use console_trylock() to try to resume the console immediately (Chris) Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org> [danvet: move dev_priv->console_resume_work next to the fbdev pointer.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-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);