1 // SPDX-License-Identifier: GPL-2.0
3 * Software nodes for the firmware node framework.
5 * Copyright (C) 2018, Intel Corporation
6 * Author: Heikki Krogerus <heikki.krogerus@linux.intel.com>
9 #include <linux/device.h>
10 #include <linux/kernel.h>
11 #include <linux/property.h>
12 #include <linux/slab.h>
17 struct fwnode_handle fwnode
;
18 const struct software_node
*node
;
22 struct list_head entry
;
23 struct list_head children
;
24 struct swnode
*parent
;
26 unsigned int allocated
:1;
29 static DEFINE_IDA(swnode_root_ids
);
30 static struct kset
*swnode_kset
;
32 #define kobj_to_swnode(_kobj_) container_of(_kobj_, struct swnode, kobj)
34 static const struct fwnode_operations software_node_ops
;
36 bool is_software_node(const struct fwnode_handle
*fwnode
)
38 return !IS_ERR_OR_NULL(fwnode
) && fwnode
->ops
== &software_node_ops
;
40 EXPORT_SYMBOL_GPL(is_software_node
);
42 #define to_swnode(__fwnode) \
44 typeof(__fwnode) __to_swnode_fwnode = __fwnode; \
46 is_software_node(__to_swnode_fwnode) ? \
47 container_of(__to_swnode_fwnode, \
48 struct swnode, fwnode) : NULL; \
51 static struct swnode
*
52 software_node_to_swnode(const struct software_node
*node
)
54 struct swnode
*swnode
= NULL
;
60 spin_lock(&swnode_kset
->list_lock
);
62 list_for_each_entry(k
, &swnode_kset
->list
, entry
) {
63 swnode
= kobj_to_swnode(k
);
64 if (swnode
->node
== node
)
69 spin_unlock(&swnode_kset
->list_lock
);
74 const struct software_node
*to_software_node(struct fwnode_handle
*fwnode
)
76 struct swnode
*swnode
= to_swnode(fwnode
);
78 return swnode
? swnode
->node
: NULL
;
80 EXPORT_SYMBOL_GPL(to_software_node
);
82 struct fwnode_handle
*software_node_fwnode(const struct software_node
*node
)
84 struct swnode
*swnode
= software_node_to_swnode(node
);
86 return swnode
? &swnode
->fwnode
: NULL
;
88 EXPORT_SYMBOL_GPL(software_node_fwnode
);
90 /* -------------------------------------------------------------------------- */
91 /* property_entry processing */
93 static const struct property_entry
*
94 property_entry_get(const struct property_entry
*prop
, const char *name
)
99 for (; prop
->name
; prop
++)
100 if (!strcmp(name
, prop
->name
))
107 property_set_pointer(struct property_entry
*prop
, const void *pointer
)
109 switch (prop
->type
) {
112 prop
->pointer
.u8_data
= pointer
;
114 prop
->value
.u8_data
= *((u8
*)pointer
);
118 prop
->pointer
.u16_data
= pointer
;
120 prop
->value
.u16_data
= *((u16
*)pointer
);
124 prop
->pointer
.u32_data
= pointer
;
126 prop
->value
.u32_data
= *((u32
*)pointer
);
130 prop
->pointer
.u64_data
= pointer
;
132 prop
->value
.u64_data
= *((u64
*)pointer
);
134 case DEV_PROP_STRING
:
136 prop
->pointer
.str
= pointer
;
138 prop
->value
.str
= pointer
;
145 static const void *property_get_pointer(const struct property_entry
*prop
)
147 switch (prop
->type
) {
150 return prop
->pointer
.u8_data
;
151 return &prop
->value
.u8_data
;
154 return prop
->pointer
.u16_data
;
155 return &prop
->value
.u16_data
;
158 return prop
->pointer
.u32_data
;
159 return &prop
->value
.u32_data
;
162 return prop
->pointer
.u64_data
;
163 return &prop
->value
.u64_data
;
164 case DEV_PROP_STRING
:
166 return prop
->pointer
.str
;
167 return &prop
->value
.str
;
173 static const void *property_entry_find(const struct property_entry
*props
,
174 const char *propname
, size_t length
)
176 const struct property_entry
*prop
;
179 prop
= property_entry_get(props
, propname
);
181 return ERR_PTR(-EINVAL
);
182 pointer
= property_get_pointer(prop
);
184 return ERR_PTR(-ENODATA
);
185 if (length
> prop
->length
)
186 return ERR_PTR(-EOVERFLOW
);
190 static int property_entry_read_u8_array(const struct property_entry
*props
,
191 const char *propname
,
192 u8
*values
, size_t nval
)
195 size_t length
= nval
* sizeof(*values
);
197 pointer
= property_entry_find(props
, propname
, length
);
199 return PTR_ERR(pointer
);
201 memcpy(values
, pointer
, length
);
205 static int property_entry_read_u16_array(const struct property_entry
*props
,
206 const char *propname
,
207 u16
*values
, size_t nval
)
210 size_t length
= nval
* sizeof(*values
);
212 pointer
= property_entry_find(props
, propname
, length
);
214 return PTR_ERR(pointer
);
216 memcpy(values
, pointer
, length
);
220 static int property_entry_read_u32_array(const struct property_entry
*props
,
221 const char *propname
,
222 u32
*values
, size_t nval
)
225 size_t length
= nval
* sizeof(*values
);
227 pointer
= property_entry_find(props
, propname
, length
);
229 return PTR_ERR(pointer
);
231 memcpy(values
, pointer
, length
);
235 static int property_entry_read_u64_array(const struct property_entry
*props
,
236 const char *propname
,
237 u64
*values
, size_t nval
)
240 size_t length
= nval
* sizeof(*values
);
242 pointer
= property_entry_find(props
, propname
, length
);
244 return PTR_ERR(pointer
);
246 memcpy(values
, pointer
, length
);
251 property_entry_count_elems_of_size(const struct property_entry
*props
,
252 const char *propname
, size_t length
)
254 const struct property_entry
*prop
;
256 prop
= property_entry_get(props
, propname
);
260 return prop
->length
/ length
;
263 static int property_entry_read_int_array(const struct property_entry
*props
,
265 unsigned int elem_size
, void *val
,
269 return property_entry_count_elems_of_size(props
, name
,
273 return property_entry_read_u8_array(props
, name
, val
, nval
);
275 return property_entry_read_u16_array(props
, name
, val
, nval
);
277 return property_entry_read_u32_array(props
, name
, val
, nval
);
279 return property_entry_read_u64_array(props
, name
, val
, nval
);
285 static int property_entry_read_string_array(const struct property_entry
*props
,
286 const char *propname
,
287 const char **strings
, size_t nval
)
289 const struct property_entry
*prop
;
291 size_t array_len
, length
;
293 /* Find out the array length. */
294 prop
= property_entry_get(props
, propname
);
299 /* Find the length of an array. */
300 array_len
= property_entry_count_elems_of_size(props
, propname
,
301 sizeof(const char *));
303 /* The array length for a non-array string property is 1. */
306 /* Return how many there are if strings is NULL. */
310 array_len
= min(nval
, array_len
);
311 length
= array_len
* sizeof(*strings
);
313 pointer
= property_entry_find(props
, propname
, length
);
315 return PTR_ERR(pointer
);
317 memcpy(strings
, pointer
, length
);
322 static void property_entry_free_data(const struct property_entry
*p
)
324 const void *pointer
= property_get_pointer(p
);
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
]);
334 } else if (p
->type
== DEV_PROP_STRING
) {
340 static int property_copy_string_array(struct property_entry
*dst
,
341 const struct property_entry
*src
)
344 size_t nval
= src
->length
/ sizeof(*d
);
347 d
= kcalloc(nval
, sizeof(*d
), GFP_KERNEL
);
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
]) {
361 dst
->pointer
.str
= d
;
365 static int property_entry_copy_data(struct property_entry
*dst
,
366 const struct property_entry
*src
)
368 const void *pointer
= property_get_pointer(src
);
376 if (src
->type
== DEV_PROP_STRING
) {
377 error
= property_copy_string_array(dst
, src
);
380 new = dst
->pointer
.str
;
382 new = kmemdup(pointer
, src
->length
, GFP_KERNEL
);
386 } else if (src
->type
== DEV_PROP_STRING
) {
387 new = kstrdup(src
->value
.str
, GFP_KERNEL
);
388 if (!new && src
->value
.str
)
394 dst
->length
= src
->length
;
395 dst
->is_array
= src
->is_array
;
396 dst
->type
= src
->type
;
398 property_set_pointer(dst
, new);
400 dst
->name
= kstrdup(src
->name
, GFP_KERNEL
);
407 property_entry_free_data(dst
);
412 * property_entries_dup - duplicate array of properties
413 * @properties: array of properties to copy
415 * This function creates a deep copy of the given NULL-terminated array
416 * of property entries.
418 struct property_entry
*
419 property_entries_dup(const struct property_entry
*properties
)
421 struct property_entry
*p
;
428 while (properties
[n
].name
)
431 p
= kcalloc(n
+ 1, sizeof(*p
), GFP_KERNEL
);
433 return ERR_PTR(-ENOMEM
);
435 for (i
= 0; i
< n
; i
++) {
436 ret
= property_entry_copy_data(&p
[i
], &properties
[i
]);
439 property_entry_free_data(&p
[i
]);
447 EXPORT_SYMBOL_GPL(property_entries_dup
);
450 * property_entries_free - free previously allocated array of properties
451 * @properties: array of properties to destroy
453 * This function frees given NULL-terminated array of property entries,
454 * along with their data.
456 void property_entries_free(const struct property_entry
*properties
)
458 const struct property_entry
*p
;
463 for (p
= properties
; p
->name
; p
++)
464 property_entry_free_data(p
);
468 EXPORT_SYMBOL_GPL(property_entries_free
);
470 /* -------------------------------------------------------------------------- */
471 /* fwnode operations */
473 static struct fwnode_handle
*software_node_get(struct fwnode_handle
*fwnode
)
475 struct swnode
*swnode
= to_swnode(fwnode
);
477 kobject_get(&swnode
->kobj
);
479 return &swnode
->fwnode
;
482 static void software_node_put(struct fwnode_handle
*fwnode
)
484 struct swnode
*swnode
= to_swnode(fwnode
);
486 kobject_put(&swnode
->kobj
);
489 static bool software_node_property_present(const struct fwnode_handle
*fwnode
,
490 const char *propname
)
492 struct swnode
*swnode
= to_swnode(fwnode
);
494 return !!property_entry_get(swnode
->node
->properties
, propname
);
497 static int software_node_read_int_array(const struct fwnode_handle
*fwnode
,
498 const char *propname
,
499 unsigned int elem_size
, void *val
,
502 struct swnode
*swnode
= to_swnode(fwnode
);
504 return property_entry_read_int_array(swnode
->node
->properties
, propname
,
505 elem_size
, val
, nval
);
508 static int software_node_read_string_array(const struct fwnode_handle
*fwnode
,
509 const char *propname
,
510 const char **val
, size_t nval
)
512 struct swnode
*swnode
= to_swnode(fwnode
);
514 return property_entry_read_string_array(swnode
->node
->properties
,
515 propname
, val
, nval
);
518 static struct fwnode_handle
*
519 software_node_get_parent(const struct fwnode_handle
*fwnode
)
521 struct swnode
*swnode
= to_swnode(fwnode
);
523 return swnode
? (swnode
->parent
? &swnode
->parent
->fwnode
: NULL
) : NULL
;
526 static struct fwnode_handle
*
527 software_node_get_next_child(const struct fwnode_handle
*fwnode
,
528 struct fwnode_handle
*child
)
530 struct swnode
*p
= to_swnode(fwnode
);
531 struct swnode
*c
= to_swnode(child
);
533 if (!p
|| list_empty(&p
->children
) ||
534 (c
&& list_is_last(&c
->entry
, &p
->children
)))
538 c
= list_next_entry(c
, entry
);
540 c
= list_first_entry(&p
->children
, struct swnode
, entry
);
544 static struct fwnode_handle
*
545 software_node_get_named_child_node(const struct fwnode_handle
*fwnode
,
546 const char *childname
)
548 struct swnode
*swnode
= to_swnode(fwnode
);
549 struct swnode
*child
;
551 if (!swnode
|| list_empty(&swnode
->children
))
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
;
564 software_node_get_reference_args(const struct fwnode_handle
*fwnode
,
565 const char *propname
, const char *nargs_prop
,
566 unsigned int nargs
, unsigned int index
,
567 struct fwnode_reference_args
*args
)
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
;
575 if (!swnode
|| !swnode
->node
->references
)
578 for (ref
= swnode
->node
->references
; ref
->name
; ref
++)
579 if (!strcmp(ref
->name
, propname
))
582 if (!ref
->name
|| index
> (ref
->nrefs
- 1))
585 refnode
= software_node_fwnode(ref
->refs
[index
].node
);
590 prop
= property_entry_get(swnode
->node
->properties
, nargs_prop
);
594 nargs
= prop
->value
.u32_data
;
597 if (nargs
> NR_FWNODE_REFERENCE_ARGS
)
600 args
->fwnode
= software_node_get(refnode
);
603 for (i
= 0; i
< nargs
; i
++)
604 args
->args
[i
] = ref
->refs
[index
].args
[i
];
609 static const struct fwnode_operations software_node_ops
= {
610 .get
= software_node_get
,
611 .put
= software_node_put
,
612 .property_present
= software_node_property_present
,
613 .property_read_int_array
= software_node_read_int_array
,
614 .property_read_string_array
= software_node_read_string_array
,
615 .get_parent
= software_node_get_parent
,
616 .get_next_child_node
= software_node_get_next_child
,
617 .get_named_child_node
= software_node_get_named_child_node
,
618 .get_reference_args
= software_node_get_reference_args
621 /* -------------------------------------------------------------------------- */
624 * software_node_find_by_name - Find software node by name
625 * @parent: Parent of the software node
626 * @name: Name of the software node
628 * The function will find a node that is child of @parent and that is named
629 * @name. If no node is found, the function returns NULL.
631 * NOTE: you will need to drop the reference with fwnode_handle_put() after use.
633 const struct software_node
*
634 software_node_find_by_name(const struct software_node
*parent
, const char *name
)
636 struct swnode
*swnode
= NULL
;
642 spin_lock(&swnode_kset
->list_lock
);
644 list_for_each_entry(k
, &swnode_kset
->list
, entry
) {
645 swnode
= kobj_to_swnode(k
);
646 if (parent
== swnode
->node
->parent
&& swnode
->node
->name
&&
647 !strcmp(name
, swnode
->node
->name
)) {
648 kobject_get(&swnode
->kobj
);
654 spin_unlock(&swnode_kset
->list_lock
);
656 return swnode
? swnode
->node
: NULL
;
658 EXPORT_SYMBOL_GPL(software_node_find_by_name
);
661 software_node_register_properties(struct software_node
*node
,
662 const struct property_entry
*properties
)
664 struct property_entry
*props
;
666 props
= property_entries_dup(properties
);
668 return PTR_ERR(props
);
670 node
->properties
= props
;
675 static void software_node_release(struct kobject
*kobj
)
677 struct swnode
*swnode
= kobj_to_swnode(kobj
);
679 if (swnode
->allocated
) {
680 property_entries_free(swnode
->node
->properties
);
683 ida_destroy(&swnode
->child_ids
);
687 static struct kobj_type software_node_type
= {
688 .release
= software_node_release
,
689 .sysfs_ops
= &kobj_sysfs_ops
,
692 static struct fwnode_handle
*
693 swnode_register(const struct software_node
*node
, struct swnode
*parent
,
694 unsigned int allocated
)
696 struct swnode
*swnode
;
699 swnode
= kzalloc(sizeof(*swnode
), GFP_KERNEL
);
705 ret
= ida_simple_get(parent
? &parent
->child_ids
: &swnode_root_ids
,
714 swnode
->parent
= parent
;
715 swnode
->allocated
= allocated
;
716 swnode
->kobj
.kset
= swnode_kset
;
717 swnode
->fwnode
.ops
= &software_node_ops
;
719 ida_init(&swnode
->child_ids
);
720 INIT_LIST_HEAD(&swnode
->entry
);
721 INIT_LIST_HEAD(&swnode
->children
);
724 ret
= kobject_init_and_add(&swnode
->kobj
, &software_node_type
,
725 parent
? &parent
->kobj
: NULL
,
728 ret
= kobject_init_and_add(&swnode
->kobj
, &software_node_type
,
729 parent
? &parent
->kobj
: NULL
,
730 "node%d", swnode
->id
);
732 kobject_put(&swnode
->kobj
);
737 list_add_tail(&swnode
->entry
, &parent
->children
);
739 kobject_uevent(&swnode
->kobj
, KOBJ_ADD
);
740 return &swnode
->fwnode
;
744 property_entries_free(node
->properties
);
749 * software_node_register_nodes - Register an array of software nodes
750 * @nodes: Zero terminated array of software nodes to be registered
752 * Register multiple software nodes at once.
754 int software_node_register_nodes(const struct software_node
*nodes
)
759 for (i
= 0; nodes
[i
].name
; i
++) {
760 ret
= software_node_register(&nodes
[i
]);
762 software_node_unregister_nodes(nodes
);
769 EXPORT_SYMBOL_GPL(software_node_register_nodes
);
772 * software_node_unregister_nodes - Unregister an array of software nodes
773 * @nodes: Zero terminated array of software nodes to be unregistered
775 * Unregister multiple software nodes at once.
777 void software_node_unregister_nodes(const struct software_node
*nodes
)
779 struct swnode
*swnode
;
782 for (i
= 0; nodes
[i
].name
; i
++) {
783 swnode
= software_node_to_swnode(&nodes
[i
]);
785 fwnode_remove_software_node(&swnode
->fwnode
);
788 EXPORT_SYMBOL_GPL(software_node_unregister_nodes
);
791 * software_node_register - Register static software node
792 * @node: The software node to be registered
794 int software_node_register(const struct software_node
*node
)
796 struct swnode
*parent
= software_node_to_swnode(node
->parent
);
798 if (software_node_to_swnode(node
))
801 return PTR_ERR_OR_ZERO(swnode_register(node
, parent
, 0));
803 EXPORT_SYMBOL_GPL(software_node_register
);
805 struct fwnode_handle
*
806 fwnode_create_software_node(const struct property_entry
*properties
,
807 const struct fwnode_handle
*parent
)
809 struct software_node
*node
;
810 struct swnode
*p
= NULL
;
815 return ERR_CAST(parent
);
816 if (!is_software_node(parent
))
817 return ERR_PTR(-EINVAL
);
818 p
= to_swnode(parent
);
821 node
= kzalloc(sizeof(*node
), GFP_KERNEL
);
823 return ERR_PTR(-ENOMEM
);
825 ret
= software_node_register_properties(node
, properties
);
831 node
->parent
= p
? p
->node
: NULL
;
833 return swnode_register(node
, p
, 1);
835 EXPORT_SYMBOL_GPL(fwnode_create_software_node
);
837 void fwnode_remove_software_node(struct fwnode_handle
*fwnode
)
839 struct swnode
*swnode
= to_swnode(fwnode
);
844 if (swnode
->parent
) {
845 ida_simple_remove(&swnode
->parent
->child_ids
, swnode
->id
);
846 list_del(&swnode
->entry
);
848 ida_simple_remove(&swnode_root_ids
, swnode
->id
);
851 kobject_put(&swnode
->kobj
);
853 EXPORT_SYMBOL_GPL(fwnode_remove_software_node
);
855 int software_node_notify(struct device
*dev
, unsigned long action
)
857 struct fwnode_handle
*fwnode
= dev_fwnode(dev
);
858 struct swnode
*swnode
;
864 if (!is_software_node(fwnode
))
865 fwnode
= fwnode
->secondary
;
866 if (!is_software_node(fwnode
))
869 swnode
= to_swnode(fwnode
);
873 ret
= sysfs_create_link(&dev
->kobj
, &swnode
->kobj
,
878 ret
= sysfs_create_link(&swnode
->kobj
, &dev
->kobj
,
881 sysfs_remove_link(&dev
->kobj
, "software_node");
884 kobject_get(&swnode
->kobj
);
887 sysfs_remove_link(&swnode
->kobj
, dev_name(dev
));
888 sysfs_remove_link(&dev
->kobj
, "software_node");
889 kobject_put(&swnode
->kobj
);
898 static int __init
software_node_init(void)
900 swnode_kset
= kset_create_and_add("software_nodes", NULL
, kernel_kobj
);
905 postcore_initcall(software_node_init
);
907 static void __exit
software_node_exit(void)
909 ida_destroy(&swnode_root_ids
);
910 kset_unregister(swnode_kset
);
912 __exitcall(software_node_exit
);