[PATCH RFC 07/12] rvtrace: Add pre-ratified trace funnel driver

From: Eric Lin

Date: Tue Jun 30 2026 - 05:55:52 EST


Add the initial implementation to support the pre-ratified RISC-V
trace funnel. This implementation provides basic functionality to
enable the trace funnel, configure its next sink when tracing starts,
and disable the funnel when tracing stops.

Co-developed-by: Nick Hu <nick.hu@xxxxxxxxxx>
Signed-off-by: Nick Hu <nick.hu@xxxxxxxxxx>
Co-developed-by: Vincent Chen <vincent.chen@xxxxxxxxxx>
Signed-off-by: Vincent Chen <vincent.chen@xxxxxxxxxx>
Signed-off-by: Eric Lin <eric.lin@xxxxxxxxxx>
---
drivers/hwtracing/rvtrace/Kconfig | 7 ++
drivers/hwtracing/rvtrace/Makefile | 1 +
drivers/hwtracing/rvtrace/rvtrace-funnel.c | 108 +++++++++++++++++++++++++++++
3 files changed, 116 insertions(+)

diff --git a/drivers/hwtracing/rvtrace/Kconfig b/drivers/hwtracing/rvtrace/Kconfig
index 5e84a3d0b633..f684ad0d8c3f 100644
--- a/drivers/hwtracing/rvtrace/Kconfig
+++ b/drivers/hwtracing/rvtrace/Kconfig
@@ -23,6 +23,13 @@ config RVTRACE_ENCODER
help
This driver provides support for RISC-V Trace Encoder component.

+config RVTRACE_FUNNEL
+ tristate "RISC-V Trace Funnel driver"
+ depends on RVTRACE
+ default y
+ help
+ This driver provides support for RISC-V Trace Funnel component.
+
config RVTRACE_RAMSINK
tristate "RISC-V Trace Ramsink driver"
depends on RVTRACE
diff --git a/drivers/hwtracing/rvtrace/Makefile b/drivers/hwtracing/rvtrace/Makefile
index 51b292b1b4c4..573709f9b2e3 100644
--- a/drivers/hwtracing/rvtrace/Makefile
+++ b/drivers/hwtracing/rvtrace/Makefile
@@ -5,3 +5,4 @@ obj-$(CONFIG_RVTRACE) += rvtrace.o
rvtrace-y := rvtrace-core.o rvtrace-platform.o rvtrace-perf.o
obj-$(CONFIG_RVTRACE_ENCODER) += rvtrace-encoder.o
obj-$(CONFIG_RVTRACE_RAMSINK) += rvtrace-ramsink.o
+obj-$(CONFIG_RVTRACE_FUNNEL) += rvtrace-funnel.o
diff --git a/drivers/hwtracing/rvtrace/rvtrace-funnel.c b/drivers/hwtracing/rvtrace/rvtrace-funnel.c
new file mode 100644
index 000000000000..2bf553a88d98
--- /dev/null
+++ b/drivers/hwtracing/rvtrace/rvtrace-funnel.c
@@ -0,0 +1,108 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2026 SiFive Inc.
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/rvtrace.h>
+#include <linux/types.h>
+#include "rvtrace-v0.h"
+
+static int rvtrace_funnel_start(struct rvtrace_path_node *node)
+{
+ struct rvtrace_component *comp = node->comp;
+ u32 comp_maj;
+ int ret;
+
+ /* Set pre-ratified comp's next sink */
+ comp_maj = rvtrace_component_version_major(comp->id.version);
+ if (comp_maj == 0) {
+ ret = rvtrace_v0_sink_config(node);
+ if (ret) {
+ dev_err(&comp->dev, "failed to set next sink.\n");
+ return ret;
+ }
+ } else if (comp_maj > 0) {
+ return -EOPNOTSUPP;
+ }
+
+ ret = rvtrace_enable_component(comp->pdata);
+ if (ret)
+ return dev_err_probe(&comp->dev, ret, "failed to enable funnel.\n");
+
+ return 0;
+}
+
+static int rvtrace_funnel_stop(struct rvtrace_component *comp)
+{
+ u32 comp_maj;
+ int ret;
+
+ comp_maj = rvtrace_component_version_major(comp->id.version);
+ if (comp_maj > 0)
+ return -EOPNOTSUPP;
+
+ ret = rvtrace_disable_component(comp->pdata);
+ if (ret)
+ return dev_err_probe(&comp->dev, ret, "failed to disable funnel.\n");
+
+ return rvtrace_comp_poll_empty(comp);
+}
+
+static int rvtrace_funnel_probe(struct rvtrace_component *comp)
+{
+ struct fwnode_handle *fwnode = dev_fwnode(comp->pdata->dev);
+ int ret;
+
+ ret = rvtrace_enable_component(comp->pdata);
+ if (ret)
+ return dev_err_probe(&comp->dev, ret, "failed to enable funnel.\n");
+
+ dev_info(&comp->dev, "%s is available\n", fwnode_get_name(fwnode));
+
+ return 0;
+}
+
+static void rvtrace_funnel_remove(struct rvtrace_component *comp)
+{
+ int ret;
+
+ ret = rvtrace_disable_component(comp->pdata);
+ if (ret)
+ dev_err(&comp->dev, "failed to disable funnel.\n");
+}
+
+static struct rvtrace_component_id rvtrace_funnel_ids[] = {
+ { .type = RVTRACE_COMPONENT_TYPE_FUNNEL,
+ .version = rvtrace_component_mkversion(0, 0), },
+ {},
+};
+
+static struct rvtrace_driver rvtrace_funnel_driver = {
+ .id_table = rvtrace_funnel_ids,
+ .start = rvtrace_funnel_start,
+ .stop = rvtrace_funnel_stop,
+ .probe = rvtrace_funnel_probe,
+ .remove = rvtrace_funnel_remove,
+ .driver = {
+ .name = "rvtrace-funnel",
+ },
+};
+
+static int __init rvtrace_funnel_init(void)
+{
+ return rvtrace_register_driver(&rvtrace_funnel_driver);
+}
+
+static void __exit rvtrace_funnel_exit(void)
+{
+ rvtrace_unregister_driver(&rvtrace_funnel_driver);
+}
+
+module_init(rvtrace_funnel_init);
+module_exit(rvtrace_funnel_exit);
+
+/* Module information */
+MODULE_DESCRIPTION("RISC-V Trace Funnel Driver");
+MODULE_LICENSE("GPL");

--
2.34.1