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