Add of_match_node() helper function to iterate over the device tree
and tell if a device_node has a matching of_match structure.

Signed-off-by: Biju Das <biju.das...@bp.renesas.com>
Reviewed-by: Lad Prabhakar <prabhakar.mahadev-lad...@bp.renesas.com>
---
v2->v3:
 * Added a test case for of_match_node helper function.
 (Ref: 
https://patchwork.ozlabs.org/project/uboot/patch/20201102150959.4793-2-biju.das...@bp.renesas.com/)
v1->v2:
  * No Change.
---
 drivers/core/device.c | 21 +++++++++++++++++++++
 include/dm/device.h   | 13 +++++++++++++
 test/dm/core.c        | 31 +++++++++++++++++++++++++++++++
 3 files changed, 65 insertions(+)

diff --git a/drivers/core/device.c b/drivers/core/device.c
index 4b3dcb3b37..5db4c5e78b 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -1010,6 +1010,27 @@ bool of_machine_is_compatible(const char *compat)
        return !fdt_node_check_compatible(fdt, 0, compat);
 }
 
+static
+const struct udevice_id *__of_match_node(const struct udevice_id *matches,
+                                        const ofnode node)
+{
+       if (!matches)
+               return NULL;
+
+       for (; matches->compatible; matches++) {
+               if (ofnode_device_is_compatible(node, matches->compatible))
+                       return matches;
+       }
+
+       return NULL;
+}
+
+const struct udevice_id *of_match_node(const struct udevice_id *matches,
+                                      const ofnode node)
+{
+       return __of_match_node(matches, node);
+}
+
 int dev_disable_by_path(const char *path)
 {
        struct uclass *uc;
diff --git a/include/dm/device.h b/include/dm/device.h
index 5bef484247..4c357d46ec 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -754,6 +754,19 @@ bool device_is_compatible(const struct udevice *dev, const 
char *compat);
  */
 bool of_machine_is_compatible(const char *compat);
 
+/**
+ * of_match_node() - Tell if a device_node has a matching of_match structure
+ *
+ *
+ * Low level utility function used by device matching.
+ *
+ * @matches:   array of of device match structures to search in
+ * @node:      the of device structure to match against
+ * @return matching structure on success, NULL if the match is not found
+ */
+const struct udevice_id *of_match_node(const struct udevice_id *matches,
+                                      const ofnode node);
+
 /**
  * dev_disable_by_path() - Disable a device given its device tree path
  *
diff --git a/test/dm/core.c b/test/dm/core.c
index 6f380a574c..b94b78d9ba 100644
--- a/test/dm/core.c
+++ b/test/dm/core.c
@@ -11,6 +11,7 @@
 #include <fdtdec.h>
 #include <log.h>
 #include <malloc.h>
+#include <dm/device.h>
 #include <dm/device-internal.h>
 #include <dm/root.h>
 #include <dm/util.h>
@@ -1066,3 +1067,33 @@ static int dm_test_inactive_child(struct unit_test_state 
*uts)
        return 0;
 }
 DM_TEST(dm_test_inactive_child, UT_TESTF_SCAN_PDATA);
+
+static int dm_test_of_match_node(struct unit_test_state *uts)
+{
+       const ulong test_data_expected = 0x1234;
+       ofnode root_node = ofnode_path("/");
+       const struct udevice_id *match;
+       unsigned long match_data;
+
+       const struct udevice_id soc_device_ids[] = {
+               { .compatible = "sandbox", .data = test_data_expected, },
+               { /* sentinel */ }
+       };
+
+       const struct udevice_id soc_device_nomatch_ids[] = {
+               { .compatible = "sandbox123", .data = test_data_expected, },
+               { /* sentinel */ }
+       };
+
+       match = of_match_node(soc_device_ids, root_node);
+       ut_assert(match);
+
+       match_data = match->data;
+       ut_asserteq(match_data, test_data_expected);
+
+       match = of_match_node(soc_device_nomatch_ids, root_node);
+       ut_asserteq_ptr(match, NULL);
+
+       return 0;
+}
+DM_TEST(dm_test_of_match_node, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
-- 
2.17.1

Reply via email to