Commit 5628560e authored by Takashi Iwai's avatar Takashi Iwai Committed by Mark Brown

ASoC: nau8824: Fix semaphore unbalance at error paths

The semaphore of nau8824 wasn't properly unlocked at some error
handling code paths, hence this may result in the unbalance (and
potential lock-up).  Fix them to handle the semaphore up properly.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Link: https://lore.kernel.org/r/20220823081000.2965-3-tiwai@suse.deSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent cf507187
...@@ -1043,6 +1043,7 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream, ...@@ -1043,6 +1043,7 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_component *component = dai->component; struct snd_soc_component *component = dai->component;
struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component); struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
unsigned int val_len = 0, osr, ctrl_val, bclk_fs, bclk_div; unsigned int val_len = 0, osr, ctrl_val, bclk_fs, bclk_div;
int err = -EINVAL;
nau8824_sema_acquire(nau8824, HZ); nau8824_sema_acquire(nau8824, HZ);
...@@ -1059,7 +1060,7 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream, ...@@ -1059,7 +1060,7 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream,
osr &= NAU8824_DAC_OVERSAMPLE_MASK; osr &= NAU8824_DAC_OVERSAMPLE_MASK;
if (nau8824_clock_check(nau8824, substream->stream, if (nau8824_clock_check(nau8824, substream->stream,
nau8824->fs, osr)) nau8824->fs, osr))
return -EINVAL; goto error;
regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER, regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER,
NAU8824_CLK_DAC_SRC_MASK, NAU8824_CLK_DAC_SRC_MASK,
osr_dac_sel[osr].clk_src << NAU8824_CLK_DAC_SRC_SFT); osr_dac_sel[osr].clk_src << NAU8824_CLK_DAC_SRC_SFT);
...@@ -1069,7 +1070,7 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream, ...@@ -1069,7 +1070,7 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream,
osr &= NAU8824_ADC_SYNC_DOWN_MASK; osr &= NAU8824_ADC_SYNC_DOWN_MASK;
if (nau8824_clock_check(nau8824, substream->stream, if (nau8824_clock_check(nau8824, substream->stream,
nau8824->fs, osr)) nau8824->fs, osr))
return -EINVAL; goto error;
regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER, regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER,
NAU8824_CLK_ADC_SRC_MASK, NAU8824_CLK_ADC_SRC_MASK,
osr_adc_sel[osr].clk_src << NAU8824_CLK_ADC_SRC_SFT); osr_adc_sel[osr].clk_src << NAU8824_CLK_ADC_SRC_SFT);
...@@ -1090,7 +1091,7 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream, ...@@ -1090,7 +1091,7 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream,
else if (bclk_fs <= 256) else if (bclk_fs <= 256)
bclk_div = 0; bclk_div = 0;
else else
return -EINVAL; goto error;
regmap_update_bits(nau8824->regmap, regmap_update_bits(nau8824->regmap,
NAU8824_REG_PORT0_I2S_PCM_CTRL_2, NAU8824_REG_PORT0_I2S_PCM_CTRL_2,
NAU8824_I2S_LRC_DIV_MASK | NAU8824_I2S_BLK_DIV_MASK, NAU8824_I2S_LRC_DIV_MASK | NAU8824_I2S_BLK_DIV_MASK,
...@@ -1111,15 +1112,17 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream, ...@@ -1111,15 +1112,17 @@ static int nau8824_hw_params(struct snd_pcm_substream *substream,
val_len |= NAU8824_I2S_DL_32; val_len |= NAU8824_I2S_DL_32;
break; break;
default: default:
return -EINVAL; goto error;
} }
regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_1, regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_1,
NAU8824_I2S_DL_MASK, val_len); NAU8824_I2S_DL_MASK, val_len);
err = 0;
error:
nau8824_sema_release(nau8824); nau8824_sema_release(nau8824);
return 0; return err;
} }
static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
...@@ -1128,8 +1131,6 @@ static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) ...@@ -1128,8 +1131,6 @@ static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component); struct nau8824 *nau8824 = snd_soc_component_get_drvdata(component);
unsigned int ctrl1_val = 0, ctrl2_val = 0; unsigned int ctrl1_val = 0, ctrl2_val = 0;
nau8824_sema_acquire(nau8824, HZ);
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBM_CFM: case SND_SOC_DAIFMT_CBM_CFM:
ctrl2_val |= NAU8824_I2S_MS_MASTER; ctrl2_val |= NAU8824_I2S_MS_MASTER;
...@@ -1171,6 +1172,8 @@ static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) ...@@ -1171,6 +1172,8 @@ static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
return -EINVAL; return -EINVAL;
} }
nau8824_sema_acquire(nau8824, HZ);
regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_1, regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_1,
NAU8824_I2S_DF_MASK | NAU8824_I2S_BP_MASK | NAU8824_I2S_DF_MASK | NAU8824_I2S_BP_MASK |
NAU8824_I2S_PCMB_EN, ctrl1_val); NAU8824_I2S_PCMB_EN, ctrl1_val);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment