From 6022eacdda8b0b06a2e1d4122e5268099b62ff5d Mon Sep 17 00:00:00 2001 From: Vishwaroop A Date: Tue, 28 Oct 2025 15:57:02 +0000 Subject: [PATCH] spi: tegra210-quad: Refactor error handling into helper functions 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 Acked-by: Thierry Reding Link: https://patch.msgid.link/20251028155703.4151791-3-va@nvidia.com Signed-off-by: Mark Brown --- drivers/spi/spi-tegra210-quad.c | 84 +++++++++++++++++---------------- 1 file changed, 44 insertions(+), 40 deletions(-) diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c index d9ca3d7b082f2..69defb4ffe498 100644 --- a/drivers/spi/spi-tegra210-quad.c +++ b/drivers/spi/spi-tegra210-quad.c @@ -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; -- 2.47.3