Skip to content

Commit 03430b1

Browse files
committed
Revert "Revert "serial: 8250: Fix clearing FIFOs in RS485 mode again""
This reverts commit 3c9dc27. Signed-off-by: Robert Nelson <[email protected]>
1 parent f3399eb commit 03430b1

File tree

1 file changed

+24
-5
lines changed

1 file changed

+24
-5
lines changed

drivers/tty/serial/8250/8250_port.c

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -553,11 +553,30 @@ static unsigned int serial_icr_read(struct uart_8250_port *up, int offset)
553553
*/
554554
static void serial8250_clear_fifos(struct uart_8250_port *p)
555555
{
556+
unsigned char fcr;
557+
unsigned char clr_mask = UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT;
558+
556559
if (p->capabilities & UART_CAP_FIFO) {
557-
serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO);
558-
serial_out(p, UART_FCR, UART_FCR_ENABLE_FIFO |
559-
UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
560-
serial_out(p, UART_FCR, 0);
560+
/*
561+
* Make sure to avoid changing FCR[7:3] and ENABLE_FIFO bits.
562+
* In case ENABLE_FIFO is not set, there is nothing to flush
563+
* so just return. Furthermore, on certain implementations of
564+
* the 8250 core, the FCR[7:3] bits may only be changed under
565+
* specific conditions and changing them if those conditions
566+
* are not met can have nasty side effects. One such core is
567+
* the 8250-omap present in TI AM335x.
568+
*/
569+
fcr = serial_in(p, UART_FCR);
570+
571+
/* FIFO is not enabled, there's nothing to clear. */
572+
if (!(fcr & UART_FCR_ENABLE_FIFO))
573+
return;
574+
575+
fcr |= clr_mask;
576+
serial_out(p, UART_FCR, fcr);
577+
578+
fcr &= ~clr_mask;
579+
serial_out(p, UART_FCR, fcr);
561580
}
562581
}
563582

@@ -1405,7 +1424,7 @@ static void __do_stop_tx_rs485(struct uart_8250_port *p)
14051424
* Enable previously disabled RX interrupts.
14061425
*/
14071426
if (!(p->port.rs485.flags & SER_RS485_RX_DURING_TX)) {
1408-
serial8250_clear_and_reinit_fifos(p);
1427+
serial8250_clear_fifos(p);
14091428

14101429
p->ier |= UART_IER_RLSI | UART_IER_RDI;
14111430
serial8250_set_IER(p, p->ier);

0 commit comments

Comments
 (0)