Commit d77b3f07 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

Revert "of/platform: Add functional dependency link from DT bindings"



This reverts commit 690ff788.

Based on a lot of email and in-person discussions, this patch series is
being reworked to address a number of issues that were pointed out that
needed to be taken care of before it should be merged.  It will be
resubmitted with those changes hopefully soon.

Cc: Frank Rowand <frowand.list@gmail.com>
Cc: Saravana Kannan <saravanak@google.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent bcca686c
Loading
Loading
Loading
Loading
+0 −5
Original line number Diff line number Diff line
@@ -3170,11 +3170,6 @@
			This can be set from sysctl after boot.
			See Documentation/admin-guide/sysctl/vm.rst for details.

	of_devlink	[KNL] Make device links from common DT bindings. Useful
			for optimizing probe order and making sure resources
			aren't turned off before the consumer devices have
			probed.

	ohci1394_dma=early	[HW] enable debugging via the ohci1394 driver.
			See Documentation/debugging-via-ohci1394.txt for more
			info.
+0 −165
Original line number Diff line number Diff line
@@ -503,170 +503,6 @@ int of_platform_default_populate(struct device_node *root,
}
EXPORT_SYMBOL_GPL(of_platform_default_populate);

bool of_link_is_valid(struct device_node *con, struct device_node *sup)
{
	of_node_get(sup);
	/*
	 * Don't allow linking a device node as a consumer of one of its
	 * descendant nodes. By definition, a child node can't be a functional
	 * dependency for the parent node.
	 */
	while (sup) {
		if (sup == con) {
			of_node_put(sup);
			return false;
		}
		sup = of_get_next_parent(sup);
	}
	return true;
}

static int of_link_to_phandle(struct device *dev, struct device_node *sup_np)
{
	struct platform_device *sup_dev;
	u32 dl_flags = DL_FLAG_AUTOPROBE_CONSUMER;
	int ret = 0;

	/*
	 * Since we are trying to create device links, we need to find
	 * the actual device node that owns this supplier phandle.
	 * Often times it's the same node, but sometimes it can be one
	 * of the parents. So walk up the parent till you find a
	 * device.
	 */
	while (sup_np && !of_find_property(sup_np, "compatible", NULL))
		sup_np = of_get_next_parent(sup_np);
	if (!sup_np)
		return 0;

	if (!of_link_is_valid(dev->of_node, sup_np)) {
		of_node_put(sup_np);
		return 0;
	}
	sup_dev = of_find_device_by_node(sup_np);
	of_node_put(sup_np);
	if (!sup_dev)
		return -ENODEV;
	if (!device_link_add(dev, &sup_dev->dev, dl_flags))
		ret = -ENODEV;
	put_device(&sup_dev->dev);
	return ret;
}

static struct device_node *parse_prop_cells(struct device_node *np,
					    const char *prop, int index,
					    const char *binding,
					    const char *cell)
{
	struct of_phandle_args sup_args;

	/* Don't need to check property name for every index. */
	if (!index && strcmp(prop, binding))
		return NULL;

	if (of_parse_phandle_with_args(np, binding, cell, index, &sup_args))
		return NULL;

	return sup_args.np;
}

static struct device_node *parse_clocks(struct device_node *np,
					const char *prop, int index)
{
	return parse_prop_cells(np, prop, index, "clocks", "#clock-cells");
}

static struct device_node *parse_interconnects(struct device_node *np,
					       const char *prop, int index)
{
	return parse_prop_cells(np, prop, index, "interconnects",
				"#interconnect-cells");
}

static int strcmp_suffix(const char *str, const char *suffix)
{
	unsigned int len, suffix_len;

	len = strlen(str);
	suffix_len = strlen(suffix);
	if (len <= suffix_len)
		return -1;
	return strcmp(str + len - suffix_len, suffix);
}

static struct device_node *parse_regulators(struct device_node *np,
					    const char *prop, int index)
{
	if (index || strcmp_suffix(prop, "-supply"))
		return NULL;

	return of_parse_phandle(np, prop, 0);
}

/**
 * struct supplier_bindings - Information for parsing supplier DT binding
 *
 * @parse_prop:		If the function cannot parse the property, return NULL.
 *			Otherwise, return the phandle listed in the property
 *			that corresponds to the index.
 */
struct supplier_bindings {
	struct device_node *(*parse_prop)(struct device_node *np,
					  const char *name, int index);
};

static const struct supplier_bindings bindings[] = {
	{ .parse_prop = parse_clocks, },
	{ .parse_prop = parse_interconnects, },
	{ .parse_prop = parse_regulators, },
	{ },
};

static bool of_link_property(struct device *dev, struct device_node *con_np,
			     const char *prop)
{
	struct device_node *phandle;
	const struct supplier_bindings *s = bindings;
	unsigned int i = 0;
	bool done = true, matched = false;

	while (!matched && s->parse_prop) {
		while ((phandle = s->parse_prop(con_np, prop, i))) {
			matched = true;
			i++;
			if (of_link_to_phandle(dev, phandle))
				/*
				 * Don't stop at the first failure. See
				 * Documentation for bus_type.add_links for
				 * more details.
				 */
				done = false;
		}
		s++;
	}
	return done ? 0 : -ENODEV;
}

static bool of_devlink;
core_param(of_devlink, of_devlink, bool, 0);

static int of_link_to_suppliers(struct device *dev)
{
	struct property *p;
	bool done = true;

	if (!of_devlink)
		return 0;
	if (unlikely(!dev->of_node))
		return 0;

	for_each_property_of_node(dev->of_node, p)
		if (of_link_property(dev, dev->of_node, p->name))
			done = false;

	return done ? 0 : -ENODEV;
}

#ifndef CONFIG_PPC
static const struct of_device_id reserved_mem_matches[] = {
	{ .compatible = "qcom,rmtfs-mem" },
@@ -682,7 +518,6 @@ static int __init of_platform_default_populate_init(void)
	if (!of_have_populated_dt())
		return -ENODEV;

	platform_bus_type.add_links = of_link_to_suppliers;
	/*
	 * Handle certain compatibles explicitly, since we don't want to create
	 * platform_devices for every node in /reserved-memory with a