mtd: gpmi: rewrite the gpmi_ecc_write_oob() to support the jffs2
authorHuang Shijie <b32955@freescale.com>
Wed, 25 Sep 2013 06:58:15 +0000 (14:58 +0800)
committerBrian Norris <computersforpeace@gmail.com>
Sun, 27 Oct 2013 23:27:06 +0000 (16:27 -0700)
When we use the ECC info which is get from the nand chip's datasheet,
we may have some freed oob area now.

This patch rewrites the gpmi_ecc_write_oob() to implement the ecc.write_oob().
We also update the comment for gpmi_hw_ecclayout.

Yes! We can support the JFFS2 for the SLC nand now.

Signed-off-by: Huang Shijie <b32955@freescale.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
drivers/mtd/nand/gpmi-nand/gpmi-nand.c

index 10a092dbaa71b648a812f1dbae5f0a1afb27c2a0..37508eb350d05864e5f25b0a693824912eef0b1e 100644 (file)
@@ -45,7 +45,10 @@ static struct nand_bbt_descr gpmi_bbt_descr = {
        .pattern        = scan_ff_pattern
 };
 
-/*  We will use all the (page + OOB). */
+/*
+ * We may change the layout if we can get the ECC info from the datasheet,
+ * else we will use all the (page + OOB).
+ */
 static struct nand_ecclayout gpmi_hw_ecclayout = {
        .eccbytes = 0,
        .eccpos = { 0, },
@@ -1263,14 +1266,22 @@ static int gpmi_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
 static int
 gpmi_ecc_write_oob(struct mtd_info *mtd, struct nand_chip *chip, int page)
 {
-       /*
-        * The BCH will use all the (page + oob).
-        * Our gpmi_hw_ecclayout can only prohibit the JFFS2 to write the oob.
-        * But it can not stop some ioctls such MEMWRITEOOB which uses
-        * MTD_OPS_PLACE_OOB. So We have to implement this function to prohibit
-        * these ioctls too.
-        */
-       return -EPERM;
+       struct nand_oobfree *of = mtd->ecclayout->oobfree;
+       int status = 0;
+
+       /* Do we have available oob area? */
+       if (!of->length)
+               return -EPERM;
+
+       if (!nand_is_slc(chip))
+               return -EPERM;
+
+       chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize + of->offset, page);
+       chip->write_buf(mtd, chip->oob_poi + of->offset, of->length);
+       chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
+
+       status = chip->waitfunc(mtd, chip);
+       return status & NAND_STATUS_FAIL ? -EIO : 0;
 }
 
 static int gpmi_block_markbad(struct mtd_info *mtd, loff_t ofs)