aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/fsl
diff options
context:
space:
mode:
authorNicolin Chen <Guangyu.Chen@freescale.com>2014-07-23 07:23:38 -0400
committerMark Brown <broonie@linaro.org>2014-07-25 13:52:35 -0400
commitf4075a8f452aff5465c6522c92da9db71ed11b7f (patch)
tree3f2b3e6eb22153c8a27e84abcb76d92c1dbbe058 /sound/soc/fsl
parent4800f88b615f194ae3c1577038a7ccd871c907c9 (diff)
ASoC: fsl_sai: Reduce race condition during TE/RE enabling
For trigger start, we don't need to check if it's the first time to enable TE/RE or second time. It doesn't hurt to enable them any way, which in the meantime can reduce race condition for TE/RE enabling. For trigger stop, we will definitely clear FRDE of current direction. Thus the driver only needs to read the opposite one's. Signed-off-by: Nicolin Chen <nicoleotsuka@gmail.com> Signed-off-by: Mark Brown <broonie@linaro.org>
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r--sound/soc/fsl/fsl_sai.c18
1 files changed, 7 insertions, 11 deletions
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 1b6ee2ce849f..a437899d2d11 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -327,7 +327,7 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
327{ 327{
328 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); 328 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
329 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 329 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
330 u32 tcsr, rcsr; 330 u32 xcsr;
331 331
332 /* 332 /*
333 * The transmitter bit clock and frame sync are to be 333 * The transmitter bit clock and frame sync are to be
@@ -338,9 +338,6 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
338 regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC, 338 regmap_update_bits(sai->regmap, FSL_SAI_RCR2, FSL_SAI_CR2_SYNC,
339 FSL_SAI_CR2_SYNC); 339 FSL_SAI_CR2_SYNC);
340 340
341 regmap_read(sai->regmap, FSL_SAI_TCSR, &tcsr);
342 regmap_read(sai->regmap, FSL_SAI_RCSR, &rcsr);
343
344 /* 341 /*
345 * It is recommended that the transmitter is the last enabled 342 * It is recommended that the transmitter is the last enabled
346 * and the first disabled. 343 * and the first disabled.
@@ -349,12 +346,10 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
349 case SNDRV_PCM_TRIGGER_START: 346 case SNDRV_PCM_TRIGGER_START:
350 case SNDRV_PCM_TRIGGER_RESUME: 347 case SNDRV_PCM_TRIGGER_RESUME:
351 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 348 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
352 if (!(tcsr & FSL_SAI_CSR_FRDE || rcsr & FSL_SAI_CSR_FRDE)) { 349 regmap_update_bits(sai->regmap, FSL_SAI_RCSR,
353 regmap_update_bits(sai->regmap, FSL_SAI_RCSR, 350 FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
354 FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE); 351 regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
355 regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 352 FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
356 FSL_SAI_CSR_TERE, FSL_SAI_CSR_TERE);
357 }
358 353
359 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx), 354 regmap_update_bits(sai->regmap, FSL_SAI_xCSR(tx),
360 FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS); 355 FSL_SAI_CSR_xIE_MASK, FSL_SAI_FLAGS);
@@ -370,7 +365,8 @@ static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
370 FSL_SAI_CSR_xIE_MASK, 0); 365 FSL_SAI_CSR_xIE_MASK, 0);
371 366
372 /* Check if the opposite FRDE is also disabled */ 367 /* Check if the opposite FRDE is also disabled */
373 if (!(tx ? rcsr & FSL_SAI_CSR_FRDE : tcsr & FSL_SAI_CSR_FRDE)) { 368 regmap_read(sai->regmap, FSL_SAI_xCSR(!tx), &xcsr);
369 if (!(xcsr & FSL_SAI_CSR_FRDE)) {
374 /* Disable both directions and reset their FIFOs */ 370 /* Disable both directions and reset their FIFOs */
375 regmap_update_bits(sai->regmap, FSL_SAI_TCSR, 371 regmap_update_bits(sai->regmap, FSL_SAI_TCSR,
376 FSL_SAI_CSR_TERE | FSL_SAI_CSR_FR, 372 FSL_SAI_CSR_TERE | FSL_SAI_CSR_FR,