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
))
106 static const void *property_get_pointer(const struct property_entry
*prop
)
111 return prop
->is_inline
? &prop
->value
: prop
->pointer
;
114 static const void *property_entry_find(const struct property_entry
*props
,
115 const char *propname
, size_t length
)
117 const struct property_entry
*prop
;
120 prop
= property_entry_get(props
, propname
);
122 return ERR_PTR(-EINVAL
);
123 pointer
= property_get_pointer(prop
);
125 return ERR_PTR(-ENODATA
);
126 if (length
> prop
->length
)
127 return ERR_PTR(-EOVERFLOW
);
132 property_entry_count_elems_of_size(const struct property_entry
*props
,
133 const char *propname
, size_t length
)
135 const struct property_entry
*prop
;
137 prop
= property_entry_get(props
, propname
);
141 return prop
->length
/ length
;
144 static int property_entry_read_int_array(const struct property_entry
*props
,
146 unsigned int elem_size
, void *val
,
153 return property_entry_count_elems_of_size(props
, name
,
156 if (!is_power_of_2(elem_size
) || elem_size
> sizeof(u64
))
159 length
= nval
* elem_size
;
161 pointer
= property_entry_find(props
, name
, length
);
163 return PTR_ERR(pointer
);
165 memcpy(val
, pointer
, length
);
169 static int property_entry_read_string_array(const struct property_entry
*props
,
170 const char *propname
,
171 const char **strings
, size_t nval
)
177 /* Find out the array length. */
178 array_len
= property_entry_count_elems_of_size(props
, propname
,
179 sizeof(const char *));
183 /* Return how many there are if strings is NULL. */
187 array_len
= min_t(size_t, nval
, array_len
);
188 length
= array_len
* sizeof(*strings
);
190 pointer
= property_entry_find(props
, propname
, length
);
192 return PTR_ERR(pointer
);
194 memcpy(strings
, pointer
, length
);
199 static void property_entry_free_data(const struct property_entry
*p
)
201 const char * const *src_str
;
204 if (p
->type
== DEV_PROP_STRING
) {
205 src_str
= property_get_pointer(p
);
206 nval
= p
->length
/ sizeof(*src_str
);
207 for (i
= 0; i
< nval
; i
++)
217 static bool property_copy_string_array(const char **dst_ptr
,
218 const char * const *src_ptr
,
223 for (i
= 0; i
< nval
; i
++) {
224 dst_ptr
[i
] = kstrdup(src_ptr
[i
], GFP_KERNEL
);
225 if (!dst_ptr
[i
] && src_ptr
[i
]) {
235 static int property_entry_copy_data(struct property_entry
*dst
,
236 const struct property_entry
*src
)
238 const void *pointer
= property_get_pointer(src
);
243 * Properties with no data should not be marked as stored
246 if (!src
->is_inline
&& !src
->length
)
250 * Reference properties are never stored inline as
253 if (src
->type
== DEV_PROP_REF
&& src
->is_inline
)
256 if (src
->length
<= sizeof(dst
->value
)) {
257 dst_ptr
= &dst
->value
;
258 dst
->is_inline
= true;
260 dst_ptr
= kmalloc(src
->length
, GFP_KERNEL
);
263 dst
->pointer
= dst_ptr
;
266 if (src
->type
== DEV_PROP_STRING
) {
267 nval
= src
->length
/ sizeof(const char *);
268 if (!property_copy_string_array(dst_ptr
, pointer
, nval
)) {
274 memcpy(dst_ptr
, pointer
, src
->length
);
277 dst
->length
= src
->length
;
278 dst
->type
= src
->type
;
279 dst
->name
= kstrdup(src
->name
, GFP_KERNEL
);
281 property_entry_free_data(dst
);
289 * property_entries_dup - duplicate array of properties
290 * @properties: array of properties to copy
292 * This function creates a deep copy of the given NULL-terminated array
293 * of property entries.
295 struct property_entry
*
296 property_entries_dup(const struct property_entry
*properties
)
298 struct property_entry
*p
;
305 while (properties
[n
].name
)
308 p
= kcalloc(n
+ 1, sizeof(*p
), GFP_KERNEL
);
310 return ERR_PTR(-ENOMEM
);
312 for (i
= 0; i
< n
; i
++) {
313 ret
= property_entry_copy_data(&p
[i
], &properties
[i
]);
316 property_entry_free_data(&p
[i
]);
324 EXPORT_SYMBOL_GPL(property_entries_dup
);
327 * property_entries_free - free previously allocated array of properties
328 * @properties: array of properties to destroy
330 * This function frees given NULL-terminated array of property entries,
331 * along with their data.
333 void property_entries_free(const struct property_entry
*properties
)
335 const struct property_entry
*p
;
340 for (p
= properties
; p
->name
; p
++)
341 property_entry_free_data(p
);
345 EXPORT_SYMBOL_GPL(property_entries_free
);
347 /* -------------------------------------------------------------------------- */
348 /* fwnode operations */
350 static struct fwnode_handle
*software_node_get(struct fwnode_handle
*fwnode
)
352 struct swnode
*swnode
= to_swnode(fwnode
);
354 kobject_get(&swnode
->kobj
);
356 return &swnode
->fwnode
;
359 static void software_node_put(struct fwnode_handle
*fwnode
)
361 struct swnode
*swnode
= to_swnode(fwnode
);
363 kobject_put(&swnode
->kobj
);
366 static bool software_node_property_present(const struct fwnode_handle
*fwnode
,
367 const char *propname
)
369 struct swnode
*swnode
= to_swnode(fwnode
);
371 return !!property_entry_get(swnode
->node
->properties
, propname
);
374 static int software_node_read_int_array(const struct fwnode_handle
*fwnode
,
375 const char *propname
,
376 unsigned int elem_size
, void *val
,
379 struct swnode
*swnode
= to_swnode(fwnode
);
381 return property_entry_read_int_array(swnode
->node
->properties
, propname
,
382 elem_size
, val
, nval
);
385 static int software_node_read_string_array(const struct fwnode_handle
*fwnode
,
386 const char *propname
,
387 const char **val
, size_t nval
)
389 struct swnode
*swnode
= to_swnode(fwnode
);
391 return property_entry_read_string_array(swnode
->node
->properties
,
392 propname
, val
, nval
);
396 software_node_get_name(const struct fwnode_handle
*fwnode
)
398 const struct swnode
*swnode
= to_swnode(fwnode
);
403 return kobject_name(&swnode
->kobj
);
407 software_node_get_name_prefix(const struct fwnode_handle
*fwnode
)
409 struct fwnode_handle
*parent
;
412 parent
= fwnode_get_parent(fwnode
);
416 /* Figure out the prefix from the parents. */
417 while (is_software_node(parent
))
418 parent
= fwnode_get_next_parent(parent
);
420 prefix
= fwnode_get_name_prefix(parent
);
421 fwnode_handle_put(parent
);
423 /* Guess something if prefix was NULL. */
424 return prefix
?: "/";
427 static struct fwnode_handle
*
428 software_node_get_parent(const struct fwnode_handle
*fwnode
)
430 struct swnode
*swnode
= to_swnode(fwnode
);
432 if (!swnode
|| !swnode
->parent
)
435 return fwnode_handle_get(&swnode
->parent
->fwnode
);
438 static struct fwnode_handle
*
439 software_node_get_next_child(const struct fwnode_handle
*fwnode
,
440 struct fwnode_handle
*child
)
442 struct swnode
*p
= to_swnode(fwnode
);
443 struct swnode
*c
= to_swnode(child
);
445 if (!p
|| list_empty(&p
->children
) ||
446 (c
&& list_is_last(&c
->entry
, &p
->children
)))
450 c
= list_next_entry(c
, entry
);
452 c
= list_first_entry(&p
->children
, struct swnode
, entry
);
456 static struct fwnode_handle
*
457 software_node_get_named_child_node(const struct fwnode_handle
*fwnode
,
458 const char *childname
)
460 struct swnode
*swnode
= to_swnode(fwnode
);
461 struct swnode
*child
;
463 if (!swnode
|| list_empty(&swnode
->children
))
466 list_for_each_entry(child
, &swnode
->children
, entry
) {
467 if (!strcmp(childname
, kobject_name(&child
->kobj
))) {
468 kobject_get(&child
->kobj
);
469 return &child
->fwnode
;
476 software_node_get_reference_args(const struct fwnode_handle
*fwnode
,
477 const char *propname
, const char *nargs_prop
,
478 unsigned int nargs
, unsigned int index
,
479 struct fwnode_reference_args
*args
)
481 struct swnode
*swnode
= to_swnode(fwnode
);
482 const struct software_node_ref_args
*ref_array
;
483 const struct software_node_ref_args
*ref
;
484 const struct property_entry
*prop
;
485 struct fwnode_handle
*refnode
;
493 prop
= property_entry_get(swnode
->node
->properties
, propname
);
497 if (prop
->type
!= DEV_PROP_REF
)
501 * We expect that references are never stored inline, even
502 * single ones, as they are too big.
507 if (index
* sizeof(*ref
) >= prop
->length
)
510 ref_array
= prop
->pointer
;
511 ref
= &ref_array
[index
];
513 refnode
= software_node_fwnode(ref
->node
);
518 error
= property_entry_read_int_array(swnode
->node
->properties
,
519 nargs_prop
, sizeof(u32
),
524 nargs
= nargs_prop_val
;
527 if (nargs
> NR_FWNODE_REFERENCE_ARGS
)
530 args
->fwnode
= software_node_get(refnode
);
533 for (i
= 0; i
< nargs
; i
++)
534 args
->args
[i
] = ref
->args
[i
];
539 static const struct fwnode_operations software_node_ops
= {
540 .get
= software_node_get
,
541 .put
= software_node_put
,
542 .property_present
= software_node_property_present
,
543 .property_read_int_array
= software_node_read_int_array
,
544 .property_read_string_array
= software_node_read_string_array
,
545 .get_name
= software_node_get_name
,
546 .get_name_prefix
= software_node_get_name_prefix
,
547 .get_parent
= software_node_get_parent
,
548 .get_next_child_node
= software_node_get_next_child
,
549 .get_named_child_node
= software_node_get_named_child_node
,
550 .get_reference_args
= software_node_get_reference_args
553 /* -------------------------------------------------------------------------- */
556 * software_node_find_by_name - Find software node by name
557 * @parent: Parent of the software node
558 * @name: Name of the software node
560 * The function will find a node that is child of @parent and that is named
561 * @name. If no node is found, the function returns NULL.
563 * NOTE: you will need to drop the reference with fwnode_handle_put() after use.
565 const struct software_node
*
566 software_node_find_by_name(const struct software_node
*parent
, const char *name
)
568 struct swnode
*swnode
= NULL
;
574 spin_lock(&swnode_kset
->list_lock
);
576 list_for_each_entry(k
, &swnode_kset
->list
, entry
) {
577 swnode
= kobj_to_swnode(k
);
578 if (parent
== swnode
->node
->parent
&& swnode
->node
->name
&&
579 !strcmp(name
, swnode
->node
->name
)) {
580 kobject_get(&swnode
->kobj
);
586 spin_unlock(&swnode_kset
->list_lock
);
588 return swnode
? swnode
->node
: NULL
;
590 EXPORT_SYMBOL_GPL(software_node_find_by_name
);
593 software_node_register_properties(struct software_node
*node
,
594 const struct property_entry
*properties
)
596 struct property_entry
*props
;
598 props
= property_entries_dup(properties
);
600 return PTR_ERR(props
);
602 node
->properties
= props
;
607 static void software_node_release(struct kobject
*kobj
)
609 struct swnode
*swnode
= kobj_to_swnode(kobj
);
611 if (swnode
->parent
) {
612 ida_simple_remove(&swnode
->parent
->child_ids
, swnode
->id
);
613 list_del(&swnode
->entry
);
615 ida_simple_remove(&swnode_root_ids
, swnode
->id
);
618 if (swnode
->allocated
) {
619 property_entries_free(swnode
->node
->properties
);
622 ida_destroy(&swnode
->child_ids
);
626 static struct kobj_type software_node_type
= {
627 .release
= software_node_release
,
628 .sysfs_ops
= &kobj_sysfs_ops
,
631 static struct fwnode_handle
*
632 swnode_register(const struct software_node
*node
, struct swnode
*parent
,
633 unsigned int allocated
)
635 struct swnode
*swnode
;
638 swnode
= kzalloc(sizeof(*swnode
), GFP_KERNEL
);
644 ret
= ida_simple_get(parent
? &parent
->child_ids
: &swnode_root_ids
,
653 swnode
->parent
= parent
;
654 swnode
->allocated
= allocated
;
655 swnode
->kobj
.kset
= swnode_kset
;
656 fwnode_init(&swnode
->fwnode
, &software_node_ops
);
658 ida_init(&swnode
->child_ids
);
659 INIT_LIST_HEAD(&swnode
->entry
);
660 INIT_LIST_HEAD(&swnode
->children
);
663 ret
= kobject_init_and_add(&swnode
->kobj
, &software_node_type
,
664 parent
? &parent
->kobj
: NULL
,
667 ret
= kobject_init_and_add(&swnode
->kobj
, &software_node_type
,
668 parent
? &parent
->kobj
: NULL
,
669 "node%d", swnode
->id
);
671 kobject_put(&swnode
->kobj
);
676 list_add_tail(&swnode
->entry
, &parent
->children
);
678 kobject_uevent(&swnode
->kobj
, KOBJ_ADD
);
679 return &swnode
->fwnode
;
683 property_entries_free(node
->properties
);
688 * software_node_register_nodes - Register an array of software nodes
689 * @nodes: Zero terminated array of software nodes to be registered
691 * Register multiple software nodes at once.
693 int software_node_register_nodes(const struct software_node
*nodes
)
698 for (i
= 0; nodes
[i
].name
; i
++) {
699 ret
= software_node_register(&nodes
[i
]);
701 software_node_unregister_nodes(nodes
);
708 EXPORT_SYMBOL_GPL(software_node_register_nodes
);
711 * software_node_unregister_nodes - Unregister an array of software nodes
712 * @nodes: Zero terminated array of software nodes to be unregistered
714 * Unregister multiple software nodes at once.
716 * NOTE: Be careful using this call if the nodes had parent pointers set up in
717 * them before registering. If so, it is wiser to remove the nodes
718 * individually, in the correct order (child before parent) instead of relying
719 * on the sequential order of the list of nodes in the array.
721 void software_node_unregister_nodes(const struct software_node
*nodes
)
725 for (i
= 0; nodes
[i
].name
; i
++)
726 software_node_unregister(&nodes
[i
]);
728 EXPORT_SYMBOL_GPL(software_node_unregister_nodes
);
731 * software_node_register_node_group - Register a group of software nodes
732 * @node_group: NULL terminated array of software node pointers to be registered
734 * Register multiple software nodes at once.
736 int software_node_register_node_group(const struct software_node
**node_group
)
744 for (i
= 0; node_group
[i
]; i
++) {
745 ret
= software_node_register(node_group
[i
]);
747 software_node_unregister_node_group(node_group
);
754 EXPORT_SYMBOL_GPL(software_node_register_node_group
);
757 * software_node_unregister_node_group - Unregister a group of software nodes
758 * @node_group: NULL terminated array of software node pointers to be unregistered
760 * Unregister multiple software nodes at once.
762 void software_node_unregister_node_group(const struct software_node
**node_group
)
769 for (i
= 0; node_group
[i
]; i
++)
770 software_node_unregister(node_group
[i
]);
772 EXPORT_SYMBOL_GPL(software_node_unregister_node_group
);
775 * software_node_register - Register static software node
776 * @node: The software node to be registered
778 int software_node_register(const struct software_node
*node
)
780 struct swnode
*parent
= software_node_to_swnode(node
->parent
);
782 if (software_node_to_swnode(node
))
785 return PTR_ERR_OR_ZERO(swnode_register(node
, parent
, 0));
787 EXPORT_SYMBOL_GPL(software_node_register
);
790 * software_node_unregister - Unregister static software node
791 * @node: The software node to be unregistered
793 void software_node_unregister(const struct software_node
*node
)
795 struct swnode
*swnode
;
797 swnode
= software_node_to_swnode(node
);
799 fwnode_remove_software_node(&swnode
->fwnode
);
801 EXPORT_SYMBOL_GPL(software_node_unregister
);
803 struct fwnode_handle
*
804 fwnode_create_software_node(const struct property_entry
*properties
,
805 const struct fwnode_handle
*parent
)
807 struct software_node
*node
;
808 struct swnode
*p
= NULL
;
813 return ERR_CAST(parent
);
814 if (!is_software_node(parent
))
815 return ERR_PTR(-EINVAL
);
816 p
= to_swnode(parent
);
819 node
= kzalloc(sizeof(*node
), GFP_KERNEL
);
821 return ERR_PTR(-ENOMEM
);
823 ret
= software_node_register_properties(node
, properties
);
829 node
->parent
= p
? p
->node
: NULL
;
831 return swnode_register(node
, p
, 1);
833 EXPORT_SYMBOL_GPL(fwnode_create_software_node
);
835 void fwnode_remove_software_node(struct fwnode_handle
*fwnode
)
837 struct swnode
*swnode
= to_swnode(fwnode
);
842 kobject_put(&swnode
->kobj
);
844 EXPORT_SYMBOL_GPL(fwnode_remove_software_node
);
846 int software_node_notify(struct device
*dev
, unsigned long action
)
848 struct fwnode_handle
*fwnode
= dev_fwnode(dev
);
849 struct swnode
*swnode
;
855 if (!is_software_node(fwnode
))
856 fwnode
= fwnode
->secondary
;
857 if (!is_software_node(fwnode
))
860 swnode
= to_swnode(fwnode
);
864 ret
= sysfs_create_link(&dev
->kobj
, &swnode
->kobj
,
869 ret
= sysfs_create_link(&swnode
->kobj
, &dev
->kobj
,
872 sysfs_remove_link(&dev
->kobj
, "software_node");
875 kobject_get(&swnode
->kobj
);
878 sysfs_remove_link(&swnode
->kobj
, dev_name(dev
));
879 sysfs_remove_link(&dev
->kobj
, "software_node");
880 kobject_put(&swnode
->kobj
);
889 static int __init
software_node_init(void)
891 swnode_kset
= kset_create_and_add("software_nodes", NULL
, kernel_kobj
);
896 postcore_initcall(software_node_init
);
898 static void __exit
software_node_exit(void)
900 ida_destroy(&swnode_root_ids
);
901 kset_unregister(swnode_kset
);
903 __exitcall(software_node_exit
);