* 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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox