]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmbeddedPkg/Library/FdtLib/fdt_ro.c
EmbeddedPkg: Apply uncrustify changes
[mirror_edk2.git] / EmbeddedPkg / Library / FdtLib / fdt_ro.c
index 9413f50a110f4174fb59274a48b3d5e0f2845b68..30aac37958da239f69ed6a45236480212c1dd805 100644 (file)
 \r
 #include "libfdt_internal.h"\r
 \r
-static int _fdt_nodename_eq(const void *fdt, int offset,\r
-                           const char *s, int len)\r
+static int\r
+_fdt_nodename_eq (\r
+  const void  *fdt,\r
+  int         offset,\r
+  const char  *s,\r
+  int         len\r
+  )\r
 {\r
-       const char *p = fdt_offset_ptr(fdt, offset + FDT_TAGSIZE, len+1);\r
+  const char  *p = fdt_offset_ptr (fdt, offset + FDT_TAGSIZE, len+1);\r
 \r
-       if (!p)\r
-               /* short match */\r
-               return 0;\r
+  if (!p) {\r
+    /* short match */\r
+    return 0;\r
+  }\r
 \r
-       if (memcmp(p, s, len) != 0)\r
-               return 0;\r
+  if (memcmp (p, s, len) != 0) {\r
+    return 0;\r
+  }\r
 \r
-       if (p[len] == '\0')\r
-               return 1;\r
-       else if (!memchr(s, '@', len) && (p[len] == '@'))\r
-               return 1;\r
-       else\r
-               return 0;\r
+  if (p[len] == '\0') {\r
+    return 1;\r
+  } else if (!memchr (s, '@', len) && (p[len] == '@')) {\r
+    return 1;\r
+  } else {\r
+    return 0;\r
+  }\r
 }\r
 \r
-const char *fdt_string(const void *fdt, int stroffset)\r
+const char *\r
+fdt_string (\r
+  const void  *fdt,\r
+  int         stroffset\r
+  )\r
 {\r
-       return (const char *)fdt + fdt_off_dt_strings(fdt) + stroffset;\r
+  return (const char *)fdt + fdt_off_dt_strings (fdt) + stroffset;\r
 }\r
 \r
-static int _fdt_string_eq(const void *fdt, int stroffset,\r
-                         const char *s, int len)\r
+static int\r
+_fdt_string_eq (\r
+  const void  *fdt,\r
+  int         stroffset,\r
+  const char  *s,\r
+  int         len\r
+  )\r
 {\r
-       const char *p = fdt_string(fdt, stroffset);\r
+  const char  *p = fdt_string (fdt, stroffset);\r
 \r
-       return (strlen(p) == len) && (memcmp(p, s, len) == 0);\r
+  return (strlen (p) == len) && (memcmp (p, s, len) == 0);\r
 }\r
 \r
-uint32_t fdt_get_max_phandle(const void *fdt)\r
+uint32_t\r
+fdt_get_max_phandle (\r
+  const void  *fdt\r
+  )\r
 {\r
-       uint32_t max_phandle = 0;\r
-       int offset;\r
+  uint32_t  max_phandle = 0;\r
+  int       offset;\r
 \r
-       for (offset = fdt_next_node(fdt, -1, NULL);;\r
-            offset = fdt_next_node(fdt, offset, NULL)) {\r
-               uint32_t phandle;\r
+  for (offset = fdt_next_node (fdt, -1, NULL); ;\r
+       offset = fdt_next_node (fdt, offset, NULL))\r
+  {\r
+    uint32_t  phandle;\r
 \r
-               if (offset == -FDT_ERR_NOTFOUND)\r
-                       return max_phandle;\r
+    if (offset == -FDT_ERR_NOTFOUND) {\r
+      return max_phandle;\r
+    }\r
 \r
-               if (offset < 0)\r
-                       return (uint32_t)-1;\r
+    if (offset < 0) {\r
+      return (uint32_t)-1;\r
+    }\r
 \r
-               phandle = fdt_get_phandle(fdt, offset);\r
-               if (phandle == (uint32_t)-1)\r
-                       continue;\r
+    phandle = fdt_get_phandle (fdt, offset);\r
+    if (phandle == (uint32_t)-1) {\r
+      continue;\r
+    }\r
 \r
-               if (phandle > max_phandle)\r
-                       max_phandle = phandle;\r
-       }\r
+    if (phandle > max_phandle) {\r
+      max_phandle = phandle;\r
+    }\r
+  }\r
 \r
-       return 0;\r
+  return 0;\r
 }\r
 \r
-int fdt_get_mem_rsv(const void *fdt, int n, uint64_t *address, uint64_t *size)\r
+int\r
+fdt_get_mem_rsv (\r
+  const void  *fdt,\r
+  int         n,\r
+  uint64_t    *address,\r
+  uint64_t    *size\r
+  )\r
 {\r
-       FDT_CHECK_HEADER(fdt);\r
-       *address = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->address);\r
-       *size = fdt64_to_cpu(_fdt_mem_rsv(fdt, n)->size);\r
-       return 0;\r
+  FDT_CHECK_HEADER (fdt);\r
+  *address = fdt64_to_cpu (_fdt_mem_rsv (fdt, n)->address);\r
+  *size    = fdt64_to_cpu (_fdt_mem_rsv (fdt, n)->size);\r
+  return 0;\r
 }\r
 \r
