]> git.sur5r.net Git - u-boot/blobdiff - libfdt/fdt_ro.c
Merge git://git.denx.de/u-boot into x1
[u-boot] / libfdt / fdt_ro.c
index 6292a00be5d30c2beaaf3d75fffb139628575f08..b705f91ecb760cd8120589f23865d58363ff56f0 100644 (file)
@@ -84,6 +84,14 @@ const char *fdt_string(const void *fdt, int stroffset)
        return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;
 }
 
+static int _fdt_string_eq(const void *fdt, int stroffset,
+                         const char *s, int len)
+{
+       const char *p = fdt_string(fdt, stroffset);
+
+       return (strlen(p) == len) && (memcmp(p, s, len) == 0);
+}
+
 int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)
 {
        FDT_CHECK_HEADER(fdt);
@@ -135,8 +143,20 @@ int fdt_path_offset(const void *fdt, const char *path)
 
        FDT_CHECK_HEADER(fdt);
 
-       if (*path != '/')
-               return -FDT_ERR_BADPATH;
+       /* see if we have an alias */
+       if (*path != '/') {
+               const char *q = strchr(path, '/');
+
+               if (!q)
+                       q = end;
+
+               p = fdt_get_alias_namelen(fdt, p, q - p);
+               if (!p)
+                       return -FDT_ERR_BADPATH;
+               offset = fdt_path_offset(fdt, p);
+
+               p = q;
+       }
 
        while (*p) {
                const char *q;
@@ -179,9 +199,10 @@ const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)
        return NULL;
 }
 
-const struct fdt_property *fdt_get_property(const void *fdt,
-                                           int nodeoffset,
-                                           const char *name, int *lenp)
+const struct fdt_property *fdt_get_property_namelen(const void *fdt,
+                                                   int nodeoffset,
+                                                   const char *name,
+                                                   int namelen, int *lenp)
 {
        uint32_t tag;
        const struct fdt_property *prop;
@@ -214,7 +235,7 @@ const struct fdt_property *fdt_get_property(const void *fdt,
                        if (! prop)
                                goto fail;
                        namestroff = fdt32_to_cpu(prop->nameoff);
-                       if (strcmp(fdt_string(fdt, namestroff), name) == 0) {
+                       if (_fdt_string_eq(fdt, namestroff, name, namelen)) {
                                /* Found it! */
                                int len = fdt32_to_cpu(prop->len);
                                prop = fdt_offset_ptr(fdt, offset,
@@ -242,18 +263,32 @@ const struct fdt_property *fdt_get_property(const void *fdt,
        return NULL;
 }
 
-const void *fdt_getprop(const void *fdt, int nodeoffset,
-                 const char *name, int *lenp)
+const struct fdt_property *fdt_get_property(const void *fdt,
+                                           int nodeoffset,
+                                           const char *name, int *lenp)
+{
+       return fdt_get_property_namelen(fdt, nodeoffset, name,
+                                       strlen(name), lenp);
+}
+
+const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,
+                               const char *name, int namelen, int *lenp)
 {
        const struct fdt_property *prop;
 
-       prop = fdt_get_property(fdt, nodeoffset, name, lenp);
+       prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp);
        if (! prop)
                return NULL;
 
        return prop->data;
 }
 
+const void *fdt_getprop(const void *fdt, int nodeoffset,
+                       const char *name, int *lenp)
+{
+       return fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), lenp);
+}
+
 uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
 {
        const uint32_t *php;
@@ -266,6 +301,23 @@ uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)
        return fdt32_to_cpu(*php);
 }
 
+const char *fdt_get_alias_namelen(const void *fdt,
+                                 const char *name, int namelen)
+{
+       int aliasoffset;
+
+       aliasoffset = fdt_path_offset(fdt, "/aliases");
+       if (aliasoffset < 0)
+               return NULL;
+
+       return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL);
+}
+
+const char *fdt_get_alias(const void *fdt, const char *name)
+{
+       return fdt_get_alias_namelen(fdt, name, strlen(name));
+}
+
 int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
 {
        int pdepth = 0, p = 0;
@@ -280,9 +332,6 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
        for (offset = 0, depth = 0;
             (offset >= 0) && (offset <= nodeoffset);
             offset = fdt_next_node(fdt, offset, &depth)) {
-               if (pdepth < depth)
-                       continue; /* overflowed buffer */
-
                while (pdepth > depth) {
                        do {
                                p--;
@@ -290,14 +339,16 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
                        pdepth--;
                }
 
-               name = fdt_get_name(fdt, offset, &namelen);
-               if (!name)
-                       return namelen;
-               if ((p + namelen + 1) <= buflen) {
-                       memcpy(buf + p, name, namelen);
-                       p += namelen;
-                       buf[p++] = '/';
-                       pdepth++;
+               if (pdepth >= depth) {
+                       name = fdt_get_name(fdt, offset, &namelen);
+                       if (!name)
+                               return namelen;
+                       if ((p + namelen + 1) <= buflen) {
+                               memcpy(buf + p, name, namelen);
+                               p += namelen;
+                               buf[p++] = '/';
+                               pdepth++;
+                       }
                }
 
                if (offset == nodeoffset) {
@@ -307,7 +358,7 @@ int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)
                        if (p > 1) /* special case so that root path is "/", not "" */
                                p--;
                        buf[p] = '\0';
-                       return p;
+                       return 0;
                }
        }