summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Agner <stefan@agner.ch>2015-03-13 14:51:51 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-04-19 10:10:22 +0200
commit63d7ff2248f302e4b600f72fcbec93318e7fb71b (patch)
tree26ff5e31b7c543abb1a5ebbb4feac6e82f94f6da
parentbeaa43e9b4ca8cfe4379bb2f849f10e04b85b1d4 (diff)
downloadlinux-stable-63d7ff2248f302e4b600f72fcbec93318e7fb71b.tar.gz
linux-stable-63d7ff2248f302e4b600f72fcbec93318e7fb71b.tar.bz2
linux-stable-63d7ff2248f302e4b600f72fcbec93318e7fb71b.zip
tty: serial: fsl_lpuart: clear receive flag on FIFO flush
commit 8e4934c6d6c659e22b1b746af4196683e77ce6ca upstream. When the receiver was enabled during startup, a character could have been in the FIFO when the UART get initially used. The driver configures the (receive) watermark level, and flushes the FIFO. However, the receive flag (RDRF) could still be set at that stage (as mentioned in the register description of UARTx_RWFIFO). This leads to an interrupt which won't be handled properly in interrupt mode: The receive interrupt function lpuart_rxint checks the FIFO count, which is 0 at that point (due to the flush during initialization). The problem does not manifest when using DMA to receive characters. Fix this situation by explicitly read the status register, which leads to clearing of the RDRF flag. Due to the flush just after the status flag read, a explicit data read is not to required. Signed-off-by: Stefan Agner <stefan@agner.ch> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/tty/serial/fsl_lpuart.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
index 1657514f56d2..0f63b93d8fc6 100644
--- a/drivers/tty/serial/fsl_lpuart.c
+++ b/drivers/tty/serial/fsl_lpuart.c
@@ -910,6 +910,9 @@ static void lpuart_setup_watermark(struct lpuart_port *sport)
writeb(val | UARTPFIFO_TXFE | UARTPFIFO_RXFE,
sport->port.membase + UARTPFIFO);
+ /* explicitly clear RDRF */
+ readb(sport->port.membase + UARTSR1);
+
/* flush Tx and Rx FIFO */
writeb(UARTCFIFO_TXFLUSH | UARTCFIFO_RXFLUSH,
sport->port.membase + UARTCFIFO);