Skip to content

Commit 4c7ae7d

Browse files
ujfalusibardliao
authored andcommitted
ASoC: SOF: Relocate and rework functionality for PCM stream freeing
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>
1 parent f273e69 commit 4c7ae7d

5 files changed

Lines changed: 84 additions & 84 deletions

File tree

sound/soc/sof/ipc3-topology.c

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2386,28 +2386,16 @@ static int sof_ipc3_set_up_all_pipelines(struct snd_sof_dev *sdev, bool verify)
23862386
static int sof_tear_down_left_over_pipelines(struct snd_sof_dev *sdev)
23872387
{
23882388
struct snd_sof_widget *swidget;
2389-
struct snd_sof_pcm *spcm;
2390-
int dir, ret;
2389+
int ret;
23912390

23922391
/*
23932392
* free all PCMs and their associated DAPM widgets if their connected DAPM widget
23942393
* list is not NULL. This should only be true for paused streams at this point.
23952394
* This is equivalent to the handling of FE DAI suspend trigger for running streams.
23962395
*/
2397-
list_for_each_entry(spcm, &sdev->pcm_list, list) {
2398-
for_each_pcm_streams(dir) {
2399-
struct snd_pcm_substream *substream = spcm->stream[dir].substream;
2400-
2401-
if (!substream || !substream->runtime || spcm->stream[dir].suspend_ignored)
2402-
continue;
2403-
2404-
if (spcm->stream[dir].list) {
2405-
ret = sof_pcm_stream_free(sdev, substream, spcm, dir, true);
2406-
if (ret < 0)
2407-
return ret;
2408-
}
2409-
}
2410-
}
2396+
ret = sof_pcm_free_all_streams(sdev);
2397+
if (ret)
2398+
return ret;
24112399

24122400
/*
24132401
* 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
@@ -3409,9 +3409,6 @@ static int sof_ipc4_dai_get_param(struct snd_sof_dev *sdev, struct snd_sof_dai *
34093409

34103410
static int sof_ipc4_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verify)
34113411
{
3412-
struct snd_sof_pcm *spcm;
3413-
int dir, ret;
3414-
34153412
/*
34163413
* This function is called during system suspend, we need to make sure
34173414
* that all streams have been freed up.
@@ -3423,21 +3420,8 @@ static int sof_ipc4_tear_down_all_pipelines(struct snd_sof_dev *sdev, bool verif
34233420
*
34243421
* This will also make sure that paused streams handled correctly.
34253422
*/
3426-
list_for_each_entry(spcm, &sdev->pcm_list, list) {
3427-
for_each_pcm_streams(dir) {
3428-
struct snd_pcm_substream *substream = spcm->stream[dir].substream;
3429-
3430-
if (!substream || !substream->runtime || spcm->stream[dir].suspend_ignored)
3431-
continue;
34323423

3433-
if (spcm->stream[dir].list) {
3434-
ret = sof_pcm_stream_free(sdev, substream, spcm, dir, true);
3435-
if (ret < 0)
3436-
return ret;
3437-
}
3438-
}
3439-
}
3440-
return 0;
3424+
return sof_pcm_free_all_streams(sdev);
34413425
}
34423426

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

