提交 122f2672 编写于 作者: H Henrique de Moraes Holschuh 提交者: Matthew Garrett

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: NHenrique de Moraes Holschuh <hmh@hmh.eng.br>
Signed-off-by: NMatthew Garrett <mjg@redhat.com>
上级 52d7ee55
...@@ -6080,13 +6080,18 @@ static struct backlight_ops ibm_backlight_data = { ...@@ -6080,13 +6080,18 @@ static struct backlight_ops ibm_backlight_data = {
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/*
* Call _BCL method of video device. On some ThinkPads this will
* switch the firmware to the ACPI brightness control mode.
*/
static int __init tpacpi_query_bcl_levels(acpi_handle handle) static int __init tpacpi_query_bcl_levels(acpi_handle handle)
{ {
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
union acpi_object *obj; union acpi_object *obj;
int rc; int rc;
if (ACPI_SUCCESS(acpi_evaluate_object(handle, NULL, NULL, &buffer))) { if (ACPI_SUCCESS(acpi_evaluate_object(handle, "_BCL", NULL, &buffer))) {
obj = (union acpi_object *)buffer.pointer; obj = (union acpi_object *)buffer.pointer;
if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
printk(TPACPI_ERR "Unknown _BCL data, " printk(TPACPI_ERR "Unknown _BCL data, "
...@@ -6103,55 +6108,22 @@ static int __init tpacpi_query_bcl_levels(acpi_handle handle) ...@@ -6103,55 +6108,22 @@ static int __init tpacpi_query_bcl_levels(acpi_handle handle)
return rc; return rc;
} }
static acpi_status __init tpacpi_acpi_walk_find_bcl(acpi_handle handle,
u32 lvl, void *context, void **rv)
{
char name[ACPI_PATH_SEGMENT_LENGTH];
struct acpi_buffer buffer = { sizeof(name), &name };
if (ACPI_SUCCESS(acpi_get_name(handle, ACPI_SINGLE_NAME, &buffer)) &&
!strncmp("_BCL", name, sizeof(name) - 1)) {
BUG_ON(!rv || !*rv);
**(int **)rv = tpacpi_query_bcl_levels(handle);
return AE_CTRL_TERMINATE;
} else {
return AE_OK;
}
}
/* /*
* Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map * Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map
*/ */
static unsigned int __init tpacpi_check_std_acpi_brightness_support(void) static unsigned int __init tpacpi_check_std_acpi_brightness_support(void)
{ {
int status; acpi_handle video_device;
int bcl_levels = 0; int bcl_levels = 0;
void *bcl_ptr = &bcl_levels;
if (!vid_handle) tpacpi_acpi_handle_locate("video", ACPI_VIDEO_HID, &video_device);
TPACPI_ACPIHANDLE_INIT(vid); if (video_device)
bcl_levels = tpacpi_query_bcl_levels(video_device);
if (!vid_handle) tp_features.bright_acpimode = (bcl_levels > 0);
return 0;
/*
* Search for a _BCL method, and execute it. This is safe on all
* ThinkPads, and as a side-effect, _BCL will place a Lenovo Vista
* BIOS in ACPI backlight control mode. We do NOT have to care
* about calling the _BCL method in an enabled video device, any
* will do for our purposes.
*/
status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3, return (bcl_levels > 2) ? (bcl_levels - 2) : 0;
tpacpi_acpi_walk_find_bcl, NULL, NULL,
&bcl_ptr);
if (ACPI_SUCCESS(status) && bcl_levels > 2) {
tp_features.bright_acpimode = 1;
return bcl_levels - 2;
}
return 0;
} }
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册