You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
thermal: Add event notification to thermal framework
This patch adds event notification support to the generic thermal sysfs framework in the kernel. The notification is in the form of a netlink event. Signed-off-by: R.Durgadoss <durgadoss.r@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
This commit is contained in:
@@ -32,6 +32,8 @@
|
||||
#include <linux/thermal.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <net/netlink.h>
|
||||
#include <net/genetlink.h>
|
||||
|
||||
MODULE_AUTHOR("Zhang Rui");
|
||||
MODULE_DESCRIPTION("Generic thermal management sysfs support");
|
||||
@@ -58,6 +60,22 @@ static LIST_HEAD(thermal_tz_list);
|
||||
static LIST_HEAD(thermal_cdev_list);
|
||||
static DEFINE_MUTEX(thermal_list_lock);
|
||||
|
||||
static unsigned int thermal_event_seqnum;
|
||||
|
||||
static struct genl_family thermal_event_genl_family = {
|
||||
.id = GENL_ID_GENERATE,
|
||||
.name = THERMAL_GENL_FAMILY_NAME,
|
||||
.version = THERMAL_GENL_VERSION,
|
||||
.maxattr = THERMAL_GENL_ATTR_MAX,
|
||||
};
|
||||
|
||||
static struct genl_multicast_group thermal_event_mcgrp = {
|
||||
.name = THERMAL_GENL_MCAST_GROUP_NAME,
|
||||
};
|
||||
|
||||
static int genetlink_init(void);
|
||||
static void genetlink_exit(void);
|
||||
|
||||
static int get_idr(struct idr *idr, struct mutex *lock, int *id)
|
||||
{
|
||||
int err;
|
||||
@@ -1214,6 +1232,82 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
|
||||
|
||||
EXPORT_SYMBOL(thermal_zone_device_unregister);
|
||||
|
||||
int generate_netlink_event(u32 orig, enum events event)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
struct nlattr *attr;
|
||||
struct thermal_genl_event *thermal_event;
|
||||
void *msg_header;
|
||||
int size;
|
||||
int result;
|
||||
|
||||
/* allocate memory */
|
||||
size = nla_total_size(sizeof(struct thermal_genl_event)) + \
|
||||
nla_total_size(0);
|
||||
|
||||
skb = genlmsg_new(size, GFP_ATOMIC);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
/* add the genetlink message header */
|
||||
msg_header = genlmsg_put(skb, 0, thermal_event_seqnum++,
|
||||
&thermal_event_genl_family, 0,
|
||||
THERMAL_GENL_CMD_EVENT);
|
||||
if (!msg_header) {
|
||||
nlmsg_free(skb);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* fill the data */
|
||||
attr = nla_reserve(skb, THERMAL_GENL_ATTR_EVENT, \
|
||||
sizeof(struct thermal_genl_event));
|
||||
|
||||
if (!attr) {
|
||||
nlmsg_free(skb);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
thermal_event = nla_data(attr);
|
||||
if (!thermal_event) {
|
||||
nlmsg_free(skb);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
memset(thermal_event, 0, sizeof(struct thermal_genl_event));
|
||||
|
||||
thermal_event->orig = orig;
|
||||
thermal_event->event = event;
|
||||
|
||||
/* send multicast genetlink message */
|
||||
result = genlmsg_end(skb, msg_header);
|
||||
if (result < 0) {
|
||||
nlmsg_free(skb);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = genlmsg_multicast(skb, 0, thermal_event_mcgrp.id, GFP_ATOMIC);
|
||||
if (result)
|
||||
printk(KERN_INFO "failed to send netlink event:%d", result);
|
||||
|
||||
return result;
|
||||
}
|
||||
EXPORT_SYMBOL(generate_netlink_event);
|
||||
|
||||
static int genetlink_init(void)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = genl_register_family(&thermal_event_genl_family);
|
||||
if (result)
|
||||
return result;
|
||||
|
||||
result = genl_register_mc_group(&thermal_event_genl_family,
|
||||
&thermal_event_mcgrp);
|
||||
if (result)
|
||||
genl_unregister_family(&thermal_event_genl_family);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int __init thermal_init(void)
|
||||
{
|
||||
int result = 0;
|
||||
@@ -1225,9 +1319,15 @@ static int __init thermal_init(void)
|
||||
mutex_destroy(&thermal_idr_lock);
|
||||
mutex_destroy(&thermal_list_lock);
|
||||
}
|
||||
result = genetlink_init();
|
||||
return result;
|
||||
}
|
||||
|
||||
static void genetlink_exit(void)
|
||||
{
|
||||
genl_unregister_family(&thermal_event_genl_family);
|
||||
}
|
||||
|
||||
static void __exit thermal_exit(void)
|
||||
{
|
||||
class_unregister(&thermal_class);
|
||||
@@ -1235,7 +1335,8 @@ static void __exit thermal_exit(void)
|
||||
idr_destroy(&thermal_cdev_idr);
|
||||
mutex_destroy(&thermal_idr_lock);
|
||||
mutex_destroy(&thermal_list_lock);
|
||||
genetlink_exit();
|
||||
}
|
||||
|
||||
subsys_initcall(thermal_init);
|
||||
fs_initcall(thermal_init);
|
||||
module_exit(thermal_exit);
|
||||
|
||||
Reference in New Issue
Block a user