1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include <linux/console.h>
21#include <linux/ctype.h>
22#include <linux/cpu.h>
23#include <linux/module.h>
24#include <linux/of.h>
25#include <linux/of_graph.h>
26#include <linux/spinlock.h>
27#include <linux/slab.h>
28#include <linux/string.h>
29#include <linux/proc_fs.h>
30
31#include "of_private.h"
32
33LIST_HEAD(aliases_lookup);
34
35struct device_node *of_root;
36EXPORT_SYMBOL(of_root);
37struct device_node *of_chosen;
38struct device_node *of_aliases;
39struct device_node *of_stdout;
40static const char *of_stdout_options;
41
42struct kset *of_kset;
43
44
45
46
47
48
49
50DEFINE_MUTEX(of_mutex);
51
52
53
54
55DEFINE_RAW_SPINLOCK(devtree_lock);
56
57int of_n_addr_cells(struct device_node *np)
58{
59 const __be32 *ip;
60
61 do {
62 if (np->parent)
63 np = np->parent;
64 ip = of_get_property(np, "#address-cells", NULL);
65 if (ip)
66 return be32_to_cpup(ip);
67 } while (np->parent);
68
69 return OF_ROOT_NODE_ADDR_CELLS_DEFAULT;
70}
71EXPORT_SYMBOL(of_n_addr_cells);
72
73int of_n_size_cells(struct device_node *np)
74{
75 const __be32 *ip;
76
77 do {
78 if (np->parent)
79 np = np->parent;
80 ip = of_get_property(np, "#size-cells", NULL);
81 if (ip)
82 return be32_to_cpup(ip);
83 } while (np->parent);
84
85 return OF_ROOT_NODE_SIZE_CELLS_DEFAULT;
86}
87EXPORT_SYMBOL(of_n_size_cells);
88
89#ifdef CONFIG_NUMA
90int __weak of_node_to_nid(struct device_node *np)
91{
92 return NUMA_NO_NODE;
93}
94#endif
95
96#ifndef CONFIG_OF_DYNAMIC
97static void of_node_release(struct kobject *kobj)
98{
99
100}
101#endif
102
103struct kobj_type of_node_ktype = {
104 .release = of_node_release,
105};
106
107static ssize_t of_node_property_read(struct file *filp, struct kobject *kobj,
108 struct bin_attribute *bin_attr, char *buf,
109 loff_t offset, size_t count)
110{
111 struct property *pp = container_of(bin_attr, struct property, attr);
112 return memory_read_from_buffer(buf, count, &offset, pp->value, pp->length);
113}
114
115static const char *safe_name(struct kobject *kobj, const char *orig_name)
116{
117 const char *name = orig_name;
118 struct kernfs_node *kn;
119 int i = 0;
120
121
122 while (i < 16 && (kn = sysfs_get_dirent(kobj->sd, name))) {
123 sysfs_put(kn);
124 if (name != orig_name)
125 kfree(name);
126 name = kasprintf(GFP_KERNEL, "%s#%i", orig_name, ++i);
127 }
128
129 if (name != orig_name)
130 pr_warn("device-tree: Duplicate name in %s, renamed to \"%s\"\n",
131 kobject_name(kobj), name);
132 return name;
133}
134
135int __of_add_property_sysfs(struct device_node *np, struct property *pp)
136{
137 int rc;
138
139
140 bool secure = strncmp(pp->name, "security-", 9) == 0;
141
142 if (!IS_ENABLED(CONFIG_SYSFS))
143 return 0;
144
145 if (!of_kset || !of_node_is_attached(np))
146 return 0;
147
148 sysfs_bin_attr_init(&pp->attr);
149 pp->attr.attr.name = safe_name(&np->kobj, pp->name);
150 pp->attr.attr.mode = secure ? S_IRUSR : S_IRUGO;
151 pp->attr.size = secure ? 0 : pp->length;
152 pp->attr.read = of_node_property_read;
153
154 rc = sysfs_create_bin_file(&np->kobj, &pp->attr);
155 WARN(rc, "error adding attribute %s to node %s\n", pp->name, np->full_name);
156 return rc;
157}
158
159int __of_attach_node_sysfs(struct device_node *np)
160{
161 const char *name;
162 struct property *pp;
163 int rc;
164
165 if (!IS_ENABLED(CONFIG_SYSFS))
166 return 0;
167
168 if (!of_kset)
169 return 0;
170
171 np->kobj.kset = of_kset;
172 if (!np->parent) {
173
174 rc = kobject_add(&np->kobj, NULL, "%s",
175 safe_name(&of_kset->kobj, "base"));
176 } else {
177 name = safe_name(&np->parent->kobj, kbasename(np->full_name));
178 if (!name || !name[0])
179 return -EINVAL;
180
181 rc = kobject_add(&np->kobj, &np->parent->kobj, "%s", name);
182 }
183 if (rc)
184 return rc;
185
186 for_each_property_of_node(np, pp)
187 __of_add_property_sysfs(np, pp);
188
189 return 0;
190}
191
192void __init of_core_init(void)
193{
194 struct device_node *np;
195
196
197 mutex_lock(&of_mutex);
198 of_kset = kset_create_and_add("devicetree", NULL, firmware_kobj);
199 if (!of_kset) {
200 mutex_unlock(&of_mutex);
201 pr_err("devicetree: failed to register existing nodes\n");
202 return;
203 }
204 for_each_of_allnodes(np)
205 __of_attach_node_sysfs(np);
206 mutex_unlock(&of_mutex);
207
208
209 if (of_root)
210 proc_symlink("device-tree", NULL, "/sys/firmware/devicetree/base");
211}
212
213static struct property *__of_find_property(const struct device_node *np,
214 const char *name, int *lenp)
215{
216 struct property *pp;
217
218 if (!np)
219 return NULL;
220
221 for (pp = np->properties; pp; pp = pp->next) {
222 if (of_prop_cmp(pp->name, name) == 0) {
223 if (lenp)
224 *lenp = pp->length;
225 break;
226 }
227 }
228
229 return pp;
230}
231
232struct property *of_find_property(const struct device_node *np,
233 const char *name,
234 int *lenp)
235{
236 struct property *pp;
237 unsigned long flags;
238
239 raw_spin_lock_irqsave(&devtree_lock, flags);
240 pp = __of_find_property(np, name, lenp);
241 raw_spin_unlock_irqrestore(&devtree_lock, flags);
242
243 return pp;
244}
245EXPORT_SYMBOL(of_find_property);
246
247struct device_node *__of_find_all_nodes(struct device_node *prev)
248{
249 struct device_node *np;
250 if (!prev) {
251 np = of_root;
252 } else if (prev->child) {
253 np = prev->child;
254 } else {
255
256 np = prev;
257 while (np->parent && !np->sibling)
258 np = np->parent;
259 np = np->sibling;
260 }
261 return np;
262}
263
264
265
266
267
268
269
270
271
272struct device_node *of_find_all_nodes(struct device_node *prev)
273{
274 struct device_node *np;
275 unsigned long flags;
276
277 raw_spin_lock_irqsave(&devtree_lock, flags);
278 np = __of_find_all_nodes(prev);
279 of_node_get(np);
280 of_node_put(prev);
281 raw_spin_unlock_irqrestore(&devtree_lock, flags);
282 return np;
283}
284EXPORT_SYMBOL(of_find_all_nodes);
285
286
287
288
289
290const void *__of_get_property(const struct device_node *np,
291 const char *name, int *lenp)
292{
293 struct property *pp = __of_find_property(np, name, lenp);
294
295 return pp ? pp->value : NULL;
296}
297
298
299
300
301
302const void *of_get_property(const struct device_node *np, const char *name,
303 int *lenp)
304{
305 struct property *pp = of_find_property(np, name, lenp);
306
307 return pp ? pp->value : NULL;
308}
309EXPORT_SYMBOL(of_get_property);
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325bool __weak arch_match_cpu_phys_id(int cpu, u64 phys_id)
326{
327 return (u32)phys_id == cpu;
328}
329
330
331
332
333
334
335static bool __of_find_n_match_cpu_property(struct device_node *cpun,
336 const char *prop_name, int cpu, unsigned int *thread)
337{
338 const __be32 *cell;
339 int ac, prop_len, tid;
340 u64 hwid;
341
342 ac = of_n_addr_cells(cpun);
343 cell = of_get_property(cpun, prop_name, &prop_len);
344 if (!cell || !ac)
345 return false;
346 prop_len /= sizeof(*cell) * ac;
347 for (tid = 0; tid < prop_len; tid++) {
348 hwid = of_read_number(cell, ac);
349 if (arch_match_cpu_phys_id(cpu, hwid)) {
350 if (thread)
351 *thread = tid;
352 return true;
353 }
354 cell += ac;
355 }
356 return false;
357}
358
359
360
361
362
363
364
365bool __weak arch_find_n_match_cpu_physical_id(struct device_node *cpun,
366 int cpu, unsigned int *thread)
367{
368
369
370
371
372 if (IS_ENABLED(CONFIG_PPC) &&
373 __of_find_n_match_cpu_property(cpun,
374 "ibm,ppc-interrupt-server#s",
375 cpu, thread))
376 return true;
377
378 return __of_find_n_match_cpu_property(cpun, "reg", cpu, thread);
379}
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
400{
401 struct device_node *cpun;
402
403 for_each_node_by_type(cpun, "cpu") {
404 if (arch_find_n_match_cpu_physical_id(cpun, cpu, thread))
405 return cpun;
406 }
407 return NULL;
408}
409EXPORT_SYMBOL(of_get_cpu_node);
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441static int __of_device_is_compatible(const struct device_node *device,
442 const char *compat, const char *type, const char *name)
443{
444 struct property *prop;
445 const char *cp;
446 int index = 0, score = 0;
447
448
449 if (compat && compat[0]) {
450 prop = __of_find_property(device, "compatible", NULL);
451 for (cp = of_prop_next_string(prop, NULL); cp;
452 cp = of_prop_next_string(prop, cp), index++) {
453 if (of_compat_cmp(cp, compat, strlen(compat)) == 0) {
454 score = INT_MAX/2 - (index << 2);
455 break;
456 }
457 }
458 if (!score)
459 return 0;
460 }
461
462
463 if (type && type[0]) {
464 if (!device->type || of_node_cmp(type, device->type))
465 return 0;
466 score += 2;
467 }
468
469
470 if (name && name[0]) {
471 if (!device->name || of_node_cmp(name, device->name))
472 return 0;
473 score++;
474 }
475
476 return score;
477}
478
479
480
481
482int of_device_is_compatible(const struct device_node *device,
483 const char *compat)
484{
485 unsigned long flags;
486 int res;
487
488 raw_spin_lock_irqsave(&devtree_lock, flags);
489 res = __of_device_is_compatible(device, compat, NULL, NULL);
490 raw_spin_unlock_irqrestore(&devtree_lock, flags);
491 return res;
492}
493EXPORT_SYMBOL(of_device_is_compatible);
494
495
496
497
498
499
500
501
502int of_machine_is_compatible(const char *compat)
503{
504 struct device_node *root;
505 int rc = 0;
506
507 root = of_find_node_by_path("/");
508 if (root) {
509 rc = of_device_is_compatible(root, compat);
510 of_node_put(root);
511 }
512 return rc;
513}
514EXPORT_SYMBOL(of_machine_is_compatible);
515
516
517
518
519
520
521
522
523
524static bool __of_device_is_available(const struct device_node *device)
525{
526 const char *status;
527 int statlen;
528
529 if (!device)
530 return false;
531
532 status = __of_get_property(device, "status", &statlen);
533 if (status == NULL)
534 return true;
535
536 if (statlen > 0) {
537 if (!strcmp(status, "okay") || !strcmp(status, "ok"))
538 return true;
539 }
540
541 return false;
542}
543
544
545
546
547
548
549
550
551
552bool of_device_is_available(const struct device_node *device)
553{
554 unsigned long flags;
555 bool res;
556
557 raw_spin_lock_irqsave(&devtree_lock, flags);
558 res = __of_device_is_available(device);
559 raw_spin_unlock_irqrestore(&devtree_lock, flags);
560 return res;
561
562}
563EXPORT_SYMBOL(of_device_is_available);
564
565
566
567
568
569
570
571
572
573
574
575
576
577bool of_device_is_big_endian(const struct device_node *device)
578{
579 if (of_property_read_bool(device, "big-endian"))
580 return true;
581 if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN) &&
582 of_property_read_bool(device, "native-endian"))
583 return true;
584 return false;
585}
586EXPORT_SYMBOL(of_device_is_big_endian);
587
588
589
590
591
592
593
594
595struct device_node *of_get_parent(const struct device_node *node)
596{
597 struct device_node *np;
598 unsigned long flags;
599
600 if (!node)
601 return NULL;
602
603 raw_spin_lock_irqsave(&devtree_lock, flags);
604 np = of_node_get(node->parent);
605 raw_spin_unlock_irqrestore(&devtree_lock, flags);
606 return np;
607}
608EXPORT_SYMBOL(of_get_parent);
609
610
611
612
613
614
615
616
617
618
619
620
621struct device_node *of_get_next_parent(struct device_node *node)
622{
623 struct device_node *parent;
624 unsigned long flags;
625
626 if (!node)
627 return NULL;
628
629 raw_spin_lock_irqsave(&devtree_lock, flags);
630 parent = of_node_get(node->parent);
631 of_node_put(node);
632 raw_spin_unlock_irqrestore(&devtree_lock, flags);
633 return parent;
634}
635EXPORT_SYMBOL(of_get_next_parent);
636
637static struct device_node *__of_get_next_child(const struct device_node *node,
638 struct device_node *prev)
639{
640 struct device_node *next;
641
642 if (!node)
643 return NULL;
644
645 next = prev ? prev->sibling : node->child;
646 for (; next; next = next->sibling)
647 if (of_node_get(next))
648 break;
649 of_node_put(prev);
650 return next;
651}
652#define __for_each_child_of_node(parent, child) \
653 for (child = __of_get_next_child(parent, NULL); child != NULL; \
654 child = __of_get_next_child(parent, child))
655
656
657
658
659
660
661
662
663
664
665struct device_node *of_get_next_child(const struct device_node *node,
666 struct device_node *prev)
667{
668 struct device_node *next;
669 unsigned long flags;
670
671 raw_spin_lock_irqsave(&devtree_lock, flags);
672 next = __of_get_next_child(node, prev);
673 raw_spin_unlock_irqrestore(&devtree_lock, flags);
674 return next;
675}
676EXPORT_SYMBOL(of_get_next_child);
677
678
679
680
681
682
683
684
685
686struct device_node *of_get_next_available_child(const struct device_node *node,
687 struct device_node *prev)
688{
689 struct device_node *next;
690 unsigned long flags;
691
692 if (!node)
693 return NULL;
694
695 raw_spin_lock_irqsave(&devtree_lock, flags);
696 next = prev ? prev->sibling : node->child;
697 for (; next; next = next->sibling) {
698 if (!__of_device_is_available(next))
699 continue;
700 if (of_node_get(next))
701 break;
702 }
703 of_node_put(prev);
704 raw_spin_unlock_irqrestore(&devtree_lock, flags);
705 return next;
706}
707EXPORT_SYMBOL(of_get_next_available_child);
708
709
710
711
712
713
714
715
716
717
718
719
720struct device_node *of_get_child_by_name(const struct device_node *node,
721 const char *name)
722{
723 struct device_node *child;
724
725 for_each_child_of_node(node, child)
726 if (child->name && (of_node_cmp(child->name, name) == 0))
727 break;
728 return child;
729}
730EXPORT_SYMBOL(of_get_child_by_name);
731
732static struct device_node *__of_find_node_by_path(struct device_node *parent,
733 const char *path)
734{
735 struct device_node *child;
736 int len;
737
738 len = strcspn(path, "/:");
739 if (!len)
740 return NULL;
741
742 __for_each_child_of_node(parent, child) {
743 const char *name = strrchr(child->full_name, '/');
744 if (WARN(!name, "malformed device_node %s\n", child->full_name))
745 continue;
746 name++;
747 if (strncmp(path, name, len) == 0 && (strlen(name) == len))
748 return child;
749 }
750 return NULL;
751}
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771struct device_node *of_find_node_opts_by_path(const char *path, const char **opts)
772{
773 struct device_node *np = NULL;
774 struct property *pp;
775 unsigned long flags;
776 const char *separator = strchr(path, ':');
777
778 if (opts)
779 *opts = separator ? separator + 1 : NULL;
780
781 if (strcmp(path, "/") == 0)
782 return of_node_get(of_root);
783
784
785 if (*path != '/') {
786 int len;
787 const char *p = separator;
788
789 if (!p)
790 p = strchrnul(path, '/');
791 len = p - path;
792
793
794 if (!of_aliases)
795 return NULL;
796
797 for_each_property_of_node(of_aliases, pp) {
798 if (strlen(pp->name) == len && !strncmp(pp->name, path, len)) {
799 np = of_find_node_by_path(pp->value);
800 break;
801 }
802 }
803 if (!np)
804 return NULL;
805 path = p;
806 }
807
808
809 raw_spin_lock_irqsave(&devtree_lock, flags);
810 if (!np)
811 np = of_node_get(of_root);
812 while (np && *path == '/') {
813 path++;
814 np = __of_find_node_by_path(np, path);
815 path = strchrnul(path, '/');
816 if (separator && separator < path)
817 break;
818 }
819 raw_spin_unlock_irqrestore(&devtree_lock, flags);
820 return np;
821}
822EXPORT_SYMBOL(of_find_node_opts_by_path);
823
824
825
826
827
828
829
830
831
832
833
834
835struct device_node *of_find_node_by_name(struct device_node *from,
836 const char *name)
837{
838 struct device_node *np;
839 unsigned long flags;
840
841 raw_spin_lock_irqsave(&devtree_lock, flags);
842 for_each_of_allnodes_from(from, np)
843 if (np->name && (of_node_cmp(np->name, name) == 0)
844 && of_node_get(np))
845 break;
846 of_node_put(from);
847 raw_spin_unlock_irqrestore(&devtree_lock, flags);
848 return np;
849}
850EXPORT_SYMBOL(of_find_node_by_name);
851
852
853
854
855
856
857
858
859
860
861
862
863
864struct device_node *of_find_node_by_type(struct device_node *from,
865 const char *type)
866{
867 struct device_node *np;
868 unsigned long flags;
869
870 raw_spin_lock_irqsave(&devtree_lock, flags);
871 for_each_of_allnodes_from(from, np)
872 if (np->type && (of_node_cmp(np->type, type) == 0)
873 && of_node_get(np))
874 break;
875 of_node_put(from);
876 raw_spin_unlock_irqrestore(&devtree_lock, flags);
877 return np;
878}
879EXPORT_SYMBOL(of_find_node_by_type);
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895struct device_node *of_find_compatible_node(struct device_node *from,
896 const char *type, const char *compatible)
897{
898 struct device_node *np;
899 unsigned long flags;
900
901 raw_spin_lock_irqsave(&devtree_lock, flags);
902 for_each_of_allnodes_from(from, np)
903 if (__of_device_is_compatible(np, compatible, type, NULL) &&
904 of_node_get(np))
905 break;
906 of_node_put(from);
907 raw_spin_unlock_irqrestore(&devtree_lock, flags);
908 return np;
909}
910EXPORT_SYMBOL(of_find_compatible_node);
911
912
913
914
915
916
917
918
919
920
921
922
923
924struct device_node *of_find_node_with_property(struct device_node *from,
925 const char *prop_name)
926{
927 struct device_node *np;
928 struct property *pp;
929 unsigned long flags;
930
931 raw_spin_lock_irqsave(&devtree_lock, flags);
932 for_each_of_allnodes_from(from, np) {
933 for (pp = np->properties; pp; pp = pp->next) {
934 if (of_prop_cmp(pp->name, prop_name) == 0) {
935 of_node_get(np);
936 goto out;
937 }
938 }
939 }
940out:
941 of_node_put(from);
942 raw_spin_unlock_irqrestore(&devtree_lock, flags);
943 return np;
944}
945EXPORT_SYMBOL(of_find_node_with_property);
946
947static
948const struct of_device_id *__of_match_node(const struct of_device_id *matches,
949 const struct device_node *node)
950{
951 const struct of_device_id *best_match = NULL;
952 int score, best_score = 0;
953
954 if (!matches)
955 return NULL;
956
957 for (; matches->name[0] || matches->type[0] || matches->compatible[0]; matches++) {
958 score = __of_device_is_compatible(node, matches->compatible,
959 matches->type, matches->name);
960 if (score > best_score) {
961 best_match = matches;
962 best_score = score;
963 }
964 }
965
966 return best_match;
967}
968
969
970
971
972
973
974
975
976const struct of_device_id *of_match_node(const struct of_device_id *matches,
977 const struct device_node *node)
978{
979 const struct of_device_id *match;
980 unsigned long flags;
981
982 raw_spin_lock_irqsave(&devtree_lock, flags);
983 match = __of_match_node(matches, node);
984 raw_spin_unlock_irqrestore(&devtree_lock, flags);
985 return match;
986}
987EXPORT_SYMBOL(of_match_node);
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002struct device_node *of_find_matching_node_and_match(struct device_node *from,
1003 const struct of_device_id *matches,
1004 const struct of_device_id **match)
1005{
1006 struct device_node *np;
1007 const struct of_device_id *m;
1008 unsigned long flags;
1009
1010 if (match)
1011 *match = NULL;
1012
1013 raw_spin_lock_irqsave(&devtree_lock, flags);
1014 for_each_of_allnodes_from(from, np) {
1015 m = __of_match_node(matches, np);
1016 if (m && of_node_get(np)) {
1017 if (match)
1018 *match = m;
1019 break;
1020 }
1021 }
1022 of_node_put(from);
1023 raw_spin_unlock_irqrestore(&devtree_lock, flags);
1024 return np;
1025}
1026EXPORT_SYMBOL(of_find_matching_node_and_match);
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041int of_modalias_node(struct device_node *node, char *modalias, int len)
1042{
1043 const char *compatible, *p;
1044 int cplen;
1045
1046 compatible = of_get_property(node, "compatible", &cplen);
1047 if (!compatible || strlen(compatible) > cplen)
1048 return -ENODEV;
1049 p = strchr(compatible, ',');
1050 strlcpy(modalias, p ? p + 1 : compatible, len);
1051 return 0;
1052}
1053EXPORT_SYMBOL_GPL(of_modalias_node);
1054
1055
1056
1057
1058
1059
1060
1061
1062struct device_node *of_find_node_by_phandle(phandle handle)
1063{
1064 struct device_node *np;
1065 unsigned long flags;
1066
1067 if (!handle)
1068 return NULL;
1069
1070 raw_spin_lock_irqsave(&devtree_lock, flags);
1071 for_each_of_allnodes(np)
1072 if (np->phandle == handle)
1073 break;
1074 of_node_get(np);
1075 raw_spin_unlock_irqrestore(&devtree_lock, flags);
1076 return np;
1077}
1078EXPORT_SYMBOL(of_find_node_by_phandle);
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092int of_property_count_elems_of_size(const struct device_node *np,
1093 const char *propname, int elem_size)
1094{
1095 struct property *prop = of_find_property(np, propname, NULL);
1096
1097 if (!prop)
1098 return -EINVAL;
1099 if (!prop->value)
1100 return -ENODATA;
1101
1102 if (prop->length % elem_size != 0) {
1103 pr_err("size of %s in node %s is not a multiple of %d\n",
1104 propname, np->full_name, elem_size);
1105 return -EINVAL;
1106 }
1107
1108 return prop->length / elem_size;
1109}
1110EXPORT_SYMBOL_GPL(of_property_count_elems_of_size);
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125static void *of_find_property_value_of_size(const struct device_node *np,
1126 const char *propname, u32 len)
1127{
1128 struct property *prop = of_find_property(np, propname, NULL);
1129
1130 if (!prop)
1131 return ERR_PTR(-EINVAL);
1132 if (!prop->value)
1133 return ERR_PTR(-ENODATA);
1134 if (len > prop->length)
1135 return ERR_PTR(-EOVERFLOW);
1136
1137 return prop->value;
1138}
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155int of_property_read_u32_index(const struct device_node *np,
1156 const char *propname,
1157 u32 index, u32 *out_value)
1158{
1159 const u32 *val = of_find_property_value_of_size(np, propname,
1160 ((index + 1) * sizeof(*out_value)));
1161
1162 if (IS_ERR(val))
1163 return PTR_ERR(val);
1164
1165 *out_value = be32_to_cpup(((__be32 *)val) + index);
1166 return 0;
1167}
1168EXPORT_SYMBOL_GPL(of_property_read_u32_index);
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188int of_property_read_u8_array(const struct device_node *np,
1189 const char *propname, u8 *out_values, size_t sz)
1190{
1191 const u8 *val = of_find_property_value_of_size(np, propname,
1192 (sz * sizeof(*out_values)));
1193
1194 if (IS_ERR(val))
1195 return PTR_ERR(val);
1196
1197 while (sz--)
1198 *out_values++ = *val++;
1199 return 0;
1200}
1201EXPORT_SYMBOL_GPL(of_property_read_u8_array);
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221int of_property_read_u16_array(const struct device_node *np,
1222 const char *propname, u16 *out_values, size_t sz)
1223{
1224 const __be16 *val = of_find_property_value_of_size(np, propname,
1225 (sz * sizeof(*out_values)));
1226
1227 if (IS_ERR(val))
1228 return PTR_ERR(val);
1229
1230 while (sz--)
1231 *out_values++ = be16_to_cpup(val++);
1232 return 0;
1233}
1234EXPORT_SYMBOL_GPL(of_property_read_u16_array);
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252int of_property_read_u32_array(const struct device_node *np,
1253 const char *propname, u32 *out_values,
1254 size_t sz)
1255{
1256 const __be32 *val = of_find_property_value_of_size(np, propname,
1257 (sz * sizeof(*out_values)));
1258
1259 if (IS_ERR(val))
1260 return PTR_ERR(val);
1261
1262 while (sz--)
1263 *out_values++ = be32_to_cpup(val++);
1264 return 0;
1265}
1266EXPORT_SYMBOL_GPL(of_property_read_u32_array);
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281int of_property_read_u64(const struct device_node *np, const char *propname,
1282 u64 *out_value)
1283{
1284 const __be32 *val = of_find_property_value_of_size(np, propname,
1285 sizeof(*out_value));
1286
1287 if (IS_ERR(val))
1288 return PTR_ERR(val);
1289
1290 *out_value = of_read_number(val, 2);
1291 return 0;
1292}
1293EXPORT_SYMBOL_GPL(of_property_read_u64);
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311int of_property_read_u64_array(const struct device_node *np,
1312 const char *propname, u64 *out_values,
1313 size_t sz)
1314{
1315 const __be32 *val = of_find_property_value_of_size(np, propname,
1316 (sz * sizeof(*out_values)));
1317
1318 if (IS_ERR(val))
1319 return PTR_ERR(val);
1320
1321 while (sz--) {
1322 *out_values++ = of_read_number(val, 2);
1323 val += 2;
1324 }
1325 return 0;
1326}
1327EXPORT_SYMBOL_GPL(of_property_read_u64_array);
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344int of_property_read_string(const struct device_node *np, const char *propname,
1345 const char **out_string)
1346{
1347 const struct property *prop = of_find_property(np, propname, NULL);
1348 if (!prop)
1349 return -EINVAL;
1350 if (!prop->value)
1351 return -ENODATA;
1352 if (strnlen(prop->value, prop->length) >= prop->length)
1353 return -EILSEQ;
1354 *out_string = prop->value;
1355 return 0;
1356}
1357EXPORT_SYMBOL_GPL(of_property_read_string);
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368int of_property_match_string(const struct device_node *np, const char *propname,
1369 const char *string)
1370{
1371 const struct property *prop = of_find_property(np, propname, NULL);
1372 size_t l;
1373 int i;
1374 const char *p, *end;
1375
1376 if (!prop)
1377 return -EINVAL;
1378 if (!prop->value)
1379 return -ENODATA;
1380
1381 p = prop->value;
1382 end = p + prop->length;
1383
1384 for (i = 0; p < end; i++, p += l) {
1385 l = strnlen(p, end - p) + 1;
1386 if (p + l > end)
1387 return -EILSEQ;
1388 pr_debug("comparing %s with %s\n", string, p);
1389 if (strcmp(string, p) == 0)
1390 return i;
1391 }
1392 return -ENODATA;
1393}
1394EXPORT_SYMBOL_GPL(of_property_match_string);
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407int of_property_read_string_helper(const struct device_node *np,
1408 const char *propname, const char **out_strs,
1409 size_t sz, int skip)
1410{
1411 const struct property *prop = of_find_property(np, propname, NULL);
1412 int l = 0, i = 0;
1413 const char *p, *end;
1414
1415 if (!prop)
1416 return -EINVAL;
1417 if (!prop->value)
1418 return -ENODATA;
1419 p = prop->value;
1420 end = p + prop->length;
1421
1422 for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l) {
1423 l = strnlen(p, end - p) + 1;
1424 if (p + l > end)
1425 return -EILSEQ;
1426 if (out_strs && i >= skip)
1427 *out_strs++ = p;
1428 }
1429 i -= skip;
1430 return i <= 0 ? -ENODATA : i;
1431}
1432EXPORT_SYMBOL_GPL(of_property_read_string_helper);
1433
1434void of_print_phandle_args(const char *msg, const struct of_phandle_args *args)
1435{
1436 int i;
1437 printk("%s %s", msg, of_node_full_name(args->np));
1438 for (i = 0; i < args->args_count; i++)
1439 printk(i ? ",%08x" : ":%08x", args->args[i]);
1440 printk("\n");
1441}
1442
1443static int __of_parse_phandle_with_args(const struct device_node *np,
1444 const char *list_name,
1445 const char *cells_name,
1446 int cell_count, int index,
1447 struct of_phandle_args *out_args)
1448{
1449 const __be32 *list, *list_end;
1450 int rc = 0, size, cur_index = 0;
1451 uint32_t count = 0;
1452 struct device_node *node = NULL;
1453 phandle phandle;
1454
1455
1456 list = of_get_property(np, list_name, &size);
1457 if (!list)
1458 return -ENOENT;
1459 list_end = list + size / sizeof(*list);
1460
1461
1462 while (list < list_end) {
1463 rc = -EINVAL;
1464 count = 0;
1465
1466
1467
1468
1469
1470 phandle = be32_to_cpup(list++);
1471 if (phandle) {
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481 if (cells_name || cur_index == index) {
1482 node = of_find_node_by_phandle(phandle);
1483 if (!node) {
1484 pr_err("%s: could not find phandle\n",
1485 np->full_name);
1486 goto err;
1487 }
1488 }
1489
1490 if (cells_name) {
1491 if (of_property_read_u32(node, cells_name,
1492 &count)) {
1493 pr_err("%s: could not get %s for %s\n",
1494 np->full_name, cells_name,
1495 node->full_name);
1496 goto err;
1497 }
1498 } else {
1499 count = cell_count;
1500 }
1501
1502
1503
1504
1505
1506 if (list + count > list_end) {
1507 pr_err("%s: arguments longer than property\n",
1508 np->full_name);
1509 goto err;
1510 }
1511 }
1512
1513
1514
1515
1516
1517
1518
1519 rc = -ENOENT;
1520 if (cur_index == index) {
1521 if (!phandle)
1522 goto err;
1523
1524 if (out_args) {
1525 int i;
1526 if (WARN_ON(count > MAX_PHANDLE_ARGS))
1527 count = MAX_PHANDLE_ARGS;
1528 out_args->np = node;
1529 out_args->args_count = count;
1530 for (i = 0; i < count; i++)
1531 out_args->args[i] = be32_to_cpup(list++);
1532 } else {
1533 of_node_put(node);
1534 }
1535
1536
1537 return 0;
1538 }
1539
1540 of_node_put(node);
1541 node = NULL;
1542 list += count;
1543 cur_index++;
1544 }
1545
1546
1547
1548
1549
1550
1551
1552 rc = index < 0 ? cur_index : -ENOENT;
1553 err:
1554 if (node)
1555 of_node_put(node);
1556 return rc;
1557}
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569struct device_node *of_parse_phandle(const struct device_node *np,
1570 const char *phandle_name, int index)
1571{
1572 struct of_phandle_args args;
1573
1574 if (index < 0)
1575 return NULL;
1576
1577 if (__of_parse_phandle_with_args(np, phandle_name, NULL, 0,
1578 index, &args))
1579 return NULL;
1580
1581 return args.np;
1582}
1583EXPORT_SYMBOL(of_parse_phandle);
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617int of_parse_phandle_with_args(const struct device_node *np, const char *list_name,
1618 const char *cells_name, int index,
1619 struct of_phandle_args *out_args)
1620{
1621 if (index < 0)
1622 return -EINVAL;
1623 return __of_parse_phandle_with_args(np, list_name, cells_name, 0,
1624 index, out_args);
1625}
1626EXPORT_SYMBOL(of_parse_phandle_with_args);
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658int of_parse_phandle_with_fixed_args(const struct device_node *np,
1659 const char *list_name, int cell_count,
1660 int index, struct of_phandle_args *out_args)
1661{
1662 if (index < 0)
1663 return -EINVAL;
1664 return __of_parse_phandle_with_args(np, list_name, NULL, cell_count,
1665 index, out_args);
1666}
1667EXPORT_SYMBOL(of_parse_phandle_with_fixed_args);
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684int of_count_phandle_with_args(const struct device_node *np, const char *list_name,
1685 const char *cells_name)
1686{
1687 return __of_parse_phandle_with_args(np, list_name, cells_name, 0, -1,
1688 NULL);
1689}
1690EXPORT_SYMBOL(of_count_phandle_with_args);
1691
1692
1693
1694
1695int __of_add_property(struct device_node *np, struct property *prop)
1696{
1697 struct property **next;
1698
1699 prop->next = NULL;
1700 next = &np->properties;
1701 while (*next) {
1702 if (strcmp(prop->name, (*next)->name) == 0)
1703
1704 return -EEXIST;
1705
1706 next = &(*next)->next;
1707 }
1708 *next = prop;
1709
1710 return 0;
1711}
1712
1713
1714
1715
1716int of_add_property(struct device_node *np, struct property *prop)
1717{
1718 unsigned long flags;
1719 int rc;
1720
1721 mutex_lock(&of_mutex);
1722
1723 raw_spin_lock_irqsave(&devtree_lock, flags);
1724 rc = __of_add_property(np, prop);
1725 raw_spin_unlock_irqrestore(&devtree_lock, flags);
1726
1727 if (!rc)
1728 __of_add_property_sysfs(np, prop);
1729
1730 mutex_unlock(&of_mutex);
1731
1732 if (!rc)
1733 of_property_notify(OF_RECONFIG_ADD_PROPERTY, np, prop, NULL);
1734
1735 return rc;
1736}
1737
1738int __of_remove_property(struct device_node *np, struct property *prop)
1739{
1740 struct property **next;
1741
1742 for (next = &np->properties; *next; next = &(*next)->next) {
1743 if (*next == prop)
1744 break;
1745 }
1746 if (*next == NULL)
1747 return -ENODEV;
1748
1749
1750 *next = prop->next;
1751 prop->next = np->deadprops;
1752 np->deadprops = prop;
1753
1754 return 0;
1755}
1756
1757void __of_remove_property_sysfs(struct device_node *np, struct property *prop)
1758{
1759 if (!IS_ENABLED(CONFIG_SYSFS))
1760 return;
1761
1762
1763 if (of_kset && of_node_is_attached(np))
1764 sysfs_remove_bin_file(&np->kobj, &prop->attr);
1765}
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775int of_remove_property(struct device_node *np, struct property *prop)
1776{
1777 unsigned long flags;
1778 int rc;
1779
1780 mutex_lock(&of_mutex);
1781
1782 raw_spin_lock_irqsave(&devtree_lock, flags);
1783 rc = __of_remove_property(np, prop);
1784 raw_spin_unlock_irqrestore(&devtree_lock, flags);
1785
1786 if (!rc)
1787 __of_remove_property_sysfs(np, prop);
1788
1789 mutex_unlock(&of_mutex);
1790
1791 if (!rc)
1792 of_property_notify(OF_RECONFIG_REMOVE_PROPERTY, np, prop, NULL);
1793
1794 return rc;
1795}
1796
1797int __of_update_property(struct device_node *np, struct property *newprop,
1798 struct property **oldpropp)
1799{
1800 struct property **next, *oldprop;
1801
1802 for (next = &np->properties; *next; next = &(*next)->next) {
1803 if (of_prop_cmp((*next)->name, newprop->name) == 0)
1804 break;
1805 }
1806 *oldpropp = oldprop = *next;
1807
1808 if (oldprop) {
1809
1810 newprop->next = oldprop->next;
1811 *next = newprop;
1812 oldprop->next = np->deadprops;
1813 np->deadprops = oldprop;
1814 } else {
1815
1816 newprop->next = NULL;
1817 *next = newprop;
1818 }
1819
1820 return 0;
1821}
1822
1823void __of_update_property_sysfs(struct device_node *np, struct property *newprop,
1824 struct property *oldprop)
1825{
1826 if (!IS_ENABLED(CONFIG_SYSFS))
1827 return;
1828
1829
1830 if (!of_kset)
1831 return;
1832
1833 if (oldprop)
1834 sysfs_remove_bin_file(&np->kobj, &oldprop->attr);
1835 __of_add_property_sysfs(np, newprop);
1836}
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847int of_update_property(struct device_node *np, struct property *newprop)
1848{
1849 struct property *oldprop;
1850 unsigned long flags;
1851 int rc;
1852
1853 if (!newprop->name)
1854 return -EINVAL;
1855
1856 mutex_lock(&of_mutex);
1857
1858 raw_spin_lock_irqsave(&devtree_lock, flags);
1859 rc = __of_update_property(np, newprop, &oldprop);
1860 raw_spin_unlock_irqrestore(&devtree_lock, flags);
1861
1862 if (!rc)
1863 __of_update_property_sysfs(np, newprop, oldprop);
1864
1865 mutex_unlock(&of_mutex);
1866
1867 if (!rc)
1868 of_property_notify(OF_RECONFIG_UPDATE_PROPERTY, np, newprop, oldprop);
1869
1870 return rc;
1871}
1872
1873static void of_alias_add(struct alias_prop *ap, struct device_node *np,
1874 int id, const char *stem, int stem_len)
1875{
1876 ap->np = np;
1877 ap->id = id;
1878 strncpy(ap->stem, stem, stem_len);
1879 ap->stem[stem_len] = 0;
1880 list_add_tail(&ap->link, &aliases_lookup);
1881 pr_debug("adding DT alias:%s: stem=%s id=%i node=%s\n",
1882 ap->alias, ap->stem, ap->id, of_node_full_name(np));
1883}
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
1896{
1897 struct property *pp;
1898
1899 of_aliases = of_find_node_by_path("/aliases");
1900 of_chosen = of_find_node_by_path("/chosen");
1901 if (of_chosen == NULL)
1902 of_chosen = of_find_node_by_path("/chosen@0");
1903
1904 if (of_chosen) {
1905
1906 const char *name = of_get_property(of_chosen, "stdout-path", NULL);
1907 if (!name)
1908 name = of_get_property(of_chosen, "linux,stdout-path", NULL);
1909 if (IS_ENABLED(CONFIG_PPC) && !name)
1910 name = of_get_property(of_aliases, "stdout", NULL);
1911 if (name)
1912 of_stdout = of_find_node_opts_by_path(name, &of_stdout_options);
1913 }
1914
1915 if (!of_aliases)
1916 return;
1917
1918 for_each_property_of_node(of_aliases, pp) {
1919 const char *start = pp->name;
1920 const char *end = start + strlen(start);
1921 struct device_node *np;
1922 struct alias_prop *ap;
1923 int id, len;
1924
1925
1926 if (!strcmp(pp->name, "name") ||
1927 !strcmp(pp->name, "phandle") ||
1928 !strcmp(pp->name, "linux,phandle"))
1929 continue;
1930
1931 np = of_find_node_by_path(pp->value);
1932 if (!np)
1933 continue;
1934
1935
1936
1937 while (isdigit(*(end-1)) && end > start)
1938 end--;
1939 len = end - start;
1940
1941 if (kstrtoint(end, 10, &id) < 0)
1942 continue;
1943
1944
1945 ap = dt_alloc(sizeof(*ap) + len + 1, 4);
1946 if (!ap)
1947 continue;
1948 memset(ap, 0, sizeof(*ap) + len + 1);
1949 ap->alias = start;
1950 of_alias_add(ap, np, id, start, len);
1951 }
1952}
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962int of_alias_get_id(struct device_node *np, const char *stem)
1963{
1964 struct alias_prop *app;
1965 int id = -ENODEV;
1966
1967 mutex_lock(&of_mutex);
1968 list_for_each_entry(app, &aliases_lookup, link) {
1969 if (strcmp(app->stem, stem) != 0)
1970 continue;
1971
1972 if (np == app->np) {
1973 id = app->id;
1974 break;
1975 }
1976 }
1977 mutex_unlock(&of_mutex);
1978
1979 return id;
1980}
1981EXPORT_SYMBOL_GPL(of_alias_get_id);
1982
1983
1984
1985
1986
1987
1988
1989
1990int of_alias_get_highest_id(const char *stem)
1991{
1992 struct alias_prop *app;
1993 int id = -ENODEV;
1994
1995 mutex_lock(&of_mutex);
1996 list_for_each_entry(app, &aliases_lookup, link) {
1997 if (strcmp(app->stem, stem) != 0)
1998 continue;
1999
2000 if (app->id > id)
2001 id = app->id;
2002 }
2003 mutex_unlock(&of_mutex);
2004
2005 return id;
2006}
2007EXPORT_SYMBOL_GPL(of_alias_get_highest_id);
2008
2009const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur,
2010 u32 *pu)
2011{
2012 const void *curv = cur;
2013
2014 if (!prop)
2015 return NULL;
2016
2017 if (!cur) {
2018 curv = prop->value;
2019 goto out_val;
2020 }
2021
2022 curv += sizeof(*cur);
2023 if (curv >= prop->value + prop->length)
2024 return NULL;
2025
2026out_val:
2027 *pu = be32_to_cpup(curv);
2028 return curv;
2029}
2030EXPORT_SYMBOL_GPL(of_prop_next_u32);
2031
2032const char *of_prop_next_string(struct property *prop, const char *cur)
2033{
2034 const void *curv = cur;
2035
2036 if (!prop)
2037 return NULL;
2038
2039 if (!cur)
2040 return prop->value;
2041
2042 curv += strlen(cur) + 1;
2043 if (curv >= prop->value + prop->length)
2044 return NULL;
2045
2046 return curv;
2047}
2048EXPORT_SYMBOL_GPL(of_prop_next_string);
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060bool of_console_check(struct device_node *dn, char *name, int index)
2061{
2062 if (!dn || dn != of_stdout || console_set_on_cmdline)
2063 return false;
2064 return !add_preferred_console(name, index,
2065 kstrdup(of_stdout_options, GFP_KERNEL));
2066}
2067EXPORT_SYMBOL_GPL(of_console_check);
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077struct device_node *of_find_next_cache_node(const struct device_node *np)
2078{
2079 struct device_node *child;
2080 const phandle *handle;
2081
2082 handle = of_get_property(np, "l2-cache", NULL);
2083 if (!handle)
2084 handle = of_get_property(np, "next-level-cache", NULL);
2085
2086 if (handle)
2087 return of_find_node_by_phandle(be32_to_cpup(handle));
2088
2089
2090
2091
2092 if (!strcmp(np->type, "cpu"))
2093 for_each_child_of_node(np, child)
2094 if (!strcmp(child->type, "cache"))
2095 return child;
2096
2097 return NULL;
2098}
2099
2100
2101
2102
2103
2104
2105
2106
2107int of_graph_parse_endpoint(const struct device_node *node,
2108 struct of_endpoint *endpoint)
2109{
2110 struct device_node *port_node = of_get_parent(node);
2111
2112 WARN_ONCE(!port_node, "%s(): endpoint %s has no parent node\n",
2113 __func__, node->full_name);
2114
2115 memset(endpoint, 0, sizeof(*endpoint));
2116
2117 endpoint->local_node = node;
2118
2119
2120
2121
2122 of_property_read_u32(port_node, "reg", &endpoint->port);
2123 of_property_read_u32(node, "reg", &endpoint->id);
2124
2125 of_node_put(port_node);
2126
2127 return 0;
2128}
2129EXPORT_SYMBOL(of_graph_parse_endpoint);
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139struct device_node *of_graph_get_port_by_id(struct device_node *parent, u32 id)
2140{
2141 struct device_node *node, *port;
2142
2143 node = of_get_child_by_name(parent, "ports");
2144 if (node)
2145 parent = node;
2146
2147 for_each_child_of_node(parent, port) {
2148 u32 port_id = 0;
2149
2150 if (of_node_cmp(port->name, "port") != 0)
2151 continue;
2152 of_property_read_u32(port, "reg", &port_id);
2153 if (id == port_id)
2154 break;
2155 }
2156
2157 of_node_put(node);
2158
2159 return port;
2160}
2161EXPORT_SYMBOL(of_graph_get_port_by_id);
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
2172 struct device_node *prev)
2173{
2174 struct device_node *endpoint;
2175 struct device_node *port;
2176
2177 if (!parent)
2178 return NULL;
2179
2180
2181
2182
2183
2184
2185 if (!prev) {
2186 struct device_node *node;
2187
2188 node = of_get_child_by_name(parent, "ports");
2189 if (node)
2190 parent = node;
2191
2192 port = of_get_child_by_name(parent, "port");
2193 of_node_put(node);
2194
2195 if (!port) {
2196 pr_err("%s(): no port node found in %s\n",
2197 __func__, parent->full_name);
2198 return NULL;
2199 }
2200 } else {
2201 port = of_get_parent(prev);
2202 if (WARN_ONCE(!port, "%s(): endpoint %s has no parent node\n",
2203 __func__, prev->full_name))
2204 return NULL;
2205 }
2206
2207 while (1) {
2208
2209
2210
2211
2212
2213 endpoint = of_get_next_child(port, prev);
2214 if (endpoint) {
2215 of_node_put(port);
2216 return endpoint;
2217 }
2218
2219
2220 prev = NULL;
2221
2222 do {
2223 port = of_get_next_child(parent, port);
2224 if (!port)
2225 return NULL;
2226 } while (of_node_cmp(port->name, "port"));
2227 }
2228}
2229EXPORT_SYMBOL(of_graph_get_next_endpoint);
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241struct device_node *of_graph_get_endpoint_by_regs(
2242 const struct device_node *parent, int port_reg, int reg)
2243{
2244 struct of_endpoint endpoint;
2245 struct device_node *node, *prev_node = NULL;
2246
2247 while (1) {
2248 node = of_graph_get_next_endpoint(parent, prev_node);
2249 of_node_put(prev_node);
2250 if (!node)
2251 break;
2252
2253 of_graph_parse_endpoint(node, &endpoint);
2254 if (((port_reg == -1) || (endpoint.port == port_reg)) &&
2255 ((reg == -1) || (endpoint.id == reg)))
2256 return node;
2257
2258 prev_node = node;
2259 }
2260
2261 return NULL;
2262}
2263EXPORT_SYMBOL(of_graph_get_endpoint_by_regs);
2264
2265
2266
2267
2268
2269
2270
2271
2272struct device_node *of_graph_get_remote_port_parent(
2273 const struct device_node *node)
2274{
2275 struct device_node *np;
2276 unsigned int depth;
2277
2278
2279 np = of_parse_phandle(node, "remote-endpoint", 0);
2280
2281
2282 for (depth = 3; depth && np; depth--) {
2283 np = of_get_next_parent(np);
2284 if (depth == 2 && of_node_cmp(np->name, "ports"))
2285 break;
2286 }
2287 return np;
2288}
2289EXPORT_SYMBOL(of_graph_get_remote_port_parent);
2290
2291
2292
2293
2294
2295
2296
2297
2298struct device_node *of_graph_get_remote_port(const struct device_node *node)
2299{
2300 struct device_node *np;
2301
2302
2303 np = of_parse_phandle(node, "remote-endpoint", 0);
2304 if (!np)
2305 return NULL;
2306 return of_get_next_parent(np);
2307}
2308EXPORT_SYMBOL(of_graph_get_remote_port);
2309