xref: /linux/drivers/acpi/thermal.c (revision c0e297dc61f8d4453e07afbea1fa8d0e67cd4a34)
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 					 THERMAL_WEIGHT_DEFAULT);
805 			else
806 				result =
807 					thermal_zone_unbind_cooling_device
808 					(thermal, trip, cdev);
809 			if (result)
810 				goto failed;
811 		}
812 	}
813 
814 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
815 		if (!tz->trips.active[i].flags.valid)
816 			break;
817 		trip++;
818 		for (j = 0;
819 		    j < tz->trips.active[i].devices.count;
820 		    j++) {
821 			handle = tz->trips.active[i].devices.handles[j];
822 			status = acpi_bus_get_device(handle, &dev);
823 			if (ACPI_FAILURE(status) || dev != device)
824 				continue;
825 			if (bind)
826 				result = thermal_zone_bind_cooling_device
827 					(thermal, trip, cdev,
828 					 THERMAL_NO_LIMIT, THERMAL_NO_LIMIT,
829 					 THERMAL_WEIGHT_DEFAULT);
830 			else
831 				result = thermal_zone_unbind_cooling_device
832 					(thermal, trip, cdev);
833 			if (result)
834 				goto failed;
835 		}
836 	}
837 
838 	for (i = 0; i < tz->devices.count; i++) {
839 		handle = tz->devices.handles[i];
840 		status = acpi_bus_get_device(handle, &dev);
841 		if (ACPI_SUCCESS(status) && (dev == device)) {
842 			if (bind)
843 				result = thermal_zone_bind_cooling_device
844 						(thermal, THERMAL_TRIPS_NONE,
845 						 cdev, THERMAL_NO_LIMIT,
846 						 THERMAL_NO_LIMIT,
847 						 THERMAL_WEIGHT_DEFAULT);
848 			else
849 				result = thermal_zone_unbind_cooling_device
850 						(thermal, THERMAL_TRIPS_NONE,
851 						 cdev);
852 			if (result)
853 				goto failed;
854 		}
855 	}
856 
857 failed:
858 	return result;
859 }
860 
861 static int
862 acpi_thermal_bind_cooling_device(struct thermal_zone_device *thermal,
863 					struct thermal_cooling_device *cdev)
864 {
865 	return acpi_thermal_cooling_device_cb(thermal, cdev, true);
866 }
867 
868 static int
869 acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal,
870 					struct thermal_cooling_device *cdev)
871 {
872 	return acpi_thermal_cooling_device_cb(thermal, cdev, false);
873 }
874 
875 static struct thermal_zone_device_ops acpi_thermal_zone_ops = {
876 	.bind = acpi_thermal_bind_cooling_device,
877 	.unbind	= acpi_thermal_unbind_cooling_device,
878 	.get_temp = thermal_get_temp,
879 	.get_mode = thermal_get_mode,
880 	.set_mode = thermal_set_mode,
881 	.get_trip_type = thermal_get_trip_type,
882 	.get_trip_temp = thermal_get_trip_temp,
883 	.get_crit_temp = thermal_get_crit_temp,
884 	.get_trend = thermal_get_trend,
885 	.notify = thermal_notify,
886 };
887 
888 static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
889 {
890 	int trips = 0;
891 	int result;
892 	acpi_status status;
893 	int i;
894 
895 	if (tz->trips.critical.flags.valid)
896 		trips++;
897 
898 	if (tz->trips.hot.flags.valid)
899 		trips++;
900 
901 	if (tz->trips.passive.flags.valid)
902 		trips++;
903 
904 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
905 			tz->trips.active[i].flags.valid; i++, trips++);
906 
907 	if (tz->trips.passive.flags.valid)
908 		tz->thermal_zone =
909 			thermal_zone_device_register("acpitz", trips, 0, tz,
910 						&acpi_thermal_zone_ops, NULL,
911 						     tz->trips.passive.tsp*100,
912 						     tz->polling_frequency*100);
913 	else
914 		tz->thermal_zone =
915 			thermal_zone_device_register("acpitz", trips, 0, tz,
916 						&acpi_thermal_zone_ops, NULL,
917 						0, tz->polling_frequency*100);
918 	if (IS_ERR(tz->thermal_zone))
919 		return -ENODEV;
920 
921 	result = sysfs_create_link(&tz->device->dev.kobj,
922 				   &tz->thermal_zone->device.kobj, "thermal_zone");
923 	if (result)
924 		return result;
925 
926 	result = sysfs_create_link(&tz->thermal_zone->device.kobj,
927 				   &tz->device->dev.kobj, "device");
928 	if (result)
929 		return result;
930 
931 	status =  acpi_bus_attach_private_data(tz->device->handle,
932 					       tz->thermal_zone);
933 	if (ACPI_FAILURE(status))
934 		return -ENODEV;
935 
936 	tz->tz_enabled = 1;
937 
938 	dev_info(&tz->device->dev, "registered as thermal_zone%d\n",
939 		 tz->thermal_zone->id);
940 	return 0;
941 }
942 
943 static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz)
944 {
945 	sysfs_remove_link(&tz->device->dev.kobj, "thermal_zone");
946 	sysfs_remove_link(&tz->thermal_zone->device.kobj, "device");
947 	thermal_zone_device_unregister(tz->thermal_zone);
948 	tz->thermal_zone = NULL;
949 	acpi_bus_detach_private_data(tz->device->handle);
950 }
951 
952 
953 /* --------------------------------------------------------------------------
954                                  Driver Interface
955    -------------------------------------------------------------------------- */
956 
957 static void acpi_thermal_notify(struct acpi_device *device, u32 event)
958 {
959 	struct acpi_thermal *tz = acpi_driver_data(device);
960 
961 
962 	if (!tz)
963 		return;
964 
965 	switch (event) {
966 	case ACPI_THERMAL_NOTIFY_TEMPERATURE:
967 		acpi_thermal_check(tz);
968 		break;
969 	case ACPI_THERMAL_NOTIFY_THRESHOLDS:
970 		acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_THRESHOLDS);
971 		acpi_thermal_check(tz);
972 		acpi_bus_generate_netlink_event(device->pnp.device_class,
973 						  dev_name(&device->dev), event, 0);
974 		break;
975 	case ACPI_THERMAL_NOTIFY_DEVICES:
976 		acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES);
977 		acpi_thermal_check(tz);
978 		acpi_bus_generate_netlink_event(device->pnp.device_class,
979 						  dev_name(&device->dev), event, 0);
980 		break;
981 	default:
982 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
983 				  "Unsupported event [0x%x]\n", event));
984 		break;
985 	}
986 }
987 
988 /*
989  * On some platforms, the AML code has dependency about
990  * the evaluating order of _TMP and _CRT/_HOT/_PSV/_ACx.
991  * 1. On HP Pavilion G4-1016tx, _TMP must be invoked after
992  *    /_CRT/_HOT/_PSV/_ACx, or else system will be power off.
993  * 2. On HP Compaq 6715b/6715s, the return value of _PSV is 0
994  *    if _TMP has never been evaluated.
995  *
996  * As this dependency is totally transparent to OS, evaluate
997  * all of them once, in the order of _CRT/_HOT/_PSV/_ACx,
998  * _TMP, before they are actually used.
999  */
1000 static void acpi_thermal_aml_dependency_fix(struct acpi_thermal *tz)
1001 {
1002 	acpi_handle handle = tz->device->handle;
1003 	unsigned long long value;
1004 	int i;
1005 
1006 	acpi_evaluate_integer(handle, "_CRT", NULL, &value);
1007 	acpi_evaluate_integer(handle, "_HOT", NULL, &value);
1008 	acpi_evaluate_integer(handle, "_PSV", NULL, &value);
1009 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
1010 		char name[5] = { '_', 'A', 'C', ('0' + i), '\0' };
1011 		acpi_status status;
1012 
1013 		status = acpi_evaluate_integer(handle, name, NULL, &value);
1014 		if (status == AE_NOT_FOUND)
1015 			break;
1016 	}
1017 	acpi_evaluate_integer(handle, "_TMP", NULL, &value);
1018 }
1019 
1020 static int acpi_thermal_get_info(struct acpi_thermal *tz)
1021 {
1022 	int result = 0;
1023 
1024 
1025 	if (!tz)
1026 		return -EINVAL;
1027 
1028 	acpi_thermal_aml_dependency_fix(tz);
1029 
1030 	/* Get trip points [_CRT, _PSV, etc.] (required) */
1031 	result = acpi_thermal_get_trip_points(tz);
1032 	if (result)
1033 		return result;
1034 
1035 	/* Get temperature [_TMP] (required) */
1036 	result = acpi_thermal_get_temperature(tz);
1037 	if (result)
1038 		return result;
1039 
1040 	/* Set the cooling mode [_SCP] to active cooling (default) */
1041 	result = acpi_thermal_set_cooling_mode(tz, ACPI_THERMAL_MODE_ACTIVE);
1042 	if (!result)
1043 		tz->flags.cooling_mode = 1;
1044 
1045 	/* Get default polling frequency [_TZP] (optional) */
1046 	if (tzp)
1047 		tz->polling_frequency = tzp;
1048 	else
1049 		acpi_thermal_get_polling_frequency(tz);
1050 
1051 	return 0;
1052 }
1053 
1054 /*
1055  * The exact offset between Kelvin and degree Celsius is 273.15. However ACPI
1056  * handles temperature values with a single decimal place. As a consequence,
1057  * some implementations use an offset of 273.1 and others use an offset of
1058  * 273.2. Try to find out which one is being used, to present the most
1059  * accurate and visually appealing number.
1060  *
1061  * The heuristic below should work for all ACPI thermal zones which have a
1062  * critical trip point with a value being a multiple of 0.5 degree Celsius.
1063  */
1064 static void acpi_thermal_guess_offset(struct acpi_thermal *tz)
1065 {
1066 	if (tz->trips.critical.flags.valid &&
1067 	    (tz->trips.critical.temperature % 5) == 1)
1068 		tz->kelvin_offset = 2731;
1069 	else
1070 		tz->kelvin_offset = 2732;
1071 }
1072 
1073 static void acpi_thermal_check_fn(struct work_struct *work)
1074 {
1075 	struct acpi_thermal *tz = container_of(work, struct acpi_thermal,
1076 					       thermal_check_work);
1077 	acpi_thermal_check(tz);
1078 }
1079 
1080 static int acpi_thermal_add(struct acpi_device *device)
1081 {
1082 	int result = 0;
1083 	struct acpi_thermal *tz = NULL;
1084 
1085 
1086 	if (!device)
1087 		return -EINVAL;
1088 
1089 	tz = kzalloc(sizeof(struct acpi_thermal), GFP_KERNEL);
1090 	if (!tz)
1091 		return -ENOMEM;
1092 
1093 	tz->device = device;
1094 	strcpy(tz->name, device->pnp.bus_id);
1095 	strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME);
1096 	strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS);
1097 	device->driver_data = tz;
1098 
1099 	result = acpi_thermal_get_info(tz);
1100 	if (result)
1101 		goto free_memory;
1102 
1103 	acpi_thermal_guess_offset(tz);
1104 
1105 	result = acpi_thermal_register_thermal_zone(tz);
1106 	if (result)
1107 		goto free_memory;
1108 
1109 	INIT_WORK(&tz->thermal_check_work, acpi_thermal_check_fn);
1110 
1111 	pr_info(PREFIX "%s [%s] (%ld C)\n", acpi_device_name(device),
1112 		acpi_device_bid(device), KELVIN_TO_CELSIUS(tz->temperature));
1113 	goto end;
1114 
1115 free_memory:
1116 	kfree(tz);
1117 end:
1118 	return result;
1119 }
1120 
1121 static int acpi_thermal_remove(struct acpi_device *device)
1122 {
1123 	struct acpi_thermal *tz = NULL;
1124 
1125 	if (!device || !acpi_driver_data(device))
1126 		return -EINVAL;
1127 
1128 	flush_workqueue(acpi_thermal_pm_queue);
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_suspend(struct device *dev)
1138 {
1139 	/* Make sure the previously queued thermal check work has been done */
1140 	flush_workqueue(acpi_thermal_pm_queue);
1141 	return 0;
1142 }
1143 
1144 static int acpi_thermal_resume(struct device *dev)
1145 {
1146 	struct acpi_thermal *tz;
1147 	int i, j, power_state, result;
1148 
1149 	if (!dev)
1150 		return -EINVAL;
1151 
1152 	tz = acpi_driver_data(to_acpi_device(dev));
1153 	if (!tz)
1154 		return -EINVAL;
1155 
1156 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
1157 		if (!(&tz->trips.active[i]))
1158 			break;
1159 		if (!tz->trips.active[i].flags.valid)
1160 			break;
1161 		tz->trips.active[i].flags.enabled = 1;
1162 		for (j = 0; j < tz->trips.active[i].devices.count; j++) {
1163 			result = acpi_bus_update_power(
1164 					tz->trips.active[i].devices.handles[j],
1165 					&power_state);
1166 			if (result || (power_state != ACPI_STATE_D0)) {
1167 				tz->trips.active[i].flags.enabled = 0;
1168 				break;
1169 			}
1170 		}
1171 		tz->state.active |= tz->trips.active[i].flags.enabled;
1172 	}
1173 
1174 	queue_work(acpi_thermal_pm_queue, &tz->thermal_check_work);
1175 
1176 	return AE_OK;
1177 }
1178 #endif
1179 
1180 static int thermal_act(const struct dmi_system_id *d) {
1181 
1182 	if (act == 0) {
1183 		pr_notice(PREFIX "%s detected: "
1184 			  "disabling all active thermal trip points\n", d->ident);
1185 		act = -1;
1186 	}
1187 	return 0;
1188 }
1189 static int thermal_nocrt(const struct dmi_system_id *d) {
1190 
1191 	pr_notice(PREFIX "%s detected: "
1192 		  "disabling all critical thermal trip point actions.\n", d->ident);
1193 	nocrt = 1;
1194 	return 0;
1195 }
1196 static int thermal_tzp(const struct dmi_system_id *d) {
1197 
1198 	if (tzp == 0) {
1199 		pr_notice(PREFIX "%s detected: "
1200 			  "enabling thermal zone polling\n", d->ident);
1201 		tzp = 300;	/* 300 dS = 30 Seconds */
1202 	}
1203 	return 0;
1204 }
1205 static int thermal_psv(const struct dmi_system_id *d) {
1206 
1207 	if (psv == 0) {
1208 		pr_notice(PREFIX "%s detected: "
1209 			  "disabling all passive thermal trip points\n", d->ident);
1210 		psv = -1;
1211 	}
1212 	return 0;
1213 }
1214 
1215 static struct dmi_system_id thermal_dmi_table[] __initdata = {
1216 	/*
1217 	 * Award BIOS on this AOpen makes thermal control almost worthless.
1218 	 * http://bugzilla.kernel.org/show_bug.cgi?id=8842
1219 	 */
1220 	{
1221 	 .callback = thermal_act,
1222 	 .ident = "AOpen i915GMm-HFS",
1223 	 .matches = {
1224 		DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
1225 		DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
1226 		},
1227 	},
1228 	{
1229 	 .callback = thermal_psv,
1230 	 .ident = "AOpen i915GMm-HFS",
1231 	 .matches = {
1232 		DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
1233 		DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
1234 		},
1235 	},
1236 	{
1237 	 .callback = thermal_tzp,
1238 	 .ident = "AOpen i915GMm-HFS",
1239 	 .matches = {
1240 		DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
1241 		DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
1242 		},
1243 	},
1244 	{
1245 	 .callback = thermal_nocrt,
1246 	 .ident = "Gigabyte GA-7ZX",
1247 	 .matches = {
1248 		DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."),
1249 		DMI_MATCH(DMI_BOARD_NAME, "7ZX"),
1250 		},
1251 	},
1252 	{}
1253 };
1254 
1255 static int __init acpi_thermal_init(void)
1256 {
1257 	int result = 0;
1258 
1259 	dmi_check_system(thermal_dmi_table);
1260 
1261 	if (off) {
1262 		pr_notice(PREFIX "thermal control disabled\n");
1263 		return -ENODEV;
1264 	}
1265 
1266 	acpi_thermal_pm_queue = create_workqueue("acpi_thermal_pm");
1267 	if (!acpi_thermal_pm_queue)
1268 		return -ENODEV;
1269 
1270 	result = acpi_bus_register_driver(&acpi_thermal_driver);
1271 	if (result < 0) {
1272 		destroy_workqueue(acpi_thermal_pm_queue);
1273 		return -ENODEV;
1274 	}
1275 
1276 	return 0;
1277 }
1278 
1279 static void __exit acpi_thermal_exit(void)
1280 {
1281 	acpi_bus_unregister_driver(&acpi_thermal_driver);
1282 	destroy_workqueue(acpi_thermal_pm_queue);
1283 
1284 	return;
1285 }
1286 
1287 module_init(acpi_thermal_init);
1288 module_exit(acpi_thermal_exit);
1289