Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/base/swnode.c
26378 views
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 <[email protected]>
7
*/
8
9
#include <linux/container_of.h>
10
#include <linux/device.h>
11
#include <linux/err.h>
12
#include <linux/export.h>
13
#include <linux/idr.h>
14
#include <linux/init.h>
15
#include <linux/kobject.h>
16
#include <linux/kstrtox.h>
17
#include <linux/list.h>
18
#include <linux/property.h>
19
#include <linux/slab.h>
20
#include <linux/spinlock.h>
21
#include <linux/string.h>
22
#include <linux/sysfs.h>
23
#include <linux/types.h>
24
25
#include "base.h"
26
27
struct swnode {
28
struct kobject kobj;
29
struct fwnode_handle fwnode;
30
const struct software_node *node;
31
int id;
32
33
/* hierarchy */
34
struct ida child_ids;
35
struct list_head entry;
36
struct list_head children;
37
struct swnode *parent;
38
39
unsigned int allocated:1;
40
unsigned int managed:1;
41
};
42
43
static DEFINE_IDA(swnode_root_ids);
44
static struct kset *swnode_kset;
45
46
#define kobj_to_swnode(_kobj_) container_of(_kobj_, struct swnode, kobj)
47
48
static const struct fwnode_operations software_node_ops;
49
50
bool is_software_node(const struct fwnode_handle *fwnode)
51
{
52
return !IS_ERR_OR_NULL(fwnode) && fwnode->ops == &software_node_ops;
53
}
54
EXPORT_SYMBOL_GPL(is_software_node);
55
56
#define to_swnode(__fwnode) \
57
({ \
58
typeof(__fwnode) __to_swnode_fwnode = __fwnode; \
59
\
60
is_software_node(__to_swnode_fwnode) ? \
61
container_of(__to_swnode_fwnode, \
62
struct swnode, fwnode) : NULL; \
63
})
64
65
static inline struct swnode *dev_to_swnode(struct device *dev)
66
{
67
struct fwnode_handle *fwnode = dev_fwnode(dev);
68
69
if (!fwnode)
70
return NULL;
71
72
if (!is_software_node(fwnode))
73
fwnode = fwnode->secondary;
74
75
return to_swnode(fwnode);
76
}
77
78
static struct swnode *
79
software_node_to_swnode(const struct software_node *node)
80
{
81
struct swnode *swnode = NULL;
82
struct kobject *k;
83
84
if (!node)
85
return NULL;
86
87
spin_lock(&swnode_kset->list_lock);
88
89
list_for_each_entry(k, &swnode_kset->list, entry) {
90
swnode = kobj_to_swnode(k);
91
if (swnode->node == node)
92
break;
93
swnode = NULL;
94
}
95
96
spin_unlock(&swnode_kset->list_lock);
97
98
return swnode;
99
}
100
101
const struct software_node *to_software_node(const struct fwnode_handle *fwnode)
102
{
103
const struct swnode *swnode = to_swnode(fwnode);
104
105
return swnode ? swnode->node : NULL;
106
}
107
EXPORT_SYMBOL_GPL(to_software_node);
108
109
struct fwnode_handle *software_node_fwnode(const struct software_node *node)
110
{
111
struct swnode *swnode = software_node_to_swnode(node);
112
113
return swnode ? &swnode->fwnode : NULL;
114
}
115
EXPORT_SYMBOL_GPL(software_node_fwnode);
116
117
/* -------------------------------------------------------------------------- */
118
/* property_entry processing */
119
120
static const struct property_entry *
121
property_entry_get(const struct property_entry *prop, const char *name)
122
{
123
if (!prop)
124
return NULL;
125
126
for (; prop->name; prop++)
127
if (!strcmp(name, prop->name))
128
return prop;
129
130
return NULL;
131
}
132
133
static const void *property_get_pointer(const struct property_entry *prop)
134
{
135
if (!prop->length)
136
return NULL;
137
138
return prop->is_inline ? &prop->value : prop->pointer;
139
}
140
141
static const void *property_entry_find(const struct property_entry *props,
142
const char *propname, size_t length)
143
{
144
const struct property_entry *prop;
145
const void *pointer;
146
147
prop = property_entry_get(props, propname);
148
if (!prop)
149
return ERR_PTR(-EINVAL);
150
pointer = property_get_pointer(prop);
151
if (!pointer)
152
return ERR_PTR(-ENODATA);
153
if (length > prop->length)
154
return ERR_PTR(-EOVERFLOW);
155
return pointer;
156
}
157
158
static int
159
property_entry_count_elems_of_size(const struct property_entry *props,
160
const char *propname, size_t length)
161
{
162
const struct property_entry *prop;
163
164
prop = property_entry_get(props, propname);
165
if (!prop)
166
return -EINVAL;
167
168
return prop->length / length;
169
}
170
171
static int property_entry_read_int_array(const struct property_entry *props,
172
const char *name,
173
unsigned int elem_size, void *val,
174
size_t nval)
175
{
176
const void *pointer;
177
size_t length;
178
179
if (!val)
180
return property_entry_count_elems_of_size(props, name,
181
elem_size);
182
183
if (!is_power_of_2(elem_size) || elem_size > sizeof(u64))
184
return -ENXIO;
185
186
length = nval * elem_size;
187
188
pointer = property_entry_find(props, name, length);
189
if (IS_ERR(pointer))
190
return PTR_ERR(pointer);
191
192
memcpy(val, pointer, length);
193
return 0;
194
}
195
196
static int property_entry_read_string_array(const struct property_entry *props,
197
const char *propname,
198
const char **strings, size_t nval)
199
{
200
const void *pointer;
201
size_t length;
202
int array_len;
203
204
/* Find out the array length. */
205
array_len = property_entry_count_elems_of_size(props, propname,
206
sizeof(const char *));
207
if (array_len < 0)
208
return array_len;
209
210
/* Return how many there are if strings is NULL. */
211
if (!strings)
212
return array_len;
213
214
array_len = min_t(size_t, nval, array_len);
215
length = array_len * sizeof(*strings);
216
217
pointer = property_entry_find(props, propname, length);
218
if (IS_ERR(pointer))
219
return PTR_ERR(pointer);
220
221
memcpy(strings, pointer, length);
222
223
return array_len;
224
}
225
226
static void property_entry_free_data(const struct property_entry *p)
227
{
228
const char * const *src_str;
229
size_t i, nval;
230
231
if (p->type == DEV_PROP_STRING) {
232
src_str = property_get_pointer(p);
233
nval = p->length / sizeof(*src_str);
234
for (i = 0; i < nval; i++)
235
kfree(src_str[i]);
236
}
237
238
if (!p->is_inline)
239
kfree(p->pointer);
240
241
kfree(p->name);
242
}
243
244
static bool property_copy_string_array(const char **dst_ptr,
245
const char * const *src_ptr,
246
size_t nval)
247
{
248
int i;
249
250
for (i = 0; i < nval; i++) {
251
dst_ptr[i] = kstrdup(src_ptr[i], GFP_KERNEL);
252
if (!dst_ptr[i] && src_ptr[i]) {
253
while (--i >= 0)
254
kfree(dst_ptr[i]);
255
return false;
256
}
257
}
258
259
return true;
260
}
261
262
static int property_entry_copy_data(struct property_entry *dst,
263
const struct property_entry *src)
264
{
265
const void *pointer = property_get_pointer(src);
266
void *dst_ptr;
267
size_t nval;
268
269
/*
270
* Properties with no data should not be marked as stored
271
* out of line.
272
*/
273
if (!src->is_inline && !src->length)
274
return -ENODATA;
275
276
/*
277
* Reference properties are never stored inline as
278
* they are too big.
279
*/
280
if (src->type == DEV_PROP_REF && src->is_inline)
281
return -EINVAL;
282
283
if (src->length <= sizeof(dst->value)) {
284
dst_ptr = &dst->value;
285
dst->is_inline = true;
286
} else {
287
dst_ptr = kmalloc(src->length, GFP_KERNEL);
288
if (!dst_ptr)
289
return -ENOMEM;
290
dst->pointer = dst_ptr;
291
}
292
293
if (src->type == DEV_PROP_STRING) {
294
nval = src->length / sizeof(const char *);
295
if (!property_copy_string_array(dst_ptr, pointer, nval)) {
296
if (!dst->is_inline)
297
kfree(dst->pointer);
298
return -ENOMEM;
299
}
300
} else {
301
memcpy(dst_ptr, pointer, src->length);
302
}
303
304
dst->length = src->length;
305
dst->type = src->type;
306
dst->name = kstrdup(src->name, GFP_KERNEL);
307
if (!dst->name) {
308
property_entry_free_data(dst);
309
return -ENOMEM;
310
}
311
312
return 0;
313
}
314
315
/**
316
* property_entries_dup - duplicate array of properties
317
* @properties: array of properties to copy
318
*
319
* This function creates a deep copy of the given NULL-terminated array
320
* of property entries.
321
*/
322
struct property_entry *
323
property_entries_dup(const struct property_entry *properties)
324
{
325
struct property_entry *p;
326
int i, n = 0;
327
int ret;
328
329
if (!properties)
330
return NULL;
331
332
while (properties[n].name)
333
n++;
334
335
p = kcalloc(n + 1, sizeof(*p), GFP_KERNEL);
336
if (!p)
337
return ERR_PTR(-ENOMEM);
338
339
for (i = 0; i < n; i++) {
340
ret = property_entry_copy_data(&p[i], &properties[i]);
341
if (ret) {
342
while (--i >= 0)
343
property_entry_free_data(&p[i]);
344
kfree(p);
345
return ERR_PTR(ret);
346
}
347
}
348
349
return p;
350
}
351
EXPORT_SYMBOL_GPL(property_entries_dup);
352
353
/**
354
* property_entries_free - free previously allocated array of properties
355
* @properties: array of properties to destroy
356
*
357
* This function frees given NULL-terminated array of property entries,
358
* along with their data.
359
*/
360
void property_entries_free(const struct property_entry *properties)
361
{
362
const struct property_entry *p;
363
364
if (!properties)
365
return;
366
367
for (p = properties; p->name; p++)
368
property_entry_free_data(p);
369
370
kfree(properties);
371
}
372
EXPORT_SYMBOL_GPL(property_entries_free);
373
374
/* -------------------------------------------------------------------------- */
375
/* fwnode operations */
376
377
static struct fwnode_handle *software_node_get(struct fwnode_handle *fwnode)
378
{
379
struct swnode *swnode = to_swnode(fwnode);
380
381
kobject_get(&swnode->kobj);
382
383
return &swnode->fwnode;
384
}
385
386
static void software_node_put(struct fwnode_handle *fwnode)
387
{
388
struct swnode *swnode = to_swnode(fwnode);
389
390
kobject_put(&swnode->kobj);
391
}
392
393
static bool software_node_property_present(const struct fwnode_handle *fwnode,
394
const char *propname)
395
{
396
struct swnode *swnode = to_swnode(fwnode);
397
398
return !!property_entry_get(swnode->node->properties, propname);
399
}
400
401
static int software_node_read_int_array(const struct fwnode_handle *fwnode,
402
const char *propname,
403
unsigned int elem_size, void *val,
404
size_t nval)
405
{
406
struct swnode *swnode = to_swnode(fwnode);
407
408
return property_entry_read_int_array(swnode->node->properties, propname,
409
elem_size, val, nval);
410
}
411
412
static int software_node_read_string_array(const struct fwnode_handle *fwnode,
413
const char *propname,
414
const char **val, size_t nval)
415
{
416
struct swnode *swnode = to_swnode(fwnode);
417
418
return property_entry_read_string_array(swnode->node->properties,
419
propname, val, nval);
420
}
421
422
static const char *
423
software_node_get_name(const struct fwnode_handle *fwnode)
424
{
425
const struct swnode *swnode = to_swnode(fwnode);
426
427
return kobject_name(&swnode->kobj);
428
}
429
430
static const char *
431
software_node_get_name_prefix(const struct fwnode_handle *fwnode)
432
{
433
struct fwnode_handle *parent;
434
const char *prefix;
435
436
parent = fwnode_get_parent(fwnode);
437
if (!parent)
438
return "";
439
440
/* Figure out the prefix from the parents. */
441
while (is_software_node(parent))
442
parent = fwnode_get_next_parent(parent);
443
444
prefix = fwnode_get_name_prefix(parent);
445
fwnode_handle_put(parent);
446
447
/* Guess something if prefix was NULL. */
448
return prefix ?: "/";
449
}
450
451
static struct fwnode_handle *
452
software_node_get_parent(const struct fwnode_handle *fwnode)
453
{
454
struct swnode *swnode = to_swnode(fwnode);
455
456
if (!swnode || !swnode->parent)
457
return NULL;
458
459
return fwnode_handle_get(&swnode->parent->fwnode);
460
}
461
462
static struct fwnode_handle *
463
software_node_get_next_child(const struct fwnode_handle *fwnode,
464
struct fwnode_handle *child)
465
{
466
struct swnode *p = to_swnode(fwnode);
467
struct swnode *c = to_swnode(child);
468
469
if (!p || list_empty(&p->children) ||
470
(c && list_is_last(&c->entry, &p->children))) {
471
fwnode_handle_put(child);
472
return NULL;
473
}
474
475
if (c)
476
c = list_next_entry(c, entry);
477
else
478
c = list_first_entry(&p->children, struct swnode, entry);
479
480
fwnode_handle_put(child);
481
return fwnode_handle_get(&c->fwnode);
482
}
483
484
static struct fwnode_handle *
485
software_node_get_named_child_node(const struct fwnode_handle *fwnode,
486
const char *childname)
487
{
488
struct swnode *swnode = to_swnode(fwnode);
489
struct swnode *child;
490
491
if (!swnode || list_empty(&swnode->children))
492
return NULL;
493
494
list_for_each_entry(child, &swnode->children, entry) {
495
if (!strcmp(childname, kobject_name(&child->kobj))) {
496
kobject_get(&child->kobj);
497
return &child->fwnode;
498
}
499
}
500
return NULL;
501
}
502
503
static int
504
software_node_get_reference_args(const struct fwnode_handle *fwnode,
505
const char *propname, const char *nargs_prop,
506
unsigned int nargs, unsigned int index,
507
struct fwnode_reference_args *args)
508
{
509
struct swnode *swnode = to_swnode(fwnode);
510
const struct software_node_ref_args *ref_array;
511
const struct software_node_ref_args *ref;
512
const struct property_entry *prop;
513
struct fwnode_handle *refnode;
514
u32 nargs_prop_val;
515
int error;
516
int i;
517
518
prop = property_entry_get(swnode->node->properties, propname);
519
if (!prop)
520
return -ENOENT;
521
522
if (prop->type != DEV_PROP_REF)
523
return -EINVAL;
524
525
/*
526
* We expect that references are never stored inline, even
527
* single ones, as they are too big.
528
*/
529
if (prop->is_inline)
530
return -EINVAL;
531
532
if ((index + 1) * sizeof(*ref) > prop->length)
533
return -ENOENT;
534
535
ref_array = prop->pointer;
536
ref = &ref_array[index];
537
538
refnode = software_node_fwnode(ref->node);
539
if (!refnode)
540
return -ENOENT;
541
542
if (nargs_prop) {
543
error = property_entry_read_int_array(ref->node->properties,
544
nargs_prop, sizeof(u32),
545
&nargs_prop_val, 1);
546
if (error)
547
return error;
548
549
nargs = nargs_prop_val;
550
}
551
552
if (nargs > NR_FWNODE_REFERENCE_ARGS)
553
return -EINVAL;
554
555
if (!args)
556
return 0;
557
558
args->fwnode = software_node_get(refnode);
559
args->nargs = nargs;
560
561
for (i = 0; i < nargs; i++)
562
args->args[i] = ref->args[i];
563
564
return 0;
565
}
566
567
static struct fwnode_handle *
568
swnode_graph_find_next_port(const struct fwnode_handle *parent,
569
struct fwnode_handle *port)
570
{
571
struct fwnode_handle *old = port;
572
573
while ((port = software_node_get_next_child(parent, old))) {
574
/*
575
* fwnode ports have naming style "port@", so we search for any
576
* children that follow that convention.
577
*/
578
if (!strncmp(to_swnode(port)->node->name, "port@",
579
strlen("port@")))
580
return port;
581
old = port;
582
}
583
584
return NULL;
585
}
586
587
static struct fwnode_handle *
588
software_node_graph_get_next_endpoint(const struct fwnode_handle *fwnode,
589
struct fwnode_handle *endpoint)
590
{
591
struct swnode *swnode = to_swnode(fwnode);
592
struct fwnode_handle *parent;
593
struct fwnode_handle *port;
594
595
if (!swnode)
596
return NULL;
597
598
if (endpoint) {
599
port = software_node_get_parent(endpoint);
600
parent = software_node_get_parent(port);
601
} else {
602
parent = software_node_get_named_child_node(fwnode, "ports");
603
if (!parent)
604
parent = software_node_get(&swnode->fwnode);
605
606
port = swnode_graph_find_next_port(parent, NULL);
607
}
608
609
for (; port; port = swnode_graph_find_next_port(parent, port)) {
610
endpoint = software_node_get_next_child(port, endpoint);
611
if (endpoint) {
612
fwnode_handle_put(port);
613
break;
614
}
615
}
616
617
fwnode_handle_put(parent);
618
619
return endpoint;
620
}
621
622
static struct fwnode_handle *
623
software_node_graph_get_remote_endpoint(const struct fwnode_handle *fwnode)
624
{
625
struct swnode *swnode = to_swnode(fwnode);
626
const struct software_node_ref_args *ref;
627
const struct property_entry *prop;
628
629
if (!swnode)
630
return NULL;
631
632
prop = property_entry_get(swnode->node->properties, "remote-endpoint");
633
if (!prop || prop->type != DEV_PROP_REF || prop->is_inline)
634
return NULL;
635
636
ref = prop->pointer;
637
638
return software_node_get(software_node_fwnode(ref[0].node));
639
}
640
641
static struct fwnode_handle *
642
software_node_graph_get_port_parent(struct fwnode_handle *fwnode)
643
{
644
struct swnode *swnode = to_swnode(fwnode);
645
646
swnode = swnode->parent;
647
if (swnode && !strcmp(swnode->node->name, "ports"))
648
swnode = swnode->parent;
649
650
return swnode ? software_node_get(&swnode->fwnode) : NULL;
651
}
652
653
static int
654
software_node_graph_parse_endpoint(const struct fwnode_handle *fwnode,
655
struct fwnode_endpoint *endpoint)
656
{
657
struct swnode *swnode = to_swnode(fwnode);
658
const char *parent_name = swnode->parent->node->name;
659
int ret;
660
661
if (strlen("port@") >= strlen(parent_name) ||
662
strncmp(parent_name, "port@", strlen("port@")))
663
return -EINVAL;
664
665
/* Ports have naming style "port@n", we need to select the n */
666
ret = kstrtou32(parent_name + strlen("port@"), 10, &endpoint->port);
667
if (ret)
668
return ret;
669
670
endpoint->id = swnode->id;
671
endpoint->local_fwnode = fwnode;
672
673
return 0;
674
}
675
676
static const struct fwnode_operations software_node_ops = {
677
.get = software_node_get,
678
.put = software_node_put,
679
.property_present = software_node_property_present,
680
.property_read_bool = software_node_property_present,
681
.property_read_int_array = software_node_read_int_array,
682
.property_read_string_array = software_node_read_string_array,
683
.get_name = software_node_get_name,
684
.get_name_prefix = software_node_get_name_prefix,
685
.get_parent = software_node_get_parent,
686
.get_next_child_node = software_node_get_next_child,
687
.get_named_child_node = software_node_get_named_child_node,
688
.get_reference_args = software_node_get_reference_args,
689
.graph_get_next_endpoint = software_node_graph_get_next_endpoint,
690
.graph_get_remote_endpoint = software_node_graph_get_remote_endpoint,
691
.graph_get_port_parent = software_node_graph_get_port_parent,
692
.graph_parse_endpoint = software_node_graph_parse_endpoint,
693
};
694
695
/* -------------------------------------------------------------------------- */
696
697
/**
698
* software_node_find_by_name - Find software node by name
699
* @parent: Parent of the software node
700
* @name: Name of the software node
701
*
702
* The function will find a node that is child of @parent and that is named
703
* @name. If no node is found, the function returns NULL.
704
*
705
* NOTE: you will need to drop the reference with fwnode_handle_put() after use.
706
*/
707
const struct software_node *
708
software_node_find_by_name(const struct software_node *parent, const char *name)
709
{
710
struct swnode *swnode = NULL;
711
struct kobject *k;
712
713
if (!name)
714
return NULL;
715
716
spin_lock(&swnode_kset->list_lock);
717
718
list_for_each_entry(k, &swnode_kset->list, entry) {
719
swnode = kobj_to_swnode(k);
720
if (parent == swnode->node->parent && swnode->node->name &&
721
!strcmp(name, swnode->node->name)) {
722
kobject_get(&swnode->kobj);
723
break;
724
}
725
swnode = NULL;
726
}
727
728
spin_unlock(&swnode_kset->list_lock);
729
730
return swnode ? swnode->node : NULL;
731
}
732
EXPORT_SYMBOL_GPL(software_node_find_by_name);
733
734
static struct software_node *software_node_alloc(const struct property_entry *properties)
735
{
736
struct property_entry *props;
737
struct software_node *node;
738
739
props = property_entries_dup(properties);
740
if (IS_ERR(props))
741
return ERR_CAST(props);
742
743
node = kzalloc(sizeof(*node), GFP_KERNEL);
744
if (!node) {
745
property_entries_free(props);
746
return ERR_PTR(-ENOMEM);
747
}
748
749
node->properties = props;
750
751
return node;
752
}
753
754
static void software_node_free(const struct software_node *node)
755
{
756
property_entries_free(node->properties);
757
kfree(node);
758
}
759
760
static void software_node_release(struct kobject *kobj)
761
{
762
struct swnode *swnode = kobj_to_swnode(kobj);
763
764
if (swnode->parent) {
765
ida_free(&swnode->parent->child_ids, swnode->id);
766
list_del(&swnode->entry);
767
} else {
768
ida_free(&swnode_root_ids, swnode->id);
769
}
770
771
if (swnode->allocated)
772
software_node_free(swnode->node);
773
774
ida_destroy(&swnode->child_ids);
775
kfree(swnode);
776
}
777
778
static const struct kobj_type software_node_type = {
779
.release = software_node_release,
780
.sysfs_ops = &kobj_sysfs_ops,
781
};
782
783
static struct fwnode_handle *
784
swnode_register(const struct software_node *node, struct swnode *parent,
785
unsigned int allocated)
786
{
787
struct swnode *swnode;
788
int ret;
789
790
swnode = kzalloc(sizeof(*swnode), GFP_KERNEL);
791
if (!swnode)
792
return ERR_PTR(-ENOMEM);
793
794
ret = ida_alloc(parent ? &parent->child_ids : &swnode_root_ids,
795
GFP_KERNEL);
796
if (ret < 0) {
797
kfree(swnode);
798
return ERR_PTR(ret);
799
}
800
801
swnode->id = ret;
802
swnode->node = node;
803
swnode->parent = parent;
804
swnode->kobj.kset = swnode_kset;
805
fwnode_init(&swnode->fwnode, &software_node_ops);
806
807
ida_init(&swnode->child_ids);
808
INIT_LIST_HEAD(&swnode->entry);
809
INIT_LIST_HEAD(&swnode->children);
810
811
if (node->name)
812
ret = kobject_init_and_add(&swnode->kobj, &software_node_type,
813
parent ? &parent->kobj : NULL,
814
"%s", node->name);
815
else
816
ret = kobject_init_and_add(&swnode->kobj, &software_node_type,
817
parent ? &parent->kobj : NULL,
818
"node%d", swnode->id);
819
if (ret) {
820
kobject_put(&swnode->kobj);
821
return ERR_PTR(ret);
822
}
823
824
/*
825
* Assign the flag only in the successful case, so
826
* the above kobject_put() won't mess up with properties.
827
*/
828
swnode->allocated = allocated;
829
830
if (parent)
831
list_add_tail(&swnode->entry, &parent->children);
832
833
kobject_uevent(&swnode->kobj, KOBJ_ADD);
834
return &swnode->fwnode;
835
}
836
837
/**
838
* software_node_register_node_group - Register a group of software nodes
839
* @node_group: NULL terminated array of software node pointers to be registered
840
*
841
* Register multiple software nodes at once. If any node in the array
842
* has its .parent pointer set (which can only be to another software_node),
843
* then its parent **must** have been registered before it is; either outside
844
* of this function or by ordering the array such that parent comes before
845
* child.
846
*/
847
int software_node_register_node_group(const struct software_node **node_group)
848
{
849
unsigned int i;
850
int ret;
851
852
if (!node_group)
853
return 0;
854
855
for (i = 0; node_group[i]; i++) {
856
ret = software_node_register(node_group[i]);
857
if (ret) {
858
software_node_unregister_node_group(node_group);
859
return ret;
860
}
861
}
862
863
return 0;
864
}
865
EXPORT_SYMBOL_GPL(software_node_register_node_group);
866
867
/**
868
* software_node_unregister_node_group - Unregister a group of software nodes
869
* @node_group: NULL terminated array of software node pointers to be unregistered
870
*
871
* Unregister multiple software nodes at once. If parent pointers are set up
872
* in any of the software nodes then the array **must** be ordered such that
873
* parents come before their children.
874
*
875
* NOTE: If you are uncertain whether the array is ordered such that
876
* parents will be unregistered before their children, it is wiser to
877
* remove the nodes individually, in the correct order (child before
878
* parent).
879
*/
880
void software_node_unregister_node_group(
881
const struct software_node **node_group)
882
{
883
unsigned int i = 0;
884
885
if (!node_group)
886
return;
887
888
while (node_group[i])
889
i++;
890
891
while (i--)
892
software_node_unregister(node_group[i]);
893
}
894
EXPORT_SYMBOL_GPL(software_node_unregister_node_group);
895
896
/**
897
* software_node_register - Register static software node
898
* @node: The software node to be registered
899
*/
900
int software_node_register(const struct software_node *node)
901
{
902
struct swnode *parent = software_node_to_swnode(node->parent);
903
904
if (software_node_to_swnode(node))
905
return -EEXIST;
906
907
if (node->parent && !parent)
908
return -EINVAL;
909
910
return PTR_ERR_OR_ZERO(swnode_register(node, parent, 0));
911
}
912
EXPORT_SYMBOL_GPL(software_node_register);
913
914
/**
915
* software_node_unregister - Unregister static software node
916
* @node: The software node to be unregistered
917
*/
918
void software_node_unregister(const struct software_node *node)
919
{
920
struct swnode *swnode;
921
922
swnode = software_node_to_swnode(node);
923
if (swnode)
924
fwnode_remove_software_node(&swnode->fwnode);
925
}
926
EXPORT_SYMBOL_GPL(software_node_unregister);
927
928
struct fwnode_handle *
929
fwnode_create_software_node(const struct property_entry *properties,
930
const struct fwnode_handle *parent)
931
{
932
struct fwnode_handle *fwnode;
933
struct software_node *node;
934
struct swnode *p;
935
936
if (IS_ERR(parent))
937
return ERR_CAST(parent);
938
939
p = to_swnode(parent);
940
if (parent && !p)
941
return ERR_PTR(-EINVAL);
942
943
node = software_node_alloc(properties);
944
if (IS_ERR(node))
945
return ERR_CAST(node);
946
947
node->parent = p ? p->node : NULL;
948
949
fwnode = swnode_register(node, p, 1);
950
if (IS_ERR(fwnode))
951
software_node_free(node);
952
953
return fwnode;
954
}
955
EXPORT_SYMBOL_GPL(fwnode_create_software_node);
956
957
void fwnode_remove_software_node(struct fwnode_handle *fwnode)
958
{
959
struct swnode *swnode = to_swnode(fwnode);
960
961
if (!swnode)
962
return;
963
964
kobject_put(&swnode->kobj);
965
}
966
EXPORT_SYMBOL_GPL(fwnode_remove_software_node);
967
968
/**
969
* device_add_software_node - Assign software node to a device
970
* @dev: The device the software node is meant for.
971
* @node: The software node.
972
*
973
* This function will make @node the secondary firmware node pointer of @dev. If
974
* @dev has no primary node, then @node will become the primary node. The
975
* function will register @node automatically if it wasn't already registered.
976
*/
977
int device_add_software_node(struct device *dev, const struct software_node *node)
978
{
979
struct swnode *swnode;
980
int ret;
981
982
/* Only one software node per device. */
983
if (dev_to_swnode(dev))
984
return -EBUSY;
985
986
swnode = software_node_to_swnode(node);
987
if (swnode) {
988
kobject_get(&swnode->kobj);
989
} else {
990
ret = software_node_register(node);
991
if (ret)
992
return ret;
993
994
swnode = software_node_to_swnode(node);
995
}
996
997
set_secondary_fwnode(dev, &swnode->fwnode);
998
999
/*
1000
* If the device has been fully registered by the time this function is
1001
* called, software_node_notify() must be called separately so that the
1002
* symlinks get created and the reference count of the node is kept in
1003
* balance.
1004
*/
1005
if (device_is_registered(dev))
1006
software_node_notify(dev);
1007
1008
return 0;
1009
}
1010
EXPORT_SYMBOL_GPL(device_add_software_node);
1011
1012
/**
1013
* device_remove_software_node - Remove device's software node
1014
* @dev: The device with the software node.
1015
*
1016
* This function will unregister the software node of @dev.
1017
*/
1018
void device_remove_software_node(struct device *dev)
1019
{
1020
struct swnode *swnode;
1021
1022
swnode = dev_to_swnode(dev);
1023
if (!swnode)
1024
return;
1025
1026
if (device_is_registered(dev))
1027
software_node_notify_remove(dev);
1028
1029
set_secondary_fwnode(dev, NULL);
1030
kobject_put(&swnode->kobj);
1031
}
1032
EXPORT_SYMBOL_GPL(device_remove_software_node);
1033
1034
/**
1035
* device_create_managed_software_node - Create a software node for a device
1036
* @dev: The device the software node is assigned to.
1037
* @properties: Device properties for the software node.
1038
* @parent: Parent of the software node.
1039
*
1040
* Creates a software node as a managed resource for @dev, which means the
1041
* lifetime of the newly created software node is tied to the lifetime of @dev.
1042
* Software nodes created with this function should not be reused or shared
1043
* because of that. The function takes a deep copy of @properties for the
1044
* software node.
1045
*
1046
* Since the new software node is assigned directly to @dev, and since it should
1047
* not be shared, it is not returned to the caller. The function returns 0 on
1048
* success, and errno in case of an error.
1049
*/
1050
int device_create_managed_software_node(struct device *dev,
1051
const struct property_entry *properties,
1052
const struct software_node *parent)
1053
{
1054
struct fwnode_handle *p = software_node_fwnode(parent);
1055
struct fwnode_handle *fwnode;
1056
1057
if (parent && !p)
1058
return -EINVAL;
1059
1060
fwnode = fwnode_create_software_node(properties, p);
1061
if (IS_ERR(fwnode))
1062
return PTR_ERR(fwnode);
1063
1064
to_swnode(fwnode)->managed = true;
1065
set_secondary_fwnode(dev, fwnode);
1066
1067
if (device_is_registered(dev))
1068
software_node_notify(dev);
1069
1070
return 0;
1071
}
1072
EXPORT_SYMBOL_GPL(device_create_managed_software_node);
1073
1074
void software_node_notify(struct device *dev)
1075
{
1076
struct swnode *swnode;
1077
int ret;
1078
1079
swnode = dev_to_swnode(dev);
1080
if (!swnode)
1081
return;
1082
1083
kobject_get(&swnode->kobj);
1084
ret = sysfs_create_link(&dev->kobj, &swnode->kobj, "software_node");
1085
if (ret)
1086
return;
1087
1088
ret = sysfs_create_link(&swnode->kobj, &dev->kobj, dev_name(dev));
1089
if (ret) {
1090
sysfs_remove_link(&dev->kobj, "software_node");
1091
return;
1092
}
1093
}
1094
1095
void software_node_notify_remove(struct device *dev)
1096
{
1097
struct swnode *swnode;
1098
1099
swnode = dev_to_swnode(dev);
1100
if (!swnode)
1101
return;
1102
1103
sysfs_remove_link(&swnode->kobj, dev_name(dev));
1104
sysfs_remove_link(&dev->kobj, "software_node");
1105
kobject_put(&swnode->kobj);
1106
1107
if (swnode->managed) {
1108
set_secondary_fwnode(dev, NULL);
1109
kobject_put(&swnode->kobj);
1110
}
1111
}
1112
1113
static int __init software_node_init(void)
1114
{
1115
swnode_kset = kset_create_and_add("software_nodes", NULL, kernel_kobj);
1116
if (!swnode_kset)
1117
return -ENOMEM;
1118
return 0;
1119
}
1120
postcore_initcall(software_node_init);
1121
1122
static void __exit software_node_exit(void)
1123
{
1124
ida_destroy(&swnode_root_ids);
1125
kset_unregister(swnode_kset);
1126
}
1127
__exitcall(software_node_exit);
1128
1129