When using RS485 half duplex the Transmitter Complete irq is needed to determine the moment when the transmitter can be disabled. When using DMA this irq must only be enabled when DMA has completed to transfer all data. Otherwise the CPU might busily trigger this irq which is not properly handled and so the also pending irq for the DMA transfer cannot trigger. Signed-off-by: Uwe Kleine-König <u.kleine-koenig@xxxxxxxxxxxxxx> --- drivers/tty/serial/imx.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index 328534f0a950..28eccc0ba344 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -576,6 +576,11 @@ static void dma_tx_callback(void *data) if (!uart_circ_empty(xmit) && !uart_tx_stopped(&sport->port)) imx_dma_tx(sport); + else if (sport->port.rs485.flags & SER_RS485_ENABLED) { + temp = imx_uart_readl(sport, UCR4); + temp |= UCR4_TCEN; + imx_uart_writel(sport, temp, UCR4); + } spin_unlock_irqrestore(&sport->port.lock, flags); } @@ -594,6 +599,10 @@ static void imx_dma_tx(struct imx_port *sport) if (sport->dma_is_txing) return; + temp = imx_uart_readl(sport, UCR4); + temp &= ~UCR4_TCEN; + imx_uart_writel(sport, temp, UCR4); + sport->tx_bytes = uart_circ_chars_pending(xmit); if (xmit->tail < xmit->head) { @@ -654,10 +663,15 @@ static void imx_start_tx(struct uart_port *port) if (!(port->rs485.flags & SER_RS485_RX_DURING_TX)) imx_stop_rx(port); - /* enable transmitter and shifter empty irq */ - temp = imx_uart_readl(sport, UCR4); - temp |= UCR4_TCEN; - imx_uart_writel(sport, temp, UCR4); + /* + * Enable transmitter and shifter empty irq only if DMA is off. + * In the DMA case this is done in the tx-callback. + */ + if (!sport->dma_is_enabled) { + temp = imx_uart_readl(sport, UCR4); + temp |= UCR4_TCEN; + imx_uart_writel(sport, temp, UCR4); + } } if (!sport->dma_is_enabled) { -- 2.16.1 -- To unsubscribe from this list: send the line "unsubscribe linux-serial" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html