Skip to content

ASoC/soundwire: SOF: keep WoV SoundWire paths active during suspend - #5968

Open
bardliao wants to merge 10 commits into
thesofproject:topic/sof-devfrom
bardliao:sdw-ignore-suspend
Open

bardliao wants to merge 10 commits into
thesofproject:topic/sof-devfrom
bardliao:sdw-ignore-suspend

Conversation

@bardliao

@bardliao bardliao commented Oct 7, 2026

Copy link
Copy Markdown
Collaborator

Wake-on-voice requires the DSP audio path to remain available while the
system is suspended. Although SOF can keep a D0i3-compatible PCM running,
SoundWire stream and Intel controller suspend handling may still disable
the stream or its bus, while DAPM may power down widgets on the path.
This series propagates the ignore-suspend requirement from SOF to the
SoundWire stream and connected DAPM widgets and keep the required
components alive during system suspend.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Suspend-target handling, DAPM endpoint coverage, and ACE2.x teardown currently prevent safe path retention.

Review effort: Balanced
Findings: 4 Medium severity

Open (4)
What changed in this PR

Adds suspend retention for D0i3-compatible SOF SoundWire audio paths.

Changes:

  • Propagates suspend retention through DAPM and SoundWire streams.
  • Keeps Intel SoundWire buses active during suspend.
  • Adjusts trigger handling for retained streams.
File Description
sound/​soc/​sof/​pcm.c Marks connected DAPM widgets for retention.
sound/​soc/​sof/​intel/​hda.c Propagates D0i3 compatibility to SoundWire.
sound/​soc/​sof/​intel/​hda-dai-ops.c Handles resume triggers.
sound/​soc/​sdw_utils/​soc_sdw_utils.c Preserves retained streams across suspend.
include/​linux/​soundwire/​sdw.h Adds retention state and bus API.
drivers/​soundwire/​stream.c Implements bus retention detection.
drivers/​soundwire/​intel.c Avoids suspending retained controller state.
drivers/​soundwire/​intel_auxdevice.c Skips bus power transitions when retained.
drivers/​soundwire/​intel_ace2x.c Applies retention to ACE2.x controllers.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread drivers/soundwire/stream.c Outdated
Comment thread sound/soc/sof/intel/hda-dai-ops.c Outdated
Comment thread sound/soc/sof/intel/hda.c Outdated
Comment thread sound/soc/sof/pcm.c Outdated

@ujfalusi ujfalusi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bardliao, how about the codec drivers themself? I think that the one you use only marks the regcache cache only, but it would not be far fetched if a codec driver would actually do the right thing and powers down things in their PM suspend callback?

Comment thread sound/soc/sof/intel/hda-dai-ops.c Outdated
swidget->spipe->started_count = 0;
break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
case SNDRV_PCM_TRIGGER_RESUME:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with this patch: 8d544a0

you are not going to receive the RESUME trigger.

Comment thread sound/soc/sof/intel/hda.c Outdated
break;
}
if (!list_entry_is_head(spcm, &sdev->pcm_list, list) &&
spcm->stream[dir].d0i3_compatible)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will mark DeepBuffer playback and capture also, which is not correct.

The definition to use is:
9e47005

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ujfalusi Do you mean just test spcm->stream[substream->stream].suspend_ignored?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

	 * WoV streams can be indetified by:
	 * They are capture streams and
	 * They have the d0i3_compatible flag set and
	 * They don't use Deep Buffer

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see this in #5951 :
8d544a0

Comment thread sound/soc/sof/intel/hda.c Outdated
Comment thread sound/soc/sof/pcm.c Outdated
return ret;
}

if (spcm->stream[dir].d0i3_compatible) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will break deepbuffer playback and capture during suspend, the definition to use is:
9e47005

@bardliao

bardliao commented Oct 7, 2026

Copy link
Copy Markdown
Collaborator Author

@bardliao, how about the codec drivers themself? I think that the one you use only marks the regcache cache only, but it would not be far fetched if a codec driver would actually do the right thing and powers down things in their PM suspend callback?

Most SDW codec drivers don't do power down in their suspend callback. IOW the current solution applies to most codecs. We can handle the codecs that need to skip the device suspend in the future if needed.

@ujfalusi

ujfalusi commented Oct 7, 2026

Copy link
Copy Markdown
Collaborator

@bardliao, how about the codec drivers themself? I think that the one you use only marks the regcache cache only, but it would not be far fetched if a codec driver would actually do the right thing and powers down things in their PM suspend callback?

Most SDW codec drivers don't do power down in their suspend callback. IOW the current solution applies to most codecs. We can handle the codecs that need to skip the device suspend in the future if needed.

Operation whack-a-mole?

