diff --git a/include/dm/device.h b/include/dm/device.h index bb9faa0ed9..84df5b9e95 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -369,6 +369,22 @@ struct driver { */ #define DM_DRIVER_ALIAS(__name, __alias) +/** + * Declare a macro to indicate which phase of U-Boot this driver is fore. + * + * + * This macro produces no code but its information will be parsed by dtoc. The + * macro can be only be used once in a driver. Put it within the U_BOOT_DRIVER() + * declaration, e.g.: + * + * U_BOOT_DRIVER(cpu) = { + * .name = ... + * ... + * DM_PHASE(tpl) + * }; + */ +#define DM_PHASE(_phase) + /** * dev_get_plat() - Get the platform data for a device * diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py index 28669f3121..ef0454c890 100644 --- a/tools/dtoc/dtb_platdata.py +++ b/tools/dtoc/dtb_platdata.py @@ -733,7 +733,7 @@ OUTPUT_FILES = { } -def run_steps(args, dtb_file, include_disabled, output, output_dirs, +def run_steps(args, dtb_file, include_disabled, output, output_dirs, phase, warning_disabled=False, drivers_additional=None, basedir=None, scan=None): """Run all the steps of the dtoc tool @@ -746,6 +746,8 @@ def run_steps(args, dtb_file, include_disabled, output, output_dirs, output_dirs (tuple of str): Directory to put C output files Directory to put H output files + phase: The phase of U-Boot that we are generating data for, e.g. 'spl' + or 'tpl'. None if not known warning_disabled (bool): True to avoid showing warnings about missing drivers drivers_additional (list): List of additional drivers to use during @@ -764,7 +766,8 @@ def run_steps(args, dtb_file, include_disabled, output, output_dirs, raise ValueError('Must specify either output or output_dirs, not both') if not scan: - scan = src_scan.Scanner(basedir, warning_disabled, drivers_additional) + scan = src_scan.Scanner(basedir, warning_disabled, drivers_additional, + phase) scan.scan_drivers() do_process = True else: diff --git a/tools/dtoc/main.py b/tools/dtoc/main.py index 355b1e6277..15a8ff167a 100755 --- a/tools/dtoc/main.py +++ b/tools/dtoc/main.py @@ -85,6 +85,8 @@ parser.add_option('--include-disabled', action='store_true', help='Include disabled nodes') parser.add_option('-o', '--output', action='store', help='Select output filename') +parser.add_option('-p', '--phase', type=str, + help='set phase of U-Boot this invocation is for (spl/tpl)') parser.add_option('-P', '--processes', type=int, help='set number of processes to use for running tests') parser.add_option('-t', '--test', action='store_true', dest='test', @@ -104,4 +106,5 @@ elif options.test_coverage: else: dtb_platdata.run_steps(args, options.dtb_file, options.include_disabled, options.output, - [options.c_output_dir, options.h_output_dir]) + [options.c_output_dir, options.h_output_dir], + phase=options.phase) diff --git a/tools/dtoc/src_scan.py b/tools/dtoc/src_scan.py index 1a02d41063..2699153016 100644 --- a/tools/dtoc/src_scan.py +++ b/tools/dtoc/src_scan.py @@ -67,6 +67,7 @@ class Driver: child_plat (str): struct name of the per_child_plat_auto member, e.g. 'pci_child_plat' used (bool): True if the driver is used by the structs being output + phase (str): Which phase of U-Boot to use this driver """ def __init__(self, name, fname): self.name = name @@ -78,6 +79,7 @@ class Driver: self.child_priv = '' self.child_plat = '' self.used = False + self.phase = '' def __eq__(self, other): return (self.name == other.name and @@ -173,8 +175,10 @@ class Scanner: _structs: Dict of all structs found in U-Boot: key: Name of struct value: Struct object + _phase: The phase of U-Boot that we are generating data for, e.g. 'spl' + or 'tpl'. None if not known """ - def __init__(self, basedir, warning_disabled, drivers_additional): + def __init__(self, basedir, warning_disabled, drivers_additional, phase=''): """Set up a new Scanner """ if not basedir: @@ -190,6 +194,7 @@ class Scanner: self._compat_to_driver = {} self._uclass = {} self._structs = {} + self._phase = phase def get_driver(self, name): """Get a driver given its name @@ -428,6 +433,8 @@ class Scanner: re_of_match = re.compile( r'\.of_match\s*=\s*(of_match_ptr\()?([a-z0-9_]+)(\))?,') + re_phase = re.compile('^\s*DM_PHASE\((.*)\).*$') + # Matches the struct name for priv, plat re_priv = self._get_re_for_member('priv_auto') re_plat = self._get_re_for_member('plat_auto') @@ -454,6 +461,7 @@ class Scanner: m_plat = re_plat.match(line) m_cplat = re_child_plat.match(line) m_cpriv = re_child_priv.match(line) + m_phase = re_phase.match(line) if m_priv: driver.priv = m_priv.group(1) elif m_plat: @@ -466,6 +474,8 @@ class Scanner: driver.uclass_id = m_id.group(1) elif m_of_match: compat = m_of_match.group(2) + elif m_phase: + driver.phase = m_phase.group(1) elif '};' in line: if driver.uclass_id and compat: if compat not in of_match: diff --git a/tools/dtoc/test_dtoc.py b/tools/dtoc/test_dtoc.py index d90ece205d..c1fafb656f 100755 --- a/tools/dtoc/test_dtoc.py +++ b/tools/dtoc/test_dtoc.py @@ -138,8 +138,8 @@ class TestDtoc(unittest.TestCase): dtb_file (str): Filename of .dtb file output (str): Filename of output file """ - dtb_platdata.run_steps(args, dtb_file, False, output, [], True, - None, None, scan=copy_scan()) + dtb_platdata.run_steps(args, dtb_file, False, output, [], None, + warning_disabled=True, scan=copy_scan()) def test_name(self): """Test conversion of device tree names to C identifiers""" @@ -365,7 +365,7 @@ U_BOOT_DRVINFO(gpios_at_0) = { output = tools.GetOutputFilename('output') with test_util.capture_sys_output() as _: dtb_platdata.run_steps(['struct'], dtb_file, False, output, [], - scan=copy_scan()) + None, scan=copy_scan()) with open(output) as infile: data = infile.read() self._check_strings(HEADER + ''' @@ -375,7 +375,7 @@ struct dtd_invalid { with test_util.capture_sys_output() as _: dtb_platdata.run_steps(['platdata'], dtb_file, False, output, [], - scan=copy_scan()) + None, scan=copy_scan()) with open(output) as infile: data = infile.read() self._check_strings(C_HEADER + ''' @@ -927,8 +927,8 @@ U_BOOT_DRVINFO(spl_test2) = { def test_output_conflict(self): """Test a conflict between and output dirs and output file""" with self.assertRaises(ValueError) as exc: - dtb_platdata.run_steps(['all'], None, False, 'out', ['cdir'], True, - scan=copy_scan()) + dtb_platdata.run_steps(['all'], None, False, 'out', ['cdir'], None, + warning_disabled=True, scan=copy_scan()) self.assertIn("Must specify either output or output_dirs, not both", str(exc.exception)) @@ -944,8 +944,8 @@ U_BOOT_DRVINFO(spl_test2) = { fnames = glob.glob(outdir + '/*') self.assertEqual(2, len(fnames)) - dtb_platdata.run_steps(['all'], dtb_file, False, None, [outdir], True, - scan=copy_scan()) + dtb_platdata.run_steps(['all'], dtb_file, False, None, [outdir], None, + warning_disabled=True, scan=copy_scan()) fnames = glob.glob(outdir + '/*') self.assertEqual(4, len(fnames)) diff --git a/tools/dtoc/test_src_scan.py b/tools/dtoc/test_src_scan.py index ebdc12abc8..8d35b33c28 100644 --- a/tools/dtoc/test_src_scan.py +++ b/tools/dtoc/test_src_scan.py @@ -233,6 +233,7 @@ U_BOOT_DRIVER(i2c_tegra) = { self.assertIn('i2c_tegra', scan._drivers) drv = scan._drivers['i2c_tegra'] self.assertEqual('i2c_tegra', drv.name) + self.assertEqual('', drv.phase) def test_priv(self): """Test collection of struct info from drivers""" @@ -250,6 +251,7 @@ U_BOOT_DRIVER(testing) = { .plat_auto = sizeof(struct some_plat), .per_child_auto = sizeof(struct some_cpriv), .per_child_plat_auto = sizeof(struct some_cplat), + DM_PHASE(tpl) }; ''' scan = src_scan.Scanner(None, False, None) @@ -264,6 +266,7 @@ U_BOOT_DRIVER(testing) = { self.assertEqual('some_plat', drv.plat) self.assertEqual('some_cpriv', drv.child_priv) self.assertEqual('some_cplat', drv.child_plat) + self.assertEqual('tpl', drv.phase) self.assertEqual(1, len(scan._drivers)) def test_uclass_scan(self):