]> Pileus Git - ~andy/linux/blob - drivers/acpi/thermal.c
Merge branch 'nfsd-next' of git://linux-nfs.org/~bfields/linux
[~andy/linux] / 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/slab.h>
39 #include <linux/types.h>
40 #include <linux/jiffies.h>
41 #include <linux/kmod.h>
42 #include <linux/reboot.h>
43 #include <linux/device.h>
44 #include <linux/thermal.h>
45 #include <linux/acpi.h>
46 #include <asm/uaccess.h>
47
48 #define PREFIX "ACPI: "
49
50 #define ACPI_THERMAL_CLASS              "thermal_zone"
51 #define ACPI_THERMAL_DEVICE_NAME        "Thermal Zone"
52 #define ACPI_THERMAL_NOTIFY_TEMPERATURE 0x80
53 #define ACPI_THERMAL_NOTIFY_THRESHOLDS  0x81
54 #define ACPI_THERMAL_NOTIFY_DEVICES     0x82
55 #define ACPI_THERMAL_NOTIFY_CRITICAL    0xF0
56 #define ACPI_THERMAL_NOTIFY_HOT         0xF1
57 #define ACPI_THERMAL_MODE_ACTIVE        0x00
58
59 #define ACPI_THERMAL_MAX_ACTIVE 10
60 #define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65
61
62 #define _COMPONENT              ACPI_THERMAL_COMPONENT
63 ACPI_MODULE_NAME("thermal");
64
65 MODULE_AUTHOR("Paul Diefenbaugh");
66 MODULE_DESCRIPTION("ACPI Thermal Zone Driver");
67 MODULE_LICENSE("GPL");
68
69 static int act;
70 module_param(act, int, 0644);
71 MODULE_PARM_DESC(act, "Disable or override all lowest active trip points.");
72
73 static int crt;
74 module_param(crt, int, 0644);
75 MODULE_PARM_DESC(crt, "Disable or lower all critical trip points.");
76
77 static int tzp;
78 module_param(tzp, int, 0444);
79 MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.");
80
81 static int nocrt;
82 module_param(nocrt, int, 0);
83 MODULE_PARM_DESC(nocrt, "Set to take no action upon ACPI thermal zone critical trips points.");
84
85 static int off;
86 module_param(off, int, 0);
87 MODULE_PARM_DESC(off, "Set to disable ACPI thermal support.");
88
89 static int psv;
90 module_param(psv, int, 0644);
91 MODULE_PARM_DESC(psv, "Disable or override all passive trip points.");
92
93 static int acpi_thermal_add(struct acpi_device *device);
94 static int acpi_thermal_remove(struct acpi_device *device);
95 static void acpi_thermal_notify(struct acpi_device *device, u32 event);
96
97 static const struct acpi_device_id  thermal_device_ids[] = {
98         {ACPI_THERMAL_HID, 0},
99         {"", 0},
100 };
101 MODULE_DEVICE_TABLE(acpi, thermal_device_ids);
102
103 #ifdef CONFIG_PM_SLEEP
104 static int acpi_thermal_resume(struct device *dev);
105 #else
106 #define acpi_thermal_resume NULL
107 #endif
108 static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, NULL, acpi_thermal_resume);
109
110 static struct acpi_driver acpi_thermal_driver = {
111         .name = "thermal",
112         .class = ACPI_THERMAL_CLASS,
113         .ids = thermal_device_ids,
114         .ops = {
115                 .add = acpi_thermal_add,
116                 .remove = acpi_thermal_remove,
117                 .notify = acpi_thermal_notify,
118                 },
119         .drv.pm = &acpi_thermal_pm,
120 };
121
122 struct acpi_thermal_state {
123         u8 critical:1;
124         u8 hot:1;
125         u8 passive:1;
126         u8 active:1;
127         u8 reserved:4;
128         int active_index;
129 };
130
131 struct acpi_thermal_state_flags {
132         u8 valid:1;
133         u8 enabled:1;
134         u8 reserved:6;
135 };
136
137 struct acpi_thermal_critical {
138         struct acpi_thermal_state_flags flags;
139         unsigned long temperature;
140 };
141
142 struct acpi_thermal_hot {
143         struct acpi_thermal_state_flags flags;
144         unsigned long temperature;
145 };
146
147 struct acpi_thermal_passive {
148         struct acpi_thermal_state_flags flags;
149         unsigned long temperature;
150         unsigned long tc1;
151         unsigned long tc2;
152         unsigned long tsp;
153         struct acpi_handle_list devices;
154 };
155
156 struct acpi_thermal_active {
157         struct acpi_thermal_state_flags flags;
158         unsigned long temperature;
159         struct acpi_handle_list devices;
160 };
161
162 struct acpi_thermal_trips {
163         struct acpi_thermal_critical critical;
164         struct acpi_thermal_hot hot;
165         struct acpi_thermal_passive passive;
166         struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE];
167 };
168
169 struct acpi_thermal_flags {
170         u8 cooling_mode:1;      /* _SCP */
171         u8 devices:1;           /* _TZD */
172         u8 reserved:6;
173 };
174
175 struct acpi_thermal {
176         struct acpi_device * device;
177         acpi_bus_id name;
178         unsigned long temperature;
179         unsigned long last_temperature;
180         unsigned long polling_frequency;
181         volatile u8 zombie;
182         struct acpi_thermal_flags flags;
183         struct acpi_thermal_state state;
184         struct acpi_thermal_trips trips;
185         struct acpi_handle_list devices;
186         struct thermal_zone_device *thermal_zone;
187         int tz_enabled;
188         int kelvin_offset;
189 };
190
191 /* --------------------------------------------------------------------------
192                              Thermal Zone Management
193    -------------------------------------------------------------------------- */
194
195 static int acpi_thermal_get_temperature(struct acpi_thermal *tz)
196 {
197         acpi_status status = AE_OK;
198         unsigned long long tmp;
199
200         if (!tz)
201                 return -EINVAL;
202
203         tz->last_temperature = tz->temperature;
204
205         status = acpi_evaluate_integer(tz->device->handle, "_TMP", NULL, &tmp);
206         if (ACPI_FAILURE(status))
207                 return -ENODEV;
208
209         tz->temperature = tmp;
210         ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Temperature is %lu dK\n",
211                           tz->temperature));
212
213         return 0;
214 }
215
216 static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz)
217 {
218         acpi_status status = AE_OK;
219         unsigned long long tmp;
220
221         if (!tz)
222                 return -EINVAL;
223
224         status = acpi_evaluate_integer(tz->device->handle, "_TZP", NULL, &tmp);
225         if (ACPI_FAILURE(status))
226                 return -ENODEV;
227
228         tz->polling_frequency = tmp;
229         ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency is %lu dS\n",
230                           tz->polling_frequency));
231
232         return 0;
233 }
234
235 static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode)
236 {
237         if (!tz)
238                 return -EINVAL;
239
240         if (!acpi_has_method(tz->device->handle, "_SCP")) {
241                 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n"));
242                 return -ENODEV;
243         } else if (ACPI_FAILURE(acpi_execute_simple_method(tz->device->handle,
244                                                            "_SCP", mode))) {
245                 return -ENODEV;
246         }
247
248         return 0;
249 }
250
251 #define ACPI_TRIPS_CRITICAL     0x01
252 #define ACPI_TRIPS_HOT          0x02
253 #define ACPI_TRIPS_PASSIVE      0x04
254 #define ACPI_TRIPS_ACTIVE       0x08
255 #define ACPI_TRIPS_DEVICES      0x10
256
257 #define ACPI_TRIPS_REFRESH_THRESHOLDS   (ACPI_TRIPS_PASSIVE | ACPI_TRIPS_ACTIVE)
258 #define ACPI_TRIPS_REFRESH_DEVICES      ACPI_TRIPS_DEVICES
259
260 #define ACPI_TRIPS_INIT      (ACPI_TRIPS_CRITICAL | ACPI_TRIPS_HOT |    \
261                               ACPI_TRIPS_PASSIVE | ACPI_TRIPS_ACTIVE |  \
262                               ACPI_TRIPS_DEVICES)
263
264 /*
265  * This exception is thrown out in two cases:
266  * 1.An invalid trip point becomes invalid or a valid trip point becomes invalid
267  *   when re-evaluating the AML code.
268  * 2.TODO: Devices listed in _PSL, _ALx, _TZD may change.
269  *   We need to re-bind the cooling devices of a thermal zone when this occurs.
270  */
271 #define ACPI_THERMAL_TRIPS_EXCEPTION(flags, str)        \
272 do {    \
273         if (flags != ACPI_TRIPS_INIT)   \
274                 ACPI_EXCEPTION((AE_INFO, AE_ERROR,      \
275                 "ACPI thermal trip point %s changed\n"  \
276                 "Please send acpidump to linux-acpi@vger.kernel.org", str)); \
277 } while (0)
278
279 static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
280 {
281         acpi_status status = AE_OK;
282         unsigned long long tmp;
283         struct acpi_handle_list devices;
284         int valid = 0;
285         int i;
286
287         /* Critical Shutdown */
288         if (flag & ACPI_TRIPS_CRITICAL) {
289                 status = acpi_evaluate_integer(tz->device->handle,
290                                 "_CRT", NULL, &tmp);
291                 tz->trips.critical.temperature = tmp;
292                 /*
293                  * Treat freezing temperatures as invalid as well; some
294                  * BIOSes return really low values and cause reboots at startup.
295                  * Below zero (Celsius) values clearly aren't right for sure..
296                  * ... so lets discard those as invalid.
297                  */
298                 if (ACPI_FAILURE(status)) {
299                         tz->trips.critical.flags.valid = 0;
300                         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
301                                           "No critical threshold\n"));
302                 } else if (tmp <= 2732) {
303                         pr_warn(FW_BUG "Invalid critical threshold (%llu)\n",
304                                 tmp);
305                         tz->trips.critical.flags.valid = 0;
306                 } else {
307                         tz->trips.critical.flags.valid = 1;
308                         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
309                                           "Found critical threshold [%lu]\n",
310                                           tz->trips.critical.temperature));
311                 }
312                 if (tz->trips.critical.flags.valid == 1) {
313                         if (crt == -1) {
314                                 tz->trips.critical.flags.valid = 0;
315                         } else if (crt > 0) {
316                                 unsigned long crt_k = CELSIUS_TO_KELVIN(crt);
317                                 /*
318                                  * Allow override critical threshold
319                                  */
320                                 if (crt_k > tz->trips.critical.temperature)
321                                         pr_warn(PREFIX "Critical threshold %d C\n",
322                                                 crt);
323                                 tz->trips.critical.temperature = crt_k;
324                         }
325                 }
326         }
327
328         /* Critical Sleep (optional) */
329         if (flag & ACPI_TRIPS_HOT) {
330                 status = acpi_evaluate_integer(tz->device->handle,
331                                 "_HOT", NULL, &tmp);
332                 if (ACPI_FAILURE(status)) {
333                         tz->trips.hot.flags.valid = 0;
334                         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
335                                         "No hot threshold\n"));
336                 } else {
337                         tz->trips.hot.temperature = tmp;
338                         tz->trips.hot.flags.valid = 1;
339                         ACPI_DEBUG_PRINT((ACPI_DB_INFO,
340                                         "Found hot threshold [%lu]\n",
341                                         tz->trips.critical.temperature));
342                 }
343         }
344
345         /* Passive (optional) */
346         if (((flag & ACPI_TRIPS_PASSIVE) && tz->trips.passive.flags.valid) ||
347                 (flag == ACPI_TRIPS_INIT)) {
348                 valid = tz->trips.passive.flags.valid;
349                 if (psv == -1) {
350                         status = AE_SUPPORT;
351                 } else if (psv > 0) {
352                         tmp = CELSIUS_TO_KELVIN(psv);
353                         status = AE_OK;
354                 } else {
355                         status = acpi_evaluate_integer(tz->device->handle,
356                                 "_PSV", NULL, &tmp);
357                 }
358
359                 if (ACPI_FAILURE(status))
360                         tz->trips.passive.flags.valid = 0;
361                 else {
362                         tz->trips.passive.temperature = tmp;
363                         tz->trips.passive.flags.valid = 1;
364                         if (flag == ACPI_TRIPS_INIT) {
365                                 status = acpi_evaluate_integer(
366                                                 tz->device->handle, "_TC1",
367                                                 NULL, &tmp);
368                                 if (ACPI_FAILURE(status))
369                                         tz->trips.passive.flags.valid = 0;
370                                 else
371                                         tz->trips.passive.tc1 = tmp;
372                                 status = acpi_evaluate_integer(
373                                                 tz->device->handle, "_TC2",
374                                                 NULL, &tmp);
375                                 if (ACPI_FAILURE(status))
376                                         tz->trips.passive.flags.valid = 0;
377                                 else
378                                         tz->trips.passive.tc2 = tmp;
379                                 status = acpi_evaluate_integer(
380                                                 tz->device->handle, "_TSP",
381                                                 NULL, &tmp);
382                                 if (ACPI_FAILURE(status))
383                                         tz->trips.passive.flags.valid = 0;
384                                 else
385                                         tz->trips.passive.tsp = tmp;
386                         }
387                 }
388         }
389         if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.passive.flags.valid) {
390                 memset(&devices, 0, sizeof(struct acpi_handle_list));
391                 status = acpi_evaluate_reference(tz->device->handle, "_PSL",
392                                                         NULL, &devices);
393                 if (ACPI_FAILURE(status)) {
394                         pr_warn(PREFIX "Invalid passive threshold\n");
395                         tz->trips.passive.flags.valid = 0;
396                 }
397                 else
398                         tz->trips.passive.flags.valid = 1;
399
400                 if (memcmp(&tz->trips.passive.devices, &devices,
401                                 sizeof(struct acpi_handle_list))) {
402                         memcpy(&tz->trips.passive.devices, &devices,
403                                 sizeof(struct acpi_handle_list));
404                         ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device");
405                 }
406         }
407         if ((flag & ACPI_TRIPS_PASSIVE) || (flag & ACPI_TRIPS_DEVICES)) {
408                 if (valid != tz->trips.passive.flags.valid)
409                                 ACPI_THERMAL_TRIPS_EXCEPTION(flag, "state");
410         }
411
412         /* Active (optional) */
413         for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
414                 char name[5] = { '_', 'A', 'C', ('0' + i), '\0' };
415                 valid = tz->trips.active[i].flags.valid;
416
417                 if (act == -1)
418                         break; /* disable all active trip points */
419
420                 if ((flag == ACPI_TRIPS_INIT) || ((flag & ACPI_TRIPS_ACTIVE) &&
421                         tz->trips.active[i].flags.valid)) {
422                         status = acpi_evaluate_integer(tz->device->handle,
423                                                         name, NULL, &tmp);
424                         if (ACPI_FAILURE(status)) {
425                                 tz->trips.active[i].flags.valid = 0;
426                                 if (i == 0)
427                                         break;
428                                 if (act <= 0)
429                                         break;
430                                 if (i == 1)
431                                         tz->trips.active[0].temperature =
432                                                 CELSIUS_TO_KELVIN(act);
433                                 else
434                                         /*
435                                          * Don't allow override higher than
436                                          * the next higher trip point
437                                          */
438                                         tz->trips.active[i - 1].temperature =
439                                                 (tz->trips.active[i - 2].temperature <
440                                                 CELSIUS_TO_KELVIN(act) ?
441                                                 tz->trips.active[i - 2].temperature :
442                                                 CELSIUS_TO_KELVIN(act));
443                                 break;
444                         } else {
445                                 tz->trips.active[i].temperature = tmp;
446                                 tz->trips.active[i].flags.valid = 1;
447                         }
448                 }
449
450                 name[2] = 'L';
451                 if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.active[i].flags.valid ) {
452                         memset(&devices, 0, sizeof(struct acpi_handle_list));
453                         status = acpi_evaluate_reference(tz->device->handle,
454                                                 name, NULL, &devices);
455                         if (ACPI_FAILURE(status)) {
456                                 pr_warn(PREFIX "Invalid active%d threshold\n",
457                                         i);
458                                 tz->trips.active[i].flags.valid = 0;
459                         }
460                         else
461                                 tz->trips.active[i].flags.valid = 1;
462
463                         if (memcmp(&tz->trips.active[i].devices, &devices,
464                                         sizeof(struct acpi_handle_list))) {
465                                 memcpy(&tz->trips.active[i].devices, &devices,
466                                         sizeof(struct acpi_handle_list));
467                                 ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device");
468                         }
469                 }
470                 if ((flag & ACPI_TRIPS_ACTIVE) || (flag & ACPI_TRIPS_DEVICES))
471                         if (valid != tz->trips.active[i].flags.valid)
472                                 ACPI_THERMAL_TRIPS_EXCEPTION(flag, "state");
473
474                 if (!tz->trips.active[i].flags.valid)
475                         break;
476         }
477
478         if ((flag & ACPI_TRIPS_DEVICES)
479             && acpi_has_method(tz->device->handle, "_TZD")) {
480                 memset(&devices, 0, sizeof(devices));
481                 status = acpi_evaluate_reference(tz->device->handle, "_TZD",
482                                                 NULL, &devices);
483                 if (ACPI_SUCCESS(status)
484                     && memcmp(&tz->devices, &devices, sizeof(devices))) {
485                         tz->devices = devices;
486                         ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device");
487                 }
488         }
489
490         return 0;
491 }
492
493 static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
494 {
495         int i, valid, ret = acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT);
496
497         if (ret)
498                 return ret;
499
500         valid = tz->trips.critical.flags.valid |
501                 tz->trips.hot.flags.valid |
502                 tz->trips.passive.flags.valid;
503
504         for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
505                 valid |= tz->trips.active[i].flags.valid;
506
507         if (!valid) {
508                 pr_warn(FW_BUG "No valid trip found\n");
509                 return -ENODEV;
510         }
511         return 0;
512 }
513
514 static void acpi_thermal_check(void *data)
515 {
516         struct acpi_thermal *tz = data;
517
518         if (!tz->tz_enabled)
519                 return;
520
521         thermal_zone_device_update(tz->thermal_zone);
522 }
523
524 /* sys I/F for generic thermal sysfs support */
525 #define KELVIN_TO_MILLICELSIUS(t, off) (((t) - (off)) * 100)
526
527 static int thermal_get_temp(struct thermal_zone_device *thermal,
528                             unsigned long *temp)
529 {
530         struct acpi_thermal *tz = thermal->devdata;
531         int result;
532
533         if (!tz)
534                 return -EINVAL;
535
536         result = acpi_thermal_get_temperature(tz);
537         if (result)
538                 return result;
539
540         *temp = KELVIN_TO_MILLICELSIUS(tz->temperature, tz->kelvin_offset);
541         return 0;
542 }
543
544 static int thermal_get_mode(struct thermal_zone_device *thermal,
545                                 enum thermal_device_mode *mode)
546 {
547         struct acpi_thermal *tz = thermal->devdata;
548
549         if (!tz)
550                 return -EINVAL;
551
552         *mode = tz->tz_enabled ? THERMAL_DEVICE_ENABLED :
553                 THERMAL_DEVICE_DISABLED;
554
555         return 0;
556 }
557
558 static int thermal_set_mode(struct thermal_zone_device *thermal,
559                                 enum thermal_device_mode mode)
560 {
561         struct acpi_thermal *tz = thermal->devdata;
562         int enable;
563
564         if (!tz)
565                 return -EINVAL;
566
567         /*
568          * enable/disable thermal management from ACPI thermal driver
569          */
570         if (mode == THERMAL_DEVICE_ENABLED)
571                 enable = 1;
572         else if (mode == THERMAL_DEVICE_DISABLED) {
573                 enable = 0;
574                 pr_warn("thermal zone will be disabled\n");
575         } else
576                 return -EINVAL;
577
578         if (enable != tz->tz_enabled) {
579                 tz->tz_enabled = enable;
580                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
581                         "%s kernel ACPI thermal control\n",
582                         tz->tz_enabled ? "Enable" : "Disable"));
583                 acpi_thermal_check(tz);
584         }
585         return 0;
586 }
587
588 static int thermal_get_trip_type(struct thermal_zone_device *thermal,
589                                  int trip, enum thermal_trip_type *type)
590 {
591         struct acpi_thermal *tz = thermal->devdata;
592         int i;
593
594         if (!tz || trip < 0)
595                 return -EINVAL;
596
597         if (tz->trips.critical.flags.valid) {
598                 if (!trip) {
599                         *type = THERMAL_TRIP_CRITICAL;
600                         return 0;
601                 }
602                 trip--;
603         }
604
605         if (tz->trips.hot.flags.valid) {
606                 if (!trip) {
607                         *type = THERMAL_TRIP_HOT;
608                         return 0;
609                 }
610                 trip--;
611         }
612
613         if (tz->trips.passive.flags.valid) {
614                 if (!trip) {
615                         *type = THERMAL_TRIP_PASSIVE;
616                         return 0;
617                 }
618                 trip--;
619         }
620
621         for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
622                 tz->trips.active[i].flags.valid; i++) {
623                 if (!trip) {
624                         *type = THERMAL_TRIP_ACTIVE;
625                         return 0;
626                 }
627                 trip--;
628         }
629
630         return -EINVAL;
631 }
632
633 static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
634                                  int trip, unsigned long *temp)
635 {
636         struct acpi_thermal *tz = thermal->devdata;
637         int i;
638
639         if (!tz || trip < 0)
640                 return -EINVAL;
641
642         if (tz->trips.critical.flags.valid) {
643                 if (!trip) {
644                         *temp = KELVIN_TO_MILLICELSIUS(
645                                 tz->trips.critical.temperature,
646                                 tz->kelvin_offset);
647                         return 0;
648                 }
649                 trip--;
650         }
651
652         if (tz->trips.hot.flags.valid) {
653                 if (!trip) {
654                         *temp = KELVIN_TO_MILLICELSIUS(
655                                 tz->trips.hot.temperature,
656                                 tz->kelvin_offset);
657                         return 0;
658                 }
659                 trip--;
660         }
661
662         if (tz->trips.passive.flags.valid) {
663                 if (!trip) {
664                         *temp = KELVIN_TO_MILLICELSIUS(
665                                 tz->trips.passive.temperature,
666                                 tz->kelvin_offset);
667                         return 0;
668                 }
669                 trip--;
670         }
671
672         for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
673                 tz->trips.active[i].flags.valid; i++) {
674                 if (!trip) {
675                         *temp = KELVIN_TO_MILLICELSIUS(
676                                 tz->trips.active[i].temperature,
677                                 tz->kelvin_offset);
678                         return 0;
679                 }
680                 trip--;
681         }
682
683         return -EINVAL;
684 }
685
686 static int thermal_get_crit_temp(struct thermal_zone_device *thermal,
687                                 unsigned long *temperature) {
688         struct acpi_thermal *tz = thermal->devdata;
689
690         if (tz->trips.critical.flags.valid) {
691                 *temperature = KELVIN_TO_MILLICELSIUS(
692                                 tz->trips.critical.temperature,
693                                 tz->kelvin_offset);
694                 return 0;
695         } else
696                 return -EINVAL;
697 }
698
699 static int thermal_get_trend(struct thermal_zone_device *thermal,
700                                 int trip, enum thermal_trend *trend)
701 {
702         struct acpi_thermal *tz = thermal->devdata;
703         enum thermal_trip_type type;
704         int i;
705
706         if (thermal_get_trip_type(thermal, trip, &type))
707                 return -EINVAL;
708
709         if (type == THERMAL_TRIP_ACTIVE) {
710                 unsigned long trip_temp;
711                 unsigned long temp = KELVIN_TO_MILLICELSIUS(tz->temperature,
712                                                         tz->kelvin_offset);
713                 if (thermal_get_trip_temp(thermal, trip, &trip_temp))
714                         return -EINVAL;
715
716                 if (temp > trip_temp) {
717                         *trend = THERMAL_TREND_RAISING;
718                         return 0;
719                 } else {
720                         /* Fall back on default trend */
721                         return -EINVAL;
722                 }
723         }
724
725         /*
726          * tz->temperature has already been updated by generic thermal layer,
727          * before this callback being invoked
728          */
729         i = (tz->trips.passive.tc1 * (tz->temperature - tz->last_temperature))
730                 + (tz->trips.passive.tc2
731                 * (tz->temperature - tz->trips.passive.temperature));
732
733         if (i > 0)
734                 *trend = THERMAL_TREND_RAISING;
735         else if (i < 0)
736                 *trend = THERMAL_TREND_DROPPING;
737         else
738                 *trend = THERMAL_TREND_STABLE;
739         return 0;
740 }
741
742
743 static int thermal_notify(struct thermal_zone_device *thermal, int trip,
744                            enum thermal_trip_type trip_type)
745 {
746         u8 type = 0;
747         struct acpi_thermal *tz = thermal->devdata;
748
749         if (trip_type == THERMAL_TRIP_CRITICAL)
750                 type = ACPI_THERMAL_NOTIFY_CRITICAL;
751         else if (trip_type == THERMAL_TRIP_HOT)
752                 type = ACPI_THERMAL_NOTIFY_HOT;
753         else
754                 return 0;
755
756         acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
757                                         dev_name(&tz->device->dev), type, 1);
758
759         if (trip_type == THERMAL_TRIP_CRITICAL && nocrt)
760                 return 1;
761
762         return 0;
763 }
764
765 static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
766                                         struct thermal_cooling_device *cdev,
767                                         bool bind)
768 {
769         struct acpi_device *device = cdev->devdata;
770         struct acpi_thermal *tz = thermal->devdata;
771         struct acpi_device *dev;
772         acpi_status status;
773         acpi_handle handle;
774         int i;
775         int j;
776         int trip = -1;
777         int result = 0;
778
779         if (tz->trips.critical.flags.valid)
780                 trip++;
781
782         if (tz->trips.hot.flags.valid)
783                 trip++;
784
785         if (tz->trips.passive.flags.valid) {
786                 trip++;
787                 for (i = 0; i < tz->trips.passive.devices.count;
788                     i++) {
789                         handle = tz->trips.passive.devices.handles[i];
790                         status = acpi_bus_get_device(handle, &dev);
791                         if (ACPI_FAILURE(status) || dev != device)
792                                 continue;
793                         if (bind)
794                                 result =
795                                         thermal_zone_bind_cooling_device
796                                         (thermal, trip, cdev,
797                                          THERMAL_NO_LIMIT, THERMAL_NO_LIMIT);
798                         else
799                                 result =
800                                         thermal_zone_unbind_cooling_device
801                                         (thermal, trip, cdev);
802                         if (result)
803                                 goto failed;
804                 }
805         }
806
807         for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
808                 if (!tz->trips.active[i].flags.valid)
809                         break;
810                 trip++;
811                 for (j = 0;
812                     j < tz->trips.active[i].devices.count;
813                     j++) {
814                         handle = tz->trips.active[i].devices.handles[j];
815                         status = acpi_bus_get_device(handle, &dev);
816                         if (ACPI_FAILURE(status) || dev != device)
817                                 continue;
818                         if (bind)
819                                 result = thermal_zone_bind_cooling_device
820                                         (thermal, trip, cdev,
821                                          THERMAL_NO_LIMIT, THERMAL_NO_LIMIT);
822                         else
823                                 result = thermal_zone_unbind_cooling_device
824                                         (thermal, trip, cdev);
825                         if (result)
826                                 goto failed;
827                 }
828         }
829
830         for (i = 0; i < tz->devices.count; i++) {
831                 handle = tz->devices.handles[i];
832                 status = acpi_bus_get_device(handle, &dev);
833                 if (ACPI_SUCCESS(status) && (dev == device)) {
834                         if (bind)
835                                 result = thermal_zone_bind_cooling_device
836                                                 (thermal, THERMAL_TRIPS_NONE,
837                                                  cdev, THERMAL_NO_LIMIT,
838                                                  THERMAL_NO_LIMIT);
839                         else
840                                 result = thermal_zone_unbind_cooling_device
841                                                 (thermal, THERMAL_TRIPS_NONE,
842                                                  cdev);
843                         if (result)
844                                 goto failed;
845                 }
846         }
847
848 failed:
849         return result;
850 }
851
852 static int
853 acpi_thermal_bind_cooling_device(struct thermal_zone_device *thermal,
854                                         struct thermal_cooling_device *cdev)
855 {
856         return acpi_thermal_cooling_device_cb(thermal, cdev, true);
857 }
858
859 static int
860 acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal,
861                                         struct thermal_cooling_device *cdev)
862 {
863         return acpi_thermal_cooling_device_cb(thermal, cdev, false);
864 }
865
866 static struct thermal_zone_device_ops acpi_thermal_zone_ops = {
867         .bind = acpi_thermal_bind_cooling_device,
868         .unbind = acpi_thermal_unbind_cooling_device,
869         .get_temp = thermal_get_temp,
870         .get_mode = thermal_get_mode,
871         .set_mode = thermal_set_mode,
872         .get_trip_type = thermal_get_trip_type,
873         .get_trip_temp = thermal_get_trip_temp,
874         .get_crit_temp = thermal_get_crit_temp,
875         .get_trend = thermal_get_trend,
876         .notify = thermal_notify,
877 };
878
879 static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
880 {
881         int trips = 0;
882         int result;
883         acpi_status status;
884         int i;
885
886         if (tz->trips.critical.flags.valid)
887                 trips++;
888
889         if (tz->trips.hot.flags.valid)
890                 trips++;
891
892         if (tz->trips.passive.flags.valid)
893                 trips++;
894
895         for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
896                         tz->trips.active[i].flags.valid; i++, trips++);
897
898         if (tz->trips.passive.flags.valid)
899                 tz->thermal_zone =
900                         thermal_zone_device_register("acpitz", trips, 0, tz,
901                                                 &acpi_thermal_zone_ops, NULL,
902                                                      tz->trips.passive.tsp*100,
903                                                      tz->polling_frequency*100);
904         else
905                 tz->thermal_zone =
906                         thermal_zone_device_register("acpitz", trips, 0, tz,
907                                                 &acpi_thermal_zone_ops, NULL,
908                                                 0, tz->polling_frequency*100);
909         if (IS_ERR(tz->thermal_zone))
910                 return -ENODEV;
911
912         result = sysfs_create_link(&tz->device->dev.kobj,
913                                    &tz->thermal_zone->device.kobj, "thermal_zone");
914         if (result)
915                 return result;
916
917         result = sysfs_create_link(&tz->thermal_zone->device.kobj,
918                                    &tz->device->dev.kobj, "device");
919         if (result)
920                 return result;
921
922         status = acpi_attach_data(tz->device->handle,
923                                   acpi_bus_private_data_handler,
924                                   tz->thermal_zone);
925         if (ACPI_FAILURE(status)) {
926                 pr_err(PREFIX "Error attaching device data\n");
927                 return -ENODEV;
928         }
929
930         tz->tz_enabled = 1;
931
932         dev_info(&tz->device->dev, "registered as thermal_zone%d\n",
933                  tz->thermal_zone->id);
934         return 0;
935 }
936
937 static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz)
938 {
939         sysfs_remove_link(&tz->device->dev.kobj, "thermal_zone");
940         sysfs_remove_link(&tz->thermal_zone->device.kobj, "device");
941         thermal_zone_device_unregister(tz->thermal_zone);
942         tz->thermal_zone = NULL;
943         acpi_detach_data(tz->device->handle, acpi_bus_private_data_handler);
944 }
945
946
947 /* --------------------------------------------------------------------------
948                                  Driver Interface
949    -------------------------------------------------------------------------- */
950
951 static void acpi_thermal_notify(struct acpi_device *device, u32 event)
952 {
953         struct acpi_thermal *tz = acpi_driver_data(device);
954
955
956         if (!tz)
957                 return;
958
959         switch (event) {
960         case ACPI_THERMAL_NOTIFY_TEMPERATURE:
961                 acpi_thermal_check(tz);
962                 break;
963         case ACPI_THERMAL_NOTIFY_THRESHOLDS:
964                 acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_THRESHOLDS);
965                 acpi_thermal_check(tz);
966                 acpi_bus_generate_netlink_event(device->pnp.device_class,
967                                                   dev_name(&device->dev), event, 0);
968                 break;
969         case ACPI_THERMAL_NOTIFY_DEVICES:
970                 acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES);
971                 acpi_thermal_check(tz);
972                 acpi_bus_generate_netlink_event(device->pnp.device_class,
973                                                   dev_name(&device->dev), event, 0);
974                 break;
975         default:
976                 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
977                                   "Unsupported event [0x%x]\n", event));
978                 break;
979         }
980 }
981
982 /*
983  * On some platforms, the AML code has dependency about
984  * the evaluating order of _TMP and _CRT/_HOT/_PSV/_ACx.
985  * 1. On HP Pavilion G4-1016tx, _TMP must be invoked after
986  *    /_CRT/_HOT/_PSV/_ACx, or else system will be power off.
987  * 2. On HP Compaq 6715b/6715s, the return value of _PSV is 0
988  *    if _TMP has never been evaluated.
989  *
990  * As this dependency is totally transparent to OS, evaluate
991  * all of them once, in the order of _CRT/_HOT/_PSV/_ACx,
992  * _TMP, before they are actually used.
993  */
994 static void acpi_thermal_aml_dependency_fix(struct acpi_thermal *tz)
995 {
996         acpi_handle handle = tz->device->handle;
997         unsigned long long value;
998         int i;
999
1000         acpi_evaluate_integer(handle, "_CRT", NULL, &value);
1001         acpi_evaluate_integer(handle, "_HOT", NULL, &value);
1002         acpi_evaluate_integer(handle, "_PSV", NULL, &value);
1003         for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
1004                 char name[5] = { '_', 'A', 'C', ('0' + i), '\0' };
1005                 acpi_status status;
1006
1007                 status = acpi_evaluate_integer(handle, name, NULL, &value);
1008                 if (status == AE_NOT_FOUND)
1009                         break;
1010         }
1011         acpi_evaluate_integer(handle, "_TMP", NULL, &value);
1012 }
1013
1014 static int acpi_thermal_get_info(struct acpi_thermal *tz)
1015 {
1016         int result = 0;
1017
1018
1019         if (!tz)
1020                 return -EINVAL;
1021
1022         acpi_thermal_aml_dependency_fix(tz);
1023
1024         /* Get trip points [_CRT, _PSV, etc.] (required) */
1025         result = acpi_thermal_get_trip_points(tz);
1026         if (result)
1027                 return result;
1028
1029         /* Get temperature [_TMP] (required) */
1030         result = acpi_thermal_get_temperature(tz);
1031         if (result)
1032                 return result;
1033
1034         /* Set the cooling mode [_SCP] to active cooling (default) */
1035         result = acpi_thermal_set_cooling_mode(tz, ACPI_THERMAL_MODE_ACTIVE);
1036         if (!result)
1037                 tz->flags.cooling_mode = 1;
1038
1039         /* Get default polling frequency [_TZP] (optional) */
1040         if (tzp)
1041                 tz->polling_frequency = tzp;
1042         else
1043                 acpi_thermal_get_polling_frequency(tz);
1044
1045         return 0;
1046 }
1047
1048 /*
1049  * The exact offset between Kelvin and degree Celsius is 273.15. However ACPI
1050  * handles temperature values with a single decimal place. As a consequence,
1051  * some implementations use an offset of 273.1 and others use an offset of
1052  * 273.2. Try to find out which one is being used, to present the most
1053  * accurate and visually appealing number.
1054  *
1055  * The heuristic below should work for all ACPI thermal zones which have a
1056  * critical trip point with a value being a multiple of 0.5 degree Celsius.
1057  */
1058 static void acpi_thermal_guess_offset(struct acpi_thermal *tz)
1059 {
1060         if (tz->trips.critical.flags.valid &&
1061             (tz->trips.critical.temperature % 5) == 1)
1062                 tz->kelvin_offset = 2731;
1063         else
1064                 tz->kelvin_offset = 2732;
1065 }
1066
1067 static int acpi_thermal_add(struct acpi_device *device)
1068 {
1069         int result = 0;
1070         struct acpi_thermal *tz = NULL;
1071
1072
1073         if (!device)
1074                 return -EINVAL;
1075
1076         tz = kzalloc(sizeof(struct acpi_thermal), GFP_KERNEL);
1077         if (!tz)
1078                 return -ENOMEM;
1079
1080         tz->device = device;
1081         strcpy(tz->name, device->pnp.bus_id);
1082         strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME);
1083         strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS);
1084         device->driver_data = tz;
1085
1086         result = acpi_thermal_get_info(tz);
1087         if (result)
1088                 goto free_memory;
1089
1090         acpi_thermal_guess_offset(tz);
1091
1092         result = acpi_thermal_register_thermal_zone(tz);
1093         if (result)
1094                 goto free_memory;
1095
1096         pr_info(PREFIX "%s [%s] (%ld C)\n", acpi_device_name(device),
1097                 acpi_device_bid(device), KELVIN_TO_CELSIUS(tz->temperature));
1098         goto end;
1099
1100 free_memory:
1101         kfree(tz);
1102 end:
1103         return result;
1104 }
1105
1106 static int acpi_thermal_remove(struct acpi_device *device)
1107 {
1108         struct acpi_thermal *tz = NULL;
1109
1110         if (!device || !acpi_driver_data(device))
1111                 return -EINVAL;
1112
1113         tz = acpi_driver_data(device);
1114
1115         acpi_thermal_unregister_thermal_zone(tz);
1116         kfree(tz);
1117         return 0;
1118 }
1119
1120 #ifdef CONFIG_PM_SLEEP
1121 static int acpi_thermal_resume(struct device *dev)
1122 {
1123         struct acpi_thermal *tz;
1124         int i, j, power_state, result;
1125
1126         if (!dev)
1127                 return -EINVAL;
1128
1129         tz = acpi_driver_data(to_acpi_device(dev));
1130         if (!tz)
1131                 return -EINVAL;
1132
1133         for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
1134                 if (!(&tz->trips.active[i]))
1135                         break;
1136                 if (!tz->trips.active[i].flags.valid)
1137                         break;
1138                 tz->trips.active[i].flags.enabled = 1;
1139                 for (j = 0; j < tz->trips.active[i].devices.count; j++) {
1140                         result = acpi_bus_update_power(
1141                                         tz->trips.active[i].devices.handles[j],
1142                                         &power_state);
1143                         if (result || (power_state != ACPI_STATE_D0)) {
1144                                 tz->trips.active[i].flags.enabled = 0;
1145                                 break;
1146                         }
1147                 }
1148                 tz->state.active |= tz->trips.active[i].flags.enabled;
1149         }
1150
1151         acpi_thermal_check(tz);
1152
1153         return AE_OK;
1154 }
1155 #endif
1156
1157 static int thermal_act(const struct dmi_system_id *d) {
1158
1159         if (act == 0) {
1160                 pr_notice(PREFIX "%s detected: "
1161                           "disabling all active thermal trip points\n", d->ident);
1162                 act = -1;
1163         }
1164         return 0;
1165 }
1166 static int thermal_nocrt(const struct dmi_system_id *d) {
1167
1168         pr_notice(PREFIX "%s detected: "
1169                   "disabling all critical thermal trip point actions.\n", d->ident);
1170         nocrt = 1;
1171         return 0;
1172 }
1173 static int thermal_tzp(const struct dmi_system_id *d) {
1174
1175         if (tzp == 0) {
1176                 pr_notice(PREFIX "%s detected: "
1177                           "enabling thermal zone polling\n", d->ident);
1178                 tzp = 300;      /* 300 dS = 30 Seconds */
1179         }
1180         return 0;
1181 }
1182 static int thermal_psv(const struct dmi_system_id *d) {
1183
1184         if (psv == 0) {
1185                 pr_notice(PREFIX "%s detected: "
1186                           "disabling all passive thermal trip points\n", d->ident);
1187                 psv = -1;
1188         }
1189         return 0;
1190 }
1191
1192 static struct dmi_system_id thermal_dmi_table[] __initdata = {
1193         /*
1194          * Award BIOS on this AOpen makes thermal control almost worthless.
1195          * http://bugzilla.kernel.org/show_bug.cgi?id=8842
1196          */
1197         {
1198          .callback = thermal_act,
1199          .ident = "AOpen i915GMm-HFS",
1200          .matches = {
1201                 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
1202                 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
1203                 },
1204         },
1205         {
1206          .callback = thermal_psv,
1207          .ident = "AOpen i915GMm-HFS",
1208          .matches = {
1209                 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
1210                 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
1211                 },
1212         },
1213         {
1214          .callback = thermal_tzp,
1215          .ident = "AOpen i915GMm-HFS",
1216          .matches = {
1217                 DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
1218                 DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
1219                 },
1220         },
1221         {
1222          .callback = thermal_nocrt,
1223          .ident = "Gigabyte GA-7ZX",
1224          .matches = {
1225                 DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."),
1226                 DMI_MATCH(DMI_BOARD_NAME, "7ZX"),
1227                 },
1228         },
1229         {}
1230 };
1231
1232 static int __init acpi_thermal_init(void)
1233 {
1234         int result = 0;
1235
1236         dmi_check_system(thermal_dmi_table);
1237
1238         if (off) {
1239                 pr_notice(PREFIX "thermal control disabled\n");
1240                 return -ENODEV;
1241         }
1242
1243         result = acpi_bus_register_driver(&acpi_thermal_driver);
1244         if (result < 0)
1245                 return -ENODEV;
1246
1247         return 0;
1248 }
1249
1250 static void __exit acpi_thermal_exit(void)
1251 {
1252
1253         acpi_bus_unregister_driver(&acpi_thermal_driver);
1254
1255         return;
1256 }
1257
1258 module_init(acpi_thermal_init);
1259 module_exit(acpi_thermal_exit);