diff options
author | Shardar Shariff Md <smohammed@nvidia.com> | 2019-09-04 10:12:58 +0530 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-09-05 10:00:03 +0200 |
commit | b9c2470fb150a3cc82a3ee8072da88cb2a73e213 (patch) | |
tree | 6d3043b8f583e99a5d378a031c2c150f813a2f89 /drivers/tty/serial/serial-tegra.c | |
parent | 494f79bd2365703e4093efa0ecf4b139d83aba97 (diff) | |
download | linux-b9c2470fb150a3cc82a3ee8072da88cb2a73e213.tar.bz2 |
serial: tegra: flush the RX fifo on frame error
FIFO reset/flush code implemented now does not follow programming
guidelines. RTS line has to be turned off while flushing FIFOs to
avoid new transfers. Also check LSR bits UART_LSR_TEMT and UART_LSR_DR
to confirm FIFOs are flushed.
Signed-off-by: Shardar Shariff Md <smohammed@nvidia.com>
Signed-off-by: Krishna Yarlagadda <kyarlagadda@nvidia.com>
Link: https://lore.kernel.org/r/1567572187-29820-4-git-send-email-kyarlagadda@nvidia.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/serial-tegra.c')
-rw-r--r-- | drivers/tty/serial/serial-tegra.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/drivers/tty/serial/serial-tegra.c b/drivers/tty/serial/serial-tegra.c index 29bf7b774f42..4cd6d5f84171 100644 --- a/drivers/tty/serial/serial-tegra.c +++ b/drivers/tty/serial/serial-tegra.c @@ -266,6 +266,10 @@ static void tegra_uart_wait_sym_time(struct tegra_uart_port *tup, static void tegra_uart_fifo_reset(struct tegra_uart_port *tup, u8 fcr_bits) { unsigned long fcr = tup->fcr_shadow; + unsigned int lsr, tmout = 10000; + + if (tup->rts_active) + set_rts(tup, false); if (tup->cdata->allow_txfifo_reset_fifo_mode) { fcr |= fcr_bits & (UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); @@ -289,6 +293,16 @@ static void tegra_uart_fifo_reset(struct tegra_uart_port *tup, u8 fcr_bits) * to propagate, otherwise data could be lost. */ tegra_uart_wait_cycle_time(tup, 32); + + do { + lsr = tegra_uart_read(tup, UART_LSR); + if ((lsr | UART_LSR_TEMT) && !(lsr & UART_LSR_DR)) + break; + udelay(1); + } while (--tmout); + + if (tup->rts_active) + set_rts(tup, true); } static int tegra_set_baudrate(struct tegra_uart_port *tup, unsigned int baud) |