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 <[email protected]>
---
 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


Reply via email to