Merge tag 'spi-fix-v6.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 23 Nov 2022 19:19:06 +0000 (11:19 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 23 Nov 2022 19:19:06 +0000 (11:19 -0800)
Pull spi fixes from Mark Brown:
 "A few fixes, all device specific.

  The most important ones are for the i.MX driver which had a couple of
  nasty data corruption inducing errors appear after the change to
  support PIO mode in the last merge window (one introduced by the
  change and one latent one which the PIO changes exposed).

  Thanks to Frieder, Fabio, Marc and Marek for jumping on that and
  resolving the issues quickly once they were found"

* tag 'spi-fix-v6.1-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi:
  spi: spi-imx: spi_imx_transfer_one(): check for DMA transfer first
  spi: tegra210-quad: Fix duplicate resource error
  spi: dw-dma: decrease reference count in dw_spi_dma_init_mfld()
  spi: spi-imx: Fix spi_bus_clk if requested clock is higher than input clock
  spi: mediatek: Fix DEVAPC Violation at KO Remove

drivers/spi/spi-dw-dma.c
drivers/spi/spi-imx.c
drivers/spi/spi-mt65xx.c
drivers/spi/spi-tegra210-quad.c

index 1322b8cce5b7c542f39b2022105fb50ed7aa1a26..ababb910b3914c84e88998d16b79ab6444eaac18 100644 (file)
@@ -128,12 +128,15 @@ static int dw_spi_dma_init_mfld(struct device *dev, struct dw_spi *dws)
 
        dw_spi_dma_sg_burst_init(dws);
 
+       pci_dev_put(dma_dev);
+
        return 0;
 
 free_rxchan:
        dma_release_channel(dws->rxchan);
        dws->rxchan = NULL;
 err_exit:
+       pci_dev_put(dma_dev);
        return -EBUSY;
 }
 
index 30d82cc7300b2472f6111a39ea8d9f1950016295..d209930069cf3d1ab873537bca7a3e3184baf491 100644 (file)
@@ -444,8 +444,7 @@ static unsigned int mx51_ecspi_clkdiv(struct spi_imx_data *spi_imx,
        unsigned int pre, post;
        unsigned int fin = spi_imx->spi_clk;
 
-       if (unlikely(fspi > fin))
-               return 0;
+       fspi = min(fspi, fin);
 
        post = fls(fin) - fls(fspi);
        if (fin > fspi << post)
@@ -1607,6 +1606,13 @@ static int spi_imx_transfer_one(struct spi_controller *controller,
        if (spi_imx->slave_mode)
                return spi_imx_pio_transfer_slave(spi, transfer);
 
+       /*
+        * If we decided in spi_imx_can_dma() that we want to do a DMA
+        * transfer, the SPI transfer has already been mapped, so we
+        * have to do the DMA transfer here.
+        */
+       if (spi_imx->usedma)
+               return spi_imx_dma_transfer(spi_imx, transfer);
        /*
         * Calculate the estimated time in us the transfer runs. Find
         * the number of Hz per byte per polling limit.
@@ -1618,9 +1624,6 @@ static int spi_imx_transfer_one(struct spi_controller *controller,
        if (transfer->len < byte_limit)
                return spi_imx_poll_transfer(spi, transfer);
 
-       if (spi_imx->usedma)
-               return spi_imx_dma_transfer(spi_imx, transfer);
-
        return spi_imx_pio_transfer(spi, transfer);
 }
 
index a33c9a3de395fd2972fd22fdf673b9975aa8b20f..d6aff909fc365e0fa48f0cdd2b20fa52659f7232 100644 (file)
@@ -1273,8 +1273,11 @@ static int mtk_spi_remove(struct platform_device *pdev)
 {
        struct spi_master *master = platform_get_drvdata(pdev);
        struct mtk_spi *mdata = spi_master_get_devdata(master);
+       int ret;
 
-       pm_runtime_disable(&pdev->dev);
+       ret = pm_runtime_resume_and_get(&pdev->dev);
+       if (ret < 0)
+               return ret;
 
        mtk_spi_reset(mdata);
 
@@ -1283,6 +1286,9 @@ static int mtk_spi_remove(struct platform_device *pdev)
                clk_unprepare(mdata->spi_hclk);
        }
 
+       pm_runtime_put_noidle(&pdev->dev);
+       pm_runtime_disable(&pdev->dev);
+
        return 0;
 }
 
index 10f0c5a6e0dce44ef26221b703b8e7db87f22d03..9f356612ba7e54f46fb5868e6675904a6ad20c6c 100644 (file)
@@ -924,8 +924,9 @@ static int tegra_qspi_start_transfer_one(struct spi_device *spi,
 static struct tegra_qspi_client_data *tegra_qspi_parse_cdata_dt(struct spi_device *spi)
 {
        struct tegra_qspi_client_data *cdata;
+       struct tegra_qspi *tqspi = spi_master_get_devdata(spi->master);
 
-       cdata = devm_kzalloc(&spi->dev, sizeof(*cdata), GFP_KERNEL);
+       cdata = devm_kzalloc(tqspi->dev, sizeof(*cdata), GFP_KERNEL);
        if (!cdata)
                return NULL;