aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-04-27 19:54:08 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2013-04-27 19:54:08 -0400
commitc940c8ce1db3ed3909d31c02aef01a864565519c (patch)
tree725597abd9bd910792410ddfe89cc0857d7667b2 /drivers/acpi
parent34bdb1a458baaf3e56843c36deb04283c26a8099 (diff)
parent94a409319561ec1847fd9bf996a2d5843ad00932 (diff)
Merge branch 'acpi-assorted'
* acpi-assorted: (21 commits) ACPI / thermal: do not always return THERMAL_TREND_RAISING for active trip points ACPI: video: correct acpi_video_bus_add error processing ACPI: Fix wrong parameter passed to memblock_reserve acpi: video: enhance the quirk detect logic of _BQC ACPI: update comments for acpi_event_status ACPI: remove "config ACPI_DEBUG_FUNC_TRACE" PCI / ACPI: Don't query OSC support with all possible controls ACPI / processor_thermal: avoid null pointer deference error ACPI / fan: avoid null pointer deference error ACPI / video: Fix applying indexed initial brightness value. ACPI / video: Make logic a little easier to understand. ACPI / video: Fix brightness control initialization for some laptops. ACPI: Use resource_size() in osl.c ACPI / acpi_pad: Used PTR_RET ACPI: suppress compiler warning in container.c ACPI: suppress compiler warning in battery.c ACPI: suppress compiler warnings in processor_throttling.c ACPI: suppress compiler warnings in button.c ACPI: replace kmalloc+memcpy with kmemdup ACPI: Remove acpi_pci_bind_root() definition ...
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/Kconfig8
-rw-r--r--drivers/acpi/acpi_pad.c2
-rw-r--r--drivers/acpi/battery.c2
-rw-r--r--drivers/acpi/bus.c5
-rw-r--r--drivers/acpi/button.c1
-rw-r--r--drivers/acpi/container.c2
-rw-r--r--drivers/acpi/fan.c8
-rw-r--r--drivers/acpi/osl.c4
-rw-r--r--drivers/acpi/pci_root.c4
-rw-r--r--drivers/acpi/processor_thermal.c24
-rw-r--r--drivers/acpi/processor_throttling.c3
-rw-r--r--drivers/acpi/thermal.c16
-rw-r--r--drivers/acpi/video.c318
13 files changed, 243 insertions, 154 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 8fcae6df0a42..100bd724f648 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -298,14 +298,6 @@ config ACPI_DEBUG
298 Documentation/kernel-parameters.txt to control the type and 298 Documentation/kernel-parameters.txt to control the type and
299 amount of debug output. 299 amount of debug output.
300 300
301config ACPI_DEBUG_FUNC_TRACE
302 bool "Additionally enable ACPI function tracing"
303 default n
304 depends on ACPI_DEBUG
305 help
306 ACPI Debug Statements slow down ACPI processing. Function trace
307 is about half of the penalty and is rarely useful.
308
309config ACPI_PCI_SLOT 301config ACPI_PCI_SLOT
310 bool "PCI slot detection driver" 302 bool "PCI slot detection driver"
311 depends on SYSFS 303 depends on SYSFS
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c
index 31de1043eea0..27bb6a91de5f 100644
--- a/drivers/acpi/acpi_pad.c
+++ b/drivers/acpi/acpi_pad.c
@@ -236,7 +236,7 @@ static int create_power_saving_task(void)
236 ps_tsks[ps_tsk_num] = kthread_run(power_saving_thread, 236 ps_tsks[ps_tsk_num] = kthread_run(power_saving_thread,
237 (void *)(unsigned long)ps_tsk_num, 237 (void *)(unsigned long)ps_tsk_num,
238 "acpi_pad/%d", ps_tsk_num); 238 "acpi_pad/%d", ps_tsk_num);
239 rc = IS_ERR(ps_tsks[ps_tsk_num]) ? PTR_ERR(ps_tsks[ps_tsk_num]) : 0; 239 rc = PTR_RET(ps_tsks[ps_tsk_num]);
240 if (!rc) 240 if (!rc)
241 ps_tsk_num++; 241 ps_tsk_num++;
242 else 242 else
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index c5cd5b5513e6..0cc384b72943 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -146,7 +146,7 @@ struct acpi_battery {
146 146
147#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat) 147#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat)
148 148
149inline int acpi_battery_present(struct acpi_battery *battery) 149static inline int acpi_battery_present(struct acpi_battery *battery)
150{ 150{
151 return battery->device->status.battery_present; 151 return battery->device->status.battery_present;
152} 152}
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 01708a165368..292de3cab9cc 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -288,13 +288,12 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context)
288 } 288 }
289out_success: 289out_success:
290 context->ret.length = out_obj->buffer.length; 290 context->ret.length = out_obj->buffer.length;
291 context->ret.pointer = kmalloc(context->ret.length, GFP_KERNEL); 291 context->ret.pointer = kmemdup(out_obj->buffer.pointer,
292 context->ret.length, GFP_KERNEL);
292 if (!context->ret.pointer) { 293 if (!context->ret.pointer) {
293 status = AE_NO_MEMORY; 294 status = AE_NO_MEMORY;
294 goto out_kfree; 295 goto out_kfree;
295 } 296 }
296 memcpy(context->ret.pointer, out_obj->buffer.pointer,
297 context->ret.length);
298 status = AE_OK; 297 status = AE_OK;
299 298
300out_kfree: 299out_kfree:
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 86c7d5445c38..92a659aa6396 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -33,6 +33,7 @@
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <acpi/acpi_bus.h> 34#include <acpi/acpi_bus.h>
35#include <acpi/acpi_drivers.h> 35#include <acpi/acpi_drivers.h>
36#include <acpi/button.h>
36 37
37#define PREFIX "ACPI: " 38#define PREFIX "ACPI: "
38 39
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index f9f8a08827fa..e23151667655 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -30,6 +30,8 @@
30 30
31#include "internal.h" 31#include "internal.h"
32 32
33#include "internal.h"
34
33#define PREFIX "ACPI: " 35#define PREFIX "ACPI: "
34 36
35#define _COMPONENT ACPI_CONTAINER_COMPONENT 37#define _COMPONENT ACPI_CONTAINER_COMPONENT
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index f815da82c765..8d1c0105e113 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -174,9 +174,13 @@ static int acpi_fan_add(struct acpi_device *device)
174 174
175static int acpi_fan_remove(struct acpi_device *device) 175static int acpi_fan_remove(struct acpi_device *device)
176{ 176{
177 struct thermal_cooling_device *cdev = acpi_driver_data(device); 177 struct thermal_cooling_device *cdev;
178
179 if (!device)
180 return -EINVAL;
178 181
179 if (!device || !cdev) 182 cdev = acpi_driver_data(device);
183 if (!cdev)
180 return -EINVAL; 184 return -EINVAL;
181 185
182 sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); 186 sysfs_remove_link(&device->dev.kobj, "thermal_cooling");
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 586e7e993d3d..e72186340fec 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -641,7 +641,7 @@ void __init acpi_initrd_override(void *data, size_t size)
641 * Both memblock_reserve and e820_add_region (via arch_reserve_mem_area) 641 * Both memblock_reserve and e820_add_region (via arch_reserve_mem_area)
642 * works fine. 642 * works fine.
643 */ 643 */
644 memblock_reserve(acpi_tables_addr, acpi_tables_addr + all_tables_size); 644 memblock_reserve(acpi_tables_addr, all_tables_size);
645 arch_reserve_mem_area(acpi_tables_addr, all_tables_size); 645 arch_reserve_mem_area(acpi_tables_addr, all_tables_size);
646 646
647 p = early_ioremap(acpi_tables_addr, all_tables_size); 647 p = early_ioremap(acpi_tables_addr, all_tables_size);
@@ -1555,7 +1555,7 @@ int acpi_check_resource_conflict(const struct resource *res)
1555 else 1555 else
1556 space_id = ACPI_ADR_SPACE_SYSTEM_MEMORY; 1556 space_id = ACPI_ADR_SPACE_SYSTEM_MEMORY;
1557 1557
1558 length = res->end - res->start + 1; 1558 length = resource_size(res);
1559 if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) 1559 if (acpi_enforce_resources != ENFORCE_RESOURCES_NO)
1560 warn = 1; 1560 warn = 1;
1561 clash = acpi_check_address_range(space_id, res->start, length, warn); 1561 clash = acpi_check_address_range(space_id, res->start, length, warn);
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 6ae5e440436e..4241b8d844eb 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -201,8 +201,8 @@ static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root,
201 *control &= OSC_PCI_CONTROL_MASKS; 201 *control &= OSC_PCI_CONTROL_MASKS;
202 capbuf[OSC_CONTROL_TYPE] = *control | root->osc_control_set; 202 capbuf[OSC_CONTROL_TYPE] = *control | root->osc_control_set;
203 } else { 203 } else {
204 /* Run _OSC query for all possible controls. */ 204 /* Run _OSC query only with existing controls. */
205 capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS; 205 capbuf[OSC_CONTROL_TYPE] = root->osc_control_set;
206 } 206 }
207 207
208 status = acpi_pci_run_osc(root->device->handle, capbuf, &result); 208 status = acpi_pci_run_osc(root->device->handle, capbuf, &result);
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index 641b5450a0db..e8e652710e65 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -218,9 +218,13 @@ processor_get_max_state(struct thermal_cooling_device *cdev,
218 unsigned long *state) 218 unsigned long *state)
219{ 219{
220 struct acpi_device *device = cdev->devdata; 220 struct acpi_device *device = cdev->devdata;
221 struct acpi_processor *pr = acpi_driver_data(device); 221 struct acpi_processor *pr;
222 222
223 if (!device || !pr) 223 if (!device)
224 return -EINVAL;
225
226 pr = acpi_driver_data(device);
227 if (!pr)
224 return -EINVAL; 228 return -EINVAL;
225 229
226 *state = acpi_processor_max_state(pr); 230 *state = acpi_processor_max_state(pr);
@@ -232,9 +236,13 @@ processor_get_cur_state(struct thermal_cooling_device *cdev,
232 unsigned long *cur_state) 236 unsigned long *cur_state)
233{ 237{
234 struct acpi_device *device = cdev->devdata; 238 struct acpi_device *device = cdev->devdata;
235 struct acpi_processor *pr = acpi_driver_data(device); 239 struct acpi_processor *pr;
236 240
237 if (!device || !pr) 241 if (!device)
242 return -EINVAL;
243
244 pr = acpi_driver_data(device);
245 if (!pr)
238 return -EINVAL; 246 return -EINVAL;
239 247
240 *cur_state = cpufreq_get_cur_state(pr->id); 248 *cur_state = cpufreq_get_cur_state(pr->id);
@@ -248,11 +256,15 @@ processor_set_cur_state(struct thermal_cooling_device *cdev,
248 unsigned long state) 256 unsigned long state)
249{ 257{
250 struct acpi_device *device = cdev->devdata; 258 struct acpi_device *device = cdev->devdata;
251 struct acpi_processor *pr = acpi_driver_data(device); 259 struct acpi_processor *pr;
252 int result = 0; 260 int result = 0;
253 int max_pstate; 261 int max_pstate;
254 262
255 if (!device || !pr) 263 if (!device)
264 return -EINVAL;
265
266 pr = acpi_driver_data(device);
267 if (!pr)
256 return -EINVAL; 268 return -EINVAL;
257 269
258 max_pstate = cpufreq_get_max_state(pr->id); 270 max_pstate = cpufreq_get_max_state(pr->id);
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index 1d02b7b5ade0..e7dd2c1fee79 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -211,9 +211,10 @@ err_ret:
211 */ 211 */
212void acpi_processor_throttling_init(void) 212void acpi_processor_throttling_init(void)
213{ 213{
214 if (acpi_processor_update_tsd_coord()) 214 if (acpi_processor_update_tsd_coord()) {
215 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 215 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
216 "Assume no T-state coordination\n")); 216 "Assume no T-state coordination\n"));
217 }
217 218
218 return; 219 return;
219} 220}
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 8470771e5eae..a33821ca3895 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -723,9 +723,19 @@ static int thermal_get_trend(struct thermal_zone_device *thermal,
723 return -EINVAL; 723 return -EINVAL;
724 724
725 if (type == THERMAL_TRIP_ACTIVE) { 725 if (type == THERMAL_TRIP_ACTIVE) {
726 /* aggressive active cooling */ 726 unsigned long trip_temp;
727 *trend = THERMAL_TREND_RAISING; 727 unsigned long temp = KELVIN_TO_MILLICELSIUS(tz->temperature,
728 return 0; 728 tz->kelvin_offset);
729 if (thermal_get_trip_temp(thermal, trip, &trip_temp))
730 return -EINVAL;
731
732 if (temp > trip_temp) {
733 *trend = THERMAL_TREND_RAISING;
734 return 0;
735 } else {
736 /* Fall back on default trend */
737 return -EINVAL;
738 }
729 } 739 }
730 740
731 /* 741 /*
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 313f959413dc..c3932d0876e0 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -167,7 +167,8 @@ struct acpi_video_device_flags {
167 u8 dvi:1; 167 u8 dvi:1;
168 u8 bios:1; 168 u8 bios:1;
169 u8 unknown:1; 169 u8 unknown:1;
170 u8 reserved:2; 170 u8 notify:1;
171 u8 reserved:1;
171}; 172};
172 173
173struct acpi_video_device_cap { 174struct acpi_video_device_cap {
@@ -222,7 +223,7 @@ static int acpi_video_device_lcd_set_level(struct acpi_video_device *device,
222 int level); 223 int level);
223static int acpi_video_device_lcd_get_level_current( 224static int acpi_video_device_lcd_get_level_current(
224 struct acpi_video_device *device, 225 struct acpi_video_device *device,
225 unsigned long long *level, int init); 226 unsigned long long *level, bool raw);
226static int acpi_video_get_next_level(struct acpi_video_device *device, 227static int acpi_video_get_next_level(struct acpi_video_device *device,
227 u32 level_current, u32 event); 228 u32 level_current, u32 event);
228static int acpi_video_switch_brightness(struct acpi_video_device *device, 229static int acpi_video_switch_brightness(struct acpi_video_device *device,
@@ -236,7 +237,7 @@ static int acpi_video_get_brightness(struct backlight_device *bd)
236 struct acpi_video_device *vd = 237 struct acpi_video_device *vd =
237 (struct acpi_video_device *)bl_get_data(bd); 238 (struct acpi_video_device *)bl_get_data(bd);
238 239
239 if (acpi_video_device_lcd_get_level_current(vd, &cur_level, 0)) 240 if (acpi_video_device_lcd_get_level_current(vd, &cur_level, false))
240 return -EINVAL; 241 return -EINVAL;
241 for (i = 2; i < vd->brightness->count; i++) { 242 for (i = 2; i < vd->brightness->count; i++) {
242 if (vd->brightness->levels[i] == cur_level) 243 if (vd->brightness->levels[i] == cur_level)
@@ -281,7 +282,7 @@ static int video_get_cur_state(struct thermal_cooling_device *cooling_dev, unsig
281 unsigned long long level; 282 unsigned long long level;
282 int offset; 283 int offset;
283 284
284 if (acpi_video_device_lcd_get_level_current(video, &level, 0)) 285 if (acpi_video_device_lcd_get_level_current(video, &level, false))
285 return -EINVAL; 286 return -EINVAL;
286 for (offset = 2; offset < video->brightness->count; offset++) 287 for (offset = 2; offset < video->brightness->count; offset++)
287 if (level == video->brightness->levels[offset]) { 288 if (level == video->brightness->levels[offset]) {
@@ -447,12 +448,45 @@ static struct dmi_system_id video_dmi_table[] __initdata = {
447 DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13 - 2000 Notebook PC"), 448 DMI_MATCH(DMI_PRODUCT_NAME, "HP Folio 13 - 2000 Notebook PC"),
448 }, 449 },
449 }, 450 },
451 {
452 .callback = video_ignore_initial_backlight,
453 .ident = "HP Pavilion dm4",
454 .matches = {
455 DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"),
456 DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dm4 Notebook PC"),
457 },
458 },
450 {} 459 {}
451}; 460};
452 461
462static unsigned long long
463acpi_video_bqc_value_to_level(struct acpi_video_device *device,
464 unsigned long long bqc_value)
465{
466 unsigned long long level;
467
468 if (device->brightness->flags._BQC_use_index) {
469 /*
470 * _BQC returns an index that doesn't account for
471 * the first 2 items with special meaning, so we need
472 * to compensate for that by offsetting ourselves
473 */
474 if (device->brightness->flags._BCL_reversed)
475 bqc_value = device->brightness->count - 3 - bqc_value;
476
477 level = device->brightness->levels[bqc_value + 2];
478 } else {
479 level = bqc_value;
480 }
481
482 level += bqc_offset_aml_bug_workaround;
483
484 return level;
485}
486
453static int 487static int
454acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, 488acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
455 unsigned long long *level, int init) 489 unsigned long long *level, bool raw)
456{ 490{
457 acpi_status status = AE_OK; 491 acpi_status status = AE_OK;
458 int i; 492 int i;
@@ -463,29 +497,30 @@ acpi_video_device_lcd_get_level_current(struct acpi_video_device *device,
463 status = acpi_evaluate_integer(device->dev->handle, buf, 497 status = acpi_evaluate_integer(device->dev->handle, buf,
464 NULL, level); 498 NULL, level);
465 if (ACPI_SUCCESS(status)) { 499 if (ACPI_SUCCESS(status)) {
466 if (device->brightness->flags._BQC_use_index) { 500 if (raw) {
467 if (device->brightness->flags._BCL_reversed) 501 /*
468 *level = device->brightness->count 502 * Caller has indicated he wants the raw
469 - 3 - (*level); 503 * value returned by _BQC, so don't furtherly
470 *level = device->brightness->levels[*level + 2]; 504 * mess with the value.
471 505 */
506 return 0;
472 } 507 }
473 *level += bqc_offset_aml_bug_workaround; 508
509 *level = acpi_video_bqc_value_to_level(device, *level);
510
474 for (i = 2; i < device->brightness->count; i++) 511 for (i = 2; i < device->brightness->count; i++)
475 if (device->brightness->levels[i] == *level) { 512 if (device->brightness->levels[i] == *level) {
476 device->brightness->curr = *level; 513 device->brightness->curr = *level;
477 return 0; 514 return 0;
478 } 515 }
479 if (!init) { 516 /*
480 /* 517 * BQC returned an invalid level.
481 * BQC returned an invalid level. 518 * Stop using it.
482 * Stop using it. 519 */
483 */ 520 ACPI_WARNING((AE_INFO,
484 ACPI_WARNING((AE_INFO, 521 "%s returned an invalid level",
485 "%s returned an invalid level", 522 buf));
486 buf)); 523 device->cap._BQC = device->cap._BCQ = 0;
487 device->cap._BQC = device->cap._BCQ = 0;
488 }
489 } else { 524 } else {
490 /* Fixme: 525 /* Fixme:
491 * should we return an error or ignore this failure? 526 * should we return an error or ignore this failure?
@@ -598,6 +633,56 @@ acpi_video_cmp_level(const void *a, const void *b)
598} 633}
599 634
600/* 635/*
636 * Decides if _BQC/_BCQ for this system is usable
637 *
638 * We do this by changing the level first and then read out the current
639 * brightness level, if the value does not match, find out if it is using
640 * index. If not, clear the _BQC/_BCQ capability.
641 */
642static int acpi_video_bqc_quirk(struct acpi_video_device *device,
643 int max_level, int current_level)
644{
645 struct acpi_video_device_brightness *br = device->brightness;
646 int result;
647 unsigned long long level;
648 int test_level;
649
650 /* don't mess with existing known broken systems */
651 if (bqc_offset_aml_bug_workaround)
652 return 0;
653
654 /*
655 * Some systems always report current brightness level as maximum
656 * through _BQC, we need to test another value for them.
657 */
658 test_level = current_level == max_level ? br->levels[2] : max_level;
659
660 result = acpi_video_device_lcd_set_level(device, test_level);
661 if (result)
662 return result;
663
664 result = acpi_video_device_lcd_get_level_current(device, &level, true);
665 if (result)
666 return result;
667
668 if (level != test_level) {
669 /* buggy _BQC found, need to find out if it uses index */
670 if (level < br->count) {
671 if (br->flags._BCL_reversed)
672 level = br->count - 3 - level;
673 if (br->levels[level + 2] == test_level)
674 br->flags._BQC_use_index = 1;
675 }
676
677 if (!br->flags._BQC_use_index)
678 device->cap._BQC = device->cap._BCQ = 0;
679 }
680
681 return 0;
682}
683
684
685/*
601 * Arg: 686 * Arg:
602 * device : video output device (LCD, CRT, ..) 687 * device : video output device (LCD, CRT, ..)
603 * 688 *
@@ -703,42 +788,36 @@ acpi_video_init_brightness(struct acpi_video_device *device)
703 if (!device->cap._BQC) 788 if (!device->cap._BQC)
704 goto set_level; 789 goto set_level;
705 790
706 result = acpi_video_device_lcd_get_level_current(device, &level_old, 1); 791 result = acpi_video_device_lcd_get_level_current(device,
707 if (result) 792 &level_old, true);
708 goto out_free_levels;
709
710 /*
711 * Set the level to maximum and check if _BQC uses indexed value
712 */
713 result = acpi_video_device_lcd_set_level(device, max_level);
714 if (result) 793 if (result)
715 goto out_free_levels; 794 goto out_free_levels;
716 795
717 result = acpi_video_device_lcd_get_level_current(device, &level, 0); 796 result = acpi_video_bqc_quirk(device, max_level, level_old);
718 if (result) 797 if (result)
719 goto out_free_levels; 798 goto out_free_levels;
799 /*
800 * cap._BQC may get cleared due to _BQC is found to be broken
801 * in acpi_video_bqc_quirk, so check again here.
802 */
803 if (!device->cap._BQC)
804 goto set_level;
720 805
721 br->flags._BQC_use_index = (level == max_level ? 0 : 1); 806 if (use_bios_initial_backlight) {
722 807 level = acpi_video_bqc_value_to_level(device, level_old);
723 if (!br->flags._BQC_use_index) {
724 /* 808 /*
725 * Set the backlight to the initial state. 809 * On some buggy laptops, _BQC returns an uninitialized
726 * On some buggy laptops, _BQC returns an uninitialized value 810 * value when invoked for the first time, i.e.
727 * when invoked for the first time, i.e. level_old is invalid. 811 * level_old is invalid (no matter whether it's a level
728 * set the backlight to max_level in this case 812 * or an index). Set the backlight to max_level in this case.
729 */ 813 */
730 if (use_bios_initial_backlight) { 814 for (i = 2; i < br->count; i++)
731 for (i = 2; i < br->count; i++) 815 if (level_old == br->levels[i])
732 if (level_old == br->levels[i]) 816 break;
733 level = level_old; 817 if (i == br->count)
734 } 818 level = max_level;
735 goto set_level;
736 } 819 }
737 820
738 if (br->flags._BCL_reversed)
739 level_old = (br->count - 1) - level_old;
740 level = br->levels[level_old];
741
742set_level: 821set_level:
743 result = acpi_video_device_lcd_set_level(device, level); 822 result = acpi_video_device_lcd_set_level(device, level);
744 if (result) 823 if (result)
@@ -996,53 +1075,51 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
996 struct acpi_video_device *data; 1075 struct acpi_video_device *data;
997 struct acpi_video_device_attrib* attribute; 1076 struct acpi_video_device_attrib* attribute;
998 1077
999 if (!device || !video)
1000 return -EINVAL;
1001
1002 status = 1078 status =
1003 acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id); 1079 acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
1004 if (ACPI_SUCCESS(status)) { 1080 /* Some device omits _ADR, we skip them instead of fail */
1005 1081 if (ACPI_FAILURE(status))
1006 data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL); 1082 return 0;
1007 if (!data)
1008 return -ENOMEM;
1009
1010 strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME);
1011 strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
1012 device->driver_data = data;
1013
1014 data->device_id = device_id;
1015 data->video = video;
1016 data->dev = device;
1017 1083
1018 attribute = acpi_video_get_device_attr(video, device_id); 1084 data = kzalloc(sizeof(struct acpi_video_device), GFP_KERNEL);
1085 if (!data)
1086 return -ENOMEM;
1019 1087
1020 if((attribute != NULL) && attribute->device_id_scheme) { 1088 strcpy(acpi_device_name(device), ACPI_VIDEO_DEVICE_NAME);
1021 switch (attribute->display_type) { 1089 strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
1022 case ACPI_VIDEO_DISPLAY_CRT: 1090 device->driver_data = data;
1023 data->flags.crt = 1; 1091
1024 break; 1092 data->device_id = device_id;
1025 case ACPI_VIDEO_DISPLAY_TV: 1093 data->video = video;
1026 data->flags.tvout = 1; 1094 data->dev = device;
1027 break; 1095
1028 case ACPI_VIDEO_DISPLAY_DVI: 1096 attribute = acpi_video_get_device_attr(video, device_id);
1029 data->flags.dvi = 1; 1097
1030 break; 1098 if((attribute != NULL) && attribute->device_id_scheme) {
1031 case ACPI_VIDEO_DISPLAY_LCD: 1099 switch (attribute->display_type) {
1032 data->flags.lcd = 1; 1100 case ACPI_VIDEO_DISPLAY_CRT:
1033 break; 1101 data->flags.crt = 1;
1034 default: 1102 break;
1035 data->flags.unknown = 1; 1103 case ACPI_VIDEO_DISPLAY_TV:
1036 break; 1104 data->flags.tvout = 1;
1037 } 1105 break;
1038 if(attribute->bios_can_detect) 1106 case ACPI_VIDEO_DISPLAY_DVI:
1039 data->flags.bios = 1; 1107 data->flags.dvi = 1;
1040 } else { 1108 break;
1041 /* Check for legacy IDs */ 1109 case ACPI_VIDEO_DISPLAY_LCD:
1042 device_type = acpi_video_get_device_type(video, 1110 data->flags.lcd = 1;
1043 device_id); 1111 break;
1044 /* Ignore bits 16 and 18-20 */ 1112 default:
1045 switch (device_type & 0xffe2ffff) { 1113 data->flags.unknown = 1;
1114 break;
1115 }
1116 if(attribute->bios_can_detect)
1117 data->flags.bios = 1;
1118 } else {
1119 /* Check for legacy IDs */
1120 device_type = acpi_video_get_device_type(video, device_id);
1121 /* Ignore bits 16 and 18-20 */
1122 switch (device_type & 0xffe2ffff) {
1046 case ACPI_VIDEO_DISPLAY_LEGACY_MONITOR: 1123 case ACPI_VIDEO_DISPLAY_LEGACY_MONITOR:
1047 data->flags.crt = 1; 1124 data->flags.crt = 1;
1048 break; 1125 break;
@@ -1054,34 +1131,24 @@ acpi_video_bus_get_one_device(struct acpi_device *device,
1054 break; 1131 break;
1055 default: 1132 default:
1056 data->flags.unknown = 1; 1133 data->flags.unknown = 1;
1057 }
1058 } 1134 }
1135 }
1059 1136
1060 acpi_video_device_bind(video, data); 1137 acpi_video_device_bind(video, data);
1061 acpi_video_device_find_cap(data); 1138 acpi_video_device_find_cap(data);
1062
1063 status = acpi_install_notify_handler(device->handle,
1064 ACPI_DEVICE_NOTIFY,
1065 acpi_video_device_notify,
1066 data);
1067 if (ACPI_FAILURE(status)) {
1068 printk(KERN_ERR PREFIX
1069 "Error installing notify handler\n");
1070 if(data->brightness)
1071 kfree(data->brightness->levels);
1072 kfree(data->brightness);
1073 kfree(data);
1074 return -ENODEV;
1075 }
1076 1139
1077 mutex_lock(&video->device_list_lock); 1140 status = acpi_install_notify_handler(device->handle, ACPI_DEVICE_NOTIFY,
1078 list_add_tail(&data->entry, &video->video_device_list); 1141 acpi_video_device_notify, data);
1079 mutex_unlock(&video->device_list_lock); 1142 if (ACPI_FAILURE(status))
1143 dev_err(&device->dev, "Error installing notify handler\n");
1144 else
1145 data->flags.notify = 1;
1080 1146
1081 return 0; 1147 mutex_lock(&video->device_list_lock);
1082 } 1148 list_add_tail(&data->entry, &video->video_device_list);
1149 mutex_unlock(&video->device_list_lock);
1083 1150
1084 return -ENOENT; 1151 return status;
1085} 1152}
1086 1153
1087/* 1154/*
@@ -1268,7 +1335,8 @@ acpi_video_switch_brightness(struct acpi_video_device *device, int event)
1268 goto out; 1335 goto out;
1269 1336
1270 result = acpi_video_device_lcd_get_level_current(device, 1337 result = acpi_video_device_lcd_get_level_current(device,
1271 &level_current, 0); 1338 &level_current,
1339 false);
1272 if (result) 1340 if (result)
1273 goto out; 1341 goto out;
1274 1342
@@ -1373,9 +1441,8 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video,
1373 1441
1374 status = acpi_video_bus_get_one_device(dev, video); 1442 status = acpi_video_bus_get_one_device(dev, video);
1375 if (status) { 1443 if (status) {
1376 printk(KERN_WARNING PREFIX 1444 dev_err(&dev->dev, "Can't attach device\n");
1377 "Can't attach device\n"); 1445 break;
1378 continue;
1379 } 1446 }
1380 } 1447 }
1381 return status; 1448 return status;
@@ -1388,13 +1455,14 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device)
1388 if (!device || !device->video) 1455 if (!device || !device->video)
1389 return -ENOENT; 1456 return -ENOENT;
1390 1457
1391 status = acpi_remove_notify_handler(device->dev->handle, 1458 if (device->flags.notify) {
1392 ACPI_DEVICE_NOTIFY, 1459 status = acpi_remove_notify_handler(device->dev->handle,
1393 acpi_video_device_notify); 1460 ACPI_DEVICE_NOTIFY, acpi_video_device_notify);
1394 if (ACPI_FAILURE(status)) { 1461 if (ACPI_FAILURE(status))
1395 printk(KERN_WARNING PREFIX 1462 dev_err(&device->dev->dev,
1396 "Can't remove video notify handler\n"); 1463 "Can't remove video notify handler\n");
1397 } 1464 }
1465
1398 if (device->backlight) { 1466 if (device->backlight) {
1399 backlight_device_unregister(device->backlight); 1467 backlight_device_unregister(device->backlight);
1400 device->backlight = NULL; 1468 device->backlight = NULL;
@@ -1676,7 +1744,7 @@ static int acpi_video_bus_add(struct acpi_device *device)
1676 1744
1677 error = acpi_video_bus_get_devices(video, device); 1745 error = acpi_video_bus_get_devices(video, device);
1678 if (error) 1746 if (error)
1679 goto err_free_video; 1747 goto err_put_video;
1680 1748
1681 video->input = input = input_allocate_device(); 1749 video->input = input = input_allocate_device();
1682 if (!input) { 1750 if (!input) {