swnode.c (28668B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Software nodes for the firmware node framework. 4 * 5 * Copyright (C) 2018, Intel Corporation 6 * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com> 7 */ 8 9#include <linux/device.h> 10#include <linux/kernel.h> 11#include <linux/property.h> 12#include <linux/slab.h> 13 14#include "base.h" 15 16struct swnode { 17 struct kobject kobj; 18 struct fwnode_handle fwnode; 19 const struct software_node *node; 20 int id; 21 22 /* hierarchy */ 23 struct ida child_ids; 24 struct list_head entry; 25 struct list_head children; 26 struct swnode *parent; 27 28 unsigned int allocated:1; 29 unsigned int managed:1; 30}; 31 32static DEFINE_IDA(swnode_root_ids); 33static struct kset *swnode_kset; 34 35#define kobj_to_swnode(_kobj_) container_of(_kobj_, struct swnode, kobj) 36 37static const struct fwnode_operations software_node_ops; 38 39bool is_software_node(const struct fwnode_handle *fwnode) 40{ 41 return !IS_ERR_OR_NULL(fwnode) && fwnode->ops == &software_node_ops; 42} 43EXPORT_SYMBOL_GPL(is_software_node); 44 45#define to_swnode(__fwnode) \ 46 ({ \ 47 typeof(__fwnode) __to_swnode_fwnode = __fwnode; \ 48 \ 49 is_software_node(__to_swnode_fwnode) ? \ 50 container_of(__to_swnode_fwnode, \ 51 struct swnode, fwnode) : NULL; \ 52 }) 53 54static inline struct swnode *dev_to_swnode(struct device *dev) 55{ 56 struct fwnode_handle *fwnode = dev_fwnode(dev); 57 58 if (!fwnode) 59 return NULL; 60 61 if (!is_software_node(fwnode)) 62 fwnode = fwnode->secondary; 63 64 return to_swnode(fwnode); 65} 66 67static struct swnode * 68software_node_to_swnode(const struct software_node *node) 69{ 70 struct swnode *swnode = NULL; 71 struct kobject *k; 72 73 if (!node) 74 return NULL; 75 76 spin_lock(&swnode_kset->list_lock); 77 78 list_for_each_entry(k, &swnode_kset->list, entry) { 79 swnode = kobj_to_swnode(k); 80 if (swnode->node == node) 81 break; 82 swnode = NULL; 83 } 84 85 spin_unlock(&swnode_kset->list_lock); 86 87 return swnode; 88} 89 90const struct software_node *to_software_node(const struct fwnode_handle *fwnode) 91{ 92 const struct swnode *swnode = to_swnode(fwnode); 93 94 return swnode ? swnode->node : NULL; 95} 96EXPORT_SYMBOL_GPL(to_software_node); 97 98struct fwnode_handle *software_node_fwnode(const struct software_node *node) 99{ 100 struct swnode *swnode = software_node_to_swnode(node); 101 102 return swnode ? &swnode->fwnode : NULL; 103} 104EXPORT_SYMBOL_GPL(software_node_fwnode); 105 106/* -------------------------------------------------------------------------- */ 107/* property_entry processing */ 108 109static const struct property_entry * 110property_entry_get(const struct property_entry *prop, const char *name) 111{ 112 if (!prop) 113 return NULL; 114 115 for (; prop->name; prop++) 116 if (!strcmp(name, prop->name)) 117 return prop; 118 119 return NULL; 120} 121 122static const void *property_get_pointer(const struct property_entry *prop) 123{ 124 if (!prop->length) 125 return NULL; 126 127 return prop->is_inline ? &prop->value : prop->pointer; 128} 129 130static const void *property_entry_find(const struct property_entry *props, 131 const char *propname, size_t length) 132{ 133 const struct property_entry *prop; 134 const void *pointer; 135 136 prop = property_entry_get(props, propname); 137 if (!prop) 138 return ERR_PTR(-EINVAL); 139 pointer = property_get_pointer(prop); 140 if (!pointer) 141 return ERR_PTR(-ENODATA); 142 if (length > prop->length) 143 return ERR_PTR(-EOVERFLOW); 144 return pointer; 145} 146 147static int 148property_entry_count_elems_of_size(const struct property_entry *props, 149 const char *propname, size_t length) 150{ 151 const struct property_entry *prop; 152 153 prop = property_entry_get(props, propname); 154 if (!prop) 155 return -EINVAL; 156 157 return prop->length / length; 158} 159 160static int property_entry_read_int_array(const struct property_entry *props, 161 const char *name, 162 unsigned int elem_size, void *val, 163 size_t nval) 164{ 165 const void *pointer; 166 size_t length; 167 168 if (!val) 169 return property_entry_count_elems_of_size(props, name, 170 elem_size); 171 172 if (!is_power_of_2(elem_size) || elem_size > sizeof(u64)) 173 return -ENXIO; 174 175 length = nval * elem_size; 176 177 pointer = property_entry_find(props, name, length); 178 if (IS_ERR(pointer)) 179 return PTR_ERR(pointer); 180 181 memcpy(val, pointer, length); 182 return 0; 183} 184 185static int property_entry_read_string_array(const struct property_entry *props, 186 const char *propname, 187 const char **strings, size_t nval) 188{ 189 const void *pointer; 190 size_t length; 191 int array_len; 192 193 /* Find out the array length. */ 194 array_len = property_entry_count_elems_of_size(props, propname, 195 sizeof(const char *)); 196 if (array_len < 0) 197 return array_len; 198 199 /* Return how many there are if strings is NULL. */ 200 if (!strings) 201 return array_len; 202 203 array_len = min_t(size_t, nval, array_len); 204 length = array_len * sizeof(*strings); 205 206 pointer = property_entry_find(props, propname, length); 207 if (IS_ERR(pointer)) 208 return PTR_ERR(pointer); 209 210 memcpy(strings, pointer, length); 211 212 return array_len; 213} 214 215static void property_entry_free_data(const struct property_entry *p) 216{ 217 const char * const *src_str; 218 size_t i, nval; 219 220 if (p->type == DEV_PROP_STRING) { 221 src_str = property_get_pointer(p); 222 nval = p->length / sizeof(*src_str); 223 for (i = 0; i < nval; i++) 224 kfree(src_str[i]); 225 } 226 227 if (!p->is_inline) 228 kfree(p->pointer); 229 230 kfree(p->name); 231} 232 233static bool property_copy_string_array(const char **dst_ptr, 234 const char * const *src_ptr, 235 size_t nval) 236{ 237 int i; 238 239 for (i = 0; i < nval; i++) { 240 dst_ptr[i] = kstrdup(src_ptr[i], GFP_KERNEL); 241 if (!dst_ptr[i] && src_ptr[i]) { 242 while (--i >= 0) 243 kfree(dst_ptr[i]); 244 return false; 245 } 246 } 247 248 return true; 249} 250 251static int property_entry_copy_data(struct property_entry *dst, 252 const struct property_entry *src) 253{ 254 const void *pointer = property_get_pointer(src); 255 void *dst_ptr; 256 size_t nval; 257 258 /* 259 * Properties with no data should not be marked as stored 260 * out of line. 261 */ 262 if (!src->is_inline && !src->length) 263 return -ENODATA; 264 265 /* 266 * Reference properties are never stored inline as 267 * they are too big. 268 */ 269 if (src->type == DEV_PROP_REF && src->is_inline) 270 return -EINVAL; 271 272 if (src->length <= sizeof(dst->value)) { 273 dst_ptr = &dst->value; 274 dst->is_inline = true; 275 } else { 276 dst_ptr = kmalloc(src->length, GFP_KERNEL); 277 if (!dst_ptr) 278 return -ENOMEM; 279 dst->pointer = dst_ptr; 280 } 281 282 if (src->type == DEV_PROP_STRING) { 283 nval = src->length / sizeof(const char *); 284 if (!property_copy_string_array(dst_ptr, pointer, nval)) { 285 if (!dst->is_inline) 286 kfree(dst->pointer); 287 return -ENOMEM; 288 } 289 } else { 290 memcpy(dst_ptr, pointer, src->length); 291 } 292 293 dst->length = src->length; 294 dst->type = src->type; 295 dst->name = kstrdup(src->name, GFP_KERNEL); 296 if (!dst->name) { 297 property_entry_free_data(dst); 298 return -ENOMEM; 299 } 300 301 return 0; 302} 303 304/** 305 * property_entries_dup - duplicate array of properties 306 * @properties: array of properties to copy 307 * 308 * This function creates a deep copy of the given NULL-terminated array 309 * of property entries. 310 */ 311struct property_entry * 312property_entries_dup(const struct property_entry *properties) 313{ 314 struct property_entry *p; 315 int i, n = 0; 316 int ret; 317 318 if (!properties) 319 return NULL; 320 321 while (properties[n].name) 322 n++; 323 324 p = kcalloc(n + 1, sizeof(*p), GFP_KERNEL); 325 if (!p) 326 return ERR_PTR(-ENOMEM); 327 328 for (i = 0; i < n; i++) { 329 ret = property_entry_copy_data(&p[i], &properties[i]); 330 if (ret) { 331 while (--i >= 0) 332 property_entry_free_data(&p[i]); 333 kfree(p); 334 return ERR_PTR(ret); 335 } 336 } 337 338 return p; 339} 340EXPORT_SYMBOL_GPL(property_entries_dup); 341 342/** 343 * property_entries_free - free previously allocated array of properties 344 * @properties: array of properties to destroy 345 * 346 * This function frees given NULL-terminated array of property entries, 347 * along with their data. 348 */ 349void property_entries_free(const struct property_entry *properties) 350{ 351 const struct property_entry *p; 352 353 if (!properties) 354 return; 355 356 for (p = properties; p->name; p++) 357 property_entry_free_data(p); 358 359 kfree(properties); 360} 361EXPORT_SYMBOL_GPL(property_entries_free); 362 363/* -------------------------------------------------------------------------- */ 364/* fwnode operations */ 365 366static struct fwnode_handle *software_node_get(struct fwnode_handle *fwnode) 367{ 368 struct swnode *swnode = to_swnode(fwnode); 369 370 kobject_get(&swnode->kobj); 371 372 return &swnode->fwnode; 373} 374 375static void software_node_put(struct fwnode_handle *fwnode) 376{ 377 struct swnode *swnode = to_swnode(fwnode); 378 379 kobject_put(&swnode->kobj); 380} 381 382static bool software_node_property_present(const struct fwnode_handle *fwnode, 383 const char *propname) 384{ 385 struct swnode *swnode = to_swnode(fwnode); 386 387 return !!property_entry_get(swnode->node->properties, propname); 388} 389 390static int software_node_read_int_array(const struct fwnode_handle *fwnode, 391 const char *propname, 392 unsigned int elem_size, void *val, 393 size_t nval) 394{ 395 struct swnode *swnode = to_swnode(fwnode); 396 397 return property_entry_read_int_array(swnode->node->properties, propname, 398 elem_size, val, nval); 399} 400 401static int software_node_read_string_array(const struct fwnode_handle *fwnode, 402 const char *propname, 403 const char **val, size_t nval) 404{ 405 struct swnode *swnode = to_swnode(fwnode); 406 407 return property_entry_read_string_array(swnode->node->properties, 408 propname, val, nval); 409} 410 411static const char * 412software_node_get_name(const struct fwnode_handle *fwnode) 413{ 414 const struct swnode *swnode = to_swnode(fwnode); 415 416 return kobject_name(&swnode->kobj); 417} 418 419static const char * 420software_node_get_name_prefix(const struct fwnode_handle *fwnode) 421{ 422 struct fwnode_handle *parent; 423 const char *prefix; 424 425 parent = fwnode_get_parent(fwnode); 426 if (!parent) 427 return ""; 428 429 /* Figure out the prefix from the parents. */ 430 while (is_software_node(parent)) 431 parent = fwnode_get_next_parent(parent); 432 433 prefix = fwnode_get_name_prefix(parent); 434 fwnode_handle_put(parent); 435 436 /* Guess something if prefix was NULL. */ 437 return prefix ?: "/"; 438} 439 440static struct fwnode_handle * 441software_node_get_parent(const struct fwnode_handle *fwnode) 442{ 443 struct swnode *swnode = to_swnode(fwnode); 444 445 if (!swnode || !swnode->parent) 446 return NULL; 447 448 return fwnode_handle_get(&swnode->parent->fwnode); 449} 450 451static struct fwnode_handle * 452software_node_get_next_child(const struct fwnode_handle *fwnode, 453 struct fwnode_handle *child) 454{ 455 struct swnode *p = to_swnode(fwnode); 456 struct swnode *c = to_swnode(child); 457 458 if (!p || list_empty(&p->children) || 459 (c && list_is_last(&c->entry, &p->children))) { 460 fwnode_handle_put(child); 461 return NULL; 462 } 463 464 if (c) 465 c = list_next_entry(c, entry); 466 else 467 c = list_first_entry(&p->children, struct swnode, entry); 468 469 fwnode_handle_put(child); 470 return fwnode_handle_get(&c->fwnode); 471} 472 473static struct fwnode_handle * 474software_node_get_named_child_node(const struct fwnode_handle *fwnode, 475 const char *childname) 476{ 477 struct swnode *swnode = to_swnode(fwnode); 478 struct swnode *child; 479 480 if (!swnode || list_empty(&swnode->children)) 481 return NULL; 482 483 list_for_each_entry(child, &swnode->children, entry) { 484 if (!strcmp(childname, kobject_name(&child->kobj))) { 485 kobject_get(&child->kobj); 486 return &child->fwnode; 487 } 488 } 489 return NULL; 490} 491 492static int 493software_node_get_reference_args(const struct fwnode_handle *fwnode, 494 const char *propname, const char *nargs_prop, 495 unsigned int nargs, unsigned int index, 496 struct fwnode_reference_args *args) 497{ 498 struct swnode *swnode = to_swnode(fwnode); 499 const struct software_node_ref_args *ref_array; 500 const struct software_node_ref_args *ref; 501 const struct property_entry *prop; 502 struct fwnode_handle *refnode; 503 u32 nargs_prop_val; 504 int error; 505 int i; 506 507 prop = property_entry_get(swnode->node->properties, propname); 508 if (!prop) 509 return -ENOENT; 510 511 if (prop->type != DEV_PROP_REF) 512 return -EINVAL; 513 514 /* 515 * We expect that references are never stored inline, even 516 * single ones, as they are too big. 517 */ 518 if (prop->is_inline) 519 return -EINVAL; 520 521 if (index * sizeof(*ref) >= prop->length) 522 return -ENOENT; 523 524 ref_array = prop->pointer; 525 ref = &ref_array[index]; 526 527 refnode = software_node_fwnode(ref->node); 528 if (!refnode) 529 return -ENOENT; 530 531 if (nargs_prop) { 532 error = property_entry_read_int_array(ref->node->properties, 533 nargs_prop, sizeof(u32), 534 &nargs_prop_val, 1); 535 if (error) 536 return error; 537 538 nargs = nargs_prop_val; 539 } 540 541 if (nargs > NR_FWNODE_REFERENCE_ARGS) 542 return -EINVAL; 543 544 args->fwnode = software_node_get(refnode); 545 args->nargs = nargs; 546 547 for (i = 0; i < nargs; i++) 548 args->args[i] = ref->args[i]; 549 550 return 0; 551} 552 553static struct fwnode_handle * 554swnode_graph_find_next_port(const struct fwnode_handle *parent, 555 struct fwnode_handle *port) 556{ 557 struct fwnode_handle *old = port; 558 559 while ((port = software_node_get_next_child(parent, old))) { 560 /* 561 * fwnode ports have naming style "port@", so we search for any 562 * children that follow that convention. 563 */ 564 if (!strncmp(to_swnode(port)->node->name, "port@", 565 strlen("port@"))) 566 return port; 567 old = port; 568 } 569 570 return NULL; 571} 572 573static struct fwnode_handle * 574software_node_graph_get_next_endpoint(const struct fwnode_handle *fwnode, 575 struct fwnode_handle *endpoint) 576{ 577 struct swnode *swnode = to_swnode(fwnode); 578 struct fwnode_handle *parent; 579 struct fwnode_handle *port; 580 581 if (!swnode) 582 return NULL; 583 584 if (endpoint) { 585 port = software_node_get_parent(endpoint); 586 parent = software_node_get_parent(port); 587 } else { 588 parent = software_node_get_named_child_node(fwnode, "ports"); 589 if (!parent) 590 parent = software_node_get(&swnode->fwnode); 591 592 port = swnode_graph_find_next_port(parent, NULL); 593 } 594 595 for (; port; port = swnode_graph_find_next_port(parent, port)) { 596 endpoint = software_node_get_next_child(port, endpoint); 597 if (endpoint) { 598 fwnode_handle_put(port); 599 break; 600 } 601 } 602 603 fwnode_handle_put(parent); 604 605 return endpoint; 606} 607 608static struct fwnode_handle * 609software_node_graph_get_remote_endpoint(const struct fwnode_handle *fwnode) 610{ 611 struct swnode *swnode = to_swnode(fwnode); 612 const struct software_node_ref_args *ref; 613 const struct property_entry *prop; 614 615 if (!swnode) 616 return NULL; 617 618 prop = property_entry_get(swnode->node->properties, "remote-endpoint"); 619 if (!prop || prop->type != DEV_PROP_REF || prop->is_inline) 620 return NULL; 621 622 ref = prop->pointer; 623 624 return software_node_get(software_node_fwnode(ref[0].node)); 625} 626 627static struct fwnode_handle * 628software_node_graph_get_port_parent(struct fwnode_handle *fwnode) 629{ 630 struct swnode *swnode = to_swnode(fwnode); 631 632 swnode = swnode->parent; 633 if (swnode && !strcmp(swnode->node->name, "ports")) 634 swnode = swnode->parent; 635 636 return swnode ? software_node_get(&swnode->fwnode) : NULL; 637} 638 639static int 640software_node_graph_parse_endpoint(const struct fwnode_handle *fwnode, 641 struct fwnode_endpoint *endpoint) 642{ 643 struct swnode *swnode = to_swnode(fwnode); 644 const char *parent_name = swnode->parent->node->name; 645 int ret; 646 647 if (strlen("port@") >= strlen(parent_name) || 648 strncmp(parent_name, "port@", strlen("port@"))) 649 return -EINVAL; 650 651 /* Ports have naming style "port@n", we need to select the n */ 652 ret = kstrtou32(parent_name + strlen("port@"), 10, &endpoint->port); 653 if (ret) 654 return ret; 655 656 endpoint->id = swnode->id; 657 endpoint->local_fwnode = fwnode; 658 659 return 0; 660} 661 662static const struct fwnode_operations software_node_ops = { 663 .get = software_node_get, 664 .put = software_node_put, 665 .property_present = software_node_property_present, 666 .property_read_int_array = software_node_read_int_array, 667 .property_read_string_array = software_node_read_string_array, 668 .get_name = software_node_get_name, 669 .get_name_prefix = software_node_get_name_prefix, 670 .get_parent = software_node_get_parent, 671 .get_next_child_node = software_node_get_next_child, 672 .get_named_child_node = software_node_get_named_child_node, 673 .get_reference_args = software_node_get_reference_args, 674 .graph_get_next_endpoint = software_node_graph_get_next_endpoint, 675 .graph_get_remote_endpoint = software_node_graph_get_remote_endpoint, 676 .graph_get_port_parent = software_node_graph_get_port_parent, 677 .graph_parse_endpoint = software_node_graph_parse_endpoint, 678}; 679 680/* -------------------------------------------------------------------------- */ 681 682/** 683 * software_node_find_by_name - Find software node by name 684 * @parent: Parent of the software node 685 * @name: Name of the software node 686 * 687 * The function will find a node that is child of @parent and that is named 688 * @name. If no node is found, the function returns NULL. 689 * 690 * NOTE: you will need to drop the reference with fwnode_handle_put() after use. 691 */ 692const struct software_node * 693software_node_find_by_name(const struct software_node *parent, const char *name) 694{ 695 struct swnode *swnode = NULL; 696 struct kobject *k; 697 698 if (!name) 699 return NULL; 700 701 spin_lock(&swnode_kset->list_lock); 702 703 list_for_each_entry(k, &swnode_kset->list, entry) { 704 swnode = kobj_to_swnode(k); 705 if (parent == swnode->node->parent && swnode->node->name && 706 !strcmp(name, swnode->node->name)) { 707 kobject_get(&swnode->kobj); 708 break; 709 } 710 swnode = NULL; 711 } 712 713 spin_unlock(&swnode_kset->list_lock); 714 715 return swnode ? swnode->node : NULL; 716} 717EXPORT_SYMBOL_GPL(software_node_find_by_name); 718 719static struct software_node *software_node_alloc(const struct property_entry *properties) 720{ 721 struct property_entry *props; 722 struct software_node *node; 723 724 props = property_entries_dup(properties); 725 if (IS_ERR(props)) 726 return ERR_CAST(props); 727 728 node = kzalloc(sizeof(*node), GFP_KERNEL); 729 if (!node) { 730 property_entries_free(props); 731 return ERR_PTR(-ENOMEM); 732 } 733 734 node->properties = props; 735 736 return node; 737} 738 739static void software_node_free(const struct software_node *node) 740{ 741 property_entries_free(node->properties); 742 kfree(node); 743} 744 745static void software_node_release(struct kobject *kobj) 746{ 747 struct swnode *swnode = kobj_to_swnode(kobj); 748 749 if (swnode->parent) { 750 ida_simple_remove(&swnode->parent->child_ids, swnode->id); 751 list_del(&swnode->entry); 752 } else { 753 ida_simple_remove(&swnode_root_ids, swnode->id); 754 } 755 756 if (swnode->allocated) 757 software_node_free(swnode->node); 758 759 ida_destroy(&swnode->child_ids); 760 kfree(swnode); 761} 762 763static struct kobj_type software_node_type = { 764 .release = software_node_release, 765 .sysfs_ops = &kobj_sysfs_ops, 766}; 767 768static struct fwnode_handle * 769swnode_register(const struct software_node *node, struct swnode *parent, 770 unsigned int allocated) 771{ 772 struct swnode *swnode; 773 int ret; 774 775 swnode = kzalloc(sizeof(*swnode), GFP_KERNEL); 776 if (!swnode) 777 return ERR_PTR(-ENOMEM); 778 779 ret = ida_simple_get(parent ? &parent->child_ids : &swnode_root_ids, 780 0, 0, GFP_KERNEL); 781 if (ret < 0) { 782 kfree(swnode); 783 return ERR_PTR(ret); 784 } 785 786 swnode->id = ret; 787 swnode->node = node; 788 swnode->parent = parent; 789 swnode->kobj.kset = swnode_kset; 790 fwnode_init(&swnode->fwnode, &software_node_ops); 791 792 ida_init(&swnode->child_ids); 793 INIT_LIST_HEAD(&swnode->entry); 794 INIT_LIST_HEAD(&swnode->children); 795 796 if (node->name) 797 ret = kobject_init_and_add(&swnode->kobj, &software_node_type, 798 parent ? &parent->kobj : NULL, 799 "%s", node->name); 800 else 801 ret = kobject_init_and_add(&swnode->kobj, &software_node_type, 802 parent ? &parent->kobj : NULL, 803 "node%d", swnode->id); 804 if (ret) { 805 kobject_put(&swnode->kobj); 806 return ERR_PTR(ret); 807 } 808 809 /* 810 * Assign the flag only in the successful case, so 811 * the above kobject_put() won't mess up with properties. 812 */ 813 swnode->allocated = allocated; 814 815 if (parent) 816 list_add_tail(&swnode->entry, &parent->children); 817 818 kobject_uevent(&swnode->kobj, KOBJ_ADD); 819 return &swnode->fwnode; 820} 821 822/** 823 * software_node_register_nodes - Register an array of software nodes 824 * @nodes: Zero terminated array of software nodes to be registered 825 * 826 * Register multiple software nodes at once. If any node in the array 827 * has its .parent pointer set (which can only be to another software_node), 828 * then its parent **must** have been registered before it is; either outside 829 * of this function or by ordering the array such that parent comes before 830 * child. 831 */ 832int software_node_register_nodes(const struct software_node *nodes) 833{ 834 int ret; 835 int i; 836 837 for (i = 0; nodes[i].name; i++) { 838 const struct software_node *parent = nodes[i].parent; 839 840 if (parent && !software_node_to_swnode(parent)) { 841 ret = -EINVAL; 842 goto err_unregister_nodes; 843 } 844 845 ret = software_node_register(&nodes[i]); 846 if (ret) 847 goto err_unregister_nodes; 848 } 849 850 return 0; 851 852err_unregister_nodes: 853 software_node_unregister_nodes(nodes); 854 return ret; 855} 856EXPORT_SYMBOL_GPL(software_node_register_nodes); 857 858/** 859 * software_node_unregister_nodes - Unregister an array of software nodes 860 * @nodes: Zero terminated array of software nodes to be unregistered 861 * 862 * Unregister multiple software nodes at once. If parent pointers are set up 863 * in any of the software nodes then the array **must** be ordered such that 864 * parents come before their children. 865 * 866 * NOTE: If you are uncertain whether the array is ordered such that 867 * parents will be unregistered before their children, it is wiser to 868 * remove the nodes individually, in the correct order (child before 869 * parent). 870 */ 871void software_node_unregister_nodes(const struct software_node *nodes) 872{ 873 unsigned int i = 0; 874 875 while (nodes[i].name) 876 i++; 877 878 while (i--) 879 software_node_unregister(&nodes[i]); 880} 881EXPORT_SYMBOL_GPL(software_node_unregister_nodes); 882 883/** 884 * software_node_register_node_group - Register a group of software nodes 885 * @node_group: NULL terminated array of software node pointers to be registered 886 * 887 * Register multiple software nodes at once. If any node in the array 888 * has its .parent pointer set (which can only be to another software_node), 889 * then its parent **must** have been registered before it is; either outside 890 * of this function or by ordering the array such that parent comes before 891 * child. 892 */ 893int software_node_register_node_group(const struct software_node **node_group) 894{ 895 unsigned int i; 896 int ret; 897 898 if (!node_group) 899 return 0; 900 901 for (i = 0; node_group[i]; i++) { 902 ret = software_node_register(node_group[i]); 903 if (ret) { 904 software_node_unregister_node_group(node_group); 905 return ret; 906 } 907 } 908 909 return 0; 910} 911EXPORT_SYMBOL_GPL(software_node_register_node_group); 912 913/** 914 * software_node_unregister_node_group - Unregister a group of software nodes 915 * @node_group: NULL terminated array of software node pointers to be unregistered 916 * 917 * Unregister multiple software nodes at once. If parent pointers are set up 918 * in any of the software nodes then the array **must** be ordered such that 919 * parents come before their children. 920 * 921 * NOTE: If you are uncertain whether the array is ordered such that 922 * parents will be unregistered before their children, it is wiser to 923 * remove the nodes individually, in the correct order (child before 924 * parent). 925 */ 926void software_node_unregister_node_group( 927 const struct software_node **node_group) 928{ 929 unsigned int i = 0; 930 931 if (!node_group) 932 return; 933 934 while (node_group[i]) 935 i++; 936 937 while (i--) 938 software_node_unregister(node_group[i]); 939} 940EXPORT_SYMBOL_GPL(software_node_unregister_node_group); 941 942/** 943 * software_node_register - Register static software node 944 * @node: The software node to be registered 945 */ 946int software_node_register(const struct software_node *node) 947{ 948 struct swnode *parent = software_node_to_swnode(node->parent); 949 950 if (software_node_to_swnode(node)) 951 return -EEXIST; 952 953 if (node->parent && !parent) 954 return -EINVAL; 955 956 return PTR_ERR_OR_ZERO(swnode_register(node, parent, 0)); 957} 958EXPORT_SYMBOL_GPL(software_node_register); 959 960/** 961 * software_node_unregister - Unregister static software node 962 * @node: The software node to be unregistered 963 */ 964void software_node_unregister(const struct software_node *node) 965{ 966 struct swnode *swnode; 967 968 swnode = software_node_to_swnode(node); 969 if (swnode) 970 fwnode_remove_software_node(&swnode->fwnode); 971} 972EXPORT_SYMBOL_GPL(software_node_unregister); 973 974struct fwnode_handle * 975fwnode_create_software_node(const struct property_entry *properties, 976 const struct fwnode_handle *parent) 977{ 978 struct fwnode_handle *fwnode; 979 struct software_node *node; 980 struct swnode *p; 981 982 if (IS_ERR(parent)) 983 return ERR_CAST(parent); 984 985 p = to_swnode(parent); 986 if (parent && !p) 987 return ERR_PTR(-EINVAL); 988 989 node = software_node_alloc(properties); 990 if (IS_ERR(node)) 991 return ERR_CAST(node); 992 993 node->parent = p ? p->node : NULL; 994 995 fwnode = swnode_register(node, p, 1); 996 if (IS_ERR(fwnode)) 997 software_node_free(node); 998 999 return fwnode; 1000} 1001EXPORT_SYMBOL_GPL(fwnode_create_software_node); 1002 1003void fwnode_remove_software_node(struct fwnode_handle *fwnode) 1004{ 1005 struct swnode *swnode = to_swnode(fwnode); 1006 1007 if (!swnode) 1008 return; 1009 1010 kobject_put(&swnode->kobj); 1011} 1012EXPORT_SYMBOL_GPL(fwnode_remove_software_node); 1013 1014/** 1015 * device_add_software_node - Assign software node to a device 1016 * @dev: The device the software node is meant for. 1017 * @node: The software node. 1018 * 1019 * This function will make @node the secondary firmware node pointer of @dev. If 1020 * @dev has no primary node, then @node will become the primary node. The 1021 * function will register @node automatically if it wasn't already registered. 1022 */ 1023int device_add_software_node(struct device *dev, const struct software_node *node) 1024{ 1025 struct swnode *swnode; 1026 int ret; 1027 1028 /* Only one software node per device. */ 1029 if (dev_to_swnode(dev)) 1030 return -EBUSY; 1031 1032 swnode = software_node_to_swnode(node); 1033 if (swnode) { 1034 kobject_get(&swnode->kobj); 1035 } else { 1036 ret = software_node_register(node); 1037 if (ret) 1038 return ret; 1039 1040 swnode = software_node_to_swnode(node); 1041 } 1042 1043 set_secondary_fwnode(dev, &swnode->fwnode); 1044 1045 /* 1046 * If the device has been fully registered by the time this function is 1047 * called, software_node_notify() must be called separately so that the 1048 * symlinks get created and the reference count of the node is kept in 1049 * balance. 1050 */ 1051 if (device_is_registered(dev)) 1052 software_node_notify(dev); 1053 1054 return 0; 1055} 1056EXPORT_SYMBOL_GPL(device_add_software_node); 1057 1058/** 1059 * device_remove_software_node - Remove device's software node 1060 * @dev: The device with the software node. 1061 * 1062 * This function will unregister the software node of @dev. 1063 */ 1064void device_remove_software_node(struct device *dev) 1065{ 1066 struct swnode *swnode; 1067 1068 swnode = dev_to_swnode(dev); 1069 if (!swnode) 1070 return; 1071 1072 if (device_is_registered(dev)) 1073 software_node_notify_remove(dev); 1074 1075 set_secondary_fwnode(dev, NULL); 1076 kobject_put(&swnode->kobj); 1077} 1078EXPORT_SYMBOL_GPL(device_remove_software_node); 1079 1080/** 1081 * device_create_managed_software_node - Create a software node for a device 1082 * @dev: The device the software node is assigned to. 1083 * @properties: Device properties for the software node. 1084 * @parent: Parent of the software node. 1085 * 1086 * Creates a software node as a managed resource for @dev, which means the 1087 * lifetime of the newly created software node is tied to the lifetime of @dev. 1088 * Software nodes created with this function should not be reused or shared 1089 * because of that. The function takes a deep copy of @properties for the 1090 * software node. 1091 * 1092 * Since the new software node is assigned directly to @dev, and since it should 1093 * not be shared, it is not returned to the caller. The function returns 0 on 1094 * success, and errno in case of an error. 1095 */ 1096int device_create_managed_software_node(struct device *dev, 1097 const struct property_entry *properties, 1098 const struct software_node *parent) 1099{ 1100 struct fwnode_handle *p = software_node_fwnode(parent); 1101 struct fwnode_handle *fwnode; 1102 1103 if (parent && !p) 1104 return -EINVAL; 1105 1106 fwnode = fwnode_create_software_node(properties, p); 1107 if (IS_ERR(fwnode)) 1108 return PTR_ERR(fwnode); 1109 1110 to_swnode(fwnode)->managed = true; 1111 set_secondary_fwnode(dev, fwnode); 1112 1113 if (device_is_registered(dev)) 1114 software_node_notify(dev); 1115 1116 return 0; 1117} 1118EXPORT_SYMBOL_GPL(device_create_managed_software_node); 1119 1120void software_node_notify(struct device *dev) 1121{ 1122 struct swnode *swnode; 1123 int ret; 1124 1125 swnode = dev_to_swnode(dev); 1126 if (!swnode) 1127 return; 1128 1129 ret = sysfs_create_link(&dev->kobj, &swnode->kobj, "software_node"); 1130 if (ret) 1131 return; 1132 1133 ret = sysfs_create_link(&swnode->kobj, &dev->kobj, dev_name(dev)); 1134 if (ret) { 1135 sysfs_remove_link(&dev->kobj, "software_node"); 1136 return; 1137 } 1138 1139 kobject_get(&swnode->kobj); 1140} 1141 1142void software_node_notify_remove(struct device *dev) 1143{ 1144 struct swnode *swnode; 1145 1146 swnode = dev_to_swnode(dev); 1147 if (!swnode) 1148 return; 1149 1150 sysfs_remove_link(&swnode->kobj, dev_name(dev)); 1151 sysfs_remove_link(&dev->kobj, "software_node"); 1152 kobject_put(&swnode->kobj); 1153 1154 if (swnode->managed) { 1155 set_secondary_fwnode(dev, NULL); 1156 kobject_put(&swnode->kobj); 1157 } 1158} 1159 1160static int __init software_node_init(void) 1161{ 1162 swnode_kset = kset_create_and_add("software_nodes", NULL, kernel_kobj); 1163 if (!swnode_kset) 1164 return -ENOMEM; 1165 return 0; 1166} 1167postcore_initcall(software_node_init); 1168 1169static void __exit software_node_exit(void) 1170{ 1171 ida_destroy(&swnode_root_ids); 1172 kset_unregister(swnode_kset); 1173} 1174__exitcall(software_node_exit);