From patchwork Thu Nov 14 21:25:36 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ezequiel Garcia X-Patchwork-Id: 3185741 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id E6D959F39E for ; Thu, 14 Nov 2013 22:31:21 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id BA8A9201F9 for ; Thu, 14 Nov 2013 22:31:20 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B994A201EF for ; Thu, 14 Nov 2013 22:31:19 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Vh4UK-0006Tx-EZ; Thu, 14 Nov 2013 21:30:09 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Vh4T8-00057G-Bt; Thu, 14 Nov 2013 21:28:54 +0000 Received: from top.free-electrons.com ([176.31.233.9] helo=mail.free-electrons.com) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Vh4Qr-0004qr-Qj; Thu, 14 Nov 2013 21:26:44 +0000 Received: by mail.free-electrons.com (Postfix, from userid 106) id 393FF824; Thu, 14 Nov 2013 22:26:19 +0100 (CET) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from localhost.localdomain (unknown [190.2.98.212]) by mail.free-electrons.com (Postfix) with ESMTPA id 635DB823; Thu, 14 Nov 2013 22:26:16 +0100 (CET) From: Ezequiel Garcia To: , Subject: [PATCH v5 11/14] mtd: nand: pxa3xx: Add a read/write buffers markers Date: Thu, 14 Nov 2013 18:25:36 -0300 Message-Id: <1384464339-6817-12-git-send-email-ezequiel.garcia@free-electrons.com> X-Mailer: git-send-email 1.8.1.5 In-Reply-To: <1384464339-6817-1-git-send-email-ezequiel.garcia@free-electrons.com> References: <1384464339-6817-1-git-send-email-ezequiel.garcia@free-electrons.com> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20131114_162634_690404_030C39BA X-CRM114-Status: GOOD ( 11.23 ) X-Spam-Score: -1.2 (-) Cc: Lior Amsalem , Thomas Petazzoni , Brian Norris , Gregory Clement , Ezequiel Garcia X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP In preparation to support multiple (aka chunked, aka splitted) page I/O, this commit adds 'data_buff_pos' and 'oob_buff_pos' fields to keep track of where the next read (or write) should be done. This will allow multiple calls to handle_data_pio() to continue the read (or write) operation. Signed-off-by: Ezequiel Garcia --- drivers/mtd/nand/pxa3xx_nand.c | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index d15aee6..8e16eeb 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -176,6 +176,8 @@ struct pxa3xx_nand_info { unsigned int buf_start; unsigned int buf_count; unsigned int buf_size; + unsigned int data_buff_pos; + unsigned int oob_buff_pos; /* DMA information */ int drcmr_dat; @@ -338,11 +340,12 @@ static void pxa3xx_nand_set_timing(struct pxa3xx_nand_host *host, * spare and ECC configuration. * Only applicable to READ0, READOOB and PAGEPROG commands. */ -static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info) +static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info, + struct mtd_info *mtd) { int oob_enable = info->reg_ndcr & NDCR_SPARE_EN; - info->data_size = info->fifo_size; + info->data_size = mtd->writesize; if (!oob_enable) return; @@ -430,26 +433,39 @@ static void disable_int(struct pxa3xx_nand_info *info, uint32_t int_mask) static void handle_data_pio(struct pxa3xx_nand_info *info) { + unsigned int do_bytes = min(info->data_size, info->fifo_size); + switch (info->state) { case STATE_PIO_WRITING: - __raw_writesl(info->mmio_base + NDDB, info->data_buff, - DIV_ROUND_UP(info->data_size, 4)); + __raw_writesl(info->mmio_base + NDDB, + info->data_buff + info->data_buff_pos, + DIV_ROUND_UP(do_bytes, 4)); + if (info->oob_size > 0) - __raw_writesl(info->mmio_base + NDDB, info->oob_buff, - DIV_ROUND_UP(info->oob_size, 4)); + __raw_writesl(info->mmio_base + NDDB, + info->oob_buff + info->oob_buff_pos, + DIV_ROUND_UP(info->oob_size, 4)); break; case STATE_PIO_READING: - __raw_readsl(info->mmio_base + NDDB, info->data_buff, - DIV_ROUND_UP(info->data_size, 4)); + __raw_readsl(info->mmio_base + NDDB, + info->data_buff + info->data_buff_pos, + DIV_ROUND_UP(do_bytes, 4)); + if (info->oob_size > 0) - __raw_readsl(info->mmio_base + NDDB, info->oob_buff, - DIV_ROUND_UP(info->oob_size, 4)); + __raw_readsl(info->mmio_base + NDDB, + info->oob_buff + info->oob_buff_pos, + DIV_ROUND_UP(info->oob_size, 4)); break; default: dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__, info->state); BUG(); } + + /* Update buffer pointers for multi-page read/write */ + info->data_buff_pos += do_bytes; + info->oob_buff_pos += info->oob_size; + info->data_size -= do_bytes; } #ifdef ARCH_HAS_DMA @@ -616,6 +632,8 @@ static void prepare_start_command(struct pxa3xx_nand_info *info, int command) info->buf_start = 0; info->buf_count = 0; info->oob_size = 0; + info->data_buff_pos = 0; + info->oob_buff_pos = 0; info->use_ecc = 0; info->use_spare = 1; info->retcode = ERR_NONE; @@ -626,7 +644,7 @@ static void prepare_start_command(struct pxa3xx_nand_info *info, int command) case NAND_CMD_PAGEPROG: info->use_ecc = 1; case NAND_CMD_READOOB: - pxa3xx_set_datasize(info); + pxa3xx_set_datasize(info, mtd); break; case NAND_CMD_PARAM: info->use_spare = 0;