Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Saravana Kannan and committed by
Greg Kroah-Hartman
b5d3e2fb ac66c5bb

+55
+52
drivers/base/property.c
··· 615 615 EXPORT_SYMBOL_GPL(fwnode_get_next_parent); 616 616 617 617 /** 618 + * fwnode_get_next_parent_dev - Find device of closest ancestor fwnode 619 + * @fwnode: firmware node 620 + * 621 + * Given a firmware node (@fwnode), this function finds its closest ancestor 622 + * firmware node that has a corresponding struct device and returns that struct 623 + * device. 624 + * 625 + * The caller of this function is expected to call put_device() on the returned 626 + * device when they are done. 627 + */ 628 + struct device *fwnode_get_next_parent_dev(struct fwnode_handle *fwnode) 629 + { 630 + struct device *dev = NULL; 631 + 632 + fwnode_handle_get(fwnode); 633 + do { 634 + fwnode = fwnode_get_next_parent(fwnode); 635 + if (fwnode) 636 + dev = get_dev_from_fwnode(fwnode); 637 + } while (fwnode && !dev); 638 + fwnode_handle_put(fwnode); 639 + return dev; 640 + } 641 + 642 + /** 618 643 * fwnode_count_parents - Return the number of parents a node has 619 644 * @fwnode: The node the parents of which are to be counted 620 645 * ··· 684 659 return fwnode; 685 660 } 686 661 EXPORT_SYMBOL_GPL(fwnode_get_nth_parent); 662 + 663 + /** 664 + * fwnode_is_ancestor_of - Test if @test_ancestor is ancestor of @test_child 665 + * @test_ancestor: Firmware which is tested for being an ancestor 666 + * @test_child: Firmware which is tested for being the child 667 + * 668 + * A node is considered an ancestor of itself too. 669 + * 670 + * Returns true if @test_ancestor is an ancestor of @test_child. 671 + * Otherwise, returns false. 672 + */ 673 + bool fwnode_is_ancestor_of(struct fwnode_handle *test_ancestor, 674 + struct fwnode_handle *test_child) 675 + { 676 + if (!test_ancestor) 677 + return false; 678 + 679 + fwnode_handle_get(test_child); 680 + while (test_child) { 681 + if (test_child == test_ancestor) { 682 + fwnode_handle_put(test_child); 683 + return true; 684 + } 685 + test_child = fwnode_get_next_parent(test_child); 686 + } 687 + return false; 688 + } 687 689 688 690 /** 689 691 * fwnode_get_next_child_node - Return the next child node handle for a node
+3
include/linux/property.h
··· 85 85 struct fwnode_handle *fwnode_get_parent(const struct fwnode_handle *fwnode); 86 86 struct fwnode_handle *fwnode_get_next_parent( 87 87 struct fwnode_handle *fwnode); 88 + struct device *fwnode_get_next_parent_dev(struct fwnode_handle *fwnode); 88 89 unsigned int fwnode_count_parents(const struct fwnode_handle *fwn); 89 90 struct fwnode_handle *fwnode_get_nth_parent(struct fwnode_handle *fwn, 90 91 unsigned int depth); 92 + bool fwnode_is_ancestor_of(struct fwnode_handle *test_ancestor, 93 + struct fwnode_handle *test_child); 91 94 struct fwnode_handle *fwnode_get_next_child_node( 92 95 const struct fwnode_handle *fwnode, struct fwnode_handle *child); 93 96 struct fwnode_handle *fwnode_get_next_available_child_node(