-int fdt_num_mem_rsv(const void *fdt)\r
+int\r
+fdt_num_mem_rsv (\r
+  const void  *fdt\r
+  )\r
 {\r
-       int i = 0;\r
+  int  i = 0;\r
 \r
-       while (fdt64_to_cpu(_fdt_mem_rsv(fdt, i)->size) != 0)\r
-               i++;\r
-       return i;\r
-}\r
-\r
-static int _nextprop(const void *fdt, int offset)\r
-{\r
-       uint32_t tag;\r
-       int nextoffset;\r
-\r
-       do {\r
-               tag = fdt_next_tag(fdt, offset, &nextoffset);\r
-\r
-               switch (tag) {\r
-               case FDT_END:\r
-                       if (nextoffset >= 0)\r
-                               return -FDT_ERR_BADSTRUCTURE;\r
-                       else\r
-                               return nextoffset;\r
+  while (fdt64_to_cpu (_fdt_mem_rsv (fdt, i)->size) != 0) {\r
+    i++;\r
+  }\r
 \r
-               case FDT_PROP:\r
-                       return offset;\r
-               }\r
-               offset = nextoffset;\r
-       } while (tag == FDT_NOP);\r
-\r
-       return -FDT_ERR_NOTFOUND;\r
+  return i;\r
 }\r
 \r
-int fdt_subnode_offset_namelen(const void *fdt, int offset,\r
-                              const char *name, int namelen)\r
+static int\r
+_nextprop (\r
+  const void  *fdt,\r
+  int         offset\r
+  )\r
 {\r
-       int depth;\r
-\r
-       FDT_CHECK_HEADER(fdt);\r
-\r
-       for (depth = 0;\r
-            (offset >= 0) && (depth >= 0);\r
-            offset = fdt_next_node(fdt, offset, &depth))\r
-               if ((depth == 1)\r
-                   && _fdt_nodename_eq(fdt, offset, name, namelen))\r
-                       return offset;\r
-\r
-       if (depth < 0)\r
-               return -FDT_ERR_NOTFOUND;\r
-       return offset; /* error */\r
-}\r
-\r
-int fdt_subnode_offset(const void *fdt, int parentoffset,\r
-                      const char *name)\r
-{\r
-       return fdt_subnode_offset_namelen(fdt, parentoffset, name, strlen(name));\r
-}\r
-\r
-int fdt_path_offset_namelen(const void *fdt, const char *path, int namelen)\r
-{\r
-       const char *end = path + namelen;\r
-       const char *p = path;\r
-       int offset = 0;\r
-\r
-       FDT_CHECK_HEADER(fdt);\r
-\r
-       /* see if we have an alias */\r
-       if (*path != '/') {\r
-               const char *q = memchr(path, '/', end - p);\r
+  uint32_t  tag;\r
+  int       nextoffset;\r
 \r
-               if (!q)\r
-                       q = end;\r
+  do {\r
+    tag = fdt_next_tag (fdt, offset, &nextoffset);\r
 \r
-               p = fdt_get_alias_namelen(fdt, p, q - p);\r
-               if (!p)\r
-                       return -FDT_ERR_BADPATH;\r
-               offset = fdt_path_offset(fdt, p);\r
+    switch (tag) {\r
+      case FDT_END:\r
+        if (nextoffset >= 0) {\r
+          return -FDT_ERR_BADSTRUCTURE;\r
+        } else {\r
+          return nextoffset;\r
+        }\r
 \r
-               p = q;\r
-       }\r
+      case FDT_PROP:\r
+        return offset;\r
+    }\r
 \r
-       while (p < end) {\r
-               const char *q;\r
+    offset = nextoffset;\r
+  } while (tag == FDT_NOP);\r
 \r
-               while (*p == '/') {\r
-                       p++;\r
-                       if (p == end)\r
-                               return offset;\r
-               }\r
-               q = memchr(p, '/', end - p);\r
-               if (! q)\r
-                       q = end;\r
-\r
-               offset = fdt_subnode_offset_namelen(fdt, offset, p, q-p);\r
-               if (offset < 0)\r
-                       return offset;\r
-\r
-               p = q;\r
-       }\r
-\r
-       return offset;\r
+  return -FDT_ERR_NOTFOUND;\r
 }\r
 \r
-int fdt_path_offset(const void *fdt, const char *path)\r
+int\r
+fdt_subnode_offset_namelen (\r
+  const void  *fdt,\r
+  int         offset,\r
+  const char  *name,\r
+  int         namelen\r
+  )\r
 {\r
-       return fdt_path_offset_namelen(fdt, path, strlen(path));\r
-}\r
+  int  depth;\r
 \r
-const char *fdt_get_name(const void *fdt, int nodeoffset, int *len)\r
-{\r
-       const struct fdt_node_header *nh = _fdt_offset_ptr(fdt, nodeoffset);\r
-       int err;\r
+  FDT_CHECK_HEADER (fdt);\r
 \r
-       if (((err = fdt_check_header(fdt)) != 0)\r
-           || ((err = _fdt_check_node_offset(fdt, nodeoffset)) < 0))\r
-                       goto fail;\r
+  for (depth = 0;\r
+       (offset >= 0) && (depth >= 0);\r
+       offset = fdt_next_node (fdt, offset, &depth))\r
+  {\r
+    if (  (depth == 1)\r
+       && _fdt_nodename_eq (fdt, offset, name, namelen))\r
+    {\r
+      return offset;\r
+    }\r
+  }\r
 \r
-       if (len)\r
-               *len = strlen(nh->name);\r
+  if (depth < 0) {\r
+    return -FDT_ERR_NOTFOUND;\r
+  }\r
 \r
-       return nh->name;\r
-\r
- fail:\r
-       if (len)\r
-               *len = err;\r
-       return NULL;\r
+  return offset;       /* error */\r
 }\r
 \r
-int fdt_first_property_offset(const void *fdt, int nodeoffset)\r
+int\r
+fdt_subnode_offset (\r
+  const void  *fdt,\r
+  int         parentoffset,\r
+  const char  *name\r
+  )\r
 {\r
-       int offset;\r
-\r
-       if ((offset = _fdt_check_node_offset(fdt, nodeoffset)) < 0)\r
-               return offset;\r
-\r
-       return _nextprop(fdt, offset);\r
+  return fdt_subnode_offset_namelen (fdt, parentoffset, name, strlen (name));\r
 }\r
 \r
