From patchwork Tue Jan 7 21:04:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Elliot Berman X-Patchwork-Id: 190751 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 10A0BC33C9B for ; Tue, 7 Jan 2020 21:19:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CBBBC2072A for ; Tue, 7 Jan 2020 21:19:23 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=mg.codeaurora.org header.i=@mg.codeaurora.org header.b="mVVn2FZ5" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728832AbgAGVTS (ORCPT ); Tue, 7 Jan 2020 16:19:18 -0500 Received: from mail26.static.mailgun.info ([104.130.122.26]:30572 "EHLO mail26.static.mailgun.info" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729126AbgAGVEw (ORCPT ); Tue, 7 Jan 2020 16:04:52 -0500 DKIM-Signature: a=rsa-sha256; v=1; c=relaxed/relaxed; d=mg.codeaurora.org; q=dns/txt; s=smtp; t=1578431092; h=References: In-Reply-To: Message-Id: Date: Subject: Cc: To: From: Sender; bh=6JoJfmlsv1t0AVxbjwAxs1a9wd+ebLh3QtfdP9Xt1ZE=; b=mVVn2FZ5uT7J1PpF0TKCOC/hB2LKsW3U4c09qXKj3N9bv831X7+1DgMN1Zc94fpH5tGL5quy uK/cPFvlyXSdFWiOmW1DtpomR5BWthmcSDDDxvqaZpe/hoSUezoT7aJBftMyZhUWe7ufHcMO kN5BVI5Bl+hx3i1F0SAS2PEFCuY= X-Mailgun-Sending-Ip: 104.130.122.26 X-Mailgun-Sid: WyI1MzIzYiIsICJsaW51eC1hcm0tbXNtQHZnZXIua2VybmVsLm9yZyIsICJiZTllNGEiXQ== Received: from smtp.codeaurora.org (ec2-35-166-182-171.us-west-2.compute.amazonaws.com [35.166.182.171]) by mxa.mailgun.org with ESMTP id 5e14f273.7f42f8cdd880-smtp-out-n03; Tue, 07 Jan 2020 21:04:51 -0000 (UTC) Received: by smtp.codeaurora.org (Postfix, from userid 1001) id DB0FBC433CB; Tue, 7 Jan 2020 21:04:48 +0000 (UTC) Received: from eberman-linux.qualcomm.com (i-global254.qualcomm.com [199.106.103.254]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: eberman) by smtp.codeaurora.org (Postfix) with ESMTPSA id 12D8BC447AD; Tue, 7 Jan 2020 21:04:45 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org 12D8BC447AD Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: aws-us-west-2-caf-mail-1.web.codeaurora.org; spf=none smtp.mailfrom=eberman@codeaurora.org From: Elliot Berman To: Bjorn Andersson , agross@kernel.org, swboyd@chromium.org, Stephan Gerhold Cc: Elliot Berman , saiprakash.ranjan@codeaurora.org, tsoni@codeaurora.org, sidgup@codeaurora.org, psodagud@codeaurora.org, Brian Masney , linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v5 13/17] firmware: qcom_scm-32: Create common legacy atomic call Date: Tue, 7 Jan 2020 13:04:22 -0800 Message-Id: <1578431066-19600-14-git-send-email-eberman@codeaurora.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1578431066-19600-1-git-send-email-eberman@codeaurora.org> References: <1578431066-19600-1-git-send-email-eberman@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org Per [1], legacy calling convention supports up to 5 arguments and 3 return values. Create one function to support this combination, and remove the original "atomic1" and "atomic2" variants for 1 and 2 arguments. This more closely aligns scm_legacy implementation with scm_smc implementation. [1]: https://source.codeaurora.org/quic/la/kernel/msm-4.9/tree/drivers/soc/qcom/scm.c?h=kernel.lnx.4.9.r28-rel#n1024 Change-Id: I516d920e00d6da99a1f8290c2ed8654c75f268f9 Tested-by: Brian Masney # arm32 Tested-by: Stephan Gerhold Signed-off-by: Elliot Berman --- drivers/firmware/qcom_scm-32.c | 106 ++++++++++++++++++++++++++--------------- 1 file changed, 68 insertions(+), 38 deletions(-) diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c index acd956f..9729a8a 100644 --- a/drivers/firmware/qcom_scm-32.c +++ b/drivers/firmware/qcom_scm-32.c @@ -266,6 +266,8 @@ static int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, return ret; } +#define SCM_LEGACY_ATOMIC_N_REG_ARGS 5 +#define SCM_LEGACY_ATOMIC_FIRST_REG_IDX 2 #define SCM_LEGACY_CLASS_REGISTER (0x2 << 8) #define SCM_LEGACY_MASK_IRQS BIT(5) #define SCM_LEGACY_ATOMIC_ID(svc, cmd, n) \ @@ -275,44 +277,35 @@ static int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc, (n & 0xf)) /** - * qcom_scm_call_atomic1() - Send an atomic SCM command with one argument - * @svc_id: service identifier - * @cmd_id: command identifier - * @arg1: first argument + * qcom_scm_call_atomic() - Send an atomic SCM command with up to 5 arguments + * and 3 return values + * @desc: SCM call descriptor containing arguments + * @res: SCM call return values * * This shall only be used with commands that are guaranteed to be * uninterruptable, atomic and SMP safe. */ -static s32 qcom_scm_call_atomic1(u32 svc, u32 cmd, u32 arg1) +static int qcom_scm_call_atomic(const struct qcom_scm_desc *desc, + struct qcom_scm_res *res) { int context_id; - struct arm_smccc_res res; + struct arm_smccc_res smc_res; + size_t arglen = desc->arginfo & 0xf; - arm_smccc_smc(SCM_LEGACY_ATOMIC_ID(svc, cmd, 1), - (unsigned long)&context_id, arg1, 0, 0, 0, 0, 0, &res); + BUG_ON(arglen > SCM_LEGACY_ATOMIC_N_REG_ARGS); - return res.a0; -} + arm_smccc_smc(SCM_LEGACY_ATOMIC_ID(desc->svc, desc->cmd, arglen), + (unsigned long)&context_id, + desc->args[0], desc->args[1], desc->args[2], + desc->args[3], desc->args[4], 0, &smc_res); -/** - * qcom_scm_call_atomic2() - Send an atomic SCM command with two arguments - * @svc_id: service identifier - * @cmd_id: command identifier - * @arg1: first argument - * @arg2: second argument - * - * This shall only be used with commands that are guaranteed to be - * uninterruptable, atomic and SMP safe. - */ -static s32 qcom_scm_call_atomic2(u32 svc, u32 cmd, u32 arg1, u32 arg2) -{ - int context_id; - struct arm_smccc_res res; - - arm_smccc_smc(SCM_LEGACY_ATOMIC_ID(svc, cmd, 2), - (unsigned long)&context_id, arg1, 0, 0, 0, 0, 0, &res); + if (res) { + res->result[0] = smc_res.a1; + res->result[1] = smc_res.a2; + res->result[2] = smc_res.a3; + } - return res.a0; + return smc_res.a0; } /** @@ -333,6 +326,10 @@ int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus) QCOM_SCM_FLAG_COLDBOOT_CPU2, QCOM_SCM_FLAG_COLDBOOT_CPU3, }; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_BOOT, + .cmd = QCOM_SCM_BOOT_SET_ADDR, + }; if (!cpus || (cpus && cpumask_empty(cpus))) return -EINVAL; @@ -344,8 +341,11 @@ int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus) set_cpu_present(cpu, false); } - return qcom_scm_call_atomic2(QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_SET_ADDR, - flags, virt_to_phys(entry)); + desc.args[0] = flags; + desc.args[1] = virt_to_phys(entry); + desc.arginfo = QCOM_SCM_ARGS(2); + + return qcom_scm_call_atomic(&desc, NULL); } /** @@ -404,8 +404,14 @@ int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry, */ void __qcom_scm_cpu_power_down(u32 flags) { - qcom_scm_call_atomic1(QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_TERMINATE_PC, - flags & QCOM_SCM_FLUSH_FLAG_MASK); + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_BOOT, + .cmd = QCOM_SCM_BOOT_TERMINATE_PC, + .args[0] = flags & QCOM_SCM_FLUSH_FLAG_MASK, + .arginfo = QCOM_SCM_ARGS(1), + }; + + qcom_scm_call_atomic(&desc, NULL); } int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id) @@ -601,8 +607,16 @@ int __qcom_scm_pas_mss_reset(struct device *dev, bool reset) int __qcom_scm_set_dload_mode(struct device *dev, bool enable) { - return qcom_scm_call_atomic2(QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_SET_DLOAD_MODE, - enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0, 0); + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_BOOT, + .cmd = QCOM_SCM_BOOT_SET_DLOAD_MODE, + }; + + desc.args[0] = QCOM_SCM_BOOT_SET_DLOAD_MODE; + desc.args[1] = enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0; + desc.arginfo = QCOM_SCM_ARGS(2); + + return qcom_scm_call_atomic(&desc, NULL); } int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id) @@ -664,18 +678,34 @@ int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr, unsigned int *val) { int ret; + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_IO, + .cmd = QCOM_SCM_IO_READ, + }; + struct qcom_scm_res res; + + desc.args[0] = addr; + desc.arginfo = QCOM_SCM_ARGS(1); - ret = qcom_scm_call_atomic1(QCOM_SCM_SVC_IO, QCOM_SCM_IO_READ, addr); + ret = qcom_scm_call_atomic(&desc, &res); if (ret >= 0) - *val = ret; + *val = res.result[0]; return ret < 0 ? ret : 0; } int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val) { - return qcom_scm_call_atomic2(QCOM_SCM_SVC_IO, QCOM_SCM_IO_WRITE, - addr, val); + struct qcom_scm_desc desc = { + .svc = QCOM_SCM_SVC_IO, + .cmd = QCOM_SCM_IO_WRITE, + }; + + desc.args[0] = addr; + desc.args[1] = val; + desc.arginfo = QCOM_SCM_ARGS(2); + + return qcom_scm_call_atomic(&desc, NULL); } int __qcom_scm_qsmmu500_wait_safe_toggle(struct device *dev, bool enable)