aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial
diff options
context:
space:
mode:
authorSascha Hauer <sascha@saschahauer.de>2008-04-17 03:39:22 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-04-17 11:18:19 -0400
commit864eeed051b527c8081e2f85b51ba24823acaf71 (patch)
tree7fa05275be02d98f5956b3030cdbf3c2a5f18228 /drivers/serial
parent8c9915bf310eeb1fe5a9a614cda6ee57d712460b (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')
-rw-r--r--drivers/serial/imx.c74
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
385out: 405out:
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
390handle_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/*