[alsa-devel] [PATCH v2 resend 0/3] ASoC: SOF: fix suspend ordering with runtime idle

Hi all, this series addresses issues with ordering of HDA codec and controller suspends in the runtime PM flows. The implemented logic for SOF is similar to what has been used by the Intel AZX HDA driver.
To implement this, first a fix is needed to hdac_hdmic ASoC codec driver. SOF framework also needs to be extended to allow SOF devices to implement a runtime_idle callback. Third, concrete implementation is in a separate patch for APL/CNL Intel hardware, for which strict ordering of codec-controller power down sequence needs to be maintained.
As this extends the SOF device interface, Pierre asked me to send to the list for wider review. This series has been prereviewd at SOF github as: https://github.com/thesofproject/linux/pull/1003
v2 resend: - no changes since v2 -- resending as 2 weeks has passed and multiple reviewed-by acks already received v2: - Rebased on broonie/for-next, there was a conflict with patch "ASoC: SOF: Intel: hda: release link DMA for paused streams during suspend" - Added Reviewed-by tags from v1 round
Kai Vehmanen (3): ASoC: hdac_hdmi: report codec link up/down status to bus ASoC: SOF: add runtime idle callback ASoC: SOF: Intel: implement runtime idle for CNL/APL
sound/soc/codecs/hdac_hdmi.c | 2 ++ sound/soc/sof/intel/apl.c | 1 + sound/soc/sof/intel/cnl.c | 1 + sound/soc/sof/intel/hda-dsp.c | 13 +++++++++++++ sound/soc/sof/intel/hda.h | 1 + sound/soc/sof/ops.h | 8 ++++++++ sound/soc/sof/pm.c | 8 ++++++++ sound/soc/sof/sof-acpi-dev.c | 2 +- sound/soc/sof/sof-pci-dev.c | 2 +- sound/soc/sof/sof-priv.h | 2 ++ 10 files changed, 38 insertions(+), 2 deletions(-)

Report codec power status to the HDA codec bus from runtime pm suspend and resume callbacks. This is required to implement runtime idle logic that relies on 'codec_powered' field of hdac_bus to be maintained for all codecs.
Signed-off-by: Kai Vehmanen kai.vehmanen@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Takashi Iwai tiwai@suse.de --- sound/soc/codecs/hdac_hdmi.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index 660e0587f3999..01ab7aed315cb 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -2090,6 +2090,7 @@ static int hdac_hdmi_runtime_suspend(struct device *dev) return -EIO; }
+ snd_hdac_codec_link_down(hdev); snd_hdac_ext_bus_link_put(bus, hlink);
snd_hdac_display_power(bus, hdev->addr, false); @@ -2116,6 +2117,7 @@ static int hdac_hdmi_runtime_resume(struct device *dev) }
snd_hdac_ext_bus_link_get(bus, hlink); + snd_hdac_codec_link_up(hdev);
snd_hdac_display_power(bus, hdev->addr, true);

The patch
ASoC: hdac_hdmi: report codec link up/down status to bus
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.3
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From e62bccf8a5ec47768ae2600dc880b148cce19f1b Mon Sep 17 00:00:00 2001
From: Kai Vehmanen kai.vehmanen@linux.intel.com Date: Tue, 2 Jul 2019 16:24:26 +0300 Subject: [PATCH] ASoC: hdac_hdmi: report codec link up/down status to bus
Report codec power status to the HDA codec bus from runtime pm suspend and resume callbacks. This is required to implement runtime idle logic that relies on 'codec_powered' field of hdac_bus to be maintained for all codecs.
Signed-off-by: Kai Vehmanen kai.vehmanen@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Takashi Iwai tiwai@suse.de Link: https://lore.kernel.org/r/20190702132428.13129-2-kai.vehmanen@linux.intel.co... Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/codecs/hdac_hdmi.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/sound/soc/codecs/hdac_hdmi.c b/sound/soc/codecs/hdac_hdmi.c index c9f9820968bb..47eee18b66a3 100644 --- a/sound/soc/codecs/hdac_hdmi.c +++ b/sound/soc/codecs/hdac_hdmi.c @@ -2088,6 +2088,7 @@ static int hdac_hdmi_runtime_suspend(struct device *dev) return -EIO; }
+ snd_hdac_codec_link_down(hdev); snd_hdac_ext_bus_link_put(bus, hlink);
snd_hdac_display_power(bus, hdev->addr, false); @@ -2114,6 +2115,7 @@ static int hdac_hdmi_runtime_resume(struct device *dev) }
snd_hdac_ext_bus_link_get(bus, hlink); + snd_hdac_codec_link_up(hdev);
snd_hdac_display_power(bus, hdev->addr, true);

