Commit a6f2b279 authored by Pierre-Louis Bossart's avatar Pierre-Louis Bossart Committed by Mark Brown

ASoC: SOF: sof-audio: revisit sof_pcm_stream_free() error handling and logs

For some reason the existing code stops on the first error, which
potentially leaves the DMA and widgets in a weird state.

Change to free-up all resources even in case of errors.

Also add a more consistent error handling and logs, with the first
error code returned to the caller.
Reviewed-by: default avatarRander Wang <rander.wang@intel.com>
Reviewed-by: default avatarPéter Ujfalusi <peter.ujfalusi@linux.intel.com>
Signed-off-by: default avatarPierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://msgid.link/r/20240402151828.175002-14-pierre-louis.bossart@linux.intel.comSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent bfe92254
......@@ -834,17 +834,21 @@ int sof_pcm_stream_free(struct snd_sof_dev *sdev, struct snd_pcm_substream *subs
{
const struct sof_ipc_pcm_ops *pcm_ops = sof_ipc_get_ops(sdev, pcm);
int ret;
int err = 0;
if (spcm->prepared[substream->stream]) {
/* stop DMA first if needed */
if (pcm_ops && pcm_ops->platform_stop_during_hw_free)
snd_sof_pcm_platform_trigger(sdev, substream, SNDRV_PCM_TRIGGER_STOP);
/* Send PCM_FREE IPC to reset pipeline */
/* free PCM in the DSP */
if (pcm_ops && pcm_ops->hw_free) {
ret = pcm_ops->hw_free(sdev->component, substream);
if (ret < 0)
return ret;
if (ret < 0) {
dev_err(sdev->dev, "%s: pcm_ops hw_free failed %d\n",
__func__, ret);
err = ret;
}
}
spcm->prepared[substream->stream] = false;
......@@ -852,17 +856,25 @@ int sof_pcm_stream_free(struct snd_sof_dev *sdev, struct snd_pcm_substream *subs
/* reset the DMA */
ret = snd_sof_pcm_platform_hw_free(sdev, substream);
if (ret < 0)
return ret;
if (ret < 0) {
dev_err(sdev->dev, "%s: platform hw free failed %d\n",
__func__, ret);
if (!err)
err = ret;
}
/* free widget list */
if (free_widget_list) {
ret = sof_widget_list_free(sdev, spcm, dir);
if (ret < 0)
dev_err(sdev->dev, "failed to free widgets during suspend\n");
if (ret < 0) {
dev_err(sdev->dev, "%s: sof_widget_list_free failed %d\n",
__func__, ret);
if (!err)
err = ret;
}
}
return ret;
return err;
}
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment