diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_lvds.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_lvds.c | 74 |
1 files changed, 72 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 9564ca44a97..9ab38efffec 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include "intel_drv.h" | 36 | #include "intel_drv.h" |
37 | #include "i915_drm.h" | 37 | #include "i915_drm.h" |
38 | #include "i915_drv.h" | 38 | #include "i915_drv.h" |
39 | #include <linux/acpi.h> | ||
39 | 40 | ||
40 | #define I915_LVDS "i915_lvds" | 41 | #define I915_LVDS "i915_lvds" |
41 | 42 | ||
@@ -252,14 +253,14 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, | |||
252 | 253 | ||
253 | /* Should never happen!! */ | 254 | /* Should never happen!! */ |
254 | if (!IS_I965G(dev) && intel_crtc->pipe == 0) { | 255 | if (!IS_I965G(dev) && intel_crtc->pipe == 0) { |
255 | printk(KERN_ERR "Can't support LVDS on pipe A\n"); | 256 | DRM_ERROR("Can't support LVDS on pipe A\n"); |
256 | return false; | 257 | return false; |
257 | } | 258 | } |
258 | 259 | ||
259 | /* Should never happen!! */ | 260 | /* Should never happen!! */ |
260 | list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, head) { | 261 | list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, head) { |
261 | if (tmp_encoder != encoder && tmp_encoder->crtc == encoder->crtc) { | 262 | if (tmp_encoder != encoder && tmp_encoder->crtc == encoder->crtc) { |
262 | printk(KERN_ERR "Can't enable LVDS and another " | 263 | DRM_ERROR("Can't enable LVDS and another " |
263 | "encoder on the same pipe\n"); | 264 | "encoder on the same pipe\n"); |
264 | return false; | 265 | return false; |
265 | } | 266 | } |
@@ -788,6 +789,65 @@ static const struct dmi_system_id intel_no_lvds[] = { | |||
788 | { } /* terminating entry */ | 789 | { } /* terminating entry */ |
789 | }; | 790 | }; |
790 | 791 | ||
792 | #ifdef CONFIG_ACPI | ||
793 | /* | ||
794 | * check_lid_device -- check whether @handle is an ACPI LID device. | ||
795 | * @handle: ACPI device handle | ||
796 | * @level : depth in the ACPI namespace tree | ||
797 | * @context: the number of LID device when we find the device | ||
798 | * @rv: a return value to fill if desired (Not use) | ||
799 | */ | ||
800 | static acpi_status | ||
801 | check_lid_device(acpi_handle handle, u32 level, void *context, | ||
802 | void **return_value) | ||
803 | { | ||
804 | struct acpi_device *acpi_dev; | ||
805 | int *lid_present = context; | ||
806 | |||
807 | acpi_dev = NULL; | ||
808 | /* Get the acpi device for device handle */ | ||
809 | if (acpi_bus_get_device(handle, &acpi_dev) || !acpi_dev) { | ||
810 | /* If there is no ACPI device for handle, return */ | ||
811 | return AE_OK; | ||
812 | } | ||
813 | |||
814 | if (!strncmp(acpi_device_hid(acpi_dev), "PNP0C0D", 7)) | ||
815 | *lid_present = 1; | ||
816 | |||
817 | return AE_OK; | ||
818 | } | ||
819 | |||
820 | /** | ||
821 | * check whether there exists the ACPI LID device by enumerating the ACPI | ||
822 | * device tree. | ||
823 | */ | ||
824 | static int intel_lid_present(void) | ||
825 | { | ||
826 | int lid_present = 0; | ||
827 | |||
828 | if (acpi_disabled) { | ||
829 | /* If ACPI is disabled, there is no ACPI device tree to | ||
830 | * check, so assume the LID device would have been present. | ||
831 | */ | ||
832 | return 1; | ||
833 | } | ||
834 | |||
835 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
836 | ACPI_UINT32_MAX, | ||
837 | check_lid_device, &lid_present, NULL); | ||
838 | |||
839 | return lid_present; | ||
840 | } | ||
841 | #else | ||
842 | static int intel_lid_present(void) | ||
843 | { | ||
844 | /* In the absence of ACPI built in, assume that the LID device would | ||
845 | * have been present. | ||
846 | */ | ||
847 | return 1; | ||
848 | } | ||
849 | #endif | ||
850 | |||
791 | /** | 851 | /** |
792 | * intel_lvds_init - setup LVDS connectors on this device | 852 | * intel_lvds_init - setup LVDS connectors on this device |
793 | * @dev: drm device | 853 | * @dev: drm device |
@@ -811,6 +871,16 @@ void intel_lvds_init(struct drm_device *dev) | |||
811 | if (dmi_check_system(intel_no_lvds)) | 871 | if (dmi_check_system(intel_no_lvds)) |
812 | return; | 872 | return; |
813 | 873 | ||
874 | /* Assume that any device without an ACPI LID device also doesn't | ||
875 | * have an integrated LVDS. We would be better off parsing the BIOS | ||
876 | * to get a reliable indicator, but that code isn't written yet. | ||
877 | * | ||
878 | * In the case of all-in-one desktops using LVDS that we've seen, | ||
879 | * they're using SDVO LVDS. | ||
880 | */ | ||
881 | if (!intel_lid_present()) | ||
882 | return; | ||
883 | |||
814 | if (IS_IGDNG(dev)) { | 884 | if (IS_IGDNG(dev)) { |
815 | if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) | 885 | if ((I915_READ(PCH_LVDS) & LVDS_DETECTED) == 0) |
816 | return; | 886 | return; |