diff mbox series

[04/11] PM: EM: Add the infrastructure for command processing.

Message ID 20250529001315.233492-5-changwoo@igalia.com
State New
Headers show
Series [01/11] PM: EM: Add ENERGY_MODEL_NETLINK Kconfig. | expand

Commit Message

Changwoo Min May 29, 2025, 12:13 a.m. UTC
The infrastructure for command processing receives a command from a
userspace and calls a callback corresponding to the request command.

Note that the callback functions are just boilerplates in this commit,
and the actual implementations will be provided in the following commits
when a callback for a specific command is implemented.

Signed-off-by: Changwoo Min <changwoo@igalia.com>
---
 kernel/power/em_netlink.c | 53 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 52 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/kernel/power/em_netlink.c b/kernel/power/em_netlink.c
index 30d83fb5a3a8..edbaecebd0b4 100644
--- a/kernel/power/em_netlink.c
+++ b/kernel/power/em_netlink.c
@@ -23,14 +23,65 @@  static const struct genl_multicast_group em_genl_mcgrps[] = {
 static const struct nla_policy em_genl_policy[EM_GENL_ATTR_MAX + 1] = {
 };
 
+struct param {
+	struct nlattr **attrs;
+	struct sk_buff *msg;
+};
+
+typedef int (*cb_t)(struct param *);
+
 static struct genl_family em_genl_family;
 
+/*************************** Command encoding ********************************/
 
-static int em_genl_cmd_doit(struct sk_buff *skb, struct genl_info *info)
+static int em_genl_cmd_pd_get_id(struct param *p)
 {
 	return -ENOTSUPP;
 }
 
+static int em_genl_cmd_pd_get_tbl(struct param *p)
+{
+	return -ENOTSUPP;
+}
+
+static const cb_t cmd_cb[] = {
+	[EM_GENL_CMD_PD_GET_ID]			= em_genl_cmd_pd_get_id,
+	[EM_GENL_CMD_PD_GET_TBL]		= em_genl_cmd_pd_get_tbl,
+};
+
+static int em_genl_cmd_doit(struct sk_buff *skb, struct genl_info *info)
+{
+	struct param p = { .attrs = info->attrs };
+	struct sk_buff *msg;
+	void *hdr;
+	int cmd = info->genlhdr->cmd;
+	int ret = -EMSGSIZE;
+
+	msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+	if (!msg)
+		return -ENOMEM;
+	p.msg = msg;
+
+	hdr = genlmsg_put_reply(msg, info, &em_genl_family, 0, cmd);
+	if (!hdr)
+		goto out_free_msg;
+
+	ret = cmd_cb[cmd](&p);
+	if (ret)
+		goto out_cancel_msg;
+
+	genlmsg_end(msg, hdr);
+
+	return genlmsg_reply(msg, info);
+
+out_cancel_msg:
+	genlmsg_cancel(msg, hdr);
+out_free_msg:
+	nlmsg_free(msg);
+
+	return ret;
+}
+
 static const struct genl_small_ops em_genl_ops[] = {
 	{
 		.cmd = EM_GENL_CMD_PD_GET_ID,