sound/soc/sof/pcm.c

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,84 @@ 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+
int err = 0;
202+
203+
if (spcm->prepared[substream->stream]) {
204+
/* stop DMA first if needed */
205+
if (pcm_ops && pcm_ops->platform_stop_during_hw_free)
206+
snd_sof_pcm_platform_trigger(sdev, substream,
207+
SNDRV_PCM_TRIGGER_STOP);
208+
209+
/* free PCM in the DSP */
210+
if (pcm_ops && pcm_ops->hw_free) {
211+
ret = pcm_ops->hw_free(sdev->component, substream);
212+
if (ret < 0) {
213+
dev_err(sdev->dev, "%s: pcm_ops hw_free failed %d\n",
214+
__func__, ret);
215+
err = ret;
216+
}
217+
}
218+
219+
spcm->prepared[substream->stream] = false;
220+
spcm->pending_stop[substream->stream] = false;
221+
}
222+
223+
/* reset the DMA */
224+
ret = snd_sof_pcm_platform_hw_free(sdev, substream);
225+
if (ret < 0) {
226+
dev_err(sdev->dev, "%s: platform hw free failed %d\n",
227+
__func__, ret);
228+
if (!err)
229+
err = ret;
230+
}
231+
232+
/* free widget list */
233+
if (free_widget_list) {
234+
ret = sof_widget_list_free(sdev, spcm, dir);
235+
if (ret < 0) {
236+
dev_err(sdev->dev, "%s: sof_widget_list_free failed %d\n",
237+
__func__, ret);
238+
if (!err)
239+
err = ret;
240+
}
241+
}
242+
243+
return err;
244+
}
245+
246+
int sof_pcm_free_all_streams(struct snd_sof_dev *sdev)
247+
{
248+
struct snd_pcm_substream *substream;
249+
struct snd_sof_pcm *spcm;
250+
int dir, ret;
251+
252+
list_for_each_entry(spcm, &sdev->pcm_list, list) {
253+
for_each_pcm_streams(dir) {
254+
substream = spcm->stream[dir].substream;
255+
256+
if (!substream || !substream->runtime ||
257+
spcm->stream[dir].suspend_ignored)
258+
continue;
259+
260+
if (spcm->stream[dir].list) {
261+
ret = sof_pcm_stream_free(sdev, substream, spcm,
262+
dir, true);
263+
if (ret < 0)
264+
return ret;
265+
}
266+
}
267+
}
268+
269+
return 0;
270+
}
271+
194272
static int sof_pcm_hw_free(struct snd_soc_component *component,
195273
struct snd_pcm_substream *substream)
196274
{

sound/soc/sof/sof-audio.c

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -829,55 +829,6 @@ bool snd_sof_stream_suspend_ignored(struct snd_sof_dev *sdev)
829829
return false;
830830
}
831831

832-
int sof_pcm_stream_free(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream,
833-
struct snd_sof_pcm *spcm, int dir, bool free_widget_list)
834-
{
835-
const struct sof_ipc_pcm_ops *pcm_ops = sof_ipc_get_ops(sdev, pcm);
836-
int ret;
837-
int err = 0;
838-
839-
if (spcm->prepared[substream->stream]) {
840-
/* stop DMA first if needed */
841-
if (pcm_ops && pcm_ops->platform_stop_during_hw_free)
842-
snd_sof_pcm_platform_trigger(sdev, substream, SNDRV_PCM_TRIGGER_STOP);
843-
844-
/* free PCM in the DSP */
845-
if (pcm_ops && pcm_ops->hw_free) {
846-
ret = pcm_ops->hw_free(sdev->component, substream);
847-
if (ret < 0) {
848-
dev_err(sdev->dev, "%s: pcm_ops hw_free failed %d\n",
849-
__func__, ret);
850-
err = ret;
851-
}
852-
}
853-
854-
spcm->prepared[substream->stream] = false;
855-
spcm->pending_stop[substream->stream] = false;
856-
}
857-
858-
/* reset the DMA */
859-
ret = snd_sof_pcm_platform_hw_free(sdev, substream);
860-
if (ret < 0) {
861-
dev_err(sdev->dev, "%s: platform hw free failed %d\n",
862-
__func__, ret);
863-
if (!err)
864-
err = ret;
865-
}
866-
867-
/* free widget list */
868-
if (free_widget_list) {
869-
ret = sof_widget_list_free(sdev, spcm, dir);
870-
if (ret < 0) {
871-
dev_err(sdev->dev, "%s: sof_widget_list_free failed %d\n",
872-
__func__, ret);
873-
if (!err)
874-
err = ret;
875-
}
876-
}
877-
878-
return err;
879-
}
880-
881832
/*
882833
* Generic object lookup APIs.
883834
*/

sound/soc/sof/sof-audio.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -649,8 +649,7 @@ int sof_widget_list_setup(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm,
649649
int sof_widget_list_free(struct snd_sof_dev *sdev, struct snd_sof_pcm *spcm, int dir);
650650
int sof_pcm_dsp_pcm_free(struct snd_pcm_substream *substream, struct snd_sof_dev *sdev,
651651
struct snd_sof_pcm *spcm);
652-
int sof_pcm_stream_free(struct snd_sof_dev *sdev, struct snd_pcm_substream *substream,
653-
struct snd_sof_pcm *spcm, int dir, bool free_widget_list);
652+
int sof_pcm_free_all_streams(struct snd_sof_dev *sdev);
654653
int get_token_u32(void *elem, void *object, u32 offset);
655654
int get_token_u16(void *elem, void *object, u32 offset);
656655
int get_token_comp_format(void *elem, void *object, u32 offset);

0 commit comments

Comments
 (0)