RE: [PATCH 3/4] serial: sh-sci: Skip TDxE status clear for PORT_SCI
From: Biju Das
Date: Tue Oct 20 2026 - 05:56:39 EST
Hi Geert,
Thanks for the feedback.
> -----Original Message-----
> From: Geert Uytterhoeven <geert@xxxxxxxxxxxxxx>
> Sent: 20 October 2026 09:36
> Subject: Re: [PATCH 3/4] serial: sh-sci: Skip TDxE status clear for PORT_SCI
>
> Hi Biju,
>
> On Mon, 19 Oct 2026 at 19:01, Biju <biju.das.au@xxxxxxxxx> wrote:
> > From: Au Dang <au.dang.jx@xxxxxxxxxxx>
> >
> > On PORT_SCI, the TDxE (Transmit Data Empty) flag in SCxSR is cleared
> > automatically by hardware when data is written to TDR. Clearing it
> > again from software via clear_SCxSR() generates a spurious TXI
> > interrupt, which causes the last character to be transmitted twice.
> >
> > Skip the clear_SCxSR() call for PORT_SCI in sci_transmit_chars() and
> > sci_poll_put_char(), as the hardware already handles it after each TDR
> > write.
> >
> > Signed-off-by: Au Dang <au.dang.jx@xxxxxxxxxxx>
> > Signed-off-by: Biju Das <biju.das.jz@xxxxxxxxxxxxxx>
>
> Thanks for your patch!
>
> > --- a/drivers/tty/serial/sh-sci.c
> > +++ b/drivers/tty/serial/sh-sci.c
> > @@ -913,7 +913,8 @@ static void sci_poll_put_char(struct uart_port *port, unsigned char c)
> > } while (!(status & SCxSR_TDxE(port)));
> >
> > sci_serial_out(port, SCxTDR, c);
> > - s->ops->clear_SCxSR(port, SCxSR_TDxE_CLEAR(port) & ~SCxSR_TEND(port));
> > + if (s->type != PORT_SCI)
> > + s->ops->clear_SCxSR(port, SCxSR_TDxE_CLEAR(port) &
> > + ~SCxSR_TEND(port));
>
> Is this issue present on both classic SCI and RZ RSCI?
> s->ops->clear_SCxSR() points to either sci_clear_SCxSR() or
> rsci_clear_CFC(). The former already has an internal check for PORT_SCI, the latter has not. So probably
> it should be handled there.
It is applicable for RZ/G2UL based SCI as for TDRE and the hardware team confirmed
it will be auto cleared by the hardware.
On RSCI, we needed to explicitly clear it and it is handled in
rsci_transmit_chars()/ rsci_poll_put_char()
Cheers,
Biju
>
> > }
> > #endif /* CONFIG_CONSOLE_POLL || CONFIG_SERIAL_SH_SCI_CONSOLE ||
> > CONFIG_SERIAL_SH_SCI_EARLYCON */ @@ -1049,7 +1050,8 @@
> > static void sci_transmit_chars(struct uart_port *port)
> > port->icount.tx++;
> > } while (--count > 0);
> >
> > - s->ops->clear_SCxSR(port, SCxSR_TDxE_CLEAR(port));
> > + if (s->type != PORT_SCI)
> > + s->ops->clear_SCxSR(port, SCxSR_TDxE_CLEAR(port));
> >
> > if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
> > uart_write_wakeup(port);
>
> Gr{oetje,eeting}s,
>
> Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@xxxxxxxxxxxxxx
>
> 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