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