mtd: nand: lpc32xx: switch to mtd_ooblayout_ops
authorBoris Brezillon <boris.brezillon@free-electrons.com>
Wed, 3 Feb 2016 19:02:41 +0000 (20:02 +0100)
committerBoris Brezillon <boris.brezillon@free-electrons.com>
Thu, 5 May 2016 21:51:45 +0000 (23:51 +0200)
Implementing the mtd_ooblayout_ops interface is the new way of exposing
ECC/OOB layout to MTD users.

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

index 8e439787b04e7f33e3f38b90ab3a664ce8d41b73..852388171f2033320e7cba102c3be24d312c0f03 100644 (file)
@@ -138,22 +138,37 @@ struct lpc32xx_nand_cfg_mlc {
        unsigned num_parts;
 };
 
-static struct nand_ecclayout lpc32xx_nand_oob = {
-       .eccbytes = 40,
-       .eccpos = { 6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
-                  22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
-                  38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
-                  54, 55, 56, 57, 58, 59, 60, 61, 62, 63 },
-       .oobfree = {
-               { .offset = 0,
-                 .length = 6, },
-               { .offset = 16,
-                 .length = 6, },
-               { .offset = 32,
-                 .length = 6, },
-               { .offset = 48,
-                 .length = 6, },
-               },
+static int lpc32xx_ooblayout_ecc(struct mtd_info *mtd, int section,
+                                struct mtd_oob_region *oobregion)
+{
+       struct nand_chip *nand_chip = mtd_to_nand(mtd);
+
+       if (section >= nand_chip->ecc.steps)
+               return -ERANGE;
+
+       oobregion->offset = ((section + 1) * 16) - nand_chip->ecc.bytes;
+       oobregion->length = nand_chip->ecc.bytes;
+
+       return 0;
+}
+
+static int lpc32xx_ooblayout_free(struct mtd_info *mtd, int section,
+                                 struct mtd_oob_region *oobregion)
+{
+       struct nand_chip *nand_chip = mtd_to_nand(mtd);
+
+       if (section >= nand_chip->ecc.steps)
+               return -ERANGE;
+
+       oobregion->offset = 16 * section;
+       oobregion->length = 16 - nand_chip->ecc.bytes;
+
+       return 0;
+}
+
+static const struct mtd_ooblayout_ops lpc32xx_ooblayout_ops = {
+       .ecc = lpc32xx_ooblayout_ecc,
+       .free = lpc32xx_ooblayout_free,
 };
 
 static struct nand_bbt_descr lpc32xx_nand_bbt = {
@@ -712,6 +727,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
        nand_chip->ecc.write_oob = lpc32xx_write_oob;
        nand_chip->ecc.read_oob = lpc32xx_read_oob;
        nand_chip->ecc.strength = 4;
+       nand_chip->ecc.bytes = 10;
        nand_chip->waitfunc = lpc32xx_waitfunc;
 
        nand_chip->options = NAND_NO_SUBPAGE_WRITE;
@@ -750,7 +766,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
 
        nand_chip->ecc.mode = NAND_ECC_HW;
        nand_chip->ecc.size = 512;
-       nand_chip->ecc.layout = &lpc32xx_nand_oob;
+       mtd_set_ooblayout(mtd, &lpc32xx_ooblayout_ops);
        host->mlcsubpages = mtd->writesize / 512;
 
        /* initially clear interrupt status */
index 10cf8e6223bce2b94ec06ab3dfb83e44f3545147..219dd674dc92a52c98fc7d5a7b6293ba3befaa34 100644 (file)
  * NAND ECC Layout for small page NAND devices
  * Note: For large and huge page devices, the default layouts are used
  */
-static struct nand_ecclayout lpc32xx_nand_oob_16 = {
-       .eccbytes = 6,
-       .eccpos = {10, 11, 12, 13, 14, 15},
-       .oobfree = {
-               { .offset = 0, .length = 4 },
-               { .offset = 6, .length = 4 },
-       },
+static int lpc32xx_ooblayout_ecc(struct mtd_info *mtd, int section,
+                                struct mtd_oob_region *oobregion)
+{
+       if (section)
+               return -ERANGE;
+
+       oobregion->length = 6;
+       oobregion->offset = 10;
+
+       return 0;
+}
+
+static int lpc32xx_ooblayout_free(struct mtd_info *mtd, int section,
+                                 struct mtd_oob_region *oobregion)
+{
+       if (section > 1)
+               return -ERANGE;
+
+       if (!section) {
+               oobregion->offset = 0;
+               oobregion->length = 4;
+       } else {
+               oobregion->offset = 6;
+               oobregion->length = 4;
+       }
+
+       return 0;
+}
+
+static const struct mtd_ooblayout_ops lpc32xx_ooblayout_ops = {
+       .ecc = lpc32xx_ooblayout_ecc,
+       .free = lpc32xx_ooblayout_free,
 };
 
 static u8 bbt_pattern[] = {'B', 'b', 't', '0' };
@@ -886,7 +911,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev)
         * custom BBT marker layout.
         */
        if (mtd->writesize <= 512)
-               chip->ecc.layout = &lpc32xx_nand_oob_16;
+               mtd_set_ooblayout(mtd, &lpc32xx_ooblayout_ops);
 
        /* These sizes remain the same regardless of page size */
        chip->ecc.size = 256;