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 struct swnode { 15 int id; 16 struct kobject kobj; 17 struct fwnode_handle fwnode; 18 const struct software_node *node; 19 20 /* hierarchy */ 21 struct ida child_ids; 22 struct list_head entry; 23 struct list_head children; 24 struct swnode *parent; 25 26 unsigned int allocated:1; 27 }; 28 29 static DEFINE_IDA(swnode_root_ids); 30 static struct kset *swnode_kset; 31 32 #define kobj_to_swnode(_kobj_) container_of(_kobj_, struct swnode, kobj) 33 34 static const struct fwnode_operations software_node_ops; 35 36 bool is_software_node(const struct fwnode_handle *fwnode) 37 { 38 return !IS_ERR_OR_NULL(fwnode) && fwnode->ops == &software_node_ops; 39 } 40 EXPORT_SYMBOL_GPL(is_software_node); 41 42 #define to_swnode(__fwnode) \ 43 ({ \ 44 typeof(__fwnode) __to_swnode_fwnode = __fwnode; \ 45 \ 46 is_software_node(__to_swnode_fwnode) ? \ 47 container_of(__to_swnode_fwnode, \ 48 struct swnode, fwnode) : NULL; \ 49 }) 50 51 static struct swnode * 52 software_node_to_swnode(const struct software_node *node) 53 { 54 struct swnode *swnode = NULL; 55 struct kobject *k; 56 57 if (!node) 58 return NULL; 59 60 spin_lock(&swnode_kset->list_lock); 61 62 list_for_each_entry(k, &swnode_kset->list, entry) { 63 swnode = kobj_to_swnode(k); 64 if (swnode->node == node) 65 break; 66 swnode = NULL; 67 } 68 69 spin_unlock(&swnode_kset->list_lock); 70 71 return swnode; 72 } 73 74 const struct software_node *to_software_node(struct fwnode_handle *fwnode) 75 { 76 struct swnode *swnode = to_swnode(fwnode); 77 78 return swnode ? swnode->node : NULL; 79 } 80 EXPORT_SYMBOL_GPL(to_software_node); 81 82 struct fwnode_handle *software_node_fwnode(const struct software_node *node) 83 { 84 struct swnode *swnode = software_node_to_swnode(node); 85 86 return swnode ? &swnode->fwnode : NULL; 87 } 88 EXPORT_SYMBOL_GPL(software_node_fwnode); 89 90 /* -------------------------------------------------------------------------- */ 91 /* property_entry processing */ 92 93 static const struct property_entry * 94 property_entry_get(const struct property_entry *prop, const char *name) 95 { 96 if (!prop) 97 return NULL; 98 99 for (; prop->name; prop++) 100 if (!strcmp(name, prop->name)) 101 return prop; 102 103 return NULL; 104 } 105 106 static void 107 property_set_pointer(struct property_entry *prop, const void *pointer) 108 { 109 switch (prop->type) { 110 case DEV_PROP_U8: 111 if (prop->is_array) 112 prop->pointer.u8_data = pointer; 113 else 114 prop->value.u8_data = *((u8 *)pointer); 115 break; 116 case DEV_PROP_U16: 117 if (prop->is_array) 118 prop->pointer.u16_data = pointer; 119 else 120 prop->value.u16_data = *((u16 *)pointer); 121 break; 122 case DEV_PROP_U32: 123 if (prop->is_array) 124 prop->pointer.u32_data = pointer; 125 else 126 prop->value.u32_data = *((u32 *)pointer); 127 break; 128 case DEV_PROP_U64: 129 if (prop->is_array) 130 prop->pointer.u64_data = pointer; 131 else 132 prop->value.u64_data = *((u64 *)pointer); 133 break; 134 case DEV_PROP_STRING: 135 if (prop->is_array) 136 prop->pointer.str = pointer; 137 else 138 prop->value.str = pointer; 139 break; 140 default: 141 break; 142 } 143 } 144 145 static const void *property_get_pointer(const struct property_entry *prop) 146 { 147 switch (prop->type) { 148 case DEV_PROP_U8: 149 if (prop->is_array) 150 return prop->pointer.u8_data; 151 return &prop->value.u8_data; 152 case DEV_PROP_U16: 153 if (prop->is_array) 154 return prop->pointer.u16_data; 155 return &prop->value.u16_data; 156 case DEV_PROP_U32: 157 if (prop->is_array) 158 return prop->pointer.u32_data; 159 return &prop->value.u32_data; 160 case DEV_PROP_U64: 161 if (prop->is_array) 162 return prop->pointer.u64_data; 163 return &prop->value.u64_data; 164 case DEV_PROP_STRING: 165 if (prop->is_array) 166 return prop->pointer.str; 167 return &prop->value.str; 168 default: 169 return NULL; 170 } 171 } 172 173 static const void *property_entry_find(const struct property_entry *props, 174 const char *propname, size_t length) 175 { 176 const struct property_entry *prop; 177 const void *pointer; 178 179 prop = property_entry_get(props, propname); 180 if (!prop) 181 return ERR_PTR(-EINVAL); 182 pointer = property_get_pointer(prop); 183 if (!pointer) 184 return ERR_PTR(-ENODATA); 185 if (length > prop->length) 186 return ERR_PTR(-EOVERFLOW); 187 return pointer; 188 } 189 190 static int property_entry_read_u8_array(const struct property_entry *props, 191 const char *propname, 192 u8 *values, size_t nval) 193 { 194 const void *pointer; 195 size_t length = nval * sizeof(*values); 196 197 pointer = property_entry_find(props, propname, length); 198 if (IS_ERR(pointer)) 199 return PTR_ERR(pointer); 200 201 memcpy(values, pointer, length); 202 return 0; 203 } 204 205 static int property_entry_read_u16_array(const struct property_entry *props, 206 const char *propname, 207 u16 *values, size_t nval) 208 { 209 const void *pointer; 210 size_t length = nval * sizeof(*values); 211 212 pointer = property_entry_find(props, propname, length); 213 if (IS_ERR(pointer)) 214 return PTR_ERR(pointer); 215 216 memcpy(values, pointer, length); 217 return 0; 218 } 219 220 static int property_entry_read_u32_array(const struct property_entry *props, 221 const char *propname, 222 u32 *values, size_t nval) 223 { 224 const void *pointer; 225 size_t length = nval * sizeof(*values); 226 227 pointer = property_entry_find(props, propname, length); 228 if (IS_ERR(pointer)) 229 return PTR_ERR(pointer); 230 231 memcpy(values, pointer, length); 232 return 0; 233 } 234 235 static int property_entry_read_u64_array(const struct property_entry *props, 236 const char *propname, 237 u64 *values, size_t nval) 238 { 239 const void *pointer; 240 size_t length = nval * sizeof(*values); 241 242 pointer = property_entry_find(props, propname, length); 243 if (IS_ERR(pointer)) 244 return PTR_ERR(pointer); 245 246 memcpy(values, pointer, length); 247 return 0; 248 } 249 250 static int 251 property_entry_count_elems_of_size(const struct property_entry *props, 252 const char *propname, size_t length) 253 { 254 const struct property_entry *prop; 255 256 prop = property_entry_get(props, propname); 257 if (!prop) 258 return -EINVAL; 259 260 return prop->length / length; 261 } 262 263 static int property_entry_read_int_array(const struct property_entry *props, 264 const char *name, 265 unsigned int elem_size, void *val, 266 size_t nval) 267 { 268 if (!val) 269 return property_entry_count_elems_of_size(props, name, 270 elem_size); 271 switch (elem_size) { 272 case sizeof(u8): 273 return property_entry_read_u8_array(props, name, val, nval); 274 case sizeof(u16): 275 return property_entry_read_u16_array(props, name, val, nval); 276 case sizeof(u32): 277 return property_entry_read_u32_array(props, name, val, nval); 278 case sizeof(u64): 279 return property_entry_read_u64_array(props, name, val, nval); 280 } 281 282 return -ENXIO; 283 } 284 285 static int property_entry_read_string_array(const struct property_entry *props, 286 const char *propname, 287 const char **strings, size_t nval) 288 { 289 const struct property_entry *prop; 290 const void *pointer; 291 size_t array_len, length; 292 293 /* Find out the array length. */ 294 prop = property_entry_get(props, propname); 295 if (!prop) 296 return -EINVAL; 297 298 if (prop->is_array) 299 /* Find the length of an array. */ 300 array_len = property_entry_count_elems_of_size(props, propname, 301 sizeof(const char *)); 302 else 303 /* The array length for a non-array string property is 1. */ 304 array_len = 1; 305 306 /* Return how many there are if strings is NULL. */ 307 if (!strings) 308 return array_len; 309 310 array_len = min(nval, array_len); 311 length = array_len * sizeof(*strings); 312 313 pointer = property_entry_find(props, propname, length); 314 if (IS_ERR(pointer)) 315 return PTR_ERR(pointer); 316 317 memcpy(strings, pointer, length); 318 319 return array_len; 320 } 321 322 static void property_entry_free_data(const struct property_entry *p) 323 { 324 const void *pointer = property_get_pointer(p); 325 size_t i, nval; 326 327 if (p->is_array) { 328 if (p->type == DEV_PROP_STRING && p->pointer.str) { 329 nval = p->length / sizeof(const char *); 330 for (i = 0; i < nval; i++) 331 kfree(p->pointer.str[i]); 332 } 333 kfree(pointer); 334 } else if (p->type == DEV_PROP_STRING) { 335 kfree(p->value.str); 336 } 337 kfree(p->name); 338 } 339 340 static int property_copy_string_array(struct property_entry *dst, 341 const struct property_entry *src) 342 { 343 const char **d; 344 size_t nval = src->length / sizeof(*d); 345 int i; 346 347 d = kcalloc(nval, sizeof(*d), GFP_KERNEL); 348 if (!d) 349 return -ENOMEM; 350 351 for (i = 0; i < nval; i++) { 352 d[i] = kstrdup(src->pointer.str[i], GFP_KERNEL); 353 if (!d[i] && src->pointer.str[i]) { 354 while (--i >= 0) 355 kfree(d[i]); 356 kfree(d); 357 return -ENOMEM; 358 } 359 } 360 361 dst->pointer.str = d; 362 return 0; 363 } 364 365 static int property_entry_copy_data(struct property_entry *dst, 366 const struct property_entry *src) 367 { 368 const void *pointer = property_get_pointer(src); 369 const void *new; 370 int error; 371 372 if (src->is_array) { 373 if (!src->length) 374 return -ENODATA; 375 376 if (src->type == DEV_PROP_STRING) { 377 error = property_copy_string_array(dst, src); 378 if (error) 379 return error; 380 new = dst->pointer.str; 381 } else { 382 new = kmemdup(pointer, src->length, GFP_KERNEL); 383 if (!new) 384 return -ENOMEM; 385 } 386 } else if (src->type == DEV_PROP_STRING) { 387 new = kstrdup(src->value.str, GFP_KERNEL); 388 if (!new && src->value.str) 389 return -ENOMEM; 390 } else { 391 new = pointer; 392 } 393 394 dst->length = src->length; 395 dst->is_array = src->is_array; 396 dst->type = src->type; 397 398 property_set_pointer(dst, new); 399 400 dst->name = kstrdup(src->name, GFP_KERNEL); 401 if (!dst->name) 402 goto out_free_data; 403 404 return 0; 405 406 out_free_data: 407 property_entry_free_data(dst); 408 return -ENOMEM; 409 } 410 411 /** 412 * property_entries_dup - duplicate array of properties 413 * @properties: array of properties to copy 414 * 415 * This function creates a deep copy of the given NULL-terminated array 416 * of property entries. 417 */ 418 struct property_entry * 419 property_entries_dup(const struct property_entry *properties) 420 { 421 struct property_entry *p; 422 int i, n = 0; 423 int ret; 424 425 if (!properties) 426 return NULL; 427 428 while (properties[n].name) 429 n++; 430 431 p = kcalloc(n + 1, sizeof(*p), GFP_KERNEL); 432 if (!p) 433 return ERR_PTR(-ENOMEM); 434 435 for (i = 0; i < n; i++) { 436 ret = property_entry_copy_data(&p[i], &properties[i]); 437 if (ret) { 438 while (--i >= 0) 439 property_entry_free_data(&p[i]); 440 kfree(p); 441 return ERR_PTR(ret); 442 } 443 } 444 445 return p; 446 } 447 EXPORT_SYMBOL_GPL(property_entries_dup); 448 449 /** 450 * property_entries_free - free previously allocated array of properties 451 * @properties: array of properties to destroy 452 * 453 * This function frees given NULL-terminated array of property entries, 454 * along with their data. 455 */ 456 void property_entries_free(const struct property_entry *properties) 457 { 458 const struct property_entry *p; 459 460 if (!properties) 461 return; 462 463 for (p = properties; p->name; p++) 464 property_entry_free_data(p); 465 466 kfree(properties); 467 } 468 EXPORT_SYMBOL_GPL(property_entries_free); 469 470 /* -------------------------------------------------------------------------- */ 471 /* fwnode operations */ 472 473 static struct fwnode_handle *software_node_get(struct fwnode_handle *fwnode) 474 { 475 struct swnode *swnode = to_swnode(fwnode); 476 477 kobject_get(&swnode->kobj); 478 479 return &swnode->fwnode; 480 } 481 482 static void software_node_put(struct fwnode_handle *fwnode) 483 { 484 struct swnode *swnode = to_swnode(fwnode); 485 486 kobject_put(&swnode->kobj); 487 } 488 489 static bool software_node_property_present(const struct fwnode_handle *fwnode, 490 const char *propname) 491 { 492 struct swnode *swnode = to_swnode(fwnode); 493 494 return !!property_entry_get(swnode->node->properties, propname); 495 } 496 497 static int software_node_read_int_array(const struct fwnode_handle *fwnode, 498 const char *propname, 499 unsigned int elem_size, void *val, 500 size_t nval) 501 { 502 struct swnode *swnode = to_swnode(fwnode); 503 504 return property_entry_read_int_array(swnode->node->properties, propname, 505 elem_size, val, nval); 506 } 507 508 static int software_node_read_string_array(const struct fwnode_handle *fwnode, 509 const char *propname, 510 const char **val, size_t nval) 511 { 512 struct swnode *swnode = to_swnode(fwnode); 513 514 return property_entry_read_string_array(swnode->node->properties, 515 propname, val, nval); 516 } 517 518 static struct fwnode_handle * 519 software_node_get_parent(const struct fwnode_handle *fwnode) 520 { 521 struct swnode *swnode = to_swnode(fwnode); 522 523 return swnode ? (swnode->parent ? &swnode->parent->fwnode : NULL) : NULL; 524 } 525 526 static struct fwnode_handle * 527 software_node_get_next_child(const struct fwnode_handle *fwnode, 528 struct fwnode_handle *child) 529 { 530 struct swnode *p = to_swnode(fwnode); 531 struct swnode *c = to_swnode(child); 532 533 if (!p || list_empty(&p->children) || 534 (c && list_is_last(&c->entry, &p->children))) 535 return NULL; 536 537 if (c) 538 c = list_next_entry(c, entry); 539 else 540 c = list_first_entry(&p->children, struct swnode, entry); 541 return &c->fwnode; 542 } 543 544 static struct fwnode_handle * 545 software_node_get_named_child_node(const struct fwnode_handle *fwnode, 546 const char *childname) 547 { 548 struct swnode *swnode = to_swnode(fwnode); 549 struct swnode *child; 550 551 if (!swnode || list_empty(&swnode->children)) 552 return NULL; 553 554 list_for_each_entry(child, &swnode->children, entry) { 555 if (!strcmp(childname, kobject_name(&child->kobj))) { 556 kobject_get(&child->kobj); 557 return &child->fwnode; 558 } 559 } 560 return NULL; 561 } 562 563 static int 564 software_node_get_reference_args(const struct fwnode_handle *fwnode, 565 const char *propname, const char *nargs_prop, 566 unsigned int nargs, unsigned int index, 567 struct fwnode_reference_args *args) 568 { 569 struct swnode *swnode = to_swnode(fwnode); 570 const struct software_node_reference *ref; 571 const struct property_entry *prop; 572 struct fwnode_handle *refnode; 573 int i; 574 575 if (!swnode || !swnode->node->references) 576 return -ENOENT; 577 578 for (ref = swnode->node->references; ref->name; ref++) 579 if (!strcmp(ref->name, propname)) 580 break; 581 582 if (!ref->name || index > (ref->nrefs - 1)) 583 return -ENOENT; 584 585 refnode = software_node_fwnode(ref->refs[index].node); 586 if (!refnode) 587 return -ENOENT; 588 589 if (nargs_prop) { 590 prop = property_entry_get(swnode->node->properties, nargs_prop); 591 if (!prop) 592 return -EINVAL; 593 594 nargs = prop->value.u32_data; 595 } 596 597 if (nargs > NR_FWNODE_REFERENCE_ARGS) 598 return -EINVAL; 599 600 args->fwnode = software_node_get(refnode); 601 args->nargs = nargs; 602 603 for (i = 0; i < nargs; i++) 604 args->args[i] = ref->refs[index].args[i]; 605 606 return 0; 607 } 608 609 static const struct fwnode_operations software_node_ops = { 610 .get = software_node_get, 611 .put = software_node_put, 612 .property_present = software_node_property_present, 613 .property_read_int_array = software_node_read_int_array, 614 .property_read_string_array = software_node_read_string_array, 615 .get_parent = software_node_get_parent, 616 .get_next_child_node = software_node_get_next_child, 617 .get_named_child_node = software_node_get_named_child_node, 618 .get_reference_args = software_node_get_reference_args 619 }; 620 621 /* -------------------------------------------------------------------------- */ 622 623 /** 624 * software_node_find_by_name - Find software node by name 625 * @parent: Parent of the software node 626 * @name: Name of the software node 627 * 628 * The function will find a node that is child of @parent and that is named 629 * @name. If no node is found, the function returns NULL. 630 * 631 * NOTE: you will need to drop the reference with fwnode_handle_put() after use. 632 */ 633 const struct software_node * 634 software_node_find_by_name(const struct software_node *parent, const char *name) 635 { 636 struct swnode *swnode = NULL; 637 struct kobject *k; 638 639 if (!name) 640 return NULL; 641 642 spin_lock(&swnode_kset->list_lock); 643 644 list_for_each_entry(k, &swnode_kset->list, entry) { 645 swnode = kobj_to_swnode(k); 646 if (parent == swnode->node->parent && swnode->node->name && 647 !strcmp(name, swnode->node->name)) { 648 kobject_get(&swnode->kobj); 649 break; 650 } 651 swnode = NULL; 652 } 653 654 spin_unlock(&swnode_kset->list_lock); 655 656 return swnode ? swnode->node : NULL; 657 } 658 EXPORT_SYMBOL_GPL(software_node_find_by_name); 659 660 static int 661 software_node_register_properties(struct software_node *node, 662 const struct property_entry *properties) 663 { 664 struct property_entry *props; 665 666 props = property_entries_dup(properties); 667 if (IS_ERR(props)) 668 return PTR_ERR(props); 669 670 node->properties = props; 671 672 return 0; 673 } 674 675 static void software_node_release(struct kobject *kobj) 676 { 677 struct swnode *swnode = kobj_to_swnode(kobj); 678 679 if (swnode->allocated) { 680 property_entries_free(swnode->node->properties); 681 kfree(swnode->node); 682 } 683 ida_destroy(&swnode->child_ids); 684 kfree(swnode); 685 } 686 687 static struct kobj_type software_node_type = { 688 .release = software_node_release, 689 .sysfs_ops = &kobj_sysfs_ops, 690 }; 691 692 static struct fwnode_handle * 693 swnode_register(const struct software_node *node, struct swnode *parent, 694 unsigned int allocated) 695 { 696 struct swnode *swnode; 697 int ret; 698 699 swnode = kzalloc(sizeof(*swnode), GFP_KERNEL); 700 if (!swnode) { 701 ret = -ENOMEM; 702 goto out_err; 703 } 704 705 ret = ida_simple_get(parent ? &parent->child_ids : &swnode_root_ids, 706 0, 0, GFP_KERNEL); 707 if (ret < 0) { 708 kfree(swnode); 709 goto out_err; 710 } 711 712 swnode->id = ret; 713 swnode->node = node; 714 swnode->parent = parent; 715 swnode->allocated = allocated; 716 swnode->kobj.kset = swnode_kset; 717 swnode->fwnode.ops = &software_node_ops; 718 719 ida_init(&swnode->child_ids); 720 INIT_LIST_HEAD(&swnode->entry); 721 INIT_LIST_HEAD(&swnode->children); 722 723 if (node->name) 724 ret = kobject_init_and_add(&swnode->kobj, &software_node_type, 725 parent ? &parent->kobj : NULL, 726 "%s", node->name); 727 else 728 ret = kobject_init_and_add(&swnode->kobj, &software_node_type, 729 parent ? &parent->kobj : NULL, 730 "node%d", swnode->id); 731 if (ret) { 732 kobject_put(&swnode->kobj); 733 return ERR_PTR(ret); 734 } 735 736 if (parent) 737 list_add_tail(&swnode->entry, &parent->children); 738 739 kobject_uevent(&swnode->kobj, KOBJ_ADD); 740 return &swnode->fwnode; 741 742 out_err: 743 if (allocated) 744 property_entries_free(node->properties); 745 return ERR_PTR(ret); 746 } 747 748 /** 749 * software_node_register_nodes - Register an array of software nodes 750 * @nodes: Zero terminated array of software nodes to be registered 751 * 752 * Register multiple software nodes at once. 753 */ 754 int software_node_register_nodes(const struct software_node *nodes) 755 { 756 int ret; 757 int i; 758 759 for (i = 0; nodes[i].name; i++) { 760 ret = software_node_register(&nodes[i]); 761 if (ret) { 762 software_node_unregister_nodes(nodes); 763 return ret; 764 } 765 } 766 767 return 0; 768 } 769 EXPORT_SYMBOL_GPL(software_node_register_nodes); 770 771 /** 772 * software_node_unregister_nodes - Unregister an array of software nodes 773 * @nodes: Zero terminated array of software nodes to be unregistered 774 * 775 * Unregister multiple software nodes at once. 776 */ 777 void software_node_unregister_nodes(const struct software_node *nodes) 778 { 779 struct swnode *swnode; 780 int i; 781 782 for (i = 0; nodes[i].name; i++) { 783 swnode = software_node_to_swnode(&nodes[i]); 784 if (swnode) 785 fwnode_remove_software_node(&swnode->fwnode); 786 } 787 } 788 EXPORT_SYMBOL_GPL(software_node_unregister_nodes); 789 790 /** 791 * software_node_register - Register static software node 792 * @node: The software node to be registered 793 */ 794 int software_node_register(const struct software_node *node) 795 { 796 struct swnode *parent = software_node_to_swnode(node->parent); 797 798 if (software_node_to_swnode(node)) 799 return -EEXIST; 800 801 return PTR_ERR_OR_ZERO(swnode_register(node, parent, 0)); 802 } 803 EXPORT_SYMBOL_GPL(software_node_register); 804 805 struct fwnode_handle * 806 fwnode_create_software_node(const struct property_entry *properties, 807 const struct fwnode_handle *parent) 808 { 809 struct software_node *node; 810 struct swnode *p = NULL; 811 int ret; 812 813 if (parent) { 814 if (IS_ERR(parent)) 815 return ERR_CAST(parent); 816 if (!is_software_node(parent)) 817 return ERR_PTR(-EINVAL); 818 p = to_swnode(parent); 819 } 820 821 node = kzalloc(sizeof(*node), GFP_KERNEL); 822 if (!node) 823 return ERR_PTR(-ENOMEM); 824 825 ret = software_node_register_properties(node, properties); 826 if (ret) { 827 kfree(node); 828 return ERR_PTR(ret); 829 } 830 831 node->parent = p ? p->node : NULL; 832 833 return swnode_register(node, p, 1); 834 } 835 EXPORT_SYMBOL_GPL(fwnode_create_software_node); 836 837 void fwnode_remove_software_node(struct fwnode_handle *fwnode) 838 { 839 struct swnode *swnode = to_swnode(fwnode); 840 841 if (!swnode) 842 return; 843 844 if (swnode->parent) { 845 ida_simple_remove(&swnode->parent->child_ids, swnode->id); 846 list_del(&swnode->entry); 847 } else { 848 ida_simple_remove(&swnode_root_ids, swnode->id); 849 } 850 851 kobject_put(&swnode->kobj); 852 } 853 EXPORT_SYMBOL_GPL(fwnode_remove_software_node); 854 855 int software_node_notify(struct device *dev, unsigned long action) 856 { 857 struct fwnode_handle *fwnode = dev_fwnode(dev); 858 struct swnode *swnode; 859 int ret; 860 861 if (!fwnode) 862 return 0; 863 864 if (!is_software_node(fwnode)) 865 fwnode = fwnode->secondary; 866 if (!is_software_node(fwnode)) 867 return 0; 868 869 swnode = to_swnode(fwnode); 870 871 switch (action) { 872 case KOBJ_ADD: 873 ret = sysfs_create_link(&dev->kobj, &swnode->kobj, 874 "software_node"); 875 if (ret) 876 break; 877 878 ret = sysfs_create_link(&swnode->kobj, &dev->kobj, 879 dev_name(dev)); 880 if (ret) { 881 sysfs_remove_link(&dev->kobj, "software_node"); 882 break; 883 } 884 kobject_get(&swnode->kobj); 885 break; 886 case KOBJ_REMOVE: 887 sysfs_remove_link(&swnode->kobj, dev_name(dev)); 888 sysfs_remove_link(&dev->kobj, "software_node"); 889 kobject_put(&swnode->kobj); 890 break; 891 default: 892 break; 893 } 894 895 return 0; 896 } 897 898 static int __init software_node_init(void) 899 { 900 swnode_kset = kset_create_and_add("software_nodes", NULL, kernel_kobj); 901 if (!swnode_kset) 902 return -ENOMEM; 903 return 0; 904 } 905 postcore_initcall(software_node_init); 906 907 static void __exit software_node_exit(void) 908 { 909 ida_destroy(&swnode_root_ids); 910 kset_unregister(swnode_kset); 911 } 912 __exitcall(software_node_exit); 913