As per bootph schema, bootph-* property in child node should be
implied in their parent, but this feature is not implemented in
the U-Boot proper stage (before relocation) resulting in devices
not being bound because of the missing bootph-all or bootph-some-ram
property in the parent node.

To mitigate this issue, add a function to scan through all the nodes
in the device-tree for bootph-all and bootph-some-ram properties. If
found, propagate it to all of its parent nodes up the hierarchy.

Signed-off-by: Moteen Shah <m-s...@ti.com>
Signed-off-by: Simon Glass <s...@chromium.org>

Reviewed-by: Simon Glass <s...@chromium.org>

---
 tools/binman/control.py | 54 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/tools/binman/control.py b/tools/binman/control.py
index 81f61e3e152..dcbc028adcc 100644
--- a/tools/binman/control.py
+++ b/tools/binman/control.py
@@ -530,6 +530,57 @@ def _RemoveTemplates(parent):
     for node in del_nodes:
         node.Delete()
 
+def propagate_prop(node, prop):
+    """Propagate the provided property to all the parent nodes up the hierarchy
+
+    Args:
+        node (fdt.Node): Node and all its parent nodes up to the root to
+            propagate the property.
+        prop (str): Boolean property to propagate
+
+    Return:
+        True if any change was made, else False
+    """
+    changed = False
+    while node:
+        if prop not in node.props:
+            node.AddEmptyProp(prop, 0)
+            changed = True
+        node = node.parent
+    return changed
+
+def scan_and_prop_bootph(node):
+    """Propagate bootph properties from children to parents
+
+    The bootph schema indicates that bootph properties in children should be
+    implied in their parents, all the way up the hierarchy. This is expensive
+    to implement in U-Boot before relocation at runtime, so this function
+    explicitly propagates these bootph properties upwards during build time.
+
+    This is used to set the bootph-all, bootph-some-ram property in the parent
+    node if the respective property is found in any of the parent's subnodes.
+    The other bootph-* properties are associated with the SPL stage and hence
+    handled by fdtgrep.c.
+
+    Args:
+        node (fdt.Node): Node to scan for bootph-all and bootph-some-ram
+            property
+
+    Return:
+        True if any change was made, else False
+
+    """
+    bootph_prop = {'bootph-all', 'bootph-some-ram'}
+
+    changed = False
+    for prop in bootph_prop:
+        if prop in node.props:
+            changed |= propagate_prop(node.parent, prop)
+
+    for subnode in node.subnodes:
+        changed |= scan_and_prop_bootph(subnode)
+    return changed
+
 def PrepareImagesAndDtbs(dtb_fname, select_images, update_fdt, use_expanded, 
indir):
     """Prepare the images to be processed and select the device tree
 
@@ -589,6 +640,9 @@ def PrepareImagesAndDtbs(dtb_fname, select_images, 
update_fdt, use_expanded, ind
         fname = tools.get_output_filename('u-boot.dtb.tmpl2')
         tools.write_file(fname, dtb.GetContents())
 
+    if scan_and_prop_bootph(dtb.GetRoot()):
+        dtb.Sync(True)
+
     images = _ReadImageDesc(node, use_expanded)
 
     if select_images:
-- 
2.34.1

Reply via email to