aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/Kconfig18
-rw-r--r--drivers/acpi/ac.c5
-rw-r--r--drivers/acpi/asus_acpi.c2
-rw-r--r--drivers/acpi/battery.c52
-rw-r--r--drivers/acpi/bus.c10
-rw-r--r--drivers/acpi/button.c2
-rw-r--r--drivers/acpi/ec.c50
-rw-r--r--drivers/acpi/event.c22
-rw-r--r--drivers/acpi/hardware/hwsleep.c19
-rw-r--r--drivers/acpi/namespace/nsxfeval.c2
-rw-r--r--drivers/acpi/processor_core.c36
-rw-r--r--drivers/acpi/processor_idle.c51
-rw-r--r--drivers/acpi/sbs.c3
-rw-r--r--drivers/acpi/scan.c5
-rw-r--r--drivers/acpi/sleep/Makefile4
-rw-r--r--drivers/acpi/sleep/main.c63
-rw-r--r--drivers/acpi/sleep/poweroff.c75
-rw-r--r--drivers/acpi/sleep/proc.c10
-rw-r--r--drivers/acpi/tables/tbutils.c71
-rw-r--r--drivers/acpi/thermal.c67
-rw-r--r--drivers/acpi/utilities/utglobal.c1
-rw-r--r--drivers/acpi/video.c112
22 files changed, 497 insertions, 183 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index f1372de4ce79..4875f0149eb4 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -68,6 +68,24 @@ config ACPI_PROCFS
68 68
69 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/
70 70
71config ACPI_PROC_EVENT
72 bool "Deprecated /proc/acpi/event support"
73 depends on PROC_FS
74 default y
75 ---help---
76 A user-space daemon, acpi, typically read /proc/acpi/event
77 and handled all ACPI sub-system generated events.
78
79 These events are now delivered to user-space via
80 either the input layer, or as netlink events.
81
82 This build option enables the old code for legacy
83 user-space implementation. After some time, this will
84 be moved under CONFIG_ACPI_PROCFS, and then deleted.
85
86 Say Y here to retain the old behaviour. Say N if your
87 user-space is newer than kernel 2.6.23 (September 2007).
88
71config ACPI_AC 89config ACPI_AC
72 tristate "AC Adapter" 90 tristate "AC Adapter"
73 depends on X86 91 depends on X86
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index d8b35093527a..26d70702b313 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -204,7 +204,10 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)
204 case ACPI_NOTIFY_BUS_CHECK: 204 case ACPI_NOTIFY_BUS_CHECK:
205 case ACPI_NOTIFY_DEVICE_CHECK: 205 case ACPI_NOTIFY_DEVICE_CHECK:
206 acpi_ac_get_state(ac); 206 acpi_ac_get_state(ac);
207 acpi_bus_generate_event(device, event, (u32) ac->state); 207 acpi_bus_generate_proc_event(device, event, (u32) ac->state);
208 acpi_bus_generate_netlink_event(device->pnp.device_class,
209 device->dev.bus_id, event,
210 (u32) ac->state);
208 break; 211 break;
209 default: 212 default:
210 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 213 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
index 86fd142f4bf3..d915fec9bf63 100644
--- a/drivers/acpi/asus_acpi.c
+++ b/drivers/acpi/asus_acpi.c
@@ -1069,7 +1069,7 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data)
1069 hotk->brightness = (event & ~((u32) BR_DOWN)); 1069 hotk->brightness = (event & ~((u32) BR_DOWN));
1070 } 1070 }
1071 1071
1072 acpi_bus_generate_event(hotk->device, event, 1072 acpi_bus_generate_proc_event(hotk->device, event,
1073 hotk->event_count[event % 128]++); 1073 hotk->event_count[event % 128]++);
1074 1074
1075 return; 1075 return;
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index d7b499fe0cd9..9b2c0f74f869 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -113,7 +113,7 @@ struct acpi_battery_info {
113 acpi_string oem_info; 113 acpi_string oem_info;
114}; 114};
115 115
116enum acpi_battery_files { 116enum acpi_battery_files{
117 ACPI_BATTERY_INFO = 0, 117 ACPI_BATTERY_INFO = 0,
118 ACPI_BATTERY_STATE, 118 ACPI_BATTERY_STATE,
119 ACPI_BATTERY_ALARM, 119 ACPI_BATTERY_ALARM,
@@ -129,14 +129,13 @@ struct acpi_battery_flags {
129}; 129};
130 130
131struct acpi_battery { 131struct acpi_battery {
132 struct mutex mutex;
132 struct acpi_device *device; 133 struct acpi_device *device;
133 struct acpi_battery_flags flags; 134 struct acpi_battery_flags flags;
134 struct acpi_buffer bif_data; 135 struct acpi_buffer bif_data;
135 struct acpi_buffer bst_data; 136 struct acpi_buffer bst_data;
136 struct mutex lock;
137 unsigned long alarm; 137 unsigned long alarm;
138 unsigned long update_time[ACPI_BATTERY_NUMFILES]; 138 unsigned long update_time[ACPI_BATTERY_NUMFILES];
139
140}; 139};
141 140
142inline int acpi_battery_present(struct acpi_battery *battery) 141inline int acpi_battery_present(struct acpi_battery *battery)
@@ -236,10 +235,10 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
236 return 0; 235 return 0;
237 236
238 /* Evaluate _BIF */ 237 /* Evaluate _BIF */
239 mutex_lock(&battery->lock); 238
240 status = acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", 239 status =
241 NULL, &buffer); 240 acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL,
242 mutex_unlock(&battery->lock); 241 &buffer);
243 if (ACPI_FAILURE(status)) { 242 if (ACPI_FAILURE(status)) {
244 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); 243 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF"));
245 return -ENODEV; 244 return -ENODEV;
@@ -286,10 +285,10 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
286 return 0; 285 return 0;
287 286
288 /* Evaluate _BST */ 287 /* Evaluate _BST */
289 mutex_lock(&battery->lock); 288
290 status = acpi_evaluate_object(acpi_battery_handle(battery), "_BST", 289 status =
291 NULL, &buffer); 290 acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL,
292 mutex_unlock(&battery->lock); 291 &buffer);
293 if (ACPI_FAILURE(status)) { 292 if (ACPI_FAILURE(status)) {
294 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); 293 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
295 return -ENODEV; 294 return -ENODEV;
@@ -337,10 +336,9 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,
337 336
338 arg0.integer.value = alarm; 337 arg0.integer.value = alarm;
339 338
340 mutex_lock(&battery->lock); 339 status =
341 status = acpi_evaluate_object(acpi_battery_handle(battery), "_BTP", 340 acpi_evaluate_object(acpi_battery_handle(battery), "_BTP",
342 &arg_list, NULL); 341 &arg_list, NULL);
343 mutex_unlock(&battery->lock);
344 if (ACPI_FAILURE(status)) 342 if (ACPI_FAILURE(status))
345 return -ENODEV; 343 return -ENODEV;
346 344
@@ -660,6 +658,8 @@ acpi_battery_write_alarm(struct file *file,
660 if (!battery || (count > sizeof(alarm_string) - 1)) 658 if (!battery || (count > sizeof(alarm_string) - 1))
661 return -EINVAL; 659 return -EINVAL;
662 660
661 mutex_lock(&battery->mutex);
662
663 result = acpi_battery_update(battery, 1, &update_result); 663 result = acpi_battery_update(battery, 1, &update_result);
664 if (result) { 664 if (result) {
665 result = -ENODEV; 665 result = -ENODEV;
@@ -688,7 +688,9 @@ acpi_battery_write_alarm(struct file *file,
688 acpi_battery_check_result(battery, result); 688 acpi_battery_check_result(battery, result);
689 689
690 if (!result) 690 if (!result)
691 return count; 691 result = count;
692
693 mutex_unlock(&battery->mutex);
692 694
693 return result; 695 return result;
694} 696}
@@ -712,6 +714,8 @@ static int acpi_battery_read(int fid, struct seq_file *seq)
712 int update_result = ACPI_BATTERY_NONE_UPDATE; 714 int update_result = ACPI_BATTERY_NONE_UPDATE;
713 int update = 0; 715 int update = 0;
714 716
717 mutex_lock(&battery->mutex);
718
715 update = (get_seconds() - battery->update_time[fid] >= update_time); 719 update = (get_seconds() - battery->update_time[fid] >= update_time);
716 update = (update | battery->flags.update[fid]); 720 update = (update | battery->flags.update[fid]);
717 721
@@ -729,6 +733,7 @@ static int acpi_battery_read(int fid, struct seq_file *seq)
729 result = acpi_read_funcs[fid].print(seq, result); 733 result = acpi_read_funcs[fid].print(seq, result);
730 acpi_battery_check_result(battery, result); 734 acpi_battery_check_result(battery, result);
731 battery->flags.update[fid] = result; 735 battery->flags.update[fid] = result;
736 mutex_unlock(&battery->mutex);
732 return result; 737 return result;
733} 738}
734 739
@@ -867,8 +872,11 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
867 case ACPI_NOTIFY_DEVICE_CHECK: 872 case ACPI_NOTIFY_DEVICE_CHECK:
868 device = battery->device; 873 device = battery->device;
869 acpi_battery_notify_update(battery); 874 acpi_battery_notify_update(battery);
870 acpi_bus_generate_event(device, event, 875 acpi_bus_generate_proc_event(device, event,
871 acpi_battery_present(battery)); 876 acpi_battery_present(battery));
877 acpi_bus_generate_netlink_event(device->pnp.device_class,
878 device->dev.bus_id, event,
879 acpi_battery_present(battery));
872 break; 880 break;
873 default: 881 default:
874 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 882 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -892,7 +900,10 @@ static int acpi_battery_add(struct acpi_device *device)
892 if (!battery) 900 if (!battery)
893 return -ENOMEM; 901 return -ENOMEM;
894 902
895 mutex_init(&battery->lock); 903 mutex_init(&battery->mutex);
904
905 mutex_lock(&battery->mutex);
906
896 battery->device = device; 907 battery->device = device;
897 strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); 908 strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
898 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); 909 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
@@ -928,6 +939,7 @@ static int acpi_battery_add(struct acpi_device *device)
928 kfree(battery); 939 kfree(battery);
929 } 940 }
930 941
942 mutex_unlock(&battery->mutex);
931 943
932 return result; 944 return result;
933} 945}
@@ -942,6 +954,8 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
942 954
943 battery = acpi_driver_data(device); 955 battery = acpi_driver_data(device);
944 956
957 mutex_lock(&battery->mutex);
958
945 status = acpi_remove_notify_handler(device->handle, 959 status = acpi_remove_notify_handler(device->handle,
946 ACPI_ALL_NOTIFY, 960 ACPI_ALL_NOTIFY,
947 acpi_battery_notify); 961 acpi_battery_notify);
@@ -952,7 +966,9 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
952 966
953 kfree(battery->bst_data.pointer); 967 kfree(battery->bst_data.pointer);
954 968
955 mutex_destroy(&battery->lock); 969 mutex_unlock(&battery->mutex);
970
971 mutex_destroy(&battery->mutex);
956 972
957 kfree(battery); 973 kfree(battery);
958 974
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index 6b2658c96242..9ba778a2b484 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -276,6 +276,7 @@ EXPORT_SYMBOL(acpi_bus_set_power);
276 Event Management 276 Event Management
277 -------------------------------------------------------------------------- */ 277 -------------------------------------------------------------------------- */
278 278
279#ifdef CONFIG_ACPI_PROC_EVENT
279static DEFINE_SPINLOCK(acpi_bus_event_lock); 280static DEFINE_SPINLOCK(acpi_bus_event_lock);
280 281
281LIST_HEAD(acpi_bus_event_list); 282LIST_HEAD(acpi_bus_event_list);
@@ -283,7 +284,7 @@ DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue);
283 284
284extern int event_is_open; 285extern int event_is_open;
285 286
286int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data) 287int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
287{ 288{
288 struct acpi_bus_event *event = NULL; 289 struct acpi_bus_event *event = NULL;
289 unsigned long flags = 0; 290 unsigned long flags = 0;
@@ -292,10 +293,6 @@ int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data)
292 if (!device) 293 if (!device)
293 return -EINVAL; 294 return -EINVAL;
294 295
295 if (acpi_bus_generate_genetlink_event(device, type, data))
296 printk(KERN_WARNING PREFIX
297 "Failed to generate an ACPI event via genetlink!\n");
298
299 /* drop event on the floor if no one's listening */ 296 /* drop event on the floor if no one's listening */
300 if (!event_is_open) 297 if (!event_is_open)
301 return 0; 298 return 0;
@@ -318,7 +315,7 @@ int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data)
318 return 0; 315 return 0;
319} 316}
320 317
321EXPORT_SYMBOL(acpi_bus_generate_event); 318EXPORT_SYMBOL(acpi_bus_generate_proc_event);
322 319
323int acpi_bus_receive_event(struct acpi_bus_event *event) 320int acpi_bus_receive_event(struct acpi_bus_event *event)
324{ 321{
@@ -364,6 +361,7 @@ int acpi_bus_receive_event(struct acpi_bus_event *event)
364} 361}
365 362
366EXPORT_SYMBOL(acpi_bus_receive_event); 363EXPORT_SYMBOL(acpi_bus_receive_event);
364#endif /* CONFIG_ACPI_PROC_EVENT */
367 365
368/* -------------------------------------------------------------------------- 366/* --------------------------------------------------------------------------
369 Notification Handling 367 Notification Handling
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 540581338ef5..2e79a3395ecf 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -284,7 +284,7 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
284 } 284 }
285 input_sync(input); 285 input_sync(input);
286 286
287 acpi_bus_generate_event(button->device, event, 287 acpi_bus_generate_proc_event(button->device, event,
288 ++button->pushed); 288 ++button->pushed);
289 break; 289 break;
290 default: 290 default:
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 56bee9e065cf..3f7935ab0cf5 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -696,14 +696,6 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
696 return AE_CTRL_TERMINATE; 696 return AE_CTRL_TERMINATE;
697} 697}
698 698
699static void ec_remove_handlers(struct acpi_ec *ec)
700{
701 acpi_remove_address_space_handler(ec->handle,
702 ACPI_ADR_SPACE_EC,
703 &acpi_ec_space_handler);
704 acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
705}
706
707static int acpi_ec_add(struct acpi_device *device) 699static int acpi_ec_add(struct acpi_device *device)
708{ 700{
709 struct acpi_ec *ec = NULL; 701 struct acpi_ec *ec = NULL;
@@ -727,13 +719,16 @@ static int acpi_ec_add(struct acpi_device *device)
727 /* Check if we found the boot EC */ 719 /* Check if we found the boot EC */
728 if (boot_ec) { 720 if (boot_ec) {
729 if (boot_ec->gpe == ec->gpe) { 721 if (boot_ec->gpe == ec->gpe) {
730 ec_remove_handlers(boot_ec); 722 /* We might have incorrect info for GL at boot time */
731 mutex_destroy(&boot_ec->lock); 723 mutex_lock(&boot_ec->lock);
732 kfree(boot_ec); 724 boot_ec->global_lock = ec->global_lock;
733 first_ec = boot_ec = NULL; 725 /* Copy handlers from new ec into boot ec */
726 list_splice(&ec->list, &boot_ec->list);
727 mutex_unlock(&boot_ec->lock);
728 kfree(ec);
729 ec = boot_ec;
734 } 730 }
735 } 731 } else
736 if (!first_ec)
737 first_ec = ec; 732 first_ec = ec;
738 ec->handle = device->handle; 733 ec->handle = device->handle;
739 acpi_driver_data(device) = ec; 734 acpi_driver_data(device) = ec;
@@ -762,6 +757,9 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
762 if (ec == first_ec) 757 if (ec == first_ec)
763 first_ec = NULL; 758 first_ec = NULL;
764 759
760 /* Don't touch boot EC */
761 if (boot_ec != ec)
762 kfree(ec);
765 return 0; 763 return 0;
766} 764}
767 765
@@ -825,7 +823,9 @@ static int acpi_ec_start(struct acpi_device *device)
825 if (!ec) 823 if (!ec)
826 return -EINVAL; 824 return -EINVAL;
827 825
828 ret = ec_install_handlers(ec); 826 /* Boot EC is already working */
827 if (ec != boot_ec)
828 ret = ec_install_handlers(ec);
829 829
830 /* EC is fully operational, allow queries */ 830 /* EC is fully operational, allow queries */
831 atomic_set(&ec->query_pending, 0); 831 atomic_set(&ec->query_pending, 0);
@@ -835,6 +835,7 @@ static int acpi_ec_start(struct acpi_device *device)
835 835
836static int acpi_ec_stop(struct acpi_device *device, int type) 836static int acpi_ec_stop(struct acpi_device *device, int type)
837{ 837{
838 acpi_status status;
838 struct acpi_ec *ec; 839 struct acpi_ec *ec;
839 840
840 if (!device) 841 if (!device)
@@ -843,7 +844,21 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
843 ec = acpi_driver_data(device); 844 ec = acpi_driver_data(device);
844 if (!ec) 845 if (!ec)
845 return -EINVAL; 846 return -EINVAL;
846 ec_remove_handlers(ec); 847
848 /* Don't touch boot EC */
849 if (ec == boot_ec)
850 return 0;
851
852 status = acpi_remove_address_space_handler(ec->handle,
853 ACPI_ADR_SPACE_EC,
854 &acpi_ec_space_handler);
855 if (ACPI_FAILURE(status))
856 return -ENODEV;
857
858 status = acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
859 if (ACPI_FAILURE(status))
860 return -ENODEV;
861
847 return 0; 862 return 0;
848} 863}
849 864
@@ -871,7 +886,8 @@ int __init acpi_ec_ecdt_probe(void)
871 printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n"); 886 printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n");
872 status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device, 887 status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device,
873 boot_ec, NULL); 888 boot_ec, NULL);
874 if (ACPI_FAILURE(status)) 889 /* Check that acpi_get_devices actually find something */
890 if (ACPI_FAILURE(status) || !boot_ec->handle)
875 goto error; 891 goto error;
876 } 892 }
877 893
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c
index 95637a4ff782..5c95863f8fa9 100644
--- a/drivers/acpi/event.c
+++ b/drivers/acpi/event.c
@@ -17,6 +17,7 @@
17#define _COMPONENT ACPI_SYSTEM_COMPONENT 17#define _COMPONENT ACPI_SYSTEM_COMPONENT
18ACPI_MODULE_NAME("event"); 18ACPI_MODULE_NAME("event");
19 19
20#ifdef CONFIG_ACPI_PROC_EVENT
20/* Global vars for handling event proc entry */ 21/* Global vars for handling event proc entry */
21static DEFINE_SPINLOCK(acpi_system_event_lock); 22static DEFINE_SPINLOCK(acpi_system_event_lock);
22int event_is_open = 0; 23int event_is_open = 0;
@@ -106,6 +107,7 @@ static const struct file_operations acpi_system_event_ops = {
106 .release = acpi_system_close_event, 107 .release = acpi_system_close_event,
107 .poll = acpi_system_poll_event, 108 .poll = acpi_system_poll_event,
108}; 109};
110#endif /* CONFIG_ACPI_PROC_EVENT */
109 111
110#ifdef CONFIG_NET 112#ifdef CONFIG_NET
111static unsigned int acpi_event_seqnum; 113static unsigned int acpi_event_seqnum;
@@ -147,7 +149,8 @@ static struct genl_multicast_group acpi_event_mcgrp = {
147 .name = ACPI_GENL_MCAST_GROUP_NAME, 149 .name = ACPI_GENL_MCAST_GROUP_NAME,
148}; 150};
149 151
150int acpi_bus_generate_genetlink_event(struct acpi_device *device, 152int acpi_bus_generate_netlink_event(const char *device_class,
153 const char *bus_id,
151 u8 type, int data) 154 u8 type, int data)
152{ 155{
153 struct sk_buff *skb; 156 struct sk_buff *skb;
@@ -191,8 +194,8 @@ int acpi_bus_generate_genetlink_event(struct acpi_device *device,
191 194
192 memset(event, 0, sizeof(struct acpi_genl_event)); 195 memset(event, 0, sizeof(struct acpi_genl_event));
193 196
194 strcpy(event->device_class, device->pnp.device_class); 197 strcpy(event->device_class, device_class);
195 strcpy(event->bus_id, device->dev.bus_id); 198 strcpy(event->bus_id, bus_id);
196 event->type = type; 199 event->type = type;
197 event->data = data; 200 event->data = data;
198 201
@@ -211,6 +214,8 @@ int acpi_bus_generate_genetlink_event(struct acpi_device *device,
211 return 0; 214 return 0;
212} 215}
213 216
217EXPORT_SYMBOL(acpi_bus_generate_netlink_event);
218
214static int acpi_event_genetlink_init(void) 219static int acpi_event_genetlink_init(void)
215{ 220{
216 int result; 221 int result;
@@ -228,12 +233,15 @@ static int acpi_event_genetlink_init(void)
228} 233}
229 234
230#else 235#else
231int acpi_bus_generate_genetlink_event(struct acpi_device *device, u8 type, 236int acpi_bus_generate_netlink_event(const char *device_class,
232 int data) 237 const char *bus_id,
238 u8 type, int data)
233{ 239{
234 return 0; 240 return 0;
235} 241}
236 242
243EXPORT_SYMBOL(acpi_bus_generate_netlink_event);
244
237static int acpi_event_genetlink_init(void) 245static int acpi_event_genetlink_init(void)
238{ 246{
239 return -ENODEV; 247 return -ENODEV;
@@ -242,7 +250,9 @@ static int acpi_event_genetlink_init(void)
242 250
243static int __init acpi_event_init(void) 251static int __init acpi_event_init(void)
244{ 252{
253#ifdef CONFIG_ACPI_PROC_EVENT
245 struct proc_dir_entry *entry; 254 struct proc_dir_entry *entry;
255#endif
246 int error = 0; 256 int error = 0;
247 257
248 if (acpi_disabled) 258 if (acpi_disabled)
@@ -254,12 +264,14 @@ static int __init acpi_event_init(void)
254 printk(KERN_WARNING PREFIX 264 printk(KERN_WARNING PREFIX
255 "Failed to create genetlink family for ACPI event\n"); 265 "Failed to create genetlink family for ACPI event\n");
256 266
267#ifdef CONFIG_ACPI_PROC_EVENT
257 /* 'event' [R] */ 268 /* 'event' [R] */
258 entry = create_proc_entry("event", S_IRUSR, acpi_root_dir); 269 entry = create_proc_entry("event", S_IRUSR, acpi_root_dir);
259 if (entry) 270 if (entry)
260 entry->proc_fops = &acpi_system_event_ops; 271 entry->proc_fops = &acpi_system_event_ops;
261 else 272 else
262 return -ENODEV; 273 return -ENODEV;
274#endif
263 275
264 return 0; 276 return 0;
265} 277}
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
index 76c525dc590b..cf69c0040a39 100644
--- a/drivers/acpi/hardware/hwsleep.c
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -576,13 +576,10 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
576 ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS")); 576 ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS"));
577 } 577 }
578 578
579 status = acpi_evaluate_object(NULL, METHOD_NAME__WAK, &arg_list, NULL);
580 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
581 ACPI_EXCEPTION((AE_INFO, status, "During Method _WAK"));
582 }
583 /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
584
585 /* 579 /*
580 * GPEs must be enabled before _WAK is called as GPEs
581 * might get fired there
582 *
586 * Restore the GPEs: 583 * Restore the GPEs:
587 * 1) Disable/Clear all GPEs 584 * 1) Disable/Clear all GPEs
588 * 2) Enable all runtime GPEs 585 * 2) Enable all runtime GPEs
@@ -591,13 +588,19 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state)
591 if (ACPI_FAILURE(status)) { 588 if (ACPI_FAILURE(status)) {
592 return_ACPI_STATUS(status); 589 return_ACPI_STATUS(status);
593 } 590 }
594 acpi_gbl_system_awake_and_running = TRUE;
595
596 status = acpi_hw_enable_all_runtime_gpes(); 591 status = acpi_hw_enable_all_runtime_gpes();
597 if (ACPI_FAILURE(status)) { 592 if (ACPI_FAILURE(status)) {
598 return_ACPI_STATUS(status); 593 return_ACPI_STATUS(status);
599 } 594 }
600 595
596 status = acpi_evaluate_object(NULL, METHOD_NAME__WAK, &arg_list, NULL);
597 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
598 ACPI_EXCEPTION((AE_INFO, status, "During Method _WAK"));
599 }
600 /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */
601
602 acpi_gbl_system_awake_and_running = TRUE;
603
601 /* Enable power button */ 604 /* Enable power button */
602 605
603 (void) 606 (void)
diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c
index ab65b2c2560e..f39fbc6b9237 100644
--- a/drivers/acpi/namespace/nsxfeval.c
+++ b/drivers/acpi/namespace/nsxfeval.c
@@ -540,7 +540,7 @@ acpi_ns_get_device_callback(acpi_handle obj_handle,
540 ******************************************************************************/ 540 ******************************************************************************/
541 541
542acpi_status 542acpi_status
543acpi_get_devices(char *HID, 543acpi_get_devices(const char *HID,
544 acpi_walk_callback user_function, 544 acpi_walk_callback user_function,
545 void *context, void **return_value) 545 void *context, void **return_value)
546{ 546{
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 498422343f38..9f11dc296cdd 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -102,6 +102,8 @@ static struct acpi_driver acpi_processor_driver = {
102 .add = acpi_processor_add, 102 .add = acpi_processor_add,
103 .remove = acpi_processor_remove, 103 .remove = acpi_processor_remove,
104 .start = acpi_processor_start, 104 .start = acpi_processor_start,
105 .suspend = acpi_processor_suspend,
106 .resume = acpi_processor_resume,
105 }, 107 },
106}; 108};
107 109
@@ -698,16 +700,23 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
698 switch (event) { 700 switch (event) {
699 case ACPI_PROCESSOR_NOTIFY_PERFORMANCE: 701 case ACPI_PROCESSOR_NOTIFY_PERFORMANCE:
700 acpi_processor_ppc_has_changed(pr); 702 acpi_processor_ppc_has_changed(pr);
701 acpi_bus_generate_event(device, event, 703 acpi_bus_generate_proc_event(device, event,
702 pr->performance_platform_limit); 704 pr->performance_platform_limit);
705 acpi_bus_generate_netlink_event(device->pnp.device_class,
706 device->dev.bus_id, event,
707 pr->performance_platform_limit);
703 break; 708 break;
704 case ACPI_PROCESSOR_NOTIFY_POWER: 709 case ACPI_PROCESSOR_NOTIFY_POWER:
705 acpi_processor_cst_has_changed(pr); 710 acpi_processor_cst_has_changed(pr);
706 acpi_bus_generate_event(device, event, 0); 711 acpi_bus_generate_proc_event(device, event, 0);
712 acpi_bus_generate_netlink_event(device->pnp.device_class,
713 device->dev.bus_id, event, 0);
707 break; 714 break;
708 case ACPI_PROCESSOR_NOTIFY_THROTTLING: 715 case ACPI_PROCESSOR_NOTIFY_THROTTLING:
709 acpi_processor_tstate_has_changed(pr); 716 acpi_processor_tstate_has_changed(pr);
710 acpi_bus_generate_event(device, event, 0); 717 acpi_bus_generate_proc_event(device, event, 0);
718 acpi_bus_generate_netlink_event(device->pnp.device_class,
719 device->dev.bus_id, event, 0);
711 default: 720 default:
712 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 721 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
713 "Unsupported event [0x%x]\n", event)); 722 "Unsupported event [0x%x]\n", event));
@@ -717,6 +726,25 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data)
717 return; 726 return;
718} 727}
719 728
729static int acpi_cpu_soft_notify(struct notifier_block *nfb,
730 unsigned long action, void *hcpu)
731{
732 unsigned int cpu = (unsigned long)hcpu;
733 struct acpi_processor *pr = processors[cpu];
734
735 if (action == CPU_ONLINE && pr) {
736 acpi_processor_ppc_has_changed(pr);
737 acpi_processor_cst_has_changed(pr);
738 acpi_processor_tstate_has_changed(pr);
739 }
740 return NOTIFY_OK;
741}
742
743static struct notifier_block acpi_cpu_notifier =
744{
745 .notifier_call = acpi_cpu_soft_notify,
746};
747
720static int acpi_processor_add(struct acpi_device *device) 748static int acpi_processor_add(struct acpi_device *device)
721{ 749{
722 struct acpi_processor *pr = NULL; 750 struct acpi_processor *pr = NULL;
@@ -980,6 +1008,7 @@ void acpi_processor_install_hotplug_notify(void)
980 ACPI_UINT32_MAX, 1008 ACPI_UINT32_MAX,
981 processor_walk_namespace_cb, &action, NULL); 1009 processor_walk_namespace_cb, &action, NULL);
982#endif 1010#endif
1011 register_hotcpu_notifier(&acpi_cpu_notifier);
983} 1012}
984 1013
985static 1014static
@@ -992,6 +1021,7 @@ void acpi_processor_uninstall_hotplug_notify(void)
992 ACPI_UINT32_MAX, 1021 ACPI_UINT32_MAX,
993 processor_walk_namespace_cb, &action, NULL); 1022 processor_walk_namespace_cb, &action, NULL);
994#endif 1023#endif
1024 unregister_hotcpu_notifier(&acpi_cpu_notifier);
995} 1025}
996 1026
997/* 1027/*
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index a8634a0655fc..f18261368e76 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -63,6 +63,7 @@
63ACPI_MODULE_NAME("processor_idle"); 63ACPI_MODULE_NAME("processor_idle");
64#define ACPI_PROCESSOR_FILE_POWER "power" 64#define ACPI_PROCESSOR_FILE_POWER "power"
65#define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000) 65#define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
66#define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY)
66#define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */ 67#define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */
67#define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */ 68#define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */
68static void (*pm_idle_save) (void) __read_mostly; 69static void (*pm_idle_save) (void) __read_mostly;
@@ -324,6 +325,23 @@ static void acpi_state_timer_broadcast(struct acpi_processor *pr,
324 325
325#endif 326#endif
326 327
328/*
329 * Suspend / resume control
330 */
331static int acpi_idle_suspend;
332
333int acpi_processor_suspend(struct acpi_device * device, pm_message_t state)
334{
335 acpi_idle_suspend = 1;
336 return 0;
337}
338
339int acpi_processor_resume(struct acpi_device * device)
340{
341 acpi_idle_suspend = 0;
342 return 0;
343}
344
327static void acpi_processor_idle(void) 345static void acpi_processor_idle(void)
328{ 346{
329 struct acpi_processor *pr = NULL; 347 struct acpi_processor *pr = NULL;
@@ -354,7 +372,7 @@ static void acpi_processor_idle(void)
354 } 372 }
355 373
356 cx = pr->power.state; 374 cx = pr->power.state;
357 if (!cx) { 375 if (!cx || acpi_idle_suspend) {
358 if (pm_idle_save) 376 if (pm_idle_save)
359 pm_idle_save(); 377 pm_idle_save();
360 else 378 else
@@ -462,6 +480,9 @@ static void acpi_processor_idle(void)
462 * TBD: Can't get time duration while in C1, as resumes 480 * TBD: Can't get time duration while in C1, as resumes
463 * go to an ISR rather than here. Need to instrument 481 * go to an ISR rather than here. Need to instrument
464 * base interrupt handler. 482 * base interrupt handler.
483 *
484 * Note: the TSC better not stop in C1, sched_clock() will
485 * skew otherwise.
465 */ 486 */
466 sleep_ticks = 0xFFFFFFFF; 487 sleep_ticks = 0xFFFFFFFF;
467 break; 488 break;
@@ -469,6 +490,8 @@ static void acpi_processor_idle(void)
469 case ACPI_STATE_C2: 490 case ACPI_STATE_C2:
470 /* Get start time (ticks) */ 491 /* Get start time (ticks) */
471 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); 492 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
493 /* Tell the scheduler that we are going deep-idle: */
494 sched_clock_idle_sleep_event();
472 /* Invoke C2 */ 495 /* Invoke C2 */
473 acpi_state_timer_broadcast(pr, cx, 1); 496 acpi_state_timer_broadcast(pr, cx, 1);
474 acpi_cstate_enter(cx); 497 acpi_cstate_enter(cx);
@@ -479,17 +502,22 @@ static void acpi_processor_idle(void)
479 /* TSC halts in C2, so notify users */ 502 /* TSC halts in C2, so notify users */
480 mark_tsc_unstable("possible TSC halt in C2"); 503 mark_tsc_unstable("possible TSC halt in C2");
481#endif 504#endif
505 /* Compute time (ticks) that we were actually asleep */
506 sleep_ticks = ticks_elapsed(t1, t2);
507
508 /* Tell the scheduler how much we idled: */
509 sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
510
482 /* Re-enable interrupts */ 511 /* Re-enable interrupts */
483 local_irq_enable(); 512 local_irq_enable();
513 /* Do not account our idle-switching overhead: */
514 sleep_ticks -= cx->latency_ticks + C2_OVERHEAD;
515
484 current_thread_info()->status |= TS_POLLING; 516 current_thread_info()->status |= TS_POLLING;
485 /* Compute time (ticks) that we were actually asleep */
486 sleep_ticks =
487 ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD;
488 acpi_state_timer_broadcast(pr, cx, 0); 517 acpi_state_timer_broadcast(pr, cx, 0);
489 break; 518 break;
490 519
491 case ACPI_STATE_C3: 520 case ACPI_STATE_C3:
492
493 /* 521 /*
494 * disable bus master 522 * disable bus master
495 * bm_check implies we need ARB_DIS 523 * bm_check implies we need ARB_DIS
@@ -518,6 +546,8 @@ static void acpi_processor_idle(void)
518 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); 546 t1 = inl(acpi_gbl_FADT.xpm_timer_block.address);
519 /* Invoke C3 */ 547 /* Invoke C3 */
520 acpi_state_timer_broadcast(pr, cx, 1); 548 acpi_state_timer_broadcast(pr, cx, 1);
549 /* Tell the scheduler that we are going deep-idle: */
550 sched_clock_idle_sleep_event();
521 acpi_cstate_enter(cx); 551 acpi_cstate_enter(cx);
522 /* Get end time (ticks) */ 552 /* Get end time (ticks) */
523 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); 553 t2 = inl(acpi_gbl_FADT.xpm_timer_block.address);
@@ -531,12 +561,17 @@ static void acpi_processor_idle(void)
531 /* TSC halts in C3, so notify users */ 561 /* TSC halts in C3, so notify users */
532 mark_tsc_unstable("TSC halts in C3"); 562 mark_tsc_unstable("TSC halts in C3");
533#endif 563#endif
564 /* Compute time (ticks) that we were actually asleep */
565 sleep_ticks = ticks_elapsed(t1, t2);
566 /* Tell the scheduler how much we idled: */
567 sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS);
568
534 /* Re-enable interrupts */ 569 /* Re-enable interrupts */
535 local_irq_enable(); 570 local_irq_enable();
571 /* Do not account our idle-switching overhead: */
572 sleep_ticks -= cx->latency_ticks + C3_OVERHEAD;
573
536 current_thread_info()->status |= TS_POLLING; 574 current_thread_info()->status |= TS_POLLING;
537 /* Compute time (ticks) that we were actually asleep */
538 sleep_ticks =
539 ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD;
540 acpi_state_timer_broadcast(pr, cx, 0); 575 acpi_state_timer_broadcast(pr, cx, 0);
541 break; 576 break;
542 577
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index 82c3a550016d..a578986e3214 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -440,11 +440,12 @@ static int acpi_sbs_generate_event(struct acpi_device *device,
440 strcpy(acpi_device_bid(device), bid); 440 strcpy(acpi_device_bid(device), bid);
441 strcpy(acpi_device_class(device), class); 441 strcpy(acpi_device_class(device), class);
442 442
443 result = acpi_bus_generate_event(device, event, state); 443 result = acpi_bus_generate_proc_event(device, event, state);
444 444
445 strcpy(acpi_device_bid(device), bid_saved); 445 strcpy(acpi_device_bid(device), bid_saved);
446 strcpy(acpi_device_class(device), class_saved); 446 strcpy(acpi_device_class(device), class_saved);
447 447
448 acpi_bus_generate_netlink_event(class, bid, event, state);
448 return result; 449 return result;
449} 450}
450 451
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index be74347d1354..64620d668742 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -35,8 +35,9 @@ struct acpi_device_bus_id{
35 * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get: 35 * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get:
36 * char *modalias: "acpi:IBM0001:ACPI0001" 36 * char *modalias: "acpi:IBM0001:ACPI0001"
37*/ 37*/
38int create_modalias(struct acpi_device *acpi_dev, char *modalias, int size){ 38static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
39 39 int size)
40{
40 int len; 41 int len;
41 42
42 if (!acpi_dev->flags.hardware_id) 43 if (!acpi_dev->flags.hardware_id)
diff --git a/drivers/acpi/sleep/Makefile b/drivers/acpi/sleep/Makefile
index 195a4f69c0f7..f1fb888c2d29 100644
--- a/drivers/acpi/sleep/Makefile
+++ b/drivers/acpi/sleep/Makefile
@@ -1,5 +1,5 @@
1obj-y := poweroff.o wakeup.o 1obj-y := wakeup.o
2obj-$(CONFIG_ACPI_SLEEP) += main.o 2obj-y += main.o
3obj-$(CONFIG_ACPI_SLEEP) += proc.o 3obj-$(CONFIG_ACPI_SLEEP) += proc.o
4 4
5EXTRA_CFLAGS += $(ACPI_CFLAGS) 5EXTRA_CFLAGS += $(ACPI_CFLAGS)
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index e8cff5dd4cbc..2cbb9aabd00e 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -15,13 +15,39 @@
15#include <linux/dmi.h> 15#include <linux/dmi.h>
16#include <linux/device.h> 16#include <linux/device.h>
17#include <linux/suspend.h> 17#include <linux/suspend.h>
18
19#include <asm/io.h>
20
18#include <acpi/acpi_bus.h> 21#include <acpi/acpi_bus.h>
19#include <acpi/acpi_drivers.h> 22#include <acpi/acpi_drivers.h>
20#include "sleep.h" 23#include "sleep.h"
21 24
22u8 sleep_states[ACPI_S_STATE_COUNT]; 25u8 sleep_states[ACPI_S_STATE_COUNT];
23 26
27#ifdef CONFIG_PM_SLEEP
24static u32 acpi_target_sleep_state = ACPI_STATE_S0; 28static u32 acpi_target_sleep_state = ACPI_STATE_S0;
29#endif
30
31int acpi_sleep_prepare(u32 acpi_state)
32{
33#ifdef CONFIG_ACPI_SLEEP
34 /* do we have a wakeup address for S2 and S3? */
35 if (acpi_state == ACPI_STATE_S3) {
36 if (!acpi_wakeup_address) {
37 return -EFAULT;
38 }
39 acpi_set_firmware_waking_vector((acpi_physical_address)
40 virt_to_phys((void *)
41 acpi_wakeup_address));
42
43 }
44 ACPI_FLUSH_CPU_CACHE();
45 acpi_enable_wakeup_device_prep(acpi_state);
46#endif
47 acpi_gpe_sleep_prepare(acpi_state);
48 acpi_enter_sleep_state_prep(acpi_state);
49 return 0;
50}
25 51
26#ifdef CONFIG_SUSPEND 52#ifdef CONFIG_SUSPEND
27static struct pm_ops acpi_pm_ops; 53static struct pm_ops acpi_pm_ops;
@@ -275,6 +301,7 @@ int acpi_suspend(u32 acpi_state)
275 return -EINVAL; 301 return -EINVAL;
276} 302}
277 303
304#ifdef CONFIG_PM_SLEEP
278/** 305/**
279 * acpi_pm_device_sleep_state - return preferred power state of ACPI device 306 * acpi_pm_device_sleep_state - return preferred power state of ACPI device
280 * in the system sleep state given by %acpi_target_sleep_state 307 * in the system sleep state given by %acpi_target_sleep_state
@@ -305,7 +332,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p)
305 unsigned long d_min, d_max; 332 unsigned long d_min, d_max;
306 333
307 if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { 334 if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) {
308 printk(KERN_ERR "ACPI handle has no context!\n"); 335 printk(KERN_DEBUG "ACPI handle has no context!\n");
309 return -ENODEV; 336 return -ENODEV;
310 } 337 }
311 338
@@ -349,6 +376,21 @@ int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p)
349 *d_min_p = d_min; 376 *d_min_p = d_min;
350 return d_max; 377 return d_max;
351} 378}
379#endif
380
381static void acpi_power_off_prepare(void)
382{
383 /* Prepare to power off the system */
384 acpi_sleep_prepare(ACPI_STATE_S5);
385}
386
387static void acpi_power_off(void)
388{
389 /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
390 printk("%s called\n", __FUNCTION__);
391 local_irq_disable();
392 acpi_enter_sleep_state(ACPI_STATE_S5);
393}
352 394
353int __init acpi_sleep_init(void) 395int __init acpi_sleep_init(void)
354{ 396{
@@ -363,16 +405,17 @@ int __init acpi_sleep_init(void)
363 if (acpi_disabled) 405 if (acpi_disabled)
364 return 0; 406 return 0;
365 407
408 sleep_states[ACPI_STATE_S0] = 1;
409 printk(KERN_INFO PREFIX "(supports S0");
410
366#ifdef CONFIG_SUSPEND 411#ifdef CONFIG_SUSPEND
367 printk(KERN_INFO PREFIX "(supports"); 412 for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++) {
368 for (i = ACPI_STATE_S0; i < ACPI_STATE_S4; i++) {
369 status = acpi_get_sleep_type_data(i, &type_a, &type_b); 413 status = acpi_get_sleep_type_data(i, &type_a, &type_b);
370 if (ACPI_SUCCESS(status)) { 414 if (ACPI_SUCCESS(status)) {
371 sleep_states[i] = 1; 415 sleep_states[i] = 1;
372 printk(" S%d", i); 416 printk(" S%d", i);
373 } 417 }
374 } 418 }
375 printk(")\n");
376 419
377 pm_set_ops(&acpi_pm_ops); 420 pm_set_ops(&acpi_pm_ops);
378#endif 421#endif
@@ -382,10 +425,16 @@ int __init acpi_sleep_init(void)
382 if (ACPI_SUCCESS(status)) { 425 if (ACPI_SUCCESS(status)) {
383 hibernation_set_ops(&acpi_hibernation_ops); 426 hibernation_set_ops(&acpi_hibernation_ops);
384 sleep_states[ACPI_STATE_S4] = 1; 427 sleep_states[ACPI_STATE_S4] = 1;
428 printk(" S4");
385 } 429 }
386#else
387 sleep_states[ACPI_STATE_S4] = 0;
388#endif 430#endif
389 431 status = acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);
432 if (ACPI_SUCCESS(status)) {
433 sleep_states[ACPI_STATE_S5] = 1;
434 printk(" S5");
435 pm_power_off_prepare = acpi_power_off_prepare;
436 pm_power_off = acpi_power_off;
437 }
438 printk(")\n");
390 return 0; 439 return 0;
391} 440}
diff --git a/drivers/acpi/sleep/poweroff.c b/drivers/acpi/sleep/poweroff.c
deleted file mode 100644
index 39e40d56b034..000000000000
--- a/drivers/acpi/sleep/poweroff.c
+++ /dev/null
@@ -1,75 +0,0 @@
1/*
2 * poweroff.c - ACPI handler for powering off the system.
3 *
4 * AKA S5, but it is independent of whether or not the kernel supports
5 * any other sleep support in the system.
6 *
7 * Copyright (c) 2005 Alexey Starikovskiy <alexey.y.starikovskiy@intel.com>
8 *
9 * This file is released under the GPLv2.
10 */
11
12#include <linux/pm.h>
13#include <linux/init.h>
14#include <acpi/acpi_bus.h>
15#include <linux/sysdev.h>
16#include <asm/io.h>
17#include "sleep.h"
18
19int acpi_sleep_prepare(u32 acpi_state)
20{
21#ifdef CONFIG_ACPI_SLEEP
22 /* do we have a wakeup address for S2 and S3? */
23 if (acpi_state == ACPI_STATE_S3) {
24 if (!acpi_wakeup_address) {
25 return -EFAULT;
26 }
27 acpi_set_firmware_waking_vector((acpi_physical_address)
28 virt_to_phys((void *)
29 acpi_wakeup_address));
30
31 }
32 ACPI_FLUSH_CPU_CACHE();
33 acpi_enable_wakeup_device_prep(acpi_state);
34#endif
35 acpi_gpe_sleep_prepare(acpi_state);
36 acpi_enter_sleep_state_prep(acpi_state);
37 return 0;
38}
39
40#ifdef CONFIG_PM
41
42static void acpi_power_off_prepare(void)
43{
44 /* Prepare to power off the system */
45 acpi_sleep_prepare(ACPI_STATE_S5);
46}
47
48static void acpi_power_off(void)
49{
50 /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
51 printk("%s called\n", __FUNCTION__);
52 local_irq_disable();
53 /* Some SMP machines only can poweroff in boot CPU */
54 acpi_enter_sleep_state(ACPI_STATE_S5);
55}
56
57static int acpi_poweroff_init(void)
58{
59 if (!acpi_disabled) {
60 u8 type_a, type_b;
61 acpi_status status;
62
63 status =
64 acpi_get_sleep_type_data(ACPI_STATE_S5, &type_a, &type_b);
65 if (ACPI_SUCCESS(status)) {
66 pm_power_off_prepare = acpi_power_off_prepare;
67 pm_power_off = acpi_power_off;
68 }
69 }
70 return 0;
71}
72
73late_initcall(acpi_poweroff_init);
74
75#endif /* CONFIG_PM */
diff --git a/drivers/acpi/sleep/proc.c b/drivers/acpi/sleep/proc.c
index 66b62b0d3609..3839efd5eaea 100644
--- a/drivers/acpi/sleep/proc.c
+++ b/drivers/acpi/sleep/proc.c
@@ -23,7 +23,7 @@
23 */ 23 */
24 24
25ACPI_MODULE_NAME("sleep") 25ACPI_MODULE_NAME("sleep")
26#ifdef CONFIG_ACPI_PROCFS_SLEEP 26#ifdef CONFIG_ACPI_PROCFS
27static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset) 27static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset)
28{ 28{
29 int i; 29 int i;
@@ -76,7 +76,7 @@ acpi_system_write_sleep(struct file *file,
76 Done: 76 Done:
77 return error ? error : count; 77 return error ? error : count;
78} 78}
79#endif /* CONFIG_ACPI_PROCFS_SLEEP */ 79#endif /* CONFIG_ACPI_PROCFS */
80 80
81#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) || !defined(CONFIG_X86) 81#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE) || !defined(CONFIG_X86)
82/* use /sys/class/rtc/rtcX/wakealarm instead; it's not ACPI-specific */ 82/* use /sys/class/rtc/rtcX/wakealarm instead; it's not ACPI-specific */
@@ -471,7 +471,7 @@ static const struct file_operations acpi_system_wakeup_device_fops = {
471 .release = single_release, 471 .release = single_release,
472}; 472};
473 473
474#ifdef CONFIG_ACPI_PROCFS_SLEEP 474#ifdef CONFIG_ACPI_PROCFS
475static const struct file_operations acpi_system_sleep_fops = { 475static const struct file_operations acpi_system_sleep_fops = {
476 .open = acpi_system_sleep_open_fs, 476 .open = acpi_system_sleep_open_fs,
477 .read = seq_read, 477 .read = seq_read,
@@ -479,7 +479,7 @@ static const struct file_operations acpi_system_sleep_fops = {
479 .llseek = seq_lseek, 479 .llseek = seq_lseek,
480 .release = single_release, 480 .release = single_release,
481}; 481};
482#endif /* CONFIG_ACPI_PROCFS_SLEEP */ 482#endif /* CONFIG_ACPI_PROCFS */
483 483
484#ifdef HAVE_ACPI_LEGACY_ALARM 484#ifdef HAVE_ACPI_LEGACY_ALARM
485static const struct file_operations acpi_system_alarm_fops = { 485static const struct file_operations acpi_system_alarm_fops = {
@@ -506,7 +506,7 @@ static int __init acpi_sleep_proc_init(void)
506 if (acpi_disabled) 506 if (acpi_disabled)
507 return 0; 507 return 0;
508 508
509#ifdef CONFIG_ACPI_PROCFS_SLEEP 509#ifdef CONFIG_ACPI_PROCFS
510 /* 'sleep' [R/W] */ 510 /* 'sleep' [R/W] */
511 entry = 511 entry =
512 create_proc_entry("sleep", S_IFREG | S_IRUGO | S_IWUSR, 512 create_proc_entry("sleep", S_IFREG | S_IRUGO | S_IWUSR,
diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c
index 1da64b4518c0..8cc9492ffbf2 100644
--- a/drivers/acpi/tables/tbutils.c
+++ b/drivers/acpi/tables/tbutils.c
@@ -51,6 +51,65 @@ ACPI_MODULE_NAME("tbutils")
51static acpi_physical_address 51static acpi_physical_address
52acpi_tb_get_root_table_entry(u8 * table_entry, 52acpi_tb_get_root_table_entry(u8 * table_entry,
53 acpi_native_uint table_entry_size); 53 acpi_native_uint table_entry_size);
54/*******************************************************************************
55 *
56 * FUNCTION: acpi_tb_check_xsdt
57 *
58 * PARAMETERS: address - Pointer to the XSDT
59 *
60 * RETURN: status
61 * AE_OK - XSDT is okay
62 * AE_NO_MEMORY - can't map XSDT
63 * AE_INVALID_TABLE_LENGTH - invalid table length
64 * AE_NULL_ENTRY - XSDT has NULL entry
65 *
66 * DESCRIPTION: validate XSDT
67******************************************************************************/
68
69static acpi_status
70acpi_tb_check_xsdt(acpi_physical_address address)
71{
72 struct acpi_table_header *table;
73 u32 length;
74 u64 xsdt_entry_address;
75 u8 *table_entry;
76 u32 table_count;
77 int i;
78
79 table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
80 if (!table)
81 return AE_NO_MEMORY;
82
83 length = table->length;
84 acpi_os_unmap_memory(table, sizeof(struct acpi_table_header));
85 if (length < sizeof(struct acpi_table_header))
86 return AE_INVALID_TABLE_LENGTH;
87
88 table = acpi_os_map_memory(address, length);
89 if (!table)
90 return AE_NO_MEMORY;
91
92 /* Calculate the number of tables described in XSDT */
93 table_count =
94 (u32) ((table->length -
95 sizeof(struct acpi_table_header)) / sizeof(u64));
96 table_entry =
97 ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header);
98 for (i = 0; i < table_count; i++) {
99 ACPI_MOVE_64_TO_64(&xsdt_entry_address, table_entry);
100 if (!xsdt_entry_address) {
101 /* XSDT has NULL entry */
102 break;
103 }
104 table_entry += sizeof(u64);
105 }
106 acpi_os_unmap_memory(table, length);
107
108 if (i < table_count)
109 return AE_NULL_ENTRY;
110 else
111 return AE_OK;
112}
54 113
55/******************************************************************************* 114/*******************************************************************************
56 * 115 *
@@ -341,6 +400,7 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
341 u32 table_count; 400 u32 table_count;
342 struct acpi_table_header *table; 401 struct acpi_table_header *table;
343 acpi_physical_address address; 402 acpi_physical_address address;
403 acpi_physical_address rsdt_address;
344 u32 length; 404 u32 length;
345 u8 *table_entry; 405 u8 *table_entry;
346 acpi_status status; 406 acpi_status status;
@@ -369,6 +429,8 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
369 */ 429 */
370 address = (acpi_physical_address) rsdp->xsdt_physical_address; 430 address = (acpi_physical_address) rsdp->xsdt_physical_address;
371 table_entry_size = sizeof(u64); 431 table_entry_size = sizeof(u64);
432 rsdt_address = (acpi_physical_address)
433 rsdp->rsdt_physical_address;
372 } else { 434 } else {
373 /* Root table is an RSDT (32-bit physical addresses) */ 435 /* Root table is an RSDT (32-bit physical addresses) */
374 436
@@ -382,6 +444,15 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)
382 */ 444 */
383 acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp)); 445 acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp));
384 446
447 if (table_entry_size == sizeof(u64)) {
448 if (acpi_tb_check_xsdt(address) == AE_NULL_ENTRY) {
449 /* XSDT has NULL entry, RSDT is used */
450 address = rsdt_address;
451 table_entry_size = sizeof(u32);
452 ACPI_WARNING((AE_INFO, "BIOS XSDT has NULL entry,"
453 "using RSDT"));
454 }
455 }
385 /* Map the RSDT/XSDT table header to get the full table length */ 456 /* Map the RSDT/XSDT table header to get the full table length */
386 457
387 table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); 458 table = acpi_os_map_memory(address, sizeof(struct acpi_table_header));
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 1e06159fd9c4..bc6d5866ef98 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -77,23 +77,27 @@ MODULE_LICENSE("GPL");
77 77
78static int act; 78static int act;
79module_param(act, int, 0644); 79module_param(act, int, 0644);
80MODULE_PARM_DESC(act, "Disable or override all lowest active trip points.\n"); 80MODULE_PARM_DESC(act, "Disable or override all lowest active trip points.");
81
82static int crt;
83module_param(crt, int, 0644);
84MODULE_PARM_DESC(crt, "Disable or lower all critical trip points.");
81 85
82static int tzp; 86static int tzp;
83module_param(tzp, int, 0444); 87module_param(tzp, int, 0444);
84MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n"); 88MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.");
85 89
86static int nocrt; 90static int nocrt;
87module_param(nocrt, int, 0); 91module_param(nocrt, int, 0);
88MODULE_PARM_DESC(nocrt, "Set to disable action on ACPI thermal zone critical and hot trips.\n"); 92MODULE_PARM_DESC(nocrt, "Set to take no action upon ACPI thermal zone critical trips points.");
89 93
90static int off; 94static int off;
91module_param(off, int, 0); 95module_param(off, int, 0);
92MODULE_PARM_DESC(off, "Set to disable ACPI thermal support.\n"); 96MODULE_PARM_DESC(off, "Set to disable ACPI thermal support.");
93 97
94static int psv; 98static int psv;
95module_param(psv, int, 0644); 99module_param(psv, int, 0644);
96MODULE_PARM_DESC(psv, "Disable or override all passive trip points.\n"); 100MODULE_PARM_DESC(psv, "Disable or override all passive trip points.");
97 101
98static int acpi_thermal_add(struct acpi_device *device); 102static int acpi_thermal_add(struct acpi_device *device);
99static int acpi_thermal_remove(struct acpi_device *device, int type); 103static int acpi_thermal_remove(struct acpi_device *device, int type);
@@ -340,6 +344,20 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
340 tz->trips.critical.temperature)); 344 tz->trips.critical.temperature));
341 } 345 }
342 346
347 if (tz->trips.critical.flags.valid == 1) {
348 if (crt == -1) {
349 tz->trips.critical.flags.valid = 0;
350 } else if (crt > 0) {
351 unsigned long crt_k = CELSIUS_TO_KELVIN(crt);
352
353 /*
354 * Allow override to lower critical threshold
355 */
356 if (crt_k < tz->trips.critical.temperature)
357 tz->trips.critical.temperature = crt_k;
358 }
359 }
360
343 /* Critical Sleep (optional) */ 361 /* Critical Sleep (optional) */
344 362
345 status = 363 status =
@@ -485,8 +503,12 @@ static int acpi_thermal_critical(struct acpi_thermal *tz)
485 printk(KERN_EMERG 503 printk(KERN_EMERG
486 "Critical temperature reached (%ld C), shutting down.\n", 504 "Critical temperature reached (%ld C), shutting down.\n",
487 KELVIN_TO_CELSIUS(tz->temperature)); 505 KELVIN_TO_CELSIUS(tz->temperature));
488 acpi_bus_generate_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL, 506 acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL,
489 tz->trips.critical.flags.enabled); 507 tz->trips.critical.flags.enabled);
508 acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
509 tz->device->dev.bus_id,
510 ACPI_THERMAL_NOTIFY_CRITICAL,
511 tz->trips.critical.flags.enabled);
490 512
491 orderly_poweroff(true); 513 orderly_poweroff(true);
492 514
@@ -504,8 +526,12 @@ static int acpi_thermal_hot(struct acpi_thermal *tz)
504 } else if (tz->trips.hot.flags.enabled) 526 } else if (tz->trips.hot.flags.enabled)
505 tz->trips.hot.flags.enabled = 0; 527 tz->trips.hot.flags.enabled = 0;
506 528
507 acpi_bus_generate_event(tz->device, ACPI_THERMAL_NOTIFY_HOT, 529 acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_HOT,
508 tz->trips.hot.flags.enabled); 530 tz->trips.hot.flags.enabled);
531 acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
532 tz->device->dev.bus_id,
533 ACPI_THERMAL_NOTIFY_HOT,
534 tz->trips.hot.flags.enabled);
509 535
510 /* TBD: Call user-mode "sleep(S4)" function */ 536 /* TBD: Call user-mode "sleep(S4)" function */
511 537
@@ -1067,9 +1093,9 @@ static int acpi_thermal_add_fs(struct acpi_device *device)
1067 entry->owner = THIS_MODULE; 1093 entry->owner = THIS_MODULE;
1068 } 1094 }
1069 1095
1070 /* 'trip_points' [R/W] */ 1096 /* 'trip_points' [R] */
1071 entry = create_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS, 1097 entry = create_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS,
1072 S_IFREG | S_IRUGO | S_IWUSR, 1098 S_IRUGO,
1073 acpi_device_dir(device)); 1099 acpi_device_dir(device));
1074 if (!entry) 1100 if (!entry)
1075 return -ENODEV; 1101 return -ENODEV;
@@ -1149,12 +1175,16 @@ static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
1149 case ACPI_THERMAL_NOTIFY_THRESHOLDS: 1175 case ACPI_THERMAL_NOTIFY_THRESHOLDS:
1150 acpi_thermal_get_trip_points(tz); 1176 acpi_thermal_get_trip_points(tz);
1151 acpi_thermal_check(tz); 1177 acpi_thermal_check(tz);
1152 acpi_bus_generate_event(device, event, 0); 1178 acpi_bus_generate_proc_event(device, event, 0);
1179 acpi_bus_generate_netlink_event(device->pnp.device_class,
1180 device->dev.bus_id, event, 0);
1153 break; 1181 break;
1154 case ACPI_THERMAL_NOTIFY_DEVICES: 1182 case ACPI_THERMAL_NOTIFY_DEVICES:
1155 if (tz->flags.devices) 1183 if (tz->flags.devices)
1156 acpi_thermal_get_devices(tz); 1184 acpi_thermal_get_devices(tz);
1157 acpi_bus_generate_event(device, event, 0); 1185 acpi_bus_generate_proc_event(device, event, 0);
1186 acpi_bus_generate_netlink_event(device->pnp.device_class,
1187 device->dev.bus_id, event, 0);
1158 break; 1188 break;
1159 default: 1189 default:
1160 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 1190 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -1339,6 +1369,13 @@ static int thermal_act(struct dmi_system_id *d) {
1339 } 1369 }
1340 return 0; 1370 return 0;
1341} 1371}
1372static int thermal_nocrt(struct dmi_system_id *d) {
1373
1374 printk(KERN_NOTICE "ACPI: %s detected: "
1375 "disabling all critical thermal trip point actions.\n", d->ident);
1376 nocrt = 1;
1377 return 0;
1378}
1342static int thermal_tzp(struct dmi_system_id *d) { 1379static int thermal_tzp(struct dmi_system_id *d) {
1343 1380
1344 if (tzp == 0) { 1381 if (tzp == 0) {
@@ -1387,6 +1424,14 @@ static struct dmi_system_id thermal_dmi_table[] __initdata = {
1387 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), 1424 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
1388 }, 1425 },
1389 }, 1426 },
1427 {
1428 .callback = thermal_nocrt,
1429 .ident = "Gigabyte GA-7ZX",
1430 .matches = {
1431 DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."),
1432 DMI_MATCH(DMI_BOARD_NAME, "7ZX"),
1433 },
1434 },
1390 {} 1435 {}
1391}; 1436};
1392#endif /* CONFIG_DMI */ 1437#endif /* CONFIG_DMI */
diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c
index 1621655d6e2b..93ea8290b4f7 100644
--- a/drivers/acpi/utilities/utglobal.c
+++ b/drivers/acpi/utilities/utglobal.c
@@ -126,6 +126,7 @@ const char *acpi_format_exception(acpi_status status)
126 "Unknown exception code: 0x%8.8X", status)); 126 "Unknown exception code: 0x%8.8X", status));
127 127
128 exception = "UNKNOWN_STATUS_CODE"; 128 exception = "UNKNOWN_STATUS_CODE";
129 dump_stack();
129 } 130 }
130 131
131 return (ACPI_CAST_PTR(const char, exception)); 132 return (ACPI_CAST_PTR(const char, exception));
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index d98701941981..d05891f16282 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -31,7 +31,7 @@
31#include <linux/list.h> 31#include <linux/list.h>
32#include <linux/proc_fs.h> 32#include <linux/proc_fs.h>
33#include <linux/seq_file.h> 33#include <linux/seq_file.h>
34 34#include <linux/input.h>
35#include <linux/backlight.h> 35#include <linux/backlight.h>
36#include <linux/video_output.h> 36#include <linux/video_output.h>
37#include <asm/uaccess.h> 37#include <asm/uaccess.h>
@@ -138,6 +138,8 @@ struct acpi_video_bus {
138 struct semaphore sem; 138 struct semaphore sem;
139 struct list_head video_device_list; 139 struct list_head video_device_list;
140 struct proc_dir_entry *dir; 140 struct proc_dir_entry *dir;
141 struct input_dev *input;
142 char phys[32]; /* for input device */
141}; 143};
142 144
143struct acpi_video_device_flags { 145struct acpi_video_device_flags {
@@ -415,7 +417,6 @@ acpi_video_device_lcd_set_level(struct acpi_video_device *device, int level)
415 arg0.integer.value = level; 417 arg0.integer.value = level;
416 status = acpi_evaluate_object(device->dev->handle, "_BCM", &args, NULL); 418 status = acpi_evaluate_object(device->dev->handle, "_BCM", &args, NULL);
417 419
418 printk(KERN_DEBUG "set_level status: %x\n", status);
419 return status; 420 return status;
420} 421}
421 422
@@ -1752,7 +1753,7 @@ static int acpi_video_bus_put_devices(struct acpi_video_bus *video)
1752 1753
1753static int acpi_video_bus_start_devices(struct acpi_video_bus *video) 1754static int acpi_video_bus_start_devices(struct acpi_video_bus *video)
1754{ 1755{
1755 return acpi_video_bus_DOS(video, 1, 0); 1756 return acpi_video_bus_DOS(video, 0, 0);
1756} 1757}
1757 1758
1758static int acpi_video_bus_stop_devices(struct acpi_video_bus *video) 1759static int acpi_video_bus_stop_devices(struct acpi_video_bus *video)
@@ -1764,6 +1765,9 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
1764{ 1765{
1765 struct acpi_video_bus *video = data; 1766 struct acpi_video_bus *video = data;
1766 struct acpi_device *device = NULL; 1767 struct acpi_device *device = NULL;
1768 struct input_dev *input;
1769 int keycode;
1770
1767 1771
1768 printk("video bus notify\n"); 1772 printk("video bus notify\n");
1769 1773
@@ -1771,11 +1775,13 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
1771 return; 1775 return;
1772 1776
1773 device = video->device; 1777 device = video->device;
1778 input = video->input;
1774 1779
1775 switch (event) { 1780 switch (event) {
1776 case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch, 1781 case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch,
1777 * most likely via hotkey. */ 1782 * most likely via hotkey. */
1778 acpi_bus_generate_event(device, event, 0); 1783 acpi_bus_generate_proc_event(device, event, 0);
1784 keycode = KEY_SWITCHVIDEOMODE;
1779 break; 1785 break;
1780 1786
1781 case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video 1787 case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video
@@ -1783,22 +1789,38 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data)
1783 acpi_video_device_enumerate(video); 1789 acpi_video_device_enumerate(video);
1784 acpi_video_device_rebind(video); 1790 acpi_video_device_rebind(video);
1785 acpi_video_switch_output(video, event); 1791 acpi_video_switch_output(video, event);
1786 acpi_bus_generate_event(device, event, 0); 1792 acpi_bus_generate_proc_event(device, event, 0);
1793 keycode = KEY_SWITCHVIDEOMODE;
1787 break; 1794 break;
1788 1795
1789 case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */ 1796 case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */
1797 acpi_video_switch_output(video, event);
1798 acpi_bus_generate_proc_event(device, event, 0);
1799 keycode = KEY_SWITCHVIDEOMODE;
1800 break;
1790 case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */ 1801 case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */
1802 acpi_video_switch_output(video, event);
1803 acpi_bus_generate_proc_event(device, event, 0);
1804 keycode = KEY_VIDEO_NEXT;
1805 break;
1791 case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */ 1806 case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */
1792 acpi_video_switch_output(video, event); 1807 acpi_video_switch_output(video, event);
1793 acpi_bus_generate_event(device, event, 0); 1808 acpi_bus_generate_proc_event(device, event, 0);
1809 keycode = KEY_VIDEO_PREV;
1794 break; 1810 break;
1795 1811
1796 default: 1812 default:
1813 keycode = KEY_UNKNOWN;
1797 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 1814 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1798 "Unsupported event [0x%x]\n", event)); 1815 "Unsupported event [0x%x]\n", event));
1799 break; 1816 break;
1800 } 1817 }
1801 1818
1819 input_report_key(input, keycode, 1);
1820 input_sync(input);
1821 input_report_key(input, keycode, 0);
1822 input_sync(input);
1823
1802 return; 1824 return;
1803} 1825}
1804 1826
@@ -1806,38 +1828,65 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data)
1806{ 1828{
1807 struct acpi_video_device *video_device = data; 1829 struct acpi_video_device *video_device = data;
1808 struct acpi_device *device = NULL; 1830 struct acpi_device *device = NULL;
1831 struct acpi_video_bus *bus;
1832 struct input_dev *input;
1833 int keycode;
1809 1834
1810 if (!video_device) 1835 if (!video_device)
1811 return; 1836 return;
1812 1837
1813 device = video_device->dev; 1838 device = video_device->dev;
1839 bus = video_device->video;
1840 input = bus->input;
1814 1841
1815 switch (event) { 1842 switch (event) {
1816 case ACPI_VIDEO_NOTIFY_SWITCH: /* change in status (cycle output device) */
1817 case ACPI_VIDEO_NOTIFY_PROBE: /* change in status (output device status) */
1818 acpi_bus_generate_event(device, event, 0);
1819 break;
1820 case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */ 1843 case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */
1844 acpi_video_switch_brightness(video_device, event);
1845 acpi_bus_generate_proc_event(device, event, 0);
1846 keycode = KEY_BRIGHTNESS_CYCLE;
1847 break;
1821 case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */ 1848 case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */
1849 acpi_video_switch_brightness(video_device, event);
1850 acpi_bus_generate_proc_event(device, event, 0);
1851 keycode = KEY_BRIGHTNESSUP;
1852 break;
1822 case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */ 1853 case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */
1854 acpi_video_switch_brightness(video_device, event);
1855 acpi_bus_generate_proc_event(device, event, 0);
1856 keycode = KEY_BRIGHTNESSDOWN;
1857 break;
1823 case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */ 1858 case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */
1859 acpi_video_switch_brightness(video_device, event);
1860 acpi_bus_generate_proc_event(device, event, 0);
1861 keycode = KEY_BRIGHTNESS_ZERO;
1862 break;
1824 case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */ 1863 case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */
1825 acpi_video_switch_brightness(video_device, event); 1864 acpi_video_switch_brightness(video_device, event);
1826 acpi_bus_generate_event(device, event, 0); 1865 acpi_bus_generate_proc_event(device, event, 0);
1866 keycode = KEY_DISPLAY_OFF;
1827 break; 1867 break;
1828 default: 1868 default:
1869 keycode = KEY_UNKNOWN;
1829 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 1870 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1830 "Unsupported event [0x%x]\n", event)); 1871 "Unsupported event [0x%x]\n", event));
1831 break; 1872 break;
1832 } 1873 }
1874
1875 input_report_key(input, keycode, 1);
1876 input_sync(input);
1877 input_report_key(input, keycode, 0);
1878 input_sync(input);
1879
1833 return; 1880 return;
1834} 1881}
1835 1882
1883static int instance;
1836static int acpi_video_bus_add(struct acpi_device *device) 1884static int acpi_video_bus_add(struct acpi_device *device)
1837{ 1885{
1838 int result = 0; 1886 int result = 0;
1839 acpi_status status = 0; 1887 acpi_status status = 0;
1840 struct acpi_video_bus *video = NULL; 1888 struct acpi_video_bus *video = NULL;
1889 struct input_dev *input;
1841 1890
1842 1891
1843 if (!device) 1892 if (!device)
@@ -1847,6 +1896,13 @@ static int acpi_video_bus_add(struct acpi_device *device)
1847 if (!video) 1896 if (!video)
1848 return -ENOMEM; 1897 return -ENOMEM;
1849 1898
1899 /* a hack to fix the duplicate name "VID" problem on T61 */
1900 if (!strcmp(device->pnp.bus_id, "VID")) {
1901 if (instance)
1902 device->pnp.bus_id[3] = '0' + instance;
1903 instance ++;
1904 }
1905
1850 video->device = device; 1906 video->device = device;
1851 strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); 1907 strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME);
1852 strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); 1908 strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS);
@@ -1881,6 +1937,39 @@ static int acpi_video_bus_add(struct acpi_device *device)
1881 goto end; 1937 goto end;
1882 } 1938 }
1883 1939
1940
1941 video->input = input = input_allocate_device();
1942
1943 snprintf(video->phys, sizeof(video->phys),
1944 "%s/video/input0", acpi_device_hid(video->device));
1945
1946 input->name = acpi_device_name(video->device);
1947 input->phys = video->phys;
1948 input->id.bustype = BUS_HOST;
1949 input->id.product = 0x06;
1950 input->evbit[0] = BIT(EV_KEY);
1951 set_bit(KEY_SWITCHVIDEOMODE, input->keybit);
1952 set_bit(KEY_VIDEO_NEXT, input->keybit);
1953 set_bit(KEY_VIDEO_PREV, input->keybit);
1954 set_bit(KEY_BRIGHTNESS_CYCLE, input->keybit);
1955 set_bit(KEY_BRIGHTNESSUP, input->keybit);
1956 set_bit(KEY_BRIGHTNESSDOWN, input->keybit);
1957 set_bit(KEY_BRIGHTNESS_ZERO, input->keybit);
1958 set_bit(KEY_DISPLAY_OFF, input->keybit);
1959 set_bit(KEY_UNKNOWN, input->keybit);
1960 result = input_register_device(input);
1961 if (result) {
1962 acpi_remove_notify_handler(video->device->handle,
1963 ACPI_DEVICE_NOTIFY,
1964 acpi_video_bus_notify);
1965 acpi_video_bus_stop_devices(video);
1966 acpi_video_bus_put_devices(video);
1967 kfree(video->attached_array);
1968 acpi_video_bus_remove_fs(device);
1969 goto end;
1970 }
1971
1972
1884 printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", 1973 printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n",
1885 ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), 1974 ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device),
1886 video->flags.multihead ? "yes" : "no", 1975 video->flags.multihead ? "yes" : "no",
@@ -1914,6 +2003,7 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type)
1914 acpi_video_bus_put_devices(video); 2003 acpi_video_bus_put_devices(video);
1915 acpi_video_bus_remove_fs(device); 2004 acpi_video_bus_remove_fs(device);
1916 2005
2006 input_unregister_device(video->input);
1917 kfree(video->attached_array); 2007 kfree(video->attached_array);
1918 kfree(video); 2008 kfree(video);
1919 2009