[PATCH 2/3] serial: 8250: Clear IIR.RDI in serial8250_clear_fifos()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



At least on MPC83xx (but I suspect also on other implementations) it can
happen that after irqs are disabled but before the FIFOs are cleared a
character is received. Resetting the FIFO throws away that character,
but doesn't clear the IIR.RDI event that signals that there is read data
available.

Read from RX to clear IIR.RDI and throw away the result.

This fixes a infinite loop after the above described race happened: The
irq handler (here: fsl8250_handle_irq()) triggers, but LSR.DR isn't set,
so RX isn't read and the irq handler returns just to be called again.

Signed-off-by: Uwe Kleine-König <u.kleine-koenig@xxxxxxxxxxxxxx>
---
 drivers/tty/serial/8250/8250_port.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index fe8d79c4ae95..8b47ec000922 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -556,6 +556,18 @@ static void serial8250_clear_fifos(struct uart_8250_port *p)
 		serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO |
 			       UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
 		serial_out(p, UART_FCR, 0);
+
+		/*
+		 * When doing rs485 on MPC8313 it can happen that in the short
+		 * window when switching from RX to TX there is a character in
+		 * the RX FIFO which isn't processed any more and then discarded
+		 * in here by clearing the FIFO. In that case IIR signals an RX
+		 * timeout once irqs are reenabled (i.e. in
+		 * serial8250_em485_stop_tx()) but LSR shows no pending event.
+		 * The RX timeout event can only be cleared by reading RX. Do
+		 * this here before reenabling the FIFO and irqs.
+		 */
+		serial_port_in(&p->port, UART_RX);
 	}
 }
 
-- 
2.39.2




[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux