On Thu, Jan 26, 2023 at 04:11:28PM -0800, Saravana Kannan wrote: > 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. ... > 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; I'm wondering if may avoid adding more forward declarations... Perhaps it's a sign that devlink code should be split to its own module? ... > -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) I believe we tolerate a bit longer lines, so you may still have it on a single line. ... > +int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup) > +{ > + int ret = 0; Redundant assignment. > + mutex_lock(&fwnode_link_lock); > + ret = __fwnode_link_add(con, sup); > + mutex_unlock(&fwnode_link_lock); > return ret; > } ... > if (dev->fwnode && dev->fwnode->dev == dev) { You may have above something like fwnode = dev_fwnode(dev); if (fwnode && 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_pickup_dangling_consumers(child, fwnode); > + __fw_devlink_link_to_consumers(dev); > + mutex_unlock(&fwnode_link_lock); > } -- With Best Regards, Andy Shevchenko