-int fdt_next_property_offset(const void *fdt, int offset)\r
+int\r
+fdt_path_offset_namelen (\r
+  const void  *fdt,\r
+  const char  *path,\r
+  int         namelen\r
+  )\r
 {\r
-       if ((offset = _fdt_check_prop_offset(fdt, offset)) < 0)\r
-               return offset;\r
+  const char  *end   = path + namelen;\r
+  const char  *p     = path;\r
+  int         offset = 0;\r
 \r
-       return _nextprop(fdt, offset);\r
-}\r
+  FDT_CHECK_HEADER (fdt);\r
 \r
-const struct fdt_property *fdt_get_property_by_offset(const void *fdt,\r
-                                                     int offset,\r
-                                                     int *lenp)\r
-{\r
-       int err;\r
-       const struct fdt_property *prop;\r
-\r
-       if ((err = _fdt_check_prop_offset(fdt, offset)) < 0) {\r
-               if (lenp)\r
-                       *lenp = err;\r
-               return NULL;\r
-       }\r
+  /* see if we have an alias */\r
+  if (*path != '/') {\r
+    const char  *q = memchr (path, '/', end - p);\r
 \r
-       prop = _fdt_offset_ptr(fdt, offset);\r
+    if (!q) {\r
+      q = end;\r
+    }\r
 \r
-       if (lenp)\r
-               *lenp = fdt32_to_cpu(prop->len);\r
+    p = fdt_get_alias_namelen (fdt, p, q - p);\r
+    if (!p) {\r
+      return -FDT_ERR_BADPATH;\r
+    }\r
 \r
-       return prop;\r
-}\r
+    offset = fdt_path_offset (fdt, p);\r
 \r
-const struct fdt_property *fdt_get_property_namelen(const void *fdt,\r
-                                                   int offset,\r
-                                                   const char *name,\r
-                                                   int namelen, int *lenp)\r
-{\r
-       for (offset = fdt_first_property_offset(fdt, offset);\r
-            (offset >= 0);\r
-            (offset = fdt_next_property_offset(fdt, offset))) {\r
-               const struct fdt_property *prop;\r
+    p = q;\r
+  }\r
 \r
-               if (!(prop = fdt_get_property_by_offset(fdt, offset, lenp))) {\r
-                       offset = -FDT_ERR_INTERNAL;\r
-                       break;\r
-               }\r
-               if (_fdt_string_eq(fdt, fdt32_to_cpu(prop->nameoff),\r
-                                  name, namelen))\r
-                       return prop;\r
-       }\r
+  while (p < end) {\r
+    const char  *q;\r
 \r
-       if (lenp)\r
-               *lenp = offset;\r
-       return NULL;\r
-}\r
+    while (*p == '/') {\r
+      p++;\r
+      if (p == end) {\r
+        return offset;\r
+      }\r
+    }\r
 \r
-const struct fdt_property *fdt_get_property(const void *fdt,\r
-                                           int nodeoffset,\r
-                                           const char *name, int *lenp)\r
-{\r
-       return fdt_get_property_namelen(fdt, nodeoffset, name,\r
-                                       strlen(name), lenp);\r
-}\r
+    q = memchr (p, '/', end - p);\r
+    if (!q) {\r
+      q = end;\r
+    }\r
 \r
-const void *fdt_getprop_namelen(const void *fdt, int nodeoffset,\r
-                               const char *name, int namelen, int *lenp)\r
-{\r
-       const struct fdt_property *prop;\r
+    offset = fdt_subnode_offset_namelen (fdt, offset, p, q-p);\r
+    if (offset < 0) {\r
+      return offset;\r
+    }\r
 \r
-       prop = fdt_get_property_namelen(fdt, nodeoffset, name, namelen, lenp);\r
-       if (!prop)\r
-               return NULL;\r
+    p = q;\r
+  }\r
 \r
-       return prop->data;\r
+  return offset;\r
 }\r
 \r
-const void *fdt_getprop_by_offset(const void *fdt, int offset,\r
-                                 const char **namep, int *lenp)\r
+int\r
+fdt_path_offset (\r
+  const void  *fdt,\r
+  const char  *path\r
+  )\r
 {\r
-       const struct fdt_property *prop;\r
-\r
-       prop = fdt_get_property_by_offset(fdt, offset, lenp);\r
-       if (!prop)\r
-               return NULL;\r
-       if (namep)\r
-               *namep = fdt_string(fdt, fdt32_to_cpu(prop->nameoff));\r
-       return prop->data;\r
+  return fdt_path_offset_namelen (fdt, path, strlen (path));\r
 }\r
 \r
-const void *fdt_getprop(const void *fdt, int nodeoffset,\r
-                       const char *name, int *lenp)\r
+const char *\r
+fdt_get_name (\r
+  const void  *fdt,\r
+  int         nodeoffset,\r
+  int         *len\r
+  )\r
 {\r
-       return fdt_getprop_namelen(fdt, nodeoffset, name, strlen(name), lenp);\r
-}\r
+  const struct fdt_node_header  *nh = _fdt_offset_ptr (fdt, nodeoffset);\r
+  int                           err;\r
 \r
-uint32_t fdt_get_phandle(const void *fdt, int nodeoffset)\r
-{\r
-       const fdt32_t *php;\r
-       int len;\r
+  if (  ((err = fdt_check_header (fdt)) != 0)\r
+     || ((err = _fdt_check_node_offset (fdt, nodeoffset)) < 0))\r
+  {\r
+    goto fail;\r
+  }\r
 \r
-       /* FIXME: This is a bit sub-optimal, since we potentially scan\r
-        * over all the properties twice. */\r
-       php = fdt_getprop(fdt, nodeoffset, "phandle", &len);\r
-       if (!php || (len != sizeof(*php))) {\r
-               php = fdt_getprop(fdt, nodeoffset, "linux,phandle", &len);\r
-               if (!php || (len != sizeof(*php)))\r
-                       return 0;\r
-       }\r
+  if (len) {\r
+    *len = strlen (nh->name);\r
+  }\r
 \r
-       return fdt32_to_cpu(*php);\r
-}\r
+  return nh->name;\r
 \r
