]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/hwtracing/coresight/coresight-platform.c
net: phy: micrel: Discern KSZ8051 and KSZ8795 PHYs
[linux.git] / drivers / hwtracing / coresight / coresight-platform.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2012, The Linux Foundation. All rights reserved.
4  */
5
6 #include <linux/acpi.h>
7 #include <linux/types.h>
8 #include <linux/err.h>
9 #include <linux/slab.h>
10 #include <linux/clk.h>
11 #include <linux/of.h>
12 #include <linux/of_address.h>
13 #include <linux/of_graph.h>
14 #include <linux/of_platform.h>
15 #include <linux/platform_device.h>
16 #include <linux/amba/bus.h>
17 #include <linux/coresight.h>
18 #include <linux/cpumask.h>
19 #include <asm/smp_plat.h>
20
21 #include "coresight-priv.h"
22 /*
23  * coresight_alloc_conns: Allocate connections record for each output
24  * port from the device.
25  */
26 static int coresight_alloc_conns(struct device *dev,
27                                  struct coresight_platform_data *pdata)
28 {
29         if (pdata->nr_outport) {
30                 pdata->conns = devm_kzalloc(dev, pdata->nr_outport *
31                                             sizeof(*pdata->conns),
32                                             GFP_KERNEL);
33                 if (!pdata->conns)
34                         return -ENOMEM;
35         }
36
37         return 0;
38 }
39
40 static struct device *
41 coresight_find_device_by_fwnode(struct fwnode_handle *fwnode)
42 {
43         struct device *dev = NULL;
44
45         /*
46          * If we have a non-configurable replicator, it will be found on the
47          * platform bus.
48          */
49         dev = bus_find_device_by_fwnode(&platform_bus_type, fwnode);
50         if (dev)
51                 return dev;
52
53         /*
54          * We have a configurable component - circle through the AMBA bus
55          * looking for the device that matches the endpoint node.
56          */
57         return bus_find_device_by_fwnode(&amba_bustype, fwnode);
58 }
59
60 #ifdef CONFIG_OF
61 static inline bool of_coresight_legacy_ep_is_input(struct device_node *ep)
62 {
63         return of_property_read_bool(ep, "slave-mode");
64 }
65
66 static void of_coresight_get_ports_legacy(const struct device_node *node,
67                                           int *nr_inport, int *nr_outport)
68 {
69         struct device_node *ep = NULL;
70         int in = 0, out = 0;
71
72         do {
73                 ep = of_graph_get_next_endpoint(node, ep);
74                 if (!ep)
75                         break;
76
77                 if (of_coresight_legacy_ep_is_input(ep))
78                         in++;
79                 else
80                         out++;
81
82         } while (ep);
83
84         *nr_inport = in;
85         *nr_outport = out;
86 }
87
88 static struct device_node *of_coresight_get_port_parent(struct device_node *ep)
89 {
90         struct device_node *parent = of_graph_get_port_parent(ep);
91
92         /*
93          * Skip one-level up to the real device node, if we
94          * are using the new bindings.
95          */
96         if (of_node_name_eq(parent, "in-ports") ||
97             of_node_name_eq(parent, "out-ports"))
98                 parent = of_get_next_parent(parent);
99
100         return parent;
101 }
102
103 static inline struct device_node *
104 of_coresight_get_input_ports_node(const struct device_node *node)
105 {
106         return of_get_child_by_name(node, "in-ports");
107 }
108
109 static inline struct device_node *
110 of_coresight_get_output_ports_node(const struct device_node *node)
111 {
112         return of_get_child_by_name(node, "out-ports");
113 }
114
115 static inline int
116 of_coresight_count_ports(struct device_node *port_parent)
117 {
118         int i = 0;
119         struct device_node *ep = NULL;
120
121         while ((ep = of_graph_get_next_endpoint(port_parent, ep)))
122                 i++;
123         return i;
124 }
125
126 static void of_coresight_get_ports(const struct device_node *node,
127                                    int *nr_inport, int *nr_outport)
128 {
129         struct device_node *input_ports = NULL, *output_ports = NULL;
130
131         input_ports = of_coresight_get_input_ports_node(node);
132         output_ports = of_coresight_get_output_ports_node(node);
133
134         if (input_ports || output_ports) {
135                 if (input_ports) {
136                         *nr_inport = of_coresight_count_ports(input_ports);
137                         of_node_put(input_ports);
138                 }
139                 if (output_ports) {
140                         *nr_outport = of_coresight_count_ports(output_ports);
141                         of_node_put(output_ports);
142                 }
143         } else {
144                 /* Fall back to legacy DT bindings parsing */
145                 of_coresight_get_ports_legacy(node, nr_inport, nr_outport);
146         }
147 }
148
149 static int of_coresight_get_cpu(struct device *dev)
150 {
151         int cpu;
152         struct device_node *dn;
153
154         if (!dev->of_node)
155                 return -ENODEV;
156
157         dn = of_parse_phandle(dev->of_node, "cpu", 0);
158         if (!dn)
159                 return -ENODEV;
160
161         cpu = of_cpu_node_to_id(dn);
162         of_node_put(dn);
163
164         return cpu;
165 }
166
167 /*
168  * of_coresight_parse_endpoint : Parse the given output endpoint @ep
169  * and fill the connection information in @conn
170  *
171  * Parses the local port, remote device name and the remote port.
172  *
173  * Returns :
174  *       1      - If the parsing is successful and a connection record
175  *                was created for an output connection.
176  *       0      - If the parsing completed without any fatal errors.
177  *      -Errno  - Fatal error, abort the scanning.
178  */
179 static int of_coresight_parse_endpoint(struct device *dev,
180                                        struct device_node *ep,
181                                        struct coresight_connection *conn)
182 {
183         int ret = 0;
184         struct of_endpoint endpoint, rendpoint;
185         struct device_node *rparent = NULL;
186         struct device_node *rep = NULL;
187         struct device *rdev = NULL;
188         struct fwnode_handle *rdev_fwnode;
189
190         do {
191                 /* Parse the local port details */
192                 if (of_graph_parse_endpoint(ep, &endpoint))
193                         break;
194                 /*
195                  * Get a handle on the remote endpoint and the device it is
196                  * attached to.
197                  */
198                 rep = of_graph_get_remote_endpoint(ep);
199                 if (!rep)
200                         break;
201                 rparent = of_coresight_get_port_parent(rep);
202                 if (!rparent)
203                         break;
204                 if (of_graph_parse_endpoint(rep, &rendpoint))
205                         break;
206
207                 rdev_fwnode = of_fwnode_handle(rparent);
208                 /* If the remote device is not available, defer probing */
209                 rdev = coresight_find_device_by_fwnode(rdev_fwnode);
210                 if (!rdev) {
211                         ret = -EPROBE_DEFER;
212                         break;
213                 }
214
215                 conn->outport = endpoint.port;
216                 /*
217                  * Hold the refcount to the target device. This could be
218                  * released via:
219                  * 1) coresight_release_platform_data() if the probe fails or
220                  *    this device is unregistered.
221                  * 2) While removing the target device via
222                  *    coresight_remove_match()
223                  */
224                 conn->child_fwnode = fwnode_handle_get(rdev_fwnode);
225                 conn->child_port = rendpoint.port;
226                 /* Connection record updated */
227                 ret = 1;
228         } while (0);
229
230         of_node_put(rparent);
231         of_node_put(rep);
232         put_device(rdev);
233
234         return ret;
235 }
236
237 static int of_get_coresight_platform_data(struct device *dev,
238                                           struct coresight_platform_data *pdata)
239 {
240         int ret = 0;
241         struct coresight_connection *conn;
242         struct device_node *ep = NULL;
243         const struct device_node *parent = NULL;
244         bool legacy_binding = false;
245         struct device_node *node = dev->of_node;
246
247         /* Get the number of input and output port for this component */
248         of_coresight_get_ports(node, &pdata->nr_inport, &pdata->nr_outport);
249
250         /* If there are no output connections, we are done */
251         if (!pdata->nr_outport)
252                 return 0;
253
254         ret = coresight_alloc_conns(dev, pdata);
255         if (ret)
256                 return ret;
257
258         parent = of_coresight_get_output_ports_node(node);
259         /*
260          * If the DT uses obsoleted bindings, the ports are listed
261          * under the device and we need to filter out the input
262          * ports.
263          */
264         if (!parent) {
265                 legacy_binding = true;
266                 parent = node;
267                 dev_warn_once(dev, "Uses obsolete Coresight DT bindings\n");
268         }
269
270         conn = pdata->conns;
271
272         /* Iterate through each output port to discover topology */
273         while ((ep = of_graph_get_next_endpoint(parent, ep))) {
274                 /*
275                  * Legacy binding mixes input/output ports under the
276                  * same parent. So, skip the input ports if we are dealing
277                  * with legacy binding, as they processed with their
278                  * connected output ports.
279                  */
280                 if (legacy_binding && of_coresight_legacy_ep_is_input(ep))
281                         continue;
282
283                 ret = of_coresight_parse_endpoint(dev, ep, conn);
284                 switch (ret) {
285                 case 1:
286                         conn++;         /* Fall through */
287                 case 0:
288                         break;
289                 default:
290                         return ret;
291                 }
292         }
293
294         return 0;
295 }
296 #else
297 static inline int
298 of_get_coresight_platform_data(struct device *dev,
299                                struct coresight_platform_data *pdata)
300 {
301         return -ENOENT;
302 }
303
304 static inline int of_coresight_get_cpu(struct device *dev)
305 {
306         return -ENODEV;
307 }
308 #endif
309
310 #ifdef CONFIG_ACPI
311
312 #include <acpi/actypes.h>
313 #include <acpi/processor.h>
314
315 /* ACPI Graph _DSD UUID : "ab02a46b-74c7-45a2-bd68-f7d344ef2153" */
316 static const guid_t acpi_graph_uuid = GUID_INIT(0xab02a46b, 0x74c7, 0x45a2,
317                                                 0xbd, 0x68, 0xf7, 0xd3,
318                                                 0x44, 0xef, 0x21, 0x53);
319 /* Coresight ACPI Graph UUID : "3ecbc8b6-1d0e-4fb3-8107-e627f805c6cd" */
320 static const guid_t coresight_graph_uuid = GUID_INIT(0x3ecbc8b6, 0x1d0e, 0x4fb3,
321                                                      0x81, 0x07, 0xe6, 0x27,
322                                                      0xf8, 0x05, 0xc6, 0xcd);
323 #define ACPI_CORESIGHT_LINK_SLAVE       0
324 #define ACPI_CORESIGHT_LINK_MASTER      1
325
326 static inline bool is_acpi_guid(const union acpi_object *obj)
327 {
328         return (obj->type == ACPI_TYPE_BUFFER) && (obj->buffer.length == 16);
329 }
330
331 /*
332  * acpi_guid_matches    - Checks if the given object is a GUID object and
333  * that it matches the supplied the GUID.
334  */
335 static inline bool acpi_guid_matches(const union acpi_object *obj,
336                                    const guid_t *guid)
337 {
338         return is_acpi_guid(obj) &&
339                guid_equal((guid_t *)obj->buffer.pointer, guid);
340 }
341
342 static inline bool is_acpi_dsd_graph_guid(const union acpi_object *obj)
343 {
344         return acpi_guid_matches(obj, &acpi_graph_uuid);
345 }
346
347 static inline bool is_acpi_coresight_graph_guid(const union acpi_object *obj)
348 {
349         return acpi_guid_matches(obj, &coresight_graph_uuid);
350 }
351
352 static inline bool is_acpi_coresight_graph(const union acpi_object *obj)
353 {
354         const union acpi_object *graphid, *guid, *links;
355
356         if (obj->type != ACPI_TYPE_PACKAGE ||
357             obj->package.count < 3)
358                 return false;
359
360         graphid = &obj->package.elements[0];
361         guid = &obj->package.elements[1];
362         links = &obj->package.elements[2];
363
364         if (graphid->type != ACPI_TYPE_INTEGER ||
365             links->type != ACPI_TYPE_INTEGER)
366                 return false;
367
368         return is_acpi_coresight_graph_guid(guid);
369 }
370
371 /*
372  * acpi_validate_dsd_graph      - Make sure the given _DSD graph conforms
373  * to the ACPI _DSD Graph specification.
374  *
375  * ACPI Devices Graph property has the following format:
376  *  {
377  *      Revision        - Integer, must be 0
378  *      NumberOfGraphs  - Integer, N indicating the following list.
379  *      Graph[1],
380  *       ...
381  *      Graph[N]
382  *  }
383  *
384  * And each Graph entry has the following format:
385  *  {
386  *      GraphID         - Integer, identifying a graph the device belongs to.
387  *      UUID            - UUID identifying the specification that governs
388  *                        this graph. (e.g, see is_acpi_coresight_graph())
389  *      NumberOfLinks   - Number "N" of connections on this node of the graph.
390  *      Links[1]
391  *      ...
392  *      Links[N]
393  *  }
394  *
395  * Where each "Links" entry has the following format:
396  *
397  * {
398  *      SourcePortAddress       - Integer
399  *      DestinationPortAddress  - Integer
400  *      DestinationDeviceName   - Reference to another device
401  *      ( --- CoreSight specific extensions below ---)
402  *      DirectionOfFlow         - Integer 1 for output(master)
403  *                                0 for input(slave)
404  * }
405  *
406  * e.g:
407  * For a Funnel device
408  *
409  * Device(MFUN) {
410  *   ...
411  *
412  *   Name (_DSD, Package() {
413  *      // DSD Package contains tuples of {  Proeprty_Type_UUID, Package() }
414  *      ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), //Std. Property UUID
415  *      Package() {
416  *              Package(2) { "property-name", <property-value> }
417  *      },
418  *
419  *      ToUUID("ab02a46b-74c7-45a2-bd68-f7d344ef2153"), // ACPI Graph UUID
420  *      Package() {
421  *        0,            // Revision
422  *        1,            // NumberOfGraphs.
423  *        Package() {   // Graph[0] Package
424  *           1,         // GraphID
425  *           // Coresight Graph UUID
426  *           ToUUID("3ecbc8b6-1d0e-4fb3-8107-e627f805c6cd"),
427  *           3,         // NumberOfLinks aka ports
428  *           // Link[0]: Output_0 -> Replicator:Input_0
429  *           Package () { 0, 0, \_SB_.RPL0, 1 },
430  *           // Link[1]: Input_0 <- Cluster0_Funnel0:Output_0
431  *           Package () { 0, 0, \_SB_.CLU0.FUN0, 0 },
432  *           // Link[2]: Input_1 <- Cluster1_Funnel0:Output_0
433  *            Package () { 1, 0, \_SB_.CLU1.FUN0, 0 },
434  *        }     // End of Graph[0] Package
435  *
436  *      }, // End of ACPI Graph Property
437  *  })
438  */
439 static inline bool acpi_validate_dsd_graph(const union acpi_object *graph)
440 {
441         int i, n;
442         const union acpi_object *rev, *nr_graphs;
443
444         /* The graph must contain at least the Revision and Number of Graphs */
445         if (graph->package.count < 2)
446                 return false;
447
448         rev = &graph->package.elements[0];
449         nr_graphs = &graph->package.elements[1];
450
451         if (rev->type != ACPI_TYPE_INTEGER ||
452             nr_graphs->type != ACPI_TYPE_INTEGER)
453                 return false;
454
455         /* We only support revision 0 */
456         if (rev->integer.value != 0)
457                 return false;
458
459         n = nr_graphs->integer.value;
460         /* CoreSight devices are only part of a single Graph */
461         if (n != 1)
462                 return false;
463
464         /* Make sure the ACPI graph package has right number of elements */
465         if (graph->package.count != (n + 2))
466                 return false;
467
468         /*
469          * Each entry must be a graph package with at least 3 members :
470          * { GraphID, UUID, NumberOfLinks(n), Links[.],... }
471          */
472         for (i = 2; i < n + 2; i++) {
473                 const union acpi_object *obj = &graph->package.elements[i];
474
475                 if (obj->type != ACPI_TYPE_PACKAGE ||
476                     obj->package.count < 3)
477                         return false;
478         }
479
480         return true;
481 }
482
483 /* acpi_get_dsd_graph   - Find the _DSD Graph property for the given device. */
484 const union acpi_object *
485 acpi_get_dsd_graph(struct acpi_device *adev)
486 {
487         int i;
488         struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
489         acpi_status status;
490         const union acpi_object *dsd;
491
492         status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL,
493                                             &buf, ACPI_TYPE_PACKAGE);
494         if (ACPI_FAILURE(status))
495                 return NULL;
496
497         dsd = buf.pointer;
498
499         /*
500          * _DSD property consists tuples { Prop_UUID, Package() }
501          * Iterate through all the packages and find the Graph.
502          */
503         for (i = 0; i + 1 < dsd->package.count; i += 2) {
504                 const union acpi_object *guid, *package;
505
506                 guid = &dsd->package.elements[i];
507                 package = &dsd->package.elements[i + 1];
508
509                 /* All _DSD elements must have a UUID and a Package */
510                 if (!is_acpi_guid(guid) || package->type != ACPI_TYPE_PACKAGE)
511                         break;
512                 /* Skip the non-Graph _DSD packages */
513                 if (!is_acpi_dsd_graph_guid(guid))
514                         continue;
515                 if (acpi_validate_dsd_graph(package))
516                         return package;
517                 /* Invalid graph format, continue */
518                 dev_warn(&adev->dev, "Invalid Graph _DSD property\n");
519         }
520
521         return NULL;
522 }
523
524 static inline bool
525 acpi_validate_coresight_graph(const union acpi_object *cs_graph)
526 {
527         int nlinks;
528
529         nlinks = cs_graph->package.elements[2].integer.value;
530         /*
531          * Graph must have the following fields :
532          * { GraphID, GraphUUID, NumberOfLinks, Links... }
533          */
534         if (cs_graph->package.count != (nlinks + 3))
535                 return false;
536         /* The links are validated in acpi_coresight_parse_link() */
537         return true;
538 }
539
540 /*
541  * acpi_get_coresight_graph     - Parse the device _DSD tables and find
542  * the Graph property matching the CoreSight Graphs.
543  *
544  * Returns the pointer to the CoreSight Graph Package when found. Otherwise
545  * returns NULL.
546  */
547 const union acpi_object *
548 acpi_get_coresight_graph(struct acpi_device *adev)
549 {
550         const union acpi_object *graph_list, *graph;
551         int i, nr_graphs;
552
553         graph_list = acpi_get_dsd_graph(adev);
554         if (!graph_list)
555                 return graph_list;
556
557         nr_graphs = graph_list->package.elements[1].integer.value;
558
559         for (i = 2; i < nr_graphs + 2; i++) {
560                 graph = &graph_list->package.elements[i];
561                 if (!is_acpi_coresight_graph(graph))
562                         continue;
563                 if (acpi_validate_coresight_graph(graph))
564                         return graph;
565                 /* Invalid graph format */
566                 break;
567         }
568
569         return NULL;
570 }
571
572 /*
573  * acpi_coresight_parse_link    - Parse the given Graph connection
574  * of the device and populate the coresight_connection for an output
575  * connection.
576  *
577  * CoreSight Graph specification mandates that the direction of the data
578  * flow must be specified in the link. i.e,
579  *
580  *      SourcePortAddress,      // Integer
581  *      DestinationPortAddress, // Integer
582  *      DestinationDeviceName,  // Reference to another device
583  *      DirectionOfFlow,        // 1 for output(master), 0 for input(slave)
584  *
585  * Returns the direction of the data flow [ Input(slave) or Output(master) ]
586  * upon success.
587  * Returns an negative error number otherwise.
588  */
589 static int acpi_coresight_parse_link(struct acpi_device *adev,
590                                      const union acpi_object *link,
591                                      struct coresight_connection *conn)
592 {
593         int rc, dir;
594         const union acpi_object *fields;
595         struct acpi_device *r_adev;
596         struct device *rdev;
597
598         if (link->type != ACPI_TYPE_PACKAGE ||
599             link->package.count != 4)
600                 return -EINVAL;
601
602         fields = link->package.elements;
603
604         if (fields[0].type != ACPI_TYPE_INTEGER ||
605             fields[1].type != ACPI_TYPE_INTEGER ||
606             fields[2].type != ACPI_TYPE_LOCAL_REFERENCE ||
607             fields[3].type != ACPI_TYPE_INTEGER)
608                 return -EINVAL;
609
610         rc = acpi_bus_get_device(fields[2].reference.handle, &r_adev);
611         if (rc)
612                 return rc;
613
614         dir = fields[3].integer.value;
615         if (dir == ACPI_CORESIGHT_LINK_MASTER) {
616                 conn->outport = fields[0].integer.value;
617                 conn->child_port = fields[1].integer.value;
618                 rdev = coresight_find_device_by_fwnode(&r_adev->fwnode);
619                 if (!rdev)
620                         return -EPROBE_DEFER;
621                 /*
622                  * Hold the refcount to the target device. This could be
623                  * released via:
624                  * 1) coresight_release_platform_data() if the probe fails or
625                  *    this device is unregistered.
626                  * 2) While removing the target device via
627                  *    coresight_remove_match().
628                  */
629                 conn->child_fwnode = fwnode_handle_get(&r_adev->fwnode);
630         }
631
632         return dir;
633 }
634
635 /*
636  * acpi_coresight_parse_graph   - Parse the _DSD CoreSight graph
637  * connection information and populate the supplied coresight_platform_data
638  * instance.
639  */
640 static int acpi_coresight_parse_graph(struct acpi_device *adev,
641                                       struct coresight_platform_data *pdata)
642 {
643         int rc, i, nlinks;
644         const union acpi_object *graph;
645         struct coresight_connection *conns, *ptr;
646
647         pdata->nr_inport = pdata->nr_outport = 0;
648         graph = acpi_get_coresight_graph(adev);
649         if (!graph)
650                 return -ENOENT;
651
652         nlinks = graph->package.elements[2].integer.value;
653         if (!nlinks)
654                 return 0;
655
656         /*
657          * To avoid scanning the table twice (once for finding the number of
658          * output links and then later for parsing the output links),
659          * cache the links information in one go and then later copy
660          * it to the pdata.
661          */
662         conns = devm_kcalloc(&adev->dev, nlinks, sizeof(*conns), GFP_KERNEL);
663         if (!conns)
664                 return -ENOMEM;
665         ptr = conns;
666         for (i = 0; i < nlinks; i++) {
667                 const union acpi_object *link = &graph->package.elements[3 + i];
668                 int dir;
669
670                 dir = acpi_coresight_parse_link(adev, link, ptr);
671                 if (dir < 0)
672                         return dir;
673
674                 if (dir == ACPI_CORESIGHT_LINK_MASTER) {
675                         pdata->nr_outport++;
676                         ptr++;
677                 } else {
678                         pdata->nr_inport++;
679                 }
680         }
681
682         rc = coresight_alloc_conns(&adev->dev, pdata);
683         if (rc)
684                 return rc;
685
686         /* Copy the connection information to the final location */
687         for (i = 0; i < pdata->nr_outport; i++)
688                 pdata->conns[i] = conns[i];
689
690         devm_kfree(&adev->dev, conns);
691         return 0;
692 }
693
694 /*
695  * acpi_handle_to_logical_cpuid - Map a given acpi_handle to the
696  * logical CPU id of the corresponding CPU device.
697  *
698  * Returns the logical CPU id when found. Otherwise returns >= nr_cpus_id.
699  */
700 static int
701 acpi_handle_to_logical_cpuid(acpi_handle handle)
702 {
703         int i;
704         struct acpi_processor *pr;
705
706         for_each_possible_cpu(i) {
707                 pr = per_cpu(processors, i);
708                 if (pr && pr->handle == handle)
709                         break;
710         }
711
712         return i;
713 }
714
715 /*
716  * acpi_coresigh_get_cpu - Find the logical CPU id of the CPU associated
717  * with this coresight device. With ACPI bindings, the CoreSight components
718  * are listed as child device of the associated CPU.
719  *
720  * Returns the logical CPU id when found. Otherwise returns 0.
721  */
722 static int acpi_coresight_get_cpu(struct device *dev)
723 {
724         int cpu;
725         acpi_handle cpu_handle;
726         acpi_status status;
727         struct acpi_device *adev = ACPI_COMPANION(dev);
728
729         if (!adev)
730                 return -ENODEV;
731         status = acpi_get_parent(adev->handle, &cpu_handle);
732         if (ACPI_FAILURE(status))
733                 return -ENODEV;
734
735         cpu = acpi_handle_to_logical_cpuid(cpu_handle);
736         if (cpu >= nr_cpu_ids)
737                 return -ENODEV;
738         return cpu;
739 }
740
741 static int
742 acpi_get_coresight_platform_data(struct device *dev,
743                                  struct coresight_platform_data *pdata)
744 {
745         struct acpi_device *adev;
746
747         adev = ACPI_COMPANION(dev);
748         if (!adev)
749                 return -EINVAL;
750
751         return acpi_coresight_parse_graph(adev, pdata);
752 }
753
754 #else
755
756 static inline int
757 acpi_get_coresight_platform_data(struct device *dev,
758                                  struct coresight_platform_data *pdata)
759 {
760         return -ENOENT;
761 }
762
763 static inline int acpi_coresight_get_cpu(struct device *dev)
764 {
765         return -ENODEV;
766 }
767 #endif
768
769 int coresight_get_cpu(struct device *dev)
770 {
771         if (is_of_node(dev->fwnode))
772                 return of_coresight_get_cpu(dev);
773         else if (is_acpi_device_node(dev->fwnode))
774                 return acpi_coresight_get_cpu(dev);
775         return 0;
776 }
777 EXPORT_SYMBOL_GPL(coresight_get_cpu);
778
779 struct coresight_platform_data *
780 coresight_get_platform_data(struct device *dev)
781 {
782         int ret = -ENOENT;
783         struct coresight_platform_data *pdata = NULL;
784         struct fwnode_handle *fwnode = dev_fwnode(dev);
785
786         if (IS_ERR_OR_NULL(fwnode))
787                 goto error;
788
789         pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
790         if (!pdata) {
791                 ret = -ENOMEM;
792                 goto error;
793         }
794
795         if (is_of_node(fwnode))
796                 ret = of_get_coresight_platform_data(dev, pdata);
797         else if (is_acpi_device_node(fwnode))
798                 ret = acpi_get_coresight_platform_data(dev, pdata);
799
800         if (!ret)
801                 return pdata;
802 error:
803         if (!IS_ERR_OR_NULL(pdata))
804                 /* Cleanup the connection information */
805                 coresight_release_platform_data(pdata);
806         return ERR_PTR(ret);
807 }
808 EXPORT_SYMBOL_GPL(coresight_get_platform_data);