Skip to content

Commit a3650a4

Browse files
ujfalusibardliao
authored andcommitted
soundwire: intel: Move suspend tracking from trigger to pm suspend
Mark all open DAI runtimes as suspended in the component .suspend callback instead of relying on SNDRV_PCM_TRIGGER_SUSPEND, which is not delivered during PAUSE or xrun states. If during system suspend a dai is open it means that it is in either in SUSPENDED, PAUSED or STOPPED (due to xrun) state and they will need to be re-initialized during resume (which is done in .prepare callback). Signed-off-by: Peter Ujfalusi <[email protected]>
1 parent 14ec6be commit a3650a4

2 files changed

Lines changed: 33 additions & 37 deletions

File tree

drivers/soundwire/intel.c

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -906,19 +906,6 @@ static int intel_trigger(struct snd_pcm_substream *substream, int cmd, struct sn
906906
}
907907

908908
switch (cmd) {
909-
case SNDRV_PCM_TRIGGER_SUSPEND:
910-
911-
/*
912-
* The .prepare callback is used to deal with xruns and resume operations.
913-
* In the case of xruns, the DMAs and SHIM registers cannot be touched,
914-
* but for resume operations the DMAs and SHIM registers need to be initialized.
915-
* the .trigger callback is used to track the suspend case only.
916-
*/
917-
918-
dai_runtime->suspended = true;
919-
920-
break;
921-
922909
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
923910
dai_runtime->paused = true;
924911
break;
@@ -955,24 +942,20 @@ static int intel_component_dais_suspend(struct snd_soc_component *component)
955942
struct snd_soc_dai *dai;
956943

957944
/*
958-
* In the corner case where a SUSPEND happens during a PAUSE, the ALSA core
959-
* does not throw the TRIGGER_SUSPEND. This leaves the DAIs in an unbalanced state.
960-
* Since the component suspend is called last, we can trap this corner case
961-
* and force the DAIs to release their resources.
945+
* Mark all open streams as suspended.
946+
* Open streams at this point can be in SUSPENDED, PAUSED or STOPPED
947+
* state and during prepare the DMAs and SHIM registers need to be
948+
* initialized for them.
949+
* The STOPPED state is a special corner case which can happen if audio
950+
* experiences xrun at suspend time.
962951
*/
963952
for_each_component_dais(component, dai) {
964953
struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
965954
struct sdw_cdns_dai_runtime *dai_runtime;
966955

967956
dai_runtime = cdns->dai_runtime_array[dai->id];
968957

969-
if (!dai_runtime)
970-
continue;
971-
972-
if (dai_runtime->suspended)
973-
continue;
974-
975-
if (dai_runtime->paused)
958+
if (dai_runtime)
976959
dai_runtime->suspended = true;
977960
}
978961

drivers/soundwire/intel_ace2x.c

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -895,19 +895,6 @@ static int intel_trigger(struct snd_pcm_substream *substream, int cmd, struct sn
895895
}
896896

897897
switch (cmd) {
898-
case SNDRV_PCM_TRIGGER_SUSPEND:
899-
900-
/*
901-
* The .prepare callback is used to deal with xruns and resume operations.
902-
* In the case of xruns, the DMAs and SHIM registers cannot be touched,
903-
* but for resume operations the DMAs and SHIM registers need to be initialized.
904-
* the .trigger callback is used to track the suspend case only.
905-
*/
906-
907-
dai_runtime->suspended = true;
908-
909-
break;
910-
911898
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
912899
dai_runtime->paused = true;
913900
break;
@@ -931,8 +918,34 @@ static const struct snd_soc_dai_ops intel_pcm_dai_ops = {
931918
.get_stream = intel_get_sdw_stream,
932919
};
933920

921+
static int intel_component_dais_suspend(struct snd_soc_component *component)
922+
{
923+
struct snd_soc_dai *dai;
924+
925+
/*
926+
* Mark all open streams as suspended.
927+
* Open streams at this point can be in SUSPENDED, PAUSED or STOPPED
928+
* state and during prepare the DMAs and SHIM registers need to be
929+
* initialized for them.
930+
* The STOPPED state is a special corner case which can happen if audio
931+
* experiences xrun at suspend time.
932+
*/
933+
for_each_component_dais(component, dai) {
934+
struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
935+
struct sdw_cdns_dai_runtime *dai_runtime;
936+
937+
dai_runtime = cdns->dai_runtime_array[dai->id];
938+
939+
if (dai_runtime)
940+
dai_runtime->suspended = true;
941+
}
942+
943+
return 0;
944+
}
945+
934946
static const struct snd_soc_component_driver dai_component = {
935947
.name = "soundwire",
948+
.suspend = intel_component_dais_suspend,
936949
};
937950

938951
/*

0 commit comments

Comments
 (0)