-const char *fdt_get_alias_namelen(const void *fdt,\r
-                                 const char *name, int namelen)\r
-{\r
-       int aliasoffset;\r
+fail:\r
+  if (len) {\r
+    *len = err;\r
+  }\r
 \r
-       aliasoffset = fdt_path_offset(fdt, "/aliases");\r
-       if (aliasoffset < 0)\r
-               return NULL;\r
-\r
-       return fdt_getprop_namelen(fdt, aliasoffset, name, namelen, NULL);\r
-}\r
-\r
-const char *fdt_get_alias(const void *fdt, const char *name)\r
-{\r
-       return fdt_get_alias_namelen(fdt, name, strlen(name));\r
+  return NULL;\r
 }\r
 \r
-int fdt_get_path(const void *fdt, int nodeoffset, char *buf, int buflen)\r
+int\r
+fdt_first_property_offset (\r
+  const void  *fdt,\r
+  int         nodeoffset\r
+  )\r
 {\r
-       int pdepth = 0, p = 0;\r
-       int offset, depth, namelen;\r
-       const char *name;\r
+  int  offset;\r
 \r
-       FDT_CHECK_HEADER(fdt);\r
+  if ((offset = _fdt_check_node_offset (fdt, nodeoffset)) < 0) {\r
+    return offset;\r
+  }\r
 \r
-       if (buflen < 2)\r
-               return -FDT_ERR_NOSPACE;\r
-\r
-       for (offset = 0, depth = 0;\r
-            (offset >= 0) && (offset <= nodeoffset);\r
-            offset = fdt_next_node(fdt, offset, &depth)) {\r
-               while (pdepth > depth) {\r
-                       do {\r
-                               p--;\r
-                       } while (buf[p-1] != '/');\r
-                       pdepth--;\r
-               }\r
-\r
-               if (pdepth >= depth) {\r
-                       name = fdt_get_name(fdt, offset, &namelen);\r
-                       if (!name)\r
-                               return namelen;\r
-                       if ((p + namelen + 1) <= buflen) {\r
-                               memcpy(buf + p, name, namelen);\r
-                               p += namelen;\r
-                               buf[p++] = '/';\r
-                               pdepth++;\r
-                       }\r
-               }\r
-\r
-               if (offset == nodeoffset) {\r
-                       if (pdepth < (depth + 1))\r
-                               return -FDT_ERR_NOSPACE;\r
-\r
-                       if (p > 1) /* special case so that root path is "/", not "" */\r
-                               p--;\r
-                       buf[p] = '\0';\r
-                       return 0;\r
-               }\r
-       }\r
-\r
-       if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))\r
-               return -FDT_ERR_BADOFFSET;\r
-       else if (offset == -FDT_ERR_BADOFFSET)\r
-               return -FDT_ERR_BADSTRUCTURE;\r
-\r
-       return offset; /* error from fdt_next_node() */\r
+  return _nextprop (fdt, offset);\r
 }\r
 \r
-int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,\r
-                                int supernodedepth, int *nodedepth)\r
+int\r
+fdt_next_property_offset (\r
+  const void  *fdt,\r
+  int         offset\r
+  )\r
 {\r
-       int offset, depth;\r
-       int supernodeoffset = -FDT_ERR_INTERNAL;\r
-\r
-       FDT_CHECK_HEADER(fdt);\r
-\r
-       if (supernodedepth < 0)\r
-               return -FDT_ERR_NOTFOUND;\r
+  if ((offset = _fdt_check_prop_offset (fdt, offset)) < 0) {\r
+    return offset;\r
+  }\r
 \r
-       for (offset = 0, depth = 0;\r
-            (offset >= 0) && (offset <= nodeoffset);\r
-            offset = fdt_next_node(fdt, offset, &depth)) {\r
-               if (depth == supernodedepth)\r
-                       supernodeoffset = offset;\r
-\r
-               if (offset == nodeoffset) {\r
-                       if (nodedepth)\r
-                               *nodedepth = depth;\r
-\r
-                       if (supernodedepth > depth)\r
-                               return -FDT_ERR_NOTFOUND;\r
-                       else\r
-                               return supernodeoffset;\r
-               }\r
-       }\r
-\r
-       if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0))\r
-               return -FDT_ERR_BADOFFSET;\r
-       else if (offset == -FDT_ERR_BADOFFSET)\r
-               return -FDT_ERR_BADSTRUCTURE;\r
-\r
-       return offset; /* error from fdt_next_node() */\r
-}\r
-\r
-int fdt_node_depth(const void *fdt, int nodeoffset)\r
-{\r
-       int nodedepth;\r
-       int err;\r
-\r
-       err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);\r
-       if (err)\r
-               return (err < 0) ? err : -FDT_ERR_INTERNAL;\r
-       return nodedepth;\r
+  return _nextprop (fdt, offset);\r
 }\r
 \r
