diff options
-rw-r--r-- | arch/arm/mach-tegra/tegra_i2s_audio.c | 7 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra_spdif_audio.c | 22 |
2 files changed, 20 insertions, 9 deletions
diff --git a/arch/arm/mach-tegra/tegra_i2s_audio.c b/arch/arm/mach-tegra/tegra_i2s_audio.c index c36fe3b5671f..56857beae63a 100644 --- a/arch/arm/mach-tegra/tegra_i2s_audio.c +++ b/arch/arm/mach-tegra/tegra_i2s_audio.c @@ -690,12 +690,17 @@ static void request_stop_nosync(struct audio_stream *as) pr_debug("%s\n", __func__); if (!as->stop) { as->stop = true; - wait_till_stopped(as); + if (pending_buffer_requests(as)) + wait_till_stopped(as); for (i = 0; i < as->num_bufs; i++) { init_completion(&as->comp[i]); complete(&as->comp[i]); } } + if (!tegra_dma_is_empty(as->dma_chan)) + pr_err("%s: DMA not empty!\n", __func__); + /* Stop the DMA then dequeue anything that's in progress. */ + tegra_dma_cancel(as->dma_chan); as->active = false; /* applies to recording only */ pr_debug("%s: done\n", __func__); } diff --git a/arch/arm/mach-tegra/tegra_spdif_audio.c b/arch/arm/mach-tegra/tegra_spdif_audio.c index 3fb90905bc87..64a85c28efaa 100644 --- a/arch/arm/mach-tegra/tegra_spdif_audio.c +++ b/arch/arm/mach-tegra/tegra_spdif_audio.c @@ -455,12 +455,17 @@ static void request_stop_nosync(struct audio_stream *as) pr_debug("%s\n", __func__); if (!as->stop) { as->stop = true; - wait_till_stopped(as); + if (pending_buffer_requests(as)) + wait_till_stopped(as); for (i = 0; i < as->num_bufs; i++) { init_completion(&as->comp[i]); complete(&as->comp[i]); } } + if (!tegra_dma_is_empty(as->dma_chan)) + pr_err("%s: DMA not empty!\n", __func__); + /* Stop the DMA then dequeue anything that's in progress. */ + tegra_dma_cancel(as->dma_chan); as->active = false; /* applies to recording only */ pr_debug("%s: done\n", __func__); } @@ -538,13 +543,9 @@ static void dma_tx_complete_callback(struct tegra_dma_req *req) complete(&aos->comp[req_num]); - if (stop_playback_if_necessary(aos)) { - pr_debug("%s: done (stopped)\n", __func__); - if (!completion_done(&aos->stop_completion)) { - pr_debug("%s: signalling stop completion\n", __func__); - complete(&aos->stop_completion); - } - return; + if (!pending_buffer_requests(aos)) { + pr_debug("%s: Playback underflow", __func__); + complete(&aos->stop_completion); } } @@ -724,6 +725,8 @@ static long tegra_spdif_out_ioctl(struct file *file, request_stop_nosync(aos); pr_debug("%s: flushed\n", __func__); } + if (stop_playback_if_necessary(aos)) + pr_debug("%s: done (stopped)\n", __func__); aos->stop = false; break; case TEGRA_AUDIO_OUT_SET_NUM_BUFS: { @@ -747,6 +750,7 @@ static long tegra_spdif_out_ioctl(struct file *file, if (rc < 0) break; aos->num_bufs = num; + sound_ops->setup(ads); } break; case TEGRA_AUDIO_OUT_GET_NUM_BUFS: @@ -801,6 +805,8 @@ static int tegra_spdif_out_release(struct inode *inode, struct file *file) mutex_lock(&ads->out.lock); ads->out.opened = 0; request_stop_nosync(&ads->out); + if (stop_playback_if_necessary(&ads->out)) + pr_debug("%s: done (stopped)\n", __func__); allow_suspend(&ads->out); mutex_unlock(&ads->out.lock); pr_debug("%s: done\n", __func__); |