Commit 122f26726b5e16174bf8a707df14be1d93c49d62

Authored by Henrique de Moraes Holschuh
Committed by Matthew Garrett
1 parent 52d7ee558d

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 /*