-int fdt_parent_offset(const void *fdt, int nodeoffset)\r
+const struct fdt_property *\r
+fdt_get_property_by_offset (\r
+  const void  *fdt,\r
+  int         offset,\r
+  int         *lenp\r
+  )\r
 {\r
-       int nodedepth = fdt_node_depth(fdt, nodeoffset);\r
+  int                        err;\r
+  const struct fdt_property  *prop;\r
 \r
-       if (nodedepth < 0)\r
-               return nodedepth;\r
-       return fdt_supernode_atdepth_offset(fdt, nodeoffset,\r
-                                           nodedepth - 1, NULL);\r
-}\r
+  if ((err = _fdt_check_prop_offset (fdt, offset)) < 0) {\r
+    if (lenp) {\r
+      *lenp = err;\r
+    }\r
 \r
-int fdt_node_offset_by_prop_value(const void *fdt, int startoffset,\r
-                                 const char *propname,\r
-                                 const void *propval, int proplen)\r
-{\r
-       int offset;\r
-       const void *val;\r
-       int len;\r
+    return NULL;\r
+  }\r
 \r
-       FDT_CHECK_HEADER(fdt);\r
+  prop = _fdt_offset_ptr (fdt, offset);\r
 \r
-       /* FIXME: The algorithm here is pretty horrible: we scan each\r
-        * property of a node in fdt_getprop(), then if that didn't\r
-        * find what we want, we scan over them again making our way\r
-        * to the next node.  Still it's the easiest to implement\r
-        * approach; performance can come later. */\r
-       for (offset = fdt_next_node(fdt, startoffset, NULL);\r
-            offset >= 0;\r
-            offset = fdt_next_node(fdt, offset, NULL)) {\r
-               val = fdt_getprop(fdt, offset, propname, &len);\r
-               if (val && (len == proplen)\r
-                   && (memcmp(val, propval, len) == 0))\r
-                       return offset;\r
-       }\r
+  if (lenp) {\r
+    *lenp = fdt32_to_cpu (prop->len);\r
+  }\r
 \r
-       return offset; /* error from fdt_next_node() */\r
+  return prop;\r
 }\r
 \r
-int fdt_node_offset_by_phandle(const void *fdt, uint32_t phandle)\r
+const struct fdt_property *\r
+fdt_get_property_namelen (\r
+  const void  *fdt,\r
+  int         offset,\r
+  const char  *name,\r
+  int         namelen,\r
+  int         *lenp\r
+  )\r
 {\r
-       int offset;\r
+  for (offset = fdt_first_property_offset (fdt, offset);\r
+       (offset >= 0);\r
+       (offset = fdt_next_property_offset (fdt, offset)))\r
+  {\r
+    const struct fdt_property  *prop;\r
 \r
-       if ((phandle == 0) || (phandle == -1))\r
-               return -FDT_ERR_BADPHANDLE;\r
+    if (!(prop = fdt_get_property_by_offset (fdt, offset, lenp))) {\r
+      offset = -FDT_ERR_INTERNAL;\r
+      break;\r
+    }\r
 \r
-       FDT_CHECK_HEADER(fdt);\r
+    if (_fdt_string_eq (\r
+          fdt,\r
+          fdt32_to_cpu (prop->nameoff),\r
+          name,\r
+          namelen\r
+          ))\r
+    {\r
+      return prop;\r
+    }\r
+  }\r
 \r
-       /* FIXME: The algorithm here is pretty horrible: we\r
-        * potentially scan each property of a node in\r
-        * fdt_get_phandle(), then if that didn't find what\r
-        * we want, we scan over them again making our way to the next\r
-        * node.  Still it's the easiest to implement approach;\r
-        * performance can come later. */\r
-       for (offset = fdt_next_node(fdt, -1, NULL);\r
-            offset >= 0;\r
-            offset = fdt_next_node(fdt, offset, NULL)) {\r
-               if (fdt_get_phandle(fdt, offset) == phandle)\r
-                       return offset;\r
-       }\r
+  if (lenp) {\r
+    *lenp = offset;\r
+  }\r
 \r
-       return offset; /* error from fdt_next_node() */\r
+  return NULL;\r
 }\r
 \r
-int fdt_stringlist_contains(const char *strlist, int listlen, const char *str)\r
+const struct fdt_property *\r
+fdt_get_property (\r
+  const void  *fdt,\r
+  int         nodeoffset,\r
+  const char  *name,\r
+  int         *lenp\r
+  )\r
 {\r
-       int len = strlen(str);\r
-       const char *p;\r
-\r
-       while (listlen >= len) {\r
-               if (memcmp(str, strlist, len+1) == 0)\r
-                       return 1;\r
-               p = memchr(strlist, '\0', listlen);\r
-               if (!p)\r
-                       return 0; /* malformed strlist.. */\r
-               listlen -= (p-strlist) + 1;\r
-               strlist = p + 1;\r
-       }\r
-       return 0;\r
+  return fdt_get_property_namelen (\r
+           fdt,\r
+           nodeoffset,\r
+           name,\r
+           strlen (name),\r
+           lenp\r
+           );\r
 }\r
 \r
