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