summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiquel Raynal (Schneider Electric) <miquel.raynal@bootlin.com>2026-01-22 18:13:33 +0300
committerMark Brown <broonie@kernel.org>2026-01-28 23:41:24 +0300
commitf18c8cfa4f1af2cf7d68d86989a7d6109acfa1bb (patch)
treeb66c6bc311f92981dd92ecbf35e3ccbe66b05a19
parentbee085476d277e1f993cdec57e3c730f536594f0 (diff)
downloadlinux-f18c8cfa4f1af2cf7d68d86989a7d6109acfa1bb.tar.xz
spi: cadence-qspi: Fix probe error path and remove
The probe has been modified by many different users, it is hard to track history, but for sure its current state is partially broken. One easy rule to follow is to drop/free/release the resources in the opposite order they have been queried. Fix the labels, the order for freeing the resources, and add the missing DMA channel step. Replicate these changes in the remove path as well. Tested-by: Wolfram Sang <wsa+renesas@sang-engineering.com> Signed-off-by: Miquel Raynal (Schneider Electric) <miquel.raynal@bootlin.com> Tested-by: Santhosh Kumar K <s-k6@ti.com> Link: https://patch.msgid.link/20260122-schneider-6-19-rc1-qspi-v4-8-f9c21419a3e6@bootlin.com Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/spi/spi-cadence-quadspi.c44
1 files changed, 25 insertions, 19 deletions
diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
index 38518475858d..9c2b2b8649de 100644
--- a/drivers/spi/spi-cadence-quadspi.c
+++ b/drivers/spi/spi-cadence-quadspi.c
@@ -1889,7 +1889,7 @@ static int cqspi_probe(struct platform_device *pdev)
ret = clk_prepare_enable(cqspi->clk);
if (ret) {
dev_err(dev, "Cannot enable QSPI clock.\n");
- goto probe_clk_failed;
+ goto disable_rpm;
}
/* Obtain QSPI reset control */
@@ -1897,14 +1897,14 @@ static int cqspi_probe(struct platform_device *pdev)
if (IS_ERR(rstc)) {
ret = PTR_ERR(rstc);
dev_err(dev, "Cannot get QSPI reset.\n");
- goto probe_reset_failed;
+ goto disable_clk;
}
rstc_ocp = devm_reset_control_get_optional_exclusive(dev, "qspi-ocp");
if (IS_ERR(rstc_ocp)) {
ret = PTR_ERR(rstc_ocp);
dev_err(dev, "Cannot get QSPI OCP reset.\n");
- goto probe_reset_failed;
+ goto disable_clk;
}
if (of_device_is_compatible(pdev->dev.of_node, "starfive,jh7110-qspi")) {
@@ -1912,7 +1912,7 @@ static int cqspi_probe(struct platform_device *pdev)
if (IS_ERR(rstc_ref)) {
ret = PTR_ERR(rstc_ref);
dev_err(dev, "Cannot get QSPI REF reset.\n");
- goto probe_reset_failed;
+ goto disable_clk;
}
reset_control_assert(rstc_ref);
reset_control_deassert(rstc_ref);
@@ -1954,7 +1954,7 @@ static int cqspi_probe(struct platform_device *pdev)
if (ddata->jh7110_clk_init) {
ret = cqspi_jh7110_clk_init(pdev, cqspi);
if (ret)
- goto probe_reset_failed;
+ goto disable_clk;
}
if (ddata->quirks & CQSPI_DISABLE_STIG_MODE)
cqspi->disable_stig_mode = true;
@@ -1962,7 +1962,7 @@ static int cqspi_probe(struct platform_device *pdev)
if (ddata->quirks & CQSPI_DMA_SET_MASK) {
ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
if (ret)
- goto probe_reset_failed;
+ goto disable_clks;
}
}
@@ -1973,7 +1973,7 @@ static int cqspi_probe(struct platform_device *pdev)
pdev->name, cqspi);
if (ret) {
dev_err(dev, "Cannot request IRQ.\n");
- goto probe_reset_failed;
+ goto disable_clks;
}
cqspi_wait_idle(cqspi);
@@ -2000,31 +2000,36 @@ static int cqspi_probe(struct platform_device *pdev)
ret = cqspi_request_mmap_dma(cqspi);
if (ret == -EPROBE_DEFER) {
dev_err_probe(&pdev->dev, ret, "Failed to request mmap DMA\n");
- goto probe_setup_failed;
+ goto disable_controller;
}
}
ret = spi_register_controller(host);
if (ret) {
dev_err(&pdev->dev, "failed to register SPI ctlr %d\n", ret);
- goto probe_setup_failed;
+ goto release_dma_chan;
}
if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM)))
pm_runtime_put_autosuspend(dev);
return 0;
-probe_setup_failed:
- if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM)))
- pm_runtime_disable(dev);
+
+release_dma_chan:
+ if (cqspi->rx_chan)
+ dma_release_channel(cqspi->rx_chan);
+disable_controller:
cqspi_controller_enable(cqspi, 0);
-probe_reset_failed:
+disable_clks:
if (cqspi->is_jh7110)
cqspi_jh7110_disable_clk(pdev, cqspi);
-
+disable_clk:
if (pm_runtime_get_sync(&pdev->dev) >= 0)
clk_disable_unprepare(cqspi->clk);
-probe_clk_failed:
+disable_rpm:
+ if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM)))
+ pm_runtime_disable(dev);
+
return ret;
}
@@ -2042,18 +2047,19 @@ static void cqspi_remove(struct platform_device *pdev)
cqspi_wait_idle(cqspi);
spi_unregister_controller(cqspi->host);
- cqspi_controller_enable(cqspi, 0);
if (cqspi->rx_chan)
dma_release_channel(cqspi->rx_chan);
- if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM)))
- if (pm_runtime_get_sync(&pdev->dev) >= 0)
- clk_disable(cqspi->clk);
+ cqspi_controller_enable(cqspi, 0);
if (cqspi->is_jh7110)
cqspi_jh7110_disable_clk(pdev, cqspi);
+ if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM)))
+ if (pm_runtime_get_sync(&pdev->dev) >= 0)
+ clk_disable(cqspi->clk);
+
if (!(ddata && (ddata->quirks & CQSPI_DISABLE_RUNTIME_PM))) {
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);