diff options
author | Etienne Carriere <etienne.carriere@linaro.org> | 2018-12-17 16:54:14 +0100 |
---|---|---|
committer | Jérôme Forissier <jerome.forissier@linaro.org> | 2018-12-18 17:00:46 +0100 |
commit | 391d677e7e955455133256a255ccbc9380680ef2 (patch) | |
tree | dafbd6bc672bff19c928c937a1b1801e77323eae /core/drivers | |
parent | 33d30a74502ba03cece2857f37e3099fc7e3449b (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.c | 12 |
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); } |