[PATCH v2 3/3] serial: 8250_mxpcie: take the line settings from the new termios

From: Linmao Li

Date: Tue Sep 01 2026 - 00:16:45 EST


mxpcie8250_set_termios() reads the line settings out of
port->state->port.tty, which is only set once the port has been opened.

uart_set_options() builds a termios of its own and calls ->set_termios()
with no tty behind it, so using such a board as the console
(console=ttyS<n>) dereferences a NULL tty during console setup, as does
attaching kgdboc to it and resuming a suspended console from
uart_resume_port().

Read the settings from the termios the serial core passes in instead.
It holds the same values on the normal path - uart_change_line_settings()
passes &tty->termios - and it is what serial8250_do_set_termios() right
above already uses.

Fixes: 55edf8511f47 ("serial: 8250_mxpcie: enable automatic RTS/CTS flow control")
Signed-off-by: Linmao Li <lilinmao@xxxxxxxxxx>
Tested-by: Crescent Hsieh <crescentcy.hsieh@xxxxxxxx>
---
v2: drop the cflag local, read new->c_cflag directly (Crescent Hsieh).

drivers/tty/serial/8250/8250_mxpcie.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_mxpcie.c b/drivers/tty/serial/8250/8250_mxpcie.c
index ef2516ec16da..19f1f51eec47 100644
--- a/drivers/tty/serial/8250/8250_mxpcie.c
+++ b/drivers/tty/serial/8250/8250_mxpcie.c
@@ -218,8 +218,6 @@ static void mxpcie8250_set_termios(struct uart_port *port,
const struct ktermios *old)
{
struct uart_8250_port *up = up_to_u8250p(port);
- struct tty_struct *tty = port->state->port.tty;
- unsigned int cflag = tty->termios.c_cflag;
u8 efr, val;

serial8250_do_set_termios(port, new, old);
@@ -229,23 +227,25 @@ static void mxpcie8250_set_termios(struct uart_port *port,
efr = serial_in(up, MOXA_PUART_EFR);
efr &= ~(MOXA_PUART_EFR_AUTO_RTS | MOXA_PUART_EFR_AUTO_CTS);

- if (cflag & CRTSCTS) {
+ if (new->c_cflag & CRTSCTS) {
efr |= (MOXA_PUART_EFR_AUTO_RTS | MOXA_PUART_EFR_AUTO_CTS);
up->port.status |= (UPSTAT_AUTORTS | UPSTAT_AUTOCTS);
}
/* Set on-chip software flow control character */
- serial_out(up, MOXA_PUART_XON1, START_CHAR(tty));
- serial_out(up, MOXA_PUART_XON2, START_CHAR(tty));
- serial_out(up, MOXA_PUART_XOFF1, STOP_CHAR(tty));
- serial_out(up, MOXA_PUART_XOFF2, STOP_CHAR(tty));
+ serial_out(up, MOXA_PUART_XON1, new->c_cc[VSTART]);
+ serial_out(up, MOXA_PUART_XON2, new->c_cc[VSTART]);
+ serial_out(up, MOXA_PUART_XOFF1, new->c_cc[VSTOP]);
+ serial_out(up, MOXA_PUART_XOFF2, new->c_cc[VSTOP]);

- val = I_IXON(tty) ? MOXA_PUART_EFR_RX_FLOW_XON1_XOFF1 : MOXA_PUART_EFR_RX_FLOW_DISABLED;
+ val = (new->c_iflag & IXON) ? MOXA_PUART_EFR_RX_FLOW_XON1_XOFF1 :
+ MOXA_PUART_EFR_RX_FLOW_DISABLED;
FIELD_MODIFY(MOXA_PUART_EFR_RX_FLOW_MASK, &efr, val);

- val = I_IXOFF(tty) ? MOXA_PUART_EFR_TX_FLOW_XON1_XOFF1 : MOXA_PUART_EFR_TX_FLOW_DISABLED;
+ val = (new->c_iflag & IXOFF) ? MOXA_PUART_EFR_TX_FLOW_XON1_XOFF1 :
+ MOXA_PUART_EFR_TX_FLOW_DISABLED;
FIELD_MODIFY(MOXA_PUART_EFR_TX_FLOW_MASK, &efr, val);

- if (I_IXOFF(tty))
+ if (new->c_iflag & IXOFF)
up->port.status |= UPSTAT_AUTOXOFF;

serial_out(up, MOXA_PUART_EFR, efr);
--
2.25.1