From 7ef99fcfbbac20ebec10d21a37aeaf8321de7829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Wed, 14 Oct 2026 22:06:01 +0200 Subject: [PATCH 1/8] ASoC: soc-link: Correct stream stop operations in snd_soc_link_trigger MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When snd_soc_link_trigger() is called to stop, pause push or suspend stream it should call soc_link_mark_pop() on proper target to reverse operation from trigger start, pause release or resume. Fixes: 6374f493d93b ("ASoC: soc-pcm: care trigger rollback") Signed-off-by: Amadeusz Sławiński Link: https://patch.msgid.link/20261014200608.118770-2-amade@asmblr.net Signed-off-by: Mark Brown --- sound/soc/soc-link.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/soc-link.c b/sound/soc/soc-link.c index 02fd68f2e702..50ff9ba3ac87 100644 --- a/sound/soc/soc-link.c +++ b/sound/soc/soc-link.c @@ -161,7 +161,7 @@ int snd_soc_link_trigger(struct snd_pcm_substream *substream, int cmd, break; ret = soc_link_trigger(substream, cmd); - soc_link_mark_pop(rtd, startup); + soc_link_mark_pop(rtd, trigger); } return ret; From 223ec2a93bec6c5ee859094c826fec78516a0bb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Wed, 14 Oct 2026 22:06:02 +0200 Subject: [PATCH 2/8] ASoC: ops: Fix return value in snd_soc_limit_volume() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As documented snd_soc_limit_volume() should return 0 on success, however at some point in time this promise was broken when snd_soc_clip_to_platform_max() was refactored, refactor it once again using __free() to automatically free struct snd_ctl_elem_value and return proper value. Fixes: 7e10d7242ea8 ("ASoC: ops: dynamically allocate struct snd_ctl_elem_value") Signed-off-by: Amadeusz Sławiński Link: https://patch.msgid.link/20261014200608.118770-3-amade@asmblr.net Signed-off-by: Mark Brown --- sound/soc/soc-ops.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c index 142f407e3939..b3a719604ec7 100644 --- a/sound/soc/soc-ops.c +++ b/sound/soc/soc-ops.c @@ -406,7 +406,7 @@ EXPORT_SYMBOL_GPL(snd_soc_put_volsw_sx); static int snd_soc_clip_to_platform_max(struct snd_kcontrol *kctl) { struct soc_mixer_control *mc = (struct soc_mixer_control *)kctl->private_value; - struct snd_ctl_elem_value *uctl; + struct snd_ctl_elem_value *uctl __free(kfree) = NULL; int ret; if (!mc->platform_max) @@ -418,7 +418,7 @@ static int snd_soc_clip_to_platform_max(struct snd_kcontrol *kctl) ret = kctl->get(kctl, uctl); if (ret < 0) - goto out; + return ret; if (uctl->value.integer.value[0] > mc->platform_max) uctl->value.integer.value[0] = mc->platform_max; @@ -428,10 +428,10 @@ static int snd_soc_clip_to_platform_max(struct snd_kcontrol *kctl) uctl->value.integer.value[1] = mc->platform_max; ret = kctl->put(kctl, uctl); + if (ret < 0) + return ret; -out: - kfree(uctl); - return ret; + return 0; } /** From 1641c1ba27abcd3ea3bba1232d9d817092f1b757 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Wed, 14 Oct 2026 22:06:03 +0200 Subject: [PATCH 3/8] ASoC: soc-topology-test: Check return value of kunit_device_register() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call to kunit_device_register() can fail. Check return result of register call. While at it introduce helper variable so that if it fails put_device is called on properly initialized variable. Fixes: e57cdff0ddc4 ("ASoC: topology: Replace fake root_device with kunit_device in tests") Signed-off-by: Amadeusz Sławiński Link: https://patch.msgid.link/20261014200608.118770-4-amade@asmblr.net Signed-off-by: Mark Brown --- sound/soc/soc-topology-test.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sound/soc/soc-topology-test.c b/sound/soc/soc-topology-test.c index bcfb52061133..8df845a196fe 100644 --- a/sound/soc/soc-topology-test.c +++ b/sound/soc/soc-topology-test.c @@ -24,8 +24,12 @@ static struct device *test_dev; static int snd_soc_tplg_test_init(struct kunit *test) { - test_dev = kunit_device_register(test, "sound-soc-topology-test"); - test_dev = get_device(test_dev); + struct device *dev; + + dev = kunit_device_register(test, "sound-soc-topology-test"); + if (IS_ERR(dev)) + return PTR_ERR(dev); + test_dev = get_device(dev); if (!test_dev) return -ENODEV; From 77dfd98b1642b9bc6c2312bd8b805c321fb878b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Wed, 14 Oct 2026 22:06:04 +0200 Subject: [PATCH 4/8] ASoC: soc-card-test: Check return value of kunit_device_register() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Call to kunit_device_register() can fail. Check return result of register call. While at it introduce helper variable so that if it fails put_device is called on properly initialized variable. Fixes: ef7784e41db7 ("ASoC: soc-card: Add KUnit test case for snd_soc_card_get_kcontrol") Signed-off-by: Amadeusz Sławiński Link: https://patch.msgid.link/20261014200608.118770-5-amade@asmblr.net Signed-off-by: Mark Brown --- sound/soc/soc-card-test.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sound/soc/soc-card-test.c b/sound/soc/soc-card-test.c index 47dfd8b1babc..610b8220786d 100644 --- a/sound/soc/soc-card-test.c +++ b/sound/soc/soc-card-test.c @@ -70,6 +70,7 @@ static void test_snd_soc_card_get_kcontrol(struct kunit *test) static int soc_card_test_case_init(struct kunit *test) { struct soc_card_test_priv *priv; + struct device *dev; int ret; priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); @@ -82,8 +83,10 @@ static int soc_card_test_case_init(struct kunit *test) if (!priv->card) return -ENOMEM; - priv->card_dev = kunit_device_register(test, "sound-soc-card-test"); - priv->card_dev = get_device(priv->card_dev); + dev = kunit_device_register(test, "sound-soc-card-test"); + if (IS_ERR(dev)) + return PTR_ERR(dev); + priv->card_dev = get_device(dev); if (!priv->card_dev) return -ENODEV; From fc081cdfc6b370f6b6853cdeb4313f92561770d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Wed, 14 Oct 2026 22:06:05 +0200 Subject: [PATCH 5/8] ASoC: soc-ac97: Fix error handling in snd_soc_new_ac97_component() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If call to snd_soc_ac97_init_gpio() fails, proper removal procedure should mirror snd_soc_free_ac97_component() behaviour and call device_del() before put_device(). Fixes: 9bf5c3d11f1f ("ASoC: ac97: add gpio chip") Signed-off-by: Amadeusz Sławiński Link: https://patch.msgid.link/20261014200608.118770-6-amade@asmblr.net Signed-off-by: Mark Brown --- sound/soc/soc-ac97.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sound/soc/soc-ac97.c b/sound/soc/soc-ac97.c index 5f81e3606655..5c573c8dc249 100644 --- a/sound/soc/soc-ac97.c +++ b/sound/soc/soc-ac97.c @@ -241,10 +241,12 @@ struct snd_ac97 *snd_soc_new_ac97_component(struct snd_soc_component *component, ret = snd_soc_ac97_init_gpio(ac97, component); if (ret) - goto err_put_device; + goto err_del_device; return ac97; +err_del_device: + device_del(&ac97->dev); err_put_device: put_device(&ac97->dev); return ERR_PTR(ret); From 9d4bab22932fb6202a4a4e9cbe5e719ad6b3a438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Wed, 14 Oct 2026 22:06:06 +0200 Subject: [PATCH 6/8] ASoC: soc-ac97: Fix debug message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Seems like copy paste mistake, it should have been input, as in the name of the function. Signed-off-by: Amadeusz Sławiński Link: https://patch.msgid.link/20261014200608.118770-7-amade@asmblr.net Signed-off-by: Mark Brown --- sound/soc/soc-ac97.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/soc-ac97.c b/sound/soc/soc-ac97.c index 5c573c8dc249..9d38b38d88df 100644 --- a/sound/soc/soc-ac97.c +++ b/sound/soc/soc-ac97.c @@ -69,7 +69,7 @@ static int snd_soc_ac97_gpio_direction_in(struct gpio_chip *chip, { struct snd_soc_component *component = gpio_to_component(chip); - dev_dbg(component->dev, "set gpio %d to output\n", offset); + dev_dbg(component->dev, "set gpio %d to input\n", offset); return snd_soc_component_update_bits(component, AC97_GPIO_CFG, 1 << offset, 1 << offset); } From 9df30adce80dd6b0646e58c12a4cf7c6c88d0778 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Wed, 14 Oct 2026 22:06:07 +0200 Subject: [PATCH 7/8] ASoC: soc-component: Fix return type of snd_soc_pcm_component_pointer() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both caller and pointer callback expect the return value to be snd_pcm_uframes_t, however it was defined incorrectly leading to potential truncation of returned value. Fixes: 0035e2565b93 ("ASoC: soc-component: add snd_soc_pcm_component_pointer()") Signed-off-by: Amadeusz Sławiński Link: https://patch.msgid.link/20261014200608.118770-8-amade@asmblr.net Signed-off-by: Mark Brown --- include/sound/soc-component.h | 2 +- sound/soc/soc-component.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/sound/soc-component.h b/include/sound/soc-component.h index ac5e9412582e..ba860e28eec1 100644 --- a/include/sound/soc-component.h +++ b/include/sound/soc-component.h @@ -432,7 +432,7 @@ int snd_soc_component_compr_set_metadata(struct snd_compr_stream *cstream, int snd_soc_component_compr_get_metadata(struct snd_compr_stream *cstream, struct snd_compr_metadata *metadata); -int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream); +snd_pcm_uframes_t snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream); int snd_soc_pcm_component_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg); int snd_soc_pcm_component_sync_stop(struct snd_pcm_substream *substream); diff --git a/sound/soc/soc-component.c b/sound/soc/soc-component.c index 34efb270ce29..746fa4f54450 100644 --- a/sound/soc/soc-component.c +++ b/sound/soc/soc-component.c @@ -920,7 +920,7 @@ int snd_soc_component_test_bits(struct snd_soc_component *component, } EXPORT_SYMBOL_GPL(snd_soc_component_test_bits); -int snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream) +snd_pcm_uframes_t snd_soc_pcm_component_pointer(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); struct snd_soc_component *component; From 568406bc832e7e9e333e2ab05aafd0b83ffb9610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amadeusz=20S=C5=82awi=C5=84ski?= Date: Wed, 14 Oct 2026 22:06:08 +0200 Subject: [PATCH 8/8] ASoC: soc-dapm: Remove widget from cache on removal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a single DAPM widget is removed, it also needs to be removed from the widget cache to prevent dapm_wcache_lookup() from using a dangling pointer when checking if a widget is in cache. Since widgets may be cached across different DAPM contexts on the card (e.g. card routes), clear any matching cache entries across all DAPM contexts on the card. Since dapm_free_widgets() calls snd_soc_dapm_free_widget() anyway, it does not need to clear cache anymore. Signed-off-by: Amadeusz Sławiński Link: https://patch.msgid.link/20261014200608.118770-9-amade@asmblr.net Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 74be5e209493..7455160b11fe 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -2869,6 +2869,7 @@ static void dapm_free_path(struct snd_soc_dapm_path *path) */ void snd_soc_dapm_free_widget(struct snd_soc_dapm_widget *w) { + struct snd_soc_dapm_context *d; struct snd_soc_dapm_path *p, *next_p; enum snd_soc_dapm_direction dir; @@ -2889,6 +2890,22 @@ void snd_soc_dapm_free_widget(struct snd_soc_dapm_widget *w) dapm_debugfs_free_widget(w); + if (w->dapm) { + if (w->dapm->card) { + for_each_card_dapms(w->dapm->card, d) { + if (d->wcache_sink == w) + d->wcache_sink = NULL; + if (d->wcache_source == w) + d->wcache_source = NULL; + } + } else { + if (w->dapm->wcache_sink == w) + w->dapm->wcache_sink = NULL; + if (w->dapm->wcache_source == w) + w->dapm->wcache_source = NULL; + } + } + kfree(w->kcontrols); kfree_const(w->name); kfree_const(w->sname); @@ -2906,9 +2923,6 @@ static void dapm_free_widgets(struct snd_soc_dapm_context *dapm) continue; snd_soc_dapm_free_widget(w); } - - dapm->wcache_sink = NULL; - dapm->wcache_source = NULL; } static struct snd_soc_dapm_widget *dapm_find_widget(