aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/thermal
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/thermal')
-rw-r--r--drivers/thermal/Kconfig1
-rw-r--r--drivers/thermal/thermal_sys.c120
2 files changed, 108 insertions, 13 deletions
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index bf7c687519e..f7a5dba3ca2 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -4,6 +4,7 @@
4 4
5menuconfig THERMAL 5menuconfig THERMAL
6 tristate "Generic Thermal sysfs driver" 6 tristate "Generic Thermal sysfs driver"
7 depends on NET
7 help 8 help
8 Generic Thermal Sysfs driver offers a generic mechanism for 9 Generic Thermal Sysfs driver offers a generic mechanism for
9 thermal management. Usually it's made up of one or more thermal 10 thermal management. Usually it's made up of one or more thermal
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
36MODULE_AUTHOR("Zhang Rui"); 38MODULE_AUTHOR("Zhang Rui");
37MODULE_DESCRIPTION("Generic thermal management sysfs support"); 39MODULE_DESCRIPTION("Generic thermal management sysfs support");
@@ -58,6 +60,22 @@ static LIST_HEAD(thermal_tz_list);
58static LIST_HEAD(thermal_cdev_list); 60static LIST_HEAD(thermal_cdev_list);
59static DEFINE_MUTEX(thermal_list_lock); 61static DEFINE_MUTEX(thermal_list_lock);
60 62
63static unsigned int thermal_event_seqnum;
64
65static 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
72static struct genl_multicast_group thermal_event_mcgrp = {
73 .name = THERMAL_GENL_MCAST_GROUP_NAME,
74};
75
76static int genetlink_init(void);
77static void genetlink_exit(void);
78
61static int get_idr(struct idr *idr, struct mutex *lock, int *id) 79static 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 */
826struct thermal_cooling_device *thermal_cooling_device_register(char *type, 844struct 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 */
1050struct thermal_zone_device *thermal_zone_device_register(char *type, 1065struct 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
1215EXPORT_SYMBOL(thermal_zone_device_unregister); 1226EXPORT_SYMBOL(thermal_zone_device_unregister);
1216 1227
1228int 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}
1287EXPORT_SYMBOL(generate_netlink_event);
1288
1289static 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
1217static int __init thermal_init(void) 1304static 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
1319static void genetlink_exit(void)
1320{
1321 genl_unregister_family(&thermal_event_genl_family);
1322}
1323
1231static void __exit thermal_exit(void) 1324static 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
1240subsys_initcall(thermal_init); 1334fs_initcall(thermal_init);
1241module_exit(thermal_exit); 1335module_exit(thermal_exit);