diff options
Diffstat (limited to 'drivers/thermal/thermal_sys.c')
-rw-r--r-- | drivers/thermal/thermal_sys.c | 120 |
1 files changed, 107 insertions, 13 deletions
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index 13c72c62932..7d0e63c7928 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c | |||
@@ -32,6 +32,8 @@ | |||
32 | #include <linux/thermal.h> | 32 | #include <linux/thermal.h> |
33 | #include <linux/spinlock.h> | 33 | #include <linux/spinlock.h> |
34 | #include <linux/reboot.h> | 34 | #include <linux/reboot.h> |
35 | #include <net/netlink.h> | ||
36 | #include <net/genetlink.h> | ||
35 | 37 | ||
36 | MODULE_AUTHOR("Zhang Rui"); | 38 | MODULE_AUTHOR("Zhang Rui"); |
37 | MODULE_DESCRIPTION("Generic thermal management sysfs support"); | 39 | MODULE_DESCRIPTION("Generic thermal management sysfs support"); |
@@ -58,6 +60,22 @@ static LIST_HEAD(thermal_tz_list); | |||
58 | static LIST_HEAD(thermal_cdev_list); | 60 | static LIST_HEAD(thermal_cdev_list); |
59 | static DEFINE_MUTEX(thermal_list_lock); | 61 | static DEFINE_MUTEX(thermal_list_lock); |
60 | 62 | ||
63 | static unsigned int thermal_event_seqnum; | ||
64 | |||
65 | static struct genl_family thermal_event_genl_family = { | ||
66 | .id = GENL_ID_GENERATE, | ||
67 | .name = THERMAL_GENL_FAMILY_NAME, | ||
68 | .version = THERMAL_GENL_VERSION, | ||
69 | .maxattr = THERMAL_GENL_ATTR_MAX, | ||
70 | }; | ||
71 | |||
72 | static struct genl_multicast_group thermal_event_mcgrp = { | ||
73 | .name = THERMAL_GENL_MCAST_GROUP_NAME, | ||
74 | }; | ||
75 | |||
76 | static int genetlink_init(void); | ||
77 | static void genetlink_exit(void); | ||
78 | |||
61 | static int get_idr(struct idr *idr, struct mutex *lock, int *id) | 79 | static int get_idr(struct idr *idr, struct mutex *lock, int *id) |
62 | { | 80 | { |
63 | int err; | 81 | int err; |
@@ -823,11 +841,8 @@ static struct class thermal_class = { | |||
823 | * @devdata: device private data. | 841 | * @devdata: device private data. |
824 | * @ops: standard thermal cooling devices callbacks. | 842 | * @ops: standard thermal cooling devices callbacks. |
825 | */ | 843 | */ |
826 | struct thermal_cooling_device *thermal_cooling_device_register(char *type, | 844 | struct thermal_cooling_device *thermal_cooling_device_register( |
827 | void *devdata, | 845 | char *type, void *devdata, const struct thermal_cooling_device_ops *ops) |
828 | struct | ||
829 | thermal_cooling_device_ops | ||
830 | *ops) | ||
831 | { | 846 | { |
832 | struct thermal_cooling_device *cdev; | 847 | struct thermal_cooling_device *cdev; |
833 | struct thermal_zone_device *pos; | 848 | struct thermal_zone_device *pos; |
@@ -1048,13 +1063,9 @@ EXPORT_SYMBOL(thermal_zone_device_update); | |||
1048 | * section 11.1.5.1 of the ACPI specification 3.0. | 1063 | * section 11.1.5.1 of the ACPI specification 3.0. |
1049 | */ | 1064 | */ |
1050 | struct thermal_zone_device *thermal_zone_device_register(char *type, | 1065 | struct thermal_zone_device *thermal_zone_device_register(char *type, |
1051 | int trips, | 1066 | int trips, void *devdata, |
1052 | void *devdata, struct | 1067 | const struct thermal_zone_device_ops *ops, |
1053 | thermal_zone_device_ops | 1068 | int tc1, int tc2, int passive_delay, int polling_delay) |
1054 | *ops, int tc1, int | ||
1055 | tc2, | ||
1056 | int passive_delay, | ||
1057 | int polling_delay) | ||
1058 | { | 1069 | { |
1059 | struct thermal_zone_device *tz; | 1070 | struct thermal_zone_device *tz; |
1060 | struct thermal_cooling_device *pos; | 1071 | struct thermal_cooling_device *pos; |
@@ -1214,6 +1225,82 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) | |||
1214 | 1225 | ||
1215 | EXPORT_SYMBOL(thermal_zone_device_unregister); | 1226 | EXPORT_SYMBOL(thermal_zone_device_unregister); |
1216 | 1227 | ||
1228 | int generate_netlink_event(u32 orig, enum events event) | ||
1229 | { | ||
1230 | struct sk_buff *skb; | ||
1231 | struct nlattr *attr; | ||
1232 | struct thermal_genl_event *thermal_event; | ||
1233 | void *msg_header; | ||
1234 | int size; | ||
1235 | int result; | ||
1236 | |||
1237 | /* allocate memory */ | ||
1238 | size = nla_total_size(sizeof(struct thermal_genl_event)) + \ | ||
1239 | nla_total_size(0); | ||
1240 | |||
1241 | skb = genlmsg_new(size, GFP_ATOMIC); | ||
1242 | if (!skb) | ||
1243 | return -ENOMEM; | ||
1244 | |||
1245 | /* add the genetlink message header */ | ||
1246 | msg_header = genlmsg_put(skb, 0, thermal_event_seqnum++, | ||
1247 | &thermal_event_genl_family, 0, | ||
1248 | THERMAL_GENL_CMD_EVENT); | ||
1249 | if (!msg_header) { | ||
1250 | nlmsg_free(skb); | ||
1251 | return -ENOMEM; | ||
1252 | } | ||
1253 | |||
1254 | /* fill the data */ | ||
1255 | attr = nla_reserve(skb, THERMAL_GENL_ATTR_EVENT, \ | ||
1256 | sizeof(struct thermal_genl_event)); | ||
1257 | |||
1258 | if (!attr) { | ||
1259 | nlmsg_free(skb); | ||
1260 | return -EINVAL; | ||
1261 | } | ||
1262 | |||
1263 | thermal_event = nla_data(attr); | ||
1264 | if (!thermal_event) { | ||
1265 | nlmsg_free(skb); | ||
1266 | return -EINVAL; | ||
1267 | } | ||
1268 | |||
1269 | memset(thermal_event, 0, sizeof(struct thermal_genl_event)); | ||
1270 | |||
1271 | thermal_event->orig = orig; | ||
1272 | thermal_event->event = event; | ||
1273 | |||
1274 | /* send multicast genetlink message */ | ||
1275 | result = genlmsg_end(skb, msg_header); | ||
1276 | if (result < 0) { | ||
1277 | nlmsg_free(skb); | ||
1278 | return result; | ||
1279 | } | ||
1280 | |||
1281 | result = genlmsg_multicast(skb, 0, thermal_event_mcgrp.id, GFP_ATOMIC); | ||
1282 | if (result) | ||
1283 | printk(KERN_INFO "failed to send netlink event:%d", result); | ||
1284 | |||
1285 | return result; | ||
1286 | } | ||
1287 | EXPORT_SYMBOL(generate_netlink_event); | ||
1288 | |||
1289 | static int genetlink_init(void) | ||
1290 | { | ||
1291 | int result; | ||
1292 | |||
1293 | result = genl_register_family(&thermal_event_genl_family); | ||
1294 | if (result) | ||
1295 | return result; | ||
1296 | |||
1297 | result = genl_register_mc_group(&thermal_event_genl_family, | ||
1298 | &thermal_event_mcgrp); | ||
1299 | if (result) | ||
1300 | genl_unregister_family(&thermal_event_genl_family); | ||
1301 | return result; | ||
1302 | } | ||
1303 | |||
1217 | static int __init thermal_init(void) | 1304 | static int __init thermal_init(void) |
1218 | { | 1305 | { |
1219 | int result = 0; | 1306 | int result = 0; |
@@ -1225,9 +1312,15 @@ static int __init thermal_init(void) | |||
1225 | mutex_destroy(&thermal_idr_lock); | 1312 | mutex_destroy(&thermal_idr_lock); |
1226 | mutex_destroy(&thermal_list_lock); | 1313 | mutex_destroy(&thermal_list_lock); |
1227 | } | 1314 | } |
1315 | result = genetlink_init(); | ||
1228 | return result; | 1316 | return result; |
1229 | } | 1317 | } |
1230 | 1318 | ||
1319 | static void genetlink_exit(void) | ||
1320 | { | ||
1321 | genl_unregister_family(&thermal_event_genl_family); | ||
1322 | } | ||
1323 | |||
1231 | static void __exit thermal_exit(void) | 1324 | static void __exit thermal_exit(void) |
1232 | { | 1325 | { |
1233 | class_unregister(&thermal_class); | 1326 | class_unregister(&thermal_class); |
@@ -1235,7 +1328,8 @@ static void __exit thermal_exit(void) | |||
1235 | idr_destroy(&thermal_cdev_idr); | 1328 | idr_destroy(&thermal_cdev_idr); |
1236 | mutex_destroy(&thermal_idr_lock); | 1329 | mutex_destroy(&thermal_idr_lock); |
1237 | mutex_destroy(&thermal_list_lock); | 1330 | mutex_destroy(&thermal_list_lock); |
1331 | genetlink_exit(); | ||
1238 | } | 1332 | } |
1239 | 1333 | ||
1240 | subsys_initcall(thermal_init); | 1334 | fs_initcall(thermal_init); |
1241 | module_exit(thermal_exit); | 1335 | module_exit(thermal_exit); |