From 408d18f6b06d8ebd750f7bc1308e3a0dec5cb35c Mon Sep 17 00:00:00 2001 From: Ranjani Sridharan Date: Tue, 18 Dec 2018 22:02:20 -0800 Subject: [PATCH] ASoC: SOF: pm: check if core is powered up before performing resume sequence There are some corner cases that the pm suspend callback could fail and the DSP is not powered off. If this happens, we should skip performing the actions in the resume callback to avoid any DSP panic. Signed-off-by: Ranjani Sridharan --- sound/soc/sof/intel/apl.c | 1 + sound/soc/sof/ops.h | 9 +++++++++ sound/soc/sof/pm.c | 9 +++++++++ sound/soc/sof/sof-priv.h | 2 ++ 4 files changed, 21 insertions(+) diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c index 5de30087ded6d7..fb6e9d742695c8 100644 --- a/sound/soc/sof/intel/apl.c +++ b/sound/soc/sof/intel/apl.c @@ -80,6 +80,7 @@ const struct snd_sof_dsp_ops sof_apl_ops = { /* dsp core power up/down */ .core_power_up = hda_dsp_enable_core, .core_power_down = hda_dsp_core_reset_power_down, + .is_core_enabled = hda_dsp_core_is_enabled, /* trace callback */ .trace_init = hda_dsp_trace_init, diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index cf7438ce19eb20..585e6ba8820484 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -79,6 +79,15 @@ static inline int snd_sof_dsp_core_power_down(struct snd_sof_dev *sdev, return 0; } +static inline int snd_sof_dsp_core_is_enabled(struct snd_sof_dev *sdev, + unsigned int core_mask) +{ + if (sdev->ops->is_core_enabled) + return sdev->ops->is_core_enabled(sdev, core_mask); + + return 0; +} + /* pre/post fw load */ static inline int snd_sof_dsp_pre_fw_run(struct snd_sof_dev *sdev) { diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c index 77388a36434bed..83a51d204de7d1 100644 --- a/sound/soc/sof/pm.c +++ b/sound/soc/sof/pm.c @@ -236,6 +236,15 @@ static int sof_resume(struct device *dev, bool runtime_resume) if (!sdev->ops->resume || !sdev->ops->runtime_resume) return 0; + /* + * If for some reason, the cores were not powered off + * during suspend, powering them up again will lead to + * DSP panic. So check if core 0 is powered off to make + * sure before proceeding further. + */ + if (snd_sof_dsp_core_is_enabled(sdev, BIT(0)) + return 0; + /* * if the runtime_resume flag is set, call the runtime_resume routine * or else call the system resume routine diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 1ada7eab46c887..effe732fb0b4ac 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -79,6 +79,8 @@ struct snd_sof_dsp_ops { unsigned int core_mask); int (*core_power_down)(struct snd_sof_dev *sof_dev, unsigned int core_mask); + bool (*is_core_enabled)(struct snd_sof_dev *sof_dev, + unsigned int core_mask); /* pre/post firmware run */ int (*pre_fw_run)(struct snd_sof_dev *sof_dev);