aboutsummaryrefslogtreecommitdiff
path: root/tools/dtoc
diff options
context:
space:
mode:
authorSimon Glass2023-07-18 07:24:03 -0600
committerSimon Glass2023-07-20 14:10:58 -0600
commit55e1278d5eca233421c92122e7fe2361eb010710 (patch)
treee154c101d2e6609036ee8257c7f049161cc68928 /tools/dtoc
parent4df457b657b6d0c10031ab4b1eb414e3ea6c3819 (diff)
dtoc: Allow inserting a list of nodes into another
Provide a way to specify a phandle list of nodes which are to be inserted into an existing node. Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'tools/dtoc')
-rw-r--r--tools/dtoc/fdt.py22
-rw-r--r--tools/dtoc/test/dtoc_test_copy.dts14
-rwxr-xr-xtools/dtoc/test_fdt.py39
3 files changed, 74 insertions, 1 deletions
diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py
index f4d84083e49..fd0f3e94f5c 100644
--- a/tools/dtoc/fdt.py
+++ b/tools/dtoc/fdt.py
@@ -748,6 +748,28 @@ class Node:
dst.copy_node(node)
return dst
+ def copy_subnodes_from_phandles(self, phandle_list):
+ """Copy subnodes of a list of nodes into another node
+
+ Args:
+ phandle_list (list of int): List of phandles of nodes to copy
+
+ For each node in the phandle list, its subnodes and their properties are
+ copied recursively. Note that it does not copy the node itself, nor its
+ properties.
+ """
+ # Process in reverse order, since new nodes are inserted at the start of
+ # the destination's node list. We want them to appear in order of the
+ # phandle list
+ for phandle in phandle_list.__reversed__():
+ parent = self.GetFdt().LookupPhandle(phandle)
+ tout.debug(f'adding template {parent.path} to node {self.path}')
+ for node in parent.subnodes.__reversed__():
+ dst = self.copy_node(node)
+
+ tout.debug(f'merge props from {parent.path} to {dst.path}')
+ self.merge_props(parent)
+
class Fdt:
"""Provides simple access to a flat device tree blob using libfdts.
diff --git a/tools/dtoc/test/dtoc_test_copy.dts b/tools/dtoc/test/dtoc_test_copy.dts
index 85e2c342a7e..36faa9b72b5 100644
--- a/tools/dtoc/test/dtoc_test_copy.dts
+++ b/tools/dtoc/test/dtoc_test_copy.dts
@@ -11,6 +11,7 @@
#address-cells = <1>;
#size-cells = <1>;
reference = <&over>; /* nake sure that the 'over' phandle exists */
+ copy-list = <&another &base>;
dest {
bootph-all;
@@ -46,7 +47,7 @@
};
};
- base {
+ base: base {
compatible = "sandbox,i2c";
bootph-all;
#address-cells = <1>;
@@ -73,4 +74,15 @@
};
};
};
+
+ another: another {
+ new-prop = "hello";
+ earlier {
+ wibble = <2>;
+ };
+
+ later {
+ fibble = <3>;
+ };
+ };
};
diff --git a/tools/dtoc/test_fdt.py b/tools/dtoc/test_fdt.py
index ebc5297b506..3e54694eec9 100755
--- a/tools/dtoc/test_fdt.py
+++ b/tools/dtoc/test_fdt.py
@@ -380,6 +380,45 @@ class TestNode(unittest.TestCase):
dst = new_dtb.GetNode('/dest')
do_copy_checks(new_dtb, dst, expect_none=False)
+ def test_copy_subnodes_from_phandles(self):
+ """Test copy_node() function"""
+ dtb = fdt.FdtScan(find_dtb_file('dtoc_test_copy.dts'))
+
+ orig = dtb.GetNode('/')
+ node_list = fdt_util.GetPhandleList(orig, 'copy-list')
+
+ dst = dtb.GetNode('/dest')
+ dst.copy_subnodes_from_phandles(node_list)
+
+ pmic = dtb.GetNode('/dest/over')
+ self.assertTrue(pmic)
+
+ subn = dtb.GetNode('/dest/first@0')
+ self.assertTrue(subn)
+ self.assertEqual({'a-prop', 'b-prop', 'reg'}, subn.props.keys())
+
+ self.assertEqual(
+ ['/dest/earlier', '/dest/later', '/dest/over', '/dest/first@0',
+ '/dest/second', '/dest/existing', '/dest/base'],
+ [n.path for n in dst.subnodes])
+
+ # Make sure that the phandle for 'over' is not copied
+ over = dst.FindNode('over')
+ print('keys', over.props.keys())
+ self.assertNotIn('phandle', over.props.keys())
+
+ # Check the merged properties, first the base ones in '/dest'
+ expect = {'bootph-all', 'compatible', 'stringarray', 'longbytearray',
+ 'maybe-empty-int'}
+
+ # Properties from 'base'
+ expect.update({'#address-cells', '#size-cells'})
+
+ # Properties from 'another'
+ expect.add('new-prop')
+
+ self.assertEqual(expect, set(dst.props.keys()))
+
class TestProp(unittest.TestCase):
"""Test operation of the Prop class"""