summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2016-07-09 12:31:06 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2016-07-09 12:31:06 +0000
commitb6f269b8c9cc451c29a728d0fd141fe1a55d2740 (patch)
tree9aabaf66bd294c276b5d2d63919cbaa6054b910a /sys/dev
parentf5a617912a3335375e11717bd7fb496e3e5e9f2e (diff)
Add interfaces to look up a device tree node by phandle.
ok patrick@, jsg@, visa@
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/ofw/fdt.c40
-rw-r--r--sys/dev/ofw/fdt.h3
-rw-r--r--sys/dev/ofw/openfirm.h3
3 files changed, 43 insertions, 3 deletions
diff --git a/sys/dev/ofw/fdt.c b/sys/dev/ofw/fdt.c
index 77c497282a7..96ca6284ef2 100644
--- a/sys/dev/ofw/fdt.c
+++ b/sys/dev/ofw/fdt.c
@@ -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.
*
@@ -752,6 +781,15 @@ OF_getnodebyname(int handle, const char *name)
}
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)
{
void *node = (char *)tree.header + handle;
diff --git a/sys/dev/ofw/fdt.h b/sys/dev/ofw/fdt.h
index 4949b426bdb..2e1c40517ab 100644
--- a/sys/dev/ofw/fdt.h
+++ b/sys/dev/ofw/fdt.h
@@ -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
diff --git a/sys/dev/ofw/openfirm.h b/sys/dev/ofw/openfirm.h
index 4d505deec4c..cf3ff9c6649 100644
--- a/sys/dev/ofw/openfirm.h
+++ b/sys/dev/ofw/openfirm.h
@@ -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.