diff options
| author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-07-24 16:21:27 +0200 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-07-24 16:21:27 +0200 |
| commit | 8f9aa2c90530ab92301a82231ae44f3722becd93 (patch) | |
| tree | fb282e955b0a880b07131a135257fe3ec764e928 /drivers/spi | |
| parent | 93467b31bec6da512b51544e5e4584f2745e995e (diff) | |
| parent | 155b42bec9cbb6b8cdc47dd9bd09503a81fbe493 (diff) | |
Merge v7.1.5linux-rolling-stable
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/spi')
| -rw-r--r-- | drivers/spi/spi-atcspi200.c | 13 | ||||
| -rw-r--r-- | drivers/spi/spi-atmel.c | 133 | ||||
| -rw-r--r-- | drivers/spi/spi-dw.h | 1 | ||||
| -rw-r--r-- | drivers/spi/spi-ep93xx.c | 1 | ||||
| -rw-r--r-- | drivers/spi/spi-hisi-kunpeng.c | 6 | ||||
| -rw-r--r-- | drivers/spi/spi-imx.c | 19 | ||||
| -rw-r--r-- | drivers/spi/spi-meson-spifc.c | 1 | ||||
| -rw-r--r-- | drivers/spi/spi-rpc-if.c | 6 | ||||
| -rw-r--r-- | drivers/spi/spi-rzv2h-rspi.c | 4 | ||||
| -rw-r--r-- | drivers/spi/spi-sh-msiof.c | 10 | ||||
| -rw-r--r-- | drivers/spi/spi-uniphier.c | 4 | ||||
| -rw-r--r-- | drivers/spi/spi-xilinx.c | 11 | ||||
| -rw-r--r-- | drivers/spi/spi.c | 5 |
13 files changed, 114 insertions, 100 deletions
diff --git a/drivers/spi/spi-atcspi200.c b/drivers/spi/spi-atcspi200.c index 3832d9db3cbf..c5cf1aa2d674 100644 --- a/drivers/spi/spi-atcspi200.c +++ b/drivers/spi/spi-atcspi200.c @@ -575,12 +575,6 @@ static int atcspi_probe(struct platform_device *pdev) if (ret) 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 free_controller; - } spi->use_dma = false; if (ATCSPI_DMA_SUPPORT) { ret = atcspi_configure_dma(spi); @@ -591,6 +585,13 @@ static int atcspi_probe(struct platform_device *pdev) spi->use_dma = true; } + ret = devm_spi_register_controller(&pdev->dev, host); + if (ret) { + dev_err_probe(spi->dev, ret, + "Failed to register SPI controller\n"); + goto free_controller; + } + return 0; free_controller: diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index 42db85d7ff8e..397bc819e716 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c @@ -559,6 +559,38 @@ static int atmel_spi_dma_slave_config(struct atmel_spi *as, u8 bits_per_word) return err; } +static void atmel_spi_release_dma(void *data) +{ + struct spi_controller *host = data; + struct atmel_spi *as = spi_controller_get_devdata(host); + struct device *dev = &as->pdev->dev; + + if (host->dma_tx) { + dma_release_channel(host->dma_tx); + host->dma_tx = NULL; + } + + if (host->dma_rx) { + dma_release_channel(host->dma_rx); + host->dma_rx = NULL; + } + + if (IS_ENABLED(CONFIG_SOC_SAM_V4_V5)) { + if (as->addr_tx_bbuf) { + dma_free_coherent(dev, SPI_MAX_DMA_XFER, + as->addr_tx_bbuf, + as->dma_addr_tx_bbuf); + as->addr_tx_bbuf = NULL; + } + if (as->addr_rx_bbuf) { + dma_free_coherent(dev, SPI_MAX_DMA_XFER, + as->addr_rx_bbuf, + as->dma_addr_rx_bbuf); + as->addr_rx_bbuf = NULL; + } + } +} + static int atmel_spi_configure_dma(struct spi_controller *host, struct atmel_spi *as) { @@ -569,7 +601,8 @@ static int atmel_spi_configure_dma(struct spi_controller *host, if (IS_ERR(host->dma_tx)) { err = PTR_ERR(host->dma_tx); dev_dbg(dev, "No TX DMA channel, DMA is disabled\n"); - goto error_clear; + host->dma_tx = NULL; + return err; } host->dma_rx = dma_request_chan(dev, "rx"); @@ -580,26 +613,45 @@ static int atmel_spi_configure_dma(struct spi_controller *host, * requested tx channel. */ dev_dbg(dev, "No RX DMA channel, DMA is disabled\n"); - goto error; + host->dma_rx = NULL; + goto err_release_dma; } err = atmel_spi_dma_slave_config(as, 8); if (err) - goto error; + goto err_release_dma; + + if (IS_ENABLED(CONFIG_SOC_SAM_V4_V5)) { + as->addr_tx_bbuf = dma_alloc_coherent(dev, SPI_MAX_DMA_XFER, + &as->dma_addr_tx_bbuf, + GFP_KERNEL | GFP_DMA); + if (!as->addr_tx_bbuf) { + err = -ENOMEM; + goto err_release_dma; + } + + as->addr_rx_bbuf = dma_alloc_coherent(dev, SPI_MAX_DMA_XFER, + &as->dma_addr_rx_bbuf, + GFP_KERNEL | GFP_DMA); + if (!as->addr_rx_bbuf) { + err = -ENOMEM; + goto err_release_dma; + } + } + + err = devm_add_action_or_reset(dev, atmel_spi_release_dma, host); + if (err) + return err; dev_info(&as->pdev->dev, - "Using %s (tx) and %s (rx) for DMA transfers\n", - dma_chan_name(host->dma_tx), - dma_chan_name(host->dma_rx)); + "Using %s (tx) and %s (rx) for DMA transfers\n", + dma_chan_name(host->dma_tx), dma_chan_name(host->dma_rx)); return 0; -error: - if (!IS_ERR(host->dma_rx)) - dma_release_channel(host->dma_rx); - if (!IS_ERR(host->dma_tx)) - dma_release_channel(host->dma_tx); -error_clear: - host->dma_tx = host->dma_rx = NULL; + +err_release_dma: + atmel_spi_release_dma(host); + return err; } @@ -611,18 +663,6 @@ static void atmel_spi_stop_dma(struct spi_controller *host) dmaengine_terminate_all(host->dma_tx); } -static void atmel_spi_release_dma(struct spi_controller *host) -{ - if (host->dma_rx) { - dma_release_channel(host->dma_rx); - host->dma_rx = NULL; - } - if (host->dma_tx) { - dma_release_channel(host->dma_tx); - host->dma_tx = NULL; - } -} - /* This function is called by the DMA driver from tasklet context */ static void dma_callback(void *data) { @@ -1585,30 +1625,6 @@ static int atmel_spi_probe(struct platform_device *pdev) as->use_pdc = true; } - if (IS_ENABLED(CONFIG_SOC_SAM_V4_V5)) { - as->addr_rx_bbuf = dma_alloc_coherent(&pdev->dev, - SPI_MAX_DMA_XFER, - &as->dma_addr_rx_bbuf, - GFP_KERNEL | GFP_DMA); - if (!as->addr_rx_bbuf) { - as->use_dma = false; - } else { - as->addr_tx_bbuf = dma_alloc_coherent(&pdev->dev, - SPI_MAX_DMA_XFER, - &as->dma_addr_tx_bbuf, - GFP_KERNEL | GFP_DMA); - if (!as->addr_tx_bbuf) { - as->use_dma = false; - dma_free_coherent(&pdev->dev, SPI_MAX_DMA_XFER, - as->addr_rx_bbuf, - as->dma_addr_rx_bbuf); - } - } - if (!as->use_dma) - dev_info(host->dev.parent, - " can not allocate dma coherent memory\n"); - } - if (as->caps.has_dma_support && !as->use_dma) dev_info(&pdev->dev, "Atmel SPI Controller using PIO only\n"); @@ -1668,13 +1684,10 @@ static int atmel_spi_probe(struct platform_device *pdev) out_free_dma: pm_runtime_disable(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); - - if (as->use_dma) - atmel_spi_release_dma(host); - spi_writel(as, CR, SPI_BIT(SWRST)); spi_writel(as, CR, SPI_BIT(SWRST)); /* AT91SAM9263 Rev B workaround */ - clk_disable_unprepare(as->gclk); + if (as->gclk) + clk_disable_unprepare(as->gclk); out_disable_clk: clk_disable_unprepare(clk); out_free_irq: @@ -1695,18 +1708,8 @@ static void atmel_spi_remove(struct platform_device *pdev) spi_unregister_controller(host); /* reset the hardware and block queue progress */ - if (as->use_dma) { + if (as->use_dma) atmel_spi_stop_dma(host); - atmel_spi_release_dma(host); - if (IS_ENABLED(CONFIG_SOC_SAM_V4_V5)) { - dma_free_coherent(&pdev->dev, SPI_MAX_DMA_XFER, - as->addr_tx_bbuf, - as->dma_addr_tx_bbuf); - dma_free_coherent(&pdev->dev, SPI_MAX_DMA_XFER, - as->addr_rx_bbuf, - as->dma_addr_rx_bbuf); - } - } spin_lock_irq(&as->lock); spi_writel(as, CR, SPI_BIT(SWRST)); diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index 9cc79c566a70..2f2debc64e73 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h @@ -282,6 +282,7 @@ static inline void dw_spi_shutdown_chip(struct dw_spi *dws) { dw_spi_enable_chip(dws, 0); dw_spi_set_clk(dws, 0); + dws->current_freq = 0; } extern void dw_spi_set_cs(struct spi_device *spi, bool enable); diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index f716c9607be4..4cab0d97a68a 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c @@ -600,6 +600,7 @@ fail_release_rx: espi->dma_rx = NULL; fail_free_page: free_page((unsigned long)espi->zeropage); + espi->zeropage = NULL; return ret; } diff --git a/drivers/spi/spi-hisi-kunpeng.c b/drivers/spi/spi-hisi-kunpeng.c index 046bd894040b..395214b81179 100644 --- a/drivers/spi/spi-hisi-kunpeng.c +++ b/drivers/spi/spi-hisi-kunpeng.c @@ -520,10 +520,8 @@ static int hisi_spi_probe(struct platform_device *pdev) } ret = spi_register_controller(host); - if (ret) { - dev_err(dev, "failed to register spi host, ret=%d\n", ret); - return ret; - } + if (ret) + return dev_err_probe(dev, ret, "failed to register spi host\n"); if (hisi_spi_debugfs_init(hs)) dev_info(dev, "failed to create debugfs dir\n"); diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 480d1e8b281f..79a6c1a60b0a 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c @@ -1774,8 +1774,8 @@ static int spi_imx_dma_submit(struct spi_imx_data *spi_imx, transfer_timeout); if (!time_left) { dev_err(spi_imx->dev, "I/O Error in DMA TX\n"); - dmaengine_terminate_all(controller->dma_tx); - dmaengine_terminate_all(controller->dma_rx); + dmaengine_terminate_sync(controller->dma_tx); + dmaengine_terminate_sync(controller->dma_rx); return -ETIMEDOUT; } @@ -1784,7 +1784,7 @@ static int spi_imx_dma_submit(struct spi_imx_data *spi_imx, if (!time_left) { dev_err(&controller->dev, "I/O Error in DMA RX\n"); spi_imx->devtype_data->reset(spi_imx); - dmaengine_terminate_all(controller->dma_rx); + dmaengine_terminate_sync(controller->dma_rx); return -ETIMEDOUT; } } else { @@ -1793,15 +1793,15 @@ static int spi_imx_dma_submit(struct spi_imx_data *spi_imx, if (wait_for_completion_interruptible(&spi_imx->dma_tx_completion) || READ_ONCE(spi_imx->target_aborted)) { dev_dbg(spi_imx->dev, "I/O Error in DMA TX interrupted\n"); - dmaengine_terminate_all(controller->dma_tx); - dmaengine_terminate_all(controller->dma_rx); + dmaengine_terminate_sync(controller->dma_tx); + dmaengine_terminate_sync(controller->dma_rx); return -EINTR; } if (wait_for_completion_interruptible(&spi_imx->dma_rx_completion) || READ_ONCE(spi_imx->target_aborted)) { dev_dbg(spi_imx->dev, "I/O Error in DMA RX interrupted\n"); - dmaengine_terminate_all(controller->dma_rx); + dmaengine_terminate_sync(controller->dma_rx); return -EINTR; } @@ -1818,9 +1818,9 @@ static int spi_imx_dma_submit(struct spi_imx_data *spi_imx, return 0; dmaengine_terminate_tx: - dmaengine_terminate_all(controller->dma_tx); + dmaengine_terminate_sync(controller->dma_tx); dmaengine_terminate_rx: - dmaengine_terminate_all(controller->dma_rx); + dmaengine_terminate_sync(controller->dma_rx); return -EINVAL; } @@ -2152,7 +2152,8 @@ static int spi_imx_transfer_one(struct spi_controller *controller, if (spi_imx->usedma) { ret = spi_imx_dma_transfer(spi_imx, transfer); if (transfer->error & SPI_TRANS_FAIL_NO_START) { - spi_imx->usedma = false; + controller->fallback = true; + spi_imx_setupxfer(spi, transfer); if (spi_imx->target_mode) return spi_imx_pio_transfer_target(spi, transfer); else diff --git a/drivers/spi/spi-meson-spifc.c b/drivers/spi/spi-meson-spifc.c index b818950a8cb7..e2d19c3873f7 100644 --- a/drivers/spi/spi-meson-spifc.c +++ b/drivers/spi/spi-meson-spifc.c @@ -351,6 +351,7 @@ static void meson_spifc_remove(struct platform_device *pdev) { pm_runtime_get_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); } #ifdef CONFIG_PM_SLEEP diff --git a/drivers/spi/spi-rpc-if.c b/drivers/spi/spi-rpc-if.c index 6edc0c4db854..c2f9c86c1d8d 100644 --- a/drivers/spi/spi-rpc-if.c +++ b/drivers/spi/spi-rpc-if.c @@ -206,8 +206,12 @@ static int rpcif_spi_suspend(struct device *dev) static int rpcif_spi_resume(struct device *dev) { struct spi_controller *ctlr = dev_get_drvdata(dev); + struct rpcif *rpc = spi_controller_get_devdata(ctlr); + int ret; - rpcif_hw_init(dev, false); + ret = rpcif_hw_init(rpc->dev, false); + if (ret) + return ret; return spi_controller_resume(ctlr); } diff --git a/drivers/spi/spi-rzv2h-rspi.c b/drivers/spi/spi-rzv2h-rspi.c index 6ed3fad873b8..190d7eb2034a 100644 --- a/drivers/spi/spi-rzv2h-rspi.c +++ b/drivers/spi/spi-rzv2h-rspi.c @@ -366,14 +366,14 @@ static int rzv2h_rspi_transfer_dma(struct rzv2h_rspi_priv *rspi, rzv2h_rspi_clear_all_irqs(rspi); ret = wait_event_interruptible_timeout(rspi->wait, rspi->dma_callbacked, HZ); - if (ret) { + if (ret > 0) { dmaengine_synchronize(rspi->controller->dma_tx); dmaengine_synchronize(rspi->controller->dma_rx); ret = 0; } else { dmaengine_terminate_sync(rspi->controller->dma_tx); dmaengine_terminate_sync(rspi->controller->dma_rx); - ret = -ETIMEDOUT; + ret = ret ?: -ETIMEDOUT; } enable_irq(rspi->irq_rx); diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index f114b6313f4f..5e49ce15ac4d 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c @@ -114,7 +114,7 @@ static irqreturn_t sh_msiof_spi_irq(int irq, void *data) return IRQ_HANDLED; } -static void sh_msiof_spi_reset_regs(struct sh_msiof_spi_priv *p) +static int sh_msiof_spi_reset_regs(struct sh_msiof_spi_priv *p) { u32 mask = SICTR_TXRST | SICTR_RXRST; u32 data; @@ -123,8 +123,8 @@ static void sh_msiof_spi_reset_regs(struct sh_msiof_spi_priv *p) data |= mask; sh_msiof_write(p, SICTR, data); - readl_poll_timeout_atomic(p->mapbase + SICTR, data, !(data & mask), 1, - 100); + return readl_poll_timeout_atomic(p->mapbase + SICTR, data, + !(data & mask), 1, 100); } static void sh_msiof_spi_set_clk_regs(struct sh_msiof_spi_priv *p, @@ -834,7 +834,9 @@ static int sh_msiof_transfer_one(struct spi_controller *ctlr, int ret; /* reset registers */ - sh_msiof_spi_reset_regs(p); + ret = sh_msiof_spi_reset_regs(p); + if (ret) + return ret; /* setup clocks (clock already enabled in chipselect()) */ if (!spi_controller_is_target(p->ctlr)) diff --git a/drivers/spi/spi-uniphier.c b/drivers/spi/spi-uniphier.c index eac6c3e8908b..f2859e96003a 100644 --- a/drivers/spi/spi-uniphier.c +++ b/drivers/spi/spi-uniphier.c @@ -659,6 +659,8 @@ static int uniphier_spi_probe(struct platform_device *pdev) priv->host = host; priv->is_save_param = false; + init_completion(&priv->xfer_done); + priv->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(priv->base)) { ret = PTR_ERR(priv->base); @@ -686,8 +688,6 @@ static int uniphier_spi_probe(struct platform_device *pdev) goto out_host_put; } - init_completion(&priv->xfer_done); - clk_rate = clk_get_rate(priv->clk); host->max_speed_hz = DIV_ROUND_UP(clk_rate, SSI_MIN_CLK_DIVIDER); diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c index 9f065d4e27d1..b95485710e2f 100644 --- a/drivers/spi/spi-xilinx.c +++ b/drivers/spi/spi-xilinx.c @@ -371,11 +371,18 @@ static int xilinx_spi_find_buffer_size(struct xilinx_spi *xspi) xspi->regs + XIPIF_V123B_RESETR_OFFSET); /* Fill the Tx FIFO with as many words as possible */ - do { + while (1) { xspi->write_fn(0, xspi->regs + XSPI_TXD_OFFSET); sr = xspi->read_fn(xspi->regs + XSPI_SR_OFFSET); + if (sr & XSPI_SR_TX_FULL_MASK) + break; + n_words++; - } while (!(sr & XSPI_SR_TX_FULL_MASK)); + } + + /* Handle the NO FIFO case separately */ + if (!n_words) + return 1; return n_words; } diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 104279858f56..889e1eecc757 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -5003,11 +5003,6 @@ static int of_spi_notify(struct notifier_block *nb, unsigned long action, return NOTIFY_OK; } - /* - * Clear the flag before adding the device so that fw_devlink - * doesn't skip adding consumers to this device. - */ - fwnode_clear_flag(&rd->dn->fwnode, FWNODE_FLAG_NOT_DEVICE); spi = of_register_spi_device(ctlr, rd->dn); put_device(&ctlr->dev); |
