On 21.02.19 10:15, Miquel Raynal wrote: > From: Boris Brezillon <bbrezillon@xxxxxxxxxx> > > 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@xxxxxxxxxx> > Signed-off-by: Miquel Raynal <miquel.raynal@xxxxxxxxxxx> > --- > 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 | 60 ++++++++++++++++++++++++++--- > 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 | 6 +++ > 11 files changed, 172 insertions(+), 44 deletions(-) > [...] > diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c > index d3092c9a3e21..cb03877c775c 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,13 +4611,21 @@ 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->erasesize; This should be: 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; > chip->options |= type->options; > @@ -4632,7 +4656,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 +4711,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 +4829,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 +5060,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 +5128,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; > [...] > --- a/drivers/mtd/nand/raw/nandsim.c > +++ b/drivers/mtd/nand/raw/nandsim.c > @@ -2302,6 +2302,11 @@ static int __init ns_init_module(void) > > if (overridesize) { > uint64_t new_size = (uint64_t)nsmtd->erasesize << overridesize; > + struct nand_memory_organization *memorg; > + u64 targetsize; This variable is not used yet. It rather belongs into patch 13. > + > + memorg = nanddev_get_memorg(&chip->base); > + > if (new_size >> overridesize != nsmtd->erasesize) { > NS_ERR("overridesize is too big\n"); > retval = -EINVAL; > @@ -2309,6 +2314,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; > ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/