From 8fed2eb20c2ef95d69f9683ab07f0ea869616713 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 29 Aug 2017 14:15:55 -0600 Subject: [PATCH] dtoc: Rename is_phandle() and adjust it to return more detail Update this function to return more detail about a property that contains phandles. This will allow (in a future commit) more accurate handling of these properties. Signed-off-by: Simon Glass Tested-by: Kever Yang --- tools/dtoc/dtb_platdata.py | 79 +++++++++++++++++++++++--------- tools/dtoc/dtoc_test_phandle.dts | 1 + 2 files changed, 58 insertions(+), 22 deletions(-) diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py index a483d6c875..001bc4ea66 100644 --- a/tools/dtoc/dtb_platdata.py +++ b/tools/dtoc/dtb_platdata.py @@ -12,6 +12,7 @@ This supports converting device tree data to C structures definitions and static data. """ +import collections import copy import sys @@ -44,6 +45,14 @@ TYPE_NAMES = { STRUCT_PREFIX = 'dtd_' VAL_PREFIX = 'dtv_' +# This holds information about a property which includes phandles. +# +# max_args: integer: Maximum number or arguments that any phandle uses (int). +# args: Number of args for each phandle in the property. The total number of +# phandles is len(args). This is a list of integers. +PhandleInfo = collections.namedtuple('PhandleInfo', ['max_args', 'args']) + + def conv_name_to_c(name): """Convert a device-tree name to a C identifier @@ -181,20 +190,42 @@ class DtbPlatdata(object): self._lines = [] return lines - def is_phandle(self, prop): - """Check if a node contains phandles + def get_phandle_argc(self, prop, node_name): + """Check if a node contains phandles - We have no reliable way of detecting whether a node uses a phandle - or not. As an interim measure, use a list of known property names. + We have no reliable way of detecting whether a node uses a phandle + or not. As an interim measure, use a list of known property names. - Args: - prop: Prop object to check - Return: - True if the object value contains phandles, else False - """ - if prop.name in ['clocks']: - return True - return False + Args: + prop: Prop object to check + Return: + Number of argument cells is this is a phandle, else None + """ + if prop.name in ['clocks']: + val = prop.value + if not isinstance(val, list): + val = [val] + i = 0 + + max_args = 0 + args = [] + while i < len(val): + phandle = fdt_util.fdt32_to_cpu(val[i]) + target = self._fdt.phandle_to_node.get(phandle) + if not target: + raise ValueError("Cannot parse '%s' in node '%s'" % + (prop.name, node_name)) + prop_name = '#clock-cells' + cells = target.props.get(prop_name) + if not cells: + raise ValueError("Node '%s' has no '%s' property" % + (target.name, prop_name)) + num_args = fdt_util.fdt32_to_cpu(cells.value) + max_args = max(max_args, num_args) + args.append(num_args) + i += 1 + num_args + return PhandleInfo(max_args, args) + return None def scan_dtb(self): """Scan the device tree to obtain a tree of nodes and properties @@ -358,14 +389,16 @@ class DtbPlatdata(object): for pname, prop in node.props.items(): if pname in PROP_IGNORE_LIST or pname[0] == '#': continue - if isinstance(prop.value, list): - if self.is_phandle(prop): - # Process the list as pairs of (phandle, id) - value_it = iter(prop.value) - for phandle_cell, _ in zip(value_it, value_it): - phandle = fdt_util.fdt32_to_cpu(phandle_cell) - target_node = self._fdt.phandle_to_node[phandle] - node.phandles.add(target_node) + info = self.get_phandle_argc(prop, node.name) + if info: + if not isinstance(prop.value, list): + prop.value = [prop.value] + # Process the list as pairs of (phandle, id) + value_it = iter(prop.value) + for phandle_cell, _ in zip(value_it, value_it): + phandle = fdt_util.fdt32_to_cpu(phandle_cell) + target_node = self._fdt.phandle_to_node[phandle] + node.phandles.add(target_node) def generate_structs(self, structs): @@ -383,7 +416,8 @@ class DtbPlatdata(object): self.out('struct %s%s {\n' % (STRUCT_PREFIX, name)) for pname in sorted(structs[name]): prop = structs[name][pname] - if self.is_phandle(prop): + info = self.get_phandle_argc(prop, structs[name]) + if info: # For phandles, include a reference to the target self.out('\t%s%s[%d]' % (tab_to(2, 'struct phandle_2_cell'), conv_name_to_c(prop.name), @@ -423,7 +457,8 @@ class DtbPlatdata(object): vals = [] # For phandles, output a reference to the platform data # of the target node. - if self.is_phandle(prop): + info = self.get_phandle_argc(prop, node.name) + if info: # Process the list as pairs of (phandle, id) value_it = iter(prop.value) for phandle_cell, id_cell in zip(value_it, value_it): diff --git a/tools/dtoc/dtoc_test_phandle.dts b/tools/dtoc/dtoc_test_phandle.dts index e9828a695b..c0a602f296 100644 --- a/tools/dtoc/dtoc_test_phandle.dts +++ b/tools/dtoc/dtoc_test_phandle.dts @@ -13,6 +13,7 @@ u-boot,dm-pre-reloc; compatible = "target"; intval = <1>; + #clock-cells = <1>; }; phandle-source { -- 2.39.5