-int fdt_stringlist_count(const void *fdt, int nodeoffset, const char *property)\r
+const void *\r
+fdt_getprop_namelen (\r
+  const void  *fdt,\r
+  int         nodeoffset,\r
+  const char  *name,\r
+  int         namelen,\r
+  int         *lenp\r
+  )\r
 {\r
-       const char *list, *end;\r
-       int length, count = 0;\r
-\r
-       list = fdt_getprop(fdt, nodeoffset, property, &length);\r
-       if (!list)\r
-               return length;\r
+  const struct fdt_property  *prop;\r
 \r
-       end = list + length;\r
+  prop = fdt_get_property_namelen (fdt, nodeoffset, name, namelen, lenp);\r
+  if (!prop) {\r
+    return NULL;\r
+  }\r
 \r
-       while (list < end) {\r
-               length = strnlen(list, end - list) + 1;\r
-\r
-               /* Abort if the last string isn't properly NUL-terminated. */\r
-               if (list + length > end)\r
-                       return -FDT_ERR_BADVALUE;\r
+  return prop->data;\r
+}\r
+\r
+const void *\r
+fdt_getprop_by_offset (\r
+  const void  *fdt,\r
+  int         offset,\r
+  const char  **namep,\r
+  int         *lenp\r
+  )\r
+{\r
+  const struct fdt_property  *prop;\r
+\r
+  prop = fdt_get_property_by_offset (fdt, offset, lenp);\r
+  if (!prop) {\r
+    return NULL;\r
+  }\r
+\r
+  if (namep) {\r
+    *namep = fdt_string (fdt, fdt32_to_cpu (prop->nameoff));\r
+  }\r
+\r
+  return prop->data;\r
+}\r
+\r
+const void *\r
+fdt_getprop (\r
+  const void  *fdt,\r
+  int         nodeoffset,\r
+  const char  *name,\r
+  int         *lenp\r
+  )\r
+{\r
+  return fdt_getprop_namelen (fdt, nodeoffset, name, strlen (name), lenp);\r
+}\r
+\r
+uint32_t\r
+fdt_get_phandle (\r
+  const void  *fdt,\r
+  int         nodeoffset\r
+  )\r
+{\r
+  const fdt32_t  *php;\r
+  int            len;\r
+\r
+  /* FIXME: This is a bit sub-optimal, since we potentially scan\r
+   * over all the properties twice. */\r
+  php = fdt_getprop (fdt, nodeoffset, "phandle", &len);\r
+  if (!php || (len != sizeof (*php))) {\r
+    php = fdt_getprop (fdt, nodeoffset, "linux,phandle", &len);\r
+    if (!php || (len != sizeof (*php))) {\r
+      return 0;\r
+    }\r
+  }\r
+\r
+  return fdt32_to_cpu (*php);\r
+}\r
+\r
+const char *\r
+fdt_get_alias_namelen (\r
+  const void  *fdt,\r
+  const char  *name,\r
+  int         namelen\r
+  )\r
+{\r
+  int  aliasoffset;\r
+\r
+  aliasoffset = fdt_path_offset (fdt, "/aliases");\r
+  if (aliasoffset < 0) {\r
+    return NULL;\r
+  }\r
+\r
+  return fdt_getprop_namelen (fdt, aliasoffset, name, namelen, NULL);\r
+}\r
+\r
+const char *\r
+fdt_get_alias (\r
+  const void  *fdt,\r
+  const char  *name\r
+  )\r
+{\r
+  return fdt_get_alias_namelen (fdt, name, strlen (name));\r
+}\r
+\r
+int\r
+fdt_get_path (\r
+  const void  *fdt,\r
+  int         nodeoffset,\r
+  char        *buf,\r
+  int         buflen\r
+  )\r
+{\r
+  int         pdepth = 0, p = 0;\r
+  int         offset, depth, namelen;\r
+  const char  *name;\r
+\r
+  FDT_CHECK_HEADER (fdt);\r
+\r
+  if (buflen < 2) {\r
+    return -FDT_ERR_NOSPACE;\r
+  }\r
+\r
+  for (offset = 0, depth = 0;\r
+       (offset >= 0) && (offset <= nodeoffset);\r
+       offset = fdt_next_node (fdt, offset, &depth))\r
+  {\r
+    while (pdepth > depth) {\r
+      do {\r
+        p--;\r
+      } while (buf[p-1] != '/');\r
+\r
+      pdepth--;\r
+    }\r
+\r
+    if (pdepth >= depth) {\r
+      name = fdt_get_name (fdt, offset, &namelen);\r
+      if (!name) {\r
+        return namelen;\r
+      }\r
+\r
+      if ((p + namelen + 1) <= buflen) {\r
+        memcpy (buf + p, name, namelen);\r
+        p       += namelen;\r
+        buf[p++] = '/';\r
+        pdepth++;\r
+      }\r
+    }\r
+\r
+    if (offset == nodeoffset) {\r
+      if (pdepth < (depth + 1)) {\r
+        return -FDT_ERR_NOSPACE;\r
+      }\r
+\r
+      if (p > 1) {\r
+        /* special case so that root path is "/", not "" */\r
+        p--;\r
+      }\r
+\r
+      buf[p] = '\0';\r
+      return 0;\r
+    }\r
+  }\r
+\r
+  if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) {\r
+    return -FDT_ERR_BADOFFSET;\r
+  } else if (offset == -FDT_ERR_BADOFFSET) {\r
+    return -FDT_ERR_BADSTRUCTURE;\r
+  }\r
+\r
+  return offset;       /* error from fdt_next_node() */\r
+}\r
+\r
+int\r
+fdt_supernode_atdepth_offset (\r
+  const void  *fdt,\r
+  int         nodeoffset,\r
+  int         supernodedepth,\r
+  int         *nodedepth\r
+  )\r
+{\r
+  int  offset, depth;\r
+  int  supernodeoffset = -FDT_ERR_INTERNAL;\r
+\r
+  FDT_CHECK_HEADER (fdt);\r
+\r
+  if (supernodedepth < 0) {\r
+    return -FDT_ERR_NOTFOUND;\r
+  }\r
+\r
+  for (offset = 0, depth = 0;\r
+       (offset >= 0) && (offset <= nodeoffset);\r
+       offset = fdt_next_node (fdt, offset, &depth))\r
+  {\r
+    if (depth == supernodedepth) {\r
+      supernodeoffset = offset;\r
+    }\r
+\r
+    if (offset == nodeoffset) {\r
+      if (nodedepth) {\r
+        *nodedepth = depth;\r
+      }\r
+\r
+      if (supernodedepth > depth) {\r
+        return -FDT_ERR_NOTFOUND;\r
+      } else {\r
+        return supernodeoffset;\r
+      }\r
+    }\r
+  }\r
+\r
+  if ((offset == -FDT_ERR_NOTFOUND) || (offset >= 0)) {\r
+    return -FDT_ERR_BADOFFSET;\r
+  } else if (offset == -FDT_ERR_BADOFFSET) {\r
+    return -FDT_ERR_BADSTRUCTURE;\r
+  }\r
+\r
+  return offset;       /* error from fdt_next_node() */\r
+}\r
+\r
+int\r
+fdt_node_depth (\r
+  const void  *fdt,\r
+  int         nodeoffset\r
+  )\r
+{\r
+  int  nodedepth;\r
+  int  err;\r
+\r
+  err = fdt_supernode_atdepth_offset (fdt, nodeoffset, 0, &nodedepth);\r
+  if (err) {\r
+    return (err < 0) ? err : -FDT_ERR_INTERNAL;\r
+  }\r
+\r
+  return nodedepth;\r
+}\r
+\r
+int\r
+fdt_parent_offset (\r
+  const void  *fdt,\r
+  int         nodeoffset\r
+  )\r
+{\r
+  int  nodedepth = fdt_node_depth (fdt, nodeoffset);\r
+\r
+  if (nodedepth < 0) {\r
+    return nodedepth;\r
+  }\r
+\r
+  return fdt_supernode_atdepth_offset (\r
+           fdt,\r
+           nodeoffset,\r
+           nodedepth - 1,\r
+           NULL\r
+           );\r
+}\r
+\r
+int\r
+fdt_node_offset_by_prop_value (\r
+  const void  *fdt,\r
+  int         startoffset,\r
+  const char  *propname,\r
+  const void  *propval,\r
+  int         proplen\r
+  )\r
+{\r
+  int         offset;\r
+  const void  *val;\r
+  int         len;\r
+\r
+  FDT_CHECK_HEADER (fdt);\r
+\r
+  /* FIXME: The algorithm here is pretty horrible: we scan each\r
+   * property of a node in fdt_getprop(), then if that didn't\r
+   * find what we want, we scan over them again making our way\r
+   * to the next node.  Still it's the easiest to implement\r
+   * approach; performance can come later. */\r
+  for (offset = fdt_next_node (fdt, startoffset, NULL);\r
+       offset >= 0;\r
+       offset = fdt_next_node (fdt, offset, NULL))\r
+  {\r
+    val = fdt_getprop (fdt, offset, propname, &len);\r
+    if (  val && (len == proplen)\r
+       && (memcmp (val, propval, len) == 0))\r
+    {\r
+      return offset;\r
+    }\r
+  }\r
+\r
+  return offset;       /* error from fdt_next_node() */\r
+}\r
+\r
+int\r
+fdt_node_offset_by_phandle (\r
+  const void  *fdt,\r
+  uint32_t    phandle\r
+  )\r
+{\r
+  int  offset;\r
+\r
+  if ((phandle == 0) || (phandle == -1)) {\r
+    return -FDT_ERR_BADPHANDLE;\r
+  }\r
+\r
+  FDT_CHECK_HEADER (fdt);\r
+\r
+  /* FIXME: The algorithm here is pretty horrible: we\r
+   * potentially scan each property of a node in\r
+   * fdt_get_phandle(), then if that didn't find what\r
+   * we want, we scan over them again making our way to the next\r
+   * node.  Still it's the easiest to implement approach;\r
+   * performance can come later. */\r
+  for (offset = fdt_next_node (fdt, -1, NULL);\r
+       offset >= 0;\r
+       offset = fdt_next_node (fdt, offset, NULL))\r
+  {\r
+    if (fdt_get_phandle (fdt, offset) == phandle) {\r
+      return offset;\r
+    }\r
+  }\r
+\r
+  return offset;       /* error from fdt_next_node() */\r
+}\r
+\r
+int\r
+fdt_stringlist_contains (\r
+  const char  *strlist,\r
+  int         listlen,\r
+  const char  *str\r
+  )\r
+{\r
+  int         len = strlen (str);\r
+  const char  *p;\r
+\r
+  while (listlen >= len) {\r
+    if (memcmp (str, strlist, len+1) == 0) {\r
+      return 1;\r
+    }\r
+\r
+    p = memchr (strlist, '\0', listlen);\r
+    if (!p) {\r
+      return 0;                   /* malformed strlist.. */\r
+    }\r
+\r
+    listlen -= (p-strlist) + 1;\r
+    strlist  = p + 1;\r
+  }\r
+\r
+  return 0;\r
+}\r
+\r
+int\r
+fdt_stringlist_count (\r
+  const void  *fdt,\r
+  int         nodeoffset,\r
+  const char  *property\r
+  )\r
+{\r
+  const char  *list, *end;\r
+  int         length, count = 0;\r
+\r
+  list = fdt_getprop (fdt, nodeoffset, property, &length);\r
+  if (!list) {\r
+    return length;\r
+  }\r
+\r
+  end = list + length;\r
+\r
+  while (list < end) {\r
+    length = strnlen (list, end - list) + 1;\r
+\r
+    /* Abort if the last string isn't properly NUL-terminated. */\r
+    if (list + length > end) {\r
+      return -FDT_ERR_BADVALUE;\r
+    }\r
 \r
-               list += length;\r
-               count++;\r
-       }\r
+    list += length;\r
+    count++;\r
+  }\r
 \r
