Commit 4a032827 authored by Saravana Kannan's avatar Saravana Kannan Committed by Greg Kroah-Hartman

of: property: Simplify of_link_to_phandle()

The driver core now:
- Has the parent device of a supplier pick up the consumers if the
  supplier never has a device created for it.
- Ignores a supplier if the supplier has no parent device and will never
  be probed by a driver

And already prevents creating a device link with the consumer as a
supplier of a parent.

So, we no longer need to find the "compatible" node of the supplier or
do any other checks in of_link_to_phandle(). We simply need to make sure
that the supplier is available in DT.
Signed-off-by: default avatarSaravana Kannan <saravanak@google.com>
Tested-by: default avatarColin Foster <colin.foster@in-advantage.com>
Tested-by: default avatarSudeep Holla <sudeep.holla@arm.com>
Tested-by: default avatarDouglas Anderson <dianders@chromium.org>
Tested-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Tested-by: Luca Weiss <luca.weiss@fairphone.com> # qcom/sm7225-fairphone-fp4
Link: https://lore.kernel.org/r/20230207014207.1678715-10-saravanak@google.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 3fb16866
...@@ -1062,20 +1062,6 @@ of_fwnode_device_get_match_data(const struct fwnode_handle *fwnode, ...@@ -1062,20 +1062,6 @@ of_fwnode_device_get_match_data(const struct fwnode_handle *fwnode,
return of_device_get_match_data(dev); return of_device_get_match_data(dev);
} }
static bool of_is_ancestor_of(struct device_node *test_ancestor,
struct device_node *child)
{
of_node_get(child);
while (child) {
if (child == test_ancestor) {
of_node_put(child);
return true;
}
child = of_get_next_parent(child);
}
return false;
}
static struct device_node *of_get_compat_node(struct device_node *np) static struct device_node *of_get_compat_node(struct device_node *np)
{ {
of_node_get(np); of_node_get(np);
...@@ -1106,71 +1092,27 @@ static struct device_node *of_get_compat_node_parent(struct device_node *np) ...@@ -1106,71 +1092,27 @@ static struct device_node *of_get_compat_node_parent(struct device_node *np)
return node; return node;
} }
/** static void of_link_to_phandle(struct device_node *con_np,
* of_link_to_phandle - Add fwnode link to supplier from supplier phandle
* @con_np: consumer device tree node
* @sup_np: supplier device tree node
*
* Given a phandle to a supplier device tree node (@sup_np), this function
* finds the device that owns the supplier device tree node and creates a
* device link from @dev consumer device to the supplier device. This function
* doesn't create device links for invalid scenarios such as trying to create a
* link with a parent device as the consumer of its child device. In such
* cases, it returns an error.
*
* Returns:
* - 0 if fwnode link successfully created to supplier
* - -EINVAL if the supplier link is invalid and should not be created
* - -ENODEV if struct device will never be create for supplier
*/
static int of_link_to_phandle(struct device_node *con_np,
struct device_node *sup_np) struct device_node *sup_np)
{ {
struct device *sup_dev; struct device_node *tmp_np = of_node_get(sup_np);
struct device_node *tmp_np = sup_np;
/* /* Check that sup_np and its ancestors are available. */
* Find the device node that contains the supplier phandle. It may be while (tmp_np) {
* @sup_np or it may be an ancestor of @sup_np. if (of_fwnode_handle(tmp_np)->dev) {
*/ of_node_put(tmp_np);
sup_np = of_get_compat_node(sup_np); break;
if (!sup_np) { }
pr_debug("Not linking %pOFP to %pOFP - No device\n",
con_np, tmp_np);
return -ENODEV;
}
/* if (!of_device_is_available(tmp_np)) {
* Don't allow linking a device node as a consumer of one of its of_node_put(tmp_np);
* descendant nodes. By definition, a child node can't be a functional return;
* dependency for the parent node. }
*/
if (of_is_ancestor_of(con_np, sup_np)) {
pr_debug("Not linking %pOFP to %pOFP - is descendant\n",
con_np, sup_np);
of_node_put(sup_np);
return -EINVAL;
}
/* tmp_np = of_get_next_parent(tmp_np);
* Don't create links to "early devices" that won't have struct devices
* created for them.
*/
sup_dev = get_dev_from_fwnode(&sup_np->fwnode);
if (!sup_dev &&
(of_node_check_flag(sup_np, OF_POPULATED) ||
sup_np->fwnode.flags & FWNODE_FLAG_NOT_DEVICE)) {
pr_debug("Not linking %pOFP to %pOFP - No struct device\n",
con_np, sup_np);
of_node_put(sup_np);
return -ENODEV;
} }
put_device(sup_dev);
fwnode_link_add(of_fwnode_handle(con_np), of_fwnode_handle(sup_np)); fwnode_link_add(of_fwnode_handle(con_np), of_fwnode_handle(sup_np));
of_node_put(sup_np);
return 0;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment