[PATCH] Serial: Add uart_insert_char()

Add uart_insert_char(), which handles inserting characters into the
flip buffer.  This helper function handles the correct semantics
for handling overrun in addition to inserting normal characters.

Signed-off-by: Russell King <rmk@arm.linux.org.uk>
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c
index 33fbda7..0b10169 100644
--- a/drivers/serial/21285.c
+++ b/drivers/serial/21285.c
@@ -126,18 +126,8 @@
 				flag = TTY_FRAME;
 		}
 
-		if ((rxs & port->ignore_status_mask) == 0) {
-			tty_insert_flip_char(tty, ch, flag);
-		}
-		if ((rxs & RXSTAT_OVERRUN) &&
-		    tty->flip.count < TTY_FLIPBUF_SIZE) {
-			/*
-			 * Overrun is special, since it's reported
-			 * immediately, and doesn't affect the current
-			 * character.
-			 */
-			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-		}
+		uart_insert_char(port, rxs, RXSTAT_OVERRUN, ch, flag);
+
 		status = *CSR_UARTFLG;
 	}
 	tty_flip_buffer_push(tty);
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 0d93586..3bbf0cc 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -1122,18 +1122,9 @@
 		}
 		if (uart_handle_sysrq_char(&up->port, ch, regs))
 			goto ignore_char;
-		if ((lsr & up->port.ignore_status_mask) == 0) {
-			tty_insert_flip_char(tty, ch, flag);
-		}
-		if ((lsr & UART_LSR_OE) &&
-		    tty->flip.count < TTY_FLIPBUF_SIZE) {
-			/*
-			 * Overrun is special, since it's reported
-			 * immediately, and doesn't affect the current
-			 * character.
-			 */
-			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-		}
+
+		uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag);
+
 	ignore_char:
 		lsr = serial_inp(up, UART_LSR);
 	} while ((lsr & UART_LSR_DR) && (max_count-- > 0));
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index f2a5e29..2884b31 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -198,18 +198,8 @@
 		if (uart_handle_sysrq_char(port, ch, regs))
 			goto ignore_char;
 
-		if ((rsr & port->ignore_status_mask) == 0) {
-			tty_insert_flip_char(tty, ch, flag);
-		}
-		if ((rsr & UART01x_RSR_OE) &&
-		    tty->flip.count < TTY_FLIPBUF_SIZE) {
-			/*
-			 * Overrun is special, since it's reported
-			 * immediately, and doesn't affect the current
-			 * character
-			 */
-			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-		}
+		uart_insert_char(port, rsr, UART01x_RSR_OE, ch, flag);
+
 	ignore_char:
 		status = UART_GET_FR(port);
 	}
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c
index d5cbef3..7db88ee 100644
--- a/drivers/serial/amba-pl011.c
+++ b/drivers/serial/amba-pl011.c
@@ -163,18 +163,8 @@
 		if (uart_handle_sysrq_char(&uap->port, ch, regs))
 			goto ignore_char;
 
-		if ((rsr & uap->port.ignore_status_mask) == 0) {
-			tty_insert_flip_char(tty, ch, flag);
-		}
-		if ((rsr & UART01x_RSR_OE) &&
-		    tty->flip.count < TTY_FLIPBUF_SIZE) {
-			/*
-			 * Overrun is special, since it's reported
-			 * immediately, and doesn't affect the current
-			 * character
-			 */
-			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-		}
+		uart_insert_char(&uap->port, rsr, UART01x_RSR_OE, ch, flag);
+
 	ignore_char:
 		status = readw(uap->port.membase + UART01x_FR);
 	}
diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c
index 6242f30..e92522b 100644
--- a/drivers/serial/clps711x.c
+++ b/drivers/serial/clps711x.c
@@ -143,10 +143,7 @@
 		 * CHECK: does overrun affect the current character?
 		 * ASSUMPTION: it does not.
 		 */
-		if ((ch & port->ignore_status_mask & ~RXSTAT_OVERRUN) == 0)
-			tty_insert_flip_char(tty, ch, flg);
-		if ((ch & ~port->ignore_status_mask & RXSTAT_OVERRUN) == 0)
-			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+		uart_insert_char(port, ch, UARTDR_OVERR, ch, flg);
 
 	ignore_char:
 		status = clps_readl(SYSFLG(port));
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c
index 51d8a49..9dc151d 100644
--- a/drivers/serial/pxa.c
+++ b/drivers/serial/pxa.c
@@ -161,20 +161,12 @@
 			else if (*status & UART_LSR_FE)
 				flag = TTY_FRAME;
 		}
+
 		if (uart_handle_sysrq_char(&up->port, ch, regs))
 			goto ignore_char;
