From patchwork Mon Mar 7 16:21:35 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Boris BREZILLON X-Patchwork-Id: 8521151 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 365DCC0553 for ; Mon, 7 Mar 2016 16:43:27 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 45A862027D for ; Mon, 7 Mar 2016 16:43:26 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 65EA9201C8 for ; Mon, 7 Mar 2016 16:43:25 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1acyEs-0006xj-2X; Mon, 07 Mar 2016 16:42:34 +0000 Received: from down.free-electrons.com ([37.187.137.238] helo=mail.free-electrons.com) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1acxw0-00040w-QU; Mon, 07 Mar 2016 16:23:43 +0000 Received: by mail.free-electrons.com (Postfix, from userid 110) id 1038B1C4; Mon, 7 Mar 2016 17:21:41 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from localhost.localdomain (AToulouse-657-1-1129-172.w92-156.abo.wanadoo.fr [92.156.51.172]) by mail.free-electrons.com (Postfix) with ESMTPSA id 063113DE; Mon, 7 Mar 2016 17:21:39 +0100 (CET) From: Boris Brezillon To: David Woodhouse , Brian Norris , linux-mtd@lists.infradead.org Subject: [PATCH 16/16] mtd: nand: sunxi: poll for events instead of using interrupts Date: Mon, 7 Mar 2016 17:21:35 +0100 Message-Id: <1457367695-26420-7-git-send-email-boris.brezillon@free-electrons.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1457367695-26420-1-git-send-email-boris.brezillon@free-electrons.com> References: <1457367513-26069-1-git-send-email-boris.brezillon@free-electrons.com> <1457367695-26420-1-git-send-email-boris.brezillon@free-electrons.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160307_082305_962430_5AA73095 X-CRM114-Status: GOOD ( 16.02 ) X-Spam-Score: -1.9 (-) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Boris Brezillon , Chen-Yu Tsai , linux-kernel@vger.kernel.org, linux-sunxi@googlegroups.com, Maxime Ripard , linux-arm-kernel@lists.infradead.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Some NAND operations are so fast that it doesn't make any sense to use interrupt based waits (the scheduling overhead is not worth it). Rename sunxi_nfc_wait_int() into sunxi_nfc_wait_events() and add a parameter to specify whether polling should be used or not. Note that all sunxi_nfc_wait_int() are moved to the polling approach now, but this should change as soon as we have more information about the approximate time we are about to wait (can be extracted from the NAND timings, and the type of operation). Signed-off-by: Boris Brezillon --- drivers/mtd/nand/sunxi_nand.c | 45 +++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c index 002194b..0616f3b 100644 --- a/drivers/mtd/nand/sunxi_nand.c +++ b/drivers/mtd/nand/sunxi_nand.c @@ -302,23 +302,40 @@ static irqreturn_t sunxi_nfc_interrupt(int irq, void *dev_id) return IRQ_HANDLED; } -static int sunxi_nfc_wait_int(struct sunxi_nfc *nfc, u32 flags, - unsigned int timeout_ms) +static int sunxi_nfc_wait_events(struct sunxi_nfc *nfc, u32 events, + bool use_polling, unsigned int timeout_ms) { - init_completion(&nfc->complete); + int ret; - writel(flags, nfc->regs + NFC_REG_INT); + if (events & ~NFC_INT_MASK) + return -EINVAL; if (!timeout_ms) timeout_ms = NFC_DEFAULT_TIMEOUT_MS; - if (!wait_for_completion_timeout(&nfc->complete, - msecs_to_jiffies(timeout_ms))) { - dev_err(nfc->dev, "wait interrupt timedout\n"); - return -ETIMEDOUT; + if (!use_polling) { + init_completion(&nfc->complete); + + writel(events, nfc->regs + NFC_REG_INT); + + ret = wait_for_completion_timeout(&nfc->complete, + msecs_to_jiffies(timeout_ms)); + + writel(0, nfc->regs + NFC_REG_INT); + } else { + u32 status; + + ret = readl_poll_timeout(nfc->regs + NFC_REG_ST, status, + (status & events) == events, 1, + timeout_ms * 1000); } - return 0; + writel(events & NFC_INT_MASK, nfc->regs + NFC_REG_ST); + + if (ret) + dev_err(nfc->dev, "wait interrupt timedout\n"); + + return ret; } static int sunxi_nfc_wait_cmd_fifo_empty(struct sunxi_nfc *nfc) @@ -449,7 +466,7 @@ static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) tmp = NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD; writel(tmp, nfc->regs + NFC_REG_CMD); - ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0); + ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, true, 0); if (ret) break; @@ -484,7 +501,7 @@ static void sunxi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, NFC_ACCESS_DIR; writel(tmp, nfc->regs + NFC_REG_CMD); - ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0); + ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, true, 0); if (ret) break; @@ -546,7 +563,7 @@ static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat, sunxi_nand->addr[0] = 0; sunxi_nand->addr[1] = 0; sunxi_nand->addr_cycles = 0; - sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0); + sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, true, 0); } if (ctrl & NAND_CLE) { @@ -789,7 +806,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd, writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ECC_OP, nfc->regs + NFC_REG_CMD); - ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0); + ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, true, 0); sunxi_nfc_randomizer_disable(mtd); if (ret) return ret; @@ -927,7 +944,7 @@ static int sunxi_nfc_hw_ecc_write_chunk(struct mtd_info *mtd, NFC_ACCESS_DIR | NFC_ECC_OP, nfc->regs + NFC_REG_CMD); - ret = sunxi_nfc_wait_int(nfc, NFC_CMD_INT_FLAG, 0); + ret = sunxi_nfc_wait_events(nfc, NFC_CMD_INT_FLAG, true, 0); sunxi_nfc_randomizer_disable(mtd); if (ret) return ret;