diff --git a/sound/soc/sof/intel/hda-pcm.c b/sound/soc/sof/intel/hda-pcm.c index 83efc9bdf418af..b887624e7f8521 100644 --- a/sound/soc/sof/intel/hda-pcm.c +++ b/sound/soc/sof/intel/hda-pcm.c @@ -352,6 +352,15 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev, spcm->stream[substream->stream].d0i3_compatible) flags |= SOF_HDA_STREAM_DMI_L1_COMPATIBLE; + /* + * d0i3 on a capture stream indicates WoV support which needs to allow + * RESUME. The core will ignore the trigger but applications must not + * try to restart the WoV capture stream due to not supported RESUME + */ + if (direction == SNDRV_PCM_STREAM_CAPTURE && + spcm->stream[substream->stream].d0i3_compatible) + runtime->hw.info |= SNDRV_PCM_INFO_RESUME; + dsp_stream = hda_dsp_stream_get(sdev, direction, flags); if (!dsp_stream) { dev_err(sdev->dev, "error: no stream available\n"); diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index 42738f12fa3390..6a7acbb69fb4a4 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -428,6 +428,13 @@ static int sof_pcm_trigger(struct snd_soc_component *component, if (pcm_ops && pcm_ops->ipc_first_on_start) ipc_first = true; break; + case SNDRV_PCM_TRIGGER_RESUME: + if (spcm->stream[substream->stream].suspend_ignored) { + spcm->stream[substream->stream].suspend_ignored = false; + return 0; + } + spcm_err(spcm, substream->stream, "RESUME trigger is not supported\n"); + return -EINVAL; case SNDRV_PCM_TRIGGER_SUSPEND: /* * If DSP D0I3 is allowed during S0iX, set the suspend_ignored flag for diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c index 1d71d483588eb1..b5d239b12e59d2 100644 --- a/sound/soc/sof/pm.c +++ b/sound/soc/sof/pm.c @@ -248,7 +248,8 @@ static int sof_suspend(struct device *dev, bool runtime_suspend) * suspended, it is brought back to full power and then * suspended again */ - if (tplg_ops && tplg_ops->tear_down_all_pipelines && (old_state == SOF_DSP_PM_D0)) + if (tplg_ops && tplg_ops->tear_down_all_pipelines && (old_state == SOF_DSP_PM_D0) && + (target_state != SOF_DSP_PM_D0)) tplg_ops->tear_down_all_pipelines(sdev, false); if (sdev->fw_state != SOF_FW_BOOT_COMPLETE)