-       return count;\r
+  return count;\r
 }\r
 \r
-int fdt_stringlist_search(const void *fdt, int nodeoffset, const char *property,\r
-                         const char *string)\r
+int\r
+fdt_stringlist_search (\r
+  const void  *fdt,\r
+  int         nodeoffset,\r
+  const char  *property,\r
+  const char  *string\r
+  )\r
 {\r
-       int length, len, idx = 0;\r
-       const char *list, *end;\r
+  int         length, len, idx = 0;\r
+  const char  *list, *end;\r
 \r
-       list = fdt_getprop(fdt, nodeoffset, property, &length);\r
-       if (!list)\r
-               return length;\r
+  list = fdt_getprop (fdt, nodeoffset, property, &length);\r
+  if (!list) {\r
+    return length;\r
+  }\r
 \r
-       len = strlen(string) + 1;\r
-       end = list + length;\r
+  len = strlen (string) + 1;\r
+  end = list + length;\r
 \r
-       while (list < end) {\r
-               length = strnlen(list, end - list) + 1;\r
+  while (list < end) {\r
+    length = strnlen (list, end - list) + 1;\r
 \r
-               /* Abort if the last string isn't properly NUL-terminated. */\r
-               if (list + length > end)\r
-                       return -FDT_ERR_BADVALUE;\r
+    /* Abort if the last string isn't properly NUL-terminated. */\r
+    if (list + length > end) {\r
+      return -FDT_ERR_BADVALUE;\r
+    }\r
 \r
-               if (length == len && memcmp(list, string, length) == 0)\r
-                       return idx;\r
+    if ((length == len) && (memcmp (list, string, length) == 0)) {\r
+      return idx;\r
+    }\r
 \r
-               list += length;\r
-               idx++;\r
-       }\r
+    list += length;\r
+    idx++;\r
+  }\r
 \r
-       return -FDT_ERR_NOTFOUND;\r
+  return -FDT_ERR_NOTFOUND;\r
 }\r
 \r
