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(const struct fwnode_handle
*fwnode
)
76 const 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
);
519 software_node_get_name(const struct fwnode_handle
*fwnode
)
521 const struct swnode
*swnode
= to_swnode(fwnode
);
526 return kobject_name(&swnode
->kobj
);
529 static struct fwnode_handle
*
530 software_node_get_parent(const struct fwnode_handle
*fwnode
)
532 struct swnode
*swnode
= to_swnode(fwnode
);
534 if (!swnode
|| !swnode
->parent
)
537 return fwnode_handle_get(&swnode
->parent
->fwnode
);
540 static struct fwnode_handle
*
541 software_node_get_next_child(const struct fwnode_handle
*fwnode
,
542 struct fwnode_handle
*child
)
544 struct swnode
*p
= to_swnode(fwnode
);
545 struct swnode
*c
= to_swnode(child
);
547 if (!p
|| list_empty(&p
->children
) ||
548 (c
&& list_is_last(&c
->entry
, &p
->children
)))
552 c
= list_next_entry(c
, entry
);
554 c
= list_first_entry(&p
->children
, struct swnode
, entry
);
558 static struct fwnode_handle
*
559 software_node_get_named_child_node(const struct fwnode_handle
*fwnode
,
560 const char *childname
)
562 struct swnode
*swnode
= to_swnode(fwnode
);
563 struct swnode
*child
;
565 if (!swnode
|| list_empty(&swnode
->children
))
568 list_for_each_entry(child
, &swnode
->children
, entry
) {
569 if (!strcmp(childname
, kobject_name(&child
->kobj
))) {
570 kobject_get(&child
->kobj
);
571 return &child
->fwnode
;
578 software_node_get_reference_args(const struct fwnode_handle
*fwnode
,
579 const char *propname
, const char *nargs_prop
,
580 unsigned int nargs
, unsigned int index
,
581 struct fwnode_reference_args
*args
)
583 struct swnode
*swnode
= to_swnode(fwnode
);
584 const struct software_node_reference
*ref
;
585 const struct property_entry
*prop
;
586 struct fwnode_handle
*refnode
;
589 if (!swnode
|| !swnode
->node
->references
)
592 for (ref
= swnode
->node
->references
; ref
->name
; ref
++)
593 if (!strcmp(ref
->name
, propname
))
596 if (!ref
->name
|| index
> (ref
->nrefs
- 1))
599 refnode
= software_node_fwnode(ref
->refs
[index
].node
);
604 prop
= property_entry_get(swnode
->node
->properties
, nargs_prop
);
608 nargs
= prop
->value
.u32_data
;
611 if (nargs
> NR_FWNODE_REFERENCE_ARGS
)
614 args
->fwnode
= software_node_get(refnode
);
617 for (i
= 0; i
< nargs
; i
++)
618 args
->args
[i
] = ref
->refs
[index
].args
[i
];
623 static const struct fwnode_operations software_node_ops
= {
624 .get
= software_node_get
,
625 .put
= software_node_put
,
626 .property_present
= software_node_property_present
,
627 .property_read_int_array
= software_node_read_int_array
,
628 .property_read_string_array
= software_node_read_string_array
,
629 .get_name
= software_node_get_name
,
630 .get_parent
= software_node_get_parent
,
631 .get_next_child_node
= software_node_get_next_child
,
632 .get_named_child_node
= software_node_get_named_child_node
,
633 .get_reference_args
= software_node_get_reference_args
636 /* -------------------------------------------------------------------------- */
639 * software_node_find_by_name - Find software node by name
640 * @parent: Parent of the software node
641 * @name: Name of the software node
643 * The function will find a node that is child of @parent and that is named
644 * @name. If no node is found, the function returns NULL.
646 * NOTE: you will need to drop the reference with fwnode_handle_put() after use.
648 const struct software_node
*
649 software_node_find_by_name(const struct software_node
*parent
, const char *name
)
651 struct swnode
*swnode
= NULL
;
657 spin_lock(&swnode_kset
->list_lock
);
659 list_for_each_entry(k
, &swnode_kset
->list
, entry
) {
660 swnode
= kobj_to_swnode(k
);
661 if (parent
== swnode
->node
->parent
&& swnode
->node
->name
&&
662 !strcmp(name
, swnode
->node
->name
)) {
663 kobject_get(&swnode
->kobj
);
669 spin_unlock(&swnode_kset
->list_lock
);
671 return swnode
? swnode
->node
: NULL
;
673 EXPORT_SYMBOL_GPL(software_node_find_by_name
);
676 software_node_register_properties(struct software_node
*node
,
677 const struct property_entry
*properties
)
679 struct property_entry
*props
;
681 props
= property_entries_dup(properties
);
683 return PTR_ERR(props
);
685 node
->properties
= props
;
690 static void software_node_release(struct kobject
*kobj
)
692 struct swnode
*swnode
= kobj_to_swnode(kobj
);
694 if (swnode
->allocated
) {
695 property_entries_free(swnode
->node
->properties
);
698 ida_destroy(&swnode
->child_ids
);
702 static struct kobj_type software_node_type
= {
703 .release
= software_node_release
,
704 .sysfs_ops
= &kobj_sysfs_ops
,
707 static struct fwnode_handle
*
708 swnode_register(const struct software_node
*node
, struct swnode
*parent
,
709 unsigned int allocated
)
711 struct swnode
*swnode
;
714 swnode
= kzalloc(sizeof(*swnode
), GFP_KERNEL
);
720 ret
= ida_simple_get(parent
? &parent
->child_ids
: &swnode_root_ids
,
729 swnode
->parent
= parent
;
730 swnode
->allocated
= allocated
;
731 swnode
->kobj
.kset
= swnode_kset
;
732 swnode
->fwnode
.ops
= &software_node_ops
;
734 ida_init(&swnode
->child_ids
);
735 INIT_LIST_HEAD(&swnode
->entry
);
736 INIT_LIST_HEAD(&swnode
->children
);
739 ret
= kobject_init_and_add(&swnode
->kobj
, &software_node_type
,
740 parent
? &parent
->kobj
: NULL
,
743 ret
= kobject_init_and_add(&swnode
->kobj
, &software_node_type
,
744 parent
? &parent
->kobj
: NULL
,
745 "node%d", swnode
->id
);
747 kobject_put(&swnode
->kobj
);
752 list_add_tail(&swnode
->entry
, &parent
->children
);
754 kobject_uevent(&swnode
->kobj
, KOBJ_ADD
);
755 return &swnode
->fwnode
;
759 property_entries_free(node
->properties
);
764 * software_node_register_nodes - Register an array of software nodes
765 * @nodes: Zero terminated array of software nodes to be registered
767 * Register multiple software nodes at once.
769 int software_node_register_nodes(const struct software_node
*nodes
)
774 for (i
= 0; nodes
[i
].name
; i
++) {
775 ret
= software_node_register(&nodes
[i
]);
777 software_node_unregister_nodes(nodes
);
784 EXPORT_SYMBOL_GPL(software_node_register_nodes
);
787 * software_node_unregister_nodes - Unregister an array of software nodes
788 * @nodes: Zero terminated array of software nodes to be unregistered
790 * Unregister multiple software nodes at once.
792 void software_node_unregister_nodes(const struct software_node
*nodes
)
794 struct swnode
*swnode
;
797 for (i
= 0; nodes
[i
].name
; i
++) {
798 swnode
= software_node_to_swnode(&nodes
[i
]);
800 fwnode_remove_software_node(&swnode
->fwnode
);
803 EXPORT_SYMBOL_GPL(software_node_unregister_nodes
);
806 * software_node_register - Register static software node
807 * @node: The software node to be registered
809 int software_node_register(const struct software_node
*node
)
811 struct swnode
*parent
= software_node_to_swnode(node
->parent
);
813 if (software_node_to_swnode(node
))
816 return PTR_ERR_OR_ZERO(swnode_register(node
, parent
, 0));
818 EXPORT_SYMBOL_GPL(software_node_register
);
820 struct fwnode_handle
*
821 fwnode_create_software_node(const struct property_entry
*properties
,
822 const struct fwnode_handle
*parent
)
824 struct software_node
*node
;
825 struct swnode
*p
= NULL
;
830 return ERR_CAST(parent
);
831 if (!is_software_node(parent
))
832 return ERR_PTR(-EINVAL
);
833 p
= to_swnode(parent
);
836 node
= kzalloc(sizeof(*node
), GFP_KERNEL
);
838 return ERR_PTR(-ENOMEM
);
840 ret
= software_node_register_properties(node
, properties
);
846 node
->parent
= p
? p
->node
: NULL
;
848 return swnode_register(node
, p
, 1);
850 EXPORT_SYMBOL_GPL(fwnode_create_software_node
);
852 void fwnode_remove_software_node(struct fwnode_handle
*fwnode
)
854 struct swnode
*swnode
= to_swnode(fwnode
);
859 if (swnode
->parent
) {
860 ida_simple_remove(&swnode
->parent
->child_ids
, swnode
->id
);
861 list_del(&swnode
->entry
);
863 ida_simple_remove(&swnode_root_ids
, swnode
->id
);
866 kobject_put(&swnode
->kobj
);
868 EXPORT_SYMBOL_GPL(fwnode_remove_software_node
);
870 int software_node_notify(struct device
*dev
, unsigned long action
)
872 struct fwnode_handle
*fwnode
= dev_fwnode(dev
);
873 struct swnode
*swnode
;
879 if (!is_software_node(fwnode
))
880 fwnode
= fwnode
->secondary
;
881 if (!is_software_node(fwnode
))
884 swnode
= to_swnode(fwnode
);
888 ret
= sysfs_create_link(&dev
->kobj
, &swnode
->kobj
,
893 ret
= sysfs_create_link(&swnode
->kobj
, &dev
->kobj
,
896 sysfs_remove_link(&dev
->kobj
, "software_node");
899 kobject_get(&swnode
->kobj
);
902 sysfs_remove_link(&swnode
->kobj
, dev_name(dev
));
903 sysfs_remove_link(&dev
->kobj
, "software_node");
904 kobject_put(&swnode
->kobj
);
913 static int __init
software_node_init(void)
915 swnode_kset
= kset_create_and_add("software_nodes", NULL
, kernel_kobj
);
920 postcore_initcall(software_node_init
);
922 static void __exit
software_node_exit(void)
924 ida_destroy(&swnode_root_ids
);
925 kset_unregister(swnode_kset
);
927 __exitcall(software_node_exit
);