dtoc: Support properties containing multiple phandle values
authorSimon Glass <sjg@chromium.org>
Tue, 29 Aug 2017 20:15:59 +0000 (14:15 -0600)
committerSimon Glass <sjg@chromium.org>
Fri, 15 Sep 2017 11:27:48 +0000 (05:27 -0600)
At present dtoc has a very simplistic view of phandles. It assumes that
a property has only a single phandle with a single argument (i.e. two
cells per property).

This is not true in many cases. Enhance the implementation to scan all
phandles in a property and to use the correct number of arguments (which
can be 0, 1, 2 or more) when generating the C code. For the struct
definitions, use a struct which can hold the maximum number of arguments
used by the property.

Signed-off-by: Simon Glass <sjg@chromium.org>
Tested-by: Kever Yang <kever.yang@rock-chips.com>
include/dt-structs.h
tools/dtoc/dtb_platdata.py
tools/dtoc/dtoc_test_phandle.dts
tools/dtoc/test_dtoc.py

index 9ab4e2524d1884342410557168647f1e2a937224..76979e73e174a01959bf08286e0c392a86445d12 100644 (file)
@@ -18,6 +18,11 @@ struct phandle_1_arg {
        const void *node;
        int arg[1];
 };
+
+struct phandle_2_arg {
+       const void *node;
+       int arg[2];
+};
 #include <generated/dt-structs.h>
 #endif
 
index 1920a59f821055f0cd5eccbe9ca01fed92fb458d..cfca45b0ac9382e9ecf6f8ced74fffae6eeb3c5e 100644 (file)
@@ -394,11 +394,13 @@ class DtbPlatdata(object):
                     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):
@@ -422,7 +424,7 @@ class DtbPlatdata(object):
                     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),
@@ -461,13 +463,18 @@ 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:
index c0a602f296717d900e98bbc28746a2bb1e0bf35c..ba12b0fe65ea88ef49744ceae31f283131e124a1 100644 (file)
 
 / {
        phandle: phandle-target {
+               u-boot,dm-pre-reloc;
+               compatible = "target";
+               intval = <0>;
+                #clock-cells = <0>;
+       };
+
+       phandle_1: phandle2-target {
                u-boot,dm-pre-reloc;
                compatible = "target";
                intval = <1>;
-                #clock-cells = <1>;
+               #clock-cells = <1>;
+       };
+       phandle_2: phandle3-target {
+               u-boot,dm-pre-reloc;
+               compatible = "target";
+               intval = <2>;
+               #clock-cells = <2>;
        };
 
        phandle-source {
                u-boot,dm-pre-reloc;
                compatible = "source";
-               clocks = <&phandle 1>;
+               clocks = <&phandle &phandle_1 11 &phandle_2 12 13 &phandle>;
        };
 };
index fbae927cf8fcb9e5a002113590848cfcb788bfd0..cc009b2a256a248fc0f1faff6b303a7381f22066 100644 (file)
@@ -228,7 +228,7 @@ U_BOOT_DEVICE(pmic_at_9) = {
         self.assertEqual('''#include <stdbool.h>
 #include <libfdt.h>
 struct dtd_source {
-\tstruct phandle_1_arg clocks[1];
+\tstruct phandle_2_arg clocks[4];
 };
 struct dtd_target {
 \tfdt32_t\t\tintval;
@@ -243,7 +243,7 @@ struct dtd_target {
 #include <dt-structs.h>
 
 static struct dtd_target dtv_phandle_target = {
-\t.intval\t\t\t= 0x1,
+\t.intval\t\t\t= 0x0,
 };
 U_BOOT_DEVICE(phandle_target) = {
 \t.name\t\t= "target",
@@ -251,9 +251,30 @@ U_BOOT_DEVICE(phandle_target) = {
 \t.platdata_size\t= sizeof(dtv_phandle_target),
 };
 
+static struct dtd_target dtv_phandle2_target = {
+\t.intval\t\t\t= 0x1,
+};
+U_BOOT_DEVICE(phandle2_target) = {
+\t.name\t\t= "target",
+\t.platdata\t= &dtv_phandle2_target,
+\t.platdata_size\t= sizeof(dtv_phandle2_target),
+};
+
+static struct dtd_target dtv_phandle3_target = {
+\t.intval\t\t\t= 0x2,
+};
+U_BOOT_DEVICE(phandle3_target) = {
+\t.name\t\t= "target",
+\t.platdata\t= &dtv_phandle3_target,
+\t.platdata_size\t= sizeof(dtv_phandle3_target),
+};
+
 static struct dtd_source dtv_phandle_source = {
 \t.clocks\t\t\t= {
-\t\t{&dtv_phandle_target, {1}},},
+\t\t\t{&dtv_phandle_target, {}},
+\t\t\t{&dtv_phandle2_target, {11}},
+\t\t\t{&dtv_phandle3_target, {12, 13}},
+\t\t\t{&dtv_phandle_target, {}},},
 };
 U_BOOT_DEVICE(phandle_source) = {
 \t.name\t\t= "source",