aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2026-04-15 14:34:11 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2026-04-15 14:34:11 -0700
commit405f6584d7d0fc46534fd370e374630283dffe60 (patch)
tree3fb3b28d26578f450f446bedc2818a6fc26101f0
parent44f7a3795395b54bf674002803e3e80c6312e210 (diff)
parentc4c3fc872d2a05bf10372233c98e81344e685cdf (diff)
Merge tag 'spi-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
Pull spi updates from Mark Brown: "A busy release for SPI, almost all of it in a couple of larger fix and cleanup series for patterns that affected many drivers. We do have a couple of core API additions as well, relatively application specific but they enable some new use cases. - A packed command operation for spi-mem devices - Improvements to the ancillary device support to enable some IIO use cases from Antoniu Miclaus - Fixes for a registration ordering issue pattern caused by the handover between allocation and registration of controllers in concert with devm from Johan Hovold - Improvements to handling of clock allocation from Pei Xiao - Cleanups in the fsl-lpspi driver from Marc Kleine-Budde - Support for Renesas RZ/G3E and RZ/G3L" * tag 'spi-v7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (115 commits) spi: sn-f-ospi: fix incorrect return code for invalid num-cs spi: spi-mem: Add a packed command operation spi: cadence-qspi: Revert the filtering of certain opcodes in ODTR spi: mtk-snfi: unregister ECC engine on probe failure and remove() callback spi: s3c64xx: fix NULL-deref on driver unbind spi: zynq-qspi: fix controller deregistration spi: zynqmp-gqspi: fix controller deregistration spi: uniphier: fix controller deregistration spi: ti-qspi: fix controller deregistration spi: tegra20-sflash: fix controller deregistration spi: tegra114: fix controller deregistration spi: syncuacer: fix controller deregistration spi: sun6i: fix controller deregistration spi: sun4i: fix controller deregistration spi: st-ssc4: fix controller deregistration spi: sprd: fix controller deregistration spi: slave-mt27xx: fix controller deregistration spi: sifive: fix controller deregistration spi: sh-msiof: fix controller deregistration spi: sh-hspi: fix controller deregistration ...
-rw-r--r--Documentation/devicetree/bindings/spi/microchip,mpfs-spi.yaml4
-rw-r--r--Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml52
-rw-r--r--drivers/spi/Kconfig4
-rw-r--r--drivers/spi/spi-amlogic-spisg.c10
-rw-r--r--drivers/spi/spi-aspeed-smc.c9
-rw-r--r--drivers/spi/spi-at91-usart.c8
-rw-r--r--drivers/spi/spi-atcspi200.c29
-rw-r--r--drivers/spi/spi-atmel.c8
-rw-r--r--drivers/spi/spi-axiado.c1
-rw-r--r--drivers/spi/spi-bcm63xx-hsspi.c54
-rw-r--r--drivers/spi/spi-bcm63xx.c8
-rw-r--r--drivers/spi/spi-bcmbca-hsspi.c53
-rw-r--r--drivers/spi/spi-cadence-quadspi.c4
-rw-r--r--drivers/spi/spi-cavium-octeon.c8
-rw-r--r--drivers/spi/spi-cavium-thunderx.c8
-rw-r--r--drivers/spi/spi-ch341.c43
-rw-r--r--drivers/spi/spi-coldfire-qspi.c10
-rw-r--r--drivers/spi/spi-cs42l43.c4
-rw-r--r--drivers/spi/spi-dln2.c8
-rw-r--r--drivers/spi/spi-ep93xx.c8
-rw-r--r--drivers/spi/spi-fsl-espi.c10
-rw-r--r--drivers/spi/spi-fsl-lpspi.c68
-rw-r--r--drivers/spi/spi-fsl-qspi.c3
-rw-r--r--drivers/spi/spi-fsl-spi.c14
-rw-r--r--drivers/spi/spi-hisi-kunpeng.c17
-rw-r--r--drivers/spi/spi-img-spfi.c8
-rw-r--r--drivers/spi/spi-imx.c41
-rw-r--r--drivers/spi/spi-lantiq-ssc.c8
-rw-r--r--drivers/spi/spi-meson-spicc.c8
-rw-r--r--drivers/spi/spi-microchip-core-qspi.c12
-rw-r--r--drivers/spi/spi-microchip-core-spi.c4
-rw-r--r--drivers/spi/spi-mpfs.c4
-rw-r--r--drivers/spi/spi-mt65xx.c4
-rw-r--r--drivers/spi/spi-mtk-nor.c4
-rw-r--r--drivers/spi/spi-mtk-snfi.c14
-rw-r--r--drivers/spi/spi-mxs.c8
-rw-r--r--drivers/spi/spi-npcm-fiu.c8
-rw-r--r--drivers/spi/spi-npcm-pspi.c8
-rw-r--r--drivers/spi/spi-nxp-fspi.c3
-rw-r--r--drivers/spi/spi-nxp-xspi.c3
-rw-r--r--drivers/spi/spi-omap2-mcspi.c25
-rw-r--r--drivers/spi/spi-pic32-sqi.c8
-rw-r--r--drivers/spi/spi-pic32.c11
-rw-r--r--drivers/spi/spi-pl022.c18
-rw-r--r--drivers/spi/spi-pxa2xx-dma.c6
-rw-r--r--drivers/spi/spi-pxa2xx.c11
-rw-r--r--drivers/spi/spi-qup.c8
-rw-r--r--drivers/spi/spi-rockchip.c40
-rw-r--r--drivers/spi/spi-rspi.c10
-rw-r--r--drivers/spi/spi-rzv2h-rspi.c60
-rw-r--r--drivers/spi/spi-s3c64xx.c9
-rw-r--r--drivers/spi/spi-sh-hspi.c10
-rw-r--r--drivers/spi/spi-sh-msiof.c10
-rw-r--r--drivers/spi/spi-sifive.c29
-rw-r--r--drivers/spi/spi-slave-mt27xx.c10
-rw-r--r--drivers/spi/spi-sn-f-ospi.c2
-rw-r--r--drivers/spi/spi-sprd.c8
-rw-r--r--drivers/spi/spi-st-ssc4.c8
-rw-r--r--drivers/spi/spi-stm32-ospi.c5
-rw-r--r--drivers/spi/spi-stm32.c72
-rw-r--r--drivers/spi/spi-sun4i.c10
-rw-r--r--drivers/spi/spi-sun6i.c8
-rw-r--r--drivers/spi/spi-sunplus-sp7021.c15
-rw-r--r--drivers/spi/spi-synquacer.c8
-rw-r--r--drivers/spi/spi-tegra114.c8
-rw-r--r--drivers/spi/spi-tegra20-sflash.c8
-rw-r--r--drivers/spi/spi-tegra20-slink.c26
-rw-r--r--drivers/spi/spi-tegra210-quad.c22
-rw-r--r--drivers/spi/spi-ti-qspi.c14
-rw-r--r--drivers/spi/spi-uniphier.c24
-rw-r--r--drivers/spi/spi-zynq-qspi.c15
-rw-r--r--drivers/spi/spi-zynqmp-gqspi.c4
-rw-r--r--drivers/spi/spi.c113
-rw-r--r--include/linux/spi/spi-mem.h16
-rw-r--r--include/linux/spi/spi.h1
75 files changed, 741 insertions, 493 deletions
diff --git a/Documentation/devicetree/bindings/spi/microchip,mpfs-spi.yaml b/Documentation/devicetree/bindings/spi/microchip,mpfs-spi.yaml
index 636338d24bdf..8ff50dfcf585 100644
--- a/Documentation/devicetree/bindings/spi/microchip,mpfs-spi.yaml
+++ b/Documentation/devicetree/bindings/spi/microchip,mpfs-spi.yaml
@@ -35,10 +35,10 @@ properties:
interrupts:
maxItems: 1
- clock-names:
+ clocks:
maxItems: 1
- clocks:
+ resets:
maxItems: 1
microchip,apb-datawidth:
diff --git a/Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml b/Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml
index a588b112e11e..f40f316943ba 100644
--- a/Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml
+++ b/Documentation/devicetree/bindings/spi/renesas,rzv2h-rspi.yaml
@@ -13,10 +13,13 @@ properties:
compatible:
oneOf:
- enum:
+ - renesas,r9a08g046-rspi # RZ/G3L
- renesas,r9a09g057-rspi # RZ/V2H(P)
- renesas,r9a09g077-rspi # RZ/T2H
- items:
- - const: renesas,r9a09g056-rspi # RZ/V2N
+ - enum:
+ - renesas,r9a09g047-rspi # RZ/G3E
+ - renesas,r9a09g056-rspi # RZ/V2N
- const: renesas,r9a09g057-rspi
- items:
- const: renesas,r9a09g087-rspi # RZ/N2H
@@ -58,12 +61,19 @@ properties:
- const: tresetn
dmas:
- maxItems: 2
+ minItems: 2
+ maxItems: 10
+ description:
+ Must contain a list of pairs of references to DMA specifiers, one for
+ transmission, and one for reception.
dma-names:
+ minItems: 2
+ maxItems: 10
items:
- - const: rx
- - const: tx
+ enum:
+ - rx
+ - tx
power-domains:
maxItems: 1
@@ -86,6 +96,34 @@ allOf:
compatible:
contains:
enum:
+ - renesas,r9a08g046-rspi
+ then:
+ properties:
+ clocks:
+ maxItems: 2
+
+ clock-names:
+ items:
+ - const: pclk
+ - const: tclk
+
+ dmas:
+ maxItems: 2
+
+ dma-names:
+ items:
+ - const: rx
+ - const: tx
+
+ required:
+ - resets
+ - reset-names
+
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
- renesas,r9a09g057-rspi
then:
properties:
@@ -121,6 +159,12 @@ allOf:
resets: false
reset-names: false
+ dmas:
+ maxItems: 6
+
+ dma-names:
+ maxItems: 6
+
unevaluatedProperties: false
examples:
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index c3b2f02f5912..b563f49e2197 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -138,7 +138,7 @@ config SPI_AR934X
config SPI_ATCSPI200
tristate "Andes ATCSPI200 SPI controller"
- depends on ARCH_ANDES
+ depends on ARCH_ANDES || COMPILE_TEST
help
SPI driver for Andes ATCSPI200 SPI controller.
ATCSPI200 controller supports DMA and PIO modes. When DMA
@@ -866,7 +866,7 @@ config SPI_PIC32_SQI
config SPI_PL022
tristate "ARM AMBA PL022 SSP controller"
- depends on ARM_AMBA
+ depends on ARM_AMBA || COMPILE_TEST
default y if ARCH_REALVIEW
default y if INTEGRATOR_IMPD1
default y if ARCH_VERSATILE
diff --git a/drivers/spi/spi-amlogic-spisg.c b/drivers/spi/spi-amlogic-spisg.c
index 9d568e385f05..19c5eba412ef 100644
--- a/drivers/spi/spi-amlogic-spisg.c
+++ b/drivers/spi/spi-amlogic-spisg.c
@@ -647,13 +647,13 @@ static int aml_spisg_clk_init(struct spisg_device *spisg, void __iomem *base)
int ret, i;
spisg->core = devm_clk_get_enabled(dev, "core");
- if (IS_ERR_OR_NULL(spisg->core)) {
+ if (IS_ERR(spisg->core)) {
dev_err(dev, "core clock request failed\n");
return PTR_ERR(spisg->core);
}
spisg->pclk = devm_clk_get_enabled(dev, "pclk");
- if (IS_ERR_OR_NULL(spisg->pclk)) {
+ if (IS_ERR(spisg->pclk)) {
dev_err(dev, "pclk clock request failed\n");
return PTR_ERR(spisg->pclk);
}
@@ -703,7 +703,7 @@ static int aml_spisg_clk_init(struct spisg_device *spisg, void __iomem *base)
}
spisg->sclk = devm_clk_hw_get_clk(dev, &div->hw, NULL);
- if (IS_ERR_OR_NULL(spisg->sclk)) {
+ if (IS_ERR(spisg->sclk)) {
dev_err(dev, "get clock failed\n");
return PTR_ERR(spisg->sclk);
}
@@ -800,7 +800,7 @@ static int aml_spisg_probe(struct platform_device *pdev)
goto out_clk;
}
- ret = devm_spi_register_controller(dev, ctlr);
+ ret = spi_register_controller(ctlr);
if (ret) {
dev_err(&pdev->dev, "spi controller registration failed\n");
goto out_clk;
@@ -823,6 +823,8 @@ static void aml_spisg_remove(struct platform_device *pdev)
{
struct spisg_device *spisg = platform_get_drvdata(pdev);
+ spi_unregister_controller(spisg->controller);
+
if (!pm_runtime_suspended(&pdev->dev)) {
pinctrl_pm_select_sleep_state(&spisg->pdev->dev);
clk_disable_unprepare(spisg->core);
diff --git a/drivers/spi/spi-aspeed-smc.c b/drivers/spi/spi-aspeed-smc.c
index 9c286e534bf0..c21323e07d3c 100644
--- a/drivers/spi/spi-aspeed-smc.c
+++ b/drivers/spi/spi-aspeed-smc.c
@@ -972,7 +972,7 @@ static int aspeed_spi_probe(struct platform_device *pdev)
return -ENOMEM;
aspi = spi_controller_get_devdata(ctlr);
- platform_set_drvdata(pdev, aspi);
+ platform_set_drvdata(pdev, ctlr);
aspi->data = data;
aspi->dev = dev;
@@ -1021,7 +1021,7 @@ static int aspeed_spi_probe(struct platform_device *pdev)
return ret;
}
- ret = devm_spi_register_controller(dev, ctlr);
+ ret = spi_register_controller(ctlr);
if (ret)
dev_err(&pdev->dev, "spi_register_controller failed\n");
@@ -1030,7 +1030,10 @@ static int aspeed_spi_probe(struct platform_device *pdev)
static void aspeed_spi_remove(struct platform_device *pdev)
{
- struct aspeed_spi *aspi = platform_get_drvdata(pdev);
+ struct spi_controller *ctlr = platform_get_drvdata(pdev);
+ struct aspeed_spi *aspi = spi_controller_get_devdata(ctlr);
+
+ spi_unregister_controller(ctlr);
aspeed_spi_enable(aspi, false);
}
diff --git a/drivers/spi/spi-at91-usart.c b/drivers/spi/spi-at91-usart.c
index 76eb3ba75ab1..79edc1cd13c0 100644
--- a/drivers/spi/spi-at91-usart.c
+++ b/drivers/spi/spi-at91-usart.c
@@ -556,7 +556,7 @@ static int at91_usart_spi_probe(struct platform_device *pdev)
spin_lock_init(&aus->lock);
init_completion(&aus->xfer_completion);
- ret = devm_spi_register_controller(&pdev->dev, controller);
+ ret = spi_register_controller(controller);
if (ret)
goto at91_usart_fail_register_controller;
@@ -634,8 +634,14 @@ static void at91_usart_spi_remove(struct platform_device *pdev)
struct spi_controller *ctlr = platform_get_drvdata(pdev);
struct at91_usart_spi *aus = spi_controller_get_devdata(ctlr);
+ spi_controller_get(ctlr);
+
+ spi_unregister_controller(ctlr);
+
at91_usart_spi_release_dma(ctlr);
clk_disable_unprepare(aus->clk);
+
+ spi_controller_put(ctlr);
}
static const struct dev_pm_ops at91_usart_spi_pm_ops = {
diff --git a/drivers/spi/spi-atcspi200.c b/drivers/spi/spi-atcspi200.c
index 2665f31a49ce..3832d9db3cbf 100644
--- a/drivers/spi/spi-atcspi200.c
+++ b/drivers/spi/spi-atcspi200.c
@@ -494,11 +494,6 @@ static int atcspi_init_resources(struct platform_device *pdev,
return dev_err_probe(spi->dev, PTR_ERR(spi->regmap),
"Failed to init regmap\n");
- spi->clk = devm_clk_get(spi->dev, NULL);
- if (IS_ERR(spi->clk))
- return dev_err_probe(spi->dev, PTR_ERR(spi->clk),
- "Failed to get SPI clock\n");
-
spi->sclk_rate = ATCSPI_MAX_SPEED_HZ;
return 0;
}
@@ -520,13 +515,10 @@ static int atcspi_configure_dma(struct atcspi_dev *spi)
static int atcspi_enable_clk(struct atcspi_dev *spi)
{
- int ret;
-
- ret = clk_prepare_enable(spi->clk);
- if (ret)
- return dev_err_probe(spi->dev, ret,
- "Failed to enable clock\n");
-
+ spi->clk = devm_clk_get_enabled(spi->dev, NULL);
+ if (IS_ERR(spi->clk))
+ return dev_err_probe(spi->dev, PTR_ERR(spi->clk),
+ "Failed to get SPI clock\n");
spi->clk_rate = clk_get_rate(spi->clk);
if (!spi->clk_rate)
return dev_err_probe(spi->dev, -EINVAL,
@@ -567,6 +559,8 @@ static int atcspi_probe(struct platform_device *pdev)
spi->dev = &pdev->dev;
dev_set_drvdata(&pdev->dev, host);
+ mutex_init(&spi->mutex_lock);
+
ret = atcspi_init_resources(pdev, spi, &mem_res);
if (ret)
goto free_controller;
@@ -579,15 +573,14 @@ static int atcspi_probe(struct platform_device *pdev)
ret = atcspi_setup(spi);
if (ret)
- goto disable_clk;
+ goto free_controller;
ret = devm_spi_register_controller(&pdev->dev, host);
if (ret) {
dev_err_probe(spi->dev, ret,
"Failed to register SPI controller\n");
- goto disable_clk;
+ goto free_controller;
}
-
spi->use_dma = false;
if (ATCSPI_DMA_SUPPORT) {
ret = atcspi_configure_dma(spi);
@@ -597,14 +590,11 @@ static int atcspi_probe(struct platform_device *pdev)
else
spi->use_dma = true;
}
- mutex_init(&spi->mutex_lock);
return 0;
-disable_clk:
- clk_disable_unprepare(spi->clk);
-
free_controller:
+ mutex_destroy(&spi->mutex_lock);
spi_controller_put(host);
return ret;
}
@@ -661,7 +651,6 @@ static struct platform_driver atcspi_driver = {
.probe = atcspi_probe,
.driver = {
.name = "atcspi200",
- .owner = THIS_MODULE,
.of_match_table = atcspi_of_match,
.pm = pm_sleep_ptr(&atcspi_pm_ops)
}
diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c
index 445d645585bf..42db85d7ff8e 100644
--- a/drivers/spi/spi-atmel.c
+++ b/drivers/spi/spi-atmel.c
@@ -1654,7 +1654,7 @@ static int atmel_spi_probe(struct platform_device *pdev)
pm_runtime_set_active(&pdev->dev);
pm_runtime_enable(&pdev->dev);
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret)
goto out_free_dma;
@@ -1688,8 +1688,12 @@ static void atmel_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct atmel_spi *as = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
pm_runtime_get_sync(&pdev->dev);
+ spi_unregister_controller(host);
+
/* reset the hardware and block queue progress */
if (as->use_dma) {
atmel_spi_stop_dma(host);
@@ -1716,6 +1720,8 @@ static void atmel_spi_remove(struct platform_device *pdev)
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
+
+ spi_controller_put(host);
}
static int atmel_spi_runtime_suspend(struct device *dev)
diff --git a/drivers/spi/spi-axiado.c b/drivers/spi/spi-axiado.c
index 8ddcd27def22..dc55c55ae63c 100644
--- a/drivers/spi/spi-axiado.c
+++ b/drivers/spi/spi-axiado.c
@@ -842,7 +842,6 @@ static int ax_spi_probe(struct platform_device *pdev)
ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
- pm_runtime_mark_last_busy(&pdev->dev);
pm_runtime_put_autosuspend(&pdev->dev);
ctlr->mem_ops = &ax_spi_mem_ops;
diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c
index 612f8802e690..e935e8ab9cfd 100644
--- a/drivers/spi/spi-bcm63xx-hsspi.c
+++ b/drivers/spi/spi-bcm63xx-hsspi.c
@@ -758,8 +758,7 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev)
if (IS_ERR(regs))
return PTR_ERR(regs);
- clk = devm_clk_get(dev, "hsspi");
-
+ clk = devm_clk_get_enabled(dev, "hsspi");
if (IS_ERR(clk))
return PTR_ERR(clk);
@@ -767,41 +766,26 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev)
if (IS_ERR(reset))
return PTR_ERR(reset);
- ret = clk_prepare_enable(clk);
- if (ret)
- return ret;
-
ret = reset_control_reset(reset);
- if (ret) {
- dev_err(dev, "unable to reset device: %d\n", ret);
- goto out_disable_clk;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "unable to reset device: %d\n", ret);
rate = clk_get_rate(clk);
if (!rate) {
- pll_clk = devm_clk_get(dev, "pll");
-
- if (IS_ERR(pll_clk)) {
- ret = PTR_ERR(pll_clk);
- goto out_disable_clk;
- }
-
- ret = clk_prepare_enable(pll_clk);
- if (ret)
- goto out_disable_clk;
+ pll_clk = devm_clk_get_enabled(dev, "pll");
+ if (IS_ERR(pll_clk))
+ return dev_err_probe(dev, PTR_ERR(pll_clk),
+ "failed enable pll clk\n");
rate = clk_get_rate(pll_clk);
- if (!rate) {
- ret = -EINVAL;
- goto out_disable_pll_clk;
- }
+ if (!rate)
+ return dev_err_probe(dev, -EINVAL,
+ "failed get pll clk rate\n");
}
host = spi_alloc_host(&pdev->dev, sizeof(*bs));
- if (!host) {
- ret = -ENOMEM;
- goto out_disable_pll_clk;
- }
+ if (!host)
+ return dev_err_probe(dev, -ENOMEM, "alloc host no mem\n");
bs = spi_controller_get_devdata(host);
bs->pdev = pdev;
@@ -873,7 +857,7 @@ static int bcm63xx_hsspi_probe(struct platform_device *pdev)
}
/* register and we are done */
- ret = devm_spi_register_controller(dev, host);
+ ret = spi_register_controller(host);
if (ret)
goto out_sysgroup_disable;
@@ -887,10 +871,6 @@ out_pm_disable:
pm_runtime_disable(&pdev->dev);
out_put_host:
spi_controller_put(host);
-out_disable_pll_clk:
- clk_disable_unprepare(pll_clk);
-out_disable_clk:
- clk_disable_unprepare(clk);
return ret;
}
@@ -900,11 +880,15 @@ static void bcm63xx_hsspi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev