diff options
-rw-r--r-- | arch/powerpc/boot/flatdevtree.c | 59 | ||||
-rw-r--r-- | arch/powerpc/boot/flatdevtree.h | 1 | ||||
-rw-r--r-- | arch/powerpc/boot/flatdevtree_misc.c | 6 | ||||
-rw-r--r-- | arch/powerpc/boot/ops.h | 9 |
4 files changed, 75 insertions, 0 deletions
diff --git a/arch/powerpc/boot/flatdevtree.c b/arch/powerpc/boot/flatdevtree.c index 0af7291fc67c..cf30675c6116 100644 --- a/arch/powerpc/boot/flatdevtree.c +++ b/arch/powerpc/boot/flatdevtree.c | |||
@@ -975,3 +975,62 @@ void *ft_create_node(struct ft_cxt *cxt, const void *parent, const char *name) | |||
975 | } | 975 | } |
976 | return NULL; | 976 | return NULL; |
977 | } | 977 | } |
978 | |||
979 | /* Returns the start of the path within the provided buffer, or NULL on | ||
980 | * error. | ||
981 | */ | ||
982 | char *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 | |||
1014 | found: | ||
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 | } | ||
diff --git a/arch/powerpc/boot/flatdevtree.h b/arch/powerpc/boot/flatdevtree.h index 2c1c826c4eca..b0957a2d967f 100644 --- a/arch/powerpc/boot/flatdevtree.h +++ b/arch/powerpc/boot/flatdevtree.h | |||
@@ -108,5 +108,6 @@ void *ft_find_node_by_prop_value(struct ft_cxt *cxt, const void *prev, | |||
108 | const char *propname, const char *propval, | 108 | const char *propname, const char *propval, |
109 | int proplen); | 109 | int proplen); |
110 | void *ft_create_node(struct ft_cxt *cxt, const void *parent, const char *name); | 110 | void *ft_create_node(struct ft_cxt *cxt, const void *parent, const char *name); |
111 | char *ft_get_path(struct ft_cxt *cxt, const void *phandle, char *buf, int len); | ||
111 | 112 | ||
112 | #endif /* FLATDEVTREE_H */ | 113 | #endif /* FLATDEVTREE_H */ |
diff --git a/arch/powerpc/boot/flatdevtree_misc.c b/arch/powerpc/boot/flatdevtree_misc.c index 8d1debe8d941..b3670096fa71 100644 --- a/arch/powerpc/boot/flatdevtree_misc.c +++ b/arch/powerpc/boot/flatdevtree_misc.c | |||
@@ -58,6 +58,11 @@ static unsigned long fdtm_finalize(void) | |||
58 | return (unsigned long)cxt.bph; | 58 | return (unsigned long)cxt.bph; |
59 | } | 59 | } |
60 | 60 | ||
61 | static char *fdtm_get_path(const void *phandle, char *buf, int len) | ||
62 | { | ||
63 | return ft_get_path(&cxt, phandle, buf, len); | ||
64 | } | ||
65 | |||
61 | int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device) | 66 | int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device) |
62 | { | 67 | { |
63 | dt_ops.finddevice = fdtm_finddevice; | 68 | dt_ops.finddevice = fdtm_finddevice; |
@@ -67,6 +72,7 @@ int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device) | |||
67 | dt_ops.create_node = fdtm_create_node; | 72 | dt_ops.create_node = fdtm_create_node; |
68 | dt_ops.find_node_by_prop_value = fdtm_find_node_by_prop_value; | 73 | dt_ops.find_node_by_prop_value = fdtm_find_node_by_prop_value; |
69 | dt_ops.finalize = fdtm_finalize; | 74 | dt_ops.finalize = fdtm_finalize; |
75 | dt_ops.get_path = fdtm_get_path; | ||
70 | 76 | ||
71 | return ft_open(&cxt, dt_blob, max_size, max_find_device, | 77 | return ft_open(&cxt, dt_blob, max_size, max_find_device, |
72 | platform_ops.realloc); | 78 | platform_ops.realloc); |
diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h index 45c2268d5c56..703255bf0089 100644 --- a/arch/powerpc/boot/ops.h +++ b/arch/powerpc/boot/ops.h | |||
@@ -47,6 +47,7 @@ struct dt_ops { | |||
47 | const char *propname, | 47 | const char *propname, |
48 | const char *propval, int proplen); | 48 | const char *propval, int proplen); |
49 | unsigned long (*finalize)(void); | 49 | unsigned long (*finalize)(void); |
50 | char *(*get_path)(const void *phandle, char *buf, int len); | ||
50 | }; | 51 | }; |
51 | extern struct dt_ops dt_ops; | 52 | extern struct dt_ops dt_ops; |
52 | 53 | ||
@@ -170,6 +171,14 @@ static inline void *find_node_by_linuxphandle(const u32 linuxphandle) | |||
170 | (char *)&linuxphandle, sizeof(u32)); | 171 | (char *)&linuxphandle, sizeof(u32)); |
171 | } | 172 | } |
172 | 173 | ||
174 | static inline char *get_path(const void *phandle, char *buf, int len) | ||
175 | { | ||
176 | if (dt_ops.get_path) | ||
177 | return dt_ops.get_path(phandle, buf, len); | ||
178 | |||
179 | return NULL; | ||
180 | } | ||
181 | |||
173 | static inline void *malloc(unsigned long size) | 182 | static inline void *malloc(unsigned long size) |
174 | { | 183 | { |
175 | return (platform_ops.malloc) ? platform_ops.malloc(size) : NULL; | 184 | return (platform_ops.malloc) ? platform_ops.malloc(size) : NULL; |