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

device property: Add fwnode_is_ancestor_of() and fwnode_get_next_parent_dev()



Add fwnode_is_ancestor_of() helper function to check if a fwnode is an
ancestor of another fwnode.

Add fwnode_get_next_parent_dev() helper function that take as input a
fwnode and finds the closest ancestor fwnode that has a corresponding
struct device and returns that struct device.

Signed-off-by: default avatarSaravana Kannan <saravanak@google.com>
Link: https://lore.kernel.org/r/20201121020232.908850-11-saravanak@google.com


Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent ac66c5bb
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
@@ -614,6 +614,31 @@ struct fwnode_handle *fwnode_get_next_parent(struct fwnode_handle *fwnode)
}
EXPORT_SYMBOL_GPL(fwnode_get_next_parent);

/**
 * fwnode_get_next_parent_dev - Find device of closest ancestor fwnode
 * @fwnode: firmware node
 *
 * Given a firmware node (@fwnode), this function finds its closest ancestor
 * firmware node that has a corresponding struct device and returns that struct
 * device.
 *
 * The caller of this function is expected to call put_device() on the returned
 * device when they are done.
 */
struct device *fwnode_get_next_parent_dev(struct fwnode_handle *fwnode)
{
	struct device *dev = NULL;

	fwnode_handle_get(fwnode);
	do {
		fwnode = fwnode_get_next_parent(fwnode);
		if (fwnode)
			dev = get_dev_from_fwnode(fwnode);
	} while (fwnode && !dev);
	fwnode_handle_put(fwnode);
	return dev;
}

/**
 * fwnode_count_parents - Return the number of parents a node has
 * @fwnode: The node the parents of which are to be counted
@@ -660,6 +685,33 @@ struct fwnode_handle *fwnode_get_nth_parent(struct fwnode_handle *fwnode,
}
EXPORT_SYMBOL_GPL(fwnode_get_nth_parent);

/**
 * fwnode_is_ancestor_of - Test if @test_ancestor is ancestor of @test_child
 * @test_ancestor: Firmware which is tested for being an ancestor
 * @test_child: Firmware which is tested for being the child
 *
 * A node is considered an ancestor of itself too.
 *
 * Returns true if @test_ancestor is an ancestor of @test_child.
 * Otherwise, returns false.
 */
bool fwnode_is_ancestor_of(struct fwnode_handle *test_ancestor,
				  struct fwnode_handle *test_child)
{
	if (!test_ancestor)
		return false;

	fwnode_handle_get(test_child);
	while (test_child) {
		if (test_child == test_ancestor) {
			fwnode_handle_put(test_child);
			return true;
		}
		test_child = fwnode_get_next_parent(test_child);
	}
	return false;
}

/**
 * fwnode_get_next_child_node - Return the next child node handle for a node
 * @fwnode: Firmware node to find the next child node for.
+3 −0
Original line number Diff line number Diff line
@@ -85,9 +85,12 @@ const char *fwnode_get_name_prefix(const struct fwnode_handle *fwnode);
struct fwnode_handle *fwnode_get_parent(const struct fwnode_handle *fwnode);
struct fwnode_handle *fwnode_get_next_parent(
	struct fwnode_handle *fwnode);
struct device *fwnode_get_next_parent_dev(struct fwnode_handle *fwnode);
unsigned int fwnode_count_parents(const struct fwnode_handle *fwn);
struct fwnode_handle *fwnode_get_nth_parent(struct fwnode_handle *fwn,
					    unsigned int depth);
bool fwnode_is_ancestor_of(struct fwnode_handle *test_ancestor,
				  struct fwnode_handle *test_child);
struct fwnode_handle *fwnode_get_next_child_node(
	const struct fwnode_handle *fwnode, struct fwnode_handle *child);
struct fwnode_handle *fwnode_get_next_available_child_node(