root/drivers/base/swnode.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. is_software_node
  2. software_node_to_swnode
  3. to_software_node
  4. software_node_fwnode
  5. property_entry_get
  6. property_set_pointer
  7. property_get_pointer
  8. property_entry_find
  9. property_entry_read_u8_array
  10. property_entry_read_u16_array
  11. property_entry_read_u32_array
  12. property_entry_read_u64_array
  13. property_entry_count_elems_of_size
  14. property_entry_read_int_array
  15. property_entry_read_string_array
  16. property_entry_free_data
  17. property_copy_string_array
  18. property_entry_copy_data
  19. property_entries_dup
  20. property_entries_free
  21. software_node_get
  22. software_node_put
  23. software_node_property_present
  24. software_node_read_int_array
  25. software_node_read_string_array
  26. software_node_get_parent
  27. software_node_get_next_child
  28. software_node_get_named_child_node
  29. software_node_get_reference_args
  30. software_node_find_by_name
  31. software_node_register_properties
  32. software_node_release
  33. swnode_register
  34. software_node_register_nodes
  35. software_node_unregister_nodes
  36. software_node_register
  37. fwnode_create_software_node
  38. fwnode_remove_software_node
  39. software_node_notify
  40. software_node_init
  41. software_node_exit

   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         if (!swnode || !swnode->parent)
 524                 return NULL;
 525 
 526         return fwnode_handle_get(&swnode->parent->fwnode);
 527 }
 528 
 529 static struct fwnode_handle *
 530 software_node_get_next_child(const struct fwnode_handle *fwnode,
 531                              struct fwnode_handle *child)
 532 {
 533         struct swnode *p = to_swnode(fwnode);
 534         struct swnode *c = to_swnode(child);
 535 
 536         if (!p || list_empty(&p->children) ||
 537             (c && list_is_last(&c->entry, &p->children)))
 538                 return NULL;
 539 
 540         if (c)
 541                 c = list_next_entry(c, entry);
 542         else
 543                 c = list_first_entry(&p->children, struct swnode, entry);
 544         return &c->fwnode;
 545 }
 546 
 547 static struct fwnode_handle *
 548 software_node_get_named_child_node(const struct fwnode_handle *fwnode,
 549                                    const char *childname)
 550 {
 551         struct swnode *swnode = to_swnode(fwnode);
 552         struct swnode *child;
 553 
 554         if (!swnode || list_empty(&swnode->children))
 555                 return NULL;
 556 
 557         list_for_each_entry(child, &swnode->children, entry) {
 558                 if (!strcmp(childname, kobject_name(&child->kobj))) {
 559                         kobject_get(&child->kobj);
 560                         return &child->fwnode;
 561                 }
 562         }
 563         return NULL;
 564 }
 565 
 566 static int
 567 software_node_get_reference_args(const struct fwnode_handle *fwnode,
 568                                  const char *propname, const char *nargs_prop,
 569                                  unsigned int nargs, unsigned int index,
 570                                  struct fwnode_reference_args *args)
 571 {
 572         struct swnode *swnode = to_swnode(fwnode);
 573         const struct software_node_reference *ref;
 574         const struct property_entry *prop;
 575         struct fwnode_handle *refnode;
 576         int i;
 577 
 578         if (!swnode || !swnode->node->references)
 579                 return -ENOENT;
 580 
 581         for (ref = swnode->node->references; ref->name; ref++)
 582                 if (!strcmp(ref->name, propname))
 583                         break;
 584 
 585         if (!ref->name || index > (ref->nrefs - 1))
 586                 return -ENOENT;
 587 
 588         refnode = software_node_fwnode(ref->refs[index].node);
 589         if (!refnode)
 590                 return -ENOENT;
 591 
 592         if (nargs_prop) {
 593                 prop = property_entry_get(swnode->node->properties, nargs_prop);
 594                 if (!prop)
 595                         return -EINVAL;
 596 
 597                 nargs = prop->value.u32_data;
 598         }
 599 
 600         if (nargs > NR_FWNODE_REFERENCE_ARGS)
 601                 return -EINVAL;
 602 
 603         args->fwnode = software_node_get(refnode);
 604         args->nargs = nargs;
 605 
 606         for (i = 0; i < nargs; i++)
 607                 args->args[i] = ref->refs[index].args[i];
 608 
 609         return 0;
 610 }
 611 
 612 static const struct fwnode_operations software_node_ops = {
 613         .get = software_node_get,
 614         .put = software_node_put,
 615         .property_present = software_node_property_present,
 616         .property_read_int_array = software_node_read_int_array,
 617         .property_read_string_array = software_node_read_string_array,
 618         .get_parent = software_node_get_parent,
 619         .get_next_child_node = software_node_get_next_child,
 620         .get_named_child_node = software_node_get_named_child_node,
 621         .get_reference_args = software_node_get_reference_args
 622 };
 623 
 624 /* -------------------------------------------------------------------------- */
 625 
 626 /**
 627  * software_node_find_by_name - Find software node by name
 628  * @parent: Parent of the software node
 629  * @name: Name of the software node
 630  *
 631  * The function will find a node that is child of @parent and that is named
 632  * @name. If no node is found, the function returns NULL.
 633  *
 634  * NOTE: you will need to drop the reference with fwnode_handle_put() after use.
 635  */
 636 const struct software_node *
 637 software_node_find_by_name(const struct software_node *parent, const char *name)
 638 {
 639         struct swnode *swnode = NULL;
 640         struct kobject *k;
 641 
 642         if (!name)
 643                 return NULL;
 644 
 645         spin_lock(&swnode_kset->list_lock);
 646 
 647         list_for_each_entry(k, &swnode_kset->list, entry) {
 648                 swnode = kobj_to_swnode(k);
 649                 if (parent == swnode->node->parent && swnode->node->name &&
 650                     !strcmp(name, swnode->node->name)) {
 651                         kobject_get(&swnode->kobj);
 652                         break;
 653                 }
 654                 swnode = NULL;
 655         }
 656 
 657         spin_unlock(&swnode_kset->list_lock);
 658 
 659         return swnode ? swnode->node : NULL;
 660 }
 661 EXPORT_SYMBOL_GPL(software_node_find_by_name);
 662 
 663 static int
 664 software_node_register_properties(struct software_node *node,
 665                                   const struct property_entry *properties)
 666 {
 667         struct property_entry *props;
 668 
 669         props = property_entries_dup(properties);
 670         if (IS_ERR(props))
 671                 return PTR_ERR(props);
 672 
 673         node->properties = props;
 674 
 675         return 0;
 676 }
 677 
 678 static void software_node_release(struct kobject *kobj)
 679 {
 680         struct swnode *swnode = kobj_to_swnode(kobj);
 681 
 682         if (swnode->parent) {
 683                 ida_simple_remove(&swnode->parent->child_ids, swnode->id);
 684                 list_del(&swnode->entry);
 685         } else {
 686                 ida_simple_remove(&swnode_root_ids, swnode->id);
 687         }
 688 
 689         if (swnode->allocated) {
 690                 property_entries_free(swnode->node->properties);
 691                 kfree(swnode->node);
 692         }
 693         ida_destroy(&swnode->child_ids);
 694         kfree(swnode);
 695 }
 696 
 697 static struct kobj_type software_node_type = {
 698         .release = software_node_release,
 699         .sysfs_ops = &kobj_sysfs_ops,
 700 };
 701 
 702 static struct fwnode_handle *
 703 swnode_register(const struct software_node *node, struct swnode *parent,
 704                 unsigned int allocated)
 705 {
 706         struct swnode *swnode;
 707         int ret;
 708 
 709         swnode = kzalloc(sizeof(*swnode), GFP_KERNEL);
 710         if (!swnode) {
 711                 ret = -ENOMEM;
 712                 goto out_err;
 713         }
 714 
 715         ret = ida_simple_get(parent ? &parent->child_ids : &swnode_root_ids,
 716                              0, 0, GFP_KERNEL);
 717         if (ret < 0) {
 718                 kfree(swnode);
 719                 goto out_err;
 720         }
 721 
 722         swnode->id = ret;
 723         swnode->node = node;
 724         swnode->parent = parent;
 725         swnode->allocated = allocated;
 726         swnode->kobj.kset = swnode_kset;
 727         swnode->fwnode.ops = &software_node_ops;
 728 
 729         ida_init(&swnode->child_ids);
 730         INIT_LIST_HEAD(&swnode->entry);
 731         INIT_LIST_HEAD(&swnode->children);
 732 
 733         if (node->name)
 734                 ret = kobject_init_and_add(&swnode->kobj, &software_node_type,
 735                                            parent ? &parent->kobj : NULL,
 736                                            "%s", node->name);
 737         else
 738                 ret = kobject_init_and_add(&swnode->kobj, &software_node_type,
 739                                            parent ? &parent->kobj : NULL,
 740                                            "node%d", swnode->id);
 741         if (ret) {
 742                 kobject_put(&swnode->kobj);
 743                 return ERR_PTR(ret);
 744         }
 745 
 746         if (parent)
 747                 list_add_tail(&swnode->entry, &parent->children);
 748 
 749         kobject_uevent(&swnode->kobj, KOBJ_ADD);
 750         return &swnode->fwnode;
 751 
 752 out_err:
 753         if (allocated)
 754                 property_entries_free(node->properties);
 755         return ERR_PTR(ret);
 756 }
 757 
 758 /**
 759  * software_node_register_nodes - Register an array of software nodes
 760  * @nodes: Zero terminated array of software nodes to be registered
 761  *
 762  * Register multiple software nodes at once.
 763  */
 764 int software_node_register_nodes(const struct software_node *nodes)
 765 {
 766         int ret;
 767         int i;
 768 
 769         for (i = 0; nodes[i].name; i++) {
 770                 ret = software_node_register(&nodes[i]);
 771                 if (ret) {
 772                         software_node_unregister_nodes(nodes);
 773                         return ret;
 774                 }
 775         }
 776 
 777         return 0;
 778 }
 779 EXPORT_SYMBOL_GPL(software_node_register_nodes);
 780 
 781 /**
 782  * software_node_unregister_nodes - Unregister an array of software nodes
 783  * @nodes: Zero terminated array of software nodes to be unregistered
 784  *
 785  * Unregister multiple software nodes at once.
 786  */
 787 void software_node_unregister_nodes(const struct software_node *nodes)
 788 {
 789         struct swnode *swnode;
 790         int i;
 791 
 792         for (i = 0; nodes[i].name; i++) {
 793                 swnode = software_node_to_swnode(&nodes[i]);
 794                 if (swnode)
 795                         fwnode_remove_software_node(&swnode->fwnode);
 796         }
 797 }
 798 EXPORT_SYMBOL_GPL(software_node_unregister_nodes);
 799 
 800 /**
 801  * software_node_register - Register static software node
 802  * @node: The software node to be registered
 803  */
 804 int software_node_register(const struct software_node *node)
 805 {
 806         struct swnode *parent = software_node_to_swnode(node->parent);
 807 
 808         if (software_node_to_swnode(node))
 809                 return -EEXIST;
 810 
 811         return PTR_ERR_OR_ZERO(swnode_register(node, parent, 0));
 812 }
 813 EXPORT_SYMBOL_GPL(software_node_register);
 814 
 815 struct fwnode_handle *
 816 fwnode_create_software_node(const struct property_entry *properties,
 817                             const struct fwnode_handle *parent)
 818 {
 819         struct software_node *node;
 820         struct swnode *p = NULL;
 821         int ret;
 822 
 823         if (parent) {
 824                 if (IS_ERR(parent))
 825                         return ERR_CAST(parent);
 826                 if (!is_software_node(parent))
 827                         return ERR_PTR(-EINVAL);
 828                 p = to_swnode(parent);
 829         }
 830 
 831         node = kzalloc(sizeof(*node), GFP_KERNEL);
 832         if (!node)
 833                 return ERR_PTR(-ENOMEM);
 834 
 835         ret = software_node_register_properties(node, properties);
 836         if (ret) {
 837                 kfree(node);
 838                 return ERR_PTR(ret);
 839         }
 840 
 841         node->parent = p ? p->node : NULL;
 842 
 843         return swnode_register(node, p, 1);
 844 }
 845 EXPORT_SYMBOL_GPL(fwnode_create_software_node);
 846 
 847 void fwnode_remove_software_node(struct fwnode_handle *fwnode)
 848 {
 849         struct swnode *swnode = to_swnode(fwnode);
 850 
 851         if (!swnode)
 852                 return;
 853 
 854         kobject_put(&swnode->kobj);
 855 }
 856 EXPORT_SYMBOL_GPL(fwnode_remove_software_node);
 857 
 858 int software_node_notify(struct device *dev, unsigned long action)
 859 {
 860         struct fwnode_handle *fwnode = dev_fwnode(dev);
 861         struct swnode *swnode;
 862         int ret;
 863 
 864         if (!fwnode)
 865                 return 0;
 866 
 867         if (!is_software_node(fwnode))
 868                 fwnode = fwnode->secondary;
 869         if (!is_software_node(fwnode))
 870                 return 0;
 871 
 872         swnode = to_swnode(fwnode);
 873 
 874         switch (action) {
 875         case KOBJ_ADD:
 876                 ret = sysfs_create_link(&dev->kobj, &swnode->kobj,
 877                                         "software_node");
 878                 if (ret)
 879                         break;
 880 
 881                 ret = sysfs_create_link(&swnode->kobj, &dev->kobj,
 882                                         dev_name(dev));
 883                 if (ret) {
 884                         sysfs_remove_link(&dev->kobj, "software_node");
 885                         break;
 886                 }
 887                 kobject_get(&swnode->kobj);
 888                 break;
 889         case KOBJ_REMOVE:
 890                 sysfs_remove_link(&swnode->kobj, dev_name(dev));
 891                 sysfs_remove_link(&dev->kobj, "software_node");
 892                 kobject_put(&swnode->kobj);
 893                 break;
 894         default:
 895                 break;
 896         }
 897 
 898         return 0;
 899 }
 900 
 901 static int __init software_node_init(void)
 902 {
 903         swnode_kset = kset_create_and_add("software_nodes", NULL, kernel_kobj);
 904         if (!swnode_kset)
 905                 return -ENOMEM;
 906         return 0;
 907 }
 908 postcore_initcall(software_node_init);
 909 
 910 static void __exit software_node_exit(void)
 911 {
 912         ida_destroy(&swnode_root_ids);
 913         kset_unregister(swnode_kset);
 914 }
 915 __exitcall(software_node_exit);

/* [<][>][^][v][top][bottom][index][help] */