diff options
author | Simon Glass <sjg@chromium.org> | 2021-02-03 06:01:20 -0700 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2021-03-22 19:23:27 +1300 |
commit | ea74c95103c66282b8c43e7893bdcd533cab220f (patch) | |
tree | 9abea76c49022e6409902b6fbf9bacea4ac83606 /tools/dtoc/dtb_platdata.py | |
parent | 9763e4eb93bfcb5cc50edf13b152c231b218591f (diff) |
dtoc: Generate uclass devices
Add support for generating a file containing uclass instances. This avoids
the need to create these at run time.
Update a test uclass to include a 'priv_auto' member, to increase test
coverage.
Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'tools/dtoc/dtb_platdata.py')
-rw-r--r-- | tools/dtoc/dtb_platdata.py | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/tools/dtoc/dtb_platdata.py b/tools/dtoc/dtb_platdata.py index ab26c4adca..6dadf37582 100644 --- a/tools/dtoc/dtb_platdata.py +++ b/tools/dtoc/dtb_platdata.py @@ -246,6 +246,7 @@ class DtbPlatdata(): """ if self._outfile != sys.stdout: self._outfile.close() + self._outfile = None def out(self, line): """Output a string to the output file @@ -649,6 +650,27 @@ class DtbPlatdata(): self.buf('};\n') self.buf('\n') + def prep_priv(self, struc, name, suffix, section='.priv_data'): + if not struc: + return None + var_name = '_%s%s' % (name, suffix) + hdr = self._scan._structs.get(struc) + if hdr: + self.buf('#include <%s>\n' % hdr.fname) + else: + print('Warning: Cannot find header file for struct %s' % struc) + attr = '__attribute__ ((section ("%s")))' % section + return var_name, struc, attr + + def alloc_priv(self, info, name, extra, suffix='_priv'): + result = self.prep_priv(info, name, suffix) + if not result: + return None + var_name, struc, section = result + self.buf('u8 %s_%s[sizeof(struct %s)]\n\t%s;\n' % + (var_name, extra, struc.strip(), section)) + return '%s_%s' % (var_name, extra) + def _output_prop(self, node, prop): """Output a line containing the value of a struct member @@ -680,6 +702,74 @@ class DtbPlatdata(): self._output_prop(node, node.props[pname]) self.buf('};\n') + def list_head(self, head_member, node_member, node_refs, var_name): + self.buf('\t.%s\t= {\n' % head_member) + if node_refs: + last = node_refs[-1].dev_ref + first = node_refs[0].dev_ref + member = node_member + else: + last = 'DM_DEVICE_REF(%s)' % var_name + first = last + member = head_member + self.buf('\t\t.prev = &%s->%s,\n' % (last, member)) + self.buf('\t\t.next = &%s->%s,\n' % (first, member)) + self.buf('\t},\n') + + def list_node(self, member, node_refs, seq): + self.buf('\t.%s\t= {\n' % member) + self.buf('\t\t.prev = %s,\n' % node_refs[seq - 1]) + self.buf('\t\t.next = %s,\n' % node_refs[seq + 1]) + self.buf('\t},\n') + + def generate_uclasses(self): + if not self.check_instantiate(True): + return + self.out('\n') + self.out('#include <common.h>\n') + self.out('#include <dm.h>\n') + self.out('#include <dt-structs.h>\n') + self.out('\n') + self.buf('/*\n') + self.buf(' * uclass declarations\n') + self.buf(' *\n') + self.buf(' * Sequence numbers:\n') + uclass_list = self._valid_uclasses + for uclass in uclass_list: + if uclass.alias_num_to_node: + self.buf(' * %s: %s\n' % (uclass.name, uclass.uclass_id)) + for seq, node in uclass.alias_num_to_node.items(): + self.buf(' * %d: %s\n' % (seq, node.path)) + self.buf(' */\n') + + uclass_node = {} + for seq, uclass in enumerate(uclass_list): + uclass_node[seq] = ('&DM_UCLASS_REF(%s)->sibling_node' % + uclass.name) + uclass_node[-1] = '&uclass_head' + uclass_node[len(uclass_list)] = '&uclass_head' + self.buf('\n') + self.buf('struct list_head %s = {\n' % 'uclass_head') + self.buf('\t.prev = %s,\n' % uclass_node[len(uclass_list) -1]) + self.buf('\t.next = %s,\n' % uclass_node[0]) + self.buf('};\n') + self.buf('\n') + + for seq, uclass in enumerate(uclass_list): + uc_drv = self._scan._uclass.get(uclass.uclass_id) + + priv_name = self.alloc_priv(uc_drv.priv, uc_drv.name, '') + + self.buf('DM_UCLASS_INST(%s) = {\n' % uclass.name) + if priv_name: + self.buf('\t.priv_\t\t= %s,\n' % priv_name) + self.buf('\t.uc_drv\t\t= DM_UCLASS_DRIVER_REF(%s),\n' % uclass.name) + self.list_node('sibling_node', uclass_node, seq) + self.list_head('dev_head', 'uclass_node', uc_drv.devs, None) + self.buf('};\n') + self.buf('\n') + self.out(''.join(self.get_buf())) + def read_aliases(self): """Read the aliases and attach the information to self._alias @@ -894,6 +984,9 @@ OUTPUT_FILES = { 'platdata': OutputFile(Ftype.SOURCE, 'dt-plat.c', DtbPlatdata.generate_plat, 'Declares the U_BOOT_DRIVER() records and platform data'), + 'uclass': + OutputFile(Ftype.SOURCE, 'dt-uclass.c', DtbPlatdata.generate_uclasses, + 'Declares the uclass instances (struct uclass)'), } |