[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <faa728f587df5372dd78b3d012ed6bf78e92e883.1525343531.git.asutoshd@codeaurora.org>
Date: Thu, 3 May 2018 16:37:20 +0530
From: Asutosh Das <asutoshd@...eaurora.org>
To: subhashj@...eaurora.org, cang@...eaurora.org,
vivek.gautam@...eaurora.org, rnayak@...eaurora.org,
vinholikatti@...il.com, jejb@...ux.vnet.ibm.com,
martin.petersen@...cle.com, asutoshd@...eaurora.org,
linux-mmc@...r.kernel.org
Cc: linux-scsi@...r.kernel.org,
Venkat Gopalakrishnan <venkatg@...eaurora.org>,
linux-arm-msm@...r.kernel.org,
linux-kernel@...r.kernel.org (open list)
Subject: [PATCH v2 08/10] scsi: ufs: make sure all interrupts are processed
From: Venkat Gopalakrishnan <venkatg@...eaurora.org>
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@...eaurora.org>
Signed-off-by: Asutosh Das <asutoshd@...eaurora.org>
---
drivers/scsi/ufs/ufshcd.c | 27 +++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index c35a076..09b7a3f 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -5383,19 +5383,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;
}
--
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.
Powered by blists - more mailing lists