diff options
author | Jesse Barnes <jbarnes@virtuousgeek.org> | 2009-09-10 18:28:03 -0400 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2009-09-10 19:10:00 -0400 |
commit | c1c7af60892070e4b82ad63bbfb95ae745056de0 (patch) | |
tree | cac0b3068c8c85319f54d8ca8f43af040a6666c9 /drivers/gpu/drm/i915 | |
parent | 7e12715ecc47a8a59154afe2746e48998225bb69 (diff) |
drm/i915: force mode set at lid open time
Some laptop platforms will disable pipes and/or planes at lid close time
and not restore them when the lid is opened again. So catch the lid
event, and if the lid was opened, force a mode restore.
Fixes fdo bug #21230.
Acked-by: Matthew Garrett <mjg@redhat.com>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_lvds.c | 23 |
3 files changed, 27 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index df4597d9dac0..f2b8d27aef2a 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -222,6 +222,8 @@ typedef struct drm_i915_private { | |||
222 | unsigned int edp_support:1; | 222 | unsigned int edp_support:1; |
223 | int lvds_ssc_freq; | 223 | int lvds_ssc_freq; |
224 | 224 | ||
225 | struct notifier_block lid_notifier; | ||
226 | |||
225 | int crt_ddc_bus; /* -1 = unknown, else GPIO to use for CRT DDC */ | 227 | int crt_ddc_bus; /* -1 = unknown, else GPIO to use for CRT DDC */ |
226 | struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ | 228 | struct drm_i915_fence_reg fence_regs[16]; /* assume 965 */ |
227 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ | 229 | int fence_reg_start; /* 4 if userland hasn't ioctl'd us yet */ |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index cb5305ccb15c..92e0aae7070a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -24,6 +24,8 @@ | |||
24 | * Eric Anholt <eric@anholt.net> | 24 | * Eric Anholt <eric@anholt.net> |
25 | */ | 25 | */ |
26 | 26 | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/input.h> | ||
27 | #include <linux/i2c.h> | 29 | #include <linux/i2c.h> |
28 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
29 | #include "drmP.h" | 31 | #include "drmP.h" |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index dafc0da1c256..e190ff792bf0 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -27,6 +27,7 @@ | |||
27 | * Jesse Barnes <jesse.barnes@intel.com> | 27 | * Jesse Barnes <jesse.barnes@intel.com> |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <acpi/button.h> | ||
30 | #include <linux/dmi.h> | 31 | #include <linux/dmi.h> |
31 | #include <linux/i2c.h> | 32 | #include <linux/i2c.h> |
32 | #include "drmP.h" | 33 | #include "drmP.h" |
@@ -632,6 +633,19 @@ static int intel_lvds_get_modes(struct drm_connector *connector) | |||
632 | return 0; | 633 | return 0; |
633 | } | 634 | } |
634 | 635 | ||
636 | static int intel_lid_notify(struct notifier_block *nb, unsigned long val, | ||
637 | void *unused) | ||
638 | { | ||
639 | struct drm_i915_private *dev_priv = | ||
640 | container_of(nb, struct drm_i915_private, lid_notifier); | ||
641 | struct drm_device *dev = dev_priv->dev; | ||
642 | |||
643 | if (acpi_lid_open()) | ||
644 | drm_helper_resume_force_mode(dev); | ||
645 | |||
646 | return NOTIFY_OK; | ||
647 | } | ||
648 | |||
635 | /** | 649 | /** |
636 | * intel_lvds_destroy - unregister and free LVDS structures | 650 | * intel_lvds_destroy - unregister and free LVDS structures |
637 | * @connector: connector to free | 651 | * @connector: connector to free |
@@ -641,10 +655,14 @@ static int intel_lvds_get_modes(struct drm_connector *connector) | |||
641 | */ | 655 | */ |
642 | static void intel_lvds_destroy(struct drm_connector *connector) | 656 | static void intel_lvds_destroy(struct drm_connector *connector) |
643 | { | 657 | { |
658 | struct drm_device *dev = connector->dev; | ||
644 | struct intel_output *intel_output = to_intel_output(connector); | 659 | struct intel_output *intel_output = to_intel_output(connector); |
660 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
645 | 661 | ||
646 | if (intel_output->ddc_bus) | 662 | if (intel_output->ddc_bus) |
647 | intel_i2c_destroy(intel_output->ddc_bus); | 663 | intel_i2c_destroy(intel_output->ddc_bus); |
664 | if (dev_priv->lid_notifier.notifier_call) | ||
665 | acpi_lid_notifier_unregister(&dev_priv->lid_notifier); | ||
648 | drm_sysfs_connector_remove(connector); | 666 | drm_sysfs_connector_remove(connector); |
649 | drm_connector_cleanup(connector); | 667 | drm_connector_cleanup(connector); |
650 | kfree(connector); | 668 | kfree(connector); |
@@ -1011,6 +1029,11 @@ out: | |||
1011 | pwm |= PWM_PCH_ENABLE; | 1029 | pwm |= PWM_PCH_ENABLE; |
1012 | I915_WRITE(BLC_PWM_PCH_CTL1, pwm); | 1030 | I915_WRITE(BLC_PWM_PCH_CTL1, pwm); |
1013 | } | 1031 | } |
1032 | dev_priv->lid_notifier.notifier_call = intel_lid_notify; | ||
1033 | if (acpi_lid_notifier_register(&dev_priv->lid_notifier)) { | ||
1034 | DRM_DEBUG("lid notifier registration failed\n"); | ||
1035 | dev_priv->lid_notifier.notifier_call = NULL; | ||
1036 | } | ||
1014 | drm_sysfs_connector_add(connector); | 1037 | drm_sysfs_connector_add(connector); |
1015 | return; | 1038 | return; |
1016 | 1039 | ||