aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2011-10-27 15:01:42 -0700
committerColin Cross <ccross@android.com>2011-10-27 15:01:42 -0700
commitbc2e7067af4c1cd074aaec71c2982e2265f7f169 (patch)
treebc8bcb97155bada3d09c91c6b8aa56ed546471a9 /sound/core
parent4e9ff24781ab987120e792a667ba45b3d3dd51a0 (diff)
parent97596c34030ed28657ccafddb67e17a03890b90a (diff)
downloadkernel_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.c33
-rw-r--r--sound/core/timer.c2
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;