From: Saravana Kannan <saravanak@google.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
"Rafael J. Wysocki" <rafael@kernel.org>,
Sudeep Holla <sudeep.holla@arm.com>,
Cristian Marussi <cristian.marussi@arm.com>,
Linus Walleij <linus.walleij@linaro.org>,
Bartosz Golaszewski <brgl@bgdev.pl>,
Thomas Gleixner <tglx@linutronix.de>,
Marc Zyngier <maz@kernel.org>, Shawn Guo <shawnguo@kernel.org>,
Sascha Hauer <s.hauer@pengutronix.de>,
Pengutronix Kernel Team <kernel@pengutronix.de>,
Fabio Estevam <festevam@gmail.com>,
NXP Linux Team <linux-imx@nxp.com>,
Rob Herring <robh+dt@kernel.org>,
Frank Rowand <frowand.list@gmail.com>,
Geert Uytterhoeven <geert+renesas@glider.be>,
Magnus Damm <magnus.damm@gmail.com>, Len Brown <lenb@kernel.org>,
Andy Shevchenko <andriy.shevchenko@linux.intel.com>,
Daniel Scally <djrscally@gmail.com>,
Heikki Krogerus <heikki.krogerus@linux.intel.com>,
Sakari Ailus <sakari.ailus@linux.intel.com>,
Saravana Kannan <saravanak@google.com>
Cc: Tony Lindgren <tony@atomide.com>,
Linux Kernel Functional Testing <lkft@linaro.org>,
Naresh Kamboju <naresh.kamboju@linaro.org>,
Abel Vesa <abel.vesa@linaro.org>,
Alexander Stein <alexander.stein@ew.tq-group.com>,
Geert Uytterhoeven <geert@linux-m68k.org>,
John Stultz <jstultz@google.com>,
Doug Anderson <dianders@chromium.org>,
Guenter Roeck <linux@roeck-us.net>,
Dmitry Baryshkov <dmitry.baryshkov@linaro.org>,
Maxim Kiselev <bigunclemax@gmail.com>,
Maxim Kochetkov <fido_max@inbox.ru>,
Miquel Raynal <miquel.raynal@bootlin.com>,
Luca Weiss <luca.weiss@fairphone.com>,
Colin Foster <colin.foster@in-advantage.com>,
Martin Kepplinger <martin.kepplinger@puri.sm>,
Jean-Philippe Brucker <jpb@kernel.org>,
kernel-team@android.com, linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, linux-gpio@vger.kernel.org,
devicetree@vger.kernel.org, linux-renesas-soc@vger.kernel.org,
linux-acpi@vger.kernel.org
Subject: [PATCH v2 01/11] driver core: fw_devlink: Don't purge child fwnode's consumer links
Date: Thu, 26 Jan 2023 16:11:28 -0800 [thread overview]
Message-ID: <20230127001141.407071-2-saravanak@google.com> (raw)
In-Reply-To: <20230127001141.407071-1-saravanak@google.com>
When a device X is bound successfully to a driver, if it has a child
firmware node Y that doesn't have a struct device created by then, we
delete fwnode links where the child firmware node Y is the supplier. We
did this to avoid blocking the consumers of the child firmware node Y
from deferring probe indefinitely.
While that a step in the right direction, it's better to make the
consumers of the child firmware node Y to be consumers of the device X
because device X is probably implementing whatever functionality is
represented by child firmware node Y. By doing this, we capture the
device dependencies more accurately and ensure better
probe/suspend/resume ordering.
Signed-off-by: Saravana Kannan <saravanak@google.com>
---
drivers/base/core.c | 97 ++++++++++++++++++++++++++++++++++++---------
1 file changed, 79 insertions(+), 18 deletions(-)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index a3e14143ec0c..b6d98cc82f26 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -54,11 +54,12 @@ static LIST_HEAD(deferred_sync);
static unsigned int defer_sync_state_count = 1;
static DEFINE_MUTEX(fwnode_link_lock);
static bool fw_devlink_is_permissive(void);
+static void __fw_devlink_link_to_consumers(struct device *dev);
static bool fw_devlink_drv_reg_done;
static bool fw_devlink_best_effort;
/**
- * fwnode_link_add - Create a link between two fwnode_handles.
+ * __fwnode_link_add - Create a link between two fwnode_handles.
* @con: Consumer end of the link.
* @sup: Supplier end of the link.
*
@@ -74,22 +75,18 @@ static bool fw_devlink_best_effort;
* Attempts to create duplicate links between the same pair of fwnode handles
* are ignored and there is no reference counting.
*/
-int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup)
+static int __fwnode_link_add(struct fwnode_handle *con,
+ struct fwnode_handle *sup)
{
struct fwnode_link *link;
- int ret = 0;
-
- mutex_lock(&fwnode_link_lock);
list_for_each_entry(link, &sup->consumers, s_hook)
if (link->consumer == con)
- goto out;
+ return 0;
link = kzalloc(sizeof(*link), GFP_KERNEL);
- if (!link) {
- ret = -ENOMEM;
- goto out;
- }
+ if (!link)
+ return -ENOMEM;
link->supplier = sup;
INIT_LIST_HEAD(&link->s_hook);
@@ -100,9 +97,17 @@ int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup)
list_add(&link->c_hook, &con->suppliers);
pr_debug("%pfwP Linked as a fwnode consumer to %pfwP\n",
con, sup);
-out:
- mutex_unlock(&fwnode_link_lock);
+ return 0;
+}
+
+int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup)
+{
+ int ret = 0;
+
+ mutex_lock(&fwnode_link_lock);
+ ret = __fwnode_link_add(con, sup);
+ mutex_unlock(&fwnode_link_lock);
return ret;
}
@@ -181,6 +186,51 @@ void fw_devlink_purge_absent_suppliers(struct fwnode_handle *fwnode)
}
EXPORT_SYMBOL_GPL(fw_devlink_purge_absent_suppliers);
+/**
+ * __fwnode_links_move_consumers - Move consumer from @from to @to fwnode_handle
+ * @from: move consumers away from this fwnode
+ * @to: move consumers to this fwnode
+ *
+ * Move all consumer links from @from fwnode to @to fwnode.
+ */
+static void __fwnode_links_move_consumers(struct fwnode_handle *from,
+ struct fwnode_handle *to)
+{
+ struct fwnode_link *link, *tmp;
+
+ list_for_each_entry_safe(link, tmp, &from->consumers, s_hook) {
+ __fwnode_link_add(link->consumer, to);
+ __fwnode_link_del(link);
+ }
+}
+
+/**
+ * __fw_devlink_pickup_dangling_consumers - Pick up dangling consumers
+ * @fwnode: fwnode from which to pick up dangling consumers
+ * @new_sup: fwnode of new supplier
+ *
+ * If the @fwnode has a corresponding struct device and the device supports
+ * probing (that is, added to a bus), then we want to let fw_devlink create
+ * MANAGED device links to this device, so leave @fwnode and its descendant's
+ * fwnode links alone.
+ *
+ * Otherwise, move its consumers to the new supplier @new_sup.
+ */
+static void __fw_devlink_pickup_dangling_consumers(struct fwnode_handle *fwnode,
+ struct fwnode_handle *new_sup)
+{
+ struct fwnode_handle *child;
+
+ if (fwnode->dev && fwnode->dev->bus)
+ return;
+
+ fwnode->flags |= FWNODE_FLAG_NOT_DEVICE;
+ __fwnode_links_move_consumers(fwnode, new_sup);
+
+ fwnode_for_each_available_child_node(fwnode, child)
+ __fw_devlink_pickup_dangling_consumers(child, new_sup);
+}
+
#ifdef CONFIG_SRCU
static DEFINE_MUTEX(device_links_lock);
DEFINE_STATIC_SRCU(device_links_srcu);
@@ -1267,16 +1317,23 @@ void device_links_driver_bound(struct device *dev)
* them. So, fw_devlink no longer needs to create device links to any
* of the device's suppliers.
*
- * Also, if a child firmware node of this bound device is not added as
- * a device by now, assume it is never going to be added and make sure
- * other devices don't defer probe indefinitely by waiting for such a
- * child device.
+ * Also, if a child firmware node of this bound device is not added as a
+ * device by now, assume it is never going to be added. Make this bound
+ * device the fallback supplier to the dangling consumers of the child
+ * firmware node because this bound device is probably implementing the
+ * child firmware node functionality and we don't want the dangling
+ * consumers to defer probe indefinitely waiting for a device for the
+ * child firmware node.
*/
if (dev->fwnode && dev->fwnode->dev == dev) {
struct fwnode_handle *child;
fwnode_links_purge_suppliers(dev->fwnode);
+ mutex_lock(&fwnode_link_lock);
fwnode_for_each_available_child_node(dev->fwnode, child)
- fw_devlink_purge_absent_suppliers(child);
+ __fw_devlink_pickup_dangling_consumers(child,
+ dev->fwnode);
+ __fw_devlink_link_to_consumers(dev);
+ mutex_unlock(&fwnode_link_lock);
}
device_remove_file(dev, &dev_attr_waiting_for_supplier);
@@ -1855,7 +1912,11 @@ static int fw_devlink_create_devlink(struct device *con,
fwnode_is_ancestor_of(sup_handle, con->fwnode))
return -EINVAL;
- sup_dev = get_dev_from_fwnode(sup_handle);
+ if (sup_handle->flags & FWNODE_FLAG_NOT_DEVICE)
+ sup_dev = fwnode_get_next_parent_dev(sup_handle);
+ else
+ sup_dev = get_dev_from_fwnode(sup_handle);
+
if (sup_dev) {
/*
* If it's one of those drivers that don't actually bind to
--
2.39.1.456.gfc5497dd1b-goog
next prev parent reply other threads:[~2023-01-27 0:12 UTC|newest]
Thread overview: 73+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-27 0:11 [PATCH v2 00/11] fw_devlink improvements Saravana Kannan
2023-01-27 0:11 ` Saravana Kannan [this message]
2023-01-27 9:21 ` [PATCH v2 01/11] driver core: fw_devlink: Don't purge child fwnode's consumer links Andy Shevchenko
2023-01-28 7:33 ` Saravana Kannan
2023-01-30 12:04 ` Andy Shevchenko
2023-01-27 0:11 ` [PATCH v2 02/11] driver core: fw_devlink: Improve check for fwnode with no device/driver Saravana Kannan
2023-01-27 0:11 ` [PATCH v2 03/11] soc: renesas: Move away from using OF_POPULATED for fw_devlink Saravana Kannan
2023-01-27 8:11 ` Geert Uytterhoeven
2023-01-28 7:18 ` Saravana Kannan
2023-01-30 8:42 ` Geert Uytterhoeven
2023-01-30 20:00 ` Saravana Kannan
2023-01-31 8:14 ` Geert Uytterhoeven
2023-02-04 22:30 ` Saravana Kannan
2023-01-27 9:25 ` Andy Shevchenko
2023-01-27 9:30 ` Geert Uytterhoeven
2023-01-27 9:44 ` Andy Shevchenko
2023-01-27 0:11 ` [PATCH v2 04/11] gpiolib: Clear the gpio_device's fwnode initialized flag before adding Saravana Kannan
2023-01-27 9:27 ` Andy Shevchenko
2023-01-28 7:33 ` Saravana Kannan
2023-01-30 12:05 ` Andy Shevchenko
2023-01-30 14:31 ` Sudeep Holla
2023-01-30 15:14 ` Andy Shevchenko
2023-01-31 4:01 ` Saravana Kannan
2023-01-31 10:13 ` Sudeep Holla
2023-02-04 22:32 ` Saravana Kannan
2023-01-27 0:11 ` [PATCH v2 05/11] driver core: fw_devlink: Add DL_FLAG_CYCLE support to device links Saravana Kannan
2023-01-27 9:29 ` Andy Shevchenko
2023-01-27 9:30 ` Andy Shevchenko
2023-01-27 9:55 ` Geert Uytterhoeven
2023-01-28 7:34 ` Saravana Kannan
2023-01-30 12:08 ` Andy Shevchenko
2023-01-27 0:11 ` [PATCH v2 06/11] driver core: fw_devlink: Allow marking a fwnode link as being part of a cycle Saravana Kannan
2023-01-27 9:33 ` Andy Shevchenko
2023-01-28 7:34 ` Saravana Kannan
2023-01-30 12:09 ` Andy Shevchenko
2023-01-27 0:11 ` [PATCH v2 07/11] driver core: fw_devlink: Consolidate device link flag computation Saravana Kannan
2023-01-27 0:11 ` [PATCH v2 08/11] driver core: fw_devlink: Make cycle detection more robust Saravana Kannan
2023-01-27 9:43 ` Andy Shevchenko
2023-01-27 9:52 ` Geert Uytterhoeven
2023-01-27 10:10 ` Andy Shevchenko
2023-01-27 10:29 ` Geert Uytterhoeven
2023-01-28 7:34 ` Saravana Kannan
2023-01-30 12:15 ` Andy Shevchenko
2023-01-30 14:36 ` Geert Uytterhoeven
2023-01-30 15:16 ` Andy Shevchenko
2023-01-27 0:11 ` [PATCH v2 09/11] of: property: Simplify of_link_to_phandle() Saravana Kannan
2023-01-30 14:39 ` Sakari Ailus
2023-01-31 3:51 ` Saravana Kannan
2023-01-27 0:11 ` [PATCH v2 10/11] irqchip/irq-imx-gpcv2: Mark fwnode device as not initialized Saravana Kannan
2023-01-27 9:51 ` Andy Shevchenko
2023-01-28 7:34 ` Saravana Kannan
2023-01-27 0:11 ` [PATCH v2 11/11] firmware: arm_scmi: Set fwnode for the scmi_device Saravana Kannan
2023-01-27 9:52 ` Andy Shevchenko
2023-01-27 10:48 ` Sudeep Holla
2023-01-27 20:30 ` [PATCH v2 00/11] fw_devlink improvements Colin Foster
2023-01-27 21:35 ` Saravana Kannan
2023-01-30 8:55 ` Naresh Kamboju
2023-01-30 10:49 ` Marc Zyngier
2023-01-30 23:03 ` Saravana Kannan
2023-01-31 10:18 ` Sudeep Holla
2023-02-02 17:36 ` Maxim Kiselev
2023-02-03 6:07 ` Saravana Kannan
2023-02-03 9:39 ` Maxim Kiselev
2023-02-06 1:32 ` Saravana Kannan
2023-02-06 2:17 ` Saravana Kannan
2023-02-06 9:39 ` Miquel Raynal
2023-02-06 20:08 ` Saravana Kannan
2023-02-24 14:46 ` Miquel Raynal
2023-02-06 15:18 ` Rob Herring
2023-02-06 19:59 ` Saravana Kannan
2023-01-30 10:48 ` Miquel Raynal
2023-01-30 12:08 ` Maxim Kiselev
2023-01-31 1:20 ` Saravana Kannan
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=20230127001141.407071-2-saravanak@google.com \
--to=saravanak@google.com \
--cc=abel.vesa@linaro.org \
--cc=alexander.stein@ew.tq-group.com \
--cc=andriy.shevchenko@linux.intel.com \
--cc=bigunclemax@gmail.com \
--cc=brgl@bgdev.pl \
--cc=colin.foster@in-advantage.com \
--cc=cristian.marussi@arm.com \
--cc=devicetree@vger.kernel.org \
--cc=dianders@chromium.org \
--cc=djrscally@gmail.com \
--cc=dmitry.baryshkov@linaro.org \
--cc=festevam@gmail.com \
--cc=fido_max@inbox.ru \
--cc=frowand.list@gmail.com \
--cc=geert+renesas@glider.be \
--cc=geert@linux-m68k.org \
--cc=gregkh@linuxfoundation.org \
--cc=heikki.krogerus@linux.intel.com \
--cc=jpb@kernel.org \
--cc=jstultz@google.com \
--cc=kernel-team@android.com \
--cc=kernel@pengutronix.de \
--cc=lenb@kernel.org \
--cc=linus.walleij@linaro.org \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-imx@nxp.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-renesas-soc@vger.kernel.org \
--cc=linux@roeck-us.net \
--cc=lkft@linaro.org \
--cc=luca.weiss@fairphone.com \
--cc=magnus.damm@gmail.com \
--cc=martin.kepplinger@puri.sm \
--cc=maz@kernel.org \
--cc=miquel.raynal@bootlin.com \
--cc=naresh.kamboju@linaro.org \
--cc=rafael@kernel.org \
--cc=robh+dt@kernel.org \
--cc=s.hauer@pengutronix.de \
--cc=sakari.ailus@linux.intel.com \
--cc=shawnguo@kernel.org \
--cc=sudeep.holla@arm.com \
--cc=tglx@linutronix.de \
--cc=tony@atomide.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