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