All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Diogo Ivo" <diogo.ivo.sx@renesas.com>
Cc: linux-serial@vger.kernel.org, wsa+renesas@sang-engineering.com
Subject: Re: [PATCH v4 2/7] serial: sh-sci: Keep TX enabled on TEI while data is pending
Date: Fri, 13 Nov 2026 19:18:08 +0000	[thread overview]
Message-ID: <sashiko-outbox-213538@kernel.org> (raw)
In-Reply-To: <20261113-g2ul_sci-v4-2-6815e41d90c5@renesas.com>

Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [High] serial: sh-sci: missing sci_stop_tx() when stopped in
  sci_transmit_chars()
- [Medium] serial: sh-sci: premature TE disable in
  sci_tx_end_interrupt() during active TX
--

commit 2144acd3ea7e3d82d9a7516af61337ce1de099e8
Author: Biju Das <biju.das.jz@bp.renesas.com>

serial: sh-sci: Keep TX enabled on TEI while data is pending

This commit keeps the transmitter enabled in sci_tx_end_interrupt() when
x_char or unstopped xmit_fifo data is pending, and updates
sci_transmit_chars() and rsci_transmit_chars() to switch from TIE to TEIE
when transmission is stopped.

> diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
> index 9eb297dbc9010..6df25fef5a5f5 100644
> --- a/drivers/tty/serial/sh-sci.c
> +++ b/drivers/tty/serial/sh-sci.c
[ ... ]
> @@ -1007,6 +1011,20 @@ static int sci_rxfill(struct uart_port *port)
>   *                   the interrupt related routines                       *
>   * ********************************************************************** */
>  
> +static void sci_clr_tie_set_teie(struct uart_port *port)
> +{
> +	struct sci_port *s = to_sci_port(port);
> +	unsigned short ctrl;
> +
> +	if (s->type != PORT_SCI)
> +		return;
> +
> +	ctrl = sci_serial_in(port, SCSCR);
> +	ctrl &= ~SCSCR_TIE;
> +	ctrl |= SCSCR_TEIE;
> +	sci_serial_out(port, SCSCR, ctrl);
> +}
> +
>  static void sci_transmit_chars(struct uart_port *port)
>  {
>  	struct tty_port *tport = &port->state->port;
> @@ -1050,14 +1068,10 @@ static void sci_transmit_chars(struct uart_port *port)
>  	if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)
>  		uart_write_wakeup(port);
>  	if (kfifo_is_empty(&tport->xmit_fifo)) {
> -		if (s->type == PORT_SCI) {
> -			ctrl = sci_serial_in(port, SCSCR);
> -			ctrl &= ~SCSCR_TIE;
> -			ctrl |= SCSCR_TEIE;
> -			sci_serial_out(port, SCSCR, ctrl);
> -		}
> -
> +		sci_clr_tie_set_teie(port);
>  		sci_stop_tx(port);
> +	} else if (stopped) {
> +		sci_clr_tie_set_teie(port);
>  	}
>  }

[Severity: High]
Does the "else if (stopped)" branch leave SCSCR_TIE enabled on
non-PORT_SCI ports?

sci_clr_tie_set_teie() returns immediately when s->type != PORT_SCI, and
this branch does not call sci_stop_tx().  If sci_transmit_chars() runs on
a PORT_SCIF, PORT_SCIFA, PORT_SCIFB, PORT_HSCIF, or PORT_IRDA port while
stopped with data still in xmit_fifo (for example, after uart_send_xchar()
calls sci_start_tx()), SCSCR_TIE remains set and triggers a continuous TXI
interrupt storm until transmission is unstopped.

