diff options
author | Stefan Agner <stefan@agner.ch> | 2014-08-19 17:54:27 +0200 |
---|---|---|
committer | Stefano Babic <sbabic@denx.de> | 2014-09-09 16:52:44 +0200 |
commit | a3db78d8870c8fb5bc0b1acd73bdc998d0d34200 (patch) | |
tree | ae8bb037cb325b841b003320dda5b7d327fa5b26 /drivers/serial/serial_lpuart.c | |
parent | 2d59e3ecd202e64a164b813a9ce9da2fd74f3e6a (diff) | |
download | u-boot-imx-a3db78d8870c8fb5bc0b1acd73bdc998d0d34200.zip u-boot-imx-a3db78d8870c8fb5bc0b1acd73bdc998d0d34200.tar.gz u-boot-imx-a3db78d8870c8fb5bc0b1acd73bdc998d0d34200.tar.bz2 |
arm: vf610: lpuart: fix status register handling
The status register 1 (S1) is not writeable, hence we should not
write it. In order to clear the RDRF flag we only need to read
the data register.
Also, when stressing U-Boot a lot with serial input, an overflow can
occur which asserts the S1_OR flag (while not asserting the S1_RDRF
flag). To clear this flag we again just need to read the data
register, hence add this flag to the abort conditions for the while
loop.
Insert a compiler barrier to make sure reading the data register
gets executed after reading the status register.
Signed-off-by: Stefan Agner <stefan@agner.ch>
Diffstat (limited to 'drivers/serial/serial_lpuart.c')
-rw-r--r-- | drivers/serial/serial_lpuart.c | 9 |
1 files changed, 3 insertions, 6 deletions
diff --git a/drivers/serial/serial_lpuart.c b/drivers/serial/serial_lpuart.c index da5f9a2..96173ca 100644 --- a/drivers/serial/serial_lpuart.c +++ b/drivers/serial/serial_lpuart.c @@ -14,6 +14,7 @@ #define US1_TDRE (1 << 7) #define US1_RDRF (1 << 5) +#define US1_OR (1 << 3) #define UC2_TE (1 << 3) #define UC2_RE (1 << 2) @@ -38,14 +39,10 @@ static void lpuart_serial_setbrg(void) static int lpuart_serial_getc(void) { - u8 status; - - while (!(__raw_readb(&base->us1) & US1_RDRF)) + while (!(__raw_readb(&base->us1) & (US1_RDRF | US1_OR))) WATCHDOG_RESET(); - status = __raw_readb(&base->us1); - status |= US1_RDRF; - __raw_writeb(status, &base->us1); + barrier(); return __raw_readb(&base->ud); } |