From 7b51a258a123b94c0d1425be2e28a2593c1f1400 Mon Sep 17 00:00:00 2001 From: Weiyin Jiang Date: Tue, 26 Nov 2019 03:33:12 +0800 Subject: [PATCH] ASoC: compr: wake up drain only if it's the last buffer There's a corner case where there're pause and resume operations in the middle of last full buffer drain. Waking up drain without checking against the real byte available violates the assumption only one partial buffer in the last write. The solution is to just resume the write pipe if there's more than one fragment pending. CRs-Fixed: 2536883 Change-Id: Id24c63bad774ec916942b8f94ddaa396d2560517 Signed-off-by: Weiyin Jiang --- asoc/msm-compress-q6-v2.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/asoc/msm-compress-q6-v2.c b/asoc/msm-compress-q6-v2.c index c0452922c828..cfb560bda941 100644 --- a/asoc/msm-compress-q6-v2.c +++ b/asoc/msm-compress-q6-v2.c @@ -825,15 +825,23 @@ static void compr_event_handler(uint32_t opcode, * RESUME */ if ((prtd->copied_total == prtd->bytes_sent) && - atomic_read(&prtd->drain)) { - pr_debug("RUN ack, wake up & continue pending drain\n"); + atomic_read(&prtd->drain)) { + bytes_available = prtd->bytes_received - prtd->copied_total; + if (bytes_available < cstream->runtime->fragment_size) { + pr_debug("%s: RUN ack, wake up & continue pending drain\n", + __func__); - if (prtd->last_buffer) - prtd->last_buffer = 0; + if (prtd->last_buffer) + prtd->last_buffer = 0; - prtd->drain_ready = 1; - wake_up(&prtd->drain_wait); - atomic_set(&prtd->drain, 0); + prtd->drain_ready = 1; + wake_up(&prtd->drain_wait); + atomic_set(&prtd->drain, 0); + } else if (atomic_read(&prtd->xrun)) { + pr_debug("%s: RUN ack, continue write cycle\n", __func__); + atomic_set(&prtd->xrun, 0); + msm_compr_send_buffer(prtd); + } } spin_unlock_irqrestore(&prtd->lock, flags);