From 836e075c18bcb8e414b519715ed41bcf7738c8a6 Mon Sep 17 00:00:00 2001 From: Youngmin Nam Date: Fri, 18 Sep 2015 10:17:57 +0900 Subject: [PATCH] serial: samsung: optimize UART RX interrupt handler This patch optimizes UART RX interurpt handler by reading UART SFR when necessary. Change-Id: I45def0b0906b0d55a7c1314832d9fab593c87e71 Signed-off-by: Youngmin Nam --- drivers/tty/serial/samsung.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 32ff12cada86..81b173b5ef6d 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -385,16 +385,23 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id) struct uart_port *port = &ourport->port; unsigned int ufcon, ch, flag, ufstat, uerstat; unsigned long flags; + int fifocnt = 0; int max_count = 64; spin_lock_irqsave(&port->lock, flags); while (max_count-- > 0) { - ufcon = rd_regl(port, S3C2410_UFCON); - ufstat = rd_regl(port, S3C2410_UFSTAT); - - if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0) - break; + /* + * Receive all characters known to be in FIFO + * before reading FIFO level again + */ + if (fifocnt == 0) { + ufstat = rd_regl(port, S3C2410_UFSTAT); + fifocnt = s3c24xx_serial_rx_fifocnt(ourport, ufstat); + if (fifocnt == 0) + break; + } + fifocnt--; uerstat = rd_regl(port, S3C2410_UERSTAT); ch = rd_regb(port, S3C2410_URXH); @@ -409,6 +416,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id) } } else { if (txe) { + ufcon = rd_regl(port, S3C2410_UFCON); ufcon |= S3C2410_UFCON_RESETRX; wr_regl(port, S3C2410_UFCON, ufcon); rx_enabled(port) = 1; -- 2.20.1