{
        struct nand_chip *chip = &denali->nand;
        struct mtd_info *mtd = nand_to_mtd(chip);
+       struct nand_memory_organization *memorg;
+
+       memorg = nanddev_get_memorg(&chip->base);
 
        /*
         * Support for multi device:
        }
 
        /* 2 chips in parallel */
+       memorg->pagesize <<= 1;
+       memorg->oobsize <<= 1;
        mtd->size <<= 1;
        mtd->erasesize <<= 1;
        mtd->writesize <<= 1;
 
 {
        struct nand_chip *this = mtd_to_nand(mtd);
        struct doc_priv *doc = nand_get_controller_data(this);
+       struct nand_memory_organization *memorg;
        int ret = 0;
        u_char *buf;
        struct NFTLMediaHeader *mh;
        unsigned blocks, maxblocks;
        int offs, numheaders;
 
+       memorg = nanddev_get_memorg(&this->base);
+
        buf = kmalloc(mtd->writesize, GFP_KERNEL);
        if (!buf) {
                return 0;
           implementation of the NAND layer.  */
        if (mh->UnitSizeFactor != 0xff) {
                this->bbt_erase_shift += (0xff - mh->UnitSizeFactor);
+               memorg->pages_per_eraseblock <<= (0xff - mh->UnitSizeFactor);
                mtd->erasesize <<= (0xff - mh->UnitSizeFactor);
                pr_info("Setting virtual erase size to %d\n", mtd->erasesize);
                blocks = mtd->size >> this->bbt_erase_shift;
 
        uint32_t ctrl;
        struct nand_chip *chip = &nand->chip;
        struct mtd_info *mtd = nand_to_mtd(chip);
+       struct nand_memory_organization *memorg;
        u8 id[2];
 
+       memorg = nanddev_get_memorg(&chip->base);
+
        /* Request I/O resource. */
        sprintf(res_name, "bank%d", bank);
        ret = jz_nand_ioremap_resource(pdev, res_name,
 
                /* Update size of the MTD. */
                chip->numchips++;
+               memorg->ntargets++;
                mtd->size += chip->chipsize;
        }
 
 
 static void amd_nand_decode_id(struct nand_chip *chip)
 {
        struct mtd_info *mtd = nand_to_mtd(chip);
+       struct nand_memory_organization *memorg;
+
+       memorg = nanddev_get_memorg(&chip->base);
 
        nand_decode_ext_id(chip);
 
         */
        if (chip->id.data[4] != 0x00 && chip->id.data[5] == 0x00 &&
            chip->id.data[6] == 0x00 && chip->id.data[7] == 0x00 &&
-           mtd->writesize == 512) {
-               mtd->erasesize = 128 * 1024;
-               mtd->erasesize <<= ((chip->id.data[3] & 0x03) << 1);
+           memorg->pagesize == 512) {
+               memorg->pages_per_eraseblock = 256;
+               memorg->pages_per_eraseblock <<= ((chip->id.data[3] & 0x03) << 1);
+               mtd->erasesize = memorg->pages_per_eraseblock *
+                                memorg->pagesize;
        }
 }
 
 
  */
 void nand_decode_ext_id(struct nand_chip *chip)
 {
+       struct nand_memory_organization *memorg;
        struct mtd_info *mtd = nand_to_mtd(chip);
        int extid;
        u8 *id_data = chip->id.data;
+
+       memorg = nanddev_get_memorg(&chip->base);
+
        /* The 3rd id byte holds MLC / multichip data */
+       memorg->bits_per_cell = nand_get_bits_per_cell(id_data[2]);
        chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]);
        /* The 4th id byte is the important one */
        extid = id_data[3];
 
        /* Calc pagesize */
-       mtd->writesize = 1024 << (extid & 0x03);
+       memorg->pagesize = 1024 << (extid & 0x03);
+       mtd->writesize = memorg->pagesize;
        extid >>= 2;
        /* Calc oobsize */
-       mtd->oobsize = (8 << (extid & 0x01)) * (mtd->writesize >> 9);
+       memorg->oobsize = (8 << (extid & 0x01)) * (mtd->writesize >> 9);
+       mtd->oobsize = memorg->oobsize;
        extid >>= 2;
        /* Calc blocksize. Blocksize is multiples of 64KiB */
+       memorg->pages_per_eraseblock = ((64 * 1024) << (extid & 0x03)) /
+                                      memorg->pagesize;
        mtd->erasesize = (64 * 1024) << (extid & 0x03);
        extid >>= 2;
        /* Get buswidth information */
 static void nand_decode_id(struct nand_chip *chip, struct nand_flash_dev *type)
 {
        struct mtd_info *mtd = nand_to_mtd(chip);
+       struct nand_memory_organization *memorg;
+
+       memorg = nanddev_get_memorg(&chip->base);
 
+       memorg->pages_per_eraseblock = type->erasesize / type->pagesize;
        mtd->erasesize = type->erasesize;
-       mtd->writesize = type->pagesize;
-       mtd->oobsize = mtd->writesize / 32;
+       memorg->pagesize = type->pagesize;
+       mtd->writesize = memorg->pagesize;
+       memorg->oobsize = memorg->pagesize / 32;
+       mtd->oobsize = memorg->oobsize;
 
        /* All legacy ID NAND are small-page, SLC */
+       memorg->bits_per_cell = 1;
        chip->bits_per_cell = 1;
 }
 
                              struct nand_flash_dev *type)
 {
        struct mtd_info *mtd = nand_to_mtd(chip);
+       struct nand_memory_organization *memorg;
        u8 *id_data = chip->id.data;
 
+       memorg = nanddev_get_memorg(&chip->base);
+
        if (!strncmp(type->id, id_data, type->id_len)) {
-               mtd->writesize = type->pagesize;
+               memorg->pagesize = type->pagesize;
+               mtd->writesize = memorg->pagesize;
+               memorg->pages_per_eraseblock = type->erasesize /
+                                              type->pagesize;
                mtd->erasesize = type->erasesize;
-               mtd->oobsize = type->oobsize;
+               memorg->oobsize = type->oobsize;
+               mtd->oobsize = memorg->oobsize;
 
+               memorg->bits_per_cell = nand_get_bits_per_cell(id_data[2]);
                chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]);
                chip->chipsize = (uint64_t)type->chipsize << 20;
+               memorg->eraseblocks_per_lun =
+                       DIV_ROUND_DOWN_ULL((u64)type->chipsize << 20,
+                                          memorg->pagesize *
+                                          memorg->pages_per_eraseblock);
                chip->options |= type->options;
                chip->ecc_strength_ds = NAND_ECC_STRENGTH(type);
                chip->ecc_step_ds = NAND_ECC_STEP(type);
         */
        if (chip->manufacturer.desc && chip->manufacturer.desc->ops &&
            chip->manufacturer.desc->ops->detect) {
+               struct nand_memory_organization *memorg;
+
+               memorg = nanddev_get_memorg(&chip->base);
+
                /* The 3rd id byte holds MLC / multichip data */
+               memorg->bits_per_cell = nand_get_bits_per_cell(chip->id.data[2]);
                chip->bits_per_cell = nand_get_bits_per_cell(chip->id.data[2]);
                chip->manufacturer.desc->ops->detect(chip);
        } else {
 {
        const struct nand_manufacturer *manufacturer;
        struct mtd_info *mtd = nand_to_mtd(chip);
+       struct nand_memory_organization *memorg;
        int busw, ret;
        u8 *id_data = chip->id.data;
        u8 maf_id, dev_id;
 
+       /*
+        * Let's start by initializing memorg fields that might be left
+        * unassigned by the ID-based detection logic.
+        */
+       memorg = nanddev_get_memorg(&chip->base);
+       memorg->planes_per_lun = 1;
+       memorg->luns_per_target = 1;
+       memorg->ntargets = 1;
+
        /*
         * Reset the chip, required by some chips (e.g. Micron MT29FxGxxxxx)
         * after power-up.
        /* Get chip options */
        chip->options |= type->options;
 
+       memorg->eraseblocks_per_lun =
+                       DIV_ROUND_DOWN_ULL((u64)type->chipsize << 20,
+                                          memorg->pagesize *
+                                          memorg->pages_per_eraseblock);
+
 ident_done:
        if (!mtd->name)
                mtd->name = chip->parameters.model;
                           struct nand_flash_dev *table)
 {
        struct mtd_info *mtd = nand_to_mtd(chip);
+       struct nand_memory_organization *memorg;
        int nand_maf_id, nand_dev_id;
        unsigned int i;
        int ret;
 
+       memorg = nanddev_get_memorg(&chip->base);
+
        /* Assume all dies are deselected when we enter nand_scan_ident(). */
        chip->cur_cs = -1;
 
                pr_info("%d chips detected\n", i);
 
        /* Store the number of chips and calc total size for mtd */
+       memorg->ntargets = i;
        chip->numchips = i;
        mtd->size = i * chip->chipsize;
 
 
                                       bool valid_jedecid)
 {
        struct mtd_info *mtd = nand_to_mtd(chip);
+       struct nand_memory_organization *memorg;
        u8 oobsize;
 
+       memorg = nanddev_get_memorg(&chip->base);
+
        oobsize = ((chip->id.data[3] >> 2) & 0x3) |
                  ((chip->id.data[3] >> 4) & 0x4);
 
        if (valid_jedecid) {
                switch (oobsize) {
                case 0:
-                       mtd->oobsize = 2048;
+                       memorg->oobsize = 2048;
                        break;
                case 1:
-                       mtd->oobsize = 1664;
+                       memorg->oobsize = 1664;
                        break;
                case 2:
-                       mtd->oobsize = 1024;
+                       memorg->oobsize = 1024;
                        break;
                case 3:
-                       mtd->oobsize = 640;
+                       memorg->oobsize = 640;
                        break;
                default:
                        /*
        } else {
                switch (oobsize) {
                case 0:
-                       mtd->oobsize = 128;
+                       memorg->oobsize = 128;
                        break;
                case 1:
-                       mtd->oobsize = 224;
+                       memorg->oobsize = 224;
                        break;
                case 2:
-                       mtd->oobsize = 448;
+                       memorg->oobsize = 448;
                        break;
                case 3:
-                       mtd->oobsize = 64;
+                       memorg->oobsize = 64;
                        break;
                case 4:
-                       mtd->oobsize = 32;
+                       memorg->oobsize = 32;
                        break;
                case 5:
-                       mtd->oobsize = 16;
+                       memorg->oobsize = 16;
                        break;
                case 6:
-                       mtd->oobsize = 640;
+                       memorg->oobsize = 640;
                        break;
                default:
                        /*
                 * the actual OOB size for this chip is: 640 * 16k / 8k).
                 */
                if (chip->id.data[1] == 0xde)
-                       mtd->oobsize *= mtd->writesize / SZ_8K;
+                       memorg->oobsize *= memorg->pagesize / SZ_8K;
        }
+
+       mtd->oobsize = memorg->oobsize;
 }
 
 static void hynix_nand_extract_ecc_requirements(struct nand_chip *chip,
 static void hynix_nand_decode_id(struct nand_chip *chip)
 {
        struct mtd_info *mtd = nand_to_mtd(chip);
+       struct nand_memory_organization *memorg;
        bool valid_jedecid;
        u8 tmp;
 
+       memorg = nanddev_get_memorg(&chip->base);
+
        /*
         * Exclude all SLC NANDs from this advanced detection scheme.
         * According to the ranges defined in several datasheets, it might
        }
 
        /* Extract pagesize */
-       mtd->writesize = 2048 << (chip->id.data[3] & 0x03);
+       memorg->pagesize = 2048 << (chip->id.data[3] & 0x03);
+       mtd->writesize = memorg->pagesize;
 
        tmp = (chip->id.data[3] >> 4) & 0x3;
        /*
         * The only exception is when ID[3][4:5] == 3 and ID[3][7] == 0, in
         * this case the erasesize is set to 768KiB.
         */
-       if (chip->id.data[3] & 0x80)
+       if (chip->id.data[3] & 0x80) {
+               memorg->pages_per_eraseblock = (SZ_1M << tmp) /
+                                              memorg->pagesize;
                mtd->erasesize = SZ_1M << tmp;
-       else if (tmp == 3)
+       } else if (tmp == 3) {
+               memorg->pages_per_eraseblock = (SZ_512K + SZ_256K) /
+                                              memorg->pagesize;
                mtd->erasesize = SZ_512K + SZ_256K;
-       else
+       } else {
+               memorg->pages_per_eraseblock = (SZ_128K << tmp) /
+                                              memorg->pagesize;
                mtd->erasesize = SZ_128K << tmp;
+       }
 
        /*
         * Modern Toggle DDR NANDs have a valid JEDECID even though they are
 
 int nand_jedec_detect(struct nand_chip *chip)
 {
        struct mtd_info *mtd = nand_to_mtd(chip);
+       struct nand_memory_organization *memorg;
        struct nand_jedec_params *p;
        struct jedec_ecc_info *ecc;
        int jedec_version = 0;
        char id[5];
        int i, val, ret;
 
+       memorg = nanddev_get_memorg(&chip->base);
+
        /* Try JEDEC for unknown chip or LP */
        ret = nand_readid_op(chip, 0x40, id, sizeof(id));
        if (ret || strncmp(id, "JEDEC", sizeof(id)))
                goto free_jedec_param_page;
        }
 
-       mtd->writesize = le32_to_cpu(p->byte_per_page);
+       memorg->pagesize = le32_to_cpu(p->byte_per_page);
+       mtd->writesize = memorg->pagesize;
 
        /* Please reference to the comment for nand_flash_detect_onfi. */
-       mtd->erasesize = 1 << (fls(le32_to_cpu(p->pages_per_block)) - 1);
-       mtd->erasesize *= mtd->writesize;
+       memorg->pages_per_eraseblock =
+                       1 << (fls(le32_to_cpu(p->pages_per_block)) - 1);
+       mtd->erasesize = memorg->pages_per_eraseblock * memorg->pagesize;
+
+       memorg->oobsize = le16_to_cpu(p->spare_bytes_per_page);
+       mtd->oobsize = memorg->oobsize;
 
-       mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page);
+       memorg->luns_per_target = p->lun_count;
+       memorg->planes_per_lun = 1 << p->multi_plane_addr;
 
        /* Please reference to the comment for nand_flash_detect_onfi. */
-       chip->chipsize = 1 << (fls(le32_to_cpu(p->blocks_per_lun)) - 1);
+       memorg->eraseblocks_per_lun =
+               1 << (fls(le32_to_cpu(p->blocks_per_lun)) - 1);
+       chip->chipsize = memorg->eraseblocks_per_lun;
        chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
+       memorg->bits_per_cell = p->bits_per_cell;
        chip->bits_per_cell = p->bits_per_cell;
 
        if (le16_to_cpu(p->features) & JEDEC_FEATURE_16_BIT_BUS)
 
 int nand_onfi_detect(struct nand_chip *chip)
 {
        struct mtd_info *mtd = nand_to_mtd(chip);
+       struct nand_memory_organization *memorg;
        struct nand_onfi_params *p;
        struct onfi_params *onfi;
        int onfi_version = 0;
        char id[4];
        int i, ret, val;
 
+       memorg = nanddev_get_memorg(&chip->base);
+
        /* Try ONFI for unknown chip or LP */
        ret = nand_readid_op(chip, 0x20, id, sizeof(id));
        if (ret || strncmp(id, "ONFI", 4))
                goto free_onfi_param_page;
        }
 
-       mtd->writesize = le32_to_cpu(p->byte_per_page);
+       memorg->pagesize = le32_to_cpu(p->byte_per_page);
+       mtd->writesize = memorg->pagesize;
 
        /*
         * pages_per_block and blocks_per_lun may not be a power-of-2 size
         * (don't ask me who thought of this...). MTD assumes that these
         * dimensions will be power-of-2, so just truncate the remaining area.
         */
-       mtd->erasesize = 1 << (fls(le32_to_cpu(p->pages_per_block)) - 1);
-       mtd->erasesize *= mtd->writesize;
+       memorg->pages_per_eraseblock =
+                       1 << (fls(le32_to_cpu(p->pages_per_block)) - 1);
+       mtd->erasesize = memorg->pages_per_eraseblock * memorg->pagesize;
+
+       memorg->oobsize = le16_to_cpu(p->spare_bytes_per_page);
+       mtd->oobsize = memorg->oobsize;
 
-       mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page);
+       memorg->luns_per_target = p->lun_count;
+       memorg->planes_per_lun = 1 << p->interleaved_bits;
 
        /* See erasesize comment */
-       chip->chipsize = 1 << (fls(le32_to_cpu(p->blocks_per_lun)) - 1);
+       memorg->eraseblocks_per_lun =
+               1 << (fls(le32_to_cpu(p->blocks_per_lun)) - 1);
+       memorg->max_bad_eraseblocks_per_lun = le32_to_cpu(p->blocks_per_lun);
+       chip->chipsize = memorg->eraseblocks_per_lun;
        chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
+       memorg->bits_per_cell = p->bits_per_cell;
        chip->bits_per_cell = p->bits_per_cell;
 
        chip->max_bb_per_die = le16_to_cpu(p->bb_per_lun);
 
 static void samsung_nand_decode_id(struct nand_chip *chip)
 {
        struct mtd_info *mtd = nand_to_mtd(chip);
+       struct nand_memory_organization *memorg;
+
+       memorg = nanddev_get_memorg(&chip->base);
 
        /* New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44) */
        if (chip->id.len == 6 && !nand_is_slc(chip) &&
                u8 extid = chip->id.data[3];
 
                /* Get pagesize */
-               mtd->writesize = 2048 << (extid & 0x03);
+               memorg->pagesize = 2048 << (extid & 0x03);
+               mtd->writesize = memorg->pagesize;
 
                extid >>= 2;
 
                /* Get oobsize */
                switch (((extid >> 2) & 0x4) | (extid & 0x3)) {
                case 1:
-                       mtd->oobsize = 128;
+                       memorg->oobsize = 128;
                        break;
                case 2:
-                       mtd->oobsize = 218;
+                       memorg->oobsize = 218;
                        break;
                case 3:
-                       mtd->oobsize = 400;
+                       memorg->oobsize = 400;
                        break;
                case 4:
-                       mtd->oobsize = 436;
+                       memorg->oobsize = 436;
                        break;
                case 5:
-                       mtd->oobsize = 512;
+                       memorg->oobsize = 512;
                        break;
                case 6:
-                       mtd->oobsize = 640;
+                       memorg->oobsize = 640;
                        break;
                default:
                        /*
                        break;
                }
 
+               mtd->oobsize = memorg->oobsize;
+
                /* Get blocksize */
                extid >>= 2;
+               memorg->pages_per_eraseblock = (128 * 1024) <<
+                                              (((extid >> 1) & 0x04) |
+                                               (extid & 0x03)) /
+                                              memorg->pagesize;
                mtd->erasesize = (128 * 1024) <<
                                 (((extid >> 1) & 0x04) | (extid & 0x03));
 
 
 static void toshiba_nand_decode_id(struct nand_chip *chip)
 {
        struct mtd_info *mtd = nand_to_mtd(chip);
+       struct nand_memory_organization *memorg;
+
+       memorg = nanddev_get_memorg(&chip->base);
 
        nand_decode_ext_id(chip);
 
         */
        if (chip->id.len >= 6 && nand_is_slc(chip) &&
            (chip->id.data[5] & 0x7) == 0x6 /* 24nm */ &&
-           !(chip->id.data[4] & 0x80) /* !BENAND */)
-               mtd->oobsize = 32 * mtd->writesize >> 9;
+           !(chip->id.data[4] & 0x80) /* !BENAND */) {
+               memorg->oobsize = 32 * memorg->pagesize >> 9;
+               mtd->oobsize = memorg->oobsize;
+       }
 
        /*
         * Extract ECC requirements from 6th id byte.
 
 
        if (overridesize) {
                uint64_t new_size = (uint64_t)nsmtd->erasesize << overridesize;
+               struct nand_memory_organization *memorg;
+
+               memorg = nanddev_get_memorg(&chip->base);
+
                if (new_size >> overridesize != nsmtd->erasesize) {
                        NS_ERR("overridesize is too big\n");
                        retval = -EINVAL;
                }
                /* N.B. This relies on nand_scan not doing anything with the size before we change it */
                nsmtd->size = new_size;
+               memorg->eraseblocks_per_lun = 1 << overridesize;
                chip->chipsize = new_size;
                chip->chip_shift = ffs(nsmtd->erasesize) + overridesize - 1;
                chip->pagemask = (chip->chipsize >> chip->page_shift) - 1;