]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ASoC: es8311: Fix clock leak and check update_bits in set_bias_level()
authorHsieh Hung-En <hungen3108@gmail.com>
Wed, 15 Apr 2026 03:02:52 +0000 (11:02 +0800)
committerMark Brown <broonie@kernel.org>
Thu, 16 Apr 2026 12:39:10 +0000 (13:39 +0100)
In es8311_set_bias_level(), the return value of
snd_soc_component_update_bits() was ignored. If this fails, not only
is the VMID selection not applied, but the previously enabled mclk
is left running, leading to an unbalanced clock reference count
(clock leak).

Check the return value and ensure clk_disable_unprepare() is called on
failure to maintain proper resource management.

Signed-off-by: Hsieh Hung-En <hungen3108@gmail.com>
Link: https://patch.msgid.link/20260415030252.5547-3-hungen3108@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/es8311.c

index 9e371e2d6eae8e638769230a1e8f7ed10b550dc6..564af5c04dbb8bb40c3f771dd66f3f4c223dbd54 100644 (file)
@@ -761,6 +761,7 @@ static int es8311_set_bias_level(struct snd_soc_component *component,
 {
        struct es8311_priv *es8311 = snd_soc_component_get_drvdata(component);
        struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
+       int ret;
 
        switch (level) {
        case SND_SOC_BIAS_ON:
@@ -769,17 +770,21 @@ static int es8311_set_bias_level(struct snd_soc_component *component,
                break;
        case SND_SOC_BIAS_STANDBY:
                if (snd_soc_dapm_get_bias_level(dapm) == SND_SOC_BIAS_OFF) {
-                       int ret = clk_prepare_enable(es8311->mclk);
+                       ret = clk_prepare_enable(es8311->mclk);
                        if (ret) {
                                dev_err(component->dev,
                                        "unable to prepare mclk\n");
                                return ret;
                        }
 
-                       snd_soc_component_update_bits(
-                               component, ES8311_SYS3,
-                               ES8311_SYS3_PDN_VMIDSEL_MASK,
-                               ES8311_SYS3_PDN_VMIDSEL_STARTUP_NORMAL_SPEED);
+                       ret = snd_soc_component_update_bits(
+                                     component, ES8311_SYS3,
+                                     ES8311_SYS3_PDN_VMIDSEL_MASK,
+                                     ES8311_SYS3_PDN_VMIDSEL_STARTUP_NORMAL_SPEED);
+                       if (ret < 0) {
+                               clk_disable_unprepare(es8311->mclk);
+                               return ret;
+                       }
                }
 
                break;