mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	scripts/dtc: Update to upstream version v1.4.6-21-g84e414b0b5bc
This adds the following commits from upstream: 84e414b0b5bc tests: Add a test case for the omit-if-no-ref keyword 4038fd90056e dtc: add ability to make nodes conditional on them being referenced e1f139ea4900 checks: drop warning for missing PCI bridge bus-range f4eba68d89ee checks: Print duplicate node name instead of parent name 46df1fb1b211 .travis.yml: Run valgrind checks via Travis 14a3002a1aee tests: Update valgrind suppressions for sw_tree1 02c5fe9debc0 tests: Remove valgrind error from tests/get_path df536831d02c checks: add graph binding checks 2347c96edcbe checks: add a check for duplicate unit-addresses of child nodes 8f1b35f88395 Correct overlay syntactic sugar for generating target-path fragments afbddcd418fb Suppress warnings on overlay fragments 119e27300359 Improve tests for dtc overlay generation Signed-off-by: Rob Herring <robh@kernel.org>
This commit is contained in:
		
							parent
							
								
									9601000cd5
								
							
						
					
					
						commit
						50aafd6089
					
				
					 6 changed files with 261 additions and 16 deletions
				
			
		| 
						 | 
				
			
			@ -255,7 +255,7 @@ static void check_duplicate_node_names(struct check *c, struct dt_info *dti,
 | 
			
		|||
		     child2;
 | 
			
		||||
		     child2 = child2->next_sibling)
 | 
			
		||||
			if (streq(child->name, child2->name))
 | 
			
		||||
				FAIL(c, dti, node, "Duplicate node name");
 | 
			
		||||
				FAIL(c, dti, child2, "Duplicate node name");
 | 
			
		||||
}
 | 
			
		||||
