1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include <linux/ctype.h>
21#include <linux/module.h>
22#include <linux/of.h>
23#include <linux/spinlock.h>
24#include <linux/slab.h>
25#include <linux/proc_fs.h>
26
27#include "of_private.h"
28
29LIST_HEAD(aliases_lookup);
30
31struct device_node *of_allnodes;
32EXPORT_SYMBOL(of_allnodes);
33struct device_node *of_chosen;
34struct device_node *of_aliases;
35
36DEFINE_MUTEX(of_aliases_mutex);
37
38
39
40
41DEFINE_RAW_SPINLOCK(devtree_lock);
42
43int of_n_addr_cells(struct device_node *np)
44{
45 const __be32 *ip;
46
47 do {
48 if (np->parent)
49 np = np->parent;
50 ip = of_get_property(np, "#address-cells", NULL);
51 if (ip)
52 return be32_to_cpup(ip);
53 } while (np->parent);
54
55 return OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
56}
57EXPORT_SYMBOL(of_n_addr_cells);
58
59int of_n_size_cells(struct device_node *np)
60{
61 const __be32 *ip;
62
63 do {
64 if (np->parent)
65 np = np->parent;
66 ip = of_get_property(np, "#size-cells", NULL);
67 if (ip)
68 return be32_to_cpup(ip);
69 } while (np->parent);
70
71 return OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
72}
73EXPORT_SYMBOL(of_n_size_cells);
74
75#if defined(CONFIG_OF_DYNAMIC)
76
77
78
79
80
81
82
83struct device_node *of_node_get(struct device_node *node)
84{
85 if (node)
86 kref_get(&node->kref);
87 return node;
88}
89EXPORT_SYMBOL(of_node_get);
90
91static inline struct device_node *kref_to_device_node(struct kref *kref)
92{
93 return container_of(kref, struct device_node, kref);
94}
95
96
97
98
99
100
101
102
103static void of_node_release(struct kref *kref)
104{
105 struct device_node *node = kref_to_device_node(kref);
106 struct property *prop = node->properties;
107
108
109 if (!of_node_check_flag(node, OF_DETACHED)) {
110 pr_err("ERROR: Bad of_node_put() on %s\n", node->full_name);
111 dump_stack();
112 kref_init(&node->kref);
113 return;
114 }
115
116 if (!of_node_check_flag(node, OF_DYNAMIC))
117 return;
118
119 while (prop) {
120 struct property *next = prop->next;
121 kfree(prop->name);
122 kfree(prop->value);
123 kfree(prop);
124 prop = next;
125
126 if (!prop) {
127 prop = node->deadprops;
128 node->deadprops = NULL;
129 }
130 }
131 kfree(node->full_name);
132 kfree(node->data);
133 kfree(node);
134}
135
136
137
138
139
140
141
142void of_node_put(struct device_node *node)
143{
144 if (node)
145 kref_put(&node->kref, of_node_release);
146}
147EXPORT_SYMBOL(of_node_put);
148#endif
149
150static struct property *__of_find_property(const struct device_node *np,
151 const char *name, int *lenp)
152{
153 struct property *pp;
154
155 if (!np)
156 return NULL;
157
158 for (pp = np->properties; pp; pp = pp->next) {
159 if (of_prop_cmp(pp->name, name) == 0) {
160 if (lenp)
161 *lenp = pp->length;
162 break;
163 }
164 }
165
166 return pp;
167}
168
169struct property *of_find_property(const struct device_node *np,
170 const char *name,
171 int *lenp)
172{
173 struct property *pp;
174 unsigned long flags;
175
176 raw_spin_lock_irqsave(&devtree_lock, flags);
177 pp = __of_find_property(np, name, lenp);
178 raw_spin_unlock_irqrestore(&devtree_lock, flags);
179
180 return pp;
181}
182EXPORT_SYMBOL(of_find_property);
183
184
185
186
187
188
189
190
191
192struct device_node *of_find_all_nodes(struct device_node *prev)
193{
194 struct device_node *np;
195 unsigned long flags;
196
197 raw_spin_lock_irqsave(&devtree_lock, flags);
198 np = prev ? prev->allnext : of_allnodes;
199 for (; np != NULL; np = np->allnext)
200 if (of_node_get(np))
201 break;
202 of_node_put(prev);
203 raw_spin_unlock_irqrestore(&devtree_lock, flags);
204 return np;
205}
206EXPORT_SYMBOL(of_find_all_nodes);
207
208
209
210
211
212static const void *__of_get_property(const struct device_node *np,
213 const char *name, int *lenp)
214{
215 struct property *pp = __of_find_property(np, name, lenp);
216
217 return pp ? pp->value : NULL;
218}
219
220
221
222
223
224const void *of_get_property(const struct device_node *np, const char *name,
225 int *lenp)
226{
227 struct property *pp = of_find_property(np, name, lenp);
228
229 return pp ? pp->value : NULL;
230}
231EXPORT_SYMBOL(of_get_property);
232
233
234
235
236static int __of_device_is_compatible(const struct device_node *device,
237 const char *compat)
238{
239 const char* cp;
240 int cplen, l;
241
242 cp = __of_get_property(device, "compatible", &cplen);
243 if (cp == NULL)
244 return 0;
245 while (cplen > 0) {
246 if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
247 return 1;
248 l = strlen(cp) + 1;
249 cp += l;
250 cplen -= l;
251 }
252
253 return 0;
254}
255
256
257
258
259int of_device_is_compatible(const struct device_node *device,
260 const char *compat)
261{
262 unsigned long flags;
263 int res;
264
265 raw_spin_lock_irqsave(&devtree_lock, flags);
266 res = __of_device_is_compatible(device, compat);
267 raw_spin_unlock_irqrestore(&devtree_lock, flags);
268 return res;
269}
270EXPORT_SYMBOL(of_device_is_compatible);
271
272
273
274
275
276
277
278
279int of_machine_is_compatible(const char *compat)
280{
281 struct device_node *root;
282 int rc = 0;
283
284 root = of_find_node_by_path("/");
285 if (root) {
286 rc = of_device_is_compatible(root, compat);
287 of_node_put(root);
288 }
289 return rc;
290}
291EXPORT_SYMBOL(of_machine_is_compatible);
292
293
294
295
296
297
298
299
300
301static int __of_device_is_available(const struct device_node *device)
302{
303 const char *status;
304 int statlen;
305
306 status = __of_get_property(device, "status", &statlen);
307 if (status == NULL)
308 return 1;
309
310 if (statlen > 0) {
311 if (!strcmp(status, "okay") || !strcmp(status, "ok"))
312 return 1;
313 }
314
315 return 0;
316}
317
318
319
320
321
322
323
324
325
326int of_device_is_available(const struct device_node *device)
327{
328 unsigned long flags;
329 int res;
330
331 raw_spin_lock_irqsave(&devtree_lock, flags);
332 res = __of_device_is_available(device);
333 raw_spin_unlock_irqrestore(&devtree_lock, flags);
334 return res;
335
336}
337EXPORT_SYMBOL(of_device_is_available);
338
339
340
341
342
343
344
345
346struct device_node *of_get_parent(const struct device_node *node)
347{
348 struct device_node *np;
349 unsigned long flags;
350
351 if (!node)
352 return NULL;
353
354 raw_spin_lock_irqsave(&devtree_lock, flags);
355 np = of_node_get(node->parent);
356 raw_spin_unlock_irqrestore(&devtree_lock, flags);
357 return np;
358}
359EXPORT_SYMBOL(of_get_parent);
360
361
362
363
364
365
366
367
368
369
370
371
372struct device_node *of_get_next_parent(struct device_node *node)
373{
374 struct device_node *parent;
375 unsigned long flags;
376
377 if (!node)
378 return NULL;
379
380 raw_spin_lock_irqsave(&devtree_lock, flags);
381 parent = of_node_get(node->parent);
382 of_node_put(node);
383 raw_spin_unlock_irqrestore(&devtree_lock, flags);
384 return parent;
385}
386EXPORT_SYMBOL(of_get_next_parent);
387
388
389
390
391
392
393
394
395
396struct device_node *of_get_next_child(const struct device_node *node,
397 struct device_node *prev)
398{
399 struct device_node *next;
400 unsigned long flags;
401
402 raw_spin_lock_irqsave(&devtree_lock, flags);
403 next = prev ? prev->sibling : node->child;
404 for (; next; next = next->sibling)
405 if (of_node_get(next))
406 break;
407 of_node_put(prev);
408 raw_spin_unlock_irqrestore(&devtree_lock, flags);
409 return next;
410}
411EXPORT_SYMBOL(of_get_next_child);
412
413
414
415
416
417
418
419
420
421struct device_node *of_get_next_available_child(const struct device_node *node,
422 struct device_node *prev)
423{
424 struct device_node *next;
425 unsigned long flags;
426
427 raw_spin_lock_irqsave(&devtree_lock, flags);
428 next = prev ? prev->sibling : node->child;
429 for (; next; next = next->sibling) {
430 if (!__of_device_is_available(next))
431 continue;
432 if (of_node_get(next))
433 break;
434 }
435 of_node_put(prev);
436 raw_spin_unlock_irqrestore(&devtree_lock, flags);
437 return next;
438}
439EXPORT_SYMBOL(of_get_next_available_child);
440
441
442
443
444
445
446
447
448
449
450
451
452struct device_node *of_get_child_by_name(const struct device_node *node,
453 const char *name)
454{
455 struct device_node *child;
456
457 for_each_child_of_node(node, child)
458 if (child->name && (of_node_cmp(child->name, name) == 0))
459 break;
460 return child;
461}
462EXPORT_SYMBOL(of_get_child_by_name);
463
464
465
466
467
468
469
470
471struct device_node *of_find_node_by_path(const char *path)
472{
473 struct device_node *np = of_allnodes;
474 unsigned long flags;
475
476 raw_spin_lock_irqsave(&devtree_lock, flags);
477 for (; np; np = np->allnext) {
478 if (np->full_name && (of_node_cmp(np->full_name, path) == 0)
479 && of_node_get(np))
480 break;
481 }
482 raw_spin_unlock_irqrestore(&devtree_lock, flags);
483 return np;
484}
485EXPORT_SYMBOL(of_find_node_by_path);
486
487
488
489
490
491
492
493
494
495
496
497
498struct device_node *of_find_node_by_name(struct device_node *from,
499 const char *name)
500{
501 struct device_node *np;
502 unsigned long flags;
503
504 raw_spin_lock_irqsave(&devtree_lock, flags);
505 np = from ? from->allnext : of_allnodes;
506 for (; np; np = np->allnext)
507 if (np->name && (of_node_cmp(np->name, name) == 0)
508 && of_node_get(np))
509 break;
510 of_node_put(from);
511 raw_spin_unlock_irqrestore(&devtree_lock, flags);
512 return np;
513}
514EXPORT_SYMBOL(of_find_node_by_name);
515
516
517
518
519
520
521
522
523
524
525
526
527
528struct device_node *of_find_node_by_type(struct device_node *from,
529 const char *type)
530{
531 struct device_node *np;
532 unsigned long flags;
533
534 raw_spin_lock_irqsave(&devtree_lock, flags);
535 np = from ? from->allnext : of_allnodes;
536 for (; np; np = np->allnext)
537 if (np->type && (of_node_cmp(np->type, type) == 0)
538 && of_node_get(np))
539 break;
540 of_node_put(from);
541 raw_spin_unlock_irqrestore(&devtree_lock, flags);
542 return np;
543}
544EXPORT_SYMBOL(of_find_node_by_type);
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560struct device_node *of_find_compatible_node(struct device_node *from,
561 const char *type, const char *compatible)
562{
563 struct device_node *np;
564 unsigned long flags;
565
566 raw_spin_lock_irqsave(&devtree_lock, flags);
567 np = from ? from->allnext : of_allnodes;
568 for (; np; np = np->allnext) {
569 if (type
570 && !(np->type && (of_node_cmp(np->type, type) == 0)))
571 continue;
572 if (__of_device_is_compatible(np, compatible) &&
573 of_node_get(np))
574 break;
575 }
576 of_node_put(from);
577 raw_spin_unlock_irqrestore(&devtree_lock, flags);
578 return np;
579}
580EXPORT_SYMBOL(of_find_compatible_node);
581
582
583
584
585
586
587
588
589
590
591
592
593
594struct device_node *of_find_node_with_property(struct device_node *from,
595 const char *prop_name)
596{
597 struct device_node *np;
598 struct property *pp;
599 unsigned long flags;
600
601 raw_spin_lock_irqsave(&devtree_lock, flags);
602 np = from ? from->allnext : of_allnodes;
603 for (; np; np = np->allnext) {
604 for (pp = np->properties; pp; pp = pp->next) {
605 if (of_prop_cmp(pp->name, prop_name) == 0) {
606 of_node_get(np);
607 goto out;
608 }
609 }
610 }
611out:
612 of_node_put(from);
613 raw_spin_unlock_irqrestore(&devtree_lock, flags);
614 return np;
615}
616EXPORT_SYMBOL(of_find_node_with_property);
617
618static
619const struct of_device_id *__of_match_node(const struct of_device_id *matches,
620 const struct device_node *node)
621{
622 if (!matches)
623 return NULL;
624
625 while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
626 int match = 1;
627 if (matches->name[0])
628 match &= node->name
629 && !strcmp(matches->name, node->name);
630 if (matches->type[0])
631 match &= node->type
632 && !strcmp(matches->type, node->type);
633 if (matches->compatible[0])
634 match &= __of_device_is_compatible(node,
635 matches->compatible);
636 if (match)
637 return matches;
638 matches++;
639 }
640 return NULL;
641}
642
643
644
645
646
647
648
649
650const struct of_device_id *of_match_node(const struct of_device_id *matches,
651 const struct device_node *node)
652{
653 const struct of_device_id *match;
654 unsigned long flags;
655
656 raw_spin_lock_irqsave(&devtree_lock, flags);
657 match = __of_match_node(matches, node);
658 raw_spin_unlock_irqrestore(&devtree_lock, flags);
659 return match;
660}
661EXPORT_SYMBOL(of_match_node);
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676struct device_node *of_find_matching_node_and_match(struct device_node *from,
677 const struct of_device_id *matches,
678 const struct of_device_id **match)
679{
680 struct device_node *np;
681 const struct of_device_id *m;
682 unsigned long flags;
683
684 if (match)
685 *match = NULL;
686
687 raw_spin_lock_irqsave(&devtree_lock, flags);
688 np = from ? from->allnext : of_allnodes;
689 for (; np; np = np->allnext) {
690 m = __of_match_node(matches, np);
691 if (m && of_node_get(np)) {
692 if (match)
693 *match = m;
694 break;
695 }
696 }
697 of_node_put(from);
698 raw_spin_unlock_irqrestore(&devtree_lock, flags);
699 return np;
700}
701EXPORT_SYMBOL(of_find_matching_node_and_match);
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716int of_modalias_node(struct device_node *node, char *modalias, int len)
717{
718 const char *compatible, *p;
719 int cplen;
720
721 compatible = of_get_property(node, "compatible", &cplen);
722 if (!compatible || strlen(compatible) > cplen)
723 return -ENODEV;
724 p = strchr(compatible, ',');
725 strlcpy(modalias, p ? p + 1 : compatible, len);
726 return 0;
727}
728EXPORT_SYMBOL_GPL(of_modalias_node);
729
730
731
732
733
734
735
736
737struct device_node *of_find_node_by_phandle(phandle handle)
738{
739 struct device_node *np;
740 unsigned long flags;
741
742 raw_spin_lock_irqsave(&devtree_lock, flags);
743 for (np = of_allnodes; np; np = np->allnext)
744 if (np->phandle == handle)
745 break;
746 of_node_get(np);
747 raw_spin_unlock_irqrestore(&devtree_lock, flags);
748 return np;
749}
750EXPORT_SYMBOL(of_find_node_by_phandle);
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765static void *of_find_property_value_of_size(const struct device_node *np,
766 const char *propname, u32 len)
767{
768 struct property *prop = of_find_property(np, propname, NULL);
769
770 if (!prop)
771 return ERR_PTR(-EINVAL);
772 if (!prop->value)
773 return ERR_PTR(-ENODATA);
774 if (len > prop->length)
775 return ERR_PTR(-EOVERFLOW);
776
777 return prop->value;
778}
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795int of_property_read_u32_index(const struct device_node *np,
796 const char *propname,
797 u32 index, u32 *out_value)
798{
799 const u32 *val = of_find_property_value_of_size(np, propname,
800 ((index + 1) * sizeof(*out_value)));
801
802 if (IS_ERR(val))
803 return PTR_ERR(val);
804
805 *out_value = be32_to_cpup(((__be32 *)val) + index);
806 return 0;
807}
808EXPORT_SYMBOL_GPL(of_property_read_u32_index);
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828int of_property_read_u8_array(const struct device_node *np,
829 const char *propname, u8 *out_values, size_t sz)
830{
831 const u8 *val = of_find_property_value_of_size(np, propname,
832 (sz * sizeof(*out_values)));
833
834 if (IS_ERR(val))
835 return PTR_ERR(val);
836
837 while (sz--)
838 *out_values++ = *val++;
839 return 0;
840}
841EXPORT_SYMBOL_GPL(of_property_read_u8_array);
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861int of_property_read_u16_array(const struct device_node *np,
862 const char *propname, u16 *out_values, size_t sz)
863{
864 const __be16 *val = of_find_property_value_of_size(np, propname,
865 (sz * sizeof(*out_values)));
866
867 if (IS_ERR(val))
868 return PTR_ERR(val);
869
870 while (sz--)
871 *out_values++ = be16_to_cpup(val++);
872 return 0;
873}
874EXPORT_SYMBOL_GPL(of_property_read_u16_array);
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892int of_property_read_u32_array(const struct device_node *np,
893 const char *propname, u32 *out_values,
894 size_t sz)
895{
896 const __be32 *val = of_find_property_value_of_size(np, propname,
897 (sz * sizeof(*out_values)));
898
899 if (IS_ERR(val))
900 return PTR_ERR(val);
901
902 while (sz--)
903 *out_values++ = be32_to_cpup(val++);
904 return 0;
905}
906EXPORT_SYMBOL_GPL(of_property_read_u32_array);
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921int of_property_read_u64(const struct device_node *np, const char *propname,
922 u64 *out_value)
923{
924 const __be32 *val = of_find_property_value_of_size(np, propname,
925 sizeof(*out_value));
926
927 if (IS_ERR(val))
928 return PTR_ERR(val);
929
930 *out_value = of_read_number(val, 2);
931 return 0;
932}
933EXPORT_SYMBOL_GPL(of_property_read_u64);
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950int of_property_read_string(struct device_node *np, const char *propname,
951 const char **out_string)
952{
953 struct property *prop = of_find_property(np, propname, NULL);
954 if (!prop)
955 return -EINVAL;
956 if (!prop->value)
957 return -ENODATA;
958 if (strnlen(prop->value, prop->length) >= prop->length)
959 return -EILSEQ;
960 *out_string = prop->value;
961 return 0;
962}
963EXPORT_SYMBOL_GPL(of_property_read_string);
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983int of_property_read_string_index(struct device_node *np, const char *propname,
984 int index, const char **output)
985{
986 struct property *prop = of_find_property(np, propname, NULL);
987 int i = 0;
988 size_t l = 0, total = 0;
989 const char *p;
990
991 if (!prop)
992 return -EINVAL;
993 if (!prop->value)
994 return -ENODATA;
995 if (strnlen(prop->value, prop->length) >= prop->length)
996 return -EILSEQ;
997
998 p = prop->value;
999
1000 for (i = 0; total < prop->length; total += l, p += l) {
1001 l = strlen(p) + 1;
1002 if (i++ == index) {
1003 *output = p;
1004 return 0;
1005 }
1006 }
1007 return -ENODATA;
1008}
1009EXPORT_SYMBOL_GPL(of_property_read_string_index);
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020int of_property_match_string(struct device_node *np, const char *propname,
1021 const char *string)
1022{
1023 struct property *prop = of_find_property(np, propname, NULL);
1024 size_t l;
1025 int i;
1026 const char *p, *end;
1027
1028 if (!prop)
1029 return -EINVAL;
1030 if (!prop->value)
1031 return -ENODATA;
1032
1033 p = prop->value;
1034 end = p + prop->length;
1035
1036 for (i = 0; p < end; i++, p += l) {
1037 l = strlen(p) + 1;
1038 if (p + l > end)
1039 return -EILSEQ;
1040 pr_debug("comparing %s with %s\n", string, p);
1041 if (strcmp(string, p) == 0)
1042 return i;
1043 }
1044 return -ENODATA;
1045}
1046EXPORT_SYMBOL_GPL(of_property_match_string);
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060int of_property_count_strings(struct device_node *np, const char *propname)
1061{
1062 struct property *prop = of_find_property(np, propname, NULL);
1063 int i = 0;
1064 size_t l = 0, total = 0;
1065 const char *p;
1066
1067 if (!prop)
1068 return -EINVAL;
1069 if (!prop->value)
1070 return -ENODATA;
1071 if (strnlen(prop->value, prop->length) >= prop->length)
1072 return -EILSEQ;
1073
1074 p = prop->value;
1075
1076 for (i = 0; total < prop->length; total += l, p += l, i++)
1077 l = strlen(p) + 1;
1078
1079 return i;
1080}
1081EXPORT_SYMBOL_GPL(of_property_count_strings);
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093struct device_node *of_parse_phandle(const struct device_node *np,
1094 const char *phandle_name, int index)
1095{
1096 const __be32 *phandle;
1097 int size;
1098
1099 phandle = of_get_property(np, phandle_name, &size);
1100 if ((!phandle) || (size < sizeof(*phandle) * (index + 1)))
1101 return NULL;
1102
1103 return of_find_node_by_phandle(be32_to_cpup(phandle + index));
1104}
1105EXPORT_SYMBOL(of_parse_phandle);
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139static int __of_parse_phandle_with_args(const struct device_node *np,
1140 const char *list_name,
1141 const char *cells_name, int index,
1142 struct of_phandle_args *out_args)
1143{
1144 const __be32 *list, *list_end;
1145 int rc = 0, size, cur_index = 0;
1146 uint32_t count = 0;
1147 struct device_node *node = NULL;
1148 phandle phandle;
1149
1150
1151 list = of_get_property(np, list_name, &size);
1152 if (!list)
1153 return -ENOENT;
1154 list_end = list + size / sizeof(*list);
1155
1156
1157 while (list < list_end) {
1158 rc = -EINVAL;
1159 count = 0;
1160
1161
1162
1163
1164
1165 phandle = be32_to_cpup(list++);
1166 if (phandle) {
1167
1168
1169
1170
1171 node = of_find_node_by_phandle(phandle);
1172 if (!node) {
1173 pr_err("%s: could not find phandle\n",
1174 np->full_name);
1175 goto err;
1176 }
1177 if (of_property_read_u32(node, cells_name, &count)) {
1178 pr_err("%s: could not get %s for %s\n",
1179 np->full_name, cells_name,
1180 node->full_name);
1181 goto err;
1182 }
1183
1184
1185
1186
1187
1188 if (list + count > list_end) {
1189 pr_err("%s: arguments longer than property\n",
1190 np->full_name);
1191 goto err;
1192 }
1193 }
1194
1195
1196
1197
1198
1199
1200
1201 rc = -ENOENT;
1202 if (cur_index == index) {
1203 if (!phandle)
1204 goto err;
1205
1206 if (out_args) {
1207 int i;
1208 if (WARN_ON(count > MAX_PHANDLE_ARGS))
1209 count = MAX_PHANDLE_ARGS;
1210 out_args->np = node;
1211 out_args->args_count = count;
1212 for (i = 0; i < count; i++)
1213 out_args->args[i] = be32_to_cpup(list++);
1214 } else {
1215 of_node_put(node);
1216 }
1217
1218
1219 return 0;
1220 }
1221
1222 of_node_put(node);
1223 node = NULL;
1224 list += count;
1225 cur_index++;
1226 }
1227
1228
1229
1230
1231
1232
1233
1234 rc = index < 0 ? cur_index : -ENOENT;
1235 err:
1236 if (node)
1237 of_node_put(node);
1238 return rc;
1239}
1240
1241int of_parse_phandle_with_args(const struct device_node *np, const char *list_name,
1242 const char *cells_name, int index,
1243 struct of_phandle_args *out_args)
1244{
1245 if (index < 0)
1246 return -EINVAL;
1247 return __of_parse_phandle_with_args(np, list_name, cells_name, index, out_args);
1248}
1249EXPORT_SYMBOL(of_parse_phandle_with_args);
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266int of_count_phandle_with_args(const struct device_node *np, const char *list_name,
1267 const char *cells_name)
1268{
1269 return __of_parse_phandle_with_args(np, list_name, cells_name, -1, NULL);
1270}
1271EXPORT_SYMBOL(of_count_phandle_with_args);
1272
1273#if defined(CONFIG_OF_DYNAMIC)
1274static int of_property_notify(int action, struct device_node *np,
1275 struct property *prop)
1276{
1277 struct of_prop_reconfig pr;
1278
1279 pr.dn = np;
1280 pr.prop = prop;
1281 return of_reconfig_notify(action, &pr);
1282}
1283#else
1284static int of_property_notify(int action, struct device_node *np,
1285 struct property *prop)
1286{
1287 return 0;
1288}
1289#endif
1290
1291
1292
1293
1294int of_add_property(struct device_node *np, struct property *prop)
1295{
1296 struct property **next;
1297 unsigned long flags;
1298 int rc;
1299
1300 rc = of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop);
1301 if (rc)
1302 return rc;
1303
1304 prop->next = NULL;
1305 raw_spin_lock_irqsave(&devtree_lock, flags);
1306 next = &np->properties;
1307 while (*next) {
1308 if (strcmp(prop->name, (*next)->name) == 0) {
1309
1310 raw_spin_unlock_irqrestore(&devtree_lock, flags);
1311 return -1;
1312 }
1313 next = &(*next)->next;
1314 }
1315 *next = prop;
1316 raw_spin_unlock_irqrestore(&devtree_lock, flags);
1317
1318#ifdef CONFIG_PROC_DEVICETREE
1319
1320 if (np->pde)
1321 proc_device_tree_add_prop(np->pde, prop);
1322#endif
1323
1324 return 0;
1325}
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335int of_remove_property(struct device_node *np, struct property *prop)
1336{
1337 struct property **next;
1338 unsigned long flags;
1339 int found = 0;
1340 int rc;
1341
1342 rc = of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop);
1343 if (rc)
1344 return rc;
1345
1346 raw_spin_lock_irqsave(&devtree_lock, flags);
1347 next = &np->properties;
1348 while (*next) {
1349 if (*next == prop) {
1350
1351 *next = prop->next;
1352 prop->next = np->deadprops;
1353 np->deadprops = prop;
1354 found = 1;
1355 break;
1356 }
1357 next = &(*next)->next;
1358 }
1359 raw_spin_unlock_irqrestore(&devtree_lock, flags);
1360
1361 if (!found)
1362 return -ENODEV;
1363
1364#ifdef CONFIG_PROC_DEVICETREE
1365
1366 if (np->pde)
1367 proc_device_tree_remove_prop(np->pde, prop);
1368#endif
1369
1370 return 0;
1371}
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382int of_update_property(struct device_node *np, struct property *newprop)
1383{
1384 struct property **next, *oldprop;
1385 unsigned long flags;
1386 int rc, found = 0;
1387
1388 rc = of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop);
1389 if (rc)
1390 return rc;
1391
1392 if (!newprop->name)
1393 return -EINVAL;
1394
1395 oldprop = of_find_property(np, newprop->name, NULL);
1396 if (!oldprop)
1397 return of_add_property(np, newprop);
1398
1399 raw_spin_lock_irqsave(&devtree_lock, flags);
1400 next = &np->properties;
1401 while (*next) {
1402 if (*next == oldprop) {
1403
1404 newprop->next = oldprop->next;
1405 *next = newprop;
1406 oldprop->next = np->deadprops;
1407 np->deadprops = oldprop;
1408 found = 1;
1409 break;
1410 }
1411 next = &(*next)->next;
1412 }
1413 raw_spin_unlock_irqrestore(&devtree_lock, flags);
1414
1415 if (!found)
1416 return -ENODEV;
1417
1418#ifdef CONFIG_PROC_DEVICETREE
1419
1420 if (np->pde)
1421 proc_device_tree_update_prop(np->pde, newprop, oldprop);
1422#endif
1423
1424 return 0;
1425}
1426
1427#if defined(CONFIG_OF_DYNAMIC)
1428
1429
1430
1431
1432
1433
1434
1435
1436static BLOCKING_NOTIFIER_HEAD(of_reconfig_chain);
1437
1438int of_reconfig_notifier_register(struct notifier_block *nb)
1439{
1440 return blocking_notifier_chain_register(&of_reconfig_chain, nb);
1441}
1442EXPORT_SYMBOL_GPL(of_reconfig_notifier_register);
1443
1444int of_reconfig_notifier_unregister(struct notifier_block *nb)
1445{
1446 return blocking_notifier_chain_unregister(&of_reconfig_chain, nb);
1447}
1448EXPORT_SYMBOL_GPL(of_reconfig_notifier_unregister);
1449
1450int of_reconfig_notify(unsigned long action, void *p)
1451{
1452 int rc;
1453
1454 rc = blocking_notifier_call_chain(&of_reconfig_chain, action, p);
1455 return notifier_to_errno(rc);
1456}
1457
1458#ifdef CONFIG_PROC_DEVICETREE
1459static void of_add_proc_dt_entry(struct device_node *dn)
1460{
1461 struct proc_dir_entry *ent;
1462
1463 ent = proc_mkdir(strrchr(dn->full_name, '/') + 1, dn->parent->pde);
1464 if (ent)
1465 proc_device_tree_add_node(dn, ent);
1466}
1467#else
1468static void of_add_proc_dt_entry(struct device_node *dn)
1469{
1470 return;
1471}
1472#endif
1473
1474
1475
1476
1477int of_attach_node(struct device_node *np)
1478{
1479 unsigned long flags;
1480 int rc;
1481
1482 rc = of_reconfig_notify(OF_RECONFIG_ATTACH_NODE, np);
1483 if (rc)
1484 return rc;
1485
1486 raw_spin_lock_irqsave(&devtree_lock, flags);
1487 np->sibling = np->parent->child;
1488 np->allnext = of_allnodes;
1489 np->parent->child = np;
1490 of_allnodes = np;
1491 raw_spin_unlock_irqrestore(&devtree_lock, flags);
1492
1493 of_add_proc_dt_entry(np);
1494 return 0;
1495}
1496
1497#ifdef CONFIG_PROC_DEVICETREE
1498static void of_remove_proc_dt_entry(struct device_node *dn)
1499{
1500 proc_remove(dn->pde);
1501}
1502#else
1503static void of_remove_proc_dt_entry(struct device_node *dn)
1504{
1505 return;
1506}
1507#endif
1508
1509
1510
1511
1512
1513
1514
1515int of_detach_node(struct device_node *np)
1516{
1517 struct device_node *parent;
1518 unsigned long flags;
1519 int rc = 0;
1520
1521 rc = of_reconfig_notify(OF_RECONFIG_DETACH_NODE, np);
1522 if (rc)
1523 return rc;
1524
1525 raw_spin_lock_irqsave(&devtree_lock, flags);
1526
1527 if (of_node_check_flag(np, OF_DETACHED)) {
1528
1529 raw_spin_unlock_irqrestore(&devtree_lock, flags);
1530 return rc;
1531 }
1532
1533 parent = np->parent;
1534 if (!parent) {
1535 raw_spin_unlock_irqrestore(&devtree_lock, flags);
1536 return rc;
1537 }
1538
1539 if (of_allnodes == np)
1540 of_allnodes = np->allnext;
1541 else {
1542 struct device_node *prev;
1543 for (prev = of_allnodes;
1544 prev->allnext != np;
1545 prev = prev->allnext)
1546 ;
1547 prev->allnext = np->allnext;
1548 }
1549
1550 if (parent->child == np)
1551 parent->child = np->sibling;
1552 else {
1553 struct device_node *prevsib;
1554 for (prevsib = np->parent->child;
1555 prevsib->sibling != np;
1556 prevsib = prevsib->sibling)
1557 ;
1558 prevsib->sibling = np->sibling;
1559 }
1560
1561 of_node_set_flag(np, OF_DETACHED);
1562 raw_spin_unlock_irqrestore(&devtree_lock, flags);
1563
1564 of_remove_proc_dt_entry(np);
1565 return rc;
1566}
1567#endif
1568
1569static void of_alias_add(struct alias_prop *ap, struct device_node *np,
1570 int id, const char *stem, int stem_len)
1571{
1572 ap->np = np;
1573 ap->id = id;
1574 strncpy(ap->stem, stem, stem_len);
1575 ap->stem[stem_len] = 0;
1576 list_add_tail(&ap->link, &aliases_lookup);
1577 pr_debug("adding DT alias:%s: stem=%s id=%i node=%s\n",
1578 ap->alias, ap->stem, ap->id, of_node_full_name(np));
1579}
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
1592{
1593 struct property *pp;
1594
1595 of_chosen = of_find_node_by_path("/chosen");
1596 if (of_chosen == NULL)
1597 of_chosen = of_find_node_by_path("/chosen@0");
1598 of_aliases = of_find_node_by_path("/aliases");
1599 if (!of_aliases)
1600 return;
1601
1602 for_each_property_of_node(of_aliases, pp) {
1603 const char *start = pp->name;
1604 const char *end = start + strlen(start);
1605 struct device_node *np;
1606 struct alias_prop *ap;
1607 int id, len;
1608
1609
1610 if (!strcmp(pp->name, "name") ||
1611 !strcmp(pp->name, "phandle") ||
1612 !strcmp(pp->name, "linux,phandle"))
1613 continue;
1614
1615 np = of_find_node_by_path(pp->value);
1616 if (!np)
1617 continue;
1618
1619
1620
1621 while (isdigit(*(end-1)) && end > start)
1622 end--;
1623 len = end - start;
1624
1625 if (kstrtoint(end, 10, &id) < 0)
1626 continue;
1627
1628
1629 ap = dt_alloc(sizeof(*ap) + len + 1, 4);
1630 if (!ap)
1631 continue;
1632 ap->alias = start;
1633 of_alias_add(ap, np, id, start, len);
1634 }
1635}
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645int of_alias_get_id(struct device_node *np, const char *stem)
1646{
1647 struct alias_prop *app;
1648 int id = -ENODEV;
1649
1650 mutex_lock(&of_aliases_mutex);
1651 list_for_each_entry(app, &aliases_lookup, link) {
1652 if (strcmp(app->stem, stem) != 0)
1653 continue;
1654
1655 if (np == app->np) {
1656 id = app->id;
1657 break;
1658 }
1659 }
1660 mutex_unlock(&of_aliases_mutex);
1661
1662 return id;
1663}
1664EXPORT_SYMBOL_GPL(of_alias_get_id);
1665
1666const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur,
1667 u32 *pu)
1668{
1669 const void *curv = cur;
1670
1671 if (!prop)
1672 return NULL;
1673
1674 if (!cur) {
1675 curv = prop->value;
1676 goto out_val;
1677 }
1678
1679 curv += sizeof(*cur);
1680 if (curv >= prop->value + prop->length)
1681 return NULL;
1682
1683out_val:
1684 *pu = be32_to_cpup(curv);
1685 return curv;
1686}
1687EXPORT_SYMBOL_GPL(of_prop_next_u32);
1688
1689const char *of_prop_next_string(struct property *prop, const char *cur)
1690{
1691 const void *curv = cur;
1692
1693 if (!prop)
1694 return NULL;
1695
1696 if (!cur)
1697 return prop->value;
1698
1699 curv += strlen(cur) + 1;
1700 if (curv >= prop->value + prop->length)
1701 return NULL;
1702
1703 return curv;
1704}
1705EXPORT_SYMBOL_GPL(of_prop_next_string);
1706