lib: utils: Add FDT match table based node lookup
authorAnup Patel <anup.patel@wdc.com>
Fri, 24 Apr 2020 13:02:10 +0000 (18:32 +0530)
committerAnup Patel <anup@brainfault.org>
Fri, 1 May 2020 04:09:44 +0000 (09:39 +0530)
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>
include/sbi_utils/fdt/fdt_helper.h
lib/utils/fdt/fdt_helper.c

index 57c4720..a525493 100644 (file)
 #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);
 
index 573cc71..e8c927d 100644 (file)
 #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)
 {