static int update_usages_of_a_phandle_reference()

in resolver.c [72:136]


static int update_usages_of_a_phandle_reference(struct device_node *overlay,
		struct property *prop_fixup, phandle phandle)
{
	struct device_node *refnode;
	struct property *prop;
	char *value, *cur, *end, *node_path, *prop_name, *s;
	int offset, len;
	int err = 0;

	value = kmemdup(prop_fixup->value, prop_fixup->length, GFP_KERNEL);
	if (!value)
		return -ENOMEM;

	/* prop_fixup contains a list of tuples of path:property_name:offset */
	end = value + prop_fixup->length;
	for (cur = value; cur < end; cur += len + 1) {
		len = strlen(cur);

		node_path = cur;
		s = strchr(cur, ':');
		if (!s) {
			err = -EINVAL;
			goto err_fail;
		}
		*s++ = '\0';

		prop_name = s;
		s = strchr(s, ':');
		if (!s) {
			err = -EINVAL;
			goto err_fail;
		}
		*s++ = '\0';

		err = kstrtoint(s, 10, &offset);
		if (err)
			goto err_fail;

		refnode = __of_find_node_by_full_path(of_node_get(overlay), node_path);
		if (!refnode)
			continue;

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

		if (!prop) {
			err = -ENOENT;
			goto err_fail;
		}

		if (offset < 0 || offset + sizeof(__be32) > prop->length) {
			err = -EINVAL;
			goto err_fail;
		}

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

err_fail:
	kfree(value);
	return err;
}