diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 818dff1de545fa..b6e158ce6650de 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -1506,6 +1506,14 @@ int snd_pcm_suspend_all(struct snd_pcm *pcm) /* FIXME: the open/close code should lock this as well */ if (substream->runtime == NULL) continue; + + /* + * Skip BE dai link PCM's that are internal and may + * not have their substream ops set. + */ + if (!substream->ops) + continue; + err = snd_pcm_suspend(substream); if (err < 0 && err != -EBUSY) return err; diff --git a/sound/soc/intel/boards/bxt_pcm512x.c b/sound/soc/intel/boards/bxt_pcm512x.c index e2605df8b6efab..47e21e26c0084b 100644 --- a/sound/soc/intel/boards/bxt_pcm512x.c +++ b/sound/soc/intel/boards/bxt_pcm512x.c @@ -305,6 +305,7 @@ static int bxt_pcm512x_probe(struct platform_device *pdev) static struct platform_driver bxt_pcm521x_driver = { .driver = { .name = "bxt-pcm512x", + .pm = &snd_soc_pm_ops, }, .probe = bxt_pcm512x_probe, }; diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index 3c4526f15bf195..cea7601d16b1ff 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -163,6 +163,9 @@ static int sof_pcm_hw_params(struct snd_pcm_substream *substream, /* save pcm hw_params */ memcpy(&spcm->params[substream->stream], params, sizeof(*params)); + /* unset restore_stream */ + spcm->restore_stream[substream->stream] = 0; + return ret; } @@ -252,22 +255,6 @@ static int sof_pcm_trigger(struct snd_pcm_substream *substream, int cmd) stream.comp_id = spcm->stream[substream->stream].comp_id; switch (cmd) { - case SNDRV_PCM_TRIGGER_STOP: - - /* - * Check if stream was marked for restore before suspend - */ - if (spcm->restore_stream[substream->stream]) { - - /* unset restore_stream */ - spcm->restore_stream[substream->stream] = 0; - - /* do not send ipc as the stream hasn't been set up */ - return 0; - } - - stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_STOP; - break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_PAUSE; break; @@ -313,6 +300,20 @@ static int sof_pcm_trigger(struct snd_pcm_substream *substream, int cmd) break; case SNDRV_PCM_TRIGGER_SUSPEND: + /* fallthrough */ + case SNDRV_PCM_TRIGGER_STOP: + + /* Check if stream was marked for restore before suspend */ + if (spcm->restore_stream[substream->stream]) { + + /* unset restore_stream */ + spcm->restore_stream[substream->stream] = 0; + + /* do not send ipc as the stream hasn't been set up */ + return 0; + } + + stream.hdr.cmd |= SOF_IPC_STREAM_TRIG_STOP; break; default: dev_err(sdev->dev, "error: unhandled trigger cmd %d\n", cmd); diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c index 93102993b508dc..fd9d07892201f7 100644 --- a/sound/soc/sof/pm.c +++ b/sound/soc/sof/pm.c @@ -194,35 +194,16 @@ static int sof_send_pm_ipc(struct snd_sof_dev *sdev, int cmd) sizeof(pm_ctx), &reply, sizeof(reply)); } -static void sof_suspend_streams(struct snd_sof_dev *sdev) +static void sof_set_restore_stream(struct snd_sof_dev *sdev) { struct snd_sof_pcm *spcm; - struct snd_pcm_substream *substream; - int dir, playback_dir, capture_dir; /* suspend all running streams */ list_for_each_entry(spcm, &sdev->pcm_list, list) { - mutex_lock(&spcm->mutex); - playback_dir = SNDRV_PCM_STREAM_PLAYBACK; - capture_dir = SNDRV_PCM_STREAM_CAPTURE; - - /* suspend running streams in both directions */ - for (dir = playback_dir; dir <= capture_dir; dir++) { - substream = spcm->stream[dir].substream; - - if (substream && substream->runtime) { - - snd_pcm_suspend(substream); - - /* - * set restore_stream so that hw_params can be - * restored during resume - */ - spcm->restore_stream[dir] = 1; - } - } + spcm->restore_stream[0] = 1; + spcm->restore_stream[1] = 1; mutex_unlock(&spcm->mutex); } @@ -311,11 +292,9 @@ static int sof_suspend(struct device *dev, bool runtime_suspend) /* release trace */ snd_sof_release_trace(sdev); - /* - * Suspend running pcm streams. - * They will be restarted by ALSA resume trigger call. - */ - sof_suspend_streams(sdev); + /* set restore_stream for all streams during system suspend */ + if (!runtime_suspend) + sof_set_restore_stream(sdev); /* notify DSP of upcoming power down */ ret = sof_send_pm_ipc(sdev, SOF_IPC_PM_CTX_SAVE);