Skip to content

Commit 880924c

Browse files
plbossartbroonie
authored andcommitted
ASoC: SOF: Intel: add helper for link DMA cleanups
We do the same operations from different places, add a helper to enforce consistency and make the programming sequences clearer. Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Reviewed-by: Rander Wang <rander.wang@intel.com> Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Reviewed-by: Péter Ujfalusi <peter.ujfalusi@linux.intel.com> Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com> Link: https://lore.kernel.org/r/20220421203201.1550328-14-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 722cbbf commit 880924c

1 file changed

Lines changed: 45 additions & 67 deletions

File tree

sound/soc/sof/intel/hda-dai.c

Lines changed: 45 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
131165
static 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

302301
static 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

Comments
 (0)