summaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/8250.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/serial/8250.c')
-rw-r--r--drivers/tty/serial/8250.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c
index a5e290de8c9..b40f7b90c81 100644
--- a/drivers/tty/serial/8250.c
+++ b/drivers/tty/serial/8250.c
@@ -1433,6 +1433,27 @@ static void serial8250_enable_ms(struct uart_port *port)
serial_out(up, UART_IER, up->ier);
}
+/*
+ * Clear the Tegra rx fifo after a break
+ *
+ * FIXME: This needs to become a port specific callback once we have a
+ * framework for this
+ */
+static void clear_rx_fifo(struct uart_8250_port *up)
+{
+ unsigned int status, tmout = 10000;
+ do {
+ status = serial_in(up, UART_LSR);
+ if (status & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS))
+ status = serial_in(up, UART_RX);
+ else
+ break;
+ if (--tmout == 0)
+ break;
+ udelay(1);
+ } while (1);
+}
+
static void
receive_chars(struct uart_8250_port *up, unsigned int *status)
{
@@ -1468,6 +1489,13 @@ receive_chars(struct uart_8250_port *up, unsigned int *status)
lsr &= ~(UART_LSR_FE | UART_LSR_PE);
up->port.icount.brk++;
/*
+ * If tegra port then clear the rx fifo to
+ * accept another break/character.
+ */
+ if (up->port.type == PORT_TEGRA)
+ clear_rx_fifo(up);
+
+ /*
* We do the SysRQ and SAK checking
* here because otherwise the break
* may get masked by ignore_status_mask