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); 816