aboutsummaryrefslogtreecommitdiff
path: root/core/drivers
diff options
context:
space:
mode:
authorEtienne Carriere <etienne.carriere@linaro.org>2018-12-17 16:54:14 +0100
committerJérôme Forissier <jerome.forissier@linaro.org>2018-12-18 17:00:46 +0100
commit391d677e7e955455133256a255ccbc9380680ef2 (patch)
treedafbd6bc672bff19c928c937a1b1801e77323eae /core/drivers
parent33d30a74502ba03cece2857f37e3099fc7e3449b (diff)
stm32_uart: timeout to escape waiting loops
Add a timeout in output console waiting loops. This is useful if the secure world relies on a non-secure UART that may be suspended or disabled from the non-secure world. Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org> Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org> Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org>
Diffstat (limited to 'core/drivers')
-rw-r--r--core/drivers/stm32_uart.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/core/drivers/stm32_uart.c b/core/drivers/stm32_uart.c
index 1febd841..53d9c1e6 100644
--- a/core/drivers/stm32_uart.c
+++ b/core/drivers/stm32_uart.c
@@ -8,6 +8,7 @@
#include <drivers/stm32_uart.h>
#include <io.h>
#include <keep.h>
+#include <kernel/delay.h>
#include <util.h>
#define UART_REG_CR1 0x00 /* Control register 1 */
@@ -21,6 +22,9 @@
#define UART_REG_TDR 0x28 /* Transmit data register */
#define UART_REG_PRESC 0x2c /* Prescaler register */
+#define PUTC_TIMEOUT_US 1000
+#define FLUSH_TIMEOUT_US 16000
+
/*
* Uart Interrupt & status register bits
*
@@ -45,17 +49,21 @@ static vaddr_t loc_chip_to_base(struct serial_chip *chip)
static void loc_flush(struct serial_chip *chip)
{
vaddr_t base = loc_chip_to_base(chip);
+ uint64_t timeout = timeout_init_us(FLUSH_TIMEOUT_US);
while (!(read32(base + UART_REG_ISR) & USART_ISR_TXFE))
- ;
+ if (timeout_elapsed(timeout))
+ return;
}
static void loc_putc(struct serial_chip *chip, int ch)
{
vaddr_t base = loc_chip_to_base(chip);
+ uint64_t timeout = timeout_init_us(PUTC_TIMEOUT_US);
while (!(read32(base + UART_REG_ISR) & USART_ISR_TXE_TXFNF))
- ;
+ if (timeout_elapsed(timeout))
+ return;
write32(ch, base + UART_REG_TDR);
}