[PATCH RFC 03/12] rvtrace: Add pre-ratified private data callback

Eric Lin eric.lin at sifive.com
Tue Jun 30 02:46:26 PDT 2026


For pre-ratified trace hardware, a trace component might support
different trace sinks, and its trace sink availability information
is embedded within the implementation register.

Introduce a get_data() callback function in 'struct rvtrace_driver_data'
to retrieve the component's supported trace sink features and store
this information in the component's private data. This allows the driver
to access the pre-ratified hardware capabilities during setup.

Co-developed-by: Nick Hu <nick.hu at sifive.com>
Signed-off-by: Nick Hu <nick.hu at sifive.com>
Co-developed-by: Vincent Chen <vincent.chen at sifive.com>
Signed-off-by: Vincent Chen <vincent.chen at sifive.com>
Signed-off-by: Eric Lin <eric.lin at sifive.com>
---
 drivers/hwtracing/rvtrace/rvtrace-core.c     |  4 +++-
 drivers/hwtracing/rvtrace/rvtrace-platform.c | 11 ++++++++++-
 drivers/hwtracing/rvtrace/rvtrace-v0.c       | 20 ++++++++++++++++++++
 drivers/hwtracing/rvtrace/rvtrace-v0.h       | 21 +++++++++++++++++++++
 include/linux/rvtrace.h                      |  4 +++-
 5 files changed, 57 insertions(+), 3 deletions(-)

