scsi: ufs: make sure all interrupts are processed
As multiple requests are submitted to the ufs host controller in parallel there could be instances where the command completion interrupt arrives later for a request that is already processed earlier as the corresponding doorbell was cleared when handling the previous interrupt. Read the interrupt status in a loop after processing the received interrupt to catch such interrupts and handle it. Signed-off-by: Venkat Gopalakrishnan <venkatg@codeaurora.org> Signed-off-by: Asutosh Das <asutoshd@codeaurora.org> Reviewed-by: Subhash Jadavani <subhashj@codeaurora.org> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
69a6fff068
commit
7f6ba4f12e
@ -5489,19 +5489,30 @@ static irqreturn_t ufshcd_intr(int irq, void *__hba)
|
||||
u32 intr_status, enabled_intr_status;
|
||||
irqreturn_t retval = IRQ_NONE;
|
||||
struct ufs_hba *hba = __hba;
|
||||
int retries = hba->nutrs;
|
||||
|
||||
spin_lock(hba->host->host_lock);
|
||||
intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS);
|
||||
enabled_intr_status =
|
||||
intr_status & ufshcd_readl(hba, REG_INTERRUPT_ENABLE);
|
||||
|
||||
if (intr_status)
|
||||
ufshcd_writel(hba, intr_status, REG_INTERRUPT_STATUS);
|
||||
/*
|
||||
* There could be max of hba->nutrs reqs in flight and in worst case
|
||||
* if the reqs get finished 1 by 1 after the interrupt status is
|
||||
* read, make sure we handle them by checking the interrupt status
|
||||
* again in a loop until we process all of the reqs before returning.
|
||||
*/
|
||||
do {
|
||||
enabled_intr_status =
|
||||
intr_status & ufshcd_readl(hba, REG_INTERRUPT_ENABLE);
|
||||
if (intr_status)
|
||||
ufshcd_writel(hba, intr_status, REG_INTERRUPT_STATUS);
|
||||
if (enabled_intr_status) {
|
||||
ufshcd_sl_intr(hba, enabled_intr_status);
|
||||
retval = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS);
|
||||
} while (intr_status && --retries);
|
||||
|
||||
if (enabled_intr_status) {
|
||||
ufshcd_sl_intr(hba, enabled_intr_status);
|
||||
retval = IRQ_HANDLED;
|
||||
}
|
||||
spin_unlock(hba->host->host_lock);
|
||||
return retval;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user