diff options
Diffstat (limited to 'drivers/mtd/nand')
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 27 | ||||
-rw-r--r-- | drivers/mtd/nand/pxa3xx_nand.c | 14 |
2 files changed, 25 insertions, 16 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index a46e9bb847b..86f05f45780 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2097,14 +2097,22 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, /** * nand_fill_oob - [Internal] Transfer client buffer to oob - * @chip: nand chip structure + * @mtd: MTD device structure * @oob: oob data buffer * @len: oob data write length * @ops: oob ops structure */ -static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob, size_t len, - struct mtd_oob_ops *ops) +static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len, + struct mtd_oob_ops *ops) { + struct nand_chip *chip = mtd->priv; + + /* + * Initialise to all 0xFF, to avoid the possibility of left over OOB + * data from a previous OOB read. + */ + memset(chip->oob_poi, 0xff, mtd->oobsize); + switch (ops->mode) { case MTD_OOB_PLACE: @@ -2201,10 +2209,6 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, (chip->pagebuf << chip->page_shift) < (to + ops->len)) chip->pagebuf = -1; - /* If we're not given explicit OOB data, let it be 0xFF */ - if (likely(!oob)) - memset(chip->oob_poi, 0xff, mtd->oobsize); - /* Don't allow multipage oob writes with offset */ if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen)) return -EINVAL; @@ -2226,8 +2230,11 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, if (unlikely(oob)) { size_t len = min(oobwritelen, oobmaxlen); - oob = nand_fill_oob(chip, oob, len, ops); + oob = nand_fill_oob(mtd, oob, len, ops); oobwritelen -= len; + } else { + /* We still need to erase leftover OOB data */ + memset(chip->oob_poi, 0xff, mtd->oobsize); } ret = chip->write_page(mtd, chip, wbuf, page, cached, @@ -2401,10 +2408,8 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, if (page == chip->pagebuf) chip->pagebuf = -1; - memset(chip->oob_poi, 0xff, mtd->oobsize); - nand_fill_oob(chip, ops->oobbuf, ops->ooblen, ops); + nand_fill_oob(mtd, ops->oobbuf, ops->ooblen, ops); status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask); - memset(chip->oob_poi, 0xff, mtd->oobsize); if (status) return status; diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 1fb3b3a8058..30689cc2b3c 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c @@ -685,6 +685,8 @@ static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd, * OOB, ignore such double bit errors */ if (is_buf_blank(buf, mtd->writesize)) + info->retcode = ERR_NONE; + else mtd->ecc_stats.failed++; } @@ -813,7 +815,7 @@ static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info) info->page_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512; /* set info fields needed to read id */ info->read_id_bytes = (info->page_size == 2048) ? 4 : 2; - info->reg_ndcr = ndcr; + info->reg_ndcr = ndcr & ~NDCR_INT_MASK; info->cmdset = &default_cmdset; info->ndtr0cs0 = nand_readl(info, NDTR0CS0); @@ -882,7 +884,7 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) struct pxa3xx_nand_info *info = mtd->priv; struct platform_device *pdev = info->pdev; struct pxa3xx_nand_platform_data *pdata = pdev->dev.platform_data; - struct nand_flash_dev pxa3xx_flash_ids[2] = { {NULL,}, {NULL,} }; + struct nand_flash_dev pxa3xx_flash_ids[2], *def = NULL; const struct pxa3xx_nand_flash *f = NULL; struct nand_chip *chip = mtd->priv; uint32_t id = -1; @@ -942,8 +944,10 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) pxa3xx_flash_ids[0].erasesize = f->page_size * f->page_per_block; if (f->flash_width == 16) pxa3xx_flash_ids[0].options = NAND_BUSWIDTH_16; + pxa3xx_flash_ids[1].name = NULL; + def = pxa3xx_flash_ids; KEEP_CONFIG: - if (nand_scan_ident(mtd, 1, pxa3xx_flash_ids)) + if (nand_scan_ident(mtd, 1, def)) return -ENODEV; /* calculate addressing information */ info->col_addr_cycles = (mtd->writesize >= 2048) ? 2 : 1; @@ -954,9 +958,9 @@ KEEP_CONFIG: info->row_addr_cycles = 2; mtd->name = mtd_names[0]; chip->ecc.mode = NAND_ECC_HW; - chip->ecc.size = f->page_size; + chip->ecc.size = info->page_size; - chip->options = (f->flash_width == 16) ? NAND_BUSWIDTH_16 : 0; + chip->options = (info->reg_ndcr & NDCR_DWIDTH_M) ? NAND_BUSWIDTH_16 : 0; chip->options |= NAND_NO_AUTOINCR; chip->options |= NAND_NO_READRDY; |