* [PATCH 0/2] Add trace event support for GENI SE registers dump
@ 2026-07-06 11:08 Praveen Talari
2026-07-06 11:08 ` [PATCH 1/2] soc: qcom: geni-se: trace: " Praveen Talari
2026-07-06 11:08 ` [PATCH 2/2] spi: qcom-geni: add GENI SE registers trace event on error paths Praveen Talari
0 siblings, 2 replies; 6+ messages in thread
From: Praveen Talari @ 2026-07-06 11:08 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Steven Rostedt, Masami Hiramatsu,
Mathieu Desnoyers, Mark Brown
Cc: linux-kernel, linux-arm-msm, linux-trace-kernel, linux-spi,
Mukesh Kumar Savaliya, aniket.randive, chandana.chiluveru,
Praveen Talari
The GENI framework is used by multiple drivers including UART, I2C, and
SPI. When hardware-related failures occur, each driver typically relies
on local logging, which often lacks sufficient information to determine
the exact controller state.
This series introduces a common tracing mechanism for GENI Serial Engine
debug registers and demonstrates its use in the SPI driver.
Patch 1 adds a new tracepoint that captures an extensive set of GENI SE
registers, including command state, interrupt status, FIFO state, DMA
configuration, and clock-related information.
Patch 2 hooks the tracepoint into SPI error paths so that register
snapshots are automatically generated when timeouts or transfer-related
failures occur.
Usage examples:
Enable all I2C traces:
echo 1 > /sys/kernel/tracing/events/qcom_geni_se/enable
cat /sys/kernel/debug/tracing/trace_pipe
Example trace output:
114.291299: geni_se_regs: 888000.spi: m_cmd0=0x18000000
m_irq_status=0x00000080 s_cmd0=0x00000000 s_irq_status=0x08000000
geni_status=0x00000000 geni_ios=0x00000000 m_cmd_ctrl=0x00000000
m_cmd_err=0x00000000 m_fw_err=0x00000000 tx_fifo_sts=0x00000000
rx_fifo_sts=0x00000000 tx_watermark=0x00000000 rx_watermark=0x0000000d
rx_watermark_rfr=0x0000000e m_gp_length=0x00000004 s_gp_length=0x00000000
dma_tx_irq=0x00000000 dma_rx_irq=0x00000000 dma_tx_irq_en=0x0000000f
dma_rx_irq_en=0x0000001f dma_rx_len=0x00001400 dma_rx_len_in=0x00001400
dma_tx_len=0x00001400 dma_tx_len_in=0x00001400 dma_tx_ptr_l=0xffffc000
dma_tx_ptr_h=0x00000000 dma_rx_ptr_l=0xffffa000 dma_rx_ptr_h=0x00000000
dma_tx_attr=0x00000001 dma_tx_max_burst=0x00000002 dma_rx_attr=0x00000000
dma_rx_max_burst=0x00000002 dma_if_en=0x00000009 dma_if_en_ro=0x00000001
dma_general_cfg=0x0000000f dma_qsb_trans_cfg=0x00000000 dma_dbg=0x00000000
m_irq_en=0x7fc0007f s_irq_en=0x03003e3e gsi_event_en=0x00000000
se_irq_en=0x0000000f ser_m_clk_cfg=0x000000a1 ser_s_clk_cfg=0x00000000
general_cfg=0x00000048 output_ctrl=0x0000007f clk_ctrl_ro=0x00000001
fifo_if_dis=0x00000000 fw_multilock_msa=0x00000000 clk_sel=0x00000005
Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
Praveen Talari (2):
soc: qcom: geni-se: trace: Add trace event support for GENI SE registers dump
spi: qcom-geni: add GENI SE registers trace event on error paths
drivers/spi/spi-geni-qcom.c | 22 ++++-
include/linux/soc/qcom/geni-se.h | 38 +++++++++
include/trace/events/qcom_geni_se.h | 157 ++++++++++++++++++++++++++++++++++++
3 files changed, 213 insertions(+), 4 deletions(-)
---
base-commit: 7de6ae9e12207ec146f2f3f1e58d1a99317e88bc
change-id: 20260630-add-tracepoints-for-se-reg-dump-c2c8bc875658
Best regards,
--
Praveen Talari <praveen.talari@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/2] soc: qcom: geni-se: trace: Add trace event support for GENI SE registers dump
2026-07-06 11:08 [PATCH 0/2] Add trace event support for GENI SE registers dump Praveen Talari
@ 2026-07-06 11:08 ` Praveen Talari
2026-07-06 14:59 ` Steven Rostedt
2026-07-06 11:08 ` [PATCH 2/2] spi: qcom-geni: add GENI SE registers trace event on error paths Praveen Talari
1 sibling, 1 reply; 6+ messages in thread
From: Praveen Talari @ 2026-07-06 11:08 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Steven Rostedt, Masami Hiramatsu,
Mathieu Desnoyers, Mark Brown
Cc: linux-kernel, linux-arm-msm, linux-trace-kernel, linux-spi,
Mukesh Kumar Savaliya, aniket.randive, chandana.chiluveru,
Praveen Talari
Add a new trace event header for the Qualcomm GENI Serial Engine (SE)
framework providing a geni_se_regs tracepoint. This tracepoint
captures a comprehensive snapshot of the GENI SE hardware state in a
single trace record, making it possible to correlate register values at
a precise point in time without multiple sequential reads.
The trace event records the following register groups:
- Main/secondary command and IRQ status (M_CMD0, S_CMD0, M/S_IRQ_STATUS)
- Engine status, IOS, and command control/error registers
- TX/RX FIFO status and watermark registers (including RFR watermark)
- M/S GP length registers
- DMA TX/RX IRQ, enable, length, pointer, attribute, and burst registers
- DMA interface enable, general config, QSB trans config, and debug
- M/S IRQ enable, GSI event enable, and top-level SE IRQ enable
- Serial master/slave clock config, general config, output control,
clock control RO, FIFO interface disable, and FW multilock MSA
- Clock select register
Having all these registers captured atomically in a single ftrace record
allows drivers built on top of the GENI SE framework (serial, SPI, I2C)
to invoke this tracepoint on error paths and reconstruct the full engine
state during post-mortem analysis without instrumenting each driver
separately.
Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
include/linux/soc/qcom/geni-se.h | 38 +++++++++
include/trace/events/qcom_geni_se.h | 157 ++++++++++++++++++++++++++++++++++++
2 files changed, 195 insertions(+)
diff --git a/include/linux/soc/qcom/geni-se.h b/include/linux/soc/qcom/geni-se.h
index c5e6ab85df09..58c84b5fb3c2 100644
--- a/include/linux/soc/qcom/geni-se.h
+++ b/include/linux/soc/qcom/geni-se.h
@@ -81,13 +81,17 @@ struct geni_se {
};
/* Common SE registers */
+#define SE_DMA_IF_EN 0x4
+#define GENI_GENERAL_CFG 0x10
#define GENI_FORCE_DEFAULT_REG 0x20
#define GENI_OUTPUT_CTRL 0x24
#define SE_GENI_STATUS 0x40
#define GENI_SER_M_CLK_CFG 0x48
#define GENI_SER_S_CLK_CFG 0x4c
+#define GENI_CLK_CTRL_RO 0x60
#define GENI_IF_DISABLE_RO 0x64
#define GENI_FW_REVISION_RO 0x68
+#define GENI_FW_MULTILOCK_MSA_RO 0x74
#define SE_GENI_CLK_SEL 0x7c
#define SE_GENI_CFG_SEQ_START 0x84
#define SE_GENI_DMA_MODE_EN 0x258
@@ -98,6 +102,8 @@ struct geni_se {
#define SE_GENI_M_IRQ_CLEAR 0x618
#define SE_GENI_M_IRQ_EN_SET 0x61c
#define SE_GENI_M_IRQ_EN_CLEAR 0x620
+#define M_CMD_ERR_STATUS 0x624
+#define M_FW_ERR_STATUS 0x628
#define SE_GENI_S_CMD0 0x630
#define SE_GENI_S_CMD_CTRL_REG 0x634
#define SE_GENI_S_IRQ_STATUS 0x640
@@ -115,15 +121,41 @@ struct geni_se {
#define SE_GENI_IOS 0x908
#define SE_GENI_M_GP_LENGTH 0x910
#define SE_GENI_S_GP_LENGTH 0x914
+/* TX DMA registers */
+#define SE_DMA_TX_PTR_L 0xc30
+#define SE_DMA_TX_PTR_H 0xc34
+#define SE_DMA_TX_ATTR 0xc38
+#define SE_DMA_TX_LEN 0xc3c
#define SE_DMA_TX_IRQ_STAT 0xc40
#define SE_DMA_TX_IRQ_CLR 0xc44
+#define SE_DMA_TX_IRQ_EN 0xc48
+#define SE_DMA_TX_IRQ_EN_SET 0xc4c
+#define SE_DMA_TX_IRQ_EN_CLR 0xc50
+#define SE_DMA_TX_LEN_IN 0xc54
#define SE_DMA_TX_FSM_RST 0xc58
+#define SE_DMA_TX_MAX_BURST 0xc5c
+/* RX DMA registers */
+#define SE_DMA_RX_PTR_L 0xd30
+#define SE_DMA_RX_PTR_H 0xd34
+#define SE_DMA_RX_ATTR 0xd38
+#define SE_DMA_RX_LEN 0xd3c
#define SE_DMA_RX_IRQ_STAT 0xd40
#define SE_DMA_RX_IRQ_CLR 0xd44
+#define SE_DMA_RX_IRQ_EN 0xd48
+#define SE_DMA_RX_IRQ_EN_SET 0xd4c
+#define SE_DMA_RX_IRQ_EN_CLR 0xd50
#define SE_DMA_RX_LEN_IN 0xd54
#define SE_DMA_RX_FSM_RST 0xd58
+#define SE_DMA_RX_MAX_BURST 0xd5c
+/* DMA general / debug registers */
+#define SE_GSI_EVENT_EN 0xe18
+#define SE_IRQ_EN 0xe1c
+#define DMA_IF_EN_RO 0xe20
#define SE_HW_PARAM_0 0xe24
#define SE_HW_PARAM_1 0xe28
+#define DMA_GENERAL_CFG 0xe30
+#define SE_DMA_QSB_TRANS_CFG 0xe38
+#define SE_DMA_DEBUG_REG0 0xe40
/* GENI_FORCE_DEFAULT_REG fields */
#define FORCE_DEFAULT BIT(0)
@@ -269,6 +301,12 @@ struct geni_se {
#define RX_GENI_GP_IRQ_EXT GENMASK(13, 12)
#define RX_GENI_CANCEL_IRQ BIT(14)
+/* SE_DMA_DEBUG_REG0 fields */
+#define DMA_TX_ACTIVE BIT(0)
+#define DMA_RX_ACTIVE BIT(1)
+#define DMA_TX_STATE GENMASK(7, 4)
+#define DMA_RX_STATE GENMASK(11, 8)
+
/* SE_HW_PARAM_0 fields */
#define TX_FIFO_WIDTH_MSK GENMASK(29, 24)
#define TX_FIFO_WIDTH_SHFT 24
diff --git a/include/trace/events/qcom_geni_se.h b/include/trace/events/qcom_geni_se.h
new file mode 100644
index 000000000000..4a6e1ba2d147
--- /dev/null
+++ b/include/trace/events/qcom_geni_se.h
@@ -0,0 +1,157 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+ */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM qcom_geni_se
+
+#if !defined(_TRACE_QCOM_GENI_SE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_QCOM_GENI_SE_H
+
+#include <linux/io.h>
+#include <linux/tracepoint.h>
+#include <linux/soc/qcom/geni-se.h>
+
+TRACE_EVENT(geni_se_regs,
+ TP_PROTO(struct geni_se *se),
+
+ TP_ARGS(se),
+
+ TP_STRUCT__entry(__string(geni_se_name, dev_name(se->dev))
+ __field(u32, geni_se_m_cmd0)
+ __field(u32, geni_se_m_irq_status)
+ __field(u32, geni_se_s_cmd0)
+ __field(u32, geni_se_s_irq_status)
+ __field(u32, geni_se_status)
+ __field(u32, geni_se_ios)
+ __field(u32, geni_se_m_cmd_ctrl)
+ __field(u32, geni_se_m_cmd_err)
+ __field(u32, geni_se_m_fw_err)
+ __field(u32, geni_se_tx_fifo_status)
+ __field(u32, geni_se_rx_fifo_status)
+ __field(u32, geni_se_tx_watermark)
+ __field(u32, geni_se_rx_watermark)
+ __field(u32, geni_se_rx_watermark_rfr)
+ __field(u32, geni_se_m_gp_length)
+ __field(u32, geni_se_s_gp_length)
+ __field(u32, geni_se_dma_tx_irq)
+ __field(u32, geni_se_dma_rx_irq)
+ __field(u32, geni_se_dma_tx_irq_en)
+ __field(u32, geni_se_dma_rx_irq_en)
+ __field(u32, geni_se_dma_rx_len)
+ __field(u32, geni_se_dma_rx_len_in)
+ __field(u32, geni_se_dma_tx_len)
+ __field(u32, geni_se_dma_tx_len_in)
+ __field(u32, geni_se_dma_tx_ptr_l)
+ __field(u32, geni_se_dma_tx_ptr_h)
+ __field(u32, geni_se_dma_rx_ptr_l)
+ __field(u32, geni_se_dma_rx_ptr_h)
+ __field(u32, geni_se_dma_tx_attr)
+ __field(u32, geni_se_dma_tx_max_burst)
+ __field(u32, geni_se_dma_rx_attr)
+ __field(u32, geni_se_dma_rx_max_burst)
+ __field(u32, geni_se_dma_if_en)
+ __field(u32, geni_se_dma_if_en_ro)
+ __field(u32, geni_se_dma_general_cfg)
+ __field(u32, geni_se_dma_qsb_trans_cfg)
+ __field(u32, geni_se_dma_dbg)
+ __field(u32, geni_se_m_irq_en)
+ __field(u32, geni_se_s_irq_en)
+ __field(u32, geni_se_gsi_event_en)
+ __field(u32, geni_se_irq_en)
+ __field(u32, geni_se_ser_m_clk_cfg)
+ __field(u32, geni_se_ser_s_clk_cfg)
+ __field(u32, geni_se_general_cfg)
+ __field(u32, geni_se_output_ctrl)
+ __field(u32, geni_se_clk_ctrl_ro)
+ __field(u32, geni_se_fifo_if_disable)
+ __field(u32, geni_se_fw_multilock_msa)
+ __field(u32, geni_se_clk_sel)
+ ),
+
+ TP_fast_assign(__assign_str(geni_se_name);
+ __entry->geni_se_m_cmd0 = readl(se->base + SE_GENI_M_CMD0);
+ __entry->geni_se_m_irq_status = readl(se->base + SE_GENI_M_IRQ_STATUS);
+ __entry->geni_se_s_cmd0 = readl(se->base + SE_GENI_S_CMD0);
+ __entry->geni_se_s_irq_status = readl(se->base + SE_GENI_S_IRQ_STATUS);
+ __entry->geni_se_status = readl(se->base + SE_GENI_STATUS);
+ __entry->geni_se_ios = readl(se->base + SE_GENI_IOS);
+ __entry->geni_se_m_cmd_ctrl = readl(se->base + SE_GENI_M_CMD_CTRL_REG);
+ __entry->geni_se_m_cmd_err = readl(se->base + M_CMD_ERR_STATUS);
+ __entry->geni_se_m_fw_err = readl(se->base + M_FW_ERR_STATUS);
+ __entry->geni_se_tx_fifo_status = readl(se->base + SE_GENI_TX_FIFO_STATUS);
+ __entry->geni_se_rx_fifo_status = readl(se->base + SE_GENI_RX_FIFO_STATUS);
+ __entry->geni_se_tx_watermark = readl(se->base + SE_GENI_TX_WATERMARK_REG);
+ __entry->geni_se_rx_watermark = readl(se->base + SE_GENI_RX_WATERMARK_REG);
+ __entry->geni_se_rx_watermark_rfr = readl(se->base + SE_GENI_RX_RFR_WATERMARK_REG);
+ __entry->geni_se_m_gp_length = readl(se->base + SE_GENI_M_GP_LENGTH);
+ __entry->geni_se_s_gp_length = readl(se->base + SE_GENI_S_GP_LENGTH);
+ __entry->geni_se_dma_tx_irq = readl(se->base + SE_DMA_TX_IRQ_STAT);
+ __entry->geni_se_dma_rx_irq = readl(se->base + SE_DMA_RX_IRQ_STAT);
+ __entry->geni_se_dma_tx_irq_en = readl(se->base + SE_DMA_TX_IRQ_EN);
+ __entry->geni_se_dma_rx_irq_en = readl(se->base + SE_DMA_RX_IRQ_EN);
+ __entry->geni_se_dma_rx_len = readl(se->base + SE_DMA_RX_LEN);
+ __entry->geni_se_dma_rx_len_in = readl(se->base + SE_DMA_RX_LEN_IN);
+ __entry->geni_se_dma_tx_len = readl(se->base + SE_DMA_TX_LEN);
+ __entry->geni_se_dma_tx_len_in = readl(se->base + SE_DMA_TX_LEN_IN);
+ __entry->geni_se_dma_tx_ptr_l = readl(se->base + SE_DMA_TX_PTR_L);
+ __entry->geni_se_dma_tx_ptr_h = readl(se->base + SE_DMA_TX_PTR_H);
+ __entry->geni_se_dma_rx_ptr_l = readl(se->base + SE_DMA_RX_PTR_L);
+ __entry->geni_se_dma_rx_ptr_h = readl(se->base + SE_DMA_RX_PTR_H);
+ __entry->geni_se_dma_tx_attr = readl(se->base + SE_DMA_TX_ATTR);
+ __entry->geni_se_dma_tx_max_burst = readl(se->base + SE_DMA_TX_MAX_BURST);
+ __entry->geni_se_dma_rx_attr = readl(se->base + SE_DMA_RX_ATTR);
+ __entry->geni_se_dma_rx_max_burst = readl(se->base + SE_DMA_RX_MAX_BURST);
+ __entry->geni_se_dma_if_en = readl(se->base + SE_DMA_IF_EN);
+ __entry->geni_se_dma_if_en_ro = readl(se->base + DMA_IF_EN_RO);
+ __entry->geni_se_dma_general_cfg = readl(se->base + DMA_GENERAL_CFG);
+ __entry->geni_se_dma_qsb_trans_cfg = readl(se->base + SE_DMA_QSB_TRANS_CFG);
+ __entry->geni_se_dma_dbg = readl(se->base + SE_DMA_DEBUG_REG0);
+ __entry->geni_se_m_irq_en = readl(se->base + SE_GENI_M_IRQ_EN);
+ __entry->geni_se_s_irq_en = readl(se->base + SE_GENI_S_IRQ_EN);
+ __entry->geni_se_gsi_event_en = readl(se->base + SE_GSI_EVENT_EN);
+ __entry->geni_se_irq_en = readl(se->base + SE_IRQ_EN);
+ __entry->geni_se_ser_m_clk_cfg = readl(se->base + GENI_SER_M_CLK_CFG);
+ __entry->geni_se_ser_s_clk_cfg = readl(se->base + GENI_SER_S_CLK_CFG);
+ __entry->geni_se_general_cfg = readl(se->base + GENI_GENERAL_CFG);
+ __entry->geni_se_output_ctrl = readl(se->base + GENI_OUTPUT_CTRL);
+ __entry->geni_se_clk_ctrl_ro = readl(se->base + GENI_CLK_CTRL_RO);
+ __entry->geni_se_fifo_if_disable = readl(se->base + GENI_IF_DISABLE_RO);
+ __entry->geni_se_fw_multilock_msa = readl(se->base + GENI_FW_MULTILOCK_MSA_RO);
+ __entry->geni_se_clk_sel = readl(se->base + SE_GENI_CLK_SEL);
+ ),
+
+ TP_printk("%s: m_cmd0=0x%08x m_irq_status=0x%08x s_cmd0=0x%08x s_irq_status=0x%08x geni_status=0x%08x geni_ios=0x%08x m_cmd_ctrl=0x%08x m_cmd_err=0x%08x m_fw_err=0x%08x tx_fifo_sts=0x%08x rx_fifo_sts=0x%08x tx_watermark=0x%08x rx_watermark=0x%08x rx_watermark_rfr=0x%08x m_gp_length=0x%08x s_gp_length=0x%08x dma_tx_irq=0x%08x dma_rx_irq=0x%08x dma_tx_irq_en=0x%08x dma_rx_irq_en=0x%08x dma_rx_len=0x%08x dma_rx_len_in=0x%08x dma_tx_len=0x%08x dma_tx_len_in=0x%08x dma_tx_ptr_l=0x%08x dma_tx_ptr_h=0x%08x dma_rx_ptr_l=0x%08x dma_rx_ptr_h=0x%08x dma_tx_attr=0x%08x dma_tx_max_burst=0x%08x dma_rx_attr=0x%08x dma_rx_max_burst=0x%08x dma_if_en=0x%08x dma_if_en_ro=0x%08x dma_general_cfg=0x%08x dma_qsb_trans_cfg=0x%08x dma_dbg=0x%08x m_irq_en=0x%08x s_irq_en=0x%08x gsi_event_en=0x%08x se_irq_en=0x%08x ser_m_clk_cfg=0x%08x ser_s_clk_cfg=0x%08x general_cfg=0x%08x output_ctrl=0x%08x clk_ctrl_ro=0x%08x fifo_if_dis=0x%08x fw_multilock_msa=0x%08x clk_sel=0x%08x",
+ __get_str(geni_se_name),
+ __entry->geni_se_m_cmd0, __entry->geni_se_m_irq_status,
+ __entry->geni_se_s_cmd0, __entry->geni_se_s_irq_status,
+ __entry->geni_se_status, __entry->geni_se_ios,
+ __entry->geni_se_m_cmd_ctrl,
+ __entry->geni_se_m_cmd_err, __entry->geni_se_m_fw_err,
+ __entry->geni_se_tx_fifo_status, __entry->geni_se_rx_fifo_status,
+ __entry->geni_se_tx_watermark, __entry->geni_se_rx_watermark,
+ __entry->geni_se_rx_watermark_rfr,
+ __entry->geni_se_m_gp_length, __entry->geni_se_s_gp_length,
+ __entry->geni_se_dma_tx_irq, __entry->geni_se_dma_rx_irq,
+ __entry->geni_se_dma_tx_irq_en, __entry->geni_se_dma_rx_irq_en,
+ __entry->geni_se_dma_rx_len, __entry->geni_se_dma_rx_len_in,
+ __entry->geni_se_dma_tx_len, __entry->geni_se_dma_tx_len_in,
+ __entry->geni_se_dma_tx_ptr_l, __entry->geni_se_dma_tx_ptr_h,
+ __entry->geni_se_dma_rx_ptr_l, __entry->geni_se_dma_rx_ptr_h,
+ __entry->geni_se_dma_tx_attr, __entry->geni_se_dma_tx_max_burst,
+ __entry->geni_se_dma_rx_attr, __entry->geni_se_dma_rx_max_burst,
+ __entry->geni_se_dma_if_en, __entry->geni_se_dma_if_en_ro,
+ __entry->geni_se_dma_general_cfg, __entry->geni_se_dma_qsb_trans_cfg,
+ __entry->geni_se_dma_dbg,
+ __entry->geni_se_m_irq_en, __entry->geni_se_s_irq_en,
+ __entry->geni_se_gsi_event_en, __entry->geni_se_irq_en,
+ __entry->geni_se_ser_m_clk_cfg, __entry->geni_se_ser_s_clk_cfg,
+ __entry->geni_se_general_cfg, __entry->geni_se_output_ctrl,
+ __entry->geni_se_clk_ctrl_ro, __entry->geni_se_fifo_if_disable,
+ __entry->geni_se_fw_multilock_msa, __entry->geni_se_clk_sel)
+);
+
+#endif /* _TRACE_QCOM_GENI_SE_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 2/2] spi: qcom-geni: add GENI SE registers trace event on error paths
2026-07-06 11:08 [PATCH 0/2] Add trace event support for GENI SE registers dump Praveen Talari
2026-07-06 11:08 ` [PATCH 1/2] soc: qcom: geni-se: trace: " Praveen Talari
@ 2026-07-06 11:08 ` Praveen Talari
2026-07-06 15:35 ` Konrad Dybcio
2026-07-08 10:06 ` Mukesh Savaliya
1 sibling, 2 replies; 6+ messages in thread
From: Praveen Talari @ 2026-07-06 11:08 UTC (permalink / raw)
To: Bjorn Andersson, Konrad Dybcio, Steven Rostedt, Masami Hiramatsu,
Mathieu Desnoyers, Mark Brown
Cc: linux-kernel, linux-arm-msm, linux-trace-kernel, linux-spi,
Mukesh Kumar Savaliya, aniket.randive, chandana.chiluveru,
Praveen Talari
The GENI SPI driver reports various transfer failures such as command
timeouts, DMA reset timeouts, DMA transaction errors, and unexpected
interrupt conditions. However, diagnosing the root cause of these
failures is difficult as the hardware state is not captured when the
error occurs.
Add trace_geni_se_regs() calls at critical SPI error handling paths to
automatically capture GENI serial engine debug registers when failures
are detected. This includes:
- M_CMD abort/cancel timeout
- DMA TX/RX FSM reset timeout
- DMA transaction failures and pending residue conditions
- Unexpected interrupt error status
- Premature transfer completion with pending TX/RX data
Dumping the SE debug registers at the time of failure provides
additional hardware context and significantly improves post-mortem
analysis of SPI transfer issues without affecting normal operation.
Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
---
drivers/spi/spi-geni-qcom.c | 22 ++++++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
index 26e723cfea61..7db0836308c2 100644
--- a/drivers/spi/spi-geni-qcom.c
+++ b/drivers/spi/spi-geni-qcom.c
@@ -3,6 +3,7 @@
#define CREATE_TRACE_POINTS
#include <trace/events/qcom_geni_spi.h>
+#include <trace/events/qcom_geni_se.h>
#include <linux/clk.h>
#include <linux/dmaengine.h>
@@ -184,6 +185,7 @@ static void handle_se_timeout(struct spi_controller *spi)
time_left = wait_for_completion_timeout(&mas->abort_done, HZ);
if (!time_left) {
dev_err(mas->dev, "Failed to cancel/abort m_cmd\n");
+ trace_geni_se_regs(se);
/*
* No need for a lock since SPI core has a lock and we never
@@ -201,8 +203,10 @@ static void handle_se_timeout(struct spi_controller *spi)
writel(1, se->base + SE_DMA_TX_FSM_RST);
spin_unlock_irq(&mas->lock);
time_left = wait_for_completion_timeout(&mas->tx_reset_done, HZ);
- if (!time_left)
+ if (!time_left) {
dev_err(mas->dev, "DMA TX RESET failed\n");
+ trace_geni_se_regs(se);
+ }
}
if (xfer->rx_buf) {
spin_lock_irq(&mas->lock);
@@ -210,8 +214,10 @@ static void handle_se_timeout(struct spi_controller *spi)
writel(1, se->base + SE_DMA_RX_FSM_RST);
spin_unlock_irq(&mas->lock);
time_left = wait_for_completion_timeout(&mas->rx_reset_done, HZ);
- if (!time_left)
+ if (!time_left) {
dev_err(mas->dev, "DMA RX RESET failed\n");
+ trace_geni_se_regs(se);
+ }
}
} else {
/*
@@ -382,10 +388,12 @@ static void
spi_gsi_callback_result(void *cb, const struct dmaengine_result *result)
{
struct spi_controller *spi = cb;
+ struct spi_geni_master *mas = spi_controller_get_devdata(spi);
spi->cur_msg->status = -EIO;
if (result->result != DMA_TRANS_NOERROR) {
dev_err(&spi->dev, "DMA txn failed: %d\n", result->result);
+ trace_geni_se_regs(&mas->se);
spi_finalize_current_transfer(spi);
return;
}
@@ -395,6 +403,7 @@ spi_gsi_callback_result(void *cb, const struct dmaengine_result *result)
dev_dbg(&spi->dev, "DMA txn completed\n");
} else {
dev_err(&spi->dev, "DMA xfer has pending: %d\n", result->residue);
+ trace_geni_se_regs(&mas->se);
}
spi_finalize_current_transfer(spi);
@@ -941,8 +950,10 @@ static irqreturn_t geni_spi_isr(int irq, void *data)
if (m_irq & (M_CMD_OVERRUN_EN | M_ILLEGAL_CMD_EN | M_CMD_FAILURE_EN |
M_RX_FIFO_RD_ERR_EN | M_RX_FIFO_WR_ERR_EN |
- M_TX_FIFO_RD_ERR_EN | M_TX_FIFO_WR_ERR_EN))
+ M_TX_FIFO_RD_ERR_EN | M_TX_FIFO_WR_ERR_EN)) {
dev_warn(mas->dev, "Unexpected IRQ err status %#010x\n", m_irq);
+ trace_geni_se_regs(se);
+ }
spin_lock(&mas->lock);
@@ -974,10 +985,13 @@ static irqreturn_t geni_spi_isr(int irq, void *data)
writel(0, se->base + SE_GENI_TX_WATERMARK_REG);
dev_err(mas->dev, "Premature done. tx_rem = %d bpw%d\n",
mas->tx_rem_bytes, mas->cur_bits_per_word);
+ trace_geni_se_regs(se);
}
- if (mas->rx_rem_bytes)
+ if (mas->rx_rem_bytes) {
dev_err(mas->dev, "Premature done. rx_rem = %d bpw%d\n",
mas->rx_rem_bytes, mas->cur_bits_per_word);
+ trace_geni_se_regs(se);
+ }
} else {
complete(&mas->cs_done);
}
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] soc: qcom: geni-se: trace: Add trace event support for GENI SE registers dump
2026-07-06 11:08 ` [PATCH 1/2] soc: qcom: geni-se: trace: " Praveen Talari
@ 2026-07-06 14:59 ` Steven Rostedt
0 siblings, 0 replies; 6+ messages in thread
From: Steven Rostedt @ 2026-07-06 14:59 UTC (permalink / raw)
To: Praveen Talari
Cc: Bjorn Andersson, Konrad Dybcio, Masami Hiramatsu,
Mathieu Desnoyers, Mark Brown, linux-kernel, linux-arm-msm,
linux-trace-kernel, linux-spi, Mukesh Kumar Savaliya,
aniket.randive, chandana.chiluveru
On Mon, 06 Jul 2026 16:38:12 +0530
Praveen Talari <praveen.talari@oss.qualcomm.com> wrote:
> +TRACE_EVENT(geni_se_regs,
> + TP_PROTO(struct geni_se *se),
> +
> + TP_ARGS(se),
> +
> + TP_STRUCT__entry(__string(geni_se_name, dev_name(se->dev))
> + __field(u32, geni_se_m_cmd0)
> + __field(u32, geni_se_m_irq_status)
> + __field(u32, geni_se_s_cmd0)
> + __field(u32, geni_se_s_irq_status)
> + __field(u32, geni_se_status)
> + __field(u32, geni_se_ios)
> + __field(u32, geni_se_m_cmd_ctrl)
> + __field(u32, geni_se_m_cmd_err)
> + __field(u32, geni_se_m_fw_err)
> + __field(u32, geni_se_tx_fifo_status)
> + __field(u32, geni_se_rx_fifo_status)
> + __field(u32, geni_se_tx_watermark)
> + __field(u32, geni_se_rx_watermark)
> + __field(u32, geni_se_rx_watermark_rfr)
> + __field(u32, geni_se_m_gp_length)
> + __field(u32, geni_se_s_gp_length)
> + __field(u32, geni_se_dma_tx_irq)
> + __field(u32, geni_se_dma_rx_irq)
> + __field(u32, geni_se_dma_tx_irq_en)
> + __field(u32, geni_se_dma_rx_irq_en)
> + __field(u32, geni_se_dma_rx_len)
> + __field(u32, geni_se_dma_rx_len_in)
> + __field(u32, geni_se_dma_tx_len)
> + __field(u32, geni_se_dma_tx_len_in)
> + __field(u32, geni_se_dma_tx_ptr_l)
> + __field(u32, geni_se_dma_tx_ptr_h)
> + __field(u32, geni_se_dma_rx_ptr_l)
> + __field(u32, geni_se_dma_rx_ptr_h)
> + __field(u32, geni_se_dma_tx_attr)
> + __field(u32, geni_se_dma_tx_max_burst)
> + __field(u32, geni_se_dma_rx_attr)
> + __field(u32, geni_se_dma_rx_max_burst)
> + __field(u32, geni_se_dma_if_en)
> + __field(u32, geni_se_dma_if_en_ro)
> + __field(u32, geni_se_dma_general_cfg)
> + __field(u32, geni_se_dma_qsb_trans_cfg)
> + __field(u32, geni_se_dma_dbg)
> + __field(u32, geni_se_m_irq_en)
> + __field(u32, geni_se_s_irq_en)
> + __field(u32, geni_se_gsi_event_en)
> + __field(u32, geni_se_irq_en)
> + __field(u32, geni_se_ser_m_clk_cfg)
> + __field(u32, geni_se_ser_s_clk_cfg)
> + __field(u32, geni_se_general_cfg)
> + __field(u32, geni_se_output_ctrl)
> + __field(u32, geni_se_clk_ctrl_ro)
> + __field(u32, geni_se_fifo_if_disable)
> + __field(u32, geni_se_fw_multilock_msa)
> + __field(u32, geni_se_clk_sel)
> + ),
Wow, a pretty big trace event! But it still fits in the ring buffer.
Acked-by: Steven Rostedt <rostedt@goodmis.org>
-- Steve
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] spi: qcom-geni: add GENI SE registers trace event on error paths
2026-07-06 11:08 ` [PATCH 2/2] spi: qcom-geni: add GENI SE registers trace event on error paths Praveen Talari
@ 2026-07-06 15:35 ` Konrad Dybcio
2026-07-08 10:06 ` Mukesh Savaliya
1 sibling, 0 replies; 6+ messages in thread
From: Konrad Dybcio @ 2026-07-06 15:35 UTC (permalink / raw)
To: Praveen Talari, Bjorn Andersson, Konrad Dybcio, Steven Rostedt,
Masami Hiramatsu, Mathieu Desnoyers, Mark Brown
Cc: linux-kernel, linux-arm-msm, linux-trace-kernel, linux-spi,
Mukesh Kumar Savaliya, aniket.randive, chandana.chiluveru
On 7/6/26 1:08 PM, Praveen Talari wrote:
> The GENI SPI driver reports various transfer failures such as command
> timeouts, DMA reset timeouts, DMA transaction errors, and unexpected
> interrupt conditions. However, diagnosing the root cause of these
> failures is difficult as the hardware state is not captured when the
> error occurs.
>
> Add trace_geni_se_regs() calls at critical SPI error handling paths to
> automatically capture GENI serial engine debug registers when failures
> are detected. This includes:
>
> - M_CMD abort/cancel timeout
> - DMA TX/RX FSM reset timeout
> - DMA transaction failures and pending residue conditions
> - Unexpected interrupt error status
> - Premature transfer completion with pending TX/RX data
>
> Dumping the SE debug registers at the time of failure provides
> additional hardware context and significantly improves post-mortem
> analysis of SPI transfer issues without affecting normal operation.
>
> Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
> ---
> drivers/spi/spi-geni-qcom.c | 22 ++++++++++++++++++----
> 1 file changed, 18 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c
> index 26e723cfea61..7db0836308c2 100644
> --- a/drivers/spi/spi-geni-qcom.c
> +++ b/drivers/spi/spi-geni-qcom.c
> @@ -3,6 +3,7 @@
>
> #define CREATE_TRACE_POINTS
> #include <trace/events/qcom_geni_spi.h>
> +#include <trace/events/qcom_geni_se.h>
nit: this could be sorted alphabetically (Mark, could you fix
it up while applying?)
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Konrad
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] spi: qcom-geni: add GENI SE registers trace event on error paths
2026-07-06 11:08 ` [PATCH 2/2] spi: qcom-geni: add GENI SE registers trace event on error paths Praveen Talari
2026-07-06 15:35 ` Konrad Dybcio
@ 2026-07-08 10:06 ` Mukesh Savaliya
1 sibling, 0 replies; 6+ messages in thread
From: Mukesh Savaliya @ 2026-07-08 10:06 UTC (permalink / raw)
To: Praveen Talari, Bjorn Andersson, Konrad Dybcio, Steven Rostedt,
Masami Hiramatsu, Mathieu Desnoyers, Mark Brown
Cc: linux-kernel, linux-arm-msm, linux-trace-kernel, linux-spi,
aniket.randive, chandana.chiluveru
On 7/6/2026 4:38 PM, Praveen Talari wrote:
> The GENI SPI driver reports various transfer failures such as command
> timeouts, DMA reset timeouts, DMA transaction errors, and unexpected
> interrupt conditions. However, diagnosing the root cause of these
> failures is difficult as the hardware state is not captured when the
> error occurs.
>
> Add trace_geni_se_regs() calls at critical SPI error handling paths to
> automatically capture GENI serial engine debug registers when failures
> are detected. This includes:
>
> - M_CMD abort/cancel timeout
> - DMA TX/RX FSM reset timeout
> - DMA transaction failures and pending residue conditions
> - Unexpected interrupt error status
> - Premature transfer completion with pending TX/RX data
>
> Dumping the SE debug registers at the time of failure provides
> additional hardware context and significantly improves post-mortem
> analysis of SPI transfer issues without affecting normal operation.
>
> Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
> ---
> drivers/spi/spi-geni-qcom.c | 22 ++++++++++++++++++----
> 1 file changed, 18 insertions(+), 4 deletions(-)
>
Acked-by: Mukesh Kumar Savaliya <mukesh.savaliya@oss.qualcomm.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-07-08 10:06 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-06 11:08 [PATCH 0/2] Add trace event support for GENI SE registers dump Praveen Talari
2026-07-06 11:08 ` [PATCH 1/2] soc: qcom: geni-se: trace: " Praveen Talari
2026-07-06 14:59 ` Steven Rostedt
2026-07-06 11:08 ` [PATCH 2/2] spi: qcom-geni: add GENI SE registers trace event on error paths Praveen Talari
2026-07-06 15:35 ` Konrad Dybcio
2026-07-08 10:06 ` Mukesh Savaliya
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox