Skip to content

Commit 02c2c19

Browse files
committed
Merge tag 'qcom-drivers-for-6.10' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into soc/drivers
Qualcomm driver updates for v6.10 The Qualcomm SCM driver initialization order is improved, to avoid any potential for a client to find a half-initialized SCM instance. The handling of download mode bits is updated to not attempt QCOM_SCM_BOOT_SET_DLOAD_MODE if a io-address for the update is specified, and that path is changed to perform a read-modify-write to avoid updating unrelated bits. Error handling is corrected in the peripheral authentication service (PAS) functions, to release interconnect bandwidth votes in the case of an error. An unwanted error print on allocation error is also removed from this code path. The QSEECOM allow list is marked __maybe_unused to avoid build warnings when built with !OF. The error handling related to the interconnect API is cleaned up to avoid handling the impossible IS_ERR() condition. initcall level is bumped to "core" for cmd-db and rpmh-rsc, as dependent drivers like regulators, interconnects and clocks are registered at this level. Another attempt is made to remove the strncpy() usage in cmd-db, this time with strtomem_pad() which has the correct characteristics. The bwmon regmap cache is changed to maple tree. After an attempt to add missing MODULE_DEVICE_TABLEs to debug drivers, the intention of not having them automatically load is documented. Operations on the pmic_glink client list is put under mutual exclusion, to avoid races when clients are being registered. pmic_glink client registered after the firmware notification arrived was not informed that the firmware was up, this is resolved. More DSPs and the apss subsystem is added to the Qualcomm sleep stats driver. Checks for in-flight regulator requests in the RPMh RSC driver is improved to deal with the fact that these occupy multiple registers, so it's insufficient to just to direct address comparison. The socinfo drivers learns about X1 Elite and SMB2360 PMIC. The maintainers entry is split between the linux-arm-msm list and subset that is maintained in the qcom-soc tree, to avoid some confusion about maintainership. * tag 'qcom-drivers-for-6.10' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux: (21 commits) soc: qcom: cmd-db: replace deprecated strncpy with strtomem soc: qcom: rpmh-rsc: Enhance check for VRM in-flight request firmware: qcom: scm: Modify only the download bits in TCSR register firmware: qcom: scm: Fix __scm and waitq completion variable initialization firmware: qcom: scm: Rework dload mode availability check firmware: qcom: scm: Remove redundant scm argument from qcom_scm_waitq_wakeup() firmware: qcom: scm: Remove log reporting memory allocation failure soc: qcom: pmic_glink: notify clients about the current state soc: qcom: pmic_glink: don't traverse clients list without a lock soc: qcom: mention intentionally broken module autoloading firmware: qcom: qcm: fix unused qcom_scm_qseecom_allowlist MAINTAINERS: Split Qualcomm SoC and linux-arm-msm entries soc: qcom: qcom_stats: Add DSPs and apss subsystem stats dt-bindings: soc: qcom: qcom,pmic-glink: document QCM6490 compatible soc: qcom: socinfo: Add SMB2360 PMIC soc: qcom: socinfo: Add X1E80100 SoC ID table entry dt-bindings: arm: qcom,ids: Add SoC ID for X1E80100 soc: qcom: Update init level to core_initcall() for cmd-db and rpmh-rsc soc: qcom: icc-bwmon: Convert to use maple tree register cache firmware: qcom_scm: remove IS_ERR() checks from qcom_scm_bw_{en,dis}able() ... Link: https://lore.kernel.org/r/20240427160917.1431354-1-andersson@kernel.org Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2 parents cc0739f + 166db01 commit 02c2c19

File tree

12 files changed

+151
-49
lines changed

12 files changed

+151
-49
lines changed

MAINTAINERS

+28-5
Original file line numberDiff line numberDiff line change
@@ -2586,12 +2586,8 @@ F: arch/arm64/boot/dts/qcom/sc7180*
25862586
F: arch/arm64/boot/dts/qcom/sc7280*
25872587
F: arch/arm64/boot/dts/qcom/sdm845-cheza*
25882588

