summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorManjula Gupta <magupta@nvidia.com>2010-03-31 18:00:56 +0530
committerGary King <gking@nvidia.com>2010-03-31 14:48:08 -0800
commitf7993d029dca1275c292b11e4e04006ce470d98b (patch)
tree52de7ec1b16d6a1c4f2d4bc8ea69507715cd7f73 /sound
parent2552f1cb5f0efd10509ea92bceb477b90fc7e7f5 (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>
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/tegra/tegra_pcm_rpc.c15
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));