From patchwork Wed Oct 19 20:46:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 5838 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp528201wrs; Wed, 19 Oct 2022 13:50:13 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4qWS7Ph0NV4BuwO7T4w5jTDSPu4SGsrnVMbrPEh2Ud2K94JIFOj6u6DWtMxkR+u4jn8kFK X-Received: by 2002:a05:6a00:3406:b0:55c:e661:6d31 with SMTP id cn6-20020a056a00340600b0055ce6616d31mr10338901pfb.42.1666212613216; Wed, 19 Oct 2022 13:50:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666212613; cv=none; d=google.com; s=arc-20160816; b=nTUPRfxgExclx0HT1JJVl++pSCen9BLUX7Cv5EZl/L7eY8o9Oh+h6JPiO/g0C8LLNG NC8M8GGazj0SrWl9CzNjM5H89UNC1+LpCOVW55sBtrggH3rr/b7wzc7/QkrtIfHsqbn9 pGeqJQAKhf9qvpPjiL1qUhNJq+iq+6tMqEXGh/9nUfkAot70ffuxRw+FVzDD4zKFLUll Z7hxn98KBSkn+bOkkvGwnze8OZR+0HiagYmYdIPvqWER6t7OiR+oLdBsj/2ArUtW65Df cZkkB8U+GRsQGlzKisr8iJAwLCgsZm4hhUqUdKKzecf5ofFJ7IgOdyxwoBXSaacI7Ydr DdyA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=eHbgsYBY6z5vFFAspd3x4418pi+3pUGiv0cvV8WPVWY=; b=svjg7apM8UeNzAHT4b3TrLy/CH39m/b4gcC0amvpAKyX+QQY3EyqMQXYH9NuiplY33 8byZOE0kmEtQkUM4nZRchMnvuG9IFcucqB8hmweWxljfLGj7nCMG1Hud0u5Flf8YP4gI wfDjNcOx0nPNRzXtBkxJ9ydiq56ykeJ71AtnxUF2d9X5sb4yTuqIwqUehXR0CwyCjPBz xAt2KRO3Maz/zvpOt11Ijmgxwos8FUleN9JZJzAr7wPWcJ+hzUWyWSi4GSzIK5fOmP7j A9YAcd+s8jALbiH60/btODrc6MPhbCCcagOCwY8sq8LPB5rLXBBBJDKftVm30lpZw0NM U7Mw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id o14-20020a635a0e000000b0042ad04f3686si19181650pgb.616.2022.10.19.13.49.59; Wed, 19 Oct 2022 13:50:13 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231325AbiJSUqr (ORCPT + 99 others); Wed, 19 Oct 2022 16:46:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37300 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231215AbiJSUqp (ORCPT ); Wed, 19 Oct 2022 16:46:45 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 24F1D1BBEC3 for ; Wed, 19 Oct 2022 13:46:44 -0700 (PDT) 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 25D6714BF; Wed, 19 Oct 2022 13:46:50 -0700 (PDT) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id EE3C83F792; Wed, 19 Oct 2022 13:46:41 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, etienne.carriere@linaro.org, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, wleavitt@marvell.com, peter.hilber@opensynergy.com, nicola.mazzucato@arm.com, tarek.el-sherbiny@arm.com, quic_kshivnan@quicinc.com, cristian.marussi@arm.com Subject: [PATCH v4 01/11] firmware: arm_scmi: Refactor xfer in-flight registration routines Date: Wed, 19 Oct 2022 21:46:16 +0100 Message-Id: <20221019204626.3813043-2-cristian.marussi@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221019204626.3813043-1-cristian.marussi@arm.com> References: <20221019204626.3813043-1-cristian.marussi@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW, SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747150557237383660?= X-GMAIL-MSGID: =?utf-8?q?1747150557237383660?= Move the whole xfer in-flight registration process out of scmi_xfer_get and while at that, split the sequence number selection steps from the in-flight registration procedure itself. No functional change. Signed-off-by: Cristian Marussi --- drivers/firmware/arm_scmi/driver.c | 102 +++++++++++++++++++---------- 1 file changed, 68 insertions(+), 34 deletions(-) diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 609ebedee9cb..e5193da2ce09 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -311,8 +311,6 @@ static int scmi_xfer_token_set(struct scmi_xfers_info *minfo, if (xfer_id != next_token) atomic_add((int)(xfer_id - next_token), &transfer_last_id); - /* Set in-flight */ - set_bit(xfer_id, minfo->xfer_alloc_table); xfer->hdr.seq = (u16)xfer_id; return 0; @@ -330,33 +328,77 @@ static inline void scmi_xfer_token_clear(struct scmi_xfers_info *minfo, clear_bit(xfer->hdr.seq, minfo->xfer_alloc_table); } +/** + * scmi_xfer_inflight_register_unlocked - Register the xfer as in-flight + * + * @xfer: The xfer to register + * @minfo: Pointer to Tx/Rx Message management info based on channel type + * + * Note that this helper assumes that the xfer to be registered as in-flight + * had been built using an xfer sequence number which still corresponds to a + * free slot in the xfer_alloc_table. + * + * Context: Assumes to be called with @xfer_lock already acquired. + */ +static inline void +scmi_xfer_inflight_register_unlocked(struct scmi_xfer *xfer, + struct scmi_xfers_info *minfo) +{ + /* Set in-flight */ + set_bit(xfer->hdr.seq, minfo->xfer_alloc_table); + hash_add(minfo->pending_xfers, &xfer->node, xfer->hdr.seq); + xfer->pending = true; +} + +/** + * scmi_xfer_pending_set - Pick a proper sequence number and mark the xfer + * as pending in-flight + * + * @xfer: The xfer to act upon + * @minfo: Pointer to Tx/Rx Message management info based on channel type + * + * Return: 0 on Success or error otherwise + */ +static inline int scmi_xfer_pending_set(struct scmi_xfer *xfer, + struct scmi_xfers_info *minfo) +{ + int ret; + unsigned long flags; + + spin_lock_irqsave(&minfo->xfer_lock, flags); + /* Set a new monotonic token as the xfer sequence number */ + ret = scmi_xfer_token_set(minfo, xfer); + if (!ret) + scmi_xfer_inflight_register_unlocked(xfer, minfo); + spin_unlock_irqrestore(&minfo->xfer_lock, flags); + + return ret; +} + /** * scmi_xfer_get() - Allocate one message * * @handle: Pointer to SCMI entity handle * @minfo: Pointer to Tx/Rx Message management info based on channel type - * @set_pending: If true a monotonic token is picked and the xfer is added to - * the pending hash table. * * Helper function which is used by various message functions that are * exposed to clients of this driver for allocating a message traffic event. * - * Picks an xfer from the free list @free_xfers (if any available) and, if - * required, sets a monotonically increasing token and stores the inflight xfer - * into the @pending_xfers hashtable for later retrieval. + * Picks an xfer from the free list @free_xfers (if any available) and perform + * a basic initialization. + * + * Note that, at this point, still no sequence number is assigned to the + * allocated xfer, nor it is registered as a pending transaction. * * The successfully initialized xfer is refcounted. * - * Context: Holds @xfer_lock while manipulating @xfer_alloc_table and - * @free_xfers. + * Context: Holds @xfer_lock while manipulating @free_xfers. * - * Return: 0 if all went fine, else corresponding error. + * Return: An initialized xfer if all went fine, else pointer error. */ static struct scmi_xfer *scmi_xfer_get(const struct scmi_handle *handle, - struct scmi_xfers_info *minfo, - bool set_pending) + struct scmi_xfers_info *minfo) { - int ret; unsigned long flags; struct scmi_xfer *xfer; @@ -376,25 +418,8 @@ static struct scmi_xfer *scmi_xfer_get(const struct scmi_handle *handle, */ xfer->transfer_id = atomic_inc_return(&transfer_last_id); - if (set_pending) { - /* Pick and set monotonic token */ - ret = scmi_xfer_token_set(minfo, xfer); - if (!ret) { - hash_add(minfo->pending_xfers, &xfer->node, - xfer->hdr.seq); - xfer->pending = true; - } else { - dev_err(handle->dev, - "Failed to get monotonic token %d\n", ret); - hlist_add_head(&xfer->node, &minfo->free_xfers); - xfer = ERR_PTR(ret); - } - } - - if (!IS_ERR(xfer)) { - refcount_set(&xfer->users, 1); - atomic_set(&xfer->busy, SCMI_XFER_FREE); - } + refcount_set(&xfer->users, 1); + atomic_set(&xfer->busy, SCMI_XFER_FREE); spin_unlock_irqrestore(&minfo->xfer_lock, flags); return xfer; @@ -652,7 +677,7 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo, ktime_t ts; ts = ktime_get_boottime(); - xfer = scmi_xfer_get(cinfo->handle, minfo, false); + xfer = scmi_xfer_get(cinfo->handle, minfo); if (IS_ERR(xfer)) { dev_err(dev, "failed to get free message slot (%ld)\n", PTR_ERR(xfer)); @@ -1041,13 +1066,22 @@ static int xfer_get_init(const struct scmi_protocol_handle *ph, tx_size > info->desc->max_msg_size) return -ERANGE; - xfer = scmi_xfer_get(pi->handle, minfo, true); + xfer = scmi_xfer_get(pi->handle, minfo); if (IS_ERR(xfer)) { ret = PTR_ERR(xfer); dev_err(dev, "failed to get free message slot(%d)\n", ret); return ret; } + /* Pick a sequence number and register this xfer as in-flight */ + ret = scmi_xfer_pending_set(xfer, minfo); + if (ret) { + dev_err(pi->handle->dev, + "Failed to get monotonic token %d\n", ret); + __scmi_xfer_put(minfo, xfer); + return ret; + } + xfer->tx.len = tx_size; xfer->rx.len = rx_size ? : info->desc->max_msg_size; xfer->hdr.type = MSG_TYPE_COMMAND; From patchwork Wed Oct 19 20:46:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 5846 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp529245wrs; Wed, 19 Oct 2022 13:53:18 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6KXK8RVY3p7qOgZbwnQplA3/GiA3mtPzcabM5Q2M/G/9BMN72SVOSJqp1LTJv9q2HbV760 X-Received: by 2002:a17:907:97cc:b0:797:c389:de5f with SMTP id js12-20020a17090797cc00b00797c389de5fmr60908ejc.627.1666212798104; Wed, 19 Oct 2022 13:53:18 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666212798; cv=none; d=google.com; s=arc-20160816; b=FG3xVfqyHoDNVt6ICtVa5YtFOTAURXKPa7miLHnTJoz72p1m4k4apS1htNJDOxCeI+ CvwmiffK99RoONlRASMsOWooCuAh1L/fOSm0Ja9UkjR8GEX26cIMmhMi/e/huQ9jlht9 qy02opy5H/7nd8XA/o/VxxmREFsLuxslUb2C8meXInvuQtx95yj6nBnZrf/53SOLvfni GnwEEygRxtE3ReD+E3O7FV+XgSEd1B6GztXHyfIZ4ZOR49LiL8VzIY3NnC5kYrhpEzCB 0eDAKRwOPOx35BI35us2DnEr2XsTRCJ0H3V7rfP10NYYTs+zCDqe4eazy8CdZ5yYGAhS Y0yQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=zsfNYEQ7duIKip7HOhg1qLOzTdQ2B9hbSGAt8g/33x0=; b=XmjQOQ1SYtSE3Wxg3AnOIvoGtExUFXqBeTXxUPTLdkuwoTOEjyTYG+OaN3mzEksSIK WDtafIKGZDPAFWjlQSiRETPXPxqAXfspM2RaiGULxRzDyMZuk7RtPUBZNGEZfK0PBSj6 AIosSWCkHx6a1e8JqKasd74cu3Ood6akOihqj1lPE23vQdugTHvR+wdZD7qF00LvHJ8R qJ9lPhm0LF96SjyV0UYxdj77Ci4qpPYEHd1CXiHuTZeJZ+J8UQX56BOJhIPU7v4zlo1R aym1Ya04XxhJ/zvs08BweLpxwia3+vb7lSN1a3VQhzjSq2ySVNkS9eKkdUg6UqWKiXu1 eQjQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id h13-20020a05640250cd00b0045c3f5b458fsi17484618edb.397.2022.10.19.13.52.53; Wed, 19 Oct 2022 13:53:18 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231394AbiJSUq7 (ORCPT + 99 others); Wed, 19 Oct 2022 16:46:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37340 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231343AbiJSUqs (ORCPT ); Wed, 19 Oct 2022 16:46:48 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 735C81BBEE1 for ; Wed, 19 Oct 2022 13:46:46 -0700 (PDT) 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 542031A25; Wed, 19 Oct 2022 13:46:52 -0700 (PDT) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 285ED3F792; Wed, 19 Oct 2022 13:46:44 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, etienne.carriere@linaro.org, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, wleavitt@marvell.com, peter.hilber@opensynergy.com, nicola.mazzucato@arm.com, tarek.el-sherbiny@arm.com, quic_kshivnan@quicinc.com, cristian.marussi@arm.com Subject: [PATCH v4 02/11] firmware: arm_scmi: Simplify chan_available transport operation Date: Wed, 19 Oct 2022 21:46:17 +0100 Message-Id: <20221019204626.3813043-3-cristian.marussi@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221019204626.3813043-1-cristian.marussi@arm.com> References: <20221019204626.3813043-1-cristian.marussi@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW, SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747150751347226797?= X-GMAIL-MSGID: =?utf-8?q?1747150751347226797?= SCMI transport operation .chan_available determines in a transport-specific way if an SCMI channel is still available and to be configured: such information is derived analyzing bits of DT in a transport specific way; all it needs is a DT node to operate upon, not necessarily a full blown device. Simplify the helper to receive in input a reference to a device_node instead of a device carrying a pointer to such device_node. Signed-off-by: Cristian Marussi --- v3 --> v4 - fixes in commmit message --- drivers/firmware/arm_scmi/common.h | 2 +- drivers/firmware/arm_scmi/driver.c | 2 +- drivers/firmware/arm_scmi/mailbox.c | 4 ++-- drivers/firmware/arm_scmi/optee.c | 4 ++-- drivers/firmware/arm_scmi/smc.c | 4 ++-- drivers/firmware/arm_scmi/virtio.c | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h index 61aba7447c32..096b66442d84 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -150,7 +150,7 @@ struct scmi_chan_info { */ struct scmi_transport_ops { int (*link_supplier)(struct device *dev); - bool (*chan_available)(struct device *dev, int idx); + bool (*chan_available)(struct device_node *of_node, int idx); int (*chan_setup)(struct scmi_chan_info *cinfo, struct device *dev, bool tx); int (*chan_free)(int id, void *p, void *data); diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index e5193da2ce09..62e02b6475ff 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -2035,7 +2035,7 @@ static int scmi_chan_setup(struct scmi_info *info, struct device *dev, if (cinfo) return 0; - if (!info->desc->ops->chan_available(dev, idx)) { + if (!info->desc->ops->chan_available(dev->of_node, idx)) { cinfo = idr_find(idr, SCMI_PROTOCOL_BASE); if (unlikely(!cinfo)) /* Possible only if platform has no Rx */ return -EINVAL; diff --git a/drivers/firmware/arm_scmi/mailbox.c b/drivers/firmware/arm_scmi/mailbox.c index 08ff4d110beb..ed7e66788134 100644 --- a/drivers/firmware/arm_scmi/mailbox.c +++ b/drivers/firmware/arm_scmi/mailbox.c @@ -46,9 +46,9 @@ static void rx_callback(struct mbox_client *cl, void *m) scmi_rx_callback(smbox->cinfo, shmem_read_header(smbox->shmem), NULL); } -static bool mailbox_chan_available(struct device *dev, int idx) +static bool mailbox_chan_available(struct device_node *of_node, int idx) { - return !of_parse_phandle_with_args(dev->of_node, "mboxes", + return !of_parse_phandle_with_args(of_node, "mboxes", "#mbox-cells", idx, NULL); } diff --git a/drivers/firmware/arm_scmi/optee.c b/drivers/firmware/arm_scmi/optee.c index f42dad997ac9..59e688767af2 100644 --- a/drivers/firmware/arm_scmi/optee.c +++ b/drivers/firmware/arm_scmi/optee.c @@ -328,11 +328,11 @@ static int scmi_optee_link_supplier(struct device *dev) return 0; } -static bool scmi_optee_chan_available(struct device *dev, int idx) +static bool scmi_optee_chan_available(struct device_node *of_node, int idx) { u32 channel_id; - return !of_property_read_u32_index(dev->of_node, "linaro,optee-channel-id", + return !of_property_read_u32_index(of_node, "linaro,optee-channel-id", idx, &channel_id); } diff --git a/drivers/firmware/arm_scmi/smc.c b/drivers/firmware/arm_scmi/smc.c index 745acfdd0b3d..0e21bd01348b 100644 --- a/drivers/firmware/arm_scmi/smc.c +++ b/drivers/firmware/arm_scmi/smc.c @@ -52,9 +52,9 @@ static irqreturn_t smc_msg_done_isr(int irq, void *data) return IRQ_HANDLED; } -static bool smc_chan_available(struct device *dev, int idx) +static bool smc_chan_available(struct device_node *of_node, int idx) { - struct device_node *np = of_parse_phandle(dev->of_node, "shmem", 0); + struct device_node *np = of_parse_phandle(of_node, "shmem", 0); if (!np) return false; diff --git a/drivers/firmware/arm_scmi/virtio.c b/drivers/firmware/arm_scmi/virtio.c index 14709dbc96a1..e0c92037a9e6 100644 --- a/drivers/firmware/arm_scmi/virtio.c +++ b/drivers/firmware/arm_scmi/virtio.c @@ -392,7 +392,7 @@ static int virtio_link_supplier(struct device *dev) return 0; } -static bool virtio_chan_available(struct device *dev, int idx) +static bool virtio_chan_available(struct device_node *of_node, int idx) { struct scmi_vio_channel *channels, *vioch = NULL; From patchwork Wed Oct 19 20:46:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 5841 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp528470wrs; Wed, 19 Oct 2022 13:50:58 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4TtXXS/x2xeO1Z8a97GwCOfKxeWJP1g9tmsMlMPq3jI3FXAnVyegk90v4UOVhx4HqvxTdw X-Received: by 2002:a17:902:8542:b0:179:eb8d:f41d with SMTP id d2-20020a170902854200b00179eb8df41dmr10013523plo.62.1666212657894; Wed, 19 Oct 2022 13:50:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666212657; cv=none; d=google.com; s=arc-20160816; b=Rukw3G0v/exixFDNW9CzaXjwCEFJGy2mzDSGJEuMJ6to/9I4cWjN9nLflq9+Ao2JNJ IvzwejBO1LBz3u/rHAVnu1Ff3+z/4Yd+uMntfU3hcqYErNGeuthmrQ8Z3gFBG7Hiw2Yd wLNn+0gRc6KlFK4ezFMsBxClzs+vZY2X6UhqznAdl7iSzoTKe8QxE/N4urJSc6KHe1sF A9PA1ebvuKkzSEJWekIrU6uPxUBExwRyQQ8j+ULUJOPl99KNOwwW90tybIHSJSinLsNq +Cgud4wV8so07vyeRih+wlbOh58razcxJeUOR4lUa/fmJra78AzZR34Ym+ovhFfIGjBf P0Dw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=xymnmmhxquaa6r9I5+RBgUiOWwrpzo6HVv2WyDGnL1o=; b=YBAS77Am/Hpd1bguoQguwrY7/me+zs4x+n+2uiclTaaJkY+r+5iDReYekaBVxb5HPa VAHxIegbYdACtch9HZ5grjyB0YcK0r2SgQ3yRiMGSThwPYHOgC86ZeLz7FRsBbXKdgTa WwwV9IzrsKdj+Yv++yG1N3S7lw+bxq8OjZ4cj5lvZkiiUMwB0CIbtXoFpoEgMkKfTKnA 7dj1LsbwBjlp/VaMxGvqq0mNpyepmJTLCM7PjaD3kkYpD0pnCb81FBE8lOLLMa+dLPUO SMYMr1UtYf8ZQnUG/zkfa6Yw7OKMji5kMetiAzmzBcqM1nWpHwg7dYIKe0XawABONLWS dLDQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id bd12-20020a656e0c000000b0046b158da2d9si19922051pgb.528.2022.10.19.13.50.44; Wed, 19 Oct 2022 13:50:57 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231474AbiJSUrE (ORCPT + 99 others); Wed, 19 Oct 2022 16:47:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37400 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231411AbiJSUqt (ORCPT ); Wed, 19 Oct 2022 16:46:49 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 8D2541BE41A for ; Wed, 19 Oct 2022 13:46:48 -0700 (PDT) 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 8211A1A2D; Wed, 19 Oct 2022 13:46:54 -0700 (PDT) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 56D1D3F792; Wed, 19 Oct 2022 13:46:46 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, etienne.carriere@linaro.org, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, wleavitt@marvell.com, peter.hilber@opensynergy.com, nicola.mazzucato@arm.com, tarek.el-sherbiny@arm.com, quic_kshivnan@quicinc.com, cristian.marussi@arm.com Subject: [PATCH v4 03/11] firmware: arm_scmi: Use dedicated devices to initialize channels Date: Wed, 19 Oct 2022 21:46:18 +0100 Message-Id: <20221019204626.3813043-4-cristian.marussi@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221019204626.3813043-1-cristian.marussi@arm.com> References: <20221019204626.3813043-1-cristian.marussi@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW, SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747150603842951067?= X-GMAIL-MSGID: =?utf-8?q?1747150603842951067?= Refactor channels initialization to use dedicated devices instead of using devices borrowed from the SCMI drivers. Initialize all channels as described in the DT upfront. Signed-off-by: Cristian Marussi --- v3 --> v4 - fix missing devm_kfree on failpath in scmi_chan_setup --- drivers/firmware/arm_scmi/driver.c | 96 ++++++++++++++++++++++-------- 1 file changed, 72 insertions(+), 24 deletions(-) diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 62e02b6475ff..032d1140d631 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -2019,23 +2019,20 @@ static int scmi_xfer_info_init(struct scmi_info *sinfo) return ret; } -static int scmi_chan_setup(struct scmi_info *info, struct device *dev, +static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node, int prot_id, bool tx) { int ret, idx; + char name[32]; struct scmi_chan_info *cinfo; struct idr *idr; + struct scmi_device *tdev = NULL; /* Transmit channel is first entry i.e. index 0 */ idx = tx ? 0 : 1; idr = tx ? &info->tx_idr : &info->rx_idr; - /* check if already allocated, used for multiple device per protocol */ - cinfo = idr_find(idr, prot_id); - if (cinfo) - return 0; - - if (!info->desc->ops->chan_available(dev->of_node, idx)) { + if (!info->desc->ops->chan_available(of_node, idx)) { cinfo = idr_find(idr, SCMI_PROTOCOL_BASE); if (unlikely(!cinfo)) /* Possible only if platform has no Rx */ return -EINVAL; @@ -2046,26 +2043,43 @@ static int scmi_chan_setup(struct scmi_info *info, struct device *dev, if (!cinfo) return -ENOMEM; - cinfo->dev = dev; + /* Create a unique name for this transport device */ + snprintf(name, 32, "__scmi_transport_device_%s_%02X", + idx ? "rx" : "tx", prot_id); + /* Create a uniquely named, dedicated transport device for this chan */ + tdev = scmi_device_create(of_node, info->dev, prot_id, name); + if (!tdev) { + devm_kfree(info->dev, cinfo); + return -EINVAL; + } + cinfo->dev = &tdev->dev; ret = info->desc->ops->chan_setup(cinfo, info->dev, tx); - if (ret) + if (ret) { + scmi_device_destroy(tdev); + devm_kfree(info->dev, cinfo); return ret; + } if (tx && is_polling_required(cinfo, info)) { if (is_transport_polling_capable(info)) - dev_info(dev, + dev_info(&tdev->dev, "Enabled polling mode TX channel - prot_id:%d\n", prot_id); else - dev_warn(dev, + dev_warn(&tdev->dev, "Polling mode NOT supported by transport.\n"); } idr_alloc: ret = idr_alloc(idr, cinfo, prot_id, prot_id + 1, GFP_KERNEL); if (ret != prot_id) { - dev_err(dev, "unable to allocate SCMI idr slot err %d\n", ret); + dev_err(info->dev, + "unable to allocate SCMI idr slot err %d\n", ret); + if (tdev) { + scmi_device_destroy(tdev); + devm_kfree(info->dev, cinfo); + } return ret; } @@ -2074,16 +2088,57 @@ static int scmi_chan_setup(struct scmi_info *info, struct device *dev, } static inline int -scmi_txrx_setup(struct scmi_info *info, struct device *dev, int prot_id) +scmi_txrx_setup(struct scmi_info *info, struct device_node *of_node, + int prot_id) { - int ret = scmi_chan_setup(info, dev, prot_id, true); + int ret = scmi_chan_setup(info, of_node, prot_id, true); if (!ret) /* Rx is optional, hence no error check */ - scmi_chan_setup(info, dev, prot_id, false); + scmi_chan_setup(info, of_node, prot_id, false); return ret; } +/** + * scmi_channels_setup - Helper to initialize all required channels + * + * @info: The SCMI instance descriptor. + * + * Initialize all the channels found described in the DT against the underlying + * configured transport using custom defined dedicated devices instead of + * borrowing devices from the SCMI drivers; this way channels are initialized + * upfront during core SCMI stack probing and are operational even if then no + * SCMI driver is loaded. (useful to operate in Raw mode) + * + * Return: 0 on Success + */ +static int scmi_channels_setup(struct scmi_info *info) +{ + int ret; + struct device_node *child, *top_np = info->dev->of_node; + + ret = scmi_txrx_setup(info, top_np, SCMI_PROTOCOL_BASE); + if (ret) + return ret; + + for_each_available_child_of_node(top_np, child) { + u32 prot_id; + + if (of_property_read_u32(child, "reg", &prot_id)) + continue; + + if (!FIELD_FIT(MSG_PROTOCOL_ID_MASK, prot_id)) + dev_err(info->dev, + "Out of range protocol %d\n", prot_id); + + ret = scmi_txrx_setup(info, child, prot_id); + if (ret) + return ret; + } + + return 0; +} + /** * scmi_get_protocol_device - Helper to get/create an SCMI device. * @@ -2133,14 +2188,6 @@ scmi_get_protocol_device(struct device_node *np, struct scmi_info *info, return NULL; } - if (scmi_txrx_setup(info, &sdev->dev, prot_id)) { - dev_err(&sdev->dev, "failed to setup transport\n"); - scmi_device_destroy(sdev); - mutex_unlock(&scmi_syspower_mtx); - - return NULL; - } - if (prot_id == SCMI_PROTOCOL_SYSTEM) scmi_syspower_registered = true; @@ -2432,7 +2479,8 @@ static int scmi_probe(struct platform_device *pdev) return ret; } - ret = scmi_txrx_setup(info, dev, SCMI_PROTOCOL_BASE); + /* Setup all channels described in the DT at first */ + ret = scmi_channels_setup(info); if (ret) return ret; From patchwork Wed Oct 19 20:46:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 5840 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp528469wrs; Wed, 19 Oct 2022 13:50:58 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4k+RNEsDalQFN3vGpSAUWOesB6SROK5/Ze+CJGUpro5fsP2QGwBFz00FxFRECJ3/3OUaJx X-Received: by 2002:a65:5807:0:b0:459:a31a:80c2 with SMTP id g7-20020a655807000000b00459a31a80c2mr8808083pgr.27.1666212657864; Wed, 19 Oct 2022 13:50:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666212657; cv=none; d=google.com; s=arc-20160816; b=QCA6H9d0uNd6pV3mKj7H2VWhLbIJ/gEDjx1FQelq3tUf0217I7bVm8BINY5LY59jq8 w0cLrAApAvzd6ZJNp1aMO51sev3uB2TrSOlMrPaazKM/CbEljjqmVon0pwhXTrIiIxpY +fTLGhLLu9RjPAS06g+MdWDiSbsBdGQs9zVkGItNew7eVJXlrRSn67OUAQVKoH2NXhww G77baYKlfaLwRHw6bCAIvX2aOkhU6DQGspnF6lpmuFdtQg6E7bhbwDLVA7d1gYDziGl2 VCNn2lgIHJCxMzDyKkmCPqmfJyvTsOnDP+M2hPhQLPaQMGz+MDCMJHcJR6aQ9LYj9CWd BtBQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=yuDWZ+7/SPg5dV3t9/Wu1Lv5eAyr+z9fiRN8t0RGUFU=; b=p9LRWKSy6IKBXH3PvIm6Q8RPBJg0iGQJmXg51cQcSGYATDuyQxNfEjXnuhIKWK/ukr y/KU9eWh4x2/O17MW11OKzEFCGE4IHn5ALnkZrUybgM3+3AUWdSkdwP7BpcKLD28tBDK Dl7Fjl3mAEfzRo4X4GpDb8A4Ipxpq0QqRENvsBQysrs54oUaXAoRw37R6yVt87MJwBXB kc/8ZNfiCmBwhSOrhq4uxcPjSTWDXPmQk6K0WQosPxqkiLiOb0yNUweC6v94NcvzG9/n xgEhJs67L90cTYq36G8wpkGiG2/aBvY2yfQfrltvvM0pbTbBl5hTvPNWINB2Cgnwke4i qnDA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id x11-20020aa78f0b000000b00560f0fe840asi18285789pfr.157.2022.10.19.13.50.45; Wed, 19 Oct 2022 13:50:57 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231476AbiJSUrJ (ORCPT + 99 others); Wed, 19 Oct 2022 16:47:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37536 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231468AbiJSUq4 (ORCPT ); Wed, 19 Oct 2022 16:46:56 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id B63E81BE439 for ; Wed, 19 Oct 2022 13:46:50 -0700 (PDT) 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 AF6A41D6F; Wed, 19 Oct 2022 13:46:56 -0700 (PDT) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 848923F792; Wed, 19 Oct 2022 13:46:48 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, etienne.carriere@linaro.org, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, wleavitt@marvell.com, peter.hilber@opensynergy.com, nicola.mazzucato@arm.com, tarek.el-sherbiny@arm.com, quic_kshivnan@quicinc.com, cristian.marussi@arm.com Subject: [PATCH v4 04/11] firmware: arm_scmi: Refactor polling helpers Date: Wed, 19 Oct 2022 21:46:19 +0100 Message-Id: <20221019204626.3813043-5-cristian.marussi@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221019204626.3813043-1-cristian.marussi@arm.com> References: <20221019204626.3813043-1-cristian.marussi@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW, SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747150603978864188?= X-GMAIL-MSGID: =?utf-8?q?1747150603978864188?= Refactor polling helpers to receive scmi_desc directly as a parameter and move all of them to common.h. No functional change. Signed-off-by: Cristian Marussi --- drivers/firmware/arm_scmi/common.h | 18 ++++++++++++++++ drivers/firmware/arm_scmi/driver.c | 34 ++++++++---------------------- 2 files changed, 27 insertions(+), 25 deletions(-) diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h index 096b66442d84..30d056febef1 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -212,6 +212,24 @@ struct scmi_desc { const bool atomic_enabled; }; +static inline bool is_polling_required(struct scmi_chan_info *cinfo, + const struct scmi_desc *desc) +{ + return cinfo->no_completion_irq || desc->force_polling; +} + +static inline bool is_transport_polling_capable(const struct scmi_desc *desc) +{ + return desc->ops->poll_done || desc->sync_cmds_completed_on_ret; +} + +static inline bool is_polling_enabled(struct scmi_chan_info *cinfo, + const struct scmi_desc *desc) +{ + return is_polling_required(cinfo, desc) && + is_transport_polling_capable(desc); +} + #ifdef CONFIG_ARM_SCMI_TRANSPORT_MAILBOX extern const struct scmi_desc scmi_mailbox_desc; #endif diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 032d1140d631..9c77c931d91b 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -648,25 +648,6 @@ static inline void scmi_clear_channel(struct scmi_info *info, info->desc->ops->clear_channel(cinfo); } -static inline bool is_polling_required(struct scmi_chan_info *cinfo, - struct scmi_info *info) -{ - return cinfo->no_completion_irq || info->desc->force_polling; -} - -static inline bool is_transport_polling_capable(struct scmi_info *info) -{ - return info->desc->ops->poll_done || - info->desc->sync_cmds_completed_on_ret; -} - -static inline bool is_polling_enabled(struct scmi_chan_info *cinfo, - struct scmi_info *info) -{ - return is_polling_required(cinfo, info) && - is_transport_polling_capable(info); -} - static void scmi_handle_notification(struct scmi_chan_info *cinfo, u32 msg_hdr, void *priv) { @@ -909,7 +890,8 @@ static int do_xfer(const struct scmi_protocol_handle *ph, struct scmi_chan_info *cinfo; /* Check for polling request on custom command xfers at first */ - if (xfer->hdr.poll_completion && !is_transport_polling_capable(info)) { + if (xfer->hdr.poll_completion && + !is_transport_polling_capable(info->desc)) { dev_warn_once(dev, "Polling mode is not supported by transport.\n"); return -EINVAL; @@ -920,7 +902,7 @@ static int do_xfer(const struct scmi_protocol_handle *ph, return -EINVAL; /* True ONLY if also supported by transport. */ - if (is_polling_enabled(cinfo, info)) + if (is_polling_enabled(cinfo, info->desc)) xfer->hdr.poll_completion = true; /* @@ -1854,7 +1836,8 @@ static bool scmi_is_transport_atomic(const struct scmi_handle *handle, bool ret; struct scmi_info *info = handle_to_scmi_info(handle); - ret = info->desc->atomic_enabled && is_transport_polling_capable(info); + ret = info->desc->atomic_enabled && + is_transport_polling_capable(info->desc); if (ret && atomic_threshold) *atomic_threshold = info->atomic_threshold; @@ -2061,8 +2044,8 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node, return ret; } - if (tx && is_polling_required(cinfo, info)) { - if (is_transport_polling_capable(info)) + if (tx && is_polling_required(cinfo, info->desc)) { + if (is_transport_polling_capable(info->desc)) dev_info(&tdev->dev, "Enabled polling mode TX channel - prot_id:%d\n", prot_id); @@ -2491,7 +2474,8 @@ static int scmi_probe(struct platform_device *pdev) if (scmi_notification_init(handle)) dev_err(dev, "SCMI Notifications NOT available.\n"); - if (info->desc->atomic_enabled && !is_transport_polling_capable(info)) + if (info->desc->atomic_enabled && + !is_transport_polling_capable(info->desc)) dev_err(dev, "Transport is not polling capable. Atomic mode not supported.\n"); From patchwork Wed Oct 19 20:46:20 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 5842 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp528503wrs; Wed, 19 Oct 2022 13:51:02 -0700 (PDT) X-Google-Smtp-Source: AMsMyM7vapOvM5hzgmGabckCvTf0cbsNjnWAV2VsZPVbe5oYepvyFBukmFGJIgCsK1xzuv5Eazll X-Received: by 2002:a17:902:ba95:b0:17f:9943:2dea with SMTP id k21-20020a170902ba9500b0017f99432deamr10422436pls.81.1666212662262; Wed, 19 Oct 2022 13:51:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666212662; cv=none; d=google.com; s=arc-20160816; b=rPI7OKQ2NrT/PnJ+Vc7fpBaTgzEz0xLH6SEPMlYyQquu842LuXyxcVvTaMdBBF2vRL KnkOC0VQj/saDw5dRQb8DX6y2T0XjiIN0k69Rx6c6OLxD97eZBGwyRR6KF8ZWHsq6cAW 2apMYt29CyFq2oJe7Ekvb8nAMbfIhWpUgiWDZmYvNc03JwtzQXI4cNTFZchhXxTWVslh kYvg5Uh2visJSAIcrFNzKqSMjKdthPmb45uS0mLiPeYS3Z9Z2FYpnoiVyhys5XKy9Fut Q8WVC3pYAzYDcJzkzgoGwpGpyBog9Q2831qjTB4vX3I06jup0O7yehHER0WW7RXEiVVr zQRw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=jJ6xLshG7yqUfQ+av1ZOGkHbgVpq47YQYGI7uAci9tM=; b=nl4JZaVd425/4+l8CXIWj3uNsWKF/XRMzG/z5UOIcQzYnacrLaDst73Gq71hol/h2z wKdvkfNN2Ni/gIdepH5AJZRNkPJ5z6yR8DgI702etJ+A9nuuojvse9zMVN34lpocOZSM dyTa1pmqQZy15yclrdJqkhsZQQ9X2rJgwJqk9jGtJmMjB10CSNwhf9SvGg4VMwkCAJqi 7a+O/hfAUgM3gdGMFtGUSn2pMJem8mRaaekxLkxZX6S6rqjX0LaQak4FsIvl3jfxSLlX m3caCf+LADLg8DNhWrVFIHDEYVHixjGUwHpxgb0ZuFxihTIK8Zyc1IT+zokbBrE20XYw C0aA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id d17-20020a170903231100b00176939b5cd9si25003130plh.578.2022.10.19.13.50.50; Wed, 19 Oct 2022 13:51:02 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231516AbiJSUrN (ORCPT + 99 others); Wed, 19 Oct 2022 16:47:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37538 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231480AbiJSUq5 (ORCPT ); Wed, 19 Oct 2022 16:46:57 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 1D7DE1BF851 for ; Wed, 19 Oct 2022 13:46:53 -0700 (PDT) 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 DCD971D70; Wed, 19 Oct 2022 13:46:58 -0700 (PDT) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id B1FA93F792; Wed, 19 Oct 2022 13:46:50 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, etienne.carriere@linaro.org, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, wleavitt@marvell.com, peter.hilber@opensynergy.com, nicola.mazzucato@arm.com, tarek.el-sherbiny@arm.com, quic_kshivnan@quicinc.com, cristian.marussi@arm.com Subject: [PATCH v4 05/11] firmware: arm_scmi: Refactor scmi_wait_for_message_response Date: Wed, 19 Oct 2022 21:46:20 +0100 Message-Id: <20221019204626.3813043-6-cristian.marussi@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221019204626.3813043-1-cristian.marussi@arm.com> References: <20221019204626.3813043-1-cristian.marussi@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW, SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747150608181974894?= X-GMAIL-MSGID: =?utf-8?q?1747150608181974894?= Refactor scmi_wait_for_message_response() to use a internal helper to carry out its main duties; while doing that make it accept directly an scmi_desc parameter to interact with the configured transport. No functional change. Signed-off-by: Cristian Marussi --- drivers/firmware/arm_scmi/driver.c | 57 +++++++++++++++++------------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 9c77c931d91b..d496dfe43618 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -791,36 +791,18 @@ static bool scmi_xfer_done_no_timeout(struct scmi_chan_info *cinfo, ktime_after(ktime_get(), stop); } -/** - * scmi_wait_for_message_response - An helper to group all the possible ways of - * waiting for a synchronous message response. - * - * @cinfo: SCMI channel info - * @xfer: Reference to the transfer being waited for. - * - * Chooses waiting strategy (sleep-waiting vs busy-waiting) depending on - * configuration flags like xfer->hdr.poll_completion. - * - * Return: 0 on Success, error otherwise. - */ -static int scmi_wait_for_message_response(struct scmi_chan_info *cinfo, - struct scmi_xfer *xfer) +static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc, + struct scmi_chan_info *cinfo, + struct scmi_xfer *xfer, unsigned int timeout_ms) { - struct scmi_info *info = handle_to_scmi_info(cinfo->handle); - struct device *dev = info->dev; - int ret = 0, timeout_ms = info->desc->max_rx_timeout_ms; - - trace_scmi_xfer_response_wait(xfer->transfer_id, xfer->hdr.id, - xfer->hdr.protocol_id, xfer->hdr.seq, - timeout_ms, - xfer->hdr.poll_completion); + int ret = 0; if (xfer->hdr.poll_completion) { /* * Real polling is needed only if transport has NOT declared * itself to support synchronous commands replies. */ - if (!info->desc->sync_cmds_completed_on_ret) { + if (!desc->sync_cmds_completed_on_ret) { /* * Poll on xfer using transport provided .poll_done(); * assumes no completion interrupt was available. @@ -846,7 +828,7 @@ static int scmi_wait_for_message_response(struct scmi_chan_info *cinfo, */ spin_lock_irqsave(&xfer->lock, flags); if (xfer->state == SCMI_XFER_SENT_OK) { - info->desc->ops->fetch_response(cinfo, xfer); + desc->ops->fetch_response(cinfo, xfer); xfer->state = SCMI_XFER_RESP_OK; } spin_unlock_irqrestore(&xfer->lock, flags); @@ -870,6 +852,33 @@ static int scmi_wait_for_message_response(struct scmi_chan_info *cinfo, return ret; } +/** + * scmi_wait_for_message_response - An helper to group all the possible ways of + * waiting for a synchronous message response. + * + * @cinfo: SCMI channel info + * @xfer: Reference to the transfer being waited for. + * + * Chooses waiting strategy (sleep-waiting vs busy-waiting) depending on + * configuration flags like xfer->hdr.poll_completion. + * + * Return: 0 on Success, error otherwise. + */ +static int scmi_wait_for_message_response(struct scmi_chan_info *cinfo, + struct scmi_xfer *xfer) +{ + struct scmi_info *info = handle_to_scmi_info(cinfo->handle); + struct device *dev = info->dev; + + trace_scmi_xfer_response_wait(xfer->transfer_id, xfer->hdr.id, + xfer->hdr.protocol_id, xfer->hdr.seq, + info->desc->max_rx_timeout_ms, + xfer->hdr.poll_completion); + + return scmi_wait_for_reply(dev, info->desc, cinfo, xfer, + info->desc->max_rx_timeout_ms); +} + /** * do_xfer() - Do one transfer * From patchwork Wed Oct 19 20:46:21 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 5843 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp528592wrs; Wed, 19 Oct 2022 13:51:17 -0700 (PDT) X-Google-Smtp-Source: AMsMyM7rAs5/XOGT/wBuoSy4fxAAaeE3LlbFLqtxhcikO/4KchB3qLjhL1cJk/qu7j8LnRAnx+05 X-Received: by 2002:a05:6402:34cd:b0:45d:a345:764 with SMTP id w13-20020a05640234cd00b0045da3450764mr9180032edc.415.1666212677220; Wed, 19 Oct 2022 13:51:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666212677; cv=none; d=google.com; s=arc-20160816; b=iBzZj0euL49uGED1BJaWJ8Ddjv0UPU+ZByqEvITGlJWlP/J/NZREs6gkynHt0yjM31 d67uJMb0jL9Fn7WtuRPmNdGfZ3XcLjA04iVi2c73VWxe2d4+zAmZ10P0XWkC2h/Zbj1o tlcmrhvN4nk8rR36XjMDs1HehpS+5UYkisYL7S8R/qrouiqset4uz7objxB0/Nnl4tXL RLMcwWHyfvttxWaMjZRQgmcrsdCEjMwgX0U0JFxsG73IVuSWpb9lZmfvXOLtqm+MdaGz 8ycowrVQN3DlPl6u1eAfC7lkJEtdFCWfLU+fLqDu+FUFCfVqz0SgFBZ9PaIAWHu6d9so UZ6w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=7gmC0Ldty1trmF2lchY5Z/OifxyyH1eG5MoNUcdJCHc=; b=ZnZuFHyjd/5oSAl49hmSEj4jj8aFngzWeSmC31uBhAGK0mXZ+FeMpHxWVoBNZNYGTo VwKiTDRn2CY48oP0j9uJMmYT5k8KOW3oWVsO2IcY0pLLfaEpdLT6/0zrcqm5LjCA5Yry mC3jQNt010hXfmqp97jjzG/pAKiqTvVyKvkelzKlCaOMmNmkpRZK9d83+YGJg0ph/MOR 5IpUFQtoZF8CcrPRmDPDW/jddiUFoa2JaaSwGGMKeuLUYogYqlCO34KxzLPVit0T7yRv +Glw/sOZFDRuKsOVh4nS44JaUIe/2LlpIzgXDp3NtPN2KPtfBTBoyrqcOcJjSUl/8vDQ dCzw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id z5-20020a056402274500b0045c13366de4si17181180edd.572.2022.10.19.13.50.52; Wed, 19 Oct 2022 13:51:17 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231555AbiJSUrR (ORCPT + 99 others); Wed, 19 Oct 2022 16:47:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37780 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231452AbiJSUrC (ORCPT ); Wed, 19 Oct 2022 16:47:02 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id A7DFA1C77D3 for ; Wed, 19 Oct 2022 13:46:55 -0700 (PDT) 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 18A401DB5; Wed, 19 Oct 2022 13:47:01 -0700 (PDT) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id DFD813F792; Wed, 19 Oct 2022 13:46:52 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, etienne.carriere@linaro.org, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, wleavitt@marvell.com, peter.hilber@opensynergy.com, nicola.mazzucato@arm.com, tarek.el-sherbiny@arm.com, quic_kshivnan@quicinc.com, cristian.marussi@arm.com Subject: [PATCH v4 06/11] firmware: arm_scmi: Add xfer raw helpers Date: Wed, 19 Oct 2022 21:46:21 +0100 Message-Id: <20221019204626.3813043-7-cristian.marussi@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221019204626.3813043-1-cristian.marussi@arm.com> References: <20221019204626.3813043-1-cristian.marussi@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW, SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747150624132633820?= X-GMAIL-MSGID: =?utf-8?q?1747150624132633820?= Add a few SCMI helpers useful to implement SCMI Raw access support. Signed-off-by: Cristian Marussi --- v3 --> v4 - add scmi_xfer_raw_wait_for_response helper - fixed typos in comments v2 --> v3 - allow for DT-unknown protocols to get a channel v1 --> v2 - added scmi_xfer_raw_channel_get --- drivers/firmware/arm_scmi/common.h | 12 +++ drivers/firmware/arm_scmi/driver.c | 141 +++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+) diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h index 30d056febef1..3dceb69b8484 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -230,6 +230,18 @@ static inline bool is_polling_enabled(struct scmi_chan_info *cinfo, is_transport_polling_capable(desc); } +void scmi_xfer_raw_put(const struct scmi_handle *handle, + struct scmi_xfer *xfer); +struct scmi_xfer *scmi_xfer_raw_get(const struct scmi_handle *handle); +struct scmi_chan_info * +scmi_xfer_raw_channel_get(const struct scmi_handle *handle, u8 protocol_id); + +int scmi_xfer_raw_inflight_register(const struct scmi_handle *handle, + struct scmi_xfer *xfer); + +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 diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index d496dfe43618..3649435082bb 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -350,6 +350,53 @@ scmi_xfer_inflight_register_unlocked(struct scmi_xfer *xfer, xfer->pending = true; } +/** + * scmi_xfer_inflight_register - Try to register an xfer as in-flight + * + * @xfer: The xfer to register + * @minfo: Pointer to Tx/Rx Message management info based on channel type + * + * Note that this helper does NOT assume anything about the sequence number + * that was baked into the provided xfer, so it checks at first if it can + * be mapped to a free slot and fails with an error if another xfer with the + * same sequence number is currently still registered as in-flight. + * + * Return: 0 on Success or -EBUSY if sequence number embedded in the xfer + * could not rbe mapped to a free slot in the xfer_alloc_table. + */ +static int scmi_xfer_inflight_register(struct scmi_xfer *xfer, + struct scmi_xfers_info *minfo) +{ + int ret = 0; + unsigned long flags; + + spin_lock_irqsave(&minfo->xfer_lock, flags); + if (!test_bit(xfer->hdr.seq, minfo->xfer_alloc_table)) + scmi_xfer_inflight_register_unlocked(xfer, minfo); + else + ret = -EBUSY; + spin_unlock_irqrestore(&minfo->xfer_lock, flags); + + return ret; +} + +/** + * scmi_xfer_raw_inflight_register - An helper to register the given xfer as in + * flight on the TX channel, if possible. + * + * @handle: Pointer to SCMI entity handle + * @xfer: The xfer to register + * + * Return: 0 on Success, error otherwise + */ +int scmi_xfer_raw_inflight_register(const struct scmi_handle *handle, + struct scmi_xfer *xfer) +{ + struct scmi_info *info = handle_to_scmi_info(handle); + + return scmi_xfer_inflight_register(xfer, &info->tx_minfo); +} + /** * scmi_xfer_pending_set - Pick a proper sequence number and mark the xfer * as pending in-flight @@ -425,6 +472,58 @@ static struct scmi_xfer *scmi_xfer_get(const struct scmi_handle *handle, return xfer; } +/** + * scmi_xfer_raw_get - Helper to get a bare free xfer from the TX channel + * + * @handle: Pointer to SCMI entity handle + * + * Note that xfer is taken from the TX channel structures. + * + * Return: A valid xfer on Success, or an error-pointer otherwise + */ +struct scmi_xfer *scmi_xfer_raw_get(const struct scmi_handle *handle) +{ + struct scmi_info *info = handle_to_scmi_info(handle); + + return scmi_xfer_get(handle, &info->tx_minfo); +} + +/** + * scmi_xfer_raw_channel_get - Helper to get a reference to the proper channel + * to use for a specific protocol_id Raw transaction. + * + * @handle: Pointer to SCMI entity handle + * @protocol_id: Identifier of the protocol + * + * Note that in a regular SCMI stack, usually, a protocol has to be defined in + * the DT to have an associated channel and be usable; but in Raw mode any + * protocol in range is allowed, re-using the Base channel, so as to enable + * fuzzing on any protocol without the need of a fully compiled DT. + * + * Return: A reference to the channel to use, or an ERR_PTR + */ +struct scmi_chan_info * +scmi_xfer_raw_channel_get(const struct scmi_handle *handle, u8 protocol_id) +{ + struct scmi_chan_info *cinfo; + struct scmi_info *info = handle_to_scmi_info(handle); + + cinfo = idr_find(&info->tx_idr, protocol_id); + if (!cinfo) { + if (protocol_id == SCMI_PROTOCOL_BASE) + return ERR_PTR(-EINVAL); + /* Use Base channel for protocols not defined for DT */ + cinfo = idr_find(&info->tx_idr, SCMI_PROTOCOL_BASE); + if (!cinfo) + return ERR_PTR(-EINVAL); + dev_warn_once(handle->dev, + "Using Base channel for protocol 0x%X\n", + protocol_id); + } + + return cinfo; +} + /** * __scmi_xfer_put() - Release a message * @@ -453,6 +552,22 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer) spin_unlock_irqrestore(&minfo->xfer_lock, flags); } +/** + * scmi_xfer_raw_put - Release an xfer that was taken by @scmi_xfer_raw_get + * + * @handle: Pointer to SCMI entity handle + * @xfer: A reference to the xfer to put + * + * Note that as with other xfer_put() handlers the xfer is really effectively + * released only if there are no more users on the system. + */ +void scmi_xfer_raw_put(const struct scmi_handle *handle, struct scmi_xfer *xfer) +{ + struct scmi_info *info = handle_to_scmi_info(handle); + + return __scmi_xfer_put(&info->tx_minfo, xfer); +} + /** * scmi_xfer_lookup_unlocked - Helper to lookup an xfer_id * @@ -879,6 +994,32 @@ static int scmi_wait_for_message_response(struct scmi_chan_info *cinfo, info->desc->max_rx_timeout_ms); } +/** + * scmi_xfer_raw_wait_for_message_response - An helper to wait for a message + * reply to an xfer raw request on a specific channel for the required timeout. + * + * @cinfo: SCMI channel info + * @xfer: Reference to the transfer being waited for. + * @timeout_ms: The maximum timeout in milliseconds + * + * Return: 0 on Success, error otherwise. + */ +int scmi_xfer_raw_wait_for_message_response(struct scmi_chan_info *cinfo, + struct scmi_xfer *xfer, + unsigned int timeout_ms) +{ + int ret; + struct scmi_info *info = handle_to_scmi_info(cinfo->handle); + struct device *dev = info->dev; + + ret = scmi_wait_for_reply(dev, info->desc, cinfo, xfer, timeout_ms); + if (ret) + dev_dbg(dev, "timed out in RAW response - HDR:%08X\n", + pack_scmi_header(&xfer->hdr)); + + return ret; +} + /** * do_xfer() - Do one transfer * From patchwork Wed Oct 19 20:46:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 5847 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp529321wrs; Wed, 19 Oct 2022 13:53:32 -0700 (PDT) X-Google-Smtp-Source: AMsMyM7JEHJ20p7YBIJMgr+7Mz6gcnMc2wg6yrqKch9UMIypXAk6w06+5E+BhZCGipVxnRDUiRlv X-Received: by 2002:a17:907:160e:b0:791:8ae7:4fb8 with SMTP id hb14-20020a170907160e00b007918ae74fb8mr8649792ejc.271.1666212812234; Wed, 19 Oct 2022 13:53:32 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666212812; cv=none; d=google.com; s=arc-20160816; b=A7L5N3k72uFn1gJ0Iz528KW8J0HyH+GDrvm2fKWIyiPxjzOrYduEbi5sVgZ+WumFDG IM5wsYclXhbRux/K0TFf60sHy0DZlLRoYbDOYXUYnUpfKxLvY1Dv2/AmMrJmFunik+Gn 9MdP+/02G6tuhP7n0nXP2RHCPR6+HIvtqeF31VQ4nUfXLNd16OsiaTMOAk/uy5t2lKyJ ie8vGkJTs+x/cebpP5oz9hum+edaFNa+ElThz4xw0jqoo4Uk6denCKcB/2wE41wfrHeb P+VmvVpU7UA0ozuIzkRdIQcKgKb6PddmwpFRpbU0fuvCgpWFBTIv3HbFYDQW/kDo0Y5p 2dvQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=f/GZOyEgRoJanFyrT6saJCgV0yj4rrrd1Ie1VyrBGq4=; b=LfBlzF8i7Cusk0ZSWgiN199BWB8bxNfYxDiTWHO6QHQZaNpNxdPeQMWnZcYsUs5PVs r57YJkr4TQbFgxXwQ6XDulEgLdI+sLX+lMKbbdIfRJyrEbWHwP+c65+i3GL/irfO15kj H48RAZTzVNVqeS7uJLypEyjCIjOQ4BN0TDkzZR2+KT1zr0dypg+oLr/qK4vWwXiuDjQc 2Li+YxRYnggEdjQdaOvPvwrIajexXuKSqsuUY+MMd0XYmsHl5wKUlpfSiozBvPsF1tNI Ahba2kLXGU9BCEOea1OBQ5EHf1dSIqVvtmd8Vjust/gHunj+Rsx2ZD0hAKM/nGNwT+Kc odiQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id j15-20020aa7de8f000000b0045c0c18dde7si13597734edv.524.2022.10.19.13.53.07; Wed, 19 Oct 2022 13:53:32 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231559AbiJSUrU (ORCPT + 99 others); Wed, 19 Oct 2022 16:47:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37826 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231469AbiJSUrD (ORCPT ); Wed, 19 Oct 2022 16:47:03 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 7384B1C904A for ; Wed, 19 Oct 2022 13:46:58 -0700 (PDT) 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 5ABB114BF; Wed, 19 Oct 2022 13:47:03 -0700 (PDT) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 1B6A33F792; Wed, 19 Oct 2022 13:46:54 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, etienne.carriere@linaro.org, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, wleavitt@marvell.com, peter.hilber@opensynergy.com, nicola.mazzucato@arm.com, tarek.el-sherbiny@arm.com, quic_kshivnan@quicinc.com, cristian.marussi@arm.com Subject: [PATCH v4 07/11] firmware: arm_scmi: Move errors defs and code to common.h Date: Wed, 19 Oct 2022 21:46:22 +0100 Message-Id: <20221019204626.3813043-8-cristian.marussi@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221019204626.3813043-1-cristian.marussi@arm.com> References: <20221019204626.3813043-1-cristian.marussi@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW, SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747150765459435173?= X-GMAIL-MSGID: =?utf-8?q?1747150765459435173?= Move SCMI error codes definitions and helper to the common.h header together with the delayed response timeout define. No functional change. Signed-off-by: Cristian Marussi --- drivers/firmware/arm_scmi/common.h | 40 ++++++++++++++++++++++++++++++ drivers/firmware/arm_scmi/driver.c | 40 ------------------------------ 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h index 3dceb69b8484..3b2b18d37093 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -27,6 +27,46 @@ #include "protocols.h" #include "notify.h" +#define SCMI_MAX_RESPONSE_TIMEOUT (2 * MSEC_PER_SEC) + +enum scmi_error_codes { + SCMI_SUCCESS = 0, /* Success */ + SCMI_ERR_SUPPORT = -1, /* Not supported */ + SCMI_ERR_PARAMS = -2, /* Invalid Parameters */ + SCMI_ERR_ACCESS = -3, /* Invalid access/permission denied */ + SCMI_ERR_ENTRY = -4, /* Not found */ + SCMI_ERR_RANGE = -5, /* Value out of range */ + SCMI_ERR_BUSY = -6, /* Device busy */ + SCMI_ERR_COMMS = -7, /* Communication Error */ + SCMI_ERR_GENERIC = -8, /* Generic Error */ + SCMI_ERR_HARDWARE = -9, /* Hardware Error */ + SCMI_ERR_PROTOCOL = -10,/* Protocol Error */ +}; + +static const int scmi_linux_errmap[] = { + /* better than switch case as long as return value is continuous */ + 0, /* SCMI_SUCCESS */ + -EOPNOTSUPP, /* SCMI_ERR_SUPPORT */ + -EINVAL, /* SCMI_ERR_PARAM */ + -EACCES, /* SCMI_ERR_ACCESS */ + -ENOENT, /* SCMI_ERR_ENTRY */ + -ERANGE, /* SCMI_ERR_RANGE */ + -EBUSY, /* SCMI_ERR_BUSY */ + -ECOMM, /* SCMI_ERR_COMMS */ + -EIO, /* SCMI_ERR_GENERIC */ + -EREMOTEIO, /* SCMI_ERR_HARDWARE */ + -EPROTO, /* SCMI_ERR_PROTOCOL */ +}; + +static inline int scmi_to_linux_errno(int errno) +{ + int err_idx = -errno; + + if (err_idx >= SCMI_SUCCESS && err_idx < ARRAY_SIZE(scmi_linux_errmap)) + return scmi_linux_errmap[err_idx]; + return -EIO; +} + #define MSG_ID_MASK GENMASK(7, 0) #define MSG_XTRACT_ID(hdr) FIELD_GET(MSG_ID_MASK, (hdr)) #define MSG_TYPE_MASK GENMASK(9, 8) diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 3649435082bb..b504b5cdc55f 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -37,20 +37,6 @@ #define CREATE_TRACE_POINTS #include -enum scmi_error_codes { - SCMI_SUCCESS = 0, /* Success */ - SCMI_ERR_SUPPORT = -1, /* Not supported */ - SCMI_ERR_PARAMS = -2, /* Invalid Parameters */ - SCMI_ERR_ACCESS = -3, /* Invalid access/permission denied */ - SCMI_ERR_ENTRY = -4, /* Not found */ - SCMI_ERR_RANGE = -5, /* Value out of range */ - SCMI_ERR_BUSY = -6, /* Device busy */ - SCMI_ERR_COMMS = -7, /* Communication Error */ - SCMI_ERR_GENERIC = -8, /* Generic Error */ - SCMI_ERR_HARDWARE = -9, /* Hardware Error */ - SCMI_ERR_PROTOCOL = -10,/* Protocol Error */ -}; - /* List of all SCMI devices active in system */ static LIST_HEAD(scmi_list); /* Protection for the entire list */ @@ -170,30 +156,6 @@ struct scmi_info { #define handle_to_scmi_info(h) container_of(h, struct scmi_info, handle) -static const int scmi_linux_errmap[] = { - /* better than switch case as long as return value is continuous */ - 0, /* SCMI_SUCCESS */ - -EOPNOTSUPP, /* SCMI_ERR_SUPPORT */ - -EINVAL, /* SCMI_ERR_PARAM */ - -EACCES, /* SCMI_ERR_ACCESS */ - -ENOENT, /* SCMI_ERR_ENTRY */ - -ERANGE, /* SCMI_ERR_RANGE */ - -EBUSY, /* SCMI_ERR_BUSY */ - -ECOMM, /* SCMI_ERR_COMMS */ - -EIO, /* SCMI_ERR_GENERIC */ - -EREMOTEIO, /* SCMI_ERR_HARDWARE */ - -EPROTO, /* SCMI_ERR_PROTOCOL */ -}; - -static inline int scmi_to_linux_errno(int errno) -{ - int err_idx = -errno; - - if (err_idx >= SCMI_SUCCESS && err_idx < ARRAY_SIZE(scmi_linux_errmap)) - return scmi_linux_errmap[err_idx]; - return -EIO; -} - void scmi_notification_instance_data_set(const struct scmi_handle *handle, void *priv) { @@ -1109,8 +1071,6 @@ static void reset_rx_to_maxsz(const struct scmi_protocol_handle *ph, xfer->rx.len = info->desc->max_msg_size; } -#define SCMI_MAX_RESPONSE_TIMEOUT (2 * MSEC_PER_SEC) - /** * do_xfer_with_response() - Do one transfer and wait until the delayed * response is received From patchwork Wed Oct 19 20:46:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 5844 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp528716wrs; Wed, 19 Oct 2022 13:51:47 -0700 (PDT) X-Google-Smtp-Source: AMsMyM6Gkzy+aYrVvRCZ+sG99Vku2SZo7muWOjvjxERh6Z8ClOJkPKw9qyUO8RAV4R8N0Uag/pYT X-Received: by 2002:a05:6a00:1a0e:b0:547:1cf9:40e8 with SMTP id g14-20020a056a001a0e00b005471cf940e8mr10487753pfv.82.1666212707363; Wed, 19 Oct 2022 13:51:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666212707; cv=none; d=google.com; s=arc-20160816; b=rfpBMNRrr2M690RgxHIWd+B46rp2qhpIZwh8XSmYzcBK5UZZq/pGsEbZ8tm5XO8iU4 gMDOdDv8jIQUt5l8h0MR9klc2r6b2mt3cgZosQGoZuj7HfQswwOkmPfq5mU2sAPpDKA4 XCG65+BbOKN4Q7MlKPJE5xjCB4jZLiTItv6yJWHawyUSygwmz32Sl8yxS9O50FORaskK 3F4dcZMlLdlSZJbpocRyCklCVj10VW++qKeGDBsPwQAOg3i9w41eLn2BCWdLXYyB9Hgt /i6JSPoTYZiBjJMz6PF+On45sQLSvKHj4tVyZPrdaQX0/RVyDt0Bs1sVpnrZn7zJw+a+ u88Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=MvyQyIlGp/YcQQVwObQ5xowUkKaCN8AsWVC9SwKikK0=; b=qqUGwP+iUjeYO3IMwz7Acf9pSE1lP4YO8afjfzJxZZxxQqemESR09FdRR+lIIB1rI9 c0dy0eHAkWwDzGGcuHQZmbtBiTAGTyGq07EZqI21BN8jd1aHWZPN9JGH6y38AbxopoEk a818TrcnI9yzDL+B2dLycaE3BA5NxWpuOcMvLdUgkQV64QIl3eTUL2M/AkV89ApBEdYJ PQiLt3X7q4Csx2x19S84oyWyh3Wcc+3paD3vkdACh1TtazrfrctZIzGr9IqQq77KUrbB AeJX0jWQC78tjPesjTQrmJZ+wvggwizgb0Im+cUxyi7dEo60DUPCBHIOHerNtgUv7gfJ d4SA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id n5-20020a63e045000000b004554963e1d2si19663927pgj.172.2022.10.19.13.51.34; Wed, 19 Oct 2022 13:51:47 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231572AbiJSUrY (ORCPT + 99 others); Wed, 19 Oct 2022 16:47:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37998 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231502AbiJSUrI (ORCPT ); Wed, 19 Oct 2022 16:47:08 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 992751BE931 for ; Wed, 19 Oct 2022 13:47:00 -0700 (PDT) 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 AF9A51424; Wed, 19 Oct 2022 13:47:05 -0700 (PDT) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 4A5163F792; Wed, 19 Oct 2022 13:46:57 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, etienne.carriere@linaro.org, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, wleavitt@marvell.com, peter.hilber@opensynergy.com, nicola.mazzucato@arm.com, tarek.el-sherbiny@arm.com, quic_kshivnan@quicinc.com, cristian.marussi@arm.com Subject: [PATCH v4 08/11] firmware: arm_scmi: Add raw transmission support Date: Wed, 19 Oct 2022 21:46:23 +0100 Message-Id: <20221019204626.3813043-9-cristian.marussi@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221019204626.3813043-1-cristian.marussi@arm.com> References: <20221019204626.3813043-1-cristian.marussi@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW, SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747150655933318534?= X-GMAIL-MSGID: =?utf-8?q?1747150655933318534?= Add SCMI Raw mode support which exposes a userspace interface to allow for bare SCMI command injection and snooping from userspace. Signed-off-by: Cristian Marussi --- v3 --> v4 - fix handling of O_NONBLOCK raw_mode read requests - add support for polled/nocomnpletion_irq transports - removed inlines v2 --> v3 - changed to dev_dbg when retrying inflight reg - refactored and simplfiied waiters deferred worker - fixed sparse errors about LE and __poll_t v1 --> v2 - make use of proper channel depending on protocol at hand (using scmi_xfer_raw_channel_get to lookup related DT config) - refactored scmi_inflight_register call - added debugfs docs and comments --- drivers/firmware/arm_scmi/Kconfig | 13 + drivers/firmware/arm_scmi/Makefile | 1 + drivers/firmware/arm_scmi/raw_mode.c | 1244 ++++++++++++++++++++++++++ drivers/firmware/arm_scmi/raw_mode.h | 29 + 4 files changed, 1287 insertions(+) create mode 100644 drivers/firmware/arm_scmi/raw_mode.c create mode 100644 drivers/firmware/arm_scmi/raw_mode.h diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig index a14f65444b35..ab726a92ac2f 100644 --- a/drivers/firmware/arm_scmi/Kconfig +++ b/drivers/firmware/arm_scmi/Kconfig @@ -23,6 +23,19 @@ config ARM_SCMI_PROTOCOL if ARM_SCMI_PROTOCOL +config ARM_SCMI_RAW_MODE_SUPPORT + bool "Enable support for SCMI Raw transmission mode" + help + Enable support for SCMI Raw transmission mode. + + If enabled allows the direct injection and snooping of SCMI bare + messages through a dedicated debugfs interface. + It is meant to be used by SCMI compliance/testing suites. + + When enabled regular SCMI drivers interactions are inhibited in + order to avoid unexpected interactions with the SCMI Raw message + flow. If unsure say N. + config ARM_SCMI_HAVE_TRANSPORT bool help diff --git a/drivers/firmware/arm_scmi/Makefile b/drivers/firmware/arm_scmi/Makefile index 9ea86f8cc8f7..7c1aca60c8ce 100644 --- a/drivers/firmware/arm_scmi/Makefile +++ b/drivers/firmware/arm_scmi/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only scmi-bus-y = bus.o scmi-driver-y = driver.o notify.o +scmi-driver-$(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT) += raw_mode.o scmi-transport-$(CONFIG_ARM_SCMI_HAVE_SHMEM) = shmem.o scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) += mailbox.o scmi-transport-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) += smc.o diff --git a/drivers/firmware/arm_scmi/raw_mode.c b/drivers/firmware/arm_scmi/raw_mode.c new file mode 100644 index 000000000000..3fdfc0564286 --- /dev/null +++ b/drivers/firmware/arm_scmi/raw_mode.c @@ -0,0 +1,1244 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * System Control and Management Interface (SCMI) Raw mode support + * + * Copyright (C) 2022 ARM Ltd. + */ +/** + * DOC: Theory of operation + * + * When enabled the SCMI Raw mode support exposes a userspace API which allows + * to send and receive SCMI commands, replies and notifications from a user + * application through injection and snooping of bare SCMI messages in binary + * little-endian format. + * + * Such injected SCMI transactions will then be routed through the SCMI core + * stack towards the SCMI backend server using whatever SCMI transport is + * currently configured on the system under test. + * + * It is meant to help in running any sort of SCMI backend server testing, no + * matter where the server is placed, as long as it is normally reachable via + * the transport configured on the system. + * + * It is activated by a Kernel configuration option since it is NOT meant to + * be used in production but only during development and in CI deployments. + * + * In order to avoid possible interferences between the SCMI Raw transactions + * originated from a test-suite and the normal operations of the SCMI drivers, + * when Raw mode is enabled, by default, all the regular SCMI drivers are + * inhibited. + * + * The exposed API is as follows: + * + * /sys/kernel/debug/scmi_raw/ + * |-- errors + * |-- message + * |-- message_async + * |-- notification + * |-- reset + * |-- transport_max_msg_size + * |-- transport_rx_timeout_ms + * |-- transport_tx_max_msg + * + * where: + * + * - errors: used to read back timed-out and unexpected replies + * - message*: used to send sync/async commands and read back immediate and + * delayed reponses (if any) + * - notification: used to read any notification being emitted by the system + * (if previously enabled by the user app) + * - reset: used to flush the queues of messages (of any kind) still pending + * to be read; this is useful at test-suite start/stop to get + * rid of any unread messages from the previous run. + * - transport*: a bunch of configurations useful to setup the user + * application expectations in terms of timeouts and message + * characteristics. + * + * Each write to the message* entries causes one command request to be built + * and sent while the replies or delayed response are read back from those same + * entries one message at time (receiving an EOF at each message boundary). + * + * The user application running the test is in charge of handling timeouts + * on replies and properly choosing SCMI sequence numbers for the outgoing + * requests (using the same sequence number is supported but discouraged). + * + * Injection of multiple in-flight requests is supported as long as the user + * application uses properly distinct sequence numbers for concurrent requests + * and takes care to properly manage all the related issues about concurrency + * and command/reply pairing. Keep in mind that, anyway, the real level of + * parallelism attainable in such scenario is dependent on the characteristics + * of the underlying transport being used. + * + * Since the SCMI core regular stack is partially used to deliver and collect + * the messages, late replies arrived after timeouts and any other sort of + * unexpected message can be identified by the SCMI core as usual and they will + * be reported as messages under "errors" for later analysis. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" + +#include "raw_mode.h" + +#include + +#define SCMI_XFER_RAW_MAX_RETRIES 10 + +/** + * struct scmi_raw_mode_info - Structure holding SCMI Raw instance data + * + * @handle: Pointer to SCMI entity handle to use + * @desc: Pointer to the transport descriptor to use + * @tx_max_msg: Maximum number of concurrent TX in-flight messages + * @free_raw_bufs: An array of freelists heads used to keep unused raw buffers + * @free_bufs_lock: Spinlocks used to protect access to each @free_raw_bufs + * @msg_q: An array of lists to queue snooped messages waiting to be read out + * @msg_q_lock: Spinlocks used to protect access to each @msg_q + * @wqs: An array of waitqueues used to wait and poll on related @msg_q + * @free_waiters: Head of freelist for unused waiters + * @free_mtx: A mutex to protect the waiters freelist + * @active_waiters: Head of list for currently active and used waiters + * @active_mtx: A mutex to protect the active waiters list + * @waiters_work: A work descriptor to be used with the workqueue machinery + * @wait_wq: A workqueue reference to the created workqueue + * @dentry: Top debugfs root dentry for SCMI Raw + * @gid: A group ID used for devres accounting + * + * Note that this descriptor is passed back to the core after SCMI Raw is + * initialized as an opaque handle to use by subsequent SCMI Raw call hooks. + * + */ +struct scmi_raw_mode_info { + const struct scmi_handle *handle; + const struct scmi_desc *desc; + int tx_max_msg; + struct list_head free_raw_bufs[SCMI_RAW_MAX_QUEUE]; + /* Protect free_raw_bufs[] lists */ + spinlock_t free_bufs_lock[SCMI_RAW_MAX_QUEUE]; + struct list_head msg_q[SCMI_RAW_MAX_QUEUE]; + /* Protect msg_q[] lists */ + spinlock_t msg_q_lock[SCMI_RAW_MAX_QUEUE]; + wait_queue_head_t wqs[SCMI_RAW_MAX_QUEUE]; + struct list_head free_waiters; + /* Protect free_waiters list */ + struct mutex free_mtx; + struct list_head active_waiters; + /* Protect active_waiters list */ + struct mutex active_mtx; + struct work_struct waiters_work; + struct workqueue_struct *wait_wq; + struct dentry *dentry; + void *gid; +}; + +/** + * struct scmi_xfer_raw_waiter - Structure to describe an xfer to be waited for + * + * @start_jiffies: The timestamp in jiffies of when this structure was queued. + * @cinfo: A reference to the channel to use for this transaction + * @xfer: A reference to the xfer to be waited for + * @async_response: A completion to be, optionally, used for async waits: it + * will be setup by @scmi_do_xfer_raw_start, if needed, to be + * pointed at by xfer->async_done. + * @node: A list node. + */ +struct scmi_xfer_raw_waiter { + unsigned long start_jiffies; + struct scmi_chan_info *cinfo; + struct scmi_xfer *xfer; + struct completion async_response; + struct list_head node; +}; + +/** + * struct scmi_raw_buffer - Structure to hold a full SCMI message + * + * @max_len: The maximum allowed message size (header included) that can be + * stored into @msg + * @msg: A message buffer used to collect a full message grabbed from an xfer. + * @node: A list node. + */ +struct scmi_raw_buffer { + size_t max_len; + struct scmi_msg msg; + struct list_head node; +}; + +/** + * struct scmi_dbg_raw_data - Structure holding data needed by the debugfs + * layer + * + * @raw: A reference to the Raw instance. + * @tx: A message buffer used to collect TX message on write. + * @tx_size: The effective size of the TX message. + * @tx_req_size: The final expected size of the complete TX message. + * @rx: A message buffer to collect RX message on read. + * @rx_size: The effective size of the RX message. + */ +struct scmi_dbg_raw_data { + struct scmi_raw_mode_info *raw; + struct scmi_msg tx; + size_t tx_size; + size_t tx_req_size; + struct scmi_msg rx; + size_t rx_size; +}; + +static struct scmi_raw_buffer * +scmi_raw_buffer_get(struct scmi_raw_mode_info *raw, unsigned int idx) +{ + unsigned long flags; + struct scmi_raw_buffer *rb = NULL; + struct list_head *head = &raw->free_raw_bufs[idx]; + + spin_lock_irqsave(&raw->free_bufs_lock[idx], flags); + if (!list_empty(head)) { + rb = list_first_entry(head, struct scmi_raw_buffer, node); + list_del_init(&rb->node); + } + spin_unlock_irqrestore(&raw->free_bufs_lock[idx], flags); + + return rb; +} + +static void scmi_raw_buffer_put(struct scmi_raw_mode_info *raw, + struct scmi_raw_buffer *rb, unsigned int idx) +{ + unsigned long flags; + + /* Reset to full buffer length */ + rb->msg.len = rb->max_len; + + spin_lock_irqsave(&raw->free_bufs_lock[idx], flags); + list_add_tail(&rb->node, &raw->free_raw_bufs[idx]); + spin_unlock_irqrestore(&raw->free_bufs_lock[idx], flags); +} + +static void scmi_raw_buffer_enqueue(struct scmi_raw_mode_info *raw, + struct scmi_raw_buffer *rb, + unsigned int idx) +{ + unsigned long flags; + + spin_lock_irqsave(&raw->msg_q_lock[idx], flags); + list_add_tail(&rb->node, &raw->msg_q[idx]); + spin_unlock_irqrestore(&raw->msg_q_lock[idx], flags); + + wake_up_interruptible(&raw->wqs[idx]); +} + +static struct scmi_raw_buffer * +scmi_raw_buffer_dequeue(struct scmi_raw_mode_info *raw, unsigned int idx) +{ + unsigned long flags; + struct scmi_raw_buffer *rb = NULL; + + spin_lock_irqsave(&raw->msg_q_lock[idx], flags); + if (!list_empty(&raw->msg_q[idx])) { + rb = list_first_entry(&raw->msg_q[idx], + struct scmi_raw_buffer, node); + list_del_init(&rb->node); + } + spin_unlock_irqrestore(&raw->msg_q_lock[idx], flags); + + return rb; +} + +static void scmi_raw_buffer_queue_flush(struct scmi_raw_mode_info *raw, + unsigned int idx) +{ + struct scmi_raw_buffer *rb; + + do { + rb = scmi_raw_buffer_dequeue(raw, idx); + if (rb) + scmi_raw_buffer_put(raw, rb, idx); + } while (rb); +} + +static struct scmi_xfer_raw_waiter * +scmi_xfer_raw_waiter_get(struct scmi_raw_mode_info *raw, struct scmi_xfer *xfer, + struct scmi_chan_info *cinfo, bool async) +{ + struct scmi_xfer_raw_waiter *rw = NULL; + + mutex_lock(&raw->free_mtx); + if (!list_empty(&raw->free_waiters)) { + rw = list_first_entry(&raw->free_waiters, + struct scmi_xfer_raw_waiter, node); + list_del_init(&rw->node); + + if (async) { + reinit_completion(&rw->async_response); + xfer->async_done = &rw->async_response; + } + + rw->cinfo = cinfo; + rw->xfer = xfer; + } + mutex_unlock(&raw->free_mtx); + + return rw; +} + +static void scmi_xfer_raw_waiter_put(struct scmi_raw_mode_info *raw, + struct scmi_xfer_raw_waiter *rw) +{ + if (rw->xfer) { + rw->xfer->async_done = NULL; + rw->xfer = NULL; + } + + mutex_lock(&raw->free_mtx); + list_add_tail(&rw->node, &raw->free_waiters); + mutex_unlock(&raw->free_mtx); +} + +static void scmi_xfer_raw_waiter_enqueue(struct scmi_raw_mode_info *raw, + struct scmi_xfer_raw_waiter *rw) +{ + /* A timestamp for the deferred worker to know how much this has aged */ + rw->start_jiffies = jiffies; + + trace_scmi_xfer_response_wait(rw->xfer->transfer_id, rw->xfer->hdr.id, + rw->xfer->hdr.protocol_id, + rw->xfer->hdr.seq, + raw->desc->max_rx_timeout_ms, + rw->xfer->hdr.poll_completion); + + mutex_lock(&raw->active_mtx); + list_add_tail(&rw->node, &raw->active_waiters); + mutex_unlock(&raw->active_mtx); + + /* kick waiter work */ + queue_work(raw->wait_wq, &raw->waiters_work); +} + +static struct scmi_xfer_raw_waiter * +scmi_xfer_raw_waiter_dequeue(struct scmi_raw_mode_info *raw) +{ + struct scmi_xfer_raw_waiter *rw = NULL; + + mutex_lock(&raw->active_mtx); + if (!list_empty(&raw->active_waiters)) { + rw = list_first_entry(&raw->active_waiters, + struct scmi_xfer_raw_waiter, node); + list_del_init(&rw->node); + } + mutex_unlock(&raw->active_mtx); + + return rw; +} + +/** + * scmi_xfer_raw_worker - Work function to wait for Raw xfers completions + * + * @work: A reference to the work. + * + * In SCMI Raw mode, once a user-provided injected SCMI message is sent, we + * cannot wait to receive its response (if any) in the context of the injection + * routines so as not to leave the userspace write syscall, which delivered the + * SCMI message to send, pending till eventually a reply is received. + * Userspace should and will poll/wait instead on the read syscalls which will + * be in charge of reading a received reply (if any). + * + * Even though reply messages are collected and reported into the SCMI Raw layer + * on the RX path, nonetheless we have to properly wait for their completion as + * usual (and async_completion too if needed) in order to properly release the + * xfer structure at the end: to do this out of the context of the write/send + * these waiting jobs are delegated to this deferred worker. + * + * Any sent xfer, to be waited for, is timestamped and queued for later + * consumption by this worker: queue aging is accounted for while choosing a + * timeout for the completion, BUT we do not really care here if we end up + * accidentally waiting for a bit too long. + */ +static void scmi_xfer_raw_worker(struct work_struct *work) +{ + struct scmi_raw_mode_info *raw; + struct device *dev; + unsigned long max_tmo; + + raw = container_of(work, struct scmi_raw_mode_info, waiters_work); + dev = raw->handle->dev; + max_tmo = msecs_to_jiffies(raw->desc->max_rx_timeout_ms); + + do { + int ret = 0; + unsigned int timeout_ms; + unsigned long aging; + struct scmi_xfer *xfer; + struct scmi_xfer_raw_waiter *rw; + struct scmi_chan_info *cinfo; + + rw = scmi_xfer_raw_waiter_dequeue(raw); + if (!rw) + return; + + cinfo = rw->cinfo; + xfer = rw->xfer; + /* + * Waiters are queued by wait-deadline at the end, so some of + * them could have been already expired when processed, BUT we + * have to check the completion status anyway just in case a + * virtually expired (aged) transaction was indeed completed + * fine and we'll have to wait for the asynchronous part (if + * any): for this reason a 1 ms timeout is used for already + * expired/aged xfers. + */ + aging = jiffies - rw->start_jiffies; + timeout_ms = max_tmo > aging ? + jiffies_to_msecs(max_tmo - aging) : 1; + + ret = scmi_xfer_raw_wait_for_message_response(cinfo, xfer, + timeout_ms); + if (!ret && xfer->hdr.status) + ret = scmi_to_linux_errno(xfer->hdr.status); + + if (raw->desc->ops->mark_txdone) + raw->desc->ops->mark_txdone(rw->cinfo, ret, xfer); + + trace_scmi_xfer_end(xfer->transfer_id, xfer->hdr.id, + xfer->hdr.protocol_id, xfer->hdr.seq, ret); + + /* Wait also for an async delayed response if needed */ + if (!ret && xfer->async_done) { + unsigned long tmo = msecs_to_jiffies(SCMI_MAX_RESPONSE_TIMEOUT); + + if (!wait_for_completion_timeout(xfer->async_done, tmo)) + dev_err(dev, + "timed out in RAW delayed resp - HDR:%08X\n", + pack_scmi_header(&xfer->hdr)); + } + + /* Release waiter and xfer */ + scmi_xfer_raw_put(raw->handle, xfer); + scmi_xfer_raw_waiter_put(raw, rw); + } while (1); +} + +static void scmi_xfer_raw_reset(struct scmi_raw_mode_info *raw) +{ + int i; + + dev_info(raw->handle->dev, "Resetting SCMI Raw stack.\n"); + + for (i = 0; i < SCMI_RAW_MAX_QUEUE; i++) + scmi_raw_buffer_queue_flush(raw, i); +} + +/** + * scmi_xfer_raw_get_init - An helper to build a valid xfer from the provided + * bare SCMI message. + * + * @raw: A reference to the Raw instance. + * @buf: A buffer containing the whole SCMI message to send (including the + * header) in little-endian binary formmat. + * @len: Length of the message in @buf. + * @p: A pointer to return the initialized Raw xfer. + * + * After an xfer is picked from the TX pool and filled in with the message + * content, the xfer is registered as pending with the core in the usual way + * using the original sequence number provided by the user with the message. + * + * Note that, in case the testing user application is NOT using distinct + * sequence-numbers between successive SCMI messages such registration could + * fail temporarily if the previous message, using the same sequence number, + * had still not released; in such a case we just wait and retry. + * + * Return: 0 on Success + */ +static int scmi_xfer_raw_get_init(struct scmi_raw_mode_info *raw, void *buf, + size_t len, struct scmi_xfer **p) +{ + u32 msg_hdr; + size_t tx_size; + struct scmi_xfer *xfer; + int ret, retry = SCMI_XFER_RAW_MAX_RETRIES; + struct device *dev = raw->handle->dev; + + if (!buf || len < sizeof(u32)) + return -EINVAL; + + tx_size = len - sizeof(u32); + /* Ensure we have sane transfer sizes */ + if (tx_size > raw->desc->max_msg_size) + return -ERANGE; + + xfer = scmi_xfer_raw_get(raw->handle); + if (IS_ERR(xfer)) { + dev_warn(dev, "RAW - Cannot get a free RAW xfer !\n"); + return PTR_ERR(xfer); + } + + /* Build xfer from the provided SCMI bare LE message */ + msg_hdr = le32_to_cpu(*((__le32 *)buf)); + unpack_scmi_header(msg_hdr, &xfer->hdr); + xfer->hdr.seq = (u16)MSG_XTRACT_TOKEN(msg_hdr); + /* Polling not supported */ + xfer->hdr.poll_completion = false; + xfer->hdr.status = SCMI_SUCCESS; + xfer->tx.len = tx_size; + xfer->rx.len = raw->desc->max_msg_size; + /* Clear the whole TX buffer */ + memset(xfer->tx.buf, 0x00, raw->desc->max_msg_size); + if (xfer->tx.len) + memcpy(xfer->tx.buf, (u8 *)buf + sizeof(msg_hdr), xfer->tx.len); + *p = xfer; + + /* + * In flight registration can temporarily fail in case of Raw messages + * if the user injects messages without using monotonically increasing + * sequence numbers since, in Raw mode, the xfer (and the token) is + * finally released later by a deferred worker. Just retry for a while. + */ + do { + ret = scmi_xfer_raw_inflight_register(raw->handle, xfer); + if (ret) { + dev_dbg(dev, + "...retrying[%d] inflight registration\n", + retry); + msleep(raw->desc->max_rx_timeout_ms / + SCMI_XFER_RAW_MAX_RETRIES); + } + } while (ret && --retry); + + if (ret) { + dev_warn(dev, + "RAW - Could NOT register xfer %d in-flight HDR:0x%08X\n", + xfer->hdr.seq, msg_hdr); + scmi_xfer_raw_put(raw->handle, xfer); + } + + return ret; +} + +/** + * scmi_do_xfer_raw_start - An helper to send a valid raw xfer + * + * @raw: A reference to the Raw instance. + * @xfer: The xfer to send + * @async: A flag stating if an asynchronous command is required. + * + * This function send a previously built raw xfer using an appropriate channel + * and queues the related waiting work. + * + * Note that we need to know explicitly if the required command is meant to be + * asynchronous in kind since we have to properly setup the waiter. + * (and deducing this from the payload is weak and do not scale given there is + * NOT a common header-flag stating if the command is asynchronous or not) + * + * Return: 0 on Success + */ +static int scmi_do_xfer_raw_start(struct scmi_raw_mode_info *raw, + struct scmi_xfer *xfer, bool async) +{ + int ret; + struct scmi_chan_info *cinfo; + struct scmi_xfer_raw_waiter *rw; + struct device *dev = raw->handle->dev; + + cinfo = scmi_xfer_raw_channel_get(raw->handle, xfer->hdr.protocol_id); + if (IS_ERR(cinfo)) + return PTR_ERR(cinfo); + + rw = scmi_xfer_raw_waiter_get(raw, xfer, cinfo, async); + if (!rw) { + dev_warn(dev, "RAW - Cannot get a free waiter !\n"); + return -ENOMEM; + } + + /* True ONLY if also supported by transport. */ + if (is_polling_enabled(cinfo, raw->desc)) + xfer->hdr.poll_completion = true; + + reinit_completion(&xfer->done); + /* Make sure xfer state update is visible before sending */ + smp_store_mb(xfer->state, SCMI_XFER_SENT_OK); + + trace_scmi_xfer_begin(xfer->transfer_id, xfer->hdr.id, + xfer->hdr.protocol_id, xfer->hdr.seq, + xfer->hdr.poll_completion); + + ret = raw->desc->ops->send_message(rw->cinfo, xfer); + if (ret) { + dev_err(dev, "Failed to send RAW message %d\n", ret); + scmi_xfer_raw_waiter_put(raw, rw); + return ret; + } + + trace_scmi_msg_dump(xfer->hdr.protocol_id, xfer->hdr.id, "CMND", + xfer->hdr.seq, xfer->hdr.status, + xfer->tx.buf, xfer->tx.len); + + scmi_xfer_raw_waiter_enqueue(raw, rw); + + return ret; +} + +/** + * scmi_raw_message_send - An helper to build and send an SCMI command using + * the provided SCMI bare message buffer + * + * @raw: A reference to the Raw instance. + * @buf: A buffer containing the whole SCMI message to send (including the + * header) in little-endian binary format. + * @len: Length of the message in @buf. + * @async: A flag stating if an asynchronous command is required. + * + * Return: 0 on Success + */ +static int scmi_raw_message_send(struct scmi_raw_mode_info *raw, + void *buf, size_t len, bool async) +{ + int ret; + struct scmi_xfer *xfer; + + ret = scmi_xfer_raw_get_init(raw, buf, len, &xfer); + if (ret) + return ret; + + ret = scmi_do_xfer_raw_start(raw, xfer, async); + if (ret) + scmi_xfer_raw_put(raw->handle, xfer); + + return ret; +} + +static struct scmi_raw_buffer * +scmi_raw_message_dequeue(struct scmi_raw_mode_info *raw, unsigned int idx, + bool o_nonblock) +{ + unsigned long flags; + + spin_lock_irqsave(&raw->msg_q_lock[idx], flags); + while (list_empty(&raw->msg_q[idx])) { + spin_unlock_irqrestore(&raw->msg_q_lock[idx], flags); + + if (o_nonblock) + return ERR_PTR(-EAGAIN); + + if (wait_event_interruptible(raw->wqs[idx], + !list_empty(&raw->msg_q[idx]))) + return ERR_PTR(-ERESTARTSYS); + + spin_lock_irqsave(&raw->msg_q_lock[idx], flags); + } + spin_unlock_irqrestore(&raw->msg_q_lock[idx], flags); + + return scmi_raw_buffer_dequeue(raw, idx); +} + +/** + * scmi_raw_message_receive - An helper to dequeue and report the next + * available enqueued raw message payload that has been collected. + * + * @raw: A reference to the Raw instance. + * @buf: A buffer to get hold of the whole SCMI message received and represented + * in little-endian binary format. + * @len: Length of @buf. + * @size: The effective size of the message copied into @buf + * @idx: The index of the queue to pick the next queued message from. + * @o_nonblock: A flag to request a non-blocking message dequeue. + * + * Return: 0 on Success + */ +static int scmi_raw_message_receive(struct scmi_raw_mode_info *raw, + void *buf, size_t len, size_t *size, + unsigned int idx, + bool o_nonblock) +{ + int ret = 0; + struct scmi_raw_buffer *rb; + + rb = scmi_raw_message_dequeue(raw, idx, o_nonblock); + if (IS_ERR(rb)) { + dev_dbg(raw->handle->dev, "RAW - No message available!\n"); + return PTR_ERR(rb); + } + + if (rb->msg.len <= len) { + memcpy(buf, rb->msg.buf, rb->msg.len); + *size = rb->msg.len; + } else { + ret = -ENOSPC; + } + + scmi_raw_buffer_put(raw, rb, idx); + + return ret; +} + +/* SCMI Raw debugfs helpers */ + +static ssize_t scmi_dbg_raw_mode_common_read(struct file *filp, + char __user *buf, + size_t count, loff_t *ppos, + unsigned int idx) +{ + ssize_t cnt; + struct scmi_dbg_raw_data *rd = filp->private_data; + + if (!rd->rx_size) { + int ret; + + ret = scmi_raw_message_receive(rd->raw, rd->rx.buf, rd->rx.len, + &rd->rx_size, idx, + filp->f_flags & O_NONBLOCK); + if (ret) { + rd->rx_size = 0; + return ret; + } + + /* Reset any previous filepos change, including writes */ + *ppos = 0; + } else if (*ppos == rd->rx_size) { + /* Return EOF once all the message has been read-out */ + rd->rx_size = 0; + return 0; + } + + cnt = simple_read_from_buffer(buf, count, ppos, + rd->rx.buf, rd->rx_size); + + return cnt; +} + +static ssize_t scmi_dbg_raw_mode_common_write(struct file *filp, + const char __user *buf, + size_t count, loff_t *ppos, + bool async) +{ + int ret; + struct scmi_dbg_raw_data *rd = filp->private_data; + + if (count > rd->tx.len - rd->tx_size) + return -ENOSPC; + + /* On first write attempt @count carries the total full message size. */ + if (!rd->tx_size) + rd->tx_req_size = count; + + /* + * Gather a full message, possibly across multiple interrupted wrrtes, + * before sending it with a single RAW xfer. + */ + if (rd->tx_size < rd->tx_req_size) { + size_t cnt; + + cnt = simple_write_to_buffer(rd->tx.buf, rd->tx.len, ppos, + buf, count); + rd->tx_size += cnt; + if (cnt < count) + return cnt; + } + + ret = scmi_raw_message_send(rd->raw, rd->tx.buf, rd->tx_size, async); + + /* Reset ppos for next message ... */ + rd->tx_size = 0; + + return ret ?: count; +} + +static __poll_t scmi_test_dbg_raw_common_poll(struct file *filp, + struct poll_table_struct *wait, + unsigned int idx) +{ + unsigned long flags; + struct scmi_dbg_raw_data *rd = filp->private_data; + __poll_t mask = 0; + + poll_wait(filp, &rd->raw->wqs[idx], wait); + + spin_lock_irqsave(&rd->raw->msg_q_lock[idx], flags); + if (!list_empty(&rd->raw->msg_q[idx])) + mask = EPOLLIN | EPOLLRDNORM; + spin_unlock_irqrestore(&rd->raw->msg_q_lock[idx], flags); + + return mask; +} + +static ssize_t scmi_dbg_raw_mode_message_read(struct file *filp, + char __user *buf, + size_t count, loff_t *ppos) +{ + return scmi_dbg_raw_mode_common_read(filp, buf, count, ppos, + SCMI_RAW_REPLY_QUEUE); +} + +static ssize_t scmi_dbg_raw_mode_message_write(struct file *filp, + const char __user *buf, + size_t count, loff_t *ppos) +{ + return scmi_dbg_raw_mode_common_write(filp, buf, count, ppos, false); +} + +static __poll_t scmi_dbg_raw_mode_message_poll(struct file *filp, + struct poll_table_struct *wait) +{ + return scmi_test_dbg_raw_common_poll(filp, wait, SCMI_RAW_REPLY_QUEUE); +} + +static int scmi_dbg_raw_mode_open(struct inode *inode, struct file *filp) +{ + struct scmi_raw_mode_info *raw; + struct scmi_dbg_raw_data *rd; + + if (!inode->i_private) + return -ENODEV; + + raw = inode->i_private; + rd = kzalloc(sizeof(*rd), GFP_KERNEL); + if (!rd) + return -ENOMEM; + + rd->rx.len = raw->desc->max_msg_size + sizeof(u32); + rd->rx.buf = kzalloc(rd->rx.len, GFP_KERNEL); + if (!rd->rx.buf) { + kfree(rd); + return -ENOMEM; + } + + rd->tx.len = raw->desc->max_msg_size + sizeof(u32); + rd->tx.buf = kzalloc(rd->tx.len, GFP_KERNEL); + if (!rd->tx.buf) { + kfree(rd->rx.buf); + kfree(rd); + return -ENOMEM; + } + + rd->raw = raw; + filp->private_data = rd; + + return 0; +} + +static int scmi_dbg_raw_mode_release(struct inode *inode, struct file *filp) +{ + struct scmi_dbg_raw_data *rd = filp->private_data; + + kfree(rd->rx.buf); + kfree(rd->tx.buf); + kfree(rd); + + return 0; +} + +static ssize_t scmi_dbg_raw_mode_reset_write(struct file *filp, + const char __user *buf, + size_t count, loff_t *ppos) +{ + struct scmi_dbg_raw_data *rd = filp->private_data; + + scmi_xfer_raw_reset(rd->raw); + + return count; +} + +static const struct file_operations scmi_dbg_raw_mode_reset_fops = { + .open = scmi_dbg_raw_mode_open, + .release = scmi_dbg_raw_mode_release, + .write = scmi_dbg_raw_mode_reset_write, + .owner = THIS_MODULE, +}; + +static const struct file_operations scmi_dbg_raw_mode_message_fops = { + .open = scmi_dbg_raw_mode_open, + .release = scmi_dbg_raw_mode_release, + .read = scmi_dbg_raw_mode_message_read, + .write = scmi_dbg_raw_mode_message_write, + .poll = scmi_dbg_raw_mode_message_poll, + .owner = THIS_MODULE, +}; + +static ssize_t scmi_dbg_raw_mode_message_async_write(struct file *filp, + const char __user *buf, + size_t count, loff_t *ppos) +{ + return scmi_dbg_raw_mode_common_write(filp, buf, count, ppos, true); +} + +static const struct file_operations scmi_dbg_raw_mode_message_async_fops = { + .open = scmi_dbg_raw_mode_open, + .release = scmi_dbg_raw_mode_release, + .read = scmi_dbg_raw_mode_message_read, + .write = scmi_dbg_raw_mode_message_async_write, + .poll = scmi_dbg_raw_mode_message_poll, + .owner = THIS_MODULE, +}; + +static ssize_t scmi_test_dbg_raw_mode_notif_read(struct file *filp, + char __user *buf, + size_t count, loff_t *ppos) +{ + return scmi_dbg_raw_mode_common_read(filp, buf, count, ppos, + SCMI_RAW_NOTIF_QUEUE); +} + +static __poll_t scmi_test_dbg_raw_mode_notif_poll(struct file *filp, + struct poll_table_struct *wait) +{ + return scmi_test_dbg_raw_common_poll(filp, wait, SCMI_RAW_NOTIF_QUEUE); +} + +static const struct file_operations scmi_dbg_raw_mode_notification_fops = { + .open = scmi_dbg_raw_mode_open, + .release = scmi_dbg_raw_mode_release, + .read = scmi_test_dbg_raw_mode_notif_read, + .poll = scmi_test_dbg_raw_mode_notif_poll, + .owner = THIS_MODULE, +}; + +static ssize_t scmi_test_dbg_raw_mode_errors_read(struct file *filp, + char __user *buf, + size_t count, loff_t *ppos) +{ + return scmi_dbg_raw_mode_common_read(filp, buf, count, ppos, + SCMI_RAW_ERRS_QUEUE); +} + +static __poll_t scmi_test_dbg_raw_mode_errors_poll(struct file *filp, + struct poll_table_struct *wait) +{ + return scmi_test_dbg_raw_common_poll(filp, wait, SCMI_RAW_ERRS_QUEUE); +} + +static const struct file_operations scmi_dbg_raw_mode_errors_fops = { + .open = scmi_dbg_raw_mode_open, + .release = scmi_dbg_raw_mode_release, + .read = scmi_test_dbg_raw_mode_errors_read, + .poll = scmi_test_dbg_raw_mode_errors_poll, + .owner = THIS_MODULE, +}; + +static int scmi_xfer_raw_free_bufs_init(struct scmi_raw_mode_info *raw, int idx) +{ + int i; + struct scmi_raw_buffer *rb; + struct device *dev = raw->handle->dev; + + rb = devm_kcalloc(dev, raw->tx_max_msg, sizeof(*rb), GFP_KERNEL); + if (!rb) + return -ENOMEM; + + spin_lock_init(&raw->free_bufs_lock[idx]); + INIT_LIST_HEAD(&raw->free_raw_bufs[idx]); + for (i = 0; i < raw->tx_max_msg; i++, rb++) { + rb->max_len = raw->desc->max_msg_size + sizeof(u32); + rb->msg.buf = devm_kzalloc(dev, rb->max_len, GFP_KERNEL); + if (!rb->msg.buf) + return -ENOMEM; + scmi_raw_buffer_put(raw, rb, idx); + } + + spin_lock_init(&raw->msg_q_lock[idx]); + INIT_LIST_HEAD(&raw->msg_q[idx]); + init_waitqueue_head(&raw->wqs[idx]); + + return 0; +} + +static int scmi_xfer_raw_worker_init(struct scmi_raw_mode_info *raw) +{ + int i; + struct scmi_xfer_raw_waiter *rw; + struct device *dev = raw->handle->dev; + + rw = devm_kcalloc(dev, raw->tx_max_msg, sizeof(*rw), GFP_KERNEL); + if (!rw) + return -ENOMEM; + + raw->wait_wq = alloc_workqueue("scmi-raw-wait-wq-%d", + WQ_UNBOUND | WQ_FREEZABLE | + WQ_HIGHPRI, WQ_SYSFS, 0); + if (!raw->wait_wq) + return -ENOMEM; + + mutex_init(&raw->free_mtx); + INIT_LIST_HEAD(&raw->free_waiters); + mutex_init(&raw->active_mtx); + INIT_LIST_HEAD(&raw->active_waiters); + + for (i = 0; i < raw->tx_max_msg; i++, rw++) { + init_completion(&rw->async_response); + scmi_xfer_raw_waiter_put(raw, rw); + } + INIT_WORK(&raw->waiters_work, scmi_xfer_raw_worker); + + return 0; +} + +static int scmi_raw_mode_setup(struct scmi_raw_mode_info *raw) +{ + int ret, idx; + void *gid; + struct device *dev = raw->handle->dev; + + gid = devres_open_group(dev, NULL, GFP_KERNEL); + if (!gid) + return -ENOMEM; + + for (idx = 0; idx < SCMI_RAW_MAX_QUEUE; idx++) { + ret = scmi_xfer_raw_free_bufs_init(raw, idx); + if (ret) + goto err; + } + + ret = scmi_xfer_raw_worker_init(raw); + if (ret) + goto err; + + devres_close_group(dev, gid); + raw->gid = gid; + + return 0; + +err: + devres_release_group(dev, gid); + return ret; +} + +/** + * scmi_raw_mode_init - Function to initialize the SCMI Raw stack + * + * @handle: Pointer to SCMI entity handle + * @desc: Reference to the transport operations + * @tx_max_msg: Max number of in-flight messages allowed by the transport + * + * This function prepare the SCMI Raw stack and creates the debugfs API. + * + * Return: An opaque handle to the Raw instance on Success, an ERR_PTR otherwise + */ +void *scmi_raw_mode_init(const struct scmi_handle *handle, + const struct scmi_desc *desc, int tx_max_msg) +{ + int ret; + struct scmi_raw_mode_info *raw; + struct device *dev; + + if (!handle || !desc) + return ERR_PTR(-EINVAL); + + dev = handle->dev; + raw = devm_kzalloc(dev, sizeof(*raw), GFP_KERNEL); + if (!raw) + return ERR_PTR(-ENOMEM); + + raw->handle = handle; + raw->desc = desc; + raw->tx_max_msg = tx_max_msg; + + ret = scmi_raw_mode_setup(raw); + if (ret) { + devm_kfree(dev, raw); + return ERR_PTR(ret); + } + + raw->dentry = debugfs_create_dir("scmi_raw", NULL); + if (IS_ERR(raw->dentry)) { + ret = PTR_ERR(raw->dentry); + devres_release_group(dev, raw->gid); + devm_kfree(dev, raw); + return ERR_PTR(ret); + } + + debugfs_create_file("reset", 0200, raw->dentry, raw, + &scmi_dbg_raw_mode_reset_fops); + + debugfs_create_u32("transport_rx_timeout_ms", 0400, raw->dentry, + (u32 *)&raw->desc->max_rx_timeout_ms); + + debugfs_create_u32("transport_max_msg_size", 0400, raw->dentry, + (u32 *)&raw->desc->max_msg_size); + + debugfs_create_u32("transport_tx_max_msg", 0400, raw->dentry, + (u32 *)&raw->tx_max_msg); + + debugfs_create_file("message", 0600, raw->dentry, raw, + &scmi_dbg_raw_mode_message_fops); + + debugfs_create_file("message_async", 0600, raw->dentry, raw, + &scmi_dbg_raw_mode_message_async_fops); + + debugfs_create_file("notification", 0400, raw->dentry, raw, + &scmi_dbg_raw_mode_notification_fops); + + debugfs_create_file("errors", 0400, raw->dentry, raw, + &scmi_dbg_raw_mode_errors_fops); + + return raw; +} + +/** + * scmi_raw_mode_cleanup - Function to cleanup the SCMI Raw stack + * + * @r: An opaque handle to an initialized SCMI Raw instance + */ +void scmi_raw_mode_cleanup(void *r) +{ + struct scmi_raw_mode_info *raw = r; + + if (!raw) + return; + + debugfs_remove_recursive(raw->dentry); + + cancel_work_sync(&raw->waiters_work); + destroy_workqueue(raw->wait_wq); +} + +static int scmi_xfer_raw_collect(struct scmi_xfer *xfer, + void *msg, size_t *msg_len) +{ + __le32 *m; + size_t msg_size; + + if (!xfer || !msg || !msg_len) + return -EINVAL; + + /* Account for hdr ...*/ + msg_size = xfer->rx.len + sizeof(u32); + /* ... and status if needed */ + if (xfer->hdr.type != MSG_TYPE_NOTIFICATION) + msg_size += sizeof(u32); + + if (msg_size > *msg_len) + return -ENOSPC; + + m = msg; + *m = cpu_to_le32(pack_scmi_header(&xfer->hdr)); + if (xfer->hdr.type != MSG_TYPE_NOTIFICATION) + *++m = cpu_to_le32(xfer->hdr.status); + + memcpy(++m, xfer->rx.buf, xfer->rx.len); + + *msg_len = msg_size; + + return 0; +} + +/** + * scmi_raw_message_report - Helper to report back valid reponses/notifications + * to raw message requests. + * + * @r: An opaque reference to the raw instance configuration + * @xfer: The xfer containing the message to be reported + * @idx: The index of the queue. + * + * If Raw mode is enabled, this is called from the SCMI core on the regular RX + * path to save and enqueue the response/notification payload carried by this + * xfer into a dedicated scmi_raw_buffer for later consumption by the user. + * + * This way the caller can free the related xfer immediately afterwards and the + * user can read back the raw message payload at its own pace (if ever) without + * holding an xfer for too long. + */ +void scmi_raw_message_report(void *r, struct scmi_xfer *xfer, unsigned int idx) +{ + int ret; + struct scmi_raw_buffer *rb; + struct device *dev; + struct scmi_raw_mode_info *raw = r; + + if (!raw) + return; + + dev = raw->handle->dev; + rb = scmi_raw_buffer_get(raw, idx); + if (!rb) { + dev_warn(dev, "RAW[%d] - Cannot get a free RAW buffer\n", idx); + return; + } + + ret = scmi_xfer_raw_collect(xfer, rb->msg.buf, &rb->msg.len); + if (ret) { + dev_warn(dev, "RAW - Cannot collect xfer into buffer !\n"); + scmi_raw_buffer_put(raw, rb, idx); + return; + } + + scmi_raw_buffer_enqueue(raw, rb, idx); +} + +static void scmi_xfer_raw_fill(struct scmi_raw_mode_info *raw, + struct scmi_chan_info *cinfo, + struct scmi_xfer *xfer, u32 msg_hdr) +{ + /* Unpack received HDR as it is */ + unpack_scmi_header(msg_hdr, &xfer->hdr); + xfer->hdr.seq = MSG_XTRACT_TOKEN(msg_hdr); + + memset(xfer->rx.buf, 0x00, xfer->rx.len); + + raw->desc->ops->fetch_response(cinfo, xfer); +} + +/** + * scmi_raw_error_report - Helper to report back timed-out or generally + * unexpected replies. + * + * @r: An opaque reference to the raw instance configuration + * @cinfo: A reference to the channel to use to retrieve the broken xfer + * @msg_hdr: The SCMI message header of the message to fetch and report + * @priv: Any private data related to the xfer. + * + * If Raw mode is enabled, this is called from the SCMI core on the RX path in + * case of errors to save and enqueue the bad message payload carried by the + * message that has just been received. + * + * Note that we have to manually fetch any available payload into a temporary + * xfer to be able to save and enqueue the message, since the regular RX error + * path which had called this would have not fetched the message payload having + * classified it as an error. + */ +void scmi_raw_error_report(void *r, struct scmi_chan_info *cinfo, + u32 msg_hdr, void *priv) +{ + struct scmi_xfer xfer; + struct scmi_raw_buffer *rb; + struct scmi_raw_mode_info *raw = r; + + if (!raw) + return; + + rb = scmi_raw_buffer_get(raw, SCMI_RAW_ERRS_QUEUE); + if (!rb) { + dev_warn(raw->handle->dev, + "RAW[%d] - Cannot get a free RAW buffer\n", + SCMI_RAW_ERRS_QUEUE); + return; + } + + /* Use a raw buffer to provide rx space to the temp xfer */ + xfer.rx.buf = rb->msg.buf; + /* + * Allow max_msg_size...note that allocated rx.buf length is + * max_msg_size + sizeof(u32). + */ + xfer.rx.len = raw->desc->max_msg_size; + if (priv) + /* + * Any transport-provided priv must be passed back down + * to transport + */ + smp_store_mb(xfer.priv, priv); + + scmi_xfer_raw_fill(raw, cinfo, &xfer, msg_hdr); + scmi_raw_message_report(raw, &xfer, SCMI_RAW_ERRS_QUEUE); + + scmi_raw_buffer_put(raw, rb, SCMI_RAW_ERRS_QUEUE); +} diff --git a/drivers/firmware/arm_scmi/raw_mode.h b/drivers/firmware/arm_scmi/raw_mode.h new file mode 100644 index 000000000000..e2d8672e1f8b --- /dev/null +++ b/drivers/firmware/arm_scmi/raw_mode.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * System Control and Management Interface (SCMI) Message Protocol + * Raw mode support header. + * + * Copyright (C) 2022 ARM Ltd. + */ +#ifndef _SCMI_RAW_MODE_H +#define _SCMI_RAW_MODE_H + +#include "common.h" + +enum { + SCMI_RAW_REPLY_QUEUE, + SCMI_RAW_NOTIF_QUEUE, + SCMI_RAW_ERRS_QUEUE, + SCMI_RAW_MAX_QUEUE +}; + +void *scmi_raw_mode_init(const struct scmi_handle *handle, + const struct scmi_desc *desc, int tx_max_msg); +void scmi_raw_mode_cleanup(void *raw); + +void scmi_raw_message_report(void *raw, struct scmi_xfer *xfer, + unsigned int idx); +void scmi_raw_error_report(void *raw, struct scmi_chan_info *cinfo, + u32 msg_hdr, void *priv); + +#endif /* _SCMI_RAW_MODE_H */ From patchwork Wed Oct 19 20:46:24 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 5848 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp529344wrs; Wed, 19 Oct 2022 13:53:34 -0700 (PDT) X-Google-Smtp-Source: AMsMyM500Rhs/elAlM0b3glvFwAofySlUul9dhUlvrE/e2rko/P+xetyeQKJl2Yqq34tXL5eIWe9 X-Received: by 2002:a65:4c0c:0:b0:45f:f12d:f46f with SMTP id u12-20020a654c0c000000b0045ff12df46fmr8805555pgq.579.1666212814092; Wed, 19 Oct 2022 13:53:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666212814; cv=none; d=google.com; s=arc-20160816; b=waQxhQrR1eFw0R80OLbGDnuxDN+Bygg9buy5y3UhAb1i96ZL6KbvscmYf7T7QFiNqj DTwZba5GKaFz12hGWA2Wrt/zSmxCfrqguIdE3GW9Nr3wUzuK0wEluRTp4FHvSo8CxpGf EdN6x3du62yXCLtyrabSM5Brqn5KVzF1a9DhwyzTMdC9Gt6O8beQO6CjjgBJ14dOhyrY NL9esp4E0uMdvQmWjORWC3tR2GPnRz2lvTakYOjEjgLI/mBbHgqKA1rrp+VfDPr63+3V sGcY8Sn65fs0kyxkiG1U93iqXwytjkKGv+4BFNcmibngpecFVRVquH+RSaCCTbvQdBYv wRNA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=w3gKSt4eUH8XBCbsPy2dzGb7MpmyrdEci6Re84DAPtw=; b=aVXl/Hbcf8LqUiESBInQp27u1rs2xyH0+1kO7z+ZWtOm9oFfHR89tDGuOqNkXOfAIc UvEdUgXgHB4rg7Hablsqk0r/0d//exHmDgENcVUlkr0mJ92TS96V16e1o3S9ITEDEq3j cBTGTU97TQPcSnFpNZhOuXFBFQyXOuUjBIgXE1UDX2NbNUIFWWb+pvjM6r0ZroTmEuHa +3YvBNKYoDibfFDUyV0xt20OaKf9PTiZZZKoWDApddfZHkXsQNqRsNIqF8i7g90ZTzu8 IAWezbYrFb7LXuKGyMxOOQkp4AqvT9Wzy5v6T6I5ud0ajq0PBouKA5I2JHkzn3GXJAyn 3zpQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id 190-20020a6300c7000000b0045ec918ad31si18372417pga.544.2022.10.19.13.52.47; Wed, 19 Oct 2022 13:53:34 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231651AbiJSUrl (ORCPT + 99 others); Wed, 19 Oct 2022 16:47:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38220 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231571AbiJSUrX (ORCPT ); Wed, 19 Oct 2022 16:47:23 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id DB9221BE905 for ; Wed, 19 Oct 2022 13:47:02 -0700 (PDT) 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 DC4A71A25; Wed, 19 Oct 2022 13:47:07 -0700 (PDT) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id B22693F792; Wed, 19 Oct 2022 13:46:59 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, etienne.carriere@linaro.org, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, wleavitt@marvell.com, peter.hilber@opensynergy.com, nicola.mazzucato@arm.com, tarek.el-sherbiny@arm.com, quic_kshivnan@quicinc.com, cristian.marussi@arm.com Subject: [PATCH v4 09/11] firmware: arm_scmi: Add debugfs ABI documentation for Raw mode Date: Wed, 19 Oct 2022 21:46:24 +0100 Message-Id: <20221019204626.3813043-10-cristian.marussi@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221019204626.3813043-1-cristian.marussi@arm.com> References: <20221019204626.3813043-1-cristian.marussi@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW, SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747150767918192478?= X-GMAIL-MSGID: =?utf-8?q?1747150767918192478?= Add description of the debugfs SCMI Raw ABI. Signed-off-by: Cristian Marussi --- Documentation/ABI/testing/debugfs-scmi-raw | 88 ++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 Documentation/ABI/testing/debugfs-scmi-raw diff --git a/Documentation/ABI/testing/debugfs-scmi-raw b/Documentation/ABI/testing/debugfs-scmi-raw new file mode 100644 index 000000000000..183ec678cb3e --- /dev/null +++ b/Documentation/ABI/testing/debugfs-scmi-raw @@ -0,0 +1,88 @@ +What: /sys/kernel/debug/scmi_raw/transport_max_msg_size +Date: December 2022 +KernelVersion: 6.1 +Contact: cristian.marussi@arm.com +Description: Max message size of allowed SCMI messages for the currently + configured SCMI transport. +Users: Debugging, any userspace test suite + +What: /sys/kernel/debug/scmi_raw/transport_tx_max_msg +Date: December 2022 +KernelVersion: 6.1 +Contact: cristian.marussi@arm.com +Description: Max number of concurrently allowed in-flight SCMI messages for + the currently configured SCMI transport. +Users: Debugging, any userspace test suite + +What: /sys/kernel/debug/scmi_raw/transport_rx_timeout_ms +Date: December 2022 +KernelVersion: 6.1 +Contact: cristian.marussi@arm.com +Description: Timeout in milliseconds allowed for SCMI synchronous replies + for the currently configured SCMI transport. +Users: Debugging, any userspace test suite + +What: /sys/kernel/debug/scmi_raw/message +Date: December 2022 +KernelVersion: 6.1 +Contact: cristian.marussi@arm.com +Description: SCMI Raw synchronous message injection/snooping facility; write + a complete SCMI synchronous command message (header included) + in little-endian binary format to have it sent to the configured + backend SCMI server. + Any subsequently received response can be read from this same + entry if it arrived within the configured timeout. + Each write to the entry causes one command request to be built + and sent while the replies are read back one message at time + (receiving an EOF at each message boundary). +Users: Debugging, any userspace test suite + +What: /sys/kernel/debug/scmi_raw/message_async +Date: December 2022 +KernelVersion: 6.1 +Contact: cristian.marussi@arm.com +Description: SCMI Raw asynchronous message injection/snooping facility; write + a complete SCMI asynchronous command message (header included) + in little-endian binary format to have it sent to the configured + backend SCMI server. + Any subsequently received response can be read from this same + entry if it arrived within the configured timeout. + Any additional delayed response received afterwards can be read + from this same entry too if it arrived within the configured + timeout. + Each write to the entry causes one command request to be built + and sent while the replies are read back one message at time + (receiving an EOF at each message boundary). +Users: Debugging, any userspace test suite + +What: /sys/kernel/debug/scmi_raw/errors +Date: December 2022 +KernelVersion: 6.1 +Contact: cristian.marussi@arm.com +Description: SCMI Raw message errors facility; any kind of timed-out or + generally unexpectedly received SCMI message can be read from + this entry. + Each read gives back one message at time (receiving an EOF at + each message boundary). +Users: Debugging, any userspace test suite + +What: /sys/kernel/debug/scmi_raw/notification +Date: December 2022 +KernelVersion: 6.1 +Contact: cristian.marussi@arm.com +Description: SCMI Raw notification snooping facility; any notification + emitted by the backend SCMI server can be read from this entry. + Each read gives back one message at time (receiving an EOF at + each message boundary). +Users: Debugging, any userspace test suite + +What: /sys/kernel/debug/scmi_raw/reset +Date: December 2022 +KernelVersion: 6.1 +Contact: cristian.marussi@arm.com +Description: SCMI Raw stack reset facility; writing a value to this entry + causes the internal queues of any kind of received message, + still pending to be read out, to be flushed. + Can be used to reset and clean the SCMI Raw stack between to + different test-run. +Users: Debugging, any userspace test suite From patchwork Wed Oct 19 20:46:25 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 5845 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp529144wrs; Wed, 19 Oct 2022 13:53:03 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4xhOP7eo3v1xAPImXvHhi1qhJ9m1K1Z4ZGSk+YG1dSzNyuiO6rBtcok9hmDM7J23QWw4bJ X-Received: by 2002:a17:90a:e387:b0:211:2d90:675 with SMTP id b7-20020a17090ae38700b002112d900675mr1397349pjz.66.1666212782889; Wed, 19 Oct 2022 13:53:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666212782; cv=none; d=google.com; s=arc-20160816; b=JEizu7pWRlAgjZttQhQNrjxhe3HuctTQcPiYJOs2TnNVwTHFoSfokZWvlneLuA0QAp H00xElNdZj7kWXCF07e+USXuScV/e6glIQoxAjf/4TvhK10vanSn0wE1xW9+5hT9NldI NjwYVAEVk1zxac2nZuTaZ+VQtNhmf+Q6lKbSbmUbtcbEY/VRXvzWSxmVBuSPTPnURRq6 s1v9nuTYQSqShhwhzKzx9TxIbcf19a7I8bdNjjEM9uY57yqpUOGaYf+viV2gSzLqIwD1 uTaCh8sHHDq8KURt/JkOu1Lkk3E43vpXOfXly44jeOqi59BLIeseW3+GPlTZxi4etvqm BYYQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=+HQgqLmFWEA8RFbEhIt25agn4Qcnx+daroIfFpe90n0=; b=kL0FnbNeqloEslEZcg7FK1i8TQE6KV//KZord6JyQc0eZVs7aIRK6+R+X/jRzRoiCP EJswG6AzaXTqqS9nkISpxmnakT1m5Rl+FX9DW+T9kALErMfkEfFGnJxZsq+19ua/QqkD nQJNRoq/wfqmynkpYOg6sqn1OhZfNDx3IvBIroUYpz369Z8nWxWUsS8Vn1lbMpaGd3/P aPVJiA8ocDi2u9E7wusJ0W9sC4ZgJY2y2rNvanyzoXqP01M/wVekYos52vQYoCoYncbV TWMgf3CsVF2dh8hMsaHECK1u6RpLQgU5ld5JCJW47sUT+3XUnp9h2Zvqq43cuMG3+gFD zXJw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id on7-20020a17090b1d0700b0020d4b43d8b5si1015503pjb.103.2022.10.19.13.52.25; Wed, 19 Oct 2022 13:53:02 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231587AbiJSUr1 (ORCPT + 99 others); Wed, 19 Oct 2022 16:47:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38022 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231509AbiJSUrI (ORCPT ); Wed, 19 Oct 2022 16:47:08 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 568161C7D7E for ; Wed, 19 Oct 2022 13:47:04 -0700 (PDT) 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 164AC14BF; Wed, 19 Oct 2022 13:47:10 -0700 (PDT) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id DF50D3F792; Wed, 19 Oct 2022 13:47:01 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, etienne.carriere@linaro.org, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, wleavitt@marvell.com, peter.hilber@opensynergy.com, nicola.mazzucato@arm.com, tarek.el-sherbiny@arm.com, quic_kshivnan@quicinc.com, cristian.marussi@arm.com Subject: [PATCH v4 10/11] firmware: arm_scmi: Reject SCMI drivers while in Raw mode Date: Wed, 19 Oct 2022 21:46:25 +0100 Message-Id: <20221019204626.3813043-11-cristian.marussi@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221019204626.3813043-1-cristian.marussi@arm.com> References: <20221019204626.3813043-1-cristian.marussi@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW, SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747150735027772317?= X-GMAIL-MSGID: =?utf-8?q?1747150735027772317?= Reject SCMI driver registration when SCMI Raw mode support is configured, so as to avoid interferences between the SCMI Raw mode transactions and the normal SCMI stack operations. Signed-off-by: Cristian Marussi --- drivers/firmware/arm_scmi/driver.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index b504b5cdc55f..3e5539987443 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -2365,6 +2365,12 @@ int scmi_protocol_device_request(const struct scmi_device_id *id_table) pr_debug("Requesting SCMI device (%s) for protocol %x\n", id_table->name, id_table->protocol_id); + if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) { + pr_warn("SCMI Raw mode active. Rejecting '%s'/0x%02X\n", + id_table->name, id_table->protocol_id); + return -EINVAL; + } + /* * Search for the matching protocol rdev list and then search * of any existent equally named device...fails if any duplicate found. From patchwork Wed Oct 19 20:46:26 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 5850 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a5d:4ac7:0:0:0:0:0 with SMTP id y7csp529566wrs; Wed, 19 Oct 2022 13:54:14 -0700 (PDT) X-Google-Smtp-Source: AMsMyM5qKVoeMLwoJ1WaZ58yZHurDYNc+pfOqVLbj31qL/cAb3oNbgqAfe0ruPop10b25AcG3Eom X-Received: by 2002:a17:907:72c3:b0:792:56d7:285a with SMTP id du3-20020a17090772c300b0079256d7285amr3584989ejc.597.1666212854805; Wed, 19 Oct 2022 13:54:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1666212854; cv=none; d=google.com; s=arc-20160816; b=DkD6EXrmjP5oOqloaie9mu29BPvon6x4hr5dMCusq0OKkmMBfwrjaqowznlFzDBAj+ 6+x2Me82r8bJl5ygXMKAqwtokrpfYtjyoQFqxVTN+OJlssMxRvh2ss4LgBH6Zm1kS8+d eXrtPCurmuSWvHfm4uKWuxAMnNqFjPoJwei8zNutJPE3LW4QwtYG99S7XjiQwQRQJmKp Q4C2JH9YQHKuf50HtS1aIymZrrM+VDCL76YTf/tzlSkkXXQsiNONrxEUeOnz8BUYSPHA 36PLyer2I8f5GNwn6vmO+niCwHKZVImTVhMLeETHxH8PjaQtgf4AuQvNxPjYupxLaU/G Jylw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=Y9HhzO5HM4BO3jp4nfsPG32ZidpAzlZM6xt/sE9SJvk=; b=lp9Poix+rKQERrnkpb8/6MxxUrYEaW4kSJt7ElUwzcZnVkK1peZKEf4rg8ljka6aMy zzVkOp+owt0DhTPn7FHUGE+Q6VMmVBfPMAIsRU15NeTuPMgaRCfnDsGYHpVXaq4G/3O1 qtthN2JKHv4/J6iFCRyOiaPo4owazGymnbwQk+M2mdzIqhWSqO3p7Jb5F3o6cVBMGpAp /7QjGO91EcGVt4VR2a1xYGtFhO/lUlJzJiwuhxCY5JKJSA1t7uPIP0669N0eE1/gzseH Ovki/TPm9MhMhe3O9nbOoh67aJcHg+sd9rxtqJr0k3ss13a+dN2pB27e0bXQj9/HT8v/ M1dQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id y14-20020a056402358e00b00456d3fc12d4si16204244edc.222.2022.10.19.13.53.26; Wed, 19 Oct 2022 13:54:14 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231609AbiJSUrp (ORCPT + 99 others); Wed, 19 Oct 2022 16:47:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37996 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231575AbiJSUrY (ORCPT ); Wed, 19 Oct 2022 16:47:24 -0400 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 0963F1BE1FA for ; Wed, 19 Oct 2022 13:47:06 -0700 (PDT) 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 42DD41424; Wed, 19 Oct 2022 13:47:12 -0700 (PDT) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 18C933F792; Wed, 19 Oct 2022 13:47:03 -0700 (PDT) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, etienne.carriere@linaro.org, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, wleavitt@marvell.com, peter.hilber@opensynergy.com, nicola.mazzucato@arm.com, tarek.el-sherbiny@arm.com, quic_kshivnan@quicinc.com, cristian.marussi@arm.com Subject: [PATCH v4 11/11] firmware: arm_scmi: Call Raw mode hooks from the core stack Date: Wed, 19 Oct 2022 21:46:26 +0100 Message-Id: <20221019204626.3813043-12-cristian.marussi@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20221019204626.3813043-1-cristian.marussi@arm.com> References: <20221019204626.3813043-1-cristian.marussi@arm.com> MIME-Version: 1.0 X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW, SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1747150810557356770?= X-GMAIL-MSGID: =?utf-8?q?1747150810557356770?= Add a few call sites where, if SCMI Raw mode access had been enabled in Kconfig, the needed SCMI Raw initialization and hooks are called. Signed-off-by: Cristian Marussi --- v3 --> v4 - add call hooks to support polled transports v1 --> v2 - fixes need to use multiple cinfo if available --- drivers/firmware/arm_scmi/driver.c | 45 ++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 3e5539987443..e28104e1b961 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -34,6 +34,8 @@ #include "common.h" #include "notify.h" +#include "raw_mode.h" + #define CREATE_TRACE_POINTS #include @@ -133,6 +135,7 @@ struct scmi_protocol_instance { * @notify_priv: Pointer to private data structure specific to notifications. * @node: List head * @users: Number of users of this instance + * @raw: An opaque reference handle used by SCMI Raw mode. */ struct scmi_info { struct device *dev; @@ -152,6 +155,7 @@ struct scmi_info { void *notify_priv; struct list_head node; int users; + void *raw; }; #define handle_to_scmi_info(h) container_of(h, struct scmi_info, handle) @@ -761,6 +765,11 @@ static void scmi_handle_notification(struct scmi_chan_info *cinfo, xfer->hdr.protocol_id, xfer->hdr.seq, MSG_TYPE_NOTIFICATION); + if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) { + xfer->hdr.seq = MSG_XTRACT_TOKEN(msg_hdr); + scmi_raw_message_report(info->raw, xfer, SCMI_RAW_NOTIF_QUEUE); + } + __scmi_xfer_put(minfo, xfer); scmi_clear_channel(info, cinfo); @@ -774,6 +783,9 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo, xfer = scmi_xfer_command_acquire(cinfo, msg_hdr); if (IS_ERR(xfer)) { + if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) + scmi_raw_error_report(info->raw, cinfo, msg_hdr, priv); + if (MSG_XTRACT_TYPE(msg_hdr) == MSG_TYPE_DELAYED_RESP) scmi_clear_channel(info, cinfo); return; @@ -805,6 +817,16 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo, complete(&xfer->done); } + if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) { + /* + * When in polling mode avoid to queue the Raw xfer on the IRQ + * RX path since it will be already queued at the end of the TX + * poll loop. + */ + if (!xfer->hdr.poll_completion) + scmi_raw_message_report(info->raw, xfer, SCMI_RAW_REPLY_QUEUE); + } + scmi_xfer_command_release(info, xfer); } @@ -915,6 +937,14 @@ static int scmi_wait_for_reply(struct device *dev, const struct scmi_desc *desc, "RESP", xfer->hdr.seq, xfer->hdr.status, xfer->rx.buf, xfer->rx.len); + + if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) { + struct scmi_info *info = + handle_to_scmi_info(cinfo->handle); + + scmi_raw_message_report(info->raw, xfer, + SCMI_RAW_REPLY_QUEUE); + } } } else { /* And we wait for the response. */ @@ -2587,6 +2617,18 @@ static int scmi_probe(struct platform_device *pdev) if (ret) goto clear_txrx_setup; + if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) { + info->raw = scmi_raw_mode_init(handle, info->desc, + info->tx_minfo.max_msg); + if (!IS_ERR(info->raw)) { + dev_info(dev, "SCMI RAW Mode initialized.\n"); + return 0; + } + + dev_err(dev, "Failed to initialize SCMI RAW Mode !\n"); + info->raw = NULL; + } + if (scmi_notification_init(handle)) dev_err(dev, "SCMI Notifications NOT available.\n"); @@ -2661,6 +2703,9 @@ static int scmi_remove(struct platform_device *pdev) struct scmi_info *info = platform_get_drvdata(pdev); struct device_node *child; + if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) + scmi_raw_mode_cleanup(info->raw); + mutex_lock(&scmi_list_mutex); if (info->users) ret = -EBUSY;