]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
dm: core: Add a function to create an empty tree
authorSimon Glass <sjg@chromium.org>
Tue, 26 Sep 2023 14:14:40 +0000 (08:14 -0600)
committerTom Rini <trini@konsulko.com>
Fri, 6 Oct 2023 18:38:12 +0000 (14:38 -0400)
Provide a function to create a new, empty tree.

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

index 515396c62f4997677a6d10ab10bcbfd495726e71..d2bdb8b9af1cea63c3c311596686c1c57579dbd2 100644 (file)
@@ -47,6 +47,17 @@ static int oftree_find(const void *fdt)
        return -1;
 }
 
+static int check_tree_count(void)
+{
+       if (oftree_count == CONFIG_OFNODE_MULTI_TREE_MAX) {
+               log_warning("Too many registered device trees (max %d)\n",
+                           CONFIG_OFNODE_MULTI_TREE_MAX);
+               return -E2BIG;
+       }
+
+       return 0;
+}
+
 static oftree oftree_ensure(void *fdt)
 {
        oftree tree;
@@ -69,11 +80,8 @@ static oftree oftree_ensure(void *fdt)
        if (gd->flags & GD_FLG_RELOC) {
                i = oftree_find(fdt);
                if (i == -1) {
-                       if (oftree_count == CONFIG_OFNODE_MULTI_TREE_MAX) {
-                               log_warning("Too many registered device trees (max %d)\n",
-                                           CONFIG_OFNODE_MULTI_TREE_MAX);
+                       if (check_tree_count())
                                return oftree_null();
-                       }
 
                        /* register the new tree */
                        i = oftree_count++;
@@ -92,6 +100,41 @@ static oftree oftree_ensure(void *fdt)
        return tree;
 }
 
+int oftree_new(oftree *treep)
+{
+       oftree tree = oftree_null();
+       int ret;
+
+       if (of_live_active()) {
+               struct device_node *root;
+
+               ret = of_live_create_empty(&root);
+               if (ret)
+                       return log_msg_ret("liv", ret);
+               tree = oftree_from_np(root);
+       } else {
+               const int size = 1024;
+               void *fdt;
+
+               ret = check_tree_count();
+               if (ret)
+                       return log_msg_ret("fla", ret);
+
+               /* register the new tree with a small size */
+               fdt = malloc(size);
+               if (!fdt)
+                       return log_msg_ret("fla", -ENOMEM);
+               ret = fdt_create_empty_tree(fdt, size);
+               if (ret)
+                       return log_msg_ret("fla", -EINVAL);
+               oftree_list[oftree_count++] = fdt;
+               tree.fdt = fdt;
+       }
+       *treep = tree;
+
+       return 0;
+}
+
 void oftree_dispose(oftree tree)
 {
        if (of_live_active())
@@ -193,6 +236,11 @@ static inline int oftree_find(const void *fdt)
        return 0;
 }
 
+int oftree_new(oftree *treep)
+{
+       return -ENOSYS;
+}
+
 #endif /* OFNODE_MULTI_TREE */
 
 /**
index 32917f6615573d2367557511059a860e1b15456d..0b96ab34ede0f6f8a1c2da4bd6ad4466e71f9355 100644 (file)
@@ -127,6 +127,15 @@ static inline ofnode noffset_to_ofnode(ofnode other_node, int of_offset)
 
 #endif /* OFNODE_MULTI_TREE */
 
+/**
+ * oftree_new() - Create a new, empty tree
+ *
+ * @treep: Returns a pointer to the tree, on success
+ * Returns: 0 on success, -ENOMEM if out of memory, -E2BIG if !OF_LIVE and
+ * there are too many (flattrees) already
+ */
+int oftree_new(oftree *treep);
+
 /**
  * ofnode_to_np() - convert an ofnode to a live DT node pointer
  *
index 05e86ac06b1a2df4f6e963ac7190765ec549b00e..81cb9bd13e2ce45f995cd0b636898220850e02ba 100644 (file)
@@ -46,4 +46,12 @@ int unflatten_device_tree(const void *blob, struct device_node **mynodes);
  */
 void of_live_free(struct device_node *root);
 
+/**
+ * of_live_create_empty() - Create a new, empty tree
+ *
+ * @rootp: Returns the root node of the created tree
+ * Return: 0 if OK, -ENOMEM if out of memory
+ */
+int of_live_create_empty(struct device_node **rootp);
+
 #endif
index 25f7af61061e7543a765bcd75d120ff4d9fa23a1..e4eee38554761d55568d24fa5227620e700df4fb 100644 (file)
@@ -336,3 +336,22 @@ void of_live_free(struct device_node *root)
        /* the tree is stored as a contiguous block of memory */
        free(root);
 }
+
+int of_live_create_empty(struct device_node **rootp)
+{
+       struct device_node *root;
+
+       root = calloc(1, sizeof(struct device_node));
+       if (!root)
+               return -ENOMEM;
+       root->name = strdup("");
+       if (!root->name) {
+               free(root);
+               return -ENOMEM;
+       }
+       root->type = "<NULL>";
+       root->full_name = "";
+       *rootp = root;
+
+       return 0;
+}
index 3bf97761d1ee48c677515492a86ed69314393b24..594116e3c0458bc65f27001377f4ceb85e846f80 100644 (file)
@@ -1346,3 +1346,19 @@ static int dm_test_livetree_ensure(struct unit_test_state *uts)
        return 0;
 }
 DM_TEST(dm_test_livetree_ensure, UT_TESTF_SCAN_FDT);
+
+static int dm_test_oftree_new(struct unit_test_state *uts)
+{
+       ofnode node, subnode, check;
+       oftree tree;
+
+       ut_assertok(oftree_new(&tree));
+       node = oftree_root(tree);
+       ut_assert(ofnode_valid(node));
+       ut_assertok(ofnode_add_subnode(node, "edmund", &subnode));
+       check = ofnode_find_subnode(node, "edmund");
+       ut_asserteq(check.of_offset, subnode.of_offset);
+
+       return 0;
+}
+DM_TEST(dm_test_oftree_new, UT_TESTF_SCAN_FDT);