summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Agner <stefan.agner@toradex.com>2014-03-19 18:01:05 +0100
committerStefan Agner <stefan@agner.ch>2014-05-15 13:13:32 +0200
commit9d9594580ea77eb2fe7537e2b7e3f3abfc684db2 (patch)
treeacb5d13d366080977aaf8d22b972081cc6fe52da
parent72249651843f93d50c302833546fb2880052a80f (diff)
serial: mvf: clear pending data before alter FIFO
When data are pending and altering FIFO size and flushing FIFO, we end up having the UARTSR1_RDRF (receive data register full) bit set while UARTSFIFO_RXEMPT (FIFO empty) is set too. We check the second flag in the interrupt routine, which is set, and hence don't read the data register. This leads to an interrupt storm, which never gets handled properly. However, we can not check the UARTSR1_RDRF flag in the interrupt routine, since reading data in this case would misalign the FIFO buffer. Hence we should make sure there are no data before dealing with the FIFO. This fixes a race condition during bootup: when a character was sent between imx_console_setup and imx_startup, the kernel got stuck in a interrupt storm. Another character usually fixed that storm.
-rw-r--r--drivers/tty/serial/mvf.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/tty/serial/mvf.c b/drivers/tty/serial/mvf.c
index ae35ffdf4907..1bf9a474aa46 100644
--- a/drivers/tty/serial/mvf.c
+++ b/drivers/tty/serial/mvf.c
@@ -552,6 +552,10 @@ static int imx_setup_watermark(struct imx_port *sport, unsigned int mode)
MXC_UARTCR2_RIE | MXC_UARTCR2_RE);
writeb(cr2, sport->port.membase + MXC_UARTCR2);
+ /* Clear pending receive interrupt if needed */
+ while (readb(sport->port.membase + MXC_UARTSR1) & MXC_UARTSR1_RDRF)
+ val = readb(sport->port.membase + MXC_UARTDR);
+
val = TXTL;
writeb(val, sport->port.membase + MXC_UARTTWFIFO);
val = RXTL;