[PATCH 1/1] UBUNTU: SAUCE: ACPI: Populate DIDL before registering ACPI video device on Intel
Andy Whitcroft
apw at canonical.com
Tue Jul 21 15:54:38 UTC 2009
From: Matthew Garrett <mjg59 at srcf.ucam.org>
BugLink: http://bugs.launchpad.net/bugs/228399
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 at redhat.com>
Acked-by: Eric Anholt <eric at anholt.net>
Signed-off-by: Len Brown <len.brown at intel.com>
commit 74a365b3f354fafc537efa5867deb7a9fadbfe27 backported
Note we lose the KMS support which makes most of this redundant
including the DIDL update.
Signed-off-by: Andy Whitcroft <apw at canonical.com>
---
drivers/acpi/video.c | 40 ++++++++++++++++++++++++++++++++++++++-
drivers/gpu/drm/i915/i915_dma.c | 5 ++-
include/acpi/video.h | 11 ++++++++++
3 files changed, 53 insertions(+), 3 deletions(-)
create mode 100644 include/acpi/video.h
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 8bcca4b..2283ccb 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -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>
@@ -2124,7 +2126,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;
@@ -2141,6 +2163,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)
{
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c
index c6d5528..7672db6 100644
--- a/drivers/gpu/drm/i915/i915_dma.c
+++ b/drivers/gpu/drm/i915/i915_dma.c
@@ -865,8 +865,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
if (!IS_I945G(dev) && !IS_I945GM(dev))
pci_enable_msi(dev->pdev);
- intel_opregion_init(dev);
-
spin_lock_init(&dev_priv->user_irq_lock);
ret = drm_vblank_init(dev, I915_NUM_PIPE);
@@ -876,6 +874,9 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
return ret;
}
+ /* Must be done after probing outputs */
+ intel_opregion_init(dev);
+
return ret;
}
diff --git a/include/acpi/video.h b/include/acpi/video.h
new file mode 100644
index 0000000..f0275bb
--- /dev/null
+++ b/include/acpi/video.h
@@ -0,0 +1,11 @@
+#ifndef __ACPI_VIDEO_H
+#define __ACPI_VIDEO_H
+
+#if (defined CONFIG_ACPI_VIDEO || defined CONFIG_ACPI_VIDEO_MODULE)
+extern int acpi_video_register(void);
+#else
+static inline int acpi_video_register(void) { return 0; }
+#endif
+
+#endif
+
--
1.6.3.rc3.199.g24398
More information about the kernel-team
mailing list