diff options
author | Charles Keepax <ckeepax@opensource.cirrus.com> | 2021-05-10 14:13:56 +0100 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2021-05-10 17:27:54 +0100 |
commit | e2bb1077cee4d13dc85d53d76deac73b24d7f845 (patch) | |
tree | 04d4d1f8b7c34e75808c102ec7d46a950e89b4fa | |
parent | 26495252fe0d1ebf548c02cb63b51abae5d5e5a3 (diff) | |
download | linux-e2bb1077cee4d13dc85d53d76deac73b24d7f845.tar.gz |
ASoC: cs43130: Minor error paths fixups
Correct some unchecked re-allocations of ret whilst reading the device
ID and ensure the hardware state is returned to off on the error
paths.
Reported-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20210510131357.17170-10-ckeepax@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | sound/soc/codecs/cs43130.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/sound/soc/codecs/cs43130.c b/sound/soc/codecs/cs43130.c index 80bc7c10ed75..642338cdc8b6 100644 --- a/sound/soc/codecs/cs43130.c +++ b/sound/soc/codecs/cs43130.c @@ -36,6 +36,7 @@ #include <sound/jack.h> #include "cs43130.h" +#include "cirrus_legacy.h" static const struct reg_default cs43130_reg_defaults[] = { {CS43130_SYS_CLK_CTL_1, 0x06}, @@ -2424,9 +2425,8 @@ static int cs43130_i2c_probe(struct i2c_client *client, { struct cs43130_private *cs43130; int ret; - unsigned int devid = 0; unsigned int reg; - int i; + int i, devid; cs43130 = devm_kzalloc(&client->dev, sizeof(*cs43130), GFP_KERNEL); if (!cs43130) @@ -2464,20 +2464,21 @@ static int cs43130_i2c_probe(struct i2c_client *client, cs43130->reset_gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_LOW); - if (IS_ERR(cs43130->reset_gpio)) - return PTR_ERR(cs43130->reset_gpio); + if (IS_ERR(cs43130->reset_gpio)) { + ret = PTR_ERR(cs43130->reset_gpio); + goto err_supplies; + } gpiod_set_value_cansleep(cs43130->reset_gpio, 1); usleep_range(2000, 2050); - ret = regmap_read(cs43130->regmap, CS43130_DEVID_AB, ®); - - devid = (reg & 0xFF) << 12; - ret = regmap_read(cs43130->regmap, CS43130_DEVID_CD, ®); - devid |= (reg & 0xFF) << 4; - ret = regmap_read(cs43130->regmap, CS43130_DEVID_E, ®); - devid |= (reg & 0xF0) >> 4; + devid = cirrus_read_device_id(cs43130->regmap, CS43130_DEVID_AB); + if (devid < 0) { + ret = devid; + dev_err(&client->dev, "Failed to read device ID: %d\n", ret); + goto err; + } switch (devid) { case CS43130_CHIP_ID: @@ -2517,7 +2518,7 @@ static int cs43130_i2c_probe(struct i2c_client *client, "cs43130", cs43130); if (ret != 0) { dev_err(&client->dev, "Failed to request IRQ: %d\n", ret); - return ret; + goto err; } cs43130->mclk_int_src = CS43130_MCLK_SRC_RCO; @@ -2576,7 +2577,13 @@ static int cs43130_i2c_probe(struct i2c_client *client, CS43130_XSP_3ST_MASK, 0); return 0; + err: + gpiod_set_value_cansleep(cs43130->reset_gpio, 0); +err_supplies: + regulator_bulk_disable(ARRAY_SIZE(cs43130->supplies), + cs43130->supplies); + return ret; } |