Repository navigation
Conversation
Some streams, such as those used for wake-on-voice, must remain active during system suspend. Add an ignore_suspend flag to sdw_stream_runtime and export sdw_bus_ignore_suspend() so bus drivers can check whether any stream on the bus requires it to remain active. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Honor the SoundWire bus ignore-suspend state in the Intel drivers. Preserve the master across system suspend when a stream requires the bus to remain active. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Do not disable a SoundWire stream on suspend when it is marked to remain active. If the stream is already enabled on resume, no further action is needed. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
There was a problem hiding this comment.
🟡 Changes recommended
Critical retention-handling defects allow duplicate IPC3 STARTs, fail to retain legacy SoundWire streams, and leave wake-on-voice disabled after aborted S3 preparation.
3 open issues
What changed in this PR
This PR extends SOF’s wake-on-voice retention across SoundWire streams, Intel controllers, and DAPM paths so required audio resources remain active during system suspend.
Changes:
- Propagates per-stream retention decisions from SOF to SoundWire and connected DAPM widgets.
- Updates Intel suspend/resume handling to preserve retained buses and clean up revoked retention.
- Revises PCM recovery and IPC4 pipeline reference accounting.
| File | Description |
|---|---|
| sound/soc/sof/sof-priv.h | Tracks suspend progress and retention revocation. |
| sound/soc/sof/sof-audio.h | Adds PCM retention state and lifecycle declarations. |
| sound/soc/sof/pm.c | Integrates retention preparation and completion. |
| sound/soc/sof/pcm.c | Selects retained streams and updates PCM lifecycle handling. |
| sound/soc/sof/ipc4-topology.c | Resets pipeline counters when freeing pipelines. |
| sound/soc/sof/ipc4-pcm.c | Tracks per-stream pipeline references and cleanup. |
| sound/soc/sof/intel/hda.c | Adds SoundWire retention-query callbacks. |
| sound/soc/sof/intel/hda-dsp.c | Clears retention state during system D3 transitions. |
| sound/soc/sof/intel/hda-dai.c | Propagates retention and updates backend recovery. |
| sound/soc/sof/intel/hda-dai-ops.c | Skips firmware IPC during cleanup after firmware failure. |
| sound/soc/soc-dapm.c | Marks and preserves connected retained audio paths. |
| sound/soc/sdw_utils/soc_sdw_utils.c | Handles retained SoundWire streams across PCM operations. |
| include/sound/soc-dapm.h | Adds widget retention flags. |
| include/sound/soc-component.h | Adds a component retention-query callback. |
| include/linux/soundwire/sdw.h | Exposes stream retention state and a bus query. |
| include/linux/soundwire/sdw_intel.h | Adds the Intel retention-query interface. |
| drivers/soundwire/stream.c | Detects enabled retained streams on a bus. |
| drivers/soundwire/intel.h | Records whether a bus remained active. |
| drivers/soundwire/intel.c | Exempts retained streams from DAI suspend marking. |
| drivers/soundwire/intel_auxdevice.c | Preserves retained buses and revokes stale retention. |
| drivers/soundwire/intel_ace2x.c | Exempts retained ACE2x streams from suspend marking. |
Review effort: Balanced
| struct sdw_intel_ops sdw_callback = { | ||
| .params_stream = sdw_params_stream, | ||
| .free_stream = sdw_params_free, | ||
| .ignore_suspend = sdw_ignore_suspend, |
| if (sdev->system_suspend_retention_revoked && !sdev->system_suspend_started) | ||
| dev_err(sdev->dev, "system suspend aborted after revoking WoV retention; close and reopen PCM\n"); |
b724fb3 to
bac09f9
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Critical retention-state and microphone-routing defects can leave streams inconsistent across suspend or recovery, power down retained capture paths, and prevent supported sound cards from registering.
10 open issues
Revoke SoundWire retention when SOF cannot retain the DSP · New Recover SoundWire retention if suspend preparation fails · New Accept instance-suffixed RT1320/RT1321 component prefixes · New Initialize microphone routes for every codec instance · New Resolve WoV retention from the card's actual microphone endpoint · New Restore DAPM ignore-suspend flags when PCM retention is revoked · New Restore frontend and SoundWire retention if suspend preparation fails Preserve retention on no-op prepare or stop before clearing it Enable WoV retention on legacy SoundWire trigger paths Enable SoundWire retention for pre-ACE2 controllers · New
Review effort: Balanced
| * Revoke retention from an earlier S0ix before any controller or codec | ||
| * suspends. An already-suspended PCM will not issue another trigger. | ||
| */ | ||
| if (pm_suspend_target_state != PM_SUSPEND_TO_IDLE) { |
| if (stream->state == SDW_STREAM_ENABLED) { | ||
| ret = sdw_disable_stream(stream); |
| !strcmp(component->name_prefix, "rt713") || | ||
| !strcmp(component->name_prefix, "rt713-dmic") || | ||
| !strcmp(component->name_prefix, "rt766") || | ||
| !strcmp(component->name_prefix, "rt1320")) { |
|
|
||
| list_for_each_entry(spcm, &sdev->pcm_list, list) | ||
| for_each_pcm_streams(dir) | ||
| spcm->stream[dir].suspend_ignored = false; |
bac09f9 to
c44ad6b
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Critical suspend-retention bugs leave DAPM and SoundWire state inconsistent across sleep and recovery, while rejecting instance-suffixed codec prefixes can prevent sound-card registration.
12 open issues
Accept numbered RT1320 codec prefixes during route initialization · New Restore temporary DAPM ignore-suspend flags when retention ends · New Restore DAPM ignore-suspend flags when PCM retention is revoked Resolve WoV retention from the card's actual microphone endpoint Initialize microphone routes for every codec instance Accept instance-suffixed RT1320/RT1321 component prefixes Recover SoundWire retention if suspend preparation fails Revoke SoundWire retention when SOF cannot retain the DSP Restore frontend and SoundWire retention if suspend preparation fails Preserve retention on no-op prepare or stop before clearing it Enable WoV retention on legacy SoundWire trigger paths Enable SoundWire retention for pre-ACE2 controllers
Review effort: Balanced
c44ad6b to
e57b823
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Critical suspend-retention defects leave legacy SoundWire capture unprotected and mishandle cleanup, recovery, and suspend aborts, risking broken capture and audio paths remaining powered during D3 transitions.
12 open issues
Propagate retention to the legacy SoundWire trigger path · New Clear temporary DAPM ignore_suspend when retention ends · New Avoid tearing down retained pipelines during PCM prepare · New Restore temporary DAPM ignore-suspend flags when retention ends Accept numbered RT1320 codec prefixes during route initialization Restore DAPM ignore-suspend flags when PCM retention is revoked Initialize microphone routes for every codec instance Accept instance-suffixed RT1320/RT1321 component prefixes Recover SoundWire retention if suspend preparation fails Revoke SoundWire retention when SOF cannot retain the DSP Restore frontend and SoundWire retention if suspend preparation fails Enable WoV retention on legacy SoundWire trigger paths
3 resolved since last review
Review effort: Balanced
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>
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>
A WoV PCM can remain SUSPENDED after waking from S0ix until userspace recovers it. If the next sleep transition enters S3 or S4 first, ALSA does not send another SUSPEND trigger, leaving the SoundWire stream ENABLED with ignore_suspend set even though the hardware loses its configuration during the deeper transition. The controller suspend-target check alone does not invalidate the stream state. An ENABLED stream makes prepare and RESUME skip port configuration, so the stream must be disabled before powering down. Disable retained SoundWire streams and clear ignore_suspend in Intel link PM prepare when the target is not suspend-to-idle, before the controller and codecs suspend. Use each stream state, retention flag and sleep target to decide whether its Intel DAI needs reinitialization. Keep the component suspend callbacks limited to marking DAI state and preserve the S0ix retention path. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
A WoV PCM can remain SUSPENDED after waking from S0ix until userspace recovers it. If the next sleep transition enters S3 or S4 first, ALSA does not send another SUSPEND trigger. The FE and HDA BE can therefore keep suspend_ignored although the deeper transition resets the DSP and link DMA hardware. A retained FE pipeline still owes the STOP it skipped at SUSPEND. Its started_count stays non-zero, which makes the IPC4 RESET and later RUNNING transitions skip the pipeline. Clearing the flag before teardown would lose this information. Pay the skipped STOP in sof_pcm_stream_free() and clear the flag there. Include retained streams in sof_pcm_free_all_streams(), which only runs when the DSP is not staying in D0. If the STOP fails, still free the stream so the flag cannot outlive the firmware state. A retained stream that is dropped while SUSPENDED never receives a STOP trigger. PREPARE cannot tell this from a normal recovery because ALSA moves a SUSPENDED PCM to SETUP before calling it, and the pipeline is still running in both cases. Keep the stream in PREPARE and let START skip it. Clear the flag on STOP, PAUSE and close. Clear HDA stream retention flags on the system D3 path so subsequent BE triggers cannot mistake reset hardware for a still-running stream. Preserve the S0ix WoV retention path. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
A BE may be shared by multiple FEs. Some FEs need to remain active during system suspend while others do not. Keep a BE DAI endpoint active if it is connected to an active FE DAI with ignore_suspend set. This lets drivers mark only the FE DAI instead of retaining the shared BE for every connected FE. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
Keep the DAPM capture path of a WoV stream powered during S0ix. Find the microphone endpoint from the FE capture path instead of assuming a card widget named DMIC, since cards may name it differently. Mark the FE DAI widget and the endpoint when the WoV stream is suspended for S0ix, so the lookup runs while the path is connected. If no endpoint is found, the stream is suspended normally. Signed-off-by: Bard Liao <yung-chuan.liao@linux.intel.com>
e57b823 to
b8243d5
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Uncoordinated WoV retention decisions and incomplete cleanup before D3 can leave SoundWire and DMA state inconsistent with the reset DSP, preventing capture from restarting.
9 open issues
Invalidate retained link-DMA resources before D3 · New Share a successful retention decision between FE and BE · New Restore DAPM ignore-suspend flags when PCM retention is revoked Accept instance-suffixed RT1320/RT1321 component prefixes Recover SoundWire retention if suspend preparation fails Revoke SoundWire retention when SOF cannot retain the DSP Restore frontend and SoundWire retention if suspend preparation fails Enable WoV retention on legacy SoundWire trigger paths Restore temporary widget flags when WoV retention ends · New
6 resolved since last review
Avoid tearing down retained pipelines during PCM prepare Clear temporary DAPM ignore_suspend when retention ends Propagate retention to the legacy SoundWire trigger path Restore temporary DAPM ignore-suspend flags when retention ends Accept numbered RT1320 codec prefixes during route initialization Initialize microphone routes for every codec instance
Review effort: Balanced
| hda_stream = hstream_to_sof_hda_stream(stream_to_hdac_ext_stream(s)); | ||
| hda_stream->suspend_ignored = false; |
| if (!sof_pcm_set_dai_ignore_suspend(rtd, substream->stream)) { | ||
| spcm->stream[substream->stream].suspend_ignored = true; | ||
| return 0; | ||
| } |
| if (!ret) | ||
| widget->ignore_suspend = 1; |


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.
An alternative to #5968