mtd: eLBC NAND: fix subpage write support
authorPekon Gupta <pekon@ti.com>
Tue, 6 May 2014 04:11:32 +0000 (09:41 +0530)
committerBrian Norris <computersforpeace@gmail.com>
Tue, 20 May 2014 23:35:31 +0000 (16:35 -0700)
As subpage write is enabled by default for all drivers, nand_write_subpage_hwecc
causes a crash if the driver did not register ecc->hwctl or ecc->calculate.
This behavior was introduced in
   commit 837a6ba4f3b6d23026674e6af6b6849a4634fff9
   "mtd: nand: subpage write support for hardware based ECC schemes".

This fixes a crash by emulating subpage write support by padding sub-page data
with 0xff on either sides to make it full page compatible.

Reported-by: Helmut Schaa <helmut.schaa@googlemail.com>
Tested-by: Helmut Schaa <helmut.schaa@googlemail.com>
Signed-off-by: Pekon Gupta <pekon@ti.com>
Reviewed-by: Scott Wood <scottwood@freescale.com>
Cc: <stable@vger.kernel.org> # 3.10.x+
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
drivers/mtd/nand/fsl_elbc_nand.c

index ec549cd9849fbc426c598240e6fbce6fabf1cd1e..545a5c002f09a48b76bce2c873af1b3161083362 100644 (file)
@@ -723,6 +723,19 @@ static int fsl_elbc_write_page(struct mtd_info *mtd, struct nand_chip *chip,
        return 0;
 }
 
+/* ECC will be calculated automatically, and errors will be detected in
+ * waitfunc.
+ */
+static int fsl_elbc_write_subpage(struct mtd_info *mtd, struct nand_chip *chip,
+                               uint32_t offset, uint32_t data_len,
+                               const uint8_t *buf, int oob_required)
+{
+       fsl_elbc_write_buf(mtd, buf, mtd->writesize);
+       fsl_elbc_write_buf(mtd, chip->oob_poi, mtd->oobsize);
+
+       return 0;
+}
+
 static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
 {
        struct fsl_lbc_ctrl *ctrl = priv->ctrl;
@@ -761,6 +774,7 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv)
 
        chip->ecc.read_page = fsl_elbc_read_page;
        chip->ecc.write_page = fsl_elbc_write_page;
+       chip->ecc.write_subpage = fsl_elbc_write_subpage;
 
        /* If CS Base Register selects full hardware ECC then use it */
        if ((in_be32(&lbc->bank[priv->bank].br) & BR_DECC) ==