* Note that the error handling code is
* out of the main execution path
*/
- if (unlikely(ch & UART_ANY_ERR))
- goto handle_error;
+ if (unlikely(ch & UART_ANY_ERR)) {
+ if (ch & UARTDR_PARERR)
+ port->icount.parity++;
+ else if (ch & UARTDR_FRMERR)
+ port->icount.frame++;
+ if (ch & UARTDR_OVERR)
+ port->icount.overrun++;
- if (uart_handle_sysrq_char(port, ch, regs))
- goto ignore_char;
+ ch &= port->read_status_mask;
- error_return:
- tty_insert_flip_char(tty, ch, flg);
- ignore_char:
- status = clps_readl(SYSFLG(port));
- }
- out:
- tty_flip_buffer_push(tty);
- return IRQ_HANDLED;
+ if (ch & UARTDR_PARERR)
+ flg = TTY_PARITY;
+ else if (ch & UARTDR_FRMERR)
+ flg = TTY_FRAME;
- handle_error:
- if (ch & UARTDR_PARERR)
- port->icount.parity++;
- else if (ch & UARTDR_FRMERR)
- port->icount.frame++;
- if (ch & UARTDR_OVERR)
- port->icount.overrun++;
-
- if (ch & port->ignore_status_mask) {
- if (++ignored > 100)
- goto out;
- goto ignore_char;
- }
- ch &= port->read_status_mask;
+#ifdef SUPPORT_SYSRQ
+ port->sysrq = 0;
+#endif
+ }
- if (ch & UARTDR_PARERR)
- flg = TTY_PARITY;
- else if (ch & UARTDR_FRMERR)
- flg = TTY_FRAME;
+ if (uart_handle_sysrq_char(port, ch, regs))
+ goto ignore_char;
- if (ch & UARTDR_OVERR) {
/*
* CHECK: does overrun affect the current character?
* ASSUMPTION: it does not.
*/
- tty_insert_flip_char(tty, ch, flg);
- ch = 0;
- flg = TTY_OVERRUN;
+ 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);
+
+ ignore_char:
+ status = clps_readl(SYSFLG(port));
}
-#ifdef SUPPORT_SYSRQ
- port->sysrq = 0;
-#endif
- goto error_return;
+ tty_flip_buffer_push(tty);
+ return IRQ_HANDLED;
}
static irqreturn_t clps711xuart_int_tx(int irq, void *dev_id, struct pt_regs *regs)
* note that the error handling code is
* out of the main execution path
*/
- if (status & UTSR1_TO_SM(UTSR1_PRE | UTSR1_FRE | UTSR1_ROR))
- goto handle_error;
+ if (status & UTSR1_TO_SM(UTSR1_PRE | UTSR1_FRE | UTSR1_ROR)) {
+ if (status & UTSR1_TO_SM(UTSR1_PRE))
+ sport->port.icount.parity++;
+ else if (status & UTSR1_TO_SM(UTSR1_FRE))
+ sport->port.icount.frame++;
+ if (status & UTSR1_TO_SM(UTSR1_ROR))
+ sport->port.icount.overrun++;
+
+ status &= sport->port.read_status_mask;
+
+ if (status & UTSR1_TO_SM(UTSR1_PRE))
+ flg = TTY_PARITY;
+ else if (status & UTSR1_TO_SM(UTSR1_FRE))
+ flg = TTY_FRAME;
+
+#ifdef SUPPORT_SYSRQ
+ sport->port.sysrq = 0;
+#endif
+ }
if (uart_handle_sysrq_char(&sport->port, ch, regs))
goto ignore_char;
- error_return:
- tty_insert_flip_char(tty, ch, flg);
+ 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);
+
ignore_char:
status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) |
UTSR0_TO_SM(UART_GET_UTSR0(sport));
}
- out:
tty_flip_buffer_push(tty);
- return;
-
- handle_error:
- if (status & UTSR1_TO_SM(UTSR1_PRE))
- sport->port.icount.parity++;
- else if (status & UTSR1_TO_SM(UTSR1_FRE))
- sport->port.icount.frame++;
- if (status & UTSR1_TO_SM(UTSR1_ROR))
- sport->port.icount.overrun++;
-
- if (status & sport->port.ignore_status_mask) {
- if (++ignored > 100)
- goto out;
- goto ignore_char;
- }
-
- status &= sport->port.read_status_mask;
-
- if (status & UTSR1_TO_SM(UTSR1_PRE))
- flg = TTY_PARITY;
- else if (status & UTSR1_TO_SM(UTSR1_FRE))
- flg = TTY_FRAME;
-
- if (status & UTSR1_TO_SM(UTSR1_ROR)) {
- /*
- * overrun does *not* affect the character
- * we read from the FIFO
- */
- tty_insert_flip_char(tty, ch, flg);
- ch = 0;
- flg = TTY_OVERRUN;
- }
-#ifdef SUPPORT_SYSRQ
- sport->port.sysrq = 0;
-#endif
- goto error_return;
}
static void sa1100_tx_chars(struct sa1100_port *sport)