summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);
struct bcm63xx_hsspi *bs = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
/* reset the hardware and block queue progress */
__raw_writel(0, bs->regs + HSSPI_INT_MASK_REG);
- clk_disable_unprepare(bs->pll_clk);
- clk_disable_unprepare(bs->clk);
sysfs_remove_group(&pdev->dev.kobj, &bcm63xx_hsspi_group);
+
+ spi_controller_put(host);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c
index 47266bb23a33..40cd7efc4b54 100644
--- a/drivers/spi/spi-bcm63xx.c
+++ b/drivers/spi/spi-bcm63xx.c
@@ -602,7 +602,7 @@ static int bcm63xx_spi_probe(struct platform_device *pdev)
goto out_clk_disable;
/* register and we are done */
- ret = devm_spi_register_controller(dev, host);
+ ret = spi_register_controller(host);
if (ret) {
dev_err(dev, "spi register failed\n");
goto out_clk_disable;
@@ -625,11 +625,17 @@ static void bcm63xx_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct bcm63xx_spi *bs = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
/* reset spi block */
bcm_spi_writeb(bs, 0, SPI_INT_MASK);
/* HW shutdown */
clk_disable_unprepare(bs->clk);
+
+ spi_controller_put(host);
}
static int bcm63xx_spi_suspend(struct device *dev)
diff --git a/drivers/spi/spi-bcmbca-hsspi.c b/drivers/spi/spi-bcmbca-hsspi.c
index ece22260f570..09c1472ae4fa 100644
--- a/drivers/spi/spi-bcmbca-hsspi.c
+++ b/drivers/spi/spi-bcmbca-hsspi.c
@@ -452,39 +452,30 @@ static int bcmbca_hsspi_probe(struct platform_device *pdev)
if (IS_ERR(spim_ctrl))
return PTR_ERR(spim_ctrl);
- clk = devm_clk_get(dev, "hsspi");
+ clk = devm_clk_get_enabled(dev, "hsspi");
if (IS_ERR(clk))
- return PTR_ERR(clk);
-
- ret = clk_prepare_enable(clk);
- if (ret)
- return ret;
+ return dev_err_probe(dev, PTR_ERR(clk),
+ "Failed to get hsspi clock\n");
rate = clk_get_rate(clk);
if (!rate) {
- pll_clk = devm_clk_get(dev, "pll");
+ pll_clk = devm_clk_get_enabled(dev, "pll");
if (IS_ERR(pll_clk)) {
- ret = PTR_ERR(pll_clk);
- goto out_disable_clk;
+ return dev_err_probe(dev, PTR_ERR(pll_clk),
+ "Failed to get pll clock\n");
}
- ret = clk_prepare_enable(pll_clk);
- if (ret)
- goto out_disable_clk;
-
rate = clk_get_rate(pll_clk);
- if (!rate) {
- ret = -EINVAL;
- goto out_disable_pll_clk;
- }
+ if (!rate)
+ return dev_err_probe(dev, -EINVAL,
+ "Failed to get pll clock rate\n");
}
host = devm_spi_alloc_host(&pdev->dev, sizeof(*bs));
- if (!host) {
- ret = -ENOMEM;
- goto out_disable_pll_clk;
- }
+ if (!host)
+ return dev_err_probe(dev, -ENOMEM,
+ "Failed alloc spi host\n");
bs = spi_controller_get_devdata(host);
bs->pdev = pdev;
@@ -535,21 +526,19 @@ static int bcmbca_hsspi_probe(struct platform_device *pdev)
ret = devm_request_irq(dev, irq, bcmbca_hsspi_interrupt, IRQF_SHARED,
pdev->name, bs);
if (ret)
- goto out_disable_pll_clk;
+ return dev_err_probe(dev, ret, "Failed request irq\n");
}
ret = devm_pm_runtime_enable(&pdev->dev);
if (ret)
- goto out_disable_pll_clk;
+ return dev_err_probe(dev, ret, "Failed pm runtime enable\n");
ret = sysfs_create_group(&pdev->dev.kobj, &bcmbca_hsspi_group);
- if (ret) {
- dev_err(&pdev->dev, "couldn't register sysfs group\n");
- goto out_disable_pll_clk;
- }
+ if (ret)
+ return dev_err_probe(dev, ret, "couldn't register sysfs group\n");
/* register and we are done */
- ret = devm_spi_register_controller(dev, host);
+ ret = spi_register_controller(host);
if (ret)
goto out_sysgroup_disable;
@@ -559,10 +548,6 @@ static int bcmbca_hsspi_probe(struct platform_device *pdev)
out_sysgroup_disable:
sysfs_remove_group(&pdev->dev.kobj, &bcmbca_hsspi_group);
-out_disable_pll_clk:
- clk_disable_unprepare(pll_clk);
-out_disable_clk:
- clk_disable_unprepare(clk);
return ret;
}
@@ -571,10 +556,10 @@ static void bcmbca_hsspi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct bcmbca_hsspi *bs = spi_controller_get_devdata(host);
+ spi_unregister_controller(host);
+
/* reset the hardware and block queue progress */
__raw_writel(0, bs->regs + HSSPI_INT_MASK_REG);
- clk_disable_unprepare(bs->pll_clk);
- clk_disable_unprepare(bs->clk);
sysfs_remove_group(&pdev->dev.kobj, &bcmbca_hsspi_group);
}
diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c
index 2ead419e896e..b6f7f95e8bd3 100644
--- a/drivers/spi/spi-cadence-quadspi.c
+++ b/drivers/spi/spi-cadence-quadspi.c
@@ -1544,10 +1544,6 @@ static bool cqspi_supports_mem_op(struct spi_mem *mem,
if (op->data.nbytes && op->data.buswidth != 8)
return false;
- /* A single opcode is supported, it will be repeated */
- if ((op->cmd.opcode >> 8) != (op->cmd.opcode & 0xFF))
- return false;
-
if (cqspi->is_rzn1)
return false;
} else if (!all_false) {
diff --git a/drivers/spi/spi-cavium-octeon.c b/drivers/spi/spi-cavium-octeon.c
index 155085a053a1..b95bfa6a3013 100644
--- a/drivers/spi/spi-cavium-octeon.c
+++ b/drivers/spi/spi-cavium-octeon.c
@@ -54,7 +54,7 @@ static int octeon_spi_probe(struct platform_device *pdev)
host->bits_per_word_mask = SPI_BPW_MASK(8);
host->max_speed_hz = OCTEON_SPI_MAX_CLOCK_HZ;
- err = devm_spi_register_controller(&pdev->dev, host);
+ err = spi_register_controller(host);
if (err) {
dev_err(&pdev->dev, "register host failed: %d\n", err);
goto fail;
@@ -73,8 +73,14 @@ static void octeon_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct octeon_spi *p = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
/* Clear the CSENA* and put everything in a known state. */
writeq(0, p->register_base + OCTEON_SPI_CFG(p));
+
+ spi_controller_put(host);
}
static const struct of_device_id octeon_spi_match[] = {
diff --git a/drivers/spi/spi-cavium-thunderx.c b/drivers/spi/spi-cavium-thunderx.c
index 99aac40a1bba..f1a9aa696c87 100644
--- a/drivers/spi/spi-cavium-thunderx.c
+++ b/drivers/spi/spi-cavium-thunderx.c
@@ -70,7 +70,7 @@ static int thunderx_spi_probe(struct pci_dev *pdev,
pci_set_drvdata(pdev, host);
- ret = devm_spi_register_controller(dev, host);
+ ret = spi_register_controller(host);
if (ret)
goto error;
@@ -90,8 +90,14 @@ static void thunderx_spi_remove(struct pci_dev *pdev)
if (!p)
return;
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
/* Put everything in a known state. */
writeq(0, p->register_base + OCTEON_SPI_CFG(p));
+
+ spi_controller_put(host);
}
static const struct pci_device_id thunderx_spi_pci_id_table[] = {
diff --git a/drivers/spi/spi-ch341.c b/drivers/spi/spi-ch341.c
index 79d2f9ab4ef0..3eaa8f176f63 100644
--- a/drivers/spi/spi-ch341.c
+++ b/drivers/spi/spi-ch341.c
@@ -152,7 +152,7 @@ static int ch341_probe(struct usb_interface *intf,
if (ret)
return ret;
- ctrl = devm_spi_alloc_host(&udev->dev, sizeof(struct ch341_spi_dev));
+ ctrl = devm_spi_alloc_host(&intf->dev, sizeof(struct ch341_spi_dev));
if (!ctrl)
return -ENOMEM;
@@ -163,7 +163,7 @@ static int ch341_probe(struct usb_interface *intf,
ch341->read_pipe = usb_rcvbulkpipe(udev, usb_endpoint_num(in));
ch341->rx_len = usb_endpoint_maxp(in);
- ch341->rx_buf = devm_kzalloc(&udev->dev, ch341->rx_len, GFP_KERNEL);
+ ch341->rx_buf = devm_kzalloc(&intf->dev, ch341->rx_len, GFP_KERNEL);
if (!ch341->rx_buf)
return -ENOMEM;
@@ -171,19 +171,18 @@ static int ch341_probe(struct usb_interface *intf,
if (!ch341->rx_urb)
return -ENOMEM;
- ch341->tx_buf =
- devm_kzalloc(&udev->dev, CH341_PACKET_LENGTH, GFP_KERNEL);
- if (!ch341->tx_buf)
- return -ENOMEM;
+ ch341->tx_buf = devm_kzalloc(&intf->dev, CH341_PACKET_LENGTH, GFP_KERNEL);
+ if (!ch341->tx_buf) {
+ ret = -ENOMEM;
+ goto err_free_urb;
+ }
usb_fill_bulk_urb(ch341->rx_urb, udev, ch341->read_pipe, ch341->rx_buf,
ch341->rx_len, ch341_recv, ch341);
ret = usb_submit_urb(ch341->rx_urb, GFP_KERNEL);
- if (ret) {
- usb_free_urb(ch341->rx_urb);
- return -ENOMEM;
- }
+ if (ret)
+ goto err_free_urb;
ctrl->bus_num = -1;
ctrl->mode_bits = SPI_CPHA;
@@ -195,21 +194,34 @@ static int ch341_probe(struct usb_interface *intf,
ret = ch341_config_stream(ch341);
if (ret)
- return ret;
+ goto err_kill_urb;
ret = ch341_enable_pins(ch341, true);
if (ret)
- return ret;
+ goto err_kill_urb;
ret = spi_register_controller(ctrl);
if (ret)
- return ret;
+ goto err_disable_pins;
ch341->spidev = spi_new_device(ctrl, &chip);
- if (!ch341->spidev)
- return -ENOMEM;
+ if (!ch341->spidev) {
+ ret = -ENOMEM;
+ goto err_unregister;
+ }
return 0;
+
+err_unregister:
+ spi_unregister_controller(ctrl);
+err_disable_pins:
+ ch341_enable_pins(ch341, false);
+err_kill_urb:
+ usb_kill_urb(ch341->rx_urb);
+err_free_urb:
+ usb_free_urb(ch341->rx_urb);
+
+ return ret;
}
static void ch341_disconnect(struct usb_interface *intf)
@@ -219,6 +231,7 @@ static void ch341_disconnect(struct usb_interface *intf)
spi_unregister_device(ch341->spidev);
spi_unregister_controller(ch341->ctrl);
ch341_enable_pins(ch341, false);
+ usb_kill_urb(ch341->rx_urb);
usb_free_urb(ch341->rx_urb);
}
diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c
index fdf37636cb9f..b45f44de85dc 100644
--- a/drivers/spi/spi-coldfire-qspi.c
+++ b/drivers/spi/spi-coldfire-qspi.c
@@ -410,9 +410,9 @@ static int mcfqspi_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, host);
pm_runtime_enable(&pdev->dev);
- status = devm_spi_register_controller(&pdev->dev, host);
+ status = spi_register_controller(host);
if (status) {
- dev_dbg(&pdev->dev, "devm_spi_register_controller failed\n");
+ dev_dbg(&pdev->dev, "failed to register controller\n");
goto fail1;
}
@@ -436,11 +436,17 @@ static void mcfqspi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct mcfqspi *mcfqspi = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
pm_runtime_disable(&pdev->dev);
/* disable the hardware (set the baud rate to 0) */
mcfqspi_wr_qmr(mcfqspi, MCFQSPI_QMR_MSTR);
mcfqspi_cs_teardown(mcfqspi);
+
+ spi_controller_put(host);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-cs42l43.c b/drivers/spi/spi-cs42l43.c
index a4a650c8d740..68f208ef1e01 100644
--- a/drivers/spi/spi-cs42l43.c
+++ b/drivers/spi/spi-cs42l43.c
@@ -367,10 +367,10 @@ static int cs42l43_spi_probe(struct platform_device *pdev)
ret = devm_add_action_or_reset(priv->dev, cs42l43_release_of_node, fwnode);
if (ret)
return ret;
+ } else {
+ fwnode_property_read_u32(xu_fwnode, "01fa-sidecar-instances", &nsidecars);
}
- fwnode_property_read_u32(xu_fwnode, "01fa-sidecar-instances", &nsidecars);
-
/*
* Depending on the value of nsidecars we either create a software node
* or assign an fwnode. We don't want software node to be attached to
diff --git a/drivers/spi/spi-dln2.c b/drivers/spi/spi-dln2.c
index d90282960ab6..392f0d05f508 100644
--- a/drivers/spi/spi-dln2.c
+++ b/drivers/spi/spi-dln2.c
@@ -758,7 +758,7 @@ static int dln2_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 < 0) {
dev_err(&pdev->dev, "Failed to register host\n");
goto exit_register;
@@ -783,10 +783,16 @@ static void dln2_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct dln2_spi *dln2 = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
pm_runtime_disable(&pdev->dev);
if (dln2_spi_enable(dln2, false) < 0)
dev_err(&pdev->dev, "Failed to disable SPI module\n");
+
+ spi_controller_put(host);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c
index 90d5f3ea6508..db50018050e5 100644
--- a/drivers/spi/spi-ep93xx.c
+++ b/drivers/spi/spi-ep93xx.c
@@ -689,7 +689,7 @@ static int ep93xx_spi_probe(struct platform_device *pdev)
/* make sure that the hardware is disabled */
writel(0, espi->mmio + SSPCR1);
- error = devm_spi_register_controller(&pdev->dev, host);
+ error = spi_register_controller(host);
if (error) {
dev_err(&pdev->dev, "failed to register SPI host\n");
goto fail_free_dma;
@@ -713,7 +713,13 @@ static void ep93xx_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct ep93xx_spi *espi = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
ep93xx_spi_release_dma(espi);
+
+ spi_controller_put(host);
}
static const struct of_device_id ep93xx_spi_of_ids[] = {
diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 56270f8fdc17..45b9974ae911 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -718,7 +718,7 @@ static int fsl_espi_probe(struct device *dev, struct resource *mem,
pm_runtime_enable(dev);
pm_runtime_get_sync(dev);
- ret = devm_spi_register_controller(dev, host);
+ ret = spi_register_controller(host);
if (ret < 0)
goto err_pm;
@@ -782,7 +782,15 @@ static int of_fsl_espi_probe(struct platform_device *ofdev)
static void of_fsl_espi_remove(struct platform_device *dev)
{
+ struct spi_controller *host = platform_get_drvdata(dev);
+
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
pm_runtime_disable(&dev->dev);
+
+ spi_controller_put(host);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-fsl-lpspi.c b/drivers/spi/spi-fsl-lpspi.c
index 45390e9b8cae..e201309f8aae 100644
--- a/drivers/spi/spi-fsl-lpspi.c
+++ b/drivers/spi/spi-fsl-lpspi.c
@@ -75,14 +75,20 @@
#define CFGR1_PCSPOL_MASK GENMASK(11, 8)
#define CFGR1_NOSTALL BIT(3)
#define CFGR1_HOST BIT(0)
+#define FCR_RXWATER GENMASK(18, 16)
+#define FCR_TXWATER GENMASK(2, 0)
#define FSR_TXCOUNT (0xFF)
#define RSR_RXEMPTY BIT(1)
#define TCR_CPOL BIT(31)
#define TCR_CPHA BIT(30)
+#define TCR_MODE GENMASK(31, 30)
+#define TCR_PRESCALE GENMASK(29, 27)
+#define TCR_PCS GENMASK(25, 24)
#define TCR_CONT BIT(21)
#define TCR_CONTC BIT(20)
#define TCR_RXMSK BIT(19)
#define TCR_TXMSK BIT(18)
+#define TCR_FRAMESZ GENMASK(11, 0)
#define SR_CLEAR_MASK GENMASK(13, 8)
@@ -95,7 +101,7 @@ struct lpspi_config {
u8 bpw;
u8 chip_select;
u8 prescale;
- u16 mode;
+ u32 mode;
u32 speed_hz;
u32 effective_speed_hz;
};
@@ -112,8 +118,8 @@ struct fsl_lpspi_data {
void *rx_buf;
const void *tx_buf;
- void (*tx)(struct fsl_lpspi_data *);
- void (*rx)(struct fsl_lpspi_data *);
+ void (*tx)(struct fsl_lpspi_data *fsl_lpspi);
+ void (*rx)(struct fsl_lpspi_data *fsl_lpspi);
u32 remain;
u8 watermark;
@@ -256,9 +262,7 @@ static void fsl_lpspi_write_tx_fifo(struct fsl_lpspi_data *fsl_lpspi)
txfifo_cnt = readl(fsl_lpspi->base + IMX7ULP_FSR) & 0xff;
- while (txfifo_cnt < fsl_lpspi->txfifosize) {
- if (!fsl_lpspi->remain)
- break;
+ while (txfifo_cnt < fsl_lpspi->txfifosize && fsl_lpspi->remain) {
fsl_lpspi->tx(fsl_lpspi);
txfifo_cnt++;
}
@@ -271,8 +275,9 @@ static void fsl_lpspi_write_tx_fifo(struct fsl_lpspi_data *fsl_lpspi)
}
fsl_lpspi_intctrl(fsl_lpspi, IER_FCIE);
- } else
+ } else {
fsl_lpspi_intctrl(fsl_lpspi, IER_TDIE);
+ }
}
static void fsl_lpspi_read_rx_fifo(struct fsl_lpspi_data *fsl_lpspi)
@@ -281,16 +286,14 @@ static void fsl_lpspi_read_rx_fifo(struct fsl_lpspi_data *fsl_lpspi)
fsl_lpspi->rx(fsl_lpspi);
}
-static void fsl_lpspi_set_cmd(struct fsl_lpspi_data *fsl_lpspi,
- struct spi_device *spi)
+static void fsl_lpspi_set_cmd(struct fsl_lpspi_data *fsl_lpspi)
{
u32 temp = 0;
- temp |= fsl_lpspi->config.bpw - 1;
- temp |= (fsl_lpspi->config.mode & 0x3) << 30;
- temp |= (fsl_lpspi->config.chip_select & 0x3) << 24;
+ temp |= FIELD_PREP(TCR_FRAMESZ, fsl_lpspi->config.bpw - 1);
+ temp |= FIELD_PREP(TCR_PCS, fsl_lpspi->config.chip_select);
if (!fsl_lpspi->is_target) {
- temp |= fsl_lpspi->config.prescale << 27;
+ temp |= FIELD_PREP(TCR_PRESCALE, fsl_lpspi->config.prescale);
/*
* Set TCR_CONT will keep SS asserted after current transfer.
* For the first transfer, clear TCR_CONTC to assert SS.
@@ -305,10 +308,10 @@ static void fsl_lpspi_set_cmd(struct fsl_lpspi_data *fsl_lpspi,
}
}
- if (spi->mode & SPI_CPOL)
+ if (fsl_lpspi->config.mode & SPI_CPOL)
temp |= TCR_CPOL;
- if (spi->mode & SPI_CPHA)
+ if (fsl_lpspi->config.mode & SPI_CPHA)
temp |= TCR_CPHA;
writel(temp, fsl_lpspi->base + IMX7ULP_TCR);
@@ -318,17 +321,18 @@ static void fsl_lpspi_set_cmd(struct fsl_lpspi_data *fsl_lpspi,
static void fsl_lpspi_set_watermark(struct fsl_lpspi_data *fsl_lpspi)
{
+ u8 watermark = fsl_lpspi->watermark >> 1;
u32 temp;
if (!fsl_lpspi->usedma)
- temp = fsl_lpspi->watermark >> 1 |
- (fsl_lpspi->watermark >> 1) << 16;
+ temp = FIELD_PREP(FCR_TXWATER, watermark) |
+ FIELD_PREP(FCR_RXWATER, watermark);
else
- temp = fsl_lpspi->watermark >> 1;
+ temp = FIELD_PREP(FCR_TXWATER, watermark);
writel(temp, fsl_lpspi->base + IMX7ULP_FCR);
- dev_dbg(fsl_lpspi->dev, "FCR=0x%x\n", temp);
+ dev_dbg(fsl_lpspi->dev, "FCR=0x%08x\n", temp);
}
static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi)
@@ -348,11 +352,10 @@ static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi)
return -EINVAL;
}
- if (config.speed_hz > perclk_rate / 2) {
+ if (config.speed_hz > perclk_rate / 2)
div = 2;
- } else {
+ else
div = DIV_ROUND_UP(perclk_rate, config.speed_hz);
- }
for (prescale = 0; prescale <= prescale_max; prescale++) {
scldiv = div / (1 << prescale) - 2;
@@ -466,9 +469,6 @@ static int fsl_lpspi_setup_transfer(struct spi_controller *controller,
struct fsl_lpspi_data *fsl_lpspi =
spi_controller_get_devdata(spi->controller);
- if (t == NULL)
- return -EINVAL;
-
fsl_lpspi->config.mode = spi->mode;
fsl_lpspi->config.bpw = t->bits_per_word;
fsl_lpspi->config.speed_hz = t->speed_hz;
@@ -517,15 +517,12 @@ static int fsl_lpspi_prepare_message(struct spi_controller *controller,
fsl_lpspi->usedma = false;
ret = fsl_lpspi_setup_transfer(controller, spi, t);
- if (fsl_lpspi_can_dma(controller, spi, t))
- fsl_lpspi->usedma = true;
- else
- fsl_lpspi->usedma = false;
+ fsl_lpspi->usedma = fsl_lpspi_can_dma(controller, spi, t);
if (ret < 0)
return ret;
- fsl_lpspi_set_cmd(fsl_lpspi, spi);
+ fsl_lpspi_set_cmd(fsl_lpspi);
/* No IRQs */
writel(0, fsl_lpspi->base + IMX7ULP_IER);
@@ -574,7 +571,7 @@ static int fsl_lpspi_wait_for_completion(struct spi_controller *controller)
return 0;
}
-static int fsl_lpspi_reset(struct fsl_lpspi_data *fsl_lpspi)
+static void fsl_lpspi_reset(struct fsl_lpspi_data *fsl_lpspi)
{
u32 temp;
@@ -589,8 +586,6 @@ static int fsl_lpspi_reset(struct fsl_lpspi_data *fsl_lpspi)
/* W1C for all flags in SR */
writel(SR_CLEAR_MASK, fsl_lpspi->base + IMX7ULP_SR);
-
- return 0;
}
static void fsl_lpspi_dma_rx_callback(void *cookie)
@@ -794,10 +789,7 @@ static int fsl_lpspi_transfer_one(struct spi_controller *controller,
spi_controller_get_devdata(controller);
int ret;
- if (fsl_lpspi_can_dma(controller, spi, t))
- fsl_lpspi->usedma = true;
- else
- fsl_lpspi->usedma = false;
+ fsl_lpspi->usedma = fsl_lpspi_can_dma(controller, spi, t);
ret = fsl_lpspi_setup_transfer(controller, spi, t);
if (ret < 0)
@@ -805,7 +797,7 @@ static int fsl_lpspi_transfer_one(struct spi_controller *controller,
t->effective_speed_hz = fsl_lpspi->config.effective_speed_hz;
- fsl_lpspi_set_cmd(fsl_lpspi, spi);
+ fsl_lpspi_set_cmd(fsl_lpspi);
fsl_lpspi->is_first_byte = false;
if (fsl_lpspi->usedma)
diff --git a/drivers/spi/spi-fsl-qspi.c b/drivers/spi/spi-fsl-qspi.c
index a223b4bc6e63..57358851029b 100644
--- a/drivers/spi/spi-fsl-qspi.c
+++ b/drivers/spi/spi-fsl-qspi.c
@@ -633,7 +633,7 @@ static int fsl_qspi_do_op(struct fsl_qspi *q, const struct spi_mem_op *op)
void __iomem *base = q->iobase;
int err = 0;
- init_completion(&q->c);
+ reinit_completion(&q->c);
/*
* Always start the sequence at the same index since we update
@@ -965,6 +965,7 @@ static int fsl_qspi_probe(struct platform_device *pdev)
if (ret < 0)
return ret;
+ init_completion(&q->c);
ret = devm_request_irq(dev, ret,
fsl_qspi_irq_handler, 0, pdev->name, q);
if (ret) {
diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c
index bf3fc3ce0cc2..1252c41c206f 100644
--- a/drivers/spi/spi-fsl-spi.c
+++ b/drivers/spi/spi-fsl-spi.c
@@ -614,7 +614,7 @@ static struct spi_controller *fsl_spi_probe(struct device *dev,
mpc8xxx_spi_write_reg(&reg_base->mode, regval);
- ret = devm_spi_register_controller(dev, host);
+ ret = spi_register_controller(host);
if (ret < 0)
goto err_probe;
@@ -705,7 +705,13 @@ static void of_fsl_spi_remove(struct platform_device *ofdev)
struct spi_controller *host = platform_get_drvdata(ofdev);
struct mpc8xxx_spi *mpc8xxx_spi = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
fsl_spi_cpm_free(mpc8xxx_spi);
+
+ spi_controller_put(host);
}
static struct platform_driver of_fsl_spi_driver = {
@@ -751,7 +757,13 @@ static void plat_mpc8xxx_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct mpc8xxx_spi *mpc8xxx_spi = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
fsl_spi_cpm_free(mpc8xxx_spi);
+
+ spi_controller_put(host);
}
MODULE_ALIAS("platform:mpc8xxx_spi");
diff --git a/drivers/spi/spi-hisi-kunpeng.c b/drivers/spi/spi-hisi-kunpeng.c
index 216a0a91fc47..046bd894040b 100644
--- a/drivers/spi/spi-hisi-kunpeng.c
+++ b/drivers/spi/spi-hisi-kunpeng.c
@@ -196,9 +196,22 @@ static void hisi_spi_flush_fifo(struct hisi_spi *hs)
unsigned long limit = loops_per_jiffy << 1;
do {
- while (hisi_spi_rx_not_empty(hs))
+ unsigned long inner_limit = loops_per_jiffy;
+
+ while (hisi_spi_rx_not_empty(hs) && --inner_limit) {
readl(hs->regs + HISI_SPI_DOUT);
- } while (hisi_spi_busy(hs) && limit--);
+ cpu_relax();
+ }
+
+ if (!inner_limit) {
+ dev_warn_ratelimited(hs->dev, "RX FIFO flush timeout\n");
+ break;
+ }
+
+ } while (hisi_spi_busy(hs) && --limit);
+
+ if (!limit)
+ dev_warn_ratelimited(hs->dev, "SPI busy timeout\n");
}
/* Disable the controller and all interrupts */
diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c
index 902fb64815c9..57625a3ce2f2 100644
--- a/drivers/spi/spi-img-spfi.c
+++ b/drivers/spi/spi-img-spfi.c
@@ -643,7 +643,7 @@ static int img_spfi_probe(struct platform_device *pdev)
pm_runtime_set_active(spfi->dev);
pm_runtime_enable(spfi->dev);
- ret = devm_spi_register_controller(spfi->dev, host);
+ ret = spi_register_controller(host);
if (ret)
goto disable_pm;
@@ -669,6 +669,10 @@ static void img_spfi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct img_spfi *spfi = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
if (spfi->tx_ch)
dma_release_channel(spfi->tx_ch);
if (spfi->rx_ch)
@@ -679,6 +683,8 @@ static void img_spfi_remove(struct platform_device *pdev)
clk_disable_unprepare(spfi->spfi_clk);
clk_disable_unprepare(spfi->sys_clk);
}
+
+ spi_controller_put(host);
}
#ifdef CONFIG_PM
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c
index 64c6c09e1e7b..4747899e0646 100644
--- a/drivers/spi/spi-imx.c
+++ b/drivers/spi/spi-imx.c
@@ -2231,11 +2231,9 @@ static int spi_imx_probe(struct platform_device *pdev)
target_mode = devtype_data->has_targetmode &&
of_property_read_bool(np, "spi-slave");
if (target_mode)
- controller = spi_alloc_target(&pdev->dev,
- sizeof(struct spi_imx_data));
+ controller = devm_spi_alloc_target(&pdev->dev, sizeof(*spi_imx));
else
- controller = spi_alloc_host(&pdev->dev,
- sizeof(struct spi_imx_data));
+ controller = devm_spi_alloc_host(&pdev->dev, sizeof(*spi_imx));
if (!controller)
return -ENOMEM;
@@ -2304,40 +2302,31 @@ static int spi_imx_probe(struct platform_device *pdev)
init_completion(&spi_imx->xfer_done);
spi_imx->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
- if (IS_ERR(spi_imx->base)) {
- ret = PTR_ERR(spi_imx->base);
- goto out_controller_put;
- }
+ if (IS_ERR(spi_imx->base))
+ return PTR_ERR(spi_imx->base);
+
spi_imx->base_phys = res->start;
irq = platform_get_irq(pdev, 0);
- if (irq < 0) {
- ret = irq;
- goto out_controller_put;
- }
+ if (irq < 0)
+ return irq;
ret = devm_request_irq(&pdev->dev, irq, spi_imx_isr, 0,
dev_name(&pdev->dev), spi_imx);
- if (ret) {
- dev_err(&pdev->dev, "can't get irq%d: %d\n", irq, ret);
- goto out_controller_put;
- }
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "can't get irq%d\n", irq);
spi_imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
- if (IS_ERR(spi_imx->clk_ipg)) {
- ret = PTR_ERR(spi_imx->clk_ipg);
- goto out_controller_put;
- }
+ if (IS_ERR(spi_imx->clk_ipg))
+ return PTR_ERR(spi_imx->clk_ipg);
spi_imx->clk_per = devm_clk_get(&pdev->dev, "per");
- if (IS_ERR(spi_imx->clk_per)) {
- ret = PTR_ERR(spi_imx->clk_per);
- goto out_controller_put;
- }
+ if (IS_ERR(spi_imx->clk_per))
+ return PTR_ERR(spi_imx->clk_per);
ret = clk_prepare_enable(spi_imx->clk_per);
if (ret)
- goto out_controller_put;
+ return ret;
ret = clk_prepare_enable(spi_imx->clk_ipg);
if (ret)
@@ -2389,8 +2378,6 @@ out_runtime_pm_put:
clk_disable_unprepare(spi_imx->clk_ipg);
out_put_per:
clk_disable_unprepare(spi_imx->clk_per);
-out_controller_put:
- spi_controller_put(controller);
return ret;
}
diff --git a/drivers/spi/spi-lantiq-ssc.c b/drivers/spi/spi-lantiq-ssc.c
index f83cb63c9d0c..75b9af8cb5db 100644
--- a/drivers/spi/spi-lantiq-ssc.c
+++ b/drivers/spi/spi-lantiq-ssc.c
@@ -994,7 +994,7 @@ static int lantiq_ssc_probe(struct platform_device *pdev)
"Lantiq SSC SPI controller (Rev %i, TXFS %u, RXFS %u, DMA %u)\n",
revision, spi->tx_fifo_size, spi->rx_fifo_size, supports_dma);
- err = devm_spi_register_controller(dev, host);
+ err = spi_register_controller(host);
if (err) {
dev_err(dev, "failed to register spi host\n");
goto err_wq_destroy;
@@ -1016,6 +1016,10 @@ static void lantiq_ssc_remove(struct platform_device *pdev)
{
struct lantiq_ssc_spi *spi = platform_get_drvdata(pdev);
+ spi_controller_get(spi->host);
+
+ spi_unregister_controller(spi->host);
+
lantiq_ssc_writel(spi, 0, LTQ_SPI_IRNEN);
lantiq_ssc_writel(spi, 0, LTQ_SPI_CLC);
rx_fifo_flush(spi);
@@ -1024,6 +1028,8 @@ static void lantiq_ssc_remove(struct platform_device *pdev)
destroy_workqueue(spi->wq);
clk_put(spi->fpi_clk);
+
+ spi_controller_put(spi->host);
}
static struct platform_driver lantiq_ssc_driver = {
diff --git a/drivers/spi/spi-meson-spicc.c b/drivers/spi/spi-meson-spicc.c
index 57768da3205d..b80f9f457b66 100644
--- a/drivers/spi/spi-meson-spicc.c
+++ b/drivers/spi/spi-meson-spicc.c
@@ -1081,7 +1081,7 @@ static int meson_spicc_probe(struct platform_device *pdev)
}
}
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret) {
dev_err(&pdev->dev, "spi registration failed\n");
goto out_host;
@@ -1099,8 +1099,14 @@ static void meson_spicc_remove(struct platform_device *pdev)
{
struct meson_spicc_device *spicc = platform_get_drvdata(pdev);
+ spi_controller_get(spicc->host);
+
+ spi_unregister_controller(spicc->host);
+
/* Disable SPI */
writel(0, spicc->base + SPICC_CONREG);
+
+ spi_controller_put(spicc->host);
}
static const struct meson_spicc_data meson_spicc_gx_data = {
diff --git a/drivers/spi/spi-microchip-core-qspi.c b/drivers/spi/spi-microchip-core-qspi.c
index aafe6cbf2aea..eab059fb0bc2 100644
--- a/drivers/spi/spi-microchip-core-qspi.c
+++ b/drivers/spi/spi-microchip-core-qspi.c
@@ -692,7 +692,7 @@ static int mchp_coreqspi_probe(struct platform_device *pdev)
return -ENOMEM;
qspi = spi_controller_get_devdata(ctlr);
- platform_set_drvdata(pdev, qspi);
+ platform_set_drvdata(pdev, ctlr);
qspi->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(qspi->regs))
@@ -732,7 +732,7 @@ static int mchp_coreqspi_probe(struct platform_device *pdev)
ctlr->num_chipselect = 2;
ctlr->use_gpio_descriptors = true;
- ret = devm_spi_register_controller(&pdev->dev, ctlr);
+ ret = spi_register_controller(ctlr);
if (ret)
return dev_err_probe(&pdev->dev, ret,
"spi_register_controller failed\n");
@@ -742,9 +742,13 @@ static int mchp_coreqspi_probe(struct platform_device *pdev)
static void mchp_coreqspi_remove(struct platform_device *pdev)
{
- struct mchp_coreqspi *qspi = platform_get_drvdata(pdev);
- u32 control = readl_relaxed(qspi->regs + REG_CONTROL);
+ struct spi_controller *ctlr = platform_get_drvdata(pdev);
+ struct mchp_coreqspi *qspi = spi_controller_get_devdata(ctlr);
+ u32 control;
+ spi_unregister_controller(ctlr);
+
+ control = readl_relaxed(qspi->regs + REG_CONTROL);
mchp_coreqspi_disable_ints(qspi);
control &= ~CONTROL_ENABLE;
writel_relaxed(control, qspi->regs + REG_CONTROL);
diff --git a/drivers/spi/spi-microchip-core-spi.c b/drivers/spi/spi-microchip-core-spi.c
index a4c128ae391b..be01c178e2b0 100644
--- a/drivers/spi/spi-microchip-core-spi.c
+++ b/drivers/spi/spi-microchip-core-spi.c
@@ -384,7 +384,7 @@ static int mchp_corespi_probe(struct platform_device *pdev)
mchp_corespi_init(host, spi);
- ret = devm_spi_register_controller(dev, host);
+ ret = spi_register_controller(host);
if (ret) {
mchp_corespi_disable_ints(spi);
mchp_corespi_disable(spi);
@@ -399,6 +399,8 @@ static void mchp_corespi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct mchp_corespi *spi = spi_controller_get_devdata(host);
+ spi_unregister_controller(host);
+
mchp_corespi_disable_ints(spi);
mchp_corespi_disable(spi);
}
diff --git a/drivers/spi/spi-mpfs.c b/drivers/spi/spi-mpfs.c
index 64d15a6188ac..989a379b0700 100644
--- a/drivers/spi/spi-mpfs.c
+++ b/drivers/spi/spi-mpfs.c
@@ -574,7 +574,7 @@ static int mpfs_spi_probe(struct platform_device *pdev)
mpfs_spi_init(host, spi);
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret) {
mpfs_spi_disable_ints(spi);
mpfs_spi_disable(spi);
@@ -592,6 +592,8 @@ static void mpfs_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct mpfs_spi *spi = spi_controller_get_devdata(host);
+ spi_unregister_controller(host);
+
mpfs_spi_disable_ints(spi);
mpfs_spi_disable(spi);
}
diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c
index 0368a26bca9a..96f8555be983 100644
--- a/drivers/spi/spi-mt65xx.c
+++ b/drivers/spi/spi-mt65xx.c
@@ -1325,7 +1325,7 @@ static int mtk_spi_probe(struct platform_device *pdev)
pm_runtime_enable(dev);
- ret = devm_spi_register_controller(dev, host);
+ ret = spi_register_controller(host);
if (ret) {
pm_runtime_disable(dev);
return dev_err_probe(dev, ret, "failed to register host\n");
@@ -1340,6 +1340,8 @@ static void mtk_spi_remove(struct platform_device *pdev)
struct mtk_spi *mdata = spi_controller_get_devdata(host);
int ret;
+ spi_unregister_controller(host);
+
cpu_latency_qos_remove_request(&mdata->qos_request);
if (mdata->use_spimem && !completion_done(&mdata->spimem_done))
complete(&mdata->spimem_done);
diff --git a/drivers/spi/spi-mtk-nor.c b/drivers/spi/spi-mtk-nor.c
index 1e5ec0840174..74f34537b02c 100644
--- a/drivers/spi/spi-mtk-nor.c
+++ b/drivers/spi/spi-mtk-nor.c
@@ -913,7 +913,7 @@ static int mtk_nor_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
pm_runtime_get_noresume(&pdev->dev);
- ret = devm_spi_register_controller(&pdev->dev, ctlr);
+ ret = spi_register_controller(ctlr);
if (ret < 0)
goto err_probe;
@@ -938,6 +938,8 @@ static void mtk_nor_remove(struct platform_device *pdev)
struct spi_controller *ctlr = dev_get_drvdata(&pdev->dev);
struct mtk_nor *sp = spi_controller_get_devdata(ctlr);
+ spi_unregister_controller(ctlr);
+
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
diff --git a/drivers/spi/spi-mtk-snfi.c b/drivers/spi/spi-mtk-snfi.c
index 437edbd658aa..73fa84475f0e 100644
--- a/drivers/spi/spi-mtk-snfi.c
+++ b/drivers/spi/spi-mtk-snfi.c
@@ -1303,6 +1303,13 @@ static const struct spi_controller_mem_caps mtk_snand_mem_caps = {
.ecc = true,
};
+static void mtk_unregister_ecc_engine(void *data)
+{
+ struct nand_ecc_engine *eng = data;
+
+ nand_ecc_unregister_on_host_hw_engine(eng);
+}
+
static irqreturn_t mtk_snand_irq(int irq, void *id)
{
struct mtk_snand *snf = id;
@@ -1443,6 +1450,13 @@ static int mtk_snand_probe(struct platform_device *pdev)
goto release_ecc;
}
+ ret = devm_add_action_or_reset(&pdev->dev, mtk_unregister_ecc_engine,
+ &ms->ecc_eng);
+ if (ret) {
+ dev_err_probe(&pdev->dev, ret, "failed to add ECC unregister action\n");
+ goto release_ecc;
+ }
+
ctlr->num_chipselect = 1;
ctlr->mem_ops = &mtk_snand_mem_ops;
ctlr->mem_caps = &mtk_snand_mem_caps;
diff --git a/drivers/spi/spi-mxs.c b/drivers/spi/spi-mxs.c
index b3301c69e2de..0164e04d59a1 100644
--- a/drivers/spi/spi-mxs.c
+++ b/drivers/spi/spi-mxs.c
@@ -619,7 +619,7 @@ static int mxs_spi_probe(struct platform_device *pdev)
if (ret)
goto out_pm_runtime_put;
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret) {
dev_err(&pdev->dev, "Cannot register SPI host, %d\n", ret);
goto out_pm_runtime_put;
@@ -650,11 +650,17 @@ static void mxs_spi_remove(struct platform_device *pdev)
spi = spi_controller_get_devdata(host);
ssp = &spi->ssp;
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
mxs_spi_runtime_suspend(&pdev->dev);
dma_release_channel(ssp->dmach);
+
+ spi_controller_put(host);
}
static struct platform_driver mxs_spi_driver = {
diff --git a/drivers/spi/spi-npcm-fiu.c b/drivers/spi/spi-npcm-fiu.c
index 3961b0ccdb4b..6617751009c3 100644
--- a/drivers/spi/spi-npcm-fiu.c
+++ b/drivers/spi/spi-npcm-fiu.c
@@ -715,7 +715,6 @@ static int npcm_fiu_probe(struct platform_device *pdev)
fiu->info = &fiu_data_match->npcm_fiu_data_info[id];
- platform_set_drvdata(pdev, fiu);
fiu->dev = dev;
regbase = devm_platform_ioremap_resource_byname(pdev, "control");
@@ -738,8 +737,6 @@ static int npcm_fiu_probe(struct platform_device *pdev)
fiu->spix_mode = of_property_read_bool(dev->of_node,
"nuvoton,spix-mode");
- platform_set_drvdata(pdev, fiu);
-
ctrl->mode_bits = SPI_RX_DUAL | SPI_RX_QUAD
| SPI_TX_DUAL | SPI_TX_QUAD;
ctrl->setup = npcm_fiu_setup;
@@ -750,10 +747,6 @@ static int npcm_fiu_probe(struct platform_device *pdev)
return devm_spi_register_controller(dev, ctrl);
}
-static void npcm_fiu_remove(struct platform_device *pdev)
-{
-}
-
MODULE_DEVICE_TABLE(of, npcm_fiu_dt_ids);
static struct platform_driver npcm_fiu_driver = {
@@ -763,7 +756,6 @@ static struct platform_driver npcm_fiu_driver = {
.of_match_table = npcm_fiu_dt_ids,
},
.probe = npcm_fiu_probe,
- .remove = npcm_fiu_remove,
};
module_platform_driver(npcm_fiu_driver);
diff --git a/drivers/spi/spi-npcm-pspi.c b/drivers/spi/spi-npcm-pspi.c
index e60b3cc398ec..cffef0a5977d 100644
--- a/drivers/spi/spi-npcm-pspi.c
+++ b/drivers/spi/spi-npcm-pspi.c
@@ -413,7 +413,7 @@ static int npcm_pspi_probe(struct platform_device *pdev)
/* set to default clock rate */
npcm_pspi_set_baudrate(priv, NPCM_PSPI_DEFAULT_CLK);
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret)
goto out_disable_clk;
@@ -434,8 +434,14 @@ static void npcm_pspi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct npcm_pspi *priv = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
npcm_pspi_reset_hw(priv);
clk_disable_unprepare(priv->clk);
+
+ spi_controller_put(host);
}
static const struct of_device_id npcm_pspi_match[] = {
diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
index 320b3d93df57..1e36ae084dd8 100644
--- a/drivers/spi/spi-nxp-fspi.c
+++ b/drivers/spi/spi-nxp-fspi.c
@@ -996,7 +996,7 @@ static int nxp_fspi_do_op(struct nxp_fspi *f, const struct spi_mem_op *op)
reg = reg | FSPI_IPRXFCR_CLR;
fspi_writel(f, reg, base + FSPI_IPRXFCR);
- init_completion(&f->c);
+ reinit_completion(&f->c);
fspi_writel(f, op->addr.val, base + FSPI_IPCR0);
/*
@@ -1365,6 +1365,7 @@ static int nxp_fspi_probe(struct platform_device *pdev)
if (ret < 0)
return dev_err_probe(dev, ret, "Failed to disable clock");
+ init_completion(&f->c);
ret = devm_request_irq(dev, irq,
nxp_fspi_irq_handler, 0, pdev->name, f);
if (ret)
diff --git a/drivers/spi/spi-nxp-xspi.c b/drivers/spi/spi-nxp-xspi.c
index 06fcdf22990b..385302a6e62f 100644
--- a/drivers/spi/spi-nxp-xspi.c
+++ b/drivers/spi/spi-nxp-xspi.c
@@ -958,7 +958,7 @@ static int nxp_xspi_do_op(struct nxp_xspi *xspi, const struct spi_mem_op *op)
writel(reg, base + XSPI_RBCT);
}
- init_completion(&xspi->c);
+ reinit_completion(&xspi->c);
/* Config the data address */
writel(op->addr.val + xspi->memmap_phy, base + XSPI_SFP_TG_SFAR);
@@ -1273,6 +1273,7 @@ static int nxp_xspi_probe(struct platform_device *pdev)
nxp_xspi_default_setup(xspi);
+ init_completion(&xspi->c);
ret = devm_request_irq(dev, irq,
nxp_xspi_irq_handler, 0, pdev->name, xspi);
if (ret)
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c
index 2207e05c9d06..56b30ff58771 100644
--- a/drivers/spi/spi-omap2-mcspi.c
+++ b/drivers/spi/spi-omap2-mcspi.c
@@ -942,10 +942,16 @@ static int omap2_mcspi_setup_transfer(struct spi_device *spi,
l = mcspi_cached_chconf0(spi);
- /* standard 4-wire host mode: SCK, MOSI/out, MISO/in, nCS
- * REVISIT: this controller could support SPI_3WIRE mode.
- */
- if (mcspi->pin_dir == MCSPI_PINDIR_D0_IN_D1_OUT) {
+ if (spi->mode & SPI_3WIRE) {
+ if (t && !t->tx_buf) {
+ l &= ~OMAP2_MCSPI_CHCONF_IS;
+ l |= OMAP2_MCSPI_CHCONF_DPE0;
+ } else if (t && !t->rx_buf) {
+ l |= OMAP2_MCSPI_CHCONF_IS;
+ l &= ~OMAP2_MCSPI_CHCONF_DPE0;
+ }
+ l |= OMAP2_MCSPI_CHCONF_DPE1;
+ } else if (mcspi->pin_dir == MCSPI_PINDIR_D0_IN_D1_OUT) {
l &= ~OMAP2_MCSPI_CHCONF_IS;
l &= ~OMAP2_MCSPI_CHCONF_DPE1;
l |= OMAP2_MCSPI_CHCONF_DPE0;
@@ -1178,6 +1184,7 @@ static int omap2_mcspi_transfer_one(struct spi_controller *ctlr,
omap2_mcspi_set_cs(spi, spi->mode & SPI_CS_HIGH);
if (par_override ||
+ (spi->mode & SPI_3WIRE) ||
(t->speed_hz != spi->max_speed_hz) ||
(t->bits_per_word != spi->bits_per_word)) {
par_override = 1;
@@ -1484,7 +1491,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
return -ENOMEM;
/* the spi->mode bits understood by this driver: */
- ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
+ ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_3WIRE;
ctlr->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32);
ctlr->setup = omap2_mcspi_setup;
ctlr->auto_runtime_pm = true;
@@ -1585,7 +1592,7 @@ static int omap2_mcspi_probe(struct platform_device *pdev)
if (status < 0)
goto disable_pm;
- status = devm_spi_register_controller(&pdev->dev, ctlr);
+ status = spi_register_controller(ctlr);
if (status < 0)
goto disable_pm;
@@ -1606,11 +1613,17 @@ static void omap2_mcspi_remove(struct platform_device *pdev)
struct spi_controller *ctlr = platform_get_drvdata(pdev);
struct omap2_mcspi *mcspi = spi_controller_get_devdata(ctlr);
+ spi_controller_get(ctlr);
+
+ spi_unregister_controller(ctlr);
+
omap2_mcspi_release_dma(ctlr);
pm_runtime_dont_use_autosuspend(mcspi->dev);
pm_runtime_put_sync(mcspi->dev);
pm_runtime_disable(&pdev->dev);
+
+ spi_controller_put(ctlr);
}
/* work with hotplug and coldplug */
diff --git a/drivers/spi/spi-pic32-sqi.c b/drivers/spi/spi-pic32-sqi.c
index 051590038895..41662992dbe5 100644
--- a/drivers/spi/spi-pic32-sqi.c
+++ b/drivers/spi/spi-pic32-sqi.c
@@ -642,7 +642,7 @@ static int pic32_sqi_probe(struct platform_device *pdev)
host->prepare_transfer_hardware = pic32_sqi_prepare_hardware;
host->unprepare_transfer_hardware = pic32_sqi_unprepare_hardware;
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret) {
dev_err(&host->dev, "failed registering spi host\n");
free_irq(sqi->irq, sqi);
@@ -665,9 +665,15 @@ static void pic32_sqi_remove(struct platform_device *pdev)
{
struct pic32_sqi *sqi = platform_get_drvdata(pdev);
+ spi_controller_get(sqi->host);
+
+ spi_unregister_controller(sqi->host);
+
/* release resources */
free_irq(sqi->irq, sqi);
ring_desc_ring_free(sqi);
+
+ spi_controller_put(sqi->host);
}
static const struct of_device_id pic32_sqi_of_ids[] = {
diff --git a/drivers/spi/spi-pic32.c b/drivers/spi/spi-pic32.c
index 369850d14313..70427e529945 100644
--- a/drivers/spi/spi-pic32.c
+++ b/drivers/spi/spi-pic32.c
@@ -821,7 +821,7 @@ static int pic32_spi_probe(struct platform_device *pdev)
}
/* register host */
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret) {
dev_err(&host->dev, "failed registering spi host\n");
goto err_bailout;
@@ -840,11 +840,16 @@ err_host:
static void pic32_spi_remove(struct platform_device *pdev)
{
- struct pic32_spi *pic32s;
+ struct pic32_spi *pic32s = platform_get_drvdata(pdev);
+
+ spi_controller_get(pic32s->host);
+
+ spi_unregister_controller(pic32s->host);
- pic32s = platform_get_drvdata(pdev);
pic32_spi_disable(pic32s);
pic32_spi_dma_unprep(pic32s);
+
+ spi_controller_put(pic32s->host);
}
static const struct of_device_id pic32_spi_of_match[] = {
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
index c82cc522776d..9c0211f94fd0 100644
--- a/drivers/spi/spi-pl022.c
+++ b/drivers/spi/spi-pl022.c
@@ -1127,11 +1127,11 @@ static inline void pl022_dma_remove(struct pl022 *pl022)
*
* This function handles interrupts generated for an interrupt based transfer.
* If a receive overrun (ROR) interrupt is there then we disable SSP, flag the
- * current message's state as STATE_ERROR and schedule the tasklet
- * pump_transfers which will do the postprocessing of the current message by
- * calling giveback(). Otherwise it reads data from RX FIFO till there is no
- * more data, and writes data in TX FIFO till it is not full. If we complete
- * the transfer we move to the next transfer and schedule the tasklet.
+ * current transfer with SPI_TRANS_FAIL_IO and call
+ * spi_finalize_current_transfer() to let the core finish the message.
+ * Otherwise it reads data from RX FIFO till there is no more data, and writes
+ * data in TX FIFO till it is not full. When the transfer is complete we call
+ * spi_finalize_current_transfer() so the core can schedule the next one.
*/
static irqreturn_t pl022_interrupt_handler(int irq, void *dev_id)
{
@@ -1956,7 +1956,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
/* Register with the SPI framework */
amba_set_drvdata(adev, pl022);
- status = devm_spi_register_controller(&adev->dev, host);
+ status = spi_register_controller(host);
if (status != 0) {
dev_err_probe(&adev->dev, status,
"problem registering spi host\n");
@@ -1997,6 +1997,10 @@ pl022_remove(struct amba_device *adev)
if (!pl022)
return;
+ spi_controller_get(pl022->host);
+
+ spi_unregister_controller(pl022->host);
+
/*
* undo pm_runtime_put() in probe. I assume that we're not
* accessing the primecell here.
@@ -2008,6 +2012,8 @@ pl022_remove(struct amba_device *adev)
pl022_dma_remove(pl022);
amba_release_regions(adev);
+
+ spi_controller_put(pl022->host);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-pxa2xx-dma.c b/drivers/spi/spi-pxa2xx-dma.c
index 08cb6e96ac94..c94d1d192e74 100644
--- a/drivers/spi/spi-pxa2xx-dma.c
+++ b/drivers/spi/spi-pxa2xx-dma.c
@@ -29,9 +29,9 @@ static void pxa2xx_spi_dma_transfer_complete(struct driver_data *drv_data,
/*
* It is possible that one CPU is handling ROR interrupt and other
- * just gets DMA completion. Calling pump_transfers() twice for the
- * same transfer leads to problems thus we prevent concurrent calls
- * by using dma_running.
+ * just gets DMA completion. Calling spi_finalize_current_transfer()
+ * twice for the same transfer leads to problems thus we prevent
+ * concurrent calls by using dma_running.
*/
if (atomic_dec_and_test(&drv_data->dma_running)) {
/*
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
index f7881a31e4cc..6291d7c2e06f 100644
--- a/drivers/spi/spi-pxa2xx.c
+++ b/drivers/spi/spi-pxa2xx.c
@@ -796,7 +796,7 @@ static irqreturn_t ssp_int(int irq, void *dev_id)
* The function calculates parameters for all cases and chooses the one closest
* to the asked baud rate.
*/
-static unsigned int quark_x1000_get_clk_div(int rate, u32 *dds)
+static unsigned int quark_x1000_get_clk_div(u32 rate, u32 *dds)
{
unsigned long xtal = 200000000;
unsigned long fref = xtal / 2; /* mandatory division by 2,
@@ -885,12 +885,12 @@ static unsigned int quark_x1000_get_clk_div(int rate, u32 *dds)
return q - 1;
}
-static unsigned int ssp_get_clk_div(struct driver_data *drv_data, int rate)
+static unsigned int ssp_get_clk_div(struct driver_data *drv_data, u32 rate)
{
- unsigned long ssp_clk = drv_data->controller->max_speed_hz;
+ u32 ssp_clk = drv_data->controller->max_speed_hz;
const struct ssp_device *ssp = drv_data->ssp;
- rate = min_t(int, ssp_clk, rate);
+ rate = min(ssp_clk, rate);
/*
* Calculate the divisor for the SCR (Serial Clock Rate), avoiding
@@ -902,8 +902,7 @@ static unsigned int ssp_get_clk_div(struct driver_data *drv_data, int rate)
return (DIV_ROUND_UP(ssp_clk, rate) - 1) & 0xfff;
}
-static unsigned int pxa2xx_ssp_get_clk_div(struct driver_data *drv_data,
- int rate)
+static unsigned int pxa2xx_ssp_get_clk_div(struct driver_data *drv_data, u32 rate)
{
struct chip_data *chip =
spi_get_ctldata(drv_data->controller->cur_msg->spi);
diff --git a/drivers/spi/spi-qup.c b/drivers/spi/spi-qup.c
index 6cbdcd060e8c..45d9b4cb75e4 100644
--- a/drivers/spi/spi-qup.c
+++ b/drivers/spi/spi-qup.c
@@ -1193,7 +1193,7 @@ static int spi_qup_probe(struct platform_device *pdev)
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
- ret = devm_spi_register_controller(dev, host);
+ ret = spi_register_controller(host);
if (ret)
goto disable_pm;
@@ -1320,6 +1320,10 @@ static void spi_qup_remove(struct platform_device *pdev)
struct spi_qup *controller = spi_controller_get_devdata(host);
int ret;
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
ret = pm_runtime_get_sync(&pdev->dev);
if (ret >= 0) {
@@ -1339,6 +1343,8 @@ static void spi_qup_remove(struct platform_device *pdev)
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
+
+ spi_controller_put(host);
}
static const struct of_device_id spi_qup_dt_match[] = {
diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
index fd2ebef4903f..14cd1b9d9793 100644
--- a/drivers/spi/spi-rockchip.c
+++ b/drivers/spi/spi-rockchip.c
@@ -767,9 +767,9 @@ static int rockchip_spi_probe(struct platform_device *pdev)
target_mode = of_property_read_bool(np, "spi-slave");
if (target_mode)
- ctlr = spi_alloc_target(&pdev->dev, sizeof(struct rockchip_spi));
+ ctlr = devm_spi_alloc_target(&pdev->dev, sizeof(*rs));
else
- ctlr = spi_alloc_host(&pdev->dev, sizeof(struct rockchip_spi));
+ ctlr = devm_spi_alloc_host(&pdev->dev, sizeof(*rs));
if (!ctlr)
return -ENOMEM;
@@ -780,35 +780,31 @@ static int rockchip_spi_probe(struct platform_device *pdev)
/* Get basic io resource and map it */
rs->regs = devm_platform_get_and_ioremap_resource(pdev, 0, &mem);
- if (IS_ERR(rs->regs)) {
- ret = PTR_ERR(rs->regs);
- goto err_put_ctlr;
- }
+ if (IS_ERR(rs->regs))
+ return PTR_ERR(rs->regs);
rs->apb_pclk = devm_clk_get_enabled(&pdev->dev, "apb_pclk");
if (IS_ERR(rs->apb_pclk)) {
- ret = dev_err_probe(&pdev->dev, PTR_ERR(rs->apb_pclk),
- "Failed to get apb_pclk\n");
- goto err_put_ctlr;
+ return dev_err_probe(&pdev->dev, PTR_ERR(rs->apb_pclk),
+ "Failed to get apb_pclk\n");
}
rs->spiclk = devm_clk_get_enabled(&pdev->dev, "spiclk");
if (IS_ERR(rs->spiclk)) {
- ret = dev_err_probe(&pdev->dev, PTR_ERR(rs->spiclk),
- "Failed to get spi_pclk\n");
- goto err_put_ctlr;
+ return dev_err_probe(&pdev->dev, PTR_ERR(rs->spiclk),
+ "Failed to get spi_pclk\n");
}
spi_enable_chip(rs, false);
ret = platform_get_irq(pdev, 0);
if (ret < 0)
- goto err_put_ctlr;
+ return ret;
ret = devm_request_irq(&pdev->dev, ret, rockchip_spi_isr, 0,
dev_name(&pdev->dev), ctlr);
if (ret)
- goto err_put_ctlr;
+ return ret;
rs->dev = &pdev->dev;
rs->freq = clk_get_rate(rs->spiclk);
@@ -830,10 +826,8 @@ static int rockchip_spi_probe(struct platform_device *pdev)
}
rs->fifo_len = get_fifo_len(rs);
- if (!rs->fifo_len) {
- ret = dev_err_probe(&pdev->dev, -EINVAL, "Failed to get fifo length\n");
- goto err_put_ctlr;
- }
+ if (!rs->fifo_len)
+ return dev_err_probe(&pdev->dev, -EINVAL, "Failed to get fifo length\n");
pm_runtime_set_autosuspend_delay(&pdev->dev, ROCKCHIP_AUTOSUSPEND_TIMEOUT);
pm_runtime_use_autosuspend(&pdev->dev);
@@ -908,7 +902,7 @@ static int rockchip_spi_probe(struct platform_device *pdev)
break;
}
- ret = devm_spi_register_controller(&pdev->dev, ctlr);
+ ret = spi_register_controller(ctlr);
if (ret < 0) {
dev_err(&pdev->dev, "Failed to register controller\n");
goto err_free_dma_rx;
@@ -924,18 +918,18 @@ err_free_dma_tx:
dma_release_channel(ctlr->dma_tx);
err_disable_pm_runtime:
pm_runtime_disable(&pdev->dev);
-err_put_ctlr:
- spi_controller_put(ctlr);
return ret;
}
static void rockchip_spi_remove(struct platform_device *pdev)
{
- struct spi_controller *ctlr = spi_controller_get(platform_get_drvdata(pdev));
+ struct spi_controller *ctlr = platform_get_drvdata(pdev);
pm_runtime_get_sync(&pdev->dev);
+ spi_unregister_controller(ctlr);
+
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
@@ -944,8 +938,6 @@ static void rockchip_spi_remove(struct platform_device *pdev)
dma_release_channel(ctlr->dma_tx);
if (ctlr->dma_rx)
dma_release_channel(ctlr->dma_rx);
-
- spi_controller_put(ctlr);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c
index c739c1998b4c..a8180dece716 100644
--- a/drivers/spi/spi-rspi.c
+++ b/drivers/spi/spi-rspi.c
@@ -1171,8 +1171,14 @@ static void rspi_remove(struct platform_device *pdev)
{
struct rspi_data *rspi = platform_get_drvdata(pdev);
+ spi_controller_get(rspi->ctlr);
+
+ spi_unregister_controller(rspi->ctlr);
+
rspi_release_dma(rspi->ctlr);
pm_runtime_disable(&pdev->dev);
+
+ spi_controller_put(rspi->ctlr);
}
static const struct spi_ops rspi_ops = {
@@ -1376,9 +1382,9 @@ static int rspi_probe(struct platform_device *pdev)
if (ret < 0)
dev_warn(&pdev->dev, "DMA not available, using PIO\n");
- ret = devm_spi_register_controller(&pdev->dev, ctlr);
+ ret = spi_register_controller(ctlr);
if (ret < 0) {
- dev_err(&pdev->dev, "devm_spi_register_controller error.\n");
+ dev_err(&pdev->dev, "failed to register controller\n");
goto error3;
}
diff --git a/drivers/spi/spi-rzv2h-rspi.c b/drivers/spi/spi-rzv2h-rspi.c
index 23f0e92ae208..f45af5884638 100644
--- a/drivers/spi/spi-rzv2h-rspi.c
+++ b/drivers/spi/spi-rzv2h-rspi.c
@@ -50,7 +50,6 @@
/* Register SPBR */
#define RSPI_SPBR_SPR_MIN 0
-#define RSPI_SPBR_SPR_PCLK_MIN 1
#define RSPI_SPBR_SPR_MAX 255
/* Register SPCMD */
@@ -77,6 +76,8 @@
#define RSPI_RESET_NUM 2
+#define RSPI_MAX_SPEED_HZ 50000000
+
struct rzv2h_rspi_best_clock {
struct clk *clk;
unsigned long clk_rate;
@@ -87,9 +88,9 @@ struct rzv2h_rspi_best_clock {
};
struct rzv2h_rspi_info {
- void (*find_tclk_rate)(struct clk *clk, u32 hz, u8 spr_min, u8 spr_max,
+ void (*find_tclk_rate)(struct clk *clk, u32 hz,
struct rzv2h_rspi_best_clock *best_clk);
- void (*find_pclk_rate)(struct clk *clk, u32 hz, u8 spr_low, u8 spr_high,
+ void (*find_pclk_rate)(struct clk *clk, u32 hz,
struct rzv2h_rspi_best_clock *best_clk);
const char *tclk_name;
unsigned int fifo_size;
@@ -412,7 +413,6 @@ static inline u32 rzv2h_rspi_calc_bitrate(unsigned long tclk_rate, u8 spr,
}
static void rzv2h_rspi_find_rate_variable(struct clk *clk, u32 hz,
- u8 spr_min, u8 spr_max,
struct rzv2h_rspi_best_clock *best)
{
long clk_rate, clk_min_rate, clk_max_rate;
@@ -463,7 +463,7 @@ static void rzv2h_rspi_find_rate_variable(struct clk *clk, u32 hz,
* minimum SPR that is in the valid range.
*/
min_rate_spr = DIV_ROUND_CLOSEST(clk_min_rate, rate_div) - 1;
- if (min_rate_spr > spr_max)
+ if (min_rate_spr > RSPI_SPBR_SPR_MAX)
continue;
/*
@@ -473,14 +473,14 @@ static void rzv2h_rspi_find_rate_variable(struct clk *clk, u32 hz,
* maximum SPR that is in the valid range.
*/
max_rate_spr = DIV_ROUND_CLOSEST(clk_max_rate, rate_div) - 1;
- if (max_rate_spr < spr_min)
+ if (max_rate_spr < RSPI_SPBR_SPR_MIN)
break;
- if (min_rate_spr < spr_min)
- min_rate_spr = spr_min;
+ if (min_rate_spr < RSPI_SPBR_SPR_MIN)
+ min_rate_spr = RSPI_SPBR_SPR_MIN;
- if (max_rate_spr > spr_max)
- max_rate_spr = spr_max;
+ if (max_rate_spr > RSPI_SPBR_SPR_MAX)
+ max_rate_spr = RSPI_SPBR_SPR_MAX;
for (spr = min_rate_spr; spr <= max_rate_spr; spr++) {
clk_rate = (spr + 1) * rate_div;
@@ -511,7 +511,6 @@ static void rzv2h_rspi_find_rate_variable(struct clk *clk, u32 hz,
}
static void rzv2h_rspi_find_rate_fixed(struct clk *clk, u32 hz,
- u8 spr_min, u8 spr_max,
struct rzv2h_rspi_best_clock *best)
{
unsigned long clk_rate;
@@ -533,7 +532,18 @@ static void rzv2h_rspi_find_rate_fixed(struct clk *clk, u32 hz,
for (brdv = RSPI_SPCMD_BRDV_MIN; brdv <= RSPI_SPCMD_BRDV_MAX; brdv++) {
spr = DIV_ROUND_UP(clk_rate, hz * (1 << (brdv + 1)));
spr--;
- if (spr >= spr_min && spr <= spr_max)
+ /*
+ * Skip SPR=0 and BRDV=0 as it is not a valid combination:
+ * - On RZ/G3E, RZ/G3L, RZ/V2H(P) and RZ/V2N, RSPI_n_TCLK is
+ * fixed at 200MHz and SPR=0 and BRDV=0 results in the maximum
+ * bit rate of 100Mbps which is prohibited.
+ * - On RZ/T2H and RZ/N2H, when PCLK (125MHz) is used as
+ * the clock source, SPR=0 and BRDV=0 is explicitly listed
+ * as unsupported in the hardware manual (Table 36.7).
+ */
+ if (!spr && !brdv)
+ continue;
+ if (spr >= RSPI_SPBR_SPR_MIN && spr <= RSPI_SPBR_SPR_MAX)
goto clock_found;
}
@@ -563,16 +573,10 @@ static u32 rzv2h_rspi_setup_clock(struct rzv2h_rspi_priv *rspi, u32 hz)
};
int ret;
- rspi->info->find_tclk_rate(rspi->tclk, hz, RSPI_SPBR_SPR_MIN,
- RSPI_SPBR_SPR_MAX, &best_clock);
+ rspi->info->find_tclk_rate(rspi->tclk, hz, &best_clock);
- /*
- * T2H and N2H can also use PCLK as a source, which is 125MHz, but not
- * when both SPR and BRDV are 0.
- */
if (best_clock.error && rspi->info->find_pclk_rate)
- rspi->info->find_pclk_rate(rspi->pclk, hz, RSPI_SPBR_SPR_PCLK_MIN,
- RSPI_SPBR_SPR_MAX, &best_clock);
+ rspi->info->find_pclk_rate(rspi->pclk, hz, &best_clock);
if (!best_clock.clk_rate)
return -EINVAL;
@@ -771,13 +775,7 @@ static int rzv2h_rspi_probe(struct platform_device *pdev)
RSPI_SPBR_SPR_MAX,
RSPI_SPCMD_BRDV_MAX);
- tclk_rate = clk_round_rate(rspi->tclk, ULONG_MAX);
- if (tclk_rate < 0)
- return tclk_rate;
-
- controller->max_speed_hz = rzv2h_rspi_calc_bitrate(tclk_rate,
- RSPI_SPBR_SPR_MIN,
- RSPI_SPCMD_BRDV_MIN);
+ controller->max_speed_hz = RSPI_MAX_SPEED_HZ;
controller->dma_tx = devm_dma_request_chan(dev, "tx");
if (IS_ERR(controller->dma_tx)) {
@@ -811,6 +809,13 @@ static const struct rzv2h_rspi_info rzv2h_info = {
.num_clks = 3,
};
+static const struct rzv2h_rspi_info rzg3l_info = {
+ .find_tclk_rate = rzv2h_rspi_find_rate_fixed,
+ .tclk_name = "tclk",
+ .fifo_size = 16,
+ .num_clks = 2,
+};
+
static const struct rzv2h_rspi_info rzt2h_info = {
.find_tclk_rate = rzv2h_rspi_find_rate_variable,
.find_pclk_rate = rzv2h_rspi_find_rate_fixed,
@@ -820,6 +825,7 @@ static const struct rzv2h_rspi_info rzt2h_info = {
};
static const struct of_device_id rzv2h_rspi_match[] = {
+ { .compatible = "renesas,r9a08g046-rspi", &rzg3l_info },
{ .compatible = "renesas,r9a09g057-rspi", &rzv2h_info },
{ .compatible = "renesas,r9a09g077-rspi", &rzt2h_info },
{ /* sentinel */ }
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c
index ba85243d6d89..37176e557099 100644
--- a/drivers/spi/spi-s3c64xx.c
+++ b/drivers/spi/spi-s3c64xx.c
@@ -1369,7 +1369,7 @@ static int s3c64xx_spi_probe(struct platform_device *pdev)
S3C64XX_SPI_INT_TX_OVERRUN_EN | S3C64XX_SPI_INT_TX_UNDERRUN_EN,
sdd->regs + S3C64XX_SPI_INT_EN);
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret != 0) {
dev_err(&pdev->dev, "cannot register SPI host: %d\n", ret);
goto err_pm_put;
@@ -1399,12 +1399,9 @@ static void s3c64xx_spi_remove(struct platform_device *pdev)
pm_runtime_get_sync(&pdev->dev);
- writel(0, sdd->regs + S3C64XX_SPI_INT_EN);
+ spi_unregister_controller(host);
- if (!is_polling(sdd)) {
- dma_release_channel(sdd->rx_dma.ch);
- dma_release_channel(sdd->tx_dma.ch);
- }
+ writel(0, sdd->regs + S3C64XX_SPI_INT_EN);
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
diff --git a/drivers/spi/spi-sh-hspi.c b/drivers/spi/spi-sh-hspi.c
index e03eaca1b1a7..1e3ca718ca73 100644
--- a/drivers/spi/spi-sh-hspi.c
+++ b/drivers/spi/spi-sh-hspi.c
@@ -257,9 +257,9 @@ static int hspi_probe(struct platform_device *pdev)
ctlr->transfer_one_message = hspi_transfer_one_message;
ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
- ret = devm_spi_register_controller(&pdev->dev, ctlr);
+ ret = spi_register_controller(ctlr);
if (ret < 0) {
- dev_err(&pdev->dev, "devm_spi_register_controller error.\n");
+ dev_err(&pdev->dev, "failed to register controller\n");
goto error2;
}
@@ -279,9 +279,15 @@ static void hspi_remove(struct platform_device *pdev)
{
struct hspi_priv *hspi = platform_get_drvdata(pdev);
+ spi_controller_get(hspi->ctlr);
+
+ spi_unregister_controller(hspi->ctlr);
+
pm_runtime_disable(&pdev->dev);
clk_put(hspi->clk);
+
+ spi_controller_put(hspi->ctlr);
}
static const struct of_device_id hspi_of_match[] = {
diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c
index 7f3e08810560..f114b6313f4f 100644
--- a/drivers/spi/spi-sh-msiof.c
+++ b/drivers/spi/spi-sh-msiof.c
@@ -1289,9 +1289,9 @@ static int sh_msiof_spi_probe(struct platform_device *pdev)
if (ret < 0)
dev_warn(dev, "DMA not available, using PIO\n");
- ret = devm_spi_register_controller(dev, ctlr);
+ ret = spi_register_controller(ctlr);
if (ret < 0) {
- dev_err(dev, "devm_spi_register_controller error.\n");
+ dev_err(dev, "failed to register controller\n");
goto err2;
}
@@ -1309,8 +1309,14 @@ static void sh_msiof_spi_remove(struct platform_device *pdev)
{
struct sh_msiof_spi_priv *p = platform_get_drvdata(pdev);
+ spi_controller_get(p->ctlr);
+
+ spi_unregister_controller(p->ctlr);
+
sh_msiof_release_dma(p);
pm_runtime_disable(&pdev->dev);
+
+ spi_controller_put(p->ctlr);
}
static const struct platform_device_id spi_driver_ids[] = {
diff --git a/drivers/spi/spi-sifive.c b/drivers/spi/spi-sifive.c
index 6c7aba8befa0..74a3e32fd2b5 100644
--- a/drivers/spi/spi-sifive.c
+++ b/drivers/spi/spi-sifive.c
@@ -312,7 +312,8 @@ static int sifive_spi_probe(struct platform_device *pdev)
goto put_host;
}
- spi->clk = devm_clk_get(&pdev->dev, NULL);
+ /* Spin up the bus clock before hitting registers */
+ spi->clk = devm_clk_get_enabled(&pdev->dev, NULL);
if (IS_ERR(spi->clk)) {
dev_err(&pdev->dev, "Unable to find bus clock\n");
ret = PTR_ERR(spi->clk);
@@ -342,13 +343,6 @@ static int sifive_spi_probe(struct platform_device *pdev)
goto put_host;
}
- /* Spin up the bus clock before hitting registers */
- ret = clk_prepare_enable(spi->clk);
- if (ret) {
- dev_err(&pdev->dev, "Unable to enable bus clock\n");
- goto put_host;
- }
-
/* probe the number of CS lines */
spi->cs_inactive = sifive_spi_read(spi, SIFIVE_SPI_REG_CSDEF);
sifive_spi_write(spi, SIFIVE_SPI_REG_CSDEF, 0xffffffffU);
@@ -357,14 +351,14 @@ static int sifive_spi_probe(struct platform_device *pdev)
if (!cs_bits) {
dev_err(&pdev->dev, "Could not auto probe CS lines\n");
ret = -EINVAL;
- goto disable_clk;
+ goto put_host;
}
num_cs = ilog2(cs_bits) + 1;
if (num_cs > SIFIVE_SPI_MAX_CS) {
dev_err(&pdev->dev, "Invalid number of spi targets\n");
ret = -EINVAL;
- goto disable_clk;
+ goto put_host;
}
/* Define our host */
@@ -392,22 +386,20 @@ static int sifive_spi_probe(struct platform_device *pdev)
dev_name(&pdev->dev), spi);
if (ret) {
dev_err(&pdev->dev, "Unable to bind to interrupt\n");
- goto disable_clk;
+ goto put_host;
}
dev_info(&pdev->dev, "mapped; irq=%d, cs=%d\n",
irq, host->num_chipselect);
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret < 0) {
dev_err(&pdev->dev, "spi_register_host failed\n");
- goto disable_clk;
+ goto put_host;
}
return 0;
-disable_clk:
- clk_disable_unprepare(spi->clk);
put_host:
spi_controller_put(host);
@@ -419,9 +411,14 @@ static void sifive_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct sifive_spi *spi = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
/* Disable all the interrupts just in case */
sifive_spi_write(spi, SIFIVE_SPI_REG_IE, 0);
- clk_disable_unprepare(spi->clk);
+
+ spi_controller_put(host);
}
static int sifive_spi_suspend(struct device *dev)
diff --git a/drivers/spi/spi-slave-mt27xx.c b/drivers/spi/spi-slave-mt27xx.c
index ce889cb33228..7aedeaa5889d 100644
--- a/drivers/spi/spi-slave-mt27xx.c
+++ b/drivers/spi/spi-slave-mt27xx.c
@@ -453,7 +453,7 @@ static int mtk_spi_slave_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
- ret = devm_spi_register_controller(&pdev->dev, ctlr);
+ ret = spi_register_controller(ctlr);
clk_disable_unprepare(mdata->spi_clk);
if (ret) {
dev_err(&pdev->dev,
@@ -473,7 +473,15 @@ err_put_ctlr:
static void mtk_spi_slave_remove(struct platform_device *pdev)
{
+ struct spi_controller *ctlr = platform_get_drvdata(pdev);
+
+ spi_controller_get(ctlr);
+
+ spi_unregister_controller(ctlr);
+
pm_runtime_disable(&pdev->dev);
+
+ spi_controller_put(ctlr);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-sn-f-ospi.c b/drivers/spi/spi-sn-f-ospi.c
index 3c61c799723b..b459d51cb3a8 100644
--- a/drivers/spi/spi-sn-f-ospi.c
+++ b/drivers/spi/spi-sn-f-ospi.c
@@ -625,7 +625,7 @@ static int f_ospi_probe(struct platform_device *pdev)
of_property_read_u32(dev->of_node, "num-cs", &num_cs);
if (num_cs > OSPI_NUM_CS) {
dev_err(dev, "num-cs too large: %d\n", num_cs);
- return -ENOMEM;
+ return -EINVAL;
}
ctlr->num_chipselect = num_cs;
diff --git a/drivers/spi/spi-sprd.c b/drivers/spi/spi-sprd.c
index 0f9fc320363c..fd3fd0ce122c 100644
--- a/drivers/spi/spi-sprd.c
+++ b/drivers/spi/spi-sprd.c
@@ -977,7 +977,7 @@ static int sprd_spi_probe(struct platform_device *pdev)
goto err_rpm_put;
}
- ret = devm_spi_register_controller(&pdev->dev, sctlr);
+ ret = spi_register_controller(sctlr);
if (ret)
goto err_rpm_put;
@@ -1008,7 +1008,9 @@ static void sprd_spi_remove(struct platform_device *pdev)
if (ret < 0)
dev_err(ss->dev, "failed to resume SPI controller\n");
- spi_controller_suspend(sctlr);
+ spi_controller_get(sctlr);
+
+ spi_unregister_controller(sctlr);
if (ret >= 0) {
if (ss->dma.enable)
@@ -1017,6 +1019,8 @@ static void sprd_spi_remove(struct platform_device *pdev)
}
pm_runtime_put_noidle(&pdev->dev);
pm_runtime_disable(&pdev->dev);
+
+ spi_controller_put(sctlr);
}
static int __maybe_unused sprd_spi_runtime_suspend(struct device *dev)
diff --git a/drivers/spi/spi-st-ssc4.c b/drivers/spi/spi-st-ssc4.c
index b173ef70d77e..9c8099fe6e19 100644
--- a/drivers/spi/spi-st-ssc4.c
+++ b/drivers/spi/spi-st-ssc4.c
@@ -349,7 +349,7 @@ static int spi_st_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, host);
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret) {
dev_err(&pdev->dev, "Failed to register host\n");
goto rpm_disable;
@@ -371,10 +371,16 @@ static void spi_st_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct spi_st *spi_st = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
pm_runtime_disable(&pdev->dev);
clk_disable_unprepare(spi_st->clk);
+ spi_controller_put(host);
+
pinctrl_pm_select_sleep_state(&pdev->dev);
}
diff --git a/drivers/spi/spi-stm32-ospi.c b/drivers/spi/spi-stm32-ospi.c
index 38405f8f547f..4461c6e24b9e 100644
--- a/drivers/spi/spi-stm32-ospi.c
+++ b/drivers/spi/spi-stm32-ospi.c
@@ -469,11 +469,6 @@ static int stm32_ospi_send(struct spi_device *spi, const struct spi_mem_op *op)
int timeout, err = 0, err_poll_status = 0;
u8 cs = spi->chip_select[ffs(spi->cs_index_mask) - 1];
- dev_dbg(ospi->dev, "cmd:%#x mode:%d.%d.%d.%d addr:%#llx len:%#x\n",
- op->cmd.opcode, op->cmd.buswidth, op->addr.buswidth,
- op->dummy.buswidth, op->data.buswidth,
- op->addr.val, op->data.nbytes);
-
cr = readl_relaxed(ospi->regs_base + OSPI_CR);
cr &= ~CR_CSSEL;
cr |= FIELD_PREP(CR_CSSEL, cs);
diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c
index 33f211e159ef..be88e62075af 100644
--- a/drivers/spi/spi-stm32.c
+++ b/drivers/spi/spi-stm32.c
@@ -1659,7 +1659,7 @@ static int stm32_spi_transfer_one_dma(struct stm32_spi *spi,
ret = stm32_spi_prepare_rx_dma_mdma_chaining(spi, xfer, &rx_dma_conf,
&rx_dma_desc, &rx_mdma_desc);
if (ret) { /* RX DMA MDMA chaining not possible, fallback to DMA only */
- rx_dma_conf.peripheral_config = 0;
+ rx_dma_conf.peripheral_config = NULL;
rx_dma_desc = NULL;
}
}
@@ -2360,25 +2360,20 @@ static int stm32_spi_probe(struct platform_device *pdev)
int ret;
cfg = of_device_get_match_data(&pdev->dev);
- if (!cfg) {
- dev_err(&pdev->dev, "Failed to get match data for platform\n");
- return -ENODEV;
- }
+ if (!cfg)
+ return dev_err_probe(&pdev->dev, -ENODEV,
+ "Failed to get match data for platform\n");
device_mode = of_property_read_bool(np, "spi-slave");
- if (!cfg->has_device_mode && device_mode) {
- dev_err(&pdev->dev, "spi-slave not supported\n");
- return -EPERM;
- }
+ if (!cfg->has_device_mode && device_mode)
+ return dev_err_probe(&pdev->dev, -EPERM, "spi-slave not supported\n");
if (device_mode)
ctrl = devm_spi_alloc_target(&pdev->dev, sizeof(struct stm32_spi));
else
ctrl = devm_spi_alloc_host(&pdev->dev, sizeof(struct stm32_spi));
- if (!ctrl) {
- dev_err(&pdev->dev, "spi controller allocation failed\n");
- return -ENOMEM;
- }
+ if (!ctrl)
+ return dev_err_probe(&pdev->dev, -ENOMEM, "spi controller allocation failed\n");
platform_set_drvdata(pdev, ctrl);
spi = spi_controller_get_devdata(ctrl);
@@ -2409,32 +2404,18 @@ static int stm32_spi_probe(struct platform_device *pdev)
return ret;
}
- spi->clk = devm_clk_get(&pdev->dev, NULL);
- if (IS_ERR(spi->clk)) {
- ret = PTR_ERR(spi->clk);
- dev_err(&pdev->dev, "clk get failed: %d\n", ret);
- return ret;
- }
+ spi->clk = devm_clk_get_enabled(&pdev->dev, NULL);
+ if (IS_ERR(spi->clk))
+ return dev_err_probe(&pdev->dev, PTR_ERR(spi->clk), "clk enabled failed\n");
- ret = clk_prepare_enable(spi->clk);
- if (ret) {
- dev_err(&pdev->dev, "clk enable failed: %d\n", ret);
- return ret;
- }
spi->clk_rate = clk_get_rate(spi->clk);
- if (!spi->clk_rate) {
- dev_err(&pdev->dev, "clk rate = 0\n");
- ret = -EINVAL;
- goto err_clk_disable;
- }
+ if (!spi->clk_rate)
+ return dev_err_probe(&pdev->dev, -EINVAL, "clk rate = 0\n");
rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
if (rst) {
- if (IS_ERR(rst)) {
- ret = dev_err_probe(&pdev->dev, PTR_ERR(rst),
- "failed to get reset\n");
- goto err_clk_disable;
- }
+ if (IS_ERR(rst))
+ return dev_err_probe(&pdev->dev, PTR_ERR(rst), "failed to get reset\n");
reset_control_assert(rst);
udelay(2);
@@ -2461,11 +2442,8 @@ static int stm32_spi_probe(struct platform_device *pdev)
dev_dbg(spi->dev, "one message max size %d\n", spi->t_size_max);
ret = spi->cfg->config(spi);
- if (ret) {
- dev_err(&pdev->dev, "controller configuration failed: %d\n",
- ret);
- goto err_clk_disable;
- }
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "controller configuration failed: %d\n", ret);
ctrl->auto_runtime_pm = true;
ctrl->bus_num = pdev->id;
@@ -2490,8 +2468,7 @@ static int stm32_spi_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "tx dma disabled\n");
spi->dma_tx = NULL;
} else {
- dev_err_probe(&pdev->dev, ret, "failed to request tx dma channel\n");
- goto err_clk_disable;
+ return dev_err_probe(&pdev->dev, ret, "failed to request tx dma channel\n");
}
} else {
ctrl->dma_tx = spi->dma_tx;
@@ -2505,7 +2482,7 @@ static int stm32_spi_probe(struct platform_device *pdev)
spi->dma_rx = NULL;
} else {
dev_err_probe(&pdev->dev, ret, "failed to request rx dma channel\n");
- goto err_dma_release;
+ goto err_dma_tx_release;
}
} else {
ctrl->dma_rx = spi->dma_rx;
@@ -2574,13 +2551,11 @@ err_pool_free:
if (spi->sram_pool)
gen_pool_free(spi->sram_pool, (unsigned long)spi->sram_rx_buf,
spi->sram_rx_buf_size);
-err_dma_release:
- if (spi->dma_tx)
- dma_release_channel(spi->dma_tx);
if (spi->dma_rx)
dma_release_channel(spi->dma_rx);
-err_clk_disable:
- clk_disable_unprepare(spi->clk);
+err_dma_tx_release:
+ if (spi->dma_tx)
+ dma_release_channel(spi->dma_tx);
return ret;
}
@@ -2610,9 +2585,6 @@ static void stm32_spi_remove(struct platform_device *pdev)
gen_pool_free(spi->sram_pool, (unsigned long)spi->sram_rx_buf,
spi->sram_rx_buf_size);
- clk_disable_unprepare(spi->clk);
-
-
pinctrl_pm_select_sleep_state(&pdev->dev);
}
diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c
index bfdf419a583c..b7fbb5270edb 100644
--- a/drivers/spi/spi-sun4i.c
+++ b/drivers/spi/spi-sun4i.c
@@ -504,7 +504,7 @@ static int sun4i_spi_probe(struct platform_device *pdev)
pm_runtime_enable(&pdev->dev);
pm_runtime_idle(&pdev->dev);
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret) {
dev_err(&pdev->dev, "cannot register SPI host\n");
goto err_pm_disable;
@@ -522,7 +522,15 @@ err_free_host:
static void sun4i_spi_remove(struct platform_device *pdev)
{
+ struct spi_controller *host = platform_get_drvdata(pdev);
+
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
pm_runtime_force_suspend(&pdev->dev);
+
+ spi_controller_put(host);
}
static const struct of_device_id sun4i_spi_match[] = {
diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c
index 240e46f84f7b..5ac73d324d06 100644
--- a/drivers/spi/spi-sun6i.c
+++ b/drivers/spi/spi-sun6i.c
@@ -742,7 +742,7 @@ static int sun6i_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) {
dev_err(&pdev->dev, "cannot register SPI host\n");
goto err_pm_disable;
@@ -768,12 +768,18 @@ static void sun6i_spi_remove(struct platform_device *pdev)
{
struct spi_controller *host = platform_get_drvdata(pdev);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
pm_runtime_force_suspend(&pdev->dev);
if (host->dma_tx)
dma_release_channel(host->dma_tx);
if (host->dma_rx)
dma_release_channel(host->dma_rx);
+
+ spi_controller_put(host);
}
static const struct sun6i_spi_cfg sun6i_a31_spi_cfg = {
diff --git a/drivers/spi/spi-sunplus-sp7021.c b/drivers/spi/spi-sunplus-sp7021.c
index 789b092fe8c0..35601212fb78 100644
--- a/drivers/spi/spi-sunplus-sp7021.c
+++ b/drivers/spi/spi-sunplus-sp7021.c
@@ -389,11 +389,6 @@ static int sp7021_spi_target_transfer_one(struct spi_controller *ctlr, struct sp
return ret;
}
-static void sp7021_spi_disable_unprepare(void *data)
-{
- clk_disable_unprepare(data);
-}
-
static void sp7021_spi_reset_control_assert(void *data)
{
reset_control_assert(data);
@@ -460,7 +455,7 @@ static int sp7021_spi_controller_probe(struct platform_device *pdev)
if (pspim->s_irq < 0)
return pspim->s_irq;
- pspim->spi_clk = devm_clk_get(dev, NULL);
+ pspim->spi_clk = devm_clk_get_enabled(dev, NULL);
if (IS_ERR(pspim->spi_clk))
return dev_err_probe(dev, PTR_ERR(pspim->spi_clk), "clk get fail\n");
@@ -468,14 +463,6 @@ static int sp7021_spi_controller_probe(struct platform_device *pdev)
if (IS_ERR(pspim->rstc))
return dev_err_probe(dev, PTR_ERR(pspim->rstc), "rst get fail\n");
- ret = clk_prepare_enable(pspim->spi_clk);
- if (ret)
- return dev_err_probe(dev, ret, "failed to enable clk\n");
-
- ret = devm_add_action_or_reset(dev, sp7021_spi_disable_unprepare, pspim->spi_clk);
- if (ret)
- return ret;
-
ret = reset_control_deassert(pspim->rstc);
if (ret)
return dev_err_probe(dev, ret, "failed to deassert reset\n");
diff --git a/drivers/spi/spi-synquacer.c b/drivers/spi/spi-synquacer.c
index d0a875249910..290c439897c4 100644
--- a/drivers/spi/spi-synquacer.c
+++ b/drivers/spi/spi-synquacer.c
@@ -716,7 +716,7 @@ static int synquacer_spi_probe(struct platform_device *pdev)
pm_runtime_set_active(sspi->dev);
pm_runtime_enable(sspi->dev);
- ret = devm_spi_register_controller(sspi->dev, host);
+ ret = spi_register_controller(host);
if (ret)
goto disable_pm;
@@ -737,9 +737,15 @@ static void synquacer_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct synquacer_spi *sspi = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
pm_runtime_disable(sspi->dev);
clk_disable_unprepare(sspi->clk);
+
+ spi_controller_put(host);
}
static int __maybe_unused synquacer_spi_suspend(struct device *dev)
diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c
index 848cb6836bd5..b8b0ebe0fe93 100644
--- a/drivers/spi/spi-tegra114.c
+++ b/drivers/spi/spi-tegra114.c
@@ -1415,7 +1415,7 @@ static int tegra_spi_probe(struct platform_device *pdev)
goto exit_pm_disable;
}
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret < 0) {
dev_err(&pdev->dev, "can not register to host err %d\n", ret);
goto exit_free_irq;
@@ -1441,6 +1441,10 @@ static void tegra_spi_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct tegra_spi_data *tspi = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
free_irq(tspi->irq, tspi);
if (tspi->tx_dma_chan)
@@ -1452,6 +1456,8 @@ static void tegra_spi_remove(struct platform_device *pdev)
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
tegra_spi_runtime_suspend(&pdev->dev);
+
+ spi_controller_put(host);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-tegra20-sflash.c b/drivers/spi/spi-tegra20-sflash.c
index d9d536d7f7b6..9256729f2d49 100644
--- a/drivers/spi/spi-tegra20-sflash.c
+++ b/drivers/spi/spi-tegra20-sflash.c
@@ -505,7 +505,7 @@ static int tegra_sflash_probe(struct platform_device *pdev)
tegra_sflash_writel(tsd, tsd->def_command_reg, SPI_COMMAND);
pm_runtime_put(&pdev->dev);
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret < 0) {
dev_err(&pdev->dev, "can not register to host err %d\n", ret);
goto exit_pm_disable;
@@ -528,11 +528,17 @@ static void tegra_sflash_remove(struct platform_device *pdev)
struct spi_controller *host = platform_get_drvdata(pdev);
struct tegra_sflash_data *tsd = spi_controller_get_devdata(host);
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
+
free_irq(tsd->irq, tsd);
pm_runtime_disable(&pdev->dev);
if (!pm_runtime_status_suspended(&pdev->dev))
tegra_sflash_runtime_suspend(&pdev->dev);
+
+ spi_controller_put(host);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-tegra20-slink.c b/drivers/spi/spi-tegra20-slink.c
index 8c608abd6076..c15c076295cd 100644
--- a/drivers/spi/spi-tegra20-slink.c
+++ b/drivers/spi/spi-tegra20-slink.c
@@ -1007,7 +1007,7 @@ static int tegra_slink_probe(struct platform_device *pdev)
cdata = of_device_get_match_data(&pdev->dev);
- host = spi_alloc_host(&pdev->dev, sizeof(*tspi));
+ host = devm_spi_alloc_host(&pdev->dev, sizeof(*tspi));
if (!host) {
dev_err(&pdev->dev, "host allocation failed\n");
return -ENOMEM;
@@ -1034,37 +1034,34 @@ static int tegra_slink_probe(struct platform_device *pdev)
host->max_speed_hz = 25000000; /* 25MHz */
tspi->base = devm_platform_get_and_ioremap_resource(pdev, 0, &r);
- if (IS_ERR(tspi->base)) {
- ret = PTR_ERR(tspi->base);
- goto exit_free_host;
- }
+ if (IS_ERR(tspi->base))
+ return PTR_ERR(tspi->base);
+
tspi->phys = r->start;
/* disabled clock may cause interrupt storm upon request */
tspi->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(tspi->clk)) {
ret = PTR_ERR(tspi->clk);
- dev_err(&pdev->dev, "Can not get clock %d\n", ret);
- goto exit_free_host;
+ return dev_err_probe(&pdev->dev, ret, "Can not get clock\n");
}
tspi->rst = devm_reset_control_get_exclusive(&pdev->dev, "spi");
if (IS_ERR(tspi->rst)) {
- dev_err(&pdev->dev, "can not get reset\n");
ret = PTR_ERR(tspi->rst);
- goto exit_free_host;
+ return dev_err_probe(&pdev->dev, ret, "can not get reset\n");
}
ret = devm_tegra_core_dev_init_opp_table_common(&pdev->dev);
if (ret)
- goto exit_free_host;
+ return ret;
tspi->max_buf_size = SLINK_FIFO_DEPTH << 2;
tspi->dma_buf_size = DEFAULT_SPI_DMA_BUF_LEN;
ret = tegra_slink_init_dma_param(tspi, true);
if (ret < 0)
- goto exit_free_host;
+ return ret;
ret = tegra_slink_init_dma_param(tspi, false);
if (ret < 0)
goto exit_rx_dma_free;
@@ -1125,14 +1122,13 @@ exit_pm_disable:
tegra_slink_deinit_dma_param(tspi, false);
exit_rx_dma_free:
tegra_slink_deinit_dma_param(tspi, true);
-exit_free_host:
- spi_controller_put(host);
+
return ret;
}
static void tegra_slink_remove(struct platform_device *pdev)
{
- struct spi_controller *host = spi_controller_get(platform_get_drvdata(pdev));
+ struct spi_controller *host = platform_get_drvdata(pdev);
struct tegra_slink_data *tspi = spi_controller_get_devdata(host);
spi_unregister_controller(host);
@@ -1146,8 +1142,6 @@ static void tegra_slink_remove(struct platform_device *pdev)
if (tspi->rx_dma_chan)
tegra_slink_deinit_dma_param(tspi, true);
-
- spi_controller_put(host);
}
#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c
index 7ea5aa993596..db28dd556484 100644
--- a/drivers/spi/spi-tegra210-quad.c
+++ b/drivers/spi/spi-tegra210-quad.c
@@ -1000,7 +1000,7 @@ static int tegra_qspi_setup(struct spi_device *spi)
spin_unlock_irqrestore(&tqspi->lock, flags);
- pm_runtime_put(tqspi->dev);
+ pm_runtime_put_autosuspend(tqspi->dev);
return 0;
}
@@ -1223,7 +1223,7 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi,
(&tqspi->xfer_completion,
QSPI_DMA_TIMEOUT);
- if (WARN_ON_ONCE(ret == 0)) {
+ if (ret == 0) {
/*
* Check if hardware completed the transfer
* even though interrupt was lost or delayed.
@@ -1232,6 +1232,7 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi,
ret = tegra_qspi_handle_timeout(tqspi);
if (ret < 0) {
/* Real timeout - clean up and fail */
+ WARN_ON_ONCE(1);
dev_err(tqspi->dev, "transfer timeout\n");
/* Abort transfer by resetting pio/dma bit */
@@ -1340,7 +1341,7 @@ static int tegra_qspi_non_combined_seq_xfer(struct tegra_qspi *tqspi,
ret = wait_for_completion_timeout(&tqspi->xfer_completion,
QSPI_DMA_TIMEOUT);
- if (WARN_ON(ret == 0)) {
+ if (ret == 0) {
/*
* Check if hardware completed the transfer even though
* interrupt was lost or delayed. If so, process the
@@ -1349,6 +1350,7 @@ static int tegra_qspi_non_combined_seq_xfer(struct tegra_qspi *tqspi,
ret = tegra_qspi_handle_timeout(tqspi);
if (ret < 0) {
/* Real timeout - clean up and fail */
+ WARN_ON(1);
dev_err(tqspi->dev, "transfer timeout\n");
if (tqspi->is_curr_dma_xfer)
@@ -1765,6 +1767,14 @@ static int tegra_qspi_probe(struct platform_device *pdev)
init_completion(&tqspi->rx_dma_complete);
init_completion(&tqspi->xfer_completion);
+ /*
+ * Set autosuspend delay to 500ms. Testing shows this value eliminates
+ * suspend/resume overhead during burst operations while allowing quick
+ * suspension during idle. For longer operations, the overhead is negligible.
+ */
+ pm_runtime_set_autosuspend_delay(&pdev->dev, 500);
+ pm_runtime_use_autosuspend(&pdev->dev);
+
pm_runtime_enable(&pdev->dev);
ret = pm_runtime_resume_and_get(&pdev->dev);
if (ret < 0) {
@@ -1781,7 +1791,7 @@ static int tegra_qspi_probe(struct platform_device *pdev)
tqspi->spi_cs_timing2 = tegra_qspi_readl(tqspi, QSPI_CS_TIMING2);
tqspi->def_command2_reg = tegra_qspi_readl(tqspi, QSPI_COMMAND2);
- pm_runtime_put(&pdev->dev);
+ pm_runtime_put_autosuspend(&pdev->dev);
ret = request_threaded_irq(tqspi->irq, NULL,
tegra_qspi_isr_thread, IRQF_ONESHOT,
@@ -1802,6 +1812,7 @@ static int tegra_qspi_probe(struct platform_device *pdev)
exit_free_irq:
free_irq(qspi_irq, tqspi);
exit_pm_disable:
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_force_suspend(&pdev->dev);
tegra_qspi_deinit_dma(tqspi);
return ret;
@@ -1814,6 +1825,7 @@ static void tegra_qspi_remove(struct platform_device *pdev)
spi_unregister_controller(host);
free_irq(tqspi->irq, tqspi);
+ pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_force_suspend(&pdev->dev);
tegra_qspi_deinit_dma(tqspi);
}
@@ -1839,7 +1851,7 @@ static int __maybe_unused tegra_qspi_resume(struct device *dev)
tegra_qspi_writel(tqspi, tqspi->command1_reg, QSPI_COMMAND1);
tegra_qspi_writel(tqspi, tqspi->def_command2_reg, QSPI_COMMAND2);
- pm_runtime_put(dev);
+ pm_runtime_put_autosuspend(dev);
return spi_controller_resume(host);
}
diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c
index d1d880a8ed7d..1fbd710d616f 100644
--- a/drivers/spi/spi-ti-qspi.c
+++ b/drivers/spi/spi-ti-qspi.c
@@ -888,7 +888,7 @@ no_dma:
qspi->mmap_enabled = false;
qspi->current_cs = -1;
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (!ret)
return 0;
@@ -903,19 +903,17 @@ free_host:
static void ti_qspi_remove(struct platform_device *pdev)
{
struct ti_qspi *qspi = platform_get_drvdata(pdev);
- int rc;
- rc = spi_controller_suspend(qspi->host);
- if (rc) {
- dev_alert(&pdev->dev, "spi_controller_suspend() failed (%pe)\n",
- ERR_PTR(rc));
- return;
- }
+ spi_controller_get(qspi->host);
+
+ spi_unregister_controller(qspi->host);
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
ti_qspi_dma_cleanup(qspi);
+
+ spi_controller_put(qspi->host);
}
static const struct dev_pm_ops ti_qspi_pm_ops = {
diff --git a/drivers/spi/spi-uniphier.c b/drivers/spi/spi-uniphier.c
index 9e1d364a6198..eac6c3e8908b 100644
--- a/drivers/spi/spi-uniphier.c
+++ b/drivers/spi/spi-uniphier.c
@@ -666,28 +666,24 @@ static int uniphier_spi_probe(struct platform_device *pdev)
}
priv->base_dma_addr = res->start;
- priv->clk = devm_clk_get(&pdev->dev, NULL);
+ priv->clk = devm_clk_get_enabled(&pdev->dev, NULL);
if (IS_ERR(priv->clk)) {
dev_err(&pdev->dev, "failed to get clock\n");
ret = PTR_ERR(priv->clk);
goto out_host_put;
}
- ret = clk_prepare_enable(priv->clk);
- if (ret)
- goto out_host_put;
-
irq = platform_get_irq(pdev, 0);
if (irq < 0) {
ret = irq;
- goto out_disable_clk;
+ goto out_host_put;
}
ret = devm_request_irq(&pdev->dev, irq, uniphier_spi_handler,
0, "uniphier-spi", priv);
if (ret) {
dev_err(&pdev->dev, "failed to request IRQ\n");
- goto out_disable_clk;
+ goto out_host_put;
}
init_completion(&priv->xfer_done);
@@ -716,7 +712,7 @@ static int uniphier_spi_probe(struct platform_device *pdev)
if (IS_ERR_OR_NULL(host->dma_tx)) {
if (PTR_ERR(host->dma_tx) == -EPROBE_DEFER) {
ret = -EPROBE_DEFER;
- goto out_disable_clk;
+ goto out_host_put;
}
host->dma_tx = NULL;
dma_tx_burst = INT_MAX;
@@ -750,7 +746,7 @@ static int uniphier_spi_probe(struct platform_device *pdev)
host->max_dma_len = min(dma_tx_burst, dma_rx_burst);
- ret = devm_spi_register_controller(&pdev->dev, host);
+ ret = spi_register_controller(host);
if (ret)
goto out_release_dma;
@@ -766,9 +762,6 @@ out_release_dma:
host->dma_tx = NULL;
}
-out_disable_clk:
- clk_disable_unprepare(priv->clk);
-
out_host_put:
spi_controller_put(host);
return ret;
@@ -777,14 +770,17 @@ out_host_put:
static void uniphier_spi_remove(struct platform_device *pdev)
{
struct spi_controller *host = platform_get_drvdata(pdev);
- struct uniphier_spi_priv *priv = spi_controller_get_devdata(host);
+
+ spi_controller_get(host);
+
+ spi_unregister_controller(host);
if (host->dma_tx)
dma_release_channel(host->dma_tx);
if (host->dma_rx)
dma_release_channel(host->dma_rx);
- clk_disable_unprepare(priv->clk);
+ spi_controller_put(host);
}
static const struct of_device_id uniphier_spi_match[] = {
diff --git a/drivers/spi/spi-zynq-qspi.c b/drivers/spi/spi-zynq-qspi.c
index af252500195c..406fd9d5337e 100644
--- a/drivers/spi/spi-zynq-qspi.c
+++ b/drivers/spi/spi-zynq-qspi.c
@@ -643,7 +643,7 @@ static int zynq_qspi_probe(struct platform_device *pdev)
xqspi = spi_controller_get_devdata(ctlr);
xqspi->dev = dev;
- platform_set_drvdata(pdev, xqspi);
+ platform_set_drvdata(pdev, ctlr);
xqspi->regs = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(xqspi->regs)) {
ret = PTR_ERR(xqspi->regs);
@@ -702,9 +702,9 @@ static int zynq_qspi_probe(struct platform_device *pdev)
/* QSPI controller initializations */
zynq_qspi_init_hw(xqspi, ctlr->num_chipselect);
- ret = devm_spi_register_controller(&pdev->dev, ctlr);
+ ret = spi_register_controller(ctlr);
if (ret) {
- dev_err(&pdev->dev, "devm_spi_register_controller failed\n");
+ dev_err(&pdev->dev, "failed to register controller\n");
goto remove_ctlr;
}
@@ -728,9 +728,16 @@ remove_ctlr:
*/
static void zynq_qspi_remove(struct platform_device *pdev)
{
- struct zynq_qspi *xqspi = platform_get_drvdata(pdev);
+ struct spi_controller *ctlr = platform_get_drvdata(pdev);
+ struct zynq_qspi *xqspi = spi_controller_get_devdata(ctlr);
+
+ spi_controller_get(ctlr);
+
+ spi_unregister_controller(ctlr);
zynq_qspi_write(xqspi, ZYNQ_QSPI_ENABLE_OFFSET, 0);
+
+ spi_controller_put(ctlr);
}
static const struct of_device_id zynq_qspi_of_match[] = {
diff --git a/drivers/spi/spi-zynqmp-gqspi.c b/drivers/spi/spi-zynqmp-gqspi.c
index 502fd5eccc83..f9a1427dabad 100644
--- a/drivers/spi/spi-zynqmp-gqspi.c
+++ b/drivers/spi/spi-zynqmp-gqspi.c
@@ -1324,7 +1324,7 @@ static int zynqmp_qspi_probe(struct platform_device *pdev)
ctlr->dev.of_node = np;
ctlr->auto_runtime_pm = true;
- ret = devm_spi_register_controller(&pdev->dev, ctlr);
+ ret = spi_register_controller(ctlr);
if (ret) {
dev_err(&pdev->dev, "spi_register_controller failed\n");
goto clk_dis_all;
@@ -1362,6 +1362,8 @@ static void zynqmp_qspi_remove(struct platform_device *pdev)
pm_runtime_get_sync(&pdev->dev);
+ spi_unregister_controller(xqspi->ctlr);
+
zynqmp_gqspi_write(xqspi, GQSPI_EN_OFST, 0x0);
pm_runtime_disable(&pdev->dev);
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index 91dd831d2d3b..7001f5dce8bd 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -89,25 +89,22 @@ static ssize_t driver_override_show(struct device *dev,
}
static DEVICE_ATTR_RW(driver_override);
-static struct spi_statistics __percpu *spi_alloc_pcpu_stats(struct device *dev)
+static struct spi_statistics __percpu *spi_alloc_pcpu_stats(void)
{
struct spi_statistics __percpu *pcpu_stats;
+ int cpu;
- if (dev)
- pcpu_stats = devm_alloc_percpu(dev, struct spi_statistics);
- else
- pcpu_stats = alloc_percpu_gfp(struct spi_statistics, GFP_KERNEL);
-
- if (pcpu_stats) {
- int cpu;
+ pcpu_stats = alloc_percpu_gfp(struct spi_statistics, GFP_KERNEL);
+ if (!pcpu_stats)
+ return NULL;
- for_each_possible_cpu(cpu) {
- struct spi_statistics *stat;
+ for_each_possible_cpu(cpu) {
+ struct spi_statistics *stat;
- stat = per_cpu_ptr(pcpu_stats, cpu);
- u64_stats_init(&stat->syncp);
- }
+ stat = per_cpu_ptr(pcpu_stats, cpu);
+ u64_stats_init(&stat->syncp);
}
+
return pcpu_stats;
}
@@ -569,7 +566,7 @@ struct spi_device *spi_alloc_device(struct spi_controller *ctlr)
return NULL;
}
- spi->pcpu_statistics = spi_alloc_pcpu_stats(NULL);
+ spi->pcpu_statistics = spi_alloc_pcpu_stats();
if (!spi->pcpu_statistics) {
kfree(spi);
spi_controller_put(ctlr);
@@ -636,12 +633,26 @@ static inline int spi_dev_check_cs(struct device *dev,
return 0;
}
+struct spi_dev_check_info {
+ struct spi_device *new_spi;
+ struct spi_device *parent; /* set for ancillary devices */
+};
+
static int spi_dev_check(struct device *dev, void *data)
{
struct spi_device *spi = to_spi_device(dev);
- struct spi_device *new_spi = data;
+ struct spi_dev_check_info *info = data;
+ struct spi_device *new_spi = info->new_spi;
int status, idx;
+ /*
+ * When registering an ancillary device, skip checking against the
+ * parent device since the ancillary is intentionally using one of
+ * the parent's chip selects.
+ */
+ if (info->parent && spi == info->parent)
+ return 0;
+
if (spi->controller == new_spi->controller) {
for (idx = 0; idx < spi->num_chipselect; idx++) {
status = spi_dev_check_cs(dev, spi, idx, new_spi, 0);
@@ -658,10 +669,11 @@ static void spi_cleanup(struct spi_device *spi)
spi->controller->cleanup(spi);
}
-static int __spi_add_device(struct spi_device *spi)
+static int __spi_add_device(struct spi_device *spi, struct spi_device *parent)
{
struct spi_controller *ctlr = spi->controller;
struct device *dev = ctlr->dev.parent;
+ struct spi_dev_check_info check_info;
int status, idx;
u8 cs;
@@ -705,7 +717,9 @@ static int __spi_add_device(struct spi_device *spi)
* chipselect **BEFORE** we call setup(), else we'll trash
* its configuration.
*/
- status = bus_for_each_dev(&spi_bus_type, NULL, spi, spi_dev_check);
+ check_info.new_spi = spi;
+ check_info.parent = parent;
+ status = bus_for_each_dev(&spi_bus_type, NULL, &check_info, spi_dev_check);
if (status)
return status;
@@ -767,7 +781,7 @@ int spi_add_device(struct spi_device *spi)
spi_dev_set_name(spi);
mutex_lock(&ctlr->add_lock);
- status = __spi_add_device(spi);
+ status = __spi_add_device(spi, NULL);
mutex_unlock(&ctlr->add_lock);
return status;
}
@@ -2710,8 +2724,8 @@ struct spi_device *spi_new_ancillary_device(struct spi_device *spi,
WARN_ON(!mutex_is_locked(&ctlr->add_lock));
- /* Register the new device */
- rc = __spi_add_device(ancillary);
+ /* Register the new device, passing the parent to skip CS conflict check */
+ rc = __spi_add_device(ancillary, spi);
if (rc) {
dev_err(&spi->dev, "failed to register ancillary device\n");
goto err_out;
@@ -2725,6 +2739,46 @@ err_out:
}
EXPORT_SYMBOL_GPL(spi_new_ancillary_device);
+static void devm_spi_unregister_device(void *spi)
+{
+ spi_unregister_device(spi);
+}
+
+/**
+ * devm_spi_new_ancillary_device() - Register managed ancillary SPI device
+ * @spi: Pointer to the main SPI device registering the ancillary device
+ * @chip_select: Chip Select of the ancillary device
+ *
+ * Register an ancillary SPI device; for example some chips have a chip-select
+ * for normal device usage and another one for setup/firmware upload.
+ *
+ * This is the managed version of spi_new_ancillary_device(). The ancillary
+ * device will be unregistered automatically when the parent SPI device is
+ * unregistered.
+ *
+ * This may only be called from main SPI device's probe routine.
+ *
+ * Return: Pointer to new ancillary device on success; ERR_PTR on failure
+ */
+struct spi_device *devm_spi_new_ancillary_device(struct spi_device *spi,
+ u8 chip_select)
+{
+ struct spi_device *ancillary;
+ int ret;
+
+ ancillary = spi_new_ancillary_device(spi, chip_select);
+ if (IS_ERR(ancillary))
+ return ancillary;
+
+ ret = devm_add_action_or_reset(&spi->dev, devm_spi_unregister_device,
+ ancillary);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return ancillary;
+}
+EXPORT_SYMBOL_GPL(devm_spi_new_ancillary_device);
+
#ifdef CONFIG_ACPI
struct acpi_spi_lookup {
struct spi_controller *ctlr;
@@ -3189,7 +3243,7 @@ struct spi_controller *__spi_alloc_controller(struct device *dev,
if (!ctlr)
return NULL;
- ctlr->pcpu_statistics = spi_alloc_pcpu_stats(NULL);
+ ctlr->pcpu_statistics = spi_alloc_pcpu_stats();
if (!ctlr->pcpu_statistics) {
kfree(ctlr);
return NULL;
@@ -3386,8 +3440,8 @@ static int spi_controller_id_alloc(struct spi_controller *ctlr, int start, int e
* device identification, boards need configuration tables telling which
* chip is at which address.
*
- * This must be called from context that can sleep. It returns zero on
- * success, else a negative error code (dropping the controller's refcount).
+ * This must be called from context that can sleep.
+ *
* After a successful return, the caller is responsible for calling
* spi_unregister_controller().
*
@@ -3521,7 +3575,8 @@ static void devm_spi_unregister_controller(void *ctlr)
* Context: can sleep
*
* Register a SPI device as with spi_register_controller() which will
- * automatically be unregistered and freed.
+ * automatically be unregistered (and freed unless it has been allocated using
+ * devm_spi_alloc_host/target()).
*
* Return: zero on success, else a negative error code.
*/
@@ -3566,7 +3621,8 @@ static int __unregister(struct device *dev, void *null)
*
* This must be called from context that can sleep.
*
- * Note that this function also drops a reference to the controller.
+ * Note that this function also drops a reference to the controller unless it
+ * has been allocated using devm_spi_alloc_host/target().
*/
void spi_unregister_controller(struct spi_controller *ctlr)
{
@@ -4232,12 +4288,7 @@ static int __spi_validate(struct spi_device *spi, struct spi_message *message)
* SPI transfer length should be multiple of SPI word size
* where SPI word size should be power-of-two multiple.
*/
- if (xfer->bits_per_word <= 8)
- w_size = 1;
- else if (xfer->bits_per_word <= 16)
- w_size = 2;
- else
- w_size = 4;
+ w_size = spi_bpw_to_bytes(xfer->bits_per_word);
/* No partial transfers accepted */
if (xfer->len % w_size)
diff --git a/include/linux/spi/spi-mem.h b/include/linux/spi/spi-mem.h
index 5774e554c0f0..c8e207522223 100644
--- a/include/linux/spi/spi-mem.h
+++ b/include/linux/spi/spi-mem.h
@@ -28,6 +28,14 @@
.dtr = true, \
}
+#define SPI_MEM_DTR_OP_PACKED_CMD(__opcode, __addr, __buswidth) \
+ { \
+ .nbytes = 2, \
+ .opcode = __opcode << 8 | __addr, \
+ .buswidth = __buswidth, \
+ .dtr = true, \
+ }
+
#define SPI_MEM_OP_ADDR(__nbytes, __val, __buswidth) \
{ \
.nbytes = __nbytes, \
@@ -130,11 +138,13 @@ enum spi_mem_data_dir {
/**
* struct spi_mem_op - describes a SPI memory operation
+ * @cmd: the complete command
* @cmd.nbytes: number of opcode bytes (only 1 or 2 are valid). The opcode is
* sent MSB-first.
* @cmd.buswidth: number of IO lines used to transmit the command
* @cmd.opcode: operation opcode
* @cmd.dtr: whether the command opcode should be sent in DTR mode or not
+ * @addr: the address attributes
* @addr.nbytes: number of address bytes to send. Can be zero if the operation
* does not need to send an address
* @addr.buswidth: number of IO lines used to transmit the address cycles
@@ -143,10 +153,12 @@ enum spi_mem_data_dir {
* Note that only @addr.nbytes are taken into account in this
* address value, so users should make sure the value fits in the
* assigned number of bytes.
+ * @dummy: data for dummy operation
* @dummy.nbytes: number of dummy bytes to send after an opcode or address. Can
* be zero if the operation does not require dummy bytes
* @dummy.buswidth: number of IO lanes used to transmit the dummy bytes
* @dummy.dtr: whether the dummy bytes should be sent in DTR mode or not
+ * @data: the data attributes
* @data.buswidth: number of IO lanes used to send/receive the data
* @data.dtr: whether the data should be sent in DTR mode or not
* @data.ecc: whether error correction is required or not
@@ -273,7 +285,7 @@ struct spi_mem {
};
/**
- * struct spi_mem_set_drvdata() - attach driver private data to a SPI mem
+ * spi_mem_set_drvdata() - attach driver private data to a SPI mem
* device
* @mem: memory device
* @data: data to attach to the memory device
@@ -284,7 +296,7 @@ static inline void spi_mem_set_drvdata(struct spi_mem *mem, void *data)
}
/**
- * struct spi_mem_get_drvdata() - get driver private data attached to a SPI mem
+ * spi_mem_get_drvdata() - get driver private data attached to a SPI mem
* device
* @mem: memory device
*
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 0dc671c07d3a..7587b1c5d7ec 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -382,6 +382,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
}
extern struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 chip_select);
+extern struct spi_device *devm_spi_new_ancillary_device(struct spi_device *spi, u8 chip_select);
/* Use a define to avoid include chaining to get THIS_MODULE */
#define spi_register_driver(driver) \