diff options
Diffstat (limited to 'sound/soc/sof/core.c')
-rw-r--r-- | sound/soc/sof/core.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c index 32105e0fabe8..5beda47cdf9f 100644 --- a/sound/soc/sof/core.c +++ b/sound/soc/sof/core.c @@ -382,7 +382,7 @@ static int sof_probe_continue(struct snd_sof_dev *sdev) if (IS_ERR(plat_data->pdev_mach)) { ret = PTR_ERR(plat_data->pdev_mach); - goto comp_err; + goto fw_run_err; } dev_dbg(sdev->dev, "created machine %s\n", @@ -393,8 +393,7 @@ static int sof_probe_continue(struct snd_sof_dev *sdev) return 0; -comp_err: - snd_soc_unregister_component(sdev->dev); +#if !IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE) fw_run_err: snd_sof_fw_unload(sdev); fw_load_err: @@ -403,6 +402,21 @@ ipc_err: 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 return ret; } @@ -484,7 +498,6 @@ int snd_sof_device_remove(struct device *dev) snd_sof_ipc_free(sdev); snd_sof_free_debug(sdev); snd_sof_free_trace(sdev); - snd_sof_remove(sdev); /* * Unregister machine driver. This will unbind the snd_card which @@ -494,6 +507,14 @@ int snd_sof_device_remove(struct device *dev) if (!IS_ERR_OR_NULL(pdata->pdev_mach)) platform_device_unregister(pdata->pdev_mach); + /* + * 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); + /* release firmware */ release_firmware(pdata->fw); pdata->fw = NULL; |