Add traces for purposed of debugging spi_hid driver.

Signed-off-by: Dmitry Antipov <[email protected]>
Signed-off-by: Angela Czubak <[email protected]>
Signed-off-by: Jingyuan Liang <[email protected]>
---
 drivers/hid/spi-hid/spi-hid-core.c |  71 -----------------
 drivers/hid/spi-hid/spi-hid-core.h |  83 ++++++++++++++++++++
 include/trace/events/spi_hid.h     | 156 +++++++++++++++++++++++++++++++++++++
 3 files changed, 239 insertions(+), 71 deletions(-)

diff --git a/drivers/hid/spi-hid/spi-hid-core.c 
b/drivers/hid/spi-hid/spi-hid-core.c
index 08865d42555f..e3273846267e 100644
--- a/drivers/hid/spi-hid/spi-hid-core.c
+++ b/drivers/hid/spi-hid/spi-hid-core.c
@@ -81,13 +81,6 @@
 #define SPI_HID_CREATE_DEVICE  4
 #define SPI_HID_ERROR  5
 
-/* Raw input buffer with data from the bus */
-struct spi_hid_input_buf {
-       u8 header[HIDSPI_INPUT_HEADER_SIZE];
-       u8 body[HIDSPI_INPUT_BODY_HEADER_SIZE];
-       u8 content[];
-};
-
 /* Processed data from input report header */
 struct spi_hid_input_header {
        u8 version;
@@ -104,12 +97,6 @@ struct spi_hid_input_report {
        u8 *content;
 };
 
-/* Raw output report buffer to be put on the bus */
-struct spi_hid_output_buf {
-       u8 header[SPI_HID_OUTPUT_HEADER_LEN];
-       u8 content[];
-};
-
 /* Data necessary to send an output report */
 struct spi_hid_output_report {
        u8 report_type;
@@ -118,19 +105,6 @@ struct spi_hid_output_report {
        u8 *content;
 };
 
-/* Processed data from a device descriptor */
-struct spi_hid_device_descriptor {
-       u16 hid_version;
-       u16 report_descriptor_length;
-       u16 max_input_length;
-       u16 max_output_length;
-       u16 max_fragment_length;
-       u16 vendor_id;
-       u16 product_id;
-       u16 version_id;
-       u8 no_output_report_ack;
-};
-
 /* struct spi_hid_conf - Conf provided to the core */
 struct spi_hid_conf {
        u32 input_report_header_address;
@@ -155,51 +129,6 @@ struct spihid_ops {
        void (*sleep_minimal_reset_delay)(struct spihid_ops *ops);
 };
 
-/* Driver context */
-struct spi_hid {
-       struct spi_device       *spi;   /* spi device. */
-       struct hid_device       *hid;   /* pointer to corresponding HID dev. */
-
-       struct spi_transfer     input_transfer[2];      /* Transfer buffer for 
read and write. */
-       struct spi_message      input_message;  /* used to execute a sequence 
of spi transfers. */
-
-       struct spihid_ops       *ops;
-       struct spi_hid_conf     *conf;
-
-       struct spi_hid_device_descriptor desc;  /* HID device descriptor. */
-       struct spi_hid_output_buf *output;      /* Output buffer. */
-       struct spi_hid_input_buf *input;        /* Input buffer. */
-       struct spi_hid_input_buf *response;     /* Response buffer. */
-
-       u16 response_length;
-       u16 bufsize;
-
-       enum hidspi_power_state power_state;
-
-       u8 reset_attempts;      /* The number of reset attempts. */
-
-       unsigned long flags;    /* device flags. */
-
-       struct work_struct reset_work;
-
-       /* Control lock to make sure one output transaction at a time. */
-       struct mutex output_lock;
-       /* Power lock to make sure one power state change at a time. */
-       struct mutex power_lock;
-       struct completion output_done;
-
-       u8 read_approval_header[SPI_HID_READ_APPROVAL_LEN];
-       u8 read_approval_body[SPI_HID_READ_APPROVAL_LEN];
-
-       u32 report_descriptor_crc32;    /* HID report descriptor crc32 
checksum. */
-
-       u32 regulator_error_count;
-       int regulator_last_error;
-       u32 bus_error_count;
-       int bus_last_error;
-       u32 dir_count;  /* device initiated reset count. */
-};
-
 static struct hid_ll_driver spi_hid_ll_driver;
 
 static void spi_hid_populate_read_approvals(const struct spi_hid_conf *conf,
diff --git a/drivers/hid/spi-hid/spi-hid-core.h 
b/drivers/hid/spi-hid/spi-hid-core.h
new file mode 100644
index 000000000000..2bfdfbe6d7fc
--- /dev/null
+++ b/drivers/hid/spi-hid/spi-hid-core.h
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 Microsoft Corporation
+ * Copyright (c) 2026 Google LLC
+ */
+
+#include <linux/hid-over-spi.h>
+#include <linux/spi/spi.h>
+
+/* Protocol message size constants */
+#define SPI_HID_READ_APPROVAL_LEN              5
+#define SPI_HID_OUTPUT_HEADER_LEN              8
+
+/* Raw input buffer with data from the bus */
+struct spi_hid_input_buf {
+       u8 header[HIDSPI_INPUT_HEADER_SIZE];
+       u8 body[HIDSPI_INPUT_BODY_HEADER_SIZE];
+       u8 content[];
+};
+
+/* Raw output report buffer to be put on the bus */
+struct spi_hid_output_buf {
+       u8 header[SPI_HID_OUTPUT_HEADER_LEN];
+       u8 content[];
+};
+
+/* Processed data from a device descriptor */
+struct spi_hid_device_descriptor {
+       u16 hid_version;
+       u16 report_descriptor_length;
+       u16 max_input_length;
+       u16 max_output_length;
+       u16 max_fragment_length;
+       u16 vendor_id;
+       u16 product_id;
+       u16 version_id;
+       u8 no_output_report_ack;
+};
+
+/* Driver context */
+struct spi_hid {
+       struct spi_device       *spi;   /* spi device. */
+       struct hid_device       *hid;   /* pointer to corresponding HID dev. */
+
+       struct spi_transfer     input_transfer[2];      /* Transfer buffer for 
read and write. */
+       struct spi_message      input_message;  /* used to execute a sequence 
of spi transfers. */
+
+       struct spihid_ops       *ops;
+       struct spi_hid_conf     *conf;
+
+       struct spi_hid_device_descriptor desc;  /* HID device descriptor. */
+       struct spi_hid_output_buf *output;      /* Output buffer. */
+       struct spi_hid_input_buf *input;        /* Input buffer. */
+       struct spi_hid_input_buf *response;     /* Response buffer. */
+
+       u16 response_length;
+       u16 bufsize;
+
+       enum hidspi_power_state power_state;
+
+       u8 reset_attempts;      /* The number of reset attempts. */
+
+       unsigned long flags;    /* device flags. */
+
+       struct work_struct reset_work;
+
+       /* Control lock to make sure one output transaction at a time. */
+       struct mutex output_lock;
+       /* Power lock to make sure one power state change at a time. */
+       struct mutex power_lock;
+       struct completion output_done;
+
+       u8 read_approval_header[SPI_HID_READ_APPROVAL_LEN];
+       u8 read_approval_body[SPI_HID_READ_APPROVAL_LEN];
+
+       u32 report_descriptor_crc32;    /* HID report descriptor crc32 
checksum. */
+
+       u32 regulator_error_count;
+       int regulator_last_error;
+       u32 bus_error_count;
+       int bus_last_error;
+       u32 dir_count;          /* device initiated reset count. */
+};
diff --git a/include/trace/events/spi_hid.h b/include/trace/events/spi_hid.h
new file mode 100644
index 000000000000..e9a579b3806c
--- /dev/null
+++ b/include/trace/events/spi_hid.h
@@ -0,0 +1,156 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2021 Microsoft Corporation
+ */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM spi_hid
+
+#if !defined(_SPI_HID_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _SPI_HID_TRACE_H
+
+#include <linux/types.h>
+#include <linux/tracepoint.h>
+
+DECLARE_EVENT_CLASS(spi_hid_transfer,
+       TP_PROTO(struct spi_hid *shid, const void *tx_buf, int tx_len,
+                const void *rx_buf, u16 rx_len, int ret),
+
+       TP_ARGS(shid, tx_buf, tx_len, rx_buf, rx_len, ret),
+
+       TP_STRUCT__entry(
+               __field(int, bus_num)
+               __field(int, chip_select)
+               __field(int, ret)
+               __dynamic_array(u8, rx_buf, rx_len)
+               __dynamic_array(u8, tx_buf, tx_len)
+       ),
+
+       TP_fast_assign(
+               __entry->bus_num = shid->spi->controller->bus_num;
+               __entry->chip_select = shid->spi->chip_select;
+               __entry->ret = ret;
+
+               memcpy(__get_dynamic_array(tx_buf), tx_buf, tx_len);
+               memcpy(__get_dynamic_array(rx_buf), rx_buf, rx_len);
+       ),
+
+       TP_printk("spi%d.%d: len=%d tx=[%*phD] rx=[%*phD] --> %d",
+                 __entry->bus_num, __entry->chip_select,
+                 __get_dynamic_array_len(tx_buf) + 
__get_dynamic_array_len(rx_buf),
+                 __get_dynamic_array_len(tx_buf), __get_dynamic_array(tx_buf),
+                 __get_dynamic_array_len(rx_buf), __get_dynamic_array(rx_buf),
+                 __entry->ret)
+);
+
+DEFINE_EVENT(spi_hid_transfer, spi_hid_input_sync,
+            TP_PROTO(struct spi_hid *shid, const void *tx_buf, int tx_len,
+                     const void *rx_buf, u16 rx_len, int ret),
+            TP_ARGS(shid, tx_buf, tx_len, rx_buf, rx_len, ret));
+
+DEFINE_EVENT(spi_hid_transfer, spi_hid_input_header_complete,
+            TP_PROTO(struct spi_hid *shid, const void *tx_buf, int tx_len,
+                     const void *rx_buf, u16 rx_len, int ret),
+            TP_ARGS(shid, tx_buf, tx_len, rx_buf, rx_len, ret));
+
+DEFINE_EVENT(spi_hid_transfer, spi_hid_input_body_complete,
+            TP_PROTO(struct spi_hid *shid, const void *tx_buf, int tx_len,
+                     const void *rx_buf, u16 rx_len, int ret),
+            TP_ARGS(shid, tx_buf, tx_len, rx_buf, rx_len, ret));
+
+DECLARE_EVENT_CLASS(spi_hid_irq,
+       TP_PROTO(struct spi_hid *shid, int irq),
+
+       TP_ARGS(shid, irq),
+
+       TP_STRUCT__entry(
+               __field(int, bus_num)
+               __field(int, chip_select)
+               __field(int, irq)
+       ),
+
+       TP_fast_assign(
+               __entry->bus_num = shid->spi->controller->bus_num;
+               __entry->chip_select = shid->spi->chip_select;
+               __entry->irq = irq;
+       ),
+
+       TP_printk("spi%d.%d: IRQ %d",
+                 __entry->bus_num, __entry->chip_select, __entry->irq)
+);
+
+DEFINE_EVENT(spi_hid_irq, spi_hid_dev_irq,
+            TP_PROTO(struct spi_hid *shid, int irq), TP_ARGS(shid, irq));
+
+DECLARE_EVENT_CLASS(spi_hid,
+       TP_PROTO(struct spi_hid *shid),
+
+       TP_ARGS(shid),
+
+       TP_STRUCT__entry(
+               __field(int, bus_num)
+               __field(int, chip_select)
+               __field(int, power_state)
+               __field(u32, flags)
+
+               __field(int, vendor_id)
+               __field(int, product_id)
+               __field(int, max_input_length)
+               __field(int, max_output_length)
+               __field(u16, hid_version)
+               __field(u16, report_descriptor_length)
+               __field(u16, version_id)
+       ),
+
+       TP_fast_assign(
+               __entry->bus_num = shid->spi->controller->bus_num;
+               __entry->chip_select = shid->spi->chip_select;
+               __entry->power_state = shid->power_state;
+               __entry->flags = shid->flags;
+
+               __entry->vendor_id = shid->desc.vendor_id;
+               __entry->product_id = shid->desc.product_id;
+               __entry->max_input_length = shid->desc.max_input_length;
+               __entry->max_output_length = shid->desc.max_output_length;
+               __entry->hid_version = shid->desc.hid_version;
+               __entry->report_descriptor_length =
+                                       shid->desc.report_descriptor_length;
+               __entry->version_id = shid->desc.version_id;
+       ),
+
+       TP_printk("spi%d.%d: (%04x:%04x v%d) HID v%d.%d state p:%d len i:%d 
o:%d r:%d flags 0x%08x",
+                 __entry->bus_num, __entry->chip_select,
+                 __entry->vendor_id, __entry->product_id, __entry->version_id,
+                 __entry->hid_version >> 8, __entry->hid_version & 0xff,
+                 __entry->power_state, __entry->max_input_length,
+                 __entry->max_output_length, __entry->report_descriptor_length,
+                 __entry->flags)
+);
+
+DEFINE_EVENT(spi_hid, spi_hid_header_transfer, TP_PROTO(struct spi_hid *shid),
+            TP_ARGS(shid));
+
+DEFINE_EVENT(spi_hid, spi_hid_process_input_report,
+            TP_PROTO(struct spi_hid *shid), TP_ARGS(shid));
+
+DEFINE_EVENT(spi_hid, spi_hid_input_report_handler,
+            TP_PROTO(struct spi_hid *shid), TP_ARGS(shid));
+
+DEFINE_EVENT(spi_hid, spi_hid_reset_response, TP_PROTO(struct spi_hid *shid),
+            TP_ARGS(shid));
+
+DEFINE_EVENT(spi_hid, spi_hid_create_device, TP_PROTO(struct spi_hid *shid),
+            TP_ARGS(shid));
+
+DEFINE_EVENT(spi_hid, spi_hid_refresh_device, TP_PROTO(struct spi_hid *shid),
+            TP_ARGS(shid));
+
+DEFINE_EVENT(spi_hid, spi_hid_response_handler, TP_PROTO(struct spi_hid *shid),
+            TP_ARGS(shid));
+
+DEFINE_EVENT(spi_hid, spi_hid_error_handler, TP_PROTO(struct spi_hid *shid),
+            TP_ARGS(shid));
+
+#endif /* _SPI_HID_TRACE_H */
+
+#include <trace/define_trace.h>

-- 
2.53.0.473.g4a7958ca14-goog


Reply via email to