Skip to content

Commit bbfbb57

Browse files
committed
Merge tag 'qcom-drivers-fixes-for-6.12' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into arm/fixes
Qualcomm driver fixes for v6.12 The Qualcomm EDAC driver's configuration of interrupts is made optional, to avoid violating security constriants on X Elite platform . The SCM drivers' detection mechanism for the presence of SHM bridge in QTEE, is corrected to handle the case where firmware successfully returns that the interface isn't supported. The GLINK driver and the PMIC GLINK interface is updated to handle buffer allocation issues during initialization of the communication channel. Allocation error handling in the socinfo dirver is corrected, and then the fix is corrected. * tag 'qcom-drivers-fixes-for-6.12' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux: soc: qcom: pmic_glink: Handle GLINK intent allocation rejections rpmsg: glink: Handle rejected intent request better soc: qcom: socinfo: fix revision check in qcom_socinfo_probe() firmware: qcom: scm: Return -EOPNOTSUPP for unsupported SHM bridge enabling EDAC/qcom: Make irq configuration optional firmware: qcom: scm: fix a NULL-pointer dereference firmware: qcom: scm: suppress download mode error soc: qcom: Add check devm_kasprintf() returned value MAINTAINERS: Qualcomm SoC: Match reserved-memory bindings Link: https://lore.kernel.org/r/20241101161455.746290-1-andersson@kernel.org Signed-off-by: Arnd Bergmann <arnd@arndb.de>
2 parents 566064e + f8c8791 commit bbfbb57

File tree

8 files changed

+61
-14
lines changed

8 files changed

+61
-14
lines changed

MAINTAINERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2852,7 +2852,7 @@ F: Documentation/devicetree/bindings/arm/qcom.yaml
28522852
F: Documentation/devicetree/bindings/bus/qcom*
28532853
F: Documentation/devicetree/bindings/cache/qcom,llcc.yaml
28542854
F: Documentation/devicetree/bindings/firmware/qcom,scm.yaml
2855-
F: Documentation/devicetree/bindings/reserved-memory/qcom
2855+
F: Documentation/devicetree/bindings/reserved-memory/qcom*
28562856
F: Documentation/devicetree/bindings/soc/qcom/
28572857
F: arch/arm/boot/dts/qcom/
28582858
F: arch/arm/configs/qcom_defconfig

drivers/edac/qcom_edac.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -342,9 +342,11 @@ static int qcom_llcc_edac_probe(struct platform_device *pdev)
342342
int ecc_irq;
343343
int rc;
344344

345-
rc = qcom_llcc_core_setup(llcc_driv_data, llcc_driv_data->bcast_regmap);
346-
if (rc)
347-
return rc;
345+
if (!llcc_driv_data->ecc_irq_configured) {
346+
rc = qcom_llcc_core_setup(llcc_driv_data, llcc_driv_data->bcast_regmap);
347+
if (rc)
348+
return rc;
349+
}
348350

349351
/* Allocate edac control info */
350352
edev_ctl = edac_device_alloc_ctl_info(0, "qcom-llcc", 1, "bank",

drivers/firmware/qcom/qcom_scm.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ enum qcom_scm_qseecom_tz_cmd_info {
112112
};
113113

114114
#define QSEECOM_MAX_APP_NAME_SIZE 64
115+
#define SHMBRIDGE_RESULT_NOTSUPP 4
115116

116117
/* Each bit configures cold/warm boot address for one of the 4 CPUs */
117118
static const u8 qcom_scm_cpu_cold_bits[QCOM_SCM_BOOT_MAX_CPUS] = {
@@ -216,7 +217,7 @@ static DEFINE_SPINLOCK(scm_query_lock);
216217

217218
struct qcom_tzmem_pool *qcom_scm_get_tzmem_pool(void)
218219
{
219-
return __scm->mempool;
220+
return __scm ? __scm->mempool : NULL;
220221
}
221222

222223
static enum qcom_scm_convention __get_convention(void)
@@ -545,7 +546,7 @@ static void qcom_scm_set_download_mode(u32 dload_mode)
545546
} else if (__qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_BOOT,
546547
QCOM_SCM_BOOT_SET_DLOAD_MODE)) {
547548
ret = __qcom_scm_set_dload_mode(__scm->dev, !!dload_mode);
548-
} else {
549+
} else if (dload_mode) {
549550
dev_err(__scm->dev,
550551
"No available mechanism for setting download mode\n");
551552
}
@@ -1361,6 +1362,8 @@ EXPORT_SYMBOL_GPL(qcom_scm_lmh_dcvsh_available);
13611362

