From: Jérôme Pouiller <jerome.pouil...@silabs.com>

Some tracepoints are useful for debugging.

Signed-off-by: Jérôme Pouiller <jerome.pouil...@silabs.com>
---
 drivers/staging/wfx/Makefile |   6 +-
 drivers/staging/wfx/debug.c  |  10 +++
 drivers/staging/wfx/hwio.c   |  11 +++
 drivers/staging/wfx/traces.h | 154 +++++++++++++++++++++++++++++++++++
 4 files changed, 180 insertions(+), 1 deletion(-)
 create mode 100644 drivers/staging/wfx/debug.c
 create mode 100644 drivers/staging/wfx/traces.h

diff --git a/drivers/staging/wfx/Makefile b/drivers/staging/wfx/Makefile
index e860845186cf..330b7288ebb5 100644
--- a/drivers/staging/wfx/Makefile
+++ b/drivers/staging/wfx/Makefile
@@ -1,8 +1,12 @@
 # SPDX-License-Identifier: GPL-2.0
 
+# Necessary for CREATE_TRACE_POINTS
+CFLAGS_debug.o = -I$(src)
+
 wfx-y := \
        hwio.o \
-       main.o
+       main.o \
+       debug.o
 wfx-$(CONFIG_SPI) += bus_spi.o
 wfx-$(subst m,y,$(CONFIG_MMC)) += bus_sdio.o
 
diff --git a/drivers/staging/wfx/debug.c b/drivers/staging/wfx/debug.c
new file mode 100644
index 000000000000..bf44c944640d
--- /dev/null
+++ b/drivers/staging/wfx/debug.c
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Debugfs interface.
+ *
+ * Copyright (c) 2017-2019, Silicon Laboratories, Inc.
+ * Copyright (c) 2010, ST-Ericsson
+ */
+
+#define CREATE_TRACE_POINTS
+#include "traces.h"
diff --git a/drivers/staging/wfx/hwio.c b/drivers/staging/wfx/hwio.c
index fa626a49dd8a..0cf52aee10e7 100644
--- a/drivers/staging/wfx/hwio.c
+++ b/drivers/staging/wfx/hwio.c
@@ -12,6 +12,7 @@
 #include "hwio.h"
 #include "wfx.h"
 #include "bus.h"
