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