aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSarangdhar Joshi <spjoshi@codeaurora.org>2018-01-05 19:04:20 -0500
committerBjorn Andersson <bjorn.andersson@linaro.org>2018-02-12 14:05:46 -0500
commitdcb57ed43d9ec5e16628c337143cd6b387f42778 (patch)
treef62daf90f0f53b6c78530c8b0af682f19ff49ebb
parent4dd27f544c84c4d079049dd716beee192fcc7e03 (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.c1
-rw-r--r--drivers/remoteproc/qcom_common.c44
-rw-r--r--drivers/remoteproc/qcom_common.h2
-rw-r--r--drivers/remoteproc/qcom_wcnss.c1
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}
80EXPORT_SYMBOL_GPL(qcom_remove_glink_subdev); 81EXPORT_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 */
92int 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}
124EXPORT_SYMBOL_GPL(qcom_register_dump_segments);
125
82static int smd_subdev_probe(struct rproc_subdev *subdev) 126static 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 {
30void qcom_add_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink); 30void qcom_add_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink);
31void qcom_remove_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink); 31void qcom_remove_glink_subdev(struct rproc *rproc, struct qcom_rproc_glink *glink);
32 32
33int qcom_register_dump_segments(struct rproc *rproc, const struct firmware *fw);
34
33void qcom_add_smd_subdev(struct rproc *rproc, struct qcom_rproc_subdev *smd); 35void qcom_add_smd_subdev(struct rproc *rproc, struct qcom_rproc_subdev *smd);
34void qcom_remove_smd_subdev(struct rproc *rproc, struct qcom_rproc_subdev *smd); 36void 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