Skip to content

Commit 46445b6

Browse files
Aaron Lurafaeljw
authored andcommitted
thinkpad-acpi: fix handle locate for video and query of _BCL
The tpacpi_acpi_handle_locate function makes use of acpi_get_devices to locate handle for ACPI video by HID, the problem is, ACPI video node doesn't really have HID defined(i.e. no _HID control method is defined for video device), so.. that function would fail. This can be solved by enhancing the callback function for acpi_get_devices, where we can use acpi_device_hid function to check if the ACPI node corresponds to a video controller. In addition to that, the _BCL control method only exists under a video output device node, not a video controller device node. So to evaluate _BCL, we need the handle of a video output device node, which is child of the located video controller node from tpacpi_acpi_handle_locate. The two fix are necessary for some Thinkpad models to emit notification on backlight hotkey press as a result of evaluation of _BCL. Signed-off-by: Aaron Lu <[email protected]> Tested-by: Igor Gnatenko <[email protected]> Acked-by: Henrique de Moraes Holschuh <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent fbc9fe1 commit 46445b6

File tree

1 file changed

+24
-7
lines changed

1 file changed

+24
-7
lines changed

drivers/platform/x86/thinkpad_acpi.c

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,14 @@ static void __init drv_acpi_handle_init(const char *name,
700700
static acpi_status __init tpacpi_acpi_handle_locate_callback(acpi_handle handle,
701701
u32 level, void *context, void **return_value)
702702
{
703+
struct acpi_device *dev;
704+
if (!strcmp(context, "video")) {
705+
if (acpi_bus_get_device(handle, &dev))
706+
return AE_OK;
707+
if (strcmp(ACPI_VIDEO_HID, acpi_device_hid(dev)))
708+
return AE_OK;
709+
}
710+
703711
*(acpi_handle *)return_value = handle;
704712

705713
return AE_CTRL_TERMINATE;
@@ -712,10 +720,10 @@ static void __init tpacpi_acpi_handle_locate(const char *name,
712720
acpi_status status;
713721
acpi_handle device_found;
714722

715-
BUG_ON(!name || !hid || !handle);
723+
BUG_ON(!name || !handle);
716724
vdbg_printk(TPACPI_DBG_INIT,
717725
"trying to locate ACPI handle for %s, using HID %s\n",
718-
name, hid);
726+
name, hid ? hid : "NULL");
719727

720728
memset(&device_found, 0, sizeof(device_found));
721729
status = acpi_get_devices(hid, tpacpi_acpi_handle_locate_callback,
@@ -6090,19 +6098,28 @@ static int __init tpacpi_query_bcl_levels(acpi_handle handle)
60906098
{
60916099
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
60926100
union acpi_object *obj;
6101+
struct acpi_device *device, *child;
60936102
int rc;
60946103

6095-
if (ACPI_SUCCESS(acpi_evaluate_object(handle, "_BCL", NULL, &buffer))) {
6104+
if (acpi_bus_get_device(handle, &device))
6105+
return 0;
6106+
6107+
rc = 0;
6108+
list_for_each_entry(child, &device->children, node) {
6109+
acpi_status status = acpi_evaluate_object(child->handle, "_BCL",
6110+
NULL, &buffer);
6111+
if (ACPI_FAILURE(status))
6112+
continue;
6113+
60966114
obj = (union acpi_object *)buffer.pointer;
60976115
if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
60986116
pr_err("Unknown _BCL data, please report this to %s\n",
6099-
TPACPI_MAIL);
6117+
TPACPI_MAIL);
61006118
rc = 0;
61016119
} else {
61026120
rc = obj->package.count;
61036121
}
6104-
} else {
6105-
return 0;
6122+
break;
61066123
}
61076124

61086125
kfree(buffer.pointer);
@@ -6118,7 +6135,7 @@ static unsigned int __init tpacpi_check_std_acpi_brightness_support(void)
61186135
acpi_handle video_device;
61196136
int bcl_levels = 0;
61206137

6121-
tpacpi_acpi_handle_locate("video", ACPI_VIDEO_HID, &video_device);
6138+
tpacpi_acpi_handle_locate("video", NULL, &video_device);
61226139
if (video_device)
61236140
bcl_levels = tpacpi_query_bcl_levels(video_device);
61246141

0 commit comments

Comments
 (0)