diff options
| -rw-r--r-- | drivers/gpu/drm/i915/i915_opregion.c | 54 |
1 files changed, 50 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/i915_opregion.c b/drivers/gpu/drm/i915/i915_opregion.c index 7cc8410239cb..8fcc75c1aa28 100644 --- a/drivers/gpu/drm/i915/i915_opregion.c +++ b/drivers/gpu/drm/i915/i915_opregion.c | |||
| @@ -382,8 +382,57 @@ static void intel_didl_outputs(struct drm_device *dev) | |||
| 382 | struct drm_i915_private *dev_priv = dev->dev_private; | 382 | struct drm_i915_private *dev_priv = dev->dev_private; |
| 383 | struct intel_opregion *opregion = &dev_priv->opregion; | 383 | struct intel_opregion *opregion = &dev_priv->opregion; |
| 384 | struct drm_connector *connector; | 384 | struct drm_connector *connector; |
| 385 | acpi_handle handle; | ||
| 386 | struct acpi_device *acpi_dev, *acpi_cdev, *acpi_video_bus = NULL; | ||
| 387 | unsigned long long device_id; | ||
| 388 | acpi_status status; | ||
| 385 | int i = 0; | 389 | int i = 0; |
| 386 | 390 | ||
| 391 | handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev); | ||
| 392 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) | ||
| 393 | return; | ||
| 394 | |||
| 395 | if (acpi_is_video_device(acpi_dev)) | ||
| 396 | acpi_video_bus = acpi_dev; | ||
| 397 | else { | ||
| 398 | list_for_each_entry(acpi_cdev, &acpi_dev->children, node) { | ||
| 399 | if (acpi_is_video_device(acpi_cdev)) { | ||
| 400 | acpi_video_bus = acpi_cdev; | ||
| 401 | break; | ||
| 402 | } | ||
| 403 | } | ||
| 404 | } | ||
| 405 | |||
| 406 | if (!acpi_video_bus) { | ||
| 407 | printk(KERN_WARNING "No ACPI video bus found\n"); | ||
| 408 | return; | ||
| 409 | } | ||
| 410 | |||
| 411 | list_for_each_entry(acpi_cdev, &acpi_video_bus->children, node) { | ||
| 412 | if (i >= 8) { | ||
| 413 | dev_printk (KERN_ERR, &dev->pdev->dev, | ||
| 414 | "More than 8 outputs detected\n"); | ||
| 415 | return; | ||
| 416 | } | ||
| 417 | status = | ||
| 418 | acpi_evaluate_integer(acpi_cdev->handle, "_ADR", | ||
| 419 | NULL, &device_id); | ||
| 420 | if (ACPI_SUCCESS(status)) { | ||
| 421 | if (!device_id) | ||
| 422 | goto blind_set; | ||
| 423 | opregion->acpi->didl[i] = (u32)(device_id & 0x0f0f); | ||
| 424 | i++; | ||
| 425 | } | ||
| 426 | } | ||
| 427 | |||
| 428 | end: | ||
| 429 | /* If fewer than 8 outputs, the list must be null terminated */ | ||
| 430 | if (i < 8) | ||
| 431 | opregion->acpi->didl[i] = 0; | ||
| 432 | return; | ||
| 433 | |||
| 434 | blind_set: | ||
| 435 | i = 0; | ||
| 387 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | 436 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
| 388 | int output_type = ACPI_OTHER_OUTPUT; | 437 | int output_type = ACPI_OTHER_OUTPUT; |
| 389 | if (i >= 8) { | 438 | if (i >= 8) { |
| @@ -416,10 +465,7 @@ static void intel_didl_outputs(struct drm_device *dev) | |||
| 416 | opregion->acpi->didl[i] |= (1<<31) | output_type | i; | 465 | opregion->acpi->didl[i] |= (1<<31) | output_type | i; |
| 417 | i++; | 466 | i++; |
| 418 | } | 467 | } |
| 419 | 468 | goto end; | |
| 420 | /* If fewer than 8 outputs, the list must be null terminated */ | ||
| 421 | if (i < 8) | ||
| 422 | opregion->acpi->didl[i] = 0; | ||
| 423 | } | 469 | } |
| 424 | 470 | ||
| 425 | int intel_opregion_init(struct drm_device *dev, int resume) | 471 | int intel_opregion_init(struct drm_device *dev, int resume) |
