From nobody Sun Feb 8 23:42:03 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 130B319F499; Tue, 30 Jul 2024 13:33:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722346426; cv=none; b=bmhuQxCQxy8oXhk+m1T9/EcFMo5+El+8Eo75/xtb9zUuCkhtOqnyd49mlW+YlQ2bv69izyx6Hcp7Af+kdvpqgENu3/H2W8uK+kHDhkhz+emJ30yTccEfOnC+vNjCikEOm+/9NLwi7e2vTjxZsfv1/11UjUj48+7vdyIkntg50Gs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722346426; c=relaxed/simple; bh=B4Mt04DHLpCnBffsmbdlRl31oSaexKqLft6+Vvaqa1w=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=RlT1wCJtH/EvsRson1BbTOP202LOTPea17/t5rD4XH5tDaT7Giwe0r88o+2gseEISVouPCj6ftxK4mRTrzR3N/73SktmGF9Yb46N4SFRS9SgtlkRz+YCh02MX7fCNim7+xAmocD4Qnoyuh37GcK2rBaHv+mcKWP558abuIXaIQk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com 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 49EE4106F; Tue, 30 Jul 2024 06:34:10 -0700 (PDT) Received: from pluto.guestnet.cambridge.arm.com (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id F39733F5A1; Tue, 30 Jul 2024 06:33:41 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, arm-scmi@vger.kernel.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, etienne.carriere@st.com, peng.fan@oss.nxp.com, michal.simek@amd.com, quic_sibis@quicinc.com, quic_nkela@quicinc.com, ptosi@google.com, dan.carpenter@linaro.org, souvik.chakravarty@arm.com, Cristian Marussi Subject: [PATCH v3 1/9] firmware: arm_scmi: Fix double free in OPTEE transport Date: Tue, 30 Jul 2024 14:33:10 +0100 Message-ID: <20240730133318.1573765-2-cristian.marussi@arm.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240730133318.1573765-1-cristian.marussi@arm.com> References: <20240730133318.1573765-1-cristian.marussi@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Channels can be shared between protocols, avoid freeing the same channel descriptors twice when unloading the stack. Fixes: 5f90f189a052 ("firmware: arm_scmi: Add optee transport") Signed-off-by: Cristian Marussi Tested-by: Florian Fainelli --- drivers/firmware/arm_scmi/optee.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/firmware/arm_scmi/optee.c b/drivers/firmware/arm_scmi/= optee.c index 4e7944b91e38..0c8908d3b1d6 100644 --- a/drivers/firmware/arm_scmi/optee.c +++ b/drivers/firmware/arm_scmi/optee.c @@ -473,6 +473,13 @@ static int scmi_optee_chan_free(int id, void *p, void = *data) struct scmi_chan_info *cinfo =3D p; struct scmi_optee_channel *channel =3D cinfo->transport_info; =20 + /* + * Different protocols might share the same chan info, so a previous + * call might have already freed the structure. + */ + if (!channel) + return 0; + mutex_lock(&scmi_optee_private->mu); list_del(&channel->link); mutex_unlock(&scmi_optee_private->mu); --=20 2.45.2 From nobody Sun Feb 8 23:42:03 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 6DC9E1A01AD; Tue, 30 Jul 2024 13:33:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722346430; cv=none; b=HSRlNz3iaqXkCPY+WZQo+iFpH6vV2PEqPa/Lhphq9Qjw8IU2JXazwfSvdmWftO4Pf2Cwz3hdGJdAHPOZLp0Yczj4IsM562xZn55Ihp/x/uDrOePsSDjS1zkzF8suwoSESMGyvRJtTQjaPXftB5jpLfbRlVfZt88R+c5M5x0TWxs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722346430; c=relaxed/simple; bh=MXDuRrwNh+QKOAW1PrFj9XJzAD6GTkG6WksYmtyNNWc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=mfFzlqD6jkLfwNCZm66xX7punTh9e1x8KifOYYZfRk1MiWyeuQK1Oz/E+mKrM+DbzAoPDQhuWi3m8QxnJJdrai8S+Tuc39ERR42ZxU4fFjZOME1rv1HuvQQ9IV/j5H/oyDFiHSziLVXL3FGeo5TXPcqKem48KNQY8ybgdc+AkHM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com 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 6EB6F1515; Tue, 30 Jul 2024 06:34:13 -0700 (PDT) Received: from pluto.guestnet.cambridge.arm.com (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id F06BD3F5A1; Tue, 30 Jul 2024 06:33:44 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, arm-scmi@vger.kernel.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, etienne.carriere@st.com, peng.fan@oss.nxp.com, michal.simek@amd.com, quic_sibis@quicinc.com, quic_nkela@quicinc.com, ptosi@google.com, dan.carpenter@linaro.org, souvik.chakravarty@arm.com, Peng Fan , Cristian Marussi Subject: [PATCH v3 2/9] firmware: arm_scmi: Introduce setup_shmem_iomap Date: Tue, 30 Jul 2024 14:33:11 +0100 Message-ID: <20240730133318.1573765-3-cristian.marussi@arm.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240730133318.1573765-1-cristian.marussi@arm.com> References: <20240730133318.1573765-1-cristian.marussi@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Peng Fan To get the address of shmem could be generalized by introducing setup_shmem_iomap. Then the duplicated code in mailbox.c, optee.c and smc.c could be dropped. Signed-off-by: Peng Fan [ Cristian: use OF __free and make use of the new helper also in smc.c ] Signed-off-by: Cristian Marussi Tested-by: Florian Fainelli --- v2 --> v3 - use IOMEM_ERR_PTR to avoid sparse errors v1 --> v2 - add optional *res param to setup_shmem_iomap - fixed __iomem tagging - use OF __free cleanup.h magic to of_put() --- drivers/firmware/arm_scmi/common.h | 2 ++ drivers/firmware/arm_scmi/mailbox.c | 27 +++---------------- drivers/firmware/arm_scmi/optee.c | 35 +++--------------------- drivers/firmware/arm_scmi/shmem.c | 41 +++++++++++++++++++++++++++++ drivers/firmware/arm_scmi/smc.c | 27 ++++--------------- 5 files changed, 56 insertions(+), 76 deletions(-) diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi= /common.h index 4b8c5250cdb5..d5e80a24e2d4 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -327,6 +327,8 @@ bool shmem_poll_done(struct scmi_shared_mem __iomem *sh= mem, struct scmi_xfer *xfer); bool shmem_channel_free(struct scmi_shared_mem __iomem *shmem); bool shmem_channel_intr_enabled(struct scmi_shared_mem __iomem *shmem); +void __iomem *setup_shmem_iomap(struct scmi_chan_info *cinfo, struct devic= e *dev, + bool tx, struct resource *res); =20 /* declarations for message passing transports */ struct scmi_msg_payld; diff --git a/drivers/firmware/arm_scmi/mailbox.c b/drivers/firmware/arm_scm= i/mailbox.c index 0219a12e3209..886fc4eedb4a 100644 --- a/drivers/firmware/arm_scmi/mailbox.c +++ b/drivers/firmware/arm_scmi/mailbox.c @@ -178,11 +178,8 @@ static int mailbox_chan_setup(struct scmi_chan_info *c= info, struct device *dev, const char *desc =3D tx ? "Tx" : "Rx"; struct device *cdev =3D cinfo->dev; struct scmi_mailbox *smbox; - struct device_node *shmem; - int ret, a2p_rx_chan, p2a_chan, p2a_rx_chan, idx =3D tx ? 0 : 1; + int ret, a2p_rx_chan, p2a_chan, p2a_rx_chan; struct mbox_client *cl; - resource_size_t size; - struct resource res; =20 ret =3D mailbox_chan_validate(cdev, &a2p_rx_chan, &p2a_chan, &p2a_rx_chan= ); if (ret) @@ -195,25 +192,9 @@ static int mailbox_chan_setup(struct scmi_chan_info *c= info, struct device *dev, if (!smbox) return -ENOMEM; =20 - shmem =3D of_parse_phandle(cdev->of_node, "shmem", idx); - if (!of_device_is_compatible(shmem, "arm,scmi-shmem")) { - of_node_put(shmem); - return -ENXIO; - } - - ret =3D of_address_to_resource(shmem, 0, &res); - of_node_put(shmem); - if (ret) { - dev_err(cdev, "failed to get SCMI %s shared memory\n", desc); - return ret; - } - - size =3D resource_size(&res); - smbox->shmem =3D devm_ioremap(dev, res.start, size); - if (!smbox->shmem) { - dev_err(dev, "failed to ioremap SCMI %s shared memory\n", desc); - return -EADDRNOTAVAIL; - } + smbox->shmem =3D setup_shmem_iomap(cinfo, dev, tx, NULL); + if (IS_ERR(smbox->shmem)) + return PTR_ERR(smbox->shmem); =20 cl =3D &smbox->cl; cl->dev =3D cdev; diff --git a/drivers/firmware/arm_scmi/optee.c b/drivers/firmware/arm_scmi/= optee.c index 0c8908d3b1d6..ee9cda1a8211 100644 --- a/drivers/firmware/arm_scmi/optee.c +++ b/drivers/firmware/arm_scmi/optee.c @@ -368,38 +368,11 @@ static int setup_dynamic_shmem(struct device *dev, st= ruct scmi_optee_channel *ch static int setup_static_shmem(struct device *dev, struct scmi_chan_info *c= info, struct scmi_optee_channel *channel) { - struct device_node *np; - resource_size_t size; - struct resource res; - int ret; - - np =3D of_parse_phandle(cinfo->dev->of_node, "shmem", 0); - if (!of_device_is_compatible(np, "arm,scmi-shmem")) { - ret =3D -ENXIO; - goto out; - } - - ret =3D of_address_to_resource(np, 0, &res); - if (ret) { - dev_err(dev, "Failed to get SCMI Tx shared memory\n"); - goto out; - } - - size =3D resource_size(&res); + channel->req.shmem =3D setup_shmem_iomap(cinfo, dev, true, NULL); + if (IS_ERR(channel->req.shmem)) + return PTR_ERR(channel->req.shmem); =20 - channel->req.shmem =3D devm_ioremap(dev, res.start, size); - if (!channel->req.shmem) { - dev_err(dev, "Failed to ioremap SCMI Tx shared memory\n"); - ret =3D -EADDRNOTAVAIL; - goto out; - } - - ret =3D 0; - -out: - of_node_put(np); - - return ret; + return 0; } =20 static int setup_shmem(struct device *dev, struct scmi_chan_info *cinfo, diff --git a/drivers/firmware/arm_scmi/shmem.c b/drivers/firmware/arm_scmi/= shmem.c index b74e5a740f2c..a0d6f68172fc 100644 --- a/drivers/firmware/arm_scmi/shmem.c +++ b/drivers/firmware/arm_scmi/shmem.c @@ -7,6 +7,8 @@ =20 #include #include +#include +#include #include #include =20 @@ -133,3 +135,42 @@ bool shmem_channel_intr_enabled(struct scmi_shared_mem= __iomem *shmem) { return ioread32(&shmem->flags) & SCMI_SHMEM_FLAG_INTR_ENABLED; } + +void __iomem *setup_shmem_iomap(struct scmi_chan_info *cinfo, + struct device *dev, bool tx, + struct resource *res) +{ + struct device_node *shmem __free(device_node); + const char *desc =3D tx ? "Tx" : "Rx"; + int ret, idx =3D tx ? 0 : 1; + struct device *cdev =3D cinfo->dev; + struct resource lres =3D {}; + resource_size_t size; + void __iomem *addr; + + shmem =3D of_parse_phandle(cdev->of_node, "shmem", idx); + if (!shmem) + return IOMEM_ERR_PTR(-ENODEV); + + if (!of_device_is_compatible(shmem, "arm,scmi-shmem")) + return IOMEM_ERR_PTR(-ENXIO); + + /* Use a local on-stack as a working area when not provided */ + if (!res) + res =3D &lres; + + ret =3D of_address_to_resource(shmem, 0, res); + if (ret) { + dev_err(cdev, "failed to get SCMI %s shared memory\n", desc); + return IOMEM_ERR_PTR(ret); + } + + size =3D resource_size(res); + addr =3D devm_ioremap(dev, res->start, size); + if (!addr) { + dev_err(dev, "failed to ioremap SCMI %s shared memory\n", desc); + return IOMEM_ERR_PTR(-EADDRNOTAVAIL); + } + + return addr; +} diff --git a/drivers/firmware/arm_scmi/smc.c b/drivers/firmware/arm_scmi/sm= c.c index 39936e1dd30e..59b6c04b52bc 100644 --- a/drivers/firmware/arm_scmi/smc.c +++ b/drivers/firmware/arm_scmi/smc.c @@ -130,9 +130,7 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo,= struct device *dev, struct device *cdev =3D cinfo->dev; unsigned long cap_id =3D ULONG_MAX; struct scmi_smc *scmi_info; - resource_size_t size; - struct resource res; - struct device_node *np; + struct resource res =3D {}; u32 func_id; int ret; =20 @@ -143,31 +141,16 @@ static int smc_chan_setup(struct scmi_chan_info *cinf= o, struct device *dev, if (!scmi_info) return -ENOMEM; =20 - np =3D of_parse_phandle(cdev->of_node, "shmem", 0); - if (!of_device_is_compatible(np, "arm,scmi-shmem")) { - of_node_put(np); - return -ENXIO; - } - - ret =3D of_address_to_resource(np, 0, &res); - of_node_put(np); - if (ret) { - dev_err(cdev, "failed to get SCMI Tx shared memory\n"); - return ret; - } - - size =3D resource_size(&res); - scmi_info->shmem =3D devm_ioremap(dev, res.start, size); - if (!scmi_info->shmem) { - dev_err(dev, "failed to ioremap SCMI Tx shared memory\n"); - return -EADDRNOTAVAIL; - } + scmi_info->shmem =3D setup_shmem_iomap(cinfo, dev, tx, &res); + if (IS_ERR(scmi_info->shmem)) + return PTR_ERR(scmi_info->shmem); =20 ret =3D of_property_read_u32(dev->of_node, "arm,smc-id", &func_id); if (ret < 0) return ret; =20 if (of_device_is_compatible(dev->of_node, "qcom,scmi-smc")) { + resource_size_t size =3D resource_size(&res); void __iomem *ptr =3D (void __iomem *)scmi_info->shmem + size - 8; /* The capability-id is kept in last 8 bytes of shmem. * +-------+ <-- 0 --=20 2.45.2 From nobody Sun Feb 8 23:42:03 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 68EF61A01D2; Tue, 30 Jul 2024 13:33:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722346434; cv=none; b=VpTQYeN5QLYgD07TJVXcOUk5UPEv44KM9GCKoBPgzc5Xak7QU+wbizbqjIUY5IVOVkWpCytlX1zNNkPoOihouKwHoDKTjyEpWDoBncaPd6j+LcX1L6MRZiHCk0KmsWLRnbbaV537wOhT2OX5I+i5LGYMbYylxLY69Lkq7nb7mt0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722346434; c=relaxed/simple; bh=IWZqeu1ffqoIFc0dPLz8ylOq+XRJYblvZFP0Lr4y9Lk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=oNro0VuNOt7udvjkKqbyA+fv7/UMOVJa23owkKWCEXk+WpMLTcF0Zwy7qTglAQ/dZuCHCZ0LnoAMxoLZluKSHK2e+FxT2UubLJMB8kzzq80sDoId4NSNsNU/dDmU9J9I0ovX9oOviL1PZf71vhmXJlvcayCZrO1mqIrEz+0jito= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com 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 776E7152B; Tue, 30 Jul 2024 06:34:16 -0700 (PDT) Received: from pluto.guestnet.cambridge.arm.com (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 24B083F5A1; Tue, 30 Jul 2024 06:33:48 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, arm-scmi@vger.kernel.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, etienne.carriere@st.com, peng.fan@oss.nxp.com, michal.simek@amd.com, quic_sibis@quicinc.com, quic_nkela@quicinc.com, ptosi@google.com, dan.carpenter@linaro.org, souvik.chakravarty@arm.com, Cristian Marussi Subject: [PATCH v3 3/9] firmware: arm_scmi: Introduce packet handling helpers Date: Tue, 30 Jul 2024 14:33:12 +0100 Message-ID: <20240730133318.1573765-4-cristian.marussi@arm.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240730133318.1573765-1-cristian.marussi@arm.com> References: <20240730133318.1573765-1-cristian.marussi@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Introduce a pair of structures initialized to contain all the existing packet handling helpers, both for transports based on shared memory and messages. No functional change. Signed-off-by: Cristian Marussi Tested-by: Florian Fainelli --- v2 --> v3 - fixed Copyright v1 --> v2 - fixed commit message --- drivers/firmware/arm_scmi/common.h | 78 +++++++++++++++++++++-------- drivers/firmware/arm_scmi/mailbox.c | 20 ++++---- drivers/firmware/arm_scmi/msg.c | 27 ++++++---- drivers/firmware/arm_scmi/optee.c | 14 +++--- drivers/firmware/arm_scmi/shmem.c | 45 +++++++++++------ drivers/firmware/arm_scmi/smc.c | 8 +-- drivers/firmware/arm_scmi/virtio.c | 14 +++--- 7 files changed, 131 insertions(+), 75 deletions(-) diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi= /common.h index d5e80a24e2d4..8e5751aaa600 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -4,7 +4,7 @@ * driver common header file containing some definitions, structures * and function prototypes used in all the different SCMI protocols. * - * Copyright (C) 2018-2022 ARM Ltd. + * Copyright (C) 2018-2024 ARM Ltd. */ #ifndef _SCMI_COMMON_H #define _SCMI_COMMON_H @@ -315,20 +315,39 @@ void scmi_bad_message_trace(struct scmi_chan_info *ci= nfo, u32 msg_hdr, /* shmem related declarations */ struct scmi_shared_mem; =20 -void shmem_tx_prepare(struct scmi_shared_mem __iomem *shmem, - struct scmi_xfer *xfer, struct scmi_chan_info *cinfo); -u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem); -void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem, +/** + * struct scmi_shared_mem_operations - Transport core operations for + * Shared Memory + * + * @tx_prepare: Prepare the @xfer message for transmission on the chosen @= shmem + * @read_header: Read header of the message currently hold in @shmem + * @fetch_response: Copy the message response from @shmem into @xfer + * @fetch_notification: Copy the message notification from @shmem into @xf= er + * @clear_channel: Clear the @shmem channel busy flag + * @poll_done: Check if poll has completed for @xfer on @shmem + * @channel_free: Check if @shmem channel is marked as free + * @channel_intr_enabled: Check is @shmem channel has requested a completi= on irq + * @setup_iomap: Setup IO shared memory for channel @cinfo + */ +struct scmi_shared_mem_operations { + void (*tx_prepare)(struct scmi_shared_mem __iomem *shmem, + struct scmi_xfer *xfer, + struct scmi_chan_info *cinfo); + u32 (*read_header)(struct scmi_shared_mem __iomem *shmem); + + void (*fetch_response)(struct scmi_shared_mem __iomem *shmem, + struct scmi_xfer *xfer); + void (*fetch_notification)(struct scmi_shared_mem __iomem *shmem, + size_t max_len, struct scmi_xfer *xfer); + void (*clear_channel)(struct scmi_shared_mem __iomem *shmem); + bool (*poll_done)(struct scmi_shared_mem __iomem *shmem, struct scmi_xfer *xfer); -void shmem_fetch_notification(struct scmi_shared_mem __iomem *shmem, - size_t max_len, struct scmi_xfer *xfer); -void shmem_clear_channel(struct scmi_shared_mem __iomem *shmem); -bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem, - struct scmi_xfer *xfer); -bool shmem_channel_free(struct scmi_shared_mem __iomem *shmem); -bool shmem_channel_intr_enabled(struct scmi_shared_mem __iomem *shmem); -void __iomem *setup_shmem_iomap(struct scmi_chan_info *cinfo, struct devic= e *dev, - bool tx, struct resource *res); + bool (*channel_free)(struct scmi_shared_mem __iomem *shmem); + bool (*channel_intr_enabled)(struct scmi_shared_mem __iomem *shmem); + void __iomem *(*setup_iomap)(struct scmi_chan_info *cinfo, + struct device *dev, + bool tx, struct resource *res); +}; =20 /* declarations for message passing transports */ struct scmi_msg_payld; @@ -336,14 +355,29 @@ struct scmi_msg_payld; /* Maximum overhead of message w.r.t. struct scmi_desc.max_msg_size */ #define SCMI_MSG_MAX_PROT_OVERHEAD (2 * sizeof(__le32)) =20 -size_t msg_response_size(struct scmi_xfer *xfer); -size_t msg_command_size(struct scmi_xfer *xfer); -void msg_tx_prepare(struct scmi_msg_payld *msg, struct scmi_xfer *xfer); -u32 msg_read_header(struct scmi_msg_payld *msg); -void msg_fetch_response(struct scmi_msg_payld *msg, size_t len, - struct scmi_xfer *xfer); -void msg_fetch_notification(struct scmi_msg_payld *msg, size_t len, - size_t max_len, struct scmi_xfer *xfer); +/** + * struct scmi_message_operations - Transport core operations for Message + * + * @response_size: Get calculated response size for @xfer + * @command_size: Get calculated command size for @xfer + * @tx_prepare: Prepare the @xfer message for transmission on the provided= @msg + * @read_header: Read header of the message currently hold in @msg + * @fetch_response: Copy the message response from @msg into @xfer + * @fetch_notification: Copy the message notification from @msg into @xfer + */ +struct scmi_message_operations { + size_t (*response_size)(struct scmi_xfer *xfer); + size_t (*command_size)(struct scmi_xfer *xfer); + void (*tx_prepare)(struct scmi_msg_payld *msg, struct scmi_xfer *xfer); + u32 (*read_header)(struct scmi_msg_payld *msg); + void (*fetch_response)(struct scmi_msg_payld *msg, size_t len, + struct scmi_xfer *xfer); + void (*fetch_notification)(struct scmi_msg_payld *msg, size_t len, + size_t max_len, struct scmi_xfer *xfer); +}; + +extern const struct scmi_shared_mem_operations scmi_shmem_ops; +extern const struct scmi_message_operations scmi_msg_ops; =20 void scmi_notification_instance_data_set(const struct scmi_handle *handle, void *priv); diff --git a/drivers/firmware/arm_scmi/mailbox.c b/drivers/firmware/arm_scm= i/mailbox.c index 886fc4eedb4a..60698efe8442 100644 --- a/drivers/firmware/arm_scmi/mailbox.c +++ b/drivers/firmware/arm_scmi/mailbox.c @@ -40,7 +40,7 @@ static void tx_prepare(struct mbox_client *cl, void *m) { struct scmi_mailbox *smbox =3D client_to_scmi_mailbox(cl); =20 - shmem_tx_prepare(smbox->shmem, m, smbox->cinfo); + scmi_shmem_ops.tx_prepare(smbox->shmem, m, smbox->cinfo); } =20 static void rx_callback(struct mbox_client *cl, void *m) @@ -56,15 +56,15 @@ static void rx_callback(struct mbox_client *cl, void *m) * a previous timed-out reply which arrived late could be wrongly * associated with the next pending transaction. */ - if (cl->knows_txdone && !shmem_channel_free(smbox->shmem)) { + if (cl->knows_txdone && !scmi_shmem_ops.channel_free(smbox->shmem)) { dev_warn(smbox->cinfo->dev, "Ignoring spurious A2P IRQ !\n"); scmi_bad_message_trace(smbox->cinfo, - shmem_read_header(smbox->shmem), + scmi_shmem_ops.read_header(smbox->shmem), MSG_MBOX_SPURIOUS); return; } =20 - scmi_rx_callback(smbox->cinfo, shmem_read_header(smbox->shmem), NULL); + scmi_rx_callback(smbox->cinfo, scmi_shmem_ops.read_header(smbox->shmem), = NULL); } =20 static bool mailbox_chan_available(struct device_node *of_node, int idx) @@ -192,7 +192,7 @@ static int mailbox_chan_setup(struct scmi_chan_info *ci= nfo, struct device *dev, if (!smbox) return -ENOMEM; =20 - smbox->shmem =3D setup_shmem_iomap(cinfo, dev, tx, NULL); + smbox->shmem =3D scmi_shmem_ops.setup_iomap(cinfo, dev, tx, NULL); if (IS_ERR(smbox->shmem)) return PTR_ERR(smbox->shmem); =20 @@ -293,7 +293,7 @@ static void mailbox_fetch_response(struct scmi_chan_inf= o *cinfo, { struct scmi_mailbox *smbox =3D cinfo->transport_info; =20 - shmem_fetch_response(smbox->shmem, xfer); + scmi_shmem_ops.fetch_response(smbox->shmem, xfer); } =20 static void mailbox_fetch_notification(struct scmi_chan_info *cinfo, @@ -301,7 +301,7 @@ static void mailbox_fetch_notification(struct scmi_chan= _info *cinfo, { struct scmi_mailbox *smbox =3D cinfo->transport_info; =20 - shmem_fetch_notification(smbox->shmem, max_len, xfer); + scmi_shmem_ops.fetch_notification(smbox->shmem, max_len, xfer); } =20 static void mailbox_clear_channel(struct scmi_chan_info *cinfo) @@ -310,9 +310,9 @@ static void mailbox_clear_channel(struct scmi_chan_info= *cinfo) struct mbox_chan *intr_chan; int ret; =20 - shmem_clear_channel(smbox->shmem); + scmi_shmem_ops.clear_channel(smbox->shmem); =20 - if (!shmem_channel_intr_enabled(smbox->shmem)) + if (!scmi_shmem_ops.channel_intr_enabled(smbox->shmem)) return; =20 if (smbox->chan_platform_receiver) @@ -335,7 +335,7 @@ mailbox_poll_done(struct scmi_chan_info *cinfo, struct = scmi_xfer *xfer) { struct scmi_mailbox *smbox =3D cinfo->transport_info; =20 - return shmem_poll_done(smbox->shmem, xfer); + return scmi_shmem_ops.poll_done(smbox->shmem, xfer); } =20 static const struct scmi_transport_ops scmi_mailbox_ops =3D { diff --git a/drivers/firmware/arm_scmi/msg.c b/drivers/firmware/arm_scmi/ms= g.c index d33a704e5814..f5f6c2c55577 100644 --- a/drivers/firmware/arm_scmi/msg.c +++ b/drivers/firmware/arm_scmi/msg.c @@ -4,7 +4,7 @@ * * Derived from shm.c. * - * Copyright (C) 2019-2021 ARM Ltd. + * Copyright (C) 2019-2024 ARM Ltd. * Copyright (C) 2020-2021 OpenSynergy GmbH */ =20 @@ -30,7 +30,7 @@ struct scmi_msg_payld { * * Return: transport SDU size. */ -size_t msg_command_size(struct scmi_xfer *xfer) +static size_t msg_command_size(struct scmi_xfer *xfer) { return sizeof(struct scmi_msg_payld) + xfer->tx.len; } @@ -42,7 +42,7 @@ size_t msg_command_size(struct scmi_xfer *xfer) * * Return: transport SDU size. */ -size_t msg_response_size(struct scmi_xfer *xfer) +static size_t msg_response_size(struct scmi_xfer *xfer) { return sizeof(struct scmi_msg_payld) + sizeof(__le32) + xfer->rx.len; } @@ -53,7 +53,7 @@ size_t msg_response_size(struct scmi_xfer *xfer) * @msg: transport SDU for command * @xfer: message which is being sent */ -void msg_tx_prepare(struct scmi_msg_payld *msg, struct scmi_xfer *xfer) +static void msg_tx_prepare(struct scmi_msg_payld *msg, struct scmi_xfer *x= fer) { msg->msg_header =3D cpu_to_le32(pack_scmi_header(&xfer->hdr)); if (xfer->tx.buf) @@ -67,7 +67,7 @@ void msg_tx_prepare(struct scmi_msg_payld *msg, struct sc= mi_xfer *xfer) * * Return: SCMI header */ -u32 msg_read_header(struct scmi_msg_payld *msg) +static u32 msg_read_header(struct scmi_msg_payld *msg) { return le32_to_cpu(msg->msg_header); } @@ -79,8 +79,8 @@ u32 msg_read_header(struct scmi_msg_payld *msg) * @len: transport SDU size * @xfer: message being responded to */ -void msg_fetch_response(struct scmi_msg_payld *msg, size_t len, - struct scmi_xfer *xfer) +static void msg_fetch_response(struct scmi_msg_payld *msg, + size_t len, struct scmi_xfer *xfer) { size_t prefix_len =3D sizeof(*msg) + sizeof(msg->msg_payload[0]); =20 @@ -100,8 +100,8 @@ void msg_fetch_response(struct scmi_msg_payld *msg, siz= e_t len, * @max_len: maximum SCMI payload size to fetch * @xfer: notification message */ -void msg_fetch_notification(struct scmi_msg_payld *msg, size_t len, - size_t max_len, struct scmi_xfer *xfer) +static void msg_fetch_notification(struct scmi_msg_payld *msg, size_t len, + size_t max_len, struct scmi_xfer *xfer) { xfer->rx.len =3D min_t(size_t, max_len, len >=3D sizeof(*msg) ? len - sizeof(*msg) : 0); @@ -109,3 +109,12 @@ void msg_fetch_notification(struct scmi_msg_payld *msg= , size_t len, /* Take a copy to the rx buffer.. */ memcpy(xfer->rx.buf, msg->msg_payload, xfer->rx.len); } + +const struct scmi_message_operations scmi_msg_ops =3D { + .tx_prepare =3D msg_tx_prepare, + .command_size =3D msg_command_size, + .response_size =3D msg_response_size, + .read_header =3D msg_read_header, + .fetch_response =3D msg_fetch_response, + .fetch_notification =3D msg_fetch_notification, +}; diff --git a/drivers/firmware/arm_scmi/optee.c b/drivers/firmware/arm_scmi/= optee.c index ee9cda1a8211..dae68adf6f9e 100644 --- a/drivers/firmware/arm_scmi/optee.c +++ b/drivers/firmware/arm_scmi/optee.c @@ -343,7 +343,7 @@ static void scmi_optee_clear_channel(struct scmi_chan_i= nfo *cinfo) struct scmi_optee_channel *channel =3D cinfo->transport_info; =20 if (!channel->tee_shm) - shmem_clear_channel(channel->req.shmem); + scmi_shmem_ops.clear_channel(channel->req.shmem); } =20 static int setup_dynamic_shmem(struct device *dev, struct scmi_optee_chann= el *channel) @@ -368,7 +368,7 @@ static int setup_dynamic_shmem(struct device *dev, stru= ct scmi_optee_channel *ch static int setup_static_shmem(struct device *dev, struct scmi_chan_info *c= info, struct scmi_optee_channel *channel) { - channel->req.shmem =3D setup_shmem_iomap(cinfo, dev, true, NULL); + channel->req.shmem =3D scmi_shmem_ops.setup_iomap(cinfo, dev, true, NULL); if (IS_ERR(channel->req.shmem)) return PTR_ERR(channel->req.shmem); =20 @@ -479,10 +479,10 @@ static int scmi_optee_send_message(struct scmi_chan_i= nfo *cinfo, mutex_lock(&channel->mu); =20 if (channel->tee_shm) { - msg_tx_prepare(channel->req.msg, xfer); - ret =3D invoke_process_msg_channel(channel, msg_command_size(xfer)); + scmi_msg_ops.tx_prepare(channel->req.msg, xfer); + ret =3D invoke_process_msg_channel(channel, scmi_msg_ops.command_size(xf= er)); } else { - shmem_tx_prepare(channel->req.shmem, xfer, cinfo); + scmi_shmem_ops.tx_prepare(channel->req.shmem, xfer, cinfo); ret =3D invoke_process_smt_channel(channel); } =20 @@ -498,9 +498,9 @@ static void scmi_optee_fetch_response(struct scmi_chan_= info *cinfo, struct scmi_optee_channel *channel =3D cinfo->transport_info; =20 if (channel->tee_shm) - msg_fetch_response(channel->req.msg, channel->rx_len, xfer); + scmi_msg_ops.fetch_response(channel->req.msg, channel->rx_len, xfer); else - shmem_fetch_response(channel->req.shmem, xfer); + scmi_shmem_ops.fetch_response(channel->req.shmem, xfer); } =20 static void scmi_optee_mark_txdone(struct scmi_chan_info *cinfo, int ret, diff --git a/drivers/firmware/arm_scmi/shmem.c b/drivers/firmware/arm_scmi/= shmem.c index a0d6f68172fc..477d391968c6 100644 --- a/drivers/firmware/arm_scmi/shmem.c +++ b/drivers/firmware/arm_scmi/shmem.c @@ -2,7 +2,7 @@ /* * For transport using shared mem structure. * - * Copyright (C) 2019 ARM Ltd. + * Copyright (C) 2019-2024 ARM Ltd. */ =20 #include @@ -34,8 +34,9 @@ struct scmi_shared_mem { u8 msg_payload[]; }; =20 -void shmem_tx_prepare(struct scmi_shared_mem __iomem *shmem, - struct scmi_xfer *xfer, struct scmi_chan_info *cinfo) +static void shmem_tx_prepare(struct scmi_shared_mem __iomem *shmem, + struct scmi_xfer *xfer, + struct scmi_chan_info *cinfo) { ktime_t stop; =20 @@ -75,13 +76,13 @@ void shmem_tx_prepare(struct scmi_shared_mem __iomem *s= hmem, memcpy_toio(shmem->msg_payload, xfer->tx.buf, xfer->tx.len); } =20 -u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem) +static u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem) { return ioread32(&shmem->msg_header); } =20 -void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem, - struct scmi_xfer *xfer) +static void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem, + struct scmi_xfer *xfer) { size_t len =3D ioread32(&shmem->length); =20 @@ -93,8 +94,8 @@ void shmem_fetch_response(struct scmi_shared_mem __iomem = *shmem, memcpy_fromio(xfer->rx.buf, shmem->msg_payload + 4, xfer->rx.len); } =20 -void shmem_fetch_notification(struct scmi_shared_mem __iomem *shmem, - size_t max_len, struct scmi_xfer *xfer) +static void shmem_fetch_notification(struct scmi_shared_mem __iomem *shmem, + size_t max_len, struct scmi_xfer *xfer) { size_t len =3D ioread32(&shmem->length); =20 @@ -105,13 +106,13 @@ void shmem_fetch_notification(struct scmi_shared_mem = __iomem *shmem, memcpy_fromio(xfer->rx.buf, shmem->msg_payload, xfer->rx.len); } =20 -void shmem_clear_channel(struct scmi_shared_mem __iomem *shmem) +static void shmem_clear_channel(struct scmi_shared_mem __iomem *shmem) { iowrite32(SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE, &shmem->channel_status); } =20 -bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem, - struct scmi_xfer *xfer) +static bool shmem_poll_done(struct scmi_shared_mem __iomem *shmem, + struct scmi_xfer *xfer) { u16 xfer_id; =20 @@ -125,20 +126,20 @@ bool shmem_poll_done(struct scmi_shared_mem __iomem *= shmem, SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE); } =20 -bool shmem_channel_free(struct scmi_shared_mem __iomem *shmem) +static bool shmem_channel_free(struct scmi_shared_mem __iomem *shmem) { return (ioread32(&shmem->channel_status) & SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE); } =20 -bool shmem_channel_intr_enabled(struct scmi_shared_mem __iomem *shmem) +static bool shmem_channel_intr_enabled(struct scmi_shared_mem __iomem *shm= em) { return ioread32(&shmem->flags) & SCMI_SHMEM_FLAG_INTR_ENABLED; } =20 -void __iomem *setup_shmem_iomap(struct scmi_chan_info *cinfo, - struct device *dev, bool tx, - struct resource *res) +static void __iomem *shmem_setup_iomap(struct scmi_chan_info *cinfo, + struct device *dev, bool tx, + struct resource *res) { struct device_node *shmem __free(device_node); const char *desc =3D tx ? "Tx" : "Rx"; @@ -174,3 +175,15 @@ void __iomem *setup_shmem_iomap(struct scmi_chan_info = *cinfo, =20 return addr; } + +const struct scmi_shared_mem_operations scmi_shmem_ops =3D { + .tx_prepare =3D shmem_tx_prepare, + .read_header =3D shmem_read_header, + .fetch_response =3D shmem_fetch_response, + .fetch_notification =3D shmem_fetch_notification, + .clear_channel =3D shmem_clear_channel, + .poll_done =3D shmem_poll_done, + .channel_free =3D shmem_channel_free, + .channel_intr_enabled =3D shmem_channel_intr_enabled, + .setup_iomap =3D shmem_setup_iomap, +}; diff --git a/drivers/firmware/arm_scmi/smc.c b/drivers/firmware/arm_scmi/sm= c.c index 59b6c04b52bc..4cb86386c490 100644 --- a/drivers/firmware/arm_scmi/smc.c +++ b/drivers/firmware/arm_scmi/smc.c @@ -74,7 +74,7 @@ static irqreturn_t smc_msg_done_isr(int irq, void *data) struct scmi_smc *scmi_info =3D data; =20 scmi_rx_callback(scmi_info->cinfo, - shmem_read_header(scmi_info->shmem), NULL); + scmi_shmem_ops.read_header(scmi_info->shmem), NULL); =20 return IRQ_HANDLED; } @@ -141,7 +141,7 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo,= struct device *dev, if (!scmi_info) return -ENOMEM; =20 - scmi_info->shmem =3D setup_shmem_iomap(cinfo, dev, tx, &res); + scmi_info->shmem =3D scmi_shmem_ops.setup_iomap(cinfo, dev, tx, &res); if (IS_ERR(scmi_info->shmem)) return PTR_ERR(scmi_info->shmem); =20 @@ -226,7 +226,7 @@ static int smc_send_message(struct scmi_chan_info *cinf= o, */ smc_channel_lock_acquire(scmi_info, xfer); =20 - shmem_tx_prepare(scmi_info->shmem, xfer, cinfo); + scmi_shmem_ops.tx_prepare(scmi_info->shmem, xfer, cinfo); =20 if (scmi_info->cap_id !=3D ULONG_MAX) arm_smccc_1_1_invoke(scmi_info->func_id, scmi_info->cap_id, 0, @@ -250,7 +250,7 @@ static void smc_fetch_response(struct scmi_chan_info *c= info, { struct scmi_smc *scmi_info =3D cinfo->transport_info; =20 - shmem_fetch_response(scmi_info->shmem, xfer); + scmi_shmem_ops.fetch_response(scmi_info->shmem, xfer); } =20 static void smc_mark_txdone(struct scmi_chan_info *cinfo, int ret, diff --git a/drivers/firmware/arm_scmi/virtio.c b/drivers/firmware/arm_scmi= /virtio.c index dd3459bdb9cb..e8d38e822c7e 100644 --- a/drivers/firmware/arm_scmi/virtio.c +++ b/drivers/firmware/arm_scmi/virtio.c @@ -295,7 +295,7 @@ static void scmi_vio_complete_cb(struct virtqueue *vque= ue) if (msg) { msg->rx_len =3D length; scmi_rx_callback(vioch->cinfo, - msg_read_header(msg->input), msg); + scmi_msg_ops.read_header(msg->input), msg); =20 scmi_finalize_message(vioch, msg); } @@ -340,7 +340,7 @@ static void scmi_vio_deferred_tx_worker(struct work_str= uct *work) */ if (msg->poll_status =3D=3D VIO_MSG_NOT_POLLED) scmi_rx_callback(vioch->cinfo, - msg_read_header(msg->input), msg); + scmi_msg_ops.read_header(msg->input), msg); =20 /* Free the processed message once done */ scmi_vio_msg_release(vioch, msg); @@ -510,10 +510,10 @@ static int virtio_send_message(struct scmi_chan_info = *cinfo, return -EBUSY; } =20 - msg_tx_prepare(msg->request, xfer); + scmi_msg_ops.tx_prepare(msg->request, xfer); =20 - sg_init_one(&sg_out, msg->request, msg_command_size(xfer)); - sg_init_one(&sg_in, msg->input, msg_response_size(xfer)); + sg_init_one(&sg_out, msg->request, scmi_msg_ops.command_size(xfer)); + sg_init_one(&sg_in, msg->input, scmi_msg_ops.response_size(xfer)); =20 spin_lock_irqsave(&vioch->lock, flags); =20 @@ -560,7 +560,7 @@ static void virtio_fetch_response(struct scmi_chan_info= *cinfo, struct scmi_vio_msg *msg =3D xfer->priv; =20 if (msg) - msg_fetch_response(msg->input, msg->rx_len, xfer); + scmi_msg_ops.fetch_response(msg->input, msg->rx_len, xfer); } =20 static void virtio_fetch_notification(struct scmi_chan_info *cinfo, @@ -569,7 +569,7 @@ static void virtio_fetch_notification(struct scmi_chan_= info *cinfo, struct scmi_vio_msg *msg =3D xfer->priv; =20 if (msg) - msg_fetch_notification(msg->input, msg->rx_len, max_len, xfer); + scmi_msg_ops.fetch_notification(msg->input, msg->rx_len, max_len, xfer); } =20 /** --=20 2.45.2 From nobody Sun Feb 8 23:42:03 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4064719F48D; Tue, 30 Jul 2024 13:33:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722346435; cv=none; b=g2yWaEPYbMs6pw+k1OP3HvisDrThMFFMuDPahFh+S9NpO/yePZ5ADf5MMjww6HhbGxUGu1dVjSApXkDiTbAv2tJEUREG58rHLGf4kKJtGbm0aWuYwRTaYcqpcQ6YiEgDo7mDN7rWsSL+oTnQo2RkhQUEa4nvRBdgtXsUIoWjYe0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722346435; c=relaxed/simple; bh=rMsmUMQQ7uKsKrwVyhVPoljN8MMlbZtpsK9MnkwnLLs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ks75+VoaWuRNNnv6f2odvu7S6DMFbHxjakVompkQolRm48ciNkbUniDRIBtgaAqAwqp4SaOI6aEhNAyRgY/BbF7j4TmWNmVa7Kj1tnXYyCz9Jaegv79JOI+KvEEncIRdIsskio4XcJ2rxZ/+bE1iQLVOm6+tSYvqKpgnM6P1aoI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com 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 6D49C153B; Tue, 30 Jul 2024 06:34:19 -0700 (PDT) Received: from pluto.guestnet.cambridge.arm.com (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 2BA193F5A1; Tue, 30 Jul 2024 06:33:51 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, arm-scmi@vger.kernel.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, etienne.carriere@st.com, peng.fan@oss.nxp.com, michal.simek@amd.com, quic_sibis@quicinc.com, quic_nkela@quicinc.com, ptosi@google.com, dan.carpenter@linaro.org, souvik.chakravarty@arm.com, Cristian Marussi Subject: [PATCH v3 4/9] firmware: arm_scmi: Add support for standalone transport drivers Date: Tue, 30 Jul 2024 14:33:13 +0100 Message-ID: <20240730133318.1573765-5-cristian.marussi@arm.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240730133318.1573765-1-cristian.marussi@arm.com> References: <20240730133318.1573765-1-cristian.marussi@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Extend the core SCMI stack with structures and methods to allow for transports to be split out as standalone drivers, while still supporting old style transports, defined as built into the SCMI core stack. No functional change. Signed-off-by: Cristian Marussi Tested-by: Florian Fainelli --- NOTE: old style transport support will be removed later in this series. v2 --> v3 - reworked DEFINE_SCMI_TRANSPORT + using platform device_alloc + add_data + add (so as to gain a proper default device_release method) + dropped remove in favour of devres_add_action_or_reset + using explicit parameters for driver/desc structs naming - renamed scmi_transport_lookup() to scmi_transport_setup() - fixed typo in comments v1 --> v2 - fixed comit message --- drivers/firmware/arm_scmi/common.h | 84 ++++++++++++++++++++++++++++++ drivers/firmware/arm_scmi/driver.c | 44 +++++++++++++++- drivers/firmware/arm_scmi/msg.c | 5 ++ drivers/firmware/arm_scmi/shmem.c | 5 ++ 4 files changed, 136 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi= /common.h index 8e5751aaa600..0f24f83112b9 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -349,6 +349,8 @@ struct scmi_shared_mem_operations { bool tx, struct resource *res); }; =20 +const struct scmi_shared_mem_operations *scmi_shared_mem_operations_get(vo= id); + /* declarations for message passing transports */ struct scmi_msg_payld; =20 @@ -376,6 +378,88 @@ struct scmi_message_operations { size_t max_len, struct scmi_xfer *xfer); }; =20 +const struct scmi_message_operations *scmi_message_operations_get(void); + +/** + * struct scmi_transport_core_operations - Transpoert core operations + * + * @bad_message_trace: An helper to report a malformed/unexpected message + * @rx_callback: Callback to report received messages + * @shmem: Datagram operations for shared memory based transports + * @msg: Datagram operations for message based transports + */ +struct scmi_transport_core_operations { + void (*bad_message_trace)(struct scmi_chan_info *cinfo, + u32 msg_hdr, enum scmi_bad_msg err); + void (*rx_callback)(struct scmi_chan_info *cinfo, u32 msg_hdr, + void *priv); + const struct scmi_shared_mem_operations *shmem; + const struct scmi_message_operations *msg; +}; + +/** + * struct scmi_transport - A structure representing a configured transport + * + * @supplier: Device representing the transport and acting as a supplier f= or + * the core SCMI stack + * @desc: Transport descriptor + * @core_ops: A pointer to a pointer used by the core SCMI stack to make t= he + * core transport operations accessible to the transports. + */ +struct scmi_transport { + struct device *supplier; + const struct scmi_desc *desc; + struct scmi_transport_core_operations **core_ops; +}; + +#define DEFINE_SCMI_TRANSPORT_DRIVER(__tag, __drv, __desc, __match, __core= _ops)\ +static void __tag##_dev_free(void *data) \ +{ \ + struct platform_device *spdev =3D data; \ + \ + platform_device_unregister(spdev); \ +} \ + \ +static int __tag##_probe(struct platform_device *pdev) \ +{ \ + struct device *dev =3D &pdev->dev; \ + struct platform_device *spdev; \ + struct scmi_transport strans; \ + int ret; \ + \ + spdev =3D platform_device_alloc("arm-scmi", PLATFORM_DEVID_AUTO); \ + if (!spdev) \ + return -ENOMEM; \ + \ + device_set_of_node_from_dev(&spdev->dev, dev); \ + \ + strans.supplier =3D dev; \ + strans.desc =3D &(__desc); \ + strans.core_ops =3D &(__core_ops); \ + \ + ret =3D platform_device_add_data(spdev, &strans, sizeof(strans)); \ + if (ret) \ + goto err; \ + \ + ret =3D platform_device_add(spdev); \ + if (ret) \ + goto err; \ + \ + return devm_add_action_or_reset(dev, __tag##_dev_free, spdev); \ + \ +err: \ + platform_device_put(spdev); \ + return ret; \ +} \ + \ +static struct platform_driver __drv =3D { \ + .driver =3D { \ + .name =3D #__tag "_transport", \ + .of_match_table =3D __match, \ + }, \ + .probe =3D __tag##_probe, \ +} + extern const struct scmi_shared_mem_operations scmi_shmem_ops; extern const struct scmi_message_operations scmi_msg_ops; =20 diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi= /driver.c index 6b6957f4743f..722306cc19bf 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -194,6 +194,11 @@ struct scmi_info { #define bus_nb_to_scmi_info(nb) container_of(nb, struct scmi_info, bus_nb) #define req_nb_to_scmi_info(nb) container_of(nb, struct scmi_info, dev_req= _nb) =20 +static struct scmi_transport_core_operations scmi_trans_core_ops =3D { + .bad_message_trace =3D scmi_bad_message_trace, + .rx_callback =3D scmi_rx_callback, +}; + static unsigned long scmi_vendor_protocol_signature(unsigned int protocol_id, char *vendor_id, char *sub_vendor_id, u32 impl_ver) @@ -2950,6 +2955,28 @@ static int scmi_debugfs_raw_mode_setup(struct scmi_i= nfo *info) return ret; } =20 +static const struct scmi_desc *scmi_transport_setup(struct device *dev) +{ + struct scmi_transport *trans; + + trans =3D dev_get_platdata(dev); + if (!trans || !trans->desc || !trans->supplier || !trans->core_ops) + return NULL; + + if (!device_link_add(dev, trans->supplier, DL_FLAG_AUTOREMOVE_CONSUMER)) { + dev_err(dev, + "Adding link to supplier transport device failed\n"); + return NULL; + } + + /* Provide core transport ops */ + *trans->core_ops =3D &scmi_trans_core_ops; + + dev_info(dev, "Using %s\n", dev_driver_string(trans->supplier)); + + return trans->desc; +} + static int scmi_probe(struct platform_device *pdev) { int ret; @@ -2962,8 +2989,14 @@ static int scmi_probe(struct platform_device *pdev) struct device_node *child, *np =3D dev->of_node; =20 desc =3D of_device_get_match_data(dev); - if (!desc) - return -EINVAL; + if (!desc) { + desc =3D scmi_transport_setup(dev); + if (!desc) { + err_str =3D "transport invalid\n"; + ret =3D -EINVAL; + goto out_err; + } + } =20 info =3D devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); if (!info) @@ -3130,6 +3163,7 @@ static int scmi_probe(struct platform_device *pdev) clear_ida: ida_free(&scmi_id, info->id); =20 +out_err: return dev_err_probe(dev, ret, "%s", err_str); } =20 @@ -3321,6 +3355,12 @@ static int __init scmi_driver_init(void) if (ret) return ret; =20 + if (IS_ENABLED(CONFIG_ARM_SCMI_HAVE_SHMEM)) + scmi_trans_core_ops.shmem =3D scmi_shared_mem_operations_get(); + + if (IS_ENABLED(CONFIG_ARM_SCMI_HAVE_MSG)) + scmi_trans_core_ops.msg =3D scmi_message_operations_get(); + if (IS_ENABLED(CONFIG_ARM_SCMI_NEED_DEBUGFS)) scmi_top_dentry =3D scmi_debugfs_init(); =20 diff --git a/drivers/firmware/arm_scmi/msg.c b/drivers/firmware/arm_scmi/ms= g.c index f5f6c2c55577..18337f9191d0 100644 --- a/drivers/firmware/arm_scmi/msg.c +++ b/drivers/firmware/arm_scmi/msg.c @@ -118,3 +118,8 @@ const struct scmi_message_operations scmi_msg_ops =3D { .fetch_response =3D msg_fetch_response, .fetch_notification =3D msg_fetch_notification, }; + +const struct scmi_message_operations *scmi_message_operations_get(void) +{ + return &scmi_msg_ops; +} diff --git a/drivers/firmware/arm_scmi/shmem.c b/drivers/firmware/arm_scmi/= shmem.c index 477d391968c6..3fba05e1560c 100644 --- a/drivers/firmware/arm_scmi/shmem.c +++ b/drivers/firmware/arm_scmi/shmem.c @@ -187,3 +187,8 @@ const struct scmi_shared_mem_operations scmi_shmem_ops = =3D { .channel_intr_enabled =3D shmem_channel_intr_enabled, .setup_iomap =3D shmem_setup_iomap, }; + +const struct scmi_shared_mem_operations *scmi_shared_mem_operations_get(vo= id) +{ + return &scmi_shmem_ops; +} --=20 2.45.2 From nobody Sun Feb 8 23:42:03 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 6F6681A071F; Tue, 30 Jul 2024 13:33:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722346439; cv=none; b=XYQOqVPHRExmxKh1YCJ7PcPTYpxey2rzrL6dg5QL97kjLFHVqnh+MpZZBPW4KQGmj/c3saURE6Z0R8Phk4yTThxz62PGd5ysbdPwRthEt8Geu7vDxI9aJ2j9jmGNGeV/6nLHd0vQl8poxA8MeTJSFNI8IoT3vSNNHVsfeGBUhjk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722346439; c=relaxed/simple; bh=cMJxGgAikLEu95luJ3Ht/cOUB7eOWZ5Knhpt+2DLBW8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=eyYEokoO+s5I92uUqZxD9/NZBRiACT0uD3LwrXdWCCuMQAXNyvQhrto/hXQLOnxKdaONdS/NLDLpV7VHGY40Oyfy3xr9FyNuE2SF4G3H1SWCabceZP+sVXsugU2cr3nZZsPZ5joX0UWF7aAGAtmQMFvT3rpCPuv6TPh3yiOV2WQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com 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 44F4A1576; Tue, 30 Jul 2024 06:34:22 -0700 (PDT) Received: from pluto.guestnet.cambridge.arm.com (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 22D723F5A1; Tue, 30 Jul 2024 06:33:54 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, arm-scmi@vger.kernel.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, etienne.carriere@st.com, peng.fan@oss.nxp.com, michal.simek@amd.com, quic_sibis@quicinc.com, quic_nkela@quicinc.com, ptosi@google.com, dan.carpenter@linaro.org, souvik.chakravarty@arm.com, Cristian Marussi Subject: [PATCH v3 5/9] firmware: arm_scmi: Make MBOX transport a standalone driver Date: Tue, 30 Jul 2024 14:33:14 +0100 Message-ID: <20240730133318.1573765-6-cristian.marussi@arm.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240730133318.1573765-1-cristian.marussi@arm.com> References: <20240730133318.1573765-1-cristian.marussi@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Make SCMI mailbox transport a standalne driver that can be optionally loaded as a module. Signed-off-by: Cristian Marussi Tested-by: Florian Fainelli --- v2 --> v3 - fixed spacing in Kconfig - updated Copyright - use new params in DEFINE_SCMI_TRANSPORT_DRIVER --- drivers/firmware/arm_scmi/Kconfig | 4 +- drivers/firmware/arm_scmi/Makefile | 3 +- drivers/firmware/arm_scmi/common.h | 3 -- drivers/firmware/arm_scmi/driver.c | 3 -- .../{mailbox.c =3D> scmi_transport_mailbox.c} | 47 +++++++++++++------ 5 files changed, 38 insertions(+), 22 deletions(-) rename drivers/firmware/arm_scmi/{mailbox.c =3D> scmi_transport_mailbox.c}= (87%) diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/= Kconfig index aa5842be19b2..f03875169215 100644 --- a/drivers/firmware/arm_scmi/Kconfig +++ b/drivers/firmware/arm_scmi/Kconfig @@ -75,7 +75,7 @@ config ARM_SCMI_HAVE_MSG available. =20 config ARM_SCMI_TRANSPORT_MAILBOX - bool "SCMI transport based on Mailbox" + tristate "SCMI transport based on Mailbox" depends on MAILBOX select ARM_SCMI_HAVE_TRANSPORT select ARM_SCMI_HAVE_SHMEM @@ -85,6 +85,8 @@ config ARM_SCMI_TRANSPORT_MAILBOX =20 If you want the ARM SCMI PROTOCOL stack to include support for a transport based on mailboxes, answer Y. + This driver can also be built as a module. If so, the module + will be called scmi_transport_mailbox. =20 config ARM_SCMI_TRANSPORT_OPTEE bool "SCMI transport based on OP-TEE service" diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi= /Makefile index fd59f58ce8a2..121612d75f0b 100644 --- a/drivers/firmware/arm_scmi/Makefile +++ b/drivers/firmware/arm_scmi/Makefile @@ -5,7 +5,6 @@ scmi-core-objs :=3D $(scmi-bus-y) scmi-driver-y =3D driver.o notify.o scmi-driver-$(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT) +=3D raw_mode.o scmi-transport-$(CONFIG_ARM_SCMI_HAVE_SHMEM) =3D shmem.o -scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) +=3D mailbox.o scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) +=3D smc.o scmi-transport-$(CONFIG_ARM_SCMI_HAVE_MSG) +=3D msg.o scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) +=3D virtio.o @@ -14,6 +13,8 @@ scmi-protocols-y :=3D base.o clock.o perf.o power.o reset= .o sensors.o system.o vol scmi-protocols-y +=3D pinctrl.o scmi-module-objs :=3D $(scmi-driver-y) $(scmi-protocols-y) $(scmi-transpor= t-y) =20 +obj-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) +=3D scmi_transport_mailbox.o + obj-$(CONFIG_ARM_SCMI_PROTOCOL) +=3D scmi-core.o obj-$(CONFIG_ARM_SCMI_PROTOCOL) +=3D scmi-module.o =20 diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi= /common.h index 0f24f83112b9..abaf7ce6fbab 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -286,9 +286,6 @@ int scmi_xfer_raw_inflight_register(const struct scmi_h= andle *handle, int scmi_xfer_raw_wait_for_message_response(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer, unsigned int timeout_ms); -#ifdef CONFIG_ARM_SCMI_TRANSPORT_MAILBOX -extern const struct scmi_desc scmi_mailbox_desc; -#endif #ifdef CONFIG_ARM_SCMI_TRANSPORT_SMC extern const struct scmi_desc scmi_smc_desc; #endif diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi= /driver.c index 722306cc19bf..9d869ab2d003 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -3251,9 +3251,6 @@ ATTRIBUTE_GROUPS(versions); =20 /* Each compatible listed below must have descriptor associated with it */ static const struct of_device_id scmi_of_match[] =3D { -#ifdef CONFIG_ARM_SCMI_TRANSPORT_MAILBOX - { .compatible =3D "arm,scmi", .data =3D &scmi_mailbox_desc }, -#endif #ifdef CONFIG_ARM_SCMI_TRANSPORT_OPTEE { .compatible =3D "linaro,scmi-optee", .data =3D &scmi_optee_desc }, #endif diff --git a/drivers/firmware/arm_scmi/mailbox.c b/drivers/firmware/arm_scm= i/scmi_transport_mailbox.c similarity index 87% rename from drivers/firmware/arm_scmi/mailbox.c rename to drivers/firmware/arm_scmi/scmi_transport_mailbox.c index 60698efe8442..75483b6778ee 100644 --- a/drivers/firmware/arm_scmi/mailbox.c +++ b/drivers/firmware/arm_scmi/scmi_transport_mailbox.c @@ -3,7 +3,7 @@ * System Control and Management Interface (SCMI) Message Mailbox Transport * driver. * - * Copyright (C) 2019 ARM Ltd. + * Copyright (C) 2019-2024 ARM Ltd. */ =20 #include @@ -11,6 +11,7 @@ #include #include #include +#include #include =20 #include "common.h" @@ -36,11 +37,13 @@ struct scmi_mailbox { =20 #define client_to_scmi_mailbox(c) container_of(c, struct scmi_mailbox, cl) =20 +static struct scmi_transport_core_operations *core; + static void tx_prepare(struct mbox_client *cl, void *m) { struct scmi_mailbox *smbox =3D client_to_scmi_mailbox(cl); =20 - scmi_shmem_ops.tx_prepare(smbox->shmem, m, smbox->cinfo); + core->shmem->tx_prepare(smbox->shmem, m, smbox->cinfo); } =20 static void rx_callback(struct mbox_client *cl, void *m) @@ -56,15 +59,17 @@ static void rx_callback(struct mbox_client *cl, void *m) * a previous timed-out reply which arrived late could be wrongly * associated with the next pending transaction. */ - if (cl->knows_txdone && !scmi_shmem_ops.channel_free(smbox->shmem)) { + if (cl->knows_txdone && + !core->shmem->channel_free(smbox->shmem)) { dev_warn(smbox->cinfo->dev, "Ignoring spurious A2P IRQ !\n"); - scmi_bad_message_trace(smbox->cinfo, - scmi_shmem_ops.read_header(smbox->shmem), - MSG_MBOX_SPURIOUS); + core->bad_message_trace(smbox->cinfo, + core->shmem->read_header(smbox->shmem), + MSG_MBOX_SPURIOUS); return; } =20 - scmi_rx_callback(smbox->cinfo, scmi_shmem_ops.read_header(smbox->shmem), = NULL); + core->rx_callback(smbox->cinfo, + core->shmem->read_header(smbox->shmem), NULL); } =20 static bool mailbox_chan_available(struct device_node *of_node, int idx) @@ -192,7 +197,7 @@ static int mailbox_chan_setup(struct scmi_chan_info *ci= nfo, struct device *dev, if (!smbox) return -ENOMEM; =20 - smbox->shmem =3D scmi_shmem_ops.setup_iomap(cinfo, dev, tx, NULL); + smbox->shmem =3D core->shmem->setup_iomap(cinfo, dev, tx, NULL); if (IS_ERR(smbox->shmem)) return PTR_ERR(smbox->shmem); =20 @@ -293,7 +298,7 @@ static void mailbox_fetch_response(struct scmi_chan_inf= o *cinfo, { struct scmi_mailbox *smbox =3D cinfo->transport_info; =20 - scmi_shmem_ops.fetch_response(smbox->shmem, xfer); + core->shmem->fetch_response(smbox->shmem, xfer); } =20 static void mailbox_fetch_notification(struct scmi_chan_info *cinfo, @@ -301,7 +306,7 @@ static void mailbox_fetch_notification(struct scmi_chan= _info *cinfo, { struct scmi_mailbox *smbox =3D cinfo->transport_info; =20 - scmi_shmem_ops.fetch_notification(smbox->shmem, max_len, xfer); + core->shmem->fetch_notification(smbox->shmem, max_len, xfer); } =20 static void mailbox_clear_channel(struct scmi_chan_info *cinfo) @@ -310,9 +315,9 @@ static void mailbox_clear_channel(struct scmi_chan_info= *cinfo) struct mbox_chan *intr_chan; int ret; =20 - scmi_shmem_ops.clear_channel(smbox->shmem); + core->shmem->clear_channel(smbox->shmem); =20 - if (!scmi_shmem_ops.channel_intr_enabled(smbox->shmem)) + if (!core->shmem->channel_intr_enabled(smbox->shmem)) return; =20 if (smbox->chan_platform_receiver) @@ -335,7 +340,7 @@ mailbox_poll_done(struct scmi_chan_info *cinfo, struct = scmi_xfer *xfer) { struct scmi_mailbox *smbox =3D cinfo->transport_info; =20 - return scmi_shmem_ops.poll_done(smbox->shmem, xfer); + return core->shmem->poll_done(smbox->shmem, xfer); } =20 static const struct scmi_transport_ops scmi_mailbox_ops =3D { @@ -350,9 +355,23 @@ static const struct scmi_transport_ops scmi_mailbox_op= s =3D { .poll_done =3D mailbox_poll_done, }; =20 -const struct scmi_desc scmi_mailbox_desc =3D { +static const struct scmi_desc scmi_mailbox_desc =3D { .ops =3D &scmi_mailbox_ops, .max_rx_timeout_ms =3D 30, /* We may increase this if required */ .max_msg =3D 20, /* Limited by MBOX_TX_QUEUE_LEN */ .max_msg_size =3D 128, }; + +static const struct of_device_id scmi_of_match[] =3D { + { .compatible =3D "arm,scmi" }, + { /* Sentinel */ }, +}; + +DEFINE_SCMI_TRANSPORT_DRIVER(scmi_mailbox, scmi_mailbox_driver, + scmi_mailbox_desc, scmi_of_match, core); +module_platform_driver(scmi_mailbox_driver); + +MODULE_ALIAS("scmi-transport-mailbox"); +MODULE_AUTHOR("Sudeep Holla "); +MODULE_DESCRIPTION("SCMI Mailbox Transport driver"); +MODULE_LICENSE("GPL"); --=20 2.45.2 From nobody Sun Feb 8 23:42:03 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 5B2A41A08B5; Tue, 30 Jul 2024 13:34:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722346442; cv=none; b=eoZANFmdfz2yxDquN1NTy4thL3b0Ee5pVYp1bZgTStBYt0DG9aQ+2vZcKTeU8hU4iYe4XkMUWWtP5RExTr1RA8RKbWl21gLDYt3AiFxE76evNv/PQ9PfaTgqvjp9kVRg4YS8v6VszA/3PjeJUvPz/wFVAl0j/ZsekrXj6Hb35Rk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722346442; c=relaxed/simple; bh=5FIksF/KU0+nb4wa9QbNrPkjt6vdx2/HTR2ofeKeyzQ=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=IEM7Ev/W82/fcQX9mpuNgPw0LiA5K3CELUjhwW6pxVmeyWk6S9IQSsU6IvjxT1gLMsXeN2moJjTAJJ64xpz7MhTNcpDL9BA0WfuVPeB2PqHm75zEt8n71DdL4a+z42AlvdEFFH1aEial6iI6AWXZTW7N+zIUWM8m0HKOdBEX2M4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com 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 524C61007; Tue, 30 Jul 2024 06:34:25 -0700 (PDT) Received: from pluto.guestnet.cambridge.arm.com (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id EFD123F5A1; Tue, 30 Jul 2024 06:33:56 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, arm-scmi@vger.kernel.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, etienne.carriere@st.com, peng.fan@oss.nxp.com, michal.simek@amd.com, quic_sibis@quicinc.com, quic_nkela@quicinc.com, ptosi@google.com, dan.carpenter@linaro.org, souvik.chakravarty@arm.com, Cristian Marussi , Peng Fan Subject: [PATCH v3 6/9] firmware: arm_scmi: Make SMC transport a standalone driver Date: Tue, 30 Jul 2024 14:33:15 +0100 Message-ID: <20240730133318.1573765-7-cristian.marussi@arm.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240730133318.1573765-1-cristian.marussi@arm.com> References: <20240730133318.1573765-1-cristian.marussi@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Make SCMI SMC transport a standalone driver that can be optionally loaded as a module. CC: Peng Fan CC: Nikunj Kela Signed-off-by: Cristian Marussi Tested-by: Florian Fainelli Tested-by: Nikunj Kela --- v2 --> v3 - fixed spacing in Kconfig and Copyright - use new params in DEFINE_SCMI_TRANSPORT_DRIVER v1 --> v2 - make scmi_smc_desc static --- drivers/firmware/arm_scmi/Kconfig | 4 ++- drivers/firmware/arm_scmi/Makefile | 2 +- drivers/firmware/arm_scmi/common.h | 3 -- drivers/firmware/arm_scmi/driver.c | 5 --- .../arm_scmi/{smc.c =3D> scmi_transport_smc.c} | 32 +++++++++++++++---- 5 files changed, 30 insertions(+), 16 deletions(-) rename drivers/firmware/arm_scmi/{smc.c =3D> scmi_transport_smc.c} (88%) diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/= Kconfig index f03875169215..f634c5af1912 100644 --- a/drivers/firmware/arm_scmi/Kconfig +++ b/drivers/firmware/arm_scmi/Kconfig @@ -102,7 +102,7 @@ config ARM_SCMI_TRANSPORT_OPTEE transport based on OP-TEE SCMI service, answer Y. =20 config ARM_SCMI_TRANSPORT_SMC - bool "SCMI transport based on SMC" + tristate "SCMI transport based on SMC" depends on HAVE_ARM_SMCCC_DISCOVERY select ARM_SCMI_HAVE_TRANSPORT select ARM_SCMI_HAVE_SHMEM @@ -112,6 +112,8 @@ config ARM_SCMI_TRANSPORT_SMC =20 If you want the ARM SCMI PROTOCOL stack to include support for a transport based on SMC, answer Y. + This driver can also be built as a module. If so, the module + will be called scmi_transport_smc. =20 config ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE bool "Enable atomic mode support for SCMI SMC transport" diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi= /Makefile index 121612d75f0b..6868a47fa4ab 100644 --- a/drivers/firmware/arm_scmi/Makefile +++ b/drivers/firmware/arm_scmi/Makefile @@ -5,7 +5,6 @@ scmi-core-objs :=3D $(scmi-bus-y) scmi-driver-y =3D driver.o notify.o scmi-driver-$(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT) +=3D raw_mode.o scmi-transport-$(CONFIG_ARM_SCMI_HAVE_SHMEM) =3D shmem.o -scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) +=3D smc.o scmi-transport-$(CONFIG_ARM_SCMI_HAVE_MSG) +=3D msg.o scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) +=3D virtio.o scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) +=3D optee.o @@ -13,6 +12,7 @@ scmi-protocols-y :=3D base.o clock.o perf.o power.o reset= .o sensors.o system.o vol scmi-protocols-y +=3D pinctrl.o scmi-module-objs :=3D $(scmi-driver-y) $(scmi-protocols-y) $(scmi-transpor= t-y) =20 +obj-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) +=3D scmi_transport_smc.o obj-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) +=3D scmi_transport_mailbox.o =20 obj-$(CONFIG_ARM_SCMI_PROTOCOL) +=3D scmi-core.o diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi= /common.h index abaf7ce6fbab..f44763bfec16 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -286,9 +286,6 @@ int scmi_xfer_raw_inflight_register(const struct scmi_h= andle *handle, int scmi_xfer_raw_wait_for_message_response(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer, unsigned int timeout_ms); -#ifdef CONFIG_ARM_SCMI_TRANSPORT_SMC -extern const struct scmi_desc scmi_smc_desc; -#endif #ifdef CONFIG_ARM_SCMI_TRANSPORT_VIRTIO extern const struct scmi_desc scmi_virtio_desc; #endif diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi= /driver.c index 9d869ab2d003..c4d0195f0fdb 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -3254,11 +3254,6 @@ static const struct of_device_id scmi_of_match[] =3D= { #ifdef CONFIG_ARM_SCMI_TRANSPORT_OPTEE { .compatible =3D "linaro,scmi-optee", .data =3D &scmi_optee_desc }, #endif -#ifdef CONFIG_ARM_SCMI_TRANSPORT_SMC - { .compatible =3D "arm,scmi-smc", .data =3D &scmi_smc_desc}, - { .compatible =3D "arm,scmi-smc-param", .data =3D &scmi_smc_desc}, - { .compatible =3D "qcom,scmi-smc", .data =3D &scmi_smc_desc}, -#endif #ifdef CONFIG_ARM_SCMI_TRANSPORT_VIRTIO { .compatible =3D "arm,scmi-virtio", .data =3D &scmi_virtio_desc}, #endif diff --git a/drivers/firmware/arm_scmi/smc.c b/drivers/firmware/arm_scmi/sc= mi_transport_smc.c similarity index 88% rename from drivers/firmware/arm_scmi/smc.c rename to drivers/firmware/arm_scmi/scmi_transport_smc.c index 4cb86386c490..1c203a68acd4 100644 --- a/drivers/firmware/arm_scmi/smc.c +++ b/drivers/firmware/arm_scmi/scmi_transport_smc.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include =20 @@ -69,12 +70,14 @@ struct scmi_smc { unsigned long cap_id; }; =20 +static struct scmi_transport_core_operations *core; + static irqreturn_t smc_msg_done_isr(int irq, void *data) { struct scmi_smc *scmi_info =3D data; =20 - scmi_rx_callback(scmi_info->cinfo, - scmi_shmem_ops.read_header(scmi_info->shmem), NULL); + core->rx_callback(scmi_info->cinfo, + core->shmem->read_header(scmi_info->shmem), NULL); =20 return IRQ_HANDLED; } @@ -141,7 +144,7 @@ static int smc_chan_setup(struct scmi_chan_info *cinfo,= struct device *dev, if (!scmi_info) return -ENOMEM; =20 - scmi_info->shmem =3D scmi_shmem_ops.setup_iomap(cinfo, dev, tx, &res); + scmi_info->shmem =3D core->shmem->setup_iomap(cinfo, dev, tx, &res); if (IS_ERR(scmi_info->shmem)) return PTR_ERR(scmi_info->shmem); =20 @@ -226,7 +229,7 @@ static int smc_send_message(struct scmi_chan_info *cinf= o, */ smc_channel_lock_acquire(scmi_info, xfer); =20 - scmi_shmem_ops.tx_prepare(scmi_info->shmem, xfer, cinfo); + core->shmem->tx_prepare(scmi_info->shmem, xfer, cinfo); =20 if (scmi_info->cap_id !=3D ULONG_MAX) arm_smccc_1_1_invoke(scmi_info->func_id, scmi_info->cap_id, 0, @@ -250,7 +253,7 @@ static void smc_fetch_response(struct scmi_chan_info *c= info, { struct scmi_smc *scmi_info =3D cinfo->transport_info; =20 - scmi_shmem_ops.fetch_response(scmi_info->shmem, xfer); + core->shmem->fetch_response(scmi_info->shmem, xfer); } =20 static void smc_mark_txdone(struct scmi_chan_info *cinfo, int ret, @@ -270,7 +273,7 @@ static const struct scmi_transport_ops scmi_smc_ops =3D= { .fetch_response =3D smc_fetch_response, }; =20 -const struct scmi_desc scmi_smc_desc =3D { +static const struct scmi_desc scmi_smc_desc =3D { .ops =3D &scmi_smc_ops, .max_rx_timeout_ms =3D 30, .max_msg =3D 20, @@ -286,3 +289,20 @@ const struct scmi_desc scmi_smc_desc =3D { .sync_cmds_completed_on_ret =3D true, .atomic_enabled =3D IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABL= E), }; + +static const struct of_device_id scmi_of_match[] =3D { + { .compatible =3D "arm,scmi-smc" }, + { .compatible =3D "arm,scmi-smc-param" }, + { .compatible =3D "qcom,scmi-smc" }, + { /* Sentinel */ }, +}; + +DEFINE_SCMI_TRANSPORT_DRIVER(scmi_smc, scmi_smc_driver, scmi_smc_desc, + scmi_of_match, core); +module_platform_driver(scmi_smc_driver); + +MODULE_ALIAS("scmi-transport-smc"); +MODULE_AUTHOR("Peng Fan "); +MODULE_AUTHOR("Nikunj Kela "); +MODULE_DESCRIPTION("SCMI SMC Transport driver"); +MODULE_LICENSE("GPL"); --=20 2.45.2 From nobody Sun Feb 8 23:42:03 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 44BD01A00E7; Tue, 30 Jul 2024 13:34:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722346445; cv=none; b=bHO+a/h5MppI1WLo/4IGmf7ecpfxjxVYDdKhpoumUCmiWWTk8h4QJ1twFVCxcQnNwY35fT/BpVBlm+pQCKWYkhNZ6hh6tM0k9Msd9DvN/DbjdaC05JOjYOL80wM/zO2TV69R+I32lYTc0I+rT4zEZo/CPEeB0ZkR7ZhP3mskQZU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722346445; c=relaxed/simple; bh=/pZGdLDkczKQndNo6Gq5sJk05wn7Z+IeYQJK7L0gSRA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=JaLOwZmFHn70We6DiVjre9aQtvizD2Vf3xYXcKC2g2fe7mmVnxR9T8ESY9zpTU2b7DTOu2uKYknezle5DrzaMOlw2bEf4FCW7y9hzbJRQEMRO+ApN7J6CicOs/11I+jA1+83yZti0vi4bQBFsd4eIoxTWI6AYFLX5q0lEIldZrE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com 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 4EF9C106F; Tue, 30 Jul 2024 06:34:28 -0700 (PDT) Received: from pluto.guestnet.cambridge.arm.com (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 04E723F5A1; Tue, 30 Jul 2024 06:33:59 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, arm-scmi@vger.kernel.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, etienne.carriere@st.com, peng.fan@oss.nxp.com, michal.simek@amd.com, quic_sibis@quicinc.com, quic_nkela@quicinc.com, ptosi@google.com, dan.carpenter@linaro.org, souvik.chakravarty@arm.com, Cristian Marussi , Etienne Carriere Subject: [PATCH v3 7/9] firmware: arm_scmi: Make OPTEE transport a standalone driver Date: Tue, 30 Jul 2024 14:33:16 +0100 Message-ID: <20240730133318.1573765-8-cristian.marussi@arm.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240730133318.1573765-1-cristian.marussi@arm.com> References: <20240730133318.1573765-1-cristian.marussi@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Make SCMI OPTEE transport a standalone driver that can be optionally loaded as a module. CC: Etienne Carriere Signed-off-by: Cristian Marussi Tested-by: Florian Fainelli --- v2 --> v3 - fixed spacing in Kconfig and Copyright - fixed platform_driver_unregister call in .remove (was called to late to work...) - use new params in DEFINE_SCMI_TRANSPORT_DRIVER v1 --> v2 - handle platform_driver_register() failures --- drivers/firmware/arm_scmi/Kconfig | 6 +- drivers/firmware/arm_scmi/Makefile | 2 +- drivers/firmware/arm_scmi/common.h | 3 - drivers/firmware/arm_scmi/driver.c | 3 - .../{optee.c =3D> scmi_transport_optee.c} | 90 ++++++++++--------- 5 files changed, 52 insertions(+), 52 deletions(-) rename drivers/firmware/arm_scmi/{optee.c =3D> scmi_transport_optee.c} (91= %) diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/= Kconfig index f634c5af1912..5186794b0505 100644 --- a/drivers/firmware/arm_scmi/Kconfig +++ b/drivers/firmware/arm_scmi/Kconfig @@ -89,8 +89,8 @@ config ARM_SCMI_TRANSPORT_MAILBOX will be called scmi_transport_mailbox. =20 config ARM_SCMI_TRANSPORT_OPTEE - bool "SCMI transport based on OP-TEE service" - depends on OPTEE=3Dy || OPTEE=3DARM_SCMI_PROTOCOL + tristate "SCMI transport based on OP-TEE service" + depends on OPTEE select ARM_SCMI_HAVE_TRANSPORT select ARM_SCMI_HAVE_SHMEM select ARM_SCMI_HAVE_MSG @@ -100,6 +100,8 @@ config ARM_SCMI_TRANSPORT_OPTEE =20 If you want the ARM SCMI PROTOCOL stack to include support for a transport based on OP-TEE SCMI service, answer Y. + This driver can also be built as a module. If so, the module + will be called scmi_transport_optee. =20 config ARM_SCMI_TRANSPORT_SMC tristate "SCMI transport based on SMC" diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi= /Makefile index 6868a47fa4ab..b04119ce972f 100644 --- a/drivers/firmware/arm_scmi/Makefile +++ b/drivers/firmware/arm_scmi/Makefile @@ -7,13 +7,13 @@ scmi-driver-$(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT) +=3D raw_= mode.o scmi-transport-$(CONFIG_ARM_SCMI_HAVE_SHMEM) =3D shmem.o scmi-transport-$(CONFIG_ARM_SCMI_HAVE_MSG) +=3D msg.o scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) +=3D virtio.o -scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) +=3D optee.o scmi-protocols-y :=3D base.o clock.o perf.o power.o reset.o sensors.o syst= em.o voltage.o powercap.o scmi-protocols-y +=3D pinctrl.o scmi-module-objs :=3D $(scmi-driver-y) $(scmi-protocols-y) $(scmi-transpor= t-y) =20 obj-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) +=3D scmi_transport_smc.o obj-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) +=3D scmi_transport_mailbox.o +obj-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) +=3D scmi_transport_optee.o =20 obj-$(CONFIG_ARM_SCMI_PROTOCOL) +=3D scmi-core.o obj-$(CONFIG_ARM_SCMI_PROTOCOL) +=3D scmi-module.o diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi= /common.h index f44763bfec16..3ee775fca1d2 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -289,9 +289,6 @@ int scmi_xfer_raw_wait_for_message_response(struct scmi= _chan_info *cinfo, #ifdef CONFIG_ARM_SCMI_TRANSPORT_VIRTIO extern const struct scmi_desc scmi_virtio_desc; #endif -#ifdef CONFIG_ARM_SCMI_TRANSPORT_OPTEE -extern const struct scmi_desc scmi_optee_desc; -#endif =20 void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, void *pri= v); =20 diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi= /driver.c index c4d0195f0fdb..e4fb1f75200f 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -3251,9 +3251,6 @@ ATTRIBUTE_GROUPS(versions); =20 /* Each compatible listed below must have descriptor associated with it */ static const struct of_device_id scmi_of_match[] =3D { -#ifdef CONFIG_ARM_SCMI_TRANSPORT_OPTEE - { .compatible =3D "linaro,scmi-optee", .data =3D &scmi_optee_desc }, -#endif #ifdef CONFIG_ARM_SCMI_TRANSPORT_VIRTIO { .compatible =3D "arm,scmi-virtio", .data =3D &scmi_virtio_desc}, #endif diff --git a/drivers/firmware/arm_scmi/optee.c b/drivers/firmware/arm_scmi/= scmi_transport_optee.c similarity index 91% rename from drivers/firmware/arm_scmi/optee.c rename to drivers/firmware/arm_scmi/scmi_transport_optee.c index dae68adf6f9e..974128d73f2d 100644 --- a/drivers/firmware/arm_scmi/optee.c +++ b/drivers/firmware/arm_scmi/scmi_transport_optee.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -148,12 +149,11 @@ struct scmi_optee_agent { struct list_head channel_list; }; =20 +static struct scmi_transport_core_operations *core; + /* There can be only 1 SCMI service in OP-TEE we connect to */ static struct scmi_optee_agent *scmi_optee_private; =20 -/* Forward reference to scmi_optee transport initialization */ -static int scmi_optee_init(void); - /* Open a session toward SCMI OP-TEE service with REE_KERNEL identity */ static int open_session(struct scmi_optee_agent *agent, u32 *tee_session) { @@ -312,24 +312,6 @@ static int invoke_process_msg_channel(struct scmi_opte= e_channel *channel, size_t return 0; } =20 -static int scmi_optee_link_supplier(struct device *dev) -{ - if (!scmi_optee_private) { - if (scmi_optee_init()) - dev_dbg(dev, "Optee bus not yet ready\n"); - - /* Wait for optee bus */ - return -EPROBE_DEFER; - } - - if (!device_link_add(dev, scmi_optee_private->dev, DL_FLAG_AUTOREMOVE_CON= SUMER)) { - dev_err(dev, "Adding link to supplier optee device failed\n"); - return -ECANCELED; - } - - return 0; -} - static bool scmi_optee_chan_available(struct device_node *of_node, int idx) { u32 channel_id; @@ -343,7 +325,7 @@ static void scmi_optee_clear_channel(struct scmi_chan_i= nfo *cinfo) struct scmi_optee_channel *channel =3D cinfo->transport_info; =20 if (!channel->tee_shm) - scmi_shmem_ops.clear_channel(channel->req.shmem); + core->shmem->clear_channel(channel->req.shmem); } =20 static int setup_dynamic_shmem(struct device *dev, struct scmi_optee_chann= el *channel) @@ -368,7 +350,7 @@ static int setup_dynamic_shmem(struct device *dev, stru= ct scmi_optee_channel *ch static int setup_static_shmem(struct device *dev, struct scmi_chan_info *c= info, struct scmi_optee_channel *channel) { - channel->req.shmem =3D scmi_shmem_ops.setup_iomap(cinfo, dev, true, NULL); + channel->req.shmem =3D core->shmem->setup_iomap(cinfo, dev, true, NULL); if (IS_ERR(channel->req.shmem)) return PTR_ERR(channel->req.shmem); =20 @@ -479,10 +461,11 @@ static int scmi_optee_send_message(struct scmi_chan_i= nfo *cinfo, mutex_lock(&channel->mu); =20 if (channel->tee_shm) { - scmi_msg_ops.tx_prepare(channel->req.msg, xfer); - ret =3D invoke_process_msg_channel(channel, scmi_msg_ops.command_size(xf= er)); + core->msg->tx_prepare(channel->req.msg, xfer); + ret =3D invoke_process_msg_channel(channel, + core->msg->command_size(xfer)); } else { - scmi_shmem_ops.tx_prepare(channel->req.shmem, xfer, cinfo); + core->shmem->tx_prepare(channel->req.shmem, xfer, cinfo); ret =3D invoke_process_smt_channel(channel); } =20 @@ -498,9 +481,10 @@ static void scmi_optee_fetch_response(struct scmi_chan= _info *cinfo, struct scmi_optee_channel *channel =3D cinfo->transport_info; =20 if (channel->tee_shm) - scmi_msg_ops.fetch_response(channel->req.msg, channel->rx_len, xfer); + core->msg->fetch_response(channel->req.msg, + channel->rx_len, xfer); else - scmi_shmem_ops.fetch_response(channel->req.shmem, xfer); + core->shmem->fetch_response(channel->req.shmem, xfer); } =20 static void scmi_optee_mark_txdone(struct scmi_chan_info *cinfo, int ret, @@ -512,7 +496,6 @@ static void scmi_optee_mark_txdone(struct scmi_chan_inf= o *cinfo, int ret, } =20 static struct scmi_transport_ops scmi_optee_ops =3D { - .link_supplier =3D scmi_optee_link_supplier, .chan_available =3D scmi_optee_chan_available, .chan_setup =3D scmi_optee_chan_setup, .chan_free =3D scmi_optee_chan_free, @@ -527,6 +510,22 @@ static int scmi_optee_ctx_match(struct tee_ioctl_versi= on_data *ver, const void * return ver->impl_id =3D=3D TEE_IMPL_ID_OPTEE; } =20 +static const struct scmi_desc scmi_optee_desc =3D { + .ops =3D &scmi_optee_ops, + .max_rx_timeout_ms =3D 30, + .max_msg =3D 20, + .max_msg_size =3D SCMI_OPTEE_MAX_MSG_SIZE, + .sync_cmds_completed_on_ret =3D true, +}; + +static const struct of_device_id scmi_of_match[] =3D { + { .compatible =3D "linaro,scmi-optee" }, + { /* Sentinel */ }, +}; + +DEFINE_SCMI_TRANSPORT_DRIVER(scmi_optee, scmi_optee_driver, scmi_optee_des= c, + scmi_of_match, core); + static int scmi_optee_service_probe(struct device *dev) { struct scmi_optee_agent *agent; @@ -562,6 +561,12 @@ static int scmi_optee_service_probe(struct device *dev) smp_mb(); scmi_optee_private =3D agent; =20 + ret =3D platform_driver_register(&scmi_optee_driver); + if (ret) { + scmi_optee_private =3D NULL; + goto err; + } + return 0; =20 err: @@ -577,6 +582,8 @@ static int scmi_optee_service_remove(struct device *dev) if (!scmi_optee_private) return -EINVAL; =20 + platform_driver_unregister(&scmi_optee_driver); + if (!list_empty(&scmi_optee_private->channel_list)) return -EBUSY; =20 @@ -598,7 +605,7 @@ static const struct tee_client_device_id scmi_optee_ser= vice_id[] =3D { =20 MODULE_DEVICE_TABLE(tee, scmi_optee_service_id); =20 -static struct tee_client_driver scmi_optee_driver =3D { +static struct tee_client_driver scmi_optee_service_driver =3D { .id_table =3D scmi_optee_service_id, .driver =3D { .name =3D "scmi-optee", @@ -608,22 +615,19 @@ static struct tee_client_driver scmi_optee_driver =3D= { }, }; =20 -static int scmi_optee_init(void) +static int __init scmi_transport_optee_init(void) { - return driver_register(&scmi_optee_driver.driver); + return driver_register(&scmi_optee_service_driver.driver); } +module_init(scmi_transport_optee_init); =20 -static void scmi_optee_exit(void) +static void __exit scmi_transport_optee_exit(void) { - if (scmi_optee_private) - driver_unregister(&scmi_optee_driver.driver); + driver_unregister(&scmi_optee_service_driver.driver); } +module_exit(scmi_transport_optee_exit); =20 -const struct scmi_desc scmi_optee_desc =3D { - .transport_exit =3D scmi_optee_exit, - .ops =3D &scmi_optee_ops, - .max_rx_timeout_ms =3D 30, - .max_msg =3D 20, - .max_msg_size =3D SCMI_OPTEE_MAX_MSG_SIZE, - .sync_cmds_completed_on_ret =3D true, -}; +MODULE_ALIAS("scmi-transport-optee"); +MODULE_AUTHOR("Etienne Carriere "); +MODULE_DESCRIPTION("SCMI OPTEE Transport driver"); +MODULE_LICENSE("GPL"); --=20 2.45.2 From nobody Sun Feb 8 23:42:03 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id A24CB1A00FD; Tue, 30 Jul 2024 13:34:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722346448; cv=none; b=gdWFFc+HrR6uCsWfg4wgFLjdRJGCeC94SwDAhp5iQMnl5IMyPt6cBMKdbParirwx+gF6UXtlI8Wv/GMq4zQDFNlApNrNr4wbrg9g59li250r6HsmjX9zWIesMLnI2NoijLnaQsL97b4KdIf17JoPSkiEqBZjvI0Jz+8U+EljSvg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722346448; c=relaxed/simple; bh=UWJQCrdV/GdPQnUtO8PmOK9T3e3qRalptRxPDWHnIc0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=sFPBHRWV6OiYsgup0c8gzxegXEHA00mZxYGqu+NimIofSHpVO+USFWeTWTj9BstqPMlS9sL85F5rw7nBNK6OPZXP9W0wrVU+nriy+fKDhsYNhP3j0I0YKsviWnfYk3bHRQEMiZo4QHjnS1oe3+STH2PEFvEkNOW/h+MN6HMJv9E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com 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 9C8B4168F; Tue, 30 Jul 2024 06:34:31 -0700 (PDT) Received: from pluto.guestnet.cambridge.arm.com (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 026FC3F5A1; Tue, 30 Jul 2024 06:34:02 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, arm-scmi@vger.kernel.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, etienne.carriere@st.com, peng.fan@oss.nxp.com, michal.simek@amd.com, quic_sibis@quicinc.com, quic_nkela@quicinc.com, ptosi@google.com, dan.carpenter@linaro.org, souvik.chakravarty@arm.com, Cristian Marussi , "Michael S . Tsirkin" , Igor Skalkin , Peter Hilber Subject: [PATCH v3 8/9] firmware: arm_scmi: Make VirtIO transport a standalone driver Date: Tue, 30 Jul 2024 14:33:17 +0100 Message-ID: <20240730133318.1573765-9-cristian.marussi@arm.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240730133318.1573765-1-cristian.marussi@arm.com> References: <20240730133318.1573765-1-cristian.marussi@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Make SCMI VirtIO transport a standalone driver that can be optionally loaded as a module. CC: Michael S. Tsirkin CC: Igor Skalkin CC: Peter Hilber Signed-off-by: Cristian Marussi Tested-by: Florian Fainelli --- v2 --> v3 - fixed spacing in Kconfig and Copyright - use new params in DEFINE_SCMI_TRANSPORT_DRIVER v1 --> v2 - handle platform_driver_register() failures - make scmi_virtio_desc static | Reported-by: kernel test robot | Closes: https://lore.kernel.org/oe-kbuild-all/202407081344.9OceqFie-lkp@intel.com/ --- drivers/firmware/arm_scmi/Kconfig | 6 +- drivers/firmware/arm_scmi/Makefile | 2 +- drivers/firmware/arm_scmi/common.h | 3 - drivers/firmware/arm_scmi/driver.c | 3 - .../{virtio.c =3D> scmi_transport_virtio.c} | 102 +++++++++--------- 5 files changed, 59 insertions(+), 57 deletions(-) rename drivers/firmware/arm_scmi/{virtio.c =3D> scmi_transport_virtio.c} (= 94%) diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/= Kconfig index 5186794b0505..e2de7b3fabc2 100644 --- a/drivers/firmware/arm_scmi/Kconfig +++ b/drivers/firmware/arm_scmi/Kconfig @@ -132,8 +132,8 @@ config ARM_SCMI_TRANSPORT_SMC_ATOMIC_ENABLE primitives all over instead. If unsure say N. =20 config ARM_SCMI_TRANSPORT_VIRTIO - bool "SCMI transport based on VirtIO" - depends on VIRTIO=3Dy || VIRTIO=3DARM_SCMI_PROTOCOL + tristate "SCMI transport based on VirtIO" + depends on VIRTIO select ARM_SCMI_HAVE_TRANSPORT select ARM_SCMI_HAVE_MSG help @@ -141,6 +141,8 @@ config ARM_SCMI_TRANSPORT_VIRTIO =20 If you want the ARM SCMI PROTOCOL stack to include support for a transport based on VirtIO, answer Y. + This driver can also be built as a module. If so, the module + will be called scmi_transport_virtio. =20 config ARM_SCMI_TRANSPORT_VIRTIO_VERSION1_COMPLIANCE bool "SCMI VirtIO transport Version 1 compliance" diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi= /Makefile index b04119ce972f..846b4939258d 100644 --- a/drivers/firmware/arm_scmi/Makefile +++ b/drivers/firmware/arm_scmi/Makefile @@ -6,12 +6,12 @@ scmi-driver-y =3D driver.o notify.o scmi-driver-$(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT) +=3D raw_mode.o scmi-transport-$(CONFIG_ARM_SCMI_HAVE_SHMEM) =3D shmem.o scmi-transport-$(CONFIG_ARM_SCMI_HAVE_MSG) +=3D msg.o -scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) +=3D virtio.o scmi-protocols-y :=3D base.o clock.o perf.o power.o reset.o sensors.o syst= em.o voltage.o powercap.o scmi-protocols-y +=3D pinctrl.o scmi-module-objs :=3D $(scmi-driver-y) $(scmi-protocols-y) $(scmi-transpor= t-y) =20 obj-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) +=3D scmi_transport_smc.o +obj-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) +=3D scmi_transport_virtio.o obj-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) +=3D scmi_transport_mailbox.o obj-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) +=3D scmi_transport_optee.o =20 diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi= /common.h index 3ee775fca1d2..ddd0d35d9821 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -286,9 +286,6 @@ int scmi_xfer_raw_inflight_register(const struct scmi_h= andle *handle, int scmi_xfer_raw_wait_for_message_response(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer, unsigned int timeout_ms); -#ifdef CONFIG_ARM_SCMI_TRANSPORT_VIRTIO -extern const struct scmi_desc scmi_virtio_desc; -#endif =20 void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, void *pri= v); =20 diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi= /driver.c index e4fb1f75200f..498002025404 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -3251,9 +3251,6 @@ ATTRIBUTE_GROUPS(versions); =20 /* Each compatible listed below must have descriptor associated with it */ static const struct of_device_id scmi_of_match[] =3D { -#ifdef CONFIG_ARM_SCMI_TRANSPORT_VIRTIO - { .compatible =3D "arm,scmi-virtio", .data =3D &scmi_virtio_desc}, -#endif { /* Sentinel */ }, }; =20 diff --git a/drivers/firmware/arm_scmi/virtio.c b/drivers/firmware/arm_scmi= /scmi_transport_virtio.c similarity index 94% rename from drivers/firmware/arm_scmi/virtio.c rename to drivers/firmware/arm_scmi/scmi_transport_virtio.c index e8d38e822c7e..55d7245fa7ee 100644 --- a/drivers/firmware/arm_scmi/virtio.c +++ b/drivers/firmware/arm_scmi/scmi_transport_virtio.c @@ -4,7 +4,7 @@ * (SCMI). * * Copyright (C) 2020-2022 OpenSynergy. - * Copyright (C) 2021-2022 ARM Ltd. + * Copyright (C) 2021-2024 ARM Ltd. */ =20 /** @@ -19,6 +19,7 @@ =20 #include #include +#include #include #include #include @@ -108,6 +109,8 @@ struct scmi_vio_msg { refcount_t users; }; =20 +static struct scmi_transport_core_operations *core; + /* Only one SCMI VirtIO device can possibly exist */ static struct virtio_device *scmi_vdev; =20 @@ -294,8 +297,9 @@ static void scmi_vio_complete_cb(struct virtqueue *vque= ue) =20 if (msg) { msg->rx_len =3D length; - scmi_rx_callback(vioch->cinfo, - scmi_msg_ops.read_header(msg->input), msg); + core->rx_callback(vioch->cinfo, + core->msg->read_header(msg->input), + msg); =20 scmi_finalize_message(vioch, msg); } @@ -339,8 +343,9 @@ static void scmi_vio_deferred_tx_worker(struct work_str= uct *work) * is no more processed elsewhere so no poll_lock needed. */ if (msg->poll_status =3D=3D VIO_MSG_NOT_POLLED) - scmi_rx_callback(vioch->cinfo, - scmi_msg_ops.read_header(msg->input), msg); + core->rx_callback(vioch->cinfo, + core->msg->read_header(msg->input), + msg); =20 /* Free the processed message once done */ scmi_vio_msg_release(vioch, msg); @@ -366,23 +371,6 @@ static unsigned int virtio_get_max_msg(struct scmi_cha= n_info *base_cinfo) return vioch->max_msg; } =20 -static int virtio_link_supplier(struct device *dev) -{ - if (!scmi_vdev) { - dev_notice(dev, - "Deferring probe after not finding a bound scmi-virtio device\n"); - return -EPROBE_DEFER; - } - - if (!device_link_add(dev, &scmi_vdev->dev, - DL_FLAG_AUTOREMOVE_CONSUMER)) { - dev_err(dev, "Adding link to supplier virtio device failed\n"); - return -ECANCELED; - } - - return 0; -} - static bool virtio_chan_available(struct device_node *of_node, int idx) { struct scmi_vio_channel *channels, *vioch =3D NULL; @@ -510,10 +498,10 @@ static int virtio_send_message(struct scmi_chan_info = *cinfo, return -EBUSY; } =20 - scmi_msg_ops.tx_prepare(msg->request, xfer); + core->msg->tx_prepare(msg->request, xfer); =20 - sg_init_one(&sg_out, msg->request, scmi_msg_ops.command_size(xfer)); - sg_init_one(&sg_in, msg->input, scmi_msg_ops.response_size(xfer)); + sg_init_one(&sg_out, msg->request, core->msg->command_size(xfer)); + sg_init_one(&sg_in, msg->input, core->msg->response_size(xfer)); =20 spin_lock_irqsave(&vioch->lock, flags); =20 @@ -560,7 +548,7 @@ static void virtio_fetch_response(struct scmi_chan_info= *cinfo, struct scmi_vio_msg *msg =3D xfer->priv; =20 if (msg) - scmi_msg_ops.fetch_response(msg->input, msg->rx_len, xfer); + core->msg->fetch_response(msg->input, msg->rx_len, xfer); } =20 static void virtio_fetch_notification(struct scmi_chan_info *cinfo, @@ -569,7 +557,8 @@ static void virtio_fetch_notification(struct scmi_chan_= info *cinfo, struct scmi_vio_msg *msg =3D xfer->priv; =20 if (msg) - scmi_msg_ops.fetch_notification(msg->input, msg->rx_len, max_len, xfer); + core->msg->fetch_notification(msg->input, msg->rx_len, + max_len, xfer); } =20 /** @@ -669,7 +658,7 @@ static void virtio_mark_txdone(struct scmi_chan_info *c= info, int ret, * the message we are polling for could be alternatively delivered via usu= al * IRQs callbacks on another core which happened to have IRQs enabled whil= e we * are actively polling for it here: in such a case it will be handled as = such - * by scmi_rx_callback() and the polling loop in the SCMI Core TX path wil= l be + * by rx_callback() and the polling loop in the SCMI Core TX path will be * transparently terminated anyway. * * Return: True once polling has successfully completed. @@ -790,7 +779,6 @@ static bool virtio_poll_done(struct scmi_chan_info *cin= fo, } =20 static const struct scmi_transport_ops scmi_virtio_ops =3D { - .link_supplier =3D virtio_link_supplier, .chan_available =3D virtio_chan_available, .chan_setup =3D virtio_chan_setup, .chan_free =3D virtio_chan_free, @@ -802,6 +790,23 @@ static const struct scmi_transport_ops scmi_virtio_ops= =3D { .poll_done =3D virtio_poll_done, }; =20 +static const struct scmi_desc scmi_virtio_desc =3D { + .ops =3D &scmi_virtio_ops, + /* for non-realtime virtio devices */ + .max_rx_timeout_ms =3D VIRTIO_MAX_RX_TIMEOUT_MS, + .max_msg =3D 0, /* overridden by virtio_get_max_msg() */ + .max_msg_size =3D VIRTIO_SCMI_MAX_MSG_SIZE, + .atomic_enabled =3D IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO_ATOMIC_EN= ABLE), +}; + +static const struct of_device_id scmi_of_match[] =3D { + { .compatible =3D "arm,scmi-virtio" }, + { /* Sentinel */ }, +}; + +DEFINE_SCMI_TRANSPORT_DRIVER(scmi_virtio, scmi_virtio_driver, scmi_virtio_= desc, + scmi_of_match, core); + static int scmi_vio_probe(struct virtio_device *vdev) { struct device *dev =3D &vdev->dev; @@ -861,14 +866,27 @@ static int scmi_vio_probe(struct virtio_device *vdev) } =20 vdev->priv =3D channels; + /* Ensure initialized scmi_vdev is visible */ smp_store_mb(scmi_vdev, vdev); =20 + ret =3D platform_driver_register(&scmi_virtio_driver); + if (ret) { + vdev->priv =3D NULL; + vdev->config->del_vqs(vdev); + /* Ensure NULLified scmi_vdev is visible */ + smp_store_mb(scmi_vdev, NULL); + + return ret; + } + return 0; } =20 static void scmi_vio_remove(struct virtio_device *vdev) { + platform_driver_unregister(&scmi_virtio_driver); + /* * Once we get here, virtio_chan_free() will have already been called by * the SCMI core for any existing channel and, as a consequence, all the @@ -913,23 +931,11 @@ static struct virtio_driver virtio_scmi_driver =3D { .validate =3D scmi_vio_validate, }; =20 -static int __init virtio_scmi_init(void) -{ - return register_virtio_driver(&virtio_scmi_driver); -} - -static void virtio_scmi_exit(void) -{ - unregister_virtio_driver(&virtio_scmi_driver); -} +module_virtio_driver(virtio_scmi_driver); =20 -const struct scmi_desc scmi_virtio_desc =3D { - .transport_init =3D virtio_scmi_init, - .transport_exit =3D virtio_scmi_exit, - .ops =3D &scmi_virtio_ops, - /* for non-realtime virtio devices */ - .max_rx_timeout_ms =3D VIRTIO_MAX_RX_TIMEOUT_MS, - .max_msg =3D 0, /* overridden by virtio_get_max_msg() */ - .max_msg_size =3D VIRTIO_SCMI_MAX_MSG_SIZE, - .atomic_enabled =3D IS_ENABLED(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO_ATOMIC_EN= ABLE), -}; +MODULE_ALIAS("scmi-transport-virtio"); +MODULE_AUTHOR("Igor Skalkin "); +MODULE_AUTHOR("Peter Hilber "); +MODULE_AUTHOR("Cristian Marussi "); +MODULE_DESCRIPTION("SCMI VirtIO Transport driver"); +MODULE_LICENSE("GPL"); --=20 2.45.2 From nobody Sun Feb 8 23:42:03 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 4E77B1A0B14; Tue, 30 Jul 2024 13:34:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722346451; cv=none; b=S2MGePExMXDgVHyeAf9XbFXofiyLhC8MUD2GRB2l1hUBKK+6INJoCpMy8L/JseUkeIHbw2PU6t5g9mqjWCCIrwpPlmiM0yAh0+POCzO7gI58UtpPOjh1JYN/WLWkmKPMNDxgcgl6ZpVYkR1K6m8XMQSt1Ma7RJaRxvtTPK8VpDg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1722346451; c=relaxed/simple; bh=XJWrHl8dLD0J8MCN0Wvlcti3ru1RIqTvE4d3w6fbDEU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YSuUqrfSposuHYxdkoW0rqPguanWbdCBYS4wWjD/aILHCofOZGfz37++pVovv9UOFWSBO8W4bLnUh5PPq5i1636DmjKBh/LTj+1S1kRcsp7IVhLtG6IU+gq5Frv6blVFEKdZ4oAHgFVxRtyg0Y4v62KAuXW/XzgS/I0MZHU/vRU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com 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 65EC11515; Tue, 30 Jul 2024 06:34:34 -0700 (PDT) Received: from pluto.guestnet.cambridge.arm.com (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 533133F5A1; Tue, 30 Jul 2024 06:34:06 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, arm-scmi@vger.kernel.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, etienne.carriere@st.com, peng.fan@oss.nxp.com, michal.simek@amd.com, quic_sibis@quicinc.com, quic_nkela@quicinc.com, ptosi@google.com, dan.carpenter@linaro.org, souvik.chakravarty@arm.com, Cristian Marussi Subject: [PATCH v3 9/9] firmware: arm_scmi: Remove legacy transport-layer code Date: Tue, 30 Jul 2024 14:33:18 +0100 Message-ID: <20240730133318.1573765-10-cristian.marussi@arm.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240730133318.1573765-1-cristian.marussi@arm.com> References: <20240730133318.1573765-1-cristian.marussi@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Since all SCMI transports have been made standalone drivers, remove all the core SCMI stack legacy support that was needed to run transports as built into the stack. Signed-off-by: Cristian Marussi Tested-by: Florian Fainelli --- v2 --> v3 - updated Copyright --- drivers/firmware/arm_scmi/common.h | 18 ------ drivers/firmware/arm_scmi/driver.c | 98 +++++------------------------- drivers/firmware/arm_scmi/msg.c | 2 +- drivers/firmware/arm_scmi/shmem.c | 2 +- 4 files changed, 16 insertions(+), 104 deletions(-) diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi= /common.h index ddd0d35d9821..77721cb4ac34 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -183,7 +183,6 @@ struct scmi_chan_info { /** * struct scmi_transport_ops - Structure representing a SCMI transport ops * - * @link_supplier: Optional callback to add link to a supplier device * @chan_available: Callback to check if channel is available or not * @chan_setup: Callback to allocate and setup a channel * @chan_free: Callback to free a channel @@ -198,7 +197,6 @@ struct scmi_chan_info { * @poll_done: Callback to poll transfer status */ struct scmi_transport_ops { - int (*link_supplier)(struct device *dev); bool (*chan_available)(struct device_node *of_node, int idx); int (*chan_setup)(struct scmi_chan_info *cinfo, struct device *dev, bool tx); @@ -219,12 +217,6 @@ struct scmi_transport_ops { /** * struct scmi_desc - Description of SoC integration * - * @transport_init: An optional function that a transport can provide to - * initialize some transport-specific setup during SCMI core - * initialization, so ahead of SCMI core probing. - * @transport_exit: An optional function that a transport can provide to - * de-initialize some transport-specific setup during SCMI core - * de-initialization, so after SCMI core removal. * @ops: Pointer to the transport specific ops structure * @max_rx_timeout_ms: Timeout for communication with SoC (in Milliseconds) * @max_msg: Maximum number of messages for a channel type (tx or rx) that= can @@ -245,8 +237,6 @@ struct scmi_transport_ops { * when requested. */ struct scmi_desc { - int (*transport_init)(void); - void (*transport_exit)(void); const struct scmi_transport_ops *ops; int max_rx_timeout_ms; int max_msg; @@ -287,8 +277,6 @@ int scmi_xfer_raw_wait_for_message_response(struct scmi= _chan_info *cinfo, struct scmi_xfer *xfer, unsigned int timeout_ms); =20 -void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, void *pri= v); - enum scmi_bad_msg { MSG_UNEXPECTED =3D -1, MSG_INVALID =3D -2, @@ -297,9 +285,6 @@ enum scmi_bad_msg { MSG_MBOX_SPURIOUS =3D -5, }; =20 -void scmi_bad_message_trace(struct scmi_chan_info *cinfo, u32 msg_hdr, - enum scmi_bad_msg err); - /* shmem related declarations */ struct scmi_shared_mem; =20 @@ -448,9 +433,6 @@ static struct platform_driver __drv =3D { \ .probe =3D __tag##_probe, \ } =20 -extern const struct scmi_shared_mem_operations scmi_shmem_ops; -extern const struct scmi_message_operations scmi_msg_ops; - void scmi_notification_instance_data_set(const struct scmi_handle *handle, void *priv); void *scmi_notification_instance_data_get(const struct scmi_handle *handle= ); diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi= /driver.c index 498002025404..332cd5207bbc 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -11,7 +11,7 @@ * various power domain DVFS including the core/cluster, certain system * clocks configuration, thermal sensors and many others. * - * Copyright (C) 2018-2021 ARM Ltd. + * Copyright (C) 2018-2024 ARM Ltd. */ =20 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -194,6 +194,11 @@ struct scmi_info { #define bus_nb_to_scmi_info(nb) container_of(nb, struct scmi_info, bus_nb) #define req_nb_to_scmi_info(nb) container_of(nb, struct scmi_info, dev_req= _nb) =20 +static void scmi_rx_callback(struct scmi_chan_info *cinfo, + u32 msg_hdr, void *priv); +static void scmi_bad_message_trace(struct scmi_chan_info *cinfo, + u32 msg_hdr, enum scmi_bad_msg err); + static struct scmi_transport_core_operations scmi_trans_core_ops =3D { .bad_message_trace =3D scmi_bad_message_trace, .rx_callback =3D scmi_rx_callback, @@ -838,8 +843,8 @@ scmi_xfer_lookup_unlocked(struct scmi_xfers_info *minfo= , u16 xfer_id) * timed-out message that arrives and as such, can be traced only referrin= g to * the header content, since the payload is missing/unreliable. */ -void scmi_bad_message_trace(struct scmi_chan_info *cinfo, u32 msg_hdr, - enum scmi_bad_msg err) +static void scmi_bad_message_trace(struct scmi_chan_info *cinfo, u32 msg_h= dr, + enum scmi_bad_msg err) { char *tag; struct scmi_info *info =3D handle_to_scmi_info(cinfo->handle); @@ -1165,7 +1170,8 @@ static void scmi_handle_response(struct scmi_chan_inf= o *cinfo, * NOTE: This function will be invoked in IRQ context, hence should be * as optimal as possible. */ -void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, void *pri= v) +static void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr, + void *priv) { u8 msg_type =3D MSG_XTRACT_TYPE(msg_hdr); =20 @@ -2988,14 +2994,11 @@ static int scmi_probe(struct platform_device *pdev) struct device *dev =3D &pdev->dev; struct device_node *child, *np =3D dev->of_node; =20 - desc =3D of_device_get_match_data(dev); + desc =3D scmi_transport_setup(dev); if (!desc) { - desc =3D scmi_transport_setup(dev); - if (!desc) { - err_str =3D "transport invalid\n"; - ret =3D -EINVAL; - goto out_err; - } + err_str =3D "transport invalid\n"; + ret =3D -EINVAL; + goto out_err; } =20 info =3D devm_kzalloc(dev, sizeof(*info), GFP_KERNEL); @@ -3035,14 +3038,6 @@ static int scmi_probe(struct platform_device *pdev) info->atomic_threshold); handle->is_transport_atomic =3D scmi_is_transport_atomic; =20 - if (desc->ops->link_supplier) { - ret =3D desc->ops->link_supplier(dev); - if (ret) { - err_str =3D "transport not ready\n"; - goto clear_ida; - } - } - /* Setup all channels described in the DT at first */ ret =3D scmi_channels_setup(info); if (ret) { @@ -3249,72 +3244,16 @@ static struct attribute *versions_attrs[] =3D { }; ATTRIBUTE_GROUPS(versions); =20 -/* Each compatible listed below must have descriptor associated with it */ -static const struct of_device_id scmi_of_match[] =3D { - { /* Sentinel */ }, -}; - -MODULE_DEVICE_TABLE(of, scmi_of_match); - static struct platform_driver scmi_driver =3D { .driver =3D { .name =3D "arm-scmi", .suppress_bind_attrs =3D true, - .of_match_table =3D scmi_of_match, .dev_groups =3D versions_groups, }, .probe =3D scmi_probe, .remove_new =3D scmi_remove, }; =20 -/** - * __scmi_transports_setup - Common helper to call transport-specific - * .init/.exit code if provided. - * - * @init: A flag to distinguish between init and exit. - * - * Note that, if provided, we invoke .init/.exit functions for all the - * transports currently compiled in. - * - * Return: 0 on Success. - */ -static inline int __scmi_transports_setup(bool init) -{ - int ret =3D 0; - const struct of_device_id *trans; - - for (trans =3D scmi_of_match; trans->data; trans++) { - const struct scmi_desc *tdesc =3D trans->data; - - if ((init && !tdesc->transport_init) || - (!init && !tdesc->transport_exit)) - continue; - - if (init) - ret =3D tdesc->transport_init(); - else - tdesc->transport_exit(); - - if (ret) { - pr_err("SCMI transport %s FAILED initialization!\n", - trans->compatible); - break; - } - } - - return ret; -} - -static int __init scmi_transports_init(void) -{ - return __scmi_transports_setup(true); -} - -static void __exit scmi_transports_exit(void) -{ - __scmi_transports_setup(false); -} - static struct dentry *scmi_debugfs_init(void) { struct dentry *d; @@ -3330,17 +3269,10 @@ static struct dentry *scmi_debugfs_init(void) =20 static int __init scmi_driver_init(void) { - int ret; - /* Bail out if no SCMI transport was configured */ if (WARN_ON(!IS_ENABLED(CONFIG_ARM_SCMI_HAVE_TRANSPORT))) return -EINVAL; =20 - /* Initialize any compiled-in transport which provided an init/exit */ - ret =3D scmi_transports_init(); - if (ret) - return ret; - if (IS_ENABLED(CONFIG_ARM_SCMI_HAVE_SHMEM)) scmi_trans_core_ops.shmem =3D scmi_shared_mem_operations_get(); =20 @@ -3380,8 +3312,6 @@ static void __exit scmi_driver_exit(void) scmi_powercap_unregister(); scmi_pinctrl_unregister(); =20 - scmi_transports_exit(); - platform_driver_unregister(&scmi_driver); =20 debugfs_remove_recursive(scmi_top_dentry); diff --git a/drivers/firmware/arm_scmi/msg.c b/drivers/firmware/arm_scmi/ms= g.c index 18337f9191d0..2cc74e6bbd72 100644 --- a/drivers/firmware/arm_scmi/msg.c +++ b/drivers/firmware/arm_scmi/msg.c @@ -110,7 +110,7 @@ static void msg_fetch_notification(struct scmi_msg_payl= d *msg, size_t len, memcpy(xfer->rx.buf, msg->msg_payload, xfer->rx.len); } =20 -const struct scmi_message_operations scmi_msg_ops =3D { +static const struct scmi_message_operations scmi_msg_ops =3D { .tx_prepare =3D msg_tx_prepare, .command_size =3D msg_command_size, .response_size =3D msg_response_size, diff --git a/drivers/firmware/arm_scmi/shmem.c b/drivers/firmware/arm_scmi/= shmem.c index 3fba05e1560c..01d8a9398fe8 100644 --- a/drivers/firmware/arm_scmi/shmem.c +++ b/drivers/firmware/arm_scmi/shmem.c @@ -176,7 +176,7 @@ static void __iomem *shmem_setup_iomap(struct scmi_chan= _info *cinfo, return addr; } =20 -const struct scmi_shared_mem_operations scmi_shmem_ops =3D { +static const struct scmi_shared_mem_operations scmi_shmem_ops =3D { .tx_prepare =3D shmem_tx_prepare, .read_header =3D shmem_read_header, .fetch_response =3D shmem_fetch_response, --=20 2.45.2