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