}
 EXPORT_SYMBOL_GPL(nanddev_mtd_erase);
 
+/**
+ * nanddev_mtd_max_bad_blocks() - Get the maximum number of bad eraseblock on
+ *                               a specific region of the NAND device
+ * @mtd: MTD device
+ * @offs: offset of the NAND region
+ * @len: length of the NAND region
+ *
+ * Default implementation for mtd->_max_bad_blocks(). Only works if
+ * nand->memorg.max_bad_eraseblocks_per_lun is > 0.
+ *
+ * Return: a positive number encoding the maximum number of eraseblocks on a
+ * portion of memory, a negative error code otherwise.
+ */
+int nanddev_mtd_max_bad_blocks(struct mtd_info *mtd, loff_t offs, size_t len)
+{
+       struct nand_device *nand = mtd_to_nanddev(mtd);
+       struct nand_pos pos, end;
+       unsigned int max_bb = 0;
+
+       if (!nand->memorg.max_bad_eraseblocks_per_lun)
+               return -ENOTSUPP;
+
+       nanddev_offs_to_pos(nand, offs, &pos);
+       nanddev_offs_to_pos(nand, offs + len, &end);
+
+       for (nanddev_offs_to_pos(nand, offs, &pos);
+            nanddev_pos_cmp(&pos, &end) < 0;
+            nanddev_pos_next_lun(nand, &pos))
+               max_bb += nand->memorg.max_bad_eraseblocks_per_lun;
+
+       return max_bb;
+}
+EXPORT_SYMBOL_GPL(nanddev_mtd_max_bad_blocks);
+
 /**
  * nanddev_init() - Initialize a NAND device
  * @nand: NAND device
 
 
 static const struct spinand_info gigadevice_spinand_table[] = {
        SPINAND_INFO("GD5F1GQ4xA", 0xF1,
-                    NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
+                    NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
                     NAND_ECCREQ(8, 512),
                     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
                                              &write_cache_variants,
                     SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
                                     gd5fxgq4xa_ecc_get_status)),
        SPINAND_INFO("GD5F2GQ4xA", 0xF2,
-                    NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1),
+                    NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1),
                     NAND_ECCREQ(8, 512),
                     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
                                              &write_cache_variants,
                     SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
                                     gd5fxgq4xa_ecc_get_status)),
        SPINAND_INFO("GD5F4GQ4xA", 0xF4,
-                    NAND_MEMORG(1, 2048, 64, 64, 4096, 1, 1, 1),
+                    NAND_MEMORG(1, 2048, 64, 64, 4096, 40, 1, 1, 1),
                     NAND_ECCREQ(8, 512),
                     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
                                              &write_cache_variants,
                     SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout,
                                     gd5fxgq4xa_ecc_get_status)),
        SPINAND_INFO("GD5F1GQ4UExxG", 0xd1,
-                    NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
+                    NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
                     NAND_ECCREQ(8, 512),
                     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
                                              &write_cache_variants,
 
 
 static const struct spinand_info macronix_spinand_table[] = {
        SPINAND_INFO("MX35LF1GE4AB", 0x12,
-                    NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
+                    NAND_MEMORG(1, 2048, 64, 64, 1024, 40, 1, 1, 1),
                     NAND_ECCREQ(4, 512),
                     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
                                              &write_cache_variants,
                     SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout,
                                     mx35lf1ge4ab_ecc_get_status)),
        SPINAND_INFO("MX35LF2GE4AB", 0x22,
-                    NAND_MEMORG(1, 2048, 64, 64, 2048, 2, 1, 1),
+                    NAND_MEMORG(1, 2048, 64, 64, 2048, 20, 2, 1, 1),
                     NAND_ECCREQ(4, 512),
                     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
                                              &write_cache_variants,
 
 
 static const struct spinand_info micron_spinand_table[] = {
        SPINAND_INFO("MT29F2G01ABAGD", 0x24,
-                    NAND_MEMORG(1, 2048, 128, 64, 2048, 2, 1, 1),
+                    NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1),
                     NAND_ECCREQ(8, 512),
                     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
                                              &write_cache_variants,
 
 static const struct spinand_info toshiba_spinand_table[] = {
        /* 3.3V 1Gb */
        SPINAND_INFO("TC58CVG0S3", 0xC2,
-                    NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
+                    NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
                     NAND_ECCREQ(8, 512),
                     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
                                              &write_cache_variants,
                                     tc58cxgxsx_ecc_get_status)),
        /* 3.3V 2Gb */
        SPINAND_INFO("TC58CVG1S3", 0xCB,
-                    NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
+                    NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
                     NAND_ECCREQ(8, 512),
                     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
                                              &write_cache_variants,
                                     tc58cxgxsx_ecc_get_status)),
        /* 3.3V 4Gb */
        SPINAND_INFO("TC58CVG2S0", 0xCD,
-                    NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
+                    NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
                     NAND_ECCREQ(8, 512),
                     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
                                              &write_cache_variants,
                                     tc58cxgxsx_ecc_get_status)),
        /* 1.8V 1Gb */
        SPINAND_INFO("TC58CYG0S3", 0xB2,
-                    NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1),
+                    NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1),
                     NAND_ECCREQ(8, 512),
                     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
                                              &write_cache_variants,
                                     tc58cxgxsx_ecc_get_status)),
        /* 1.8V 2Gb */
        SPINAND_INFO("TC58CYG1S3", 0xBB,
-                    NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1),
+                    NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
                     NAND_ECCREQ(8, 512),
                     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
                                              &write_cache_variants,
                                     tc58cxgxsx_ecc_get_status)),
        /* 1.8V 4Gb */
        SPINAND_INFO("TC58CYG2S0", 0xBD,
-                    NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1),
+                    NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1),
                     NAND_ECCREQ(8, 512),
                     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
                                              &write_cache_variants,
 
 
 static const struct spinand_info winbond_spinand_table[] = {
        SPINAND_INFO("W25M02GV", 0xAB,
-                    NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 2),
+                    NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 2),
                     NAND_ECCREQ(1, 512),
                     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
                                              &write_cache_variants,
                     SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL),
                     SPINAND_SELECT_TARGET(w25m02gv_select_target)),
        SPINAND_INFO("W25N01GV", 0xAA,
-                    NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1),
+                    NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1),
                     NAND_ECCREQ(1, 512),
                     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
                                              &write_cache_variants,
 
  * @oobsize: OOB area size
  * @pages_per_eraseblock: number of pages per eraseblock
  * @eraseblocks_per_lun: number of eraseblocks per LUN (Logical Unit Number)
