ASoC: SOF: Move DSP power state transitions to platform-specific ops
[platform/kernel/linux-rpi.git] / sound / soc / sof / core.c
index 44f9c04..1d07450 100644 (file)
@@ -224,12 +224,12 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
        if (ret < 0) {
                dev_err(sdev->dev,
                        "error: failed to register DSP DAI driver %d\n", ret);
        if (ret < 0) {
                dev_err(sdev->dev,
                        "error: failed to register DSP DAI driver %d\n", ret);
-               goto fw_run_err;
+               goto fw_trace_err;
        }
 
        ret = snd_sof_machine_register(sdev, plat_data);
        if (ret < 0)
        }
 
        ret = snd_sof_machine_register(sdev, plat_data);
        if (ret < 0)
-               goto fw_run_err;
+               goto fw_trace_err;
 
        /*
         * Some platforms in SOF, ex: BYT, may not have their platform PM
 
        /*
         * Some platforms in SOF, ex: BYT, may not have their platform PM
@@ -244,7 +244,8 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
 
        return 0;
 
 
        return 0;
 
-#if !IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)
+fw_trace_err:
+       snd_sof_free_trace(sdev);
 fw_run_err:
        snd_sof_fw_unload(sdev);
 fw_load_err:
 fw_run_err:
        snd_sof_fw_unload(sdev);
 fw_load_err:
@@ -253,21 +254,10 @@ ipc_err:
        snd_sof_free_debug(sdev);
 dbg_err:
        snd_sof_remove(sdev);
        snd_sof_free_debug(sdev);
 dbg_err:
        snd_sof_remove(sdev);
-#else
-
-       /*
-        * when the probe_continue is handled in a work queue, the
-        * probe does not fail so we don't release resources here.
-        * They will be released with an explicit call to
-        * snd_sof_device_remove() when the PCI/ACPI device is removed
-        */
-
-fw_run_err:
-fw_load_err:
-ipc_err:
-dbg_err:
 
 
-#endif
+       /* all resources freed, update state to match */
+       sdev->fw_state = SOF_FW_BOOT_NOT_STARTED;
+       sdev->first_boot = true;
 
        return ret;
 }
 
        return ret;
 }
@@ -296,8 +286,8 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data)
        /* initialize sof device */
        sdev->dev = dev;
 
        /* initialize sof device */
        sdev->dev = dev;
 
-       /* initialize default D0 sub-state */
-       sdev->d0_substate = SOF_DSP_D0I0;
+       /* initialize default DSP power state */
+       sdev->dsp_power_state.state = SOF_DSP_PM_D0;
 
        sdev->pdata = plat_data;
        sdev->first_boot = true;
 
        sdev->pdata = plat_data;
        sdev->first_boot = true;
@@ -350,10 +340,12 @@ int snd_sof_device_remove(struct device *dev)
        if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE))
                cancel_work_sync(&sdev->probe_work);
 
        if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE))
                cancel_work_sync(&sdev->probe_work);
 
-       snd_sof_fw_unload(sdev);
-       snd_sof_ipc_free(sdev);
-       snd_sof_free_debug(sdev);
-       snd_sof_free_trace(sdev);
+       if (sdev->fw_state > SOF_FW_BOOT_NOT_STARTED) {
+               snd_sof_fw_unload(sdev);
+               snd_sof_ipc_free(sdev);
+               snd_sof_free_debug(sdev);
+               snd_sof_free_trace(sdev);
+       }
 
        /*
         * Unregister machine driver. This will unbind the snd_card which
 
        /*
         * Unregister machine driver. This will unbind the snd_card which
@@ -361,13 +353,15 @@ int snd_sof_device_remove(struct device *dev)
         * before freeing the snd_card.
         */
        snd_sof_machine_unregister(sdev, pdata);
         * before freeing the snd_card.
         */
        snd_sof_machine_unregister(sdev, pdata);
+
        /*
         * Unregistering the machine driver results in unloading the topology.
         * Some widgets, ex: scheduler, attempt to power down the core they are
         * scheduled on, when they are unloaded. Therefore, the DSP must be
         * removed only after the topology has been unloaded.
         */
        /*
         * Unregistering the machine driver results in unloading the topology.
         * Some widgets, ex: scheduler, attempt to power down the core they are
         * scheduled on, when they are unloaded. Therefore, the DSP must be
         * removed only after the topology has been unloaded.
         */
-       snd_sof_remove(sdev);
+       if (sdev->fw_state > SOF_FW_BOOT_NOT_STARTED)
+               snd_sof_remove(sdev);
 
        /* release firmware */
        release_firmware(pdata->fw);
 
        /* release firmware */
        release_firmware(pdata->fw);