* FAILED: patch "[PATCH] device property: Allow secondary lookup in" failed to apply to 5.10-stable tree
@ 2026-03-17 11:35 gregkh
2026-03-17 17:19 ` [PATCH 5.10.y 1/8] device property: Add fwnode_is_ancestor_of() and fwnode_get_next_parent_dev() Sasha Levin
0 siblings, 1 reply; 9+ messages in thread
From: gregkh @ 2026-03-17 11:35 UTC (permalink / raw)
To: andriy.shevchenko, dakr, rafael, sakari.ailus; +Cc: stable
The patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm
tree, then please email the backport, including the original git commit
id to <stable@vger.kernel.org>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.10.y
git checkout FETCH_HEAD
git cherry-pick -x 2692c614f8f05929d692b3dbfd3faef1f00fbaf0
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<stable@vger.kernel.org>' --in-reply-to '2026031703-caravan-bladder-c63a@gregkh' --subject-prefix 'PATCH 5.10.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 2692c614f8f05929d692b3dbfd3faef1f00fbaf0 Mon Sep 17 00:00:00 2001
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Date: Tue, 10 Feb 2026 14:58:22 +0100
Subject: [PATCH] device property: Allow secondary lookup in
fwnode_get_next_child_node()
When device_get_child_node_count() got split to the fwnode and device
respective APIs, the fwnode didn't inherit the ability to traverse over
the secondary fwnode. Hence any user, that switches from device to fwnode
API misses this feature. In particular, this was revealed by the commit
1490cbb9dbfd ("device property: Split fwnode_get_child_node_count()")
that effectively broke the GPIO enumeration on Intel Galileo boards.
Fix this by moving the secondary lookup from device to fwnode API.
Note, in general no device_*() API should go into the depth of the fwnode
implementation.
Fixes: 114dbb4fa7c4 ("drivers property: When no children in primary, try secondary")
Cc: stable@vger.kernel.org
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Rafael J. Wysocki (Intel) <rafael@kernel.org>
Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Link: https://patch.msgid.link/20260210135822.47335-1-andriy.shevchenko@linux.intel.com
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
diff --git a/drivers/base/property.c b/drivers/base/property.c
index 6a63860579dd..8d9a34be57fb 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -797,7 +797,18 @@ struct fwnode_handle *
fwnode_get_next_child_node(const struct fwnode_handle *fwnode,
struct fwnode_handle *child)
{
- return fwnode_call_ptr_op(fwnode, get_next_child_node, child);
+ struct fwnode_handle *next;
+
+ if (IS_ERR_OR_NULL(fwnode))
+ return NULL;
+
+ /* Try to find a child in primary fwnode */
+ next = fwnode_call_ptr_op(fwnode, get_next_child_node, child);
+ if (next)
+ return next;
+
+ /* When no more children in primary, continue with secondary */
+ return fwnode_call_ptr_op(fwnode->secondary, get_next_child_node, child);
}
EXPORT_SYMBOL_GPL(fwnode_get_next_child_node);
@@ -841,19 +852,7 @@ EXPORT_SYMBOL_GPL(fwnode_get_next_available_child_node);
struct fwnode_handle *device_get_next_child_node(const struct device *dev,
struct fwnode_handle *child)
{
- const struct fwnode_handle *fwnode = dev_fwnode(dev);
- struct fwnode_handle *next;
-
- if (IS_ERR_OR_NULL(fwnode))
- return NULL;
-
- /* Try to find a child in primary fwnode */
- next = fwnode_get_next_child_node(fwnode, child);
- if (next)
- return next;
-
- /* When no more children in primary, continue with secondary */
- return fwnode_get_next_child_node(fwnode->secondary, child);
+ return fwnode_get_next_child_node(dev_fwnode(dev), child);
}
EXPORT_SYMBOL_GPL(device_get_next_child_node);
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5.10.y 1/8] device property: Add fwnode_is_ancestor_of() and fwnode_get_next_parent_dev()
2026-03-17 11:35 FAILED: patch "[PATCH] device property: Allow secondary lookup in" failed to apply to 5.10-stable tree gregkh
@ 2026-03-17 17:19 ` Sasha Levin
2026-03-17 17:19 ` [PATCH 5.10.y 2/8] media: device property: Return true in fwnode_device_is_available for NULL ops Sasha Levin
` (6 more replies)
0 siblings, 7 replies; 9+ messages in thread
From: Sasha Levin @ 2026-03-17 17:19 UTC (permalink / raw)
To: stable; +Cc: Saravana Kannan, Greg Kroah-Hartman, Sasha Levin
From: Saravana Kannan <saravanak@google.com>
[ 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 <saravanak@google.com>
Link: https://lore.kernel.org/r/20201121020232.908850-11-saravanak@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: 2692c614f8f0 ("device property: Allow secondary lookup in fwnode_get_next_child_node()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/base/property.c | 52 ++++++++++++++++++++++++++++++++++++++++
include/linux/property.h | 3 +++
2 files changed, 55 insertions(+)
diff --git a/drivers/base/property.c b/drivers/base/property.c
index e9fdef1f45175..9b28f8233ef21 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -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.
diff --git a/include/linux/property.h b/include/linux/property.h
index 34ac286db88d2..3c2031c2c3034 100644
--- 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);
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(
--
2.51.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5.10.y 2/8] media: device property: Return true in fwnode_device_is_available for NULL ops
2026-03-17 17:19 ` [PATCH 5.10.y 1/8] device property: Add fwnode_is_ancestor_of() and fwnode_get_next_parent_dev() Sasha Levin
@ 2026-03-17 17:19 ` Sasha Levin
2026-03-17 17:19 ` [PATCH 5.10.y 3/8] device property: Retrieve fwnode from of_node via accessor Sasha Levin
` (5 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Sasha Levin @ 2026-03-17 17:19 UTC (permalink / raw)
To: stable
Cc: Daniel Scally, Laurent Pinchart, Andy Shevchenko, Heikki Krogerus,
Greg Kroah-Hartman, Rafael J. Wysocki, Sakari Ailus,
Mauro Carvalho Chehab, Sasha Levin
From: Daniel Scally <djrscally@gmail.com>
[ Upstream commit 5273382d03763277aaf8c6a2d6088e2afaee0cf0 ]
Some types of fwnode_handle do not implement the device_is_available()
check, such as those created by software_nodes. There isn't really a
meaningful way to check for the availability of a device that doesn't
actually exist, so if the check isn't implemented just assume that the
"device" is present.
Suggested-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Daniel Scally <djrscally@gmail.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Stable-dep-of: 2692c614f8f0 ("device property: Allow secondary lookup in fwnode_get_next_child_node()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/base/property.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/base/property.c b/drivers/base/property.c
index 9b28f8233ef21..80686d4a2bb35 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -837,9 +837,15 @@ EXPORT_SYMBOL_GPL(fwnode_handle_put);
/**
* fwnode_device_is_available - check if a device is available for use
* @fwnode: Pointer to the fwnode of the device.
+ *
+ * For fwnode node types that don't implement the .device_is_available()
+ * operation, this function returns true.
*/
bool fwnode_device_is_available(const struct fwnode_handle *fwnode)
{
+ if (!fwnode_has_op(fwnode, device_is_available))
+ return true;
+
return fwnode_call_bool_op(fwnode, device_is_available);
}
EXPORT_SYMBOL_GPL(fwnode_device_is_available);
--
2.51.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5.10.y 3/8] device property: Retrieve fwnode from of_node via accessor
2026-03-17 17:19 ` [PATCH 5.10.y 1/8] device property: Add fwnode_is_ancestor_of() and fwnode_get_next_parent_dev() Sasha Levin
2026-03-17 17:19 ` [PATCH 5.10.y 2/8] media: device property: Return true in fwnode_device_is_available for NULL ops Sasha Levin
@ 2026-03-17 17:19 ` Sasha Levin
2026-03-17 17:19 ` [PATCH 5.10.y 4/8] device property: Unify access to of_node Sasha Levin
` (4 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Sasha Levin @ 2026-03-17 17:19 UTC (permalink / raw)
To: stable; +Cc: Andy Shevchenko, Rafael J. Wysocki, Sasha Levin
From: Andy Shevchenko <andy.shevchenko@gmail.com>
[ Upstream commit 3cd8015040d7537a6b88e26f36768a90d9247829 ]
OF provides a specific accessor to retrieve fwnode handle.
Use it instead of direct dereferencing.
Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Stable-dep-of: 2692c614f8f0 ("device property: Allow secondary lookup in fwnode_get_next_child_node()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/base/property.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/base/property.c b/drivers/base/property.c
index 80686d4a2bb35..f8d9b9056d9c7 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -21,7 +21,7 @@
struct fwnode_handle *dev_fwnode(const struct device *dev)
{
return IS_ENABLED(CONFIG_OF) && dev->of_node ?
- &dev->of_node->fwnode : dev->fwnode;
+ of_fwnode_handle(dev->of_node) : dev->fwnode;
}
EXPORT_SYMBOL_GPL(dev_fwnode);
@@ -763,7 +763,7 @@ struct fwnode_handle *device_get_next_child_node(struct device *dev,
struct fwnode_handle *fwnode = NULL, *next;
if (dev->of_node)
- fwnode = &dev->of_node->fwnode;
+ fwnode = of_fwnode_handle(dev->of_node);
else if (adev)
fwnode = acpi_fwnode_handle(adev);
--
2.51.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5.10.y 4/8] device property: Unify access to of_node
2026-03-17 17:19 ` [PATCH 5.10.y 1/8] device property: Add fwnode_is_ancestor_of() and fwnode_get_next_parent_dev() Sasha Levin
2026-03-17 17:19 ` [PATCH 5.10.y 2/8] media: device property: Return true in fwnode_device_is_available for NULL ops Sasha Levin
2026-03-17 17:19 ` [PATCH 5.10.y 3/8] device property: Retrieve fwnode from of_node via accessor Sasha Levin
@ 2026-03-17 17:19 ` Sasha Levin
2026-03-17 17:19 ` [PATCH 5.10.y 5/8] device property: Check fwnode->secondary in fwnode_graph_get_next_endpoint() Sasha Levin
` (3 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Sasha Levin @ 2026-03-17 17:19 UTC (permalink / raw)
To: stable; +Cc: Andy Shevchenko, Rafael J. Wysocki, Sasha Levin
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[ Upstream commit fb38f314fbd173e2e9f9f0f2e720a5f4889562da ]
Historically we have a few variants how we access dev->fwnode
and dev->of_node. Some of the functions during development
gained different versions of the getters. Unify access to of_node
and as a side change slightly refactor ACPI specific branches.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Stable-dep-of: 2692c614f8f0 ("device property: Allow secondary lookup in fwnode_get_next_child_node()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/base/property.c | 29 +++++++++++++----------------
include/linux/property.h | 2 +-
2 files changed, 14 insertions(+), 17 deletions(-)
diff --git a/drivers/base/property.c b/drivers/base/property.c
index f8d9b9056d9c7..40968fd9c8d14 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -759,13 +759,8 @@ EXPORT_SYMBOL_GPL(fwnode_get_next_available_child_node);
struct fwnode_handle *device_get_next_child_node(struct device *dev,
struct fwnode_handle *child)
{
- struct acpi_device *adev = ACPI_COMPANION(dev);
- struct fwnode_handle *fwnode = NULL, *next;
-
- if (dev->of_node)
- fwnode = of_fwnode_handle(dev->of_node);
- else if (adev)
- fwnode = acpi_fwnode_handle(adev);
+ const struct fwnode_handle *fwnode = dev_fwnode(dev);
+ struct fwnode_handle *next;
/* Try to find a child in primary fwnode */
next = fwnode_get_next_child_node(fwnode, child);
@@ -868,28 +863,31 @@ EXPORT_SYMBOL_GPL(device_get_child_node_count);
bool device_dma_supported(struct device *dev)
{
+ const struct fwnode_handle *fwnode = dev_fwnode(dev);
+
/* For DT, this is always supported.
* For ACPI, this depends on CCA, which
* is determined by the acpi_dma_supported().
*/
- if (IS_ENABLED(CONFIG_OF) && dev->of_node)
+ if (is_of_node(fwnode))
return true;
- return acpi_dma_supported(ACPI_COMPANION(dev));
+ return acpi_dma_supported(to_acpi_device_node(fwnode));
}
EXPORT_SYMBOL_GPL(device_dma_supported);
enum dev_dma_attr device_get_dma_attr(struct device *dev)
{
+ const struct fwnode_handle *fwnode = dev_fwnode(dev);
enum dev_dma_attr attr = DEV_DMA_NOT_SUPPORTED;
- if (IS_ENABLED(CONFIG_OF) && dev->of_node) {
- if (of_dma_is_coherent(dev->of_node))
+ if (is_of_node(fwnode)) {
+ if (of_dma_is_coherent(to_of_node(fwnode)))
attr = DEV_DMA_COHERENT;
else
attr = DEV_DMA_NON_COHERENT;
} else
- attr = acpi_get_dma_attr(ACPI_COMPANION(dev));
+ attr = acpi_get_dma_attr(to_acpi_device_node(fwnode));
return attr;
}
@@ -1007,14 +1005,13 @@ EXPORT_SYMBOL(device_get_mac_address);
* Returns Linux IRQ number on success. Other values are determined
* accordingly to acpi_/of_ irq_get() operation.
*/
-int fwnode_irq_get(struct fwnode_handle *fwnode, unsigned int index)
+int fwnode_irq_get(const struct fwnode_handle *fwnode, unsigned int index)
{
- struct device_node *of_node = to_of_node(fwnode);
struct resource res;
int ret;
- if (IS_ENABLED(CONFIG_OF) && of_node)
- return of_irq_get(of_node, index);
+ if (is_of_node(fwnode))
+ return of_irq_get(to_of_node(fwnode), index);
ret = acpi_irq_get(ACPI_HANDLE_FWNODE(fwnode), index, &res);
if (ret)
diff --git a/include/linux/property.h b/include/linux/property.h
index 3c2031c2c3034..0604bb73e6282 100644
--- a/include/linux/property.h
+++ b/include/linux/property.h
@@ -119,7 +119,7 @@ struct fwnode_handle *device_get_named_child_node(struct device *dev,
struct fwnode_handle *fwnode_handle_get(struct fwnode_handle *fwnode);
void fwnode_handle_put(struct fwnode_handle *fwnode);
-int fwnode_irq_get(struct fwnode_handle *fwnode, unsigned int index);
+int fwnode_irq_get(const struct fwnode_handle *fwnode, unsigned int index);
unsigned int device_get_child_node_count(struct device *dev);
--
2.51.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5.10.y 5/8] device property: Check fwnode->secondary in fwnode_graph_get_next_endpoint()
2026-03-17 17:19 ` [PATCH 5.10.y 1/8] device property: Add fwnode_is_ancestor_of() and fwnode_get_next_parent_dev() Sasha Levin
` (2 preceding siblings ...)
2026-03-17 17:19 ` [PATCH 5.10.y 4/8] device property: Unify access to of_node Sasha Levin
@ 2026-03-17 17:19 ` Sasha Levin
2026-03-17 17:19 ` [PATCH 5.10.y 6/8] device property: Check fwnode->secondary when finding properties Sasha Levin
` (2 subsequent siblings)
6 siblings, 0 replies; 9+ messages in thread
From: Sasha Levin @ 2026-03-17 17:19 UTC (permalink / raw)
To: stable; +Cc: Daniel Scally, Andy Shevchenko, Rafael J. Wysocki, Sasha Levin
From: Daniel Scally <djrscally@gmail.com>
[ Upstream commit b5b41ab6b0c1bb70fe37a0d193006c969e3b5909 ]
Sensor drivers often check for an endpoint to make sure that they're
connected to a consuming device like a CIO2 during .probe(). Some of
those endpoints might be in the form of software_nodes assigned as
a secondary to the device's fwnode_handle. Account for this possibility
in fwnode_graph_get_next_endpoint() to avoid having to do it in the
sensor drivers themselves.
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Daniel Scally <djrscally@gmail.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Stable-dep-of: 2692c614f8f0 ("device property: Allow secondary lookup in fwnode_get_next_child_node()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/base/property.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/drivers/base/property.c b/drivers/base/property.c
index 40968fd9c8d14..bf9673fe59b3b 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -1033,7 +1033,26 @@ struct fwnode_handle *
fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode,
struct fwnode_handle *prev)
{
- return fwnode_call_ptr_op(fwnode, graph_get_next_endpoint, prev);
+ const struct fwnode_handle *parent;
+ struct fwnode_handle *ep;
+
+ /*
+ * If this function is in a loop and the previous iteration returned
+ * an endpoint from fwnode->secondary, then we need to use the secondary
+ * as parent rather than @fwnode.
+ */
+ if (prev)
+ parent = fwnode_graph_get_port_parent(prev);
+ else
+ parent = fwnode;
+
+ ep = fwnode_call_ptr_op(parent, graph_get_next_endpoint, prev);
+
+ if (IS_ERR_OR_NULL(ep) &&
+ !IS_ERR_OR_NULL(parent) && !IS_ERR_OR_NULL(parent->secondary))
+ ep = fwnode_graph_get_next_endpoint(parent->secondary, NULL);
+
+ return ep;
}
EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint);
--
2.51.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5.10.y 6/8] device property: Check fwnode->secondary when finding properties
2026-03-17 17:19 ` [PATCH 5.10.y 1/8] device property: Add fwnode_is_ancestor_of() and fwnode_get_next_parent_dev() Sasha Levin
` (3 preceding siblings ...)
2026-03-17 17:19 ` [PATCH 5.10.y 5/8] device property: Check fwnode->secondary in fwnode_graph_get_next_endpoint() Sasha Levin
@ 2026-03-17 17:19 ` Sasha Levin
2026-03-17 17:19 ` [PATCH 5.10.y 7/8] device property: Allow error pointer to be passed to fwnode APIs Sasha Levin
2026-03-17 17:19 ` [PATCH 5.10.y 8/8] device property: Allow secondary lookup in fwnode_get_next_child_node() Sasha Levin
6 siblings, 0 replies; 9+ messages in thread
From: Sasha Levin @ 2026-03-17 17:19 UTC (permalink / raw)
To: stable
Cc: Daniel Scally, Andy Shevchenko, Hans de Goede, Greg Kroah-Hartman,
Sasha Levin
From: Daniel Scally <djrscally@gmail.com>
[ Upstream commit c097af1d0a8483b44fa30e86b311991d76b6ae67 ]
fwnode_property_get_reference_args() searches for named properties
against a fwnode_handle, but these could instead be against the fwnode's
secondary. If the property isn't found against the primary, check the
secondary to see if it's there instead.
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Daniel Scally <djrscally@gmail.com>
Link: https://lore.kernel.org/r/20211128232455.39332-1-djrscally@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Stable-dep-of: 2692c614f8f0 ("device property: Allow secondary lookup in fwnode_get_next_child_node()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/base/property.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/drivers/base/property.c b/drivers/base/property.c
index bf9673fe59b3b..7de58f4887860 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -479,8 +479,17 @@ int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode,
unsigned int nargs, unsigned int index,
struct fwnode_reference_args *args)
{
- return fwnode_call_int_op(fwnode, get_reference_args, prop, nargs_prop,
- nargs, index, args);
+ int ret;
+
+ ret = fwnode_call_int_op(fwnode, get_reference_args, prop, nargs_prop,
+ nargs, index, args);
+
+ if (ret < 0 && !IS_ERR_OR_NULL(fwnode) &&
+ !IS_ERR_OR_NULL(fwnode->secondary))
+ ret = fwnode_call_int_op(fwnode->secondary, get_reference_args,
+ prop, nargs_prop, nargs, index, args);
+
+ return ret;
}
EXPORT_SYMBOL_GPL(fwnode_property_get_reference_args);
--
2.51.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5.10.y 7/8] device property: Allow error pointer to be passed to fwnode APIs
2026-03-17 17:19 ` [PATCH 5.10.y 1/8] device property: Add fwnode_is_ancestor_of() and fwnode_get_next_parent_dev() Sasha Levin
` (4 preceding siblings ...)
2026-03-17 17:19 ` [PATCH 5.10.y 6/8] device property: Check fwnode->secondary when finding properties Sasha Levin
@ 2026-03-17 17:19 ` Sasha Levin
2026-03-17 17:19 ` [PATCH 5.10.y 8/8] device property: Allow secondary lookup in fwnode_get_next_child_node() Sasha Levin
6 siblings, 0 replies; 9+ messages in thread
From: Sasha Levin @ 2026-03-17 17:19 UTC (permalink / raw)
To: stable
Cc: Andy Shevchenko, Nuno Sá, Sakari Ailus, Heikki Krogerus,
Michael Walle, Rafael J. Wysocki, Sasha Levin
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[ Upstream commit 002752af7b89b74c64fe6bec8c5fde3d3a7810d8 ]
Some of the fwnode APIs might return an error pointer instead of NULL
or valid fwnode handle. The result of such API call may be considered
optional and hence the test for it is usually done in a form of
fwnode = fwnode_find_reference(...);
if (IS_ERR(fwnode))
...error handling...
Nevertheless the resulting fwnode may have bumped the reference count
and hence caller of the above API is obliged to call fwnode_handle_put().
Since fwnode may be not valid either as NULL or error pointer the check
has to be performed there. This approach uglifies the code and adds
a point of making a mistake, i.e. forgetting about error point case.
To prevent this, allow an error pointer to be passed to the fwnode APIs.
Fixes: 83b34afb6b79 ("device property: Introduce fwnode_find_reference()")
Reported-by: Nuno Sá <nuno.sa@analog.com>
Tested-by: Nuno Sá <nuno.sa@analog.com>
Acked-by: Nuno Sá <nuno.sa@analog.com>
Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Reviewed-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Tested-by: Michael Walle <michael@walle.cc>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Stable-dep-of: 2692c614f8f0 ("device property: Allow secondary lookup in fwnode_get_next_child_node()")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/base/property.c | 89 +++++++++++++++++++++++------------------
include/linux/fwnode.h | 10 ++---
2 files changed, 56 insertions(+), 43 deletions(-)
diff --git a/drivers/base/property.c b/drivers/base/property.c
index 7de58f4887860..ed767dc2630d0 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -48,12 +48,14 @@ bool fwnode_property_present(const struct fwnode_handle *fwnode,
{
bool ret;
+ if (IS_ERR_OR_NULL(fwnode))
+ return false;
+
ret = fwnode_call_bool_op(fwnode, property_present, propname);
- if (ret == false && !IS_ERR_OR_NULL(fwnode) &&
- !IS_ERR_OR_NULL(fwnode->secondary))
- ret = fwnode_call_bool_op(fwnode->secondary, property_present,
- propname);
- return ret;
+ if (ret)
+ return ret;
+
+ return fwnode_call_bool_op(fwnode->secondary, property_present, propname);
}
EXPORT_SYMBOL_GPL(fwnode_property_present);
@@ -233,15 +235,16 @@ static int fwnode_property_read_int_array(const struct fwnode_handle *fwnode,
{
int ret;
+ if (IS_ERR_OR_NULL(fwnode))
+ return -EINVAL;
+
ret = fwnode_call_int_op(fwnode, property_read_int_array, propname,
elem_size, val, nval);
- if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) &&
- !IS_ERR_OR_NULL(fwnode->secondary))
- ret = fwnode_call_int_op(
- fwnode->secondary, property_read_int_array, propname,
- elem_size, val, nval);
+ if (ret != -EINVAL)
+ return ret;
- return ret;
+ return fwnode_call_int_op(fwnode->secondary, property_read_int_array, propname,
+ elem_size, val, nval);
}
/**
@@ -372,14 +375,16 @@ int fwnode_property_read_string_array(const struct fwnode_handle *fwnode,
{
int ret;
+ if (IS_ERR_OR_NULL(fwnode))
+ return -EINVAL;
+
ret = fwnode_call_int_op(fwnode, property_read_string_array, propname,
val, nval);
- if (ret == -EINVAL && !IS_ERR_OR_NULL(fwnode) &&
- !IS_ERR_OR_NULL(fwnode->secondary))
- ret = fwnode_call_int_op(fwnode->secondary,
- property_read_string_array, propname,
- val, nval);
- return ret;
+ if (ret != -EINVAL)
+ return ret;
+
+ return fwnode_call_int_op(fwnode->secondary, property_read_string_array, propname,
+ val, nval);
}
EXPORT_SYMBOL_GPL(fwnode_property_read_string_array);
@@ -481,15 +486,19 @@ int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode,
{
int ret;
+ if (IS_ERR_OR_NULL(fwnode))
+ return -ENOENT;
+
ret = fwnode_call_int_op(fwnode, get_reference_args, prop, nargs_prop,
nargs, index, args);
+ if (ret == 0)
+ return ret;
- if (ret < 0 && !IS_ERR_OR_NULL(fwnode) &&
- !IS_ERR_OR_NULL(fwnode->secondary))
- ret = fwnode_call_int_op(fwnode->secondary, get_reference_args,
- prop, nargs_prop, nargs, index, args);
+ if (IS_ERR_OR_NULL(fwnode->secondary))
+ return ret;
- return ret;
+ return fwnode_call_int_op(fwnode->secondary, get_reference_args, prop, nargs_prop,
+ nargs, index, args);
}
EXPORT_SYMBOL_GPL(fwnode_property_get_reference_args);
@@ -683,12 +692,13 @@ EXPORT_SYMBOL_GPL(fwnode_count_parents);
struct fwnode_handle *fwnode_get_nth_parent(struct fwnode_handle *fwnode,
unsigned int depth)
{
- unsigned int i;
-
fwnode_handle_get(fwnode);
- for (i = 0; i < depth && fwnode; i++)
+ do {
+ if (depth-- == 0)
+ break;
fwnode = fwnode_get_next_parent(fwnode);
+ } while (fwnode);
return fwnode;
}
@@ -707,17 +717,17 @@ EXPORT_SYMBOL_GPL(fwnode_get_nth_parent);
bool fwnode_is_ancestor_of(struct fwnode_handle *test_ancestor,
struct fwnode_handle *test_child)
{
- if (!test_ancestor)
+ if (IS_ERR_OR_NULL(test_ancestor))
return false;
fwnode_handle_get(test_child);
- while (test_child) {
+ do {
if (test_child == test_ancestor) {
fwnode_handle_put(test_child);
return true;
}
test_child = fwnode_get_next_parent(test_child);
- }
+ } while (test_child);
return false;
}
@@ -746,7 +756,7 @@ fwnode_get_next_available_child_node(const struct fwnode_handle *fwnode,
{
struct fwnode_handle *next_child = child;
- if (!fwnode)
+ if (IS_ERR_OR_NULL(fwnode))
return NULL;
do {
@@ -771,16 +781,16 @@ struct fwnode_handle *device_get_next_child_node(struct device *dev,
const struct fwnode_handle *fwnode = dev_fwnode(dev);
struct fwnode_handle *next;
+ if (IS_ERR_OR_NULL(fwnode))
+ return NULL;
+
/* Try to find a child in primary fwnode */
next = fwnode_get_next_child_node(fwnode, child);
if (next)
return next;
/* When no more children in primary, continue with secondary */
- if (fwnode && !IS_ERR_OR_NULL(fwnode->secondary))
- next = fwnode_get_next_child_node(fwnode->secondary, child);
-
- return next;
+ return fwnode_get_next_child_node(fwnode->secondary, child);
}
EXPORT_SYMBOL_GPL(device_get_next_child_node);
@@ -847,6 +857,9 @@ EXPORT_SYMBOL_GPL(fwnode_handle_put);
*/
bool fwnode_device_is_available(const struct fwnode_handle *fwnode)
{
+ if (IS_ERR_OR_NULL(fwnode))
+ return false;
+
if (!fwnode_has_op(fwnode, device_is_available))
return true;
@@ -1054,14 +1067,14 @@ fwnode_graph_get_next_endpoint(const struct fwnode_handle *fwnode,
parent = fwnode_graph_get_port_parent(prev);
else
parent = fwnode;
+ if (IS_ERR_OR_NULL(parent))
+ return NULL;
ep = fwnode_call_ptr_op(parent, graph_get_next_endpoint, prev);
+ if (ep)
+ return ep;
- if (IS_ERR_OR_NULL(ep) &&
- !IS_ERR_OR_NULL(parent) && !IS_ERR_OR_NULL(parent->secondary))
- ep = fwnode_graph_get_next_endpoint(parent->secondary, NULL);
-
- return ep;
+ return fwnode_graph_get_next_endpoint(parent->secondary, NULL);
}
EXPORT_SYMBOL_GPL(fwnode_graph_get_next_endpoint);
diff --git a/include/linux/fwnode.h b/include/linux/fwnode.h
index 9506f8ec09740..946eb9d74e393 100644
--- a/include/linux/fwnode.h
+++ b/include/linux/fwnode.h
@@ -149,12 +149,12 @@ struct fwnode_operations {
struct device *dev);
};
-#define fwnode_has_op(fwnode, op) \
- ((fwnode) && (fwnode)->ops && (fwnode)->ops->op)
+#define fwnode_has_op(fwnode, op) \
+ (!IS_ERR_OR_NULL(fwnode) && (fwnode)->ops && (fwnode)->ops->op)
+
#define fwnode_call_int_op(fwnode, op, ...) \
- (fwnode ? (fwnode_has_op(fwnode, op) ? \
- (fwnode)->ops->op(fwnode, ## __VA_ARGS__) : -ENXIO) : \
- -EINVAL)
+ (fwnode_has_op(fwnode, op) ? \
+ (fwnode)->ops->op(fwnode, ## __VA_ARGS__) : (IS_ERR_OR_NULL(fwnode) ? -EINVAL : -ENXIO))
#define fwnode_call_bool_op(fwnode, op, ...) \
(fwnode_has_op(fwnode, op) ? \
--
2.51.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5.10.y 8/8] device property: Allow secondary lookup in fwnode_get_next_child_node()
2026-03-17 17:19 ` [PATCH 5.10.y 1/8] device property: Add fwnode_is_ancestor_of() and fwnode_get_next_parent_dev() Sasha Levin
` (5 preceding siblings ...)
2026-03-17 17:19 ` [PATCH 5.10.y 7/8] device property: Allow error pointer to be passed to fwnode APIs Sasha Levin
@ 2026-03-17 17:19 ` Sasha Levin
6 siblings, 0 replies; 9+ messages in thread
From: Sasha Levin @ 2026-03-17 17:19 UTC (permalink / raw)
To: stable
Cc: Andy Shevchenko, Rafael J. Wysocki (Intel), Sakari Ailus,
Danilo Krummrich, Sasha Levin
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[ Upstream commit 2692c614f8f05929d692b3dbfd3faef1f00fbaf0 ]
When device_get_child_node_count() got split to the fwnode and device
respective APIs, the fwnode didn't inherit the ability to traverse over
the secondary fwnode. Hence any user, that switches from device to fwnode
API misses this feature. In particular, this was revealed by the commit
1490cbb9dbfd ("device property: Split fwnode_get_child_node_count()")
that effectively broke the GPIO enumeration on Intel Galileo boards.
Fix this by moving the secondary lookup from device to fwnode API.
Note, in general no device_*() API should go into the depth of the fwnode
implementation.
Fixes: 114dbb4fa7c4 ("drivers property: When no children in primary, try secondary")
Cc: stable@vger.kernel.org
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Rafael J. Wysocki (Intel) <rafael@kernel.org>
Reviewed-by: Sakari Ailus <sakari.ailus@linux.intel.com>
Link: https://patch.msgid.link/20260210135822.47335-1-andriy.shevchenko@linux.intel.com
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/base/property.c | 27 +++++++++++++--------------
1 file changed, 13 insertions(+), 14 deletions(-)
diff --git a/drivers/base/property.c b/drivers/base/property.c
index ed767dc2630d0..2577d0e9bfbd7 100644
--- a/drivers/base/property.c
+++ b/drivers/base/property.c
@@ -740,7 +740,18 @@ struct fwnode_handle *
fwnode_get_next_child_node(const struct fwnode_handle *fwnode,
struct fwnode_handle *child)
{
- return fwnode_call_ptr_op(fwnode, get_next_child_node, child);
+ struct fwnode_handle *next;
+
+ if (IS_ERR_OR_NULL(fwnode))
+ return NULL;
+
+ /* Try to find a child in primary fwnode */
+ next = fwnode_call_ptr_op(fwnode, get_next_child_node, child);
+ if (next)
+ return next;
+
+ /* When no more children in primary, continue with secondary */
+ return fwnode_call_ptr_op(fwnode->secondary, get_next_child_node, child);
}
EXPORT_SYMBOL_GPL(fwnode_get_next_child_node);
@@ -778,19 +789,7 @@ EXPORT_SYMBOL_GPL(fwnode_get_next_available_child_node);
struct fwnode_handle *device_get_next_child_node(struct device *dev,
struct fwnode_handle *child)
{
- const struct fwnode_handle *fwnode = dev_fwnode(dev);
- struct fwnode_handle *next;
-
- if (IS_ERR_OR_NULL(fwnode))
- return NULL;
-
- /* Try to find a child in primary fwnode */
- next = fwnode_get_next_child_node(fwnode, child);
- if (next)
- return next;
-
- /* When no more children in primary, continue with secondary */
- return fwnode_get_next_child_node(fwnode->secondary, child);
+ return fwnode_get_next_child_node(dev_fwnode(dev), child);
}
EXPORT_SYMBOL_GPL(device_get_next_child_node);
--
2.51.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-03-17 17:20 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-17 11:35 FAILED: patch "[PATCH] device property: Allow secondary lookup in" failed to apply to 5.10-stable tree gregkh
2026-03-17 17:19 ` [PATCH 5.10.y 1/8] device property: Add fwnode_is_ancestor_of() and fwnode_get_next_parent_dev() Sasha Levin
2026-03-17 17:19 ` [PATCH 5.10.y 2/8] media: device property: Return true in fwnode_device_is_available for NULL ops Sasha Levin
2026-03-17 17:19 ` [PATCH 5.10.y 3/8] device property: Retrieve fwnode from of_node via accessor Sasha Levin
2026-03-17 17:19 ` [PATCH 5.10.y 4/8] device property: Unify access to of_node Sasha Levin
2026-03-17 17:19 ` [PATCH 5.10.y 5/8] device property: Check fwnode->secondary in fwnode_graph_get_next_endpoint() Sasha Levin
2026-03-17 17:19 ` [PATCH 5.10.y 6/8] device property: Check fwnode->secondary when finding properties Sasha Levin
2026-03-17 17:19 ` [PATCH 5.10.y 7/8] device property: Allow error pointer to be passed to fwnode APIs Sasha Levin
2026-03-17 17:19 ` [PATCH 5.10.y 8/8] device property: Allow secondary lookup in fwnode_get_next_child_node() Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox