| From 0090114d336a9604aa2d90bc83f20f7cd121b76c Mon Sep 17 00:00:00 2001 |
| From: Bin Liu <b-liu@ti.com> |
| Date: Fri, 10 Mar 2017 14:43:35 -0600 |
| Subject: usb: musb: cppi41: don't check early-TX-interrupt for Isoch transfer |
| |
| From: Bin Liu <b-liu@ti.com> |
| |
| commit 0090114d336a9604aa2d90bc83f20f7cd121b76c upstream. |
| |
| The CPPI 4.1 driver polls register to workaround the premature TX |
| interrupt issue, but it causes audio playback underrun when triggered in |
| Isoch transfers. |
| |
| Isoch doesn't do back-to-back transfers, the TX should be done by the |
| time the next transfer is scheduled. So skip this polling workaround for |
| Isoch transfer. |
| |
| Fixes: a655f481d83d6 ("usb: musb: musb_cppi41: handle pre-mature TX complete interrupt") |
| Reported-by: Alexandre Bailon <abailon@baylibre.com> |
| Acked-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
| Tested-by: Alexandre Bailon <abailon@baylibre.com> |
| Signed-off-by: Bin Liu <b-liu@ti.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/usb/musb/musb_cppi41.c | 23 +++++++++++++++++++++-- |
| 1 file changed, 21 insertions(+), 2 deletions(-) |
| |
| --- a/drivers/usb/musb/musb_cppi41.c |
| +++ b/drivers/usb/musb/musb_cppi41.c |
| @@ -232,8 +232,27 @@ static void cppi41_dma_callback(void *pr |
| transferred < cppi41_channel->packet_sz) |
| cppi41_channel->prog_len = 0; |
| |
| - if (cppi41_channel->is_tx) |
| - empty = musb_is_tx_fifo_empty(hw_ep); |
| + if (cppi41_channel->is_tx) { |
| + u8 type; |
| + |
| + if (is_host_active(musb)) |
| + type = hw_ep->out_qh->type; |
| + else |
| + type = hw_ep->ep_in.type; |
| + |
| + if (type == USB_ENDPOINT_XFER_ISOC) |
| + /* |
| + * Don't use the early-TX-interrupt workaround below |
| + * for Isoch transfter. Since Isoch are periodic |
| + * transfer, by the time the next transfer is |
| + * scheduled, the current one should be done already. |
| + * |
| + * This avoids audio playback underrun issue. |
| + */ |
| + empty = true; |
| + else |
| + empty = musb_is_tx_fifo_empty(hw_ep); |
| + } |
| |
| if (!cppi41_channel->is_tx || empty) { |
| cppi41_trans_done(cppi41_channel); |