[PATCH v2 4/8] spi: cadence-xspi: support clocks and resets
From: Nuno Sá
Date: Wed Nov 11 2026 - 08:39:31 EST
The driver assumes the controller clock is already running and that the
controller is out of reset, which only holds if the firmware left it
that way.
Get and enable the optional controller clock and, if a reset line is
described, reset the controller during probe so it starts from a known
state. After the reset, wait for the controller to complete its reset
and initialization process before touching it. Both are optional to keep
compatibility with existing devicetrees.
Signed-off-by: Nuno Sá <nuno.sa@xxxxxxxxxx>
---
drivers/spi/spi-cadence-xspi.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c
index c02069715153..5d8d102ef397 100644
--- a/drivers/spi/spi-cadence-xspi.c
+++ b/drivers/spi/spi-cadence-xspi.c
@@ -2,6 +2,7 @@
// Cadence XSPI flash controller driver
// Copyright (C) 2020-21 Cadence
+#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/delay.h>
#include <linux/err.h>
@@ -14,6 +15,7 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
+#include <linux/reset.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi-mem.h>
#include <linux/bitfield.h>
@@ -1236,7 +1238,9 @@ static int cdns_xspi_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct spi_controller *host = NULL;
struct cdns_xspi_dev *cdns_xspi = NULL;
+ struct reset_control *rstc;
struct resource *res;
+ struct clk *clk;
int ret;
host = devm_spi_alloc_host(dev, sizeof(*cdns_xspi));
@@ -1322,6 +1326,25 @@ static int cdns_xspi_probe(struct platform_device *pdev)
}
#endif
+ /* Optional to keep compatibility with existing devicetrees */
+ clk = devm_clk_get_optional_enabled(dev, NULL);
+ if (IS_ERR(clk))
+ return dev_err_probe(dev, PTR_ERR(clk), "Failed to get clock\n");
+
+ rstc = devm_reset_control_get_optional_exclusive(dev, NULL);
+ if (IS_ERR(rstc))
+ return dev_err_probe(dev, PTR_ERR(rstc), "Failed to get reset\n");
+
+ if (rstc) {
+ ret = reset_control_reset(rstc);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to reset controller\n");
+
+ ret = cdns_xspi_wait_for_init(cdns_xspi);
+ if (ret)
+ return ret;
+ }
+
cdns_xspi->irq = platform_get_irq(pdev, 0);
if (cdns_xspi->irq < 0)
return -ENXIO;
--
2.56.0