summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/sound/compress_driver.h11
-rw-r--r--sound/core/compress_offload.c31
2 files changed, 23 insertions, 19 deletions
diff --git a/include/sound/compress_driver.h b/include/sound/compress_driver.h
index 175ab3237b5..ae6c3b8ed2f 100644
--- a/include/sound/compress_driver.h
+++ b/include/sound/compress_driver.h
@@ -48,8 +48,6 @@ struct snd_compr_ops;
* the ring buffer
* @total_bytes_transferred: cumulative bytes transferred by offload DSP
* @sleep: poll sleep
- * @wait: drain wait queue
- * @drain_wake: condition for drain wake
*/
struct snd_compr_runtime {
snd_pcm_state_t state;
@@ -61,8 +59,6 @@ struct snd_compr_runtime {
u64 total_bytes_available;
u64 total_bytes_transferred;
wait_queue_head_t sleep;
- wait_queue_head_t wait;
- unsigned int drain_wake;
void *private_data;
};
@@ -177,10 +173,11 @@ static inline void snd_compr_fragment_elapsed(struct snd_compr_stream *stream)
static inline void snd_compr_drain_notify(struct snd_compr_stream *stream)
{
- snd_BUG_ON(!stream);
+ if (snd_BUG_ON(!stream))
+ return;
- stream->runtime->drain_wake = 1;
- wake_up(&stream->runtime->wait);
+ stream->runtime->state = SNDRV_PCM_STATE_SETUP;
+ wake_up(&stream->runtime->sleep);
}
#endif
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
index 68d3ffcac78..19799931c51 100644
--- a/sound/core/compress_offload.c
+++ b/sound/core/compress_offload.c
@@ -123,7 +123,6 @@ static int snd_compr_open(struct inode *inode, struct file *f)
}
runtime->state = SNDRV_PCM_STATE_OPEN;
init_waitqueue_head(&runtime->sleep);
- init_waitqueue_head(&runtime->wait);
data->stream.runtime = runtime;
f->private_data = (void *)data;
mutex_lock(&compr->lock);
@@ -669,8 +668,6 @@ static int snd_compr_stop(struct snd_compr_stream *stream)
return -EPERM;
retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_STOP);
if (!retval) {
- stream->runtime->state = SNDRV_PCM_STATE_SETUP;
- wake_up(&stream->runtime->sleep);
snd_compr_drain_notify(stream);
stream->runtime->total_bytes_available = 0;
stream->runtime->total_bytes_transferred = 0;
@@ -680,6 +677,8 @@ static int snd_compr_stop(struct snd_compr_stream *stream)
static int snd_compress_wait_for_drain(struct snd_compr_stream *stream)
{
+ int ret;
+
/*
* We are called with lock held. So drop the lock while we wait for
* drain complete notfication from the driver
@@ -691,12 +690,24 @@ static int snd_compress_wait_for_drain(struct snd_compr_stream *stream)
stream->runtime->state = SNDRV_PCM_STATE_DRAINING;
mutex_unlock(&stream->device->lock);
- wait_event(stream->runtime->wait, stream->runtime->drain_wake);
+ /* we wait for drain to complete here, drain can return when
+ * interruption occurred, wait returned error or success.
+ * For the first two cases we don't do anything different here and
+ * return after waking up
+ */
+
+ ret = wait_event_interruptible(stream->runtime->sleep,
+ (stream->runtime->state != SNDRV_PCM_STATE_DRAINING));
+ if (ret == -ERESTARTSYS)
+ pr_debug("wait aborted by a signal");
+ else if (ret)
+ pr_debug("wait for drain failed with %d\n", ret);
+
wake_up(&stream->runtime->sleep);
mutex_lock(&stream->device->lock);
- return 0;
+ return ret;
}
static int snd_compr_drain(struct snd_compr_stream *stream)
@@ -707,17 +718,14 @@ static int snd_compr_drain(struct snd_compr_stream *stream)
stream->runtime->state == SNDRV_PCM_STATE_SETUP)
return -EPERM;
- stream->runtime->drain_wake = 0;
retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_DRAIN);
if (retval) {
- pr_err("SND_COMPR_TRIGGER_DRAIN failed %d\n", retval);
+ pr_debug("SND_COMPR_TRIGGER_DRAIN failed %d\n", retval);
wake_up(&stream->runtime->sleep);
return retval;
}
- retval = snd_compress_wait_for_drain(stream);
- stream->runtime->state = SNDRV_PCM_STATE_SETUP;
- return retval;
+ return snd_compress_wait_for_drain(stream);
}
static int snd_compr_next_track(struct snd_compr_stream *stream)
@@ -752,10 +760,9 @@ static int snd_compr_partial_drain(struct snd_compr_stream *stream)
if (stream->next_track == false)
return -EPERM;
- stream->runtime->drain_wake = 0;
retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_PARTIAL_DRAIN);
if (retval) {
- pr_err("Partial drain returned failure\n");
+ pr_debug("Partial drain returned failure\n");
wake_up(&stream->runtime->sleep);
return retval;
}