aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Hsu <KCHSU0@nuvoton.com>2017-11-30 21:01:50 -0500
committerMark Brown <broonie@kernel.org>2017-12-04 13:14:42 -0500
commit70424d8e6e15abd32e189130be220d0063e082bc (patch)
treeaa415170b6f98fa07cac4810810c168600d27ca5
parente3fee43a968fd39dcc56be3757fcdfe250964125 (diff)
ASoC: nau8825: improve semaphore control
After reviewing the crosstalk protection, there are two flaws at semaphore control. The first one is that the semaphore releases are not enough; and the other is that down_interruptible has an risk to make the ISR sleep. Therefore, the driver add more releases before the funcitons return. Take down_trylock to replace down_interruptible. The ISR can control the protection as well and never sleep by semaphore. Signed-off-by: John Hsu <KCHSU0@nuvoton.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/codecs/nau8825.c38
1 files changed, 23 insertions, 15 deletions
diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c
index 603cd72c2a25..5778eadbf9e6 100644
--- a/sound/soc/codecs/nau8825.c
+++ b/sound/soc/codecs/nau8825.c
@@ -245,13 +245,14 @@ static const unsigned short logtable[256] = {
245 * tasks are allowed to acquire the semaphore, calling this function will 245 * tasks are allowed to acquire the semaphore, calling this function will
246 * put the task to sleep. If the semaphore is not released within the 246 * put the task to sleep. If the semaphore is not released within the
247 * specified number of jiffies, this function returns. 247 * specified number of jiffies, this function returns.
248 * Acquires the semaphore without jiffies. If no more tasks are allowed
249 * to acquire the semaphore, calling this function will put the task to
250 * sleep until the semaphore is released.
251 * If the semaphore is not released within the specified number of jiffies, 248 * If the semaphore is not released within the specified number of jiffies,
252 * this function returns -ETIME. 249 * this function returns -ETIME. If the sleep is interrupted by a signal,
253 * If the sleep is interrupted by a signal, this function will return -EINTR. 250 * this function will return -EINTR. It returns 0 if the semaphore was
254 * It returns 0 if the semaphore was acquired successfully. 251 * acquired successfully.
252 *
253 * Acquires the semaphore without jiffies. Try to acquire the semaphore
254 * atomically. Returns 0 if the semaphore has been acquired successfully
255 * or 1 if it it cannot be acquired.
255 */ 256 */
256static int nau8825_sema_acquire(struct nau8825 *nau8825, long timeout) 257static int nau8825_sema_acquire(struct nau8825 *nau8825, long timeout)
257{ 258{
@@ -262,8 +263,8 @@ static int nau8825_sema_acquire(struct nau8825 *nau8825, long timeout)
262 if (ret < 0) 263 if (ret < 0)
263 dev_warn(nau8825->dev, "Acquire semaphore timeout\n"); 264 dev_warn(nau8825->dev, "Acquire semaphore timeout\n");
264 } else { 265 } else {
265 ret = down_interruptible(&nau8825->xtalk_sem); 266 ret = down_trylock(&nau8825->xtalk_sem);
266 if (ret < 0) 267 if (ret)
267 dev_warn(nau8825->dev, "Acquire semaphore fail\n"); 268 dev_warn(nau8825->dev, "Acquire semaphore fail\n");
268 } 269 }
269 270
@@ -1246,8 +1247,10 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
1246 regmap_read(nau8825->regmap, NAU8825_REG_DAC_CTRL1, &osr); 1247 regmap_read(nau8825->regmap, NAU8825_REG_DAC_CTRL1, &osr);
1247 osr &= NAU8825_DAC_OVERSAMPLE_MASK; 1248 osr &= NAU8825_DAC_OVERSAMPLE_MASK;
1248 if (nau8825_clock_check(nau8825, substream->stream, 1249 if (nau8825_clock_check(nau8825, substream->stream,
1249 params_rate(params), osr)) 1250 params_rate(params), osr)) {
1251 nau8825_sema_release(nau8825);
1250 return -EINVAL; 1252 return -EINVAL;
1253 }
1251 regmap_update_bits(nau8825->regmap, NAU8825_REG_CLK_DIVIDER, 1254 regmap_update_bits(nau8825->regmap, NAU8825_REG_CLK_DIVIDER,
1252 NAU8825_CLK_DAC_SRC_MASK, 1255 NAU8825_CLK_DAC_SRC_MASK,
1253 osr_dac_sel[osr].clk_src << NAU8825_CLK_DAC_SRC_SFT); 1256 osr_dac_sel[osr].clk_src << NAU8825_CLK_DAC_SRC_SFT);
@@ -1255,8 +1258,10 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
1255 regmap_read(nau8825->regmap, NAU8825_REG_ADC_RATE, &osr); 1258 regmap_read(nau8825->regmap, NAU8825_REG_ADC_RATE, &osr);
1256 osr &= NAU8825_ADC_SYNC_DOWN_MASK; 1259 osr &= NAU8825_ADC_SYNC_DOWN_MASK;
1257 if (nau8825_clock_check(nau8825, substream->stream, 1260 if (nau8825_clock_check(nau8825, substream->stream,
1258 params_rate(params), osr)) 1261 params_rate(params), osr)) {
1262 nau8825_sema_release(nau8825);
1259 return -EINVAL; 1263 return -EINVAL;
1264 }
1260 regmap_update_bits(nau8825->regmap, NAU8825_REG_CLK_DIVIDER, 1265 regmap_update_bits(nau8825->regmap, NAU8825_REG_CLK_DIVIDER,
1261 NAU8825_CLK_ADC_SRC_MASK, 1266 NAU8825_CLK_ADC_SRC_MASK,
1262 osr_adc_sel[osr].clk_src << NAU8825_CLK_ADC_SRC_SFT); 1267 osr_adc_sel[osr].clk_src << NAU8825_CLK_ADC_SRC_SFT);
@@ -1273,8 +1278,10 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
1273 bclk_div = 1; 1278 bclk_div = 1;
1274 else if (bclk_fs <= 128) 1279 else if (bclk_fs <= 128)
1275 bclk_div = 0; 1280 bclk_div = 0;
1276 else 1281 else {
1282 nau8825_sema_release(nau8825);
1277 return -EINVAL; 1283 return -EINVAL;
1284 }
1278 regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2, 1285 regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2,
1279 NAU8825_I2S_LRC_DIV_MASK | NAU8825_I2S_BLK_DIV_MASK, 1286 NAU8825_I2S_LRC_DIV_MASK | NAU8825_I2S_BLK_DIV_MASK,
1280 ((bclk_div + 1) << NAU8825_I2S_LRC_DIV_SFT) | bclk_div); 1287 ((bclk_div + 1) << NAU8825_I2S_LRC_DIV_SFT) | bclk_div);
@@ -1294,6 +1301,7 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
1294 val_len |= NAU8825_I2S_DL_32; 1301 val_len |= NAU8825_I2S_DL_32;
1295 break; 1302 break;
1296 default: 1303 default:
1304 nau8825_sema_release(nau8825);
1297 return -EINVAL; 1305 return -EINVAL;
1298 } 1306 }
1299 1307
@@ -1312,8 +1320,6 @@ static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
1312 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec); 1320 struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
1313 unsigned int ctrl1_val = 0, ctrl2_val = 0; 1321 unsigned int ctrl1_val = 0, ctrl2_val = 0;
1314 1322
1315 nau8825_sema_acquire(nau8825, 3 * HZ);
1316
1317 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 1323 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
1318 case SND_SOC_DAIFMT_CBM_CFM: 1324 case SND_SOC_DAIFMT_CBM_CFM:
1319 ctrl2_val |= NAU8825_I2S_MS_MASTER; 1325 ctrl2_val |= NAU8825_I2S_MS_MASTER;
@@ -1355,6 +1361,8 @@ static int nau8825_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)
1355 return -EINVAL; 1361 return -EINVAL;
1356 } 1362 }
1357 1363
1364 nau8825_sema_acquire(nau8825, 3 * HZ);
1365
1358 regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL1, 1366 regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL1,
1359 NAU8825_I2S_DL_MASK | NAU8825_I2S_DF_MASK | 1367 NAU8825_I2S_DL_MASK | NAU8825_I2S_DF_MASK |
1360 NAU8825_I2S_BP_MASK | NAU8825_I2S_PCMB_MASK, 1368 NAU8825_I2S_BP_MASK | NAU8825_I2S_PCMB_MASK,
@@ -1701,7 +1709,7 @@ static irqreturn_t nau8825_interrupt(int irq, void *data)
1701 int ret; 1709 int ret;
1702 nau8825->xtalk_protect = true; 1710 nau8825->xtalk_protect = true;
1703 ret = nau8825_sema_acquire(nau8825, 0); 1711 ret = nau8825_sema_acquire(nau8825, 0);
1704 if (ret < 0) 1712 if (ret)
1705 nau8825->xtalk_protect = false; 1713 nau8825->xtalk_protect = false;
1706 } 1714 }
1707 /* Startup cross talk detection process */ 1715 /* Startup cross talk detection process */
@@ -2383,7 +2391,7 @@ static int __maybe_unused nau8825_resume(struct snd_soc_codec *codec)
2383 regcache_sync(nau8825->regmap); 2391 regcache_sync(nau8825->regmap);
2384 nau8825->xtalk_protect = true; 2392 nau8825->xtalk_protect = true;
2385 ret = nau8825_sema_acquire(nau8825, 0); 2393 ret = nau8825_sema_acquire(nau8825, 0);
2386 if (ret < 0) 2394 if (ret)
2387 nau8825->xtalk_protect = false; 2395 nau8825->xtalk_protect = false;
2388 enable_irq(nau8825->irq); 2396 enable_irq(nau8825->irq);
2389 2397