+ * @max_bad_eraseblocks_per_lun: maximum number of eraseblocks per LUN
  * @planes_per_lun: number of planes per LUN
  * @luns_per_target: number of LUN per target (target is a synonym for die)
  * @ntargets: total number of targets exposed by the NAND device
        unsigned int oobsize;
        unsigned int pages_per_eraseblock;
        unsigned int eraseblocks_per_lun;
+       unsigned int max_bad_eraseblocks_per_lun;
        unsigned int planes_per_lun;
        unsigned int luns_per_target;
        unsigned int ntargets;
 };
 
-#define NAND_MEMORG(bpc, ps, os, ppe, epl, ppl, lpt, nt)       \
+#define NAND_MEMORG(bpc, ps, os, ppe, epl, mbb, ppl, lpt, nt)  \
        {                                                       \
                .bits_per_cell = (bpc),                         \
                .pagesize = (ps),                               \
                .oobsize = (os),                                \
                .pages_per_eraseblock = (ppe),                  \
                .eraseblocks_per_lun = (epl),                   \
+               .max_bad_eraseblocks_per_lun = (mbb),           \
                .planes_per_lun = (ppl),                        \
                .luns_per_target = (lpt),                       \
                .ntargets = (nt),                               \
 
 /* MTD -> NAND helper functions. */
 int nanddev_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo);
+int nanddev_mtd_max_bad_blocks(struct mtd_info *mtd, loff_t offs, size_t len);
 
 #endif /* __LINUX_MTD_NAND_H */