Skip to content

Commit 5d389af

Browse files
superm1rafaeljw
authored andcommitted
ACPI: video: Handle fetching EDID that is longer than 256 bytes
The ACPI specification allows for an EDID to be up to 512 bytes but the _DDC EDID fetching code will only try up to 256 bytes. Modify the code to instead start at 512 bytes and work it's way down instead. As _DDC is now called up to 4 times on a machine debugging messages are noisier than necessary. Decrease from info to debug. Link: https://uefi.org/htmlspecs/ACPI_Spec_6_4_html/Apx_B_Video_Extensions/output-device-specific-methods.html#ddc-return-the-edid-for-this-device Signed-off-by: Mario Limonciello <mario.limonciello@amd.com> [ rjw: Type mismatch fix, minor whitespace adjustment ] Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
1 parent 54be6c6 commit 5d389af

File tree

1 file changed

+11
-17
lines changed

1 file changed

+11
-17
lines changed

drivers/acpi/acpi_video.c

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,7 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
612612

613613
static int
614614
acpi_video_device_EDID(struct acpi_video_device *device,
615-
union acpi_object **edid, ssize_t length)
615+
union acpi_object **edid, int length)
616616
{
617617
int status;
618618
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
@@ -625,13 +625,11 @@ acpi_video_device_EDID(struct acpi_video_device *device,
625625

626626
if (!device)
627627
return -ENODEV;
628-
if (length == 128)
629-
arg0.integer.value = 1;
630-
else if (length == 256)
631-
arg0.integer.value = 2;
632-
else
628+
if (!length || (length % 128))
633629
return -EINVAL;
634630

631+
arg0.integer.value = length / 128;
632+
635633
status = acpi_evaluate_object(device->dev->handle, "_DDC", &args, &buffer);
636634
if (ACPI_FAILURE(status))
637635
return -ENODEV;
@@ -641,7 +639,8 @@ acpi_video_device_EDID(struct acpi_video_device *device,
641639
if (obj && obj->type == ACPI_TYPE_BUFFER)
642640
*edid = obj;
643641
else {
644-
acpi_handle_info(device->dev->handle, "Invalid _DDC data\n");
642+
acpi_handle_debug(device->dev->handle,
643+
"Invalid _DDC data for length %d\n", length);
645644
status = -EFAULT;
646645
kfree(obj);
647646
}
@@ -1447,7 +1446,6 @@ int acpi_video_get_edid(struct acpi_device *device, int type, int device_id,
14471446

14481447
for (i = 0; i < video->attached_count; i++) {
14491448
video_device = video->attached_array[i].bind_info;
1450-
length = 256;
14511449

14521450
if (!video_device)
14531451
continue;
@@ -1478,18 +1476,14 @@ int acpi_video_get_edid(struct acpi_device *device, int type, int device_id,
14781476
continue;
14791477
}
14801478

1481-
status = acpi_video_device_EDID(video_device, &buffer, length);
1482-
1483-
if (ACPI_FAILURE(status) || !buffer ||
1484-
buffer->type != ACPI_TYPE_BUFFER) {
1485-
length = 128;
1479+
for (length = 512; length > 0; length -= 128) {
14861480
status = acpi_video_device_EDID(video_device, &buffer,
14871481
length);
1488-
if (ACPI_FAILURE(status) || !buffer ||
1489-
buffer->type != ACPI_TYPE_BUFFER) {
1490-
continue;
1491-
}
1482+
if (ACPI_SUCCESS(status))
1483+
break;
14921484
}
1485+
if (!length)
1486+
continue;
14931487

14941488
*edid = buffer->buffer.pointer;
14951489
return length;

0 commit comments

Comments
 (0)