summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorStefan Agner <stefan@agner.ch>2014-08-19 17:54:27 +0200
committerStefano Babic <sbabic@denx.de>2014-09-09 16:52:44 +0200
commita3db78d8870c8fb5bc0b1acd73bdc998d0d34200 (patch)
treeae8bb037cb325b841b003320dda5b7d327fa5b26 /drivers
parent2d59e3ecd202e64a164b813a9ce9da2fd74f3e6a (diff)
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')
-rw-r--r--drivers/serial/serial_lpuart.c9
1 files changed, 3 insertions, 6 deletions
diff --git a/drivers/serial/serial_lpuart.c b/drivers/serial/serial_lpuart.c
index da5f9a21f46..96173ca4409 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);
}