1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26#define pr_fmt(fmt) "OF: " fmt
27
28#include <linux/of.h>
29#include <linux/of_device.h>
30#include <linux/of_graph.h>
31#include <linux/string.h>
32
33#include "of_private.h"
34
35
36
37
38
39
40
41
42
43
44
45
46
47int of_property_count_elems_of_size(const struct device_node *np,
48 const char *propname, int elem_size)
49{
50 struct property *prop = of_find_property(np, propname, NULL);
51
52 if (!prop)
53 return -EINVAL;
54 if (!prop->value)
55 return -ENODATA;
56
57 if (prop->length % elem_size != 0) {
58 pr_err("size of %s in node %pOF is not a multiple of %d\n",
59 propname, np, elem_size);
60 return -EINVAL;
61 }
62
63 return prop->length / elem_size;
64}
65EXPORT_SYMBOL_GPL(of_property_count_elems_of_size);
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82static void *of_find_property_value_of_size(const struct device_node *np,
83 const char *propname, u32 min, u32 max, size_t *len)
84{
85 struct property *prop = of_find_property(np, propname, NULL);
86
87 if (!prop)
88 return ERR_PTR(-EINVAL);
89 if (!prop->value)
90 return ERR_PTR(-ENODATA);
91 if (prop->length < min)
92 return ERR_PTR(-EOVERFLOW);
93 if (max && prop->length > max)
94 return ERR_PTR(-EOVERFLOW);
95
96 if (len)
97 *len = prop->length;
98
99 return prop->value;
100}
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117int of_property_read_u32_index(const struct device_node *np,
118 const char *propname,
119 u32 index, u32 *out_value)
120{
121 const u32 *val = of_find_property_value_of_size(np, propname,
122 ((index + 1) * sizeof(*out_value)),
123 0,
124 NULL);
125
126 if (IS_ERR(val))
127 return PTR_ERR(val);
128
129 *out_value = be32_to_cpup(((__be32 *)val) + index);
130 return 0;
131}
132EXPORT_SYMBOL_GPL(of_property_read_u32_index);
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149int of_property_read_u64_index(const struct device_node *np,
150 const char *propname,
151 u32 index, u64 *out_value)
152{
153 const u64 *val = of_find_property_value_of_size(np, propname,
154 ((index + 1) * sizeof(*out_value)),
155 0, NULL);
156
157 if (IS_ERR(val))
158 return PTR_ERR(val);
159
160 *out_value = be64_to_cpup(((__be64 *)val) + index);
161 return 0;
162}
163EXPORT_SYMBOL_GPL(of_property_read_u64_index);
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187int of_property_read_variable_u8_array(const struct device_node *np,
188 const char *propname, u8 *out_values,
189 size_t sz_min, size_t sz_max)
190{
191 size_t sz, count;
192 const u8 *val = of_find_property_value_of_size(np, propname,
193 (sz_min * sizeof(*out_values)),
194 (sz_max * sizeof(*out_values)),
195 &sz);
196
197 if (IS_ERR(val))
198 return PTR_ERR(val);
199
200 if (!sz_max)
201 sz = sz_min;
202 else
203 sz /= sizeof(*out_values);
204
205 count = sz;
206 while (count--)
207 *out_values++ = *val++;
208
209 return sz;
210}
211EXPORT_SYMBOL_GPL(of_property_read_variable_u8_array);
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235int of_property_read_variable_u16_array(const struct device_node *np,
236 const char *propname, u16 *out_values,
237 size_t sz_min, size_t sz_max)
238{
239 size_t sz, count;
240 const __be16 *val = of_find_property_value_of_size(np, propname,
241 (sz_min * sizeof(*out_values)),
242 (sz_max * sizeof(*out_values)),
243 &sz);
244
245 if (IS_ERR(val))
246 return PTR_ERR(val);
247
248 if (!sz_max)
249 sz = sz_min;
250 else
251 sz /= sizeof(*out_values);
252
253 count = sz;
254 while (count--)
255 *out_values++ = be16_to_cpup(val++);
256
257 return sz;
258}
259EXPORT_SYMBOL_GPL(of_property_read_variable_u16_array);
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280int of_property_read_variable_u32_array(const struct device_node *np,
281 const char *propname, u32 *out_values,
282 size_t sz_min, size_t sz_max)
283{
284 size_t sz, count;
285 const __be32 *val = of_find_property_value_of_size(np, propname,
286 (sz_min * sizeof(*out_values)),
287 (sz_max * sizeof(*out_values)),
288 &sz);
289
290 if (IS_ERR(val))
291 return PTR_ERR(val);
292
293 if (!sz_max)
294 sz = sz_min;
295 else
296 sz /= sizeof(*out_values);
297
298 count = sz;
299 while (count--)
300 *out_values++ = be32_to_cpup(val++);
301
302 return sz;
303}
304EXPORT_SYMBOL_GPL(of_property_read_variable_u32_array);
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319int of_property_read_u64(const struct device_node *np, const char *propname,
320 u64 *out_value)
321{
322 const __be32 *val = of_find_property_value_of_size(np, propname,
323 sizeof(*out_value),
324 0,
325 NULL);
326
327 if (IS_ERR(val))
328 return PTR_ERR(val);
329
330 *out_value = of_read_number(val, 2);
331 return 0;
332}
333EXPORT_SYMBOL_GPL(of_property_read_u64);
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354int of_property_read_variable_u64_array(const struct device_node *np,
355 const char *propname, u64 *out_values,
356 size_t sz_min, size_t sz_max)
357{
358 size_t sz, count;
359 const __be32 *val = of_find_property_value_of_size(np, propname,
360 (sz_min * sizeof(*out_values)),
361 (sz_max * sizeof(*out_values)),
362 &sz);
363
364 if (IS_ERR(val))
365 return PTR_ERR(val);
366
367 if (!sz_max)
368 sz = sz_min;
369 else
370 sz /= sizeof(*out_values);
371
372 count = sz;
373 while (count--) {
374 *out_values++ = of_read_number(val, 2);
375 val += 2;
376 }
377
378 return sz;
379}
380EXPORT_SYMBOL_GPL(of_property_read_variable_u64_array);
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397int of_property_read_string(const struct device_node *np, const char *propname,
398 const char **out_string)
399{
400 const struct property *prop = of_find_property(np, propname, NULL);
401 if (!prop)
402 return -EINVAL;
403 if (!prop->value)
404 return -ENODATA;
405 if (strnlen(prop->value, prop->length) >= prop->length)
406 return -EILSEQ;
407 *out_string = prop->value;
408 return 0;
409}
410EXPORT_SYMBOL_GPL(of_property_read_string);
411
412
413
414
415
416
417
418
419
420
421int of_property_match_string(const struct device_node *np, const char *propname,
422 const char *string)
423{
424 const struct property *prop = of_find_property(np, propname, NULL);
425 size_t l;
426 int i;
427 const char *p, *end;
428
429 if (!prop)
430 return -EINVAL;
431 if (!prop->value)
432 return -ENODATA;
433
434 p = prop->value;
435 end = p + prop->length;
436
437 for (i = 0; p < end; i++, p += l) {
438 l = strnlen(p, end - p) + 1;
439 if (p + l > end)
440 return -EILSEQ;
441 pr_debug("comparing %s with %s\n", string, p);
442 if (strcmp(string, p) == 0)
443 return i;
444 }
445 return -ENODATA;
446}
447EXPORT_SYMBOL_GPL(of_property_match_string);
448
449
450
451
452
453
454
455
456
457
458
459
460int of_property_read_string_helper(const struct device_node *np,
461 const char *propname, const char **out_strs,
462 size_t sz, int skip)
463{
464 const struct property *prop = of_find_property(np, propname, NULL);
465 int l = 0, i = 0;
466 const char *p, *end;
467
468 if (!prop)
469 return -EINVAL;
470 if (!prop->value)
471 return -ENODATA;
472 p = prop->value;
473 end = p + prop->length;
474
475 for (i = 0; p < end && (!out_strs || i < skip + sz); i++, p += l) {
476 l = strnlen(p, end - p) + 1;
477 if (p + l > end)
478 return -EILSEQ;
479 if (out_strs && i >= skip)
480 *out_strs++ = p;
481 }
482 i -= skip;
483 return i <= 0 ? -ENODATA : i;
484}
485EXPORT_SYMBOL_GPL(of_property_read_string_helper);
486
487const __be32 *of_prop_next_u32(struct property *prop, const __be32 *cur,
488 u32 *pu)
489{
490 const void *curv = cur;
491
492 if (!prop)
493 return NULL;
494
495 if (!cur) {
496 curv = prop->value;
497 goto out_val;
498 }
499
500 curv += sizeof(*cur);
501 if (curv >= prop->value + prop->length)
502 return NULL;
503
504out_val:
505 *pu = be32_to_cpup(curv);
506 return curv;
507}
508EXPORT_SYMBOL_GPL(of_prop_next_u32);
509
510const char *of_prop_next_string(struct property *prop, const char *cur)
511{
512 const void *curv = cur;
513
514 if (!prop)
515 return NULL;
516
517 if (!cur)
518 return prop->value;
519
520 curv += strlen(cur) + 1;
521 if (curv >= prop->value + prop->length)
522 return NULL;
523
524 return curv;
525}
526EXPORT_SYMBOL_GPL(of_prop_next_string);
527
528
529
530
531
532
533
534
535int of_graph_parse_endpoint(const struct device_node *node,
536 struct of_endpoint *endpoint)
537{
538 struct device_node *port_node = of_get_parent(node);
539
540 WARN_ONCE(!port_node, "%s(): endpoint %pOF has no parent node\n",
541 __func__, node);
542
543 memset(endpoint, 0, sizeof(*endpoint));
544
545 endpoint->local_node = node;
546
547
548
549
550 of_property_read_u32(port_node, "reg", &endpoint->port);
551 of_property_read_u32(node, "reg", &endpoint->id);
552
553 of_node_put(port_node);
554
555 return 0;
556}
557EXPORT_SYMBOL(of_graph_parse_endpoint);
558
559
560
561
562
563
564
565
566
567struct device_node *of_graph_get_port_by_id(struct device_node *parent, u32 id)
568{
569 struct device_node *node, *port;
570
571 node = of_get_child_by_name(parent, "ports");
572 if (node)
573 parent = node;
574
575 for_each_child_of_node(parent, port) {
576 u32 port_id = 0;
577
578 if (of_node_cmp(port->name, "port") != 0)
579 continue;
580 of_property_read_u32(port, "reg", &port_id);
581 if (id == port_id)
582 break;
583 }
584
585 of_node_put(node);
586
587 return port;
588}
589EXPORT_SYMBOL(of_graph_get_port_by_id);
590
591
592
593
594
595
596
597
598
599struct device_node *of_graph_get_next_endpoint(const struct device_node *parent,
600 struct device_node *prev)
601{
602 struct device_node *endpoint;
603 struct device_node *port;
604
605 if (!parent)
606 return NULL;
607
608
609
610
611
612
613 if (!prev) {
614 struct device_node *node;
615
616 node = of_get_child_by_name(parent, "ports");
617 if (node)
618 parent = node;
619
620 port = of_get_child_by_name(parent, "port");
621 of_node_put(node);
622
623 if (!port) {
624 pr_err("graph: no port node found in %pOF\n", parent);
625 return NULL;
626 }
627 } else {
628 port = of_get_parent(prev);
629 if (WARN_ONCE(!port, "%s(): endpoint %pOF has no parent node\n",
630 __func__, prev))
631 return NULL;
632 }
633
634 while (1) {
635
636
637
638
639
640 endpoint = of_get_next_child(port, prev);
641 if (endpoint) {
642 of_node_put(port);
643 return endpoint;
644 }
645
646
647 prev = NULL;
648
649 do {
650 port = of_get_next_child(parent, port);
651 if (!port)
652 return NULL;
653 } while (of_node_cmp(port->name, "port"));
654 }
655}
656EXPORT_SYMBOL(of_graph_get_next_endpoint);
657
658
659
660
661
662
663
664
665
666
667
668struct device_node *of_graph_get_endpoint_by_regs(
669 const struct device_node *parent, int port_reg, int reg)
670{
671 struct of_endpoint endpoint;
672 struct device_node *node = NULL;
673
674 for_each_endpoint_of_node(parent, node) {
675 of_graph_parse_endpoint(node, &endpoint);
676 if (((port_reg == -1) || (endpoint.port == port_reg)) &&
677 ((reg == -1) || (endpoint.id == reg)))
678 return node;
679 }
680
681 return NULL;
682}
683EXPORT_SYMBOL(of_graph_get_endpoint_by_regs);
684
685
686
687
688
689
690
691
692struct device_node *of_graph_get_remote_endpoint(const struct device_node *node)
693{
694
695 return of_parse_phandle(node, "remote-endpoint", 0);
696}
697EXPORT_SYMBOL(of_graph_get_remote_endpoint);
698
699
700
701
702
703
704
705
706struct device_node *of_graph_get_port_parent(struct device_node *node)
707{
708 unsigned int depth;
709
710 if (!node)
711 return NULL;
712
713
714
715
716
717 of_node_get(node);
718
719
720 for (depth = 3; depth && node; depth--) {
721 node = of_get_next_parent(node);
722 if (depth == 2 && of_node_cmp(node->name, "ports"))
723 break;
724 }
725 return node;
726}
727EXPORT_SYMBOL(of_graph_get_port_parent);
728
729
730
731
732
733
734
735
736struct device_node *of_graph_get_remote_port_parent(
737 const struct device_node *node)
738{
739 struct device_node *np, *pp;
740
741
742 np = of_graph_get_remote_endpoint(node);
743
744 pp = of_graph_get_port_parent(np);
745
746 of_node_put(np);
747
748 return pp;
749}
750EXPORT_SYMBOL(of_graph_get_remote_port_parent);
751
752
753
754
755
756
757
758
759struct device_node *of_graph_get_remote_port(const struct device_node *node)
760{
761 struct device_node *np;
762
763
764 np = of_graph_get_remote_endpoint(node);
765 if (!np)
766 return NULL;
767 return of_get_next_parent(np);
768}
769EXPORT_SYMBOL(of_graph_get_remote_port);
770
771int of_graph_get_endpoint_count(const struct device_node *np)
772{
773 struct device_node *endpoint;
774 int num = 0;
775
776 for_each_endpoint_of_node(np, endpoint)
777 num++;
778
779 return num;
780}
781EXPORT_SYMBOL(of_graph_get_endpoint_count);
782
783
784
785
786
787
788
789
790
791
792struct device_node *of_graph_get_remote_node(const struct device_node *node,
793 u32 port, u32 endpoint)
794{
795 struct device_node *endpoint_node, *remote;
796
797 endpoint_node = of_graph_get_endpoint_by_regs(node, port, endpoint);
798 if (!endpoint_node) {
799 pr_debug("no valid endpoint (%d, %d) for node %pOF\n",
800 port, endpoint, node);
801 return NULL;
802 }
803
804 remote = of_graph_get_remote_port_parent(endpoint_node);
805 of_node_put(endpoint_node);
806 if (!remote) {
807 pr_debug("no valid remote node\n");
808 return NULL;
809 }
810
811 if (!of_device_is_available(remote)) {
812 pr_debug("not available for remote node\n");
813 return NULL;
814 }
815
816 return remote;
817}
818EXPORT_SYMBOL(of_graph_get_remote_node);
819
820static void of_fwnode_get(struct fwnode_handle *fwnode)
821{
822 of_node_get(to_of_node(fwnode));
823}
824
825static void of_fwnode_put(struct fwnode_handle *fwnode)
826{
827 of_node_put(to_of_node(fwnode));
828}
829
830static bool of_fwnode_device_is_available(const struct fwnode_handle *fwnode)
831{
832 return of_device_is_available(to_of_node(fwnode));
833}
834
835static bool of_fwnode_property_present(const struct fwnode_handle *fwnode,
836 const char *propname)
837{
838 return of_property_read_bool(to_of_node(fwnode), propname);
839}
840
841static int of_fwnode_property_read_int_array(const struct fwnode_handle *fwnode,
842 const char *propname,
843 unsigned int elem_size, void *val,
844 size_t nval)
845{
846 const struct device_node *node = to_of_node(fwnode);
847
848 if (!val)
849 return of_property_count_elems_of_size(node, propname,
850 elem_size);
851
852 switch (elem_size) {
853 case sizeof(u8):
854 return of_property_read_u8_array(node, propname, val, nval);
855 case sizeof(u16):
856 return of_property_read_u16_array(node, propname, val, nval);
857 case sizeof(u32):
858 return of_property_read_u32_array(node, propname, val, nval);
859 case sizeof(u64):
860 return of_property_read_u64_array(node, propname, val, nval);
861 }
862
863 return -ENXIO;
864}
865
866static int
867of_fwnode_property_read_string_array(const struct fwnode_handle *fwnode,
868 const char *propname, const char **val,
869 size_t nval)
870{
871 const struct device_node *node = to_of_node(fwnode);
872
873 return val ?
874 of_property_read_string_array(node, propname, val, nval) :
875 of_property_count_strings(node, propname);
876}
877
878static struct fwnode_handle *
879of_fwnode_get_parent(const struct fwnode_handle *fwnode)
880{
881 return of_fwnode_handle(of_get_parent(to_of_node(fwnode)));
882}
883
884static struct fwnode_handle *
885of_fwnode_get_next_child_node(const struct fwnode_handle *fwnode,
886 struct fwnode_handle *child)
887{
888 return of_fwnode_handle(of_get_next_available_child(to_of_node(fwnode),
889 to_of_node(child)));
890}
891
892static struct fwnode_handle *
893of_fwnode_get_named_child_node(const struct fwnode_handle *fwnode,
894 const char *childname)
895{
896 const struct device_node *node = to_of_node(fwnode);
897 struct device_node *child;
898
899 for_each_available_child_of_node(node, child)
900 if (!of_node_cmp(child->name, childname))
901 return of_fwnode_handle(child);
902
903 return NULL;
904}
905
906static int
907of_fwnode_get_reference_args(const struct fwnode_handle *fwnode,
908 const char *prop, const char *nargs_prop,
909 unsigned int nargs, unsigned int index,
910 struct fwnode_reference_args *args)
911{
912 struct of_phandle_args of_args;
913 unsigned int i;
914 int ret;
915
916 if (nargs_prop)
917 ret = of_parse_phandle_with_args(to_of_node(fwnode), prop,
918 nargs_prop, index, &of_args);
919 else
920 ret = of_parse_phandle_with_fixed_args(to_of_node(fwnode), prop,
921 nargs, index, &of_args);
922 if (ret < 0)
923 return ret;
924 if (!args)
925 return 0;
926
927 args->nargs = of_args.args_count;
928 args->fwnode = of_fwnode_handle(of_args.np);
929
930 for (i = 0; i < NR_FWNODE_REFERENCE_ARGS; i++)
931 args->args[i] = i < of_args.args_count ? of_args.args[i] : 0;
932
933 return 0;
934}
935
936static struct fwnode_handle *
937of_fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode,
938 struct fwnode_handle *prev)
939{
940 return of_fwnode_handle(of_graph_get_next_endpoint(to_of_node(fwnode),
941 to_of_node(prev)));
942}
943
944static struct fwnode_handle *
945of_fwnode_graph_get_remote_endpoint(const struct fwnode_handle *fwnode)
946{
947 return of_fwnode_handle(
948 of_graph_get_remote_endpoint(to_of_node(fwnode)));
949}
950
951static struct fwnode_handle *
952of_fwnode_graph_get_port_parent(struct fwnode_handle *fwnode)
953{
954 struct device_node *np;
955
956
957 np = of_get_parent(to_of_node(fwnode));
958 if (!np)
959 return NULL;
960
961
962 if (of_node_cmp(np->name, "ports"))
963 return of_fwnode_handle(np);
964
965 return of_fwnode_handle(of_get_next_parent(np));
966}
967
968static int of_fwnode_graph_parse_endpoint(const struct fwnode_handle *fwnode,
969 struct fwnode_endpoint *endpoint)
970{
971 const struct device_node *node = to_of_node(fwnode);
972 struct device_node *port_node = of_get_parent(node);
973
974 endpoint->local_fwnode = fwnode;
975
976 of_property_read_u32(port_node, "reg", &endpoint->port);
977 of_property_read_u32(node, "reg", &endpoint->id);
978
979 of_node_put(port_node);
980
981 return 0;
982}
983
984const struct fwnode_operations of_fwnode_ops = {
985 .get = of_fwnode_get,
986 .put = of_fwnode_put,
987 .device_is_available = of_fwnode_device_is_available,
988 .property_present = of_fwnode_property_present,
989 .property_read_int_array = of_fwnode_property_read_int_array,
990 .property_read_string_array = of_fwnode_property_read_string_array,
991 .get_parent = of_fwnode_get_parent,
992 .get_next_child_node = of_fwnode_get_next_child_node,
993 .get_named_child_node = of_fwnode_get_named_child_node,
994 .get_reference_args = of_fwnode_get_reference_args,
995 .graph_get_next_endpoint = of_fwnode_graph_get_next_endpoint,
996 .graph_get_remote_endpoint = of_fwnode_graph_get_remote_endpoint,
997 .graph_get_port_parent = of_fwnode_graph_get_port_parent,
998 .graph_parse_endpoint = of_fwnode_graph_parse_endpoint,
999};
1000EXPORT_SYMBOL_GPL(of_fwnode_ops);
1001