aboutsummaryrefslogtreecommitdiff
path: root/device_tree.c
diff options
context:
space:
mode:
authorEric Auger <eric.auger@redhat.com>2018-06-29 15:11:01 +0100
committerPeter Maydell <peter.maydell@linaro.org>2018-06-29 15:11:01 +0100
commitf963cc26dfd7832b6371c312a817a1950bfe398a (patch)
tree48376d69c0179a572cb4f528ba2d2a4a3e36c469 /device_tree.c
parent38754e43f605be90f0603631f257b3bc2d115126 (diff)
device_tree: Add qemu_fdt_node_unit_path
This helper allows to retrieve the paths of nodes whose name match node-name or node-name@unit-address patterns. Signed-off-by: Eric Auger <eric.auger@redhat.com> Message-id: 1530044492-24921-2-git-send-email-eric.auger@redhat.com Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'device_tree.c')
-rw-r--r--device_tree.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/device_tree.c b/device_tree.c
index 3553819257..6d9c9726f6 100644
--- a/device_tree.c
+++ b/device_tree.c
@@ -232,6 +232,61 @@ static int findnode_nofail(void *fdt, const char *node_path)
return offset;
}
+char **qemu_fdt_node_unit_path(void *fdt, const char *name, Error **errp)
+{
+ char *prefix = g_strdup_printf("%s@", name);
+ unsigned int path_len = 16, n = 0;
+ GSList *path_list = NULL, *iter;
+ const char *iter_name;
+ int offset, len, ret;
+ char **path_array;
+
+ offset = fdt_next_node(fdt, -1, NULL);
+
+ while (offset >= 0) {
+ iter_name = fdt_get_name(fdt, offset, &len);
+ if (!iter_name) {
+ offset = len;
+ break;
+ }
+ if (!strcmp(iter_name, name) || g_str_has_prefix(iter_name, prefix)) {
+ char *path;
+
+ path = g_malloc(path_len);
+ while ((ret = fdt_get_path(fdt, offset, path, path_len))
+ == -FDT_ERR_NOSPACE) {
+ path_len += 16;
+ path = g_realloc(path, path_len);
+ }
+ path_list = g_slist_prepend(path_list, path);
+ n++;
+ }
+ offset = fdt_next_node(fdt, offset, NULL);
+ }
+ g_free(prefix);
+
+ if (offset < 0 && offset != -FDT_ERR_NOTFOUND) {
+ error_setg(errp, "%s: abort parsing dt for %s node units: %s",
+ __func__, name, fdt_strerror(offset));
+ for (iter = path_list; iter; iter = iter->next) {
+ g_free(iter->data);
+ }
+ g_slist_free(path_list);
+ return NULL;
+ }
+
+ path_array = g_new(char *, n + 1);
+ path_array[n--] = NULL;
+
+ for (iter = path_list; iter; iter = iter->next) {
+ path_array[n--] = iter->data;
+ }
+
+ g_slist_free(path_list);
+
+ return path_array;
+}
+
char **qemu_fdt_node_path(void *fdt, const char *name, char *compat,
Error **errp)
{