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: Rander Wang <rander.wang@intel.com> Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com> Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Link: https://msgid.link/r/20240402151828.175002-14-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
bfe9225455
commit
a6f2b279d2
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user