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 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 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_device_is_available(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 /* 249 * Get the firmware node of the filter source through the 250 * reference. This could be used to filter the source in 251 * building path. 252 */ 253 conn.filter_src_fwnode = 254 fwnode_find_reference(&ep->fwnode, "filter-source", 0); 255 if (IS_ERR(conn.filter_src_fwnode)) { 256 conn.filter_src_fwnode = NULL; 257 } else { 258 conn.filter_src_dev = 259 coresight_find_csdev_by_fwnode(conn.filter_src_fwnode); 260 if (conn.filter_src_dev && 261 !coresight_is_device_source(conn.filter_src_dev)) { 262 dev_warn(dev, "port %d: Filter handle is not a trace source : %s\n", 263 conn.src_port, dev_name(&conn.filter_src_dev->dev)); 264 conn.filter_src_dev = NULL; 265 conn.filter_src_fwnode = NULL; 266 } 267 } 268 269 new_conn = coresight_add_out_conn(dev, pdata, &conn); 270 if (IS_ERR_VALUE(new_conn)) { 271 fwnode_handle_put(conn.dest_fwnode); 272 return PTR_ERR(new_conn); 273 } 274 /* Connection record updated */ 275 } while (0); 276 277 of_node_put(rparent); 278 of_node_put(rep); 279 put_device(rdev); 280 281 return ret; 282 } 283 284 static int of_get_coresight_platform_data(struct device *dev, 285 struct coresight_platform_data *pdata) 286 { 287 int ret = 0; 288 struct device_node *ep = NULL; 289 const struct device_node *parent = NULL; 290 bool legacy_binding = false; 291 struct device_node *node = dev->of_node; 292 293 parent = of_coresight_get_output_ports_node(node); 294 /* 295 * If the DT uses obsoleted bindings, the ports are listed 296 * under the device and we need to filter out the input 297 * ports. 298 */ 299 if (!parent) { 300 /* 301 * Avoid warnings in for_each_endpoint_of_node() 302 * if the device doesn't have any graph connections 303 */ 304 if (!of_graph_is_present(node)) 305 return 0; 306 legacy_binding = true; 307 parent = node; 308 dev_warn_once(dev, "Uses obsolete Coresight DT bindings\n"); 309 } 310 311 /* Iterate through each output port to discover topology */ 312 for_each_endpoint_of_node(parent, ep) { 313 /* 314 * Legacy binding mixes input/output ports under the 315 * same parent. So, skip the input ports if we are dealing 316 * with legacy binding, as they processed with their 317 * connected output ports. 318 */ 319 if (legacy_binding && of_coresight_legacy_ep_is_input(ep)) 320 continue; 321 322 ret = of_coresight_parse_endpoint(dev, ep, pdata); 323 if (ret) { 324 of_node_put(ep); 325 return ret; 326 } 327 } 328 329 return 0; 330 } 331 #else 332 static int 333 of_get_coresight_platform_data(struct device *dev, 334 struct coresight_platform_data *pdata) 335 { 336 return -ENOENT; 337 } 338 339 static int of_coresight_get_cpu(struct device *dev) 340 { 341 return -ENODEV; 342 } 343 #endif 344 345 #ifdef CONFIG_ACPI 346 347 #include <acpi/actypes.h> 348 #include <acpi/processor.h> 349 350 /* ACPI Graph _DSD UUID : "ab02a46b-74c7-45a2-bd68-f7d344ef2153" */ 351 static const guid_t acpi_graph_uuid = GUID_INIT(0xab02a46b, 0x74c7, 0x45a2, 352 0xbd, 0x68, 0xf7, 0xd3, 353 0x44, 0xef, 0x21, 0x53); 354 /* Coresight ACPI Graph UUID : "3ecbc8b6-1d0e-4fb3-8107-e627f805c6cd" */ 355 static const guid_t coresight_graph_uuid = GUID_INIT(0x3ecbc8b6, 0x1d0e, 0x4fb3, 356 0x81, 0x07, 0xe6, 0x27, 357 0xf8, 0x05, 0xc6, 0xcd); 358 #define ACPI_CORESIGHT_LINK_SLAVE 0 359 #define ACPI_CORESIGHT_LINK_MASTER 1 360 361 static bool is_acpi_guid(const union acpi_object *obj) 362 { 363 return (obj->type == ACPI_TYPE_BUFFER) && (obj->buffer.length == 16); 364 } 365 366 /* 367 * acpi_guid_matches - Checks if the given object is a GUID object and 368 * that it matches the supplied the GUID. 369 */ 370 static bool acpi_guid_matches(const union acpi_object *obj, 371 const guid_t *guid) 372 { 373 return is_acpi_guid(obj) && 374 guid_equal((guid_t *)obj->buffer.pointer, guid); 375 } 376 377 static bool is_acpi_dsd_graph_guid(const union acpi_object *obj) 378 { 379 return acpi_guid_matches(obj, &acpi_graph_uuid); 380 } 381 382 static bool is_acpi_coresight_graph_guid(const union acpi_object *obj) 383 { 384 return acpi_guid_matches(obj, &coresight_graph_uuid); 385 } 386 387 static bool is_acpi_coresight_graph(const union acpi_object *obj) 388 { 389 const union acpi_object *graphid, *guid, *links; 390 391 if (obj->type != ACPI_TYPE_PACKAGE || 392 obj->package.count < 3) 393 return false; 394 395 graphid = &obj->package.elements[0]; 396 guid = &obj->package.elements[1]; 397 links = &obj->package.elements[2]; 398 399 if (graphid->type != ACPI_TYPE_INTEGER || 400 links->type != ACPI_TYPE_INTEGER) 401 return false; 402 403 return is_acpi_coresight_graph_guid(guid); 404 } 405 406 /* 407 * acpi_validate_dsd_graph - Make sure the given _DSD graph conforms 408 * to the ACPI _DSD Graph specification. 409 * 410 * ACPI Devices Graph property has the following format: 411 * { 412 * Revision - Integer, must be 0 413 * NumberOfGraphs - Integer, N indicating the following list. 414 * Graph[1], 415 * ... 416 * Graph[N] 417 * } 418 * 419 * And each Graph entry has the following format: 420 * { 421 * GraphID - Integer, identifying a graph the device belongs to. 422 * UUID - UUID identifying the specification that governs 423 * this graph. (e.g, see is_acpi_coresight_graph()) 424 * NumberOfLinks - Number "N" of connections on this node of the graph. 425 * Links[1] 426 * ... 427 * Links[N] 428 * } 429 * 430 * Where each "Links" entry has the following format: 431 * 432 * { 433 * SourcePortAddress - Integer 434 * DestinationPortAddress - Integer 435 * DestinationDeviceName - Reference to another device 436 * ( --- CoreSight specific extensions below ---) 437 * DirectionOfFlow - Integer 1 for output(master) 438 * 0 for input(slave) 439 * } 440 * 441 * e.g: 442 * For a Funnel device 443 * 444 * Device(MFUN) { 445 * ... 446 * 447 * Name (_DSD, Package() { 448 * // DSD Package contains tuples of { Proeprty_Type_UUID, Package() } 449 * ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), //Std. Property UUID 450 * Package() { 451 * Package(2) { "property-name", <property-value> } 452 * }, 453 * 454 * ToUUID("ab02a46b-74c7-45a2-bd68-f7d344ef2153"), // ACPI Graph UUID 455 * Package() { 456 * 0, // Revision 457 * 1, // NumberOfGraphs. 458 * Package() { // Graph[0] Package 459 * 1, // GraphID 460 * // Coresight Graph UUID 461 * ToUUID("3ecbc8b6-1d0e-4fb3-8107-e627f805c6cd"), 462 * 3, // NumberOfLinks aka ports 463 * // Link[0]: Output_0 -> Replicator:Input_0 464 * Package () { 0, 0, \_SB_.RPL0, 1 }, 465 * // Link[1]: Input_0 <- Cluster0_Funnel0:Output_0 466 * Package () { 0, 0, \_SB_.CLU0.FUN0, 0 }, 467 * // Link[2]: Input_1 <- Cluster1_Funnel0:Output_0 468 * Package () { 1, 0, \_SB_.CLU1.FUN0, 0 }, 469 * } // End of Graph[0] Package 470 * 471 * }, // End of ACPI Graph Property 472 * }) 473 */ 474 static bool acpi_validate_dsd_graph(const union acpi_object *graph) 475 { 476 int i, n; 477 const union acpi_object *rev, *nr_graphs; 478 479 /* The graph must contain at least the Revision and Number of Graphs */ 480 if (graph->package.count < 2) 481 return false; 482 483 rev = &graph->package.elements[0]; 484 nr_graphs = &graph->package.elements[1]; 485 486 if (rev->type != ACPI_TYPE_INTEGER || 487 nr_graphs->type != ACPI_TYPE_INTEGER) 488 return false; 489 490 /* We only support revision 0 */ 491 if (rev->integer.value != 0) 492 return false; 493 494 n = nr_graphs->integer.value; 495 /* CoreSight devices are only part of a single Graph */ 496 if (n != 1) 497 return false; 498 499 /* Make sure the ACPI graph package has right number of elements */ 500 if (graph->package.count != (n + 2)) 501 return false; 502 503 /* 504 * Each entry must be a graph package with at least 3 members : 505 * { GraphID, UUID, NumberOfLinks(n), Links[.],... } 506 */ 507 for (i = 2; i < n + 2; i++) { 508 const union acpi_object *obj = &graph->package.elements[i]; 509 510 if (obj->type != ACPI_TYPE_PACKAGE || 511 obj->package.count < 3) 512 return false; 513 } 514 515 return true; 516 } 517 518 /* acpi_get_dsd_graph - Find the _DSD Graph property for the given device. */ 519 static const union acpi_object * 520 acpi_get_dsd_graph(struct acpi_device *adev, struct acpi_buffer *buf) 521 { 522 int i; 523 acpi_status status; 524 const union acpi_object *dsd; 525 526 status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL, 527 buf, ACPI_TYPE_PACKAGE); 528 if (ACPI_FAILURE(status)) 529 return NULL; 530 531 dsd = buf->pointer; 532 533 /* 534 * _DSD property consists tuples { Prop_UUID, Package() } 535 * Iterate through all the packages and find the Graph. 536 */ 537 for (i = 0; i + 1 < dsd->package.count; i += 2) { 538 const union acpi_object *guid, *package; 539 540 guid = &dsd->package.elements[i]; 541 package = &dsd->package.elements[i + 1]; 542 543 /* All _DSD elements must have a UUID and a Package */ 544 if (!is_acpi_guid(guid) || package->type != ACPI_TYPE_PACKAGE) 545 break; 546 /* Skip the non-Graph _DSD packages */ 547 if (!is_acpi_dsd_graph_guid(guid)) 548 continue; 549 if (acpi_validate_dsd_graph(package)) 550 return package; 551 /* Invalid graph format, continue */ 552 dev_warn(&adev->dev, "Invalid Graph _DSD property\n"); 553 } 554 555 return NULL; 556 } 557 558 static bool 559 acpi_validate_coresight_graph(const union acpi_object *cs_graph) 560 { 561 int nlinks; 562 563 nlinks = cs_graph->package.elements[2].integer.value; 564 /* 565 * Graph must have the following fields : 566 * { GraphID, GraphUUID, NumberOfLinks, Links... } 567 */ 568 if (cs_graph->package.count != (nlinks + 3)) 569 return false; 570 /* The links are validated in acpi_coresight_parse_link() */ 571 return true; 572 } 573 574 /* 575 * acpi_get_coresight_graph - Parse the device _DSD tables and find 576 * the Graph property matching the CoreSight Graphs. 577 * 578 * Returns the pointer to the CoreSight Graph Package when found. Otherwise 579 * returns NULL. 580 */ 581 static const union acpi_object * 582 acpi_get_coresight_graph(struct acpi_device *adev, struct acpi_buffer *buf) 583 { 584 const union acpi_object *graph_list, *graph; 585 int i, nr_graphs; 586 587 graph_list = acpi_get_dsd_graph(adev, buf); 588 if (!graph_list) 589 return graph_list; 590 591 nr_graphs = graph_list->package.elements[1].integer.value; 592 593 for (i = 2; i < nr_graphs + 2; i++) { 594 graph = &graph_list->package.elements[i]; 595 if (!is_acpi_coresight_graph(graph)) 596 continue; 597 if (acpi_validate_coresight_graph(graph)) 598 return graph; 599 /* Invalid graph format */ 600 break; 601 } 602 603 return NULL; 604 } 605 606 /* 607 * acpi_coresight_parse_link - Parse the given Graph connection 608 * of the device and populate the coresight_connection for an output 609 * connection. 610 * 611 * CoreSight Graph specification mandates that the direction of the data 612 * flow must be specified in the link. i.e, 613 * 614 * SourcePortAddress, // Integer 615 * DestinationPortAddress, // Integer 616 * DestinationDeviceName, // Reference to another device 617 * DirectionOfFlow, // 1 for output(master), 0 for input(slave) 618 * 619 * Returns the direction of the data flow [ Input(slave) or Output(master) ] 620 * upon success. 621 * Returns an negative error number otherwise. 622 */ 623 static int acpi_coresight_parse_link(struct acpi_device *adev, 624 const union acpi_object *link, 625 struct coresight_connection *conn) 626 { 627 int dir; 628 const union acpi_object *fields; 629 struct acpi_device *r_adev; 630 struct device *rdev; 631 632 if (link->type != ACPI_TYPE_PACKAGE || 633 link->package.count != 4) 634 return -EINVAL; 635 636 fields = link->package.elements; 637 638 if (fields[0].type != ACPI_TYPE_INTEGER || 639 fields[1].type != ACPI_TYPE_INTEGER || 640 fields[2].type != ACPI_TYPE_LOCAL_REFERENCE || 641 fields[3].type != ACPI_TYPE_INTEGER) 642 return -EINVAL; 643 644 r_adev = acpi_fetch_acpi_dev(fields[2].reference.handle); 645 if (!r_adev) 646 return -ENODEV; 647 648 dir = fields[3].integer.value; 649 if (dir == ACPI_CORESIGHT_LINK_MASTER) { 650 conn->src_port = fields[0].integer.value; 651 conn->dest_port = fields[1].integer.value; 652 rdev = coresight_find_device_by_fwnode(&r_adev->fwnode); 653 if (!rdev) 654 return -EPROBE_DEFER; 655 /* 656 * Hold the refcount to the target device. This could be 657 * released via: 658 * 1) coresight_release_platform_data() if the probe fails or 659 * this device is unregistered. 660 * 2) While removing the target device via 661 * coresight_remove_match(). 662 */ 663 conn->dest_fwnode = fwnode_handle_get(&r_adev->fwnode); 664 } else if (dir == ACPI_CORESIGHT_LINK_SLAVE) { 665 /* 666 * We are only interested in the port number 667 * for the input ports at this component. 668 * Store the port number in child_port. 669 */ 670 conn->dest_port = fields[0].integer.value; 671 } else { 672 /* Invalid direction */ 673 return -EINVAL; 674 } 675 676 return dir; 677 } 678 679 /* 680 * acpi_coresight_parse_graph - Parse the _DSD CoreSight graph 681 * connection information and populate the supplied coresight_platform_data 682 * instance. 683 */ 684 static int acpi_coresight_parse_graph(struct device *dev, 685 struct acpi_device *adev, 686 struct coresight_platform_data *pdata) 687 { 688 int ret = 0; 689 int i, nlinks; 690 const union acpi_object *graph; 691 struct coresight_connection conn, zero_conn = {}; 692 struct coresight_connection *new_conn; 693 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; 694 695 graph = acpi_get_coresight_graph(adev, &buf); 696 /* 697 * There are no graph connections, which is fine for some components. 698 * e.g., ETE 699 */ 700 if (!graph) 701 goto free; 702 703 nlinks = graph->package.elements[2].integer.value; 704 if (!nlinks) 705 goto free; 706 707 for (i = 0; i < nlinks; i++) { 708 const union acpi_object *link = &graph->package.elements[3 + i]; 709 int dir; 710 711 conn = zero_conn; 712 dir = acpi_coresight_parse_link(adev, link, &conn); 713 if (dir < 0) { 714 ret = dir; 715 goto free; 716 } 717 718 if (dir == ACPI_CORESIGHT_LINK_MASTER) { 719 new_conn = coresight_add_out_conn(dev, pdata, &conn); 720 if (IS_ERR(new_conn)) { 721 ret = PTR_ERR(new_conn); 722 goto free; 723 } 724 } 725 } 726 727 free: 728 /* 729 * When ACPI fails to alloc a buffer, it will free the buffer 730 * created via ACPI_ALLOCATE_BUFFER and set to NULL. 731 * ACPI_FREE can handle NULL pointers, so free it directly. 732 */ 733 ACPI_FREE(buf.pointer); 734 return ret; 735 } 736 737 /* 738 * acpi_handle_to_logical_cpuid - Map a given acpi_handle to the 739 * logical CPU id of the corresponding CPU device. 740 * 741 * Returns the logical CPU id when found. Otherwise returns >= nr_cpus_id. 742 */ 743 static int 744 acpi_handle_to_logical_cpuid(acpi_handle handle) 745 { 746 int i; 747 struct acpi_processor *pr; 748 749 for_each_possible_cpu(i) { 750 pr = per_cpu(processors, i); 751 if (pr && pr->handle == handle) 752 break; 753 } 754 755 return i; 756 } 757 758 /* 759 * acpi_coresigh_get_cpu - Find the logical CPU id of the CPU associated 760 * with this coresight device. With ACPI bindings, the CoreSight components 761 * are listed as child device of the associated CPU. 762 * 763 * Returns the logical CPU id when found. Otherwise returns 0. 764 */ 765 static int acpi_coresight_get_cpu(struct device *dev) 766 { 767 int cpu; 768 acpi_handle cpu_handle; 769 acpi_status status; 770 struct acpi_device *adev = ACPI_COMPANION(dev); 771 772 if (!adev) 773 return -ENODEV; 774 status = acpi_get_parent(adev->handle, &cpu_handle); 775 if (ACPI_FAILURE(status)) 776 return -ENODEV; 777 778 cpu = acpi_handle_to_logical_cpuid(cpu_handle); 779 if (cpu >= nr_cpu_ids) 780 return -ENODEV; 781 return cpu; 782 } 783 784 static int 785 acpi_get_coresight_platform_data(struct device *dev, 786 struct coresight_platform_data *pdata) 787 { 788 struct acpi_device *adev; 789 790 adev = ACPI_COMPANION(dev); 791 if (!adev) 792 return -EINVAL; 793 794 return acpi_coresight_parse_graph(dev, adev, pdata); 795 } 796 797 #else 798 799 static int 800 acpi_get_coresight_platform_data(struct device *dev, 801 struct coresight_platform_data *pdata) 802 { 803 return -ENOENT; 804 } 805 806 static int acpi_coresight_get_cpu(struct device *dev) 807 { 808 return -ENODEV; 809 } 810 #endif 811 812 int coresight_get_cpu(struct device *dev) 813 { 814 if (is_of_node(dev->fwnode)) 815 return of_coresight_get_cpu(dev); 816 else if (is_acpi_device_node(dev->fwnode)) 817 return acpi_coresight_get_cpu(dev); 818 return 0; 819 } 820 EXPORT_SYMBOL_GPL(coresight_get_cpu); 821 822 int coresight_get_static_trace_id(struct device *dev, u32 *id) 823 { 824 return fwnode_property_read_u32(dev_fwnode(dev), "arm,static-trace-id", id); 825 } 826 EXPORT_SYMBOL_GPL(coresight_get_static_trace_id); 827 828 struct coresight_platform_data * 829 coresight_get_platform_data(struct device *dev) 830 { 831 int ret = -ENOENT; 832 struct coresight_platform_data *pdata = NULL; 833 struct fwnode_handle *fwnode = dev_fwnode(dev); 834 835 if (IS_ERR_OR_NULL(fwnode)) 836 goto error; 837 838 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 839 if (!pdata) { 840 ret = -ENOMEM; 841 goto error; 842 } 843 844 if (is_of_node(fwnode)) 845 ret = of_get_coresight_platform_data(dev, pdata); 846 else if (is_acpi_device_node(fwnode)) 847 ret = acpi_get_coresight_platform_data(dev, pdata); 848 849 if (!ret) 850 return pdata; 851 error: 852 if (!IS_ERR_OR_NULL(pdata)) 853 /* Cleanup the connection information */ 854 coresight_release_platform_data(dev, pdata); 855 return ERR_PTR(ret); 856 } 857 EXPORT_SYMBOL_GPL(coresight_get_platform_data); 858