From patchwork Thu May 3 10:35:29 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Asutosh Das (asd)" X-Patchwork-Id: 10377729 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 0C97C60327 for ; Thu, 3 May 2018 10:42:06 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1269F28EE3 for ; Thu, 3 May 2018 10:42:06 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 0745F28F29; Thu, 3 May 2018 10:42:06 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.9 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9D61D28EE3 for ; Thu, 3 May 2018 10:42:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751824AbeECKmD (ORCPT ); Thu, 3 May 2018 06:42:03 -0400 Received: from alexa-out-tai-01.qualcomm.com ([103.229.16.226]:41330 "EHLO alexa-out-tai-01.qualcomm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751759AbeECKmA (ORCPT ); Thu, 3 May 2018 06:42:00 -0400 X-Greylist: delayed 378 seconds by postgrey-1.27 at vger.kernel.org; Thu, 03 May 2018 06:41:55 EDT X-IronPort-AV: E=Sophos;i="5.49,358,1520870400"; d="scan'208";a="443495" Received: from ironmsg02-tai.qualcomm.com ([10.249.140.7]) by alexa-out-tai-01.qualcomm.com with ESMTP; 03 May 2018 18:35:37 +0800 X-IronPort-AV: E=McAfee;i="5900,7806,8881"; a="7388592" Received: from asutoshd-linux.qualcomm.com ([10.206.24.163]) by ironmsg02-tai.qualcomm.com with ESMTP; 03 May 2018 18:35:34 +0800 Received: by asutoshd-linux.qualcomm.com (Postfix, from userid 92687) id 054232E8E; Thu, 3 May 2018 16:05:31 +0530 (IST) From: Asutosh Das To: asutoshd@qti.qualcomm.com, linux-mmc@vger.kernel.org Subject: [PATCH v2 08/10] scsi: ufs: make sure all interrupts are processed Date: Thu, 3 May 2018 16:05:29 +0530 Message-Id: X-Mailer: git-send-email 1.9.1 In-Reply-To: References: In-Reply-To: References: Sender: linux-mmc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-mmc@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Venkat Gopalakrishnan 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 Signed-off-by: Asutosh Das Reviewed-by: Subhash Jadavani Reviewed-by: Subhash Jadavani --- 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; }