diff options
Diffstat (limited to 'drivers/usb/renesas_usbhs/fifo.c')
-rw-r--r-- | drivers/usb/renesas_usbhs/fifo.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 4fd36530bfa3..3efece3c72a3 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -544,6 +544,7 @@ static int usbhsf_pio_try_push(struct usbhs_pkt *pkt, int *is_done) usbhsf_send_terminator(pipe, fifo); usbhsf_tx_irq_ctrl(pipe, !*is_done); + usbhs_pipe_running(pipe, !*is_done); usbhs_pipe_enable(pipe); dev_dbg(dev, " send %d (%d/ %d/ %d/ %d)\n", @@ -570,12 +571,21 @@ usbhs_fifo_write_busy: * retry in interrupt */ usbhsf_tx_irq_ctrl(pipe, 1); + usbhs_pipe_running(pipe, 1); return ret; } +static int usbhsf_pio_prepare_push(struct usbhs_pkt *pkt, int *is_done) +{ + if (usbhs_pipe_is_running(pkt->pipe)) + return 0; + + return usbhsf_pio_try_push(pkt, is_done); +} + struct usbhs_pkt_handle usbhs_fifo_pio_push_handler = { - .prepare = usbhsf_pio_try_push, + .prepare = usbhsf_pio_prepare_push, .try_run = usbhsf_pio_try_push, }; @@ -589,6 +599,9 @@ static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done) if (usbhs_pipe_is_busy(pipe)) return 0; + if (usbhs_pipe_is_running(pipe)) + return 0; + /* * pipe enable to prepare packet receive */ @@ -597,6 +610,7 @@ static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done) usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->length); usbhs_pipe_enable(pipe); + usbhs_pipe_running(pipe, 1); usbhsf_rx_irq_ctrl(pipe, 1); return 0; @@ -642,6 +656,7 @@ static int usbhsf_pio_try_pop(struct usbhs_pkt *pkt, int *is_done) (total_len < maxp)) { /* short packet */ *is_done = 1; usbhsf_rx_irq_ctrl(pipe, 0); + usbhs_pipe_running(pipe, 0); usbhs_pipe_disable(pipe); /* disable pipe first */ } @@ -805,6 +820,7 @@ static void xfer_work(struct work_struct *work) dev_dbg(dev, " %s %d (%d/ %d)\n", fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero); + usbhs_pipe_running(pipe, 1); usbhs_pipe_set_trans_count_if_bulk(pipe, pkt->trans); usbhs_pipe_enable(pipe); usbhsf_dma_start(pipe, fifo); @@ -836,6 +852,10 @@ static int usbhsf_dma_prepare_push(struct usbhs_pkt *pkt, int *is_done) if ((uintptr_t)(pkt->buf + pkt->actual) & 0x7) /* 8byte alignment */ goto usbhsf_pio_prepare_push; + /* return at this time if the pipe is running */ + if (usbhs_pipe_is_running(pipe)) + return 0; + /* get enable DMA fifo */ fifo = usbhsf_get_dma_fifo(priv, pkt); if (!fifo) @@ -873,6 +893,7 @@ static int usbhsf_dma_push_done(struct usbhs_pkt *pkt, int *is_done) pkt->actual = pkt->trans; *is_done = !pkt->zero; /* send zero packet ? */ + usbhs_pipe_running(pipe, !*is_done); usbhsf_dma_stop(pipe, pipe->fifo); usbhsf_dma_unmap(pkt); @@ -972,8 +993,10 @@ static int usbhsf_dma_pop_done(struct usbhs_pkt *pkt, int *is_done) if ((pkt->actual == pkt->length) || /* receive all data */ (pkt->trans < maxp)) { /* short packet */ *is_done = 1; + usbhs_pipe_running(pipe, 0); } else { /* re-enable */ + usbhs_pipe_running(pipe, 0); usbhsf_prepare_pop(pkt, is_done); } |