]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/acpi/thermal.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/sparc-2.6
[linux-2.6-omap-h63xx.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/dmi.h>
37 #include <linux/init.h>
38 #include <linux/types.h>
39 #include <linux/proc_fs.h>
40 #include <linux/timer.h>
41 #include <linux/jiffies.h>
42 #include <linux/kmod.h>
43 #include <linux/seq_file.h>
44 #include <linux/reboot.h>
45 #include <asm/uaccess.h>
46 #include <linux/thermal.h>
47 #include <acpi/acpi_bus.h>
48 #include <acpi/acpi_drivers.h>
49
50 #define ACPI_THERMAL_COMPONENT          0x04000000
51 #define ACPI_THERMAL_CLASS              "thermal_zone"
52 #define ACPI_THERMAL_DEVICE_NAME        "Thermal Zone"
53 #define ACPI_THERMAL_FILE_STATE         "state"
54 #define ACPI_THERMAL_FILE_TEMPERATURE   "temperature"
55 #define ACPI_THERMAL_FILE_TRIP_POINTS   "trip_points"
56 #define ACPI_THERMAL_FILE_COOLING_MODE  "cooling_mode"
57 #define ACPI_THERMAL_FILE_POLLING_FREQ  "polling_frequency"
58 #define ACPI_THERMAL_NOTIFY_TEMPERATURE 0x80
59 #define ACPI_THERMAL_NOTIFY_THRESHOLDS  0x81
60 #define ACPI_THERMAL_NOTIFY_DEVICES     0x82
61 #define ACPI_THERMAL_NOTIFY_CRITICAL    0xF0
62 #define ACPI_THERMAL_NOTIFY_HOT         0xF1
63 #define ACPI_THERMAL_MODE_ACTIVE        0x00
64
65 #define ACPI_THERMAL_MAX_ACTIVE 10
66 #define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65
67
68 #define _COMPONENT              ACPI_THERMAL_COMPONENT
69 ACPI_MODULE_NAME("thermal");
70
71 MODULE_AUTHOR("Paul Diefenbaugh");
72 MODULE_DESCRIPTION("ACPI Thermal Zone Driver");
73 MODULE_LICENSE("GPL");
74
75 static int act;
76 module_param(act, int, 0644);
77 MODULE_PARM_DESC(act, "Disable or override all lowest active trip points.");
78
79 static int crt;
80 module_param(crt, int, 0644);
81 MODULE_PARM_DESC(crt, "Disable or lower all critical trip points.");
82
83 static int tzp;
84 module_param(tzp, int, 0444);
85 MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.");
86
87 static int nocrt;
88 module_param(nocrt, int, 0);
89 MODULE_PARM_DESC(nocrt, "Set to take no action upon ACPI thermal zone critical trips points.");
90
91 static int off;
92 module_param(off, int, 0);
93 MODULE_PARM_DESC(off, "Set to disable ACPI thermal support.");
94
95 static int psv;
96 module_param(psv, int, 0644);
97 MODULE_PARM_DESC(psv, "Disable or override all passive trip points.");
98
99 static int acpi_thermal_add(struct acpi_device *device);
100 static int acpi_thermal_remove(struct acpi_device *device, int type);
101 static int acpi_thermal_resume(struct acpi_device *device);
102 static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
103 static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
104 static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
105 static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file);
106 static ssize_t acpi_thermal_write_cooling_mode(struct file *,
107                                                const char __user *, size_t,
108                                                loff_t *);
109 static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file);
110 static ssize_t acpi_thermal_write_polling(struct file *, const char __user *,
111                                           size_t, loff_t *);
112
113 static const struct acpi_device_id  thermal_device_ids[] = {
114         {ACPI_THERMAL_HID, 0},
115         {"", 0},
116 };
117 MODULE_DEVICE_TABLE(acpi, thermal_device_ids);
118
119 static struct acpi_driver acpi_thermal_driver = {
120         .name = "thermal",
121         .class = ACPI_THERMAL_CLASS,
122         .ids = thermal_device_ids,
123         .ops = {
124                 .add = acpi_thermal_add,
125                 .remove = acpi_thermal_remove,
126                 .resume = acpi_thermal_resume,
127                 },
128 };
129
130 struct acpi_thermal_state {
131         u8 critical:1;
132         u8 hot:1;
133         u8 passive:1;
134         u8 active:1;
135         u8 reserved:4;
136         int active_index;
137 };
138
139 struct acpi_thermal_state_flags {
140         u8 valid:1;
141         u8 enabled:1;
142         u8 reserved:6;
143 };
144
145 struct acpi_thermal_critical {
146         struct acpi_thermal_state_flags flags;
147         unsigned long temperature;
148 };
149
150 struct acpi_thermal_hot {
151         struct acpi_thermal_state_flags flags;
152         unsigned long temperature;
153 };
154
155 struct acpi_thermal_passive {
156         struct acpi_thermal_state_flags flags;
157         unsigned long temperature;
158         unsigned long tc1;
159         unsigned long tc2;
160         unsigned long tsp;
161         struct acpi_handle_list devices;
162 };
163
164 struct acpi_thermal_active {
165         struct acpi_thermal_state_flags flags;
166         unsigned long temperature;
167         struct acpi_handle_list devices;
168 };
169
170 struct acpi_thermal_trips {
171         struct acpi_thermal_critical critical;
172         struct acpi_thermal_hot hot;
173         struct acpi_thermal_passive passive;
174         struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE];
175 };
176
177 struct acpi_thermal_flags {
178         u8 cooling_mode:1;      /* _SCP */
179         u8 devices:1;           /* _TZD */
180         u8 reserved:6;
181 };
182
183 struct acpi_thermal {
184         struct acpi_device * device;
185         acpi_bus_id name;
186         unsigned long temperature;
187         unsigned long last_temperature;
188         unsigned long polling_frequency;
189         volatile u8 zombie;
190         struct acpi_thermal_flags flags;
191         struct acpi_thermal_state state;
192         struct acpi_thermal_trips trips;
193         struct acpi_handle_list devices;
194         struct timer_list timer;
195         struct thermal_zone_device *thermal_zone;
196         int tz_enabled;
197         struct mutex lock;
198 };
199
200 static const struct file_operations acpi_thermal_state_fops = {
201         .owner = THIS_MODULE,
202         .open = acpi_thermal_state_open_fs,
203         .read = seq_read,
204         .llseek = seq_lseek,
205         .release = single_release,
206 };
207
208 static const struct file_operations acpi_thermal_temp_fops = {
209         .owner = THIS_MODULE,
210         .open = acpi_thermal_temp_open_fs,
211         .read = seq_read,
212         .llseek = seq_lseek,
213         .release = single_release,
214 };
215
216 static const struct file_operations acpi_thermal_trip_fops = {
217         .owner = THIS_MODULE,
218         .open = acpi_thermal_trip_open_fs,
219         .read = seq_read,
220         .llseek = seq_lseek,
221         .release = single_release,
222 };
223
224 static const struct file_operations acpi_thermal_cooling_fops = {
225         .owner = THIS_MODULE,
226         .open = acpi_thermal_cooling_open_fs,
227         .read = seq_read,
228         .write = acpi_thermal_write_cooling_mode,
229         .llseek = seq_lseek,
230         .release = single_release,
231 };
232
233 static const struct file_operations acpi_thermal_polling_fops = {
234         .owner = THIS_MODULE,
235         .open = acpi_thermal_polling_open_fs,
236         .read = seq_read,
237         .write = acpi_thermal_write_polling,
238         .llseek = seq_lseek,
239         .release = single_release,
240 };
241
242 /* --------------------------------------------------------------------------
243                              Thermal Zone Management
244    -------------------------------------------------------------------------- */
245
246 static int acpi_thermal_get_temperature(struct acpi_thermal *tz)
247 {
248         acpi_status status = AE_OK;
249         unsigned long long tmp;
250
251         if (!tz)
252                 return -EINVAL;
253
254         tz->last_temperature = tz->temperature;
255
256         status = acpi_evaluate_integer(tz->device->handle, "_TMP", NULL, &tmp);
257         if (ACPI_FAILURE(status))
258                 return -ENODEV;
259
260         tz->temperature = tmp;
261         ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Temperature is %lu dK\n",
262                           tz->temperature));
263
264         return 0;
265 }
266
267 static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz)
268 {
269         acpi_status status = AE_OK;
270         unsigned long long tmp;
271
272         if (!tz)
273                 return -EINVAL;
274
275         status = acpi_evaluate_integer(tz->device->handle, "_TZP", NULL, &tmp);
276         if (ACPI_FAILURE(status))
277                 return -ENODEV;
278
279         tz->polling_frequency = tmp;
280         ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency is %lu dS\n",
281                           tz->polling_frequency));
282
283         return 0;
284 }
285
286 static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds)
287 {
288
289         if (!tz)
290                 return -EINVAL;
291
292         tz->polling_frequency = seconds * 10;   /* Convert value to deci-seconds */
293
294         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
295                           "Polling frequency set to %lu seconds\n",
296                           tz->polling_frequency/10));
297
298         return 0;
299 }
300
301 static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode)
302 {
303         acpi_status status = AE_OK;
304         union acpi_object arg0 = { ACPI_TYPE_INTEGER };
305         struct acpi_object_list arg_list = { 1, &arg0 };
306         acpi_handle handle = NULL;
307
308
309         if (!tz)
310                 return -EINVAL;
311
312         status = acpi_get_handle(tz->device->handle, "_SCP", &handle);
313         if (ACPI_FAILURE(status)) {
314                 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n"));
315                 return -ENODEV;
316         }
317
318         arg0.integer.value = mode;
319
320         status = acpi_evaluate_object(handle, NULL, &arg_list, NULL);
321         if (ACPI_FAILURE(status))
322                 return -ENODEV;
323
324         return 0;
325 }
326
327 #define ACPI_TRIPS_CRITICAL     0x01
328 #define ACPI_TRIPS_HOT          0x02
329 #define ACPI_TRIPS_PASSIVE      0x04
330 #define ACPI_TRIPS_ACTIVE       0x08
331 #define ACPI_TRIPS_DEVICES      0x10
332
333 #define ACPI_TRIPS_REFRESH_THRESHOLDS   (ACPI_TRIPS_PASSIVE | ACPI_TRIPS_ACTIVE)
334 #define ACPI_TRIPS_REFRESH_DEVICES      ACPI_TRIPS_DEVICES
335
336 #define ACPI_TRIPS_INIT      (ACPI_TRIPS_CRITICAL | ACPI_TRIPS_HOT |    \
337                               ACPI_TRIPS_PASSIVE | ACPI_TRIPS_ACTIVE |  \
338                               ACPI_TRIPS_DEVICES)
339
340 /*
341  * This exception is thrown out in two cases:
342  * 1.An invalid trip point becomes invalid or a valid trip point becomes invalid
343  *   when re-evaluating the AML code.
344  * 2.TODO: Devices listed in _PSL, _ALx, _TZD may change.
345  *   We need to re-bind the cooling devices of a thermal zone when this occurs.
346  */
347 #define ACPI_THERMAL_TRIPS_EXCEPTION(flags, str)        \
348 do {    \
349         if (flags != ACPI_TRIPS_INIT)   \
350                 ACPI_EXCEPTION((AE_INFO, AE_ERROR,      \
351                 "ACPI thermal trip point %s changed\n"  \
352                 "Please send acpidump to linux-acpi@vger.kernel.org\n", str)); \
353 } while (0)
354
355 static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
356 {
357         acpi_status status = AE_OK;
358         unsigned long long tmp;
359         struct acpi_handle_list devices;
360         int valid = 0;
361         int i;
362
363         /* Critical Shutdown (required) */
364         if (flag & ACPI_TRIPS_CRITICAL) {
365                 status = acpi_evaluate_integer(tz->device->handle,
366                                 "_CRT", NULL, &tmp);
367                 tz->trips.critical.temperature = tmp;
368                 /*
369                  * Treat freezing temperatures as invalid as well; some
370                  * BIOSes return really low values and cause reboots at startup.
371                  * Below zero (Celcius) values clearly aren't right for sure..
372                  * ... so lets discard those as invalid.
373                  */
374                 if (ACPI_FAILURE(status) ||
375                                 tz->trips.critical.temperature <= 2732) {
376                         tz->trips.critical.flags.valid = 0;
377                         ACPI_EXCEPTION((AE_INFO, status,
378                                         "No or invalid critical threshold"));
379                         return -ENODEV;
380                 } else {
381                         tz->trips.critical.flags.valid = 1;
382                         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
383                                         "Found critical threshold [%lu]\n",
384                                         tz->trips.critical.temperature));
385                 }
386                 if (tz->trips.critical.flags.valid == 1) {
387                         if (crt == -1) {
388                                 tz->trips.critical.flags.valid = 0;
389                         } else if (crt > 0) {
390                                 unsigned long crt_k = CELSIUS_TO_KELVIN(crt);
391                                 /*
392                                  * Allow override critical threshold
393                                  */
394                                 if (crt_k > tz->trips.critical.temperature)
395                                         printk(KERN_WARNING PREFIX
396                                                 "Critical threshold %d C\n", crt);
397                                 tz->trips.critical.temperature = crt_k;
398                         }
399                 }
400         }
401
402         /* Critical Sleep (optional) */
403         if (flag & ACPI_TRIPS_HOT) {
404                 status = acpi_evaluate_integer(tz->device->handle,
405                                 "_HOT", NULL, &tmp);
406                 if (ACPI_FAILURE(status)) {
407                         tz->trips.hot.flags.valid = 0;
408                         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
409                                         "No hot threshold\n"));
410                 } else {
411                         tz->trips.hot.temperature = tmp;
412                         tz->trips.hot.flags.valid = 1;
413                         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
414                                         "Found hot threshold [%lu]\n",
415                                         tz->trips.critical.temperature));
416                 }
417         }
418
419         /* Passive (optional) */
420         if (flag & ACPI_TRIPS_PASSIVE) {
421                 valid = tz->trips.passive.flags.valid;
422                 if (psv == -1) {
423                         status = AE_SUPPORT;
424                 } else if (psv > 0) {
425                         tmp = CELSIUS_TO_KELVIN(psv);
426                         status = AE_OK;
427                 } else {
428                         status = acpi_evaluate_integer(tz->device->handle,
429                                 "_PSV", NULL, &tmp);
430                 }
431
432                 if (ACPI_FAILURE(status))
433                         tz->trips.passive.flags.valid = 0;
434                 else {
435                         tz->trips.passive.temperature = tmp;
436                         tz->trips.passive.flags.valid = 1;
437                         if (flag == ACPI_TRIPS_INIT) {
438                                 status = acpi_evaluate_integer(
439                                                 tz->device->handle, "_TC1",
440                                                 NULL, &tmp);
441                                 if (ACPI_FAILURE(status))
442                                         tz->trips.passive.flags.valid = 0;
443                                 else
444                                         tz->trips.passive.tc1 = tmp;
445                                 status = acpi_evaluate_integer(
446                                                 tz->device->handle, "_TC2",
447                                                 NULL, &tmp);
448                                 if (ACPI_FAILURE(status))
449                                         tz->trips.passive.flags.valid = 0;
450                                 else
451                                         tz->trips.passive.tc2 = tmp;
452                                 status = acpi_evaluate_integer(
453                                                 tz->device->handle, "_TSP",
454                                                 NULL, &tmp);
455                                 if (ACPI_FAILURE(status))
456                                         tz->trips.passive.flags.valid = 0;
457                                 else
458                                         tz->trips.passive.tsp = tmp;
459                         }
460                 }
461         }
462         if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.passive.flags.valid) {
463                 memset(&devices, 0, sizeof(struct acpi_handle_list));
464                 status = acpi_evaluate_reference(tz->device->handle, "_PSL",
465                                                         NULL, &devices);
466                 if (ACPI_FAILURE(status))
467                         tz->trips.passive.flags.valid = 0;
468                 else
469                         tz->trips.passive.flags.valid = 1;
470
471                 if (memcmp(&tz->trips.passive.devices, &devices,
472                                 sizeof(struct acpi_handle_list))) {
473                         memcpy(&tz->trips.passive.devices, &devices,
474                                 sizeof(struct acpi_handle_list));
475                         ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device");
476                 }
477         }
478         if ((flag & ACPI_TRIPS_PASSIVE) || (flag & ACPI_TRIPS_DEVICES)) {
479                 if (valid != tz->trips.passive.flags.valid)
480                                 ACPI_THERMAL_TRIPS_EXCEPTION(flag, "state");
481         }
482
483         /* Active (optional) */
484         for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
485                 char name[5] = { '_', 'A', 'C', ('0' + i), '\0' };
486                 valid = tz->trips.active[i].flags.valid;
487
488                 if (act == -1)
489                         break; /* disable all active trip points */
490
491                 if (flag & ACPI_TRIPS_ACTIVE) {
492                         status = acpi_evaluate_integer(tz->device->handle,
493                                                         name, NULL, &tmp);
494                         if (ACPI_FAILURE(status)) {
495                                 tz->trips.active[i].flags.valid = 0;
496                                 if (i == 0)
497                                         break;
498                                 if (act <= 0)
499                                         break;
500                                 if (i == 1)
501                                         tz->trips.active[0].temperature =
502                                                 CELSIUS_TO_KELVIN(act);
503                                 else
504                                         /*
505                                          * Don't allow override higher than
506                                          * the next higher trip point
507                                          */
508                                         tz->trips.active[i - 1].temperature =
509                                                 (tz->trips.active[i - 2].temperature <
510                                                 CELSIUS_TO_KELVIN(act) ?
511                                                 tz->trips.active[i - 2].temperature :
512                                                 CELSIUS_TO_KELVIN(act));
513                                 break;
514                         } else {
515                                 tz->trips.active[i].temperature = tmp;
516                                 tz->trips.active[i].flags.valid = 1;
517                         }
518                 }
519
520                 name[2] = 'L';
521                 if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.active[i].flags.valid ) {
522                         memset(&devices, 0, sizeof(struct acpi_handle_list));
523                         status = acpi_evaluate_reference(tz->device->handle,
524                                                 name, NULL, &devices);
525                         if (ACPI_FAILURE(status))
526                                 tz->trips.active[i].flags.valid = 0;
527                         else
528                                 tz->trips.active[i].flags.valid = 1;
529
530                         if (memcmp(&tz->trips.active[i].devices, &devices,
531                                         sizeof(struct acpi_handle_list))) {
532                                 memcpy(&tz->trips.active[i].devices, &devices,
533                                         sizeof(struct acpi_handle_list));
534                                 ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device");
535                         }
536                 }
537                 if ((flag & ACPI_TRIPS_ACTIVE) || (flag & ACPI_TRIPS_DEVICES))
538                         if (valid != tz->trips.active[i].flags.valid)
539                                 ACPI_THERMAL_TRIPS_EXCEPTION(flag, "state");
540
541                 if (!tz->trips.active[i].flags.valid)
542                         break;
543         }
544
545         if (flag & ACPI_TRIPS_DEVICES) {
546                 memset(&devices, 0, sizeof(struct acpi_handle_list));
547                 status = acpi_evaluate_reference(tz->device->handle, "_TZD",
548                                                 NULL, &devices);
549                 if (memcmp(&tz->devices, &devices,
550                                 sizeof(struct acpi_handle_list))) {
551                         memcpy(&tz->devices, &devices,
552                                 sizeof(struct acpi_handle_list));
553                         ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device");
554                 }
555         }
556
557         return 0;
558 }
559
560 static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
561 {
562         return acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT);
563 }
564
565 static int acpi_thermal_critical(struct acpi_thermal *tz)
566 {
567         if (!tz || !tz->trips.critical.flags.valid)
568                 return -EINVAL;
569
570         if (tz->temperature >= tz->trips.critical.temperature) {
571                 printk(KERN_WARNING PREFIX "Critical trip point\n");
572                 tz->trips.critical.flags.enabled = 1;
573         } else if (tz->trips.critical.flags.enabled)
574                 tz->trips.critical.flags.enabled = 0;
575
576         acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL,
577                                 tz->trips.critical.flags.enabled);
578         acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
579                                           tz->device->dev.bus_id,
580                                           ACPI_THERMAL_NOTIFY_CRITICAL,
581                                           tz->trips.critical.flags.enabled);
582
583         /* take no action if nocrt is set */
584         if(!nocrt) {
585                 printk(KERN_EMERG
586                         "Critical temperature reached (%ld C), shutting down.\n",
587                         KELVIN_TO_CELSIUS(tz->temperature));
588                 orderly_poweroff(true);
589         }
590
591         return 0;
592 }
593
594 static int acpi_thermal_hot(struct acpi_thermal *tz)
595 {
596         if (!tz || !tz->trips.hot.flags.valid)
597                 return -EINVAL;
598
599         if (tz->temperature >= tz->trips.hot.temperature) {
600                 printk(KERN_WARNING PREFIX "Hot trip point\n");
601                 tz->trips.hot.flags.enabled = 1;
602         } else if (tz->trips.hot.flags.enabled)
603                 tz->trips.hot.flags.enabled = 0;
604
605         acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_HOT,
606                                 tz->trips.hot.flags.enabled);
607         acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
608                                           tz->device->dev.bus_id,
609                                           ACPI_THERMAL_NOTIFY_HOT,
610                                           tz->trips.hot.flags.enabled);
611
612         /* TBD: Call user-mode "sleep(S4)" function if nocrt is cleared */
613
614         return 0;
615 }
616
617 static void acpi_thermal_passive(struct acpi_thermal *tz)
618 {
619         int result = 1;
620         struct acpi_thermal_passive *passive = NULL;
621         int trend = 0;
622         int i = 0;
623
624
625         if (!tz || !tz->trips.passive.flags.valid)
626                 return;
627
628         passive = &(tz->trips.passive);
629
630         /*
631          * Above Trip?
632          * -----------
633          * Calculate the thermal trend (using the passive cooling equation)
634          * and modify the performance limit for all passive cooling devices
635          * accordingly.  Note that we assume symmetry.
636          */
637         if (tz->temperature >= passive->temperature) {
638                 trend =
639                     (passive->tc1 * (tz->temperature - tz->last_temperature)) +
640                     (passive->tc2 * (tz->temperature - passive->temperature));
641                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
642                                   "trend[%d]=(tc1[%lu]*(tmp[%lu]-last[%lu]))+(tc2[%lu]*(tmp[%lu]-psv[%lu]))\n",
643                                   trend, passive->tc1, tz->temperature,
644                                   tz->last_temperature, passive->tc2,
645                                   tz->temperature, passive->temperature));
646                 passive->flags.enabled = 1;
647                 /* Heating up? */
648                 if (trend > 0)
649                         for (i = 0; i < passive->devices.count; i++)
650                                 acpi_processor_set_thermal_limit(passive->
651                                                                  devices.
652                                                                  handles[i],
653                                                                  ACPI_PROCESSOR_LIMIT_INCREMENT);
654                 /* Cooling off? */
655                 else if (trend < 0) {
656                         for (i = 0; i < passive->devices.count; i++)
657                                 /*
658                                  * assume that we are on highest
659                                  * freq/lowest thrott and can leave
660                                  * passive mode, even in error case
661                                  */
662                                 if (!acpi_processor_set_thermal_limit
663                                     (passive->devices.handles[i],
664                                      ACPI_PROCESSOR_LIMIT_DECREMENT))
665                                         result = 0;
666                         /*
667                          * Leave cooling mode, even if the temp might
668                          * higher than trip point This is because some
669                          * machines might have long thermal polling
670                          * frequencies (tsp) defined. We will fall back
671                          * into passive mode in next cycle (probably quicker)
672                          */
673                         if (result) {
674                                 passive->flags.enabled = 0;
675                                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
676                                                   "Disabling passive cooling, still above threshold,"
677                                                   " but we are cooling down\n"));
678                         }
679                 }
680                 return;
681         }
682
683         /*
684          * Below Trip?
685          * -----------
686          * Implement passive cooling hysteresis to slowly increase performance
687          * and avoid thrashing around the passive trip point.  Note that we
688          * assume symmetry.
689          */
690         if (!passive->flags.enabled)
691                 return;
692         for (i = 0; i < passive->devices.count; i++)
693                 if (!acpi_processor_set_thermal_limit
694                     (passive->devices.handles[i],
695                      ACPI_PROCESSOR_LIMIT_DECREMENT))
696                         result = 0;
697         if (result) {
698                 passive->flags.enabled = 0;
699                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
700                                   "Disabling passive cooling (zone is cool)\n"));
701         }
702 }
703
704 static void acpi_thermal_active(struct acpi_thermal *tz)
705 {
706         int result = 0;
707         struct acpi_thermal_active *active = NULL;
708         int i = 0;
709         int j = 0;
710         unsigned long maxtemp = 0;
711
712
713         if (!tz)
714                 return;
715
716         for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
717                 active = &(tz->trips.active[i]);
718                 if (!active || !active->flags.valid)
719                         break;
720                 if (tz->temperature >= active->temperature) {
721                         /*
722                          * Above Threshold?
723                          * ----------------
724                          * If not already enabled, turn ON all cooling devices
725                          * associated with this active threshold.
726                          */
727                         if (active->temperature > maxtemp)
728                                 tz->state.active_index = i;
729                         maxtemp = active->temperature;
730                         if (active->flags.enabled)
731                                 continue;
732                         for (j = 0; j < active->devices.count; j++) {
733                                 result =
734                                     acpi_bus_set_power(active->devices.
735                                                        handles[j],
736                                                        ACPI_STATE_D0);
737                                 if (result) {
738                                         printk(KERN_WARNING PREFIX
739                                                       "Unable to turn cooling device [%p] 'on'\n",
740                                                       active->devices.
741                                                       handles[j]);
742                                         continue;
743                                 }
744                                 active->flags.enabled = 1;
745                                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
746                                                   "Cooling device [%p] now 'on'\n",
747                                                   active->devices.handles[j]));
748                         }
749                         continue;
750                 }
751                 if (!active->flags.enabled)
752                         continue;
753                 /*
754                  * Below Threshold?
755                  * ----------------
756                  * Turn OFF all cooling devices associated with this
757                  * threshold.
758                  */
759                 for (j = 0; j < active->devices.count; j++) {
760                         result = acpi_bus_set_power(active->devices.handles[j],
761                                                     ACPI_STATE_D3);
762                         if (result) {
763                                 printk(KERN_WARNING PREFIX
764                                               "Unable to turn cooling device [%p] 'off'\n",
765                                               active->devices.handles[j]);
766                                 continue;
767                         }
768                         active->flags.enabled = 0;
769                         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
770                                           "Cooling device [%p] now 'off'\n",
771                                           active->devices.handles[j]));
772                 }
773         }
774 }
775
776 static void acpi_thermal_check(void *context);
777
778 static void acpi_thermal_run(unsigned long data)
779 {
780         struct acpi_thermal *tz = (struct acpi_thermal *)data;
781         if (!tz->zombie)
782                 acpi_os_execute(OSL_GPE_HANDLER, acpi_thermal_check, (void *)data);
783 }
784
785 static void acpi_thermal_active_off(void *data)
786 {
787         int result = 0;
788         struct acpi_thermal *tz = data;
789         int i = 0;
790         int j = 0;
791         struct acpi_thermal_active *active = NULL;
792
793         if (!tz) {
794                 printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
795                 return;
796         }
797
798         result = acpi_thermal_get_temperature(tz);
799         if (result)
800                 return;
801
802         for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
803                 active = &(tz->trips.active[i]);
804                 if (!active || !active->flags.valid)
805                         break;
806                 if (tz->temperature >= active->temperature) {
807                         /*
808                          * If the thermal temperature is greater than the
809                          * active threshod, unnecessary to turn off the
810                          * the active cooling device.
811                          */
812                         continue;
813                 }
814                 /*
815                  * Below Threshold?
816                  * ----------------
817                  * Turn OFF all cooling devices associated with this
818                  * threshold.
819                  */
820                 for (j = 0; j < active->devices.count; j++)
821                         result = acpi_bus_set_power(active->devices.handles[j],
822                                                     ACPI_STATE_D3);
823         }
824 }
825
826 static void acpi_thermal_check(void *data)
827 {
828         int result = 0;
829         struct acpi_thermal *tz = data;
830         unsigned long sleep_time = 0;
831         unsigned long timeout_jiffies = 0;
832         int i = 0;
833         struct acpi_thermal_state state;
834
835
836         if (!tz) {
837                 printk(KERN_ERR PREFIX "Invalid (NULL) context\n");
838                 return;
839         }
840
841         /* Check if someone else is already running */
842         if (!mutex_trylock(&tz->lock))
843                 return;
844
845         state = tz->state;
846
847         result = acpi_thermal_get_temperature(tz);
848         if (result)
849                 goto unlock;
850
851         if (!tz->tz_enabled)
852                 goto unlock;
853
854         memset(&tz->state, 0, sizeof(tz->state));
855
856         /*
857          * Check Trip Points
858          * -----------------
859          * Compare the current temperature to the trip point values to see
860          * if we've entered one of the thermal policy states.  Note that
861          * this function determines when a state is entered, but the 
862          * individual policy decides when it is exited (e.g. hysteresis).
863          */
864         if (tz->trips.critical.flags.valid)
865                 state.critical |=
866                     (tz->temperature >= tz->trips.critical.temperature);
867         if (tz->trips.hot.flags.valid)
868                 state.hot |= (tz->temperature >= tz->trips.hot.temperature);
869         if (tz->trips.passive.flags.valid)
870                 state.passive |=
871                     (tz->temperature >= tz->trips.passive.temperature);
872         for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
873                 if (tz->trips.active[i].flags.valid)
874                         state.active |=
875                             (tz->temperature >=
876                              tz->trips.active[i].temperature);
877
878         /*
879          * Invoke Policy
880          * -------------
881          * Separated from the above check to allow individual policy to 
882          * determine when to exit a given state.
883          */
884         if (state.critical)
885                 acpi_thermal_critical(tz);
886         if (state.hot)
887                 acpi_thermal_hot(tz);
888         if (state.passive)
889                 acpi_thermal_passive(tz);
890         if (state.active)
891                 acpi_thermal_active(tz);
892
893         /*
894          * Calculate State
895          * ---------------
896          * Again, separated from the above two to allow independent policy
897          * decisions.
898          */
899         tz->state.critical = tz->trips.critical.flags.enabled;
900         tz->state.hot = tz->trips.hot.flags.enabled;
901         tz->state.passive = tz->trips.passive.flags.enabled;
902         tz->state.active = 0;
903         for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
904                 tz->state.active |= tz->trips.active[i].flags.enabled;
905
906         /*
907          * Calculate Sleep Time
908          * --------------------
909          * If we're in the passive state, use _TSP's value.  Otherwise
910          * use the default polling frequency (e.g. _TZP).  If no polling
911          * frequency is specified then we'll wait forever (at least until
912          * a thermal event occurs).  Note that _TSP and _TZD values are
913          * given in 1/10th seconds (we must covert to milliseconds).
914          */
915         if (tz->state.passive) {
916                 sleep_time = tz->trips.passive.tsp * 100;
917                 timeout_jiffies =  jiffies + (HZ * sleep_time) / 1000;
918         } else if (tz->polling_frequency > 0) {
919                 sleep_time = tz->polling_frequency * 100;
920                 timeout_jiffies =  round_jiffies(jiffies + (HZ * sleep_time) / 1000);
921         }
922
923         ACPI_DEBUG_PRINT((ACPI_DB_INFO, "%s: temperature[%lu] sleep[%lu]\n",
924                           tz->name, tz->temperature, sleep_time));
925
926         /*
927          * Schedule Next Poll
928          * ------------------
929          */
930         if (!sleep_time) {
931                 if (timer_pending(&(tz->timer)))
932                         del_timer(&(tz->timer));
933         } else {
934                 if (timer_pending(&(tz->timer)))
935                         mod_timer(&(tz->timer), timeout_jiffies);
936                 else {
937                         tz->timer.data = (unsigned long)tz;
938                         tz->timer.function = acpi_thermal_run;
939                         tz->timer.expires = timeout_jiffies;
940                         add_timer(&(tz->timer));
941                 }
942         }
943       unlock:
944         mutex_unlock(&tz->lock);
945 }
946
947 /* sys I/F for generic thermal sysfs support */
948 #define KELVIN_TO_MILLICELSIUS(t) (t * 100 - 273200)
949
950 static int thermal_get_temp(struct thermal_zone_device *thermal, char *buf)
951 {
952         struct acpi_thermal *tz = thermal->devdata;
953         int result;
954
955         if (!tz)
956                 return -EINVAL;
957
958         result = acpi_thermal_get_temperature(tz);
959         if (result)
960                 return result;
961
962         return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(tz->temperature));
963 }
964
965 static const char enabled[] = "kernel";
966 static const char disabled[] = "user";
967 static int thermal_get_mode(struct thermal_zone_device *thermal,
968                                 char *buf)
969 {
970         struct acpi_thermal *tz = thermal->devdata;
971
972         if (!tz)
973                 return -EINVAL;
974
975         return sprintf(buf, "%s\n", tz->tz_enabled ?
976                         enabled : disabled);
977 }
978
979 static int thermal_set_mode(struct thermal_zone_device *thermal,
980                                 const char *buf)
981 {
982         struct acpi_thermal *tz = thermal->devdata;
983         int enable;
984
985         if (!tz)
986                 return -EINVAL;
987
988         /*
989          * enable/disable thermal management from ACPI thermal driver
990          */
991         if (!strncmp(buf, enabled, sizeof enabled - 1))
992                 enable = 1;
993         else if (!strncmp(buf, disabled, sizeof disabled - 1))
994                 enable = 0;
995         else
996                 return -EINVAL;
997
998         if (enable != tz->tz_enabled) {
999                 tz->tz_enabled = enable;
1000                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1001                         "%s ACPI thermal control\n",
1002                         tz->tz_enabled ? enabled : disabled));
1003                 acpi_thermal_check(tz);
1004         }
1005         return 0;
1006 }
1007
1008 static int thermal_get_trip_type(struct thermal_zone_device *thermal,
1009                                  int trip, char *buf)
1010 {
1011         struct acpi_thermal *tz = thermal->devdata;
1012         int i;
1013
1014         if (!tz || trip < 0)
1015                 return -EINVAL;
1016
1017         if (tz->trips.critical.flags.valid) {
1018                 if (!trip)
1019                         return sprintf(buf, "critical\n");
1020                 trip--;
1021         }
1022
1023         if (tz->trips.hot.flags.valid) {
1024                 if (!trip)
1025                         return sprintf(buf, "hot\n");
1026                 trip--;
1027         }
1028
1029         if (tz->trips.passive.flags.valid) {
1030                 if (!trip)
1031                         return sprintf(buf, "passive\n");
1032                 trip--;
1033         }
1034
1035         for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
1036                 tz->trips.active[i].flags.valid; i++) {
1037                 if (!trip)
1038                         return sprintf(buf, "active%d\n", i);
1039                 trip--;
1040         }
1041
1042         return -EINVAL;
1043 }
1044
1045 static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
1046                                  int trip, char *buf)
1047 {
1048         struct acpi_thermal *tz = thermal->devdata;
1049         int i;
1050
1051         if (!tz || trip < 0)
1052                 return -EINVAL;
1053
1054         if (tz->trips.critical.flags.valid) {
1055                 if (!trip)
1056                         return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
1057                                 tz->trips.critical.temperature));
1058                 trip--;
1059         }
1060
1061         if (tz->trips.hot.flags.valid) {
1062                 if (!trip)
1063                         return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
1064                                         tz->trips.hot.temperature));
1065                 trip--;
1066         }
1067
1068         if (tz->trips.passive.flags.valid) {
1069                 if (!trip)
1070                         return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
1071                                         tz->trips.passive.temperature));
1072                 trip--;
1073         }
1074
1075         for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
1076                 tz->trips.active[i].flags.valid; i++) {
1077                 if (!trip)
1078                         return sprintf(buf, "%ld\n", KELVIN_TO_MILLICELSIUS(
1079                                         tz->trips.active[i].temperature));
1080                 trip--;
1081         }
1082
1083         return -EINVAL;
1084 }
1085
1086 static int thermal_get_crit_temp(struct thermal_zone_device *thermal,
1087                                 unsigned long *temperature) {
1088         struct acpi_thermal *tz = thermal->devdata;
1089
1090         if (tz->trips.critical.flags.valid) {
1091                 *temperature = KELVIN_TO_MILLICELSIUS(
1092                                 tz->trips.critical.temperature);
1093                 return 0;
1094         } else
1095                 return -EINVAL;
1096 }
1097
1098 typedef int (*cb)(struct thermal_zone_device *, int,
1099                   struct thermal_cooling_device *);
1100 static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
1101                                         struct thermal_cooling_device *cdev,
1102                                         cb action)
1103 {
1104         struct acpi_device *device = cdev->devdata;
1105         struct acpi_thermal *tz = thermal->devdata;
1106         struct acpi_device *dev;
1107         acpi_status status;
1108         acpi_handle handle;
1109         int i;
1110         int j;
1111         int trip = -1;
1112         int result = 0;
1113
1114         if (tz->trips.critical.flags.valid)
1115                 trip++;
1116
1117         if (tz->trips.hot.flags.valid)
1118                 trip++;
1119
1120         if (tz->trips.passive.flags.valid) {
1121                 trip++;
1122                 for (i = 0; i < tz->trips.passive.devices.count;
1123                     i++) {
1124                         handle = tz->trips.passive.devices.handles[i];
1125                         status = acpi_bus_get_device(handle, &dev);
1126                         if (ACPI_SUCCESS(status) && (dev == device)) {
1127                                 result = action(thermal, trip, cdev);
1128                                 if (result)
1129                                         goto failed;
1130                         }
1131                 }
1132         }
1133
1134         for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
1135                 if (!tz->trips.active[i].flags.valid)
1136                         break;
1137                 trip++;
1138                 for (j = 0;
1139                     j < tz->trips.active[i].devices.count;
1140                     j++) {
1141                         handle = tz->trips.active[i].devices.handles[j];
1142                         status = acpi_bus_get_device(handle, &dev);
1143                         if (ACPI_SUCCESS(status) && (dev == device)) {
1144                                 result = action(thermal, trip, cdev);
1145                                 if (result)
1146                                         goto failed;
1147                         }
1148                 }
1149         }
1150
1151         for (i = 0; i < tz->devices.count; i++) {
1152                 handle = tz->devices.handles[i];
1153                 status = acpi_bus_get_device(handle, &dev);
1154                 if (ACPI_SUCCESS(status) && (dev == device)) {
1155                         result = action(thermal, -1, cdev);
1156                         if (result)
1157                                 goto failed;
1158                 }
1159         }
1160
1161 failed:
1162         return result;
1163 }
1164
1165 static int
1166 acpi_thermal_bind_cooling_device(struct thermal_zone_device *thermal,
1167                                         struct thermal_cooling_device *cdev)
1168 {
1169         return acpi_thermal_cooling_device_cb(thermal, cdev,
1170                                 thermal_zone_bind_cooling_device);
1171 }
1172
1173 static int
1174 acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal,
1175                                         struct thermal_cooling_device *cdev)
1176 {
1177         return acpi_thermal_cooling_device_cb(thermal, cdev,
1178                                 thermal_zone_unbind_cooling_device);
1179 }
1180
1181 static struct thermal_zone_device_ops acpi_thermal_zone_ops = {
1182         .bind = acpi_thermal_bind_cooling_device,
1183         .unbind = acpi_thermal_unbind_cooling_device,
1184         .get_temp = thermal_get_temp,
1185         .get_mode = thermal_get_mode,
1186         .set_mode = thermal_set_mode,
1187         .get_trip_type = thermal_get_trip_type,
1188         .get_trip_temp = thermal_get_trip_temp,
1189         .get_crit_temp = thermal_get_crit_temp,
1190 };
1191
1192 static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
1193 {
1194         int trips = 0;
1195         int result;
1196         acpi_status status;
1197         int i;
1198
1199         if (tz->trips.critical.flags.valid)
1200                 trips++;
1201
1202         if (tz->trips.hot.flags.valid)
1203                 trips++;
1204
1205         if (tz->trips.passive.flags.valid)
1206                 trips++;
1207
1208         for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
1209                         tz->trips.active[i].flags.valid; i++, trips++);
1210         tz->thermal_zone = thermal_zone_device_register("acpitz",
1211                                         trips, tz, &acpi_thermal_zone_ops);
1212         if (IS_ERR(tz->thermal_zone))
1213                 return -ENODEV;
1214
1215         result = sysfs_create_link(&tz->device->dev.kobj,
1216                                    &tz->thermal_zone->device.kobj, "thermal_zone");
1217         if (result)
1218                 return result;
1219
1220         result = sysfs_create_link(&tz->thermal_zone->device.kobj,
1221                                    &tz->device->dev.kobj, "device");
1222         if (result)
1223                 return result;
1224
1225         status = acpi_attach_data(tz->device->handle,
1226                                   acpi_bus_private_data_handler,
1227                                   tz->thermal_zone);
1228         if (ACPI_FAILURE(status)) {
1229                 printk(KERN_ERR PREFIX
1230                                 "Error attaching device data\n");
1231                 return -ENODEV;
1232         }
1233
1234         tz->tz_enabled = 1;
1235
1236         dev_info(&tz->device->dev, "registered as thermal_zone%d\n",
1237                  tz->thermal_zone->id);
1238         return 0;
1239 }
1240
1241 static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz)
1242 {
1243         sysfs_remove_link(&tz->device->dev.kobj, "thermal_zone");
1244         sysfs_remove_link(&tz->thermal_zone->device.kobj, "device");
1245         thermal_zone_device_unregister(tz->thermal_zone);
1246         tz->thermal_zone = NULL;
1247         acpi_detach_data(tz->device->handle, acpi_bus_private_data_handler);
1248 }
1249
1250
1251 /* --------------------------------------------------------------------------
1252                               FS Interface (/proc)
1253    -------------------------------------------------------------------------- */
1254
1255 static struct proc_dir_entry *acpi_thermal_dir;
1256
1257 static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset)
1258 {
1259         struct acpi_thermal *tz = seq->private;
1260
1261
1262         if (!tz)
1263                 goto end;
1264
1265         seq_puts(seq, "state:                   ");
1266
1267         if (!tz->state.critical && !tz->state.hot && !tz->state.passive
1268             && !tz->state.active)
1269                 seq_puts(seq, "ok\n");
1270         else {
1271                 if (tz->state.critical)
1272                         seq_puts(seq, "critical ");
1273                 if (tz->state.hot)
1274                         seq_puts(seq, "hot ");
1275                 if (tz->state.passive)
1276                         seq_puts(seq, "passive ");
1277                 if (tz->state.active)
1278                         seq_printf(seq, "active[%d]", tz->state.active_index);
1279                 seq_puts(seq, "\n");
1280         }
1281
1282       end:
1283         return 0;
1284 }
1285
1286 static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file)
1287 {
1288         return single_open(file, acpi_thermal_state_seq_show, PDE(inode)->data);
1289 }
1290
1291 static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset)
1292 {
1293         int result = 0;
1294         struct acpi_thermal *tz = seq->private;
1295
1296
1297         if (!tz)
1298                 goto end;
1299
1300         result = acpi_thermal_get_temperature(tz);
1301         if (result)
1302                 goto end;
1303
1304         seq_printf(seq, "temperature:             %ld C\n",
1305                    KELVIN_TO_CELSIUS(tz->temperature));
1306
1307       end:
1308         return 0;
1309 }
1310
1311 static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file)
1312 {
1313         return single_open(file, acpi_thermal_temp_seq_show, PDE(inode)->data);
1314 }
1315
1316 static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset)
1317 {
1318         struct acpi_thermal *tz = seq->private;
1319         struct acpi_device *device;
1320         acpi_status status;
1321
1322         int i = 0;
1323         int j = 0;
1324
1325
1326         if (!tz)
1327                 goto end;
1328
1329         if (tz->trips.critical.flags.valid)
1330                 seq_printf(seq, "critical (S5):           %ld C%s",
1331                            KELVIN_TO_CELSIUS(tz->trips.critical.temperature),
1332                            nocrt ? " <disabled>\n" : "\n");
1333
1334         if (tz->trips.hot.flags.valid)
1335                 seq_printf(seq, "hot (S4):                %ld C%s",
1336                            KELVIN_TO_CELSIUS(tz->trips.hot.temperature),
1337                            nocrt ? " <disabled>\n" : "\n");
1338
1339         if (tz->trips.passive.flags.valid) {
1340                 seq_printf(seq,
1341                            "passive:                 %ld C: tc1=%lu tc2=%lu tsp=%lu devices=",
1342                            KELVIN_TO_CELSIUS(tz->trips.passive.temperature),
1343                            tz->trips.passive.tc1, tz->trips.passive.tc2,
1344                            tz->trips.passive.tsp);
1345                 for (j = 0; j < tz->trips.passive.devices.count; j++) {
1346                         status = acpi_bus_get_device(tz->trips.passive.devices.
1347                                                      handles[j], &device);
1348                         seq_printf(seq, "%4.4s ", status ? "" :
1349                                    acpi_device_bid(device));
1350                 }
1351                 seq_puts(seq, "\n");
1352         }
1353
1354         for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
1355                 if (!(tz->trips.active[i].flags.valid))
1356                         break;
1357                 seq_printf(seq, "active[%d]:               %ld C: devices=",
1358                            i,
1359                            KELVIN_TO_CELSIUS(tz->trips.active[i].temperature));
1360                 for (j = 0; j < tz->trips.active[i].devices.count; j++){
1361                         status = acpi_bus_get_device(tz->trips.active[i].
1362                                                      devices.handles[j],
1363                                                      &device);
1364                         seq_printf(seq, "%4.4s ", status ? "" :
1365                                    acpi_device_bid(device));
1366                 }
1367                 seq_puts(seq, "\n");
1368         }
1369
1370       end:
1371         return 0;
1372 }
1373
1374 static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file)
1375 {
1376         return single_open(file, acpi_thermal_trip_seq_show, PDE(inode)->data);
1377 }
1378
1379 static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset)
1380 {
1381         struct acpi_thermal *tz = seq->private;
1382
1383
1384         if (!tz)
1385                 goto end;
1386
1387         if (!tz->flags.cooling_mode)
1388                 seq_puts(seq, "<setting not supported>\n");
1389         else
1390                 seq_puts(seq, "0 - Active; 1 - Passive\n");
1391
1392       end:
1393         return 0;
1394 }
1395
1396 static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file)
1397 {
1398         return single_open(file, acpi_thermal_cooling_seq_show,
1399                            PDE(inode)->data);
1400 }
1401
1402 static ssize_t
1403 acpi_thermal_write_cooling_mode(struct file *file,
1404                                 const char __user * buffer,
1405                                 size_t count, loff_t * ppos)
1406 {
1407         struct seq_file *m = file->private_data;
1408         struct acpi_thermal *tz = m->private;
1409         int result = 0;
1410         char mode_string[12] = { '\0' };
1411
1412
1413         if (!tz || (count > sizeof(mode_string) - 1))
1414                 return -EINVAL;
1415
1416         if (!tz->flags.cooling_mode)
1417                 return -ENODEV;
1418
1419         if (copy_from_user(mode_string, buffer, count))
1420                 return -EFAULT;
1421
1422         mode_string[count] = '\0';
1423
1424         result = acpi_thermal_set_cooling_mode(tz,
1425                                                simple_strtoul(mode_string, NULL,
1426                                                               0));
1427         if (result)
1428                 return result;
1429
1430         acpi_thermal_check(tz);
1431
1432         return count;
1433 }
1434
1435 static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset)
1436 {
1437         struct acpi_thermal *tz = seq->private;
1438
1439
1440         if (!tz)
1441                 goto end;
1442
1443         if (!tz->polling_frequency) {
1444                 seq_puts(seq, "<polling disabled>\n");
1445                 goto end;
1446         }
1447
1448         seq_printf(seq, "polling frequency:       %lu seconds\n",
1449                    (tz->polling_frequency / 10));
1450
1451       end:
1452         return 0;
1453 }
1454
1455 static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file)
1456 {
1457         return single_open(file, acpi_thermal_polling_seq_show,
1458                            PDE(inode)->data);
1459 }
1460
1461 static ssize_t
1462 acpi_thermal_write_polling(struct file *file,
1463                            const char __user * buffer,
1464                            size_t count, loff_t * ppos)
1465 {
1466         struct seq_file *m = file->private_data;
1467         struct acpi_thermal *tz = m->private;
1468         int result = 0;
1469         char polling_string[12] = { '\0' };
1470         int seconds = 0;
1471
1472
1473         if (!tz || (count > sizeof(polling_string) - 1))
1474                 return -EINVAL;
1475
1476         if (copy_from_user(polling_string, buffer, count))
1477                 return -EFAULT;
1478
1479         polling_string[count] = '\0';
1480
1481         seconds = simple_strtoul(polling_string, NULL, 0);
1482
1483         result = acpi_thermal_set_polling(tz, seconds);
1484         if (result)
1485                 return result;
1486
1487         acpi_thermal_check(tz);
1488
1489         return count;
1490 }
1491
1492 static int acpi_thermal_add_fs(struct acpi_device *device)
1493 {
1494         struct proc_dir_entry *entry = NULL;
1495
1496
1497         if (!acpi_device_dir(device)) {
1498                 acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
1499                                                      acpi_thermal_dir);
1500                 if (!acpi_device_dir(device))
1501                         return -ENODEV;
1502                 acpi_device_dir(device)->owner = THIS_MODULE;
1503         }
1504
1505         /* 'state' [R] */
1506         entry = proc_create_data(ACPI_THERMAL_FILE_STATE,
1507                                  S_IRUGO, acpi_device_dir(device),
1508                                  &acpi_thermal_state_fops,
1509                                  acpi_driver_data(device));
1510         if (!entry)
1511                 return -ENODEV;
1512
1513         /* 'temperature' [R] */
1514         entry = proc_create_data(ACPI_THERMAL_FILE_TEMPERATURE,
1515                                  S_IRUGO, acpi_device_dir(device),
1516                                  &acpi_thermal_temp_fops,
1517                                  acpi_driver_data(device));
1518         if (!entry)
1519                 return -ENODEV;
1520
1521         /* 'trip_points' [R] */
1522         entry = proc_create_data(ACPI_THERMAL_FILE_TRIP_POINTS,
1523                                  S_IRUGO,
1524                                  acpi_device_dir(device),
1525                                  &acpi_thermal_trip_fops,
1526                                  acpi_driver_data(device));
1527         if (!entry)
1528                 return -ENODEV;
1529
1530         /* 'cooling_mode' [R/W] */
1531         entry = proc_create_data(ACPI_THERMAL_FILE_COOLING_MODE,
1532                                  S_IFREG | S_IRUGO | S_IWUSR,
1533                                  acpi_device_dir(device),
1534                                  &acpi_thermal_cooling_fops,
1535                                  acpi_driver_data(device));
1536         if (!entry)
1537                 return -ENODEV;
1538
1539         /* 'polling_frequency' [R/W] */
1540         entry = proc_create_data(ACPI_THERMAL_FILE_POLLING_FREQ,
1541                                  S_IFREG | S_IRUGO | S_IWUSR,
1542                                  acpi_device_dir(device),
1543                                  &acpi_thermal_polling_fops,
1544                                  acpi_driver_data(device));
1545         if (!entry)
1546                 return -ENODEV;
1547         return 0;
1548 }
1549
1550 static int acpi_thermal_remove_fs(struct acpi_device *device)
1551 {
1552
1553         if (acpi_device_dir(device)) {
1554                 remove_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ,
1555                                   acpi_device_dir(device));
1556                 remove_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE,
1557                                   acpi_device_dir(device));
1558                 remove_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS,
1559                                   acpi_device_dir(device));
1560                 remove_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE,
1561                                   acpi_device_dir(device));
1562                 remove_proc_entry(ACPI_THERMAL_FILE_STATE,
1563                                   acpi_device_dir(device));
1564                 remove_proc_entry(acpi_device_bid(device), acpi_thermal_dir);
1565                 acpi_device_dir(device) = NULL;
1566         }
1567
1568         return 0;
1569 }
1570
1571 /* --------------------------------------------------------------------------
1572                                  Driver Interface
1573    -------------------------------------------------------------------------- */
1574
1575 static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data)
1576 {
1577         struct acpi_thermal *tz = data;
1578         struct acpi_device *device = NULL;
1579
1580
1581         if (!tz)
1582                 return;
1583
1584         device = tz->device;
1585
1586         switch (event) {
1587         case ACPI_THERMAL_NOTIFY_TEMPERATURE:
1588                 acpi_thermal_check(tz);
1589                 break;
1590         case ACPI_THERMAL_NOTIFY_THRESHOLDS:
1591                 acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_THRESHOLDS);
1592                 acpi_thermal_check(tz);
1593                 acpi_bus_generate_proc_event(device, event, 0);
1594                 acpi_bus_generate_netlink_event(device->pnp.device_class,
1595                                                   device->dev.bus_id, event, 0);
1596                 break;
1597         case ACPI_THERMAL_NOTIFY_DEVICES:
1598                 acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES);
1599                 acpi_thermal_check(tz);
1600                 acpi_bus_generate_proc_event(device, event, 0);
1601                 acpi_bus_generate_netlink_event(device->pnp.device_class,
1602                                                   device->dev.bus_id, event, 0);
1603                 break;
1604         default:
1605                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1606                                   "Unsupported event [0x%x]\n", event));
1607                 break;
1608         }
1609
1610         return;
1611 }
1612
1613 static int acpi_thermal_get_info(struct acpi_thermal *tz)
1614 {
1615         int result = 0;
1616
1617
1618         if (!tz)
1619                 return -EINVAL;
1620
1621         /* Get temperature [_TMP] (required) */
1622         result = acpi_thermal_get_temperature(tz);
1623         if (result)
1624                 return result;
1625
1626         /* Get trip points [_CRT, _PSV, etc.] (required) */
1627         result = acpi_thermal_get_trip_points(tz);
1628         if (result)
1629                 return result;
1630
1631         /* Set the cooling mode [_SCP] to active cooling (default) */
1632         result = acpi_thermal_set_cooling_mode(tz, ACPI_THERMAL_MODE_ACTIVE);
1633         if (!result)
1634                 tz->flags.cooling_mode = 1;
1635
1636         /* Get default polling frequency [_TZP] (optional) */
1637         if (tzp)
1638                 tz->polling_frequency = tzp;
1639         else
1640                 acpi_thermal_get_polling_frequency(tz);
1641
1642         return 0;
1643 }
1644
1645 static int acpi_thermal_add(struct acpi_device *device)
1646 {
1647         int result = 0;
1648         acpi_status status = AE_OK;
1649         struct acpi_thermal *tz = NULL;
1650
1651
1652         if (!device)
1653                 return -EINVAL;
1654
1655         tz = kzalloc(sizeof(struct acpi_thermal), GFP_KERNEL);
1656         if (!tz)
1657                 return -ENOMEM;
1658
1659         tz->device = device;
1660         strcpy(tz->name, device->pnp.bus_id);
1661         strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME);
1662         strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS);
1663         device->driver_data = tz;
1664         mutex_init(&tz->lock);
1665
1666
1667         result = acpi_thermal_get_info(tz);
1668         if (result)
1669                 goto free_memory;
1670
1671         result = acpi_thermal_register_thermal_zone(tz);
1672         if (result)
1673                 goto free_memory;
1674
1675         result = acpi_thermal_add_fs(device);
1676         if (result)
1677                 goto unregister_thermal_zone;
1678
1679         init_timer(&tz->timer);
1680
1681         acpi_thermal_active_off(tz);
1682
1683         acpi_thermal_check(tz);
1684
1685         status = acpi_install_notify_handler(device->handle,
1686                                              ACPI_DEVICE_NOTIFY,
1687                                              acpi_thermal_notify, tz);
1688         if (ACPI_FAILURE(status)) {
1689                 result = -ENODEV;
1690                 goto remove_fs;
1691         }
1692
1693         printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n",
1694                acpi_device_name(device), acpi_device_bid(device),
1695                KELVIN_TO_CELSIUS(tz->temperature));
1696         goto end;
1697
1698 remove_fs:
1699         acpi_thermal_remove_fs(device);
1700 unregister_thermal_zone:
1701         thermal_zone_device_unregister(tz->thermal_zone);
1702 free_memory:
1703         kfree(tz);
1704 end:
1705         return result;
1706 }
1707
1708 static int acpi_thermal_remove(struct acpi_device *device, int type)
1709 {
1710         acpi_status status = AE_OK;
1711         struct acpi_thermal *tz = NULL;
1712
1713
1714         if (!device || !acpi_driver_data(device))
1715                 return -EINVAL;
1716
1717         tz = acpi_driver_data(device);
1718
1719         /* avoid timer adding new defer task */
1720         tz->zombie = 1;
1721         /* wait for running timer (on other CPUs) finish */
1722         del_timer_sync(&(tz->timer));
1723         /* synchronize deferred task */
1724         acpi_os_wait_events_complete(NULL);
1725         /* deferred task may reinsert timer */
1726         del_timer_sync(&(tz->timer));
1727
1728         status = acpi_remove_notify_handler(device->handle,
1729                                             ACPI_DEVICE_NOTIFY,
1730                                             acpi_thermal_notify);
1731
1732         /* Terminate policy */
1733         if (tz->trips.passive.flags.valid && tz->trips.passive.flags.enabled) {
1734                 tz->trips.passive.flags.enabled = 0;
1735                 acpi_thermal_passive(tz);
1736         }
1737         if (tz->trips.active[0].flags.valid
1738             && tz->trips.active[0].flags.enabled) {
1739                 tz->trips.active[0].flags.enabled = 0;
1740                 acpi_thermal_active(tz);
1741         }
1742
1743         acpi_thermal_remove_fs(device);
1744         acpi_thermal_unregister_thermal_zone(tz);
1745         mutex_destroy(&tz->lock);
1746         kfree(tz);
1747         return 0;
1748 }
1749
1750 static int acpi_thermal_resume(struct acpi_device *device)
1751 {
1752         struct acpi_thermal *tz = NULL;
1753         int i, j, power_state, result;
1754
1755
1756         if (!device || !acpi_driver_data(device))
1757                 return -EINVAL;
1758
1759         tz = acpi_driver_data(device);
1760
1761         for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
1762                 if (!(&tz->trips.active[i]))
1763                         break;
1764                 if (!tz->trips.active[i].flags.valid)
1765                         break;
1766                 tz->trips.active[i].flags.enabled = 1;
1767                 for (j = 0; j < tz->trips.active[i].devices.count; j++) {
1768                         result = acpi_bus_get_power(tz->trips.active[i].devices.
1769                             handles[j], &power_state);
1770                         if (result || (power_state != ACPI_STATE_D0)) {
1771                                 tz->trips.active[i].flags.enabled = 0;
1772                                 break;
1773                         }
1774                 }
1775                 tz->state.active |= tz->trips.active[i].flags.enabled;
1776         }
1777
1778         acpi_thermal_check(tz);
1779
1780         return AE_OK;
1781 }
1782
1783 static int thermal_act(const struct dmi_system_id *d) {
1784
1785         if (act == 0) {
1786                 printk(KERN_NOTICE "ACPI: %s detected: "
1787                         "disabling all active thermal trip points\n", d->ident);
1788                 act = -1;
1789         }
1790         return 0;
1791 }
1792 static int thermal_nocrt(const struct dmi_system_id *d) {
1793
1794         printk(KERN_NOTICE "ACPI: %s detected: "
1795                 "disabling all critical thermal trip point actions.\n", d->ident);
1796         nocrt = 1;
1797         return 0;
1798 }
1799 static int thermal_tzp(const struct dmi_system_id *d) {
1800
1801         if (tzp == 0) {
1802                 printk(KERN_NOTICE "ACPI: %s detected: "
1803                         "enabling thermal zone polling\n", d->ident);
1804                 tzp = 300;      /* 300 dS = 30 Seconds */
1805         }
1806         return 0;
1807 }
1808 static int thermal_psv(const struct dmi_system_id *d) {
1809
1810         if (psv == 0) {
1811                 printk(KERN_NOTICE "ACPI: %s detected: "
1812                         "disabling all passive thermal trip points\n", d->ident);
1813                 psv = -1;
1814         }
1815         return 0;
1816 }
1817
1818 static struct dmi_system_id thermal_dmi_table[] __initdata = {
1819         /*
1820          * Award BIOS on this AOpen makes thermal control almost worthless.
1821          * http://bugzilla.kernel.org/show_bug.cgi?id=8842
1822          */
1823         {
1824          .callback = thermal_act,
1825          .ident = "AOpen i915GMm-HFS",
1826          .matches = {
1827                 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
1828                 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
1829                 },
1830         },
1831         {
1832          .callback = thermal_psv,
1833          .ident = "AOpen i915GMm-HFS",
1834          .matches = {
1835                 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
1836                 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
1837                 },
1838         },
1839         {
1840          .callback = thermal_tzp,
1841          .ident = "AOpen i915GMm-HFS",
1842          .matches = {
1843                 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
1844                 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
1845                 },
1846         },
1847         {
1848          .callback = thermal_nocrt,
1849          .ident = "Gigabyte GA-7ZX",
1850          .matches = {
1851                 DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."),
1852                 DMI_MATCH(DMI_BOARD_NAME, "7ZX"),
1853                 },
1854         },
1855         {}
1856 };
1857
1858 static int __init acpi_thermal_init(void)
1859 {
1860         int result = 0;
1861
1862         dmi_check_system(thermal_dmi_table);
1863
1864         if (off) {
1865                 printk(KERN_NOTICE "ACPI: thermal control disabled\n");
1866                 return -ENODEV;
1867         }
1868         acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir);
1869         if (!acpi_thermal_dir)
1870                 return -ENODEV;
1871         acpi_thermal_dir->owner = THIS_MODULE;
1872
1873         result = acpi_bus_register_driver(&acpi_thermal_driver);
1874         if (result < 0) {
1875                 remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir);
1876                 return -ENODEV;
1877         }
1878
1879         return 0;
1880 }
1881
1882 static void __exit acpi_thermal_exit(void)
1883 {
1884
1885         acpi_bus_unregister_driver(&acpi_thermal_driver);
1886
1887         remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir);
1888
1889         return;
1890 }
1891
1892 module_init(acpi_thermal_init);
1893 module_exit(acpi_thermal_exit);