Linux Serial subsystem development
 help / color / mirror / Atom feed
* Re: [PATCH v2] dt-bindings: qcom: geni-se-qup: Add compatible for SA8797P SoC
From: Bjorn Andersson @ 2026-05-12 20:23 UTC (permalink / raw)
  To: Shawn Guo
  Cc: Rob Herring, Krzysztof Kozlowski, Conor Dooley, Praveen Talari,
	Konrad Dybcio, Dmitry Baryshkov, Bartosz Golaszewski,
	Deepti Jaggi, linux-serial, devicetree, linux-arm-msm,
	linux-kernel
In-Reply-To: <20260427005901.230237-1-shengchao.guo@oss.qualcomm.com>


On Mon, 27 Apr 2026 08:59:01 +0800, Shawn Guo wrote:
> Document GENI Serial Engine QUP Wrapper Controller on Nord SA8797P SoC
> which is compatible with SA8255P one.
> 
> 

Applied, thanks!

[1/1] dt-bindings: qcom: geni-se-qup: Add compatible for SA8797P SoC
      commit: 35466ef5db1fbdff49c4142026c4c56514d5ff47

Best regards,
-- 
Bjorn Andersson <andersson@kernel.org>

^ permalink raw reply

* [tty:tty-next 28/31] drivers/tty/serial/max310x.c:1507:20: warning: 'max310x_regmap_name' defined but not used
From: kernel test robot @ 2026-05-12 19:53 UTC (permalink / raw)
  To: Hugo Villeneuve; +Cc: oe-kbuild-all, linux-serial, Greg Kroah-Hartman

Hi Hugo,

First bad commit (maybe != root cause):

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-next
head:   16e95bfb79b5d9d01dc7651d98caf3c2ace331cd
commit: 20ffe4b3330a8bde9e933e9ba2323d5e9386caa5 [28/31] serial: max310x: allow driver to be built with SPI or I2C
config: powerpc64-randconfig-001-20260513 (https://download.01.org/0day-ci/archive/20260513/202605130334.e6V1YDQN-lkp@intel.com/config)
compiler: powerpc64-linux-gcc (GCC) 8.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260513/202605130334.e6V1YDQN-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202605130334.e6V1YDQN-lkp@intel.com/

All warnings (new ones prefixed by >>):

   drivers/tty/serial/max310x.c: In function 'max310x_uart_init':
   drivers/tty/serial/max310x.c:1730:1: warning: label 'err_spi_register' defined but not used [-Wunused-label]
    err_spi_register:
    ^~~~~~~~~~~~~~~~
   At top level:
>> drivers/tty/serial/max310x.c:1507:20: warning: 'max310x_regmap_name' defined but not used [-Wunused-function]
    static const char *max310x_regmap_name(u8 port_id)
                       ^~~~~~~~~~~~~~~~~~~
   drivers/tty/serial/max310x.c:1492:29: warning: 'regcfg' defined but not used [-Wunused-variable]
    static struct regmap_config regcfg = {
                                ^~~~~~
>> drivers/tty/serial/max310x.c:1464:13: warning: 'max310x_remove' defined but not used [-Wunused-function]
    static void max310x_remove(struct device *dev)
                ^~~~~~~~~~~~~~
>> drivers/tty/serial/max310x.c:1280:12: warning: 'max310x_probe' defined but not used [-Wunused-function]
    static int max310x_probe(struct device *dev, const struct max310x_devtype *devtype,
               ^~~~~~~~~~~~~


vim +/max310x_regmap_name +1507 drivers/tty/serial/max310x.c

f65444187a66bf Alexander Shiyan 2012-08-06  1463  
70b4d23226c85a Uwe Kleine-König 2021-10-12 @1464  static void max310x_remove(struct device *dev)
f65444187a66bf Alexander Shiyan 2012-08-06  1465  {
f65444187a66bf Alexander Shiyan 2012-08-06  1466  	struct max310x_port *s = dev_get_drvdata(dev);
88d5e520aa9701 abdoulaye berthe 2014-07-12  1467  	int i;
f65444187a66bf Alexander Shiyan 2012-08-06  1468  
6286767ad3afc8 Alexander Shiyan 2016-06-07  1469  	for (i = 0; i < s->devtype->nr; i++) {
10d8b34a421716 Alexander Shiyan 2013-06-29  1470  		cancel_work_sync(&s->p[i].tx_work);
e7b8a3ceff5e5c Alexander Shiyan 2014-02-07  1471  		cancel_work_sync(&s->p[i].md_work);
5bdb48b501e836 Alexander Shiyan 2016-06-07  1472  		cancel_work_sync(&s->p[i].rs_work);
5d888f1c32e228 Hugo Villeneuve  2024-01-18  1473  
5d888f1c32e228 Hugo Villeneuve  2024-01-18  1474  		if (test_and_clear_bit(s->p[i].port.line, max310x_lines))
6286767ad3afc8 Alexander Shiyan 2016-06-07  1475  			uart_remove_one_port(&max310x_uart, &s->p[i].port);
5d888f1c32e228 Hugo Villeneuve  2024-01-18  1476  
9464833a765f66 Hugo Villeneuve  2024-01-18  1477  		max310x_power(&s->p[i].port, 0);
10d8b34a421716 Alexander Shiyan 2013-06-29  1478  	}
f65444187a66bf Alexander Shiyan 2012-08-06  1479  
d3a8a252e177cf Alexander Shiyan 2014-02-10  1480  	clk_disable_unprepare(s->clk);
f65444187a66bf Alexander Shiyan 2012-08-06  1481  }
f65444187a66bf Alexander Shiyan 2012-08-06  1482  
58afc909772c9b Alexander Shiyan 2014-02-10  1483  static const struct of_device_id __maybe_unused max310x_dt_ids[] = {
58afc909772c9b Alexander Shiyan 2014-02-10  1484  	{ .compatible = "maxim,max3107",	.data = &max3107_devtype, },
58afc909772c9b Alexander Shiyan 2014-02-10  1485  	{ .compatible = "maxim,max3108",	.data = &max3108_devtype, },
58afc909772c9b Alexander Shiyan 2014-02-10  1486  	{ .compatible = "maxim,max3109",	.data = &max3109_devtype, },
58afc909772c9b Alexander Shiyan 2014-02-10  1487  	{ .compatible = "maxim,max14830",	.data = &max14830_devtype },
58afc909772c9b Alexander Shiyan 2014-02-10  1488  	{ }
58afc909772c9b Alexander Shiyan 2014-02-10  1489  };
58afc909772c9b Alexander Shiyan 2014-02-10  1490  MODULE_DEVICE_TABLE(of, max310x_dt_ids);
58afc909772c9b Alexander Shiyan 2014-02-10  1491  
27027a70e21f62 Alexander Shiyan 2014-02-10  1492  static struct regmap_config regcfg = {
27027a70e21f62 Alexander Shiyan 2014-02-10  1493  	.reg_bits = 8,
27027a70e21f62 Alexander Shiyan 2014-02-10  1494  	.val_bits = 8,
d584b65c0ddf20 Jan Kundrát      2017-12-13  1495  	.write_flag_mask = MAX310X_WRITE_BIT,
c9615d34ce2619 wangkaiyuan      2024-03-18  1496  	.cache_type = REGCACHE_MAPLE,
6ef281daf02059 Cosmin Tanislav  2022-06-05  1497  	.max_register = MAX310X_REG_1F,
27027a70e21f62 Alexander Shiyan 2014-02-10  1498  	.writeable_reg = max310x_reg_writeable,
27027a70e21f62 Alexander Shiyan 2014-02-10  1499  	.volatile_reg = max310x_reg_volatile,
27027a70e21f62 Alexander Shiyan 2014-02-10  1500  	.precious_reg = max310x_reg_precious,
3f42b142ea1171 Jan Kundrát      2023-04-05  1501  	.writeable_noinc_reg = max310x_reg_noinc,
3f42b142ea1171 Jan Kundrát      2023-04-05  1502  	.readable_noinc_reg = max310x_reg_noinc,
3f42b142ea1171 Jan Kundrát      2023-04-05  1503  	.max_raw_read = MAX310X_FIFO_SIZE,
3f42b142ea1171 Jan Kundrát      2023-04-05  1504  	.max_raw_write = MAX310X_FIFO_SIZE,
27027a70e21f62 Alexander Shiyan 2014-02-10  1505  };
27027a70e21f62 Alexander Shiyan 2014-02-10  1506  
609aabb259d497 Hugo Villeneuve  2024-01-18 @1507  static const char *max310x_regmap_name(u8 port_id)
609aabb259d497 Hugo Villeneuve  2024-01-18  1508  {
609aabb259d497 Hugo Villeneuve  2024-01-18  1509  	switch (port_id) {
609aabb259d497 Hugo Villeneuve  2024-01-18  1510  	case 0:	return "port0";
609aabb259d497 Hugo Villeneuve  2024-01-18  1511  	case 1:	return "port1";
609aabb259d497 Hugo Villeneuve  2024-01-18  1512  	case 2:	return "port2";
609aabb259d497 Hugo Villeneuve  2024-01-18  1513  	case 3:	return "port3";
609aabb259d497 Hugo Villeneuve  2024-01-18  1514  	default:
609aabb259d497 Hugo Villeneuve  2024-01-18  1515  		WARN_ON(true);
609aabb259d497 Hugo Villeneuve  2024-01-18  1516  		return NULL;
609aabb259d497 Hugo Villeneuve  2024-01-18  1517  	}
609aabb259d497 Hugo Villeneuve  2024-01-18  1518  }
609aabb259d497 Hugo Villeneuve  2024-01-18  1519  

:::::: The code at line 1507 was first introduced by commit
:::::: 609aabb259d497578ffa2d66ced57c22044f821c serial: max310x: use separate regmap name for each port

:::::: TO: Hugo Villeneuve <hvilleneuve@dimonoff.com>
:::::: CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* [PATCH v2 2/2] serial: qcom-geni: Add tracepoints for Qualcomm GENI serial driver
From: Praveen Talari @ 2026-05-12 17:14 UTC (permalink / raw)
  To: Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
	Greg Kroah-Hartman, Jiri Slaby, Konrad Dybcio
  Cc: linux-kernel, linux-trace-kernel, linux-arm-msm, linux-serial,
	Mukesh Kumar Savaliya, Aniket Randive, chandana.chiluveru,
	jyothi.seerapu, Praveen Talari
In-Reply-To: <20260512-add-tracepoints-for-qcom-geni-serial-v2-0-a5726421b3af@oss.qualcomm.com>

Add tracing to the Qualcomm GENI serial driver to improve runtime
observability.

Trace hooks are added at key points including termios and clock
configuration, manual control get/set, interrupt handling, and data
TX/RX paths.

Usage examples:

Enable all serial traces:
  echo 1 > /sys/kernel/debug/tracing/events/qcom_geni_serial/enable
  cat /sys/kernel/debug/tracing/trace_pipe

Example trace output:

2517.938432: geni_serial_clk_cfg: a94000.serial: desired_rate=1843200
     clk_rate=7372800 clk_div=4 clk_idx=0
2517.938753: geni_serial_irq: a94000.serial: m_irq=0x88800000
     s_irq=0x08000111 dma_tx=0x00000000 dma_rx=0x00000000
2517.938803: geni_serial_set_termios: a94000.serial: baud=115200 bpc=8
     tx_trans=0x00000002 tx_par=0x00000000 rx_trans=0x00000000
rx_par=0x00000000 stop=0
2517.938807: geni_serial_set_mctrl: a94000.serial: mctrl=0x8006
     uart_manual_rfr=0x00000000
2517.938818: geni_serial_get_mctrl: a94000.serial: mctrl=0x0160
     geni_ios=0x00000001
2517.939165: geni_serial_irq: a94000.serial: m_irq=0x00400000
     s_irq=0x00000000 dma_tx=0x00000000 dma_rx=0x00000000
2517.939592: geni_serial_tx_data: a94000.serial: tx_len=8 data=61 62 63
     64 65 66 67 68
2517.940610: geni_serial_irq: a94000.serial: m_irq=0x00000001
     s_irq=0x00000000 dma_tx=0x00000003 dma_rx=0x00000000
2517.942174: geni_serial_irq: a94000.serial: m_irq=0x08000000
     s_irq=0x08000100 dma_tx=0x00000000 dma_rx=0x00000003
2517.942323: geni_serial_rx_data: a94000.serial: rx_len=8 data=61 62 63
     64 65 66 67 68
2517.942680: geni_serial_set_mctrl: a94000.serial: mctrl=0x8000
     uart_manual_rfr=0x80000002

Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
 drivers/tty/serial/qcom_geni_serial.c | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)

diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index e6b0a55f0cfb..9e2de074d799 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -7,6 +7,9 @@
 /* Disable MMIO tracing to prevent excessive logging of unwanted MMIO traces */
 #define __DISABLE_TRACE_MMIO__
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/qcom_geni_serial.h>
+
 #include <linux/clk.h>
 #include <linux/console.h>
 #include <linux/io.h>
@@ -225,7 +228,7 @@ static void qcom_geni_serial_config_port(struct uart_port *uport, int cfg_flags)
 static unsigned int qcom_geni_serial_get_mctrl(struct uart_port *uport)
 {
 	unsigned int mctrl = TIOCM_DSR | TIOCM_CAR;
-	u32 geni_ios;
+	u32 geni_ios = 0;
 
 	if (uart_console(uport)) {
 		mctrl |= TIOCM_CTS;
@@ -235,6 +238,8 @@ static unsigned int qcom_geni_serial_get_mctrl(struct uart_port *uport)
 			mctrl |= TIOCM_CTS;
 	}
 
+	trace_geni_serial_get_mctrl(uport->dev, mctrl, geni_ios);
+
 	return mctrl;
 }
 
@@ -253,6 +258,8 @@ static void qcom_geni_serial_set_mctrl(struct uart_port *uport,
 	if (!(mctrl & TIOCM_RTS) && !uport->suspended)
 		uart_manual_rfr = UART_MANUAL_RFR_EN | UART_RFR_NOT_READY;
 	writel(uart_manual_rfr, uport->membase + SE_UART_MANUAL_RFR);
+
+	trace_geni_serial_set_mctrl(uport->dev, mctrl, uart_manual_rfr);
 }
 
 static const char *qcom_geni_serial_get_type(struct uart_port *uport)
@@ -683,6 +690,8 @@ static void qcom_geni_serial_start_tx_dma(struct uart_port *uport)
 	xmit_size = kfifo_out_linear_ptr(&tport->xmit_fifo, &tail,
 			UART_XMIT_SIZE);
 
+	trace_geni_serial_tx_data(uport->dev, tail, xmit_size);
+
 	qcom_geni_set_rs485_mode(uport, SER_RS485_RTS_ON_SEND);
 
 	qcom_geni_serial_setup_tx(uport, xmit_size);
@@ -909,8 +918,10 @@ static void qcom_geni_serial_handle_rx_dma(struct uart_port *uport, bool drop)
 		return;
 	}
 
-	if (!drop)
+	if (!drop) {
+		trace_geni_serial_rx_data(uport->dev, port->rx_buf, rx_in);
 		handle_rx_uart(uport, rx_in);
+	}
 
 	ret = geni_se_rx_dma_prep(&port->se, port->rx_buf,
 				  DMA_RX_BUF_SIZE,
@@ -1069,6 +1080,10 @@ static irqreturn_t qcom_geni_serial_isr(int isr, void *dev)
 	geni_status = readl(uport->membase + SE_GENI_STATUS);
 	dma = readl(uport->membase + SE_GENI_DMA_MODE_EN);
 	m_irq_en = readl(uport->membase + SE_GENI_M_IRQ_EN);
+
+	trace_geni_serial_irq(uport->dev, m_irq_status, s_irq_status,
+			      dma_tx_status, dma_rx_status);
+
 	writel(m_irq_status, uport->membase + SE_GENI_M_IRQ_CLEAR);
 	writel(s_irq_status, uport->membase + SE_GENI_S_IRQ_CLEAR);
 	writel(dma_tx_status, uport->membase + SE_DMA_TX_IRQ_CLR);
@@ -1281,8 +1296,8 @@ static int geni_serial_set_rate(struct uart_port *uport, unsigned int baud)
 		return -EINVAL;
 	}
 
-	dev_dbg(port->se.dev, "desired_rate = %u, clk_rate = %lu, clk_div = %u\n, clk_idx = %u\n",
-		baud * sampling_rate, clk_rate, clk_div, clk_idx);
+	trace_geni_serial_clk_cfg(uport->dev, baud * sampling_rate, clk_rate,
+				  clk_div, clk_idx);
 
 	uport->uartclk = clk_rate;
 	port->clk_rate = clk_rate;
@@ -1432,6 +1447,10 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport,
 	writel(bits_per_char, uport->membase + SE_UART_TX_WORD_LEN);
 	writel(bits_per_char, uport->membase + SE_UART_RX_WORD_LEN);
 	writel(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN);
+
+	trace_geni_serial_set_termios(uport->dev, baud, bits_per_char,
+				      tx_trans_cfg, tx_parity_cfg, rx_trans_cfg,
+				      rx_parity_cfg, stop_bit_len);
 }
 
 #ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 1/2] serial: qcom-geni: trace: Add tracepoint support for Qualcomm GENI serial
