[PATCH 1/4] spi: Follow spi-parent when retrieving a controller from node

From: Ayush Singh
Date: Tue Jul 29 2025 - 05:51:40 EST


spi bus extension were introduced to decouple spi busses when they are
wired to connectors. Combined with devicetree overlays, they introduce
an additional level of indirection, which is needed to decouple the
overlay (describing the hardware available on addon baord) and the base
tree (describing resources provided to the addon board).

For instance, the following devicetree fragment, available once
overlays are applied, is legit:

```
spi1: spi@abcd0000 {
compatible = "xyz,spi-ctrl";
spi-bus-extension@0 {
reg = <0>;
spi-bus = <&spi-ctrl>;
};
...
};

connector {
spi-ctrl {
spi-parent = <&spi1>;
#address-cells = <1>;
#size-cells = <0>;

spi-bus-extension@0 {
reg = <0>;
spi-bus = <&spi-other-connector>;
};

device@1 {
compatible = "xyz,foo";
reg = <1>;
};
};

devices {
other-connector {
spi-at-other-connector {
spi-parent = <&spi-ctrl>;
#address-cells = <1>;
#size-cells = <0>;

device@2 {
compatible = "xyz,bar";
reg = <2>;
};
};
};
};
};
```

Current implementation of of_find_spi_controller_by_node() supposes that
the node parameter correspond to the adapter.

This assumption is no more valid with spi bus extensions. Indeed, the
node parameter can reference an spi bus extension node and not the
related adapter.

In the example, spi-ctrl and spi-at-other-connector nodes are chained
bus extensions and those node can be passed to
of_find_spi_controller_by_node() in order to get the related adapter (i.e
the adapter handling the bus and its extensions: spi@abcd0000).

Extend of_find_spi_controller_by_node() to perform the walking from the
given node through spi-parent references up to the adapter.

Signed-off-by: Ayush Singh <ayush@xxxxxxxxxxxxxxx>
---
drivers/spi/spi.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index a388f372b27a7f29d18f1dd5e862902811016fc6..0030e0be0d9b2f9e2b0c4a1d806b42bdb4ecb5d2 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -4776,11 +4776,18 @@ static struct spi_device *of_find_spi_device_by_node(struct device_node *node)
/* The spi controllers are not using spi_bus, so we find it with another way */
static struct spi_controller *of_find_spi_controller_by_node(struct device_node *node)
{
+ struct device_node *ctlr_node = node;
struct device *dev;

- dev = class_find_device_by_of_node(&spi_controller_class, node);
+ while (of_property_present(ctlr_node, "spi-parent")) {
+ ctlr_node = of_parse_phandle(ctlr_node, "spi-parent", 0);
+ if (!ctlr_node)
+ return NULL;
+ }
+
+ dev = class_find_device_by_of_node(&spi_controller_class, ctlr_node);
if (!dev && IS_ENABLED(CONFIG_SPI_SLAVE))
- dev = class_find_device_by_of_node(&spi_target_class, node);
+ dev = class_find_device_by_of_node(&spi_target_class, ctlr_node);
if (!dev)
return NULL;


--
2.50.1