Re: [PATCH v2 07/15] mtd: rawnand: Fill memorg during detection

Schrempf Frieder
2019-03-21T09:03:32Z

On 04.03.19 21:15, Miquel Raynal wrote:
> From: Boris Brezillon <bbrezillon@kernel.org>
>
> 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>
> Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>

Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>

> ---
> drivers/mtd/nand/raw/denali.c | 5 +++
> drivers/mtd/nand/raw/diskonchip.c | 4 ++
> drivers/mtd/nand/raw/jz4740_nand.c | 4 ++
> drivers/mtd/nand/raw/nand_amd.c | 11 +++--
> drivers/mtd/nand/raw/nand_base.c | 64 ++++++++++++++++++++++++++---
> drivers/mtd/nand/raw/nand_hynix.c | 48 ++++++++++++++--------
> drivers/mtd/nand/raw/nand_jedec.c | 22 +++++++---
> drivers/mtd/nand/raw/nand_onfi.c | 23 ++++++++---
> drivers/mtd/nand/raw/nand_samsung.c | 24 +++++++----
> drivers/mtd/nand/raw/nand_toshiba.c | 9 +++-
> drivers/mtd/nand/raw/nandsim.c | 5 +++
> 11 files changed, 175 insertions(+), 44 deletions(-)
>
> diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c
> index eebac35304c6..86e5df403beb 100644
> --- a/drivers/mtd/nand/raw/denali.c
> +++ b/drivers/mtd/nand/raw/denali.c
> @@ -1119,6 +1119,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:
> @@ -1148,6 +1151,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;
> diff --git a/drivers/mtd/nand/raw/diskonchip.c b/drivers/mtd/nand/raw/diskonchip.c
> index 53f57e0f007e..e9767e06415d 100644
> --- a/drivers/mtd/nand/raw/diskonchip.c
> +++ b/drivers/mtd/nand/raw/diskonchip.c
> @@ -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;
> diff --git a/drivers/mtd/nand/raw/jz4740_nand.c b/drivers/mtd/nand/raw/jz4740_nand.c
> index f92ae5aa2a54..76a32ad2cf83 100644
> --- a/drivers/mtd/nand/raw/jz4740_nand.c
> +++ b/drivers/mtd/nand/raw/jz4740_nand.c
> @@ -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;
> }
>
> diff --git a/drivers/mtd/nand/raw/nand_amd.c b/drivers/mtd/nand/raw/nand_amd.c
> index 890c5b43e03c..e008fd662ee6 100644
> --- a/drivers/mtd/nand/raw/nand_amd.c
> +++ b/drivers/mtd/nand/raw/nand_amd.c
> @@ -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;
> }
> }
>
> diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
> index d3092c9a3e21..5aba1cf38a4b 100644
> --- a/drivers/mtd/nand/raw/nand_base.c
> +++ b/drivers/mtd/nand/raw/nand_base.c
> @@ -4530,21 +4530,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 */
> @@ -4561,12 +4570,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;
> }
>
> @@ -4595,15 +4611,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);
> @@ -4632,7 +4660,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 {
> @@ -4682,10 +4715,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.
> @@ -4790,6 +4833,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;
> @@ -5016,10 +5064,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;
>
> @@ -5081,6 +5132,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;
>
> diff --git a/drivers/mtd/nand/raw/nand_hynix.c b/drivers/mtd/nand/raw/nand_hynix.c
> index 343f477362d1..94ea8c593589 100644
> --- a/drivers/mtd/nand/raw/nand_hynix.c
> +++ b/drivers/mtd/nand/raw/nand_hynix.c
> @@ -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
> diff --git a/drivers/mtd/nand/raw/nand_jedec.c b/drivers/mtd/nand/raw/nand_jedec.c
> index 38b5dc22cb30..61e33ee7ee19 100644
> --- a/drivers/mtd/nand/raw/nand_jedec.c
> +++ b/drivers/mtd/nand/raw/nand_jedec.c
> @@ -22,12 +22,15 @@
> 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;
>
> - mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page);
> + memorg->oobsize = le16_to_cpu(p->spare_bytes_per_page);
> + mtd->oobsize = memorg->oobsize;
> +
> + 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)
> diff --git a/drivers/mtd/nand/raw/nand_onfi.c b/drivers/mtd/nand/raw/nand_onfi.c
> index d8184cf591ad..f3f59cf37d7f 100644
> --- a/drivers/mtd/nand/raw/nand_onfi.c
> +++ b/drivers/mtd/nand/raw/nand_onfi.c
> @@ -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;
>
> - mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page);
> + memorg->oobsize = le16_to_cpu(p->spare_bytes_per_page);
> + mtd->oobsize = memorg->oobsize;
> +
> + 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);
> diff --git a/drivers/mtd/nand/raw/nand_samsung.c b/drivers/mtd/nand/raw/nand_samsung.c
> index e46d4c492ad8..9a9ad43cc97d 100644
> --- a/drivers/mtd/nand/raw/nand_samsung.c
> +++ b/drivers/mtd/nand/raw/nand_samsung.c
> @@ -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));
>
> diff --git a/drivers/mtd/nand/raw/nand_toshiba.c b/drivers/mtd/nand/raw/nand_toshiba.c
> index d068163b64b3..d8465049dfd6 100644
> --- a/drivers/mtd/nand/raw/nand_toshiba.c
> +++ b/drivers/mtd/nand/raw/nand_toshiba.c
> @@ -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.
> diff --git a/drivers/mtd/nand/raw/nandsim.c b/drivers/mtd/nand/raw/nandsim.c
> index 933d1a629c51..07144c992d54 100644
> --- a/drivers/mtd/nand/raw/nandsim.c
> +++ b/drivers/mtd/nand/raw/nandsim.c
> @@ -2302,6 +2302,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;
> @@ -2309,6 +2313,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;
>