diff options
author | Sascha Hauer <sascha@saschahauer.de> | 2008-04-17 03:39:22 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-04-17 11:18:19 -0400 |
commit | 864eeed051b527c8081e2f85b51ba24823acaf71 (patch) | |
tree | 7fa05275be02d98f5956b3030cdbf3c2a5f18228 /drivers/serial/imx.c | |
parent | 8c9915bf310eeb1fe5a9a614cda6ee57d712460b (diff) |
[ARM] 4994/1: <IMX UART>: Move error handling into execution path
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>
Diffstat (limited to 'drivers/serial/imx.c')
-rw-r--r-- | drivers/serial/imx.c | 74 |
1 files changed, 33 insertions, 41 deletions
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index 06fa54c53fdc..c637ae219126 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c | |||
@@ -354,66 +354,58 @@ static irqreturn_t imx_rxint(int irq, void *dev_id) | |||
354 | struct tty_struct *tty = sport->port.info->tty; | 354 | struct tty_struct *tty = sport->port.info->tty; |
355 | unsigned long flags, temp; | 355 | unsigned long flags, temp; |
356 | 356 | ||
357 | rx = readl(sport->port.membase + URXD0); | ||
358 | spin_lock_irqsave(&sport->port.lock,flags); | 357 | spin_lock_irqsave(&sport->port.lock,flags); |
359 | 358 | ||
360 | do { | 359 | while ((rx = readl(sport->port.membase + URXD0)) & URXD_CHARRDY) { |
361 | flg = TTY_NORMAL; | 360 | flg = TTY_NORMAL; |
362 | sport->port.icount.rx++; | 361 | sport->port.icount.rx++; |
363 | 362 | ||
364 | temp = readl(sport->port.membase + USR2); | 363 | temp = readl(sport->port.membase + USR2); |
365 | if( temp & USR2_BRCD ) { | 364 | if (temp & USR2_BRCD) { |
366 | writel(temp | USR2_BRCD, sport->port.membase + USR2); | 365 | writel(temp | USR2_BRCD, sport->port.membase + USR2); |
367 | if(uart_handle_break(&sport->port)) | 366 | if (uart_handle_break(&sport->port)) |
368 | goto ignore_char; | 367 | continue; |
369 | } | 368 | } |
370 | 369 | ||
371 | if (uart_handle_sysrq_char | 370 | if (uart_handle_sysrq_char |
372 | (&sport->port, (unsigned char)rx)) | 371 | (&sport->port, (unsigned char)rx)) |
373 | goto ignore_char; | 372 | continue; |
373 | |||
374 | if (rx & (URXD_PRERR | URXD_OVRRUN | URXD_FRMERR) ) { | ||
375 | if (rx & URXD_PRERR) | ||
376 | sport->port.icount.parity++; | ||
377 | else if (rx & URXD_FRMERR) | ||
378 | sport->port.icount.frame++; | ||
379 | if (rx & URXD_OVRRUN) | ||
380 | sport->port.icount.overrun++; | ||
381 | |||
382 | if (rx & sport->port.ignore_status_mask) { | ||
383 | if (++ignored > 100) | ||
384 | goto out; | ||
385 | continue; | ||
386 | } | ||
387 | |||
388 | rx &= sport->port.read_status_mask; | ||
389 | |||
390 | if (rx & URXD_PRERR) | ||
391 | flg = TTY_PARITY; | ||
392 | else if (rx & URXD_FRMERR) | ||
393 | flg = TTY_FRAME; | ||
394 | if (rx & URXD_OVRRUN) | ||
395 | flg = TTY_OVERRUN; | ||
374 | 396 | ||
375 | if( rx & (URXD_PRERR | URXD_OVRRUN | URXD_FRMERR) ) | 397 | #ifdef SUPPORT_SYSRQ |
376 | goto handle_error; | 398 | sport->port.sysrq = 0; |
399 | #endif | ||
400 | } | ||
377 | 401 | ||
378 | error_return: | ||
379 | tty_insert_flip_char(tty, rx, flg); | 402 | tty_insert_flip_char(tty, rx, flg); |
380 | 403 | } | |
381 | ignore_char: | ||
382 | rx = readl(sport->port.membase + URXD0); | ||
383 | } while(rx & URXD_CHARRDY); | ||
384 | 404 | ||
385 | out: | 405 | out: |
386 | spin_unlock_irqrestore(&sport->port.lock,flags); | 406 | spin_unlock_irqrestore(&sport->port.lock,flags); |
387 | tty_flip_buffer_push(tty); | 407 | tty_flip_buffer_push(tty); |
388 | return IRQ_HANDLED; | 408 | return IRQ_HANDLED; |
389 | |||
390 | handle_error: | ||
391 | if (rx & URXD_PRERR) | ||
392 | sport->port.icount.parity++; | ||
393 | else if (rx & URXD_FRMERR) | ||
394 | sport->port.icount.frame++; | ||
395 | if (rx & URXD_OVRRUN) | ||
396 | sport->port.icount.overrun++; | ||
397 | |||
398 | if (rx & sport->port.ignore_status_mask) { | ||
399 | if (++ignored > 100) | ||
400 | goto out; | ||
401 | goto ignore_char; | ||
402 | } | ||
403 | |||
404 | rx &= sport->port.read_status_mask; | ||
405 | |||
406 | if (rx & URXD_PRERR) | ||
407 | flg = TTY_PARITY; | ||
408 | else if (rx & URXD_FRMERR) | ||
409 | flg = TTY_FRAME; | ||
410 | if (rx & URXD_OVRRUN) | ||
411 | flg = TTY_OVERRUN; | ||
412 | |||
413 | #ifdef SUPPORT_SYSRQ | ||
414 | sport->port.sysrq = 0; | ||
415 | #endif | ||
416 | goto error_return; | ||
417 | } | 409 | } |
418 | 410 | ||
419 | /* | 411 | /* |