Commit 6dad3bc8 authored by Simon Glass's avatar Simon Glass
Browse files

dtoc: Only generate the required files

At present all possible files are generated, even if some of them just
have a header and an empty body. It is better to generate only the files
that are needed, so that the two types of build (based on the setting of
OF_PLATDATA_INST) can be mutually exclusive.

This is intended to fix a strange problem sometimes found with CI:

   Building current source for 1 boards (1 thread, 40 jobs per thread)
      sandbox:  +   sandbox_spl
   +drivers/built-in.o: In function `dm_setup_inst':
   +drivers/core/root.c:135: undefined reference to
   +dts/dt-uclass.o:(.u_boot_list_2_uclass_2_serial+0x10): undefined
   reference to `_u_boot_list_2_udevice_2_serial'

This likely happens when switching from !OF_PLATDATA_INST to
OF_PLATDATA_INST since running 'make xxx_defconfig" does not currently
cause any change in which files are generated. With !OF_PLATDATA_INST
the dt-device.c file has no declarations and this is assumed to be the
starting state. The error above seems to indicate that, after changing
to OF_PLATDATA_INST, the dt-uclass.c file is regenerated but the
dt-device.c files is not. This does not seem possible from the relevant
Makefile.spl rule:

   u-boot-spl-platdata := $(obj)/dts/dt-plat.o $(obj)/dts/dt-uclass.o

   cmd_dtoc = $(DTOC_ARGS) -c $(obj)/dts -C include/generated all

   include/generated/dt-structs-gen.h $(u-boot-spl-platdata_c) &: \
	@[ -d $(obj)/dts ] || mkdir -p $(obj)/dts
	$(call if_changed,dtoc)

It seems that this cannot regenerate dt-uclass.c without dt-device.c since
'dtoc all' is used. So here the trail ends for now.

In any case it seems better to generate files that are uses and not bother
with those that serve no purpose. So update dtoc to do this automatically.
Signed-off-by: Simon Glass's avatarSimon Glass <>
parent 0d870b4c
......@@ -1128,7 +1128,7 @@ class DtbPlatdata():
# Types of output file we understand
# key: Command used to generate this file
# value: OutputFile for this command
OutputFile(Ftype.HEADER, 'dt-decl.h', DtbPlatdata.generate_decl,
'Declares externs for all device/uclass instances'),
......@@ -1136,9 +1136,17 @@ OUTPUT_FILES = {
OutputFile(Ftype.HEADER, 'dt-structs-gen.h',
'Defines the structs used to hold devicetree data'),
# File generated without instantiate
OutputFile(Ftype.SOURCE, 'dt-plat.c', DtbPlatdata.generate_plat,
'Declares the U_BOOT_DRIVER() records and platform data'),
# File generated with instantiate
OutputFile(Ftype.SOURCE, 'dt-device.c', DtbPlatdata.generate_device,
'Declares the DM_DEVICE_INST() records'),
......@@ -1204,14 +1212,21 @@ def run_steps(args, dtb_file, include_disabled, output, output_dirs, phase,
# Figure out what output files we plan to generate
output_files = OUTPUT_FILES_COMMON
if instantiate:
cmds = args[0].split(',')
if 'all' in cmds:
cmds = sorted(OUTPUT_FILES.keys())
cmds = sorted(output_files.keys())
for cmd in cmds:
outfile = OUTPUT_FILES.get(cmd)
outfile = output_files.get(cmd)
if not outfile:
raise ValueError("Unknown command '%s': (use: %s)" %
(cmd, ', '.join(sorted(OUTPUT_FILES.keys()))))
(cmd, ', '.join(sorted(output_files.keys()))))
outfile.fname if output_dirs else output)
......@@ -1554,7 +1554,7 @@ U_BOOT_DRVINFO(spl_test2) = {
with self.assertRaises(ValueError) as exc:
self.run_test(['invalid-cmd'], dtb_file, output)
"Unknown command 'invalid-cmd': (use: decl, device, platdata, struct, uclass)",
"Unknown command 'invalid-cmd': (use: decl, platdata, struct)",
def test_output_conflict(self):
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment