]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
spi: geni-qcom: Fix abort sequence execution for serial engine errors
authorPraveen Talari <praveen.talari@oss.qualcomm.com>
Wed, 4 Feb 2026 16:28:52 +0000 (21:58 +0530)
committerMark Brown <broonie@kernel.org>
Wed, 4 Feb 2026 17:37:34 +0000 (17:37 +0000)
The driver currently skips the abort sequence for target mode when serial
engine errors occur. This leads to improper error recovery as the serial
engine may remain in an undefined state without proper cleanup, potentially
causing subsequent operations to fail or behave unpredictably.

Fix this by ensuring the abort sequence and DMA reset always execute during
error recovery, as both are required for proper serial engine error
handling.

Co-developed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Signed-off-by: Praveen Talari <praveen.talari@oss.qualcomm.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@oss.qualcomm.com>
Link: https://patch.msgid.link/20260204162854.1206323-3-praveen.talari@oss.qualcomm.com
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi-geni-qcom.c

index f886a9ba56e6e0d74982489fcac0a674aff47c9d..e48aea7ce681a8275a90f424da067f8ac41c208d 100644 (file)
@@ -161,24 +161,20 @@ static void handle_se_timeout(struct spi_controller *spi,
        xfer = mas->cur_xfer;
        mas->cur_xfer = NULL;
 
-       if (spi->target) {
-               /*
-                * skip CMD Cancel sequnece since spi target
-                * doesn`t support CMD Cancel sequnece
-                */
+       /* The controller doesn't support the Cancel commnand in target mode */
+       if (!spi->target) {
+               reinit_completion(&mas->cancel_done);
+               geni_se_cancel_m_cmd(se);
+
                spin_unlock_irq(&mas->lock);
-               goto reset_if_dma;
-       }
 
-       reinit_completion(&mas->cancel_done);
-       geni_se_cancel_m_cmd(se);
-       spin_unlock_irq(&mas->lock);
+               time_left = wait_for_completion_timeout(&mas->cancel_done, HZ);
+               if (time_left)
+                       goto reset_if_dma;
 
-       time_left = wait_for_completion_timeout(&mas->cancel_done, HZ);
-       if (time_left)
-               goto reset_if_dma;
+               spin_lock_irq(&mas->lock);
+       }
 
-       spin_lock_irq(&mas->lock);
        reinit_completion(&mas->abort_done);
        geni_se_abort_m_cmd(se);
        spin_unlock_irq(&mas->lock);