Copilot AI balanced review requested due to automatic review settings October 7, 2026 11:12
@bardliao
bardliao force-pushed the sdw-ignore-suspend branch from 0377bcf to d247a69 Compare October 7, 2026 11:12

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Suspend policy is applied too broadly and required DAPM endpoints are omitted, potentially breaking wake-on-voice and deeper suspend states.

Review effort: Balanced
Findings: 6 Medium severity

Open (6)

Comment thread sound/soc/sof/intel/hda.c Outdated
Comment thread sound/soc/sof/pcm.c Outdated
@bardliao
bardliao force-pushed the sdw-ignore-suspend branch from d247a69 to 558587f Compare October 7, 2026 12:04
Copilot AI balanced review requested due to automatic review settings October 7, 2026 12:04

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread sound/soc/sof/pcm.c Outdated
Copilot AI balanced review requested due to automatic review settings October 7, 2026 14:38
@bardliao
bardliao force-pushed the sdw-ignore-suspend branch from 558587f to 9e0e7c2 Compare October 7, 2026 14:38

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread sound/soc/sof/pcm.c Outdated
@bardliao
bardliao force-pushed the sdw-ignore-suspend branch from 9e0e7c2 to 191e953 Compare October 8, 2026 07:54
Copilot AI balanced review requested due to automatic review settings October 8, 2026 07:54

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread sound/soc/sof/intel/hda-dai.c Outdated
Comment thread sound/soc/sof/pcm.c Outdated
Copilot AI balanced review requested due to automatic review settings October 20, 2026 13:48

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Firmware-crash recovery and suspend-abort handling can leave retention state or hardware in an incorrect state.

5 open issues
1 resolved since last review

Review effort: Balanced

Comment thread sound/soc/sof/pcm.c Outdated
Comment thread sound/soc/sof/pcm.c Outdated
Comment thread sound/soc/sof/pm.c Outdated
Copilot AI balanced review requested due to automatic review settings October 20, 2026 15:22

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Cross-layer suspend ordering and shared-stream recovery need human validation, and prepare-error cleanup remains unresolved.

4 open issues
2 resolved since last review

Review effort: Balanced

Comment thread sound/soc/sof/pm.c Outdated
Copilot AI balanced review requested due to automatic review settings October 21, 2026 00:50

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Transitioning from S0ix to S3 without PCM resume leaves stale frontend pipeline references that prevent capture from restarting.

1 open issue
4 resolved since last review

Review effort: Balanced

Comment thread sound/soc/sof/pcm.c Outdated
Copilot AI balanced review requested due to automatic review settings October 21, 2026 01:11

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Cross-layer suspend and shared-stream transitions need fixes, human review, and hardware validation.

4 open issues
1 resolved since last review

Review effort: Balanced

Comment thread sound/soc/soc-pcm.c Outdated
Comment thread sound/soc/sof/pcm.c Outdated
Comment thread sound/soc/sof/pm.c Outdated
Comment thread sound/soc/sof/pcm.c
Copilot AI balanced review requested due to automatic review settings October 21, 2026 04:23

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread sound/soc/sof/pcm.c Outdated
bardliao and others added 7 commits October 21, 2026 14:24
SOF needs to stop a frontend pipeline that was retained across S0ix when
the system later transitions to S3. That frontend is already in the
suspended state, so it will not receive a SUSPEND trigger, and SOF must
issue the component STOP trigger directly.

Export snd_soc_pcm_component_trigger() so it can be used from the SOF
module.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Keep connected DAPM endpoint widgets active while SOF retains a
wake-on-voice PCM across suspend.
Track ownership per PCM stream so shared widgets remain marked until
their final WoV user releases them. Refresh DAPM endpoint path caches
after changing ignore_suspend.
A DROP on a suspended PCM does not issue STOP, so suspend_ignored can
remain set if userspace prepares the PCM instead of resuming it. Clear
suspend_ignored and release DAPM retention from hw_free and close,
which may also run without START or RESUME. Clear them in prepare as
a final fallback when a suspended PCM is prepared directly while
suspend_ignored is still set.

Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Every caller of sof_pcm_set_widget_ignore_suspend() updates the stream's
suspend_ignored flag right after it: the flag is set when the DAPM
widgets were successfully retained and cleared otherwise.

Move these updates into sof_pcm_set_widget_ignore_suspend() so the
suspend_ignored flag and the DAPM widget retention cannot get out of
sync, and drop the open-coded assignments from sof_pcm_trigger() and
the other callers.

No functional change intended.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Keep a SoundWire stream active during system suspend when it is used by
a WoV stream. WoV streams can be identified by: They are capture streams
and. They have the d0i3_compatible flag set and They don't use Deep
Buffer.

The decision is made in the BE SUSPEND trigger. The BE DAI trigger runs
before the SoundWire link trigger, so the ignore_suspend flag of the
SoundWire stream is updated before the link trigger decides whether to
disable the stream. When a BE is shared by WoV and regular FEs, the BE
only receives SUSPEND once the last FE is suspended, and all connected
FEs are checked at that point regardless of their open or suspend order.

