Skip to content

Commit 25e7ede

Browse files
committed
Merge tag 'coresight-next-v6.14' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/coresight/linux into char-misc-next
Pull coresight updates from Suzuki: coresight: Updates for Linux v6.14 Coresight self-hosted tracing subsystem updates for v6.14 includes: - Support for static traceid allocation for devices - Support for impdef, static trace filtering in Qualcomm replicators - Miscellaneous fixes Signed-off-by: Suzuki K Poulose <[email protected]> * tag 'coresight-next-v6.14' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/coresight/linux: coresight-tpda: Optimize the function of reading element size coresight: Add support for trace filtering by source coresight: Add a helper to check if a device is source dt-bindings: arm: qcom,coresight-static-replicator: Add property for source filtering coresight: Fix dsb_mode_store() unsigned val is never less than zero coresight: dummy: Add static trace id support for dummy source coresight: Add support to get static id for system trace sources dt-bindings: arm: Add arm,static-trace-id for coresight dummy source coresight: Drop atomics in connection refcounts Coresight: Narrow down the matching range of tpdm
2 parents e966eae + 56e14a2 commit 25e7ede

13 files changed

+309
-59
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
What: /sys/bus/coresight/devices/dummy_source<N>/enable_source
2+
Date: Dec 2024
3+
KernelVersion: 6.14
4+
Contact: Mao Jinlong <[email protected]>
5+
Description: (RW) Enable/disable tracing of dummy source. A sink should be activated
6+
before enabling the source. The path of coresight components linking
7+
the source to the sink is configured and managed automatically by the
8+
coresight framework.
9+
10+
What: /sys/bus/coresight/devices/dummy_source<N>/traceid
11+
Date: Dec 2024
12+
KernelVersion: 6.14
13+
Contact: Mao Jinlong <[email protected]>
14+
Description: (R) Show the trace ID that will appear in the trace stream
15+
coming from this trace entity.

Documentation/devicetree/bindings/arm/arm,coresight-dummy-source.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ properties:
3838
enum:
3939
- arm,coresight-dummy-source
4040

41+
arm,static-trace-id:
42+
description: If dummy source needs static id support, use this to set trace id.
43+
$ref: /schemas/types.yaml#/definitions/uint32
44+
minimum: 1
45+
maximum: 111
46+
4147
out-ports:
4248
$ref: /schemas/graph.yaml#/properties/ports
4349

Documentation/devicetree/bindings/arm/arm,coresight-static-replicator.yaml

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,22 @@ properties:
4545
patternProperties:
4646
'^port@[01]$':
4747
description: Output connections to CoreSight Trace bus
48-
$ref: /schemas/graph.yaml#/properties/port
48+
$ref: /schemas/graph.yaml#/$defs/port-base
49+
unevaluatedProperties: false
50+
51+
properties:
52+
endpoint:
53+
$ref: /schemas/graph.yaml#/$defs/endpoint-base
54+
unevaluatedProperties: false
55+
56+
properties:
57+
filter-source:
58+
$ref: /schemas/types.yaml#/definitions/phandle
59+
description:
60+
phandle to the coresight trace source device matching the
61+
hard coded filtering for this port
62+
63+
remote-endpoint: true
4964

5065
required:
5166
- compatible
@@ -72,13 +87,15 @@ examples:
7287
reg = <0>;
7388
replicator_out_port0: endpoint {
7489
remote-endpoint = <&etb_in_port>;
90+
filter-source = <&tpdm_video>;
7591
};
7692
};
7793
7894
port@1 {
7995
reg = <1>;
8096
replicator_out_port1: endpoint {
8197
remote-endpoint = <&tpiu_in_port>;
98+
filter-source = <&tpdm_mdss>;
8299
};
83100
};
84101
};

drivers/hwtracing/coresight/coresight-core.c

Lines changed: 94 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -75,22 +75,54 @@ struct coresight_device *coresight_get_percpu_sink(int cpu)
7575
}
7676
EXPORT_SYMBOL_GPL(coresight_get_percpu_sink);
7777