From: Praveen Talari @ 2026-05-12 17:14 UTC (permalink / raw)
  To: Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
	Greg Kroah-Hartman, Jiri Slaby, Konrad Dybcio
  Cc: linux-kernel, linux-trace-kernel, linux-arm-msm, linux-serial,
	Mukesh Kumar Savaliya, Aniket Randive, chandana.chiluveru,
	jyothi.seerapu, Praveen Talari
In-Reply-To: <20260512-add-tracepoints-for-qcom-geni-serial-v2-0-a5726421b3af@oss.qualcomm.com>

Add tracepoint support to the Qualcomm GENI serial driver to provide
runtime visibility into driver behavior without requiring invasive debug
patches.

The trace events cover UART termios configuration, clock setup, modem
control state, interrupt status, and TX/RX data, making it easier to
diagnose communication issues in the field.

Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
v1->v2:
- Removed multiple TX/RX trace events, instead used
  DECLARE_EVENT_CLASS and DEFINE_EVENT.
---
 include/trace/events/qcom_geni_serial.h | 172 ++++++++++++++++++++++++++++++++
 1 file changed, 172 insertions(+)

diff --git a/include/trace/events/qcom_geni_serial.h b/include/trace/events/qcom_geni_serial.h
new file mode 100644
index 000000000000..5e23827881d0
--- /dev/null
+++ b/include/trace/events/qcom_geni_serial.h
@@ -0,0 +1,172 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM qcom_geni_serial
+
+#if !defined(_TRACE_QCOM_GENI_SERIAL_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_QCOM_GENI_SERIAL_H
+
+#include <linux/device.h>
+#include <linux/tracepoint.h>
+
+TRACE_EVENT(geni_serial_set_termios,
+	    TP_PROTO(struct device *dev, unsigned int baud,
+		     unsigned int bits_per_char, u32 tx_trans_cfg,
+		     u32 tx_parity_cfg, u32 rx_trans_cfg,
+		     u32 rx_parity_cfg, u32 stop_bit_len),
+	    TP_ARGS(dev, baud, bits_per_char, tx_trans_cfg, tx_parity_cfg,
+		    rx_trans_cfg, rx_parity_cfg, stop_bit_len),
+
+	    TP_STRUCT__entry(__string(name, dev_name(dev))
+			     __field(unsigned int, baud)
+			     __field(unsigned int, bits_per_char)
+			     __field(u32, tx_trans_cfg)
+			     __field(u32, tx_parity_cfg)
+			     __field(u32, rx_trans_cfg)
+			     __field(u32, rx_parity_cfg)
+			     __field(u32, stop_bit_len)
+	    ),
+
+	    TP_fast_assign(__assign_str(name);
+			   __entry->baud = baud;
+			   __entry->bits_per_char = bits_per_char;
+			   __entry->tx_trans_cfg = tx_trans_cfg;
+			   __entry->tx_parity_cfg = tx_parity_cfg;
+			   __entry->rx_trans_cfg = rx_trans_cfg;
+			   __entry->rx_parity_cfg = rx_parity_cfg;
+			   __entry->stop_bit_len = stop_bit_len;
+	    ),
+
+	    TP_printk("%s: baud=%u bpc=%u tx_trans=0x%08x tx_par=0x%08x rx_trans=0x%08x rx_par=0x%08x stop=%u",
+		      __get_str(name), __entry->baud, __entry->bits_per_char,
+		      __entry->tx_trans_cfg, __entry->tx_parity_cfg,
+		      __entry->rx_trans_cfg, __entry->rx_parity_cfg,
+		      __entry->stop_bit_len)
+);
+
+TRACE_EVENT(geni_serial_clk_cfg,
+	    TP_PROTO(struct device *dev, unsigned int desired_rate,
+		     unsigned long clk_rate, unsigned int clk_div,
+		     unsigned int clk_idx),
+	    TP_ARGS(dev, desired_rate, clk_rate, clk_div, clk_idx),
+
+	    TP_STRUCT__entry(__string(name, dev_name(dev))
+			     __field(unsigned int, desired_rate)
+			     __field(unsigned long, clk_rate)
+			     __field(unsigned int, clk_div)
+			     __field(unsigned int, clk_idx)
+	    ),
+
+	    TP_fast_assign(__assign_str(name);
+			   __entry->desired_rate = desired_rate;
+			   __entry->clk_rate = clk_rate;
+			   __entry->clk_div = clk_div;
+			   __entry->clk_idx = clk_idx;
+	    ),
+
+	    TP_printk("%s: desired_rate=%u clk_rate=%lu clk_div=%u clk_idx=%u",
+		      __get_str(name), __entry->desired_rate, __entry->clk_rate,
+		      __entry->clk_div, __entry->clk_idx)
+);
+
+TRACE_EVENT(geni_serial_irq,
+	    TP_PROTO(struct device *dev, u32 m_irq, u32 s_irq,
+		     u32 dma_tx, u32 dma_rx),
+	    TP_ARGS(dev, m_irq, s_irq, dma_tx, dma_rx),
+
+	    TP_STRUCT__entry(__string(name, dev_name(dev))
+			     __field(u32, m_irq)
+			     __field(u32, s_irq)
+			     __field(u32, dma_tx)
+			     __field(u32, dma_rx)
+	    ),
+
+	    TP_fast_assign(__assign_str(name);
+			   __entry->m_irq = m_irq;
+			   __entry->s_irq = s_irq;
+			   __entry->dma_tx = dma_tx;
+			   __entry->dma_rx = dma_rx;
+	    ),
+
+	    TP_printk("%s: m_irq=0x%08x s_irq=0x%08x dma_tx=0x%08x dma_rx=0x%08x",
+		      __get_str(name), __entry->m_irq, __entry->s_irq,
+		      __entry->dma_tx, __entry->dma_rx)
+);
+
+DECLARE_EVENT_CLASS(geni_serial_data,
+
+	TP_PROTO(struct device *dev, const u8 *buf, unsigned int len),
+
+	TP_ARGS(dev, buf, len),
+
+	TP_STRUCT__entry(__string(name, dev_name(dev))
+			 __field(unsigned int, len)
+			 __dynamic_array(u8, data, len)
+	),
+
+	TP_fast_assign(__assign_str(name);
+		       __entry->len = len;
+		       memcpy(__get_dynamic_array(data), buf, len);
+	),
+
+	TP_printk("%s: len=%u data=%s",
+		  __get_str(name), __entry->len,
+		  __print_hex(__get_dynamic_array(data), __entry->len))
+);
+
+DEFINE_EVENT(geni_serial_data, geni_serial_tx_data,
+
+	TP_PROTO(struct device *dev, const u8 *buf, unsigned int len),
+
+	TP_ARGS(dev, buf, len)
+
+);
+
+DEFINE_EVENT(geni_serial_data, geni_serial_rx_data,
+
+	TP_PROTO(struct device *dev, const u8 *buf, unsigned int len),
+
+	TP_ARGS(dev, buf, len)
+
+);
+
+TRACE_EVENT(geni_serial_set_mctrl,
+	    TP_PROTO(struct device *dev, unsigned int mctrl,
+		     u32 uart_manual_rfr),
+	    TP_ARGS(dev, mctrl, uart_manual_rfr),
+
+	    TP_STRUCT__entry(__string(name, dev_name(dev))
+			     __field(unsigned int, mctrl)
+			     __field(u32, uart_manual_rfr)
+	    ),
+
+	    TP_fast_assign(__assign_str(name);
+			   __entry->mctrl = mctrl;
+			   __entry->uart_manual_rfr = uart_manual_rfr;
+	    ),
+
+	    TP_printk("%s: mctrl=0x%04x uart_manual_rfr=0x%08x",
+		      __get_str(name), __entry->mctrl, __entry->uart_manual_rfr)
+);
+
+TRACE_EVENT(geni_serial_get_mctrl,
+	    TP_PROTO(struct device *dev, unsigned int mctrl, u32 geni_ios),
+	    TP_ARGS(dev, mctrl, geni_ios),
+
+	    TP_STRUCT__entry(__string(name, dev_name(dev))
+			     __field(unsigned int, mctrl)
+			     __field(u32, geni_ios)
+	    ),
+
+	    TP_fast_assign(__assign_str(name);
+			   __entry->mctrl = mctrl;
+			   __entry->geni_ios = geni_ios;
+	    ),
+
+	    TP_printk("%s: mctrl=0x%04x geni_ios=0x%08x",
+		      __get_str(name), __entry->mctrl, __entry->geni_ios)
+);
+
+#endif /* _TRACE_QCOM_GENI_SERIAL_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>

-- 
2.34.1


^ permalink raw reply related

* [PATCH v2 0/2] Add tracepoints support for Qualcomm GENI Serial drivers
From: Praveen Talari @ 2026-05-12 17:14 UTC (permalink / raw)
  To: Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers,
	Greg Kroah-Hartman, Jiri Slaby, Konrad Dybcio
  Cc: linux-kernel, linux-trace-kernel, linux-arm-msm, linux-serial,
	Mukesh Kumar Savaliya, Aniket Randive, chandana.chiluveru,
	jyothi.seerapu, Praveen Talari

Add tracepoints to the Qualcomm GENI (Generic Interface) serial driver.
These trace events enable runtime debugging and performance analysis of
UART operations.

The trace events cover UART termios configuration, clock setup, manual
control state, interrupt status, and actual transmitted/received data in
hexadecimal format.

Usage examples:

Enable all serial traces:
  echo 1 > /sys/kernel/debug/tracing/events/qcom_geni_serial/enable
  cat /sys/kernel/debug/tracing/trace_pipe

Example trace output:

2517.938432: geni_serial_clk_cfg: a94000.serial: desired_rate=1843200
     clk_rate=7372800 clk_div=4 clk_idx=0
2517.938753: geni_serial_irq: a94000.serial: m_irq=0x88800000
     s_irq=0x08000111 dma_tx=0x00000000 dma_rx=0x00000000
2517.938803: geni_serial_set_termios: a94000.serial: baud=115200 bpc=8
     tx_trans=0x00000002 tx_par=0x00000000 rx_trans=0x00000000
rx_par=0x00000000 stop=0
2517.938807: geni_serial_set_mctrl: a94000.serial: mctrl=0x8006
     uart_manual_rfr=0x00000000
2517.938818: geni_serial_get_mctrl: a94000.serial: mctrl=0x0160
     geni_ios=0x00000001
2517.939165: geni_serial_irq: a94000.serial: m_irq=0x00400000
     s_irq=0x00000000 dma_tx=0x00000000 dma_rx=0x00000000
2517.939592: geni_serial_tx_data: a94000.serial: tx_len=8 data=61 62 63
     64 65 66 67 68
2517.940610: geni_serial_irq: a94000.serial: m_irq=0x00000001
     s_irq=0x00000000 dma_tx=0x00000003 dma_rx=0x00000000
2517.942174: geni_serial_irq: a94000.serial: m_irq=0x08000000
     s_irq=0x08000100 dma_tx=0x00000000 dma_rx=0x00000003
2517.942323: geni_serial_rx_data: a94000.serial: rx_len=8 data=61 62 63
     64 65 66 67 68
2517.942680: geni_serial_set_mctrl: a94000.serial: mctrl=0x8000
     uart_manual_rfr=0x80000002

Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
Changes in v2:
- removed multiple trace events for TX/RX events, instead used
  DECLARE_EVENT_CLASS and DEFINE_EVENT.
- Link to v1: https://lore.kernel.org/r/20260506-add-tracepoints-for-qcom-geni-serial-v1-0-544b22612e08@oss.qualcomm.com

---
Praveen Talari (2):
      serial: qcom-geni: trace: Add tracepoint support for Qualcomm GENI serial
      serial: qcom-geni: Add tracepoints for Qualcomm GENI serial driver

 drivers/tty/serial/qcom_geni_serial.c   |  27 ++++-
 include/trace/events/qcom_geni_serial.h | 172 ++++++++++++++++++++++++++++++++
 2 files changed, 195 insertions(+), 4 deletions(-)
---
base-commit: 1f5ffc672165ff851063a5fd044b727ab2517ae3
change-id: 20260427-add-tracepoints-for-qcom-geni-serial-948777218b7b

Best regards,
-- 
Praveen Talari <praveen.talari@oss.qualcomm.com>


^ permalink raw reply

* [PATCH] serial: max310x: fix compile errors if CONFIG_SPI_MASTER is disabled
From: Hugo Villeneuve @ 2026-05-12 15:27 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby, Hugo Villeneuve
  Cc: hugo, linux-serial, kernel test robot, linux-kernel

From: Hugo Villeneuve <hvilleneuve@dimonoff.com>

