Skip to content

Commit 92589cb

Browse files
committed
Merge tag 'rproc-v4.17' of git://github.com/andersson/remoteproc
Pull remoteproc updates from Bjorn Andersson: - add support for generating coredumps for remoteprocs using devcoredump - add the Qualcomm sysmon driver for intra-remoteproc crash handling - a number of fixes in Qualcomm and IMX drivers * tag 'rproc-v4.17' of git://github.com/andersson/remoteproc: remoteproc: fix null pointer dereference on glink only platforms soc: qcom: qmi: add CONFIG_NET dependency remoteproc: imx_rproc: Slightly simplify code in 'imx_rproc_probe()' remoteproc: imx_rproc: Re-use existing error handling path in 'imx_rproc_probe()' remoteproc: imx_rproc: Fix an error handling path in 'imx_rproc_probe()' samples: Introduce Qualcomm QMI sample client remoteproc: qcom: Introduce sysmon remoteproc: Pass type of shutdown to subdev remove remoteproc: qcom: Register segments for core dump soc: qcom: mdt-loader: Return relocation base remoteproc: Rename "load_rsc_table" to "parse_fw" remoteproc: Add remote processor coredump support remoteproc: Remove null character write of shared mem
2 parents 9ab89c4 + 730b2ad commit 92589cb

File tree

21 files changed

+1524
-56
lines changed

21 files changed

+1524
-56
lines changed

drivers/gpu/drm/msm/adreno/a5xx_gpu.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,14 @@ static int zap_shader_load_mdt(struct msm_gpu *gpu, const char *fwname)
8989
*/
9090
if (to_adreno_gpu(gpu)->fwloc == FW_LOCATION_LEGACY) {
9191
ret = qcom_mdt_load(dev, fw, fwname, GPU_PAS_ID,
92-
mem_region, mem_phys, mem_size);
92+
mem_region, mem_phys, mem_size, NULL);
9393
} else {
9494
char newname[strlen("qcom/") + strlen(fwname) + 1];
9595

9696
sprintf(newname, "qcom/%s", fwname);
9797

9898
ret = qcom_mdt_load(dev, fw, newname, GPU_PAS_ID,
99-
mem_region, mem_phys, mem_size);
99+
mem_region, mem_phys, mem_size, NULL);
100100
}
101101
if (ret)
102102
goto out;

drivers/media/platform/qcom/venus/firmware.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ int venus_boot(struct device *dev, const char *fwname)
7676
}
7777

7878
ret = qcom_mdt_load(dev, mdt, fwname, VENUS_PAS_ID, mem_va, mem_phys,
79-
mem_size);
79+
mem_size, NULL);
8080

8181
release_firmware(mdt);
8282

drivers/remoteproc/Kconfig

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ config REMOTEPROC
66
select CRC32
77
select FW_LOADER
88
select VIRTIO
9+
select WANT_DEV_COREDUMP
910
help
1011
Support for remote processors (such as DSP coprocessors). These
1112
are mainly used on embedded systems.
@@ -90,6 +91,7 @@ config QCOM_ADSP_PIL
9091
depends on QCOM_SMEM
9192
depends on RPMSG_QCOM_SMD || (COMPILE_TEST && RPMSG_QCOM_SMD=n)
9293
depends on RPMSG_QCOM_GLINK_SMEM || RPMSG_QCOM_GLINK_SMEM=n
94+
depends on QCOM_SYSMON || QCOM_SYSMON=n
9395
select MFD_SYSCON
9496
select QCOM_MDT_LOADER
9597
select QCOM_RPROC_COMMON
@@ -107,19 +109,36 @@ config QCOM_Q6V5_PIL
107109
depends on QCOM_SMEM
108110
depends on RPMSG_QCOM_SMD || (COMPILE_TEST && RPMSG_QCOM_SMD=n)
109111
depends on RPMSG_QCOM_GLINK_SMEM || RPMSG_QCOM_GLINK_SMEM=n
112+
depends on QCOM_SYSMON || QCOM_SYSMON=n
110113
select MFD_SYSCON
111114
select QCOM_RPROC_COMMON
112115
select QCOM_SCM
113116
help
114117
Say y here to support the Qualcomm Peripherial Image Loader for the
115118
Hexagon V5 based remote processors.
116119

