aboutsummaryrefslogtreecommitdiff
path: root/sound/soc/sof
diff options
context:
space:
mode:
authorGravatar Mark Brown <broonie@kernel.org> 2023-11-30 11:23:17 +0000
committerGravatar Mark Brown <broonie@kernel.org> 2023-11-30 11:23:17 +0000
commitef6069f3f6577b2e5bdf223d2f6d09f23bed8c6c (patch)
tree76c3f82274d0e81e75f4e0ff96b2eb01c222ca17 /sound/soc/sof
parentASoC: qcom: Move Soundwire runtime stream alloc to soundcards (diff)
parentASoC: SOF: core: Implement IPC version fallback if firmware files are missing (diff)
downloadlinux-ef6069f3f6577b2e5bdf223d2f6d09f23bed8c6c.tar.gz
linux-ef6069f3f6577b2e5bdf223d2f6d09f23bed8c6c.tar.bz2
linux-ef6069f3f6577b2e5bdf223d2f6d09f23bed8c6c.zip
ASoC: SOF: IPC path handling and fallback support
Merge series from Peter Ujfalusi <peter.ujfalusi@linux.intel.com>: The main aim of the series is to provide a mechanism to fallback to 'older' IPC versions in case the desired one is missing either a firmware or topology file. It is going to make the life of users and distributions if we are going to start transition existing IPC3 platforms to IPC4 (CAVS2.5) and we might have missed some topology file to convert for example. In that case the kernel will fallback to IPC3 without audio regression. To be able to support this we needed to change the probe sequence to know the topology filename earlier and check if it is present in the filesystem. No functional changes for now, the default IPC versions have not been changed.
Diffstat (limited to 'sound/soc/sof')
-rw-r--r--sound/soc/sof/Kconfig11
-rw-r--r--sound/soc/sof/Makefile3
-rw-r--r--sound/soc/sof/core.c289
-rw-r--r--sound/soc/sof/fw-file-profile.c322
-rw-r--r--sound/soc/sof/intel/apl.c2
-rw-r--r--sound/soc/sof/intel/cnl.c2
-rw-r--r--sound/soc/sof/intel/hda-dai.c3
-rw-r--r--sound/soc/sof/intel/icl.c2
-rw-r--r--sound/soc/sof/intel/lnl.c2
-rw-r--r--sound/soc/sof/intel/mtl.c2
-rw-r--r--sound/soc/sof/intel/skl.c2
-rw-r--r--sound/soc/sof/intel/tgl.c2
-rw-r--r--sound/soc/sof/sof-acpi-dev.c16
-rw-r--r--sound/soc/sof/sof-audio.c120
-rw-r--r--sound/soc/sof/sof-of-dev.c36
-rw-r--r--sound/soc/sof/sof-of-dev.h9
-rw-r--r--sound/soc/sof/sof-pci-dev.c102
-rw-r--r--sound/soc/sof/sof-priv.h9
18 files changed, 656 insertions, 278 deletions
diff --git a/sound/soc/sof/Kconfig b/sound/soc/sof/Kconfig
index a741ed96e789..32ffd345e07f 100644
--- a/sound/soc/sof/Kconfig
+++ b/sound/soc/sof/Kconfig
@@ -126,6 +126,17 @@ config SND_SOC_SOF_STRICT_ABI_CHECKS
If you are not involved in SOF releases and CI development,
select "N".
+config SND_SOC_SOF_ALLOW_FALLBACK_TO_NEWER_IPC_VERSION
+ bool "SOF allow fallback to newer IPC version"
+ help
+ This option will allow the kernel to try to 'fallback' to a newer IPC
+ version if there are missing firmware files to satisfy the default IPC
+ version.
+ IPC version fallback to older versions is not affected by this option,
+ it is always available.
+ Say Y if you are involved in SOF development and need this option.
+ If not, select N.
+
config SND_SOC_SOF_DEBUG
bool "SOF debugging features"
help
diff --git a/sound/soc/sof/Makefile b/sound/soc/sof/Makefile
index ef6fd43d0b72..3624124575af 100644
--- a/sound/soc/sof/Makefile
+++ b/sound/soc/sof/Makefile
@@ -1,7 +1,8 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
snd-sof-objs := core.o ops.o loader.o ipc.o pcm.o pm.o debug.o topology.o\
- control.o trace.o iomem-utils.o sof-audio.o stream-ipc.o
+ control.o trace.o iomem-utils.o sof-audio.o stream-ipc.o\
+ fw-file-profile.o
# IPC implementations
ifneq ($(CONFIG_SND_SOC_SOF_IPC3),)
diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c
index d7b090224f1b..a2afec8f5879 100644
--- a/sound/soc/sof/core.c
+++ b/sound/soc/sof/core.c
@@ -13,6 +13,7 @@
#include <sound/soc.h>
#include <sound/sof.h>
#include "sof-priv.h"
+#include "sof-of-dev.h"
#include "ops.h"
#define CREATE_TRACE_POINTS
@@ -143,6 +144,211 @@ void sof_set_fw_state(struct snd_sof_dev *sdev, enum sof_fw_state new_state)
}
EXPORT_SYMBOL(sof_set_fw_state);
+/* SOF Driver enumeration */
+static int sof_machine_check(struct snd_sof_dev *sdev)
+{
+ struct snd_sof_pdata *sof_pdata = sdev->pdata;
+ const struct sof_dev_desc *desc = sof_pdata->desc;
+ struct snd_soc_acpi_mach *mach;
+
+ if (!IS_ENABLED(CONFIG_SND_SOC_SOF_FORCE_NOCODEC_MODE)) {
+ const struct snd_sof_of_mach *of_mach;
+
+ if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) &&
+ sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC))
+ goto nocodec;
+
+ /* find machine */
+ mach = snd_sof_machine_select(sdev);
+ if (mach) {
+ sof_pdata->machine = mach;
+
+ if (sof_pdata->subsystem_id_set) {
+ mach->mach_params.subsystem_vendor = sof_pdata->subsystem_vendor;
+ mach->mach_params.subsystem_device = sof_pdata->subsystem_device;
+ mach->mach_params.subsystem_id_set = true;
+ }
+
+ snd_sof_set_mach_params(mach, sdev);
+ return 0;
+ }
+
+ of_mach = sof_of_machine_select(sdev);
+ if (of_mach) {
+ sof_pdata->of_machine = of_mach;
+ return 0;
+ }
+
+ if (!IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC)) {
+ dev_err(sdev->dev, "error: no matching ASoC machine driver found - aborting probe\n");
+ return -ENODEV;
+ }
+ } else {
+ dev_warn(sdev->dev, "Force to use nocodec mode\n");
+ }
+
+nocodec:
+ /* select nocodec mode */
+ dev_warn(sdev->dev, "Using nocodec machine driver\n");
+ mach = devm_kzalloc(sdev->dev, sizeof(*mach), GFP_KERNEL);
+ if (!mach)
+ return -ENOMEM;
+
+ mach->drv_name = "sof-nocodec";
+ if (!sof_pdata->tplg_filename)
+ sof_pdata->tplg_filename = desc->nocodec_tplg_filename;
+
+ sof_pdata->machine = mach;
+ snd_sof_set_mach_params(mach, sdev);
+
+ return 0;
+}
+
+static int sof_select_ipc_and_paths(struct snd_sof_dev *sdev)
+{
+ struct snd_sof_pdata *plat_data = sdev->pdata;
+ struct sof_loadable_file_profile *base_profile = &plat_data->ipc_file_profile_base;
+ struct sof_loadable_file_profile out_profile;
+ struct device *dev = sdev->dev;
+ int ret;
+
+ if (base_profile->ipc_type != plat_data->desc->ipc_default)
+ dev_info(dev,
+ "Module parameter used, overriding default IPC %d to %d\n",
+ plat_data->desc->ipc_default, base_profile->ipc_type);
+
+ if (base_profile->fw_path)
+ dev_dbg(dev, "Module parameter used, changed fw path to %s\n",
+ base_profile->fw_path);
+ else if (base_profile->fw_path_postfix)
+ dev_dbg(dev, "Path postfix appended to default fw path: %s\n",
+ base_profile->fw_path_postfix);
+
+ if (base_profile->fw_lib_path)
+ dev_dbg(dev, "Module parameter used, changed fw_lib path to %s\n",
+ base_profile->fw_lib_path);
+ else if (base_profile->fw_lib_path_postfix)
+ dev_dbg(dev, "Path postfix appended to default fw_lib path: %s\n",
+ base_profile->fw_lib_path_postfix);
+
+ if (base_profile->fw_name)
+ dev_dbg(dev, "Module parameter used, changed fw filename to %s\n",
+ base_profile->fw_name);
+
+ if (base_profile->tplg_path)
+ dev_dbg(dev, "Module parameter used, changed tplg path to %s\n",
+ base_profile->tplg_path);
+
+ if (base_profile->tplg_name)
+ dev_dbg(dev, "Module parameter used, changed tplg name to %s\n",
+ base_profile->tplg_name);
+
+ ret = sof_create_ipc_file_profile(sdev, base_profile, &out_profile);
+ if (ret)
+ return ret;
+
+ plat_data->ipc_type = out_profile.ipc_type;
+ plat_data->fw_filename = out_profile.fw_name;
+ plat_data->fw_filename_prefix = out_profile.fw_path;
+ plat_data->fw_lib_prefix = out_profile.fw_lib_path;
+ plat_data->tplg_filename_prefix = out_profile.tplg_path;
+
+ return 0;
+}
+
+static int validate_sof_ops(struct snd_sof_dev *sdev)
+{
+ int ret;
+
+ /* init ops, if necessary */
+ ret = sof_ops_init(sdev);
+ if (ret < 0)
+ return ret;
+
+ /* check all mandatory ops */
+ if (!sof_ops(sdev) || !sof_ops(sdev)->probe) {
+ dev_err(sdev->dev, "missing mandatory ops\n");
+ sof_ops_free(sdev);
+ return -EINVAL;
+ }
+
+ if (!sdev->dspless_mode_selected &&
+ (!sof_ops(sdev)->run || !sof_ops(sdev)->block_read ||
+ !sof_ops(sdev)->block_write || !sof_ops(sdev)->send_msg ||
+ !sof_ops(sdev)->load_firmware || !sof_ops(sdev)->ipc_msg_data)) {
+ dev_err(sdev->dev, "missing mandatory DSP ops\n");
+ sof_ops_free(sdev);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int sof_init_sof_ops(struct snd_sof_dev *sdev)
+{
+ struct snd_sof_pdata *plat_data = sdev->pdata;
+ struct sof_loadable_file_profile *base_profile = &plat_data->ipc_file_profile_base;
+
+ /* check IPC support */
+ if (!(BIT(base_profile->ipc_type) & plat_data->desc->ipc_supported_mask)) {
+ dev_err(sdev->dev,
+ "ipc_type %d is not supported on this platform, mask is %#x\n",
+ base_profile->ipc_type, plat_data->desc->ipc_supported_mask);
+ return -EINVAL;
+ }
+
+ /*
+ * Save the selected IPC type and a topology name override before
+ * selecting ops since platform code might need this information
+ */
+ plat_data->ipc_type = base_profile->ipc_type;
+ plat_data->tplg_filename = base_profile->tplg_name;
+
+ return validate_sof_ops(sdev);
+}
+
+static int sof_init_environment(struct snd_sof_dev *sdev)
+{
+ struct snd_sof_pdata *plat_data = sdev->pdata;
+ struct sof_loadable_file_profile *base_profile = &plat_data->ipc_file_profile_base;
+ int ret;
+
+ /* probe the DSP hardware */
+ ret = snd_sof_probe(sdev);
+ if (ret < 0) {
+ dev_err(sdev->dev, "failed to probe DSP %d\n", ret);
+ sof_ops_free(sdev);
+ return ret;
+ }
+
+ /* check machine info */
+ ret = sof_machine_check(sdev);
+ if (ret < 0) {
+ dev_err(sdev->dev, "failed to get machine info %d\n", ret);
+ goto err_machine_check;
+ }
+
+ ret = sof_select_ipc_and_paths(sdev);
+ if (!ret && plat_data->ipc_type != base_profile->ipc_type) {
+ /* IPC type changed, re-initialize the ops */
+ sof_ops_free(sdev);
+
+ ret = validate_sof_ops(sdev);
+ if (ret < 0) {
+ snd_sof_remove(sdev);
+ return ret;
+ }
+ }
+
+err_machine_check:
+ if (ret) {
+ snd_sof_remove(sdev);
+ sof_ops_free(sdev);
+ }
+
+ return ret;
+}
+
/*
* FW Boot State Transition Diagram
*
@@ -188,23 +394,13 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
struct snd_sof_pdata *plat_data = sdev->pdata;
int ret;
- /* probe the DSP hardware */
- ret = snd_sof_probe(sdev);
- if (ret < 0) {
- dev_err(sdev->dev, "error: failed to probe DSP %d\n", ret);
- goto probe_err;
- }
+ /* Initialize loadable file paths and check the environment validity */
+ ret = sof_init_environment(sdev);
+ if (ret)
+ return ret;
sof_set_fw_state(sdev, SOF_FW_BOOT_PREPARE);
- /* check machine info */
- ret = sof_machine_check(sdev);
- if (ret < 0) {
- dev_err(sdev->dev, "error: failed to get machine info %d\n",
- ret);
- goto dsp_err;
- }
-
/* set up platform component driver */
snd_sof_new_platform_drv(sdev);
@@ -324,9 +520,7 @@ fw_load_err:
ipc_err:
dbg_err:
snd_sof_free_debug(sdev);
-dsp_err:
snd_sof_remove(sdev);
-probe_err:
snd_sof_remove_late(sdev);
sof_ops_free(sdev);
@@ -381,34 +575,11 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data)
}
}
- /* check IPC support */
- if (!(BIT(plat_data->ipc_type) & plat_data->desc->ipc_supported_mask)) {
- dev_err(dev, "ipc_type %d is not supported on this platform, mask is %#x\n",
- plat_data->ipc_type, plat_data->desc->ipc_supported_mask);
- return -EINVAL;
- }
-
- /* init ops, if necessary */
- ret = sof_ops_init(sdev);
- if (ret < 0)
+ /* Initialize sof_ops based on the initial selected IPC version */
+ ret = sof_init_sof_ops(sdev);
+ if (ret)
return ret;
- /* check all mandatory ops */
- if (!sof_ops(sdev) || !sof_ops(sdev)->probe) {
- sof_ops_free(sdev);
- dev_err(dev, "missing mandatory ops\n");
- return -EINVAL;
- }
-
- if (!sdev->dspless_mode_selected &&
- (!sof_ops(sdev)->run || !sof_ops(sdev)->block_read ||
- !sof_ops(sdev)->block_write || !sof_ops(sdev)->send_msg ||
- !sof_ops(sdev)->load_firmware || !sof_ops(sdev)->ipc_msg_data)) {
- sof_ops_free(sdev);
- dev_err(dev, "missing mandatory DSP ops\n");
- return -EINVAL;
- }
-
INIT_LIST_HEAD(&sdev->pcm_list);
INIT_LIST_HEAD(&sdev->kcontrol_list);
INIT_LIST_HEAD(&sdev->widget_list);
@@ -527,6 +698,40 @@ int snd_sof_device_shutdown(struct device *dev)
}
EXPORT_SYMBOL(snd_sof_device_shutdown);
+/* Machine driver registering and unregistering */
+int sof_machine_register(struct snd_sof_dev *sdev, void *pdata)
+{
+ struct snd_sof_pdata *plat_data = pdata;
+ const char *drv_name;
+ const void *mach;
+ int size;
+
+ drv_name = plat_data->machine->drv_name;
+ mach = plat_data->machine;
+ size = sizeof(*plat_data->machine);
+
+ /* register machine driver, pass machine info as pdata */
+ plat_data->pdev_mach =
+ platform_device_register_data(sdev->dev, drv_name,
+ PLATFORM_DEVID_NONE, mach, size);
+ if (IS_ERR(plat_data->pdev_mach))
+ return PTR_ERR(plat_data->pdev_mach);
+
+ dev_dbg(sdev->dev, "created machine %s\n",
+ dev_name(&plat_data->pdev_mach->dev));
+
+ return 0;
+}
+EXPORT_SYMBOL(sof_machine_register);
+
+void sof_machine_unregister(struct snd_sof_dev *sdev, void *pdata)
+{
+ struct snd_sof_pdata *plat_data = pdata;
+
+ platform_device_unregister(plat_data->pdev_mach);
+}
+EXPORT_SYMBOL(sof_machine_unregister);
+
MODULE_AUTHOR("Liam Girdwood");
MODULE_DESCRIPTION("Sound Open Firmware (SOF) Core");
MODULE_LICENSE("Dual BSD/GPL");
diff --git a/sound/soc/sof/fw-file-profile.c b/sound/soc/sof/fw-file-profile.c
new file mode 100644
index 000000000000..138a1ca2c4a8
--- /dev/null
+++ b/sound/soc/sof/fw-file-profile.c
@@ -0,0 +1,322 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// This file is provided under a dual BSD/GPLv2 license. When using or
+// redistributing this file, you may do so under either license.
+//
+// Copyright(c) 2023 Intel Corporation. All rights reserved.
+//
+
+#include <linux/firmware.h>
+#include <sound/sof.h>
+#include <sound/sof/ext_manifest4.h>
+#include "sof-priv.h"
+
+static int sof_test_firmware_file(struct device *dev,
+ struct sof_loadable_file_profile *profile,
+ enum sof_ipc_type *ipc_type_to_adjust)
+{
+ enum sof_ipc_type fw_ipc_type;
+ const struct firmware *fw;
+ const char *fw_filename;
+ const u32 *magic;
+ int ret;
+
+ fw_filename = kasprintf(GFP_KERNEL, "%s/%s", profile->fw_path,
+ profile->fw_name);
+ if (!fw_filename)
+ return -ENOMEM;
+
+ ret = firmware_request_nowarn(&fw, fw_filename, dev);
+ if (ret < 0) {
+ dev_dbg(dev, "Failed to open firmware file: %s\n", fw_filename);
+ kfree(fw_filename);
+ return ret;
+ }
+
+ /* firmware file exists, check the magic number */
+ magic = (const u32 *)fw->data;
+ switch (*magic) {
+ case SOF_EXT_MAN_MAGIC_NUMBER:
+ fw_ipc_type = SOF_IPC_TYPE_3;
+ break;
+ case SOF_EXT_MAN4_MAGIC_NUMBER:
+ fw_ipc_type = SOF_IPC_TYPE_4;
+ break;
+ default:
+ dev_err(dev, "Invalid firmware magic: %#x\n", *magic);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (ipc_type_to_adjust) {
+ *ipc_type_to_adjust = fw_ipc_type;
+ } else if (fw_ipc_type != profile->ipc_type) {
+ dev_err(dev,
+ "ipc type mismatch between %s and expected: %d vs %d\n",
+ fw_filename, fw_ipc_type, profile->ipc_type);
+ ret = -EINVAL;
+ }
+out:
+ release_firmware(fw);
+ kfree(fw_filename);
+
+ return ret;
+}
+
+static int sof_test_topology_file(struct device *dev,
+ struct sof_loadable_file_profile *profile)
+{
+ const struct firmware *fw;
+ const char *tplg_filename;
+ int ret;
+
+ if (!profile->tplg_path || !profile->tplg_name)
+ return 0;
+
+ tplg_filename = kasprintf(GFP_KERNEL, "%s/%s", profile->tplg_path,
+ profile->tplg_name);
+ if (!tplg_filename)
+ return -ENOMEM;
+
+ ret = firmware_request_nowarn(&fw, tplg_filename, dev);
+ if (!ret)
+ release_firmware(fw);
+ else
+ dev_dbg(dev, "Failed to open topology file: %s\n", tplg_filename);
+
+ kfree(tplg_filename);
+
+ return ret;
+}
+
+static int
+sof_file_profile_for_ipc_type(struct snd_sof_dev *sdev,
+ enum sof_ipc_type ipc_type,
+ const struct sof_dev_desc *desc,
+ struct sof_loadable_file_profile *base_profile,
+ struct sof_loadable_file_profile *out_profile)
+{
+ struct snd_sof_pdata *plat_data = sdev->pdata;
+ bool fw_lib_path_allocated = false;
+ struct device *dev = sdev->dev;
+ bool fw_path_allocated = false;
+ int ret = 0;
+
+ /* firmware path */
+ if (base_profile->fw_path) {
+ out_profile->fw_path = base_profile->fw_path;
+ } else if (base_profile->fw_path_postfix) {
+ out_profile->fw_path = devm_kasprintf(dev, GFP_KERNEL, "%s/%s",
+ desc->default_fw_path[ipc_type],
+ base_profile->fw_path_postfix);
+ if (!out_profile->fw_path)
+ return -ENOMEM;
+
+ fw_path_allocated = true;
+ } else {
+ out_profile->fw_path = desc->default_fw_path[ipc_type];
+ }
+
+ /* firmware filename */
+ if (base_profile->fw_name)
+ out_profile->fw_name = base_profile->fw_name;
+ else
+ out_profile->fw_name = desc->default_fw_filename[ipc_type];
+
+ /*
+ * Check the custom firmware path/filename and adjust the ipc_type to
+ * match with the existing file for the remaining path configuration.
+ *
+ * For default path and firmware name do a verification before
+ * continuing further.
+ */
+ if (base_profile->fw_path || base_profile->fw_name) {
+ ret = sof_test_firmware_file(dev, out_profile, &ipc_type);
+ if (ret)
+ return ret;
+
+ if (!(desc->ipc_supported_mask & BIT(ipc_type))) {
+ dev_err(dev, "Unsupported IPC type %d needed by %s/%s\n",
+ ipc_type, out_profile->fw_path,
+ out_profile->fw_name);
+ return -EINVAL;
+ }
+ }
+
+ /* firmware library path */
+ if (base_profile->fw_lib_path) {
+ out_profile->fw_lib_path = base_profile->fw_lib_path;
+ } else if (desc->default_lib_path[ipc_type]) {
+ if (base_profile->fw_lib_path_postfix) {
+ out_profile->fw_lib_path = devm_kasprintf(dev,
+ GFP_KERNEL, "%s/%s",
+ desc->default_lib_path[ipc_type],
+ base_profile->fw_lib_path_postfix);
+ if (!out_profile->fw_lib_path) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ fw_lib_path_allocated = true;
+ } else {
+ out_profile->fw_lib_path = desc->default_lib_path[ipc_type];
+ }
+ }
+
+ if (base_profile->fw_path_postfix)
+ out_profile->fw_path_postfix = base_profile->fw_path_postfix;
+
+ if (base_profile->fw_lib_path_postfix)
+ out_profile->fw_lib_path_postfix = base_profile->fw_lib_path_postfix;
+
+ /* topology path */
+ if (base_profile->tplg_path)
+ out_profile->tplg_path = base_profile->tplg_path;
+ else
+ out_profile->tplg_path = desc->default_tplg_path[ipc_type];
+
+ /* topology name */
+ out_profile->tplg_name = plat_data->tplg_filename;
+
+ out_profile->ipc_type = ipc_type;
+
+ /* Test only default firmware file */
+ if (!base_profile->fw_path && !base_profile->fw_name)
+ ret = sof_test_firmware_file(dev, out_profile, NULL);
+
+ if (!ret)
+ ret = sof_test_topology_file(dev, out_profile);
+
+out:
+ if (ret) {
+ /* Free up path strings created with devm_kasprintf */
+ if (fw_path_allocated)
+ devm_kfree(dev, out_profile->fw_path);
+ if (fw_lib_path_allocated)
+ devm_kfree(dev, out_profile->fw_lib_path);
+
+ memset(out_profile, 0, sizeof(*out_profile));
+ }
+
+ return ret;
+}
+
+static void
+sof_print_missing_firmware_info(struct snd_sof_dev *sdev,
+ enum sof_ipc_type ipc_type,
+ struct sof_loadable_file_profile *base_profile)
+{
+ struct snd_sof_pdata *plat_data = sdev->pdata;
+ const struct sof_dev_desc *desc = plat_data->desc;
+ struct device *dev = sdev->dev;
+ int ipc_type_count, i;
+ char *marker;
+
+ dev_err(dev, "SOF firmware and/or topology file not found.\n");
+ dev_info(dev, "Supported default profiles\n");
+
+ if (IS_ENABLED(CONFIG_SND_SOC_SOF_ALLOW_FALLBACK_TO_NEWER_IPC_VERSION))
+ ipc_type_count = SOF_IPC_TYPE_COUNT - 1;
+ else
+ ipc_type_count = base_profile->ipc_type;
+
+ for (i = 0; i <= ipc_type_count; i++) {
+ if (!(desc->ipc_supported_mask & BIT(i)))
+ continue;
+
+ if (i == ipc_type)
+ marker = "Requested";
+ else
+ marker = "Fallback";
+
+ dev_info(dev, "- ipc type %d (%s):\n", i, marker);
+ if (base_profile->fw_path_postfix)
+ dev_info(dev, " Firmware file: %s/%s/%s\n",
+ desc->default_fw_path[i],
+ base_profile->fw_path_postfix,
+ desc->default_fw_filename[i]);
+ else
+ dev_info(dev, " Firmware file: %s/%s\n",
+ desc->default_fw_path[i],
+ desc->default_fw_filename[i]);
+
+ dev_info(dev, " Topology file: %s/%s\n",
+ desc->default_tplg_path[i],
+ plat_data->tplg_filename);
+ }
+
+ if (base_profile->fw_path || base_profile->fw_name ||
+ base_profile->tplg_path || base_profile->tplg_name)
+ dev_info(dev, "Verify the path/name override module parameters.\n");
+
+ dev_info(dev, "Check if you have 'sof-firmware' package installed.\n");
+ dev_info(dev, "Optionally it can be manually downloaded from:\n");
+ dev_info(dev, " https://github.com/thesofproject/sof-bin/\n");
+}
+
+static void sof_print_profile_info(struct snd_sof_dev *sdev,
+ enum sof_ipc_type ipc_type,
+ struct sof_loadable_file_profile *profile)
+{
+ struct device *dev = sdev->dev;
+
+ if (ipc_type != profile->ipc_type)
+ dev_info(dev,
+ "Using fallback IPC type %d (requested type was %d)\n",
+ profile->ipc_type, ipc_type);
+
+ dev_info(dev, "Firmware paths/files for ipc type %d:\n", profile->ipc_type);
+
+ dev_info(dev, " Firmware file: %s/%s\n", profile->fw_path, profile->fw_name);
+ if (profile->fw_lib_path)
+ dev_info(dev, " Firmware lib path: %s\n", profile->fw_lib_path);
+ dev_info(dev, " Topology file: %s/%s\n", profile->tplg_path, profile->tplg_name);
+}
+
+int sof_create_ipc_file_profile(struct snd_sof_dev *sdev,
+ struct sof_loadable_file_profile *base_profile,
+ struct sof_loadable_file_profile *out_profile)
+{
+ const struct sof_dev_desc *desc = sdev->pdata->desc;
+ int ipc_fallback_start, ret, i;
+
+ memset(out_profile, 0, sizeof(*out_profile));
+
+ ret = sof_file_profile_for_ipc_type(sdev, base_profile->ipc_type, desc,
+ base_profile, out_profile);
+ if (!ret)
+ goto out;
+
+ /*
+ * No firmware file was found for the requested IPC type, as fallback
+ * if SND_SOC_SOF_ALLOW_FALLBACK_TO_NEWER_IPC_VERSION is selected, check
+ * all IPC versions in a backwards direction (from newer to older)
+ * if SND_SOC_SOF_ALLOW_FALLBACK_TO_NEWER_IPC_VERSION is not selected,
+ * check only older IPC versions than the selected/default version
+ */
+ if (IS_ENABLED(CONFIG_SND_SOC_SOF_ALLOW_FALLBACK_TO_NEWER_IPC_VERSION))
+ ipc_fallback_start = SOF_IPC_TYPE_COUNT - 1;
+ else
+ ipc_fallback_start = (int)base_profile->ipc_type - 1;
+
+ for (i = ipc_fallback_start; i >= 0 ; i--) {
+ if (i == base_profile->ipc_type ||
+ !(desc->ipc_supported_mask & BIT(i)))
+ continue;
+
+ ret = sof_file_profile_for_ipc_type(sdev, i, desc, base_profile,
+ out_profile);
+ if (!ret)
+ break;
+ }
+
+out:
+ if (ret)
+ sof_print_missing_firmware_info(sdev, base_profile->ipc_type,
+ base_profile);
+ else
+ sof_print_profile_info(sdev, base_profile->ipc_type, out_profile);
+
+ return ret;
+}
+EXPORT_SYMBOL(sof_create_ipc_file_profile);
diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c
index 776b66389c34..dee6c7f73e80 100644
--- a/sound/soc/sof/intel/apl.c
+++ b/sound/soc/sof/intel/apl.c
@@ -55,7 +55,7 @@ int sof_apl_ops_init(struct snd_sof_dev *sdev)
if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) {
struct sof_ipc4_fw_data *ipc4_data;
- sdev->private = devm_kzalloc(sdev->dev, sizeof(*ipc4_data), GFP_KERNEL);
+ sdev->private = kzalloc(sizeof(*ipc4_data), GFP_KERNEL);
if (!sdev->private)
return -ENOMEM;
diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c
index 598cf50abadb..85e1e4760d0e 100644
--- a/sound/soc/sof/intel/cnl.c
+++ b/sound/soc/sof/intel/cnl.c
@@ -402,7 +402,7 @@ int sof_cnl_ops_init(struct snd_sof_dev *sdev)
if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) {
struct sof_ipc4_fw_data *ipc4_data;
- sdev->private = devm_kzalloc(sdev->dev, sizeof(*ipc4_data), GFP_KERNEL);
+ sdev->private = kzalloc(sizeof(*ipc4_data), GFP_KERNEL);
if (!sdev->private)
return -ENOMEM;
diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c
index a20deaf3b428..f4cbc0ad5de3 100644
--- a/sound/soc/sof/intel/hda-dai.c
+++ b/sound/soc/sof/intel/hda-dai.c
@@ -621,6 +621,9 @@ void hda_ops_free(struct snd_sof_dev *sdev)
if (!hda_use_tplg_nhlt)
intel_nhlt_free(ipc4_data->nhlt);
+
+ kfree(sdev->private);
+ sdev->private = NULL;
}
}
EXPORT_SYMBOL_NS(hda_ops_free, SND_SOC_SOF_INTEL_HDA_COMMON);
diff --git a/sound/soc/sof/intel/icl.c b/sound/soc/sof/intel/icl.c
index 8e29d6bb6fe8..040698591992 100644
--- a/sound/soc/sof/intel/icl.c
+++ b/sound/soc/sof/intel/icl.c
@@ -123,7 +123,7 @@ int sof_icl_ops_init(struct snd_sof_dev *sdev)
if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) {
struct sof_ipc4_fw_data *ipc4_data;
- sdev->private = devm_kzalloc(sdev->dev, sizeof(*ipc4_data), GFP_KERNEL);
+ sdev->private = kzalloc(sizeof(*ipc4_data), GFP_KERNEL);
if (!sdev->private)
return -ENOMEM;
diff --git a/sound/soc/sof/intel/lnl.c b/sound/soc/sof/intel/lnl.c
index db94b45e53af..03308721ebd4 100644
--- a/sound/soc/sof/intel/lnl.c
+++ b/sound/soc/sof/intel/lnl.c
@@ -120,7 +120,7 @@ int sof_lnl_ops_init(struct snd_sof_dev *sdev)
sof_lnl_ops.get_stream_position = mtl_dsp_get_stream_hda_link_position;
- sdev->private = devm_kzalloc(sdev->dev, sizeof(struct sof_ipc4_fw_data), GFP_KERNEL);
+ sdev->private = kzalloc(sizeof(struct sof_ipc4_fw_data), GFP_KERNEL);
if (!sdev->private)
return -ENOMEM;
diff --git a/sound/soc/sof/intel/mtl.c b/sound/soc/sof/intel/mtl.c
index 3ef9e5c37028..f941e2c49d78 100644
--- a/sound/soc/sof/intel/mtl.c
+++ b/sound/soc/sof/intel/mtl.c
@@ -709,7 +709,7 @@ int sof_mtl_ops_init(struct snd_sof_dev *sdev)
sof_mtl_ops.get_stream_position = mtl_dsp_get_stream_hda_link_position;
- sdev->private = devm_kzalloc(sdev->dev, sizeof(struct sof_ipc4_fw_data), GFP_KERNEL);
+ sdev->private = kzalloc(sizeof(struct sof_ipc4_fw_data), GFP_KERNEL);
if (!sdev->private)
return -ENOMEM;
diff --git a/sound/soc/sof/intel/skl.c b/sound/soc/sof/intel/skl.c
index d24e64e71b58..93824e6ce573 100644
--- a/sound/soc/sof/intel/skl.c
+++ b/sound/soc/sof/intel/skl.c
@@ -62,7 +62,7 @@ int sof_skl_ops_init(struct snd_sof_dev *sdev)
/* probe/remove/shutdown */
sof_skl_ops.shutdown = hda_dsp_shutdown;
- sdev->private = devm_kzalloc(sdev->dev, sizeof(*ipc4_data), GFP_KERNEL);
+ sdev->private = kzalloc(sizeof(*ipc4_data), GFP_KERNEL);
if (!sdev->private)
return -ENOMEM;
diff --git a/sound/soc/sof/intel/tgl.c b/sound/soc/sof/intel/tgl.c
index f7de1f5ba06d..d890cac6cb01 100644
--- a/sound/soc/sof/intel/tgl.c
+++ b/sound/soc/sof/intel/tgl.c
@@ -82,7 +82,7 @@ int sof_tgl_ops_init(struct snd_sof_dev *sdev)
if (sdev->pdata->ipc_type == SOF_IPC_TYPE_4) {
struct sof_ipc4_fw_data *ipc4_data;
- sdev->private = devm_kzalloc(sdev->dev, sizeof(*ipc4_data), GFP_KERNEL);
+ sdev->private = kzalloc(sizeof(*ipc4_data), GFP_KERNEL);
if (!sdev->private)
return -ENOMEM;
diff --git a/sound/soc/sof/sof-acpi-dev.c b/sound/soc/sof/sof-acpi-dev.c
index 84a4a0a3318e..2977f0a63fba 100644
--- a/sound/soc/sof/sof-acpi-dev.c
+++ b/sound/soc/sof/sof-acpi-dev.c
@@ -74,18 +74,10 @@ int sof_acpi_probe(struct platform_device *pdev, const struct sof_dev_desc *desc
sof_pdata->desc = desc;
sof_pdata->dev = &pdev->dev;
- sof_pdata->fw_filename = desc->default_fw_filename[SOF_IPC_TYPE_3];
-
- /* alternate fw and tplg filenames ? */
- if (fw_path)
- sof_pdata->fw_filename_prefix = fw_path;
- else
- sof_pdata->fw_filename_prefix = desc->default_fw_path[SOF_IPC_TYPE_3];
-
- if (tplg_path)
- sof_pdata->tplg_filename_prefix = tplg_path;
- else
- sof_pdata->tplg_filename_prefix = desc->default_tplg_path[SOF_IPC_TYPE_3];
+
+ sof_pdata->ipc_file_profile_base.ipc_type = desc->ipc_default;
+ sof_pdata->ipc_file_profile_base.fw_path = fw_path;
+ sof_pdata->ipc_file_profile_base.tplg_path = tplg_path;
/* set callback to be called on successful device probe to enable runtime_pm */
sof_pdata->sof_probe_complete = sof_acpi_probe_complete;
diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c
index 563fe6f7789f..de40a5e227f4 100644
--- a/sound/soc/sof/sof-audio.c
+++ b/sound/soc/sof/sof-audio.c
@@ -11,7 +11,6 @@
#include <linux/bitfield.h>
#include <trace/events/sof.h>
#include "sof-audio.h"
-#include "sof-of-dev.h"
#include "ops.h"
static bool is_virtual_widget(struct snd_sof_dev *sdev, struct snd_soc_dapm_widget *widget,
@@ -989,122 +988,3 @@ int sof_dai_get_bclk(struct snd_soc_pcm_runtime *rtd)
return sof_dai_get_clk(rtd, SOF_DAI_CLK_INTEL_SSP_BCLK);
}
EXPORT_SYMBOL(sof_dai_get_bclk);
-
-static struct snd_sof_of_mach *sof_of_machine_select(struct snd_sof_dev *sdev)
-{
- struct snd_sof_pdata *sof_pdata = sdev->pdata;
- const struct sof_dev_desc *desc = sof_pdata->desc;
- struct snd_sof_of_mach *mach = desc->of_machines;
-
- if (!mach)
- return NULL;
-
- for (; mach->compatible; mach++) {
- if (of_machine_is_compatible(mach->compatible)) {
- sof_pdata->tplg_filename = mach->sof_tplg_filename;
- if (mach->fw_filename)
- sof_pdata->fw_filename = mach->fw_filename;
-
- return mach;
- }
- }
-
- return NULL;
-}
-
-/*
- * SOF Driver enumeration.
- */
-int sof_machine_check(struct snd_sof_dev *sdev)
-{
- struct snd_sof_pdata *sof_pdata = sdev->pdata;
- const struct sof_dev_desc *desc = sof_pdata->desc;
- struct snd_soc_acpi_mach *mach;
-
- if (!IS_ENABLED(CONFIG_SND_SOC_SOF_FORCE_NOCODEC_MODE)) {
- const struct snd_sof_of_mach *of_mach;
-
- if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) &&
- sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC))
- goto nocodec;
-
- /* find machine */
- mach = snd_sof_machine_select(sdev);
- if (mach) {
- sof_pdata->machine = mach;
-
- if (sof_pdata->subsystem_id_set) {
- mach->mach_params.subsystem_vendor = sof_pdata->subsystem_vendor;
- mach->mach_params.subsystem_device = sof_pdata->subsystem_device;
- mach->mach_params.subsystem_id_set = true;
- }
-
- snd_sof_set_mach_params(mach, sdev);
- return 0;
- }
-
- of_mach = sof_of_machine_select(sdev);
- if (of_mach) {
- sof_pdata->of_machine = of_mach;
- return 0;
- }
-
- if (!IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC)) {
- dev_err(sdev->dev, "error: no matching ASoC machine driver found - aborting probe\n");
- return -ENODEV;
- }
- } else {
- dev_warn(sdev->dev, "Force to use nocodec mode\n");
- }
-
-nocodec:
- /* select nocodec mode */
- dev_warn(sdev->dev, "Using nocodec machine driver\n");
- mach = devm_kzalloc(sdev->dev, sizeof(*mach), GFP_KERNEL);
- if (!mach)
- return -ENOMEM;
-
- mach->drv_name = "sof-nocodec";
- if (!sof_pdata->tplg_filename)
- sof_pdata->tplg_filename = desc->nocodec_tplg_filename;
-
- sof_pdata->machine = mach;
- snd_sof_set_mach_params(mach, sdev);
-
- return 0;
-}
-EXPORT_SYMBOL(sof_machine_check);
-
-int sof_machine_register(struct snd_sof_dev *sdev, void *pdata)
-{
- struct snd_sof_pdata *plat_data = pdata;
- const char *drv_name;
- const void *mach;
- int size;
-
- drv_name = plat_data->machine->drv_name;
- mach = plat_data->machine;
- size = sizeof(*plat_data->machine);
-
- /* register machine driver, pass machine info as pdata */
- plat_data->pdev_mach =
- platform_device_register_data(sdev->dev, drv_name,
- PLATFORM_DEVID_NONE, mach, size);
- if (IS_ERR(plat_data->pdev_mach))
- return PTR_ERR(plat_data->pdev_mach);
-
- dev_dbg(sdev->dev, "created machine %s\n",
- dev_name(&plat_data->pdev_mach->dev));
-
- return 0;
-}
-EXPORT_SYMBOL(sof_machine_register);
-
-void sof_machine_unregister(struct snd_sof_dev *sdev, void *pdata)
-{
- struct snd_sof_pdata *plat_data = pdata;
-
- if (!IS_ERR_OR_NULL(plat_data->pdev_mach))
- platform_device_unregister(plat_data->pdev_mach);
-}
-EXPORT_SYMBOL(sof_machine_unregister);
diff --git a/sound/soc/sof/sof-of-dev.c b/sound/soc/sof/sof-of-dev.c
index c6be8a91e74b..fa92da5ee9b3 100644
--- a/sound/soc/sof/sof-of-dev.c
+++ b/sound/soc/sof/sof-of-dev.c
@@ -41,6 +41,29 @@ static void sof_of_probe_complete(struct device *dev)
pm_runtime_enable(dev);
}
+struct snd_sof_of_mach *sof_of_machine_select(struct snd_sof_dev *sdev)
+{
+ struct snd_sof_pdata *sof_pdata = sdev->pdata;
+ const struct sof_dev_desc *desc = sof_pdata->desc;
+ struct snd_sof_of_mach *mach = desc->of_machines;
+
+ if (!mach)
+ return NULL;
+
+ for (; mach->compatible; mach++) {
+ if (of_machine_is_compatible(mach->compatible)) {
+ sof_pdata->tplg_filename = mach->sof_tplg_filename;
+ if (mach->fw_filename)
+ sof_pdata->fw_filename = mach->fw_filename;
+
+ return mach;
+ }
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL(sof_of_machine_select);
+
int sof_of_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
@@ -64,17 +87,10 @@ int sof_of_probe(struct platform_device *pdev)
sof_pdata->desc = desc;
sof_pdata->dev = &pdev->dev;
- sof_pdata->fw_filename = desc->default_fw_filename[SOF_IPC_TYPE_3];
-
- if (fw_path)
- sof_pdata->fw_filename_prefix = fw_path;
- else
- sof_pdata->fw_filename_prefix = desc->default_fw_path[SOF_IPC_TYPE_3];
- if (tplg_path)
- sof_pdata->tplg_filename_prefix = tplg_path;
- else
- sof_pdata->tplg_filename_prefix = desc->default_tplg_path[SOF_IPC_TYPE_3];
+ sof_pdata->ipc_file_profile_base.ipc_type = desc->ipc_default;
+ sof_pdata->ipc_file_profile_base.fw_path = fw_path;
+ sof_pdata->ipc_file_profile_base.tplg_path = tplg_path;
/* set callback to be called on successful device probe to enable runtime_pm */
sof_pdata->sof_probe_complete = sof_of_probe_complete;
diff --git a/sound/soc/sof/sof-of-dev.h b/sound/soc/sof/sof-of-dev.h
index b6cc70595f3b..547e358a37e3 100644
--- a/sound/soc/sof/sof-of-dev.h
+++ b/sound/soc/sof/sof-of-dev.h
@@ -16,6 +16,15 @@ struct snd_sof_of_mach {
const char *sof_tplg_filename;
};
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_OF_DEV)
+struct snd_sof_of_mach *sof_of_machine_select(struct snd_sof_dev *sdev);
+#else
+static inline struct snd_sof_of_mach *sof_of_machine_select(struct snd_sof_dev *sdev)
+{
+ return NULL;
+}
+#endif
+
extern const struct dev_pm_ops sof_of_pm;
int sof_of_probe(struct platform_device *pdev);
diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c
index 64b326e3ef85..aab5c900cecf 100644
--- a/sound/soc/sof/sof-pci-dev.c
+++ b/sound/soc/sof/sof-pci-dev.c
@@ -190,6 +190,7 @@ static void sof_pci_probe_complete(struct device *dev)
int sof_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
{
+ struct sof_loadable_file_profile *path_override;
struct device *dev = &pci->dev;
const struct sof_dev_desc *desc =
(const struct sof_dev_desc *)pci_id->driver_data;
@@ -232,106 +233,39 @@ int sof_pci_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
sof_pdata->desc = desc;
sof_pdata->dev = dev;
- sof_pdata->ipc_type = desc->ipc_default;
+ path_override = &sof_pdata->ipc_file_profile_base;
if (sof_pci_ipc_type < 0) {
- sof_pdata->ipc_type = desc->ipc_default;
+ path_override->ipc_type = desc->ipc_default;
+ } else if (sof_pci_ipc_type < SOF_IPC_TYPE_COUNT) {
+ path_override->ipc_type = sof_pci_ipc_type;
} else {
- dev_info(dev, "overriding default IPC %d to requested %d\n",
- desc->ipc_default, sof_pci_ipc_type);
- if (sof_pci_ipc_type >= SOF_IPC_TYPE_COUNT) {
- dev_err(dev, "invalid request value %d\n", sof_pci_ipc_type);
- ret = -EINVAL;
- goto out;
- }
- if (!(BIT(sof_pci_ipc_type) & desc->ipc_supported_mask)) {
- dev_err(dev, "invalid request value %d, supported mask is %#x\n",
- sof_pci_ipc_type, desc->ipc_supported_mask);
- ret = -EINVAL;
- goto out;
- }
- sof_pdata->ipc_type = sof_pci_ipc_type;
+ dev_err(dev, "Invalid IPC type requested: %d\n", sof_pci_ipc_type);
+ ret = -EINVAL;
+ goto out;
}
- if (fw_filename) {
- sof_pdata->fw_filename = fw_filename;
+ path_override->fw_path = fw_path;
+ path_override->fw_name = fw_filename;
+ path_override->fw_lib_path = lib_path;
+ path_override->tplg_path = tplg_path;
- dev_dbg(dev, "Module parameter used, changed fw filename to %s\n",
- sof_pdata->fw_filename);
- } else {
- sof_pdata->fw_filename = desc->default_fw_filename[sof_pdata->ipc_type];
+ if (dmi_check_system(community_key_platforms) &&
+ sof_dmi_use_community_key) {
+ path_override->fw_path_postfix = "community";
+ path_override->fw_lib_path_postfix = "community";
}
/*
- * for platforms using the SOF community key, change the
- * default path automatically to pick the right files from the
- * linux-firmware tree. This can be overridden with the
- * fw_path kernel parameter, e.g. for developers.
- */
-
- /* alternate fw and tplg filenames ? */
- if (fw_path) {
- sof_pdata->fw_filename_prefix = fw_path;
-
- dev_dbg(dev,
- "Module parameter used, changed fw path to %s\n",
- sof_pdata->fw_filename_prefix);
-
- } else if (dmi_check_system(community_key_platforms) && sof_dmi_use_community_key) {
- sof_pdata->fw_filename_prefix =
- devm_kasprintf(dev, GFP_KERNEL, "%s/%s",
- sof_pdata->desc->default_fw_path[sof_pdata->ipc_type],
- "community");
-
- dev_dbg(dev,
- "Platform uses community key, changed fw path to %s\n",
- sof_pdata->fw_filename_prefix);
- } else {
- sof_pdata->fw_filename_prefix =
- sof_pdata->desc->default_fw_path[sof_pdata->ipc_type];
- }
-
- if (lib_path) {
- sof_pdata->fw_lib_prefix = lib_path;
-
- dev_dbg(dev, "Module parameter used, changed fw_lib path to %s\n",
- sof_pdata->fw_lib_prefix);
-
- } else if (sof_pdata->desc->default_lib_path[sof_pdata->ipc_type]) {
- if (dmi_check_system(community_key_platforms) && sof_dmi_use_community_key) {
- sof_pdata->fw_lib_prefix =
- devm_kasprintf(dev, GFP_KERNEL, "%s/%s",
- sof_pdata->desc->default_lib_path[sof_pdata->ipc_type],
- "community");
-
- dev_dbg(dev,
- "Platform uses community key, changed fw_lib path to %s\n",
- sof_pdata->fw_lib_prefix);
- } else {
- sof_pdata->fw_lib_prefix =
- sof_pdata->desc->default_lib_path[sof_pdata->ipc_type];
- }
- }
-
- if (tplg_path)
- sof_pdata->tplg_filename_prefix = tplg_path;
- else
- sof_pdata->tplg_filename_prefix =
- sof_pdata->desc->default_tplg_path[sof_pdata->ipc_type];
-
- /*
* the topology filename will be provided in the machine descriptor, unless
* it is overridden by a module parameter or DMI quirk.
*/
if (tplg_filename) {
- sof_pdata->tplg_filename = tplg_filename;
-
- dev_dbg(dev, "Module parameter used, changed tplg filename to %s\n",
- sof_pdata->tplg_filename);
+ path_override->tplg_name = tplg_filename;
} else {
dmi_check_system(sof_tplg_table);
if (sof_dmi_override_tplg_name)
- sof_pdata->tplg_filename = sof_dmi_override_tplg_name;
+ path_override->tplg_name = sof_dmi_override_tplg_name;
}
/* set callback to be called on successful device probe to enable runtime_pm */
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
index f4185012eb69..6d7897bf9607 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -696,6 +696,13 @@ void snd_sof_new_platform_drv(struct snd_sof_dev *sdev);
extern struct snd_compress_ops sof_compressed_ops;
/*
+ * Firmware (firmware, libraries, topologies) file location
+ */
+int sof_create_ipc_file_profile(struct snd_sof_dev *sdev,
+ struct sof_loadable_file_profile *base_profile,
+ struct sof_loadable_file_profile *out_profile);
+
+/*
* Firmware loading.
*/
int snd_sof_load_firmware_raw(struct snd_sof_dev *sdev);
@@ -814,8 +821,6 @@ int sof_stream_pcm_open(struct snd_sof_dev *sdev,
int sof_stream_pcm_close(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream);
-int sof_machine_check(struct snd_sof_dev *sdev);
-
/* SOF client support */
#if IS_ENABLED(CONFIG_SND_SOC_SOF_CLIENT)
int sof_client_dev_register(struct snd_sof_dev *sdev, const char *name, u32 id,