diff options
author | Manjula Gupta <magupta@nvidia.com> | 2010-06-15 17:59:50 +0530 |
---|---|---|
committer | Gary King <gking@nvidia.com> | 2010-06-22 10:31:52 -0700 |
commit | cfc9f617720bda069b54d2233ee91d1cd55d9865 (patch) | |
tree | bc35c687ce8e00a362f1aad6786e58c6a40eb59f /sound | |
parent | b51a545ccd32f85e3c37d87ae3888b9ee7ef82a2 (diff) |
[tegra ALSA]: Fix hang when CLOSE is delayed after STOP.
If CLOSE call is delayed after STOP, it set's the prtd->state
to SNDRV_PCM_TRIGGER_STOP causing the STOP case execution twice
in play_thread which leads to hang as mixer doesn't respect
and don't send the notification of completion for second mixer
stop done call which is the expected behaviour.
Putting a flag to ensure that stop is executed only once in
play and record thread.
We are setting prtd->state to SNDRV_PCM_TRIGGER_STOP specifically
in CLOSE as application directly call CLOSE without STOP in some
cases.
For Bug: 697124
Change-Id: I0a543bca2488afe0bacbf6497df49f24aecb46bc
Reviewed-on: http://git-master/r/2659
Tested-by: Manjula Gupta <magupta@nvidia.com>
Reviewed-by: Vijay Mali <vmali@nvidia.com>
Reviewed-by: Gary King <gking@nvidia.com>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/tegra/tegra_pcm_rpc.c | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/sound/soc/tegra/tegra_pcm_rpc.c b/sound/soc/tegra/tegra_pcm_rpc.c index bfa2a4d459c9..cc255de26ca8 100644 --- a/sound/soc/tegra/tegra_pcm_rpc.c +++ b/sound/soc/tegra/tegra_pcm_rpc.c @@ -65,7 +65,7 @@ static int play_thread( void *arg) struct snd_pcm_runtime *runtime = substream->runtime; struct pcm_runtime_data *prtd = substream->runtime->private_data; NvError e; - int size; + int size = 0; int offset = 0; int period_offset = 0; int rtbuffersize = 0; @@ -90,15 +90,17 @@ static int play_thread( void *arg) prtd->state = NVALSA_INVALID_STATE; break; case SNDRV_PCM_TRIGGER_STOP: - state = NvAudioFxState_Stop; - tegra_snd_cx->xrt_fxn.SetProperty( + if (state != NvAudioFxState_Stop) { + state = NvAudioFxState_Stop; + tegra_snd_cx->xrt_fxn.SetProperty( prtd->stdoutpath->Stream, NvAudioFxProperty_State, sizeof(NvAudioFxState), &state); - down(&prtd->stop_done_sem); - buffer_in_queue = 0; - prtd->state = NVALSA_INVALID_STATE; + down(&prtd->stop_done_sem); + buffer_in_queue = 0; + prtd->state = NVALSA_INVALID_STATE; + } default: ; } @@ -107,7 +109,7 @@ static int play_thread( void *arg) break; if ((prtd->audiofx_frames < runtime->control->appl_ptr) && - (state != SNDRV_PCM_TRIGGER_STOP)) { + (state != NvAudioFxState_Stop)) { memset(&abd, 0, sizeof(NvAudioFxBufferDescriptor)); size = TEGRA_DEFAULT_BUFFER_SIZE; @@ -188,7 +190,7 @@ static int rec_thread( void *arg ) struct snd_pcm_runtime *runtime = substream->runtime; struct pcm_runtime_data *prtd = substream->runtime->private_data; NvError e; - int size; + int size = 0; int offset = 0; int period_offset = 0; int rtbuffersize = 0; @@ -239,15 +241,17 @@ static int rec_thread( void *arg ) prtd->state = NVALSA_INVALID_STATE; break; case SNDRV_PCM_TRIGGER_STOP: - state = NvAudioFxState_Stop; - tegra_snd_cx->xrt_fxn.SetProperty( + if (state != NvAudioFxState_Stop) { + state = NvAudioFxState_Stop; + tegra_snd_cx->xrt_fxn.SetProperty( prtd->stdinpath->Stream, NvAudioFxProperty_State, sizeof(NvAudioFxState), &state); - down(&prtd->stop_done_sem); - buffer_in_queue = 0; - prtd->state = NVALSA_INVALID_STATE; + down(&prtd->stop_done_sem); + buffer_in_queue = 0; + prtd->state = NVALSA_INVALID_STATE; + } goto EXIT; default: ; |