From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=209.85.214.176 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1792436499; b=QD4zn6YJ495qbki6ef0hUltd9XKA179jKHgEFiAsFwHKiDiCf7W5DyPHFTBmhE5V2F+R RHOHl+SweCGvgGdBp4HaWuToyB20zTsDhW0dPrE0xZNChSmj8hi/zbkpBcnrKQJSJDCfb LAlxbh3OhrgpFbPfwcSUwrytk24THrQk+heM4r3G9tuha52XlMYTYWdjn6m/DmTAmjuz5 3y56a+NMAxNbk0UsIq4YiCDMkt+Z++PbV5RCCUHj12OFRk8gcMmcvnu6ESU9DMwOlE6Rm JWDewz4xVgySFY08Mt2/2WnO24EP7FudTuGBleEVdIjOx+Jho1NONbQ3Ionx2UNBqcQ== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1792436499; h=DMARC-Filter:Received:DKIM-Signature:X-Google-DKIM-Signature: X-Forwarded-Encrypted:X-Gm-Message-State:X-Gm-Gg:X-Received:Received: From:Date:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding: Message-Id:References:In-Reply-To:To:Cc:X-Mailer: X-Developer-Signature:X-Developer-Key; bh=OM1JZFtjmmQotINbt6oHj3VrgH0GqWedt4B5k3hFivI=; b=xrbMKxaLZBwdXeTq1/MI4r2cqWetixYFP7coT4FLBIdQoA5BZOmrViCh+YRlPitwx7ug NKdta8QnFlQFRcbyolks31T0dc//508Za8pSMwUXLlT2x/HbZp6jp/bT6mXZ2ogBlN3cL zkvN1oHKztfTZPlfODzXIsWruaG46Kf1w0UDdJdEFlII0f9tpUtJtSYWhGp8uyOHqFNOy vfKcy9hO+5BVAqNRUcpJ1wNgiDwl4RyYXwky9MwRFA30o2I31VEC2VStlzHNti3GBiNTy Sk7qMRSAAoBmmBT35WAXecExRbKJU1ioB3ekRxtkNtHVDBzR75k9+jn+bxy0YHIVZLg== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256 header.s=google header.b=JobUJgbk; arc=none smtp.remote-ip=209.85.214.176 Received: from mail-pl1-f176.google.com (mail-pl1-f176.google.com [209.85.214.176]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 531BB60A2638 for ; Mon, 19 Oct 2026 19:01:38 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.2 smtp.subspace.kernel.org 531BB60A2638 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key, unprotected) header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256 header.s=google header.b=JobUJgbk Received: by mail-pl1-f176.google.com with SMTP id d9443c01a7336-2e8f2c3ad6bso13314065ad.1 for ; Mon, 19 Oct 2026 12:01:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1792436498; x=1793041298; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=OM1JZFtjmmQotINbt6oHj3VrgH0GqWedt4B5k3hFivI=; b=JobUJgbkgtKADOUqDydLL3f5X3ffb1RJCvEIRzUY6uiHk0FrfcumS7BvwhwT4oU7Ln VhsM6/bD7Fho4iJmYXAZsz7fXLz4zTXbznt8vQrTQrbZKf1eiw15X6FVS3QN2JAuwTX4 ViX8TtTKicwDXILeGJBO8Rx/fm6qlgGqaCVTo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1792436498; x=1793041298; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=OM1JZFtjmmQotINbt6oHj3VrgH0GqWedt4B5k3hFivI=; b=PqfBO0whGoFNmWelGH3mU3uHF+0zHYWGxtQR4Nm4p2y5hHeYNsoz/ltYnSykMh6jco APRXo9roMNYEn6qVII2BRKq8xlEZiBcXbUK6e2iCGNUppd2rU298RaRPpmVzTrb5oEkN sxu49s5jW3dRhrGMXey8pmQnlbdzfrh8KF4bBlMYcQtKZjGtIXWh4M2KLalaL2RzmDB2 4z04KMwEevfwhZfIuKawgtI/w6eSNUyZ4/hhD1C27RnpWmfqsXH6aMx3h8ob4WQa5PW4 HxJJmJx1tptdMJCwzMprGkpS7cPL7N3Vgb7TxBHITAF5xVMBKPs8hhcEMQQ5b0ZBpomh Tjkw== X-Forwarded-Encrypted: i=1; AKwUvBwLayOQVHw/Lq2DL/HQGTgwN8b3CdUJg4Z3tMcExaeWnzBkICQCcJiljusA5Qi4E8neBgD0eJbFInuokbBEMwYDWQE=@vger.kernel.org X-Gm-Message-State: AFq9FYLppxTOYnAQ8PJ2i016WITa/dZccuQJy5IrUAoQB2ITfT2wUanb XtgKy3QMR/+bqTBmMHecsleI6F4VoCDwI0RnuJg2b8+Rpwn5Y/qSbu6Y1P+AqMSD3g== X-Gm-Gg: AYBFou15RJqms+O5mzvIFA3Ot85azqS28bF9oHDP9pbWzbhHvXiWBooHy/KXnCj9BN1 p0IrWYRt8I1i3s/Hml4nG5yWb9dgtA9J/JYw5dhBySmhzKTPR5dtV0sNCBoZiXqCkfaB7RdQmxG Bf7ijN89lQ+/3hNbcfISqrnEaV+78lMeISnJKSywSJxYeOzM0TJqsmk6DUywsEcl1/1USh8ol4W 7jhPzWM7wjdAkCW8fVTRQL4hs+KVOsZn6PYCBwzbv/YevwFkg8iwUfYWalZIX+Q5i307RM2edvj +P9ELG2QrNLsqvMHw1X6CGcuWkALW9iOXlxpfnmFEJT7H4qnG/4voZt7Kbq/Bul+mr9TzZhhozx UE+jDeG8O5zSlZHD/3sJUiFQPz/1lboJ0QiStaPAe9pUmUmuyTM62GYLa5VvfgHI8Pl8KnOn+Oh NKAz2mxMQcpNZixYixZYFWyxFBi1iWYW1pqjQMh32Df8XjDj9xhdO7FJsy1H/hTLelRGTARZ1KH MMwHTpWlYzSSGNX7PNdL/TIooNDGf95T9qTddfAZ65JAa3kI4xovv12dB6UIAzbNSlHUgYIoS/2 QTyjVtXwbi6TgMqcfkN0DNVL8Y9ZQ5kU3UIaLNq2YD/1NkoUqbNEvVd1e83/L4s= X-Received: by 2002:a17:902:d581:b0:2e8:3e5d:b2b7 with SMTP id d9443c01a7336-2e9a6a0c6d3mr79091235ad.40.1792436497379; Mon, 19 Oct 2026 12:01:37 -0700 (PDT) Received: from jingyliang-input-linux.c.googlers.com (218.117.230.35.bc.googleusercontent.com. [35.230.117.218]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2ea151e1b7esm4473105ad.75.2026.10.19.12.01.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Oct 2026 12:01:36 -0700 (PDT) From: Jingyuan Liang Date: Mon, 19 Oct 2026 19:01:18 +0000 Subject: [PATCH v6 06/11] HID: spi-hid: add spi_hid traces X-Mailing-List: linux-trace-kernel@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20261019-send-upstream-v6-6-cb9ba4b3d6fa@chromium.org> References: <20261019-send-upstream-v6-0-cb9ba4b3d6fa@chromium.org> In-Reply-To: <20261019-send-upstream-v6-0-cb9ba4b3d6fa@chromium.org> To: Jiri Kosina , Benjamin Tissoires , Jonathan Corbet , Mark Brown , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Dmitry Torokhov , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: linux-input@vger.kernel.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-spi@vger.kernel.org, linux-trace-kernel@vger.kernel.org, devicetree@vger.kernel.org, hbarnor@chromium.org, tfiga@chromium.org, fqwqf@fqwqf.xyz, daleyo@gmail.com, Jingyuan Liang , Dmitry Antipov , Angela Czubak X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1792436487; l=19082; i=jingyliang@chromium.org; s=20260213; h=from:subject:message-id; bh=6rUSNvy1nkhD2CciUOpqjHID+A4zkDMT7hEVtZ0vHxo=; b=WNaVowykblkw/5i5+7z3dkmdYTmUccH8kWtx3YsUYUx7jR26Mur1aZDaD7Xc2YmxQP6NMzU1D BID4bdm2g8wCN/YmiAVns+1ax/PuLar4OX/oi/r4XhuWBCfYix/2pcI X-Developer-Key: i=jingyliang@chromium.org; a=ed25519; pk=VTYSdqslTtYOjWWoIGgYoWupGWqNSidrggReKMgfPo4= Add traces for the purpose of debugging spi_hid driver. Signed-off-by: Dmitry Antipov Signed-off-by: Angela Czubak Tested-by: Dale Whinham Signed-off-by: Jingyuan Liang --- drivers/hid/spi-hid/Makefile | 1 + drivers/hid/spi-hid/spi-hid-core.c | 132 ++++++++------------------ drivers/hid/spi-hid/spi-hid-core.h | 109 +++++++++++++++++++++ drivers/hid/spi-hid/spi-hid-trace.h | 184 ++++++++++++++++++++++++++++++++++++ 4 files changed, 334 insertions(+), 92 deletions(-) diff --git a/drivers/hid/spi-hid/Makefile b/drivers/hid/spi-hid/Makefile index 92e24cddbfc2..733e006df56e 100644 --- a/drivers/hid/spi-hid/Makefile +++ b/drivers/hid/spi-hid/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_SPI_HID_CORE) += spi-hid.o spi-hid-objs = spi-hid-core.o +CFLAGS_spi-hid-core.o := -I$(src) diff --git a/drivers/hid/spi-hid/spi-hid-core.c b/drivers/hid/spi-hid/spi-hid-core.c index 90b2c2fea650..e428fae762ac 100644 --- a/drivers/hid/spi-hid/spi-hid-core.c +++ b/drivers/hid/spi-hid/spi-hid-core.c @@ -44,6 +44,11 @@ #include #include +#include "spi-hid-core.h" + +#define CREATE_TRACE_POINTS +#include "spi-hid-trace.h" + /* Protocol constants */ #define SPI_HID_READ_APPROVAL_CONSTANT 0xff #define SPI_HID_INPUT_HEADER_SYNC_BYTE 0x5a @@ -86,13 +91,6 @@ */ #define SPI_HID_STARTED 6 -/* 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; @@ -109,12 +107,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; @@ -123,19 +115,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; @@ -161,72 +140,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; - /* Response type awaited by a sync request, 0 if none. Protected by io_lock. */ - u8 expected_response; - /* Content ID of that request. Protected by io_lock. */ - u8 expected_content_id; - - enum hidspi_power_state power_state; - - u8 reset_attempts; /* The number of reset attempts. */ - - unsigned long flags; /* device flags. */ - - struct work_struct reset_work; - - /* - * Serializes request/response transactions: held from sending a - * request until its response in shid->response has been consumed. - * Taken before io_lock. - */ - struct mutex output_lock; - /* Power lock to make sure one power state change at a time. */ - struct mutex power_lock; - /* - * Serializes SPI bus transfers (output writes vs. IRQ-thread reads) and - * protects shid->expected_response, updates to shid->desc and - * publication of shid->hid. Held only briefly and never while waiting - * for a response, since the IRQ thread needs it to deliver that - * response. Nests inside output_lock. - * - * It does not keep the hid_device alive: the IRQ must be quiesced with - * disable_irq() before the hid_device is destroyed. - */ - struct mutex io_lock; - - struct completion output_done; - - 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. */ - - /* DMA-safe transfer buffers */ - u8 read_approval_header[SPI_HID_READ_APPROVAL_LEN] ____cacheline_aligned; - u8 read_approval_body[SPI_HID_READ_APPROVAL_LEN]; -}; - static struct hid_ll_driver spi_hid_ll_driver; static void spi_hid_populate_read_approvals(const struct spi_hid_conf *conf, @@ -309,6 +222,11 @@ static int spi_hid_input_sync(struct spi_hid *shid, void *buf, u16 length, spi_message_init_with_transfers(&shid->input_message, shid->input_transfer, 2); + /* rx_buf is not filled yet; received data is traced by *_complete. */ + trace_spi_hid_input_sync(shid, shid->input_transfer[0].tx_buf, + shid->input_transfer[0].len, + shid->input_transfer[1].rx_buf, 0, 0); + error = spi_sync(shid->spi, &shid->input_message); if (error) { dev_err(&shid->spi->dev, "Error starting sync transfer: %d\n", error); @@ -367,6 +285,8 @@ static void spi_hid_error_handler(struct spi_hid *shid) struct device *dev = &shid->spi->dev; int error; + trace_spi_hid_error_handler(shid); + guard(mutex)(&shid->power_lock); if (shid->power_state == HIDSPI_OFF) return; @@ -544,6 +464,8 @@ static void spi_hid_reset_response(struct spi_hid *shid) }; int error; + trace_spi_hid_reset_response(shid); + if (test_bit(SPI_HID_READY, &shid->flags)) { dev_err(dev, "Spontaneous FW reset!\n"); clear_bit(SPI_HID_READY, &shid->flags); @@ -571,6 +493,8 @@ static int spi_hid_input_report_handler(struct spi_hid *shid, int error = 0; scoped_guard(mutex, &shid->io_lock) { + trace_spi_hid_input_report_handler(shid); + if (!test_bit(SPI_HID_READY, &shid->flags) || !test_bit(SPI_HID_STARTED, &shid->flags) || test_bit(SPI_HID_REFRESH_IN_PROGRESS, &shid->flags) || !shid->hid) { @@ -673,6 +597,8 @@ static int spi_hid_response_handler(struct spi_hid *shid, } shid->expected_response = 0; + trace_spi_hid_response_handler(shid); + shid->response_length = body->content_length; if (body->report_type == REPORT_DESCRIPTOR_RESPONSE || body->report_type == GET_FEATURE_RESPONSE) { @@ -736,6 +662,8 @@ static int spi_hid_create_device(struct spi_hid *shid) struct device *dev = &shid->spi->dev; int error; + trace_spi_hid_create_device(shid); + hid = hid_allocate_device(); error = PTR_ERR_OR_ZERO(hid); if (error) { @@ -780,6 +708,8 @@ static void spi_hid_refresh_device(struct spi_hid *shid) u32 new_crc32 = 0; int error = 0; + trace_spi_hid_refresh_device(shid); + /* Keep shid->response stable until the CRC is computed. */ scoped_guard(mutex, &shid->output_lock) { error = spi_hid_report_descriptor_request(shid); @@ -868,6 +798,8 @@ static int spi_hid_process_input_report(struct spi_hid *shid, struct spi_hid_input_report body; struct device *dev = &shid->spi->dev; + trace_spi_hid_process_input_report(shid); + spi_hid_populate_input_header(buf->header, &header); spi_hid_input_report_prepare(buf, &body); @@ -1039,6 +971,9 @@ static irqreturn_t spi_hid_dev_irq(int irq, void *_shid) struct spi_hid_input_header header; int error = 0; + trace_spi_hid_dev_irq(shid, irq); + trace_spi_hid_header_transfer(shid); + scoped_guard(mutex, &shid->io_lock) { if (shid->power_state == HIDSPI_OFF) { dev_warn(dev, "Device is off, ignoring interrupt\n"); @@ -1052,6 +987,13 @@ static irqreturn_t spi_hid_dev_irq(int irq, void *_shid) return spi_hid_irq_error(shid); } + trace_spi_hid_input_header_complete(shid, + shid->input_transfer[0].tx_buf, + shid->input_transfer[0].len, + shid->input_transfer[1].rx_buf, + shid->input_transfer[1].len, + shid->input_message.status); + if (shid->input_message.status < 0) { dev_warn(dev, "Error reading header: %d\n", shid->input_message.status); @@ -1083,6 +1025,12 @@ static irqreturn_t spi_hid_dev_irq(int irq, void *_shid) return spi_hid_irq_error(shid); } + trace_spi_hid_input_body_complete(shid, shid->input_transfer[0].tx_buf, + shid->input_transfer[0].len, + shid->input_transfer[1].rx_buf, + shid->input_transfer[1].len, + shid->input_message.status); + if (shid->input_message.status < 0) { dev_warn(dev, "Error reading body: %d\n", shid->input_message.status); 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..1d8356f787f3 --- /dev/null +++ b/drivers/hid/spi-hid/spi-hid-core.h @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (c) 2021 Microsoft Corporation + * Copyright (c) 2026 Google LLC + */ + +#ifndef SPI_HID_CORE_H +#define SPI_HID_CORE_H + +#include +#include + +/* 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; + /* Response type awaited by a sync request, 0 if none. Protected by io_lock. */ + u8 expected_response; + /* Content ID of that request. Protected by io_lock. */ + u8 expected_content_id; + + enum hidspi_power_state power_state; + + u8 reset_attempts; /* The number of reset attempts. */ + + unsigned long flags; /* device flags. */ + + struct work_struct reset_work; + + /* + * Serializes request/response transactions: held from sending a + * request until its response in shid->response has been consumed. + * Taken before io_lock. + */ + struct mutex output_lock; + /* Power lock to make sure one power state change at a time. */ + struct mutex power_lock; + /* + * Serializes SPI bus transfers (output writes vs. IRQ-thread reads) and + * protects shid->expected_response, updates to shid->desc and + * publication of shid->hid. Held only briefly and never while waiting + * for a response, since the IRQ thread needs it to deliver that + * response. Nests inside output_lock. + * + * It does not keep the hid_device alive: the IRQ must be quiesced with + * disable_irq() before the hid_device is destroyed. + */ + struct mutex io_lock; + + struct completion output_done; + + 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. */ + + /* DMA-safe transfer buffers */ + u8 read_approval_header[SPI_HID_READ_APPROVAL_LEN] ____cacheline_aligned; + u8 read_approval_body[SPI_HID_READ_APPROVAL_LEN]; +}; + +#endif /* SPI_HID_CORE_H */ diff --git a/drivers/hid/spi-hid/spi-hid-trace.h b/drivers/hid/spi-hid/spi-hid-trace.h new file mode 100644 index 000000000000..a36e07b95001 --- /dev/null +++ b/drivers/hid/spi-hid/spi-hid-trace.h @@ -0,0 +1,184 @@ +/* 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 +#include +#include "spi-hid-core.h" + +/* + * Maximum number of tx/rx bytes copied into the ring buffer per event. This + * matches the most %*ph will print, keeps events small, and ensures the copy + * never depends on the caller-supplied length fitting inside the buffer. + */ +#define SPI_HID_TRACE_BUF_MAX 64 + +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) + __field(int, tx_len) + __field(u16, rx_len) + __dynamic_array(u8, rx_buf, + min_t(u16, rx_len, SPI_HID_TRACE_BUF_MAX)) + __dynamic_array(u8, tx_buf, + min_t(int, tx_len, SPI_HID_TRACE_BUF_MAX)) + ), + + TP_fast_assign( + __entry->bus_num = shid->spi->controller->bus_num; + __entry->chip_select = spi_get_chipselect(shid->spi, 0); + __entry->ret = ret; + __entry->tx_len = tx_len; + __entry->rx_len = rx_len; + + memcpy(__get_dynamic_array(tx_buf), tx_buf, + __get_dynamic_array_len(tx_buf)); + memcpy(__get_dynamic_array(rx_buf), rx_buf, + __get_dynamic_array_len(rx_buf)); + ), + + TP_printk("spi%d.%d: len=%d tx=[%*phD] rx=[%*phD] --> %d", + __entry->bus_num, __entry->chip_select, + __entry->tx_len + __entry->rx_len, + __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 = spi_get_chipselect(shid->spi, 0); + __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 = spi_get_chipselect(shid->spi, 0); + __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 */ + +/* + * The following must be outside the protection of the above #if block. + */ +#undef TRACE_INCLUDE_PATH +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_PATH . + +/* + * It is required that the TRACE_INCLUDE_FILE be the same + * as this file without the ".h". + */ +#define TRACE_INCLUDE_FILE spi-hid-trace +#include -- 2.56.0.212.g129ede20d9-goog