diff options
author | Manjula Gupta <magupta@nvidia.com> | 2010-03-31 18:00:56 +0530 |
---|---|---|
committer | Gary King <gking@nvidia.com> | 2010-03-31 14:48:08 -0800 |
commit | f7993d029dca1275c292b11e4e04006ce470d98b (patch) | |
tree | 52de7ec1b16d6a1c4f2d4bc8ea69507715cd7f73 | |
parent | 2552f1cb5f0efd10509ea92bceb477b90fc7e7f5 (diff) |
[ALSA]: Fix Record Hang
- Don't signal the shutdown thread until the thread
process the SNDRV_PCM_TRIGGER_STOP call. The Kthread_stop()
call is a blocking call that waits until the kthread_should_stop()
returns.
- Set the prtd->state to SNDRV_PCM_TRIGGER_STOP in pcm_common_close
specifically to ensure proper clean-up and to handle the case
where application exits without triggering the STOP call.
- wait for the buffer done notification for the buffers queued in
before setting mixer state to stop.
- For Bug 667787 [LDK/Whistler/ALSA]"arecord" app hung
with DVD quality .raw audio recording (Mono/Stereo).
Change-Id: Id9c13bbd2dd0b5f90b3c545677eddfa05849c45f
Reviewed-on: http://git-master/r/997
Reviewed-by: Vijay Mali <vmali@nvidia.com>
Tested-by: Vijay Mali <vmali@nvidia.com>
Reviewed-by: Gary King <gking@nvidia.com>
-rw-r--r-- | sound/soc/tegra/tegra_pcm_rpc.c | 15 |
1 files changed, 9 insertions, 6 deletions
diff --git a/sound/soc/tegra/tegra_pcm_rpc.c b/sound/soc/tegra/tegra_pcm_rpc.c index 3e5058da7554..afa17e4b43e8 100644 --- a/sound/soc/tegra/tegra_pcm_rpc.c +++ b/sound/soc/tegra/tegra_pcm_rpc.c @@ -234,6 +234,11 @@ static int rec_thread( void *arg ) prtd->state = NVALSA_INVALID_STATE; break; case SNDRV_PCM_TRIGGER_STOP: + while (buffer_in_queue > 0) { + down(&prtd->buf_done_sem); + buffer_in_queue--; + } + state = NvAudioFxState_Stop; tegra_snd_cx->xrt_fxn.SetProperty( prtd->stdinpath->Stream, @@ -308,10 +313,6 @@ static int rec_thread( void *arg ) } } EXIT: - while (buffer_in_queue > 0) { - down(&prtd->buf_done_sem); - buffer_in_queue--; - } while (!kthread_should_stop()) { } @@ -460,8 +461,7 @@ static int pcm_common_close(struct snd_pcm_substream *substream) if (!prtd) snd_printk(KERN_ERR "pcm_close called with prtd = NULL\n"); - prtd->shutdown_thrd = 1; - up(&prtd->buf_done_sem); + prtd->state = SNDRV_PCM_TRIGGER_STOP; if (prtd->play_thread) kthread_stop(prtd->play_thread); @@ -469,6 +469,9 @@ static int pcm_common_close(struct snd_pcm_substream *substream) if (prtd->rec_thread) kthread_stop(prtd->rec_thread); + prtd->shutdown_thrd = 1; + up(&prtd->buf_done_sem); + if (tegra_snd_cx->m_FxNotifier.Event & NvAudioFxEventBufferDone) { memset(&message, 0, sizeof(NvAudioFxMessage)); |