Skip to content

Commit 4dbe191

Browse files
Saravana Kannangregkh
authored andcommitted
driver core: Add device links from fwnode only for the primary device
Sometimes, more than one (generally two) device can point to the same fwnode. However, only one device is set as the fwnode's device (fwnode->dev) and can be looked up from the fwnode. Typically, only one of these devices actually have a driver and actually probe. If we create device links for all these devices, then the suppliers' of these devices (with the same fwnode) will never get a sync_state() call because one of their consumer devices will never probe (because they don't have a driver). So, create device links only for the device that is considered as the fwnode's device. One such example of this is the PCI bridge platform_device and the corresponding pci_bus device. Both these devices will have the same fwnode. It's the platform_device that is registered first and is set as the fwnode's device. Also the platform_device is the one that actually probes. Without this patch none of the suppliers of a PCI bridge platform_device would get a sync_state() callback. Cc: Bjorn Helgaas <[email protected]> Cc: [email protected] Reviewed-by: Rafael J. Wysocki <[email protected]> Signed-off-by: Saravana Kannan <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent b94b807 commit 4dbe191

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

drivers/base/core.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2404,6 +2404,7 @@ int device_add(struct device *dev)
24042404
struct class_interface *class_intf;
24052405
int error = -EINVAL, fw_ret;
24062406
struct kobject *glue_dir = NULL;
2407+
bool is_fwnode_dev = false;
24072408

24082409
dev = get_device(dev);
24092410
if (!dev)
@@ -2501,8 +2502,10 @@ int device_add(struct device *dev)
25012502

25022503
kobject_uevent(&dev->kobj, KOBJ_ADD);
25032504

2504-
if (dev->fwnode && !dev->fwnode->dev)
2505+
if (dev->fwnode && !dev->fwnode->dev) {
25052506
dev->fwnode->dev = dev;
2507+
is_fwnode_dev = true;
2508+
}
25062509

25072510
/*
25082511
* Check if any of the other devices (consumers) have been waiting for
@@ -2518,7 +2521,8 @@ int device_add(struct device *dev)
25182521
*/
25192522
device_link_add_missing_supplier_links();
25202523

2521-
if (fw_devlink_flags && fwnode_has_op(dev->fwnode, add_links)) {
2524+
if (fw_devlink_flags && is_fwnode_dev &&
2525+
fwnode_has_op(dev->fwnode, add_links)) {
25222526
fw_ret = fwnode_call_int_op(dev->fwnode, add_links, dev);
25232527
if (fw_ret == -ENODEV)
25242528
device_link_wait_for_mandatory_supplier(dev);

0 commit comments

Comments
 (0)