From 12bc0980e6c675631a1e61e528859408dc47ab96 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 2 Nov 2012 11:13:59 -0700 Subject: [PATCH] --- yaml --- r: 345281 b: refs/heads/master c: 073f34d9d49bdbadbea8198ddc3fbb7e736a94dd h: refs/heads/master i: 345279: 461a9b44a72a6768103f8bd00c56e18d11bd8d43 v: v3 --- [refs] | 2 +- trunk/drivers/gpu/drm/i915/i915_dma.c | 3 +++ trunk/drivers/gpu/drm/i915/i915_drv.c | 27 ++++++++++++++++++++++++--- trunk/drivers/gpu/drm/i915/i915_drv.h | 7 +++++++ 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/[refs] b/[refs] index 398d819680bb..c0a65c9f6bd3 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: a4da4fa4e55a8cea7fe603e7564e72db97b77a89 +refs/heads/master: 073f34d9d49bdbadbea8198ddc3fbb7e736a94dd diff --git a/trunk/drivers/gpu/drm/i915/i915_dma.c b/trunk/drivers/gpu/drm/i915/i915_dma.c index e67080729746..530cf90d13b0 100644 --- a/trunk/drivers/gpu/drm/i915/i915_dma.c +++ b/trunk/drivers/gpu/drm/i915/i915_dma.c @@ -1329,6 +1329,8 @@ static int i915_load_modeset_init(struct drm_device *dev) intel_modeset_gem_init(dev); + INIT_WORK(&dev_priv->console_resume_work, intel_console_resume); + ret = drm_irq_install(dev); if (ret) goto cleanup_gem; @@ -1723,6 +1725,7 @@ int i915_driver_unload(struct drm_device *dev) if (drm_core_check_feature(dev, DRIVER_MODESET)) { intel_fbdev_fini(dev); intel_modeset_cleanup(dev); + cancel_work_sync(&dev_priv->console_resume_work); /* * free the memory space allocated for the child device diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.c b/trunk/drivers/gpu/drm/i915/i915_drv.c index a08e9cafb7f2..cfd8920537c5 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.c +++ b/trunk/drivers/gpu/drm/i915/i915_drv.c @@ -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; } diff --git a/trunk/drivers/gpu/drm/i915/i915_drv.h b/trunk/drivers/gpu/drm/i915/i915_drv.h index 135b9db55279..f8fa63deb92c 100644 --- a/trunk/drivers/gpu/drm/i915/i915_drv.h +++ b/trunk/drivers/gpu/drm/i915/i915_drv.h @@ -887,6 +887,12 @@ typedef struct drm_i915_private { /* list of fbdev register on this device */ struct intel_fbdev *fbdev; + /* + * The console may be contended at resume, but we don't + * want it to block on it. + */ + struct work_struct console_resume_work; + struct backlight_device *backlight; struct drm_property *broadcast_rgb_property; @@ -1273,6 +1279,7 @@ extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv); extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv); extern void i915_update_gfx_val(struct drm_i915_private *dev_priv); +extern void intel_console_resume(struct work_struct *work); /* i915_irq.c */ void i915_hangcheck_elapsed(unsigned long data);