@@ -553,11 +553,30 @@ static unsigned int serial_icr_read(struct uart_8250_port *up, int offset)
553553 */
554554static 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