+#include "traces.h"
 
 /*
  * Internal helpers.
@@ -63,6 +64,7 @@ static int read32_locked(struct wfx_dev *wdev, int reg, u32 
*val)
 
        wdev->hwbus_ops->lock(wdev->hwbus_priv);
        ret = read32(wdev, reg, val);
+       _trace_io_read32(reg, *val);
        wdev->hwbus_ops->unlock(wdev->hwbus_priv);
        return ret;
 }
@@ -73,6 +75,7 @@ static int write32_locked(struct wfx_dev *wdev, int reg, u32 
val)
 
        wdev->hwbus_ops->lock(wdev->hwbus_priv);
        ret = write32(wdev, reg, val);
+       _trace_io_write32(reg, val);
        wdev->hwbus_ops->unlock(wdev->hwbus_priv);
        return ret;
 }
@@ -86,11 +89,13 @@ static int write32_bits_locked(struct wfx_dev *wdev, int 
reg, u32 mask, u32 val)
        val &= mask;
        wdev->hwbus_ops->lock(wdev->hwbus_priv);
        ret = read32(wdev, reg, &val_r);
+       _trace_io_read32(reg, val_r);
        if (ret < 0)
                goto err;
        val_w = (val_r & ~mask) | val;
        if (val_w != val_r) {
                ret = write32(wdev, reg, val_w);
+               _trace_io_write32(reg, val_w);
        }
 err:
        wdev->hwbus_ops->unlock(wdev->hwbus_priv);
@@ -166,6 +171,7 @@ static int indirect_read_locked(struct wfx_dev *wdev, int 
reg, u32 addr, void *b
 
        wdev->hwbus_ops->lock(wdev->hwbus_priv);
        ret = indirect_read(wdev, reg, addr, buf, len);
+       _trace_io_ind_read(reg, addr, buf, len);
        wdev->hwbus_ops->unlock(wdev->hwbus_priv);
        return ret;
 }
@@ -176,6 +182,7 @@ static int indirect_write_locked(struct wfx_dev *wdev, int 
reg, u32 addr, const
 
        wdev->hwbus_ops->lock(wdev->hwbus_priv);
        ret = indirect_write(wdev, reg, addr, buf, len);
+       _trace_io_ind_write(reg, addr, buf, len);
        wdev->hwbus_ops->unlock(wdev->hwbus_priv);
        return ret;
 }
@@ -190,6 +197,7 @@ static int indirect_read32_locked(struct wfx_dev *wdev, int 
reg, u32 addr, u32 *
        wdev->hwbus_ops->lock(wdev->hwbus_priv);
        ret = indirect_read(wdev, reg, addr, tmp, sizeof(u32));
        *val = cpu_to_le32(*tmp);
+       _trace_io_ind_read32(reg, addr, *val);
        wdev->hwbus_ops->unlock(wdev->hwbus_priv);
        kfree(tmp);
        return ret;
@@ -205,6 +213,7 @@ static int indirect_write32_locked(struct wfx_dev *wdev, 
int reg, u32 addr, u32
        *tmp = cpu_to_le32(val);
        wdev->hwbus_ops->lock(wdev->hwbus_priv);
        ret = indirect_write(wdev, reg, addr, tmp, sizeof(u32));
+       _trace_io_ind_write32(reg, addr, val);
        wdev->hwbus_ops->unlock(wdev->hwbus_priv);
        kfree(tmp);
        return ret;
@@ -217,6 +226,7 @@ int wfx_data_read(struct wfx_dev *wdev, void *buf, size_t 
len)
        WARN((long) buf & 3, "%s: unaligned buffer", __func__);
        wdev->hwbus_ops->lock(wdev->hwbus_priv);
        ret = wdev->hwbus_ops->copy_from_io(wdev->hwbus_priv, 
WFX_REG_IN_OUT_QUEUE, buf, len);
+       _trace_io_read(WFX_REG_IN_OUT_QUEUE, buf, len);
        wdev->hwbus_ops->unlock(wdev->hwbus_priv);
        if (ret)
                dev_err(wdev->dev, "%s: bus communication error: %d\n", 
__func__, ret);
@@ -230,6 +240,7 @@ int wfx_data_write(struct wfx_dev *wdev, const void *buf, 
size_t len)
        WARN((long) buf & 3, "%s: unaligned buffer", __func__);
        wdev->hwbus_ops->lock(wdev->hwbus_priv);
        ret = wdev->hwbus_ops->copy_to_io(wdev->hwbus_priv, 
WFX_REG_IN_OUT_QUEUE, buf, len);
+       _trace_io_write(WFX_REG_IN_OUT_QUEUE, buf, len);
        wdev->hwbus_ops->unlock(wdev->hwbus_priv);
        if (ret)
                dev_err(wdev->dev, "%s: bus communication error: %d\n", 
__func__, ret);
diff --git a/drivers/staging/wfx/traces.h b/drivers/staging/wfx/traces.h
new file mode 100644
index 000000000000..ba97df821f1b
--- /dev/null
+++ b/drivers/staging/wfx/traces.h
@@ -0,0 +1,154 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Tracepoints definitions.
+ *
+ * Copyright (c) 2018-2019, Silicon Laboratories, Inc.
+ */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM wfx
+
+#if !defined(_WFX_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _WFX_TRACE_H
+
+#include <linux/tracepoint.h>
+#include <linux/version.h>
+
+#include "bus.h"
+
+#if (KERNEL_VERSION(4, 1, 0) > LINUX_VERSION_CODE)
+#define TRACE_DEFINE_ENUM(a)
+#endif
+
+/* The hell below need some explanations. For each symbolic number, we need to
+ * define it with TRACE_DEFINE_ENUM() and in a list for __print_symbolic.
+ *
+ *   1. Define a new macro that call TRACE_DEFINE_ENUM():
+ *
+ *          #define xxx_name(sym) TRACE_DEFINE_ENUM(sym);
+ *
+ *   2. Define list of all symbols:
+ *
+ *          #define list_names     \
+ *             ...                 \
+ *             xxx_name(XXX)       \
+ *             ...
+ *
+ *   3. Instanciate that list_names:
+ *
+ *          list_names
+ *
+ *   4. Redefine xxx_name() as a entry of array for __print_symbolic()
+ *
+ *          #undef xxx_name
+ *          #define xxx_name(msg) { msg, #msg },
+ *
+ *   5. list_name can now nearlu be used with __print_symbolic() but,
+ *      __print_symbolic() dislike last comma of list. So we define a new list
+ *      with a dummy element:
+ *
+ *          #define list_for_print_symbolic list_names { -1, NULL }
+ */
+
+#define wfx_reg_list_enum                                 \
+       wfx_reg_name(WFX_REG_CONFIG,       "CONFIG")      \
+       wfx_reg_name(WFX_REG_CONTROL,      "CONTROL")     \
+       wfx_reg_name(WFX_REG_IN_OUT_QUEUE, "QUEUE")       \
+       wfx_reg_name(WFX_REG_AHB_DPORT,    "AHB")         \
+       wfx_reg_name(WFX_REG_BASE_ADDR,    "BASE_ADDR")   \
+       wfx_reg_name(WFX_REG_SRAM_DPORT,   "SRAM")        \
+       wfx_reg_name(WFX_REG_SET_GEN_R_W,  "SET_GEN_R_W") \
+       wfx_reg_name(WFX_REG_FRAME_OUT,    "FRAME_OUT")
+
+#undef wfx_reg_name
+#define wfx_reg_name(sym, name) TRACE_DEFINE_ENUM(sym);
+wfx_reg_list_enum
+#undef wfx_reg_name
+#define wfx_reg_name(sym, name) { sym, name },
+#define wfx_reg_list wfx_reg_list_enum { -1, NULL }
+
+DECLARE_EVENT_CLASS(io_data,
+       TP_PROTO(int reg, int addr, const void *io_buf, size_t len),
+       TP_ARGS(reg, addr, io_buf, len),
+       TP_STRUCT__entry(
+               __field(int, reg)
+               __field(int, addr)
+               __field(int, msg_len)
+               __field(int, buf_len)
+               __array(u8, buf, 32)
+               __array(u8, addr_str, 10)
+       ),
+       TP_fast_assign(
+               __entry->reg = reg;
+               __entry->addr = addr;
+               __entry->msg_len = len;
+               __entry->buf_len = min_t(int, sizeof(__entry->buf), 
__entry->msg_len);
+               memcpy(__entry->buf, io_buf, __entry->buf_len);
+               if (addr >= 0)
+                       snprintf(__entry->addr_str, 10, "/%08x", addr);
+               else
+                       __entry->addr_str[0] = 0;
+       ),
+       TP_printk("%s%s: %s%s (%d bytes)",
+               __print_symbolic(__entry->reg, wfx_reg_list),
+               __entry->addr_str,
+               __print_hex(__entry->buf, __entry->buf_len),
+               __entry->msg_len > sizeof(__entry->buf) ? " ..." : "",
+               __entry->msg_len
+       )
+);
+DEFINE_EVENT(io_data, io_write,
+       TP_PROTO(int reg, int addr, const void *io_buf, size_t len),
+       TP_ARGS(reg, addr, io_buf, len));
+#define _trace_io_ind_write(reg, addr, io_buf, len) trace_io_write(reg, addr, 
io_buf, len)
+#define _trace_io_write(reg, io_buf, len) trace_io_write(reg, -1, io_buf, len)
+DEFINE_EVENT(io_data, io_read,
+       TP_PROTO(int reg, int addr, const void *io_buf, size_t len),
+       TP_ARGS(reg, addr, io_buf, len));
+#define _trace_io_ind_read(reg, addr, io_buf, len) trace_io_read(reg, addr, 
io_buf, len)
+#define _trace_io_read(reg, io_buf, len) trace_io_read(reg, -1, io_buf, len)
+
+DECLARE_EVENT_CLASS(io_data32,
+       TP_PROTO(int reg, int addr, u32 val),
+       TP_ARGS(reg, addr, val),
+       TP_STRUCT__entry(
+               __field(int, reg)
+               __field(int, addr)
+               __field(int, val)
+               __array(u8, addr_str, 10)
+       ),
+       TP_fast_assign(
+               __entry->reg = reg;
+               __entry->addr = addr;
+               __entry->val = val;
+               if (addr >= 0)
+                       snprintf(__entry->addr_str, 10, "/%08x", addr);
+               else
+                       __entry->addr_str[0] = 0;
+       ),
+       TP_printk("%s%s: %08x",
+               __print_symbolic(__entry->reg, wfx_reg_list),
+               __entry->addr_str,
+               __entry->val
+       )
+);
+DEFINE_EVENT(io_data32, io_write32,
+       TP_PROTO(int reg, int addr, u32 val),
+       TP_ARGS(reg, addr, val));
+#define _trace_io_ind_write32(reg, addr, val) trace_io_write32(reg, addr, val)
+#define _trace_io_write32(reg, val) trace_io_write32(reg, -1, val)
+DEFINE_EVENT(io_data32, io_read32,
+       TP_PROTO(int reg, int addr, u32 val),
+       TP_ARGS(reg, addr, val));
+#define _trace_io_ind_read32(reg, addr, val) trace_io_read32(reg, addr, val)
+#define _trace_io_read32(reg, val) trace_io_read32(reg, -1, val)
+
+#endif
+
+/* This part must be outside protection */
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH .
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE traces
+
+#include <trace/define_trace.h>
-- 
2.20.1
_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to