120+
config QCOM_SYSMON
121+
tristate "Qualcomm sysmon driver"
122+
depends on RPMSG
123+
depends on ARCH_QCOM
124+
depends on NET
125+
select QCOM_QMI_HELPERS
126+
help
127+
The sysmon driver implements a sysmon QMI client and a handler for
128+
the sys_mon SMD and GLINK channel, which are used for graceful
129+
shutdown, retrieving failure information and propagating information
130+
about other subsystems being shut down.
131+
132+
Say y here if your system runs firmware on any other subsystems, e.g.
133+
modem or DSP.
134+
117135
config QCOM_WCNSS_PIL
118136
tristate "Qualcomm WCNSS Peripheral Image Loader"
119137
depends on OF && ARCH_QCOM
120138
depends on RPMSG_QCOM_SMD || (COMPILE_TEST && RPMSG_QCOM_SMD=n)
121139
depends on RPMSG_QCOM_GLINK_SMEM || RPMSG_QCOM_GLINK_SMEM=n
122140
depends on QCOM_SMEM
141+
depends on QCOM_SYSMON || QCOM_SYSMON=n
123142
select QCOM_MDT_LOADER
124143
select QCOM_RPROC_COMMON
125144
select QCOM_SCM

drivers/remoteproc/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ obj-$(CONFIG_KEYSTONE_REMOTEPROC) += keystone_remoteproc.o
1717
obj-$(CONFIG_QCOM_ADSP_PIL) += qcom_adsp_pil.o
1818
obj-$(CONFIG_QCOM_RPROC_COMMON) += qcom_common.o
1919
obj-$(CONFIG_QCOM_Q6V5_PIL) += qcom_q6v5_pil.o
20+
obj-$(CONFIG_QCOM_SYSMON) += qcom_sysmon.o
2021
obj-$(CONFIG_QCOM_WCNSS_PIL) += qcom_wcnss_pil.o
2122
qcom_wcnss_pil-y += qcom_wcnss.o
2223
qcom_wcnss_pil-y += qcom_wcnss_iris.o

drivers/remoteproc/imx_rproc.c

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -333,14 +333,14 @@ static int imx_rproc_probe(struct platform_device *pdev)
333333
/* set some other name then imx */
334334
rproc = rproc_alloc(dev, "imx-rproc", &imx_rproc_ops,
335335
NULL, sizeof(*priv));
336-
if (!rproc) {
337-
ret = -ENOMEM;
338-
goto err;
339-
}
336+
if (!rproc)
337+
return -ENOMEM;
340338

341339
dcfg = of_device_get_match_data(dev);
342-
if (!dcfg)
343-
return -EINVAL;
340+
if (!dcfg) {
341+
ret = -EINVAL;
342+
goto err_put_rproc;
343+
}
344344

345345
priv = rproc->priv;
346346
priv->rproc = rproc;
@@ -359,8 +359,8 @@ static int imx_rproc_probe(struct platform_device *pdev)
359359
priv->clk = devm_clk_get(dev, NULL);
360360
if (IS_ERR(priv->clk)) {
361361
dev_err(dev, "Failed to get clock\n");
362-
rproc_free(rproc);
363-
return PTR_ERR(priv->clk);
362+
ret = PTR_ERR(priv->clk);
363+
goto err_put_rproc;
364364
}
365365

