Re: [PATCH v2 01/11] driver core: fw_devlink: Don't purge child fwnode's consumer links

Andy Shevchenko
2023-01-27T09:24:34Z

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