From: Bean Huo <beanhuo@xxxxxxxxxx> Add {pre,post}_erase hooks in the structure nand_chip_ops: pre_erase will be called before a block is physically erased. post_erase will be called after a block is erased. Signed-off-by: Bean Huo <beanhuo@xxxxxxxxxx> --- drivers/mtd/nand/raw/nand_base.c | 18 +++++++++++++----- include/linux/mtd/rawnand.h | 16 ++++++++++------ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 7af21cf49290..e90b7ae878e2 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4318,7 +4318,7 @@ static int nand_erase(struct mtd_info *mtd, struct erase_info *instr) int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr, int allowbbt) { - int page, pages_per_block, ret, chipnr; + int page, pages_per_block, ret, chipnr, eb; loff_t len; pr_debug("%s: start = 0x%012llx, len = %llu\n", @@ -4372,16 +4372,24 @@ int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr, (page + pages_per_block)) chip->pagecache.page = -1; - ret = nand_erase_op(chip, (page & chip->pagemask) >> - (chip->phys_erase_shift - chip->page_shift)); + eb = (page & chip->pagemask) >> + (chip->phys_erase_shift - chip->page_shift); + + if (chip->ops.pre_erase) + chip->ops.pre_erase(chip, eb); + + ret = nand_erase_op(chip, eb); if (ret) { - pr_debug("%s: failed erase, page 0x%08x\n", - __func__, page); + pr_debug("%s: failed erase block %d, page 0x%08x\n", + __func__, eb, page); instr->fail_addr = ((loff_t)page << chip->page_shift); goto erase_exit; } + if (chip->ops.post_erase) + chip->ops.post_erase(chip, eb); + /* Increment page address and decrement length */ len -= (1ULL << chip->phys_erase_shift); page += pages_per_block; diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index 62932cc3ed8d..df3d4b3ef2f6 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -1027,12 +1027,14 @@ struct nand_legacy { /** * struct nand_chip_ops - NAND Chip specific operations - * @suspend: [REPLACEABLE] specific NAND device suspend operation - * @resume: [REPLACEABLE] specific NAND device resume operation - * @lock_area: [REPLACEABLE] specific NAND chip lock operation - * @unlock_area: [REPLACEABLE] specific NAND chip unlock operation - * @setup_read_retry: [FLASHSPECIFIC] flash (vendor) specific function for - * setting the read-retry mode. Mostly needed for MLC NAND. + * @suspend: [REPLACEABLE] specific NAND device suspend operation + * @resume: [REPLACEABLE] specific NAND device resume operation + * @lock_area: [REPLACEABLE] specific NAND chip lock operation + * @unlock_area: [REPLACEABLE] specific NAND chip unlock operation + * @setup_read_retry: [FLASHSPECIFIC] flash (vendor) specific function for + * setting the read-retry mode. Mostly needed for MLC NAND. + * @pre_erase: [FLASHSPECIFIC] prepare a physical erase block + * @post_erase: [FLASHSPECIFIC] physical block erase post */ struct nand_chip_ops { int (*suspend)(struct nand_chip *chip); @@ -1040,6 +1042,8 @@ struct nand_chip_ops { int (*lock_area)(struct nand_chip *chip, loff_t ofs, u64 len); int (*unlock_area)(struct nand_chip *chip, loff_t ofs, u64 len); int (*setup_read_retry)(struct nand_chip *chip, int retry_mode); + int (*pre_erase)(struct nand_chip *chip, u32 eraseblock); + int (*post_erase)(struct nand_chip *chip, u32 eraseblock); }; /** -- 2.17.1 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/