366366
/*
@@ -370,8 +370,7 @@ static int imx_rproc_probe(struct platform_device *pdev)
370370
ret = clk_prepare_enable(priv->clk);
371371
if (ret) {
372372
dev_err(&rproc->dev, "Failed to enable clock\n");
373-
rproc_free(rproc);
374-
return ret;
373+
goto err_put_rproc;
375374
}
376375

377376
ret = rproc_add(rproc);
@@ -380,13 +379,13 @@ static int imx_rproc_probe(struct platform_device *pdev)
380379
goto err_put_clk;
381380
}
382381

383-
return ret;
382+
return 0;
384383

385384
err_put_clk:
386385
clk_disable_unprepare(priv->clk);
387386
err_put_rproc:
388387
rproc_free(rproc);
389-
err:
388+
390389
return ret;
391390
}
392391

drivers/remoteproc/qcom_adsp_pil.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@ struct adsp_data {
3838
const char *firmware_name;
3939
int pas_id;
4040
bool has_aggre2_clk;
41+
4142
const char *ssr_name;
43+
const char *sysmon_name;
44+
int ssctl_id;
4245
};
4346

4447
struct qcom_adsp {
@@ -75,14 +78,17 @@ struct qcom_adsp {
7578
struct qcom_rproc_glink glink_subdev;
7679
struct qcom_rproc_subdev smd_subdev;
7780
struct qcom_rproc_ssr ssr_subdev;
81+
struct qcom_sysmon *sysmon;
7882
};
7983

8084
static int adsp_load(struct rproc *rproc, const struct firmware *fw)
8185
{
8286
struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
8387

8488
return qcom_mdt_load(adsp->dev, fw, rproc->firmware, adsp->pas_id,
85-
adsp->mem_region, adsp->mem_phys, adsp->mem_size);
89+
adsp->mem_region, adsp->mem_phys, adsp->mem_size,
90+
&adsp->mem_reloc);
91+
8692
}
8793

8894
static int adsp_start(struct rproc *rproc)
@@ -177,6 +183,7 @@ static const struct rproc_ops adsp_ops = {
177183
.start = adsp_start,
178184
.stop = adsp_stop,
179185
.da_to_va = adsp_da_to_va,
186+
.parse_fw = qcom_register_dump_segments,
180187
.load = adsp_load,
181188
};
182189

@@ -201,9 +208,6 @@ static irqreturn_t adsp_fatal_interrupt(int irq, void *dev)
201208

202209
rproc_report_crash(adsp->rproc, RPROC_FATAL_ERROR);
203210

204-
if (!IS_ERR(msg))
205-
msg[0] = '\0';
206-
207211
return IRQ_HANDLED;
208212
}
209213

@@ -398,6 +402,9 @@ static int adsp_probe(struct platform_device *pdev)
398402
qcom_add_glink_subdev(rproc, &adsp->glink_subdev);
399403
qcom_add_smd_subdev(rproc, &adsp->smd_subdev);
400404
qcom_add_ssr_subdev(rproc, &adsp->ssr_subdev, desc->ssr_name);
405+
adsp->sysmon = qcom_add_sysmon_subdev(rproc,
406+
desc->sysmon_name,
407+
desc->ssctl_id);
401408

402409
ret = rproc_add(rproc);
403410
if (ret)
@@ -419,6 +426,7 @@ static int adsp_remove(struct platform_device *pdev)
419426
rproc_del(adsp->rproc);
420427

421428
qcom_remove_glink_subdev(adsp->rproc, &adsp->glink_subdev);
429+
qcom_remove_sysmon_subdev(adsp->sysmon);
422430
qcom_remove_smd_subdev(adsp->rproc, &adsp->smd_subdev);
423431
qcom_remove_ssr_subdev(adsp->rproc, &adsp->ssr_subdev);
424432
rproc_free(adsp->rproc);
@@ -432,6 +440,8 @@ static const struct adsp_data adsp_resource_init = {
432440
.pas_id = 1,
433441
.has_aggre2_clk = false,
434442
.ssr_name = "lpass",
443+
.sysmon_name = "adsp",
444+
.ssctl_id = 0x14,
435445
};
436446

437447
static const struct adsp_data slpi_resource_init = {
@@ -440,6 +450,8 @@ static const struct adsp_data slpi_resource_init = {
440450
.pas_id = 12,
441451
.has_aggre2_clk = true,
442452
.ssr_name = "dsps",
453+
.sysmon_name = "slpi",
454+
.ssctl_id = 0x16,
443455
};
444456

445457
static const struct of_device_id adsp_of_match[] = {

drivers/remoteproc/qcom_common.c

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/remoteproc.h>
2323
#include <linux/rpmsg/qcom_glink.h>
2424
#include <linux/rpmsg/qcom_smd.h>
25+
#include <linux/soc/qcom/mdt_loader.h>
2526

2627
#include "remoteproc_internal.h"
2728
#include "qcom_common.h"
@@ -41,7 +42,7 @@ static int glink_subdev_probe(struct rproc_subdev *subdev)
4142
return PTR_ERR_OR_ZERO(glink->edge);
4243
}
4344

44-
static void glink_subdev_remove(struct rproc_subdev *subdev)
45+
static void glink_subdev_remove(struct rproc_subdev *subdev, bool crashed)
4546
{
4647
struct qcom_rproc_glink *glink = to_glink_subdev(subdev);
4748

@@ -74,11 +75,57 @@ EXPORT_SYMBOL_GPL(qcom_add_glink_subdev);
7475
*/
7576
void qcom_remove_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink)
7677
{
78+
if (!glink->node)
79+
return;
80+
7781
rproc_remove_subdev(rproc, &glink->subdev);
7882
of_node_put(glink->node);
7983
}
8084
EXPORT_SYMBOL_GPL(qcom_remove_glink_subdev);
8185

