aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/imx.c
diff options
context:
space:
mode:
authorLucas Stach <l.stach@pengutronix.de>2015-09-04 17:52:39 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-10-04 18:42:26 +0100
commit976b39cd5b1d671bb2b2512b1a79fef2b210c875 (patch)
tree41c11349b2cdfa70c40853f3ea515ca60aaa5e9a /drivers/tty/serial/imx.c
parentserial: imx: set up aging timer interrupt as DMA trigger (diff)
downloadlinux-dev-976b39cd5b1d671bb2b2512b1a79fef2b210c875.tar.xz
linux-dev-976b39cd5b1d671bb2b2512b1a79fef2b210c875.zip
serial: imx: always restart DMA if more data is available
Simplify the DMA restart logic to always queue up the next transfer immediately if there is at least one more byte available in the FIFO, so that the transfer will finish in a limited time. This way the driver stops to rely on zero length transfers to signal transfers ends. Those will go away when the idle detect DMA requests are disabled. Signed-off-by: Lucas Stach <l.stach@pengutronix.de> Acked-by: Jiada Wang <jiada_wang@mentor.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/imx.c')
-rw-r--r--drivers/tty/serial/imx.c25
1 files changed, 11 insertions, 14 deletions
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index db1987a0f513..dbee7ff2f8fd 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -927,23 +927,20 @@ static void dma_rx_callback(void *data)
sport->port.icount.buf_overrun++;
}
tty_flip_buffer_push(port);
+ }
+ /*
+ * Restart RX DMA directly if more data is available in order to skip
+ * the roundtrip through the IRQ handler. If there is some data already
+ * in the FIFO, DMA needs to be restarted soon anyways.
+ *
+ * Otherwise stop the DMA and reactivate FIFO IRQs to restart DMA once
+ * data starts to arrive again.
+ */
+ if (readl(sport->port.membase + USR2) & USR2_RDR)
start_rx_dma(sport);
- } else if (readl(sport->port.membase + USR2) & USR2_RDR) {
- /*
- * start rx_dma directly once data in RXFIFO, more efficient
- * than before:
- * 1. call imx_rx_dma_done to stop dma if no data received
- * 2. wait next RDR interrupt to start dma transfer.
- */
- start_rx_dma(sport);
- } else {
- /*
- * stop dma to prevent too many IDLE event trigged if no data
- * in RXFIFO
- */
+ else
imx_rx_dma_done(sport);
- }
}
static int start_rx_dma(struct imx_port *sport)