From 80f21b25abd038b688df045fefb792731666276d Mon Sep 17 00:00:00 2001 From: Saravana Kannan Date: Thu, 14 May 2020 22:34:58 -0700 Subject: [PATCH] BACKPORT: driver core: Look for waiting consumers only for a fwnode's primary device Commit 4dbe191c046e ("driver core: Add device links from fwnode only for the primary device") skipped linking a fwnode's secondary device to the suppliers listed in its fwnode. However, a fwnode's secondary device can't be found using get_dev_from_fwnode(). So, there's no point in trying to see if devices waiting for suppliers might want to link to a fwnode's secondary device. This commit removes that unnecessary step for devices that aren't a fwnode's primary device and also moves the code to a more appropriate part of the file. Signed-off-by: Saravana Kannan Link: https://lore.kernel.org/r/20200515053500.215929-3-saravanak@google.com Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 5f5377eaddfc24e5d7562e588d0ff84f9264d7c1) [conflict fixes due to of_devlink rename to fw_devlink] Bug: 157691602 Signed-off-by: Saravana Kannan Change-Id: Id0455f6bc05d89b0f81d1574a242be6b8ff67975 --- drivers/base/core.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index dc1a12b4bcdb..ae794271735b 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1165,6 +1165,21 @@ static void device_links_purge(struct device *dev) device_links_write_unlock(); } +static void fw_devlink_link_device(struct device *dev) +{ + int fw_ret; + + device_link_add_missing_supplier_links(); + + if (fwnode_has_op(dev->fwnode, add_links)) { + fw_ret = fwnode_call_int_op(dev->fwnode, add_links, dev); + if (fw_ret == -ENODEV) + device_link_wait_for_mandatory_supplier(dev); + else if (fw_ret) + device_link_wait_for_optional_supplier(dev); + } +} + /* Device links support end. */ int (*platform_notify)(struct device *dev) = NULL; @@ -2365,7 +2380,7 @@ int device_add(struct device *dev) struct device *parent; struct kobject *kobj; struct class_interface *class_intf; - int error = -EINVAL, fw_ret; + int error = -EINVAL; struct kobject *glue_dir = NULL; bool is_fwnode_dev = false; @@ -2481,15 +2496,8 @@ int device_add(struct device *dev) * waiting consumers can link to it before the driver is bound to the * device and the driver sync_state callback is called for this device. */ - device_link_add_missing_supplier_links(); - - if (is_fwnode_dev && fwnode_has_op(dev->fwnode, add_links)) { - fw_ret = fwnode_call_int_op(dev->fwnode, add_links, dev); - if (fw_ret == -ENODEV) - device_link_wait_for_mandatory_supplier(dev); - else if (fw_ret) - device_link_wait_for_optional_supplier(dev); - } + if (is_fwnode_dev) + fw_devlink_link_device(dev); bus_probe_device(dev); if (parent)