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 <sjg@chromium.org>
Tested-by: Kever Yang <kever.yang@rock-chips.com>
diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py
index a483d6c..001bc4e 100644
--- a/tools/dtoc/dtb_platdata.py
+++ b/tools/dtoc/dtb_platdata.py
@@ -12,6 +12,7 @@
 static data.
 """
 
+import collections
 import copy
 import sys
 
@@ -44,6 +45,14 @@
 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 @@
         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:
+            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
 
-	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
+            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 @@
             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 @@
             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 @@
                 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 e9828a6..c0a602f 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 {