summaryrefslogtreecommitdiff
path: root/sound/soc/sof
diff options
context:
space:
mode:
authorJason Liu <jason.hui.liu@nxp.com>2020-03-08 18:57:18 +0800
committerJason Liu <jason.hui.liu@nxp.com>2020-03-08 18:57:18 +0800
commit335d2828a9000fab6f3895f261e3281342f51f5b (patch)
tree6c7443842b407e98ef110de6683346455b4d0f88 /sound/soc/sof
parent1d12f4912e3b630ee81f17e164309d172d8c50b5 (diff)
parentcff670b3eb68257029e2977a6bfeac7d9b829e9a (diff)
Merge tag 'v5.4.24' into imx_5.4.y
Merge Linux stable release v5.4.24 into imx_5.4.y * tag 'v5.4.24': (3306 commits) Linux 5.4.24 blktrace: Protect q->blk_trace with RCU kvm: nVMX: VMWRITE checks unsupported field before read-only field ... Signed-off-by: Jason Liu <jason.hui.liu@nxp.com> Conflicts: arch/arm/boot/dts/imx6sll-evk.dts arch/arm/boot/dts/imx7ulp.dtsi arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi drivers/clk/imx/clk-composite-8m.c drivers/gpio/gpio-mxc.c drivers/irqchip/Kconfig drivers/mmc/host/sdhci-of-esdhc.c drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c drivers/net/can/flexcan.c drivers/net/ethernet/freescale/dpaa/dpaa_eth.c drivers/net/ethernet/mscc/ocelot.c drivers/net/ethernet/stmicro/stmmac/stmmac_main.c drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c drivers/net/phy/realtek.c drivers/pci/controller/mobiveil/pcie-mobiveil-host.c drivers/perf/fsl_imx8_ddr_perf.c drivers/tee/optee/shm_pool.c drivers/usb/cdns3/gadget.c kernel/sched/cpufreq.c net/core/xdp.c sound/soc/fsl/fsl_esai.c sound/soc/fsl/fsl_sai.c sound/soc/sof/core.c sound/soc/sof/imx/Kconfig sound/soc/sof/loader.c
Diffstat (limited to 'sound/soc/sof')
-rw-r--r--sound/soc/sof/core.c45
-rw-r--r--sound/soc/sof/imx/imx8.c2
-rw-r--r--sound/soc/sof/intel/Kconfig10
-rw-r--r--sound/soc/sof/intel/byt.c7
-rw-r--r--sound/soc/sof/intel/hda-codec.c19
-rw-r--r--sound/soc/sof/intel/hda-dai.c18
-rw-r--r--sound/soc/sof/intel/hda-loader.c1
-rw-r--r--sound/soc/sof/intel/hda.c5
-rw-r--r--sound/soc/sof/intel/hda.h2
-rw-r--r--sound/soc/sof/ipc.c20
-rw-r--r--sound/soc/sof/loader.c19
-rw-r--r--sound/soc/sof/pm.c25
-rw-r--r--sound/soc/sof/sof-priv.h11
-rw-r--r--sound/soc/sof/topology.c4
14 files changed, 125 insertions, 63 deletions
diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c
index 6a32eb8c0795..6a252f2ebbc4 100644
--- a/sound/soc/sof/core.c
+++ b/sound/soc/sof/core.c
@@ -278,6 +278,8 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
return ret;
}
+ sdev->fw_state = SOF_FW_BOOT_PREPARE;
+
/* check machine info */
ret = snd_sof_machine_check(sdev);
if (ret < 0) {
@@ -317,7 +319,12 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
goto fw_load_err;
}
- /* boot the firmware */
+ sdev->fw_state = SOF_FW_BOOT_IN_PROGRESS;
+
+ /*
+ * Boot the firmware. The FW boot status will be modified
+ * in snd_sof_run_firmware() depending on the outcome.
+ */
ret = snd_sof_run_firmware(sdev);
if (ret < 0) {
dev_err(sdev->dev, "error: failed to boot DSP firmware %d\n",
@@ -343,7 +350,7 @@ 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);
- goto fw_run_err;
+ goto fw_trace_err;
}
ret = snd_sof_machine_register(sdev, plat_data);
@@ -363,7 +370,8 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
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:
@@ -372,21 +380,10 @@ 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
+ /* all resources freed, update state to match */
+ sdev->fw_state = SOF_FW_BOOT_NOT_STARTED;
+ sdev->first_boot = true;
return ret;
}
@@ -417,6 +414,7 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data)
sdev->pdata = plat_data;
sdev->first_boot = true;
+ sdev->fw_state = SOF_FW_BOOT_NOT_STARTED;
dev_set_drvdata(dev, sdev);
/* check all mandatory ops */
@@ -464,10 +462,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);
- 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
@@ -481,7 +481,8 @@ int snd_sof_device_remove(struct device *dev)
* 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);
diff --git a/sound/soc/sof/imx/imx8.c b/sound/soc/sof/imx/imx8.c
index 49dfbeecddff..d9d47972908b 100644
--- a/sound/soc/sof/imx/imx8.c
+++ b/sound/soc/sof/imx/imx8.c
@@ -231,7 +231,7 @@ static int imx8_probe(struct snd_sof_dev *sdev)
priv->pd_dev = devm_kmalloc_array(&pdev->dev, priv->num_domains,
sizeof(*priv->pd_dev), GFP_KERNEL);
- if (!priv)
+ if (!priv->pd_dev)
return -ENOMEM;
priv->link = devm_kmalloc_array(&pdev->dev, priv->num_domains,
diff --git a/sound/soc/sof/intel/Kconfig b/sound/soc/sof/intel/Kconfig
index d62f51d33be1..8421b97d949e 100644
--- a/sound/soc/sof/intel/Kconfig
+++ b/sound/soc/sof/intel/Kconfig
@@ -76,10 +76,18 @@ config SND_SOC_SOF_BAYTRAIL
config SND_SOC_SOF_BROADWELL_SUPPORT
bool "SOF support for Broadwell"
+ depends on SND_SOC_INTEL_HASWELL=n
help
This adds support for Sound Open Firmware for Intel(R) platforms
using the Broadwell processors.
- Say Y if you have such a device.
+ This option is mutually exclusive with the Haswell/Broadwell legacy
+ driver. If you want to enable SOF on Broadwell you need to deselect
+ the legacy driver first.
+ SOF does fully support Broadwell yet, so this option is not
+ recommended for distros. At some point all legacy drivers will be
+ deprecated but not before all userspace firmware/topology/UCM files
+ are made available to downstream distros.
+ Say Y if you want to enable SOF on Broadwell
If unsure select "N".
config SND_SOC_SOF_BROADWELL
diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c
index b55aecd6fe3f..a876e1e60c2f 100644
--- a/sound/soc/sof/intel/byt.c
+++ b/sound/soc/sof/intel/byt.c
@@ -24,7 +24,8 @@
#define DRAM_OFFSET 0x100000
#define DRAM_SIZE (160 * 1024)
#define SHIM_OFFSET 0x140000
-#define SHIM_SIZE 0x100
+#define SHIM_SIZE_BYT 0x100
+#define SHIM_SIZE_CHT 0x118
#define MBOX_OFFSET 0x144000
#define MBOX_SIZE 0x1000
#define EXCEPT_OFFSET 0x800
@@ -75,7 +76,7 @@ static const struct snd_sof_debugfs_map byt_debugfs[] = {
SOF_DEBUGFS_ACCESS_D0_ONLY},
{"dram", BYT_DSP_BAR, DRAM_OFFSET, DRAM_SIZE,
SOF_DEBUGFS_ACCESS_D0_ONLY},
- {"shim", BYT_DSP_BAR, SHIM_OFFSET, SHIM_SIZE,
+ {"shim", BYT_DSP_BAR, SHIM_OFFSET, SHIM_SIZE_BYT,
SOF_DEBUGFS_ACCESS_ALWAYS},
};
@@ -102,7 +103,7 @@ static const struct snd_sof_debugfs_map cht_debugfs[] = {
SOF_DEBUGFS_ACCESS_D0_ONLY},
{"dram", BYT_DSP_BAR, DRAM_OFFSET, DRAM_SIZE,
SOF_DEBUGFS_ACCESS_D0_ONLY},
- {"shim", BYT_DSP_BAR, SHIM_OFFSET, SHIM_SIZE,
+ {"shim", BYT_DSP_BAR, SHIM_OFFSET, SHIM_SIZE_CHT,
SOF_DEBUGFS_ACCESS_ALWAYS},
};
diff --git a/sound/soc/sof/intel/hda-codec.c b/sound/soc/sof/intel/hda-codec.c
index 3ca6795a89ba..9e8233c10d86 100644
--- a/sound/soc/sof/intel/hda-codec.c
+++ b/sound/soc/sof/intel/hda-codec.c
@@ -24,19 +24,18 @@
#define IDISP_VID_INTEL 0x80860000
/* load the legacy HDA codec driver */
-#ifdef MODULE
-static void hda_codec_load_module(struct hda_codec *codec)
+static int hda_codec_load_module(struct hda_codec *codec)
{
+#ifdef MODULE
char alias[MODULE_NAME_LEN];
const char *module = alias;
snd_hdac_codec_modalias(&codec->core, alias, sizeof(alias));
dev_dbg(&codec->core.dev, "loading codec module: %s\n", module);
request_module(module);
-}
-#else
-static void hda_codec_load_module(struct hda_codec *codec) {}
#endif
+ return device_attach(hda_codec_dev(codec));
+}
/* enable controller wake up event for all codecs with jack connectors */
void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev)
@@ -116,10 +115,16 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address)
/* use legacy bus only for HDA codecs, idisp uses ext bus */
if ((resp & 0xFFFF0000) != IDISP_VID_INTEL) {
hdev->type = HDA_DEV_LEGACY;
- hda_codec_load_module(&hda_priv->codec);
+ ret = hda_codec_load_module(&hda_priv->codec);
+ /*
+ * handle ret==0 (no driver bound) as an error, but pass
+ * other return codes without modification
+ */
+ if (ret == 0)
+ ret = -ENOENT;
}
- return 0;
+ return ret;
#else
hdev = devm_kzalloc(sdev->dev, sizeof(*hdev), GFP_KERNEL);
if (!hdev)
diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c
index 8796f385be76..3f645200d3a5 100644
--- a/sound/soc/sof/intel/hda-dai.c
+++ b/sound/soc/sof/intel/hda-dai.c
@@ -216,6 +216,8 @@ static int hda_link_hw_params(struct snd_pcm_substream *substream,
link_dev = hda_link_stream_assign(bus, substream);
if (!link_dev)
return -EBUSY;
+
+ snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev);
}
stream_tag = hdac_stream(link_dev)->stream_tag;
@@ -228,8 +230,6 @@ static int hda_link_hw_params(struct snd_pcm_substream *substream,
if (ret < 0)
return ret;
- snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev);
-
link = snd_hdac_ext_bus_get_link(bus, codec_dai->component->name);
if (!link)
return -EINVAL;
@@ -261,14 +261,11 @@ static int hda_link_pcm_prepare(struct snd_pcm_substream *substream,
{
struct hdac_ext_stream *link_dev =
snd_soc_dai_get_dma_data(dai, substream);
- struct sof_intel_hda_stream *hda_stream;
struct snd_sof_dev *sdev =
snd_soc_component_get_drvdata(dai->component);
struct snd_soc_pcm_runtime *rtd = snd_pcm_substream_chip(substream);
int stream = substream->stream;
- hda_stream = hstream_to_sof_hda_stream(link_dev);
-
if (link_dev->link_prepared)
return 0;
@@ -361,6 +358,13 @@ static int hda_link_hw_free(struct snd_pcm_substream *substream,
bus = hstream->bus;
rtd = snd_pcm_substream_chip(substream);
link_dev = snd_soc_dai_get_dma_data(dai, substream);
+
+ if (!link_dev) {
+ dev_dbg(dai->dev,
+ "%s: link_dev is not assigned\n", __func__);
+ return -EINVAL;
+ }
+
hda_stream = hstream_to_sof_hda_stream(link_dev);
/* free the link DMA channel in the FW */
@@ -440,6 +444,10 @@ struct snd_soc_dai_driver skl_dai[] = {
.ops = &hda_link_dai_ops,
},
{
+ .name = "iDisp4 Pin",
+ .ops = &hda_link_dai_ops,
+},
+{
.name = "Analog CPU DAI",
.ops = &hda_link_dai_ops,
},
diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c
index 65c2af3fcaab..356bb134ae93 100644
--- a/sound/soc/sof/intel/hda-loader.c
+++ b/sound/soc/sof/intel/hda-loader.c
@@ -278,7 +278,6 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev)
/* init for booting wait */
init_waitqueue_head(&sdev->boot_wait);
- sdev->boot_complete = false;
/* prepare DMA for code loader stream */
tag = cl_stream_prepare(sdev, 0x40, stripped_firmware.size,
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
index 06e84679087b..3c4b604412f0 100644
--- a/sound/soc/sof/intel/hda.c
+++ b/sound/soc/sof/intel/hda.c
@@ -166,7 +166,7 @@ void hda_dsp_dump_skl(struct snd_sof_dev *sdev, u32 flags)
panic = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
HDA_ADSP_ERROR_CODE_SKL + 0x4);
- if (sdev->boot_complete) {
+ if (sdev->fw_state == SOF_FW_BOOT_COMPLETE) {
hda_dsp_get_registers(sdev, &xoops, &panic_info, stack,
HDA_DSP_STACK_DUMP_SIZE);
snd_sof_get_status(sdev, status, panic, &xoops, &panic_info,
@@ -193,7 +193,7 @@ void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags)
HDA_DSP_SRAM_REG_FW_STATUS);
panic = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_SRAM_REG_FW_TRACEP);
- if (sdev->boot_complete) {
+ if (sdev->fw_state == SOF_FW_BOOT_COMPLETE) {
hda_dsp_get_registers(sdev, &xoops, &panic_info, stack,
HDA_DSP_STACK_DUMP_SIZE);
snd_sof_get_status(sdev, status, panic, &xoops, &panic_info,
@@ -268,6 +268,7 @@ static int hda_init(struct snd_sof_dev *sdev)
bus->use_posbuf = 1;
bus->bdl_pos_adj = 0;
+ bus->sync_write = 1;
mutex_init(&hbus->prepare_mutex);
hbus->pci = pci;
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index 23e430d3e056..4be53ef2eab6 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -336,7 +336,7 @@
/* Number of DAIs */
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
-#define SOF_SKL_NUM_DAIS 14
+#define SOF_SKL_NUM_DAIS 15
#else
#define SOF_SKL_NUM_DAIS 8
#endif
diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c
index 086eeeab8679..8984d965037d 100644
--- a/sound/soc/sof/ipc.c
+++ b/sound/soc/sof/ipc.c
@@ -348,19 +348,12 @@ void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev)
break;
case SOF_IPC_FW_READY:
/* check for FW boot completion */
- if (!sdev->boot_complete) {
+ if (sdev->fw_state == SOF_FW_BOOT_IN_PROGRESS) {
err = sof_ops(sdev)->fw_ready(sdev, cmd);
- if (err < 0) {
- /*
- * this indicates a mismatch in ABI
- * between the driver and fw
- */
- dev_err(sdev->dev, "error: ABI mismatch %d\n",
- err);
- } else {
- /* firmware boot completed OK */
- sdev->boot_complete = true;
- }
+ if (err < 0)
+ sdev->fw_state = SOF_FW_BOOT_READY_FAILED;
+ else
+ sdev->fw_state = SOF_FW_BOOT_COMPLETE;
/* wake up firmware loader */
wake_up(&sdev->boot_wait);
@@ -834,6 +827,9 @@ void snd_sof_ipc_free(struct snd_sof_dev *sdev)
{
struct snd_sof_ipc *ipc = sdev->ipc;
+ if (!ipc)
+ return;
+
/* disable sending of ipc's */
mutex_lock(&ipc->tx_mutex);
ipc->disable_ipc_tx = true;
diff --git a/sound/soc/sof/loader.c b/sound/soc/sof/loader.c
index abbe462d6efd..235be4fc0862 100644
--- a/sound/soc/sof/loader.c
+++ b/sound/soc/sof/loader.c
@@ -551,7 +551,6 @@ int snd_sof_run_firmware(struct snd_sof_dev *sdev)
int init_core_mask;
init_waitqueue_head(&sdev->boot_wait);
- sdev->boot_complete = false;
/* create read-only fw_version debugfs to store boot version info */
if (sdev->first_boot) {
@@ -583,19 +582,27 @@ int snd_sof_run_firmware(struct snd_sof_dev *sdev)
init_core_mask = ret;
- /* now wait for the DSP to boot */
- ret = wait_event_timeout(sdev->boot_wait, sdev->boot_complete,
+ /*
+ * now wait for the DSP to boot. There are 3 possible outcomes:
+ * 1. Boot wait times out indicating FW boot failure.
+ * 2. FW boots successfully and fw_ready op succeeds.
+ * 3. FW boots but fw_ready op fails.
+ */
+ ret = wait_event_timeout(sdev->boot_wait,
+ sdev->fw_state > SOF_FW_BOOT_IN_PROGRESS,
msecs_to_jiffies(sdev->boot_timeout));
if (ret == 0) {
dev_err(sdev->dev, "error: firmware boot failure\n");
snd_sof_dsp_dbg_dump(sdev, SOF_DBG_REGS | SOF_DBG_MBOX |
SOF_DBG_TEXT | SOF_DBG_PCI);
- /* after this point FW_READY msg should be ignored */
- sdev->boot_complete = true;
+ sdev->fw_state = SOF_FW_BOOT_FAILED;
return -EIO;
}
- dev_info(sdev->dev, "firmware boot complete\n");
+ if (sdev->fw_state == SOF_FW_BOOT_COMPLETE)
+ dev_info(sdev->dev, "firmware boot complete\n");
+ else
+ return -EIO; /* FW boots but fw_ready op failed */
/* perform post fw run operations */
ret = snd_sof_dsp_post_fw_run(sdev);
diff --git a/sound/soc/sof/pm.c b/sound/soc/sof/pm.c
index e23beaeefe00..195af259e78e 100644
--- a/sound/soc/sof/pm.c
+++ b/sound/soc/sof/pm.c
@@ -269,6 +269,10 @@ static int sof_resume(struct device *dev, bool runtime_resume)
if (!sof_ops(sdev)->resume || !sof_ops(sdev)->runtime_resume)
return 0;
+ /* DSP was never successfully started, nothing to resume */
+ if (sdev->first_boot)
+ return 0;
+
/*
* if the runtime_resume flag is set, call the runtime_resume routine
* or else call the system resume routine
@@ -283,6 +287,8 @@ static int sof_resume(struct device *dev, bool runtime_resume)
return ret;
}
+ sdev->fw_state = SOF_FW_BOOT_PREPARE;
+
/* load the firmware */
ret = snd_sof_load_firmware(sdev);
if (ret < 0) {
@@ -292,7 +298,12 @@ static int sof_resume(struct device *dev, bool runtime_resume)
return ret;
}
- /* boot the firmware */
+ sdev->fw_state = SOF_FW_BOOT_IN_PROGRESS;
+
+ /*
+ * Boot the firmware. The FW boot status will be modified
+ * in snd_sof_run_firmware() depending on the outcome.
+ */
ret = snd_sof_run_firmware(sdev);
if (ret < 0) {
dev_err(sdev->dev,
@@ -338,6 +349,9 @@ static int sof_suspend(struct device *dev, bool runtime_suspend)
if (!sof_ops(sdev)->suspend)
return 0;
+ if (sdev->fw_state != SOF_FW_BOOT_COMPLETE)
+ goto power_down;
+
/* release trace */
snd_sof_release_trace(sdev);
@@ -375,6 +389,12 @@ static int sof_suspend(struct device *dev, bool runtime_suspend)
ret);
}
+power_down:
+
+ /* return if the DSP was not probed successfully */
+ if (sdev->fw_state == SOF_FW_BOOT_NOT_STARTED)
+ return 0;
+
/* power down all DSP cores */
if (runtime_suspend)
ret = snd_sof_dsp_runtime_suspend(sdev);
@@ -385,6 +405,9 @@ static int sof_suspend(struct device *dev, bool runtime_suspend)
"error: failed to power down DSP during suspend %d\n",
ret);
+ /* reset FW state */
+ sdev->fw_state = SOF_FW_BOOT_NOT_STARTED;
+
return ret;
}
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
index e201f7aa245b..40678383de03 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -363,6 +363,15 @@ struct snd_sof_dai {
struct list_head list; /* list in sdev dai list */
};
+enum snd_sof_fw_state {
+ SOF_FW_BOOT_NOT_STARTED = 0,
+ SOF_FW_BOOT_PREPARE,
+ SOF_FW_BOOT_IN_PROGRESS,
+ SOF_FW_BOOT_FAILED,
+ SOF_FW_BOOT_READY_FAILED, /* firmware booted but fw_ready op failed */
+ SOF_FW_BOOT_COMPLETE,
+};
+
/*
* SOF Device Level.
*/
@@ -379,7 +388,7 @@ struct snd_sof_dev {
/* DSP firmware boot */
wait_queue_head_t boot_wait;
- u32 boot_complete;
+ enum snd_sof_fw_state fw_state;
u32 first_boot;
/* work queue in case the probe is implemented in two steps */
diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c
index d424413dc531..5e86072e057a 100644
--- a/sound/soc/sof/topology.c
+++ b/sound/soc/sof/topology.c
@@ -2959,6 +2959,10 @@ static int sof_link_load(struct snd_soc_component *scomp, int index,
if (!link->no_pcm) {
link->nonatomic = true;
+ /* set trigger order */
+ link->trigger[0] = SND_SOC_DPCM_TRIGGER_POST;
+ link->trigger[1] = SND_SOC_DPCM_TRIGGER_POST;
+
/* nothing more to do for FE dai links */
return 0;
}