diff options
author | Stephen Warren <swarren@nvidia.com> | 2011-05-17 18:12:37 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-05-19 19:51:02 -0400 |
commit | 5f873bae704cf8b7cbd64b5720912266286c9146 (patch) | |
tree | 0e861218bdb25d0ad3f41aa569f89d0f56d59d18 /drivers/tty | |
parent | 4539c24fe4f92c09ee668ef959d3e8180df619b9 (diff) |
tty/serial: Fix break handling for PORT_TEGRA
When a break is received, Tegra's UART apparently fills the FIFO with
0 bytes. These must be drained so that they aren't interpreted as actual
data received. This allows e.g. MAGIC_SYSRQ to work on Tegra's UARTs.
v2: Added FIXME comment to clear_rx_fifo
Originally-by: Laxman Dewangan <ldewangan@nvidia.com>
Cc: Laxman Dewangan <ldewangan@nvidia.com>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Acked-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/tty')
-rw-r--r-- | drivers/tty/serial/8250.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/drivers/tty/serial/8250.c b/drivers/tty/serial/8250.c index a5e290de8c93..b40f7b90c81d 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) | |||
1433 | serial_out(up, UART_IER, up->ier); | 1433 | serial_out(up, UART_IER, up->ier); |
1434 | } | 1434 | } |
1435 | 1435 | ||
1436 | /* | ||
1437 | * Clear the Tegra rx fifo after a break | ||
1438 | * | ||
1439 | * FIXME: This needs to become a port specific callback once we have a | ||
1440 | * framework for this | ||
1441 | */ | ||
1442 | static void clear_rx_fifo(struct uart_8250_port *up) | ||
1443 | { | ||
1444 | unsigned int status, tmout = 10000; | ||
1445 | do { | ||
1446 | status = serial_in(up, UART_LSR); | ||
1447 | if (status & (UART_LSR_FIFOE | UART_LSR_BRK_ERROR_BITS)) | ||
1448 | status = serial_in(up, UART_RX); | ||
1449 | else | ||
1450 | break; | ||
1451 | if (--tmout == 0) | ||
1452 | break; | ||
1453 | udelay(1); | ||
1454 | } while (1); | ||
1455 | } | ||
1456 | |||
1436 | static void | 1457 | static void |
1437 | receive_chars(struct uart_8250_port *up, unsigned int *status) | 1458 | receive_chars(struct uart_8250_port *up, unsigned int *status) |
1438 | { | 1459 | { |
@@ -1468,6 +1489,13 @@ receive_chars(struct uart_8250_port *up, unsigned int *status) | |||
1468 | lsr &= ~(UART_LSR_FE | UART_LSR_PE); | 1489 | lsr &= ~(UART_LSR_FE | UART_LSR_PE); |
1469 | up->port.icount.brk++; | 1490 | up->port.icount.brk++; |
1470 | /* | 1491 | /* |
1492 | * If tegra port then clear the rx fifo to | ||
1493 | * accept another break/character. | ||
1494 | */ | ||
1495 | if (up->port.type == PORT_TEGRA) | ||
1496 | clear_rx_fifo(up); | ||
1497 | |||
1498 | /* | ||
1471 | * We do the SysRQ and SAK checking | 1499 | * We do the SysRQ and SAK checking |
1472 | * here because otherwise the break | 1500 | * here because otherwise the break |
1473 | * may get masked by ignore_status_mask | 1501 | * may get masked by ignore_status_mask |