diff options
Diffstat (limited to 'drivers/thermal')
-rw-r--r-- | drivers/thermal/Kconfig | 1 | ||||
-rw-r--r-- | drivers/thermal/thermal.c | 169 |
2 files changed, 26 insertions, 144 deletions
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 3ab313ed441c..69f19f224875 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig | |||
@@ -4,7 +4,6 @@ | |||
4 | 4 | ||
5 | menuconfig THERMAL | 5 | menuconfig THERMAL |
6 | bool "Generic Thermal sysfs driver" | 6 | bool "Generic Thermal sysfs driver" |
7 | select HWMON | ||
8 | default y | 7 | default y |
9 | help | 8 | help |
10 | Generic Thermal Sysfs driver offers a generic mechanism for | 9 | Generic Thermal Sysfs driver offers a generic mechanism for |
diff --git a/drivers/thermal/thermal.c b/drivers/thermal/thermal.c index 41bd4c805ace..8b86e53ccf7a 100644 --- a/drivers/thermal/thermal.c +++ b/drivers/thermal/thermal.c | |||
@@ -30,10 +30,8 @@ | |||
30 | #include <linux/idr.h> | 30 | #include <linux/idr.h> |
31 | #include <linux/thermal.h> | 31 | #include <linux/thermal.h> |
32 | #include <linux/spinlock.h> | 32 | #include <linux/spinlock.h> |
33 | #include <linux/hwmon.h> | ||
34 | #include <linux/hwmon-sysfs.h> | ||
35 | 33 | ||
36 | MODULE_AUTHOR("Zhang Rui"); | 34 | MODULE_AUTHOR("Zhang Rui") |
37 | MODULE_DESCRIPTION("Generic thermal management sysfs support"); | 35 | MODULE_DESCRIPTION("Generic thermal management sysfs support"); |
38 | MODULE_LICENSE("GPL"); | 36 | MODULE_LICENSE("GPL"); |
39 | 37 | ||
@@ -58,9 +56,6 @@ static LIST_HEAD(thermal_tz_list); | |||
58 | static LIST_HEAD(thermal_cdev_list); | 56 | static LIST_HEAD(thermal_cdev_list); |
59 | static DEFINE_MUTEX(thermal_list_lock); | 57 | static DEFINE_MUTEX(thermal_list_lock); |
60 | 58 | ||
61 | static struct device *thermal_hwmon; | ||
62 | #define MAX_THERMAL_ZONES 10 | ||
63 | |||
64 | static int get_idr(struct idr *idr, struct mutex *lock, int *id) | 59 | static int get_idr(struct idr *idr, struct mutex *lock, int *id) |
65 | { | 60 | { |
66 | int err; | 61 | int err; |
@@ -92,67 +87,7 @@ static void release_idr(struct idr *idr, struct mutex *lock, int id) | |||
92 | mutex_unlock(lock); | 87 | mutex_unlock(lock); |
93 | } | 88 | } |
94 | 89 | ||
95 | /* hwmon sys I/F*/ | 90 | /* sys I/F for thermal zone */ |
96 | static ssize_t | ||
97 | name_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
98 | { | ||
99 | return sprintf(buf, "thermal_sys_class\n"); | ||
100 | } | ||
101 | |||
102 | static ssize_t | ||
103 | temp_input_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
104 | { | ||
105 | struct thermal_zone_device *tz; | ||
106 | struct sensor_device_attribute *sensor_attr | ||
107 | = to_sensor_dev_attr(attr); | ||
108 | |||
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); | ||
112 | |||
113 | return -ENODEV; | ||
114 | } | ||
115 | |||
116 | static ssize_t | ||
117 | temp_crit_show(struct device *dev, struct device_attribute *attr, | ||
118 | char *buf) | ||
119 | { | ||
120 | struct thermal_zone_device *tz; | ||
121 | struct sensor_device_attribute *sensor_attr | ||
122 | = to_sensor_dev_attr(attr); | ||
123 | |||
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); | ||
127 | |||
128 | return -ENODEV; | ||
129 | } | ||
130 | |||
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), | ||
153 | }; | ||
154 | |||
155 | /* thermal zone sys I/F */ | ||
156 | 91 | ||
157 | #define to_thermal_zone(_dev) \ | 92 | #define to_thermal_zone(_dev) \ |
158 | container_of(_dev, struct thermal_zone_device, device) | 93 | container_of(_dev, struct thermal_zone_device, device) |
@@ -279,7 +214,7 @@ do { \ | |||
279 | device_remove_file(_dev, &trip_point_attrs[_index * 2 + 1]); \ | 214 | device_remove_file(_dev, &trip_point_attrs[_index * 2 + 1]); \ |
280 | } while (0) | 215 | } while (0) |
281 | 216 | ||
282 | /* cooling device sys I/F */ | 217 | /* sys I/F for cooling device */ |
283 | #define to_cooling_device(_dev) \ | 218 | #define to_cooling_device(_dev) \ |
284 | container_of(_dev, struct thermal_cooling_device, device) | 219 | container_of(_dev, struct thermal_cooling_device, device) |
285 | 220 | ||
@@ -512,9 +447,6 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *type, | |||
512 | struct thermal_zone_device *pos; | 447 | struct thermal_zone_device *pos; |
513 | int result; | 448 | int result; |
514 | 449 | ||
515 | if (!type) | ||
516 | return ERR_PTR(-EINVAL); | ||
517 | |||
518 | if (strlen(type) >= THERMAL_NAME_LENGTH) | 450 | if (strlen(type) >= THERMAL_NAME_LENGTH) |
519 | return ERR_PTR(-EINVAL); | 451 | return ERR_PTR(-EINVAL); |
520 | 452 | ||
@@ -545,9 +477,11 @@ struct thermal_cooling_device *thermal_cooling_device_register(char *type, | |||
545 | } | 477 | } |
546 | 478 | ||
547 | /* sys I/F */ | 479 | /* sys I/F */ |
548 | result = device_create_file(&cdev->device, &dev_attr_cdev_type); | 480 | if (type) { |
549 | if (result) | 481 | result = device_create_file(&cdev->device, &dev_attr_cdev_type); |
550 | goto unregister; | 482 | if (result) |
483 | goto unregister; | ||
484 | } | ||
551 | 485 | ||
552 | result = device_create_file(&cdev->device, &dev_attr_max_state); | 486 | result = device_create_file(&cdev->device, &dev_attr_max_state); |
553 | if (result) | 487 | if (result) |
@@ -613,8 +547,8 @@ void thermal_cooling_device_unregister(struct | |||
613 | tz->ops->unbind(tz, cdev); | 547 | tz->ops->unbind(tz, cdev); |
614 | } | 548 | } |
615 | mutex_unlock(&thermal_list_lock); | 549 | mutex_unlock(&thermal_list_lock); |
616 | 550 | if (cdev->type[0]) | |
617 | device_remove_file(&cdev->device, &dev_attr_cdev_type); | 551 | device_remove_file(&cdev->device, &dev_attr_cdev_type); |
618 | device_remove_file(&cdev->device, &dev_attr_max_state); | 552 | device_remove_file(&cdev->device, &dev_attr_max_state); |
619 | device_remove_file(&cdev->device, &dev_attr_cur_state); | 553 | device_remove_file(&cdev->device, &dev_attr_cur_state); |
620 | 554 | ||
@@ -646,9 +580,6 @@ struct thermal_zone_device *thermal_zone_device_register(char *type, | |||
646 | int result; | 580 | int result; |
647 | int count; | 581 | int count; |
648 | 582 | ||
649 | if (!type) | ||
650 | return ERR_PTR(-EINVAL); | ||
651 | |||
652 | if (strlen(type) >= THERMAL_NAME_LENGTH) | 583 | if (strlen(type) >= THERMAL_NAME_LENGTH) |
653 | return ERR_PTR(-EINVAL); | 584 | return ERR_PTR(-EINVAL); |
654 | 585 | ||
@@ -670,13 +601,6 @@ struct thermal_zone_device *thermal_zone_device_register(char *type, | |||
670 | kfree(tz); | 601 | kfree(tz); |
671 | return ERR_PTR(result); | 602 | return ERR_PTR(result); |
672 | } | 603 | } |
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); | ||
677 | kfree(tz); | ||
678 | return ERR_PTR(-EINVAL); | ||
679 | } | ||
680 | 604 | ||
681 | strcpy(tz->type, type); | 605 | strcpy(tz->type, type); |
682 | tz->ops = ops; | 606 | tz->ops = ops; |
@@ -691,27 +615,12 @@ struct thermal_zone_device *thermal_zone_device_register(char *type, | |||
691 | return ERR_PTR(result); | 615 | return ERR_PTR(result); |
692 | } | 616 | } |
693 | 617 | ||
694 | /* hwmon sys I/F */ | ||
695 | result = device_create_file(thermal_hwmon, | ||
696 | &sensor_attrs[tz->id * 2].dev_attr); | ||
697 | if (result) | ||
698 | goto unregister; | ||
699 | |||
700 | if (trips > 0) { | ||
701 | char buf[40]; | ||
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); | ||
706 | if (result) | ||
707 | goto unregister; | ||
708 | } | ||
709 | } | ||
710 | |||
711 | /* sys I/F */ | 618 | /* sys I/F */ |
712 | result = device_create_file(&tz->device, &dev_attr_type); | 619 | if (type) { |
713 | if (result) | 620 | result = device_create_file(&tz->device, &dev_attr_type); |
714 | goto unregister; | 621 | if (result) |
622 | goto unregister; | ||
623 | } | ||
715 | 624 | ||
716 | result = device_create_file(&tz->device, &dev_attr_temp); | 625 | result = device_create_file(&tz->device, &dev_attr_temp); |
717 | if (result) | 626 | if (result) |
@@ -778,17 +687,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) | |||
778 | tz->ops->unbind(tz, cdev); | 687 | tz->ops->unbind(tz, cdev); |
779 | mutex_unlock(&thermal_list_lock); | 688 | mutex_unlock(&thermal_list_lock); |
780 | 689 | ||
781 | device_remove_file(thermal_hwmon, | 690 | if (tz->type[0]) |
782 | &sensor_attrs[tz->id * 2].dev_attr); | 691 | device_remove_file(&tz->device, &dev_attr_type); |
783 | if (tz->trips > 0) { | ||
784 | char buf[40]; | ||
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); | ||
789 | } | ||
790 | |||
791 | device_remove_file(&tz->device, &dev_attr_type); | ||
792 | device_remove_file(&tz->device, &dev_attr_temp); | 692 | device_remove_file(&tz->device, &dev_attr_temp); |
793 | if (tz->ops->get_mode) | 693 | if (tz->ops->get_mode) |
794 | device_remove_file(&tz->device, &dev_attr_mode); | 694 | device_remove_file(&tz->device, &dev_attr_mode); |
@@ -805,19 +705,6 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) | |||
805 | 705 | ||
806 | EXPORT_SYMBOL(thermal_zone_device_unregister); | 706 | EXPORT_SYMBOL(thermal_zone_device_unregister); |
807 | 707 | ||
808 | static void thermal_exit(void) | ||
809 | { | ||
810 | if (thermal_hwmon) { | ||
811 | device_remove_file(thermal_hwmon, &dev_attr_name); | ||
812 | hwmon_device_unregister(thermal_hwmon); | ||
813 | } | ||
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); | ||
819 | } | ||
820 | |||
821 | static int __init thermal_init(void) | 708 | static int __init thermal_init(void) |
822 | { | 709 | { |
823 | int result = 0; | 710 | int result = 0; |
@@ -829,21 +716,17 @@ static int __init thermal_init(void) | |||
829 | mutex_destroy(&thermal_idr_lock); | 716 | mutex_destroy(&thermal_idr_lock); |
830 | mutex_destroy(&thermal_list_lock); | 717 | mutex_destroy(&thermal_list_lock); |
831 | } | 718 | } |
832 | |||
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"); | ||
839 | thermal_exit(); | ||
840 | return result; | ||
841 | } | ||
842 | |||
843 | result = device_create_file(thermal_hwmon, &dev_attr_name); | ||
844 | |||
845 | return result; | 719 | return result; |
846 | } | 720 | } |
847 | 721 | ||
722 | static void __exit thermal_exit(void) | ||
723 | { | ||
724 | class_unregister(&thermal_class); | ||
725 | idr_destroy(&thermal_tz_idr); | ||
726 | idr_destroy(&thermal_cdev_idr); | ||
727 | mutex_destroy(&thermal_idr_lock); | ||
728 | mutex_destroy(&thermal_list_lock); | ||
729 | } | ||
730 | |||
848 | subsys_initcall(thermal_init); | 731 | subsys_initcall(thermal_init); |
849 | module_exit(thermal_exit); | 732 | module_exit(thermal_exit); |