OSDN Git Service

ASoC: SOF: topology: fix core enable sequence
authorRanjani Sridharan <ranjani.sridharan@linux.intel.com>
Wed, 2 Sep 2020 14:07:56 +0000 (17:07 +0300)
committerMark Brown <broonie@kernel.org>
Fri, 4 Sep 2020 09:12:23 +0000 (10:12 +0100)
Core power up involves 2 steps: The first step tries to
power up the core by setting the ADSPCS.SPA bit for the host-managed
cores. The second step involves sending the IPC to power up other
cores that are not host managed. The enabled_cores_mask should
be updated only when both these steps are successful. If the
IPC to the DSP fails, the host-managed core that was powered in
step 1 should be powered off before returning the error.

Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
Reviewed-by: Rander Wang <rander.wang@linux.intel.com>
Reviewed-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Reviewed-by: Keyon Jie <yang.jie@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/20200902140756.1427005-4-kai.vehmanen@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/topology.c

index 46468fb..d47da40 100644 (file)
@@ -1303,7 +1303,7 @@ static int sof_core_enable(struct snd_sof_dev *sdev, int core)
        if (sdev->enabled_cores_mask & BIT(core))
                return 0;
 
-       /* power up the core */
+       /* power up the core if it is host managed */
        ret = snd_sof_dsp_core_power_up(sdev, BIT(core));
        if (ret < 0) {
                dev_err(sdev->dev, "error: %d powering up core %d\n",
@@ -1311,16 +1311,24 @@ static int sof_core_enable(struct snd_sof_dev *sdev, int core)
                return ret;
        }
 
-       /* update enabled cores mask */
-       sdev->enabled_cores_mask |= BIT(core);
-
-       /* Now notify DSP that the core has been powered up */
+       /* Now notify DSP */
        ret = sof_ipc_tx_message(sdev->ipc, pm_core_config.hdr.cmd,
                                 &pm_core_config, sizeof(pm_core_config),
                                 &pm_core_config, sizeof(pm_core_config));
-       if (ret < 0)
+       if (ret < 0) {
                dev_err(sdev->dev, "error: core %d enable ipc failure %d\n",
                        core, ret);
+               goto err;
+       }
+
+       /* update enabled cores mask */
+       sdev->enabled_cores_mask |= BIT(core);
+
+       return ret;
+err:
+       /* power down core if it is host managed and return the original error if this fails too */
+       if (snd_sof_dsp_core_power_down(sdev, BIT(core)) < 0)
+               dev_err(sdev->dev, "error: powering down core %d\n", core);
 
        return ret;
 }