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