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