a24847c08f7f43d47cc28b33440e5d8d1bd04268
[linux-2.6.git] / drivers / acpi / thermal.c
1 /*
2  *  acpi_thermal.c - ACPI Thermal Zone Driver ($Revision: 41 $)
3  *
4  *  Copyright (C) 2001, 2002 Andy Grover <andrew.grover@intel.com>
5  *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
6  *
7  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or (at
12  *  your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful, but
15  *  WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *  General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License along
20  *  with this program; if not, write to the Free Software Foundation, Inc.,
21  *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
22  *
23  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24  *
25  *  This driver fully implements the ACPI thermal policy as described in the
26  *  ACPI 2.0 Specification.
27  *
28  *  TBD: 1. Implement passive cooling hysteresis.
29  *       2. Enhance passive cooling (CPU) states/limit interface to support
30  *          concepts of 'multiple limiters', upper/lower limits, etc.
31  *
32  */
33
34 #include <linux/kernel.h>
35 #include <linux/module.h>
36 #include <linux/init.h>
37 #include <linux/types.h>
38 #include <linux/proc_fs.h>
39 #include <linux/sched.h>
40 #include <linux/kmod.h>
41 #include <linux/seq_file.h>
42 #include <asm/uaccess.h>
43
44 #include <acpi/acpi_bus.h>
45 #include <acpi/acpi_drivers.h>
46
47 #define ACPI_THERMAL_COMPONENT          0x04000000
48 #define ACPI_THERMAL_CLASS              "thermal_zone"
49 #define ACPI_THERMAL_DRIVER_NAME        "ACPI Thermal Zone Driver"
50 #define ACPI_THERMAL_DEVICE_NAME        "Thermal Zone"
51 #define ACPI_THERMAL_FILE_STATE         "state"
52 #define ACPI_THERMAL_FILE_TEMPERATURE   "temperature"
53 #define ACPI_THERMAL_FILE_TRIP_POINTS   "trip_points"
54 #define ACPI_THERMAL_FILE_COOLING_MODE  "cooling_mode"
55 #define ACPI_THERMAL_FILE_POLLING_FREQ  "polling_frequency"
56 #define ACPI_THERMAL_NOTIFY_TEMPERATURE 0x80
57 #define ACPI_THERMAL_NOTIFY_THRESHOLDS  0x81
58 #define ACPI_THERMAL_NOTIFY_DEVICES     0x82
59 #define ACPI_THERMAL_NOTIFY_CRITICAL    0xF0
60 #define ACPI_THERMAL_NOTIFY_HOT         0xF1
61 #define ACPI_THERMAL_MODE_ACTIVE        0x00
62 #define ACPI_THERMAL_MODE_PASSIVE       0x01
63 #define ACPI_THERMAL_MODE_CRITICAL      0xff
64 #define ACPI_THERMAL_PATH_POWEROFF      "/sbin/poweroff"
65
66 #define ACPI_THERMAL_MAX_ACTIVE 10
67 #define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65
68
69 #define KELVIN_TO_CELSIUS(t)    (long)(((long)t-2732>=0) ? ((long)t-2732+5)/10 : ((long)t-2732-5)/10)
70 #define CELSIUS_TO_KELVIN(t)    ((t+273)*10)
71
72 #define _COMPONENT              ACPI_THERMAL_COMPONENT
73 ACPI_MODULE_NAME("acpi_thermal")
74
75     MODULE_AUTHOR("Paul Diefenbaugh");
76 MODULE_DESCRIPTION(ACPI_THERMAL_DRIVER_NAME);
77 MODULE_LICENSE("GPL");
78
79 static int tzp;
80 module_param(tzp, int, 0);
81 MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n");
82
83 static int acpi_thermal_add(struct acpi_device *device);
84 static int acpi_thermal_remove(struct acpi_device *device, int type);
85 static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
86 static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
87 static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
88 static ssize_t acpi_thermal_write_trip_points(struct file *,
89                                               const char __user *, size_t,
90                                               loff_t *);
91 static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file);
92 static ssize_t acpi_thermal_write_cooling_mode(struct file *,
93                                                const char __user *, size_t,
94                                                loff_t *);
95 static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file);
96 static ssize_t acpi_thermal_write_polling(struct file *, const char __user *,
97                                           size_t, loff_t *);
98
99 static struct acpi_driver acpi_thermal_driver = {
100         .name = ACPI_THERMAL_DRIVER_NAME,
101         .class = ACPI_THERMAL_CLASS,
102         .ids = ACPI_THERMAL_HID,
103         .ops = {
104                 .add = acpi_thermal_add,
105                 .remove = acpi_thermal_remove,
106                 },
107 };
108
109 struct acpi_thermal_state {
110         u8 critical:1;
111         u8 hot:1;
112         u8 passive:1;
113         u8 active:1;
114         u8 reserved:4;
115         int active_index;
116 };
117
118 struct acpi_thermal_state_flags {
119         u8 valid:1;
120         u8 enabled:1;
121         u8 reserved:6;
122 };
123
124 struct acpi_thermal_critical {
125         struct acpi_thermal_state_flags flags;
126         unsigned long temperature;
127 };
128
129 struct acpi_thermal_hot {
130         struct acpi_thermal_state_flags flags;
131         unsigned long temperature;
132 };
133
134 struct acpi_thermal_passive {
135         struct acpi_thermal_state_flags flags;
136         unsigned long temperature;
137         unsigned long tc1;
138         unsigned long tc2;
139         unsigned long tsp;
140         struct acpi_handle_list devices;
141 };
142
143 struct acpi_thermal_active {
144         struct acpi_thermal_state_flags flags;
145         unsigned long temperature;
146         struct acpi_handle_list devices;
147 };
148
149 struct acpi_thermal_trips {
150         struct acpi_thermal_critical critical;
151         struct acpi_thermal_hot hot;
152         struct acpi_thermal_passive passive;
153         struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE];
154 };
155
156 struct acpi_thermal_flags {
157         u8 cooling_mode:1;      /* _SCP */
158         u8 devices:1;           /* _TZD */
159         u8 reserved:6;
160 };
161
162 struct acpi_thermal {
163         acpi_handle handle;
164         acpi_bus_id name;
165         unsigned long temperature;
166         unsigned long last_temperature;
167         unsigned long polling_frequency;
168         u8 cooling_mode;
169         volatile u8 zombie;
170         struct acpi_thermal_flags flags;
171         struct acpi_thermal_state state;
172         struct acpi_thermal_trips trips;
173         struct acpi_handle_list devices;
174         struct timer_list timer;
175 };
176
177 static struct file_operations acpi_thermal_state_fops = {
178         .open = acpi_thermal_state_open_fs,
179         .read = seq_read,
180         .llseek = seq_lseek,
181         .release = single_release,
182 };
183
184 static struct file_operations acpi_thermal_temp_fops = {
185         .open = acpi_thermal_temp_open_fs,
186         .read = seq_read,
187         .llseek = seq_lseek,
188         .release = single_release,
189 };
190
191 static struct file_operations acpi_thermal_trip_fops = {
192         .open = acpi_thermal_trip_open_fs,
193         .read = seq_read,
194         .write = acpi_thermal_write_trip_points,
195         .llseek = seq_lseek,
196         .release = single_release,
197 };
198
199 static struct file_operations acpi_thermal_cooling_fops = {
200         .open = acpi_thermal_cooling_open_fs,
201         .read = seq_read,
202         .write = acpi_thermal_write_cooling_mode,
203         .llseek = seq_lseek,
204         .release = single_release,
205 };
206
207 static struct file_operations acpi_thermal_polling_fops = {
208         .open = acpi_thermal_polling_open_fs,
209         .read = seq_read,
210         .write = acpi_thermal_write_polling,
211         .llseek = seq_lseek,
212         .release = single_release,
213 };
214
215 /* --------------------------------------------------------------------------
216                              Thermal Zone Management
217    -------------------------------------------------------------------------- */
218
219 static int acpi_thermal_get_temperature(struct acpi_thermal *tz)
220 {
221         acpi_status status = AE_OK;
222
223         ACPI_FUNCTION_TRACE("acpi_thermal_get_temperature");
224
225         if (!tz)
226                 return_VALUE(-EINVAL);
227
228         tz->last_temperature = tz->temperature;
229
230         status =
231             acpi_evaluate_integer(tz->handle, "_TMP", NULL, &tz->temperature);
232         if (ACPI_FAILURE(status))
233                 return_VALUE(-ENODEV);
234
235         ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Temperature is %lu dK\n",
236                           tz->temperature));
237
238         return_VALUE(0);
239 }
240
241 static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz)
242 {
243         acpi_status status = AE_OK;
244
245         ACPI_FUNCTION_TRACE("acpi_thermal_get_polling_frequency");
246
247         if (!tz)
248                 return_VALUE(-EINVAL);
249
250         status =
251             acpi_evaluate_integer(tz->handle, "_TZP", NULL,
252                                   &tz->polling_frequency);
253         if (ACPI_FAILURE(status))
254                 return_VALUE(-ENODEV);
255
256         ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency is %lu dS\n",
257                           tz->polling_frequency));
258
259         return_VALUE(0);
260 }
261
262 static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds)
263 {
264         ACPI_FUNCTION_TRACE("acpi_thermal_set_polling");
265
266         if (!tz)
267                 return_VALUE(-EINVAL);
268
269         tz->polling_frequency = seconds * 10;   /* Convert value to deci-seconds */
270
271         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
272                           "Polling frequency set to %lu seconds\n",
273                           tz->polling_frequency));
274
275         return_VALUE(0);
276 }
277
278 static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode)
279 {
280         acpi_status status = AE_OK;
281         union acpi_object arg0 = { ACPI_TYPE_INTEGER };
282         struct acpi_object_list arg_list = { 1, &arg0 };
283         acpi_handle handle = NULL;
284
285         ACPI_FUNCTION_TRACE("acpi_thermal_set_cooling_mode");
286
287         if (!tz)
288                 return_VALUE(-EINVAL);
289
290         status = acpi_get_handle(tz->handle, "_SCP", &handle);
291         if (ACPI_FAILURE(status)) {
292                 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n"));
293                 return_VALUE(-ENODEV);
294         }
295
296         arg0.integer.value = mode;
297
298         status = acpi_evaluate_object(handle, NULL, &arg_list, NULL);
299         if (ACPI_FAILURE(status))
300                 return_VALUE(-ENODEV);
301
302         tz->cooling_mode = mode;
303
304         ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cooling mode [%s]\n",
305                           mode ? "passive" : "active"));
306
307         return_VALUE(0);
308 }
309
310 static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
311 {
312         acpi_status status = AE_OK;
313         int i = 0;
314
315         ACPI_FUNCTION_TRACE("acpi_thermal_get_trip_points");
316
317         if (!tz)
318                 return_VALUE(-EINVAL);
319
320         /* Critical Shutdown (required) */
321
322         status = acpi_evaluate_integer(tz->handle, "_CRT", NULL,
323                                        &tz->trips.critical.temperature);
324         if (ACPI_FAILURE(status)) {
325                 tz->trips.critical.flags.valid = 0;
326                 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "No critical threshold\n"));
327                 return_VALUE(-ENODEV);
328         } else {
329                 tz->trips.critical.flags.valid = 1;
330                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
331                                   "Found critical threshold [%lu]\n",
332                                   tz->trips.critical.temperature));
333         }
334
335         /* Critical Sleep (optional) */
336
337         status =
338             acpi_evaluate_integer(tz->handle, "_HOT", NULL,
339                                   &tz->trips.hot.temperature);
340         if (ACPI_FAILURE(status)) {
341                 tz->trips.hot.flags.valid = 0;
342                 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No hot threshold\n"));
343         } else {
344                 tz->trips.hot.flags.valid = 1;
345                 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found hot threshold [%lu]\n",
346                                   tz->trips.hot.temperature));
347         }
348
349         /* Passive: Processors (optional) */
350
351         status =
352             acpi_evaluate_integer(tz->handle, "_PSV", NULL,
353                                   &tz->trips.passive.temperature);
354         if (ACPI_FAILURE(status)) {
355                 tz->trips.passive.flags.valid = 0;
356                 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No passive threshold\n"));
357         } else {
358                 tz->trips.passive.flags.valid = 1;
359
360                 status =
361                     acpi_evaluate_integer(tz->handle, "_TC1", NULL,
362                                           &tz->trips.passive.tc1);
363                 if (ACPI_FAILURE(status))
364                         tz->trips.passive.flags.valid = 0;
365
366                 status =
367                     acpi_evaluate_integer(tz->handle, "_TC2", NULL,
368                                           &tz->trips.passive.tc2);
369                 if (ACPI_FAILURE(status))
370                         tz->trips.passive.flags.valid = 0;
371
372                 status =
373                     acpi_evaluate_integer(tz->handle, "_TSP", NULL,
374                                           &tz->trips.passive.tsp);
375                 if (ACPI_FAILURE(status))
376                         tz->trips.passive.flags.valid = 0;
377
378                 status =
379                     acpi_evaluate_reference(tz->handle, "_PSL", NULL,
380                                             &tz->trips.passive.devices);
381                 if (ACPI_FAILURE(status))
382                         tz->trips.passive.flags.valid = 0;
383
384                 if (!tz->trips.passive.flags.valid)
385                         ACPI_DEBUG_PRINT((ACPI_DB_WARN,
386                                           "Invalid passive threshold\n"));
387                 else
388                         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
389                                           "Found passive threshold [%lu]\n",
390                                           tz->trips.passive.temperature));
391         }
392
393         /* Active: Fans, etc. (optional) */
394
395         for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
396
397                 char name[5] = { '_', 'A', 'C', ('0' + i), '\0' };
398
399                 status =
400                     acpi_evaluate_integer(tz->handle, name, NULL,
401                                           &tz->trips.active[i].temperature);
402                 if (ACPI_FAILURE(status))
403                         break;
404
405                 name[2] = 'L';
406                 status =
407                     acpi_evaluate_reference(tz->handle, name, NULL,
408                                             &tz->trips.active[i].devices);
409                 if (ACPI_SUCCESS(status)) {
410                         tz->trips.active[i].flags.valid = 1;
411                         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
412                                           "Found active threshold [%d]:[%lu]\n",
413                                           i, tz->trips.active[i].temperature));
414                 } else
415                         ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
416                                           "Invalid active threshold [%d]\n",
417                                           i));
418         }
419
420         return_VALUE(0);
421 }
422
423 static int acpi_thermal_get_devices(struct acpi_thermal *tz)
424 {
425         acpi_status status = AE_OK;
426
427         ACPI_FUNCTION_TRACE("acpi_thermal_get_devices");
428
429         if (!tz)
430                 return_VALUE(-EINVAL);
431
432         status =
433             acpi_evaluate_reference(tz->handle, "_TZD", NULL, &tz->devices);
434         if (ACPI_FAILURE(status))
435                 return_VALUE(-ENODEV);
436
437         return_VALUE(0);
438 }
439
440 static int acpi_thermal_call_usermode(char *path)
441 {
442         char *argv[2] = { NULL, NULL };
443         char *envp[3] = { NULL, NULL, NULL };
444
445         ACPI_FUNCTION_TRACE("acpi_thermal_call_usermode");
446
447         if (!path)
448                 return_VALUE(-EINVAL);
449
450         argv[0] = path;
451
452         /* minimal command environment */
453         envp[0] = "HOME=/";
454         envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
455
456         call_usermodehelper(argv[0], argv, envp, 0);
457
458         return_VALUE(0);
459 }
460
461 static int acpi_thermal_critical(struct acpi_thermal *tz)
462 {
463         int result = 0;
464         struct acpi_device *device = NULL;
465
466         ACPI_FUNCTION_TRACE("acpi_thermal_critical");
467
468         if (!tz || !tz->trips.critical.flags.valid)
469                 return_VALUE(-EINVAL);
470
471         if (tz->temperature >= tz->trips.critical.temperature) {
472                 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Critical trip point\n"));
473                 tz->trips.critical.flags.enabled = 1;
474         } else if (tz->trips.critical.flags.enabled)
475                 tz->trips.critical.flags.enabled = 0;
476
477         result = acpi_bus_get_device(tz->handle, &device);
478         if (result)
479                 return_VALUE(result);
480
481         printk(KERN_EMERG
482                "Critical temperature reached (%ld C), shutting down.\n",
483                KELVIN_TO_CELSIUS(tz->temperature));
484         acpi_bus_generate_event(device, ACPI_THERMAL_NOTIFY_CRITICAL,
485                                 tz->trips.critical.flags.enabled);
486
487         acpi_thermal_call_usermode(ACPI_THERMAL_PATH_POWEROFF);
488
489         return_VALUE(0);
490 }
491
492 static int acpi_thermal_hot(struct acpi_thermal *tz)
493 {
494         int result = 0;
495         struct acpi_device *device = NULL;
496
497         ACPI_FUNCTION_TRACE("acpi_thermal_hot");
498
499         if (!tz || !tz->trips.hot.flags.valid)
500                 return_VALUE(-EINVAL);
501
502         if (tz->temperature >= tz->trips.hot.temperature) {
503                 ACPI_DEBUG_PRINT((ACPI_DB_WARN, "Hot trip point\n"));
504                 tz->trips.hot.flags.enabled = 1;
505         } else if (tz->trips.hot.flags.enabled)
506                 tz->trips.hot.flags.enabled = 0;
507
508         result = acpi_bus_get_device(tz->handle, &device);
509         if (result)
510                 return_VALUE(result);
511
512         acpi_bus_generate_event(device, ACPI_THERMAL_NOTIFY_HOT,
513                                 tz->trips.hot.flags.enabled);
514
515         /* TBD: Call user-mode "sleep(S4)" function */
516
517         return_VALUE(0);
518 }
519
520 static int acpi_thermal_passive(struct acpi_thermal *tz)
521 {
522         int result = 0;
523         struct acpi_thermal_passive *passive = NULL;
524         int trend = 0;
525         int i = 0;
526
527         ACPI_FUNCTION_TRACE("acpi_thermal_passive");
528
529         if (!tz || !tz->trips.passive.flags.valid)
530                 return_VALUE(-EINVAL);
531
532         passive = &(tz->trips.passive);
533
534         /*
535          * Above Trip?
536          * -----------
537          * Calculate the thermal trend (using the passive cooling equation)
538          * and modify the performance limit for all passive cooling devices
539          * accordingly.  Note that we assume symmetry.
540          */
541         if (tz->temperature >= passive->temperature) {
542                 trend =
543                     (passive->tc1 * (tz->temperature - tz->last_temperature)) +
544                     (passive->tc2 * (tz->temperature - passive->temperature));
545                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
546                                   "trend[%d]=(tc1[%lu]*(tmp[%lu]-last[%lu]))+(tc2[%lu]*(tmp[%lu]-psv[%lu]))\n",
547                                   trend, passive->tc1, tz->temperature,
548                                   tz->last_temperature, passive->tc2,
549                                   tz->temperature, passive->temperature));
550                 tz->trips.passive.flags.enabled = 1;
551                 /* Heating up? */
552                 if (trend > 0)
553                         for (i = 0; i < passive->devices.count; i++)
554                                 acpi_processor_set_thermal_limit(passive->
555                                                                  devices.
556                                                                  handles[i],
557                                                                  ACPI_PROCESSOR_LIMIT_INCREMENT);
558                 /* Cooling off? */
559                 else if (trend < 0)
560                         for (i = 0; i < passive->devices.count; i++)
561                                 acpi_processor_set_thermal_limit(passive->
562                                                                  devices.
563                                                                  handles[i],
564                                                                  ACPI_PROCESSOR_LIMIT_DECREMENT);
565         }
566
567         /*
568          * Below Trip?
569          * -----------
570          * Implement passive cooling hysteresis to slowly increase performance
571          * and avoid thrashing around the passive trip point.  Note that we
572          * assume symmetry.
573          */
574         else if (tz->trips.passive.flags.enabled) {
575                 for (i = 0; i < passive->devices.count; i++)
576                         result =
577                             acpi_processor_set_thermal_limit(passive->devices.
578                                                              handles[i],
579                                                              ACPI_PROCESSOR_LIMIT_DECREMENT);
580                 if (result == 1) {
581                         tz->trips.passive.flags.enabled = 0;
582                         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
583                                           "Disabling passive cooling (zone is cool)\n"));
584                 }
585         }
586
587         return_VALUE(0);
588 }
589
590 static int acpi_thermal_active(struct acpi_thermal *tz)
591 {
592         int result = 0;
593         struct acpi_thermal_active *active = NULL;
594         int i = 0;
595         int j = 0;
596         unsigned long maxtemp = 0;
597
598         ACPI_FUNCTION_TRACE("acpi_thermal_active");
599
600         if (!tz)
601                 return_VALUE(-EINVAL);
602
603         for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
604
605                 active = &(tz->trips.active[i]);
606                 if (!active || !active->flags.valid)
607                         break;
608
609                 /*
610                  * Above Threshold?
611                  * ----------------
612                  * If not already enabled, turn ON all cooling devices
613                  * associated with this active threshold.
614                  */
615                 if (tz->temperature >= active->temperature) {
616                         if (active->temperature > maxtemp)
617                                 tz->state.active_index = i, maxtemp =
618                                     active->temperature;
619                         if (!active->flags.enabled) {
620                                 for (j = 0; j < active->devices.count; j++) {
621                                         result =
622                                             acpi_bus_set_power(active->devices.
623                                                                handles[j],
624                                                                ACPI_STATE_D0);
625                                         if (result) {
626                                                 ACPI_DEBUG_PRINT((ACPI_DB_WARN,
627                                                                   "Unable to turn cooling device [%p] 'on'\n",
628                                                                   active->
629                                                                   devices.
630                                                                   handles[j]));
631                                                 continue;
632                                         }
633                                         active->flags.enabled = 1;
634                                         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
635                                                           "Cooling device [%p] now 'on'\n",
636                                                           active->devices.
637                                                           handles[j]));
638                                 }
639                         }
640                 }
641                 /*
642                  * Below Threshold?
643                  * ----------------
644                  * Turn OFF all cooling devices associated with this
645                  * threshold.
646                  */
647                 else if (active->flags.enabled) {
648                         for (j = 0; j < active->devices.count; j++) {
649                                 result =
650                                     acpi_bus_set_power(active->devices.
651                                                        handles[j],
652                                                        ACPI_STATE_D3);
653                                 if (result) {
654                                         ACPI_DEBUG_PRINT((ACPI_DB_WARN,
655                                                           "Unable to turn cooling device [%p] 'off'\n",
656                                                           active->devices.
657                                                           handles[j]));
658                                         continue;
659                                 }
660                                 active->flags.enabled = 0;
661                                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
662                                                   "Cooling device [%p] now 'off'\n",
663                                                   active->devices.handles[j]));
664                         }
665                 }
666         }
667
668         return_VALUE(0);
669 }
670
671 static void acpi_thermal_check(void *context);
672
673 static void acpi_thermal_run(unsigned long data)
674 {
675         struct acpi_thermal *tz = (struct acpi_thermal *)data;
676         if (!tz->zombie)
677                 acpi_os_queue_for_execution(OSD_PRIORITY_GPE,
678                                             acpi_thermal_check, (void *)data);
679 }
680
681 static void acpi_thermal_check(void *data)
682 {
683         int result = 0;
684         struct acpi_thermal *tz = (struct acpi_thermal *)data;
685         unsigned long sleep_time = 0;
686         int i = 0;
687         struct acpi_thermal_state state;
688
689         ACPI_FUNCTION_TRACE("acpi_thermal_check");
690
691         if (!tz) {
692                 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid (NULL) context.\n"));
693                 return_VOID;
694         }
695
696         state = tz->state;
697
698         result = acpi_thermal_get_temperature(tz);
699         if (result)
700                 return_VOID;
701
702         memset(&tz->state, 0, sizeof(tz->state));
703
704         /*
705          * Check Trip Points
706          * -----------------
707          * Compare the current temperature to the trip point values to see
708          * if we've entered one of the thermal policy states.  Note that
709          * this function determines when a state is entered, but the 
710          * individual policy decides when it is exited (e.g. hysteresis).
711          */
712         if (tz->trips.critical.flags.valid)
713                 state.critical |=
714                     (tz->temperature >= tz->trips.critical.temperature);
715         if (tz->trips.hot.flags.valid)
716                 state.hot |= (tz->temperature >= tz->trips.hot.temperature);
717         if (tz->trips.passive.flags.valid)
718                 state.passive |=
719                     (tz->temperature >= tz->trips.passive.temperature);
720         for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
721                 if (tz->trips.active[i].flags.valid)
722                         state.active |=
723                             (tz->temperature >=
724                              tz->trips.active[i].temperature);
725
726         /*
727          * Invoke Policy
728          * -------------
729          * Separated from the above check to allow individual policy to 
730          * determine when to exit a given state.
731          */
732         if (state.critical)
733                 acpi_thermal_critical(tz);
734         if (state.hot)
735                 acpi_thermal_hot(tz);
736         if (state.passive)
737                 acpi_thermal_passive(tz);
738         if (state.active)
739                 acpi_thermal_active(tz);
740
741         /*
742          * Calculate State
743          * ---------------
744          * Again, separated from the above two to allow independent policy
745          * decisions.
746          */
747         if (tz->trips.critical.flags.enabled)
748                 tz->state.critical = 1;
749         if (tz->trips.hot.flags.enabled)
750                 tz->state.hot = 1;
751         if (tz->trips.passive.flags.enabled)
752                 tz->state.passive = 1;
753         for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
754                 if (tz->trips.active[i].flags.enabled)
755                         tz->state.active = 1;
756
757         /*
758          * Calculate Sleep Time
759          * --------------------
760          * If we're in the passive state, use _TSP's value.  Otherwise
761          * use the default polling frequency (e.g. _TZP).  If no polling
762          * frequency is specified then we'll wait forever (at least until
763          * a thermal event occurs).  Note that _TSP and _TZD values are
764          * given in 1/10th seconds (we must covert to milliseconds).
765          */
766         if (tz->state.passive)
767                 sleep_time = tz->trips.passive.tsp * 100;
768         else if (tz->polling_frequency > 0)
769                 sleep_time = tz->polling_frequency * 100;
770
771         ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n",
772                           tz->name, tz->temperature, sleep_time));
773
774         /*
775          * Schedule Next Poll
776          * ------------------
777          */
778         if (!sleep_time) {
779                 if (timer_pending(&(tz->timer)))
780                         del_timer(&(tz->timer));
781         } else {
782                 if (timer_pending(&(tz->timer)))
783                         mod_timer(&(tz->timer), (HZ * sleep_time) / 1000);
784                 else {
785                         tz->timer.data = (unsigned long)tz;
786                         tz->timer.function = acpi_thermal_run;
787                         tz->timer.expires = jiffies + (HZ * sleep_time) / 1000;
788                         add_timer(&(tz->timer));
789                 }
790         }
791
792         return_VOID;
793 }
794
795 /* --------------------------------------------------------------------------
796                               FS Interface (/proc)
797    -------------------------------------------------------------------------- */
798
799 static struct proc_dir_entry *acpi_thermal_dir;
800
801 static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset)
802 {
803         struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
804
805         ACPI_FUNCTION_TRACE("acpi_thermal_state_seq_show");
806
807         if (!tz)
808                 goto end;
809
810         seq_puts(seq, "state:                   ");
811
812         if (!tz->state.critical && !tz->state.hot && !tz->state.passive
813             && !tz->state.active)
814                 seq_puts(seq, "ok\n");
815         else {
816                 if (tz->state.critical)
817                         seq_puts(seq, "critical ");
818                 if (tz->state.hot)
819                         seq_puts(seq, "hot ");
820                 if (tz->state.passive)
821                         seq_puts(seq, "passive ");
822                 if (tz->state.active)
823                         seq_printf(seq, "active[%d]", tz->state.active_index);
824                 seq_puts(seq, "\n");
825         }
826
827       end:
828         return_VALUE(0);
829 }
830
831 static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file)
832 {
833         return single_open(file, acpi_thermal_state_seq_show, PDE(inode)->data);
834 }
835
836 static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset)
837 {
838         int result = 0;
839         struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
840
841         ACPI_FUNCTION_TRACE("acpi_thermal_temp_seq_show");
842
843         if (!tz)
844                 goto end;
845
846         result = acpi_thermal_get_temperature(tz);
847         if (result)
848                 goto end;
849
850         seq_printf(seq, "temperature:             %ld C\n",
851                    KELVIN_TO_CELSIUS(tz->temperature));
852
853       end:
854         return_VALUE(0);
855 }
856
857 static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file)
858 {
859         return single_open(file, acpi_thermal_temp_seq_show, PDE(inode)->data);
860 }
861
862 static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset)
863 {
864         struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
865         int i = 0;
866         int j = 0;
867
868         ACPI_FUNCTION_TRACE("acpi_thermal_trip_seq_show");
869
870         if (!tz)
871                 goto end;
872
873         if (tz->trips.critical.flags.valid)
874                 seq_printf(seq, "critical (S5):           %ld C\n",
875                            KELVIN_TO_CELSIUS(tz->trips.critical.temperature));
876
877         if (tz->trips.hot.flags.valid)
878                 seq_printf(seq, "hot (S4):                %ld C\n",
879                            KELVIN_TO_CELSIUS(tz->trips.hot.temperature));
880
881         if (tz->trips.passive.flags.valid) {
882                 seq_printf(seq,
883                            "passive:                 %ld C: tc1=%lu tc2=%lu tsp=%lu devices=",
884                            KELVIN_TO_CELSIUS(tz->trips.passive.temperature),
885                            tz->trips.passive.tc1, tz->trips.passive.tc2,
886                            tz->trips.passive.tsp);
887                 for (j = 0; j < tz->trips.passive.devices.count; j++) {
888
889                         seq_printf(seq, "0x%p ",
890                                    tz->trips.passive.devices.handles[j]);
891                 }
892                 seq_puts(seq, "\n");
893         }
894
895         for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
896                 if (!(tz->trips.active[i].flags.valid))
897                         break;
898                 seq_printf(seq, "active[%d]:               %ld C: devices=",
899                            i,
900                            KELVIN_TO_CELSIUS(tz->trips.active[i].temperature));
901                 for (j = 0; j < tz->trips.active[i].devices.count; j++)
902                         seq_printf(seq, "0x%p ",
903                                    tz->trips.active[i].devices.handles[j]);
904                 seq_puts(seq, "\n");
905         }
906
907       end:
908         return_VALUE(0);
909 }
910
911 static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file)
912 {
913         return single_open(file, acpi_thermal_trip_seq_show, PDE(inode)->data);
914 }
915
916 static ssize_t
917 acpi_thermal_write_trip_points(struct file *file,
918                                const char __user * buffer,
919                                size_t count, loff_t * ppos)
920 {
921         struct seq_file *m = (struct seq_file *)file->private_data;
922         struct acpi_thermal *tz = (struct acpi_thermal *)m->private;
923
924         char *limit_string;
925         int num, critical, hot, passive;
926         int *active;
927         int i = 0;
928
929         ACPI_FUNCTION_TRACE("acpi_thermal_write_trip_points");
930
931         limit_string = kmalloc(ACPI_THERMAL_MAX_LIMIT_STR_LEN, GFP_KERNEL);
932         if (!limit_string)
933                 return_VALUE(-ENOMEM);
934
935         memset(limit_string, 0, ACPI_THERMAL_MAX_LIMIT_STR_LEN);
936
937         active = kmalloc(ACPI_THERMAL_MAX_ACTIVE * sizeof(int), GFP_KERNEL);
938         if (!active)
939                 return_VALUE(-ENOMEM);
940
941         if (!tz || (count > ACPI_THERMAL_MAX_LIMIT_STR_LEN - 1)) {
942                 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid argument\n"));
943                 count = -EINVAL;
944                 goto end;
945         }
946
947         if (copy_from_user(limit_string, buffer, count)) {
948                 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data\n"));
949                 count = -EFAULT;
950                 goto end;
951         }
952
953         limit_string[count] = '\0';
954
955         num = sscanf(limit_string, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
956                      &critical, &hot, &passive,
957                      &active[0], &active[1], &active[2], &active[3], &active[4],
958                      &active[5], &active[6], &active[7], &active[8],
959                      &active[9]);
960         if (!(num >= 5 && num < (ACPI_THERMAL_MAX_ACTIVE + 3))) {
961                 ACPI_DEBUG_PRINT((ACPI_DB_ERROR, "Invalid data format\n"));
962                 count = -EINVAL;
963                 goto end;
964         }
965
966         tz->trips.critical.temperature = CELSIUS_TO_KELVIN(critical);
967         tz->trips.hot.temperature = CELSIUS_TO_KELVIN(hot);
968         tz->trips.passive.temperature = CELSIUS_TO_KELVIN(passive);
969         for (i = 0; i < num - 3; i++) {
970                 if (!(tz->trips.active[i].flags.valid))
971                         break;
972                 tz->trips.active[i].temperature = CELSIUS_TO_KELVIN(active[i]);
973         }
974
975       end:
976         kfree(active);
977         kfree(limit_string);
978         return_VALUE(count);
979 }
980
981 static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset)
982 {
983         struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
984
985         ACPI_FUNCTION_TRACE("acpi_thermal_cooling_seq_show");
986
987         if (!tz)
988                 goto end;
989
990         if (!tz->flags.cooling_mode) {
991                 seq_puts(seq, "<setting not supported>\n");
992         }
993
994         if (tz->cooling_mode == ACPI_THERMAL_MODE_CRITICAL)
995                 seq_printf(seq, "cooling mode:  critical\n");
996         else
997                 seq_printf(seq, "cooling mode:  %s\n",
998                            tz->cooling_mode ? "passive" : "active");
999
1000       end:
1001         return_VALUE(0);
1002 }
1003
1004 static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file)
1005 {
1006         return single_open(file, acpi_thermal_cooling_seq_show,
1007                            PDE(inode)->data);
1008 }
1009
1010 static ssize_t
1011 acpi_thermal_write_cooling_mode(struct file *file,
1012                                 const char __user * buffer,
1013                                 size_t count, loff_t * ppos)
1014 {
1015         struct seq_file *m = (struct seq_file *)file->private_data;
1016         struct acpi_thermal *tz = (struct acpi_thermal *)m->private;
1017         int result = 0;
1018         char mode_string[12] = { '\0' };
1019
1020         ACPI_FUNCTION_TRACE("acpi_thermal_write_cooling_mode");
1021
1022         if (!tz || (count > sizeof(mode_string) - 1))
1023                 return_VALUE(-EINVAL);
1024
1025         if (!tz->flags.cooling_mode)
1026                 return_VALUE(-ENODEV);
1027
1028         if (copy_from_user(mode_string, buffer, count))
1029                 return_VALUE(-EFAULT);
1030
1031         mode_string[count] = '\0';
1032
1033         result = acpi_thermal_set_cooling_mode(tz,
1034                                                simple_strtoul(mode_string, NULL,
1035                                                               0));
1036         if (result)
1037                 return_VALUE(result);
1038
1039         acpi_thermal_check(tz);
1040
1041         return_VALUE(count);
1042 }
1043
1044 static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset)
1045 {
1046         struct acpi_thermal *tz = (struct acpi_thermal *)seq->private;
1047
1048         ACPI_FUNCTION_TRACE("acpi_thermal_polling_seq_show");
1049
1050         if (!tz)
1051                 goto end;
1052
1053         if (!tz->polling_frequency) {
1054                 seq_puts(seq, "<polling disabled>\n");
1055                 goto end;
1056         }
1057
1058         seq_printf(seq, "polling frequency:       %lu seconds\n",
1059                    (tz->polling_frequency / 10));
1060
1061       end:
1062         return_VALUE(0);
1063 }
1064
1065 static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file)
1066 {
1067         return single_open(file, acpi_thermal_polling_seq_show,
1068                            PDE(inode)->data);
1069 }
1070
1071 static ssize_t
1072 acpi_thermal_write_polling(struct file *file,
1073                            const char __user * buffer,
1074                            size_t count, loff_t * ppos)
1075 {
1076         struct seq_file *m = (struct seq_file *)file->private_data;
1077         struct acpi_thermal *tz = (struct acpi_thermal *)m->private;
1078         int result = 0;
1079         char polling_string[12] = { '\0' };
1080         int seconds = 0;
1081
1082         ACPI_FUNCTION_TRACE("acpi_thermal_write_polling");
1083
1084         if (!tz || (count > sizeof(polling_string) - 1))
1085                 return_VALUE(-EINVAL);
1086
1087         if (copy_from_user(polling_string, buffer, count))
1088                 return_VALUE(-EFAULT);
1089
1090         polling_string[count] = '\0';
1091
1092         seconds = simple_strtoul(polling_string, NULL, 0);
1093
1094         result = acpi_thermal_set_polling(tz, seconds);
1095         if (result)
1096                 return_VALUE(result);
1097
1098         acpi_thermal_check(tz);
1099
1100         return_VALUE(count);
1101 }
1102
1103 static int acpi_thermal_add_fs(struct acpi_device *device)
1104 {
1105         struct proc_dir_entry *entry = NULL;
1106
1107         ACPI_FUNCTION_TRACE("acpi_thermal_add_fs");
1108
1109         if (!acpi_device_dir(device)) {
1110                 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
1111                                                      acpi_thermal_dir);
1112                 if (!acpi_device_dir(device))
1113                         return_VALUE(-ENODEV);
1114                 acpi_device_dir(device)->owner = THIS_MODULE;
1115         }
1116
1117         /* 'state' [R] */
1118         entry = create_proc_entry(ACPI_THERMAL_FILE_STATE,
1119                                   S_IRUGO, acpi_device_dir(device));
1120         if (!entry)
1121                 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1122                                   "Unable to create '%s' fs entry\n",
1123                                   ACPI_THERMAL_FILE_STATE));
1124         else {
1125                 entry->proc_fops = &acpi_thermal_state_fops;
1126                 entry->data = acpi_driver_data(device);
1127                 entry->owner = THIS_MODULE;
1128         }
1129
1130         /* 'temperature' [R] */
1131         entry = create_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE,
1132                                   S_IRUGO, acpi_device_dir(device));
1133         if (!entry)
1134                 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1135                                   "Unable to create '%s' fs entry\n",
1136                                   ACPI_THERMAL_FILE_TEMPERATURE));
1137         else {
1138                 entry->proc_fops = &acpi_thermal_temp_fops;
1139                 entry->data = acpi_driver_data(device);
1140                 entry->owner = THIS_MODULE;
1141         }
1142
1143         /* 'trip_points' [R/W] */
1144         entry = create_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS,
1145                                   S_IFREG | S_IRUGO | S_IWUSR,
1146                                   acpi_device_dir(device));
1147         if (!entry)
1148                 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1149                                   "Unable to create '%s' fs entry\n",
1150                                   ACPI_THERMAL_FILE_TRIP_POINTS));
1151         else {
1152                 entry->proc_fops = &acpi_thermal_trip_fops;
1153                 entry->data = acpi_driver_data(device);
1154                 entry->owner = THIS_MODULE;
1155         }
1156
1157         /* 'cooling_mode' [R/W] */
1158         entry = create_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE,
1159                                   S_IFREG | S_IRUGO | S_IWUSR,
1160                                   acpi_device_dir(device));
1161         if (!entry)
1162                 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1163                                   "Unable to create '%s' fs entry\n",
1164                                   ACPI_THERMAL_FILE_COOLING_MODE));
1165         else {
1166                 entry->proc_fops = &acpi_thermal_cooling_fops;
1167                 entry->data = acpi_driver_data(device);
1168                 entry->owner = THIS_MODULE;
1169         }
1170
1171         /* 'polling_frequency' [R/W] */
1172         entry = create_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ,
1173                                   S_IFREG | S_IRUGO | S_IWUSR,
1174                                   acpi_device_dir(device));
1175         if (!entry)
1176                 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1177                                   "Unable to create '%s' fs entry\n",
1178                                   ACPI_THERMAL_FILE_POLLING_FREQ));
1179         else {
1180                 entry->proc_fops = &acpi_thermal_polling_fops;
1181                 entry->data = acpi_driver_data(device);
1182                 entry->owner = THIS_MODULE;
1183         }
1184
1185         return_VALUE(0);
1186 }
1187
1188 static int acpi_thermal_remove_fs(struct acpi_device *device)
1189 {
1190         ACPI_FUNCTION_TRACE("acpi_thermal_remove_fs");
1191
1192         if (acpi_device_dir(device)) {
1193                 remove_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ,
1194                                   acpi_device_dir(device));
1195                 remove_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE,
1196                                   acpi_device_dir(device));
1197                 remove_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS,
1198                                   acpi_device_dir(device));
1199                 remove_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE,
1200                                   acpi_device_dir(device));
1201                 remove_proc_entry(ACPI_THERMAL_FILE_STATE,
1202                                   acpi_device_dir(device));
1203                 remove_proc_entry(acpi_device_bid(device), acpi_thermal_dir);
1204                 acpi_device_dir(device) = NULL;
1205         }
1206
1207         return_VALUE(0);
1208 }
1209
1210 /* --------------------------------------------------------------------------
1211                                  Driver Interface
1212    -------------------------------------------------------------------------- */
1213
1214 static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
1215 {
1216         struct acpi_thermal *tz = (struct acpi_thermal *)data;
1217         struct acpi_device *device = NULL;
1218
1219         ACPI_FUNCTION_TRACE("acpi_thermal_notify");
1220
1221         if (!tz)
1222                 return_VOID;
1223
1224         if (acpi_bus_get_device(tz->handle, &device))
1225                 return_VOID;
1226
1227         switch (event) {
1228         case ACPI_THERMAL_NOTIFY_TEMPERATURE:
1229                 acpi_thermal_check(tz);
1230                 break;
1231         case ACPI_THERMAL_NOTIFY_THRESHOLDS:
1232                 acpi_thermal_get_trip_points(tz);
1233                 acpi_thermal_check(tz);
1234                 acpi_bus_generate_event(device, event, 0);
1235                 break;
1236         case ACPI_THERMAL_NOTIFY_DEVICES:
1237                 if (tz->flags.devices)
1238                         acpi_thermal_get_devices(tz);
1239                 acpi_bus_generate_event(device, event, 0);
1240                 break;
1241         default:
1242                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1243                                   "Unsupported event [0x%x]\n", event));
1244                 break;
1245         }
1246
1247         return_VOID;
1248 }
1249
1250 static int acpi_thermal_get_info(struct acpi_thermal *tz)
1251 {
1252         int result = 0;
1253
1254         ACPI_FUNCTION_TRACE("acpi_thermal_get_info");
1255
1256         if (!tz)
1257                 return_VALUE(-EINVAL);
1258
1259         /* Get temperature [_TMP] (required) */
1260         result = acpi_thermal_get_temperature(tz);
1261         if (result)
1262                 return_VALUE(result);
1263
1264         /* Get trip points [_CRT, _PSV, etc.] (required) */
1265         result = acpi_thermal_get_trip_points(tz);
1266         if (result)
1267                 return_VALUE(result);
1268
1269         /* Set the cooling mode [_SCP] to active cooling (default) */
1270         result = acpi_thermal_set_cooling_mode(tz, ACPI_THERMAL_MODE_ACTIVE);
1271         if (!result)
1272                 tz->flags.cooling_mode = 1;
1273         else {
1274                 /* Oh,we have not _SCP method.
1275                    Generally show cooling_mode by _ACx, _PSV,spec 12.2 */
1276                 tz->flags.cooling_mode = 0;
1277                 if (tz->trips.active[0].flags.valid
1278                     && tz->trips.passive.flags.valid) {
1279                         if (tz->trips.passive.temperature >
1280                             tz->trips.active[0].temperature)
1281                                 tz->cooling_mode = ACPI_THERMAL_MODE_ACTIVE;
1282                         else
1283                                 tz->cooling_mode = ACPI_THERMAL_MODE_PASSIVE;
1284                 } else if (!tz->trips.active[0].flags.valid
1285                            && tz->trips.passive.flags.valid) {
1286                         tz->cooling_mode = ACPI_THERMAL_MODE_PASSIVE;
1287                 } else if (tz->trips.active[0].flags.valid
1288                            && !tz->trips.passive.flags.valid) {
1289                         tz->cooling_mode = ACPI_THERMAL_MODE_ACTIVE;
1290                 } else {
1291                         /* _ACx and _PSV are optional, but _CRT is required */
1292                         tz->cooling_mode = ACPI_THERMAL_MODE_CRITICAL;
1293                 }
1294         }
1295
1296         /* Get default polling frequency [_TZP] (optional) */
1297         if (tzp)
1298                 tz->polling_frequency = tzp;
1299         else
1300                 acpi_thermal_get_polling_frequency(tz);
1301
1302         /* Get devices in this thermal zone [_TZD] (optional) */
1303         result = acpi_thermal_get_devices(tz);
1304         if (!result)
1305                 tz->flags.devices = 1;
1306
1307         return_VALUE(0);
1308 }
1309
1310 static int acpi_thermal_add(struct acpi_device *device)
1311 {
1312         int result = 0;
1313         acpi_status status = AE_OK;
1314         struct acpi_thermal *tz = NULL;
1315
1316         ACPI_FUNCTION_TRACE("acpi_thermal_add");
1317
1318         if (!device)
1319                 return_VALUE(-EINVAL);
1320
1321         tz = kmalloc(sizeof(struct acpi_thermal), GFP_KERNEL);
1322         if (!tz)
1323                 return_VALUE(-ENOMEM);
1324         memset(tz, 0, sizeof(struct acpi_thermal));
1325
1326         tz->handle = device->handle;
1327         strcpy(tz->name, device->pnp.bus_id);
1328         strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME);
1329         strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS);
1330         acpi_driver_data(device) = tz;
1331
1332         result = acpi_thermal_get_info(tz);
1333         if (result)
1334                 goto end;
1335
1336         result = acpi_thermal_add_fs(device);
1337         if (result)
1338                 return_VALUE(result);
1339
1340         init_timer(&tz->timer);
1341
1342         acpi_thermal_check(tz);
1343
1344         status = acpi_install_notify_handler(tz->handle,
1345                                              ACPI_DEVICE_NOTIFY,
1346                                              acpi_thermal_notify, tz);
1347         if (ACPI_FAILURE(status)) {
1348                 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1349                                   "Error installing notify handler\n"));
1350                 result = -ENODEV;
1351                 goto end;
1352         }
1353
1354         printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n",
1355                acpi_device_name(device), acpi_device_bid(device),
1356                KELVIN_TO_CELSIUS(tz->temperature));
1357
1358       end:
1359         if (result) {
1360                 acpi_thermal_remove_fs(device);
1361                 kfree(tz);
1362         }
1363
1364         return_VALUE(result);
1365 }
1366
1367 static int acpi_thermal_remove(struct acpi_device *device, int type)
1368 {
1369         acpi_status status = AE_OK;
1370         struct acpi_thermal *tz = NULL;
1371
1372         ACPI_FUNCTION_TRACE("acpi_thermal_remove");
1373
1374         if (!device || !acpi_driver_data(device))
1375                 return_VALUE(-EINVAL);
1376
1377         tz = (struct acpi_thermal *)acpi_driver_data(device);
1378
1379         /* avoid timer adding new defer task */
1380         tz->zombie = 1;
1381         /* wait for running timer (on other CPUs) finish */
1382         del_timer_sync(&(tz->timer));
1383         /* synchronize deferred task */
1384         acpi_os_wait_events_complete(NULL);
1385         /* deferred task may reinsert timer */
1386         del_timer_sync(&(tz->timer));
1387
1388         status = acpi_remove_notify_handler(tz->handle,
1389                                             ACPI_DEVICE_NOTIFY,
1390                                             acpi_thermal_notify);
1391         if (ACPI_FAILURE(status))
1392                 ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
1393                                   "Error removing notify handler\n"));
1394
1395         /* Terminate policy */
1396         if (tz->trips.passive.flags.valid && tz->trips.passive.flags.enabled) {
1397                 tz->trips.passive.flags.enabled = 0;
1398                 acpi_thermal_passive(tz);
1399         }
1400         if (tz->trips.active[0].flags.valid
1401             && tz->trips.active[0].flags.enabled) {
1402                 tz->trips.active[0].flags.enabled = 0;
1403                 acpi_thermal_active(tz);
1404         }
1405
1406         acpi_thermal_remove_fs(device);
1407
1408         kfree(tz);
1409         return_VALUE(0);
1410 }
1411
1412 static int __init acpi_thermal_init(void)
1413 {
1414         int result = 0;
1415
1416         ACPI_FUNCTION_TRACE("acpi_thermal_init");
1417
1418         acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir);
1419         if (!acpi_thermal_dir)
1420                 return_VALUE(-ENODEV);
1421         acpi_thermal_dir->owner = THIS_MODULE;
1422
1423         result = acpi_bus_register_driver(&acpi_thermal_driver);
1424         if (result < 0) {
1425                 remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir);
1426                 return_VALUE(-ENODEV);
1427         }
1428
1429         return_VALUE(0);
1430 }
1431
1432 static void __exit acpi_thermal_exit(void)
1433 {
1434         ACPI_FUNCTION_TRACE("acpi_thermal_exit");
1435
1436         acpi_bus_unregister_driver(&acpi_thermal_driver);
1437
1438         remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir);
1439
1440         return_VOID;
1441 }
1442
1443 module_init(acpi_thermal_init);
1444 module_exit(acpi_thermal_exit);