From 0c50b7fcf2773b4853e83fc15aba1a196ba95966 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Mon, 4 Mar 2024 14:14:53 +0100 Subject: [PATCH 01/21] firmware: qcom_scm: disable clocks if qcom_scm_bw_enable() fails There are several functions which are calling qcom_scm_bw_enable() then returns immediately if the call fails and leaves the clocks enabled. Change the code of these functions to disable clocks when the qcom_scm_bw_enable() call fails. This also fixes a possible dma buffer leak in the qcom_scm_pas_init_image() function. Compile tested only due to lack of hardware with interconnect support. Cc: stable@vger.kernel.org Fixes: 65b7ebda5028 ("firmware: qcom_scm: Add bw voting support to the SCM interface") Signed-off-by: Gabor Juhos Reviewed-by: Mukesh Ojha Link: https://lore.kernel.org/r/20240304-qcom-scm-disable-clk-v1-1-b36e51577ca1@gmail.com Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom/qcom_scm.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index 520de9b5633a..e8460626fb0c 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -569,13 +569,14 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size, ret = qcom_scm_bw_enable(); if (ret) - return ret; + goto disable_clk; desc.args[1] = mdata_phys; ret = qcom_scm_call(__scm->dev, &desc, &res); - qcom_scm_bw_disable(); + +disable_clk: qcom_scm_clk_disable(); out: @@ -637,10 +638,12 @@ int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size) ret = qcom_scm_bw_enable(); if (ret) - return ret; + goto disable_clk; ret = qcom_scm_call(__scm->dev, &desc, &res); qcom_scm_bw_disable(); + +disable_clk: qcom_scm_clk_disable(); return ret ? : res.result[0]; @@ -672,10 +675,12 @@ int qcom_scm_pas_auth_and_reset(u32 peripheral) ret = qcom_scm_bw_enable(); if (ret) - return ret; + goto disable_clk; ret = qcom_scm_call(__scm->dev, &desc, &res); qcom_scm_bw_disable(); + +disable_clk: qcom_scm_clk_disable(); return ret ? : res.result[0]; @@ -706,11 +711,12 @@ int qcom_scm_pas_shutdown(u32 peripheral) ret = qcom_scm_bw_enable(); if (ret) - return ret; + goto disable_clk; ret = qcom_scm_call(__scm->dev, &desc, &res); - qcom_scm_bw_disable(); + +disable_clk: qcom_scm_clk_disable(); return ret ? : res.result[0]; From e6f3dac9cf11eff1daddeaa69521370c8941a5f9 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Fri, 8 Mar 2024 10:25:07 +0100 Subject: [PATCH 02/21] firmware: qcom_scm: remove IS_ERR() checks from qcom_scm_bw_{en,dis}able() Since the qcom_scm_probe() function returns with an error if __scm->path contains an error pointer, it is not needed to verify that again in the qcom_scm_bw_{en,dis}able() functions so remove the superfluous IS_ERR() checks. Signed-off-by: Gabor Juhos Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20240308-qcom_scm-is_err-check-v1-1-9c3e1ceefafe@gmail.com Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom/qcom_scm.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index e8460626fb0c..49ddbcab0680 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -163,9 +163,6 @@ static int qcom_scm_bw_enable(void) if (!__scm->path) return 0; - if (IS_ERR(__scm->path)) - return -EINVAL; - mutex_lock(&__scm->scm_bw_lock); if (!__scm->scm_vote_count) { ret = icc_set_bw(__scm->path, 0, UINT_MAX); @@ -183,7 +180,7 @@ err_bw: static void qcom_scm_bw_disable(void) { - if (IS_ERR_OR_NULL(__scm->path)) + if (!__scm->path) return; mutex_lock(&__scm->scm_bw_lock); From a8adf216136a16f8b31ece4455f60d59db3d6d62 Mon Sep 17 00:00:00 2001 From: wangkaiyuan Date: Sat, 9 Mar 2024 15:28:25 +0800 Subject: [PATCH 03/21] soc: qcom: icc-bwmon: Convert to use maple tree register cache The maple tree register cache is based on a much more modern data structure than the rbtree cache and makes optimisation choices which are probably more appropriate for modern systems than those made by the rbtree cache. Signed-off-by: wangkaiyuan Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240309072825.45385-1-wangkaiyuan@inspur.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/icc-bwmon.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/soc/qcom/icc-bwmon.c b/drivers/soc/qcom/icc-bwmon.c index 656706259353..fb323b3364db 100644 --- a/drivers/soc/qcom/icc-bwmon.c +++ b/drivers/soc/qcom/icc-bwmon.c @@ -282,7 +282,7 @@ static const struct regmap_config msm8998_bwmon_regmap_cfg = { * Cache is necessary for using regmap fields with non-readable * registers. */ - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, }; static const struct regmap_config msm8998_bwmon_global_regmap_cfg = { @@ -301,7 +301,7 @@ static const struct regmap_config msm8998_bwmon_global_regmap_cfg = { * Cache is necessary for using regmap fields with non-readable * registers. */ - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, }; static const struct reg_field sdm845_cpu_bwmon_reg_fields[] = { @@ -369,7 +369,7 @@ static const struct regmap_config sdm845_cpu_bwmon_regmap_cfg = { * Cache is necessary for using regmap fields with non-readable * registers. */ - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, }; /* BWMON v5 */ @@ -446,7 +446,7 @@ static const struct regmap_config sdm845_llcc_bwmon_regmap_cfg = { * Cache is necessary for using regmap fields with non-readable * registers. */ - .cache_type = REGCACHE_RBTREE, + .cache_type = REGCACHE_MAPLE, }; static void bwmon_clear_counters(struct icc_bwmon *bwmon, bool clear_all) From 15ec7c641dd3a33f4d7b7c0cc59369d87edcec5c Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Sat, 17 Feb 2024 19:27:07 +0530 Subject: [PATCH 04/21] soc: qcom: Update init level to core_initcall() for cmd-db and rpmh-rsc cmd-db and rpmh-rsc are used by clients like regulators, interconnects and clocks for resource voting. These clients are in core_initcall() while cmd-db and rpmh-rsc are in arch_initcall(). Update init level for these drivers also to core_initcall() to avoid unnecessary probe defer during boot up. Signed-off-by: Maulik Shah Reviewed-by: Ulf Hansson Link: https://lore.kernel.org/r/20240217-init_level-v1-1-bde9e11f8317@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/cmd-db.c | 2 +- drivers/soc/qcom/rpmh-rsc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/soc/qcom/cmd-db.c b/drivers/soc/qcom/cmd-db.c index a5fd68411bed..c344107bc36c 100644 --- a/drivers/soc/qcom/cmd-db.c +++ b/drivers/soc/qcom/cmd-db.c @@ -362,7 +362,7 @@ static int __init cmd_db_device_init(void) { return platform_driver_register(&cmd_db_dev_driver); } -arch_initcall(cmd_db_device_init); +core_initcall(cmd_db_device_init); MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Command DB Driver"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index a021dc71807b..c4c7aad957e6 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -1154,7 +1154,7 @@ static int __init rpmh_driver_init(void) { return platform_driver_register(&rpmh_driver); } -arch_initcall(rpmh_driver_init); +core_initcall(rpmh_driver_init); MODULE_DESCRIPTION("Qualcomm Technologies, Inc. RPMh Driver"); MODULE_LICENSE("GPL v2"); From 734364d0ddee6c145705bac89400266c972efc0b Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Fri, 23 Feb 2024 16:37:55 +0200 Subject: [PATCH 05/21] dt-bindings: arm: qcom,ids: Add SoC ID for X1E80100 Add the ID for the Qualcomm X1E80100 SoC. Signed-off-by: Abel Vesa Reviewed-by: Konrad Dybcio Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240223-x1e80100-socinfo-v1-1-be581ca60f27@linaro.org Signed-off-by: Bjorn Andersson --- include/dt-bindings/arm/qcom,ids.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/dt-bindings/arm/qcom,ids.h b/include/dt-bindings/arm/qcom,ids.h index 19ac7b36f608..d040033dc8ee 100644 --- a/include/dt-bindings/arm/qcom,ids.h +++ b/include/dt-bindings/arm/qcom,ids.h @@ -258,6 +258,7 @@ #define QCOM_ID_QRU1000 539 #define QCOM_ID_SM8475_2 540 #define QCOM_ID_QDU1000 545 +#define QCOM_ID_X1E80100 555 #define QCOM_ID_SM8650 557 #define QCOM_ID_SM4450 568 #define QCOM_ID_QDU1010 587 From e876303c6f18da4c649d97f6d488ee0a850ad384 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Fri, 23 Feb 2024 16:37:56 +0200 Subject: [PATCH 06/21] soc: qcom: socinfo: Add X1E80100 SoC ID table entry Add SoC Info support for the X1E80100 platform. Signed-off-by: Abel Vesa Reviewed-by: Konrad Dybcio Reviewed-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240223-x1e80100-socinfo-v1-2-be581ca60f27@linaro.org Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/socinfo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index e8ff9819ac47..c8e968d7a620 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -430,6 +430,7 @@ static const struct soc_id soc_id[] = { { qcom_board_id(QRU1000) }, { qcom_board_id(SM8475_2) }, { qcom_board_id(QDU1000) }, + { qcom_board_id(X1E80100) }, { qcom_board_id(SM8650) }, { qcom_board_id(SM4450) }, { qcom_board_id(QDU1010) }, From e025171d1ab1edf286c102f7adecafd51c3a84c3 Mon Sep 17 00:00:00 2001 From: Abel Vesa Date: Fri, 23 Feb 2024 16:37:57 +0200 Subject: [PATCH 07/21] soc: qcom: socinfo: Add SMB2360 PMIC The SMB2360 PMIC is used on boards with X1E80100. Signed-off-by: Abel Vesa Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20240223-x1e80100-socinfo-v1-3-be581ca60f27@linaro.org Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/socinfo.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index c8e968d7a620..277c07a6603d 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -133,6 +133,7 @@ static const char *const pmic_models[] = { [72] = "PMR735D", [73] = "PM8550", [74] = "PMK8550", + [82] = "SMB2360", }; struct socinfo_params { From a5b150af2c6ad2749aee51edc36f9f9883869f5b Mon Sep 17 00:00:00 2001 From: Luca Weiss Date: Thu, 8 Feb 2024 10:52:32 +0100 Subject: [PATCH 08/21] dt-bindings: soc: qcom: qcom,pmic-glink: document QCM6490 compatible Document the QCM6490 compatible used to describe the pmic glink on this platform. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Luca Weiss Link: https://lore.kernel.org/r/20240208-fp5-pmic-glink-v2-1-4837d4abd5a4@fairphone.com Signed-off-by: Bjorn Andersson --- Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml index d3f3259ef77d..4310bae6c58e 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,pmic-glink.yaml @@ -23,6 +23,7 @@ properties: oneOf: - items: - enum: + - qcom,qcm6490-pmic-glink - qcom,sc8180x-pmic-glink - qcom,sc8280xp-pmic-glink - qcom,sm8350-pmic-glink From f8627c303fd34ab70ff6fd8a1048ac11035b7fd6 Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Thu, 15 Feb 2024 14:53:50 +0530 Subject: [PATCH 09/21] soc: qcom: qcom_stats: Add DSPs and apss subsystem stats Add SMEM items for compute, general purpose DSPs and application processor subsystem stats. Signed-off-by: Maulik Shah Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/20240215-qcom_stats-v1-1-4a2cf83d0bdd@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/qcom_stats.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/soc/qcom/qcom_stats.c b/drivers/soc/qcom/qcom_stats.c index 0216fc24f2ca..c429d5154aae 100644 --- a/drivers/soc/qcom/qcom_stats.c +++ b/drivers/soc/qcom/qcom_stats.c @@ -35,11 +35,15 @@ static const struct subsystem_data subsystems[] = { { "wpss", 605, 13 }, { "adsp", 606, 2 }, { "cdsp", 607, 5 }, + { "cdsp1", 607, 12 }, + { "gpdsp0", 607, 17 }, + { "gpdsp1", 607, 18 }, { "slpi", 608, 3 }, { "gpu", 609, 0 }, { "display", 610, 0 }, { "adsp_island", 613, 2 }, { "slpi_island", 613, 3 }, + { "apss", 631, QCOM_SMEM_HOST_ANY }, }; struct stats_config { From 8b90269ee6d7f8e714a1ba57a85444a67b9f0104 Mon Sep 17 00:00:00 2001 From: Bjorn Andersson Date: Tue, 19 Mar 2024 17:01:45 -0700 Subject: [PATCH 10/21] MAINTAINERS: Split Qualcomm SoC and linux-arm-msm entries The Qualcomm Support entry in MAINTAINERS has served the purpose of both defining the scope of the Qualcomm support, and to make Qualcomm-related patches show up on the linux-arm-msm mailing list. While this continues to serve our needs, it occasionally do create confusion about the ownership. Split the entry to clarify which components are maintained under the qcom-soc tree. Signed-off-by: Bjorn Andersson Acked-by: Konrad Dybcio Link: https://lore.kernel.org/r/20240319-maintainer-qcom-split-v1-1-735d975af2c2@quicinc.com Signed-off-by: Bjorn Andersson --- MAINTAINERS | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index aa3b947fb080..1f642120fbec 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2586,12 +2586,8 @@ F: arch/arm64/boot/dts/qcom/sc7180* F: arch/arm64/boot/dts/qcom/sc7280* F: arch/arm64/boot/dts/qcom/sdm845-cheza* -ARM/QUALCOMM SUPPORT -M: Bjorn Andersson -M: Konrad Dybcio +ARM/QUALCOMM MAILING LIST L: linux-arm-msm@vger.kernel.org -S: Maintained -T: git git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git F: Documentation/devicetree/bindings/*/qcom* F: Documentation/devicetree/bindings/soc/qcom/ F: arch/arm/boot/dts/qcom/ @@ -2628,6 +2624,33 @@ F: include/dt-bindings/*/qcom* F: include/linux/*/qcom* F: include/linux/soc/qcom/ +ARM/QUALCOMM SUPPORT +M: Bjorn Andersson +M: Konrad Dybcio +L: linux-arm-msm@vger.kernel.org +S: Maintained +T: git git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git +F: Documentation/devicetree/bindings/arm/qcom-soc.yaml +F: Documentation/devicetree/bindings/arm/qcom.yaml +F: Documentation/devicetree/bindings/bus/qcom* +F: Documentation/devicetree/bindings/cache/qcom,llcc.yaml +F: Documentation/devicetree/bindings/firmware/qcom,scm.yaml +F: Documentation/devicetree/bindings/reserved-memory/qcom +F: Documentation/devicetree/bindings/soc/qcom/ +F: arch/arm/boot/dts/qcom/ +F: arch/arm/configs/qcom_defconfig +F: arch/arm/mach-qcom/ +F: arch/arm64/boot/dts/qcom/ +F: drivers/bus/qcom* +F: drivers/firmware/qcom/ +F: drivers/soc/qcom/ +F: include/dt-bindings/arm/qcom,ids.h +F: include/dt-bindings/firmware/qcom,scm.h +F: include/dt-bindings/soc/qcom* +F: include/linux/firmware/qcom +F: include/linux/soc/qcom/ +F: include/soc/qcom/ + ARM/RDA MICRO ARCHITECTURE M: Manivannan Sadhasivam L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) From e478c5fb6aa10af7b7edbff69bc8aef6fbb5f0ed Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Mon, 20 Nov 2023 19:56:23 +0100 Subject: [PATCH 11/21] firmware: qcom: qcm: fix unused qcom_scm_qseecom_allowlist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For !OF builds, the qcom_scm_qseecom_allowlist is unused: drivers/firmware/qcom/qcom_scm.c:1652:34: error: ‘qcom_scm_qseecom_allowlist’ defined but not used [-Werror=unused-const-variable=] Fixes: 00b1248606ba ("firmware: qcom_scm: Add support for Qualcomm Secure Execution Environment SCM interface") Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202311191654.S4wlVUrz-lkp@intel.com/ Signed-off-by: Krzysztof Kozlowski Acked-by: Maximilian Luz Link: https://lore.kernel.org/r/20231120185623.338608-1-krzysztof.kozlowski@linaro.org Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom/qcom_scm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index 49ddbcab0680..81c15aeff934 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -1652,7 +1652,7 @@ EXPORT_SYMBOL_GPL(qcom_scm_qseecom_app_send); * We do not yet support re-entrant calls via the qseecom interface. To prevent + any potential issues with this, only allow validated machines for now. */ -static const struct of_device_id qcom_scm_qseecom_allowlist[] = { +static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = { { .compatible = "lenovo,thinkpad-x13s", }, { } }; From 77706838f837785189578bd8fd768e646e63f8c2 Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Wed, 10 Apr 2024 20:45:22 +0200 Subject: [PATCH 12/21] soc: qcom: mention intentionally broken module autoloading Qualcomm PMIC ChargerPD ULOG and RPM Master Statistics drivers are solely for debugging purposes and should not be autoloaded as modules. Add comments to annotate missing MODULE_DEVICE_TABLE. Signed-off-by: Krzysztof Kozlowski Link: https://lore.kernel.org/r/20240410184522.271889-1-krzk@kernel.org Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/pmic_pdcharger_ulog.c | 4 ++++ drivers/soc/qcom/rpm_master_stats.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/drivers/soc/qcom/pmic_pdcharger_ulog.c b/drivers/soc/qcom/pmic_pdcharger_ulog.c index 238cd38589dc..39f412bbf2c1 100644 --- a/drivers/soc/qcom/pmic_pdcharger_ulog.c +++ b/drivers/soc/qcom/pmic_pdcharger_ulog.c @@ -150,6 +150,10 @@ static const struct rpmsg_device_id pmic_pdcharger_ulog_rpmsg_id_match[] = { { "PMIC_LOGS_ADSP_APPS" }, {} }; +/* + * No MODULE_DEVICE_TABLE intentionally: that's a debugging module, to be + * loaded manually only. + */ static struct rpmsg_driver pmic_pdcharger_ulog_rpmsg_driver = { .probe = pmic_pdcharger_ulog_rpmsg_probe, diff --git a/drivers/soc/qcom/rpm_master_stats.c b/drivers/soc/qcom/rpm_master_stats.c index 9ca13bcf67d3..086fe4ba6707 100644 --- a/drivers/soc/qcom/rpm_master_stats.c +++ b/drivers/soc/qcom/rpm_master_stats.c @@ -148,6 +148,10 @@ static const struct of_device_id rpm_master_table[] = { { .compatible = "qcom,rpm-master-stats" }, { }, }; +/* + * No MODULE_DEVICE_TABLE intentionally: that's a debugging module, to be + * loaded manually only. + */ static struct platform_driver master_stats_driver = { .probe = master_stats_probe, From 635ce0db89567ba62f64b79e8c6664ba3eff6516 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 3 Apr 2024 06:10:57 +0300 Subject: [PATCH 13/21] soc: qcom: pmic_glink: don't traverse clients list without a lock Take the client_lock before traversing the clients list at the pmic_glink_state_notify_clients() function. This is required to keep the list traversal safe from concurrent modification. Fixes: 58ef4ece1e41 ("soc: qcom: pmic_glink: Introduce base PMIC GLINK driver") Signed-off-by: Dmitry Baryshkov Reviewed-by: Andrew Halaney Reviewed-by: Mukesh Ojha Tested-by: Xilin Wu # on QCS8550 AYN Odin 2 Link: https://lore.kernel.org/r/20240403-pmic-glink-fix-clients-v2-1-aed4e02baacc@linaro.org Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/pmic_glink.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/soc/qcom/pmic_glink.c b/drivers/soc/qcom/pmic_glink.c index f913e9bd57ed..2b2cdf479654 100644 --- a/drivers/soc/qcom/pmic_glink.c +++ b/drivers/soc/qcom/pmic_glink.c @@ -115,10 +115,12 @@ static int pmic_glink_rpmsg_callback(struct rpmsg_device *rpdev, void *data, hdr = data; + mutex_lock(&pg->client_lock); list_for_each_entry(client, &pg->clients, node) { if (client->id == le32_to_cpu(hdr->owner)) client->cb(data, len, client->priv); } + mutex_unlock(&pg->client_lock); return 0; } @@ -168,8 +170,10 @@ static void pmic_glink_state_notify_clients(struct pmic_glink *pg) } if (new_state != pg->client_state) { + mutex_lock(&pg->client_lock); list_for_each_entry(client, &pg->clients, node) client->pdr_notify(client->priv, new_state); + mutex_unlock(&pg->client_lock); pg->client_state = new_state; } } From d6cbce2cd354c9a37a558f290a8f1dfd20584f99 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Wed, 3 Apr 2024 06:10:58 +0300 Subject: [PATCH 14/21] soc: qcom: pmic_glink: notify clients about the current state In case the client is registered after the pmic-glink recived a response from the Protection Domain mapper, it is going to miss the notification about the state. Notify clients about the current state upon registration. Fixes: 58ef4ece1e41 ("soc: qcom: pmic_glink: Introduce base PMIC GLINK driver") Reviewed-by: Andrew Halaney Signed-off-by: Dmitry Baryshkov Reviewed-by: Mukesh Ojha Tested-by: Xilin Wu # on QCS8550 AYN Odin 2 Link: https://lore.kernel.org/r/20240403-pmic-glink-fix-clients-v2-2-aed4e02baacc@linaro.org Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/pmic_glink.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/soc/qcom/pmic_glink.c b/drivers/soc/qcom/pmic_glink.c index 2b2cdf479654..e85a12ec2aab 100644 --- a/drivers/soc/qcom/pmic_glink.c +++ b/drivers/soc/qcom/pmic_glink.c @@ -83,9 +83,14 @@ struct pmic_glink_client *devm_pmic_glink_register_client(struct device *dev, client->pdr_notify = pdr; client->priv = priv; + mutex_lock(&pg->state_lock); mutex_lock(&pg->client_lock); + list_add(&client->node, &pg->clients); + client->pdr_notify(client->priv, pg->client_state); + mutex_unlock(&pg->client_lock); + mutex_unlock(&pg->state_lock); devres_add(dev, client); From 3de990f7895906a7a18d2dff63e3e525acaa4ecc Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Thu, 21 Mar 2024 20:53:59 +0530 Subject: [PATCH 15/21] firmware: qcom: scm: Remove log reporting memory allocation failure Remove redundant memory allocation failure. WARNING: Possible unnecessary 'out of memory' message + if (!mdata_buf) { + dev_err(__scm->dev, "Allocation of metadata buffer failed.\n"); Signed-off-by: Mukesh Ojha Reviewed-by: Bjorn Andersson Link: https://lore.kernel.org/r/1711034642-22860-1-git-send-email-quic_mojha@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom/qcom_scm.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index 81c15aeff934..137bda5a0a63 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -554,10 +554,9 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size, */ mdata_buf = dma_alloc_coherent(__scm->dev, size, &mdata_phys, GFP_KERNEL); - if (!mdata_buf) { - dev_err(__scm->dev, "Allocation of metadata buffer failed.\n"); + if (!mdata_buf) return -ENOMEM; - } + memcpy(mdata_buf, metadata, size); ret = qcom_scm_clk_enable(); From 000636d91d605f6209a635a29d0487af5b12b237 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Thu, 21 Mar 2024 20:54:00 +0530 Subject: [PATCH 16/21] firmware: qcom: scm: Remove redundant scm argument from qcom_scm_waitq_wakeup() Remove redundant scm argument from qcom_scm_waitq_wakeup(). Signed-off-by: Mukesh Ojha Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/1711034642-22860-2-git-send-email-quic_mojha@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom/qcom_scm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index 137bda5a0a63..d32fae53be1c 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -1771,7 +1771,7 @@ int qcom_scm_wait_for_wq_completion(u32 wq_ctx) return 0; } -static int qcom_scm_waitq_wakeup(struct qcom_scm *scm, unsigned int wq_ctx) +static int qcom_scm_waitq_wakeup(unsigned int wq_ctx) { int ret; @@ -1803,7 +1803,7 @@ static irqreturn_t qcom_scm_irq_handler(int irq, void *data) goto out; } - ret = qcom_scm_waitq_wakeup(scm, wq_ctx); + ret = qcom_scm_waitq_wakeup(wq_ctx); if (ret) goto out; } while (more_pending); From 398a4c58f3f29ac3ff4d777dc91fe40a07bbca8c Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Thu, 21 Mar 2024 20:54:01 +0530 Subject: [PATCH 17/21] firmware: qcom: scm: Rework dload mode availability check QCOM_SCM_BOOT_SET_DLOAD_MODE scm command is applicable for very older SoCs where this command is supported from firmware and for newer SoCs, dload mode tcsr registers is used for setting the download mode. Currently, qcom_scm_set_download_mode() checks for availability of QCOM_SCM_BOOT_SET_DLOAD_MODE command even for SoCs where this is not used. Fix this by switching the condition to keep the command availability check only if dload mode registers are not available. Signed-off-by: Mukesh Ojha Reviewed-by: Elliot Berman Reviewed-by: Konrad Dybcio Link: https://lore.kernel.org/r/1711034642-22860-3-git-send-email-quic_mojha@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom/qcom_scm.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index d32fae53be1c..d9cee441d81c 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -495,17 +495,14 @@ static int __qcom_scm_set_dload_mode(struct device *dev, bool enable) static void qcom_scm_set_download_mode(bool enable) { - bool avail; int ret = 0; - avail = __qcom_scm_is_call_available(__scm->dev, - QCOM_SCM_SVC_BOOT, - QCOM_SCM_BOOT_SET_DLOAD_MODE); - if (avail) { - ret = __qcom_scm_set_dload_mode(__scm->dev, enable); - } else if (__scm->dload_mode_addr) { + if (__scm->dload_mode_addr) { ret = qcom_scm_io_writel(__scm->dload_mode_addr, - enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0); + enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0); + } else if (__qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_BOOT, + QCOM_SCM_BOOT_SET_DLOAD_MODE)) { + ret = __qcom_scm_set_dload_mode(__scm->dev, enable); } else { dev_err(__scm->dev, "No available mechanism for setting download mode\n"); From 2e4955167ec5c04534cebea9e8273a907e7a75e1 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Thu, 21 Mar 2024 20:54:02 +0530 Subject: [PATCH 18/21] firmware: qcom: scm: Fix __scm and waitq completion variable initialization It is possible qcom_scm_is_available() gives wrong indication that if __scm is initialized while __scm->dev is not and similar issue is also possible with __scm->waitq_comp. Fix this appropriately by the use of release barrier and read barrier that will make sure if __scm is initialized so, is all of its field variable. Fixes: d0f6fa7ba2d6 ("firmware: qcom: scm: Convert SCM to platform driver") Fixes: 6bf325992236 ("firmware: qcom: scm: Add wait-queue handling logic") Signed-off-by: Mukesh Ojha Link: https://lore.kernel.org/r/1711034642-22860-4-git-send-email-quic_mojha@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom/qcom_scm.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index d9cee441d81c..84aa30b5a19e 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -1737,7 +1737,7 @@ static int qcom_scm_qseecom_init(struct qcom_scm *scm) */ bool qcom_scm_is_available(void) { - return !!__scm; + return !!READ_ONCE(__scm); } EXPORT_SYMBOL_GPL(qcom_scm_is_available); @@ -1818,10 +1818,12 @@ static int qcom_scm_probe(struct platform_device *pdev) if (!scm) return -ENOMEM; + scm->dev = &pdev->dev; ret = qcom_scm_find_dload_address(&pdev->dev, &scm->dload_mode_addr); if (ret < 0) return ret; + init_completion(&scm->waitq_comp); mutex_init(&scm->scm_bw_lock); scm->path = devm_of_icc_get(&pdev->dev, NULL); @@ -1853,10 +1855,8 @@ static int qcom_scm_probe(struct platform_device *pdev) if (ret) return ret; - __scm = scm; - __scm->dev = &pdev->dev; - - init_completion(&__scm->waitq_comp); + /* Let all above stores be available after this */ + smp_store_release(&__scm, scm); irq = platform_get_irq_optional(pdev, 0); if (irq < 0) { From b9718298e028f9edbe0fcdf48c02a1c355409410 Mon Sep 17 00:00:00 2001 From: Mukesh Ojha Date: Thu, 21 Mar 2024 23:07:35 +0530 Subject: [PATCH 19/21] firmware: qcom: scm: Modify only the download bits in TCSR register Crashdump collection is done based on DLOAD bits of TCSR register. To retain other bits, scm driver need to read the register and modify only the DLOAD bits, as other bits in TCSR may have their own significance. Co-developed-by: Poovendhan Selvaraj Signed-off-by: Poovendhan Selvaraj Signed-off-by: Mukesh Ojha Tested-by: Kathiravan Thirumoorthy # IPQ9574 and IPQ5332 Reviewed-by: Dmitry Baryshkov Reviewed-by: Elliot Berman Link: https://lore.kernel.org/r/1711042655-31948-1-git-send-email-quic_mojha@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/firmware/qcom/qcom_scm.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index 84aa30b5a19e..5ff62f57aa55 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -4,6 +4,8 @@ */ #include +#include +#include #include #include #include @@ -114,6 +116,10 @@ static const u8 qcom_scm_cpu_warm_bits[QCOM_SCM_BOOT_MAX_CPUS] = { #define QCOM_SMC_WAITQ_FLAG_WAKE_ONE BIT(0) #define QCOM_SMC_WAITQ_FLAG_WAKE_ALL BIT(1) +#define QCOM_DLOAD_MASK GENMASK(5, 4) +#define QCOM_DLOAD_NODUMP 0 +#define QCOM_DLOAD_FULLDUMP 1 + static const char * const qcom_scm_convention_names[] = { [SMC_CONVENTION_UNKNOWN] = "unknown", [SMC_CONVENTION_ARM_32] = "smc arm 32", @@ -493,13 +499,29 @@ static int __qcom_scm_set_dload_mode(struct device *dev, bool enable) return qcom_scm_call_atomic(__scm->dev, &desc, NULL); } +static int qcom_scm_io_rmw(phys_addr_t addr, unsigned int mask, unsigned int val) +{ + unsigned int old; + unsigned int new; + int ret; + + ret = qcom_scm_io_readl(addr, &old); + if (ret) + return ret; + + new = (old & ~mask) | (val & mask); + + return qcom_scm_io_writel(addr, new); +} + static void qcom_scm_set_download_mode(bool enable) { + u32 val = enable ? QCOM_DLOAD_FULLDUMP : QCOM_DLOAD_NODUMP; int ret = 0; if (__scm->dload_mode_addr) { - ret = qcom_scm_io_writel(__scm->dload_mode_addr, - enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0); + ret = qcom_scm_io_rmw(__scm->dload_mode_addr, QCOM_DLOAD_MASK, + FIELD_PREP(QCOM_DLOAD_MASK, val)); } else if (__qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_SET_DLOAD_MODE)) { ret = __qcom_scm_set_dload_mode(__scm->dev, enable); From f592cc5794747b81e53b53dd6e80219ee25f0611 Mon Sep 17 00:00:00 2001 From: Maulik Shah Date: Thu, 15 Feb 2024 10:55:44 +0530 Subject: [PATCH 20/21] soc: qcom: rpmh-rsc: Enhance check for VRM in-flight request Each RPMh VRM accelerator resource has 3 or 4 contiguous 4-byte aligned addresses associated with it. These control voltage, enable state, mode, and in legacy targets, voltage headroom. The current in-flight request checking logic looks for exact address matches. Requests for different addresses of the same RPMh resource as thus not detected as in-flight. Add new cmd-db API cmd_db_match_resource_addr() to enhance the in-flight request check for VRM requests by ignoring the address offset. This ensures that only one request is allowed to be in-flight for a given VRM resource. This is needed to avoid scenarios where request commands are carried out by RPMh hardware out-of-order leading to LDO regulator over-current protection triggering. Fixes: 658628e7ef78 ("drivers: qcom: rpmh-rsc: add RPMH controller for QCOM SoCs") Cc: stable@vger.kernel.org Reviewed-by: Konrad Dybcio Tested-by: Elliot Berman # sm8650-qrd Signed-off-by: Maulik Shah Link: https://lore.kernel.org/r/20240215-rpmh-rsc-fixes-v4-1-9cbddfcba05b@quicinc.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/cmd-db.c | 32 +++++++++++++++++++++++++++++++- drivers/soc/qcom/rpmh-rsc.c | 3 ++- include/soc/qcom/cmd-db.h | 10 +++++++++- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/drivers/soc/qcom/cmd-db.c b/drivers/soc/qcom/cmd-db.c index c344107bc36c..b4e613c34a5c 100644 --- a/drivers/soc/qcom/cmd-db.c +++ b/drivers/soc/qcom/cmd-db.c @@ -1,6 +1,10 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2016-2018, 2020, The Linux Foundation. All rights reserved. */ +/* + * Copyright (c) 2016-2018, 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. + */ +#include #include #include #include @@ -17,6 +21,8 @@ #define MAX_SLV_ID 8 #define SLAVE_ID_MASK 0x7 #define SLAVE_ID_SHIFT 16 +#define SLAVE_ID(addr) FIELD_GET(GENMASK(19, 16), addr) +#define VRM_ADDR(addr) FIELD_GET(GENMASK(19, 4), addr) /** * struct entry_header: header for each entry in cmddb @@ -220,6 +226,30 @@ const void *cmd_db_read_aux_data(const char *id, size_t *len) } EXPORT_SYMBOL_GPL(cmd_db_read_aux_data); +/** + * cmd_db_match_resource_addr() - Compare if both Resource addresses are same + * + * @addr1: Resource address to compare + * @addr2: Resource address to compare + * + * Return: true if two addresses refer to the same resource, false otherwise + */ +bool cmd_db_match_resource_addr(u32 addr1, u32 addr2) +{ + /* + * Each RPMh VRM accelerator resource has 3 or 4 contiguous 4-byte + * aligned addresses associated with it. Ignore the offset to check + * for VRM requests. + */ + if (addr1 == addr2) + return true; + else if (SLAVE_ID(addr1) == CMD_DB_HW_VRM && VRM_ADDR(addr1) == VRM_ADDR(addr2)) + return true; + + return false; +} +EXPORT_SYMBOL_GPL(cmd_db_match_resource_addr); + /** * cmd_db_read_slave_id - Get the slave ID for a given resource address * diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index c4c7aad957e6..561d8037b50a 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0 /* * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved. */ #define pr_fmt(fmt) "%s " fmt, KBUILD_MODNAME @@ -557,7 +558,7 @@ static int check_for_req_inflight(struct rsc_drv *drv, struct tcs_group *tcs, for_each_set_bit(j, &curr_enabled, MAX_CMDS_PER_TCS) { addr = read_tcs_cmd(drv, drv->regs[RSC_DRV_CMD_ADDR], i, j); for (k = 0; k < msg->num_cmds; k++) { - if (addr == msg->cmds[k].addr) + if (cmd_db_match_resource_addr(msg->cmds[k].addr, addr)) return -EBUSY; } } diff --git a/include/soc/qcom/cmd-db.h b/include/soc/qcom/cmd-db.h index c8bb56e6852a..47a6cab75e63 100644 --- a/include/soc/qcom/cmd-db.h +++ b/include/soc/qcom/cmd-db.h @@ -1,5 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. */ +/* + * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved. + */ #ifndef __QCOM_COMMAND_DB_H__ #define __QCOM_COMMAND_DB_H__ @@ -21,6 +24,8 @@ u32 cmd_db_read_addr(const char *resource_id); const void *cmd_db_read_aux_data(const char *resource_id, size_t *len); +bool cmd_db_match_resource_addr(u32 addr1, u32 addr2); + enum cmd_db_hw_type cmd_db_read_slave_id(const char *resource_id); int cmd_db_ready(void); @@ -31,6 +36,9 @@ static inline u32 cmd_db_read_addr(const char *resource_id) static inline const void *cmd_db_read_aux_data(const char *resource_id, size_t *len) { return ERR_PTR(-ENODEV); } +static inline bool cmd_db_match_resource_addr(u32 addr1, u32 addr2) +{ return false; } + static inline enum cmd_db_hw_type cmd_db_read_slave_id(const char *resource_id) { return -ENODEV; } From 166db01007ea802ff9933ac73ec8f140ca0cf5d5 Mon Sep 17 00:00:00 2001 From: Justin Stitt Date: Tue, 19 Mar 2024 21:19:59 +0000 Subject: [PATCH 21/21] soc: qcom: cmd-db: replace deprecated strncpy with strtomem strncpy() is an ambiguous and potentially dangerous interface [1]. We should prefer more robust and less ambiguous alternatives. @query is marked as __nonstring and doesn't need to be NUL-terminated. Since we are doing a string to memory copy, we can use the aptly named "strtomem" -- specifically, the "pad" variant to also ensure NUL-padding throughout the destination buffer. Link: https://www.kernel.org/doc/html/latest/process/deprecated.html#strncpy-on-nul-terminated-strings [1] Link: https://manpages.debian.org/testing/linux-manual-4.8/strscpy.9.en.html [2] Link: https://github.com/KSPP/linux/issues/90 Cc: linux-hardening@vger.kernel.org Reviewed-by: Kees Cook Signed-off-by: Justin Stitt Link: https://lore.kernel.org/r/20240319-strncpy-drivers-soc-qcom-cmd-db-c-v3-1-aeb5c5180c32@google.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/cmd-db.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/soc/qcom/cmd-db.c b/drivers/soc/qcom/cmd-db.c index b4e613c34a5c..d84572662017 100644 --- a/drivers/soc/qcom/cmd-db.c +++ b/drivers/soc/qcom/cmd-db.c @@ -153,12 +153,7 @@ static int cmd_db_get_header(const char *id, const struct entry_header **eh, if (ret) return ret; - /* - * Pad out query string to same length as in DB. NOTE: the output - * query string is not necessarily '\0' terminated if it bumps up - * against the max size. That's OK and expected. - */ - strncpy(query, id, sizeof(query)); + strtomem_pad(query, id, 0); for (i = 0; i < MAX_SLV_ID; i++) { rsc_hdr = &cmd_db_header->header[i];