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