]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
spi: tegra210-quad: Refactor error handling into helper functions
authorVishwaroop A <va@nvidia.com>
Tue, 28 Oct 2025 15:57:02 +0000 (15:57 +0000)
committerMark Brown <broonie@kernel.org>
Tue, 4 Nov 2025 16:48:54 +0000 (16:48 +0000)
Extract common cleanup code into dedicated helper functions to simplify
the code and improve readability. This refactoring includes:

- tegra_qspi_reset(): Device reset and interrupt cleanup
- tegra_qspi_dma_stop(): DMA termination and disable
- tegra_qspi_pio_stop(): PIO mode disable

No functional changes. This is purely a code reorganization to prepare
for improved timeout handling in subsequent patches.

Signed-off-by: Vishwaroop A <va@nvidia.com>
Acked-by: Thierry Reding <treding@nvidia.com>
Link: https://patch.msgid.link/20251028155703.4151791-3-va@nvidia.com
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi-tegra210-quad.c

index d9ca3d7b082f296491090ebc5cc993ba11147be5..69defb4ffe498d34f0dc938a042b9912ef27ccab 100644 (file)
@@ -1019,17 +1019,22 @@ static void tegra_qspi_dump_regs(struct tegra_qspi *tqspi)
                tegra_qspi_readl(tqspi, QSPI_FIFO_STATUS));
 }
 
-static void tegra_qspi_handle_error(struct tegra_qspi *tqspi)
+static void tegra_qspi_reset(struct tegra_qspi *tqspi)
 {
-       dev_err(tqspi->dev, "error in transfer, fifo status 0x%08x\n", tqspi->status_reg);
-       tegra_qspi_dump_regs(tqspi);
-       tegra_qspi_flush_fifos(tqspi, true);
        if (device_reset(tqspi->dev) < 0) {
                dev_warn_once(tqspi->dev, "device reset failed\n");
                tegra_qspi_mask_clear_irq(tqspi);
        }
 }
 
+static void tegra_qspi_handle_error(struct tegra_qspi *tqspi)
+{
+       dev_err(tqspi->dev, "error in transfer, fifo status 0x%08x\n", tqspi->status_reg);
+       tegra_qspi_dump_regs(tqspi);
+       tegra_qspi_flush_fifos(tqspi, true);
+       tegra_qspi_reset(tqspi);
+}
+
 static void tegra_qspi_transfer_end(struct spi_device *spi)
 {
        struct tegra_qspi *tqspi = spi_controller_get_devdata(spi->controller);
@@ -1074,6 +1079,30 @@ static u32 tegra_qspi_addr_config(bool is_ddr, u8 bus_width, u8 len)
        return addr_config;
 }
 
+static void tegra_qspi_dma_stop(struct tegra_qspi *tqspi)
+{
+       u32 value;
+
+       if ((tqspi->cur_direction & DATA_DIR_TX) && tqspi->tx_dma_chan)
+               dmaengine_terminate_all(tqspi->tx_dma_chan);
+
+       if ((tqspi->cur_direction & DATA_DIR_RX) && tqspi->rx_dma_chan)
+               dmaengine_terminate_all(tqspi->rx_dma_chan);
+
+       value = tegra_qspi_readl(tqspi, QSPI_DMA_CTL);
+       value &= ~QSPI_DMA_EN;
+       tegra_qspi_writel(tqspi, value, QSPI_DMA_CTL);
+}
+
+static void tegra_qspi_pio_stop(struct tegra_qspi *tqspi)
+{
+       u32 value;
+
+       value = tegra_qspi_readl(tqspi, QSPI_COMMAND1);
+       value &= ~QSPI_PIO;
+       tegra_qspi_writel(tqspi, value, QSPI_COMMAND1);
+}
+
 static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi,
                                        struct spi_message *msg)
 {
@@ -1081,7 +1110,7 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi,
        struct spi_transfer *xfer;
        struct spi_device *spi = msg->spi;
        u8 transfer_phase = 0;
-       u32 cmd1 = 0, dma_ctl = 0;
+       u32 cmd1 = 0;
        int ret = 0;
        u32 address_value = 0;
        u32 cmd_config = 0, addr_config = 0;
@@ -1150,39 +1179,16 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi,
                        if (WARN_ON_ONCE(ret == 0)) {
                                dev_err_ratelimited(tqspi->dev,
                                                    "QSPI Transfer failed with timeout\n");
-                               if (tqspi->is_curr_dma_xfer) {
-                                       if ((tqspi->cur_direction & DATA_DIR_TX) &&
-                                           tqspi->tx_dma_chan)
-                                               dmaengine_terminate_all(tqspi->tx_dma_chan);
-                                       if ((tqspi->cur_direction & DATA_DIR_RX) &&
-                                           tqspi->rx_dma_chan)
-                                               dmaengine_terminate_all(tqspi->rx_dma_chan);
-                               }
 
                                /* Abort transfer by resetting pio/dma bit */
-                               if (!tqspi->is_curr_dma_xfer) {
-                                       cmd1 = tegra_qspi_readl
-                                                       (tqspi,
-                                                        QSPI_COMMAND1);
-                                       cmd1 &= ~QSPI_PIO;
-                                       tegra_qspi_writel
-                                                       (tqspi, cmd1,
-                                                        QSPI_COMMAND1);
-                               } else {
-                                       dma_ctl = tegra_qspi_readl
-                                                       (tqspi,
-                                                        QSPI_DMA_CTL);
-                                       dma_ctl &= ~QSPI_DMA_EN;
-                                       tegra_qspi_writel(tqspi, dma_ctl,
-                                                         QSPI_DMA_CTL);
-                               }
+                               if (tqspi->is_curr_dma_xfer)
+                                       tegra_qspi_dma_stop(tqspi);
+                               else
+                                       tegra_qspi_pio_stop(tqspi);
 
                                /* Reset controller if timeout happens */
-                               if (device_reset(tqspi->dev) < 0) {
-                                       dev_warn_once(tqspi->dev,
-                                                     "device reset failed\n");
-                                       tegra_qspi_mask_clear_irq(tqspi);
-                               }
+                               tegra_qspi_reset(tqspi);
+
                                ret = -EIO;
                                goto exit;
                        }
@@ -1276,12 +1282,10 @@ static int tegra_qspi_non_combined_seq_xfer(struct tegra_qspi *tqspi,
                                                  QSPI_DMA_TIMEOUT);
                if (WARN_ON(ret == 0)) {
                        dev_err(tqspi->dev, "transfer timeout\n");
-                       if (tqspi->is_curr_dma_xfer) {
-                               if ((tqspi->cur_direction & DATA_DIR_TX) && tqspi->tx_dma_chan)
-                                       dmaengine_terminate_all(tqspi->tx_dma_chan);
-                               if ((tqspi->cur_direction & DATA_DIR_RX) && tqspi->rx_dma_chan)
-                                       dmaengine_terminate_all(tqspi->rx_dma_chan);
-                       }
+
+                       if (tqspi->is_curr_dma_xfer)
+                               tegra_qspi_dma_stop(tqspi);
+
                        tegra_qspi_handle_error(tqspi);
                        ret = -EIO;
                        goto complete_xfer;