From patchwork Thu Jun 23 00:57:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vadim Fedorenko X-Patchwork-Id: 12891613 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6135DC433EF for ; Thu, 23 Jun 2022 01:05:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=HncAF5T3KaVptlMx5ldWyR6FR1CyQ4xDv3OFNudisBY=; b=D0z/8Ul0ajLSVq rJG+FBP/XN8qk/9DytbXvstumJd9UC0//2AwWLpE6N8kGutkvZdlaEI/Uf4HMqzjX84kurQcqp4y5 lyvlf0sNoO5VvnXIfE7E+s/BtJOROEIKv3JVwalnhpnENjfZx58051Jpp9cAOOucjh1xa1Gr0UeWD /NHC0CExA+PdVvN8PI5y8+0slWgRxZrIarvCj4u4NCIrF/84s65YFHWewgjcJ5uGj/j80/jjNDgXi /bgk8K0XRhynfl5zustSqkA+bX1s62i1t/tfC1PB4BnAqJHUvYBcz9/GYRA5bwGisxvggBRvzZtSP eZQefFbnVXWtvQrcSyXw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1o4BGw-00CejT-Hs; Thu, 23 Jun 2022 01:04:38 +0000 Received: from [213.148.174.62] (helo=novek.ru) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1o4BGb-00CeeM-T3 for linux-arm-kernel@lists.infradead.org; Thu, 23 Jun 2022 01:04:20 +0000 Received: from nat1.ooonet.ru (gw.zelenaya.net [91.207.137.40]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by novek.ru (Postfix) with ESMTPSA id 697695005AA; Thu, 23 Jun 2022 03:55:56 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 novek.ru 697695005AA DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=novek.ru; s=mail; t=1655945757; bh=hFwcPtqUi4OXcdZaJCWlKseEHWPoD/3i6N4Jh42dQTI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=k1JON8ICRQF4HTn3c9WmlECtU8/P4WN+oFiKg4gDnDneYFPWy6xqkIr6E+iC4h/xr rbxiOoitoa9Cpduyc9cPekOUNo6imCF/fB9zjbUjNxPNVvclYYtpPTs+rCWgtHRMzg pjbelgXdPw6lzqUQu04TQpIQXIFK/yHTm/NUC0WY= From: Vadim Fedorenko To: Jakub Kicinski Cc: Vadim Fedorenko , Aya Levin , Arkadiusz Kubalewski , netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [RFC PATCH v1 2/3] dpll: add netlink events Date: Thu, 23 Jun 2022 03:57:16 +0300 Message-Id: <20220623005717.31040-3-vfedorenko@novek.ru> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220623005717.31040-1-vfedorenko@novek.ru> References: <20220623005717.31040-1-vfedorenko@novek.ru> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220622_180418_330914_6DAAF08D X-CRM114-Status: GOOD ( 15.94 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Vadim Fedorenko Add netlink interface to enable notification of users about events in DPLL framework. Part of this interface should be used by drivers directly, i.e. lock status changes. Signed-off-by: Vadim Fedorenko --- drivers/dpll/dpll_core.c | 2 + drivers/dpll/dpll_netlink.c | 141 ++++++++++++++++++++++++++++++++++++ drivers/dpll/dpll_netlink.h | 7 ++ 3 files changed, 150 insertions(+) diff --git a/drivers/dpll/dpll_core.c b/drivers/dpll/dpll_core.c index e34767e723cf..6be169df3c9e 100644 --- a/drivers/dpll/dpll_core.c +++ b/drivers/dpll/dpll_core.c @@ -99,6 +99,8 @@ struct dpll_device *dpll_device_alloc(struct dpll_device_ops *ops, int sources_c mutex_unlock(&dpll_device_xa_lock); dpll->priv = priv; + dpll_notify_device_create(dpll->id, dev_name(&dpll->dev)); + return dpll; error: diff --git a/drivers/dpll/dpll_netlink.c b/drivers/dpll/dpll_netlink.c index 0bbdaa6dde8e..6c1dd4ce1f89 100644 --- a/drivers/dpll/dpll_netlink.c +++ b/drivers/dpll/dpll_netlink.c @@ -48,6 +48,8 @@ struct param { int dpll_source_type; int dpll_output_id; int dpll_output_type; + int dpll_status; + const char *dpll_name; }; struct dpll_dump_ctx { @@ -222,6 +224,8 @@ static int dpll_genl_cmd_set_source(struct param *p) ret = dpll->ops->set_source_type(dpll, src_id, type); mutex_unlock(&dpll->lock); + dpll_notify_source_change(dpll->id, src_id, type); + return ret; } @@ -245,6 +249,8 @@ static int dpll_genl_cmd_set_output(struct param *p) ret = dpll->ops->set_source_type(dpll, out_id, type); mutex_unlock(&dpll->lock); + dpll_notify_source_change(dpll->id, out_id, type); + return ret; } @@ -421,6 +427,141 @@ static struct genl_family dpll_gnl_family __ro_after_init = { .pre_doit = dpll_pre_doit, }; +static int dpll_event_device_create(struct param *p) +{ + if (nla_put_u32(p->msg, DPLLA_DEVICE_ID, p->dpll_id) || + nla_put_string(p->msg, DPLLA_DEVICE_NAME, p->dpll_name)) + return -EMSGSIZE; + + return 0; +} + +static int dpll_event_device_delete(struct param *p) +{ + if (nla_put_u32(p->msg, DPLLA_DEVICE_ID, p->dpll_id)) + return -EMSGSIZE; + + return 0; +} + +static int dpll_event_status(struct param *p) +{ + if (nla_put_u32(p->msg, DPLLA_DEVICE_ID, p->dpll_id) || + nla_put_u32(p->msg, DPLLA_LOCK_STATUS, p->dpll_status)) + return -EMSGSIZE; + + return 0; +} + +static int dpll_event_source_change(struct param *p) +{ + if (nla_put_u32(p->msg, DPLLA_DEVICE_ID, p->dpll_id) || + nla_put_u32(p->msg, DPLLA_SOURCE_ID, p->dpll_source_id) || + nla_put_u32(p->msg, DPLLA_SOURCE_TYPE, p->dpll_source_type)) + return -EMSGSIZE; + + return 0; +} + +static int dpll_event_output_change(struct param *p) +{ + if (nla_put_u32(p->msg, DPLLA_DEVICE_ID, p->dpll_id) || + nla_put_u32(p->msg, DPLLA_OUTPUT_ID, p->dpll_output_id) || + nla_put_u32(p->msg, DPLLA_OUTPUT_TYPE, p->dpll_output_type)) + return -EMSGSIZE; + + return 0; +} + +static cb_t event_cb[] = { + [DPLL_EVENT_DEVICE_CREATE] = dpll_event_device_create, + [DPLL_EVENT_DEVICE_DELETE] = dpll_event_device_delete, + [DPLL_EVENT_STATUS_LOCKED] = dpll_event_status, + [DPLL_EVENT_STATUS_UNLOCKED] = dpll_event_status, + [DPLL_EVENT_SOURCE_CHANGE] = dpll_event_source_change, + [DPLL_EVENT_OUTPUT_CHANGE] = dpll_event_output_change, +}; +/* + * Generic netlink DPLL event encoding + */ +static int dpll_send_event(enum dpll_genl_event event, + struct param *p) +{ + struct sk_buff *msg; + int ret = -EMSGSIZE; + void *hdr; + + msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL); + if (!msg) + return -ENOMEM; + p->msg = msg; + + hdr = genlmsg_put(msg, 0, 0, &dpll_gnl_family, 0, event); + if (!hdr) + goto out_free_msg; + + ret = event_cb[event](p); + if (ret) + goto out_cancel_msg; + + genlmsg_end(msg, hdr); + + genlmsg_multicast(&dpll_gnl_family, msg, 0, 1, GFP_KERNEL); + + return 0; + +out_cancel_msg: + genlmsg_cancel(msg, hdr); +out_free_msg: + nlmsg_free(msg); + + return ret; +} + +int dpll_notify_device_create(int dpll_id, const char *name) +{ + struct param p = { .dpll_id = dpll_id, .dpll_name = name }; + + return dpll_send_event(DPLL_EVENT_DEVICE_CREATE, &p); +} + +int dpll_notify_device_delete(int dpll_id) +{ + struct param p = { .dpll_id = dpll_id }; + + return dpll_send_event(DPLL_EVENT_DEVICE_DELETE, &p); +} + +int dpll_notify_status_locked(int dpll_id) +{ + struct param p = { .dpll_id = dpll_id, .dpll_status = 1 }; + + return dpll_send_event(DPLL_EVENT_STATUS_LOCKED, &p); +} + +int dpll_notify_status_unlocked(int dpll_id) +{ + struct param p = { .dpll_id = dpll_id, .dpll_status = 0 }; + + return dpll_send_event(DPLL_EVENT_STATUS_UNLOCKED, &p); +} + +int dpll_notify_source_change(int dpll_id, int source_id, int source_type) +{ + struct param p = { .dpll_id = dpll_id, .dpll_source_id = source_id, + .dpll_source_type = source_type }; + + return dpll_send_event(DPLL_EVENT_SOURCE_CHANGE, &p); +} + +int dpll_notify_output_change(int dpll_id, int output_id, int output_type) +{ + struct param p = { .dpll_id = dpll_id, .dpll_output_id = output_id, + .dpll_output_type = output_type }; + + return dpll_send_event(DPLL_EVENT_OUTPUT_CHANGE, &p); +} + int __init dpll_netlink_init(void) { return genl_register_family(&dpll_gnl_family); diff --git a/drivers/dpll/dpll_netlink.h b/drivers/dpll/dpll_netlink.h index e2d100f59dd6..0dc81320f982 100644 --- a/drivers/dpll/dpll_netlink.h +++ b/drivers/dpll/dpll_netlink.h @@ -3,5 +3,12 @@ * Copyright (c) 2021 Meta Platforms, Inc. and affiliates */ +int dpll_notify_device_create(int dpll_id, const char *name); +int dpll_notify_device_delete(int dpll_id); +int dpll_notify_status_locked(int dpll_id); +int dpll_notify_status_unlocked(int dpll_id); +int dpll_notify_source_change(int dpll_id, int source_id, int source_type); +int dpll_notify_output_change(int dpll_id, int output_id, int output_type); + int __init dpll_netlink_init(void); void dpll_netlink_finish(void);