int of_resolve_phandles()

in resolver.c [263:350]


int of_resolve_phandles(struct device_node *overlay)
{
	struct device_node *child, *local_fixups, *refnode;
	struct device_node *tree_symbols, *overlay_fixups;
	struct property *prop;
	const char *refpath;
	phandle phandle, phandle_delta;
	int err;

	tree_symbols = NULL;

	if (!overlay) {
		pr_err("null overlay\n");
		err = -EINVAL;
		goto out;
	}

	if (!of_node_check_flag(overlay, OF_DETACHED)) {
		pr_err("overlay not detached\n");
		err = -EINVAL;
		goto out;
	}

	phandle_delta = live_tree_max_phandle() + 1;
	adjust_overlay_phandles(overlay, phandle_delta);

	for_each_child_of_node(overlay, local_fixups)
		if (of_node_name_eq(local_fixups, "__local_fixups__"))
			break;

	err = adjust_local_phandle_references(local_fixups, overlay, phandle_delta);
	if (err)
		goto out;

	overlay_fixups = NULL;

	for_each_child_of_node(overlay, child) {
		if (of_node_name_eq(child, "__fixups__"))
			overlay_fixups = child;
	}

	if (!overlay_fixups) {
		err = 0;
		goto out;
	}

	tree_symbols = of_find_node_by_path("/__symbols__");
	if (!tree_symbols) {
		pr_err("no symbols in root of device tree.\n");
		err = -EINVAL;
		goto out;
	}

	for_each_property_of_node(overlay_fixups, prop) {

		/* skip properties added automatically */
		if (!of_prop_cmp(prop->name, "name"))
			continue;

		err = of_property_read_string(tree_symbols,
				prop->name, &refpath);
		if (err) {
			pr_err("node label '%s' not found in live devicetree symbols table\n",
			       prop->name);
			goto out;
		}

		refnode = of_find_node_by_path(refpath);
		if (!refnode) {
			err = -ENOENT;
			goto out;
		}

		phandle = refnode->phandle;
		of_node_put(refnode);

		err = update_usages_of_a_phandle_reference(overlay, prop, phandle);
		if (err)
			break;
	}

out:
	if (err)
		pr_err("overlay phandle fixup failed: %d\n", err);
	of_node_put(tree_symbols);

	return err;
}