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