diff options
Diffstat (limited to 'drivers/acpi')
-rw-r--r-- | drivers/acpi/Kconfig | 18 | ||||
-rw-r--r-- | drivers/acpi/ac.c | 5 | ||||
-rw-r--r-- | drivers/acpi/asus_acpi.c | 2 | ||||
-rw-r--r-- | drivers/acpi/battery.c | 52 | ||||
-rw-r--r-- | drivers/acpi/bus.c | 10 | ||||
-rw-r--r-- | drivers/acpi/button.c | 2 | ||||
-rw-r--r-- | drivers/acpi/ec.c | 50 | ||||
-rw-r--r-- | drivers/acpi/event.c | 22 | ||||
-rw-r--r-- | drivers/acpi/hardware/hwsleep.c | 19 | ||||
-rw-r--r-- | drivers/acpi/namespace/nsxfeval.c | 2 | ||||
-rw-r--r-- | drivers/acpi/processor_core.c | 36 | ||||
-rw-r--r-- | drivers/acpi/processor_idle.c | 51 | ||||
-rw-r--r-- | drivers/acpi/sbs.c | 3 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 5 | ||||
-rw-r--r-- | drivers/acpi/sleep/Makefile | 4 | ||||
-rw-r--r-- | drivers/acpi/sleep/main.c | 63 | ||||
-rw-r--r-- | drivers/acpi/sleep/poweroff.c | 75 | ||||
-rw-r--r-- | drivers/acpi/sleep/proc.c | 10 | ||||
-rw-r--r-- | drivers/acpi/tables/tbutils.c | 71 | ||||
-rw-r--r-- | drivers/acpi/thermal.c | 67 | ||||
-rw-r--r-- | drivers/acpi/utilities/utglobal.c | 1 | ||||
-rw-r--r-- | drivers/acpi/video.c | 112 |
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 | ||
71 | config 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 | |||
71 | config ACPI_AC | 89 | config 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 | ||
116 | enum acpi_battery_files { | 116 | enum 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 | ||
131 | struct acpi_battery { | 131 | struct 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 | ||
142 | inline int acpi_battery_present(struct acpi_battery *battery) | 141 | inline 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 | ||
279 | static DEFINE_SPINLOCK(acpi_bus_event_lock); | 280 | static DEFINE_SPINLOCK(acpi_bus_event_lock); |
280 | 281 | ||
281 | LIST_HEAD(acpi_bus_event_list); | 282 | LIST_HEAD(acpi_bus_event_list); |
@@ -283,7 +284,7 @@ DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue); | |||
283 | 284 | ||
284 | extern int event_is_open; | 285 | extern int event_is_open; |
285 | 286 | ||
286 | int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data) | 287 | int 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 | ||
321 | EXPORT_SYMBOL(acpi_bus_generate_event); | 318 | EXPORT_SYMBOL(acpi_bus_generate_proc_event); |
322 | 319 | ||
323 | int acpi_bus_receive_event(struct acpi_bus_event *event) | 320 | int 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 | ||
366 | EXPORT_SYMBOL(acpi_bus_receive_event); | 363 | EXPORT_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 | ||
699 | static 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 | |||
707 | static int acpi_ec_add(struct acpi_device *device) | 699 | static 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 | ||
836 | static int acpi_ec_stop(struct acpi_device *device, int type) | 836 | static 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 |
18 | ACPI_MODULE_NAME("event"); | 18 | ACPI_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 */ |
21 | static DEFINE_SPINLOCK(acpi_system_event_lock); | 22 | static DEFINE_SPINLOCK(acpi_system_event_lock); |
22 | int event_is_open = 0; | 23 | int 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 |
111 | static unsigned int acpi_event_seqnum; | 113 | static 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 | ||
150 | int acpi_bus_generate_genetlink_event(struct acpi_device *device, | 152 | int 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 | ||
217 | EXPORT_SYMBOL(acpi_bus_generate_netlink_event); | ||
218 | |||
214 | static int acpi_event_genetlink_init(void) | 219 | static 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 |
231 | int acpi_bus_generate_genetlink_event(struct acpi_device *device, u8 type, | 236 | int 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 | ||
243 | EXPORT_SYMBOL(acpi_bus_generate_netlink_event); | ||
244 | |||
237 | static int acpi_event_genetlink_init(void) | 245 | static 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 | ||
243 | static int __init acpi_event_init(void) | 251 | static 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 | ||
542 | acpi_status | 542 | acpi_status |
543 | acpi_get_devices(char *HID, | 543 | acpi_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 | ||
729 | static 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 | |||
743 | static struct notifier_block acpi_cpu_notifier = | ||
744 | { | ||
745 | .notifier_call = acpi_cpu_soft_notify, | ||
746 | }; | ||
747 | |||
720 | static int acpi_processor_add(struct acpi_device *device) | 748 | static 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 | ||
985 | static | 1014 | static |
@@ -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 @@ | |||
63 | ACPI_MODULE_NAME("processor_idle"); | 63 | ACPI_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) */ |
68 | static void (*pm_idle_save) (void) __read_mostly; | 69 | static 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 | */ | ||
331 | static int acpi_idle_suspend; | ||
332 | |||
333 | int acpi_processor_suspend(struct acpi_device * device, pm_message_t state) | ||
334 | { | ||
335 | acpi_idle_suspend = 1; | ||
336 | return 0; | ||
337 | } | ||
338 | |||
339 | int acpi_processor_resume(struct acpi_device * device) | ||
340 | { | ||
341 | acpi_idle_suspend = 0; | ||
342 | return 0; | ||
343 | } | ||
344 | |||
327 | static void acpi_processor_idle(void) | 345 | static 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 | */ |
38 | int create_modalias(struct acpi_device *acpi_dev, char *modalias, int size){ | 38 | static 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 @@ | |||
1 | obj-y := poweroff.o wakeup.o | 1 | obj-y := wakeup.o |
2 | obj-$(CONFIG_ACPI_SLEEP) += main.o | 2 | obj-y += main.o |
3 | obj-$(CONFIG_ACPI_SLEEP) += proc.o | 3 | obj-$(CONFIG_ACPI_SLEEP) += proc.o |
4 | 4 | ||
5 | EXTRA_CFLAGS += $(ACPI_CFLAGS) | 5 | EXTRA_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 | ||
22 | u8 sleep_states[ACPI_S_STATE_COUNT]; | 25 | u8 sleep_states[ACPI_S_STATE_COUNT]; |
23 | 26 | ||
27 | #ifdef CONFIG_PM_SLEEP | ||
24 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; | 28 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; |
29 | #endif | ||
30 | |||
31 | int 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 |
27 | static struct pm_ops acpi_pm_ops; | 53 | static 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 | |||
381 | static void acpi_power_off_prepare(void) | ||
382 | { | ||
383 | /* Prepare to power off the system */ | ||
384 | acpi_sleep_prepare(ACPI_STATE_S5); | ||
385 | } | ||
386 | |||
387 | static 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 | ||
353 | int __init acpi_sleep_init(void) | 395 | int __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 | |||
19 | int 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 | |||
42 | static void acpi_power_off_prepare(void) | ||
43 | { | ||
44 | /* Prepare to power off the system */ | ||
45 | acpi_sleep_prepare(ACPI_STATE_S5); | ||
46 | } | ||
47 | |||
48 | static 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 | |||
57 | static 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 | |||
73 | late_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 | ||
25 | ACPI_MODULE_NAME("sleep") | 25 | ACPI_MODULE_NAME("sleep") |
26 | #ifdef CONFIG_ACPI_PROCFS_SLEEP | 26 | #ifdef CONFIG_ACPI_PROCFS |
27 | static int acpi_system_sleep_seq_show(struct seq_file *seq, void *offset) | 27 | static 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 |
475 | static const struct file_operations acpi_system_sleep_fops = { | 475 | static 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 |
485 | static const struct file_operations acpi_system_alarm_fops = { | 485 | static 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") | |||
51 | static acpi_physical_address | 51 | static acpi_physical_address |
52 | acpi_tb_get_root_table_entry(u8 * table_entry, | 52 | acpi_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 | |||
69 | static acpi_status | ||
70 | acpi_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 | ||
78 | static int act; | 78 | static int act; |
79 | module_param(act, int, 0644); | 79 | module_param(act, int, 0644); |
80 | MODULE_PARM_DESC(act, "Disable or override all lowest active trip points.\n"); | 80 | MODULE_PARM_DESC(act, "Disable or override all lowest active trip points."); |
81 | |||
82 | static int crt; | ||
83 | module_param(crt, int, 0644); | ||
84 | MODULE_PARM_DESC(crt, "Disable or lower all critical trip points."); | ||
81 | 85 | ||
82 | static int tzp; | 86 | static int tzp; |
83 | module_param(tzp, int, 0444); | 87 | module_param(tzp, int, 0444); |
84 | MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n"); | 88 | MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds."); |
85 | 89 | ||
86 | static int nocrt; | 90 | static int nocrt; |
87 | module_param(nocrt, int, 0); | 91 | module_param(nocrt, int, 0); |
88 | MODULE_PARM_DESC(nocrt, "Set to disable action on ACPI thermal zone critical and hot trips.\n"); | 92 | MODULE_PARM_DESC(nocrt, "Set to take no action upon ACPI thermal zone critical trips points."); |
89 | 93 | ||
90 | static int off; | 94 | static int off; |
91 | module_param(off, int, 0); | 95 | module_param(off, int, 0); |
92 | MODULE_PARM_DESC(off, "Set to disable ACPI thermal support.\n"); | 96 | MODULE_PARM_DESC(off, "Set to disable ACPI thermal support."); |
93 | 97 | ||
94 | static int psv; | 98 | static int psv; |
95 | module_param(psv, int, 0644); | 99 | module_param(psv, int, 0644); |
96 | MODULE_PARM_DESC(psv, "Disable or override all passive trip points.\n"); | 100 | MODULE_PARM_DESC(psv, "Disable or override all passive trip points."); |
97 | 101 | ||
98 | static int acpi_thermal_add(struct acpi_device *device); | 102 | static int acpi_thermal_add(struct acpi_device *device); |
99 | static int acpi_thermal_remove(struct acpi_device *device, int type); | 103 | static 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 | } |
1372 | static 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 | } | ||
1342 | static int thermal_tzp(struct dmi_system_id *d) { | 1379 | static 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 | ||
143 | struct acpi_video_device_flags { | 145 | struct 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 | ||
1753 | static int acpi_video_bus_start_devices(struct acpi_video_bus *video) | 1754 | static 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 | ||
1758 | static int acpi_video_bus_stop_devices(struct acpi_video_bus *video) | 1759 | static 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 | ||
1883 | static int instance; | ||
1836 | static int acpi_video_bus_add(struct acpi_device *device) | 1884 | static 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 | ||