Commit 122f26726b5e16174bf8a707df14be1d93c49d62
Committed by
Matthew Garrett
1 parent
52d7ee558d
Exists in
master
and in
7 other branches
thinkpad-acpi: find ACPI video device by synthetic HID
The Linux ACPI core locates the ACPI video devices for us and marks them with ACPI_VIDEO_HID. Use that information to locate the video device instead of a half-baked hunt for _BCL. This uncouples the detection of the number of backlight brightness levels on ThinkPads from the ACPI paths in vid_handle. With this change, the driver should be able to always detect whether the ThinkPad uses a 8-level or 16-level brightness scale even on newer models for which the vid_handle paths have not been updated yet. It will skip deactivated devices in the ACPI device tree, which is a change in behaviour. Signed-off-by: Henrique de Moraes Holschuh <hmh@hmh.eng.br> Signed-off-by: Matthew Garrett <mjg@redhat.com>
Showing 1 changed file with 12 additions and 40 deletions Side-by-side Diff
drivers/platform/x86/thinkpad_acpi.c
... | ... | @@ -6080,13 +6080,18 @@ |
6080 | 6080 | |
6081 | 6081 | /* --------------------------------------------------------------------- */ |
6082 | 6082 | |
6083 | +/* | |
6084 | + * Call _BCL method of video device. On some ThinkPads this will | |
6085 | + * switch the firmware to the ACPI brightness control mode. | |
6086 | + */ | |
6087 | + | |
6083 | 6088 | static int __init tpacpi_query_bcl_levels(acpi_handle handle) |
6084 | 6089 | { |
6085 | 6090 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
6086 | 6091 | union acpi_object *obj; |
6087 | 6092 | int rc; |
6088 | 6093 | |
6089 | - if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) { | |
6094 | + if (ACPI_SUCCESS(acpi_evaluate_object(handle, "_BCL", NULL, &buffer))) { | |
6090 | 6095 | obj = (union acpi_object *)buffer.pointer; |
6091 | 6096 | if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { |
6092 | 6097 | printk(TPACPI_ERR "Unknown _BCL data, " |
6093 | 6098 | |
6094 | 6099 | |
6095 | 6100 | |
6096 | 6101 | |
6097 | 6102 | |
6098 | 6103 | |
... | ... | @@ -6103,55 +6108,22 @@ |
6103 | 6108 | return rc; |
6104 | 6109 | } |
6105 | 6110 | |
6106 | -static acpi_status __init tpacpi_acpi_walk_find_bcl(acpi_handle handle, | |
6107 | - u32 lvl, void *context, void **rv) | |
6108 | -{ | |
6109 | - char name[ACPI_PATH_SEGMENT_LENGTH]; | |
6110 | - struct acpi_buffer buffer = { sizeof(name), &name }; | |
6111 | 6111 | |
6112 | - if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) && | |
6113 | - !strncmp("_BCL", name, sizeof(name) - 1)) { | |
6114 | - BUG_ON(!rv || !*rv); | |
6115 | - **(int **)rv = tpacpi_query_bcl_levels(handle); | |
6116 | - return AE_CTRL_TERMINATE; | |
6117 | - } else { | |
6118 | - return AE_OK; | |
6119 | - } | |
6120 | -} | |
6121 | - | |
6122 | 6112 | /* |
6123 | 6113 | * Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map |
6124 | 6114 | */ |
6125 | 6115 | static unsigned int __init tpacpi_check_std_acpi_brightness_support(void) |
6126 | 6116 | { |
6127 | - int status; | |
6117 | + acpi_handle video_device; | |
6128 | 6118 | int bcl_levels = 0; |
6129 | - void *bcl_ptr = &bcl_levels; | |
6130 | 6119 | |
6131 | - if (!vid_handle) | |
6132 | - TPACPI_ACPIHANDLE_INIT(vid); | |
6120 | + tpacpi_acpi_handle_locate("video", ACPI_VIDEO_HID, &video_device); | |
6121 | + if (video_device) | |
6122 | + bcl_levels = tpacpi_query_bcl_levels(video_device); | |
6133 | 6123 | |
6134 | - if (!vid_handle) | |
6135 | - return 0; | |
6124 | + tp_features.bright_acpimode = (bcl_levels > 0); | |
6136 | 6125 | |
6137 | - /* | |
6138 | - * Search for a _BCL method, and execute it. This is safe on all | |
6139 | - * ThinkPads, and as a side-effect, _BCL will place a Lenovo Vista | |
6140 | - * BIOS in ACPI backlight control mode. We do NOT have to care | |
6141 | - * about calling the _BCL method in an enabled video device, any | |
6142 | - * will do for our purposes. | |
6143 | - */ | |
6144 | - | |
6145 | - status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3, | |
6146 | - tpacpi_acpi_walk_find_bcl, NULL, NULL, | |
6147 | - &bcl_ptr); | |
6148 | - | |
6149 | - if (ACPI_SUCCESS(status) && bcl_levels > 2) { | |
6150 | - tp_features.bright_acpimode = 1; | |
6151 | - return bcl_levels - 2; | |
6152 | - } | |
6153 | - | |
6154 | - return 0; | |
6126 | + return (bcl_levels > 2) ? (bcl_levels - 2) : 0; | |
6155 | 6127 | } |
6156 | 6128 | |
6157 | 6129 | /* |