A WoV PCM retained in a previous S0ix suspend stays in the SUSPENDED
state and will not receive another SUSPEND trigger. If the system then
enters a deeper suspend state, stop its FE and BE pipelines and release
its DAPM retention at PM prepare time.

Assisted-by: LLM

Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Multiple FE streams can share a SoundWire BE, so prepare may arrive
after another FE has enabled the shared stream. Skip
sdw_prepare_stream() when the stream is already enabled.

When hw_free is called for an enabled stream, disable it before
depreparing. Propagate disable errors rather than attempting to
deprepare an enabled stream.

Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Two FEs sharing a BE can recover from system suspend differently: one
prepares and starts again, while the other resumes. Their recovery
callbacks can run concurrently.

BE prepare checks the DPCM state and then calls the prepare callbacks
without holding the BE stream lock used by trigger. A concurrent RESUME
can therefore change the BE from SUSPEND to START and increment be_start
while the other FE is still preparing. When prepare returns, it overwrites
START with PREPARE. The subsequent START increments be_start to two but
skips the hardware trigger and state update because it is not the first
user, leaving the active BE in PREPARE.

Both later STOP requests reject PREPARE, so neither decrements be_start nor
stops the BE. This was observed with regular and retained capture FEs
sharing a SoundWire BE: the firmware pipeline remained running and could
not be reset before deletion, and the SoundWire stream remained enabled
when teardown attempted to deprepare it.

Serialize the state checks, prepare callbacks and PREPARE assignment with
BE triggers for non-atomic PCMs, using their sleepable stream mutex. Do not
hold an atomic PCM spinlock over prepare callbacks, which may sleep.

Also handle the opposite recovery order. If another FE has already
prepared or started the BE, RESUME must still account for its FE in
be_start. Accept PREPARE and START as well as SUSPEND, and trigger only the
first user. Use START when the BE has already been prepared, retaining
RESUME for a BE that is still suspended. Roll back the increment if the
hardware trigger fails.

With POST trigger ordering, the BEs are resumed before the FE. If the FE
RESUME trigger then fails, the PCM core does not undo it because the
stream has not entered the running state, leaving be_start counting this
FE. A later prepare and START of the FE would count it again, so the
shared BE could never be stopped. Suspend the BEs again in that case.
Failed START and PAUSE_RELEASE triggers are already undone by the PCM
core, which issues STOP or PAUSE_PUSH through the regular DPCM path.

This keeps the BE state and active-user count consistent so that only the
last stopping FE shuts down the shared BE.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
A SoundWire capture BE shared by regular and WoV FEs can remain running
across S0ix. Its HDA suspend trigger sets suspend_ignored and skips the
pipeline and link DMA teardown. Recovery must consume that flag without
starting the retained hardware again.

The first BE trigger after system resume is not necessarily RESUME. A
regular capture FE can recover through prepare followed by START. Also,
when another FE has already prepared the shared BE, DPCM translates the
first RESUME into START rather than resuming an unprepared stream.

Only handling RESUME in the retained-stream shortcut lets START fall
through to the normal HDA trigger callbacks. This unnecessarily pauses
and restarts the retained IPC4 pipeline, starts the link DMA again and
increments the BE pipeline's started_count even though its existing
running reference was preserved during suspend. It also leaves
suspend_ignored set after recovery.

Consume suspend_ignored on either START or RESUME and return without
retriggering the retained hardware. DPCM still accounts for the recovering
FE in be_start, while the HDA pipeline keeps its existing running reference
until the last BE user stops. Ordinary START triggers are unchanged when
suspend_ignored is false.

With IPC4 capture links the FE is triggered before the BE. If a regular
FE has prepared the shared BE before a retained WoV FE resumes, the WoV
FE trigger consumes its suspend_ignored flag before DPCM sends START to
the BE, and its DPCM state is only updated after the trigger completes.
Treat a WoV FE which is being triggered while its PCM is still SUSPENDED
as resuming so the retained BE is not restarted.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Copilot AI balanced review requested due to automatic review settings October 22, 2026 11:25

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Legacy SoundWire retention propagation is missing, and partial backend resume failures can leak running-stream references.

5 open issues
1 resolved since last review

Review effort: Balanced

Comment thread sound/soc/soc-pcm.c
Comment on lines +2273 to +2275
if (be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND &&
be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE &&
be->dpcm[stream].state != SND_SOC_DPCM_STATE_START)
Comment on lines +750 to +751
if (cmd == SNDRV_PCM_TRIGGER_SUSPEND || cmd == SNDRV_PCM_TRIGGER_STOP)
hda_dai_set_sdw_ignore_suspend(cpu_dai, substream->stream, retain);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Assignees

Couldn't load assignees.