aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHenrique de Moraes Holschuh <hmh@hmh.eng.br>2010-08-09 22:48:18 -0400
committerMatthew Garrett <mjg@redhat.com>2010-08-16 11:54:47 -0400
commit122f26726b5e16174bf8a707df14be1d93c49d62 (patch)
tree7e71e1fa0c2dda912796f1cb9fd1f1f71bb872e4 /drivers
parent52d7ee558d3babb4918eed6769f593adc1b6616e (diff)
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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/platform/x86/thinkpad_acpi.c52
1 files changed, 12 insertions, 40 deletions
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c
index 5d6119bed00c..9d6fc4c7c08e 100644
--- a/drivers/platform/x86/thinkpad_acpi.c
+++ b/drivers/platform/x86/thinkpad_acpi.c
@@ -6080,13 +6080,18 @@ static struct backlight_ops ibm_backlight_data = {
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
6083static int __init tpacpi_query_bcl_levels(acpi_handle handle) 6088static int __init tpacpi_query_bcl_levels(acpi_handle handle)
6084{ 6089{
6085 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 6090 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
6086 union acpi_object *obj; 6091 union acpi_object *obj;
6087 int rc; 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 obj = (union acpi_object *)buffer.pointer; 6095 obj = (union acpi_object *)buffer.pointer;
6091 if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) { 6096 if (!obj || (obj->type != ACPI_TYPE_PACKAGE)) {
6092 printk(TPACPI_ERR "Unknown _BCL data, " 6097 printk(TPACPI_ERR "Unknown _BCL data, "
@@ -6103,55 +6108,22 @@ static int __init tpacpi_query_bcl_levels(acpi_handle handle)
6103 return rc; 6108 return rc;
6104} 6109}
6105 6110
6106static 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
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 6111
6122/* 6112/*
6123 * Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map 6113 * Returns 0 (no ACPI _BCL or _BCL invalid), or size of brightness map
6124 */ 6114 */
6125static unsigned int __init tpacpi_check_std_acpi_brightness_support(void) 6115static unsigned int __init tpacpi_check_std_acpi_brightness_support(void)
6126{ 6116{
6127 int status; 6117 acpi_handle video_device;
6128 int bcl_levels = 0; 6118 int bcl_levels = 0;
6129 void *bcl_ptr = &bcl_levels;
6130 6119
6131 if (!vid_handle) 6120 tpacpi_acpi_handle_locate("video", ACPI_VIDEO_HID, &video_device);
6132 TPACPI_ACPIHANDLE_INIT(vid); 6121 if (video_device)
6122 bcl_levels = tpacpi_query_bcl_levels(video_device);
6133 6123
6134 if (!vid_handle) 6124 tp_features.bright_acpimode = (bcl_levels > 0);
6135 return 0;
6136
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 6125
6145 status = acpi_walk_namespace(ACPI_TYPE_METHOD, vid_handle, 3, 6126 return (bcl_levels > 2) ? (bcl_levels - 2) : 0;
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;
6155} 6127}
6156 6128
6157/* 6129/*