From 405552399f9ce4fa14a791eb8b84baba2c87963d Mon Sep 17 00:00:00 2001 From: Burt P Date: Wed, 19 Jul 2017 03:30:43 -0500 Subject: device tree: fixes * /aliases/* and /__symbols/* are always strings * phandle ref element bug fix, re-enabled phandle refs * notes on a few more property types Signed-off-by: Burt P --- includes/dt_util.h | 7 ++++-- modules/devices/devicetree/dt_util.c | 41 ++++++++++++++++++++++++++---------- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/includes/dt_util.h b/includes/dt_util.h index 95373c00..18de6094 100644 --- a/includes/dt_util.h +++ b/includes/dt_util.h @@ -5,7 +5,7 @@ #include /* some not-quite-complete stuff that can be disabled */ -#define DTEX_PHREFS 0 +#define DTEX_PHREFS 1 #ifndef DTR_ROOT #define DTR_ROOT "/proc/device-tree" @@ -23,6 +23,9 @@ enum { /* DTP_INT, */ DTP_PH, /* phandle */ DTP_PH_REF, /* reference to phandle */ + DTP_REG, /* <#address-cells, #size-cells> */ + DTP_CLOCKS, /* */ + DTP_GPIOS, /* */ }; /* simplest, no aliases. @@ -56,7 +59,7 @@ uint32_t dtr_get_prop_u32(dtr *, dtr_obj *node, const char *name); char* dtr_str(dtr_obj *obj); int dtr_guess_type(dtr_obj *obj); -char *dtr_elem_phref(dtr *, dt_uint e); +char *dtr_elem_phref(dtr *, dt_uint e, int show_path); char *dtr_elem_hex(dt_uint e); char *dtr_elem_byte(uint8_t e); char *dtr_elem_uint(dt_uint e); diff --git a/modules/devices/devicetree/dt_util.c b/modules/devices/devicetree/dt_util.c index 3e0cdd37..684b2f89 100644 --- a/modules/devices/devicetree/dt_util.c +++ b/modules/devices/devicetree/dt_util.c @@ -33,9 +33,9 @@ static struct { { "name", DTP_STR }, { "compatible", DTP_STR }, { "model", DTP_STR }, - { "reg", DTP_HEX }, - { "clocks", DTP_HEX }, - { "gpios", DTP_HEX }, + { "reg", DTP_REG }, + { "clocks", DTP_CLOCKS }, + { "gpios", DTP_GPIOS }, { "phandle", DTP_PH }, { "interrupts", DTP_HEX }, { "interrupt-parent", DTP_PH_REF }, @@ -109,6 +109,10 @@ void dtr_map_free(dtr_map *map) { const char *dtr_phandle_lookup(dtr *s, uint32_t v) { dtr_map *phi = s->phandles; + /* 0 and 0xffffffff are invalid phandle values */ + /* TODO: perhaps "INVALID" or something */ + if (v == 0 || v == 0xffffffff) + return NULL; while(phi != NULL) { if (phi->v == v) return phi->path; @@ -359,6 +363,12 @@ int dtr_guess_type(dtr_obj *obj) { } } + /* /aliases/* and /__symbols/* are always strings */ + if (strncmp(obj->path, "/aliases/", strlen("/aliases/") ) == 0) + return DTP_STR; + if (strncmp(obj->path, "/__symbols__/", strlen("/__symbols__/") ) == 0) + return DTP_STR; + /* lookup known type */ while (prop_types[i].name != NULL) { if (strcmp(obj->name, prop_types[i].name) == 0) @@ -387,17 +397,23 @@ int dtr_guess_type(dtr_obj *obj) { return DTP_UNK; } -char *dtr_elem_phref(dtr *s, dt_uint e) { - char *ph_path, *al_label, *ret = NULL; - ph_path = (char*)dtr_phandle_lookup(s, be32toh(e)); +char *dtr_elem_phref(dtr *s, dt_uint e, int show_path) { + const char *ph_path, *al_label; + char *ret = NULL; + ph_path = dtr_phandle_lookup(s, be32toh(e)); if (ph_path != NULL) { - al_label = (char*)dtr_alias_lookup_by_path(s, ph_path); + /* TODO: alias or symbol? */ + al_label = dtr_symbol_lookup_by_path(s, ph_path); if (al_label != NULL) { - ret = g_strdup_printf("&%s", al_label); + if (show_path) + ret = g_strdup_printf("&%s (%s)", al_label, ph_path); + else + ret = g_strdup_printf("&%s", al_label); + } else { + if (show_path) + ret = g_strdup_printf("0x%x (%s)", be32toh(e), ph_path); } } - free(ph_path); - free(al_label); if (ret == NULL) ret = dtr_elem_hex(e); return ret; @@ -500,6 +516,9 @@ char* dtr_str(dtr_obj *obj) { ret = dtr_list_str0(obj->data_str, obj->length); break; case DTP_PH: + case DTP_REG: + case DTP_CLOCKS: + case DTP_GPIOS: case DTP_HEX: if (obj->length % 4) ret = dtr_list_byte((uint8_t*)obj->data, obj->length); @@ -507,7 +526,7 @@ char* dtr_str(dtr_obj *obj) { ret = dtr_list_hex(obj->data, obj->length / 4); break; case DTP_PH_REF: - ret = dtr_elem_phref(obj->dt, *obj->data_int); + ret = dtr_elem_phref(obj->dt, *obj->data_int, 1); break; case DTP_UINT: ret = dtr_elem_uint(*obj->data_int); -- cgit v1.2.3