• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6/drivers/thermal/
1/*
2 *  thermal.c - Generic Thermal Management Sysfs support.
3 *
4 *  Copyright (C) 2008 Intel Corp
5 *  Copyright (C) 2008 Zhang Rui <rui.zhang@intel.com>
6 *  Copyright (C) 2008 Sujith Thomas <sujith.thomas@intel.com>
7 *
8 *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
9 *
10 *  This program is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License as published by
12 *  the Free Software Foundation; version 2 of the License.
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
26#include <linux/module.h>
27#include <linux/device.h>
28#include <linux/err.h>
29#include <linux/slab.h>
30#include <linux/kdev_t.h>
31#include <linux/idr.h>
32#include <linux/thermal.h>
33#include <linux/spinlock.h>
34#include <linux/reboot.h>
35
36MODULE_AUTHOR("Zhang Rui");
37MODULE_DESCRIPTION("Generic thermal management sysfs support");
38MODULE_LICENSE("GPL");
39
40#define PREFIX "Thermal: "
41
42struct thermal_cooling_device_instance {
43	int id;
44	char name[THERMAL_NAME_LENGTH];
45	struct thermal_zone_device *tz;
46	struct thermal_cooling_device *cdev;
47	int trip;
48	char attr_name[THERMAL_NAME_LENGTH];
49	struct device_attribute attr;
50	struct list_head node;
51};
52
53static DEFINE_IDR(thermal_tz_idr);
54static DEFINE_IDR(thermal_cdev_idr);
55static DEFINE_MUTEX(thermal_idr_lock);
56
57static LIST_HEAD(thermal_tz_list);
58static LIST_HEAD(thermal_cdev_list);
59static DEFINE_MUTEX(thermal_list_lock);
60
61static int get_idr(struct idr *idr, struct mutex *lock, int *id)
62{
63	int err;
64
65      again:
66	if (unlikely(idr_pre_get(idr, GFP_KERNEL) == 0))
67		return -ENOMEM;
68
69	if (lock)
70		mutex_lock(lock);
71	err = idr_get_new(idr, NULL, id);
72	if (lock)
73		mutex_unlock(lock);
74	if (unlikely(err == -EAGAIN))
75		goto again;
76	else if (unlikely(err))
77		return err;
78
79	*id = *id & MAX_ID_MASK;
80	return 0;
81}
82
83static void release_idr(struct idr *idr, struct mutex *lock, int id)
84{
85	if (lock)
86		mutex_lock(lock);
87	idr_remove(idr, id);
88	if (lock)
89		mutex_unlock(lock);
90}
91
92/* sys I/F for thermal zone */
93
94#define to_thermal_zone(_dev) \
95	container_of(_dev, struct thermal_zone_device, device)
96
97static ssize_t
98type_show(struct device *dev, struct device_attribute *attr, char *buf)
99{
100	struct thermal_zone_device *tz = to_thermal_zone(dev);
101
102	return sprintf(buf, "%s\n", tz->type);
103}
104
105static ssize_t
106temp_show(struct device *dev, struct device_attribute *attr, char *buf)
107{
108	struct thermal_zone_device *tz = to_thermal_zone(dev);
109	long temperature;
110	int ret;
111
112	if (!tz->ops->get_temp)
113		return -EPERM;
114
115	ret = tz->ops->get_temp(tz, &temperature);
116
117	if (ret)
118		return ret;
119
120	return sprintf(buf, "%ld\n", temperature);
121}
122
123static ssize_t
124mode_show(struct device *dev, struct device_attribute *attr, char *buf)
125{
126	struct thermal_zone_device *tz = to_thermal_zone(dev);
127	enum thermal_device_mode mode;
128	int result;
129
130	if (!tz->ops->get_mode)
131		return -EPERM;
132
133	result = tz->ops->get_mode(tz, &mode);
134	if (result)
135		return result;
136
137	return sprintf(buf, "%s\n", mode == THERMAL_DEVICE_ENABLED ? "enabled"
138		       : "disabled");
139}
140
141static ssize_t
142mode_store(struct device *dev, struct device_attribute *attr,
143	   const char *buf, size_t count)
144{
145	struct thermal_zone_device *tz = to_thermal_zone(dev);
146	int result;
147
148	if (!tz->ops->set_mode)
149		return -EPERM;
150
151	if (!strncmp(buf, "enabled", sizeof("enabled")))
152		result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED);
153	else if (!strncmp(buf, "disabled", sizeof("disabled")))
154		result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED);
155	else
156		result = -EINVAL;
157
158	if (result)
159		return result;
160
161	return count;
162}
163
164static ssize_t
165trip_point_type_show(struct device *dev, struct device_attribute *attr,
166		     char *buf)
167{
168	struct thermal_zone_device *tz = to_thermal_zone(dev);
169	enum thermal_trip_type type;
170	int trip, result;
171
172	if (!tz->ops->get_trip_type)
173		return -EPERM;
174
175	if (!sscanf(attr->attr.name, "trip_point_%d_type", &trip))
176		return -EINVAL;
177
178	result = tz->ops->get_trip_type(tz, trip, &type);
179	if (result)
180		return result;
181
182	switch (type) {
183	case THERMAL_TRIP_CRITICAL:
184		return sprintf(buf, "critical\n");
185	case THERMAL_TRIP_HOT:
186		return sprintf(buf, "hot\n");
187	case THERMAL_TRIP_PASSIVE:
188		return sprintf(buf, "passive\n");
189	case THERMAL_TRIP_ACTIVE:
190		return sprintf(buf, "active\n");
191	default:
192		return sprintf(buf, "unknown\n");
193	}
194}
195
196static ssize_t
197trip_point_temp_show(struct device *dev, struct device_attribute *attr,
198		     char *buf)
199{
200	struct thermal_zone_device *tz = to_thermal_zone(dev);
201	int trip, ret;
202	long temperature;
203
204	if (!tz->ops->get_trip_temp)
205		return -EPERM;
206
207	if (!sscanf(attr->attr.name, "trip_point_%d_temp", &trip))
208		return -EINVAL;
209
210	ret = tz->ops->get_trip_temp(tz, trip, &temperature);
211
212	if (ret)
213		return ret;
214
215	return sprintf(buf, "%ld\n", temperature);
216}
217
218static ssize_t
219passive_store(struct device *dev, struct device_attribute *attr,
220		    const char *buf, size_t count)
221{
222	struct thermal_zone_device *tz = to_thermal_zone(dev);
223	struct thermal_cooling_device *cdev = NULL;
224	int state;
225
226	if (!sscanf(buf, "%d\n", &state))
227		return -EINVAL;
228
229	/* sanity check: values below 1000 millicelcius don't make sense
230	 * and can cause the system to go into a thermal heart attack
231	 */
232	if (state && state < 1000)
233		return -EINVAL;
234
235	if (state && !tz->forced_passive) {
236		mutex_lock(&thermal_list_lock);
237		list_for_each_entry(cdev, &thermal_cdev_list, node) {
238			if (!strncmp("Processor", cdev->type,
239				     sizeof("Processor")))
240				thermal_zone_bind_cooling_device(tz,
241								 THERMAL_TRIPS_NONE,
242								 cdev);
243		}
244		mutex_unlock(&thermal_list_lock);
245		if (!tz->passive_delay)
246			tz->passive_delay = 1000;
247	} else if (!state && tz->forced_passive) {
248		mutex_lock(&thermal_list_lock);
249		list_for_each_entry(cdev, &thermal_cdev_list, node) {
250			if (!strncmp("Processor", cdev->type,
251				     sizeof("Processor")))
252				thermal_zone_unbind_cooling_device(tz,
253								   THERMAL_TRIPS_NONE,
254								   cdev);
255		}
256		mutex_unlock(&thermal_list_lock);
257		tz->passive_delay = 0;
258	}
259
260	tz->tc1 = 1;
261	tz->tc2 = 1;
262
263	tz->forced_passive = state;
264
265	thermal_zone_device_update(tz);
266
267	return count;
268}
269
270static ssize_t
271passive_show(struct device *dev, struct device_attribute *attr,
272		   char *buf)
273{
274	struct thermal_zone_device *tz = to_thermal_zone(dev);
275
276	return sprintf(buf, "%d\n", tz->forced_passive);
277}
278
279static DEVICE_ATTR(type, 0444, type_show, NULL);
280static DEVICE_ATTR(temp, 0444, temp_show, NULL);
281static DEVICE_ATTR(mode, 0644, mode_show, mode_store);
282static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, \
283		   passive_store);
284
285static struct device_attribute trip_point_attrs[] = {
286	__ATTR(trip_point_0_type, 0444, trip_point_type_show, NULL),
287	__ATTR(trip_point_0_temp, 0444, trip_point_temp_show, NULL),
288	__ATTR(trip_point_1_type, 0444, trip_point_type_show, NULL),
289	__ATTR(trip_point_1_temp, 0444, trip_point_temp_show, NULL),
290	__ATTR(trip_point_2_type, 0444, trip_point_type_show, NULL),
291	__ATTR(trip_point_2_temp, 0444, trip_point_temp_show, NULL),
292	__ATTR(trip_point_3_type, 0444, trip_point_type_show, NULL),
293	__ATTR(trip_point_3_temp, 0444, trip_point_temp_show, NULL),
294	__ATTR(trip_point_4_type, 0444, trip_point_type_show, NULL),
295	__ATTR(trip_point_4_temp, 0444, trip_point_temp_show, NULL),
296	__ATTR(trip_point_5_type, 0444, trip_point_type_show, NULL),
297	__ATTR(trip_point_5_temp, 0444, trip_point_temp_show, NULL),
298	__ATTR(trip_point_6_type, 0444, trip_point_type_show, NULL),
299	__ATTR(trip_point_6_temp, 0444, trip_point_temp_show, NULL),
300	__ATTR(trip_point_7_type, 0444, trip_point_type_show, NULL),
301	__ATTR(trip_point_7_temp, 0444, trip_point_temp_show, NULL),
302	__ATTR(trip_point_8_type, 0444, trip_point_type_show, NULL),
303	__ATTR(trip_point_8_temp, 0444, trip_point_temp_show, NULL),
304	__ATTR(trip_point_9_type, 0444, trip_point_type_show, NULL),
305	__ATTR(trip_point_9_temp, 0444, trip_point_temp_show, NULL),
306	__ATTR(trip_point_10_type, 0444, trip_point_type_show, NULL),
307	__ATTR(trip_point_10_temp, 0444, trip_point_temp_show, NULL),
308	__ATTR(trip_point_11_type, 0444, trip_point_type_show, NULL),
309	__ATTR(trip_point_11_temp, 0444, trip_point_temp_show, NULL),
310};
311
312#define TRIP_POINT_ATTR_ADD(_dev, _index, result)     \
313do {    \
314	result = device_create_file(_dev,	\
315				&trip_point_attrs[_index * 2]);	\
316	if (result)	\
317		break;	\
318	result = device_create_file(_dev,	\
319			&trip_point_attrs[_index * 2 + 1]);	\
320} while (0)
321
322#define TRIP_POINT_ATTR_REMOVE(_dev, _index)	\
323do {	\
324	device_remove_file(_dev, &trip_point_attrs[_index * 2]);	\
325	device_remove_file(_dev, &trip_point_attrs[_index * 2 + 1]);	\
326} while (0)
327
328/* sys I/F for cooling device */
329#define to_cooling_device(_dev)	\
330	container_of(_dev, struct thermal_cooling_device, device)
331
332static ssize_t
333thermal_cooling_device_type_show(struct device *dev,
334				 struct device_attribute *attr, char *buf)
335{
336	struct thermal_cooling_device *cdev = to_cooling_device(dev);
337
338	return sprintf(buf, "%s\n", cdev->type);
339}
340
341static ssize_t
342thermal_cooling_device_max_state_show(struct device *dev,
343				      struct device_attribute *attr, char *buf)
344{
345	struct thermal_cooling_device *cdev = to_cooling_device(dev);
346	unsigned long state;
347	int ret;
348
349	ret = cdev->ops->get_max_state(cdev, &state);
350	if (ret)
351		return ret;
352	return sprintf(buf, "%ld\n", state);
353}
354
355static ssize_t
356thermal_cooling_device_cur_state_show(struct device *dev,
357				      struct device_attribute *attr, char *buf)
358{
359	struct thermal_cooling_device *cdev = to_cooling_device(dev);
360	unsigned long state;
361	int ret;
362
363	ret = cdev->ops->get_cur_state(cdev, &state);
364	if (ret)
365		return ret;
366	return sprintf(buf, "%ld\n", state);
367}
368
369static ssize_t
370thermal_cooling_device_cur_state_store(struct device *dev,
371				       struct device_attribute *attr,
372				       const char *buf, size_t count)
373{
374	struct thermal_cooling_device *cdev = to_cooling_device(dev);
375	unsigned long state;
376	int result;
377
378	if (!sscanf(buf, "%ld\n", &state))
379		return -EINVAL;
380
381	if ((long)state < 0)
382		return -EINVAL;
383
384	result = cdev->ops->set_cur_state(cdev, state);
385	if (result)
386		return result;
387	return count;
388}
389
390static struct device_attribute dev_attr_cdev_type =
391__ATTR(type, 0444, thermal_cooling_device_type_show, NULL);
392static DEVICE_ATTR(max_state, 0444,
393		   thermal_cooling_device_max_state_show, NULL);
394static DEVICE_ATTR(cur_state, 0644,
395		   thermal_cooling_device_cur_state_show,
396		   thermal_cooling_device_cur_state_store);
397
398static ssize_t
399thermal_cooling_device_trip_point_show(struct device *dev,
400				       struct device_attribute *attr, char *buf)
401{
402	struct thermal_cooling_device_instance *instance;
403
404	instance =
405	    container_of(attr, struct thermal_cooling_device_instance, attr);
406
407	if (instance->trip == THERMAL_TRIPS_NONE)
408		return sprintf(buf, "-1\n");
409	else
410		return sprintf(buf, "%d\n", instance->trip);
411}
412
413/* Device management */
414
415#if defined(CONFIG_THERMAL_HWMON)
416
417/* hwmon sys I/F */
418#include <linux/hwmon.h>
419static LIST_HEAD(thermal_hwmon_list);
420
421static ssize_t
422name_show(struct device *dev, struct device_attribute *attr, char *buf)
423{
424	struct thermal_hwmon_device *hwmon = dev_get_drvdata(dev);
425	return sprintf(buf, "%s\n", hwmon->type);
426}
427static DEVICE_ATTR(name, 0444, name_show, NULL);
428
429static ssize_t
430temp_input_show(struct device *dev, struct device_attribute *attr, char *buf)
431{
432	long temperature;
433	int ret;
434	struct thermal_hwmon_attr *hwmon_attr
435			= container_of(attr, struct thermal_hwmon_attr, attr);
436	struct thermal_zone_device *tz
437			= container_of(hwmon_attr, struct thermal_zone_device,
438				       temp_input);
439
440	ret = tz->ops->get_temp(tz, &temperature);
441
442	if (ret)
443		return ret;
444
445	return sprintf(buf, "%ld\n", temperature);
446}
447
448static ssize_t
449temp_crit_show(struct device *dev, struct device_attribute *attr,
450		char *buf)
451{
452	struct thermal_hwmon_attr *hwmon_attr
453			= container_of(attr, struct thermal_hwmon_attr, attr);
454	struct thermal_zone_device *tz
455			= container_of(hwmon_attr, struct thermal_zone_device,
456				       temp_crit);
457	long temperature;
458	int ret;
459
460	ret = tz->ops->get_trip_temp(tz, 0, &temperature);
461	if (ret)
462		return ret;
463
464	return sprintf(buf, "%ld\n", temperature);
465}
466
467
468static int
469thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
470{
471	struct thermal_hwmon_device *hwmon;
472	int new_hwmon_device = 1;
473	int result;
474
475	mutex_lock(&thermal_list_lock);
476	list_for_each_entry(hwmon, &thermal_hwmon_list, node)
477		if (!strcmp(hwmon->type, tz->type)) {
478			new_hwmon_device = 0;
479			mutex_unlock(&thermal_list_lock);
480			goto register_sys_interface;
481		}
482	mutex_unlock(&thermal_list_lock);
483
484	hwmon = kzalloc(sizeof(struct thermal_hwmon_device), GFP_KERNEL);
485	if (!hwmon)
486		return -ENOMEM;
487
488	INIT_LIST_HEAD(&hwmon->tz_list);
489	strlcpy(hwmon->type, tz->type, THERMAL_NAME_LENGTH);
490	hwmon->device = hwmon_device_register(NULL);
491	if (IS_ERR(hwmon->device)) {
492		result = PTR_ERR(hwmon->device);
493		goto free_mem;
494	}
495	dev_set_drvdata(hwmon->device, hwmon);
496	result = device_create_file(hwmon->device, &dev_attr_name);
497	if (result)
498		goto unregister_hwmon_device;
499
500 register_sys_interface:
501	tz->hwmon = hwmon;
502	hwmon->count++;
503
504	snprintf(tz->temp_input.name, THERMAL_NAME_LENGTH,
505		 "temp%d_input", hwmon->count);
506	tz->temp_input.attr.attr.name = tz->temp_input.name;
507	tz->temp_input.attr.attr.mode = 0444;
508	tz->temp_input.attr.show = temp_input_show;
509	sysfs_attr_init(&tz->temp_input.attr.attr);
510	result = device_create_file(hwmon->device, &tz->temp_input.attr);
511	if (result)
512		goto unregister_hwmon_device;
513
514	if (tz->ops->get_crit_temp) {
515		unsigned long temperature;
516		if (!tz->ops->get_crit_temp(tz, &temperature)) {
517			snprintf(tz->temp_crit.name, THERMAL_NAME_LENGTH,
518				"temp%d_crit", hwmon->count);
519			tz->temp_crit.attr.attr.name = tz->temp_crit.name;
520			tz->temp_crit.attr.attr.mode = 0444;
521			tz->temp_crit.attr.show = temp_crit_show;
522			sysfs_attr_init(&tz->temp_crit.attr.attr);
523			result = device_create_file(hwmon->device,
524						    &tz->temp_crit.attr);
525			if (result)
526				goto unregister_hwmon_device;
527		}
528	}
529
530	mutex_lock(&thermal_list_lock);
531	if (new_hwmon_device)
532		list_add_tail(&hwmon->node, &thermal_hwmon_list);
533	list_add_tail(&tz->hwmon_node, &hwmon->tz_list);
534	mutex_unlock(&thermal_list_lock);
535
536	return 0;
537
538 unregister_hwmon_device:
539	device_remove_file(hwmon->device, &tz->temp_crit.attr);
540	device_remove_file(hwmon->device, &tz->temp_input.attr);
541	if (new_hwmon_device) {
542		device_remove_file(hwmon->device, &dev_attr_name);
543		hwmon_device_unregister(hwmon->device);
544	}
545 free_mem:
546	if (new_hwmon_device)
547		kfree(hwmon);
548
549	return result;
550}
551
552static void
553thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
554{
555	struct thermal_hwmon_device *hwmon = tz->hwmon;
556
557	tz->hwmon = NULL;
558	device_remove_file(hwmon->device, &tz->temp_input.attr);
559	device_remove_file(hwmon->device, &tz->temp_crit.attr);
560
561	mutex_lock(&thermal_list_lock);
562	list_del(&tz->hwmon_node);
563	if (!list_empty(&hwmon->tz_list)) {
564		mutex_unlock(&thermal_list_lock);
565		return;
566	}
567	list_del(&hwmon->node);
568	mutex_unlock(&thermal_list_lock);
569
570	device_remove_file(hwmon->device, &dev_attr_name);
571	hwmon_device_unregister(hwmon->device);
572	kfree(hwmon);
573}
574#else
575static int
576thermal_add_hwmon_sysfs(struct thermal_zone_device *tz)
577{
578	return 0;
579}
580
581static void
582thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
583{
584}
585#endif
586
587static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
588					    int delay)
589{
590	cancel_delayed_work(&(tz->poll_queue));
591
592	if (!delay)
593		return;
594
595	if (delay > 1000)
596		schedule_delayed_work(&(tz->poll_queue),
597				      round_jiffies(msecs_to_jiffies(delay)));
598	else
599		schedule_delayed_work(&(tz->poll_queue),
600				      msecs_to_jiffies(delay));
601}
602
603static void thermal_zone_device_passive(struct thermal_zone_device *tz,
604					int temp, int trip_temp, int trip)
605{
606	int trend = 0;
607	struct thermal_cooling_device_instance *instance;
608	struct thermal_cooling_device *cdev;
609	long state, max_state;
610
611	/*
612	 * Above Trip?
613	 * -----------
614	 * Calculate the thermal trend (using the passive cooling equation)
615	 * and modify the performance limit for all passive cooling devices
616	 * accordingly.  Note that we assume symmetry.
617	 */
618	if (temp >= trip_temp) {
619		tz->passive = true;
620
621		trend = (tz->tc1 * (temp - tz->last_temperature)) +
622			(tz->tc2 * (temp - trip_temp));
623
624		/* Heating up? */
625		if (trend > 0) {
626			list_for_each_entry(instance, &tz->cooling_devices,
627					    node) {
628				if (instance->trip != trip)
629					continue;
630				cdev = instance->cdev;
631				cdev->ops->get_cur_state(cdev, &state);
632				cdev->ops->get_max_state(cdev, &max_state);
633				if (state++ < max_state)
634					cdev->ops->set_cur_state(cdev, state);
635			}
636		} else if (trend < 0) { /* Cooling off? */
637			list_for_each_entry(instance, &tz->cooling_devices,
638					    node) {
639				if (instance->trip != trip)
640					continue;
641				cdev = instance->cdev;
642				cdev->ops->get_cur_state(cdev, &state);
643				cdev->ops->get_max_state(cdev, &max_state);
644				if (state > 0)
645					cdev->ops->set_cur_state(cdev, --state);
646			}
647		}
648		return;
649	}
650
651	/*
652	 * Below Trip?
653	 * -----------
654	 * Implement passive cooling hysteresis to slowly increase performance
655	 * and avoid thrashing around the passive trip point.  Note that we
656	 * assume symmetry.
657	 */
658	list_for_each_entry(instance, &tz->cooling_devices, node) {
659		if (instance->trip != trip)
660			continue;
661		cdev = instance->cdev;
662		cdev->ops->get_cur_state(cdev, &state);
663		cdev->ops->get_max_state(cdev, &max_state);
664		if (state > 0)
665			cdev->ops->set_cur_state(cdev, --state);
666		if (state == 0)
667			tz->passive = false;
668	}
669}
670
671static void thermal_zone_device_check(struct work_struct *work)
672{
673	struct thermal_zone_device *tz = container_of(work, struct
674						      thermal_zone_device,
675						      poll_queue.work);
676	thermal_zone_device_update(tz);
677}
678
679/**
680 * thermal_zone_bind_cooling_device - bind a cooling device to a thermal zone
681 * @tz:		thermal zone device
682 * @trip:	indicates which trip point the cooling devices is
683 *		associated with in this thermal zone.
684 * @cdev:	thermal cooling device
685 *
686 * This function is usually called in the thermal zone device .bind callback.
687 */
688int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
689				     int trip,
690				     struct thermal_cooling_device *cdev)
691{
692	struct thermal_cooling_device_instance *dev;
693	struct thermal_cooling_device_instance *pos;
694	struct thermal_zone_device *pos1;
695	struct thermal_cooling_device *pos2;
696	int result;
697
698	if (trip >= tz->trips || (trip < 0 && trip != THERMAL_TRIPS_NONE))
699		return -EINVAL;
700
701	list_for_each_entry(pos1, &thermal_tz_list, node) {
702		if (pos1 == tz)
703			break;
704	}
705	list_for_each_entry(pos2, &thermal_cdev_list, node) {
706		if (pos2 == cdev)
707			break;
708	}
709
710	if (tz != pos1 || cdev != pos2)
711		return -EINVAL;
712
713	dev =
714	    kzalloc(sizeof(struct thermal_cooling_device_instance), GFP_KERNEL);
715	if (!dev)
716		return -ENOMEM;
717	dev->tz = tz;
718	dev->cdev = cdev;
719	dev->trip = trip;
720	result = get_idr(&tz->idr, &tz->lock, &dev->id);
721	if (result)
722		goto free_mem;
723
724	sprintf(dev->name, "cdev%d", dev->id);
725	result =
726	    sysfs_create_link(&tz->device.kobj, &cdev->device.kobj, dev->name);
727	if (result)
728		goto release_idr;
729
730	sprintf(dev->attr_name, "cdev%d_trip_point", dev->id);
731	sysfs_attr_init(&dev->attr.attr);
732	dev->attr.attr.name = dev->attr_name;
733	dev->attr.attr.mode = 0444;
734	dev->attr.show = thermal_cooling_device_trip_point_show;
735	result = device_create_file(&tz->device, &dev->attr);
736	if (result)
737		goto remove_symbol_link;
738
739	mutex_lock(&tz->lock);
740	list_for_each_entry(pos, &tz->cooling_devices, node)
741	    if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
742		result = -EEXIST;
743		break;
744	}
745	if (!result)
746		list_add_tail(&dev->node, &tz->cooling_devices);
747	mutex_unlock(&tz->lock);
748
749	if (!result)
750		return 0;
751
752	device_remove_file(&tz->device, &dev->attr);
753      remove_symbol_link:
754	sysfs_remove_link(&tz->device.kobj, dev->name);
755      release_idr:
756	release_idr(&tz->idr, &tz->lock, dev->id);
757      free_mem:
758	kfree(dev);
759	return result;
760}
761
762EXPORT_SYMBOL(thermal_zone_bind_cooling_device);
763
764/**
765 * thermal_zone_unbind_cooling_device - unbind a cooling device from a thermal zone
766 * @tz:		thermal zone device
767 * @trip:	indicates which trip point the cooling devices is
768 *		associated with in this thermal zone.
769 * @cdev:	thermal cooling device
770 *
771 * This function is usually called in the thermal zone device .unbind callback.
772 */
773int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
774				       int trip,
775				       struct thermal_cooling_device *cdev)
776{
777	struct thermal_cooling_device_instance *pos, *next;
778
779	mutex_lock(&tz->lock);
780	list_for_each_entry_safe(pos, next, &tz->cooling_devices, node) {
781		if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
782			list_del(&pos->node);
783			mutex_unlock(&tz->lock);
784			goto unbind;
785		}
786	}
787	mutex_unlock(&tz->lock);
788
789	return -ENODEV;
790
791      unbind:
792	device_remove_file(&tz->device, &pos->attr);
793	sysfs_remove_link(&tz->device.kobj, pos->name);
794	release_idr(&tz->idr, &tz->lock, pos->id);
795	kfree(pos);
796	return 0;
797}
798
799EXPORT_SYMBOL(thermal_zone_unbind_cooling_device);
800
801static void thermal_release(struct device *dev)
802{
803	struct thermal_zone_device *tz;
804	struct thermal_cooling_device *cdev;
805
806	if (!strncmp(dev_name(dev), "thermal_zone", sizeof "thermal_zone" - 1)) {
807		tz = to_thermal_zone(dev);
808		kfree(tz);
809	} else {
810		cdev = to_cooling_device(dev);
811		kfree(cdev);
812	}
813}
814
815static struct class thermal_class = {
816	.name = "thermal",
817	.dev_release = thermal_release,
818};
819
820/**
821 * thermal_cooling_device_register - register a new thermal cooling device
822 * @type:	the thermal cooling device type.
823 * @devdata:	device private data.
824 * @ops:		standard thermal cooling devices callbacks.
825 */
826struct thermal_cooling_device *thermal_cooling_device_register(char *type,
827							       void *devdata,
828							       struct
829							       thermal_cooling_device_ops
830							       *ops)
831{
832	struct thermal_cooling_device *cdev;
833	struct thermal_zone_device *pos;
834	int result;
835
836	if (strlen(type) >= THERMAL_NAME_LENGTH)
837		return ERR_PTR(-EINVAL);
838
839	if (!ops || !ops->get_max_state || !ops->get_cur_state ||
840	    !ops->set_cur_state)
841		return ERR_PTR(-EINVAL);
842
843	cdev = kzalloc(sizeof(struct thermal_cooling_device), GFP_KERNEL);
844	if (!cdev)
845		return ERR_PTR(-ENOMEM);
846
847	result = get_idr(&thermal_cdev_idr, &thermal_idr_lock, &cdev->id);
848	if (result) {
849		kfree(cdev);
850		return ERR_PTR(result);
851	}
852
853	strcpy(cdev->type, type);
854	cdev->ops = ops;
855	cdev->device.class = &thermal_class;
856	cdev->devdata = devdata;
857	dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
858	result = device_register(&cdev->device);
859	if (result) {
860		release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id);
861		kfree(cdev);
862		return ERR_PTR(result);
863	}
864
865	/* sys I/F */
866	if (type) {
867		result = device_create_file(&cdev->device, &dev_attr_cdev_type);
868		if (result)
869			goto unregister;
870	}
871
872	result = device_create_file(&cdev->device, &dev_attr_max_state);
873	if (result)
874		goto unregister;
875
876	result = device_create_file(&cdev->device, &dev_attr_cur_state);
877	if (result)
878		goto unregister;
879
880	mutex_lock(&thermal_list_lock);
881	list_add(&cdev->node, &thermal_cdev_list);
882	list_for_each_entry(pos, &thermal_tz_list, node) {
883		if (!pos->ops->bind)
884			continue;
885		result = pos->ops->bind(pos, cdev);
886		if (result)
887			break;
888
889	}
890	mutex_unlock(&thermal_list_lock);
891
892	if (!result)
893		return cdev;
894
895      unregister:
896	release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id);
897	device_unregister(&cdev->device);
898	return ERR_PTR(result);
899}
900
901EXPORT_SYMBOL(thermal_cooling_device_register);
902
903/**
904 * thermal_cooling_device_unregister - removes the registered thermal cooling device
905 * @cdev:	the thermal cooling device to remove.
906 *
907 * thermal_cooling_device_unregister() must be called when the device is no
908 * longer needed.
909 */
910void thermal_cooling_device_unregister(struct
911				       thermal_cooling_device
912				       *cdev)
913{
914	struct thermal_zone_device *tz;
915	struct thermal_cooling_device *pos = NULL;
916
917	if (!cdev)
918		return;
919
920	mutex_lock(&thermal_list_lock);
921	list_for_each_entry(pos, &thermal_cdev_list, node)
922	    if (pos == cdev)
923		break;
924	if (pos != cdev) {
925		/* thermal cooling device not found */
926		mutex_unlock(&thermal_list_lock);
927		return;
928	}
929	list_del(&cdev->node);
930	list_for_each_entry(tz, &thermal_tz_list, node) {
931		if (!tz->ops->unbind)
932			continue;
933		tz->ops->unbind(tz, cdev);
934	}
935	mutex_unlock(&thermal_list_lock);
936	if (cdev->type[0])
937		device_remove_file(&cdev->device, &dev_attr_cdev_type);
938	device_remove_file(&cdev->device, &dev_attr_max_state);
939	device_remove_file(&cdev->device, &dev_attr_cur_state);
940
941	release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id);
942	device_unregister(&cdev->device);
943	return;
944}
945
946EXPORT_SYMBOL(thermal_cooling_device_unregister);
947
948/**
949 * thermal_zone_device_update - force an update of a thermal zone's state
950 * @ttz:	the thermal zone to update
951 */
952
953void thermal_zone_device_update(struct thermal_zone_device *tz)
954{
955	int count, ret = 0;
956	long temp, trip_temp;
957	enum thermal_trip_type trip_type;
958	struct thermal_cooling_device_instance *instance;
959	struct thermal_cooling_device *cdev;
960
961	mutex_lock(&tz->lock);
962
963	if (tz->ops->get_temp(tz, &temp)) {
964		/* get_temp failed - retry it later */
965		printk(KERN_WARNING PREFIX "failed to read out thermal zone "
966		       "%d\n", tz->id);
967		goto leave;
968	}
969
970	for (count = 0; count < tz->trips; count++) {
971		tz->ops->get_trip_type(tz, count, &trip_type);
972		tz->ops->get_trip_temp(tz, count, &trip_temp);
973
974		switch (trip_type) {
975		case THERMAL_TRIP_CRITICAL:
976			if (temp >= trip_temp) {
977				if (tz->ops->notify)
978					ret = tz->ops->notify(tz, count,
979							      trip_type);
980				if (!ret) {
981					printk(KERN_EMERG
982					       "Critical temperature reached (%ld C), shutting down.\n",
983					       temp/1000);
984					orderly_poweroff(true);
985				}
986			}
987			break;
988		case THERMAL_TRIP_HOT:
989			if (temp >= trip_temp)
990				if (tz->ops->notify)
991					tz->ops->notify(tz, count, trip_type);
992			break;
993		case THERMAL_TRIP_ACTIVE:
994			list_for_each_entry(instance, &tz->cooling_devices,
995					    node) {
996				if (instance->trip != count)
997					continue;
998
999				cdev = instance->cdev;
1000
1001				if (temp >= trip_temp)
1002					cdev->ops->set_cur_state(cdev, 1);
1003				else
1004					cdev->ops->set_cur_state(cdev, 0);
1005			}
1006			break;
1007		case THERMAL_TRIP_PASSIVE:
1008			if (temp >= trip_temp || tz->passive)
1009				thermal_zone_device_passive(tz, temp,
1010							    trip_temp, count);
1011			break;
1012		}
1013	}
1014
1015	if (tz->forced_passive)
1016		thermal_zone_device_passive(tz, temp, tz->forced_passive,
1017					    THERMAL_TRIPS_NONE);
1018
1019	tz->last_temperature = temp;
1020
1021      leave:
1022	if (tz->passive)
1023		thermal_zone_device_set_polling(tz, tz->passive_delay);
1024	else if (tz->polling_delay)
1025		thermal_zone_device_set_polling(tz, tz->polling_delay);
1026	else
1027		thermal_zone_device_set_polling(tz, 0);
1028	mutex_unlock(&tz->lock);
1029}
1030EXPORT_SYMBOL(thermal_zone_device_update);
1031
1032/**
1033 * thermal_zone_device_register - register a new thermal zone device
1034 * @type:	the thermal zone device type
1035 * @trips:	the number of trip points the thermal zone support
1036 * @devdata:	private device data
1037 * @ops:	standard thermal zone device callbacks
1038 * @tc1:	thermal coefficient 1 for passive calculations
1039 * @tc2:	thermal coefficient 2 for passive calculations
1040 * @passive_delay: number of milliseconds to wait between polls when
1041 *		   performing passive cooling
1042 * @polling_delay: number of milliseconds to wait between polls when checking
1043 *		   whether trip points have been crossed (0 for interrupt
1044 *		   driven systems)
1045 *
1046 * thermal_zone_device_unregister() must be called when the device is no
1047 * longer needed. The passive cooling formula uses tc1 and tc2 as described in
1048 * section 11.1.5.1 of the ACPI specification 3.0.
1049 */
1050struct thermal_zone_device *thermal_zone_device_register(char *type,
1051							 int trips,
1052							 void *devdata, struct
1053							 thermal_zone_device_ops
1054							 *ops, int tc1, int
1055							 tc2,
1056							 int passive_delay,
1057							 int polling_delay)
1058{
1059	struct thermal_zone_device *tz;
1060	struct thermal_cooling_device *pos;
1061	enum thermal_trip_type trip_type;
1062	int result;
1063	int count;
1064	int passive = 0;
1065
1066	if (strlen(type) >= THERMAL_NAME_LENGTH)
1067		return ERR_PTR(-EINVAL);
1068
1069	if (trips > THERMAL_MAX_TRIPS || trips < 0)
1070		return ERR_PTR(-EINVAL);
1071
1072	if (!ops || !ops->get_temp)
1073		return ERR_PTR(-EINVAL);
1074
1075	tz = kzalloc(sizeof(struct thermal_zone_device), GFP_KERNEL);
1076	if (!tz)
1077		return ERR_PTR(-ENOMEM);
1078
1079	INIT_LIST_HEAD(&tz->cooling_devices);
1080	idr_init(&tz->idr);
1081	mutex_init(&tz->lock);
1082	result = get_idr(&thermal_tz_idr, &thermal_idr_lock, &tz->id);
1083	if (result) {
1084		kfree(tz);
1085		return ERR_PTR(result);
1086	}
1087
1088	strcpy(tz->type, type);
1089	tz->ops = ops;
1090	tz->device.class = &thermal_class;
1091	tz->devdata = devdata;
1092	tz->trips = trips;
1093	tz->tc1 = tc1;
1094	tz->tc2 = tc2;
1095	tz->passive_delay = passive_delay;
1096	tz->polling_delay = polling_delay;
1097
1098	dev_set_name(&tz->device, "thermal_zone%d", tz->id);
1099	result = device_register(&tz->device);
1100	if (result) {
1101		release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id);
1102		kfree(tz);
1103		return ERR_PTR(result);
1104	}
1105
1106	/* sys I/F */
1107	if (type) {
1108		result = device_create_file(&tz->device, &dev_attr_type);
1109		if (result)
1110			goto unregister;
1111	}
1112
1113	result = device_create_file(&tz->device, &dev_attr_temp);
1114	if (result)
1115		goto unregister;
1116
1117	if (ops->get_mode) {
1118		result = device_create_file(&tz->device, &dev_attr_mode);
1119		if (result)
1120			goto unregister;
1121	}
1122
1123	for (count = 0; count < trips; count++) {
1124		TRIP_POINT_ATTR_ADD(&tz->device, count, result);
1125		if (result)
1126			goto unregister;
1127		tz->ops->get_trip_type(tz, count, &trip_type);
1128		if (trip_type == THERMAL_TRIP_PASSIVE)
1129			passive = 1;
1130	}
1131
1132	if (!passive)
1133		result = device_create_file(&tz->device,
1134					    &dev_attr_passive);
1135
1136	if (result)
1137		goto unregister;
1138
1139	result = thermal_add_hwmon_sysfs(tz);
1140	if (result)
1141		goto unregister;
1142
1143	mutex_lock(&thermal_list_lock);
1144	list_add_tail(&tz->node, &thermal_tz_list);
1145	if (ops->bind)
1146		list_for_each_entry(pos, &thermal_cdev_list, node) {
1147		result = ops->bind(tz, pos);
1148		if (result)
1149			break;
1150		}
1151	mutex_unlock(&thermal_list_lock);
1152
1153	INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check);
1154
1155	thermal_zone_device_update(tz);
1156
1157	if (!result)
1158		return tz;
1159
1160      unregister:
1161	release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id);
1162	device_unregister(&tz->device);
1163	return ERR_PTR(result);
1164}
1165
1166EXPORT_SYMBOL(thermal_zone_device_register);
1167
1168/**
1169 * thermal_device_unregister - removes the registered thermal zone device
1170 * @tz: the thermal zone device to remove
1171 */
1172void thermal_zone_device_unregister(struct thermal_zone_device *tz)
1173{
1174	struct thermal_cooling_device *cdev;
1175	struct thermal_zone_device *pos = NULL;
1176	int count;
1177
1178	if (!tz)
1179		return;
1180
1181	mutex_lock(&thermal_list_lock);
1182	list_for_each_entry(pos, &thermal_tz_list, node)
1183	    if (pos == tz)
1184		break;
1185	if (pos != tz) {
1186		/* thermal zone device not found */
1187		mutex_unlock(&thermal_list_lock);
1188		return;
1189	}
1190	list_del(&tz->node);
1191	if (tz->ops->unbind)
1192		list_for_each_entry(cdev, &thermal_cdev_list, node)
1193		    tz->ops->unbind(tz, cdev);
1194	mutex_unlock(&thermal_list_lock);
1195
1196	thermal_zone_device_set_polling(tz, 0);
1197
1198	if (tz->type[0])
1199		device_remove_file(&tz->device, &dev_attr_type);
1200	device_remove_file(&tz->device, &dev_attr_temp);
1201	if (tz->ops->get_mode)
1202		device_remove_file(&tz->device, &dev_attr_mode);
1203
1204	for (count = 0; count < tz->trips; count++)
1205		TRIP_POINT_ATTR_REMOVE(&tz->device, count);
1206
1207	thermal_remove_hwmon_sysfs(tz);
1208	release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id);
1209	idr_destroy(&tz->idr);
1210	mutex_destroy(&tz->lock);
1211	device_unregister(&tz->device);
1212	return;
1213}
1214
1215EXPORT_SYMBOL(thermal_zone_device_unregister);
1216
1217static int __init thermal_init(void)
1218{
1219	int result = 0;
1220
1221	result = class_register(&thermal_class);
1222	if (result) {
1223		idr_destroy(&thermal_tz_idr);
1224		idr_destroy(&thermal_cdev_idr);
1225		mutex_destroy(&thermal_idr_lock);
1226		mutex_destroy(&thermal_list_lock);
1227	}
1228	return result;
1229}
1230
1231static void __exit thermal_exit(void)
1232{
1233	class_unregister(&thermal_class);
1234	idr_destroy(&thermal_tz_idr);
1235	idr_destroy(&thermal_cdev_idr);
1236	mutex_destroy(&thermal_idr_lock);
1237	mutex_destroy(&thermal_list_lock);
1238}
1239
1240subsys_initcall(thermal_init);
1241module_exit(thermal_exit);
1242