From bb2636a19963ce1a421e86bbf7848a61936e3432 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Tue, 22 Jan 2019 23:39:38 -0800 Subject: [PATCH 1/5] ASoC: SOF: pm: set restore_stream for all streams during suspend. The machine driver pm ops suspends all streams during system suspend. So it is not needed to suspend streams in the SOF driver suspend callback. But since all streams are suspended, set restore_stream so that hw_params can be restored upon resuming. Signed-off-by: Ranjani Sridharan --- sound/soc/sof/pm.c | 33 ++++++--------------------------- 1 file changed, 6 insertions(+), 27 deletions(-) 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); From 22d08b35a5219cf6d838ec054bbc7ebbfe0c3bd0 Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Tue, 22 Jan 2019 23:40:36 -0800 Subject: [PATCH 2/5] ASoC: SOF: send IPC to stop stream during SUSPEND trigger When a suspend trigger is received, send the stop IPC to the DSP to stop the stream. Signed-off-by: Ranjani Sridharan --- sound/soc/sof/pcm.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index 3c4526f15bf195..eb6eeaeb3f0cb6 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -252,22 +252,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 +297,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); From b845426862aaf90db37450e284d08cb47c9a528f Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Wed, 23 Jan 2019 13:01:32 -0800 Subject: [PATCH 3/5] ASoC: SOF: unset restore_stream after hw_params With the use of snd_pcm_suspend_all(), all streams in a pcm will be marked for restoring. So unset restore_stream after hw_params to avoid duplicating the call to hw_params. Signed-off-by: Ranjani Sridharan --- sound/soc/sof/pcm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index eb6eeaeb3f0cb6..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; } From 06d4593de8fefcabde60fa1218287007e158a7cc Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Thu, 24 Jan 2019 09:01:35 -0800 Subject: [PATCH 4/5] ASoC: intel: bxt_pcm512x: set pm ops Set pm ops for the bxt_pcm512x machine driver. Signed-off-by: Ranjani Sridharan --- sound/soc/intel/boards/bxt_pcm512x.c | 1 + 1 file changed, 1 insertion(+) 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, }; From eacadee9dd0e2aa58582460e693a035279995dad Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Thu, 24 Jan 2019 09:02:22 -0800 Subject: [PATCH 5/5] ALSA: PCM: check if ops are defined before suspending PCM BE dai links only have internal PCM's and their substream ops may not be set. Suspending these PCM's will result in their ops->trigger() being invoked and cause a kernel oops. So skip suspending PCM's if their ops are NULL. Signed-off-by: Ranjani Sridharan --- sound/core/pcm_native.c | 8 ++++++++ 1 file changed, 8 insertions(+) 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;