Skip to content

Commit

Permalink
device: add dt_find_by_name_addr
Browse files Browse the repository at this point in the history
Adds two helper functions that allow device nodes to be found via
their name and unit address. One will take an integer address and
format it to a hex string while the other looks up the unit based
a user supplied string. This is handy in a few places inside the
HDAT parser.

Signed-off-by: Oliver O'Halloran <oohall@gmail.com>
Reviewed-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
  • Loading branch information
oohal authored and stewartsmith committed Apr 7, 2017
1 parent 47a4831 commit 510e2b0
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 0 deletions.
50 changes: 50 additions & 0 deletions core/device.c
Expand Up @@ -21,6 +21,7 @@
#include <libfdt/libfdt_internal.h>
#include <ccan/str/str.h>
#include <ccan/endian/endian.h>
#include <inttypes.h>

/* Used to give unique handles. */
u32 last_phandle = 0;
Expand Down Expand Up @@ -155,6 +156,55 @@ struct dt_node *dt_new(struct dt_node *parent, const char *name)
return new;
}

/*
* low level variant, we export this because there are "weird" address
* formats, such as LPC/ISA bus addresses which have a letter to identify
* which bus space the address is inside of.
*/
struct dt_node *__dt_find_by_name_addr(struct dt_node *parent, const char *name,
const char *addr)
{
struct dt_node *node;

if (list_empty(&parent->children))
return NULL;

dt_for_each_child(parent, node) {
const char *unit = get_unitname(node);
int len;

if (!unit)
continue;

/* match the name */
len = (int) (unit - node->name) - 1;
if (strncmp(node->name, name, len))
continue;

/* match the unit */
if (strcmp(unit, addr) == 0)
return node;
}

dt_for_each_child(parent, node) {
struct dt_node *ret = __dt_find_by_name_addr(node, name, addr);

if (ret)
return ret;
}

return NULL;
}

struct dt_node *dt_find_by_name_addr(struct dt_node *parent, const char *name,
uint64_t addr)
{
char addr_str[16 + 1]; /* max size of a 64bit int */
snprintf(addr_str, sizeof(addr_str), "%" PRIx64, addr);

return __dt_find_by_name_addr(parent, name, addr_str);
}

struct dt_node *dt_new_addr(struct dt_node *parent, const char *name,
uint64_t addr)
{
Expand Down
1 change: 1 addition & 0 deletions core/test/run-device.c
Expand Up @@ -150,6 +150,7 @@ int main(void)
assert(!list_top(&addr1->properties, struct dt_property, list));
check_path(addr1, "/addrs/addr@1337");
assert(dt_find_by_name(root, "addr@1337") == addr1);
assert(dt_find_by_name_addr(root, "addr", 0x1337) == addr1);
assert(dt_find_by_path(root, "/addrs/addr@1337") == addr1);

addr2 = dt_new_2addr(addrs, "2addr", 0xdead, 0xbeef);
Expand Down
5 changes: 5 additions & 0 deletions include/device.h
Expand Up @@ -247,4 +247,9 @@ u64 dt_translate_address(const struct dt_node *node, unsigned int index,
*/
int dt_cmp_subnodes(const struct dt_node *a, const struct dt_node *b);

struct dt_node *__dt_find_by_name_addr(struct dt_node *parent, const char *name,
const char *addr);
struct dt_node *dt_find_by_name_addr(struct dt_node *parent, const char *name,
uint64_t addr);

#endif /* __DEVICE_H */

0 comments on commit 510e2b0

Please sign in to comment.