Skip to content

Commit c40aad7

Browse files
ujfalusibroonie
authored andcommitted
ASoC: SOF: ipc4-pcm: Workaround for crashed firmware on system suspend
When the system is suspended while audio is active, the sof_ipc4_pcm_hw_free() is invoked to reset the pipelines since during suspend the DSP is turned off, streams will be re-started after resume. If the firmware crashes during while audio is running (or when we reset the stream before suspend) then the sof_ipc4_set_multi_pipeline_state() will fail with IPC error and the state change is interrupted. This will cause misalignment between the kernel and firmware state on next DSP boot resulting errors returned by firmware for IPC messages, eventually failing the audio resume. On stream close the errors are ignored so the kernel state will be corrected on the next DSP boot, so the second boot after the DSP panic. If sof_ipc4_trigger_pipelines() is called from sof_ipc4_pcm_hw_free() then state parameter is SOF_IPC4_PIPE_RESET and only in this case. Treat a forced pipeline reset similarly to how we treat a pcm_free by ignoring error on state sending to allow the kernel's state to be consistent with the state the firmware will have after the next boot. Link: thesofproject/sof#8721 Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com> Link: https://msgid.link/r/20240213115233.15716-1-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 5b5089e commit c40aad7

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

sound/soc/sof/ipc4-pcm.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,18 @@ static int sof_ipc4_trigger_pipelines(struct snd_soc_component *component,
413413
ret = sof_ipc4_set_multi_pipeline_state(sdev, state, trigger_list);
414414
if (ret < 0) {
415415
dev_err(sdev->dev, "failed to set final state %d for all pipelines\n", state);
416-
goto free;
416+
/*
417+
* workaround: if the firmware is crashed while setting the
418+
* pipelines to reset state we must ignore the error code and
419+
* reset it to 0.
420+
* Since the firmware is crashed we will not send IPC messages
421+
* and we are going to see errors printed, but the state of the
422+
* widgets will be correct for the next boot.
423+
*/
424+
if (sdev->fw_state != SOF_FW_CRASHED || state != SOF_IPC4_PIPE_RESET)
425+
goto free;
426+
427+
ret = 0;
417428
}
418429

419430
/* update RUNNING/RESET state for all pipelines that were just triggered */

0 commit comments

Comments
 (0)