2589-
ARM/QUALCOMM SUPPORT
2590-
M: Bjorn Andersson <andersson@kernel.org>
2591-
M: Konrad Dybcio <konrad.dybcio@linaro.org>
2589+
ARM/QUALCOMM MAILING LIST
25922590
L: linux-arm-msm@vger.kernel.org
2593-
S: Maintained
2594-
T: git git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git
25952591
F: Documentation/devicetree/bindings/*/qcom*
25962592
F: Documentation/devicetree/bindings/soc/qcom/
25972593
F: arch/arm/boot/dts/qcom/
@@ -2628,6 +2624,33 @@ F: include/dt-bindings/*/qcom*
26282624
F: include/linux/*/qcom*
26292625
F: include/linux/soc/qcom/
26302626

2627+
ARM/QUALCOMM SUPPORT
2628+
M: Bjorn Andersson <andersson@kernel.org>
2629+
M: Konrad Dybcio <konrad.dybcio@linaro.org>
2630+
L: linux-arm-msm@vger.kernel.org
2631+
S: Maintained
2632+
T: git git://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux.git
2633+
F: Documentation/devicetree/bindings/arm/qcom-soc.yaml
2634+
F: Documentation/devicetree/bindings/arm/qcom.yaml
2635+
F: Documentation/devicetree/bindings/bus/qcom*
2636+
F: Documentation/devicetree/bindings/cache/qcom,llcc.yaml
2637+
F: Documentation/devicetree/bindings/firmware/qcom,scm.yaml
2638+
F: Documentation/devicetree/bindings/reserved-memory/qcom
2639+
F: Documentation/devicetree/bindings/soc/qcom/
2640+
F: arch/arm/boot/dts/qcom/
2641+
F: arch/arm/configs/qcom_defconfig
2642+
F: arch/arm/mach-qcom/
2643+
F: arch/arm64/boot/dts/qcom/
2644+
F: drivers/bus/qcom*
2645+
F: drivers/firmware/qcom/
2646+
F: drivers/soc/qcom/
2647+
F: include/dt-bindings/arm/qcom,ids.h
2648+
F: include/dt-bindings/firmware/qcom,scm.h
2649+
F: include/dt-bindings/soc/qcom*
2650+
F: include/linux/firmware/qcom
2651+
F: include/linux/soc/qcom/
2652+
F: include/soc/qcom/
2653+
26312654
ARM/RDA MICRO ARCHITECTURE
26322655
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
26332656
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)

drivers/firmware/qcom/qcom_scm.c

+50-29
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
*/
55

