Add interfaces to look up a device tree node by phandle.
authorkettenis <kettenis@openbsd.org>
Sat, 9 Jul 2016 12:31:05 +0000 (12:31 +0000)
committerkettenis <kettenis@openbsd.org>
Sat, 9 Jul 2016 12:31:05 +0000 (12:31 +0000)
ok patrick@, jsg@, visa@

sys/dev/ofw/fdt.c
sys/dev/ofw/fdt.h
sys/dev/ofw/openfirm.h

index 77c4972..96ca628 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: fdt.c,v 1.16 2016/07/08 18:20:48 kettenis Exp $       */
+/*     $OpenBSD: fdt.c,v 1.17 2016/07/09 12:31:05 kettenis Exp $       */
 
 /*
  * Copyright (c) 2009 Dariusz Swiderski <sfires@sfires.net>
@@ -35,6 +35,7 @@ void  *skip_node_name(u_int32_t *);
 void   *skip_node(void *);
 void   *skip_nops(u_int32_t *);
 void   *fdt_parent_node_recurse(void *, void *);
+void   *fdt_find_phandle_recurse(void *, uint32_t);
 int     fdt_node_property_int(void *, char *, int *);
 int     fdt_node_property_ints(void *, char *, int *, int);
 int     fdt_translate_memory_address(void *, struct fdt_memory *);
@@ -443,6 +444,34 @@ fdt_parent_node(void *node)
        return fdt_parent_node_recurse(pnode, node);
 }
 
+void *
+fdt_find_phandle_recurse(void *node, uint32_t phandle)
+{
+       void *child;
+       char *data;
+       void *tmp;
+       int len;
+
+       len = fdt_node_property(node, "phandle", &data);
+       if (len < 0)
+               len = fdt_node_property(node, "linux,phandle", &data);
+
+       if (len == sizeof(uint32_t) && bemtoh32(data) == phandle)
+               return node;
+
+       for (child = fdt_child_node(node); child; child = fdt_next_node(child))
+               if ((tmp = fdt_find_phandle_recurse(child, phandle)))
+                       return tmp;
+
+       return NULL;
+}
+
+void *
+fdt_find_phandle(uint32_t phandle)
+{
+       return fdt_find_phandle_recurse(fdt_next_node(0), phandle);
+}
+
 /*
  * Translate memory address depending on parent's range.
  *
@@ -751,6 +780,15 @@ OF_getnodebyname(int handle, const char *name)
        return node ? ((char *)node - (char *)tree.header) : 0;
 }
 
+int
+OF_getnodebyphandle(uint32_t phandle)
+{
+       void *node;
+
+       node = fdt_find_phandle(phandle);
+       return node ? ((char *)node - (char *)tree.header) : 0;
+}
+
 int
 OF_getproplen(int handle, char *prop)
 {
index 4949b42..2e1c405 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: fdt.h,v 1.3 2016/06/08 15:27:05 jsg Exp $     */
+/*     $OpenBSD: fdt.h,v 1.4 2016/07/09 12:31:05 kettenis Exp $        */
 
 /*
  * Copyright (c) 2009 Dariusz Swiderski <sfires@sfires.net>
@@ -60,6 +60,7 @@ char  *fdt_node_name(void *);
 void   *fdt_find_node(char *);
 int     fdt_node_property(void *, char *, char **);
 void   *fdt_parent_node(void *);
+void   *fdt_find_phandle(uint32_t);
 int     fdt_get_memory_address(void *, int, struct fdt_memory *);
 int     fdt_is_compatible(void *, const char *);
 #ifdef DEBUG
index 4d505de..cf3ff9c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: openfirm.h,v 1.12 2016/06/12 12:55:42 kettenis Exp $  */
+/*     $OpenBSD: openfirm.h,v 1.13 2016/07/09 12:31:05 kettenis Exp $  */
 /*     $NetBSD: openfirm.h,v 1.1 1996/09/30 16:35:10 ws Exp $  */
 
 /*
@@ -71,6 +71,7 @@ int OF_interpret(char *cmd, int nreturns, ...);
 void (*OF_set_callback(void (*newfunc)(void *))) ();
 #endif
 int OF_getnodebyname(int, const char *);
+int OF_getnodebyphandle(uint32_t);
 
 /*
  * Some generic routines for OpenFirmware handling.