Skip to content

Commit 734dfed

Browse files
committed
Fix for IPC timeouts
squash me with earlier commits Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
1 parent 9be436d commit 734dfed

File tree

2 files changed

+74
-36
lines changed

2 files changed

+74
-36
lines changed

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

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ static int __maybe_unused hda_dai_hw_free(struct snd_pcm_substream *substream,
232232
return ret;
233233

234234
free:
235-
if (sof_is_widget_pipeline_be_managed(w)) {
235+
if (swidget->spipe->complete && sof_is_widget_pipeline_be_managed(w)) {
236236
ret = snd_sof_free_be_pipeline(w, substream->stream);
237237
if (ret < 0)
238238
return ret;
@@ -294,6 +294,7 @@ static int __maybe_unused hda_dai_hw_params(struct snd_pcm_substream *substream,
294294
static int __maybe_unused hda_dai_trigger(struct snd_pcm_substream *substream, int cmd,
295295
struct snd_soc_dai *dai)
296296
{
297+
struct snd_soc_dapm_widget *w = snd_soc_dai_get_widget(dai, substream->stream);
297298
const struct hda_dai_widget_dma_ops *ops = hda_dai_get_ops(substream, dai);
298299
struct hdac_ext_stream *hext_stream;
299300
struct snd_sof_dev *sdev;
@@ -309,6 +310,14 @@ static int __maybe_unused hda_dai_trigger(struct snd_pcm_substream *substream, i
309310

310311
sdev = dai_to_sdev(substream, dai);
311312

313+
/* For playback, set up the widgets first */
314+
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK &&
315+
cmd == SNDRV_PCM_TRIGGER_START) {
316+
ret = snd_sof_set_up_be_pipeline(w, substream->stream);
317+
if (ret < 0)
318+
return ret;
319+
}
320+
312321
hext_stream = ops->get_hext_stream(sdev, dai, substream);
313322
if (!hext_stream)
314323
return -EINVAL;
@@ -393,8 +402,9 @@ static int hda_dai_prepare(struct snd_pcm_substream *substream, struct snd_soc_d
393402
if (ret < 0)
394403
return ret;
395404

396-
if (sof_is_widget_pipeline_be_managed(w))
397-
return snd_sof_set_up_be_pipeline(w, stream);
405+
/* set up the widgets in the case of capture */
406+
if (stream == SNDRV_PCM_STREAM_CAPTURE && sof_is_widget_pipeline_be_managed(w))
407+
return snd_sof_set_up_be_pipeline(w, stream);
398408

399409
return 0;
400410
}
@@ -535,9 +545,9 @@ static int non_hda_dai_prepare(struct snd_pcm_substream *substream,
535545
if (ret < 0)
536546
return ret;
537547

538-
if (sof_is_widget_pipeline_be_managed(w))
539-
return snd_sof_set_up_be_pipeline(w, stream);
540-
548+
/* set up the widgets in the case of capture */
549+
if (stream == SNDRV_PCM_STREAM_CAPTURE && sof_is_widget_pipeline_be_managed(w))
550+
return snd_sof_set_up_be_pipeline(w, stream);
541551
return 0;
542552
}
543553

@@ -738,8 +748,9 @@ int sdw_hda_dai_prepare(struct snd_pcm_substream *substream, struct snd_pcm_hw_p
738748
if (ret < 0)
739749
return ret;
740750

741-
if (sof_is_widget_pipeline_be_managed(w))
742-
return snd_sof_set_up_be_pipeline(w, stream);
751+
/* set up the widgets in the case of capture */
752+
if (stream == SNDRV_PCM_STREAM_CAPTURE && sof_is_widget_pipeline_be_managed(w))
753+
return snd_sof_set_up_be_pipeline(w, stream);
743754

744755
return 0;
745756
}

sound/soc/sof/sof-audio.c

Lines changed: 55 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -331,9 +331,9 @@ static int sof_setup_pipeline_connections(struct snd_sof_dev *sdev,
331331

332332
if (p->sink->dobj.private) {
333333
/*
334-
* skip routes between widgets belonging to the BE pipeline
334+
* skip routes with widgets belonging to the BE pipeline
335335
*/
336-
if (sof_is_widget_pipeline_be_managed(widget) &&
336+
if (sof_is_widget_pipeline_be_managed(widget) ||
337337
sof_is_widget_pipeline_be_managed(p->sink))
338338
continue;
339339
ret = sof_route_setup(sdev, widget, p->sink);
@@ -1026,6 +1026,32 @@ int sof_dai_get_tdm_slots(struct snd_soc_pcm_runtime *rtd)
10261026
}
10271027
EXPORT_SYMBOL(sof_dai_get_tdm_slots);
10281028

1029+
static struct snd_soc_dapm_widget *snd_sof_get_pipeline_source(struct snd_sof_pipeline *spipe,
1030+
struct snd_soc_dapm_widget *w)
1031+
{
1032+
struct snd_soc_dapm_path *p;
1033+
1034+
snd_soc_dapm_widget_for_each_source_path(w, p) {
1035+
if (!p->walking) {
1036+
struct snd_soc_dapm_widget *wsource = p->source;
1037+
struct snd_sof_widget *source_swidget = wsource->dobj.private;
1038+
struct snd_soc_dapm_widget *source_widget;
1039+
1040+
p->walking = true;
1041+
if (source_swidget->spipe != spipe) {
1042+
p->walking = false;
1043+
break;
1044+
}
1045+
1046+
source_widget = snd_sof_get_pipeline_source(spipe, wsource);
1047+
p->walking = false;
1048+
return source_widget;
1049+
}
1050+
}
1051+
1052+
return w;
1053+
}
1054+
10291055
static int snd_sof_set_up_widgets_in_pipeline(struct snd_soc_dapm_widget *w,
10301056
struct snd_sof_pipeline *spipe, int dir)
10311057
{
@@ -1042,27 +1068,17 @@ static int snd_sof_set_up_widgets_in_pipeline(struct snd_soc_dapm_widget *w,
10421068
if (ret < 0)
10431069
return ret;
10441070

1045-
if (dir == SNDRV_PCM_STREAM_PLAYBACK) {
1046-
snd_soc_dapm_widget_for_each_source_path(w, p) {
1047-
if (!p->walking) {
1048-
p->walking = true;
1071+
if (dir == SNDRV_PCM_STREAM_PLAYBACK && WIDGET_IS_DAI(swidget->id))
1072+
return 0;
10491073

1050-
ret = snd_sof_set_up_widgets_in_pipeline(p->source, spipe, dir);
1051-
p->walking = false;
1052-
if (ret < 0)
1053-
goto err;
1054-
}
1055-
}
1056-
} else {
1057-
snd_soc_dapm_widget_for_each_sink_path(w, p) {
1058-
if (!p->walking) {
1059-
p->walking = true;
1074+
snd_soc_dapm_widget_for_each_sink_path(w, p) {
1075+
if (!p->walking) {
1076+
p->walking = true;
10601077

1061-
ret = snd_sof_set_up_widgets_in_pipeline(p->sink, spipe, dir);
1062-
p->walking = false;
1063-
if (ret < 0)
1064-
goto err;
1065-
}
1078+
ret = snd_sof_set_up_widgets_in_pipeline(p->sink, spipe, dir);
1079+
p->walking = false;
1080+
if (ret < 0)
1081+
goto err;
10661082
}
10671083
}
10681084

@@ -1185,15 +1201,19 @@ static int snd_sof_set_up_routes_in_pipeline(struct snd_soc_dapm_widget *w,
11851201
struct snd_soc_dapm_widget *wsource = p->source;
11861202
struct snd_sof_widget *source_swidget = wsource->dobj.private;
11871203

1188-
if (source_swidget->spipe != spipe)
1189-
continue;
1190-
11911204
p->walking = true;
11921205

1193-
ret = sof_route_setup(sdev, wsource, w);
1194-
if (ret < 0) {
1206+
if (source_swidget->use_count > 0) {
1207+
ret = sof_route_setup(sdev, wsource, w);
1208+
if (ret < 0) {
1209+
p->walking = false;
1210+
return ret;
1211+
}
1212+
}
1213+
1214+
if (source_swidget->spipe != spipe) {
11951215
p->walking = false;
1196-
return ret;
1216+
continue;
11971217
}
11981218

11991219
ret = snd_sof_set_up_routes_in_pipeline(wsource, spipe, dir);
@@ -1234,10 +1254,17 @@ int snd_sof_set_up_be_pipeline(struct snd_soc_dapm_widget *w, int dir)
12341254
{
12351255
struct snd_sof_widget *swidget = w->dobj.private;
12361256
struct snd_sof_dev *sdev = widget_to_sdev(w);
1257+
struct snd_soc_dapm_widget *wsource;
12371258
int ret;
12381259

1260+
/* get the source widget for the BE pipeline */
1261+
if (dir == SNDRV_PCM_STREAM_PLAYBACK)
1262+
wsource = snd_sof_get_pipeline_source(swidget->spipe, w);
1263+
else
1264+
wsource = w;
1265+
12391266
/* set up the widgets in the BE pipeline */
1240-
ret = snd_sof_set_up_widgets_in_pipeline(w, swidget->spipe, dir);
1267+
ret = snd_sof_set_up_widgets_in_pipeline(wsource, swidget->spipe, dir);
12411268
if (ret < 0) {
12421269
dev_err(sdev->dev, "failed to set up widgets in the BE pipeline with DAI: %s\n",
12431270
w->name);

0 commit comments

Comments
 (0)