xref: /linux/drivers/acpi/thermal.c (revision d39d0ed196aa1685bb24771e92f78633c66ac9cb)
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 
41 #ifdef CONFIG_ACPI_PROCFS
42 #include <linux/proc_fs.h>
43 #include <linux/seq_file.h>
44 #endif
45 
46 #include <linux/jiffies.h>
47 #include <linux/kmod.h>
48 #include <linux/reboot.h>
49 #include <linux/device.h>
50 #include <asm/uaccess.h>
51 #include <linux/thermal.h>
52 #include <acpi/acpi_bus.h>
53 #include <acpi/acpi_drivers.h>
54 
55 #define PREFIX "ACPI: "
56 
57 #define ACPI_THERMAL_CLASS		"thermal_zone"
58 #define ACPI_THERMAL_DEVICE_NAME	"Thermal Zone"
59 #define ACPI_THERMAL_FILE_STATE		"state"
60 #define ACPI_THERMAL_FILE_TEMPERATURE	"temperature"
61 #define ACPI_THERMAL_FILE_TRIP_POINTS	"trip_points"
62 #define ACPI_THERMAL_FILE_COOLING_MODE	"cooling_mode"
63 #define ACPI_THERMAL_FILE_POLLING_FREQ	"polling_frequency"
64 #define ACPI_THERMAL_NOTIFY_TEMPERATURE	0x80
65 #define ACPI_THERMAL_NOTIFY_THRESHOLDS	0x81
66 #define ACPI_THERMAL_NOTIFY_DEVICES	0x82
67 #define ACPI_THERMAL_NOTIFY_CRITICAL	0xF0
68 #define ACPI_THERMAL_NOTIFY_HOT		0xF1
69 #define ACPI_THERMAL_MODE_ACTIVE	0x00
70 
71 #define ACPI_THERMAL_MAX_ACTIVE	10
72 #define ACPI_THERMAL_MAX_LIMIT_STR_LEN 65
73 
74 #define _COMPONENT		ACPI_THERMAL_COMPONENT
75 ACPI_MODULE_NAME("thermal");
76 
77 MODULE_AUTHOR("Paul Diefenbaugh");
78 MODULE_DESCRIPTION("ACPI Thermal Zone Driver");
79 MODULE_LICENSE("GPL");
80 
81 static int act;
82 module_param(act, int, 0644);
83 MODULE_PARM_DESC(act, "Disable or override all lowest active trip points.");
84 
85 static int crt;
86 module_param(crt, int, 0644);
87 MODULE_PARM_DESC(crt, "Disable or lower all critical trip points.");
88 
89 static int tzp;
90 module_param(tzp, int, 0444);
91 MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.");
92 
93 static int nocrt;
94 module_param(nocrt, int, 0);
95 MODULE_PARM_DESC(nocrt, "Set to take no action upon ACPI thermal zone critical trips points.");
96 
97 static int off;
98 module_param(off, int, 0);
99 MODULE_PARM_DESC(off, "Set to disable ACPI thermal support.");
100 
101 static int psv;
102 module_param(psv, int, 0644);
103 MODULE_PARM_DESC(psv, "Disable or override all passive trip points.");
104 
105 static int acpi_thermal_add(struct acpi_device *device);
106 static int acpi_thermal_remove(struct acpi_device *device, int type);
107 static int acpi_thermal_resume(struct acpi_device *device);
108 static void acpi_thermal_notify(struct acpi_device *device, u32 event);
109 
110 static const struct acpi_device_id  thermal_device_ids[] = {
111 	{ACPI_THERMAL_HID, 0},
112 	{"", 0},
113 };
114 MODULE_DEVICE_TABLE(acpi, thermal_device_ids);
115 
116 static struct acpi_driver acpi_thermal_driver = {
117 	.name = "thermal",
118 	.class = ACPI_THERMAL_CLASS,
119 	.ids = thermal_device_ids,
120 	.ops = {
121 		.add = acpi_thermal_add,
122 		.remove = acpi_thermal_remove,
123 		.resume = acpi_thermal_resume,
124 		.notify = acpi_thermal_notify,
125 		},
126 };
127 
128 struct acpi_thermal_state {
129 	u8 critical:1;
130 	u8 hot:1;
131 	u8 passive:1;
132 	u8 active:1;
133 	u8 reserved:4;
134 	int active_index;
135 };
136 
137 struct acpi_thermal_state_flags {
138 	u8 valid:1;
139 	u8 enabled:1;
140 	u8 reserved:6;
141 };
142 
143 struct acpi_thermal_critical {
144 	struct acpi_thermal_state_flags flags;
145 	unsigned long temperature;
146 };
147 
148 struct acpi_thermal_hot {
149 	struct acpi_thermal_state_flags flags;
150 	unsigned long temperature;
151 };
152 
153 struct acpi_thermal_passive {
154 	struct acpi_thermal_state_flags flags;
155 	unsigned long temperature;
156 	unsigned long tc1;
157 	unsigned long tc2;
158 	unsigned long tsp;
159 	struct acpi_handle_list devices;
160 };
161 
162 struct acpi_thermal_active {
163 	struct acpi_thermal_state_flags flags;
164 	unsigned long temperature;
165 	struct acpi_handle_list devices;
166 };
167 
168 struct acpi_thermal_trips {
169 	struct acpi_thermal_critical critical;
170 	struct acpi_thermal_hot hot;
171 	struct acpi_thermal_passive passive;
172 	struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE];
173 };
174 
175 struct acpi_thermal_flags {
176 	u8 cooling_mode:1;	/* _SCP */
177 	u8 devices:1;		/* _TZD */
178 	u8 reserved:6;
179 };
180 
181 struct acpi_thermal {
182 	struct acpi_device * device;
183 	acpi_bus_id name;
184 	unsigned long temperature;
185 	unsigned long last_temperature;
186 	unsigned long polling_frequency;
187 	volatile u8 zombie;
188 	struct acpi_thermal_flags flags;
189 	struct acpi_thermal_state state;
190 	struct acpi_thermal_trips trips;
191 	struct acpi_handle_list devices;
192 	struct thermal_zone_device *thermal_zone;
193 	int tz_enabled;
194 	int kelvin_offset;
195 	struct mutex lock;
196 };
197 
198 #ifdef CONFIG_ACPI_PROCFS
199 static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file);
200 static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file);
201 static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file);
202 static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file);
203 static ssize_t acpi_thermal_write_cooling_mode(struct file *,
204 					       const char __user *, size_t,
205 					       loff_t *);
206 static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file);
207 static ssize_t acpi_thermal_write_polling(struct file *, const char __user *,
208 					  size_t, loff_t *);
209 
210 static const struct file_operations acpi_thermal_state_fops = {
211 	.owner = THIS_MODULE,
212 	.open = acpi_thermal_state_open_fs,
213 	.read = seq_read,
214 	.llseek = seq_lseek,
215 	.release = single_release,
216 };
217 
218 static const struct file_operations acpi_thermal_temp_fops = {
219 	.owner = THIS_MODULE,
220 	.open = acpi_thermal_temp_open_fs,
221 	.read = seq_read,
222 	.llseek = seq_lseek,
223 	.release = single_release,
224 };
225 
226 static const struct file_operations acpi_thermal_trip_fops = {
227 	.owner = THIS_MODULE,
228 	.open = acpi_thermal_trip_open_fs,
229 	.read = seq_read,
230 	.llseek = seq_lseek,
231 	.release = single_release,
232 };
233 
234 static const struct file_operations acpi_thermal_cooling_fops = {
235 	.owner = THIS_MODULE,
236 	.open = acpi_thermal_cooling_open_fs,
237 	.read = seq_read,
238 	.write = acpi_thermal_write_cooling_mode,
239 	.llseek = seq_lseek,
240 	.release = single_release,
241 };
242 
243 static const struct file_operations acpi_thermal_polling_fops = {
244 	.owner = THIS_MODULE,
245 	.open = acpi_thermal_polling_open_fs,
246 	.read = seq_read,
247 	.write = acpi_thermal_write_polling,
248 	.llseek = seq_lseek,
249 	.release = single_release,
250 };
251 #endif /* CONFIG_ACPI_PROCFS*/
252 
253 /* --------------------------------------------------------------------------
254                              Thermal Zone Management
255    -------------------------------------------------------------------------- */
256 
257 static int acpi_thermal_get_temperature(struct acpi_thermal *tz)
258 {
259 	acpi_status status = AE_OK;
260 	unsigned long long tmp;
261 
262 	if (!tz)
263 		return -EINVAL;
264 
265 	tz->last_temperature = tz->temperature;
266 
267 	status = acpi_evaluate_integer(tz->device->handle, "_TMP", NULL, &tmp);
268 	if (ACPI_FAILURE(status))
269 		return -ENODEV;
270 
271 	tz->temperature = tmp;
272 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Temperature is %lu dK\n",
273 			  tz->temperature));
274 
275 	return 0;
276 }
277 
278 static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz)
279 {
280 	acpi_status status = AE_OK;
281 	unsigned long long tmp;
282 
283 	if (!tz)
284 		return -EINVAL;
285 
286 	status = acpi_evaluate_integer(tz->device->handle, "_TZP", NULL, &tmp);
287 	if (ACPI_FAILURE(status))
288 		return -ENODEV;
289 
290 	tz->polling_frequency = tmp;
291 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Polling frequency is %lu dS\n",
292 			  tz->polling_frequency));
293 
294 	return 0;
295 }
296 
297 static int acpi_thermal_set_cooling_mode(struct acpi_thermal *tz, int mode)
298 {
299 	acpi_status status = AE_OK;
300 	union acpi_object arg0 = { ACPI_TYPE_INTEGER };
301 	struct acpi_object_list arg_list = { 1, &arg0 };
302 	acpi_handle handle = NULL;
303 
304 
305 	if (!tz)
306 		return -EINVAL;
307 
308 	status = acpi_get_handle(tz->device->handle, "_SCP", &handle);
309 	if (ACPI_FAILURE(status)) {
310 		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "_SCP not present\n"));
311 		return -ENODEV;
312 	}
313 
314 	arg0.integer.value = mode;
315 
316 	status = acpi_evaluate_object(handle, NULL, &arg_list, NULL);
317 	if (ACPI_FAILURE(status))
318 		return -ENODEV;
319 
320 	return 0;
321 }
322 
323 #define ACPI_TRIPS_CRITICAL	0x01
324 #define ACPI_TRIPS_HOT		0x02
325 #define ACPI_TRIPS_PASSIVE	0x04
326 #define ACPI_TRIPS_ACTIVE	0x08
327 #define ACPI_TRIPS_DEVICES	0x10
328 
329 #define ACPI_TRIPS_REFRESH_THRESHOLDS	(ACPI_TRIPS_PASSIVE | ACPI_TRIPS_ACTIVE)
330 #define ACPI_TRIPS_REFRESH_DEVICES	ACPI_TRIPS_DEVICES
331 
332 #define ACPI_TRIPS_INIT      (ACPI_TRIPS_CRITICAL | ACPI_TRIPS_HOT |	\
333 			      ACPI_TRIPS_PASSIVE | ACPI_TRIPS_ACTIVE |	\
334 			      ACPI_TRIPS_DEVICES)
335 
336 /*
337  * This exception is thrown out in two cases:
338  * 1.An invalid trip point becomes invalid or a valid trip point becomes invalid
339  *   when re-evaluating the AML code.
340  * 2.TODO: Devices listed in _PSL, _ALx, _TZD may change.
341  *   We need to re-bind the cooling devices of a thermal zone when this occurs.
342  */
343 #define ACPI_THERMAL_TRIPS_EXCEPTION(flags, str)	\
344 do {	\
345 	if (flags != ACPI_TRIPS_INIT)	\
346 		ACPI_EXCEPTION((AE_INFO, AE_ERROR,	\
347 		"ACPI thermal trip point %s changed\n"	\
348 		"Please send acpidump to linux-acpi@vger.kernel.org\n", str)); \
349 } while (0)
350 
351 static int acpi_thermal_trips_update(struct acpi_thermal *tz, int flag)
352 {
353 	acpi_status status = AE_OK;
354 	unsigned long long tmp;
355 	struct acpi_handle_list devices;
356 	int valid = 0;
357 	int i;
358 
359 	/* Critical Shutdown */
360 	if (flag & ACPI_TRIPS_CRITICAL) {
361 		status = acpi_evaluate_integer(tz->device->handle,
362 				"_CRT", NULL, &tmp);
363 		tz->trips.critical.temperature = tmp;
364 		/*
365 		 * Treat freezing temperatures as invalid as well; some
366 		 * BIOSes return really low values and cause reboots at startup.
367 		 * Below zero (Celsius) values clearly aren't right for sure..
368 		 * ... so lets discard those as invalid.
369 		 */
370 		if (ACPI_FAILURE(status)) {
371 			tz->trips.critical.flags.valid = 0;
372 			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
373 					  "No critical threshold\n"));
374 		} else if (tmp <= 2732) {
375 			printk(KERN_WARNING FW_BUG "Invalid critical threshold "
376 			       "(%llu)\n", tmp);
377 			tz->trips.critical.flags.valid = 0;
378 		} else {
379 			tz->trips.critical.flags.valid = 1;
380 			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
381 					  "Found critical threshold [%lu]\n",
382 					  tz->trips.critical.temperature));
383 		}
384 		if (tz->trips.critical.flags.valid == 1) {
385 			if (crt == -1) {
386 				tz->trips.critical.flags.valid = 0;
387 			} else if (crt > 0) {
388 				unsigned long crt_k = CELSIUS_TO_KELVIN(crt);
389 				/*
390 				 * Allow override critical threshold
391 				 */
392 				if (crt_k > tz->trips.critical.temperature)
393 					printk(KERN_WARNING PREFIX
394 						"Critical threshold %d C\n", crt);
395 				tz->trips.critical.temperature = crt_k;
396 			}
397 		}
398 	}
399 
400 	/* Critical Sleep (optional) */
401 	if (flag & ACPI_TRIPS_HOT) {
402 		status = acpi_evaluate_integer(tz->device->handle,
403 				"_HOT", NULL, &tmp);
404 		if (ACPI_FAILURE(status)) {
405 			tz->trips.hot.flags.valid = 0;
406 			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
407 					"No hot threshold\n"));
408 		} else {
409 			tz->trips.hot.temperature = tmp;
410 			tz->trips.hot.flags.valid = 1;
411 			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
412 					"Found hot threshold [%lu]\n",
413 					tz->trips.critical.temperature));
414 		}
415 	}
416 
417 	/* Passive (optional) */
418 	if (((flag & ACPI_TRIPS_PASSIVE) && tz->trips.passive.flags.valid) ||
419 		(flag == ACPI_TRIPS_INIT)) {
420 		valid = tz->trips.passive.flags.valid;
421 		if (psv == -1) {
422 			status = AE_SUPPORT;
423 		} else if (psv > 0) {
424 			tmp = CELSIUS_TO_KELVIN(psv);
425 			status = AE_OK;
426 		} else {
427 			status = acpi_evaluate_integer(tz->device->handle,
428 				"_PSV", NULL, &tmp);
429 		}
430 
431 		if (ACPI_FAILURE(status))
432 			tz->trips.passive.flags.valid = 0;
433 		else {
434 			tz->trips.passive.temperature = tmp;
435 			tz->trips.passive.flags.valid = 1;
436 			if (flag == ACPI_TRIPS_INIT) {
437 				status = acpi_evaluate_integer(
438 						tz->device->handle, "_TC1",
439 						NULL, &tmp);
440 				if (ACPI_FAILURE(status))
441 					tz->trips.passive.flags.valid = 0;
442 				else
443 					tz->trips.passive.tc1 = tmp;
444 				status = acpi_evaluate_integer(
445 						tz->device->handle, "_TC2",
446 						NULL, &tmp);
447 				if (ACPI_FAILURE(status))
448 					tz->trips.passive.flags.valid = 0;
449 				else
450 					tz->trips.passive.tc2 = tmp;
451 				status = acpi_evaluate_integer(
452 						tz->device->handle, "_TSP",
453 						NULL, &tmp);
454 				if (ACPI_FAILURE(status))
455 					tz->trips.passive.flags.valid = 0;
456 				else
457 					tz->trips.passive.tsp = tmp;
458 			}
459 		}
460 	}
461 	if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.passive.flags.valid) {
462 		memset(&devices, 0, sizeof(struct acpi_handle_list));
463 		status = acpi_evaluate_reference(tz->device->handle, "_PSL",
464 							NULL, &devices);
465 		if (ACPI_FAILURE(status)) {
466 			printk(KERN_WARNING PREFIX
467 				"Invalid passive threshold\n");
468 			tz->trips.passive.flags.valid = 0;
469 		}
470 		else
471 			tz->trips.passive.flags.valid = 1;
472 
473 		if (memcmp(&tz->trips.passive.devices, &devices,
474 				sizeof(struct acpi_handle_list))) {
475 			memcpy(&tz->trips.passive.devices, &devices,
476 				sizeof(struct acpi_handle_list));
477 			ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device");
478 		}
479 	}
480 	if ((flag & ACPI_TRIPS_PASSIVE) || (flag & ACPI_TRIPS_DEVICES)) {
481 		if (valid != tz->trips.passive.flags.valid)
482 				ACPI_THERMAL_TRIPS_EXCEPTION(flag, "state");
483 	}
484 
485 	/* Active (optional) */
486 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
487 		char name[5] = { '_', 'A', 'C', ('0' + i), '\0' };
488 		valid = tz->trips.active[i].flags.valid;
489 
490 		if (act == -1)
491 			break; /* disable all active trip points */
492 
493 		if ((flag == ACPI_TRIPS_INIT) || ((flag & ACPI_TRIPS_ACTIVE) &&
494 			tz->trips.active[i].flags.valid)) {
495 			status = acpi_evaluate_integer(tz->device->handle,
496 							name, NULL, &tmp);
497 			if (ACPI_FAILURE(status)) {
498 				tz->trips.active[i].flags.valid = 0;
499 				if (i == 0)
500 					break;
501 				if (act <= 0)
502 					break;
503 				if (i == 1)
504 					tz->trips.active[0].temperature =
505 						CELSIUS_TO_KELVIN(act);
506 				else
507 					/*
508 					 * Don't allow override higher than
509 					 * the next higher trip point
510 					 */
511 					tz->trips.active[i - 1].temperature =
512 						(tz->trips.active[i - 2].temperature <
513 						CELSIUS_TO_KELVIN(act) ?
514 						tz->trips.active[i - 2].temperature :
515 						CELSIUS_TO_KELVIN(act));
516 				break;
517 			} else {
518 				tz->trips.active[i].temperature = tmp;
519 				tz->trips.active[i].flags.valid = 1;
520 			}
521 		}
522 
523 		name[2] = 'L';
524 		if ((flag & ACPI_TRIPS_DEVICES) && tz->trips.active[i].flags.valid ) {
525 			memset(&devices, 0, sizeof(struct acpi_handle_list));
526 			status = acpi_evaluate_reference(tz->device->handle,
527 						name, NULL, &devices);
528 			if (ACPI_FAILURE(status)) {
529 				printk(KERN_WARNING PREFIX
530 					"Invalid active%d threshold\n", i);
531 				tz->trips.active[i].flags.valid = 0;
532 			}
533 			else
534 				tz->trips.active[i].flags.valid = 1;
535 
536 			if (memcmp(&tz->trips.active[i].devices, &devices,
537 					sizeof(struct acpi_handle_list))) {
538 				memcpy(&tz->trips.active[i].devices, &devices,
539 					sizeof(struct acpi_handle_list));
540 				ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device");
541 			}
542 		}
543 		if ((flag & ACPI_TRIPS_ACTIVE) || (flag & ACPI_TRIPS_DEVICES))
544 			if (valid != tz->trips.active[i].flags.valid)
545 				ACPI_THERMAL_TRIPS_EXCEPTION(flag, "state");
546 
547 		if (!tz->trips.active[i].flags.valid)
548 			break;
549 	}
550 
551 	if (flag & ACPI_TRIPS_DEVICES) {
552 		memset(&devices, 0, sizeof(struct acpi_handle_list));
553 		status = acpi_evaluate_reference(tz->device->handle, "_TZD",
554 						NULL, &devices);
555 		if (memcmp(&tz->devices, &devices,
556 				sizeof(struct acpi_handle_list))) {
557 			memcpy(&tz->devices, &devices,
558 				sizeof(struct acpi_handle_list));
559 			ACPI_THERMAL_TRIPS_EXCEPTION(flag, "device");
560 		}
561 	}
562 
563 	return 0;
564 }
565 
566 static int acpi_thermal_get_trip_points(struct acpi_thermal *tz)
567 {
568 	int i, valid, ret = acpi_thermal_trips_update(tz, ACPI_TRIPS_INIT);
569 
570 	if (ret)
571 		return ret;
572 
573 	valid = tz->trips.critical.flags.valid |
574 		tz->trips.hot.flags.valid |
575 		tz->trips.passive.flags.valid;
576 
577 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++)
578 		valid |= tz->trips.active[i].flags.valid;
579 
580 	if (!valid) {
581 		printk(KERN_WARNING FW_BUG "No valid trip found\n");
582 		return -ENODEV;
583 	}
584 	return 0;
585 }
586 
587 static void acpi_thermal_check(void *data)
588 {
589 	struct acpi_thermal *tz = data;
590 
591 	thermal_zone_device_update(tz->thermal_zone);
592 }
593 
594 /* sys I/F for generic thermal sysfs support */
595 #define KELVIN_TO_MILLICELSIUS(t, off) (((t) - (off)) * 100)
596 
597 static int thermal_get_temp(struct thermal_zone_device *thermal,
598 			    unsigned long *temp)
599 {
600 	struct acpi_thermal *tz = thermal->devdata;
601 	int result;
602 
603 	if (!tz)
604 		return -EINVAL;
605 
606 	result = acpi_thermal_get_temperature(tz);
607 	if (result)
608 		return result;
609 
610 	*temp = KELVIN_TO_MILLICELSIUS(tz->temperature, tz->kelvin_offset);
611 	return 0;
612 }
613 
614 static const char enabled[] = "kernel";
615 static const char disabled[] = "user";
616 static int thermal_get_mode(struct thermal_zone_device *thermal,
617 				enum thermal_device_mode *mode)
618 {
619 	struct acpi_thermal *tz = thermal->devdata;
620 
621 	if (!tz)
622 		return -EINVAL;
623 
624 	*mode = tz->tz_enabled ? THERMAL_DEVICE_ENABLED :
625 		THERMAL_DEVICE_DISABLED;
626 
627 	return 0;
628 }
629 
630 static int thermal_set_mode(struct thermal_zone_device *thermal,
631 				enum thermal_device_mode mode)
632 {
633 	struct acpi_thermal *tz = thermal->devdata;
634 	int enable;
635 
636 	if (!tz)
637 		return -EINVAL;
638 
639 	/*
640 	 * enable/disable thermal management from ACPI thermal driver
641 	 */
642 	if (mode == THERMAL_DEVICE_ENABLED)
643 		enable = 1;
644 	else if (mode == THERMAL_DEVICE_DISABLED)
645 		enable = 0;
646 	else
647 		return -EINVAL;
648 
649 	if (enable != tz->tz_enabled) {
650 		tz->tz_enabled = enable;
651 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
652 			"%s ACPI thermal control\n",
653 			tz->tz_enabled ? enabled : disabled));
654 		acpi_thermal_check(tz);
655 	}
656 	return 0;
657 }
658 
659 static int thermal_get_trip_type(struct thermal_zone_device *thermal,
660 				 int trip, enum thermal_trip_type *type)
661 {
662 	struct acpi_thermal *tz = thermal->devdata;
663 	int i;
664 
665 	if (!tz || trip < 0)
666 		return -EINVAL;
667 
668 	if (tz->trips.critical.flags.valid) {
669 		if (!trip) {
670 			*type = THERMAL_TRIP_CRITICAL;
671 			return 0;
672 		}
673 		trip--;
674 	}
675 
676 	if (tz->trips.hot.flags.valid) {
677 		if (!trip) {
678 			*type = THERMAL_TRIP_HOT;
679 			return 0;
680 		}
681 		trip--;
682 	}
683 
684 	if (tz->trips.passive.flags.valid) {
685 		if (!trip) {
686 			*type = THERMAL_TRIP_PASSIVE;
687 			return 0;
688 		}
689 		trip--;
690 	}
691 
692 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
693 		tz->trips.active[i].flags.valid; i++) {
694 		if (!trip) {
695 			*type = THERMAL_TRIP_ACTIVE;
696 			return 0;
697 		}
698 		trip--;
699 	}
700 
701 	return -EINVAL;
702 }
703 
704 static int thermal_get_trip_temp(struct thermal_zone_device *thermal,
705 				 int trip, unsigned long *temp)
706 {
707 	struct acpi_thermal *tz = thermal->devdata;
708 	int i;
709 
710 	if (!tz || trip < 0)
711 		return -EINVAL;
712 
713 	if (tz->trips.critical.flags.valid) {
714 		if (!trip) {
715 			*temp = KELVIN_TO_MILLICELSIUS(
716 				tz->trips.critical.temperature,
717 				tz->kelvin_offset);
718 			return 0;
719 		}
720 		trip--;
721 	}
722 
723 	if (tz->trips.hot.flags.valid) {
724 		if (!trip) {
725 			*temp = KELVIN_TO_MILLICELSIUS(
726 				tz->trips.hot.temperature,
727 				tz->kelvin_offset);
728 			return 0;
729 		}
730 		trip--;
731 	}
732 
733 	if (tz->trips.passive.flags.valid) {
734 		if (!trip) {
735 			*temp = KELVIN_TO_MILLICELSIUS(
736 				tz->trips.passive.temperature,
737 				tz->kelvin_offset);
738 			return 0;
739 		}
740 		trip--;
741 	}
742 
743 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE &&
744 		tz->trips.active[i].flags.valid; i++) {
745 		if (!trip) {
746 			*temp = KELVIN_TO_MILLICELSIUS(
747 				tz->trips.active[i].temperature,
748 				tz->kelvin_offset);
749 			return 0;
750 		}
751 		trip--;
752 	}
753 
754 	return -EINVAL;
755 }
756 
757 static int thermal_get_crit_temp(struct thermal_zone_device *thermal,
758 				unsigned long *temperature) {
759 	struct acpi_thermal *tz = thermal->devdata;
760 
761 	if (tz->trips.critical.flags.valid) {
762 		*temperature = KELVIN_TO_MILLICELSIUS(
763 				tz->trips.critical.temperature,
764 				tz->kelvin_offset);
765 		return 0;
766 	} else
767 		return -EINVAL;
768 }
769 
770 static int thermal_notify(struct thermal_zone_device *thermal, int trip,
771 			   enum thermal_trip_type trip_type)
772 {
773 	u8 type = 0;
774 	struct acpi_thermal *tz = thermal->devdata;
775 
776 	if (trip_type == THERMAL_TRIP_CRITICAL)
777 		type = ACPI_THERMAL_NOTIFY_CRITICAL;
778 	else if (trip_type == THERMAL_TRIP_HOT)
779 		type = ACPI_THERMAL_NOTIFY_HOT;
780 	else
781 		return 0;
782 
783 	acpi_bus_generate_proc_event(tz->device, type, 1);
784 	acpi_bus_generate_netlink_event(tz->device->pnp.device_class,
785 					dev_name(&tz->device->dev), type, 1);
786 
787 	if (trip_type == THERMAL_TRIP_CRITICAL && nocrt)
788 		return 1;
789 
790 	return 0;
791 }
792 
793 typedef int (*cb)(struct thermal_zone_device *, int,
794 		  struct thermal_cooling_device *);
795 static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal,
796 					struct thermal_cooling_device *cdev,
797 					cb action)
798 {
799 	struct acpi_device *device = cdev->devdata;
800 	struct acpi_thermal *tz = thermal->devdata;
801 	struct acpi_device *dev;
802 	acpi_status status;
803 	acpi_handle handle;
804 	int i;
805 	int j;
806 	int trip = -1;
807 	int result = 0;
808 
809 	if (tz->trips.critical.flags.valid)
810 		trip++;
811 
812 	if (tz->trips.hot.flags.valid)
813 		trip++;
814 
815 	if (tz->trips.passive.flags.valid) {
816 		trip++;
817 		for (i = 0; i < tz->trips.passive.devices.count;
818 		    i++) {
819 			handle = tz->trips.passive.devices.handles[i];
820 			status = acpi_bus_get_device(handle, &dev);
821 			if (ACPI_SUCCESS(status) && (dev == device)) {
822 				result = action(thermal, trip, cdev);
823 				if (result)
824 					goto failed;
825 			}
826 		}
827 	}
828 
829 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
830 		if (!tz->trips.active[i].flags.valid)
831 			break;
832 		trip++;
833 		for (j = 0;
834 		    j < tz->trips.active[i].devices.count;
835 		    j++) {
836 			handle = tz->trips.active[i].devices.handles[j];
837 			status = acpi_bus_get_device(handle, &dev);
838 			if (ACPI_SUCCESS(status) && (dev == device)) {
839 				result = action(thermal, trip, cdev);
840 				if (result)
841 					goto failed;
842 			}
843 		}
844 	}
845 
846 	for (i = 0; i < tz->devices.count; i++) {
847 		handle = tz->devices.handles[i];
848 		status = acpi_bus_get_device(handle, &dev);
849 		if (ACPI_SUCCESS(status) && (dev == device)) {
850 			result = action(thermal, -1, cdev);
851 			if (result)
852 				goto failed;
853 		}
854 	}
855 
856 failed:
857 	return result;
858 }
859 
860 static int
861 acpi_thermal_bind_cooling_device(struct thermal_zone_device *thermal,
862 					struct thermal_cooling_device *cdev)
863 {
864 	return acpi_thermal_cooling_device_cb(thermal, cdev,
865 				thermal_zone_bind_cooling_device);
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,
873 				thermal_zone_unbind_cooling_device);
874 }
875 
876 static struct thermal_zone_device_ops acpi_thermal_zone_ops = {
877 	.bind = acpi_thermal_bind_cooling_device,
878 	.unbind	= acpi_thermal_unbind_cooling_device,
879 	.get_temp = thermal_get_temp,
880 	.get_mode = thermal_get_mode,
881 	.set_mode = thermal_set_mode,
882 	.get_trip_type = thermal_get_trip_type,
883 	.get_trip_temp = thermal_get_trip_temp,
884 	.get_crit_temp = thermal_get_crit_temp,
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, tz,
910 						     &acpi_thermal_zone_ops,
911 						     tz->trips.passive.tc1,
912 						     tz->trips.passive.tc2,
913 						     tz->trips.passive.tsp*100,
914 						     tz->polling_frequency*100);
915 	else
916 		tz->thermal_zone =
917 			thermal_zone_device_register("acpitz", trips, tz,
918 						     &acpi_thermal_zone_ops,
919 						     0, 0, 0,
920 						     tz->polling_frequency*100);
921 	if (IS_ERR(tz->thermal_zone))
922 		return -ENODEV;
923 
924 	result = sysfs_create_link(&tz->device->dev.kobj,
925 				   &tz->thermal_zone->device.kobj, "thermal_zone");
926 	if (result)
927 		return result;
928 
929 	result = sysfs_create_link(&tz->thermal_zone->device.kobj,
930 				   &tz->device->dev.kobj, "device");
931 	if (result)
932 		return result;
933 
934 	status = acpi_attach_data(tz->device->handle,
935 				  acpi_bus_private_data_handler,
936 				  tz->thermal_zone);
937 	if (ACPI_FAILURE(status)) {
938 		printk(KERN_ERR PREFIX
939 				"Error attaching device data\n");
940 		return -ENODEV;
941 	}
942 
943 	tz->tz_enabled = 1;
944 
945 	dev_info(&tz->device->dev, "registered as thermal_zone%d\n",
946 		 tz->thermal_zone->id);
947 	return 0;
948 }
949 
950 static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz)
951 {
952 	sysfs_remove_link(&tz->device->dev.kobj, "thermal_zone");
953 	sysfs_remove_link(&tz->thermal_zone->device.kobj, "device");
954 	thermal_zone_device_unregister(tz->thermal_zone);
955 	tz->thermal_zone = NULL;
956 	acpi_detach_data(tz->device->handle, acpi_bus_private_data_handler);
957 }
958 
959 
960 /* --------------------------------------------------------------------------
961                               FS Interface (/proc)
962    -------------------------------------------------------------------------- */
963 #ifdef CONFIG_ACPI_PROCFS
964 static struct proc_dir_entry *acpi_thermal_dir;
965 
966 static int acpi_thermal_state_seq_show(struct seq_file *seq, void *offset)
967 {
968 	struct acpi_thermal *tz = seq->private;
969 
970 
971 	if (!tz)
972 		goto end;
973 
974 	seq_puts(seq, "state:                   ");
975 
976 	if (!tz->state.critical && !tz->state.hot && !tz->state.passive
977 	    && !tz->state.active)
978 		seq_puts(seq, "ok\n");
979 	else {
980 		if (tz->state.critical)
981 			seq_puts(seq, "critical ");
982 		if (tz->state.hot)
983 			seq_puts(seq, "hot ");
984 		if (tz->state.passive)
985 			seq_puts(seq, "passive ");
986 		if (tz->state.active)
987 			seq_printf(seq, "active[%d]", tz->state.active_index);
988 		seq_puts(seq, "\n");
989 	}
990 
991       end:
992 	return 0;
993 }
994 
995 static int acpi_thermal_state_open_fs(struct inode *inode, struct file *file)
996 {
997 	return single_open(file, acpi_thermal_state_seq_show, PDE(inode)->data);
998 }
999 
1000 static int acpi_thermal_temp_seq_show(struct seq_file *seq, void *offset)
1001 {
1002 	int result = 0;
1003 	struct acpi_thermal *tz = seq->private;
1004 
1005 
1006 	if (!tz)
1007 		goto end;
1008 
1009 	result = acpi_thermal_get_temperature(tz);
1010 	if (result)
1011 		goto end;
1012 
1013 	seq_printf(seq, "temperature:             %ld C\n",
1014 		   KELVIN_TO_CELSIUS(tz->temperature));
1015 
1016       end:
1017 	return 0;
1018 }
1019 
1020 static int acpi_thermal_temp_open_fs(struct inode *inode, struct file *file)
1021 {
1022 	return single_open(file, acpi_thermal_temp_seq_show, PDE(inode)->data);
1023 }
1024 
1025 static int acpi_thermal_trip_seq_show(struct seq_file *seq, void *offset)
1026 {
1027 	struct acpi_thermal *tz = seq->private;
1028 	struct acpi_device *device;
1029 	acpi_status status;
1030 
1031 	int i = 0;
1032 	int j = 0;
1033 
1034 
1035 	if (!tz)
1036 		goto end;
1037 
1038 	if (tz->trips.critical.flags.valid)
1039 		seq_printf(seq, "critical (S5):           %ld C%s",
1040 			   KELVIN_TO_CELSIUS(tz->trips.critical.temperature),
1041 			   nocrt ? " <disabled>\n" : "\n");
1042 
1043 	if (tz->trips.hot.flags.valid)
1044 		seq_printf(seq, "hot (S4):                %ld C%s",
1045 			   KELVIN_TO_CELSIUS(tz->trips.hot.temperature),
1046 			   nocrt ? " <disabled>\n" : "\n");
1047 
1048 	if (tz->trips.passive.flags.valid) {
1049 		seq_printf(seq,
1050 			   "passive:                 %ld C: tc1=%lu tc2=%lu tsp=%lu devices=",
1051 			   KELVIN_TO_CELSIUS(tz->trips.passive.temperature),
1052 			   tz->trips.passive.tc1, tz->trips.passive.tc2,
1053 			   tz->trips.passive.tsp);
1054 		for (j = 0; j < tz->trips.passive.devices.count; j++) {
1055 			status = acpi_bus_get_device(tz->trips.passive.devices.
1056 						     handles[j], &device);
1057 			seq_printf(seq, "%4.4s ", status ? "" :
1058 				   acpi_device_bid(device));
1059 		}
1060 		seq_puts(seq, "\n");
1061 	} else {
1062 		seq_printf(seq, "passive (forced):");
1063 		if (tz->thermal_zone->forced_passive)
1064 			seq_printf(seq, "        %i C\n",
1065 				   tz->thermal_zone->forced_passive / 1000);
1066 		else
1067 			seq_printf(seq, "<not set>\n");
1068 	}
1069 
1070 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
1071 		if (!(tz->trips.active[i].flags.valid))
1072 			break;
1073 		seq_printf(seq, "active[%d]:               %ld C: devices=",
1074 			   i,
1075 			   KELVIN_TO_CELSIUS(tz->trips.active[i].temperature));
1076 		for (j = 0; j < tz->trips.active[i].devices.count; j++){
1077 			status = acpi_bus_get_device(tz->trips.active[i].
1078 						     devices.handles[j],
1079 						     &device);
1080 			seq_printf(seq, "%4.4s ", status ? "" :
1081 				   acpi_device_bid(device));
1082 		}
1083 		seq_puts(seq, "\n");
1084 	}
1085 
1086       end:
1087 	return 0;
1088 }
1089 
1090 static int acpi_thermal_trip_open_fs(struct inode *inode, struct file *file)
1091 {
1092 	return single_open(file, acpi_thermal_trip_seq_show, PDE(inode)->data);
1093 }
1094 
1095 static int acpi_thermal_cooling_seq_show(struct seq_file *seq, void *offset)
1096 {
1097 	struct acpi_thermal *tz = seq->private;
1098 
1099 
1100 	if (!tz)
1101 		goto end;
1102 
1103 	if (!tz->flags.cooling_mode)
1104 		seq_puts(seq, "<setting not supported>\n");
1105 	else
1106 		seq_puts(seq, "0 - Active; 1 - Passive\n");
1107 
1108       end:
1109 	return 0;
1110 }
1111 
1112 static int acpi_thermal_cooling_open_fs(struct inode *inode, struct file *file)
1113 {
1114 	return single_open(file, acpi_thermal_cooling_seq_show,
1115 			   PDE(inode)->data);
1116 }
1117 
1118 static ssize_t
1119 acpi_thermal_write_cooling_mode(struct file *file,
1120 				const char __user * buffer,
1121 				size_t count, loff_t * ppos)
1122 {
1123 	struct seq_file *m = file->private_data;
1124 	struct acpi_thermal *tz = m->private;
1125 	int result = 0;
1126 	char mode_string[12] = { '\0' };
1127 
1128 
1129 	if (!tz || (count > sizeof(mode_string) - 1))
1130 		return -EINVAL;
1131 
1132 	if (!tz->flags.cooling_mode)
1133 		return -ENODEV;
1134 
1135 	if (copy_from_user(mode_string, buffer, count))
1136 		return -EFAULT;
1137 
1138 	mode_string[count] = '\0';
1139 
1140 	result = acpi_thermal_set_cooling_mode(tz,
1141 					       simple_strtoul(mode_string, NULL,
1142 							      0));
1143 	if (result)
1144 		return result;
1145 
1146 	acpi_thermal_check(tz);
1147 
1148 	return count;
1149 }
1150 
1151 static int acpi_thermal_polling_seq_show(struct seq_file *seq, void *offset)
1152 {
1153 	struct acpi_thermal *tz = seq->private;
1154 
1155 
1156 	if (!tz)
1157 		goto end;
1158 
1159 	if (!tz->thermal_zone->polling_delay) {
1160 		seq_puts(seq, "<polling disabled>\n");
1161 		goto end;
1162 	}
1163 
1164 	seq_printf(seq, "polling frequency:       %d seconds\n",
1165 		   (tz->thermal_zone->polling_delay / 1000));
1166 
1167       end:
1168 	return 0;
1169 }
1170 
1171 static int acpi_thermal_polling_open_fs(struct inode *inode, struct file *file)
1172 {
1173 	return single_open(file, acpi_thermal_polling_seq_show,
1174 			   PDE(inode)->data);
1175 }
1176 
1177 static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds)
1178 {
1179 	if (!tz)
1180 		return -EINVAL;
1181 
1182 	/* Convert value to deci-seconds */
1183 	tz->polling_frequency = seconds * 10;
1184 
1185 	tz->thermal_zone->polling_delay = seconds * 1000;
1186 
1187 	if (tz->tz_enabled)
1188 		thermal_zone_device_update(tz->thermal_zone);
1189 
1190 	ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1191 			  "Polling frequency set to %lu seconds\n",
1192 			  tz->polling_frequency/10));
1193 
1194 	return 0;
1195 }
1196 
1197 static ssize_t
1198 acpi_thermal_write_polling(struct file *file,
1199 			   const char __user * buffer,
1200 			   size_t count, loff_t * ppos)
1201 {
1202 	struct seq_file *m = file->private_data;
1203 	struct acpi_thermal *tz = m->private;
1204 	int result = 0;
1205 	char polling_string[12] = { '\0' };
1206 	int seconds = 0;
1207 
1208 
1209 	if (!tz || (count > sizeof(polling_string) - 1))
1210 		return -EINVAL;
1211 
1212 	if (copy_from_user(polling_string, buffer, count))
1213 		return -EFAULT;
1214 
1215 	polling_string[count] = '\0';
1216 
1217 	seconds = simple_strtoul(polling_string, NULL, 0);
1218 
1219 	result = acpi_thermal_set_polling(tz, seconds);
1220 	if (result)
1221 		return result;
1222 
1223 	acpi_thermal_check(tz);
1224 
1225 	return count;
1226 }
1227 
1228 static int acpi_thermal_add_fs(struct acpi_device *device)
1229 {
1230 	struct proc_dir_entry *entry = NULL;
1231 
1232 
1233 	if (!acpi_device_dir(device)) {
1234 		acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device),
1235 						     acpi_thermal_dir);
1236 		if (!acpi_device_dir(device))
1237 			return -ENODEV;
1238 	}
1239 
1240 	/* 'state' [R] */
1241 	entry = proc_create_data(ACPI_THERMAL_FILE_STATE,
1242 				 S_IRUGO, acpi_device_dir(device),
1243 				 &acpi_thermal_state_fops,
1244 				 acpi_driver_data(device));
1245 	if (!entry)
1246 		return -ENODEV;
1247 
1248 	/* 'temperature' [R] */
1249 	entry = proc_create_data(ACPI_THERMAL_FILE_TEMPERATURE,
1250 				 S_IRUGO, acpi_device_dir(device),
1251 				 &acpi_thermal_temp_fops,
1252 				 acpi_driver_data(device));
1253 	if (!entry)
1254 		return -ENODEV;
1255 
1256 	/* 'trip_points' [R] */
1257 	entry = proc_create_data(ACPI_THERMAL_FILE_TRIP_POINTS,
1258 				 S_IRUGO,
1259 				 acpi_device_dir(device),
1260 				 &acpi_thermal_trip_fops,
1261 				 acpi_driver_data(device));
1262 	if (!entry)
1263 		return -ENODEV;
1264 
1265 	/* 'cooling_mode' [R/W] */
1266 	entry = proc_create_data(ACPI_THERMAL_FILE_COOLING_MODE,
1267 				 S_IFREG | S_IRUGO | S_IWUSR,
1268 				 acpi_device_dir(device),
1269 				 &acpi_thermal_cooling_fops,
1270 				 acpi_driver_data(device));
1271 	if (!entry)
1272 		return -ENODEV;
1273 
1274 	/* 'polling_frequency' [R/W] */
1275 	entry = proc_create_data(ACPI_THERMAL_FILE_POLLING_FREQ,
1276 				 S_IFREG | S_IRUGO | S_IWUSR,
1277 				 acpi_device_dir(device),
1278 				 &acpi_thermal_polling_fops,
1279 				 acpi_driver_data(device));
1280 	if (!entry)
1281 		return -ENODEV;
1282 	return 0;
1283 }
1284 
1285 static int acpi_thermal_remove_fs(struct acpi_device *device)
1286 {
1287 
1288 	if (acpi_device_dir(device)) {
1289 		remove_proc_entry(ACPI_THERMAL_FILE_POLLING_FREQ,
1290 				  acpi_device_dir(device));
1291 		remove_proc_entry(ACPI_THERMAL_FILE_COOLING_MODE,
1292 				  acpi_device_dir(device));
1293 		remove_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS,
1294 				  acpi_device_dir(device));
1295 		remove_proc_entry(ACPI_THERMAL_FILE_TEMPERATURE,
1296 				  acpi_device_dir(device));
1297 		remove_proc_entry(ACPI_THERMAL_FILE_STATE,
1298 				  acpi_device_dir(device));
1299 		remove_proc_entry(acpi_device_bid(device), acpi_thermal_dir);
1300 		acpi_device_dir(device) = NULL;
1301 	}
1302 
1303 	return 0;
1304 }
1305 #else
1306 static inline int acpi_thermal_add_fs(struct acpi_device *device) { return 0; }
1307 static inline int acpi_thermal_remove_fs(struct acpi_device *device)
1308 {
1309 	return 0;
1310 }
1311 #endif /* CONFIG_ACPI_PROCFS */
1312 /* --------------------------------------------------------------------------
1313                                  Driver Interface
1314    -------------------------------------------------------------------------- */
1315 
1316 static void acpi_thermal_notify(struct acpi_device *device, u32 event)
1317 {
1318 	struct acpi_thermal *tz = acpi_driver_data(device);
1319 
1320 
1321 	if (!tz)
1322 		return;
1323 
1324 	switch (event) {
1325 	case ACPI_THERMAL_NOTIFY_TEMPERATURE:
1326 		acpi_thermal_check(tz);
1327 		break;
1328 	case ACPI_THERMAL_NOTIFY_THRESHOLDS:
1329 		acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_THRESHOLDS);
1330 		acpi_thermal_check(tz);
1331 		acpi_bus_generate_proc_event(device, event, 0);
1332 		acpi_bus_generate_netlink_event(device->pnp.device_class,
1333 						  dev_name(&device->dev), event, 0);
1334 		break;
1335 	case ACPI_THERMAL_NOTIFY_DEVICES:
1336 		acpi_thermal_trips_update(tz, ACPI_TRIPS_REFRESH_DEVICES);
1337 		acpi_thermal_check(tz);
1338 		acpi_bus_generate_proc_event(device, event, 0);
1339 		acpi_bus_generate_netlink_event(device->pnp.device_class,
1340 						  dev_name(&device->dev), event, 0);
1341 		break;
1342 	default:
1343 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1344 				  "Unsupported event [0x%x]\n", event));
1345 		break;
1346 	}
1347 }
1348 
1349 static int acpi_thermal_get_info(struct acpi_thermal *tz)
1350 {
1351 	int result = 0;
1352 
1353 
1354 	if (!tz)
1355 		return -EINVAL;
1356 
1357 	/* Get temperature [_TMP] (required) */
1358 	result = acpi_thermal_get_temperature(tz);
1359 	if (result)
1360 		return result;
1361 
1362 	/* Get trip points [_CRT, _PSV, etc.] (required) */
1363 	result = acpi_thermal_get_trip_points(tz);
1364 	if (result)
1365 		return result;
1366 
1367 	/* Set the cooling mode [_SCP] to active cooling (default) */
1368 	result = acpi_thermal_set_cooling_mode(tz, ACPI_THERMAL_MODE_ACTIVE);
1369 	if (!result)
1370 		tz->flags.cooling_mode = 1;
1371 
1372 	/* Get default polling frequency [_TZP] (optional) */
1373 	if (tzp)
1374 		tz->polling_frequency = tzp;
1375 	else
1376 		acpi_thermal_get_polling_frequency(tz);
1377 
1378 	return 0;
1379 }
1380 
1381 /*
1382  * The exact offset between Kelvin and degree Celsius is 273.15. However ACPI
1383  * handles temperature values with a single decimal place. As a consequence,
1384  * some implementations use an offset of 273.1 and others use an offset of
1385  * 273.2. Try to find out which one is being used, to present the most
1386  * accurate and visually appealing number.
1387  *
1388  * The heuristic below should work for all ACPI thermal zones which have a
1389  * critical trip point with a value being a multiple of 0.5 degree Celsius.
1390  */
1391 static void acpi_thermal_guess_offset(struct acpi_thermal *tz)
1392 {
1393 	if (tz->trips.critical.flags.valid &&
1394 	    (tz->trips.critical.temperature % 5) == 1)
1395 		tz->kelvin_offset = 2731;
1396 	else
1397 		tz->kelvin_offset = 2732;
1398 }
1399 
1400 static int acpi_thermal_add(struct acpi_device *device)
1401 {
1402 	int result = 0;
1403 	struct acpi_thermal *tz = NULL;
1404 
1405 
1406 	if (!device)
1407 		return -EINVAL;
1408 
1409 	tz = kzalloc(sizeof(struct acpi_thermal), GFP_KERNEL);
1410 	if (!tz)
1411 		return -ENOMEM;
1412 
1413 	tz->device = device;
1414 	strcpy(tz->name, device->pnp.bus_id);
1415 	strcpy(acpi_device_name(device), ACPI_THERMAL_DEVICE_NAME);
1416 	strcpy(acpi_device_class(device), ACPI_THERMAL_CLASS);
1417 	device->driver_data = tz;
1418 	mutex_init(&tz->lock);
1419 
1420 
1421 	result = acpi_thermal_get_info(tz);
1422 	if (result)
1423 		goto free_memory;
1424 
1425 	acpi_thermal_guess_offset(tz);
1426 
1427 	result = acpi_thermal_register_thermal_zone(tz);
1428 	if (result)
1429 		goto free_memory;
1430 
1431 	result = acpi_thermal_add_fs(device);
1432 	if (result)
1433 		goto unregister_thermal_zone;
1434 
1435 	printk(KERN_INFO PREFIX "%s [%s] (%ld C)\n",
1436 	       acpi_device_name(device), acpi_device_bid(device),
1437 	       KELVIN_TO_CELSIUS(tz->temperature));
1438 	goto end;
1439 
1440 unregister_thermal_zone:
1441 	thermal_zone_device_unregister(tz->thermal_zone);
1442 free_memory:
1443 	kfree(tz);
1444 end:
1445 	return result;
1446 }
1447 
1448 static int acpi_thermal_remove(struct acpi_device *device, int type)
1449 {
1450 	struct acpi_thermal *tz = NULL;
1451 
1452 	if (!device || !acpi_driver_data(device))
1453 		return -EINVAL;
1454 
1455 	tz = acpi_driver_data(device);
1456 
1457 	acpi_thermal_remove_fs(device);
1458 	acpi_thermal_unregister_thermal_zone(tz);
1459 	mutex_destroy(&tz->lock);
1460 	kfree(tz);
1461 	return 0;
1462 }
1463 
1464 static int acpi_thermal_resume(struct acpi_device *device)
1465 {
1466 	struct acpi_thermal *tz = NULL;
1467 	int i, j, power_state, result;
1468 
1469 
1470 	if (!device || !acpi_driver_data(device))
1471 		return -EINVAL;
1472 
1473 	tz = acpi_driver_data(device);
1474 
1475 	for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
1476 		if (!(&tz->trips.active[i]))
1477 			break;
1478 		if (!tz->trips.active[i].flags.valid)
1479 			break;
1480 		tz->trips.active[i].flags.enabled = 1;
1481 		for (j = 0; j < tz->trips.active[i].devices.count; j++) {
1482 			result = acpi_bus_get_power(tz->trips.active[i].devices.
1483 			    handles[j], &power_state);
1484 			if (result || (power_state != ACPI_STATE_D0)) {
1485 				tz->trips.active[i].flags.enabled = 0;
1486 				break;
1487 			}
1488 		}
1489 		tz->state.active |= tz->trips.active[i].flags.enabled;
1490 	}
1491 
1492 	acpi_thermal_check(tz);
1493 
1494 	return AE_OK;
1495 }
1496 
1497 static int thermal_act(const struct dmi_system_id *d) {
1498 
1499 	if (act == 0) {
1500 		printk(KERN_NOTICE "ACPI: %s detected: "
1501 			"disabling all active thermal trip points\n", d->ident);
1502 		act = -1;
1503 	}
1504 	return 0;
1505 }
1506 static int thermal_nocrt(const struct dmi_system_id *d) {
1507 
1508 	printk(KERN_NOTICE "ACPI: %s detected: "
1509 		"disabling all critical thermal trip point actions.\n", d->ident);
1510 	nocrt = 1;
1511 	return 0;
1512 }
1513 static int thermal_tzp(const struct dmi_system_id *d) {
1514 
1515 	if (tzp == 0) {
1516 		printk(KERN_NOTICE "ACPI: %s detected: "
1517 			"enabling thermal zone polling\n", d->ident);
1518 		tzp = 300;	/* 300 dS = 30 Seconds */
1519 	}
1520 	return 0;
1521 }
1522 static int thermal_psv(const struct dmi_system_id *d) {
1523 
1524 	if (psv == 0) {
1525 		printk(KERN_NOTICE "ACPI: %s detected: "
1526 			"disabling all passive thermal trip points\n", d->ident);
1527 		psv = -1;
1528 	}
1529 	return 0;
1530 }
1531 
1532 static struct dmi_system_id thermal_dmi_table[] __initdata = {
1533 	/*
1534 	 * Award BIOS on this AOpen makes thermal control almost worthless.
1535 	 * http://bugzilla.kernel.org/show_bug.cgi?id=8842
1536 	 */
1537 	{
1538 	 .callback = thermal_act,
1539 	 .ident = "AOpen i915GMm-HFS",
1540 	 .matches = {
1541 		DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
1542 		DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
1543 		},
1544 	},
1545 	{
1546 	 .callback = thermal_psv,
1547 	 .ident = "AOpen i915GMm-HFS",
1548 	 .matches = {
1549 		DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
1550 		DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
1551 		},
1552 	},
1553 	{
1554 	 .callback = thermal_tzp,
1555 	 .ident = "AOpen i915GMm-HFS",
1556 	 .matches = {
1557 		DMI_MATCH(DMI_BOARD_VENDOR, "AOpen"),
1558 		DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"),
1559 		},
1560 	},
1561 	{
1562 	 .callback = thermal_nocrt,
1563 	 .ident = "Gigabyte GA-7ZX",
1564 	 .matches = {
1565 		DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."),
1566 		DMI_MATCH(DMI_BOARD_NAME, "7ZX"),
1567 		},
1568 	},
1569 	{}
1570 };
1571 
1572 static int __init acpi_thermal_init(void)
1573 {
1574 	int result = 0;
1575 
1576 	dmi_check_system(thermal_dmi_table);
1577 
1578 	if (off) {
1579 		printk(KERN_NOTICE "ACPI: thermal control disabled\n");
1580 		return -ENODEV;
1581 	}
1582 
1583 #ifdef CONFIG_ACPI_PROCFS
1584 	acpi_thermal_dir = proc_mkdir(ACPI_THERMAL_CLASS, acpi_root_dir);
1585 	if (!acpi_thermal_dir)
1586 		return -ENODEV;
1587 #endif
1588 
1589 	result = acpi_bus_register_driver(&acpi_thermal_driver);
1590 	if (result < 0) {
1591 #ifdef CONFIG_ACPI_PROCFS
1592 		remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir);
1593 #endif
1594 		return -ENODEV;
1595 	}
1596 
1597 	return 0;
1598 }
1599 
1600 static void __exit acpi_thermal_exit(void)
1601 {
1602 
1603 	acpi_bus_unregister_driver(&acpi_thermal_driver);
1604 
1605 #ifdef CONFIG_ACPI_PROCFS
1606 	remove_proc_entry(ACPI_THERMAL_CLASS, acpi_root_dir);
1607 #endif
1608 
1609 	return;
1610 }
1611 
1612 module_init(acpi_thermal_init);
1613 module_exit(acpi_thermal_exit);
1614