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