From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 34B32330B3A; Mon, 13 Apr 2026 17:03:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776099801; cv=none; b=ktG7xys13GiBLcKQaaHuU9cLTW81GUbiWq27CqxLvYLimRRrMowKEFJO99i/52EKMsX8dHCiiL8N4yhBeehH5e4f3NVI1rPVLyVXiq8Sbpk7VRtNA76XbnQsFFnqSqlvsEiBZ8TMDDUaqdJtI1yio9cjD9FLc/UaB7Zas47OVIM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1776099801; c=relaxed/simple; bh=0c/5GwnUpUttApvRM88SqACHsIp8kcPYDVQ1vBBKlME=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=I3fRx9WwEjg4eRpF+yvBJnhtm9mfFb4PwVCW0VTlbjO+h0ZYnos1UDS2drH1k9bqz5KQx3B49uFGGlTypLXDKSLYLIeFsCQaSwsyvg+KsvM4YzP+2LznThWP09OHhBUInjERetumT51MeipKmMQuIo7e29Mt8jt/CLE+3mZP4Dw= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=Y8kngO3D; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="Y8kngO3D" Received: by smtp.kernel.org (Postfix) with ESMTPSA id C1C4CC2BCAF; Mon, 13 Apr 2026 17:03:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1776099801; bh=0c/5GwnUpUttApvRM88SqACHsIp8kcPYDVQ1vBBKlME=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Y8kngO3DTLrjMMu7bnzshxgPnhhpxxe0/YiK+6/wn32p1Die4xWQQ8O4sq6HHOqgs nIO4Y07XcJcYWR2LlGCeLqNKDY1ImLpolEFbv8p6jULcoPSOUzed1hNbBHY+7ca47h mptDzLtoMB50N87moI9CcA0DhMp05dWjjIy7GNxo= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Saravana Kannan , Sasha Levin Subject: [PATCH 5.10 479/491] device property: Add fwnode_is_ancestor_of() and fwnode_get_next_parent_dev() Date: Mon, 13 Apr 2026 18:02:04 +0200 Message-ID: <20260413155836.985950427@linuxfoundation.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260413155819.042779211@linuxfoundation.org> References: <20260413155819.042779211@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 5.10-stable review patch. If anyone has any objections, please let me know. ------------------ From: Saravana Kannan [ Upstream commit b5d3e2fbcb10957521af14c4256cd0e5f68b9234 ] 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 Link: https://lore.kernel.org/r/20201121020232.908850-11-saravanak@google.com Signed-off-by: Greg Kroah-Hartman Stable-dep-of: 2692c614f8f0 ("device property: Allow secondary lookup in fwnode_get_next_child_node()") Signed-off-by: Sasha Levin Signed-off-by: Greg Kroah-Hartman --- drivers/base/property.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/property.h | 3 ++ 2 files changed, 55 insertions(+) --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -615,6 +615,31 @@ struct fwnode_handle *fwnode_get_next_pa 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_par 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. --- a/include/linux/property.h +++ b/include/linux/property.h @@ -85,9 +85,12 @@ const char *fwnode_get_name_prefix(const 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(