1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
6 #include <linux/coresight.h>
7 #include <linux/kernel.h>
8 #include <linux/module.h>
10 #include <linux/platform_device.h>
11 #include <linux/pm_runtime.h>
13 #include "coresight-priv.h"
15 struct dummy_drvdata
{
17 struct coresight_device
*csdev
;
20 DEFINE_CORESIGHT_DEVLIST(source_devs
, "dummy_source");
21 DEFINE_CORESIGHT_DEVLIST(sink_devs
, "dummy_sink");
23 static int dummy_source_enable(struct coresight_device
*csdev
,
24 struct perf_event
*event
, enum cs_mode mode
,
25 __maybe_unused
struct coresight_trace_id_map
*id_map
)
27 if (!coresight_take_mode(csdev
, mode
))
30 dev_dbg(csdev
->dev
.parent
, "Dummy source enabled\n");
35 static void dummy_source_disable(struct coresight_device
*csdev
,
36 struct perf_event
*event
)
38 coresight_set_mode(csdev
, CS_MODE_DISABLED
);
39 dev_dbg(csdev
->dev
.parent
, "Dummy source disabled\n");
42 static int dummy_sink_enable(struct coresight_device
*csdev
, enum cs_mode mode
,
45 dev_dbg(csdev
->dev
.parent
, "Dummy sink enabled\n");
50 static int dummy_sink_disable(struct coresight_device
*csdev
)
52 dev_dbg(csdev
->dev
.parent
, "Dummy sink disabled\n");
57 static const struct coresight_ops_source dummy_source_ops
= {
58 .enable
= dummy_source_enable
,
59 .disable
= dummy_source_disable
,
62 static const struct coresight_ops dummy_source_cs_ops
= {
63 .source_ops
= &dummy_source_ops
,
66 static const struct coresight_ops_sink dummy_sink_ops
= {
67 .enable
= dummy_sink_enable
,
68 .disable
= dummy_sink_disable
,
71 static const struct coresight_ops dummy_sink_cs_ops
= {
72 .sink_ops
= &dummy_sink_ops
,
75 static int dummy_probe(struct platform_device
*pdev
)
77 struct device
*dev
= &pdev
->dev
;
78 struct device_node
*node
= dev
->of_node
;
79 struct coresight_platform_data
*pdata
;
80 struct dummy_drvdata
*drvdata
;
81 struct coresight_desc desc
= { 0 };
83 if (of_device_is_compatible(node
, "arm,coresight-dummy-source")) {
85 desc
.name
= coresight_alloc_device_name(&source_devs
, dev
);
89 desc
.type
= CORESIGHT_DEV_TYPE_SOURCE
;
90 desc
.subtype
.source_subtype
=
91 CORESIGHT_DEV_SUBTYPE_SOURCE_OTHERS
;
92 desc
.ops
= &dummy_source_cs_ops
;
93 } else if (of_device_is_compatible(node
, "arm,coresight-dummy-sink")) {
94 desc
.name
= coresight_alloc_device_name(&sink_devs
, dev
);
98 desc
.type
= CORESIGHT_DEV_TYPE_SINK
;
99 desc
.subtype
.sink_subtype
= CORESIGHT_DEV_SUBTYPE_SINK_DUMMY
;
100 desc
.ops
= &dummy_sink_cs_ops
;
102 dev_err(dev
, "Device type not set\n");
106 pdata
= coresight_get_platform_data(dev
);
108 return PTR_ERR(pdata
);
109 pdev
->dev
.platform_data
= pdata
;
111 drvdata
= devm_kzalloc(dev
, sizeof(*drvdata
), GFP_KERNEL
);
115 drvdata
->dev
= &pdev
->dev
;
116 platform_set_drvdata(pdev
, drvdata
);
118 desc
.pdata
= pdev
->dev
.platform_data
;
119 desc
.dev
= &pdev
->dev
;
120 drvdata
->csdev
= coresight_register(&desc
);
121 if (IS_ERR(drvdata
->csdev
))
122 return PTR_ERR(drvdata
->csdev
);
124 pm_runtime_enable(dev
);
125 dev_dbg(dev
, "Dummy device initialized\n");
130 static void dummy_remove(struct platform_device
*pdev
)
132 struct dummy_drvdata
*drvdata
= platform_get_drvdata(pdev
);
133 struct device
*dev
= &pdev
->dev
;
135 pm_runtime_disable(dev
);
136 coresight_unregister(drvdata
->csdev
);
139 static const struct of_device_id dummy_match
[] = {
140 {.compatible
= "arm,coresight-dummy-source"},
141 {.compatible
= "arm,coresight-dummy-sink"},
145 static struct platform_driver dummy_driver
= {
146 .probe
= dummy_probe
,
147 .remove_new
= dummy_remove
,
149 .name
= "coresight-dummy",
150 .of_match_table
= dummy_match
,
154 module_platform_driver(dummy_driver
);
156 MODULE_LICENSE("GPL");
157 MODULE_DESCRIPTION("CoreSight dummy driver");