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> Reviewed-by: Simon Glass <s...@chromium.org> --- v3->v4: No change * Added Simon's Rb tag. 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