aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/boot/flatdevtree.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/boot/flatdevtree.c')
-rw-r--r--arch/powerpc/boot/flatdevtree.c100
1 files changed, 78 insertions, 22 deletions
diff --git a/arch/powerpc/boot/flatdevtree.c b/arch/powerpc/boot/flatdevtree.c
index 13761bf160c4..cf30675c6116 100644
--- a/arch/powerpc/boot/flatdevtree.c
+++ b/arch/powerpc/boot/flatdevtree.c
@@ -354,16 +354,21 @@ static void ft_put_bin(struct ft_cxt *cxt, const void *data, unsigned int sz)
354 cxt->p += sza; 354 cxt->p += sza;
355} 355}
356 356
357int ft_begin_node(struct ft_cxt *cxt, const char *name) 357char *ft_begin_node(struct ft_cxt *cxt, const char *name)
358{ 358{
359 unsigned long nlen = strlen(name) + 1; 359 unsigned long nlen = strlen(name) + 1;
360 unsigned long len = 8 + _ALIGN(nlen, 4); 360 unsigned long len = 8 + _ALIGN(nlen, 4);
361 char *ret;
361 362
362 if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, len)) 363 if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, len))
363 return -1; 364 return NULL;
365
366 ret = cxt->p;
367
364 ft_put_word(cxt, OF_DT_BEGIN_NODE); 368 ft_put_word(cxt, OF_DT_BEGIN_NODE);
365 ft_put_bin(cxt, name, strlen(name) + 1); 369 ft_put_bin(cxt, name, strlen(name) + 1);
366 return 0; 370
371 return ret;
367} 372}
368 373
369void ft_end_node(struct ft_cxt *cxt) 374void ft_end_node(struct ft_cxt *cxt)
@@ -625,25 +630,17 @@ void ft_end_tree(struct ft_cxt *cxt)
625 bph->dt_strings_size = cpu_to_be32(ssize); 630 bph->dt_strings_size = cpu_to_be32(ssize);
626} 631}
627 632
628void *ft_find_device(struct ft_cxt *cxt, const char *srch_path) 633void *ft_find_device(struct ft_cxt *cxt, const void *top, const char *srch_path)
629{
630 char *node;
631
632 /* require absolute path */
633 if (srch_path[0] != '/')
634 return NULL;
635 node = ft_find_descendent(cxt, ft_root_node(cxt), srch_path);
636 return ft_get_phandle(cxt, node);
637}
638
639void *ft_find_device_rel(struct ft_cxt *cxt, const void *top,
640 const char *srch_path)
641{ 634{
642 char *node; 635 char *node;
643 636
644 node = ft_node_ph2node(cxt, top); 637 if (top) {
645 if (node == NULL) 638 node = ft_node_ph2node(cxt, top);
646 return NULL; 639 if (node == NULL)
640 return NULL;
641 } else {
642 node = ft_root_node(cxt);
643 }
647 644
648 node = ft_find_descendent(cxt, node, srch_path); 645 node = ft_find_descendent(cxt, node, srch_path);
649 return ft_get_phandle(cxt, node); 646 return ft_get_phandle(cxt, node);
@@ -945,7 +942,7 @@ int ft_del_prop(struct ft_cxt *cxt, const void *phandle, const char *propname)
945void *ft_create_node(struct ft_cxt *cxt, const void *parent, const char *name) 942void *ft_create_node(struct ft_cxt *cxt, const void *parent, const char *name)
946{ 943{
947 struct ft_atom atom; 944 struct ft_atom atom;
948 char *p, *next; 945 char *p, *next, *ret;
949 int depth = 0; 946 int depth = 0;
950 947
951 if (parent) { 948 if (parent) {
@@ -970,11 +967,70 @@ void *ft_create_node(struct ft_cxt *cxt, const void *parent, const char *name)
970 break; 967 break;
971 /* end of node, insert here */ 968 /* end of node, insert here */
972 cxt->p = p; 969 cxt->p = p;
973 ft_begin_node(cxt, name); 970 ret = ft_begin_node(cxt, name);
974 ft_end_node(cxt); 971 ft_end_node(cxt);
975 return p; 972 return ft_get_phandle(cxt, ret);
976 } 973 }
977 p = next; 974 p = next;
978 } 975 }
979 return NULL; 976 return NULL;
980} 977}
978
979/* Returns the start of the path within the provided buffer, or NULL on
980 * error.
981 */
982char *ft_get_path(struct ft_cxt *cxt, const void *phandle,
983 char *buf, int len)
984{
985 const char *path_comp[FT_MAX_DEPTH];
986 struct ft_atom atom;
987 char *p, *next, *pos;
988 int depth = 0, i;
989 void *node;
990
991 node = ft_node_ph2node(cxt, phandle);
992 if (node == NULL)
993 return NULL;
994
995 p = ft_root_node(cxt);
996
997 while ((next = ft_next(cxt, p, &atom)) != NULL) {
998 switch (atom.tag) {
999 case OF_DT_BEGIN_NODE:
1000 path_comp[depth++] = atom.name;
1001 if (p == node)
1002 goto found;
1003
1004 break;
1005
1006 case OF_DT_END_NODE:
1007 if (--depth == 0)
1008 return NULL;
1009 }
1010
1011 p = next;
1012 }
1013
1014found:
1015 pos = buf;
1016 for (i = 1; i < depth; i++) {
1017 int this_len;
1018
1019 if (len <= 1)
1020 return NULL;
1021
1022 *pos++ = '/';
1023 len--;
1024
1025 strncpy(pos, path_comp[i], len);
1026
1027 if (pos[len - 1] != 0)
1028 return NULL;
1029
1030 this_len = strlen(pos);
1031 len -= this_len;
1032 pos += this_len;
1033 }
1034
1035 return buf;
1036}