diff options
author | Sarangdhar Joshi <spjoshi@codeaurora.org> | 2018-01-05 19:04:20 -0500 |
---|---|---|
committer | Bjorn Andersson <bjorn.andersson@linaro.org> | 2018-02-12 14:05:46 -0500 |
commit | dcb57ed43d9ec5e16628c337143cd6b387f42778 (patch) | |
tree | f62daf90f0f53b6c78530c8b0af682f19ff49ebb | |
parent | 4dd27f544c84c4d079049dd716beee192fcc7e03 (diff) |
remoteproc: qcom: Register segments for core dump
Register MDT segments with the remoteproc core dump functionality in
order to include them in a core dump, in case of a recovery of the remote
processor.
Signed-off-by: Sarangdhar Joshi <spjoshi@codeaurora.org>
Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
-rw-r--r-- | drivers/remoteproc/qcom_adsp_pil.c | 1 | ||||
-rw-r--r-- | drivers/remoteproc/qcom_common.c | 44 | ||||
-rw-r--r-- | drivers/remoteproc/qcom_common.h | 2 | ||||
-rw-r--r-- | drivers/remoteproc/qcom_wcnss.c | 1 |
4 files changed, 48 insertions, 0 deletions
diff --git a/drivers/remoteproc/qcom_adsp_pil.c b/drivers/remoteproc/qcom_adsp_pil.c index ca2bda9bc71d..ac8f9a77b821 100644 --- a/drivers/remoteproc/qcom_adsp_pil.c +++ b/drivers/remoteproc/qcom_adsp_pil.c | |||
@@ -179,6 +179,7 @@ static const struct rproc_ops adsp_ops = { | |||
179 | .start = adsp_start, | 179 | .start = adsp_start, |
180 | .stop = adsp_stop, | 180 | .stop = adsp_stop, |
181 | .da_to_va = adsp_da_to_va, | 181 | .da_to_va = adsp_da_to_va, |
182 | .parse_fw = qcom_register_dump_segments, | ||
182 | .load = adsp_load, | 183 | .load = adsp_load, |
183 | }; | 184 | }; |
184 | 185 | ||
diff --git a/drivers/remoteproc/qcom_common.c b/drivers/remoteproc/qcom_common.c index 00602499713f..b7d53a9cf21f 100644 --- a/drivers/remoteproc/qcom_common.c +++ b/drivers/remoteproc/qcom_common.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/remoteproc.h> | 22 | #include <linux/remoteproc.h> |
23 | #include <linux/rpmsg/qcom_glink.h> | 23 | #include <linux/rpmsg/qcom_glink.h> |
24 | #include <linux/rpmsg/qcom_smd.h> | 24 | #include <linux/rpmsg/qcom_smd.h> |
25 | #include <linux/soc/qcom/mdt_loader.h> | ||
25 | 26 | ||
26 | #include "remoteproc_internal.h" | 27 | #include "remoteproc_internal.h" |
27 | #include "qcom_common.h" | 28 | #include "qcom_common.h" |
@@ -79,6 +80,49 @@ void qcom_remove_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glin | |||
79 | } | 80 | } |
80 | EXPORT_SYMBOL_GPL(qcom_remove_glink_subdev); | 81 | EXPORT_SYMBOL_GPL(qcom_remove_glink_subdev); |
81 | 82 | ||
83 | /** | ||
84 | * qcom_register_dump_segments() - register segments for coredump | ||
85 | * @rproc: remoteproc handle | ||
86 | * @fw: firmware header | ||
87 | * | ||
88 | * Register all segments of the ELF in the remoteproc coredump segment list | ||
89 | * | ||
90 | * Return: 0 on success, negative errno on failure. | ||
91 | */ | ||
92 | int qcom_register_dump_segments(struct rproc *rproc, | ||
93 | const struct firmware *fw) | ||
94 | { | ||
95 | const struct elf32_phdr *phdrs; | ||
96 | const struct elf32_phdr *phdr; | ||
97 | const struct elf32_hdr *ehdr; | ||
98 | int ret; | ||
99 | int i; | ||
100 | |||
101 | ehdr = (struct elf32_hdr *)fw->data; | ||
102 | phdrs = (struct elf32_phdr *)(ehdr + 1); | ||
103 | |||
104 | for (i = 0; i < ehdr->e_phnum; i++) { | ||
105 | phdr = &phdrs[i]; | ||
106 | |||
107 | if (phdr->p_type != PT_LOAD) | ||
108 | continue; | ||
109 | |||
110 | if ((phdr->p_flags & QCOM_MDT_TYPE_MASK) == QCOM_MDT_TYPE_HASH) | ||
111 | continue; | ||
112 | |||
113 | if (!phdr->p_memsz) | ||
114 | continue; | ||
115 | |||
116 | ret = rproc_coredump_add_segment(rproc, phdr->p_paddr, | ||
117 | phdr->p_memsz); | ||
118 | if (ret) | ||
119 | return ret; | ||
120 | } | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | EXPORT_SYMBOL_GPL(qcom_register_dump_segments); | ||
125 | |||
82 | static int smd_subdev_probe(struct rproc_subdev *subdev) | 126 | static int smd_subdev_probe(struct rproc_subdev *subdev) |
83 | { | 127 | { |
84 | struct qcom_rproc_subdev *smd = to_smd_subdev(subdev); | 128 | struct qcom_rproc_subdev *smd = to_smd_subdev(subdev); |
diff --git a/drivers/remoteproc/qcom_common.h b/drivers/remoteproc/qcom_common.h index 728be9834d8b..7e614520fb69 100644 --- a/drivers/remoteproc/qcom_common.h +++ b/drivers/remoteproc/qcom_common.h | |||
@@ -30,6 +30,8 @@ struct qcom_rproc_ssr { | |||
30 | void qcom_add_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink); | 30 | void qcom_add_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink); |
31 | void qcom_remove_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink); | 31 | void qcom_remove_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink); |
32 | 32 | ||
33 | int qcom_register_dump_segments(struct rproc *rproc, const struct firmware *fw); | ||
34 | |||
33 | void qcom_add_smd_subdev(struct rproc *rproc, struct qcom_rproc_subdev *smd); | 35 | void qcom_add_smd_subdev(struct rproc *rproc, struct qcom_rproc_subdev *smd); |
34 | void qcom_remove_smd_subdev(struct rproc *rproc, struct qcom_rproc_subdev *smd); | 36 | void qcom_remove_smd_subdev(struct rproc *rproc, struct qcom_rproc_subdev *smd); |
35 | 37 | ||
diff --git a/drivers/remoteproc/qcom_wcnss.c b/drivers/remoteproc/qcom_wcnss.c index f1ae5ecbc392..32a3a53589dc 100644 --- a/drivers/remoteproc/qcom_wcnss.c +++ b/drivers/remoteproc/qcom_wcnss.c | |||
@@ -309,6 +309,7 @@ static const struct rproc_ops wcnss_ops = { | |||
309 | .start = wcnss_start, | 309 | .start = wcnss_start, |
310 | .stop = wcnss_stop, | 310 | .stop = wcnss_stop, |
311 | .da_to_va = wcnss_da_to_va, | 311 | .da_to_va = wcnss_da_to_va, |
312 | .parse_fw = qcom_register_dump_segments, | ||
312 | .load = wcnss_load, | 313 | .load = wcnss_load, |
313 | }; | 314 | }; |
314 | 315 | ||