Skip to content
Snippets Groups Projects
Commit 346179f0 authored by Simon Glass's avatar Simon Glass
Browse files

dtoc: Prepare for supporting changing of device trees


For binman we need to support deleting properties in the device tree. This
will change the offsets of nodes after the deletion. In preparation, add
code to keep track of when the offsets are invalid, and regenerate them.

Signed-off-by: default avatarSimon Glass <sjg@chromium.org>
parent 6b93c55f
No related branches found
No related tags found
No related merge requests found
...@@ -53,15 +53,24 @@ class Node(NodeBase): ...@@ -53,15 +53,24 @@ class Node(NodeBase):
def __init__(self, fdt, offset, name, path): def __init__(self, fdt, offset, name, path):
NodeBase.__init__(self, fdt, offset, name, path) NodeBase.__init__(self, fdt, offset, name, path)
def Offset(self):
"""Returns the offset of a node, after checking the cache
This should be used instead of self._offset directly, to ensure that
the cache does not contain invalid offsets.
"""
self._fdt.CheckCache()
return self._offset
def Scan(self): def Scan(self):
"""Scan a node's properties and subnodes """Scan a node's properties and subnodes
This fills in the props and subnodes properties, recursively This fills in the props and subnodes properties, recursively
searching into subnodes so that the entire tree is built. searching into subnodes so that the entire tree is built.
""" """
self.props = self._fdt.GetProps(self.path) self.props = self._fdt.GetProps(self, self.path)
offset = libfdt.fdt_first_subnode(self._fdt.GetFdt(), self._offset) offset = libfdt.fdt_first_subnode(self._fdt.GetFdt(), self.Offset())
while offset >= 0: while offset >= 0:
sep = '' if self.path[-1] == '/' else '/' sep = '' if self.path[-1] == '/' else '/'
name = libfdt.Name(self._fdt.GetFdt(), offset) name = libfdt.Name(self._fdt.GetFdt(), offset)
...@@ -72,6 +81,19 @@ class Node(NodeBase): ...@@ -72,6 +81,19 @@ class Node(NodeBase):
node.Scan() node.Scan()
offset = libfdt.fdt_next_subnode(self._fdt.GetFdt(), offset) offset = libfdt.fdt_next_subnode(self._fdt.GetFdt(), offset)
def Refresh(self, my_offset):
"""Fix up the _offset for each node, recursively
Note: This does not take account of property offsets - these will not
be updated.
"""
if self._offset != my_offset:
#print '%s: %d -> %d\n' % (self.path, self._offset, my_offset)
self._offset = my_offset
offset = libfdt.fdt_first_subnode(self._fdt.GetFdt(), self._offset)
for subnode in self.subnodes:
subnode.Refresh(offset)
offset = libfdt.fdt_next_subnode(self._fdt.GetFdt(), offset)
class FdtNormal(Fdt): class FdtNormal(Fdt):
"""Provides simple access to a flat device tree blob using libfdt. """Provides simple access to a flat device tree blob using libfdt.
...@@ -83,6 +105,7 @@ class FdtNormal(Fdt): ...@@ -83,6 +105,7 @@ class FdtNormal(Fdt):
""" """
def __init__(self, fname): def __init__(self, fname):
Fdt.__init__(self, fname) Fdt.__init__(self, fname)
self._cached_offsets = False
if self._fname: if self._fname:
self._fname = fdt_util.EnsureCompiled(self._fname) self._fname = fdt_util.EnsureCompiled(self._fname)
...@@ -97,7 +120,7 @@ class FdtNormal(Fdt): ...@@ -97,7 +120,7 @@ class FdtNormal(Fdt):
""" """
return self._fdt return self._fdt
def GetProps(self, node): def GetProps(self, node, path):
"""Get all properties from a node. """Get all properties from a node.
Args: Args:
...@@ -110,7 +133,7 @@ class FdtNormal(Fdt): ...@@ -110,7 +133,7 @@ class FdtNormal(Fdt):
Raises: Raises:
ValueError: if the node does not exist. ValueError: if the node does not exist.
""" """
offset = libfdt.fdt_path_offset(self._fdt, node) offset = libfdt.fdt_path_offset(self._fdt, path)
if offset < 0: if offset < 0:
libfdt.Raise(offset) libfdt.Raise(offset)
props_dict = {} props_dict = {}
...@@ -124,6 +147,21 @@ class FdtNormal(Fdt): ...@@ -124,6 +147,21 @@ class FdtNormal(Fdt):
poffset = libfdt.fdt_next_property_offset(self._fdt, poffset) poffset = libfdt.fdt_next_property_offset(self._fdt, poffset)
return props_dict return props_dict
def Invalidate(self):
"""Mark our offset cache as invalid"""
self._cached_offsets = False
def CheckCache(self):
"""Refresh the offset cache if needed"""
if self._cached_offsets:
return
self.Refresh()
self._cached_offsets = True
def Refresh(self):
"""Refresh the offset cache"""
self._root.Refresh(0)
@classmethod @classmethod
def Node(self, fdt, offset, name, path): def Node(self, fdt, offset, name, path):
"""Create a new node """Create a new node
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment