[PATCH 2/2] ASoC: cs35l56: Cleanup if component_probe fails
From: Richard Fitzgerald
Date: Tue Jun 09 2026 - 08:14:00 EST
If cs35l56_component_probe() fails, call cs35l56_component_remove() to
clean up.
All the cleanup in cs35l56_component_remove() is the same cleanup that
would need to be done (at least partially) if cs35l56_component_probe()
fails. So calling cs35l56_component_remove() avoids convoluted cleanup
gotos and duplicated code in cs35l56_component_probe().
The only action in cs35l56_component_remove() that is nominally
dependent on having completed the component_probe() action is the call
to wm_adsp2_component_remove(). Though it is currently safe to call that
even if wm_adsp2_component_probe() was not called. However,
wm_adsp2_component_probe() has been trivially updated to check itself
whether it needs to cleanup.
Signed-off-by: Richard Fitzgerald <rf@xxxxxxxxxxxxxxxxxxxxx>
Fixes: e49611252900 ("ASoC: cs35l56: Add driver for Cirrus Logic CS35L56")
---
sound/soc/codecs/cs35l56.c | 13 ++++++++++++-
sound/soc/codecs/wm_adsp.c | 7 +++++++
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c
index 5de9cf3d0330..6e2d92ab98e1 100644
--- a/sound/soc/codecs/cs35l56.c
+++ b/sound/soc/codecs/cs35l56.c
@@ -1359,7 +1359,7 @@ VISIBLE_IF_KUNIT int cs35l56_set_fw_name(struct snd_soc_component *component)
}
EXPORT_SYMBOL_IF_KUNIT(cs35l56_set_fw_name);
-static int cs35l56_component_probe(struct snd_soc_component *component)
+static int _cs35l56_component_probe(struct snd_soc_component *component)
{
struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
struct cs35l56_private *cs35l56 = snd_soc_component_get_drvdata(component);
@@ -1459,6 +1459,17 @@ static void cs35l56_component_remove(struct snd_soc_component *component)
cs35l56->component = NULL;
}
+static int cs35l56_component_probe(struct snd_soc_component *component)
+{
+ int ret;
+
+ ret = _cs35l56_component_probe(component);
+ if (ret < 0)
+ cs35l56_component_remove(component);
+
+ return ret;
+}
+
static int cs35l56_set_bias_level(struct snd_soc_component *component,
enum snd_soc_bias_level level)
{
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index ca630c9948e4..baa75e7ff53b 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -1170,7 +1170,14 @@ EXPORT_SYMBOL_GPL(wm_adsp2_component_probe);
int wm_adsp2_component_remove(struct wm_adsp *dsp, struct snd_soc_component *component)
{
+ if (!dsp)
+ return 0;
+
+ if (!dsp->component)
+ return 0;
+
cs_dsp_cleanup_debugfs(&dsp->cs_dsp);
+ dsp->component = NULL;
return 0;
}
--
2.47.3