mtd: nand: sunxi: make OOB retrieval optional
authorBoris Brezillon <boris.brezillon@free-electrons.com>
Fri, 4 Mar 2016 17:09:21 +0000 (18:09 +0100)
committerBoris Brezillon <boris.brezillon@free-electrons.com>
Tue, 19 Apr 2016 20:05:46 +0000 (22:05 +0200)
sunxi_nfc_hw_ecc_read_chunk() always retrieves the ECC and protected free
bytes, no matter if the user really asked for it or not. This can take a
non negligible amount of time, especially on NAND chips exposing large OOB
areas (> 1KB). Make it optional.

Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
drivers/mtd/nand/sunxi_nand.c

index c20bf59..b710532 100644 (file)
@@ -868,7 +868,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd,
                                       u8 *oob, int oob_off,
                                       int *cur_off,
                                       unsigned int *max_bitflips,
-                                      bool bbm, int page)
+                                      bool bbm, bool oob_required, int page)
 {
        struct nand_chip *nand = mtd_to_nand(mtd);
        struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
@@ -900,7 +900,8 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd,
 
        *cur_off = oob_off + ecc->bytes + 4;
 
-       ret = sunxi_nfc_hw_ecc_correct(mtd, data, oob, 0, &erased);
+       ret = sunxi_nfc_hw_ecc_correct(mtd, data, oob_required ? oob : NULL, 0,
+                                      &erased);
        if (erased)
                return 1;
 
@@ -928,12 +929,14 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd,
        } else {
                memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size);
 
-               nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
-               sunxi_nfc_randomizer_read_buf(mtd, oob, ecc->bytes + 4,
-                                             true, page);
+               if (oob_required) {
+                       nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
+                       sunxi_nfc_randomizer_read_buf(mtd, oob, ecc->bytes + 4,
+                                                     true, page);
 
-               sunxi_nfc_hw_ecc_get_prot_oob_bytes(mtd, oob, 0,
-                                                   bbm, page);
+                       sunxi_nfc_hw_ecc_get_prot_oob_bytes(mtd, oob, 0,
+                                                           bbm, page);
+               }
        }
 
        sunxi_nfc_hw_ecc_update_stats(mtd, max_bitflips, ret);
@@ -1047,7 +1050,7 @@ static int sunxi_nfc_hw_ecc_read_page(struct mtd_info *mtd,
                ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
                                                  oob_off + mtd->writesize,
                                                  &cur_off, &max_bitflips,
-                                                 !i, page);
+                                                 !i, oob_required, page);
                if (ret < 0)
                        return ret;
                else if (ret)
@@ -1085,8 +1088,8 @@ static int sunxi_nfc_hw_ecc_read_subpage(struct mtd_info *mtd,
                ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off,
                                                  oob,
                                                  oob_off + mtd->writesize,
-                                                 &cur_off, &max_bitflips,
-                                                 !i, page);
+                                                 &cur_off, &max_bitflips, !i,
+                                                 false, page);
                if (ret < 0)
                        return ret;
        }
@@ -1148,7 +1151,9 @@ static int sunxi_nfc_hw_syndrome_ecc_read_page(struct mtd_info *mtd,
 
                ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
                                                  oob_off, &cur_off,
-                                                 &max_bitflips, !i, page);
+                                                 &max_bitflips, !i,
+                                                 oob_required,
+                                                 page);
                if (ret < 0)
                        return ret;
                else if (ret)