mtd: rawnand: Fill memorg during detection
authorBoris Brezillon <bbrezillon@kernel.org>
Thu, 25 Oct 2018 15:10:37 +0000 (17:10 +0200)
committerMiquel Raynal <miquel.raynal@bootlin.com>
Mon, 8 Apr 2019 08:21:12 +0000 (10:21 +0200)
If we want to use the generic NAND layer, we need to have the memorg
struct appropriately filled. Patch the detection code to fill this
struct.

Signed-off-by: Boris Brezillon <bbrezillon@kernel.org>
Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
drivers/mtd/nand/raw/denali.c
drivers/mtd/nand/raw/diskonchip.c
drivers/mtd/nand/raw/ingenic/jz4740_nand.c
drivers/mtd/nand/raw/nand_amd.c
drivers/mtd/nand/raw/nand_base.c
drivers/mtd/nand/raw/nand_hynix.c
drivers/mtd/nand/raw/nand_jedec.c
drivers/mtd/nand/raw/nand_onfi.c
drivers/mtd/nand/raw/nand_samsung.c
drivers/mtd/nand/raw/nand_toshiba.c
drivers/mtd/nand/raw/nandsim.c

index 24aeafc67cd4ea9f1eeb79652074785b0b45446e..e99d59d8519724c0636bba044396f6466391d82b 100644 (file)
@@ -1096,6 +1096,9 @@ static int denali_multidev_fixup(struct denali_nand_info *denali)
 {
        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:
@@ -1125,6 +1128,8 @@ static int denali_multidev_fixup(struct denali_nand_info *denali)
        }
 
        /* 2 chips in parallel */
+       memorg->pagesize <<= 1;
+       memorg->oobsize <<= 1;
        mtd->size <<= 1;
        mtd->erasesize <<= 1;
        mtd->writesize <<= 1;
index ead54c90f2d1bd3bcc1774bb652d00247902d0e0..2e0da6a24bfd1122554187da02f1d89a3714e516 100644 (file)
@@ -1028,6 +1028,7 @@ static inline int __init nftl_partscan(struct mtd_info *mtd, struct mtd_partitio
 {
        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;
@@ -1036,6 +1037,8 @@ static inline int __init nftl_partscan(struct mtd_info *mtd, struct mtd_partitio
        unsigned blocks, maxblocks;
        int offs, numheaders;
 
+       memorg = nanddev_get_memorg(&this->base);
+
        buf = kmalloc(mtd->writesize, GFP_KERNEL);
        if (!buf) {
                return 0;
@@ -1082,6 +1085,7 @@ static inline int __init nftl_partscan(struct mtd_info *mtd, struct mtd_partitio
           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;
index 9526d5b23c809886dbb824808a5b67d0a0967f5b..d5715dde4237a7abb45fe3c569ed89bcaea57042 100644 (file)
@@ -313,8 +313,11 @@ static int jz_nand_detect_bank(struct platform_device *pdev,
        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,
@@ -352,6 +355,7 @@ static int jz_nand_detect_bank(struct platform_device *pdev,
 
                /* Update size of the MTD. */
                chip->numchips++;
+               memorg->ntargets++;
                mtd->size += chip->chipsize;
        }
 
index 890c5b43e03c53e3019151acba6f1d568466d92e..e008fd662ee69cb9c375e85520f2e47381f3e05e 100644 (file)
@@ -20,6 +20,9 @@
 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);
 
@@ -31,9 +34,11 @@ static void amd_nand_decode_id(struct nand_chip *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;
        }
 }
 
index ddd396e93e321055d425c2baba0cb634dae6c879..dbe3d96b74da9425b8cdf9895bc1897f25f3b8b0 100644 (file)
@@ -4485,21 +4485,30 @@ static int nand_get_bits_per_cell(u8 cellinfo)
  */
 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 */
@@ -4516,12 +4525,19 @@ EXPORT_SYMBOL_GPL(nand_decode_ext_id);
 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;
 }
 
@@ -4550,15 +4566,27 @@ static bool find_full_id_nand(struct nand_chip *chip,
                              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);
@@ -4587,7 +4615,12 @@ static void nand_manufacturer_detect(struct nand_chip *chip)
         */
        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 {
@@ -4637,10 +4670,20 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
 {
        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.
@@ -4745,6 +4788,11 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
        /* 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;
@@ -4971,10 +5019,13 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips,
                           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;
 
@@ -5042,6 +5093,7 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips,
                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;
 
index 343f477362d1d03e8c607c4f4507854875e4c48f..94ea8c593589c83cf2c58ab3a3b32c4215e97888 100644 (file)
@@ -418,24 +418,27 @@ static void hynix_nand_extract_oobsize(struct nand_chip *chip,
                                       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:
                        /*
@@ -450,25 +453,25 @@ static void hynix_nand_extract_oobsize(struct nand_chip *chip,
        } 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:
                        /*
@@ -492,8 +495,10 @@ static void hynix_nand_extract_oobsize(struct nand_chip *chip,
                 * 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,
@@ -609,9 +614,12 @@ static void hynix_nand_extract_scrambling_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
@@ -625,7 +633,8 @@ static void hynix_nand_decode_id(struct nand_chip *chip)
        }
 
        /* 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;
        /*
@@ -635,12 +644,19 @@ static void hynix_nand_decode_id(struct nand_chip *chip)
         * 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
index 38b5dc22cb30a6c56dec29ba71fe2b93b1362555..61e33ee7ee19b1cb201f2451502f5cc419d38871 100644 (file)
 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)))
@@ -81,17 +84,26 @@ int nand_jedec_detect(struct nand_chip *chip)
                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)
index d8184cf591ada1d511f5bde67bd837132420b5b8..f3f59cf37d7f4f8e77e05513b5566358ce5e1e29 100644 (file)
@@ -140,12 +140,15 @@ static void nand_bit_wise_majority(const void **srcbufs,
 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))
@@ -221,21 +224,31 @@ int nand_onfi_detect(struct nand_chip *chip)
                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);
index e46d4c492ad81ab7fc44ab7d0d9d22aeec56bdfc..9a9ad43cc97d48dd64ee56574dc82ed3f2b0625d 100644 (file)
@@ -20,6 +20,9 @@
 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) &&
@@ -27,29 +30,30 @@ static void samsung_nand_decode_id(struct nand_chip *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:
                        /*
@@ -62,8 +66,14 @@ static void samsung_nand_decode_id(struct nand_chip *chip)
                        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));
 
index d068163b64b3ff1755f5a66d6b3227d627603b93..d8465049dfd6c93ae8294701d0a94c9f12481fb8 100644 (file)
@@ -101,6 +101,9 @@ static void toshiba_nand_benand_init(struct nand_chip *chip)
 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);
 
@@ -114,8 +117,10 @@ static void toshiba_nand_decode_id(struct nand_chip *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.
index edf5fd3d5f07f2e2ae312c199fe4c9f7f7c91bed..bf54733f8b5b2a2ce337544370d1d65e1e3f86c3 100644 (file)
@@ -2304,6 +2304,10 @@ static int __init ns_init_module(void)
 
        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;
@@ -2311,6 +2315,7 @@ static int __init ns_init_module(void)
                }
                /* 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;