summaryrefslogtreecommitdiff
path: root/tools/dtoc/fdt.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/dtoc/fdt.py')
-rw-r--r--tools/dtoc/fdt.py44
1 files changed, 35 insertions, 9 deletions
diff --git a/tools/dtoc/fdt.py b/tools/dtoc/fdt.py
index a5e1d0b52f..63d1f68d81 100644
--- a/tools/dtoc/fdt.py
+++ b/tools/dtoc/fdt.py
@@ -503,9 +503,13 @@ class Node:
auto_resize: Resize the device tree automatically if it does not
have enough space for the update
+ Returns:
+ True if the node had to be added, False if it already existed
+
Raises:
FdtException if auto_resize is False and there is not enough space
"""
+ added = False
if self._offset is None:
# The subnode doesn't exist yet, so add it
fdt_obj = self._fdt._fdt_obj
@@ -519,23 +523,45 @@ class Node:
else:
offset = fdt_obj.add_subnode(self.parent._offset, self.name)
self._offset = offset
+ added = True
- # Sync subnodes in reverse so that we don't disturb node offsets for
- # nodes that are earlier in the DT. This avoids an O(n^2) rescan of
- # node offsets.
+ # Sync the existing subnodes first, so that we can rely on the offsets
+ # being correct. As soon as we add new subnodes, it pushes all the
+ # existing subnodes up.
for node in reversed(self.subnodes):
- node.Sync(auto_resize)
+ if node._offset is not None:
+ node.Sync(auto_resize)
- # Sync properties now, whose offsets should not have been disturbed.
- # We do this after subnodes, since this disturbs the offsets of these
- # properties. Note that new properties will have an offset of None here,
- # which Python 3 cannot sort against int. So use a large value instead
- # to ensure that the new properties are added first.
+ # Sync subnodes in reverse so that we get the expected order. Each
+ # new node goes at the start of the subnode list. This avoids an O(n^2)
+ # rescan of node offsets.
+ num_added = 0
+ for node in reversed(self.subnodes):
+ if node.Sync(auto_resize):
+ num_added += 1
+ if num_added:
+ # Reorder our list of nodes to put the new ones first, since that's
+ # what libfdt does
+ old_count = len(self.subnodes) - num_added
+ subnodes = self.subnodes[old_count:] + self.subnodes[:old_count]
+ self.subnodes = subnodes
+
+ # Sync properties now, whose offsets should not have been disturbed,
+ # since properties come before subnodes. This is done after all the
+ # subnode processing above, since updating properties can disturb the
+ # offsets of those subnodes.
+ # Properties are synced in reverse order, with new properties added
+ # before existing properties are synced. This ensures that the offsets
+ # of earlier properties are not disturbed.
+ # Note that new properties will have an offset of None here, which
+ # Python cannot sort against int. So use a large value instead so that
+ # new properties are added first.
prop_list = sorted(self.props.values(),
key=lambda prop: prop._offset or 1 << 31,
reverse=True)
for prop in prop_list:
prop.Sync(auto_resize)
+ return added
class Fdt: