1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Interconnect framework core driver 4 * 5 * Copyright (c) 2017-2019, Linaro Ltd. 6 * Author: Georgi Djakov <georgi.djakov@linaro.org> 7 */ 8 9 #include <linux/debugfs.h> 10 #include <linux/device.h> 11 #include <linux/idr.h> 12 #include <linux/init.h> 13 #include <linux/interconnect.h> 14 #include <linux/interconnect-provider.h> 15 #include <linux/list.h> 16 #include <linux/module.h> 17 #include <linux/mutex.h> 18 #include <linux/slab.h> 19 #include <linux/of.h> 20 #include <linux/overflow.h> 21 22 #include "internal.h" 23 24 #define CREATE_TRACE_POINTS 25 #include "trace.h" 26 27 static DEFINE_IDR(icc_idr); 28 static LIST_HEAD(icc_providers); 29 static DEFINE_MUTEX(icc_lock); 30 static struct dentry *icc_debugfs_dir; 31 32 static void icc_summary_show_one(struct seq_file *s, struct icc_node *n) 33 { 34 if (!n) 35 return; 36 37 seq_printf(s, "%-42s %12u %12u\n", 38 n->name, n->avg_bw, n->peak_bw); 39 } 40 41 static int icc_summary_show(struct seq_file *s, void *data) 42 { 43 struct icc_provider *provider; 44 45 seq_puts(s, " node tag avg peak\n"); 46 seq_puts(s, "--------------------------------------------------------------------\n"); 47 48 mutex_lock(&icc_lock); 49 50 list_for_each_entry(provider, &icc_providers, provider_list) { 51 struct icc_node *n; 52 53 list_for_each_entry(n, &provider->nodes, node_list) { 54 struct icc_req *r; 55 56 icc_summary_show_one(s, n); 57 hlist_for_each_entry(r, &n->req_list, req_node) { 58 u32 avg_bw = 0, peak_bw = 0; 59 60 if (!r->dev) 61 continue; 62 63 if (r->enabled) { 64 avg_bw = r->avg_bw; 65 peak_bw = r->peak_bw; 66 } 67 68 seq_printf(s, " %-27s %12u %12u %12u\n", 69 dev_name(r->dev), r->tag, avg_bw, peak_bw); 70 } 71 } 72 } 73 74 mutex_unlock(&icc_lock); 75 76 return 0; 77 } 78 DEFINE_SHOW_ATTRIBUTE(icc_summary); 79 80 static void icc_graph_show_link(struct seq_file *s, int level, 81 struct icc_node *n, struct icc_node *m) 82 { 83 seq_printf(s, "%s\"%d:%s\" -> \"%d:%s\"\n", 84 level == 2 ? "\t\t" : "\t", 85 n->id, n->name, m->id, m->name); 86 } 87 88 static void icc_graph_show_node(struct seq_file *s, struct icc_node *n) 89 { 90 seq_printf(s, "\t\t\"%d:%s\" [label=\"%d:%s", 91 n->id, n->name, n->id, n->name); 92 seq_printf(s, "\n\t\t\t|avg_bw=%ukBps", n->avg_bw); 93 seq_printf(s, "\n\t\t\t|peak_bw=%ukBps", n->peak_bw); 94 seq_puts(s, "\"]\n"); 95 } 96 97 static int icc_graph_show(struct seq_file *s, void *data) 98 { 99 struct icc_provider *provider; 100 struct icc_node *n; 101 int cluster_index = 0; 102 int i; 103 104 seq_puts(s, "digraph {\n\trankdir = LR\n\tnode [shape = record]\n"); 105 mutex_lock(&icc_lock); 106 107 /* draw providers as cluster subgraphs */ 108 cluster_index = 0; 109 list_for_each_entry(provider, &icc_providers, provider_list) { 110 seq_printf(s, "\tsubgraph cluster_%d {\n", ++cluster_index); 111 if (provider->dev) 112 seq_printf(s, "\t\tlabel = \"%s\"\n", 113 dev_name(provider->dev)); 114 115 /* draw nodes */ 116 list_for_each_entry(n, &provider->nodes, node_list) 117 icc_graph_show_node(s, n); 118 119 /* draw internal links */ 120 list_for_each_entry(n, &provider->nodes, node_list) 121 for (i = 0; i < n->num_links; ++i) 122 if (n->provider == n->links[i]->provider) 123 icc_graph_show_link(s, 2, n, 124 n->links[i]); 125 126 seq_puts(s, "\t}\n"); 127 } 128 129 /* draw external links */ 130 list_for_each_entry(provider, &icc_providers, provider_list) 131 list_for_each_entry(n, &provider->nodes, node_list) 132 for (i = 0; i < n->num_links; ++i) 133 if (n->provider != n->links[i]->provider) 134 icc_graph_show_link(s, 1, n, 135 n->links[i]); 136 137 mutex_unlock(&icc_lock); 138 seq_puts(s, "}"); 139 140 return 0; 141 } 142 DEFINE_SHOW_ATTRIBUTE(icc_graph); 143 144 static struct icc_node *node_find(const int id) 145 { 146 return idr_find(&icc_idr, id); 147 } 148 149 static struct icc_path *path_init(struct device *dev, struct icc_node *dst, 150 ssize_t num_nodes) 151 { 152 struct icc_node *node = dst; 153 struct icc_path *path; 154 int i; 155 156 path = kzalloc(struct_size(path, reqs, num_nodes), GFP_KERNEL); 157 if (!path) 158 return ERR_PTR(-ENOMEM); 159 160 path->num_nodes = num_nodes; 161 162 for (i = num_nodes - 1; i >= 0; i--) { 163 node->provider->users++; 164 hlist_add_head(&path->reqs[i].req_node, &node->req_list); 165 path->reqs[i].node = node; 166 path->reqs[i].dev = dev; 167 path->reqs[i].enabled = true; 168 /* reference to previous node was saved during path traversal */ 169 node = node->reverse; 170 } 171 172 return path; 173 } 174 175 static struct icc_path *path_find(struct device *dev, struct icc_node *src, 176 struct icc_node *dst) 177 { 178 struct icc_path *path = ERR_PTR(-EPROBE_DEFER); 179 struct icc_node *n, *node = NULL; 180 struct list_head traverse_list; 181 struct list_head edge_list; 182 struct list_head visited_list; 183 size_t i, depth = 1; 184 bool found = false; 185 186 INIT_LIST_HEAD(&traverse_list); 187 INIT_LIST_HEAD(&edge_list); 188 INIT_LIST_HEAD(&visited_list); 189 190 list_add(&src->search_list, &traverse_list); 191 src->reverse = NULL; 192 193 do { 194 list_for_each_entry_safe(node, n, &traverse_list, search_list) { 195 if (node == dst) { 196 found = true; 197 list_splice_init(&edge_list, &visited_list); 198 list_splice_init(&traverse_list, &visited_list); 199 break; 200 } 201 for (i = 0; i < node->num_links; i++) { 202 struct icc_node *tmp = node->links[i]; 203 204 if (!tmp) { 205 path = ERR_PTR(-ENOENT); 206 goto out; 207 } 208 209 if (tmp->is_traversed) 210 continue; 211 212 tmp->is_traversed = true; 213 tmp->reverse = node; 214 list_add_tail(&tmp->search_list, &edge_list); 215 } 216 } 217 218 if (found) 219 break; 220 221 list_splice_init(&traverse_list, &visited_list); 222 list_splice_init(&edge_list, &traverse_list); 223 224 /* count the hops including the source */ 225 depth++; 226 227 } while (!list_empty(&traverse_list)); 228 229 out: 230 231 /* reset the traversed state */ 232 list_for_each_entry_reverse(n, &visited_list, search_list) 233 n->is_traversed = false; 234 235 if (found) 236 path = path_init(dev, dst, depth); 237 238 return path; 239 } 240 241 /* 242 * We want the path to honor all bandwidth requests, so the average and peak 243 * bandwidth requirements from each consumer are aggregated at each node. 244 * The aggregation is platform specific, so each platform can customize it by 245 * implementing its own aggregate() function. 246 */ 247 248 static int aggregate_requests(struct icc_node *node) 249 { 250 struct icc_provider *p = node->provider; 251 struct icc_req *r; 252 u32 avg_bw, peak_bw; 253 254 node->avg_bw = 0; 255 node->peak_bw = 0; 256 257 if (p->pre_aggregate) 258 p->pre_aggregate(node); 259 260 hlist_for_each_entry(r, &node->req_list, req_node) { 261 if (r->enabled) { 262 avg_bw = r->avg_bw; 263 peak_bw = r->peak_bw; 264 } else { 265 avg_bw = 0; 266 peak_bw = 0; 267 } 268 p->aggregate(node, r->tag, avg_bw, peak_bw, 269 &node->avg_bw, &node->peak_bw); 270 } 271 272 return 0; 273 } 274 275 static int apply_constraints(struct icc_path *path) 276 { 277 struct icc_node *next, *prev = NULL; 278 struct icc_provider *p; 279 int ret = -EINVAL; 280 int i; 281 282 for (i = 0; i < path->num_nodes; i++) { 283 next = path->reqs[i].node; 284 p = next->provider; 285 286 /* both endpoints should be valid master-slave pairs */ 287 if (!prev || (p != prev->provider && !p->inter_set)) { 288 prev = next; 289 continue; 290 } 291 292 /* set the constraints */ 293 ret = p->set(prev, next); 294 if (ret) 295 goto out; 296 297 prev = next; 298 } 299 out: 300 return ret; 301 } 302 303 int icc_std_aggregate(struct icc_node *node, u32 tag, u32 avg_bw, 304 u32 peak_bw, u32 *agg_avg, u32 *agg_peak) 305 { 306 *agg_avg += avg_bw; 307 *agg_peak = max(*agg_peak, peak_bw); 308 309 return 0; 310 } 311 EXPORT_SYMBOL_GPL(icc_std_aggregate); 312 313 /* of_icc_xlate_onecell() - Translate function using a single index. 314 * @spec: OF phandle args to map into an interconnect node. 315 * @data: private data (pointer to struct icc_onecell_data) 316 * 317 * This is a generic translate function that can be used to model simple 318 * interconnect providers that have one device tree node and provide 319 * multiple interconnect nodes. A single cell is used as an index into 320 * an array of icc nodes specified in the icc_onecell_data struct when 321 * registering the provider. 322 */ 323 struct icc_node *of_icc_xlate_onecell(struct of_phandle_args *spec, 324 void *data) 325 { 326 struct icc_onecell_data *icc_data = data; 327 unsigned int idx = spec->args[0]; 328 329 if (idx >= icc_data->num_nodes) { 330 pr_err("%s: invalid index %u\n", __func__, idx); 331 return ERR_PTR(-EINVAL); 332 } 333 334 return icc_data->nodes[idx]; 335 } 336 EXPORT_SYMBOL_GPL(of_icc_xlate_onecell); 337 338 /** 339 * of_icc_get_from_provider() - Look-up interconnect node 340 * @spec: OF phandle args to use for look-up 341 * 342 * Looks for interconnect provider under the node specified by @spec and if 343 * found, uses xlate function of the provider to map phandle args to node. 344 * 345 * Returns a valid pointer to struct icc_node on success or ERR_PTR() 346 * on failure. 347 */ 348 struct icc_node *of_icc_get_from_provider(struct of_phandle_args *spec) 349 { 350 struct icc_node *node = ERR_PTR(-EPROBE_DEFER); 351 struct icc_provider *provider; 352 353 if (!spec) 354 return ERR_PTR(-EINVAL); 355 356 mutex_lock(&icc_lock); 357 list_for_each_entry(provider, &icc_providers, provider_list) { 358 if (provider->dev->of_node == spec->np) 359 node = provider->xlate(spec, provider->data); 360 if (!IS_ERR(node)) 361 break; 362 } 363 mutex_unlock(&icc_lock); 364 365 return node; 366 } 367 EXPORT_SYMBOL_GPL(of_icc_get_from_provider); 368 369 static void devm_icc_release(struct device *dev, void *res) 370 { 371 icc_put(*(struct icc_path **)res); 372 } 373 374 struct icc_path *devm_of_icc_get(struct device *dev, const char *name) 375 { 376 struct icc_path **ptr, *path; 377 378 ptr = devres_alloc(devm_icc_release, sizeof(**ptr), GFP_KERNEL); 379 if (!ptr) 380 return ERR_PTR(-ENOMEM); 381 382 path = of_icc_get(dev, name); 383 if (!IS_ERR(path)) { 384 *ptr = path; 385 devres_add(dev, ptr); 386 } else { 387 devres_free(ptr); 388 } 389 390 return path; 391 } 392 EXPORT_SYMBOL_GPL(devm_of_icc_get); 393 394 /** 395 * of_icc_get_by_index() - get a path handle from a DT node based on index 396 * @dev: device pointer for the consumer device 397 * @idx: interconnect path index 398 * 399 * This function will search for a path between two endpoints and return an 400 * icc_path handle on success. Use icc_put() to release constraints when they 401 * are not needed anymore. 402 * If the interconnect API is disabled, NULL is returned and the consumer 403 * drivers will still build. Drivers are free to handle this specifically, 404 * but they don't have to. 405 * 406 * Return: icc_path pointer on success or ERR_PTR() on error. NULL is returned 407 * when the API is disabled or the "interconnects" DT property is missing. 408 */ 409 struct icc_path *of_icc_get_by_index(struct device *dev, int idx) 410 { 411 struct icc_path *path; 412 struct icc_node *src_node, *dst_node; 413 struct device_node *np; 414 struct of_phandle_args src_args, dst_args; 415 int ret; 416 417 if (!dev || !dev->of_node) 418 return ERR_PTR(-ENODEV); 419 420 np = dev->of_node; 421 422 /* 423 * When the consumer DT node do not have "interconnects" property 424 * return a NULL path to skip setting constraints. 425 */ 426 if (!of_find_property(np, "interconnects", NULL)) 427 return NULL; 428 429 /* 430 * We use a combination of phandle and specifier for endpoint. For now 431 * lets support only global ids and extend this in the future if needed 432 * without breaking DT compatibility. 433 */ 434 ret = of_parse_phandle_with_args(np, "interconnects", 435 "#interconnect-cells", idx * 2, 436 &src_args); 437 if (ret) 438 return ERR_PTR(ret); 439 440 of_node_put(src_args.np); 441 442 ret = of_parse_phandle_with_args(np, "interconnects", 443 "#interconnect-cells", idx * 2 + 1, 444 &dst_args); 445 if (ret) 446 return ERR_PTR(ret); 447 448 of_node_put(dst_args.np); 449 450 src_node = of_icc_get_from_provider(&src_args); 451 452 if (IS_ERR(src_node)) { 453 if (PTR_ERR(src_node) != -EPROBE_DEFER) 454 dev_err(dev, "error finding src node: %ld\n", 455 PTR_ERR(src_node)); 456 return ERR_CAST(src_node); 457 } 458 459 dst_node = of_icc_get_from_provider(&dst_args); 460 461 if (IS_ERR(dst_node)) { 462 if (PTR_ERR(dst_node) != -EPROBE_DEFER) 463 dev_err(dev, "error finding dst node: %ld\n", 464 PTR_ERR(dst_node)); 465 return ERR_CAST(dst_node); 466 } 467 468 mutex_lock(&icc_lock); 469 path = path_find(dev, src_node, dst_node); 470 mutex_unlock(&icc_lock); 471 if (IS_ERR(path)) { 472 dev_err(dev, "%s: invalid path=%ld\n", __func__, PTR_ERR(path)); 473 return path; 474 } 475 476 path->name = kasprintf(GFP_KERNEL, "%s-%s", 477 src_node->name, dst_node->name); 478 if (!path->name) { 479 kfree(path); 480 return ERR_PTR(-ENOMEM); 481 } 482 483 return path; 484 } 485 EXPORT_SYMBOL_GPL(of_icc_get_by_index); 486 487 /** 488 * of_icc_get() - get a path handle from a DT node based on name 489 * @dev: device pointer for the consumer device 490 * @name: interconnect path name 491 * 492 * This function will search for a path between two endpoints and return an 493 * icc_path handle on success. Use icc_put() to release constraints when they 494 * are not needed anymore. 495 * If the interconnect API is disabled, NULL is returned and the consumer 496 * drivers will still build. Drivers are free to handle this specifically, 497 * but they don't have to. 498 * 499 * Return: icc_path pointer on success or ERR_PTR() on error. NULL is returned 500 * when the API is disabled or the "interconnects" DT property is missing. 501 */ 502 struct icc_path *of_icc_get(struct device *dev, const char *name) 503 { 504 struct device_node *np; 505 int idx = 0; 506 507 if (!dev || !dev->of_node) 508 return ERR_PTR(-ENODEV); 509 510 np = dev->of_node; 511 512 /* 513 * When the consumer DT node do not have "interconnects" property 514 * return a NULL path to skip setting constraints. 515 */ 516 if (!of_find_property(np, "interconnects", NULL)) 517 return NULL; 518 519 /* 520 * We use a combination of phandle and specifier for endpoint. For now 521 * lets support only global ids and extend this in the future if needed 522 * without breaking DT compatibility. 523 */ 524 if (name) { 525 idx = of_property_match_string(np, "interconnect-names", name); 526 if (idx < 0) 527 return ERR_PTR(idx); 528 } 529 530 return of_icc_get_by_index(dev, idx); 531 } 532 EXPORT_SYMBOL_GPL(of_icc_get); 533 534 /** 535 * icc_set_tag() - set an optional tag on a path 536 * @path: the path we want to tag 537 * @tag: the tag value 538 * 539 * This function allows consumers to append a tag to the requests associated 540 * with a path, so that a different aggregation could be done based on this tag. 541 */ 542 void icc_set_tag(struct icc_path *path, u32 tag) 543 { 544 int i; 545 546 if (!path) 547 return; 548 549 mutex_lock(&icc_lock); 550 551 for (i = 0; i < path->num_nodes; i++) 552 path->reqs[i].tag = tag; 553 554 mutex_unlock(&icc_lock); 555 } 556 EXPORT_SYMBOL_GPL(icc_set_tag); 557 558 /** 559 * icc_get_name() - Get name of the icc path 560 * @path: reference to the path returned by icc_get() 561 * 562 * This function is used by an interconnect consumer to get the name of the icc 563 * path. 564 * 565 * Returns a valid pointer on success, or NULL otherwise. 566 */ 567 const char *icc_get_name(struct icc_path *path) 568 { 569 if (!path) 570 return NULL; 571 572 return path->name; 573 } 574 EXPORT_SYMBOL_GPL(icc_get_name); 575 576 /** 577 * icc_set_bw() - set bandwidth constraints on an interconnect path 578 * @path: reference to the path returned by icc_get() 579 * @avg_bw: average bandwidth in kilobytes per second 580 * @peak_bw: peak bandwidth in kilobytes per second 581 * 582 * This function is used by an interconnect consumer to express its own needs 583 * in terms of bandwidth for a previously requested path between two endpoints. 584 * The requests are aggregated and each node is updated accordingly. The entire 585 * path is locked by a mutex to ensure that the set() is completed. 586 * The @path can be NULL when the "interconnects" DT properties is missing, 587 * which will mean that no constraints will be set. 588 * 589 * Returns 0 on success, or an appropriate error code otherwise. 590 */ 591 int icc_set_bw(struct icc_path *path, u32 avg_bw, u32 peak_bw) 592 { 593 struct icc_node *node; 594 u32 old_avg, old_peak; 595 size_t i; 596 int ret; 597 598 if (!path) 599 return 0; 600 601 if (WARN_ON(IS_ERR(path) || !path->num_nodes)) 602 return -EINVAL; 603 604 mutex_lock(&icc_lock); 605 606 old_avg = path->reqs[0].avg_bw; 607 old_peak = path->reqs[0].peak_bw; 608 609 for (i = 0; i < path->num_nodes; i++) { 610 node = path->reqs[i].node; 611 612 /* update the consumer request for this path */ 613 path->reqs[i].avg_bw = avg_bw; 614 path->reqs[i].peak_bw = peak_bw; 615 616 /* aggregate requests for this node */ 617 aggregate_requests(node); 618 619 trace_icc_set_bw(path, node, i, avg_bw, peak_bw); 620 } 621 622 ret = apply_constraints(path); 623 if (ret) { 624 pr_debug("interconnect: error applying constraints (%d)\n", 625 ret); 626 627 for (i = 0; i < path->num_nodes; i++) { 628 node = path->reqs[i].node; 629 path->reqs[i].avg_bw = old_avg; 630 path->reqs[i].peak_bw = old_peak; 631 aggregate_requests(node); 632 } 633 apply_constraints(path); 634 } 635 636 mutex_unlock(&icc_lock); 637 638 trace_icc_set_bw_end(path, ret); 639 640 return ret; 641 } 642 EXPORT_SYMBOL_GPL(icc_set_bw); 643 644 static int __icc_enable(struct icc_path *path, bool enable) 645 { 646 int i; 647 648 if (!path) 649 return 0; 650 651 if (WARN_ON(IS_ERR(path) || !path->num_nodes)) 652 return -EINVAL; 653 654 mutex_lock(&icc_lock); 655 656 for (i = 0; i < path->num_nodes; i++) 657 path->reqs[i].enabled = enable; 658 659 mutex_unlock(&icc_lock); 660 661 return icc_set_bw(path, path->reqs[0].avg_bw, 662 path->reqs[0].peak_bw); 663 } 664 665 int icc_enable(struct icc_path *path) 666 { 667 return __icc_enable(path, true); 668 } 669 EXPORT_SYMBOL_GPL(icc_enable); 670 671 int icc_disable(struct icc_path *path) 672 { 673 return __icc_enable(path, false); 674 } 675 EXPORT_SYMBOL_GPL(icc_disable); 676 677 /** 678 * icc_get() - return a handle for path between two endpoints 679 * @dev: the device requesting the path 680 * @src_id: source device port id 681 * @dst_id: destination device port id 682 * 683 * This function will search for a path between two endpoints and return an 684 * icc_path handle on success. Use icc_put() to release 685 * constraints when they are not needed anymore. 686 * If the interconnect API is disabled, NULL is returned and the consumer 687 * drivers will still build. Drivers are free to handle this specifically, 688 * but they don't have to. 689 * 690 * Return: icc_path pointer on success, ERR_PTR() on error or NULL if the 691 * interconnect API is disabled. 692 */ 693 struct icc_path *icc_get(struct device *dev, const int src_id, const int dst_id) 694 { 695 struct icc_node *src, *dst; 696 struct icc_path *path = ERR_PTR(-EPROBE_DEFER); 697 698 mutex_lock(&icc_lock); 699 700 src = node_find(src_id); 701 if (!src) 702 goto out; 703 704 dst = node_find(dst_id); 705 if (!dst) 706 goto out; 707 708 path = path_find(dev, src, dst); 709 if (IS_ERR(path)) { 710 dev_err(dev, "%s: invalid path=%ld\n", __func__, PTR_ERR(path)); 711 goto out; 712 } 713 714 path->name = kasprintf(GFP_KERNEL, "%s-%s", src->name, dst->name); 715 if (!path->name) { 716 kfree(path); 717 path = ERR_PTR(-ENOMEM); 718 } 719 out: 720 mutex_unlock(&icc_lock); 721 return path; 722 } 723 EXPORT_SYMBOL_GPL(icc_get); 724 725 /** 726 * icc_put() - release the reference to the icc_path 727 * @path: interconnect path 728 * 729 * Use this function to release the constraints on a path when the path is 730 * no longer needed. The constraints will be re-aggregated. 731 */ 732 void icc_put(struct icc_path *path) 733 { 734 struct icc_node *node; 735 size_t i; 736 int ret; 737 738 if (!path || WARN_ON(IS_ERR(path))) 739 return; 740 741 ret = icc_set_bw(path, 0, 0); 742 if (ret) 743 pr_err("%s: error (%d)\n", __func__, ret); 744 745 mutex_lock(&icc_lock); 746 for (i = 0; i < path->num_nodes; i++) { 747 node = path->reqs[i].node; 748 hlist_del(&path->reqs[i].req_node); 749 if (!WARN_ON(!node->provider->users)) 750 node->provider->users--; 751 } 752 mutex_unlock(&icc_lock); 753 754 kfree_const(path->name); 755 kfree(path); 756 } 757 EXPORT_SYMBOL_GPL(icc_put); 758 759 static struct icc_node *icc_node_create_nolock(int id) 760 { 761 struct icc_node *node; 762 763 /* check if node already exists */ 764 node = node_find(id); 765 if (node) 766 return node; 767 768 node = kzalloc(sizeof(*node), GFP_KERNEL); 769 if (!node) 770 return ERR_PTR(-ENOMEM); 771 772 id = idr_alloc(&icc_idr, node, id, id + 1, GFP_KERNEL); 773 if (id < 0) { 774 WARN(1, "%s: couldn't get idr\n", __func__); 775 kfree(node); 776 return ERR_PTR(id); 777 } 778 779 node->id = id; 780 781 return node; 782 } 783 784 /** 785 * icc_node_create() - create a node 786 * @id: node id 787 * 788 * Return: icc_node pointer on success, or ERR_PTR() on error 789 */ 790 struct icc_node *icc_node_create(int id) 791 { 792 struct icc_node *node; 793 794 mutex_lock(&icc_lock); 795 796 node = icc_node_create_nolock(id); 797 798 mutex_unlock(&icc_lock); 799 800 return node; 801 } 802 EXPORT_SYMBOL_GPL(icc_node_create); 803 804 /** 805 * icc_node_destroy() - destroy a node 806 * @id: node id 807 */ 808 void icc_node_destroy(int id) 809 { 810 struct icc_node *node; 811 812 mutex_lock(&icc_lock); 813 814 node = node_find(id); 815 if (node) { 816 idr_remove(&icc_idr, node->id); 817 WARN_ON(!hlist_empty(&node->req_list)); 818 } 819 820 mutex_unlock(&icc_lock); 821 822 kfree(node); 823 } 824 EXPORT_SYMBOL_GPL(icc_node_destroy); 825 826 /** 827 * icc_link_create() - create a link between two nodes 828 * @node: source node id 829 * @dst_id: destination node id 830 * 831 * Create a link between two nodes. The nodes might belong to different 832 * interconnect providers and the @dst_id node might not exist (if the 833 * provider driver has not probed yet). So just create the @dst_id node 834 * and when the actual provider driver is probed, the rest of the node 835 * data is filled. 836 * 837 * Return: 0 on success, or an error code otherwise 838 */ 839 int icc_link_create(struct icc_node *node, const int dst_id) 840 { 841 struct icc_node *dst; 842 struct icc_node **new; 843 int ret = 0; 844 845 if (!node->provider) 846 return -EINVAL; 847 848 mutex_lock(&icc_lock); 849 850 dst = node_find(dst_id); 851 if (!dst) { 852 dst = icc_node_create_nolock(dst_id); 853 854 if (IS_ERR(dst)) { 855 ret = PTR_ERR(dst); 856 goto out; 857 } 858 } 859 860 new = krealloc(node->links, 861 (node->num_links + 1) * sizeof(*node->links), 862 GFP_KERNEL); 863 if (!new) { 864 ret = -ENOMEM; 865 goto out; 866 } 867 868 node->links = new; 869 node->links[node->num_links++] = dst; 870 871 out: 872 mutex_unlock(&icc_lock); 873 874 return ret; 875 } 876 EXPORT_SYMBOL_GPL(icc_link_create); 877 878 /** 879 * icc_link_destroy() - destroy a link between two nodes 880 * @src: pointer to source node 881 * @dst: pointer to destination node 882 * 883 * Return: 0 on success, or an error code otherwise 884 */ 885 int icc_link_destroy(struct icc_node *src, struct icc_node *dst) 886 { 887 struct icc_node **new; 888 size_t slot; 889 int ret = 0; 890 891 if (IS_ERR_OR_NULL(src)) 892 return -EINVAL; 893 894 if (IS_ERR_OR_NULL(dst)) 895 return -EINVAL; 896 897 mutex_lock(&icc_lock); 898 899 for (slot = 0; slot < src->num_links; slot++) 900 if (src->links[slot] == dst) 901 break; 902 903 if (WARN_ON(slot == src->num_links)) { 904 ret = -ENXIO; 905 goto out; 906 } 907 908 src->links[slot] = src->links[--src->num_links]; 909 910 new = krealloc(src->links, src->num_links * sizeof(*src->links), 911 GFP_KERNEL); 912 if (new) 913 src->links = new; 914 915 out: 916 mutex_unlock(&icc_lock); 917 918 return ret; 919 } 920 EXPORT_SYMBOL_GPL(icc_link_destroy); 921 922 /** 923 * icc_node_add() - add interconnect node to interconnect provider 924 * @node: pointer to the interconnect node 925 * @provider: pointer to the interconnect provider 926 */ 927 void icc_node_add(struct icc_node *node, struct icc_provider *provider) 928 { 929 mutex_lock(&icc_lock); 930 931 node->provider = provider; 932 list_add_tail(&node->node_list, &provider->nodes); 933 934 mutex_unlock(&icc_lock); 935 } 936 EXPORT_SYMBOL_GPL(icc_node_add); 937 938 /** 939 * icc_node_del() - delete interconnect node from interconnect provider 940 * @node: pointer to the interconnect node 941 */ 942 void icc_node_del(struct icc_node *node) 943 { 944 mutex_lock(&icc_lock); 945 946 list_del(&node->node_list); 947 948 mutex_unlock(&icc_lock); 949 } 950 EXPORT_SYMBOL_GPL(icc_node_del); 951 952 /** 953 * icc_nodes_remove() - remove all previously added nodes from provider 954 * @provider: the interconnect provider we are removing nodes from 955 * 956 * Return: 0 on success, or an error code otherwise 957 */ 958 int icc_nodes_remove(struct icc_provider *provider) 959 { 960 struct icc_node *n, *tmp; 961 962 if (WARN_ON(IS_ERR_OR_NULL(provider))) 963 return -EINVAL; 964 965 list_for_each_entry_safe_reverse(n, tmp, &provider->nodes, node_list) { 966 icc_node_del(n); 967 icc_node_destroy(n->id); 968 } 969 970 return 0; 971 } 972 EXPORT_SYMBOL_GPL(icc_nodes_remove); 973 974 /** 975 * icc_provider_add() - add a new interconnect provider 976 * @provider: the interconnect provider that will be added into topology 977 * 978 * Return: 0 on success, or an error code otherwise 979 */ 980 int icc_provider_add(struct icc_provider *provider) 981 { 982 if (WARN_ON(!provider->set)) 983 return -EINVAL; 984 if (WARN_ON(!provider->xlate)) 985 return -EINVAL; 986 987 mutex_lock(&icc_lock); 988 989 INIT_LIST_HEAD(&provider->nodes); 990 list_add_tail(&provider->provider_list, &icc_providers); 991 992 mutex_unlock(&icc_lock); 993 994 dev_dbg(provider->dev, "interconnect provider added to topology\n"); 995 996 return 0; 997 } 998 EXPORT_SYMBOL_GPL(icc_provider_add); 999 1000 /** 1001 * icc_provider_del() - delete previously added interconnect provider 1002 * @provider: the interconnect provider that will be removed from topology 1003 * 1004 * Return: 0 on success, or an error code otherwise 1005 */ 1006 int icc_provider_del(struct icc_provider *provider) 1007 { 1008 mutex_lock(&icc_lock); 1009 if (provider->users) { 1010 pr_warn("interconnect provider still has %d users\n", 1011 provider->users); 1012 mutex_unlock(&icc_lock); 1013 return -EBUSY; 1014 } 1015 1016 if (!list_empty(&provider->nodes)) { 1017 pr_warn("interconnect provider still has nodes\n"); 1018 mutex_unlock(&icc_lock); 1019 return -EBUSY; 1020 } 1021 1022 list_del(&provider->provider_list); 1023 mutex_unlock(&icc_lock); 1024 1025 return 0; 1026 } 1027 EXPORT_SYMBOL_GPL(icc_provider_del); 1028 1029 static int __init icc_init(void) 1030 { 1031 icc_debugfs_dir = debugfs_create_dir("interconnect", NULL); 1032 debugfs_create_file("interconnect_summary", 0444, 1033 icc_debugfs_dir, NULL, &icc_summary_fops); 1034 debugfs_create_file("interconnect_graph", 0444, 1035 icc_debugfs_dir, NULL, &icc_graph_fops); 1036 return 0; 1037 } 1038 1039 device_initcall(icc_init); 1040 1041 MODULE_AUTHOR("Georgi Djakov <georgi.djakov@linaro.org>"); 1042 MODULE_DESCRIPTION("Interconnect Driver Core"); 1043 MODULE_LICENSE("GPL v2"); 1044