-		if ((*status & up->port.ignore_status_mask) == 0) {
-			tty_insert_flip_char(tty, ch, flag);
-		}
-		if ((*status & UART_LSR_OE) &&
-		    tty->flip.count < TTY_FLIPBUF_SIZE) {
-			/*
-			 * Overrun is special, since it's reported
-			 * immediately, and doesn't affect the current
-			 * character.
-			 */
-			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-		}
+
+		uart_insert_char(&up->port, *status, UART_LSR_OE, ch, flag);
+
 	ignore_char:
 		*status = serial_in(up, UART_LSR);
 	} while ((*status & UART_LSR_DR) && (max_count-- > 0));
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c
index 435750d..2a9f7ad 100644
--- a/drivers/serial/s3c2410.c
+++ b/drivers/serial/s3c2410.c
@@ -394,20 +394,7 @@
 		if (uart_handle_sysrq_char(port, ch, regs))
 			goto ignore_char;
 
-		if ((uerstat & port->ignore_status_mask) == 0) {
-			tty_insert_flip_char(tty, ch, flag);
-		}
-
-		if ((uerstat & S3C2410_UERSTAT_OVERRUN) &&
-		    tty->flip.count < TTY_FLIPBUF_SIZE) {
-			/*
-			 * Overrun is special, since it's reported
-			 * immediately, and doesn't affect the current
-			 * character.
-			 */
-
-			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-		}
+		uart_insert_char(port, uerstat, S3C2410_UERSTAT_OVERRUN, ch, flag);
 
 	ignore_char:
 		continue;
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c
index 157218b..22565a6 100644
--- a/drivers/serial/sa1100.c
+++ b/drivers/serial/sa1100.c
@@ -237,10 +237,7 @@
 		if (uart_handle_sysrq_char(&sport->port, ch, regs))
 			goto ignore_char;
 
-		if ((status & port->ignore_status_mask & ~UTSR1_TO_SM(UTSR1_ROR)) == 0)
-			tty_insert_flip_char(tty, ch, flg);
-		if (status & ~port->ignore_status_mask & UTSR1_TO_SM(UTSR1_ROR))
-			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+		uart_insert_char(&sport->port, status, UTSR1_TO_SM(UTSR1_ROR), ch, flg);
 
 	ignore_char:
 		status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) |
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c
index 85cfa08..56f269b 100644
--- a/drivers/serial/serial_lh7a40x.c
+++ b/drivers/serial/serial_lh7a40x.c
@@ -190,18 +190,7 @@
 		if (uart_handle_sysrq_char (port, (unsigned char) data, regs))
 			continue;
 
-		if ((data & port->ignore_status_mask) == 0) {
-			tty_insert_flip_char(tty, data, flag);
-		}
-		if ((data & RxOverrunError)
-		    && tty->flip.count < TTY_FLIPBUF_SIZE) {
-			/*
-			 * Overrun is special, since it's reported
-			 * immediately, and doesn't affect the current
-			 * character
-			 */
-			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-		}
+		uart_insert_char(port, data, RxOverrunError, data, flag);
 	}
 	tty_flip_buffer_push (tty);
 	return;
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 37b2ef2..3f1051a 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -350,18 +350,9 @@
 		}
 		if (uart_handle_sysrq_char(&up->port, ch, regs))
 			goto ignore_char;
-		if ((disr & up->port.ignore_status_mask) == 0) {
-			tty_insert_flip_char(tty, ch, flag);
-		}
-		if ((disr & TXX9_SIDISR_UOER) &&
-		    tty->flip.count < TTY_FLIPBUF_SIZE) {
-			/*
-			 * Overrun is special, since it's reported
-			 * immediately, and doesn't affect the current
-			 * character.
-			 */
-			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
-		}
+
+		uart_insert_char(&up->port, disr, TXX9_SIDISR_UOER, ch, flag);
+
 	ignore_char:
 		disr = sio_in(up, TXX9_SIDISR);
 	} while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0));
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c
index 3078861..5d2ceb6 100644
--- a/drivers/serial/vr41xx_siu.c
+++ b/drivers/serial/vr41xx_siu.c
@@ -412,10 +412,8 @@
 
 		if (uart_handle_sysrq_char(port, ch, regs))
 			goto ignore_char;
-		if ((lsr & port->ignore_status_mask) == 0)
-			tty_insert_flip_char(tty, ch, flag);
-		if ((lsr & UART_LSR_OE) && (tty->flip.count < TTY_FLIPBUF_SIZE))
-			tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+
+		uart_insert_char(port, lsr, UART_LSR_OE, ch, flag);
 
 	ignore_char:
 		lsr = siu_read(port, UART_LSR);