dm: core: Complete phandle implementation using the other FDT
authorSimon Glass <sjg@chromium.org>
Wed, 7 Sep 2022 02:27:27 +0000 (20:27 -0600)
committerTom Rini <trini@konsulko.com>
Fri, 30 Sep 2022 02:43:43 +0000 (22:43 -0400)
We need to be able to look up phandles in any FDT, not just the control
FDT. Use the 'other' FDT to test this, with a helper function which gets
this as an oftree that can then we used as needed.

Add a few more tests and some comments at the top of the file, to explain
what is going on.

Signed-off-by: Simon Glass <sjg@chromium.org>
drivers/core/ofnode.c
include/test/ut.h
test/dm/ofnode.c

index 53db7b5..2c4d521 100644 (file)
@@ -599,9 +599,9 @@ ofnode oftree_get_by_phandle(oftree tree, uint phandle)
        if (of_live_active())
                node = np_to_ofnode(of_find_node_by_phandle(tree.np, phandle));
        else
-               node.of_offset =
+               node = ofnode_from_tree_offset(tree,
                        fdt_node_offset_by_phandle(oftree_lookup_fdt(tree),
-                                                  phandle);
+                                                  phandle));
 
        return node;
 }
index f7d1d18..f7217aa 100644 (file)
@@ -119,6 +119,11 @@ int ut_check_console_end(struct unit_test_state *uts);
  */
 int ut_check_console_dump(struct unit_test_state *uts, int total_bytes);
 
+/* Report a failure, with printf() string */
+#define ut_reportf(fmt, args...)                                       \
+       ut_failf(uts, __FILE__, __LINE__, __func__, "report",           \
+                fmt, ##args)
+
 /* Assert that a condition is non-zero */
 #define ut_assert(cond)                                                        \
        if (!(cond)) {                                                  \
index b73ab98..134a307 100644 (file)
@@ -1,4 +1,20 @@
 // SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2022 Google LLC
+ *
+ * There are two types of tests in this file:
+ * - normal ones which act on the control FDT (gd->fdt_blob or gd->of_root)
+ * - 'other' ones which act on the 'other' FDT (other.dts)
+ *
+ * The 'other' ones have an _ot suffix.
+ *
+ * The latter are used to check behaviour with multiple device trees,
+ * particularly with flat tree, where a tree ID is included in ofnode as part of
+ * the node offset. These tests are typically just for making sure that the
+ * offset makes it to libfdt correctly and that the resulting return value is
+ * correctly turned into an ofnode. The 'other' tests do not fully check the
+ * behaviour of each ofnode function, since that is done by the normal ones.
+ */
 
 #include <common.h>
 #include <dm.h>
 #include <test/test.h>
 #include <test/ut.h>
 
+/**
+ * get_other_oftree() - Convert a flat tree into an oftree object
+ *
+ * @uts: Test state
+ * @return: oftree object for the 'other' FDT (see sandbox' other.dts)
+ */
+oftree get_other_oftree(struct unit_test_state *uts)
+{
+       oftree tree;
+
+       if (of_live_active())
+               tree = oftree_from_np(uts->of_other);
+       else
+               tree = oftree_from_fdt(uts->other_fdt);
+
+       /* An invalid tree may cause failure or crashes */
+       if (!oftree_valid(tree))
+               ut_reportf("test needs the UT_TESTF_OTHER_FDT flag");
+
+       return tree;
+}
+
 static int dm_test_ofnode_compatible(struct unit_test_state *uts)
 {
        ofnode root_node = ofnode_path("/");
@@ -42,6 +80,20 @@ static int dm_test_ofnode_get_by_phandle(struct unit_test_state *uts)
 }
 DM_TEST(dm_test_ofnode_get_by_phandle, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
 
+static int dm_test_ofnode_get_by_phandle_ot(struct unit_test_state *uts)
+{
+       oftree otree = get_other_oftree(uts);
+       ofnode node;
+
+       ut_assert(ofnode_valid(oftree_get_by_phandle(oftree_default(), 1)));
+       node = oftree_get_by_phandle(otree, 1);
+       ut_assert(ofnode_valid(node));
+       ut_asserteq_str("target", ofnode_get_name(node));
+
+       return 0;
+}
+DM_TEST(dm_test_ofnode_get_by_phandle_ot, UT_TESTF_OTHER_FDT);
+
 static int dm_test_ofnode_by_prop_value(struct unit_test_state *uts)
 {
        const char propname[] = "compatible";
@@ -185,6 +237,34 @@ static int dm_test_ofnode_phandle(struct unit_test_state *uts)
 }
 DM_TEST(dm_test_ofnode_phandle, UT_TESTF_SCAN_PDATA | UT_TESTF_SCAN_FDT);
 
+static int dm_test_ofnode_phandle_ot(struct unit_test_state *uts)
+{
+       oftree otree = get_other_oftree(uts);
+       struct ofnode_phandle_args args;
+       ofnode node;
+       int ret;
+
+       node = oftree_path(otree, "/node");
+
+       /* Test ofnode_count_phandle_with_args with cell name */
+       ret = ofnode_count_phandle_with_args(node, "missing", "#gpio-cells", 0);
+       ut_asserteq(-ENOENT, ret);
+       ret = ofnode_count_phandle_with_args(node, "target", "#invalid", 0);
+       ut_asserteq(-EINVAL, ret);
+       ret = ofnode_count_phandle_with_args(node, "target", "#gpio-cells", 0);
+       ut_asserteq(1, ret);
+
+       ret = ofnode_parse_phandle_with_args(node, "target", "#gpio-cells", 0,
+                                            0, &args);
+       ut_assertok(ret);
+       ut_asserteq(2, args.args_count);
+       ut_asserteq(3, args.args[0]);
+       ut_asserteq(4, args.args[1]);
+
+       return 0;
+}
+DM_TEST(dm_test_ofnode_phandle_ot, UT_TESTF_OTHER_FDT);
+
 static int dm_test_ofnode_read_chosen(struct unit_test_state *uts)
 {
        const char *str;