From 80b3f283e9616821ba2f121ed5e4b2e6af93d771 Mon Sep 17 00:00:00 2001 From: Mingxuan Guo Date: Tue, 13 Oct 2026 18:23:59 +0800 Subject: [PATCH] firmware: cs_dsp: add a KUnit test for the cs_dsp_run() error path Cover the case where the post_run client hook fails: cs_dsp_run() must return the error and the DSP must not be left marked as running, and a subsequent run must be able to start it again. The test fails without the previous patch and passes with it. Full suite run (UML, KUnit) on top of that patch: before: Ran 5829 tests: passed: 5825, failed: 4 (cs_dsp_test_run_error_clears_running in each of the four cs_dsp_callbacks_* suites) after: Ran 5829 tests: passed: 5829 Signed-off-by: Mingxuan Guo Reviewed-by: Richard Fitzgerald Link: https://patch.msgid.link/tencent_113ABD187DD2A0C99CB7D4003B81AB94DC07@qq.com Signed-off-by: Mark Brown --- .../cirrus/test/cs_dsp_test_callbacks.c | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/firmware/cirrus/test/cs_dsp_test_callbacks.c b/drivers/firmware/cirrus/test/cs_dsp_test_callbacks.c index e5a389808e5f..b6e141ec409f 100644 --- a/drivers/firmware/cirrus/test/cs_dsp_test_callbacks.c +++ b/drivers/firmware/cirrus/test/cs_dsp_test_callbacks.c @@ -36,6 +36,8 @@ struct cs_dsp_test_local { int num_post_stop; int num_watchdog_expired; + bool fail_post_run; + struct cs_dsp_coeff_ctl *passed_ctl[16]; struct cs_dsp *passed_dsp; }; @@ -106,6 +108,9 @@ static int cs_dsp_test_post_run_callback(struct cs_dsp *dsp) local->passed_dsp = dsp; local->num_post_run++; + if (local->fail_post_run) + return -EIO; + return 0; } @@ -198,6 +203,33 @@ static void cs_dsp_test_run_stop_callbacks(struct kunit *test) local->passed_dsp = NULL; } +static void cs_dsp_test_run_error_clears_running(struct kunit *test) +{ + struct cs_dsp_test *priv = test->priv; + struct cs_dsp_test_local *local = priv->local; + struct firmware *wmfw; + + wmfw = cs_dsp_mock_wmfw_get_firmware(local->wmfw_builder); + + KUNIT_EXPECT_EQ(test, + cs_dsp_power_up(priv->dsp, wmfw, "wmfw", NULL, NULL, "misc"), + 0); + + /* + * By the time the post_run hook runs, the core has been started. A + * failure there stops and disables the core again, so the DSP must not + * be left looking like it is running. + */ + local->fail_post_run = true; + KUNIT_EXPECT_EQ(test, cs_dsp_run(priv->dsp), -EIO); + KUNIT_EXPECT_FALSE(test, priv->dsp->running); + + /* and the next run must be able to start it again */ + local->fail_post_run = false; + KUNIT_EXPECT_EQ(test, cs_dsp_run(priv->dsp), 0); + KUNIT_EXPECT_TRUE(test, priv->dsp->running); +} + static void cs_dsp_test_ctl_v1_callbacks(struct kunit *test) { struct cs_dsp_test *priv = test->priv; @@ -609,6 +641,7 @@ KUNIT_ARRAY_PARAM(cs_dsp_no_callbacks, static struct kunit_case cs_dsp_callbacks_adsp2_wmfwv1_test_cases[] = { KUNIT_CASE_PARAM(cs_dsp_test_run_stop_callbacks, cs_dsp_callbacks_ops_gen_params), + KUNIT_CASE_PARAM(cs_dsp_test_run_error_clears_running, cs_dsp_callbacks_ops_gen_params), KUNIT_CASE_PARAM(cs_dsp_test_ctl_v1_callbacks, cs_dsp_callbacks_ops_gen_params), KUNIT_CASE_PARAM(cs_dsp_test_no_callbacks, cs_dsp_no_callbacks_gen_params), @@ -617,6 +650,7 @@ static struct kunit_case cs_dsp_callbacks_adsp2_wmfwv1_test_cases[] = { static struct kunit_case cs_dsp_callbacks_adsp2_wmfwv2_test_cases[] = { KUNIT_CASE_PARAM(cs_dsp_test_run_stop_callbacks, cs_dsp_callbacks_ops_gen_params), + KUNIT_CASE_PARAM(cs_dsp_test_run_error_clears_running, cs_dsp_callbacks_ops_gen_params), KUNIT_CASE_PARAM(cs_dsp_test_ctl_v2_callbacks, cs_dsp_callbacks_ops_gen_params), KUNIT_CASE_PARAM(cs_dsp_test_no_callbacks, cs_dsp_no_callbacks_gen_params), @@ -625,6 +659,7 @@ static struct kunit_case cs_dsp_callbacks_adsp2_wmfwv2_test_cases[] = { static struct kunit_case cs_dsp_callbacks_halo_test_cases[] = { KUNIT_CASE_PARAM(cs_dsp_test_run_stop_callbacks, cs_dsp_callbacks_ops_gen_params), + KUNIT_CASE_PARAM(cs_dsp_test_run_error_clears_running, cs_dsp_callbacks_ops_gen_params), KUNIT_CASE_PARAM(cs_dsp_test_ctl_v2_callbacks, cs_dsp_callbacks_ops_gen_params), KUNIT_CASE_PARAM(cs_dsp_test_no_callbacks, cs_dsp_no_callbacks_gen_params),