static int add_changeset_node()

in overlay.c [409:464]


static int add_changeset_node(struct overlay_changeset *ovcs,
		struct target *target, struct device_node *node)
{
	const char *node_kbasename;
	const __be32 *phandle;
	struct device_node *tchild;
	struct target target_child;
	int ret = 0, size;

	node_kbasename = kbasename(node->full_name);

	for_each_child_of_node(target->np, tchild)
		if (!of_node_cmp(node_kbasename, kbasename(tchild->full_name)))
			break;

	if (!tchild) {
		tchild = __of_node_dup(NULL, node_kbasename);
		if (!tchild)
			return -ENOMEM;

		tchild->parent = target->np;
		tchild->name = __of_get_property(node, "name", NULL);

		if (!tchild->name)
			tchild->name = "<NULL>";

		/* ignore obsolete "linux,phandle" */
		phandle = __of_get_property(node, "phandle", &size);
		if (phandle && (size == 4))
			tchild->phandle = be32_to_cpup(phandle);

		of_node_set_flag(tchild, OF_OVERLAY);

		ret = of_changeset_attach_node(&ovcs->cset, tchild);
		if (ret)
			return ret;

		target_child.np = tchild;
		target_child.in_livetree = false;

		ret = build_changeset_next_level(ovcs, &target_child, node);
		of_node_put(tchild);
		return ret;
	}

	if (node->phandle && tchild->phandle) {
		ret = -EINVAL;
	} else {
		target_child.np = tchild;
		target_child.in_livetree = target->in_livetree;
		ret = build_changeset_next_level(ovcs, &target_child, node);
	}
	of_node_put(tchild);

	return ret;
}