* [PATCH 00/10] ASoC: wm_adsp: Some improvements to firmware file search
@ 2026-03-10 14:18 Richard Fitzgerald
2026-03-10 14:18 ` [PATCH 01/10] ASoC: wm_adsp: Remove unused argument to wm_adsp_release_firmware_files() Richard Fitzgerald
` (11 more replies)
0 siblings, 12 replies; 20+ messages in thread
From: Richard Fitzgerald @ 2026-03-10 14:18 UTC (permalink / raw)
To: broonie; +Cc: linux-sound, linux-kernel, patches
This series makes some improvements to the code that searches for firmware
files.
Patch 1 is a trivial patch to remove an unused function argument, before
adding any new code that uses this API.
Patches 2..4 add KUnit testing to prove that the subsequent changes don't
break anything.
The remaining patches remove duplicated code and clean up some of the
implementation.
Richard Fitzgerald (10):
ASoC: wm_adsp: Remove unused argument to
wm_adsp_release_firmware_files()
ASoC: wm_adsp: Add KUnit redirection stubs for firmware file search
ASoC: wm_adsp: Export function for KUnit test to get firmware
filenames
ASoC: wm_adsp: Add kunit test for firmware file search
ASoC: wm_adsp: Remove duplicated code to find firmware file
ASoC: wm_adsp: Use consistent error checks in
wm_adsp_request_firmware_files()
ASoC: wm_adsp: Convert '/' to '-' when normalizing firmware filenames
ASoC: wm_adsp: Add KUnit test cases for '/' in firmware filenames
ASoC: wm_adsp: Use a struct to pass around firmware struct and
filename
ASoC: wm_adsp: Combine some similar code in firmware file search
sound/soc/codecs/Kconfig | 14 +-
sound/soc/codecs/Makefile | 2 +
sound/soc/codecs/wm_adsp.c | 234 +++--
sound/soc/codecs/wm_adsp.h | 19 +
sound/soc/codecs/wm_adsp_fw_find_test.c | 1221 +++++++++++++++++++++++
5 files changed, 1383 insertions(+), 107 deletions(-)
create mode 100644 sound/soc/codecs/wm_adsp_fw_find_test.c
--
2.47.3
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 01/10] ASoC: wm_adsp: Remove unused argument to wm_adsp_release_firmware_files()
2026-03-10 14:18 [PATCH 00/10] ASoC: wm_adsp: Some improvements to firmware file search Richard Fitzgerald
@ 2026-03-10 14:18 ` Richard Fitzgerald
2026-03-10 14:18 ` [PATCH 02/10] ASoC: wm_adsp: Add KUnit redirection stubs for firmware file search Richard Fitzgerald
` (10 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Richard Fitzgerald @ 2026-03-10 14:18 UTC (permalink / raw)
To: broonie; +Cc: linux-sound, linux-kernel, patches
The dsp argument to wm_adsp_release_firmware_files() isn't used so
remove it.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
sound/soc/codecs/wm_adsp.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index f0aa6e3a1cfa..4b0c53d4f524 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -704,8 +704,7 @@ int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type,
}
EXPORT_SYMBOL_GPL(wm_adsp_read_ctl);
-static void wm_adsp_release_firmware_files(struct wm_adsp *dsp,
- const struct firmware *wmfw_firmware,
+static void wm_adsp_release_firmware_files(const struct firmware *wmfw_firmware,
char *wmfw_filename,
const struct firmware *coeff_firmware,
char *coeff_filename)
@@ -908,8 +907,7 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
coeff_firmware, coeff_filename,
wm_adsp_fw_text[dsp->fw]);
- wm_adsp_release_firmware_files(dsp,
- wmfw_firmware, wmfw_filename,
+ wm_adsp_release_firmware_files(wmfw_firmware, wmfw_filename,
coeff_firmware, coeff_filename);
break;
case SND_SOC_DAPM_PRE_PMD:
@@ -1011,8 +1009,7 @@ int wm_adsp_power_up(struct wm_adsp *dsp, bool load_firmware)
wm_adsp_fw_text[dsp->fw]);
err:
- wm_adsp_release_firmware_files(dsp,
- wmfw_firmware, wmfw_filename,
+ wm_adsp_release_firmware_files(wmfw_firmware, wmfw_filename,
coeff_firmware, coeff_filename);
return ret;
--
2.47.3
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 02/10] ASoC: wm_adsp: Add KUnit redirection stubs for firmware file search
2026-03-10 14:18 [PATCH 00/10] ASoC: wm_adsp: Some improvements to firmware file search Richard Fitzgerald
2026-03-10 14:18 ` [PATCH 01/10] ASoC: wm_adsp: Remove unused argument to wm_adsp_release_firmware_files() Richard Fitzgerald
@ 2026-03-10 14:18 ` Richard Fitzgerald
2026-03-10 14:18 ` [PATCH 03/10] ASoC: wm_adsp: Export function for KUnit test to get firmware filenames Richard Fitzgerald
` (9 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Richard Fitzgerald @ 2026-03-10 14:18 UTC (permalink / raw)
To: broonie; +Cc: linux-sound, linux-kernel, patches
Make some of the firmware file search functions redirectable for KUnit
testing.
- The call to firmware_request_nowarn() is factored out into a wrapper
function so that it can be redirected.
- wm_adsp_request_firmware_files() and wm_adsp_release_firmware_files()
are made visible and exported if KUNIT is enabled.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
sound/soc/codecs/wm_adsp.c | 38 ++++++++++++++++++++++++++++----------
sound/soc/codecs/wm_adsp.h | 15 +++++++++++++++
2 files changed, 43 insertions(+), 10 deletions(-)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 4b0c53d4f524..68e00970b8a2 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -7,6 +7,8 @@
* Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
*/
+#include <kunit/static_stub.h>
+#include <kunit/visibility.h>
#include <linux/array_size.h>
#include <linux/cleanup.h>
#include <linux/ctype.h>
@@ -704,17 +706,32 @@ int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type,
}
EXPORT_SYMBOL_GPL(wm_adsp_read_ctl);
-static void wm_adsp_release_firmware_files(const struct firmware *wmfw_firmware,
- char *wmfw_filename,
- const struct firmware *coeff_firmware,
- char *coeff_filename)
+VISIBLE_IF_KUNIT void wm_adsp_release_firmware_files(const struct firmware *wmfw_firmware,
+ char *wmfw_filename,
+ const struct firmware *coeff_firmware,
+ char *coeff_filename)
{
+ KUNIT_STATIC_STUB_REDIRECT(wm_adsp_release_firmware_files,
+ wmfw_firmware, wmfw_filename,
+ coeff_firmware, coeff_filename);
+
release_firmware(wmfw_firmware);
kfree(wmfw_filename);
release_firmware(coeff_firmware);
kfree(coeff_filename);
}
+EXPORT_SYMBOL_IF_KUNIT(wm_adsp_release_firmware_files);
+
+VISIBLE_IF_KUNIT int wm_adsp_firmware_request(const struct firmware **firmware,
+ const char *filename,
+ struct device *dev)
+{
+ KUNIT_STATIC_STUB_REDIRECT(wm_adsp_firmware_request, firmware, filename, dev);
+
+ return firmware_request_nowarn(firmware, filename, dev);
+}
+EXPORT_SYMBOL_IF_KUNIT(wm_adsp_firmware_request);
static int wm_adsp_request_firmware_file(struct wm_adsp *dsp,
const struct firmware **firmware, char **filename,
@@ -762,7 +779,7 @@ static int wm_adsp_request_firmware_file(struct wm_adsp *dsp,
s++;
}
- ret = firmware_request_nowarn(firmware, *filename, cs_dsp->dev);
+ ret = wm_adsp_firmware_request(firmware, *filename, cs_dsp->dev);
if (ret != 0) {
adsp_dbg(dsp, "Failed to request '%s'\n", *filename);
kfree(*filename);
@@ -775,11 +792,11 @@ static int wm_adsp_request_firmware_file(struct wm_adsp *dsp,
}
static const char * const cirrus_dir = "cirrus/";
-static int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
- const struct firmware **wmfw_firmware,
- char **wmfw_filename,
- const struct firmware **coeff_firmware,
- char **coeff_filename)
+VISIBLE_IF_KUNIT int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
+ const struct firmware **wmfw_firmware,
+ char **wmfw_filename,
+ const struct firmware **coeff_firmware,
+ char **coeff_filename)
{
const char *system_name = dsp->system_name;
const char *suffix = dsp->component->name_prefix;
@@ -856,6 +873,7 @@ static int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
return -ENOENT;
}
+EXPORT_SYMBOL_IF_KUNIT(wm_adsp_request_firmware_files);
static int wm_adsp_common_init(struct wm_adsp *dsp)
{
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index a9118be793d7..599be409b669 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -143,4 +143,19 @@ int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type,
int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type,
unsigned int alg, void *buf, size_t len);
+#if IS_ENABLED(CONFIG_KUNIT)
+void wm_adsp_release_firmware_files(const struct firmware *wmfw_firmware,
+ char *wmfw_filename,
+ const struct firmware *coeff_firmware,
+ char *coeff_filename);
+int wm_adsp_firmware_request(const struct firmware **firmware,
+ const char *filename,
+ struct device *dev);
+int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
+ const struct firmware **wmfw_firmware,
+ char **wmfw_filename,
+ const struct firmware **coeff_firmware,
+ char **coeff_filename);
+#endif
+
#endif
--
2.47.3
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 03/10] ASoC: wm_adsp: Export function for KUnit test to get firmware filenames
2026-03-10 14:18 [PATCH 00/10] ASoC: wm_adsp: Some improvements to firmware file search Richard Fitzgerald
2026-03-10 14:18 ` [PATCH 01/10] ASoC: wm_adsp: Remove unused argument to wm_adsp_release_firmware_files() Richard Fitzgerald
2026-03-10 14:18 ` [PATCH 02/10] ASoC: wm_adsp: Add KUnit redirection stubs for firmware file search Richard Fitzgerald
@ 2026-03-10 14:18 ` Richard Fitzgerald
2026-03-10 14:18 ` [PATCH 04/10] ASoC: wm_adsp: Add kunit test for firmware file search Richard Fitzgerald
` (8 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Richard Fitzgerald @ 2026-03-10 14:18 UTC (permalink / raw)
To: broonie; +Cc: linux-sound, linux-kernel, patches
Export a function that KUnit tests can use to get the firmware filenames
from the wm_adsp_fw[] array.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
sound/soc/codecs/wm_adsp.c | 11 +++++++++++
sound/soc/codecs/wm_adsp.h | 1 +
2 files changed, 12 insertions(+)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 68e00970b8a2..79695ead5788 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -318,6 +318,17 @@ struct wm_coeff_ctl {
struct work_struct work;
};
+#if IS_ENABLED(CONFIG_KUNIT)
+const char *wm_adsp_get_fwf_name_by_index(int index)
+{
+ if (index < ARRAY_SIZE(wm_adsp_fw))
+ return wm_adsp_fw[index].file;
+
+ return NULL;
+}
+EXPORT_SYMBOL_IF_KUNIT(wm_adsp_get_fwf_name_by_index);
+#endif
+
int wm_adsp_fw_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index 599be409b669..b4d5bd321c0b 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -144,6 +144,7 @@ int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type,
unsigned int alg, void *buf, size_t len);
#if IS_ENABLED(CONFIG_KUNIT)
+const char *wm_adsp_get_fwf_name_by_index(int index);
void wm_adsp_release_firmware_files(const struct firmware *wmfw_firmware,
char *wmfw_filename,
const struct firmware *coeff_firmware,
--
2.47.3
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 04/10] ASoC: wm_adsp: Add kunit test for firmware file search
2026-03-10 14:18 [PATCH 00/10] ASoC: wm_adsp: Some improvements to firmware file search Richard Fitzgerald
` (2 preceding siblings ...)
2026-03-10 14:18 ` [PATCH 03/10] ASoC: wm_adsp: Export function for KUnit test to get firmware filenames Richard Fitzgerald
@ 2026-03-10 14:18 ` Richard Fitzgerald
2026-03-10 14:18 ` [PATCH 05/10] ASoC: wm_adsp: Remove duplicated code to find firmware file Richard Fitzgerald
` (7 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Richard Fitzgerald @ 2026-03-10 14:18 UTC (permalink / raw)
To: broonie; +Cc: linux-sound, linux-kernel, patches
Add KUnit testing of the wm_adsp code that searches for firmware files.
Also make the SND_SOC_WM_ADSP Kconfig symbol visible if KUNIT is enabled
so that wm_adsp can be manually included for KUnit testing.
The firmware filename is composed of several fields, some of which are
optional, and there is a search algorithm to fallback from specific to
generic versions of firmware for a device. This KUnit test verifies that
wm_adsp is searching for the correct sequence of filenames.
The are two ways of testing this, and both are used in this KUnit test.
1. Trap the calls to firmware_request_nowarn() and test that the sequence
of filenames request is correct.
This is the most thorough test because it proves that exactly the
expected filenames are requested, in the correct order.
But it doesn't fully cover regression testing. If a change to the search
algorithm changes the expected sequence of requested files, the test
must also be changed to expect that new sequence. If the expectation is
wrong, the tests can pass (because the search order is as expected)
while picking a different file in some cases from what it did before the
change.
2. Test which file is picked from a simulated directory of files.
This is better for regression testing because it is independent of the
search algorithm. It does not need to change if the search algorithm
changes. It is not testing exactly which files the algorithm searches
for, only which file it eventually picks from a given set of available
files.
In other words, the regression test is: does it still pick the same file
from the same directory of files?
But it is impractical for thorough testing. It doesn't prove that
exactly the correct files were searched for, unless it was to test with
every possible combination of file names and directory content that
could ever exist. Clearly this is impossible to implement, since the
number of combations of possible valid filenames in a directory and
number of files in a directory is astronomically large.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
sound/soc/codecs/Kconfig | 14 +-
sound/soc/codecs/Makefile | 2 +
sound/soc/codecs/wm_adsp_fw_find_test.c | 1223 +++++++++++++++++++++++
3 files changed, 1238 insertions(+), 1 deletion(-)
create mode 100644 sound/soc/codecs/wm_adsp_fw_find_test.c
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index adb3fb923be3..f9e6a83e55c6 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -398,7 +398,7 @@ config SND_SOC_WM_HUBS
default m if SND_SOC_WM8993=m || SND_SOC_WM8994=m
config SND_SOC_WM_ADSP
- tristate
+ tristate "Cirrus Logic wm_adsp driver" if KUNIT
select FW_CS_DSP
select SND_SOC_COMPRESS
default y if SND_SOC_MADERA=y
@@ -424,6 +424,18 @@ config SND_SOC_WM_ADSP
default m if SND_SOC_CS35L56=m
default m if SND_SOC_CS48L32=m
+config SND_SOC_WM_ADSP_TEST
+ tristate "KUnit tests for Cirrus Logic wm_adsp" if !KUNIT_ALL_TESTS
+ depends on KUNIT
+ depends on SND_SOC_WM_ADSP
+ default KUNIT_ALL_TESTS
+ help
+ This builds KUnit tests for the Cirrus Logic wm_adsp library.
+ For more information on KUnit and unit tests in general,
+ please refer to the KUnit documentation in
+ Documentation/dev-tools/kunit/.
+ If in doubt, say "N".
+
config SND_SOC_AB8500_CODEC
tristate
depends on ABX500_CORE
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 3ddee5298721..172861d17cfd 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -361,6 +361,7 @@ snd-soc-wcd938x-sdw-y := wcd938x-sdw.o
snd-soc-wcd939x-y := wcd939x.o
snd-soc-wcd939x-sdw-y := wcd939x-sdw.o
snd-soc-wm-adsp-y := wm_adsp.o
+snd-soc-wm-adsp-test-y := wm_adsp_fw_find_test.o
snd-soc-wm0010-y := wm0010.o
snd-soc-wm1250-ev1-y := wm1250-ev1.o
snd-soc-wm2000-y := wm2000.o
@@ -862,6 +863,7 @@ obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o
obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o
obj-$(CONFIG_SND_SOC_WM9713) += snd-soc-wm9713.o
obj-$(CONFIG_SND_SOC_WM_ADSP) += snd-soc-wm-adsp.o
+obj-$(CONFIG_SND_SOC_WM_ADSP_TEST) += snd-soc-wm-adsp-test.o
obj-$(CONFIG_SND_SOC_WM_HUBS) += snd-soc-wm-hubs.o
obj-$(CONFIG_SND_SOC_WSA881X) += snd-soc-wsa881x.o
obj-$(CONFIG_SND_SOC_WSA883X) += snd-soc-wsa883x.o
diff --git a/sound/soc/codecs/wm_adsp_fw_find_test.c b/sound/soc/codecs/wm_adsp_fw_find_test.c
new file mode 100644
index 000000000000..556221d38a50
--- /dev/null
+++ b/sound/soc/codecs/wm_adsp_fw_find_test.c
@@ -0,0 +1,1223 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Test cases for wm_adsp library.
+//
+// Copyright (C) 2025 Cirrus Logic, Inc. and
+// Cirrus Logic International Semiconductor Ltd.
+
+#include <kunit/device.h>
+#include <kunit/static_stub.h>
+#include <kunit/test.h>
+#include <linux/slab.h>
+#include "wm_adsp.h"
+
+KUNIT_DEFINE_ACTION_WRAPPER(_put_device_wrapper, put_device, struct device *);
+
+struct wm_adsp_fw_find_test {
+ struct wm_adsp dsp;
+
+ const struct firmware *found_wmfw_firmware;
+ const struct firmware *found_bin_firmware;
+ char *found_wmfw_filename;
+ char *found_bin_filename;
+ char searched_fw_files[768];
+};
+
+struct wm_adsp_fw_find_test_params {
+ const char *part;
+ const char *dsp_name;
+ const char *fwf_name;
+ const char *system_name;
+ const char *alsa_name;
+ bool wmfw_optional;
+ bool bin_mandatory;
+
+ /* If non-NULL this file should be returned as "found" */
+ const char *expect_wmfw;
+
+ /* If non-NULL this file should be returned as "found" */
+ const char *expect_bin;
+
+ /* Space-separated list of filenames in expected order of searching */
+ const char *expected_searches;
+
+ /* NULL-terminated array of pointers to filenames to simulate directory content */
+ const char * const *dir_files;
+};
+
+/* Dummy struct firmware to return from wm_adsp_request_firmware_files */
+static const struct firmware wm_adsp_find_test_dummy_firmware;
+
+/* Simple lookup of a filename in a list of names */
+static int wm_adsp_fw_find_test_firmware_request_simple_stub(const struct firmware **firmware,
+ const char *filename,
+ struct device *dev)
+{
+ struct kunit *test = kunit_get_current_test();
+ const struct wm_adsp_fw_find_test_params *params = test->param_value;
+ int i;
+
+ /* Non-parameterized test? */
+ if (!params)
+ return -ENOENT;
+
+ if (!params->dir_files)
+ return -ENOENT;
+
+ for (i = 0; params->dir_files[i]; i++) {
+ if (strcmp(params->dir_files[i], filename) == 0) {
+ *firmware = &wm_adsp_find_test_dummy_firmware;
+ return 0;
+ }
+ }
+
+ return -ENOENT;
+}
+
+static void wm_adsp_fw_find_test_pick_file(struct kunit *test)
+{
+ struct wm_adsp_fw_find_test *priv = test->priv;
+ const struct wm_adsp_fw_find_test_params *params = test->param_value;
+ struct wm_adsp *dsp = &priv->dsp;
+ int i, ret;
+
+ /* Concatenate string of dir content for error messages */
+ for (i = 0; params->dir_files[i]; i++) {
+ strlcat(priv->searched_fw_files, params->dir_files[i],
+ sizeof(priv->searched_fw_files));
+ strlcat(priv->searched_fw_files, ";",
+ sizeof(priv->searched_fw_files));
+ }
+
+ dsp->cs_dsp.name = params->dsp_name;
+ dsp->part = params->part;
+ dsp->fwf_name = params->fwf_name;
+ dsp->system_name = params->system_name;
+ dsp->component->name_prefix = params->alsa_name;
+ dsp->wmfw_optional = params->wmfw_optional;
+ dsp->bin_mandatory = params->bin_mandatory;
+
+ kunit_activate_static_stub(test,
+ wm_adsp_firmware_request,
+ wm_adsp_fw_find_test_firmware_request_simple_stub);
+
+ ret = wm_adsp_request_firmware_files(dsp,
+ &priv->found_wmfw_firmware,
+ &priv->found_wmfw_filename,
+ &priv->found_bin_firmware,
+ &priv->found_bin_filename);
+ kunit_deactivate_static_stub(test, wm_adsp_firmware_request);
+ KUNIT_EXPECT_EQ_MSG(test, ret,
+ (params->expect_wmfw || params->expect_bin) ? 0 : -ENOENT,
+ "%s\n", priv->searched_fw_files);
+
+ KUNIT_EXPECT_EQ_MSG(test, !!priv->found_wmfw_filename, !!params->expect_wmfw,
+ "%s\n", priv->searched_fw_files);
+ KUNIT_EXPECT_EQ_MSG(test, !!priv->found_bin_filename, !!params->expect_bin,
+ "%s\n", priv->searched_fw_files);
+
+ if (params->expect_wmfw) {
+ KUNIT_EXPECT_STREQ_MSG(test, priv->found_wmfw_filename, params->expect_wmfw,
+ "%s\n", priv->searched_fw_files);
+ }
+
+ if (params->expect_bin) {
+ KUNIT_EXPECT_STREQ_MSG(test, priv->found_bin_filename, params->expect_bin,
+ "%s\n", priv->searched_fw_files);
+ }
+}
+
+static int wm_adsp_fw_find_test_firmware_request_stub(const struct firmware **firmware,
+ const char *filename,
+ struct device *dev)
+{
+ struct kunit *test = kunit_get_current_test();
+ const struct wm_adsp_fw_find_test_params *params = test->param_value;
+ struct wm_adsp_fw_find_test *priv = test->priv;
+
+ /*
+ * Searches are accumulated as a single string of space-separated names.
+ * The list of expected searches are stored the same way in
+ * struct wm_adsp_fw_find_test_params. This allows for comparision using
+ * a simple KUNIT_EXPECT_STREQ(), which avoids the risk of bugs in a
+ * more complex custom comparison.
+ */
+ if (priv->searched_fw_files[0] != '\0')
+ strlcat(priv->searched_fw_files, " ", sizeof(priv->searched_fw_files));
+
+ strlcat(priv->searched_fw_files, filename, sizeof(priv->searched_fw_files));
+
+ /* Non-parameterized test? */
+ if (!params)
+ return -ENOENT;
+
+ if (params->expect_wmfw && (strcmp(filename, params->expect_wmfw) == 0)) {
+ *firmware = &wm_adsp_find_test_dummy_firmware;
+ return 0;
+ }
+
+ if (params->expect_bin && (strcmp(filename, params->expect_bin) == 0)) {
+ *firmware = &wm_adsp_find_test_dummy_firmware;
+ return 0;
+ }
+
+ return -ENOENT;
+}
+
+static void wm_adsp_fw_find_test_search_order(struct kunit *test)
+{
+ struct wm_adsp_fw_find_test *priv = test->priv;
+ const struct wm_adsp_fw_find_test_params *params = test->param_value;
+ struct wm_adsp *dsp = &priv->dsp;
+
+ dsp->cs_dsp.name = params->dsp_name;
+ dsp->part = params->part;
+ dsp->fwf_name = params->fwf_name;
+ dsp->system_name = params->system_name;
+ dsp->component->name_prefix = params->alsa_name;
+ dsp->wmfw_optional = params->wmfw_optional;
+
+ kunit_activate_static_stub(test,
+ wm_adsp_firmware_request,
+ wm_adsp_fw_find_test_firmware_request_stub);
+
+ wm_adsp_request_firmware_files(dsp,
+ &priv->found_wmfw_firmware,
+ &priv->found_wmfw_filename,
+ &priv->found_bin_firmware,
+ &priv->found_bin_filename);
+
+ kunit_deactivate_static_stub(test, wm_adsp_firmware_request);
+
+ KUNIT_EXPECT_STREQ(test, priv->searched_fw_files, params->expected_searches);
+
+ KUNIT_EXPECT_EQ(test, !!priv->found_wmfw_filename, !!params->expect_wmfw);
+ if (params->expect_wmfw)
+ KUNIT_EXPECT_STREQ(test, priv->found_wmfw_filename, params->expect_wmfw);
+
+ KUNIT_EXPECT_EQ(test, !!priv->found_bin_filename, !!params->expect_bin);
+ if (params->expect_bin)
+ KUNIT_EXPECT_STREQ(test, priv->found_bin_filename, params->expect_bin);
+
+ /* Either we get a filename and firmware, or neither */
+ KUNIT_EXPECT_EQ(test, !!priv->found_wmfw_filename, !!priv->found_wmfw_firmware);
+ KUNIT_EXPECT_EQ(test, !!priv->found_bin_filename, !!priv->found_bin_firmware);
+}
+
+static void wm_adsp_fw_find_test_find_firmware_byindex(struct kunit *test)
+{
+ struct wm_adsp_fw_find_test *priv = test->priv;
+ struct wm_adsp *dsp = &priv->dsp;
+ const char *fw_name;
+
+ dsp->cs_dsp.name = "cs1234";
+ dsp->part = "dsp1";
+ for (dsp->fw = 0;; dsp->fw++) {
+ fw_name = wm_adsp_get_fwf_name_by_index(dsp->fw);
+ if (!fw_name)
+ break;
+
+ kunit_activate_static_stub(test,
+ wm_adsp_firmware_request,
+ wm_adsp_fw_find_test_firmware_request_stub);
+
+ wm_adsp_request_firmware_files(dsp,
+ &priv->found_wmfw_firmware,
+ &priv->found_wmfw_filename,
+ &priv->found_bin_firmware,
+ &priv->found_bin_filename);
+
+ kunit_deactivate_static_stub(test, wm_adsp_firmware_request);
+
+ KUNIT_EXPECT_NOT_NULL_MSG(test,
+ strstr(priv->searched_fw_files, fw_name),
+ "fw#%d Did not find '%s' in '%s'\n",
+ dsp->fw, fw_name, priv->searched_fw_files);
+ }
+}
+
+static int wm_adsp_fw_find_test_case_init(struct kunit *test)
+{
+ struct wm_adsp_fw_find_test *priv;
+ struct device *test_dev;
+ int ret;
+
+ priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ /* Require dummy struct snd_soc_component for the alsa name prefix string */
+ priv->dsp.component = kunit_kzalloc(test, sizeof(*priv->dsp.component), GFP_KERNEL);
+ if (!priv->dsp.component)
+ return -ENOMEM;
+
+ test->priv = priv;
+
+ /* Create dummy amp device */
+ test_dev = kunit_device_register(test, "wm_adsp_test_drv");
+ if (IS_ERR(test_dev))
+ return PTR_ERR(test_dev);
+
+ priv->dsp.cs_dsp.dev = get_device(test_dev);
+ if (!priv->dsp.cs_dsp.dev)
+ return -ENODEV;
+
+ ret = kunit_add_action_or_reset(test, _put_device_wrapper, priv->dsp.cs_dsp.dev);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static void wm_adsp_fw_find_test_case_exit(struct kunit *test)
+{
+ struct wm_adsp_fw_find_test *priv = test->priv;
+
+ /*
+ * priv->found_wmfw_firmware and priv->found_bin_firmware are
+ * dummies not allocated by the real request_firmware() call they
+ * must not be passed to release_firmware().
+ */
+ wm_adsp_release_firmware_files(NULL, priv->found_wmfw_filename,
+ NULL, priv->found_bin_filename);
+}
+
+static void wm_adsp_fw_find_test_param_desc(const struct wm_adsp_fw_find_test_params *param,
+ char *desc)
+{
+ snprintf(desc, KUNIT_PARAM_DESC_SIZE,
+ "%s %s fwf_name:%s system:%s alsa_name:%s %s expects:(%s %s)",
+ param->part, param->dsp_name,
+ param->fwf_name ? param->fwf_name : "",
+ param->system_name ? param->system_name : "",
+ param->alsa_name ? param->alsa_name : "",
+ param->wmfw_optional ? "wmfw_optional" : "",
+ param->expect_wmfw ? param->expect_wmfw : "",
+ param->expect_bin ? param->expect_bin : "");
+}
+
+/* Cases where firmware file not found. Tests full search sequence. */
+static const struct wm_adsp_fw_find_test_params wm_adsp_fw_find_full_search_cases[] = {
+ { /* system name and alsa prefix, wmfw mandatory. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw",
+ },
+ { /* system name and alsa prefix, wmfw optional. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1", .wmfw_optional = true,
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.bin "
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* system name only, wmfw mandatory. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw",
+ },
+ { /* system name only, wmfw optional. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .wmfw_optional = true,
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.bin "
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.bin",
+ },
+
+ /*
+ * TODO: Is this a bug? Device-specific bin is only allowed when there
+ * is a system_name. But if there isn't any meaningful system name on
+ * a product, why can't it load firmware files qualified by alsa prefix?
+ */
+
+ { /* Alsa prefix, wmfw mandatory. No system name so generic files only. */
+ .part = "cs1234", .dsp_name = "dsp1", .alsa_name = "amp1",
+ .expected_searches =
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw",
+ },
+ { /* Alsa prefix, wmfw optional. No system name so generic files only. */
+ .part = "cs1234", .dsp_name = "dsp1", .alsa_name = "amp1",
+ .wmfw_optional = true,
+ .expected_searches =
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.bin",
+ },
+
+ { /* fwf_name, system name and alsa prefix, wmfw mandatory. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1", .fwf_name = "ao",
+ .expected_searches =
+ "cirrus/cs1234-ao-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-ao-mbc-vss-abc123.wmfw "
+ "cs1234-ao-mbc-vss.wmfw "
+ "cirrus/cs1234-ao-mbc-vss.wmfw",
+ },
+ { /* fwf_name, system name and alsa prefix, wmfw optional. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1", .fwf_name = "ao",
+ .wmfw_optional = true,
+ .expected_searches =
+ "cirrus/cs1234-ao-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-ao-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-ao-mbc-vss-abc123-amp1.bin "
+ "cirrus/cs1234-ao-mbc-vss-abc123.bin "
+ "cs1234-ao-mbc-vss.wmfw "
+ "cirrus/cs1234-ao-mbc-vss.wmfw "
+ "cirrus/cs1234-ao-mbc-vss.bin",
+ },
+};
+KUNIT_ARRAY_PARAM(wm_adsp_fw_find_full_search,
+ wm_adsp_fw_find_full_search_cases,
+ wm_adsp_fw_find_test_param_desc);
+
+/* Cases with system name and alsa prefix both given. */
+static const struct wm_adsp_fw_find_test_params wm_adsp_fw_find_system_alsaname_cases[] = {
+ { /* Fully-qualified wmfw exists. No bin */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin",
+ },
+ { /* Optional fully-qualified wmfw exists. No bin */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1", .wmfw_optional = true,
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin",
+ },
+ { /* Fully-qualified wmfw and bin exist. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin",
+ },
+ { /* Optional fully-qualified wmfw and fully-qualified bin exist. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1", .wmfw_optional = true,
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin",
+ },
+ { /* wmfw matches system name only. No bin */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
+ },
+ { /* Optional wmfw matches system name only. No bin */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1", .wmfw_optional = true,
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
+ },
+ { /* wmfw matches system name only. Fully-qualified bin. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin",
+ },
+ { /* Optional wmfw matches system name only. Fully-qualified bin. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1", .wmfw_optional = true,
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin",
+ },
+ { /* wmfw and bin match system name only. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
+ },
+ { /* Optional wmfw and bin match system name only. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1", .wmfw_optional = true,
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
+ },
+ { /* Optional wmfw not found. bin matches fully-qualified name. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1", .wmfw_optional = true,
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin",
+ },
+ { /* Optional wmfw not found. bin matches system name only. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1", .wmfw_optional = true,
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
+ },
+ { /* No qualified wmfw. Legacy generic wmfw found. No bin. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1",
+ .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No qualified optional wmfw. Legacy generic wmfw found. No bin. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1", .wmfw_optional = true,
+ .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.bin "
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No qualified wmfw. Legacy generic wmfw and bin found. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1",
+ .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
+ .expect_bin = "cs1234-dsp1-mbc-vss.bin",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No qualified optional wmfw. Legacy generic wmfw and bin found. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1", .wmfw_optional = true,
+ .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
+ .expect_bin = "cs1234-dsp1-mbc-vss.bin",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.bin "
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No qualified or legacy wmfw. Generic wmfw found. No bin. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No optional qualified or legacy wmfw. Generic wmfw found. No bin. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1", .wmfw_optional = true,
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.bin "
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No qualified or legacy wmfw. Generic wmfw and bin found. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No optional qualified or legacy wmfw. Generic wmfw and bin found. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1", .wmfw_optional = true,
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.bin "
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No optional qualified or generic wmfw. Generic bin found. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .alsa_name = "amp1", .wmfw_optional = true,
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.bin "
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.bin",
+ },
+};
+KUNIT_ARRAY_PARAM(wm_adsp_fw_find_system_alsaname,
+ wm_adsp_fw_find_system_alsaname_cases,
+ wm_adsp_fw_find_test_param_desc);
+
+/* Cases with system name but without alsa name prefix. */
+static const struct wm_adsp_fw_find_test_params wm_adsp_fw_find_system_cases[] = {
+ { /* Qualified wmfw found. No bin */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
+ },
+ { /* Optional qualified wmfw found. No bin */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .wmfw_optional = true,
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
+ },
+ { /* Qualified wmfw found. Qualified bin found. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
+ },
+ { /* Optional qualified wmfw found. Qualified bin found. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .wmfw_optional = true,
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
+ },
+ { /* Optional wmfw not found. Qualified bin found. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .wmfw_optional = true,
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.bin",
+ },
+ { /* No qualified wmfw. Legacy generic wmfw found. No bin. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No qualified optional wmfw. Legacy generic wmfw found. No bin. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .wmfw_optional = true,
+ .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.bin "
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No qualified wmfw. Legacy generic wmfw and bin found. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
+ .expect_bin = "cs1234-dsp1-mbc-vss.bin",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No qualified optional wmfw. Legacy generic wmfw and bin found. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .wmfw_optional = true,
+ .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
+ .expect_bin = "cs1234-dsp1-mbc-vss.bin",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.bin "
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No qualified or legacy wmfw. Generic wmfw found. No bin. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No optional qualified or legacy wmfw. Generic wmfw found. No bin. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .wmfw_optional = true,
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.bin "
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No qualified or legacy wmfw. Generic wmfw and bin found. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No optional qualified or legacy wmfw. Generic wmfw and bin found. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .wmfw_optional = true,
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.bin "
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No optional qualified or generic wmfw. Generic bin found. */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "ABC123",
+ .wmfw_optional = true,
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc123.bin "
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.bin",
+ },
+};
+KUNIT_ARRAY_PARAM(wm_adsp_fw_find_system,
+ wm_adsp_fw_find_system_cases,
+ wm_adsp_fw_find_test_param_desc);
+
+/* Cases without system name but with alsa name prefix. */
+static const struct wm_adsp_fw_find_test_params wm_adsp_fw_find_alsaname_cases[] = {
+ { /* Legacy generic wmfw found. No bin. */
+ .part = "cs1234", .dsp_name = "dsp1", .alsa_name = "amp1",
+ .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
+ .expected_searches =
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* wmfw optional. Legacy generic wmfw found. No bin. */
+ .part = "cs1234", .dsp_name = "dsp1", .alsa_name = "amp1",
+ .wmfw_optional = true,
+ .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
+ .expected_searches =
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* Legacy generic wmfw and bin found. */
+ .part = "cs1234", .dsp_name = "dsp1", .alsa_name = "amp1",
+ .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
+ .expect_bin = "cs1234-dsp1-mbc-vss.bin",
+ .expected_searches =
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* wmfw optional. Legacy generic wmfw and bin found. */
+ .part = "cs1234", .dsp_name = "dsp1", .alsa_name = "amp1",
+ .wmfw_optional = true,
+ .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
+ .expect_bin = "cs1234-dsp1-mbc-vss.bin",
+ .expected_searches =
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No legacy wmfw. Generic wmfw found. No bin. */
+ .part = "cs1234", .dsp_name = "dsp1", .alsa_name = "amp1",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
+ .expected_searches =
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No legacy wmfw. Optional generic wmfw found. No bin. */
+ .part = "cs1234", .dsp_name = "dsp1", .alsa_name = "amp1",
+ .wmfw_optional = true,
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
+ .expected_searches =
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No legacy wmfw. Generic wmfw and bin found. */
+ .part = "cs1234", .dsp_name = "dsp1", .alsa_name = "amp1",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
+ .expected_searches =
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No legacy wmfw. Optional generic wmfw and bin found. */
+ .part = "cs1234", .dsp_name = "dsp1", .alsa_name = "amp1",
+ .wmfw_optional = true,
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
+ .expected_searches =
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No legacy or generic wmfw. Generic bin found. */
+ .part = "cs1234", .dsp_name = "dsp1", .alsa_name = "amp1",
+ .wmfw_optional = true,
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
+ .expected_searches =
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.bin",
+ },
+};
+KUNIT_ARRAY_PARAM(wm_adsp_fw_find_alsaname,
+ wm_adsp_fw_find_alsaname_cases,
+ wm_adsp_fw_find_test_param_desc);
+
+/* Cases without system name or alsa name prefix. */
+static const struct wm_adsp_fw_find_test_params wm_adsp_fw_find_noqual_cases[] = {
+ { /* Legacy generic wmfw found. No bin. */
+ .part = "cs1234", .dsp_name = "dsp1",
+ .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
+ .expected_searches =
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* wmfw optional. Legacy generic wmfw found. No bin. */
+ .part = "cs1234", .dsp_name = "dsp1",
+ .wmfw_optional = true,
+ .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
+ .expected_searches =
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* Legacy generic wmfw and bin found. */
+ .part = "cs1234", .dsp_name = "dsp1",
+ .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
+ .expect_bin = "cs1234-dsp1-mbc-vss.bin",
+ .expected_searches =
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* wmfw optional. Legacy generic wmfw and bin found. */
+ .part = "cs1234", .dsp_name = "dsp1",
+ .wmfw_optional = true,
+ .expect_wmfw = "cs1234-dsp1-mbc-vss.wmfw",
+ .expect_bin = "cs1234-dsp1-mbc-vss.bin",
+ .expected_searches =
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No legacy wmfw. Generic wmfw found. No bin. */
+ .part = "cs1234", .dsp_name = "dsp1",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
+ .expected_searches =
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No legacy wmfw. Optional generic wmfw found. No bin. */
+ .part = "cs1234", .dsp_name = "dsp1",
+ .wmfw_optional = true,
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
+ .expected_searches =
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No legacy wmfw. Generic wmfw and bin found. */
+ .part = "cs1234", .dsp_name = "dsp1",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
+ .expected_searches =
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No legacy wmfw. Optional generic wmfw and bin found. */
+ .part = "cs1234", .dsp_name = "dsp1",
+ .wmfw_optional = true,
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
+ .expected_searches =
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.bin",
+ },
+ { /* No legacy or generic wmfw. Generic bin found. */
+ .part = "cs1234", .dsp_name = "dsp1",
+ .wmfw_optional = true,
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
+ .expected_searches =
+ "cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss.bin",
+ },
+};
+KUNIT_ARRAY_PARAM(wm_adsp_fw_find_noqual,
+ wm_adsp_fw_find_noqual_cases,
+ wm_adsp_fw_find_test_param_desc);
+
+/*
+ * Tests for filename normalization. The system name and alsa prefix strings
+ * should be converted to lower-case and delimiters are converted to '-', except
+ * for '.' which is preserved.
+ */
+static const struct wm_adsp_fw_find_test_params wm_adsp_fw_find_normalization_cases[] = {
+ {
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "Vendor",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-vendor.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-vendor.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-vendor.bin",
+ },
+ {
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "Vendor Device",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-vendor-device.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-vendor-device.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-vendor-device.bin",
+ },
+ {
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "Vendor_Device",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-vendor-device.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-vendor-device.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-vendor-device.bin",
+ },
+ {
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "1234:56AB",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-1234-56ab.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-1234-56ab.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-1234-56ab.bin",
+ },
+
+ {
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "abc",
+ .alsa_name = "LEFT",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc-left.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc-left.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc-left.bin",
+ },
+ {
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "abc",
+ .alsa_name = "LEFT AMP",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc-left-amp.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc-left-amp.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc-left-amp.bin",
+ },
+ {
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "abc",
+ .alsa_name = "Left Amp",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc-left-amp.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc-left-amp.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc-left-amp.bin",
+ },
+ {
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "abc",
+ .alsa_name = "Amp_1",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc-amp-1.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc-amp-1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc-amp-1.bin",
+ },
+ {
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "abc",
+ .alsa_name = "cs1234.1",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc-cs1234.1.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc-cs1234.1.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc-cs1234.1.bin",
+ },
+};
+KUNIT_ARRAY_PARAM(wm_adsp_fw_find_normalization,
+ wm_adsp_fw_find_normalization_cases,
+ wm_adsp_fw_find_test_param_desc);
+
+/*
+ * Dummy directory content for regression tests.
+ * DSP part name and system name are used to select different available
+ * files.
+ *
+ * System:
+ * WFBF1111 = wmfw and bin fully-qualified
+ * WSBF1111 = wmfw system-qualified, bin fully-qualified
+ * WSBS1111 = wmfw and bin system-qualified
+ * WFXX1111 = wmfw fully-qualified, bin not present
+ * XXBF1111 = wmfw not present, bin fully-qualified
+ *
+ * Part:
+ * cs1234 = for testing fully-qualified configurations
+ * cs1234nobin = generic wmfw without a bin available
+ * wm1234 = legacy wmfw and bin
+ * wm1234nobin = legacy wmfw without bin
+ */
+static const char * const wm_adsp_fw_find_test_dir_all_files[] = {
+ "cirrus/cs1234-dsp1-mbc-vss-wfbf1111-amp1.wmfw",
+ "cirrus/cs1234-dsp1-mbc-vss-wfbf1111-l1u2.wmfw",
+ "cirrus/cs1234-dsp1-mbc-vss-wfbf1111.wmfw",
+ "cirrus/cs1234-dsp1-mbc-vss-wsbf1111.wmfw",
+ "cirrus/cs1234-dsp1-mbc-vss-wsbs1111.wmfw",
+ "cirrus/cs1234-dsp1-mbc-vss-wfxx1111.wmfw",
+ "cirrus/cs1234-dsp1-mbc-vss.wmfw",
+ "cirrus/cs1234nobin-dsp1-mbc-vss.wmfw",
+ "cirrus/wm1234-dsp1-mbc-vss.wmfw",
+ "cirrus/wm1234nobin-dsp1-mbc-vss.wmfw",
+ "wm1234-dsp1-mbc-vss.wmfw",
+ "wm1234nobin-dsp1-mbc-vss.wmfw",
+ "cirrus/cs1234-dsp1-mbc-vss-wfbf1111-amp1.bin",
+ "cirrus/cs1234-dsp1-mbc-vss-wfbf1111-l1u2.bin",
+ "cirrus/cs1234-dsp1-mbc-vss-wsbf1111-amp1.bin",
+ "cirrus/cs1234-dsp1-mbc-vss-wsbf1111-l1u2.bin",
+ "cirrus/cs1234-dsp1-mbc-vss-wsbs1111.bin",
+ "cirrus/cs1234-dsp1-mbc-vss-xxbf1111-amp1.bin",
+ "cirrus/cs1234-dsp1-mbc-vss.bin",
+ "cirrus/wm1234-dsp1-mbc-vss.bin",
+ "wm1234-dsp1-mbc-vss.bin",
+};
+
+/*
+ * Regression testing that a change in the search algorithm doesn't change
+ * which file is picked. This doesn't cover every possible combination, only
+ * those that are already in use and typical cases.
+ *
+ * It wouldn't be efficent to fully prove the algorithm this way (too many
+ * directory content combinations would be needed, and it only infers what the
+ * algorithm searched for, it doesn't prove exactly what searches were made).
+ * So the main testing is done by checking for the expected file searches.
+ * This regression test is independent of the search algorithm.
+ *
+ * The main tests already prove that the algorithm only searches for files
+ * with the correct qualifiers so we can assume that files with the wrong
+ * qualifiers would not be picked and there's no need to test for that here.
+ */
+static const struct wm_adsp_fw_find_test_params wm_adsp_fw_find_pick_cases[] = {
+ /*
+ * Amps
+ */
+ { /* Full info, wmfw and bin fully-qualified */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "WFBF1111",
+ .alsa_name = "amp1",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-wfbf1111-amp1.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-wfbf1111-amp1.bin",
+ .dir_files = wm_adsp_fw_find_test_dir_all_files,
+ },
+ { /* Full info, wmfw and bin fully-qualified */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "WFBF1111",
+ .alsa_name = "l1u2",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-wfbf1111-l1u2.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-wfbf1111-l1u2.bin",
+ .dir_files = wm_adsp_fw_find_test_dir_all_files,
+ },
+ { /* Full info, wmfw only system-qualified, bin fully-qualified */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "WSBF1111",
+ .alsa_name = "amp1",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-wsbf1111.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-wsbf1111-amp1.bin",
+ .dir_files = wm_adsp_fw_find_test_dir_all_files,
+ },
+ { /* Full info, wmfw only system-qualified, bin fully-qualified */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "WSBF1111",
+ .alsa_name = "l1u2",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-wsbf1111.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-wsbf1111-l1u2.bin",
+ .dir_files = wm_adsp_fw_find_test_dir_all_files,
+ },
+ { /* Full info, wmfw optional but present, and bin fully-qualified */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "WFBF1111",
+ .alsa_name = "amp1", .wmfw_optional = true,
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-wfbf1111-amp1.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-wfbf1111-amp1.bin",
+ .dir_files = wm_adsp_fw_find_test_dir_all_files,
+ },
+ { /* Full info, wmfw and bin only system-qualified */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "WSBS1111",
+ .alsa_name = "amp1",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-wsbs1111.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-wsbs1111.bin",
+ .dir_files = wm_adsp_fw_find_test_dir_all_files,
+ },
+ { /* Full info, wmfw optional but system-qualified wmfm present, bin fully-qualified */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "WSBF1111",
+ .alsa_name = "amp1", .wmfw_optional = true,
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-wsbf1111.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-wsbf1111-amp1.bin",
+ .dir_files = wm_adsp_fw_find_test_dir_all_files,
+ },
+ { /* Full info, wmfw optional not present, and bin fully-qualified */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "XXBF1111",
+ .alsa_name = "amp1", .wmfw_optional = true,
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-xxbf1111-amp1.bin",
+ .dir_files = wm_adsp_fw_find_test_dir_all_files,
+ },
+ { /* Full info, wmfw and bin fully-qualified, bin mandatory and present */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "WFBF1111",
+ .alsa_name = "amp1", .bin_mandatory = true,
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-wfbf1111-amp1.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss-wfbf1111-amp1.bin",
+ .dir_files = wm_adsp_fw_find_test_dir_all_files,
+ },
+ { /* Full info, wmfw and bin fully-qualified, bin mandatory but not present */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "WFXX1111",
+ .alsa_name = "amp1", .bin_mandatory = true,
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-wfxx1111.wmfw",
+ .dir_files = wm_adsp_fw_find_test_dir_all_files,
+ },
+ { /* Full info, wmfw optional but present, bin mandatory but not present */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "WFXX1111",
+ .alsa_name = "amp1", .wmfw_optional = true, .bin_mandatory = true,
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-wfxx1111.wmfw",
+ .dir_files = wm_adsp_fw_find_test_dir_all_files,
+ },
+ { /* Full info, wmfw and bin not present, generic fallbacks are present */
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "XXXX1111",
+ .alsa_name = "amp1",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
+ .dir_files = wm_adsp_fw_find_test_dir_all_files,
+ },
+ { /* Full info, wmfw and bin not present, generic wmfw present */
+ .part = "cs1234nobin", .dsp_name = "dsp1", .system_name = "XXXX1111",
+ .alsa_name = "amp1",
+ .expect_wmfw = "cirrus/cs1234nobin-dsp1-mbc-vss.wmfw",
+ .dir_files = wm_adsp_fw_find_test_dir_all_files,
+ },
+
+ /*
+ * Codecs
+ */
+ { /* No qualifiers. Generic wmfws exist, legacy should be chosen. */
+ .part = "wm1234nobin", .dsp_name = "dsp1",
+ .expect_wmfw = "wm1234nobin-dsp1-mbc-vss.wmfw",
+ .dir_files = wm_adsp_fw_find_test_dir_all_files,
+ },
+ { /* No qualifiers. Generic wmfw and bin exist, legacy should be chosen */
+ .part = "wm1234", .dsp_name = "dsp1",
+ .expect_wmfw = "wm1234-dsp1-mbc-vss.wmfw",
+ .expect_bin = "wm1234-dsp1-mbc-vss.bin",
+ .dir_files = wm_adsp_fw_find_test_dir_all_files,
+ },
+ { /* No qualifiers. New generic wmfw exists, no legacy files. */
+ .part = "cs1234nobin", .dsp_name = "dsp1",
+ .expect_wmfw = "cirrus/cs1234nobin-dsp1-mbc-vss.wmfw",
+ .dir_files = wm_adsp_fw_find_test_dir_all_files,
+ },
+ { /* No qualifiers. New generic wmfw and bin exist, no legacy files. */
+ .part = "cs1234", .dsp_name = "dsp1",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss.wmfw",
+ .expect_bin = "cirrus/cs1234-dsp1-mbc-vss.bin",
+ .dir_files = wm_adsp_fw_find_test_dir_all_files,
+ },
+};
+KUNIT_ARRAY_PARAM(wm_adsp_fw_find_pick,
+ wm_adsp_fw_find_pick_cases,
+ wm_adsp_fw_find_test_param_desc);
+
+static struct kunit_case wm_adsp_fw_find_test_cases[] = {
+ KUNIT_CASE_PARAM(wm_adsp_fw_find_test_search_order,
+ wm_adsp_fw_find_full_search_gen_params),
+
+ KUNIT_CASE_PARAM(wm_adsp_fw_find_test_search_order,
+ wm_adsp_fw_find_system_alsaname_gen_params),
+
+ KUNIT_CASE_PARAM(wm_adsp_fw_find_test_search_order,
+ wm_adsp_fw_find_system_gen_params),
+
+ KUNIT_CASE_PARAM(wm_adsp_fw_find_test_search_order,
+ wm_adsp_fw_find_alsaname_gen_params),
+
+ KUNIT_CASE_PARAM(wm_adsp_fw_find_test_search_order,
+ wm_adsp_fw_find_noqual_gen_params),
+
+ KUNIT_CASE_PARAM(wm_adsp_fw_find_test_search_order,
+ wm_adsp_fw_find_normalization_gen_params),
+
+ KUNIT_CASE_PARAM(wm_adsp_fw_find_test_pick_file,
+ wm_adsp_fw_find_pick_gen_params),
+
+ KUNIT_CASE(wm_adsp_fw_find_test_find_firmware_byindex),
+
+ { } /* terminator */
+};
+
+static struct kunit_suite wm_adsp_fw_find_test_suite = {
+ .name = "wm-adsp-fw-find",
+ .init = wm_adsp_fw_find_test_case_init,
+ .exit = wm_adsp_fw_find_test_case_exit,
+ .test_cases = wm_adsp_fw_find_test_cases,
+};
+
+kunit_test_suite(wm_adsp_fw_find_test_suite);
+
+MODULE_DESCRIPTION("KUnit test for Cirrus Logic wm_adsp driver");
+MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
+MODULE_LICENSE("GPL");
+MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
--
2.47.3
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 05/10] ASoC: wm_adsp: Remove duplicated code to find firmware file
2026-03-10 14:18 [PATCH 00/10] ASoC: wm_adsp: Some improvements to firmware file search Richard Fitzgerald
` (3 preceding siblings ...)
2026-03-10 14:18 ` [PATCH 04/10] ASoC: wm_adsp: Add kunit test for firmware file search Richard Fitzgerald
@ 2026-03-10 14:18 ` Richard Fitzgerald
2026-03-10 14:18 ` [PATCH 06/10] ASoC: wm_adsp: Use consistent error checks in wm_adsp_request_firmware_files() Richard Fitzgerald
` (6 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Richard Fitzgerald @ 2026-03-10 14:18 UTC (permalink / raw)
To: broonie; +Cc: linux-sound, linux-kernel, patches
The 3rd search case in wm_adsp_request_firmware_files() does exactly the
same bin file searches as the case immediately above it. Merge the
conditional from the 3rd case into the second case so the duplicated code
can be removed.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
sound/soc/codecs/wm_adsp.c | 27 +++++++--------------------
1 file changed, 7 insertions(+), 20 deletions(-)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 79695ead5788..b904d1e1b00c 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -828,9 +828,10 @@ VISIBLE_IF_KUNIT int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
}
if (system_name) {
- if (!wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename,
- cirrus_dir, system_name,
- NULL, "wmfw")) {
+ ret = wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename,
+ cirrus_dir, system_name,
+ NULL, "wmfw");
+ if (!ret || dsp->wmfw_optional) {
if (suffix)
wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
cirrus_dir, system_name,
@@ -840,26 +841,12 @@ VISIBLE_IF_KUNIT int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
cirrus_dir, system_name,
NULL, "bin");
- return 0;
+
+ if (*wmfw_firmware || (dsp->wmfw_optional && *coeff_firmware))
+ return 0;
}
}
- /* Check system-specific bin without wmfw before falling back to generic */
- if (dsp->wmfw_optional && system_name) {
- if (suffix)
- wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
- cirrus_dir, system_name,
- suffix, "bin");
-
- if (!*coeff_firmware)
- wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
- cirrus_dir, system_name,
- NULL, "bin");
-
- if (*coeff_firmware)
- return 0;
- }
-
/* Check legacy location */
if (!wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename,
"", NULL, NULL, "wmfw")) {
--
2.47.3
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 06/10] ASoC: wm_adsp: Use consistent error checks in wm_adsp_request_firmware_files()
2026-03-10 14:18 [PATCH 00/10] ASoC: wm_adsp: Some improvements to firmware file search Richard Fitzgerald
` (4 preceding siblings ...)
2026-03-10 14:18 ` [PATCH 05/10] ASoC: wm_adsp: Remove duplicated code to find firmware file Richard Fitzgerald
@ 2026-03-10 14:18 ` Richard Fitzgerald
2026-03-10 14:18 ` [PATCH 07/10] ASoC: wm_adsp: Convert '/' to '-' when normalizing firmware filenames Richard Fitzgerald
` (5 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Richard Fitzgerald @ 2026-03-10 14:18 UTC (permalink / raw)
To: broonie; +Cc: linux-sound, linux-kernel, patches
Use a consistent pattern of error checking in
wm_adsp_request_firmware_files().
- The integer return value of wm_adsp_request_firmware_file() reports
unrecoverable errors, for example -ENOMEM.
- A NULL struct firmware pointer is a valid result. This not an error,
not all DSPs require both files, some may not require any files.
Previously wm_adsp_request_firmware_files() was using a mix of checking
the return value and checking the struct firmware pointer to determine
whether a file was found. It wasn't checking for unrecoverable errors.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
sound/soc/codecs/wm_adsp.c | 92 +++++++++++++++++++++++++++-----------
1 file changed, 65 insertions(+), 27 deletions(-)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index b904d1e1b00c..69e573507df3 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -753,7 +753,7 @@ static int wm_adsp_request_firmware_file(struct wm_adsp *dsp,
struct cs_dsp *cs_dsp = &dsp->cs_dsp;
const char *fwf;
char *s, c;
- int ret = 0;
+ int ret;
if (dsp->fwf_name)
fwf = dsp->fwf_name;
@@ -791,15 +791,17 @@ static int wm_adsp_request_firmware_file(struct wm_adsp *dsp,
}
ret = wm_adsp_firmware_request(firmware, *filename, cs_dsp->dev);
- if (ret != 0) {
- adsp_dbg(dsp, "Failed to request '%s'\n", *filename);
+ if (ret < 0) {
+ adsp_dbg(dsp, "Failed to request '%s': %d\n", *filename, ret);
kfree(*filename);
*filename = NULL;
+ if (ret != -ENOENT)
+ return ret;
} else {
adsp_dbg(dsp, "Found '%s'\n", *filename);
}
- return ret;
+ return 0;
}
static const char * const cirrus_dir = "cirrus/";
@@ -817,12 +819,19 @@ VISIBLE_IF_KUNIT int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
suffix = dsp->fwf_suffix;
if (system_name && suffix) {
- if (!wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename,
- cirrus_dir, system_name,
- suffix, "wmfw")) {
- wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
- cirrus_dir, system_name,
- suffix, "bin");
+ ret = wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename,
+ cirrus_dir, system_name,
+ suffix, "wmfw");
+ if (ret < 0)
+ goto err;
+
+ if (*wmfw_firmware) {
+ ret = wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
+ cirrus_dir, system_name,
+ suffix, "bin");
+ if (ret < 0)
+ goto err;
+
return 0;
}
}
@@ -831,16 +840,27 @@ VISIBLE_IF_KUNIT int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
ret = wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename,
cirrus_dir, system_name,
NULL, "wmfw");
- if (!ret || dsp->wmfw_optional) {
- if (suffix)
- wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
- cirrus_dir, system_name,
- suffix, "bin");
+ if (ret < 0)
+ goto err;
- if (!*coeff_firmware)
- wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
- cirrus_dir, system_name,
- NULL, "bin");
+ if (*wmfw_firmware || dsp->wmfw_optional) {
+ if (suffix) {
+ ret = wm_adsp_request_firmware_file(dsp,
+ coeff_firmware, coeff_filename,
+ cirrus_dir, system_name,
+ suffix, "bin");
+ if (ret < 0)
+ goto err;
+ }
+
+ if (!*coeff_firmware) {
+ ret = wm_adsp_request_firmware_file(dsp,
+ coeff_firmware, coeff_filename,
+ cirrus_dir, system_name,
+ NULL, "bin");
+ if (ret < 0)
+ goto err;
+ }
if (*wmfw_firmware || (dsp->wmfw_optional && *coeff_firmware))
return 0;
@@ -848,19 +868,32 @@ VISIBLE_IF_KUNIT int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
}
/* Check legacy location */
- if (!wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename,
- "", NULL, NULL, "wmfw")) {
- wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
- "", NULL, NULL, "bin");
+ ret = wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename,
+ "", NULL, NULL, "wmfw");
+ if (ret < 0)
+ goto err;
+
+ if (*wmfw_firmware) {
+ ret = wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
+ "", NULL, NULL, "bin");
+ if (ret < 0)
+ goto err;
+
return 0;
}
/* Fall back to generic wmfw and optional matching bin */
ret = wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename,
cirrus_dir, NULL, NULL, "wmfw");
- if (!ret || dsp->wmfw_optional) {
- wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
- cirrus_dir, NULL, NULL, "bin");
+ if (ret < 0)
+ goto err;
+
+ if (*wmfw_firmware || dsp->wmfw_optional) {
+ ret = wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
+ cirrus_dir, NULL, NULL, "bin");
+ if (ret < 0)
+ goto err;
+
return 0;
}
@@ -869,7 +902,12 @@ VISIBLE_IF_KUNIT int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
dsp->fwf_name ? dsp->fwf_name : dsp->cs_dsp.name,
wm_adsp_fw[dsp->fw].file, system_name, suffix);
- return -ENOENT;
+ ret = -ENOENT;
+err:
+ wm_adsp_release_firmware_files(*wmfw_firmware, *wmfw_filename,
+ *coeff_firmware, *coeff_filename);
+
+ return ret;
}
EXPORT_SYMBOL_IF_KUNIT(wm_adsp_request_firmware_files);
--
2.47.3
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 07/10] ASoC: wm_adsp: Convert '/' to '-' when normalizing firmware filenames
2026-03-10 14:18 [PATCH 00/10] ASoC: wm_adsp: Some improvements to firmware file search Richard Fitzgerald
` (5 preceding siblings ...)
2026-03-10 14:18 ` [PATCH 06/10] ASoC: wm_adsp: Use consistent error checks in wm_adsp_request_firmware_files() Richard Fitzgerald
@ 2026-03-10 14:18 ` Richard Fitzgerald
2026-03-10 14:18 ` [PATCH 08/10] ASoC: wm_adsp: Add KUnit test cases for '/' in " Richard Fitzgerald
` (4 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Richard Fitzgerald @ 2026-03-10 14:18 UTC (permalink / raw)
To: broonie; +Cc: linux-sound, linux-kernel, patches
Don't preserve '/' in firmware filename fields - convert it to '-' like
other punctuation characters.
The code originally normalized the entire string, including the
directory prefix. To prevent breaking the directory it had to preserve
'/' characters in the name, but this meant that the system name and ALSA
prefix must not contain those characters.
It's trivial to skip the directory name prefix and start the
normalization after it, and that means the normalization does not need
to make a special case for '/'.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
sound/soc/codecs/wm_adsp.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 69e573507df3..034766760c86 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -776,16 +776,15 @@ static int wm_adsp_request_firmware_file(struct wm_adsp *dsp,
return -ENOMEM;
/*
- * Make sure that filename is lower-case and any non alpha-numeric
- * characters except full stop and forward slash are replaced with
- * hyphens.
+ * Make sure that filename after dir is lower-case and any non-alpha-numeric
+ * characters except full-stop are replaced with hyphens.
*/
- s = *filename;
+ s = *filename + strlen(dir);
while (*s) {
c = *s;
if (isalnum(c))
*s = tolower(c);
- else if ((c != '.') && (c != '/'))
+ else if (c != '.')
*s = '-';
s++;
}
--
2.47.3
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 08/10] ASoC: wm_adsp: Add KUnit test cases for '/' in firmware filenames
2026-03-10 14:18 [PATCH 00/10] ASoC: wm_adsp: Some improvements to firmware file search Richard Fitzgerald
` (6 preceding siblings ...)
2026-03-10 14:18 ` [PATCH 07/10] ASoC: wm_adsp: Convert '/' to '-' when normalizing firmware filenames Richard Fitzgerald
@ 2026-03-10 14:18 ` Richard Fitzgerald
2026-03-10 14:18 ` [PATCH 09/10] ASoC: wm_adsp: Use a struct to pass around firmware struct and filename Richard Fitzgerald
` (3 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Richard Fitzgerald @ 2026-03-10 14:18 UTC (permalink / raw)
To: broonie; +Cc: linux-sound, linux-kernel, patches
Add test cases that '/' in the system name or ALSA prefix are converted
to '-' in the firmware filename.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
sound/soc/codecs/wm_adsp_fw_find_test.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/sound/soc/codecs/wm_adsp_fw_find_test.c b/sound/soc/codecs/wm_adsp_fw_find_test.c
index 556221d38a50..11047851fd80 100644
--- a/sound/soc/codecs/wm_adsp_fw_find_test.c
+++ b/sound/soc/codecs/wm_adsp_fw_find_test.c
@@ -949,6 +949,13 @@ static const struct wm_adsp_fw_find_test_params wm_adsp_fw_find_normalization_ca
"cirrus/cs1234-dsp1-mbc-vss-vendor-device.wmfw "
"cirrus/cs1234-dsp1-mbc-vss-vendor-device.bin",
},
+ {
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "Vendor/Device",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-vendor-device.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-vendor-device.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-vendor-device.bin",
+ },
{
.part = "cs1234", .dsp_name = "dsp1", .system_name = "1234:56AB",
.expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-1234-56ab.wmfw",
@@ -997,6 +1004,14 @@ static const struct wm_adsp_fw_find_test_params wm_adsp_fw_find_normalization_ca
"cirrus/cs1234-dsp1-mbc-vss-abc-cs1234.1.wmfw "
"cirrus/cs1234-dsp1-mbc-vss-abc-cs1234.1.bin",
},
+ {
+ .part = "cs1234", .dsp_name = "dsp1", .system_name = "abc",
+ .alsa_name = "Spk/Jack",
+ .expect_wmfw = "cirrus/cs1234-dsp1-mbc-vss-abc-spk-jack.wmfw",
+ .expected_searches =
+ "cirrus/cs1234-dsp1-mbc-vss-abc-spk-jack.wmfw "
+ "cirrus/cs1234-dsp1-mbc-vss-abc-spk-jack.bin",
+ },
};
KUNIT_ARRAY_PARAM(wm_adsp_fw_find_normalization,
wm_adsp_fw_find_normalization_cases,
--
2.47.3
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 09/10] ASoC: wm_adsp: Use a struct to pass around firmware struct and filename
2026-03-10 14:18 [PATCH 00/10] ASoC: wm_adsp: Some improvements to firmware file search Richard Fitzgerald
` (7 preceding siblings ...)
2026-03-10 14:18 ` [PATCH 08/10] ASoC: wm_adsp: Add KUnit test cases for '/' in " Richard Fitzgerald
@ 2026-03-10 14:18 ` Richard Fitzgerald
2026-03-10 14:18 ` [PATCH 10/10] ASoC: wm_adsp: Combine some similar code in firmware file search Richard Fitzgerald
` (2 subsequent siblings)
11 siblings, 0 replies; 20+ messages in thread
From: Richard Fitzgerald @ 2026-03-10 14:18 UTC (permalink / raw)
To: broonie; +Cc: linux-sound, linux-kernel, patches
Bundle the pointers to struct firmware and its filename into a new
struct wm_adsp_fw_files. This simplifies passing these pointers around.
Changes are also needed to the test cases in wm_adsp_fw_find_test.c that
use this API.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
sound/soc/codecs/wm_adsp.c | 123 ++++++++++--------------
sound/soc/codecs/wm_adsp.h | 21 ++--
sound/soc/codecs/wm_adsp_fw_find_test.c | 47 +++------
3 files changed, 77 insertions(+), 114 deletions(-)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 034766760c86..1c480d59bd55 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -717,20 +717,15 @@ int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type,
}
EXPORT_SYMBOL_GPL(wm_adsp_read_ctl);
-VISIBLE_IF_KUNIT void wm_adsp_release_firmware_files(const struct firmware *wmfw_firmware,
- char *wmfw_filename,
- const struct firmware *coeff_firmware,
- char *coeff_filename)
+VISIBLE_IF_KUNIT void wm_adsp_release_firmware_files(struct wm_adsp_fw_files *fw)
{
- KUNIT_STATIC_STUB_REDIRECT(wm_adsp_release_firmware_files,
- wmfw_firmware, wmfw_filename,
- coeff_firmware, coeff_filename);
+ KUNIT_STATIC_STUB_REDIRECT(wm_adsp_release_firmware_files, fw);
- release_firmware(wmfw_firmware);
- kfree(wmfw_filename);
+ release_firmware(fw->wmfw.firmware);
+ kfree(fw->wmfw.filename);
- release_firmware(coeff_firmware);
- kfree(coeff_filename);
+ release_firmware(fw->coeff.firmware);
+ kfree(fw->coeff.filename);
}
EXPORT_SYMBOL_IF_KUNIT(wm_adsp_release_firmware_files);
@@ -745,7 +740,7 @@ VISIBLE_IF_KUNIT int wm_adsp_firmware_request(const struct firmware **firmware,
EXPORT_SYMBOL_IF_KUNIT(wm_adsp_firmware_request);
static int wm_adsp_request_firmware_file(struct wm_adsp *dsp,
- const struct firmware **firmware, char **filename,
+ struct wm_adsp_fw_file *fw,
const char *dir, const char *system_name,
const char *asoc_component_prefix,
const char *filetype)
@@ -761,25 +756,25 @@ static int wm_adsp_request_firmware_file(struct wm_adsp *dsp,
fwf = dsp->cs_dsp.name;
if (system_name && asoc_component_prefix)
- *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-%s.%s", dir, dsp->part,
- fwf, wm_adsp_fw[dsp->fw].file, system_name,
- asoc_component_prefix, filetype);
+ fw->filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s-%s.%s", dir, dsp->part,
+ fwf, wm_adsp_fw[dsp->fw].file, system_name,
+ asoc_component_prefix, filetype);
else if (system_name)
- *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s.%s", dir, dsp->part,
- fwf, wm_adsp_fw[dsp->fw].file, system_name,
- filetype);
+ fw->filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s-%s.%s", dir, dsp->part,
+ fwf, wm_adsp_fw[dsp->fw].file, system_name,
+ filetype);
else
- *filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s.%s", dir, dsp->part, fwf,
- wm_adsp_fw[dsp->fw].file, filetype);
+ fw->filename = kasprintf(GFP_KERNEL, "%s%s-%s-%s.%s", dir, dsp->part, fwf,
+ wm_adsp_fw[dsp->fw].file, filetype);
- if (*filename == NULL)
+ if (!fw->filename)
return -ENOMEM;
/*
* Make sure that filename after dir is lower-case and any non-alpha-numeric
* characters except full-stop are replaced with hyphens.
*/
- s = *filename + strlen(dir);
+ s = fw->filename + strlen(dir);
while (*s) {
c = *s;
if (isalnum(c))
@@ -789,15 +784,15 @@ static int wm_adsp_request_firmware_file(struct wm_adsp *dsp,
s++;
}
- ret = wm_adsp_firmware_request(firmware, *filename, cs_dsp->dev);
+ ret = wm_adsp_firmware_request(&fw->firmware, fw->filename, cs_dsp->dev);
if (ret < 0) {
- adsp_dbg(dsp, "Failed to request '%s': %d\n", *filename, ret);
- kfree(*filename);
- *filename = NULL;
+ adsp_dbg(dsp, "Failed to request '%s': %d\n", fw->filename, ret);
+ kfree(fw->filename);
+ fw->filename = NULL;
if (ret != -ENOENT)
return ret;
} else {
- adsp_dbg(dsp, "Found '%s'\n", *filename);
+ adsp_dbg(dsp, "Found '%s'\n", fw->filename);
}
return 0;
@@ -805,10 +800,7 @@ static int wm_adsp_request_firmware_file(struct wm_adsp *dsp,
static const char * const cirrus_dir = "cirrus/";
VISIBLE_IF_KUNIT int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
- const struct firmware **wmfw_firmware,
- char **wmfw_filename,
- const struct firmware **coeff_firmware,
- char **coeff_filename)
+ struct wm_adsp_fw_files *fw)
{
const char *system_name = dsp->system_name;
const char *suffix = dsp->component->name_prefix;
@@ -818,14 +810,14 @@ VISIBLE_IF_KUNIT int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
suffix = dsp->fwf_suffix;
if (system_name && suffix) {
- ret = wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename,
+ ret = wm_adsp_request_firmware_file(dsp, &fw->wmfw,
cirrus_dir, system_name,
suffix, "wmfw");
if (ret < 0)
goto err;
- if (*wmfw_firmware) {
- ret = wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
+ if (fw->wmfw.firmware) {
+ ret = wm_adsp_request_firmware_file(dsp, &fw->coeff,
cirrus_dir, system_name,
suffix, "bin");
if (ret < 0)
@@ -836,45 +828,43 @@ VISIBLE_IF_KUNIT int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
}
if (system_name) {
- ret = wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename,
+ ret = wm_adsp_request_firmware_file(dsp, &fw->wmfw,
cirrus_dir, system_name,
NULL, "wmfw");
if (ret < 0)
goto err;
- if (*wmfw_firmware || dsp->wmfw_optional) {
+ if (fw->wmfw.firmware || dsp->wmfw_optional) {
if (suffix) {
ret = wm_adsp_request_firmware_file(dsp,
- coeff_firmware, coeff_filename,
+ &fw->coeff,
cirrus_dir, system_name,
suffix, "bin");
if (ret < 0)
goto err;
}
- if (!*coeff_firmware) {
+ if (!fw->coeff.firmware) {
ret = wm_adsp_request_firmware_file(dsp,
- coeff_firmware, coeff_filename,
+ &fw->coeff,
cirrus_dir, system_name,
NULL, "bin");
if (ret < 0)
goto err;
}
- if (*wmfw_firmware || (dsp->wmfw_optional && *coeff_firmware))
+ if (fw->wmfw.firmware || (dsp->wmfw_optional && fw->coeff.firmware))
return 0;
}
}
/* Check legacy location */
- ret = wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename,
- "", NULL, NULL, "wmfw");
+ ret = wm_adsp_request_firmware_file(dsp, &fw->wmfw, "", NULL, NULL, "wmfw");
if (ret < 0)
goto err;
- if (*wmfw_firmware) {
- ret = wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
- "", NULL, NULL, "bin");
+ if (fw->wmfw.firmware) {
+ ret = wm_adsp_request_firmware_file(dsp, &fw->coeff, "", NULL, NULL, "bin");
if (ret < 0)
goto err;
@@ -882,13 +872,13 @@ VISIBLE_IF_KUNIT int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
}
/* Fall back to generic wmfw and optional matching bin */
- ret = wm_adsp_request_firmware_file(dsp, wmfw_firmware, wmfw_filename,
+ ret = wm_adsp_request_firmware_file(dsp, &fw->wmfw,
cirrus_dir, NULL, NULL, "wmfw");
if (ret < 0)
goto err;
- if (*wmfw_firmware || dsp->wmfw_optional) {
- ret = wm_adsp_request_firmware_file(dsp, coeff_firmware, coeff_filename,
+ if (fw->wmfw.firmware || dsp->wmfw_optional) {
+ ret = wm_adsp_request_firmware_file(dsp, &fw->coeff,
cirrus_dir, NULL, NULL, "bin");
if (ret < 0)
goto err;
@@ -903,8 +893,7 @@ VISIBLE_IF_KUNIT int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
ret = -ENOENT;
err:
- wm_adsp_release_firmware_files(*wmfw_firmware, *wmfw_filename,
- *coeff_firmware, *coeff_filename);
+ wm_adsp_release_firmware_files(fw);
return ret;
}
@@ -939,29 +928,23 @@ int wm_adsp1_event(struct snd_soc_dapm_widget *w,
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
struct wm_adsp *dsps = snd_soc_component_get_drvdata(component);
struct wm_adsp *dsp = &dsps[w->shift];
+ struct wm_adsp_fw_files fw = { 0 };
int ret = 0;
- char *wmfw_filename = NULL;
- const struct firmware *wmfw_firmware = NULL;
- char *coeff_filename = NULL;
- const struct firmware *coeff_firmware = NULL;
dsp->component = component;
switch (event) {
case SND_SOC_DAPM_POST_PMU:
- ret = wm_adsp_request_firmware_files(dsp,
- &wmfw_firmware, &wmfw_filename,
- &coeff_firmware, &coeff_filename);
+ ret = wm_adsp_request_firmware_files(dsp, &fw);
if (ret)
break;
ret = cs_dsp_adsp1_power_up(&dsp->cs_dsp,
- wmfw_firmware, wmfw_filename,
- coeff_firmware, coeff_filename,
+ fw.wmfw.firmware, fw.wmfw.filename,
+ fw.coeff.firmware, fw.coeff.filename,
wm_adsp_fw_text[dsp->fw]);
- wm_adsp_release_firmware_files(wmfw_firmware, wmfw_filename,
- coeff_firmware, coeff_filename);
+ wm_adsp_release_firmware_files(&fw);
break;
case SND_SOC_DAPM_PRE_PMD:
cs_dsp_adsp1_power_down(&dsp->cs_dsp);
@@ -1037,33 +1020,27 @@ EXPORT_SYMBOL_GPL(wm_adsp2_preloader_put);
int wm_adsp_power_up(struct wm_adsp *dsp, bool load_firmware)
{
+ struct wm_adsp_fw_files fw = { 0 };
int ret = 0;
- char *wmfw_filename = NULL;
- const struct firmware *wmfw_firmware = NULL;
- char *coeff_filename = NULL;
- const struct firmware *coeff_firmware = NULL;
if (load_firmware) {
- ret = wm_adsp_request_firmware_files(dsp,
- &wmfw_firmware, &wmfw_filename,
- &coeff_firmware, &coeff_filename);
+ ret = wm_adsp_request_firmware_files(dsp, &fw);
if (ret)
return ret;
}
- if (dsp->bin_mandatory && !coeff_firmware) {
+ if (dsp->bin_mandatory && !fw.coeff.firmware) {
ret = -ENOENT;
goto err;
}
ret = cs_dsp_power_up(&dsp->cs_dsp,
- wmfw_firmware, wmfw_filename,
- coeff_firmware, coeff_filename,
+ fw.wmfw.firmware, fw.wmfw.filename,
+ fw.coeff.firmware, fw.coeff.filename,
wm_adsp_fw_text[dsp->fw]);
err:
- wm_adsp_release_firmware_files(wmfw_firmware, wmfw_filename,
- coeff_firmware, coeff_filename);
+ wm_adsp_release_firmware_files(&fw);
return ret;
}
diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h
index b4d5bd321c0b..8922732479c2 100644
--- a/sound/soc/codecs/wm_adsp.h
+++ b/sound/soc/codecs/wm_adsp.h
@@ -79,6 +79,16 @@ struct wm_adsp {
SOC_ENUM_EXT(dspname " Firmware", wm_adsp_fw_enum[num], \
wm_adsp_fw_get, wm_adsp_fw_put)
+struct wm_adsp_fw_file {
+ const struct firmware *firmware;
+ char *filename;
+};
+
+struct wm_adsp_fw_files {
+ struct wm_adsp_fw_file wmfw;
+ struct wm_adsp_fw_file coeff;
+};
+
extern const struct soc_enum wm_adsp_fw_enum[];
int wm_adsp1_init(struct wm_adsp *dsp);
@@ -145,18 +155,11 @@ int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type,
#if IS_ENABLED(CONFIG_KUNIT)
const char *wm_adsp_get_fwf_name_by_index(int index);
-void wm_adsp_release_firmware_files(const struct firmware *wmfw_firmware,
- char *wmfw_filename,
- const struct firmware *coeff_firmware,
- char *coeff_filename);
+void wm_adsp_release_firmware_files(struct wm_adsp_fw_files *fw);
int wm_adsp_firmware_request(const struct firmware **firmware,
const char *filename,
struct device *dev);
-int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
- const struct firmware **wmfw_firmware,
- char **wmfw_filename,
- const struct firmware **coeff_firmware,
- char **coeff_filename);
+int wm_adsp_request_firmware_files(struct wm_adsp *dsp, struct wm_adsp_fw_files *fw);
#endif
#endif
diff --git a/sound/soc/codecs/wm_adsp_fw_find_test.c b/sound/soc/codecs/wm_adsp_fw_find_test.c
index 11047851fd80..44c26e991b35 100644
--- a/sound/soc/codecs/wm_adsp_fw_find_test.c
+++ b/sound/soc/codecs/wm_adsp_fw_find_test.c
@@ -16,10 +16,7 @@ KUNIT_DEFINE_ACTION_WRAPPER(_put_device_wrapper, put_device, struct device *);
struct wm_adsp_fw_find_test {
struct wm_adsp dsp;
- const struct firmware *found_wmfw_firmware;
- const struct firmware *found_bin_firmware;
- char *found_wmfw_filename;
- char *found_bin_filename;
+ struct wm_adsp_fw_files found_fw;
char searched_fw_files[768];
};
@@ -101,28 +98,24 @@ static void wm_adsp_fw_find_test_pick_file(struct kunit *test)
wm_adsp_firmware_request,
wm_adsp_fw_find_test_firmware_request_simple_stub);
- ret = wm_adsp_request_firmware_files(dsp,
- &priv->found_wmfw_firmware,
- &priv->found_wmfw_filename,
- &priv->found_bin_firmware,
- &priv->found_bin_filename);
+ ret = wm_adsp_request_firmware_files(dsp, &priv->found_fw);
kunit_deactivate_static_stub(test, wm_adsp_firmware_request);
KUNIT_EXPECT_EQ_MSG(test, ret,
(params->expect_wmfw || params->expect_bin) ? 0 : -ENOENT,
"%s\n", priv->searched_fw_files);
- KUNIT_EXPECT_EQ_MSG(test, !!priv->found_wmfw_filename, !!params->expect_wmfw,
+ KUNIT_EXPECT_EQ_MSG(test, !!priv->found_fw.wmfw.filename, !!params->expect_wmfw,
"%s\n", priv->searched_fw_files);
- KUNIT_EXPECT_EQ_MSG(test, !!priv->found_bin_filename, !!params->expect_bin,
+ KUNIT_EXPECT_EQ_MSG(test, !!priv->found_fw.coeff.filename, !!params->expect_bin,
"%s\n", priv->searched_fw_files);
if (params->expect_wmfw) {
- KUNIT_EXPECT_STREQ_MSG(test, priv->found_wmfw_filename, params->expect_wmfw,
+ KUNIT_EXPECT_STREQ_MSG(test, priv->found_fw.wmfw.filename, params->expect_wmfw,
"%s\n", priv->searched_fw_files);
}
if (params->expect_bin) {
- KUNIT_EXPECT_STREQ_MSG(test, priv->found_bin_filename, params->expect_bin,
+ KUNIT_EXPECT_STREQ_MSG(test, priv->found_fw.coeff.filename, params->expect_bin,
"%s\n", priv->searched_fw_files);
}
}
@@ -181,27 +174,23 @@ static void wm_adsp_fw_find_test_search_order(struct kunit *test)
wm_adsp_firmware_request,
wm_adsp_fw_find_test_firmware_request_stub);
- wm_adsp_request_firmware_files(dsp,
- &priv->found_wmfw_firmware,
- &priv->found_wmfw_filename,
- &priv->found_bin_firmware,
- &priv->found_bin_filename);
+ wm_adsp_request_firmware_files(dsp, &priv->found_fw);
kunit_deactivate_static_stub(test, wm_adsp_firmware_request);
KUNIT_EXPECT_STREQ(test, priv->searched_fw_files, params->expected_searches);
- KUNIT_EXPECT_EQ(test, !!priv->found_wmfw_filename, !!params->expect_wmfw);
+ KUNIT_EXPECT_EQ(test, !!priv->found_fw.wmfw.filename, !!params->expect_wmfw);
if (params->expect_wmfw)
- KUNIT_EXPECT_STREQ(test, priv->found_wmfw_filename, params->expect_wmfw);
+ KUNIT_EXPECT_STREQ(test, priv->found_fw.wmfw.filename, params->expect_wmfw);
- KUNIT_EXPECT_EQ(test, !!priv->found_bin_filename, !!params->expect_bin);
+ KUNIT_EXPECT_EQ(test, !!priv->found_fw.coeff.filename, !!params->expect_bin);
if (params->expect_bin)
- KUNIT_EXPECT_STREQ(test, priv->found_bin_filename, params->expect_bin);
+ KUNIT_EXPECT_STREQ(test, priv->found_fw.coeff.filename, params->expect_bin);
/* Either we get a filename and firmware, or neither */
- KUNIT_EXPECT_EQ(test, !!priv->found_wmfw_filename, !!priv->found_wmfw_firmware);
- KUNIT_EXPECT_EQ(test, !!priv->found_bin_filename, !!priv->found_bin_firmware);
+ KUNIT_EXPECT_EQ(test, !!priv->found_fw.wmfw.filename, !!priv->found_fw.wmfw.firmware);
+ KUNIT_EXPECT_EQ(test, !!priv->found_fw.coeff.filename, !!priv->found_fw.coeff.firmware);
}
static void wm_adsp_fw_find_test_find_firmware_byindex(struct kunit *test)
@@ -221,12 +210,7 @@ static void wm_adsp_fw_find_test_find_firmware_byindex(struct kunit *test)
wm_adsp_firmware_request,
wm_adsp_fw_find_test_firmware_request_stub);
- wm_adsp_request_firmware_files(dsp,
- &priv->found_wmfw_firmware,
- &priv->found_wmfw_filename,
- &priv->found_bin_firmware,
- &priv->found_bin_filename);
-
+ wm_adsp_request_firmware_files(dsp, &priv->found_fw);
kunit_deactivate_static_stub(test, wm_adsp_firmware_request);
KUNIT_EXPECT_NOT_NULL_MSG(test,
@@ -278,8 +262,7 @@ static void wm_adsp_fw_find_test_case_exit(struct kunit *test)
* dummies not allocated by the real request_firmware() call they
* must not be passed to release_firmware().
*/
- wm_adsp_release_firmware_files(NULL, priv->found_wmfw_filename,
- NULL, priv->found_bin_filename);
+ wm_adsp_release_firmware_files(&priv->found_fw);
}
static void wm_adsp_fw_find_test_param_desc(const struct wm_adsp_fw_find_test_params *param,
--
2.47.3
^ permalink raw reply related [flat|nested] 20+ messages in thread
* [PATCH 10/10] ASoC: wm_adsp: Combine some similar code in firmware file search
2026-03-10 14:18 [PATCH 00/10] ASoC: wm_adsp: Some improvements to firmware file search Richard Fitzgerald
` (8 preceding siblings ...)
2026-03-10 14:18 ` [PATCH 09/10] ASoC: wm_adsp: Use a struct to pass around firmware struct and filename Richard Fitzgerald
@ 2026-03-10 14:18 ` Richard Fitzgerald
2026-03-12 17:34 ` [PATCH 00/10] ASoC: wm_adsp: Some improvements to " Mark Brown
2026-03-13 14:58 ` Mark Brown
11 siblings, 0 replies; 20+ messages in thread
From: Richard Fitzgerald @ 2026-03-10 14:18 UTC (permalink / raw)
To: broonie; +Cc: linux-sound, linux-kernel, patches
In wm_adsp_request_firmware_files() squash the if (system_name && suffix)
and the following if (system_name) blocks together. This removes some
duplicated code.
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
---
sound/soc/codecs/wm_adsp.c | 49 +++++++++++++++++---------------------
1 file changed, 22 insertions(+), 27 deletions(-)
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 1c480d59bd55..a637e22c3929 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -804,47 +804,42 @@ VISIBLE_IF_KUNIT int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
{
const char *system_name = dsp->system_name;
const char *suffix = dsp->component->name_prefix;
+ bool require_bin_suffix = false;
int ret = 0;
if (dsp->fwf_suffix)
suffix = dsp->fwf_suffix;
- if (system_name && suffix) {
+ if (system_name) {
ret = wm_adsp_request_firmware_file(dsp, &fw->wmfw,
cirrus_dir, system_name,
suffix, "wmfw");
if (ret < 0)
goto err;
- if (fw->wmfw.firmware) {
+ if (suffix) {
+ if (fw->wmfw.firmware) {
+ require_bin_suffix = true;
+ } else {
+ /* Fallback to name without suffix */
+ ret = wm_adsp_request_firmware_file(dsp, &fw->wmfw,
+ cirrus_dir, system_name,
+ NULL, "wmfw");
+ if (ret < 0)
+ goto err;
+ }
+ }
+
+ /* Look for matching .bin file */
+ if (fw->wmfw.firmware || dsp->wmfw_optional) {
ret = wm_adsp_request_firmware_file(dsp, &fw->coeff,
cirrus_dir, system_name,
suffix, "bin");
if (ret < 0)
goto err;
- return 0;
- }
- }
-
- if (system_name) {
- ret = wm_adsp_request_firmware_file(dsp, &fw->wmfw,
- cirrus_dir, system_name,
- NULL, "wmfw");
- if (ret < 0)
- goto err;
-
- if (fw->wmfw.firmware || dsp->wmfw_optional) {
- if (suffix) {
- ret = wm_adsp_request_firmware_file(dsp,
- &fw->coeff,
- cirrus_dir, system_name,
- suffix, "bin");
- if (ret < 0)
- goto err;
- }
-
- if (!fw->coeff.firmware) {
+ if (suffix && !fw->coeff.firmware && !require_bin_suffix) {
+ /* Fallback to name without suffix */
ret = wm_adsp_request_firmware_file(dsp,
&fw->coeff,
cirrus_dir, system_name,
@@ -852,10 +847,10 @@ VISIBLE_IF_KUNIT int wm_adsp_request_firmware_files(struct wm_adsp *dsp,
if (ret < 0)
goto err;
}
-
- if (fw->wmfw.firmware || (dsp->wmfw_optional && fw->coeff.firmware))
- return 0;
}
+
+ if (fw->wmfw.firmware || (dsp->wmfw_optional && fw->coeff.firmware))
+ return 0;
}
/* Check legacy location */
--
2.47.3
^ permalink raw reply related [flat|nested] 20+ messages in thread
* Re: [PATCH 00/10] ASoC: wm_adsp: Some improvements to firmware file search
2026-03-10 14:18 [PATCH 00/10] ASoC: wm_adsp: Some improvements to firmware file search Richard Fitzgerald
` (9 preceding siblings ...)
2026-03-10 14:18 ` [PATCH 10/10] ASoC: wm_adsp: Combine some similar code in firmware file search Richard Fitzgerald
@ 2026-03-12 17:34 ` Mark Brown
2026-03-13 14:58 ` Mark Brown
11 siblings, 0 replies; 20+ messages in thread
From: Mark Brown @ 2026-03-12 17:34 UTC (permalink / raw)
To: Richard Fitzgerald; +Cc: linux-sound, linux-kernel, patches
On Tue, 10 Mar 2026 14:18:07 +0000, Richard Fitzgerald wrote:
> This series makes some improvements to the code that searches for firmware
> files.
>
> Patch 1 is a trivial patch to remove an unused function argument, before
> adding any new code that uses this API.
>
> Patches 2..4 add KUnit testing to prove that the subsequent changes don't
> break anything.
>
> [...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[01/10] ASoC: wm_adsp: Remove unused argument to wm_adsp_release_firmware_files()
commit: 1eadb7791ee5699ca58920ef705ce0934c814ece
[02/10] ASoC: wm_adsp: Add KUnit redirection stubs for firmware file search
commit: 70057cfe492d600c2b83598e8b8b64780b2ca147
[03/10] ASoC: wm_adsp: Export function for KUnit test to get firmware filenames
commit: b4e6b01191afb9516570437a7aff61019134fd59
[04/10] ASoC: wm_adsp: Add kunit test for firmware file search
commit: bf2d44d07de726b0393439cb4d4defc5cf89a4fc
[05/10] ASoC: wm_adsp: Remove duplicated code to find firmware file
commit: 2c7c27025374abbdeda201ad103ddf27e8079aec
[06/10] ASoC: wm_adsp: Use consistent error checks in wm_adsp_request_firmware_files()
commit: f8f0c68c75214e326c0d4cbcab8ecab882201f48
[07/10] ASoC: wm_adsp: Convert '/' to '-' when normalizing firmware filenames
commit: 66170cc7ed59fb7e1e192e53f1d690bd04e8c720
[08/10] ASoC: wm_adsp: Add KUnit test cases for '/' in firmware filenames
commit: d8a4c96082e6f5c7aaf6f3e101effe7ff0ea4d6e
[09/10] ASoC: wm_adsp: Use a struct to pass around firmware struct and filename
commit: 7bca3ca55ef53ca66fdf6e663290d0596a8f520d
[10/10] ASoC: wm_adsp: Combine some similar code in firmware file search
commit: 8fc5c7895185d1119ae76b509892a1d14e0bd483
All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying
to this mail.
Thanks,
Mark
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 00/10] ASoC: wm_adsp: Some improvements to firmware file search
2026-03-10 14:18 [PATCH 00/10] ASoC: wm_adsp: Some improvements to firmware file search Richard Fitzgerald
` (10 preceding siblings ...)
2026-03-12 17:34 ` [PATCH 00/10] ASoC: wm_adsp: Some improvements to " Mark Brown
@ 2026-03-13 14:58 ` Mark Brown
2026-03-17 15:37 ` Mark Brown
11 siblings, 1 reply; 20+ messages in thread
From: Mark Brown @ 2026-03-13 14:58 UTC (permalink / raw)
To: Richard Fitzgerald; +Cc: linux-sound, linux-kernel, patches
[-- Attachment #1: Type: text/plain, Size: 29838 bytes --]
On Tue, Mar 10, 2026 at 02:18:07PM +0000, Richard Fitzgerald wrote:
> This series makes some improvements to the code that searches for firmware
> files.
>
> Patch 1 is a trivial patch to remove an unused function argument, before
> adding any new code that uses this API.
>
> Patches 2..4 add KUnit testing to prove that the subsequent changes don't
> break anything.
>
> The remaining patches remove duplicated code and clean up some of the
> implementation.
Actually I'm seeing failures with this running on arm64, they were
missed by my testing due to issues with KUnit in -rc1, looking at this
clearly a lot of the problems are knock on results of an initial failure:
[14:52:36] ============ wm_adsp_fw_find_test_search_order ============
[14:52:36] [PASSED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name:amp1 expects:( )
[14:52:36] [PASSED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name:amp1 wmfw_optional expects:( )
[14:52:36] [PASSED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name: expects:( )
[14:52:36] [PASSED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name: wmfw_optional expects:( )
[14:52:36] [PASSED] cs1234 dsp1 fwf_name: system: alsa_name:amp1 expects:( )
[14:52:36] [PASSED] cs1234 dsp1 fwf_name: system: alsa_name:amp1 wmfw_optional expects:( )
[14:52:36] [PASSED] cs1234 dsp1 fwf_name:ao system:ABC123 alsa_name:amp1 expects:( )
[14:52:36] [PASSED] cs1234 dsp1 fwf_name:ao system:ABC123 alsa_name:amp1 wmfw_optional expects:( )
[14:52:36] ======== [PASSED] wm_adsp_fw_find_test_search_order ========
[14:52:36] ============ wm_adsp_fw_find_test_search_order ============
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name:amp1 expects:(cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name:amp1 wmfw_optional expects:(cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name:amp1 expects:(cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw cirrus/cs1234-dsp1-mbc
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name:amp1 wmfw_optional expects:(cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.wmfw cirrus/cs
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name:amp1 expects:(cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name:amp1 wmfw_optional expects:(cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name:amp1 expects:(cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw cirrus/cs1234-dsp1-mbc-vss-
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name:amp1 wmfw_optional expects:(cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw cirrus/cs1234-
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name:amp1 expects:(cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw cirrus/cs1234-dsp1-mbc-vss-
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name:amp1 wmfw_optional expects:(cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw cirrus/cs1234-
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name:amp1 wmfw_optional expects:( cirrus/cs1234-dsp1-mbc-vss-abc123-amp1.bin)
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name:amp1 wmfw_optional expects:( cirrus/cs1234-dsp1-mbc-vss-abc123.bin)
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name:amp1 expects:(cs1234-dsp1-mbc-vss.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name:amp1 wmfw_optional expects:(cs1234-dsp1-mbc-vss.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name:amp1 expects:(cs1234-dsp1-mbc-vss.wmfw cs1234-dsp1-mbc-vss.bin)
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name:amp1 wmfw_optional expects:(cs1234-dsp1-mbc-vss.wmfw cs1234-dsp1-mbc-vss.bin)
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name:amp1 expects:(cirrus/cs1234-dsp1-mbc-vss.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name:amp1 wmfw_optional expects:(cirrus/cs1234-dsp1-mbc-vss.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name:amp1 expects:(cirrus/cs1234-dsp1-mbc-vss.wmfw cirrus/cs1234-dsp1-mbc-vss.bin)
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name:amp1 wmfw_optional expects:(cirrus/cs1234-dsp1-mbc-vss.wmfw cirrus/cs1234-dsp1-mb
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name:amp1 wmfw_optional expects:( cirrus/cs1234-dsp1-mbc-vss.bin)
[14:52:36] Unable to handle kernel paging request at virtual address ffffffffc202b0c8
[14:52:36] Mem abort info:
[14:52:36] ESR = 0x0000000096000006
[14:52:36] EC = 0x25: DABT (current EL), IL = 32 bits
[14:52:36] SET = 0, FnV = 0
[14:52:36] EA = 0, S1PTW = 0
[14:52:36] FSC = 0x06: level 2 translation fault
[14:52:36] Data abort info:
[14:52:36] ISV = 0, ISS = 0x00000006, ISS2 = 0x00000000
[14:52:36] CM = 0, WnR = 0, TnD = 0, TagAccess = 0
[14:52:36] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
[14:52:36] swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000040e95000
[14:52:36] [ffffffffc202b0c8] pgd=0000000000000000, p4d=0000000041103403, pud=0000000041104403, pmd=0000000000000000
[14:52:36] Internal error: Oops: 0000000096000006 [#2] SMP
[14:52:36] CPU: 0 UID: 0 PID: 11523 Comm: kunit_try_catch Tainted: G D W N 7.0.0-rc3-ga7ea17ac86d4 #11 PREEMPTLAZY
[14:52:36] Tainted: [D]=DIE, [W]=WARN, [N]=TEST
[14:52:36] Hardware name: linux,dummy-virt (DT)
[14:52:36] pstate: a3400005 (NzCv daif +PAN -UAO +TCO +DIT -SSBS BTYPE=--)
[14:52:36] pc : kfree+0x38/0x2a0
[14:52:36] lr : release_firmware+0x28/0x6c
[14:52:36] sp : ffff80008348bda0
[14:52:36] x29: ffff80008348bda0 x28: 0000000000000000 x27: 0000000000000000
[14:52:36] x26: 0000000000000000 x25: 0000000000000000 x24: ffff800080fbb850
[14:52:36] x23: ffff8000803e9e80 x22: ffff800080fbb680 x21: ffff000006923b40
[14:52:36] x20: ffff800080ac3010 x19: ffffffffc202b0c0 x18: 0000000000000014
[14:52:36] x17: 00000000f7d33fac x16: 00000000fda59ba1 x15: 00000000e1f102aa
[14:52:36] x14: 000000000000026d x13: 0000000000000000 x12: ffff00003fddaf40
[14:52:36] x11: 00000000000000c0 x10: ffff0000045a26e8 x9 : 0000000000000000
[14:52:36] x8 : ffff00000a1e4cc0 x7 : 0000000000000000 x6 : 0000000000000001
[14:52:36] x5 : 000000000000003c x4 : ffff800080fbb898 x3 : ffff8000803e8820
[14:52:36] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffffffffc202b0c0
[14:52:36] Call trace:
[14:52:36] kfree+0x38/0x2a0 (P)
[14:52:36] release_firmware+0x28/0x6c
[14:52:36] wm_adsp_release_firmware_files+0x20/0x80
[14:52:36] wm_adsp_fw_find_test_case_exit+0x18/0x24
[14:52:36] kunit_try_run_case_cleanup+0x2c/0x44
[14:52:36] kunit_generic_run_threadfn_adapter+0x28/0x4c
[14:52:36] kthread+0x108/0x120
[14:52:36] ret_from_fork+0x10/0x20
[14:52:36] Code: d34cfe73 f2d83fe0 8b131813 aa1303e0 (f9400661)
[14:52:36] ---[ end trace 0000000000000000 ]---
[14:52:36] # wm_adsp_fw_find_test_search_order: try faulted: last line seen sound/soc/codecs/wm_adsp_fw_find_test.c:193
[14:52:36] # wm_adsp_fw_find_test_search_order: internal error occurred during test case cleanup: -4
[14:52:36] # wm_adsp_fw_find_test_search_order: pass:0 fail:21 skip:0 total:21
[14:52:36] ======== [FAILED] wm_adsp_fw_find_test_search_order ========
[14:52:36] ============ wm_adsp_fw_find_test_search_order ============
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name: expects:(cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name: wmfw_optional expects:(cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name: expects:(cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw cirrus/cs1234-dsp1-mbc-vss-abc1
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name: wmfw_optional expects:(cirrus/cs1234-dsp1-mbc-vss-abc123.wmfw cirrus/cs1234-dsp1
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name: wmfw_optional expects:( cirrus/cs1234-dsp1-mbc-vss-abc123.bin)
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name: expects:(cs1234-dsp1-mbc-vss.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name: wmfw_optional expects:(cs1234-dsp1-mbc-vss.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name: expects:(cs1234-dsp1-mbc-vss.wmfw cs1234-dsp1-mbc-vss.bin)
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name: wmfw_optional expects:(cs1234-dsp1-mbc-vss.wmfw cs1234-dsp1-mbc-vss.bin)
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name: expects:(cirrus/cs1234-dsp1-mbc-vss.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name: wmfw_optional expects:(cirrus/cs1234-dsp1-mbc-vss.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name: expects:(cirrus/cs1234-dsp1-mbc-vss.wmfw cirrus/cs1234-dsp1-mbc-vss.bin)
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name: wmfw_optional expects:(cirrus/cs1234-dsp1-mbc-vss.wmfw cirrus/cs1234-dsp1-mbc-vs
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:ABC123 alsa_name: wmfw_optional expects:( cirrus/cs1234-dsp1-mbc-vss.bin)
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] # wm_adsp_fw_find_test_search_order: pass:0 fail:14 skip:0 total:14
[14:52:36] ======== [FAILED] wm_adsp_fw_find_test_search_order ========
[14:52:36] ============ wm_adsp_fw_find_test_search_order ============
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system: alsa_name:amp1 expects:(cs1234-dsp1-mbc-vss.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system: alsa_name:amp1 wmfw_optional expects:(cs1234-dsp1-mbc-vss.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system: alsa_name:amp1 expects:(cs1234-dsp1-mbc-vss.wmfw cs1234-dsp1-mbc-vss.bin)
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system: alsa_name:amp1 wmfw_optional expects:(cs1234-dsp1-mbc-vss.wmfw cs1234-dsp1-mbc-vss.bin)
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system: alsa_name:amp1 expects:(cirrus/cs1234-dsp1-mbc-vss.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system: alsa_name:amp1 wmfw_optional expects:(cirrus/cs1234-dsp1-mbc-vss.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system: alsa_name:amp1 expects:(cirrus/cs1234-dsp1-mbc-vss.wmfw cirrus/cs1234-dsp1-mbc-vss.bin)
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system: alsa_name:amp1 wmfw_optional expects:(cirrus/cs1234-dsp1-mbc-vss.wmfw cirrus/cs1234-dsp1-mbc-vss.
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system: alsa_name:amp1 wmfw_optional expects:( cirrus/cs1234-dsp1-mbc-vss.bin)
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] # wm_adsp_fw_find_test_search_order: pass:0 fail:9 skip:0 total:9
[14:52:36] ======== [FAILED] wm_adsp_fw_find_test_search_order ========
[14:52:36] ============ wm_adsp_fw_find_test_search_order ============
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system: alsa_name: expects:(cs1234-dsp1-mbc-vss.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system: alsa_name: wmfw_optional expects:(cs1234-dsp1-mbc-vss.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system: alsa_name: expects:(cs1234-dsp1-mbc-vss.wmfw cs1234-dsp1-mbc-vss.bin)
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system: alsa_name: wmfw_optional expects:(cs1234-dsp1-mbc-vss.wmfw cs1234-dsp1-mbc-vss.bin)
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system: alsa_name: expects:(cirrus/cs1234-dsp1-mbc-vss.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system: alsa_name: wmfw_optional expects:(cirrus/cs1234-dsp1-mbc-vss.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system: alsa_name: expects:(cirrus/cs1234-dsp1-mbc-vss.wmfw cirrus/cs1234-dsp1-mbc-vss.bin)
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system: alsa_name: wmfw_optional expects:(cirrus/cs1234-dsp1-mbc-vss.wmfw cirrus/cs1234-dsp1-mbc-vss.bin)
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system: alsa_name: wmfw_optional expects:( cirrus/cs1234-dsp1-mbc-vss.bin)
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] # wm_adsp_fw_find_test_search_order: pass:0 fail:9 skip:0 total:9
[14:52:36] ======== [FAILED] wm_adsp_fw_find_test_search_order ========
[14:52:36] ============ wm_adsp_fw_find_test_search_order ============
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:Vendor alsa_name: expects:(cirrus/cs1234-dsp1-mbc-vss-vendor.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:Vendor Device alsa_name: expects:(cirrus/cs1234-dsp1-mbc-vss-vendor-device.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:Vendor_Device alsa_name: expects:(cirrus/cs1234-dsp1-mbc-vss-vendor-device.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:Vendor/Device alsa_name: expects:(cirrus/cs1234-dsp1-mbc-vss-vendor-device.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:1234:56AB alsa_name: expects:(cirrus/cs1234-dsp1-mbc-vss-1234-56ab.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:abc alsa_name:LEFT expects:(cirrus/cs1234-dsp1-mbc-vss-abc-left.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:abc alsa_name:LEFT AMP expects:(cirrus/cs1234-dsp1-mbc-vss-abc-left-amp.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:abc alsa_name:Left Amp expects:(cirrus/cs1234-dsp1-mbc-vss-abc-left-amp.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:abc alsa_name:Amp_1 expects:(cirrus/cs1234-dsp1-mbc-vss-abc-amp-1.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:abc alsa_name:cs1234.1 expects:(cirrus/cs1234-dsp1-mbc-vss-abc-cs1234.1.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:abc alsa_name:Spk/Jack expects:(cirrus/cs1234-dsp1-mbc-vss-abc-spk-jack.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_search_order: failed to initialize: -16
[14:52:36] # wm_adsp_fw_find_test_search_order: pass:0 fail:11 skip:0 total:11
[14:52:36] ======== [FAILED] wm_adsp_fw_find_test_search_order ========
[14:52:36] ============= wm_adsp_fw_find_test_pick_file ==============
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:WFBF1111 alsa_name:amp1 expects:(cirrus/cs1234-dsp1-mbc-vss-wfbf1111-amp1.wmfw cirrus/cs1234-dsp1
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_pick_file: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:WFBF1111 alsa_name:l1u2 expects:(cirrus/cs1234-dsp1-mbc-vss-wfbf1111-l1u2.wmfw cirrus/cs1234-dsp1
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_pick_file: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:WSBF1111 alsa_name:amp1 expects:(cirrus/cs1234-dsp1-mbc-vss-wsbf1111.wmfw cirrus/cs1234-dsp1-mbc-
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_pick_file: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:WSBF1111 alsa_name:l1u2 expects:(cirrus/cs1234-dsp1-mbc-vss-wsbf1111.wmfw cirrus/cs1234-dsp1-mbc-
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_pick_file: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:WFBF1111 alsa_name:amp1 wmfw_optional expects:(cirrus/cs1234-dsp1-mbc-vss-wfbf1111-amp1.wmfw cirru
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_pick_file: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:WSBS1111 alsa_name:amp1 expects:(cirrus/cs1234-dsp1-mbc-vss-wsbs1111.wmfw cirrus/cs1234-dsp1-mbc-
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_pick_file: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:WSBF1111 alsa_name:amp1 wmfw_optional expects:(cirrus/cs1234-dsp1-mbc-vss-wsbf1111.wmfw cirrus/cs1
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_pick_file: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:XXBF1111 alsa_name:amp1 wmfw_optional expects:( cirrus/cs1234-dsp1-mbc-vss-xxbf1111-amp1.bin)
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_pick_file: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:WFBF1111 alsa_name:amp1 expects:(cirrus/cs1234-dsp1-mbc-vss-wfbf1111-amp1.wmfw cirrus/cs1234-dsp1
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_pick_file: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:WFXX1111 alsa_name:amp1 expects:(cirrus/cs1234-dsp1-mbc-vss-wfxx1111.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_pick_file: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:WFXX1111 alsa_name:amp1 wmfw_optional expects:(cirrus/cs1234-dsp1-mbc-vss-wfxx1111.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_pick_file: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system:XXXX1111 alsa_name:amp1 expects:(cirrus/cs1234-dsp1-mbc-vss.wmfw cirrus/cs1234-dsp1-mbc-vss.bin)
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_pick_file: failed to initialize: -16
[14:52:36] [FAILED] cs1234nobin dsp1 fwf_name: system:XXXX1111 alsa_name:amp1 expects:(cirrus/cs1234nobin-dsp1-mbc-vss.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_pick_file: failed to initialize: -16
[14:52:36] [FAILED] wm1234nobin dsp1 fwf_name: system: alsa_name: expects:(wm1234nobin-dsp1-mbc-vss.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_pick_file: failed to initialize: -16
[14:52:36] [FAILED] wm1234 dsp1 fwf_name: system: alsa_name: expects:(wm1234-dsp1-mbc-vss.wmfw wm1234-dsp1-mbc-vss.bin)
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_pick_file: failed to initialize: -16
[14:52:36] [FAILED] cs1234nobin dsp1 fwf_name: system: alsa_name: expects:(cirrus/cs1234nobin-dsp1-mbc-vss.wmfw )
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_pick_file: failed to initialize: -16
[14:52:36] [FAILED] cs1234 dsp1 fwf_name: system: alsa_name: expects:(cirrus/cs1234-dsp1-mbc-vss.wmfw cirrus/cs1234-dsp1-mbc-vss.bin)
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_pick_file: failed to initialize: -16
[14:52:36] # wm_adsp_fw_find_test_pick_file: pass:0 fail:17 skip:0 total:17
[14:52:36] ========= [FAILED] wm_adsp_fw_find_test_pick_file ==========
[14:52:36] Error: Driver 'wm_adsp_test_drv' is already registered, aborting...
[14:52:36] # wm_adsp_fw_find_test_find_firmware_byindex: failed to initialize: -16
[14:52:36] [FAILED] wm_adsp_fw_find_test_find_firmware_byindex
[14:52:36] # module: snd_soc_wm_adsp_test
[14:52:36] # wm-adsp-fw-find: pass:1 fail:7 skip:0 total:8
[14:52:36] # Totals: pass:8 fail:82 skip:0 total:90
[14:52:36] ================= [FAILED] wm-adsp-fw-find =================
Failures: wm-adsp-fw-find.wm_adsp_fw_find_test_search_order, wm-adsp-fw-find.wm_adsp_fw_find_test_search_order, wm-adsp-fw-find.wm_adsp_fw_find_test_search_order, wm-adsp-fw-find.wm_adsp_fw_find_test_search_order, wm-adsp-fw-find.wm_adsp_fw_find_test_search_order, wm-adsp-fw-find.wm_adsp_fw_find_test_pick_file, wm-adsp-fw-find.wm_adsp_fw_find_test_find_firmware_byindex
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 00/10] ASoC: wm_adsp: Some improvements to firmware file search
2026-03-13 14:58 ` Mark Brown
@ 2026-03-17 15:37 ` Mark Brown
2026-03-17 15:52 ` Charles Keepax
0 siblings, 1 reply; 20+ messages in thread
From: Mark Brown @ 2026-03-17 15:37 UTC (permalink / raw)
To: Richard Fitzgerald; +Cc: linux-sound, linux-kernel, patches
[-- Attachment #1: Type: text/plain, Size: 798 bytes --]
On Fri, Mar 13, 2026 at 02:58:13PM +0000, Mark Brown wrote:
> On Tue, Mar 10, 2026 at 02:18:07PM +0000, Richard Fitzgerald wrote:
> > This series makes some improvements to the code that searches for firmware
> > files.
> > Patch 1 is a trivial patch to remove an unused function argument, before
> > adding any new code that uses this API.
> > Patches 2..4 add KUnit testing to prove that the subsequent changes don't
> > break anything.
> > The remaining patches remove duplicated code and clean up some of the
> > implementation.
> Actually I'm seeing failures with this running on arm64, they were
> missed by my testing due to issues with KUnit in -rc1, looking at this
> clearly a lot of the problems are knock on results of an initial failure:
Any updates on getting this fixed?
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 00/10] ASoC: wm_adsp: Some improvements to firmware file search
2026-03-17 15:37 ` Mark Brown
@ 2026-03-17 15:52 ` Charles Keepax
2026-03-17 17:47 ` Charles Keepax
0 siblings, 1 reply; 20+ messages in thread
From: Charles Keepax @ 2026-03-17 15:52 UTC (permalink / raw)
To: Mark Brown; +Cc: Richard Fitzgerald, linux-sound, linux-kernel, patches
On Tue, Mar 17, 2026 at 03:37:53PM +0000, Mark Brown wrote:
> On Fri, Mar 13, 2026 at 02:58:13PM +0000, Mark Brown wrote:
> > On Tue, Mar 10, 2026 at 02:18:07PM +0000, Richard Fitzgerald wrote:
>
> > > This series makes some improvements to the code that searches for firmware
> > > files.
>
> > > Patch 1 is a trivial patch to remove an unused function argument, before
> > > adding any new code that uses this API.
>
> > > Patches 2..4 add KUnit testing to prove that the subsequent changes don't
> > > break anything.
>
> > > The remaining patches remove duplicated code and clean up some of the
> > > implementation.
>
> > Actually I'm seeing failures with this running on arm64, they were
> > missed by my testing due to issues with KUnit in -rc1, looking at this
> > clearly a lot of the problems are knock on results of an initial failure:
>
> Any updates on getting this fixed?
Apologies Richard is on holiday this week. I will see if I can
find a moment to have a quick look.
Thanks,
Charles
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 00/10] ASoC: wm_adsp: Some improvements to firmware file search
2026-03-17 15:52 ` Charles Keepax
@ 2026-03-17 17:47 ` Charles Keepax
2026-03-17 18:11 ` Mark Brown
0 siblings, 1 reply; 20+ messages in thread
From: Charles Keepax @ 2026-03-17 17:47 UTC (permalink / raw)
To: Mark Brown; +Cc: Richard Fitzgerald, linux-sound, linux-kernel, patches
On Tue, Mar 17, 2026 at 03:52:33PM +0000, Charles Keepax wrote:
> On Tue, Mar 17, 2026 at 03:37:53PM +0000, Mark Brown wrote:
> > On Fri, Mar 13, 2026 at 02:58:13PM +0000, Mark Brown wrote:
> > > On Tue, Mar 10, 2026 at 02:18:07PM +0000, Richard Fitzgerald wrote:
> >
> > > > This series makes some improvements to the code that searches for firmware
> > > > files.
> >
> > > > Patch 1 is a trivial patch to remove an unused function argument, before
> > > > adding any new code that uses this API.
> >
> > > > Patches 2..4 add KUnit testing to prove that the subsequent changes don't
> > > > break anything.
> >
> > > > The remaining patches remove duplicated code and clean up some of the
> > > > implementation.
> >
> > > Actually I'm seeing failures with this running on arm64, they were
> > > missed by my testing due to issues with KUnit in -rc1, looking at this
> > > clearly a lot of the problems are knock on results of an initial failure:
> >
> > Any updates on getting this fixed?
>
> Apologies Richard is on holiday this week. I will see if I can
> find a moment to have a quick look.
The rabbit whole looks pretty deep on this one. As far as I can
see it fails adding the device because the device already exists
on the bus but this is the first time it added the device and also
I can find no evidence it even created a bus in the first place.
Feels like there is a large piece of my understanding of how
this is supposed to work that is missing. I think we might have
to wait for Richard to return on Monday, how much of a problem
is that from your end?
Thanks,
Charles
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 00/10] ASoC: wm_adsp: Some improvements to firmware file search
2026-03-17 17:47 ` Charles Keepax
@ 2026-03-17 18:11 ` Mark Brown
2026-03-18 9:31 ` Charles Keepax
0 siblings, 1 reply; 20+ messages in thread
From: Mark Brown @ 2026-03-17 18:11 UTC (permalink / raw)
To: Charles Keepax; +Cc: Richard Fitzgerald, linux-sound, linux-kernel, patches
[-- Attachment #1: Type: text/plain, Size: 758 bytes --]
On Tue, Mar 17, 2026 at 05:47:19PM +0000, Charles Keepax wrote:
> The rabbit whole looks pretty deep on this one. As far as I can
> see it fails adding the device because the device already exists
> on the bus but this is the first time it added the device and also
> I can find no evidence it even created a bus in the first place.
> Feels like there is a large piece of my understanding of how
> this is supposed to work that is missing. I think we might have
> to wait for Richard to return on Monday, how much of a problem
> is that from your end?
This is holding inclusion of any new ASoC code since last Thursday out
of -next, that's pretty disruptive really. It might be easiest to just
drop the changes and let Richard resubmit when he gets back.
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 00/10] ASoC: wm_adsp: Some improvements to firmware file search
2026-03-17 18:11 ` Mark Brown
@ 2026-03-18 9:31 ` Charles Keepax
2026-03-18 10:27 ` Charles Keepax
0 siblings, 1 reply; 20+ messages in thread
From: Charles Keepax @ 2026-03-18 9:31 UTC (permalink / raw)
To: Mark Brown; +Cc: Richard Fitzgerald, linux-sound, linux-kernel, patches
On Tue, Mar 17, 2026 at 06:11:23PM +0000, Mark Brown wrote:
> On Tue, Mar 17, 2026 at 05:47:19PM +0000, Charles Keepax wrote:
>
> > The rabbit whole looks pretty deep on this one. As far as I can
> > see it fails adding the device because the device already exists
> > on the bus but this is the first time it added the device and also
> > I can find no evidence it even created a bus in the first place.
> > Feels like there is a large piece of my understanding of how
> > this is supposed to work that is missing. I think we might have
> > to wait for Richard to return on Monday, how much of a problem
> > is that from your end?
>
> This is holding inclusion of any new ASoC code since last Thursday out
> of -next, that's pretty disruptive really. It might be easiest to just
> drop the changes and let Richard resubmit when he gets back.
Ok I will have a bit more of a gander today and chat to the boss
here, but I suspect you are right we may have to revert the
change. I will report back by end of today if not sooner.
Thanks,
Charles
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 00/10] ASoC: wm_adsp: Some improvements to firmware file search
2026-03-18 9:31 ` Charles Keepax
@ 2026-03-18 10:27 ` Charles Keepax
2026-03-18 11:15 ` Mark Brown
0 siblings, 1 reply; 20+ messages in thread
From: Charles Keepax @ 2026-03-18 10:27 UTC (permalink / raw)
To: Mark Brown; +Cc: Richard Fitzgerald, linux-sound, linux-kernel, patches
On Wed, Mar 18, 2026 at 09:31:41AM +0000, Charles Keepax wrote:
> On Tue, Mar 17, 2026 at 06:11:23PM +0000, Mark Brown wrote:
> > On Tue, Mar 17, 2026 at 05:47:19PM +0000, Charles Keepax wrote:
> >
> > > The rabbit whole looks pretty deep on this one. As far as I can
> > > see it fails adding the device because the device already exists
> > > on the bus but this is the first time it added the device and also
> > > I can find no evidence it even created a bus in the first place.
> > > Feels like there is a large piece of my understanding of how
> > > this is supposed to work that is missing. I think we might have
> > > to wait for Richard to return on Monday, how much of a problem
> > > is that from your end?
> >
> > This is holding inclusion of any new ASoC code since last Thursday out
> > of -next, that's pretty disruptive really. It might be easiest to just
> > drop the changes and let Richard resubmit when he gets back.
>
> Ok I will have a bit more of a gander today and chat to the boss
> here, but I suspect you are right we may have to revert the
> change. I will report back by end of today if not sooner.
Ok looking again with fresh eyes I think I have it. Turns out
most of my problems yesterday were just finding the right
incantations to get kunit to show me all the debug.
Patch incoming shortly.
Thanks,
Charles
^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH 00/10] ASoC: wm_adsp: Some improvements to firmware file search
2026-03-18 10:27 ` Charles Keepax
@ 2026-03-18 11:15 ` Mark Brown
0 siblings, 0 replies; 20+ messages in thread
From: Mark Brown @ 2026-03-18 11:15 UTC (permalink / raw)
To: Charles Keepax; +Cc: Richard Fitzgerald, linux-sound, linux-kernel, patches
[-- Attachment #1: Type: text/plain, Size: 558 bytes --]
On Wed, Mar 18, 2026 at 10:27:15AM +0000, Charles Keepax wrote:
> On Wed, Mar 18, 2026 at 09:31:41AM +0000, Charles Keepax wrote:
> > Ok I will have a bit more of a gander today and chat to the boss
> > here, but I suspect you are right we may have to revert the
> > change. I will report back by end of today if not sooner.
> Ok looking again with fresh eyes I think I have it. Turns out
> most of my problems yesterday were just finding the right
> incantations to get kunit to show me all the debug.
> Patch incoming shortly.
Awesome, thanks so much!
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2026-03-18 11:15 UTC | newest]
Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-10 14:18 [PATCH 00/10] ASoC: wm_adsp: Some improvements to firmware file search Richard Fitzgerald
2026-03-10 14:18 ` [PATCH 01/10] ASoC: wm_adsp: Remove unused argument to wm_adsp_release_firmware_files() Richard Fitzgerald
2026-03-10 14:18 ` [PATCH 02/10] ASoC: wm_adsp: Add KUnit redirection stubs for firmware file search Richard Fitzgerald
2026-03-10 14:18 ` [PATCH 03/10] ASoC: wm_adsp: Export function for KUnit test to get firmware filenames Richard Fitzgerald
2026-03-10 14:18 ` [PATCH 04/10] ASoC: wm_adsp: Add kunit test for firmware file search Richard Fitzgerald
2026-03-10 14:18 ` [PATCH 05/10] ASoC: wm_adsp: Remove duplicated code to find firmware file Richard Fitzgerald
2026-03-10 14:18 ` [PATCH 06/10] ASoC: wm_adsp: Use consistent error checks in wm_adsp_request_firmware_files() Richard Fitzgerald
2026-03-10 14:18 ` [PATCH 07/10] ASoC: wm_adsp: Convert '/' to '-' when normalizing firmware filenames Richard Fitzgerald
2026-03-10 14:18 ` [PATCH 08/10] ASoC: wm_adsp: Add KUnit test cases for '/' in " Richard Fitzgerald
2026-03-10 14:18 ` [PATCH 09/10] ASoC: wm_adsp: Use a struct to pass around firmware struct and filename Richard Fitzgerald
2026-03-10 14:18 ` [PATCH 10/10] ASoC: wm_adsp: Combine some similar code in firmware file search Richard Fitzgerald
2026-03-12 17:34 ` [PATCH 00/10] ASoC: wm_adsp: Some improvements to " Mark Brown
2026-03-13 14:58 ` Mark Brown
2026-03-17 15:37 ` Mark Brown
2026-03-17 15:52 ` Charles Keepax
2026-03-17 17:47 ` Charles Keepax
2026-03-17 18:11 ` Mark Brown
2026-03-18 9:31 ` Charles Keepax
2026-03-18 10:27 ` Charles Keepax
2026-03-18 11:15 ` Mark Brown
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox