Jesse Keating 2f82dd
diff -up linux-2.6.33.noarch/drivers/gpu/drm/i915/i915_opregion.c.orig linux-2.6.33.noarch/drivers/gpu/drm/i915/i915_opregion.c
Jesse Keating 2f82dd
--- linux-2.6.33.noarch/drivers/gpu/drm/i915/i915_opregion.c.orig	2010-02-24 13:52:17.000000000 -0500
Jesse Keating 2f82dd
+++ linux-2.6.33.noarch/drivers/gpu/drm/i915/i915_opregion.c	2010-04-01 10:35:35.249121262 -0400
Jesse Keating 2f82dd
@@ -382,8 +382,54 @@ static void intel_didl_outputs(struct dr
Jesse Keating 2f82dd
 	struct drm_i915_private *dev_priv = dev->dev_private;
Jesse Keating 2f82dd
 	struct intel_opregion *opregion = &dev_priv->opregion;
Jesse Keating 2f82dd
 	struct drm_connector *connector;
Jesse Keating 2f82dd
+	acpi_handle handle;
Jesse Keating 2f82dd
+	struct acpi_device *acpi_dev, *acpi_cdev, *acpi_video_bus = NULL;
Jesse Keating 2f82dd
+	unsigned long long device_id;
Jesse Keating 2f82dd
+	acpi_status status;
Jesse Keating 2f82dd
 	int i = 0;
Jesse Keating 2f82dd
 
Jesse Keating 2f82dd
+	handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev);
Jesse Keating 2f82dd
+	if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev)))
Jesse Keating 2f82dd
+		return;
Jesse Keating 2f82dd
+
Jesse Keating 2f82dd
+	if (acpi_is_video_device(acpi_dev))
Jesse Keating 2f82dd
+		acpi_video_bus = acpi_dev;
Jesse Keating 2f82dd
+	else {
Jesse Keating 2f82dd
+		list_for_each_entry(acpi_cdev, &acpi_dev->children, node) {
Jesse Keating 2f82dd
+			if (acpi_is_video_device(acpi_cdev)) {
Jesse Keating 2f82dd
+				acpi_video_bus = acpi_cdev;
Jesse Keating 2f82dd
+				break;
Jesse Keating 2f82dd
+			}
Jesse Keating 2f82dd
+		}
Jesse Keating 2f82dd
+	}
Jesse Keating 2f82dd
+
Jesse Keating 2f82dd
+	if (!acpi_video_bus)
Jesse Keating 2f82dd
+		goto blind_set;
Jesse Keating 2f82dd
+
Jesse Keating 2f82dd
+	list_for_each_entry(acpi_cdev, &acpi_video_bus->children, node) {
Jesse Keating 2f82dd
+		if (i >= 8) {
Jesse Keating 2f82dd
+			dev_printk (KERN_ERR, &dev->pdev->dev,
Jesse Keating 2f82dd
+				    "More than 8 outputs detected\n");
Jesse Keating 2f82dd
+			return;
Jesse Keating 2f82dd
+		}
Jesse Keating 2f82dd
+		status = acpi_evaluate_integer(acpi_cdev->handle, "_ADR",
Jesse Keating 2f82dd
+					       NULL, &device_id);
Jesse Keating 2f82dd
+		if (ACPI_SUCCESS(status)) {
Jesse Keating 2f82dd
+			if (!device_id)
Jesse Keating 2f82dd
+				goto blind_set;
Jesse Keating 2f82dd
+			opregion->acpi->didl[i] = (u32)(device_id & 0x0f0f);
Jesse Keating 2f82dd
+			i++;
Jesse Keating 2f82dd
+		}
Jesse Keating 2f82dd
+	}
Jesse Keating 2f82dd
+
Jesse Keating 2f82dd
+end:
Jesse Keating 2f82dd
+	/* If fewer than 8 outputs, the list must be null terminated */
Jesse Keating 2f82dd
+	if (i < 8)
Jesse Keating 2f82dd
+		opregion->acpi->didl[i] = 0;
Jesse Keating 2f82dd
+	return;
Jesse Keating 2f82dd
+
Jesse Keating 2f82dd
+blind_set:
Jesse Keating 2f82dd
+	i = 0;
Jesse Keating 2f82dd
 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
Jesse Keating 2f82dd
 		int output_type = ACPI_OTHER_OUTPUT;
Jesse Keating 2f82dd
 		if (i >= 8) {
Jesse Keating 2f82dd
@@ -416,10 +462,7 @@ static void intel_didl_outputs(struct dr
Jesse Keating 2f82dd
 		opregion->acpi->didl[i] |= (1<<31) | output_type | i;
Jesse Keating 2f82dd
 		i++;
Jesse Keating 2f82dd
 	}
Jesse Keating 2f82dd
-
Jesse Keating 2f82dd
-	/* If fewer than 8 outputs, the list must be null terminated */
Jesse Keating 2f82dd
-	if (i < 8)
Jesse Keating 2f82dd
-		opregion->acpi->didl[i] = 0;
Jesse Keating 2f82dd
+	goto end;
Jesse Keating 2f82dd
 }
Jesse Keating 2f82dd
 
Jesse Keating 2f82dd
 int intel_opregion_init(struct drm_device *dev, int resume)