Commit cd115c04 authored by Saravana Kannan's avatar Saravana Kannan Committed by Greg Kroah-Hartman
Browse files

driver core: fw_devlink: Consolidate device link flag computation



Consolidate the code that computes the flags to be used when creating a
device link from a fwnode link.

Fixes: 2de9d8e0 ("driver core: fw_devlink: Improve handling of cyclic dependencies")
Signed-off-by: default avatarSaravana Kannan <saravanak@google.com>
Tested-by: default avatarColin Foster <colin.foster@in-advantage.com>
Tested-by: default avatarSudeep Holla <sudeep.holla@arm.com>
Tested-by: default avatarDouglas Anderson <dianders@chromium.org>
Tested-by: default avatarGeert Uytterhoeven <geert+renesas@glider.be>
Tested-by: Luca Weiss <luca.weiss@fairphone.com> # qcom/sm7225-fairphone-fp4
Link: https://lore.kernel.org/r/20230207014207.1678715-8-saravanak@google.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 6a6dfdf8
Loading
Loading
Loading
Loading
+15 −13
Original line number Diff line number Diff line
@@ -1727,8 +1727,11 @@ static int __init fw_devlink_strict_setup(char *arg)
}
early_param("fw_devlink.strict", fw_devlink_strict_setup);

u32 fw_devlink_get_flags(void)
static inline u32 fw_devlink_get_flags(u8 fwlink_flags)
{
	if (fwlink_flags & FWLINK_FLAG_CYCLE)
		return FW_DEVLINK_FLAGS_PERMISSIVE | DL_FLAG_CYCLE;

	return fw_devlink_flags;
}

@@ -1938,7 +1941,7 @@ static bool fwnode_ancestor_init_without_drv(struct fwnode_handle *fwnode)
 * fw_devlink_create_devlink - Create a device link from a consumer to fwnode
 * @con: consumer device for the device link
 * @sup_handle: fwnode handle of supplier
 * @flags: devlink flags
 * @link: fwnode link that's being converted to a device link
 *
 * This function will try to create a device link between the consumer device
 * @con and the supplier device represented by @sup_handle.
@@ -1955,10 +1958,17 @@ static bool fwnode_ancestor_init_without_drv(struct fwnode_handle *fwnode)
 *  possible to do that in the future
 */
static int fw_devlink_create_devlink(struct device *con,
				     struct fwnode_handle *sup_handle, u32 flags)
				     struct fwnode_handle *sup_handle,
				     struct fwnode_link *link)
{
	struct device *sup_dev;
	int ret = 0;
	u32 flags;

	if (con->fwnode == link->consumer)
		flags = fw_devlink_get_flags(link->flags);
	else
		flags = FW_DEVLINK_FLAGS_PERMISSIVE;

	/*
	 * In some cases, a device P might also be a supplier to its child node
@@ -2091,7 +2101,6 @@ static void __fw_devlink_link_to_consumers(struct device *dev)
	struct fwnode_link *link, *tmp;

	list_for_each_entry_safe(link, tmp, &fwnode->consumers, s_hook) {
		u32 dl_flags = fw_devlink_get_flags();
		struct device *con_dev;
		bool own_link = true;
		int ret;
@@ -2121,14 +2130,13 @@ static void __fw_devlink_link_to_consumers(struct device *dev)
				con_dev = NULL;
			} else {
				own_link = false;
				dl_flags = FW_DEVLINK_FLAGS_PERMISSIVE;
			}
		}

		if (!con_dev)
			continue;

		ret = fw_devlink_create_devlink(con_dev, fwnode, dl_flags);
		ret = fw_devlink_create_devlink(con_dev, fwnode, link);
		put_device(con_dev);
		if (!own_link || ret == -EAGAIN)
			continue;
@@ -2169,19 +2177,13 @@ static void __fw_devlink_link_to_suppliers(struct device *dev,
	bool own_link = (dev->fwnode == fwnode);
	struct fwnode_link *link, *tmp;
	struct fwnode_handle *child = NULL;
	u32 dl_flags;

	if (own_link)
		dl_flags = fw_devlink_get_flags();
	else
		dl_flags = FW_DEVLINK_FLAGS_PERMISSIVE;

	list_for_each_entry_safe(link, tmp, &fwnode->suppliers, c_hook) {
		int ret;
		struct device *sup_dev;
		struct fwnode_handle *sup = link->supplier;

		ret = fw_devlink_create_devlink(dev, sup, dl_flags);
		ret = fw_devlink_create_devlink(dev, sup, link);
		if (!own_link || ret == -EAGAIN)
			continue;

+0 −1
Original line number Diff line number Diff line
@@ -207,7 +207,6 @@ static inline void fwnode_dev_initialized(struct fwnode_handle *fwnode,
		fwnode->flags &= ~FWNODE_FLAG_INITIALIZED;
}

extern u32 fw_devlink_get_flags(void);
extern bool fw_devlink_is_strict(void);
int fwnode_link_add(struct fwnode_handle *con, struct fwnode_handle *sup);
void fwnode_links_purge(struct fwnode_handle *fwnode);