aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/thermal/thermal_sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/thermal/thermal_sys.c')
-rw-r--r--drivers/thermal/thermal_sys.c94
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");
39MODULE_DESCRIPTION("Generic thermal management sysfs support"); 41MODULE_DESCRIPTION("Generic thermal management sysfs support");
40MODULE_LICENSE("GPL"); 42MODULE_LICENSE("GPL");
41 43
42#define PREFIX "Thermal: "
43
44struct thermal_cooling_device_instance { 44struct 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);
60static LIST_HEAD(thermal_cdev_list); 60static LIST_HEAD(thermal_cdev_list);
61static DEFINE_MUTEX(thermal_list_lock); 61static DEFINE_MUTEX(thermal_list_lock);
62 62
63static unsigned int thermal_event_seqnum;
64
65static int get_idr(struct idr *idr, struct mutex *lock, int *id) 63static int get_idr(struct idr *idr, struct mutex *lock, int *id)
66{ 64{
67 int err; 65 int err;
68 66
69 again: 67again:
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,
283static DEVICE_ATTR(type, 0444, type_show, NULL); 281static DEVICE_ATTR(type, 0444, type_show, NULL);
284static DEVICE_ATTR(temp, 0444, temp_show, NULL); 282static DEVICE_ATTR(temp, 0444, temp_show, NULL);
285static DEVICE_ATTR(mode, 0644, mode_show, mode_store); 283static DEVICE_ATTR(mode, 0644, mode_show, mode_store);
286static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, \ 284static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, passive_store);
287 passive_store);
288 285
289static struct device_attribute trip_point_attrs[] = { 286static 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) \
317do { \
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) \
327do { \
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: 819remove_symbol_link:
839 sysfs_remove_link(&tz->device.kobj, dev->name); 820 sysfs_remove_link(&tz->device.kobj, dev->name);
840 release_idr: 821release_idr:
841 release_idr(&tz->idr, &tz->lock, dev->id); 822 release_idr(&tz->idr, &tz->lock, dev->id);
842 free_mem: 823free_mem:
843 kfree(dev); 824 kfree(dev);
844 return result; 825 return result;
845} 826}
846
847EXPORT_SYMBOL(thermal_zone_bind_cooling_device); 827EXPORT_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: 856unbind:
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
884EXPORT_SYMBOL(thermal_zone_unbind_cooling_device); 863EXPORT_SYMBOL(thermal_zone_unbind_cooling_device);
885 864
886static void thermal_release(struct device *dev) 865static 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 */
911struct thermal_cooling_device *thermal_cooling_device_register( 891struct thermal_cooling_device *
912 char *type, void *devdata, const struct thermal_cooling_device_ops *ops) 892thermal_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: 958unregister:
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
983EXPORT_SYMBOL(thermal_cooling_device_register); 963EXPORT_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
1028EXPORT_SYMBOL(thermal_cooling_device_unregister); 1007EXPORT_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: 1080leave:
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: 1220unregister:
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
1244EXPORT_SYMBOL(thermal_zone_device_register); 1225EXPORT_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
1293EXPORT_SYMBOL(thermal_zone_device_unregister); 1276EXPORT_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}