ERROR(duplicate_node_names, check_duplicate_node_names, NULL);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -317,6 +317,11 @@ static void check_unit_address_vs_reg(struct check *c, struct dt_info *dti,
 | 
			
		|||
	const char *unitname = get_unitname(node);
 | 
			
		||||
	struct property *prop = get_property(node, "reg");
 | 
			
		||||
 | 
			
		||||
	if (get_subnode(node, "__overlay__")) {
 | 
			
		||||
		/* HACK: Overlay fragments are a special case */
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!prop) {
 | 
			
		||||
		prop = get_property(node, "ranges");
 | 
			
		||||
		if (prop && !prop->val.len)
 | 
			
		||||
| 
						 | 
				
			
			@ -579,6 +584,8 @@ static void fixup_phandle_references(struct check *c, struct dt_info *dti,
 | 
			
		|||
 | 
			
		||||
			phandle = get_node_phandle(dt, refnode);
 | 
			
		||||
			*((fdt32_t *)(prop->val.val + m->offset)) = cpu_to_fdt32(phandle);
 | 
			
		||||
 | 
			
		||||
			reference_node(refnode);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -609,11 +616,21 @@ static void fixup_path_references(struct check *c, struct dt_info *dti,
 | 
			
		|||
			path = refnode->fullpath;
 | 
			
		||||
			prop->val = data_insert_at_marker(prop->val, m, path,
 | 
			
		||||
							  strlen(path) + 1);
 | 
			
		||||
 | 
			
		||||
			reference_node(refnode);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
ERROR(path_references, fixup_path_references, NULL, &duplicate_node_names);
 | 
			
		||||
 | 
			
		||||
static void fixup_omit_unused_nodes(struct check *c, struct dt_info *dti,
 | 
			
		||||
				    struct node *node)
 | 
			
		||||
{
 | 
			
		||||
	if (node->omit_if_unused && !node->is_referenced)
 | 
			
		||||
		delete_node(node);
 | 
			
		||||
}
 | 
			
		||||
ERROR(omit_unused_nodes, fixup_omit_unused_nodes, NULL, &phandle_references, &path_references);
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Semantic checks
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			@ -1017,6 +1034,36 @@ static void check_avoid_unnecessary_addr_size(struct check *c, struct dt_info *d
 | 
			
		|||
}
 | 
			
		||||
WARNING(avoid_unnecessary_addr_size, check_avoid_unnecessary_addr_size, NULL, &avoid_default_addr_size);
 | 
			
		||||
 | 
			
		||||
static void check_unique_unit_address(struct check *c, struct dt_info *dti,
 | 
			
		||||
					      struct node *node)
 | 
			
		||||
{
 | 
			
		||||
	struct node *childa;
 | 
			
		||||
 | 
			
		||||
	if (node->addr_cells < 0 || node->size_cells < 0)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (!node->children)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	for_each_child(node, childa) {
 | 
			
		||||
		struct node *childb;
 | 
			
		||||
		const char *addr_a = get_unitname(childa);
 | 
			
		||||
 | 
			
		||||
		if (!strlen(addr_a))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		for_each_child(node, childb) {
 | 
			
		||||
			const char *addr_b = get_unitname(childb);
 | 
			
		||||
			if (childa == childb)
 | 
			
		||||
				break;
 | 
			
		||||
 | 
			
		||||
			if (streq(addr_a, addr_b))
 | 
			
		||||
				FAIL(c, dti, childb, "duplicate unit-address (also used in node %s)", childa->fullpath);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
WARNING(unique_unit_address, check_unique_unit_address, NULL, &avoid_default_addr_size);
 | 
			
		||||
 | 
			
		||||
static void check_obsolete_chosen_interrupt_controller(struct check *c,
 | 
			
		||||
						       struct dt_info *dti,
 | 
			
		||||
						       struct node *node)
 | 
			
		||||
| 
						 | 
				
			
			@ -1357,6 +1404,152 @@ static void check_interrupts_property(struct check *c,
 | 
			
		|||
}
 | 
			
		||||
WARNING(interrupts_property, check_interrupts_property, &phandle_references);
 | 
			
		||||
 | 
			
		||||
static const struct bus_type graph_port_bus = {
 | 
			
		||||
	.name = "graph-port",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const struct bus_type graph_ports_bus = {
 | 
			
		||||
	.name = "graph-ports",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static void check_graph_nodes(struct check *c, struct dt_info *dti,
 | 
			
		||||
			      struct node *node)
 | 
			
		||||
{
 | 
			
		||||
	struct node *child;
 | 
			
		||||
 | 
			
		||||
	for_each_child(node, child) {
 | 
			
		||||
		if (!(strprefixeq(child->name, child->basenamelen, "endpoint") ||
 | 
			
		||||
		      get_property(child, "remote-endpoint")))
 | 
			
		||||
			continue;
 | 
			
		||||
 | 
			
		||||
		node->bus = &graph_port_bus;
 | 
			
		||||
 | 
			
		||||
		/* The parent of 'port' nodes can be either 'ports' or a device */
 | 
			
		||||
		if (!node->parent->bus &&
 | 
			
		||||
		    (streq(node->parent->name, "ports") || get_property(node, "reg")))
 | 
			
		||||
			node->parent->bus = &graph_ports_bus;
 | 
			
		||||
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
WARNING(graph_nodes, check_graph_nodes, NULL);
 | 
			
		||||
 | 
			
		||||
static void check_graph_child_address(struct check *c, struct dt_info *dti,
 | 
			
		||||
				      struct node *node)
 | 
			
		||||
{
 | 
			
		||||
	int cnt = 0;
 | 
			
		||||
	struct node *child;
 | 
			
		||||
 | 
			
		||||
	if (node->bus != &graph_ports_bus && node->bus != &graph_port_bus)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	for_each_child(node, child) {
 | 
			
		||||
		struct property *prop = get_property(child, "reg");
 | 
			
		||||
 | 
			
		||||
		/* No error if we have any non-zero unit address */
 | 
			
		||||
		if (prop && propval_cell(prop) != 0)
 | 
			
		||||
			return;
 | 
			
		||||
 | 
			
		||||
		cnt++;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (cnt == 1 && node->addr_cells != -1)
 | 
			
		||||
		FAIL(c, dti, node, "graph node has single child node '%s', #address-cells/#size-cells are not necessary",
 | 
			
		||||
		     node->children->name);
 | 
			
		||||
}
 | 
			
		||||
WARNING(graph_child_address, check_graph_child_address, NULL, &graph_nodes);
 | 
			
		||||
 | 
			
		||||
static void check_graph_reg(struct check *c, struct dt_info *dti,
 | 
			
		||||
			    struct node *node)
 | 
			
		||||
{
 | 
			
		||||
	char unit_addr[9];
 | 
			
		||||
	const char *unitname = get_unitname(node);
 | 
			
		||||
	struct property *prop;
 | 
			
		||||
 | 
			
		||||
	prop = get_property(node, "reg");
 | 
			
		||||
	if (!prop || !unitname)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (!(prop->val.val && prop->val.len == sizeof(cell_t))) {
 | 
			
		||||
		FAIL(c, dti, node, "graph node malformed 'reg' property");
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	snprintf(unit_addr, sizeof(unit_addr), "%x", propval_cell(prop));
 | 
			
		||||
	if (!streq(unitname, unit_addr))
 | 
			
		||||
		FAIL(c, dti, node, "graph node unit address error, expected \"%s\"",
 | 
			
		||||
		     unit_addr);
 | 
			
		||||
 | 
			
		||||
	if (node->parent->addr_cells != 1)
 | 
			
		||||
		FAIL_PROP(c, dti, node, get_property(node, "#address-cells"),
 | 
			
		||||
			  "graph node '#address-cells' is %d, must be 1",
 | 
			
		||||
			  node->parent->addr_cells);
 | 
			
		||||
	if (node->parent->size_cells != 0)
 | 
			
		||||
		FAIL_PROP(c, dti, node, get_property(node, "#size-cells"),
 | 
			
		||||
			  "graph node '#size-cells' is %d, must be 0",
 | 
			
		||||
			  node->parent->size_cells);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void check_graph_port(struct check *c, struct dt_info *dti,
 | 
			
		||||
			     struct node *node)
 | 
			
		||||
{
 | 
			
		||||
	if (node->bus != &graph_port_bus)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (!strprefixeq(node->name, node->basenamelen, "port"))
 | 
			
		||||
		FAIL(c, dti, node, "graph port node name should be 'port'");
 | 
			
		||||
 | 
			
		||||
	check_graph_reg(c, dti, node);
 | 
			
		||||
}
 | 
			
		||||
WARNING(graph_port, check_graph_port, NULL, &graph_nodes);
 | 
			
		||||
 | 
			
		||||
static struct node *get_remote_endpoint(struct check *c, struct dt_info *dti,
 | 
			
		||||
					struct node *endpoint)
 | 
			
		||||
{
 | 
			
		||||
	int phandle;
 | 
			
		||||
	struct node *node;
 | 
			
		||||
	struct property *prop;
 | 
			
		||||
 | 
			
		||||
	prop = get_property(endpoint, "remote-endpoint");
 | 
			
		||||
	if (!prop)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	phandle = propval_cell(prop);
 | 
			
		||||
	/* Give up if this is an overlay with external references */
 | 
			
		||||
	if (phandle == 0 || phandle == -1)
 | 
			
		||||
		return NULL;
 | 
			
		||||
 | 
			
		||||
	node = get_node_by_phandle(dti->dt, phandle);
 | 
			
		||||
	if (!node)
 | 
			
		||||
		FAIL_PROP(c, dti, endpoint, prop, "graph phandle is not valid");
 | 
			
		||||
 | 
			
		||||
	return node;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void check_graph_endpoint(struct check *c, struct dt_info *dti,
 | 
			
		||||
				 struct node *node)
 | 
			
		||||
{
 | 
			
		||||
	struct node *remote_node;
 | 
			
		||||
 | 
			
		||||
	if (!node->parent || node->parent->bus != &graph_port_bus)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (!strprefixeq(node->name, node->basenamelen, "endpoint"))
 | 
			
		||||
		FAIL(c, dti, node, "graph endpont node name should be 'endpoint'");
 | 
			
		||||
 | 
			
		||||
	check_graph_reg(c, dti, node);
 | 
			
		||||
 | 
			
		||||
	remote_node = get_remote_endpoint(c, dti, node);
 | 
			
		||||
	if (!remote_node)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (get_remote_endpoint(c, dti, remote_node) != node)
 | 
			
		||||
		FAIL(c, dti, node, "graph connection to node '%s' is not bidirectional",
 | 
			
		||||
		     remote_node->fullpath);
 | 
			
		||||
}
 | 
			
		||||
WARNING(graph_endpoint, check_graph_endpoint, NULL, &graph_nodes);
 | 
			
		||||
 | 
			
		||||
static struct check *check_table[] = {
 | 
			
		||||
	&duplicate_node_names, &duplicate_property_names,
 | 
			
		||||
	&node_name_chars, &node_name_format, &property_name_chars,
 | 
			
		||||
| 
						 | 
				
			
			@ -1366,6 +1559,7 @@ static struct check *check_table[] = {
 | 
			
		|||
 | 
			
		||||
	&explicit_phandles,
 | 
			
		||||
	&phandle_references, &path_references,
 | 
			
		||||
	&omit_unused_nodes,
 | 
			
		||||
 | 
			
		||||
	&address_cells_is_cell, &size_cells_is_cell, &interrupt_cells_is_cell,
 | 
			
		||||
	&device_type_is_string, &model_is_string, &status_is_string,
 | 
			
		||||
| 
						 | 
				
			
			@ -1390,6 +1584,7 @@ static struct check *check_table[] = {
 | 
			
		|||
 | 
			
		||||
	&avoid_default_addr_size,
 | 
			
		||||
	&avoid_unnecessary_addr_size,
 | 
			
		||||
	&unique_unit_address,
 | 
			
		||||
	&obsolete_chosen_interrupt_controller,
 | 
			
		||||
	&chosen_node_is_root, &chosen_node_bootargs, &chosen_node_stdout_path,
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1416,6 +1611,8 @@ static struct check *check_table[] = {
 | 
			
		|||
 | 
			
		||||
	&alias_paths,
 | 
			
		||||
 | 
			
		||||
	&graph_nodes, &graph_child_address, &graph_port, &graph_endpoint,
 | 
			
		||||
 | 
			
		||||
	&always_fail,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -153,6 +153,13 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
 | 
			
		|||
			return DT_DEL_NODE;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
<*>"/omit-if-no-ref/"	{
 | 
			
		||||
			DPRINT("Keyword: /omit-if-no-ref/\n");
 | 
			
		||||
			DPRINT("<PROPNODENAME>\n");
 | 
			
		||||
			BEGIN(PROPNODENAME);
 | 
			
		||||
			return DT_OMIT_NO_REF;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
<*>{LABEL}:	{
 | 
			
		||||
			DPRINT("Label: %s\n", yytext);
 | 
			
		||||
			yylval.labelref = xstrdup(yytext);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -63,6 +63,7 @@ extern bool treesource_error;
 | 
			
		|||
%token DT_BITS
 | 
			
		||||
%token DT_DEL_PROP
 | 
			
		||||
%token DT_DEL_NODE
 | 
			
		||||
%token DT_OMIT_NO_REF
 | 
			
		||||
%token <propnodename> DT_PROPNODENAME
 | 
			
		||||
%token <integer> DT_LITERAL
 | 
			
		||||
%token <integer> DT_CHAR_LITERAL
 | 
			
		||||
| 
						 | 
				
			
			@ -190,18 +191,18 @@ devicetree:
 | 
			
		|||
		}
 | 
			
		||||
	| devicetree DT_REF nodedef
 | 
			
		||||
		{
 | 
			
		||||
			struct node *target = get_node_by_ref($1, $2);
 | 
			
		||||
 | 
			
		||||
			if (target) {
 | 
			
		||||
				merge_nodes(target, $3);
 | 
			
		||||
			/*
 | 
			
		||||
			 * We rely on the rule being always:
 | 
			
		||||
			 *   versioninfo plugindecl memreserves devicetree
 | 
			
		||||
			 * so $-1 is what we want (plugindecl)
 | 
			
		||||
			 */
 | 
			
		||||
			if ($<flags>-1 & DTSF_PLUGIN) {
 | 
			
		||||
				add_orphan_node($1, $3, $2);
 | 
			
		||||
			} else {
 | 
			
		||||
				/*
 | 
			
		||||
				 * We rely on the rule being always:
 | 
			
		||||
				 *   versioninfo plugindecl memreserves devicetree
 | 
			
		||||
				 * so $-1 is what we want (plugindecl)
 | 
			
		||||
				 */
 | 
			
		||||
				if ($<flags>-1 & DTSF_PLUGIN)
 | 
			
		||||
					add_orphan_node($1, $3, $2);
 | 
			
		||||
				struct node *target = get_node_by_ref($1, $2);
 | 
			
		||||
 | 
			
		||||
				if (target)
 | 
			
		||||
					merge_nodes(target, $3);
 | 
			
		||||
				else
 | 
			
		||||
					ERROR(&@2, "Label or path %s not found", $2);
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			@ -217,6 +218,18 @@ devicetree:
 | 
			
		|||
				ERROR(&@3, "Label or path %s not found", $3);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
			$$ = $1;
 | 
			
		||||
		}
 | 
			
		||||
	| devicetree DT_OMIT_NO_REF DT_REF ';'
 | 
			
		||||
		{
 | 
			
		||||
			struct node *target = get_node_by_ref($1, $3);
 | 
			
		||||
 | 
			
		||||
			if (target)
 | 
			
		||||
				omit_node_if_unused(target);
 | 
			
		||||
			else
 | 
			
		||||
				ERROR(&@3, "Label or path %s not found", $3);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
			$$ = $1;
 | 
			
		||||
		}
 | 
			
		||||
	;
 | 
			
		||||
| 
						 | 
				
			
			@ -523,6 +536,10 @@ subnode:
 | 
			
		|||
		{
 | 
			
		||||
			$$ = name_node(build_node_delete(), $2);
 | 
			
		||||
		}
 | 
			
		||||
	| DT_OMIT_NO_REF subnode
 | 
			
		||||
		{
 | 
			
		||||
			$$ = omit_node_if_unused($2);
 | 
			
		||||
		}
 | 
			
		||||
	| DT_LABEL subnode
 | 
			
		||||
		{
 | 
			
		||||
			add_label(&$2->labels, $1);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -168,6 +168,8 @@ struct node {
 | 
			
		|||
 | 
			
		||||
	struct label *labels;
 | 
			
		||||
	const struct bus_type *bus;
 | 
			
		||||
 | 
			
		||||
	bool omit_if_unused, is_referenced;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define for_each_label_withdel(l0, l) \
 | 
			
		||||
| 
						 | 
				
			
			@ -202,6 +204,8 @@ struct property *reverse_properties(struct property *first);
 | 
			
		|||
struct node *build_node(struct property *proplist, struct node *children);
 | 
			
		||||
struct node *build_node_delete(void);
 | 
			
		||||
struct node *name_node(struct node *node, char *name);
 | 
			
		||||
struct node *omit_node_if_unused(struct node *node);
 | 
			
		||||
struct node *reference_node(struct node *node);
 | 
			
		||||
struct node *chain_node(struct node *first, struct node *list);
 | 
			
		||||
struct node *merge_nodes(struct node *old_node, struct node *new_node);
 | 
			
		||||
struct node *add_orphan_node(struct node *old_node, struct node *new_node, char *ref);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -134,6 +134,20 @@ struct node *name_node(struct node *node, char *name)
 | 
			
		|||
	return node;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct node *omit_node_if_unused(struct node *node)
 | 
			
		||||
{
 | 
			
		||||
	node->omit_if_unused = 1;
 | 
			
		||||
 | 
			
		||||
	return node;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct node *reference_node(struct node *node)
 | 
			
		||||
{
 | 
			
		||||
	node->is_referenced = 1;
 | 
			
		||||
 | 
			
		||||
	return node;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct node *merge_nodes(struct node *old_node, struct node *new_node)
 | 
			
		||||
{
 | 
			
		||||
	struct property *new_prop, *old_prop;
 | 
			
		||||
| 
						 | 
				
			
			@ -224,10 +238,16 @@ struct node * add_orphan_node(struct node *dt, struct node *new_node, char *ref)
 | 
			
		|||
	struct data d = empty_data;
 | 
			
		||||
	char *name;
 | 
			
		||||
 | 
			
		||||
	d = data_add_marker(d, REF_PHANDLE, ref);
 | 
			
		||||
	d = data_append_integer(d, 0xffffffff, 32);
 | 
			
		||||
	if (ref[0] == '/') {
 | 
			
		||||
		d = data_append_data(d, ref, strlen(ref) + 1);
 | 
			
		||||
 | 
			
		||||
	p = build_property("target", d);
 | 
			
		||||
		p = build_property("target-path", d);
 | 
			
		||||
	} else {
 | 
			
		||||
		d = data_add_marker(d, REF_PHANDLE, ref);
 | 
			
		||||
		d = data_append_integer(d, 0xffffffff, 32);
 | 
			
		||||
 | 
			
		||||
		p = build_property("target", d);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	xasprintf(&name, "fragment@%u",
 | 
			
		||||
			next_orphan_fragment++);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1 +1 @@
 | 
			
		|||
#define DTC_VERSION "DTC 1.4.6-gaadd0b65"
 | 
			
		||||
#define DTC_VERSION "DTC 1.4.6-g84e414b0"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue