[PATCH -next 2/4] spi: mockup: Add writeable tracepoint for spi transfer

From: Wei Yongjun
Date: Fri Aug 26 2022 - 10:26:10 EST


Add writeable tracepoint for transfer_one_message(), then bpf program can
be used to control read and write data from spi master, as mockup chip's
expectation.

For example:

#include "vmlinux.h"
#include <bpf/bpf_helpers.h>
#include <bpf/bpf_tracing.h>

SEC("raw_tp.w/spi_transfer_writeable")
int BPF_PROG(spi_transfer_writeable_test, struct spi_msg_ctx *msg,
u8 chip, unsigned int len, u8 tx_nbits, u8 rx_nbits)
{
if (tx_nbits)
msg->data[0] = 0x20;

return 0;
}

char LICENSE[] SEC("license") = "GPL";

This will be useful for writing spi device mockup backend.

Signed-off-by: Wei Yongjun <weiyongjun1@xxxxxxxxxx>
---
drivers/spi/Kconfig | 1 +
drivers/spi/spi-mockup.c | 50 +++++++++++++++++++++++++++++--
include/linux/spi/spi-mockup.h | 13 ++++++++
include/trace/events/spi_mockup.h | 32 ++++++++++++++++++++
4 files changed, 94 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index b58a1bd7999d..e0f0fa2746ad 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -1161,6 +1161,7 @@ config SPI_TLE62X0
config SPI_MOCKUP
tristate "SPI controller Testing Driver"
depends on OF
+ select BPF_EVENTS
help
This enables SPI controller testing driver, which provides a way to
test SPI subsystem.
diff --git a/drivers/spi/spi-mockup.c b/drivers/spi/spi-mockup.c
index 06cf9d122d64..7a93b194ee53 100644
--- a/drivers/spi/spi-mockup.c
+++ b/drivers/spi/spi-mockup.c
@@ -13,6 +13,9 @@
#include <linux/platform_device.h>
#include <linux/spi/spi.h>

+#define CREATE_TRACE_POINTS
+#include <trace/events/spi_mockup.h>
+
#define MOCKUP_CHIPSELECT_MAX 8

struct mockup_spi {
@@ -149,13 +152,56 @@ static struct attribute *spi_mockup_attrs[] = {
};
ATTRIBUTE_GROUPS(spi_mockup);

+static int spi_mockup_transfer_writeable(struct spi_master *master,
+ struct spi_message *msg)
+{
+ struct spi_msg_ctx *ctx;
+ struct spi_transfer *t;
+ int ret = 0;
+
+ ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC);
+ if (!ctx)
+ return -ENOMEM;
+
+ list_for_each_entry(t, &msg->transfers, transfer_list) {
+ if (t->len > SPI_BUFSIZ_MAX)
+ return -E2BIG;
+
+ memset(ctx, 0, sizeof(*ctx));
+
+ if (t->tx_nbits)
+ memcpy(ctx->data, t->tx_buf, t->len);
+
+ trace_spi_transfer_writeable(ctx, msg->spi->chip_select, t->len,
+ t->tx_nbits, t->rx_nbits);
+
+ if (ctx->ret) {
+ ret = ctx->ret;
+ break;
+ }
+
+ if (t->rx_nbits)
+ memcpy(t->rx_buf, ctx->data, t->len);
+ msg->actual_length += t->len;
+ }
+
+ kfree(ctx);
+
+ return ret;
+}
+
static int spi_mockup_transfer(struct spi_master *master,
struct spi_message *msg)
{
- msg->status = 0;
+ int ret = 0;
+
+ if (trace_spi_transfer_writeable_enabled())
+ ret = spi_mockup_transfer_writeable(master, msg);
+
+ msg->status = ret;
spi_finalize_current_message(master);

- return 0;
+ return ret;
}

static int spi_mockup_probe(struct platform_device *pdev)
diff --git a/include/linux/spi/spi-mockup.h b/include/linux/spi/spi-mockup.h
new file mode 100644
index 000000000000..6a4fe88cb376
--- /dev/null
+++ b/include/linux/spi/spi-mockup.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __LINUX_SPI_MOCKUP_H
+#define __LINUX_SPI_MOCKUP_H
+
+#define SPI_BUFSIZ_MAX 0x1000
+
+struct spi_msg_ctx {
+ int ret;
+ __u8 data[SPI_BUFSIZ_MAX];
+};
+
+#endif
diff --git a/include/trace/events/spi_mockup.h b/include/trace/events/spi_mockup.h
new file mode 100644
index 000000000000..193302f8627a
--- /dev/null
+++ b/include/trace/events/spi_mockup.h
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * SPI mockup controller transfer writeable tracepoint
+ *
+ * Copyright(c) 2022 Huawei Technologies Co., Ltd.
+ */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM spi_mockup
+
+#if !defined(_TRACE_SPI_MOCKUP_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_SPI_MOCKUP_H
+
+#include <linux/tracepoint.h>
+#include <linux/spi/spi-mockup.h>
+
+#ifndef DECLARE_TRACE_WRITABLE
+#define DECLARE_TRACE_WRITABLE(call, proto, args, size) \
+ DECLARE_TRACE(call, PARAMS(proto), PARAMS(args))
+#endif
+
+DECLARE_TRACE_WRITABLE(spi_transfer_writeable,
+ TP_PROTO(struct spi_msg_ctx *msg, u8 chip_select, unsigned int len,
+ u8 tx_nbits, u8 rx_nbits),
+ TP_ARGS(msg, chip_select, len, tx_nbits, rx_nbits),
+ sizeof(struct spi_msg_ctx)
+);
+
+#endif /* _TRACE_SPI_MOCKUP_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
--
2.34.1