Skip to content

Commit 93c9bee

Browse files
ujfalusigregkh
authored andcommitted
ASoC: SOF: Relocate and rework functionality for PCM stream freeing
[ Upstream commit 169ec0a ] Move the sof_pcm_stream_free() from sof-audio.c to pcm.c as static function and add wrapper to free all active stream, which is going to be used in ipc3/4 topology code (removes duplicated code). With this change most of the PCM stream related code is located in one source file for easier lookup and simplified flow. Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Liam Girdwood <liam.r.girdwood@intel.com> Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Link: https://patch.msgid.link/20250206092828.7569-2-peter.ujfalusi@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org> Stable-dep-of: 17661c6 ("ASoC: SOF: ipc4-pcm: Continue the pipeline trigger in case of IPC timeout") Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 925cb11 commit 93c9bee

5 files changed

Lines changed: 71 additions & 71 deletions

File tree

sound/soc/sof/ipc3-topology.c

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2295,28 +2295,16 @@ static int sof_ipc3_set_up_all_pipelines(struct snd_sof_dev *sdev, bool verify)
22952295
static int sof_tear_down_left_over_pipelines(struct snd_sof_dev *sdev)
22962296
{
22972297
struct snd_sof_widget *swidget;
2298-
struct snd_sof_pcm *spcm;
2299-
int dir, ret;
2298+
int ret;
23002299

23012300
/*
23022301
* free all PCMs and their associated DAPM widgets if their connected DAPM widget
23032302
* list is not NULL. This should only be true for paused streams at this point.
23042303
* This is equivalent to the handling of FE DAI suspend trigger for running streams.
23052304
*/
2306-
list_for_each_entry(spcm, &sdev->pcm_list, list) {
2307-
for_each_pcm_streams(dir) {
2308-
struct snd_pcm_substream *substream = spcm->stream[dir].substream;
2309-
2310-
if (!substream || !substream->runtime || spcm->stream[dir].suspend_ignored)
2311-
continue;
2312-
2313-
if (spcm->stream[dir].list) {
2314-
ret = sof_pcm_stream_free(sdev, substream, spcm, dir, true);
2315-
if (ret < 0)
2316-
return ret;
2317-
}
2318-
}
2319-
}
2305+
ret = sof_pcm_free_all_streams(sdev);
2306+
if (ret)
2307+
return ret;
23202308

23212309
/*
23222310
* free any left over DAI widgets. This is equivalent to the handling of suspend trigger

sound/soc/sof/ipc4-topology.c

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2951,9 +2951,6 @@ static int sof_ipc4_dai_get_clk(struct snd_sof_dev *sdev, struct snd_sof_dai *da
29512951

29522952
static int sof_ipc4_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verify)
29532953
{
2954-
struct snd_sof_pcm *spcm;
2955-
int dir, ret;
2956-
29572954
/*
29582955
* This function is called during system suspend, we need to make sure
29592956
* that all streams have been freed up.
@@ -2965,21 +2962,8 @@ static int sof_ipc4_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif
29652962
*
29662963
* This will also make sure that paused streams handled correctly.
29672964
*/
2968-
list_for_each_entry(spcm, &sdev->pcm_list, list) {
2969-
for_each_pcm_streams(dir) {
2970-
struct snd_pcm_substream *substream = spcm->stream[dir].substream;
2971-
2972-
if (!substream || !substream->runtime || spcm->stream[dir].suspend_ignored)
2973-
continue;
29742965

2975-
if (spcm->stream[dir].list) {
2976-
ret = sof_pcm_stream_free(sdev, substream, spcm, dir, true);
2977-
if (ret < 0)
2978-
return ret;
2979-
}
2980-
}
2981-
}
2982-
return 0;
2966+
return sof_pcm_free_all_streams(sdev);
29832967
}
29842968

29852969
static int sof_ipc4_link_setup(struct snd_sof_dev *sdev, struct snd_soc_dai_link *link)

sound/soc/sof/pcm.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,71 @@ static int sof_pcm_hw_params(struct snd_soc_component *component,
191191
return 0;
192192
}
193193

