Skip to content

Commit

Permalink
ASoC: codecs: wcd938x: fix regulator leaks on probe errors
Browse files Browse the repository at this point in the history
Make sure to disable and free the regulators on probe errors and on
driver unbind.

Fixes: 1657252 ("ASoC: codecs: wcd938x-sdw: add SoundWire driver")
Cc: stable@vger.kernel.org      # 5.14
Cc: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Signed-off-by: Johan Hovold <johan+linaro@kernel.org>
Link: https://lore.kernel.org/r/20231003155558.27079-5-johan+linaro@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Johan Hovold authored and Mark Brown committed Oct 9, 2023
1 parent da29b94 commit 69a026a
Showing 1 changed file with 15 additions and 3 deletions.
18 changes: 15 additions & 3 deletions sound/soc/codecs/wcd938x.c
Original file line number Diff line number Diff line change
Expand Up @@ -3325,8 +3325,10 @@ static int wcd938x_populate_dt_data(struct wcd938x_priv *wcd938x, struct device
return dev_err_probe(dev, ret, "Failed to get supplies\n");

ret = regulator_bulk_enable(WCD938X_MAX_SUPPLY, wcd938x->supplies);
if (ret)
if (ret) {
regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies);
return dev_err_probe(dev, ret, "Failed to enable supplies\n");
}

wcd938x_dt_parse_micbias_info(dev, wcd938x);

Expand Down Expand Up @@ -3592,13 +3594,13 @@ static int wcd938x_probe(struct platform_device *pdev)

ret = wcd938x_add_slave_components(wcd938x, dev, &match);
if (ret)
return ret;
goto err_disable_regulators;

wcd938x_reset(wcd938x);

ret = component_master_add_with_match(dev, &wcd938x_comp_ops, match);
if (ret)
return ret;
goto err_disable_regulators;

pm_runtime_set_autosuspend_delay(dev, 1000);
pm_runtime_use_autosuspend(dev);
Expand All @@ -3608,11 +3610,21 @@ static int wcd938x_probe(struct platform_device *pdev)
pm_runtime_idle(dev);

return 0;

err_disable_regulators:
regulator_bulk_disable(WCD938X_MAX_SUPPLY, wcd938x->supplies);
regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies);

return ret;
}

static void wcd938x_remove(struct platform_device *pdev)
{
struct wcd938x_priv *wcd938x = dev_get_drvdata(&pdev->dev);

component_master_del(&pdev->dev, &wcd938x_comp_ops);
regulator_bulk_disable(WCD938X_MAX_SUPPLY, wcd938x->supplies);
regulator_bulk_free(WCD938X_MAX_SUPPLY, wcd938x->supplies);
}

#if defined(CONFIG_OF)
Expand Down

0 comments on commit 69a026a

Please sign in to comment.