78+
static struct coresight_device *coresight_get_source(struct list_head *path)
79+
{
80+
struct coresight_device *csdev;
81+
82+
if (!path)
83+
return NULL;
84+
85+
csdev = list_first_entry(path, struct coresight_node, link)->csdev;
86+
if (!coresight_is_device_source(csdev))
87+
return NULL;
88+
89+
return csdev;
90+
}
91+
92+
/**
93+
* coresight_blocks_source - checks whether the connection matches the source
94+
* of path if connection is bound to specific source.
95+
* @src: The source device of the trace path
96+
* @conn: The connection of one outport
97+
*
98+
* Return false if the connection doesn't have a source binded or source of the
99+
* path matches the source binds to connection.
100+
*/
101+
static bool coresight_blocks_source(struct coresight_device *src,
102+
struct coresight_connection *conn)
103+
{
104+
return conn->filter_src_fwnode && (conn->filter_src_dev != src);
105+
}
106+
78107
static struct coresight_connection *
79-
coresight_find_out_connection(struct coresight_device *src_dev,
80-
struct coresight_device *dest_dev)
108+
coresight_find_out_connection(struct coresight_device *csdev,
109+
struct coresight_device *out_dev,
110+
struct coresight_device *trace_src)
81111
{
82112
int i;
83113
struct coresight_connection *conn;
84114

85-
for (i = 0; i < src_dev->pdata->nr_outconns; i++) {
86-
conn = src_dev->pdata->out_conns[i];
87-
if (conn->dest_dev == dest_dev)
115+
for (i = 0; i < csdev->pdata->nr_outconns; i++) {
116+
conn = csdev->pdata->out_conns[i];
117+
if (coresight_blocks_source(trace_src, conn))
118+
continue;
119+
if (conn->dest_dev == out_dev)
88120
return conn;
89121
}
90122

91-
dev_err(&src_dev->dev,
92-
"couldn't find output connection, src_dev: %s, dest_dev: %s\n",
93-
dev_name(&src_dev->dev), dev_name(&dest_dev->dev));
123+
dev_err(&csdev->dev,
124+
"couldn't find output connection, csdev: %s, out_dev: %s\n",
125+
dev_name(&csdev->dev), dev_name(&out_dev->dev));
94126

95127
return ERR_PTR(-ENODEV);
96128
}
@@ -251,16 +283,17 @@ static void coresight_disable_sink(struct coresight_device *csdev)
251283

252284
static int coresight_enable_link(struct coresight_device *csdev,
253285
struct coresight_device *parent,
254-
struct coresight_device *child)
286+
struct coresight_device *child,
287+
struct coresight_device *source)
255288
{
256289
int link_subtype;
257290
struct coresight_connection *inconn, *outconn;
258291

259292
if (!parent || !child)
260293
return -EINVAL;
261294

262-
inconn = coresight_find_out_connection(parent, csdev);
263-
outconn = coresight_find_out_connection(csdev, child);
295+
inconn = coresight_find_out_connection(parent, csdev, source);
296+
outconn = coresight_find_out_connection(csdev, child, source);
264297
link_subtype = csdev->subtype.link_subtype;
265298

266299
if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG && IS_ERR(inconn))
@@ -273,15 +306,16 @@ static int coresight_enable_link(struct coresight_device *csdev,
273306

274307
static void coresight_disable_link(struct coresight_device *csdev,
275308
struct coresight_device *parent,
276-
struct coresight_device *child)
309+
struct coresight_device *child,
310+
struct coresight_device *source)
277311
{
278312
struct coresight_connection *inconn, *outconn;
279313

280314
if (!parent || !child)
281315
return;
282316

283-
inconn = coresight_find_out_connection(parent, csdev);
284-
outconn = coresight_find_out_connection(csdev, child);
317+
inconn = coresight_find_out_connection(parent, csdev, source);
318+
outconn = coresight_find_out_connection(csdev, child, source);
285319

286320
link_ops(csdev)->disable(csdev, inconn, outconn);
287321
}
@@ -375,7 +409,8 @@ static void coresight_disable_path_from(struct list_head *path,
375409
case CORESIGHT_DEV_TYPE_LINK:
376410
parent = list_prev_entry(nd, link)->csdev;
377411
child = list_next_entry(nd, link)->csdev;
378-
coresight_disable_link(csdev, parent, child);
412+
coresight_disable_link(csdev, parent, child,
413+
coresight_get_source(path));
379414
break;
380415
default:
381416
break;
@@ -418,7 +453,9 @@ int coresight_enable_path(struct list_head *path, enum cs_mode mode,
418453
u32 type;
419454
struct coresight_node *nd;
420455
struct coresight_device *csdev, *parent, *child;
456+
struct coresight_device *source;
421457

458+
source = coresight_get_source(path);
422459
list_for_each_entry_reverse(nd, path, link) {
423460
csdev = nd->csdev;
424461
type = csdev->type;
@@ -456,7 +493,7 @@ int coresight_enable_path(struct list_head *path, enum cs_mode mode,
456493
case CORESIGHT_DEV_TYPE_LINK:
457494
parent = list_prev_entry(nd, link)->csdev;
458495
child = list_next_entry(nd, link)->csdev;
459-
ret = coresight_enable_link(csdev, parent, child);
496+
ret = coresight_enable_link(csdev, parent, child, source);
460497
if (ret)
461498
goto err;
462499
break;
@@ -619,6 +656,7 @@ static void coresight_drop_device(struct coresight_device *csdev)
619656
/**
620657
* _coresight_build_path - recursively build a path from a @csdev to a sink.
621658
* @csdev: The device to start from.
659+
* @source: The trace source device of the path.
622660
* @sink: The final sink we want in this path.
623661
* @path: The list to add devices to.
624662
*
@@ -628,6 +666,7 @@ static void coresight_drop_device(struct coresight_device *csdev)
628666
* the source is the first device and the sink the last one.
629667
*/
630668
static int _coresight_build_path(struct coresight_device *csdev,
669+
struct coresight_device *source,
631670
struct coresight_device *sink,
632671
struct list_head *path)
633672
{
@@ -641,7 +680,7 @@ static int _coresight_build_path(struct coresight_device *csdev,
641680

642681
if (coresight_is_percpu_source(csdev) && coresight_is_percpu_sink(sink) &&
643682
sink == per_cpu(csdev_sink, source_ops(csdev)->cpu_id(csdev))) {
644-
if (_coresight_build_path(sink, sink, path) == 0) {
683+
if (_coresight_build_path(sink, source, sink, path) == 0) {
645684
found = true;
646685
goto out;
647686
}
@@ -652,8 +691,12 @@ static int _coresight_build_path(struct coresight_device *csdev,
652691
struct coresight_device *child_dev;
653692

654693
child_dev = csdev->pdata->out_conns[i]->dest_dev;
694+
695+
if (coresight_blocks_source(source, csdev->pdata->out_conns[i]))
696+
continue;
697+
655698
if (child_dev &&
656-
_coresight_build_path(child_dev, sink, path) == 0) {
699+
_coresight_build_path(child_dev, source, sink, path) == 0) {
657700
found = true;
658701
break;
659702
}
@@ -698,7 +741,7 @@ struct list_head *coresight_build_path(struct coresight_device *source,
698741

699742
INIT_LIST_HEAD(path);
700743

701-
rc = _coresight_build_path(source, sink, path);
744+
rc = _coresight_build_path(source, source, sink, path);
702745
if (rc) {
703746
kfree(path);
704747
return ERR_PTR(rc);
@@ -927,6 +970,16 @@ static int coresight_orphan_match(struct device *dev, void *data)
927970
for (i = 0; i < src_csdev->pdata->nr_outconns; i++) {
928971
conn = src_csdev->pdata->out_conns[i];
929972

973+
/* Fix filter source device before skip the port */
974+
if (conn->filter_src_fwnode && !conn->filter_src_dev) {
975+
if (dst_csdev &&
976+
(conn->filter_src_fwnode == dst_csdev->dev.fwnode) &&
977+
!WARN_ON_ONCE(!coresight_is_device_source(dst_csdev)))
978+
conn->filter_src_dev = dst_csdev;
979+
else
980+
still_orphan = true;
981+
}
982+
930983
/* Skip the port if it's already connected. */
931984
if (conn->dest_dev)
932985
continue;
@@ -977,18 +1030,40 @@ static int coresight_fixup_orphan_conns(struct coresight_device *csdev)
9771030
csdev, coresight_orphan_match);
9781031
}
9791032

1033+
static int coresight_clear_filter_source(struct device *dev, void *data)
1034+
{
1035+
int i;
1036+
struct coresight_device *source = data;
1037+
struct coresight_device *csdev = to_coresight_device(dev);
1038+
1039+
for (i = 0; i < csdev->pdata->nr_outconns; ++i) {
1040+
if (csdev->pdata->out_conns[i]->filter_src_dev == source)
1041+
csdev->pdata->out_conns[i]->filter_src_dev = NULL;
1042+
}
1043+
return 0;
1044+
}
1045+
9801046
/* coresight_remove_conns - Remove other device's references to this device */
9811047
static void coresight_remove_conns(struct coresight_device *csdev)
9821048
{
9831049
int i, j;
9841050
struct coresight_connection *conn;
9851051

1052+
if (coresight_is_device_source(csdev))
1053+
bus_for_each_dev(&coresight_bustype, NULL, csdev,
1054+
coresight_clear_filter_source);
1055+
9861056
/*
9871057
* Remove the input connection references from the destination device
9881058
* for each output connection.
9891059
*/
9901060
for (i = 0; i < csdev->pdata->nr_outconns; i++) {
9911061
conn = csdev->pdata->out_conns[i];
1062+
if (conn->filter_src_fwnode) {
1063+
conn->filter_src_dev = NULL;
1064+
fwnode_handle_put(conn->filter_src_fwnode);
1065+
}
1066+
9921067
if (!conn->dest_dev)
9931068
continue;
9941069

0 commit comments

Comments
 (0)