1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2017 Google, Inc
7 #define LOG_CATEGORY LOGC_DT
11 #include <fdt_support.h>
15 #include <linux/libfdt.h>
16 #include <dm/of_access.h>
17 #include <dm/of_addr.h>
18 #include <dm/ofnode.h>
20 #include <linux/err.h>
21 #include <linux/ioport.h>
22 #include <asm/global_data.h>
24 DECLARE_GLOBAL_DATA_PTR;
26 #if CONFIG_IS_ENABLED(OFNODE_MULTI_TREE)
27 static void *oftree_list[CONFIG_OFNODE_MULTI_TREE_MAX];
28 static int oftree_count;
30 void oftree_reset(void)
32 if (gd->flags & GD_FLG_RELOC) {
34 oftree_list[oftree_count++] = (void *)gd->fdt_blob;
38 static int oftree_find(const void *fdt)
42 for (i = 0; i < oftree_count; i++) {
43 if (fdt == oftree_list[i])
50 static int check_tree_count(void)
52 if (oftree_count == CONFIG_OFNODE_MULTI_TREE_MAX) {
53 log_warning("Too many registered device trees (max %d)\n",
54 CONFIG_OFNODE_MULTI_TREE_MAX);
61 static oftree oftree_ensure(void *fdt)
66 if (of_live_active()) {
67 struct device_node *root;
70 ret = unflatten_device_tree(fdt, &root);
72 log_err("Failed to create live tree: err=%d\n", ret);
75 tree = oftree_from_np(root);
80 if (gd->flags & GD_FLG_RELOC) {
83 if (check_tree_count())
86 if (fdt_check_header(fdt)) {
87 log_err("Invalid device tree blob header\n");
91 /* register the new tree */
94 log_debug("oftree: registered tree %d: %p\n", i, fdt);
97 if (fdt != gd->fdt_blob) {
98 log_debug("Only the control FDT can be accessed before relocation\n");
108 int oftree_new(oftree *treep)
110 oftree tree = oftree_null();
113 if (of_live_active()) {
114 struct device_node *root;
116 ret = of_live_create_empty(&root);
118 return log_msg_ret("liv", ret);
119 tree = oftree_from_np(root);
121 const int size = 1024;
124 ret = check_tree_count();
126 return log_msg_ret("fla", ret);
128 /* register the new tree with a small size */
131 return log_msg_ret("fla", -ENOMEM);
132 ret = fdt_create_empty_tree(fdt, size);
134 return log_msg_ret("fla", -EINVAL);
135 oftree_list[oftree_count++] = fdt;
143 void oftree_dispose(oftree tree)
145 if (of_live_active())
146 of_live_free(tree.np);
149 void *ofnode_lookup_fdt(ofnode node)
151 if (gd->flags & GD_FLG_RELOC) {
152 uint i = OFTREE_TREE_ID(node.of_offset);
154 if (i >= oftree_count) {
155 log_debug("Invalid tree ID %x\n", i);
159 return oftree_list[i];
161 return (void *)gd->fdt_blob;
165 void *ofnode_to_fdt(ofnode node)
168 if (of_live_active())
171 if (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) && ofnode_valid(node))
172 return ofnode_lookup_fdt(node);
174 /* Use the control FDT by default */
175 return (void *)gd->fdt_blob;
179 * ofnode_to_offset() - convert an ofnode to a flat DT offset
181 * This cannot be called if the reference contains a node pointer.
183 * @node: Reference containing offset (possibly invalid)
184 * Return: DT offset (can be -1)
186 int ofnode_to_offset(ofnode node)
189 if (of_live_active())
192 if (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) && node.of_offset >= 0)
193 return OFTREE_OFFSET(node.of_offset);
195 return node.of_offset;
198 oftree oftree_from_fdt(void *fdt)
202 if (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE))
203 return oftree_ensure(fdt);
206 if (of_live_active())
207 return oftree_null();
215 * noffset_to_ofnode() - convert a DT offset to an ofnode
217 * @other_node: Node in the same tree to use as a reference
218 * @of_offset: DT offset (either valid, or -1)
219 * Return: reference to the associated DT offset
221 ofnode noffset_to_ofnode(ofnode other_node, int of_offset)
225 if (of_live_active())
227 else if (!CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) || of_offset < 0 ||
228 !ofnode_valid(other_node))
229 node.of_offset = of_offset;
231 node.of_offset = OFTREE_MAKE_NODE(other_node.of_offset,
237 #else /* !OFNODE_MULTI_TREE */
239 static inline int oftree_find(const void *fdt)
244 int oftree_new(oftree *treep)
249 #endif /* OFNODE_MULTI_TREE */
251 int oftree_to_fdt(oftree tree, struct abuf *buf)
255 if (of_live_active()) {
256 ret = of_live_flatten(ofnode_to_np(oftree_root(tree)), buf);
258 return log_msg_ret("flt", ret);
260 void *fdt = oftree_lookup_fdt(tree);
263 abuf_set(buf, fdt, fdt_totalsize(fdt));
270 * ofnode_from_tree_offset() - get an ofnode from a tree offset (flat tree)
272 * Looks up the tree and returns an ofnode with the correct of_offset (i.e.
273 * containing the tree ID).
275 * If @offset is < 0 then this returns an ofnode with that offset and no tree
278 * @tree: tree to check
279 * @offset: offset within that tree (can be < 0)
280 * @return node for that offset, with the correct ID
282 static ofnode ofnode_from_tree_offset(oftree tree, int offset)
286 if (CONFIG_IS_ENABLED(OFNODE_MULTI_TREE) && offset >= 0) {
287 int tree_id = oftree_find(tree.fdt);
290 return ofnode_null();
291 node.of_offset = OFTREE_NODE(tree_id, offset);
293 node.of_offset = offset;
299 bool ofnode_name_eq(ofnode node, const char *name)
301 const char *node_name;
304 assert(ofnode_valid(node));
306 node_name = ofnode_get_name(node);
307 len = strchrnul(node_name, '@') - node_name;
309 return (strlen(name) == len) && !strncmp(node_name, name, len);
312 int ofnode_read_u8(ofnode node, const char *propname, u8 *outp)
317 assert(ofnode_valid(node));
318 log_debug("%s: %s: ", __func__, propname);
320 if (ofnode_is_np(node))
321 return of_read_u8(ofnode_to_np(node), propname, outp);
323 cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), propname,
325 if (!cell || len < sizeof(*cell)) {
326 log_debug("(not found)\n");
330 log_debug("%#x (%u)\n", *outp, *outp);
335 u8 ofnode_read_u8_default(ofnode node, const char *propname, u8 def)
337 assert(ofnode_valid(node));
338 ofnode_read_u8(node, propname, &def);
343 int ofnode_read_u16(ofnode node, const char *propname, u16 *outp)
348 assert(ofnode_valid(node));
349 log_debug("%s: %s: ", __func__, propname);
351 if (ofnode_is_np(node))
352 return of_read_u16(ofnode_to_np(node), propname, outp);
354 cell = fdt_getprop(gd->fdt_blob, ofnode_to_offset(node), propname,
356 if (!cell || len < sizeof(*cell)) {
357 log_debug("(not found)\n");
360 *outp = be16_to_cpup(cell);
361 log_debug("%#x (%u)\n", *outp, *outp);
366 u16 ofnode_read_u16_default(ofnode node, const char *propname, u16 def)
368 assert(ofnode_valid(node));
369 ofnode_read_u16(node, propname, &def);
374 int ofnode_read_u32(ofnode node, const char *propname, u32 *outp)
376 return ofnode_read_u32_index(node, propname, 0, outp);
379 u32 ofnode_read_u32_default(ofnode node, const char *propname, u32 def)
381 assert(ofnode_valid(node));
382 ofnode_read_u32_index(node, propname, 0, &def);
387 int ofnode_read_u32_index(ofnode node, const char *propname, int index,
393 assert(ofnode_valid(node));
394 log_debug("%s: %s: ", __func__, propname);
396 if (ofnode_is_np(node))
397 return of_read_u32_index(ofnode_to_np(node), propname, index,
400 cell = fdt_getprop(ofnode_to_fdt(node), ofnode_to_offset(node),
403 log_debug("(not found)\n");
407 if (len < (sizeof(int) * (index + 1))) {
408 log_debug("(not large enough)\n");
412 *outp = fdt32_to_cpu(cell[index]);
413 log_debug("%#x (%u)\n", *outp, *outp);
418 int ofnode_read_u64_index(ofnode node, const char *propname, int index,
424 assert(ofnode_valid(node));
426 if (ofnode_is_np(node))
427 return of_read_u64_index(ofnode_to_np(node), propname, index,
430 cell = fdt_getprop(ofnode_to_fdt(node), ofnode_to_offset(node),
433 log_debug("(not found)\n");
437 if (len < (sizeof(u64) * (index + 1))) {
438 log_debug("(not large enough)\n");
442 *outp = fdt64_to_cpu(cell[index]);
443 log_debug("%#llx (%llu)\n", *outp, *outp);
448 u32 ofnode_read_u32_index_default(ofnode node, const char *propname, int index,
451 assert(ofnode_valid(node));
452 ofnode_read_u32_index(node, propname, index, &def);
457 int ofnode_read_s32_default(ofnode node, const char *propname, s32 def)
459 assert(ofnode_valid(node));
460 ofnode_read_u32(node, propname, (u32 *)&def);
465 int ofnode_read_u64(ofnode node, const char *propname, u64 *outp)
467 const unaligned_fdt64_t *cell;
470 assert(ofnode_valid(node));
471 log_debug("%s: %s: ", __func__, propname);
473 if (ofnode_is_np(node))
474 return of_read_u64(ofnode_to_np(node), propname, outp);
476 cell = fdt_getprop(ofnode_to_fdt(node), ofnode_to_offset(node),
478 if (!cell || len < sizeof(*cell)) {
479 log_debug("(not found)\n");
482 *outp = fdt64_to_cpu(cell[0]);
483 log_debug("%#llx (%llu)\n", (unsigned long long)*outp,
484 (unsigned long long)*outp);
489 u64 ofnode_read_u64_default(ofnode node, const char *propname, u64 def)
491 assert(ofnode_valid(node));
492 ofnode_read_u64(node, propname, &def);
497 bool ofnode_read_bool(ofnode node, const char *propname)
501 assert(ofnode_valid(node));
502 log_debug("%s: %s: ", __func__, propname);
504 prop = ofnode_has_property(node, propname);
506 log_debug("%s\n", prop ? "true" : "false");
508 return prop ? true : false;
511 const void *ofnode_read_prop(ofnode node, const char *propname, int *sizep)
513 const char *val = NULL;
516 assert(ofnode_valid(node));
517 log_debug("%s: %s: ", __func__, propname);
519 if (ofnode_is_np(node)) {
520 struct property *prop = of_find_property(
521 ofnode_to_np(node), propname, &len);
528 val = fdt_getprop(ofnode_to_fdt(node), ofnode_to_offset(node),
532 log_debug("<not found>\n");
534 *sizep = -FDT_ERR_NOTFOUND;
543 const char *ofnode_read_string(ofnode node, const char *propname)
548 str = ofnode_read_prop(node, propname, &len);
552 if (strnlen(str, len) >= len) {
553 dm_warn("<invalid>\n");
556 log_debug("%s\n", str);
561 int ofnode_read_size(ofnode node, const char *propname)
565 if (!ofnode_read_prop(node, propname, &len))
571 ofnode ofnode_find_subnode(ofnode node, const char *subnode_name)
575 assert(ofnode_valid(node));
576 log_debug("%s: %s: ", __func__, subnode_name);
578 if (ofnode_is_np(node)) {
579 struct device_node *np = ofnode_to_np(node);
581 for (np = np->child; np; np = np->sibling) {
582 if (!strcmp(subnode_name, np->name))
585 subnode = np_to_ofnode(np);
587 int ooffset = fdt_subnode_offset(ofnode_to_fdt(node),
588 ofnode_to_offset(node), subnode_name);
589 subnode = noffset_to_ofnode(node, ooffset);
591 log_debug("%s\n", ofnode_valid(subnode) ?
592 ofnode_get_name(subnode) : "<none>");
597 int ofnode_read_u32_array(ofnode node, const char *propname,
598 u32 *out_values, size_t sz)
600 assert(ofnode_valid(node));
601 log_debug("%s: %s: ", __func__, propname);
603 if (ofnode_is_np(node)) {
604 return of_read_u32_array(ofnode_to_np(node), propname,
609 ret = fdtdec_get_int_array(ofnode_to_fdt(node),
610 ofnode_to_offset(node), propname,
613 /* get the error right, but space is more important in SPL */
614 if (!IS_ENABLED(CONFIG_XPL_BUILD)) {
615 if (ret == -FDT_ERR_NOTFOUND)
617 else if (ret == -FDT_ERR_BADLAYOUT)
624 #if !CONFIG_IS_ENABLED(DM_INLINE_OFNODE)
625 bool ofnode_is_enabled(ofnode node)
627 if (ofnode_is_np(node)) {
628 return of_device_is_available(ofnode_to_np(node));
630 return fdtdec_get_is_enabled(ofnode_to_fdt(node),
631 ofnode_to_offset(node));
635 ofnode ofnode_first_subnode(ofnode node)
637 assert(ofnode_valid(node));
638 if (ofnode_is_np(node))
639 return np_to_ofnode(node.np->child);
641 return noffset_to_ofnode(node,
642 fdt_first_subnode(ofnode_to_fdt(node), ofnode_to_offset(node)));
645 ofnode ofnode_next_subnode(ofnode node)
647 assert(ofnode_valid(node));
648 if (ofnode_is_np(node))
649 return np_to_ofnode(node.np->sibling);
651 return noffset_to_ofnode(node,
652 fdt_next_subnode(ofnode_to_fdt(node), ofnode_to_offset(node)));
654 #endif /* !DM_INLINE_OFNODE */
656 ofnode ofnode_get_parent(ofnode node)
660 assert(ofnode_valid(node));
661 if (ofnode_is_np(node))
662 parent = np_to_ofnode(of_get_parent(ofnode_to_np(node)));
664 parent.of_offset = fdt_parent_offset(ofnode_to_fdt(node),
665 ofnode_to_offset(node));
670 const char *ofnode_get_name(ofnode node)
672 if (!ofnode_valid(node)) {
673 dm_warn("%s node not valid\n", __func__);
677 if (ofnode_is_np(node))
678 return node.np->name;
680 return fdt_get_name(ofnode_to_fdt(node), ofnode_to_offset(node), NULL);
683 int ofnode_get_path(ofnode node, char *buf, int buflen)
685 assert(ofnode_valid(node));
687 if (ofnode_is_np(node)) {
688 if (strlen(node.np->full_name) >= buflen)
691 strcpy(buf, node.np->full_name);
697 res = fdt_get_path(ofnode_to_fdt(node), ofnode_to_offset(node), buf,
701 else if (res == -FDT_ERR_NOSPACE)
708 ofnode ofnode_get_by_phandle(uint phandle)
712 if (of_live_active())
713 node = np_to_ofnode(of_find_node_by_phandle(NULL, phandle));
715 node.of_offset = fdt_node_offset_by_phandle(gd->fdt_blob,
721 ofnode oftree_get_by_phandle(oftree tree, uint phandle)
725 if (of_live_active())
726 node = np_to_ofnode(of_find_node_by_phandle(tree.np, phandle));
728 node = ofnode_from_tree_offset(tree,
729 fdt_node_offset_by_phandle(oftree_lookup_fdt(tree),
735 static fdt_addr_t __ofnode_get_addr_size_index(ofnode node, int index,
736 fdt_size_t *size, bool translate)
741 *size = FDT_SIZE_T_NONE;
743 if (ofnode_is_np(node)) {
744 const __be32 *prop_val;
748 prop_val = of_get_address(ofnode_to_np(node), index, &size64,
751 return FDT_ADDR_T_NONE;
756 ns = of_n_size_cells(ofnode_to_np(node));
758 if (translate && IS_ENABLED(CONFIG_OF_TRANSLATE) && ns > 0) {
759 return of_translate_address(ofnode_to_np(node), prop_val);
761 na = of_n_addr_cells(ofnode_to_np(node));
762 return of_read_number(prop_val, na);
765 ofnode parent = ofnode_get_parent(node);
766 na = ofnode_read_simple_addr_cells(parent);
767 ns = ofnode_read_simple_size_cells(parent);
768 return fdtdec_get_addr_size_fixed(ofnode_to_fdt(node),
769 ofnode_to_offset(node), "reg",
775 fdt_addr_t ofnode_get_addr_size_index(ofnode node, int index, fdt_size_t *size)
777 return __ofnode_get_addr_size_index(node, index, size, true);
780 fdt_addr_t ofnode_get_addr_size_index_notrans(ofnode node, int index,
783 return __ofnode_get_addr_size_index(node, index, size, false);
786 fdt_addr_t ofnode_get_addr_index(ofnode node, int index)
790 return ofnode_get_addr_size_index(node, index, &size);
793 fdt_addr_t ofnode_get_addr(ofnode node)
795 return ofnode_get_addr_index(node, 0);
798 fdt_size_t ofnode_get_size(ofnode node)
802 ofnode_get_addr_size_index(node, 0, &size);
807 int ofnode_stringlist_search(ofnode node, const char *property,
810 if (ofnode_is_np(node)) {
811 return of_property_match_string(ofnode_to_np(node),
816 ret = fdt_stringlist_search(ofnode_to_fdt(node),
817 ofnode_to_offset(node), property,
819 if (ret == -FDT_ERR_NOTFOUND)
828 int ofnode_read_string_index(ofnode node, const char *property, int index,
831 if (ofnode_is_np(node)) {
832 return of_property_read_string_index(ofnode_to_np(node),
833 property, index, outp);
837 *outp = fdt_stringlist_get(ofnode_to_fdt(node),
838 ofnode_to_offset(node),
839 property, index, &len);
846 int ofnode_read_string_count(ofnode node, const char *property)
848 if (ofnode_is_np(node)) {
849 return of_property_count_strings(ofnode_to_np(node), property);
851 return fdt_stringlist_count(ofnode_to_fdt(node),
852 ofnode_to_offset(node), property);
856 int ofnode_read_string_list(ofnode node, const char *property,
864 count = ofnode_read_string_count(node, property);
870 prop = calloc(count + 1, sizeof(char *));
874 for (i = 0; i < count; i++)
875 ofnode_read_string_index(node, property, i, &prop[i]);
882 ofnode ofnode_parse_phandle(ofnode node, const char *phandle_name,
887 if (ofnode_is_np(node)) {
888 struct device_node *np;
890 np = of_parse_phandle(ofnode_to_np(node), phandle_name,
893 return ofnode_null();
895 phandle = np_to_ofnode(np);
897 struct fdtdec_phandle_args args;
899 if (fdtdec_parse_phandle_with_args(ofnode_to_fdt(node),
900 ofnode_to_offset(node),
903 return ofnode_null();
905 phandle = offset_to_ofnode(args.node);
911 ofnode oftree_parse_phandle(oftree tree, ofnode node, const char *phandle_name,
916 if (ofnode_is_np(node)) {
917 struct device_node *np;
919 np = of_root_parse_phandle(tree.np, ofnode_to_np(node),
920 phandle_name, index);
922 return ofnode_null();
924 phandle = np_to_ofnode(np);
926 struct fdtdec_phandle_args args;
928 if (fdtdec_parse_phandle_with_args(tree.fdt,
929 ofnode_to_offset(node),
932 return ofnode_null();
934 phandle = noffset_to_ofnode(node, args.node);
940 static void ofnode_from_fdtdec_phandle_args(ofnode node, struct fdtdec_phandle_args *in,
941 struct ofnode_phandle_args *out)
943 assert(OF_MAX_PHANDLE_ARGS == MAX_PHANDLE_ARGS);
944 out->node = noffset_to_ofnode(node, in->node);
945 out->args_count = in->args_count;
946 memcpy(out->args, in->args, sizeof(out->args));
949 static void ofnode_from_of_phandle_args(struct of_phandle_args *in,
950 struct ofnode_phandle_args *out)
952 assert(OF_MAX_PHANDLE_ARGS == MAX_PHANDLE_ARGS);
953 out->node = np_to_ofnode(in->np);
954 out->args_count = in->args_count;
955 memcpy(out->args, in->args, sizeof(out->args));
958 int ofnode_parse_phandle_with_args(ofnode node, const char *list_name,
959 const char *cells_name, int cell_count,
961 struct ofnode_phandle_args *out_args)
963 if (ofnode_is_np(node)) {
964 struct of_phandle_args args;
967 ret = of_parse_phandle_with_args(ofnode_to_np(node),
968 list_name, cells_name,
973 ofnode_from_of_phandle_args(&args, out_args);
975 struct fdtdec_phandle_args args;
978 ret = fdtdec_parse_phandle_with_args(ofnode_to_fdt(node),
979 ofnode_to_offset(node),
980 list_name, cells_name,
981 cell_count, index, &args);
984 ofnode_from_fdtdec_phandle_args(node, &args, out_args);
990 int oftree_parse_phandle_with_args(oftree tree, ofnode node, const char *list_name,
991 const char *cells_name, int cell_count,
993 struct ofnode_phandle_args *out_args)
995 if (ofnode_is_np(node)) {
996 struct of_phandle_args args;
999 ret = of_root_parse_phandle_with_args(tree.np,
1001 list_name, cells_name,
1006 ofnode_from_of_phandle_args(&args, out_args);
1008 struct fdtdec_phandle_args args;
1011 ret = fdtdec_parse_phandle_with_args(tree.fdt,
1012 ofnode_to_offset(node),
1013 list_name, cells_name,
1014 cell_count, index, &args);
1017 ofnode_from_fdtdec_phandle_args(node, &args, out_args);
1023 int ofnode_count_phandle_with_args(ofnode node, const char *list_name,
1024 const char *cells_name, int cell_count)
1026 if (ofnode_is_np(node))
1027 return of_count_phandle_with_args(ofnode_to_np(node),
1028 list_name, cells_name, cell_count);
1030 return fdtdec_parse_phandle_with_args(ofnode_to_fdt(node),
1031 ofnode_to_offset(node), list_name, cells_name,
1032 cell_count, -1, NULL);
1035 int oftree_count_phandle_with_args(oftree tree, ofnode node, const char *list_name,
1036 const char *cells_name, int cell_count)
1038 if (ofnode_is_np(node))
1039 return of_root_count_phandle_with_args(tree.np, ofnode_to_np(node),
1040 list_name, cells_name, cell_count);
1042 return fdtdec_parse_phandle_with_args(tree.fdt,
1043 ofnode_to_offset(node), list_name, cells_name,
1044 cell_count, -1, NULL);
1047 ofnode ofnode_path(const char *path)
1049 if (of_live_active())
1050 return np_to_ofnode(of_find_node_by_path(path));
1052 return offset_to_ofnode(fdt_path_offset(gd->fdt_blob, path));
1055 ofnode oftree_root(oftree tree)
1057 if (of_live_active()) {
1058 return np_to_ofnode(tree.np);
1060 return ofnode_from_tree_offset(tree, 0);
1064 ofnode oftree_path(oftree tree, const char *path)
1066 if (of_live_active()) {
1067 return np_to_ofnode(of_find_node_opts_by_path(tree.np, path,
1069 } else if (*path != '/' && tree.fdt != gd->fdt_blob) {
1070 return ofnode_null(); /* Aliases only on control FDT */
1072 int offset = fdt_path_offset(tree.fdt, path);
1074 return ofnode_from_tree_offset(tree, offset);
1078 const void *ofnode_read_chosen_prop(const char *propname, int *sizep)
1082 chosen_node = ofnode_path("/chosen");
1084 return ofnode_read_prop(chosen_node, propname, sizep);
1087 const char *ofnode_read_chosen_string(const char *propname)
1089 return ofnode_read_chosen_prop(propname, NULL);
1092 ofnode ofnode_get_chosen_node(const char *name)
1096 prop = ofnode_read_chosen_prop(name, NULL);
1098 return ofnode_null();
1100 return ofnode_path(prop);
1103 int ofnode_read_baud(void)
1105 const char *str, *p;
1108 str = ofnode_read_chosen_string("stdout-path");
1112 /* Parse string serial0:115200n8 */
1113 p = strchr(str, ':');
1117 baud = dectoul(p + 1, NULL);
1121 const void *ofnode_read_aliases_prop(const char *propname, int *sizep)
1125 node = ofnode_path("/aliases");
1127 return ofnode_read_prop(node, propname, sizep);
1130 ofnode ofnode_get_aliases_node(const char *name)
1134 prop = ofnode_read_aliases_prop(name, NULL);
1136 return ofnode_null();
1138 log_debug("%s: node_path: %s\n", __func__, prop);
1140 return ofnode_path(prop);
1143 int ofnode_get_child_count(ofnode parent)
1148 ofnode_for_each_subnode(child, parent)
1154 static int decode_timing_property(ofnode node, const char *name,
1155 struct timing_entry *result)
1157 int length, ret = 0;
1159 length = ofnode_read_size(node, name);
1161 dm_warn("%s: could not find property %s\n",
1162 ofnode_get_name(node), name);
1166 if (length == sizeof(u32)) {
1167 result->typ = ofnode_read_u32_default(node, name, 0);
1168 result->min = result->typ;
1169 result->max = result->typ;
1171 ret = ofnode_read_u32_array(node, name, &result->min, 3);
1177 int ofnode_decode_display_timing(ofnode parent, int index,
1178 struct display_timing *dt)
1181 ofnode timings, node;
1185 timings = ofnode_find_subnode(parent, "display-timings");
1186 if (!ofnode_valid(timings))
1190 ofnode_for_each_subnode(node, timings) {
1195 if (!ofnode_valid(node))
1198 memset(dt, 0, sizeof(*dt));
1200 ret |= decode_timing_property(node, "hback-porch", &dt->hback_porch);
1201 ret |= decode_timing_property(node, "hfront-porch", &dt->hfront_porch);
1202 ret |= decode_timing_property(node, "hactive", &dt->hactive);
1203 ret |= decode_timing_property(node, "hsync-len", &dt->hsync_len);
1204 ret |= decode_timing_property(node, "vback-porch", &dt->vback_porch);
1205 ret |= decode_timing_property(node, "vfront-porch", &dt->vfront_porch);
1206 ret |= decode_timing_property(node, "vactive", &dt->vactive);
1207 ret |= decode_timing_property(node, "vsync-len", &dt->vsync_len);
1208 ret |= decode_timing_property(node, "clock-frequency", &dt->pixelclock);
1211 val = ofnode_read_u32_default(node, "vsync-active", -1);
1213 dt->flags |= val ? DISPLAY_FLAGS_VSYNC_HIGH :
1214 DISPLAY_FLAGS_VSYNC_LOW;
1216 val = ofnode_read_u32_default(node, "hsync-active", -1);
1218 dt->flags |= val ? DISPLAY_FLAGS_HSYNC_HIGH :
1219 DISPLAY_FLAGS_HSYNC_LOW;
1221 val = ofnode_read_u32_default(node, "de-active", -1);
1223 dt->flags |= val ? DISPLAY_FLAGS_DE_HIGH :
1224 DISPLAY_FLAGS_DE_LOW;
1226 val = ofnode_read_u32_default(node, "pixelclk-active", -1);
1228 dt->flags |= val ? DISPLAY_FLAGS_PIXDATA_POSEDGE :
1229 DISPLAY_FLAGS_PIXDATA_NEGEDGE;
1232 if (ofnode_read_bool(node, "interlaced"))
1233 dt->flags |= DISPLAY_FLAGS_INTERLACED;
1234 if (ofnode_read_bool(node, "doublescan"))
1235 dt->flags |= DISPLAY_FLAGS_DOUBLESCAN;
1236 if (ofnode_read_bool(node, "doubleclk"))
1237 dt->flags |= DISPLAY_FLAGS_DOUBLECLK;
1242 int ofnode_decode_panel_timing(ofnode parent,
1243 struct display_timing *dt)
1249 timings = ofnode_find_subnode(parent, "panel-timing");
1250 if (!ofnode_valid(timings))
1252 memset(dt, 0, sizeof(*dt));
1253 ret |= decode_timing_property(timings, "hback-porch", &dt->hback_porch);
1254 ret |= decode_timing_property(timings, "hfront-porch", &dt->hfront_porch);
1255 ret |= decode_timing_property(timings, "hactive", &dt->hactive);
1256 ret |= decode_timing_property(timings, "hsync-len", &dt->hsync_len);
1257 ret |= decode_timing_property(timings, "vback-porch", &dt->vback_porch);
1258 ret |= decode_timing_property(timings, "vfront-porch", &dt->vfront_porch);
1259 ret |= decode_timing_property(timings, "vactive", &dt->vactive);
1260 ret |= decode_timing_property(timings, "vsync-len", &dt->vsync_len);
1261 ret |= decode_timing_property(timings, "clock-frequency", &dt->pixelclock);
1263 if (!ofnode_read_u32(timings, "vsync-active", &val)) {
1264 dt->flags |= val ? DISPLAY_FLAGS_VSYNC_HIGH :
1265 DISPLAY_FLAGS_VSYNC_LOW;
1267 if (!ofnode_read_u32(timings, "hsync-active", &val)) {
1268 dt->flags |= val ? DISPLAY_FLAGS_HSYNC_HIGH :
1269 DISPLAY_FLAGS_HSYNC_LOW;
1271 if (!ofnode_read_u32(timings, "de-active", &val)) {
1272 dt->flags |= val ? DISPLAY_FLAGS_DE_HIGH :
1273 DISPLAY_FLAGS_DE_LOW;
1275 if (!ofnode_read_u32(timings, "pixelclk-active", &val)) {
1276 dt->flags |= val ? DISPLAY_FLAGS_PIXDATA_POSEDGE :
1277 DISPLAY_FLAGS_PIXDATA_NEGEDGE;
1279 if (ofnode_read_bool(timings, "interlaced"))
1280 dt->flags |= DISPLAY_FLAGS_INTERLACED;
1281 if (ofnode_read_bool(timings, "doublescan"))
1282 dt->flags |= DISPLAY_FLAGS_DOUBLESCAN;
1283 if (ofnode_read_bool(timings, "doubleclk"))
1284 dt->flags |= DISPLAY_FLAGS_DOUBLECLK;
1289 const void *ofnode_get_property(ofnode node, const char *propname, int *lenp)
1291 if (ofnode_is_np(node))
1292 return of_get_property(ofnode_to_np(node), propname, lenp);
1294 return fdt_getprop(ofnode_to_fdt(node), ofnode_to_offset(node),
1298 bool ofnode_has_property(ofnode node, const char *propname)
1300 if (ofnode_is_np(node))
1301 return of_find_property(ofnode_to_np(node), propname, NULL);
1303 return ofnode_get_property(node, propname, NULL);
1306 int ofnode_first_property(ofnode node, struct ofprop *prop)
1310 if (ofnode_is_np(node)) {
1311 prop->prop = of_get_first_property(ofnode_to_np(prop->node));
1313 return -FDT_ERR_NOTFOUND;
1316 fdt_first_property_offset(ofnode_to_fdt(node),
1317 ofnode_to_offset(prop->node));
1318 if (prop->offset < 0)
1319 return prop->offset;
1325 int ofnode_next_property(struct ofprop *prop)
1327 if (ofnode_is_np(prop->node)) {
1328 prop->prop = of_get_next_property(ofnode_to_np(prop->node),
1331 return -FDT_ERR_NOTFOUND;
1334 fdt_next_property_offset(ofnode_to_fdt(prop->node),
1336 if (prop->offset < 0)
1337 return prop->offset;
1343 const void *ofprop_get_property(const struct ofprop *prop,
1344 const char **propname, int *lenp)
1346 if (ofnode_is_np(prop->node))
1347 return of_get_property_by_prop(ofnode_to_np(prop->node),
1348 prop->prop, propname, lenp);
1350 return fdt_getprop_by_offset(ofnode_to_fdt(prop->node),
1355 fdt_addr_t ofnode_get_addr_size(ofnode node, const char *property,
1358 if (ofnode_is_np(node)) {
1361 const struct device_node *np = ofnode_to_np(node);
1362 const __be32 *prop = of_get_property(np, property, &psize);
1365 return FDT_ADDR_T_NONE;
1366 na = of_n_addr_cells(np);
1367 ns = of_n_size_cells(np);
1368 *sizep = of_read_number(prop + na, ns);
1370 if (CONFIG_IS_ENABLED(OF_TRANSLATE) && ns > 0)
1371 return of_translate_address(np, prop);
1373 return of_read_number(prop, na);
1375 return fdtdec_get_addr_size(ofnode_to_fdt(node),
1376 ofnode_to_offset(node), property,
1381 const uint8_t *ofnode_read_u8_array_ptr(ofnode node, const char *propname,
1384 if (ofnode_is_np(node)) {
1385 const struct device_node *np = ofnode_to_np(node);
1387 const __be32 *prop = of_get_property(np, propname, &psize);
1389 if (!prop || sz != psize)
1391 return (uint8_t *)prop;
1394 return fdtdec_locate_byte_array(ofnode_to_fdt(node),
1395 ofnode_to_offset(node), propname, sz);
1399 int ofnode_read_pci_addr(ofnode node, enum fdt_pci_space type,
1400 const char *propname, struct fdt_pci_addr *addr,
1403 const fdt32_t *cell;
1407 log_debug("%s: %s: ", __func__, propname);
1410 * If we follow the pci bus bindings strictly, we should check
1411 * the value of the node's parent node's #address-cells and
1412 * #size-cells. They need to be 3 and 2 accordingly. However,
1413 * for simplicity we skip the check here.
1415 cell = ofnode_get_property(node, propname, &len);
1419 if ((len % FDT_PCI_REG_SIZE) == 0) {
1420 int num = len / FDT_PCI_REG_SIZE;
1423 for (i = 0; i < num; i++) {
1424 log_debug("pci address #%d: %08lx %08lx %08lx\n", i,
1425 (ulong)fdt32_to_cpu(cell[0]),
1426 (ulong)fdt32_to_cpu(cell[1]),
1427 (ulong)fdt32_to_cpu(cell[2]));
1428 if ((fdt32_to_cpu(*cell) & type) == type) {
1429 const unaligned_fdt64_t *ptr;
1431 addr->phys_hi = fdt32_to_cpu(cell[0]);
1432 addr->phys_mid = fdt32_to_cpu(cell[1]);
1433 addr->phys_lo = fdt32_to_cpu(cell[2]);
1434 ptr = (const unaligned_fdt64_t *)(cell + 3);
1436 *size = fdt64_to_cpu(*ptr);
1440 cell += FDT_PCI_ADDR_CELLS + FDT_PCI_SIZE_CELLS;
1454 log_debug("(not found)\n");
1458 int ofnode_read_pci_vendev(ofnode node, u16 *vendor, u16 *device)
1460 const char *list, *end;
1463 list = ofnode_get_property(node, "compatible", &len);
1468 while (list < end) {
1470 if (len >= strlen("pciVVVV,DDDD")) {
1471 char *s = strstr(list, "pci");
1474 * check if the string is something like pciVVVV,DDDD.RR
1475 * or just pciVVVV,DDDD
1477 if (s && s[7] == ',' &&
1478 (s[12] == '.' || s[12] == 0)) {
1480 *vendor = simple_strtol(s, NULL, 16);
1483 *device = simple_strtol(s, NULL, 16);
1494 int ofnode_read_eth_phy_id(ofnode node, u16 *vendor, u16 *device)
1496 const char *list, *end;
1499 list = ofnode_get_property(node, "compatible", &len);
1505 while (list < end) {
1508 if (len >= strlen("ethernet-phy-idVVVV.DDDD")) {
1509 char *s = strstr(list, "ethernet-phy-id");
1512 * check if the string is something like
1513 * ethernet-phy-idVVVV.DDDD
1515 if (s && s[19] == '.') {
1516 s += strlen("ethernet-phy-id");
1517 *vendor = simple_strtol(s, NULL, 16);
1519 *device = simple_strtol(s, NULL, 16);
1530 int ofnode_read_addr_cells(ofnode node)
1532 if (ofnode_is_np(node)) {
1533 return of_n_addr_cells(ofnode_to_np(node));
1535 int parent = fdt_parent_offset(ofnode_to_fdt(node),
1536 ofnode_to_offset(node));
1538 return fdt_address_cells(ofnode_to_fdt(node), parent);
1542 int ofnode_read_size_cells(ofnode node)
1544 if (ofnode_is_np(node)) {
1545 return of_n_size_cells(ofnode_to_np(node));
1547 int parent = fdt_parent_offset(ofnode_to_fdt(node),
1548 ofnode_to_offset(node));
1550 return fdt_size_cells(ofnode_to_fdt(node), parent);
1554 int ofnode_read_simple_addr_cells(ofnode node)
1556 if (ofnode_is_np(node))
1557 return of_simple_addr_cells(ofnode_to_np(node));
1559 return fdt_address_cells(ofnode_to_fdt(node),
1560 ofnode_to_offset(node));
1563 int ofnode_read_simple_size_cells(ofnode node)
1565 if (ofnode_is_np(node))
1566 return of_simple_size_cells(ofnode_to_np(node));
1568 return fdt_size_cells(ofnode_to_fdt(node),
1569 ofnode_to_offset(node));
1572 bool ofnode_pre_reloc(ofnode node)
1574 #if defined(CONFIG_XPL_BUILD) || defined(CONFIG_TPL_BUILD)
1575 /* for SPL and TPL the remaining nodes after the fdtgrep 1st pass
1576 * had property bootph-all or bootph-pre-sram/bootph-pre-ram.
1577 * They are removed in final dtb (fdtgrep 2nd pass)
1581 if (ofnode_read_bool(node, "bootph-all"))
1583 if (ofnode_read_bool(node, "bootph-some-ram"))
1587 * In regular builds individual spl and tpl handling both
1588 * count as handled pre-relocation for later second init.
1590 if (ofnode_read_bool(node, "bootph-pre-ram") ||
1591 ofnode_read_bool(node, "bootph-pre-sram"))
1592 return gd->flags & GD_FLG_RELOC;
1594 if (IS_ENABLED(CONFIG_OF_TAG_MIGRATE)) {
1595 /* detect and handle old tags */
1596 if (ofnode_read_bool(node, "u-boot,dm-pre-reloc") ||
1597 ofnode_read_bool(node, "u-boot,dm-pre-proper") ||
1598 ofnode_read_bool(node, "u-boot,dm-spl") ||
1599 ofnode_read_bool(node, "u-boot,dm-tpl") ||
1600 ofnode_read_bool(node, "u-boot,dm-vpl")) {
1601 gd->flags |= GD_FLG_OF_TAG_MIGRATE;
1610 int ofnode_read_resource(ofnode node, uint index, struct resource *res)
1612 if (ofnode_is_np(node)) {
1613 return of_address_to_resource(ofnode_to_np(node), index, res);
1615 struct fdt_resource fres;
1618 ret = fdt_get_resource(ofnode_to_fdt(node),
1619 ofnode_to_offset(node),
1620 "reg", index, &fres);
1623 memset(res, '\0', sizeof(*res));
1624 res->start = fres.start;
1625 res->end = fres.end;
1631 int ofnode_read_resource_byname(ofnode node, const char *name,
1632 struct resource *res)
1636 index = ofnode_stringlist_search(node, "reg-names", name);
1640 return ofnode_read_resource(node, index, res);
1643 u64 ofnode_translate_address(ofnode node, const fdt32_t *in_addr)
1645 if (ofnode_is_np(node))
1646 return of_translate_address(ofnode_to_np(node), in_addr);
1648 return fdt_translate_address(ofnode_to_fdt(node),
1649 ofnode_to_offset(node), in_addr);
1652 u64 ofnode_translate_dma_address(ofnode node, const fdt32_t *in_addr)
1654 if (ofnode_is_np(node))
1655 return of_translate_dma_address(ofnode_to_np(node), in_addr);
1657 return fdt_translate_dma_address(ofnode_to_fdt(node),
1658 ofnode_to_offset(node), in_addr);
1661 int ofnode_get_dma_range(ofnode node, phys_addr_t *cpu, dma_addr_t *bus, u64 *size)
1663 if (ofnode_is_np(node))
1664 return of_get_dma_range(ofnode_to_np(node), cpu, bus, size);
1666 return fdt_get_dma_range(ofnode_to_fdt(node),
1667 ofnode_to_offset(node),
1671 int ofnode_device_is_compatible(ofnode node, const char *compat)
1673 if (ofnode_is_np(node))
1674 return of_device_is_compatible(ofnode_to_np(node), compat,
1677 return !fdt_node_check_compatible(ofnode_to_fdt(node),
1678 ofnode_to_offset(node),
1682 ofnode ofnode_by_compatible(ofnode from, const char *compat)
1684 if (of_live_active()) {
1685 return np_to_ofnode(of_find_compatible_node(
1686 (struct device_node *)ofnode_to_np(from), NULL,
1689 return noffset_to_ofnode(from,
1690 fdt_node_offset_by_compatible(ofnode_to_fdt(from),
1691 ofnode_to_offset(from), compat));
1695 ofnode ofnode_by_prop_value(ofnode from, const char *propname,
1696 const void *propval, int proplen)
1698 if (of_live_active()) {
1699 return np_to_ofnode(of_find_node_by_prop_value(
1700 (struct device_node *)ofnode_to_np(from), propname,
1703 return noffset_to_ofnode(from,
1704 fdt_node_offset_by_prop_value(ofnode_to_fdt(from),
1705 ofnode_to_offset(from), propname, propval,
1710 int ofnode_write_prop(ofnode node, const char *propname, const void *value,
1713 if (of_live_active()) {
1718 newval = malloc(len);
1720 return log_ret(-ENOMEM);
1721 memcpy(newval, value, len);
1724 ret = of_write_prop(ofnode_to_np(node), propname, len, value);
1729 return fdt_setprop(ofnode_to_fdt(node), ofnode_to_offset(node),
1730 propname, value, len);
1734 int ofnode_write_string(ofnode node, const char *propname, const char *value)
1736 assert(ofnode_valid(node));
1738 log_debug("%s: %s = %s", __func__, propname, value);
1740 return ofnode_write_prop(node, propname, value, strlen(value) + 1,
1744 int ofnode_write_u32(ofnode node, const char *propname, u32 value)
1748 assert(ofnode_valid(node));
1750 log_debug("%s = %x", propname, value);
1751 val = malloc(sizeof(*val));
1754 *val = cpu_to_fdt32(value);
1756 return ofnode_write_prop(node, propname, val, sizeof(value), true);
1759 int ofnode_write_u64(ofnode node, const char *propname, u64 value)
1763 assert(ofnode_valid(node));
1765 log_debug("%s = %llx", propname, (unsigned long long)value);
1766 val = malloc(sizeof(*val));
1769 *val = cpu_to_fdt64(value);
1771 return ofnode_write_prop(node, propname, val, sizeof(value), true);
1774 int ofnode_write_bool(ofnode node, const char *propname, bool value)
1777 return ofnode_write_prop(node, propname, NULL, 0, false);
1779 return ofnode_delete_prop(node, propname);
1782 int ofnode_delete_prop(ofnode node, const char *propname)
1784 if (ofnode_is_np(node)) {
1785 struct property *prop;
1788 prop = of_find_property(ofnode_to_np(node), propname, &len);
1790 return of_remove_property(ofnode_to_np(node), prop);
1793 return fdt_delprop(ofnode_to_fdt(node), ofnode_to_offset(node),
1798 int ofnode_set_enabled(ofnode node, bool value)
1800 assert(ofnode_valid(node));
1803 return ofnode_write_string(node, "status", "okay");
1805 return ofnode_write_string(node, "status", "disabled");
1808 bool ofnode_conf_read_bool(const char *prop_name)
1812 node = ofnode_path("/config");
1813 if (!ofnode_valid(node))
1816 return ofnode_read_bool(node, prop_name);
1819 int ofnode_conf_read_int(const char *prop_name, int default_val)
1823 node = ofnode_path("/config");
1824 if (!ofnode_valid(node))
1827 return ofnode_read_u32_default(node, prop_name, default_val);
1830 const char *ofnode_conf_read_str(const char *prop_name)
1834 node = ofnode_path("/config");
1835 if (!ofnode_valid(node))
1838 return ofnode_read_string(node, prop_name);
1841 bool ofnode_options_read_bool(const char *prop_name)
1845 uboot = ofnode_path("/options/u-boot");
1846 if (!ofnode_valid(uboot))
1849 return ofnode_read_bool(uboot, prop_name);
1852 int ofnode_options_read_int(const char *prop_name, int default_val)
1856 uboot = ofnode_path("/options/u-boot");
1857 if (!ofnode_valid(uboot))
1860 return ofnode_read_u32_default(uboot, prop_name, default_val);
1863 const char *ofnode_options_read_str(const char *prop_name)
1867 uboot = ofnode_path("/options/u-boot");
1868 if (!ofnode_valid(uboot))
1871 return ofnode_read_string(uboot, prop_name);
1874 int ofnode_options_get_by_phandle(const char *prop_name, ofnode *nodep)
1878 uboot = ofnode_path("/options/u-boot");
1879 if (!ofnode_valid(uboot))
1882 *nodep = ofnode_parse_phandle(uboot, prop_name, 0);
1883 if (!ofnode_valid(*nodep))
1889 int ofnode_read_bootscript_address(u64 *bootscr_address, u64 *bootscr_offset)
1894 *bootscr_address = 0;
1895 *bootscr_offset = 0;
1897 uboot = ofnode_path("/options/u-boot");
1898 if (!ofnode_valid(uboot)) {
1899 dm_warn("%s: Missing /u-boot node\n", __func__);
1903 ret = ofnode_read_u64(uboot, "bootscr-address", bootscr_address);
1905 ret = ofnode_read_u64(uboot, "bootscr-ram-offset",
1914 int ofnode_read_bootscript_flash(u64 *bootscr_flash_offset,
1915 u64 *bootscr_flash_size)
1920 *bootscr_flash_offset = 0;
1921 *bootscr_flash_size = 0;
1923 uboot = ofnode_path("/options/u-boot");
1924 if (!ofnode_valid(uboot)) {
1925 dm_warn("%s: Missing /u-boot node\n", __func__);
1929 ret = ofnode_read_u64(uboot, "bootscr-flash-offset",
1930 bootscr_flash_offset);
1934 ret = ofnode_read_u64(uboot, "bootscr-flash-size",
1935 bootscr_flash_size);
1939 if (!bootscr_flash_size) {
1940 dm_warn("bootscr-flash-size is zero. Ignoring properties!\n");
1941 *bootscr_flash_offset = 0;
1948 ofnode ofnode_get_phy_node(ofnode node)
1950 /* DT node properties that reference a PHY node */
1951 static const char * const phy_handle_str[] = {
1952 "phy-handle", "phy", "phy-device",
1954 struct ofnode_phandle_args args = {
1955 .node = ofnode_null()
1959 assert(ofnode_valid(node));
1961 for (i = 0; i < ARRAY_SIZE(phy_handle_str); i++)
1962 if (!ofnode_parse_phandle_with_args(node, phy_handle_str[i],
1969 phy_interface_t ofnode_read_phy_mode(ofnode node)
1974 assert(ofnode_valid(node));
1976 mode = ofnode_read_string(node, "phy-mode");
1978 mode = ofnode_read_string(node, "phy-connection-type");
1981 return PHY_INTERFACE_MODE_NA;
1983 for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++)
1984 if (!strcmp(mode, phy_interface_strings[i]))
1987 dm_warn("%s: Invalid PHY interface '%s'\n", __func__, mode);
1989 return PHY_INTERFACE_MODE_NA;
1992 int ofnode_add_subnode(ofnode node, const char *name, ofnode *subnodep)
1997 assert(ofnode_valid(node));
1999 if (ofnode_is_np(node)) {
2000 struct device_node *np, *child;
2002 np = (struct device_node *)ofnode_to_np(node);
2003 ret = of_add_subnode(np, name, -1, &child);
2004 if (ret && ret != -EEXIST)
2006 subnode = np_to_ofnode(child);
2008 void *fdt = ofnode_to_fdt(node);
2009 int poffset = ofnode_to_offset(node);
2012 offset = fdt_add_subnode(fdt, poffset, name);
2013 if (offset == -FDT_ERR_EXISTS) {
2014 offset = fdt_subnode_offset(fdt, poffset, name);
2019 subnode = noffset_to_ofnode(node, offset);
2022 *subnodep = subnode;
2024 return ret; /* 0 or -EEXIST */
2027 int ofnode_delete(ofnode *nodep)
2029 ofnode node = *nodep;
2032 assert(ofnode_valid(node));
2033 if (ofnode_is_np(node)) {
2034 ret = of_remove_node(ofnode_to_np(node));
2036 void *fdt = ofnode_to_fdt(node);
2037 int offset = ofnode_to_offset(node);
2039 ret = fdt_del_node(fdt, offset);
2045 *nodep = ofnode_null();
2050 int ofnode_copy_props(ofnode dst, ofnode src)
2054 ofnode_for_each_prop(prop, src) {
2059 val = ofprop_get_property(&prop, &name, &len);
2061 log_debug("Cannot read prop (err=%d)\n", len);
2062 return log_msg_ret("get", -EINVAL);
2064 ret = ofnode_write_prop(dst, name, val, len, true);
2066 log_debug("Cannot write prop (err=%d)\n", ret);
2067 return log_msg_ret("wr", -EINVAL);
2074 int ofnode_copy_node(ofnode dst_parent, const char *name, ofnode src,
2080 ret = ofnode_add_subnode(dst_parent, name, &node);
2084 return log_msg_ret("add", ret);
2086 ret = ofnode_copy_props(node, src);
2088 return log_msg_ret("cpy", ret);