diff options
Diffstat (limited to 'drivers/thermal/thermal_sys.c')
-rw-r--r-- | drivers/thermal/thermal_sys.c | 94 |
1 files changed, 39 insertions, 55 deletions
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index 220ce7e31cf5..022bacb71a7e 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c | |||
@@ -23,6 +23,8 @@ | |||
23 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 23 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
24 | */ | 24 | */ |
25 | 25 | ||
26 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
27 | |||
26 | #include <linux/module.h> | 28 | #include <linux/module.h> |
27 | #include <linux/device.h> | 29 | #include <linux/device.h> |
28 | #include <linux/err.h> | 30 | #include <linux/err.h> |
@@ -39,8 +41,6 @@ MODULE_AUTHOR("Zhang Rui"); | |||
39 | MODULE_DESCRIPTION("Generic thermal management sysfs support"); | 41 | MODULE_DESCRIPTION("Generic thermal management sysfs support"); |
40 | MODULE_LICENSE("GPL"); | 42 | MODULE_LICENSE("GPL"); |
41 | 43 | ||
42 | #define PREFIX "Thermal: " | ||
43 | |||
44 | struct thermal_cooling_device_instance { | 44 | struct thermal_cooling_device_instance { |
45 | int id; | 45 | int id; |
46 | char name[THERMAL_NAME_LENGTH]; | 46 | char name[THERMAL_NAME_LENGTH]; |
@@ -60,13 +60,11 @@ static LIST_HEAD(thermal_tz_list); | |||
60 | static LIST_HEAD(thermal_cdev_list); | 60 | static LIST_HEAD(thermal_cdev_list); |
61 | static DEFINE_MUTEX(thermal_list_lock); | 61 | static DEFINE_MUTEX(thermal_list_lock); |
62 | 62 | ||
63 | static unsigned int thermal_event_seqnum; | ||
64 | |||
65 | static int get_idr(struct idr *idr, struct mutex *lock, int *id) | 63 | static int get_idr(struct idr *idr, struct mutex *lock, int *id) |
66 | { | 64 | { |
67 | int err; | 65 | int err; |
68 | 66 | ||
69 | again: | 67 | again: |
70 | if (unlikely(idr_pre_get(idr, GFP_KERNEL) == 0)) | 68 | if (unlikely(idr_pre_get(idr, GFP_KERNEL) == 0)) |
71 | return -ENOMEM; | 69 | return -ENOMEM; |
72 | 70 | ||
@@ -152,9 +150,9 @@ mode_store(struct device *dev, struct device_attribute *attr, | |||
152 | if (!tz->ops->set_mode) | 150 | if (!tz->ops->set_mode) |
153 | return -EPERM; | 151 | return -EPERM; |
154 | 152 | ||
155 | if (!strncmp(buf, "enabled", sizeof("enabled"))) | 153 | if (!strncmp(buf, "enabled", sizeof("enabled") - 1)) |
156 | result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED); | 154 | result = tz->ops->set_mode(tz, THERMAL_DEVICE_ENABLED); |
157 | else if (!strncmp(buf, "disabled", sizeof("disabled"))) | 155 | else if (!strncmp(buf, "disabled", sizeof("disabled") - 1)) |
158 | result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED); | 156 | result = tz->ops->set_mode(tz, THERMAL_DEVICE_DISABLED); |
159 | else | 157 | else |
160 | result = -EINVAL; | 158 | result = -EINVAL; |
@@ -283,8 +281,7 @@ passive_show(struct device *dev, struct device_attribute *attr, | |||
283 | static DEVICE_ATTR(type, 0444, type_show, NULL); | 281 | static DEVICE_ATTR(type, 0444, type_show, NULL); |
284 | static DEVICE_ATTR(temp, 0444, temp_show, NULL); | 282 | static DEVICE_ATTR(temp, 0444, temp_show, NULL); |
285 | static DEVICE_ATTR(mode, 0644, mode_show, mode_store); | 283 | static DEVICE_ATTR(mode, 0644, mode_show, mode_store); |
286 | static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, \ | 284 | static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, passive_store); |
287 | passive_store); | ||
288 | 285 | ||
289 | static struct device_attribute trip_point_attrs[] = { | 286 | static struct device_attribute trip_point_attrs[] = { |
290 | __ATTR(trip_point_0_type, 0444, trip_point_type_show, NULL), | 287 | __ATTR(trip_point_0_type, 0444, trip_point_type_show, NULL), |
@@ -313,22 +310,6 @@ static struct device_attribute trip_point_attrs[] = { | |||
313 | __ATTR(trip_point_11_temp, 0444, trip_point_temp_show, NULL), | 310 | __ATTR(trip_point_11_temp, 0444, trip_point_temp_show, NULL), |
314 | }; | 311 | }; |
315 | 312 | ||
316 | #define TRIP_POINT_ATTR_ADD(_dev, _index, result) \ | ||
317 | do { \ | ||
318 | result = device_create_file(_dev, \ | ||
319 | &trip_point_attrs[_index * 2]); \ | ||
320 | if (result) \ | ||
321 | break; \ | ||
322 | result = device_create_file(_dev, \ | ||
323 | &trip_point_attrs[_index * 2 + 1]); \ | ||
324 | } while (0) | ||
325 | |||
326 | #define TRIP_POINT_ATTR_REMOVE(_dev, _index) \ | ||
327 | do { \ | ||
328 | device_remove_file(_dev, &trip_point_attrs[_index * 2]); \ | ||
329 | device_remove_file(_dev, &trip_point_attrs[_index * 2 + 1]); \ | ||
330 | } while (0) | ||
331 | |||
332 | /* sys I/F for cooling device */ | 313 | /* sys I/F for cooling device */ |
333 | #define to_cooling_device(_dev) \ | 314 | #define to_cooling_device(_dev) \ |
334 | container_of(_dev, struct thermal_cooling_device, device) | 315 | container_of(_dev, struct thermal_cooling_device, device) |
@@ -835,15 +816,14 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz, | |||
835 | return 0; | 816 | return 0; |
836 | 817 | ||
837 | device_remove_file(&tz->device, &dev->attr); | 818 | device_remove_file(&tz->device, &dev->attr); |
838 | remove_symbol_link: | 819 | remove_symbol_link: |
839 | sysfs_remove_link(&tz->device.kobj, dev->name); | 820 | sysfs_remove_link(&tz->device.kobj, dev->name); |
840 | release_idr: | 821 | release_idr: |
841 | release_idr(&tz->idr, &tz->lock, dev->id); | 822 | release_idr(&tz->idr, &tz->lock, dev->id); |
842 | free_mem: | 823 | free_mem: |
843 | kfree(dev); | 824 | kfree(dev); |
844 | return result; | 825 | return result; |
845 | } | 826 | } |
846 | |||
847 | EXPORT_SYMBOL(thermal_zone_bind_cooling_device); | 827 | EXPORT_SYMBOL(thermal_zone_bind_cooling_device); |
848 | 828 | ||
849 | /** | 829 | /** |
@@ -873,14 +853,13 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz, | |||
873 | 853 | ||
874 | return -ENODEV; | 854 | return -ENODEV; |
875 | 855 | ||
876 | unbind: | 856 | unbind: |
877 | device_remove_file(&tz->device, &pos->attr); | 857 | device_remove_file(&tz->device, &pos->attr); |
878 | sysfs_remove_link(&tz->device.kobj, pos->name); | 858 | sysfs_remove_link(&tz->device.kobj, pos->name); |
879 | release_idr(&tz->idr, &tz->lock, pos->id); | 859 | release_idr(&tz->idr, &tz->lock, pos->id); |
880 | kfree(pos); | 860 | kfree(pos); |
881 | return 0; | 861 | return 0; |
882 | } | 862 | } |
883 | |||
884 | EXPORT_SYMBOL(thermal_zone_unbind_cooling_device); | 863 | EXPORT_SYMBOL(thermal_zone_unbind_cooling_device); |
885 | 864 | ||
886 | static void thermal_release(struct device *dev) | 865 | static void thermal_release(struct device *dev) |
@@ -888,7 +867,8 @@ static void thermal_release(struct device *dev) | |||
888 | struct thermal_zone_device *tz; | 867 | struct thermal_zone_device *tz; |
889 | struct thermal_cooling_device *cdev; | 868 | struct thermal_cooling_device *cdev; |
890 | 869 | ||
891 | if (!strncmp(dev_name(dev), "thermal_zone", sizeof "thermal_zone" - 1)) { | 870 | if (!strncmp(dev_name(dev), "thermal_zone", |
871 | sizeof("thermal_zone") - 1)) { | ||
892 | tz = to_thermal_zone(dev); | 872 | tz = to_thermal_zone(dev); |
893 | kfree(tz); | 873 | kfree(tz); |
894 | } else { | 874 | } else { |
@@ -908,8 +888,9 @@ static struct class thermal_class = { | |||
908 | * @devdata: device private data. | 888 | * @devdata: device private data. |
909 | * @ops: standard thermal cooling devices callbacks. | 889 | * @ops: standard thermal cooling devices callbacks. |
910 | */ | 890 | */ |
911 | struct thermal_cooling_device *thermal_cooling_device_register( | 891 | struct thermal_cooling_device * |
912 | char *type, void *devdata, const struct thermal_cooling_device_ops *ops) | 892 | thermal_cooling_device_register(char *type, void *devdata, |
893 | const struct thermal_cooling_device_ops *ops) | ||
913 | { | 894 | { |
914 | struct thermal_cooling_device *cdev; | 895 | struct thermal_cooling_device *cdev; |
915 | struct thermal_zone_device *pos; | 896 | struct thermal_zone_device *pos; |
@@ -974,12 +955,11 @@ struct thermal_cooling_device *thermal_cooling_device_register( | |||
974 | if (!result) | 955 | if (!result) |
975 | return cdev; | 956 | return cdev; |
976 | 957 | ||
977 | unregister: | 958 | unregister: |
978 | release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id); | 959 | release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id); |
979 | device_unregister(&cdev->device); | 960 | device_unregister(&cdev->device); |
980 | return ERR_PTR(result); | 961 | return ERR_PTR(result); |
981 | } | 962 | } |
982 | |||
983 | EXPORT_SYMBOL(thermal_cooling_device_register); | 963 | EXPORT_SYMBOL(thermal_cooling_device_register); |
984 | 964 | ||
985 | /** | 965 | /** |
@@ -1024,7 +1004,6 @@ void thermal_cooling_device_unregister(struct | |||
1024 | device_unregister(&cdev->device); | 1004 | device_unregister(&cdev->device); |
1025 | return; | 1005 | return; |
1026 | } | 1006 | } |
1027 | |||
1028 | EXPORT_SYMBOL(thermal_cooling_device_unregister); | 1007 | EXPORT_SYMBOL(thermal_cooling_device_unregister); |
1029 | 1008 | ||
1030 | /** | 1009 | /** |
@@ -1044,8 +1023,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz) | |||
1044 | 1023 | ||
1045 | if (tz->ops->get_temp(tz, &temp)) { | 1024 | if (tz->ops->get_temp(tz, &temp)) { |
1046 | /* get_temp failed - retry it later */ | 1025 | /* get_temp failed - retry it later */ |
1047 | printk(KERN_WARNING PREFIX "failed to read out thermal zone " | 1026 | pr_warn("failed to read out thermal zone %d\n", tz->id); |
1048 | "%d\n", tz->id); | ||
1049 | goto leave; | 1027 | goto leave; |
1050 | } | 1028 | } |
1051 | 1029 | ||
@@ -1060,9 +1038,8 @@ void thermal_zone_device_update(struct thermal_zone_device *tz) | |||
1060 | ret = tz->ops->notify(tz, count, | 1038 | ret = tz->ops->notify(tz, count, |
1061 | trip_type); | 1039 | trip_type); |
1062 | if (!ret) { | 1040 | if (!ret) { |
1063 | printk(KERN_EMERG | 1041 | pr_emerg("Critical temperature reached (%ld C), shutting down\n", |
1064 | "Critical temperature reached (%ld C), shutting down.\n", | 1042 | temp/1000); |
1065 | temp/1000); | ||
1066 | orderly_poweroff(true); | 1043 | orderly_poweroff(true); |
1067 | } | 1044 | } |
1068 | } | 1045 | } |
@@ -1100,7 +1077,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz) | |||
1100 | 1077 | ||
1101 | tz->last_temperature = temp; | 1078 | tz->last_temperature = temp; |
1102 | 1079 | ||
1103 | leave: | 1080 | leave: |
1104 | if (tz->passive) | 1081 | if (tz->passive) |
1105 | thermal_zone_device_set_polling(tz, tz->passive_delay); | 1082 | thermal_zone_device_set_polling(tz, tz->passive_delay); |
1106 | else if (tz->polling_delay) | 1083 | else if (tz->polling_delay) |
@@ -1199,7 +1176,12 @@ struct thermal_zone_device *thermal_zone_device_register(char *type, | |||
1199 | } | 1176 | } |
1200 | 1177 | ||
1201 | for (count = 0; count < trips; count++) { | 1178 | for (count = 0; count < trips; count++) { |
1202 | TRIP_POINT_ATTR_ADD(&tz->device, count, result); | 1179 | result = device_create_file(&tz->device, |
1180 | &trip_point_attrs[count * 2]); | ||
1181 | if (result) | ||
1182 | break; | ||
1183 | result = device_create_file(&tz->device, | ||
1184 | &trip_point_attrs[count * 2 + 1]); | ||
1203 | if (result) | 1185 | if (result) |
1204 | goto unregister; | 1186 | goto unregister; |
1205 | tz->ops->get_trip_type(tz, count, &trip_type); | 1187 | tz->ops->get_trip_type(tz, count, &trip_type); |
@@ -1235,12 +1217,11 @@ struct thermal_zone_device *thermal_zone_device_register(char *type, | |||
1235 | if (!result) | 1217 | if (!result) |
1236 | return tz; | 1218 | return tz; |
1237 | 1219 | ||
1238 | unregister: | 1220 | unregister: |
1239 | release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); | 1221 | release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); |
1240 | device_unregister(&tz->device); | 1222 | device_unregister(&tz->device); |
1241 | return ERR_PTR(result); | 1223 | return ERR_PTR(result); |
1242 | } | 1224 | } |
1243 | |||
1244 | EXPORT_SYMBOL(thermal_zone_device_register); | 1225 | EXPORT_SYMBOL(thermal_zone_device_register); |
1245 | 1226 | ||
1246 | /** | 1227 | /** |
@@ -1279,9 +1260,12 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) | |||
1279 | if (tz->ops->get_mode) | 1260 | if (tz->ops->get_mode) |
1280 | device_remove_file(&tz->device, &dev_attr_mode); | 1261 | device_remove_file(&tz->device, &dev_attr_mode); |
1281 | 1262 | ||
1282 | for (count = 0; count < tz->trips; count++) | 1263 | for (count = 0; count < tz->trips; count++) { |
1283 | TRIP_POINT_ATTR_REMOVE(&tz->device, count); | 1264 | device_remove_file(&tz->device, |
1284 | 1265 | &trip_point_attrs[count * 2]); | |
1266 | device_remove_file(&tz->device, | ||
1267 | &trip_point_attrs[count * 2 + 1]); | ||
1268 | } | ||
1285 | thermal_remove_hwmon_sysfs(tz); | 1269 | thermal_remove_hwmon_sysfs(tz); |
1286 | release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); | 1270 | release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id); |
1287 | idr_destroy(&tz->idr); | 1271 | idr_destroy(&tz->idr); |
@@ -1289,7 +1273,6 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) | |||
1289 | device_unregister(&tz->device); | 1273 | device_unregister(&tz->device); |
1290 | return; | 1274 | return; |
1291 | } | 1275 | } |
1292 | |||
1293 | EXPORT_SYMBOL(thermal_zone_device_unregister); | 1276 | EXPORT_SYMBOL(thermal_zone_device_unregister); |
1294 | 1277 | ||
1295 | #ifdef CONFIG_NET | 1278 | #ifdef CONFIG_NET |
@@ -1312,10 +1295,11 @@ int thermal_generate_netlink_event(u32 orig, enum events event) | |||
1312 | void *msg_header; | 1295 | void *msg_header; |
1313 | int size; | 1296 | int size; |
1314 | int result; | 1297 | int result; |
1298 | static unsigned int thermal_event_seqnum; | ||
1315 | 1299 | ||
1316 | /* allocate memory */ | 1300 | /* allocate memory */ |
1317 | size = nla_total_size(sizeof(struct thermal_genl_event)) + \ | 1301 | size = nla_total_size(sizeof(struct thermal_genl_event)) + |
1318 | nla_total_size(0); | 1302 | nla_total_size(0); |
1319 | 1303 | ||
1320 | skb = genlmsg_new(size, GFP_ATOMIC); | 1304 | skb = genlmsg_new(size, GFP_ATOMIC); |
1321 | if (!skb) | 1305 | if (!skb) |
@@ -1331,8 +1315,8 @@ int thermal_generate_netlink_event(u32 orig, enum events event) | |||
1331 | } | 1315 | } |
1332 | 1316 | ||
1333 | /* fill the data */ | 1317 | /* fill the data */ |
1334 | attr = nla_reserve(skb, THERMAL_GENL_ATTR_EVENT, \ | 1318 | attr = nla_reserve(skb, THERMAL_GENL_ATTR_EVENT, |
1335 | sizeof(struct thermal_genl_event)); | 1319 | sizeof(struct thermal_genl_event)); |
1336 | 1320 | ||
1337 | if (!attr) { | 1321 | if (!attr) { |
1338 | nlmsg_free(skb); | 1322 | nlmsg_free(skb); |
@@ -1359,7 +1343,7 @@ int thermal_generate_netlink_event(u32 orig, enum events event) | |||
1359 | 1343 | ||
1360 | result = genlmsg_multicast(skb, 0, thermal_event_mcgrp.id, GFP_ATOMIC); | 1344 | result = genlmsg_multicast(skb, 0, thermal_event_mcgrp.id, GFP_ATOMIC); |
1361 | if (result) | 1345 | if (result) |
1362 | printk(KERN_INFO "failed to send netlink event:%d", result); | 1346 | pr_info("failed to send netlink event:%d\n", result); |
1363 | 1347 | ||
1364 | return result; | 1348 | return result; |
1365 | } | 1349 | } |