Since commit 20ffe4b3330a8 ("serial: max310x: allow driver to be built with
SPI or I2C"), if I2C is enabled and SPI_MASTER is disabled, we have these
compile errors:

  drivers/tty/serial/max310x.c: In function 'max310x_uart_init':
  drivers/tty/serial/max310x.c: error: 'max310x_spi_driver' undeclared...
  drivers/tty/serial/max310x.c: In function ‘max310x_uart_init’:
  drivers/tty/serial/max310x.c: error: label ‘err_spi_register’
  defined but not used...
  drivers/tty/serial/max310x.c: error: ‘regcfg’ defined but not used

Fix by properly encapsulating i2c/spi code/variables in their respective
context with CONFIG_I2C and CONFIG_SPI_MASTER.

Fixes: 20ffe4b3330a8 ("serial: max310x: allow driver to be built with SPI or I2C")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202605121847.N9DVLNg2-lkp@intel.com/
Signed-off-by: Hugo Villeneuve <hvilleneuve@dimonoff.com>
---
note: not Cc-ing stable as the commit is still in tty-next, and even if the
errors originate from original commit that added I2C support, they were not
trigerred because the driver could not be selected/compiled if
CONFIG_SPI_MASTER was disabled.
---
 drivers/tty/serial/max310x.c | 34 ++++++++++++++++++----------------
 1 file changed, 18 insertions(+), 16 deletions(-)

diff --git a/drivers/tty/serial/max310x.c b/drivers/tty/serial/max310x.c
index 9f423b3b4201d..8380fa1b0c0eb 100644
--- a/drivers/tty/serial/max310x.c
+++ b/drivers/tty/serial/max310x.c
@@ -1507,6 +1507,21 @@ static const struct of_device_id __maybe_unused max310x_dt_ids[] = {
 };
 MODULE_DEVICE_TABLE(of, max310x_dt_ids);
 
+static const char *max310x_regmap_name(u8 port_id)
+{
+	switch (port_id) {
+	case 0:	return "port0";
+	case 1:	return "port1";
+	case 2:	return "port2";
+	case 3:	return "port3";
+	default:
+		WARN_ON(true);
+		return NULL;
+	}
+}
+
+#ifdef CONFIG_SPI_MASTER
+
 static struct regmap_config regcfg = {
 	.reg_bits = 8,
 	.val_bits = 8,
@@ -1522,20 +1537,6 @@ static struct regmap_config regcfg = {
 	.max_raw_write = MAX310X_FIFO_SIZE,
 };
 
-static const char *max310x_regmap_name(u8 port_id)
-{
-	switch (port_id) {
-	case 0:	return "port0";
-	case 1:	return "port1";
-	case 2:	return "port2";
-	case 3:	return "port3";
-	default:
-		WARN_ON(true);
-		return NULL;
-	}
-}
-
-#ifdef CONFIG_SPI_MASTER
 static int max310x_spi_extended_reg_enable(struct device *dev, bool enable)
 {
 	struct max310x_port *s = dev_get_drvdata(dev);
@@ -1742,10 +1743,11 @@ static int __init max310x_uart_init(void)
 
 #ifdef CONFIG_I2C
 err_i2c_register:
-	spi_unregister_driver(&max310x_spi_driver);
 #endif
-
+#ifdef CONFIG_SPI_MASTER
+	spi_unregister_driver(&max310x_spi_driver);
 err_spi_register:
+#endif
 	uart_unregister_driver(&max310x_uart);
 
 	return ret;

base-commit: 16e95bfb79b5d9d01dc7651d98caf3c2ace331cd
-- 
2.47.3


^ permalink raw reply related

* [PATCH 3/3] serial: 8250_dw: dispatch SysRq character in dw8250_handle_irq()
From: Jacques Nilo @ 2026-05-12 13:46 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: linux-serial, linux-kernel, Ilpo Järvinen, Johan Hovold,
	Jacques Nilo, stable
In-Reply-To: <cover.1778592805.git.jnilo@free.fr>

dw8250_handle_irq() calls serial8250_handle_irq_locked() with the port
lock held via guard(uart_port_lock_irqsave). The guard destructor is
plain uart_port_unlock_irqrestore(), so a SysRq character captured into
port->sysrq_ch by uart_prepare_sysrq_char() is dropped without ever
being dispatched to handle_sysrq().

This is the same regression pattern as in serial8250_handle_irq(),
introduced when 883c5a2bc934 ("serial: 8250_dw: Rework
dw8250_handle_irq() locking and IIR handling") moved the function to
the guard()-based locking scheme without using the sysrq-aware unlock
helper.

Switch to guard(uart_port_lock_sysrq_irqsave) so that captured
sysrq_ch is dispatched on scope exit, matching the fix in
serial8250_handle_irq().

Fixes: 883c5a2bc934 ("serial: 8250_dw: Rework dw8250_handle_irq() locking and IIR handling")
Cc: stable@vger.kernel.org
Signed-off-by: Jacques Nilo <jnilo@free.fr>
---
 drivers/tty/serial/8250/8250_dw.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index 55e40c10f..237543fa7 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -416,7 +416,7 @@ static int dw8250_handle_irq(struct uart_port *p)
 	unsigned int quirks = d->pdata->quirks;
 	unsigned int status;
 
-	guard(uart_port_lock_irqsave)(p);
+	guard(uart_port_lock_sysrq_irqsave)(p);
 
 	switch (FIELD_GET(DW_UART_IIR_IID, iir)) {
 	case UART_IIR_NO_INT:
-- 
2.43.0


^ permalink raw reply related

* [PATCH 2/3] serial: 8250: dispatch SysRq character in serial8250_handle_irq()
From: Jacques Nilo @ 2026-05-12 13:46 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: linux-serial, linux-kernel, Ilpo Järvinen, Johan Hovold,
	Jacques Nilo, stable
In-Reply-To: <cover.1778592805.git.jnilo@free.fr>

serial8250_handle_irq() captures a SysRq character into port->sysrq_ch
inside serial8250_handle_irq_locked() via uart_prepare_sysrq_char()
(reached from serial8250_read_char()). Dispatch of that captured
character to handle_sysrq() is expected to happen at port-unlock time,
through uart_unlock_and_check_sysrq[_irqrestore]().

After commit 8324a54f604d ("serial: 8250: Add
serial8250_handle_irq_locked()") the function was reduced to a wrapper
that takes the port lock via guard(uart_port_lock_irqsave) whose
destructor is plain uart_port_unlock_irqrestore(). The sysrq-aware
unlock helper is no longer called, so port->sysrq_ch is captured but
never dispatched: BREAK + SysRq key is consumed silently.

This was the very condition Johan Hovold's 853a9ae29e978 ("serial:
8250: fix handle_irq locking", 2021) introduced
uart_unlock_and_check_sysrq_irqrestore() to address.

Switch to the new guard(uart_port_lock_sysrq_irqsave), whose destructor
is the sysrq-aware unlock helper, restoring the pre-split behaviour.
Update the Context: comment on serial8250_handle_irq_locked() so future
HW-specific 8250 wrappers know to use the same guard or the explicit
sysrq-aware unlock.

Verified on RTL8196E with CONFIG_MAGIC_SYSRQ_SERIAL=y: BREAK + 'h' on
the console UART produces the SysRq help dump in dmesg and the brk
counter in /proc/tty/driver/serial increments correctly.

Fixes: 8324a54f604d ("serial: 8250: Add serial8250_handle_irq_locked()")
Cc: stable@vger.kernel.org
Signed-off-by: Jacques Nilo <jnilo@free.fr>
---
 drivers/tty/serial/8250/8250_port.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index e4e6a53eb..64f3487e8 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -1786,7 +1786,10 @@ static bool handle_rx_dma(struct uart_8250_port *up, unsigned int iir)
 }
 
 /*
- * Context: port's lock must be held by the caller.
+ * Context: port's lock must be held by the caller. The caller must
+ * release it via guard(uart_port_lock_sysrq_irqsave) or
+ * uart_unlock_and_check_sysrq_irqrestore(), which captures SysRq
+ * character on unlock.
  */
 void serial8250_handle_irq_locked(struct uart_port *port, unsigned int iir)
 {
@@ -1839,7 +1842,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
 	if (iir & UART_IIR_NO_INT)
 		return 0;
 
-	guard(uart_port_lock_irqsave)(port);
+	guard(uart_port_lock_sysrq_irqsave)(port);
 	serial8250_handle_irq_locked(port, iir);
 
 	return 1;
-- 
2.43.0


^ permalink raw reply related

* [PATCH 1/3] serial: core: introduce guard(uart_port_lock_sysrq_irqsave)
From: Jacques Nilo @ 2026-05-12 13:46 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: linux-serial, linux-kernel, Ilpo Järvinen, Johan Hovold,
	Jacques Nilo
In-Reply-To: <cover.1778592805.git.jnilo@free.fr>

uart_handle_break() and uart_prepare_sysrq_char() (in
include/linux/serial_core.h) capture a SysRq character into
port->sysrq_ch while the port lock is held and rely on the unlock
helper -- uart_unlock_and_check_sysrq_irqrestore() -- to dispatch the
captured character to handle_sysrq() on scope exit.

The existing guard(uart_port_lock_irqsave) cannot be used by IRQ
handlers that process RX, because its destructor calls plain
uart_port_unlock_irqrestore() and silently drops port->sysrq_ch.

Add a dedicated guard variant whose destructor is the sysrq-aware
unlock helper. Callers that may capture SysRq characters opt in by
using guard(uart_port_lock_sysrq_irqsave); the existing
uart_port_lock_irqsave guard keeps its current plain-unlock semantics
for the many callers that do not process RX.

The lock side is identical to uart_port_lock_irqsave -- only the
unlock-time behaviour differs. Naming mirrors
uart_unlock_and_check_sysrq_irqrestore() (sysrq before irqsave/irqrestore).

The new macro is placed after the CONFIG_MAGIC_SYSRQ_SERIAL block so
both definitions of uart_unlock_and_check_sysrq_irqrestore() (sysrq
enabled and disabled) are visible at expansion time. When
CONFIG_MAGIC_SYSRQ_SERIAL=n the destructor degenerates to plain
uart_port_unlock_irqrestore(), so there is no overhead.

No functional change on its own; users are converted in the following
patches.

Signed-off-by: Jacques Nilo <jnilo@free.fr>
---
 include/linux/serial_core.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 4f7bbdd90..4fa079dc9 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -1286,6 +1286,19 @@ static inline void uart_unlock_and_check_sysrq_irqrestore(struct uart_port *port
 }
 #endif	/* CONFIG_MAGIC_SYSRQ_SERIAL */
 
+/*
+ * Variant of guard(uart_port_lock_irqsave) for IRQ handlers that may capture
+ * a SysRq character via uart_prepare_sysrq_char(). The destructor uses the
+ * sysrq-aware unlock helper so that a captured port->sysrq_ch is dispatched
+ * to handle_sysrq() on scope exit. The plain guard variant silently drops
+ * sysrq_ch and must not be used by callers that process RX.
+ */
+DEFINE_LOCK_GUARD_1(uart_port_lock_sysrq_irqsave, struct uart_port,
+                    uart_port_lock_irqsave(_T->lock, &_T->flags),
+                    uart_unlock_and_check_sysrq_irqrestore(_T->lock,
+                                                           _T->flags),
+                    unsigned long flags);
+
 /*
  * We do the SysRQ and SAK checking like this...
  */
-- 
2.43.0


^ permalink raw reply related

* [PATCH 0/3] serial: 8250: fix BREAK+SysRq dispatch on guard()-locked IRQ handlers
From: Jacques Nilo @ 2026-05-12 13:46 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: linux-serial, linux-kernel, Ilpo Järvinen, Johan Hovold,
	Jacques Nilo
In-Reply-To: <5efe9e03-4d86-43a0-9ec2-e610ff31095d@free.fr>

This series fixes a silent regression where a SysRq character entered as
BREAK + key on the serial console is consumed by the kernel but never
dispatched to handle_sysrq().

The root cause and two fix candidates were discussed in [1]. Following
Ilpo's suggestion, this series adds a dedicated lock-guard variant whose
destructor is the sysrq-aware unlock helper, and switches the two
affected IRQ handlers (serial8250_handle_irq and dw8250_handle_irq) to
use it. The plain guard(uart_port_lock_irqsave) keeps its current
semantics for the many callers that do not process RX.

Patch 1 introduces guard(uart_port_lock_sysrq_irqsave) in serial_core.h.
Patch 2 switches serial8250_handle_irq() and updates the Context comment
        on serial8250_handle_irq_locked() so future HW-specific 8250
        wrappers know which unlock variant is required.
Patch 3 switches dw8250_handle_irq() to the same guard.

Verified on RTL8196E with CONFIG_MAGIC_SYSRQ_SERIAL=y: BREAK + 'h' on
the console UART now produces the SysRq help dump in dmesg; the brk
counter in /proc/tty/driver/serial increments per BREAK as expected.
Build tested on tty-next (base 16e95bfb79b5).

[1] https://lore.kernel.org/linux-serial/5efe9e03-4d86-43a0-9ec2-e610ff31095d@free.fr/

Jacques Nilo (3):
  serial: core: introduce guard(uart_port_lock_sysrq_irqsave)
  serial: 8250: dispatch SysRq character in serial8250_handle_irq()
  serial: 8250_dw: dispatch SysRq character in dw8250_handle_irq()

 drivers/tty/serial/8250/8250_dw.c   |  2 +-
 drivers/tty/serial/8250/8250_port.c |  7 +++++--
 include/linux/serial_core.h         | 13 +++++++++++++
 3 files changed, 19 insertions(+), 3 deletions(-)


base-commit: 16e95bfb79b5d9d01dc7651d98caf3c2ace331cd
-- 
2.43.0


^ permalink raw reply

* Re: [REPORT] serial: 8250: BREAK + SysRq dispatch silently broken since 8324a54f604d
From: Ilpo Järvinen @ 2026-05-12 13:21 UTC (permalink / raw)
  To: Jacques Nilo
  Cc: Ilpo Järvinen, Greg Kroah-Hartman, Jiri Slaby, linux-serial,
	LKML, Johan Hovold
In-Reply-To: <122f6431-2241-4367-be28-bfd3b31f5333@free.fr>

[-- Attachment #1: Type: text/plain, Size: 3670 bytes --]

On Tue, 12 May 2026, Jacques Nilo wrote:

> On Tue, 12 May 2026, Ilpo Järvinen wrote:
> 
> > I seem to have come blind to the (unlock function) names. I'm sorry
> > about breaking this.
> 
> No problem at all -- the asymmetry between the lock and unlock helper
> names is exactly the kind of thing that's easy to miss in a refactor.
> 
> > 8250_dw's handle_irq also uses guard() which was the reason for this
> > change in the first place so it should be fixed as well.
> 
> Confirmed -- dw8250_handle_irq() at drivers/tty/serial/8250/8250_dw.c:421
> does the same guard(uart_port_lock_irqsave)(p) before
> serial8250_handle_irq_locked(). Same bug.
> 
> > > Option B -- fix the guard destructor in serial_core.h:
> >
> > There will be many such sites so this doesn't sound a great idea.
> >
> > I wonder why we couldn't instead do another DEFINE_GUARD() for the
> > sysrq case?
> 
> Agreed, that's cleaner. The lock side is identical -- only the unlock
> needs the sysrq-aware variant -- so a second lock-guard macro keyed off
> the unlock destructor fits well:
> 
>   DEFINE_LOCK_GUARD_1(uart_port_lock_irqsave_sysrq, struct uart_port,
>                       uart_port_lock_irqsave(_T->lock, &_T->flags),
> uart_unlock_and_check_sysrq_irqrestore(_T->lock,
>  _T->flags),
>                       unsigned long flags);
> 
> Callers that may capture sysrq_ch (currently serial8250_handle_irq and
> dw8250_handle_irq) opt in by using guard(uart_port_lock_irqsave_sysrq);
> the existing guard(uart_port_lock_irqsave) keeps its current plain-unlock
> semantics for everyone else.
> 
> Naming-wise I'm not attached to "_sysrq" -- if you'd prefer something
> shorter (e.g. uart_port_rx_lock_irqsave) or aligned with another
> convention in the tree, happy to take direction.

I don't have strong preferences (I'm usually not good with names
anyway :-)). Somebody might object not placing _irqsave as last in the 
name (and reversing the word order would be a bit inconsistent compared 
with the unlock name).

> > I suppose thought the lockdep assert in serial8250_handle_irq_locked()
> > cannot discern that the correct one of them is being used by the
> > caller. But at least it's context comment should mention that the
> > correct guard/unlock variant should be used.
> 
> Right -- both guards take port->lock so lockdep can't distinguish them.
> I'll update the Context: line on serial8250_handle_irq_locked() to spell
> out the requirement, e.g.:
> 
>   /*
>    * Context: port's lock must be held by the caller, and must be released
>    * via guard(uart_port_lock_irqsave_sysrq) or
>    * uart_unlock_and_check_sysrq_irqrestore()

> so a SysRq character
>    * captured by serial8250_read_char() is dispatched on unlock.

This would be less words to the same effect:

which captures SysRq character on unlock.

?

>    */
> 
> Plan, then, for a v1 patch series against tty-next:
> 
>   1. include/linux/serial_core.h: add the new lock-guard macro.
>   2. drivers/tty/serial/8250/8250_port.c: switch serial8250_handle_irq()
>      to guard(uart_port_lock_irqsave_sysrq); update the Context comment
>      on serial8250_handle_irq_locked().
>   3. drivers/tty/serial/8250/8250_dw.c: switch dw8250_handle_irq() to
>      the same guard.
> 
> I'll mark it with Fixes: 8324a54f604d and Cc: stable for the kernels
> that carry the regression. Let me know if the naming or the Context
> wording wants adjusting before I send.

+

Fixes: 883c5a2bc934 ("serial: 8250_dw: Rework dw8250_handle_irq() locking and IIR handling")


-- 
 i.

^ permalink raw reply

* Re: [REPORT] serial: 8250: BREAK + SysRq dispatch silently broken since 8324a54f604d
From: Jacques Nilo @ 2026-05-12 13:06 UTC (permalink / raw)
  To: Ilpo Järvinen
  Cc: Greg Kroah-Hartman, Jiri Slaby, linux-serial, LKML, Johan Hovold
In-Reply-To: <4bab4248-1c49-3f68-d327-fc00a4d7114b@linux.intel.com>

On Tue, 12 May 2026, Ilpo Järvinen wrote:

 > I seem to have come blind to the (unlock function) names. I'm sorry
 > about breaking this.

No problem at all -- the asymmetry between the lock and unlock helper
names is exactly the kind of thing that's easy to miss in a refactor.

 > 8250_dw's handle_irq also uses guard() which was the reason for this
 > change in the first place so it should be fixed as well.

Confirmed -- dw8250_handle_irq() at drivers/tty/serial/8250/8250_dw.c:421
does the same guard(uart_port_lock_irqsave)(p) before
serial8250_handle_irq_locked(). Same bug.

 > > Option B -- fix the guard destructor in serial_core.h:
 >
 > There will be many such sites so this doesn't sound a great idea.
 >
 > I wonder why we couldn't instead do another DEFINE_GUARD() for the
 > sysrq case?

Agreed, that's cleaner. The lock side is identical -- only the unlock
needs the sysrq-aware variant -- so a second lock-guard macro keyed off
the unlock destructor fits well:

   DEFINE_LOCK_GUARD_1(uart_port_lock_irqsave_sysrq, struct uart_port,
                       uart_port_lock_irqsave(_T->lock, &_T->flags),
uart_unlock_and_check_sysrq_irqrestore(_T->lock,
  _T->flags),
                       unsigned long flags);

Callers that may capture sysrq_ch (currently serial8250_handle_irq and
dw8250_handle_irq) opt in by using guard(uart_port_lock_irqsave_sysrq);
the existing guard(uart_port_lock_irqsave) keeps its current plain-unlock
semantics for everyone else.

Naming-wise I'm not attached to "_sysrq" -- if you'd prefer something
shorter (e.g. uart_port_rx_lock_irqsave) or aligned with another
convention in the tree, happy to take direction.

 > I suppose thought the lockdep assert in serial8250_handle_irq_locked()
 > cannot discern that the correct one of them is being used by the
 > caller. But at least it's context comment should mention that the
 > correct guard/unlock variant should be used.

Right -- both guards take port->lock so lockdep can't distinguish them.
I'll update the Context: line on serial8250_handle_irq_locked() to spell
out the requirement, e.g.:

   /*
    * Context: port's lock must be held by the caller, and must be released
    * via guard(uart_port_lock_irqsave_sysrq) or
    * uart_unlock_and_check_sysrq_irqrestore() so a SysRq character
    * captured by serial8250_read_char() is dispatched on unlock.
    */

Plan, then, for a v1 patch series against tty-next:

   1. include/linux/serial_core.h: add the new lock-guard macro.
   2. drivers/tty/serial/8250/8250_port.c: switch serial8250_handle_irq()
      to guard(uart_port_lock_irqsave_sysrq); update the Context comment
      on serial8250_handle_irq_locked().
   3. drivers/tty/serial/8250/8250_dw.c: switch dw8250_handle_irq() to
      the same guard.

I'll mark it with Fixes: 8324a54f604d and Cc: stable for the kernels
that carry the regression. Let me know if the naming or the Context
wording wants adjusting before I send.

Thanks for the quick read,

Jacques

Le 12/05/2026 à 14:58, Ilpo Järvinen a écrit :
> On Tue, 12 May 2026, Jacques Nilo wrote:
>
>> Hi,
>>
>> We hit what looks like a silent SysRq-over-serial regression on a 6.18
>> build of the 8250 driver. Posting as a report rather than a patch because
>> there are at least two reasonable fixes and I'd like a maintainer call
>> before sending one.
>>
>> Symptom
>> =======
>>
>> CONFIG_MAGIC_SYSRQ=y, CONFIG_MAGIC_SYSRQ_SERIAL=y,
>> CONFIG_SERIAL_8250_CONSOLE=y.
>>
>> A BREAK followed by a SysRq key on the console UART is consumed by the
>> kernel (BREAK counter in /proc/tty/driver/serial increments correctly)
>> but is never dispatched to handle_sysrq(). dmesg shows no "sysrq: ..."
>> line.
>>
>> `echo h > /proc/sysrq-trigger` still works, isolating the regression to
>> the serial input path. Verified end-to-end on an RTL8196E MIPS board
>> running 6.18.24; the affected code is in the generic 8250 core, so the
>> issue is not platform-specific.
>>
>> Path
>> ====
>>
>>    serial8250_default_handle_irq()
>>      -> serial8250_handle_irq() [8250_port.c:1835]
>>           guard(uart_port_lock_irqsave)(port);  [8250_port.c:1840]
>>           serial8250_handle_irq_locked()
>>             -> serial8250_rx_chars()
>>                -> serial8250_read_char()
>>                   -> uart_handle_break()                 -- arms port->sysrq
>>                   -> uart_prepare_sysrq_char(port, ch)   -- captures sysrq_ch
>>           /* guard scope ends -> port unlock */
>>
>> The captured port->sysrq_ch is dispatched to handle_sysrq() at unlock
>> time -- but only by uart_unlock_and_check_sysrq[_irqrestore]() (see
>> include/linux/serial_core.h:1239). The scope guard's destructor at
>> serial_core.h:797 is plain uart_port_unlock_irqrestore(), which skips
>> the dispatch:
>>
>>    DEFINE_LOCK_GUARD_1(uart_port_lock_irqsave, struct uart_port,
>>                        uart_port_lock_irqsave(_T->lock, &_T->flags),
>>                        uart_port_unlock_irqrestore(_T->lock, _T->flags),
>>                        unsigned long flags);
>>
>> So sysrq_ch stays in the struct until the next BREAK clears it.
>>
>> Bisection
>> =========
>>
>>    commit 8324a54f604d ("serial: 8250: Add serial8250_handle_irq_locked()")
>>
>> Pre-split serial8250_handle_irq() used explicit uart_port_lock_irqsave()
>> + uart_unlock_and_check_sysrq_irqrestore(). The split moved the body into
>> _locked() and replaced the explicit lock pair with
>> guard(uart_port_lock_irqsave), losing the sysrq-aware unlock.
>>
>> This was the very condition Johan Hovold's 853a9ae29e978 ("serial: 8250:
>> fix handle_irq locking", 2021) introduced
>> uart_unlock_and_check_sysrq_irqrestore() to address -- the new helper was
>> deliberately the sysrq-aware variant. The guard() conversion undoes that
>> intent.
> I seem to have come blind to the (unlock function) names. I'm sorry about
> breaking this.
>   
>> Reproducer
>> ==========
>>
>> On any 8250-driven console with CONFIG_MAGIC_SYSRQ_SERIAL=y:
>>
>>    # On the host side:
>>    python3 -c 'import os,fcntl,termios,time
>>    fd=os.open("/dev/ttyUSB0",os.O_RDWR|os.O_NOCTTY)
>>    fcntl.ioctl(fd,0x5427); time.sleep(0.3); fcntl.ioctl(fd,0x5428)
>>    time.sleep(0.05); os.write(fd,b"h"); time.sleep(0.3)'
>>
>>    # On the gateway:
>>    grep brk /proc/tty/driver/serial      # counter increments
>>    dmesg | grep sysrq:                   # empty -- no dispatch
>>
>> Two ways to fix
>> ===============
>>
>> Option A -- surgical, only fix serial8250_handle_irq():
>>
>>    int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
>>    {
>>            unsigned long flags;
>>
>>            if (iir & UART_IIR_NO_INT)
>>                    return 0;
>>
>>            uart_port_lock_irqsave(port, &flags);
>>            serial8250_handle_irq_locked(port, iir);
>>            uart_unlock_and_check_sysrq_irqrestore(port, flags);
>>
>>            return 1;
>>    }
>>
>> Restores the pre-split behaviour. Doesn't touch the guard infrastructure.
>> Drawback: leaves uart_port_lock_irqsave() as a generic primitive that
>> silently swallows pending sysrq_ch in any other call site that processes
>> RX under the guard. There are no such sites today in 8250_port.c
>> (uart_prepare_sysrq_char is only reachable through serial8250_handle_irq),
>> but the trap remains.
> 8250_dw's handle_irq also uses guard() which was the reason for this
> change in the first place so it should be fixed as well.
>
>> Option B -- fix the guard destructor in serial_core.h:
>>
>>    DEFINE_LOCK_GUARD_1(uart_port_lock_irqsave, struct uart_port,
>>                        uart_port_lock_irqsave(_T->lock, &_T->flags),
>> uart_unlock_and_check_sysrq_irqrestore(_T->lock,
>>   _T->flags),
>>                        unsigned long flags);
>>
>> uart_unlock_and_check_sysrq_irqrestore() short-circuits to plain unlock
>> when !port->has_sysrq, so no overhead on non-sysrq ports. Fixes all
>> current and future guard(uart_port_lock_irqsave) users in one place.
>> Drawback: changes the semantics of a shared serial primitive. Some
>> callers in 8250_port.c run under that guard from non-RX contexts
>> (serial8250_set_mctrl, wait_for_xmitr, etc.); the only observable effect
>> there would be a one-time handle_sysrq() call if a previous BREAK left
>> sysrq_ch set -- functionally desirable, but a behaviour change worth
>> documenting.
> There will be many such sites so this doesn't sound a great idea.
>
> I wonder why we couldn't instead do another DEFINE_GUARD() for the sysrq
> case?
>
> I suppose thought the lockdep assert in serial8250_handle_irq_locked()
> cannot discern that the correct one of them is being used by the caller.
> But at least it's context comment should mention that the correct
> guard/unlock variant should be used.
>
>> I have a tested Option A patch against 6.18.24 (verified the dispatch
>> fires and produces the SysRq help dump). Happy to send it formally, or
>> to retarget to Option B if that's the preferred direction.
>>
>> Thanks,
>>
>> Jacques
>>

^ permalink raw reply

* Re: [REPORT] serial: 8250: BREAK + SysRq dispatch silently broken since 8324a54f604d
From: Ilpo Järvinen @ 2026-05-12 12:58 UTC (permalink / raw)
  To: Jacques Nilo
  Cc: Greg Kroah-Hartman, Jiri Slaby, linux-serial, LKML, Johan Hovold
In-Reply-To: <5efe9e03-4d86-43a0-9ec2-e610ff31095d@free.fr>

[-- Attachment #1: Type: text/plain, Size: 6161 bytes --]

On Tue, 12 May 2026, Jacques Nilo wrote:

> Hi,
> 
> We hit what looks like a silent SysRq-over-serial regression on a 6.18
> build of the 8250 driver. Posting as a report rather than a patch because
> there are at least two reasonable fixes and I'd like a maintainer call
> before sending one.
> 
> Symptom
> =======
> 
> CONFIG_MAGIC_SYSRQ=y, CONFIG_MAGIC_SYSRQ_SERIAL=y,
> CONFIG_SERIAL_8250_CONSOLE=y.
> 
> A BREAK followed by a SysRq key on the console UART is consumed by the
> kernel (BREAK counter in /proc/tty/driver/serial increments correctly)
> but is never dispatched to handle_sysrq(). dmesg shows no "sysrq: ..."
> line.
> 
> `echo h > /proc/sysrq-trigger` still works, isolating the regression to
> the serial input path. Verified end-to-end on an RTL8196E MIPS board
> running 6.18.24; the affected code is in the generic 8250 core, so the
> issue is not platform-specific.
> 
> Path
> ====
> 
>   serial8250_default_handle_irq()
>     -> serial8250_handle_irq() [8250_port.c:1835]
>          guard(uart_port_lock_irqsave)(port);  [8250_port.c:1840]
>          serial8250_handle_irq_locked()
>            -> serial8250_rx_chars()
>               -> serial8250_read_char()
>                  -> uart_handle_break()                 -- arms port->sysrq
>                  -> uart_prepare_sysrq_char(port, ch)   -- captures sysrq_ch
>          /* guard scope ends -> port unlock */
> 
> The captured port->sysrq_ch is dispatched to handle_sysrq() at unlock
> time -- but only by uart_unlock_and_check_sysrq[_irqrestore]() (see
> include/linux/serial_core.h:1239). The scope guard's destructor at
> serial_core.h:797 is plain uart_port_unlock_irqrestore(), which skips
> the dispatch:
> 
>   DEFINE_LOCK_GUARD_1(uart_port_lock_irqsave, struct uart_port,
>                       uart_port_lock_irqsave(_T->lock, &_T->flags),
>                       uart_port_unlock_irqrestore(_T->lock, _T->flags),
>                       unsigned long flags);
> 
> So sysrq_ch stays in the struct until the next BREAK clears it.
> 
> Bisection
> =========
> 
>   commit 8324a54f604d ("serial: 8250: Add serial8250_handle_irq_locked()")
> 
> Pre-split serial8250_handle_irq() used explicit uart_port_lock_irqsave()
> + uart_unlock_and_check_sysrq_irqrestore(). The split moved the body into
> _locked() and replaced the explicit lock pair with
> guard(uart_port_lock_irqsave), losing the sysrq-aware unlock.
>
> This was the very condition Johan Hovold's 853a9ae29e978 ("serial: 8250:
> fix handle_irq locking", 2021) introduced
> uart_unlock_and_check_sysrq_irqrestore() to address -- the new helper was
> deliberately the sysrq-aware variant. The guard() conversion undoes that
> intent.

I seem to have come blind to the (unlock function) names. I'm sorry about 
breaking this.
 
> Reproducer
> ==========
> 
> On any 8250-driven console with CONFIG_MAGIC_SYSRQ_SERIAL=y:
> 
>   # On the host side:
>   python3 -c 'import os,fcntl,termios,time
>   fd=os.open("/dev/ttyUSB0",os.O_RDWR|os.O_NOCTTY)
>   fcntl.ioctl(fd,0x5427); time.sleep(0.3); fcntl.ioctl(fd,0x5428)
>   time.sleep(0.05); os.write(fd,b"h"); time.sleep(0.3)'
> 
>   # On the gateway:
>   grep brk /proc/tty/driver/serial      # counter increments
>   dmesg | grep sysrq:                   # empty -- no dispatch
> 
> Two ways to fix
> ===============
> 
> Option A -- surgical, only fix serial8250_handle_irq():
> 
>   int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
>   {
>           unsigned long flags;
> 
>           if (iir & UART_IIR_NO_INT)
>                   return 0;
> 
>           uart_port_lock_irqsave(port, &flags);
>           serial8250_handle_irq_locked(port, iir);
>           uart_unlock_and_check_sysrq_irqrestore(port, flags);
> 
>           return 1;
>   }
> 
> Restores the pre-split behaviour. Doesn't touch the guard infrastructure.
> Drawback: leaves uart_port_lock_irqsave() as a generic primitive that
> silently swallows pending sysrq_ch in any other call site that processes
> RX under the guard. There are no such sites today in 8250_port.c
> (uart_prepare_sysrq_char is only reachable through serial8250_handle_irq),
> but the trap remains.

8250_dw's handle_irq also uses guard() which was the reason for this 
change in the first place so it should be fixed as well.

> Option B -- fix the guard destructor in serial_core.h:
> 
>   DEFINE_LOCK_GUARD_1(uart_port_lock_irqsave, struct uart_port,
>                       uart_port_lock_irqsave(_T->lock, &_T->flags),
> uart_unlock_and_check_sysrq_irqrestore(_T->lock,
>  _T->flags),
>                       unsigned long flags);
> 
> uart_unlock_and_check_sysrq_irqrestore() short-circuits to plain unlock
> when !port->has_sysrq, so no overhead on non-sysrq ports. Fixes all
> current and future guard(uart_port_lock_irqsave) users in one place.
> Drawback: changes the semantics of a shared serial primitive. Some
> callers in 8250_port.c run under that guard from non-RX contexts
> (serial8250_set_mctrl, wait_for_xmitr, etc.); the only observable effect
> there would be a one-time handle_sysrq() call if a previous BREAK left
> sysrq_ch set -- functionally desirable, but a behaviour change worth
> documenting.

There will be many such sites so this doesn't sound a great idea.

I wonder why we couldn't instead do another DEFINE_GUARD() for the sysrq 
case?

I suppose thought the lockdep assert in serial8250_handle_irq_locked() 
cannot discern that the correct one of them is being used by the caller. 
But at least it's context comment should mention that the correct 
guard/unlock variant should be used.

> I have a tested Option A patch against 6.18.24 (verified the dispatch
> fires and produces the SysRq help dump). Happy to send it formally, or
> to retarget to Option B if that's the preferred direction.
> 
> Thanks,
> 
> Jacques
> 

-- 
 i.

^ permalink raw reply

* [REPORT] serial: 8250: BREAK + SysRq dispatch silently broken since 8324a54f604d
From: Jacques Nilo @ 2026-05-12 12:38 UTC (permalink / raw)
  To: Greg Kroah-Hartman, Jiri Slaby
  Cc: linux-serial, linux-kernel, Ilpo Järvinen, Johan Hovold

Hi,

We hit what looks like a silent SysRq-over-serial regression on a 6.18
build of the 8250 driver. Posting as a report rather than a patch because
there are at least two reasonable fixes and I'd like a maintainer call
before sending one.

Symptom
=======

CONFIG_MAGIC_SYSRQ=y, CONFIG_MAGIC_SYSRQ_SERIAL=y,
CONFIG_SERIAL_8250_CONSOLE=y.

A BREAK followed by a SysRq key on the console UART is consumed by the
kernel (BREAK counter in /proc/tty/driver/serial increments correctly)
but is never dispatched to handle_sysrq(). dmesg shows no "sysrq: ..."
line.

`echo h > /proc/sysrq-trigger` still works, isolating the regression to
the serial input path. Verified end-to-end on an RTL8196E MIPS board
running 6.18.24; the affected code is in the generic 8250 core, so the
issue is not platform-specific.

Path
====

   serial8250_default_handle_irq()
     -> serial8250_handle_irq() [8250_port.c:1835]
          guard(uart_port_lock_irqsave)(port);  [8250_port.c:1840]
          serial8250_handle_irq_locked()
            -> serial8250_rx_chars()
               -> serial8250_read_char()
                  -> uart_handle_break()                 -- arms port->sysrq
                  -> uart_prepare_sysrq_char(port, ch)   -- captures 
sysrq_ch
          /* guard scope ends -> port unlock */

The captured port->sysrq_ch is dispatched to handle_sysrq() at unlock
time -- but only by uart_unlock_and_check_sysrq[_irqrestore]() (see
include/linux/serial_core.h:1239). The scope guard's destructor at
serial_core.h:797 is plain uart_port_unlock_irqrestore(), which skips
the dispatch:

   DEFINE_LOCK_GUARD_1(uart_port_lock_irqsave, struct uart_port,
                       uart_port_lock_irqsave(_T->lock, &_T->flags),
                       uart_port_unlock_irqrestore(_T->lock, _T->flags),
                       unsigned long flags);

So sysrq_ch stays in the struct until the next BREAK clears it.

Bisection
=========

   commit 8324a54f604d ("serial: 8250: Add serial8250_handle_irq_locked()")

Pre-split serial8250_handle_irq() used explicit uart_port_lock_irqsave()
+ uart_unlock_and_check_sysrq_irqrestore(). The split moved the body into
_locked() and replaced the explicit lock pair with
guard(uart_port_lock_irqsave), losing the sysrq-aware unlock.

This was the very condition Johan Hovold's 853a9ae29e978 ("serial: 8250:
fix handle_irq locking", 2021) introduced
uart_unlock_and_check_sysrq_irqrestore() to address -- the new helper was
deliberately the sysrq-aware variant. The guard() conversion undoes that
intent.

Reproducer
==========

On any 8250-driven console with CONFIG_MAGIC_SYSRQ_SERIAL=y:

   # On the host side:
   python3 -c 'import os,fcntl,termios,time
   fd=os.open("/dev/ttyUSB0",os.O_RDWR|os.O_NOCTTY)
   fcntl.ioctl(fd,0x5427); time.sleep(0.3); fcntl.ioctl(fd,0x5428)
   time.sleep(0.05); os.write(fd,b"h"); time.sleep(0.3)'

   # On the gateway:
   grep brk /proc/tty/driver/serial      # counter increments
   dmesg | grep sysrq:                   # empty -- no dispatch

Two ways to fix
===============

Option A -- surgical, only fix serial8250_handle_irq():

   int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
   {
           unsigned long flags;

           if (iir & UART_IIR_NO_INT)
                   return 0;

           uart_port_lock_irqsave(port, &flags);
           serial8250_handle_irq_locked(port, iir);
           uart_unlock_and_check_sysrq_irqrestore(port, flags);

           return 1;
   }

Restores the pre-split behaviour. Doesn't touch the guard infrastructure.
Drawback: leaves uart_port_lock_irqsave() as a generic primitive that
silently swallows pending sysrq_ch in any other call site that processes
RX under the guard. There are no such sites today in 8250_port.c
(uart_prepare_sysrq_char is only reachable through serial8250_handle_irq),
but the trap remains.

Option B -- fix the guard destructor in serial_core.h:

   DEFINE_LOCK_GUARD_1(uart_port_lock_irqsave, struct uart_port,
                       uart_port_lock_irqsave(_T->lock, &_T->flags),
uart_unlock_and_check_sysrq_irqrestore(_T->lock,
  _T->flags),
                       unsigned long flags);

uart_unlock_and_check_sysrq_irqrestore() short-circuits to plain unlock
when !port->has_sysrq, so no overhead on non-sysrq ports. Fixes all
current and future guard(uart_port_lock_irqsave) users in one place.
Drawback: changes the semantics of a shared serial primitive. Some
callers in 8250_port.c run under that guard from non-RX contexts
(serial8250_set_mctrl, wait_for_xmitr, etc.); the only observable effect
there would be a one-time handle_sysrq() call if a previous BREAK left
sysrq_ch set -- functionally desirable, but a behaviour change worth
documenting.

I have a tested Option A patch against 6.18.24 (verified the dispatch
fires and produces the SysRq help dump). Happy to send it formally, or
to retarget to Option B if that's the preferred direction.

Thanks,

Jacques


^ permalink raw reply

* [tty:tty-next 28/31] drivers/tty/serial/max310x.c:1727:25: error: use of undeclared identifier 'max310x_spi_driver'; did you mean 'max310x_i2c_driver'?
From: kernel test robot @ 2026-05-12 11:52 UTC (permalink / raw)
  To: Hugo Villeneuve; +Cc: oe-kbuild-all, linux-serial, Greg Kroah-Hartman

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-next
head:   16e95bfb79b5d9d01dc7651d98caf3c2ace331cd
commit: 20ffe4b3330a8bde9e933e9ba2323d5e9386caa5 [28/31] serial: max310x: allow driver to be built with SPI or I2C
config: sparc64-randconfig-r122-20260512 (https://download.01.org/0day-ci/archive/20260512/202605121900.SP8ZoaTw-lkp@intel.com/config)
compiler: clang version 23.0.0git (https://github.com/llvm/llvm-project 5bac06718f502014fade905512f1d26d578a18f3)
sparse: v0.6.5-rc1
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260512/202605121900.SP8ZoaTw-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202605121900.SP8ZoaTw-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/tty/serial/max310x.c:1727:25: error: use of undeclared identifier 'max310x_spi_driver'; did you mean 'max310x_i2c_driver'?
    1727 |         spi_unregister_driver(&max310x_spi_driver);
         |                                ^~~~~~~~~~~~~~~~~~
         |                                max310x_i2c_driver
   drivers/tty/serial/max310x.c:1689:26: note: 'max310x_i2c_driver' declared here
    1689 | static struct i2c_driver max310x_i2c_driver = {
         |                          ^
>> drivers/tty/serial/max310x.c:1727:24: error: incompatible pointer types passing 'struct i2c_driver *' to parameter of type 'struct spi_driver *' [-Wincompatible-pointer-types]
    1727 |         spi_unregister_driver(&max310x_spi_driver);
         |                               ^~~~~~~~~~~~~~~~~~~
   include/linux/spi/spi.h:378:61: note: passing argument to parameter 'sdrv' here
     378 | static inline void spi_unregister_driver(struct spi_driver *sdrv)
         |                                                             ^
   2 errors generated.


vim +1727 drivers/tty/serial/max310x.c

6286767ad3afc88 Alexander Shiyan 2016-06-07  1722  
2e1f2d9a9bdbe12 Cosmin Tanislav  2022-06-05  1723  	return 0;
2e1f2d9a9bdbe12 Cosmin Tanislav  2022-06-05  1724  
2e1f2d9a9bdbe12 Cosmin Tanislav  2022-06-05  1725  #ifdef CONFIG_I2C
2e1f2d9a9bdbe12 Cosmin Tanislav  2022-06-05  1726  err_i2c_register:
2e1f2d9a9bdbe12 Cosmin Tanislav  2022-06-05 @1727  	spi_unregister_driver(&max310x_spi_driver);
2e1f2d9a9bdbe12 Cosmin Tanislav  2022-06-05  1728  #endif
2e1f2d9a9bdbe12 Cosmin Tanislav  2022-06-05  1729  
2e1f2d9a9bdbe12 Cosmin Tanislav  2022-06-05  1730  err_spi_register:
2e1f2d9a9bdbe12 Cosmin Tanislav  2022-06-05  1731  	uart_unregister_driver(&max310x_uart);
2e1f2d9a9bdbe12 Cosmin Tanislav  2022-06-05  1732  
51f689cc1133394 Kangjie Lu       2018-12-25  1733  	return ret;
6286767ad3afc88 Alexander Shiyan 2016-06-07  1734  }
6286767ad3afc88 Alexander Shiyan 2016-06-07  1735  module_init(max310x_uart_init);
6286767ad3afc88 Alexander Shiyan 2016-06-07  1736  

:::::: The code at line 1727 was first introduced by commit
:::::: 2e1f2d9a9bdbe12ee475c82a45ac46a278e8049a serial: max310x: implement I2C support

:::::: TO: Cosmin Tanislav <cosmin.tanislav@analog.com>
:::::: CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* [tty:tty-next 28/31] drivers/tty/serial/max310x.c:1727:32: error: 'max310x_spi_driver' undeclared; did you mean 'max310x_i2c_driver'?
From: kernel test robot @ 2026-05-12 10:59 UTC (permalink / raw)
  To: Hugo Villeneuve; +Cc: oe-kbuild-all, linux-serial, Greg Kroah-Hartman

Hi Hugo,

First bad commit (maybe != root cause):

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-next
head:   16e95bfb79b5d9d01dc7651d98caf3c2ace331cd
commit: 20ffe4b3330a8bde9e933e9ba2323d5e9386caa5 [28/31] serial: max310x: allow driver to be built with SPI or I2C
config: um-randconfig-r112-20260512 (https://download.01.org/0day-ci/archive/20260512/202605121847.N9DVLNg2-lkp@intel.com/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
sparse: v0.6.5-rc1
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260512/202605121847.N9DVLNg2-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202605121847.N9DVLNg2-lkp@intel.com/

All error/warnings (new ones prefixed by >>):

   drivers/tty/serial/max310x.c: In function 'max310x_uart_init':
>> drivers/tty/serial/max310x.c:1727:32: error: 'max310x_spi_driver' undeclared (first use in this function); did you mean 'max310x_i2c_driver'?
    1727 |         spi_unregister_driver(&max310x_spi_driver);
         |                                ^~~~~~~~~~~~~~~~~~
         |                                max310x_i2c_driver
   drivers/tty/serial/max310x.c:1727:32: note: each undeclared identifier is reported only once for each function it appears in
>> drivers/tty/serial/max310x.c:1730:1: warning: label 'err_spi_register' defined but not used [-Wunused-label]
    1730 | err_spi_register:
         | ^~~~~~~~~~~~~~~~
   drivers/tty/serial/max310x.c: At top level:
>> drivers/tty/serial/max310x.c:1492:29: warning: 'regcfg' defined but not used [-Wunused-variable]
    1492 | static struct regmap_config regcfg = {
         |                             ^~~~~~


vim +1727 drivers/tty/serial/max310x.c

6286767ad3afc88 Alexander Shiyan 2016-06-07  1722  
2e1f2d9a9bdbe12 Cosmin Tanislav  2022-06-05  1723  	return 0;
2e1f2d9a9bdbe12 Cosmin Tanislav  2022-06-05  1724  
2e1f2d9a9bdbe12 Cosmin Tanislav  2022-06-05  1725  #ifdef CONFIG_I2C
2e1f2d9a9bdbe12 Cosmin Tanislav  2022-06-05  1726  err_i2c_register:
2e1f2d9a9bdbe12 Cosmin Tanislav  2022-06-05 @1727  	spi_unregister_driver(&max310x_spi_driver);
2e1f2d9a9bdbe12 Cosmin Tanislav  2022-06-05  1728  #endif
2e1f2d9a9bdbe12 Cosmin Tanislav  2022-06-05  1729  
2e1f2d9a9bdbe12 Cosmin Tanislav  2022-06-05 @1730  err_spi_register:
2e1f2d9a9bdbe12 Cosmin Tanislav  2022-06-05  1731  	uart_unregister_driver(&max310x_uart);
2e1f2d9a9bdbe12 Cosmin Tanislav  2022-06-05  1732  
51f689cc1133394 Kangjie Lu       2018-12-25  1733  	return ret;
6286767ad3afc88 Alexander Shiyan 2016-06-07  1734  }
6286767ad3afc88 Alexander Shiyan 2016-06-07  1735  module_init(max310x_uart_init);
6286767ad3afc88 Alexander Shiyan 2016-06-07  1736  

:::::: The code at line 1727 was first introduced by commit
:::::: 2e1f2d9a9bdbe12ee475c82a45ac46a278e8049a serial: max310x: implement I2C support

:::::: TO: Cosmin Tanislav <cosmin.tanislav@analog.com>
:::::: CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* Re: [PATCH tty v5 3/3] serial: 8250: Add support for console flow control
From: John Ogness @ 2026-05-12  9:29 UTC (permalink / raw)
  To: Ilpo Järvinen, Andy Shevchenko
  Cc: Greg Kroah-Hartman, Jiri Slaby, Andy Shevchenko, LKML,
	Ilpo Järvinen, Thomas Gleixner, Ingo Molnar, Kees Cook,
	Osama Abdelkader, Randy Dunlap, Joseph Tilahun,
	Krzysztof Kozlowski, Dr. David Alan Gilbert, linux-serial
In-Reply-To: <f9f408c5-72f5-4be8-7471-e9aee2935a5b@linux.intel.com>

On 2026-05-11, Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> wrote:
>> diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
>> index 4f7bbdd900176..17fcff466e301 100644
>> --- a/include/linux/serial_core.h
>> +++ b/include/linux/serial_core.h
>> @@ -1175,6 +1175,14 @@ static inline bool uart_cons_flow_enabled(const struct uart_port *uport)
>>  	return uport->cons_flow;
>>  }
>>  
>> +static inline bool uart_console_hwflow_active(struct uart_port *uport)
>> +{
>> +	return uart_console(uport) &&
>> +	       !(uport->rs485.flags & SER_RS485_ENABLED) &&
>> +	       uart_cons_flow_enabled(uport) &&
>> +	       uart_cts_enabled(uport);
>> +}
>> +
>>  /*
>>   * The following are helper functions for the low level drivers.
>>   */
>
> Did you miss Andy's comments or choose to not act on them?

You mean these [0]? For the getter, yes. (Although I left the "is_" off
so that it matches other existing flag checking functions.)

For the setter, Andy suggested explicit enable/disable
variants. However, all the users enable/disable based on some
condition. That would mean that there would be a repeated pattern of:

	if (condition)
		uart_cons_flow_enable();
	else
		uart_cons_flow_disable();

So I decided to keep a single setter.

	uart_set_cons_flow_enabled(condition);

I renamed the setter so that it is clearer that only the enabled flag is
being set and not any other special procedures.

John Ogness

[0] https://lore.kernel.org/lkml/CAHp75Vf4YZVqXa7eH-RFeVsycdzoHijcWFnUbGv2PSmtPya1-w@mail.gmail.com

^ permalink raw reply

* Re: [LINUX PATCH] serial: xilinx_uartps: fix runtime PM race during probe
From: Greg Kroah-Hartman @ 2026-05-12  7:38 UTC (permalink / raw)
  To: Shubhrajyoti Datta
  Cc: linux-kernel, git, shubhrajyoti.datta, Jiri Slaby, Michal Simek,
	linux-serial, linux-arm-kernel
In-Reply-To: <176bdb50948e99c40f8baaeaac9ffc5eaf10816f.1778567817.git.shubhrajyoti.datta@amd.com>

On Tue, May 12, 2026 at 12:11:33PM +0530, Shubhrajyoti Datta wrote:
> pm_runtime_enable() was called with usage_count=0, allowing the PM
> core to immediately queue a deferred suspend via pm_runtime_work.
> This raced with console write, causing cdns_runtime_suspend to
> fire before the port was fully registered.
> 
> Hold a reference with pm_runtime_get_noresume() before enabling
> runtime PM.
> 
> Fixes: d62100f1aac2 ("serial: xilinx_uartps: Add pm runtime support")
> Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
> ---
>  drivers/tty/serial/xilinx_uartps.c | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
> index a072b75dbaf2..e316cac4f35b 100644
> --- a/drivers/tty/serial/xilinx_uartps.c
> +++ b/drivers/tty/serial/xilinx_uartps.c
> @@ -1800,6 +1800,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
>  	pm_runtime_use_autosuspend(&pdev->dev);
>  	pm_runtime_set_autosuspend_delay(&pdev->dev, UART_AUTOSUSPEND_TIMEOUT);
>  	pm_runtime_set_active(&pdev->dev);
> +	pm_runtime_get_noresume(&pdev->dev);
>  	pm_runtime_enable(&pdev->dev);
>  	device_init_wakeup(port->dev, true);
>  
> @@ -1824,6 +1825,8 @@ static int cdns_uart_probe(struct platform_device *pdev)
>  			"uart_add_one_port() failed; err=%i\n", rc);
>  		goto err_out_pm_disable;
>  	}
> +	pm_runtime_mark_last_busy(&pdev->dev);
> +	pm_runtime_put_autosuspend(&pdev->dev);
>  
>  #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
>  	/* This is not port which is used for console that's why clean it up */
> @@ -1842,6 +1845,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
>  	return 0;
>  
>  err_out_pm_disable:
> +	pm_runtime_put_noidle(&pdev->dev);
>  	pm_runtime_disable(&pdev->dev);
>  	pm_runtime_set_suspended(&pdev->dev);
>  	pm_runtime_dont_use_autosuspend(&pdev->dev);
> -- 
> 2.49.1
> 

Hi,

This is the friendly patch-bot of Greg Kroah-Hartman.  You have sent him
a patch that has triggered this response.  He used to manually respond
to these common problems, but in order to save his sanity (he kept
writing the same thing over and over, yet to different people), I was
created.  Hopefully you will not take offence and will fix the problem
in your patch and resubmit it so that it can be accepted into the Linux
kernel tree.

You are receiving this message because of the following common error(s)
as indicated below:

- You have marked a patch with a "Fixes:" tag for a commit that is in an
  older released kernel, yet you do not have a cc: stable line in the
  signed-off-by area at all, which means that the patch will not be
  applied to any older kernel releases.  To properly fix this, please
  follow the documented rules in the
  Documentation/process/stable-kernel-rules.rst file for how to resolve
  this.

If you wish to discuss this problem further, or you have questions about
how to resolve this issue, please feel free to respond to this email and
Greg will reply once he has dug out from the pending patches received
from other developers.

thanks,

greg k-h's patch email bot

^ permalink raw reply

* [PATCH v2] serial: altera_jtaguart: handle uart_add_one_port() failures
From: Myeonghun Pak @ 2026-05-12  6:56 UTC (permalink / raw)
  To: Tobias Klauser, Greg Kroah-Hartman, Jiri Slaby
  Cc: Myeonghun Pak, linux-serial, linux-kernel, Ijae Kim

altera_jtaguart_probe() maps the register window before registering the
UART port, but it ignores failures from uart_add_one_port(). If port
registration fails, probe still returns success and the mapping remains
live until a later remove path that is not part of probe failure cleanup.

Return the uart_add_one_port() error and unmap the register window on
that failure path.

This issue was identified during our ongoing static-analysis research while
reviewing kernel code.

Fixes: 5bcd601049c6 ("serial: Add driver for the Altera JTAG UART")
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
---
Changes in v2:
- Drop the unnecessary port->membase = NULL assignment.

 drivers/tty/serial/altera_jtaguart.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/altera_jtaguart.c b/drivers/tty/serial/altera_jtaguart.c
index d47a62d1c9..20f079fe11 100644
--- a/drivers/tty/serial/altera_jtaguart.c
+++ b/drivers/tty/serial/altera_jtaguart.c
@@ -379,6 +379,7 @@ static int altera_jtaguart_probe(struct platform_device *pdev)
 	struct resource *res_mem;
 	int i = pdev->id;
 	int irq;
+	int ret;
 
 	/* -1 emphasizes that the platform must have one port, no .N suffix */
 	if (i == -1)
@@ -418,7 +419,11 @@ static int altera_jtaguart_probe(struct platform_device *pdev)
 	port->flags = UPF_BOOT_AUTOCONF;
 	port->dev = &pdev->dev;
 
-	uart_add_one_port(&altera_jtaguart_driver, port);
+	ret = uart_add_one_port(&altera_jtaguart_driver, port);
+	if (ret) {
+		iounmap(port->membase);
+		return ret;
+	}
 
 	return 0;
 }
-- 
2.47.1


^ permalink raw reply related

* [tty:tty-linus] BUILD SUCCESS 452d6fa37ae9b021f4f6d397dbae077f7296f6f4
From: kernel test robot @ 2026-05-12  6:52 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: linux-serial

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-linus
branch HEAD: 452d6fa37ae9b021f4f6d397dbae077f7296f6f4  serial: qcom_geni: fix kfifo underflow when flush precedes DMA completion IRQ

elapsed time: 932m

configs tested: 231
configs skipped: 18

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha                             allnoconfig    gcc-15.2.0
alpha                            allyesconfig    gcc-15.2.0
alpha                               defconfig    gcc-15.2.0
arc                              allmodconfig    clang-16
arc                               allnoconfig    gcc-15.2.0
arc                              allyesconfig    clang-23
arc                                 defconfig    gcc-15.2.0
arc                   randconfig-001-20260512    gcc-11.5.0
arc                   randconfig-002-20260512    gcc-11.5.0
arm                               allnoconfig    clang-23
arm                               allnoconfig    gcc-15.2.0
arm                              allyesconfig    clang-16
arm                                 defconfig    gcc-15.2.0
arm                          pxa3xx_defconfig    clang-23
arm                   randconfig-001-20260512    gcc-11.5.0
arm                   randconfig-002-20260512    gcc-11.5.0
arm                   randconfig-003-20260512    gcc-11.5.0
arm                   randconfig-004-20260512    gcc-11.5.0
arm64                            allmodconfig    clang-23
arm64                             allnoconfig    gcc-15.2.0
arm64                               defconfig    gcc-15.2.0
arm64                          randconfig-001    clang-23
arm64                 randconfig-001-20260512    clang-23
arm64                 randconfig-001-20260512    gcc-14.3.0
arm64                          randconfig-002    clang-23
arm64                 randconfig-002-20260512    clang-23
arm64                 randconfig-002-20260512    gcc-14.3.0
arm64                          randconfig-003    clang-23
arm64                 randconfig-003-20260512    clang-23
arm64                 randconfig-003-20260512    gcc-14.3.0
arm64                          randconfig-004    clang-23
arm64                 randconfig-004-20260512    clang-23
arm64                 randconfig-004-20260512    gcc-14.3.0
csky                             allmodconfig    gcc-15.2.0
csky                              allnoconfig    gcc-15.2.0
csky                                defconfig    gcc-15.2.0
csky                           randconfig-001    clang-23
csky                  randconfig-001-20260512    clang-23
csky                  randconfig-001-20260512    gcc-14.3.0
csky                           randconfig-002    clang-23
csky                  randconfig-002-20260512    clang-23
csky                  randconfig-002-20260512    gcc-14.3.0
hexagon                          allmodconfig    gcc-15.2.0
hexagon                           allnoconfig    clang-23
hexagon                           allnoconfig    gcc-15.2.0
hexagon                             defconfig    gcc-15.2.0
hexagon               randconfig-001-20260512    gcc-10.5.0
hexagon               randconfig-002-20260512    gcc-10.5.0
i386                             allmodconfig    clang-20
i386                             allmodconfig    gcc-14
i386                              allnoconfig    gcc-14
i386                              allnoconfig    gcc-15.2.0
i386                             allyesconfig    clang-20
i386                             allyesconfig    gcc-14
i386                 buildonly-randconfig-001    gcc-14
i386        buildonly-randconfig-001-20260512    gcc-14
i386                 buildonly-randconfig-002    gcc-14
i386        buildonly-randconfig-002-20260512    gcc-14
i386                 buildonly-randconfig-003    gcc-14
i386        buildonly-randconfig-003-20260512    gcc-14
i386                 buildonly-randconfig-004    gcc-14
i386        buildonly-randconfig-004-20260512    gcc-14
i386                 buildonly-randconfig-005    gcc-14
i386        buildonly-randconfig-005-20260512    gcc-14
i386                 buildonly-randconfig-006    gcc-14
i386        buildonly-randconfig-006-20260512    gcc-14
i386                                defconfig    gcc-15.2.0
i386                  randconfig-001-20260512    gcc-14
i386                  randconfig-002-20260512    gcc-14
i386                  randconfig-003-20260512    gcc-14
i386                  randconfig-004-20260512    gcc-14
i386                  randconfig-005-20260512    gcc-14
i386                  randconfig-006-20260512    gcc-14
i386                  randconfig-007-20260512    gcc-14
i386                  randconfig-011-20260512    clang-20
i386                  randconfig-011-20260512    gcc-14
i386                  randconfig-012-20260512    clang-20
i386                  randconfig-013-20260512    clang-20
i386                  randconfig-014-20260512    clang-20
i386                  randconfig-015-20260512    clang-20
i386                  randconfig-015-20260512    gcc-14
i386                  randconfig-016-20260512    clang-20
i386                  randconfig-016-20260512    gcc-14
i386                  randconfig-017-20260512    clang-20
i386                  randconfig-017-20260512    gcc-14
loongarch                        allmodconfig    clang-23
loongarch                         allnoconfig    clang-23
loongarch                         allnoconfig    gcc-15.2.0
loongarch                           defconfig    clang-19
loongarch             randconfig-001-20260512    gcc-10.5.0
loongarch             randconfig-002-20260512    gcc-10.5.0
m68k                             allmodconfig    gcc-15.2.0
m68k                              allnoconfig    gcc-15.2.0
m68k                             allyesconfig    clang-16
m68k                                defconfig    clang-19
m68k                                defconfig    gcc-15.2.0
m68k                        m5272c3_defconfig    gcc-15.2.0
microblaze                        allnoconfig    gcc-15.2.0
microblaze                       allyesconfig    gcc-15.2.0
microblaze                          defconfig    clang-19
microblaze                          defconfig    gcc-15.2.0
mips                             allmodconfig    gcc-15.2.0
mips                              allnoconfig    gcc-15.2.0
mips                             allyesconfig    gcc-15.2.0
mips                           jazz_defconfig    clang-17
mips                   sb1250_swarm_defconfig    gcc-15.2.0
nios2                            allmodconfig    clang-23
nios2                            allmodconfig    gcc-11.5.0
nios2                             allnoconfig    clang-23
nios2                             allnoconfig    gcc-11.5.0
nios2                               defconfig    clang-19
nios2                               defconfig    gcc-15.2.0
nios2                 randconfig-001-20260512    gcc-10.5.0
nios2                 randconfig-002-20260512    gcc-10.5.0
openrisc                         allmodconfig    clang-23
openrisc                         allmodconfig    gcc-15.2.0
openrisc                          allnoconfig    clang-23
openrisc                          allnoconfig    gcc-15.2.0
openrisc                            defconfig    gcc-15.2.0
parisc                           allmodconfig    gcc-15.2.0
parisc                            allnoconfig    clang-23
parisc                            allnoconfig    gcc-15.2.0
parisc                           allyesconfig    clang-19
parisc                              defconfig    gcc-15.2.0
parisc                randconfig-001-20260512    gcc-12.5.0
parisc                randconfig-002-20260512    gcc-12.5.0
parisc64                            defconfig    clang-19
parisc64                            defconfig    gcc-15.2.0
powerpc                          allmodconfig    gcc-15.2.0
powerpc                           allnoconfig    clang-23
powerpc                           allnoconfig    gcc-15.2.0
powerpc                       holly_defconfig    clang-23
powerpc               randconfig-001-20260512    gcc-12.5.0
powerpc               randconfig-002-20260512    gcc-12.5.0
powerpc64             randconfig-001-20260512    gcc-12.5.0
powerpc64             randconfig-002-20260512    gcc-12.5.0
riscv                            allmodconfig    clang-23
riscv                             allnoconfig    clang-23
riscv                             allnoconfig    gcc-15.2.0
riscv                            allyesconfig    clang-16
riscv                               defconfig    gcc-15.2.0
riscv                          randconfig-001    gcc-15.2.0
riscv                 randconfig-001-20260512    gcc-15.2.0
riscv                          randconfig-002    gcc-15.2.0
riscv                 randconfig-002-20260512    gcc-15.2.0
s390                             allmodconfig    clang-19
s390                              allnoconfig    clang-23
s390                             allyesconfig    gcc-15.2.0
s390                                defconfig    gcc-15.2.0
s390                           randconfig-001    gcc-15.2.0
s390                  randconfig-001-20260512    gcc-15.2.0
s390                           randconfig-002    gcc-15.2.0
s390                  randconfig-002-20260512    gcc-15.2.0
sh                               allmodconfig    gcc-15.2.0
sh                                allnoconfig    clang-23
sh                                allnoconfig    gcc-15.2.0
sh                               allyesconfig    clang-19
sh                                  defconfig    gcc-14
sh                             randconfig-001    gcc-15.2.0
sh                    randconfig-001-20260512    gcc-15.2.0
sh                             randconfig-002    gcc-15.2.0
sh                    randconfig-002-20260512    gcc-15.2.0
sparc                             allnoconfig    clang-23
sparc                             allnoconfig    gcc-15.2.0
sparc                               defconfig    gcc-15.2.0
sparc                          randconfig-001    gcc-13.4.0
sparc                 randconfig-001-20260512    gcc-13.4.0
sparc                          randconfig-002    gcc-13.4.0
sparc                 randconfig-002-20260512    gcc-13.4.0
sparc64                          allmodconfig    clang-23
sparc64                             defconfig    gcc-14
sparc64                        randconfig-001    gcc-13.4.0
sparc64               randconfig-001-20260512    gcc-13.4.0
sparc64                        randconfig-002    gcc-13.4.0
sparc64               randconfig-002-20260512    gcc-13.4.0
um                               allmodconfig    clang-19
um                                allnoconfig    clang-23
um                               allyesconfig    gcc-15.2.0
um                                  defconfig    gcc-14
um                             i386_defconfig    gcc-14
um                             randconfig-001    gcc-13.4.0
um                    randconfig-001-20260512    gcc-13.4.0
um                             randconfig-002    gcc-13.4.0
um                    randconfig-002-20260512    gcc-13.4.0
um                           x86_64_defconfig    gcc-14
x86_64                           allmodconfig    clang-20
x86_64                            allnoconfig    clang-20
x86_64                            allnoconfig    clang-23
x86_64                           allyesconfig    clang-20
x86_64      buildonly-randconfig-001-20260512    gcc-14
x86_64      buildonly-randconfig-002-20260512    gcc-14
x86_64      buildonly-randconfig-003-20260512    gcc-14
x86_64      buildonly-randconfig-004-20260512    gcc-14
x86_64      buildonly-randconfig-005-20260512    gcc-14
x86_64      buildonly-randconfig-006-20260512    gcc-14
x86_64                              defconfig    gcc-14
x86_64                                  kexec    clang-20
x86_64                randconfig-001-20260512    gcc-14
x86_64                randconfig-002-20260512    gcc-14
x86_64                randconfig-003-20260512    gcc-14
x86_64                randconfig-004-20260512    gcc-14
x86_64                randconfig-005-20260512    gcc-14
x86_64                randconfig-006-20260512    gcc-14
x86_64                randconfig-011-20260512    clang-20
x86_64                randconfig-012-20260512    clang-20
x86_64                randconfig-013-20260512    clang-20
x86_64                randconfig-014-20260512    clang-20
x86_64                randconfig-015-20260512    clang-20
x86_64                randconfig-016-20260512    clang-20
x86_64                randconfig-071-20260512    clang-20
x86_64                randconfig-071-20260512    gcc-14
x86_64                randconfig-072-20260512    clang-20
x86_64                randconfig-073-20260512    clang-20
x86_64                randconfig-074-20260512    clang-20
x86_64                randconfig-074-20260512    gcc-14
x86_64                randconfig-075-20260512    clang-20
x86_64                randconfig-076-20260512    clang-20
x86_64                               rhel-9.4    clang-20
x86_64                           rhel-9.4-bpf    gcc-14
x86_64                          rhel-9.4-func    clang-20
x86_64                    rhel-9.4-kselftests    clang-20
x86_64                         rhel-9.4-kunit    gcc-14
x86_64                           rhel-9.4-ltp    gcc-14
x86_64                          rhel-9.4-rust    clang-20
xtensa                            allnoconfig    clang-23
xtensa                            allnoconfig    gcc-15.2.0
xtensa                           allyesconfig    clang-23
xtensa                         randconfig-001    gcc-13.4.0
xtensa                randconfig-001-20260512    gcc-13.4.0
xtensa                         randconfig-002    gcc-13.4.0
xtensa                randconfig-002-20260512    gcc-13.4.0

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* [LINUX PATCH] serial: xilinx_uartps: fix runtime PM race during probe
From: Shubhrajyoti Datta @ 2026-05-12  6:41 UTC (permalink / raw)
  To: linux-kernel
  Cc: git, shubhrajyoti.datta, Greg Kroah-Hartman, Jiri Slaby,
	Michal Simek, Shubhrajyoti Datta, linux-serial, linux-arm-kernel

pm_runtime_enable() was called with usage_count=0, allowing the PM
core to immediately queue a deferred suspend via pm_runtime_work.
This raced with console write, causing cdns_runtime_suspend to
fire before the port was fully registered.

Hold a reference with pm_runtime_get_noresume() before enabling
runtime PM.

Fixes: d62100f1aac2 ("serial: xilinx_uartps: Add pm runtime support")
Signed-off-by: Shubhrajyoti Datta <shubhrajyoti.datta@amd.com>
---
 drivers/tty/serial/xilinx_uartps.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c
index a072b75dbaf2..e316cac4f35b 100644
--- a/drivers/tty/serial/xilinx_uartps.c
+++ b/drivers/tty/serial/xilinx_uartps.c
@@ -1800,6 +1800,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
 	pm_runtime_use_autosuspend(&pdev->dev);
 	pm_runtime_set_autosuspend_delay(&pdev->dev, UART_AUTOSUSPEND_TIMEOUT);
 	pm_runtime_set_active(&pdev->dev);
+	pm_runtime_get_noresume(&pdev->dev);
 	pm_runtime_enable(&pdev->dev);
 	device_init_wakeup(port->dev, true);
 
@@ -1824,6 +1825,8 @@ static int cdns_uart_probe(struct platform_device *pdev)
 			"uart_add_one_port() failed; err=%i\n", rc);
 		goto err_out_pm_disable;
 	}
+	pm_runtime_mark_last_busy(&pdev->dev);
+	pm_runtime_put_autosuspend(&pdev->dev);
 
 #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
 	/* This is not port which is used for console that's why clean it up */
@@ -1842,6 +1845,7 @@ static int cdns_uart_probe(struct platform_device *pdev)
 	return 0;
 
 err_out_pm_disable:
+	pm_runtime_put_noidle(&pdev->dev);
 	pm_runtime_disable(&pdev->dev);
 	pm_runtime_set_suspended(&pdev->dev);
 	pm_runtime_dont_use_autosuspend(&pdev->dev);
-- 
2.49.1


^ permalink raw reply related

* [tty:tty-testing] BUILD SUCCESS 16e95bfb79b5d9d01dc7651d98caf3c2ace331cd
From: kernel test robot @ 2026-05-12  4:09 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: linux-serial

tree/branch: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-testing
branch HEAD: 16e95bfb79b5d9d01dc7651d98caf3c2ace331cd  serial: qcom-geni: Avoid probing debug console UART without console support

elapsed time: 738m

configs tested: 145
configs skipped: 2

The following configs have been built successfully.
More configs may be tested in the coming days.

tested configs:
alpha                             allnoconfig    gcc-15.2.0
alpha                            allyesconfig    gcc-15.2.0
arc                              allmodconfig    clang-16
arc                              allmodconfig    gcc-15.2.0
arc                               allnoconfig    gcc-15.2.0
arc                              allyesconfig    gcc-15.2.0
arc                   randconfig-001-20260512    gcc-11.5.0
arc                   randconfig-001-20260512    gcc-8.5.0
arc                   randconfig-002-20260512    gcc-11.5.0
arc                   randconfig-002-20260512    gcc-8.5.0
arm                               allnoconfig    clang-23
arm                               allnoconfig    gcc-15.2.0
arm                              allyesconfig    clang-16
arm                              allyesconfig    gcc-15.2.0
arm                   randconfig-001-20260512    clang-23
arm                   randconfig-001-20260512    gcc-11.5.0
arm                   randconfig-002-20260512    gcc-11.5.0
arm                   randconfig-003-20260512    clang-23
arm                   randconfig-003-20260512    gcc-11.5.0
arm                   randconfig-004-20260512    gcc-11.5.0
arm                   randconfig-004-20260512    gcc-8.5.0
arm64                            allmodconfig    clang-19
arm64                             allnoconfig    gcc-15.2.0
csky                             allmodconfig    gcc-15.2.0
csky                              allnoconfig    gcc-15.2.0
hexagon                          allmodconfig    clang-17
hexagon                          allmodconfig    gcc-15.2.0
hexagon                           allnoconfig    clang-23
hexagon                           allnoconfig    gcc-15.2.0
hexagon               randconfig-001-20260512    clang-23
hexagon               randconfig-002-20260512    clang-23
i386                             allmodconfig    gcc-14
i386                              allnoconfig    gcc-14
i386                              allnoconfig    gcc-15.2.0
i386                             allyesconfig    gcc-14
i386        buildonly-randconfig-001-20260512    gcc-14
i386        buildonly-randconfig-002-20260512    gcc-14
i386        buildonly-randconfig-003-20260512    gcc-14
i386        buildonly-randconfig-004-20260512    clang-20
i386        buildonly-randconfig-005-20260512    clang-20
i386        buildonly-randconfig-006-20260512    clang-20
i386                  randconfig-011-20260512    clang-20
i386                  randconfig-012-20260512    clang-20
i386                  randconfig-013-20260512    clang-20
i386                  randconfig-014-20260512    clang-20
i386                  randconfig-015-20260512    clang-20
i386                  randconfig-016-20260512    clang-20
i386                  randconfig-017-20260512    clang-20
loongarch                        allmodconfig    clang-19
loongarch                         allnoconfig    clang-23
loongarch                         allnoconfig    gcc-15.2.0
loongarch                           defconfig    clang-19
loongarch             randconfig-001-20260512    clang-18
loongarch             randconfig-002-20260512    gcc-15.2.0
m68k                             allmodconfig    gcc-15.2.0
m68k                              allnoconfig    gcc-15.2.0
m68k                             allyesconfig    clang-16
m68k                             allyesconfig    gcc-15.2.0
m68k                                defconfig    gcc-15.2.0
m68k                        m5272c3_defconfig    gcc-15.2.0
microblaze                        allnoconfig    gcc-15.2.0
microblaze                       allyesconfig    gcc-15.2.0
microblaze                          defconfig    gcc-15.2.0
mips                             allmodconfig    gcc-15.2.0
mips                              allnoconfig    gcc-15.2.0
mips                             allyesconfig    gcc-15.2.0
mips                           jazz_defconfig    clang-17
nios2                            allmodconfig    clang-23
nios2                            allmodconfig    gcc-11.5.0
nios2                             allnoconfig    clang-23
nios2                             allnoconfig    gcc-11.5.0
nios2                               defconfig    gcc-11.5.0
nios2                 randconfig-001-20260512    gcc-11.5.0
nios2                 randconfig-002-20260512    gcc-10.5.0
openrisc                         allmodconfig    clang-23
openrisc                         allmodconfig    gcc-15.2.0
openrisc                          allnoconfig    clang-23
openrisc                          allnoconfig    gcc-15.2.0
openrisc                            defconfig    gcc-15.2.0
parisc                           allmodconfig    gcc-15.2.0
parisc                            allnoconfig    clang-23
parisc                            allnoconfig    gcc-15.2.0
parisc                           allyesconfig    gcc-15.2.0
parisc                              defconfig    gcc-15.2.0
parisc                randconfig-001-20260512    gcc-11.5.0
parisc                randconfig-001-20260512    gcc-12.5.0
parisc                randconfig-002-20260512    gcc-12.5.0
parisc                randconfig-002-20260512    gcc-9.5.0
parisc64                            defconfig    gcc-15.2.0
powerpc                          allmodconfig    gcc-15.2.0
powerpc                           allnoconfig    clang-23
powerpc                           allnoconfig    gcc-15.2.0
powerpc                       holly_defconfig    clang-23
powerpc               randconfig-001-20260512    clang-23
powerpc               randconfig-001-20260512    gcc-12.5.0
powerpc               randconfig-002-20260512    gcc-12.5.0
powerpc64             randconfig-001-20260512    clang-17
powerpc64             randconfig-001-20260512    gcc-12.5.0
powerpc64             randconfig-002-20260512    clang-23
powerpc64             randconfig-002-20260512    gcc-12.5.0
riscv                            allmodconfig    clang-23
riscv                             allnoconfig    clang-23
riscv                             allnoconfig    gcc-15.2.0
riscv                            allyesconfig    clang-16
s390                             allmodconfig    clang-18
s390                              allnoconfig    clang-23
s390                             allyesconfig    gcc-15.2.0
sh                               allmodconfig    gcc-15.2.0
sh                                allnoconfig    clang-23
sh                                allnoconfig    gcc-15.2.0
sh                               allyesconfig    gcc-15.2.0
sh                                  defconfig    gcc-14
sparc                             allnoconfig    clang-23
sparc                             allnoconfig    gcc-15.2.0
sparc                               defconfig    gcc-15.2.0
sparc64                          allmodconfig    clang-23
sparc64                             defconfig    gcc-14
um                               allmodconfig    clang-19
um                                allnoconfig    clang-23
um                               allyesconfig    gcc-14
um                               allyesconfig    gcc-15.2.0
um                                  defconfig    gcc-14
um                             i386_defconfig    gcc-14
um                           x86_64_defconfig    gcc-14
x86_64                           allmodconfig    clang-20
x86_64                            allnoconfig    clang-20
x86_64                            allnoconfig    clang-23
x86_64                           allyesconfig    clang-20
x86_64                              defconfig    gcc-14
x86_64                                  kexec    clang-20
x86_64                randconfig-071-20260512    clang-20
x86_64                randconfig-072-20260512    clang-20
x86_64                randconfig-073-20260512    clang-20
x86_64                randconfig-074-20260512    clang-20
x86_64                randconfig-075-20260512    clang-20
x86_64                randconfig-076-20260512    clang-20
x86_64                               rhel-9.4    clang-20
x86_64                          rhel-9.4-func    clang-20
x86_64                    rhel-9.4-kselftests    clang-20
x86_64                          rhel-9.4-rust    clang-20
xtensa                            allnoconfig    clang-23
xtensa                            allnoconfig    gcc-15.2.0
xtensa                           allyesconfig    clang-23
xtensa                           allyesconfig    gcc-15.2.0
xtensa                randconfig-001-20260512    gcc-8.5.0

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply

* [PATCH v2] tty: serial: atmel: Ignore chars when CREAD is cleared
From: Rakesh Alasyam @ 2026-05-11 16:59 UTC (permalink / raw)
  To: gregkh
  Cc: richard.genoud, jirislaby, nicolas.ferre, alexandre.belloni,
	claudiu.beznea, linux-serial, linux-kernel, linux-arm-kernel,
	Rakesh Alasyam
In-Reply-To: <2026051106-obliged-dismount-d85f@gregkh>

Ignore received characters when CREAD is cleared by adding RXRDY
to ignore_status_mask.

This replaces an existing TODO in the driver.

Tested on hardware.

Signed-off-by: Rakesh Alasyam <alasyamrakesh77@gmail.com>

---

v2:
- Add blank line before comment
- Tested on hardware
---
 drivers/tty/serial/atmel_serial.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
index 5d8c1cfc1c60..5c756dc904b0 100644
--- a/drivers/tty/serial/atmel_serial.c
+++ b/drivers/tty/serial/atmel_serial.c
@@ -2184,7 +2184,8 @@ static void atmel_set_termios(struct uart_port *port,
 		if (termios->c_iflag & IGNPAR)
 			port->ignore_status_mask |= ATMEL_US_OVRE;
 	}
-	/* TODO: Ignore all characters if CREAD is set.*/
+	if (!(termios->c_cflag & CREAD))
+		port->ignore_status_mask |= ATMEL_US_RXRDY;
 
 	/* update the per-port timeout */
 	uart_update_timeout(port, termios->c_cflag, baud);
-- 
2.43.0


^ permalink raw reply related

* Re: [PATCH] tty: serial: atmel: Ignore chars when CREAD is cleared
From: Greg KH @ 2026-05-11 16:54 UTC (permalink / raw)
  To: Rakesh Alasyam
  Cc: richard.genoud, jirislaby, nicolas.ferre, alexandre.belloni,
	claudiu.beznea, linux-serial, linux-kernel, linux-arm-kernel
In-Reply-To: <20260511155655.26435-1-alasyamrakesh77@gmail.com>

On Mon, May 11, 2026 at 09:26:55PM +0530, Rakesh Alasyam wrote:
> Ignore received characters when CREAD is cleared by adding RXRDY
> to ignore_status_mask.
> 
> This replaces an existing TODO in the driver.
> 
> Tested on hardware.
> 
> Signed-off-by: Rakesh Alasyam <alasyamrakesh77@gmail.com>
> 
> ---
> 
> v2:
> - Add blank line before comment
> - Tested on hardware
> ---
>  drivers/tty/serial/atmel_serial.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
> index 5d8c1cfc1c60..5c756dc904b0 100644
> --- a/drivers/tty/serial/atmel_serial.c
> +++ b/drivers/tty/serial/atmel_serial.c
> @@ -2184,7 +2184,8 @@ static void atmel_set_termios(struct uart_port *port,
>  		if (termios->c_iflag & IGNPAR)
>  			port->ignore_status_mask |= ATMEL_US_OVRE;
>  	}
> -	/* TODO: Ignore all characters if CREAD is set.*/
> +	if (!(termios->c_cflag & CREAD))
> +		port->ignore_status_mask |= ATMEL_US_RXRDY;
>  
>  	/* update the per-port timeout */
>  	uart_update_timeout(port, termios->c_cflag, baud);
> -- 
> 2.43.0
> 

No v2 in the subject line :(

^ permalink raw reply

* Re: [PATCH tty v5 3/3] serial: 8250: Add support for console flow control
From: Ilpo Järvinen @ 2026-05-11 16:07 UTC (permalink / raw)
  To: John Ogness, Andy Shevchenko
  Cc: Greg Kroah-Hartman, Jiri Slaby, Andy Shevchenko, LKML,
	Ilpo Järvinen, Thomas Gleixner, Ingo Molnar, Kees Cook,
	Osama Abdelkader, Randy Dunlap, Joseph Tilahun,
	Krzysztof Kozlowski, Dr. David Alan Gilbert, linux-serial
In-Reply-To: <20260511152706.151498-4-john.ogness@linutronix.de>

On Mon, 11 May 2026, John Ogness wrote:

> The kernel documentation specifies that the console option 'r' can
> be used to enable hardware flow control for console writes. The 8250
> driver does include code for hardware flow control on the console if
> cons_flow is set, but there is no code path that actually sets this.
> However, that is not the only issue. The problems are:
> 
> 1. Specifying the console option 'r' does not lead to cons_flow being
>    set.
> 
> 2. Even if cons_flow would be set, serial8250_register_8250_port()
>    clears it.
> 
> 3. When the console option 'r' is specified, uart_set_options()
>    attempts to initialize the port for CRTSCTS. However, afterwards
>    it does not set the UPSTAT_CTS_ENABLE status bit and therefore on
>    boot, uart_cts_enabled() is always false. This policy bit is
>    important for console drivers as a criteria if they may poll CTS.
> 
> 4. Even though uart_set_options() attempts to initialize the port
>    for CRTSCTS, the 8250 set_termios() callback does not enable the
>    RTS signal (TIOCM_RTS) and thus the hardware is not properly
>    initialized for CTS polling.
> 
> 5. Even if modem control was properly setup for CTS polling
>    (TIOCM_RTS), uart_configure_port() clears TIOCM_RTS, thus
>    breaking CTS polling.
> 
> 6. wait_for_xmitr() and serial8250_console_write() use cons_flow
>    to decide if CTS polling should occur. However, the condition
>    should also include a check that it is not in RS485 mode and
>    CRTSCTS is actually enabled in the hardware.
> 
> Address all these issues as conservatively as possible by gating them
> behind checks focussed on the user specifying console hardware flow
> control support and the hardware being configured for CTS polling
> at the time of the write to the UART.
> 
> Since checking the UPSTAT_CTS_ENABLE status bit is a part of the new
> condition gate, these changes also support runtime termios updates to
> disable/enable CRTSCTS.
> 
> Signed-off-by: John Ogness <john.ogness@linutronix.de>
> ---
>  drivers/tty/serial/8250/8250_core.c |  6 +++++-
>  drivers/tty/serial/8250/8250_port.c | 13 +++++++++++--
>  drivers/tty/serial/serial_core.c    | 21 ++++++++++++++++++++-
>  include/linux/serial_core.h         |  8 ++++++++
>  4 files changed, 44 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
> index b0275204e1167..1f03da85e3414 100644
> --- a/drivers/tty/serial/8250/8250_core.c
> +++ b/drivers/tty/serial/8250/8250_core.c
> @@ -693,6 +693,7 @@ static void serial_8250_overrun_backoff_work(struct work_struct *work)
>  int serial8250_register_8250_port(const struct uart_8250_port *up)
>  {
>  	struct uart_8250_port *uart;
> +	bool cons_flow;
>  	int ret;
>  
>  	if (up->port.uartclk == 0)
> @@ -716,6 +717,9 @@ int serial8250_register_8250_port(const struct uart_8250_port *up)
>  	if (uart->port.type == PORT_8250_CIR)
>  		return -ENODEV;
>  
> +	/* Preserve specified console flow control. */
> +	cons_flow = uart_cons_flow_enabled(&uart->port);
> +
>  	if (uart->port.dev)
>  		uart_remove_one_port(&serial8250_reg, &uart->port);
>  
> @@ -746,7 +750,7 @@ int serial8250_register_8250_port(const struct uart_8250_port *up)
>  	uart->lsr_save_mask	= up->lsr_save_mask;
>  	uart->dma		= up->dma;
>  
> -	uart_set_cons_flow_enabled(&uart->port, uart_cons_flow_enabled(&up->port));
> +	uart_set_cons_flow_enabled(&uart->port, uart_cons_flow_enabled(&up->port) | cons_flow);
>  
>  	/* Take tx_loadsz from fifosize if it wasn't set separately */
>  	if (uart->port.fifosize && !uart->tx_loadsz)
> diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
> index fe2e0f1e66c21..ef245114105bc 100644
> --- a/drivers/tty/serial/8250/8250_port.c
> +++ b/drivers/tty/serial/8250/8250_port.c
> @@ -1991,7 +1991,7 @@ static void wait_for_xmitr(struct uart_8250_port *up, int bits)
>  	tx_ready = wait_for_lsr(up, bits);
>  
>  	/* Wait up to 1s for flow control if necessary */
> -	if (uart_cons_flow_enabled(&up->port)) {
> +	if (uart_console_hwflow_active(&up->port)) {
>  		for (tmout = 1000000; tmout; tmout--) {
>  			unsigned int msr = serial_in(up, UART_MSR);
>  			up->msr_saved_flags |= msr & MSR_SAVE_FLAGS;
> @@ -2788,6 +2788,12 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
>  		serial8250_set_efr(port, termios);
>  		serial8250_set_divisor(port, baud, quot, frac);
>  		serial8250_set_fcr(port, termios);
> +		/* Consoles manually poll CTS for hardware flow control. */
> +		if (uart_console(port) &&
> +		    !(port->rs485.flags & SER_RS485_ENABLED)
> +		    && termios->c_cflag & CRTSCTS) {
> +			port->mctrl |= TIOCM_RTS;
> +		}
>  		serial8250_set_mctrl(port, port->mctrl);
>  	}
>  
> @@ -3357,7 +3363,7 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s,
>  		 * it regardless of the CTS state. Therefore, only use fifo
>  		 * if we don't use control flow.
>  		 */
> -		!uart_cons_flow_enabled(&up->port);
> +		!uart_console_hwflow_active(&up->port);
>  
>  	if (likely(use_fifo))
>  		serial8250_console_fifo_write(up, s, count);
> @@ -3427,6 +3433,9 @@ int serial8250_console_setup(struct uart_port *port, char *options, bool probe)
>  	if (ret)
>  		return ret;
>  
> +	/* Track user-specified console flow control. */
> +	uart_set_cons_flow_enabled(port, flow == 'r');
> +
>  	if (port->dev)
>  		pm_runtime_get_sync(port->dev);
>  
> diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
> index 89cebdd278410..840336f95c5f6 100644
> --- a/drivers/tty/serial/serial_core.c
> +++ b/drivers/tty/serial/serial_core.c
> @@ -2235,6 +2235,18 @@ uart_set_options(struct uart_port *port, struct console *co,
>  	port->mctrl |= TIOCM_DTR;
>  
>  	port->ops->set_termios(port, &termios, &dummy);
> +
> +	/*
> +	 * If console hardware flow control was specified and is supported,
> +	 * the related policy UPSTAT_CTS_ENABLE must be set to allow console
> +	 * drivers to identify if CTS should be used for polling.
> +	 */
> +	if (flow == 'r' && (termios.c_cflag & CRTSCTS)) {
> +		/* Synchronize @status RMW update against the console. */
> +		guard(uart_port_lock_irqsave)(port);
> +		port->status |= UPSTAT_CTS_ENABLE;
> +	}
> +
>  	/*
>  	 * Allow the setting of the UART parameters with a NULL console
>  	 * too:
> @@ -2541,7 +2553,14 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state,
>  		 * We probably don't need a spinlock around this, but
>  		 */
>  		scoped_guard(uart_port_lock_irqsave, port) {
> -			port->mctrl &= TIOCM_DTR;
> +			unsigned int mask = TIOCM_DTR;
> +
> +			/* Console hardware flow control polls CTS. */
> +			if (uart_console_hwflow_active(port))
> +				mask |= TIOCM_RTS;
> +
> +			port->mctrl &= mask;
> +
>  			if (!(port->rs485.flags & SER_RS485_ENABLED))
>  				port->ops->set_mctrl(port, port->mctrl);
>  		}
> diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
> index 4f7bbdd900176..17fcff466e301 100644
> --- a/include/linux/serial_core.h
> +++ b/include/linux/serial_core.h
> @@ -1175,6 +1175,14 @@ static inline bool uart_cons_flow_enabled(const struct uart_port *uport)
>  	return uport->cons_flow;
>  }
>  
> +static inline bool uart_console_hwflow_active(struct uart_port *uport)
> +{
> +	return uart_console(uport) &&
> +	       !(uport->rs485.flags & SER_RS485_ENABLED) &&
> +	       uart_cons_flow_enabled(uport) &&
> +	       uart_cts_enabled(uport);
> +}
> +
>  /*
>   * The following are helper functions for the low level drivers.
>   */
> 

Hi,

Did you miss Andy's comments or choose to not act on them?

-- 
 i.


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox