mtd: nand: pxa3xx: Add a read/write buffers markers
authorEzequiel Garcia <ezequiel.garcia@free-electrons.com>
Thu, 14 Nov 2013 21:25:36 +0000 (18:25 -0300)
committerBrian Norris <computersforpeace@gmail.com>
Fri, 3 Jan 2014 19:22:17 +0000 (11:22 -0800)
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 <ezequiel.garcia@free-electrons.com>
Tested-by: Daniel Mack <zonque@gmail.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
drivers/mtd/nand/pxa3xx_nand.c

index 579347b..c17c285 100644 (file)
@@ -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;
@@ -334,11 +336,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;
 
@@ -426,26 +429,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
@@ -612,6 +628,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;
@@ -622,7 +640,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;