diff options
| -rw-r--r-- | drivers/thermal/thermal_netlink.c | 53 | ||||
| -rw-r--r-- | drivers/thermal/thermal_netlink.h | 14 | ||||
| -rw-r--r-- | include/uapi/linux/thermal.h | 6 | 
3 files changed, 72 insertions, 1 deletions
| diff --git a/drivers/thermal/thermal_netlink.c b/drivers/thermal/thermal_netlink.c index a16dd4d5d710..7c97a091680e 100644 --- a/drivers/thermal/thermal_netlink.c +++ b/drivers/thermal/thermal_netlink.c @@ -43,6 +43,11 @@ static const struct nla_policy thermal_genl_policy[THERMAL_GENL_ATTR_MAX + 1] =  	[THERMAL_GENL_ATTR_CDEV_MAX_STATE]	= { .type = NLA_U32 },  	[THERMAL_GENL_ATTR_CDEV_NAME]		= { .type = NLA_STRING,  						    .len = THERMAL_NAME_LENGTH }, +	/* CPU capabilities */ +	[THERMAL_GENL_ATTR_CPU_CAPABILITY]		= { .type = NLA_NESTED }, +	[THERMAL_GENL_ATTR_CPU_CAPABILITY_ID]		= { .type = NLA_U32 }, +	[THERMAL_GENL_ATTR_CPU_CAPABILITY_PERFORMANCE]	= { .type = NLA_U32 }, +	[THERMAL_GENL_ATTR_CPU_CAPABILITY_EFFICIENCY]	= { .type = NLA_U32 },  };  struct param { @@ -58,6 +63,8 @@ struct param {  	int temp;  	int cdev_state;  	int cdev_max_state; +	struct thermal_genl_cpu_caps *cpu_capabilities; +	int cpu_capabilities_count;  };  typedef int (*cb_t)(struct param *); @@ -190,6 +197,42 @@ static int thermal_genl_event_gov_change(struct param *p)  	return 0;  } +static int thermal_genl_event_cpu_capability_change(struct param *p) +{ +	struct thermal_genl_cpu_caps *cpu_cap = p->cpu_capabilities; +	struct sk_buff *msg = p->msg; +	struct nlattr *start_cap; +	int i; + +	start_cap = nla_nest_start(msg, THERMAL_GENL_ATTR_CPU_CAPABILITY); +	if (!start_cap) +		return -EMSGSIZE; + +	for (i = 0; i < p->cpu_capabilities_count; ++i) { +		if (nla_put_u32(msg, THERMAL_GENL_ATTR_CPU_CAPABILITY_ID, +				cpu_cap->cpu)) +			goto out_cancel_nest; + +		if (nla_put_u32(msg, THERMAL_GENL_ATTR_CPU_CAPABILITY_PERFORMANCE, +				cpu_cap->performance)) +			goto out_cancel_nest; + +		if (nla_put_u32(msg, THERMAL_GENL_ATTR_CPU_CAPABILITY_EFFICIENCY, +				cpu_cap->efficiency)) +			goto out_cancel_nest; + +		++cpu_cap; +	} + +	nla_nest_end(msg, start_cap); + +	return 0; +out_cancel_nest: +	nla_nest_cancel(msg, start_cap); + +	return -EMSGSIZE; +} +  int thermal_genl_event_tz_delete(struct param *p)  	__attribute__((alias("thermal_genl_event_tz"))); @@ -219,6 +262,7 @@ static cb_t event_cb[] = {  	[THERMAL_GENL_EVENT_CDEV_DELETE]	= thermal_genl_event_cdev_delete,  	[THERMAL_GENL_EVENT_CDEV_STATE_UPDATE]	= thermal_genl_event_cdev_state_update,  	[THERMAL_GENL_EVENT_TZ_GOV_CHANGE]	= thermal_genl_event_gov_change, +	[THERMAL_GENL_EVENT_CPU_CAPABILITY_CHANGE] = thermal_genl_event_cpu_capability_change,  };  /* @@ -356,6 +400,15 @@ int thermal_notify_tz_gov_change(int tz_id, const char *name)  	return thermal_genl_send_event(THERMAL_GENL_EVENT_TZ_GOV_CHANGE, &p);  } +int thermal_genl_cpu_capability_event(int count, +				      struct thermal_genl_cpu_caps *caps) +{ +	struct param p = { .cpu_capabilities_count = count, .cpu_capabilities = caps }; + +	return thermal_genl_send_event(THERMAL_GENL_EVENT_CPU_CAPABILITY_CHANGE, &p); +} +EXPORT_SYMBOL_GPL(thermal_genl_cpu_capability_event); +  /*************************** Command encoding ********************************/  static int __thermal_genl_cmd_tz_get_id(struct thermal_zone_device *tz, diff --git a/drivers/thermal/thermal_netlink.h b/drivers/thermal/thermal_netlink.h index e554f76291f4..04d1adbbc012 100644 --- a/drivers/thermal/thermal_netlink.h +++ b/drivers/thermal/thermal_netlink.h @@ -4,6 +4,12 @@   *  Author: Daniel Lezcano <daniel.lezcano@linaro.org>   */ +struct thermal_genl_cpu_caps { +	int cpu; +	int performance; +	int efficiency; +}; +  /* Netlink notification function */  #ifdef CONFIG_THERMAL_NETLINK  int __init thermal_netlink_init(void); @@ -23,6 +29,8 @@ int thermal_notify_cdev_add(int cdev_id, const char *name, int max_state);  int thermal_notify_cdev_delete(int cdev_id);  int thermal_notify_tz_gov_change(int tz_id, const char *name);  int thermal_genl_sampling_temp(int id, int temp); +int thermal_genl_cpu_capability_event(int count, +				      struct thermal_genl_cpu_caps *caps);  #else  static inline int thermal_netlink_init(void)  { @@ -101,4 +109,10 @@ static inline int thermal_genl_sampling_temp(int id, int temp)  {  	return 0;  } + +static inline int thermal_genl_cpu_capability_event(int count, struct cpu_capability *caps) +{ +	return 0; +} +  #endif /* CONFIG_THERMAL_NETLINK */ diff --git a/include/uapi/linux/thermal.h b/include/uapi/linux/thermal.h index 9aa2fedfa309..fc78bf3aead7 100644 --- a/include/uapi/linux/thermal.h +++ b/include/uapi/linux/thermal.h @@ -44,7 +44,10 @@ enum thermal_genl_attr {  	THERMAL_GENL_ATTR_CDEV_MAX_STATE,  	THERMAL_GENL_ATTR_CDEV_NAME,  	THERMAL_GENL_ATTR_GOV_NAME, - +	THERMAL_GENL_ATTR_CPU_CAPABILITY, +	THERMAL_GENL_ATTR_CPU_CAPABILITY_ID, +	THERMAL_GENL_ATTR_CPU_CAPABILITY_PERFORMANCE, +	THERMAL_GENL_ATTR_CPU_CAPABILITY_EFFICIENCY,  	__THERMAL_GENL_ATTR_MAX,  };  #define THERMAL_GENL_ATTR_MAX (__THERMAL_GENL_ATTR_MAX - 1) @@ -71,6 +74,7 @@ enum thermal_genl_event {  	THERMAL_GENL_EVENT_CDEV_DELETE,		/* Cdev unbound */  	THERMAL_GENL_EVENT_CDEV_STATE_UPDATE,	/* Cdev state updated */  	THERMAL_GENL_EVENT_TZ_GOV_CHANGE,	/* Governor policy changed  */ +	THERMAL_GENL_EVENT_CPU_CAPABILITY_CHANGE,	/* CPU capability changed */  	__THERMAL_GENL_EVENT_MAX,  };  #define THERMAL_GENL_EVENT_MAX (__THERMAL_GENL_EVENT_MAX - 1) | 
