tty/serial: omap: fix RX interrupt enable/disable in half-duplex TX
authorDimitris Lampridis <dlampridis@logikonlabs.com>
Thu, 13 Mar 2014 13:11:46 +0000 (15:11 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 17 Mar 2014 23:23:07 +0000 (16:23 -0700)
Make sure that serial_omap_stop_rx() also disables RDI (Receiver Data Interrupt),
otherwise the interrupt handler will call serial_omap_rdi() to read the new data,
resulting in the transmission being echoed back.

When the half-duplex transmission is complete, in order to reverse the effects of
serial_omap_stop_rx(), we should re-enable:

  * the RX interrupts _without_ overwriting up->ier

  * the UART_LSR_DR bit of the up->port.read_status_mask

Signed-off-by: Dimitris Lampridis <dlampridis@logikonlabs.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/tty/serial/omap-serial.c

index 77f035158d6cac1cd7bd5ec094c2a9dfa71cab4e..65abea2c6e470ec61fdf5bb79bc64aeeaf039ffa 100644 (file)
@@ -342,7 +342,8 @@ static void serial_omap_stop_tx(struct uart_port *port)
 
        if ((up->rs485.flags & SER_RS485_ENABLED) &&
            !(up->rs485.flags & SER_RS485_RX_DURING_TX)) {
-               up->ier = UART_IER_RLSI | UART_IER_RDI;
+               up->ier |= UART_IER_RLSI | UART_IER_RDI;
+               up->port.read_status_mask |= UART_LSR_DR;
                serial_out(up, UART_IER, up->ier);
        }
 
@@ -355,7 +356,7 @@ static void serial_omap_stop_rx(struct uart_port *port)
        struct uart_omap_port *up = to_uart_omap_port(port);
 
        pm_runtime_get_sync(up->dev);
-       up->ier &= ~UART_IER_RLSI;
+       up->ier &= ~(UART_IER_RLSI | UART_IER_RDI);
        up->port.read_status_mask &= ~UART_LSR_DR;
        serial_out(up, UART_IER, up->ier);
        pm_runtime_mark_last_busy(up->dev);