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