> @@ -2012,6 +2026,7 @@ static irqreturn_t sci_tx_end_interrupt(int irq, void *ptr)
>  {
>  	struct uart_port *port = ptr;
>  	struct sci_port *s = to_sci_port(port);
> +	struct tty_port *tport = &port->state->port;
>  	const struct sci_common_regs *regs = s->params->common_regs;
>  	unsigned long flags;
>  	u32 ctrl;
> @@ -2020,8 +2035,18 @@ static irqreturn_t sci_tx_end_interrupt(int irq, void *ptr)
>  		return sci_tx_interrupt(irq, ptr);
>  
>  	uart_port_lock_irqsave(port, &flags);
> -	ctrl = s->ops->read_reg(port, regs->control) &
> -		~(s->params->param_bits->te_clear);
> +	ctrl = s->ops->read_reg(port, regs->control);
> +	if (port->x_char || (!kfifo_is_empty(&tport->xmit_fifo) &&
> +			     !uart_tx_stopped(port))) {
> +		ctrl &= ~(s->params->param_bits->teie);
> +		ctrl |= s->params->param_bits->tie;
> +		s->ops->write_reg(port, regs->control, ctrl);
> +		s->ops->transmit_chars(port);
> +		uart_port_unlock_irqrestore(port, flags);
> +		return IRQ_HANDLED;
> +	}
> +
> +	ctrl &= ~(s->params->param_bits->te_clear);
>  	s->ops->write_reg(port, regs->control, ctrl);
>  	uart_port_unlock_irqrestore(port, flags);

[Severity: Medium]
Can sci_tx_end_interrupt() still clear TE while newly written bytes are
being transmitted?

When transmit_chars() drains xmit_fifo, it clears TIE and sets TEIE while
the last byte is still shifting out.  If uart_write() runs before that
byte finishes, sci_start_tx() or rsci_start_tx() sets TIE without clearing
TEIE, leaving both interrupts enabled:

CPU0                              CPU1
transmit_chars()
  /* drains xmit_fifo */
  ctrl &= ~TIE;
  ctrl |= TEIE;
uart_write()
  start_tx()
    ctrl |= TIE | TE;
    /* TIE and TEIE both set */
                                  /* TDR transfers to shift reg: TXI */
                                  /* shift reg finishes: TEI */
                                  sci_tx_interrupt()
                                    lock(port)
                                    transmit_chars()
                                      /* writes new byte to TDR,
                                         drains xmit_fifo */
                                    unlock(port)
                                  sci_tx_end_interrupt()
                                    lock(port)
                                    /* xmit_fifo is now empty */
                                    ctrl &= ~te_clear;
                                      <-- clears TE during active TX
                                    unlock(port)

Because sci_tx_end_interrupt() checks only x_char and xmit_fifo without
verifying in regs->status that poll_sent_bits (TDRE and TEND) are still
set in hardware, it disables the transmitter before the newly written byte
has been sent.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261113-g2ul_sci-v4-0-6815e41d90c5@renesas.com?part=2

  reply	other threads:[~2026-11-13 19:18 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-13 18:26 [PATCH v4 0/7] Fix transmit handling on SCI/RSCI ports Diogo Ivo
2026-11-13 18:26 ` [PATCH v4 1/7] serial: sh-sci: Drop TE disable at end of transmission on SCI Diogo Ivo
2026-11-13 18:42   ` sashiko-bot
2026-11-13 18:26 ` [PATCH v4 2/7] serial: sh-sci: Keep TX enabled on TEI while data is pending Diogo Ivo
2026-11-13 19:18   ` sashiko-bot [this message]
2026-11-13 18:26 ` [PATCH v4 3/7] serial: rsci: Enable transmit end interrupt in rsci_stop_tx() Diogo Ivo
2026-11-13 19:35   ` sashiko-bot
2026-11-13 18:26 ` [PATCH v4 4/7] serial: sh-sci: Do not kick TX from sci_er_interrupt() on RSCI Diogo Ivo
2026-11-13 19:38   ` sashiko-bot
2026-11-13 18:26 ` [PATCH v4 5/7] serial: sh-sci: Skip TDxE clear when hardware clears it automatically Diogo Ivo
2026-11-13 19:47   ` sashiko-bot
2026-11-13 18:26 ` [PATCH v4 6/7] serial: sh-sci: Toggle TE when restoring SCSCR in console write on SCI Diogo Ivo
2026-11-13 19:56   ` sashiko-bot
2026-11-13 18:26 ` [PATCH v4 7/7] serial: rsci: Simplify rsci_transmit_chars() Diogo Ivo
2026-11-13 20:00   ` sashiko-bot

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=sashiko-outbox-213538@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=diogo.ivo.sx@renesas.com \
    --cc=linux-serial@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=wsa+renesas@sang-engineering.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.