From patchwork Wed Dec 1 13:05:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephan Gerhold X-Patchwork-Id: 519885 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 1A6F3C433F5 for ; Wed, 1 Dec 2021 13:08:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349494AbhLANMM (ORCPT ); Wed, 1 Dec 2021 08:12:12 -0500 Received: from mo4-p01-ob.smtp.rzone.de ([85.215.255.52]:9000 "EHLO mo4-p01-ob.smtp.rzone.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1349493AbhLANMM (ORCPT ); Wed, 1 Dec 2021 08:12:12 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1638364111; s=strato-dkim-0002; d=gerhold.net; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=6Z3g1/mwk77gEhWZbS8sZveQKgDd8C79HMRf2V9exqM=; b=mzoJ827xSG7tLJMh7/svtTNeVbV05vR3GXfbUkj9vhHvGZ1dh2K2Av07ftZBKqp/3v xUuB4P090wp1BKLjJiBuaOxckktKNl+amRWDT7ByfyNd72FvakTU+ZAQB3r4YHlTmeUQ xVIpkDULfWhfxfDP4W9zkMNa6mRayObvaVGAOArxprEee5KCRlWl6xwH1Ri6aWhELj73 qTghQ9D9HLMsua9DLeHtodmm+kILitB/H08XaB08+uSNTAT1Sxki32Yt51EFalYX7MW1 /le1KwX1HsT8vykAgTMOVv/gWpJ2dG3CP8pypH0rztF5UeD0VDqRpRlllJ94V9CBMt5D AfhQ== Authentication-Results: strato.com; dkim=none X-RZG-AUTH: ":P3gBZUipdd93FF5ZZvYFPugejmSTVR2nRPhVORvLd4SsytBXQ7UOGqRde+a0fyL2moo2" X-RZG-CLASS-ID: mo00 Received: from droid.. by smtp.strato.de (RZmta 47.34.10 AUTH) with ESMTPSA id j03bcbxB1D8Ughl (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Wed, 1 Dec 2021 14:08:30 +0100 (CET) From: Stephan Gerhold To: Bjorn Andersson Cc: Daniel Lezcano , linux-arm-msm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-pm@vger.kernel.org, Arnd Bergmann , Andy Gross , Stephan Gerhold , Marek Szyprowski Subject: [PATCH v3 1/4] cpuidle: qcom-spm: Check if any CPU is managed by SPM Date: Wed, 1 Dec 2021 14:05:02 +0100 Message-Id: <20211201130505.257379-2-stephan@gerhold.net> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20211201130505.257379-1-stephan@gerhold.net> References: <20211201130505.257379-1-stephan@gerhold.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org At the moment, the "qcom-spm-cpuidle" platform device is always created, even if none of the CPUs is actually managed by the SPM. On non-qcom platforms this will result in infinite probe-deferral due to the failing qcom_scm_is_available() call. To avoid this, look through the CPU DT nodes and check if there is actually any CPU managed by a SPM (as indicated by the qcom,saw property). It should also be available because e.g. MSM8916 has qcom,saw defined but it's typically not enabled with ARM64/PSCI firmwares. This is needed in preparation of a follow-up change that calls qcom_scm_set_warm_boot_addr() a single time before registering any cpuidle drivers. Otherwise this call might be made even on devices that have this driver enabled but actually make use of PSCI. Fixes: 60f3692b5f0b ("cpuidle: qcom_spm: Detach state machine from main SPM handling") Reported-by: Marek Szyprowski Link: https://lore.kernel.org/r/86e3e09f-a8d7-3dff-3fc6-ddd7d30c5d78@samsung.com/ Signed-off-by: Stephan Gerhold Acked-by: Daniel Lezcano --- Daniel, would be great if you could ack this patch and PATCH 3/4 (the cpuidle part) if they look good to you. I think it's easiest if Bjorn takes them together with the qcom_scm changes through the qcom tree. Marek had an alternative fix for this [1], the difference in this patch is that it avoids creating the platform device entirely if no CPU is managed by a SPM. [1]: https://lore.kernel.org/r/20211020120643.28231-1-m.szyprowski@samsung.com/ --- drivers/cpuidle/cpuidle-qcom-spm.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/drivers/cpuidle/cpuidle-qcom-spm.c b/drivers/cpuidle/cpuidle-qcom-spm.c index 01e77913a414..5f27dcc6c110 100644 --- a/drivers/cpuidle/cpuidle-qcom-spm.c +++ b/drivers/cpuidle/cpuidle-qcom-spm.c @@ -155,6 +155,22 @@ static struct platform_driver spm_cpuidle_driver = { }, }; +static bool __init qcom_spm_find_any_cpu(void) +{ + struct device_node *cpu_node, *saw_node; + + for_each_of_cpu_node(cpu_node) { + saw_node = of_parse_phandle(cpu_node, "qcom,saw", 0); + if (of_device_is_available(saw_node)) { + of_node_put(saw_node); + of_node_put(cpu_node); + return true; + } + of_node_put(saw_node); + } + return false; +} + static int __init qcom_spm_cpuidle_init(void) { struct platform_device *pdev; @@ -164,6 +180,10 @@ static int __init qcom_spm_cpuidle_init(void) if (ret) return ret; + /* Make sure there is actually any CPU managed by the SPM */ + if (!qcom_spm_find_any_cpu()) + return 0; + pdev = platform_device_register_simple("qcom-spm-cpuidle", -1, NULL, 0); if (IS_ERR(pdev)) { From patchwork Wed Dec 1 13:05:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stephan Gerhold X-Patchwork-Id: 519886 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 5D49FC433EF for ; Wed, 1 Dec 2021 13:08:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1349492AbhLANMJ (ORCPT ); Wed, 1 Dec 2021 08:12:09 -0500 Received: from mo4-p02-ob.smtp.rzone.de ([85.215.255.81]:9818 "EHLO mo4-p02-ob.smtp.rzone.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S245389AbhLANMI (ORCPT ); Wed, 1 Dec 2021 08:12:08 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; t=1638364112; s=strato-dkim-0002; d=gerhold.net; h=References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Cc:Date: From:Subject:Sender; bh=e/hPvzPGZcI+sVgz2Roj2+S/UwQDvzs55NReIYR6KFc=; b=DoRcha2EIjcjpPjh8mVueOuUcRRg/8cJOinvrr4PBe7RYRWW6SrTwjg4O/VdPHGBqg 0ywAL+ieALjHjnDe/lxrX1f7CaVnUEkfR5pnuMySGyCuCXp/jjWUBpB9BjbGt4tJuwFd C3OkVMNHM+AhpB0o9AQdSB+RGrVRsPMSKmeX7w2Uew9MB9Ktyz2HDObcctZ5Y2i7dPLH qotzU/Au4apmik1oe65hngeseQoKMbYIvS1gLbrsv3IdogXT/pT/UElng0X6AX3X9D1d GaDA0z70Ih1TP5ok5XuQ7Q0xPS7Jp9p7+y8UXCw6xKcEgLG3IrKJYuUbcj1cQnS56g2Z N1dA== Authentication-Results: strato.com; dkim=none X-RZG-AUTH: ":P3gBZUipdd93FF5ZZvYFPugejmSTVR2nRPhVORvLd4SsytBXQ7UOGqRde+a0fyL2moo2" X-RZG-CLASS-ID: mo00 Received: from droid.. by smtp.strato.de (RZmta 47.34.10 AUTH) with ESMTPSA id j03bcbxB1D8Vghn (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits)) (Client did not present a certificate); Wed, 1 Dec 2021 14:08:31 +0100 (CET) From: Stephan Gerhold To: Bjorn Andersson Cc: Daniel Lezcano , linux-arm-msm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-pm@vger.kernel.org, Arnd Bergmann , Andy Gross , Stephan Gerhold Subject: [PATCH v3 3/4] firmware: qcom: scm: Drop cpumask parameter from set_boot_addr() Date: Wed, 1 Dec 2021 14:05:04 +0100 Message-Id: <20211201130505.257379-4-stephan@gerhold.net> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20211201130505.257379-1-stephan@gerhold.net> References: <20211201130505.257379-1-stephan@gerhold.net> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org qcom_scm_set_cold/warm_boot_addr() currently take a cpumask parameter, but it's not very useful because at the end we always set the same entry address for all CPUs. This also allows speeding up probe of cpuidle-qcom-spm a bit because only one SCM call needs to be made to the TrustZone firmware, instead of one per CPU. The main reason for this change is that it allows implementing the "multi-cluster" variant of the set_boot_addr() call more easily without having to rely on functions that break in certain build configurations or that are not exported to modules. Signed-off-by: Stephan Gerhold Acked-by: Daniel Lezcano --- arch/arm/mach-qcom/platsmp.c | 3 +-- drivers/cpuidle/cpuidle-qcom-spm.c | 8 ++++---- drivers/firmware/qcom_scm.c | 19 ++++++++----------- include/linux/qcom_scm.h | 4 ++-- 4 files changed, 15 insertions(+), 19 deletions(-) diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c index 58a4228455ce..65a0d5ce2bb3 100644 --- a/arch/arm/mach-qcom/platsmp.c +++ b/arch/arm/mach-qcom/platsmp.c @@ -357,8 +357,7 @@ static void __init qcom_smp_prepare_cpus(unsigned int max_cpus) { int cpu; - if (qcom_scm_set_cold_boot_addr(secondary_startup_arm, - cpu_present_mask)) { + if (qcom_scm_set_cold_boot_addr(secondary_startup_arm)) { for_each_present_cpu(cpu) { if (cpu == smp_processor_id()) continue; diff --git a/drivers/cpuidle/cpuidle-qcom-spm.c b/drivers/cpuidle/cpuidle-qcom-spm.c index 5f27dcc6c110..beedf22cbe78 100644 --- a/drivers/cpuidle/cpuidle-qcom-spm.c +++ b/drivers/cpuidle/cpuidle-qcom-spm.c @@ -122,10 +122,6 @@ static int spm_cpuidle_register(struct device *cpuidle_dev, int cpu) if (ret <= 0) return ret ? : -ENODEV; - ret = qcom_scm_set_warm_boot_addr(cpu_resume_arm, cpumask_of(cpu)); - if (ret) - return ret; - return cpuidle_register(&data->cpuidle_driver, NULL); } @@ -136,6 +132,10 @@ static int spm_cpuidle_drv_probe(struct platform_device *pdev) if (!qcom_scm_is_available()) return -EPROBE_DEFER; + ret = qcom_scm_set_warm_boot_addr(cpu_resume_arm); + if (ret) + return dev_err_probe(&pdev->dev, ret, "set warm boot addr failed"); + for_each_possible_cpu(cpu) { ret = spm_cpuidle_register(&pdev->dev, cpu); if (ret && ret != -ENODEV) { diff --git a/drivers/firmware/qcom_scm.c b/drivers/firmware/qcom_scm.c index e0fca80bf6fc..e89be2f0cdec 100644 --- a/drivers/firmware/qcom_scm.c +++ b/drivers/firmware/qcom_scm.c @@ -246,8 +246,7 @@ static bool __qcom_scm_is_call_available(struct device *dev, u32 svc_id, return ret ? false : !!res.result[0]; } -static int qcom_scm_set_boot_addr(void *entry, const cpumask_t *cpus, - const u8 *cpu_bits) +static int qcom_scm_set_boot_addr(void *entry, const u8 *cpu_bits) { int cpu; unsigned int flags = 0; @@ -258,7 +257,7 @@ static int qcom_scm_set_boot_addr(void *entry, const cpumask_t *cpus, .owner = ARM_SMCCC_OWNER_SIP, }; - for_each_cpu(cpu, cpus) { + for_each_present_cpu(cpu) { if (cpu >= QCOM_SCM_BOOT_MAX_CPUS) return -EINVAL; flags |= cpu_bits[cpu]; @@ -271,27 +270,25 @@ static int qcom_scm_set_boot_addr(void *entry, const cpumask_t *cpus, } /** - * qcom_scm_set_warm_boot_addr() - Set the warm boot address for cpus + * qcom_scm_set_warm_boot_addr() - Set the warm boot address for all cpus * @entry: Entry point function for the cpus - * @cpus: The cpumask of cpus that will use the entry point * * Set the Linux entry point for the SCM to transfer control to when coming * out of a power down. CPU power down may be executed on cpuidle or hotplug. */ -int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus) +int qcom_scm_set_warm_boot_addr(void *entry) { - return qcom_scm_set_boot_addr(entry, cpus, qcom_scm_cpu_warm_bits); + return qcom_scm_set_boot_addr(entry, qcom_scm_cpu_warm_bits); } EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr); /** - * qcom_scm_set_cold_boot_addr() - Set the cold boot address for cpus + * qcom_scm_set_cold_boot_addr() - Set the cold boot address for all cpus * @entry: Entry point function for the cpus - * @cpus: The cpumask of cpus that will use the entry point */ -int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus) +int qcom_scm_set_cold_boot_addr(void *entry) { - return qcom_scm_set_boot_addr(entry, cpus, qcom_scm_cpu_cold_bits); + return qcom_scm_set_boot_addr(entry, qcom_scm_cpu_cold_bits); } EXPORT_SYMBOL(qcom_scm_set_cold_boot_addr); diff --git a/include/linux/qcom_scm.h b/include/linux/qcom_scm.h index 81cad9e1e412..048d09e1965b 100644 --- a/include/linux/qcom_scm.h +++ b/include/linux/qcom_scm.h @@ -63,8 +63,8 @@ enum qcom_scm_ice_cipher { extern bool qcom_scm_is_available(void); -extern int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus); -extern int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus); +extern int qcom_scm_set_cold_boot_addr(void *entry); +extern int qcom_scm_set_warm_boot_addr(void *entry); extern void qcom_scm_cpu_power_down(u32 flags); extern int qcom_scm_set_remote_state(u32 state, u32 id);