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;
  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(struct fwnode_handle *fwnode)
  75{
  76        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 void
 107property_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
 145static 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
 173static 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
 190static 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
 205static 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
 220static 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
 235static 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
 250static int
 251property_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
 263static 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
 285static 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
 322static 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
 340static 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
 365static 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
 406out_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 */
 418struct property_entry *
 419property_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}
 447EXPORT_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 */
 456void 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}
 468EXPORT_SYMBOL_GPL(property_entries_free);
 469
 470/* -------------------------------------------------------------------------- */
 471/* fwnode operations */
 472
 473static 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
 482static void software_node_put(struct fwnode_handle *fwnode)
 483{
 484        struct swnode *swnode = to_swnode(fwnode);
 485
 486        kobject_put(&swnode->kobj);
 487}
 488
 489static 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
 497static 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
 508static 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
 518static struct fwnode_handle *
 519software_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
 526static struct fwnode_handle *
 527software_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
 544static struct fwnode_handle *
 545software_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
 563static int
 564software_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
 609static 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
 623static int
 624software_node_register_properties(struct software_node *node,
 625                                  const struct property_entry *properties)
 626{
 627        struct property_entry *props;
 628
 629        props = property_entries_dup(properties);
 630        if (IS_ERR(props))
 631                return PTR_ERR(props);
 632
 633        node->properties = props;
 634
 635        return 0;
 636}
 637
 638static void software_node_release(struct kobject *kobj)
 639{
 640        struct swnode *swnode = kobj_to_swnode(kobj);
 641
 642        if (swnode->allocated) {
 643                property_entries_free(swnode->node->properties);
 644                kfree(swnode->node);
 645        }
 646        ida_destroy(&swnode->child_ids);
 647        kfree(swnode);
 648}
 649
 650static struct kobj_type software_node_type = {
 651        .release = software_node_release,
 652        .sysfs_ops = &kobj_sysfs_ops,
 653};
 654
 655static struct fwnode_handle *
 656swnode_register(const struct software_node *node, struct swnode *parent,
 657                unsigned int allocated)
 658{
 659        struct swnode *swnode;
 660        int ret;
 661
 662        swnode = kzalloc(sizeof(*swnode), GFP_KERNEL);
 663        if (!swnode) {
 664                ret = -ENOMEM;
 665                goto out_err;
 666        }
 667
 668        ret = ida_simple_get(parent ? &parent->child_ids : &swnode_root_ids,
 669                             0, 0, GFP_KERNEL);
 670        if (ret < 0) {
 671                kfree(swnode);
 672                goto out_err;
 673        }
 674
 675        swnode->id = ret;
 676        swnode->node = node;
 677        swnode->parent = parent;
 678        swnode->allocated = allocated;
 679        swnode->kobj.kset = swnode_kset;
 680        swnode->fwnode.ops = &software_node_ops;
 681
 682        ida_init(&swnode->child_ids);
 683        INIT_LIST_HEAD(&swnode->entry);
 684        INIT_LIST_HEAD(&swnode->children);
 685
 686        if (node->name)
 687                ret = kobject_init_and_add(&swnode->kobj, &software_node_type,
 688                                           parent ? &parent->kobj : NULL,
 689                                           "%s", node->name);
 690        else
 691                ret = kobject_init_and_add(&swnode->kobj, &software_node_type,
 692                                           parent ? &parent->kobj : NULL,
 693                                           "node%d", swnode->id);
 694        if (ret) {
 695                kobject_put(&swnode->kobj);
 696                return ERR_PTR(ret);
 697        }
 698
 699        if (parent)
 700                list_add_tail(&swnode->entry, &parent->children);
 701
 702        kobject_uevent(&swnode->kobj, KOBJ_ADD);
 703        return &swnode->fwnode;
 704
 705out_err:
 706        if (allocated)
 707                property_entries_free(node->properties);
 708        return ERR_PTR(ret);
 709}
 710
 711/**
 712 * software_node_register_nodes - Register an array of software nodes
 713 * @nodes: Zero terminated array of software nodes to be registered
 714 *
 715 * Register multiple software nodes at once.
 716 */
 717int software_node_register_nodes(const struct software_node *nodes)
 718{
 719        int ret;
 720        int i;
 721
 722        for (i = 0; nodes[i].name; i++) {
 723                ret = software_node_register(&nodes[i]);
 724                if (ret) {
 725                        software_node_unregister_nodes(nodes);
 726                        return ret;
 727                }
 728        }
 729
 730        return 0;
 731}
 732EXPORT_SYMBOL_GPL(software_node_register_nodes);
 733
 734/**
 735 * software_node_unregister_nodes - Unregister an array of software nodes
 736 * @nodes: Zero terminated array of software nodes to be unregistered
 737 *
 738 * Unregister multiple software nodes at once.
 739 */
 740void software_node_unregister_nodes(const struct software_node *nodes)
 741{
 742        struct swnode *swnode;
 743        int i;
 744
 745        for (i = 0; nodes[i].name; i++) {
 746                swnode = software_node_to_swnode(&nodes[i]);
 747                if (swnode)
 748                        fwnode_remove_software_node(&swnode->fwnode);
 749        }
 750}
 751EXPORT_SYMBOL_GPL(software_node_unregister_nodes);
 752
 753/**
 754 * software_node_register - Register static software node
 755 * @node: The software node to be registered
 756 */
 757int software_node_register(const struct software_node *node)
 758{
 759        struct swnode *parent = software_node_to_swnode(node->parent);
 760
 761        if (software_node_to_swnode(node))
 762                return -EEXIST;
 763
 764        return PTR_ERR_OR_ZERO(swnode_register(node, parent, 0));
 765}
 766EXPORT_SYMBOL_GPL(software_node_register);
 767
 768struct fwnode_handle *
 769fwnode_create_software_node(const struct property_entry *properties,
 770                            const struct fwnode_handle *parent)
 771{
 772        struct software_node *node;
 773        struct swnode *p = NULL;
 774        int ret;
 775
 776        if (parent) {
 777                if (IS_ERR(parent))
 778                        return ERR_CAST(parent);
 779                if (!is_software_node(parent))
 780                        return ERR_PTR(-EINVAL);
 781                p = to_swnode(parent);
 782        }
 783
 784        node = kzalloc(sizeof(*node), GFP_KERNEL);
 785        if (!node)
 786                return ERR_PTR(-ENOMEM);
 787
 788        ret = software_node_register_properties(node, properties);
 789        if (ret) {
 790                kfree(node);
 791                return ERR_PTR(ret);
 792        }
 793
 794        node->parent = p ? p->node : NULL;
 795
 796        return swnode_register(node, p, 1);
 797}
 798EXPORT_SYMBOL_GPL(fwnode_create_software_node);
 799
 800void fwnode_remove_software_node(struct fwnode_handle *fwnode)
 801{
 802        struct swnode *swnode = to_swnode(fwnode);
 803
 804        if (!swnode)
 805                return;
 806
 807        if (swnode->parent) {
 808                ida_simple_remove(&swnode->parent->child_ids, swnode->id);
 809                list_del(&swnode->entry);
 810        } else {
 811                ida_simple_remove(&swnode_root_ids, swnode->id);
 812        }
 813
 814        kobject_put(&swnode->kobj);
 815}
 816EXPORT_SYMBOL_GPL(fwnode_remove_software_node);
 817
 818int software_node_notify(struct device *dev, unsigned long action)
 819{
 820        struct fwnode_handle *fwnode = dev_fwnode(dev);
 821        struct swnode *swnode;
 822        int ret;
 823
 824        if (!fwnode)
 825                return 0;
 826
 827        if (!is_software_node(fwnode))
 828                fwnode = fwnode->secondary;
 829        if (!is_software_node(fwnode))
 830                return 0;
 831
 832        swnode = to_swnode(fwnode);
 833
 834        switch (action) {
 835        case KOBJ_ADD:
 836                ret = sysfs_create_link(&dev->kobj, &swnode->kobj,
 837                                        "software_node");
 838                if (ret)
 839                        break;
 840
 841                ret = sysfs_create_link(&swnode->kobj, &dev->kobj,
 842                                        dev_name(dev));
 843                if (ret) {
 844                        sysfs_remove_link(&dev->kobj, "software_node");
 845                        break;
 846                }
 847                kobject_get(&swnode->kobj);
 848                break;
 849        case KOBJ_REMOVE:
 850                sysfs_remove_link(&swnode->kobj, dev_name(dev));
 851                sysfs_remove_link(&dev->kobj, "software_node");
 852                kobject_put(&swnode->kobj);
 853                break;
 854        default:
 855                break;
 856        }
 857
 858        return 0;
 859}
 860
 861static int __init software_node_init(void)
 862{
 863        swnode_kset = kset_create_and_add("software_nodes", NULL, kernel_kobj);
 864        if (!swnode_kset)
 865                return -ENOMEM;
 866        return 0;
 867}
 868postcore_initcall(software_node_init);
 869
 870static void __exit software_node_exit(void)
 871{
 872        ida_destroy(&swnode_root_ids);
 873        kset_unregister(swnode_kset);
 874}
 875__exitcall(software_node_exit);
 876