aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/Kconfig9
-rw-r--r--drivers/acpi/ac.c16
-rw-r--r--drivers/acpi/asus_acpi.c55
-rw-r--r--drivers/acpi/battery.c36
-rw-r--r--drivers/acpi/bay.c6
-rw-r--r--drivers/acpi/blacklist.c383
-rw-r--r--drivers/acpi/bus.c20
-rw-r--r--drivers/acpi/debug.c57
-rw-r--r--drivers/acpi/dock.c6
-rw-r--r--drivers/acpi/ec.c59
-rw-r--r--drivers/acpi/events/evgpe.c8
-rw-r--r--drivers/acpi/events/evregion.c8
-rw-r--r--drivers/acpi/fan.c40
-rw-r--r--drivers/acpi/hardware/hwsleep.c79
-rw-r--r--drivers/acpi/osl.c181
-rw-r--r--drivers/acpi/pci_irq.c9
-rw-r--r--drivers/acpi/pci_link.c2
-rw-r--r--drivers/acpi/processor_idle.c56
-rw-r--r--drivers/acpi/processor_throttling.c4
-rw-r--r--drivers/acpi/sbs.c23
-rw-r--r--drivers/acpi/scan.c108
-rw-r--r--drivers/acpi/sleep/main.c144
-rw-r--r--drivers/acpi/sleep/proc.c46
-rw-r--r--drivers/acpi/sleep/sleep.h2
-rw-r--r--drivers/acpi/system.c13
-rw-r--r--drivers/acpi/tables/Makefile2
-rw-r--r--drivers/acpi/tables/tbxfroot.c4
-rw-r--r--drivers/acpi/thermal.c17
-rw-r--r--drivers/acpi/utilities/utresrc.c2
-rw-r--r--drivers/acpi/video.c49
30 files changed, 1208 insertions, 236 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index b9f923ef173d..ccf6ea95f68c 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -82,6 +82,12 @@ config ACPI_PROCFS_POWER
82 and functions, which do not yet exist in /sys 82 and functions, which do not yet exist in /sys
83 83
84 Say N to delete power /proc/acpi/ folders that have moved to /sys/ 84 Say N to delete power /proc/acpi/ folders that have moved to /sys/
85config ACPI_SYSFS_POWER
86 bool "Future power /sys interface"
87 select POWER_SUPPLY
88 default y
89 ---help---
90 Say N to disable power /sys interface
85config ACPI_PROC_EVENT 91config ACPI_PROC_EVENT
86 bool "Deprecated /proc/acpi/event support" 92 bool "Deprecated /proc/acpi/event support"
87 depends on PROC_FS 93 depends on PROC_FS
@@ -103,7 +109,6 @@ config ACPI_PROC_EVENT
103config ACPI_AC 109config ACPI_AC
104 tristate "AC Adapter" 110 tristate "AC Adapter"
105 depends on X86 111 depends on X86
106 select POWER_SUPPLY
107 default y 112 default y
108 help 113 help
109 This driver adds support for the AC Adapter object, which indicates 114 This driver adds support for the AC Adapter object, which indicates
@@ -113,7 +118,6 @@ config ACPI_AC
113config ACPI_BATTERY 118config ACPI_BATTERY
114 tristate "Battery" 119 tristate "Battery"
115 depends on X86 120 depends on X86
116 select POWER_SUPPLY
117 default y 121 default y
118 help 122 help
119 This driver adds support for battery information through 123 This driver adds support for battery information through
@@ -368,7 +372,6 @@ config ACPI_HOTPLUG_MEMORY
368config ACPI_SBS 372config ACPI_SBS
369 tristate "Smart Battery System" 373 tristate "Smart Battery System"
370 depends on X86 374 depends on X86
371 select POWER_SUPPLY
372 help 375 help
373 This driver adds support for the Smart Battery System, another 376 This driver adds support for the Smart Battery System, another
374 type of access to battery information, found on some laptops. 377 type of access to battery information, found on some laptops.
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 76ed4f52bebd..76b9bea98b6d 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -31,7 +31,9 @@
31#include <linux/proc_fs.h> 31#include <linux/proc_fs.h>
32#include <linux/seq_file.h> 32#include <linux/seq_file.h>
33#endif 33#endif
34#ifdef CONFIG_ACPI_SYSFS_POWER
34#include <linux/power_supply.h> 35#include <linux/power_supply.h>
36#endif
35#include <acpi/acpi_bus.h> 37#include <acpi/acpi_bus.h>
36#include <acpi/acpi_drivers.h> 38#include <acpi/acpi_drivers.h>
37 39
@@ -79,7 +81,9 @@ static struct acpi_driver acpi_ac_driver = {
79}; 81};
80 82
81struct acpi_ac { 83struct acpi_ac {
84#ifdef CONFIG_ACPI_SYSFS_POWER
82 struct power_supply charger; 85 struct power_supply charger;
86#endif
83 struct acpi_device * device; 87 struct acpi_device * device;
84 unsigned long state; 88 unsigned long state;
85}; 89};
@@ -94,7 +98,7 @@ static const struct file_operations acpi_ac_fops = {
94 .release = single_release, 98 .release = single_release,
95}; 99};
96#endif 100#endif
97 101#ifdef CONFIG_ACPI_SYSFS_POWER
98static int get_ac_property(struct power_supply *psy, 102static int get_ac_property(struct power_supply *psy,
99 enum power_supply_property psp, 103 enum power_supply_property psp,
100 union power_supply_propval *val) 104 union power_supply_propval *val)
@@ -113,7 +117,7 @@ static int get_ac_property(struct power_supply *psy,
113static enum power_supply_property ac_props[] = { 117static enum power_supply_property ac_props[] = {
114 POWER_SUPPLY_PROP_ONLINE, 118 POWER_SUPPLY_PROP_ONLINE,
115}; 119};
116 120#endif
117/* -------------------------------------------------------------------------- 121/* --------------------------------------------------------------------------
118 AC Adapter Management 122 AC Adapter Management
119 -------------------------------------------------------------------------- */ 123 -------------------------------------------------------------------------- */
@@ -241,7 +245,9 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
241 acpi_bus_generate_netlink_event(device->pnp.device_class, 245 acpi_bus_generate_netlink_event(device->pnp.device_class,
242 device->dev.bus_id, event, 246 device->dev.bus_id, event,
243 (u32) ac->state); 247 (u32) ac->state);
248#ifdef CONFIG_ACPI_SYSFS_POWER
244 kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); 249 kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
250#endif
245 break; 251 break;
246 default: 252 default:
247 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 253 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -280,12 +286,14 @@ static int acpi_ac_add(struct acpi_device *device)
280#endif 286#endif
281 if (result) 287 if (result)
282 goto end; 288 goto end;
289#ifdef CONFIG_ACPI_SYSFS_POWER
283 ac->charger.name = acpi_device_bid(device); 290 ac->charger.name = acpi_device_bid(device);
284 ac->charger.type = POWER_SUPPLY_TYPE_MAINS; 291 ac->charger.type = POWER_SUPPLY_TYPE_MAINS;
285 ac->charger.properties = ac_props; 292 ac->charger.properties = ac_props;
286 ac->charger.num_properties = ARRAY_SIZE(ac_props); 293 ac->charger.num_properties = ARRAY_SIZE(ac_props);
287 ac->charger.get_property = get_ac_property; 294 ac->charger.get_property = get_ac_property;
288 power_supply_register(&ac->device->dev, &ac->charger); 295 power_supply_register(&ac->device->dev, &ac->charger);
296#endif
289 status = acpi_install_notify_handler(device->handle, 297 status = acpi_install_notify_handler(device->handle,
290 ACPI_ALL_NOTIFY, acpi_ac_notify, 298 ACPI_ALL_NOTIFY, acpi_ac_notify,
291 ac); 299 ac);
@@ -319,8 +327,10 @@ static int acpi_ac_resume(struct acpi_device *device)
319 old_state = ac->state; 327 old_state = ac->state;
320 if (acpi_ac_get_state(ac)) 328 if (acpi_ac_get_state(ac))
321 return 0; 329 return 0;
330#ifdef CONFIG_ACPI_SYSFS_POWER
322 if (old_state != ac->state) 331 if (old_state != ac->state)
323 kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); 332 kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE);
333#endif
324 return 0; 334 return 0;
325} 335}
326 336
@@ -337,8 +347,10 @@ static int acpi_ac_remove(struct acpi_device *device, int type)
337 347
338 status = acpi_remove_notify_handler(device->handle, 348 status = acpi_remove_notify_handler(device->handle,
339 ACPI_ALL_NOTIFY, acpi_ac_notify); 349 ACPI_ALL_NOTIFY, acpi_ac_notify);
350#ifdef CONFIG_ACPI_SYSFS_POWER
340 if (ac->charger.dev) 351 if (ac->charger.dev)
341 power_supply_unregister(&ac->charger); 352 power_supply_unregister(&ac->charger);
353#endif
342#ifdef CONFIG_ACPI_PROCFS_POWER 354#ifdef CONFIG_ACPI_PROCFS_POWER
343 acpi_ac_remove_fs(device); 355 acpi_ac_remove_fs(device);
344#endif 356#endif
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
index d915fec9bf63..d25ef961415c 100644
--- a/drivers/acpi/asus_acpi.c
+++ b/drivers/acpi/asus_acpi.c
@@ -142,6 +142,7 @@ struct asus_hotk {
142 xxN, //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N 142 xxN, //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N
143 A4S, //Z81sp 143 A4S, //Z81sp
144 //(Centrino) 144 //(Centrino)
145 F3Sa,
145 END_MODEL 146 END_MODEL
146 } model; //Models currently supported 147 } model; //Models currently supported
147 u16 event_count[128]; //count for each event TODO make this better 148 u16 event_count[128]; //count for each event TODO make this better
@@ -405,7 +406,20 @@ static struct model_data model_conf[END_MODEL] = {
405 .brightness_get = "GPLV", 406 .brightness_get = "GPLV",
406 .mt_bt_switch = "BLED", 407 .mt_bt_switch = "BLED",
407 .mt_wled = "WLED" 408 .mt_wled = "WLED"
408 } 409 },
410
411 {
412 .name = "F3Sa",
413 .mt_bt_switch = "BLED",
414 .mt_wled = "WLED",
415 .mt_mled = "MLED",
416 .brightness_get = "GPLV",
417 .brightness_set = "SPLV",
418 .mt_lcd_switch = "\\_SB.PCI0.SBRG.EC0._Q10",
419 .lcd_status = "\\_SB.PCI0.SBRG.EC0.RPIN",
420 .display_get = "\\ADVG",
421 .display_set = "SDSP",
422 },
409 423
410}; 424};
411 425
@@ -710,15 +724,8 @@ static int get_lcd_state(void)
710{ 724{
711 int lcd = 0; 725 int lcd = 0;
712 726
713 if (hotk->model != L3H) { 727 if (hotk->model == L3H) {
714 /* We don't have to check anything if we are here */ 728 /* L3H and the like have to be handled differently */
715 if (!read_acpi_int(NULL, hotk->methods->lcd_status, &lcd))
716 printk(KERN_WARNING
717 "Asus ACPI: Error reading LCD status\n");
718
719 if (hotk->model == L2D)
720 lcd = ~lcd;
721 } else { /* L3H and the like have to be handled differently */
722 acpi_status status = 0; 729 acpi_status status = 0;
723 struct acpi_object_list input; 730 struct acpi_object_list input;
724 union acpi_object mt_params[2]; 731 union acpi_object mt_params[2];
@@ -745,6 +752,32 @@ static int get_lcd_state(void)
745 if (out_obj.type == ACPI_TYPE_INTEGER) 752 if (out_obj.type == ACPI_TYPE_INTEGER)
746 /* That's what the AML code does */ 753 /* That's what the AML code does */
747 lcd = out_obj.integer.value >> 8; 754 lcd = out_obj.integer.value >> 8;
755 } else if (hotk->model == F3Sa) {
756 unsigned long tmp;
757 union acpi_object param;
758 struct acpi_object_list input;
759 acpi_status status;
760
761 /* Read pin 11 */
762 param.type = ACPI_TYPE_INTEGER;
763 param.integer.value = 0x11;
764 input.count = 1;
765 input.pointer = &param;
766
767 status = acpi_evaluate_integer(NULL, hotk->methods->lcd_status,
768 &input, &tmp);
769 if (status != AE_OK)
770 return -1;
771
772 lcd = tmp;
773 } else {
774 /* We don't have to check anything if we are here */
775 if (!read_acpi_int(NULL, hotk->methods->lcd_status, &lcd))
776 printk(KERN_WARNING
777 "Asus ACPI: Error reading LCD status\n");
778
779 if (hotk->model == L2D)
780 lcd = ~lcd;
748 } 781 }
749 782
750 return (lcd & 1); 783 return (lcd & 1);
@@ -1134,6 +1167,8 @@ static int asus_model_match(char *model)
1134 return W5A; 1167 return W5A;
1135 else if (strncmp(model, "A4S", 3) == 0) 1168 else if (strncmp(model, "A4S", 3) == 0)
1136 return A4S; 1169 return A4S;
1170 else if (strncmp(model, "F3Sa", 4) == 0)
1171 return F3Sa;
1137 else 1172 else
1138 return END_MODEL; 1173 return END_MODEL;
1139} 1174}
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 8f7505d304b5..f6215e809808 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -40,7 +40,9 @@
40#include <acpi/acpi_bus.h> 40#include <acpi/acpi_bus.h>
41#include <acpi/acpi_drivers.h> 41#include <acpi/acpi_drivers.h>
42 42
43#ifdef CONFIG_ACPI_SYSFS_POWER
43#include <linux/power_supply.h> 44#include <linux/power_supply.h>
45#endif
44 46
45#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF 47#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF
46 48
@@ -86,7 +88,9 @@ MODULE_DEVICE_TABLE(acpi, battery_device_ids);
86 88
87struct acpi_battery { 89struct acpi_battery {
88 struct mutex lock; 90 struct mutex lock;
91#ifdef CONFIG_ACPI_SYSFS_POWER
89 struct power_supply bat; 92 struct power_supply bat;
93#endif
90 struct acpi_device *device; 94 struct acpi_device *device;
91 unsigned long update_time; 95 unsigned long update_time;
92 int current_now; 96 int current_now;
@@ -117,6 +121,7 @@ inline int acpi_battery_present(struct acpi_battery *battery)
117 return battery->device->status.battery_present; 121 return battery->device->status.battery_present;
118} 122}
119 123
124#ifdef CONFIG_ACPI_SYSFS_POWER
120static int acpi_battery_technology(struct acpi_battery *battery) 125static int acpi_battery_technology(struct acpi_battery *battery)
121{ 126{
122 if (!strcasecmp("NiCd", battery->type)) 127 if (!strcasecmp("NiCd", battery->type))
@@ -189,6 +194,9 @@ static int acpi_battery_get_property(struct power_supply *psy,
189 case POWER_SUPPLY_PROP_MANUFACTURER: 194 case POWER_SUPPLY_PROP_MANUFACTURER:
190 val->strval = battery->oem_info; 195 val->strval = battery->oem_info;
191 break; 196 break;
197 case POWER_SUPPLY_PROP_SERIAL_NUMBER:
198 val->strval = battery->serial_number;
199 break;
192 default: 200 default:
193 return -EINVAL; 201 return -EINVAL;
194 } 202 }
@@ -207,6 +215,7 @@ static enum power_supply_property charge_battery_props[] = {
207 POWER_SUPPLY_PROP_CHARGE_NOW, 215 POWER_SUPPLY_PROP_CHARGE_NOW,
208 POWER_SUPPLY_PROP_MODEL_NAME, 216 POWER_SUPPLY_PROP_MODEL_NAME,
209 POWER_SUPPLY_PROP_MANUFACTURER, 217 POWER_SUPPLY_PROP_MANUFACTURER,
218 POWER_SUPPLY_PROP_SERIAL_NUMBER,
210}; 219};
211 220
212static enum power_supply_property energy_battery_props[] = { 221static enum power_supply_property energy_battery_props[] = {
@@ -221,7 +230,9 @@ static enum power_supply_property energy_battery_props[] = {
221 POWER_SUPPLY_PROP_ENERGY_NOW, 230 POWER_SUPPLY_PROP_ENERGY_NOW,
222 POWER_SUPPLY_PROP_MODEL_NAME, 231 POWER_SUPPLY_PROP_MODEL_NAME,
223 POWER_SUPPLY_PROP_MANUFACTURER, 232 POWER_SUPPLY_PROP_MANUFACTURER,
233 POWER_SUPPLY_PROP_SERIAL_NUMBER,
224}; 234};
235#endif
225 236
226#ifdef CONFIG_ACPI_PROCFS_POWER 237#ifdef CONFIG_ACPI_PROCFS_POWER
227inline char *acpi_battery_units(struct acpi_battery *battery) 238inline char *acpi_battery_units(struct acpi_battery *battery)
@@ -398,6 +409,7 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery)
398 return acpi_battery_set_alarm(battery); 409 return acpi_battery_set_alarm(battery);
399} 410}
400 411
412#ifdef CONFIG_ACPI_SYSFS_POWER
401static ssize_t acpi_battery_alarm_show(struct device *dev, 413static ssize_t acpi_battery_alarm_show(struct device *dev,
402 struct device_attribute *attr, 414 struct device_attribute *attr,
403 char *buf) 415 char *buf)
@@ -429,11 +441,6 @@ static int sysfs_add_battery(struct acpi_battery *battery)
429{ 441{
430 int result; 442 int result;
431 443
432 battery->update_time = 0;
433 result = acpi_battery_get_info(battery);
434 acpi_battery_init_alarm(battery);
435 if (result)
436 return result;
437 if (battery->power_unit) { 444 if (battery->power_unit) {
438 battery->bat.properties = charge_battery_props; 445 battery->bat.properties = charge_battery_props;
439 battery->bat.num_properties = 446 battery->bat.num_properties =
@@ -462,18 +469,31 @@ static void sysfs_remove_battery(struct acpi_battery *battery)
462 power_supply_unregister(&battery->bat); 469 power_supply_unregister(&battery->bat);
463 battery->bat.dev = NULL; 470 battery->bat.dev = NULL;
464} 471}
472#endif
465 473
466static int acpi_battery_update(struct acpi_battery *battery) 474static int acpi_battery_update(struct acpi_battery *battery)
467{ 475{
468 int result = acpi_battery_get_status(battery); 476 int result;
477 result = acpi_battery_get_status(battery);
469 if (result) 478 if (result)
470 return result; 479 return result;
480#ifdef CONFIG_ACPI_SYSFS_POWER
471 if (!acpi_battery_present(battery)) { 481 if (!acpi_battery_present(battery)) {
472 sysfs_remove_battery(battery); 482 sysfs_remove_battery(battery);
483 battery->update_time = 0;
473 return 0; 484 return 0;
474 } 485 }
486#endif
487 if (!battery->update_time) {
488 result = acpi_battery_get_info(battery);
489 if (result)
490 return result;
491 acpi_battery_init_alarm(battery);
492 }
493#ifdef CONFIG_ACPI_SYSFS_POWER
475 if (!battery->bat.dev) 494 if (!battery->bat.dev)
476 sysfs_add_battery(battery); 495 sysfs_add_battery(battery);
496#endif
477 return acpi_battery_get_state(battery); 497 return acpi_battery_get_state(battery);
478} 498}
479 499
@@ -767,9 +787,11 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
767 acpi_bus_generate_netlink_event(device->pnp.device_class, 787 acpi_bus_generate_netlink_event(device->pnp.device_class,
768 device->dev.bus_id, event, 788 device->dev.bus_id, event,
769 acpi_battery_present(battery)); 789 acpi_battery_present(battery));
790#ifdef CONFIG_ACPI_SYSFS_POWER
770 /* acpi_batter_update could remove power_supply object */ 791 /* acpi_batter_update could remove power_supply object */
771 if (battery->bat.dev) 792 if (battery->bat.dev)
772 kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE); 793 kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE);
794#endif
773} 795}
774 796
775static int acpi_battery_add(struct acpi_device *device) 797static int acpi_battery_add(struct acpi_device *device)
@@ -828,7 +850,9 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
828#ifdef CONFIG_ACPI_PROCFS_POWER 850#ifdef CONFIG_ACPI_PROCFS_POWER
829 acpi_battery_remove_fs(device); 851 acpi_battery_remove_fs(device);
830#endif 852#endif
853#ifdef CONFIG_ACPI_SYSFS_POWER
831 sysfs_remove_battery(battery); 854 sysfs_remove_battery(battery);
855#endif
832 mutex_destroy(&battery->lock); 856 mutex_destroy(&battery->lock);
833 kfree(battery); 857 kfree(battery);
834 return 0; 858 return 0;
diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c
index 6daf6088ac88..477711435b24 100644
--- a/drivers/acpi/bay.c
+++ b/drivers/acpi/bay.c
@@ -46,6 +46,12 @@ MODULE_LICENSE("GPL");
46 printk(KERN_DEBUG PREFIX "%s: %s\n", prefix, s); } 46 printk(KERN_DEBUG PREFIX "%s: %s\n", prefix, s); }
47static void bay_notify(acpi_handle handle, u32 event, void *data); 47static void bay_notify(acpi_handle handle, u32 event, void *data);
48 48
49static const struct acpi_device_id bay_device_ids[] = {
50 {"LNXIOBAY", 0},
51 {"", 0},
52};
53MODULE_DEVICE_TABLE(acpi, bay_device_ids);
54
49struct bay { 55struct bay {
50 acpi_handle handle; 56 acpi_handle handle;
51 char *name; 57 char *name;
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c
index 3ec110ce00c8..3ade01680989 100644
--- a/drivers/acpi/blacklist.c
+++ b/drivers/acpi/blacklist.c
@@ -3,6 +3,7 @@
3 * 3 *
4 * Check to see if the given machine has a known bad ACPI BIOS 4 * Check to see if the given machine has a known bad ACPI BIOS
5 * or if the BIOS is too old. 5 * or if the BIOS is too old.
6 * Check given machine against acpi_osi_dmi_table[].
6 * 7 *
7 * Copyright (C) 2004 Len Brown <len.brown@intel.com> 8 * Copyright (C) 2004 Len Brown <len.brown@intel.com>
8 * Copyright (C) 2002 Andy Grover <andrew.grover@intel.com> 9 * Copyright (C) 2002 Andy Grover <andrew.grover@intel.com>
@@ -50,6 +51,8 @@ struct acpi_blacklist_item {
50 u32 is_critical_error; 51 u32 is_critical_error;
51}; 52};
52 53
54static struct dmi_system_id acpi_osi_dmi_table[] __initdata;
55
53/* 56/*
54 * POLICY: If *anything* doesn't work, put it on the blacklist. 57 * POLICY: If *anything* doesn't work, put it on the blacklist.
55 * If they are critical errors, mark it critical, and abort driver load. 58 * If they are critical errors, mark it critical, and abort driver load.
@@ -67,8 +70,6 @@ static struct acpi_blacklist_item acpi_blacklist[] __initdata = {
67 /* IBM 600E - _ADR should return 7, but it returns 1 */ 70 /* IBM 600E - _ADR should return 7, but it returns 1 */
68 {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal, 71 {"IBM ", "TP600E ", 0x00000105, ACPI_SIG_DSDT, less_than_or_equal,
69 "Incorrect _ADR", 1}, 72 "Incorrect _ADR", 1},
70 {"ASUS\0\0", "P2B-S ", 0, ACPI_SIG_DSDT, all_versions,
71 "Bogus PCI routing", 1},
72 73
73 {""} 74 {""}
74}; 75};
@@ -165,5 +166,383 @@ int __init acpi_blacklisted(void)
165 166
166 blacklisted += blacklist_by_year(); 167 blacklisted += blacklist_by_year();
167 168
169 dmi_check_system(acpi_osi_dmi_table);
170
168 return blacklisted; 171 return blacklisted;
169} 172}
173#ifdef CONFIG_DMI
174static int __init dmi_enable_osi_linux(const struct dmi_system_id *d)
175{
176 acpi_dmi_osi_linux(1, d); /* enable */
177 return 0;
178}
179static int __init dmi_disable_osi_linux(const struct dmi_system_id *d)
180{
181 acpi_dmi_osi_linux(0, d); /* disable */
182 return 0;
183}
184static int __init dmi_unknown_osi_linux(const struct dmi_system_id *d)
185{
186 acpi_dmi_osi_linux(-1, d); /* unknown */
187 return 0;
188}
189
190/*
191 * Most BIOS that invoke OSI(Linux) do nothing with it.
192 * But some cause Linux to break.
193 * Only a couple use it to make Linux run better.
194 *
195 * Thus, Linux should continue to disable OSI(Linux) by default,
196 * should continue to discourage BIOS writers from using it, and
197 * should whitelist the few existing systems that require it.
198 *
199 * If it appears clear a vendor isn't using OSI(Linux)
200 * for anything constructive, blacklist them by name to disable
201 * unnecessary dmesg warnings on all of their products.
202 */
203
204static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
205 /*
206 * Disable OSI(Linux) warnings on all "Acer, inc."
207 *
208 * _OSI(Linux) disables the latest Windows BIOS code:
209 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5050"),
210 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5580"),
211 * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 3010"),
212 * _OSI(Linux) effect unknown:
213 * DMI_MATCH(DMI_PRODUCT_NAME, "Ferrari 5000"),
214 */
215 {
216 .callback = dmi_disable_osi_linux,
217 .ident = "Acer, inc.",
218 .matches = {
219 DMI_MATCH(DMI_SYS_VENDOR, "Acer, inc."),
220 },
221 },
222 /*
223 * Disable OSI(Linux) warnings on all "Acer"
224 *
225 * _OSI(Linux) effect unknown:
226 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5100"),
227 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"),
228 * DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 7720Z"),
229 * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 5520"),
230 * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 6460"),
231 * DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate 7510"),
232 * DMI_MATCH(DMI_PRODUCT_NAME, "Extensa 5220"),
233 */
234 {
235 .callback = dmi_unknown_osi_linux,
236 .ident = "Acer",
237 .matches = {
238 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
239 },
240 },
241 /*
242 * Disable OSI(Linux) warnings on all "Apple Computer, Inc."
243 *
244 * _OSI(Linux) confirmed to be a NOP:
245 * DMI_MATCH(DMI_PRODUCT_NAME, "MacBook1,1"),
246 * DMI_MATCH(DMI_PRODUCT_NAME, "MacBook2,1"),
247 * DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro2,2"),
248 * _OSI(Linux) effect unknown:
249 * DMI_MATCH(DMI_PRODUCT_NAME, "MacPro2,1"),
250 * DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro1,1"),
251 * DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro3,1"),
252 */
253 {
254 .callback = dmi_disable_osi_linux,
255 .ident = "Apple",
256 .matches = {
257 DMI_MATCH(DMI_SYS_VENDOR, "Apple Computer, Inc."),
258 },
259 },
260 /*
261 * Disable OSI(Linux) warnings on all "BenQ"
262 *
263 * _OSI(Linux) confirmed to be a NOP:
264 * DMI_MATCH(DMI_PRODUCT_NAME, "Joybook S31"),
265 */
266 {
267 .callback = dmi_disable_osi_linux,
268 .ident = "BenQ",
269 .matches = {
270 DMI_MATCH(DMI_SYS_VENDOR, "BenQ"),
271 },
272 },
273 /*
274 * Disable OSI(Linux) warnings on all "Clevo Co."
275 *
276 * _OSI(Linux) confirmed to be a NOP:
277 * DMI_MATCH(DMI_PRODUCT_NAME, "M570RU"),
278 */
279 {
280 .callback = dmi_disable_osi_linux,
281 .ident = "Clevo",
282 .matches = {
283 DMI_MATCH(DMI_SYS_VENDOR, "Clevo Co."),
284 },
285 },
286 /*
287 * Disable OSI(Linux) warnings on all "COMPAL"
288 *
289 * _OSI(Linux) confirmed to be a NOP:
290 * DMI_MATCH(DMI_BOARD_NAME, "HEL8X"),
291 * _OSI(Linux) unknown effect:
292 * DMI_MATCH(DMI_BOARD_NAME, "IFL91"),
293 */
294 {
295 .callback = dmi_unknown_osi_linux,
296 .ident = "Compal",
297 .matches = {
298 DMI_MATCH(DMI_BIOS_VENDOR, "COMPAL"),
299 },
300 },
301 { /* OSI(Linux) touches USB, breaks suspend to disk */
302 .callback = dmi_disable_osi_linux,
303 .ident = "Dell Dimension 5150",
304 .matches = {
305 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
306 DMI_MATCH(DMI_PRODUCT_NAME, "Dell DM051"),
307 },
308 },
309 { /* OSI(Linux) is a NOP */
310 .callback = dmi_disable_osi_linux,
311 .ident = "Dell",
312 .matches = {
313 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
314 DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 1501"),
315 },
316 },
317 { /* OSI(Linux) effect unknown */
318 .callback = dmi_unknown_osi_linux,
319 .ident = "Dell",
320 .matches = {
321 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
322 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude D830"),
323 },
324 },
325 { /* OSI(Linux) effect unknown */
326 .callback = dmi_unknown_osi_linux,
327 .ident = "Dell",
328 .matches = {
329 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
330 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex GX620"),
331 },
332 },
333 { /* OSI(Linux) effect unknown */
334 .callback = dmi_unknown_osi_linux,
335 .ident = "Dell",
336 .matches = {
337 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
338 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1900"),
339 },
340 },
341 { /* OSI(Linux) touches USB */
342 .callback = dmi_disable_osi_linux,
343 .ident = "Dell",
344 .matches = {
345 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
346 DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation 390"),
347 },
348 },
349 { /* OSI(Linux) is a NOP */
350 .callback = dmi_disable_osi_linux,
351 .ident = "Dell Vostro 1000",
352 .matches = {
353 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
354 DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1000"),
355 },
356 },
357 { /* OSI(Linux) effect unknown */
358 .callback = dmi_unknown_osi_linux,
359 .ident = "Dell",
360 .matches = {
361 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
362 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge SC440"),
363 },
364 },
365 { /* OSI(Linux) effect unknown */
366 .callback = dmi_unknown_osi_linux,
367 .ident = "Dialogue Flybook V5",
368 .matches = {
369 DMI_MATCH(DMI_SYS_VENDOR, "Dialogue Technology Corporation"),
370 DMI_MATCH(DMI_PRODUCT_NAME, "Flybook V5"),
371 },
372 },
373 /*
374 * Disable OSI(Linux) warnings on all "FUJITSU SIEMENS"
375 *
376 * _OSI(Linux) disables latest Windows BIOS code:
377 * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 2510"),
378 * _OSI(Linux) confirmed to be a NOP:
379 * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 1536"),
380 * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pi 1556"),
381 * DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 1546"),
382 * _OSI(Linux) unknown effect:
383 * DMI_MATCH(DMI_PRODUCT_NAME, "Amilo M1425"),
384 * DMI_MATCH(DMI_PRODUCT_NAME, "Amilo Si 1520"),
385 * DMI_MATCH(DMI_PRODUCT_NAME, "ESPRIMO Mobile V5505"),
386 */
387 {
388 .callback = dmi_disable_osi_linux,
389 .ident = "Fujitsu Siemens",
390 .matches = {
391 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
392 },
393 },
394 /*
395 * Disable OSI(Linux) warnings on all "Hewlett-Packard"
396 *
397 * _OSI(Linux) confirmed to be a NOP:
398 * .ident = "HP Pavilion tx 1000"
399 * DMI_MATCH(DMI_BOARD_NAME, "30BF"),
400 * .ident = "HP Pavilion dv2000"
401 * DMI_MATCH(DMI_BOARD_NAME, "30B5"),
402 * .ident = "HP Pavilion dv5000",
403 * DMI_MATCH(DMI_BOARD_NAME, "30A7"),
404 * .ident = "HP Pavilion dv6300 30BC",
405 * DMI_MATCH(DMI_BOARD_NAME, "30BC"),
406 * .ident = "HP Pavilion dv6000",
407 * DMI_MATCH(DMI_BOARD_NAME, "30B7"),
408 * DMI_MATCH(DMI_BOARD_NAME, "30B8"),
409 * .ident = "HP Pavilion dv9000",
410 * DMI_MATCH(DMI_BOARD_NAME, "30B9"),
411 * .ident = "HP Pavilion dv9500",
412 * DMI_MATCH(DMI_BOARD_NAME, "30CB"),
413 * .ident = "HP/Compaq Presario C500",
414 * DMI_MATCH(DMI_BOARD_NAME, "30C6"),
415 * .ident = "HP/Compaq Presario F500",
416 * DMI_MATCH(DMI_BOARD_NAME, "30D3"),
417 * _OSI(Linux) unknown effect:
418 * .ident = "HP Pavilion dv6500",
419 * DMI_MATCH(DMI_BOARD_NAME, "30D0"),
420 */
421 {
422 .callback = dmi_disable_osi_linux,
423 .ident = "Hewlett-Packard",
424 .matches = {
425 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
426 },
427 },
428 /*
429 * Lenovo has a mix of systems OSI(Linux) situations
430 * and thus we can not wildcard the vendor.
431 *
432 * _OSI(Linux) helps sound
433 * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad R61"),
434 * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T61"),
435 * _OSI(Linux) is a NOP:
436 * DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"),
437 */
438 {
439 .callback = dmi_enable_osi_linux,
440 .ident = "Lenovo ThinkPad R61",
441 .matches = {
442 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
443 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad R61"),
444 },
445 },
446 {
447 .callback = dmi_enable_osi_linux,
448 .ident = "Lenovo ThinkPad T61",
449 .matches = {
450 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
451 DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T61"),
452 },
453 },
454 {
455 .callback = dmi_unknown_osi_linux,
456 .ident = "Lenovo 3000 V100",
457 .matches = {
458 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
459 DMI_MATCH(DMI_PRODUCT_VERSION, "LENOVO3000 V100"),
460 },
461 },
462 {
463 .callback = dmi_disable_osi_linux,
464 .ident = "Lenovo 3000 N100",
465 .matches = {
466 DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
467 DMI_MATCH(DMI_PRODUCT_VERSION, "3000 N100"),
468 },
469 },
470 /*
471 * Disable OSI(Linux) warnings on all "LG Electronics"
472 *
473 * _OSI(Linux) confirmed to be a NOP:
474 * DMI_MATCH(DMI_PRODUCT_NAME, "P1-J150B"),
475 */
476 {
477 .callback = dmi_disable_osi_linux,
478 .ident = "LG",
479 .matches = {
480 DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"),
481 },
482 },
483 /* NEC - OSI(Linux) effect unknown */
484 {
485 .callback = dmi_unknown_osi_linux,
486 .ident = "NEC VERSA M360",
487 .matches = {
488 DMI_MATCH(DMI_SYS_VENDOR, "NEC Computers SAS"),
489 DMI_MATCH(DMI_PRODUCT_NAME, "NEC VERSA M360"),
490 },
491 },
492 /*
493 * Disable OSI(Linux) warnings on all "Samsung Electronics"
494 *
495 * OSI(Linux) disables PNP0C32 and other BIOS code for Windows:
496 * DMI_MATCH(DMI_PRODUCT_NAME, "R40P/R41P"),
497 * DMI_MATCH(DMI_PRODUCT_NAME, "R59P/R60P/R61P"),
498 */
499 {
500 .callback = dmi_disable_osi_linux,
501 .ident = "Samsung",
502 .matches = {
503 DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."),
504 },
505 },
506 /*
507 * Disable OSI(Linux) warnings on all "Sony Corporation"
508 *
509 * _OSI(Linux) is a NOP:
510 * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SZ650N"),
511 * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-SZ38GP_C"),
512 * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-TZ21MN_N"),
513 * _OSI(Linux) unknown effect:
514 * DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ11M"),
515 */
516 {
517 .callback = dmi_unknown_osi_linux,
518 .ident = "Sony",
519 .matches = {
520 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
521 },
522 },
523 /*
524 * Disable OSI(Linux) warnings on all "TOSHIBA"
525 *
526 * _OSI(Linux) breaks sound (bugzilla 7787):
527 * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P100"),
528 * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P105"),
529 * _OSI(Linux) is a NOP:
530 * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A100"),
531 * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A210"),
532 * _OSI(Linux) unknown effect:
533 * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A135"),
534 * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite A200"),
535 * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite P205"),
536 * DMI_MATCH(DMI_PRODUCT_NAME, "Satellite U305"),
537 */
538 {
539 .callback = dmi_disable_osi_linux,
540 .ident = "Toshiba",
541 .matches = {
542 DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
543 },
544 },
545 {}
546};
547
548#endif /* CONFIG_DMI */
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 49d432d0a12c..1b4cf984b081 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -29,7 +29,6 @@
29#include <linux/list.h> 29#include <linux/list.h>
30#include <linux/sched.h> 30#include <linux/sched.h>
31#include <linux/pm.h> 31#include <linux/pm.h>
32#include <linux/pm_legacy.h>
33#include <linux/device.h> 32#include <linux/device.h>
34#include <linux/proc_fs.h> 33#include <linux/proc_fs.h>
35#ifdef CONFIG_X86 34#ifdef CONFIG_X86
@@ -201,7 +200,7 @@ int acpi_bus_set_power(acpi_handle handle, int state)
201 * Get device's current power state 200 * Get device's current power state
202 */ 201 */
203 acpi_bus_get_power(device->handle, &device->power.state); 202 acpi_bus_get_power(device->handle, &device->power.state);
204 if (state == device->power.state) { 203 if ((state == device->power.state) && !device->flags.force_power_state) {
205 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", 204 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
206 state)); 205 state));
207 return 0; 206 return 0;
@@ -744,7 +743,7 @@ static int __init acpi_bus_init(void)
744 return -ENODEV; 743 return -ENODEV;
745} 744}
746 745
747decl_subsys(acpi, NULL, NULL); 746struct kobject *acpi_kobj;
748 747
749static int __init acpi_init(void) 748static int __init acpi_init(void)
750{ 749{
@@ -756,24 +755,23 @@ static int __init acpi_init(void)
756 return -ENODEV; 755 return -ENODEV;
757 } 756 }
758 757
759 result = firmware_register(&acpi_subsys); 758 acpi_kobj = kobject_create_and_add("acpi", firmware_kobj);
760 if (result < 0) 759 if (!acpi_kobj) {
761 printk(KERN_WARNING "%s: firmware_register error: %d\n", 760 printk(KERN_WARNING "%s: kset create error\n", __FUNCTION__);
762 __FUNCTION__, result); 761 acpi_kobj = NULL;
762 }
763 763
764 result = acpi_bus_init(); 764 result = acpi_bus_init();
765 765
766 if (!result) { 766 if (!result) {
767#ifdef CONFIG_PM_LEGACY 767 if (!(pm_flags & PM_APM))
768 if (!PM_IS_ACTIVE()) 768 pm_flags |= PM_ACPI;
769 pm_active = 1;
770 else { 769 else {
771 printk(KERN_INFO PREFIX 770 printk(KERN_INFO PREFIX
772 "APM is already active, exiting\n"); 771 "APM is already active, exiting\n");
773 disable_acpi(); 772 disable_acpi();
774 result = -ENODEV; 773 result = -ENODEV;
775 } 774 }
776#endif
777 } else 775 } else
778 disable_acpi(); 776 disable_acpi();
779 777
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c
index bf513e07b773..6df564f4ca6e 100644
--- a/drivers/acpi/debug.c
+++ b/drivers/acpi/debug.c
@@ -130,6 +130,63 @@ static int param_get_debug_level(char *buffer, struct kernel_param *kp) {
130module_param_call(debug_layer, param_set_uint, param_get_debug_layer, &acpi_dbg_layer, 0644); 130module_param_call(debug_layer, param_set_uint, param_get_debug_layer, &acpi_dbg_layer, 0644);
131module_param_call(debug_level, param_set_uint, param_get_debug_level, &acpi_dbg_level, 0644); 131module_param_call(debug_level, param_set_uint, param_get_debug_level, &acpi_dbg_level, 0644);
132 132
133static char trace_method_name[6];
134module_param_string(trace_method_name, trace_method_name, 6, 0644);
135static unsigned int trace_debug_layer;
136module_param(trace_debug_layer, uint, 0644);
137static unsigned int trace_debug_level;
138module_param(trace_debug_level, uint, 0644);
139
140static int param_set_trace_state(const char *val, struct kernel_param *kp)
141{
142 int result = 0;
143
144 if (!strncmp(val, "enable", strlen("enable") - 1)) {
145 result = acpi_debug_trace(trace_method_name, trace_debug_level,
146 trace_debug_layer, 0);
147 if (result)
148 result = -EBUSY;
149 goto exit;
150 }
151
152 if (!strncmp(val, "disable", strlen("disable") - 1)) {
153 int name = 0;
154 result = acpi_debug_trace((char *)&name, trace_debug_level,
155 trace_debug_layer, 0);
156 if (result)
157 result = -EBUSY;
158 goto exit;
159 }
160
161 if (!strncmp(val, "1", 1)) {
162 result = acpi_debug_trace(trace_method_name, trace_debug_level,
163 trace_debug_layer, 1);
164 if (result)
165 result = -EBUSY;
166 goto exit;
167 }
168
169 result = -EINVAL;
170exit:
171 return result;
172}
173
174static int param_get_trace_state(char *buffer, struct kernel_param *kp)
175{
176 if (!acpi_gbl_trace_method_name)
177 return sprintf(buffer, "disable");
178 else {
179 if (acpi_gbl_trace_flags & 1)
180 return sprintf(buffer, "1");
181 else
182 return sprintf(buffer, "enable");
183 }
184 return 0;
185}
186
187module_param_call(trace_state, param_set_trace_state, param_get_trace_state,
188 NULL, 0644);
189
133/* -------------------------------------------------------------------------- 190/* --------------------------------------------------------------------------
134 FS Interface (/proc) 191 FS Interface (/proc)
135 -------------------------------------------------------------------------- */ 192 -------------------------------------------------------------------------- */
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 1dabdf4c07b3..b3dec2101e2e 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -51,6 +51,12 @@ static struct atomic_notifier_head dock_notifier_list;
51static struct platform_device *dock_device; 51static struct platform_device *dock_device;
52static char dock_device_name[] = "dock"; 52static char dock_device_name[] = "dock";
53 53
54static const struct acpi_device_id dock_device_ids[] = {
55 {"LNXDOCK", 0},
56 {"", 0},
57};
58MODULE_DEVICE_TABLE(acpi, dock_device_ids);
59
54struct dock_station { 60struct dock_station {
55 acpi_handle handle; 61 acpi_handle handle;
56 unsigned long last_dock_time; 62 unsigned long last_dock_time;
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index d411017f8c06..7222a18a0319 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -26,6 +26,9 @@
26 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 26 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
27 */ 27 */
28 28
29/* Uncomment next line to get verbose print outs*/
30/* #define DEBUG */
31
29#include <linux/kernel.h> 32#include <linux/kernel.h>
30#include <linux/module.h> 33#include <linux/module.h>
31#include <linux/init.h> 34#include <linux/init.h>
@@ -47,9 +50,6 @@
47#undef PREFIX 50#undef PREFIX
48#define PREFIX "ACPI: EC: " 51#define PREFIX "ACPI: EC: "
49 52
50/* Uncomment next line to get verbose print outs*/
51/* #define DEBUG */
52
53/* EC status register */ 53/* EC status register */
54#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ 54#define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */
55#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ 55#define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */
@@ -82,6 +82,7 @@ enum {
82 EC_FLAGS_ADDRESS, /* Address is being written */ 82 EC_FLAGS_ADDRESS, /* Address is being written */
83 EC_FLAGS_NO_WDATA_GPE, /* Don't expect WDATA GPE event */ 83 EC_FLAGS_NO_WDATA_GPE, /* Don't expect WDATA GPE event */
84 EC_FLAGS_WDATA, /* Data is being written */ 84 EC_FLAGS_WDATA, /* Data is being written */
85 EC_FLAGS_NO_OBF1_GPE, /* Don't expect GPE before read */
85}; 86};
86 87
87static int acpi_ec_remove(struct acpi_device *device, int type); 88static int acpi_ec_remove(struct acpi_device *device, int type);
@@ -138,26 +139,26 @@ static struct acpi_ec {
138static inline u8 acpi_ec_read_status(struct acpi_ec *ec) 139static inline u8 acpi_ec_read_status(struct acpi_ec *ec)
139{ 140{
140 u8 x = inb(ec->command_addr); 141 u8 x = inb(ec->command_addr);
141 pr_debug(PREFIX "---> status = 0x%2x\n", x); 142 pr_debug(PREFIX "---> status = 0x%2.2x\n", x);
142 return x; 143 return x;
143} 144}
144 145
145static inline u8 acpi_ec_read_data(struct acpi_ec *ec) 146static inline u8 acpi_ec_read_data(struct acpi_ec *ec)
146{ 147{
147 u8 x = inb(ec->data_addr); 148 u8 x = inb(ec->data_addr);
148 pr_debug(PREFIX "---> data = 0x%2x\n", x); 149 pr_debug(PREFIX "---> data = 0x%2.2x\n", x);
149 return inb(ec->data_addr); 150 return inb(ec->data_addr);
150} 151}
151 152
152static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) 153static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command)
153{ 154{
154 pr_debug(PREFIX "<--- command = 0x%2x\n", command); 155 pr_debug(PREFIX "<--- command = 0x%2.2x\n", command);
155 outb(command, ec->command_addr); 156 outb(command, ec->command_addr);
156} 157}
157 158
158static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) 159static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)
159{ 160{
160 pr_debug(PREFIX "<--- data = 0x%2x\n", data); 161 pr_debug(PREFIX "<--- data = 0x%2.2x\n", data);
161 outb(data, ec->data_addr); 162 outb(data, ec->data_addr);
162} 163}
163 164
@@ -179,6 +180,10 @@ static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event)
179static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) 180static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
180{ 181{
181 int ret = 0; 182 int ret = 0;
183
184 if (unlikely(event == ACPI_EC_EVENT_OBF_1 &&
185 test_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags)))
186 force_poll = 1;
182 if (unlikely(test_bit(EC_FLAGS_ADDRESS, &ec->flags) && 187 if (unlikely(test_bit(EC_FLAGS_ADDRESS, &ec->flags) &&
183 test_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags))) 188 test_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags)))
184 force_poll = 1; 189 force_poll = 1;
@@ -192,7 +197,12 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
192 goto end; 197 goto end;
193 clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); 198 clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
194 if (acpi_ec_check_status(ec, event)) { 199 if (acpi_ec_check_status(ec, event)) {
195 if (test_bit(EC_FLAGS_ADDRESS, &ec->flags)) { 200 if (event == ACPI_EC_EVENT_OBF_1) {
201 /* miss OBF_1 GPE, don't expect it */
202 pr_info(PREFIX "missing OBF confirmation, "
203 "don't expect it any longer.\n");
204 set_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags);
205 } else if (test_bit(EC_FLAGS_ADDRESS, &ec->flags)) {
196 /* miss address GPE, don't expect it anymore */ 206 /* miss address GPE, don't expect it anymore */
197 pr_info(PREFIX "missing address confirmation, " 207 pr_info(PREFIX "missing address confirmation, "
198 "don't expect it any longer.\n"); 208 "don't expect it any longer.\n");
@@ -563,7 +573,7 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
563 void *handler_context, void *region_context) 573 void *handler_context, void *region_context)
564{ 574{
565 struct acpi_ec *ec = handler_context; 575 struct acpi_ec *ec = handler_context;
566 int result = 0, i = 0; 576 int result = 0, i;
567 u8 temp = 0; 577 u8 temp = 0;
568 578
569 if ((address > 0xFF) || !value || !handler_context) 579 if ((address > 0xFF) || !value || !handler_context)
@@ -575,7 +585,18 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
575 if (bits != 8 && acpi_strict) 585 if (bits != 8 && acpi_strict)
576 return AE_BAD_PARAMETER; 586 return AE_BAD_PARAMETER;
577 587
578 while (bits - i > 0) { 588 acpi_ec_burst_enable(ec);
589
590 if (function == ACPI_READ) {
591 result = acpi_ec_read(ec, address, &temp);
592 *value = temp;
593 } else {
594 temp = 0xff & (*value);
595 result = acpi_ec_write(ec, address, temp);
596 }
597
598 for (i = 8; unlikely(bits - i > 0); i += 8) {
599 ++address;
579 if (function == ACPI_READ) { 600 if (function == ACPI_READ) {
580 result = acpi_ec_read(ec, address, &temp); 601 result = acpi_ec_read(ec, address, &temp);
581 (*value) |= ((acpi_integer)temp) << i; 602 (*value) |= ((acpi_integer)temp) << i;
@@ -583,10 +604,10 @@ acpi_ec_space_handler(u32 function, acpi_physical_address address,
583 temp = 0xff & ((*value) >> i); 604 temp = 0xff & ((*value) >> i);
584 result = acpi_ec_write(ec, address, temp); 605 result = acpi_ec_write(ec, address, temp);
585 } 606 }
586 i += 8;
587 ++address;
588 } 607 }
589 608
609 acpi_ec_burst_disable(ec);
610
590 switch (result) { 611 switch (result) {
591 case -EINVAL: 612 case -EINVAL:
592 return AE_BAD_PARAMETER; 613 return AE_BAD_PARAMETER;
@@ -892,6 +913,17 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
892 return 0; 913 return 0;
893} 914}
894 915
916int __init acpi_boot_ec_enable(void)
917{
918 if (!boot_ec || boot_ec->handlers_installed)
919 return 0;
920 if (!ec_install_handlers(boot_ec)) {
921 first_ec = boot_ec;
922 return 0;
923 }
924 return -EFAULT;
925}
926
895int __init acpi_ec_ecdt_probe(void) 927int __init acpi_ec_ecdt_probe(void)
896{ 928{
897 int ret; 929 int ret;
@@ -924,9 +956,10 @@ int __init acpi_ec_ecdt_probe(void)
924 goto error; 956 goto error;
925 /* We really need to limit this workaround, the only ASUS, 957 /* We really need to limit this workaround, the only ASUS,
926 * which needs it, has fake EC._INI method, so use it as flag. 958 * which needs it, has fake EC._INI method, so use it as flag.
959 * Keep boot_ec struct as it will be needed soon.
927 */ 960 */
928 if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &x))) 961 if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &x)))
929 goto error; 962 return -ENODEV;
930 } 963 }
931 964
932 ret = ec_install_handlers(boot_ec); 965 ret = ec_install_handlers(boot_ec);
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
index e22f4a973c0f..056b78844829 100644
--- a/drivers/acpi/events/evgpe.c
+++ b/drivers/acpi/events/evgpe.c
@@ -270,18 +270,18 @@ acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info)
270 case ACPI_GPE_TYPE_WAKE_RUN: 270 case ACPI_GPE_TYPE_WAKE_RUN:
271 ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED); 271 ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_WAKE_ENABLED);
272 272
273 /*lint -fallthrough */ 273 /* fallthrough */
274 274
275 case ACPI_GPE_TYPE_RUNTIME: 275 case ACPI_GPE_TYPE_RUNTIME:
276 276
277 /* Disable the requested runtime GPE */ 277 /* Disable the requested runtime GPE */
278 278
279 ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_RUN_ENABLED); 279 ACPI_CLEAR_BIT(gpe_event_info->flags, ACPI_GPE_RUN_ENABLED);
280 status = acpi_hw_write_gpe_enable_reg(gpe_event_info); 280
281 break; 281 /* fallthrough */
282 282
283 default: 283 default:
284 return_ACPI_STATUS(AE_BAD_PARAMETER); 284 acpi_hw_write_gpe_enable_reg(gpe_event_info);
285 } 285 }
286 286
287 return_ACPI_STATUS(AE_OK); 287 return_ACPI_STATUS(AE_OK);
diff --git a/drivers/acpi/events/evregion.c b/drivers/acpi/events/evregion.c
index e99f0c435a47..58ad09725dd2 100644
--- a/drivers/acpi/events/evregion.c
+++ b/drivers/acpi/events/evregion.c
@@ -344,7 +344,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
344 * setup will potentially execute control methods 344 * setup will potentially execute control methods
345 * (e.g., _REG method for this region) 345 * (e.g., _REG method for this region)
346 */ 346 */
347 acpi_ex_relinquish_interpreter(); 347 acpi_ex_exit_interpreter();
348 348
349 status = region_setup(region_obj, ACPI_REGION_ACTIVATE, 349 status = region_setup(region_obj, ACPI_REGION_ACTIVATE,
350 handler_desc->address_space.context, 350 handler_desc->address_space.context,
@@ -352,7 +352,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
352 352
353 /* Re-enter the interpreter */ 353 /* Re-enter the interpreter */
354 354
355 acpi_ex_reacquire_interpreter(); 355 acpi_ex_enter_interpreter();
356 356
357 /* Check for failure of the Region Setup */ 357 /* Check for failure of the Region Setup */
358 358
@@ -405,7 +405,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
405 * exit the interpreter because the handler *might* block -- we don't 405 * exit the interpreter because the handler *might* block -- we don't
406 * know what it will do, so we can't hold the lock on the intepreter. 406 * know what it will do, so we can't hold the lock on the intepreter.
407 */ 407 */
408 acpi_ex_relinquish_interpreter(); 408 acpi_ex_exit_interpreter();
409 } 409 }
410 410
411 /* Call the handler */ 411 /* Call the handler */
@@ -426,7 +426,7 @@ acpi_ev_address_space_dispatch(union acpi_operand_object *region_obj,
426 * We just returned from a non-default handler, we must re-enter the 426 * We just returned from a non-default handler, we must re-enter the
427 * interpreter 427 * interpreter
428 */ 428 */
429 acpi_ex_reacquire_interpreter(); 429 acpi_ex_enter_interpreter();
430 } 430 }
431 431
432 return_ACPI_STATUS(status); 432 return_ACPI_STATUS(status);
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index a5a5532db268..a6e149d692cb 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -47,6 +47,8 @@ MODULE_LICENSE("GPL");
47 47
48static int acpi_fan_add(struct acpi_device *device); 48static int acpi_fan_add(struct acpi_device *device);
49static int acpi_fan_remove(struct acpi_device *device, int type); 49static int acpi_fan_remove(struct acpi_device *device, int type);
50static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state);
51static int acpi_fan_resume(struct acpi_device *device);
50 52
51static const struct acpi_device_id fan_device_ids[] = { 53static const struct acpi_device_id fan_device_ids[] = {
52 {"PNP0C0B", 0}, 54 {"PNP0C0B", 0},
@@ -61,6 +63,8 @@ static struct acpi_driver acpi_fan_driver = {
61 .ops = { 63 .ops = {
62 .add = acpi_fan_add, 64 .add = acpi_fan_add,
63 .remove = acpi_fan_remove, 65 .remove = acpi_fan_remove,
66 .suspend = acpi_fan_suspend,
67 .resume = acpi_fan_resume,
64 }, 68 },
65}; 69};
66 70
@@ -191,6 +195,10 @@ static int acpi_fan_add(struct acpi_device *device)
191 goto end; 195 goto end;
192 } 196 }
193 197
198 device->flags.force_power_state = 1;
199 acpi_bus_set_power(device->handle, state);
200 device->flags.force_power_state = 0;
201
194 result = acpi_fan_add_fs(device); 202 result = acpi_fan_add_fs(device);
195 if (result) 203 if (result)
196 goto end; 204 goto end;
@@ -216,6 +224,38 @@ static int acpi_fan_remove(struct acpi_device *device, int type)
216 return 0; 224 return 0;
217} 225}
218 226
227static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state)
228{
229 if (!device)
230 return -EINVAL;
231
232 acpi_bus_set_power(device->handle, ACPI_STATE_D0);
233
234 return AE_OK;
235}
236
237static int acpi_fan_resume(struct acpi_device *device)
238{
239 int result = 0;
240 int power_state = 0;
241
242 if (!device)
243 return -EINVAL;
244
245 result = acpi_bus_get_power(device->handle, &power_state);
246 if (result) {
247 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
248 "Error reading fan power state\n"));
249 return result;
250 }
251
252 device->flags.force_power_state = 1;
253 acpi_bus_set_power(device->handle, power_state);
254 device->flags.force_power_state = 0;
255
256 return result;
257}
258
219static int __init acpi_fan_init(void) 259static int __init acpi_fan_init(void)
220{ 260{
221 int result = 0; 261 int result = 0;
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
index 81b248429703..fd1c4ba63367 100644
--- a/drivers/acpi/hardware/hwsleep.c
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -192,18 +192,13 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
192 arg.type = ACPI_TYPE_INTEGER; 192 arg.type = ACPI_TYPE_INTEGER;
193 arg.integer.value = sleep_state; 193 arg.integer.value = sleep_state;
194 194
195 /* Run the _PTS and _GTS methods */ 195 /* Run the _PTS method */
196 196
197 status = acpi_evaluate_object(NULL, METHOD_NAME__PTS, &arg_list, NULL); 197 status = acpi_evaluate_object(NULL, METHOD_NAME__PTS, &arg_list, NULL);
198 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { 198 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
199 return_ACPI_STATUS(status); 199 return_ACPI_STATUS(status);
200 } 200 }
201 201
202 status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL);
203 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
204 return_ACPI_STATUS(status);
205 }
206
207 /* Setup the argument to _SST */ 202 /* Setup the argument to _SST */
208 203
209 switch (sleep_state) { 204 switch (sleep_state) {
@@ -234,10 +229,6 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
234 "While executing method _SST")); 229 "While executing method _SST"));
235 } 230 }
236 231
237 /* Disable/Clear all GPEs */
238
239 status = acpi_hw_disable_all_gpes();
240
241 return_ACPI_STATUS(status); 232 return_ACPI_STATUS(status);
242} 233}
243 234
@@ -262,6 +253,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
262 struct acpi_bit_register_info *sleep_type_reg_info; 253 struct acpi_bit_register_info *sleep_type_reg_info;
263 struct acpi_bit_register_info *sleep_enable_reg_info; 254 struct acpi_bit_register_info *sleep_enable_reg_info;
264 u32 in_value; 255 u32 in_value;
256 struct acpi_object_list arg_list;
257 union acpi_object arg;
265 acpi_status status; 258 acpi_status status;
266 259
267 ACPI_FUNCTION_TRACE(acpi_enter_sleep_state); 260 ACPI_FUNCTION_TRACE(acpi_enter_sleep_state);
@@ -307,6 +300,18 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
307 return_ACPI_STATUS(status); 300 return_ACPI_STATUS(status);
308 } 301 }
309 302
303 /* Execute the _GTS method */
304
305 arg_list.count = 1;
306 arg_list.pointer = &arg;
307 arg.type = ACPI_TYPE_INTEGER;
308 arg.integer.value = sleep_state;
309
310 status = acpi_evaluate_object(NULL, METHOD_NAME__GTS, &arg_list, NULL);
311 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
312 return_ACPI_STATUS(status);
313 }
314
310 /* Get current value of PM1A control */ 315 /* Get current value of PM1A control */
311 316
312 status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol); 317 status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, &PM1Acontrol);
@@ -473,17 +478,18 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios)
473 478
474/******************************************************************************* 479/*******************************************************************************
475 * 480 *
476 * FUNCTION: acpi_leave_sleep_state 481 * FUNCTION: acpi_leave_sleep_state_prep
477 * 482 *
478 * PARAMETERS: sleep_state - Which sleep state we just exited 483 * PARAMETERS: sleep_state - Which sleep state we are exiting
479 * 484 *
480 * RETURN: Status 485 * RETURN: Status
481 * 486 *
482 * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep 487 * DESCRIPTION: Perform the first state of OS-independent ACPI cleanup after a
483 * Called with interrupts ENABLED. 488 * sleep.
489 * Called with interrupts DISABLED.
484 * 490 *
485 ******************************************************************************/ 491 ******************************************************************************/
486acpi_status acpi_leave_sleep_state(u8 sleep_state) 492acpi_status acpi_leave_sleep_state_prep(u8 sleep_state)
487{ 493{
488 struct acpi_object_list arg_list; 494 struct acpi_object_list arg_list;
489 union acpi_object arg; 495 union acpi_object arg;
@@ -493,7 +499,7 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
493 u32 PM1Acontrol; 499 u32 PM1Acontrol;
494 u32 PM1Bcontrol; 500 u32 PM1Bcontrol;
495 501
496 ACPI_FUNCTION_TRACE(acpi_leave_sleep_state); 502 ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep);
497 503
498 /* 504 /*
499 * Set SLP_TYPE and SLP_EN to state S0. 505 * Set SLP_TYPE and SLP_EN to state S0.
@@ -540,6 +546,41 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
540 } 546 }
541 } 547 }
542 548
549 /* Execute the _BFS method */
550
551 arg_list.count = 1;
552 arg_list.pointer = &arg;
553 arg.type = ACPI_TYPE_INTEGER;
554 arg.integer.value = sleep_state;
555
556 status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL);
557 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
558 ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS"));
559 }
560
561 return_ACPI_STATUS(status);
562}
563
564/*******************************************************************************
565 *
566 * FUNCTION: acpi_leave_sleep_state
567 *
568 * PARAMETERS: sleep_state - Which sleep state we just exited
569 *
570 * RETURN: Status
571 *
572 * DESCRIPTION: Perform OS-independent ACPI cleanup after a sleep
573 * Called with interrupts ENABLED.
574 *
575 ******************************************************************************/
576acpi_status acpi_leave_sleep_state(u8 sleep_state)
577{
578 struct acpi_object_list arg_list;
579 union acpi_object arg;
580 acpi_status status;
581
582 ACPI_FUNCTION_TRACE(acpi_leave_sleep_state);
583
543 /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */ 584 /* Ensure enter_sleep_state_prep -> enter_sleep_state ordering */
544 585
545 acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID; 586 acpi_gbl_sleep_type_a = ACPI_SLEEP_TYPE_INVALID;
@@ -558,12 +599,6 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
558 ACPI_EXCEPTION((AE_INFO, status, "During Method _SST")); 599 ACPI_EXCEPTION((AE_INFO, status, "During Method _SST"));
559 } 600 }
560 601
561 arg.integer.value = sleep_state;
562 status = acpi_evaluate_object(NULL, METHOD_NAME__BFS, &arg_list, NULL);
563 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
564 ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS"));
565 }
566
567 /* 602 /*
568 * GPEs must be enabled before _WAK is called as GPEs 603 * GPEs must be enabled before _WAK is called as GPEs
569 * might get fired there 604 * might get fired there
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index e3a673a00845..e96f3d933f67 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -77,11 +77,55 @@ static struct workqueue_struct *kacpi_notify_wq;
77#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ 77#define OSI_STRING_LENGTH_MAX 64 /* arbitrary */
78static char osi_additional_string[OSI_STRING_LENGTH_MAX]; 78static char osi_additional_string[OSI_STRING_LENGTH_MAX];
79 79
80static int osi_linux; /* disable _OSI(Linux) by default */ 80/*
81 * "Ode to _OSI(Linux)"
82 *
83 * osi_linux -- Control response to BIOS _OSI(Linux) query.
84 *
85 * As Linux evolves, the features that it supports change.
86 * So an OSI string such as "Linux" is not specific enough
87 * to be useful across multiple versions of Linux. It
88 * doesn't identify any particular feature, interface,
89 * or even any particular version of Linux...
90 *
91 * Unfortunately, Linux-2.6.22 and earlier responded "yes"
92 * to a BIOS _OSI(Linux) query. When
93 * a reference mobile BIOS started using it, its use
94 * started to spread to many vendor platforms.
95 * As it is not supportable, we need to halt that spread.
96 *
97 * Today, most BIOS references to _OSI(Linux) are noise --
98 * they have no functional effect and are just dead code
99 * carried over from the reference BIOS.
100 *
101 * The next most common case is that _OSI(Linux) harms Linux,
102 * usually by causing the BIOS to follow paths that are
103 * not tested during Windows validation.
104 *
105 * Finally, there is a short list of platforms
106 * where OSI(Linux) benefits Linux.
107 *
108 * In Linux-2.6.23, OSI(Linux) is first disabled by default.
109 * DMI is used to disable the dmesg warning about OSI(Linux)
110 * on platforms where it is known to have no effect.
111 * But a dmesg warning remains for systems where
112 * we do not know if OSI(Linux) is good or bad for the system.
113 * DMI is also used to enable OSI(Linux) for the machines
114 * that are known to need it.
115 *
116 * BIOS writers should NOT query _OSI(Linux) on future systems.
117 * It will be ignored by default, and to get Linux to
118 * not ignore it will require a kernel source update to
119 * add a DMI entry, or a boot-time "acpi_osi=Linux" invocation.
120 */
121#define OSI_LINUX_ENABLE 0
81 122
82#ifdef CONFIG_DMI 123struct osi_linux {
83static struct __initdata dmi_system_id acpi_osl_dmi_table[]; 124 unsigned int enable:1;
84#endif 125 unsigned int dmi:1;
126 unsigned int cmdline:1;
127 unsigned int known:1;
128} osi_linux = { OSI_LINUX_ENABLE, 0, 0, 0};
85 129
86static void __init acpi_request_region (struct acpi_generic_address *addr, 130static void __init acpi_request_region (struct acpi_generic_address *addr,
87 unsigned int length, char *desc) 131 unsigned int length, char *desc)
@@ -133,7 +177,6 @@ device_initcall(acpi_reserve_resources);
133 177
134acpi_status __init acpi_os_initialize(void) 178acpi_status __init acpi_os_initialize(void)
135{ 179{
136 dmi_check_system(acpi_osl_dmi_table);
137 return AE_OK; 180 return AE_OK;
138} 181}
139 182
@@ -207,8 +250,12 @@ acpi_physical_address __init acpi_os_get_root_pointer(void)
207 "System description tables not found\n"); 250 "System description tables not found\n");
208 return 0; 251 return 0;
209 } 252 }
210 } else 253 } else {
211 return acpi_find_rsdp(); 254 acpi_physical_address pa = 0;
255
256 acpi_find_root_pointer(&pa);
257 return pa;
258 }
212} 259}
213 260
214void __iomem *acpi_os_map_memory(acpi_physical_address phys, acpi_size size) 261void __iomem *acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
@@ -964,13 +1011,37 @@ static int __init acpi_os_name_setup(char *str)
964 1011
965__setup("acpi_os_name=", acpi_os_name_setup); 1012__setup("acpi_os_name=", acpi_os_name_setup);
966 1013
967static void enable_osi_linux(int enable) { 1014static void __init set_osi_linux(unsigned int enable)
1015{
1016 if (osi_linux.enable != enable) {
1017 osi_linux.enable = enable;
1018 printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n",
1019 enable ? "Add": "Delet");
1020 }
1021 return;
1022}
1023
1024static void __init acpi_cmdline_osi_linux(unsigned int enable)
1025{
1026 osi_linux.cmdline = 1; /* cmdline set the default */
1027 set_osi_linux(enable);
1028
1029 return;
1030}
1031
1032void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d)
1033{
1034 osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */
1035
1036 printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident);
1037
1038 if (enable == -1)
1039 return;
1040
1041 osi_linux.known = 1; /* DMI knows which OSI(Linux) default needed */
968 1042
969 if (osi_linux != enable) 1043 set_osi_linux(enable);
970 printk(KERN_INFO PREFIX "%sabled _OSI(Linux)\n",
971 enable ? "En": "Dis");
972 1044
973 osi_linux = enable;
974 return; 1045 return;
975} 1046}
976 1047
@@ -987,12 +1058,12 @@ static int __init acpi_osi_setup(char *str)
987 printk(KERN_INFO PREFIX "_OSI method disabled\n"); 1058 printk(KERN_INFO PREFIX "_OSI method disabled\n");
988 acpi_gbl_create_osi_method = FALSE; 1059 acpi_gbl_create_osi_method = FALSE;
989 } else if (!strcmp("!Linux", str)) { 1060 } else if (!strcmp("!Linux", str)) {
990 enable_osi_linux(0); 1061 acpi_cmdline_osi_linux(0); /* !enable */
991 } else if (*str == '!') { 1062 } else if (*str == '!') {
992 if (acpi_osi_invalidate(++str) == AE_OK) 1063 if (acpi_osi_invalidate(++str) == AE_OK)
993 printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); 1064 printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str);
994 } else if (!strcmp("Linux", str)) { 1065 } else if (!strcmp("Linux", str)) {
995 enable_osi_linux(1); 1066 acpi_cmdline_osi_linux(1); /* enable */
996 } else if (*osi_additional_string == '\0') { 1067 } else if (*osi_additional_string == '\0') {
997 strncpy(osi_additional_string, str, OSI_STRING_LENGTH_MAX); 1068 strncpy(osi_additional_string, str, OSI_STRING_LENGTH_MAX);
998 printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); 1069 printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str);
@@ -1141,6 +1212,34 @@ acpi_status acpi_os_release_object(acpi_cache_t * cache, void *object)
1141 return (AE_OK); 1212 return (AE_OK);
1142} 1213}
1143 1214
1215/**
1216 * acpi_dmi_dump - dump DMI slots needed for blacklist entry
1217 *
1218 * Returns 0 on success
1219 */
1220int acpi_dmi_dump(void)
1221{
1222
1223 if (!dmi_available)
1224 return -1;
1225
1226 printk(KERN_NOTICE PREFIX "DMI System Vendor: %s\n",
1227 dmi_get_slot(DMI_SYS_VENDOR));
1228 printk(KERN_NOTICE PREFIX "DMI Product Name: %s\n",
1229 dmi_get_slot(DMI_PRODUCT_NAME));
1230 printk(KERN_NOTICE PREFIX "DMI Product Version: %s\n",
1231 dmi_get_slot(DMI_PRODUCT_VERSION));
1232 printk(KERN_NOTICE PREFIX "DMI Board Name: %s\n",
1233 dmi_get_slot(DMI_BOARD_NAME));
1234 printk(KERN_NOTICE PREFIX "DMI BIOS Vendor: %s\n",
1235 dmi_get_slot(DMI_BIOS_VENDOR));
1236 printk(KERN_NOTICE PREFIX "DMI BIOS Date: %s\n",
1237 dmi_get_slot(DMI_BIOS_DATE));
1238
1239 return 0;
1240}
1241
1242
1144/****************************************************************************** 1243/******************************************************************************
1145 * 1244 *
1146 * FUNCTION: acpi_os_validate_interface 1245 * FUNCTION: acpi_os_validate_interface
@@ -1160,13 +1259,29 @@ acpi_os_validate_interface (char *interface)
1160 if (!strncmp(osi_additional_string, interface, OSI_STRING_LENGTH_MAX)) 1259 if (!strncmp(osi_additional_string, interface, OSI_STRING_LENGTH_MAX))
1161 return AE_OK; 1260 return AE_OK;
1162 if (!strcmp("Linux", interface)) { 1261 if (!strcmp("Linux", interface)) {
1163 printk(KERN_WARNING PREFIX 1262
1164 "System BIOS is requesting _OSI(Linux)\n"); 1263 printk(KERN_NOTICE PREFIX
1165 printk(KERN_WARNING PREFIX 1264 "BIOS _OSI(Linux) query %s%s\n",
1166 "If \"acpi_osi=Linux\" works better,\n" 1265 osi_linux.enable ? "honored" : "ignored",
1167 "Please send dmidecode " 1266 osi_linux.cmdline ? " via cmdline" :
1168 "to linux-acpi@vger.kernel.org\n"); 1267 osi_linux.dmi ? " via DMI" : "");
1169 if(osi_linux) 1268
1269 if (!osi_linux.dmi) {
1270 if (acpi_dmi_dump())
1271 printk(KERN_NOTICE PREFIX
1272 "[please extract dmidecode output]\n");
1273 printk(KERN_NOTICE PREFIX
1274 "Please send DMI info above to "
1275 "linux-acpi@vger.kernel.org\n");
1276 }
1277 if (!osi_linux.known && !osi_linux.cmdline) {
1278 printk(KERN_NOTICE PREFIX
1279 "If \"acpi_osi=%sLinux\" works better, "
1280 "please notify linux-acpi@vger.kernel.org\n",
1281 osi_linux.enable ? "!" : "");
1282 }
1283
1284 if (osi_linux.enable)
1170 return AE_OK; 1285 return AE_OK;
1171 } 1286 }
1172 return AE_SUPPORT; 1287 return AE_SUPPORT;
@@ -1198,28 +1313,4 @@ acpi_os_validate_address (
1198 return AE_OK; 1313 return AE_OK;
1199} 1314}
1200 1315
1201#ifdef CONFIG_DMI
1202static int dmi_osi_linux(const struct dmi_system_id *d)
1203{
1204 printk(KERN_NOTICE "%s detected: enabling _OSI(Linux)\n", d->ident);
1205 enable_osi_linux(1);
1206 return 0;
1207}
1208
1209static struct dmi_system_id acpi_osl_dmi_table[] __initdata = {
1210 /*
1211 * Boxes that need _OSI(Linux)
1212 */
1213 {
1214 .callback = dmi_osi_linux,
1215 .ident = "Intel Napa CRB",
1216 .matches = {
1217 DMI_MATCH(DMI_BOARD_VENDOR, "Intel Corporation"),
1218 DMI_MATCH(DMI_BOARD_NAME, "MPAD-MSAE Customer Reference Boards"),
1219 },
1220 },
1221 {}
1222};
1223#endif /* CONFIG_DMI */
1224
1225#endif 1316#endif
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index dd3186abe07a..62010c2481b3 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -429,6 +429,15 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
429 &polarity, &link, 429 &polarity, &link,
430 acpi_pci_allocate_irq); 430 acpi_pci_allocate_irq);
431 431
432 if (irq < 0) {
433 /*
434 * IDE legacy mode controller IRQs are magic. Why do compat
435 * extensions always make such a nasty mess.
436 */
437 if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE &&
438 (dev->class & 0x05) == 0)
439 return 0;
440 }
432 /* 441 /*
433 * No IRQ known to the ACPI subsystem - maybe the BIOS / 442 * No IRQ known to the ACPI subsystem - maybe the BIOS /
434 * driver reported one, then use it. Exit in any case. 443 * driver reported one, then use it. Exit in any case.
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index c9f526e55392..5400ea173f6f 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -911,7 +911,7 @@ __setup("acpi_irq_balance", acpi_irq_balance_set);
911 911
912/* FIXME: we will remove this interface after all drivers call pci_disable_device */ 912/* FIXME: we will remove this interface after all drivers call pci_disable_device */
913static struct sysdev_class irqrouter_sysdev_class = { 913static struct sysdev_class irqrouter_sysdev_class = {
914 set_kset_name("irqrouter"), 914 .name = "irqrouter",
915 .resume = irqrouter_resume, 915 .resume = irqrouter_resume,
916}; 916};
917 917
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 2fe34cc73c13..199ea2146153 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -38,7 +38,7 @@
38#include <linux/dmi.h> 38#include <linux/dmi.h>
39#include <linux/moduleparam.h> 39#include <linux/moduleparam.h>
40#include <linux/sched.h> /* need_resched() */ 40#include <linux/sched.h> /* need_resched() */
41#include <linux/latency.h> 41#include <linux/pm_qos_params.h>
42#include <linux/clockchips.h> 42#include <linux/clockchips.h>
43#include <linux/cpuidle.h> 43#include <linux/cpuidle.h>
44 44
@@ -76,7 +76,11 @@ static void (*pm_idle_save) (void) __read_mostly;
76#define PM_TIMER_TICKS_TO_US(p) (((p) * 1000)/(PM_TIMER_FREQUENCY/1000)) 76#define PM_TIMER_TICKS_TO_US(p) (((p) * 1000)/(PM_TIMER_FREQUENCY/1000))
77 77
78static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER; 78static unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER;
79#ifdef CONFIG_CPU_IDLE
79module_param(max_cstate, uint, 0000); 80module_param(max_cstate, uint, 0000);
81#else
82module_param(max_cstate, uint, 0644);
83#endif
80static unsigned int nocst __read_mostly; 84static unsigned int nocst __read_mostly;
81module_param(nocst, uint, 0000); 85module_param(nocst, uint, 0000);
82 86
@@ -353,6 +357,26 @@ int acpi_processor_resume(struct acpi_device * device)
353 return 0; 357 return 0;
354} 358}
355 359
360#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
361static int tsc_halts_in_c(int state)
362{
363 switch (boot_cpu_data.x86_vendor) {
364 case X86_VENDOR_AMD:
365 /*
366 * AMD Fam10h TSC will tick in all
367 * C/P/S0/S1 states when this bit is set.
368 */
369 if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC))
370 return 0;
371 /*FALL THROUGH*/
372 case X86_VENDOR_INTEL:
373 /* Several cases known where TSC halts in C2 too */
374 default:
375 return state > ACPI_STATE_C1;
376 }
377}
378#endif
379
356#ifndef CONFIG_CPU_IDLE 380#ifndef CONFIG_CPU_IDLE
357static void acpi_processor_idle(void) 381static void acpi_processor_idle(void)
358{ 382{
@@ -512,7 +536,8 @@ static void acpi_processor_idle(void)
512 536
513#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) 537#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
514 /* TSC halts in C2, so notify users */ 538 /* TSC halts in C2, so notify users */
515 mark_tsc_unstable("possible TSC halt in C2"); 539 if (tsc_halts_in_c(ACPI_STATE_C2))
540 mark_tsc_unstable("possible TSC halt in C2");
516#endif 541#endif
517 /* Compute time (ticks) that we were actually asleep */ 542 /* Compute time (ticks) that we were actually asleep */
518 sleep_ticks = ticks_elapsed(t1, t2); 543 sleep_ticks = ticks_elapsed(t1, t2);
@@ -530,6 +555,7 @@ static void acpi_processor_idle(void)
530 break; 555 break;
531 556
532 case ACPI_STATE_C3: 557 case ACPI_STATE_C3:
558 acpi_unlazy_tlb(smp_processor_id());
533 /* 559 /*
534 * Must be done before busmaster disable as we might 560 * Must be done before busmaster disable as we might
535 * need to access HPET ! 561 * need to access HPET !
@@ -575,7 +601,8 @@ static void acpi_processor_idle(void)
575 601
576#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) 602#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
577 /* TSC halts in C3, so notify users */ 603 /* TSC halts in C3, so notify users */
578 mark_tsc_unstable("TSC halts in C3"); 604 if (tsc_halts_in_c(ACPI_STATE_C3))
605 mark_tsc_unstable("TSC halts in C3");
579#endif 606#endif
580 /* Compute time (ticks) that we were actually asleep */ 607 /* Compute time (ticks) that we were actually asleep */
581 sleep_ticks = ticks_elapsed(t1, t2); 608 sleep_ticks = ticks_elapsed(t1, t2);
@@ -621,7 +648,8 @@ static void acpi_processor_idle(void)
621 if (cx->promotion.state && 648 if (cx->promotion.state &&
622 ((cx->promotion.state - pr->power.states) <= max_cstate)) { 649 ((cx->promotion.state - pr->power.states) <= max_cstate)) {
623 if (sleep_ticks > cx->promotion.threshold.ticks && 650 if (sleep_ticks > cx->promotion.threshold.ticks &&
624 cx->promotion.state->latency <= system_latency_constraint()) { 651 cx->promotion.state->latency <=
652 pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)) {
625 cx->promotion.count++; 653 cx->promotion.count++;
626 cx->demotion.count = 0; 654 cx->demotion.count = 0;
627 if (cx->promotion.count >= 655 if (cx->promotion.count >=
@@ -665,7 +693,8 @@ static void acpi_processor_idle(void)
665 * or if the latency of the current state is unacceptable 693 * or if the latency of the current state is unacceptable
666 */ 694 */
667 if ((pr->power.state - pr->power.states) > max_cstate || 695 if ((pr->power.state - pr->power.states) > max_cstate ||
668 pr->power.state->latency > system_latency_constraint()) { 696 pr->power.state->latency >
697 pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY)) {
669 if (cx->demotion.state) 698 if (cx->demotion.state)
670 next_state = cx->demotion.state; 699 next_state = cx->demotion.state;
671 } 700 }
@@ -1173,7 +1202,7 @@ static int acpi_processor_power_seq_show(struct seq_file *seq, void *offset)
1173 "maximum allowed latency: %d usec\n", 1202 "maximum allowed latency: %d usec\n",
1174 pr->power.state ? pr->power.state - pr->power.states : 0, 1203 pr->power.state ? pr->power.state - pr->power.states : 0,
1175 max_cstate, (unsigned)pr->power.bm_activity, 1204 max_cstate, (unsigned)pr->power.bm_activity,
1176 system_latency_constraint()); 1205 pm_qos_requirement(PM_QOS_CPU_DMA_LATENCY));
1177 1206
1178 seq_puts(seq, "states:\n"); 1207 seq_puts(seq, "states:\n");
1179 1208
@@ -1419,6 +1448,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
1419 return 0; 1448 return 0;
1420 } 1449 }
1421 1450
1451 acpi_unlazy_tlb(smp_processor_id());
1422 /* 1452 /*
1423 * Must be done before busmaster disable as we might need to 1453 * Must be done before busmaster disable as we might need to
1424 * access HPET ! 1454 * access HPET !
@@ -1439,7 +1469,8 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
1439 1469
1440#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) 1470#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
1441 /* TSC could halt in idle, so notify users */ 1471 /* TSC could halt in idle, so notify users */
1442 mark_tsc_unstable("TSC halts in idle");; 1472 if (tsc_halts_in_c(cx->type))
1473 mark_tsc_unstable("TSC halts in idle");;
1443#endif 1474#endif
1444 sleep_ticks = ticks_elapsed(t1, t2); 1475 sleep_ticks = ticks_elapsed(t1, t2);
1445 1476
@@ -1550,7 +1581,8 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
1550 1581
1551#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC) 1582#if defined (CONFIG_GENERIC_TIME) && defined (CONFIG_X86_TSC)
1552 /* TSC could halt in idle, so notify users */ 1583 /* TSC could halt in idle, so notify users */
1553 mark_tsc_unstable("TSC halts in idle"); 1584 if (tsc_halts_in_c(ACPI_STATE_C3))
1585 mark_tsc_unstable("TSC halts in idle");
1554#endif 1586#endif
1555 sleep_ticks = ticks_elapsed(t1, t2); 1587 sleep_ticks = ticks_elapsed(t1, t2);
1556 /* Tell the scheduler how much we idled: */ 1588 /* Tell the scheduler how much we idled: */
@@ -1688,8 +1720,9 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr,
1688 "ACPI: processor limited to max C-state %d\n", 1720 "ACPI: processor limited to max C-state %d\n",
1689 max_cstate); 1721 max_cstate);
1690 first_run++; 1722 first_run++;
1691#if !defined (CONFIG_CPU_IDLE) && defined (CONFIG_SMP) 1723#if !defined(CONFIG_CPU_IDLE) && defined(CONFIG_SMP)
1692 register_latency_notifier(&acpi_processor_latency_notifier); 1724 pm_qos_add_notifier(PM_QOS_CPU_DMA_LATENCY,
1725 &acpi_processor_latency_notifier);
1693#endif 1726#endif
1694 } 1727 }
1695 1728
@@ -1776,7 +1809,8 @@ int acpi_processor_power_exit(struct acpi_processor *pr,
1776 */ 1809 */
1777 cpu_idle_wait(); 1810 cpu_idle_wait();
1778#ifdef CONFIG_SMP 1811#ifdef CONFIG_SMP
1779 unregister_latency_notifier(&acpi_processor_latency_notifier); 1812 pm_qos_remove_notifier(PM_QOS_CPU_DMA_LATENCY,
1813 &acpi_processor_latency_notifier);
1780#endif 1814#endif
1781 } 1815 }
1782#endif 1816#endif
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index 6742d7bc4777..1685b40abda7 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -775,12 +775,12 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr)
775 acpi_processor_get_throttling_states(pr) || 775 acpi_processor_get_throttling_states(pr) ||
776 acpi_processor_get_platform_limit(pr)) 776 acpi_processor_get_platform_limit(pr))
777 { 777 {
778 if (acpi_processor_get_fadt_info(pr))
779 return 0;
780 pr->throttling.acpi_processor_get_throttling = 778 pr->throttling.acpi_processor_get_throttling =
781 &acpi_processor_get_throttling_fadt; 779 &acpi_processor_get_throttling_fadt;
782 pr->throttling.acpi_processor_set_throttling = 780 pr->throttling.acpi_processor_set_throttling =
783 &acpi_processor_set_throttling_fadt; 781 &acpi_processor_set_throttling_fadt;
782 if (acpi_processor_get_fadt_info(pr))
783 return 0;
784 } else { 784 } else {
785 pr->throttling.acpi_processor_get_throttling = 785 pr->throttling.acpi_processor_get_throttling =
786 &acpi_processor_get_throttling_ptc; 786 &acpi_processor_get_throttling_ptc;
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 22cb95b349e4..f136c7d3b3c2 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -40,7 +40,9 @@
40#include <linux/jiffies.h> 40#include <linux/jiffies.h>
41#include <linux/delay.h> 41#include <linux/delay.h>
42 42
43#ifdef CONFIG_ACPI_SYSFS_POWER
43#include <linux/power_supply.h> 44#include <linux/power_supply.h>
45#endif
44 46
45#include "sbshc.h" 47#include "sbshc.h"
46 48
@@ -80,7 +82,9 @@ static const struct acpi_device_id sbs_device_ids[] = {
80MODULE_DEVICE_TABLE(acpi, sbs_device_ids); 82MODULE_DEVICE_TABLE(acpi, sbs_device_ids);
81 83
82struct acpi_battery { 84struct acpi_battery {
85#ifdef CONFIG_ACPI_SYSFS_POWER
83 struct power_supply bat; 86 struct power_supply bat;
87#endif
84 struct acpi_sbs *sbs; 88 struct acpi_sbs *sbs;
85#ifdef CONFIG_ACPI_PROCFS_POWER 89#ifdef CONFIG_ACPI_PROCFS_POWER
86 struct proc_dir_entry *proc_entry; 90 struct proc_dir_entry *proc_entry;
@@ -113,7 +117,9 @@ struct acpi_battery {
113#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); 117#define to_acpi_battery(x) container_of(x, struct acpi_battery, bat);
114 118
115struct acpi_sbs { 119struct acpi_sbs {
120#ifdef CONFIG_ACPI_SYSFS_POWER
116 struct power_supply charger; 121 struct power_supply charger;
122#endif
117 struct acpi_device *device; 123 struct acpi_device *device;
118 struct acpi_smb_hc *hc; 124 struct acpi_smb_hc *hc;
119 struct mutex lock; 125 struct mutex lock;
@@ -157,6 +163,7 @@ static inline int acpi_battery_scale(struct acpi_battery *battery)
157 acpi_battery_ipscale(battery); 163 acpi_battery_ipscale(battery);
158} 164}
159 165
166#ifdef CONFIG_ACPI_SYSFS_POWER
160static int sbs_get_ac_property(struct power_supply *psy, 167static int sbs_get_ac_property(struct power_supply *psy,
161 enum power_supply_property psp, 168 enum power_supply_property psp,
162 union power_supply_propval *val) 169 union power_supply_propval *val)
@@ -294,6 +301,7 @@ static enum power_supply_property sbs_energy_battery_props[] = {
294 POWER_SUPPLY_PROP_MODEL_NAME, 301 POWER_SUPPLY_PROP_MODEL_NAME,
295 POWER_SUPPLY_PROP_MANUFACTURER, 302 POWER_SUPPLY_PROP_MANUFACTURER,
296}; 303};
304#endif
297 305
298/* -------------------------------------------------------------------------- 306/* --------------------------------------------------------------------------
299 Smart Battery System Management 307 Smart Battery System Management
@@ -429,6 +437,7 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs)
429 return result; 437 return result;
430} 438}
431 439
440#ifdef CONFIG_ACPI_SYSFS_POWER
432static ssize_t acpi_battery_alarm_show(struct device *dev, 441static ssize_t acpi_battery_alarm_show(struct device *dev,
433 struct device_attribute *attr, 442 struct device_attribute *attr,
434 char *buf) 443 char *buf)
@@ -458,6 +467,7 @@ static struct device_attribute alarm_attr = {
458 .show = acpi_battery_alarm_show, 467 .show = acpi_battery_alarm_show,
459 .store = acpi_battery_alarm_store, 468 .store = acpi_battery_alarm_store,
460}; 469};
470#endif
461 471
462/* -------------------------------------------------------------------------- 472/* --------------------------------------------------------------------------
463 FS Interface (/proc/acpi) 473 FS Interface (/proc/acpi)
@@ -793,6 +803,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
793 &acpi_battery_state_fops, &acpi_battery_alarm_fops, 803 &acpi_battery_state_fops, &acpi_battery_alarm_fops,
794 battery); 804 battery);
795#endif 805#endif
806#ifdef CONFIG_ACPI_SYSFS_POWER
796 battery->bat.name = battery->name; 807 battery->bat.name = battery->name;
797 battery->bat.type = POWER_SUPPLY_TYPE_BATTERY; 808 battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
798 if (!acpi_battery_mode(battery)) { 809 if (!acpi_battery_mode(battery)) {
@@ -813,6 +824,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
813 goto end; 824 goto end;
814 battery->have_sysfs_alarm = 1; 825 battery->have_sysfs_alarm = 1;
815 end: 826 end:
827#endif
816 printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n", 828 printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",
817 ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), 829 ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
818 battery->name, sbs->battery->present ? "present" : "absent"); 830 battery->name, sbs->battery->present ? "present" : "absent");
@@ -822,12 +834,13 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)
822static void acpi_battery_remove(struct acpi_sbs *sbs, int id) 834static void acpi_battery_remove(struct acpi_sbs *sbs, int id)
823{ 835{
824 struct acpi_battery *battery = &sbs->battery[id]; 836 struct acpi_battery *battery = &sbs->battery[id];
825 837#ifdef CONFIG_ACPI_SYSFS_POWER
826 if (battery->bat.dev) { 838 if (battery->bat.dev) {
827 if (battery->have_sysfs_alarm) 839 if (battery->have_sysfs_alarm)
828 device_remove_file(battery->bat.dev, &alarm_attr); 840 device_remove_file(battery->bat.dev, &alarm_attr);
829 power_supply_unregister(&battery->bat); 841 power_supply_unregister(&battery->bat);
830 } 842 }
843#endif
831#ifdef CONFIG_ACPI_PROCFS_POWER 844#ifdef CONFIG_ACPI_PROCFS_POWER
832 if (battery->proc_entry) 845 if (battery->proc_entry)
833 acpi_sbs_remove_fs(&battery->proc_entry, acpi_battery_dir); 846 acpi_sbs_remove_fs(&battery->proc_entry, acpi_battery_dir);
@@ -848,12 +861,14 @@ static int acpi_charger_add(struct acpi_sbs *sbs)
848 if (result) 861 if (result)
849 goto end; 862 goto end;
850#endif 863#endif
864#ifdef CONFIG_ACPI_SYSFS_POWER
851 sbs->charger.name = "sbs-charger"; 865 sbs->charger.name = "sbs-charger";
852 sbs->charger.type = POWER_SUPPLY_TYPE_MAINS; 866 sbs->charger.type = POWER_SUPPLY_TYPE_MAINS;
853 sbs->charger.properties = sbs_ac_props; 867 sbs->charger.properties = sbs_ac_props;
854 sbs->charger.num_properties = ARRAY_SIZE(sbs_ac_props); 868 sbs->charger.num_properties = ARRAY_SIZE(sbs_ac_props);
855 sbs->charger.get_property = sbs_get_ac_property; 869 sbs->charger.get_property = sbs_get_ac_property;
856 power_supply_register(&sbs->device->dev, &sbs->charger); 870 power_supply_register(&sbs->device->dev, &sbs->charger);
871#endif
857 printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n", 872 printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n",
858 ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), 873 ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device),
859 ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line"); 874 ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line");
@@ -863,8 +878,10 @@ static int acpi_charger_add(struct acpi_sbs *sbs)
863 878
864static void acpi_charger_remove(struct acpi_sbs *sbs) 879static void acpi_charger_remove(struct acpi_sbs *sbs)
865{ 880{
881#ifdef CONFIG_ACPI_SYSFS_POWER
866 if (sbs->charger.dev) 882 if (sbs->charger.dev)
867 power_supply_unregister(&sbs->charger); 883 power_supply_unregister(&sbs->charger);
884#endif
868#ifdef CONFIG_ACPI_PROCFS_POWER 885#ifdef CONFIG_ACPI_PROCFS_POWER
869 if (sbs->charger_entry) 886 if (sbs->charger_entry)
870 acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir); 887 acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir);
@@ -885,7 +902,9 @@ void acpi_sbs_callback(void *context)
885 ACPI_SBS_NOTIFY_STATUS, 902 ACPI_SBS_NOTIFY_STATUS,
886 sbs->charger_present); 903 sbs->charger_present);
887#endif 904#endif
905#ifdef CONFIG_ACPI_SYSFS_POWER
888 kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE); 906 kobject_uevent(&sbs->charger.dev->kobj, KOBJ_CHANGE);
907#endif
889 } 908 }
890 if (sbs->manager_present) { 909 if (sbs->manager_present) {
891 for (id = 0; id < MAX_SBS_BAT; ++id) { 910 for (id = 0; id < MAX_SBS_BAT; ++id) {
@@ -902,7 +921,9 @@ void acpi_sbs_callback(void *context)
902 ACPI_SBS_NOTIFY_STATUS, 921 ACPI_SBS_NOTIFY_STATUS,
903 bat->present); 922 bat->present);
904#endif 923#endif
924#ifdef CONFIG_ACPI_SYSFS_POWER
905 kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE); 925 kobject_uevent(&bat->bat.dev->kobj, KOBJ_CHANGE);
926#endif
906 } 927 }
907 } 928 }
908} 929}
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 5b4d462117cf..c7b0aa52dd23 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -830,7 +830,7 @@ static int acpi_bus_get_flags(struct acpi_device *device)
830 if (ACPI_SUCCESS(status)) 830 if (ACPI_SUCCESS(status))
831 device->flags.wake_capable = 1; 831 device->flags.wake_capable = 1;
832 832
833 /* TBD: Peformance management */ 833 /* TBD: Performance management */
834 834
835 return 0; 835 return 0;
836} 836}
@@ -941,6 +941,15 @@ static int acpi_bay_match(struct acpi_device *device){
941 return -ENODEV; 941 return -ENODEV;
942} 942}
943 943
944/*
945 * acpi_dock_match - see if a device has a _DCK method
946 */
947static int acpi_dock_match(struct acpi_device *device)
948{
949 acpi_handle tmp;
950 return acpi_get_handle(device->handle, "_DCK", &tmp);
951}
952
944static void acpi_device_set_id(struct acpi_device *device, 953static void acpi_device_set_id(struct acpi_device *device,
945 struct acpi_device *parent, acpi_handle handle, 954 struct acpi_device *parent, acpi_handle handle,
946 int type) 955 int type)
@@ -950,6 +959,7 @@ static void acpi_device_set_id(struct acpi_device *device,
950 char *hid = NULL; 959 char *hid = NULL;
951 char *uid = NULL; 960 char *uid = NULL;
952 struct acpi_compatible_id_list *cid_list = NULL; 961 struct acpi_compatible_id_list *cid_list = NULL;
962 const char *cid_add = NULL;
953 acpi_status status; 963 acpi_status status;
954 964
955 switch (type) { 965 switch (type) {
@@ -972,15 +982,18 @@ static void acpi_device_set_id(struct acpi_device *device,
972 device->flags.bus_address = 1; 982 device->flags.bus_address = 1;
973 } 983 }
974 984
975 if(!(info->valid & (ACPI_VALID_HID | ACPI_VALID_CID))){ 985 /* If we have a video/bay/dock device, add our selfdefined
976 status = acpi_video_bus_match(device); 986 HID to the CID list. Like that the video/bay/dock drivers
977 if(ACPI_SUCCESS(status)) 987 will get autoloaded and the device might still match
978 hid = ACPI_VIDEO_HID; 988 against another driver.
989 */
990 if (ACPI_SUCCESS(acpi_video_bus_match(device)))
991 cid_add = ACPI_VIDEO_HID;
992 else if (ACPI_SUCCESS(acpi_bay_match(device)))
993 cid_add = ACPI_BAY_HID;
994 else if (ACPI_SUCCESS(acpi_dock_match(device)))
995 cid_add = ACPI_DOCK_HID;
979 996
980 status = acpi_bay_match(device);
981 if (ACPI_SUCCESS(status))
982 hid = ACPI_BAY_HID;
983 }
984 break; 997 break;
985 case ACPI_BUS_TYPE_POWER: 998 case ACPI_BUS_TYPE_POWER:
986 hid = ACPI_POWER_HID; 999 hid = ACPI_POWER_HID;
@@ -1021,11 +1034,44 @@ static void acpi_device_set_id(struct acpi_device *device,
1021 strcpy(device->pnp.unique_id, uid); 1034 strcpy(device->pnp.unique_id, uid);
1022 device->flags.unique_id = 1; 1035 device->flags.unique_id = 1;
1023 } 1036 }
1024 if (cid_list) { 1037 if (cid_list || cid_add) {
1025 device->pnp.cid_list = kmalloc(cid_list->size, GFP_KERNEL); 1038 struct acpi_compatible_id_list *list;
1026 if (device->pnp.cid_list) 1039 int size = 0;
1027 memcpy(device->pnp.cid_list, cid_list, cid_list->size); 1040 int count = 0;
1028 else 1041
1042 if (cid_list) {
1043 size = cid_list->size;
1044 } else if (cid_add) {
1045 size = sizeof(struct acpi_compatible_id_list);
1046 cid_list = ACPI_ALLOCATE_ZEROED((acpi_size) size);
1047 if (!cid_list) {
1048 printk(KERN_ERR "Memory allocation error\n");
1049 kfree(buffer.pointer);
1050 return;
1051 } else {
1052 cid_list->count = 0;
1053 cid_list->size = size;
1054 }
1055 }
1056 if (cid_add)
1057 size += sizeof(struct acpi_compatible_id);
1058 list = kmalloc(size, GFP_KERNEL);
1059
1060 if (list) {
1061 if (cid_list) {
1062 memcpy(list, cid_list, cid_list->size);
1063 count = cid_list->count;
1064 }
1065 if (cid_add) {
1066 strncpy(list->id[count].value, cid_add,
1067 ACPI_MAX_CID_LENGTH);
1068 count++;
1069 device->flags.compatible_ids = 1;
1070 }
1071 list->size = size;
1072 list->count = count;
1073 device->pnp.cid_list = list;
1074 } else
1029 printk(KERN_ERR "Memory allocation error\n"); 1075 printk(KERN_ERR "Memory allocation error\n");
1030 } 1076 }
1031 1077
@@ -1081,6 +1127,20 @@ static int acpi_bus_remove(struct acpi_device *dev, int rmdevice)
1081} 1127}
1082 1128
1083static int 1129static int
1130acpi_is_child_device(struct acpi_device *device,
1131 int (*matcher)(struct acpi_device *))
1132{
1133 int result = -ENODEV;
1134
1135 do {
1136 if (ACPI_SUCCESS(matcher(device)))
1137 return AE_OK;
1138 } while ((device = device->parent));
1139
1140 return result;
1141}
1142
1143static int
1084acpi_add_single_object(struct acpi_device **child, 1144acpi_add_single_object(struct acpi_device **child,
1085 struct acpi_device *parent, acpi_handle handle, int type, 1145 struct acpi_device *parent, acpi_handle handle, int type,
1086 struct acpi_bus_ops *ops) 1146 struct acpi_bus_ops *ops)
@@ -1131,10 +1191,20 @@ acpi_add_single_object(struct acpi_device **child,
1131 case ACPI_BUS_TYPE_PROCESSOR: 1191 case ACPI_BUS_TYPE_PROCESSOR:
1132 case ACPI_BUS_TYPE_DEVICE: 1192 case ACPI_BUS_TYPE_DEVICE:
1133 result = acpi_bus_get_status(device); 1193 result = acpi_bus_get_status(device);
1134 if (ACPI_FAILURE(result) || !device->status.present) { 1194 if (ACPI_FAILURE(result)) {
1135 result = -ENOENT; 1195 result = -ENODEV;
1136 goto end; 1196 goto end;
1137 } 1197 }
1198 if (!device->status.present) {
1199 /* Bay and dock should be handled even if absent */
1200 if (!ACPI_SUCCESS(
1201 acpi_is_child_device(device, acpi_bay_match)) &&
1202 !ACPI_SUCCESS(
1203 acpi_is_child_device(device, acpi_dock_match))) {
1204 result = -ENODEV;
1205 goto end;
1206 }
1207 }
1138 break; 1208 break;
1139 default: 1209 default:
1140 STRUCT_TO_INT(device->status) = 1210 STRUCT_TO_INT(device->status) =
@@ -1449,6 +1519,8 @@ static int acpi_bus_scan_fixed(struct acpi_device *root)
1449 return result; 1519 return result;
1450} 1520}
1451 1521
1522int __init acpi_boot_ec_enable(void);
1523
1452static int __init acpi_scan_init(void) 1524static int __init acpi_scan_init(void)
1453{ 1525{
1454 int result; 1526 int result;
@@ -1480,6 +1552,10 @@ static int __init acpi_scan_init(void)
1480 * Enumerate devices in the ACPI namespace. 1552 * Enumerate devices in the ACPI namespace.
1481 */ 1553 */
1482 result = acpi_bus_scan_fixed(acpi_root); 1554 result = acpi_bus_scan_fixed(acpi_root);
1555
1556 /* EC region might be needed at bus_scan, so enable it now */
1557 acpi_boot_ec_enable();
1558
1483 if (!result) 1559 if (!result)
1484 result = acpi_bus_scan(acpi_root, &ops); 1560 result = acpi_bus_scan(acpi_root, &ops);
1485 1561
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index 2c0b6630f8ba..7f97e32fc33f 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -26,9 +26,24 @@ u8 sleep_states[ACPI_S_STATE_COUNT];
26 26
27#ifdef CONFIG_PM_SLEEP 27#ifdef CONFIG_PM_SLEEP
28static u32 acpi_target_sleep_state = ACPI_STATE_S0; 28static u32 acpi_target_sleep_state = ACPI_STATE_S0;
29static bool acpi_sleep_finish_wake_up;
30
31/*
32 * ACPI 2.0 and later want us to execute _PTS after suspending devices, so we
33 * allow the user to request that behavior by using the 'acpi_new_pts_ordering'
34 * kernel command line option that causes the following variable to be set.
35 */
36static bool new_pts_ordering;
37
38static int __init acpi_new_pts_ordering(char *str)
39{
40 new_pts_ordering = true;
41 return 1;
42}
43__setup("acpi_new_pts_ordering", acpi_new_pts_ordering);
29#endif 44#endif
30 45
31int acpi_sleep_prepare(u32 acpi_state) 46static int acpi_sleep_prepare(u32 acpi_state)
32{ 47{
33#ifdef CONFIG_ACPI_SLEEP 48#ifdef CONFIG_ACPI_SLEEP
34 /* do we have a wakeup address for S2 and S3? */ 49 /* do we have a wakeup address for S2 and S3? */
@@ -44,6 +59,8 @@ int acpi_sleep_prepare(u32 acpi_state)
44 ACPI_FLUSH_CPU_CACHE(); 59 ACPI_FLUSH_CPU_CACHE();
45 acpi_enable_wakeup_device_prep(acpi_state); 60 acpi_enable_wakeup_device_prep(acpi_state);
46#endif 61#endif
62 printk(KERN_INFO PREFIX "Preparing to enter system sleep state S%d\n",
63 acpi_state);
47 acpi_enter_sleep_state_prep(acpi_state); 64 acpi_enter_sleep_state_prep(acpi_state);
48 return 0; 65 return 0;
49} 66}
@@ -63,17 +80,25 @@ static u32 acpi_suspend_states[] = {
63static int init_8259A_after_S1; 80static int init_8259A_after_S1;
64 81
65/** 82/**
66 * acpi_pm_set_target - Set the target system sleep state to the state 83 * acpi_pm_begin - Set the target system sleep state to the state
67 * associated with given @pm_state, if supported. 84 * associated with given @pm_state, if supported.
68 */ 85 */
69 86
70static int acpi_pm_set_target(suspend_state_t pm_state) 87static int acpi_pm_begin(suspend_state_t pm_state)
71{ 88{
72 u32 acpi_state = acpi_suspend_states[pm_state]; 89 u32 acpi_state = acpi_suspend_states[pm_state];
73 int error = 0; 90 int error = 0;
74 91
75 if (sleep_states[acpi_state]) { 92 if (sleep_states[acpi_state]) {
76 acpi_target_sleep_state = acpi_state; 93 acpi_target_sleep_state = acpi_state;
94 if (new_pts_ordering)
95 return 0;
96
97 error = acpi_sleep_prepare(acpi_state);
98 if (error)
99 acpi_target_sleep_state = ACPI_STATE_S0;
100 else
101 acpi_sleep_finish_wake_up = true;
77 } else { 102 } else {
78 printk(KERN_ERR "ACPI does not support this state: %d\n", 103 printk(KERN_ERR "ACPI does not support this state: %d\n",
79 pm_state); 104 pm_state);
@@ -91,12 +116,17 @@ static int acpi_pm_set_target(suspend_state_t pm_state)
91 116
92static int acpi_pm_prepare(void) 117static int acpi_pm_prepare(void)
93{ 118{
94 int error = acpi_sleep_prepare(acpi_target_sleep_state); 119 if (new_pts_ordering) {
120 int error = acpi_sleep_prepare(acpi_target_sleep_state);
95 121
96 if (error) 122 if (error) {
97 acpi_target_sleep_state = ACPI_STATE_S0; 123 acpi_target_sleep_state = ACPI_STATE_S0;
124 return error;
125 }
126 acpi_sleep_finish_wake_up = true;
127 }
98 128
99 return error; 129 return ACPI_SUCCESS(acpi_hw_disable_all_gpes()) ? 0 : -EFAULT;
100} 130}
101 131
102/** 132/**
@@ -120,10 +150,8 @@ static int acpi_pm_enter(suspend_state_t pm_state)
120 if (acpi_state == ACPI_STATE_S3) { 150 if (acpi_state == ACPI_STATE_S3) {
121 int error = acpi_save_state_mem(); 151 int error = acpi_save_state_mem();
122 152
123 if (error) { 153 if (error)
124 acpi_target_sleep_state = ACPI_STATE_S0;
125 return error; 154 return error;
126 }
127 } 155 }
128 156
129 local_irq_save(flags); 157 local_irq_save(flags);
@@ -139,6 +167,9 @@ static int acpi_pm_enter(suspend_state_t pm_state)
139 break; 167 break;
140 } 168 }
141 169
170 /* Reprogram control registers and execute _BFS */
171 acpi_leave_sleep_state_prep(acpi_state);
172
142 /* ACPI 3.0 specs (P62) says that it's the responsabilty 173 /* ACPI 3.0 specs (P62) says that it's the responsabilty
143 * of the OSPM to clear the status bit [ implying that the 174 * of the OSPM to clear the status bit [ implying that the
144 * POWER_BUTTON event should not reach userspace ] 175 * POWER_BUTTON event should not reach userspace ]
@@ -146,6 +177,13 @@ static int acpi_pm_enter(suspend_state_t pm_state)
146 if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3)) 177 if (ACPI_SUCCESS(status) && (acpi_state == ACPI_STATE_S3))
147 acpi_clear_event(ACPI_EVENT_POWER_BUTTON); 178 acpi_clear_event(ACPI_EVENT_POWER_BUTTON);
148 179
180 /*
181 * Disable and clear GPE status before interrupt is enabled. Some GPEs
182 * (like wakeup GPE) haven't handler, this can avoid such GPE misfire.
183 * acpi_leave_sleep_state will reenable specific GPEs later
184 */
185 acpi_hw_disable_all_gpes();
186
149 local_irq_restore(flags); 187 local_irq_restore(flags);
150 printk(KERN_DEBUG "Back to C!\n"); 188 printk(KERN_DEBUG "Back to C!\n");
151 189
@@ -157,7 +195,7 @@ static int acpi_pm_enter(suspend_state_t pm_state)
157} 195}
158 196
159/** 197/**
160 * acpi_pm_finish - Finish up suspend sequence. 198 * acpi_pm_finish - Instruct the platform to leave a sleep state.
161 * 199 *
162 * This is called after we wake back up (or if entering the sleep state 200 * This is called after we wake back up (or if entering the sleep state
163 * failed). 201 * failed).
@@ -174,6 +212,7 @@ static void acpi_pm_finish(void)
174 acpi_set_firmware_waking_vector((acpi_physical_address) 0); 212 acpi_set_firmware_waking_vector((acpi_physical_address) 0);
175 213
176 acpi_target_sleep_state = ACPI_STATE_S0; 214 acpi_target_sleep_state = ACPI_STATE_S0;
215 acpi_sleep_finish_wake_up = false;
177 216
178#ifdef CONFIG_X86 217#ifdef CONFIG_X86
179 if (init_8259A_after_S1) { 218 if (init_8259A_after_S1) {
@@ -183,6 +222,20 @@ static void acpi_pm_finish(void)
183#endif 222#endif
184} 223}
185 224
225/**
226 * acpi_pm_end - Finish up suspend sequence.
227 */
228
229static void acpi_pm_end(void)
230{
231 /*
232 * This is necessary in case acpi_pm_finish() is not called directly
233 * during a failing transition to a sleep state.
234 */
235 if (acpi_sleep_finish_wake_up)
236 acpi_pm_finish();
237}
238
186static int acpi_pm_state_valid(suspend_state_t pm_state) 239static int acpi_pm_state_valid(suspend_state_t pm_state)
187{ 240{
188 u32 acpi_state; 241 u32 acpi_state;
@@ -201,10 +254,11 @@ static int acpi_pm_state_valid(suspend_state_t pm_state)
201 254
202static struct platform_suspend_ops acpi_pm_ops = { 255static struct platform_suspend_ops acpi_pm_ops = {
203 .valid = acpi_pm_state_valid, 256 .valid = acpi_pm_state_valid,
204 .set_target = acpi_pm_set_target, 257 .begin = acpi_pm_begin,
205 .prepare = acpi_pm_prepare, 258 .prepare = acpi_pm_prepare,
206 .enter = acpi_pm_enter, 259 .enter = acpi_pm_enter,
207 .finish = acpi_pm_finish, 260 .finish = acpi_pm_finish,
261 .end = acpi_pm_end,
208}; 262};
209 263
210/* 264/*
@@ -229,15 +283,36 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
229#endif /* CONFIG_SUSPEND */ 283#endif /* CONFIG_SUSPEND */
230 284
231#ifdef CONFIG_HIBERNATION 285#ifdef CONFIG_HIBERNATION
232static int acpi_hibernation_start(void) 286static int acpi_hibernation_begin(void)
233{ 287{
288 int error;
289
234 acpi_target_sleep_state = ACPI_STATE_S4; 290 acpi_target_sleep_state = ACPI_STATE_S4;
235 return 0; 291 if (new_pts_ordering)
292 return 0;
293
294 error = acpi_sleep_prepare(ACPI_STATE_S4);
295 if (error)
296 acpi_target_sleep_state = ACPI_STATE_S0;
297 else
298 acpi_sleep_finish_wake_up = true;
299
300 return error;
236} 301}
237 302
238static int acpi_hibernation_prepare(void) 303static int acpi_hibernation_prepare(void)
239{ 304{
240 return acpi_sleep_prepare(ACPI_STATE_S4); 305 if (new_pts_ordering) {
306 int error = acpi_sleep_prepare(ACPI_STATE_S4);
307
308 if (error) {
309 acpi_target_sleep_state = ACPI_STATE_S0;
310 return error;
311 }
312 acpi_sleep_finish_wake_up = true;
313 }
314
315 return ACPI_SUCCESS(acpi_hw_disable_all_gpes()) ? 0 : -EFAULT;
241} 316}
242 317
243static int acpi_hibernation_enter(void) 318static int acpi_hibernation_enter(void)
@@ -251,6 +326,8 @@ static int acpi_hibernation_enter(void)
251 acpi_enable_wakeup_device(ACPI_STATE_S4); 326 acpi_enable_wakeup_device(ACPI_STATE_S4);
252 /* This shouldn't return. If it returns, we have a problem */ 327 /* This shouldn't return. If it returns, we have a problem */
253 status = acpi_enter_sleep_state(ACPI_STATE_S4); 328 status = acpi_enter_sleep_state(ACPI_STATE_S4);
329 /* Reprogram control registers and execute _BFS */
330 acpi_leave_sleep_state_prep(ACPI_STATE_S4);
254 local_irq_restore(flags); 331 local_irq_restore(flags);
255 332
256 return ACPI_SUCCESS(status) ? 0 : -EFAULT; 333 return ACPI_SUCCESS(status) ? 0 : -EFAULT;
@@ -263,15 +340,12 @@ static void acpi_hibernation_leave(void)
263 * enable it here. 340 * enable it here.
264 */ 341 */
265 acpi_enable(); 342 acpi_enable();
343 /* Reprogram control registers and execute _BFS */
344 acpi_leave_sleep_state_prep(ACPI_STATE_S4);
266} 345}
267 346
268static void acpi_hibernation_finish(void) 347static void acpi_hibernation_finish(void)
269{ 348{
270 /*
271 * If ACPI is not enabled by the BIOS and the boot kernel, we need to
272 * enable it here.
273 */
274 acpi_enable();
275 acpi_disable_wakeup_device(ACPI_STATE_S4); 349 acpi_disable_wakeup_device(ACPI_STATE_S4);
276 acpi_leave_sleep_state(ACPI_STATE_S4); 350 acpi_leave_sleep_state(ACPI_STATE_S4);
277 351
@@ -279,6 +353,17 @@ static void acpi_hibernation_finish(void)
279 acpi_set_firmware_waking_vector((acpi_physical_address) 0); 353 acpi_set_firmware_waking_vector((acpi_physical_address) 0);
280 354
281 acpi_target_sleep_state = ACPI_STATE_S0; 355 acpi_target_sleep_state = ACPI_STATE_S0;
356 acpi_sleep_finish_wake_up = false;
357}
358
359static void acpi_hibernation_end(void)
360{
361 /*
362 * This is necessary in case acpi_hibernation_finish() is not called
363 * directly during a failing transition to the sleep state.
364 */
365 if (acpi_sleep_finish_wake_up)
366 acpi_hibernation_finish();
282} 367}
283 368
284static int acpi_hibernation_pre_restore(void) 369static int acpi_hibernation_pre_restore(void)
@@ -296,7 +381,8 @@ static void acpi_hibernation_restore_cleanup(void)
296} 381}
297 382
298static struct platform_hibernation_ops acpi_hibernation_ops = { 383static struct platform_hibernation_ops acpi_hibernation_ops = {
299 .start = acpi_hibernation_start, 384 .begin = acpi_hibernation_begin,
385 .end = acpi_hibernation_end,
300 .pre_snapshot = acpi_hibernation_prepare, 386 .pre_snapshot = acpi_hibernation_prepare,
301 .finish = acpi_hibernation_finish, 387 .finish = acpi_hibernation_finish,
302 .prepare = acpi_hibernation_prepare, 388 .prepare = acpi_hibernation_prepare,
@@ -386,11 +472,20 @@ int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p)
386 if (acpi_target_sleep_state == ACPI_STATE_S0 || 472 if (acpi_target_sleep_state == ACPI_STATE_S0 ||
387 (wake && adev->wakeup.state.enabled && 473 (wake && adev->wakeup.state.enabled &&
388 adev->wakeup.sleep_state <= acpi_target_sleep_state)) { 474 adev->wakeup.sleep_state <= acpi_target_sleep_state)) {
475 acpi_status status;
476
389 acpi_method[3] = 'W'; 477 acpi_method[3] = 'W';
390 acpi_evaluate_integer(handle, acpi_method, NULL, &d_max); 478 status = acpi_evaluate_integer(handle, acpi_method, NULL,
391 /* Sanity check */ 479 &d_max);
392 if (d_max < d_min) 480 if (ACPI_FAILURE(status)) {
481 d_max = d_min;
482 } else if (d_max < d_min) {
483 /* Warn the user of the broken DSDT */
484 printk(KERN_WARNING "ACPI: Wrong value from %s\n",
485 acpi_method);
486 /* Sanitize it */
393 d_min = d_max; 487 d_min = d_max;
488 }
394 } 489 }
395 490
396 if (d_min_p) 491 if (d_min_p)
@@ -403,6 +498,7 @@ static void acpi_power_off_prepare(void)
403{ 498{
404 /* Prepare to power off the system */ 499 /* Prepare to power off the system */
405 acpi_sleep_prepare(ACPI_STATE_S5); 500 acpi_sleep_prepare(ACPI_STATE_S5);
501 acpi_hw_disable_all_gpes();
406} 502}
407 503
408static void acpi_power_off(void) 504static void acpi_power_off(void)
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c
index 1538355c266b..f8df5217d477 100644
--- a/drivers/acpi/sleep/proc.c
+++ b/drivers/acpi/sleep/proc.c
@@ -178,6 +178,9 @@ static int get_date_field(char **p, u32 * value)
178 * Try to find delimeter, only to insert null. The end of the 178 * Try to find delimeter, only to insert null. The end of the
179 * string won't have one, but is still valid. 179 * string won't have one, but is still valid.
180 */ 180 */
181 if (*p == NULL)
182 return result;
183
181 next = strpbrk(*p, "- :"); 184 next = strpbrk(*p, "- :");
182 if (next) 185 if (next)
183 *next++ = '\0'; 186 *next++ = '\0';
@@ -190,6 +193,8 @@ static int get_date_field(char **p, u32 * value)
190 193
191 if (next) 194 if (next)
192 *p = next; 195 *p = next;
196 else
197 *p = NULL;
193 198
194 return result; 199 return result;
195} 200}
@@ -251,27 +256,6 @@ acpi_system_write_alarm(struct file *file,
251 if ((result = get_date_field(&p, &sec))) 256 if ((result = get_date_field(&p, &sec)))
252 goto end; 257 goto end;
253 258
254 if (sec > 59) {
255 min += 1;
256 sec -= 60;
257 }
258 if (min > 59) {
259 hr += 1;
260 min -= 60;
261 }
262 if (hr > 23) {
263 day += 1;
264 hr -= 24;
265 }
266 if (day > 31) {
267 mo += 1;
268 day -= 31;
269 }
270 if (mo > 12) {
271 yr += 1;
272 mo -= 12;
273 }
274
275 spin_lock_irq(&rtc_lock); 259 spin_lock_irq(&rtc_lock);
276 260
277 rtc_control = CMOS_READ(RTC_CONTROL); 261 rtc_control = CMOS_READ(RTC_CONTROL);
@@ -288,24 +272,24 @@ acpi_system_write_alarm(struct file *file,
288 spin_unlock_irq(&rtc_lock); 272 spin_unlock_irq(&rtc_lock);
289 273
290 if (sec > 59) { 274 if (sec > 59) {
291 min++; 275 min += sec/60;
292 sec -= 60; 276 sec = sec%60;
293 } 277 }
294 if (min > 59) { 278 if (min > 59) {
295 hr++; 279 hr += min/60;
296 min -= 60; 280 min = min%60;
297 } 281 }
298 if (hr > 23) { 282 if (hr > 23) {
299 day++; 283 day += hr/24;
300 hr -= 24; 284 hr = hr%24;
301 } 285 }
302 if (day > 31) { 286 if (day > 31) {
303 mo++; 287 mo += day/32;
304 day -= 31; 288 day = day%32;
305 } 289 }
306 if (mo > 12) { 290 if (mo > 12) {
307 yr++; 291 yr += mo/13;
308 mo -= 12; 292 mo = mo%13;
309 } 293 }
310 294
311 spin_lock_irq(&rtc_lock); 295 spin_lock_irq(&rtc_lock);
diff --git a/drivers/acpi/sleep/sleep.h b/drivers/acpi/sleep/sleep.h
index a2ea125ae2d0..cfaf8f5b0a14 100644
--- a/drivers/acpi/sleep/sleep.h
+++ b/drivers/acpi/sleep/sleep.h
@@ -5,5 +5,3 @@ extern int acpi_suspend (u32 state);
5extern void acpi_enable_wakeup_device_prep(u8 sleep_state); 5extern void acpi_enable_wakeup_device_prep(u8 sleep_state);
6extern void acpi_enable_wakeup_device(u8 sleep_state); 6extern void acpi_enable_wakeup_device(u8 sleep_state);
7extern void acpi_disable_wakeup_device(u8 sleep_state); 7extern void acpi_disable_wakeup_device(u8 sleep_state);
8
9extern int acpi_sleep_prepare(u32 acpi_state);
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index edee2806e37b..5ffe0ea18967 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -58,7 +58,7 @@ module_param_call(acpica_version, NULL, param_get_acpica_version, NULL, 0444);
58 FS Interface (/sys) 58 FS Interface (/sys)
59 -------------------------------------------------------------------------- */ 59 -------------------------------------------------------------------------- */
60static LIST_HEAD(acpi_table_attr_list); 60static LIST_HEAD(acpi_table_attr_list);
61static struct kobject tables_kobj; 61static struct kobject *tables_kobj;
62 62
63struct acpi_table_attr { 63struct acpi_table_attr {
64 struct bin_attribute attr; 64 struct bin_attribute attr;
@@ -135,11 +135,9 @@ static int acpi_system_sysfs_init(void)
135 int table_index = 0; 135 int table_index = 0;
136 int result; 136 int result;
137 137
138 tables_kobj.parent = &acpi_subsys.kobj; 138 tables_kobj = kobject_create_and_add("tables", acpi_kobj);
139 kobject_set_name(&tables_kobj, "tables"); 139 if (!tables_kobj)
140 result = kobject_register(&tables_kobj); 140 return -ENOMEM;
141 if (result)
142 return result;
143 141
144 do { 142 do {
145 result = acpi_get_table_by_index(table_index, &table_header); 143 result = acpi_get_table_by_index(table_index, &table_header);
@@ -153,7 +151,7 @@ static int acpi_system_sysfs_init(void)
153 151
154 acpi_table_attr_init(table_attr, table_header); 152 acpi_table_attr_init(table_attr, table_header);
155 result = 153 result =
156 sysfs_create_bin_file(&tables_kobj, 154 sysfs_create_bin_file(tables_kobj,
157 &table_attr->attr); 155 &table_attr->attr);
158 if (result) { 156 if (result) {
159 kfree(table_attr); 157 kfree(table_attr);
@@ -163,6 +161,7 @@ static int acpi_system_sysfs_init(void)
163 &acpi_table_attr_list); 161 &acpi_table_attr_list);
164 } 162 }
165 } while (!result); 163 } while (!result);
164 kobject_uevent(tables_kobj, KOBJ_ADD);
166 165
167 return 0; 166 return 0;
168} 167}
diff --git a/drivers/acpi/tables/Makefile b/drivers/acpi/tables/Makefile
index 0a7d7afac255..7385efa61622 100644
--- a/drivers/acpi/tables/Makefile
+++ b/drivers/acpi/tables/Makefile
@@ -2,6 +2,6 @@
2# Makefile for all Linux ACPI interpreter subdirectories 2# Makefile for all Linux ACPI interpreter subdirectories
3# 3#
4 4
5obj-y := tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o 5obj-y := tbxface.o tbinstal.o tbutils.o tbfind.o tbfadt.o tbxfroot.o
6 6
7EXTRA_CFLAGS += $(ACPI_CFLAGS) 7EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/tables/tbxfroot.c b/drivers/acpi/tables/tbxfroot.c
index cf8fa514189f..9ecb4b6c1e7d 100644
--- a/drivers/acpi/tables/tbxfroot.c
+++ b/drivers/acpi/tables/tbxfroot.c
@@ -100,7 +100,7 @@ static acpi_status acpi_tb_validate_rsdp(struct acpi_table_rsdp *rsdp)
100 100
101/******************************************************************************* 101/*******************************************************************************
102 * 102 *
103 * FUNCTION: acpi_tb_find_rsdp 103 * FUNCTION: acpi_find_root_pointer
104 * 104 *
105 * PARAMETERS: table_address - Where the table pointer is returned 105 * PARAMETERS: table_address - Where the table pointer is returned
106 * 106 *
@@ -219,8 +219,6 @@ acpi_status acpi_find_root_pointer(acpi_native_uint * table_address)
219 return_ACPI_STATUS(AE_NOT_FOUND); 219 return_ACPI_STATUS(AE_NOT_FOUND);
220} 220}
221 221
222ACPI_EXPORT_SYMBOL(acpi_find_root_pointer)
223
224/******************************************************************************* 222/*******************************************************************************
225 * 223 *
226 * FUNCTION: acpi_tb_scan_memory_for_rsdp 224 * FUNCTION: acpi_tb_scan_memory_for_rsdp
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 5f79b4451212..3a0af9a8cd27 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -492,7 +492,7 @@ static int acpi_thermal_get_devices(struct acpi_thermal *tz)
492 492
493static int acpi_thermal_critical(struct acpi_thermal *tz) 493static int acpi_thermal_critical(struct acpi_thermal *tz)
494{ 494{
495 if (!tz || !tz->trips.critical.flags.valid || nocrt) 495 if (!tz || !tz->trips.critical.flags.valid)
496 return -EINVAL; 496 return -EINVAL;
497 497
498 if (tz->temperature >= tz->trips.critical.temperature) { 498 if (tz->temperature >= tz->trips.critical.temperature) {
@@ -501,9 +501,6 @@ static int acpi_thermal_critical(struct acpi_thermal *tz)
501 } else if (tz->trips.critical.flags.enabled) 501 } else if (tz->trips.critical.flags.enabled)
502 tz->trips.critical.flags.enabled = 0; 502 tz->trips.critical.flags.enabled = 0;
503 503
504 printk(KERN_EMERG
505 "Critical temperature reached (%ld C), shutting down.\n",
506 KELVIN_TO_CELSIUS(tz->temperature));
507 acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL, 504 acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL,
508 tz->trips.critical.flags.enabled); 505 tz->trips.critical.flags.enabled);
509 acpi_bus_generate_netlink_event(tz->device->pnp.device_class, 506 acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
@@ -511,14 +508,20 @@ static int acpi_thermal_critical(struct acpi_thermal *tz)
511 ACPI_THERMAL_NOTIFY_CRITICAL, 508 ACPI_THERMAL_NOTIFY_CRITICAL,
512 tz->trips.critical.flags.enabled); 509 tz->trips.critical.flags.enabled);
513 510
514 orderly_poweroff(true); 511 /* take no action if nocrt is set */
512 if(!nocrt) {
513 printk(KERN_EMERG
514 "Critical temperature reached (%ld C), shutting down.\n",
515 KELVIN_TO_CELSIUS(tz->temperature));
516 orderly_poweroff(true);
517 }
515 518
516 return 0; 519 return 0;
517} 520}
518 521
519static int acpi_thermal_hot(struct acpi_thermal *tz) 522static int acpi_thermal_hot(struct acpi_thermal *tz)
520{ 523{
521 if (!tz || !tz->trips.hot.flags.valid || nocrt) 524 if (!tz || !tz->trips.hot.flags.valid)
522 return -EINVAL; 525 return -EINVAL;
523 526
524 if (tz->temperature >= tz->trips.hot.temperature) { 527 if (tz->temperature >= tz->trips.hot.temperature) {
@@ -534,7 +537,7 @@ static int acpi_thermal_hot(struct acpi_thermal *tz)
534 ACPI_THERMAL_NOTIFY_HOT, 537 ACPI_THERMAL_NOTIFY_HOT,
535 tz->trips.hot.flags.enabled); 538 tz->trips.hot.flags.enabled);
536 539
537 /* TBD: Call user-mode "sleep(S4)" function */ 540 /* TBD: Call user-mode "sleep(S4)" function if nocrt is cleared */
538 541
539 return 0; 542 return 0;
540} 543}
diff --git a/drivers/acpi/utilities/utresrc.c b/drivers/acpi/utilities/utresrc.c
index cbbd3315a1e2..b630ee137ee1 100644
--- a/drivers/acpi/utilities/utresrc.c
+++ b/drivers/acpi/utilities/utresrc.c
@@ -1,6 +1,6 @@
1/******************************************************************************* 1/*******************************************************************************
2 * 2 *
3 * Module Name: utresrc - Resource managment utilities 3 * Module Name: utresrc - Resource management utilities
4 * 4 *
5 ******************************************************************************/ 5 ******************************************************************************/
6 6
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index bd77e81e81c1..a54ff6bce8fa 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -292,18 +292,26 @@ static int acpi_video_device_set_state(struct acpi_video_device *device, int sta
292static int acpi_video_get_brightness(struct backlight_device *bd) 292static int acpi_video_get_brightness(struct backlight_device *bd)
293{ 293{
294 unsigned long cur_level; 294 unsigned long cur_level;
295 int i;
295 struct acpi_video_device *vd = 296 struct acpi_video_device *vd =
296 (struct acpi_video_device *)bl_get_data(bd); 297 (struct acpi_video_device *)bl_get_data(bd);
297 acpi_video_device_lcd_get_level_current(vd, &cur_level); 298 acpi_video_device_lcd_get_level_current(vd, &cur_level);
298 return (int) cur_level; 299 for (i = 2; i < vd->brightness->count; i++) {
300 if (vd->brightness->levels[i] == cur_level)
301 /* The first two entries are special - see page 575
302 of the ACPI spec 3.0 */
303 return i-2;
304 }
305 return 0;
299} 306}
300 307
301static int acpi_video_set_brightness(struct backlight_device *bd) 308static int acpi_video_set_brightness(struct backlight_device *bd)
302{ 309{
303 int request_level = bd->props.brightness; 310 int request_level = bd->props.brightness+2;
304 struct acpi_video_device *vd = 311 struct acpi_video_device *vd =
305 (struct acpi_video_device *)bl_get_data(bd); 312 (struct acpi_video_device *)bl_get_data(bd);
306 acpi_video_device_lcd_set_level(vd, request_level); 313 acpi_video_device_lcd_set_level(vd,
314 vd->brightness->levels[request_level]);
307 return 0; 315 return 0;
308} 316}
309 317
@@ -652,7 +660,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
652 kfree(obj); 660 kfree(obj);
653 661
654 if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){ 662 if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){
655 unsigned long tmp;
656 static int count = 0; 663 static int count = 0;
657 char *name; 664 char *name;
658 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL); 665 name = kzalloc(MAX_NAME_LEN, GFP_KERNEL);
@@ -660,11 +667,10 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
660 return; 667 return;
661 668
662 sprintf(name, "acpi_video%d", count++); 669 sprintf(name, "acpi_video%d", count++);
663 acpi_video_device_lcd_get_level_current(device, &tmp);
664 device->backlight = backlight_device_register(name, 670 device->backlight = backlight_device_register(name,
665 NULL, device, &acpi_backlight_ops); 671 NULL, device, &acpi_backlight_ops);
666 device->backlight->props.max_brightness = max_level; 672 device->backlight->props.max_brightness = device->brightness->count-3;
667 device->backlight->props.brightness = (int)tmp; 673 device->backlight->props.brightness = acpi_video_get_brightness(device->backlight);
668 backlight_update_status(device->backlight); 674 backlight_update_status(device->backlight);
669 675
670 kfree(name); 676 kfree(name);
@@ -1256,8 +1262,37 @@ acpi_video_bus_write_DOS(struct file *file,
1256 1262
1257static int acpi_video_bus_add_fs(struct acpi_device *device) 1263static int acpi_video_bus_add_fs(struct acpi_device *device)
1258{ 1264{
1265 long device_id;
1266 int status;
1259 struct proc_dir_entry *entry = NULL; 1267 struct proc_dir_entry *entry = NULL;
1260 struct acpi_video_bus *video; 1268 struct acpi_video_bus *video;
1269 struct device *dev;
1270
1271 status =
1272 acpi_evaluate_integer(device->handle, "_ADR", NULL, &device_id);
1273
1274 if (!ACPI_SUCCESS(status))
1275 return -ENODEV;
1276
1277 /* We need to attempt to determine whether the _ADR refers to a
1278 PCI device or not. There's no terribly good way to do this,
1279 so the best we can hope for is to assume that there'll never
1280 be a video device in the host bridge */
1281 if (device_id >= 0x10000) {
1282 /* It looks like a PCI device. Does it exist? */
1283 dev = acpi_get_physical_device(device->handle);
1284 } else {
1285 /* It doesn't look like a PCI device. Does its parent
1286 exist? */
1287 acpi_handle phandle;
1288 if (acpi_get_parent(device->handle, &phandle))
1289 return -ENODEV;
1290 dev = acpi_get_physical_device(phandle);
1291 }
1292 if (!dev)
1293 return -ENODEV;
1294 put_device(dev);
1295
1261 1296
1262 1297
1263 video = acpi_driver_data(device); 1298 video = acpi_driver_data(device);