diff --git a/include/dm/device.h b/include/dm/device.h index 84df5b9e95..45010b4df9 100644 --- a/include/dm/device.h +++ b/include/dm/device.h @@ -385,6 +385,24 @@ struct driver { */ #define DM_PHASE(_phase) +/** + * Declare a macro to declare a header needed for a driver. Often the correct + * header can be found automatically, but only for struct declarations. For + * enums and #defines used in the driver declaration and declared in a different + * header from the structs, this macro must be used. + * + * This macro produces no code but its information will be parsed by dtoc. The + * macro can be used multiple times with different headers, for the same driver. + * Put it within the U_BOOT_DRIVER() declaration, e.g.: + * + * U_BOOT_DRIVER(cpu) = { + * .name = ... + * ... + * DM_HEADER() + * }; + */ +#define DM_HEADER(_hdr) + /** * dev_get_plat() - Get the platform data for a device * diff --git a/tools/dtoc/src_scan.py b/tools/dtoc/src_scan.py index 2699153016..206b2b3758 100644 --- a/tools/dtoc/src_scan.py +++ b/tools/dtoc/src_scan.py @@ -68,6 +68,8 @@ class Driver: 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 + headers (list): List of header files needed for this driver (each a str) + e.g. [''] """ def __init__(self, name, fname): self.name = name @@ -80,6 +82,7 @@ class Driver: self.child_plat = '' self.used = False self.phase = '' + self.headers = [] def __eq__(self, other): return (self.name == other.name and @@ -434,6 +437,7 @@ class Scanner: r'\.of_match\s*=\s*(of_match_ptr\()?([a-z0-9_]+)(\))?,') re_phase = re.compile('^\s*DM_PHASE\((.*)\).*$') + re_hdr = re.compile('^\s*DM_HEADER\((.*)\).*$') # Matches the struct name for priv, plat re_priv = self._get_re_for_member('priv_auto') @@ -462,6 +466,7 @@ class Scanner: m_cplat = re_child_plat.match(line) m_cpriv = re_child_priv.match(line) m_phase = re_phase.match(line) + m_hdr = re_hdr.match(line) if m_priv: driver.priv = m_priv.group(1) elif m_plat: @@ -476,6 +481,8 @@ class Scanner: compat = m_of_match.group(2) elif m_phase: driver.phase = m_phase.group(1) + elif m_hdr: + driver.headers.append(m_hdr.group(1)) elif '};' in line: if driver.uclass_id and compat: if compat not in of_match: diff --git a/tools/dtoc/test_src_scan.py b/tools/dtoc/test_src_scan.py index 8d35b33c28..245b7302fd 100644 --- a/tools/dtoc/test_src_scan.py +++ b/tools/dtoc/test_src_scan.py @@ -234,6 +234,7 @@ U_BOOT_DRIVER(i2c_tegra) = { drv = scan._drivers['i2c_tegra'] self.assertEqual('i2c_tegra', drv.name) self.assertEqual('', drv.phase) + self.assertEqual([], drv.headers) def test_priv(self): """Test collection of struct info from drivers""" @@ -252,6 +253,8 @@ U_BOOT_DRIVER(testing) = { .per_child_auto = sizeof(struct some_cpriv), .per_child_plat_auto = sizeof(struct some_cplat), DM_PHASE(tpl) + DM_HEADER() + DM_HEADER() }; ''' scan = src_scan.Scanner(None, False, None) @@ -267,6 +270,7 @@ U_BOOT_DRIVER(testing) = { self.assertEqual('some_cpriv', drv.child_priv) self.assertEqual('some_cplat', drv.child_plat) self.assertEqual('tpl', drv.phase) + self.assertEqual(['', ''], drv.headers) self.assertEqual(1, len(scan._drivers)) def test_uclass_scan(self):