From d0cd2b3a7284f73e9d8033370adc687373e80086 Mon Sep 17 00:00:00 2001 From: kettenis Date: Sat, 9 Jul 2016 12:31:05 +0000 Subject: [PATCH] Add interfaces to look up a device tree node by phandle. ok patrick@, jsg@, visa@ --- sys/dev/ofw/fdt.c | 40 +++++++++++++++++++++++++++++++++++++++- sys/dev/ofw/fdt.h | 3 ++- sys/dev/ofw/openfirm.h | 3 ++- 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 @@ -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) { 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 @@ -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. -- 2.20.1