| From 392bceedb107a3dc1d4287e63d7670d08f702feb Mon Sep 17 00:00:00 2001 |
| From: Philipp Zabel <p.zabel@pengutronix.de> |
| Date: Tue, 19 May 2015 10:54:09 +0200 |
| Subject: serial: imx: Fix DMA handling for IDLE condition aborts |
| |
| From: Philipp Zabel <p.zabel@pengutronix.de> |
| |
| commit 392bceedb107a3dc1d4287e63d7670d08f702feb upstream. |
| |
| The driver configures the IDLE condition to interrupt the SDMA engine. |
| Since the SDMA UART ROM script doesn't clear the IDLE bit itself, this |
| caused repeated 1-byte DMA transfers, regardless of available data in the |
| RX FIFO. Also, when returning due to the IDLE condition, the UART ROM |
| script already increased its counter, causing residue to be off by one. |
| |
| This patch clears the IDLE condition to avoid repeated 1-byte DMA transfers |
| and decreases count by when the DMA transfer was aborted due to the IDLE |
| condition, fixing serial transfers using DMA on i.MX6Q. |
| |
| Reported-by: Peter Seiderer <ps.report@gmx.net> |
| Signed-off-by: Philipp Zabel <p.zabel@pengutronix.de> |
| Tested-by: Fabio Estevam <fabio.estevam@freescale.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/tty/serial/imx.c | 8 ++++++++ |
| 1 file changed, 8 insertions(+) |
| |
| --- a/drivers/tty/serial/imx.c |
| +++ b/drivers/tty/serial/imx.c |
| @@ -959,6 +959,14 @@ static void dma_rx_callback(void *data) |
| |
| status = dmaengine_tx_status(chan, (dma_cookie_t)0, &state); |
| count = RX_BUF_SIZE - state.residue; |
| + |
| + if (readl(sport->port.membase + USR2) & USR2_IDLE) { |
| + /* In condition [3] the SDMA counted up too early */ |
| + count--; |
| + |
| + writel(USR2_IDLE, sport->port.membase + USR2); |
| + } |
| + |
| dev_dbg(sport->port.dev, "We get %d bytes.\n", count); |
| |
| if (count) { |