[PATCH] ASoC: simple-card-utils: fix graph_util_is_ports0() for DT overlays

From: Sen Wang

Date: Sat Mar 07 2026 - 23:42:29 EST


graph_util_is_ports0() identifies DPCM front-end (ports@0) vs back-end
(ports@1) by calling of_get_child_by_name() to find the first "ports"
child and comparing pointers. This relies on child iteration order
matching DTS source order.

But when the DPCM topology comes from a DT overlay, __of_attach_node()
inserts new children at the head of the sibling list, reversing the
order. of_get_child_by_name() then returns ports@N instead of ports@0,
causing all front-end links to be classified as back-ends in
audio-graph-card2. The card subsequently breaks and registers with no
PCM devices.

Therefore fix this by string matching the unit address in the node name,
instead of relying on sibling order.

To mimic the original behavior, the function will match against "ports"
or "ports@0".

Fixes: 92939252458f ("ASoC: simple-card-utils: add asoc_graph_is_ports0()")
Signed-off-by: Sen Wang <sen@xxxxxx>
---
sound/soc/generic/simple-card-utils.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/sound/soc/generic/simple-card-utils.c b/sound/soc/generic/simple-card-utils.c
index bdc02e85b089..8e0efc78b490 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -1038,11 +1038,12 @@ int graph_util_is_ports0(struct device_node *np)
else
port = np;

- struct device_node *ports __free(device_node) = of_get_parent(port);
- struct device_node *top __free(device_node) = of_get_parent(ports);
- struct device_node *ports0 __free(device_node) = of_get_child_by_name(top, "ports");
+ struct device_node *ports __free(device_node) = of_get_parent(port);

- return ports0 == ports;
+ const char *at = strchr(kbasename(ports->full_name), '@');
+
+ /* match "ports" or "ports@0" by unit address in node name */
+ return !at || !strcmp(at, "@0");
}
EXPORT_SYMBOL_GPL(graph_util_is_ports0);

--
2.43.0