-const char *fdt_stringlist_get(const void *fdt, int nodeoffset,\r
-                              const char *property, int idx,\r
-                              int *lenp)\r
+const char *\r
+fdt_stringlist_get (\r
+  const void  *fdt,\r
+  int         nodeoffset,\r
+  const char  *property,\r
+  int         idx,\r
+  int         *lenp\r
+  )\r
 {\r
-       const char *list, *end;\r
-       int length;\r
+  const char  *list, *end;\r
+  int         length;\r
 \r
-       list = fdt_getprop(fdt, nodeoffset, property, &length);\r
-       if (!list) {\r
-               if (lenp)\r
-                       *lenp = length;\r
+  list = fdt_getprop (fdt, nodeoffset, property, &length);\r
+  if (!list) {\r
+    if (lenp) {\r
+      *lenp = length;\r
+    }\r
 \r
-               return NULL;\r
-       }\r
+    return NULL;\r
+  }\r
 \r
-       end = list + length;\r
+  end = list + length;\r
 \r
-       while (list < end) {\r
-               length = strnlen(list, end - list) + 1;\r
+  while (list < end) {\r
+    length = strnlen (list, end - list) + 1;\r
 \r
-               /* Abort if the last string isn't properly NUL-terminated. */\r
-               if (list + length > end) {\r
-                       if (lenp)\r
-                               *lenp = -FDT_ERR_BADVALUE;\r
+    /* Abort if the last string isn't properly NUL-terminated. */\r
+    if (list + length > end) {\r
+      if (lenp) {\r
+        *lenp = -FDT_ERR_BADVALUE;\r
+      }\r
 \r
-                       return NULL;\r
-               }\r
+      return NULL;\r
+    }\r
 \r
-               if (idx == 0) {\r
-                       if (lenp)\r
-                               *lenp = length - 1;\r
+    if (idx == 0) {\r
+      if (lenp) {\r
+        *lenp = length - 1;\r
+      }\r
 \r
-                       return list;\r
-               }\r
+      return list;\r
+    }\r
 \r
-               list += length;\r
-               idx--;\r
-       }\r
+    list += length;\r
+    idx--;\r
+  }\r
 \r
-       if (lenp)\r
-               *lenp = -FDT_ERR_NOTFOUND;\r
+  if (lenp) {\r
+    *lenp = -FDT_ERR_NOTFOUND;\r
+  }\r
 \r
-       return NULL;\r
+  return NULL;\r
 }\r
 \r
-int fdt_node_check_compatible(const void *fdt, int nodeoffset,\r
-                             const char *compatible)\r
+int\r
+fdt_node_check_compatible (\r
+  const void  *fdt,\r
+  int         nodeoffset,\r
+  const char  *compatible\r
+  )\r
 {\r
-       const void *prop;\r
-       int len;\r
+  const void  *prop;\r
+  int         len;\r
+\r
+  prop = fdt_getprop (fdt, nodeoffset, "compatible", &len);\r
+  if (!prop) {\r
+    return len;\r
+  }\r
 \r
-       prop = fdt_getprop(fdt, nodeoffset, "compatible", &len);\r
-       if (!prop)\r
-               return len;\r
-\r
-       return !fdt_stringlist_contains(prop, len, compatible);\r
+  return !fdt_stringlist_contains (prop, len, compatible);\r
 }\r
 \r
-int fdt_node_offset_by_compatible(const void *fdt, int startoffset,\r
-                                 const char *compatible)\r
+int\r
+fdt_node_offset_by_compatible (\r
+  const void  *fdt,\r
+  int         startoffset,\r
+  const char  *compatible\r
+  )\r
 {\r
-       int offset, err;\r
-\r
-       FDT_CHECK_HEADER(fdt);\r
+  int  offset, err;\r
 \r
-       /* FIXME: The algorithm here is pretty horrible: we scan each\r
-        * property of a node in fdt_node_check_compatible(), then if\r
-        * that didn't find what we want, we scan over them again\r
-        * making our way to the next node.  Still it's the easiest to\r
-        * implement approach; performance can come later. */\r
-       for (offset = fdt_next_node(fdt, startoffset, NULL);\r
-            offset >= 0;\r
-            offset = fdt_next_node(fdt, offset, NULL)) {\r
-               err = fdt_node_check_compatible(fdt, offset, compatible);\r
-               if ((err < 0) && (err != -FDT_ERR_NOTFOUND))\r
-                       return err;\r
-               else if (err == 0)\r
-                       return offset;\r
-       }\r
+  FDT_CHECK_HEADER (fdt);\r
 \r
-       return offset; /* error from fdt_next_node() */\r
+  /* FIXME: The algorithm here is pretty horrible: we scan each\r
+   * property of a node in fdt_node_check_compatible(), then if\r
+   * that didn't find what we want, we scan over them again\r
+   * making our way to the next node.  Still it's the easiest to\r
+   * implement approach; performance can come later. */\r
+  for (offset = fdt_next_node (fdt, startoffset, NULL);\r
+       offset >= 0;\r
+       offset = fdt_next_node (fdt, offset, NULL))\r
+  {\r
+    err = fdt_node_check_compatible (fdt, offset, compatible);\r
+    if ((err < 0) && (err != -FDT_ERR_NOTFOUND)) {\r
+      return err;\r
+    } else if (err == 0) {\r
+      return offset;\r
+    }\r
+  }\r
+\r
+  return offset;       /* error from fdt_next_node() */\r
 }\r