From patchwork Tue Aug 30 22:25:07 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guru Das Srinagesh X-Patchwork-Id: 601107 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CF8F5ECAAD4 for ; Tue, 30 Aug 2022 22:27:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232138AbiH3W1Y (ORCPT ); Tue, 30 Aug 2022 18:27:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40174 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232397AbiH3W05 (ORCPT ); Tue, 30 Aug 2022 18:26:57 -0400 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C94B261B3A; Tue, 30 Aug 2022 15:25:32 -0700 (PDT) Received: from pps.filterd (m0279864.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 27UMBc6i003473; Tue, 30 Aug 2022 22:25:19 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=qcppdkim1; bh=KE+Fl0ZxBTCz3b0DZd6BUNq+L+lHnmfuXs5O5UWd4b4=; b=mGv6T39y8fibyQKrhSiu4gQpTA0Fbz9NZTkwVhLPASCAY4CiMnzZ35Z/aonuZWpHTpcB fO0WgJ7c7gsrPhpiKtaAqSuTmD1vZrDDckmlhs7/HWZfZ+RPf/DgcTkCWNx5DkikEApf a6ldrKY64370Qaw+Y3lkc1PUAjy4yxFgziaHXeksiT8mKxdnMDGrjF/7puQeeyqBPxcr I1xhQAEBF2YK+mw2/VSl7NG+Dt4guszRw7r6bc/cqKuRPGTXAcOnT57dwUIx+aMiT6dA 19Zp9wZej5ysM2MHqIgYIIqFRMER9IcGCjSi9XMdbXzQGyPkWzVAf3oVtNG9tdSqaknU 3Q== Received: from nasanppmta05.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3j9mwjhdcr-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 30 Aug 2022 22:25:19 +0000 Received: from nasanex01b.na.qualcomm.com (nasanex01b.na.qualcomm.com [10.46.141.250]) by NASANPPMTA05.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 27UMPJBE004044 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 30 Aug 2022 22:25:19 GMT Received: from hu-gurus-sd.qualcomm.com (10.80.80.8) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.29; Tue, 30 Aug 2022 15:25:18 -0700 From: Guru Das Srinagesh To: Andy Gross , Bjorn Andersson , Philipp Zabel , , CC: David Heidelberg , Robert Marko , Rajendra Nayak , Elliot Berman , Guru Das Srinagesh Subject: [RESEND PATCH v2 1/5] dt-bindings: firmware: qcom-scm: Add "allow-multi-call" property Date: Tue, 30 Aug 2022 15:25:07 -0700 Message-ID: <1661898311-30126-2-git-send-email-quic_gurus@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1661898311-30126-1-git-send-email-quic_gurus@quicinc.com> References: <1661898311-30126-1-git-send-email-quic_gurus@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: 9Yx0SXJ5p3iohX8XcTkIOkCRJHEXTXUz X-Proofpoint-ORIG-GUID: 9Yx0SXJ5p3iohX8XcTkIOkCRJHEXTXUz X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-08-30_12,2022-08-30_01,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 suspectscore=0 adultscore=0 malwarescore=0 bulkscore=0 lowpriorityscore=0 impostorscore=0 clxscore=1015 mlxlogscore=889 phishscore=0 priorityscore=1501 mlxscore=0 spamscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2207270000 definitions=main-2208300100 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org For firmware that supports it, allow multiple SCM calls to be passed down to it by removing the serialization lock in the SCM driver. This patch is based on this YAML conversion patch [1] that is in-flight currently. [1] https://lore.kernel.org/lkml/20220708090431.30437-1-david@ixit.cz/ Signed-off-by: Guru Das Srinagesh --- Documentation/devicetree/bindings/firmware/qcom,scm.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml index 9fdeee0..e279fd2 100644 --- a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml +++ b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml @@ -70,6 +70,11 @@ properties: '#reset-cells': const: 1 + allow-multi-call: + description: + Specify this flag to remove SCM call serialization. Need to ensure that + the firmware being used supports this feature first. + qcom,dload-mode: $ref: /schemas/types.yaml#/definitions/phandle-array items: From patchwork Tue Aug 30 22:25:08 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guru Das Srinagesh X-Patchwork-Id: 601901 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A2857ECAAA1 for ; Tue, 30 Aug 2022 22:27:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232422AbiH3W1Z (ORCPT ); Tue, 30 Aug 2022 18:27:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40172 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232152AbiH3W05 (ORCPT ); Tue, 30 Aug 2022 18:26:57 -0400 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C94335F202; Tue, 30 Aug 2022 15:25:32 -0700 (PDT) Received: from pps.filterd (m0279866.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 27UKnHt9018087; Tue, 30 Aug 2022 22:25:20 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=qcppdkim1; bh=E0OVYP5v1R1xQJJorOW590/QSlnrwFy0QK0M4kKysOQ=; b=DX4Wo+J76F3pBkUCwVUqWyM9/fWstPEvrtSAJNPvc/PYr2o4Gj7nlgOVJJyNxEE6MaFQ 8FOyHysiGWe+Pb9HL0UAANl3WZ4mLQ27DC7z8gAJ6VKaeM5tkFFadqnlXUqARpG+atFG w3sTxsdDtIhgiofvv54TyjhTv2c1Db6nx7NVvYgLYes6SBcwIo5T8LwcnY7zYsZ2vwCx NbPW11Qp4EY5VJb3FOjbzNkqLzxx3qfashaqqJAAYw1O9w7eNwMmjVgURLu6B3JMOxPp cNRvOTJqcLt+Og5SfJgCpW8H6cVjA0XlqNSTM8K1wGJUz4rFmiq60ToXWRr8pnXH5FGT 6Q== Received: from nasanppmta04.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3j9mwg1e9j-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 30 Aug 2022 22:25:19 +0000 Received: from nasanex01b.na.qualcomm.com (nasanex01b.na.qualcomm.com [10.46.141.250]) by NASANPPMTA04.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 27UMPJJt010683 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 30 Aug 2022 22:25:19 GMT Received: from hu-gurus-sd.qualcomm.com (10.80.80.8) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.29; Tue, 30 Aug 2022 15:25:19 -0700 From: Guru Das Srinagesh To: Andy Gross , Bjorn Andersson , Philipp Zabel , , CC: David Heidelberg , Robert Marko , Rajendra Nayak , Elliot Berman , Guru Das Srinagesh Subject: [RESEND PATCH v2 2/5] firmware: qcom: scm: Optionally remove SCM call serialization Date: Tue, 30 Aug 2022 15:25:08 -0700 Message-ID: <1661898311-30126-3-git-send-email-quic_gurus@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1661898311-30126-1-git-send-email-quic_gurus@quicinc.com> References: <1661898311-30126-1-git-send-email-quic_gurus@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: zi3BVz5VUYQEQSHagPXKDC5qRrt-YZeZ X-Proofpoint-GUID: zi3BVz5VUYQEQSHagPXKDC5qRrt-YZeZ X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-08-30_12,2022-08-30_01,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 priorityscore=1501 mlxscore=0 adultscore=0 lowpriorityscore=0 mlxlogscore=999 malwarescore=0 bulkscore=0 suspectscore=0 spamscore=0 impostorscore=0 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2207270000 definitions=main-2208300100 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Some firmware versions support the handling of multiple SCM calls at the same time. Add a device tree boolean property which, when specified, allows this to happen. Signed-off-by: Guru Das Srinagesh --- drivers/firmware/qcom_scm-smc.c | 8 ++++++-- drivers/firmware/qcom_scm.c | 6 ++++++ drivers/firmware/qcom_scm.h | 2 ++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/qcom_scm-smc.c b/drivers/firmware/qcom_scm-smc.c index d111833..66193c2 100644 --- a/drivers/firmware/qcom_scm-smc.c +++ b/drivers/firmware/qcom_scm-smc.c @@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2015,2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -63,11 +64,14 @@ static void __scm_smc_do(const struct arm_smccc_args *smc, } do { - mutex_lock(&qcom_scm_lock); + if (!qcom_scm_allow_multicall) + mutex_lock(&qcom_scm_lock); __scm_smc_do_quirk(smc, res); - mutex_unlock(&qcom_scm_lock); + if (!qcom_scm_allow_multicall) + mutex_unlock(&qcom_scm_lock); + if (res->a0 == QCOM_SCM_V2_EBUSY) { if (retry_count++ > QCOM_SCM_EBUSY_MAX_RETRY) diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index cdbfe54..978706a 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* Copyright (c) 2010,2015,2019 The Linux Foundation. All rights reserved. * Copyright (C) 2015 Linaro Ltd. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #include #include @@ -23,6 +24,8 @@ static bool download_mode = IS_ENABLED(CONFIG_QCOM_SCM_DOWNLOAD_MODE_DEFAULT); module_param(download_mode, bool, 0); +bool qcom_scm_allow_multicall = false; + #define SCM_HAS_CORE_CLK BIT(0) #define SCM_HAS_IFACE_CLK BIT(1) #define SCM_HAS_BUS_CLK BIT(2) @@ -1402,6 +1405,9 @@ static int qcom_scm_probe(struct platform_device *pdev) __scm = scm; __scm->dev = &pdev->dev; + qcom_scm_allow_multicall = of_property_read_bool(__scm->dev->of_node, + "allow-multi-call"); + __get_convention(); /* diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index 0d51eef..c0a4d6b 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (c) 2010-2015,2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef __QCOM_SCM_INT_H #define __QCOM_SCM_INT_H @@ -12,6 +13,7 @@ enum qcom_scm_convention { }; extern enum qcom_scm_convention qcom_scm_convention; +extern bool qcom_scm_allow_multicall; #define MAX_QCOM_SCM_ARGS 10 #define MAX_QCOM_SCM_RETS 3 From patchwork Tue Aug 30 22:25:09 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guru Das Srinagesh X-Patchwork-Id: 601106 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E63CDECAAD5 for ; Tue, 30 Aug 2022 22:27:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232241AbiH3W1Z (ORCPT ); Tue, 30 Aug 2022 18:27:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39458 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229723AbiH3W05 (ORCPT ); Tue, 30 Aug 2022 18:26:57 -0400 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C9BB767C93; Tue, 30 Aug 2022 15:25:31 -0700 (PDT) Received: from pps.filterd (m0279867.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 27UJAgYk004621; Tue, 30 Aug 2022 22:25:20 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=qcppdkim1; bh=YHfq26Jki1OpoFOt7dvhlzhQTdKm3YYxb/Io14yx4fo=; b=BVmIDYd+myLqbxO4JtGnYs4UCkf+MXg8Hi98qo6FX83sp7sr/7Y8EsmjWE4nqN9KpaAz HqtM3vKfDe1tA2hzM3EA2LyQ2UPfsNpqJnarIYSJcvjL8ePvjTPD0be14CvBkXVaKrls ovGihV+39M/Q+2o9mw+7o5Bsie0qeI4JNZzsbPgyo7UWPxwkUrHYwpryAsJvyUxRW82+ ObdkV3+G1zl2Kr3d9t/AHHNwrMZZDBzN6b5vo/5WPqbifua7Q/ZiFZ2IhwbwVusLaXj6 ClusJCleaNmdjewYD+eBaBcnYPDWnamW25dirlLnKBNnw0+4jmRK3PhQGpXEO2g8HaBy kw== Received: from nasanppmta04.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3j9n861cfr-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 30 Aug 2022 22:25:20 +0000 Received: from nasanex01b.na.qualcomm.com (nasanex01b.na.qualcomm.com [10.46.141.250]) by NASANPPMTA04.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 27UMPJbm010687 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 30 Aug 2022 22:25:19 GMT Received: from hu-gurus-sd.qualcomm.com (10.80.80.8) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.29; Tue, 30 Aug 2022 15:25:19 -0700 From: Guru Das Srinagesh To: Andy Gross , Bjorn Andersson , Philipp Zabel , , CC: David Heidelberg , Robert Marko , Rajendra Nayak , Elliot Berman , Guru Das Srinagesh Subject: [RESEND PATCH v2 3/5] dt-bindings: firmware: qcom-scm: Add optional interrupt Date: Tue, 30 Aug 2022 15:25:09 -0700 Message-ID: <1661898311-30126-4-git-send-email-quic_gurus@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1661898311-30126-1-git-send-email-quic_gurus@quicinc.com> References: <1661898311-30126-1-git-send-email-quic_gurus@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: DIKGDZpMiUu2u6MAiV3vD0dIIxA6PxVb X-Proofpoint-ORIG-GUID: DIKGDZpMiUu2u6MAiV3vD0dIIxA6PxVb X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-08-30_12,2022-08-30_01,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 suspectscore=0 impostorscore=0 adultscore=0 mlxlogscore=532 spamscore=0 clxscore=1015 phishscore=0 bulkscore=0 priorityscore=1501 mlxscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2207270000 definitions=main-2208300100 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add an interrupt specification to the bindings to support the wait-queue feature. Signed-off-by: Guru Das Srinagesh --- Documentation/devicetree/bindings/firmware/qcom,scm.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml index e279fd2..4d6c89f 100644 --- a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml +++ b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml @@ -75,6 +75,11 @@ properties: Specify this flag to remove SCM call serialization. Need to ensure that the firmware being used supports this feature first. + interrupts: + description: + The wait-queue interrupt that firmware raises as part of handshake + protocol to handle sleeping SCM calls. + qcom,dload-mode: $ref: /schemas/types.yaml#/definitions/phandle-array items: From patchwork Tue Aug 30 22:25:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guru Das Srinagesh X-Patchwork-Id: 601105 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6531EC54EE9 for ; Tue, 30 Aug 2022 22:27:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232397AbiH3W11 (ORCPT ); Tue, 30 Aug 2022 18:27:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35384 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232203AbiH3W06 (ORCPT ); Tue, 30 Aug 2022 18:26:58 -0400 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C936251412; Tue, 30 Aug 2022 15:25:31 -0700 (PDT) Received: from pps.filterd (m0279862.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 27UIhu4l023099; Tue, 30 Aug 2022 22:25:20 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=qcppdkim1; bh=v+6QGWapg4lcMz1/CQru86fm3pEvXRPhAWhGsqIFLq8=; b=OK/40uLhqyhpollK+bDm7/lzHH3+dxhlX/aZEORz9LDmcI+7fOqwb+SIUrAbWlXSA5Vy v5KUdGC5S63s7mqY8ncbkrfMis16h2VmRDQFJnPfLfuIfC3uL/2Znd3FZXkTSel/nPRF 2OBobcmx7dOWiRJE+P09wiP83J8qJ2Yp91jkxVyV8Aqs3gYN40hJBpes5FYS9YiTZRZk ehdWbtrWkwFvZ4eq+raJfpZNQz5jIsV+KJ/gWfSVZsku79anlakw4LcOhunF7h2fyXBs fIvrhtgm2yjFIni33bSmKz4WywmYaQEuwQUxQgFSMMCOqWADw+zFOZEUr8NAdCHTeBmE cg== Received: from nasanppmta05.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3j9m2t1heh-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 30 Aug 2022 22:25:20 +0000 Received: from nasanex01b.na.qualcomm.com (nasanex01b.na.qualcomm.com [10.46.141.250]) by NASANPPMTA05.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 27UMPJvW004051 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 30 Aug 2022 22:25:19 GMT Received: from hu-gurus-sd.qualcomm.com (10.80.80.8) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.29; Tue, 30 Aug 2022 15:25:19 -0700 From: Guru Das Srinagesh To: Andy Gross , Bjorn Andersson , Philipp Zabel , , CC: David Heidelberg , Robert Marko , Rajendra Nayak , Elliot Berman , Guru Das Srinagesh Subject: [RESEND PATCH v2 4/5] firmware: qcom: scm: Add wait-queue helper functions Date: Tue, 30 Aug 2022 15:25:10 -0700 Message-ID: <1661898311-30126-5-git-send-email-quic_gurus@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1661898311-30126-1-git-send-email-quic_gurus@quicinc.com> References: <1661898311-30126-1-git-send-email-quic_gurus@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-GUID: hg2nWvfYeXz_FnJC67TQQ-HjiEU8XfrK X-Proofpoint-ORIG-GUID: hg2nWvfYeXz_FnJC67TQQ-HjiEU8XfrK X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-08-30_12,2022-08-30_01,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 phishscore=0 adultscore=0 mlxlogscore=999 bulkscore=0 suspectscore=0 mlxscore=0 clxscore=1015 spamscore=0 malwarescore=0 impostorscore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2207270000 definitions=main-2208300100 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org When the firmware (FW) supports multiple requests per VM, and the VM also supports it via the `allow-multi-call` device tree flag, the floodgates are thrown open for them to all reach the firmware at the same time. Since the firmware currently being used has limited resources, it guards them with a resource lock and puts requests on a wait-queue internally and signals to HLOS that it is doing so. It does this by returning two new return values in addition to success or error: SCM_WAITQ_SLEEP and SCM_WAITQ_WAKE. 1) SCM_WAITQ_SLEEP: When an SCM call receives this return value instead of success or error, FW has placed this call on a wait-queue and has signalled HLOS to put it to non-interruptible sleep. (The mechanism to wake it back up will be described in detail in the next patch for the sake of simplicity.) Along with this return value, FW also passes to HLOS `wq_ctx` - a unique number (UID) identifying the wait-queue that it has put the call on, internally. This is to help HLOS with its own bookkeeping to wake this sleeping call later. Additionally, FW also passes to HLOS `smc_call_ctx` - a UID identifying the SCM call thus being put to sleep. This is also for HLOS' bookkeeping to wake this call up later. These two additional values are passed via the a1 and a2 registers. N.B.: The "ctx" in the above UID names = "context". 2) SCM_WAITQ_WAKE: When an SCM call receives this return value instead of success or error, FW wishes to signal HLOS to wake up a (different) previously sleeping call. FW tells HLOS which call to wake up via the additional return values `wq_ctx`, `smc_call_ctx` and `flags`. The first two have already been explained above. `flags` can be either WAKE_ONE or WAKE_ALL. Meaning, wake either one, or all, of the SCM calls that HLOS is associating with the given `wq_ctx`. A sleeping SCM call can be woken up by either an interrupt that FW raises, or via a SCM_WAITQ_WAKE return value for a new SCM call. The handshake mechanism that HLOS uses to talk to FW about wait-queue operations involves three new SMC calls. These are: 1) get_wq_ctx(): Arguments: None Returns: wq_ctx, flags, more_pending Get the wait-queue context, and wake up either one or all of the sleeping SCM calls associated with that wait-queue. Additionally, repeat this if there are more wait-queues that are ready to have their requests woken up (`more_pending`). 2) wq_resume(smc_call_ctx): Arguments: smc_call_ctx HLOS needs to issue this in response to receiving an IRQ, passing to FW the same smc_call_ctx that FW receives from HLOS via the get_wq_ctx() call. 3) wq_wake_ack(smc_call_ctx): Arguments: smc_call_ctx HLOS needs to issue this in response to receiving an SCM_WAITQ_WAKE, passing to FW the same smc_call_ctx that FW passed to HLOS via the SMC_WAITQ_WAKE call. (Reminder that the full handshake mechanism will be detailed in the subsequent patch.) Also add the interrupt handler that wakes up a sleeping SCM call. Signed-off-by: Guru Das Srinagesh Reported-by: kernel test robot Reported-by: kernel test robot --- drivers/firmware/qcom_scm-smc.c | 56 +++++++++++++++++++ drivers/firmware/qcom_scm.c | 119 +++++++++++++++++++++++++++++++++++++++- drivers/firmware/qcom_scm.h | 12 ++++ 3 files changed, 186 insertions(+), 1 deletion(-) diff --git a/drivers/firmware/qcom_scm-smc.c b/drivers/firmware/qcom_scm-smc.c index 66193c2..4150da1 100644 --- a/drivers/firmware/qcom_scm-smc.c +++ b/drivers/firmware/qcom_scm-smc.c @@ -53,6 +53,62 @@ static void __scm_smc_do_quirk(const struct arm_smccc_args *smc, } while (res->a0 == QCOM_SCM_INTERRUPTED); } +static void fill_wq_resume_args(struct arm_smccc_args *resume, u32 smc_call_ctx) +{ + memset(resume->args, 0, ARRAY_SIZE(resume->args)); + + resume->args[0] = ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL, + ARM_SMCCC_SMC_64, ARM_SMCCC_OWNER_SIP, + SCM_SMC_FNID(QCOM_SCM_SVC_WAITQ, QCOM_SCM_WAITQ_RESUME)); + + resume->args[1] = QCOM_SCM_ARGS(1); + + resume->args[2] = smc_call_ctx; +} + +static void fill_wq_wake_ack_args(struct arm_smccc_args *wake_ack, u32 smc_call_ctx) +{ + memset(wake_ack->args, 0, ARRAY_SIZE(wake_ack->args)); + + wake_ack->args[0] = ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL, + ARM_SMCCC_SMC_64, ARM_SMCCC_OWNER_SIP, + SCM_SMC_FNID(QCOM_SCM_SVC_WAITQ, QCOM_SCM_WAITQ_ACK)); + + wake_ack->args[1] = QCOM_SCM_ARGS(1); + + wake_ack->args[2] = smc_call_ctx; +} + +static void fill_get_wq_ctx_args(struct arm_smccc_args *get_wq_ctx) +{ + memset(get_wq_ctx->args, 0, ARRAY_SIZE(get_wq_ctx->args)); + + get_wq_ctx->args[0] = ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL, + ARM_SMCCC_SMC_64, ARM_SMCCC_OWNER_SIP, + SCM_SMC_FNID(QCOM_SCM_SVC_WAITQ, QCOM_SCM_WAITQ_GET_WQ_CTX)); +} + +int scm_get_wq_ctx(u32 *wq_ctx, u32 *flags, u32 *more_pending) +{ + int ret; + struct arm_smccc_args get_wq_ctx = {0}; + struct arm_smccc_res get_wq_res; + + fill_get_wq_ctx_args(&get_wq_ctx); + + __scm_smc_do_quirk(&get_wq_ctx, &get_wq_res); + /* Guaranteed to return only success or error, no WAITQ_* */ + ret = get_wq_res.a0; + if (ret) + return ret; + + *wq_ctx = get_wq_res.a1; + *flags = get_wq_res.a2; + *more_pending = get_wq_res.a3; + + return 0; +} + static void __scm_smc_do(const struct arm_smccc_args *smc, struct arm_smccc_res *res, bool atomic) { diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index 978706a..9ae3fcf 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -3,8 +3,12 @@ * Copyright (C) 2015 Linaro Ltd. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. */ +#define pr_fmt(fmt) "qcom-scm: %s: " fmt, __func__ + #include +#include #include +#include #include #include #include @@ -13,10 +17,13 @@ #include #include #include +#include #include #include #include #include +#include +#include #include #include "qcom_scm.h" @@ -30,6 +37,12 @@ bool qcom_scm_allow_multicall = false; #define SCM_HAS_IFACE_CLK BIT(1) #define SCM_HAS_BUS_CLK BIT(2) +struct qcom_scm_waitq { + struct idr idr; + spinlock_t idr_lock; + struct work_struct scm_irq_work; +}; + struct qcom_scm { struct device *dev; struct clk *core_clk; @@ -37,6 +50,7 @@ struct qcom_scm { struct clk *bus_clk; struct icc_path *path; struct reset_controller_dev reset; + struct qcom_scm_waitq waitq; /* control access to the interconnect path */ struct mutex scm_bw_lock; @@ -62,10 +76,14 @@ struct qcom_scm_mem_map_info { static const u8 qcom_scm_cpu_cold_bits[QCOM_SCM_BOOT_MAX_CPUS] = { 0, BIT(0), BIT(3), BIT(5) }; + static const u8 qcom_scm_cpu_warm_bits[QCOM_SCM_BOOT_MAX_CPUS] = { BIT(2), BIT(1), BIT(4), BIT(6) }; +#define QCOM_SMC_WAITQ_FLAG_WAKE_ONE BIT(0) +#define QCOM_SMC_WAITQ_FLAG_WAKE_ALL BIT(1) + static const char * const qcom_scm_convention_names[] = { [SMC_CONVENTION_UNKNOWN] = "unknown", [SMC_CONVENTION_ARM_32] = "smc arm 32", @@ -1328,11 +1346,92 @@ bool qcom_scm_is_available(void) } EXPORT_SYMBOL(qcom_scm_is_available); +struct completion *qcom_scm_lookup_wq(struct qcom_scm *scm, u32 wq_ctx) +{ + struct completion *wq = NULL; + u32 wq_ctx_idr = wq_ctx; + unsigned long flags; + int err; + + spin_lock_irqsave(&scm->waitq.idr_lock, flags); + wq = idr_find(&scm->waitq.idr, wq_ctx); + if (wq) + goto out; + + wq = devm_kzalloc(scm->dev, sizeof(*wq), GFP_ATOMIC); + if (!wq) { + wq = ERR_PTR(-ENOMEM); + goto out; + } + + init_completion(wq); + + err = idr_alloc_u32(&scm->waitq.idr, wq, &wq_ctx_idr, + U32_MAX, GFP_ATOMIC); + if (err < 0) { + devm_kfree(scm->dev, wq); + wq = ERR_PTR(err); + } + +out: + spin_unlock_irqrestore(&scm->waitq.idr_lock, flags); + return wq; +} + +void scm_waitq_flag_handler(struct completion *wq, u32 flags) +{ + switch (flags) { + case QCOM_SMC_WAITQ_FLAG_WAKE_ONE: + complete(wq); + break; + case QCOM_SMC_WAITQ_FLAG_WAKE_ALL: + complete_all(wq); + break; + default: + pr_err("invalid flags: %u\n", flags); + } +} + +static void scm_irq_work(struct work_struct *work) +{ + int ret; + u32 wq_ctx, flags, more_pending = 0; + struct completion *wq_to_wake; + struct qcom_scm_waitq *w = container_of(work, struct qcom_scm_waitq, scm_irq_work); + struct qcom_scm *scm = container_of(w, struct qcom_scm, waitq); + + do { + ret = scm_get_wq_ctx(&wq_ctx, &flags, &more_pending); + if (ret) { + pr_err("GET_WQ_CTX SMC call failed: %d\n", ret); + return; + } + + wq_to_wake = qcom_scm_lookup_wq(scm, wq_ctx); + if (IS_ERR_OR_NULL(wq_to_wake)) { + pr_err("No waitqueue found for wq_ctx %d: %ld\n", + wq_ctx, PTR_ERR(wq_to_wake)); + return; + } + + scm_waitq_flag_handler(wq_to_wake, flags); + } while (more_pending); +} + +static irqreturn_t qcom_scm_irq_handler(int irq, void *p) +{ + struct qcom_scm *scm = p; + + schedule_work(&scm->waitq.scm_irq_work); + + return IRQ_HANDLED; +} + static int qcom_scm_probe(struct platform_device *pdev) { struct qcom_scm *scm; unsigned long clks; - int ret; + int irq, ret; scm = devm_kzalloc(&pdev->dev, sizeof(*scm), GFP_KERNEL); if (!scm) @@ -1402,12 +1501,29 @@ static int qcom_scm_probe(struct platform_device *pdev) if (ret) return ret; + platform_set_drvdata(pdev, scm); + __scm = scm; __scm->dev = &pdev->dev; + spin_lock_init(&__scm->waitq.idr_lock); + idr_init(&__scm->waitq.idr); qcom_scm_allow_multicall = of_property_read_bool(__scm->dev->of_node, "allow-multi-call"); + INIT_WORK(&__scm->waitq.scm_irq_work, scm_irq_work); + + irq = platform_get_irq(pdev, 0); + if (irq) { + ret = devm_request_threaded_irq(__scm->dev, irq, NULL, + qcom_scm_irq_handler, IRQF_ONESHOT, "qcom-scm", __scm); + if (ret < 0) { + pr_err("Failed to request qcom-scm irq: %d\n", ret); + idr_destroy(&__scm->waitq.idr); + return ret; + } + } + __get_convention(); /* @@ -1423,6 +1539,7 @@ static int qcom_scm_probe(struct platform_device *pdev) static void qcom_scm_shutdown(struct platform_device *pdev) { + idr_destroy(&__scm->waitq.idr); /* Clean shutdown, disable download mode to allow normal restart */ if (download_mode) qcom_scm_set_download_mode(false); diff --git a/drivers/firmware/qcom_scm.h b/drivers/firmware/qcom_scm.h index c0a4d6b..ae3a331 100644 --- a/drivers/firmware/qcom_scm.h +++ b/drivers/firmware/qcom_scm.h @@ -62,6 +62,11 @@ struct qcom_scm_res { u64 result[MAX_QCOM_SCM_RETS]; }; +struct qcom_scm; +extern struct completion *qcom_scm_lookup_wq(struct qcom_scm *scm, u32 wq_ctx); +extern void scm_waitq_flag_handler(struct completion *wq, u32 flags); +extern int scm_get_wq_ctx(u32 *wq_ctx, u32 *flags, u32 *more_pending); + #define SCM_SMC_FNID(s, c) ((((s) & 0xFF) << 8) | ((c) & 0xFF)) extern int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc, enum qcom_scm_convention qcom_convention, @@ -131,6 +136,11 @@ extern int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc, #define QCOM_SCM_SMMU_CONFIG_ERRATA1 0x03 #define QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL 0x02 +#define QCOM_SCM_SVC_WAITQ 0x24 +#define QCOM_SCM_WAITQ_ACK 0x01 +#define QCOM_SCM_WAITQ_RESUME 0x02 +#define QCOM_SCM_WAITQ_GET_WQ_CTX 0x03 + extern void __qcom_scm_init(void); /* common error codes */ @@ -141,6 +151,8 @@ extern void __qcom_scm_init(void); #define QCOM_SCM_EINVAL_ARG -2 #define QCOM_SCM_ERROR -1 #define QCOM_SCM_INTERRUPTED 1 +#define QCOM_SCM_WAITQ_SLEEP 2 +#define QCOM_SCM_WAITQ_WAKE 3 static inline int qcom_scm_remap_error(int err) { From patchwork Tue Aug 30 22:25:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Guru Das Srinagesh X-Patchwork-Id: 601899 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id EAA46ECAAA1 for ; Tue, 30 Aug 2022 22:27:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231404AbiH3W11 (ORCPT ); Tue, 30 Aug 2022 18:27:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41174 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230362AbiH3W07 (ORCPT ); Tue, 30 Aug 2022 18:26:59 -0400 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D6C48520A7; Tue, 30 Aug 2022 15:25:33 -0700 (PDT) Received: from pps.filterd (m0279863.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.17.1.5/8.17.1.5) with ESMTP id 27UK1XGn009466; Tue, 30 Aug 2022 22:25:20 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type : content-transfer-encoding; s=qcppdkim1; bh=N5jo3cXf1pHUAhz7MPG4SablCWfdRBY03Ry80OidHIY=; b=N5ZjmgYKefwqW2/riNv89ROnFmGbpnhyzX17l8jP6nxiUj9Ru5D0pgOXMCVbkzceNkmy R0qm60c/3nY35kVHUYoT+4giyCoVakdx4K5+nKLIGV6UXFXVkMnr6NT7xgP/fYNnfAbu ouoGxIbkXaAONwVo762ufb1EjoP/KWx/gDrHlp2lR3bfcJIUHhDdZrIvmKlz/hj1orcj 6aBF8Bq7jSQ0UOl5SVXxrEXQ99vYJbBsNFA/Ta0LZjbYdYgMqUjrcwAoMQCR8x0G8r34 f9w8oEsTJ7RieXOOX5fKBpYdJs0uAF+XyQfPOlPlvUrcYgC5ONZDW/CfrI7oGK/YVWSe Rg== Received: from nasanppmta02.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 3j9qdm0u1e-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 30 Aug 2022 22:25:20 +0000 Received: from nasanex01b.na.qualcomm.com (corens_vlan604_snip.qualcomm.com [10.53.140.1]) by NASANPPMTA02.qualcomm.com (8.17.1.5/8.17.1.5) with ESMTPS id 27UMPJae008290 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 30 Aug 2022 22:25:19 GMT Received: from hu-gurus-sd.qualcomm.com (10.80.80.8) by nasanex01b.na.qualcomm.com (10.46.141.250) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.29; Tue, 30 Aug 2022 15:25:19 -0700 From: Guru Das Srinagesh To: Andy Gross , Bjorn Andersson , Philipp Zabel , , CC: David Heidelberg , Robert Marko , Rajendra Nayak , Elliot Berman , Guru Das Srinagesh Subject: [RESEND PATCH v2 5/5] firmware: qcom: scm: Add wait-queue handling logic Date: Tue, 30 Aug 2022 15:25:11 -0700 Message-ID: <1661898311-30126-6-git-send-email-quic_gurus@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1661898311-30126-1-git-send-email-quic_gurus@quicinc.com> References: <1661898311-30126-1-git-send-email-quic_gurus@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01b.na.qualcomm.com (10.46.141.250) To nasanex01b.na.qualcomm.com (10.46.141.250) X-QCInternal: smtphost X-Proofpoint-Virus-Version: vendor=nai engine=6200 definitions=5800 signatures=585085 X-Proofpoint-ORIG-GUID: p_NwbDbAG9I0Gb77UnXm6PVAC1CZDANf X-Proofpoint-GUID: p_NwbDbAG9I0Gb77UnXm6PVAC1CZDANf X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.895,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-08-30_12,2022-08-30_01,2022-06-22_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 priorityscore=1501 adultscore=0 spamscore=0 bulkscore=0 suspectscore=0 clxscore=1015 malwarescore=0 mlxscore=0 impostorscore=0 phishscore=0 mlxlogscore=999 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2207270000 definitions=main-2208300100 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Add logic to handle QCOM_SCM_WAITQ_SLEEP or QCOM_SCM_WAITQ_WAKE return codes. Scenario 1: Requests made by 2 different VMs: VM_1 VM_2 Firmware │ │ │ │ │ │ │ │ │ │ │ │ │ REQUEST_1 │ │ ├────────────────────────┼─────────────────────────────────┤ │ │ │ │ │ ┌──┼──┐ │ │ │ │ │ │ │ REQUEST_2 │ │ │ │ ├──────────────────────────────┼──┤ │ │ │ │ │ │Resource │ │ │ │ │is busy │ │ {WQ_SLEEP} │ │ │ │ │◄─────────────────────────────┼──┤ │ │ │ wq_ctx, smc_call_ctx │ │ │ │ │ └──┼──┘ │ REQUEST_1 COMPLETE │ │ │◄───────────────────────┼─────────────────────────────────┤ │ │ │ │ │ IRQ │ │ │◄─-------------------------------│ │ │ │ │ │ get_wq_ctx() │ │ ├────────────────────────────────►│ │ │ │ │ │ │ │ │◄────────────────────────────────┤ │ │ wq_ctx, flags, and │ │ │ more_pending │ │ │ │ │ │ │ │ │ wq_resume(smc_call_ctx) │ │ ├────────────────────────────────►│ │ │ │ │ │ │ │ │ REQUEST_2 COMPLETE │ │ │◄────────────────────────────────┤ │ │ │ │ │ │ Scenario 2: Two Requests coming in from same VM: VM_1 Firmware │ │ │ │ │ │ │ │ │ REQUEST_1 │ ├──────────────────────────────────────────────────────────┤ │ │ │ ┌────┼───┐ │ │ │ │ │ │ │ │ │ │ │ │ │ REQUEST_2 │ │ │ ├─────────────────────────────────────────────────────┼───►│ │ │ │ │ │Resource │ │ │ │is busy │ {WQ_SLEEP} │ │ │ │◄────────────────────────────────────────────────────┼────┤ │ │ wq_ctx, req2_smc_call_ctx │ │ │ │ │ │ │ │ └────┼───┘ │ │ │ {WQ_WAKE} │ │◄─────────────────────────────────────────────────────────┤ │ wq_ctx, req1_smc_call_ctx, flags │ │ │ │ │ │ wq_wake_ack(req1_smc_call_ctx) │ ├─────────────────────────────────────────────────────────►│ │ │ │ REQUEST_1 COMPLETE │ │◄─────────────────────────────────────────────────────────┤ │ │ │ │ │ wq_resume(req_2_smc_call_ctx) │ ├─────────────────────────────────────────────────────────►│ │ │ │ REQUEST_2 COMPLETE │ │◄─────────────────────────────────────────────────────────┤ │ │ With the exception of get_wq_ctx(), the other two newly-introduced SMC calls, wq_ack() and wq_resume() can themselves return WQ_SLEEP (these nested rounds of WQ_SLEEP are not shown in the above diagram for the sake of simplicity). Therefore, introduce a new do-while loop to handle multiple WQ_SLEEP return values for the same parent SCM call. Request Completion in the above diagram refers to either a success return value (zero) or error (and not SMC_WAITQ_SLEEP or SMC_WAITQ_WAKE). Signed-off-by: Guru Das Srinagesh --- drivers/firmware/qcom_scm-smc.c | 76 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 7 deletions(-) diff --git a/drivers/firmware/qcom_scm-smc.c b/drivers/firmware/qcom_scm-smc.c index 4150da1..09cca48 100644 --- a/drivers/firmware/qcom_scm-smc.c +++ b/drivers/firmware/qcom_scm-smc.c @@ -53,6 +53,9 @@ static void __scm_smc_do_quirk(const struct arm_smccc_args *smc, } while (res->a0 == QCOM_SCM_INTERRUPTED); } +#define IS_WAITQ_SLEEP_OR_WAKE(res) \ + (res->a0 == QCOM_SCM_WAITQ_SLEEP || res->a0 == QCOM_SCM_WAITQ_WAKE) + static void fill_wq_resume_args(struct arm_smccc_args *resume, u32 smc_call_ctx) { memset(resume->args, 0, ARRAY_SIZE(resume->args)); @@ -109,25 +112,77 @@ int scm_get_wq_ctx(u32 *wq_ctx, u32 *flags, u32 *more_pending) return 0; } -static void __scm_smc_do(const struct arm_smccc_args *smc, +static int scm_smc_do_quirk(struct device *dev, struct arm_smccc_args *smc, + struct arm_smccc_res *res) +{ + struct completion *wq = NULL; + struct qcom_scm *qscm; + u32 wq_ctx, smc_call_ctx, flags; + + do { + __scm_smc_do_quirk(smc, res); + + if (IS_WAITQ_SLEEP_OR_WAKE(res)) { + wq_ctx = res->a1; + smc_call_ctx = res->a2; + flags = res->a3; + + if (!dev) + return -EPROBE_DEFER; + + qscm = dev_get_drvdata(dev); + wq = qcom_scm_lookup_wq(qscm, wq_ctx); + if (IS_ERR_OR_NULL(wq)) { + pr_err("No waitqueue found for wq_ctx %d: %ld\n", + wq_ctx, PTR_ERR(wq)); + return PTR_ERR(wq); + } + + if (res->a0 == QCOM_SCM_WAITQ_SLEEP) { + wait_for_completion(wq); + fill_wq_resume_args(smc, smc_call_ctx); + wq = NULL; + continue; + } else { + fill_wq_wake_ack_args(smc, smc_call_ctx); + continue; + } + } else if (!res->a0 || (long)res->a0 < 0) { + /* + * Success, or error. + * wq will be set only if a prior WAKE happened. + * Its value will be the one from the prior WAKE. + */ + if (wq) + scm_waitq_flag_handler(wq, flags); + break; + } + } while (IS_WAITQ_SLEEP_OR_WAKE(res)); + + return 0; +} + +static int __scm_smc_do(struct device *dev, struct arm_smccc_args *smc, struct arm_smccc_res *res, bool atomic) { - int retry_count = 0; + int ret, retry_count = 0; if (atomic) { __scm_smc_do_quirk(smc, res); - return; + return 0; } do { if (!qcom_scm_allow_multicall) mutex_lock(&qcom_scm_lock); - __scm_smc_do_quirk(smc, res); + ret = scm_smc_do_quirk(dev, smc, res); if (!qcom_scm_allow_multicall) mutex_unlock(&qcom_scm_lock); + if (ret) + return ret; if (res->a0 == QCOM_SCM_V2_EBUSY) { if (retry_count++ > QCOM_SCM_EBUSY_MAX_RETRY) @@ -135,6 +190,8 @@ static void __scm_smc_do(const struct arm_smccc_args *smc, msleep(QCOM_SCM_EBUSY_WAIT_MS); } } while (res->a0 == QCOM_SCM_V2_EBUSY); + + return 0; } @@ -143,7 +200,7 @@ int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc, struct qcom_scm_res *res, bool atomic) { int arglen = desc->arginfo & 0xf; - int i; + int i, ret; dma_addr_t args_phys = 0; void *args_virt = NULL; size_t alloc_len; @@ -195,19 +252,24 @@ int __scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc, smc.args[SCM_SMC_LAST_REG_IDX] = args_phys; } - __scm_smc_do(&smc, &smc_res, atomic); + ret = __scm_smc_do(dev, &smc, &smc_res, atomic); + /* ret error check follows after args_virt cleanup*/ if (args_virt) { dma_unmap_single(dev, args_phys, alloc_len, DMA_TO_DEVICE); kfree(args_virt); } + if (ret) + return ret; + if (res) { res->result[0] = smc_res.a1; res->result[1] = smc_res.a2; res->result[2] = smc_res.a3; } - return (long)smc_res.a0 ? qcom_scm_remap_error(smc_res.a0) : 0; + ret = (long)smc_res.a0 ? qcom_scm_remap_error(smc_res.a0) : 0; + return ret; }