Skip to content

Commit

Permalink
[ARM] 4994/1: <IMX UART>: Move error handling into execution path
Browse files Browse the repository at this point in the history
Move the error handling code for erroneous receive characters into
execution path. This makes the code more readable and the compiler
should know how to optimize this, right?

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
  • Loading branch information
Sascha Hauer authored and Russell King committed Apr 17, 2008
1 parent 8c9915b commit 864eeed
Showing 1 changed file with 33 additions and 41 deletions.
74 changes: 33 additions & 41 deletions drivers/serial/imx.c
Original file line number Diff line number Diff line change
Expand Up @@ -354,66 +354,58 @@ static irqreturn_t imx_rxint(int irq, void *dev_id)
struct tty_struct *tty = sport->port.info->tty;
unsigned long flags, temp;

rx = readl(sport->port.membase + URXD0);
spin_lock_irqsave(&sport->port.lock,flags);

do {
while ((rx = readl(sport->port.membase + URXD0)) & URXD_CHARRDY) {
flg = TTY_NORMAL;
sport->port.icount.rx++;

temp = readl(sport->port.membase + USR2);
if( temp & USR2_BRCD ) {
if (temp & USR2_BRCD) {
writel(temp | USR2_BRCD, sport->port.membase + USR2);
if(uart_handle_break(&sport->port))
goto ignore_char;
if (uart_handle_break(&sport->port))
continue;
}

if (uart_handle_sysrq_char
(&sport->port, (unsigned char)rx))
goto ignore_char;
continue;

if (rx & (URXD_PRERR | URXD_OVRRUN | URXD_FRMERR) ) {
if (rx & URXD_PRERR)
sport->port.icount.parity++;
else if (rx & URXD_FRMERR)
sport->port.icount.frame++;
if (rx & URXD_OVRRUN)
sport->port.icount.overrun++;

if (rx & sport->port.ignore_status_mask) {
if (++ignored > 100)
goto out;
continue;
}

rx &= sport->port.read_status_mask;

if (rx & URXD_PRERR)
flg = TTY_PARITY;
else if (rx & URXD_FRMERR)
flg = TTY_FRAME;
if (rx & URXD_OVRRUN)
flg = TTY_OVERRUN;

if( rx & (URXD_PRERR | URXD_OVRRUN | URXD_FRMERR) )
goto handle_error;
#ifdef SUPPORT_SYSRQ
sport->port.sysrq = 0;
#endif
}

error_return:
tty_insert_flip_char(tty, rx, flg);

ignore_char:
rx = readl(sport->port.membase + URXD0);
} while(rx & URXD_CHARRDY);
}

out:
spin_unlock_irqrestore(&sport->port.lock,flags);
tty_flip_buffer_push(tty);
return IRQ_HANDLED;

handle_error:
if (rx & URXD_PRERR)
sport->port.icount.parity++;
else if (rx & URXD_FRMERR)
sport->port.icount.frame++;
if (rx & URXD_OVRRUN)
sport->port.icount.overrun++;

if (rx & sport->port.ignore_status_mask) {
if (++ignored > 100)
goto out;
goto ignore_char;
}

rx &= sport->port.read_status_mask;

if (rx & URXD_PRERR)
flg = TTY_PARITY;
else if (rx & URXD_FRMERR)
flg = TTY_FRAME;
if (rx & URXD_OVRRUN)
flg = TTY_OVERRUN;

#ifdef SUPPORT_SYSRQ
sport->port.sysrq = 0;
#endif
goto error_return;
}

/*
Expand Down

0 comments on commit 864eeed

Please sign in to comment.