| From 07a4ba789f23687ecfec750f812d45d93992fb2d Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 11 Aug 2021 08:17:56 -0700 |
| Subject: ASoC: rt5682: Properly turn off regulators if wrong device ID |
| |
| From: Douglas Anderson <dianders@chromium.org> |
| |
| [ Upstream commit 772d44526e203c062171786e514373f129616278 ] |
| |
| When I booted up on a board that had a slightly different codec |
| stuffed on it, I got this message at bootup: |
| |
| rt5682 9-001a: Device with ID register 6749 is not rt5682 |
| |
| That's normal/expected, but what wasn't normal was the splat that I |
| got after: |
| |
| WARNING: CPU: 7 PID: 176 at drivers/regulator/core.c:2151 _regulator_put+0x150/0x158 |
| pc : _regulator_put+0x150/0x158 |
| ... |
| Call trace: |
| _regulator_put+0x150/0x158 |
| regulator_bulk_free+0x48/0x70 |
| devm_regulator_bulk_release+0x20/0x2c |
| release_nodes+0x1cc/0x244 |
| devres_release_all+0x44/0x60 |
| really_probe+0x17c/0x378 |
| ... |
| |
| This is because the error paths don't turn off the regulator. Let's |
| fix that. |
| |
| Fixes: 0ddce71c21f0 ("ASoC: rt5682: add rt5682 codec driver") |
| Fixes: 87b42abae99d ("ASoC: rt5682: Implement remove callback") |
| Signed-off-by: Douglas Anderson <dianders@chromium.org> |
| Reviewed-by: Stephen Boyd <swboyd@chromium.org> |
| Link: https://lore.kernel.org/r/20210811081751.v2.1.I4a1d9aa5d99e05aeee15c2768db600158d76cab8@changeid |
| Signed-off-by: Mark Brown <broonie@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| sound/soc/codecs/rt5682-i2c.c | 13 ++++++++++++- |
| 1 file changed, 12 insertions(+), 1 deletion(-) |
| |
| diff --git a/sound/soc/codecs/rt5682-i2c.c b/sound/soc/codecs/rt5682-i2c.c |
| index 4a56a52adab5..e559b965a0a6 100644 |
| --- a/sound/soc/codecs/rt5682-i2c.c |
| +++ b/sound/soc/codecs/rt5682-i2c.c |
| @@ -117,6 +117,13 @@ static struct snd_soc_dai_driver rt5682_dai[] = { |
| }, |
| }; |
| |
| +static void rt5682_i2c_disable_regulators(void *data) |
| +{ |
| + struct rt5682_priv *rt5682 = data; |
| + |
| + regulator_bulk_disable(ARRAY_SIZE(rt5682->supplies), rt5682->supplies); |
| +} |
| + |
| static int rt5682_i2c_probe(struct i2c_client *i2c, |
| const struct i2c_device_id *id) |
| { |
| @@ -157,6 +164,11 @@ static int rt5682_i2c_probe(struct i2c_client *i2c, |
| return ret; |
| } |
| |
| + ret = devm_add_action_or_reset(&i2c->dev, rt5682_i2c_disable_regulators, |
| + rt5682); |
| + if (ret) |
| + return ret; |
| + |
| ret = regulator_bulk_enable(ARRAY_SIZE(rt5682->supplies), |
| rt5682->supplies); |
| if (ret) { |
| @@ -285,7 +297,6 @@ static int rt5682_i2c_remove(struct i2c_client *client) |
| struct rt5682_priv *rt5682 = i2c_get_clientdata(client); |
| |
| rt5682_i2c_shutdown(client); |
| - regulator_bulk_disable(ARRAY_SIZE(rt5682->supplies), rt5682->supplies); |
| |
| return 0; |
| } |
| -- |
| 2.30.2 |
| |