lkml.org 
[lkml]   [2020]   [Nov]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    Subject[PATCH v2 14/17] of: property: Update implementation of add_links() to create fwnode links
    From
    The semantics of add_links() has changed from creating device link
    between devices to creating fwnode links between fwnodes. So, update the
    implementation of add_links() to match the new semantics.

    Signed-off-by: Saravana Kannan <saravanak@google.com>
    ---
    drivers/of/property.c | 150 ++++++++++++------------------------------
    1 file changed, 41 insertions(+), 109 deletions(-)

    diff --git a/drivers/of/property.c b/drivers/of/property.c
    index 408a7b5f06a9..620d29fdace8 100644
    --- a/drivers/of/property.c
    +++ b/drivers/of/property.c
    @@ -1038,33 +1038,9 @@ static bool of_is_ancestor_of(struct device_node *test_ancestor,
    }

    /**
    - * of_get_next_parent_dev - Add device link to supplier from supplier phandle
    - * @np: device tree node
    - *
    - * Given a device tree node (@np), this function finds its closest ancestor
    - * device tree node that has a corresponding struct device.
    - *
    - * The caller of this function is expected to call put_device() on the returned
    - * device when they are done.
    - */
    -static struct device *of_get_next_parent_dev(struct device_node *np)
    -{
    - struct device *dev = NULL;
    -
    - of_node_get(np);
    - do {
    - np = of_get_next_parent(np);
    - if (np)
    - dev = get_dev_from_fwnode(&np->fwnode);
    - } while (np && !dev);
    - of_node_put(np);
    - return dev;
    -}
    -
    -/**
    - * of_link_to_phandle - Add device link to supplier from supplier phandle
    - * @dev: consumer device
    - * @sup_np: phandle to supplier device tree node
    + * 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
    @@ -1074,16 +1050,14 @@ static struct device *of_get_next_parent_dev(struct device_node *np)
    * cases, it returns an error.
    *
    * Returns:
    - * - 0 if link successfully created to supplier
    - * - -EAGAIN if linking to the supplier should be reattempted
    + * - 0 if fwnode link successfully created to supplier
    * - -EINVAL if the supplier link is invalid and should not be created
    - * - -ENODEV if there is no device that corresponds to the supplier phandle
    + * - -ENODEV if struct device will never be create for supplier
    */
    -static int of_link_to_phandle(struct device *dev, struct device_node *sup_np,
    - u32 dl_flags)
    +static int of_link_to_phandle(struct device_node *con_np,
    + struct device_node *sup_np)
    {
    - struct device *sup_dev, *sup_par_dev;
    - int ret = 0;
    + struct device *sup_dev;
    struct device_node *tmp_np = sup_np;

    of_node_get(sup_np);
    @@ -1106,7 +1080,8 @@ static int of_link_to_phandle(struct device *dev, struct device_node *sup_np,
    }

    if (!sup_np) {
    - dev_dbg(dev, "Not linking to %pOFP - No device\n", tmp_np);
    + pr_debug("Not linking %pOFP to %pOFP - No device\n",
    + con_np, tmp_np);
    return -ENODEV;
    }

    @@ -1115,53 +1090,30 @@ static int of_link_to_phandle(struct device *dev, struct device_node *sup_np,
    * descendant nodes. By definition, a child node can't be a functional
    * dependency for the parent node.
    */
    - if (of_is_ancestor_of(dev->of_node, sup_np)) {
    - dev_dbg(dev, "Not linking to %pOFP - is descendant\n", sup_np);
    + 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;
    }
    +
    + /*
    + * 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)) {
    - /* Early device without struct device. */
    - dev_dbg(dev, "Not linking to %pOFP - No struct device\n",
    - sup_np);
    + pr_debug("Not linking %pOFP to %pOFP - No struct device\n",
    + con_np, sup_np);
    of_node_put(sup_np);
    return -ENODEV;
    - } else if (!sup_dev) {
    - /*
    - * DL_FLAG_SYNC_STATE_ONLY doesn't block probing and supports
    - * cycles. So cycle detection isn't necessary and shouldn't be
    - * done.
    - */
    - if (dl_flags & DL_FLAG_SYNC_STATE_ONLY) {
    - of_node_put(sup_np);
    - return -EAGAIN;
    - }
    -
    - sup_par_dev = of_get_next_parent_dev(sup_np);
    -
    - if (sup_par_dev && device_is_dependent(dev, sup_par_dev)) {
    - /* Cyclic dependency detected, don't try to link */
    - dev_dbg(dev, "Not linking to %pOFP - cycle detected\n",
    - sup_np);
    - ret = -EINVAL;
    - } else {
    - /*
    - * Can't check for cycles or no cycles. So let's try
    - * again later.
    - */
    - ret = -EAGAIN;
    - }
    -
    - of_node_put(sup_np);
    - put_device(sup_par_dev);
    - return ret;
    }
    - of_node_put(sup_np);
    - if (!device_link_add(dev, sup_dev, dl_flags))
    - ret = -EINVAL;
    put_device(sup_dev);
    - return ret;
    +
    + fwnode_link_add(of_fwnode_handle(con_np), of_fwnode_handle(sup_np));
    + of_node_put(sup_np);
    +
    + return 0;
    }

    /**
    @@ -1361,37 +1313,29 @@ static const struct supplier_bindings of_supplier_bindings[] = {
    * that list phandles to suppliers. If @prop_name isn't one, this function
    * doesn't do anything.
    *
    - * If @prop_name is one, this function attempts to create device links from the
    - * consumer device @dev to all the devices of the suppliers listed in
    - * @prop_name.
    + * If @prop_name is one, this function attempts to create fwnode links from the
    + * consumer device tree node @con_np to all the suppliers device tree nodes
    + * listed in @prop_name.
    *
    - * Any failed attempt to create a device link will NOT result in an immediate
    + * Any failed attempt to create a fwnode link will NOT result in an immediate
    * return. of_link_property() must create links to all the available supplier
    - * devices even when attempts to create a link to one or more suppliers fail.
    + * device tree nodes even when attempts to create a link to one or more
    + * suppliers fail.
    */
    -static int of_link_property(struct device *dev, struct device_node *con_np,
    - const char *prop_name)
    +static int of_link_property(struct device_node *con_np, const char *prop_name)
    {
    struct device_node *phandle;
    const struct supplier_bindings *s = of_supplier_bindings;
    unsigned int i = 0;
    bool matched = false;
    int ret = 0;
    - u32 dl_flags;
    -
    - if (dev->of_node == con_np)
    - dl_flags = fw_devlink_get_flags();
    - else
    - dl_flags = DL_FLAG_SYNC_STATE_ONLY;

    /* Do not stop at first failed link, link all available suppliers. */
    while (!matched && s->parse_prop) {
    while ((phandle = s->parse_prop(con_np, prop_name, i))) {
    matched = true;
    i++;
    - if (of_link_to_phandle(dev, phandle, dl_flags)
    - == -EAGAIN)
    - ret = -EAGAIN;
    + of_link_to_phandle(con_np, phandle);
    of_node_put(phandle);
    }
    s++;
    @@ -1399,31 +1343,19 @@ static int of_link_property(struct device *dev, struct device_node *con_np,
    return ret;
    }

    -static int of_link_to_suppliers(struct device *dev,
    - struct device_node *con_np)
    +static int of_fwnode_add_links(struct fwnode_handle *fwnode,
    + struct device *dev)
    {
    - struct device_node *child;
    struct property *p;
    - int ret = 0;
    + struct device_node *con_np = to_of_node(fwnode);

    - for_each_property_of_node(con_np, p)
    - if (of_link_property(dev, con_np, p->name))
    - ret = -ENODEV;
    -
    - for_each_available_child_of_node(con_np, child)
    - if (of_link_to_suppliers(dev, child) && !ret)
    - ret = -EAGAIN;
    -
    - return ret;
    -}
    + if (!con_np)
    + return -EINVAL;

    -static int of_fwnode_add_links(const struct fwnode_handle *fwnode,
    - struct device *dev)
    -{
    - if (unlikely(!is_of_node(fwnode)))
    - return 0;
    + for_each_property_of_node(con_np, p)
    + of_link_property(con_np, p->name);

    - return of_link_to_suppliers(dev, to_of_node(fwnode));
    + return 0;
    }

    const struct fwnode_operations of_fwnode_ops = {
    --
    2.29.2.454.gaff20da3a2-goog
    \
     
     \ /
      Last update: 2020-11-21 03:09    [W:4.201 / U:0.160 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site