194+
static int sof_pcm_stream_free(struct snd_sof_dev *sdev,
195+
struct snd_pcm_substream *substream,
196+
struct snd_sof_pcm *spcm, int dir,
197+
bool free_widget_list)
198+
{
199+
const struct sof_ipc_pcm_ops *pcm_ops = sof_ipc_get_ops(sdev, pcm);
200+
int ret;
201+
202+
if (spcm->prepared[substream->stream]) {
203+
/* stop DMA first if needed */
204+
if (pcm_ops && pcm_ops->platform_stop_during_hw_free)
205+
snd_sof_pcm_platform_trigger(sdev, substream,
206+
SNDRV_PCM_TRIGGER_STOP);
207+
208+
/* Send PCM_FREE IPC to reset pipeline */
209+
if (pcm_ops && pcm_ops->hw_free) {
210+
ret = pcm_ops->hw_free(sdev->component, substream);
211+
if (ret < 0)
212+
return ret;
213+
}
214+
215+
spcm->prepared[substream->stream] = false;
216+
}
217+
218+
/* reset the DMA */
219+
ret = snd_sof_pcm_platform_hw_free(sdev, substream);
220+
if (ret < 0)
221+
return ret;
222+
223+
/* free widget list */
224+
if (free_widget_list) {
225+
ret = sof_widget_list_free(sdev, spcm, dir);
226+
if (ret < 0)
227+
dev_err(sdev->dev, "failed to free widgets during suspend\n");
228+
}
229+
230+
return ret;
231+
}
232+
233+
int sof_pcm_free_all_streams(struct snd_sof_dev *sdev)
234+
{
235+
struct snd_pcm_substream *substream;
236+
struct snd_sof_pcm *spcm;
237+
int dir, ret;
238+
239+
list_for_each_entry(spcm, &sdev->pcm_list, list) {
240+
for_each_pcm_streams(dir) {
241+
substream = spcm->stream[dir].substream;
242+
243+
if (!substream || !substream->runtime ||
244+
spcm->stream[dir].suspend_ignored)
245+
continue;
246+
247+
if (spcm->stream[dir].list) {
248+
ret = sof_pcm_stream_free(sdev, substream, spcm,
249+
dir, true);
250+
if (ret < 0)
251+
return ret;
252+
}
253+
}
254+
}
255+
256+
return 0;
257+
}
258+
194259
static int sof_pcm_hw_free(struct snd_soc_component *component,
195260
struct snd_pcm_substream *substream)
196261
{

sound/soc/sof/sof-audio.c

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -831,42 +831,6 @@ bool snd_sof_stream_suspend_ignored(struct snd_sof_dev *sdev)
831831
return false;
832832
}
833833

834-
int sof_pcm_stream_free(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream,
835-
struct snd_sof_pcm *spcm, int dir, bool free_widget_list)
836-
{
837-
const struct sof_ipc_pcm_ops *pcm_ops = sof_ipc_get_ops(sdev, pcm);
838-
int ret;
839-
840-
if (spcm->prepared[substream->stream]) {
841-
/* stop DMA first if needed */
842-
if (pcm_ops && pcm_ops->platform_stop_during_hw_free)
843-
snd_sof_pcm_platform_trigger(sdev, substream, SNDRV_PCM_TRIGGER_STOP);
844-
845-
/* Send PCM_FREE IPC to reset pipeline */
846-
if (pcm_ops && pcm_ops->hw_free) {
847-
ret = pcm_ops->hw_free(sdev->component, substream);
848-
if (ret < 0)
849-
return ret;
850-
}
851-
852-
spcm->prepared[substream->stream] = false;
853-
}
854-
855-
/* reset the DMA */
856-
ret = snd_sof_pcm_platform_hw_free(sdev, substream);
857-
if (ret < 0)
858-
return ret;
859-
860-
/* free widget list */
861-
if (free_widget_list) {
862-
ret = sof_widget_list_free(sdev, spcm, dir);
863-
if (ret < 0)
864-
dev_err(sdev->dev, "failed to free widgets during suspend\n");
865-
}
866-
867-
return ret;
868-
}
869-
870834
/*
871835
* Generic object lookup APIs.
872836
*/

sound/soc/sof/sof-audio.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -633,8 +633,7 @@ int sof_widget_list_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm,
633633
int sof_widget_list_free(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, int dir);
634634
int sof_pcm_dsp_pcm_free(struct snd_pcm_substream *substream, struct snd_sof_dev *sdev,
635635
struct snd_sof_pcm *spcm);
636-
int sof_pcm_stream_free(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream,
637-
struct snd_sof_pcm *spcm, int dir, bool free_widget_list);
636+
int sof_pcm_free_all_streams(struct snd_sof_dev *sdev);
638637
int get_token_u32(void *elem, void *object, u32 offset);
639638
int get_token_u16(void *elem, void *object, u32 offset);
640639
int get_token_comp_format(void *elem, void *object, u32 offset);

0 commit comments

Comments
 (0)