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