On Mon, Nov 16, 2020 at 8:57 AM Rafael J. Wysocki <rafael@xxxxxxxxxx> wrote: > > On Thu, Nov 5, 2020 at 12:24 AM Saravana Kannan <saravanak@xxxxxxxxxx> wrote: > > > > Add helper functions __fw_devlink_link_to_consumers() and > > __fw_devlink_link_to_suppliers() that convert fwnode links to device > > links. > > > > __fw_devlink_link_to_consumers() is for creating: > > - Device links between a newly added device and all its consumer devices > > that have been added to driver core. > > - Proxy SYNC_STATE_ONLY device links between the newly added device and > > the parent devices of all its consumers that have not been added to > > driver core yet. > > > > __fw_devlink_link_to_suppliers() is for creating: > > - Device links between a newly added device and all its supplier devices > > - Proxy SYNC_STATE_ONLY device links between the newly added device and > > all the supplier devices of its child device nodes. > > > > Signed-off-by: Saravana Kannan <saravanak@xxxxxxxxxx> > > --- > > drivers/base/core.c | 228 ++++++++++++++++++++++++++++++++++++++++++++ > > 1 file changed, 228 insertions(+) > > > > diff --git a/drivers/base/core.c b/drivers/base/core.c > > index d51dd564add1..0c87ff949d81 100644 > > --- a/drivers/base/core.c > > +++ b/drivers/base/core.c > > @@ -1585,6 +1585,234 @@ static struct device *fwnode_get_next_parent_dev(struct fwnode_handle *fwnode) > > return dev; > > } > > > > +/** > > + * fw_devlink_create_devlink - Create a device link from a consumer to fwnode > > Have you considered renaming "fw_devlink" to "fwnode_link"? I avoided using fwnode_link prefix because it's not related to the fwnode link APIs. This is a fw_devlink feature related code and hence the fw_devlink prefix. I could just call it fw_devlink_create() or fw_devlink_create_links() or fwnode_to_dev_link() if that's less confusing. Any preferences? > That would be much less confusing IMO and the name of this function > would be clearer. > > > + * @con - Consumer device for the device link > > + * @sup - fwnode handle of supplier > > + * > > + * This function will try to create a device link between the consumer and the > > + * supplier devices. > > "... between consumer device @con and the supplier device represented > by @sup" (and see below). > > > + * > > + * The supplier has to be provided as a fwnode because incorrect cycles in > > + * fwnode links can sometimes cause the supplier device to never be created. > > + * This function detects such cases and returns an error if a device link being > > + * created in invalid. > > "... returns an error if it cannot create a device link from the > consumer to a missing supplier." > > > + * > > + * Returns, > > + * 0 on successfully creating a device link > > + * -EINVAL if the device link being attempted is invalid > > "if the device link cannot be created as expected" > > > + * -EAGAIN if the device link needs to be attempted again in the future > > "if the device link cannot be created right now, but it may be > possible to do that in the future." Ack to all the documentation comments above. > > > + */ > > +static int fw_devlink_create_devlink(struct device *con, > > + struct fwnode_handle *sup, u32 flags) > > I'd call the second arg sup_handle to indicate that it is not a struct device. Ack > > > +{ > > + struct device *sup_dev, *sup_par_dev; > > + int ret = 0; > > + > > + sup_dev = get_dev_from_fwnode(sup); > > + /* > > + * If we can't find the supplier device from its fwnode, it might be > > + * due to a cyclic dependcy between fwnodes. Some of these cycles can > > dependency > Ack > > + * be broken by applying logic. Check for these types of cycles and > > + * break them so that devices in the cycle probe properly. > > + */ > > I would do > > if (sup_dev) { > if (!device_link_add(con, sup_dev, flags)) > ret = -EINVAL; > > put_device(sup_dev); > return ret; > } > > here and the cycle detection (error code path) below, possibly using > the same dev pointer. Nice suggestion, thanks! -Saravana