From: Saravana Kannan <saravanak@google.com>
To: "Rafael J. Wysocki" <rjw@rjwysocki.net>,
"Rafael J. Wysocki" <rafael@kernel.org>,
Len Brown <lenb@kernel.org>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
Ard Biesheuvel <ardb@kernel.org>,
Rob Herring <robh+dt@kernel.org>,
Frank Rowand <frowand.list@gmail.com>,
Marc Zyngier <maz@kernel.org>,
Thomas Gleixner <tglx@linutronix.de>
Cc: Saravana Kannan <saravanak@google.com>,
Tomi Valkeinen <tomi.valkeinen@ti.com>,
Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
Grygorii Strashko <grygorii.strashko@ti.com>,
kernel-team@android.com, linux-acpi@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-efi@vger.kernel.org,
devicetree@vger.kernel.org
Subject: [PATCH v1 15/18] of: property: Update implementation of add_links() to create fwnode links
Date: Wed, 4 Nov 2020 15:23:52 -0800 [thread overview]
Message-ID: <20201104232356.4038506-16-saravanak@google.com> (raw)
In-Reply-To: <20201104232356.4038506-1-saravanak@google.com>
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..86303803f1b3 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 (unlikely(!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.1.341.ge80a0c044ae-goog
next prev parent reply other threads:[~2020-11-04 23:25 UTC|newest]
Thread overview: 55+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-11-04 23:23 [PATCH v1 00/18] Refactor fw_devlink to significantly improve boot time Saravana Kannan
2020-11-04 23:23 ` [PATCH v1 01/18] Revert "driver core: Avoid deferred probe due to fw_devlink_pause/resume()" Saravana Kannan
2020-11-05 9:34 ` Greg Kroah-Hartman
2020-11-05 23:19 ` Saravana Kannan
2020-11-04 23:23 ` [PATCH v1 02/18] Revert "driver core: Rename dev_links_info.defer_sync to defer_hook" Saravana Kannan
2020-11-04 23:23 ` [PATCH v1 03/18] Revert "driver core: Don't do deferred probe in parallel with kernel_init thread" Saravana Kannan
2020-11-04 23:23 ` [PATCH v1 04/18] Revert "driver core: Remove check in driver_deferred_probe_force_trigger()" Saravana Kannan
2020-11-04 23:23 ` [PATCH v1 05/18] Revert "of: platform: Batch fwnode parsing when adding all top level devices" Saravana Kannan
2020-11-04 23:23 ` [PATCH v1 06/18] Revert "driver core: fw_devlink: Add support for batching fwnode parsing" Saravana Kannan
2020-11-04 23:23 ` [PATCH v1 07/18] driver core: Add fwnode_init() Saravana Kannan
2020-11-05 9:36 ` Greg Kroah-Hartman
2020-11-05 23:20 ` Saravana Kannan
2020-11-04 23:23 ` [PATCH v1 08/18] driver core: Add fwnode link support Saravana Kannan
2020-11-16 15:51 ` Rafael J. Wysocki
2020-11-21 1:59 ` Saravana Kannan
2020-11-04 23:23 ` [PATCH v1 09/18] driver core: Allow only unprobed consumers for SYNC_STATE_ONLY device links Saravana Kannan
2020-11-16 15:57 ` Rafael J. Wysocki
2020-11-21 1:59 ` Saravana Kannan
2020-11-04 23:23 ` [PATCH v1 10/18] device property: Add fwnode_is_ancestor_of() Saravana Kannan
2020-11-04 23:23 ` [PATCH v1 11/18] driver core: Redefine the meaning of fwnode_operations.add_links() Saravana Kannan
2020-11-16 16:16 ` Rafael J. Wysocki
2020-11-21 1:59 ` Saravana Kannan
2020-11-04 23:23 ` [PATCH v1 12/18] driver core: Add fw_devlink_parse_fwtree() Saravana Kannan
2020-11-16 16:25 ` Rafael J. Wysocki
2020-11-21 2:00 ` Saravana Kannan
2020-11-04 23:23 ` [PATCH v1 13/18] driver core: Add fwnode_get_next_parent_dev() helper function Saravana Kannan
2020-11-16 16:27 ` Rafael J. Wysocki
2020-11-21 2:00 ` Saravana Kannan
2020-11-04 23:23 ` [PATCH v1 14/18] driver core: Use device's fwnode to check if it is waiting for suppliers Saravana Kannan
2020-11-16 16:34 ` Rafael J. Wysocki
2020-11-21 2:00 ` Saravana Kannan
2020-11-04 23:23 ` Saravana Kannan [this message]
2020-11-05 9:42 ` [PATCH v1 15/18] of: property: Update implementation of add_links() to create fwnode links Greg Kroah-Hartman
2020-11-05 23:25 ` Saravana Kannan
2020-11-06 1:24 ` Saravana Kannan
2020-11-06 7:22 ` Greg Kroah-Hartman
2020-11-06 7:41 ` Saravana Kannan
2020-11-06 7:51 ` Greg Kroah-Hartman
2020-11-06 8:29 ` Saravana Kannan
2020-11-04 23:23 ` [PATCH v1 16/18] efi: " Saravana Kannan
2020-11-05 9:43 ` Greg Kroah-Hartman
2020-11-05 23:27 ` Saravana Kannan
2020-11-06 6:45 ` Greg Kroah-Hartman
2020-11-04 23:23 ` [PATCH v1 17/18] driver core: Add helper functions to convert fwnode links to device links Saravana Kannan
2020-11-05 9:43 ` Greg Kroah-Hartman
2020-11-05 23:32 ` Saravana Kannan
2020-11-06 7:24 ` Greg Kroah-Hartman
2020-11-06 7:43 ` Saravana Kannan
2020-11-16 16:57 ` Rafael J. Wysocki
2020-11-21 2:00 ` Saravana Kannan
2020-11-04 23:23 ` [PATCH v1 18/18] driver core: Refactor fw_devlink feature Saravana Kannan
2020-11-04 23:26 ` [PATCH v1 00/18] Refactor fw_devlink to significantly improve boot time Saravana Kannan
2020-11-06 5:09 ` Laurent Pinchart
2020-11-06 8:36 ` Saravana Kannan
2020-11-06 12:46 ` Grygorii Strashko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20201104232356.4038506-16-saravanak@google.com \
--to=saravanak@google.com \
--cc=ardb@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=frowand.list@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=grygorii.strashko@ti.com \
--cc=kernel-team@android.com \
--cc=laurent.pinchart@ideasonboard.com \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-efi@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maz@kernel.org \
--cc=rafael@kernel.org \
--cc=rjw@rjwysocki.net \
--cc=robh+dt@kernel.org \
--cc=tglx@linutronix.de \
--cc=tomi.valkeinen@ti.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).