@@ -128,6 +128,40 @@ hda_link_stream_assign(struct hdac_bus *bus,
128128 return res ;
129129}
130130
131+ static int hda_link_dma_cleanup (struct snd_pcm_substream * substream ,
132+ struct hdac_stream * hstream ,
133+ struct snd_soc_dai * cpu_dai ,
134+ struct snd_soc_dai * codec_dai ,
135+ bool trigger_suspend_stop )
136+ {
137+ struct hdac_ext_stream * hext_stream = snd_soc_dai_get_dma_data (cpu_dai , substream );
138+ struct hdac_bus * bus = hstream -> bus ;
139+ struct sof_intel_hda_stream * hda_stream ;
140+ struct hdac_ext_link * link ;
141+ int stream_tag ;
142+
143+ link = snd_hdac_ext_bus_get_link (bus , codec_dai -> component -> name );
144+ if (!link )
145+ return - EINVAL ;
146+
147+ if (trigger_suspend_stop )
148+ snd_hdac_ext_link_stream_clear (hext_stream );
149+
150+ if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK ) {
151+ stream_tag = hdac_stream (hext_stream )-> stream_tag ;
152+ snd_hdac_ext_link_clear_stream_id (link , stream_tag );
153+ }
154+ snd_soc_dai_set_dma_data (cpu_dai , substream , NULL );
155+ snd_hdac_ext_stream_release (hext_stream , HDAC_EXT_STREAM_TYPE_LINK );
156+ hext_stream -> link_prepared = 0 ;
157+
158+ /* free the host DMA channel reserved by hostless streams */
159+ hda_stream = hstream_to_sof_hda_stream (hext_stream );
160+ hda_stream -> host_reserved = 0 ;
161+
162+ return 0 ;
163+ }
164+
131165static int hda_link_dma_params (struct hdac_ext_stream * hext_stream ,
132166 struct hda_pipe_params * params )
133167{
@@ -221,13 +255,7 @@ static int hda_link_dma_trigger(struct snd_pcm_substream *substream, int cmd)
221255 struct snd_soc_dai * cpu_dai = asoc_rtd_to_cpu (rtd , 0 );
222256 struct snd_soc_dai * codec_dai = asoc_rtd_to_codec (rtd , 0 );
223257 struct hdac_ext_stream * hext_stream = snd_soc_dai_get_dma_data (cpu_dai , substream );
224- struct hdac_ext_link * link ;
225- struct hdac_bus * bus = hstream -> bus ;
226- int stream_tag ;
227-
228- link = snd_hdac_ext_bus_get_link (bus , codec_dai -> component -> name );
229- if (!link )
230- return - EINVAL ;
258+ int ret ;
231259
232260 dev_dbg (cpu_dai -> dev , "%s: cmd=%d\n" , __func__ , cmd );
233261 if (!hext_stream )
@@ -240,15 +268,9 @@ static int hda_link_dma_trigger(struct snd_pcm_substream *substream, int cmd)
240268 break ;
241269 case SNDRV_PCM_TRIGGER_SUSPEND :
242270 case SNDRV_PCM_TRIGGER_STOP :
243- snd_hdac_ext_link_stream_clear (hext_stream );
244-
245- if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK ) {
246- stream_tag = hdac_stream (hext_stream )-> stream_tag ;
247- snd_hdac_ext_link_clear_stream_id (link , stream_tag );
248- }
249- snd_soc_dai_set_dma_data (cpu_dai , substream , NULL );
250- snd_hdac_ext_stream_release (hext_stream , HDAC_EXT_STREAM_TYPE_LINK );
251- hext_stream -> link_prepared = 0 ;
271+ ret = hda_link_dma_cleanup (substream , hstream , cpu_dai , codec_dai , true);
272+ if (ret < 0 )
273+ return ret ;
252274
253275 break ;
254276 case SNDRV_PCM_TRIGGER_PAUSE_PUSH :
@@ -267,36 +289,13 @@ static int hda_link_dma_hw_free(struct snd_pcm_substream *substream)
267289 struct snd_soc_pcm_runtime * rtd = asoc_substream_to_rtd (substream );
268290 struct snd_soc_dai * cpu_dai = asoc_rtd_to_cpu (rtd , 0 );
269291 struct snd_soc_dai * codec_dai = asoc_rtd_to_codec (rtd , 0 );
270- struct sof_intel_hda_stream * hda_stream ;
271- struct hdac_bus * bus = hstream -> bus ;
272292 struct hdac_ext_stream * hext_stream ;
273- struct hdac_ext_link * link ;
274- int stream_tag ;
275293
276294 hext_stream = snd_soc_dai_get_dma_data (cpu_dai , substream );
277- if (!hext_stream ) {
278- dev_dbg (cpu_dai -> dev , "%s: hext_stream is not assigned\n" , __func__ );
279- return - EINVAL ;
280- }
281-
282- link = snd_hdac_ext_bus_get_link (bus , codec_dai -> component -> name );
283- if (!link )
284- return - EINVAL ;
285-
286- if (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK ) {
287- stream_tag = hdac_stream (hext_stream )-> stream_tag ;
288- snd_hdac_ext_link_clear_stream_id (link , stream_tag );
289- }
290-
291- snd_soc_dai_set_dma_data (cpu_dai , substream , NULL );
292- snd_hdac_ext_stream_release (hext_stream , HDAC_EXT_STREAM_TYPE_LINK );
293- hext_stream -> link_prepared = 0 ;
294-
295- /* free the host DMA channel reserved by hostless streams */
296- hda_stream = hstream_to_sof_hda_stream (hext_stream );
297- hda_stream -> host_reserved = 0 ;
295+ if (!hext_stream )
296+ return 0 ;
298297
299- return 0 ;
298+ return hda_link_dma_cleanup ( substream , hstream , cpu_dai , codec_dai , false) ;
300299}
301300
302301static int hda_dai_widget_update (struct snd_soc_dapm_widget * w ,
@@ -457,15 +456,11 @@ static int hda_dai_suspend(struct hdac_bus *bus)
457456{
458457 struct snd_soc_pcm_runtime * rtd ;
459458 struct hdac_ext_stream * hext_stream ;
460- struct hdac_ext_link * link ;
461459 struct hdac_stream * s ;
462- const char * name ;
463- int stream_tag ;
464460 int ret ;
465461
466462 /* set internal flag for BE */
467463 list_for_each_entry (s , & bus -> stream_list , list ) {
468- struct sof_intel_hda_stream * hda_stream ;
469464
470465 hext_stream = stream_to_hdac_ext_stream (s );
471466
@@ -482,34 +477,17 @@ static int hda_dai_suspend(struct hdac_bus *bus)
482477 rtd = asoc_substream_to_rtd (hext_stream -> link_substream );
483478 cpu_dai = asoc_rtd_to_cpu (rtd , 0 );
484479 codec_dai = asoc_rtd_to_codec (rtd , 0 );
485- name = codec_dai -> component -> name ;
486- link = snd_hdac_ext_bus_get_link (bus , name );
487- if (!link )
488- return - EINVAL ;
489480
490- /*
491- * we don't need to call snd_hdac_ext_link_stream_clear(he_stream)
492- * since we can only reach this case in the pause_push state, and
493- * the TRIGGER_PAUSE_PUSH already stops the DMA
494- */
495- if (hdac_stream (hext_stream )-> direction == SNDRV_PCM_STREAM_PLAYBACK ) {
496- stream_tag = hdac_stream (hext_stream )-> stream_tag ;
497- snd_hdac_ext_link_clear_stream_id (link , stream_tag );
498- }
499- snd_soc_dai_set_dma_data (cpu_dai , hext_stream -> link_substream , NULL );
500- snd_hdac_ext_stream_release (hext_stream , HDAC_EXT_STREAM_TYPE_LINK );
501- hext_stream -> link_prepared = 0 ;
502-
503- /* free the host DMA channel reserved by hostless streams */
504- hda_stream = hstream_to_sof_hda_stream (hext_stream );
505- hda_stream -> host_reserved = 0 ;
481+ ret = hda_link_dma_cleanup (hext_stream -> link_substream , s ,
482+ cpu_dai , codec_dai , false);
483+ if (ret < 0 )
484+ return ret ;
506485
507486 /* for consistency with TRIGGER_SUSPEND we free DAI resources */
508487 ret = hda_dai_hw_free_ipc (hdac_stream (hext_stream )-> direction , cpu_dai );
509488 if (ret < 0 )
510489 return ret ;
511490 }
512-
513491 }
514492
515493 return 0 ;
0 commit comments