ASoC: SOF: Add ops for core_get and core_put
authorRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Fri, 19 Nov 2021 19:26:14 +0000 (21:26 +0200)
committerMark Brown <broonie@kernel.org>
Mon, 22 Nov 2021 15:40:17 +0000 (15:40 +0000)
Add ops to get/put a core that will be used to power
up/down a core along with incrementing/decrementing
its ref_count.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
Link: https://lore.kernel.org/r/20211119192621.4096077-4-kai.vehmanen@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/ops.h
sound/soc/sof/sof-priv.h

index 09bf38fdfb8a30e11cd10371a92e52ec62e0abd4..61dc2768b0005da3ce0c025b6c9b506a8db5a063 100644 (file)
@@ -103,6 +103,69 @@ static inline int snd_sof_dsp_core_power_down(struct snd_sof_dev *sdev,
        return ret;
 }
 
+static inline int snd_sof_dsp_core_get(struct snd_sof_dev *sdev, int core)
+{
+       if (core > sdev->num_cores - 1) {
+               dev_err(sdev->dev, "invalid core id: %d for num_cores: %d\n", core,
+                       sdev->num_cores);
+               return -EINVAL;
+       }
+
+       if (sof_ops(sdev)->core_get) {
+               int ret;
+
+               /* if current ref_count is > 0, increment it and return */
+               if (sdev->dsp_core_ref_count[core] > 0) {
+                       sdev->dsp_core_ref_count[core]++;
+                       return 0;
+               }
+
+               /* power up the core */
+               ret = sof_ops(sdev)->core_get(sdev, core);
+               if (ret < 0)
+                       return ret;
+
+               /* increment ref_count */
+               sdev->dsp_core_ref_count[core]++;
+
+               /* and update enabled_cores_mask */
+               sdev->enabled_cores_mask |= BIT(core);
+
+               dev_dbg(sdev->dev, "Core %d powered up\n", core);
+       }
+
+       return 0;
+}
+
+static inline int snd_sof_dsp_core_put(struct snd_sof_dev *sdev, int core)
+{
+       if (core > sdev->num_cores - 1) {
+               dev_err(sdev->dev, "invalid core id: %d for num_cores: %d\n", core,
+                       sdev->num_cores);
+               return -EINVAL;
+       }
+
+       if (sof_ops(sdev)->core_put) {
+               int ret;
+
+               /* decrement ref_count and return if it is > 0 */
+               if (--(sdev->dsp_core_ref_count[core]) > 0)
+                       return 0;
+
+               /* power down the core */
+               ret = sof_ops(sdev)->core_put(sdev, core);
+               if (ret < 0)
+                       return ret;
+
+               /* and update enabled_cores_mask */
+               sdev->enabled_cores_mask &= ~BIT(core);
+
+               dev_dbg(sdev->dev, "Core %d powered down\n", core);
+       }
+
+       return 0;
+}
+
 /* pre/post fw load */
 static inline int snd_sof_dsp_pre_fw_run(struct snd_sof_dev *sdev)
 {
index a56f3c8b483f8ce666c8e90a8064ee6b27d8d48d..f7c86a72ac104c9050e1971e04c91d1ff81d1836 100644 (file)
@@ -134,6 +134,8 @@ struct snd_sof_dsp_ops {
                             unsigned int core_mask); /* optional */
        int (*core_power_down)(struct snd_sof_dev *sof_dev,
                               unsigned int core_mask); /* optional */
+       int (*core_get)(struct snd_sof_dev *sof_dev, int core); /* optional */
+       int (*core_put)(struct snd_sof_dev *sof_dev, int core); /* optional */
 
        /*
         * Register IO: only used by respective drivers themselves,