From patchwork Sun Feb 27 20:55:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 12762132 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 E1096C433F5 for ; Sun, 27 Feb 2022 20:57: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:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id: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=YdxDFltzFLbKPyqNVroeY8WkaLMsOBBL2C7sZzZqJIk=; b=k1+LgiQtPJX7RN OahTPy+RMMt77jPlaMDFhVLvl3hDAKAx3U2T1IvqG7VQmQdn8VZ85HSvNivx2k5JwT6yhnzAg/GCR Bs+MjOvQU7rYhCTA8WceRlZMF5zXyIuyvVgHxiecTNPsOKG6160Vs+7KnxC/8jI+igKYY1DydqjO3 it5yr6fKClHEHeoMU8MZDyU6iFX1uWqZGLfJ5ZKxPgBuU7pyeDpLfjB0/ilQCFfHUOo5UHuB7mY+u mvJN00dHOYMGsSk0nac8cEo1rwY6AU+rSwL6uUN1VGngovDvkcM0IYUKz9ixxjfKZCxxJ3QuHn0/z 4XSd0YdGyS3SuCbrE9vw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQak-00A7Cq-K1; Sun, 27 Feb 2022 20:56:30 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQag-00A7Ag-2Z for linux-arm-kernel@lists.infradead.org; Sun, 27 Feb 2022 20:56:27 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id AF331106F; Sun, 27 Feb 2022 12:56:23 -0800 (PST) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 509053F66F; Sun, 27 Feb 2022 12:56:22 -0800 (PST) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, peter.hilber@opensynergy.com, cristian.marussi@arm.com Subject: [RFC PATCH 01/16] firmware: arm_scmi: Simplify scmi_devm_notifier_unregister Date: Sun, 27 Feb 2022 20:55:53 +0000 Message-Id: <20220227205608.30812-2-cristian.marussi@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220227205608.30812-1-cristian.marussi@arm.com> References: <20220227205608.30812-1-cristian.marussi@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220227_125626_294177_B4A5AA70 X-CRM114-Status: GOOD ( 13.49 ) 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Unregistering SCMI notifications using the managed devres interface can be done providing as a reference simply the previously successfully registered notification block since it could have been registered only on one kernel notification_chain: drop any reference to SCMI protocol, events and sources. Devres internal helpers can search for the provided notification block reference and, once found, the associated devres object will already provide the above SCMI references for the event. Signed-off-by: Cristian Marussi --- drivers/firmware/arm_scmi/notify.c | 30 ++++-------------------------- include/linux/scmi_protocol.h | 2 -- 2 files changed, 4 insertions(+), 28 deletions(-) diff --git a/drivers/firmware/arm_scmi/notify.c b/drivers/firmware/arm_scmi/notify.c index 0efd20cd9d69..7d0b01b59616 100644 --- a/drivers/firmware/arm_scmi/notify.c +++ b/drivers/firmware/arm_scmi/notify.c @@ -1498,17 +1498,12 @@ static int scmi_devm_notifier_register(struct scmi_device *sdev, static int scmi_devm_notifier_match(struct device *dev, void *res, void *data) { struct scmi_notifier_devres *dres = res; - struct scmi_notifier_devres *xres = data; + struct notifier_block *nb = data; - if (WARN_ON(!dres || !xres)) + if (WARN_ON(!dres || !nb)) return 0; - return dres->proto_id == xres->proto_id && - dres->evt_id == xres->evt_id && - dres->nb == xres->nb && - ((!dres->src_id && !xres->src_id) || - (dres->src_id && xres->src_id && - dres->__src_id == xres->__src_id)); + return dres->nb == nb; } /** @@ -1516,10 +1511,6 @@ static int scmi_devm_notifier_match(struct device *dev, void *res, void *data) * notifier_block for an event * @sdev: A reference to an scmi_device whose embedded struct device is to * be used for devres accounting. - * @proto_id: Protocol ID - * @evt_id: Event ID - * @src_id: Source ID, when NULL register for events coming form ALL possible - * sources * @nb: A standard notifier block to register for the specified event * * Generic devres managed helper to explicitly un-register a notifier_block @@ -1529,25 +1520,12 @@ static int scmi_devm_notifier_match(struct device *dev, void *res, void *data) * Return: 0 on Success */ static int scmi_devm_notifier_unregister(struct scmi_device *sdev, - u8 proto_id, u8 evt_id, - const u32 *src_id, struct notifier_block *nb) { int ret; - struct scmi_notifier_devres dres; - - dres.handle = sdev->handle; - dres.proto_id = proto_id; - dres.evt_id = evt_id; - if (src_id) { - dres.__src_id = *src_id; - dres.src_id = &dres.__src_id; - } else { - dres.src_id = NULL; - } ret = devres_release(&sdev->dev, scmi_devm_release_notifier, - scmi_devm_notifier_match, &dres); + scmi_devm_notifier_match, nb); WARN_ON(ret); diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h index b87551f41f9f..b0652f1411b9 100644 --- a/include/linux/scmi_protocol.h +++ b/include/linux/scmi_protocol.h @@ -595,8 +595,6 @@ struct scmi_notify_ops { const u32 *src_id, struct notifier_block *nb); int (*devm_event_notifier_unregister)(struct scmi_device *sdev, - u8 proto_id, u8 evt_id, - const u32 *src_id, struct notifier_block *nb); int (*event_notifier_register)(const struct scmi_handle *handle, u8 proto_id, u8 evt_id, From patchwork Sun Feb 27 20:55:54 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 12762134 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 4E42AC433F5 for ; Sun, 27 Feb 2022 20:58:05 +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:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id: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=PjFrN7aX18WE43vCcyuk8nYeHlqnVMxNIZSqXgFi3Ws=; b=Ha7g7NzG5CG34g lnkipnoERAtJVWznsWgRW6Y7EKMS/0DDayGBVtJI+pF9Nxyeu8s2iKTNpnJT6qdKW68ciFBsvXz/a jBdIMcnt4UkgDj8nL49kM3Jw7ulHL13hOlal2c5xLVmb1VJmZ+YzAAtwL/+ZAl2WIR7HVow0Co/PN tj8aneDSNn2QTMyg4T897vs8edr9lUH0uVjx3KUdciuXfrimU/7NHFwZX2X5j+lBasWesAhzKNPMk tuK5ERcBG6yXhfTHXNUoXYj62w9/UEj27JGpwk/hOaHz+zcjlthsqc/ZLIVlsoLW/1rhVyGmjLg/T 2+YBfBBNS7XjJ9rHbC0w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQb7-00A7NY-To; Sun, 27 Feb 2022 20:56:54 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQag-00A7Bp-Su for linux-arm-kernel@lists.infradead.org; Sun, 27 Feb 2022 20:56:29 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4D90811FB; Sun, 27 Feb 2022 12:56:25 -0800 (PST) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id E4B5D3F66F; Sun, 27 Feb 2022 12:56:23 -0800 (PST) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, peter.hilber@opensynergy.com, cristian.marussi@arm.com Subject: [RFC PATCH 02/16] firmware: arm_scmi: Make protocols init fail on basic errors Date: Sun, 27 Feb 2022 20:55:54 +0000 Message-Id: <20220227205608.30812-3-cristian.marussi@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220227205608.30812-1-cristian.marussi@arm.com> References: <20220227205608.30812-1-cristian.marussi@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220227_125627_113016_D76D2794 X-CRM114-Status: GOOD ( 11.45 ) 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Bail out of protocol initialization routine early when basic information about protocol version and attributes could not be retrieved: failing to act this way can lead to a successfully initialized SCMI protocol which is in fact not functional. Signed-off-by: Cristian Marussi --- drivers/firmware/arm_scmi/base.c | 5 ++++- drivers/firmware/arm_scmi/clock.c | 8 ++++++-- drivers/firmware/arm_scmi/perf.c | 10 +++++++--- drivers/firmware/arm_scmi/power.c | 10 +++++++--- drivers/firmware/arm_scmi/reset.c | 10 +++++++--- drivers/firmware/arm_scmi/sensors.c | 4 +++- drivers/firmware/arm_scmi/system.c | 5 ++++- 7 files changed, 38 insertions(+), 14 deletions(-) diff --git a/drivers/firmware/arm_scmi/base.c b/drivers/firmware/arm_scmi/base.c index f5219334fd3a..ebaef5d320af 100644 --- a/drivers/firmware/arm_scmi/base.c +++ b/drivers/firmware/arm_scmi/base.c @@ -359,7 +359,10 @@ static int scmi_base_protocol_init(const struct scmi_protocol_handle *ph) rev->minor_ver = PROTOCOL_REV_MINOR(version); ph->set_priv(ph, rev); - scmi_base_attributes_get(ph); + ret = scmi_base_attributes_get(ph); + if (ret) + return ret; + scmi_base_vendor_id_get(ph, false); scmi_base_vendor_id_get(ph, true); scmi_base_implementation_version_get(ph); diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c index cf6fed6dec77..e2059d2025a2 100644 --- a/drivers/firmware/arm_scmi/clock.c +++ b/drivers/firmware/arm_scmi/clock.c @@ -360,7 +360,9 @@ static int scmi_clock_protocol_init(const struct scmi_protocol_handle *ph) int clkid, ret; struct clock_info *cinfo; - ph->xops->version_get(ph, &version); + ret = ph->xops->version_get(ph, &version); + if (ret) + return ret; dev_dbg(ph->dev, "Clock Version %d.%d\n", PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version)); @@ -369,7 +371,9 @@ static int scmi_clock_protocol_init(const struct scmi_protocol_handle *ph) if (!cinfo) return -ENOMEM; - scmi_clock_protocol_attributes_get(ph, cinfo); + ret = scmi_clock_protocol_attributes_get(ph, cinfo); + if (ret) + return ret; cinfo->clk = devm_kcalloc(ph->dev, cinfo->num_clocks, sizeof(*cinfo->clk), GFP_KERNEL); diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c index f4cd5193b961..e9f68b91580c 100644 --- a/drivers/firmware/arm_scmi/perf.c +++ b/drivers/firmware/arm_scmi/perf.c @@ -873,11 +873,13 @@ static const struct scmi_protocol_events perf_protocol_events = { static int scmi_perf_protocol_init(const struct scmi_protocol_handle *ph) { - int domain; + int domain, ret; u32 version; struct scmi_perf_info *pinfo; - ph->xops->version_get(ph, &version); + ret = ph->xops->version_get(ph, &version); + if (ret) + return ret; dev_dbg(ph->dev, "Performance Version %d.%d\n", PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version)); @@ -886,7 +888,9 @@ static int scmi_perf_protocol_init(const struct scmi_protocol_handle *ph) if (!pinfo) return -ENOMEM; - scmi_perf_attributes_get(ph, pinfo); + ret = scmi_perf_attributes_get(ph, pinfo); + if (ret) + return ret; pinfo->dom_info = devm_kcalloc(ph->dev, pinfo->num_domains, sizeof(*pinfo->dom_info), GFP_KERNEL); diff --git a/drivers/firmware/arm_scmi/power.c b/drivers/firmware/arm_scmi/power.c index ad2ab080f344..0f0b94f0b624 100644 --- a/drivers/firmware/arm_scmi/power.c +++ b/drivers/firmware/arm_scmi/power.c @@ -280,11 +280,13 @@ static const struct scmi_protocol_events power_protocol_events = { static int scmi_power_protocol_init(const struct scmi_protocol_handle *ph) { - int domain; + int domain, ret; u32 version; struct scmi_power_info *pinfo; - ph->xops->version_get(ph, &version); + ret = ph->xops->version_get(ph, &version); + if (ret) + return ret; dev_dbg(ph->dev, "Power Version %d.%d\n", PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version)); @@ -293,7 +295,9 @@ static int scmi_power_protocol_init(const struct scmi_protocol_handle *ph) if (!pinfo) return -ENOMEM; - scmi_power_attributes_get(ph, pinfo); + ret = scmi_power_attributes_get(ph, pinfo); + if (ret) + return ret; pinfo->dom_info = devm_kcalloc(ph->dev, pinfo->num_domains, sizeof(*pinfo->dom_info), GFP_KERNEL); diff --git a/drivers/firmware/arm_scmi/reset.c b/drivers/firmware/arm_scmi/reset.c index 9bf2478ec6d1..9cdbd133db10 100644 --- a/drivers/firmware/arm_scmi/reset.c +++ b/drivers/firmware/arm_scmi/reset.c @@ -293,11 +293,13 @@ static const struct scmi_protocol_events reset_protocol_events = { static int scmi_reset_protocol_init(const struct scmi_protocol_handle *ph) { - int domain; + int domain, ret; u32 version; struct scmi_reset_info *pinfo; - ph->xops->version_get(ph, &version); + ret = ph->xops->version_get(ph, &version); + if (ret) + return ret; dev_dbg(ph->dev, "Reset Version %d.%d\n", PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version)); @@ -306,7 +308,9 @@ static int scmi_reset_protocol_init(const struct scmi_protocol_handle *ph) if (!pinfo) return -ENOMEM; - scmi_reset_attributes_get(ph, pinfo); + ret = scmi_reset_attributes_get(ph, pinfo); + if (ret) + return ret; pinfo->dom_info = devm_kcalloc(ph->dev, pinfo->num_domains, sizeof(*pinfo->dom_info), GFP_KERNEL); diff --git a/drivers/firmware/arm_scmi/sensors.c b/drivers/firmware/arm_scmi/sensors.c index cdbb287bd8bc..f37ac9824a87 100644 --- a/drivers/firmware/arm_scmi/sensors.c +++ b/drivers/firmware/arm_scmi/sensors.c @@ -966,7 +966,9 @@ static int scmi_sensors_protocol_init(const struct scmi_protocol_handle *ph) int ret; struct sensors_info *sinfo; - ph->xops->version_get(ph, &version); + ret = ph->xops->version_get(ph, &version); + if (ret) + return ret; dev_dbg(ph->dev, "Sensor Version %d.%d\n", PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version)); diff --git a/drivers/firmware/arm_scmi/system.c b/drivers/firmware/arm_scmi/system.c index e5175ef73b40..cbfc19f7a463 100644 --- a/drivers/firmware/arm_scmi/system.c +++ b/drivers/firmware/arm_scmi/system.c @@ -113,10 +113,13 @@ static const struct scmi_protocol_events system_protocol_events = { static int scmi_system_protocol_init(const struct scmi_protocol_handle *ph) { + int ret; u32 version; struct scmi_system_info *pinfo; - ph->xops->version_get(ph, &version); + ret = ph->xops->version_get(ph, &version); + if (ret) + return ret; dev_dbg(ph->dev, "System Power Version %d.%d\n", PROTOCOL_REV_MAJOR(version), PROTOCOL_REV_MINOR(version)); From patchwork Sun Feb 27 20:55:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 12762135 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 5DE6EC433F5 for ; Sun, 27 Feb 2022 20:58:22 +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:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id: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=Nzwj7qrPbUPlqYfP7/iVafWZmadkssmSgONDigqA7Ck=; b=OghHcZog7rA44J sfAVdkqI0P0BVzskBr2Uv7oxyySR+kiiqNuSpzNt6ZAPvsQWEsDBz90KLtTox+GbCZcZisaoD1vQj hb8HNtBQ0Wp4AFGnc/ybf2S7g8fFm6hMRaEvlVnGkzSbqXG85THRLhFeFjBA7jO7nntGTLYPDFuHv 0J8CoWyl3oVpqYklyXHcHxd1nX7LFjQKhAOJcpcE1J5VxZXf8+APwLjjNuCsy3g3bZtBBRHk3Tznl 6wc6sLDvFx2EbBwgsRjEwUw7sHfcgXwY+dlvKdcmWCq/gYoNzl9Ism5kLq8C9HvtG0OP/pdA54O9P DNxCu6RRKXD9inWHkvPA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQbK-00A7SA-Du; Sun, 27 Feb 2022 20:57:06 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQah-00A7C3-QC for linux-arm-kernel@lists.infradead.org; Sun, 27 Feb 2022 20:56:29 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id DEEEF12FC; Sun, 27 Feb 2022 12:56:26 -0800 (PST) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 8359E3F66F; Sun, 27 Feb 2022 12:56:25 -0800 (PST) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, peter.hilber@opensynergy.com, cristian.marussi@arm.com Subject: [RFC PATCH 03/16] firmware: arm_scmi: Add multiple protocols registration support Date: Sun, 27 Feb 2022 20:55:55 +0000 Message-Id: <20220227205608.30812-4-cristian.marussi@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220227205608.30812-1-cristian.marussi@arm.com> References: <20220227205608.30812-1-cristian.marussi@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220227_125627_973903_68DD9ED0 X-CRM114-Status: GOOD ( 15.49 ) 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add the capability for one SCMI driver to register with the core SCMI stack to use multiple SCMI protocols: in such a case the SCMI driver probe function will end up being called once for each registered protocol which have been also found as implemented on the platform. This is especially useful in testing scenarios. Signed-off-by: Cristian Marussi --- drivers/firmware/arm_scmi/bus.c | 4 ++-- drivers/firmware/arm_scmi/common.h | 4 ++-- drivers/firmware/arm_scmi/driver.c | 24 ++++++++++++++++++++++-- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c index f6fe723ab869..e417e84249f2 100644 --- a/drivers/firmware/arm_scmi/bus.c +++ b/drivers/firmware/arm_scmi/bus.c @@ -135,7 +135,7 @@ int scmi_driver_register(struct scmi_driver *driver, struct module *owner, if (!driver->probe) return -EINVAL; - retval = scmi_protocol_device_request(driver->id_table); + retval = scmi_protocol_table_register(driver->id_table); if (retval) return retval; @@ -155,7 +155,7 @@ EXPORT_SYMBOL_GPL(scmi_driver_register); void scmi_driver_unregister(struct scmi_driver *driver) { driver_unregister(&driver->driver); - scmi_protocol_device_unrequest(driver->id_table); + scmi_protocol_table_unregister(driver->id_table); } EXPORT_SYMBOL_GPL(scmi_driver_unregister); diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h index 4fda84bfab42..ffaf74a36b30 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -388,8 +388,8 @@ struct scmi_transport_ops { bool (*poll_done)(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer); }; -int scmi_protocol_device_request(const struct scmi_device_id *id_table); -void scmi_protocol_device_unrequest(const struct scmi_device_id *id_table); +int scmi_protocol_table_register(const struct scmi_device_id *id_table); +void scmi_protocol_table_unregister(const struct scmi_device_id *id_table); struct scmi_device *scmi_child_dev_find(struct device *parent, int prot_id, const char *name); diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 4cb9e0ad7af5..8d356d4da0bd 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -1771,7 +1771,7 @@ static void scmi_create_protocol_devices(struct device_node *np, * * Return: 0 on Success */ -int scmi_protocol_device_request(const struct scmi_device_id *id_table) +static int scmi_protocol_device_request(const struct scmi_device_id *id_table) { int ret = 0; unsigned int id = 0; @@ -1882,6 +1882,17 @@ int scmi_protocol_device_request(const struct scmi_device_id *id_table) return ret; } +int scmi_protocol_table_register(const struct scmi_device_id *id_table) +{ + int ret = 0; + const struct scmi_device_id *entry; + + for (entry = id_table; entry->name && ret == 0; entry++) + ret = scmi_protocol_device_request(entry); + + return ret; +} + /** * scmi_protocol_device_unrequest - Helper to unrequest a device * @@ -1896,7 +1907,8 @@ int scmi_protocol_device_request(const struct scmi_device_id *id_table) * that cannot be safely destroyed till the whole SCMI stack is removed. * (unless adding further burden of refcounting.) */ -void scmi_protocol_device_unrequest(const struct scmi_device_id *id_table) +static void +scmi_protocol_device_unrequest(const struct scmi_device_id *id_table) { struct list_head *phead; @@ -1925,6 +1937,14 @@ void scmi_protocol_device_unrequest(const struct scmi_device_id *id_table) mutex_unlock(&scmi_requested_devices_mtx); } +void scmi_protocol_table_unregister(const struct scmi_device_id *id_table) +{ + const struct scmi_device_id *entry; + + for (entry = id_table; entry->name; entry++) + scmi_protocol_device_unrequest(entry); +} + static int scmi_cleanup_txrx_channels(struct scmi_info *info) { int ret; From patchwork Sun Feb 27 20:55:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 12762136 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 74D88C433EF for ; Sun, 27 Feb 2022 20:58:38 +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:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id: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=wbbSkXEg5HYtvtr0anfCLVsXgG5pZwp6qbHL4DF1nhw=; b=CTJbOD6Ki8VaLR QoEcJsRvJBjWOy62IC6qiRxyLfbZYqGwpO4wApmvz2m5Gio/f1PBxv53RmQVrnya/WhsHDW6De/76 dZ04rODd0PmBCqsi3MszC98lJ/Rr0VJXQFcU8IOy9d5S9dzuWIqaQY+zaqFbGOrukgrkQKODPcsJR o9oRrxLn7z052hZtydrkuP/Xcmf2UnYB8tctc8EW/MpS4Y/Ynur7fHlj9tQZpjFKflV/R8IvrJzLX JGmVNuW0NjW2Z6s52VTwHow0Si488rgF9nSywe6gwGqR9xGSD0TWAlrAnSqM99k98btJ23WCg9Py1 He9JADKomYs9Ex2rDlRw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQbY-00A7XS-O9; Sun, 27 Feb 2022 20:57:20 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQaj-00A7Cu-Sc for linux-arm-kernel@lists.infradead.org; Sun, 27 Feb 2022 20:56:32 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 7DF5D1424; Sun, 27 Feb 2022 12:56:28 -0800 (PST) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 20C7D3F66F; Sun, 27 Feb 2022 12:56:27 -0800 (PST) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, peter.hilber@opensynergy.com, cristian.marussi@arm.com Subject: [RFC PATCH 04/16] firmware: arm_scmi: Add .version_get protocol operation Date: Sun, 27 Feb 2022 20:55:56 +0000 Message-Id: <20220227205608.30812-5-cristian.marussi@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220227205608.30812-1-cristian.marussi@arm.com> References: <20220227205608.30812-1-cristian.marussi@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220227_125630_066488_B2EBDEBA X-CRM114-Status: GOOD ( 17.33 ) 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add new .version_get protocol operation so as to allow interested SCMI driver users to lookup protocol versions implemented by the underlying SCMI platform. Signed-off-by: Cristian Marussi --- drivers/firmware/arm_scmi/clock.c | 1 + drivers/firmware/arm_scmi/common.h | 20 ++++++++++++++++++++ drivers/firmware/arm_scmi/perf.c | 1 + drivers/firmware/arm_scmi/power.c | 1 + drivers/firmware/arm_scmi/reset.c | 1 + drivers/firmware/arm_scmi/sensors.c | 1 + drivers/firmware/arm_scmi/system.c | 6 +++++- drivers/firmware/arm_scmi/voltage.c | 1 + include/linux/scmi_protocol.h | 22 ++++++++++++++++++++++ 9 files changed, 53 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/arm_scmi/clock.c b/drivers/firmware/arm_scmi/clock.c index e2059d2025a2..c19b6bff370d 100644 --- a/drivers/firmware/arm_scmi/clock.c +++ b/drivers/firmware/arm_scmi/clock.c @@ -344,6 +344,7 @@ scmi_clock_info_get(const struct scmi_protocol_handle *ph, u32 clk_id) } static const struct scmi_clk_proto_ops clk_proto_ops = { + .version_get = scmi_protocol_version_get, .count_get = scmi_clock_count_get, .info_get = scmi_clock_info_get, .rate_get = scmi_clock_rate_get, diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h index ffaf74a36b30..e7e9c8c5d48c 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -269,6 +269,26 @@ struct scmi_xfer_ops { struct scmi_xfer *xfer); }; +/** + * scmi_protocol_version_get - Common helper to get protocol version + * + * @ph: A reference to an initialized protocol handle + * + * Exposed as .version_get for each protocol operations, it can be called by + * SCMI drivers only on initialized protocol instances so it cannot fail. + * + * Return: Protocol version for the specified protocol handle + */ +static inline +unsigned int scmi_protocol_version_get(struct scmi_protocol_handle *ph) +{ + u32 version = 0; + + ph->xops->version_get(ph, &version); + + return version; +} + struct scmi_revision_info * scmi_revision_area_get(const struct scmi_protocol_handle *ph); int scmi_handle_put(const struct scmi_handle *handle); diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c index e9f68b91580c..e58490a8d0e7 100644 --- a/drivers/firmware/arm_scmi/perf.c +++ b/drivers/firmware/arm_scmi/perf.c @@ -756,6 +756,7 @@ static bool scmi_power_scale_mw_get(const struct scmi_protocol_handle *ph) } static const struct scmi_perf_proto_ops perf_proto_ops = { + .version_get = scmi_protocol_version_get, .limits_set = scmi_perf_limits_set, .limits_get = scmi_perf_limits_get, .level_set = scmi_perf_level_set, diff --git a/drivers/firmware/arm_scmi/power.c b/drivers/firmware/arm_scmi/power.c index 0f0b94f0b624..c14bdb9a9ccd 100644 --- a/drivers/firmware/arm_scmi/power.c +++ b/drivers/firmware/arm_scmi/power.c @@ -184,6 +184,7 @@ static char *scmi_power_name_get(const struct scmi_protocol_handle *ph, } static const struct scmi_power_proto_ops power_proto_ops = { + .version_get = scmi_protocol_version_get, .num_domains_get = scmi_power_num_domains_get, .name_get = scmi_power_name_get, .state_set = scmi_power_state_set, diff --git a/drivers/firmware/arm_scmi/reset.c b/drivers/firmware/arm_scmi/reset.c index 9cdbd133db10..acf83ea361ed 100644 --- a/drivers/firmware/arm_scmi/reset.c +++ b/drivers/firmware/arm_scmi/reset.c @@ -196,6 +196,7 @@ scmi_reset_domain_deassert(const struct scmi_protocol_handle *ph, u32 domain) } static const struct scmi_reset_proto_ops reset_proto_ops = { + .version_get = scmi_protocol_version_get, .num_domains_get = scmi_reset_num_domains_get, .name_get = scmi_reset_name_get, .latency_get = scmi_reset_latency_get, diff --git a/drivers/firmware/arm_scmi/sensors.c b/drivers/firmware/arm_scmi/sensors.c index f37ac9824a87..4ee578cf0c23 100644 --- a/drivers/firmware/arm_scmi/sensors.c +++ b/drivers/firmware/arm_scmi/sensors.c @@ -828,6 +828,7 @@ static int scmi_sensor_count_get(const struct scmi_protocol_handle *ph) } static const struct scmi_sensor_proto_ops sensor_proto_ops = { + .version_get = scmi_protocol_version_get, .count_get = scmi_sensor_count_get, .info_get = scmi_sensor_info_get, .trip_point_config = scmi_sensor_trip_point_config, diff --git a/drivers/firmware/arm_scmi/system.c b/drivers/firmware/arm_scmi/system.c index cbfc19f7a463..90157d7f45bc 100644 --- a/drivers/firmware/arm_scmi/system.c +++ b/drivers/firmware/arm_scmi/system.c @@ -33,6 +33,10 @@ struct scmi_system_info { u32 version; }; +static struct scmi_system_proto_ops system_proto_ops = { + .version_get = scmi_protocol_version_get, +}; + static int scmi_system_request_notify(const struct scmi_protocol_handle *ph, bool enable) { @@ -136,7 +140,7 @@ static const struct scmi_protocol scmi_system = { .id = SCMI_PROTOCOL_SYSTEM, .owner = THIS_MODULE, .instance_init = &scmi_system_protocol_init, - .ops = NULL, + .ops = &system_proto_ops, .events = &system_protocol_events, }; diff --git a/drivers/firmware/arm_scmi/voltage.c b/drivers/firmware/arm_scmi/voltage.c index ac08e819088b..c9a7cbdc9164 100644 --- a/drivers/firmware/arm_scmi/voltage.c +++ b/drivers/firmware/arm_scmi/voltage.c @@ -324,6 +324,7 @@ static int scmi_voltage_domains_num_get(const struct scmi_protocol_handle *ph) } static struct scmi_voltage_proto_ops voltage_proto_ops = { + .version_get = scmi_protocol_version_get, .num_domains_get = scmi_voltage_domains_num_get, .info_get = scmi_voltage_info_get, .config_set = scmi_voltage_config_set, diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h index b0652f1411b9..c5881d15f7d9 100644 --- a/include/linux/scmi_protocol.h +++ b/include/linux/scmi_protocol.h @@ -65,6 +65,7 @@ struct scmi_protocol_handle; * struct scmi_clk_proto_ops - represents the various operations provided * by SCMI Clock Protocol * + * @version_get: get the protocol version implemented by this SCMI instance * @count_get: get the count of clocks provided by SCMI * @info_get: get the information of the specified clock * @rate_get: request the current clock rate of a clock @@ -73,6 +74,7 @@ struct scmi_protocol_handle; * @disable: disables the specified clock */ struct scmi_clk_proto_ops { + unsigned int (*version_get)(struct scmi_protocol_handle *ph); int (*count_get)(const struct scmi_protocol_handle *ph); const struct scmi_clock_info *(*info_get) @@ -92,6 +94,7 @@ struct scmi_clk_proto_ops { * struct scmi_perf_proto_ops - represents the various operations provided * by SCMI Performance Protocol * + * @version_get: get the protocol version implemented by this SCMI instance * @limits_set: sets limits on the performance level of a domain * @limits_get: gets limits on the performance level of a domain * @level_set: sets the performance level of a domain @@ -111,6 +114,7 @@ struct scmi_clk_proto_ops { * or in some other (abstract) scale */ struct scmi_perf_proto_ops { + unsigned int (*version_get)(struct scmi_protocol_handle *ph); int (*limits_set)(const struct scmi_protocol_handle *ph, u32 domain, u32 max_perf, u32 min_perf); int (*limits_get)(const struct scmi_protocol_handle *ph, u32 domain, @@ -139,12 +143,14 @@ struct scmi_perf_proto_ops { * struct scmi_power_proto_ops - represents the various operations provided * by SCMI Power Protocol * + * @version_get: get the protocol version implemented by this SCMI instance * @num_domains_get: get the count of power domains provided by SCMI * @name_get: gets the name of a power domain * @state_set: sets the power state of a power domain * @state_get: gets the power state of a power domain */ struct scmi_power_proto_ops { + unsigned int (*version_get)(struct scmi_protocol_handle *ph); int (*num_domains_get)(const struct scmi_protocol_handle *ph); char *(*name_get)(const struct scmi_protocol_handle *ph, u32 domain); #define SCMI_POWER_STATE_TYPE_SHIFT 30 @@ -442,6 +448,7 @@ enum scmi_sensor_class { * struct scmi_sensor_proto_ops - represents the various operations provided * by SCMI Sensor Protocol * + * @version_get: get the protocol version implemented by this SCMI instance * @count_get: get the count of sensors provided by SCMI * @info_get: get the information of the specified sensor * @trip_point_config: selects and configures a trip-point of interest @@ -455,6 +462,7 @@ enum scmi_sensor_class { * @config_set: Set sensor current configuration */ struct scmi_sensor_proto_ops { + unsigned int (*version_get)(struct scmi_protocol_handle *ph); int (*count_get)(const struct scmi_protocol_handle *ph); const struct scmi_sensor_info *(*info_get) (const struct scmi_protocol_handle *ph, u32 sensor_id); @@ -475,6 +483,7 @@ struct scmi_sensor_proto_ops { * struct scmi_reset_proto_ops - represents the various operations provided * by SCMI Reset Protocol * + * @version_get: get the protocol version implemented by this SCMI instance * @num_domains_get: get the count of reset domains provided by SCMI * @name_get: gets the name of a reset domain * @latency_get: gets the reset latency for the specified reset domain @@ -483,6 +492,7 @@ struct scmi_sensor_proto_ops { * @deassert: explicitly deassert reset signal of the specified reset domain */ struct scmi_reset_proto_ops { + unsigned int (*version_get)(struct scmi_protocol_handle *ph); int (*num_domains_get)(const struct scmi_protocol_handle *ph); char *(*name_get)(const struct scmi_protocol_handle *ph, u32 domain); int (*latency_get)(const struct scmi_protocol_handle *ph, u32 domain); @@ -526,6 +536,7 @@ struct scmi_voltage_info { * struct scmi_voltage_proto_ops - represents the various operations provided * by SCMI Voltage Protocol * + * @version_get: get the protocol version implemented by this SCMI instance * @num_domains_get: get the count of voltage domains provided by SCMI * @info_get: get the information of the specified domain * @config_set: set the config for the specified domain @@ -534,6 +545,7 @@ struct scmi_voltage_info { * @level_get: get the voltage level of the specified domain */ struct scmi_voltage_proto_ops { + unsigned int (*version_get)(struct scmi_protocol_handle *ph); int (*num_domains_get)(const struct scmi_protocol_handle *ph); const struct scmi_voltage_info __must_check *(*info_get) (const struct scmi_protocol_handle *ph, u32 domain_id); @@ -549,6 +561,16 @@ struct scmi_voltage_proto_ops { s32 *volt_uV); }; +/** + * struct scmi_system_proto_ops - represents the various operations provided + * by SCMI System Power Protocol + * + * @version_get: get the protocol version implemented by this SCMI instance + */ +struct scmi_system_proto_ops { + unsigned int (*version_get)(struct scmi_protocol_handle *ph); +}; + /** * struct scmi_notify_ops - represents notifications' operations provided by * SCMI core From patchwork Sun Feb 27 20:55:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 12762138 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 982CEC433EF for ; Sun, 27 Feb 2022 20:59:02 +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:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id: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=Ddd9Lr9XHYfthzTA2iNPoTGwUVGUqrJQua+tgQO/DCw=; b=iOsrozWys85O38 YPCRrJ+UR5SWxAUXeiS0LUNhuz4LnfqTcy2nDHTM64a3Pk55cBaCCsQ1DAJR4FTd13eUywhT/WlBv RLtU7ZJFrNpJIZ/goOOi5qYynu6G4PxB3tjVjdbhf0z+czisXUqdeIq1nRh5hE50VQ1ismj4gVhhB xzJu3b+Jyhx9yKY+zQKB3MSz1+AF5FauAK/hco3BjIHb59fiOwcPGYG+kAmZlBt+NQuIy6pew1OQD y5qrdMtgwBJxx60bRMTTXmqRGaHqhUc1ZshMs++Se0lqemhn0koKpqINVFZ6/TWiLjT3RqrJGTPC2 9Rj0/lHMaJtbMrNYab1g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQc1-00A7p6-VK; Sun, 27 Feb 2022 20:57:50 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQak-00A7DI-TU for linux-arm-kernel@lists.infradead.org; Sun, 27 Feb 2022 20:56:32 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 1AB611477; Sun, 27 Feb 2022 12:56:30 -0800 (PST) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id B39573F66F; Sun, 27 Feb 2022 12:56:28 -0800 (PST) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, peter.hilber@opensynergy.com, cristian.marussi@arm.com Subject: [RFC PATCH 05/16] firmware: arm_scmi: Expose information on configured transport Date: Sun, 27 Feb 2022 20:55:57 +0000 Message-Id: <20220227205608.30812-6-cristian.marussi@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220227205608.30812-1-cristian.marussi@arm.com> References: <20220227205608.30812-1-cristian.marussi@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220227_125631_071731_3D08EAD9 X-CRM114-Status: GOOD ( 13.14 ) 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add a common descriptor to describe transport features and expose it via the SCMI instance handle. Signed-off-by: Cristian Marussi --- drivers/firmware/arm_scmi/driver.c | 12 ++++++++++++ include/linux/scmi_protocol.h | 20 ++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 8d356d4da0bd..8c5429529946 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -1966,6 +1966,7 @@ static int scmi_probe(struct platform_device *pdev) struct scmi_handle *handle; const struct scmi_desc *desc; struct scmi_info *info; + struct scmi_transport_info *trans; struct device *dev = &pdev->dev; struct device_node *child, *np = dev->of_node; @@ -2023,6 +2024,17 @@ static int scmi_probe(struct platform_device *pdev) dev_err(dev, "Transport is not polling capable. Atomic mode not supported.\n"); + trans = devm_kzalloc(dev, sizeof(*trans), GFP_KERNEL); + if (!trans) + return -ENOMEM; + + of_property_read_string(dev->of_node, "compatible", &trans->compatible); + trans->is_atomic = + handle->is_transport_atomic(handle, + &trans->atomic_threshold_us); + trans->max_rx_timeout_ms = info->desc->max_rx_timeout_ms; + handle->transport = trans; + /* * Trigger SCMI Base protocol initialization. * It's mandatory and won't be ever released/deinit until the diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h index c5881d15f7d9..0b024d23a9b3 100644 --- a/include/linux/scmi_protocol.h +++ b/include/linux/scmi_protocol.h @@ -40,6 +40,24 @@ struct scmi_revision_info { char sub_vendor_id[SCMI_MAX_STR_SIZE]; }; +/** + * struct scmi_transport_info - transport related information + * + * @compatible: Transport name picked from compatible string + * @is_atomic: True if the underlying transport can support atomic transactions + * and atomic mode is enabled. + * @atomic_threshold_us: Optional system wide DT-configured threshold, expressed + * in microseconds, for atomic operations. + * @max_rx_timeout_ms: configured maximum timeout in milliseconds for command + * replies. + */ +struct scmi_transport_info { + const char *compatible; + bool is_atomic; + unsigned int atomic_threshold_us; + unsigned int max_rx_timeout_ms; +}; + struct scmi_clock_info { char name[SCMI_MAX_STR_SIZE]; unsigned int enable_latency; @@ -633,6 +651,7 @@ struct scmi_notify_ops { * * @dev: pointer to the SCMI device * @version: pointer to the structure containing SCMI version information + * @transport: pointer to the structure containing SCMI transport information * @devm_protocol_get: devres managed method to acquire a protocol and get specific * operations and a dedicated protocol handler * @devm_protocol_put: devres managed method to release a protocol @@ -650,6 +669,7 @@ struct scmi_notify_ops { struct scmi_handle { struct device *dev; struct scmi_revision_info *version; + struct scmi_transport_info *transport; const void __must_check * (*devm_protocol_get)(struct scmi_device *sdev, u8 proto, From patchwork Sun Feb 27 20:55:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 12762139 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 CF1FFC433F5 for ; Sun, 27 Feb 2022 20:59:14 +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:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id: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=th9DZZFF6vwb8kDpw700u6qpERBLpr6mDrw1Boz2chg=; b=FlGRL2hRiyyEVr LqTMA+rfC7W7K3uw7sXO9b2jrVR3Plp72sXsN4XgUHvKC1n45Rzm5kqGLodZYnFevT255MT+VU5aq D2Latp0FbzEvXPCdOJuRYvCdEzWPMFXNxe/Nsyy9BP23M9RQgNbbf4aYXlyajWyhUd4MoZSF5/fqc ZriTGadhHcCCrH1Qr6jNyMdsFIzwgRCwI612Pi1jO9o1RB8iJhHT8z5SNQicDomQBcjhJQTMPB1Fh 5Pf/Ey4+ueN1AO0GpzyfA77rSLJmNMlLZNep2CzcZ5otkjSDDlEK9RXk2k5svHPZzNuD8l/PsiVfx Z1ceSnYb5qR+qPGmNvmg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQcI-00A7xU-NN; Sun, 27 Feb 2022 20:58:06 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQam-00A7Cu-8C for linux-arm-kernel@lists.infradead.org; Sun, 27 Feb 2022 20:56:33 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id ABF7D14BF; Sun, 27 Feb 2022 12:56:31 -0800 (PST) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 508483F66F; Sun, 27 Feb 2022 12:56:30 -0800 (PST) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, peter.hilber@opensynergy.com, cristian.marussi@arm.com Subject: [RFC PATCH 06/16] firmware: arm_scmi: Define a common SCMI_MAX_PROTOCOLS value Date: Sun, 27 Feb 2022 20:55:58 +0000 Message-Id: <20220227205608.30812-7-cristian.marussi@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220227205608.30812-1-cristian.marussi@arm.com> References: <20220227205608.30812-1-cristian.marussi@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220227_125632_366624_86A339C9 X-CRM114-Status: UNSURE ( 9.44 ) X-CRM114-Notice: Please train this message. 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add a common definition of SCMI_MAX_PROTOCOLS and use it all over the SCMI stack. Signed-off-by: Cristian Marussi --- drivers/firmware/arm_scmi/notify.c | 4 +--- include/linux/scmi_protocol.h | 3 +++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/firmware/arm_scmi/notify.c b/drivers/firmware/arm_scmi/notify.c index 7d0b01b59616..5ccee248c22e 100644 --- a/drivers/firmware/arm_scmi/notify.c +++ b/drivers/firmware/arm_scmi/notify.c @@ -94,8 +94,6 @@ #include "common.h" #include "notify.h" -#define SCMI_MAX_PROTO 256 - #define PROTO_ID_MASK GENMASK(31, 24) #define EVT_ID_MASK GENMASK(23, 16) #define SRC_ID_MASK GENMASK(15, 0) @@ -1637,7 +1635,7 @@ int scmi_notification_init(struct scmi_handle *handle) ni->gid = gid; ni->handle = handle; - ni->registered_protocols = devm_kcalloc(handle->dev, SCMI_MAX_PROTO, + ni->registered_protocols = devm_kcalloc(handle->dev, SCMI_MAX_PROTOCOLS, sizeof(char *), GFP_KERNEL); if (!ni->registered_protocols) goto err; diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h index 0b024d23a9b3..63c1d1cc20ff 100644 --- a/include/linux/scmi_protocol.h +++ b/include/linux/scmi_protocol.h @@ -690,8 +690,11 @@ enum scmi_std_protocol { SCMI_PROTOCOL_SENSOR = 0x15, SCMI_PROTOCOL_RESET = 0x16, SCMI_PROTOCOL_VOLTAGE = 0x17, + SCMI_PROTOCOL_LAST = 0xff, }; +#define SCMI_MAX_PROTOCOLS (SCMI_PROTOCOL_LAST + 1) + enum scmi_system_events { SCMI_SYSTEM_SHUTDOWN, SCMI_SYSTEM_COLDRESET, From patchwork Sun Feb 27 20:55:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 12762140 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 B19C1C433EF for ; Sun, 27 Feb 2022 20:59:48 +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:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id: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=SfeRV1UCeNWcD79ksQ/+9TlCucCgBLJY3cqNlXl9VKg=; b=XXon2MO2p/amMc el96F28PAhjbJETxFIwlGZE14Snpc3OY0o4rdkcdFr16T7h9SNE6dYnx5fme7ib/m+O9mszFemgIn gbaAPvOchPFimPfEjWsY1UflUbsO86R0BCbgeRqtynFgzRWDaKoK28kyE08vdvSojdM8y6UmZQmG+ lhqTvRDaPvMo4A/lVulibXxn1OGjaOBVvm2gdcH5dUZK7AkP4lGEZ+ou0LkG4pJUYB5IVCMrT5E+U sOQ0iDXZzg6A37mumWqPI+DdGHp9u0dx2E5Zz70f2nStiwPtgAdMh9zMCX2DJ0TH7mfkJs5miBgN4 Y3V9zc5Bpqpfrp02/H6Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQcm-00A8Ev-QU; Sun, 27 Feb 2022 20:58:37 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQao-00A7Cu-VN for linux-arm-kernel@lists.infradead.org; Sun, 27 Feb 2022 20:56:36 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 9D9241063; Sun, 27 Feb 2022 12:56:33 -0800 (PST) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id E27883F66F; Sun, 27 Feb 2022 12:56:31 -0800 (PST) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, peter.hilber@opensynergy.com, cristian.marussi@arm.com, Greg Kroah-Hartman , "Rafael J. Wysocki" , Alexander Viro Subject: [RFC PATCH 07/16] debugfs: Add signed versions of debugfs_create_u32/64 helpers Date: Sun, 27 Feb 2022 20:55:59 +0000 Message-Id: <20220227205608.30812-8-cristian.marussi@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220227205608.30812-1-cristian.marussi@arm.com> References: <20220227205608.30812-1-cristian.marussi@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220227_125635_191105_8B7EFA52 X-CRM114-Status: GOOD ( 18.64 ) 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add a few helpers to deal with signed values integers; built on existing debugfs internal helpers as the existing unsigned functions already do. Make the simple_attr_write() internal helper detect the sign of the requested set operation from the related format string: this is needed to be able to properly parse negatively signed input strings. Cc: Greg Kroah-Hartman Cc: "Rafael J. Wysocki" Cc: Alexander Viro Signed-off-by: Cristian Marussi --- Note that in the rest of the series I do NOT need the s64 WRITE/SET operations, that required the more invasive simple_attr_write() change, but it seemed odd to implement a get only debug_create_s32/64 API. --- fs/debugfs/file.c | 74 +++++++++++++++++++++++++++++++++++++++++ fs/libfs.c | 12 +++++-- include/linux/debugfs.h | 4 +++ 3 files changed, 87 insertions(+), 3 deletions(-) diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c index 950c63fa4d0b..5363b12c3dcb 100644 --- a/fs/debugfs/file.c +++ b/fs/debugfs/file.c @@ -556,6 +556,80 @@ void debugfs_create_u64(const char *name, umode_t mode, struct dentry *parent, } EXPORT_SYMBOL_GPL(debugfs_create_u64); +static int debugfs_s32_set(void *data, u64 val) +{ + *(s32 *)data = val; + return 0; +} + +static int debugfs_s32_get(void *data, u64 *val) +{ + *val = *(s32 *)data; + return 0; +} +DEFINE_DEBUGFS_ATTRIBUTE(fops_s32, debugfs_s32_get, debugfs_s32_set, "%lld\n"); +DEFINE_DEBUGFS_ATTRIBUTE(fops_s32_ro, debugfs_s32_get, NULL, "%lld\n"); +DEFINE_DEBUGFS_ATTRIBUTE(fops_s32_wo, NULL, debugfs_s32_set, "%lld\n"); + +/** + * debugfs_create_s32 - create a debugfs file that is used to read and write an signed 32-bit value + * @name: a pointer to a string containing the name of the file to create. + * @mode: the permission that the file should have + * @parent: a pointer to the parent dentry for this file. This should be a + * directory dentry if set. If this parameter is %NULL, then the + * file will be created in the root of the debugfs filesystem. + * @value: a pointer to the variable that the file should read to and write + * from. + * + * This function creates a file in debugfs with the given name that + * contains the value of the variable @value. If the @mode variable is so + * set, it can be read from, and written to. + */ +void debugfs_create_s32(const char *name, umode_t mode, struct dentry *parent, + s32 *value) +{ + debugfs_create_mode_unsafe(name, mode, parent, value, &fops_s32, + &fops_s32_ro, &fops_s32_wo); +} +EXPORT_SYMBOL_GPL(debugfs_create_s32); + +static int debugfs_s64_set(void *data, u64 val) +{ + *(s64 *)data = val; + return 0; +} + +static int debugfs_s64_get(void *data, u64 *val) +{ + *val = *(s64 *)data; + return 0; +} +DEFINE_DEBUGFS_ATTRIBUTE(fops_s64, debugfs_s64_get, debugfs_s64_set, "%lld\n"); +DEFINE_DEBUGFS_ATTRIBUTE(fops_s64_ro, debugfs_s64_get, NULL, "%lld\n"); +DEFINE_DEBUGFS_ATTRIBUTE(fops_s64_wo, NULL, debugfs_s64_set, "%lld\n"); + +/** + * debugfs_create_s64 - create a debugfs file that is used to read and write a signed 64-bit value + * @name: a pointer to a string containing the name of the file to create. + * @mode: the permission that the file should have + * @parent: a pointer to the parent dentry for this file. This should be a + * directory dentry if set. If this parameter is %NULL, then the + * file will be created in the root of the debugfs filesystem. + * @value: a pointer to the variable that the file should read to and write + * from. + * + * This function creates a file in debugfs with the given name that + * contains the value of the variable @value. If the @mode variable is so + * set, it can be read from, and written to. + */ +void debugfs_create_s64(const char *name, umode_t mode, struct dentry *parent, + s64 *value) +{ + debugfs_create_mode_unsafe(name, mode, parent, value, &fops_s64, + &fops_s64_ro, &fops_s64_wo); +} +EXPORT_SYMBOL_GPL(debugfs_create_s64); + static int debugfs_ulong_set(void *data, u64 val) { *(unsigned long *)data = val; diff --git a/fs/libfs.c b/fs/libfs.c index ba7438ab9371..f5a554ed363b 100644 --- a/fs/libfs.c +++ b/fs/libfs.c @@ -917,8 +917,8 @@ EXPORT_SYMBOL(simple_transaction_release); struct simple_attr { int (*get)(void *, u64 *); int (*set)(void *, u64); - char get_buf[24]; /* enough to store a u64 and "\n\0" */ - char set_buf[24]; + char get_buf[25]; /* enough to store a u64, a sign and "\n\0" */ + char set_buf[25]; void *data; const char *fmt; /* format for read operation */ struct mutex mutex; /* protects access to these buffers */ @@ -1001,6 +1001,7 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf, unsigned long long val; size_t size; ssize_t ret; + char *_fmt; attr = file->private_data; if (!attr->set) @@ -1016,7 +1017,12 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf, goto out; attr->set_buf[size] = '\0'; - ret = kstrtoull(attr->set_buf, 0, &val); + _fmt = strchr(attr->fmt, '%'); + /* Deduce signedness from read format string specifier */ + if (_fmt && (strchr(_fmt, 'd') || strchr(_fmt, 'i'))) + ret = kstrtoll(attr->set_buf, 0, (long long *)&val); + else + ret = kstrtoull(attr->set_buf, 0, &val); if (ret) goto out; ret = attr->set(attr->data, val); diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index c869f1e73d75..1b8ea858f261 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h @@ -114,6 +114,10 @@ void debugfs_create_u64(const char *name, umode_t mode, struct dentry *parent, u64 *value); void debugfs_create_ulong(const char *name, umode_t mode, struct dentry *parent, unsigned long *value); +void debugfs_create_s32(const char *name, umode_t mode, struct dentry *parent, + s32 *value); +void debugfs_create_s64(const char *name, umode_t mode, struct dentry *parent, + s64 *value); void debugfs_create_x8(const char *name, umode_t mode, struct dentry *parent, u8 *value); void debugfs_create_x16(const char *name, umode_t mode, struct dentry *parent, From patchwork Sun Feb 27 20:56:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 12762141 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 18756C433EF for ; Sun, 27 Feb 2022 21:00:07 +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:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id: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=W+SLnQYqolaTfWPTglka5DsOH1uOBKIjVwCiHVQoMkY=; b=i6W2VtGAfIEy/J cNwL36KZbJf1vfZEbomeThIR3KLamoiubnwKdf7x3LU74ijKkMoppZ7qjFRF6bw18haAuDWooVVUK Y1mVN61mhLRiycVEJKeOEXu+RlJnaEYPd3C8xpPYx4wIL3tBiWE4iePpTHjLFGiOHF+MUerBJKZUl 3wVkMwJ3LKYqBRqGwjAHrAVUtOqv+/w+YAx3L4TR0AmRvwX38/BBitDO7C4JIMjeHPL9BLTWRarBs vxZ0IzceggFK8cK76m5JWSP0TL2SFxVKRvwbUcoRc2T2a0NOtmQ8coTO0r5/GwBr5oeM4zyzUaYFc rOBkRJ2kg8qrGBRRdPLQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQd2-00A8Ox-HL; Sun, 27 Feb 2022 20:58:52 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQaq-00A7FL-Ad for linux-arm-kernel@lists.infradead.org; Sun, 27 Feb 2022 20:56:39 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 5815A106F; Sun, 27 Feb 2022 12:56:35 -0800 (PST) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id D35573F66F; Sun, 27 Feb 2022 12:56:33 -0800 (PST) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, peter.hilber@opensynergy.com, cristian.marussi@arm.com Subject: [RFC PATCH 08/16] firmware: arm_scmi: Add SCMI Testing driver Date: Sun, 27 Feb 2022 20:56:00 +0000 Message-Id: <20220227205608.30812-9-cristian.marussi@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220227205608.30812-1-cristian.marussi@arm.com> References: <20220227205608.30812-1-cristian.marussi@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220227_125636_509101_AC6312B7 X-CRM114-Status: GOOD ( 28.75 ) 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add an SCMI driver that would expose all of the available SCMI protocol operations and resources under a debugfs rooted at /sys/kernel/debug/scmi, so as to be then able to script generic SCMI testcases simply accessing the available debugfs entries. The aim is to be able to test the Kernel SCMI stack in isolation without the constraints or interferences carried by the original SCMI drivers that by their nature belong and are driven by a number of Kernel subsystems: indeed, if this testing driver is enabled at compilation time, loading of all the other regular SCMI drivers is inhibited. Beside such generic SCMI test driver infrastructure, add also basic support for testing SCMI Clock protocol. Signed-off-by: Cristian Marussi --- Documentation/ABI/testing/debugfs-scmi | 101 ++++++++++++ drivers/firmware/arm_scmi/Kconfig | 12 ++ drivers/firmware/arm_scmi/Makefile | 2 + drivers/firmware/arm_scmi/driver.c | 9 + .../arm_scmi/scmi_test_driver/Makefile | 4 + .../arm_scmi/scmi_test_driver/scmi_test.c | 154 ++++++++++++++++++ .../arm_scmi/scmi_test_driver/test_clocks.c | 139 ++++++++++++++++ .../arm_scmi/scmi_test_driver/test_common.c | 60 +++++++ .../arm_scmi/scmi_test_driver/test_common.h | 76 +++++++++ 9 files changed, 557 insertions(+) create mode 100644 Documentation/ABI/testing/debugfs-scmi create mode 100644 drivers/firmware/arm_scmi/scmi_test_driver/Makefile create mode 100644 drivers/firmware/arm_scmi/scmi_test_driver/scmi_test.c create mode 100644 drivers/firmware/arm_scmi/scmi_test_driver/test_clocks.c create mode 100644 drivers/firmware/arm_scmi/scmi_test_driver/test_common.c create mode 100644 drivers/firmware/arm_scmi/scmi_test_driver/test_common.h diff --git a/Documentation/ABI/testing/debugfs-scmi b/Documentation/ABI/testing/debugfs-scmi new file mode 100644 index 000000000000..85177f3723c8 --- /dev/null +++ b/Documentation/ABI/testing/debugfs-scmi @@ -0,0 +1,101 @@ +What: /sys/kernel/debug/scmi/info/major_ver +Date: Feb 2022 +KernelVersion: 5.18 +Contact: cristian.marussi@arm.com +Description: SCMI protocol stack major version +Users: KSelftest, Debugging + +What: /sys/kernel/debug/scmi/info/minor_ver +Date: Feb 2022 +KernelVersion: 5.18 +Contact: cristian.marussi@arm.com +Description: SCMI protocol stack minor version +Users: KSelftest, Debugging + +What: /sys/kernel/debug/scmi/info/impl_ver +Date: Feb 2022 +KernelVersion: 5.18 +Contact: cristian.marussi@arm.com +Description: SCMI protocol stack (vendor-specific) implementation version +Users: KSelftest, Debugging + +What: /sys/kernel/debug/scmi/info/vendor_id +Date: Feb 2022 +KernelVersion: 5.18 +Contact: cristian.marussi@arm.com +Description: SCMI protocol stack vendor identifier ASCII string +Users: KSelftest, Debugging + +What: /sys/kernel/debug/scmi/info/sub_vendor_id +Date: Feb 2022 +KernelVersion: 5.18 +Contact: cristian.marussi@arm.com +Description: SCMI protocol stack sub_vendor identifier ASCII string +Users: KSelftest, Debugging + +What: /sys/kernel/debug/scmi/info/num_agents +Date: Feb 2022 +KernelVersion: 5.18 +Contact: cristian.marussi@arm.com +Description: Number of detected SCMI agents on the system +Users: KSelftest, Debugging + +What: /sys/kernel/debug/scmi/info/num_protocols +Date: Feb 2022 +KernelVersion: 5.18 +Contact: cristian.marussi@arm.com +Description: Number of detected SCMI protocols implemented on the system +Users: KSelftest, Debugging + +What: /sys/kernel/debug/scmi/transport/compatible +Date: Feb 2022 +KernelVersion: 5.18 +Contact: cristian.marussi@arm.com +Description: Name of the configured underlying SCMI transport identified + using the same compatible strings as defined in the bindings + at Documentation/devicetree/bindings/firmware/arm,scmi.yaml +Users: KSelftest, Debugging + +What: /sys/kernel/debug/scmi/transport/is_atomic +Date: Feb 2022 +KernelVersion: 5.18 +Contact: cristian.marussi@arm.com +Description: A boolen flag that states if the underlying SCMI transport + currently used is configured to support atomic mode of + operation. +Users: KSelftest, Debugging + +What: /sys/kernel/debug/scmi/transport/max_rx_timeout_ms +Date: Feb 2022 +KernelVersion: 5.18 +Contact: cristian.marussi@arm.com +Description: Represents the timeout, as configured in the underlying SCMI + transport, that is enforced while waiting for SCMI synchronous + command replies. +Users: KSelftest, Debugging + +What: /sys/kernel/debug/scmi/transport/atomic_threshold_us +Date: Feb 2022 +KernelVersion: 5.18 +Contact: cristian.marussi@arm.com +Description: System wide threshold optionally used to decide if honour or not + SCMI atomic transactions requests; its usage is described in + Documentation/devicetree/bindings/firmware/arm,scmi.yaml +Users: KSelftest, Debugging + +What: /sys/kernel/debug/scmi/protocol_0x/version +Date: Feb 2022 +KernelVersion: 5.18 +Contact: cristian.marussi@arm.com +Description: SCMI Protocol 0x version implemented on this system +Users: KSelftest, Debugging + +What: /sys/kernel/debug/scmi/protocol_0x14//info/* +Date: Feb 2022 +KernelVersion: 5.18 +Contact: cristian.marussi@arm.com +Description: SCMI Clock Protocol informational RO data for clock resource + with id : each entry under info/ subdir maps to an equally + named field of struct scmi_clock_info as documented in + include/scmi/protocol.h +Users: KSelftest, Debugging diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig index 7794bd41eaa0..a3726074c89e 100644 --- a/drivers/firmware/arm_scmi/Kconfig +++ b/drivers/firmware/arm_scmi/Kconfig @@ -148,4 +148,16 @@ config ARM_SCMI_POWER_DOMAIN will be called scmi_pm_domain. Note this may needed early in boot before rootfs may be available. +config ARM_SCMI_TEST_DRIVER + tristate "SCMI Testing driver" + depends on (ARM_SCMI_PROTOCOL && DEBUG_FS) || (COMPILE_TEST && OF) + help + This enables support for an SCMI testing driver. + Note that this driver will register as an SCMI driver user for + all SCMI standard protocols and at the same time will inhibit + the registration of any of regular SCMI drivers. + + This driver can also be built as a module. If so, the module + will be called scmi_test_driver. + endmenu diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi/Makefile index 8d4afadda38c..8382a5da9e39 100644 --- a/drivers/firmware/arm_scmi/Makefile +++ b/drivers/firmware/arm_scmi/Makefile @@ -13,6 +13,8 @@ scmi-module-objs := $(scmi-bus-y) $(scmi-driver-y) $(scmi-protocols-y) \ obj-$(CONFIG_ARM_SCMI_PROTOCOL) += scmi-module.o obj-$(CONFIG_ARM_SCMI_POWER_DOMAIN) += scmi_pm_domain.o +obj-$(CONFIG_ARM_SCMI_TEST_DRIVER) += scmi_test_driver/ + ifeq ($(CONFIG_THUMB2_KERNEL)$(CONFIG_CC_IS_CLANG),yy) # The use of R7 in the SMCCC conflicts with the compiler's use of R7 as a frame # pointer in Thumb2 mode, which is forcibly enabled by Clang when profiling diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 8c5429529946..8c4706b24368 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -1782,6 +1782,15 @@ static int scmi_protocol_device_request(const struct scmi_device_id *id_table) pr_debug("Requesting SCMI device (%s) for protocol %x\n", id_table->name, id_table->protocol_id); +#if IS_ENABLED(CONFIG_ARM_SCMI_TEST_DRIVER) + /* Reject non-testing SCMI drivers */ + if (strncmp(id_table->name, "__scmi_test", strlen("__scmi_test"))) { + pr_warn("SCMI Test driver loaded. Rejecting '%s'/0x%X\n", + id_table->name, id_table->protocol_id); + return -EINVAL; + } +#endif + /* * Search for the matching protocol rdev list and then search * of any existent equally named device...fails if any duplicate found. diff --git a/drivers/firmware/arm_scmi/scmi_test_driver/Makefile b/drivers/firmware/arm_scmi/scmi_test_driver/Makefile new file mode 100644 index 000000000000..6e3ddd177827 --- /dev/null +++ b/drivers/firmware/arm_scmi/scmi_test_driver/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only +scmi_test_driver-objs := scmi_test.o test_common.o test_clocks.o +obj-$(CONFIG_ARM_SCMI_TEST_DRIVER) += scmi_test_driver.o + diff --git a/drivers/firmware/arm_scmi/scmi_test_driver/scmi_test.c b/drivers/firmware/arm_scmi/scmi_test_driver/scmi_test.c new file mode 100644 index 000000000000..f99aa621684c --- /dev/null +++ b/drivers/firmware/arm_scmi/scmi_test_driver/scmi_test.c @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * SCMI Testing Driver. + * + * Copyright (C) 2022 ARM Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test_common.h" + +static struct dentry *scmi_dentry, *scmi_info_dentry, *scmi_trans_dentry; +DEFINE_MUTEX(scmi_test_mtx); + +static +int (*scmi_test_init[SCMI_MAX_PROTOCOLS])(struct scmi_test_setup *) = { + [SCMI_PROTOCOL_CLOCK] = scmi_test_clock_init, +}; + +static void +scmi_debugfs_common_info_create(struct scmi_revision_info *info, + struct dentry *parent) +{ + debugfs_create_u16("major_ver", 0400, parent, &info->major_ver); + debugfs_create_u16("minor_ver", 0400, parent, &info->minor_ver); + debugfs_create_u8("num_protocols", 0400, parent, + &info->num_protocols); + debugfs_create_u8("num_agents", 0400, parent, &info->num_agents); + debugfs_create_x32("impl_ver", 0400, parent, &info->impl_ver); + + debugfs_create_file("vendor_id", 0400, parent, + info->vendor_id, &scmi_test_string_file_fops); + debugfs_create_file("sub_vendor_id", 0400, parent, + info->sub_vendor_id, &scmi_test_string_file_fops); +} + +static void +scmi_debugfs_trans_info_create(struct scmi_transport_info *info, + struct dentry *parent) +{ + debugfs_create_file("compatible", 0400, parent, + (void *)info->compatible, + &scmi_test_string_file_fops); + debugfs_create_bool("is_atomic", 0400, parent, &info->is_atomic); + debugfs_create_u32("atomic_threshold_us", 0400, parent, + &info->atomic_threshold_us); + debugfs_create_u32("max_rx_timeout_ms", 0400, parent, + &info->max_rx_timeout_ms); +} + +static int scmi_testing_probe(struct scmi_device *sdev) +{ + int ret; + const void *ops; + struct scmi_protocol_handle *ph; + const struct scmi_handle *handle = sdev->handle; + struct device *dev = &sdev->dev; + struct scmi_test_setup *tsp; + char proto_dir[16]; + + if (!handle) + return -ENODEV; + + if (sdev->protocol_id > SCMI_PROTOCOL_LAST || + !scmi_test_init[sdev->protocol_id]) { + dev_warn(dev, "Testing protocol 0x%X NOT supported.\n", + sdev->protocol_id); + return -EINVAL; + } + + ops = handle->devm_protocol_get(sdev, sdev->protocol_id, &ph); + if (IS_ERR(ops)) { + dev_err(dev, "Cannot access protocol:0x%X - err:%ld\n", + sdev->protocol_id, PTR_ERR(ops)); + return PTR_ERR(ops); + } + + tsp = devm_kzalloc(&sdev->dev, sizeof(*tsp), GFP_KERNEL); + if (!tsp) + return -ENOMEM; + + tsp->sdev = sdev; + tsp->ops = ops; + tsp->ph = ph; + + snprintf(proto_dir, 16, "protocol_0x%02X", sdev->protocol_id); + tsp->parent = debugfs_create_dir(proto_dir, scmi_dentry); + if (IS_ERR(tsp->parent)) + return PTR_ERR(tsp->parent); + + ret = scmi_test_init[sdev->protocol_id](tsp); + if (ret) + return ret; + + /* Setup common information entries if not already done */ + mutex_lock(&scmi_test_mtx); + if (!scmi_info_dentry) { + scmi_info_dentry = debugfs_create_dir("info", scmi_dentry); + if (!IS_ERR(scmi_info_dentry)) + scmi_debugfs_common_info_create(sdev->handle->version, + scmi_info_dentry); + } + + if (!scmi_trans_dentry) { + scmi_trans_dentry = + debugfs_create_dir("transport", scmi_dentry); + if (!IS_ERR(scmi_trans_dentry)) + scmi_debugfs_trans_info_create(sdev->handle->transport, + scmi_trans_dentry); + } + mutex_unlock(&scmi_test_mtx); + + return ret; +} + +static const struct scmi_device_id scmi_id_table[] = { + { SCMI_PROTOCOL_CLOCK, "__scmi_test-clock" }, + { }, +}; +MODULE_DEVICE_TABLE(scmi, scmi_id_table); + +static struct scmi_driver scmi_testing_driver = { + .name = "scmi-testing-driver", + .probe = scmi_testing_probe, + .id_table = scmi_id_table, +}; + +static int __init scmi_testing_driver_init(void) +{ + scmi_dentry = debugfs_create_dir("scmi", NULL); + return scmi_driver_register(&scmi_testing_driver, + THIS_MODULE, KBUILD_MODNAME); +} +module_init(scmi_testing_driver_init); + +static void __exit scmi_testing_driver_exit(void) +{ + debugfs_remove_recursive(scmi_dentry); + scmi_driver_unregister(&scmi_testing_driver); +} +module_exit(scmi_testing_driver_exit); + +MODULE_AUTHOR("Cristian Marussi "); +MODULE_DESCRIPTION("ARM SCMI Testing Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/firmware/arm_scmi/scmi_test_driver/test_clocks.c b/drivers/firmware/arm_scmi/scmi_test_driver/test_clocks.c new file mode 100644 index 000000000000..3b9e92baa509 --- /dev/null +++ b/drivers/firmware/arm_scmi/scmi_test_driver/test_clocks.c @@ -0,0 +1,139 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * SCMI Testing Driver - Clock Protocol + * + * Copyright (C) 2022 ARM Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test_common.h" + +/* Clock Proto Test */ +struct scmi_clock_data { + unsigned int version; + int count; + const struct scmi_clock_info **clk_info; +}; + +static ssize_t scmi_test_clock_rates_read(struct file *filp, char __user *buf, + size_t count, loff_t *ppos) +{ + struct scmi_test_buffer *data = filp->private_data; + + if (!data) + return 0; + + if (!data->used) { + int c; + struct scmi_clock_info *ci = filp->f_inode->i_private; + + for (c = 0; c < ci->list.num_rates; c++) + data->used += scnprintf(data->buf + data->used, + data->len - data->used, + "%lld ", + ci->list.rates[c]); + + data->used += scnprintf(data->buf + data->used, + data->len - data->used, "\n"); + } + + return simple_read_from_buffer(buf, count, ppos, data->buf, data->used); +} + +static const struct file_operations test_clk_rates_fops = { + .open = scmi_test_fixed_buffer_open, + .release = scmi_test_release, + .read = scmi_test_clock_rates_read, +}; + +static void +scmi_test_debugfs_clock_info_create(const struct scmi_clock_info *ci, + struct dentry *top_dentry) +{ + struct dentry *parent; + struct scmi_clock_info *cinfo = (struct scmi_clock_info *)ci; + + parent = debugfs_create_dir("info", top_dentry); + if (IS_ERR(parent)) + return; + + debugfs_create_file("name", 0400, parent, cinfo->name, + &scmi_test_string_file_fops); + debugfs_create_u32("enable_latency", 0400, parent, + &cinfo->enable_latency); + + debugfs_create_bool("rate_discrete", 0400, parent, + &cinfo->rate_discrete); + + if (cinfo->rate_discrete) { + debugfs_create_u32("num_rates", 0400, parent, + &cinfo->list.num_rates); + debugfs_create_file("rates", 0400, parent, cinfo, + &test_clk_rates_fops); + } else { + debugfs_create_u64("min_rate", 0400, parent, + &cinfo->range.min_rate); + debugfs_create_u64("max_rate", 0400, parent, + &cinfo->range.max_rate); + debugfs_create_u64("step_size", 0400, parent, + &cinfo->range.step_size); + } +} + +int scmi_test_clock_init(struct scmi_test_setup *tsp) +{ + int i; + struct scmi_clock_data *cdata; + const struct scmi_clk_proto_ops *clock_ops; + struct device *dev = &tsp->sdev->dev; + + cdata = devm_kzalloc(dev, sizeof(*cdata), GFP_KERNEL); + if (!cdata) + return -ENOMEM; + + clock_ops = tsp->ops; + cdata->version = clock_ops->version_get(tsp->ph); + cdata->count = clock_ops->count_get(tsp->ph); + + if (cdata->count <= 0) { + dev_err(dev, "number of domains invalid: %d\n", + cdata->count); + return cdata->count ?: -EINVAL; + } + + cdata->clk_info = devm_kcalloc(dev, cdata->count, + sizeof(cdata->clk_info), GFP_KERNEL); + if (!cdata->clk_info) + return -ENOMEM; + + for (i = 0; i < cdata->count; i++) + cdata->clk_info[i] = clock_ops->info_get(tsp->ph, i); + + tsp->priv = cdata; + + debugfs_create_x32("version", 0400, tsp->parent, &cdata->version); + + dev_info(dev, "Found %d clock resources.\n", cdata->count); + + for (i = 0; i < cdata->count; i++) { + char clock_dir[16]; + struct dentry *clock_dentry; + + snprintf(clock_dir, 16, "%03d", i); + clock_dentry = debugfs_create_dir(clock_dir, tsp->parent); + if (!IS_ERR(clock_dentry)) + scmi_test_debugfs_clock_info_create(cdata->clk_info[i], + clock_dentry); + } + + return 0; +} diff --git a/drivers/firmware/arm_scmi/scmi_test_driver/test_common.c b/drivers/firmware/arm_scmi/scmi_test_driver/test_common.c new file mode 100644 index 000000000000..1a4b6aa35095 --- /dev/null +++ b/drivers/firmware/arm_scmi/scmi_test_driver/test_common.c @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * SCMI Testing Driver. + * + * Copyright (C) 2022 ARM Ltd. + */ + +#include +#include +#include +#include +#include +#include + +#include "test_common.h" + +/* Common File operations */ +int scmi_test_release(struct inode *ino, struct file *filp) +{ + kfree(filp->private_data); + + return 0; +} + +int scmi_test_fixed_buffer_open(struct inode *ino, struct file *filp) +{ + struct scmi_test_buffer *data; + + data = kzalloc(sizeof(*data) + SCMI_TEST_DEFAULT_BUF_SZ, GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->len = SCMI_TEST_DEFAULT_BUF_SZ; + filp->private_data = data; + + return 0; +} + +static ssize_t scmi_test_string_file_read(struct file *filp, char __user *buf, + size_t count, loff_t *ppos) +{ + struct scmi_test_buffer *data = filp->private_data; + + if (!data) + return 0; + + if (!data->used) { + char *str = filp->f_inode->i_private; + + data->used = scnprintf(data->buf, data->len, "%s\n", str); + } + + return simple_read_from_buffer(buf, count, ppos, data->buf, data->used); +} + +const struct file_operations scmi_test_string_file_fops = { + .open = scmi_test_fixed_buffer_open, + .release = scmi_test_release, + .read = scmi_test_string_file_read, +}; diff --git a/drivers/firmware/arm_scmi/scmi_test_driver/test_common.h b/drivers/firmware/arm_scmi/scmi_test_driver/test_common.h new file mode 100644 index 000000000000..1ff5bbc32ae3 --- /dev/null +++ b/drivers/firmware/arm_scmi/scmi_test_driver/test_common.h @@ -0,0 +1,76 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * SCMI Testing Driver. + * + * Copyright (C) 2022 ARM Ltd. + */ + +#ifndef __SCMI_TEST_COMMON_H +#define __SCMI_TEST_COMMON_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * struct scmi_test_setup - Test protocol setup descriptor + * @parent: A reference to the parent dentry + * @sdev: A reference to the related SCMI device + * @ops: A reference to the protocol ops + * @ph: A reference to the protocol handle to be used with the ops + * @blen: An optional minimum requested buffer length for output data; if zero + * the output test buffer is allocated of SCMI_TEST_DEFAULT_BUF_SZ bytes. + * @priv: A reference to optional protocol-specific data + * @n_priv: A reference to optional protocol-specific data needed by + * notifications + * + * This descriptor is created and initialized once per protocol in the + * main probe function and passed down to the testing protocol initialization + * functions where can be further customized before being optionally made + * available to the specific debugfs entries via inode i_private reference. + */ +struct scmi_test_setup { + struct dentry *parent; + struct scmi_device *sdev; + const void *ops; + struct scmi_protocol_handle *ph; + size_t blen; + void *priv; + void *n_priv; +}; + +/** + * struct scmi_test_buffer - Output test buffer descriptor + * @id: An optional resource id parsed at open from the debugfs entry name + * @len: Size of the allocated buffer len as pointed by @buf + * @used: Current number of used bytes in @buf + * @buf: Actual buffer for output data: default allocation size (@len), if not + * otherwise specified in scmi_test_setup.blen, is SCMI_TEST_DEFAULT_BUF_SZ. + * + * This describes a dynamically allocated output buffer which will be made + * available to each r/w debugfs entry file_operations. + */ +struct scmi_test_buffer { + unsigned int id; + size_t len; + size_t used; +#define SCMI_TEST_DEFAULT_BUF_SZ 64 + unsigned char buf[]; +}; + +extern const struct file_operations scmi_test_string_file_fops; + +int scmi_test_fixed_buffer_open(struct inode *ino, struct file *filp); +int scmi_test_release(struct inode *ino, struct file *filp); + +int scmi_test_clock_init(struct scmi_test_setup *tsp); + +#endif /* __SCMI_TEST_COMMON_H */ From patchwork Sun Feb 27 20:56:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 12762142 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 2B4B3C433EF for ; Sun, 27 Feb 2022 21:00:29 +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:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id: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=ZxITepvjlpHNHf8rEWVlNavo5KUgoVNca5N+whQdhBc=; b=xpcXiAo/0sXQNZ Yw2q+3ax1RiArKN/SxRfiz7sKjygpEBRc7GzkGABfgUycgpSE/SBaqsvpgUlyk5+ihdG/YeOxFw5r B84iSAgC7Z2nxrd2maJ/VDr/0xBk3paTftYWp8MWGj0ynfsZM8CwfA8RJqyty7OlBMo9Czewv4Wmc +LDFf82mSHUh5T5xJZfn16UdwfyEf8h21XD/uUFjUJDEQReiPfTCvef5LogtB0fS9VINiTKt7qbvI 25Ja4dSqWHbGs1Rm8HVWYmJNzuUtgPx56zgjectUDQnG1IQEjOtTGULGX821CuQzYCI2eus3MErrC ZOoZH5sp0caMxumCnfgQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQdJ-00A8Z6-5K; Sun, 27 Feb 2022 20:59:09 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQar-00A7Cu-K5 for linux-arm-kernel@lists.infradead.org; Sun, 27 Feb 2022 20:56:40 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id EA12C11FB; Sun, 27 Feb 2022 12:56:36 -0800 (PST) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 8D0713F66F; Sun, 27 Feb 2022 12:56:35 -0800 (PST) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, peter.hilber@opensynergy.com, cristian.marussi@arm.com Subject: [RFC PATCH 09/16] firmware: arm_scmi: testing: Add Clock protocol full support Date: Sun, 27 Feb 2022 20:56:01 +0000 Message-Id: <20220227205608.30812-10-cristian.marussi@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220227205608.30812-1-cristian.marussi@arm.com> References: <20220227205608.30812-1-cristian.marussi@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220227_125637_830131_D6F70FD0 X-CRM114-Status: GOOD ( 20.31 ) 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add SCMI Clock protocol testing support exposing SCMI Clock protocol operations under debugfs /sys/kernel/debug/scmi/protocol_0x14//, where the subdirectories represents each a distinct clock resource with ID equal . Signed-off-by: Cristian Marussi --- Documentation/ABI/testing/debugfs-scmi | 56 +++++++ .../arm_scmi/scmi_test_driver/test_clocks.c | 150 +++++++++++++++++- .../arm_scmi/scmi_test_driver/test_common.c | 48 ++++++ .../arm_scmi/scmi_test_driver/test_common.h | 1 + 4 files changed, 254 insertions(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/debugfs-scmi b/Documentation/ABI/testing/debugfs-scmi index 85177f3723c8..e91c19e7a323 100644 --- a/Documentation/ABI/testing/debugfs-scmi +++ b/Documentation/ABI/testing/debugfs-scmi @@ -99,3 +99,59 @@ Description: SCMI Clock Protocol informational RO data for clock resource named field of struct scmi_clock_info as documented in include/scmi/protocol.h Users: KSelftest, Debugging + +What: /sys/kernel/debug/scmi/protocol_0x14//rate_get_set +Date: Feb 2022 +KernelVersion: 5.19 +Contact: cristian.marussi@arm.com +Description: SCMI Clock Protocol rate get/set operation for clock resource + with id ; a read returns the currently set clock rate value + as a base-10 integer while the write of a base-10 integer sets a + new clock rate value. + Each R/W access invokes the corresponding SCMI Clock protocol + operations and issuing of needed SCMI commands. +Users: KSelftest, Debugging + +What: /sys/kernel/debug/scmi/protocol_0x14//enable +Date: Feb 2022 +KernelVersion: 5.19 +Contact: cristian.marussi@arm.com +Description: SCMI Clock Protocol enable operation for clock resource with id + ; writing a boolean value causes that specific clock to be + enabled or disabled. + No reference counting is kept: each write access invokes the + corresponding SCMI Clock protocol operations and issuing of + needed SCMI commands. +Users: KSelftest, Debugging + +What: /sys/kernel/debug/scmi/protocol_0x14//enable_atomic_irqs_on +Date: Feb 2022 +KernelVersion: 5.19 +Contact: cristian.marussi@arm.com +Description: SCMI Clock Protocol enable atomic operation for clock resource + with id ; writing a boolean value causes that specific + clock to be enabled or disabled using SCMI transport in polling + mode, if allowed by the underlying SCMI transport. + No reference counting is kept: each write access invokes the + corresponding SCMI Clock protocol operations and issuing of + needed SCMI commands. + Available only if the underlying SCMI transport is atomic + capable (/sys/kernel/debug/scmi/transport/is_atomic is True). +Users: KSelftest, Debugging + +What: /sys/kernel/debug/scmi/protocol_0x14//enable_atomic_irqs_off +Date: Feb 2022 +KernelVersion: 5.19 +Contact: cristian.marussi@arm.com +Description: SCMI Clock Protocol enable atomic operation for clock resource + with id ; writing a boolean value causes that specific + clock to be enabled or disabled using SCMI transport in polling + mode, if allowed by the underlying SCMI transport. + Local IRQs are disabled while the SCMI command transaction is + executed. + No reference counting is kept: each write access invokes the + corresponding SCMI Clock protocol operations and issuing of + needed SCMI commands. + Available only if the underlying SCMI transport is atomic + capable (/sys/kernel/debug/scmi/transport/is_atomic is True). +Users: KSelftest, Debugging diff --git a/drivers/firmware/arm_scmi/scmi_test_driver/test_clocks.c b/drivers/firmware/arm_scmi/scmi_test_driver/test_clocks.c index 3b9e92baa509..ae5b1af88f60 100644 --- a/drivers/firmware/arm_scmi/scmi_test_driver/test_clocks.c +++ b/drivers/firmware/arm_scmi/scmi_test_driver/test_clocks.c @@ -24,6 +24,139 @@ struct scmi_clock_data { const struct scmi_clock_info **clk_info; }; +static ssize_t scmi_test_clk_rate_get_read(struct file *filp, char __user *buf, + size_t count, loff_t *ppos) +{ + int ret; + struct scmi_test_buffer *data = filp->private_data; + + if (!data) + return 0; + + if (!data->used) { + u64 rate; + struct scmi_test_setup *tsp = filp->f_inode->i_private; + const struct scmi_clk_proto_ops *clock_ops = tsp->ops; + + ret = clock_ops->rate_get(tsp->ph, data->id, &rate); + if (ret) + return ret; + + data->used = scnprintf(data->buf, data->len, "%lld\n", rate); + } + + return simple_read_from_buffer(buf, count, ppos, data->buf, data->used); +} + +static ssize_t scmi_test_clk_rate_get_write(struct file *filp, + const char __user *buf, + size_t count, loff_t *ppos) +{ + int ret; + u64 rate; + struct scmi_test_setup *tsp = filp->f_inode->i_private; + const struct scmi_clk_proto_ops *clock_ops = tsp->ops; + struct scmi_test_buffer *data = filp->private_data; + + if (!data) + return 0; + + ret = kstrtou64_from_user(buf, count, 10, &rate); + if (ret < 0) + return ret; + + ret = clock_ops->rate_set(tsp->ph, data->id, rate); + if (ret) + return ret; + + return count; +} + +static const struct file_operations test_clk_rate_get_set_fops = { + .open = scmi_test_setup_open, + .release = scmi_test_release, + .read = scmi_test_clk_rate_get_read, + .write = scmi_test_clk_rate_get_write, +}; + +static ssize_t scmi_test_clk_enable_write(struct file *filp, + const char __user *buf, + size_t count, loff_t *ppos) +{ + bool enabled, irqs_off; + int ret; + unsigned long flags; + struct scmi_test_setup *tsp = filp->f_inode->i_private; + const struct scmi_clk_proto_ops *clock_ops = tsp->ops; + struct scmi_test_buffer *data = filp->private_data; + + if (!data) + return 0; + + ret = kstrtobool_from_user(buf, count, &enabled); + if (ret) + return ret; + + irqs_off = !strncmp(filp->f_path.dentry->d_name.name, + "enable_atomic_irqs_off", + strlen("enable_atomic_irqs_off")); + if (irqs_off) + local_irq_save(flags); + + if (enabled) + ret = clock_ops->enable_atomic(tsp->ph, data->id); + else + ret = clock_ops->disable_atomic(tsp->ph, data->id); + + if (irqs_off) + local_irq_restore(flags); + + if (ret) + return ret; + + return count; +} + +static const struct file_operations test_clk_enable_fops = { + .open = scmi_test_setup_open, + .release = scmi_test_release, + .write = scmi_test_clk_enable_write, +}; + +static ssize_t scmi_test_clk_prepare_enable_write(struct file *filp, + const char __user *buf, + size_t count, loff_t *ppos) +{ + bool enabled; + int ret; + struct scmi_test_setup *tsp = filp->f_inode->i_private; + const struct scmi_clk_proto_ops *clock_ops = tsp->ops; + struct scmi_test_buffer *data = filp->private_data; + + if (!data) + return 0; + + ret = kstrtobool_from_user(buf, count, &enabled); + if (ret) + return ret; + + if (enabled) + ret = clock_ops->enable(tsp->ph, data->id); + else + ret = clock_ops->disable(tsp->ph, data->id); + + if (ret) + return ret; + + return count; +} + +static const struct file_operations test_clk_prepare_enable_fops = { + .open = scmi_test_setup_open, + .release = scmi_test_release, + .write = scmi_test_clk_prepare_enable_write, +}; + static ssize_t scmi_test_clock_rates_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) { @@ -130,9 +263,24 @@ int scmi_test_clock_init(struct scmi_test_setup *tsp) snprintf(clock_dir, 16, "%03d", i); clock_dentry = debugfs_create_dir(clock_dir, tsp->parent); - if (!IS_ERR(clock_dentry)) + if (!IS_ERR(clock_dentry)) { scmi_test_debugfs_clock_info_create(cdata->clk_info[i], clock_dentry); + debugfs_create_file("rate_get_set", 0600, + clock_dentry, tsp, + &test_clk_rate_get_set_fops); + if (tsp->sdev->handle->transport->is_atomic) { + debugfs_create_file("enable_atomic_irqs_off", + 0200, clock_dentry, tsp, + &test_clk_enable_fops); + debugfs_create_file("enable_atomic_irqs_on", + 0200, clock_dentry, tsp, + &test_clk_enable_fops); + } + debugfs_create_file("enable", 0200, + clock_dentry, tsp, + &test_clk_prepare_enable_fops); + } } return 0; diff --git a/drivers/firmware/arm_scmi/scmi_test_driver/test_common.c b/drivers/firmware/arm_scmi/scmi_test_driver/test_common.c index 1a4b6aa35095..cbe2eec4f2ac 100644 --- a/drivers/firmware/arm_scmi/scmi_test_driver/test_common.c +++ b/drivers/firmware/arm_scmi/scmi_test_driver/test_common.c @@ -15,6 +15,54 @@ #include "test_common.h" /* Common File operations */ + +/** + * scmi_test_setup_open - A common open helper + * @ino: Related inode reference + * @filp: Related file pointer reference + * + * Expects to receive a struct scmi_test_setup via inode i_private reference and + * then allocate a properly sized buffer; it also tries to parse the parent + * directory name in search for a base10 integer and, if found, stores it into + * the buffer descriptor @id field: this comes handy since most of the SCMI + * protocol operations and data are bound to some specific SCMI resource id and + * the SCMI debugfs directory tree is structured to mirror this layout, so that, + * as an example, protocol would expose about its resource + * with id as: + * + * /sys/kernel/debug/scmi/protocol_0x// + * + * As as result this open would allocate a data buffer, parse the dentry and + * set data->id = + * + * Return: 0 on Success + */ +int scmi_test_setup_open(struct inode *ino, struct file *filp) +{ + unsigned int id; + size_t blen; + struct scmi_test_buffer *data; + struct scmi_test_setup *tsp = filp->f_inode->i_private; + const char *id_str = filp->f_path.dentry->d_parent->d_name.name; + + if (!tsp) + return -EINVAL; + + blen = tsp->blen ?: SCMI_TEST_DEFAULT_BUF_SZ; + data = kzalloc(sizeof(*data) + blen, GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->len = blen; + /* Grab clk ID from debugfs entry naming if any */ + if (!kstrtouint(id_str, 10, &id)) + data->id = id; + + filp->private_data = data; + + return 0; +} + int scmi_test_release(struct inode *ino, struct file *filp) { kfree(filp->private_data); diff --git a/drivers/firmware/arm_scmi/scmi_test_driver/test_common.h b/drivers/firmware/arm_scmi/scmi_test_driver/test_common.h index 1ff5bbc32ae3..3c64cae9fae9 100644 --- a/drivers/firmware/arm_scmi/scmi_test_driver/test_common.h +++ b/drivers/firmware/arm_scmi/scmi_test_driver/test_common.h @@ -68,6 +68,7 @@ struct scmi_test_buffer { extern const struct file_operations scmi_test_string_file_fops; +int scmi_test_setup_open(struct inode *ino, struct file *filp); int scmi_test_fixed_buffer_open(struct inode *ino, struct file *filp); int scmi_test_release(struct inode *ino, struct file *filp); From patchwork Sun Feb 27 20:56:02 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 12762143 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 BD825C433F5 for ; Sun, 27 Feb 2022 21:00:39 +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:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id: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=ZuHLtNXVvD04COaV+HeFzCsEgbGVFCEnr1m8Ja8aH6I=; b=ApMXRW4csIk7C+ 1RSrWaBONkykyRWACF625a/O2H9NnEsdWYX9rkFMhyS/IHhKIm5kLEq3qOLGd0tp7PB1aaxAhC/vR BUAuu7Gdheu1TqKd2Dm0vuES35FuECGiZhIpIQa7qDMlaeYgQb6gqqutjG6NrM0dqdbeI59eNktqp hXIEFCAQnLQoPWLmXUHDXAb/dXMjEbw6o9FuTYNd9JlUr3eoyCvaEYTBLEdtFpA0MPQtvP0moRmIt LXctPGQdqU89Cn2l/IRysC0oYOpoloniyWM6mLVwcHJUd4J8h6JNpfllYu/iZUiwltqrVyBiwipQd zpAymzPiyBnNtq9gSTcg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQda-00A8jS-JR; Sun, 27 Feb 2022 20:59:26 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQat-00A7Gx-Ci for linux-arm-kernel@lists.infradead.org; Sun, 27 Feb 2022 20:56:42 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 875E012FC; Sun, 27 Feb 2022 12:56:38 -0800 (PST) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 2B9C23F66F; Sun, 27 Feb 2022 12:56:37 -0800 (PST) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, peter.hilber@opensynergy.com, cristian.marussi@arm.com Subject: [RFC PATCH 10/16] firmware: arm_scmi: testing: Add Sensor protocol basic support Date: Sun, 27 Feb 2022 20:56:02 +0000 Message-Id: <20220227205608.30812-11-cristian.marussi@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220227205608.30812-1-cristian.marussi@arm.com> References: <20220227205608.30812-1-cristian.marussi@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220227_125639_630053_50ACE7A6 X-CRM114-Status: GOOD ( 23.50 ) 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add SCMI Sensor protocol testing support exposing SCMI Sensor protocol operations under debugfs /sys/kernel/debug/scmi/protocol_0x15//, where the subdirectories represents each a distinct sensor resource with ID equal . Still without any support for testing SCMI Sensor notifications. Signed-off-by: Cristian Marussi --- Documentation/ABI/testing/debugfs-scmi | 62 +++ .../arm_scmi/scmi_test_driver/Makefile | 2 +- .../arm_scmi/scmi_test_driver/scmi_test.c | 2 + .../arm_scmi/scmi_test_driver/test_common.h | 1 + .../arm_scmi/scmi_test_driver/test_sensors.c | 525 ++++++++++++++++++ 5 files changed, 591 insertions(+), 1 deletion(-) create mode 100644 drivers/firmware/arm_scmi/scmi_test_driver/test_sensors.c diff --git a/Documentation/ABI/testing/debugfs-scmi b/Documentation/ABI/testing/debugfs-scmi index e91c19e7a323..72835516dee8 100644 --- a/Documentation/ABI/testing/debugfs-scmi +++ b/Documentation/ABI/testing/debugfs-scmi @@ -155,3 +155,65 @@ Description: SCMI Clock Protocol enable atomic operation for clock resource Available only if the underlying SCMI transport is atomic capable (/sys/kernel/debug/scmi/transport/is_atomic is True). Users: KSelftest, Debugging + +What: /sys/kernel/debug/scmi/protocol_0x15//info/* +Date: Feb 2022 +KernelVersion: 5.19 +Contact: cristian.marussi@arm.com +Description: SCMI Sensor Protocol informational RO data for sensor resource + with id : each entry under info/ subdir maps to an equally + named field of struct scmi_sensor_info as documented in + include/scmi/protocol.h +Users: KSelftest, Debugging + +What: /sys/kernel/debug/scmi/protocol_0x15//reading_get +Date: Feb 2022 +KernelVersion: 5.19 +Contact: cristian.marussi@arm.com +Description: SCMI Sensor Protocol reading_get operation for sensor resource + with id ; a read returns an u64 integer value representing + the current sensor reading. +Users: KSelftest, Debugging + +What: /sys/kernel/debug/scmi/protocol_0x15//reading_get_timestamped +Date: Feb 2022 +KernelVersion: 5.19 +Contact: cristian.marussi@arm.com +Description: SCMI Sensor Protocol reading_get_timestamped operation for sensor + resource with id ; a read returns a list of pair of values + in the form :, where the TSTAMP_u64 + represents a timestamp taken by the platform when the sensor + reading was sampled. +Users: KSelftest, Debugging + +What: /sys/kernel/debug/scmi/protocol_0x15//enable +Date: Feb 2022 +KernelVersion: 5.19 +Contact: cristian.marussi@arm.com +Description: SCMI Sensor Protocol enable operation for sensor resource with + id ; a read returns a boolen value representing the current + enable state of the sensor, while writing a boolean value causes + that specific sensor to be enabled or disabled. +Users: KSelftest, Debugging + +What: /sys/kernel/debug/scmi/protocol_0x15//sensor_config +Date: Feb 2022 +KernelVersion: 5.19 +Contact: cristian.marussi@arm.com +Description: SCMI Sensor Protocol config operation for sensor resource with + id ; a read returns a base-16 integer representing the + current sensor configuration as described in the relevant SCMI + specification (SENSOR_CONFIG_GET), while writing a base-16 + integer value sets the sensor configuration as per the relevant + SCMI specification (SENSOR_CONFIG_SET). +Users: KSelftest, Debugging + +What: /sys/kernel/debug/scmi/protocol_0x15//trips//set +Date: Feb 2022 +KernelVersion: 5.19 +Contact: cristian.marussi@arm.com +Description: SCMI Sensor Protocol trip points configuration operation for + sensor resource with id and trip point number ; + writing a base-10 integer value configure and enable trip point + for sensor . +Users: KSelftest, Debugging diff --git a/drivers/firmware/arm_scmi/scmi_test_driver/Makefile b/drivers/firmware/arm_scmi/scmi_test_driver/Makefile index 6e3ddd177827..458883193f31 100644 --- a/drivers/firmware/arm_scmi/scmi_test_driver/Makefile +++ b/drivers/firmware/arm_scmi/scmi_test_driver/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0-only -scmi_test_driver-objs := scmi_test.o test_common.o test_clocks.o +scmi_test_driver-objs := scmi_test.o test_common.o test_clocks.o test_sensors.o obj-$(CONFIG_ARM_SCMI_TEST_DRIVER) += scmi_test_driver.o diff --git a/drivers/firmware/arm_scmi/scmi_test_driver/scmi_test.c b/drivers/firmware/arm_scmi/scmi_test_driver/scmi_test.c index f99aa621684c..04e01dd114c9 100644 --- a/drivers/firmware/arm_scmi/scmi_test_driver/scmi_test.c +++ b/drivers/firmware/arm_scmi/scmi_test_driver/scmi_test.c @@ -24,6 +24,7 @@ DEFINE_MUTEX(scmi_test_mtx); static int (*scmi_test_init[SCMI_MAX_PROTOCOLS])(struct scmi_test_setup *) = { [SCMI_PROTOCOL_CLOCK] = scmi_test_clock_init, + [SCMI_PROTOCOL_SENSOR] = scmi_test_sensor_init, }; static void @@ -124,6 +125,7 @@ static int scmi_testing_probe(struct scmi_device *sdev) static const struct scmi_device_id scmi_id_table[] = { { SCMI_PROTOCOL_CLOCK, "__scmi_test-clock" }, + { SCMI_PROTOCOL_SENSOR, "__scmi_test-sensor" }, { }, }; MODULE_DEVICE_TABLE(scmi, scmi_id_table); diff --git a/drivers/firmware/arm_scmi/scmi_test_driver/test_common.h b/drivers/firmware/arm_scmi/scmi_test_driver/test_common.h index 3c64cae9fae9..e02c2521f090 100644 --- a/drivers/firmware/arm_scmi/scmi_test_driver/test_common.h +++ b/drivers/firmware/arm_scmi/scmi_test_driver/test_common.h @@ -73,5 +73,6 @@ int scmi_test_fixed_buffer_open(struct inode *ino, struct file *filp); int scmi_test_release(struct inode *ino, struct file *filp); int scmi_test_clock_init(struct scmi_test_setup *tsp); +int scmi_test_sensor_init(struct scmi_test_setup *tsp); #endif /* __SCMI_TEST_COMMON_H */ diff --git a/drivers/firmware/arm_scmi/scmi_test_driver/test_sensors.c b/drivers/firmware/arm_scmi/scmi_test_driver/test_sensors.c new file mode 100644 index 000000000000..23206c2bac98 --- /dev/null +++ b/drivers/firmware/arm_scmi/scmi_test_driver/test_sensors.c @@ -0,0 +1,525 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * SCMI Testing Driver - Clock Protocol + * + * Copyright (C) 2022 ARM Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test_common.h" + +struct scmi_sensor_data { + unsigned int version; + int count; + const struct scmi_sensor_info **sinfo; +}; + +static int scmi_test_sensor_reading_open(struct inode *ino, struct file *filp) +{ + unsigned int id; + size_t blen; + struct scmi_test_buffer *data; + struct scmi_test_setup *tsp = filp->f_inode->i_private; + struct scmi_sensor_data *sdata = tsp->priv; + const char *id_str = filp->f_path.dentry->d_parent->d_name.name; + + /* Grab clk ID from debugfs entry naming if any */ + if (kstrtouint(id_str, 10, &id)) + return -EINVAL; + + if (!sdata->sinfo[id]->num_axis) + blen = SCMI_TEST_DEFAULT_BUF_SZ; + else + blen = 48 * sdata->sinfo[id]->num_axis; + + data = kzalloc(sizeof(*data) + blen, GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->id = id; + data->len = blen; + filp->private_data = data; + + return 0; +} + +static ssize_t scmi_test_sensor_reading_get(struct file *filp, char __user *buf, + size_t count, loff_t *ppos) +{ + struct scmi_test_buffer *data = filp->private_data; + + if (!data) + return 0; + + if (!data->used) { + int ret; + bool tstamp_req; + u64 value; + struct scmi_test_setup *tsp = filp->f_inode->i_private; + const struct scmi_sensor_proto_ops *sensor_ops = tsp->ops; + + tstamp_req = !strncmp(filp->f_path.dentry->d_name.name, + "reading_get_timestamped", + strlen("reading_get_timestamped")); + + if (!tstamp_req) { + ret = sensor_ops->reading_get(tsp->ph, data->id, + &value); + if (ret) + return ret; + + data->used = scnprintf(data->buf, data->len, "%llu\n", + value); + } else { + u8 count; + int i; + struct scmi_sensor_reading *readings; + const struct scmi_sensor_info *sinfo; + struct scmi_sensor_data *sdata = tsp->priv; + + sinfo = sdata->sinfo[data->id]; + if (!sinfo) + return -EINVAL; + + count = sinfo->num_axis ?: 1; + readings = kcalloc(count, sizeof(*readings), + GFP_KERNEL); + if (!readings) + return -ENOMEM; + + ret = sensor_ops->reading_get_timestamped(tsp->ph, + data->id, + count, + readings); + if (ret) { + kfree(readings); + return ret; + } + + for (i = 0; i < count; i++) + data->used += scnprintf(data->buf + data->used, + data->len - data->used, + "%llu:%lld ", + readings[i].timestamp, + readings[i].value); + + data->used += scnprintf(data->buf + data->used, + data->len - data->used, "\n"); + + kfree(readings); + } + } + + return simple_read_from_buffer(buf, count, ppos, data->buf, data->used); +} + +static const struct file_operations test_sensor_reading_get_fops_ro = { + .open = scmi_test_sensor_reading_open, + .release = scmi_test_release, + .read = scmi_test_sensor_reading_get, +}; + +static ssize_t scmi_test_sensor_enable_read(struct file *filp, char __user *buf, + size_t count, loff_t *ppos) +{ + int ret; + struct scmi_test_buffer *data = filp->private_data; + + if (!data) + return 0; + + if (!data->used) { + u32 sensor_config; + struct scmi_test_setup *tsp = filp->f_inode->i_private; + const struct scmi_sensor_proto_ops *sensor_ops = tsp->ops; + + ret = sensor_ops->config_get(tsp->ph, data->id, &sensor_config); + if (ret) + return ret; + + data->used = scnprintf(data->buf, data->len, "%lu\n", + SCMI_SENS_CFG_IS_ENABLED(sensor_config)); + } + + return simple_read_from_buffer(buf, count, ppos, data->buf, data->used); +} + +static ssize_t scmi_test_sensor_enable_write(struct file *filp, + const char __user *buf, + size_t count, loff_t *ppos) +{ + bool enabled; + int ret; + u32 sensor_config; + struct scmi_test_setup *tsp = filp->f_inode->i_private; + const struct scmi_sensor_proto_ops *sensor_ops = tsp->ops; + struct scmi_test_buffer *data = filp->private_data; + + if (!data) + return 0; + + ret = kstrtobool_from_user(buf, count, &enabled); + if (ret) + return ret; + + ret = sensor_ops->config_get(tsp->ph, data->id, &sensor_config); + if (ret) + return ret; + + sensor_config &= ~SCMI_SENS_CFG_SENSOR_ENABLED_MASK; + sensor_config |= FIELD_PREP(SCMI_SENS_CFG_SENSOR_ENABLED_MASK, enabled); + + ret = sensor_ops->config_set(tsp->ph, data->id, sensor_config); + if (ret) + return ret; + + return count; +} + +static const struct file_operations test_sensor_enable_fops_rw = { + .open = scmi_test_setup_open, + .release = scmi_test_release, + .read = scmi_test_sensor_enable_read, + .write = scmi_test_sensor_enable_write, +}; + +static ssize_t scmi_test_sensor_config_read(struct file *filp, char __user *buf, + size_t count, loff_t *ppos) +{ + int ret; + struct scmi_test_buffer *data = filp->private_data; + + if (!data) + return 0; + + if (!data->used) { + u32 sensor_config; + struct scmi_test_setup *tsp = filp->f_inode->i_private; + const struct scmi_sensor_proto_ops *sensor_ops = tsp->ops; + + ret = sensor_ops->config_get(tsp->ph, data->id, &sensor_config); + if (ret) + return ret; + + data->used = scnprintf(data->buf, data->len, "0x%X\n", + sensor_config); + } + + return simple_read_from_buffer(buf, count, ppos, data->buf, data->used); +} + +static ssize_t scmi_test_sensor_config_write(struct file *filp, + const char __user *buf, + size_t count, loff_t *ppos) +{ + int ret; + u32 sensor_config; + struct scmi_test_setup *tsp = filp->f_inode->i_private; + const struct scmi_sensor_proto_ops *sensor_ops = tsp->ops; + struct scmi_test_buffer *data = filp->private_data; + + if (!data) + return 0; + + ret = kstrtou32_from_user(buf, count, 16, &sensor_config); + if (ret) + return ret; + + ret = sensor_ops->config_set(tsp->ph, data->id, sensor_config); + if (ret) + return ret; + + return count; +} + +static const struct file_operations test_sensor_config_fops_rw = { + .open = scmi_test_setup_open, + .release = scmi_test_release, + .read = scmi_test_sensor_config_read, + .write = scmi_test_sensor_config_write, +}; + +static ssize_t scmi_test_sensor_trip_config_write(struct file *filp, + const char __user *buf, + size_t count, loff_t *ppos) +{ + int ret; + unsigned int sid; + u64 trip_config; + struct scmi_test_setup *tsp = filp->f_inode->i_private; + const struct scmi_sensor_proto_ops *sensor_ops = tsp->ops; + struct scmi_test_buffer *data = filp->private_data; + /* protocol_0x15/008/trips/001/set */ + const char *sid_str = + filp->f_path.dentry->d_parent->d_parent->d_parent->d_name.name; + + if (!data || kstrtouint(sid_str, 10, &sid)) + return 0; + + /* Cannot clear !!! Not supported by .trip_point_config */ + ret = kstrtou64_from_user(buf, count, 10, &trip_config); + if (ret) + return ret; + + ret = sensor_ops->trip_point_config(tsp->ph, sid, + data->id, trip_config); + if (ret) + return ret; + + return count; +} + +static const struct file_operations test_sensor_trip_config_fops = { + .open = scmi_test_setup_open, + .release = scmi_test_release, + .write = scmi_test_sensor_trip_config_write, +}; + +static void scmi_test_sensor_trips_debugfs(struct dentry *pdentry, + struct scmi_test_setup *tsp, + unsigned int num_points) +{ + struct dentry *trips_dentry; + + trips_dentry = debugfs_create_dir("trips", pdentry); + + if (!IS_ERR(trips_dentry)) { + int i; + + for (i = 0; i < num_points; i++) { + char point_dir[16]; + struct dentry *point_dentry; + + snprintf(point_dir, 16, "%03d", i); + point_dentry = + debugfs_create_dir(point_dir, trips_dentry); + if (!IS_ERR(point_dentry)) + debugfs_create_file("set", 0200, + point_dentry, tsp, + &test_sensor_trip_config_fops); + } + } +} + +static int scmi_test_sensor_intervals_open(struct inode *ino, struct file *filp) +{ + size_t ilen; + struct scmi_test_buffer *data; + struct scmi_sensor_intervals_info *i = filp->f_inode->i_private; + + /* 65536^-16\n */ + ilen = i->count * 16; + data = kzalloc(sizeof(*data) + ilen, GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->len = ilen; + filp->private_data = data; + + return 0; +} + +static ssize_t scmi_test_sensor_intervals_read(struct file *filp, + char __user *buf, + size_t count, loff_t *ppos) +{ + struct scmi_test_buffer *data = filp->private_data; + + if (!data) + return 0; + + if (!data->used) { + int c; + struct scmi_sensor_intervals_info *i = filp->f_inode->i_private; + + for (c = 0; c < i->count; c++) + data->used += scnprintf(data->buf + data->used, + data->len - data->used, + "%lu^%d ", + SCMI_SENS_INTVL_GET_SECS(i->desc[c]), + SCMI_SENS_INTVL_GET_EXP(i->desc[c])); + + data->used += scnprintf(data->buf + data->used, + data->len - data->used, "\n"); + } + + return simple_read_from_buffer(buf, count, ppos, data->buf, data->used); +} + +static const struct file_operations test_sensor_intervals_fops = { + .open = scmi_test_sensor_intervals_open, + .release = scmi_test_release, + .read = scmi_test_sensor_intervals_read, +}; + +static void +scmi_test_debugfs_sensor_info_create(const struct scmi_sensor_info *si, + struct dentry *top_dentry) +{ + struct dentry *parent; + struct scmi_sensor_info *sinfo = (struct scmi_sensor_info *)si; + + parent = debugfs_create_dir("info", top_dentry); + if (IS_ERR(parent)) + return; + + debugfs_create_u32("type", 0400, parent, &sinfo->type); + debugfs_create_s32("scale", 0400, parent, &sinfo->scale); + debugfs_create_u32("num_trip_points", 0400, parent, + &sinfo->num_trip_points); + debugfs_create_bool("async", 0400, parent, &sinfo->async); + debugfs_create_bool("continuos_updates", 0400, parent, + &sinfo->update); + debugfs_create_bool("timestamped", 0400, parent, + &sinfo->timestamped); + debugfs_create_s32("tstamp_scale", 0400, parent, + &sinfo->tstamp_scale); + + debugfs_create_u32("num_axis", 0400, parent, &sinfo->num_axis); + if (sinfo->num_axis) { + int i; + struct dentry *axes; + + axes = debugfs_create_dir("axes", parent); + if (IS_ERR(axes)) + return; + + for (i = 0; i < sinfo->num_axis; i++) { + char axis_dir[16]; + struct dentry *axis; + + snprintf(axis_dir, 16, "%03d", i); + axis = debugfs_create_dir(axis_dir, axes); + if (IS_ERR(axis)) + return; + + debugfs_create_u32("type", 0400, axis, + &sinfo->axis[i].type); + debugfs_create_s32("scale", 0400, axis, + &sinfo->axis[i].scale); + debugfs_create_file("name", 0400, axis, + sinfo->axis[i].name, + &scmi_test_string_file_fops); + if (sinfo->axis[i].extended_attrs) { + debugfs_create_u32("resolution", 0400, axis, + &sinfo->axis[i].resolution); + debugfs_create_s32("exponent", 0400, axis, + &sinfo->axis[i].exponent); + debugfs_create_s64("min_range", 0400, axis, + &sinfo->axis[i].attrs.min_range); + debugfs_create_s64("max_range", 0400, axis, + &sinfo->axis[i].attrs.max_range); + } + } + } + + if (sinfo->intervals.segmented && sinfo->intervals.count == 3) { + debugfs_create_u32("interval_low", 0400, parent, + &sinfo->intervals.desc[SCMI_SENS_INTVL_SEGMENT_LOW]); + debugfs_create_u32("interval_high", 0400, parent, + &sinfo->intervals.desc[SCMI_SENS_INTVL_SEGMENT_HIGH]); + debugfs_create_u32("interval_step", 0400, parent, + &sinfo->intervals.desc[SCMI_SENS_INTVL_SEGMENT_STEP]); + } else { + debugfs_create_file("intervals", 0400, parent, + &sinfo->intervals, + &test_sensor_intervals_fops); + } + + debugfs_create_u32("sensor_config", 0400, parent, + &sinfo->sensor_config); + + debugfs_create_file("name", 0400, parent, sinfo->name, + &scmi_test_string_file_fops); + + if (sinfo->extended_scalar_attrs) { + debugfs_create_u32("sensor_power", 0400, parent, + &sinfo->sensor_power); + debugfs_create_u32("resolution", 0400, parent, + &sinfo->resolution); + debugfs_create_s32("exponent", 0400, parent, + &sinfo->exponent); + debugfs_create_s64("min_range", 0400, parent, + &sinfo->scalar_attrs.min_range); + debugfs_create_s64("max_range", 0400, parent, + &sinfo->scalar_attrs.max_range); + } +} + +int scmi_test_sensor_init(struct scmi_test_setup *tsp) +{ + int i; + struct scmi_sensor_data *sdata; + const struct scmi_sensor_proto_ops *sensor_ops; + struct device *dev = &tsp->sdev->dev; + + sdata = devm_kzalloc(dev, sizeof(*sdata), GFP_KERNEL); + if (!sdata) + return -ENOMEM; + + sensor_ops = tsp->ops; + sdata->version = sensor_ops->version_get(tsp->ph); + sdata->count = sensor_ops->count_get(tsp->ph); + + if (sdata->count <= 0) { + dev_err(dev, "number of domains invalid: %d\n", + sdata->count); + return sdata->count ?: -EINVAL; + } + + sdata->sinfo = devm_kcalloc(dev, sdata->count, + sizeof(sdata->sinfo), GFP_KERNEL); + if (!sdata->sinfo) + return -ENOMEM; + + for (i = 0; i < sdata->count; i++) + sdata->sinfo[i] = sensor_ops->info_get(tsp->ph, i); + + tsp->priv = sdata; + debugfs_create_x32("version", 0400, tsp->parent, &sdata->version); + + dev_info(dev, "Found %d sensor resources.\n", sdata->count); + + for (i = 0; i < sdata->count; i++) { + char sensor_dir[16]; + struct dentry *sensor_dentry; + + if (!sdata->sinfo[i]) + continue; + + snprintf(sensor_dir, 16, "%03d", i); + sensor_dentry = debugfs_create_dir(sensor_dir, tsp->parent); + if (!IS_ERR(sensor_dentry)) { + scmi_test_debugfs_sensor_info_create(sdata->sinfo[i], + sensor_dentry); + debugfs_create_file("reading_get", 0400, + sensor_dentry, tsp, + &test_sensor_reading_get_fops_ro); + debugfs_create_file("reading_get_timestamped", 0400, + sensor_dentry, tsp, + &test_sensor_reading_get_fops_ro); + debugfs_create_file("enable", 0600, + sensor_dentry, tsp, + &test_sensor_enable_fops_rw); + debugfs_create_file("sensor_config", 0600, + sensor_dentry, tsp, + &test_sensor_config_fops_rw); + + if (sdata->sinfo[i]->num_trip_points) + scmi_test_sensor_trips_debugfs(sensor_dentry, + tsp, + sdata->sinfo[i]->num_trip_points); + } + } + + return 0; +} From patchwork Sun Feb 27 20:56:03 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 12762144 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 F3596C433EF for ; Sun, 27 Feb 2022 21:01:21 +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:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id: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=TJ1edFVHNryuI43cSR4Ojgi4wYDcgy2uVbLrAvgBoJM=; b=Q/8GCem9Mjieqp JhVJclNbxfCgz7hr6eubfKj6zC/Fu+WA1Yt28xdbHv/3V+CH3COI450JOZTJl92lGL7O+RdoadqXI XpLcJhOmzV8BrG9i/YUM80A5xN4a7hMLm8UUSl9/CeTN5TTbfHwGJPy51FC1TbwN49Dtsq0nc3iRz tWkRb8Fe8zGmXy/aJB4WQexAhRTdBoG4QQsDsjV/cEbOfTnv+7ApuWSJDtMLkZWyGRXVFP2bfFDmB HEPhdKe07Ki4hFZ1y9SpxMlGC17mvLlmNnxx9YQmNjhD8qYuyRvbGB7PbzgngR0R2FjLO4AEOZGni WhLNUUg60i263JKQfl+w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQe3-00A8yA-9P; Sun, 27 Feb 2022 20:59:55 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQau-00A7FL-RI for linux-arm-kernel@lists.infradead.org; Sun, 27 Feb 2022 20:56:43 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 2601B106F; Sun, 27 Feb 2022 12:56:40 -0800 (PST) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id BD08D3F66F; Sun, 27 Feb 2022 12:56:38 -0800 (PST) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, peter.hilber@opensynergy.com, cristian.marussi@arm.com Subject: [RFC PATCH 11/16] firmware: arm_scmi: Add test driver generic notification helpers Date: Sun, 27 Feb 2022 20:56:03 +0000 Message-Id: <20220227205608.30812-12-cristian.marussi@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220227205608.30812-1-cristian.marussi@arm.com> References: <20220227205608.30812-1-cristian.marussi@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220227_125641_010666_069E7162 X-CRM114-Status: GOOD ( 16.56 ) 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add a few generic helpers to allow the test driver to register a common notifier block and related read routines in order to test notifications when supported by the specific SCMI protocol. Signed-off-by: Cristian Marussi --- .../arm_scmi/scmi_test_driver/test_common.c | 177 ++++++++++++++++++ .../arm_scmi/scmi_test_driver/test_common.h | 28 +++ 2 files changed, 205 insertions(+) diff --git a/drivers/firmware/arm_scmi/scmi_test_driver/test_common.c b/drivers/firmware/arm_scmi/scmi_test_driver/test_common.c index cbe2eec4f2ac..c44fe702196e 100644 --- a/drivers/firmware/arm_scmi/scmi_test_driver/test_common.c +++ b/drivers/firmware/arm_scmi/scmi_test_driver/test_common.c @@ -14,6 +14,22 @@ #include "test_common.h" +struct scmi_test_setup * +scmi_test_tsp_shallow_copy(struct device *dev, + struct scmi_test_setup *tsp) +{ + struct scmi_test_setup *tsp_copy; + + tsp_copy = devm_kzalloc(dev, sizeof(*tsp_copy), GFP_KERNEL); + if (!tsp_copy) + return ERR_PTR(-ENOMEM); + + memcpy(tsp_copy, tsp, sizeof(*tsp_copy)); + tsp_copy->n_priv = NULL; + + return tsp_copy; +} + /* Common File operations */ /** @@ -70,6 +86,167 @@ int scmi_test_release(struct inode *ino, struct file *filp) return 0; } +int scmi_test_generic_notif_cb(struct notifier_block *nb, unsigned long event, + void *data) +{ + struct scmi_test_notif_reports *nrep; + void *d_report; + + nrep = container_of(nb, struct scmi_test_notif_reports, notif_nb); + + mutex_lock(&nrep->mtx); + d_report = ((u8 *)nrep->reports) + + ((nrep->count % nrep->max_reports) * nrep->report_sz); + memcpy(d_report, data, nrep->report_sz); + nrep->count++; + mutex_unlock(&nrep->mtx); + + return NOTIFY_OK; +} + +static struct scmi_test_notif_reports * +scmi_test_notif_reports_alloc(struct scmi_device *sdev, + size_t report_sz, unsigned int max_reports, + u8 proto_id, u8 evt_id, const u32 *src_id, + notifier_fn_t notif_cb) +{ + int ret; + struct scmi_test_notif_reports *nrep; + struct device *dev = &sdev->dev; + const struct scmi_notify_ops *n_ops = sdev->handle->notify_ops; + + nrep = devm_kzalloc(dev, sizeof(*nrep), GFP_KERNEL); + if (!nrep) + return ERR_PTR(-ENOMEM); + + nrep->reports = devm_kcalloc(dev, max_reports, report_sz, GFP_KERNEL); + if (!nrep->reports) { + devm_kfree(dev, nrep); + return ERR_PTR(-ENOMEM); + } + + nrep->proto_id = proto_id; + nrep->evt_id = evt_id; + if (src_id) + nrep->src_id = *src_id; + else + nrep->src_id = 0xffffffff; + nrep->report_sz = report_sz; + nrep->max_reports = max_reports; + mutex_init(&nrep->mtx); + + if (notif_cb) + nrep->notif_nb.notifier_call = notif_cb; + else + nrep->notif_nb.notifier_call = scmi_test_generic_notif_cb; + + ret = n_ops->devm_event_notifier_register(sdev, + proto_id, evt_id, src_id, + &nrep->notif_nb); + if (ret) { + devm_kfree(dev, nrep->reports); + devm_kfree(dev, nrep); + return ERR_PTR(ret); + } + + return nrep; +} + +static int scmi_test_notif_reports_free(struct scmi_device *sdev, + struct scmi_test_notif_reports *nrep) +{ + int ret; + struct device *dev = &sdev->dev; + const struct scmi_notify_ops *n_ops = sdev->handle->notify_ops; + + if (!nrep) + return -EINVAL; + + ret = n_ops->devm_event_notifier_unregister(sdev, &nrep->notif_nb); + if (ret) + return ret; + + devm_kfree(dev, nrep->reports); + devm_kfree(dev, nrep); + + return 0; +} + +int scmi_test_notif_manage(struct scmi_test_setup *tsp, bool enabled, + u8 proto_id, u8 evt_id, const u32 *src_id, + size_t rep_sz, notifier_fn_t notif_cb) +{ + int ret; + + /* For testing allow enable only for one notifier at time */ + if ((enabled && tsp->n_priv) || (!enabled && !tsp->n_priv)) + return -EINVAL; + + if (enabled) { + tsp->n_priv = + scmi_test_notif_reports_alloc(tsp->sdev, rep_sz, + SCMI_TEST_MAX_REPORTS, + proto_id, evt_id, + src_id, notif_cb); + if (IS_ERR(tsp->n_priv)) { + ret = PTR_ERR(tsp->n_priv); + tsp->n_priv = NULL; + return ret; + } + } else { + ret = scmi_test_notif_reports_free(tsp->sdev, tsp->n_priv); + if (ret) + return ret; + + tsp->n_priv = NULL; + } + + return 0; +} + +ssize_t scmi_test_notif_reports_read(struct file *filp, char __user *buf, + size_t count, loff_t *ppos) +{ + struct scmi_test_buffer *data = filp->private_data; + struct scmi_test_setup *tsp = filp->f_inode->i_private; + struct scmi_test_notif_reports *nrep = tsp->n_priv; + + if (!data || !nrep) + return 0; + + if (!data->used) { + int i, cnt; + + mutex_lock(&nrep->mtx); + cnt = nrep->count >= nrep->max_reports ? + nrep->max_reports : nrep->count; + for (i = 0; i < cnt; i++) { + u8 *rep; + int j; + + data->used += scnprintf(data->buf + data->used, + data->len - data->used, + "[%02u/%02u|%u] - |%02X|%u|%u| = Report: ", + i, + nrep->max_reports, nrep->count, + nrep->proto_id, nrep->evt_id, + nrep->src_id); + + rep = ((u8 *)nrep->reports) + i * nrep->report_sz; + for (j = 0; j < nrep->report_sz; j++) + data->used += scnprintf(data->buf + data->used, + data->len - data->used, + "%02X ", rep[j]); + + data->used += scnprintf(data->buf + data->used, + data->len - data->used, "\n"); + } + mutex_unlock(&nrep->mtx); + } + + return simple_read_from_buffer(buf, count, ppos, data->buf, data->used); +} + int scmi_test_fixed_buffer_open(struct inode *ino, struct file *filp) { struct scmi_test_buffer *data; diff --git a/drivers/firmware/arm_scmi/scmi_test_driver/test_common.h b/drivers/firmware/arm_scmi/scmi_test_driver/test_common.h index e02c2521f090..93c05db0ebff 100644 --- a/drivers/firmware/arm_scmi/scmi_test_driver/test_common.h +++ b/drivers/firmware/arm_scmi/scmi_test_driver/test_common.h @@ -66,8 +66,36 @@ struct scmi_test_buffer { unsigned char buf[]; }; +#define SCMI_TEST_MAX_REPORTS 20 +struct scmi_test_notif_reports { + u8 proto_id; + u8 evt_id; + u32 src_id; + unsigned int max_reports; + size_t report_sz; + void *reports; + unsigned int count; + struct notifier_block notif_nb; + /* Protect access to notification reports */ + struct mutex mtx; +}; + extern const struct file_operations scmi_test_string_file_fops; +int scmi_test_generic_notif_cb(struct notifier_block *nb, unsigned long event, + void *data); + +int scmi_test_notif_manage(struct scmi_test_setup *tsp, bool enabled, + u8 proto_id, u8 evt_id, const u32 *src_id, + size_t rep_sz, notifier_fn_t notif_cb); + +ssize_t scmi_test_notif_reports_read(struct file *filp, char __user *buf, + size_t count, loff_t *ppos); + +struct scmi_test_setup * +scmi_test_tsp_shallow_copy(struct device *dev, + struct scmi_test_setup *tsp); + int scmi_test_setup_open(struct inode *ino, struct file *filp); int scmi_test_fixed_buffer_open(struct inode *ino, struct file *filp); int scmi_test_release(struct inode *ino, struct file *filp); From patchwork Sun Feb 27 20:56:04 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 12762145 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 7956FC433F5 for ; Sun, 27 Feb 2022 21:01:49 +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:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id: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=yP0J9tHFaGuTeRY9Fwz2EE5UQk4eDQJ9RjEsee86RrQ=; b=4+cV5LT6ELa3VR KRFRcbwEsSCSEKrwqbWT4v45yww6TbcH+NZqrEHv+B/vHZvE3SUu4JWhNODC0e82U/tRqfgcz/nEs MugkXFHo9KL2MSAT1mTWC5+slc15J5uV8bmKjvZpecYTlFvdcUcS+OrCGAenBdbHrilV7JQSBif5E Joo2f22drQSb7pRvu4aMxabLzuBc75+cPEn+ELm/iV7pwxz6CZDi/9GhrC+0ISBNWoQZFeQfz1Ywh Ow1MgSDIzBrihOFCb6mFn7H1iyrWtSXvN0CwpyejSBsZrs4I2tasR0Fxx650BYfaWW75HPMgt4MUg z6PxOmCs4Jkl6toD/Deg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQeO-00A9Al-Eg; Sun, 27 Feb 2022 21:00:16 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQaw-00A7IU-N6 for linux-arm-kernel@lists.infradead.org; Sun, 27 Feb 2022 20:56:44 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id B755C1063; Sun, 27 Feb 2022 12:56:41 -0800 (PST) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 5BB753F66F; Sun, 27 Feb 2022 12:56:40 -0800 (PST) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, peter.hilber@opensynergy.com, cristian.marussi@arm.com Subject: [RFC PATCH 12/16] firmware: arm_scmi: Add Sensor notifications testing support Date: Sun, 27 Feb 2022 20:56:04 +0000 Message-Id: <20220227205608.30812-13-cristian.marussi@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220227205608.30812-1-cristian.marussi@arm.com> References: <20220227205608.30812-1-cristian.marussi@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220227_125642_944770_10CAD222 X-CRM114-Status: GOOD ( 16.16 ) 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add a few debugfs entry to enable Sensor notifications support, namely continuos sensor updates notifications and sensor trip point events notifications. Signed-off-by: Cristian Marussi --- Documentation/ABI/testing/debugfs-scmi | 50 +++++++++ .../arm_scmi/scmi_test_driver/test_sensors.c | 104 +++++++++++++++++- 2 files changed, 153 insertions(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/debugfs-scmi b/Documentation/ABI/testing/debugfs-scmi index 72835516dee8..8b3f9a12053d 100644 --- a/Documentation/ABI/testing/debugfs-scmi +++ b/Documentation/ABI/testing/debugfs-scmi @@ -217,3 +217,53 @@ Description: SCMI Sensor Protocol trip points configuration operation for writing a base-10 integer value configure and enable trip point for sensor . Users: KSelftest, Debugging + +What: /sys/kernel/debug/scmi/protocol_0x15//sensor_update_notifs +Date: Feb 2022 +KernelVersion: 5.19 +Contact: cristian.marussi@arm.com +Description: A RW entry to support SENSOR_UPDATE notifications testing. + Writing a true value (Y/y/1) to this entry will trigger the + registration of a common notifier block for the SENSOR_UPDATE + notification as defined in SCMI Sensor Protocol: this common + notifier block starts collecting all the received notification + payload in a circular buffer. + The rate at which such notifications are emitted depends on the + specific update interval currently selected by the resource + at hand using the SENSOR_CONFIG command. + Note that, as per SCMI specification, the related sensor + resource has also to be in an enabled state for the + notifications to be emitted by the platform. + Reading from this entry will return the latest content of the + above mentioned circular buffer. + Writing a false value (N/n/0) to this entry will cause the above + mentioned common notifier block to be unregistered and so + effectively the notification emission to be stopped. + When the notifier is unregistered the notification circular + buffer is cleared empty. + This entry is present only if the related resource has + been advertised as supporting continuos updated notifications. +Users: KSelftest, Debugging + +What: /sys/kernel/debug/scmi/protocol_0x15//sensor_trip_notifs +Date: Feb 2022 +KernelVersion: 5.19 +Contact: cristian.marussi@arm.com +Description: A RW entry to support SENSOR_TRIP_POINT_EVENT notifications + testing. Writing a true value (Y/y/1) to this entry will trigger + the registration of a common notifier block for + SENSOR_TRIP_POINT_EVENT notification as defined in SCMI Sensor + Protocol: this common notifier block starts collecting all the + received notification payload in a circular buffer. + Such notifications will be emitted once the related sensor + resource crosses one of the configured trip point: such trip + point can be cofigured using SENSOR_TRIP_POINT_CONFIG command + and related entries in the SCMI debugfs filesystem. + Reading from this entry will return the latest content of the + above mentioned circular buffer. + Writing a false value (N/n/0) to this entry will cause the above + mentioned common notifier block to be unregistered and so + effectively the notification emission to be stopped. + When the notifier is unregistered the notification circular + buffer is cleared empty. +Users: KSelftest, Debugging diff --git a/drivers/firmware/arm_scmi/scmi_test_driver/test_sensors.c b/drivers/firmware/arm_scmi/scmi_test_driver/test_sensors.c index 23206c2bac98..2d610d84390f 100644 --- a/drivers/firmware/arm_scmi/scmi_test_driver/test_sensors.c +++ b/drivers/firmware/arm_scmi/scmi_test_driver/test_sensors.c @@ -284,6 +284,79 @@ static const struct file_operations test_sensor_trip_config_fops = { .write = scmi_test_sensor_trip_config_write, }; +static ssize_t scmi_test_sensor_updates_write(struct file *filp, + const char __user *buf, + size_t count, loff_t *ppos) +{ + bool enabled; + int ret; + u32 src_id; + struct scmi_test_setup *tsp = filp->f_inode->i_private; + struct scmi_test_buffer *data = filp->private_data; + + if (!tsp || !data) + return count; + + ret = kstrtobool_from_user(buf, count, &enabled); + if (ret) + return ret; + + src_id = data->id; + ret = scmi_test_notif_manage(tsp, enabled, + SCMI_PROTOCOL_SENSOR, + SCMI_EVENT_SENSOR_UPDATE, &src_id, + sizeof(struct scmi_sensor_update_report), + scmi_test_generic_notif_cb); + if (ret < 0) + return ret; + + return count; +} + +static const struct file_operations test_sensor_updates_fops_rw = { + .open = scmi_test_setup_open, + .release = scmi_test_release, + .read = scmi_test_notif_reports_read, + .write = scmi_test_sensor_updates_write, +}; + +static ssize_t scmi_test_sensor_trip_point_write(struct file *filp, + const char __user *buf, + size_t count, loff_t *ppos) +{ + bool enabled; + int ret; + u32 src_id; + struct scmi_test_setup *tsp = filp->f_inode->i_private; + struct scmi_test_buffer *data = filp->private_data; + + if (!tsp || !data) + return count; + + ret = kstrtobool_from_user(buf, count, &enabled); + if (ret) + return ret; + + src_id = data->id; + ret = scmi_test_notif_manage(tsp, enabled, + SCMI_PROTOCOL_SENSOR, + SCMI_EVENT_SENSOR_TRIP_POINT_EVENT, + &src_id, + sizeof(struct scmi_sensor_trip_point_report), + scmi_test_generic_notif_cb); + if (ret < 0) + return ret; + + return count; +} + +static const struct file_operations test_sensor_trips_fops_rw = { + .open = scmi_test_setup_open, + .release = scmi_test_release, + .read = scmi_test_notif_reports_read, + .write = scmi_test_sensor_trip_point_write, +}; + static void scmi_test_sensor_trips_debugfs(struct dentry *pdentry, struct scmi_test_setup *tsp, unsigned int num_points) @@ -514,10 +587,39 @@ int scmi_test_sensor_init(struct scmi_test_setup *tsp) sensor_dentry, tsp, &test_sensor_config_fops_rw); - if (sdata->sinfo[i]->num_trip_points) + if (sdata->sinfo[i]->update) { + struct scmi_test_setup *tsp_copy; + + tsp_copy = scmi_test_tsp_shallow_copy(dev, tsp); + if (IS_ERR(tsp_copy)) + return PTR_ERR(tsp_copy); + + /* Bigger dedicated buffer for notifs */ + tsp_copy->blen = 4096; + debugfs_create_file("sensor_update_notifs", + 0600, sensor_dentry, + tsp_copy, + &test_sensor_updates_fops_rw); + } + + if (sdata->sinfo[i]->num_trip_points) { + struct scmi_test_setup *tsp_copy; + scmi_test_sensor_trips_debugfs(sensor_dentry, tsp, sdata->sinfo[i]->num_trip_points); + + tsp_copy = scmi_test_tsp_shallow_copy(dev, tsp); + if (IS_ERR(tsp_copy)) + return PTR_ERR(tsp_copy); + + /* Bigger dedicated buffer for notifs */ + tsp_copy->blen = 4096; + debugfs_create_file("sensor_trip_notifs", + 0600, sensor_dentry, + tsp_copy, + &test_sensor_trips_fops_rw); + } } } From patchwork Sun Feb 27 20:56:05 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 12762146 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 3A002C433F5 for ; Sun, 27 Feb 2022 21:02:26 +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:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id: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=8VKiqDv7Sopdtq+0d0vATvRUxEDMXW5MwsdOVgP14S0=; b=SmJODpC26OWIbE u2NDxYCSj0D+zSgkAvg4/KMgD3PFvyfBgcZAzIjk7MEF0o1c9meF6F89MBMwSsTykTh7HtugeU8uY +sKzw9yjAszI/GE/CcpWLuhpApg2+qDB9iOzE85osLMFz4mQED8jehWF7xfgdZGeQbJipbklXFjan o69uFuQ6Yh1a4JneHiztl98T2KWlFZdxonYvFZo0f1wNhafUez6RXeVBf+Av+KeDvZAfzKXXaLnnH XPZVp5fHLMq8cYtsK7BP9RhusE1WxfJ0jxup/LG3qNxiq4pBNuDIC15pln1vPKf8C0I94zkI597s3 twh7t+iKAcubO0dC6sgg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQf6-00A9Tw-VI; Sun, 27 Feb 2022 21:01:06 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQax-00A7Gx-J7 for linux-arm-kernel@lists.infradead.org; Sun, 27 Feb 2022 20:56:45 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 56994106F; Sun, 27 Feb 2022 12:56:43 -0800 (PST) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id ECDA33F66F; Sun, 27 Feb 2022 12:56:41 -0800 (PST) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, peter.hilber@opensynergy.com, cristian.marussi@arm.com Subject: [RFC PATCH 13/16] firmware: arm_scmi: Add testing Power protocol support Date: Sun, 27 Feb 2022 20:56:05 +0000 Message-Id: <20220227205608.30812-14-cristian.marussi@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220227205608.30812-1-cristian.marussi@arm.com> References: <20220227205608.30812-1-cristian.marussi@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220227_125643_800510_EDA743C6 X-CRM114-Status: GOOD ( 18.84 ) 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org firmware: arm_scmi: Add testing Power protocol support Signed-off-by: Cristian Marussi --- .../arm_scmi/scmi_test_driver/Makefile | 3 +- .../arm_scmi/scmi_test_driver/scmi_test.c | 2 + .../arm_scmi/scmi_test_driver/test_common.h | 1 + .../arm_scmi/scmi_test_driver/test_powers.c | 105 ++++++++++++++++++ 4 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 drivers/firmware/arm_scmi/scmi_test_driver/test_powers.c diff --git a/drivers/firmware/arm_scmi/scmi_test_driver/Makefile b/drivers/firmware/arm_scmi/scmi_test_driver/Makefile index 458883193f31..68a3d94a6a88 100644 --- a/drivers/firmware/arm_scmi/scmi_test_driver/Makefile +++ b/drivers/firmware/arm_scmi/scmi_test_driver/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only -scmi_test_driver-objs := scmi_test.o test_common.o test_clocks.o test_sensors.o +scmi_test_driver-objs := scmi_test.o test_common.o test_clocks.o test_sensors.o \ + test_powers.o obj-$(CONFIG_ARM_SCMI_TEST_DRIVER) += scmi_test_driver.o diff --git a/drivers/firmware/arm_scmi/scmi_test_driver/scmi_test.c b/drivers/firmware/arm_scmi/scmi_test_driver/scmi_test.c index 04e01dd114c9..df0d3e572010 100644 --- a/drivers/firmware/arm_scmi/scmi_test_driver/scmi_test.c +++ b/drivers/firmware/arm_scmi/scmi_test_driver/scmi_test.c @@ -23,6 +23,7 @@ DEFINE_MUTEX(scmi_test_mtx); static int (*scmi_test_init[SCMI_MAX_PROTOCOLS])(struct scmi_test_setup *) = { + [SCMI_PROTOCOL_POWER] = scmi_test_power_init, [SCMI_PROTOCOL_CLOCK] = scmi_test_clock_init, [SCMI_PROTOCOL_SENSOR] = scmi_test_sensor_init, }; @@ -126,6 +127,7 @@ static int scmi_testing_probe(struct scmi_device *sdev) static const struct scmi_device_id scmi_id_table[] = { { SCMI_PROTOCOL_CLOCK, "__scmi_test-clock" }, { SCMI_PROTOCOL_SENSOR, "__scmi_test-sensor" }, + { SCMI_PROTOCOL_POWER, "__scmi_test-power" }, { }, }; MODULE_DEVICE_TABLE(scmi, scmi_id_table); diff --git a/drivers/firmware/arm_scmi/scmi_test_driver/test_common.h b/drivers/firmware/arm_scmi/scmi_test_driver/test_common.h index 93c05db0ebff..9f3d35ba4477 100644 --- a/drivers/firmware/arm_scmi/scmi_test_driver/test_common.h +++ b/drivers/firmware/arm_scmi/scmi_test_driver/test_common.h @@ -102,5 +102,6 @@ int scmi_test_release(struct inode *ino, struct file *filp); int scmi_test_clock_init(struct scmi_test_setup *tsp); int scmi_test_sensor_init(struct scmi_test_setup *tsp); +int scmi_test_power_init(struct scmi_test_setup *tsp); #endif /* __SCMI_TEST_COMMON_H */ diff --git a/drivers/firmware/arm_scmi/scmi_test_driver/test_powers.c b/drivers/firmware/arm_scmi/scmi_test_driver/test_powers.c new file mode 100644 index 000000000000..5db1662f2dc7 --- /dev/null +++ b/drivers/firmware/arm_scmi/scmi_test_driver/test_powers.c @@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * SCMI Testing Driver - Power Protocol + * + * Copyright (C) 2022 ARM Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test_common.h" + +struct scmi_power_data { + unsigned int version; + int count; +}; + +static ssize_t scmi_test_power_info_read(struct file *filp, char __user *buf, + size_t count, loff_t *ppos) +{ + struct scmi_test_buffer *data = filp->private_data; + + if (!data) + return 0; + + if (!data->used) { + u32 pstate; + char *pname; + struct scmi_test_setup *tsp = filp->f_inode->i_private; + const struct scmi_power_proto_ops *power_ops = tsp->ops; + + pname = power_ops->name_get(tsp->ph, data->id); + power_ops->state_get(tsp->ph, data->id, &pstate); + + data->used = scnprintf(data->buf, data->len, + "%s -> state:%d\n", + pname, pstate); + } + + if (*ppos >= data->used) + return 0; + + if (count > data->used) + count = data->used; + + count -= copy_to_user(buf, data->buf + *ppos, count); + *ppos += count; + + return count; +} + +static const struct file_operations test_power_info_fops = { + .open = scmi_test_setup_open, + .release = scmi_test_release, + .read = scmi_test_power_info_read, +}; + +int scmi_test_power_init(struct scmi_test_setup *tsp) +{ + int i; + struct scmi_power_data *pdata; + const struct scmi_power_proto_ops *power_ops; + struct device *dev = &tsp->sdev->dev; + + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + power_ops = tsp->ops; + pdata->version = power_ops->version_get(tsp->ph); + pdata->count = power_ops->num_domains_get(tsp->ph); + + if (pdata->count <= 0) { + dev_err(dev, "number of domains invalid: %d\n", + pdata->count); + return pdata->count ?: -EINVAL; + } + + tsp->priv = pdata; + debugfs_create_x32("version", 0400, tsp->parent, &pdata->version); + + dev_info(dev, "Found %d power-domain resources.\n", pdata->count); + + for (i = 0; i < pdata->count; i++) { + char power_dir[16]; + struct dentry *power_dentry; + + snprintf(power_dir, 16, "%03d", i); + power_dentry = debugfs_create_dir(power_dir, tsp->parent); + if (!IS_ERR(power_dentry)) { + debugfs_create_file("info", 0400, + power_dentry, tsp, + &test_power_info_fops); + } + } + + return 0; +} From patchwork Sun Feb 27 20:56:06 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 12762147 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 9A88DC433F5 for ; Sun, 27 Feb 2022 21:03:22 +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:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id: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=dm2iBrzdrNPMS88PQrB/svM0TrvFXw4dT68fVxdLxwg=; b=BDphY2p2oyEEGC vWjc5inc9mM8L3rbnpFyXMt1cIBAXOmAY2Q6ak5tGbPQadV5YbZoEyvA4efSGg7Jxkr+cn6FLEgHW Cm/c/mVt+q/5O7ojVELrd+6RTmZNrOzmSb9Y03qujnOoBBw0cJ8LcZ/C+7MvXPtLGYJY1tIbpv1Cd HdHKrI4ezgtuLJohidXp6J1Gp/0rmf7P37AgNe+Pi/BKmtIG3UrTDZqx7ZGZZ7q8NIDjCerXsjndu +j9DRSMUKnROZV8FJmAXsNnAltETL+0h0dIxXsKQbixfywsyy7qM5WMUrCX+6a15RIQOH6Puz6ycC VFlutDpM41OOqZ2/YNGw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQg5-00AA0K-My; Sun, 27 Feb 2022 21:02:03 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQaz-00A7IU-Ct for linux-arm-kernel@lists.infradead.org; Sun, 27 Feb 2022 20:56:47 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id E786C1063; Sun, 27 Feb 2022 12:56:44 -0800 (PST) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 8C7BD3F66F; Sun, 27 Feb 2022 12:56:43 -0800 (PST) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, peter.hilber@opensynergy.com, cristian.marussi@arm.com Subject: [RFC PATCH 14/16] firmware: arm_scmi: Add testing Voltage protocol support Date: Sun, 27 Feb 2022 20:56:06 +0000 Message-Id: <20220227205608.30812-15-cristian.marussi@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220227205608.30812-1-cristian.marussi@arm.com> References: <20220227205608.30812-1-cristian.marussi@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220227_125645_559057_F73A0D99 X-CRM114-Status: GOOD ( 15.89 ) 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org firmware: arm_scmi: Add testing Voltage protocol support Signed-off-by: Cristian Marussi --- .../arm_scmi/scmi_test_driver/Makefile | 2 +- .../arm_scmi/scmi_test_driver/scmi_test.c | 2 + .../arm_scmi/scmi_test_driver/test_common.h | 1 + .../arm_scmi/scmi_test_driver/test_voltages.c | 51 +++++++++++++++++++ 4 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 drivers/firmware/arm_scmi/scmi_test_driver/test_voltages.c diff --git a/drivers/firmware/arm_scmi/scmi_test_driver/Makefile b/drivers/firmware/arm_scmi/scmi_test_driver/Makefile index 68a3d94a6a88..3b7df18de250 100644 --- a/drivers/firmware/arm_scmi/scmi_test_driver/Makefile +++ b/drivers/firmware/arm_scmi/scmi_test_driver/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only scmi_test_driver-objs := scmi_test.o test_common.o test_clocks.o test_sensors.o \ - test_powers.o + test_powers.o test_voltages.o obj-$(CONFIG_ARM_SCMI_TEST_DRIVER) += scmi_test_driver.o diff --git a/drivers/firmware/arm_scmi/scmi_test_driver/scmi_test.c b/drivers/firmware/arm_scmi/scmi_test_driver/scmi_test.c index df0d3e572010..2ca9f82c5bf3 100644 --- a/drivers/firmware/arm_scmi/scmi_test_driver/scmi_test.c +++ b/drivers/firmware/arm_scmi/scmi_test_driver/scmi_test.c @@ -26,6 +26,7 @@ int (*scmi_test_init[SCMI_MAX_PROTOCOLS])(struct scmi_test_setup *) = { [SCMI_PROTOCOL_POWER] = scmi_test_power_init, [SCMI_PROTOCOL_CLOCK] = scmi_test_clock_init, [SCMI_PROTOCOL_SENSOR] = scmi_test_sensor_init, + [SCMI_PROTOCOL_VOLTAGE] = scmi_test_voltage_init, }; static void @@ -125,6 +126,7 @@ static int scmi_testing_probe(struct scmi_device *sdev) } static const struct scmi_device_id scmi_id_table[] = { + { SCMI_PROTOCOL_VOLTAGE, "__scmi_test-voltage" }, { SCMI_PROTOCOL_CLOCK, "__scmi_test-clock" }, { SCMI_PROTOCOL_SENSOR, "__scmi_test-sensor" }, { SCMI_PROTOCOL_POWER, "__scmi_test-power" }, diff --git a/drivers/firmware/arm_scmi/scmi_test_driver/test_common.h b/drivers/firmware/arm_scmi/scmi_test_driver/test_common.h index 9f3d35ba4477..338b65da593f 100644 --- a/drivers/firmware/arm_scmi/scmi_test_driver/test_common.h +++ b/drivers/firmware/arm_scmi/scmi_test_driver/test_common.h @@ -102,6 +102,7 @@ int scmi_test_release(struct inode *ino, struct file *filp); int scmi_test_clock_init(struct scmi_test_setup *tsp); int scmi_test_sensor_init(struct scmi_test_setup *tsp); +int scmi_test_voltage_init(struct scmi_test_setup *tsp); int scmi_test_power_init(struct scmi_test_setup *tsp); #endif /* __SCMI_TEST_COMMON_H */ diff --git a/drivers/firmware/arm_scmi/scmi_test_driver/test_voltages.c b/drivers/firmware/arm_scmi/scmi_test_driver/test_voltages.c new file mode 100644 index 000000000000..ab91080e3a0f --- /dev/null +++ b/drivers/firmware/arm_scmi/scmi_test_driver/test_voltages.c @@ -0,0 +1,51 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * SCMI Testing Driver - Voltage Protocol + * + * Copyright (C) 2022 ARM Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "test_common.h" + +struct scmi_voltage_data { + unsigned int version; + int count; +}; + +int scmi_test_voltage_init(struct scmi_test_setup *tsp) +{ + struct scmi_voltage_data *vdata; + struct device *dev = &tsp->sdev->dev; + const struct scmi_voltage_proto_ops *voltage_ops; + + vdata = devm_kzalloc(dev, sizeof(*vdata), GFP_KERNEL); + if (!vdata) + return -ENOMEM; + + voltage_ops = tsp->ops; + vdata->version = voltage_ops->version_get(tsp->ph); + vdata->count = voltage_ops->num_domains_get(tsp->ph); + + if (vdata->count <= 0) { + dev_err(dev, "number of voltage doms invalid: %d\n", + vdata->count); + return vdata->count ?: -EINVAL; + } + + dev_info(dev, "Found %d voltage resources.\n", vdata->count); + + tsp->priv = vdata; + debugfs_create_x32("version", 0400, tsp->parent, &vdata->version); + + return 0; +} From patchwork Sun Feb 27 20:56:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 12762149 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 34807C433EF for ; Sun, 27 Feb 2022 21:04:02 +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:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id: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=uAPERwX2Z1zHwbSeQMhiADbObqewJqbsmtxEiY8xPQ8=; b=CA4btNZOiNt5ie rA0wVR/R8sH3TuputP55OUchrO+wkFTbheTTA/G77Q80D4KYTYzPNAgKDn3QJAM2aQzOWrEM4p9Jl DybP8+d1KIKiidoBmLKvJMIFpJq4Q+rCYwXIHJTVb3A/aKltB7V6qZtRqYluf5mVuFThgd0jiOjvc bYjqutYv9yqcl/9PTDjlmPPU03HMVbKUw+Y1/DYpEIA/j8o/ZkGaykaDO04a2xgR2a7XUhODuw4gX xJRU8F9NyOJazYpBnBVDDl8hMIE9dLOl4jbN5qoTFhtE2GP/xeeGyhBTriDzVGe8+hQQc3ZZU5DIP ucrP5PrjOd9ScXMyHKQQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQgb-00AAHp-2S; Sun, 27 Feb 2022 21:02:33 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQb0-00A7Gx-Tw for linux-arm-kernel@lists.infradead.org; Sun, 27 Feb 2022 20:56:49 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 85A5711FB; Sun, 27 Feb 2022 12:56:46 -0800 (PST) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 2911D3F66F; Sun, 27 Feb 2022 12:56:45 -0800 (PST) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, peter.hilber@opensynergy.com, cristian.marussi@arm.com Subject: [RFC PATCH 15/16] selftests: arm64: Add initial SCMI testcases Date: Sun, 27 Feb 2022 20:56:07 +0000 Message-Id: <20220227205608.30812-16-cristian.marussi@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220227205608.30812-1-cristian.marussi@arm.com> References: <20220227205608.30812-1-cristian.marussi@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220227_125647_113279_12CADC70 X-CRM114-Status: GOOD ( 17.99 ) 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org A few initial testcases for Clock and Sensot protocol plus all the test infrastructure, including the test runeer. All of this just an experimental demonstrator. Signed-off-by: Cristian Marussi --- tools/testing/selftests/arm64/Makefile | 2 +- tools/testing/selftests/arm64/scmi/Makefile | 6 + tools/testing/selftests/arm64/scmi/config | 1 + .../arm64/scmi/kselftest_scmi_lib.sh | 118 ++++++++++++++++++ .../selftests/arm64/scmi/run_scmi_tests.sh | 69 ++++++++++ .../testcases/protocol_0x14/clock_enable.sh | 33 +++++ .../protocol_0x14/clock_rate_read.sh | 18 +++ .../protocol_0x14/clock_rate_write.sh | 29 +++++ .../testcases/protocol_0x15/sensor_reading.sh | 17 +++ 9 files changed, 292 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/arm64/scmi/Makefile create mode 100644 tools/testing/selftests/arm64/scmi/config create mode 100644 tools/testing/selftests/arm64/scmi/kselftest_scmi_lib.sh create mode 100755 tools/testing/selftests/arm64/scmi/run_scmi_tests.sh create mode 100755 tools/testing/selftests/arm64/scmi/testcases/protocol_0x14/clock_enable.sh create mode 100755 tools/testing/selftests/arm64/scmi/testcases/protocol_0x14/clock_rate_read.sh create mode 100755 tools/testing/selftests/arm64/scmi/testcases/protocol_0x14/clock_rate_write.sh create mode 100755 tools/testing/selftests/arm64/scmi/testcases/protocol_0x15/sensor_reading.sh diff --git a/tools/testing/selftests/arm64/Makefile b/tools/testing/selftests/arm64/Makefile index 1e8d9a8f59df..6648dd8e2173 100644 --- a/tools/testing/selftests/arm64/Makefile +++ b/tools/testing/selftests/arm64/Makefile @@ -4,7 +4,7 @@ ARCH ?= $(shell uname -m 2>/dev/null || echo not) ifneq (,$(filter $(ARCH),aarch64 arm64)) -ARM64_SUBTARGETS ?= tags signal pauth fp mte bti abi +ARM64_SUBTARGETS ?= tags signal pauth fp mte bti abi scmi else ARM64_SUBTARGETS := endif diff --git a/tools/testing/selftests/arm64/scmi/Makefile b/tools/testing/selftests/arm64/scmi/Makefile new file mode 100644 index 000000000000..8786d8d4c332 --- /dev/null +++ b/tools/testing/selftests/arm64/scmi/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0 + +TEST_PROGS := run_scmi_tests.sh +TEST_FILES := kselftest_scmi_lib.sh testcases/* + +include ../../lib.mk diff --git a/tools/testing/selftests/arm64/scmi/config b/tools/testing/selftests/arm64/scmi/config new file mode 100644 index 000000000000..161387084a3f --- /dev/null +++ b/tools/testing/selftests/arm64/scmi/config @@ -0,0 +1 @@ +CONFIG_ARM_SCMI_TEST_DRIVER=y diff --git a/tools/testing/selftests/arm64/scmi/kselftest_scmi_lib.sh b/tools/testing/selftests/arm64/scmi/kselftest_scmi_lib.sh new file mode 100644 index 000000000000..54d27b5f3e1a --- /dev/null +++ b/tools/testing/selftests/arm64/scmi/kselftest_scmi_lib.sh @@ -0,0 +1,118 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +SCMI_TEST_DRV="scmi_test_driver" +TRES=(0 0 0) + +ksft_log() +{ + echo -e "[SCMI]: $1" +} + +ksft_skip() +{ + echo -e "[SKIP]: $1" + exit 4 +} + +ksft_pass() +{ + echo -e "[PASS]: $1" +} + +ksft_fail() +{ + echo -e "[FAIL]: $1" + exit 1 +} + +ksft_results() +{ + if [ $# -gt 0 ]; then + local val + local idx + local ret=$1 + + case "$ret" in + 0) + idx=0 + ;; + 4) + idx=1 + ;; + *) + idx=2 + ;; + esac + val=${TRES[${idx}]} + TRES[$idx]=$((val + 1)) + else + ksft_log "Summary - PASS[${TRES[0]}] SKIP[${TRES[1]}] FAIL[${TRES[2]}]" + [ "x${TRES[2]}" != "x0" ] && exit 1 + [ "x${TRES[1]}" != "x0" -a "x${TRES[0]}" == "x0" ] && exit 4 + exit 0 + fi +} + +ksft_scmi_run_one() +{ + tcase=$1 + + echo "-> Running testcase: $tcase" + + ./$tcase + ret=$? + + ksft_results $ret +} + +ksft_scmi_check_fw_version() +{ + local supported=$1 + local current="${SCMI_VENDOR}:${SCMI_SUB_VENDOR}" + + if [ "x${current}" != "x${supported}" ]; then + ksft_skip "Current FW('$current') is UNSUPPORTED. Should be '$supported'" + fi +} + +ksft_scmi_transport_is_atomic () +{ + [ "x$SCMI_TRANSPORT_IS_ATOMIC" == "xY" ] && return 0 || return 1 +} + +ksft_scmi_protocol_resources_get() +{ + local proto_dir=$1 + local resources="" + + for d in ${proto_dir}/*; do + rd="$(basename $d)" + [[ $rd =~ [0-9] ]] && resources="$resources $rd" + done + + echo "$resources" +} + +ksft_scmi_value_get() +{ + local syspath=$1 + local __retval=$2 + local value + + value=$(cat $syspath) + [ "x$?" != "x0" ] && ksft_fail "Fail to read $syspath" + + eval $__retval="'$value'" +} + +ksft_scmi_value_set() +{ + local syspath=$1 + local value=$2 + + echo $value > $syspath + [ "x$?" != "x0" ] && ksft_fail "Fail to write $syspath - err:$?" +} + + diff --git a/tools/testing/selftests/arm64/scmi/run_scmi_tests.sh b/tools/testing/selftests/arm64/scmi/run_scmi_tests.sh new file mode 100755 index 000000000000..f372744a4579 --- /dev/null +++ b/tools/testing/selftests/arm64/scmi/run_scmi_tests.sh @@ -0,0 +1,69 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +. ./kselftest_scmi_lib.sh + +check_root_privs() +{ + [ x"$(id -u)" != "x0" ] && ksft_skip "You need to be root" +} + +check_scmi_testing_stack() +{ + local debugfs_root=$(findmnt -o TARGET -t debugfs | grep -v TARGET) + export SCMI_DEBUGFS_TOPDIR="$debugfs_root/scmi" + + # Try to load module if not builtin + if [ ! -d $SCMI_DEBUGFS_TOPDIR ]; then + modprobe $SCMI_TEST_DRV || ksft_skip "Failed to load $SCMI_TEST_DRV" + [ ! -d $SCMI_DEBUGFS_TOPDIR ] && ksft_skip "SCMI Test stack not found; is CONFIG_ARM_SCMI_TEST_DRIVER enabled ?" + fi +} + +setup_scmi_test_env() +{ + local scmi_info_dir="${SCMI_DEBUGFS_TOPDIR}/info/" + + export SCMI_VENDOR="$(cat ${scmi_info_dir}/vendor_id)" + export SCMI_SUB_VENDOR="$(cat ${scmi_info_dir}/sub_vendor_id)" + export SCMI_VERS_MAJ="$(cat ${scmi_info_dir}/major_ver)" + export SCMI_VERS_MIN="$(cat ${scmi_info_dir}/minor_ver)" + export SCMI_VERS_IMPL="$(cat ${scmi_info_dir}/impl_ver)" + + ksft_log "Found stack: $SCMI_VENDOR/$SCMI_SUB_VENDOR ${SCMI_VERS_MAJ}.${SCMI_VERS_MAJ} - $SCMI_VERS_IMPL" + + SCMI_TEST_PROTOS="" + for p in ${SCMI_DEBUGFS_TOPDIR}/protocol_*; do + SCMI_TEST_PROTOS="${SCMI_TEST_PROTOS} $(basename $p)" + done + + ksft_log "Found testing protocols: $SCMI_TEST_PROTOS" + + export SCMI_TEST_PROTOS + SCMI_TRANSPORT_IS_ATOMIC="N" + [ -d "${SCMI_DEBUGFS_TOPDIR}/transport" ] && + SCMI_TRANSPORT_IS_ATOMIC=$(cat "${SCMI_DEBUGFS_TOPDIR}/transport/is_atomic") + export SCMI_TRANSPORT_IS_ATOMIC +} + +# Setup +check_root_privs + +check_scmi_testing_stack + +setup_scmi_test_env + +# Main +# Run all available tests for the found protocols +# +for proto_dir in $SCMI_TEST_PROTOS; do + [ ! -d $proto_dir ] && ksft_log "$proto_dir tests NOT supported." && continue + export TST_PROTO_DIR="${SCMI_DEBUGFS_TOPDIR}/${proto_dir}" + TST_PROTO_VERSION=$(cat ${TST_PROTO_DIR}/version) + ksft_log "Running tests for SCMI $proto_dir ver:$TST_PROTO_VERSION" + for tst in $proto_dir/*; do + ksft_scmi_run_one $tst + done +done + +ksft_results diff --git a/tools/testing/selftests/arm64/scmi/testcases/protocol_0x14/clock_enable.sh b/tools/testing/selftests/arm64/scmi/testcases/protocol_0x14/clock_enable.sh new file mode 100755 index 000000000000..4cdf3a097ba7 --- /dev/null +++ b/tools/testing/selftests/arm64/scmi/testcases/protocol_0x14/clock_enable.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +. ./kselftest_scmi_lib.sh + +supported_fw="EMU-SCMI-VM:userland" +ksft_scmi_check_fw_version $supported_fw + +clock_enable_disable() { + rname=$1 + rdir=$2 + clk_op=$3 + + ksft_scmi_value_set $rdir/$clk_op Y + ksft_scmi_value_set $rdir/$clk_op N + ksft_log "Clock $rname: $clk_op - ON/OFF ... OK" +} + +resources=$(ksft_scmi_protocol_resources_get $TST_PROTO_DIR) +ksft_log "Found Clock resources: $resources" + +for res in $resources;do + resd="$TST_PROTO_DIR/$res" + name="$(cat $resd/info/name)" + + clock_enable_disable $name $resd "enable" + if [ ksft_transport_is_atomic ]; then + clock_enable_disable $name $resd "enable_atomic_irqs_off" + clock_enable_disable $name $resd "enable_atomic_irqs_on" + fi +done + +ksft_pass "$0" diff --git a/tools/testing/selftests/arm64/scmi/testcases/protocol_0x14/clock_rate_read.sh b/tools/testing/selftests/arm64/scmi/testcases/protocol_0x14/clock_rate_read.sh new file mode 100755 index 000000000000..88c444fd317d --- /dev/null +++ b/tools/testing/selftests/arm64/scmi/testcases/protocol_0x14/clock_rate_read.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +. ./kselftest_scmi_lib.sh + +resources=$(ksft_scmi_protocol_resources_get $TST_PROTO_DIR) +ksft_log "Found Clock resources: $resources" + +for res in $resources;do + resd="$TST_PROTO_DIR/$res" + name="$(cat $resd/info/name)" + val=0 + + ksft_scmi_value_get $resd/rate_get_set val + ksft_log "$name READ => $val" +done + +ksft_pass "$0" diff --git a/tools/testing/selftests/arm64/scmi/testcases/protocol_0x14/clock_rate_write.sh b/tools/testing/selftests/arm64/scmi/testcases/protocol_0x14/clock_rate_write.sh new file mode 100755 index 000000000000..346084ec3812 --- /dev/null +++ b/tools/testing/selftests/arm64/scmi/testcases/protocol_0x14/clock_rate_write.sh @@ -0,0 +1,29 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 + +. ./kselftest_scmi_lib.sh + +supported_fw="EMU-SCMI-VM:userland" +ksft_scmi_check_fw_version $supported_fw + +resources=$(ksft_scmi_protocol_resources_get $TST_PROTO_DIR) +ksft_log "Found Clock resources: $resources" + +for res in $resources;do + resd="$TST_PROTO_DIR/$res" + name="$(cat $resd/info/name)" + val=0 + oldval=0 + setval=0 + + ksft_scmi_value_get $resd/rate_get_set oldval + setval=$((oldval + 666)) + + ksft_scmi_value_set $resd/rate_get_set $setval + + ksft_scmi_value_get $resd/rate_get_set val + [ "x$val" != "x$setval" ] && ksft_fail "Set:$setval readback:$val" + ksft_log "$name OK -> read:$oldval set:$setval readback:$val" +done + +ksft_pass "$0" diff --git a/tools/testing/selftests/arm64/scmi/testcases/protocol_0x15/sensor_reading.sh b/tools/testing/selftests/arm64/scmi/testcases/protocol_0x15/sensor_reading.sh new file mode 100755 index 000000000000..b0f5f6361379 --- /dev/null +++ b/tools/testing/selftests/arm64/scmi/testcases/protocol_0x15/sensor_reading.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +. ./kselftest_scmi_lib.sh + +resources=$(ksft_scmi_protocol_resources_get $TST_PROTO_DIR) +ksft_log "Found Sensor resources: $resources" + +for res in $resources;do + resd="$TST_PROTO_DIR/$res" + name="$(cat $resd/info/name)" + val=0 + + ksft_scmi_value_get $resd/reading_get val + ksft_log "$name READ => $val" +done + +ksft_pass $0 From patchwork Sun Feb 27 20:56:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 12762150 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 A8097C433EF for ; Sun, 27 Feb 2022 21:04:41 +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:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id: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=HTa4H4R3XkE8R1rMGEGbKtmDwqwCMRwKc28lHHy0GKM=; b=I+/1CGWOJzD/au ZJ55DnlWGeRytlbauAzPuOQ5ypgzCQmgFlLUEO7VzYMT3ajWgCW4nRnZhX0dmDQ88oK9qVDafGVEC keO5WU2eZzU6uLFgkW5cuGH+OWktP2CojxT5DvS7jL6G+ktVBhnP9dxBjtBgdPnZ5Z9D5WKEbKwEu WgCToHppuGoVVLpIrD5yaaEMqoB+8/VcY3VxxsKzCArxoMYgZSzLbmBJm4NoMCqR1VXc56qPt32UV bgLr1/OHDmXW/hROveSyg7amlmNXAHZYih9Pqb64IKmNGRWt8+vJoD2e8U+Loe6oUlzF/u5s3Rvh8 fdZHXq3wkevlKr4sMzZw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQhG-00AAYo-NK; Sun, 27 Feb 2022 21:03:15 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1nOQb2-00A7IU-If for linux-arm-kernel@lists.infradead.org; Sun, 27 Feb 2022 20:56:50 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 226C41063; Sun, 27 Feb 2022 12:56:48 -0800 (PST) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id BB1263F66F; Sun, 27 Feb 2022 12:56:46 -0800 (PST) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, peter.hilber@opensynergy.com, cristian.marussi@arm.com Subject: [RFC PATCH 16/16] [DEBUG]: firmware: arm_scmi: Add Kconfig to allow SCMI Testing driver coexistence Date: Sun, 27 Feb 2022 20:56:08 +0000 Message-Id: <20220227205608.30812-17-cristian.marussi@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20220227205608.30812-1-cristian.marussi@arm.com> References: <20220227205608.30812-1-cristian.marussi@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20220227_125648_697117_224A4B8F X-CRM114-Status: GOOD ( 11.60 ) 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: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org firmware: arm_scmi: Add Kconfig to allow SCMI Testing driver coexistence Signed-off-by: Cristian Marussi --- drivers/firmware/arm_scmi/Kconfig | 6 ++++++ drivers/firmware/arm_scmi/driver.c | 15 ++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig index a3726074c89e..c3fc608d5373 100644 --- a/drivers/firmware/arm_scmi/Kconfig +++ b/drivers/firmware/arm_scmi/Kconfig @@ -160,4 +160,10 @@ config ARM_SCMI_TEST_DRIVER This driver can also be built as a module. If so, the module will be called scmi_test_driver. +config ARM_SCMI_TEST_DRIVER_COEXISTENCE + bool "Allow Coexistence of SCMI standard drivers and test driver" + depends on ARM_SCMI_TEST_DRIVER + help + This enables coexistence for concurrent SCMI drievrs and testing driver. + endmenu diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 8c4706b24368..ff692c458a0b 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -1782,14 +1782,15 @@ static int scmi_protocol_device_request(const struct scmi_device_id *id_table) pr_debug("Requesting SCMI device (%s) for protocol %x\n", id_table->name, id_table->protocol_id); -#if IS_ENABLED(CONFIG_ARM_SCMI_TEST_DRIVER) - /* Reject non-testing SCMI drivers */ - if (strncmp(id_table->name, "__scmi_test", strlen("__scmi_test"))) { - pr_warn("SCMI Test driver loaded. Rejecting '%s'/0x%X\n", - id_table->name, id_table->protocol_id); - return -EINVAL; + if (IS_ENABLED(CONFIG_ARM_SCMI_TEST_DRIVER) && + !IS_ENABLED(CONFIG_ARM_SCMI_TEST_DRIVER_COEXISTENCE)) { + /* Reject non-testing SCMI drivers */ + if (strncmp(id_table->name, "__scmi_test", strlen("__scmi_test"))) { + pr_warn("SCMI Test driver loaded. Rejecting driver: '%s'/0x%X\n", + id_table->name, id_table->protocol_id); + return -EBUSY; + } } -#endif /* * Search for the matching protocol rdev list and then search