diff options
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r-- | drivers/tty/serial/imx.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c index e1f00d5aced9..80456ea2603a 100644 --- a/drivers/tty/serial/imx.c +++ b/drivers/tty/serial/imx.c @@ -575,6 +575,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) { + u32 ucr4 = imx_uart_readl(sport, UCR4); + ucr4 |= UCR4_TCEN; + imx_uart_writel(sport, ucr4, UCR4); + } spin_unlock_irqrestore(&sport->port.lock, flags); } @@ -587,12 +592,16 @@ static void imx_dma_tx(struct imx_port *sport) struct dma_async_tx_descriptor *desc; struct dma_chan *chan = sport->dma_chan_tx; struct device *dev = sport->port.dev; - u32 ucr1; + u32 ucr1, ucr4; int ret; if (sport->dma_is_txing) return; + ucr4 = imx_uart_readl(sport, UCR4); + ucr4 &= ~UCR4_TCEN; + imx_uart_writel(sport, ucr4, UCR4); + sport->tx_bytes = uart_circ_chars_pending(xmit); if (xmit->tail < xmit->head) { @@ -643,7 +652,7 @@ static void imx_start_tx(struct uart_port *port) u32 ucr1; if (port->rs485.flags & SER_RS485_ENABLED) { - u32 ucr2, ucr4; + u32 ucr2; ucr2 = imx_uart_readl(sport, UCR2); if (port->rs485.flags & SER_RS485_RTS_ON_SEND) @@ -655,10 +664,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 */ - ucr4 = imx_uart_readl(sport, UCR4); - ucr4 |= UCR4_TCEN; - imx_uart_writel(sport, ucr4, 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) { + u32 ucr4 = imx_uart_readl(sport, UCR4); + ucr4 |= UCR4_TCEN; + imx_uart_writel(sport, ucr4, UCR4); + } } if (!sport->dma_is_enabled) { |