aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/powerpc/boot/flatdevtree.c59
-rw-r--r--arch/powerpc/boot/flatdevtree.h1
-rw-r--r--arch/powerpc/boot/flatdevtree_misc.c6
-rw-r--r--arch/powerpc/boot/ops.h9
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 */
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}
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);
110void *ft_create_node(struct ft_cxt *cxt, const void *parent, const char *name); 110void *ft_create_node(struct ft_cxt *cxt, const void *parent, const char *name);
111char *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
61static char *fdtm_get_path(const void *phandle, char *buf, int len)
62{
63 return ft_get_path(&cxt, phandle, buf, len);
64}
65
61int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device) 66int 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};
51extern struct dt_ops dt_ops; 52extern 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
174static 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
173static inline void *malloc(unsigned long size) 182static 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;