From patchwork Thu Mar 30 06:46:12 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 96238 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp102431qgd; Wed, 29 Mar 2017 23:49:49 -0700 (PDT) X-Received: by 10.98.156.23 with SMTP id f23mr4381168pfe.3.1490856589695; Wed, 29 Mar 2017 23:49:49 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i64si1228899pfa.421.2017.03.29.23.49.49; Wed, 29 Mar 2017 23:49:49 -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=@nifty.com; 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 S933299AbdC3Gts (ORCPT + 22 others); Thu, 30 Mar 2017 02:49:48 -0400 Received: from conuserg-07.nifty.com ([210.131.2.74]:41115 "EHLO conuserg-07.nifty.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932719AbdC3Gtk (ORCPT ); Thu, 30 Mar 2017 02:49:40 -0400 Received: from pug.e01.socionext.com (p14092-ipngnfx01kyoto.kyoto.ocn.ne.jp [153.142.97.92]) (authenticated) by conuserg-07.nifty.com with ESMTP id v2U6kUco015463; Thu, 30 Mar 2017 15:47:05 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conuserg-07.nifty.com v2U6kUco015463 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nifty.com; s=dec2015msa; t=1490856426; bh=+MmBerOP8guKRZN1RZaJxxQpPu8T2jj7Icsz0Bq5Yjk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TQgFceuoZFH1gwF76zJKT3YC2UU4YrX1chIzuYffyMHMKJt1q18MeN5tEg3g/eQBv s+ATkHVQBYTLx60lYFcc34ty1Ek91KsZHvdvz9QFfygiW/pH6rdVxa+bQCUuSvyu8M cFBgsO5LuTmWcd7Wf40dszjLRoEMRCYU5adWC4bOjrDbwuAu6IXApovpLsPsroUelA taTY3RymmyxSsfkYgkmS4KO0bpoyYsUB0CMqNdoZpoXuETNDKf0Xe7S1Po8riAzLs7 rtnidXe8qH/NfXWVFpwQaVLux2SZSHg8apSzU3N/AvP+gd3w9rLNKS9rKSVCjVI86+ xtCCZWzUjmfsQ== X-Nifty-SrcIP: [153.142.97.92] From: Masahiro Yamada To: linux-mtd@lists.infradead.org Cc: Enrico Jorns , Artem Bityutskiy , Dinh Nguyen , Boris Brezillon , Marek Vasut , Graham Moore , David Woodhouse , Masami Hiramatsu , Chuanxiao Dong , Jassi Brar , Masahiro Yamada , linux-kernel@vger.kernel.org, Brian Norris , Richard Weinberger , Cyrille Pitchen Subject: [PATCH v3 26/37] mtd: nand: denali: fix bank reset function Date: Thu, 30 Mar 2017 15:46:12 +0900 Message-Id: <1490856383-31560-27-git-send-email-yamada.masahiro@socionext.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1490856383-31560-1-git-send-email-yamada.masahiro@socionext.com> References: <1490856383-31560-1-git-send-email-yamada.masahiro@socionext.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The function denali_nand_reset() is called during the driver probe, and polls the INTR__RST_COMP and INTR__TIME_OUT bits. However, INTR__RST_COMP is set anyway even if no NAND device is connected to that bank. This can be a problem for ONFi devices. The nand_scan_ident() iterates over maxchips, and calls nand_reset() for each chip. Now, this driver implements ->setup_data_interface() method, so nand_setup_data_interface() issues Set Features (0xEF) command to each chip. This can cause time-out error since denali_nand_reset() did not check the chip existence. If no chip there, the controller will wait long for R/B# response, which we know never happens. (The timeout error is correctly handled in this driver, so the driver will be successfully probed anyway, but it will take longer than needed.) The Reset (0xFF) command also toggles the R/B# pin, and it sets INTR__INT_ACT bit. The driver should check this bit to see if the chip has responded, then it can update denali->max_banks. Signed-off-by: Masahiro Yamada --- Changes in v3: None Changes in v2: - Newly added drivers/mtd/nand/denali.c | 52 +++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 29 deletions(-) -- 2.7.4 diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index 86b7c75..e4f2699 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -85,33 +85,6 @@ static void index_addr(struct denali_nand_info *denali, iowrite32(data, denali->flash_mem + 0x10); } -/* Reset the flash controller */ -static uint16_t denali_nand_reset(struct denali_nand_info *denali) -{ - int i; - - for (i = 0; i < denali->max_banks; i++) - iowrite32(INTR__RST_COMP | INTR__TIME_OUT, - denali->flash_reg + INTR_STATUS(i)); - - for (i = 0; i < denali->max_banks; i++) { - iowrite32(1 << i, denali->flash_reg + DEVICE_RESET); - while (!(ioread32(denali->flash_reg + INTR_STATUS(i)) & - (INTR__RST_COMP | INTR__TIME_OUT))) - cpu_relax(); - if (ioread32(denali->flash_reg + INTR_STATUS(i)) & - INTR__TIME_OUT) - dev_dbg(denali->dev, - "NAND Reset operation timed out on bank %d\n", i); - } - - for (i = 0; i < denali->max_banks; i++) - iowrite32(INTR__RST_COMP | INTR__TIME_OUT, - denali->flash_reg + INTR_STATUS(i)); - - return PASS; -} - /* * Use the configuration feature register to determine the maximum number of * banks that the hardware supports. @@ -999,7 +972,28 @@ static int denali_setup_data_interface(struct mtd_info *mtd, return 0; } -/* Initialization code to bring the device up to a known good state */ +static void denali_reset_banks(struct denali_nand_info *denali) +{ + int i; + + denali_clear_irq_all(denali); + + for (i = 0; i < denali->max_banks; i++) { + iowrite32(1 << i, denali->flash_reg + DEVICE_RESET); + while (!(ioread32(denali->flash_reg + INTR_STATUS(i)) & + (INTR__RST_COMP | INTR__TIME_OUT))) + cpu_relax(); + if (!(ioread32(denali->flash_reg + INTR_STATUS(i)) & + INTR__INT_ACT)) + break; + } + + dev_dbg(denali->dev, "%d chips connected\n", i); + denali->max_banks = i; + + denali_clear_irq_all(denali); +} + static void denali_hw_init(struct denali_nand_info *denali) { /* @@ -1019,7 +1013,7 @@ static void denali_hw_init(struct denali_nand_info *denali) denali->bbtskipbytes = ioread32(denali->flash_reg + SPARE_AREA_SKIP_BYTES); detect_max_banks(denali); - denali_nand_reset(denali); + denali_reset_banks(denali); iowrite32(0x0F, denali->flash_reg + RB_PIN_ENABLED); iowrite32(CHIP_EN_DONT_CARE__FLAG, denali->flash_reg + CHIP_ENABLE_DONT_CARE);