ASoC: Intel: remove conflicts when load/unload multiple firmware images
Details: 1. Unload all modules on fw_list of dsp when suspend, and reload all modules on fw_list when resume. 2. A DSP expects only one scratch, but hsw_parse_fw_image() allocates scratch blocks for each firmware image it parses. Move the allocate function sst_block_alloc_scratch() out of hsw_parse_fw_image() to make sure a scratch be allocated only after all firmware images be parsed. Signed-off-by: Lu, Han <han.lu@intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Родитель
de251d773b
Коммит
3fe0607a04
|
@ -207,9 +207,6 @@ static int hsw_parse_fw_image(struct sst_fw *sst_fw)
|
|||
module = (void *)module + sizeof(*module) + module->mod_size;
|
||||
}
|
||||
|
||||
/* allocate scratch mem regions */
|
||||
sst_block_alloc_scratch(dsp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1870,6 +1870,7 @@ static void sst_hsw_drop_all(struct sst_hsw *hsw)
|
|||
int sst_hsw_dsp_load(struct sst_hsw *hsw)
|
||||
{
|
||||
struct sst_dsp *dsp = hsw->dsp;
|
||||
struct sst_fw *sst_fw, *t;
|
||||
int ret;
|
||||
|
||||
dev_dbg(hsw->dev, "loading audio DSP....");
|
||||
|
@ -1886,12 +1887,17 @@ int sst_hsw_dsp_load(struct sst_hsw *hsw)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = sst_fw_reload(hsw->sst_fw);
|
||||
if (ret < 0) {
|
||||
dev_err(hsw->dev, "error: SST FW reload failed\n");
|
||||
sst_dsp_dma_put_channel(dsp);
|
||||
return -ENOMEM;
|
||||
list_for_each_entry_safe_reverse(sst_fw, t, &dsp->fw_list, list) {
|
||||
ret = sst_fw_reload(sst_fw);
|
||||
if (ret < 0) {
|
||||
dev_err(hsw->dev, "error: SST FW reload failed\n");
|
||||
sst_dsp_dma_put_channel(dsp);
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
ret = sst_block_alloc_scratch(hsw->dsp);
|
||||
if (ret < 0)
|
||||
return -EINVAL;
|
||||
|
||||
sst_dsp_dma_put_channel(dsp);
|
||||
return 0;
|
||||
|
@ -1947,12 +1953,17 @@ int sst_hsw_dsp_runtime_suspend(struct sst_hsw *hsw)
|
|||
|
||||
int sst_hsw_dsp_runtime_sleep(struct sst_hsw *hsw)
|
||||
{
|
||||
sst_fw_unload(hsw->sst_fw);
|
||||
sst_block_free_scratch(hsw->dsp);
|
||||
struct sst_fw *sst_fw, *t;
|
||||
struct sst_dsp *dsp = hsw->dsp;
|
||||
|
||||
list_for_each_entry_safe(sst_fw, t, &dsp->fw_list, list) {
|
||||
sst_fw_unload(sst_fw);
|
||||
}
|
||||
sst_block_free_scratch(dsp);
|
||||
|
||||
hsw->boot_complete = false;
|
||||
|
||||
sst_dsp_sleep(hsw->dsp);
|
||||
sst_dsp_sleep(dsp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2081,6 +2092,11 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata)
|
|||
goto fw_err;
|
||||
}
|
||||
|
||||
/* allocate scratch mem regions */
|
||||
ret = sst_block_alloc_scratch(hsw->dsp);
|
||||
if (ret < 0)
|
||||
goto boot_err;
|
||||
|
||||
/* wait for DSP boot completion */
|
||||
sst_dsp_boot(hsw->dsp);
|
||||
ret = wait_event_timeout(hsw->boot_wait, hsw->boot_complete,
|
||||
|
|
Загрузка…
Ссылка в новой задаче