summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/base/core.c12
-rw-r--r--include/linux/fwnode.h13
2 files changed, 17 insertions, 8 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 48cd43a91ce6..e6d3e6d485da 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -2297,7 +2297,7 @@ int device_add(struct device *dev)
struct device *parent;
struct kobject *kobj;
struct class_interface *class_intf;
- int error = -EINVAL;
+ int error = -EINVAL, fw_ret;
struct kobject *glue_dir = NULL;
dev = get_device(dev);
@@ -2413,9 +2413,13 @@ int device_add(struct device *dev)
*/
device_link_add_missing_supplier_links();
- if (fwnode_has_op(dev->fwnode, add_links)
- && fwnode_call_int_op(dev->fwnode, add_links, dev))
- device_link_wait_for_mandatory_supplier(dev, true);
+ 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);
+ }
bus_probe_device(dev);
if (parent)
diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h
index 97223e2410bd..766ff9bb5876 100644
--- a/include/linux/fwnode.h
+++ b/include/linux/fwnode.h
@@ -94,10 +94,15 @@ struct fwnode_reference_args {
* available suppliers.
*
* Return 0 if device links have been successfully created to all
- * the suppliers of this device or if the supplier information is
- * not known. Return an error if and only if the supplier
- * information is known but some of the suppliers are not yet
- * available to create device links to.
+ * the suppliers this device needs to create device links to or if
+ * the supplier information is not known.
+ *
+ * Return -ENODEV if and only if the suppliers needed for probing
+ * the device are not yet available to create device links to.
+ *
+ * Return -EAGAIN if there are suppliers that need to be linked to
+ * that are not yet available but none of those suppliers are
+ * necessary for probing this device.
*/
struct fwnode_operations {
struct fwnode_handle *(*get)(struct fwnode_handle *fwnode);