From: Paul Fulghum <paulkf@microgate.com>

Fix lockup caused by 8520 serial driver not clearing receive interrupt if
flip buffer becomes full.

Signed-off-by: Paul Fulghum <paulkf@microgate.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/serial/8250.c |   21 ++++++++++++++++++---
 1 files changed, 18 insertions(+), 3 deletions(-)

diff -puN drivers/serial/8250.c~serial-8250-receive-lockup-fix drivers/serial/8250.c
--- 25/drivers/serial/8250.c~serial-8250-receive-lockup-fix	2004-11-10 00:47:49.403649968 -0800
+++ 25-akpm/drivers/serial/8250.c	2004-11-10 00:49:14.343737112 -0800
@@ -983,9 +983,24 @@ receive_chars(struct uart_8250_port *up,
 	do {
 		if (unlikely(tty->flip.count >= TTY_FLIPBUF_SIZE)) {
 			tty->flip.work.func((void *)tty);
-			if (tty->flip.count >= TTY_FLIPBUF_SIZE)
-				return; // if TTY_DONT_FLIP is set
-		}
+			if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
+				/*
+				 * no room in flip buffer, discard rx FIFO
+				 * contents to clear IRQ.
+				 * *FIXME* Hardware with auto flow control
+				 * would benefit from leaving the data in the
+				 * FIFO and disabling the rx IRQ until space
+				 * becomes available.
+				 */
+				do {
+					serial_inp(up, UART_RX);
+					up->port.icount.overrun++;
+					*status = serial_inp(up, UART_LSR);
+				} while ((*status & UART_LSR_DR) &&
+						(max_count-- > 0));
+				return;	/* if TTY_DONT_FLIP is set */
+			}
+  		}
 		ch = serial_inp(up, UART_RX);
 		*tty->flip.char_buf_ptr = ch;
 		*tty->flip.flag_buf_ptr = TTY_NORMAL;
_