mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-15 02:57:49 +00:00
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
1 changed files with 19 additions and 8 deletions
|
@ -5489,19 +5489,30 @@ static irqreturn_t ufshcd_intr(int irq, void *__hba)
|
||||||
u32 intr_status, enabled_intr_status;
|
u32 intr_status, enabled_intr_status;
|
||||||
irqreturn_t retval = IRQ_NONE;
|
irqreturn_t retval = IRQ_NONE;
|
||||||
struct ufs_hba *hba = __hba;
|
struct ufs_hba *hba = __hba;
|
||||||
|
int retries = hba->nutrs;
|
||||||
|
|
||||||
spin_lock(hba->host->host_lock);
|
spin_lock(hba->host->host_lock);
|
||||||
intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS);
|
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);
|
spin_unlock(hba->host->host_lock);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue