drivers/of/resolver.c

Source file repositories/reference/linux-study-clean/drivers/of/resolver.c

File Facts

System
Linux kernel
Corpus path
drivers/of/resolver.c
Extension
.c
Size
8636 bytes
Lines
326
Domain
Driver Families
Bucket
drivers/of
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

for_each_property_of_node(refnode, prop) {
			if (!of_prop_cmp(prop->name, prop_name))
				break;
		}
		of_node_put(refnode);

		if (!prop)
			return -ENOENT;

		if (offset < 0 || offset + sizeof(__be32) > prop->length)
			return -EINVAL;

		*(__be32 *)(prop->value + offset) = cpu_to_be32(phandle);
	}

	return 0;
}

/* compare nodes taking into account that 'name' strips out the @ part */
static int node_name_cmp(const struct device_node *dn1,
		const struct device_node *dn2)
{
	const char *n1 = kbasename(dn1->full_name);
	const char *n2 = kbasename(dn2->full_name);

	return of_node_cmp(n1, n2);
}

/*
 * Adjust the local phandle references by the given phandle delta.
 *
 * Subtree @local_fixups, which is overlay node __local_fixups__,
 * mirrors the fragment node structure at the root of the overlay.
 *
 * For each property in the fragments that contains a phandle reference,
 * @local_fixups has a property of the same name that contains a list
 * of offsets of the phandle reference(s) within the respective property
 * value(s).  The values at these offsets will be fixed up.
 */
static int adjust_local_phandle_references(const struct device_node *local_fixups,
		const struct device_node *overlay, int phandle_delta)
{
	struct device_node *overlay_child;
	const struct property *prop_fix, *prop;
	int err, i, count;
	unsigned int off;

	if (!local_fixups)
		return 0;

	for_each_property_of_node(local_fixups, prop_fix) {

		/* skip properties added automatically */
		if (is_pseudo_property(prop_fix->name))
			continue;

		if ((prop_fix->length % 4) != 0 || prop_fix->length == 0)
			return -EINVAL;
		count = prop_fix->length / sizeof(__be32);

		for_each_property_of_node(overlay, prop) {
			if (!of_prop_cmp(prop->name, prop_fix->name))
				break;
		}

		if (!prop)
			return -EINVAL;

		for (i = 0; i < count; i++) {
			off = be32_to_cpu(((__be32 *)prop_fix->value)[i]);
			if ((off + 4) > prop->length)
				return -EINVAL;

			be32_add_cpu(prop->value + off, phandle_delta);
		}
	}

	/*
	 * These nested loops recurse down two subtrees in parallel, where the
	 * node names in the two subtrees match.
	 *
	 * The roots of the subtrees are the overlay's __local_fixups__ node
	 * and the overlay's root node.
	 */
	for_each_child_of_node_scoped(local_fixups, child) {

		for_each_child_of_node(overlay, overlay_child)
			if (!node_name_cmp(child, overlay_child)) {
				of_node_put(overlay_child);
				break;

Annotation

Implementation Notes