From patchwork Mon Nov 22 23:06:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cristian Marussi X-Patchwork-Id: 12693392 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 40E12C433EF for ; Mon, 22 Nov 2021 23:21:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:List-Subscribe:List-Help: List-Post:List-Archive:List-Unsubscribe:List-Id:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=bMdsAGxKDNUshfDSd40a6xD6h6mTRsofFC6y9a18+jY=; b=gK3Jnn7yvZ573I TSSA1bjY9B6hmutc44yruxW7zs+Ib6aBvysO88V827rzZmDLtuMm76AVn2pIyzlpKy8ZlhTWAZXMA uOGPxL4zpCcxnIawdDQJoA2Ajx6SEYqz4Y7IlslUo3jydXF8mr86ArAnihL7nB3GwXuuSvOd5sZVg BRn2ilSGrKb49eyw+7n4dXptvCt6PHjLvZOrpDi+5/4D6oZyO91dtrdcveDVnr58/TVJ9lnOdTPkQ O0okuK9UpAsRV2PDXmRthuShsSE9TIoCT9VSt9zwE2JcQyLbUl+YRo2eNuZ9UsN02QhkdHlrmPnYS fypiqXUM2jg9Nzb/8FuQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mpIbQ-000Nac-Qe; Mon, 22 Nov 2021 23:20:01 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mpIP8-000JbE-J0 for linux-arm-kernel@lists.infradead.org; Mon, 22 Nov 2021 23:07:20 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id B08F4ED1; Mon, 22 Nov 2021 15:07:17 -0800 (PST) Received: from e120937-lin.home (unknown [172.31.20.19]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 6EC753F5A1; Mon, 22 Nov 2021 15:07:16 -0800 (PST) From: Cristian Marussi To: linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Cc: sudeep.holla@arm.com, james.quinlan@broadcom.com, Jonathan.Cameron@Huawei.com, f.fainelli@gmail.com, vincent.guittot@linaro.org, souvik.chakravarty@arm.com, cristian.marussi@arm.com Subject: [PATCH v6 08/16] firmware: arm_scmi: Add sync_cmds_atomic_replies transport flag Date: Mon, 22 Nov 2021 23:06:32 +0000 Message-Id: <20211122230640.1345-9-cristian.marussi@arm.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20211122230640.1345-1-cristian.marussi@arm.com> References: <20211122230640.1345-1-cristian.marussi@arm.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20211122_150718_783141_22C5D290 X-CRM114-Status: GOOD ( 20.94 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add a flag to let the transport signal to the core if its handling of sync command implies that, after .send_message has returned successfully, the requested command can be assumed to be fully and completely executed on SCMI platform side so that any possible response value is already immediately available to be retrieved by a .fetch_response: in other words the polling phase can be skipped in such a case and the response values accessed straight away. Note that all of the above applies only when polling mode of operation was selected by the core: if instead a completion IRQ was found to be available the normal response processing path based on completions will still be followed. Signed-off-by: Cristian Marussi --- v5 --> v6 - added polling_capable helper flag v4 --> v5 - removed RFC tag - consider sync_cmds_atomic_replies flag when deciding if polling is to be supported and .poll_done() is not provided. - reviewed commit message --- drivers/firmware/arm_scmi/common.h | 8 ++++++ drivers/firmware/arm_scmi/driver.c | 43 +++++++++++++++++++++++------- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h index 99b74f4d39b6..bf25f0e89c78 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -412,6 +412,13 @@ struct scmi_device *scmi_child_dev_find(struct device *parent, * @max_msg_size: Maximum size of data per message that can be handled. * @force_polling: Flag to force this whole transport to use SCMI core polling * mechanism instead of completion interrupts even if available. + * @sync_cmds_atomic_replies: Flag to indicate that the transport assures + * synchronous-command messages are atomically + * completed on .send_message: no need to poll + * actively waiting for a response. + * Used by core internally only when polling is + * selected as a waiting for reply method: i.e. + * if a completion irq was found use that anyway. */ struct scmi_desc { int (*transport_init)(void); @@ -421,6 +428,7 @@ struct scmi_desc { int max_msg; int max_msg_size; const bool force_polling; + const bool sync_cmds_atomic_replies; }; #ifdef CONFIG_ARM_SCMI_TRANSPORT_MAILBOX diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index 8a30b832899c..8c04632f3ba3 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -134,6 +134,8 @@ struct scmi_protocol_instance { * @notify_priv: Pointer to private data structure specific to notifications. * @node: List head * @users: Number of users of this instance + * @polling_capable: A flag to annotate if the underlying transport can operate + * in polling mode. */ struct scmi_info { struct device *dev; @@ -152,6 +154,7 @@ struct scmi_info { void *notify_priv; struct list_head node; int users; + bool polling_capable; }; #define handle_to_scmi_info(h) container_of(h, struct scmi_info, handle) @@ -763,10 +766,28 @@ static int scmi_wait_for_message_response(struct scmi_chan_info *cinfo, xfer->hdr.poll_completion); if (xfer->hdr.poll_completion) { - ktime_t stop = ktime_add_ms(ktime_get(), timeout_ms); + /* + * Real polling is needed only if transport has NOT declared + * itself to support synchronous commands replies. + */ + if (!info->desc->sync_cmds_atomic_replies) { + /* + * Poll on xfer using transport provided .poll_done(); + * assumes no completion interrupt was available. + */ + ktime_t stop = ktime_add_ms(ktime_get(), timeout_ms); + + spin_until_cond(scmi_xfer_done_no_timeout(cinfo, + xfer, stop)); + if (ktime_after(ktime_get(), stop)) { + dev_err(dev, + "timed out in resp(caller: %pS) - polling\n", + (void *)_RET_IP_); + ret = -ETIMEDOUT; + } + } - spin_until_cond(scmi_xfer_done_no_timeout(cinfo, xfer, stop)); - if (ktime_before(ktime_get(), stop)) { + if (!ret) { unsigned long flags; /* @@ -779,11 +800,6 @@ static int scmi_wait_for_message_response(struct scmi_chan_info *cinfo, xfer->state = SCMI_XFER_RESP_OK; } spin_unlock_irqrestore(&xfer->lock, flags); - } else { - dev_err(dev, - "timed out in resp(caller: %pS) - polling\n", - (void *)_RET_IP_); - ret = -ETIMEDOUT; } } else { /* And we wait for the response. */ @@ -818,7 +834,7 @@ 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 && !info->desc->ops->poll_done) { + if (xfer->hdr.poll_completion && !info->polling_capable) { dev_warn_once(dev, "Polling mode is not supported by transport.\n"); return -EINVAL; @@ -1533,7 +1549,7 @@ static int scmi_chan_setup(struct scmi_info *info, struct device *dev, return ret; if (tx && (cinfo->no_completion_irq || info->desc->force_polling)) { - if (info->desc->ops->poll_done) { + if (info->polling_capable) { dev_info(dev, "Enabled polling mode TX channel - prot_id:%d\n", prot_id); @@ -1866,6 +1882,13 @@ static int scmi_probe(struct platform_device *pdev) info->dev = dev; info->desc = desc; + /* + * Annotate if the underlying transport for this instance has polling + * capabilities by providing a .poll_done callback OR not requiring + * real polling at all. + */ + info->polling_capable = info->desc->ops->poll_done || + info->desc->sync_cmds_atomic_replies; INIT_LIST_HEAD(&info->node); idr_init(&info->protocols); mutex_init(&info->protocols_mtx);