diff options
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_lvds.c | 25 |
3 files changed, 24 insertions, 8 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index b93814c0d3e2..7f436ec075f6 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -89,7 +89,8 @@ static int i915_suspend(struct drm_device *dev, pm_message_t state) pci_set_power_state(dev->pdev, PCI_D3hot); } - dev_priv->suspended = 1; + /* Modeset on resume, not lid events */ + dev_priv->modeset_on_lid = 0; return 0; } @@ -124,7 +125,7 @@ static int i915_resume(struct drm_device *dev) drm_helper_resume_force_mode(dev); } - dev_priv->suspended = 0; + dev_priv->modeset_on_lid = 0; return ret; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6035d3dae851..c5df2234418d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -274,7 +274,7 @@ typedef struct drm_i915_private { struct drm_i915_display_funcs display; /* Register state */ - bool suspended; + bool modeset_on_lid; u8 saveLBB; u32 saveDSPACNTR; u32 saveDSPBCNTR; diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 98ae3d73577e..808bbe412ba8 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -656,6 +656,15 @@ static int intel_lvds_get_modes(struct drm_connector *connector) return 0; } +/* + * Lid events. Note the use of 'modeset_on_lid': + * - we set it on lid close, and reset it on open + * - we use it as a "only once" bit (ie we ignore + * duplicate events where it was already properly + * set/reset) + * - the suspend/resume paths will also set it to + * zero, since they restore the mode ("lid open"). + */ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, void *unused) { @@ -663,13 +672,19 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, container_of(nb, struct drm_i915_private, lid_notifier); struct drm_device *dev = dev_priv->dev; - if (acpi_lid_open() && !dev_priv->suspended) { - mutex_lock(&dev->mode_config.mutex); - drm_helper_resume_force_mode(dev); - mutex_unlock(&dev->mode_config.mutex); + if (!acpi_lid_open()) { + dev_priv->modeset_on_lid = 1; + return NOTIFY_OK; } - drm_sysfs_hotplug_event(dev_priv->dev); + if (!dev_priv->modeset_on_lid) + return NOTIFY_OK; + + dev_priv->modeset_on_lid = 0; + + mutex_lock(&dev->mode_config.mutex); + drm_helper_resume_force_mode(dev); + mutex_unlock(&dev->mode_config.mutex); return NOTIFY_OK; } |