RE: [PATCH v6 5/9] serial: max310x: wait for TX to drain before powering down in shutdown
From: Maarten Brock
Date: Mon Oct 05 2026 - 06:13:09 EST
> From: Tapio Reijonen <tapio.reijonen@xxxxxxxxxxx>
> Sent: Sunday 4 October 2026 14:16
>
> Wait in shutdown() for the FIFO to drain, bounded by one character
> duration per FIFO word, plus one more character for the byte in the
> shift register, before powering the port down. The per-character
> duration is computed in set_termios() from the frame size and baud
> rate.
>
> Fixes: f65444187a66 ("serial: New serial driver MAX310X")
> Assisted-by: Claude:claude-fable-5
> Signed-off-by: Tapio Reijonen <tapio.reijonen@xxxxxxxxxxx>
> ---
> drivers/tty/serial/max310x.c | 25 +++++++++++++++++++++++--
> 1 file changed, 23 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c
> index 2456a2af891f5296cfec833d6406916073d2865f..9dcc817b9794537385aa9ca726cb1cc1b2af6b4c 100644
> --- a/drivers/tty/serial/max310x.c
> +++ b/drivers/tty/serial/max310x.c
> @@ -1223,6 +1228,22 @@ static int max310x_startup(struct uart_port *port)
>
> static void max310x_shutdown(struct uart_port *port)
> {
> + struct max310x_one *one = to_max310x_port(port);
> + unsigned int tries = port->fifosize + 1;
> +
> + /*
> + * The tty layer's wait-until-sent is bounded by closing_wait, which
> + * can be configured to none, and a hangup reaches here with no wait
> + * at all, so the FIFO may still hold anything up to its full size.
> + * tx_empty() also only reflects the chip TX FIFO - the last character
> + * may still be in the transmit shift register. Let the FIFO drain and
> + * the final character clock out before the port is powered down,
> + * otherwise the transfer is truncated on the wire.
> + */
> + while (!max310x_tx_empty(port) && tries-- > 0)
Would it not be better to retrieve the fifo level and multiply that by char_time_us
to wait first? Yes, the (MAX3109) datasheet mentions its value may sometimes be
inaccurate, but the worst that can happen is waiting too long. And after that use
this max310x_tx_empty().
> + fsleep(one->char_time_us);
> + fsleep(one->char_time_us);
> +
> /* Disable all interrupts */
> max310x_port_write(port, MAX310X_IRQEN_REG, 0);
Kind regards,
Maarten