diff --git a/drivers/hwtracing/rvtrace/rvtrace-core.c b/drivers/hwtracing/rvtrace/rvtrace-core.c
index 58454e9ddb4e..51546cbcc6ad 100644
--- a/drivers/hwtracing/rvtrace/rvtrace-core.c
+++ b/drivers/hwtracing/rvtrace/rvtrace-core.c
@@ -368,7 +368,8 @@ static void rvtrace_component_release(struct device *dev)
 
 struct rvtrace_component *rvtrace_register_component(enum rvtrace_component_type type,
 						     u32 version,
-						     struct rvtrace_platform_data *pdata)
+						     struct rvtrace_platform_data *pdata,
+						     void *data)
 {
 	struct rvtrace_connection *conn;
 	struct rvtrace_component *comp;
@@ -413,6 +414,7 @@ struct rvtrace_component *rvtrace_register_component(enum rvtrace_component_type
 	comp->pdata = pdata;
 	comp->id.type = type;
 	comp->id.version = version;
+	comp->id.data = data;
 	ret = rvtrace_alloc_type_idx(comp);
 	if (ret) {
 		kfree(comp);
diff --git a/drivers/hwtracing/rvtrace/rvtrace-platform.c b/drivers/hwtracing/rvtrace/rvtrace-platform.c
index 6cf8e7dae2ad..8d2b03668c2a 100644
--- a/drivers/hwtracing/rvtrace/rvtrace-platform.c
+++ b/drivers/hwtracing/rvtrace/rvtrace-platform.c
@@ -122,6 +122,7 @@ static int rvtrace_platform_probe(struct platform_device *pdev)
 	u32 impl, type, major, minor;
 	struct device_node *node;
 	struct resource *res;
+	void *data = NULL;
 	int ret;
 
 	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
@@ -168,6 +169,11 @@ static int rvtrace_platform_probe(struct platform_device *pdev)
 	if (driver_data) {
 		if (driver_data->get_impl)
 			impl = driver_data->get_impl(pdata);
+		if (driver_data->get_data) {
+			data = driver_data->get_data(pdata);
+			if (IS_ERR(data))
+				return PTR_ERR(data);
+		}
 	} else {
 		impl = rvtrace_read32(pdata, RVTRACE_COMPONENT_IMPL_OFFSET);
 	}
@@ -179,7 +185,8 @@ static int rvtrace_platform_probe(struct platform_device *pdev)
 	minor = (impl >> RVTRACE_COMPONENT_IMPL_VERMINOR_SHIFT) &
 		RVTRACE_COMPONENT_IMPL_VERMINOR_MASK;
 
-	comp = rvtrace_register_component(type, rvtrace_component_mkversion(major, minor), pdata);
+	comp = rvtrace_register_component(type, rvtrace_component_mkversion(major, minor),
+					  pdata, data);
 	if (IS_ERR(comp))
 		return PTR_ERR(comp);
 
@@ -205,10 +212,12 @@ static void rvtrace_platform_remove(struct platform_device *pdev)
 
 static const struct rvtrace_driver_data rvtrace_v0_encoder_data = {
 	.get_impl = rvtrace_v0_get_encoder_impl,
+	.get_data = rvtrace_v0_get_comp_data,
 };
 
 static const struct rvtrace_driver_data rvtrace_v0_funnel_data = {
 	.get_impl = rvtrace_v0_get_funnel_impl,
+	.get_data = rvtrace_v0_get_comp_data,
 };
 
 static const struct of_device_id rvtrace_platform_match[] = {
diff --git a/drivers/hwtracing/rvtrace/rvtrace-v0.c b/drivers/hwtracing/rvtrace/rvtrace-v0.c
index 825de1120c8d..bed35f631390 100644
--- a/drivers/hwtracing/rvtrace/rvtrace-v0.c
+++ b/drivers/hwtracing/rvtrace/rvtrace-v0.c
@@ -6,6 +6,26 @@
 #include <linux/rvtrace.h>
 #include "rvtrace-v0.h"
 
+void *rvtrace_v0_get_comp_data(struct rvtrace_platform_data *pdata)
+{
+	struct rvtrace_v0_comp_features	*data;
+	u32 impl;
+
+	data = devm_kzalloc(pdata->dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return ERR_PTR(-ENOMEM);
+
+	impl = rvtrace_read32(pdata, RVTRACE_COMPONENT_IMPL_OFFSET);
+
+	data->has_sram_sink = impl & RVTRACE_V0_IMPL_HAS_SRAM_SINK_MASK;
+	data->has_atb_sink = impl & RVTRACE_V0_IMPL_HAS_ATB_SINK_MASK;
+	data->has_pib_sink = impl & RVTRACE_V0_IMPL_HAS_PIB_SINK_MASK;
+	data->has_sba_sink = impl & RVTRACE_V0_IMPL_HAS_SBA_SINK_MASK;
+	data->has_funnel_sink = impl & RVTRACE_V0_IMPL_HAS_FUNNEL_SINK_MASK;
+
+	return data;
+}
+
 static u32 rvtrace_v0_get_impl(struct rvtrace_platform_data *pdata, u32 type)
 {
 	u32 impl, major, minor;
diff --git a/drivers/hwtracing/rvtrace/rvtrace-v0.h b/drivers/hwtracing/rvtrace/rvtrace-v0.h
index 511aa6489caa..562d3a77c513 100644
--- a/drivers/hwtracing/rvtrace/rvtrace-v0.h
+++ b/drivers/hwtracing/rvtrace/rvtrace-v0.h
@@ -9,8 +9,29 @@
 
 #include <linux/rvtrace.h>
 
+#define RVTRACE_V0_IMPL_HAS_SRAM_SINK_BIT	4
+#define RVTRACE_V0_IMPL_HAS_ATB_SINK_BIT	5
+#define RVTRACE_V0_IMPL_HAS_PIB_SINK_BIT	6
+#define RVTRACE_V0_IMPL_HAS_SBA_SINK_BIT	7
+#define RVTRACE_V0_IMPL_HAS_FUNNEL_SINK_BIT	8
+
+#define RVTRACE_V0_IMPL_HAS_SRAM_SINK_MASK	BIT(RVTRACE_V0_IMPL_HAS_SRAM_SINK_BIT)
+#define RVTRACE_V0_IMPL_HAS_ATB_SINK_MASK	BIT(RVTRACE_V0_IMPL_HAS_ATB_SINK_BIT)
+#define RVTRACE_V0_IMPL_HAS_PIB_SINK_MASK	BIT(RVTRACE_V0_IMPL_HAS_PIB_SINK_BIT)
+#define RVTRACE_V0_IMPL_HAS_SBA_SINK_MASK	BIT(RVTRACE_V0_IMPL_HAS_SBA_SINK_BIT)
+#define RVTRACE_V0_IMPL_HAS_FUNNEL_SINK_MASK	BIT(RVTRACE_V0_IMPL_HAS_FUNNEL_SINK_BIT)
+
+struct rvtrace_v0_comp_features {
+	bool has_sram_sink;
+	bool has_atb_sink;
+	bool has_pib_sink;
+	bool has_sba_sink;
+	bool has_funnel_sink;
+};
+
 u32 rvtrace_v0_get_encoder_impl(struct rvtrace_platform_data *pdata);
 u32 rvtrace_v0_get_funnel_impl(struct rvtrace_platform_data *pdata);
+void *rvtrace_v0_get_comp_data(struct rvtrace_platform_data *pdata);
 
 #endif /* __RVTRACE_V0_H__ */
 
diff --git a/include/linux/rvtrace.h b/include/linux/rvtrace.h
index fdf6115d7f06..9f1afcfd83e6 100644
--- a/include/linux/rvtrace.h
+++ b/include/linux/rvtrace.h
@@ -160,6 +160,7 @@ struct rvtrace_platform_data {
  */
 struct rvtrace_driver_data {
 	u32 (*get_impl)(struct rvtrace_platform_data *pdata);
+	void *(*get_data)(struct rvtrace_platform_data *pdata);
 };
 
 static inline u32 rvtrace_read32(struct rvtrace_platform_data *pdata, u32 offset)
@@ -263,7 +264,8 @@ struct rvtrace_component *rvtrace_cpu_source(unsigned int cpu);
 
 struct rvtrace_component *rvtrace_register_component(enum rvtrace_component_type type,
 						     u32 version,
-						     struct rvtrace_platform_data *pdata);
+						     struct rvtrace_platform_data *pdata,
+						     void *data);
 void rvtrace_unregister_component(struct rvtrace_component *comp);
 
 /**

-- 
2.34.1




More information about the linux-riscv mailing list