Merge patch series "Propagate bootph-all and bootph-some-ram property to all supernodes"

Moteen Shah <m-shah@ti.com> says:

In the U-Boot pre-relocation stage, if the parent node lacks
bootph-all/bootph-some-ram property and the driver lacks a pre-reloc
flag, all of its subsequent subnodes gets skipped over from driver
binding—even if they have a bootph* property.

This series addresses the issue by scanning through all the nodes during
build time and propagating the applicable  property to all of its supernode.

Link: https://lore.kernel.org/r/20250516114148.3862114-1-m-shah@ti.com
This commit is contained in:
Tom Rini
2025-06-26 11:48:39 -06:00
3 changed files with 99 additions and 0 deletions
+54
View File
@@ -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:
+24
View File
@@ -8040,5 +8040,29 @@ fdt fdtmap Extract the devicetree blob from the fdtmap
self._DoTestFile('346_remove_template.dts',
force_missing_bintools='openssl',)
def testBootphPropagation(self):
"""Test that bootph-* properties are propagated correctly to supernodes"""
_, _, _, out_dtb_fname = self._DoReadFileDtb(
'347_bootph_prop.dts', use_real_dtb=True, update_dtb=True)
dtb = fdt.Fdt(out_dtb_fname)
dtb.Scan()
root = dtb.GetRoot()
parent_node = root.FindNode('dummy-parent')
subnode1 = parent_node.FindNode('subnode-1')
subnode2 = subnode1.FindNode('subnode-2')
subnode3 = subnode1.FindNode('subnode-3')
subnode4 = subnode3.FindNode('subnode-4')
self.assertIn('bootph-some-ram', subnode1.props,
"Child node is missing 'bootph-some-ram' property")
self.assertIn('bootph-all', subnode1.props,
"Child node is missing 'bootph-all' property")
self.assertIn('bootph-some-ram', parent_node.props,
"Parent node is missing 'bootph-some-ram' property")
self.assertIn('bootph-all', parent_node.props,
"Parent node is missing 'bootph-all' property")
self.assertEqual(len(subnode4.props), 0,
"subnode shouldn't have any properties")
if __name__ == "__main__":
unittest.main()
+21
View File
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: GPL-2.0+
/dts-v1/;
/ {
dummy-parent {
subnode-1 {
subnode-2 {
bootph-all;
};
subnode-3 {
bootph-some-ram;
subnode-4 {
};
};
};
};
binman: binman {
};
};