]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
scsi: ufs: core: Fix interrupt handling for MCQ Mode
authorNitin Rawat <quic_nitirawa@quicinc.com>
Mon, 28 Jul 2025 22:57:11 +0000 (04:27 +0530)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 6 Aug 2025 01:52:53 +0000 (21:52 -0400)
Commit 3c7ac40d7322 ("scsi: ufs: core: Delegate the interrupt service
routine to a threaded IRQ handler") introduced a regression where the UFS
interrupt status register (IS) was not cleared in ufshcd_intr() when
operating in MCQ mode. As a result, the IS register remained uncleared.

This led to a persistent issue during UIC interrupts:
ufshcd_is_auto_hibern8_error() consistently returned true because the
UFSHCD_UIC_HIBERN8_MASK bit was set, while the active command was neither
UIC_CMD_DME_HIBER_ENTER nor UIC_CMD_DME_HIBER_EXIT. This caused
continuous auto hibern8 enter errors and device failed to boot.

To fix this, ensure that the interrupt status register is properly
cleared in the ufshcd_intr() function for both MCQ mode with ESI enabled.

[    4.553226] ufshcd-qcom 1d84000.ufs: ufshcd_check_errors: Auto
Hibern8 Enter failed - status: 0x00000040, upmcrs: 0x00000001
[    4.553229] ufshcd-qcom 1d84000.ufs: ufshcd_check_errors: saved_err
0x40 saved_uic_err 0x0
[    4.553311] host_regs: 00000000d5c7033f 20e0071f 00000400 00000000
[    4.553312] host_regs: 0000001001000000 00010217 00000c96 00000000
[    4.553314] host_regs: 0000002000000440 00170ef5 00000000 00000000
[    4.553316] host_regs: 000000300000010f 00000001 00000000 00000000
[    4.553317] host_regs: 0000004000000000 00000000 00000000 00000000
[    4.553319] host_regs: 00000050fffdf000 0000000f 00000000 00000000
[    4.553320] host_regs: 0000006000000001 80000000 00000000 00000000
[    4.553322] host_regs: 00000070fffde000 0000000f 00000000 00000000
[    4.553323] host_regs: 0000008000000001 00000000 00000000 00000000
[    4.553325] host_regs: 0000009000000002 d0020000 00000000 01930200

Fixes: 3c7ac40d7322 ("scsi: ufs: core: Delegate the interrupt service routine to a threaded IRQ handler")
Co-developed-by: Palash Kambar <quic_pkambar@quicinc.com>
Signed-off-by: Palash Kambar <quic_pkambar@quicinc.com>
Signed-off-by: Nitin Rawat <quic_nitirawa@quicinc.com>
Link: https://lore.kernel.org/r/20250728225711.29273-1-quic_nitirawa@quicinc.com
Tested-by: Neil Armstrong <neil.armstrong@linaro.org> # on SM8650-QRD
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Peter Wang <peter.wang@mediatek.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/ufs/core/ufshcd.c

index 5442bb8540b50f92f98424e52f637fa7c9191b98..baf28bd748ccf0af8f453f43fd42b57d4e3068d4 100644 (file)
@@ -7133,14 +7133,19 @@ static irqreturn_t ufshcd_threaded_intr(int irq, void *__hba)
 static irqreturn_t ufshcd_intr(int irq, void *__hba)
 {
        struct ufs_hba *hba = __hba;
+       u32 intr_status, enabled_intr_status;
 
        /* Move interrupt handling to thread when MCQ & ESI are not enabled */
        if (!hba->mcq_enabled || !hba->mcq_esi_enabled)
                return IRQ_WAKE_THREAD;
 
+       intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS);
+       enabled_intr_status = intr_status & ufshcd_readl(hba, REG_INTERRUPT_ENABLE);
+
+       ufshcd_writel(hba, intr_status, REG_INTERRUPT_STATUS);
+
        /* Directly handle interrupts since MCQ ESI handlers does the hard job */
-       return ufshcd_sl_intr(hba, ufshcd_readl(hba, REG_INTERRUPT_STATUS) &
-                                  ufshcd_readl(hba, REG_INTERRUPT_ENABLE));
+       return ufshcd_sl_intr(hba, enabled_intr_status);
 }
 
 static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag)