serial: bcm63xx_uart: fix irq storm after rx fifo overrun.
authorMaxime Bizon <mbizon@freebox.fr>
Fri, 10 Jun 2011 21:17:58 +0000 (23:17 +0200)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 16 Jun 2011 19:01:58 +0000 (12:01 -0700)
RX fifo reset is required to clear irq.

Signed-off-by: Maxime Bizon <mbizon@freebox.fr>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/tty/serial/bcm63xx_uart.c

index a1a0e55d0807761b59ae9a9374c3de5c03f57007..c0b68b9cad911f66652e2e9cdd5f41600a3fc21c 100644 (file)
@@ -250,6 +250,20 @@ static void bcm_uart_do_rx(struct uart_port *port)
                /* get overrun/fifo empty information from ier
                 * register */
                iestat = bcm_uart_readl(port, UART_IR_REG);
+
+               if (unlikely(iestat & UART_IR_STAT(UART_IR_RXOVER))) {
+                       unsigned int val;
+
+                       /* fifo reset is required to clear
+                        * interrupt */
+                       val = bcm_uart_readl(port, UART_CTL_REG);
+                       val |= UART_CTL_RSTRXFIFO_MASK;
+                       bcm_uart_writel(port, val, UART_CTL_REG);
+
+                       port->icount.overrun++;
+                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+               }
+
                if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY)))
                        break;
 
@@ -284,10 +298,6 @@ static void bcm_uart_do_rx(struct uart_port *port)
                if (uart_handle_sysrq_char(port, c))
                        continue;
 
-               if (unlikely(iestat & UART_IR_STAT(UART_IR_RXOVER))) {
-                       port->icount.overrun++;
-                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-               }
 
                if ((cstat & port->ignore_status_mask) == 0)
                        tty_insert_flip_char(tty, c, flag);