diff options
-rw-r--r-- | include/sound/compress_driver.h | 11 | ||||
-rw-r--r-- | sound/core/compress_offload.c | 31 |
2 files changed, 23 insertions, 19 deletions
diff --git a/include/sound/compress_driver.h b/include/sound/compress_driver.h index 175ab3237b58..ae6c3b8ed2f5 100644 --- a/include/sound/compress_driver.h +++ b/include/sound/compress_driver.h | |||
@@ -48,8 +48,6 @@ struct snd_compr_ops; | |||
48 | * the ring buffer | 48 | * the ring buffer |
49 | * @total_bytes_transferred: cumulative bytes transferred by offload DSP | 49 | * @total_bytes_transferred: cumulative bytes transferred by offload DSP |
50 | * @sleep: poll sleep | 50 | * @sleep: poll sleep |
51 | * @wait: drain wait queue | ||
52 | * @drain_wake: condition for drain wake | ||
53 | */ | 51 | */ |
54 | struct snd_compr_runtime { | 52 | struct snd_compr_runtime { |
55 | snd_pcm_state_t state; | 53 | snd_pcm_state_t state; |
@@ -61,8 +59,6 @@ struct snd_compr_runtime { | |||
61 | u64 total_bytes_available; | 59 | u64 total_bytes_available; |
62 | u64 total_bytes_transferred; | 60 | u64 total_bytes_transferred; |
63 | wait_queue_head_t sleep; | 61 | wait_queue_head_t sleep; |
64 | wait_queue_head_t wait; | ||
65 | unsigned int drain_wake; | ||
66 | void *private_data; | 62 | void *private_data; |
67 | }; | 63 | }; |
68 | 64 | ||
@@ -177,10 +173,11 @@ static inline void snd_compr_fragment_elapsed(struct snd_compr_stream *stream) | |||
177 | 173 | ||
178 | static inline void snd_compr_drain_notify(struct snd_compr_stream *stream) | 174 | static inline void snd_compr_drain_notify(struct snd_compr_stream *stream) |
179 | { | 175 | { |
180 | snd_BUG_ON(!stream); | 176 | if (snd_BUG_ON(!stream)) |
177 | return; | ||
181 | 178 | ||
182 | stream->runtime->drain_wake = 1; | 179 | stream->runtime->state = SNDRV_PCM_STATE_SETUP; |
183 | wake_up(&stream->runtime->wait); | 180 | wake_up(&stream->runtime->sleep); |
184 | } | 181 | } |
185 | 182 | ||
186 | #endif | 183 | #endif |
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index 3eb47d0006a7..d9af6387f37c 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) | |||
123 | } | 123 | } |
124 | runtime->state = SNDRV_PCM_STATE_OPEN; | 124 | runtime->state = SNDRV_PCM_STATE_OPEN; |
125 | init_waitqueue_head(&runtime->sleep); | 125 | init_waitqueue_head(&runtime->sleep); |
126 | init_waitqueue_head(&runtime->wait); | ||
127 | data->stream.runtime = runtime; | 126 | data->stream.runtime = runtime; |
128 | f->private_data = (void *)data; | 127 | f->private_data = (void *)data; |
129 | mutex_lock(&compr->lock); | 128 | mutex_lock(&compr->lock); |
@@ -681,8 +680,6 @@ static int snd_compr_stop(struct snd_compr_stream *stream) | |||
681 | return -EPERM; | 680 | return -EPERM; |
682 | retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_STOP); | 681 | retval = stream->ops->trigger(stream, SNDRV_PCM_TRIGGER_STOP); |
683 | if (!retval) { | 682 | if (!retval) { |
684 | stream->runtime->state = SNDRV_PCM_STATE_SETUP; | ||
685 | wake_up(&stream->runtime->sleep); | ||
686 | snd_compr_drain_notify(stream); | 683 | snd_compr_drain_notify(stream); |
687 | stream->runtime->total_bytes_available = 0; | 684 | stream->runtime->total_bytes_available = 0; |
688 | stream->runtime->total_bytes_transferred = 0; | 685 | stream->runtime->total_bytes_transferred = 0; |
@@ -692,6 +689,8 @@ static int snd_compr_stop(struct snd_compr_stream *stream) | |||
692 | 689 | ||
693 | static int snd_compress_wait_for_drain(struct snd_compr_stream *stream) | 690 | static int snd_compress_wait_for_drain(struct snd_compr_stream *stream) |
694 | { | 691 | { |
692 | int ret; | ||
693 | |||
695 | /* | 694 | /* |
696 | * We are called with lock held. So drop the lock while we wait for | 695 | * We are called with lock held. So drop the lock while we wait for |
697 | * drain complete notfication from the driver | 696 | * drain complete notfication from the driver |
@@ -703,12 +702,24 @@ static int snd_compress_wait_for_drain(struct snd_compr_stream *stream) | |||
703 | stream->runtime->state = SNDRV_PCM_STATE_DRAINING; | 702 | stream->runtime->state = SNDRV_PCM_STATE_DRAINING; |
704 | mutex_unlock(&stream->device->lock); | 703 | mutex_unlock(&stream->device->lock); |
705 | 704 | ||
706 | wait_event(stream->runtime->wait, stream->runtime->drain_wake); | 705 | /* we wait for drain to complete here, drain can return when |
706 | * interruption occurred, wait returned error or success. | ||
707 | * For the first two cases we don't do anything different here and | ||
708 | * return after waking up | ||
709 | */ | ||
710 | |||
711 | ret = wait_event_interruptible(stream->runtime->sleep, | ||
712 | (stream->runtime->state != SNDRV_PCM_STATE_DRAINING)); | ||
713 | if (ret == -ERESTARTSYS) | ||
714 | pr_debug("wait aborted by a signal"); | ||
715 | else if (ret) | ||
716 | pr_debug("wait for drain failed with %d\n", ret); | ||
717 | |||
707 | 718 | ||
708 | wake_up(&stream->runtime->sleep); | 719 | wake_up(&stream->runtime->sleep); |
709 | mutex_lock(&stream->device->lock); | 720 | mutex_lock(&stream->device->lock); |
710 | 721 | ||
711 | return 0; | 722 | return ret; |
712 | } | 723 | } |
713 | 724 | ||
714 | static int snd_compr_drain(struct snd_compr_stream *stream) | 725 | static int snd_compr_drain(struct snd_compr_stream *stream) |
@@ -719,17 +730,14 @@ static int snd_compr_drain(struct snd_compr_stream *stream) | |||
719 | stream->runtime->state == SNDRV_PCM_STATE_SETUP) | 730 | stream->runtime->state == SNDRV_PCM_STATE_SETUP) |
720 | return -EPERM; | 731 | return -EPERM; |
721 | 732 | ||
722 | stream->runtime->drain_wake = 0; | ||
723 | retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_DRAIN); | 733 | retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_DRAIN); |
724 | if (retval) { | 734 | if (retval) { |
725 | pr_err("SND_COMPR_TRIGGER_DRAIN failed %d\n", retval); | 735 | pr_debug("SND_COMPR_TRIGGER_DRAIN failed %d\n", retval); |
726 | wake_up(&stream->runtime->sleep); | 736 | wake_up(&stream->runtime->sleep); |
727 | return retval; | 737 | return retval; |
728 | } | 738 | } |
729 | 739 | ||
730 | retval = snd_compress_wait_for_drain(stream); | 740 | return snd_compress_wait_for_drain(stream); |
731 | stream->runtime->state = SNDRV_PCM_STATE_SETUP; | ||
732 | return retval; | ||
733 | } | 741 | } |
734 | 742 | ||
735 | static int snd_compr_next_track(struct snd_compr_stream *stream) | 743 | static int snd_compr_next_track(struct snd_compr_stream *stream) |
@@ -764,10 +772,9 @@ static int snd_compr_partial_drain(struct snd_compr_stream *stream) | |||
764 | if (stream->next_track == false) | 772 | if (stream->next_track == false) |
765 | return -EPERM; | 773 | return -EPERM; |
766 | 774 | ||
767 | stream->runtime->drain_wake = 0; | ||
768 | retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_PARTIAL_DRAIN); | 775 | retval = stream->ops->trigger(stream, SND_COMPR_TRIGGER_PARTIAL_DRAIN); |
769 | if (retval) { | 776 | if (retval) { |
770 | pr_err("Partial drain returned failure\n"); | 777 | pr_debug("Partial drain returned failure\n"); |
771 | wake_up(&stream->runtime->sleep); | 778 | wake_up(&stream->runtime->sleep); |
772 | return retval; | 779 | return retval; |
773 | } | 780 | } |