Backlight Finally Works - Generic Poulsbo GMA 500 Fix via ACPI Video Interface

The trick is to go into drivers/acpi/video.c and remove the part that disables the acpi handling if there is an intel opregion present. The patch looks like this:
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 60ea984..ad8fc2d 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -2394,9 +2394,6 @@ static int __init acpi_video_init(void)
{
dmi_check_system(video_dmi_table);

- if (intel_opregion_present())
- return 0;
-
return acpi_video_register();
}

You can compile the module by getting the sources of your running kernel, cding into the acpi directory (drivers/acpi), applying the acpi patch and then executing
make -C /lib/modules/$(uname -r)/build M=$PWD video.ko

Then just sudo insmod ./video.ko.

Alright, here's the more elaborate version by Joey Lee hopefully entering the kernel soon:
---
drivers/acpi/video.c | 17 ++++++++++++++++-
include/linux/pci_ids.h | 1 +
2 files changed, 17 insertions(+), 1 deletions(-)

diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 9865d46..25a70e0 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -88,6 +88,11 @@ static int acpi_video_bus_add(struct acpi_device *device);
static int acpi_video_bus_remove(struct acpi_device *device, int type);
static void acpi_video_bus_notify(struct acpi_device *device, u32 event);

+static const struct pci_device_id intel_drm_blacklist[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_VGA) },
+ { } /* Terminating entry */
+};
+
static const struct acpi_device_id video_device_ids[] = {
{ACPI_VIDEO_HID, 0},
{"", 0},
@@ -2531,8 +2536,11 @@ static int __init intel_opregion_present(void)
#if defined(CONFIG_DRM_I915) || defined(CONFIG_DRM_I915_MODULE)
struct pci_dev *dev = NULL;
u32 address;
+ int i;
+ bool in_blacklist;

for_each_pci_dev(dev) {
+ in_blacklist = 0;
if ((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA)
continue;
if (dev->vendor != PCI_VENDOR_ID_INTEL)
@@ -2540,7 +2548,14 @@ static int __init intel_opregion_present(void)
pci_read_config_dword(dev, 0xfc, &address);
if (!address)
continue;
- return 1;
+ for (i = 0; intel_drm_blacklist[i].device != 0; i++) {
+ if (dev->device == intel_drm_blacklist[i].device) {
+ in_blacklist = 1;
+ break;
+ }
+ }
+ if (!in_blacklist)
+ return 1;
}
#endif
return 0;
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 3bedcc1..78858b1 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2669,6 +2669,7 @@
#define PCI_DEVICE_ID_INTEL_82443GX_0 0x71a0
#define PCI_DEVICE_ID_INTEL_82443GX_2 0x71a2
#define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601
+#define PCI_DEVICE_ID_INTEL_SCH_VGA 0x8108
#define PCI_DEVICE_ID_INTEL_SCH_LPC 0x8119
#define PCI_DEVICE_ID_INTEL_SCH_IDE 0x811a
#define PCI_DEVICE_ID_INTEL_82454GX 0x84c4
--
1.6.0.2

3 comments:

  1. I am applying this patch now, but do see an inconsistency. If you look at the definition of intel_opregion_present() it only returns true if CONFIG_DRM_I915 OR CONFIG_DRM_I915_MODULE has been set. Thus if this is poulsbo, wouldn't that function return false?

    ReplyDelete
  2. I'm not sure to be honest. But I am sure that it works for me. Didn't come from me, but from Joey Lee of Novell. A more sophisticated patch should be integrated into a future kernel version if everything works out.

    ReplyDelete
  3. Thinking about it: Distribution kernels will always compile pretty much everything as module, hence it would pretty much always be active...

    ReplyDelete

I appreciate comments. And I do read them.