Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/base/swnode.c
48984 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
/*
539
* A software node can reference other software nodes or firmware
540
* nodes (which are the abstraction layer sitting on top of them).
541
* This is done to ensure we can create references to static software
542
* nodes before they're registered with the firmware node framework.
543
* At the time the reference is being resolved, we expect the swnodes
544
* in question to already have been registered and to be backed by
545
* a firmware node. This is why we use the fwnode API below to read the
546
* relevant properties and bump the reference count.
547
*/
548
549
if (ref->swnode)
550
refnode = software_node_fwnode(ref->swnode);
551
else if (ref->fwnode)
552
refnode = ref->fwnode;
553
else
554
return -EINVAL;
555
556
if (!refnode)
557
return -ENOENT;
558
559
if (nargs_prop) {
560
error = fwnode_property_read_u32(refnode, nargs_prop, &nargs_prop_val);
561
if (error)
562
return error;
563
564
nargs = nargs_prop_val;
565
}
566
567
if (nargs > NR_FWNODE_REFERENCE_ARGS)
568
return -EINVAL;
569
570
if (!args)
571
return 0;
572
573
args->fwnode = fwnode_handle_get(refnode);
574
args->nargs = nargs;
575
576
for (i = 0; i < nargs; i++)
577
args->args[i] = ref->args[i];
578
579
return 0;
580
}
581
582
static struct fwnode_handle *
583
swnode_graph_find_next_port(const struct fwnode_handle *parent,
584
struct fwnode_handle *port)
585
{
586
struct fwnode_handle *old = port;
587
588
while ((port = software_node_get_next_child(parent, old))) {
589
/*
590
* fwnode ports have naming style "port@", so we search for any
591
* children that follow that convention.
592
*/
593
if (!strncmp(to_swnode(port)->node->name, "port@",
594
strlen("port@")))
595
return port;
596
old = port;
597
}
598
599
return NULL;
600
}
601
602
static struct fwnode_handle *
603
software_node_graph_get_next_endpoint(const struct fwnode_handle *fwnode,
604
struct fwnode_handle *endpoint)
605
{
606
struct swnode *swnode = to_swnode(fwnode);
607
struct fwnode_handle *parent;
608
struct fwnode_handle *port;
609
610
if (!swnode)
611
return NULL;
612
613
if (endpoint) {
614
port = software_node_get_parent(endpoint);
615
parent = software_node_get_parent(port);
616
} else {
617
parent = software_node_get_named_child_node(fwnode, "ports");
618
if (!parent)
619
parent = software_node_get(&swnode->fwnode);
620
621
port = swnode_graph_find_next_port(parent, NULL);
622
}
623
624
for (; port; port = swnode_graph_find_next_port(parent, port)) {
625
endpoint = software_node_get_next_child(port, endpoint);
626
if (endpoint) {
627
fwnode_handle_put(port);
628
break;
629
}
630
}
631
632
fwnode_handle_put(parent);
633
634
return endpoint;
635
}
636
637
static struct fwnode_handle *
638
software_node_graph_get_remote_endpoint(const struct fwnode_handle *fwnode)
639
{
640
struct swnode *swnode = to_swnode(fwnode);
641
const struct software_node_ref_args *ref;
642
const struct property_entry *prop;
643
644
if (!swnode)
645
return NULL;
646
647
prop = property_entry_get(swnode->node->properties, "remote-endpoint");
648
if (!prop || prop->type != DEV_PROP_REF || prop->is_inline)
649
return NULL;
650
651
ref = prop->pointer;
652
653
if (!ref->swnode)
654
return NULL;
655
656
return software_node_get(software_node_fwnode(ref->swnode));
657
}
658
659
static struct fwnode_handle *
660
software_node_graph_get_port_parent(struct fwnode_handle *fwnode)
661
{
662
struct swnode *swnode = to_swnode(fwnode);
663
664
swnode = swnode->parent;
665
if (swnode && !strcmp(swnode->node->name, "ports"))
666
swnode = swnode->parent;
667
668
return swnode ? software_node_get(&swnode->fwnode) : NULL;
669
}
670
671
static int
672
software_node_graph_parse_endpoint(const struct fwnode_handle *fwnode,
673
struct fwnode_endpoint *endpoint)
674
{
675
struct swnode *swnode = to_swnode(fwnode);
676
const char *parent_name = swnode->parent->node->name;
677
int ret;
678
679
if (strlen("port@") >= strlen(parent_name) ||
680
strncmp(parent_name, "port@", strlen("port@")))
681
return -EINVAL;
682
683
/* Ports have naming style "port@n", we need to select the n */
684
ret = kstrtou32(parent_name + strlen("port@"), 10, &endpoint->port);
685
if (ret)
686
return ret;
687
688
endpoint->id = swnode->id;
689
endpoint->local_fwnode = fwnode;
690
691
return 0;
692
}
693
694
static const struct fwnode_operations software_node_ops = {
695
.get = software_node_get,
696
.put = software_node_put,
697
.property_present = software_node_property_present,
698
.property_read_bool = software_node_property_present,
699
.property_read_int_array = software_node_read_int_array,
700
.property_read_string_array = software_node_read_string_array,
701
.get_name = software_node_get_name,
702
.get_name_prefix = software_node_get_name_prefix,
703
.get_parent = software_node_get_parent,
704
.get_next_child_node = software_node_get_next_child,
705
.get_named_child_node = software_node_get_named_child_node,
706
.get_reference_args = software_node_get_reference_args,
707
.graph_get_next_endpoint = software_node_graph_get_next_endpoint,
708
.graph_get_remote_endpoint = software_node_graph_get_remote_endpoint,
709
.graph_get_port_parent = software_node_graph_get_port_parent,
710
.graph_parse_endpoint = software_node_graph_parse_endpoint,
711
};
712
713
/* -------------------------------------------------------------------------- */
714
715
/**
716
* software_node_find_by_name - Find software node by name
717
* @parent: Parent of the software node
718
* @name: Name of the software node
719
*
720
* The function will find a node that is child of @parent and that is named
721
* @name. If no node is found, the function returns NULL.
722
*
723
* NOTE: you will need to drop the reference with fwnode_handle_put() after use.
724
*/
725
const struct software_node *
726
software_node_find_by_name(const struct software_node *parent, const char *name)
727
{
728
struct swnode *swnode = NULL;
729
struct kobject *k;
730
731
if (!name)
732
return NULL;
733
734
spin_lock(&swnode_kset->list_lock);
735
736
list_for_each_entry(k, &swnode_kset->list, entry) {
737
swnode = kobj_to_swnode(k);
738
if (parent == swnode->node->parent && swnode->node->name &&
739
!strcmp(name, swnode->node->name)) {
740
kobject_get(&swnode->kobj);
741
break;
742
}
743
swnode = NULL;
744
}
745
746
spin_unlock(&swnode_kset->list_lock);
747
748
return swnode ? swnode->node : NULL;
749
}
750
EXPORT_SYMBOL_GPL(software_node_find_by_name);
751
752
static struct software_node *software_node_alloc(const struct property_entry *properties)
753
{
754
struct property_entry *props;
755
struct software_node *node;
756
757
props = property_entries_dup(properties);
758
if (IS_ERR(props))
759
return ERR_CAST(props);
760
761
node = kzalloc(sizeof(*node), GFP_KERNEL);
762
if (!node) {
763
property_entries_free(props);
764
return ERR_PTR(-ENOMEM);
765
}
766
767
node->properties = props;
768
769
return node;
770
}
771
772
static void software_node_free(const struct software_node *node)
773
{
774
property_entries_free(node->properties);
775
kfree(node);
776
}
777
778
static void software_node_release(struct kobject *kobj)
779
{
780
struct swnode *swnode = kobj_to_swnode(kobj);
781
782
if (swnode->parent) {
783
ida_free(&swnode->parent->child_ids, swnode->id);
784
list_del(&swnode->entry);
785
} else {
786
ida_free(&swnode_root_ids, swnode->id);
787
}
788
789
if (swnode->allocated)
790
software_node_free(swnode->node);
791
792
ida_destroy(&swnode->child_ids);
793
kfree(swnode);
794
}
795
796
static const struct kobj_type software_node_type = {
797
.release = software_node_release,
798
.sysfs_ops = &kobj_sysfs_ops,
799
};
800
801
static struct fwnode_handle *
802
swnode_register(const struct software_node *node, struct swnode *parent,
803
unsigned int allocated)
804
{
805
struct swnode *swnode;
806
int ret;
807
808
swnode = kzalloc(sizeof(*swnode), GFP_KERNEL);
809
if (!swnode)
810
return ERR_PTR(-ENOMEM);
811
812
ret = ida_alloc(parent ? &parent->child_ids : &swnode_root_ids,
813
GFP_KERNEL);
814
if (ret < 0) {
815
kfree(swnode);
816
return ERR_PTR(ret);
817
}
818
819
swnode->id = ret;
820
swnode->node = node;
821
swnode->parent = parent;
822
swnode->kobj.kset = swnode_kset;
823
fwnode_init(&swnode->fwnode, &software_node_ops);
824
825
ida_init(&swnode->child_ids);
826
INIT_LIST_HEAD(&swnode->entry);
827
INIT_LIST_HEAD(&swnode->children);
828
829
if (node->name)
830
ret = kobject_init_and_add(&swnode->kobj, &software_node_type,
831
parent ? &parent->kobj : NULL,
832
"%s", node->name);
833
else
834
ret = kobject_init_and_add(&swnode->kobj, &software_node_type,
835
parent ? &parent->kobj : NULL,
836
"node%d", swnode->id);
837
if (ret) {
838
kobject_put(&swnode->kobj);
839
return ERR_PTR(ret);
840
}
841
842
/*
843
* Assign the flag only in the successful case, so
844
* the above kobject_put() won't mess up with properties.
845
*/
846
swnode->allocated = allocated;
847
848
if (parent)
849
list_add_tail(&swnode->entry, &parent->children);
850
851
kobject_uevent(&swnode->kobj, KOBJ_ADD);
852
return &swnode->fwnode;
853
}
854
855
/**
856
* software_node_register_node_group - Register a group of software nodes
857
* @node_group: NULL terminated array of software node pointers to be registered
858
*
859
* Register multiple software nodes at once. If any node in the array
860
* has its .parent pointer set (which can only be to another software_node),
861
* then its parent **must** have been registered before it is; either outside
862
* of this function or by ordering the array such that parent comes before
863
* child.
864
*/
865
int software_node_register_node_group(const struct software_node * const *node_group)
866
{
867
unsigned int i;
868
int ret;
869
870
if (!node_group)
871
return 0;
872
873
for (i = 0; node_group[i]; i++) {
874
ret = software_node_register(node_group[i]);
875
if (ret) {
876
software_node_unregister_node_group(node_group);
877
return ret;
878
}
879
}
880
881
return 0;
882
}
883
EXPORT_SYMBOL_GPL(software_node_register_node_group);
884
885
/**
886
* software_node_unregister_node_group - Unregister a group of software nodes
887
* @node_group: NULL terminated array of software node pointers to be unregistered
888
*
889
* Unregister multiple software nodes at once. If parent pointers are set up
890
* in any of the software nodes then the array **must** be ordered such that
891
* parents come before their children.
892
*
893
* NOTE: If you are uncertain whether the array is ordered such that
894
* parents will be unregistered before their children, it is wiser to
895
* remove the nodes individually, in the correct order (child before
896
* parent).
897
*/
898
void software_node_unregister_node_group(const struct software_node * const *node_group)
899
{
900
unsigned int i = 0;
901
902
if (!node_group)
903
return;
904
905
while (node_group[i])
906
i++;
907
908
while (i--)
909
software_node_unregister(node_group[i]);
910
}
911
EXPORT_SYMBOL_GPL(software_node_unregister_node_group);
912
913
/**
914
* software_node_register - Register static software node
915
* @node: The software node to be registered
916
*/
917
int software_node_register(const struct software_node *node)
918
{
919
struct swnode *parent = software_node_to_swnode(node->parent);
920
921
if (software_node_to_swnode(node))
922
return -EEXIST;
923
924
if (node->parent && !parent)
925
return -EINVAL;
926
927
return PTR_ERR_OR_ZERO(swnode_register(node, parent, 0));
928
}
929
EXPORT_SYMBOL_GPL(software_node_register);
930
931
/**
932
* software_node_unregister - Unregister static software node
933
* @node: The software node to be unregistered
934
*/
935
void software_node_unregister(const struct software_node *node)
936
{
937
struct swnode *swnode;
938
939
swnode = software_node_to_swnode(node);
940
if (swnode)
941
fwnode_remove_software_node(&swnode->fwnode);
942
}
943
EXPORT_SYMBOL_GPL(software_node_unregister);
944
945
struct fwnode_handle *
946
fwnode_create_software_node(const struct property_entry *properties,
947
const struct fwnode_handle *parent)
948
{
949
struct fwnode_handle *fwnode;
950
struct software_node *node;
951
struct swnode *p;
952
953
if (IS_ERR(parent))
954
return ERR_CAST(parent);
955
956
p = to_swnode(parent);
957
if (parent && !p)
958
return ERR_PTR(-EINVAL);
959
960
node = software_node_alloc(properties);
961
if (IS_ERR(node))
962
return ERR_CAST(node);
963
964
node->parent = p ? p->node : NULL;
965
966
fwnode = swnode_register(node, p, 1);
967
if (IS_ERR(fwnode))
968
software_node_free(node);
969
970
return fwnode;
971
}
972
EXPORT_SYMBOL_GPL(fwnode_create_software_node);
973
974
void fwnode_remove_software_node(struct fwnode_handle *fwnode)
975
{
976
struct swnode *swnode = to_swnode(fwnode);
977
978
if (!swnode)
979
return;
980
981
kobject_put(&swnode->kobj);
982
}
983
EXPORT_SYMBOL_GPL(fwnode_remove_software_node);
984
985
/**
986
* device_add_software_node - Assign software node to a device
987
* @dev: The device the software node is meant for.
988
* @node: The software node.
989
*
990
* This function will make @node the secondary firmware node pointer of @dev. If
991
* @dev has no primary node, then @node will become the primary node. The
992
* function will register @node automatically if it wasn't already registered.
993
*/
994
int device_add_software_node(struct device *dev, const struct software_node *node)
995
{
996
struct swnode *swnode;
997
int ret;
998
999
/* Only one software node per device. */
1000
if (dev_to_swnode(dev))
1001
return -EBUSY;
1002
1003
swnode = software_node_to_swnode(node);
1004
if (swnode) {
1005
kobject_get(&swnode->kobj);
1006
} else {
1007
ret = software_node_register(node);
1008
if (ret)
1009
return ret;
1010
1011
swnode = software_node_to_swnode(node);
1012
}
1013
1014
set_secondary_fwnode(dev, &swnode->fwnode);
1015
1016
/*
1017
* If the device has been fully registered by the time this function is
1018
* called, software_node_notify() must be called separately so that the
1019
* symlinks get created and the reference count of the node is kept in
1020
* balance.
1021
*/
1022
if (device_is_registered(dev))
1023
software_node_notify(dev);
1024
1025
return 0;
1026
}
1027
EXPORT_SYMBOL_GPL(device_add_software_node);
1028
1029
/**
1030
* device_remove_software_node - Remove device's software node
1031
* @dev: The device with the software node.
1032
*
1033
* This function will unregister the software node of @dev.
1034
*/
1035
void device_remove_software_node(struct device *dev)
1036
{
1037
struct swnode *swnode;
1038
1039
swnode = dev_to_swnode(dev);
1040
if (!swnode)
1041
return;
1042
1043
if (device_is_registered(dev))
1044
software_node_notify_remove(dev);
1045
1046
set_secondary_fwnode(dev, NULL);
1047
kobject_put(&swnode->kobj);
1048
}
1049
EXPORT_SYMBOL_GPL(device_remove_software_node);
1050
1051
/**
1052
* device_create_managed_software_node - Create a software node for a device
1053
* @dev: The device the software node is assigned to.
1054
* @properties: Device properties for the software node.
1055
* @parent: Parent of the software node.
1056
*
1057
* Creates a software node as a managed resource for @dev, which means the
1058
* lifetime of the newly created software node is tied to the lifetime of @dev.
1059
* Software nodes created with this function should not be reused or shared
1060
* because of that. The function takes a deep copy of @properties for the
1061
* software node.
1062
*
1063
* Since the new software node is assigned directly to @dev, and since it should
1064
* not be shared, it is not returned to the caller. The function returns 0 on
1065
* success, and errno in case of an error.
1066
*/
1067
int device_create_managed_software_node(struct device *dev,
1068
const struct property_entry *properties,
1069
const struct software_node *parent)
1070
{
1071
struct fwnode_handle *p = software_node_fwnode(parent);
1072
struct fwnode_handle *fwnode;
1073
1074
if (parent && !p)
1075
return -EINVAL;
1076
1077
fwnode = fwnode_create_software_node(properties, p);
1078
if (IS_ERR(fwnode))
1079
return PTR_ERR(fwnode);
1080
1081
to_swnode(fwnode)->managed = true;
1082
set_secondary_fwnode(dev, fwnode);
1083
1084
if (device_is_registered(dev))
1085
software_node_notify(dev);
1086
1087
return 0;
1088
}
1089
EXPORT_SYMBOL_GPL(device_create_managed_software_node);
1090
1091
void software_node_notify(struct device *dev)
1092
{
1093
struct swnode *swnode;
1094
int ret;
1095
1096
swnode = dev_to_swnode(dev);
1097
if (!swnode)
1098
return;
1099
1100
kobject_get(&swnode->kobj);
1101
ret = sysfs_create_link(&dev->kobj, &swnode->kobj, "software_node");
1102
if (ret)
1103
return;
1104
1105
ret = sysfs_create_link(&swnode->kobj, &dev->kobj, dev_name(dev));
1106
if (ret) {
1107
sysfs_remove_link(&dev->kobj, "software_node");
1108
return;
1109
}
1110
}
1111
1112
void software_node_notify_remove(struct device *dev)
1113
{
1114
struct swnode *swnode;
1115
1116
swnode = dev_to_swnode(dev);
1117
if (!swnode)
1118
return;
1119
1120
sysfs_remove_link(&swnode->kobj, dev_name(dev));
1121
sysfs_remove_link(&dev->kobj, "software_node");
1122
kobject_put(&swnode->kobj);
1123
1124
if (swnode->managed) {
1125
set_secondary_fwnode(dev, NULL);
1126
kobject_put(&swnode->kobj);
1127
}
1128
}
1129
1130
static int __init software_node_init(void)
1131
{
1132
swnode_kset = kset_create_and_add("software_nodes", NULL, kernel_kobj);
1133
if (!swnode_kset)
1134
return -ENOMEM;
1135
return 0;
1136
}
1137
postcore_initcall(software_node_init);
1138
1139
static void __exit software_node_exit(void)
1140
{
1141
ida_destroy(&swnode_root_ids);
1142
kset_unregister(swnode_kset);
1143
}
1144
__exitcall(software_node_exit);
1145
1146