ASoC: SOF: Intel: implement runtime idle for CNL/APL
authorKai Vehmanen <kai.vehmanen@linux.intel.com>
Tue, 2 Jul 2019 13:24:28 +0000 (16:24 +0300)
committerMark Brown <broonie@kernel.org>
Sat, 6 Jul 2019 11:23:47 +0000 (12:23 +0100)
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.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/intel/apl.c
sound/soc/sof/intel/cnl.c
sound/soc/sof/intel/hda-dsp.c

index 43d1c9f31ec4c83c5a519f5cced01a3075878f14..fd2e26d79796190ef43516a2b0a224952fa75450 100644 (file)
@@ -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);
index 3840f81767fab1e162c4964162656ab2af47c85f..f2b392998f20dea89b89a3062b948d584f670ae8 100644 (file)
@@ -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);
index f2c5a12db930a4d6dfca46b8f5be0449d9c21af1..91de4785b6a3ec3e37b801fdcebc4bd6618b60f8 100644 (file)
@@ -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 */