remoteproc: imx_dsp_rproc: Add support of recovery and coredump process

When enabled FW recovery, but is broken because software reset is missed
in this recovery flow. So move software reset from
imx_dsp_runtime_resume() to .load() and clear memory before loading
firmware to make recovery work.

Add call rproc_coredump_set_elf_info() to initialize the elf info for
coredump, otherwise coredump will report error "ELF class is not set".

Fixes: ec0e5549f3 ("remoteproc: imx_dsp_rproc: Add remoteproc driver for DSP on i.MX")
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Reviewed-by: Daniel Baluta <daniel.baluta@nxp.com>
Link: https://lore.kernel.org/r/20250722075225.544319-1-shengjiu.wang@nxp.com
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
This commit is contained in:
Shengjiu Wang 2025-07-22 15:52:25 +08:00 committed by Mathieu Poirier
parent c17b750b3a
commit c4c432dfb0

View file

@ -774,7 +774,6 @@ static int imx_dsp_rproc_prepare(struct rproc *rproc)
{
struct imx_dsp_rproc *priv = rproc->priv;
struct device *dev = rproc->dev.parent;
struct rproc_mem_entry *carveout;
int ret;
ret = imx_dsp_rproc_add_carveout(priv);
@ -785,15 +784,6 @@ static int imx_dsp_rproc_prepare(struct rproc *rproc)
pm_runtime_get_sync(dev);
/*
* Clear buffers after pm rumtime for internal ocram is not
* accessible if power and clock are not enabled.
*/
list_for_each_entry(carveout, &rproc->carveouts, node) {
if (carveout->va)
memset(carveout->va, 0, carveout->len);
}
return 0;
}
@ -1022,13 +1012,39 @@ static int imx_dsp_rproc_parse_fw(struct rproc *rproc, const struct firmware *fw
return 0;
}
static int imx_dsp_rproc_load(struct rproc *rproc, const struct firmware *fw)
{
struct imx_dsp_rproc *priv = rproc->priv;
const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg;
struct rproc_mem_entry *carveout;
int ret;
/* Reset DSP if needed */
if (dsp_dcfg->reset)
dsp_dcfg->reset(priv);
/*
* Clear buffers after pm rumtime for internal ocram is not
* accessible if power and clock are not enabled.
*/
list_for_each_entry(carveout, &rproc->carveouts, node) {
if (carveout->va)
memset(carveout->va, 0, carveout->len);
}
ret = imx_dsp_rproc_elf_load_segments(rproc, fw);
if (ret)
return ret;
return 0;
}
static const struct rproc_ops imx_dsp_rproc_ops = {
.prepare = imx_dsp_rproc_prepare,
.unprepare = imx_dsp_rproc_unprepare,
.start = imx_dsp_rproc_start,
.stop = imx_dsp_rproc_stop,
.kick = imx_dsp_rproc_kick,
.load = imx_dsp_rproc_elf_load_segments,
.load = imx_dsp_rproc_load,
.parse_fw = imx_dsp_rproc_parse_fw,
.handle_rsc = imx_dsp_rproc_handle_rsc,
.find_loaded_rsc_table = rproc_elf_find_loaded_rsc_table,
@ -1189,6 +1205,8 @@ static int imx_dsp_rproc_probe(struct platform_device *pdev)
goto err_detach_domains;
}
rproc_coredump_set_elf_info(rproc, ELFCLASS32, EM_XTENSA);
pm_runtime_enable(dev);
return 0;
@ -1214,7 +1232,6 @@ static int imx_dsp_runtime_resume(struct device *dev)
{
struct rproc *rproc = dev_get_drvdata(dev);
struct imx_dsp_rproc *priv = rproc->priv;
const struct imx_dsp_rproc_dcfg *dsp_dcfg = priv->dsp_dcfg;
int ret;
/*
@ -1235,10 +1252,6 @@ static int imx_dsp_runtime_resume(struct device *dev)
return ret;
}
/* Reset DSP if needed */
if (dsp_dcfg->reset)
dsp_dcfg->reset(priv);
return 0;
}