From: Breno Leitao Date: Wed, 8 Apr 2026 13:45:43 +0000 (-0700) Subject: spi: tegra210-quad: Fix false positive WARN on interrupt timeout with transfer complete X-Git-Tag: v7.1-rc1~153^2~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5b94c94caafcad3c77cc6b1d213a93bf5dc0a98e;p=thirdparty%2Fkernel%2Flinux.git spi: tegra210-quad: Fix false positive WARN on interrupt timeout with transfer complete The WARN_ON_ONCE/WARN_ON fired unconditionally on any completion timeout, including the recoverable case where the interrupt was lost but the hardware actually finished the transfer. This produced a noisy splat with a full call trace even though the driver successfully recovered via tegra_qspi_handle_timeout(). Since tegra210 uses threaded interrupts, the transfer completion can be signaled before the interrupt fires, making this false positive case common in practice. Almost all the hosts I sysadmin in my fleet produce the following splat: WARNING: CPU: 47 PID: 844 at drivers/spi/spi-tegra210-quad.c:1226 tegra_qspi_transfer_one_message+0x8a4/0xba8 .... tegra-qspi NVDA1513:00: QSPI interrupt timeout, but transfer complete Move WARN_ON_ONCE/WARN_ON to fire only on real unrecoverable timeouts, i.e., when tegra_qspi_handle_timeout() confirms the hardware did NOT complete. This makes the warning actionable instead of just polluting the metrics. Signed-off-by: Breno Leitao Link: https://patch.msgid.link/20260408-tegra_warn-v1-1-669a3bc74d77@debian.org Signed-off-by: Mark Brown --- diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c index 7cca5578eba31..db28dd556484b 100644 --- a/drivers/spi/spi-tegra210-quad.c +++ b/drivers/spi/spi-tegra210-quad.c @@ -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)