Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <suzuki.poulose@arm.com>

* 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

+309 -59
+15
Documentation/ABI/testing/sysfs-bus-coresight-devices-dummy-source
··· 1 + What: /sys/bus/coresight/devices/dummy_source<N>/enable_source 2 + Date: Dec 2024 3 + KernelVersion: 6.14 4 + Contact: Mao Jinlong <quic_jinlmao@quicinc.com> 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 <quic_jinlmao@quicinc.com> 14 + Description: (R) Show the trace ID that will appear in the trace stream 15 + coming from this trace entity.
+6
Documentation/devicetree/bindings/arm/arm,coresight-dummy-source.yaml
··· 38 38 enum: 39 39 - arm,coresight-dummy-source 40 40 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 + 41 47 out-ports: 42 48 $ref: /schemas/graph.yaml#/properties/ports 43 49
+18 -1
Documentation/devicetree/bindings/arm/arm,coresight-static-replicator.yaml
··· 45 45 patternProperties: 46 46 '^port@[01]$': 47 47 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 49 64 50 65 required: 51 66 - compatible ··· 87 72 reg = <0>; 88 73 replicator_out_port0: endpoint { 89 74 remote-endpoint = <&etb_in_port>; 75 + filter-source = <&tpdm_video>; 90 76 }; 91 77 }; 92 78 ··· 95 79 reg = <1>; 96 80 replicator_out_port1: endpoint { 97 81 remote-endpoint = <&tpiu_in_port>; 82 + filter-source = <&tpdm_mdss>; 98 83 }; 99 84 }; 100 85 };
+94 -19
drivers/hwtracing/coresight/coresight-core.c
··· 75 75 } 76 76 EXPORT_SYMBOL_GPL(coresight_get_percpu_sink); 77 77 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 + 78 107 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) 81 111 { 82 112 int i; 83 113 struct coresight_connection *conn; 84 114 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) 88 120 return conn; 89 121 } 90 122 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)); 94 126 95 127 return ERR_PTR(-ENODEV); 96 128 } ··· 283 251 284 252 static int coresight_enable_link(struct coresight_device *csdev, 285 253 struct coresight_device *parent, 286 - struct coresight_device *child) 254 + struct coresight_device *child, 255 + struct coresight_device *source) 287 256 { 288 257 int link_subtype; 289 258 struct coresight_connection *inconn, *outconn; ··· 292 259 if (!parent || !child) 293 260 return -EINVAL; 294 261 295 - inconn = coresight_find_out_connection(parent, csdev); 296 - outconn = coresight_find_out_connection(csdev, child); 262 + inconn = coresight_find_out_connection(parent, csdev, source); 263 + outconn = coresight_find_out_connection(csdev, child, source); 297 264 link_subtype = csdev->subtype.link_subtype; 298 265 299 266 if (link_subtype == CORESIGHT_DEV_SUBTYPE_LINK_MERG && IS_ERR(inconn)) ··· 306 273 307 274 static void coresight_disable_link(struct coresight_device *csdev, 308 275 struct coresight_device *parent, 309 - struct coresight_device *child) 276 + struct coresight_device *child, 277 + struct coresight_device *source) 310 278 { 311 279 struct coresight_connection *inconn, *outconn; 312 280 313 281 if (!parent || !child) 314 282 return; 315 283 316 - inconn = coresight_find_out_connection(parent, csdev); 317 - outconn = coresight_find_out_connection(csdev, child); 284 + inconn = coresight_find_out_connection(parent, csdev, source); 285 + outconn = coresight_find_out_connection(csdev, child, source); 318 286 319 287 link_ops(csdev)->disable(csdev, inconn, outconn); 320 288 } ··· 409 375 case CORESIGHT_DEV_TYPE_LINK: 410 376 parent = list_prev_entry(nd, link)->csdev; 411 377 child = list_next_entry(nd, link)->csdev; 412 - coresight_disable_link(csdev, parent, child); 378 + coresight_disable_link(csdev, parent, child, 379 + coresight_get_source(path)); 413 380 break; 414 381 default: 415 382 break; ··· 453 418 u32 type; 454 419 struct coresight_node *nd; 455 420 struct coresight_device *csdev, *parent, *child; 421 + struct coresight_device *source; 456 422 423 + source = coresight_get_source(path); 457 424 list_for_each_entry_reverse(nd, path, link) { 458 425 csdev = nd->csdev; 459 426 type = csdev->type; ··· 493 456 case CORESIGHT_DEV_TYPE_LINK: 494 457 parent = list_prev_entry(nd, link)->csdev; 495 458 child = list_next_entry(nd, link)->csdev; 496 - ret = coresight_enable_link(csdev, parent, child); 459 + ret = coresight_enable_link(csdev, parent, child, source); 497 460 if (ret) 498 461 goto err; 499 462 break; ··· 656 619 /** 657 620 * _coresight_build_path - recursively build a path from a @csdev to a sink. 658 621 * @csdev: The device to start from. 622 + * @source: The trace source device of the path. 659 623 * @sink: The final sink we want in this path. 660 624 * @path: The list to add devices to. 661 625 * ··· 666 628 * the source is the first device and the sink the last one. 667 629 */ 668 630 static int _coresight_build_path(struct coresight_device *csdev, 631 + struct coresight_device *source, 669 632 struct coresight_device *sink, 670 633 struct list_head *path) 671 634 { ··· 680 641 681 642 if (coresight_is_percpu_source(csdev) && coresight_is_percpu_sink(sink) && 682 643 sink == per_cpu(csdev_sink, source_ops(csdev)->cpu_id(csdev))) { 683 - if (_coresight_build_path(sink, sink, path) == 0) { 644 + if (_coresight_build_path(sink, source, sink, path) == 0) { 684 645 found = true; 685 646 goto out; 686 647 } ··· 691 652 struct coresight_device *child_dev; 692 653 693 654 child_dev = csdev->pdata->out_conns[i]->dest_dev; 655 + 656 + if (coresight_blocks_source(source, csdev->pdata->out_conns[i])) 657 + continue; 658 + 694 659 if (child_dev && 695 - _coresight_build_path(child_dev, sink, path) == 0) { 660 + _coresight_build_path(child_dev, source, sink, path) == 0) { 696 661 found = true; 697 662 break; 698 663 } ··· 741 698 742 699 INIT_LIST_HEAD(path); 743 700 744 - rc = _coresight_build_path(source, sink, path); 701 + rc = _coresight_build_path(source, source, sink, path); 745 702 if (rc) { 746 703 kfree(path); 747 704 return ERR_PTR(rc); ··· 970 927 for (i = 0; i < src_csdev->pdata->nr_outconns; i++) { 971 928 conn = src_csdev->pdata->out_conns[i]; 972 929 930 + /* Fix filter source device before skip the port */ 931 + if (conn->filter_src_fwnode && !conn->filter_src_dev) { 932 + if (dst_csdev && 933 + (conn->filter_src_fwnode == dst_csdev->dev.fwnode) && 934 + !WARN_ON_ONCE(!coresight_is_device_source(dst_csdev))) 935 + conn->filter_src_dev = dst_csdev; 936 + else 937 + still_orphan = true; 938 + } 939 + 973 940 /* Skip the port if it's already connected. */ 974 941 if (conn->dest_dev) 975 942 continue; ··· 1030 977 csdev, coresight_orphan_match); 1031 978 } 1032 979 980 + static int coresight_clear_filter_source(struct device *dev, void *data) 981 + { 982 + int i; 983 + struct coresight_device *source = data; 984 + struct coresight_device *csdev = to_coresight_device(dev); 985 + 986 + for (i = 0; i < csdev->pdata->nr_outconns; ++i) { 987 + if (csdev->pdata->out_conns[i]->filter_src_dev == source) 988 + csdev->pdata->out_conns[i]->filter_src_dev = NULL; 989 + } 990 + return 0; 991 + } 992 + 1033 993 /* coresight_remove_conns - Remove other device's references to this device */ 1034 994 static void coresight_remove_conns(struct coresight_device *csdev) 1035 995 { 1036 996 int i, j; 1037 997 struct coresight_connection *conn; 998 + 999 + if (coresight_is_device_source(csdev)) 1000 + bus_for_each_dev(&coresight_bustype, NULL, csdev, 1001 + coresight_clear_filter_source); 1038 1002 1039 1003 /* 1040 1004 * Remove the input connection references from the destination device ··· 1059 989 */ 1060 990 for (i = 0; i < csdev->pdata->nr_outconns; i++) { 1061 991 conn = csdev->pdata->out_conns[i]; 992 + if (conn->filter_src_fwnode) { 993 + conn->filter_src_dev = NULL; 994 + fwnode_handle_put(conn->filter_src_fwnode); 995 + } 996 + 1062 997 if (!conn->dest_dev) 1063 998 continue; 1064 999
+72 -9
drivers/hwtracing/coresight/coresight-dummy.c
··· 11 11 #include <linux/pm_runtime.h> 12 12 13 13 #include "coresight-priv.h" 14 + #include "coresight-trace-id.h" 14 15 15 16 struct dummy_drvdata { 16 17 struct device *dev; 17 18 struct coresight_device *csdev; 19 + u8 traceid; 18 20 }; 19 21 20 22 DEFINE_CORESIGHT_DEVLIST(source_devs, "dummy_source"); ··· 74 72 .sink_ops = &dummy_sink_ops, 75 73 }; 76 74 75 + /* User can get the trace id of dummy source from this node. */ 76 + static ssize_t traceid_show(struct device *dev, 77 + struct device_attribute *attr, char *buf) 78 + { 79 + unsigned long val; 80 + struct dummy_drvdata *drvdata = dev_get_drvdata(dev->parent); 81 + 82 + val = drvdata->traceid; 83 + return sysfs_emit(buf, "%#lx\n", val); 84 + } 85 + static DEVICE_ATTR_RO(traceid); 86 + 87 + static struct attribute *coresight_dummy_attrs[] = { 88 + &dev_attr_traceid.attr, 89 + NULL, 90 + }; 91 + 92 + static const struct attribute_group coresight_dummy_group = { 93 + .attrs = coresight_dummy_attrs, 94 + }; 95 + 96 + static const struct attribute_group *coresight_dummy_groups[] = { 97 + &coresight_dummy_group, 98 + NULL, 99 + }; 100 + 77 101 static int dummy_probe(struct platform_device *pdev) 78 102 { 79 103 struct device *dev = &pdev->dev; ··· 107 79 struct coresight_platform_data *pdata; 108 80 struct dummy_drvdata *drvdata; 109 81 struct coresight_desc desc = { 0 }; 82 + int ret = 0, trace_id = 0; 83 + 84 + drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); 85 + if (!drvdata) 86 + return -ENOMEM; 110 87 111 88 if (of_device_is_compatible(node, "arm,coresight-dummy-source")) { 112 89 ··· 123 90 desc.subtype.source_subtype = 124 91 CORESIGHT_DEV_SUBTYPE_SOURCE_OTHERS; 125 92 desc.ops = &dummy_source_cs_ops; 93 + desc.groups = coresight_dummy_groups; 94 + 95 + ret = coresight_get_static_trace_id(dev, &trace_id); 96 + if (!ret) { 97 + /* Get the static id if id is set in device tree. */ 98 + ret = coresight_trace_id_get_static_system_id(trace_id); 99 + if (ret < 0) { 100 + dev_err(dev, "Fail to get static id.\n"); 101 + return ret; 102 + } 103 + } else { 104 + /* Get next available id if id is not set in device tree. */ 105 + trace_id = coresight_trace_id_get_system_id(); 106 + if (trace_id < 0) { 107 + ret = trace_id; 108 + return ret; 109 + } 110 + } 111 + drvdata->traceid = (u8)trace_id; 112 + 126 113 } else if (of_device_is_compatible(node, "arm,coresight-dummy-sink")) { 127 114 desc.name = coresight_alloc_device_name(&sink_devs, dev); 128 115 if (!desc.name) ··· 157 104 } 158 105 159 106 pdata = coresight_get_platform_data(dev); 160 - if (IS_ERR(pdata)) 161 - return PTR_ERR(pdata); 107 + if (IS_ERR(pdata)) { 108 + ret = PTR_ERR(pdata); 109 + goto free_id; 110 + } 162 111 pdev->dev.platform_data = pdata; 163 - 164 - drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); 165 - if (!drvdata) 166 - return -ENOMEM; 167 112 168 113 drvdata->dev = &pdev->dev; 169 114 platform_set_drvdata(pdev, drvdata); ··· 169 118 desc.pdata = pdev->dev.platform_data; 170 119 desc.dev = &pdev->dev; 171 120 drvdata->csdev = coresight_register(&desc); 172 - if (IS_ERR(drvdata->csdev)) 173 - return PTR_ERR(drvdata->csdev); 121 + if (IS_ERR(drvdata->csdev)) { 122 + ret = PTR_ERR(drvdata->csdev); 123 + goto free_id; 124 + } 174 125 175 126 pm_runtime_enable(dev); 176 127 dev_dbg(dev, "Dummy device initialized\n"); 177 128 178 - return 0; 129 + ret = 0; 130 + goto out; 131 + 132 + free_id: 133 + if (IS_VALID_CS_TRACE_ID(drvdata->traceid)) 134 + coresight_trace_id_put_system_id(drvdata->traceid); 135 + 136 + out: 137 + return ret; 179 138 } 180 139 181 140 static void dummy_remove(struct platform_device *pdev) ··· 193 132 struct dummy_drvdata *drvdata = platform_get_drvdata(pdev); 194 133 struct device *dev = &pdev->dev; 195 134 135 + if (IS_VALID_CS_TRACE_ID(drvdata->traceid)) 136 + coresight_trace_id_put_system_id(drvdata->traceid); 196 137 pm_runtime_disable(dev); 197 138 coresight_unregister(drvdata->csdev); 198 139 }
+3 -3
drivers/hwtracing/coresight/coresight-funnel.c
··· 86 86 bool first_enable = false; 87 87 88 88 spin_lock_irqsave(&drvdata->spinlock, flags); 89 - if (atomic_read(&in->dest_refcnt) == 0) { 89 + if (in->dest_refcnt == 0) { 90 90 if (drvdata->base) 91 91 rc = dynamic_funnel_enable_hw(drvdata, in->dest_port); 92 92 if (!rc) 93 93 first_enable = true; 94 94 } 95 95 if (!rc) 96 - atomic_inc(&in->dest_refcnt); 96 + in->dest_refcnt++; 97 97 spin_unlock_irqrestore(&drvdata->spinlock, flags); 98 98 99 99 if (first_enable) ··· 130 130 bool last_disable = false; 131 131 132 132 spin_lock_irqsave(&drvdata->spinlock, flags); 133 - if (atomic_dec_return(&in->dest_refcnt) == 0) { 133 + if (--in->dest_refcnt == 0) { 134 134 if (drvdata->base) 135 135 dynamic_funnel_disable_hw(drvdata, in->dest_port); 136 136 last_disable = true;
+27
drivers/hwtracing/coresight/coresight-platform.c
··· 243 243 conn.dest_fwnode = fwnode_handle_get(rdev_fwnode); 244 244 conn.dest_port = rendpoint.port; 245 245 246 + /* 247 + * Get the firmware node of the filter source through the 248 + * reference. This could be used to filter the source in 249 + * building path. 250 + */ 251 + conn.filter_src_fwnode = 252 + fwnode_find_reference(&ep->fwnode, "filter-source", 0); 253 + if (IS_ERR(conn.filter_src_fwnode)) { 254 + conn.filter_src_fwnode = NULL; 255 + } else { 256 + conn.filter_src_dev = 257 + coresight_find_csdev_by_fwnode(conn.filter_src_fwnode); 258 + if (conn.filter_src_dev && 259 + !coresight_is_device_source(conn.filter_src_dev)) { 260 + dev_warn(dev, "port %d: Filter handle is not a trace source : %s\n", 261 + conn.src_port, dev_name(&conn.filter_src_dev->dev)); 262 + conn.filter_src_dev = NULL; 263 + conn.filter_src_fwnode = NULL; 264 + } 265 + } 266 + 246 267 new_conn = coresight_add_out_conn(dev, pdata, &conn); 247 268 if (IS_ERR_VALUE(new_conn)) { 248 269 fwnode_handle_put(conn.dest_fwnode); ··· 816 795 return 0; 817 796 } 818 797 EXPORT_SYMBOL_GPL(coresight_get_cpu); 798 + 799 + int coresight_get_static_trace_id(struct device *dev, u32 *id) 800 + { 801 + return fwnode_property_read_u32(dev_fwnode(dev), "arm,static-trace-id", id); 802 + } 803 + EXPORT_SYMBOL_GPL(coresight_get_static_trace_id); 819 804 820 805 struct coresight_platform_data * 821 806 coresight_get_platform_data(struct device *dev)
+3 -3
drivers/hwtracing/coresight/coresight-replicator.c
··· 126 126 bool first_enable = false; 127 127 128 128 spin_lock_irqsave(&drvdata->spinlock, flags); 129 - if (atomic_read(&out->src_refcnt) == 0) { 129 + if (out->src_refcnt == 0) { 130 130 if (drvdata->base) 131 131 rc = dynamic_replicator_enable(drvdata, in->dest_port, 132 132 out->src_port); ··· 134 134 first_enable = true; 135 135 } 136 136 if (!rc) 137 - atomic_inc(&out->src_refcnt); 137 + out->src_refcnt++; 138 138 spin_unlock_irqrestore(&drvdata->spinlock, flags); 139 139 140 140 if (first_enable) ··· 180 180 bool last_disable = false; 181 181 182 182 spin_lock_irqsave(&drvdata->spinlock, flags); 183 - if (atomic_dec_return(&out->src_refcnt) == 0) { 183 + if (--out->src_refcnt == 0) { 184 184 if (drvdata->base) 185 185 dynamic_replicator_disable(drvdata, in->dest_port, 186 186 out->src_port);
+14 -5
drivers/hwtracing/coresight/coresight-tpda.c
··· 24 24 25 25 static bool coresight_device_is_tpdm(struct coresight_device *csdev) 26 26 { 27 - return (csdev->type == CORESIGHT_DEV_TYPE_SOURCE) && 27 + return (coresight_is_device_source(csdev)) && 28 28 (csdev->subtype.source_subtype == 29 29 CORESIGHT_DEV_SUBTYPE_SOURCE_TPDM); 30 30 } ··· 110 110 csdev->pdata->in_conns[i]->dest_port != inport) 111 111 continue; 112 112 113 + /* 114 + * If this port has a hardcoded filter, use the source 115 + * device directly. 116 + */ 117 + if (csdev->pdata->in_conns[i]->filter_src_fwnode) { 118 + in = csdev->pdata->in_conns[i]->filter_src_dev; 119 + if (!in) 120 + continue; 121 + } 122 + 113 123 if (coresight_device_is_tpdm(in)) { 114 124 if (drvdata->dsb_esize || drvdata->cmb_esize) 115 125 return -EEXIST; ··· 133 123 return rc; 134 124 } 135 125 } 136 - 137 126 138 127 return rc; 139 128 } ··· 199 190 int ret = 0; 200 191 201 192 spin_lock(&drvdata->spinlock); 202 - if (atomic_read(&in->dest_refcnt) == 0) { 193 + if (in->dest_refcnt == 0) { 203 194 ret = __tpda_enable(drvdata, in->dest_port); 204 195 if (!ret) { 205 - atomic_inc(&in->dest_refcnt); 196 + in->dest_refcnt++; 206 197 csdev->refcnt++; 207 198 dev_dbg(drvdata->dev, "TPDA inport %d enabled.\n", in->dest_port); 208 199 } ··· 232 223 struct tpda_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); 233 224 234 225 spin_lock(&drvdata->spinlock); 235 - if (atomic_dec_return(&in->dest_refcnt) == 0) { 226 + if (--in->dest_refcnt == 0) { 236 227 __tpda_disable(drvdata, in->dest_port); 237 228 csdev->refcnt--; 238 229 }
+3 -4
drivers/hwtracing/coresight/coresight-tpdm.c
··· 640 640 struct tpdm_drvdata *drvdata = dev_get_drvdata(dev->parent); 641 641 unsigned long val; 642 642 643 - if ((kstrtoul(buf, 0, &val)) || (val < 0) || 644 - (val & ~TPDM_DSB_MODE_MASK)) 643 + if ((kstrtoul(buf, 0, &val)) || (val & ~TPDM_DSB_MODE_MASK)) 645 644 return -EINVAL; 646 645 647 646 spin_lock(&drvdata->spinlock); ··· 1307 1308 */ 1308 1309 static struct amba_id tpdm_ids[] = { 1309 1310 { 1310 - .id = 0x000f0e00, 1311 - .mask = 0x000fff00, 1311 + .id = 0x001f0e00, 1312 + .mask = 0x00ffff00, 1312 1313 }, 1313 1314 { 0, 0, NULL }, 1314 1315 };
+31 -12
drivers/hwtracing/coresight/coresight-trace-id.c
··· 12 12 13 13 #include "coresight-trace-id.h" 14 14 15 + enum trace_id_flags { 16 + TRACE_ID_ANY = 0x0, 17 + TRACE_ID_PREFER_ODD = 0x1, 18 + TRACE_ID_REQ_STATIC = 0x2, 19 + }; 20 + 15 21 /* Default trace ID map. Used in sysfs mode and for system sources */ 16 22 static DEFINE_PER_CPU(atomic_t, id_map_default_cpu_ids) = ATOMIC_INIT(0); 17 23 static struct coresight_trace_id_map id_map_default = { ··· 80 74 * Otherwise allocate next available ID. 81 75 */ 82 76 static int coresight_trace_id_alloc_new_id(struct coresight_trace_id_map *id_map, 83 - int preferred_id, bool prefer_odd_id) 77 + int preferred_id, unsigned int flags) 84 78 { 85 79 int id = 0; 86 80 87 81 /* for backwards compatibility, cpu IDs may use preferred value */ 88 - if (IS_VALID_CS_TRACE_ID(preferred_id) && 89 - !test_bit(preferred_id, id_map->used_ids)) { 90 - id = preferred_id; 91 - goto trace_id_allocated; 92 - } else if (prefer_odd_id) { 82 + if (IS_VALID_CS_TRACE_ID(preferred_id)) { 83 + if (!test_bit(preferred_id, id_map->used_ids)) { 84 + id = preferred_id; 85 + goto trace_id_allocated; 86 + } else if (flags & TRACE_ID_REQ_STATIC) 87 + return -EBUSY; 88 + } else if (flags & TRACE_ID_PREFER_ODD) { 93 89 /* may use odd ids to avoid preferred legacy cpu IDs */ 94 90 id = coresight_trace_id_find_odd_id(id_map); 95 91 if (id) 96 92 goto trace_id_allocated; 97 - } 93 + } else if (!IS_VALID_CS_TRACE_ID(preferred_id) && 94 + (flags & TRACE_ID_REQ_STATIC)) 95 + return -EINVAL; 98 96 99 97 /* 100 98 * skip reserved bit 0, look at bitmap length of ··· 163 153 */ 164 154 id = coresight_trace_id_alloc_new_id(id_map, 165 155 CORESIGHT_LEGACY_CPU_TRACE_ID(cpu), 166 - false); 156 + TRACE_ID_ANY); 167 157 if (!IS_VALID_CS_TRACE_ID(id)) 168 158 goto get_cpu_id_out_unlock; 169 159 ··· 198 188 DUMP_ID_MAP(id_map); 199 189 } 200 190 201 - static int coresight_trace_id_map_get_system_id(struct coresight_trace_id_map *id_map) 191 + static int coresight_trace_id_map_get_system_id(struct coresight_trace_id_map *id_map, 192 + int preferred_id, unsigned int traceid_flags) 202 193 { 203 194 unsigned long flags; 204 195 int id; 205 196 206 197 spin_lock_irqsave(&id_map->lock, flags); 207 - /* prefer odd IDs for system components to avoid legacy CPU IDS */ 208 - id = coresight_trace_id_alloc_new_id(id_map, 0, true); 198 + id = coresight_trace_id_alloc_new_id(id_map, preferred_id, traceid_flags); 209 199 spin_unlock_irqrestore(&id_map->lock, flags); 210 200 211 201 DUMP_ID(id); ··· 265 255 266 256 int coresight_trace_id_get_system_id(void) 267 257 { 268 - return coresight_trace_id_map_get_system_id(&id_map_default); 258 + /* prefer odd IDs for system components to avoid legacy CPU IDS */ 259 + return coresight_trace_id_map_get_system_id(&id_map_default, 0, 260 + TRACE_ID_PREFER_ODD); 269 261 } 270 262 EXPORT_SYMBOL_GPL(coresight_trace_id_get_system_id); 263 + 264 + int coresight_trace_id_get_static_system_id(int trace_id) 265 + { 266 + return coresight_trace_id_map_get_system_id(&id_map_default, 267 + trace_id, TRACE_ID_REQ_STATIC); 268 + } 269 + EXPORT_SYMBOL_GPL(coresight_trace_id_get_static_system_id); 271 270 272 271 void coresight_trace_id_put_system_id(int id) 273 272 {
+9
drivers/hwtracing/coresight/coresight-trace-id.h
··· 117 117 int coresight_trace_id_get_system_id(void); 118 118 119 119 /** 120 + * Allocate a CoreSight static trace ID for a system component. 121 + * 122 + * Used to allocate static IDs for system trace sources such as dummy source. 123 + * 124 + * return: Trace ID or -EINVAL if allocation is impossible. 125 + */ 126 + int coresight_trace_id_get_static_system_id(int id); 127 + 128 + /** 120 129 * Release an allocated system trace ID. 121 130 * 122 131 * Unconditionally release a trace ID allocated to a system component.
+14 -3
include/linux/coresight.h
··· 172 172 * @dest_dev: a @coresight_device representation of the component 173 173 connected to @src_port. NULL until the device is created 174 174 * @link: Representation of the connection as a sysfs link. 175 + * @filter_src_fwnode: filter source component's fwnode handle. 176 + * @filter_src_dev: a @coresight_device representation of the component that 177 + needs to be filtered. 175 178 * 176 179 * The full connection structure looks like this, where in_conns store 177 180 * references to same connection as the source device's out_conns. ··· 203 200 struct coresight_device *dest_dev; 204 201 struct coresight_sysfs_link *link; 205 202 struct coresight_device *src_dev; 206 - atomic_t src_refcnt; 207 - atomic_t dest_refcnt; 203 + struct fwnode_handle *filter_src_fwnode; 204 + struct coresight_device *filter_src_dev; 205 + int src_refcnt; 206 + int dest_refcnt; 208 207 }; 209 208 210 209 /** ··· 593 588 } 594 589 #endif /* CONFIG_64BIT */ 595 590 591 + static inline bool coresight_is_device_source(struct coresight_device *csdev) 592 + { 593 + return csdev && (csdev->type == CORESIGHT_DEV_TYPE_SOURCE); 594 + } 595 + 596 596 static inline bool coresight_is_percpu_source(struct coresight_device *csdev) 597 597 { 598 - return csdev && (csdev->type == CORESIGHT_DEV_TYPE_SOURCE) && 598 + return csdev && coresight_is_device_source(csdev) && 599 599 (csdev->subtype.source_subtype == CORESIGHT_DEV_SUBTYPE_SOURCE_PROC); 600 600 } 601 601 ··· 672 662 void coresight_write64(struct coresight_device *csdev, u64 val, u32 offset); 673 663 674 664 extern int coresight_get_cpu(struct device *dev); 665 + extern int coresight_get_static_trace_id(struct device *dev, u32 *id); 675 666 676 667 struct coresight_platform_data *coresight_get_platform_data(struct device *dev); 677 668 struct coresight_connection *