ASoC: wm8731: Disable the regulator when probing fails
authorZheyu Ma <zheyuma97@gmail.com>
Tue, 5 Apr 2022 12:10:38 +0000 (20:10 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 9 May 2022 07:14:39 +0000 (09:14 +0200)
[ Upstream commit 92ccbf17eeacf510cf1eed9c252d9332ca24f02d ]

When the driver fails during probing, the driver should disable the
regulator, not just handle it in wm8731_hw_init().

The following log reveals it:

[   17.812483] WARNING: CPU: 1 PID: 364 at drivers/regulator/core.c:2257 _regulator_put+0x3ec/0x4e0
[   17.815958] RIP: 0010:_regulator_put+0x3ec/0x4e0
[   17.824467] Call Trace:
[   17.824774]  <TASK>
[   17.825040]  regulator_bulk_free+0x82/0xe0
[   17.825514]  devres_release_group+0x319/0x3d0
[   17.825882]  i2c_device_probe+0x766/0x940
[   17.829198]  i2c_register_driver+0xb5/0x130

Signed-off-by: Zheyu Ma <zheyuma97@gmail.com>
Link: https://lore.kernel.org/r/20220405121038.4094051-1-zheyuma97@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
sound/soc/codecs/wm8731.c

index dcee7b2bd3d79decf5cf3daf2f3498ab0ee0ea14..859ebcec83838e82b1ed88179a9a59693942cbe5 100644 (file)
@@ -602,7 +602,7 @@ static int wm8731_hw_init(struct device *dev, struct wm8731_priv *wm8731)
        ret = wm8731_reset(wm8731->regmap);
        if (ret < 0) {
                dev_err(dev, "Failed to issue reset: %d\n", ret);
-               goto err_regulator_enable;
+               goto err;
        }
 
        /* Clear POWEROFF, keep everything else disabled */
@@ -619,10 +619,7 @@ static int wm8731_hw_init(struct device *dev, struct wm8731_priv *wm8731)
 
        regcache_mark_dirty(wm8731->regmap);
 
-err_regulator_enable:
-       /* Regulators will be enabled by bias management */
-       regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
-
+err:
        return ret;
 }
 
@@ -766,21 +763,27 @@ static int wm8731_i2c_probe(struct i2c_client *i2c,
                ret = PTR_ERR(wm8731->regmap);
                dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
                        ret);
-               return ret;
+               goto err_regulator_enable;
        }
 
        ret = wm8731_hw_init(&i2c->dev, wm8731);
        if (ret != 0)
-               return ret;
+               goto err_regulator_enable;
 
        ret = devm_snd_soc_register_component(&i2c->dev,
                        &soc_component_dev_wm8731, &wm8731_dai, 1);
        if (ret != 0) {
                dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
-               return ret;
+               goto err_regulator_enable;
        }
 
        return 0;
+
+err_regulator_enable:
+       /* Regulators will be enabled by bias management */
+       regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies);
+
+       return ret;
 }
 
 static int wm8731_i2c_remove(struct i2c_client *client)