Commit 87ffea09 authored by Andy Shevchenko's avatar Andy Shevchenko Committed by Rafael J. Wysocki
Browse files

device property: Introduce fwnode_for_each_parent_node()



In a few cases the functionality of fwnode_for_each_parent_node()
is already in use. Introduce a common helper macro for it.

It may be used by others as well in the future.

Signed-off-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: default avatarSakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 002752af
Loading
Loading
Loading
Loading
+29 −27
Original line number Diff line number Diff line
@@ -596,18 +596,18 @@ EXPORT_SYMBOL_GPL(fwnode_get_next_parent);
 */
struct device *fwnode_get_next_parent_dev(struct fwnode_handle *fwnode)
{
	struct fwnode_handle *parent;
	struct device *dev;

	fwnode_handle_get(fwnode);
	do {
		fwnode = fwnode_get_next_parent(fwnode);
		if (!fwnode)
			return NULL;
	fwnode_for_each_parent_node(fwnode, parent) {
		dev = get_dev_from_fwnode(fwnode);
	} while (!dev);
	fwnode_handle_put(fwnode);
		if (dev) {
			fwnode_handle_put(parent);
			return dev;
		}
	}
	return NULL;
}

/**
 * fwnode_count_parents - Return the number of parents a node has
@@ -617,13 +617,11 @@ struct device *fwnode_get_next_parent_dev(struct fwnode_handle *fwnode)
 */
unsigned int fwnode_count_parents(const struct fwnode_handle *fwnode)
{
	struct fwnode_handle *__fwnode;
	unsigned int count;

	__fwnode = fwnode_get_parent(fwnode);
	struct fwnode_handle *parent;
	unsigned int count = 0;

	for (count = 0; __fwnode; count++)
		__fwnode = fwnode_get_next_parent(__fwnode);
	fwnode_for_each_parent_node(fwnode, parent)
		count++;

	return count;
}
@@ -644,15 +642,16 @@ EXPORT_SYMBOL_GPL(fwnode_count_parents);
struct fwnode_handle *fwnode_get_nth_parent(struct fwnode_handle *fwnode,
					    unsigned int depth)
{
	fwnode_handle_get(fwnode);
	struct fwnode_handle *parent;

	do {
		if (depth-- == 0)
			break;
		fwnode = fwnode_get_next_parent(fwnode);
	} while (fwnode);
	if (depth == 0)
		return fwnode_handle_get(fwnode);

	return fwnode;
	fwnode_for_each_parent_node(fwnode, parent) {
		if (--depth == 0)
			return parent;
	}
	return NULL;
}
EXPORT_SYMBOL_GPL(fwnode_get_nth_parent);

@@ -669,17 +668,20 @@ EXPORT_SYMBOL_GPL(fwnode_get_nth_parent);
bool fwnode_is_ancestor_of(struct fwnode_handle *test_ancestor,
				  struct fwnode_handle *test_child)
{
	struct fwnode_handle *parent;

	if (IS_ERR_OR_NULL(test_ancestor))
		return false;

	fwnode_handle_get(test_child);
	do {
		if (test_child == test_ancestor) {
			fwnode_handle_put(test_child);
	if (test_child == test_ancestor)
		return true;

	fwnode_for_each_parent_node(test_child, parent) {
		if (parent == test_ancestor) {
			fwnode_handle_put(parent);
			return true;
		}
	}
		test_child = fwnode_get_next_parent(test_child);
	} while (test_child);
	return false;
}

+7 −2
Original line number Diff line number Diff line
@@ -83,9 +83,14 @@ struct fwnode_handle *fwnode_find_reference(const struct fwnode_handle *fwnode,

const char *fwnode_get_name(const struct fwnode_handle *fwnode);
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 fwnode_handle *fwnode_get_next_parent(struct fwnode_handle *fwnode);

#define fwnode_for_each_parent_node(fwnode, parent)		\
	for (parent = fwnode_get_parent(fwnode); parent;	\
	     parent = fwnode_get_next_parent(parent))

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,