def generate_structs(self): """Generate struct defintions for the platform data This writes out the body of a header file consisting of structure definitions for node in self._valid_nodes. See the documentation in doc/driver-model/of-plat.rst for more information. """ structs = self._struct_data self.out('#include <stdbool.h>\n') self.out('#include <linux/libfdt.h>\n') # Output the struct definition for name in sorted(structs): self.out('struct %s%s {\n' % (STRUCT_PREFIX, name)) for pname in sorted(structs[name]): prop = structs[name][pname] info = self.get_phandle_argc(prop, structs[name]) if info: # For phandles, include a reference to the target struct_name = 'struct phandle_%d_arg' % info.max_args self.out('\t%s%s[%d]' % (tab_to(2, struct_name), conv_name_to_c( prop.name), len(info.args))) else: ptype = TYPE_NAMES[prop.type] self.out('\t%s%s' % (tab_to(2, ptype), conv_name_to_c(prop.name))) if isinstance(prop.value, list): self.out('[%d]' % len(prop.value)) self.out(';\n') self.out('};\n')
def test_name(self): """Test conversion of device tree names to C identifiers""" self.assertEqual('serial_at_0x12', conv_name_to_c('serial@0x12')) self.assertEqual('vendor_clock_frequency', conv_name_to_c('vendor,clock-frequency')) self.assertEqual('rockchip_rk3399_sdhci_5_1', conv_name_to_c('rockchip,rk3399-sdhci-5.1'))
def scan_tree(self): """Scan the device tree for useful information This fills in the following properties: _valid_nodes: A list of nodes we wish to consider include in the platform data """ valid_nodes = [] self.scan_node(self._fdt.GetRoot(), valid_nodes) self._valid_nodes = sorted(valid_nodes, key=lambda x: conv_name_to_c(x.name)) for idx, node in enumerate(self._valid_nodes): node.idx = idx
def output_node(self, node): """Output the C code for a node Args: node (fdt.Node): node to output """ struct_name, _ = self._scan.get_normalized_compat_name(node) var_name = conv_name_to_c(node.name) self.buf('/* Node %s index %d */\n' % (node.path, node.idx)) self._output_values(var_name, struct_name, node) self._declare_device(var_name, struct_name, node.parent) self.out(''.join(self.get_buf()))
def _output_prop(self, node, prop): """Output a line containing the value of a struct member Args: node (Node): Node being output prop (Prop): Prop object to output """ if prop.name in PROP_IGNORE_LIST or prop.name[0] == '#': return member_name = conv_name_to_c(prop.name) self.buf('\t%s= ' % tab_to(3, '.' + member_name)) # Special handling for lists if isinstance(prop.value, list): self._output_list(node, prop) else: self.buf(get_value(prop.type, prop.value)) self.buf(',\n')
def scan_tree(self, add_root): """Scan the device tree for useful information This fills in the following properties: _valid_nodes_unsorted: A list of nodes we wish to consider include in the platform data (in devicetree node order) _valid_nodes: Sorted version of _valid_nodes_unsorted Args: add_root: True to add the root node also (which wouldn't normally be added as it may not have a compatible string) """ root = self._fdt.GetRoot() valid_nodes = [] if add_root: valid_nodes.append(root) self.scan_node(root, valid_nodes) self._valid_nodes_unsorted = valid_nodes self._valid_nodes = sorted(valid_nodes, key=lambda x: conv_name_to_c(x.name))
def prepare_nodes(self): """Add extra properties to the nodes we are using The following properties are added for use by dtoc: idx: Index number of this node (0=first, etc.) struct_name: Name of the struct dtd used by this node var_name: C name for this node child_devs: List of child devices for this node, each a None child_refs: Dict of references for each child: key: Position in child list (-1=head, 0=first, 1=second, ... n-1=last, n=head) seq: Sequence number of the device (unique within its uclass), or -1 not not known yet dev_ref: Reference to this device, e.g. 'DM_DEVICE_REF(serial)' driver: Driver record for this node, or None if not known uclass: Uclass record for this node, or None if not known uclass_seq: Position of this device within the uclass list (0=first, n-1=last) parent_seq: Position of this device within it siblings (0=first, n-1=last) parent_driver: Driver record of the node's parent, or None if none. We don't use node.parent.driver since node.parent may not be in the list of valid nodes """ for idx, node in enumerate(self._valid_nodes): node.idx = idx node.struct_name, _ = self._scan.get_normalized_compat_name(node) node.var_name = conv_name_to_c(node.name) node.child_devs = [] node.child_refs = {} node.seq = -1 node.dev_ref = None node.driver = None node.uclass = None node.uclass_seq = None node.parent_seq = None node.parent_driver = None