66
#include <linux/arm-smccc.h>
7+
#include <linux/bitfield.h>
8+
#include <linux/bits.h>
79
#include <linux/clk.h>
810
#include <linux/completion.h>
911
#include <linux/cpumask.h>
@@ -114,6 +116,10 @@ static const u8 qcom_scm_cpu_warm_bits[QCOM_SCM_BOOT_MAX_CPUS] = {
114116
#define QCOM_SMC_WAITQ_FLAG_WAKE_ONE BIT(0)
115117
#define QCOM_SMC_WAITQ_FLAG_WAKE_ALL BIT(1)
116118

119+
#define QCOM_DLOAD_MASK GENMASK(5, 4)
120+
#define QCOM_DLOAD_NODUMP 0
121+
#define QCOM_DLOAD_FULLDUMP 1
122+
117123
static const char * const qcom_scm_convention_names[] = {
118124
[SMC_CONVENTION_UNKNOWN] = "unknown",
119125
[SMC_CONVENTION_ARM_32] = "smc arm 32",
@@ -163,9 +169,6 @@ static int qcom_scm_bw_enable(void)
163169
if (!__scm->path)
164170
return 0;
165171

166-
if (IS_ERR(__scm->path))
167-
return -EINVAL;
168-
169172
mutex_lock(&__scm->scm_bw_lock);
170173
if (!__scm->scm_vote_count) {
171174
ret = icc_set_bw(__scm->path, 0, UINT_MAX);
@@ -183,7 +186,7 @@ static int qcom_scm_bw_enable(void)
183186

184187
static void qcom_scm_bw_disable(void)
185188
{
186-
if (IS_ERR_OR_NULL(__scm->path))
189+
if (!__scm->path)
187190
return;
188191

189192
mutex_lock(&__scm->scm_bw_lock);
@@ -496,19 +499,32 @@ static int __qcom_scm_set_dload_mode(struct device *dev, bool enable)
496499
return qcom_scm_call_atomic(__scm->dev, &desc, NULL);
497500
}
498501

502+
static int qcom_scm_io_rmw(phys_addr_t addr, unsigned int mask, unsigned int val)
503+
{
504+
unsigned int old;
505+
unsigned int new;
506+
int ret;
507+
508+
ret = qcom_scm_io_readl(addr, &old);
509+
if (ret)
510+
return ret;
511+
512+
new = (old & ~mask) | (val & mask);
513+
514+
return qcom_scm_io_writel(addr, new);
515+
}
516+
499517
static void qcom_scm_set_download_mode(bool enable)
500518
{
501-
bool avail;
519+
u32 val = enable ? QCOM_DLOAD_FULLDUMP : QCOM_DLOAD_NODUMP;
502520
int ret = 0;
503521

504-
avail = __qcom_scm_is_call_available(__scm->dev,
505-
QCOM_SCM_SVC_BOOT,
506-
QCOM_SCM_BOOT_SET_DLOAD_MODE);
507-
if (avail) {
522+
if (__scm->dload_mode_addr) {
523+
ret = qcom_scm_io_rmw(__scm->dload_mode_addr, QCOM_DLOAD_MASK,
524+
FIELD_PREP(QCOM_DLOAD_MASK, val));
525+
} else if (__qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_BOOT,
526+
QCOM_SCM_BOOT_SET_DLOAD_MODE)) {
508527
ret = __qcom_scm_set_dload_mode(__scm->dev, enable);
509-
} else if (__scm->dload_mode_addr) {
510-
ret = qcom_scm_io_writel(__scm->dload_mode_addr,
511-
enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0);
512528
} else {
513529
dev_err(__scm->dev,
514530
"No available mechanism for setting download mode\n");
@@ -557,10 +573,9 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
557573
*/
558574
mdata_buf = dma_alloc_coherent(__scm->dev, size, &mdata_phys,
559575
GFP_KERNEL);
560-
if (!mdata_buf) {
561-
dev_err(__scm->dev, "Allocation of metadata buffer failed.\n");
576+
if (!mdata_buf)
562577
return -ENOMEM;
563-
}
578+
564579
memcpy(mdata_buf, metadata, size);
565580

566581
ret = qcom_scm_clk_enable();
@@ -569,13 +584,14 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size,
569584

570585
ret = qcom_scm_bw_enable();
571586
if (ret)
572-
return ret;
587+
goto disable_clk;
573588

574589
desc.args[1] = mdata_phys;
575590

576591
ret = qcom_scm_call(__scm->dev, &desc, &res);
577-
578592
qcom_scm_bw_disable();
593+
594+
disable_clk:
579595
qcom_scm_clk_disable();
580596

581597
out:
@@ -637,10 +653,12 @@ int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size)
637653

638654
ret = qcom_scm_bw_enable();
639655
if (ret)
640-
return ret;
656+
goto disable_clk;
641657

642658
ret = qcom_scm_call(__scm->dev, &desc, &res);
643659
qcom_scm_bw_disable();
660+
661+
disable_clk:
644662
qcom_scm_clk_disable();
645663

646664
return ret ? : res.result[0];
@@ -672,10 +690,12 @@ int qcom_scm_pas_auth_and_reset(u32 peripheral)
672690

673691
ret = qcom_scm_bw_enable();
674692
if (ret)
675-
return ret;
693+
goto disable_clk;
676694

677695
ret = qcom_scm_call(__scm->dev, &desc, &res);
678696
qcom_scm_bw_disable();
697+
698+
disable_clk:
679699
qcom_scm_clk_disable();
680700

681701
return ret ? : res.result[0];
@@ -706,11 +726,12 @@ int qcom_scm_pas_shutdown(u32 peripheral)
706726

707727
ret = qcom_scm_bw_enable();
708728
if (ret)
709-
return ret;
729+
goto disable_clk;
710730

711731
ret = qcom_scm_call(__scm->dev, &desc, &res);
712-
713732
qcom_scm_bw_disable();
733+
734+
disable_clk:
714735
qcom_scm_clk_disable();
715736

716737
return ret ? : res.result[0];
@@ -1649,7 +1670,7 @@ EXPORT_SYMBOL_GPL(qcom_scm_qseecom_app_send);
16491670
* We do not yet support re-entrant calls via the qseecom interface. To prevent
16501671
+ any potential issues with this, only allow validated machines for now.
16511672
*/
1652-
static const struct of_device_id qcom_scm_qseecom_allowlist[] = {
1673+
static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = {
16531674
{ .compatible = "lenovo,thinkpad-x13s", },
16541675
{ }
16551676
};
@@ -1738,7 +1759,7 @@ static int qcom_scm_qseecom_init(struct qcom_scm *scm)
17381759
*/
17391760
bool qcom_scm_is_available(void)
17401761
{
1741-
return !!__scm;
1762+
return !!READ_ONCE(__scm);
17421763
}
17431764
EXPORT_SYMBOL_GPL(qcom_scm_is_available);
17441765

@@ -1769,7 +1790,7 @@ int qcom_scm_wait_for_wq_completion(u32 wq_ctx)
17691790
return 0;
17701791
}
17711792

1772-
static int qcom_scm_waitq_wakeup(struct qcom_scm *scm, unsigned int wq_ctx)
1793+
static int qcom_scm_waitq_wakeup(unsigned int wq_ctx)
17731794
{
17741795
int ret;
17751796

@@ -1801,7 +1822,7 @@ static irqreturn_t qcom_scm_irq_handler(int irq, void *data)
18011822
goto out;
18021823
}
18031824

1804-
ret = qcom_scm_waitq_wakeup(scm, wq_ctx);
1825+
ret = qcom_scm_waitq_wakeup(wq_ctx);
18051826
if (ret)
18061827
goto out;
18071828
} while (more_pending);
@@ -1819,10 +1840,12 @@ static int qcom_scm_probe(struct platform_device *pdev)
18191840
if (!scm)
18201841
return -ENOMEM;
18211842

1843+
scm->dev = &pdev->dev;
18221844
ret = qcom_scm_find_dload_address(&pdev->dev, &scm->dload_mode_addr);
18231845
if (ret < 0)
18241846
return ret;
18251847

1848+
init_completion(&scm->waitq_comp);
18261849
mutex_init(&scm->scm_bw_lock);
18271850

18281851
scm->path = devm_of_icc_get(&pdev->dev, NULL);
@@ -1854,10 +1877,8 @@ static int qcom_scm_probe(struct platform_device *pdev)
18541877
if (ret)
18551878
return ret;
18561879

1857-
__scm = scm;
1858-
__scm->dev = &pdev->dev;
1859-
1860-
init_completion(&__scm->waitq_comp);
1880+
/* Let all above stores be available after this */
1881+
smp_store_release(&__scm, scm);
18611882

18621883
irq = platform_get_irq_optional(pdev, 0);
18631884
if (irq < 0) {

drivers/soc/qcom/cmd-db.c

+33-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
/* SPDX-License-Identifier: GPL-2.0 */
2-
/* Copyright (c) 2016-2018, 2020, The Linux Foundation. All rights reserved. */
2+
/*
3+
* Copyright (c) 2016-2018, 2020, The Linux Foundation. All rights reserved.
4+
* Copyright (c) 2024, Qualcomm Innovation Center, Inc. All rights reserved.
5+
*/
36

7+
#include <linux/bitfield.h>
48
#include <linux/debugfs.h>
59
#include <linux/kernel.h>
610
#include <linux/module.h>
@@ -17,6 +21,8 @@
1721
#define MAX_SLV_ID 8
1822
#define SLAVE_ID_MASK 0x7
1923
#define SLAVE_ID_SHIFT 16
24+
#define SLAVE_ID(addr) FIELD_GET(GENMASK(19, 16), addr)
25+
#define VRM_ADDR(addr) FIELD_GET(GENMASK(19, 4), addr)
2026

2127
/**
2228
* struct entry_header: header for each entry in cmddb
@@ -147,12 +153,7 @@ static int cmd_db_get_header(const char *id, const struct entry_header **eh,
147153
if (ret)
148154
return ret;
149155

150-
/*
151-
* Pad out query string to same length as in DB. NOTE: the output
152-
* query string is not necessarily '\0' terminated if it bumps up
153-
* against the max size. That's OK and expected.
154-
*/
155-
strncpy(query, id, sizeof(query));
156+
strtomem_pad(query, id, 0);
156157

157158
for (i = 0; i < MAX_SLV_ID; i++) {
158159
rsc_hdr = &cmd_db_header->header[i];
@@ -220,6 +221,30 @@ const void *cmd_db_read_aux_data(const char *id, size_t *len)
220221
}
221222
EXPORT_SYMBOL_GPL(cmd_db_read_aux_data);
222223

224+
/**
225+
* cmd_db_match_resource_addr() - Compare if both Resource addresses are same
226+
*
227+
* @addr1: Resource address to compare
228+
* @addr2: Resource address to compare
229+
*
230+
* Return: true if two addresses refer to the same resource, false otherwise
231+
*/
232+
bool cmd_db_match_resource_addr(u32 addr1, u32 addr2)
233+
{
234+
/*
235+
* Each RPMh VRM accelerator resource has 3 or 4 contiguous 4-byte
236+
* aligned addresses associated with it. Ignore the offset to check
237+
* for VRM requests.
238+
*/
239+
if (addr1 == addr2)
240+
return true;
241+
else if (SLAVE_ID(addr1) == CMD_DB_HW_VRM && VRM_ADDR(addr1) == VRM_ADDR(addr2))
242+
return true;
243+
244+
return false;
245+
}
246+
EXPORT_SYMBOL_GPL(cmd_db_match_resource_addr);
247+
223248
/**
224249
* cmd_db_read_slave_id - Get the slave ID for a given resource address
225250
*
@@ -362,7 +387,7 @@ static int __init cmd_db_device_init(void)
362387
{
363388
return platform_driver_register(&cmd_db_dev_driver);
364389
}
365-
arch_initcall(cmd_db_device_init);
390+
core_initcall(cmd_db_device_init);
366391

367392
MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Command DB Driver");
368393
MODULE_LICENSE("GPL v2");

drivers/soc/qcom/icc-bwmon.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ static const struct regmap_config msm8998_bwmon_regmap_cfg = {
282282
* Cache is necessary for using regmap fields with non-readable
283283
* registers.
284284
*/
285-
.cache_type = REGCACHE_RBTREE,
285+
.cache_type = REGCACHE_MAPLE,
286286
};
287287

288288
static const struct regmap_config msm8998_bwmon_global_regmap_cfg = {
@@ -301,7 +301,7 @@ static const struct regmap_config msm8998_bwmon_global_regmap_cfg = {
301301
* Cache is necessary for using regmap fields with non-readable
302302
* registers.
303303
*/
304-
.cache_type = REGCACHE_RBTREE,
304+
.cache_type = REGCACHE_MAPLE,
305305
};
306306

307307
static const struct reg_field sdm845_cpu_bwmon_reg_fields[] = {
@@ -369,7 +369,7 @@ static const struct regmap_config sdm845_cpu_bwmon_regmap_cfg = {
369369
* Cache is necessary for using regmap fields with non-readable
370370
* registers.
371371
*/
372-
.cache_type = REGCACHE_RBTREE,
372+
.cache_type = REGCACHE_MAPLE,
373373
};
374374

375375
/* BWMON v5 */
@@ -446,7 +446,7 @@ static const struct regmap_config sdm845_llcc_bwmon_regmap_cfg = {
446446
* Cache is necessary for using regmap fields with non-readable
447447
* registers.
448448
*/
449-
.cache_type = REGCACHE_RBTREE,
449+
.cache_type = REGCACHE_MAPLE,
450450
};
451451

452452
static void bwmon_clear_counters(struct icc_bwmon *bwmon, bool clear_all)

0 commit comments

Comments
 (0)