mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 04:44:45 +01:00
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:
parent
c17b750b3a
commit
c4c432dfb0
1 changed files with 29 additions and 16 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue