Merge tag 'u-boot-imx-20190426' of git://git.denx.de/u-boot-imx
[platform/kernel/u-boot.git] / tools / dtoc / dtb_platdata.py
index 001bc4e..17a3dcc 100644 (file)
@@ -1,10 +1,9 @@
 #!/usr/bin/python
+# SPDX-License-Identifier: GPL-2.0+
 #
 # Copyright (C) 2017 Google, Inc
 # Written by Simon Glass <sjg@chromium.org>
 #
-# SPDX-License-Identifier:     GPL-2.0+
-#
 
 """Device tree to platform data class
 
@@ -190,6 +189,16 @@ class DtbPlatdata(object):
         self._lines = []
         return lines
 
+    def out_header(self):
+        """Output a message indicating that this is an auto-generated file"""
+        self.out('''/*
+ * DO NOT MODIFY
+ *
+ * This file was generated by dtoc from a .dtb (device tree binary) file.
+ */
+
+''')
+
     def get_phandle_argc(self, prop, node_name):
         """Check if a node contains phandles
 
@@ -202,15 +211,21 @@ class DtbPlatdata(object):
             Number of argument cells is this is a phandle, else None
         """
         if prop.name in ['clocks']:
+            if not isinstance(prop.value, list):
+                prop.value = [prop.value]
             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])
+                # If we get to the end of the list, stop. This can happen
+                # since some nodes have more phandles in the list than others,
+                # but we allocate enough space for the largest list. So those
+                # nodes with shorter lists end up with zeroes at the end.
+                if not phandle:
+                    break
                 target = self._fdt.phandle_to_node.get(phandle)
                 if not target:
                     raise ValueError("Cannot parse '%s' in node '%s'" %
@@ -301,7 +316,8 @@ class DtbPlatdata(object):
             total = na + ns
 
             if reg.type != fdt.TYPE_INT:
-                raise ValueError("Node '%s' reg property is not an int")
+                raise ValueError("Node '%s' reg property is not an int" %
+                                 node.name)
             if len(reg.value) % total:
                 raise ValueError("Node '%s' reg property has %d cells "
                         'which is not a multiple of na + ns = %d + %d)' %
@@ -391,14 +407,14 @@ class DtbPlatdata(object):
                     continue
                 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):
+                    pos = 0
+                    for args in info.args:
+                        phandle_cell = prop.value[pos]
                         phandle = fdt_util.fdt32_to_cpu(phandle_cell)
                         target_node = self._fdt.phandle_to_node[phandle]
                         node.phandles.add(target_node)
+                        pos += 1 + args
 
 
     def generate_structs(self, structs):
@@ -408,8 +424,9 @@ class DtbPlatdata(object):
         definitions for node in self._valid_nodes. See the documentation in
         README.of-plat for more information.
         """
+        self.out_header()
         self.out('#include <stdbool.h>\n')
-        self.out('#include <libfdt.h>\n')
+        self.out('#include <linux/libfdt.h>\n')
 
         # Output the struct definition
         for name in sorted(structs):
@@ -419,9 +436,10 @@ class DtbPlatdata(object):
                 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'),
+                    struct_name = 'struct phandle_%d_arg' % info.max_args
+                    self.out('\t%s%s[%d]' % (tab_to(2, struct_name),
                                              conv_name_to_c(prop.name),
-                                             len(prop.value) / 2))
+                                             len(info.args)))
                 else:
                     ptype = TYPE_NAMES[prop.type]
                     self.out('\t%s%s' % (tab_to(2, ptype),
@@ -432,8 +450,9 @@ class DtbPlatdata(object):
             self.out('};\n')
 
         for alias, struct_name in self._aliases.iteritems():
-            self.out('#define %s%s %s%s\n'% (STRUCT_PREFIX, alias,
-                                             STRUCT_PREFIX, struct_name))
+            if alias not in sorted(structs):
+                self.out('#define %s%s %s%s\n'% (STRUCT_PREFIX, alias,
+                                                 STRUCT_PREFIX, struct_name))
 
     def output_node(self, node):
         """Output the C code for a node
@@ -443,7 +462,7 @@ class DtbPlatdata(object):
         """
         struct_name, _ = get_compat_name(node)
         var_name = conv_name_to_c(node.name)
-        self.buf('static struct %s%s %s%s = {\n' %
+        self.buf('static const struct %s%s %s%s = {\n' %
                  (STRUCT_PREFIX, struct_name, VAL_PREFIX, var_name))
         for pname, prop in node.props.items():
             if pname in PROP_IGNORE_LIST or pname[0] == '#':
@@ -460,22 +479,29 @@ class DtbPlatdata(object):
                 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):
+                    pos = 0
+                    for args in info.args:
+                        phandle_cell = prop.value[pos]
                         phandle = fdt_util.fdt32_to_cpu(phandle_cell)
-                        id_num = fdt_util.fdt32_to_cpu(id_cell)
                         target_node = self._fdt.phandle_to_node[phandle]
                         name = conv_name_to_c(target_node.name)
-                        vals.append('{&%s%s, %d}' % (VAL_PREFIX, name, id_num))
+                        arg_values = []
+                        for i in range(args):
+                            arg_values.append(str(fdt_util.fdt32_to_cpu(prop.value[pos + 1 + i])))
+                        pos += 1 + args
+                        vals.append('\t{&%s%s, {%s}}' % (VAL_PREFIX, name,
+                                                     ', '.join(arg_values)))
+                    for val in vals:
+                        self.buf('\n\t\t%s,' % val)
                 else:
                     for val in prop.value:
                         vals.append(get_value(prop.type, val))
 
-                # Put 8 values per line to avoid very long lines.
-                for i in xrange(0, len(vals), 8):
-                    if i:
-                        self.buf(',\n\t\t')
-                    self.buf(', '.join(vals[i:i + 8]))
+                    # Put 8 values per line to avoid very long lines.
+                    for i in xrange(0, len(vals), 8):
+                        if i:
+                            self.buf(',\n\t\t')
+                        self.buf(', '.join(vals[i:i + 8]))
                 self.buf('}')
             else:
                 self.buf(get_value(prop.type, prop.value))
@@ -502,6 +528,7 @@ class DtbPlatdata(object):
         See the documentation in doc/driver-model/of-plat.txt for more
         information.
         """
+        self.out_header()
         self.out('#include <common.h>\n')
         self.out('#include <dm.h>\n')
         self.out('#include <dt-structs.h>\n')