From patchwork Fri Jun 19 21:11:39 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Walter Lozano X-Patchwork-Id: 242718 List-Id: U-Boot discussion From: walter.lozano at collabora.com (Walter Lozano) Date: Fri, 19 Jun 2020 18:11:39 -0300 Subject: [RFC 3/4] dtoc: add support for generate stuct udevice_id In-Reply-To: <20200619211140.5081-1-walter.lozano@collabora.com> References: <20200619211140.5081-1-walter.lozano@collabora.com> Message-ID: <20200619211140.5081-4-walter.lozano@collabora.com> Based on several reports there is an increasing concern in the impact of adding additional features to drivers based on compatible strings. A good example of this situation is found in [1]. In order to reduce this impact and as an initial step for further reduction, propose a new way to declare compatible strings, which allows to only include the useful ones. The idea is to define compatible strings in a way to be easily parsed by dtoc, which will be responsible to build struct udevice_id [] based on the compatible strings present in the dtb. Additional features can be easily added, such as define constants depending on the presence of compatible strings, which allows to enable code blocks only in such cases without the need of adding additional configuration options. [1] http://patchwork.ozlabs.org/project/uboot/patch/20200525202429.2146-1-agust at denx.de/ Signed-off-by: Walter Lozano --- tools/dtoc/dtb_platdata.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py index d3fb4dcbf2..e199caf8c9 100644 --- a/tools/dtoc/dtb_platdata.py +++ b/tools/dtoc/dtb_platdata.py @@ -170,6 +170,9 @@ class DtbPlatdata(object): key: alias name value: node path _tiny_uclasses: List of uclass names that are marked as 'tiny' + _compatible_strings: Dict of compatible strings read from drivres + key: driver name + value: list of struct udevice_id """ def __init__(self, dtb_fname, config_fname, include_disabled): self._fdt = None @@ -188,6 +191,7 @@ class DtbPlatdata(object): self._tiny_uclasses = [] self._of_match = {} self._compat_to_driver = {} + self._compatible_strings = {} def get_normalized_compat_name(self, node): compat_c, aliases_c = get_compat_name(node) @@ -395,6 +399,15 @@ class DtbPlatdata(object): except: pass + # find entries declared with the form + # COMPATIBLE(driver_name, compatible_string) + compatible_strings = re.findall('COMPATIBLE\(\s*(\w+)\s*,\s*(\S+)\s*\)', b) + + for co in compatible_strings: + if not self._compatible_strings.get(co[0]): + self._compatible_strings[co[0]] = [] + self._compatible_strings[co[0]].append(co) + def scan_drivers(self): """Scan the driver folders to build a list of driver names and possible aliases @@ -805,6 +818,23 @@ class DtbPlatdata(object): self.out(''.join(self.get_buf())) self.close_output() + def generate_compatible(self): + """Generates the struct udevice_id[] to be used in drivers + + This writes C code to implement struct udevice_id[] based on + COMPATIBLE(driver_name, compatible) entries found in drivers. + + Additionally this function can filter entries in order to avoid + adding those that are not present in DT. + """ + self.out('#define COMPATIBLE(__driver_name, __compatible, ...)\n\n') + for vals in self._compatible_strings.values(): + st = '' + for comp in vals: + st += '{.compatible = %s},\\\n' % (comp[1]) + st += '{ /* sentinel */ },\\\n' + self.out('#define COMPATIBLE_LIST_%s { \\\n%s}\n' % (comp[0], st)) + def shrink(self): """Generate a shrunk version of DTB bases on valid drivers @@ -895,6 +925,8 @@ def run_steps(args, dtb_file, config_file, include_disabled, output): plat.shrink() elif cmd == 'test_del_node': plat.test_del_node() + elif cmd == 'compatible': + plat.generate_compatible() else: raise ValueError("Unknown command '%s': (use: struct, platdata)" % cmd)