86+
/**
87+
* qcom_register_dump_segments() - register segments for coredump
88+
* @rproc: remoteproc handle
89+
* @fw: firmware header
90+
*
91+
* Register all segments of the ELF in the remoteproc coredump segment list
92+
*
93+
* Return: 0 on success, negative errno on failure.
94+
*/
95+
int qcom_register_dump_segments(struct rproc *rproc,
96+
const struct firmware *fw)
97+
{
98+
const struct elf32_phdr *phdrs;
99+
const struct elf32_phdr *phdr;
100+
const struct elf32_hdr *ehdr;
101+
int ret;
102+
int i;
103+
104+
ehdr = (struct elf32_hdr *)fw->data;
105+
phdrs = (struct elf32_phdr *)(ehdr + 1);
106+
107+
for (i = 0; i < ehdr->e_phnum; i++) {
108+
phdr = &phdrs[i];
109+
110+
if (phdr->p_type != PT_LOAD)
111+
continue;
112+
113+
if ((phdr->p_flags & QCOM_MDT_TYPE_MASK) == QCOM_MDT_TYPE_HASH)
114+
continue;
115+
116+
if (!phdr->p_memsz)
117+
continue;
118+
119+
ret = rproc_coredump_add_segment(rproc, phdr->p_paddr,
120+
phdr->p_memsz);
121+
if (ret)
122+
return ret;
123+
}
124+
125+
return 0;
126+
}
127+
EXPORT_SYMBOL_GPL(qcom_register_dump_segments);
128+
82129
static int smd_subdev_probe(struct rproc_subdev *subdev)
83130
{
84131
struct qcom_rproc_subdev *smd = to_smd_subdev(subdev);
@@ -88,7 +135,7 @@ static int smd_subdev_probe(struct rproc_subdev *subdev)
88135
return PTR_ERR_OR_ZERO(smd->edge);
89136
}
90137

91-
static void smd_subdev_remove(struct rproc_subdev *subdev)
138+
static void smd_subdev_remove(struct rproc_subdev *subdev, bool crashed)
92139
{
93140
struct qcom_rproc_subdev *smd = to_smd_subdev(subdev);
94141

@@ -121,6 +168,9 @@ EXPORT_SYMBOL_GPL(qcom_add_smd_subdev);
121168
*/
122169
void qcom_remove_smd_subdev(struct rproc *rproc, struct qcom_rproc_subdev *smd)
123170
{
171+
if (!smd->node)
172+
return;
173+
124174
rproc_remove_subdev(rproc, &smd->subdev);
125175
of_node_put(smd->node);
126176
}
@@ -157,7 +207,7 @@ static int ssr_notify_start(struct rproc_subdev *subdev)
157207
return 0;
158208
}
159209

160-
static void ssr_notify_stop(struct rproc_subdev *subdev)
210+
static void ssr_notify_stop(struct rproc_subdev *subdev, bool crashed)
161211
{
162212
struct qcom_rproc_ssr *ssr = to_ssr_subdev(subdev);
163213

drivers/remoteproc/qcom_common.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
#include <linux/remoteproc.h>
66
#include "remoteproc_internal.h"
7+
#include <linux/soc/qcom/qmi.h>
8+
9+
struct qcom_sysmon;
710

811
struct qcom_rproc_glink {
912
struct rproc_subdev subdev;
@@ -30,11 +33,31 @@ struct qcom_rproc_ssr {
3033
void qcom_add_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink);
3134
void qcom_remove_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink);
3235

36+
int qcom_register_dump_segments(struct rproc *rproc, const struct firmware *fw);
37+
3338
void qcom_add_smd_subdev(struct rproc *rproc, struct qcom_rproc_subdev *smd);
3439
void qcom_remove_smd_subdev(struct rproc *rproc, struct qcom_rproc_subdev *smd);
3540

3641
void qcom_add_ssr_subdev(struct rproc *rproc, struct qcom_rproc_ssr *ssr,
3742
const char *ssr_name);
3843
void qcom_remove_ssr_subdev(struct rproc *rproc, struct qcom_rproc_ssr *ssr);
3944

45+
#if IS_ENABLED(CONFIG_QCOM_SYSMON)
46+
struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
47+
const char *name,
48+
int ssctl_instance);
49+
void qcom_remove_sysmon_subdev(struct qcom_sysmon *sysmon);
50+
#else
51+
static inline struct qcom_sysmon *qcom_add_sysmon_subdev(struct rproc *rproc,
52+
const char *name,
53+
int ssctl_instance)
54+
{
55+
return NULL;
56+
}
57+
58+
static inline void qcom_remove_sysmon_subdev(struct qcom_sysmon *sysmon)
59+
{
60+
}
61+
#endif
62+
4063
#endif

0 commit comments

Comments
 (0)