aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-03-13 16:13:47 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-03-13 16:13:47 -0400
commit96e31022a1b6e7cb173cbb3dce1fde7ba548860a (patch)
treeb50b310790cb79340a5fb67de0485a08dcf31426 /drivers
parentf2005e1777614b65d1970924ca1b61e4caccb0d3 (diff)
parent29ea5171cbd08a7ef37e543cbf02447033f0e289 (diff)
Merge branch 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6
* 'release' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6: (32 commits) ACPI: thermal: show temperature in millidegree Celsius thermal: fix generic thermal I/F for hwmon acer-wmi: build depends on i8042 documentation: Move power-related files to Documentation/power/ ACPI: buffer array too short in drivers/acpi/system.c acer-wmi: Add DMI quirk for mail LED support on Acer Aspire 3610/ 5610 acer-wmi: Fix DSDT path in documentation acer-wmi: Make device detection error messages more descriptive laptops: move laptop-mode.txt to Documentation/laptops/ ACPICA: Warn if packages with invalid references are evaluated ACPI: add _PRT quirks to work around broken firmware Hibernation: Fix mark_nosave_pages() ACPI: Ignore _BQC object when registering backlight device ACPI: WMI: Clean up handling of spec violating data blocks acer-wmi: Don't warn if mail LED cannot be detected acer-wmi: Rename mail LED correctly & remove hardcoded colour ACPI: use ACPI_DEBUG_PRINT instead of printk in acpi_processor_hotplug_notify() ACPI: button: make real parent for input devices in device tree toshiba_acpi: Enable autoloading ACPI: EC: Handle IRQ storm on Acer laptops ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/acpi/Kconfig19
-rw-r--r--drivers/acpi/bus.c2
-rw-r--r--drivers/acpi/button.c1
-rw-r--r--drivers/acpi/ec.c17
-rw-r--r--drivers/acpi/osl.c2
-rw-r--r--drivers/acpi/pci_irq.c98
-rw-r--r--drivers/acpi/pci_root.c2
-rw-r--r--drivers/acpi/processor_core.c25
-rw-r--r--drivers/acpi/scan.c5
-rw-r--r--drivers/acpi/sleep/main.c2
-rw-r--r--drivers/acpi/system.c2
-rw-r--r--drivers/acpi/thermal.c12
-rw-r--r--drivers/acpi/toshiba_acpi.c7
-rw-r--r--drivers/acpi/utilities/utdebug.c2
-rw-r--r--drivers/acpi/utilities/utobject.c2
-rw-r--r--drivers/acpi/utils.c6
-rw-r--r--drivers/acpi/video.c4
-rw-r--r--drivers/acpi/wmi.c10
-rw-r--r--drivers/misc/Kconfig1
-rw-r--r--drivers/misc/acer-wmi.c44
-rw-r--r--drivers/misc/sony-laptop.c2
-rw-r--r--drivers/pci/pci-acpi.c24
-rw-r--r--drivers/thermal/Kconfig1
-rw-r--r--drivers/thermal/thermal.c169
24 files changed, 365 insertions, 94 deletions
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index f688c214be0c..fbcaa069be86 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -283,24 +283,23 @@ config ACPI_TOSHIBA
283 If you have a legacy free Toshiba laptop (such as the Libretto L1 283 If you have a legacy free Toshiba laptop (such as the Libretto L1
284 series), say Y. 284 series), say Y.
285 285
286config ACPI_CUSTOM_DSDT 286config ACPI_CUSTOM_DSDT_FILE
287 bool "Include Custom DSDT" 287 string "Custom DSDT Table file to include"
288 default ""
288 depends on !STANDALONE 289 depends on !STANDALONE
289 default n
290 help 290 help
291 This option supports a custom DSDT by linking it into the kernel. 291 This option supports a custom DSDT by linking it into the kernel.
292 See Documentation/acpi/dsdt-override.txt 292 See Documentation/acpi/dsdt-override.txt
293 293
294 If unsure, say N.
295
296config ACPI_CUSTOM_DSDT_FILE
297 string "Custom DSDT Table file to include"
298 depends on ACPI_CUSTOM_DSDT
299 default ""
300 help
301 Enter the full path name to the file which includes the AmlCode 294 Enter the full path name to the file which includes the AmlCode
302 declaration. 295 declaration.
303 296
297 If unsure, don't enter a file name.
298
299config ACPI_CUSTOM_DSDT
300 bool
301 default ACPI_CUSTOM_DSDT_FILE != ""
302
304config ACPI_CUSTOM_DSDT_INITRD 303config ACPI_CUSTOM_DSDT_INITRD
305 bool "Read Custom DSDT from initramfs" 304 bool "Read Custom DSDT from initramfs"
306 depends on BLK_DEV_INITRD 305 depends on BLK_DEV_INITRD
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index ce3c0a2cbac4..5b6760e0f957 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -776,7 +776,7 @@ static int __init acpi_init(void)
776 776
777 acpi_kobj = kobject_create_and_add("acpi", firmware_kobj); 777 acpi_kobj = kobject_create_and_add("acpi", firmware_kobj);
778 if (!acpi_kobj) { 778 if (!acpi_kobj) {
779 printk(KERN_WARNING "%s: kset create error\n", __FUNCTION__); 779 printk(KERN_WARNING "%s: kset create error\n", __func__);
780 acpi_kobj = NULL; 780 acpi_kobj = NULL;
781 } 781 }
782 782
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index 24a7865a57cb..6c5da83cdb68 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -449,6 +449,7 @@ static int acpi_button_add(struct acpi_device *device)
449 input->phys = button->phys; 449 input->phys = button->phys;
450 input->id.bustype = BUS_HOST; 450 input->id.bustype = BUS_HOST;
451 input->id.product = button->type; 451 input->id.product = button->type;
452 input->dev.parent = &device->dev;
452 453
453 switch (button->type) { 454 switch (button->type) {
454 case ACPI_BUTTON_TYPE_POWER: 455 case ACPI_BUTTON_TYPE_POWER:
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index caf873c14bfb..e7e197e3a4ff 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -129,6 +129,7 @@ static struct acpi_ec {
129 struct mutex lock; 129 struct mutex lock;
130 wait_queue_head_t wait; 130 wait_queue_head_t wait;
131 struct list_head list; 131 struct list_head list;
132 atomic_t irq_count;
132 u8 handlers_installed; 133 u8 handlers_installed;
133} *boot_ec, *first_ec; 134} *boot_ec, *first_ec;
134 135
@@ -181,6 +182,8 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
181{ 182{
182 int ret = 0; 183 int ret = 0;
183 184
185 atomic_set(&ec->irq_count, 0);
186
184 if (unlikely(event == ACPI_EC_EVENT_OBF_1 && 187 if (unlikely(event == ACPI_EC_EVENT_OBF_1 &&
185 test_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags))) 188 test_bit(EC_FLAGS_NO_OBF1_GPE, &ec->flags)))
186 force_poll = 1; 189 force_poll = 1;
@@ -227,6 +230,7 @@ static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
227 while (time_before(jiffies, delay)) { 230 while (time_before(jiffies, delay)) {
228 if (acpi_ec_check_status(ec, event)) 231 if (acpi_ec_check_status(ec, event))
229 goto end; 232 goto end;
233 msleep(5);
230 } 234 }
231 } 235 }
232 pr_err(PREFIX "acpi_ec_wait timeout," 236 pr_err(PREFIX "acpi_ec_wait timeout,"
@@ -529,6 +533,13 @@ static u32 acpi_ec_gpe_handler(void *data)
529 struct acpi_ec *ec = data; 533 struct acpi_ec *ec = data;
530 534
531 pr_debug(PREFIX "~~~> interrupt\n"); 535 pr_debug(PREFIX "~~~> interrupt\n");
536 atomic_inc(&ec->irq_count);
537 if (atomic_read(&ec->irq_count) > 5) {
538 pr_err(PREFIX "GPE storm detected, disabling EC GPE\n");
539 acpi_disable_gpe(NULL, ec->gpe, ACPI_ISR);
540 clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
541 return ACPI_INTERRUPT_HANDLED;
542 }
532 clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags); 543 clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
533 if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) 544 if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))
534 wake_up(&ec->wait); 545 wake_up(&ec->wait);
@@ -943,11 +954,7 @@ int __init acpi_ec_ecdt_probe(void)
943 boot_ec->command_addr = ecdt_ptr->control.address; 954 boot_ec->command_addr = ecdt_ptr->control.address;
944 boot_ec->data_addr = ecdt_ptr->data.address; 955 boot_ec->data_addr = ecdt_ptr->data.address;
945 boot_ec->gpe = ecdt_ptr->gpe; 956 boot_ec->gpe = ecdt_ptr->gpe;
946 if (ACPI_FAILURE(acpi_get_handle(NULL, ecdt_ptr->id, 957 boot_ec->handle = ACPI_ROOT_OBJECT;
947 &boot_ec->handle))) {
948 pr_info("Failed to locate handle for boot EC\n");
949 boot_ec->handle = ACPI_ROOT_OBJECT;
950 }
951 } else { 958 } else {
952 /* This workaround is needed only on some broken machines, 959 /* This workaround is needed only on some broken machines,
953 * which require early EC, but fail to provide ECDT */ 960 * which require early EC, but fail to provide ECDT */
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 8edba7b678eb..065819ba87c7 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -1237,7 +1237,7 @@ int acpi_check_resource_conflict(struct resource *res)
1237 1237
1238 if (clash) { 1238 if (clash) {
1239 if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) { 1239 if (acpi_enforce_resources != ENFORCE_RESOURCES_NO) {
1240 printk(KERN_INFO "%sACPI: %s resource %s [0x%llx-0x%llx]" 1240 printk("%sACPI: %s resource %s [0x%llx-0x%llx]"
1241 " conflicts with ACPI region %s" 1241 " conflicts with ACPI region %s"
1242 " [0x%llx-0x%llx]\n", 1242 " [0x%llx-0x%llx]\n",
1243 acpi_enforce_resources == ENFORCE_RESOURCES_LAX 1243 acpi_enforce_resources == ENFORCE_RESOURCES_LAX
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index 7f19859580c7..7af414a3c63e 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -25,6 +25,7 @@
25 */ 25 */
26 26
27 27
28#include <linux/dmi.h>
28#include <linux/kernel.h> 29#include <linux/kernel.h>
29#include <linux/module.h> 30#include <linux/module.h>
30#include <linux/init.h> 31#include <linux/init.h>
@@ -76,6 +77,101 @@ static struct acpi_prt_entry *acpi_pci_irq_find_prt_entry(int segment,
76 return NULL; 77 return NULL;
77} 78}
78 79
80/* http://bugzilla.kernel.org/show_bug.cgi?id=4773 */
81static struct dmi_system_id medion_md9580[] = {
82 {
83 .ident = "Medion MD9580-F laptop",
84 .matches = {
85 DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"),
86 DMI_MATCH(DMI_PRODUCT_NAME, "A555"),
87 },
88 },
89 { }
90};
91
92/* http://bugzilla.kernel.org/show_bug.cgi?id=5044 */
93static struct dmi_system_id dell_optiplex[] = {
94 {
95 .ident = "Dell Optiplex GX1",
96 .matches = {
97 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
98 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex GX1 600S+"),
99 },
100 },
101 { }
102};
103
104/* http://bugzilla.kernel.org/show_bug.cgi?id=10138 */
105static struct dmi_system_id hp_t5710[] = {
106 {
107 .ident = "HP t5710",
108 .matches = {
109 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
110 DMI_MATCH(DMI_PRODUCT_NAME, "hp t5000 series"),
111 DMI_MATCH(DMI_BOARD_NAME, "098Ch"),
112 },
113 },
114 { }
115};
116
117struct prt_quirk {
118 struct dmi_system_id *system;
119 unsigned int segment;
120 unsigned int bus;
121 unsigned int device;
122 unsigned char pin;
123 char *source; /* according to BIOS */
124 char *actual_source;
125};
126
127/*
128 * These systems have incorrect _PRT entries. The BIOS claims the PCI
129 * interrupt at the listed segment/bus/device/pin is connected to the first
130 * link device, but it is actually connected to the second.
131 */
132static struct prt_quirk prt_quirks[] = {
133 { medion_md9580, 0, 0, 9, 'A',
134 "\\_SB_.PCI0.ISA.LNKA",
135 "\\_SB_.PCI0.ISA.LNKB"},
136 { dell_optiplex, 0, 0, 0xd, 'A',
137 "\\_SB_.LNKB",
138 "\\_SB_.LNKA"},
139 { hp_t5710, 0, 0, 1, 'A',
140 "\\_SB_.PCI0.LNK1",
141 "\\_SB_.PCI0.LNK3"},
142};
143
144static void
145do_prt_fixups(struct acpi_prt_entry *entry, struct acpi_pci_routing_table *prt)
146{
147 int i;
148 struct prt_quirk *quirk;
149
150 for (i = 0; i < ARRAY_SIZE(prt_quirks); i++) {
151 quirk = &prt_quirks[i];
152
153 /* All current quirks involve link devices, not GSIs */
154 if (!prt->source)
155 continue;
156
157 if (dmi_check_system(quirk->system) &&
158 entry->id.segment == quirk->segment &&
159 entry->id.bus == quirk->bus &&
160 entry->id.device == quirk->device &&
161 entry->pin + 'A' == quirk->pin &&
162 !strcmp(prt->source, quirk->source) &&
163 strlen(prt->source) >= strlen(quirk->actual_source)) {
164 printk(KERN_WARNING PREFIX "firmware reports "
165 "%04x:%02x:%02x[%c] connected to %s; "
166 "changing to %s\n",
167 entry->id.segment, entry->id.bus,
168 entry->id.device, 'A' + entry->pin,
169 prt->source, quirk->actual_source);
170 strcpy(prt->source, quirk->actual_source);
171 }
172 }
173}
174
79static int 175static int
80acpi_pci_irq_add_entry(acpi_handle handle, 176acpi_pci_irq_add_entry(acpi_handle handle,
81 int segment, int bus, struct acpi_pci_routing_table *prt) 177 int segment, int bus, struct acpi_pci_routing_table *prt)
@@ -96,6 +192,8 @@ acpi_pci_irq_add_entry(acpi_handle handle,
96 entry->id.function = prt->address & 0xFFFF; 192 entry->id.function = prt->address & 0xFFFF;
97 entry->pin = prt->pin; 193 entry->pin = prt->pin;
98 194
195 do_prt_fixups(entry, prt);
196
99 /* 197 /*
100 * Type 1: Dynamic 198 * Type 1: Dynamic
101 * --------------- 199 * ---------------
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index f14ff1ffab29..c3fed31166b5 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -184,7 +184,7 @@ static void acpi_pci_bridge_scan(struct acpi_device *device)
184 } 184 }
185} 185}
186 186
187static int acpi_pci_root_add(struct acpi_device *device) 187static int __devinit acpi_pci_root_add(struct acpi_device *device)
188{ 188{
189 int result = 0; 189 int result = 0;
190 struct acpi_pci_root *root = NULL; 190 struct acpi_pci_root *root = NULL;
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index a3cc8a98255c..36a68fa114e3 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -840,17 +840,19 @@ static int is_processor_present(acpi_handle handle)
840 840
841 841
842 status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); 842 status = acpi_evaluate_integer(handle, "_STA", NULL, &sta);
843 /*
844 * if a processor object does not have an _STA object,
845 * OSPM assumes that the processor is present.
846 */
847 if (status == AE_NOT_FOUND)
848 return 1;
849 843
850 if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT)) 844 if (ACPI_SUCCESS(status) && (sta & ACPI_STA_DEVICE_PRESENT))
851 return 1; 845 return 1;
852 846
853 ACPI_EXCEPTION((AE_INFO, status, "Processor Device is not present")); 847 /*
848 * _STA is mandatory for a processor that supports hot plug
849 */
850 if (status == AE_NOT_FOUND)
851 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
852 "Processor does not support hot plug\n"));
853 else
854 ACPI_EXCEPTION((AE_INFO, status,
855 "Processor Device is not present"));
854 return 0; 856 return 0;
855} 857}
856 858
@@ -886,8 +888,8 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device)
886 return 0; 888 return 0;
887} 889}
888 890
889static void 891static void __ref acpi_processor_hotplug_notify(acpi_handle handle,
890acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data) 892 u32 event, void *data)
891{ 893{
892 struct acpi_processor *pr; 894 struct acpi_processor *pr;
893 struct acpi_device *device = NULL; 895 struct acpi_device *device = NULL;
@@ -897,9 +899,10 @@ acpi_processor_hotplug_notify(acpi_handle handle, u32 event, void *data)
897 switch (event) { 899 switch (event) {
898 case ACPI_NOTIFY_BUS_CHECK: 900 case ACPI_NOTIFY_BUS_CHECK:
899 case ACPI_NOTIFY_DEVICE_CHECK: 901 case ACPI_NOTIFY_DEVICE_CHECK:
900 printk("Processor driver received %s event\n", 902 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
903 "Processor driver received %s event\n",
901 (event == ACPI_NOTIFY_BUS_CHECK) ? 904 (event == ACPI_NOTIFY_BUS_CHECK) ?
902 "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK"); 905 "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK"));
903 906
904 if (!is_processor_present(handle)) 907 if (!is_processor_present(handle))
905 break; 908 break;
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 3fac011f9cf9..57570ac47803 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -609,7 +609,8 @@ acpi_bus_get_ejd(acpi_handle handle, acpi_handle *ejd)
609 status = acpi_evaluate_object(handle, "_EJD", NULL, &buffer); 609 status = acpi_evaluate_object(handle, "_EJD", NULL, &buffer);
610 if (ACPI_SUCCESS(status)) { 610 if (ACPI_SUCCESS(status)) {
611 obj = buffer.pointer; 611 obj = buffer.pointer;
612 status = acpi_get_handle(NULL, obj->string.pointer, ejd); 612 status = acpi_get_handle(ACPI_ROOT_OBJECT, obj->string.pointer,
613 ejd);
613 kfree(buffer.pointer); 614 kfree(buffer.pointer);
614 } 615 }
615 return status; 616 return status;
@@ -966,7 +967,7 @@ static void acpi_device_set_id(struct acpi_device *device,
966 case ACPI_BUS_TYPE_DEVICE: 967 case ACPI_BUS_TYPE_DEVICE:
967 status = acpi_get_object_info(handle, &buffer); 968 status = acpi_get_object_info(handle, &buffer);
968 if (ACPI_FAILURE(status)) { 969 if (ACPI_FAILURE(status)) {
969 printk(KERN_ERR PREFIX "%s: Error reading device info\n", __FUNCTION__); 970 printk(KERN_ERR PREFIX "%s: Error reading device info\n", __func__);
970 return; 971 return;
971 } 972 }
972 973
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index 293a1cbb47c0..d2f71a54726c 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -504,7 +504,7 @@ static void acpi_power_off_prepare(void)
504static void acpi_power_off(void) 504static void acpi_power_off(void)
505{ 505{
506 /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ 506 /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
507 printk("%s called\n", __FUNCTION__); 507 printk("%s called\n", __func__);
508 local_irq_disable(); 508 local_irq_disable();
509 acpi_enable_wakeup_device(ACPI_STATE_S5); 509 acpi_enable_wakeup_device(ACPI_STATE_S5);
510 acpi_enter_sleep_state(ACPI_STATE_S5); 510 acpi_enter_sleep_state(ACPI_STATE_S5);
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index 55cf4c05bb74..4749f379a915 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -319,7 +319,7 @@ void acpi_irq_stats_init(void)
319 goto fail; 319 goto fail;
320 320
321 for (i = 0; i < num_counters; ++i) { 321 for (i = 0; i < num_counters; ++i) {
322 char buffer[10]; 322 char buffer[12];
323 char *name; 323 char *name;
324 324
325 if (i < num_gpes) 325 if (i < num_gpes)
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 8d4b79b4f933..c4e00ac8ea85 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -879,6 +879,8 @@ static void acpi_thermal_check(void *data)
879} 879}
880 880
881/* sys I/F for generic thermal sysfs support */ 881/* sys I/F for generic thermal sysfs support */
882#define KELVIN_TO_MILLICELSIUS(t) (t * 100 - 273200)
883
882static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf) 884static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf)
883{ 885{
884 struct acpi_thermal *tz = thermal->devdata; 886 struct acpi_thermal *tz = thermal->devdata;
@@ -886,7 +888,7 @@ static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf)
886 if (!tz) 888 if (!tz)
887 return -EINVAL; 889 return -EINVAL;
888 890
889 return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS(tz->temperature)); 891 return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(tz->temperature));
890} 892}
891 893
892static const char enabled[] = "kernel"; 894static const char enabled[] = "kernel";
@@ -980,21 +982,21 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
980 982
981 if (tz->trips.critical.flags.valid) { 983 if (tz->trips.critical.flags.valid) {
982 if (!trip) 984 if (!trip)
983 return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS( 985 return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
984 tz->trips.critical.temperature)); 986 tz->trips.critical.temperature));
985 trip--; 987 trip--;
986 } 988 }
987 989
988 if (tz->trips.hot.flags.valid) { 990 if (tz->trips.hot.flags.valid) {
989 if (!trip) 991 if (!trip)
990 return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS( 992 return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
991 tz->trips.hot.temperature)); 993 tz->trips.hot.temperature));
992 trip--; 994 trip--;
993 } 995 }
994 996
995 if (tz->trips.passive.flags.valid) { 997 if (tz->trips.passive.flags.valid) {
996 if (!trip) 998 if (!trip)
997 return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS( 999 return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
998 tz->trips.passive.temperature)); 1000 tz->trips.passive.temperature));
999 trip--; 1001 trip--;
1000 } 1002 }
@@ -1002,7 +1004,7 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
1002 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && 1004 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
1003 tz->trips.active[i].flags.valid; i++) { 1005 tz->trips.active[i].flags.valid; i++) {
1004 if (!trip) 1006 if (!trip)
1005 return sprintf(buf, "%ld\n", KELVIN_TO_CELSIUS( 1007 return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
1006 tz->trips.active[i].temperature)); 1008 tz->trips.active[i].temperature));
1007 trip--; 1009 trip--;
1008 } 1010 }
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
index 9e8c20c6a0b7..0a43c8e0eff3 100644
--- a/drivers/acpi/toshiba_acpi.c
+++ b/drivers/acpi/toshiba_acpi.c
@@ -99,6 +99,13 @@ MODULE_LICENSE("GPL");
99#define HCI_VIDEO_OUT_CRT 0x2 99#define HCI_VIDEO_OUT_CRT 0x2
100#define HCI_VIDEO_OUT_TV 0x4 100#define HCI_VIDEO_OUT_TV 0x4
101 101
102static const struct acpi_device_id toshiba_device_ids[] = {
103 {"TOS6200", 0},
104 {"TOS1900", 0},
105 {"", 0},
106};
107MODULE_DEVICE_TABLE(acpi, toshiba_device_ids);
108
102/* utility 109/* utility
103 */ 110 */
104 111
diff --git a/drivers/acpi/utilities/utdebug.c b/drivers/acpi/utilities/utdebug.c
index c7e128e5369b..7361204b1eef 100644
--- a/drivers/acpi/utilities/utdebug.c
+++ b/drivers/acpi/utilities/utdebug.c
@@ -109,7 +109,7 @@ void acpi_ut_track_stack_ptr(void)
109 * RETURN: Updated pointer to the function name 109 * RETURN: Updated pointer to the function name
110 * 110 *
111 * DESCRIPTION: Remove the "Acpi" prefix from the function name, if present. 111 * DESCRIPTION: Remove the "Acpi" prefix from the function name, if present.
112 * This allows compiler macros such as __FUNCTION__ to be used 112 * This allows compiler macros such as __func__ to be used
113 * with no change to the debug output. 113 * with no change to the debug output.
114 * 114 *
115 ******************************************************************************/ 115 ******************************************************************************/
diff --git a/drivers/acpi/utilities/utobject.c b/drivers/acpi/utilities/utobject.c
index 76ee766c84f9..e08b3fa6639f 100644
--- a/drivers/acpi/utilities/utobject.c
+++ b/drivers/acpi/utilities/utobject.c
@@ -432,7 +432,7 @@ acpi_ut_get_simple_object_size(union acpi_operand_object *internal_object,
432 * element -- which is legal) 432 * element -- which is legal)
433 */ 433 */
434 if (!internal_object) { 434 if (!internal_object) {
435 *obj_length = 0; 435 *obj_length = sizeof(union acpi_object);
436 return_ACPI_STATUS(AE_OK); 436 return_ACPI_STATUS(AE_OK);
437 } 437 }
438 438
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
index eba55b7d6c95..44ea60cf21c0 100644
--- a/drivers/acpi/utils.c
+++ b/drivers/acpi/utils.c
@@ -407,6 +407,12 @@ acpi_evaluate_reference(acpi_handle handle,
407 break; 407 break;
408 } 408 }
409 409
410 if (!element->reference.handle) {
411 printk(KERN_WARNING PREFIX "Invalid reference in"
412 " package %s\n", pathname);
413 status = AE_NULL_ENTRY;
414 break;
415 }
410 /* Get the acpi_handle. */ 416 /* Get the acpi_handle. */
411 417
412 list->handles[i] = element->reference.handle; 418 list->handles[i] = element->reference.handle;
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index 12cce69b5441..1bc0c74f2755 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -713,7 +713,7 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
713 713
714 kfree(obj); 714 kfree(obj);
715 715
716 if (device->cap._BCL && device->cap._BCM && device->cap._BQC && max_level > 0){ 716 if (device->cap._BCL && device->cap._BCM && max_level > 0) {
717 int result; 717 int result;
718 static int count = 0; 718 static int count = 0;
719 char *name; 719 char *name;
@@ -1201,7 +1201,7 @@ static int acpi_video_bus_ROM_seq_show(struct seq_file *seq, void *offset)
1201 if (!video) 1201 if (!video)
1202 goto end; 1202 goto end;
1203 1203
1204 printk(KERN_INFO PREFIX "Please implement %s\n", __FUNCTION__); 1204 printk(KERN_INFO PREFIX "Please implement %s\n", __func__);
1205 seq_printf(seq, "<TODO>\n"); 1205 seq_printf(seq, "<TODO>\n");
1206 1206
1207 end: 1207 end:
diff --git a/drivers/acpi/wmi.c b/drivers/acpi/wmi.c
index efacc9f8bfe3..c33b1c6e93b1 100644
--- a/drivers/acpi/wmi.c
+++ b/drivers/acpi/wmi.c
@@ -293,7 +293,7 @@ struct acpi_buffer *out)
293{ 293{
294 struct guid_block *block = NULL; 294 struct guid_block *block = NULL;
295 struct wmi_block *wblock = NULL; 295 struct wmi_block *wblock = NULL;
296 acpi_handle handle; 296 acpi_handle handle, wc_handle;
297 acpi_status status, wc_status = AE_ERROR; 297 acpi_status status, wc_status = AE_ERROR;
298 struct acpi_object_list input, wc_input; 298 struct acpi_object_list input, wc_input;
299 union acpi_object wc_params[1], wq_params[1]; 299 union acpi_object wc_params[1], wq_params[1];
@@ -338,8 +338,10 @@ struct acpi_buffer *out)
338 * expensive, but have no corresponding WCxx method. So we 338 * expensive, but have no corresponding WCxx method. So we
339 * should not fail if this happens. 339 * should not fail if this happens.
340 */ 340 */
341 wc_status = acpi_evaluate_object(handle, wc_method, 341 wc_status = acpi_get_handle(handle, wc_method, &wc_handle);
342 &wc_input, NULL); 342 if (ACPI_SUCCESS(wc_status))
343 wc_status = acpi_evaluate_object(handle, wc_method,
344 &wc_input, NULL);
343 } 345 }
344 346
345 strcpy(method, "WQ"); 347 strcpy(method, "WQ");
@@ -351,7 +353,7 @@ struct acpi_buffer *out)
351 * If ACPI_WMI_EXPENSIVE, call the relevant WCxx method, even if 353 * If ACPI_WMI_EXPENSIVE, call the relevant WCxx method, even if
352 * the WQxx method failed - we should disable collection anyway. 354 * the WQxx method failed - we should disable collection anyway.
353 */ 355 */
354 if ((block->flags & ACPI_WMI_EXPENSIVE) && wc_status) { 356 if ((block->flags & ACPI_WMI_EXPENSIVE) && ACPI_SUCCESS(wc_status)) {
355 wc_params[0].integer.value = 0; 357 wc_params[0].integer.value = 0;
356 status = acpi_evaluate_object(handle, 358 status = acpi_evaluate_object(handle,
357 wc_method, &wc_input, NULL); 359 wc_method, &wc_input, NULL);
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 982e27b86d10..962817e49fba 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -108,6 +108,7 @@ config ACER_WMI
108 depends on ACPI 108 depends on ACPI
109 depends on LEDS_CLASS 109 depends on LEDS_CLASS
110 depends on BACKLIGHT_CLASS_DEVICE 110 depends on BACKLIGHT_CLASS_DEVICE
111 depends on SERIO_I8042
111 select ACPI_WMI 112 select ACPI_WMI
112 ---help--- 113 ---help---
113 This is a driver for newer Acer (and Wistron) laptops. It adds 114 This is a driver for newer Acer (and Wistron) laptops. It adds
diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c
index 74d12b4a3abd..dd13a3749927 100644
--- a/drivers/misc/acer-wmi.c
+++ b/drivers/misc/acer-wmi.c
@@ -219,6 +219,15 @@ static struct dmi_system_id acer_quirks[] = {
219 }, 219 },
220 { 220 {
221 .callback = dmi_matched, 221 .callback = dmi_matched,
222 .ident = "Acer Aspire 3610",
223 .matches = {
224 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
225 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 3610"),
226 },
227 .driver_data = &quirk_acer_travelmate_2490,
228 },
229 {
230 .callback = dmi_matched,
222 .ident = "Acer Aspire 5100", 231 .ident = "Acer Aspire 5100",
223 .matches = { 232 .matches = {
224 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 233 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
@@ -228,6 +237,15 @@ static struct dmi_system_id acer_quirks[] = {
228 }, 237 },
229 { 238 {
230 .callback = dmi_matched, 239 .callback = dmi_matched,
240 .ident = "Acer Aspire 5610",
241 .matches = {
242 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
243 DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5610"),
244 },
245 .driver_data = &quirk_acer_travelmate_2490,
246 },
247 {
248 .callback = dmi_matched,
231 .ident = "Acer Aspire 5630", 249 .ident = "Acer Aspire 5630",
232 .matches = { 250 .matches = {
233 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 251 DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
@@ -761,11 +779,11 @@ enum led_brightness value)
761} 779}
762 780
763static struct led_classdev mail_led = { 781static struct led_classdev mail_led = {
764 .name = "acer-mail:green", 782 .name = "acer-wmi::mail",
765 .brightness_set = mail_led_set, 783 .brightness_set = mail_led_set,
766}; 784};
767 785
768static int __init acer_led_init(struct device *dev) 786static int __devinit acer_led_init(struct device *dev)
769{ 787{
770 return led_classdev_register(dev, &mail_led); 788 return led_classdev_register(dev, &mail_led);
771} 789}
@@ -798,7 +816,7 @@ static struct backlight_ops acer_bl_ops = {
798 .update_status = update_bl_status, 816 .update_status = update_bl_status,
799}; 817};
800 818
801static int __init acer_backlight_init(struct device *dev) 819static int __devinit acer_backlight_init(struct device *dev)
802{ 820{
803 struct backlight_device *bd; 821 struct backlight_device *bd;
804 822
@@ -817,7 +835,7 @@ static int __init acer_backlight_init(struct device *dev)
817 return 0; 835 return 0;
818} 836}
819 837
820static void __exit acer_backlight_exit(void) 838static void acer_backlight_exit(void)
821{ 839{
822 backlight_device_unregister(acer_backlight_device); 840 backlight_device_unregister(acer_backlight_device);
823} 841}
@@ -1052,11 +1070,12 @@ static int __init acer_wmi_init(void)
1052 1070
1053 if (wmi_has_guid(WMID_GUID2) && interface) { 1071 if (wmi_has_guid(WMID_GUID2) && interface) {
1054 if (ACPI_FAILURE(WMID_set_capabilities())) { 1072 if (ACPI_FAILURE(WMID_set_capabilities())) {
1055 printk(ACER_ERR "Unable to detect available devices\n"); 1073 printk(ACER_ERR "Unable to detect available WMID "
1074 "devices\n");
1056 return -ENODEV; 1075 return -ENODEV;
1057 } 1076 }
1058 } else if (!wmi_has_guid(WMID_GUID2) && interface) { 1077 } else if (!wmi_has_guid(WMID_GUID2) && interface) {
1059 printk(ACER_ERR "Unable to detect available devices\n"); 1078 printk(ACER_ERR "No WMID device detection method found\n");
1060 return -ENODEV; 1079 return -ENODEV;
1061 } 1080 }
1062 1081
@@ -1064,21 +1083,20 @@ static int __init acer_wmi_init(void)
1064 interface = &AMW0_interface; 1083 interface = &AMW0_interface;
1065 1084
1066 if (ACPI_FAILURE(AMW0_set_capabilities())) { 1085 if (ACPI_FAILURE(AMW0_set_capabilities())) {
1067 printk(ACER_ERR "Unable to detect available devices\n"); 1086 printk(ACER_ERR "Unable to detect available AMW0 "
1087 "devices\n");
1068 return -ENODEV; 1088 return -ENODEV;
1069 } 1089 }
1070 } 1090 }
1071 1091
1072 if (wmi_has_guid(AMW0_GUID1)) { 1092 if (wmi_has_guid(AMW0_GUID1))
1073 if (ACPI_FAILURE(AMW0_find_mailled())) 1093 AMW0_find_mailled();
1074 printk(ACER_ERR "Unable to detect mail LED\n");
1075 }
1076 1094
1077 find_quirks(); 1095 find_quirks();
1078 1096
1079 if (!interface) { 1097 if (!interface) {
1080 printk(ACER_ERR "No or unsupported WMI interface, unable to "); 1098 printk(ACER_ERR "No or unsupported WMI interface, unable to "
1081 printk(KERN_CONT "load.\n"); 1099 "load\n");
1082 return -ENODEV; 1100 return -ENODEV;
1083 } 1101 }
1084 1102
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c
index 899e3f75f288..02ff3d19b1cc 100644
--- a/drivers/misc/sony-laptop.c
+++ b/drivers/misc/sony-laptop.c
@@ -315,7 +315,7 @@ static void sony_laptop_report_input_event(u8 event)
315 break; 315 break;
316 316
317 default: 317 default:
318 if (event > ARRAY_SIZE(sony_laptop_input_index)) { 318 if (event >= ARRAY_SIZE(sony_laptop_input_index)) {
319 dprintk("sony_laptop_report_input_event, event not known: %d\n", event); 319 dprintk("sony_laptop_report_input_event, event not known: %d\n", event);
320 break; 320 break;
321 } 321 }
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 4a23654184fc..72f7476930c8 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -272,21 +272,29 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
272{ 272{
273 acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev); 273 acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev);
274 acpi_handle tmp; 274 acpi_handle tmp;
275 static int state_conv[] = { 275 static const u8 state_conv[] = {
276 [0] = 0, 276 [PCI_D0] = ACPI_STATE_D0,
277 [1] = 1, 277 [PCI_D1] = ACPI_STATE_D1,
278 [2] = 2, 278 [PCI_D2] = ACPI_STATE_D2,
279 [3] = 3, 279 [PCI_D3hot] = ACPI_STATE_D3,
280 [4] = 3 280 [PCI_D3cold] = ACPI_STATE_D3
281 }; 281 };
282 int acpi_state = state_conv[(int __force) state];
283 282
284 if (!handle) 283 if (!handle)
285 return -ENODEV; 284 return -ENODEV;
286 /* If the ACPI device has _EJ0, ignore the device */ 285 /* If the ACPI device has _EJ0, ignore the device */
287 if (ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", &tmp))) 286 if (ACPI_SUCCESS(acpi_get_handle(handle, "_EJ0", &tmp)))
288 return 0; 287 return 0;
289 return acpi_bus_set_power(handle, acpi_state); 288
289 switch (state) {
290 case PCI_D0:
291 case PCI_D1:
292 case PCI_D2:
293 case PCI_D3hot:
294 case PCI_D3cold:
295 return acpi_bus_set_power(handle, state_conv[state]);
296 }
297 return -EINVAL;
290} 298}
291 299
292 300
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index 69f19f224875..3ab313ed441c 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -4,6 +4,7 @@
4 4
5menuconfig THERMAL 5menuconfig THERMAL
6 bool "Generic Thermal sysfs driver" 6 bool "Generic Thermal sysfs driver"
7 select HWMON
7 default y 8 default y
8 help 9 help
9 Generic Thermal Sysfs driver offers a generic mechanism for 10 Generic Thermal Sysfs driver offers a generic mechanism for
diff --git a/drivers/thermal/thermal.c b/drivers/thermal/thermal.c
index 8b86e53ccf7a..41bd4c805ace 100644
--- a/drivers/thermal/thermal.c
+++ b/drivers/thermal/thermal.c
@@ -30,8 +30,10 @@
30#include <linux/idr.h> 30#include <linux/idr.h>
31#include <linux/thermal.h> 31#include <linux/thermal.h>
32#include <linux/spinlock.h> 32#include <linux/spinlock.h>
33#include <linux/hwmon.h>
34#include <linux/hwmon-sysfs.h>
33 35
34MODULE_AUTHOR("Zhang Rui") 36MODULE_AUTHOR("Zhang Rui");
35MODULE_DESCRIPTION("Generic thermal management sysfs support"); 37MODULE_DESCRIPTION("Generic thermal management sysfs support");
36MODULE_LICENSE("GPL"); 38MODULE_LICENSE("GPL");
37 39
@@ -56,6 +58,9 @@ static LIST_HEAD(thermal_tz_list);
56static LIST_HEAD(thermal_cdev_list); 58static LIST_HEAD(thermal_cdev_list);
57static DEFINE_MUTEX(thermal_list_lock); 59static DEFINE_MUTEX(thermal_list_lock);
58 60
61static struct device *thermal_hwmon;
62#define MAX_THERMAL_ZONES 10
63
59static int get_idr(struct idr *idr, struct mutex *lock, int *id) 64static int get_idr(struct idr *idr, struct mutex *lock, int *id)
60{ 65{
61 int err; 66 int err;
@@ -87,7 +92,67 @@ static void release_idr(struct idr *idr, struct mutex *lock, int id)
87 mutex_unlock(lock); 92 mutex_unlock(lock);
88} 93}
89 94
90/* sys I/F for thermal zone */ 95/* hwmon sys I/F*/
96static ssize_t
97name_show(struct device *dev, struct device_attribute *attr, char *buf)
98{
99 return sprintf(buf, "thermal_sys_class\n");
100}
101
102static ssize_t
103temp_input_show(struct device *dev, struct device_attribute *attr, char *buf)
104{
105 struct thermal_zone_device *tz;
106 struct sensor_device_attribute *sensor_attr
107 = to_sensor_dev_attr(attr);
108
109 list_for_each_entry(tz, &thermal_tz_list, node)
110 if (tz->id == sensor_attr->index)
111 return tz->ops->get_temp(tz, buf);
112
113 return -ENODEV;
114}
115
116static ssize_t
117temp_crit_show(struct device *dev, struct device_attribute *attr,
118 char *buf)
119{
120 struct thermal_zone_device *tz;
121 struct sensor_device_attribute *sensor_attr
122 = to_sensor_dev_attr(attr);
123
124 list_for_each_entry(tz, &thermal_tz_list, node)
125 if (tz->id == sensor_attr->index)
126 return tz->ops->get_trip_temp(tz, 0, buf);
127
128 return -ENODEV;
129}
130
131static DEVICE_ATTR(name, 0444, name_show, NULL);
132static struct sensor_device_attribute sensor_attrs[] = {
133 SENSOR_ATTR(temp1_input, 0444, temp_input_show, NULL, 0),
134 SENSOR_ATTR(temp1_crit, 0444, temp_crit_show, NULL, 0),
135 SENSOR_ATTR(temp2_input, 0444, temp_input_show, NULL, 1),
136 SENSOR_ATTR(temp2_crit, 0444, temp_crit_show, NULL, 1),
137 SENSOR_ATTR(temp3_input, 0444, temp_input_show, NULL, 2),
138 SENSOR_ATTR(temp3_crit, 0444, temp_crit_show, NULL, 2),
139 SENSOR_ATTR(temp4_input, 0444, temp_input_show, NULL, 3),
140 SENSOR_ATTR(temp4_crit, 0444, temp_crit_show, NULL, 3),
141 SENSOR_ATTR(temp5_input, 0444, temp_input_show, NULL, 4),
142 SENSOR_ATTR(temp5_crit, 0444, temp_crit_show, NULL, 4),
143 SENSOR_ATTR(temp6_input, 0444, temp_input_show, NULL, 5),
144 SENSOR_ATTR(temp6_crit, 0444, temp_crit_show, NULL, 5),
145 SENSOR_ATTR(temp7_input, 0444, temp_input_show, NULL, 6),
146 SENSOR_ATTR(temp7_crit, 0444, temp_crit_show, NULL, 6),
147 SENSOR_ATTR(temp8_input, 0444, temp_input_show, NULL, 7),
148 SENSOR_ATTR(temp8_crit, 0444, temp_crit_show, NULL, 7),
149 SENSOR_ATTR(temp9_input, 0444, temp_input_show, NULL, 8),
150 SENSOR_ATTR(temp9_crit, 0444, temp_crit_show, NULL, 8),
151 SENSOR_ATTR(temp10_input, 0444, temp_input_show, NULL, 9),
152 SENSOR_ATTR(temp10_crit, 0444, temp_crit_show, NULL, 9),
153};
154
155/* thermal zone sys I/F */
91 156
92#define to_thermal_zone(_dev) \ 157#define to_thermal_zone(_dev) \
93 container_of(_dev, struct thermal_zone_device, device) 158 container_of(_dev, struct thermal_zone_device, device)
@@ -214,7 +279,7 @@ do { \
214 device_remove_file(_dev, &trip_point_attrs[_index * 2 + 1]); \ 279 device_remove_file(_dev, &trip_point_attrs[_index * 2 + 1]); \
215} while (0) 280} while (0)
216 281
217/* sys I/F for cooling device */ 282/* cooling device sys I/F */
218#define to_cooling_device(_dev) \ 283#define to_cooling_device(_dev) \
219 container_of(_dev, struct thermal_cooling_device, device) 284 container_of(_dev, struct thermal_cooling_device, device)
220 285
@@ -447,6 +512,9 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *type,
447 struct thermal_zone_device *pos; 512 struct thermal_zone_device *pos;
448 int result; 513 int result;
449 514
515 if (!type)
516 return ERR_PTR(-EINVAL);
517
450 if (strlen(type) >= THERMAL_NAME_LENGTH) 518 if (strlen(type) >= THERMAL_NAME_LENGTH)
451 return ERR_PTR(-EINVAL); 519 return ERR_PTR(-EINVAL);
452 520
@@ -477,11 +545,9 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *type,
477 } 545 }
478 546
479 /* sys I/F */ 547 /* sys I/F */
480 if (type) { 548 result = device_create_file(&cdev->device, &dev_attr_cdev_type);
481 result = device_create_file(&cdev->device, &dev_attr_cdev_type); 549 if (result)
482 if (result) 550 goto unregister;
483 goto unregister;
484 }
485 551
486 result = device_create_file(&cdev->device, &dev_attr_max_state); 552 result = device_create_file(&cdev->device, &dev_attr_max_state);
487 if (result) 553 if (result)
@@ -547,8 +613,8 @@ void thermal_cooling_device_unregister(struct
547 tz->ops->unbind(tz, cdev); 613 tz->ops->unbind(tz, cdev);
548 } 614 }
549 mutex_unlock(&thermal_list_lock); 615 mutex_unlock(&thermal_list_lock);
550 if (cdev->type[0]) 616
551 device_remove_file(&cdev->device, &dev_attr_cdev_type); 617 device_remove_file(&cdev->device, &dev_attr_cdev_type);
552 device_remove_file(&cdev->device, &dev_attr_max_state); 618 device_remove_file(&cdev->device, &dev_attr_max_state);
553 device_remove_file(&cdev->device, &dev_attr_cur_state); 619 device_remove_file(&cdev->device, &dev_attr_cur_state);
554 620
@@ -580,6 +646,9 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
580 int result; 646 int result;
581 int count; 647 int count;
582 648
649 if (!type)
650 return ERR_PTR(-EINVAL);
651
583 if (strlen(type) >= THERMAL_NAME_LENGTH) 652 if (strlen(type) >= THERMAL_NAME_LENGTH)
584 return ERR_PTR(-EINVAL); 653 return ERR_PTR(-EINVAL);
585 654
@@ -601,6 +670,13 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
601 kfree(tz); 670 kfree(tz);
602 return ERR_PTR(result); 671 return ERR_PTR(result);
603 } 672 }
673 if (tz->id >= MAX_THERMAL_ZONES) {
674 printk(KERN_ERR PREFIX
675 "Too many thermal zones\n");
676 release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id);
677 kfree(tz);
678 return ERR_PTR(-EINVAL);
679 }
604 680
605 strcpy(tz->type, type); 681 strcpy(tz->type, type);
606 tz->ops = ops; 682 tz->ops = ops;
@@ -615,13 +691,28 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
615 return ERR_PTR(result); 691 return ERR_PTR(result);
616 } 692 }
617 693
618 /* sys I/F */ 694 /* hwmon sys I/F */
619 if (type) { 695 result = device_create_file(thermal_hwmon,
620 result = device_create_file(&tz->device, &dev_attr_type); 696 &sensor_attrs[tz->id * 2].dev_attr);
621 if (result) 697 if (result)
622 goto unregister; 698 goto unregister;
699
700 if (trips > 0) {
701 char buf[40];
702 result = tz->ops->get_trip_type(tz, 0, buf);
703 if (result > 0 && !strcmp(buf, "critical\n")) {
704 result = device_create_file(thermal_hwmon,
705 &sensor_attrs[tz->id * 2 + 1].dev_attr);
706 if (result)
707 goto unregister;
708 }
623 } 709 }
624 710
711 /* sys I/F */
712 result = device_create_file(&tz->device, &dev_attr_type);
713 if (result)
714 goto unregister;
715
625 result = device_create_file(&tz->device, &dev_attr_temp); 716 result = device_create_file(&tz->device, &dev_attr_temp);
626 if (result) 717 if (result)
627 goto unregister; 718 goto unregister;
@@ -687,8 +778,17 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
687 tz->ops->unbind(tz, cdev); 778 tz->ops->unbind(tz, cdev);
688 mutex_unlock(&thermal_list_lock); 779 mutex_unlock(&thermal_list_lock);
689 780
690 if (tz->type[0]) 781 device_remove_file(thermal_hwmon,
691 device_remove_file(&tz->device, &dev_attr_type); 782 &sensor_attrs[tz->id * 2].dev_attr);
783 if (tz->trips > 0) {
784 char buf[40];
785 if (tz->ops->get_trip_type(tz, 0, buf) > 0)
786 if (!strcmp(buf, "critical\n"))
787 device_remove_file(thermal_hwmon,
788 &sensor_attrs[tz->id * 2 + 1].dev_attr);
789 }
790
791 device_remove_file(&tz->device, &dev_attr_type);
692 device_remove_file(&tz->device, &dev_attr_temp); 792 device_remove_file(&tz->device, &dev_attr_temp);
693 if (tz->ops->get_mode) 793 if (tz->ops->get_mode)
694 device_remove_file(&tz->device, &dev_attr_mode); 794 device_remove_file(&tz->device, &dev_attr_mode);
@@ -705,6 +805,19 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
705 805
706EXPORT_SYMBOL(thermal_zone_device_unregister); 806EXPORT_SYMBOL(thermal_zone_device_unregister);
707 807
808static void thermal_exit(void)
809{
810 if (thermal_hwmon) {
811 device_remove_file(thermal_hwmon, &dev_attr_name);
812 hwmon_device_unregister(thermal_hwmon);
813 }
814 class_unregister(&thermal_class);
815 idr_destroy(&thermal_tz_idr);
816 idr_destroy(&thermal_cdev_idr);
817 mutex_destroy(&thermal_idr_lock);
818 mutex_destroy(&thermal_list_lock);
819}
820
708static int __init thermal_init(void) 821static int __init thermal_init(void)
709{ 822{
710 int result = 0; 823 int result = 0;
@@ -716,16 +829,20 @@ static int __init thermal_init(void)
716 mutex_destroy(&thermal_idr_lock); 829 mutex_destroy(&thermal_idr_lock);
717 mutex_destroy(&thermal_list_lock); 830 mutex_destroy(&thermal_list_lock);
718 } 831 }
719 return result;
720}
721 832
722static void __exit thermal_exit(void) 833 thermal_hwmon = hwmon_device_register(NULL);
723{ 834 if (IS_ERR(thermal_hwmon)) {
724 class_unregister(&thermal_class); 835 result = PTR_ERR(thermal_hwmon);
725 idr_destroy(&thermal_tz_idr); 836 thermal_hwmon = NULL;
726 idr_destroy(&thermal_cdev_idr); 837 printk(KERN_ERR PREFIX
727 mutex_destroy(&thermal_idr_lock); 838 "unable to register hwmon device\n");
728 mutex_destroy(&thermal_list_lock); 839 thermal_exit();
840 return result;
841 }
842
843 result = device_create_file(thermal_hwmon, &dev_attr_name);
844
845 return result;
729} 846}
730 847
731subsys_initcall(thermal_init); 848subsys_initcall(thermal_init);