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>
This commit is contained in:
parent
52d7ee558d
commit
122f26726b
1 changed files with 12 additions and 40 deletions
|
@ -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)
|
||||||
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;
|
|
||||||
|
|
||||||
/*
|
return (bcl_levels > 2) ? (bcl_levels - 2) : 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,
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue