xref: /OK3568_Linux_fs/kernel/drivers/base/swnode.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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 
is_software_node(const struct fwnode_handle * fwnode)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 
dev_to_swnode(struct device * dev)51 static inline struct swnode *dev_to_swnode(struct device *dev)
52 {
53 	struct fwnode_handle *fwnode = dev_fwnode(dev);
54 
55 	if (!fwnode)
56 		return NULL;
57 
58 	if (!is_software_node(fwnode))
59 		fwnode = fwnode->secondary;
60 
61 	return to_swnode(fwnode);
62 }
63 
64 static struct swnode *
software_node_to_swnode(const struct software_node * node)65 software_node_to_swnode(const struct software_node *node)
66 {
67 	struct swnode *swnode = NULL;
68 	struct kobject *k;
69 
70 	if (!node)
71 		return NULL;
72 
73 	spin_lock(&swnode_kset->list_lock);
74 
75 	list_for_each_entry(k, &swnode_kset->list, entry) {
76 		swnode = kobj_to_swnode(k);
77 		if (swnode->node == node)
78 			break;
79 		swnode = NULL;
80 	}
81 
82 	spin_unlock(&swnode_kset->list_lock);
83 
84 	return swnode;
85 }
86 
to_software_node(const struct fwnode_handle * fwnode)87 const struct software_node *to_software_node(const struct fwnode_handle *fwnode)
88 {
89 	const struct swnode *swnode = to_swnode(fwnode);
90 
91 	return swnode ? swnode->node : NULL;
92 }
93 EXPORT_SYMBOL_GPL(to_software_node);
94 
software_node_fwnode(const struct software_node * node)95 struct fwnode_handle *software_node_fwnode(const struct software_node *node)
96 {
97 	struct swnode *swnode = software_node_to_swnode(node);
98 
99 	return swnode ? &swnode->fwnode : NULL;
100 }
101 EXPORT_SYMBOL_GPL(software_node_fwnode);
102 
103 /* -------------------------------------------------------------------------- */
104 /* property_entry processing */
105 
106 static const struct property_entry *
property_entry_get(const struct property_entry * prop,const char * name)107 property_entry_get(const struct property_entry *prop, const char *name)
108 {
109 	if (!prop)
110 		return NULL;
111 
112 	for (; prop->name; prop++)
113 		if (!strcmp(name, prop->name))
114 			return prop;
115 
116 	return NULL;
117 }
118 
property_get_pointer(const struct property_entry * prop)119 static const void *property_get_pointer(const struct property_entry *prop)
120 {
121 	if (!prop->length)
122 		return NULL;
123 
124 	return prop->is_inline ? &prop->value : prop->pointer;
125 }
126 
property_entry_find(const struct property_entry * props,const char * propname,size_t length)127 static const void *property_entry_find(const struct property_entry *props,
128 				       const char *propname, size_t length)
129 {
130 	const struct property_entry *prop;
131 	const void *pointer;
132 
133 	prop = property_entry_get(props, propname);
134 	if (!prop)
135 		return ERR_PTR(-EINVAL);
136 	pointer = property_get_pointer(prop);
137 	if (!pointer)
138 		return ERR_PTR(-ENODATA);
139 	if (length > prop->length)
140 		return ERR_PTR(-EOVERFLOW);
141 	return pointer;
142 }
143 
144 static int
property_entry_count_elems_of_size(const struct property_entry * props,const char * propname,size_t length)145 property_entry_count_elems_of_size(const struct property_entry *props,
146 				   const char *propname, size_t length)
147 {
148 	const struct property_entry *prop;
149 
150 	prop = property_entry_get(props, propname);
151 	if (!prop)
152 		return -EINVAL;
153 
154 	return prop->length / length;
155 }
156 
property_entry_read_int_array(const struct property_entry * props,const char * name,unsigned int elem_size,void * val,size_t nval)157 static int property_entry_read_int_array(const struct property_entry *props,
158 					 const char *name,
159 					 unsigned int elem_size, void *val,
160 					 size_t nval)
161 {
162 	const void *pointer;
163 	size_t length;
164 
165 	if (!val)
166 		return property_entry_count_elems_of_size(props, name,
167 							  elem_size);
168 
169 	if (!is_power_of_2(elem_size) || elem_size > sizeof(u64))
170 		return -ENXIO;
171 
172 	length = nval * elem_size;
173 
174 	pointer = property_entry_find(props, name, length);
175 	if (IS_ERR(pointer))
176 		return PTR_ERR(pointer);
177 
178 	memcpy(val, pointer, length);
179 	return 0;
180 }
181 
property_entry_read_string_array(const struct property_entry * props,const char * propname,const char ** strings,size_t nval)182 static int property_entry_read_string_array(const struct property_entry *props,
183 					    const char *propname,
184 					    const char **strings, size_t nval)
185 {
186 	const void *pointer;
187 	size_t length;
188 	int array_len;
189 
190 	/* Find out the array length. */
191 	array_len = property_entry_count_elems_of_size(props, propname,
192 						       sizeof(const char *));
193 	if (array_len < 0)
194 		return array_len;
195 
196 	/* Return how many there are if strings is NULL. */
197 	if (!strings)
198 		return array_len;
199 
200 	array_len = min_t(size_t, nval, array_len);
201 	length = array_len * sizeof(*strings);
202 
203 	pointer = property_entry_find(props, propname, length);
204 	if (IS_ERR(pointer))
205 		return PTR_ERR(pointer);
206 
207 	memcpy(strings, pointer, length);
208 
209 	return array_len;
210 }
211 
property_entry_free_data(const struct property_entry * p)212 static void property_entry_free_data(const struct property_entry *p)
213 {
214 	const char * const *src_str;
215 	size_t i, nval;
216 
217 	if (p->type == DEV_PROP_STRING) {
218 		src_str = property_get_pointer(p);
219 		nval = p->length / sizeof(*src_str);
220 		for (i = 0; i < nval; i++)
221 			kfree(src_str[i]);
222 	}
223 
224 	if (!p->is_inline)
225 		kfree(p->pointer);
226 
227 	kfree(p->name);
228 }
229 
property_copy_string_array(const char ** dst_ptr,const char * const * src_ptr,size_t nval)230 static bool property_copy_string_array(const char **dst_ptr,
231 				       const char * const *src_ptr,
232 				       size_t nval)
233 {
234 	int i;
235 
236 	for (i = 0; i < nval; i++) {
237 		dst_ptr[i] = kstrdup(src_ptr[i], GFP_KERNEL);
238 		if (!dst_ptr[i] && src_ptr[i]) {
239 			while (--i >= 0)
240 				kfree(dst_ptr[i]);
241 			return false;
242 		}
243 	}
244 
245 	return true;
246 }
247 
property_entry_copy_data(struct property_entry * dst,const struct property_entry * src)248 static int property_entry_copy_data(struct property_entry *dst,
249 				    const struct property_entry *src)
250 {
251 	const void *pointer = property_get_pointer(src);
252 	void *dst_ptr;
253 	size_t nval;
254 
255 	/*
256 	 * Properties with no data should not be marked as stored
257 	 * out of line.
258 	 */
259 	if (!src->is_inline && !src->length)
260 		return -ENODATA;
261 
262 	/*
263 	 * Reference properties are never stored inline as
264 	 * they are too big.
265 	 */
266 	if (src->type == DEV_PROP_REF && src->is_inline)
267 		return -EINVAL;
268 
269 	if (src->length <= sizeof(dst->value)) {
270 		dst_ptr = &dst->value;
271 		dst->is_inline = true;
272 	} else {
273 		dst_ptr = kmalloc(src->length, GFP_KERNEL);
274 		if (!dst_ptr)
275 			return -ENOMEM;
276 		dst->pointer = dst_ptr;
277 	}
278 
279 	if (src->type == DEV_PROP_STRING) {
280 		nval = src->length / sizeof(const char *);
281 		if (!property_copy_string_array(dst_ptr, pointer, nval)) {
282 			if (!dst->is_inline)
283 				kfree(dst->pointer);
284 			return -ENOMEM;
285 		}
286 	} else {
287 		memcpy(dst_ptr, pointer, src->length);
288 	}
289 
290 	dst->length = src->length;
291 	dst->type = src->type;
292 	dst->name = kstrdup(src->name, GFP_KERNEL);
293 	if (!dst->name) {
294 		property_entry_free_data(dst);
295 		return -ENOMEM;
296 	}
297 
298 	return 0;
299 }
300 
301 /**
302  * property_entries_dup - duplicate array of properties
303  * @properties: array of properties to copy
304  *
305  * This function creates a deep copy of the given NULL-terminated array
306  * of property entries.
307  */
308 struct property_entry *
property_entries_dup(const struct property_entry * properties)309 property_entries_dup(const struct property_entry *properties)
310 {
311 	struct property_entry *p;
312 	int i, n = 0;
313 	int ret;
314 
315 	if (!properties)
316 		return NULL;
317 
318 	while (properties[n].name)
319 		n++;
320 
321 	p = kcalloc(n + 1, sizeof(*p), GFP_KERNEL);
322 	if (!p)
323 		return ERR_PTR(-ENOMEM);
324 
325 	for (i = 0; i < n; i++) {
326 		ret = property_entry_copy_data(&p[i], &properties[i]);
327 		if (ret) {
328 			while (--i >= 0)
329 				property_entry_free_data(&p[i]);
330 			kfree(p);
331 			return ERR_PTR(ret);
332 		}
333 	}
334 
335 	return p;
336 }
337 EXPORT_SYMBOL_GPL(property_entries_dup);
338 
339 /**
340  * property_entries_free - free previously allocated array of properties
341  * @properties: array of properties to destroy
342  *
343  * This function frees given NULL-terminated array of property entries,
344  * along with their data.
345  */
property_entries_free(const struct property_entry * properties)346 void property_entries_free(const struct property_entry *properties)
347 {
348 	const struct property_entry *p;
349 
350 	if (!properties)
351 		return;
352 
353 	for (p = properties; p->name; p++)
354 		property_entry_free_data(p);
355 
356 	kfree(properties);
357 }
358 EXPORT_SYMBOL_GPL(property_entries_free);
359 
360 /* -------------------------------------------------------------------------- */
361 /* fwnode operations */
362 
software_node_get(struct fwnode_handle * fwnode)363 static struct fwnode_handle *software_node_get(struct fwnode_handle *fwnode)
364 {
365 	struct swnode *swnode = to_swnode(fwnode);
366 
367 	kobject_get(&swnode->kobj);
368 
369 	return &swnode->fwnode;
370 }
371 
software_node_put(struct fwnode_handle * fwnode)372 static void software_node_put(struct fwnode_handle *fwnode)
373 {
374 	struct swnode *swnode = to_swnode(fwnode);
375 
376 	kobject_put(&swnode->kobj);
377 }
378 
software_node_property_present(const struct fwnode_handle * fwnode,const char * propname)379 static bool software_node_property_present(const struct fwnode_handle *fwnode,
380 					   const char *propname)
381 {
382 	struct swnode *swnode = to_swnode(fwnode);
383 
384 	return !!property_entry_get(swnode->node->properties, propname);
385 }
386 
software_node_read_int_array(const struct fwnode_handle * fwnode,const char * propname,unsigned int elem_size,void * val,size_t nval)387 static int software_node_read_int_array(const struct fwnode_handle *fwnode,
388 					const char *propname,
389 					unsigned int elem_size, void *val,
390 					size_t nval)
391 {
392 	struct swnode *swnode = to_swnode(fwnode);
393 
394 	return property_entry_read_int_array(swnode->node->properties, propname,
395 					     elem_size, val, nval);
396 }
397 
software_node_read_string_array(const struct fwnode_handle * fwnode,const char * propname,const char ** val,size_t nval)398 static int software_node_read_string_array(const struct fwnode_handle *fwnode,
399 					   const char *propname,
400 					   const char **val, size_t nval)
401 {
402 	struct swnode *swnode = to_swnode(fwnode);
403 
404 	return property_entry_read_string_array(swnode->node->properties,
405 						propname, val, nval);
406 }
407 
408 static const char *
software_node_get_name(const struct fwnode_handle * fwnode)409 software_node_get_name(const struct fwnode_handle *fwnode)
410 {
411 	const struct swnode *swnode = to_swnode(fwnode);
412 
413 	if (!swnode)
414 		return "(null)";
415 
416 	return kobject_name(&swnode->kobj);
417 }
418 
419 static const char *
software_node_get_name_prefix(const struct fwnode_handle * fwnode)420 software_node_get_name_prefix(const struct fwnode_handle *fwnode)
421 {
422 	struct fwnode_handle *parent;
423 	const char *prefix;
424 
425 	parent = fwnode_get_parent(fwnode);
426 	if (!parent)
427 		return "";
428 
429 	/* Figure out the prefix from the parents. */
430 	while (is_software_node(parent))
431 		parent = fwnode_get_next_parent(parent);
432 
433 	prefix = fwnode_get_name_prefix(parent);
434 	fwnode_handle_put(parent);
435 
436 	/* Guess something if prefix was NULL. */
437 	return prefix ?: "/";
438 }
439 
440 static struct fwnode_handle *
software_node_get_parent(const struct fwnode_handle * fwnode)441 software_node_get_parent(const struct fwnode_handle *fwnode)
442 {
443 	struct swnode *swnode = to_swnode(fwnode);
444 
445 	if (!swnode || !swnode->parent)
446 		return NULL;
447 
448 	return fwnode_handle_get(&swnode->parent->fwnode);
449 }
450 
451 static struct fwnode_handle *
software_node_get_next_child(const struct fwnode_handle * fwnode,struct fwnode_handle * child)452 software_node_get_next_child(const struct fwnode_handle *fwnode,
453 			     struct fwnode_handle *child)
454 {
455 	struct swnode *p = to_swnode(fwnode);
456 	struct swnode *c = to_swnode(child);
457 
458 	if (!p || list_empty(&p->children) ||
459 	    (c && list_is_last(&c->entry, &p->children))) {
460 		fwnode_handle_put(child);
461 		return NULL;
462 	}
463 
464 	if (c)
465 		c = list_next_entry(c, entry);
466 	else
467 		c = list_first_entry(&p->children, struct swnode, entry);
468 
469 	fwnode_handle_put(child);
470 	return fwnode_handle_get(&c->fwnode);
471 }
472 
473 static struct fwnode_handle *
software_node_get_named_child_node(const struct fwnode_handle * fwnode,const char * childname)474 software_node_get_named_child_node(const struct fwnode_handle *fwnode,
475 				   const char *childname)
476 {
477 	struct swnode *swnode = to_swnode(fwnode);
478 	struct swnode *child;
479 
480 	if (!swnode || list_empty(&swnode->children))
481 		return NULL;
482 
483 	list_for_each_entry(child, &swnode->children, entry) {
484 		if (!strcmp(childname, kobject_name(&child->kobj))) {
485 			kobject_get(&child->kobj);
486 			return &child->fwnode;
487 		}
488 	}
489 	return NULL;
490 }
491 
492 static int
software_node_get_reference_args(const struct fwnode_handle * fwnode,const char * propname,const char * nargs_prop,unsigned int nargs,unsigned int index,struct fwnode_reference_args * args)493 software_node_get_reference_args(const struct fwnode_handle *fwnode,
494 				 const char *propname, const char *nargs_prop,
495 				 unsigned int nargs, unsigned int index,
496 				 struct fwnode_reference_args *args)
497 {
498 	struct swnode *swnode = to_swnode(fwnode);
499 	const struct software_node_ref_args *ref_array;
500 	const struct software_node_ref_args *ref;
501 	const struct property_entry *prop;
502 	struct fwnode_handle *refnode;
503 	u32 nargs_prop_val;
504 	int error;
505 	int i;
506 
507 	if (!swnode)
508 		return -ENOENT;
509 
510 	prop = property_entry_get(swnode->node->properties, propname);
511 	if (!prop)
512 		return -ENOENT;
513 
514 	if (prop->type != DEV_PROP_REF)
515 		return -EINVAL;
516 
517 	/*
518 	 * We expect that references are never stored inline, even
519 	 * single ones, as they are too big.
520 	 */
521 	if (prop->is_inline)
522 		return -EINVAL;
523 
524 	if (index * sizeof(*ref) >= prop->length)
525 		return -ENOENT;
526 
527 	ref_array = prop->pointer;
528 	ref = &ref_array[index];
529 
530 	refnode = software_node_fwnode(ref->node);
531 	if (!refnode)
532 		return -ENOENT;
533 
534 	if (nargs_prop) {
535 		error = property_entry_read_int_array(ref->node->properties,
536 						      nargs_prop, sizeof(u32),
537 						      &nargs_prop_val, 1);
538 		if (error)
539 			return error;
540 
541 		nargs = nargs_prop_val;
542 	}
543 
544 	if (nargs > NR_FWNODE_REFERENCE_ARGS)
545 		return -EINVAL;
546 
547 	args->fwnode = software_node_get(refnode);
548 	args->nargs = nargs;
549 
550 	for (i = 0; i < nargs; i++)
551 		args->args[i] = ref->args[i];
552 
553 	return 0;
554 }
555 
556 static const struct fwnode_operations software_node_ops = {
557 	.get = software_node_get,
558 	.put = software_node_put,
559 	.property_present = software_node_property_present,
560 	.property_read_int_array = software_node_read_int_array,
561 	.property_read_string_array = software_node_read_string_array,
562 	.get_name = software_node_get_name,
563 	.get_name_prefix = software_node_get_name_prefix,
564 	.get_parent = software_node_get_parent,
565 	.get_next_child_node = software_node_get_next_child,
566 	.get_named_child_node = software_node_get_named_child_node,
567 	.get_reference_args = software_node_get_reference_args
568 };
569 
570 /* -------------------------------------------------------------------------- */
571 
572 /**
573  * software_node_find_by_name - Find software node by name
574  * @parent: Parent of the software node
575  * @name: Name of the software node
576  *
577  * The function will find a node that is child of @parent and that is named
578  * @name. If no node is found, the function returns NULL.
579  *
580  * NOTE: you will need to drop the reference with fwnode_handle_put() after use.
581  */
582 const struct software_node *
software_node_find_by_name(const struct software_node * parent,const char * name)583 software_node_find_by_name(const struct software_node *parent, const char *name)
584 {
585 	struct swnode *swnode = NULL;
586 	struct kobject *k;
587 
588 	if (!name)
589 		return NULL;
590 
591 	spin_lock(&swnode_kset->list_lock);
592 
593 	list_for_each_entry(k, &swnode_kset->list, entry) {
594 		swnode = kobj_to_swnode(k);
595 		if (parent == swnode->node->parent && swnode->node->name &&
596 		    !strcmp(name, swnode->node->name)) {
597 			kobject_get(&swnode->kobj);
598 			break;
599 		}
600 		swnode = NULL;
601 	}
602 
603 	spin_unlock(&swnode_kset->list_lock);
604 
605 	return swnode ? swnode->node : NULL;
606 }
607 EXPORT_SYMBOL_GPL(software_node_find_by_name);
608 
609 static int
software_node_register_properties(struct software_node * node,const struct property_entry * properties)610 software_node_register_properties(struct software_node *node,
611 				  const struct property_entry *properties)
612 {
613 	struct property_entry *props;
614 
615 	props = property_entries_dup(properties);
616 	if (IS_ERR(props))
617 		return PTR_ERR(props);
618 
619 	node->properties = props;
620 
621 	return 0;
622 }
623 
software_node_release(struct kobject * kobj)624 static void software_node_release(struct kobject *kobj)
625 {
626 	struct swnode *swnode = kobj_to_swnode(kobj);
627 
628 	if (swnode->parent) {
629 		ida_simple_remove(&swnode->parent->child_ids, swnode->id);
630 		list_del(&swnode->entry);
631 	} else {
632 		ida_simple_remove(&swnode_root_ids, swnode->id);
633 	}
634 
635 	if (swnode->allocated) {
636 		property_entries_free(swnode->node->properties);
637 		kfree(swnode->node);
638 	}
639 	ida_destroy(&swnode->child_ids);
640 	kfree(swnode);
641 }
642 
643 static struct kobj_type software_node_type = {
644 	.release = software_node_release,
645 	.sysfs_ops = &kobj_sysfs_ops,
646 };
647 
648 static struct fwnode_handle *
swnode_register(const struct software_node * node,struct swnode * parent,unsigned int allocated)649 swnode_register(const struct software_node *node, struct swnode *parent,
650 		unsigned int allocated)
651 {
652 	struct swnode *swnode;
653 	int ret;
654 
655 	swnode = kzalloc(sizeof(*swnode), GFP_KERNEL);
656 	if (!swnode) {
657 		ret = -ENOMEM;
658 		goto out_err;
659 	}
660 
661 	ret = ida_simple_get(parent ? &parent->child_ids : &swnode_root_ids,
662 			     0, 0, GFP_KERNEL);
663 	if (ret < 0) {
664 		kfree(swnode);
665 		goto out_err;
666 	}
667 
668 	swnode->id = ret;
669 	swnode->node = node;
670 	swnode->parent = parent;
671 	swnode->allocated = allocated;
672 	swnode->kobj.kset = swnode_kset;
673 	fwnode_init(&swnode->fwnode, &software_node_ops);
674 
675 	ida_init(&swnode->child_ids);
676 	INIT_LIST_HEAD(&swnode->entry);
677 	INIT_LIST_HEAD(&swnode->children);
678 
679 	if (node->name)
680 		ret = kobject_init_and_add(&swnode->kobj, &software_node_type,
681 					   parent ? &parent->kobj : NULL,
682 					   "%s", node->name);
683 	else
684 		ret = kobject_init_and_add(&swnode->kobj, &software_node_type,
685 					   parent ? &parent->kobj : NULL,
686 					   "node%d", swnode->id);
687 	if (ret) {
688 		kobject_put(&swnode->kobj);
689 		return ERR_PTR(ret);
690 	}
691 
692 	if (parent)
693 		list_add_tail(&swnode->entry, &parent->children);
694 
695 	kobject_uevent(&swnode->kobj, KOBJ_ADD);
696 	return &swnode->fwnode;
697 
698 out_err:
699 	if (allocated)
700 		property_entries_free(node->properties);
701 	return ERR_PTR(ret);
702 }
703 
704 /**
705  * software_node_register_nodes - Register an array of software nodes
706  * @nodes: Zero terminated array of software nodes to be registered
707  *
708  * Register multiple software nodes at once.
709  */
software_node_register_nodes(const struct software_node * nodes)710 int software_node_register_nodes(const struct software_node *nodes)
711 {
712 	int ret;
713 	int i;
714 
715 	for (i = 0; nodes[i].name; i++) {
716 		ret = software_node_register(&nodes[i]);
717 		if (ret) {
718 			software_node_unregister_nodes(nodes);
719 			return ret;
720 		}
721 	}
722 
723 	return 0;
724 }
725 EXPORT_SYMBOL_GPL(software_node_register_nodes);
726 
727 /**
728  * software_node_unregister_nodes - Unregister an array of software nodes
729  * @nodes: Zero terminated array of software nodes to be unregistered
730  *
731  * Unregister multiple software nodes at once.
732  *
733  * NOTE: Be careful using this call if the nodes had parent pointers set up in
734  * them before registering.  If so, it is wiser to remove the nodes
735  * individually, in the correct order (child before parent) instead of relying
736  * on the sequential order of the list of nodes in the array.
737  */
software_node_unregister_nodes(const struct software_node * nodes)738 void software_node_unregister_nodes(const struct software_node *nodes)
739 {
740 	int i;
741 
742 	for (i = 0; nodes[i].name; i++)
743 		software_node_unregister(&nodes[i]);
744 }
745 EXPORT_SYMBOL_GPL(software_node_unregister_nodes);
746 
747 /**
748  * software_node_register_node_group - Register a group of software nodes
749  * @node_group: NULL terminated array of software node pointers to be registered
750  *
751  * Register multiple software nodes at once.
752  */
software_node_register_node_group(const struct software_node ** node_group)753 int software_node_register_node_group(const struct software_node **node_group)
754 {
755 	unsigned int i;
756 	int ret;
757 
758 	if (!node_group)
759 		return 0;
760 
761 	for (i = 0; node_group[i]; i++) {
762 		ret = software_node_register(node_group[i]);
763 		if (ret) {
764 			software_node_unregister_node_group(node_group);
765 			return ret;
766 		}
767 	}
768 
769 	return 0;
770 }
771 EXPORT_SYMBOL_GPL(software_node_register_node_group);
772 
773 /**
774  * software_node_unregister_node_group - Unregister a group of software nodes
775  * @node_group: NULL terminated array of software node pointers to be unregistered
776  *
777  * Unregister multiple software nodes at once.
778  */
software_node_unregister_node_group(const struct software_node ** node_group)779 void software_node_unregister_node_group(const struct software_node **node_group)
780 {
781 	unsigned int i;
782 
783 	if (!node_group)
784 		return;
785 
786 	for (i = 0; node_group[i]; i++)
787 		software_node_unregister(node_group[i]);
788 }
789 EXPORT_SYMBOL_GPL(software_node_unregister_node_group);
790 
791 /**
792  * software_node_register - Register static software node
793  * @node: The software node to be registered
794  */
software_node_register(const struct software_node * node)795 int software_node_register(const struct software_node *node)
796 {
797 	struct swnode *parent = software_node_to_swnode(node->parent);
798 
799 	if (software_node_to_swnode(node))
800 		return -EEXIST;
801 
802 	if (node->parent && !parent)
803 		return -EINVAL;
804 
805 	return PTR_ERR_OR_ZERO(swnode_register(node, parent, 0));
806 }
807 EXPORT_SYMBOL_GPL(software_node_register);
808 
809 /**
810  * software_node_unregister - Unregister static software node
811  * @node: The software node to be unregistered
812  */
software_node_unregister(const struct software_node * node)813 void software_node_unregister(const struct software_node *node)
814 {
815 	struct swnode *swnode;
816 
817 	swnode = software_node_to_swnode(node);
818 	if (swnode)
819 		fwnode_remove_software_node(&swnode->fwnode);
820 }
821 EXPORT_SYMBOL_GPL(software_node_unregister);
822 
823 struct fwnode_handle *
fwnode_create_software_node(const struct property_entry * properties,const struct fwnode_handle * parent)824 fwnode_create_software_node(const struct property_entry *properties,
825 			    const struct fwnode_handle *parent)
826 {
827 	struct software_node *node;
828 	struct swnode *p = NULL;
829 	int ret;
830 
831 	if (parent) {
832 		if (IS_ERR(parent))
833 			return ERR_CAST(parent);
834 		if (!is_software_node(parent))
835 			return ERR_PTR(-EINVAL);
836 		p = to_swnode(parent);
837 	}
838 
839 	node = kzalloc(sizeof(*node), GFP_KERNEL);
840 	if (!node)
841 		return ERR_PTR(-ENOMEM);
842 
843 	ret = software_node_register_properties(node, properties);
844 	if (ret) {
845 		kfree(node);
846 		return ERR_PTR(ret);
847 	}
848 
849 	node->parent = p ? p->node : NULL;
850 
851 	return swnode_register(node, p, 1);
852 }
853 EXPORT_SYMBOL_GPL(fwnode_create_software_node);
854 
fwnode_remove_software_node(struct fwnode_handle * fwnode)855 void fwnode_remove_software_node(struct fwnode_handle *fwnode)
856 {
857 	struct swnode *swnode = to_swnode(fwnode);
858 
859 	if (!swnode)
860 		return;
861 
862 	kobject_put(&swnode->kobj);
863 }
864 EXPORT_SYMBOL_GPL(fwnode_remove_software_node);
865 
866 /**
867  * device_add_software_node - Assign software node to a device
868  * @dev: The device the software node is meant for.
869  * @node: The software node.
870  *
871  * This function will make @node the secondary firmware node pointer of @dev. If
872  * @dev has no primary node, then @node will become the primary node. The
873  * function will register @node automatically if it wasn't already registered.
874  */
device_add_software_node(struct device * dev,const struct software_node * node)875 int device_add_software_node(struct device *dev, const struct software_node *node)
876 {
877 	struct swnode *swnode;
878 	int ret;
879 
880 	/* Only one software node per device. */
881 	if (dev_to_swnode(dev))
882 		return -EBUSY;
883 
884 	swnode = software_node_to_swnode(node);
885 	if (swnode) {
886 		kobject_get(&swnode->kobj);
887 	} else {
888 		ret = software_node_register(node);
889 		if (ret)
890 			return ret;
891 
892 		swnode = software_node_to_swnode(node);
893 	}
894 
895 	set_secondary_fwnode(dev, &swnode->fwnode);
896 
897 	/*
898 	 * If the device has been fully registered by the time this function is
899 	 * called, software_node_notify() must be called separately so that the
900 	 * symlinks get created and the reference count of the node is kept in
901 	 * balance.
902 	 */
903 	if (device_is_registered(dev))
904 		software_node_notify(dev, KOBJ_ADD);
905 
906 	return 0;
907 }
908 EXPORT_SYMBOL_GPL(device_add_software_node);
909 
910 /**
911  * device_remove_software_node - Remove device's software node
912  * @dev: The device with the software node.
913  *
914  * This function will unregister the software node of @dev.
915  */
device_remove_software_node(struct device * dev)916 void device_remove_software_node(struct device *dev)
917 {
918 	struct swnode *swnode;
919 
920 	swnode = dev_to_swnode(dev);
921 	if (!swnode)
922 		return;
923 
924 	if (device_is_registered(dev))
925 		software_node_notify(dev, KOBJ_REMOVE);
926 	set_secondary_fwnode(dev, NULL);
927 	kobject_put(&swnode->kobj);
928 }
929 EXPORT_SYMBOL_GPL(device_remove_software_node);
930 
software_node_notify(struct device * dev,unsigned long action)931 int software_node_notify(struct device *dev, unsigned long action)
932 {
933 	struct swnode *swnode;
934 	int ret;
935 
936 	swnode = dev_to_swnode(dev);
937 	if (!swnode)
938 		return 0;
939 
940 	switch (action) {
941 	case KOBJ_ADD:
942 		ret = sysfs_create_link(&dev->kobj, &swnode->kobj, "software_node");
943 		if (ret)
944 			break;
945 
946 		ret = sysfs_create_link(&swnode->kobj, &dev->kobj,
947 					dev_name(dev));
948 		if (ret) {
949 			sysfs_remove_link(&dev->kobj, "software_node");
950 			break;
951 		}
952 		kobject_get(&swnode->kobj);
953 		break;
954 	case KOBJ_REMOVE:
955 		sysfs_remove_link(&swnode->kobj, dev_name(dev));
956 		sysfs_remove_link(&dev->kobj, "software_node");
957 		kobject_put(&swnode->kobj);
958 		break;
959 	default:
960 		break;
961 	}
962 
963 	return 0;
964 }
965 
software_node_init(void)966 static int __init software_node_init(void)
967 {
968 	swnode_kset = kset_create_and_add("software_nodes", NULL, kernel_kobj);
969 	if (!swnode_kset)
970 		return -ENOMEM;
971 	return 0;
972 }
973 postcore_initcall(software_node_init);
974 
software_node_exit(void)975 static void __exit software_node_exit(void)
976 {
977 	ida_destroy(&swnode_root_ids);
978 	kset_unregister(swnode_kset);
979 }
980 __exitcall(software_node_exit);
981