Commit 1ce50e7d authored by Daniel Lezcano's avatar Daniel Lezcano

thermal: core: genetlink support for events/cmd/sampling

Initially the thermal framework had a very simple notification
mechanism to send generic netlink messages to the userspace.

The notification function was never called from anywhere and the
corresponding dead code was removed. It was probably a first attempt
to introduce the netlink notification.

At LPC2018, the presentation "Linux thermal: User kernel interface",
proposed to create the notifications to the userspace via a kfifo.

The advantage of the kfifo is the performance. It is usually used from
a 1:1 communication channel where a driver captures data and sends it
as fast as possible to a userspace process.

The drawback is that only one process uses the notification channel
exclusively, thus no other process is allowed to use the channel to
get temperature or notifications.

This patch defines a generic netlink API to discover the current
thermal setup and adds event notifications as well as temperature
sampling. As any genetlink protocol, it can evolve and the versioning
allows to keep the backward compatibility.

In order to prevent the user from getting flooded with data on a
single channel, there are two multicast channels, one for the
temperature sampling when the thermal zone is updated and another one
for the events, so the user can get the events only without the
thermal zone temperature sampling.

Also, a list of commands to discover the thermal setup is added and
can be extended when needed.
Reviewed-by: default avatarAmit Kucheria <amit.kucheria@linaro.org>
Signed-off-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
Acked-by: default avatarZhang Rui <rui.zhang@intel.com>
Link: https://lore.kernel.org/r/20200706105538.2159-3-daniel.lezcano@linaro.org
parent 329b064f
......@@ -5,7 +5,7 @@
obj-$(CONFIG_THERMAL) += thermal_sys.o
thermal_sys-y += thermal_core.o thermal_sysfs.o \
thermal_helpers.o
thermal_helpers.o thermal_netlink.o
# interface to/from other layers providing sensors
thermal_sys-$(CONFIG_THERMAL_HWMON) += thermal_hwmon.o
......
......@@ -52,6 +52,24 @@ int for_each_thermal_governor(int (*cb)(struct thermal_governor *, void *),
struct thermal_zone_device *thermal_zone_get_by_id(int id);
/* Netlink notification function */
int thermal_notify_tz_create(int tz_id, const char *name);
int thermal_notify_tz_delete(int tz_id);
int thermal_notify_tz_enable(int tz_id);
int thermal_notify_tz_disable(int tz_id);
int thermal_notify_tz_trip_down(int tz_id, int id);
int thermal_notify_tz_trip_up(int tz_id, int id);
int thermal_notify_tz_trip_delete(int tz_id, int id);
int thermal_notify_tz_trip_add(int tz_id, int id, int type,
int temp, int hyst);
int thermal_notify_tz_trip_change(int tz_id, int id, int type,
int temp, int hyst);
int thermal_notify_cdev_state_update(int cdev_id, int state);
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);
struct thermal_attr {
struct device_attribute attr;
char name[THERMAL_NAME_LENGTH];
......
This diff is collapsed.
......@@ -37,18 +37,6 @@ struct thermal_cooling_device;
struct thermal_instance;
struct thermal_attr;
enum thermal_device_mode {
THERMAL_DEVICE_DISABLED = 0,
THERMAL_DEVICE_ENABLED,
};
enum thermal_trip_type {
THERMAL_TRIP_ACTIVE = 0,
THERMAL_TRIP_PASSIVE,
THERMAL_TRIP_HOT,
THERMAL_TRIP_CRITICAL,
};
enum thermal_trend {
THERMAL_TREND_STABLE, /* temperature is stable */
THERMAL_TREND_RAISING, /* temperature is raising */
......@@ -303,11 +291,6 @@ struct thermal_zone_params {
int offset;
};
struct thermal_genl_event {
u32 orig;
enum events event;
};
/**
* struct thermal_zone_of_device_ops - scallbacks for handling DT based zones
*
......
......@@ -4,31 +4,86 @@
#define THERMAL_NAME_LENGTH 20
/* Adding event notification support elements */
#define THERMAL_GENL_FAMILY_NAME "thermal_event"
#define THERMAL_GENL_VERSION 0x01
#define THERMAL_GENL_MCAST_GROUP_NAME "thermal_mc_grp"
/* Events supported by Thermal Netlink */
enum events {
THERMAL_AUX0,
THERMAL_AUX1,
THERMAL_CRITICAL,
THERMAL_DEV_FAULT,
enum thermal_device_mode {
THERMAL_DEVICE_DISABLED = 0,
THERMAL_DEVICE_ENABLED,
};
enum thermal_trip_type {
THERMAL_TRIP_ACTIVE = 0,
THERMAL_TRIP_PASSIVE,
THERMAL_TRIP_HOT,
THERMAL_TRIP_CRITICAL,
};
/* attributes of thermal_genl_family */
enum {
/* Adding event notification support elements */
#define THERMAL_GENL_FAMILY_NAME "thermal"
#define THERMAL_GENL_VERSION 0x01
#define THERMAL_GENL_SAMPLING_GROUP_NAME "sampling"
#define THERMAL_GENL_EVENT_GROUP_NAME "event"
/* Attributes of thermal_genl_family */
enum thermal_genl_attr {
THERMAL_GENL_ATTR_UNSPEC,
THERMAL_GENL_ATTR_EVENT,
THERMAL_GENL_ATTR_TZ,
THERMAL_GENL_ATTR_TZ_ID,
THERMAL_GENL_ATTR_TZ_TEMP,
THERMAL_GENL_ATTR_TZ_TRIP,
THERMAL_GENL_ATTR_TZ_TRIP_ID,
THERMAL_GENL_ATTR_TZ_TRIP_TYPE,
THERMAL_GENL_ATTR_TZ_TRIP_TEMP,
THERMAL_GENL_ATTR_TZ_TRIP_HYST,
THERMAL_GENL_ATTR_TZ_MODE,
THERMAL_GENL_ATTR_TZ_NAME,
THERMAL_GENL_ATTR_TZ_CDEV_WEIGHT,
THERMAL_GENL_ATTR_TZ_GOV,
THERMAL_GENL_ATTR_TZ_GOV_NAME,
THERMAL_GENL_ATTR_CDEV,
THERMAL_GENL_ATTR_CDEV_ID,
THERMAL_GENL_ATTR_CDEV_CUR_STATE,
THERMAL_GENL_ATTR_CDEV_MAX_STATE,
THERMAL_GENL_ATTR_CDEV_NAME,
THERMAL_GENL_ATTR_GOV_NAME,
__THERMAL_GENL_ATTR_MAX,
};
#define THERMAL_GENL_ATTR_MAX (__THERMAL_GENL_ATTR_MAX - 1)
/* commands supported by the thermal_genl_family */
enum {
enum thermal_genl_sampling {
THERMAL_GENL_SAMPLING_TEMP,
__THERMAL_GENL_SAMPLING_MAX,
};
#define THERMAL_GENL_SAMPLING_MAX (__THERMAL_GENL_SAMPLING_MAX - 1)
/* Events of thermal_genl_family */
enum thermal_genl_event {
THERMAL_GENL_EVENT_UNSPEC,
THERMAL_GENL_EVENT_TZ_CREATE, /* Thermal zone creation */
THERMAL_GENL_EVENT_TZ_DELETE, /* Thermal zone deletion */
THERMAL_GENL_EVENT_TZ_DISABLE, /* Thermal zone disabed */
THERMAL_GENL_EVENT_TZ_ENABLE, /* Thermal zone enabled */
THERMAL_GENL_EVENT_TZ_TRIP_UP, /* Trip point crossed the way up */
THERMAL_GENL_EVENT_TZ_TRIP_DOWN, /* Trip point crossed the way down */
THERMAL_GENL_EVENT_TZ_TRIP_CHANGE, /* Trip point changed */
THERMAL_GENL_EVENT_TZ_TRIP_ADD, /* Trip point added */
THERMAL_GENL_EVENT_TZ_TRIP_DELETE, /* Trip point deleted */
THERMAL_GENL_EVENT_CDEV_ADD, /* Cdev bound to the thermal zone */
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_MAX,
};
#define THERMAL_GENL_EVENT_MAX (__THERMAL_GENL_EVENT_MAX - 1)
/* Commands supported by the thermal_genl_family */
enum thermal_genl_cmd {
THERMAL_GENL_CMD_UNSPEC,
THERMAL_GENL_CMD_EVENT,
THERMAL_GENL_CMD_TZ_GET_ID, /* List of thermal zones id */
THERMAL_GENL_CMD_TZ_GET_TRIP, /* List of thermal trips */
THERMAL_GENL_CMD_TZ_GET_TEMP, /* Get the thermal zone temperature */
THERMAL_GENL_CMD_TZ_GET_GOV, /* Get the thermal zone governor */
THERMAL_GENL_CMD_TZ_GET_MODE, /* Get the thermal zone mode */
THERMAL_GENL_CMD_CDEV_GET, /* List of cdev id */
__THERMAL_GENL_CMD_MAX,
};
#define THERMAL_GENL_CMD_MAX (__THERMAL_GENL_CMD_MAX - 1)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment