From patchwork Tue Jun 13 05:03:53 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 103685 Delivered-To: patch@linaro.org Received: by 10.140.91.77 with SMTP id y71csp235469qgd; Mon, 12 Jun 2017 22:05:25 -0700 (PDT) X-Received: by 10.98.21.9 with SMTP id 9mr19540325pfv.46.1497330325321; Mon, 12 Jun 2017 22:05:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1497330325; cv=none; d=google.com; s=arc-20160816; b=o6DL+NB4TLeOBmKOrScXYvvU7leQ7YX4J7llwsZMPvwRrAmJ47Kx77Mw3xsP/511UY 7cDwYjx/QZYPpXlb2Csjx+LA1aL/L4bERr/ow+ZGWOExbpxes0K7ECRZCW4lQEQxPfqh JR8H3HQXQEq6Os+AZJMokVvipa0XTci7tED3OsR3pb6o51MHxCFskdnfwu5CEKGqg2XH o/H32voDduLnZGHHYtrt/ohcamz40T92s2A5MO96d6gmXNeXA0FYaxJb2VXGkF9mk8c8 E5FUcAtbQ0DAcMJETvXuuAG2TIeurHEpc9u36XJj5/gYC6q8X2u6zt1k1Bq0+MAgQ3vj QsKg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:sender:content-transfer-encoding:mime-version:cc :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:references:in-reply-to:message-id:date:subject :to:from:dkim-signature:dkim-filter:dkim-signature :arc-authentication-results; bh=6pFssw3MIvdZBhmGn1EJ2Vc9kha/WMzmxqZeI06NRag=; b=DbKZqy63CYbRDa79JkRVgz+UD2sfB0s2p2ZmxJyC0oFYSJJTbgy3eFg/I9f2mrSzaH bjNYcEyVV8gTyHUi5Pg1mZ5JttbugOGfUC4OALVzibA/1UYS0P5v2tPh+FVOpzYW2Oid 7m61P5H0WPW0TLRa3MFXxcxV2MbsDCOrJWOijObYO5voHVD9Je5xeZR5OgXsrRjJDfoY cEjdMD1RHMEJ4RM73l8Hun1Wv4vcXNY6L+tk+8WOWUeOfXuxUwu5+BYAoUoC9k1n5tPY PZCrkcVmtWGsdmJ2gFQgJNBDLF+WuKp/qrloNRdxywk8gCfFygg1DUEE5S6q6eK487Ll wlTg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.infradead.org; dkim=neutral (body hash did not verify) header.i=@nifty.com; spf=pass (google.com: best guess record for domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 65.50.211.133 as permitted sender) smtp.mailfrom=linux-mtd-bounces+patch=linaro.org@lists.infradead.org Return-Path: Received: from bombadil.infradead.org (bombadil.infradead.org. [65.50.211.133]) by mx.google.com with ESMTPS id u63si5990578pfa.301.2017.06.12.22.05.25 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 12 Jun 2017 22:05:25 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 65.50.211.133 as permitted sender) client-ip=65.50.211.133; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.infradead.org; dkim=neutral (body hash did not verify) header.i=@nifty.com; spf=pass (google.com: best guess record for domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 65.50.211.133 as permitted sender) smtp.mailfrom=linux-mtd-bounces+patch=linaro.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=6pFssw3MIvdZBhmGn1EJ2Vc9kha/WMzmxqZeI06NRag=; b=atJu2as4lvsprqfU1dgjE3zpGH VDN7APg0U/+rfyAV/ZAavB4SkuWOTFtLXV0F/lvx0iO24HG3AguVTQn5d+4OIATkrll/LO54vydrw tZezhLLa8M1e4pAVa0QgkJzm61qfy7X0AqCCbSThTf7VkIlV9a0bOTP4lC5veQlLMRLqRqO2lSAQT Jh2D7PUWpYyO7Qj18LIc4oNxqldygVM+jctm7ns9ZRsbFJLqRmYnhqtSNMyLTyblzDNWGApEaQnvt ZCKcvGu9diELEWjB6loW1Tcl7oOClRr/ZE+gi7YzVVCeluaIZ5dRBKW1cckg4fgLZLoDcQqAN+jCc ZQJrT3Cw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dKe0x-0007Bk-KA; Tue, 13 Jun 2017 05:05:15 +0000 Received: from conuserg-09.nifty.com ([210.131.2.76]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dKe0t-0005xB-R3 for linux-mtd@lists.infradead.org; Tue, 13 Jun 2017 05:05:14 +0000 Received: from pug.e01.socionext.com (p14092-ipngnfx01kyoto.kyoto.ocn.ne.jp [153.142.97.92]) (authenticated) by conuserg-09.nifty.com with ESMTP id v5D54ENf023096; Tue, 13 Jun 2017 14:04:15 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conuserg-09.nifty.com v5D54ENf023096 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nifty.com; s=dec2015msa; t=1497330256; bh=Mm7mGwczE4Dy17pTJ9UlDnTCad8AS083AYKzBRs+qUw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OTRBtEWZUwenD8JEMyPAAuzX9lYV/XMBBzJAQyHhG7MAhJKcideE2qXq/JtWYDAeY aZuaoeMD2dDMJwW2hCHCdzpll2Zp/c788NezzoBB5l6wZiCY5PDV/xfBhuDRRyYwOA ncLqqYbZq1mR5lJFYZ5wwvQ61Rq5GKLUPPiCl9Kj6XQmPw3VjhgYOeY8uZoPC6mlJJ AOKTYMw8KVOMOkOVWV3KqHzNfC6d069vjpBpyxRxUga2/N2KTDJQP6h8Jo3jwRO2LE prq/Nr475+rHavy+5xsR3eSSZQ0JxF/x/6GtOblJZIK15VLp+OslGyxgtDXD3UVxaO gm+jy2J5kxYUQ== X-Nifty-SrcIP: [153.142.97.92] From: Masahiro Yamada To: linux-mtd@lists.infradead.org Subject: [PATCH v6 01/18] mtd: nand: denali: set NAND_ECC_CUSTOM_PAGE_ACCESS Date: Tue, 13 Jun 2017 14:03:53 +0900 Message-Id: <1497330250-17348-2-git-send-email-yamada.masahiro@socionext.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1497330250-17348-1-git-send-email-yamada.masahiro@socionext.com> References: <1497330250-17348-1-git-send-email-yamada.masahiro@socionext.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170612_220512_187412_A60E3958 X-CRM114-Status: GOOD ( 15.86 ) X-Spam-Score: -1.2 (-) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-1.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.7 SPF_SOFTFAIL SPF: sender does not match SPF record (softfail) -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Boris Brezillon , Cyrille Pitchen , Richard Weinberger , Marek Vasut , Masahiro Yamada , Artem Bityutskiy , Dinh Nguyen , linux-kernel@vger.kernel.org, Enrico Jorns , Masami Hiramatsu , Chuanxiao Dong , Jassi Brar , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+patch=linaro.org@lists.infradead.org The denali_cmdfunc() actually does nothing valuable for NAND_CMD_{PAGEPROG,READ0,SEQIN}. For NAND_CMD_{READ0,SEQIN}, it copies "page" to "denali->page", then denali_read_page(_raw) compares them just for the sanity check. (Inconsistently, this check is missing from denali_write_page(_raw).) The Denali controller is equipped with high level read/write interface, so let's skip unneeded call of cmdfunc(). If NAND_ECC_CUSTOM_PAGE_ACCESS is set, nand_write_page() will not call ->waitfunc hook. So, ->write_page(_raw) hooks should directly return -EIO on failure. The error handling of page writes will be much simpler. Signed-off-by: Masahiro Yamada --- Changes in v6: - Squash two commits to adjust to commit 41145649f4ac (mtd: nand: Wait for PAGEPROG to finish in drivers setting NAND_ECC_CUSTOM_PAGE_ACCESS) Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: - Newly added drivers/mtd/nand/denali.c | 41 ++++++++++++----------------------------- drivers/mtd/nand/denali.h | 1 - 2 files changed, 12 insertions(+), 30 deletions(-) -- 2.7.4 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index 2b4618bb8d72..7133a33b4ad3 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -998,13 +998,16 @@ static void denali_setup_dma(struct denali_nand_info *denali, int op) * configuration details. */ static int write_page(struct mtd_info *mtd, struct nand_chip *chip, - const uint8_t *buf, bool raw_xfer) + const uint8_t *buf, int page, bool raw_xfer) { struct denali_nand_info *denali = mtd_to_denali(mtd); dma_addr_t addr = denali->buf.dma_buf; size_t size = mtd->writesize + mtd->oobsize; uint32_t irq_status; uint32_t irq_mask = INTR__DMA_CMD_COMP | INTR__PROGRAM_FAIL; + int ret = 0; + + denali->page = page; /* * if it is a raw xfer, we want to disable ecc and send the spare area. @@ -1036,13 +1039,13 @@ static int write_page(struct mtd_info *mtd, struct nand_chip *chip, if (irq_status == 0) { dev_err(denali->dev, "timeout on write_page (type = %d)\n", raw_xfer); - denali->status = NAND_STATUS_FAIL; + ret = -EIO; } denali_enable_dma(denali, false); dma_sync_single_for_cpu(denali->dev, addr, size, DMA_TO_DEVICE); - return 0; + return ret; } /* NAND core entry points */ @@ -1059,7 +1062,7 @@ static int denali_write_page(struct mtd_info *mtd, struct nand_chip *chip, * for regular page writes, we let HW handle all the ECC * data written to the device. */ - return write_page(mtd, chip, buf, false); + return write_page(mtd, chip, buf, page, false); } /* @@ -1075,7 +1078,7 @@ static int denali_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, * for raw page writes, we want to disable ECC and simply write * whatever data is in the buffer. */ - return write_page(mtd, chip, buf, true); + return write_page(mtd, chip, buf, page, true); } static int denali_write_oob(struct mtd_info *mtd, struct nand_chip *chip, @@ -1105,12 +1108,7 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, unsigned long uncor_ecc_flags = 0; int stat = 0; - if (page != denali->page) { - dev_err(denali->dev, - "IN %s: page %d is not equal to denali->page %d", - __func__, page, denali->page); - BUG(); - } + denali->page = page; setup_ecc_for_xfer(denali, true, false); @@ -1154,12 +1152,7 @@ static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, size_t size = mtd->writesize + mtd->oobsize; uint32_t irq_mask = INTR__DMA_CMD_COMP; - if (page != denali->page) { - dev_err(denali->dev, - "IN %s: page %d is not equal to denali->page %d", - __func__, page, denali->page); - BUG(); - } + denali->page = page; setup_ecc_for_xfer(denali, false, true); denali_enable_dma(denali, true); @@ -1204,12 +1197,7 @@ static void denali_select_chip(struct mtd_info *mtd, int chip) static int denali_waitfunc(struct mtd_info *mtd, struct nand_chip *chip) { - struct denali_nand_info *denali = mtd_to_denali(mtd); - int status = denali->status; - - denali->status = 0; - - return status; + return 0; } static int denali_erase(struct mtd_info *mtd, int page) @@ -1238,8 +1226,6 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col, int i; switch (cmd) { - case NAND_CMD_PAGEPROG: - break; case NAND_CMD_STATUS: read_status(denali); break; @@ -1259,10 +1245,6 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col, write_byte_to_buf(denali, id); } break; - case NAND_CMD_READ0: - case NAND_CMD_SEQIN: - denali->page = page; - break; case NAND_CMD_RESET: reset_bank(denali); break; @@ -1605,6 +1587,7 @@ int denali_init(struct denali_nand_info *denali) mtd_set_ooblayout(mtd, &denali_ooblayout_ops); + chip->ecc.options |= NAND_ECC_CUSTOM_PAGE_ACCESS; chip->ecc.read_page = denali_read_page; chip->ecc.read_page_raw = denali_read_page_raw; chip->ecc.write_page = denali_write_page; diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h index a06ed741b550..352d8328b94a 100644 --- a/drivers/mtd/nand/denali.h +++ b/drivers/mtd/nand/denali.h @@ -323,7 +323,6 @@ struct nand_buf { struct denali_nand_info { struct nand_chip nand; int flash_bank; /* currently selected chip */ - int status; int platform; struct nand_buf buf; struct device *dev; From patchwork Tue Jun 13 05:03:56 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 103692 Delivered-To: patch@linaro.org Received: by 10.140.91.77 with SMTP id y71csp235943qgd; Mon, 12 Jun 2017 22:06:57 -0700 (PDT) X-Received: by 10.99.123.27 with SMTP id w27mr50393734pgc.6.1497330417792; Mon, 12 Jun 2017 22:06:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1497330417; cv=none; d=google.com; s=arc-20160816; b=f0AwBtV2IDkJ/wViZ+NsFl83+B2bBXTrsG7JwCdHesq6DW/mw+uS0t/gXHoJ8NKfJd cEe4HYQpm8TRIyuNEZ6iaDgnkU86rr7KZq4I+ULJA695GJch/qyZ0zaboKkyWvWoE0mu 94o6Wk5aCCU4OgAfA8IdmbgAsAj6SiO1A1oxyy4qQNXTXUvwxc65A0B0rQD6Hp2jzE94 Lv8OuUHHRGB+Mz6JY0BDJnKOIRqBcufrFzt+UL338II1cYSKmK/Ph34DMsJ3v0qv/Ul6 qWQyUlCN6BrpX4Pui5ab7EmNnIzNMp8D60Y1s3GfwLi05/hcGroUruNVU/Zb6tXVkO1S BpHg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:sender:content-transfer-encoding:mime-version:cc :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:references:in-reply-to:message-id:date:subject :to:from:dkim-signature:dkim-filter:dkim-signature :arc-authentication-results; bh=fLj0QhUcBFjrdMvZkH7PRik86FrXjZ+NGBarsbGAFPE=; b=WiKMUNVbD7d8nyMyF6JTlj9ZfUSKsiUdvwWIojMSvy4uOTHtrpMhhDZdmIX8XKuyIc 8PdVSlRpMPVvl+E/sBQQTzK4j7Oxu7TRN4Dt/EGbtGK8HRA4LcJQtn4YWkUjXH+WVkIC XTk2CfFJafRymtEr1cpDomjuOAXcL1OdYV9CVtmDg2KcvoghM+RUsXHn+S2KwbzWK+CF x7p8T5OzWYSSDmSdTkTrwoexGdXSq3yuFf2bEucFtbnNya/P2bXUgACjJRlvZwgOLJgj jOFuUqtI+NiSiyG+K7vEYSoN078XrN2XyCmfCH7RsT3T5d2jLzEwxaNAAtYD6TITr6h1 Qyyg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.infradead.org; dkim=neutral (body hash did not verify) header.i=@nifty.com; spf=pass (google.com: best guess record for domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 65.50.211.133 as permitted sender) smtp.mailfrom=linux-mtd-bounces+patch=linaro.org@lists.infradead.org Return-Path: Received: from bombadil.infradead.org (bombadil.infradead.org. [65.50.211.133]) by mx.google.com with ESMTPS id z9si591213pgz.134.2017.06.12.22.06.57 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 12 Jun 2017 22:06:57 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 65.50.211.133 as permitted sender) client-ip=65.50.211.133; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.infradead.org; dkim=neutral (body hash did not verify) header.i=@nifty.com; spf=pass (google.com: best guess record for domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 65.50.211.133 as permitted sender) smtp.mailfrom=linux-mtd-bounces+patch=linaro.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=fLj0QhUcBFjrdMvZkH7PRik86FrXjZ+NGBarsbGAFPE=; b=oEKQSqGrLmLWN8/QtAbu/1UAuk gT3+oJ2a1dAfwD4u+xKHvnhFgH+ghU2I/1uP1aYVWD3cGSU5BG8ql5KEEdIJfbyh4E1peEdDkLiS2 I9zqvnL6C8leRMDxXmnQJn73k6OIeipuvOOiSyqH+tClkkipKXdjcBS9+tYQsrqmkEwMshKCyzTTn DshxFNIjLcbK/l3MEdEYBnfINNYdu9rckb4OAcJisKN4UCL8PYzgrXXkY8Rm4MIw6S/JF/YlexTkV rMu3LOR+OpGwCgQdhafCCt3OJaoFsuZsXN7FQZd/t8/FsQncEgTT3zy9qjL/eYFAoek7ItSV3N9q5 XkyywSWg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dKe2S-0008RD-3Y; Tue, 13 Jun 2017 05:06:48 +0000 Received: from conuserg-09.nifty.com ([210.131.2.76]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dKe0t-0005xA-R3 for linux-mtd@lists.infradead.org; Tue, 13 Jun 2017 05:05:16 +0000 Received: from pug.e01.socionext.com (p14092-ipngnfx01kyoto.kyoto.ocn.ne.jp [153.142.97.92]) (authenticated) by conuserg-09.nifty.com with ESMTP id v5D54ENi023096; Tue, 13 Jun 2017 14:04:19 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conuserg-09.nifty.com v5D54ENi023096 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nifty.com; s=dec2015msa; t=1497330260; bh=7ofDJXVOZJKimhQLQRnfcylx3XrvcF4DPpIVS4MivM8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Iznh8gkv3PlyAusRLqGGVqUGZbNs0Qj9VoBB3GjBTy/i7l0awmDkPmBqfH7lWnoQ6 dKj2bGhfRU6ZAsrA1Mc520/YOuaUDU3wo4v2bxJ7FVrobcCKgnPISWTeJkMc32B0Oq OjTyfZc9IyBs7jh8G0oilkEbXsbDFFMBRcJto7qRr6pGyDqTbfCiUNWjxrXhMsKYhP Gk4EEGK6fNCSuPmziLt83zpesFeypD/qjOc2V08y7raaSlp+zO31HfHrw3yGFJLgLt Wzp9xiuWbT+8foG69Z5PcvBkGU/ap7hvZTFrkYGuZGWCM1lq8sDiFu+4jLtmB2WieG gy3YvQ6AVee/Q== X-Nifty-SrcIP: [153.142.97.92] From: Masahiro Yamada To: linux-mtd@lists.infradead.org Subject: [PATCH v6 04/18] mtd: nand: denali: rework interrupt handling Date: Tue, 13 Jun 2017 14:03:56 +0900 Message-Id: <1497330250-17348-5-git-send-email-yamada.masahiro@socionext.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1497330250-17348-1-git-send-email-yamada.masahiro@socionext.com> References: <1497330250-17348-1-git-send-email-yamada.masahiro@socionext.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170612_220512_316378_2CF9129A X-CRM114-Status: GOOD ( 24.09 ) X-Spam-Score: -1.2 (-) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-1.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.7 SPF_SOFTFAIL SPF: sender does not match SPF record (softfail) -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Boris Brezillon , Cyrille Pitchen , Richard Weinberger , Marek Vasut , Masahiro Yamada , Artem Bityutskiy , Dinh Nguyen , linux-kernel@vger.kernel.org, Enrico Jorns , Masami Hiramatsu , Chuanxiao Dong , Jassi Brar , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+patch=linaro.org@lists.infradead.org Simplify the interrupt handling and fix issues: - The register field view of INTR_EN / INTR_STATUS is different among IP versions. The global macro DENALI_IRQ_ALL is hard-coded for Intel platforms. The interrupt mask should be determined at run-time depending on the running platform. - wait_for_irq() loops do {} while() until interested flags are asserted. The logic can be simplified. - The spin_lock() guard seems too complex (and suspicious in a race condition if wait_for_completion_timeout() bails out by timeout). - denali->complete is reused again and again, but reinit_completion() is missing. Add it. Re-work the code to make it more robust and easier to handle. While we are here, also rename the jump label "failed_req_irq" to more appropriate "disable_irq". Signed-off-by: Masahiro Yamada --- Changes in v6: None Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: - Newly added drivers/mtd/nand/denali.c | 316 +++++++++++++++++----------------------------- drivers/mtd/nand/denali.h | 1 + 2 files changed, 116 insertions(+), 201 deletions(-) -- 2.7.4 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index ca2b6b8850ba..d7e7555a3d73 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -31,26 +31,13 @@ MODULE_LICENSE("GPL"); #define DENALI_NAND_NAME "denali-nand" /* - * We define a macro here that combines all interrupts this driver uses into - * a single constant value, for convenience. - */ -#define DENALI_IRQ_ALL (INTR__DMA_CMD_COMP | \ - INTR__ECC_TRANSACTION_DONE | \ - INTR__ECC_ERR | \ - INTR__PROGRAM_FAIL | \ - INTR__LOAD_COMP | \ - INTR__PROGRAM_COMP | \ - INTR__TIME_OUT | \ - INTR__ERASE_FAIL | \ - INTR__RST_COMP | \ - INTR__ERASE_COMP) - -/* * indicates whether or not the internal value for the flash bank is * valid or not */ #define CHIP_SELECT_INVALID -1 +#define DENALI_NR_BANKS 4 + /* * The bus interface clock, clk_x, is phase aligned with the core clock. The * clk_x is an integral multiple N of the core clk. The value N is configured @@ -85,14 +72,6 @@ static inline struct denali_nand_info *mtd_to_denali(struct mtd_info *mtd) */ #define BANK(x) ((x) << 24) -/* forward declarations */ -static void clear_interrupts(struct denali_nand_info *denali); -static uint32_t wait_for_irq(struct denali_nand_info *denali, - uint32_t irq_mask); -static void denali_irq_enable(struct denali_nand_info *denali, - uint32_t int_mask); -static uint32_t read_interrupt_status(struct denali_nand_info *denali); - /* * Certain operations for the denali NAND controller use an indexed mode to * read/write data. The operation is performed by writing the address value @@ -143,22 +122,6 @@ static void read_status(struct denali_nand_info *denali) write_byte_to_buf(denali, 0); } -/* resets a specific device connected to the core */ -static void reset_bank(struct denali_nand_info *denali) -{ - uint32_t irq_status; - uint32_t irq_mask = INTR__RST_COMP | INTR__TIME_OUT; - - clear_interrupts(denali); - - iowrite32(1 << denali->flash_bank, denali->flash_reg + DEVICE_RESET); - - irq_status = wait_for_irq(denali, irq_mask); - - if (irq_status & INTR__TIME_OUT) - dev_err(denali->dev, "reset bank failed.\n"); -} - /* Reset the flash controller */ static uint16_t denali_nand_reset(struct denali_nand_info *denali) { @@ -201,169 +164,123 @@ static void detect_max_banks(struct denali_nand_info *denali) denali->max_banks <<= 1; } -static void denali_set_intr_modes(struct denali_nand_info *denali, - uint16_t INT_ENABLE) +static void denali_enable_irq(struct denali_nand_info *denali) { - if (INT_ENABLE) - iowrite32(1, denali->flash_reg + GLOBAL_INT_ENABLE); - else - iowrite32(0, denali->flash_reg + GLOBAL_INT_ENABLE); -} + int i; -/* - * validation function to verify that the controlling software is making - * a valid request - */ -static inline bool is_flash_bank_valid(int flash_bank) -{ - return flash_bank >= 0 && flash_bank < 4; + for (i = 0; i < DENALI_NR_BANKS; i++) + iowrite32(U32_MAX, denali->flash_reg + INTR_EN(i)); + iowrite32(GLOBAL_INT_EN_FLAG, denali->flash_reg + GLOBAL_INT_ENABLE); } -static void denali_irq_init(struct denali_nand_info *denali) +static void denali_disable_irq(struct denali_nand_info *denali) { - uint32_t int_mask; int i; - /* Disable global interrupts */ - denali_set_intr_modes(denali, false); - - int_mask = DENALI_IRQ_ALL; - - /* Clear all status bits */ - for (i = 0; i < denali->max_banks; ++i) - iowrite32(0xFFFF, denali->flash_reg + INTR_STATUS(i)); - - denali_irq_enable(denali, int_mask); + for (i = 0; i < DENALI_NR_BANKS; i++) + iowrite32(0, denali->flash_reg + INTR_EN(i)); + iowrite32(0, denali->flash_reg + GLOBAL_INT_ENABLE); } -static void denali_irq_cleanup(int irqnum, struct denali_nand_info *denali) +static void denali_clear_irq(struct denali_nand_info *denali, + int bank, uint32_t irq_status) { - denali_set_intr_modes(denali, false); + /* write one to clear bits */ + iowrite32(irq_status, denali->flash_reg + INTR_STATUS(bank)); } -static void denali_irq_enable(struct denali_nand_info *denali, - uint32_t int_mask) +static void denali_clear_irq_all(struct denali_nand_info *denali) { int i; - for (i = 0; i < denali->max_banks; ++i) - iowrite32(int_mask, denali->flash_reg + INTR_EN(i)); + for (i = 0; i < DENALI_NR_BANKS; i++) + denali_clear_irq(denali, i, U32_MAX); } -/* - * This function only returns when an interrupt that this driver cares about - * occurs. This is to reduce the overhead of servicing interrupts - */ -static inline uint32_t denali_irq_detected(struct denali_nand_info *denali) +static irqreturn_t denali_isr(int irq, void *dev_id) { - return read_interrupt_status(denali) & DENALI_IRQ_ALL; -} + struct denali_nand_info *denali = dev_id; + irqreturn_t ret = IRQ_NONE; + uint32_t irq_status; + int i; -/* Interrupts are cleared by writing a 1 to the appropriate status bit */ -static inline void clear_interrupt(struct denali_nand_info *denali, - uint32_t irq_mask) -{ - uint32_t intr_status_reg; + spin_lock(&denali->irq_lock); - intr_status_reg = INTR_STATUS(denali->flash_bank); + for (i = 0; i < DENALI_NR_BANKS; i++) { + irq_status = ioread32(denali->flash_reg + INTR_STATUS(i)); + if (irq_status) + ret = IRQ_HANDLED; - iowrite32(irq_mask, denali->flash_reg + intr_status_reg); -} + denali_clear_irq(denali, i, irq_status); -static void clear_interrupts(struct denali_nand_info *denali) -{ - uint32_t status; + if (i != denali->flash_bank) + continue; + + denali->irq_status |= irq_status; - spin_lock_irq(&denali->irq_lock); + if (denali->irq_status & denali->irq_mask) + complete(&denali->complete); + } - status = read_interrupt_status(denali); - clear_interrupt(denali, status); + spin_unlock(&denali->irq_lock); - denali->irq_status = 0x0; - spin_unlock_irq(&denali->irq_lock); + return ret; } -static uint32_t read_interrupt_status(struct denali_nand_info *denali) +static void denali_reset_irq(struct denali_nand_info *denali) { - uint32_t intr_status_reg; - - intr_status_reg = INTR_STATUS(denali->flash_bank); + unsigned long flags; - return ioread32(denali->flash_reg + intr_status_reg); + spin_lock_irqsave(&denali->irq_lock, flags); + denali->irq_status = 0; + denali->irq_mask = 0; + spin_unlock_irqrestore(&denali->irq_lock, flags); } -/* - * This is the interrupt service routine. It handles all interrupts - * sent to this device. Note that on CE4100, this is a shared interrupt. - */ -static irqreturn_t denali_isr(int irq, void *dev_id) +static uint32_t denali_wait_for_irq(struct denali_nand_info *denali, + uint32_t irq_mask) { - struct denali_nand_info *denali = dev_id; + unsigned long time_left, flags; uint32_t irq_status; - irqreturn_t result = IRQ_NONE; - spin_lock(&denali->irq_lock); + spin_lock_irqsave(&denali->irq_lock, flags); - /* check to see if a valid NAND chip has been selected. */ - if (is_flash_bank_valid(denali->flash_bank)) { - /* - * check to see if controller generated the interrupt, - * since this is a shared interrupt - */ - irq_status = denali_irq_detected(denali); - if (irq_status != 0) { - /* handle interrupt */ - /* first acknowledge it */ - clear_interrupt(denali, irq_status); - /* - * store the status in the device context for someone - * to read - */ - denali->irq_status |= irq_status; - /* notify anyone who cares that it happened */ - complete(&denali->complete); - /* tell the OS that we've handled this */ - result = IRQ_HANDLED; - } + irq_status = denali->irq_status; + + if (irq_mask & irq_status) { + spin_unlock_irqrestore(&denali->irq_lock, flags); + return irq_status; } - spin_unlock(&denali->irq_lock); - return result; + + denali->irq_mask = irq_mask; + reinit_completion(&denali->complete); + spin_unlock_irqrestore(&denali->irq_lock, flags); + + time_left = wait_for_completion_timeout(&denali->complete, + msecs_to_jiffies(1000)); + if (!time_left) { + dev_err(denali->dev, "timeout while waiting for irq 0x%x\n", + denali->irq_mask); + return 0; + } + + return denali->irq_status; } -static uint32_t wait_for_irq(struct denali_nand_info *denali, uint32_t irq_mask) +/* resets a specific device connected to the core */ +static void reset_bank(struct denali_nand_info *denali) { - unsigned long comp_res; - uint32_t intr_status; - unsigned long timeout = msecs_to_jiffies(1000); + uint32_t irq_status; - do { - comp_res = - wait_for_completion_timeout(&denali->complete, timeout); - spin_lock_irq(&denali->irq_lock); - intr_status = denali->irq_status; - - if (intr_status & irq_mask) { - denali->irq_status &= ~irq_mask; - spin_unlock_irq(&denali->irq_lock); - /* our interrupt was detected */ - break; - } + denali_reset_irq(denali); - /* - * these are not the interrupts you are looking for - - * need to wait again - */ - spin_unlock_irq(&denali->irq_lock); - } while (comp_res != 0); + iowrite32(1 << denali->flash_bank, denali->flash_reg + DEVICE_RESET); - if (comp_res == 0) { - /* timeout */ - pr_err("timeout occurred, status = 0x%x, mask = 0x%x\n", - intr_status, irq_mask); + irq_status = denali_wait_for_irq(denali, + INTR__RST_COMP | INTR__TIME_OUT); - intr_status = 0; - } - return intr_status; + if (!(irq_status & INTR__RST_COMP)) + dev_err(denali->dev, "reset bank failed.\n"); } /* @@ -397,7 +314,7 @@ static int denali_send_pipeline_cmd(struct denali_nand_info *denali, setup_ecc_for_xfer(denali, ecc_en, transfer_spare); - clear_interrupts(denali); + denali_reset_irq(denali); addr = BANK(denali->flash_bank) | denali->page; @@ -479,9 +396,9 @@ static int write_oob_data(struct mtd_info *mtd, uint8_t *buf, int page) write_data_to_flash_mem(denali, buf, mtd->oobsize); /* wait for operation to complete */ - irq_status = wait_for_irq(denali, irq_mask); + irq_status = denali_wait_for_irq(denali, irq_mask); - if (irq_status == 0) { + if (!(irq_status & INTR__PROGRAM_COMP)) { dev_err(denali->dev, "OOB write failed\n"); status = -EIO; } @@ -510,9 +427,9 @@ static void read_oob_data(struct mtd_info *mtd, uint8_t *buf, int page) * can always use status0 bit as the * mask is identical for each bank. */ - irq_status = wait_for_irq(denali, irq_mask); + irq_status = denali_wait_for_irq(denali, irq_mask); - if (irq_status == 0) + if (!(irq_status & INTR__LOAD_COMP)) dev_err(denali->dev, "page on OOB timeout %d\n", denali->page); @@ -620,9 +537,9 @@ static int denali_sw_ecc_fixup(struct mtd_info *mtd, unsigned int err_byte, err_sector, err_device; uint8_t err_cor_value; unsigned int prev_sector = 0; + uint32_t irq_status; - /* read the ECC errors. we'll ignore them for now */ - denali_set_intr_modes(denali, false); + denali_reset_irq(denali); do { err_addr = ioread32(denali->flash_reg + ECC_ERROR_ADDRESS); @@ -674,10 +591,9 @@ static int denali_sw_ecc_fixup(struct mtd_info *mtd, * ECC_TRANSACTION_DONE interrupt, so here just wait for * a while for this interrupt */ - while (!(read_interrupt_status(denali) & INTR__ECC_TRANSACTION_DONE)) - cpu_relax(); - clear_interrupts(denali); - denali_set_intr_modes(denali, true); + irq_status = denali_wait_for_irq(denali, INTR__ECC_TRANSACTION_DONE); + if (!(irq_status & INTR__ECC_TRANSACTION_DONE)) + return -EIO; return max_bitflips; } @@ -778,15 +694,14 @@ static int write_page(struct mtd_info *mtd, struct nand_chip *chip, dma_sync_single_for_device(denali->dev, addr, size, DMA_TO_DEVICE); - clear_interrupts(denali); + denali_reset_irq(denali); denali_enable_dma(denali, true); denali_setup_dma(denali, DENALI_WRITE); /* wait for operation to complete */ - irq_status = wait_for_irq(denali, irq_mask); - - if (irq_status == 0) { + irq_status = denali_wait_for_irq(denali, irq_mask); + if (!(irq_status & INTR__DMA_CMD_COMP)) { dev_err(denali->dev, "timeout on write_page (type = %d)\n", raw_xfer); ret = -EIO; @@ -865,11 +780,11 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, denali_enable_dma(denali, true); dma_sync_single_for_device(denali->dev, addr, size, DMA_FROM_DEVICE); - clear_interrupts(denali); + denali_reset_irq(denali); denali_setup_dma(denali, DENALI_READ); /* wait for operation to complete */ - irq_status = wait_for_irq(denali, irq_mask); + irq_status = denali_wait_for_irq(denali, irq_mask); dma_sync_single_for_cpu(denali->dev, addr, size, DMA_FROM_DEVICE); @@ -901,6 +816,7 @@ static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, dma_addr_t addr = denali->buf.dma_buf; size_t size = mtd->writesize + mtd->oobsize; uint32_t irq_mask = INTR__DMA_CMD_COMP; + uint32_t irq_status; denali->page = page; @@ -909,11 +825,13 @@ static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, dma_sync_single_for_device(denali->dev, addr, size, DMA_FROM_DEVICE); - clear_interrupts(denali); + denali_reset_irq(denali); denali_setup_dma(denali, DENALI_READ); /* wait for operation to complete */ - wait_for_irq(denali, irq_mask); + irq_status = denali_wait_for_irq(denali, irq_mask); + if (irq_status & INTR__DMA_CMD_COMP) + return -ETIMEDOUT; dma_sync_single_for_cpu(denali->dev, addr, size, DMA_FROM_DEVICE); @@ -940,9 +858,7 @@ static void denali_select_chip(struct mtd_info *mtd, int chip) { struct denali_nand_info *denali = mtd_to_denali(mtd); - spin_lock_irq(&denali->irq_lock); denali->flash_bank = chip; - spin_unlock_irq(&denali->irq_lock); } static int denali_waitfunc(struct mtd_info *mtd, struct nand_chip *chip) @@ -953,19 +869,19 @@ static int denali_waitfunc(struct mtd_info *mtd, struct nand_chip *chip) static int denali_erase(struct mtd_info *mtd, int page) { struct denali_nand_info *denali = mtd_to_denali(mtd); - uint32_t cmd, irq_status; - clear_interrupts(denali); + denali_reset_irq(denali); /* setup page read request for access type */ cmd = MODE_10 | BANK(denali->flash_bank) | page; index_addr(denali, cmd, 0x1); /* wait for erase to complete or failure to occur */ - irq_status = wait_for_irq(denali, INTR__ERASE_COMP | INTR__ERASE_FAIL); + irq_status = denali_wait_for_irq(denali, + INTR__ERASE_COMP | INTR__ERASE_FAIL); - return irq_status & INTR__ERASE_FAIL ? NAND_STATUS_FAIL : PASS; + return irq_status & INTR__ERASE_COMP ? 0 : NAND_STATUS_FAIL; } static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col, @@ -1152,7 +1068,6 @@ static void denali_hw_init(struct denali_nand_info *denali) /* Should set value for these registers when init */ iowrite32(0, denali->flash_reg + TWO_ROW_ADDR_CYCLES); iowrite32(1, denali->flash_reg + ECC_ENABLE); - denali_irq_init(denali); } int denali_calc_ecc_bytes(int step_size, int strength) @@ -1264,9 +1179,6 @@ static void denali_drv_init(struct denali_nand_info *denali) /* indicate that MTD has not selected a valid bank yet */ denali->flash_bank = CHIP_SELECT_INVALID; - - /* initialize our irq_status variable to indicate no interrupts */ - denali->irq_status = 0; } static int denali_multidev_fixup(struct denali_nand_info *denali) @@ -1336,6 +1248,8 @@ int denali_init(struct denali_nand_info *denali) denali_hw_init(denali); denali_drv_init(denali); + denali_clear_irq_all(denali); + /* Request IRQ after all the hardware initialization is finished */ ret = devm_request_irq(denali->dev, denali->irq, denali_isr, IRQF_SHARED, DENALI_NAND_NAME, denali); @@ -1344,8 +1258,8 @@ int denali_init(struct denali_nand_info *denali) return ret; } - /* now that our ISR is registered, we can enable interrupts */ - denali_set_intr_modes(denali, true); + denali_enable_irq(denali); + nand_set_flash_node(chip, denali->dev->of_node); /* Fallback to the default name if DT did not give "label" property */ if (!mtd->name) @@ -1370,7 +1284,7 @@ int denali_init(struct denali_nand_info *denali) */ ret = nand_scan_ident(mtd, denali->max_banks, NULL); if (ret) - goto failed_req_irq; + goto disable_irq; /* allocate the right size buffer now */ devm_kfree(denali->dev, denali->buf.buf); @@ -1379,7 +1293,7 @@ int denali_init(struct denali_nand_info *denali) GFP_KERNEL); if (!denali->buf.buf) { ret = -ENOMEM; - goto failed_req_irq; + goto disable_irq; } ret = dma_set_mask(denali->dev, @@ -1387,7 +1301,7 @@ int denali_init(struct denali_nand_info *denali) 64 : 32)); if (ret) { dev_err(denali->dev, "No usable DMA configuration\n"); - goto failed_req_irq; + goto disable_irq; } denali->buf.dma_buf = dma_map_single(denali->dev, denali->buf.buf, @@ -1396,7 +1310,7 @@ int denali_init(struct denali_nand_info *denali) if (dma_mapping_error(denali->dev, denali->buf.dma_buf)) { dev_err(denali->dev, "Failed to map DMA buffer\n"); ret = -EIO; - goto failed_req_irq; + goto disable_irq; } /* @@ -1420,7 +1334,7 @@ int denali_init(struct denali_nand_info *denali) ret = denali_ecc_setup(mtd, chip, denali); if (ret) { dev_err(denali->dev, "Failed to setup ECC settings.\n"); - goto failed_req_irq; + goto disable_irq; } dev_dbg(denali->dev, @@ -1454,21 +1368,21 @@ int denali_init(struct denali_nand_info *denali) ret = denali_multidev_fixup(denali); if (ret) - goto failed_req_irq; + goto disable_irq; ret = nand_scan_tail(mtd); if (ret) - goto failed_req_irq; + goto disable_irq; ret = mtd_device_register(mtd, NULL, 0); if (ret) { dev_err(denali->dev, "Failed to register MTD: %d\n", ret); - goto failed_req_irq; + goto disable_irq; } return 0; -failed_req_irq: - denali_irq_cleanup(denali->irq, denali); +disable_irq: + denali_disable_irq(denali); return ret; } @@ -1486,7 +1400,7 @@ void denali_remove(struct denali_nand_info *denali) int bufsize = mtd->writesize + mtd->oobsize; nand_release(mtd); - denali_irq_cleanup(denali->irq, denali); + denali_disable_irq(denali); dma_unmap_single(denali->dev, denali->buf.dma_buf, bufsize, DMA_BIDIRECTIONAL); } diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h index fb473895a79d..a0ac0f84f8b5 100644 --- a/drivers/mtd/nand/denali.h +++ b/drivers/mtd/nand/denali.h @@ -325,6 +325,7 @@ struct denali_nand_info { /* elements used by ISR */ struct completion complete; spinlock_t irq_lock; + uint32_t irq_mask; uint32_t irq_status; int irq; From patchwork Tue Jun 13 05:03:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 103687 Delivered-To: patch@linaro.org Received: by 10.140.91.77 with SMTP id y71csp235761qgd; Mon, 12 Jun 2017 22:06:23 -0700 (PDT) X-Received: by 10.99.169.26 with SMTP id u26mr61900446pge.177.1497330383049; Mon, 12 Jun 2017 22:06:23 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1497330383; cv=none; d=google.com; s=arc-20160816; b=JJBGLB6IZNuJeMAf7h7CAk9GcshKOzTO0C/rO6yY6xillPeq8asYXg9cCmWOAhryvw B0l1Y69HgZKerB4GKzuwpErqxsW+OtyvzsLp3d3j50BDRVj+8sjjOT44trHLEELNKf9I v4mhhOy3dQmsVeifReXZgSxBcIuRcuN6kArbvfFRrJxWdI6Y+rhAbEEGoDkiXscQ6KYA 0SArnK3vFl/gPverLuEYT8/PZ9TlUerc+jW0Ky9Rk6puwkMgYLZdKeMrUSfRyl+MmGUN DjRUNmu3TuiBCDHhyMU6alISzXgWEZHo6Q5cULiaz6UFOA5NpjgkCaFcw165T/+3CMzU mqdQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:sender:content-transfer-encoding:mime-version:cc :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:references:in-reply-to:message-id:date:subject :to:from:dkim-signature:dkim-filter:dkim-signature :arc-authentication-results; bh=5+DXaJQKSXDK5vowROIsgh68qvL0Re6U51yTLMRQn9w=; b=e8GtCkYLF+NY57sGPIjQgJ0k7Z7G7aQTm/1cuBj1dKV7Q1PU+0912La3rpuJCLHtG3 qbJ3LHNKJPcduaEutpy6oFvMXdew/Ft91eGt/s+aXWksgM43refnJBQvQzoPmsPQcRgx Fjao4RkNPXo5Il7uWwDZPG0kZq+b47PyQYwRKR5kDdksDD2MR1GsKQ71WyE6PqDhWIEr YXQnTUwtyS/gAR8IILC+atMvXp1p8j8s76odTXBuac4h/9O32FGjVWSpdt8zavpowQ+J HIqDxdJviXBpJ5T0STe9Q7AzBESOZtEfwZjLX+NkGw4igT/I9Tut5LmDX7lP5RvYK9Ly MYfg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.infradead.org; dkim=neutral (body hash did not verify) header.i=@nifty.com; spf=pass (google.com: best guess record for domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 65.50.211.133 as permitted sender) smtp.mailfrom=linux-mtd-bounces+patch=linaro.org@lists.infradead.org Return-Path: Received: from bombadil.infradead.org (bombadil.infradead.org. [65.50.211.133]) by mx.google.com with ESMTPS id v2si8396377plk.471.2017.06.12.22.06.22 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 12 Jun 2017 22:06:23 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 65.50.211.133 as permitted sender) client-ip=65.50.211.133; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.infradead.org; dkim=neutral (body hash did not verify) header.i=@nifty.com; spf=pass (google.com: best guess record for domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 65.50.211.133 as permitted sender) smtp.mailfrom=linux-mtd-bounces+patch=linaro.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=5+DXaJQKSXDK5vowROIsgh68qvL0Re6U51yTLMRQn9w=; b=UpvotOrP1g+P4oXtzFsXKo4CQe LrBJ98FXxt3i5IYAaEN9RhST8KvG8vpy9IWB8/HaPas2Aah6AtKJN1TfbZxUZnx4jBe3ce01kByVL +CJKy2l4clSYDygMZQwN/zG2oRMg4E7aEpZ8+i10zYeuQ8PRqTn0wUBfvMgJ5VB7OC6quvoMzsgI5 jVEfFiHK1MN2qzVl7E03k24QrGuzCsueQtkjSM2GzALxWU6V0+4ExXhbcwOMugqNGxNrbkldoSGhP Mok555axA8ia1eBsQeOA7MtJvBzpwFhBTr6wyxzMLqLe32wKnRkheiWW6lcM02ypEvKwba6Aepwa9 f+L2YAVQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dKe1w-0007iS-BH; Tue, 13 Jun 2017 05:06:16 +0000 Received: from conuserg-09.nifty.com ([210.131.2.76]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dKe0t-0005xD-R9 for linux-mtd@lists.infradead.org; Tue, 13 Jun 2017 05:05:15 +0000 Received: from pug.e01.socionext.com (p14092-ipngnfx01kyoto.kyoto.ocn.ne.jp [153.142.97.92]) (authenticated) by conuserg-09.nifty.com with ESMTP id v5D54ENj023096; Tue, 13 Jun 2017 14:04:20 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conuserg-09.nifty.com v5D54ENj023096 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nifty.com; s=dec2015msa; t=1497330261; bh=gc9iRZU8GbdNl4h+G7cJNgIT3hiiT3JLsaUmeFq6P18=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MhFzM3T0aRMHXMt/HY708lH51sY0R8lXweT35inr+qw+ie/W+ZRL9b3v/8A8Y0eWx vjjfBrGVboL14zkVMRfQPoMKJK6L/aR9UeNaMFa9rYZbrsgsLstVPCi7p5uSDPNixD kc7r4ewFMYASijkysBi2QJbOEw9V8KlqFOPjfedcY1yu8tjzeQX1B/CZ3E9wIu0zsT GiqKzX4MNsQL4ZOhU+Xs2oV6TKQEqUt/lpT8Nl2Ts7YKmGo7T89lZwUo4B+mkZbINS mg+EQ4CrfdD0Km2qrj6yXRGZVcXj6o7wspB5bx8FTXyz6mLxxeTbh2cupgcfbq6Zv/ o2pwaVPLsrrBg== X-Nifty-SrcIP: [153.142.97.92] From: Masahiro Yamada To: linux-mtd@lists.infradead.org Subject: [PATCH v6 05/18] mtd: nand: denali: fix NAND_CMD_STATUS handling Date: Tue, 13 Jun 2017 14:03:57 +0900 Message-Id: <1497330250-17348-6-git-send-email-yamada.masahiro@socionext.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1497330250-17348-1-git-send-email-yamada.masahiro@socionext.com> References: <1497330250-17348-1-git-send-email-yamada.masahiro@socionext.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170612_220512_329867_76E6D019 X-CRM114-Status: GOOD ( 11.54 ) X-Spam-Score: -1.2 (-) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-1.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.7 SPF_SOFTFAIL SPF: sender does not match SPF record (softfail) -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Boris Brezillon , Cyrille Pitchen , Richard Weinberger , Marek Vasut , Masahiro Yamada , Artem Bityutskiy , Dinh Nguyen , linux-kernel@vger.kernel.org, Enrico Jorns , Masami Hiramatsu , Chuanxiao Dong , Jassi Brar , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+patch=linaro.org@lists.infradead.org The current NAND_CMD_STATUS handling is weird; it just reads the WRITE_PROTECT register, and returns NAND_STATUS_WP if it is set. It does not send Read Status (0x70) command, so it is not helpful for checking the current device status. Signed-off-by: Masahiro Yamada --- Changes in v6: None Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: - Newly added drivers/mtd/nand/denali.c | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) -- 2.7.4 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index d7e7555a3d73..4bf93232ca30 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -107,21 +107,6 @@ static void write_byte_to_buf(struct denali_nand_info *denali, uint8_t byte) denali->buf.buf[denali->buf.tail++] = byte; } -/* reads the status of the device */ -static void read_status(struct denali_nand_info *denali) -{ - uint32_t cmd; - - /* initialize the data buffer to store status */ - reset_buf(denali); - - cmd = ioread32(denali->flash_reg + WRITE_PROTECT); - if (cmd) - write_byte_to_buf(denali, NAND_STATUS_WP); - else - write_byte_to_buf(denali, 0); -} - /* Reset the flash controller */ static uint16_t denali_nand_reset(struct denali_nand_info *denali) { @@ -893,7 +878,11 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col, switch (cmd) { case NAND_CMD_STATUS: - read_status(denali); + reset_buf(denali); + addr = MODE_11 | BANK(denali->flash_bank); + index_addr(denali, addr | 0, cmd); + index_addr_read_data(denali, addr | 2, &id); + write_byte_to_buf(denali, id); break; case NAND_CMD_READID: case NAND_CMD_PARAM: From patchwork Tue Jun 13 05:03:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 103693 Delivered-To: patch@linaro.org Received: by 10.140.91.77 with SMTP id y71csp235990qgd; Mon, 12 Jun 2017 22:07:07 -0700 (PDT) X-Received: by 10.99.116.2 with SMTP id p2mr6568789pgc.162.1497330427113; Mon, 12 Jun 2017 22:07:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1497330427; cv=none; d=google.com; s=arc-20160816; b=jBgs+OVPFWdTf6XqoeU4X6HE2z6TyZrJtcsqugd/Rp13r62a76o9/5Bu703RCjXvJN tNhZQpaJk//+CZDSispK4/rWWG0GsRkQTcM8e1t4OLLyGN3fz1AQukTjYuxTDcnvQQNx 8H4jaLaOrco3zOGgzJ0DIypQ6Y1E5l+6RngviAkQlqx+Zrei6aG7rAJcnTvZWa7AEom2 a48DlVMDfLL04KOIU+uwzHxeFxTYhBlqmPzKlkkx8g9tVKskH8NKUXDZzDTQCQpweI3h Q/EkPnR+tJAuQAdzrAHozqUyG6zWysub1DjgdCQZDAWzwr33n7aX75c36Bz4M0qmzucT cgdA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:sender:content-transfer-encoding:mime-version:cc :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:references:in-reply-to:message-id:date:subject :to:from:dkim-signature:dkim-filter:dkim-signature :arc-authentication-results; bh=iEPXQKxh2aiz+htG4JLee9wRKbLLAQIyyZrO00zO564=; b=q4+ResRPWlOTJPbyTLn//VQYsxHNGavf/KFqUP6PcMe+YS7cBwi/IxxUAnIsL3iOli Yk5eIlSfCCZ6mQXBLu81U1deQzv3Um6kcImjF9I1B8vH2u54ib7VeTBJQwNCgWDd+3gB NTW9TYXmwgErU5ZoBdlJNAjnI8axueKYOpRPpHxhTiik1sez+l9dLZuFto8yg0qXafU5 sljhFw4IoRtItCUT1zy10MuJEX+oFLmRqg6pc43zeepOjgcu2VXw4hIkDPdwosxFPWzd 35Qcc1eVvJN7UxJtyrmGe0GM+5uBE9CPgQioijmz3uYUpsxm6g9h4jIfxkr8uXulEHwt 2oQg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.infradead.org; dkim=neutral (body hash did not verify) header.i=@nifty.com; spf=pass (google.com: best guess record for domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 65.50.211.133 as permitted sender) smtp.mailfrom=linux-mtd-bounces+patch=linaro.org@lists.infradead.org Return-Path: Received: from bombadil.infradead.org (bombadil.infradead.org. [65.50.211.133]) by mx.google.com with ESMTPS id v18si8367093pfl.202.2017.06.12.22.07.06 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 12 Jun 2017 22:07:07 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 65.50.211.133 as permitted sender) client-ip=65.50.211.133; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.infradead.org; dkim=neutral (body hash did not verify) header.i=@nifty.com; spf=pass (google.com: best guess record for domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 65.50.211.133 as permitted sender) smtp.mailfrom=linux-mtd-bounces+patch=linaro.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=iEPXQKxh2aiz+htG4JLee9wRKbLLAQIyyZrO00zO564=; b=lV/WNYbCaC+EEP5EprN4F+CPYC ZMnIg0dIkBasXc/AObBc8F331sRihDLbEUKvcTeZiWJERzdCv1xOKBKZMXqKGOj771qT2CHkEFOrm FEpGqblft5AEsiunDfQA2qmVzWV1Tyxig16556ovyjVrqC6Z4UdKyvay+R6uQhvhiRmr+kpCaA5g3 8VhaeZwEUFnIVNMIiFmv/gYWpy/8iMWmKx4bLk8ai3/DdCeBEKThIoejJGbPJc9McrNxTOfsy2W1f F3xqQgbxjp4WnJTKEFtgrFoLp87p44fxjqmFBSQt+qUKYl2t2jwFIzJdPyETsLOGQDVqhYzKiz9RL h8aNul5Q==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dKe2h-0000KV-Id; Tue, 13 Jun 2017 05:07:03 +0000 Received: from conuserg-09.nifty.com ([210.131.2.76]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dKe0t-0005xE-R5 for linux-mtd@lists.infradead.org; Tue, 13 Jun 2017 05:05:18 +0000 Received: from pug.e01.socionext.com (p14092-ipngnfx01kyoto.kyoto.ocn.ne.jp [153.142.97.92]) (authenticated) by conuserg-09.nifty.com with ESMTP id v5D54ENk023096; Tue, 13 Jun 2017 14:04:21 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conuserg-09.nifty.com v5D54ENk023096 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nifty.com; s=dec2015msa; t=1497330262; bh=YJVVlJ0kZ4PLQEfxpw3dx+VvZG2Abn8vYgYWZ+g3t4Y=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=f/GlMkT5CqB9ZV8Ac5SjkIijbSJqcmp6ctIK1jR605tjXHzkYQUjuuvExuN1bW6NS 7Gh9aqHkii4ELZZBu0HDeEtULBg8KRwOyaxuDzb7wn+caEHOSjHYlEb9uaNAFeVsXP 4Q0Xtf3b4lDn9AJ5bo/bLd6pokaEU4G9bElM7qvdLECDSmUGYaLpRf06irvTILAbre ThZ/xnzsUFg6fmWtv5D8Ll9WtwtFo8cjm3VIx9wyh5nQGlVDRrAHK2WIom9xB3SXRN fxIO7h2DS3TXLqVkp3GnLQarREOXO42LRXRZaNeEu82v0UIphEFuE2jEeQ26wV1oKK kq3wN7qHGS6xQ== X-Nifty-SrcIP: [153.142.97.92] From: Masahiro Yamada To: linux-mtd@lists.infradead.org Subject: [PATCH v6 06/18] mtd: nand: denali: fix NAND_CMD_PARAM handling Date: Tue, 13 Jun 2017 14:03:58 +0900 Message-Id: <1497330250-17348-7-git-send-email-yamada.masahiro@socionext.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1497330250-17348-1-git-send-email-yamada.masahiro@socionext.com> References: <1497330250-17348-1-git-send-email-yamada.masahiro@socionext.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170612_220512_405978_1C4CFA88 X-CRM114-Status: GOOD ( 21.57 ) X-Spam-Score: -1.2 (-) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-1.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.7 SPF_SOFTFAIL SPF: sender does not match SPF record (softfail) -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Boris Brezillon , Cyrille Pitchen , Richard Weinberger , Marek Vasut , Masahiro Yamada , Artem Bityutskiy , Dinh Nguyen , linux-kernel@vger.kernel.org, Enrico Jorns , Masami Hiramatsu , Chuanxiao Dong , Jassi Brar , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+patch=linaro.org@lists.infradead.org NAND_CMD_PARAM is not working at all due to multiple bugs. [1] The command 0x90 issued instead of 0xec The command code 0x90 is hard-code as index_addr(denali, addr | 0, 0x90) So, Read ID (0x90) command is sent to the device instead of Read Parameter Page (0xec). [2] only first 8 bytes are read Even if [1] is fixed, the current implementation is problematic. The only first 8 bytes are read by MAP11 command, and put into the temporal buffer: for (i = 0; i < 8; i++) { index_addr_read_data(denali, addr | 2, &id); write_byte_to_buf(denali, id); } Obviously, this is not sufficient for NAND_CMD_PARAM; the ONFi parameters are 256-byte long. This is still insufficient. As you see in nand_flash_detect_onfi() reads out (256 * 3) bytes at maximum (Redundant Parameter Pages). However, changing the loop to for (i = 0; i < 768; i++) is a crazy idea. At the point of the chip->cmdfunc() call, we cannot know how many times chip->read_byte() will be called. So, pre-reading enough number of bytes in the chip->cmdfunc() is a design mistake. [3] no wait for R/B# The current code handles NAND_CMD_READID and NAND_CMD_PARAM in the same way, but this is also wrong. The difference between them is that Read ID command does not toggle R/B# whereas the Read Parameter Page command requires R/B#. Without the wait for R/B# interrupt, wrong data are retrieved. In order to fix those problems, data read cycle of the MAP11 command has been moved to chip->read_byte(). Data are read out as needed. Another good thing is early temporal buffer is not needed any more. The ugly devm_kzalloc()/devm_kfree() dance has been killed. Signed-off-by: Masahiro Yamada --- Changes in v6: None Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: - Newly added drivers/mtd/nand/denali.c | 95 +++++++++++++++-------------------------------- drivers/mtd/nand/denali.h | 2 - 2 files changed, 30 insertions(+), 67 deletions(-) -- 2.7.4 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index 4bf93232ca30..2325a97aa54a 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -85,28 +85,6 @@ static void index_addr(struct denali_nand_info *denali, iowrite32(data, denali->flash_mem + 0x10); } -/* Perform an indexed read of the device */ -static void index_addr_read_data(struct denali_nand_info *denali, - uint32_t address, uint32_t *pdata) -{ - iowrite32(address, denali->flash_mem); - *pdata = ioread32(denali->flash_mem + 0x10); -} - -/* - * We need to buffer some data for some of the NAND core routines. - * The operations manage buffering that data. - */ -static void reset_buf(struct denali_nand_info *denali) -{ - denali->buf.head = denali->buf.tail = 0; -} - -static void write_byte_to_buf(struct denali_nand_info *denali, uint8_t byte) -{ - denali->buf.buf[denali->buf.tail++] = byte; -} - /* Reset the flash controller */ static uint16_t denali_nand_reset(struct denali_nand_info *denali) { @@ -286,6 +264,15 @@ static void setup_ecc_for_xfer(struct denali_nand_info *denali, bool ecc_en, iowrite32(transfer_spare_flag, denali->flash_reg + TRANSFER_SPARE_REG); } +static uint8_t denali_read_byte(struct mtd_info *mtd) +{ + struct denali_nand_info *denali = mtd_to_denali(mtd); + + iowrite32(MODE_11 | BANK(denali->flash_bank) | 2, denali->flash_mem); + + return ioread32(denali->flash_mem + 0x10); +} + /* * sends a pipeline command operation to the controller. See the Denali NAND * controller's user guide for more information (section 4.2.3.6). @@ -828,17 +815,6 @@ static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, return 0; } -static uint8_t denali_read_byte(struct mtd_info *mtd) -{ - struct denali_nand_info *denali = mtd_to_denali(mtd); - uint8_t result = 0xff; - - if (denali->buf.head < denali->buf.tail) - result = denali->buf.buf[denali->buf.head++]; - - return result; -} - static void denali_select_chip(struct mtd_info *mtd, int chip) { struct denali_nand_info *denali = mtd_to_denali(mtd); @@ -873,43 +849,40 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col, int page) { struct denali_nand_info *denali = mtd_to_denali(mtd); - uint32_t addr, id; - int i; + uint32_t addr, irq_status; + int wait_ready = 0; switch (cmd) { - case NAND_CMD_STATUS: - reset_buf(denali); - addr = MODE_11 | BANK(denali->flash_bank); - index_addr(denali, addr | 0, cmd); - index_addr_read_data(denali, addr | 2, &id); - write_byte_to_buf(denali, id); + case NAND_CMD_PARAM: + wait_ready = 1; break; + case NAND_CMD_STATUS: case NAND_CMD_READID: - case NAND_CMD_PARAM: - reset_buf(denali); - /* - * sometimes ManufactureId read from register is not right - * e.g. some of Micron MT29F32G08QAA MLC NAND chips - * So here we send READID cmd to NAND insteand - */ - addr = MODE_11 | BANK(denali->flash_bank); - index_addr(denali, addr | 0, 0x90); - index_addr(denali, addr | 1, col); - for (i = 0; i < 8; i++) { - index_addr_read_data(denali, addr | 2, &id); - write_byte_to_buf(denali, id); - } break; case NAND_CMD_RESET: reset_bank(denali); break; case NAND_CMD_READOOB: /* TODO: Read OOB data */ - break; + return; default: pr_err(": unsupported command received 0x%x\n", cmd); - break; + return; } + + denali_reset_irq(denali); + + addr = MODE_11 | BANK(denali->flash_bank); + index_addr(denali, addr | 0, cmd); + if (col != -1) + index_addr(denali, addr | 1, col); + + if (!wait_ready) + return; + + irq_status = denali_wait_for_irq(denali, INTR__INT_ACT); + if (!(irq_status & INTR__INT_ACT)) + dev_err(denali->dev, "failed to issue command 0x%x\n", cmd); } #define DIV_ROUND_DOWN_ULL(ll, d) \ @@ -1227,12 +1200,6 @@ int denali_init(struct denali_nand_info *denali) struct mtd_info *mtd = nand_to_mtd(chip); int ret; - /* allocate a temporary buffer for nand_scan_ident() */ - denali->buf.buf = devm_kzalloc(denali->dev, PAGE_SIZE, - GFP_DMA | GFP_KERNEL); - if (!denali->buf.buf) - return -ENOMEM; - mtd->dev.parent = denali->dev; denali_hw_init(denali); denali_drv_init(denali); @@ -1275,8 +1242,6 @@ int denali_init(struct denali_nand_info *denali) if (ret) goto disable_irq; - /* allocate the right size buffer now */ - devm_kfree(denali->dev, denali->buf.buf); denali->buf.buf = devm_kzalloc(denali->dev, mtd->writesize + mtd->oobsize, GFP_KERNEL); diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h index a0ac0f84f8b5..a84d8784ee98 100644 --- a/drivers/mtd/nand/denali.h +++ b/drivers/mtd/nand/denali.h @@ -306,8 +306,6 @@ #define MODE_11 0x0C000000 struct nand_buf { - int head; - int tail; uint8_t *buf; dma_addr_t dma_buf; }; From patchwork Tue Jun 13 05:03:59 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 103686 Delivered-To: patch@linaro.org Received: by 10.140.91.77 with SMTP id y71csp235704qgd; Mon, 12 Jun 2017 22:06:11 -0700 (PDT) X-Received: by 10.99.247.83 with SMTP id f19mr62151677pgk.190.1497330371394; Mon, 12 Jun 2017 22:06:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1497330371; cv=none; d=google.com; s=arc-20160816; b=ose6PGJxYfNbfYZBKw6e1zbPMLv6DOkuknqYpLn+xSVY2emcjgzGjfaWykKDjXjfDn zolx1mT/7zzSQ6qn151G+yaosdUtfkf/yQq16X/BIo5INq9FHY1aFvTfRkXbwDv60T4a AuAjm4GE4NYFhMjJRjjv+9b88m18HVxcA5X8U/2i5Vk2KrFjEgaJnqxQZudmomUjvzQB cVpQDAAGOCpbsu8ziUvEtTWnhr4PPYZcJoGaqS1ACIadytHNoAC7PEKy9J6EK6//c9DH T6BwuzJCfnh1YLvIC8cSm13stiWXn45qiNVvMYRmGtpOUhju6gaUMTk6gvH/iKxFpWwk PbEw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:sender:content-transfer-encoding:mime-version:cc :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:references:in-reply-to:message-id:date:subject :to:from:dkim-signature:dkim-filter:dkim-signature :arc-authentication-results; bh=I6wu0YfZVOcWmCdGVkr5TeuIHdhmVCeBxZ+PXHtcZmw=; b=xO+zlMoS0R7FfSjhFSSSodqiVqDP5lyorfl/OFwEE1yW2lfHZlp/bxAfTTFw+NT3Oy uCvr3SJRo/6B1SygjK/VuM/BBjciNwVOeXUAvM5XWiU5Y0AD2f115aDQDh+o1nQG+FEw gactPIZC1xgm6nt3/RU/E/MPG5Xn2GWZOUg3WANC0CCxdl58TNv6K7S7LhnCxFNXSFOL 2iwGD8oxpx1Ej1QjKBoJtV0viKUYltHT/fG6jzjCJr9dZJiX4yD4RbOBPneX84hwIwSJ 9PF63RWVkgqrPxtmwqle5Ibu/LJIbMwNM9k4pxP6CQUWTitl5cxg1U8vzj1uTpThI1XM iOVQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.infradead.org; dkim=neutral (body hash did not verify) header.i=@nifty.com; spf=pass (google.com: best guess record for domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 65.50.211.133 as permitted sender) smtp.mailfrom=linux-mtd-bounces+patch=linaro.org@lists.infradead.org Return-Path: Received: from bombadil.infradead.org (bombadil.infradead.org. [65.50.211.133]) by mx.google.com with ESMTPS id y67si8405311pff.44.2017.06.12.22.06.11 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 12 Jun 2017 22:06:11 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 65.50.211.133 as permitted sender) client-ip=65.50.211.133; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.infradead.org; dkim=neutral (body hash did not verify) header.i=@nifty.com; spf=pass (google.com: best guess record for domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 65.50.211.133 as permitted sender) smtp.mailfrom=linux-mtd-bounces+patch=linaro.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=I6wu0YfZVOcWmCdGVkr5TeuIHdhmVCeBxZ+PXHtcZmw=; b=bzvzVAbYwOnaOxvaKTzTZS6c+9 MTAx4J+j5M0dHUbpT+AC/i3ztZR3hVgKdTmSZ7lnrpJJYcf4deZnnU2WV/+1/ssMALRYQNoDsrH2q 5s1MeYxORhwmTn5+hwIosMXcD/SsLQaDAQshdb7N98tpMydCvXBztASHCtP0yxqLd9Ar4lYnl02Np rnr1zJ0LVzArqpc4GNbtIb7TEsGGLJ1MSLDMhaMxnOoEltpnUcCjT48RZxQVyWUAUnPq2Q9ONPMo+ l3xNQHRjMBnvVKtzPOrvykeSMouhtXLvbC+AC07iOVdrZUuZahWtemssgE0FSRWMhf77/WtboqGRQ agw4MyUw==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dKe1l-0007PP-7u; Tue, 13 Jun 2017 05:06:05 +0000 Received: from conuserg-09.nifty.com ([210.131.2.76]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dKe0t-0005xC-R5 for linux-mtd@lists.infradead.org; Tue, 13 Jun 2017 05:05:14 +0000 Received: from pug.e01.socionext.com (p14092-ipngnfx01kyoto.kyoto.ocn.ne.jp [153.142.97.92]) (authenticated) by conuserg-09.nifty.com with ESMTP id v5D54ENl023096; Tue, 13 Jun 2017 14:04:22 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conuserg-09.nifty.com v5D54ENl023096 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nifty.com; s=dec2015msa; t=1497330263; bh=cOZQfvJh4mduPNNG4EcIAioA2aa56JmbcxMjDvnlefs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=WJhwPlCPO4fuZeSkE/zIToiEN5W/ylg0CO+fl4foG65TJxGZ75j+c16hnSCOx9jZy oOOqdN1YJdJD6IWCWbGG+Tg/Xnos2ywtVG0/mf5P3zMoRnaWto63a1KGJHabzUVIQ6 QgdhStAHxI5LNnnQi0QwVZGGNKvDSam7t5b1/WHV9ee7Dhp2BHw6c7Z15sO1t9ll/4 xQr7TqOSwQw5a9ojCSujL2PH5zEv4GZmT9uo0mqS2T8zhxnytBM1szMO4fugZICcdl SbB3Vdj0sLhXUCkTlxg4ZTyQR1im5rDcfhSnwh+LZ7I//u5fItwKak8ekATyFie+U1 idEJaKyMr1xSQ== X-Nifty-SrcIP: [153.142.97.92] From: Masahiro Yamada To: linux-mtd@lists.infradead.org Subject: [PATCH v6 07/18] mtd: nand: denali: switch over to cmd_ctrl instead of cmdfunc Date: Tue, 13 Jun 2017 14:03:59 +0900 Message-Id: <1497330250-17348-8-git-send-email-yamada.masahiro@socionext.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1497330250-17348-1-git-send-email-yamada.masahiro@socionext.com> References: <1497330250-17348-1-git-send-email-yamada.masahiro@socionext.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170612_220512_122862_27ACCB82 X-CRM114-Status: GOOD ( 16.94 ) X-Spam-Score: -1.2 (-) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-1.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.7 SPF_SOFTFAIL SPF: sender does not match SPF record (softfail) -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Boris Brezillon , Cyrille Pitchen , Richard Weinberger , Marek Vasut , Masahiro Yamada , Artem Bityutskiy , Dinh Nguyen , linux-kernel@vger.kernel.org, Enrico Jorns , Masami Hiramatsu , Chuanxiao Dong , Jassi Brar , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+patch=linaro.org@lists.infradead.org The NAND_CMD_SET_FEATURES support is missing from denali_cmdfunc(). Besides, we see /* TODO: Read OOB data */ comment line. It would be possible to add more commands along with the current implementation, but having ->cmd_ctrl() seems a better approach from the discussion with Boris [1]. Rely on the default ->cmdfunc() from the framework and implement the driver's own ->cmd_ctrl(). Also add ->write_byte(), which is needed for write direction commands. Then, we can drop nand_onfi_get_set_features_notsupp from this driver. [1] https://lkml.org/lkml/2017/3/15/97 Signed-off-by: Masahiro Yamada --- Changes in v6: - Remove nand_onfi_get_set_features_notsupp() Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: - Newly added drivers/mtd/nand/denali.c | 106 +++++++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 54 deletions(-) -- 2.7.4 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index 2325a97aa54a..09a14fafa967 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -230,20 +230,16 @@ static uint32_t denali_wait_for_irq(struct denali_nand_info *denali, return denali->irq_status; } -/* resets a specific device connected to the core */ -static void reset_bank(struct denali_nand_info *denali) +static uint32_t denali_check_irq(struct denali_nand_info *denali) { + unsigned long flags; uint32_t irq_status; - denali_reset_irq(denali); - - iowrite32(1 << denali->flash_bank, denali->flash_reg + DEVICE_RESET); - - irq_status = denali_wait_for_irq(denali, - INTR__RST_COMP | INTR__TIME_OUT); + spin_lock_irqsave(&denali->irq_lock, flags); + irq_status = denali->irq_status; + spin_unlock_irqrestore(&denali->irq_lock, flags); - if (!(irq_status & INTR__RST_COMP)) - dev_err(denali->dev, "reset bank failed.\n"); + return irq_status; } /* @@ -273,6 +269,42 @@ static uint8_t denali_read_byte(struct mtd_info *mtd) return ioread32(denali->flash_mem + 0x10); } +static void denali_write_byte(struct mtd_info *mtd, uint8_t byte) +{ + struct denali_nand_info *denali = mtd_to_denali(mtd); + + index_addr(denali, MODE_11 | BANK(denali->flash_bank) | 2, byte); +} + +static void denali_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl) +{ + struct denali_nand_info *denali = mtd_to_denali(mtd); + uint32_t type; + + if (ctrl & NAND_CLE) + type = 0; + else if (ctrl & NAND_ALE) + type = 1; + else + return; + + /* + * Some commands are followed by chip->dev_ready or chip->waitfunc. + * irq_status must be cleared here to catch the R/B# interrupt later. + */ + if (ctrl & NAND_CTRL_CHANGE) + denali_reset_irq(denali); + + index_addr(denali, MODE_11 | BANK(denali->flash_bank) | type, dat); +} + +static int denali_dev_ready(struct mtd_info *mtd) +{ + struct denali_nand_info *denali = mtd_to_denali(mtd); + + return !!(denali_check_irq(denali) & INTR__INT_ACT); +} + /* * sends a pipeline command operation to the controller. See the Denali NAND * controller's user guide for more information (section 4.2.3.6). @@ -824,7 +856,13 @@ static void denali_select_chip(struct mtd_info *mtd, int chip) static int denali_waitfunc(struct mtd_info *mtd, struct nand_chip *chip) { - return 0; + struct denali_nand_info *denali = mtd_to_denali(mtd); + uint32_t irq_status; + + /* R/B# pin transitioned from low to high? */ + irq_status = denali_wait_for_irq(denali, INTR__INT_ACT); + + return irq_status & INTR__INT_ACT ? 0 : NAND_STATUS_FAIL; } static int denali_erase(struct mtd_info *mtd, int page) @@ -845,46 +883,6 @@ static int denali_erase(struct mtd_info *mtd, int page) return irq_status & INTR__ERASE_COMP ? 0 : NAND_STATUS_FAIL; } -static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col, - int page) -{ - struct denali_nand_info *denali = mtd_to_denali(mtd); - uint32_t addr, irq_status; - int wait_ready = 0; - - switch (cmd) { - case NAND_CMD_PARAM: - wait_ready = 1; - break; - case NAND_CMD_STATUS: - case NAND_CMD_READID: - break; - case NAND_CMD_RESET: - reset_bank(denali); - break; - case NAND_CMD_READOOB: - /* TODO: Read OOB data */ - return; - default: - pr_err(": unsupported command received 0x%x\n", cmd); - return; - } - - denali_reset_irq(denali); - - addr = MODE_11 | BANK(denali->flash_bank); - index_addr(denali, addr | 0, cmd); - if (col != -1) - index_addr(denali, addr | 1, col); - - if (!wait_ready) - return; - - irq_status = denali_wait_for_irq(denali, INTR__INT_ACT); - if (!(irq_status & INTR__INT_ACT)) - dev_err(denali->dev, "failed to issue command 0x%x\n", cmd); -} - #define DIV_ROUND_DOWN_ULL(ll, d) \ ({ unsigned long long _tmp = (ll); do_div(_tmp, d); _tmp; }) @@ -1223,11 +1221,11 @@ int denali_init(struct denali_nand_info *denali) /* register the driver with the NAND core subsystem */ chip->select_chip = denali_select_chip; - chip->cmdfunc = denali_cmdfunc; chip->read_byte = denali_read_byte; + chip->write_byte = denali_write_byte; + chip->cmd_ctrl = denali_cmd_ctrl; + chip->dev_ready = denali_dev_ready; chip->waitfunc = denali_waitfunc; - chip->onfi_set_features = nand_onfi_get_set_features_notsupp; - chip->onfi_get_features = nand_onfi_get_set_features_notsupp; /* clk rate info is needed for setup_data_interface */ if (denali->clk_x_rate) From patchwork Tue Jun 13 05:04:02 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masahiro Yamada X-Patchwork-Id: 103697 Delivered-To: patch@linaro.org Received: by 10.140.91.77 with SMTP id y71csp236130qgd; Mon, 12 Jun 2017 22:07:35 -0700 (PDT) X-Received: by 10.101.88.130 with SMTP id d2mr17893222pgu.58.1497330455654; Mon, 12 Jun 2017 22:07:35 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1497330455; cv=none; d=google.com; s=arc-20160816; b=w3t8lzI+uBXjTdzdOz2wgDS18ljupSkYXz/KbPiSLsFVP/VfKoLn7cVfpxr8MIcS11 mFCJ8XqE/m6/k8au5KoLcxsq2O+95xaMUNEZ3e4ND+fV2qZEZR5UGk8Bedhu+aV4WPEU Hxdhg2elgff8ULZEaIxmjMxjkN/A6kKtnHJe2BWEJOPizeE59tFa0KV6b41lwzQRDxVc Kg53Lafs90hSwovcbbp0di6mHA3r4wQFrgVgmlo8Xllc4rCJmH691xFTP/vAUICIuwis Qw19YPIlkIqWWM5Gv0Wp55Y6ZImlyY5C+rtywxXJlZshIf4MCm4rOfrNiPAPI+8JjD2f a75Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:sender:content-transfer-encoding:mime-version:cc :list-subscribe:list-help:list-post:list-archive:list-unsubscribe :list-id:precedence:references:in-reply-to:message-id:date:subject :to:from:dkim-signature:dkim-filter:dkim-signature :arc-authentication-results; bh=7TvHcy0v+OPWdOaE4nDCkS8pCu/en85H1zcX4rtrdZE=; b=i8xlPX7SdvdRyG6c63biJokc75I5qQHMdnGwySMZH8IqxHLb9kjEUhEuzuhkKjWKAl w4DHA6CrFPR6Xm/M/fsxkZQmbaoIMxZGmyL7SDVe0nVOIqok6lDWpZHa43vhtLohhw5O +Sxm7UUv5cOqYsepbN27bbdv50j1famEOpD8MgUsn4M/abW/Dt7qAsDD2RmXo+Jd5GZg UvmJ2KEx6nzawGCCrpn1NW2A90U0+yLO2ZudPCmYK4Dh6zhAzE2QeAuh5GzDINw/l7XT f0Sl9SDmKOJ2IgvjI16TUh7WKaxAqBxCgpk/rSjRXEqfQDJZA5+yJQlwtpZ072Z7RpD1 FFQQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@lists.infradead.org; dkim=neutral (body hash did not verify) header.i=@nifty.com; spf=pass (google.com: best guess record for domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 65.50.211.133 as permitted sender) smtp.mailfrom=linux-mtd-bounces+patch=linaro.org@lists.infradead.org Return-Path: Received: from bombadil.infradead.org (bombadil.infradead.org. [65.50.211.133]) by mx.google.com with ESMTPS id u125si583000pgb.46.2017.06.12.22.07.35 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 12 Jun 2017 22:07:35 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 65.50.211.133 as permitted sender) client-ip=65.50.211.133; Authentication-Results: mx.google.com; dkim=pass header.i=@lists.infradead.org; dkim=neutral (body hash did not verify) header.i=@nifty.com; spf=pass (google.com: best guess record for domain of linux-mtd-bounces+patch=linaro.org@lists.infradead.org designates 65.50.211.133 as permitted sender) smtp.mailfrom=linux-mtd-bounces+patch=linaro.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=7TvHcy0v+OPWdOaE4nDCkS8pCu/en85H1zcX4rtrdZE=; b=qQ6YHT++jdxI8+DiDeie55HDjr UoRZ1hrAGN7kzDQ3YPuuTIef9zg62mADDchga1qOFG7LNepv643qzFiyPbgYdOz2o2GUrdMLgqlxr ed+nh8TL1xh9Q6lVDyKfhuMLyJJKv55VeA+AAvcdpk/ms4rChKszbeOptkhsBPp23R/fTNnTAEhsN nbafjGZvRj7GEoQCksswpeelzWAqdg+sKg3SRdROABlH+E6+51i+45yTFrab0GjycBvP28Jnh2DvR MoEB22dBJ1gmhKqG79ze5vVlVG/0Am/QEa64CzFoA2aH3WRIUpcqEe5Ky+9O4ezK1THVMQAZsiyMp tguWd1aQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dKe37-0000s7-BM; Tue, 13 Jun 2017 05:07:29 +0000 Received: from conuserg-09.nifty.com ([210.131.2.76]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dKe0y-0005xN-2f for linux-mtd@lists.infradead.org; Tue, 13 Jun 2017 05:05:18 +0000 Received: from pug.e01.socionext.com (p14092-ipngnfx01kyoto.kyoto.ocn.ne.jp [153.142.97.92]) (authenticated) by conuserg-09.nifty.com with ESMTP id v5D54ENo023096; Tue, 13 Jun 2017 14:04:26 +0900 DKIM-Filter: OpenDKIM Filter v2.10.3 conuserg-09.nifty.com v5D54ENo023096 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nifty.com; s=dec2015msa; t=1497330267; bh=cELsuhxbV/j7UdMUNSOLaDck19MHpv31SHzS/5UIp2U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=r9/I2vdj4t04XoGtMyHcxZNjQR8X53LJvgl1XjuNZVzqkt8b7yWgFlkOiL16hRvxu iTNxrWsLEBLdJilPgsNgLITyrLIBoXRH1WmYRpiNhsA2NwrtW9SUOp3L4iRMwLJ4mi vr9+CzZ1qBh+NdjHhVjkgTNlhtfmgfmrx68JXFy2fxIegZ+G3F+Xeok4bn3SHhrvh1 Tw0BCnmL77OZP+Hp++VXf+Djqtrv6JW88QFf2Aal6tpWkuxK1F5z/EIib0L2N9gMCV nua6upQpxSQ6+b7S7X9yiDcE4XMhNOLvsl9sBttD3FSHa5V4eTMXfskOKUy/J8TpMP F3S8s9WH3pdjA== X-Nifty-SrcIP: [153.142.97.92] From: Masahiro Yamada To: linux-mtd@lists.infradead.org Subject: [PATCH v6 10/18] mtd: nand: denali: propagate page to helpers via function argument Date: Tue, 13 Jun 2017 14:04:02 +0900 Message-Id: <1497330250-17348-11-git-send-email-yamada.masahiro@socionext.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1497330250-17348-1-git-send-email-yamada.masahiro@socionext.com> References: <1497330250-17348-1-git-send-email-yamada.masahiro@socionext.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170612_220516_484888_10ECB9CC X-CRM114-Status: GOOD ( 15.31 ) X-Spam-Score: -1.2 (-) X-Spam-Report: SpamAssassin version 3.4.1 on bombadil.infradead.org summary: Content analysis details: (-1.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- 0.7 SPF_SOFTFAIL SPF: sender does not match SPF record (softfail) -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Boris Brezillon , Cyrille Pitchen , Richard Weinberger , Marek Vasut , Masahiro Yamada , Artem Bityutskiy , Dinh Nguyen , linux-kernel@vger.kernel.org, Enrico Jorns , Masami Hiramatsu , Chuanxiao Dong , Jassi Brar , Brian Norris , David Woodhouse MIME-Version: 1.0 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+patch=linaro.org@lists.infradead.org This driver stores the currently addressed page into denali->page, which is later read out by helper functions. While I am tackling on this driver, I often missed to insert "denali->page = page;" where needed. This makes page_read/write callbacks to get access to a wrong page, which is a bug hard to figure out. Instead, I'd rather pass the page via function argument because the compiler's prototype checks will help to detect bugs. For the same reason, propagate dma_addr to the DMA helpers instead of denali->buf.dma_buf . Signed-off-by: Masahiro Yamada --- Changes in v6: None Changes in v5: None Changes in v4: None Changes in v3: None Changes in v2: - Newly added drivers/mtd/nand/denali.c | 58 ++++++++++++++++++++--------------------------- drivers/mtd/nand/denali.h | 1 - 2 files changed, 24 insertions(+), 35 deletions(-) -- 2.7.4 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/ diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index 7ae2fa65d601..f2e50c5856f3 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c @@ -282,7 +282,7 @@ static int denali_dev_ready(struct mtd_info *mtd) * sends a pipeline command operation to the controller. See the Denali NAND * controller's user guide for more information (section 4.2.3.6). */ -static int denali_send_pipeline_cmd(struct denali_nand_info *denali, +static int denali_send_pipeline_cmd(struct denali_nand_info *denali, int page, bool ecc_en, bool transfer_spare, int access_type, int op) { @@ -293,7 +293,7 @@ static int denali_send_pipeline_cmd(struct denali_nand_info *denali, denali_reset_irq(denali); - addr = BANK(denali->flash_bank) | denali->page; + addr = BANK(denali->flash_bank) | page; if (op == DENALI_WRITE && access_type != SPARE_ACCESS) { cmd = MODE_01 | addr; @@ -366,9 +366,7 @@ static int write_oob_data(struct mtd_info *mtd, uint8_t *buf, int page) uint32_t irq_mask = INTR__PROGRAM_COMP | INTR__PROGRAM_FAIL; int status = 0; - denali->page = page; - - if (denali_send_pipeline_cmd(denali, false, false, SPARE_ACCESS, + if (denali_send_pipeline_cmd(denali, page, false, false, SPARE_ACCESS, DENALI_WRITE) == PASS) { write_data_to_flash_mem(denali, buf, mtd->oobsize); @@ -393,9 +391,7 @@ static void read_oob_data(struct mtd_info *mtd, uint8_t *buf, int page) uint32_t irq_mask = INTR__LOAD_COMP; uint32_t irq_status, addr, cmd; - denali->page = page; - - if (denali_send_pipeline_cmd(denali, false, true, SPARE_ACCESS, + if (denali_send_pipeline_cmd(denali, page, false, true, SPARE_ACCESS, DENALI_READ) == PASS) { read_data_from_flash_mem(denali, buf, mtd->oobsize); @@ -407,8 +403,7 @@ static void read_oob_data(struct mtd_info *mtd, uint8_t *buf, int page) irq_status = denali_wait_for_irq(denali, irq_mask); if (!(irq_status & INTR__LOAD_COMP)) - dev_err(denali->dev, "page on OOB timeout %d\n", - denali->page); + dev_err(denali->dev, "page on OOB timeout %d\n", page); /* * We set the device back to MAIN_ACCESS here as I observed @@ -417,7 +412,7 @@ static void read_oob_data(struct mtd_info *mtd, uint8_t *buf, int page) * is reliable (according to the MTD test infrastructure) * if you are in MAIN_ACCESS. */ - addr = BANK(denali->flash_bank) | denali->page; + addr = BANK(denali->flash_bank) | page; cmd = MODE_10 | addr; index_addr(denali, cmd, MAIN_ACCESS); } @@ -582,13 +577,13 @@ static void denali_enable_dma(struct denali_nand_info *denali, bool en) ioread32(denali->flash_reg + DMA_ENABLE); } -static void denali_setup_dma64(struct denali_nand_info *denali, int op) +static void denali_setup_dma64(struct denali_nand_info *denali, + dma_addr_t dma_addr, int page, int op) { uint32_t mode; const int page_count = 1; - uint64_t addr = denali->buf.dma_buf; - mode = MODE_10 | BANK(denali->flash_bank) | denali->page; + mode = MODE_10 | BANK(denali->flash_bank) | page; /* DMA is a three step process */ @@ -599,41 +594,42 @@ static void denali_setup_dma64(struct denali_nand_info *denali, int op) index_addr(denali, mode, 0x01002000 | (64 << 16) | op | page_count); /* 2. set memory low address */ - index_addr(denali, mode, addr); + index_addr(denali, mode, dma_addr); /* 3. set memory high address */ - index_addr(denali, mode, addr >> 32); + index_addr(denali, mode, (uint64_t)dma_addr >> 32); } -static void denali_setup_dma32(struct denali_nand_info *denali, int op) +static void denali_setup_dma32(struct denali_nand_info *denali, + dma_addr_t dma_addr, int page, int op) { uint32_t mode; const int page_count = 1; - uint32_t addr = denali->buf.dma_buf; mode = MODE_10 | BANK(denali->flash_bank); /* DMA is a four step process */ /* 1. setup transfer type and # of pages */ - index_addr(denali, mode | denali->page, 0x2000 | op | page_count); + index_addr(denali, mode | page, 0x2000 | op | page_count); /* 2. set memory high address bits 23:8 */ - index_addr(denali, mode | ((addr >> 16) << 8), 0x2200); + index_addr(denali, mode | ((dma_addr >> 16) << 8), 0x2200); /* 3. set memory low address bits 23:8 */ - index_addr(denali, mode | ((addr & 0xffff) << 8), 0x2300); + index_addr(denali, mode | ((dma_addr & 0xffff) << 8), 0x2300); /* 4. interrupt when complete, burst len = 64 bytes */ index_addr(denali, mode | 0x14000, 0x2400); } -static void denali_setup_dma(struct denali_nand_info *denali, int op) +static void denali_setup_dma(struct denali_nand_info *denali, + dma_addr_t dma_addr, int page, int op) { if (denali->caps & DENALI_CAP_DMA_64BIT) - denali_setup_dma64(denali, op); + denali_setup_dma64(denali, dma_addr, page, op); else - denali_setup_dma32(denali, op); + denali_setup_dma32(denali, dma_addr, page, op); } /* @@ -650,8 +646,6 @@ static int write_page(struct mtd_info *mtd, struct nand_chip *chip, uint32_t irq_mask = INTR__DMA_CMD_COMP | INTR__PROGRAM_FAIL; int ret = 0; - denali->page = page; - /* * if it is a raw xfer, we want to disable ecc and send the spare area. * !raw_xfer - enable ecc @@ -674,7 +668,7 @@ static int write_page(struct mtd_info *mtd, struct nand_chip *chip, denali_reset_irq(denali); denali_enable_dma(denali, true); - denali_setup_dma(denali, DENALI_WRITE); + denali_setup_dma(denali, addr, page, DENALI_WRITE); /* wait for operation to complete */ irq_status = denali_wait_for_irq(denali, irq_mask); @@ -750,15 +744,13 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, unsigned long uncor_ecc_flags = 0; int stat = 0; - denali->page = page; - setup_ecc_for_xfer(denali, true, false); denali_enable_dma(denali, true); dma_sync_single_for_device(denali->dev, addr, size, DMA_FROM_DEVICE); denali_reset_irq(denali); - denali_setup_dma(denali, DENALI_READ); + denali_setup_dma(denali, addr, page, DENALI_READ); /* wait for operation to complete */ irq_status = denali_wait_for_irq(denali, irq_mask); @@ -777,7 +769,7 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, return stat; if (uncor_ecc_flags) { - read_oob_data(mtd, chip->oob_poi, denali->page); + read_oob_data(mtd, chip->oob_poi, page); stat = denali_check_erased_page(mtd, chip, buf, uncor_ecc_flags, stat); @@ -795,15 +787,13 @@ static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, uint32_t irq_mask = INTR__DMA_CMD_COMP; uint32_t irq_status; - denali->page = page; - setup_ecc_for_xfer(denali, false, true); denali_enable_dma(denali, true); dma_sync_single_for_device(denali->dev, addr, size, DMA_FROM_DEVICE); denali_reset_irq(denali); - denali_setup_dma(denali, DENALI_READ); + denali_setup_dma(denali, addr, page, DENALI_READ); /* wait for operation to complete */ irq_status = denali_wait_for_irq(denali, irq_mask); diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h index a84d8784ee98..ad2223d179d0 100644 --- a/drivers/mtd/nand/denali.h +++ b/drivers/mtd/nand/denali.h @@ -316,7 +316,6 @@ struct denali_nand_info { int flash_bank; /* currently selected chip */ struct nand_buf buf; struct device *dev; - int page; void __iomem *flash_reg; /* Register Interface */ void __iomem *flash_mem; /* Host Data/Command Interface */