Message ID | 20220419085330.1178925-2-valentin.caron@foss.st.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | serial: stm32: add earlycon and polling mode | expand |
Hi Valentin, On Tue, Apr 19, 2022 at 10:54 AM Valentin Caron <valentin.caron@foss.st.com> wrote: > Rework stm32_usart_console_putchar() function in order to anticipate > the case where the character can never be sent. > > Signed-off-by: Valentin Caron <valentin.caron@foss.st.com> Thanks for your patch! > --- a/drivers/tty/serial/stm32-usart.c > +++ b/drivers/tty/serial/stm32-usart.c > @@ -1640,10 +1640,16 @@ static void stm32_usart_console_putchar(struct uart_port *port, unsigned char ch > { > struct stm32_port *stm32_port = to_stm32_port(port); > const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; > + u32 isr; > + int ret; > > - while (!(readl_relaxed(port->membase + ofs->isr) & USART_SR_TXE)) > - cpu_relax(); > - > + ret = readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr, isr, > + (isr & USART_SR_TXE), 100, > + STM32_USART_TIMEOUT_USEC); > + if (ret != 0) { > + dev_err(port->dev, "Error while sending data in UART TX : %d\n", ret); Does it make sense to print this message, i.e. will the user ever see it? Or is the failure above temporary? I assume that you have seen this trigger? > + return; > + } > writel_relaxed(ch, port->membase + ofs->tdr); > } Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
On 4/19/22 10:59, Geert Uytterhoeven wrote: > Hi Valentin, > > On Tue, Apr 19, 2022 at 10:54 AM Valentin Caron > <valentin.caron@foss.st.com> wrote: >> Rework stm32_usart_console_putchar() function in order to anticipate >> the case where the character can never be sent. >> >> Signed-off-by: Valentin Caron <valentin.caron@foss.st.com> > Thanks for your patch! > >> --- a/drivers/tty/serial/stm32-usart.c >> +++ b/drivers/tty/serial/stm32-usart.c >> @@ -1640,10 +1640,16 @@ static void stm32_usart_console_putchar(struct uart_port *port, unsigned char ch >> { >> struct stm32_port *stm32_port = to_stm32_port(port); >> const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; >> + u32 isr; >> + int ret; >> >> - while (!(readl_relaxed(port->membase + ofs->isr) & USART_SR_TXE)) >> - cpu_relax(); >> - >> + ret = readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr, isr, >> + (isr & USART_SR_TXE), 100, >> + STM32_USART_TIMEOUT_USEC); >> + if (ret != 0) { >> + dev_err(port->dev, "Error while sending data in UART TX : %d\n", ret); > Does it make sense to print this message, i.e. will the user ever see it? > Or is the failure above temporary? > I assume that you have seen this trigger? > >> + return; >> + } >> writel_relaxed(ch, port->membase + ofs->tdr); >> } > Gr{oetje,eeting}s, > > Geert > > -- > Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org > > In personal conversations with technical people, I call myself a hacker. But > when I'm talking to journalists I just say "programmer" or something like that. > -- Linus Torvalds Hi Geert, The failure is temporary. It can appears when the uart is too slow to send data. I never tested the case, but I prefer to show a message to know if the console loses a character. Thanks, Valentin
diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c index f886976daef6..9910a18779af 100644 --- a/drivers/tty/serial/stm32-usart.c +++ b/drivers/tty/serial/stm32-usart.c @@ -1640,10 +1640,16 @@ static void stm32_usart_console_putchar(struct uart_port *port, unsigned char ch { struct stm32_port *stm32_port = to_stm32_port(port); const struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; + u32 isr; + int ret; - while (!(readl_relaxed(port->membase + ofs->isr) & USART_SR_TXE)) - cpu_relax(); - + ret = readl_relaxed_poll_timeout_atomic(port->membase + ofs->isr, isr, + (isr & USART_SR_TXE), 100, + STM32_USART_TIMEOUT_USEC); + if (ret != 0) { + dev_err(port->dev, "Error while sending data in UART TX : %d\n", ret); + return; + } writel_relaxed(ch, port->membase + ofs->tdr); } diff --git a/drivers/tty/serial/stm32-usart.h b/drivers/tty/serial/stm32-usart.h index feab952aec16..d734c4a5fd24 100644 --- a/drivers/tty/serial/stm32-usart.h +++ b/drivers/tty/serial/stm32-usart.h @@ -251,6 +251,8 @@ struct stm32_usart_info stm32h7_info = { #define RX_BUF_P (RX_BUF_L / 2) /* dma rx buffer period */ #define TX_BUF_L RX_BUF_L /* dma tx buffer length */ +#define STM32_USART_TIMEOUT_USEC USEC_PER_SEC /* 1s timeout in µs */ + struct stm32_port { struct uart_port port; struct clk *clk;
Rework stm32_usart_console_putchar() function in order to anticipate the case where the character can never be sent. Signed-off-by: Valentin Caron <valentin.caron@foss.st.com> --- drivers/tty/serial/stm32-usart.c | 12 +++++++++--- drivers/tty/serial/stm32-usart.h | 2 ++ 2 files changed, 11 insertions(+), 3 deletions(-)