Commit 634eba4be060af3bcba51cba2d57d217df897f31
1 parent
bc79617fdf
Exists in
smarc_8mq_lf_v2020.04
and in
17 other branches
dtoc: Support properties containing multiple phandle values
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>
Showing 4 changed files with 58 additions and 12 deletions Side-by-side Diff
include/dt-structs.h
tools/dtoc/dtb_platdata.py
... | ... | @@ -394,11 +394,13 @@ |
394 | 394 | if not isinstance(prop.value, list): |
395 | 395 | prop.value = [prop.value] |
396 | 396 | # Process the list as pairs of (phandle, id) |
397 | - value_it = iter(prop.value) | |
398 | - for phandle_cell, _ in zip(value_it, value_it): | |
397 | + pos = 0 | |
398 | + for args in info.args: | |
399 | + phandle_cell = prop.value[pos] | |
399 | 400 | phandle = fdt_util.fdt32_to_cpu(phandle_cell) |
400 | 401 | target_node = self._fdt.phandle_to_node[phandle] |
401 | 402 | node.phandles.add(target_node) |
403 | + pos += 1 + args | |
402 | 404 | |
403 | 405 | |
404 | 406 | def generate_structs(self, structs): |
... | ... | @@ -422,7 +424,7 @@ |
422 | 424 | struct_name = 'struct phandle_%d_arg' % info.max_args |
423 | 425 | self.out('\t%s%s[%d]' % (tab_to(2, struct_name), |
424 | 426 | conv_name_to_c(prop.name), |
425 | - len(prop.value) / 2)) | |
427 | + len(info.args))) | |
426 | 428 | else: |
427 | 429 | ptype = TYPE_NAMES[prop.type] |
428 | 430 | self.out('\t%s%s' % (tab_to(2, ptype), |
429 | 431 | |
430 | 432 | |
... | ... | @@ -461,13 +463,18 @@ |
461 | 463 | info = self.get_phandle_argc(prop, node.name) |
462 | 464 | if info: |
463 | 465 | # Process the list as pairs of (phandle, id) |
464 | - value_it = iter(prop.value) | |
465 | - for phandle_cell, id_cell in zip(value_it, value_it): | |
466 | + pos = 0 | |
467 | + for args in info.args: | |
468 | + phandle_cell = prop.value[pos] | |
466 | 469 | phandle = fdt_util.fdt32_to_cpu(phandle_cell) |
467 | - id_num = fdt_util.fdt32_to_cpu(id_cell) | |
468 | 470 | target_node = self._fdt.phandle_to_node[phandle] |
469 | 471 | name = conv_name_to_c(target_node.name) |
470 | - vals.append('{&%s%s, {%d}}' % (VAL_PREFIX, name, id_num)) | |
472 | + arg_values = [] | |
473 | + for i in range(args): | |
474 | + arg_values.append(str(fdt_util.fdt32_to_cpu(prop.value[pos + 1 + i]))) | |
475 | + pos += 1 + args | |
476 | + vals.append('\t{&%s%s, {%s}}' % (VAL_PREFIX, name, | |
477 | + ', '.join(arg_values))) | |
471 | 478 | for val in vals: |
472 | 479 | self.buf('\n\t\t%s,' % val) |
473 | 480 | else: |
tools/dtoc/dtoc_test_phandle.dts
... | ... | @@ -12,14 +12,27 @@ |
12 | 12 | phandle: phandle-target { |
13 | 13 | u-boot,dm-pre-reloc; |
14 | 14 | compatible = "target"; |
15 | + intval = <0>; | |
16 | + #clock-cells = <0>; | |
17 | + }; | |
18 | + | |
19 | + phandle_1: phandle2-target { | |
20 | + u-boot,dm-pre-reloc; | |
21 | + compatible = "target"; | |
15 | 22 | intval = <1>; |
16 | - #clock-cells = <1>; | |
23 | + #clock-cells = <1>; | |
17 | 24 | }; |
25 | + phandle_2: phandle3-target { | |
26 | + u-boot,dm-pre-reloc; | |
27 | + compatible = "target"; | |
28 | + intval = <2>; | |
29 | + #clock-cells = <2>; | |
30 | + }; | |
18 | 31 | |
19 | 32 | phandle-source { |
20 | 33 | u-boot,dm-pre-reloc; |
21 | 34 | compatible = "source"; |
22 | - clocks = <&phandle 1>; | |
35 | + clocks = <&phandle &phandle_1 11 &phandle_2 12 13 &phandle>; | |
23 | 36 | }; |
24 | 37 | }; |
tools/dtoc/test_dtoc.py
... | ... | @@ -228,7 +228,7 @@ |
228 | 228 | self.assertEqual('''#include <stdbool.h> |
229 | 229 | #include <libfdt.h> |
230 | 230 | struct dtd_source { |
231 | -\tstruct phandle_1_arg clocks[1]; | |
231 | +\tstruct phandle_2_arg clocks[4]; | |
232 | 232 | }; |
233 | 233 | struct dtd_target { |
234 | 234 | \tfdt32_t\t\tintval; |
... | ... | @@ -243,7 +243,7 @@ |
243 | 243 | #include <dt-structs.h> |
244 | 244 | |
245 | 245 | static struct dtd_target dtv_phandle_target = { |
246 | -\t.intval\t\t\t= 0x1, | |
246 | +\t.intval\t\t\t= 0x0, | |
247 | 247 | }; |
248 | 248 | U_BOOT_DEVICE(phandle_target) = { |
249 | 249 | \t.name\t\t= "target", |
250 | 250 | |
... | ... | @@ -251,9 +251,30 @@ |
251 | 251 | \t.platdata_size\t= sizeof(dtv_phandle_target), |
252 | 252 | }; |
253 | 253 | |
254 | +static struct dtd_target dtv_phandle2_target = { | |
255 | +\t.intval\t\t\t= 0x1, | |
256 | +}; | |
257 | +U_BOOT_DEVICE(phandle2_target) = { | |
258 | +\t.name\t\t= "target", | |
259 | +\t.platdata\t= &dtv_phandle2_target, | |
260 | +\t.platdata_size\t= sizeof(dtv_phandle2_target), | |
261 | +}; | |
262 | + | |
263 | +static struct dtd_target dtv_phandle3_target = { | |
264 | +\t.intval\t\t\t= 0x2, | |
265 | +}; | |
266 | +U_BOOT_DEVICE(phandle3_target) = { | |
267 | +\t.name\t\t= "target", | |
268 | +\t.platdata\t= &dtv_phandle3_target, | |
269 | +\t.platdata_size\t= sizeof(dtv_phandle3_target), | |
270 | +}; | |
271 | + | |
254 | 272 | static struct dtd_source dtv_phandle_source = { |
255 | 273 | \t.clocks\t\t\t= { |
256 | -\t\t{&dtv_phandle_target, {1}},}, | |
274 | +\t\t\t{&dtv_phandle_target, {}}, | |
275 | +\t\t\t{&dtv_phandle2_target, {11}}, | |
276 | +\t\t\t{&dtv_phandle3_target, {12, 13}}, | |
277 | +\t\t\t{&dtv_phandle_target, {}},}, | |
257 | 278 | }; |
258 | 279 | U_BOOT_DEVICE(phandle_source) = { |
259 | 280 | \t.name\t\t= "source", |