ACPI: Populate DIDL before registering ACPI video device on Intel

Intel graphics hardware that implements the ACPI IGD OpRegion spec
requires that the list of display devices be populated before any ACPI
video methods are called. Detect when this is the case and defer
registration until the opregion code calls it. Fixes crashes on HP
laptops.

http://bugzilla.kernel.org/show_bug.cgi?id=11259

Signed-off-by: Matthew Garrett <mjg@redhat.com>
Acked-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
Matthew Garrett
2009-03-19 21:35:39 +00:00
committed by Len Brown
부모 c60d638e29
커밋 74a365b3f3
6개의 변경된 파일119개의 추가작업 그리고 6개의 파일을 삭제

파일 보기

@@ -37,6 +37,8 @@
#include <linux/thermal.h>
#include <linux/video_output.h>
#include <linux/sort.h>
#include <linux/pci.h>
#include <linux/pci_ids.h>
#include <asm/uaccess.h>
#include <acpi/acpi_bus.h>
@@ -2251,7 +2253,27 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
return 0;
}
static int __init acpi_video_init(void)
static int __init intel_opregion_present(void)
{
#if defined(CONFIG_DRM_I915) || defined(CONFIG_DRM_I915_MODULE)
struct pci_dev *dev = NULL;
u32 address;
for_each_pci_dev(dev) {
if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
continue;
if (dev->vendor != PCI_VENDOR_ID_INTEL)
continue;
pci_read_config_dword(dev, 0xfc, &address);
if (!address)
continue;
return 1;
}
#endif
return 0;
}
int acpi_video_register(void)
{
int result = 0;
@@ -2268,6 +2290,22 @@ static int __init acpi_video_init(void)
return 0;
}
EXPORT_SYMBOL(acpi_video_register);
/*
* This is kind of nasty. Hardware using Intel chipsets may require
* the video opregion code to be run first in order to initialise
* state before any ACPI video calls are made. To handle this we defer
* registration of the video class until the opregion code has run.
*/
static int __init acpi_video_init(void)
{
if (intel_opregion_present())
return 0;
return acpi_video_register();
}
static void __exit acpi_video_exit(void)
{