mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 01:32:21 +02:00
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 <peter.ujfalusi@linux.intel.com> Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com> Link: https://patch.msgid.link/20260508101755.1247039-1-yung-chuan.liao@linux.intel.com Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
parent
4e90368e86
commit
acf676b9de
|
|
@ -906,19 +906,6 @@ static int intel_trigger(struct snd_pcm_substream *substream, int cmd, struct sn
|
|||
}
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
|
||||
/*
|
||||
* The .prepare callback is used to deal with xruns and resume operations.
|
||||
* In the case of xruns, the DMAs and SHIM registers cannot be touched,
|
||||
* but for resume operations the DMAs and SHIM registers need to be initialized.
|
||||
* the .trigger callback is used to track the suspend case only.
|
||||
*/
|
||||
|
||||
dai_runtime->suspended = true;
|
||||
|
||||
break;
|
||||
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
dai_runtime->paused = true;
|
||||
break;
|
||||
|
|
@ -955,10 +942,12 @@ static int intel_component_dais_suspend(struct snd_soc_component *component)
|
|||
struct snd_soc_dai *dai;
|
||||
|
||||
/*
|
||||
* In the corner case where a SUSPEND happens during a PAUSE, the ALSA core
|
||||
* does not throw the TRIGGER_SUSPEND. This leaves the DAIs in an unbalanced state.
|
||||
* Since the component suspend is called last, we can trap this corner case
|
||||
* and force the DAIs to release their resources.
|
||||
* Mark all open streams as suspended.
|
||||
* Open streams at this point can be in SUSPENDED, PAUSED or STOPPED
|
||||
* state and during prepare the DMAs and SHIM registers need to be
|
||||
* initialized for them.
|
||||
* The STOPPED state is a special corner case which can happen if audio
|
||||
* experiences xrun at suspend time.
|
||||
*/
|
||||
for_each_component_dais(component, dai) {
|
||||
struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
|
||||
|
|
@ -966,13 +955,7 @@ static int intel_component_dais_suspend(struct snd_soc_component *component)
|
|||
|
||||
dai_runtime = cdns->dai_runtime_array[dai->id];
|
||||
|
||||
if (!dai_runtime)
|
||||
continue;
|
||||
|
||||
if (dai_runtime->suspended)
|
||||
continue;
|
||||
|
||||
if (dai_runtime->paused)
|
||||
if (dai_runtime)
|
||||
dai_runtime->suspended = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -894,19 +894,6 @@ static int intel_trigger(struct snd_pcm_substream *substream, int cmd, struct sn
|
|||
}
|
||||
|
||||
switch (cmd) {
|
||||
case SNDRV_PCM_TRIGGER_SUSPEND:
|
||||
|
||||
/*
|
||||
* The .prepare callback is used to deal with xruns and resume operations.
|
||||
* In the case of xruns, the DMAs and SHIM registers cannot be touched,
|
||||
* but for resume operations the DMAs and SHIM registers need to be initialized.
|
||||
* the .trigger callback is used to track the suspend case only.
|
||||
*/
|
||||
|
||||
dai_runtime->suspended = true;
|
||||
|
||||
break;
|
||||
|
||||
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
|
||||
dai_runtime->paused = true;
|
||||
break;
|
||||
|
|
@ -930,8 +917,34 @@ static const struct snd_soc_dai_ops intel_pcm_dai_ops = {
|
|||
.get_stream = intel_get_sdw_stream,
|
||||
};
|
||||
|
||||
static int intel_component_dais_suspend(struct snd_soc_component *component)
|
||||
{
|
||||
struct snd_soc_dai *dai;
|
||||
|
||||
/*
|
||||
* Mark all open streams as suspended.
|
||||
* Open streams at this point can be in SUSPENDED, PAUSED or STOPPED
|
||||
* state and during prepare the DMAs and SHIM registers need to be
|
||||
* initialized for them.
|
||||
* The STOPPED state is a special corner case which can happen if audio
|
||||
* experiences xrun at suspend time.
|
||||
*/
|
||||
for_each_component_dais(component, dai) {
|
||||
struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai);
|
||||
struct sdw_cdns_dai_runtime *dai_runtime;
|
||||
|
||||
dai_runtime = cdns->dai_runtime_array[dai->id];
|
||||
|
||||
if (dai_runtime)
|
||||
dai_runtime->suspended = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct snd_soc_component_driver dai_component = {
|
||||
.name = "soundwire",
|
||||
.suspend = intel_component_dais_suspend,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user