summaryrefslogtreecommitdiff
path: root/sound
diff options
context:
space:
mode:
authorManjula Gupta <magupta@nvidia.com>2010-06-15 17:59:50 +0530
committerGary King <gking@nvidia.com>2010-06-22 10:31:52 -0700
commitcfc9f617720bda069b54d2233ee91d1cd55d9865 (patch)
treebc35c687ce8e00a362f1aad6786e58c6a40eb59f /sound
parentb51a545ccd32f85e3c37d87ae3888b9ee7ef82a2 (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.c30
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:
;