13621363
int qcom_scm_shm_bridge_enable(void)
13631364
{
1365+
int ret;
1366+
13641367
struct qcom_scm_desc desc = {
13651368
.svc = QCOM_SCM_SVC_MP,
13661369
.cmd = QCOM_SCM_MP_SHM_BRIDGE_ENABLE,
@@ -1373,7 +1376,15 @@ int qcom_scm_shm_bridge_enable(void)
13731376
QCOM_SCM_MP_SHM_BRIDGE_ENABLE))
13741377
return -EOPNOTSUPP;
13751378

1376-
return qcom_scm_call(__scm->dev, &desc, &res) ?: res.result[0];
1379+
ret = qcom_scm_call(__scm->dev, &desc, &res);
1380+
1381+
if (ret)
1382+
return ret;
1383+
1384+
if (res.result[0] == SHMBRIDGE_RESULT_NOTSUPP)
1385+
return -EOPNOTSUPP;
1386+
1387+
return res.result[0];
13771388
}
13781389
EXPORT_SYMBOL_GPL(qcom_scm_shm_bridge_enable);
13791390

drivers/rpmsg/qcom_glink_native.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,14 +1440,18 @@ static int qcom_glink_request_intent(struct qcom_glink *glink,
14401440
goto unlock;
14411441

14421442
ret = wait_event_timeout(channel->intent_req_wq,
1443-
READ_ONCE(channel->intent_req_result) >= 0 &&
1444-
READ_ONCE(channel->intent_received),
1443+
READ_ONCE(channel->intent_req_result) == 0 ||
1444+
(READ_ONCE(channel->intent_req_result) > 0 &&
1445+
READ_ONCE(channel->intent_received)) ||
1446+
glink->abort_tx,
14451447
10 * HZ);
14461448
if (!ret) {
14471449
dev_err(glink->dev, "intent request timed out\n");
14481450
ret = -ETIMEDOUT;
1451+
} else if (glink->abort_tx) {
1452+
ret = -ECANCELED;
14491453
} else {
1450-
ret = READ_ONCE(channel->intent_req_result) ? 0 : -ECANCELED;
1454+
ret = READ_ONCE(channel->intent_req_result) ? 0 : -EAGAIN;
14511455
}
14521456

14531457
unlock:

drivers/soc/qcom/llcc-qcom.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ struct qcom_llcc_config {
139139
int size;
140140
bool need_llcc_cfg;
141141
bool no_edac;
142+
bool irq_configured;
142143
};
143144

144145
struct qcom_sct_config {
@@ -718,6 +719,7 @@ static const struct qcom_llcc_config x1e80100_cfg[] = {
718719
.need_llcc_cfg = true,
719720
.reg_offset = llcc_v2_1_reg_offset,
720721
.edac_reg_offset = &llcc_v2_1_edac_reg_offset,
722+
.irq_configured = true,
721723
},
722724
};
723725

@@ -1345,6 +1347,7 @@ static int qcom_llcc_probe(struct platform_device *pdev)
13451347
drv_data->cfg = llcc_cfg;
13461348
drv_data->cfg_size = sz;
13471349
drv_data->edac_reg_offset = cfg->edac_reg_offset;
1350+
drv_data->ecc_irq_configured = cfg->irq_configured;
13481351
mutex_init(&drv_data->lock);
13491352
platform_set_drvdata(pdev, drv_data);
13501353

drivers/soc/qcom/pmic_glink.c

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* Copyright (c) 2022, Linaro Ltd
55
*/
66
#include <linux/auxiliary_bus.h>
7+
#include <linux/delay.h>
78
#include <linux/module.h>
89
#include <linux/of.h>
910
#include <linux/platform_device.h>
@@ -13,6 +14,8 @@
1314
#include <linux/soc/qcom/pmic_glink.h>
1415
#include <linux/spinlock.h>
1516

17+
#define PMIC_GLINK_SEND_TIMEOUT (5 * HZ)
18+
1619
enum {
1720
PMIC_GLINK_CLIENT_BATT = 0,
1821
PMIC_GLINK_CLIENT_ALTMODE,
@@ -112,13 +115,29 @@ EXPORT_SYMBOL_GPL(pmic_glink_client_register);
112115
int pmic_glink_send(struct pmic_glink_client *client, void *data, size_t len)
113116
{
114117
struct pmic_glink *pg = client->pg;
118+
bool timeout_reached = false;
119+
unsigned long start;
115120
int ret;
116121

117122
mutex_lock(&pg->state_lock);
118-
if (!pg->ept)
123+
if (!pg->ept) {
119124
ret = -ECONNRESET;
120-
else
121-
ret = rpmsg_send(pg->ept, data, len);
125+
} else {
126+
start = jiffies;
127+
for (;;) {
128+
ret = rpmsg_send(pg->ept, data, len);
129+
if (ret != -EAGAIN)
130+
break;
131+
132+
if (timeout_reached) {
133+
ret = -ETIMEDOUT;
134+
break;
135+
}
136+
137+
usleep_range(1000, 5000);
138+
timeout_reached = time_after(jiffies, start + PMIC_GLINK_SEND_TIMEOUT);
139+
}
140+
}
122141
mutex_unlock(&pg->state_lock);
123142

124143
return ret;

drivers/soc/qcom/socinfo.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -786,10 +786,16 @@ static int qcom_socinfo_probe(struct platform_device *pdev)
786786
qs->attr.revision = devm_kasprintf(&pdev->dev, GFP_KERNEL, "%u.%u",
787787
SOCINFO_MAJOR(le32_to_cpu(info->ver)),
788788
SOCINFO_MINOR(le32_to_cpu(info->ver)));
789-
if (offsetof(struct socinfo, serial_num) <= item_size)
789+
if (!qs->attr.soc_id || !qs->attr.revision)
790+
return -ENOMEM;
791+
792+
if (offsetof(struct socinfo, serial_num) <= item_size) {
790793
qs->attr.serial_number = devm_kasprintf(&pdev->dev, GFP_KERNEL,
791794
"%u",
792795
le32_to_cpu(info->serial_num));
796+
if (!qs->attr.serial_number)
797+
return -ENOMEM;
798+
}
793799

794800
qs->soc_dev = soc_device_register(&qs->attr);
795801
if (IS_ERR(qs->soc_dev))

include/linux/soc/qcom/llcc-qcom.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ struct llcc_edac_reg_offset {
125125
* @num_banks: Number of llcc banks
126126
* @bitmap: Bit map to track the active slice ids
127127
* @ecc_irq: interrupt for llcc cache error detection and reporting
128+
* @ecc_irq_configured: 'True' if firmware has already configured the irq propagation
128129
* @version: Indicates the LLCC version
129130
*/
130131
struct llcc_drv_data {
@@ -139,6 +140,7 @@ struct llcc_drv_data {
139140
u32 num_banks;
140141
unsigned long *bitmap;
141142
int ecc_irq;
143+
bool ecc_irq_configured;
142144
u32 version;
143145
};
144146

0 commit comments

Comments
 (0)