aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/asus_acpi.c1
-rw-r--r--drivers/acpi/battery.c47
-rw-r--r--drivers/acpi/bay.c2
-rw-r--r--drivers/acpi/dock.c6
-rw-r--r--drivers/acpi/ec.c113
-rw-r--r--drivers/acpi/tables/tbxface.c23
-rw-r--r--drivers/acpi/thermal.c143
-rw-r--r--drivers/char/sonypi.c7
-rw-r--r--drivers/misc/Kconfig22
-rw-r--r--drivers/misc/sony-laptop.c7
-rw-r--r--drivers/misc/thinkpad_acpi.c10
-rw-r--r--drivers/misc/thinkpad_acpi.h2
12 files changed, 256 insertions, 127 deletions
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
index 9c4bd220c44f..86fd142f4bf3 100644
--- a/drivers/acpi/asus_acpi.c
+++ b/drivers/acpi/asus_acpi.c
@@ -1192,6 +1192,7 @@ static int asus_hotk_get_info(void)
1192 break; 1192 break;
1193 default: 1193 default:
1194 kfree(model); 1194 kfree(model);
1195 model = NULL;
1195 break; 1196 break;
1196 } 1197 }
1197 } 1198 }
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 81651032791b..d7b499fe0cd9 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,13 +129,14 @@ struct acpi_battery_flags {
129}; 129};
130 130
131struct acpi_battery { 131struct acpi_battery {
132 struct mutex mutex;
133 struct acpi_device *device; 132 struct acpi_device *device;
134 struct acpi_battery_flags flags; 133 struct acpi_battery_flags flags;
135 struct acpi_buffer bif_data; 134 struct acpi_buffer bif_data;
136 struct acpi_buffer bst_data; 135 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
139}; 140};
140 141
141inline int acpi_battery_present(struct acpi_battery *battery) 142inline int acpi_battery_present(struct acpi_battery *battery)
@@ -235,10 +236,10 @@ static int acpi_battery_get_info(struct acpi_battery *battery)
235 return 0; 236 return 0;
236 237
237 /* Evaluate _BIF */ 238 /* Evaluate _BIF */
238 239 mutex_lock(&battery->lock);
239 status = 240 status = acpi_evaluate_object(acpi_battery_handle(battery), "_BIF",
240 acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL, 241 NULL, &buffer);
241 &buffer); 242 mutex_unlock(&battery->lock);
242 if (ACPI_FAILURE(status)) { 243 if (ACPI_FAILURE(status)) {
243 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); 244 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF"));
244 return -ENODEV; 245 return -ENODEV;
@@ -285,10 +286,10 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
285 return 0; 286 return 0;
286 287
287 /* Evaluate _BST */ 288 /* Evaluate _BST */
288 289 mutex_lock(&battery->lock);
289 status = 290 status = acpi_evaluate_object(acpi_battery_handle(battery), "_BST",
290 acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL, 291 NULL, &buffer);
291 &buffer); 292 mutex_unlock(&battery->lock);
292 if (ACPI_FAILURE(status)) { 293 if (ACPI_FAILURE(status)) {
293 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); 294 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST"));
294 return -ENODEV; 295 return -ENODEV;
@@ -336,9 +337,10 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,
336 337
337 arg0.integer.value = alarm; 338 arg0.integer.value = alarm;
338 339
339 status = 340 mutex_lock(&battery->lock);
340 acpi_evaluate_object(acpi_battery_handle(battery), "_BTP", 341 status = acpi_evaluate_object(acpi_battery_handle(battery), "_BTP",
341 &arg_list, NULL); 342 &arg_list, NULL);
343 mutex_unlock(&battery->lock);
342 if (ACPI_FAILURE(status)) 344 if (ACPI_FAILURE(status))
343 return -ENODEV; 345 return -ENODEV;
344 346
@@ -658,8 +660,6 @@ acpi_battery_write_alarm(struct file *file,
658 if (!battery || (count > sizeof(alarm_string) - 1)) 660 if (!battery || (count > sizeof(alarm_string) - 1))
659 return -EINVAL; 661 return -EINVAL;
660 662
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,9 +688,7 @@ 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 result = count; 691 return count;
692
693 mutex_unlock(&battery->mutex);
694 692
695 return result; 693 return result;
696} 694}
@@ -714,8 +712,6 @@ static int acpi_battery_read(int fid, struct seq_file *seq)
714 int update_result = ACPI_BATTERY_NONE_UPDATE; 712 int update_result = ACPI_BATTERY_NONE_UPDATE;
715 int update = 0; 713 int update = 0;
716 714
717 mutex_lock(&battery->mutex);
718
719 update = (get_seconds() - battery->update_time[fid] >= update_time); 715 update = (get_seconds() - battery->update_time[fid] >= update_time);
720 update = (update | battery->flags.update[fid]); 716 update = (update | battery->flags.update[fid]);
721 717
@@ -733,7 +729,6 @@ static int acpi_battery_read(int fid, struct seq_file *seq)
733 result = acpi_read_funcs[fid].print(seq, result); 729 result = acpi_read_funcs[fid].print(seq, result);
734 acpi_battery_check_result(battery, result); 730 acpi_battery_check_result(battery, result);
735 battery->flags.update[fid] = result; 731 battery->flags.update[fid] = result;
736 mutex_unlock(&battery->mutex);
737 return result; 732 return result;
738} 733}
739 734
@@ -897,10 +892,7 @@ static int acpi_battery_add(struct acpi_device *device)
897 if (!battery) 892 if (!battery)
898 return -ENOMEM; 893 return -ENOMEM;
899 894
900 mutex_init(&battery->mutex); 895 mutex_init(&battery->lock);
901
902 mutex_lock(&battery->mutex);
903
904 battery->device = device; 896 battery->device = device;
905 strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); 897 strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME);
906 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); 898 strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS);
@@ -936,7 +928,6 @@ static int acpi_battery_add(struct acpi_device *device)
936 kfree(battery); 928 kfree(battery);
937 } 929 }
938 930
939 mutex_unlock(&battery->mutex);
940 931
941 return result; 932 return result;
942} 933}
@@ -951,8 +942,6 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
951 942
952 battery = acpi_driver_data(device); 943 battery = acpi_driver_data(device);
953 944
954 mutex_lock(&battery->mutex);
955
956 status = acpi_remove_notify_handler(device->handle, 945 status = acpi_remove_notify_handler(device->handle,
957 ACPI_ALL_NOTIFY, 946 ACPI_ALL_NOTIFY,
958 acpi_battery_notify); 947 acpi_battery_notify);
@@ -963,9 +952,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
963 952
964 kfree(battery->bst_data.pointer); 953 kfree(battery->bst_data.pointer);
965 954
966 mutex_unlock(&battery->mutex); 955 mutex_destroy(&battery->lock);
967
968 mutex_destroy(&battery->mutex);
969 956
970 kfree(battery); 957 kfree(battery);
971 958
diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c
index 56a5b3fffeb3..6daf6088ac88 100644
--- a/drivers/acpi/bay.c
+++ b/drivers/acpi/bay.c
@@ -337,7 +337,7 @@ static void bay_notify(acpi_handle handle, u32 event, void *data)
337 char *envp[] = { event_string, NULL }; 337 char *envp[] = { event_string, NULL };
338 338
339 bay_dprintk(handle, "Bay event"); 339 bay_dprintk(handle, "Bay event");
340 sprintf(event_string, "BAY_EVENT=%d\n", event); 340 sprintf(event_string, "BAY_EVENT=%d", event);
341 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp); 341 kobject_uevent_env(&dev->kobj, KOBJ_CHANGE, envp);
342} 342}
343 343
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 6192c8be66df..1dabdf4c07b3 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -336,13 +336,13 @@ static void hotplug_dock_devices(struct dock_station *ds, u32 event)
336static void dock_event(struct dock_station *ds, u32 event, int num) 336static void dock_event(struct dock_station *ds, u32 event, int num)
337{ 337{
338 struct device *dev = &dock_device->dev; 338 struct device *dev = &dock_device->dev;
339 char event_string[7]; 339 char event_string[13];
340 char *envp[] = { event_string, NULL }; 340 char *envp[] = { event_string, NULL };
341 341
342 if (num == UNDOCK_EVENT) 342 if (num == UNDOCK_EVENT)
343 sprintf(event_string, "UNDOCK"); 343 sprintf(event_string, "EVENT=undock");
344 else 344 else
345 sprintf(event_string, "DOCK"); 345 sprintf(event_string, "EVENT=dock");
346 346
347 /* 347 /*
348 * Indicate that the status of the dock station has 348 * Indicate that the status of the dock station has
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 469f3f57f881..2300d81bbc4e 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -471,7 +471,6 @@ static void acpi_ec_gpe_query(void *ec_cxt)
471 } 471 }
472 } 472 }
473 mutex_unlock(&ec->lock); 473 mutex_unlock(&ec->lock);
474 printk(KERN_ERR PREFIX "Handler for query 0x%x is not found!\n", value);
475} 474}
476 475
477static u32 acpi_ec_gpe_handler(void *data) 476static u32 acpi_ec_gpe_handler(void *data)
@@ -653,42 +652,39 @@ static struct acpi_ec *make_acpi_ec(void)
653} 652}
654 653
655static acpi_status 654static acpi_status
656acpi_ec_register_query_methods(acpi_handle handle, u32 level, 655ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval)
657 void *context, void **return_value)
658{ 656{
659 struct acpi_namespace_node *node = handle; 657 acpi_status status;
660 struct acpi_ec *ec = context;
661 int value = 0;
662 if (sscanf(node->name.ascii, "_Q%x", &value) == 1) {
663 acpi_ec_add_query_handler(ec, value, handle, NULL, NULL);
664 }
665 return AE_OK;
666}
667 658
668static int ec_parse_device(struct acpi_ec *ec, acpi_handle handle) 659 struct acpi_ec *ec = context;
669{ 660 status = acpi_walk_resources(handle, METHOD_NAME__CRS,
670 if (ACPI_FAILURE(acpi_walk_resources(handle, METHOD_NAME__CRS, 661 ec_parse_io_ports, ec);
671 ec_parse_io_ports, ec))) 662 if (ACPI_FAILURE(status))
672 return -EINVAL; 663 return status;
673 664
674 /* Get GPE bit assignment (EC events). */ 665 /* Get GPE bit assignment (EC events). */
675 /* TODO: Add support for _GPE returning a package */ 666 /* TODO: Add support for _GPE returning a package */
676 if (ACPI_FAILURE(acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe))) 667 status = acpi_evaluate_integer(handle, "_GPE", NULL, &ec->gpe);
677 return -EINVAL; 668 if (ACPI_FAILURE(status))
669 return status;
678 670
679 /* Use the global lock for all EC transactions? */ 671 /* Use the global lock for all EC transactions? */
680 acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock); 672 acpi_evaluate_integer(handle, "_GLK", NULL, &ec->global_lock);
681 673
682 /* Find and register all query methods */
683 acpi_walk_namespace(ACPI_TYPE_METHOD, handle, 1,
684 acpi_ec_register_query_methods, ec, NULL);
685
686 ec->handle = handle; 674 ec->handle = handle;
687 675
688 printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx", 676 printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
689 ec->gpe, ec->command_addr, ec->data_addr); 677 ec->gpe, ec->command_addr, ec->data_addr);
690 678
691 return 0; 679 return AE_CTRL_TERMINATE;
680}
681
682static void ec_remove_handlers(struct acpi_ec *ec)
683{
684 acpi_remove_address_space_handler(ec->handle,
685 ACPI_ADR_SPACE_EC,
686 &acpi_ec_space_handler);
687 acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
692} 688}
693 689
694static int acpi_ec_add(struct acpi_device *device) 690static int acpi_ec_add(struct acpi_device *device)
@@ -705,7 +701,8 @@ static int acpi_ec_add(struct acpi_device *device)
705 if (!ec) 701 if (!ec)
706 return -ENOMEM; 702 return -ENOMEM;
707 703
708 if (ec_parse_device(ec, device->handle)) { 704 if (ec_parse_device(device->handle, 0, ec, NULL) !=
705 AE_CTRL_TERMINATE) {
709 kfree(ec); 706 kfree(ec);
710 return -EINVAL; 707 return -EINVAL;
711 } 708 }
@@ -713,16 +710,13 @@ static int acpi_ec_add(struct acpi_device *device)
713 /* Check if we found the boot EC */ 710 /* Check if we found the boot EC */
714 if (boot_ec) { 711 if (boot_ec) {
715 if (boot_ec->gpe == ec->gpe) { 712 if (boot_ec->gpe == ec->gpe) {
716 /* We might have incorrect info for GL at boot time */ 713 ec_remove_handlers(boot_ec);
717 mutex_lock(&boot_ec->lock); 714 mutex_destroy(&boot_ec->lock);
718 boot_ec->global_lock = ec->global_lock; 715 kfree(boot_ec);
719 /* Copy handlers from new ec into boot ec */ 716 first_ec = boot_ec = NULL;
720 list_splice(&ec->list, &boot_ec->list);
721 mutex_unlock(&boot_ec->lock);
722 kfree(ec);
723 ec = boot_ec;
724 } 717 }
725 } else 718 }
719 if (!first_ec)
726 first_ec = ec; 720 first_ec = ec;
727 ec->handle = device->handle; 721 ec->handle = device->handle;
728 acpi_driver_data(device) = ec; 722 acpi_driver_data(device) = ec;
@@ -734,14 +728,14 @@ static int acpi_ec_add(struct acpi_device *device)
734static int acpi_ec_remove(struct acpi_device *device, int type) 728static int acpi_ec_remove(struct acpi_device *device, int type)
735{ 729{
736 struct acpi_ec *ec; 730 struct acpi_ec *ec;
737 struct acpi_ec_query_handler *handler; 731 struct acpi_ec_query_handler *handler, *tmp;
738 732
739 if (!device) 733 if (!device)
740 return -EINVAL; 734 return -EINVAL;
741 735
742 ec = acpi_driver_data(device); 736 ec = acpi_driver_data(device);
743 mutex_lock(&ec->lock); 737 mutex_lock(&ec->lock);
744 list_for_each_entry(handler, &ec->list, node) { 738 list_for_each_entry_safe(handler, tmp, &ec->list, node) {
745 list_del(&handler->node); 739 list_del(&handler->node);
746 kfree(handler); 740 kfree(handler);
747 } 741 }
@@ -751,9 +745,6 @@ static int acpi_ec_remove(struct acpi_device *device, int type)
751 if (ec == first_ec) 745 if (ec == first_ec)
752 first_ec = NULL; 746 first_ec = NULL;
753 747
754 /* Don't touch boot EC */
755 if (boot_ec != ec)
756 kfree(ec);
757 return 0; 748 return 0;
758} 749}
759 750
@@ -817,9 +808,7 @@ static int acpi_ec_start(struct acpi_device *device)
817 if (!ec) 808 if (!ec)
818 return -EINVAL; 809 return -EINVAL;
819 810
820 /* Boot EC is already working */ 811 ret = ec_install_handlers(ec);
821 if (ec != boot_ec)
822 ret = ec_install_handlers(ec);
823 812
824 /* EC is fully operational, allow queries */ 813 /* EC is fully operational, allow queries */
825 atomic_set(&ec->query_pending, 0); 814 atomic_set(&ec->query_pending, 0);
@@ -829,7 +818,6 @@ static int acpi_ec_start(struct acpi_device *device)
829 818
830static int acpi_ec_stop(struct acpi_device *device, int type) 819static int acpi_ec_stop(struct acpi_device *device, int type)
831{ 820{
832 acpi_status status;
833 struct acpi_ec *ec; 821 struct acpi_ec *ec;
834 822
835 if (!device) 823 if (!device)
@@ -838,21 +826,7 @@ static int acpi_ec_stop(struct acpi_device *device, int type)
838 ec = acpi_driver_data(device); 826 ec = acpi_driver_data(device);
839 if (!ec) 827 if (!ec)
840 return -EINVAL; 828 return -EINVAL;
841 829 ec_remove_handlers(ec);
842 /* Don't touch boot EC */
843 if (ec == boot_ec)
844 return 0;
845
846 status = acpi_remove_address_space_handler(ec->handle,
847 ACPI_ADR_SPACE_EC,
848 &acpi_ec_space_handler);
849 if (ACPI_FAILURE(status))
850 return -ENODEV;
851
852 status = acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler);
853 if (ACPI_FAILURE(status))
854 return -ENODEV;
855
856 return 0; 830 return 0;
857} 831}
858 832
@@ -868,18 +842,21 @@ int __init acpi_ec_ecdt_probe(void)
868 /* 842 /*
869 * Generate a boot ec context 843 * Generate a boot ec context
870 */ 844 */
871
872 status = acpi_get_table(ACPI_SIG_ECDT, 1, 845 status = acpi_get_table(ACPI_SIG_ECDT, 1,
873 (struct acpi_table_header **)&ecdt_ptr); 846 (struct acpi_table_header **)&ecdt_ptr);
874 if (ACPI_FAILURE(status)) 847 if (ACPI_SUCCESS(status)) {
875 goto error; 848 printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n\n");
876 849 boot_ec->command_addr = ecdt_ptr->control.address;
877 printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n"); 850 boot_ec->data_addr = ecdt_ptr->data.address;
878 851 boot_ec->gpe = ecdt_ptr->gpe;
879 boot_ec->command_addr = ecdt_ptr->control.address; 852 boot_ec->handle = ACPI_ROOT_OBJECT;
880 boot_ec->data_addr = ecdt_ptr->data.address; 853 } else {
881 boot_ec->gpe = ecdt_ptr->gpe; 854 printk(KERN_DEBUG PREFIX "Look up EC in DSDT\n");
882 boot_ec->handle = ACPI_ROOT_OBJECT; 855 status = acpi_get_devices(ec_device_ids[0].id, ec_parse_device,
856 boot_ec, NULL);
857 if (ACPI_FAILURE(status))
858 goto error;
859 }
883 860
884 ret = ec_install_handlers(boot_ec); 861 ret = ec_install_handlers(boot_ec);
885 if (!ret) { 862 if (!ret) {
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
index 5b302c4e293f..a9e3331fee5d 100644
--- a/drivers/acpi/tables/tbxface.c
+++ b/drivers/acpi/tables/tbxface.c
@@ -52,6 +52,8 @@ ACPI_MODULE_NAME("tbxface")
52/* Local prototypes */ 52/* Local prototypes */
53static acpi_status acpi_tb_load_namespace(void); 53static acpi_status acpi_tb_load_namespace(void);
54 54
55static int no_auto_ssdt;
56
55/******************************************************************************* 57/*******************************************************************************
56 * 58 *
57 * FUNCTION: acpi_allocate_root_table 59 * FUNCTION: acpi_allocate_root_table
@@ -536,6 +538,10 @@ static acpi_status acpi_tb_load_namespace(void)
536 538
537 ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS")); 539 ACPI_INFO((AE_INFO, "Table DSDT replaced by host OS"));
538 acpi_tb_print_table_header(0, table); 540 acpi_tb_print_table_header(0, table);
541
542 if (no_auto_ssdt == 0) {
543 printk(KERN_WARNING "ACPI: DSDT override uses original SSDTs unless \"acpi_no_auto_ssdt\"");
544 }
539 } 545 }
540 546
541 status = 547 status =
@@ -577,6 +583,11 @@ static acpi_status acpi_tb_load_namespace(void)
577 continue; 583 continue;
578 } 584 }
579 585
586 if (no_auto_ssdt) {
587 printk(KERN_WARNING "ACPI: SSDT ignored due to \"acpi_no_auto_ssdt\"\n");
588 continue;
589 }
590
580 /* Ignore errors while loading tables, get as many as possible */ 591 /* Ignore errors while loading tables, get as many as possible */
581 592
582 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES); 593 (void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
@@ -622,3 +633,15 @@ acpi_status acpi_load_tables(void)
622} 633}
623 634
624ACPI_EXPORT_SYMBOL(acpi_load_tables) 635ACPI_EXPORT_SYMBOL(acpi_load_tables)
636
637
638static int __init acpi_no_auto_ssdt_setup(char *s) {
639
640 printk(KERN_NOTICE "ACPI: SSDT auto-load disabled\n");
641
642 no_auto_ssdt = 1;
643
644 return 1;
645}
646
647__setup("acpi_no_auto_ssdt", acpi_no_auto_ssdt_setup);
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 5a62de1b7f2a..1e06159fd9c4 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -33,6 +33,7 @@
33 33
34#include <linux/kernel.h> 34#include <linux/kernel.h>
35#include <linux/module.h> 35#include <linux/module.h>
36#include <linux/dmi.h>
36#include <linux/init.h> 37#include <linux/init.h>
37#include <linux/types.h> 38#include <linux/types.h>
38#include <linux/proc_fs.h> 39#include <linux/proc_fs.h>
@@ -74,10 +75,26 @@ MODULE_AUTHOR("Paul Diefenbaugh");
74MODULE_DESCRIPTION("ACPI Thermal Zone Driver"); 75MODULE_DESCRIPTION("ACPI Thermal Zone Driver");
75MODULE_LICENSE("GPL"); 76MODULE_LICENSE("GPL");
76 77
78static int act;
79module_param(act, int, 0644);
80MODULE_PARM_DESC(act, "Disable or override all lowest active trip points.\n");
81
77static int tzp; 82static int tzp;
78module_param(tzp, int, 0); 83module_param(tzp, int, 0444);
79MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n"); 84MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n");
80 85
86static int nocrt;
87module_param(nocrt, int, 0);
88MODULE_PARM_DESC(nocrt, "Set to disable action on ACPI thermal zone critical and hot trips.\n");
89
90static int off;
91module_param(off, int, 0);
92MODULE_PARM_DESC(off, "Set to disable ACPI thermal support.\n");
93
94static int psv;
95module_param(psv, int, 0644);
96MODULE_PARM_DESC(psv, "Disable or override all passive trip points.\n");
97
81static int acpi_thermal_add(struct acpi_device *device); 98static int acpi_thermal_add(struct acpi_device *device);
82static int acpi_thermal_remove(struct acpi_device *device, int type); 99static int acpi_thermal_remove(struct acpi_device *device, int type);
83static int acpi_thermal_resume(struct acpi_device *device); 100static int acpi_thermal_resume(struct acpi_device *device);
@@ -339,9 +356,16 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
339 356
340 /* Passive: Processors (optional) */ 357 /* Passive: Processors (optional) */
341 358
342 status = 359 if (psv == -1) {
343 acpi_evaluate_integer(tz->device->handle, "_PSV", NULL, 360 status = AE_SUPPORT;
344 &tz->trips.passive.temperature); 361 } else if (psv > 0) {
362 tz->trips.passive.temperature = CELSIUS_TO_KELVIN(psv);
363 status = AE_OK;
364 } else {
365 status = acpi_evaluate_integer(tz->device->handle,
366 "_PSV", NULL, &tz->trips.passive.temperature);
367 }
368
345 if (ACPI_FAILURE(status)) { 369 if (ACPI_FAILURE(status)) {
346 tz->trips.passive.flags.valid = 0; 370 tz->trips.passive.flags.valid = 0;
347 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No passive threshold\n")); 371 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No passive threshold\n"));
@@ -386,11 +410,33 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
386 410
387 char name[5] = { '_', 'A', 'C', ('0' + i), '\0' }; 411 char name[5] = { '_', 'A', 'C', ('0' + i), '\0' };
388 412
389 status = 413 if (act == -1)
390 acpi_evaluate_integer(tz->device->handle, name, NULL, 414 break; /* disable all active trip points */
391 &tz->trips.active[i].temperature); 415
392 if (ACPI_FAILURE(status)) 416 status = acpi_evaluate_integer(tz->device->handle,
417 name, NULL, &tz->trips.active[i].temperature);
418
419 if (ACPI_FAILURE(status)) {
420 if (i == 0) /* no active trip points */
421 break;
422 if (act <= 0) /* no override requested */
423 break;
424 if (i == 1) { /* 1 trip point */
425 tz->trips.active[0].temperature =
426 CELSIUS_TO_KELVIN(act);
427 } else { /* multiple trips */
428 /*
429 * Don't allow override higher than
430 * the next higher trip point
431 */
432 tz->trips.active[i - 1].temperature =
433 (tz->trips.active[i - 2].temperature <
434 CELSIUS_TO_KELVIN(act) ?
435 tz->trips.active[i - 2].temperature :
436 CELSIUS_TO_KELVIN(act));
437 }
393 break; 438 break;
439 }
394 440
395 name[2] = 'L'; 441 name[2] = 'L';
396 status = 442 status =
@@ -427,7 +473,7 @@ static int acpi_thermal_get_devices(struct acpi_thermal *tz)
427 473
428static int acpi_thermal_critical(struct acpi_thermal *tz) 474static int acpi_thermal_critical(struct acpi_thermal *tz)
429{ 475{
430 if (!tz || !tz->trips.critical.flags.valid) 476 if (!tz || !tz->trips.critical.flags.valid || nocrt)
431 return -EINVAL; 477 return -EINVAL;
432 478
433 if (tz->temperature >= tz->trips.critical.temperature) { 479 if (tz->temperature >= tz->trips.critical.temperature) {
@@ -449,7 +495,7 @@ static int acpi_thermal_critical(struct acpi_thermal *tz)
449 495
450static int acpi_thermal_hot(struct acpi_thermal *tz) 496static int acpi_thermal_hot(struct acpi_thermal *tz)
451{ 497{
452 if (!tz || !tz->trips.hot.flags.valid) 498 if (!tz || !tz->trips.hot.flags.valid || nocrt)
453 return -EINVAL; 499 return -EINVAL;
454 500
455 if (tz->temperature >= tz->trips.hot.temperature) { 501 if (tz->temperature >= tz->trips.hot.temperature) {
@@ -824,12 +870,14 @@ static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset)
824 goto end; 870 goto end;
825 871
826 if (tz->trips.critical.flags.valid) 872 if (tz->trips.critical.flags.valid)
827 seq_printf(seq, "critical (S5): %ld C\n", 873 seq_printf(seq, "critical (S5): %ld C%s",
828 KELVIN_TO_CELSIUS(tz->trips.critical.temperature)); 874 KELVIN_TO_CELSIUS(tz->trips.critical.temperature),
875 nocrt ? " <disabled>\n" : "\n");
829 876
830 if (tz->trips.hot.flags.valid) 877 if (tz->trips.hot.flags.valid)
831 seq_printf(seq, "hot (S4): %ld C\n", 878 seq_printf(seq, "hot (S4): %ld C%s",
832 KELVIN_TO_CELSIUS(tz->trips.hot.temperature)); 879 KELVIN_TO_CELSIUS(tz->trips.hot.temperature),
880 nocrt ? " <disabled>\n" : "\n");
833 881
834 if (tz->trips.passive.flags.valid) { 882 if (tz->trips.passive.flags.valid) {
835 seq_printf(seq, 883 seq_printf(seq,
@@ -1281,11 +1329,78 @@ static int acpi_thermal_resume(struct acpi_device *device)
1281 return AE_OK; 1329 return AE_OK;
1282} 1330}
1283 1331
1332#ifdef CONFIG_DMI
1333static int thermal_act(struct dmi_system_id *d) {
1334
1335 if (act == 0) {
1336 printk(KERN_NOTICE "ACPI: %s detected: "
1337 "disabling all active thermal trip points\n", d->ident);
1338 act = -1;
1339 }
1340 return 0;
1341}
1342static int thermal_tzp(struct dmi_system_id *d) {
1343
1344 if (tzp == 0) {
1345 printk(KERN_NOTICE "ACPI: %s detected: "
1346 "enabling thermal zone polling\n", d->ident);
1347 tzp = 300; /* 300 dS = 30 Seconds */
1348 }
1349 return 0;
1350}
1351static int thermal_psv(struct dmi_system_id *d) {
1352
1353 if (psv == 0) {
1354 printk(KERN_NOTICE "ACPI: %s detected: "
1355 "disabling all passive thermal trip points\n", d->ident);
1356 psv = -1;
1357 }
1358 return 0;
1359}
1360
1361static struct dmi_system_id thermal_dmi_table[] __initdata = {
1362 /*
1363 * Award BIOS on this AOpen makes thermal control almost worthless.
1364 * http://bugzilla.kernel.org/show_bug.cgi?id=8842
1365 */
1366 {
1367 .callback = thermal_act,
1368 .ident = "AOpen i915GMm-HFS",
1369 .matches = {
1370 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
1371 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
1372 },
1373 },
1374 {
1375 .callback = thermal_psv,
1376 .ident = "AOpen i915GMm-HFS",
1377 .matches = {
1378 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
1379 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
1380 },
1381 },
1382 {
1383 .callback = thermal_tzp,
1384 .ident = "AOpen i915GMm-HFS",
1385 .matches = {
1386 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
1387 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
1388 },
1389 },
1390 {}
1391};
1392#endif /* CONFIG_DMI */
1393
1284static int __init acpi_thermal_init(void) 1394static int __init acpi_thermal_init(void)
1285{ 1395{
1286 int result = 0; 1396 int result = 0;
1287 1397
1398 dmi_check_system(thermal_dmi_table);
1288 1399
1400 if (off) {
1401 printk(KERN_NOTICE "ACPI: thermal control disabled\n");
1402 return -ENODEV;
1403 }
1289 acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir); 1404 acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir);
1290 if (!acpi_thermal_dir) 1405 if (!acpi_thermal_dir)
1291 return -ENODEV; 1406 return -ENODEV;
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index 73037a4d3c50..aeec67e27264 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -1147,10 +1147,15 @@ static int sonypi_acpi_remove(struct acpi_device *device, int type)
1147 return 0; 1147 return 0;
1148} 1148}
1149 1149
1150const static struct acpi_device_id sonypi_device_ids[] = {
1151 {"SNY6001", 0},
1152 {"", 0},
1153};
1154
1150static struct acpi_driver sonypi_acpi_driver = { 1155static struct acpi_driver sonypi_acpi_driver = {
1151 .name = "sonypi", 1156 .name = "sonypi",
1152 .class = "hkey", 1157 .class = "hkey",
1153 .ids = "SNY6001", 1158 .ids = sonypi_device_ids,
1154 .ops = { 1159 .ops = {
1155 .add = sonypi_acpi_add, 1160 .add = sonypi_acpi_add,
1156 .remove = sonypi_acpi_remove, 1161 .remove = sonypi_acpi_remove,
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index aaaa61ea4217..518d5d335464 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -200,14 +200,22 @@ config THINKPAD_ACPI_BAY
200config THINKPAD_ACPI_INPUT_ENABLED 200config THINKPAD_ACPI_INPUT_ENABLED
201 bool "Enable input layer support by default" 201 bool "Enable input layer support by default"
202 depends on THINKPAD_ACPI 202 depends on THINKPAD_ACPI
203 default y 203 default n
204 ---help--- 204 ---help---
205 Enables hot key handling over the input layer by default. If unset, 205 This option enables thinkpad-acpi hot key handling over the input
206 the driver does not enable any hot key handling by default, and also 206 layer at driver load time. When it is unset, the driver does not
207 starts up with a mostly empty keymap. 207 enable hot key handling by default, and also starts up with a mostly
208 208 empty keymap.
209 If you are not sure, say Y here. Say N to retain the deprecated 209
210 behavior of ibm-acpi, and thinkpad-acpi for kernels up to 2.6.21. 210 This option should be enabled if you have a new enough HAL or other
211 userspace support that properly handles the thinkpad-acpi event
212 device. It auto-tunes the hot key support to those reported by the
213 firmware and enables it automatically.
214
215 If unsure, say N here to retain the old behaviour of ibm-acpi, and
216 thinkpad-acpi up to kernel 2.6.21: userspace will have to enable and
217 set up the thinkpad-acpi hot key handling using the sysfs interace
218 after loading the driver.
211 219
212 220
213endif # MISC_DEVICES 221endif # MISC_DEVICES
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c
index 14ee06c8f127..91da6880ae93 100644
--- a/drivers/misc/sony-laptop.c
+++ b/drivers/misc/sony-laptop.c
@@ -845,7 +845,7 @@ static struct sony_nc_event sony_C_events[] = {
845}; 845};
846 846
847/* SNC-only model map */ 847/* SNC-only model map */
848struct dmi_system_id sony_nc_ids[] = { 848static struct dmi_system_id sony_nc_ids[] = {
849 { 849 {
850 .ident = "Sony Vaio FE Series", 850 .ident = "Sony Vaio FE Series",
851 .callback = sony_nc_C_enable, 851 .callback = sony_nc_C_enable,
@@ -942,6 +942,11 @@ static int sony_nc_resume(struct acpi_device *device)
942 } 942 }
943 } 943 }
944 944
945 /* set the last requested brightness level */
946 if (sony_backlight_device &&
947 !sony_backlight_update_status(sony_backlight_device))
948 printk(KERN_WARNING DRV_PFX "unable to restore brightness level");
949
945 /* re-initialize models with specific requirements */ 950 /* re-initialize models with specific requirements */
946 dmi_check_system(sony_nc_ids); 951 dmi_check_system(sony_nc_ids);
947 952
diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c
index fa80f355e522..f6cd34a3dbac 100644
--- a/drivers/misc/thinkpad_acpi.c
+++ b/drivers/misc/thinkpad_acpi.c
@@ -4668,12 +4668,15 @@ static int __init thinkpad_acpi_module_init(void)
4668 thinkpad_acpi_module_exit(); 4668 thinkpad_acpi_module_exit();
4669 return ret; 4669 return ret;
4670 } 4670 }
4671 tp_features.platform_drv_registered = 1;
4672
4671 ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver); 4673 ret = tpacpi_create_driver_attributes(&tpacpi_pdriver.driver);
4672 if (ret) { 4674 if (ret) {
4673 printk(IBM_ERR "unable to create sysfs driver attributes\n"); 4675 printk(IBM_ERR "unable to create sysfs driver attributes\n");
4674 thinkpad_acpi_module_exit(); 4676 thinkpad_acpi_module_exit();
4675 return ret; 4677 return ret;
4676 } 4678 }
4679 tp_features.platform_drv_attrs_registered = 1;
4677 4680
4678 4681
4679 /* Device initialization */ 4682 /* Device initialization */
@@ -4756,8 +4759,11 @@ static void thinkpad_acpi_module_exit(void)
4756 if (tpacpi_pdev) 4759 if (tpacpi_pdev)
4757 platform_device_unregister(tpacpi_pdev); 4760 platform_device_unregister(tpacpi_pdev);
4758 4761
4759 tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver); 4762 if (tp_features.platform_drv_attrs_registered)
4760 platform_driver_unregister(&tpacpi_pdriver); 4763 tpacpi_remove_driver_attributes(&tpacpi_pdriver.driver);
4764
4765 if (tp_features.platform_drv_registered)
4766 platform_driver_unregister(&tpacpi_pdriver);
4761 4767
4762 if (proc_dir) 4768 if (proc_dir)
4763 remove_proc_entry(IBM_PROC_DIR, acpi_root_dir); 4769 remove_proc_entry(IBM_PROC_DIR, acpi_root_dir);
diff --git a/drivers/misc/thinkpad_acpi.h b/drivers/misc/thinkpad_acpi.h
index 88af089d6494..eee8809a50d9 100644
--- a/drivers/misc/thinkpad_acpi.h
+++ b/drivers/misc/thinkpad_acpi.h
@@ -246,6 +246,8 @@ static struct {
246 u16 wan:1; 246 u16 wan:1;
247 u16 fan_ctrl_status_undef:1; 247 u16 fan_ctrl_status_undef:1;
248 u16 input_device_registered:1; 248 u16 input_device_registered:1;
249 u16 platform_drv_registered:1;
250 u16 platform_drv_attrs_registered:1;
249} tp_features; 251} tp_features;
250 252
251struct thinkpad_id_data { 253struct thinkpad_id_data {