1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
6 #include <linux/acpi.h>
7 #include <linux/types.h>
9 #include <linux/slab.h>
10 #include <linux/clk.h>
12 #include <linux/of_graph.h>
13 #include <linux/platform_device.h>
14 #include <linux/amba/bus.h>
15 #include <linux/coresight.h>
16 #include <linux/cpumask.h>
17 #include <asm/smp_plat.h>
19 #include "coresight-priv.h"
22 * Add an entry to the connection list and assign @conn's contents to it.
24 * If the output port is already assigned on this device, return -EINVAL
26 struct coresight_connection
*
27 coresight_add_out_conn(struct device
*dev
,
28 struct coresight_platform_data
*pdata
,
29 const struct coresight_connection
*new_conn
)
32 struct coresight_connection
*conn
;
35 * Warn on any existing duplicate output port.
37 for (i
= 0; i
< pdata
->nr_outconns
; ++i
) {
38 conn
= pdata
->out_conns
[i
];
39 /* Output == -1 means ignore the port for example for helpers */
40 if (conn
->src_port
!= -1 &&
41 conn
->src_port
== new_conn
->src_port
) {
42 dev_warn(dev
, "Duplicate output port %d\n",
44 return ERR_PTR(-EINVAL
);
50 devm_krealloc_array(dev
, pdata
->out_conns
, pdata
->nr_outconns
,
51 sizeof(*pdata
->out_conns
), GFP_KERNEL
);
52 if (!pdata
->out_conns
)
53 return ERR_PTR(-ENOMEM
);
55 conn
= devm_kmalloc(dev
, sizeof(struct coresight_connection
),
58 return ERR_PTR(-ENOMEM
);
61 * Copy the new connection into the allocation, save the pointer to the
62 * end of the connection array and also return it in case it needs to be
66 pdata
->out_conns
[pdata
->nr_outconns
- 1] = conn
;
69 EXPORT_SYMBOL_GPL(coresight_add_out_conn
);
72 * Add an input connection reference to @out_conn in the target's in_conns array
74 * @out_conn: Existing output connection to store as an input on the
75 * connection's remote device.
77 int coresight_add_in_conn(struct coresight_connection
*out_conn
)
80 struct device
*dev
= out_conn
->dest_dev
->dev
.parent
;
81 struct coresight_platform_data
*pdata
= out_conn
->dest_dev
->pdata
;
83 for (i
= 0; i
< pdata
->nr_inconns
; ++i
)
84 if (!pdata
->in_conns
[i
]) {
85 pdata
->in_conns
[i
] = out_conn
;
91 devm_krealloc_array(dev
, pdata
->in_conns
, pdata
->nr_inconns
,
92 sizeof(*pdata
->in_conns
), GFP_KERNEL
);
95 pdata
->in_conns
[pdata
->nr_inconns
- 1] = out_conn
;
98 EXPORT_SYMBOL_GPL(coresight_add_in_conn
);
100 static struct device
*
101 coresight_find_device_by_fwnode(struct fwnode_handle
*fwnode
)
103 struct device
*dev
= NULL
;
106 * If we have a non-configurable replicator, it will be found on the
109 dev
= bus_find_device_by_fwnode(&platform_bus_type
, fwnode
);
114 * We have a configurable component - circle through the AMBA bus
115 * looking for the device that matches the endpoint node.
117 return bus_find_device_by_fwnode(&amba_bustype
, fwnode
);
121 * Find a registered coresight device from a device fwnode.
122 * The node info is associated with the AMBA parent, but the
123 * csdev keeps a copy so iterate round the coresight bus to
126 struct coresight_device
*
127 coresight_find_csdev_by_fwnode(struct fwnode_handle
*r_fwnode
)
130 struct coresight_device
*csdev
= NULL
;
132 dev
= bus_find_device_by_fwnode(&coresight_bustype
, r_fwnode
);
134 csdev
= to_coresight_device(dev
);
139 EXPORT_SYMBOL_GPL(coresight_find_csdev_by_fwnode
);
142 static inline bool of_coresight_legacy_ep_is_input(struct device_node
*ep
)
144 return of_property_read_bool(ep
, "slave-mode");
147 static struct device_node
*of_coresight_get_port_parent(struct device_node
*ep
)
149 struct device_node
*parent
= of_graph_get_port_parent(ep
);
152 * Skip one-level up to the real device node, if we
153 * are using the new bindings.
155 if (of_node_name_eq(parent
, "in-ports") ||
156 of_node_name_eq(parent
, "out-ports"))
157 parent
= of_get_next_parent(parent
);
162 static inline struct device_node
*
163 of_coresight_get_output_ports_node(const struct device_node
*node
)
165 return of_get_child_by_name(node
, "out-ports");
168 static int of_coresight_get_cpu(struct device
*dev
)
171 struct device_node
*dn
;
176 dn
= of_parse_phandle(dev
->of_node
, "cpu", 0);
180 cpu
= of_cpu_node_to_id(dn
);
187 * of_coresight_parse_endpoint : Parse the given output endpoint @ep
188 * and fill the connection information in @pdata->out_conns
190 * Parses the local port, remote device name and the remote port.
193 * 0 - If the parsing completed without any fatal errors.
194 * -Errno - Fatal error, abort the scanning.
196 static int of_coresight_parse_endpoint(struct device
*dev
,
197 struct device_node
*ep
,
198 struct coresight_platform_data
*pdata
)
201 struct of_endpoint endpoint
, rendpoint
;
202 struct device_node
*rparent
= NULL
;
203 struct device_node
*rep
= NULL
;
204 struct device
*rdev
= NULL
;
205 struct fwnode_handle
*rdev_fwnode
;
206 struct coresight_connection conn
= {};
207 struct coresight_connection
*new_conn
;
210 /* Parse the local port details */
211 if (of_graph_parse_endpoint(ep
, &endpoint
))
214 * Get a handle on the remote endpoint and the device it is
217 rep
= of_graph_get_remote_endpoint(ep
);
220 rparent
= of_coresight_get_port_parent(rep
);
223 if (of_graph_parse_endpoint(rep
, &rendpoint
))
226 rdev_fwnode
= of_fwnode_handle(rparent
);
227 /* If the remote device is not available, defer probing */
228 rdev
= coresight_find_device_by_fwnode(rdev_fwnode
);
234 conn
.src_port
= endpoint
.port
;
236 * Hold the refcount to the target device. This could be
238 * 1) coresight_release_platform_data() if the probe fails or
239 * this device is unregistered.
240 * 2) While removing the target device via
241 * coresight_remove_match()
243 conn
.dest_fwnode
= fwnode_handle_get(rdev_fwnode
);
244 conn
.dest_port
= rendpoint
.port
;
246 new_conn
= coresight_add_out_conn(dev
, pdata
, &conn
);
247 if (IS_ERR_VALUE(new_conn
)) {
248 fwnode_handle_put(conn
.dest_fwnode
);
249 return PTR_ERR(new_conn
);
251 /* Connection record updated */
254 of_node_put(rparent
);
261 static int of_get_coresight_platform_data(struct device
*dev
,
262 struct coresight_platform_data
*pdata
)
265 struct device_node
*ep
= NULL
;
266 const struct device_node
*parent
= NULL
;
267 bool legacy_binding
= false;
268 struct device_node
*node
= dev
->of_node
;
270 parent
= of_coresight_get_output_ports_node(node
);
272 * If the DT uses obsoleted bindings, the ports are listed
273 * under the device and we need to filter out the input
278 * Avoid warnings in for_each_endpoint_of_node()
279 * if the device doesn't have any graph connections
281 if (!of_graph_is_present(node
))
283 legacy_binding
= true;
285 dev_warn_once(dev
, "Uses obsolete Coresight DT bindings\n");
288 /* Iterate through each output port to discover topology */
289 for_each_endpoint_of_node(parent
, ep
) {
291 * Legacy binding mixes input/output ports under the
292 * same parent. So, skip the input ports if we are dealing
293 * with legacy binding, as they processed with their
294 * connected output ports.
296 if (legacy_binding
&& of_coresight_legacy_ep_is_input(ep
))
299 ret
= of_coresight_parse_endpoint(dev
, ep
, pdata
);
310 of_get_coresight_platform_data(struct device
*dev
,
311 struct coresight_platform_data
*pdata
)
316 static inline int of_coresight_get_cpu(struct device
*dev
)
324 #include <acpi/actypes.h>
325 #include <acpi/processor.h>
327 /* ACPI Graph _DSD UUID : "ab02a46b-74c7-45a2-bd68-f7d344ef2153" */
328 static const guid_t acpi_graph_uuid
= GUID_INIT(0xab02a46b, 0x74c7, 0x45a2,
329 0xbd, 0x68, 0xf7, 0xd3,
330 0x44, 0xef, 0x21, 0x53);
331 /* Coresight ACPI Graph UUID : "3ecbc8b6-1d0e-4fb3-8107-e627f805c6cd" */
332 static const guid_t coresight_graph_uuid
= GUID_INIT(0x3ecbc8b6, 0x1d0e, 0x4fb3,
333 0x81, 0x07, 0xe6, 0x27,
334 0xf8, 0x05, 0xc6, 0xcd);
335 #define ACPI_CORESIGHT_LINK_SLAVE 0
336 #define ACPI_CORESIGHT_LINK_MASTER 1
338 static inline bool is_acpi_guid(const union acpi_object
*obj
)
340 return (obj
->type
== ACPI_TYPE_BUFFER
) && (obj
->buffer
.length
== 16);
344 * acpi_guid_matches - Checks if the given object is a GUID object and
345 * that it matches the supplied the GUID.
347 static inline bool acpi_guid_matches(const union acpi_object
*obj
,
350 return is_acpi_guid(obj
) &&
351 guid_equal((guid_t
*)obj
->buffer
.pointer
, guid
);
354 static inline bool is_acpi_dsd_graph_guid(const union acpi_object
*obj
)
356 return acpi_guid_matches(obj
, &acpi_graph_uuid
);
359 static inline bool is_acpi_coresight_graph_guid(const union acpi_object
*obj
)
361 return acpi_guid_matches(obj
, &coresight_graph_uuid
);
364 static inline bool is_acpi_coresight_graph(const union acpi_object
*obj
)
366 const union acpi_object
*graphid
, *guid
, *links
;
368 if (obj
->type
!= ACPI_TYPE_PACKAGE
||
369 obj
->package
.count
< 3)
372 graphid
= &obj
->package
.elements
[0];
373 guid
= &obj
->package
.elements
[1];
374 links
= &obj
->package
.elements
[2];
376 if (graphid
->type
!= ACPI_TYPE_INTEGER
||
377 links
->type
!= ACPI_TYPE_INTEGER
)
380 return is_acpi_coresight_graph_guid(guid
);
384 * acpi_validate_dsd_graph - Make sure the given _DSD graph conforms
385 * to the ACPI _DSD Graph specification.
387 * ACPI Devices Graph property has the following format:
389 * Revision - Integer, must be 0
390 * NumberOfGraphs - Integer, N indicating the following list.
396 * And each Graph entry has the following format:
398 * GraphID - Integer, identifying a graph the device belongs to.
399 * UUID - UUID identifying the specification that governs
400 * this graph. (e.g, see is_acpi_coresight_graph())
401 * NumberOfLinks - Number "N" of connections on this node of the graph.
407 * Where each "Links" entry has the following format:
410 * SourcePortAddress - Integer
411 * DestinationPortAddress - Integer
412 * DestinationDeviceName - Reference to another device
413 * ( --- CoreSight specific extensions below ---)
414 * DirectionOfFlow - Integer 1 for output(master)
419 * For a Funnel device
424 * Name (_DSD, Package() {
425 * // DSD Package contains tuples of { Proeprty_Type_UUID, Package() }
426 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), //Std. Property UUID
428 * Package(2) { "property-name", <property-value> }
431 * ToUUID("ab02a46b-74c7-45a2-bd68-f7d344ef2153"), // ACPI Graph UUID
434 * 1, // NumberOfGraphs.
435 * Package() { // Graph[0] Package
437 * // Coresight Graph UUID
438 * ToUUID("3ecbc8b6-1d0e-4fb3-8107-e627f805c6cd"),
439 * 3, // NumberOfLinks aka ports
440 * // Link[0]: Output_0 -> Replicator:Input_0
441 * Package () { 0, 0, \_SB_.RPL0, 1 },
442 * // Link[1]: Input_0 <- Cluster0_Funnel0:Output_0
443 * Package () { 0, 0, \_SB_.CLU0.FUN0, 0 },
444 * // Link[2]: Input_1 <- Cluster1_Funnel0:Output_0
445 * Package () { 1, 0, \_SB_.CLU1.FUN0, 0 },
446 * } // End of Graph[0] Package
448 * }, // End of ACPI Graph Property
451 static inline bool acpi_validate_dsd_graph(const union acpi_object
*graph
)
454 const union acpi_object
*rev
, *nr_graphs
;
456 /* The graph must contain at least the Revision and Number of Graphs */
457 if (graph
->package
.count
< 2)
460 rev
= &graph
->package
.elements
[0];
461 nr_graphs
= &graph
->package
.elements
[1];
463 if (rev
->type
!= ACPI_TYPE_INTEGER
||
464 nr_graphs
->type
!= ACPI_TYPE_INTEGER
)
467 /* We only support revision 0 */
468 if (rev
->integer
.value
!= 0)
471 n
= nr_graphs
->integer
.value
;
472 /* CoreSight devices are only part of a single Graph */
476 /* Make sure the ACPI graph package has right number of elements */
477 if (graph
->package
.count
!= (n
+ 2))
481 * Each entry must be a graph package with at least 3 members :
482 * { GraphID, UUID, NumberOfLinks(n), Links[.],... }
484 for (i
= 2; i
< n
+ 2; i
++) {
485 const union acpi_object
*obj
= &graph
->package
.elements
[i
];
487 if (obj
->type
!= ACPI_TYPE_PACKAGE
||
488 obj
->package
.count
< 3)
495 /* acpi_get_dsd_graph - Find the _DSD Graph property for the given device. */
496 static const union acpi_object
*
497 acpi_get_dsd_graph(struct acpi_device
*adev
, struct acpi_buffer
*buf
)
501 const union acpi_object
*dsd
;
503 status
= acpi_evaluate_object_typed(adev
->handle
, "_DSD", NULL
,
504 buf
, ACPI_TYPE_PACKAGE
);
505 if (ACPI_FAILURE(status
))
511 * _DSD property consists tuples { Prop_UUID, Package() }
512 * Iterate through all the packages and find the Graph.
514 for (i
= 0; i
+ 1 < dsd
->package
.count
; i
+= 2) {
515 const union acpi_object
*guid
, *package
;
517 guid
= &dsd
->package
.elements
[i
];
518 package
= &dsd
->package
.elements
[i
+ 1];
520 /* All _DSD elements must have a UUID and a Package */
521 if (!is_acpi_guid(guid
) || package
->type
!= ACPI_TYPE_PACKAGE
)
523 /* Skip the non-Graph _DSD packages */
524 if (!is_acpi_dsd_graph_guid(guid
))
526 if (acpi_validate_dsd_graph(package
))
528 /* Invalid graph format, continue */
529 dev_warn(&adev
->dev
, "Invalid Graph _DSD property\n");
536 acpi_validate_coresight_graph(const union acpi_object
*cs_graph
)
540 nlinks
= cs_graph
->package
.elements
[2].integer
.value
;
542 * Graph must have the following fields :
543 * { GraphID, GraphUUID, NumberOfLinks, Links... }
545 if (cs_graph
->package
.count
!= (nlinks
+ 3))
547 /* The links are validated in acpi_coresight_parse_link() */
552 * acpi_get_coresight_graph - Parse the device _DSD tables and find
553 * the Graph property matching the CoreSight Graphs.
555 * Returns the pointer to the CoreSight Graph Package when found. Otherwise
558 static const union acpi_object
*
559 acpi_get_coresight_graph(struct acpi_device
*adev
, struct acpi_buffer
*buf
)
561 const union acpi_object
*graph_list
, *graph
;
564 graph_list
= acpi_get_dsd_graph(adev
, buf
);
568 nr_graphs
= graph_list
->package
.elements
[1].integer
.value
;
570 for (i
= 2; i
< nr_graphs
+ 2; i
++) {
571 graph
= &graph_list
->package
.elements
[i
];
572 if (!is_acpi_coresight_graph(graph
))
574 if (acpi_validate_coresight_graph(graph
))
576 /* Invalid graph format */
584 * acpi_coresight_parse_link - Parse the given Graph connection
585 * of the device and populate the coresight_connection for an output
588 * CoreSight Graph specification mandates that the direction of the data
589 * flow must be specified in the link. i.e,
591 * SourcePortAddress, // Integer
592 * DestinationPortAddress, // Integer
593 * DestinationDeviceName, // Reference to another device
594 * DirectionOfFlow, // 1 for output(master), 0 for input(slave)
596 * Returns the direction of the data flow [ Input(slave) or Output(master) ]
598 * Returns an negative error number otherwise.
600 static int acpi_coresight_parse_link(struct acpi_device
*adev
,
601 const union acpi_object
*link
,
602 struct coresight_connection
*conn
)
605 const union acpi_object
*fields
;
606 struct acpi_device
*r_adev
;
609 if (link
->type
!= ACPI_TYPE_PACKAGE
||
610 link
->package
.count
!= 4)
613 fields
= link
->package
.elements
;
615 if (fields
[0].type
!= ACPI_TYPE_INTEGER
||
616 fields
[1].type
!= ACPI_TYPE_INTEGER
||
617 fields
[2].type
!= ACPI_TYPE_LOCAL_REFERENCE
||
618 fields
[3].type
!= ACPI_TYPE_INTEGER
)
621 r_adev
= acpi_fetch_acpi_dev(fields
[2].reference
.handle
);
625 dir
= fields
[3].integer
.value
;
626 if (dir
== ACPI_CORESIGHT_LINK_MASTER
) {
627 conn
->src_port
= fields
[0].integer
.value
;
628 conn
->dest_port
= fields
[1].integer
.value
;
629 rdev
= coresight_find_device_by_fwnode(&r_adev
->fwnode
);
631 return -EPROBE_DEFER
;
633 * Hold the refcount to the target device. This could be
635 * 1) coresight_release_platform_data() if the probe fails or
636 * this device is unregistered.
637 * 2) While removing the target device via
638 * coresight_remove_match().
640 conn
->dest_fwnode
= fwnode_handle_get(&r_adev
->fwnode
);
641 } else if (dir
== ACPI_CORESIGHT_LINK_SLAVE
) {
643 * We are only interested in the port number
644 * for the input ports at this component.
645 * Store the port number in child_port.
647 conn
->dest_port
= fields
[0].integer
.value
;
649 /* Invalid direction */
657 * acpi_coresight_parse_graph - Parse the _DSD CoreSight graph
658 * connection information and populate the supplied coresight_platform_data
661 static int acpi_coresight_parse_graph(struct device
*dev
,
662 struct acpi_device
*adev
,
663 struct coresight_platform_data
*pdata
)
667 const union acpi_object
*graph
;
668 struct coresight_connection conn
, zero_conn
= {};
669 struct coresight_connection
*new_conn
;
670 struct acpi_buffer buf
= { ACPI_ALLOCATE_BUFFER
, NULL
};
672 graph
= acpi_get_coresight_graph(adev
, &buf
);
674 * There are no graph connections, which is fine for some components.
680 nlinks
= graph
->package
.elements
[2].integer
.value
;
684 for (i
= 0; i
< nlinks
; i
++) {
685 const union acpi_object
*link
= &graph
->package
.elements
[3 + i
];
689 dir
= acpi_coresight_parse_link(adev
, link
, &conn
);
695 if (dir
== ACPI_CORESIGHT_LINK_MASTER
) {
696 new_conn
= coresight_add_out_conn(dev
, pdata
, &conn
);
697 if (IS_ERR(new_conn
)) {
698 ret
= PTR_ERR(new_conn
);
706 * When ACPI fails to alloc a buffer, it will free the buffer
707 * created via ACPI_ALLOCATE_BUFFER and set to NULL.
708 * ACPI_FREE can handle NULL pointers, so free it directly.
710 ACPI_FREE(buf
.pointer
);
715 * acpi_handle_to_logical_cpuid - Map a given acpi_handle to the
716 * logical CPU id of the corresponding CPU device.
718 * Returns the logical CPU id when found. Otherwise returns >= nr_cpus_id.
721 acpi_handle_to_logical_cpuid(acpi_handle handle
)
724 struct acpi_processor
*pr
;
726 for_each_possible_cpu(i
) {
727 pr
= per_cpu(processors
, i
);
728 if (pr
&& pr
->handle
== handle
)
736 * acpi_coresigh_get_cpu - Find the logical CPU id of the CPU associated
737 * with this coresight device. With ACPI bindings, the CoreSight components
738 * are listed as child device of the associated CPU.
740 * Returns the logical CPU id when found. Otherwise returns 0.
742 static int acpi_coresight_get_cpu(struct device
*dev
)
745 acpi_handle cpu_handle
;
747 struct acpi_device
*adev
= ACPI_COMPANION(dev
);
751 status
= acpi_get_parent(adev
->handle
, &cpu_handle
);
752 if (ACPI_FAILURE(status
))
755 cpu
= acpi_handle_to_logical_cpuid(cpu_handle
);
756 if (cpu
>= nr_cpu_ids
)
762 acpi_get_coresight_platform_data(struct device
*dev
,
763 struct coresight_platform_data
*pdata
)
765 struct acpi_device
*adev
;
767 adev
= ACPI_COMPANION(dev
);
771 return acpi_coresight_parse_graph(dev
, adev
, pdata
);
777 acpi_get_coresight_platform_data(struct device
*dev
,
778 struct coresight_platform_data
*pdata
)
783 static inline int acpi_coresight_get_cpu(struct device
*dev
)
789 int coresight_get_cpu(struct device
*dev
)
791 if (is_of_node(dev
->fwnode
))
792 return of_coresight_get_cpu(dev
);
793 else if (is_acpi_device_node(dev
->fwnode
))
794 return acpi_coresight_get_cpu(dev
);
797 EXPORT_SYMBOL_GPL(coresight_get_cpu
);
799 struct coresight_platform_data
*
800 coresight_get_platform_data(struct device
*dev
)
803 struct coresight_platform_data
*pdata
= NULL
;
804 struct fwnode_handle
*fwnode
= dev_fwnode(dev
);
806 if (IS_ERR_OR_NULL(fwnode
))
809 pdata
= devm_kzalloc(dev
, sizeof(*pdata
), GFP_KERNEL
);
815 if (is_of_node(fwnode
))
816 ret
= of_get_coresight_platform_data(dev
, pdata
);
817 else if (is_acpi_device_node(fwnode
))
818 ret
= acpi_get_coresight_platform_data(dev
, pdata
);
823 if (!IS_ERR_OR_NULL(pdata
))
824 /* Cleanup the connection information */
825 coresight_release_platform_data(NULL
, dev
, pdata
);
828 EXPORT_SYMBOL_GPL(coresight_get_platform_data
);