From patchwork Tue Feb 10 18:59:55 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Uwe_Kleine-K=C3=B6nig?= X-Patchwork-Id: 5808601 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id BE63B9F36A for ; Tue, 10 Feb 2015 19:05:19 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D8C2820155 for ; Tue, 10 Feb 2015 19:05:15 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F167E20154 for ; Tue, 10 Feb 2015 19:05:14 +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 1YLG4x-0001MF-Cy; Tue, 10 Feb 2015 19:02:35 +0000 Received: from casper.infradead.org ([2001:770:15f::2]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1YLG3T-0000Nb-GH for linux-arm-kernel@bombadil.infradead.org; Tue, 10 Feb 2015 19:01:03 +0000 Received: from [2001:6f8:1178:4:290:27ff:fe1d:cc33] (helo=metis.ext.pengutronix.de) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1YLG3N-0005Fh-7l for linux-arm-kernel@lists.infradead.org; Tue, 10 Feb 2015 19:01:01 +0000 Received: from dude.hi.pengutronix.de ([2001:67c:670:100:1d::7]) by metis.ext.pengutronix.de with esmtp (Exim 4.72) (envelope-from ) id 1YLG2Y-0003Hz-7p; Tue, 10 Feb 2015 20:00:06 +0100 Received: from ukl by dude.hi.pengutronix.de with local (Exim 4.84) (envelope-from ) id 1YLG2Y-0006Jk-6i; Tue, 10 Feb 2015 20:00:06 +0100 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= To: linux-mtd@lists.infradead.org Subject: [PATCH 1/6] mtd: mxc-nand: Add a timeout when waiting for interrupt Date: Tue, 10 Feb 2015 19:59:55 +0100 Message-Id: <1423594800-24214-2-git-send-email-u.kleine-koenig@pengutronix.de> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1423594800-24214-1-git-send-email-u.kleine-koenig@pengutronix.de> References: <1423594800-24214-1-git-send-email-u.kleine-koenig@pengutronix.de> MIME-Version: 1.0 X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::7 X-SA-Exim-Mail-From: ukl@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-arm-kernel@lists.infradead.org X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150210_190057_418066_A8BBEC47 X-CRM114-Status: GOOD ( 21.72 ) X-Spam-Score: -1.1 (-) Cc: linux-arm-kernel@lists.infradead.org, kernel@pengutronix.de X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP While extending the mxc-nand driver it happend to me a few times that the device was stuck and this made the machine hang during boot. So implement a timeout and print a stack trace the first time this happens to make it debuggable. The return type of the waiting function is also changed to int to be able to handle the timeout in the caller. Signed-off-by: Uwe Kleine-König --- drivers/mtd/nand/mxc_nand.c | 47 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index a8f550fec35e..27ba07c07966 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -386,26 +386,51 @@ static irqreturn_t mxc_nfc_irq(int irq, void *dev_id) /* This function polls the NANDFC to wait for the basic operation to * complete by checking the INT bit of config2 register. */ -static void wait_op_done(struct mxc_nand_host *host, int useirq) +static int wait_op_done(struct mxc_nand_host *host, int useirq) { - int max_retries = 8000; + int ret = 0; + + /* + * If operation is already complete, don't bother to setup an irq or a + * loop. + */ + if (host->devtype_data->check_int(host)) + return 0; if (useirq) { - if (!host->devtype_data->check_int(host)) { - reinit_completion(&host->op_completion); - irq_control(host, 1); - wait_for_completion(&host->op_completion); + unsigned long timeout; + + reinit_completion(&host->op_completion); + + irq_control(host, 1); + + timeout = wait_for_completion_timeout(&host->op_completion, HZ); + if (!timeout && !host->devtype_data->check_int(host)) { + dev_dbg(host->dev, "timeout waiting for irq\n"); + ret = -ETIMEDOUT; } } else { - while (max_retries-- > 0) { - if (host->devtype_data->check_int(host)) - break; + int max_retries = 8000; + int done; + do { udelay(1); + + done = host->devtype_data->check_int(host); + if (done) + break; + + } while (--max_retries); + + if (!done) { + dev_dbg(host->dev, "timeout polling for completion\n"); + ret = -ETIMEDOUT; } - if (max_retries < 0) - pr_debug("%s: INT not set\n", __func__); } + + WARN_ONCE(ret < 0, "timeout! useirq=%d\n", useirq); + + return ret; } static void send_cmd_v3(struct mxc_nand_host *host, uint16_t cmd, int useirq)