aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnup Patel <anup.patel@wdc.com>2020-04-24 18:32:10 +0530
committerAnup Patel <anup@brainfault.org>2020-05-01 09:39:44 +0530
commita39cd6fe4c263f00228daaefc41c2b03b96f784d (patch)
tree1edcbfc52d0e842e7c4a7f1cf50fbbaa3618d58c
parente3ad7c13a07275df7f3dbee68e3e95d73d7a1e0e (diff)
downloadopensbi-a39cd6fe4c263f00228daaefc41c2b03b96f784d.tar.gz
opensbi-a39cd6fe4c263f00228daaefc41c2b03b96f784d.tar.bz2
opensbi-a39cd6fe4c263f00228daaefc41c2b03b96f784d.zip
lib: utils: Add FDT match table based node lookup
This patch adds FDT match table based node lookup funcitons. These functions will be useful in implementing simple FDT based driver frameworks. Signed-off-by: Anup Patel <anup.patel@wdc.com> Reviewed-by: Atish Patra <atish.patra@wdc.com>
-rw-r--r--include/sbi_utils/fdt/fdt_helper.h11
-rw-r--r--lib/utils/fdt/fdt_helper.c41
2 files changed, 52 insertions, 0 deletions
diff --git a/include/sbi_utils/fdt/fdt_helper.h b/include/sbi_utils/fdt/fdt_helper.h
index 57c47201..a5254930 100644
--- a/include/sbi_utils/fdt/fdt_helper.h
+++ b/include/sbi_utils/fdt/fdt_helper.h
@@ -10,6 +10,11 @@
#ifndef __FDT_HELPER_H__
#define __FDT_HELPER_H__
+struct fdt_match {
+ const char *compatible;
+ void *data;
+};
+
struct platform_uart_data {
unsigned long addr;
unsigned long freq;
@@ -23,6 +28,12 @@ struct platform_plic_data {
unsigned long num_src;
};
+const struct fdt_match *fdt_match_node(void *fdt, int nodeoff,
+ const struct fdt_match *match_table);
+
+int fdt_find_match(void *fdt, const struct fdt_match *match_table,
+ const struct fdt_match **out_match);
+
int fdt_parse_uart8250_node(void *fdt, int nodeoffset,
struct platform_uart_data *uart);
diff --git a/lib/utils/fdt/fdt_helper.c b/lib/utils/fdt/fdt_helper.c
index 573cc71f..e8c927de 100644
--- a/lib/utils/fdt/fdt_helper.c
+++ b/lib/utils/fdt/fdt_helper.c
@@ -18,6 +18,47 @@
#define DEFAULT_UART_REG_SHIFT 0
#define DEFAULT_UART_REG_IO_WIDTH 1
+const struct fdt_match *fdt_match_node(void *fdt, int nodeoff,
+ const struct fdt_match *match_table)
+{
+ int ret;
+
+ if (!fdt || nodeoff < 0 || !match_table)
+ return NULL;
+
+ while (match_table->compatible) {
+ ret = fdt_node_check_compatible(fdt, nodeoff,
+ match_table->compatible);
+ if (!ret)
+ return match_table;
+ match_table++;
+ }
+
+ return NULL;
+}
+
+int fdt_find_match(void *fdt, const struct fdt_match *match_table,
+ const struct fdt_match **out_match)
+{
+ int nodeoff;
+
+ if (!fdt || !match_table)
+ return SBI_ENODEV;
+
+ while (match_table->compatible) {
+ nodeoff = fdt_node_offset_by_compatible(fdt, -1,
+ match_table->compatible);
+ if (nodeoff >= 0) {
+ if (out_match)
+ *out_match = match_table;
+ return nodeoff;
+ }
+ match_table++;
+ }
+
+ return SBI_ENODEV;
+}
+
static int fdt_get_node_addr_size(void *fdt, int node, unsigned long *addr,
unsigned long *size)
{