From patchwork Sun Jul 7 00:20:50 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 13725935 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A9B50C38150 for ; Sun, 7 Jul 2024 00:22:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=3PcC+lBaVAiqeAnxfBDywG7tGgQvJFLJGJof9yMISdY=; b=1iR7C3yajKhww5nu2Y3qAMZ3jL 7cIyfxuwfwARuKY6hgDsNYBjR/nHm8VANoeV8KRnRWEJBEC9up9rOS3wmV+dtWjzvV7kw8WLlQEct 3LvghQjgsiFqI5Id7a13tSTyqNLazp19C2yU+M9U7rReufQ+/UtLwA8M6cRU9LrsZpYcm/AVn9bwG R4g5CyekBreW49WqaKB+GAM1drmnidE0YK4Hxp6+kdlzi3HwQjNSZIxgC9j/+dsIAdWqeQ/u6Cqdn hUBL117COnoYnNrGBVushhD1pER6irh0exKOK2yuUtL4g3MwG1MYggD5Pbf0/O9mSBhtcmdgt8uJY njcJs1eg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sQFfi-000000018V4-0dOC; Sun, 07 Jul 2024 00:22:30 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sQFev-000000018Bo-0ilL for linux-arm-kernel@lists.infradead.org; Sun, 07 Jul 2024 00:21:42 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id AA099DA7; Sat, 6 Jul 2024 17:22:05 -0700 (PDT) Received: from pluto.. (usa-sjc-mx-foss1.foss.arm.com [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 694D63F73B; Sat, 6 Jul 2024 17:21:38 -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@foss.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 3/8] firmware: arm_scmi: Add support for standalone transport drivers Date: Sun, 7 Jul 2024 01:20:50 +0100 Message-ID: <20240707002055.1835121-4-cristian.marussi@arm.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240707002055.1835121-1-cristian.marussi@arm.com> References: <20240707002055.1835121-1-cristian.marussi@arm.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240706_172141_338234_4C357F8C X-CRM114-Status: GOOD ( 20.83 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org 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 --- Old style transport support will be removed later in this series. --- 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 34df078d1cd3..fda6f96b6750 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -348,6 +348,8 @@ struct scmi_shared_mem_operations { struct device *dev, bool tx); }; +const struct scmi_shared_mem_operations *scmi_shared_mem_operations_get(void); + /* declarations for message passing transports */ struct scmi_msg_payld; @@ -375,6 +377,88 @@ struct scmi_message_operations { size_t max_len, struct scmi_xfer *xfer); }; +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 representimng the transport and acting as a supplier for + * the core SCMI stack + * @desc: Transport descriptor + * @core_ops: A pointer to a pointer used by the core SCMI stack to make the + * 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(__trans, __match_table, __core_ptr)\ +static int __trans##_probe(struct platform_device *pdev) \ +{ \ + struct scmi_transport *scmi_trans; \ + struct platform_device *scmi_pdev; \ + struct device *dev = &pdev->dev; \ + \ + scmi_trans = devm_kzalloc(dev, sizeof(*scmi_trans), GFP_KERNEL);\ + if (!scmi_trans) \ + return -ENOMEM; \ + \ + scmi_pdev = devm_kzalloc(dev, sizeof(*scmi_pdev), GFP_KERNEL); \ + if (!scmi_pdev) \ + return -ENOMEM; \ + \ + scmi_trans->supplier = dev; \ + scmi_trans->desc = &__trans##_desc; \ + scmi_trans->core_ops = __core_ptr; \ + \ + scmi_pdev->name = "arm-scmi"; \ + scmi_pdev->id = PLATFORM_DEVID_AUTO; \ + scmi_pdev->dev.platform_data = scmi_trans; \ + \ + device_set_of_node_from_dev(&scmi_pdev->dev, dev); \ + \ + dev_set_drvdata(dev, scmi_pdev); \ + \ + return platform_device_register(scmi_pdev); \ +} \ + \ +static void __trans##_remove(struct platform_device *pdev) \ +{ \ + struct platform_device *scmi_pdev; \ + \ + scmi_pdev = dev_get_drvdata(&pdev->dev); \ + \ + platform_device_unregister(scmi_pdev); \ +} \ + \ +static struct platform_driver __trans##_driver = { \ + .driver = { \ + .name = #__trans "_transport", \ + .of_match_table = __match_table, \ + }, \ + .probe = __trans##_probe, \ + .remove_new = __trans##_remove, \ +} + extern const struct scmi_shared_mem_operations scmi_shmem_ops; extern const struct scmi_message_operations scmi_msg_ops; diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 6b6957f4743f..a1892d4d8c69 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) +static struct scmi_transport_core_operations scmi_trans_core_ops = { + .bad_message_trace = scmi_bad_message_trace, + .rx_callback = 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_info *info) return ret; } +static const struct scmi_desc *scmi_transport_lookup(struct device *dev) +{ + struct scmi_transport *trans; + + trans = 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 = &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 = dev->of_node; desc = of_device_get_match_data(dev); - if (!desc) - return -EINVAL; + if (!desc) { + desc = scmi_transport_lookup(dev); + if (!desc) { + err_str = "transport invalid\n"; + ret = -EINVAL; + goto out_err; + } + } info = 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); +out_err: return dev_err_probe(dev, ret, "%s", err_str); } @@ -3321,6 +3355,12 @@ static int __init scmi_driver_init(void) if (ret) return ret; + if (IS_ENABLED(CONFIG_ARM_SCMI_HAVE_SHMEM)) + scmi_trans_core_ops.shmem = scmi_shared_mem_operations_get(); + + if (IS_ENABLED(CONFIG_ARM_SCMI_HAVE_MSG)) + scmi_trans_core_ops.msg = scmi_message_operations_get(); + if (IS_ENABLED(CONFIG_ARM_SCMI_NEED_DEBUGFS)) scmi_top_dentry = scmi_debugfs_init(); diff --git a/drivers/firmware/arm_scmi/msg.c b/drivers/firmware/arm_scmi/msg.c index f4ba38afe0bb..0bed1d2825af 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 = { .fetch_response = msg_fetch_response, .fetch_notification = 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 c84321ff5428..feb4215831dc 100644 --- a/drivers/firmware/arm_scmi/shmem.c +++ b/drivers/firmware/arm_scmi/shmem.c @@ -182,3 +182,8 @@ const struct scmi_shared_mem_operations scmi_shmem_ops = { .channel_intr_enabled = shmem_channel_intr_enabled, .setup_iomap = shmem_setup_iomap, }; + +const struct scmi_shared_mem_operations *scmi_shared_mem_operations_get(void) +{ + return &scmi_shmem_ops; +}