summaryrefslogtreecommitdiff
path: root/drivers/base/property.c
diff options
context:
space:
mode:
authorSaravana Kannan <saravanak@google.com>2020-11-20 18:02:25 -0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2020-12-09 19:10:21 +0100
commitb5d3e2fbcb10957521af14c4256cd0e5f68b9234 (patch)
treec40d818e24ef8da83ed6bd939ab2092d074967ed /drivers/base/property.c
parentac66c5bbb4371073dcace77e47c234d2e36a006b (diff)
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: Saravana Kannan <saravanak@google.com> Link: https://lore.kernel.org/r/20201121020232.908850-11-saravanak@google.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/base/property.c')
-rw-r--r--drivers/base/property.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/drivers/base/property.c b/drivers/base/property.c
index 4c43d30145c6..35b95c6ac0c6 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -615,6 +615,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
*
@@ -661,6 +686,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.
* @child: Handle to one of the node's child nodes or a %NULL handle.