diff options
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/Kconfig | 18 | ||||
-rw-r--r-- | drivers/acpi/Makefile | 2 | ||||
-rw-r--r-- | drivers/acpi/ac.c | 20 | ||||
-rw-r--r-- | drivers/acpi/battery.c | 22 | ||||
-rw-r--r-- | drivers/acpi/ec.c | 100 | ||||
-rw-r--r-- | drivers/acpi/processor_core.c | 21 | ||||
-rw-r--r-- | drivers/acpi/processor_idle.c | 112 | ||||
-rw-r--r-- | drivers/acpi/sbs.c | 43 | ||||
-rw-r--r-- | drivers/acpi/tables/tbutils.c | 2 | ||||
-rw-r--r-- | drivers/acpi/video.c | 155 |
10 files changed, 286 insertions, 209 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 087a7028ae84..b9f923ef173d 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -50,7 +50,6 @@ config ACPI_SLEEP | |||
50 | config ACPI_PROCFS | 50 | config ACPI_PROCFS |
51 | bool "Deprecated /proc/acpi files" | 51 | bool "Deprecated /proc/acpi files" |
52 | depends on PROC_FS | 52 | depends on PROC_FS |
53 | default y | ||
54 | ---help--- | 53 | ---help--- |
55 | For backwards compatibility, this option allows | 54 | For backwards compatibility, this option allows |
56 | deprecated /proc/acpi/ files to exist, even when | 55 | deprecated /proc/acpi/ files to exist, even when |
@@ -61,7 +60,6 @@ config ACPI_PROCFS | |||
61 | /proc/acpi/info (/sys/modules/acpi/parameters/acpica_version) | 60 | /proc/acpi/info (/sys/modules/acpi/parameters/acpica_version) |
62 | /proc/acpi/dsdt (/sys/firmware/acpi/tables/DSDT) | 61 | /proc/acpi/dsdt (/sys/firmware/acpi/tables/DSDT) |
63 | /proc/acpi/fadt (/sys/firmware/acpi/tables/FACP) | 62 | /proc/acpi/fadt (/sys/firmware/acpi/tables/FACP) |
64 | /proc/acpi/battery (/sys/class/power_supply) | ||
65 | /proc/acpi/debug_layer (/sys/module/acpi/parameters/debug_layer) | 63 | /proc/acpi/debug_layer (/sys/module/acpi/parameters/debug_layer) |
66 | /proc/acpi/debug_level (/sys/module/acpi/parameters/debug_level) | 64 | /proc/acpi/debug_level (/sys/module/acpi/parameters/debug_level) |
67 | 65 | ||
@@ -69,7 +67,21 @@ config ACPI_PROCFS | |||
69 | and functions which do not yet exist in /sys. | 67 | and functions which do not yet exist in /sys. |
70 | 68 | ||
71 | Say N to delete /proc/acpi/ files that have moved to /sys/ | 69 | Say N to delete /proc/acpi/ files that have moved to /sys/ |
72 | 70 | config ACPI_PROCFS_POWER | |
71 | bool "Deprecated power /proc/acpi folders" | ||
72 | depends on PROC_FS | ||
73 | default y | ||
74 | ---help--- | ||
75 | For backwards compatibility, this option allows | ||
76 | deprecated power /proc/acpi/ folders to exist, even when | ||
77 | they have been replaced by functions in /sys. | ||
78 | The deprecated folders (and their replacements) include: | ||
79 | /proc/acpi/battery/* (/sys/class/power_supply/*) | ||
80 | /proc/acpi/ac_adapter/* (sys/class/power_supply/*) | ||
81 | This option has no effect on /proc/acpi/ folders | ||
82 | and functions, which do not yet exist in /sys | ||
83 | |||
84 | Say N to delete power /proc/acpi/ folders that have moved to /sys/ | ||
73 | config ACPI_PROC_EVENT | 85 | config ACPI_PROC_EVENT |
74 | bool "Deprecated /proc/acpi/event support" | 86 | bool "Deprecated /proc/acpi/event support" |
75 | depends on PROC_FS | 87 | depends on PROC_FS |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 54e3ab0e5fc0..456446f90077 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -58,6 +58,6 @@ obj-$(CONFIG_ACPI_NUMA) += numa.o | |||
58 | obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o | 58 | obj-$(CONFIG_ACPI_ASUS) += asus_acpi.o |
59 | obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o | 59 | obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o |
60 | obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o | 60 | obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o |
61 | obj-y += cm_sbs.o | 61 | obj-$(CONFIG_ACPI_PROCFS_POWER) += cm_sbs.o |
62 | obj-$(CONFIG_ACPI_SBS) += sbs.o | 62 | obj-$(CONFIG_ACPI_SBS) += sbs.o |
63 | obj-$(CONFIG_ACPI_SBS) += sbshc.o | 63 | obj-$(CONFIG_ACPI_SBS) += sbshc.o |
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index 30238f6ff232..76ed4f52bebd 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/types.h> | 29 | #include <linux/types.h> |
30 | #ifdef CONFIG_ACPI_PROCFS | 30 | #ifdef CONFIG_ACPI_PROCFS_POWER |
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 |
@@ -51,7 +51,7 @@ MODULE_AUTHOR("Paul Diefenbaugh"); | |||
51 | MODULE_DESCRIPTION("ACPI AC Adapter Driver"); | 51 | MODULE_DESCRIPTION("ACPI AC Adapter Driver"); |
52 | MODULE_LICENSE("GPL"); | 52 | MODULE_LICENSE("GPL"); |
53 | 53 | ||
54 | #ifdef CONFIG_ACPI_PROCFS | 54 | #ifdef CONFIG_ACPI_PROCFS_POWER |
55 | extern struct proc_dir_entry *acpi_lock_ac_dir(void); | 55 | extern struct proc_dir_entry *acpi_lock_ac_dir(void); |
56 | extern void *acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir); | 56 | extern void *acpi_unlock_ac_dir(struct proc_dir_entry *acpi_ac_dir); |
57 | static int acpi_ac_open_fs(struct inode *inode, struct file *file); | 57 | static int acpi_ac_open_fs(struct inode *inode, struct file *file); |
@@ -86,7 +86,7 @@ struct acpi_ac { | |||
86 | 86 | ||
87 | #define to_acpi_ac(x) container_of(x, struct acpi_ac, charger); | 87 | #define to_acpi_ac(x) container_of(x, struct acpi_ac, charger); |
88 | 88 | ||
89 | #ifdef CONFIG_ACPI_PROCFS | 89 | #ifdef CONFIG_ACPI_PROCFS_POWER |
90 | static const struct file_operations acpi_ac_fops = { | 90 | static const struct file_operations acpi_ac_fops = { |
91 | .open = acpi_ac_open_fs, | 91 | .open = acpi_ac_open_fs, |
92 | .read = seq_read, | 92 | .read = seq_read, |
@@ -136,7 +136,7 @@ static int acpi_ac_get_state(struct acpi_ac *ac) | |||
136 | return 0; | 136 | return 0; |
137 | } | 137 | } |
138 | 138 | ||
139 | #ifdef CONFIG_ACPI_PROCFS | 139 | #ifdef CONFIG_ACPI_PROCFS_POWER |
140 | /* -------------------------------------------------------------------------- | 140 | /* -------------------------------------------------------------------------- |
141 | FS Interface (/proc) | 141 | FS Interface (/proc) |
142 | -------------------------------------------------------------------------- */ | 142 | -------------------------------------------------------------------------- */ |
@@ -275,7 +275,7 @@ static int acpi_ac_add(struct acpi_device *device) | |||
275 | if (result) | 275 | if (result) |
276 | goto end; | 276 | goto end; |
277 | 277 | ||
278 | #ifdef CONFIG_ACPI_PROCFS | 278 | #ifdef CONFIG_ACPI_PROCFS_POWER |
279 | result = acpi_ac_add_fs(device); | 279 | result = acpi_ac_add_fs(device); |
280 | #endif | 280 | #endif |
281 | if (result) | 281 | if (result) |
@@ -300,7 +300,7 @@ static int acpi_ac_add(struct acpi_device *device) | |||
300 | 300 | ||
301 | end: | 301 | end: |
302 | if (result) { | 302 | if (result) { |
303 | #ifdef CONFIG_ACPI_PROCFS | 303 | #ifdef CONFIG_ACPI_PROCFS_POWER |
304 | acpi_ac_remove_fs(device); | 304 | acpi_ac_remove_fs(device); |
305 | #endif | 305 | #endif |
306 | kfree(ac); | 306 | kfree(ac); |
@@ -339,7 +339,7 @@ static int acpi_ac_remove(struct acpi_device *device, int type) | |||
339 | ACPI_ALL_NOTIFY, acpi_ac_notify); | 339 | ACPI_ALL_NOTIFY, acpi_ac_notify); |
340 | if (ac->charger.dev) | 340 | if (ac->charger.dev) |
341 | power_supply_unregister(&ac->charger); | 341 | power_supply_unregister(&ac->charger); |
342 | #ifdef CONFIG_ACPI_PROCFS | 342 | #ifdef CONFIG_ACPI_PROCFS_POWER |
343 | acpi_ac_remove_fs(device); | 343 | acpi_ac_remove_fs(device); |
344 | #endif | 344 | #endif |
345 | 345 | ||
@@ -355,7 +355,7 @@ static int __init acpi_ac_init(void) | |||
355 | if (acpi_disabled) | 355 | if (acpi_disabled) |
356 | return -ENODEV; | 356 | return -ENODEV; |
357 | 357 | ||
358 | #ifdef CONFIG_ACPI_PROCFS | 358 | #ifdef CONFIG_ACPI_PROCFS_POWER |
359 | acpi_ac_dir = acpi_lock_ac_dir(); | 359 | acpi_ac_dir = acpi_lock_ac_dir(); |
360 | if (!acpi_ac_dir) | 360 | if (!acpi_ac_dir) |
361 | return -ENODEV; | 361 | return -ENODEV; |
@@ -363,7 +363,7 @@ static int __init acpi_ac_init(void) | |||
363 | 363 | ||
364 | result = acpi_bus_register_driver(&acpi_ac_driver); | 364 | result = acpi_bus_register_driver(&acpi_ac_driver); |
365 | if (result < 0) { | 365 | if (result < 0) { |
366 | #ifdef CONFIG_ACPI_PROCFS | 366 | #ifdef CONFIG_ACPI_PROCFS_POWER |
367 | acpi_unlock_ac_dir(acpi_ac_dir); | 367 | acpi_unlock_ac_dir(acpi_ac_dir); |
368 | #endif | 368 | #endif |
369 | return -ENODEV; | 369 | return -ENODEV; |
@@ -377,7 +377,7 @@ static void __exit acpi_ac_exit(void) | |||
377 | 377 | ||
378 | acpi_bus_unregister_driver(&acpi_ac_driver); | 378 | acpi_bus_unregister_driver(&acpi_ac_driver); |
379 | 379 | ||
380 | #ifdef CONFIG_ACPI_PROCFS | 380 | #ifdef CONFIG_ACPI_PROCFS_POWER |
381 | acpi_unlock_ac_dir(acpi_ac_dir); | 381 | acpi_unlock_ac_dir(acpi_ac_dir); |
382 | #endif | 382 | #endif |
383 | 383 | ||
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 192c244f6190..7d6be23eff89 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/types.h> | 31 | #include <linux/types.h> |
32 | #include <linux/jiffies.h> | 32 | #include <linux/jiffies.h> |
33 | 33 | ||
34 | #ifdef CONFIG_ACPI_PROCFS | 34 | #ifdef CONFIG_ACPI_PROCFS_POWER |
35 | #include <linux/proc_fs.h> | 35 | #include <linux/proc_fs.h> |
36 | #include <linux/seq_file.h> | 36 | #include <linux/seq_file.h> |
37 | #include <asm/uaccess.h> | 37 | #include <asm/uaccess.h> |
@@ -63,7 +63,7 @@ static unsigned int cache_time = 1000; | |||
63 | module_param(cache_time, uint, 0644); | 63 | module_param(cache_time, uint, 0644); |
64 | MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); | 64 | MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); |
65 | 65 | ||
66 | #ifdef CONFIG_ACPI_PROCFS | 66 | #ifdef CONFIG_ACPI_PROCFS_POWER |
67 | extern struct proc_dir_entry *acpi_lock_battery_dir(void); | 67 | extern struct proc_dir_entry *acpi_lock_battery_dir(void); |
68 | extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); | 68 | extern void *acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir); |
69 | 69 | ||
@@ -153,6 +153,8 @@ static int acpi_battery_get_property(struct power_supply *psy, | |||
153 | val->intval = POWER_SUPPLY_STATUS_CHARGING; | 153 | val->intval = POWER_SUPPLY_STATUS_CHARGING; |
154 | else if (battery->state == 0) | 154 | else if (battery->state == 0) |
155 | val->intval = POWER_SUPPLY_STATUS_FULL; | 155 | val->intval = POWER_SUPPLY_STATUS_FULL; |
156 | else | ||
157 | val->intval = POWER_SUPPLY_STATUS_UNKNOWN; | ||
156 | break; | 158 | break; |
157 | case POWER_SUPPLY_PROP_PRESENT: | 159 | case POWER_SUPPLY_PROP_PRESENT: |
158 | val->intval = acpi_battery_present(battery); | 160 | val->intval = acpi_battery_present(battery); |
@@ -221,7 +223,7 @@ static enum power_supply_property energy_battery_props[] = { | |||
221 | POWER_SUPPLY_PROP_MANUFACTURER, | 223 | POWER_SUPPLY_PROP_MANUFACTURER, |
222 | }; | 224 | }; |
223 | 225 | ||
224 | #ifdef CONFIG_ACPI_PROCFS | 226 | #ifdef CONFIG_ACPI_PROCFS_POWER |
225 | inline char *acpi_battery_units(struct acpi_battery *battery) | 227 | inline char *acpi_battery_units(struct acpi_battery *battery) |
226 | { | 228 | { |
227 | return (battery->power_unit)?"mA":"mW"; | 229 | return (battery->power_unit)?"mA":"mW"; |
@@ -479,7 +481,7 @@ static int acpi_battery_update(struct acpi_battery *battery) | |||
479 | FS Interface (/proc) | 481 | FS Interface (/proc) |
480 | -------------------------------------------------------------------------- */ | 482 | -------------------------------------------------------------------------- */ |
481 | 483 | ||
482 | #ifdef CONFIG_ACPI_PROCFS | 484 | #ifdef CONFIG_ACPI_PROCFS_POWER |
483 | static struct proc_dir_entry *acpi_battery_dir; | 485 | static struct proc_dir_entry *acpi_battery_dir; |
484 | 486 | ||
485 | static int acpi_battery_print_info(struct seq_file *seq, int result) | 487 | static int acpi_battery_print_info(struct seq_file *seq, int result) |
@@ -786,7 +788,7 @@ static int acpi_battery_add(struct acpi_device *device) | |||
786 | acpi_driver_data(device) = battery; | 788 | acpi_driver_data(device) = battery; |
787 | mutex_init(&battery->lock); | 789 | mutex_init(&battery->lock); |
788 | acpi_battery_update(battery); | 790 | acpi_battery_update(battery); |
789 | #ifdef CONFIG_ACPI_PROCFS | 791 | #ifdef CONFIG_ACPI_PROCFS_POWER |
790 | result = acpi_battery_add_fs(device); | 792 | result = acpi_battery_add_fs(device); |
791 | if (result) | 793 | if (result) |
792 | goto end; | 794 | goto end; |
@@ -804,7 +806,7 @@ static int acpi_battery_add(struct acpi_device *device) | |||
804 | device->status.battery_present ? "present" : "absent"); | 806 | device->status.battery_present ? "present" : "absent"); |
805 | end: | 807 | end: |
806 | if (result) { | 808 | if (result) { |
807 | #ifdef CONFIG_ACPI_PROCFS | 809 | #ifdef CONFIG_ACPI_PROCFS_POWER |
808 | acpi_battery_remove_fs(device); | 810 | acpi_battery_remove_fs(device); |
809 | #endif | 811 | #endif |
810 | kfree(battery); | 812 | kfree(battery); |
@@ -823,7 +825,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type) | |||
823 | status = acpi_remove_notify_handler(device->handle, | 825 | status = acpi_remove_notify_handler(device->handle, |
824 | ACPI_ALL_NOTIFY, | 826 | ACPI_ALL_NOTIFY, |
825 | acpi_battery_notify); | 827 | acpi_battery_notify); |
826 | #ifdef CONFIG_ACPI_PROCFS | 828 | #ifdef CONFIG_ACPI_PROCFS_POWER |
827 | acpi_battery_remove_fs(device); | 829 | acpi_battery_remove_fs(device); |
828 | #endif | 830 | #endif |
829 | sysfs_remove_battery(battery); | 831 | sysfs_remove_battery(battery); |
@@ -859,13 +861,13 @@ static int __init acpi_battery_init(void) | |||
859 | { | 861 | { |
860 | if (acpi_disabled) | 862 | if (acpi_disabled) |
861 | return -ENODEV; | 863 | return -ENODEV; |
862 | #ifdef CONFIG_ACPI_PROCFS | 864 | #ifdef CONFIG_ACPI_PROCFS_POWER |
863 | acpi_battery_dir = acpi_lock_battery_dir(); | 865 | acpi_battery_dir = acpi_lock_battery_dir(); |
864 | if (!acpi_battery_dir) | 866 | if (!acpi_battery_dir) |
865 | return -ENODEV; | 867 | return -ENODEV; |
866 | #endif | 868 | #endif |
867 | if (acpi_bus_register_driver(&acpi_battery_driver) < 0) { | 869 | if (acpi_bus_register_driver(&acpi_battery_driver) < 0) { |
868 | #ifdef CONFIG_ACPI_PROCFS | 870 | #ifdef CONFIG_ACPI_PROCFS_POWER |
869 | acpi_unlock_battery_dir(acpi_battery_dir); | 871 | acpi_unlock_battery_dir(acpi_battery_dir); |
870 | #endif | 872 | #endif |
871 | return -ENODEV; | 873 | return -ENODEV; |
@@ -876,7 +878,7 @@ static int __init acpi_battery_init(void) | |||
876 | static void __exit acpi_battery_exit(void) | 878 | static void __exit acpi_battery_exit(void) |
877 | { | 879 | { |
878 | acpi_bus_unregister_driver(&acpi_battery_driver); | 880 | acpi_bus_unregister_driver(&acpi_battery_driver); |
879 | #ifdef CONFIG_ACPI_PROCFS | 881 | #ifdef CONFIG_ACPI_PROCFS_POWER |
880 | acpi_unlock_battery_dir(acpi_battery_dir); | 882 | acpi_unlock_battery_dir(acpi_battery_dir); |
881 | #endif | 883 | #endif |
882 | } | 884 | } |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 06b78e5e33a1..d411017f8c06 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -47,6 +47,9 @@ | |||
47 | #undef PREFIX | 47 | #undef PREFIX |
48 | #define PREFIX "ACPI: EC: " | 48 | #define PREFIX "ACPI: EC: " |
49 | 49 | ||
50 | /* Uncomment next line to get verbose print outs*/ | ||
51 | /* #define DEBUG */ | ||
52 | |||
50 | /* EC status register */ | 53 | /* EC status register */ |
51 | #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ | 54 | #define ACPI_EC_FLAG_OBF 0x01 /* Output buffer full */ |
52 | #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ | 55 | #define ACPI_EC_FLAG_IBF 0x02 /* Input buffer full */ |
@@ -75,7 +78,10 @@ enum { | |||
75 | EC_FLAGS_WAIT_GPE = 0, /* Don't check status until GPE arrives */ | 78 | EC_FLAGS_WAIT_GPE = 0, /* Don't check status until GPE arrives */ |
76 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ | 79 | EC_FLAGS_QUERY_PENDING, /* Query is pending */ |
77 | EC_FLAGS_GPE_MODE, /* Expect GPE to be sent for status change */ | 80 | EC_FLAGS_GPE_MODE, /* Expect GPE to be sent for status change */ |
78 | EC_FLAGS_ONLY_IBF_GPE, /* Expect GPE only for IBF = 0 event */ | 81 | EC_FLAGS_NO_ADDRESS_GPE, /* Expect GPE only for non-address event */ |
82 | EC_FLAGS_ADDRESS, /* Address is being written */ | ||
83 | EC_FLAGS_NO_WDATA_GPE, /* Don't expect WDATA GPE event */ | ||
84 | EC_FLAGS_WDATA, /* Data is being written */ | ||
79 | }; | 85 | }; |
80 | 86 | ||
81 | static int acpi_ec_remove(struct acpi_device *device, int type); | 87 | static int acpi_ec_remove(struct acpi_device *device, int type); |
@@ -131,21 +137,27 @@ static struct acpi_ec { | |||
131 | 137 | ||
132 | static inline u8 acpi_ec_read_status(struct acpi_ec *ec) | 138 | static inline u8 acpi_ec_read_status(struct acpi_ec *ec) |
133 | { | 139 | { |
134 | return inb(ec->command_addr); | 140 | u8 x = inb(ec->command_addr); |
141 | pr_debug(PREFIX "---> status = 0x%2x\n", x); | ||
142 | return x; | ||
135 | } | 143 | } |
136 | 144 | ||
137 | static inline u8 acpi_ec_read_data(struct acpi_ec *ec) | 145 | static inline u8 acpi_ec_read_data(struct acpi_ec *ec) |
138 | { | 146 | { |
147 | u8 x = inb(ec->data_addr); | ||
148 | pr_debug(PREFIX "---> data = 0x%2x\n", x); | ||
139 | return inb(ec->data_addr); | 149 | return inb(ec->data_addr); |
140 | } | 150 | } |
141 | 151 | ||
142 | static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) | 152 | static inline void acpi_ec_write_cmd(struct acpi_ec *ec, u8 command) |
143 | { | 153 | { |
154 | pr_debug(PREFIX "<--- command = 0x%2x\n", command); | ||
144 | outb(command, ec->command_addr); | 155 | outb(command, ec->command_addr); |
145 | } | 156 | } |
146 | 157 | ||
147 | static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) | 158 | static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data) |
148 | { | 159 | { |
160 | pr_debug(PREFIX "<--- data = 0x%2x\n", data); | ||
149 | outb(data, ec->data_addr); | 161 | outb(data, ec->data_addr); |
150 | } | 162 | } |
151 | 163 | ||
@@ -166,38 +178,54 @@ static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event) | |||
166 | 178 | ||
167 | static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) | 179 | static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll) |
168 | { | 180 | { |
181 | int ret = 0; | ||
182 | if (unlikely(test_bit(EC_FLAGS_ADDRESS, &ec->flags) && | ||
183 | test_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags))) | ||
184 | force_poll = 1; | ||
185 | if (unlikely(test_bit(EC_FLAGS_WDATA, &ec->flags) && | ||
186 | test_bit(EC_FLAGS_NO_WDATA_GPE, &ec->flags))) | ||
187 | force_poll = 1; | ||
169 | if (likely(test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) && | 188 | if (likely(test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) && |
170 | likely(!force_poll)) { | 189 | likely(!force_poll)) { |
171 | if (wait_event_timeout(ec->wait, acpi_ec_check_status(ec, event), | 190 | if (wait_event_timeout(ec->wait, acpi_ec_check_status(ec, event), |
172 | msecs_to_jiffies(ACPI_EC_DELAY))) | 191 | msecs_to_jiffies(ACPI_EC_DELAY))) |
173 | return 0; | 192 | goto end; |
174 | clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); | 193 | clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); |
175 | if (acpi_ec_check_status(ec, event)) { | 194 | if (acpi_ec_check_status(ec, event)) { |
176 | if (event == ACPI_EC_EVENT_OBF_1) { | 195 | if (test_bit(EC_FLAGS_ADDRESS, &ec->flags)) { |
177 | /* miss OBF = 1 GPE, don't expect it anymore */ | 196 | /* miss address GPE, don't expect it anymore */ |
178 | printk(KERN_INFO PREFIX "missing OBF_1 confirmation," | 197 | pr_info(PREFIX "missing address confirmation, " |
179 | "switching to degraded mode.\n"); | 198 | "don't expect it any longer.\n"); |
180 | set_bit(EC_FLAGS_ONLY_IBF_GPE, &ec->flags); | 199 | set_bit(EC_FLAGS_NO_ADDRESS_GPE, &ec->flags); |
200 | } else if (test_bit(EC_FLAGS_WDATA, &ec->flags)) { | ||
201 | /* miss write data GPE, don't expect it */ | ||
202 | pr_info(PREFIX "missing write data confirmation, " | ||
203 | "don't expect it any longer.\n"); | ||
204 | set_bit(EC_FLAGS_NO_WDATA_GPE, &ec->flags); | ||
181 | } else { | 205 | } else { |
182 | /* missing GPEs, switch back to poll mode */ | 206 | /* missing GPEs, switch back to poll mode */ |
183 | printk(KERN_INFO PREFIX "missing IBF_1 confirmations," | 207 | if (printk_ratelimit()) |
184 | "switch off interrupt mode.\n"); | 208 | pr_info(PREFIX "missing confirmations, " |
209 | "switch off interrupt mode.\n"); | ||
185 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); | 210 | clear_bit(EC_FLAGS_GPE_MODE, &ec->flags); |
186 | } | 211 | } |
187 | return 0; | 212 | goto end; |
188 | } | 213 | } |
189 | } else { | 214 | } else { |
190 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); | 215 | unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY); |
191 | clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); | 216 | clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); |
192 | while (time_before(jiffies, delay)) { | 217 | while (time_before(jiffies, delay)) { |
193 | if (acpi_ec_check_status(ec, event)) | 218 | if (acpi_ec_check_status(ec, event)) |
194 | return 0; | 219 | goto end; |
195 | } | 220 | } |
196 | } | 221 | } |
197 | printk(KERN_ERR PREFIX "acpi_ec_wait timeout," | 222 | pr_err(PREFIX "acpi_ec_wait timeout," |
198 | " status = %d, expect_event = %d\n", | 223 | " status = %d, expect_event = %d\n", |
199 | acpi_ec_read_status(ec), event); | 224 | acpi_ec_read_status(ec), event); |
200 | return -ETIME; | 225 | ret = -ETIME; |
226 | end: | ||
227 | clear_bit(EC_FLAGS_ADDRESS, &ec->flags); | ||
228 | return ret; | ||
201 | } | 229 | } |
202 | 230 | ||
203 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, | 231 | static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, |
@@ -208,22 +236,26 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, | |||
208 | int result = 0; | 236 | int result = 0; |
209 | set_bit(EC_FLAGS_WAIT_GPE, &ec->flags); | 237 | set_bit(EC_FLAGS_WAIT_GPE, &ec->flags); |
210 | acpi_ec_write_cmd(ec, command); | 238 | acpi_ec_write_cmd(ec, command); |
211 | 239 | pr_debug(PREFIX "transaction start\n"); | |
212 | for (; wdata_len > 0; --wdata_len) { | 240 | for (; wdata_len > 0; --wdata_len) { |
213 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll); | 241 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll); |
214 | if (result) { | 242 | if (result) { |
215 | printk(KERN_ERR PREFIX | 243 | pr_err(PREFIX |
216 | "write_cmd timeout, command = %d\n", command); | 244 | "write_cmd timeout, command = %d\n", command); |
217 | goto end; | 245 | goto end; |
218 | } | 246 | } |
247 | /* mark the address byte written to EC */ | ||
248 | if (rdata_len + wdata_len > 1) | ||
249 | set_bit(EC_FLAGS_ADDRESS, &ec->flags); | ||
219 | set_bit(EC_FLAGS_WAIT_GPE, &ec->flags); | 250 | set_bit(EC_FLAGS_WAIT_GPE, &ec->flags); |
220 | acpi_ec_write_data(ec, *(wdata++)); | 251 | acpi_ec_write_data(ec, *(wdata++)); |
221 | } | 252 | } |
222 | 253 | ||
223 | if (!rdata_len) { | 254 | if (!rdata_len) { |
255 | set_bit(EC_FLAGS_WDATA, &ec->flags); | ||
224 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll); | 256 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll); |
225 | if (result) { | 257 | if (result) { |
226 | printk(KERN_ERR PREFIX | 258 | pr_err(PREFIX |
227 | "finish-write timeout, command = %d\n", command); | 259 | "finish-write timeout, command = %d\n", command); |
228 | goto end; | 260 | goto end; |
229 | } | 261 | } |
@@ -231,12 +263,9 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, | |||
231 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | 263 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
232 | 264 | ||
233 | for (; rdata_len > 0; --rdata_len) { | 265 | for (; rdata_len > 0; --rdata_len) { |
234 | if (test_bit(EC_FLAGS_ONLY_IBF_GPE, &ec->flags)) | ||
235 | force_poll = 1; | ||
236 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1, force_poll); | 266 | result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1, force_poll); |
237 | if (result) { | 267 | if (result) { |
238 | printk(KERN_ERR PREFIX "read timeout, command = %d\n", | 268 | pr_err(PREFIX "read timeout, command = %d\n", command); |
239 | command); | ||
240 | goto end; | 269 | goto end; |
241 | } | 270 | } |
242 | /* Don't expect GPE after last read */ | 271 | /* Don't expect GPE after last read */ |
@@ -245,6 +274,7 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command, | |||
245 | *(rdata++) = acpi_ec_read_data(ec); | 274 | *(rdata++) = acpi_ec_read_data(ec); |
246 | } | 275 | } |
247 | end: | 276 | end: |
277 | pr_debug(PREFIX "transaction end\n"); | ||
248 | return result; | 278 | return result; |
249 | } | 279 | } |
250 | 280 | ||
@@ -273,8 +303,8 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command, | |||
273 | 303 | ||
274 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0); | 304 | status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0); |
275 | if (status) { | 305 | if (status) { |
276 | printk(KERN_ERR PREFIX | 306 | pr_err(PREFIX "input buffer is not empty, " |
277 | "input buffer is not empty, aborting transaction\n"); | 307 | "aborting transaction\n"); |
278 | goto end; | 308 | goto end; |
279 | } | 309 | } |
280 | 310 | ||
@@ -488,6 +518,7 @@ static u32 acpi_ec_gpe_handler(void *data) | |||
488 | acpi_status status = AE_OK; | 518 | acpi_status status = AE_OK; |
489 | struct acpi_ec *ec = data; | 519 | struct acpi_ec *ec = data; |
490 | 520 | ||
521 | pr_debug(PREFIX "~~~> interrupt\n"); | ||
491 | clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); | 522 | clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); |
492 | if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) | 523 | if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) |
493 | wake_up(&ec->wait); | 524 | wake_up(&ec->wait); |
@@ -498,8 +529,9 @@ static u32 acpi_ec_gpe_handler(void *data) | |||
498 | acpi_ec_gpe_query, ec); | 529 | acpi_ec_gpe_query, ec); |
499 | } else if (unlikely(!test_bit(EC_FLAGS_GPE_MODE, &ec->flags))) { | 530 | } else if (unlikely(!test_bit(EC_FLAGS_GPE_MODE, &ec->flags))) { |
500 | /* this is non-query, must be confirmation */ | 531 | /* this is non-query, must be confirmation */ |
501 | printk(KERN_INFO PREFIX "non-query interrupt received," | 532 | if (printk_ratelimit()) |
502 | " switching to interrupt mode\n"); | 533 | pr_info(PREFIX "non-query interrupt received," |
534 | " switching to interrupt mode\n"); | ||
503 | set_bit(EC_FLAGS_GPE_MODE, &ec->flags); | 535 | set_bit(EC_FLAGS_GPE_MODE, &ec->flags); |
504 | } | 536 | } |
505 | 537 | ||
@@ -701,10 +733,10 @@ static void ec_remove_handlers(struct acpi_ec *ec) | |||
701 | { | 733 | { |
702 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, | 734 | if (ACPI_FAILURE(acpi_remove_address_space_handler(ec->handle, |
703 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) | 735 | ACPI_ADR_SPACE_EC, &acpi_ec_space_handler))) |
704 | printk(KERN_ERR PREFIX "failed to remove space handler\n"); | 736 | pr_err(PREFIX "failed to remove space handler\n"); |
705 | if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe, | 737 | if (ACPI_FAILURE(acpi_remove_gpe_handler(NULL, ec->gpe, |
706 | &acpi_ec_gpe_handler))) | 738 | &acpi_ec_gpe_handler))) |
707 | printk(KERN_ERR PREFIX "failed to remove gpe handler\n"); | 739 | pr_err(PREFIX "failed to remove gpe handler\n"); |
708 | ec->handlers_installed = 0; | 740 | ec->handlers_installed = 0; |
709 | } | 741 | } |
710 | 742 | ||
@@ -747,9 +779,9 @@ static int acpi_ec_add(struct acpi_device *device) | |||
747 | first_ec = ec; | 779 | first_ec = ec; |
748 | acpi_driver_data(device) = ec; | 780 | acpi_driver_data(device) = ec; |
749 | acpi_ec_add_fs(device); | 781 | acpi_ec_add_fs(device); |
750 | printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", | 782 | pr_info(PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", |
751 | ec->gpe, ec->command_addr, ec->data_addr); | 783 | ec->gpe, ec->command_addr, ec->data_addr); |
752 | printk(KERN_INFO PREFIX "driver started in %s mode\n", | 784 | pr_info(PREFIX "driver started in %s mode\n", |
753 | (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))?"interrupt":"poll"); | 785 | (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))?"interrupt":"poll"); |
754 | return 0; | 786 | return 0; |
755 | } | 787 | } |
@@ -875,18 +907,26 @@ int __init acpi_ec_ecdt_probe(void) | |||
875 | status = acpi_get_table(ACPI_SIG_ECDT, 1, | 907 | status = acpi_get_table(ACPI_SIG_ECDT, 1, |
876 | (struct acpi_table_header **)&ecdt_ptr); | 908 | (struct acpi_table_header **)&ecdt_ptr); |
877 | if (ACPI_SUCCESS(status)) { | 909 | if (ACPI_SUCCESS(status)) { |
878 | printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n"); | 910 | pr_info(PREFIX "EC description table is found, configuring boot EC\n"); |
879 | boot_ec->command_addr = ecdt_ptr->control.address; | 911 | boot_ec->command_addr = ecdt_ptr->control.address; |
880 | boot_ec->data_addr = ecdt_ptr->data.address; | 912 | boot_ec->data_addr = ecdt_ptr->data.address; |
881 | boot_ec->gpe = ecdt_ptr->gpe; | 913 | boot_ec->gpe = ecdt_ptr->gpe; |
882 | boot_ec->handle = ACPI_ROOT_OBJECT; | 914 | boot_ec->handle = ACPI_ROOT_OBJECT; |
883 | } else { | 915 | } else { |
916 | /* This workaround is needed only on some broken machines, | ||
917 | * which require early EC, but fail to provide ECDT */ | ||
918 | acpi_handle x; | ||
884 | printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); | 919 | printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); |
885 | status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, | 920 | status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, |
886 | boot_ec, NULL); | 921 | boot_ec, NULL); |
887 | /* Check that acpi_get_devices actually find something */ | 922 | /* Check that acpi_get_devices actually find something */ |
888 | if (ACPI_FAILURE(status) || !boot_ec->handle) | 923 | if (ACPI_FAILURE(status) || !boot_ec->handle) |
889 | goto error; | 924 | goto error; |
925 | /* We really need to limit this workaround, the only ASUS, | ||
926 | * which needs it, has fake EC._INI method, so use it as flag. | ||
927 | */ | ||
928 | if (ACPI_FAILURE(acpi_get_handle(boot_ec->handle, "_INI", &x))) | ||
929 | goto error; | ||
890 | } | 930 | } |
891 | 931 | ||
892 | ret = ec_install_handlers(boot_ec); | 932 | ret = ec_install_handlers(boot_ec); |
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index e93318bb029e..e48ee4f8749f 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c | |||
@@ -494,7 +494,7 @@ static int get_cpu_id(acpi_handle handle, u32 acpi_id) | |||
494 | if (apic_id == -1) | 494 | if (apic_id == -1) |
495 | return apic_id; | 495 | return apic_id; |
496 | 496 | ||
497 | for (i = 0; i < NR_CPUS; ++i) { | 497 | for_each_possible_cpu(i) { |
498 | if (cpu_physical_id(i) == apic_id) | 498 | if (cpu_physical_id(i) == apic_id) |
499 | return i; | 499 | return i; |
500 | } | 500 | } |
@@ -632,7 +632,7 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device) | |||
632 | return 0; | 632 | return 0; |
633 | } | 633 | } |
634 | 634 | ||
635 | BUG_ON((pr->id >= NR_CPUS) || (pr->id < 0)); | 635 | BUG_ON((pr->id >= nr_cpu_ids) || (pr->id < 0)); |
636 | 636 | ||
637 | /* | 637 | /* |
638 | * Buggy BIOS check | 638 | * Buggy BIOS check |
@@ -641,7 +641,7 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device) | |||
641 | */ | 641 | */ |
642 | if (processor_device_array[pr->id] != NULL && | 642 | if (processor_device_array[pr->id] != NULL && |
643 | processor_device_array[pr->id] != device) { | 643 | processor_device_array[pr->id] != device) { |
644 | printk(KERN_WARNING "BIOS reported wrong ACPI id" | 644 | printk(KERN_WARNING "BIOS reported wrong ACPI id " |
645 | "for the processor\n"); | 645 | "for the processor\n"); |
646 | return -ENODEV; | 646 | return -ENODEV; |
647 | } | 647 | } |
@@ -684,7 +684,7 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data) | |||
684 | { | 684 | { |
685 | struct acpi_processor *pr = data; | 685 | struct acpi_processor *pr = data; |
686 | struct acpi_device *device = NULL; | 686 | struct acpi_device *device = NULL; |
687 | 687 | int saved; | |
688 | 688 | ||
689 | if (!pr) | 689 | if (!pr) |
690 | return; | 690 | return; |
@@ -694,7 +694,10 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data) | |||
694 | 694 | ||
695 | switch (event) { | 695 | switch (event) { |
696 | case ACPI_PROCESSOR_NOTIFY_PERFORMANCE: | 696 | case ACPI_PROCESSOR_NOTIFY_PERFORMANCE: |
697 | saved = pr->performance_platform_limit; | ||
697 | acpi_processor_ppc_has_changed(pr); | 698 | acpi_processor_ppc_has_changed(pr); |
699 | if (saved == pr->performance_platform_limit) | ||
700 | break; | ||
698 | acpi_bus_generate_proc_event(device, event, | 701 | acpi_bus_generate_proc_event(device, event, |
699 | pr->performance_platform_limit); | 702 | pr->performance_platform_limit); |
700 | acpi_bus_generate_netlink_event(device->pnp.device_class, | 703 | acpi_bus_generate_netlink_event(device->pnp.device_class, |
@@ -771,7 +774,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type) | |||
771 | 774 | ||
772 | pr = acpi_driver_data(device); | 775 | pr = acpi_driver_data(device); |
773 | 776 | ||
774 | if (pr->id >= NR_CPUS) { | 777 | if (pr->id >= nr_cpu_ids) { |
775 | kfree(pr); | 778 | kfree(pr); |
776 | return 0; | 779 | return 0; |
777 | } | 780 | } |
@@ -842,7 +845,7 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device) | |||
842 | if (!pr) | 845 | if (!pr) |
843 | return -ENODEV; | 846 | return -ENODEV; |
844 | 847 | ||
845 | if ((pr->id >= 0) && (pr->id < NR_CPUS)) { | 848 | if ((pr->id >= 0) && (pr->id < nr_cpu_ids)) { |
846 | kobject_uevent(&(*device)->dev.kobj, KOBJ_ONLINE); | 849 | kobject_uevent(&(*device)->dev.kobj, KOBJ_ONLINE); |
847 | } | 850 | } |
848 | return 0; | 851 | return 0; |
@@ -880,13 +883,13 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data) | |||
880 | break; | 883 | break; |
881 | } | 884 | } |
882 | 885 | ||
883 | if (pr->id >= 0 && (pr->id < NR_CPUS)) { | 886 | if (pr->id >= 0 && (pr->id < nr_cpu_ids)) { |
884 | kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); | 887 | kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); |
885 | break; | 888 | break; |
886 | } | 889 | } |
887 | 890 | ||
888 | result = acpi_processor_start(device); | 891 | result = acpi_processor_start(device); |
889 | if ((!result) && ((pr->id >= 0) && (pr->id < NR_CPUS))) { | 892 | if ((!result) && ((pr->id >= 0) && (pr->id < nr_cpu_ids))) { |
890 | kobject_uevent(&device->dev.kobj, KOBJ_ONLINE); | 893 | kobject_uevent(&device->dev.kobj, KOBJ_ONLINE); |
891 | } else { | 894 | } else { |
892 | printk(KERN_ERR PREFIX "Device [%s] failed to start\n", | 895 | printk(KERN_ERR PREFIX "Device [%s] failed to start\n", |
@@ -909,7 +912,7 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data) | |||
909 | return; | 912 | return; |
910 | } | 913 | } |
911 | 914 | ||
912 | if ((pr->id < NR_CPUS) && (cpu_present(pr->id))) | 915 | if ((pr->id < nr_cpu_ids) && (cpu_present(pr->id))) |
913 | kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); | 916 | kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); |
914 | break; | 917 | break; |
915 | default: | 918 | default: |
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index f996d0e37689..b1fbee3f7fe1 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c | |||
@@ -197,6 +197,19 @@ static inline u32 ticks_elapsed_in_us(u32 t1, u32 t2) | |||
197 | return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2); | 197 | return PM_TIMER_TICKS_TO_US((0xFFFFFFFF - t1) + t2); |
198 | } | 198 | } |
199 | 199 | ||
200 | static void acpi_safe_halt(void) | ||
201 | { | ||
202 | current_thread_info()->status &= ~TS_POLLING; | ||
203 | /* | ||
204 | * TS_POLLING-cleared state must be visible before we | ||
205 | * test NEED_RESCHED: | ||
206 | */ | ||
207 | smp_mb(); | ||
208 | if (!need_resched()) | ||
209 | safe_halt(); | ||
210 | current_thread_info()->status |= TS_POLLING; | ||
211 | } | ||
212 | |||
200 | #ifndef CONFIG_CPU_IDLE | 213 | #ifndef CONFIG_CPU_IDLE |
201 | 214 | ||
202 | static void | 215 | static void |
@@ -239,19 +252,6 @@ acpi_processor_power_activate(struct acpi_processor *pr, | |||
239 | return; | 252 | return; |
240 | } | 253 | } |
241 | 254 | ||
242 | static void acpi_safe_halt(void) | ||
243 | { | ||
244 | current_thread_info()->status &= ~TS_POLLING; | ||
245 | /* | ||
246 | * TS_POLLING-cleared state must be visible before we | ||
247 | * test NEED_RESCHED: | ||
248 | */ | ||
249 | smp_mb(); | ||
250 | if (!need_resched()) | ||
251 | safe_halt(); | ||
252 | current_thread_info()->status |= TS_POLLING; | ||
253 | } | ||
254 | |||
255 | static atomic_t c3_cpu_count; | 255 | static atomic_t c3_cpu_count; |
256 | 256 | ||
257 | /* Common C-state entry for C2, C3, .. */ | 257 | /* Common C-state entry for C2, C3, .. */ |
@@ -1373,15 +1373,7 @@ static int acpi_idle_enter_c1(struct cpuidle_device *dev, | |||
1373 | if (pr->flags.bm_check) | 1373 | if (pr->flags.bm_check) |
1374 | acpi_idle_update_bm_rld(pr, cx); | 1374 | acpi_idle_update_bm_rld(pr, cx); |
1375 | 1375 | ||
1376 | current_thread_info()->status &= ~TS_POLLING; | 1376 | acpi_safe_halt(); |
1377 | /* | ||
1378 | * TS_POLLING-cleared state must be visible before we test | ||
1379 | * NEED_RESCHED: | ||
1380 | */ | ||
1381 | smp_mb(); | ||
1382 | if (!need_resched()) | ||
1383 | safe_halt(); | ||
1384 | current_thread_info()->status |= TS_POLLING; | ||
1385 | 1377 | ||
1386 | cx->usage++; | 1378 | cx->usage++; |
1387 | 1379 | ||
@@ -1399,6 +1391,8 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
1399 | struct acpi_processor *pr; | 1391 | struct acpi_processor *pr; |
1400 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state); | 1392 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state); |
1401 | u32 t1, t2; | 1393 | u32 t1, t2; |
1394 | int sleep_ticks = 0; | ||
1395 | |||
1402 | pr = processors[smp_processor_id()]; | 1396 | pr = processors[smp_processor_id()]; |
1403 | 1397 | ||
1404 | if (unlikely(!pr)) | 1398 | if (unlikely(!pr)) |
@@ -1428,6 +1422,8 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
1428 | ACPI_FLUSH_CPU_CACHE(); | 1422 | ACPI_FLUSH_CPU_CACHE(); |
1429 | 1423 | ||
1430 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); | 1424 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); |
1425 | /* Tell the scheduler that we are going deep-idle: */ | ||
1426 | sched_clock_idle_sleep_event(); | ||
1431 | acpi_state_timer_broadcast(pr, cx, 1); | 1427 | acpi_state_timer_broadcast(pr, cx, 1); |
1432 | acpi_idle_do_entry(cx); | 1428 | acpi_idle_do_entry(cx); |
1433 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); | 1429 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); |
@@ -1436,6 +1432,10 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
1436 | /* TSC could halt in idle, so notify users */ | 1432 | /* TSC could halt in idle, so notify users */ |
1437 | mark_tsc_unstable("TSC halts in idle");; | 1433 | mark_tsc_unstable("TSC halts in idle");; |
1438 | #endif | 1434 | #endif |
1435 | sleep_ticks = ticks_elapsed(t1, t2); | ||
1436 | |||
1437 | /* Tell the scheduler how much we idled: */ | ||
1438 | sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); | ||
1439 | 1439 | ||
1440 | local_irq_enable(); | 1440 | local_irq_enable(); |
1441 | current_thread_info()->status |= TS_POLLING; | 1441 | current_thread_info()->status |= TS_POLLING; |
@@ -1443,7 +1443,7 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev, | |||
1443 | cx->usage++; | 1443 | cx->usage++; |
1444 | 1444 | ||
1445 | acpi_state_timer_broadcast(pr, cx, 0); | 1445 | acpi_state_timer_broadcast(pr, cx, 0); |
1446 | cx->time += ticks_elapsed(t1, t2); | 1446 | cx->time += sleep_ticks; |
1447 | return ticks_elapsed_in_us(t1, t2); | 1447 | return ticks_elapsed_in_us(t1, t2); |
1448 | } | 1448 | } |
1449 | 1449 | ||
@@ -1463,6 +1463,8 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
1463 | struct acpi_processor *pr; | 1463 | struct acpi_processor *pr; |
1464 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state); | 1464 | struct acpi_processor_cx *cx = cpuidle_get_statedata(state); |
1465 | u32 t1, t2; | 1465 | u32 t1, t2; |
1466 | int sleep_ticks = 0; | ||
1467 | |||
1466 | pr = processors[smp_processor_id()]; | 1468 | pr = processors[smp_processor_id()]; |
1467 | 1469 | ||
1468 | if (unlikely(!pr)) | 1470 | if (unlikely(!pr)) |
@@ -1471,6 +1473,15 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
1471 | if (acpi_idle_suspend) | 1473 | if (acpi_idle_suspend) |
1472 | return(acpi_idle_enter_c1(dev, state)); | 1474 | return(acpi_idle_enter_c1(dev, state)); |
1473 | 1475 | ||
1476 | if (acpi_idle_bm_check()) { | ||
1477 | if (dev->safe_state) { | ||
1478 | return dev->safe_state->enter(dev, dev->safe_state); | ||
1479 | } else { | ||
1480 | acpi_safe_halt(); | ||
1481 | return 0; | ||
1482 | } | ||
1483 | } | ||
1484 | |||
1474 | local_irq_disable(); | 1485 | local_irq_disable(); |
1475 | current_thread_info()->status &= ~TS_POLLING; | 1486 | current_thread_info()->status &= ~TS_POLLING; |
1476 | /* | 1487 | /* |
@@ -1485,38 +1496,45 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
1485 | return 0; | 1496 | return 0; |
1486 | } | 1497 | } |
1487 | 1498 | ||
1499 | /* Tell the scheduler that we are going deep-idle: */ | ||
1500 | sched_clock_idle_sleep_event(); | ||
1488 | /* | 1501 | /* |
1489 | * Must be done before busmaster disable as we might need to | 1502 | * Must be done before busmaster disable as we might need to |
1490 | * access HPET ! | 1503 | * access HPET ! |
1491 | */ | 1504 | */ |
1492 | acpi_state_timer_broadcast(pr, cx, 1); | 1505 | acpi_state_timer_broadcast(pr, cx, 1); |
1493 | 1506 | ||
1494 | if (acpi_idle_bm_check()) { | 1507 | acpi_idle_update_bm_rld(pr, cx); |
1495 | cx = pr->power.bm_state; | ||
1496 | |||
1497 | acpi_idle_update_bm_rld(pr, cx); | ||
1498 | |||
1499 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); | ||
1500 | acpi_idle_do_entry(cx); | ||
1501 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); | ||
1502 | } else { | ||
1503 | acpi_idle_update_bm_rld(pr, cx); | ||
1504 | 1508 | ||
1509 | /* | ||
1510 | * disable bus master | ||
1511 | * bm_check implies we need ARB_DIS | ||
1512 | * !bm_check implies we need cache flush | ||
1513 | * bm_control implies whether we can do ARB_DIS | ||
1514 | * | ||
1515 | * That leaves a case where bm_check is set and bm_control is | ||
1516 | * not set. In that case we cannot do much, we enter C3 | ||
1517 | * without doing anything. | ||
1518 | */ | ||
1519 | if (pr->flags.bm_check && pr->flags.bm_control) { | ||
1505 | spin_lock(&c3_lock); | 1520 | spin_lock(&c3_lock); |
1506 | c3_cpu_count++; | 1521 | c3_cpu_count++; |
1507 | /* Disable bus master arbitration when all CPUs are in C3 */ | 1522 | /* Disable bus master arbitration when all CPUs are in C3 */ |
1508 | if (c3_cpu_count == num_online_cpus()) | 1523 | if (c3_cpu_count == num_online_cpus()) |
1509 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); | 1524 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1); |
1510 | spin_unlock(&c3_lock); | 1525 | spin_unlock(&c3_lock); |
1526 | } else if (!pr->flags.bm_check) { | ||
1527 | ACPI_FLUSH_CPU_CACHE(); | ||
1528 | } | ||
1511 | 1529 | ||
1512 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); | 1530 | t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); |
1513 | acpi_idle_do_entry(cx); | 1531 | acpi_idle_do_entry(cx); |
1514 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); | 1532 | t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); |
1515 | 1533 | ||
1534 | /* Re-enable bus master arbitration */ | ||
1535 | if (pr->flags.bm_check && pr->flags.bm_control) { | ||
1516 | spin_lock(&c3_lock); | 1536 | spin_lock(&c3_lock); |
1517 | /* Re-enable bus master arbitration */ | 1537 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); |
1518 | if (c3_cpu_count == num_online_cpus()) | ||
1519 | acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); | ||
1520 | c3_cpu_count--; | 1538 | c3_cpu_count--; |
1521 | spin_unlock(&c3_lock); | 1539 | spin_unlock(&c3_lock); |
1522 | } | 1540 | } |
@@ -1525,6 +1543,9 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
1525 | /* TSC could halt in idle, so notify users */ | 1543 | /* TSC could halt in idle, so notify users */ |
1526 | mark_tsc_unstable("TSC halts in idle"); | 1544 | mark_tsc_unstable("TSC halts in idle"); |
1527 | #endif | 1545 | #endif |
1546 | sleep_ticks = ticks_elapsed(t1, t2); | ||
1547 | /* Tell the scheduler how much we idled: */ | ||
1548 | sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); | ||
1528 | 1549 | ||
1529 | local_irq_enable(); | 1550 | local_irq_enable(); |
1530 | current_thread_info()->status |= TS_POLLING; | 1551 | current_thread_info()->status |= TS_POLLING; |
@@ -1532,7 +1553,7 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev, | |||
1532 | cx->usage++; | 1553 | cx->usage++; |
1533 | 1554 | ||
1534 | acpi_state_timer_broadcast(pr, cx, 0); | 1555 | acpi_state_timer_broadcast(pr, cx, 0); |
1535 | cx->time += ticks_elapsed(t1, t2); | 1556 | cx->time += sleep_ticks; |
1536 | return ticks_elapsed_in_us(t1, t2); | 1557 | return ticks_elapsed_in_us(t1, t2); |
1537 | } | 1558 | } |
1538 | 1559 | ||
@@ -1584,12 +1605,14 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) | |||
1584 | case ACPI_STATE_C1: | 1605 | case ACPI_STATE_C1: |
1585 | state->flags |= CPUIDLE_FLAG_SHALLOW; | 1606 | state->flags |= CPUIDLE_FLAG_SHALLOW; |
1586 | state->enter = acpi_idle_enter_c1; | 1607 | state->enter = acpi_idle_enter_c1; |
1608 | dev->safe_state = state; | ||
1587 | break; | 1609 | break; |
1588 | 1610 | ||
1589 | case ACPI_STATE_C2: | 1611 | case ACPI_STATE_C2: |
1590 | state->flags |= CPUIDLE_FLAG_BALANCED; | 1612 | state->flags |= CPUIDLE_FLAG_BALANCED; |
1591 | state->flags |= CPUIDLE_FLAG_TIME_VALID; | 1613 | state->flags |= CPUIDLE_FLAG_TIME_VALID; |
1592 | state->enter = acpi_idle_enter_simple; | 1614 | state->enter = acpi_idle_enter_simple; |
1615 | dev->safe_state = state; | ||
1593 | break; | 1616 | break; |
1594 | 1617 | ||
1595 | case ACPI_STATE_C3: | 1618 | case ACPI_STATE_C3: |
@@ -1610,14 +1633,6 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr) | |||
1610 | if (!count) | 1633 | if (!count) |
1611 | return -EINVAL; | 1634 | return -EINVAL; |
1612 | 1635 | ||
1613 | /* find the deepest state that can handle active BM */ | ||
1614 | if (pr->flags.bm_check) { | ||
1615 | for (i = 1; i < ACPI_PROCESSOR_MAX_POWER && i <= max_cstate; i++) | ||
1616 | if (pr->power.states[i].type == ACPI_STATE_C3) | ||
1617 | break; | ||
1618 | pr->power.bm_state = &pr->power.states[i-1]; | ||
1619 | } | ||
1620 | |||
1621 | return 0; | 1636 | return 0; |
1622 | } | 1637 | } |
1623 | 1638 | ||
@@ -1658,6 +1673,7 @@ int __cpuinit acpi_processor_power_init(struct acpi_processor *pr, | |||
1658 | 1673 | ||
1659 | if (!first_run) { | 1674 | if (!first_run) { |
1660 | dmi_check_system(processor_power_dmi_table); | 1675 | dmi_check_system(processor_power_dmi_table); |
1676 | max_cstate = acpi_processor_cstate_check(max_cstate); | ||
1661 | if (max_cstate < ACPI_C_STATES_MAX) | 1677 | if (max_cstate < ACPI_C_STATES_MAX) |
1662 | printk(KERN_NOTICE | 1678 | printk(KERN_NOTICE |
1663 | "ACPI: processor limited to max C-state %d\n", | 1679 | "ACPI: processor limited to max C-state %d\n", |
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 90fd09c65f95..6045cdbe176b 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include <linux/moduleparam.h> | 29 | #include <linux/moduleparam.h> |
30 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
31 | 31 | ||
32 | #ifdef CONFIG_ACPI_PROCFS | 32 | #ifdef CONFIG_ACPI_PROCFS_POWER |
33 | #include <linux/proc_fs.h> | 33 | #include <linux/proc_fs.h> |
34 | #include <linux/seq_file.h> | 34 | #include <linux/seq_file.h> |
35 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
@@ -88,7 +88,7 @@ MODULE_DEVICE_TABLE(acpi, sbs_device_ids); | |||
88 | struct acpi_battery { | 88 | struct acpi_battery { |
89 | struct power_supply bat; | 89 | struct power_supply bat; |
90 | struct acpi_sbs *sbs; | 90 | struct acpi_sbs *sbs; |
91 | #ifdef CONFIG_ACPI_PROCFS | 91 | #ifdef CONFIG_ACPI_PROCFS_POWER |
92 | struct proc_dir_entry *proc_entry; | 92 | struct proc_dir_entry *proc_entry; |
93 | #endif | 93 | #endif |
94 | unsigned long update_time; | 94 | unsigned long update_time; |
@@ -113,6 +113,7 @@ struct acpi_battery { | |||
113 | u16 spec; | 113 | u16 spec; |
114 | u8 id; | 114 | u8 id; |
115 | u8 present:1; | 115 | u8 present:1; |
116 | u8 have_sysfs_alarm:1; | ||
116 | }; | 117 | }; |
117 | 118 | ||
118 | #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); | 119 | #define to_acpi_battery(x) container_of(x, struct acpi_battery, bat); |
@@ -122,7 +123,7 @@ struct acpi_sbs { | |||
122 | struct acpi_device *device; | 123 | struct acpi_device *device; |
123 | struct acpi_smb_hc *hc; | 124 | struct acpi_smb_hc *hc; |
124 | struct mutex lock; | 125 | struct mutex lock; |
125 | #ifdef CONFIG_ACPI_PROCFS | 126 | #ifdef CONFIG_ACPI_PROCFS_POWER |
126 | struct proc_dir_entry *charger_entry; | 127 | struct proc_dir_entry *charger_entry; |
127 | #endif | 128 | #endif |
128 | struct acpi_battery battery[MAX_SBS_BAT]; | 129 | struct acpi_battery battery[MAX_SBS_BAT]; |
@@ -468,7 +469,7 @@ static struct device_attribute alarm_attr = { | |||
468 | FS Interface (/proc/acpi) | 469 | FS Interface (/proc/acpi) |
469 | -------------------------------------------------------------------------- */ | 470 | -------------------------------------------------------------------------- */ |
470 | 471 | ||
471 | #ifdef CONFIG_ACPI_PROCFS | 472 | #ifdef CONFIG_ACPI_PROCFS_POWER |
472 | /* Generic Routines */ | 473 | /* Generic Routines */ |
473 | static int | 474 | static int |
474 | acpi_sbs_add_fs(struct proc_dir_entry **dir, | 475 | acpi_sbs_add_fs(struct proc_dir_entry **dir, |
@@ -789,7 +790,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) | |||
789 | return result; | 790 | return result; |
790 | 791 | ||
791 | sprintf(battery->name, ACPI_BATTERY_DIR_NAME, id); | 792 | sprintf(battery->name, ACPI_BATTERY_DIR_NAME, id); |
792 | #ifdef CONFIG_ACPI_PROCFS | 793 | #ifdef CONFIG_ACPI_PROCFS_POWER |
793 | acpi_sbs_add_fs(&battery->proc_entry, acpi_battery_dir, | 794 | acpi_sbs_add_fs(&battery->proc_entry, acpi_battery_dir, |
794 | battery->name, &acpi_battery_info_fops, | 795 | battery->name, &acpi_battery_info_fops, |
795 | &acpi_battery_state_fops, &acpi_battery_alarm_fops, | 796 | &acpi_battery_state_fops, &acpi_battery_alarm_fops, |
@@ -808,7 +809,13 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) | |||
808 | } | 809 | } |
809 | battery->bat.get_property = acpi_sbs_battery_get_property; | 810 | battery->bat.get_property = acpi_sbs_battery_get_property; |
810 | result = power_supply_register(&sbs->device->dev, &battery->bat); | 811 | result = power_supply_register(&sbs->device->dev, &battery->bat); |
811 | device_create_file(battery->bat.dev, &alarm_attr); | 812 | if (result) |
813 | goto end; | ||
814 | result = device_create_file(battery->bat.dev, &alarm_attr); | ||
815 | if (result) | ||
816 | goto end; | ||
817 | battery->have_sysfs_alarm = 1; | ||
818 | end: | ||
812 | printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n", | 819 | printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n", |
813 | ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), | 820 | ACPI_SBS_DEVICE_NAME, acpi_device_bid(sbs->device), |
814 | battery->name, sbs->battery->present ? "present" : "absent"); | 821 | battery->name, sbs->battery->present ? "present" : "absent"); |
@@ -817,14 +824,16 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) | |||
817 | 824 | ||
818 | static void acpi_battery_remove(struct acpi_sbs *sbs, int id) | 825 | static void acpi_battery_remove(struct acpi_sbs *sbs, int id) |
819 | { | 826 | { |
820 | if (sbs->battery[id].bat.dev) | 827 | struct acpi_battery *battery = &sbs->battery[id]; |
821 | device_remove_file(sbs->battery[id].bat.dev, &alarm_attr); | 828 | |
822 | power_supply_unregister(&sbs->battery[id].bat); | 829 | if (battery->bat.dev) { |
823 | #ifdef CONFIG_ACPI_PROCFS | 830 | if (battery->have_sysfs_alarm) |
824 | if (sbs->battery[id].proc_entry) { | 831 | device_remove_file(battery->bat.dev, &alarm_attr); |
825 | acpi_sbs_remove_fs(&(sbs->battery[id].proc_entry), | 832 | power_supply_unregister(&battery->bat); |
826 | acpi_battery_dir); | ||
827 | } | 833 | } |
834 | #ifdef CONFIG_ACPI_PROCFS_POWER | ||
835 | if (battery->proc_entry) | ||
836 | acpi_sbs_remove_fs(&battery->proc_entry, acpi_battery_dir); | ||
828 | #endif | 837 | #endif |
829 | } | 838 | } |
830 | 839 | ||
@@ -835,7 +844,7 @@ static int acpi_charger_add(struct acpi_sbs *sbs) | |||
835 | result = acpi_ac_get_present(sbs); | 844 | result = acpi_ac_get_present(sbs); |
836 | if (result) | 845 | if (result) |
837 | goto end; | 846 | goto end; |
838 | #ifdef CONFIG_ACPI_PROCFS | 847 | #ifdef CONFIG_ACPI_PROCFS_POWER |
839 | result = acpi_sbs_add_fs(&sbs->charger_entry, acpi_ac_dir, | 848 | result = acpi_sbs_add_fs(&sbs->charger_entry, acpi_ac_dir, |
840 | ACPI_AC_DIR_NAME, NULL, | 849 | ACPI_AC_DIR_NAME, NULL, |
841 | &acpi_ac_state_fops, NULL, sbs); | 850 | &acpi_ac_state_fops, NULL, sbs); |
@@ -859,7 +868,7 @@ static void acpi_charger_remove(struct acpi_sbs *sbs) | |||
859 | { | 868 | { |
860 | if (sbs->charger.dev) | 869 | if (sbs->charger.dev) |
861 | power_supply_unregister(&sbs->charger); | 870 | power_supply_unregister(&sbs->charger); |
862 | #ifdef CONFIG_ACPI_PROCFS | 871 | #ifdef CONFIG_ACPI_PROCFS_POWER |
863 | if (sbs->charger_entry) | 872 | if (sbs->charger_entry) |
864 | acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir); | 873 | acpi_sbs_remove_fs(&sbs->charger_entry, acpi_ac_dir); |
865 | #endif | 874 | #endif |
@@ -965,7 +974,7 @@ static int acpi_sbs_remove(struct acpi_device *device, int type) | |||
965 | 974 | ||
966 | static void acpi_sbs_rmdirs(void) | 975 | static void acpi_sbs_rmdirs(void) |
967 | { | 976 | { |
968 | #ifdef CONFIG_ACPI_PROCFS | 977 | #ifdef CONFIG_ACPI_PROCFS_POWER |
969 | if (acpi_ac_dir) { | 978 | if (acpi_ac_dir) { |
970 | acpi_unlock_ac_dir(acpi_ac_dir); | 979 | acpi_unlock_ac_dir(acpi_ac_dir); |
971 | acpi_ac_dir = NULL; | 980 | acpi_ac_dir = NULL; |
@@ -1004,7 +1013,7 @@ static int __init acpi_sbs_init(void) | |||
1004 | 1013 | ||
1005 | if (acpi_disabled) | 1014 | if (acpi_disabled) |
1006 | return -ENODEV; | 1015 | return -ENODEV; |
1007 | #ifdef CONFIG_ACPI_PROCFS | 1016 | #ifdef CONFIG_ACPI_PROCFS_POWER |
1008 | acpi_ac_dir = acpi_lock_ac_dir(); | 1017 | acpi_ac_dir = acpi_lock_ac_dir(); |
1009 | if (!acpi_ac_dir) | 1018 | if (!acpi_ac_dir) |
1010 | return -ENODEV; | 1019 | return -ENODEV; |
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c index 5f1d85f2ffe4..010f19652f80 100644 --- a/drivers/acpi/tables/tbutils.c +++ b/drivers/acpi/tables/tbutils.c | |||
@@ -449,7 +449,7 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) | |||
449 | /* XSDT has NULL entry, RSDT is used */ | 449 | /* XSDT has NULL entry, RSDT is used */ |
450 | address = rsdt_address; | 450 | address = rsdt_address; |
451 | table_entry_size = sizeof(u32); | 451 | table_entry_size = sizeof(u32); |
452 | ACPI_WARNING((AE_INFO, "BIOS XSDT has NULL entry," | 452 | ACPI_WARNING((AE_INFO, "BIOS XSDT has NULL entry, " |
453 | "using RSDT")); | 453 | "using RSDT")); |
454 | } | 454 | } |
455 | } | 455 | } |
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index bac956b30c57..44a0d9ba9bd6 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <linux/list.h> | 31 | #include <linux/list.h> |
32 | #include <linux/mutex.h> | ||
32 | #include <linux/proc_fs.h> | 33 | #include <linux/proc_fs.h> |
33 | #include <linux/seq_file.h> | 34 | #include <linux/seq_file.h> |
34 | #include <linux/input.h> | 35 | #include <linux/input.h> |
@@ -135,8 +136,8 @@ struct acpi_video_bus { | |||
135 | u8 attached_count; | 136 | u8 attached_count; |
136 | struct acpi_video_bus_cap cap; | 137 | struct acpi_video_bus_cap cap; |
137 | struct acpi_video_bus_flags flags; | 138 | struct acpi_video_bus_flags flags; |
138 | struct semaphore sem; | ||
139 | struct list_head video_device_list; | 139 | struct list_head video_device_list; |
140 | struct mutex device_list_lock; /* protects video_device_list */ | ||
140 | struct proc_dir_entry *dir; | 141 | struct proc_dir_entry *dir; |
141 | struct input_dev *input; | 142 | struct input_dev *input; |
142 | char phys[32]; /* for input device */ | 143 | char phys[32]; /* for input device */ |
@@ -896,7 +897,7 @@ acpi_video_device_write_brightness(struct file *file, | |||
896 | { | 897 | { |
897 | struct seq_file *m = file->private_data; | 898 | struct seq_file *m = file->private_data; |
898 | struct acpi_video_device *dev = m->private; | 899 | struct acpi_video_device *dev = m->private; |
899 | char str[4] = { 0 }; | 900 | char str[5] = { 0 }; |
900 | unsigned int level = 0; | 901 | unsigned int level = 0; |
901 | int i; | 902 | int i; |
902 | 903 | ||
@@ -1436,9 +1437,9 @@ acpi_video_bus_get_one_device(struct acpi_device *device, | |||
1436 | return -ENODEV; | 1437 | return -ENODEV; |
1437 | } | 1438 | } |
1438 | 1439 | ||
1439 | down(&video->sem); | 1440 | mutex_lock(&video->device_list_lock); |
1440 | list_add_tail(&data->entry, &video->video_device_list); | 1441 | list_add_tail(&data->entry, &video->video_device_list); |
1441 | up(&video->sem); | 1442 | mutex_unlock(&video->device_list_lock); |
1442 | 1443 | ||
1443 | acpi_video_device_add_fs(device); | 1444 | acpi_video_device_add_fs(device); |
1444 | 1445 | ||
@@ -1462,12 +1463,14 @@ acpi_video_bus_get_one_device(struct acpi_device *device, | |||
1462 | 1463 | ||
1463 | static void acpi_video_device_rebind(struct acpi_video_bus *video) | 1464 | static void acpi_video_device_rebind(struct acpi_video_bus *video) |
1464 | { | 1465 | { |
1465 | struct list_head *node, *next; | 1466 | struct acpi_video_device *dev; |
1466 | list_for_each_safe(node, next, &video->video_device_list) { | 1467 | |
1467 | struct acpi_video_device *dev = | 1468 | mutex_lock(&video->device_list_lock); |
1468 | container_of(node, struct acpi_video_device, entry); | 1469 | |
1470 | list_for_each_entry(dev, &video->video_device_list, entry) | ||
1469 | acpi_video_device_bind(video, dev); | 1471 | acpi_video_device_bind(video, dev); |
1470 | } | 1472 | |
1473 | mutex_unlock(&video->device_list_lock); | ||
1471 | } | 1474 | } |
1472 | 1475 | ||
1473 | /* | 1476 | /* |
@@ -1592,30 +1595,33 @@ static int acpi_video_device_enumerate(struct acpi_video_bus *video) | |||
1592 | 1595 | ||
1593 | static int acpi_video_switch_output(struct acpi_video_bus *video, int event) | 1596 | static int acpi_video_switch_output(struct acpi_video_bus *video, int event) |
1594 | { | 1597 | { |
1595 | struct list_head *node, *next; | 1598 | struct list_head *node; |
1596 | struct acpi_video_device *dev = NULL; | 1599 | struct acpi_video_device *dev = NULL; |
1597 | struct acpi_video_device *dev_next = NULL; | 1600 | struct acpi_video_device *dev_next = NULL; |
1598 | struct acpi_video_device *dev_prev = NULL; | 1601 | struct acpi_video_device *dev_prev = NULL; |
1599 | unsigned long state; | 1602 | unsigned long state; |
1600 | int status = 0; | 1603 | int status = 0; |
1601 | 1604 | ||
1605 | mutex_lock(&video->device_list_lock); | ||
1602 | 1606 | ||
1603 | list_for_each_safe(node, next, &video->video_device_list) { | 1607 | list_for_each(node, &video->video_device_list) { |
1604 | dev = container_of(node, struct acpi_video_device, entry); | 1608 | dev = container_of(node, struct acpi_video_device, entry); |
1605 | status = acpi_video_device_get_state(dev, &state); | 1609 | status = acpi_video_device_get_state(dev, &state); |
1606 | if (state & 0x2) { | 1610 | if (state & 0x2) { |
1607 | dev_next = | 1611 | dev_next = container_of(node->next, |
1608 | container_of(node->next, struct acpi_video_device, | 1612 | struct acpi_video_device, entry); |
1609 | entry); | 1613 | dev_prev = container_of(node->prev, |
1610 | dev_prev = | 1614 | struct acpi_video_device, entry); |
1611 | container_of(node->prev, struct acpi_video_device, | ||
1612 | entry); | ||
1613 | goto out; | 1615 | goto out; |
1614 | } | 1616 | } |
1615 | } | 1617 | } |
1618 | |||
1616 | dev_next = container_of(node->next, struct acpi_video_device, entry); | 1619 | dev_next = container_of(node->next, struct acpi_video_device, entry); |
1617 | dev_prev = container_of(node->prev, struct acpi_video_device, entry); | 1620 | dev_prev = container_of(node->prev, struct acpi_video_device, entry); |
1618 | out: | 1621 | |
1622 | out: | ||
1623 | mutex_unlock(&video->device_list_lock); | ||
1624 | |||
1619 | switch (event) { | 1625 | switch (event) { |
1620 | case ACPI_VIDEO_NOTIFY_CYCLE: | 1626 | case ACPI_VIDEO_NOTIFY_CYCLE: |
1621 | case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: | 1627 | case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: |
@@ -1691,24 +1697,17 @@ acpi_video_bus_get_devices(struct acpi_video_bus *video, | |||
1691 | struct acpi_device *device) | 1697 | struct acpi_device *device) |
1692 | { | 1698 | { |
1693 | int status = 0; | 1699 | int status = 0; |
1694 | struct list_head *node, *next; | 1700 | struct acpi_device *dev; |
1695 | |||
1696 | 1701 | ||
1697 | acpi_video_device_enumerate(video); | 1702 | acpi_video_device_enumerate(video); |
1698 | 1703 | ||
1699 | list_for_each_safe(node, next, &device->children) { | 1704 | list_for_each_entry(dev, &device->children, node) { |
1700 | struct acpi_device *dev = | ||
1701 | list_entry(node, struct acpi_device, node); | ||
1702 | |||
1703 | if (!dev) | ||
1704 | continue; | ||
1705 | 1705 | ||
1706 | status = acpi_video_bus_get_one_device(dev, video); | 1706 | status = acpi_video_bus_get_one_device(dev, video); |
1707 | if (ACPI_FAILURE(status)) { | 1707 | if (ACPI_FAILURE(status)) { |
1708 | ACPI_EXCEPTION((AE_INFO, status, "Cant attach device")); | 1708 | ACPI_EXCEPTION((AE_INFO, status, "Cant attach device")); |
1709 | continue; | 1709 | continue; |
1710 | } | 1710 | } |
1711 | |||
1712 | } | 1711 | } |
1713 | return status; | 1712 | return status; |
1714 | } | 1713 | } |
@@ -1724,9 +1723,6 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) | |||
1724 | 1723 | ||
1725 | video = device->video; | 1724 | video = device->video; |
1726 | 1725 | ||
1727 | down(&video->sem); | ||
1728 | list_del(&device->entry); | ||
1729 | up(&video->sem); | ||
1730 | acpi_video_device_remove_fs(device->dev); | 1726 | acpi_video_device_remove_fs(device->dev); |
1731 | 1727 | ||
1732 | status = acpi_remove_notify_handler(device->dev->handle, | 1728 | status = acpi_remove_notify_handler(device->dev->handle, |
@@ -1734,32 +1730,34 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) | |||
1734 | acpi_video_device_notify); | 1730 | acpi_video_device_notify); |
1735 | backlight_device_unregister(device->backlight); | 1731 | backlight_device_unregister(device->backlight); |
1736 | video_output_unregister(device->output_dev); | 1732 | video_output_unregister(device->output_dev); |
1733 | |||
1737 | return 0; | 1734 | return 0; |
1738 | } | 1735 | } |
1739 | 1736 | ||
1740 | static int acpi_video_bus_put_devices(struct acpi_video_bus *video) | 1737 | static int acpi_video_bus_put_devices(struct acpi_video_bus *video) |
1741 | { | 1738 | { |
1742 | int status; | 1739 | int status; |
1743 | struct list_head *node, *next; | 1740 | struct acpi_video_device *dev, *next; |
1744 | 1741 | ||
1742 | mutex_lock(&video->device_list_lock); | ||
1745 | 1743 | ||
1746 | list_for_each_safe(node, next, &video->video_device_list) { | 1744 | list_for_each_entry_safe(dev, next, &video->video_device_list, entry) { |
1747 | struct acpi_video_device *data = | ||
1748 | list_entry(node, struct acpi_video_device, entry); | ||
1749 | if (!data) | ||
1750 | continue; | ||
1751 | 1745 | ||
1752 | status = acpi_video_bus_put_one_device(data); | 1746 | status = acpi_video_bus_put_one_device(dev); |
1753 | if (ACPI_FAILURE(status)) | 1747 | if (ACPI_FAILURE(status)) |
1754 | printk(KERN_WARNING PREFIX | 1748 | printk(KERN_WARNING PREFIX |
1755 | "hhuuhhuu bug in acpi video driver.\n"); | 1749 | "hhuuhhuu bug in acpi video driver.\n"); |
1756 | 1750 | ||
1757 | if (data->brightness) | 1751 | if (dev->brightness) { |
1758 | kfree(data->brightness->levels); | 1752 | kfree(dev->brightness->levels); |
1759 | kfree(data->brightness); | 1753 | kfree(dev->brightness); |
1760 | kfree(data); | 1754 | } |
1755 | list_del(&dev->entry); | ||
1756 | kfree(dev); | ||
1761 | } | 1757 | } |
1762 | 1758 | ||
1759 | mutex_unlock(&video->device_list_lock); | ||
1760 | |||
1763 | return 0; | 1761 | return 0; |
1764 | } | 1762 | } |
1765 | 1763 | ||
@@ -1782,9 +1780,6 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) | |||
1782 | struct input_dev *input; | 1780 | struct input_dev *input; |
1783 | int keycode; | 1781 | int keycode; |
1784 | 1782 | ||
1785 | |||
1786 | printk("video bus notify\n"); | ||
1787 | |||
1788 | if (!video) | 1783 | if (!video) |
1789 | return; | 1784 | return; |
1790 | 1785 | ||
@@ -1897,14 +1892,10 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) | |||
1897 | static int instance; | 1892 | static int instance; |
1898 | static int acpi_video_bus_add(struct acpi_device *device) | 1893 | static int acpi_video_bus_add(struct acpi_device *device) |
1899 | { | 1894 | { |
1900 | int result = 0; | 1895 | acpi_status status; |
1901 | acpi_status status = 0; | 1896 | struct acpi_video_bus *video; |
1902 | struct acpi_video_bus *video = NULL; | ||
1903 | struct input_dev *input; | 1897 | struct input_dev *input; |
1904 | 1898 | int error; | |
1905 | |||
1906 | if (!device) | ||
1907 | return -EINVAL; | ||
1908 | 1899 | ||
1909 | video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL); | 1900 | video = kzalloc(sizeof(struct acpi_video_bus), GFP_KERNEL); |
1910 | if (!video) | 1901 | if (!video) |
@@ -1923,15 +1914,15 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
1923 | acpi_driver_data(device) = video; | 1914 | acpi_driver_data(device) = video; |
1924 | 1915 | ||
1925 | acpi_video_bus_find_cap(video); | 1916 | acpi_video_bus_find_cap(video); |
1926 | result = acpi_video_bus_check(video); | 1917 | error = acpi_video_bus_check(video); |
1927 | if (result) | 1918 | if (error) |
1928 | goto end; | 1919 | goto err_free_video; |
1929 | 1920 | ||
1930 | result = acpi_video_bus_add_fs(device); | 1921 | error = acpi_video_bus_add_fs(device); |
1931 | if (result) | 1922 | if (error) |
1932 | goto end; | 1923 | goto err_free_video; |
1933 | 1924 | ||
1934 | init_MUTEX(&video->sem); | 1925 | mutex_init(&video->device_list_lock); |
1935 | INIT_LIST_HEAD(&video->video_device_list); | 1926 | INIT_LIST_HEAD(&video->video_device_list); |
1936 | 1927 | ||
1937 | acpi_video_bus_get_devices(video, device); | 1928 | acpi_video_bus_get_devices(video, device); |
@@ -1943,16 +1934,15 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
1943 | if (ACPI_FAILURE(status)) { | 1934 | if (ACPI_FAILURE(status)) { |
1944 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, | 1935 | ACPI_DEBUG_PRINT((ACPI_DB_ERROR, |
1945 | "Error installing notify handler\n")); | 1936 | "Error installing notify handler\n")); |
1946 | acpi_video_bus_stop_devices(video); | 1937 | error = -ENODEV; |
1947 | acpi_video_bus_put_devices(video); | 1938 | goto err_stop_video; |
1948 | kfree(video->attached_array); | ||
1949 | acpi_video_bus_remove_fs(device); | ||
1950 | result = -ENODEV; | ||
1951 | goto end; | ||
1952 | } | 1939 | } |
1953 | 1940 | ||
1954 | |||
1955 | video->input = input = input_allocate_device(); | 1941 | video->input = input = input_allocate_device(); |
1942 | if (!input) { | ||
1943 | error = -ENOMEM; | ||
1944 | goto err_uninstall_notify; | ||
1945 | } | ||
1956 | 1946 | ||
1957 | snprintf(video->phys, sizeof(video->phys), | 1947 | snprintf(video->phys, sizeof(video->phys), |
1958 | "%s/video/input0", acpi_device_hid(video->device)); | 1948 | "%s/video/input0", acpi_device_hid(video->device)); |
@@ -1961,6 +1951,7 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
1961 | input->phys = video->phys; | 1951 | input->phys = video->phys; |
1962 | input->id.bustype = BUS_HOST; | 1952 | input->id.bustype = BUS_HOST; |
1963 | input->id.product = 0x06; | 1953 | input->id.product = 0x06; |
1954 | input->dev.parent = &device->dev; | ||
1964 | input->evbit[0] = BIT(EV_KEY); | 1955 | input->evbit[0] = BIT(EV_KEY); |
1965 | set_bit(KEY_SWITCHVIDEOMODE, input->keybit); | 1956 | set_bit(KEY_SWITCHVIDEOMODE, input->keybit); |
1966 | set_bit(KEY_VIDEO_NEXT, input->keybit); | 1957 | set_bit(KEY_VIDEO_NEXT, input->keybit); |
@@ -1971,18 +1962,10 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
1971 | set_bit(KEY_BRIGHTNESS_ZERO, input->keybit); | 1962 | set_bit(KEY_BRIGHTNESS_ZERO, input->keybit); |
1972 | set_bit(KEY_DISPLAY_OFF, input->keybit); | 1963 | set_bit(KEY_DISPLAY_OFF, input->keybit); |
1973 | set_bit(KEY_UNKNOWN, input->keybit); | 1964 | set_bit(KEY_UNKNOWN, input->keybit); |
1974 | result = input_register_device(input); | ||
1975 | if (result) { | ||
1976 | acpi_remove_notify_handler(video->device->handle, | ||
1977 | ACPI_DEVICE_NOTIFY, | ||
1978 | acpi_video_bus_notify); | ||
1979 | acpi_video_bus_stop_devices(video); | ||
1980 | acpi_video_bus_put_devices(video); | ||
1981 | kfree(video->attached_array); | ||
1982 | acpi_video_bus_remove_fs(device); | ||
1983 | goto end; | ||
1984 | } | ||
1985 | 1965 | ||
1966 | error = input_register_device(input); | ||
1967 | if (error) | ||
1968 | goto err_free_input_dev; | ||
1986 | 1969 | ||
1987 | printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", | 1970 | printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", |
1988 | ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), | 1971 | ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), |
@@ -1990,11 +1973,23 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
1990 | video->flags.rom ? "yes" : "no", | 1973 | video->flags.rom ? "yes" : "no", |
1991 | video->flags.post ? "yes" : "no"); | 1974 | video->flags.post ? "yes" : "no"); |
1992 | 1975 | ||
1993 | end: | 1976 | return 0; |
1994 | if (result) | 1977 | |
1995 | kfree(video); | 1978 | err_free_input_dev: |
1979 | input_free_device(input); | ||
1980 | err_uninstall_notify: | ||
1981 | acpi_remove_notify_handler(device->handle, ACPI_DEVICE_NOTIFY, | ||
1982 | acpi_video_bus_notify); | ||
1983 | err_stop_video: | ||
1984 | acpi_video_bus_stop_devices(video); | ||
1985 | acpi_video_bus_put_devices(video); | ||
1986 | kfree(video->attached_array); | ||
1987 | acpi_video_bus_remove_fs(device); | ||
1988 | err_free_video: | ||
1989 | kfree(video); | ||
1990 | acpi_driver_data(device) = NULL; | ||
1996 | 1991 | ||
1997 | return result; | 1992 | return error; |
1998 | } | 1993 | } |
1999 | 1994 | ||
2000 | static int acpi_video_bus_remove(struct acpi_device *device, int type) | 1995 | static int acpi_video_bus_remove(struct acpi_device *device, int type) |