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) | |||
| 89 | pci_set_power_state(dev->pdev, PCI_D3hot); | 89 | pci_set_power_state(dev->pdev, PCI_D3hot); |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | dev_priv->suspended = 1; | 92 | /* Modeset on resume, not lid events */ |
| 93 | dev_priv->modeset_on_lid = 0; | ||
| 93 | 94 | ||
| 94 | return 0; | 95 | return 0; |
| 95 | } | 96 | } |
| @@ -124,7 +125,7 @@ static int i915_resume(struct drm_device *dev) | |||
| 124 | drm_helper_resume_force_mode(dev); | 125 | drm_helper_resume_force_mode(dev); |
| 125 | } | 126 | } |
| 126 | 127 | ||
| 127 | dev_priv->suspended = 0; | 128 | dev_priv->modeset_on_lid = 0; |
| 128 | 129 | ||
| 129 | return ret; | 130 | return ret; |
| 130 | } | 131 | } |
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 { | |||
| 274 | struct drm_i915_display_funcs display; | 274 | struct drm_i915_display_funcs display; |
| 275 | 275 | ||
| 276 | /* Register state */ | 276 | /* Register state */ |
| 277 | bool suspended; | 277 | bool modeset_on_lid; |
| 278 | u8 saveLBB; | 278 | u8 saveLBB; |
| 279 | u32 saveDSPACNTR; | 279 | u32 saveDSPACNTR; |
| 280 | u32 saveDSPBCNTR; | 280 | 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) | |||
| 656 | return 0; | 656 | return 0; |
| 657 | } | 657 | } |
| 658 | 658 | ||
| 659 | /* | ||
| 660 | * Lid events. Note the use of 'modeset_on_lid': | ||
| 661 | * - we set it on lid close, and reset it on open | ||
| 662 | * - we use it as a "only once" bit (ie we ignore | ||
| 663 | * duplicate events where it was already properly | ||
| 664 | * set/reset) | ||
| 665 | * - the suspend/resume paths will also set it to | ||
| 666 | * zero, since they restore the mode ("lid open"). | ||
| 667 | */ | ||
| 659 | static int intel_lid_notify(struct notifier_block *nb, unsigned long val, | 668 | static int intel_lid_notify(struct notifier_block *nb, unsigned long val, |
| 660 | void *unused) | 669 | void *unused) |
| 661 | { | 670 | { |
| @@ -663,13 +672,19 @@ static int intel_lid_notify(struct notifier_block *nb, unsigned long val, | |||
| 663 | container_of(nb, struct drm_i915_private, lid_notifier); | 672 | container_of(nb, struct drm_i915_private, lid_notifier); |
| 664 | struct drm_device *dev = dev_priv->dev; | 673 | struct drm_device *dev = dev_priv->dev; |
| 665 | 674 | ||
| 666 | if (acpi_lid_open() && !dev_priv->suspended) { | 675 | if (!acpi_lid_open()) { |
| 667 | mutex_lock(&dev->mode_config.mutex); | 676 | dev_priv->modeset_on_lid = 1; |
| 668 | drm_helper_resume_force_mode(dev); | 677 | return NOTIFY_OK; |
| 669 | mutex_unlock(&dev->mode_config.mutex); | ||
| 670 | } | 678 | } |
| 671 | 679 | ||
| 672 | drm_sysfs_hotplug_event(dev_priv->dev); | 680 | if (!dev_priv->modeset_on_lid) |
| 681 | return NOTIFY_OK; | ||
| 682 | |||
| 683 | dev_priv->modeset_on_lid = 0; | ||
| 684 | |||
| 685 | mutex_lock(&dev->mode_config.mutex); | ||
| 686 | drm_helper_resume_force_mode(dev); | ||
| 687 | mutex_unlock(&dev->mode_config.mutex); | ||
| 673 | 688 | ||
| 674 | return NOTIFY_OK; | 689 | return NOTIFY_OK; |
| 675 | } | 690 | } |
