diff options
| -rw-r--r-- | drivers/platform/x86/thinkpad_acpi.c | 52 |
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 | |||
| 6083 | static int __init tpacpi_query_bcl_levels(acpi_handle handle) | 6088 | static 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 | ||
| 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 | |||
| 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 | */ |
| 6125 | static unsigned int __init tpacpi_check_std_acpi_brightness_support(void) | 6115 | static 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 | /* |
