2 * thermal.c - Generic Thermal Management Sysfs support.
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>
8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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.
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.
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.
23 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26 #include <linux/module.h>
27 #include <linux/device.h>
28 #include <linux/err.h>
29 #include <linux/kdev_t.h>
30 #include <linux/idr.h>
31 #include <linux/thermal.h>
32 #include <linux/spinlock.h>
33 #include <linux/hwmon.h>
34 #include <linux/hwmon-sysfs.h>
36 MODULE_AUTHOR("Zhang Rui");
37 MODULE_DESCRIPTION("Generic thermal management sysfs support");
38 MODULE_LICENSE("GPL");
40 #define PREFIX "Thermal: "
42 struct thermal_cooling_device_instance
{
44 char name
[THERMAL_NAME_LENGTH
];
45 struct thermal_zone_device
*tz
;
46 struct thermal_cooling_device
*cdev
;
48 char attr_name
[THERMAL_NAME_LENGTH
];
49 struct device_attribute attr
;
50 struct list_head node
;
53 static DEFINE_IDR(thermal_tz_idr
);
54 static DEFINE_IDR(thermal_cdev_idr
);
55 static DEFINE_MUTEX(thermal_idr_lock
);
57 static LIST_HEAD(thermal_tz_list
);
58 static LIST_HEAD(thermal_cdev_list
);
59 static DEFINE_MUTEX(thermal_list_lock
);
61 static struct device
*thermal_hwmon
;
62 #define MAX_THERMAL_ZONES 10
64 static int get_idr(struct idr
*idr
, struct mutex
*lock
, int *id
)
69 if (unlikely(idr_pre_get(idr
, GFP_KERNEL
) == 0))
74 err
= idr_get_new(idr
, NULL
, id
);
77 if (unlikely(err
== -EAGAIN
))
79 else if (unlikely(err
))
82 *id
= *id
& MAX_ID_MASK
;
86 static void release_idr(struct idr
*idr
, struct mutex
*lock
, int id
)
97 name_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
99 return sprintf(buf
, "thermal_sys_class\n");
103 temp_input_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
105 struct thermal_zone_device
*tz
;
106 struct sensor_device_attribute
*sensor_attr
107 = to_sensor_dev_attr(attr
);
109 list_for_each_entry(tz
, &thermal_tz_list
, node
)
110 if (tz
->id
== sensor_attr
->index
)
111 return tz
->ops
->get_temp(tz
, buf
);
117 temp_crit_show(struct device
*dev
, struct device_attribute
*attr
,
120 struct thermal_zone_device
*tz
;
121 struct sensor_device_attribute
*sensor_attr
122 = to_sensor_dev_attr(attr
);
124 list_for_each_entry(tz
, &thermal_tz_list
, node
)
125 if (tz
->id
== sensor_attr
->index
)
126 return tz
->ops
->get_trip_temp(tz
, 0, buf
);
131 static DEVICE_ATTR(name
, 0444, name_show
, NULL
);
132 static struct sensor_device_attribute sensor_attrs
[] = {
133 SENSOR_ATTR(temp1_input
, 0444, temp_input_show
, NULL
, 0),
134 SENSOR_ATTR(temp1_crit
, 0444, temp_crit_show
, NULL
, 0),
135 SENSOR_ATTR(temp2_input
, 0444, temp_input_show
, NULL
, 1),
136 SENSOR_ATTR(temp2_crit
, 0444, temp_crit_show
, NULL
, 1),
137 SENSOR_ATTR(temp3_input
, 0444, temp_input_show
, NULL
, 2),
138 SENSOR_ATTR(temp3_crit
, 0444, temp_crit_show
, NULL
, 2),
139 SENSOR_ATTR(temp4_input
, 0444, temp_input_show
, NULL
, 3),
140 SENSOR_ATTR(temp4_crit
, 0444, temp_crit_show
, NULL
, 3),
141 SENSOR_ATTR(temp5_input
, 0444, temp_input_show
, NULL
, 4),
142 SENSOR_ATTR(temp5_crit
, 0444, temp_crit_show
, NULL
, 4),
143 SENSOR_ATTR(temp6_input
, 0444, temp_input_show
, NULL
, 5),
144 SENSOR_ATTR(temp6_crit
, 0444, temp_crit_show
, NULL
, 5),
145 SENSOR_ATTR(temp7_input
, 0444, temp_input_show
, NULL
, 6),
146 SENSOR_ATTR(temp7_crit
, 0444, temp_crit_show
, NULL
, 6),
147 SENSOR_ATTR(temp8_input
, 0444, temp_input_show
, NULL
, 7),
148 SENSOR_ATTR(temp8_crit
, 0444, temp_crit_show
, NULL
, 7),
149 SENSOR_ATTR(temp9_input
, 0444, temp_input_show
, NULL
, 8),
150 SENSOR_ATTR(temp9_crit
, 0444, temp_crit_show
, NULL
, 8),
151 SENSOR_ATTR(temp10_input
, 0444, temp_input_show
, NULL
, 9),
152 SENSOR_ATTR(temp10_crit
, 0444, temp_crit_show
, NULL
, 9),
155 /* thermal zone sys I/F */
157 #define to_thermal_zone(_dev) \
158 container_of(_dev, struct thermal_zone_device, device)
161 type_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
163 struct thermal_zone_device
*tz
= to_thermal_zone(dev
);
165 return sprintf(buf
, "%s\n", tz
->type
);
169 temp_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
171 struct thermal_zone_device
*tz
= to_thermal_zone(dev
);
173 if (!tz
->ops
->get_temp
)
176 return tz
->ops
->get_temp(tz
, buf
);
180 mode_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
182 struct thermal_zone_device
*tz
= to_thermal_zone(dev
);
184 if (!tz
->ops
->get_mode
)
187 return tz
->ops
->get_mode(tz
, buf
);
191 mode_store(struct device
*dev
, struct device_attribute
*attr
,
192 const char *buf
, size_t count
)
194 struct thermal_zone_device
*tz
= to_thermal_zone(dev
);
197 if (!tz
->ops
->set_mode
)
200 result
= tz
->ops
->set_mode(tz
, buf
);
208 trip_point_type_show(struct device
*dev
, struct device_attribute
*attr
,
211 struct thermal_zone_device
*tz
= to_thermal_zone(dev
);
214 if (!tz
->ops
->get_trip_type
)
217 if (!sscanf(attr
->attr
.name
, "trip_point_%d_type", &trip
))
220 return tz
->ops
->get_trip_type(tz
, trip
, buf
);
224 trip_point_temp_show(struct device
*dev
, struct device_attribute
*attr
,
227 struct thermal_zone_device
*tz
= to_thermal_zone(dev
);
230 if (!tz
->ops
->get_trip_temp
)
233 if (!sscanf(attr
->attr
.name
, "trip_point_%d_temp", &trip
))
236 return tz
->ops
->get_trip_temp(tz
, trip
, buf
);
239 static DEVICE_ATTR(type
, 0444, type_show
, NULL
);
240 static DEVICE_ATTR(temp
, 0444, temp_show
, NULL
);
241 static DEVICE_ATTR(mode
, 0644, mode_show
, mode_store
);
243 static struct device_attribute trip_point_attrs
[] = {
244 __ATTR(trip_point_0_type
, 0444, trip_point_type_show
, NULL
),
245 __ATTR(trip_point_0_temp
, 0444, trip_point_temp_show
, NULL
),
246 __ATTR(trip_point_1_type
, 0444, trip_point_type_show
, NULL
),
247 __ATTR(trip_point_1_temp
, 0444, trip_point_temp_show
, NULL
),
248 __ATTR(trip_point_2_type
, 0444, trip_point_type_show
, NULL
),
249 __ATTR(trip_point_2_temp
, 0444, trip_point_temp_show
, NULL
),
250 __ATTR(trip_point_3_type
, 0444, trip_point_type_show
, NULL
),
251 __ATTR(trip_point_3_temp
, 0444, trip_point_temp_show
, NULL
),
252 __ATTR(trip_point_4_type
, 0444, trip_point_type_show
, NULL
),
253 __ATTR(trip_point_4_temp
, 0444, trip_point_temp_show
, NULL
),
254 __ATTR(trip_point_5_type
, 0444, trip_point_type_show
, NULL
),
255 __ATTR(trip_point_5_temp
, 0444, trip_point_temp_show
, NULL
),
256 __ATTR(trip_point_6_type
, 0444, trip_point_type_show
, NULL
),
257 __ATTR(trip_point_6_temp
, 0444, trip_point_temp_show
, NULL
),
258 __ATTR(trip_point_7_type
, 0444, trip_point_type_show
, NULL
),
259 __ATTR(trip_point_7_temp
, 0444, trip_point_temp_show
, NULL
),
260 __ATTR(trip_point_8_type
, 0444, trip_point_type_show
, NULL
),
261 __ATTR(trip_point_8_temp
, 0444, trip_point_temp_show
, NULL
),
262 __ATTR(trip_point_9_type
, 0444, trip_point_type_show
, NULL
),
263 __ATTR(trip_point_9_temp
, 0444, trip_point_temp_show
, NULL
),
266 #define TRIP_POINT_ATTR_ADD(_dev, _index, result) \
268 result = device_create_file(_dev, \
269 &trip_point_attrs[_index * 2]); \
272 result = device_create_file(_dev, \
273 &trip_point_attrs[_index * 2 + 1]); \
276 #define TRIP_POINT_ATTR_REMOVE(_dev, _index) \
278 device_remove_file(_dev, &trip_point_attrs[_index * 2]); \
279 device_remove_file(_dev, &trip_point_attrs[_index * 2 + 1]); \
282 /* cooling device sys I/F */
283 #define to_cooling_device(_dev) \
284 container_of(_dev, struct thermal_cooling_device, device)
287 thermal_cooling_device_type_show(struct device
*dev
,
288 struct device_attribute
*attr
, char *buf
)
290 struct thermal_cooling_device
*cdev
= to_cooling_device(dev
);
292 return sprintf(buf
, "%s\n", cdev
->type
);
296 thermal_cooling_device_max_state_show(struct device
*dev
,
297 struct device_attribute
*attr
, char *buf
)
299 struct thermal_cooling_device
*cdev
= to_cooling_device(dev
);
301 return cdev
->ops
->get_max_state(cdev
, buf
);
305 thermal_cooling_device_cur_state_show(struct device
*dev
,
306 struct device_attribute
*attr
, char *buf
)
308 struct thermal_cooling_device
*cdev
= to_cooling_device(dev
);
310 return cdev
->ops
->get_cur_state(cdev
, buf
);
314 thermal_cooling_device_cur_state_store(struct device
*dev
,
315 struct device_attribute
*attr
,
316 const char *buf
, size_t count
)
318 struct thermal_cooling_device
*cdev
= to_cooling_device(dev
);
322 if (!sscanf(buf
, "%d\n", &state
))
328 result
= cdev
->ops
->set_cur_state(cdev
, state
);
334 static struct device_attribute dev_attr_cdev_type
=
335 __ATTR(type
, 0444, thermal_cooling_device_type_show
, NULL
);
336 static DEVICE_ATTR(max_state
, 0444,
337 thermal_cooling_device_max_state_show
, NULL
);
338 static DEVICE_ATTR(cur_state
, 0644,
339 thermal_cooling_device_cur_state_show
,
340 thermal_cooling_device_cur_state_store
);
343 thermal_cooling_device_trip_point_show(struct device
*dev
,
344 struct device_attribute
*attr
, char *buf
)
346 struct thermal_cooling_device_instance
*instance
;
349 container_of(attr
, struct thermal_cooling_device_instance
, attr
);
351 if (instance
->trip
== THERMAL_TRIPS_NONE
)
352 return sprintf(buf
, "-1\n");
354 return sprintf(buf
, "%d\n", instance
->trip
);
357 /* Device management */
360 * thermal_zone_bind_cooling_device - bind a cooling device to a thermal zone
361 * @tz: thermal zone device
362 * @trip: indicates which trip point the cooling devices is
363 * associated with in this thermal zone.
364 * @cdev: thermal cooling device
366 * This function is usually called in the thermal zone device .bind callback.
368 int thermal_zone_bind_cooling_device(struct thermal_zone_device
*tz
,
370 struct thermal_cooling_device
*cdev
)
372 struct thermal_cooling_device_instance
*dev
;
373 struct thermal_cooling_device_instance
*pos
;
374 struct thermal_zone_device
*pos1
;
375 struct thermal_cooling_device
*pos2
;
378 if (trip
>= tz
->trips
|| (trip
< 0 && trip
!= THERMAL_TRIPS_NONE
))
381 list_for_each_entry(pos1
, &thermal_tz_list
, node
) {
385 list_for_each_entry(pos2
, &thermal_cdev_list
, node
) {
390 if (tz
!= pos1
|| cdev
!= pos2
)
394 kzalloc(sizeof(struct thermal_cooling_device_instance
), GFP_KERNEL
);
400 result
= get_idr(&tz
->idr
, &tz
->lock
, &dev
->id
);
404 sprintf(dev
->name
, "cdev%d", dev
->id
);
406 sysfs_create_link(&tz
->device
.kobj
, &cdev
->device
.kobj
, dev
->name
);
410 sprintf(dev
->attr_name
, "cdev%d_trip_point", dev
->id
);
411 dev
->attr
.attr
.name
= dev
->attr_name
;
412 dev
->attr
.attr
.mode
= 0444;
413 dev
->attr
.show
= thermal_cooling_device_trip_point_show
;
414 result
= device_create_file(&tz
->device
, &dev
->attr
);
416 goto remove_symbol_link
;
418 mutex_lock(&tz
->lock
);
419 list_for_each_entry(pos
, &tz
->cooling_devices
, node
)
420 if (pos
->tz
== tz
&& pos
->trip
== trip
&& pos
->cdev
== cdev
) {
425 list_add_tail(&dev
->node
, &tz
->cooling_devices
);
426 mutex_unlock(&tz
->lock
);
431 device_remove_file(&tz
->device
, &dev
->attr
);
433 sysfs_remove_link(&tz
->device
.kobj
, dev
->name
);
435 release_idr(&tz
->idr
, &tz
->lock
, dev
->id
);
441 EXPORT_SYMBOL(thermal_zone_bind_cooling_device
);
444 * thermal_zone_unbind_cooling_device - unbind a cooling device from a thermal zone
445 * @tz: thermal zone device
446 * @trip: indicates which trip point the cooling devices is
447 * associated with in this thermal zone.
448 * @cdev: thermal cooling device
450 * This function is usually called in the thermal zone device .unbind callback.
452 int thermal_zone_unbind_cooling_device(struct thermal_zone_device
*tz
,
454 struct thermal_cooling_device
*cdev
)
456 struct thermal_cooling_device_instance
*pos
, *next
;
458 mutex_lock(&tz
->lock
);
459 list_for_each_entry_safe(pos
, next
, &tz
->cooling_devices
, node
) {
460 if (pos
->tz
== tz
&& pos
->trip
== trip
&& pos
->cdev
== cdev
) {
461 list_del(&pos
->node
);
462 mutex_unlock(&tz
->lock
);
466 mutex_unlock(&tz
->lock
);
471 device_remove_file(&tz
->device
, &pos
->attr
);
472 sysfs_remove_link(&tz
->device
.kobj
, pos
->name
);
473 release_idr(&tz
->idr
, &tz
->lock
, pos
->id
);
478 EXPORT_SYMBOL(thermal_zone_unbind_cooling_device
);
480 static void thermal_release(struct device
*dev
)
482 struct thermal_zone_device
*tz
;
483 struct thermal_cooling_device
*cdev
;
485 if (!strncmp(dev
->bus_id
, "thermal_zone", sizeof "thermal_zone" - 1)) {
486 tz
= to_thermal_zone(dev
);
489 cdev
= to_cooling_device(dev
);
494 static struct class thermal_class
= {
496 .dev_release
= thermal_release
,
500 * thermal_cooling_device_register - register a new thermal cooling device
501 * @type: the thermal cooling device type.
502 * @devdata: device private data.
503 * @ops: standard thermal cooling devices callbacks.
505 struct thermal_cooling_device
*thermal_cooling_device_register(char *type
,
508 thermal_cooling_device_ops
511 struct thermal_cooling_device
*cdev
;
512 struct thermal_zone_device
*pos
;
516 return ERR_PTR(-EINVAL
);
518 if (strlen(type
) >= THERMAL_NAME_LENGTH
)
519 return ERR_PTR(-EINVAL
);
521 if (!ops
|| !ops
->get_max_state
|| !ops
->get_cur_state
||
523 return ERR_PTR(-EINVAL
);
525 cdev
= kzalloc(sizeof(struct thermal_cooling_device
), GFP_KERNEL
);
527 return ERR_PTR(-ENOMEM
);
529 result
= get_idr(&thermal_cdev_idr
, &thermal_idr_lock
, &cdev
->id
);
532 return ERR_PTR(result
);
535 strcpy(cdev
->type
, type
);
537 cdev
->device
.class = &thermal_class
;
538 cdev
->devdata
= devdata
;
539 sprintf(cdev
->device
.bus_id
, "cooling_device%d", cdev
->id
);
540 result
= device_register(&cdev
->device
);
542 release_idr(&thermal_cdev_idr
, &thermal_idr_lock
, cdev
->id
);
544 return ERR_PTR(result
);
548 result
= device_create_file(&cdev
->device
, &dev_attr_cdev_type
);
552 result
= device_create_file(&cdev
->device
, &dev_attr_max_state
);
556 result
= device_create_file(&cdev
->device
, &dev_attr_cur_state
);
560 mutex_lock(&thermal_list_lock
);
561 list_add(&cdev
->node
, &thermal_cdev_list
);
562 list_for_each_entry(pos
, &thermal_tz_list
, node
) {
565 result
= pos
->ops
->bind(pos
, cdev
);
570 mutex_unlock(&thermal_list_lock
);
576 release_idr(&thermal_cdev_idr
, &thermal_idr_lock
, cdev
->id
);
577 device_unregister(&cdev
->device
);
578 return ERR_PTR(result
);
581 EXPORT_SYMBOL(thermal_cooling_device_register
);
584 * thermal_cooling_device_unregister - removes the registered thermal cooling device
585 * @cdev: the thermal cooling device to remove.
587 * thermal_cooling_device_unregister() must be called when the device is no
590 void thermal_cooling_device_unregister(struct
591 thermal_cooling_device
594 struct thermal_zone_device
*tz
;
595 struct thermal_cooling_device
*pos
= NULL
;
600 mutex_lock(&thermal_list_lock
);
601 list_for_each_entry(pos
, &thermal_cdev_list
, node
)
605 /* thermal cooling device not found */
606 mutex_unlock(&thermal_list_lock
);
609 list_del(&cdev
->node
);
610 list_for_each_entry(tz
, &thermal_tz_list
, node
) {
611 if (!tz
->ops
->unbind
)
613 tz
->ops
->unbind(tz
, cdev
);
615 mutex_unlock(&thermal_list_lock
);
617 device_remove_file(&cdev
->device
, &dev_attr_cdev_type
);
618 device_remove_file(&cdev
->device
, &dev_attr_max_state
);
619 device_remove_file(&cdev
->device
, &dev_attr_cur_state
);
621 release_idr(&thermal_cdev_idr
, &thermal_idr_lock
, cdev
->id
);
622 device_unregister(&cdev
->device
);
626 EXPORT_SYMBOL(thermal_cooling_device_unregister
);
629 * thermal_zone_device_register - register a new thermal zone device
630 * @type: the thermal zone device type
631 * @trips: the number of trip points the thermal zone support
632 * @devdata: private device data
633 * @ops: standard thermal zone device callbacks
635 * thermal_zone_device_unregister() must be called when the device is no
638 struct thermal_zone_device
*thermal_zone_device_register(char *type
,
640 void *devdata
, struct
641 thermal_zone_device_ops
644 struct thermal_zone_device
*tz
;
645 struct thermal_cooling_device
*pos
;
650 return ERR_PTR(-EINVAL
);
652 if (strlen(type
) >= THERMAL_NAME_LENGTH
)
653 return ERR_PTR(-EINVAL
);
655 if (trips
> THERMAL_MAX_TRIPS
|| trips
< 0)
656 return ERR_PTR(-EINVAL
);
658 if (!ops
|| !ops
->get_temp
)
659 return ERR_PTR(-EINVAL
);
661 tz
= kzalloc(sizeof(struct thermal_zone_device
), GFP_KERNEL
);
663 return ERR_PTR(-ENOMEM
);
665 INIT_LIST_HEAD(&tz
->cooling_devices
);
667 mutex_init(&tz
->lock
);
668 result
= get_idr(&thermal_tz_idr
, &thermal_idr_lock
, &tz
->id
);
671 return ERR_PTR(result
);
673 if (tz
->id
>= MAX_THERMAL_ZONES
) {
674 printk(KERN_ERR PREFIX
675 "Too many thermal zones\n");
676 release_idr(&thermal_tz_idr
, &thermal_idr_lock
, tz
->id
);
678 return ERR_PTR(-EINVAL
);
681 strcpy(tz
->type
, type
);
683 tz
->device
.class = &thermal_class
;
684 tz
->devdata
= devdata
;
686 sprintf(tz
->device
.bus_id
, "thermal_zone%d", tz
->id
);
687 result
= device_register(&tz
->device
);
689 release_idr(&thermal_tz_idr
, &thermal_idr_lock
, tz
->id
);
691 return ERR_PTR(result
);
695 result
= device_create_file(thermal_hwmon
,
696 &sensor_attrs
[tz
->id
* 2].dev_attr
);
702 result
= tz
->ops
->get_trip_type(tz
, 0, buf
);
703 if (result
> 0 && !strcmp(buf
, "critical\n")) {
704 result
= device_create_file(thermal_hwmon
,
705 &sensor_attrs
[tz
->id
* 2 + 1].dev_attr
);
712 result
= device_create_file(&tz
->device
, &dev_attr_type
);
716 result
= device_create_file(&tz
->device
, &dev_attr_temp
);
721 result
= device_create_file(&tz
->device
, &dev_attr_mode
);
726 for (count
= 0; count
< trips
; count
++) {
727 TRIP_POINT_ATTR_ADD(&tz
->device
, count
, result
);
732 mutex_lock(&thermal_list_lock
);
733 list_add_tail(&tz
->node
, &thermal_tz_list
);
735 list_for_each_entry(pos
, &thermal_cdev_list
, node
) {
736 result
= ops
->bind(tz
, pos
);
740 mutex_unlock(&thermal_list_lock
);
746 release_idr(&thermal_tz_idr
, &thermal_idr_lock
, tz
->id
);
747 device_unregister(&tz
->device
);
748 return ERR_PTR(result
);
751 EXPORT_SYMBOL(thermal_zone_device_register
);
754 * thermal_device_unregister - removes the registered thermal zone device
755 * @tz: the thermal zone device to remove
757 void thermal_zone_device_unregister(struct thermal_zone_device
*tz
)
759 struct thermal_cooling_device
*cdev
;
760 struct thermal_zone_device
*pos
= NULL
;
766 mutex_lock(&thermal_list_lock
);
767 list_for_each_entry(pos
, &thermal_tz_list
, node
)
771 /* thermal zone device not found */
772 mutex_unlock(&thermal_list_lock
);
777 list_for_each_entry(cdev
, &thermal_cdev_list
, node
)
778 tz
->ops
->unbind(tz
, cdev
);
779 mutex_unlock(&thermal_list_lock
);
781 device_remove_file(thermal_hwmon
,
782 &sensor_attrs
[tz
->id
* 2].dev_attr
);
785 if (tz
->ops
->get_trip_type(tz
, 0, buf
) > 0)
786 if (!strcmp(buf
, "critical\n"))
787 device_remove_file(thermal_hwmon
,
788 &sensor_attrs
[tz
->id
* 2 + 1].dev_attr
);
791 device_remove_file(&tz
->device
, &dev_attr_type
);
792 device_remove_file(&tz
->device
, &dev_attr_temp
);
793 if (tz
->ops
->get_mode
)
794 device_remove_file(&tz
->device
, &dev_attr_mode
);
796 for (count
= 0; count
< tz
->trips
; count
++)
797 TRIP_POINT_ATTR_REMOVE(&tz
->device
, count
);
799 release_idr(&thermal_tz_idr
, &thermal_idr_lock
, tz
->id
);
800 idr_destroy(&tz
->idr
);
801 mutex_destroy(&tz
->lock
);
802 device_unregister(&tz
->device
);
806 EXPORT_SYMBOL(thermal_zone_device_unregister
);
808 static void thermal_exit(void)
811 device_remove_file(thermal_hwmon
, &dev_attr_name
);
812 hwmon_device_unregister(thermal_hwmon
);
814 class_unregister(&thermal_class
);
815 idr_destroy(&thermal_tz_idr
);
816 idr_destroy(&thermal_cdev_idr
);
817 mutex_destroy(&thermal_idr_lock
);
818 mutex_destroy(&thermal_list_lock
);
821 static int __init
thermal_init(void)
825 result
= class_register(&thermal_class
);
827 idr_destroy(&thermal_tz_idr
);
828 idr_destroy(&thermal_cdev_idr
);
829 mutex_destroy(&thermal_idr_lock
);
830 mutex_destroy(&thermal_list_lock
);
833 thermal_hwmon
= hwmon_device_register(NULL
);
834 if (IS_ERR(thermal_hwmon
)) {
835 result
= PTR_ERR(thermal_hwmon
);
836 thermal_hwmon
= NULL
;
837 printk(KERN_ERR PREFIX
838 "unable to register hwmon device\n");
843 result
= device_create_file(thermal_hwmon
, &dev_attr_name
);
848 subsys_initcall(thermal_init
);
849 module_exit(thermal_exit
);