Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

staging: wfx: add tracepoints for I/O access

Some tracepoints are useful for debugging.

Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20190919142527.31797-5-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Jérôme Pouiller and committed by
Greg Kroah-Hartman
fee695e3 a794e8b6

+175 -1
+5 -1
drivers/staging/wfx/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 3 + # Necessary for CREATE_TRACE_POINTS 4 + CFLAGS_debug.o = -I$(src) 5 + 3 6 wfx-y := \ 4 7 hwio.o \ 5 - main.o 8 + main.o \ 9 + debug.o 6 10 wfx-$(CONFIG_SPI) += bus_spi.o 7 11 wfx-$(subst m,y,$(CONFIG_MMC)) += bus_sdio.o 8 12
+10
drivers/staging/wfx/debug.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Debugfs interface. 4 + * 5 + * Copyright (c) 2017-2019, Silicon Laboratories, Inc. 6 + * Copyright (c) 2010, ST-Ericsson 7 + */ 8 + 9 + #define CREATE_TRACE_POINTS 10 + #include "traces.h"
+11
drivers/staging/wfx/hwio.c
··· 12 12 #include "hwio.h" 13 13 #include "wfx.h" 14 14 #include "bus.h" 15 + #include "traces.h" 15 16 16 17 /* 17 18 * Internal helpers. ··· 64 63 65 64 wdev->hwbus_ops->lock(wdev->hwbus_priv); 66 65 ret = read32(wdev, reg, val); 66 + _trace_io_read32(reg, *val); 67 67 wdev->hwbus_ops->unlock(wdev->hwbus_priv); 68 68 return ret; 69 69 } ··· 75 73 76 74 wdev->hwbus_ops->lock(wdev->hwbus_priv); 77 75 ret = write32(wdev, reg, val); 76 + _trace_io_write32(reg, val); 78 77 wdev->hwbus_ops->unlock(wdev->hwbus_priv); 79 78 return ret; 80 79 } ··· 89 86 val &= mask; 90 87 wdev->hwbus_ops->lock(wdev->hwbus_priv); 91 88 ret = read32(wdev, reg, &val_r); 89 + _trace_io_read32(reg, val_r); 92 90 if (ret < 0) 93 91 goto err; 94 92 val_w = (val_r & ~mask) | val; 95 93 if (val_w != val_r) { 96 94 ret = write32(wdev, reg, val_w); 95 + _trace_io_write32(reg, val_w); 97 96 } 98 97 err: 99 98 wdev->hwbus_ops->unlock(wdev->hwbus_priv); ··· 171 166 172 167 wdev->hwbus_ops->lock(wdev->hwbus_priv); 173 168 ret = indirect_read(wdev, reg, addr, buf, len); 169 + _trace_io_ind_read(reg, addr, buf, len); 174 170 wdev->hwbus_ops->unlock(wdev->hwbus_priv); 175 171 return ret; 176 172 } ··· 182 176 183 177 wdev->hwbus_ops->lock(wdev->hwbus_priv); 184 178 ret = indirect_write(wdev, reg, addr, buf, len); 179 + _trace_io_ind_write(reg, addr, buf, len); 185 180 wdev->hwbus_ops->unlock(wdev->hwbus_priv); 186 181 return ret; 187 182 } ··· 197 190 wdev->hwbus_ops->lock(wdev->hwbus_priv); 198 191 ret = indirect_read(wdev, reg, addr, tmp, sizeof(u32)); 199 192 *val = cpu_to_le32(*tmp); 193 + _trace_io_ind_read32(reg, addr, *val); 200 194 wdev->hwbus_ops->unlock(wdev->hwbus_priv); 201 195 kfree(tmp); 202 196 return ret; ··· 213 205 *tmp = cpu_to_le32(val); 214 206 wdev->hwbus_ops->lock(wdev->hwbus_priv); 215 207 ret = indirect_write(wdev, reg, addr, tmp, sizeof(u32)); 208 + _trace_io_ind_write32(reg, addr, val); 216 209 wdev->hwbus_ops->unlock(wdev->hwbus_priv); 217 210 kfree(tmp); 218 211 return ret; ··· 226 217 WARN((long) buf & 3, "%s: unaligned buffer", __func__); 227 218 wdev->hwbus_ops->lock(wdev->hwbus_priv); 228 219 ret = wdev->hwbus_ops->copy_from_io(wdev->hwbus_priv, WFX_REG_IN_OUT_QUEUE, buf, len); 220 + _trace_io_read(WFX_REG_IN_OUT_QUEUE, buf, len); 229 221 wdev->hwbus_ops->unlock(wdev->hwbus_priv); 230 222 if (ret) 231 223 dev_err(wdev->dev, "%s: bus communication error: %d\n", __func__, ret); ··· 240 230 WARN((long) buf & 3, "%s: unaligned buffer", __func__); 241 231 wdev->hwbus_ops->lock(wdev->hwbus_priv); 242 232 ret = wdev->hwbus_ops->copy_to_io(wdev->hwbus_priv, WFX_REG_IN_OUT_QUEUE, buf, len); 233 + _trace_io_write(WFX_REG_IN_OUT_QUEUE, buf, len); 243 234 wdev->hwbus_ops->unlock(wdev->hwbus_priv); 244 235 if (ret) 245 236 dev_err(wdev->dev, "%s: bus communication error: %d\n", __func__, ret);
+149
drivers/staging/wfx/traces.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + /* 3 + * Tracepoints definitions. 4 + * 5 + * Copyright (c) 2018-2019, Silicon Laboratories, Inc. 6 + */ 7 + 8 + #undef TRACE_SYSTEM 9 + #define TRACE_SYSTEM wfx 10 + 11 + #if !defined(_WFX_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) 12 + #define _WFX_TRACE_H 13 + 14 + #include <linux/tracepoint.h> 15 + 16 + #include "bus.h" 17 + 18 + /* The hell below need some explanations. For each symbolic number, we need to 19 + * define it with TRACE_DEFINE_ENUM() and in a list for __print_symbolic. 20 + * 21 + * 1. Define a new macro that call TRACE_DEFINE_ENUM(): 22 + * 23 + * #define xxx_name(sym) TRACE_DEFINE_ENUM(sym); 24 + * 25 + * 2. Define list of all symbols: 26 + * 27 + * #define list_names \ 28 + * ... \ 29 + * xxx_name(XXX) \ 30 + * ... 31 + * 32 + * 3. Instanciate that list_names: 33 + * 34 + * list_names 35 + * 36 + * 4. Redefine xxx_name() as a entry of array for __print_symbolic() 37 + * 38 + * #undef xxx_name 39 + * #define xxx_name(msg) { msg, #msg }, 40 + * 41 + * 5. list_name can now nearlu be used with __print_symbolic() but, 42 + * __print_symbolic() dislike last comma of list. So we define a new list 43 + * with a dummy element: 44 + * 45 + * #define list_for_print_symbolic list_names { -1, NULL } 46 + */ 47 + 48 + #define wfx_reg_list_enum \ 49 + wfx_reg_name(WFX_REG_CONFIG, "CONFIG") \ 50 + wfx_reg_name(WFX_REG_CONTROL, "CONTROL") \ 51 + wfx_reg_name(WFX_REG_IN_OUT_QUEUE, "QUEUE") \ 52 + wfx_reg_name(WFX_REG_AHB_DPORT, "AHB") \ 53 + wfx_reg_name(WFX_REG_BASE_ADDR, "BASE_ADDR") \ 54 + wfx_reg_name(WFX_REG_SRAM_DPORT, "SRAM") \ 55 + wfx_reg_name(WFX_REG_SET_GEN_R_W, "SET_GEN_R_W") \ 56 + wfx_reg_name(WFX_REG_FRAME_OUT, "FRAME_OUT") 57 + 58 + #undef wfx_reg_name 59 + #define wfx_reg_name(sym, name) TRACE_DEFINE_ENUM(sym); 60 + wfx_reg_list_enum 61 + #undef wfx_reg_name 62 + #define wfx_reg_name(sym, name) { sym, name }, 63 + #define wfx_reg_list wfx_reg_list_enum { -1, NULL } 64 + 65 + DECLARE_EVENT_CLASS(io_data, 66 + TP_PROTO(int reg, int addr, const void *io_buf, size_t len), 67 + TP_ARGS(reg, addr, io_buf, len), 68 + TP_STRUCT__entry( 69 + __field(int, reg) 70 + __field(int, addr) 71 + __field(int, msg_len) 72 + __field(int, buf_len) 73 + __array(u8, buf, 32) 74 + __array(u8, addr_str, 10) 75 + ), 76 + TP_fast_assign( 77 + __entry->reg = reg; 78 + __entry->addr = addr; 79 + __entry->msg_len = len; 80 + __entry->buf_len = min_t(int, sizeof(__entry->buf), __entry->msg_len); 81 + memcpy(__entry->buf, io_buf, __entry->buf_len); 82 + if (addr >= 0) 83 + snprintf(__entry->addr_str, 10, "/%08x", addr); 84 + else 85 + __entry->addr_str[0] = 0; 86 + ), 87 + TP_printk("%s%s: %s%s (%d bytes)", 88 + __print_symbolic(__entry->reg, wfx_reg_list), 89 + __entry->addr_str, 90 + __print_hex(__entry->buf, __entry->buf_len), 91 + __entry->msg_len > sizeof(__entry->buf) ? " ..." : "", 92 + __entry->msg_len 93 + ) 94 + ); 95 + DEFINE_EVENT(io_data, io_write, 96 + TP_PROTO(int reg, int addr, const void *io_buf, size_t len), 97 + TP_ARGS(reg, addr, io_buf, len)); 98 + #define _trace_io_ind_write(reg, addr, io_buf, len) trace_io_write(reg, addr, io_buf, len) 99 + #define _trace_io_write(reg, io_buf, len) trace_io_write(reg, -1, io_buf, len) 100 + DEFINE_EVENT(io_data, io_read, 101 + TP_PROTO(int reg, int addr, const void *io_buf, size_t len), 102 + TP_ARGS(reg, addr, io_buf, len)); 103 + #define _trace_io_ind_read(reg, addr, io_buf, len) trace_io_read(reg, addr, io_buf, len) 104 + #define _trace_io_read(reg, io_buf, len) trace_io_read(reg, -1, io_buf, len) 105 + 106 + DECLARE_EVENT_CLASS(io_data32, 107 + TP_PROTO(int reg, int addr, u32 val), 108 + TP_ARGS(reg, addr, val), 109 + TP_STRUCT__entry( 110 + __field(int, reg) 111 + __field(int, addr) 112 + __field(int, val) 113 + __array(u8, addr_str, 10) 114 + ), 115 + TP_fast_assign( 116 + __entry->reg = reg; 117 + __entry->addr = addr; 118 + __entry->val = val; 119 + if (addr >= 0) 120 + snprintf(__entry->addr_str, 10, "/%08x", addr); 121 + else 122 + __entry->addr_str[0] = 0; 123 + ), 124 + TP_printk("%s%s: %08x", 125 + __print_symbolic(__entry->reg, wfx_reg_list), 126 + __entry->addr_str, 127 + __entry->val 128 + ) 129 + ); 130 + DEFINE_EVENT(io_data32, io_write32, 131 + TP_PROTO(int reg, int addr, u32 val), 132 + TP_ARGS(reg, addr, val)); 133 + #define _trace_io_ind_write32(reg, addr, val) trace_io_write32(reg, addr, val) 134 + #define _trace_io_write32(reg, val) trace_io_write32(reg, -1, val) 135 + DEFINE_EVENT(io_data32, io_read32, 136 + TP_PROTO(int reg, int addr, u32 val), 137 + TP_ARGS(reg, addr, val)); 138 + #define _trace_io_ind_read32(reg, addr, val) trace_io_read32(reg, addr, val) 139 + #define _trace_io_read32(reg, val) trace_io_read32(reg, -1, val) 140 + 141 + #endif 142 + 143 + /* This part must be outside protection */ 144 + #undef TRACE_INCLUDE_PATH 145 + #define TRACE_INCLUDE_PATH . 146 + #undef TRACE_INCLUDE_FILE 147 + #define TRACE_INCLUDE_FILE traces 148 + 149 + #include <trace/define_trace.h>