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