diff options
author | Patrice Chotard <patrice.chotard@foss.st.com> | 2023-05-31 08:01:30 +0200 |
---|---|---|
committer | Patrice Chotard <patrice.chotard@foss.st.com> | 2023-06-16 11:29:29 +0200 |
commit | b4dbc5d65a67456db9cfe874d123e1c87860301d (patch) | |
tree | 7ad910087de646219df5e2a460ae0ecebc888acc /drivers/serial/serial_stm32.c | |
parent | 6d9f86571d10309f00dc9a7f3d8b9882cfd23ce4 (diff) |
serial: stm32: Wait TC bit before performing initialization
In case there is still chars from previous bootstage to transmit, wait
for TC (Transmission Complete) bit to be set which ensure that the last
data written in the USART_TDR has been transmitted out of the shift
register.
Signed-off-by: Patrice Chotard <patrice.chotard@foss.st.com>
Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>
Diffstat (limited to 'drivers/serial/serial_stm32.c')
-rw-r--r-- | drivers/serial/serial_stm32.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/serial/serial_stm32.c b/drivers/serial/serial_stm32.c index 2ba92bf9c48..93f70947eec 100644 --- a/drivers/serial/serial_stm32.c +++ b/drivers/serial/serial_stm32.c @@ -18,6 +18,7 @@ #include <dm/device_compat.h> #include <linux/bitops.h> #include <linux/delay.h> +#include <linux/iopoll.h> #include "serial_stm32.h" #include <dm/device_compat.h> @@ -181,9 +182,12 @@ static int stm32_serial_probe(struct udevice *dev) struct stm32x7_serial_plat *plat = dev_get_plat(dev); struct clk clk; struct reset_ctl reset; + u32 isr; int ret; + bool stm32f4; plat->uart_info = (struct stm32_uart_info *)dev_get_driver_data(dev); + stm32f4 = plat->uart_info->stm32f4; ret = clk_get_by_index(dev, 0, &clk); if (ret < 0) @@ -195,6 +199,17 @@ static int stm32_serial_probe(struct udevice *dev) return ret; } + /* + * before uart initialization, wait for TC bit (Transmission Complete) + * in case there is still chars from previous bootstage to transmit + */ + ret = read_poll_timeout(readl, isr, isr & USART_ISR_TC, 10, 150, + plat->base + ISR_OFFSET(stm32f4)); + if (ret) { + clk_disable(&clk); + return ret; + } + ret = reset_get_by_index(dev, 0, &reset); if (!ret) { reset_assert(&reset); |