diff options
author | Colin Cross <ccross@android.com> | 2011-10-27 15:01:42 -0700 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2011-10-27 15:01:42 -0700 |
commit | bc2e7067af4c1cd074aaec71c2982e2265f7f169 (patch) | |
tree | bc8bcb97155bada3d09c91c6b8aa56ed546471a9 /sound/core | |
parent | 4e9ff24781ab987120e792a667ba45b3d3dd51a0 (diff) | |
parent | 97596c34030ed28657ccafddb67e17a03890b90a (diff) | |
download | kernel_samsung_tuna-bc2e7067af4c1cd074aaec71c2982e2265f7f169.zip kernel_samsung_tuna-bc2e7067af4c1cd074aaec71c2982e2265f7f169.tar.gz kernel_samsung_tuna-bc2e7067af4c1cd074aaec71c2982e2265f7f169.tar.bz2 |
Merge commit 'v3.0.8' into linux-omap-3.0
Conflicts:
drivers/tty/serial/omap-serial.c
drivers/usb/musb/musb_gadget.c
sound/soc/omap/omap-mcbsp.c
Change-Id: Ic31b7266dda3ac8483f737272874ebf4725b5fe3
Diffstat (limited to 'sound/core')
-rw-r--r-- | sound/core/pcm_lib.c | 33 | ||||
-rw-r--r-- | sound/core/timer.c | 2 |
2 files changed, 26 insertions, 9 deletions
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 13b95dd..cd69b38 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -1758,6 +1758,10 @@ static int wait_for_avail(struct snd_pcm_substream *substream, snd_pcm_uframes_t avail = 0; long wait_time, tout; + init_waitqueue_entry(&wait, current); + set_current_state(TASK_INTERRUPTIBLE); + add_wait_queue(&runtime->tsleep, &wait); + if (runtime->no_period_wakeup) wait_time = MAX_SCHEDULE_TIMEOUT; else { @@ -1768,16 +1772,32 @@ static int wait_for_avail(struct snd_pcm_substream *substream, } wait_time = msecs_to_jiffies(wait_time * 1000); } - init_waitqueue_entry(&wait, current); - add_wait_queue(&runtime->tsleep, &wait); + for (;;) { if (signal_pending(current)) { err = -ERESTARTSYS; break; } + + /* + * We need to check if space became available already + * (and thus the wakeup happened already) first to close + * the race of space already having become available. + * This check must happen after been added to the waitqueue + * and having current state be INTERRUPTIBLE. + */ + if (is_playback) + avail = snd_pcm_playback_avail(runtime); + else + avail = snd_pcm_capture_avail(runtime); + if (avail >= runtime->twake) + break; snd_pcm_stream_unlock_irq(substream); - tout = schedule_timeout_interruptible(wait_time); + + tout = schedule_timeout(wait_time); + snd_pcm_stream_lock_irq(substream); + set_current_state(TASK_INTERRUPTIBLE); switch (runtime->status->state) { case SNDRV_PCM_STATE_SUSPENDED: err = -ESTRPIPE; @@ -1803,14 +1823,9 @@ static int wait_for_avail(struct snd_pcm_substream *substream, err = -EIO; break; } - if (is_playback) - avail = snd_pcm_playback_avail(runtime); - else - avail = snd_pcm_capture_avail(runtime); - if (avail >= runtime->twake) - break; } _endloop: + set_current_state(TASK_RUNNING); remove_wait_queue(&runtime->tsleep, &wait); *availp = avail; return err; diff --git a/sound/core/timer.c b/sound/core/timer.c index 7c1cbf0..950eed0 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -531,6 +531,8 @@ int snd_timer_stop(struct snd_timer_instance *timeri) if (err < 0) return err; timer = timeri->timer; + if (!timer) + return -EINVAL; spin_lock_irqsave(&timer->lock, flags); timeri->cticks = timeri->ticks; timeri->pticks = 0; |