Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp3314730imm; Mon, 6 Aug 2018 02:30:41 -0700 (PDT) X-Google-Smtp-Source: AAOMgpevpUY0zSHXuzE8CYYClTCW8Ra9x0qHGqK1GoV8HEPBVO+fc9jkMCqPHH2crsV4YjZVromg X-Received: by 2002:a63:4a07:: with SMTP id x7-v6mr13921333pga.34.1533547841097; Mon, 06 Aug 2018 02:30:41 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1533547841; cv=none; d=google.com; s=arc-20160816; b=V7U3Dr8L3yG5dPkhz6Dqe1Naz1fzatJC97hJiX1IsLjoVu+CpzU6y/RSrU/TzDFkHm QYrQq2Guf1Vsmyr49z3232pauw6OgAOiVmhVP+8Yke+ZyvJn/cicYivSqsn2SD5BZGO7 HroQ3WyxeBb7sXS0nuoJmeO7I+6qkw14Wd0ilT90WcGkITmhLgXaEYLAsPA+EJ7xq42x 8Z8zlt/cG4aURfolGuPVdQyGMkO4Zt4bOhSg9ob+/iX2DhYMI3yXjix8TZ9yIqdFPWuZ kKIXqjziVQinPFPLAKtLGZeLi5vx38v4S8ovfuuZmnrSljwKWx467V9UGIMkfmh1NRJZ C3yA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=r+cA6XclAPFZ8iiIDJY3JYH8fHWs8LkgQwhDxMbZoAM=; b=wFQWO8E3Pxxn7hObfIVEjkQQEqCgDoQ15KyxetVw1x48tkCVNX6uybpLH0omkIrC7J 9Ahc2gRZ+QackMSY7lyQx4n6oED3zrfTUxoPDJfQe2gE4n8w94Tgglv00wyoqyFuhGzq /4xAQqzGnA54PT0Ut4AG02MxCoxx6eosRVLGuZicM8jJlh7zW51M4/6D/ihybIDIZZY7 KQfSxQm1QG/OqGs7r9PeDwuErtS3G/OTIfXh3aoFbrmh5Ug4oBNNxei4DlGGkChtBOTl goZGAS7kTTcRQKBP74zmAlVxJUD7oqIvvw5eevkl2544xJP3sUZ//IDUcu/mhbcmUz+o mRhQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@agner.ch header.s=dkim header.b=WRk333VL; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l17-v6si10867199pgn.182.2018.08.06.02.30.26; Mon, 06 Aug 2018 02:30:41 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@agner.ch header.s=dkim header.b=WRk333VL; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729175AbeHFLhb (ORCPT + 99 others); Mon, 6 Aug 2018 07:37:31 -0400 Received: from mail.kmu-office.ch ([178.209.48.109]:53140 "EHLO mail.kmu-office.ch" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727561AbeHFLha (ORCPT ); Mon, 6 Aug 2018 07:37:30 -0400 Received: from trochilidae.toradex.int (unknown [46.140.72.82]) by mail.kmu-office.ch (Postfix) with ESMTPSA id 4A1BD5C16AA; Mon, 6 Aug 2018 11:29:16 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=agner.ch; s=dkim; t=1533547756; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=r+cA6XclAPFZ8iiIDJY3JYH8fHWs8LkgQwhDxMbZoAM=; b=WRk333VLEv2lF4XOmITumq1q8lni105uS8Xny2SVoiOuCoGnucuI+69Is76aN7ca8A5VPJ PmF102FZW++79uoENJPQwz8ij9YuXzi/P9o4lkEekcQpzanKvhPvlo3gpVPHBfTadDMLbZ oV/2yIqy2DXJhqKokZdCrdAv77ffiE0= From: Stefan Agner To: boris.brezillon@bootlin.com, miquel.raynal@bootlin.com Cc: computersforpeace@gmail.com, dwmw2@infradead.org, marek.vasut@gmail.com, richard@nod.at, linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org, Stefan Agner Subject: [PATCH 3/3] mtd: rawnand: vf610_nfc: handle only idle interrupts Date: Mon, 6 Aug 2018 11:29:09 +0200 Message-Id: <20180806092909.28980-3-stefan@agner.ch> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180806092909.28980-1-stefan@agner.ch> References: <20180806092909.28980-1-stefan@agner.ch> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org There are two similar sounding interrupts: IDLE and DONE. The DONE interrupt only reflects the NAND command state, but not DMA or HW ECC correction. The IDLE interrupt reflects that all components are idle. The driver can assume that the NAND command finished and that data have been transferred and corrected. This driver makes use of the IDLE interrupt only. But before this patch the driver still handled all interrupts and cleared the DONE interrupt although not used. This works just fine in practice, but is not the way it should be done. This patch makes sure that only the IDLE interrupt is handled and cleared. To do so we have to clear the status bit in the interrupt routine. With that it is also save to keep the interrupt always enabled and just clear the IRQ in the interrupt handler. This new interrupt handling has been tested for several thousand boots and did not show any adverse effects. Signed-off-by: Stefan Agner Tested-by: Stefan Agner --- drivers/mtd/nand/raw/vf610_nfc.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/mtd/nand/raw/vf610_nfc.c b/drivers/mtd/nand/raw/vf610_nfc.c index 52e7811c0bde..39307f4b1c94 100644 --- a/drivers/mtd/nand/raw/vf610_nfc.c +++ b/drivers/mtd/nand/raw/vf610_nfc.c @@ -290,15 +290,6 @@ static inline void vf610_nfc_wr_to_sram(void __iomem *dst, const void *src, } } -/* Clear flags for upcoming command */ -static inline void vf610_nfc_clear_status(struct vf610_nfc *nfc) -{ - u32 tmp = vf610_nfc_read(nfc, NFC_IRQ_STATUS); - - tmp |= DONE_CLEAR_BIT | IDLE_CLEAR_BIT; - vf610_nfc_write(nfc, NFC_IRQ_STATUS, tmp); -} - static void vf610_nfc_done(struct vf610_nfc *nfc) { unsigned long timeout = msecs_to_jiffies(100); @@ -310,24 +301,29 @@ static void vf610_nfc_done(struct vf610_nfc *nfc) * vf610_nfc_set implicates such a barrier by using writel * to write to the register. */ - vf610_nfc_set(nfc, NFC_IRQ_STATUS, IDLE_EN_BIT); vf610_nfc_set(nfc, NFC_FLASH_CMD2, START_BIT); if (!wait_for_completion_timeout(&nfc->cmd_done, timeout)) dev_warn(nfc->dev, "Timeout while waiting for BUSY.\n"); - - vf610_nfc_clear_status(nfc); } static irqreturn_t vf610_nfc_irq(int irq, void *data) { struct mtd_info *mtd = data; struct vf610_nfc *nfc = mtd_to_nfc(mtd); + u32 status; - vf610_nfc_clear(nfc, NFC_IRQ_STATUS, IDLE_EN_BIT); - complete(&nfc->cmd_done); + status = vf610_nfc_read(nfc, NFC_IRQ_STATUS); - return IRQ_HANDLED; + if (status & IDLE_IRQ_BIT) { + status |= IDLE_CLEAR_BIT; + vf610_nfc_write(nfc, NFC_IRQ_STATUS, status); + complete(&nfc->cmd_done); + + return IRQ_HANDLED; + } + + return IRQ_NONE; } static inline void vf610_nfc_ecc_mode(struct vf610_nfc *nfc, int ecc_mode) @@ -826,7 +822,9 @@ static int vf610_nfc_probe(struct platform_device *pdev) vf610_nfc_clear(nfc, NFC_IRQ_STATUS, WERR_EN_BIT); vf610_nfc_clear(nfc, NFC_IRQ_STATUS, DONE_EN_BIT); - vf610_nfc_clear(nfc, NFC_IRQ_STATUS, IDLE_EN_BIT); + + vf610_nfc_set(nfc, NFC_IRQ_STATUS, IDLE_CLEAR_BIT); + vf610_nfc_set(nfc, NFC_IRQ_STATUS, IDLE_EN_BIT); err = devm_request_irq(nfc->dev, irq, vf610_nfc_irq, 0, DRV_NAME, mtd); if (err) { -- 2.18.0