diff options
author | Stefan Agner <stefan.agner@toradex.com> | 2014-03-19 18:01:05 +0100 |
---|---|---|
committer | Stefan Agner <stefan@agner.ch> | 2014-05-15 13:13:32 +0200 |
commit | 9d9594580ea77eb2fe7537e2b7e3f3abfc684db2 (patch) | |
tree | acb5d13d366080977aaf8d22b972081cc6fe52da | |
parent | 72249651843f93d50c302833546fb2880052a80f (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.c | 4 |
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; |