Add ability to implement a SOF device level runtime idle callback.
Signed-off-by: Kai Vehmanen kai.vehmanen@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Takashi Iwai tiwai@suse.de --- sound/soc/sof/intel/hda.h | 1 + sound/soc/sof/ops.h | 8 ++++++++ sound/soc/sof/pm.c | 8 ++++++++ sound/soc/sof/sof-acpi-dev.c | 2 +- sound/soc/sof/sof-pci-dev.c | 2 +- sound/soc/sof/sof-priv.h | 2 ++ 6 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 73d7cc08afc22..d9c17146200b3 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -457,6 +457,7 @@ int hda_dsp_suspend(struct snd_sof_dev *sdev, int state); int hda_dsp_resume(struct snd_sof_dev *sdev); int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev, int state); int hda_dsp_runtime_resume(struct snd_sof_dev *sdev); +int hda_dsp_runtime_idle(struct snd_sof_dev *sdev); int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev); void hda_dsp_dump_skl(struct snd_sof_dev *sdev, u32 flags); void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags); diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index 45a3d10911634..b9bdf45889da1 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -134,6 +134,14 @@ static inline int snd_sof_dsp_runtime_suspend(struct snd_sof_dev *sdev, return 0; }
+static inline int snd_sof_dsp_runtime_idle(struct snd_sof_dev *sdev) +{ + if (sof_ops(sdev)->runtime_idle) + return sof_ops(sdev)->runtime_idle(sdev); + + return 0; +} + static inline int snd_sof_dsp_hw_params_upon_resume(struct snd_sof_dev *sdev) { if (sof_ops(sdev)->set_hw_params_upon_resume) diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c index 8eeb3a1029f24..278abfd10490d 100644 --- a/sound/soc/sof/pm.c +++ b/sound/soc/sof/pm.c @@ -394,6 +394,14 @@ int snd_sof_runtime_suspend(struct device *dev) } EXPORT_SYMBOL(snd_sof_runtime_suspend);
+int snd_sof_runtime_idle(struct device *dev) +{ + struct snd_sof_dev *sdev = dev_get_drvdata(dev); + + return snd_sof_dsp_runtime_idle(sdev); +} +EXPORT_SYMBOL(snd_sof_runtime_idle); + int snd_sof_runtime_resume(struct device *dev) { return sof_resume(dev, true); diff --git a/sound/soc/sof/sof-acpi-dev.c b/sound/soc/sof/sof-acpi-dev.c index c8dafb1ac54e2..ea7b8b8954128 100644 --- a/sound/soc/sof/sof-acpi-dev.c +++ b/sound/soc/sof/sof-acpi-dev.c @@ -116,7 +116,7 @@ static const struct sof_dev_desc sof_acpi_cherrytrail_desc = { static const struct dev_pm_ops sof_acpi_pm = { SET_SYSTEM_SLEEP_PM_OPS(snd_sof_suspend, snd_sof_resume) SET_RUNTIME_PM_OPS(snd_sof_runtime_suspend, snd_sof_runtime_resume, - NULL) + snd_sof_runtime_idle) };
static void sof_acpi_probe_complete(struct device *dev) diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c index e2b19782f01ac..65d1bac4c6b8b 100644 --- a/sound/soc/sof/sof-pci-dev.c +++ b/sound/soc/sof/sof-pci-dev.c @@ -206,7 +206,7 @@ static const struct sof_dev_desc kbl_desc = { static const struct dev_pm_ops sof_pci_pm = { SET_SYSTEM_SLEEP_PM_OPS(snd_sof_suspend, snd_sof_resume) SET_RUNTIME_PM_OPS(snd_sof_runtime_suspend, snd_sof_runtime_resume, - NULL) + snd_sof_runtime_idle) };
static void sof_pci_probe_complete(struct device *dev) diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 58621db4fd31a..b8c0b2a226845 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -176,6 +176,7 @@ struct snd_sof_dsp_ops { int (*runtime_suspend)(struct snd_sof_dev *sof_dev, int state); /* optional */ int (*runtime_resume)(struct snd_sof_dev *sof_dev); /* optional */ + int (*runtime_idle)(struct snd_sof_dev *sof_dev); /* optional */ int (*set_hw_params_upon_resume)(struct snd_sof_dev *sdev); /* optional */
/* DSP clocking */ @@ -446,6 +447,7 @@ int snd_sof_device_remove(struct device *dev);
int snd_sof_runtime_suspend(struct device *dev); int snd_sof_runtime_resume(struct device *dev); +int snd_sof_runtime_idle(struct device *dev); int snd_sof_resume(struct device *dev); int snd_sof_suspend(struct device *dev);

The patch
ASoC: SOF: add runtime idle callback
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.3
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 62fde9772dd8400bc407de8822ede56b5f2f67f1 Mon Sep 17 00:00:00 2001
From: Kai Vehmanen kai.vehmanen@linux.intel.com Date: Tue, 2 Jul 2019 16:24:27 +0300 Subject: [PATCH] ASoC: SOF: add runtime idle callback
Add ability to implement a SOF device level runtime idle callback.
Signed-off-by: Kai Vehmanen kai.vehmanen@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Takashi Iwai tiwai@suse.de Link: https://lore.kernel.org/r/20190702132428.13129-3-kai.vehmanen@linux.intel.co... Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/sof/intel/hda.h | 1 + sound/soc/sof/ops.h | 8 ++++++++ sound/soc/sof/pm.c | 8 ++++++++ sound/soc/sof/sof-acpi-dev.c | 2 +- sound/soc/sof/sof-pci-dev.c | 2 +- sound/soc/sof/sof-priv.h | 2 ++ 6 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 73d7cc08afc2..d9c17146200b 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -457,6 +457,7 @@ int hda_dsp_suspend(struct snd_sof_dev *sdev, int state); int hda_dsp_resume(struct snd_sof_dev *sdev); int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev, int state); int hda_dsp_runtime_resume(struct snd_sof_dev *sdev); +int hda_dsp_runtime_idle(struct snd_sof_dev *sdev); int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev); void hda_dsp_dump_skl(struct snd_sof_dev *sdev, u32 flags); void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags); diff --git a/sound/soc/sof/ops.h b/sound/soc/sof/ops.h index 45a3d1091163..b9bdf45889da 100644 --- a/sound/soc/sof/ops.h +++ b/sound/soc/sof/ops.h @@ -134,6 +134,14 @@ static inline int snd_sof_dsp_runtime_suspend(struct snd_sof_dev *sdev, return 0; }
+static inline int snd_sof_dsp_runtime_idle(struct snd_sof_dev *sdev) +{ + if (sof_ops(sdev)->runtime_idle) + return sof_ops(sdev)->runtime_idle(sdev); + + return 0; +} + static inline int snd_sof_dsp_hw_params_upon_resume(struct snd_sof_dev *sdev) { if (sof_ops(sdev)->set_hw_params_upon_resume) diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c index 8eeb3a1029f2..278abfd10490 100644 --- a/sound/soc/sof/pm.c +++ b/sound/soc/sof/pm.c @@ -394,6 +394,14 @@ int snd_sof_runtime_suspend(struct device *dev) } EXPORT_SYMBOL(snd_sof_runtime_suspend);
+int snd_sof_runtime_idle(struct device *dev) +{ + struct snd_sof_dev *sdev = dev_get_drvdata(dev); + + return snd_sof_dsp_runtime_idle(sdev); +} +EXPORT_SYMBOL(snd_sof_runtime_idle); + int snd_sof_runtime_resume(struct device *dev) { return sof_resume(dev, true); diff --git a/sound/soc/sof/sof-acpi-dev.c b/sound/soc/sof/sof-acpi-dev.c index c8dafb1ac54e..ea7b8b895412 100644 --- a/sound/soc/sof/sof-acpi-dev.c +++ b/sound/soc/sof/sof-acpi-dev.c @@ -116,7 +116,7 @@ static const struct sof_dev_desc sof_acpi_cherrytrail_desc = { static const struct dev_pm_ops sof_acpi_pm = { SET_SYSTEM_SLEEP_PM_OPS(snd_sof_suspend, snd_sof_resume) SET_RUNTIME_PM_OPS(snd_sof_runtime_suspend, snd_sof_runtime_resume, - NULL) + snd_sof_runtime_idle) };
static void sof_acpi_probe_complete(struct device *dev) diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c index e2b19782f01a..65d1bac4c6b8 100644 --- a/sound/soc/sof/sof-pci-dev.c +++ b/sound/soc/sof/sof-pci-dev.c @@ -206,7 +206,7 @@ static const struct sof_dev_desc kbl_desc = { static const struct dev_pm_ops sof_pci_pm = { SET_SYSTEM_SLEEP_PM_OPS(snd_sof_suspend, snd_sof_resume) SET_RUNTIME_PM_OPS(snd_sof_runtime_suspend, snd_sof_runtime_resume, - NULL) + snd_sof_runtime_idle) };
static void sof_pci_probe_complete(struct device *dev) diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index 58621db4fd31..b8c0b2a22684 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -176,6 +176,7 @@ struct snd_sof_dsp_ops { int (*runtime_suspend)(struct snd_sof_dev *sof_dev, int state); /* optional */ int (*runtime_resume)(struct snd_sof_dev *sof_dev); /* optional */ + int (*runtime_idle)(struct snd_sof_dev *sof_dev); /* optional */ int (*set_hw_params_upon_resume)(struct snd_sof_dev *sdev); /* optional */
/* DSP clocking */ @@ -446,6 +447,7 @@ int snd_sof_device_remove(struct device *dev);
int snd_sof_runtime_suspend(struct device *dev); int snd_sof_runtime_resume(struct device *dev); +int snd_sof_runtime_idle(struct device *dev); int snd_sof_resume(struct device *dev); int snd_sof_suspend(struct device *dev);

Implement runtime idle for CNL/APL devices using similar runtime PM idle logic as the Intel AZX HDA driver. If any HDA codecs are powered when runtime suspend request comes, return -EBUSY. By doing this, strict ordering is enforced between HDA codec and the HDA controller.
Signed-off-by: Kai Vehmanen kai.vehmanen@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Takashi Iwai tiwai@suse.de --- sound/soc/sof/intel/apl.c | 1 + sound/soc/sof/intel/cnl.c | 1 + sound/soc/sof/intel/hda-dsp.c | 13 +++++++++++++ 3 files changed, 15 insertions(+)
diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c index 43d1c9f31ec4c..fd2e26d797961 100644 --- a/sound/soc/sof/intel/apl.c +++ b/sound/soc/sof/intel/apl.c @@ -93,6 +93,7 @@ const struct snd_sof_dsp_ops sof_apl_ops = { .resume = hda_dsp_resume, .runtime_suspend = hda_dsp_runtime_suspend, .runtime_resume = hda_dsp_runtime_resume, + .runtime_idle = hda_dsp_runtime_idle, .set_hw_params_upon_resume = hda_dsp_set_hw_params_upon_resume, }; EXPORT_SYMBOL(sof_apl_ops); diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c index 3840f81767fab..f2b392998f20d 100644 --- a/sound/soc/sof/intel/cnl.c +++ b/sound/soc/sof/intel/cnl.c @@ -251,6 +251,7 @@ const struct snd_sof_dsp_ops sof_cnl_ops = { .resume = hda_dsp_resume, .runtime_suspend = hda_dsp_runtime_suspend, .runtime_resume = hda_dsp_runtime_resume, + .runtime_idle = hda_dsp_runtime_idle, .set_hw_params_upon_resume = hda_dsp_set_hw_params_upon_resume, }; EXPORT_SYMBOL(sof_cnl_ops); diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index f2c5a12db930a..91de4785b6a3e 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -418,6 +418,19 @@ int hda_dsp_runtime_resume(struct snd_sof_dev *sdev) return hda_resume(sdev); }
+int hda_dsp_runtime_idle(struct snd_sof_dev *sdev) +{ + struct hdac_bus *hbus = sof_to_bus(sdev); + + if (hbus->codec_powered) { + dev_dbg(sdev->dev, "some codecs still powered (%08X), not idle\n", + (unsigned int)hbus->codec_powered); + return -EBUSY; + } + + return 0; +} + int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev, int state) { /* stop hda controller and power dsp off */

The patch
ASoC: SOF: Intel: implement runtime idle for CNL/APL
has been applied to the asoc tree at
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-5.3
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
From 87a6fe80d56be85bda093c4dd8a3e6535bda7e4a Mon Sep 17 00:00:00 2001
From: Kai Vehmanen kai.vehmanen@linux.intel.com Date: Tue, 2 Jul 2019 16:24:28 +0300 Subject: [PATCH] ASoC: SOF: Intel: implement runtime idle for CNL/APL
Implement runtime idle for CNL/APL devices using similar runtime PM idle logic as the Intel AZX HDA driver. If any HDA codecs are powered when runtime suspend request comes, return -EBUSY. By doing this, strict ordering is enforced between HDA codec and the HDA controller.
Signed-off-by: Kai Vehmanen kai.vehmanen@linux.intel.com Reviewed-by: Pierre-Louis Bossart pierre-louis.bossart@linux.intel.com Reviewed-by: Takashi Iwai tiwai@suse.de Link: https://lore.kernel.org/r/20190702132428.13129-4-kai.vehmanen@linux.intel.co... Signed-off-by: Mark Brown broonie@kernel.org --- sound/soc/sof/intel/apl.c | 1 + sound/soc/sof/intel/cnl.c | 1 + sound/soc/sof/intel/hda-dsp.c | 13 +++++++++++++ 3 files changed, 15 insertions(+)
diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c index 43d1c9f31ec4..fd2e26d79796 100644 --- a/sound/soc/sof/intel/apl.c +++ b/sound/soc/sof/intel/apl.c @@ -93,6 +93,7 @@ const struct snd_sof_dsp_ops sof_apl_ops = { .resume = hda_dsp_resume, .runtime_suspend = hda_dsp_runtime_suspend, .runtime_resume = hda_dsp_runtime_resume, + .runtime_idle = hda_dsp_runtime_idle, .set_hw_params_upon_resume = hda_dsp_set_hw_params_upon_resume, }; EXPORT_SYMBOL(sof_apl_ops); diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c index 3840f81767fa..f2b392998f20 100644 --- a/sound/soc/sof/intel/cnl.c +++ b/sound/soc/sof/intel/cnl.c @@ -251,6 +251,7 @@ const struct snd_sof_dsp_ops sof_cnl_ops = { .resume = hda_dsp_resume, .runtime_suspend = hda_dsp_runtime_suspend, .runtime_resume = hda_dsp_runtime_resume, + .runtime_idle = hda_dsp_runtime_idle, .set_hw_params_upon_resume = hda_dsp_set_hw_params_upon_resume, }; EXPORT_SYMBOL(sof_cnl_ops); diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index f2c5a12db930..91de4785b6a3 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -418,6 +418,19 @@ int hda_dsp_runtime_resume(struct snd_sof_dev *sdev) return hda_resume(sdev); }
+int hda_dsp_runtime_idle(struct snd_sof_dev *sdev) +{ + struct hdac_bus *hbus = sof_to_bus(sdev); + + if (hbus->codec_powered) { + dev_dbg(sdev->dev, "some codecs still powered (%08X), not idle\n", + (unsigned int)hbus->codec_powered); + return -EBUSY; + } + + return 0; +} + int hda_dsp_runtime_suspend(struct snd_sof_dev *sdev, int state) { /* stop hda controller and power dsp off */
participants (2)
-
Kai Vehmanen
-
Mark Brown