All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/15] mtd: rawnand: 5th batch of cleanups
@ 2019-03-04 20:15 ` Miquel Raynal
  0 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

Hello,

This time I am the one who send the cleanups on behalf of Boris, I
just took his patches because I needed them for my 'generic ECC
engine' work. Between this cleanup series and the ECC engine series
there will be an additional one, to prepare the field.

Patch 1 adds a field to the memorg structure, patch 2 & 3 add helpers
in the raw NAND core, following patches are general cleanups in the
raw NAND area that prepares the use of the (generic) NAND core shared
between raw NANDs and SPI-NANDs and finally a few nand_chip entries
are dropped.

Regards,
Miquèl

Changs for v2
=============
* Fixed the inconsistencies between patch 7 and 13 pointed out by Frieder.
* Fixed the derivation of memorg->pages_per_eraseblock.
* Added Frieder Reviewed-by tags.


Boris Brezillon (15):
  mtd: nand: Add max_bad_eraseblocks_per_lun info to memorg
  mtd: nand: Add a helper returning the number of eraseblocks per target
  mtd: nand: Add a helper to retrieve the number of pages per target
  mtd: spinand: Implement mtd->_max_bad_blocks
  mtd: rawnand: Use nand_to_mtd() in nand_{set,get}_flash_node()
  mtd: rawnand: Prepare things to reuse the generic NAND layer
  mtd: rawnand: Fill memorg during detection
  mtd: rawnand: Initialize the nand_device object
  mtd: rawnand: Provide a helper to get chip->data_buf
  mtd: rawnand: Move all page cache related fields to a sub-struct
  mtd: rawnand: Use nanddev_mtd_max_bad_blocks()
  mtd: rawnand: Get rid of chip->bits_per_cell
  mtd: rawnand: Get rid of chip->chipsize
  mtd: rawnand: Get rid of chip->numchips
  mtd: rawnand: Get rid of chip->ecc_{strength,step}_ds

 drivers/mtd/nand/core.c                       |  34 +++
 drivers/mtd/nand/raw/Kconfig                  |   1 +
 drivers/mtd/nand/raw/atmel/nand-controller.c  |   8 +-
 .../mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c  |   2 +-
 drivers/mtd/nand/raw/brcmnand/brcmnand.c      |   7 +-
 drivers/mtd/nand/raw/denali.c                 |   6 +-
 drivers/mtd/nand/raw/diskonchip.c             |   6 +-
 drivers/mtd/nand/raw/fsl_elbc_nand.c          |   4 +-
 drivers/mtd/nand/raw/fsl_ifc_nand.c           |   4 +-
 drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c    |  17 +-
 drivers/mtd/nand/raw/hisi504_nand.c           |   2 +-
 drivers/mtd/nand/raw/internals.h              |   2 +-
 drivers/mtd/nand/raw/jz4740_nand.c            |   7 +-
 drivers/mtd/nand/raw/marvell_nand.c           |  49 ++--
 drivers/mtd/nand/raw/mtk_nand.c               |   4 +-
 drivers/mtd/nand/raw/nand_amd.c               |  11 +-
 drivers/mtd/nand/raw/nand_base.c              | 253 +++++++++++-------
 drivers/mtd/nand/raw/nand_bbt.c               |  45 ++--
 drivers/mtd/nand/raw/nand_esmt.c              |  10 +-
 drivers/mtd/nand/raw/nand_hynix.c             |  90 ++++---
 drivers/mtd/nand/raw/nand_jedec.c             |  27 +-
 drivers/mtd/nand/raw/nand_micron.c            |  14 +-
 drivers/mtd/nand/raw/nand_onfi.c              |  35 ++-
 drivers/mtd/nand/raw/nand_samsung.c           |  42 +--
 drivers/mtd/nand/raw/nand_toshiba.c           |  19 +-
 drivers/mtd/nand/raw/nandsim.c                |  11 +-
 drivers/mtd/nand/raw/qcom_nandc.c             |   8 +-
 drivers/mtd/nand/raw/sh_flctl.c               |   9 +-
 drivers/mtd/nand/raw/sunxi_nand.c             |  15 +-
 drivers/mtd/nand/raw/tegra_nand.c             |   8 +-
 drivers/mtd/nand/spi/core.c                   |   1 +
 drivers/mtd/nand/spi/gigadevice.c             |   6 +-
 drivers/mtd/nand/spi/macronix.c               |   4 +-
 drivers/mtd/nand/spi/micron.c                 |   2 +-
 drivers/mtd/nand/spi/toshiba.c                |   2 +-
 drivers/mtd/nand/spi/winbond.c                |   4 +-
 include/linux/mtd/nand.h                      |  32 ++-
 include/linux/mtd/rawnand.h                   |  97 ++++---
 38 files changed, 548 insertions(+), 350 deletions(-)

-- 
2.19.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH v2 00/15] mtd: rawnand: 5th batch of cleanups
@ 2019-03-04 20:15 ` Miquel Raynal
  0 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

Hello,

This time I am the one who send the cleanups on behalf of Boris, I
just took his patches because I needed them for my 'generic ECC
engine' work. Between this cleanup series and the ECC engine series
there will be an additional one, to prepare the field.

Patch 1 adds a field to the memorg structure, patch 2 & 3 add helpers
in the raw NAND core, following patches are general cleanups in the
raw NAND area that prepares the use of the (generic) NAND core shared
between raw NANDs and SPI-NANDs and finally a few nand_chip entries
are dropped.

Regards,
Miquèl

Changs for v2
=============
* Fixed the inconsistencies between patch 7 and 13 pointed out by Frieder.
* Fixed the derivation of memorg->pages_per_eraseblock.
* Added Frieder Reviewed-by tags.


Boris Brezillon (15):
  mtd: nand: Add max_bad_eraseblocks_per_lun info to memorg
  mtd: nand: Add a helper returning the number of eraseblocks per target
  mtd: nand: Add a helper to retrieve the number of pages per target
  mtd: spinand: Implement mtd->_max_bad_blocks
  mtd: rawnand: Use nand_to_mtd() in nand_{set,get}_flash_node()
  mtd: rawnand: Prepare things to reuse the generic NAND layer
  mtd: rawnand: Fill memorg during detection
  mtd: rawnand: Initialize the nand_device object
  mtd: rawnand: Provide a helper to get chip->data_buf
  mtd: rawnand: Move all page cache related fields to a sub-struct
  mtd: rawnand: Use nanddev_mtd_max_bad_blocks()
  mtd: rawnand: Get rid of chip->bits_per_cell
  mtd: rawnand: Get rid of chip->chipsize
  mtd: rawnand: Get rid of chip->numchips
  mtd: rawnand: Get rid of chip->ecc_{strength,step}_ds

 drivers/mtd/nand/core.c                       |  34 +++
 drivers/mtd/nand/raw/Kconfig                  |   1 +
 drivers/mtd/nand/raw/atmel/nand-controller.c  |   8 +-
 .../mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c  |   2 +-
 drivers/mtd/nand/raw/brcmnand/brcmnand.c      |   7 +-
 drivers/mtd/nand/raw/denali.c                 |   6 +-
 drivers/mtd/nand/raw/diskonchip.c             |   6 +-
 drivers/mtd/nand/raw/fsl_elbc_nand.c          |   4 +-
 drivers/mtd/nand/raw/fsl_ifc_nand.c           |   4 +-
 drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c    |  17 +-
 drivers/mtd/nand/raw/hisi504_nand.c           |   2 +-
 drivers/mtd/nand/raw/internals.h              |   2 +-
 drivers/mtd/nand/raw/jz4740_nand.c            |   7 +-
 drivers/mtd/nand/raw/marvell_nand.c           |  49 ++--
 drivers/mtd/nand/raw/mtk_nand.c               |   4 +-
 drivers/mtd/nand/raw/nand_amd.c               |  11 +-
 drivers/mtd/nand/raw/nand_base.c              | 253 +++++++++++-------
 drivers/mtd/nand/raw/nand_bbt.c               |  45 ++--
 drivers/mtd/nand/raw/nand_esmt.c              |  10 +-
 drivers/mtd/nand/raw/nand_hynix.c             |  90 ++++---
 drivers/mtd/nand/raw/nand_jedec.c             |  27 +-
 drivers/mtd/nand/raw/nand_micron.c            |  14 +-
 drivers/mtd/nand/raw/nand_onfi.c              |  35 ++-
 drivers/mtd/nand/raw/nand_samsung.c           |  42 +--
 drivers/mtd/nand/raw/nand_toshiba.c           |  19 +-
 drivers/mtd/nand/raw/nandsim.c                |  11 +-
 drivers/mtd/nand/raw/qcom_nandc.c             |   8 +-
 drivers/mtd/nand/raw/sh_flctl.c               |   9 +-
 drivers/mtd/nand/raw/sunxi_nand.c             |  15 +-
 drivers/mtd/nand/raw/tegra_nand.c             |   8 +-
 drivers/mtd/nand/spi/core.c                   |   1 +
 drivers/mtd/nand/spi/gigadevice.c             |   6 +-
 drivers/mtd/nand/spi/macronix.c               |   4 +-
 drivers/mtd/nand/spi/micron.c                 |   2 +-
 drivers/mtd/nand/spi/toshiba.c                |   2 +-
 drivers/mtd/nand/spi/winbond.c                |   4 +-
 include/linux/mtd/nand.h                      |  32 ++-
 include/linux/mtd/rawnand.h                   |  97 ++++---
 38 files changed, 548 insertions(+), 350 deletions(-)

-- 
2.19.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 66+ messages in thread

* [PATCH v2 01/15] mtd: nand: Add max_bad_eraseblocks_per_lun info to memorg
  2019-03-04 20:15 ` Miquel Raynal
@ 2019-03-04 20:15   ` Miquel Raynal
  -1 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

NAND datasheets usually give the maximum number of bad blocks per LUN
and this number can be used to help upper layers decide how much blocks
they should reserve for bad block handling.

Add a max_bad_eraseblocks_per_lun to the nand_memory_organization
struct and update the NAND_MEMORG() macro (and its users) accordingly.

We also provide a default mtd->_max_bad_blocks() implementation.

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/core.c           | 34 +++++++++++++++++++++++++++++++
 drivers/mtd/nand/spi/gigadevice.c |  6 +++---
 drivers/mtd/nand/spi/macronix.c   |  4 ++--
 drivers/mtd/nand/spi/micron.c     |  2 +-
 drivers/mtd/nand/spi/toshiba.c    |  2 +-
 drivers/mtd/nand/spi/winbond.c    |  4 ++--
 include/linux/mtd/nand.h          |  6 +++++-
 7 files changed, 48 insertions(+), 10 deletions(-)

diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c
index e6554b401813..0a2be5e6d669 100644
--- a/drivers/mtd/nand/core.c
+++ b/drivers/mtd/nand/core.c
@@ -173,6 +173,40 @@ int nanddev_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo)
 }
 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
diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c
index e4141c20947a..c434fbed3ce5 100644
--- a/drivers/mtd/nand/spi/gigadevice.c
+++ b/drivers/mtd/nand/spi/gigadevice.c
@@ -88,7 +88,7 @@ static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = {
 
 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,
@@ -97,7 +97,7 @@ static const struct spinand_info gigadevice_spinand_table[] = {
 		     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,
@@ -106,7 +106,7 @@ static const struct spinand_info gigadevice_spinand_table[] = {
 		     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,
diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
index 98f6b9c4b684..c6300d9d63f9 100644
--- a/drivers/mtd/nand/spi/macronix.c
+++ b/drivers/mtd/nand/spi/macronix.c
@@ -94,7 +94,7 @@ static int mx35lf1ge4ab_ecc_get_status(struct spinand_device *spinand,
 
 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,
@@ -103,7 +103,7 @@ static const struct spinand_info macronix_spinand_table[] = {
 		     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,
diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
index 9c4381d6847b..7d7b1f7fcf71 100644
--- a/drivers/mtd/nand/spi/micron.c
+++ b/drivers/mtd/nand/spi/micron.c
@@ -92,7 +92,7 @@ static int mt29f2g01abagd_ecc_get_status(struct spinand_device *spinand,
 
 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,
diff --git a/drivers/mtd/nand/spi/toshiba.c b/drivers/mtd/nand/spi/toshiba.c
index 081265557e70..00ddab08e6c6 100644
--- a/drivers/mtd/nand/spi/toshiba.c
+++ b/drivers/mtd/nand/spi/toshiba.c
@@ -95,7 +95,7 @@ static int tc58cvg2s0h_ecc_get_status(struct spinand_device *spinand,
 
 static const struct spinand_info toshiba_spinand_table[] = {
 	SPINAND_INFO("TC58CVG2S0H", 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,
diff --git a/drivers/mtd/nand/spi/winbond.c b/drivers/mtd/nand/spi/winbond.c
index 5d944580b898..a6c17e0cace8 100644
--- a/drivers/mtd/nand/spi/winbond.c
+++ b/drivers/mtd/nand/spi/winbond.c
@@ -76,7 +76,7 @@ static int w25m02gv_select_target(struct spinand_device *spinand,
 
 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,
@@ -85,7 +85,7 @@ static const struct spinand_info winbond_spinand_table[] = {
 		     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,
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 7f53ece2c039..d32bb623d532 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -19,6 +19,7 @@
  * @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
@@ -29,18 +30,20 @@ struct nand_memory_organization {
 	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),				\
@@ -729,5 +732,6 @@ static inline bool nanddev_bbt_is_initialized(struct nand_device *nand)
 
 /* 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 */
-- 
2.19.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 01/15] mtd: nand: Add max_bad_eraseblocks_per_lun info to memorg
@ 2019-03-04 20:15   ` Miquel Raynal
  0 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

NAND datasheets usually give the maximum number of bad blocks per LUN
and this number can be used to help upper layers decide how much blocks
they should reserve for bad block handling.

Add a max_bad_eraseblocks_per_lun to the nand_memory_organization
struct and update the NAND_MEMORG() macro (and its users) accordingly.

We also provide a default mtd->_max_bad_blocks() implementation.

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/core.c           | 34 +++++++++++++++++++++++++++++++
 drivers/mtd/nand/spi/gigadevice.c |  6 +++---
 drivers/mtd/nand/spi/macronix.c   |  4 ++--
 drivers/mtd/nand/spi/micron.c     |  2 +-
 drivers/mtd/nand/spi/toshiba.c    |  2 +-
 drivers/mtd/nand/spi/winbond.c    |  4 ++--
 include/linux/mtd/nand.h          |  6 +++++-
 7 files changed, 48 insertions(+), 10 deletions(-)

diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c
index e6554b401813..0a2be5e6d669 100644
--- a/drivers/mtd/nand/core.c
+++ b/drivers/mtd/nand/core.c
@@ -173,6 +173,40 @@ int nanddev_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo)
 }
 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
diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c
index e4141c20947a..c434fbed3ce5 100644
--- a/drivers/mtd/nand/spi/gigadevice.c
+++ b/drivers/mtd/nand/spi/gigadevice.c
@@ -88,7 +88,7 @@ static const struct mtd_ooblayout_ops gd5fxgq4xa_ooblayout = {
 
 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,
@@ -97,7 +97,7 @@ static const struct spinand_info gigadevice_spinand_table[] = {
 		     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,
@@ -106,7 +106,7 @@ static const struct spinand_info gigadevice_spinand_table[] = {
 		     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,
diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c
index 98f6b9c4b684..c6300d9d63f9 100644
--- a/drivers/mtd/nand/spi/macronix.c
+++ b/drivers/mtd/nand/spi/macronix.c
@@ -94,7 +94,7 @@ static int mx35lf1ge4ab_ecc_get_status(struct spinand_device *spinand,
 
 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,
@@ -103,7 +103,7 @@ static const struct spinand_info macronix_spinand_table[] = {
 		     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,
diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c
index 9c4381d6847b..7d7b1f7fcf71 100644
--- a/drivers/mtd/nand/spi/micron.c
+++ b/drivers/mtd/nand/spi/micron.c
@@ -92,7 +92,7 @@ static int mt29f2g01abagd_ecc_get_status(struct spinand_device *spinand,
 
 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,
diff --git a/drivers/mtd/nand/spi/toshiba.c b/drivers/mtd/nand/spi/toshiba.c
index 081265557e70..00ddab08e6c6 100644
--- a/drivers/mtd/nand/spi/toshiba.c
+++ b/drivers/mtd/nand/spi/toshiba.c
@@ -95,7 +95,7 @@ static int tc58cvg2s0h_ecc_get_status(struct spinand_device *spinand,
 
 static const struct spinand_info toshiba_spinand_table[] = {
 	SPINAND_INFO("TC58CVG2S0H", 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,
diff --git a/drivers/mtd/nand/spi/winbond.c b/drivers/mtd/nand/spi/winbond.c
index 5d944580b898..a6c17e0cace8 100644
--- a/drivers/mtd/nand/spi/winbond.c
+++ b/drivers/mtd/nand/spi/winbond.c
@@ -76,7 +76,7 @@ static int w25m02gv_select_target(struct spinand_device *spinand,
 
 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,
@@ -85,7 +85,7 @@ static const struct spinand_info winbond_spinand_table[] = {
 		     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,
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 7f53ece2c039..d32bb623d532 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -19,6 +19,7 @@
  * @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
@@ -29,18 +30,20 @@ struct nand_memory_organization {
 	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),				\
@@ -729,5 +732,6 @@ static inline bool nanddev_bbt_is_initialized(struct nand_device *nand)
 
 /* 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 */
-- 
2.19.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 02/15] mtd: nand: Add a helper returning the number of eraseblocks per target
  2019-03-04 20:15 ` Miquel Raynal
@ 2019-03-04 20:15   ` Miquel Raynal
  -1 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

Some drivers in the raw NAND framework seems to need this helper, so
let's just add it instead of open-coding the logic.

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>
---
 include/linux/mtd/nand.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index d32bb623d532..12d75402472a 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -294,6 +294,18 @@ nanddev_eraseblocks_per_lun(const struct nand_device *nand)
 	return nand->memorg.eraseblocks_per_lun;
 }
 
+/**
+ * nanddev_eraseblocks_per_target() - Get the number of eraseblocks per target
+ * @nand: NAND device
+ *
+ * Return: the number of eraseblocks per target.
+ */
+static inline unsigned int
+nanddev_eraseblocks_per_target(const struct nand_device *nand)
+{
+	return nand->memorg.eraseblocks_per_lun * nand->memorg.luns_per_target;
+}
+
 /**
  * nanddev_target_size() - Get the total size provided by a single target/die
  * @nand: NAND device
-- 
2.19.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 02/15] mtd: nand: Add a helper returning the number of eraseblocks per target
@ 2019-03-04 20:15   ` Miquel Raynal
  0 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

Some drivers in the raw NAND framework seems to need this helper, so
let's just add it instead of open-coding the logic.

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>
---
 include/linux/mtd/nand.h | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index d32bb623d532..12d75402472a 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -294,6 +294,18 @@ nanddev_eraseblocks_per_lun(const struct nand_device *nand)
 	return nand->memorg.eraseblocks_per_lun;
 }
 
+/**
+ * nanddev_eraseblocks_per_target() - Get the number of eraseblocks per target
+ * @nand: NAND device
+ *
+ * Return: the number of eraseblocks per target.
+ */
+static inline unsigned int
+nanddev_eraseblocks_per_target(const struct nand_device *nand)
+{
+	return nand->memorg.eraseblocks_per_lun * nand->memorg.luns_per_target;
+}
+
 /**
  * nanddev_target_size() - Get the total size provided by a single target/die
  * @nand: NAND device
-- 
2.19.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 03/15] mtd: nand: Add a helper to retrieve the number of pages per target
  2019-03-04 20:15 ` Miquel Raynal
@ 2019-03-04 20:15   ` Miquel Raynal
  -1 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

Will be used by the raw NAND framework.

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>
---
 include/linux/mtd/nand.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 12d75402472a..cebc38b6d6f5 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -271,6 +271,20 @@ nanddev_pages_per_eraseblock(const struct nand_device *nand)
 	return nand->memorg.pages_per_eraseblock;
 }
 
+/**
+ * nanddev_pages_per_target() - Get the number of pages per target
+ * @nand: NAND device
+ *
+ * Return: the number of pages per target.
+ */
+static inline unsigned int
+nanddev_pages_per_target(const struct nand_device *nand)
+{
+	return nand->memorg.pages_per_eraseblock *
+	       nand->memorg.eraseblocks_per_lun *
+	       nand->memorg.luns_per_target;
+}
+
 /**
  * nanddev_per_page_oobsize() - Get NAND erase block size
  * @nand: NAND device
-- 
2.19.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 03/15] mtd: nand: Add a helper to retrieve the number of pages per target
@ 2019-03-04 20:15   ` Miquel Raynal
  0 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

Will be used by the raw NAND framework.

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>
---
 include/linux/mtd/nand.h | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 12d75402472a..cebc38b6d6f5 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -271,6 +271,20 @@ nanddev_pages_per_eraseblock(const struct nand_device *nand)
 	return nand->memorg.pages_per_eraseblock;
 }
 
+/**
+ * nanddev_pages_per_target() - Get the number of pages per target
+ * @nand: NAND device
+ *
+ * Return: the number of pages per target.
+ */
+static inline unsigned int
+nanddev_pages_per_target(const struct nand_device *nand)
+{
+	return nand->memorg.pages_per_eraseblock *
+	       nand->memorg.eraseblocks_per_lun *
+	       nand->memorg.luns_per_target;
+}
+
 /**
  * nanddev_per_page_oobsize() - Get NAND erase block size
  * @nand: NAND device
-- 
2.19.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 04/15] mtd: spinand: Implement mtd->_max_bad_blocks
  2019-03-04 20:15 ` Miquel Raynal
@ 2019-03-04 20:15   ` Miquel Raynal
  -1 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

We just have to use nanddev_mtd_max_bad_blocks().

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/spi/core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 2ae4237a586e..ed5e340dff51 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -1040,6 +1040,7 @@ static int spinand_init(struct spinand_device *spinand)
 	mtd->_block_markbad = spinand_mtd_block_markbad;
 	mtd->_block_isreserved = spinand_mtd_block_isreserved;
 	mtd->_erase = spinand_mtd_erase;
+	mtd->_max_bad_blocks = nanddev_mtd_max_bad_blocks;
 
 	if (spinand->eccinfo.ooblayout)
 		mtd_set_ooblayout(mtd, spinand->eccinfo.ooblayout);
-- 
2.19.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 04/15] mtd: spinand: Implement mtd->_max_bad_blocks
@ 2019-03-04 20:15   ` Miquel Raynal
  0 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

We just have to use nanddev_mtd_max_bad_blocks().

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/spi/core.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 2ae4237a586e..ed5e340dff51 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -1040,6 +1040,7 @@ static int spinand_init(struct spinand_device *spinand)
 	mtd->_block_markbad = spinand_mtd_block_markbad;
 	mtd->_block_isreserved = spinand_mtd_block_isreserved;
 	mtd->_erase = spinand_mtd_erase;
+	mtd->_max_bad_blocks = nanddev_mtd_max_bad_blocks;
 
 	if (spinand->eccinfo.ooblayout)
 		mtd_set_ooblayout(mtd, spinand->eccinfo.ooblayout);
-- 
2.19.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 05/15] mtd: rawnand: Use nand_to_mtd() in nand_{set, get}_flash_node()
  2019-03-04 20:15 ` Miquel Raynal
@ 2019-03-04 20:15   ` Miquel Raynal
  -1 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

Use the nand_to_mtd() helper to access chip->mtd as done everywhere
else.

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>
---
 include/linux/mtd/rawnand.h | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index 33e240acdc6d..c20ea012aab6 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -1113,17 +1113,6 @@ struct nand_chip {
 extern const struct mtd_ooblayout_ops nand_ooblayout_sp_ops;
 extern const struct mtd_ooblayout_ops nand_ooblayout_lp_ops;
 
-static inline void nand_set_flash_node(struct nand_chip *chip,
-				       struct device_node *np)
-{
-	mtd_set_of_node(&chip->mtd, np);
-}
-
-static inline struct device_node *nand_get_flash_node(struct nand_chip *chip)
-{
-	return mtd_get_of_node(&chip->mtd);
-}
-
 static inline struct nand_chip *mtd_to_nand(struct mtd_info *mtd)
 {
 	return container_of(mtd, struct nand_chip, mtd);
@@ -1155,6 +1144,17 @@ static inline void *nand_get_manufacturer_data(struct nand_chip *chip)
 	return chip->manufacturer.priv;
 }
 
+static inline void nand_set_flash_node(struct nand_chip *chip,
+				       struct device_node *np)
+{
+	mtd_set_of_node(nand_to_mtd(chip), np);
+}
+
+static inline struct device_node *nand_get_flash_node(struct nand_chip *chip)
+{
+	return mtd_get_of_node(nand_to_mtd(chip));
+}
+
 /*
  * A helper for defining older NAND chips where the second ID byte fully
  * defined the chip, including the geometry (chip size, eraseblock size, page
-- 
2.19.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 05/15] mtd: rawnand: Use nand_to_mtd() in nand_{set, get}_flash_node()
@ 2019-03-04 20:15   ` Miquel Raynal
  0 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

Use the nand_to_mtd() helper to access chip->mtd as done everywhere
else.

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>
---
 include/linux/mtd/rawnand.h | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index 33e240acdc6d..c20ea012aab6 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -1113,17 +1113,6 @@ struct nand_chip {
 extern const struct mtd_ooblayout_ops nand_ooblayout_sp_ops;
 extern const struct mtd_ooblayout_ops nand_ooblayout_lp_ops;
 
-static inline void nand_set_flash_node(struct nand_chip *chip,
-				       struct device_node *np)
-{
-	mtd_set_of_node(&chip->mtd, np);
-}
-
-static inline struct device_node *nand_get_flash_node(struct nand_chip *chip)
-{
-	return mtd_get_of_node(&chip->mtd);
-}
-
 static inline struct nand_chip *mtd_to_nand(struct mtd_info *mtd)
 {
 	return container_of(mtd, struct nand_chip, mtd);
@@ -1155,6 +1144,17 @@ static inline void *nand_get_manufacturer_data(struct nand_chip *chip)
 	return chip->manufacturer.priv;
 }
 
+static inline void nand_set_flash_node(struct nand_chip *chip,
+				       struct device_node *np)
+{
+	mtd_set_of_node(nand_to_mtd(chip), np);
+}
+
+static inline struct device_node *nand_get_flash_node(struct nand_chip *chip)
+{
+	return mtd_get_of_node(nand_to_mtd(chip));
+}
+
 /*
  * A helper for defining older NAND chips where the second ID byte fully
  * defined the chip, including the geometry (chip size, eraseblock size, page
-- 
2.19.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 06/15] mtd: rawnand: Prepare things to reuse the generic NAND layer
  2019-03-04 20:15 ` Miquel Raynal
@ 2019-03-04 20:15   ` Miquel Raynal
  -1 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

The generic NAND layer provides abstraction of NAND devices no matter
the bus that is used to communicate with the chip. Basing the raw NAND
core on this generic layer should avoid duplication of common
operations, like iterating over all pages/blocks for MTD IO/erase
operations.

In order to re-use this layer, we must first inherit from nand_device
and then initialize the nand_device struct appropriately. This patch
is taking care of the former.

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>
---
 include/linux/mtd/rawnand.h | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index c20ea012aab6..dfeedfe2f3e0 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -22,6 +22,7 @@
 #include <linux/mtd/flashchip.h>
 #include <linux/mtd/bbm.h>
 #include <linux/mtd/jedec.h>
+#include <linux/mtd/nand.h>
 #include <linux/mtd/onfi.h>
 #include <linux/of.h>
 #include <linux/types.h>
@@ -861,6 +862,7 @@ struct nand_operation {
 int nand_op_parser_exec_op(struct nand_chip *chip,
 			   const struct nand_op_parser *parser,
 			   const struct nand_operation *op, bool check_only);
+
 /**
  * struct nand_controller_ops - Controller operations
  *
@@ -973,7 +975,7 @@ struct nand_legacy {
 
 /**
  * struct nand_chip - NAND Private Flash Chip Data
- * @mtd:		MTD device registered to the MTD framework
+ * @base:		Inherit from the generic NAND device
  * @legacy:		All legacy fields/hooks. If you develop a new driver,
  *			don't even try to use any of these fields/hooks, and if
  *			you're modifying an existing driver that is using those
@@ -1050,7 +1052,7 @@ struct nand_legacy {
  */
 
 struct nand_chip {
-	struct mtd_info mtd;
+	struct nand_device base;
 
 	struct nand_legacy legacy;
 
@@ -1115,12 +1117,12 @@ extern const struct mtd_ooblayout_ops nand_ooblayout_lp_ops;
 
 static inline struct nand_chip *mtd_to_nand(struct mtd_info *mtd)
 {
-	return container_of(mtd, struct nand_chip, mtd);
+	return container_of(mtd, struct nand_chip, base.mtd);
 }
 
 static inline struct mtd_info *nand_to_mtd(struct nand_chip *chip)
 {
-	return &chip->mtd;
+	return &chip->base.mtd;
 }
 
 static inline void *nand_get_controller_data(struct nand_chip *chip)
-- 
2.19.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 06/15] mtd: rawnand: Prepare things to reuse the generic NAND layer
@ 2019-03-04 20:15   ` Miquel Raynal
  0 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

The generic NAND layer provides abstraction of NAND devices no matter
the bus that is used to communicate with the chip. Basing the raw NAND
core on this generic layer should avoid duplication of common
operations, like iterating over all pages/blocks for MTD IO/erase
operations.

In order to re-use this layer, we must first inherit from nand_device
and then initialize the nand_device struct appropriately. This patch
is taking care of the former.

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>
---
 include/linux/mtd/rawnand.h | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index c20ea012aab6..dfeedfe2f3e0 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -22,6 +22,7 @@
 #include <linux/mtd/flashchip.h>
 #include <linux/mtd/bbm.h>
 #include <linux/mtd/jedec.h>
+#include <linux/mtd/nand.h>
 #include <linux/mtd/onfi.h>
 #include <linux/of.h>
 #include <linux/types.h>
@@ -861,6 +862,7 @@ struct nand_operation {
 int nand_op_parser_exec_op(struct nand_chip *chip,
 			   const struct nand_op_parser *parser,
 			   const struct nand_operation *op, bool check_only);
+
 /**
  * struct nand_controller_ops - Controller operations
  *
@@ -973,7 +975,7 @@ struct nand_legacy {
 
 /**
  * struct nand_chip - NAND Private Flash Chip Data
- * @mtd:		MTD device registered to the MTD framework
+ * @base:		Inherit from the generic NAND device
  * @legacy:		All legacy fields/hooks. If you develop a new driver,
  *			don't even try to use any of these fields/hooks, and if
  *			you're modifying an existing driver that is using those
@@ -1050,7 +1052,7 @@ struct nand_legacy {
  */
 
 struct nand_chip {
-	struct mtd_info mtd;
+	struct nand_device base;
 
 	struct nand_legacy legacy;
 
@@ -1115,12 +1117,12 @@ extern const struct mtd_ooblayout_ops nand_ooblayout_lp_ops;
 
 static inline struct nand_chip *mtd_to_nand(struct mtd_info *mtd)
 {
-	return container_of(mtd, struct nand_chip, mtd);
+	return container_of(mtd, struct nand_chip, base.mtd);
 }
 
 static inline struct mtd_info *nand_to_mtd(struct nand_chip *chip)
 {
-	return &chip->mtd;
+	return &chip->base.mtd;
 }
 
 static inline void *nand_get_controller_data(struct nand_chip *chip)
-- 
2.19.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 07/15] mtd: rawnand: Fill memorg during detection
  2019-03-04 20:15 ` Miquel Raynal
@ 2019-03-04 20:15   ` Miquel Raynal
  -1 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

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>
---
 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;
-- 
2.19.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 07/15] mtd: rawnand: Fill memorg during detection
@ 2019-03-04 20:15   ` Miquel Raynal
  0 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

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>
---
 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;
-- 
2.19.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 08/15] mtd: rawnand: Initialize the nand_device object
  2019-03-04 20:15 ` Miquel Raynal
@ 2019-03-04 20:15   ` Miquel Raynal
  -1 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

In order to use some of the nanddev_xxx() helpers, we need to
initialize the nand_device object embedded in nand_chip using
nanddev_init(). This requires implementing nand_ops.

We also drop useless mtd->xxx initialization when they're already taken
case of by nanddev_init().

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/Kconfig     |  1 +
 drivers/mtd/nand/raw/nand_base.c | 65 ++++++++++++++++++++++++++++----
 2 files changed, 59 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index 1a55d3e3d4c5..8c38f2c116a2 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -14,6 +14,7 @@ menuconfig MTD_NAND
 	tristate "Raw/Parallel NAND Device Support"
 	depends on MTD
 	select MTD_NAND_ECC
+	select MTD_NAND_CORE
 	help
 	  This enables support for accessing all type of raw/parallel
 	  NAND flash devices. For further information see
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 5aba1cf38a4b..fea3f8b96558 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -5523,6 +5523,50 @@ static bool nand_ecc_strength_good(struct nand_chip *chip)
 	return corr >= ds_corr && ecc->strength >= chip->ecc_strength_ds;
 }
 
+static int rawnand_erase(struct nand_device *nand, const struct nand_pos *pos)
+{
+	struct nand_chip *chip = container_of(nand, struct nand_chip,
+					      base);
+	unsigned int eb = nanddev_pos_to_row(nand, pos);
+	int ret;
+
+	eb >>= nand->rowconv.eraseblock_addr_shift;
+
+	nand_select_target(chip, pos->target);
+	ret = nand_erase_op(chip, eb);
+	nand_deselect_target(chip);
+
+	return ret;
+}
+
+static int rawnand_markbad(struct nand_device *nand,
+			   const struct nand_pos *pos)
+{
+	struct nand_chip *chip = container_of(nand, struct nand_chip,
+					      base);
+
+	return nand_markbad_bbm(chip, nanddev_pos_to_offs(nand, pos));
+}
+
+static bool rawnand_isbad(struct nand_device *nand, const struct nand_pos *pos)
+{
+	struct nand_chip *chip = container_of(nand, struct nand_chip,
+					      base);
+	int ret;
+
+	nand_select_target(chip, pos->target);
+	ret = nand_isbad_bbm(chip, nanddev_pos_to_offs(nand, pos));
+	nand_deselect_target(chip);
+
+	return ret;
+}
+
+static const struct nand_ops rawnand_ops = {
+	.erase = rawnand_erase,
+	.markbad = rawnand_markbad,
+	.isbad = rawnand_isbad,
+};
+
 /**
  * nand_scan_tail - Scan for the NAND device
  * @chip: NAND chip object
@@ -5791,10 +5835,15 @@ static int nand_scan_tail(struct nand_chip *chip)
 		break;
 	}
 
+	ret = nanddev_init(&chip->base, &rawnand_ops, mtd->owner);
+	if (ret)
+		goto err_nand_manuf_cleanup;
+
+	/* Adjust the MTD_CAP_ flags when NAND_ROM is set. */
+	if (chip->options & NAND_ROM)
+		mtd->flags = MTD_CAP_ROM;
+
 	/* Fill in remaining MTD driver data */
-	mtd->type = nand_is_slc(chip) ? MTD_NANDFLASH : MTD_MLCNANDFLASH;
-	mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM :
-						MTD_CAP_NANDFLASH;
 	mtd->_erase = nand_erase;
 	mtd->_point = NULL;
 	mtd->_unpoint = NULL;
@@ -5811,7 +5860,6 @@ static int nand_scan_tail(struct nand_chip *chip)
 	mtd->_block_isbad = nand_block_isbad;
 	mtd->_block_markbad = nand_block_markbad;
 	mtd->_max_bad_blocks = nand_max_bad_blocks;
-	mtd->writebufsize = mtd->writesize;
 
 	/*
 	 * Initialize bitflip_threshold to its default prior scan_bbt() call.
@@ -5824,13 +5872,13 @@ static int nand_scan_tail(struct nand_chip *chip)
 	/* Initialize the ->data_interface field. */
 	ret = nand_init_data_interface(chip);
 	if (ret)
-		goto err_nand_manuf_cleanup;
+		goto err_nanddev_cleanup;
 
 	/* Enter fastest possible mode on all dies. */
 	for (i = 0; i < chip->numchips; i++) {
 		ret = nand_setup_data_interface(chip, i);
 		if (ret)
-			goto err_nand_manuf_cleanup;
+			goto err_nanddev_cleanup;
 	}
 
 	/* Check, if we should skip the bad block table scan */
@@ -5840,11 +5888,14 @@ static int nand_scan_tail(struct nand_chip *chip)
 	/* Build bad block table */
 	ret = nand_create_bbt(chip);
 	if (ret)
-		goto err_nand_manuf_cleanup;
+		goto err_nanddev_cleanup;
 
 	return 0;
 
 
+err_nanddev_cleanup:
+	nanddev_cleanup(&chip->base);
+
 err_nand_manuf_cleanup:
 	nand_manufacturer_cleanup(chip);
 
-- 
2.19.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 08/15] mtd: rawnand: Initialize the nand_device object
@ 2019-03-04 20:15   ` Miquel Raynal
  0 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

In order to use some of the nanddev_xxx() helpers, we need to
initialize the nand_device object embedded in nand_chip using
nanddev_init(). This requires implementing nand_ops.

We also drop useless mtd->xxx initialization when they're already taken
case of by nanddev_init().

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/Kconfig     |  1 +
 drivers/mtd/nand/raw/nand_base.c | 65 ++++++++++++++++++++++++++++----
 2 files changed, 59 insertions(+), 7 deletions(-)

diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index 1a55d3e3d4c5..8c38f2c116a2 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -14,6 +14,7 @@ menuconfig MTD_NAND
 	tristate "Raw/Parallel NAND Device Support"
 	depends on MTD
 	select MTD_NAND_ECC
+	select MTD_NAND_CORE
 	help
 	  This enables support for accessing all type of raw/parallel
 	  NAND flash devices. For further information see
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 5aba1cf38a4b..fea3f8b96558 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -5523,6 +5523,50 @@ static bool nand_ecc_strength_good(struct nand_chip *chip)
 	return corr >= ds_corr && ecc->strength >= chip->ecc_strength_ds;
 }
 
+static int rawnand_erase(struct nand_device *nand, const struct nand_pos *pos)
+{
+	struct nand_chip *chip = container_of(nand, struct nand_chip,
+					      base);
+	unsigned int eb = nanddev_pos_to_row(nand, pos);
+	int ret;
+
+	eb >>= nand->rowconv.eraseblock_addr_shift;
+
+	nand_select_target(chip, pos->target);
+	ret = nand_erase_op(chip, eb);
+	nand_deselect_target(chip);
+
+	return ret;
+}
+
+static int rawnand_markbad(struct nand_device *nand,
+			   const struct nand_pos *pos)
+{
+	struct nand_chip *chip = container_of(nand, struct nand_chip,
+					      base);
+
+	return nand_markbad_bbm(chip, nanddev_pos_to_offs(nand, pos));
+}
+
+static bool rawnand_isbad(struct nand_device *nand, const struct nand_pos *pos)
+{
+	struct nand_chip *chip = container_of(nand, struct nand_chip,
+					      base);
+	int ret;
+
+	nand_select_target(chip, pos->target);
+	ret = nand_isbad_bbm(chip, nanddev_pos_to_offs(nand, pos));
+	nand_deselect_target(chip);
+
+	return ret;
+}
+
+static const struct nand_ops rawnand_ops = {
+	.erase = rawnand_erase,
+	.markbad = rawnand_markbad,
+	.isbad = rawnand_isbad,
+};
+
 /**
  * nand_scan_tail - Scan for the NAND device
  * @chip: NAND chip object
@@ -5791,10 +5835,15 @@ static int nand_scan_tail(struct nand_chip *chip)
 		break;
 	}
 
+	ret = nanddev_init(&chip->base, &rawnand_ops, mtd->owner);
+	if (ret)
+		goto err_nand_manuf_cleanup;
+
+	/* Adjust the MTD_CAP_ flags when NAND_ROM is set. */
+	if (chip->options & NAND_ROM)
+		mtd->flags = MTD_CAP_ROM;
+
 	/* Fill in remaining MTD driver data */
-	mtd->type = nand_is_slc(chip) ? MTD_NANDFLASH : MTD_MLCNANDFLASH;
-	mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM :
-						MTD_CAP_NANDFLASH;
 	mtd->_erase = nand_erase;
 	mtd->_point = NULL;
 	mtd->_unpoint = NULL;
@@ -5811,7 +5860,6 @@ static int nand_scan_tail(struct nand_chip *chip)
 	mtd->_block_isbad = nand_block_isbad;
 	mtd->_block_markbad = nand_block_markbad;
 	mtd->_max_bad_blocks = nand_max_bad_blocks;
-	mtd->writebufsize = mtd->writesize;
 
 	/*
 	 * Initialize bitflip_threshold to its default prior scan_bbt() call.
@@ -5824,13 +5872,13 @@ static int nand_scan_tail(struct nand_chip *chip)
 	/* Initialize the ->data_interface field. */
 	ret = nand_init_data_interface(chip);
 	if (ret)
-		goto err_nand_manuf_cleanup;
+		goto err_nanddev_cleanup;
 
 	/* Enter fastest possible mode on all dies. */
 	for (i = 0; i < chip->numchips; i++) {
 		ret = nand_setup_data_interface(chip, i);
 		if (ret)
-			goto err_nand_manuf_cleanup;
+			goto err_nanddev_cleanup;
 	}
 
 	/* Check, if we should skip the bad block table scan */
@@ -5840,11 +5888,14 @@ static int nand_scan_tail(struct nand_chip *chip)
 	/* Build bad block table */
 	ret = nand_create_bbt(chip);
 	if (ret)
-		goto err_nand_manuf_cleanup;
+		goto err_nanddev_cleanup;
 
 	return 0;
 
 
+err_nanddev_cleanup:
+	nanddev_cleanup(&chip->base);
+
 err_nand_manuf_cleanup:
 	nand_manufacturer_cleanup(chip);
 
-- 
2.19.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 09/15] mtd: rawnand: Provide a helper to get chip->data_buf
  2019-03-04 20:15 ` Miquel Raynal
@ 2019-03-04 20:15   ` Miquel Raynal
  -1 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

We plan to move cache related fields to a pagecache struct in nand_chip
but some drivers access ->pagebuf directly to invalidate the cache
before they start using ->data_buf.

Let's provide an helper that returns a pointer to ->data_buf after
invalidating the cache.

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/brcmnand/brcmnand.c   |  7 +---
 drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c |  4 +-
 drivers/mtd/nand/raw/marvell_nand.c        | 43 +++++++++-------------
 drivers/mtd/nand/raw/nand_base.c           |  7 ++--
 drivers/mtd/nand/raw/nand_bbt.c            |  4 +-
 drivers/mtd/nand/raw/qcom_nandc.c          |  8 ++--
 drivers/mtd/nand/raw/sunxi_nand.c          | 11 +++---
 include/linux/mtd/rawnand.h                | 21 +++++++++++
 8 files changed, 56 insertions(+), 49 deletions(-)

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 482c6f093f99..ce0b8ffc7812 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -1676,11 +1676,8 @@ static int brcmstb_nand_verify_erased_page(struct mtd_info *mtd,
 	int page = addr >> chip->page_shift;
 	int ret;
 
-	if (!buf) {
-		buf = chip->data_buf;
-		/* Invalidate page cache */
-		chip->pagebuf = -1;
-	}
+	if (!buf)
+		buf = nand_get_data_buf(chip);
 
 	sas = mtd->oobsize / chip->ecc.steps;
 
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
index ed405c9434fe..05f6f68e4e0d 100644
--- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
@@ -1602,7 +1602,7 @@ static int mx23_check_transcription_stamp(struct gpmi_nand_data *this)
 	unsigned int search_area_size_in_strides;
 	unsigned int stride;
 	unsigned int page;
-	uint8_t *buffer = chip->data_buf;
+	u8 *buffer = nand_get_data_buf(chip);
 	int saved_chip_number;
 	int found_an_ncb_fingerprint = false;
 
@@ -1664,7 +1664,7 @@ static int mx23_write_transcription_stamp(struct gpmi_nand_data *this)
 	unsigned int block;
 	unsigned int stride;
 	unsigned int page;
-	uint8_t      *buffer = chip->data_buf;
+	u8 *buffer = nand_get_data_buf(chip);
 	int saved_chip_number;
 	int status;
 
diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c
index 84283c6bb0ff..e8023b32be93 100644
--- a/drivers/mtd/nand/raw/marvell_nand.c
+++ b/drivers/mtd/nand/raw/marvell_nand.c
@@ -1083,12 +1083,11 @@ static int marvell_nfc_hw_ecc_hmg_read_page(struct nand_chip *chip, u8 *buf,
  */
 static int marvell_nfc_hw_ecc_hmg_read_oob_raw(struct nand_chip *chip, int page)
 {
-	/* Invalidate page cache */
-	chip->pagebuf = -1;
+	u8 *buf = nand_get_data_buf(chip);
 
 	marvell_nfc_select_target(chip, chip->cur_cs);
-	return marvell_nfc_hw_ecc_hmg_do_read_page(chip, chip->data_buf,
-						   chip->oob_poi, true, page);
+	return marvell_nfc_hw_ecc_hmg_do_read_page(chip, buf, chip->oob_poi,
+						   true, page);
 }
 
 /* Hamming write helpers */
@@ -1179,15 +1178,13 @@ static int marvell_nfc_hw_ecc_hmg_write_oob_raw(struct nand_chip *chip,
 						int page)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
+	u8 *buf = nand_get_data_buf(chip);
 
-	/* Invalidate page cache */
-	chip->pagebuf = -1;
-
-	memset(chip->data_buf, 0xFF, mtd->writesize);
+	memset(buf, 0xFF, mtd->writesize);
 
 	marvell_nfc_select_target(chip, chip->cur_cs);
-	return marvell_nfc_hw_ecc_hmg_do_write_page(chip, chip->data_buf,
-						    chip->oob_poi, true, page);
+	return marvell_nfc_hw_ecc_hmg_do_write_page(chip, buf, chip->oob_poi,
+						    true, page);
 }
 
 /* BCH read helpers */
@@ -1434,18 +1431,16 @@ static int marvell_nfc_hw_ecc_bch_read_page(struct nand_chip *chip,
 
 static int marvell_nfc_hw_ecc_bch_read_oob_raw(struct nand_chip *chip, int page)
 {
-	/* Invalidate page cache */
-	chip->pagebuf = -1;
+	u8 *buf = nand_get_data_buf(chip);
 
-	return chip->ecc.read_page_raw(chip, chip->data_buf, true, page);
+	return chip->ecc.read_page_raw(chip, buf, true, page);
 }
 
 static int marvell_nfc_hw_ecc_bch_read_oob(struct nand_chip *chip, int page)
 {
-	/* Invalidate page cache */
-	chip->pagebuf = -1;
+	u8 *buf = nand_get_data_buf(chip);
 
-	return chip->ecc.read_page(chip, chip->data_buf, true, page);
+	return chip->ecc.read_page(chip, buf, true, page);
 }
 
 /* BCH write helpers */
@@ -1619,25 +1614,21 @@ static int marvell_nfc_hw_ecc_bch_write_oob_raw(struct nand_chip *chip,
 						int page)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
+	u8 *buf = nand_get_data_buf(chip);
 
-	/* Invalidate page cache */
-	chip->pagebuf = -1;
+	memset(buf, 0xFF, mtd->writesize);
 
-	memset(chip->data_buf, 0xFF, mtd->writesize);
-
-	return chip->ecc.write_page_raw(chip, chip->data_buf, true, page);
+	return chip->ecc.write_page_raw(chip, buf, true, page);
 }
 
 static int marvell_nfc_hw_ecc_bch_write_oob(struct nand_chip *chip, int page)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
+	u8 *buf = nand_get_data_buf(chip);
 
-	/* Invalidate page cache */
-	chip->pagebuf = -1;
+	memset(buf, 0xFF, mtd->writesize);
 
-	memset(chip->data_buf, 0xFF, mtd->writesize);
-
-	return chip->ecc.write_page(chip, chip->data_buf, true, page);
+	return chip->ecc.write_page(chip, buf, true, page);
 }
 
 /* NAND framework ->exec_op() hooks and related helpers */
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index fea3f8b96558..4b10652b0b97 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -4033,10 +4033,9 @@ static int nand_do_write_ops(struct nand_chip *chip, loff_t to,
 					 __func__, buf);
 			if (part_pagewr)
 				bytes = min_t(int, bytes - column, writelen);
-			chip->pagebuf = -1;
-			memset(chip->data_buf, 0xff, mtd->writesize);
-			memcpy(&chip->data_buf[column], buf, bytes);
-			wbuf = chip->data_buf;
+			wbuf = nand_get_data_buf(chip);
+			memset(wbuf, 0xff, mtd->writesize);
+			memcpy(&wbuf[column], buf, bytes);
 		}
 
 		if (unlikely(oob)) {
diff --git a/drivers/mtd/nand/raw/nand_bbt.c b/drivers/mtd/nand/raw/nand_bbt.c
index 1b722fe9213c..0b96c4cab967 100644
--- a/drivers/mtd/nand/raw/nand_bbt.c
+++ b/drivers/mtd/nand/raw/nand_bbt.c
@@ -901,7 +901,9 @@ static int write_bbt(struct nand_chip *this, uint8_t *buf,
 static inline int nand_memory_bbt(struct nand_chip *this,
 				  struct nand_bbt_descr *bd)
 {
-	return create_bbt(this, this->data_buf, bd, -1);
+	u8 *pagebuf = nand_get_data_buf(this);
+
+	return create_bbt(this, pagebuf, bd, -1);
 }
 
 /**
diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
index 46c62a31fa46..3f8005113fe2 100644
--- a/drivers/mtd/nand/raw/qcom_nandc.c
+++ b/drivers/mtd/nand/raw/qcom_nandc.c
@@ -1680,14 +1680,12 @@ check_for_erased_page(struct qcom_nand_host *host, u8 *data_buf,
 	u8 *cw_data_buf, *cw_oob_buf;
 	int cw, data_size, oob_size, ret = 0;
 
-	if (!data_buf) {
-		data_buf = chip->data_buf;
-		chip->pagebuf = -1;
-	}
+	if (!data_buf)
+		data_buf = nand_get_data_buf(chip);
 
 	if (!oob_buf) {
+		nand_get_data_buf(chip);
 		oob_buf = chip->oob_poi;
-		chip->pagebuf = -1;
 	}
 
 	for_each_set_bit(cw, &uncorrectable_cws, ecc->steps) {
diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c
index e828ee50a201..d5de0a7114bc 100644
--- a/drivers/mtd/nand/raw/sunxi_nand.c
+++ b/drivers/mtd/nand/raw/sunxi_nand.c
@@ -1426,20 +1426,19 @@ static int sunxi_nfc_hw_ecc_write_page_dma(struct nand_chip *chip,
 
 static int sunxi_nfc_hw_ecc_read_oob(struct nand_chip *chip, int page)
 {
-	chip->pagebuf = -1;
+	u8 *buf = nand_get_data_buf(chip);
 
-	return chip->ecc.read_page(chip, chip->data_buf, 1, page);
+	return chip->ecc.read_page(chip, buf, 1, page);
 }
 
 static int sunxi_nfc_hw_ecc_write_oob(struct nand_chip *chip, int page)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
+	u8 *buf = nand_get_data_buf(chip);
 	int ret;
 
-	chip->pagebuf = -1;
-
-	memset(chip->data_buf, 0xff, mtd->writesize);
-	ret = chip->ecc.write_page(chip, chip->data_buf, 1, page);
+	memset(buf, 0xff, mtd->writesize);
+	ret = chip->ecc.write_page(chip, buf, 1, page);
 	if (ret)
 		return ret;
 
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index dfeedfe2f3e0..e62c3ab4e0f7 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -1358,4 +1358,25 @@ int nand_gpio_waitrdy(struct nand_chip *chip, struct gpio_desc *gpiod,
 void nand_select_target(struct nand_chip *chip, unsigned int cs);
 void nand_deselect_target(struct nand_chip *chip);
 
+/**
+ * nand_get_data_buf() - Get the internal page buffer
+ * @chip: NAND chip object
+ *
+ * Returns the pre-allocated page buffer after invalidating the cache. This
+ * function should be used by drivers that do not want to allocate their own
+ * bounce buffer and still need such a buffer for specific operations (most
+ * commonly when reading OOB data only).
+ *
+ * Be careful to never call this function in the write/write_oob path, because
+ * the core may have placed the data to be written out in this buffer.
+ *
+ * Return: pointer to the page cache buffer
+ */
+static inline void *nand_get_data_buf(struct nand_chip *chip)
+{
+	chip->pagebuf = -1;
+
+	return chip->data_buf;
+}
+
 #endif /* __LINUX_MTD_RAWNAND_H */
-- 
2.19.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 09/15] mtd: rawnand: Provide a helper to get chip->data_buf
@ 2019-03-04 20:15   ` Miquel Raynal
  0 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

We plan to move cache related fields to a pagecache struct in nand_chip
but some drivers access ->pagebuf directly to invalidate the cache
before they start using ->data_buf.

Let's provide an helper that returns a pointer to ->data_buf after
invalidating the cache.

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/brcmnand/brcmnand.c   |  7 +---
 drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c |  4 +-
 drivers/mtd/nand/raw/marvell_nand.c        | 43 +++++++++-------------
 drivers/mtd/nand/raw/nand_base.c           |  7 ++--
 drivers/mtd/nand/raw/nand_bbt.c            |  4 +-
 drivers/mtd/nand/raw/qcom_nandc.c          |  8 ++--
 drivers/mtd/nand/raw/sunxi_nand.c          | 11 +++---
 include/linux/mtd/rawnand.h                | 21 +++++++++++
 8 files changed, 56 insertions(+), 49 deletions(-)

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 482c6f093f99..ce0b8ffc7812 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -1676,11 +1676,8 @@ static int brcmstb_nand_verify_erased_page(struct mtd_info *mtd,
 	int page = addr >> chip->page_shift;
 	int ret;
 
-	if (!buf) {
-		buf = chip->data_buf;
-		/* Invalidate page cache */
-		chip->pagebuf = -1;
-	}
+	if (!buf)
+		buf = nand_get_data_buf(chip);
 
 	sas = mtd->oobsize / chip->ecc.steps;
 
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
index ed405c9434fe..05f6f68e4e0d 100644
--- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
@@ -1602,7 +1602,7 @@ static int mx23_check_transcription_stamp(struct gpmi_nand_data *this)
 	unsigned int search_area_size_in_strides;
 	unsigned int stride;
 	unsigned int page;
-	uint8_t *buffer = chip->data_buf;
+	u8 *buffer = nand_get_data_buf(chip);
 	int saved_chip_number;
 	int found_an_ncb_fingerprint = false;
 
@@ -1664,7 +1664,7 @@ static int mx23_write_transcription_stamp(struct gpmi_nand_data *this)
 	unsigned int block;
 	unsigned int stride;
 	unsigned int page;
-	uint8_t      *buffer = chip->data_buf;
+	u8 *buffer = nand_get_data_buf(chip);
 	int saved_chip_number;
 	int status;
 
diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c
index 84283c6bb0ff..e8023b32be93 100644
--- a/drivers/mtd/nand/raw/marvell_nand.c
+++ b/drivers/mtd/nand/raw/marvell_nand.c
@@ -1083,12 +1083,11 @@ static int marvell_nfc_hw_ecc_hmg_read_page(struct nand_chip *chip, u8 *buf,
  */
 static int marvell_nfc_hw_ecc_hmg_read_oob_raw(struct nand_chip *chip, int page)
 {
-	/* Invalidate page cache */
-	chip->pagebuf = -1;
+	u8 *buf = nand_get_data_buf(chip);
 
 	marvell_nfc_select_target(chip, chip->cur_cs);
-	return marvell_nfc_hw_ecc_hmg_do_read_page(chip, chip->data_buf,
-						   chip->oob_poi, true, page);
+	return marvell_nfc_hw_ecc_hmg_do_read_page(chip, buf, chip->oob_poi,
+						   true, page);
 }
 
 /* Hamming write helpers */
@@ -1179,15 +1178,13 @@ static int marvell_nfc_hw_ecc_hmg_write_oob_raw(struct nand_chip *chip,
 						int page)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
+	u8 *buf = nand_get_data_buf(chip);
 
-	/* Invalidate page cache */
-	chip->pagebuf = -1;
-
-	memset(chip->data_buf, 0xFF, mtd->writesize);
+	memset(buf, 0xFF, mtd->writesize);
 
 	marvell_nfc_select_target(chip, chip->cur_cs);
-	return marvell_nfc_hw_ecc_hmg_do_write_page(chip, chip->data_buf,
-						    chip->oob_poi, true, page);
+	return marvell_nfc_hw_ecc_hmg_do_write_page(chip, buf, chip->oob_poi,
+						    true, page);
 }
 
 /* BCH read helpers */
@@ -1434,18 +1431,16 @@ static int marvell_nfc_hw_ecc_bch_read_page(struct nand_chip *chip,
 
 static int marvell_nfc_hw_ecc_bch_read_oob_raw(struct nand_chip *chip, int page)
 {
-	/* Invalidate page cache */
-	chip->pagebuf = -1;
+	u8 *buf = nand_get_data_buf(chip);
 
-	return chip->ecc.read_page_raw(chip, chip->data_buf, true, page);
+	return chip->ecc.read_page_raw(chip, buf, true, page);
 }
 
 static int marvell_nfc_hw_ecc_bch_read_oob(struct nand_chip *chip, int page)
 {
-	/* Invalidate page cache */
-	chip->pagebuf = -1;
+	u8 *buf = nand_get_data_buf(chip);
 
-	return chip->ecc.read_page(chip, chip->data_buf, true, page);
+	return chip->ecc.read_page(chip, buf, true, page);
 }
 
 /* BCH write helpers */
@@ -1619,25 +1614,21 @@ static int marvell_nfc_hw_ecc_bch_write_oob_raw(struct nand_chip *chip,
 						int page)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
+	u8 *buf = nand_get_data_buf(chip);
 
-	/* Invalidate page cache */
-	chip->pagebuf = -1;
+	memset(buf, 0xFF, mtd->writesize);
 
-	memset(chip->data_buf, 0xFF, mtd->writesize);
-
-	return chip->ecc.write_page_raw(chip, chip->data_buf, true, page);
+	return chip->ecc.write_page_raw(chip, buf, true, page);
 }
 
 static int marvell_nfc_hw_ecc_bch_write_oob(struct nand_chip *chip, int page)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
+	u8 *buf = nand_get_data_buf(chip);
 
-	/* Invalidate page cache */
-	chip->pagebuf = -1;
+	memset(buf, 0xFF, mtd->writesize);
 
-	memset(chip->data_buf, 0xFF, mtd->writesize);
-
-	return chip->ecc.write_page(chip, chip->data_buf, true, page);
+	return chip->ecc.write_page(chip, buf, true, page);
 }
 
 /* NAND framework ->exec_op() hooks and related helpers */
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index fea3f8b96558..4b10652b0b97 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -4033,10 +4033,9 @@ static int nand_do_write_ops(struct nand_chip *chip, loff_t to,
 					 __func__, buf);
 			if (part_pagewr)
 				bytes = min_t(int, bytes - column, writelen);
-			chip->pagebuf = -1;
-			memset(chip->data_buf, 0xff, mtd->writesize);
-			memcpy(&chip->data_buf[column], buf, bytes);
-			wbuf = chip->data_buf;
+			wbuf = nand_get_data_buf(chip);
+			memset(wbuf, 0xff, mtd->writesize);
+			memcpy(&wbuf[column], buf, bytes);
 		}
 
 		if (unlikely(oob)) {
diff --git a/drivers/mtd/nand/raw/nand_bbt.c b/drivers/mtd/nand/raw/nand_bbt.c
index 1b722fe9213c..0b96c4cab967 100644
--- a/drivers/mtd/nand/raw/nand_bbt.c
+++ b/drivers/mtd/nand/raw/nand_bbt.c
@@ -901,7 +901,9 @@ static int write_bbt(struct nand_chip *this, uint8_t *buf,
 static inline int nand_memory_bbt(struct nand_chip *this,
 				  struct nand_bbt_descr *bd)
 {
-	return create_bbt(this, this->data_buf, bd, -1);
+	u8 *pagebuf = nand_get_data_buf(this);
+
+	return create_bbt(this, pagebuf, bd, -1);
 }
 
 /**
diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
index 46c62a31fa46..3f8005113fe2 100644
--- a/drivers/mtd/nand/raw/qcom_nandc.c
+++ b/drivers/mtd/nand/raw/qcom_nandc.c
@@ -1680,14 +1680,12 @@ check_for_erased_page(struct qcom_nand_host *host, u8 *data_buf,
 	u8 *cw_data_buf, *cw_oob_buf;
 	int cw, data_size, oob_size, ret = 0;
 
-	if (!data_buf) {
-		data_buf = chip->data_buf;
-		chip->pagebuf = -1;
-	}
+	if (!data_buf)
+		data_buf = nand_get_data_buf(chip);
 
 	if (!oob_buf) {
+		nand_get_data_buf(chip);
 		oob_buf = chip->oob_poi;
-		chip->pagebuf = -1;
 	}
 
 	for_each_set_bit(cw, &uncorrectable_cws, ecc->steps) {
diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c
index e828ee50a201..d5de0a7114bc 100644
--- a/drivers/mtd/nand/raw/sunxi_nand.c
+++ b/drivers/mtd/nand/raw/sunxi_nand.c
@@ -1426,20 +1426,19 @@ static int sunxi_nfc_hw_ecc_write_page_dma(struct nand_chip *chip,
 
 static int sunxi_nfc_hw_ecc_read_oob(struct nand_chip *chip, int page)
 {
-	chip->pagebuf = -1;
+	u8 *buf = nand_get_data_buf(chip);
 
-	return chip->ecc.read_page(chip, chip->data_buf, 1, page);
+	return chip->ecc.read_page(chip, buf, 1, page);
 }
 
 static int sunxi_nfc_hw_ecc_write_oob(struct nand_chip *chip, int page)
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
+	u8 *buf = nand_get_data_buf(chip);
 	int ret;
 
-	chip->pagebuf = -1;
-
-	memset(chip->data_buf, 0xff, mtd->writesize);
-	ret = chip->ecc.write_page(chip, chip->data_buf, 1, page);
+	memset(buf, 0xff, mtd->writesize);
+	ret = chip->ecc.write_page(chip, buf, 1, page);
 	if (ret)
 		return ret;
 
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index dfeedfe2f3e0..e62c3ab4e0f7 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -1358,4 +1358,25 @@ int nand_gpio_waitrdy(struct nand_chip *chip, struct gpio_desc *gpiod,
 void nand_select_target(struct nand_chip *chip, unsigned int cs);
 void nand_deselect_target(struct nand_chip *chip);
 
+/**
+ * nand_get_data_buf() - Get the internal page buffer
+ * @chip: NAND chip object
+ *
+ * Returns the pre-allocated page buffer after invalidating the cache. This
+ * function should be used by drivers that do not want to allocate their own
+ * bounce buffer and still need such a buffer for specific operations (most
+ * commonly when reading OOB data only).
+ *
+ * Be careful to never call this function in the write/write_oob path, because
+ * the core may have placed the data to be written out in this buffer.
+ *
+ * Return: pointer to the page cache buffer
+ */
+static inline void *nand_get_data_buf(struct nand_chip *chip)
+{
+	chip->pagebuf = -1;
+
+	return chip->data_buf;
+}
+
 #endif /* __LINUX_MTD_RAWNAND_H */
-- 
2.19.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 10/15] mtd: rawnand: Move all page cache related fields to a sub-struct
  2019-03-04 20:15 ` Miquel Raynal
@ 2019-03-04 20:15   ` Miquel Raynal
  -1 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

Looking at the field names it's hard to tell what ->data_buf, ->pagebuf
and ->pagebuf_bitflips are for. Clarify that by moving those fields
in a sub-struct named pagecache.

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/nand_base.c | 28 ++++++++++++++--------------
 include/linux/mtd/rawnand.h      | 18 +++++++++++-------
 2 files changed, 25 insertions(+), 21 deletions(-)

diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 4b10652b0b97..54d32ed57297 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -493,8 +493,8 @@ static int nand_do_write_oob(struct nand_chip *chip, loff_t to,
 	}
 
 	/* Invalidate the page cache, if we write to the cached page */
-	if (page == chip->pagebuf)
-		chip->pagebuf = -1;
+	if (page == chip->pagecache.page)
+		chip->pagecache.page = -1;
 
 	nand_fill_oob(chip, ops->oobbuf, ops->ooblen, ops);
 
@@ -3204,7 +3204,7 @@ static int nand_do_read_ops(struct nand_chip *chip, loff_t from,
 			use_bufpoi = 0;
 
 		/* Is the current page in the buffer? */
-		if (realpage != chip->pagebuf || oob) {
+		if (realpage != chip->pagecache.page || oob) {
 			bufpoi = use_bufpoi ? chip->data_buf : buf;
 
 			if (use_bufpoi && aligned)
@@ -3230,7 +3230,7 @@ static int nand_do_read_ops(struct nand_chip *chip, loff_t from,
 			if (ret < 0) {
 				if (use_bufpoi)
 					/* Invalidate page cache */
-					chip->pagebuf = -1;
+					chip->pagecache.page = -1;
 				break;
 			}
 
@@ -3239,11 +3239,11 @@ static int nand_do_read_ops(struct nand_chip *chip, loff_t from,
 				if (!NAND_HAS_SUBPAGE_READ(chip) && !oob &&
 				    !(mtd->ecc_stats.failed - ecc_failures) &&
 				    (ops->mode != MTD_OPS_RAW)) {
-					chip->pagebuf = realpage;
-					chip->pagebuf_bitflips = ret;
+					chip->pagecache.page = realpage;
+					chip->pagecache.bitflips = ret;
 				} else {
 					/* Invalidate page cache */
-					chip->pagebuf = -1;
+					chip->pagecache.page = -1;
 				}
 				memcpy(buf, chip->data_buf + col, bytes);
 			}
@@ -3283,7 +3283,7 @@ static int nand_do_read_ops(struct nand_chip *chip, loff_t from,
 			memcpy(buf, chip->data_buf + col, bytes);
 			buf += bytes;
 			max_bitflips = max_t(unsigned int, max_bitflips,
-					     chip->pagebuf_bitflips);
+					     chip->pagecache.bitflips);
 		}
 
 		readlen -= bytes;
@@ -4002,9 +4002,9 @@ static int nand_do_write_ops(struct nand_chip *chip, loff_t to,
 	page = realpage & chip->pagemask;
 
 	/* Invalidate the page cache, when we write to the cached page */
-	if (to <= ((loff_t)chip->pagebuf << chip->page_shift) &&
-	    ((loff_t)chip->pagebuf << chip->page_shift) < (to + ops->len))
-		chip->pagebuf = -1;
+	if (to <= ((loff_t)chip->pagecache.page << chip->page_shift) &&
+	    ((loff_t)chip->pagecache.page << chip->page_shift) < (to + ops->len))
+		chip->pagecache.page = -1;
 
 	/* Don't allow multipage oob writes with offset */
 	if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen)) {
@@ -4241,9 +4241,9 @@ int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr,
 		 * Invalidate the page cache, if we erase the block which
 		 * contains the current cached page.
 		 */
-		if (page <= chip->pagebuf && chip->pagebuf <
+		if (page <= chip->pagecache.page && chip->pagecache.page <
 		    (page + pages_per_block))
-			chip->pagebuf = -1;
+			chip->pagecache.page = -1;
 
 		if (chip->legacy.erase)
 			status = chip->legacy.erase(chip,
@@ -5821,7 +5821,7 @@ static int nand_scan_tail(struct nand_chip *chip)
 	chip->state = FL_READY;
 
 	/* Invalidate the pagebuffer reference */
-	chip->pagebuf = -1;
+	chip->pagecache.page = -1;
 
 	/* Large page NAND with SOFT_ECC should support subpage reads */
 	switch (ecc->mode) {
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index e62c3ab4e0f7..00a8795b215d 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -1019,10 +1019,10 @@ struct nand_legacy {
  * @chipsize:		[INTERN] the size of one chip for multichip arrays
  * @pagemask:		[INTERN] page number mask = number of (pages / chip) - 1
  * @data_buf:		[INTERN] buffer for data, size is (page size + oobsize).
- * @pagebuf:		[INTERN] holds the pagenumber which is currently in
- *			data_buf.
- * @pagebuf_bitflips:	[INTERN] holds the bitflip count for the page which is
- *			currently in data_buf.
+ * @pagecache:		Structure containing page cache related fields
+ * @pagecache.bitflips:	Number of bitflips of the cached page
+ * @pagecache.page:	Page number currently in the cache. -1 means no page is
+ *			currently cached
  * @subpagesize:	[INTERN] holds the subpagesize
  * @id:			[INTERN] holds NAND ID
  * @parameters:		[INTERN] holds generic parameters under an easily
@@ -1069,8 +1069,12 @@ struct nand_chip {
 	uint64_t chipsize;
 	int pagemask;
 	u8 *data_buf;
-	int pagebuf;
-	unsigned int pagebuf_bitflips;
+
+	struct {
+		unsigned int bitflips;
+		int page;
+	} pagecache;
+
 	int subpagesize;
 	uint8_t bits_per_cell;
 	uint16_t ecc_strength_ds;
@@ -1374,7 +1378,7 @@ void nand_deselect_target(struct nand_chip *chip);
  */
 static inline void *nand_get_data_buf(struct nand_chip *chip)
 {
-	chip->pagebuf = -1;
+	chip->pagecache.page = -1;
 
 	return chip->data_buf;
 }
-- 
2.19.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 10/15] mtd: rawnand: Move all page cache related fields to a sub-struct
@ 2019-03-04 20:15   ` Miquel Raynal
  0 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

Looking at the field names it's hard to tell what ->data_buf, ->pagebuf
and ->pagebuf_bitflips are for. Clarify that by moving those fields
in a sub-struct named pagecache.

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/nand_base.c | 28 ++++++++++++++--------------
 include/linux/mtd/rawnand.h      | 18 +++++++++++-------
 2 files changed, 25 insertions(+), 21 deletions(-)

diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 4b10652b0b97..54d32ed57297 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -493,8 +493,8 @@ static int nand_do_write_oob(struct nand_chip *chip, loff_t to,
 	}
 
 	/* Invalidate the page cache, if we write to the cached page */
-	if (page == chip->pagebuf)
-		chip->pagebuf = -1;
+	if (page == chip->pagecache.page)
+		chip->pagecache.page = -1;
 
 	nand_fill_oob(chip, ops->oobbuf, ops->ooblen, ops);
 
@@ -3204,7 +3204,7 @@ static int nand_do_read_ops(struct nand_chip *chip, loff_t from,
 			use_bufpoi = 0;
 
 		/* Is the current page in the buffer? */
-		if (realpage != chip->pagebuf || oob) {
+		if (realpage != chip->pagecache.page || oob) {
 			bufpoi = use_bufpoi ? chip->data_buf : buf;
 
 			if (use_bufpoi && aligned)
@@ -3230,7 +3230,7 @@ static int nand_do_read_ops(struct nand_chip *chip, loff_t from,
 			if (ret < 0) {
 				if (use_bufpoi)
 					/* Invalidate page cache */
-					chip->pagebuf = -1;
+					chip->pagecache.page = -1;
 				break;
 			}
 
@@ -3239,11 +3239,11 @@ static int nand_do_read_ops(struct nand_chip *chip, loff_t from,
 				if (!NAND_HAS_SUBPAGE_READ(chip) && !oob &&
 				    !(mtd->ecc_stats.failed - ecc_failures) &&
 				    (ops->mode != MTD_OPS_RAW)) {
-					chip->pagebuf = realpage;
-					chip->pagebuf_bitflips = ret;
+					chip->pagecache.page = realpage;
+					chip->pagecache.bitflips = ret;
 				} else {
 					/* Invalidate page cache */
-					chip->pagebuf = -1;
+					chip->pagecache.page = -1;
 				}
 				memcpy(buf, chip->data_buf + col, bytes);
 			}
@@ -3283,7 +3283,7 @@ static int nand_do_read_ops(struct nand_chip *chip, loff_t from,
 			memcpy(buf, chip->data_buf + col, bytes);
 			buf += bytes;
 			max_bitflips = max_t(unsigned int, max_bitflips,
-					     chip->pagebuf_bitflips);
+					     chip->pagecache.bitflips);
 		}
 
 		readlen -= bytes;
@@ -4002,9 +4002,9 @@ static int nand_do_write_ops(struct nand_chip *chip, loff_t to,
 	page = realpage & chip->pagemask;
 
 	/* Invalidate the page cache, when we write to the cached page */
-	if (to <= ((loff_t)chip->pagebuf << chip->page_shift) &&
-	    ((loff_t)chip->pagebuf << chip->page_shift) < (to + ops->len))
-		chip->pagebuf = -1;
+	if (to <= ((loff_t)chip->pagecache.page << chip->page_shift) &&
+	    ((loff_t)chip->pagecache.page << chip->page_shift) < (to + ops->len))
+		chip->pagecache.page = -1;
 
 	/* Don't allow multipage oob writes with offset */
 	if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen)) {
@@ -4241,9 +4241,9 @@ int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr,
 		 * Invalidate the page cache, if we erase the block which
 		 * contains the current cached page.
 		 */
-		if (page <= chip->pagebuf && chip->pagebuf <
+		if (page <= chip->pagecache.page && chip->pagecache.page <
 		    (page + pages_per_block))
-			chip->pagebuf = -1;
+			chip->pagecache.page = -1;
 
 		if (chip->legacy.erase)
 			status = chip->legacy.erase(chip,
@@ -5821,7 +5821,7 @@ static int nand_scan_tail(struct nand_chip *chip)
 	chip->state = FL_READY;
 
 	/* Invalidate the pagebuffer reference */
-	chip->pagebuf = -1;
+	chip->pagecache.page = -1;
 
 	/* Large page NAND with SOFT_ECC should support subpage reads */
 	switch (ecc->mode) {
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index e62c3ab4e0f7..00a8795b215d 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -1019,10 +1019,10 @@ struct nand_legacy {
  * @chipsize:		[INTERN] the size of one chip for multichip arrays
  * @pagemask:		[INTERN] page number mask = number of (pages / chip) - 1
  * @data_buf:		[INTERN] buffer for data, size is (page size + oobsize).
- * @pagebuf:		[INTERN] holds the pagenumber which is currently in
- *			data_buf.
- * @pagebuf_bitflips:	[INTERN] holds the bitflip count for the page which is
- *			currently in data_buf.
+ * @pagecache:		Structure containing page cache related fields
+ * @pagecache.bitflips:	Number of bitflips of the cached page
+ * @pagecache.page:	Page number currently in the cache. -1 means no page is
+ *			currently cached
  * @subpagesize:	[INTERN] holds the subpagesize
  * @id:			[INTERN] holds NAND ID
  * @parameters:		[INTERN] holds generic parameters under an easily
@@ -1069,8 +1069,12 @@ struct nand_chip {
 	uint64_t chipsize;
 	int pagemask;
 	u8 *data_buf;
-	int pagebuf;
-	unsigned int pagebuf_bitflips;
+
+	struct {
+		unsigned int bitflips;
+		int page;
+	} pagecache;
+
 	int subpagesize;
 	uint8_t bits_per_cell;
 	uint16_t ecc_strength_ds;
@@ -1374,7 +1378,7 @@ void nand_deselect_target(struct nand_chip *chip);
  */
 static inline void *nand_get_data_buf(struct nand_chip *chip)
 {
-	chip->pagebuf = -1;
+	chip->pagecache.page = -1;
 
 	return chip->data_buf;
 }
-- 
2.19.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 11/15] mtd: rawnand: Use nanddev_mtd_max_bad_blocks()
  2019-03-04 20:15 ` Miquel Raynal
@ 2019-03-04 20:15   ` Miquel Raynal
  -1 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

nanddev_mtd_max_bad_blocks() is implemented by the generic NAND layer
and is already doing what we need. Reuse this function instead of
having our own implementation.

While at it, get rid of the ->max_bb_per_die and ->blocks_per_die
fields which are now unused.

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/nand_base.c | 38 +-------------------------------
 drivers/mtd/nand/raw/nand_onfi.c |  3 ---
 include/linux/mtd/rawnand.h      |  5 -----
 3 files changed, 1 insertion(+), 45 deletions(-)

diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 54d32ed57297..700b99a77789 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -4350,42 +4350,6 @@ static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
 	return nand_block_markbad_lowlevel(mtd_to_nand(mtd), ofs);
 }
 
-/**
- * nand_max_bad_blocks - [MTD Interface] Max number of bad blocks for an mtd
- * @mtd: MTD device structure
- * @ofs: offset relative to mtd start
- * @len: length of mtd
- */
-static int nand_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	u32 part_start_block;
-	u32 part_end_block;
-	u32 part_start_die;
-	u32 part_end_die;
-
-	/*
-	 * max_bb_per_die and blocks_per_die used to determine
-	 * the maximum bad block count.
-	 */
-	if (!chip->max_bb_per_die || !chip->blocks_per_die)
-		return -ENOTSUPP;
-
-	/* Get the start and end of the partition in erase blocks. */
-	part_start_block = mtd_div_by_eb(ofs, mtd);
-	part_end_block = mtd_div_by_eb(len, mtd) + part_start_block - 1;
-
-	/* Get the start and end LUNs of the partition. */
-	part_start_die = part_start_block / chip->blocks_per_die;
-	part_end_die = part_end_block / chip->blocks_per_die;
-
-	/*
-	 * Look up the bad blocks per unit and multiply by the number of units
-	 * that the partition spans.
-	 */
-	return chip->max_bb_per_die * (part_end_die - part_start_die + 1);
-}
-
 /**
  * nand_suspend - [MTD Interface] Suspend the NAND flash
  * @mtd: MTD device structure
@@ -5858,7 +5822,7 @@ static int nand_scan_tail(struct nand_chip *chip)
 	mtd->_block_isreserved = nand_block_isreserved;
 	mtd->_block_isbad = nand_block_isbad;
 	mtd->_block_markbad = nand_block_markbad;
-	mtd->_max_bad_blocks = nand_max_bad_blocks;
+	mtd->_max_bad_blocks = nanddev_mtd_max_bad_blocks;
 
 	/*
 	 * Initialize bitflip_threshold to its default prior scan_bbt() call.
diff --git a/drivers/mtd/nand/raw/nand_onfi.c b/drivers/mtd/nand/raw/nand_onfi.c
index f3f59cf37d7f..3ca9c8923a30 100644
--- a/drivers/mtd/nand/raw/nand_onfi.c
+++ b/drivers/mtd/nand/raw/nand_onfi.c
@@ -251,9 +251,6 @@ int nand_onfi_detect(struct nand_chip *chip)
 	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);
-	chip->blocks_per_die = le32_to_cpu(p->blocks_per_lun);
-
 	if (le16_to_cpu(p->features) & ONFI_FEATURE_16_BIT_BUS)
 		chip->options |= NAND_BUSWIDTH_16;
 
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index 00a8795b215d..d748e09de480 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -1027,9 +1027,6 @@ struct nand_legacy {
  * @id:			[INTERN] holds NAND ID
  * @parameters:		[INTERN] holds generic parameters under an easily
  *			readable form.
- * @max_bb_per_die:	[INTERN] the max number of bad blocks each die of a
- *			this nand device will encounter their life times.
- * @blocks_per_die:	[INTERN] The number of PEBs in a die
  * @data_interface:	[INTERN] NAND interface timing information
  * @cur_cs:		currently selected target. -1 means no target selected,
  *			otherwise we should always have cur_cs >= 0 &&
@@ -1085,8 +1082,6 @@ struct nand_chip {
 
 	struct nand_id id;
 	struct nand_parameters parameters;
-	u16 max_bb_per_die;
-	u32 blocks_per_die;
 
 	struct nand_data_interface data_interface;
 
-- 
2.19.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 11/15] mtd: rawnand: Use nanddev_mtd_max_bad_blocks()
@ 2019-03-04 20:15   ` Miquel Raynal
  0 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

nanddev_mtd_max_bad_blocks() is implemented by the generic NAND layer
and is already doing what we need. Reuse this function instead of
having our own implementation.

While at it, get rid of the ->max_bb_per_die and ->blocks_per_die
fields which are now unused.

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/nand_base.c | 38 +-------------------------------
 drivers/mtd/nand/raw/nand_onfi.c |  3 ---
 include/linux/mtd/rawnand.h      |  5 -----
 3 files changed, 1 insertion(+), 45 deletions(-)

diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 54d32ed57297..700b99a77789 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -4350,42 +4350,6 @@ static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs)
 	return nand_block_markbad_lowlevel(mtd_to_nand(mtd), ofs);
 }
 
-/**
- * nand_max_bad_blocks - [MTD Interface] Max number of bad blocks for an mtd
- * @mtd: MTD device structure
- * @ofs: offset relative to mtd start
- * @len: length of mtd
- */
-static int nand_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len)
-{
-	struct nand_chip *chip = mtd_to_nand(mtd);
-	u32 part_start_block;
-	u32 part_end_block;
-	u32 part_start_die;
-	u32 part_end_die;
-
-	/*
-	 * max_bb_per_die and blocks_per_die used to determine
-	 * the maximum bad block count.
-	 */
-	if (!chip->max_bb_per_die || !chip->blocks_per_die)
-		return -ENOTSUPP;
-
-	/* Get the start and end of the partition in erase blocks. */
-	part_start_block = mtd_div_by_eb(ofs, mtd);
-	part_end_block = mtd_div_by_eb(len, mtd) + part_start_block - 1;
-
-	/* Get the start and end LUNs of the partition. */
-	part_start_die = part_start_block / chip->blocks_per_die;
-	part_end_die = part_end_block / chip->blocks_per_die;
-
-	/*
-	 * Look up the bad blocks per unit and multiply by the number of units
-	 * that the partition spans.
-	 */
-	return chip->max_bb_per_die * (part_end_die - part_start_die + 1);
-}
-
 /**
  * nand_suspend - [MTD Interface] Suspend the NAND flash
  * @mtd: MTD device structure
@@ -5858,7 +5822,7 @@ static int nand_scan_tail(struct nand_chip *chip)
 	mtd->_block_isreserved = nand_block_isreserved;
 	mtd->_block_isbad = nand_block_isbad;
 	mtd->_block_markbad = nand_block_markbad;
-	mtd->_max_bad_blocks = nand_max_bad_blocks;
+	mtd->_max_bad_blocks = nanddev_mtd_max_bad_blocks;
 
 	/*
 	 * Initialize bitflip_threshold to its default prior scan_bbt() call.
diff --git a/drivers/mtd/nand/raw/nand_onfi.c b/drivers/mtd/nand/raw/nand_onfi.c
index f3f59cf37d7f..3ca9c8923a30 100644
--- a/drivers/mtd/nand/raw/nand_onfi.c
+++ b/drivers/mtd/nand/raw/nand_onfi.c
@@ -251,9 +251,6 @@ int nand_onfi_detect(struct nand_chip *chip)
 	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);
-	chip->blocks_per_die = le32_to_cpu(p->blocks_per_lun);
-
 	if (le16_to_cpu(p->features) & ONFI_FEATURE_16_BIT_BUS)
 		chip->options |= NAND_BUSWIDTH_16;
 
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index 00a8795b215d..d748e09de480 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -1027,9 +1027,6 @@ struct nand_legacy {
  * @id:			[INTERN] holds NAND ID
  * @parameters:		[INTERN] holds generic parameters under an easily
  *			readable form.
- * @max_bb_per_die:	[INTERN] the max number of bad blocks each die of a
- *			this nand device will encounter their life times.
- * @blocks_per_die:	[INTERN] The number of PEBs in a die
  * @data_interface:	[INTERN] NAND interface timing information
  * @cur_cs:		currently selected target. -1 means no target selected,
  *			otherwise we should always have cur_cs >= 0 &&
@@ -1085,8 +1082,6 @@ struct nand_chip {
 
 	struct nand_id id;
 	struct nand_parameters parameters;
-	u16 max_bb_per_die;
-	u32 blocks_per_die;
 
 	struct nand_data_interface data_interface;
 
-- 
2.19.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 12/15] mtd: rawnand: Get rid of chip->bits_per_cell
  2019-03-04 20:15 ` Miquel Raynal
@ 2019-03-04 20:15   ` Miquel Raynal
  -1 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

Now that we inherit from nand_device, we can use
nand_device->memorg.bits_per_cell instead of having our own field at
the nand_chip level.

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/nand_base.c   | 4 ----
 drivers/mtd/nand/raw/nand_hynix.c  | 2 +-
 drivers/mtd/nand/raw/nand_jedec.c  | 1 -
 drivers/mtd/nand/raw/nand_micron.c | 2 +-
 drivers/mtd/nand/raw/nand_onfi.c   | 1 -
 include/linux/mtd/rawnand.h        | 6 ++----
 6 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 700b99a77789..91fd508cf406 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -4502,7 +4502,6 @@ void nand_decode_ext_id(struct nand_chip *chip)
 
 	/* 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];
 
@@ -4546,7 +4545,6 @@ static void nand_decode_id(struct nand_chip *chip, struct nand_flash_dev *type)
 
 	/* All legacy ID NAND are small-page, SLC */
 	memorg->bits_per_cell = 1;
-	chip->bits_per_cell = 1;
 }
 
 /*
@@ -4589,7 +4587,6 @@ static bool find_full_id_nand(struct nand_chip *chip,
 		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,
@@ -4629,7 +4626,6 @@ static void nand_manufacturer_detect(struct nand_chip *chip)
 
 		/* 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 {
 		nand_decode_ext_id(chip);
diff --git a/drivers/mtd/nand/raw/nand_hynix.c b/drivers/mtd/nand/raw/nand_hynix.c
index 94ea8c593589..272b934dffb7 100644
--- a/drivers/mtd/nand/raw/nand_hynix.c
+++ b/drivers/mtd/nand/raw/nand_hynix.c
@@ -592,7 +592,7 @@ static void hynix_nand_extract_scrambling_requirements(struct nand_chip *chip,
 	u8 nand_tech;
 
 	/* We need scrambling on all TLC NANDs*/
-	if (chip->bits_per_cell > 2)
+	if (nanddev_bits_per_cell(&chip->base) > 2)
 		chip->options |= NAND_NEED_SCRAMBLING;
 
 	/* And on MLC NANDs with sub-3xnm process */
diff --git a/drivers/mtd/nand/raw/nand_jedec.c b/drivers/mtd/nand/raw/nand_jedec.c
index 61e33ee7ee19..030f178c7a97 100644
--- a/drivers/mtd/nand/raw/nand_jedec.c
+++ b/drivers/mtd/nand/raw/nand_jedec.c
@@ -104,7 +104,6 @@ int nand_jedec_detect(struct nand_chip *chip)
 	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)
 		chip->options |= NAND_BUSWIDTH_16;
diff --git a/drivers/mtd/nand/raw/nand_micron.c b/drivers/mtd/nand/raw/nand_micron.c
index b85e1c13b79e..98ce6575aa64 100644
--- a/drivers/mtd/nand/raw/nand_micron.c
+++ b/drivers/mtd/nand/raw/nand_micron.c
@@ -385,7 +385,7 @@ static int micron_supports_on_die_ecc(struct nand_chip *chip)
 	if (!chip->parameters.onfi)
 		return MICRON_ON_DIE_UNSUPPORTED;
 
-	if (chip->bits_per_cell != 1)
+	if (nanddev_bits_per_cell(&chip->base) != 1)
 		return MICRON_ON_DIE_UNSUPPORTED;
 
 	/*
diff --git a/drivers/mtd/nand/raw/nand_onfi.c b/drivers/mtd/nand/raw/nand_onfi.c
index 3ca9c8923a30..a6b9fc9a335b 100644
--- a/drivers/mtd/nand/raw/nand_onfi.c
+++ b/drivers/mtd/nand/raw/nand_onfi.c
@@ -249,7 +249,6 @@ int nand_onfi_detect(struct nand_chip *chip)
 	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) & ONFI_FEATURE_16_BIT_BUS)
 		chip->options |= NAND_BUSWIDTH_16;
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index d748e09de480..24ecd9a4f952 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -1004,7 +1004,6 @@ struct nand_legacy {
  * @badblockbits:	[INTERN] minimum number of set bits in a good block's
  *			bad block marker position; i.e., BBM == 11110111b is
  *			not bad when badblockbits == 7
- * @bits_per_cell:	[INTERN] number of bits per cell. i.e., 1 means SLC.
  * @ecc_strength_ds:	[INTERN] ECC correctability from the datasheet.
  *			Minimum amount of bit errors per @ecc_step_ds guaranteed
  *			to be correctable. If unknown, set to zero.
@@ -1073,7 +1072,6 @@ struct nand_chip {
 	} pagecache;
 
 	int subpagesize;
-	uint8_t bits_per_cell;
 	uint16_t ecc_strength_ds;
 	uint16_t ecc_step_ds;
 	int onfi_timing_mode_default;
@@ -1244,9 +1242,9 @@ int nand_create_bbt(struct nand_chip *chip);
  */
 static inline bool nand_is_slc(struct nand_chip *chip)
 {
-	WARN(chip->bits_per_cell == 0,
+	WARN(nanddev_bits_per_cell(&chip->base) == 0,
 	     "chip->bits_per_cell is used uninitialized\n");
-	return chip->bits_per_cell == 1;
+	return nanddev_bits_per_cell(&chip->base) == 1;
 }
 
 /**
-- 
2.19.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 12/15] mtd: rawnand: Get rid of chip->bits_per_cell
@ 2019-03-04 20:15   ` Miquel Raynal
  0 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

Now that we inherit from nand_device, we can use
nand_device->memorg.bits_per_cell instead of having our own field at
the nand_chip level.

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/nand_base.c   | 4 ----
 drivers/mtd/nand/raw/nand_hynix.c  | 2 +-
 drivers/mtd/nand/raw/nand_jedec.c  | 1 -
 drivers/mtd/nand/raw/nand_micron.c | 2 +-
 drivers/mtd/nand/raw/nand_onfi.c   | 1 -
 include/linux/mtd/rawnand.h        | 6 ++----
 6 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 700b99a77789..91fd508cf406 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -4502,7 +4502,6 @@ void nand_decode_ext_id(struct nand_chip *chip)
 
 	/* 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];
 
@@ -4546,7 +4545,6 @@ static void nand_decode_id(struct nand_chip *chip, struct nand_flash_dev *type)
 
 	/* All legacy ID NAND are small-page, SLC */
 	memorg->bits_per_cell = 1;
-	chip->bits_per_cell = 1;
 }
 
 /*
@@ -4589,7 +4587,6 @@ static bool find_full_id_nand(struct nand_chip *chip,
 		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,
@@ -4629,7 +4626,6 @@ static void nand_manufacturer_detect(struct nand_chip *chip)
 
 		/* 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 {
 		nand_decode_ext_id(chip);
diff --git a/drivers/mtd/nand/raw/nand_hynix.c b/drivers/mtd/nand/raw/nand_hynix.c
index 94ea8c593589..272b934dffb7 100644
--- a/drivers/mtd/nand/raw/nand_hynix.c
+++ b/drivers/mtd/nand/raw/nand_hynix.c
@@ -592,7 +592,7 @@ static void hynix_nand_extract_scrambling_requirements(struct nand_chip *chip,
 	u8 nand_tech;
 
 	/* We need scrambling on all TLC NANDs*/
-	if (chip->bits_per_cell > 2)
+	if (nanddev_bits_per_cell(&chip->base) > 2)
 		chip->options |= NAND_NEED_SCRAMBLING;
 
 	/* And on MLC NANDs with sub-3xnm process */
diff --git a/drivers/mtd/nand/raw/nand_jedec.c b/drivers/mtd/nand/raw/nand_jedec.c
index 61e33ee7ee19..030f178c7a97 100644
--- a/drivers/mtd/nand/raw/nand_jedec.c
+++ b/drivers/mtd/nand/raw/nand_jedec.c
@@ -104,7 +104,6 @@ int nand_jedec_detect(struct nand_chip *chip)
 	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)
 		chip->options |= NAND_BUSWIDTH_16;
diff --git a/drivers/mtd/nand/raw/nand_micron.c b/drivers/mtd/nand/raw/nand_micron.c
index b85e1c13b79e..98ce6575aa64 100644
--- a/drivers/mtd/nand/raw/nand_micron.c
+++ b/drivers/mtd/nand/raw/nand_micron.c
@@ -385,7 +385,7 @@ static int micron_supports_on_die_ecc(struct nand_chip *chip)
 	if (!chip->parameters.onfi)
 		return MICRON_ON_DIE_UNSUPPORTED;
 
-	if (chip->bits_per_cell != 1)
+	if (nanddev_bits_per_cell(&chip->base) != 1)
 		return MICRON_ON_DIE_UNSUPPORTED;
 
 	/*
diff --git a/drivers/mtd/nand/raw/nand_onfi.c b/drivers/mtd/nand/raw/nand_onfi.c
index 3ca9c8923a30..a6b9fc9a335b 100644
--- a/drivers/mtd/nand/raw/nand_onfi.c
+++ b/drivers/mtd/nand/raw/nand_onfi.c
@@ -249,7 +249,6 @@ int nand_onfi_detect(struct nand_chip *chip)
 	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) & ONFI_FEATURE_16_BIT_BUS)
 		chip->options |= NAND_BUSWIDTH_16;
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index d748e09de480..24ecd9a4f952 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -1004,7 +1004,6 @@ struct nand_legacy {
  * @badblockbits:	[INTERN] minimum number of set bits in a good block's
  *			bad block marker position; i.e., BBM == 11110111b is
  *			not bad when badblockbits == 7
- * @bits_per_cell:	[INTERN] number of bits per cell. i.e., 1 means SLC.
  * @ecc_strength_ds:	[INTERN] ECC correctability from the datasheet.
  *			Minimum amount of bit errors per @ecc_step_ds guaranteed
  *			to be correctable. If unknown, set to zero.
@@ -1073,7 +1072,6 @@ struct nand_chip {
 	} pagecache;
 
 	int subpagesize;
-	uint8_t bits_per_cell;
 	uint16_t ecc_strength_ds;
 	uint16_t ecc_step_ds;
 	int onfi_timing_mode_default;
@@ -1244,9 +1242,9 @@ int nand_create_bbt(struct nand_chip *chip);
  */
 static inline bool nand_is_slc(struct nand_chip *chip)
 {
-	WARN(chip->bits_per_cell == 0,
+	WARN(nanddev_bits_per_cell(&chip->base) == 0,
 	     "chip->bits_per_cell is used uninitialized\n");
-	return chip->bits_per_cell == 1;
+	return nanddev_bits_per_cell(&chip->base) == 1;
 }
 
 /**
-- 
2.19.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 13/15] mtd: rawnand: Get rid of chip->chipsize
  2019-03-04 20:15 ` Miquel Raynal
@ 2019-03-04 20:15   ` Miquel Raynal
  -1 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

The target size can now be returned by nanddev_get_targetsize(). Get
rid of the chip->chipsize field and use this helper instead.

Signed-off-by: Boris Brezillon <bbrezillon@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 .../mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c  |  2 +-
 drivers/mtd/nand/raw/denali.c                 |  1 -
 drivers/mtd/nand/raw/fsl_elbc_nand.c          |  2 +-
 drivers/mtd/nand/raw/fsl_ifc_nand.c           |  2 +-
 drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c    |  2 +-
 drivers/mtd/nand/raw/jz4740_nand.c            |  2 +-
 drivers/mtd/nand/raw/nand_base.c              | 17 ++++++-------
 drivers/mtd/nand/raw/nand_bbt.c               | 25 ++++++++++++-------
 drivers/mtd/nand/raw/nand_jedec.c             |  2 --
 drivers/mtd/nand/raw/nand_onfi.c              |  2 --
 drivers/mtd/nand/raw/nandsim.c                |  6 +++--
 drivers/mtd/nand/raw/sh_flctl.c               |  9 ++++---
 include/linux/mtd/rawnand.h                   |  2 --
 13 files changed, 38 insertions(+), 36 deletions(-)

diff --git a/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c b/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c
index a37cbfe56567..a53ffb3d64b0 100644
--- a/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c
+++ b/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c
@@ -428,7 +428,7 @@ int bcm47xxnflash_ops_bcm4706_init(struct bcm47xxnflash *b47n)
 	}
 
 	/* Configure FLASH */
-	chipsize = b47n->nand_chip.chipsize >> 20;
+	chipsize = nanddev_target_size(&b47n->nand_chip.base) >> 20;
 	tbits = ffs(chipsize); /* find first bit set */
 	if (!tbits || tbits != fls(chipsize)) {
 		pr_err("Invalid flash size: 0x%lX\n", chipsize);
diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c
index 86e5df403beb..3ec0242b0aa2 100644
--- a/drivers/mtd/nand/raw/denali.c
+++ b/drivers/mtd/nand/raw/denali.c
@@ -1157,7 +1157,6 @@ static int denali_multidev_fixup(struct denali_nand_info *denali)
 	mtd->erasesize <<= 1;
 	mtd->writesize <<= 1;
 	mtd->oobsize <<= 1;
-	chip->chipsize <<= 1;
 	chip->page_shift += 1;
 	chip->phys_erase_shift += 1;
 	chip->bbt_erase_shift += 1;
diff --git a/drivers/mtd/nand/raw/fsl_elbc_nand.c b/drivers/mtd/nand/raw/fsl_elbc_nand.c
index 70f0d2b450ea..1d960a6cd691 100644
--- a/drivers/mtd/nand/raw/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/raw/fsl_elbc_nand.c
@@ -655,7 +655,7 @@ static int fsl_elbc_attach_chip(struct nand_chip *chip)
 	dev_dbg(priv->dev, "fsl_elbc_init: nand->numchips = %d\n",
 	        chip->numchips);
 	dev_dbg(priv->dev, "fsl_elbc_init: nand->chipsize = %lld\n",
-	        chip->chipsize);
+	        nanddev_target_size(&chip->base));
 	dev_dbg(priv->dev, "fsl_elbc_init: nand->pagemask = %8x\n",
 	        chip->pagemask);
 	dev_dbg(priv->dev, "fsl_elbc_init: nand->legacy.chip_delay = %d\n",
diff --git a/drivers/mtd/nand/raw/fsl_ifc_nand.c b/drivers/mtd/nand/raw/fsl_ifc_nand.c
index e65d274399f9..a9e8f89aeebd 100644
--- a/drivers/mtd/nand/raw/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/raw/fsl_ifc_nand.c
@@ -724,7 +724,7 @@ static int fsl_ifc_attach_chip(struct nand_chip *chip)
 	dev_dbg(priv->dev, "%s: nand->numchips = %d\n", __func__,
 							chip->numchips);
 	dev_dbg(priv->dev, "%s: nand->chipsize = %lld\n", __func__,
-							chip->chipsize);
+	        nanddev_target_size(&chip->base));
 	dev_dbg(priv->dev, "%s: nand->pagemask = %8x\n", __func__,
 							chip->pagemask);
 	dev_dbg(priv->dev, "%s: nand->legacy.chip_delay = %d\n", __func__,
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
index 05f6f68e4e0d..6151214eddec 100644
--- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
@@ -1753,7 +1753,7 @@ static int mx23_boot_init(struct gpmi_nand_data  *this)
 	dev_dbg(dev, "Transcribing bad block marks...\n");
 
 	/* Compute the number of blocks in the entire medium. */
-	block_count = chip->chipsize >> chip->phys_erase_shift;
+	block_count = nanddev_eraseblocks_per_target(&chip->base);
 
 	/*
 	 * Loop over all the blocks in the medium, transcribing block marks as
diff --git a/drivers/mtd/nand/raw/jz4740_nand.c b/drivers/mtd/nand/raw/jz4740_nand.c
index 76a32ad2cf83..06690b3603b1 100644
--- a/drivers/mtd/nand/raw/jz4740_nand.c
+++ b/drivers/mtd/nand/raw/jz4740_nand.c
@@ -356,7 +356,7 @@ static int jz_nand_detect_bank(struct platform_device *pdev,
 		/* Update size of the MTD. */
 		chip->numchips++;
 		memorg->ntargets++;
-		mtd->size += chip->chipsize;
+		mtd->size += nanddev_target_size(&chip->base);
 	}
 
 	dev_info(&pdev->dev, "Found chip %zu on bank %i\n", chipnr, bank);
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 91fd508cf406..427c80abef3f 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -4587,7 +4587,6 @@ static bool find_full_id_nand(struct nand_chip *chip,
 		mtd->oobsize = memorg->oobsize;
 
 		memorg->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 *
@@ -4678,6 +4677,7 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
 	int busw, ret;
 	u8 *id_data = chip->id.data;
 	u8 maf_id, dev_id;
+	u64 targetsize;
 
 	/*
 	 * Let's start by initializing memorg fields that might be left
@@ -4782,8 +4782,6 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
 	if (!chip->parameters.model)
 		return -ENOMEM;
 
-	chip->chipsize = (uint64_t)type->chipsize << 20;
-
 	if (!type->pagesize)
 		nand_manufacturer_detect(chip);
 	else
@@ -4825,14 +4823,15 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
 	/* Calculate the address shift from the page size */
 	chip->page_shift = ffs(mtd->writesize) - 1;
 	/* Convert chipsize to number of pages per chip -1 */
-	chip->pagemask = (chip->chipsize >> chip->page_shift) - 1;
+	targetsize = nanddev_target_size(&chip->base);
+	chip->pagemask = (targetsize >> chip->page_shift) - 1;
 
 	chip->bbt_erase_shift = chip->phys_erase_shift =
 		ffs(mtd->erasesize) - 1;
-	if (chip->chipsize & 0xffffffff)
-		chip->chip_shift = ffs((unsigned)chip->chipsize) - 1;
+	if (targetsize & 0xffffffff)
+		chip->chip_shift = ffs((unsigned)targetsize) - 1;
 	else {
-		chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32));
+		chip->chip_shift = ffs((unsigned)(targetsize >> 32));
 		chip->chip_shift += 32 - 1;
 	}
 
@@ -4848,7 +4847,7 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
 	pr_info("%s %s\n", nand_manufacturer_name(manufacturer),
 		chip->parameters.model);
 	pr_info("%d MiB, %s, erase size: %d KiB, page size: %d, OOB size: %d\n",
-		(int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC",
+		(int)(targetsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC",
 		mtd->erasesize >> 10, mtd->writesize, mtd->oobsize);
 	return 0;
 
@@ -5093,7 +5092,7 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips,
 	/* Store the number of chips and calc total size for mtd */
 	memorg->ntargets = i;
 	chip->numchips = i;
-	mtd->size = i * chip->chipsize;
+	mtd->size = i * nanddev_target_size(&chip->base);
 
 	return 0;
 }
diff --git a/drivers/mtd/nand/raw/nand_bbt.c b/drivers/mtd/nand/raw/nand_bbt.c
index 0b96c4cab967..e3308857b2ee 100644
--- a/drivers/mtd/nand/raw/nand_bbt.c
+++ b/drivers/mtd/nand/raw/nand_bbt.c
@@ -264,6 +264,7 @@ static int read_abs_bbt(struct nand_chip *this, uint8_t *buf,
 			struct nand_bbt_descr *td, int chip)
 {
 	struct mtd_info *mtd = nand_to_mtd(this);
+	u64 targetsize = nanddev_target_size(&this->base);
 	int res = 0, i;
 
 	if (td->options & NAND_BBT_PERCHIP) {
@@ -271,11 +272,11 @@ static int read_abs_bbt(struct nand_chip *this, uint8_t *buf,
 		for (i = 0; i < this->numchips; i++) {
 			if (chip == -1 || chip == i)
 				res = read_bbt(this, buf, td->pages[i],
-					this->chipsize >> this->bbt_erase_shift,
+					targetsize >> this->bbt_erase_shift,
 					td, offs);
 			if (res)
 				return res;
-			offs += this->chipsize >> this->bbt_erase_shift;
+			offs += targetsize >> this->bbt_erase_shift;
 		}
 	} else {
 		res = read_bbt(this, buf, td->pages[0],
@@ -459,6 +460,7 @@ static int scan_block_fast(struct nand_chip *this, struct nand_bbt_descr *bd,
 static int create_bbt(struct nand_chip *this, uint8_t *buf,
 		      struct nand_bbt_descr *bd, int chip)
 {
+	u64 targetsize = nanddev_target_size(&this->base);
 	struct mtd_info *mtd = nand_to_mtd(this);
 	int i, numblocks, numpages;
 	int startblock;
@@ -481,7 +483,7 @@ static int create_bbt(struct nand_chip *this, uint8_t *buf,
 			       chip + 1, this->numchips);
 			return -EINVAL;
 		}
-		numblocks = this->chipsize >> this->bbt_erase_shift;
+		numblocks = targetsize >> this->bbt_erase_shift;
 		startblock = chip * numblocks;
 		numblocks += startblock;
 		from = (loff_t)startblock << this->bbt_erase_shift;
@@ -529,6 +531,7 @@ static int create_bbt(struct nand_chip *this, uint8_t *buf,
 static int search_bbt(struct nand_chip *this, uint8_t *buf,
 		      struct nand_bbt_descr *td)
 {
+	u64 targetsize = nanddev_target_size(&this->base);
 	struct mtd_info *mtd = nand_to_mtd(this);
 	int i, chips;
 	int startblock, block, dir;
@@ -548,7 +551,7 @@ static int search_bbt(struct nand_chip *this, uint8_t *buf,
 	/* Do we have a bbt per chip? */
 	if (td->options & NAND_BBT_PERCHIP) {
 		chips = this->numchips;
-		bbtblocks = this->chipsize >> this->bbt_erase_shift;
+		bbtblocks = targetsize >> this->bbt_erase_shift;
 		startblock &= bbtblocks - 1;
 	} else {
 		chips = 1;
@@ -576,7 +579,7 @@ static int search_bbt(struct nand_chip *this, uint8_t *buf,
 				break;
 			}
 		}
-		startblock += this->chipsize >> this->bbt_erase_shift;
+		startblock += targetsize >> this->bbt_erase_shift;
 	}
 	/* Check, if we found a bbt for each requested chip */
 	for (i = 0; i < chips; i++) {
@@ -626,6 +629,7 @@ static void search_read_bbts(struct nand_chip *this, uint8_t *buf,
 static int get_bbt_block(struct nand_chip *this, struct nand_bbt_descr *td,
 			 struct nand_bbt_descr *md, int chip)
 {
+	u64 targetsize = nanddev_target_size(&this->base);
 	int startblock, dir, page, numblocks, i;
 
 	/*
@@ -637,7 +641,7 @@ static int get_bbt_block(struct nand_chip *this, struct nand_bbt_descr *td,
 		return td->pages[chip] >>
 				(this->bbt_erase_shift - this->page_shift);
 
-	numblocks = (int)(this->chipsize >> this->bbt_erase_shift);
+	numblocks = (int)(targetsize >> this->bbt_erase_shift);
 	if (!(td->options & NAND_BBT_PERCHIP))
 		numblocks *= this->numchips;
 
@@ -717,6 +721,7 @@ static int write_bbt(struct nand_chip *this, uint8_t *buf,
 		     struct nand_bbt_descr *td, struct nand_bbt_descr *md,
 		     int chipsel)
 {
+	u64 targetsize = nanddev_target_size(&this->base);
 	struct mtd_info *mtd = nand_to_mtd(this);
 	struct erase_info einfo;
 	int i, res, chip = 0;
@@ -737,7 +742,7 @@ static int write_bbt(struct nand_chip *this, uint8_t *buf,
 		rcode = 0xff;
 	/* Write bad block table per chip rather than per device? */
 	if (td->options & NAND_BBT_PERCHIP) {
-		numblocks = (int)(this->chipsize >> this->bbt_erase_shift);
+		numblocks = (int)(targetsize >> this->bbt_erase_shift);
 		/* Full device write or specific chip? */
 		if (chipsel == -1) {
 			nrchips = this->numchips;
@@ -1099,6 +1104,7 @@ static int nand_update_bbt(struct nand_chip *this, loff_t offs)
  */
 static void mark_bbt_region(struct nand_chip *this, struct nand_bbt_descr *td)
 {
+	u64 targetsize = nanddev_target_size(&this->base);
 	struct mtd_info *mtd = nand_to_mtd(this);
 	int i, j, chips, block, nrblocks, update;
 	uint8_t oldval;
@@ -1106,7 +1112,7 @@ static void mark_bbt_region(struct nand_chip *this, struct nand_bbt_descr *td)
 	/* Do we have a bbt per chip? */
 	if (td->options & NAND_BBT_PERCHIP) {
 		chips = this->numchips;
-		nrblocks = (int)(this->chipsize >> this->bbt_erase_shift);
+		nrblocks = (int)(targetsize >> this->bbt_erase_shift);
 	} else {
 		chips = 1;
 		nrblocks = (int)(mtd->size >> this->bbt_erase_shift);
@@ -1159,6 +1165,7 @@ static void mark_bbt_region(struct nand_chip *this, struct nand_bbt_descr *td)
  */
 static void verify_bbt_descr(struct nand_chip *this, struct nand_bbt_descr *bd)
 {
+	u64 targetsize = nanddev_target_size(&this->base);
 	struct mtd_info *mtd = nand_to_mtd(this);
 	u32 pattern_len;
 	u32 bits;
@@ -1187,7 +1194,7 @@ static void verify_bbt_descr(struct nand_chip *this, struct nand_bbt_descr *bd)
 	}
 
 	if (bd->options & NAND_BBT_PERCHIP)
-		table_size = this->chipsize >> this->bbt_erase_shift;
+		table_size = targetsize >> this->bbt_erase_shift;
 	else
 		table_size = mtd->size >> this->bbt_erase_shift;
 	table_size >>= 3;
diff --git a/drivers/mtd/nand/raw/nand_jedec.c b/drivers/mtd/nand/raw/nand_jedec.c
index 030f178c7a97..99e2f017c79b 100644
--- a/drivers/mtd/nand/raw/nand_jedec.c
+++ b/drivers/mtd/nand/raw/nand_jedec.c
@@ -101,8 +101,6 @@ int nand_jedec_detect(struct nand_chip *chip)
 	/* Please reference to the comment for nand_flash_detect_onfi. */
 	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;
 
 	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 a6b9fc9a335b..7b468e7214c7 100644
--- a/drivers/mtd/nand/raw/nand_onfi.c
+++ b/drivers/mtd/nand/raw/nand_onfi.c
@@ -246,8 +246,6 @@ int nand_onfi_detect(struct nand_chip *chip)
 	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;
 
 	if (le16_to_cpu(p->features) & ONFI_FEATURE_16_BIT_BUS)
diff --git a/drivers/mtd/nand/raw/nandsim.c b/drivers/mtd/nand/raw/nandsim.c
index 07144c992d54..670abe8d59ca 100644
--- a/drivers/mtd/nand/raw/nandsim.c
+++ b/drivers/mtd/nand/raw/nandsim.c
@@ -2303,6 +2303,7 @@ 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;
 
 		memorg = nanddev_get_memorg(&chip->base);
 
@@ -2311,12 +2312,13 @@ static int __init ns_init_module(void)
 			retval = -EINVAL;
 			goto err_exit;
 		}
+
 		/* 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;
+		targetsize = nanddev_target_size(&chip->base);
 		chip->chip_shift = ffs(nsmtd->erasesize) + overridesize - 1;
-		chip->pagemask = (chip->chipsize >> chip->page_shift) - 1;
+		chip->pagemask = (targetsize >> chip->page_shift) - 1;
 	}
 
 	if ((retval = setup_wear_reporting(nsmtd)) != 0)
diff --git a/drivers/mtd/nand/raw/sh_flctl.c b/drivers/mtd/nand/raw/sh_flctl.c
index cf6b1be1cf9c..3f610040f0c3 100644
--- a/drivers/mtd/nand/raw/sh_flctl.c
+++ b/drivers/mtd/nand/raw/sh_flctl.c
@@ -986,6 +986,7 @@ static void flctl_read_buf(struct nand_chip *chip, uint8_t *buf, int len)
 
 static int flctl_chip_attach_chip(struct nand_chip *chip)
 {
+	u64 targetsize = nanddev_target_size(&chip->base);
 	struct mtd_info *mtd = nand_to_mtd(chip);
 	struct sh_flctl *flctl = mtd_to_flctl(mtd);
 
@@ -998,11 +999,11 @@ static int flctl_chip_attach_chip(struct nand_chip *chip)
 
 	if (mtd->writesize == 512) {
 		flctl->page_size = 0;
-		if (chip->chipsize > (32 << 20)) {
+		if (targetsize > (32 << 20)) {
 			/* big than 32MB */
 			flctl->rw_ADRCNT = ADRCNT_4;
 			flctl->erase_ADRCNT = ADRCNT_3;
-		} else if (chip->chipsize > (2 << 16)) {
+		} else if (targetsize > (2 << 16)) {
 			/* big than 128KB */
 			flctl->rw_ADRCNT = ADRCNT_3;
 			flctl->erase_ADRCNT = ADRCNT_2;
@@ -1012,11 +1013,11 @@ static int flctl_chip_attach_chip(struct nand_chip *chip)
 		}
 	} else {
 		flctl->page_size = 1;
-		if (chip->chipsize > (128 << 20)) {
+		if (targetsize > (128 << 20)) {
 			/* big than 128MB */
 			flctl->rw_ADRCNT = ADRCNT2_E;
 			flctl->erase_ADRCNT = ADRCNT_3;
-		} else if (chip->chipsize > (8 << 16)) {
+		} else if (targetsize > (8 << 16)) {
 			/* big than 512KB */
 			flctl->rw_ADRCNT = ADRCNT_4;
 			flctl->erase_ADRCNT = ADRCNT_2;
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index 24ecd9a4f952..a127eb773b1a 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -1015,7 +1015,6 @@ struct nand_legacy {
  *			      ONFI compliant or deduced from the datasheet if
  *			      the NAND chip is not ONFI compliant.
  * @numchips:		[INTERN] number of physical chips
- * @chipsize:		[INTERN] the size of one chip for multichip arrays
  * @pagemask:		[INTERN] page number mask = number of (pages / chip) - 1
  * @data_buf:		[INTERN] buffer for data, size is (page size + oobsize).
  * @pagecache:		Structure containing page cache related fields
@@ -1062,7 +1061,6 @@ struct nand_chip {
 	int bbt_erase_shift;
 	int chip_shift;
 	int numchips;
-	uint64_t chipsize;
 	int pagemask;
 	u8 *data_buf;
 
-- 
2.19.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 13/15] mtd: rawnand: Get rid of chip->chipsize
@ 2019-03-04 20:15   ` Miquel Raynal
  0 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

The target size can now be returned by nanddev_get_targetsize(). Get
rid of the chip->chipsize field and use this helper instead.

Signed-off-by: Boris Brezillon <bbrezillon@kernel.org>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 .../mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c  |  2 +-
 drivers/mtd/nand/raw/denali.c                 |  1 -
 drivers/mtd/nand/raw/fsl_elbc_nand.c          |  2 +-
 drivers/mtd/nand/raw/fsl_ifc_nand.c           |  2 +-
 drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c    |  2 +-
 drivers/mtd/nand/raw/jz4740_nand.c            |  2 +-
 drivers/mtd/nand/raw/nand_base.c              | 17 ++++++-------
 drivers/mtd/nand/raw/nand_bbt.c               | 25 ++++++++++++-------
 drivers/mtd/nand/raw/nand_jedec.c             |  2 --
 drivers/mtd/nand/raw/nand_onfi.c              |  2 --
 drivers/mtd/nand/raw/nandsim.c                |  6 +++--
 drivers/mtd/nand/raw/sh_flctl.c               |  9 ++++---
 include/linux/mtd/rawnand.h                   |  2 --
 13 files changed, 38 insertions(+), 36 deletions(-)

diff --git a/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c b/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c
index a37cbfe56567..a53ffb3d64b0 100644
--- a/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c
+++ b/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c
@@ -428,7 +428,7 @@ int bcm47xxnflash_ops_bcm4706_init(struct bcm47xxnflash *b47n)
 	}
 
 	/* Configure FLASH */
-	chipsize = b47n->nand_chip.chipsize >> 20;
+	chipsize = nanddev_target_size(&b47n->nand_chip.base) >> 20;
 	tbits = ffs(chipsize); /* find first bit set */
 	if (!tbits || tbits != fls(chipsize)) {
 		pr_err("Invalid flash size: 0x%lX\n", chipsize);
diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c
index 86e5df403beb..3ec0242b0aa2 100644
--- a/drivers/mtd/nand/raw/denali.c
+++ b/drivers/mtd/nand/raw/denali.c
@@ -1157,7 +1157,6 @@ static int denali_multidev_fixup(struct denali_nand_info *denali)
 	mtd->erasesize <<= 1;
 	mtd->writesize <<= 1;
 	mtd->oobsize <<= 1;
-	chip->chipsize <<= 1;
 	chip->page_shift += 1;
 	chip->phys_erase_shift += 1;
 	chip->bbt_erase_shift += 1;
diff --git a/drivers/mtd/nand/raw/fsl_elbc_nand.c b/drivers/mtd/nand/raw/fsl_elbc_nand.c
index 70f0d2b450ea..1d960a6cd691 100644
--- a/drivers/mtd/nand/raw/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/raw/fsl_elbc_nand.c
@@ -655,7 +655,7 @@ static int fsl_elbc_attach_chip(struct nand_chip *chip)
 	dev_dbg(priv->dev, "fsl_elbc_init: nand->numchips = %d\n",
 	        chip->numchips);
 	dev_dbg(priv->dev, "fsl_elbc_init: nand->chipsize = %lld\n",
-	        chip->chipsize);
+	        nanddev_target_size(&chip->base));
 	dev_dbg(priv->dev, "fsl_elbc_init: nand->pagemask = %8x\n",
 	        chip->pagemask);
 	dev_dbg(priv->dev, "fsl_elbc_init: nand->legacy.chip_delay = %d\n",
diff --git a/drivers/mtd/nand/raw/fsl_ifc_nand.c b/drivers/mtd/nand/raw/fsl_ifc_nand.c
index e65d274399f9..a9e8f89aeebd 100644
--- a/drivers/mtd/nand/raw/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/raw/fsl_ifc_nand.c
@@ -724,7 +724,7 @@ static int fsl_ifc_attach_chip(struct nand_chip *chip)
 	dev_dbg(priv->dev, "%s: nand->numchips = %d\n", __func__,
 							chip->numchips);
 	dev_dbg(priv->dev, "%s: nand->chipsize = %lld\n", __func__,
-							chip->chipsize);
+	        nanddev_target_size(&chip->base));
 	dev_dbg(priv->dev, "%s: nand->pagemask = %8x\n", __func__,
 							chip->pagemask);
 	dev_dbg(priv->dev, "%s: nand->legacy.chip_delay = %d\n", __func__,
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
index 05f6f68e4e0d..6151214eddec 100644
--- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
@@ -1753,7 +1753,7 @@ static int mx23_boot_init(struct gpmi_nand_data  *this)
 	dev_dbg(dev, "Transcribing bad block marks...\n");
 
 	/* Compute the number of blocks in the entire medium. */
-	block_count = chip->chipsize >> chip->phys_erase_shift;
+	block_count = nanddev_eraseblocks_per_target(&chip->base);
 
 	/*
 	 * Loop over all the blocks in the medium, transcribing block marks as
diff --git a/drivers/mtd/nand/raw/jz4740_nand.c b/drivers/mtd/nand/raw/jz4740_nand.c
index 76a32ad2cf83..06690b3603b1 100644
--- a/drivers/mtd/nand/raw/jz4740_nand.c
+++ b/drivers/mtd/nand/raw/jz4740_nand.c
@@ -356,7 +356,7 @@ static int jz_nand_detect_bank(struct platform_device *pdev,
 		/* Update size of the MTD. */
 		chip->numchips++;
 		memorg->ntargets++;
-		mtd->size += chip->chipsize;
+		mtd->size += nanddev_target_size(&chip->base);
 	}
 
 	dev_info(&pdev->dev, "Found chip %zu on bank %i\n", chipnr, bank);
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 91fd508cf406..427c80abef3f 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -4587,7 +4587,6 @@ static bool find_full_id_nand(struct nand_chip *chip,
 		mtd->oobsize = memorg->oobsize;
 
 		memorg->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 *
@@ -4678,6 +4677,7 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
 	int busw, ret;
 	u8 *id_data = chip->id.data;
 	u8 maf_id, dev_id;
+	u64 targetsize;
 
 	/*
 	 * Let's start by initializing memorg fields that might be left
@@ -4782,8 +4782,6 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
 	if (!chip->parameters.model)
 		return -ENOMEM;
 
-	chip->chipsize = (uint64_t)type->chipsize << 20;
-
 	if (!type->pagesize)
 		nand_manufacturer_detect(chip);
 	else
@@ -4825,14 +4823,15 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
 	/* Calculate the address shift from the page size */
 	chip->page_shift = ffs(mtd->writesize) - 1;
 	/* Convert chipsize to number of pages per chip -1 */
-	chip->pagemask = (chip->chipsize >> chip->page_shift) - 1;
+	targetsize = nanddev_target_size(&chip->base);
+	chip->pagemask = (targetsize >> chip->page_shift) - 1;
 
 	chip->bbt_erase_shift = chip->phys_erase_shift =
 		ffs(mtd->erasesize) - 1;
-	if (chip->chipsize & 0xffffffff)
-		chip->chip_shift = ffs((unsigned)chip->chipsize) - 1;
+	if (targetsize & 0xffffffff)
+		chip->chip_shift = ffs((unsigned)targetsize) - 1;
 	else {
-		chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32));
+		chip->chip_shift = ffs((unsigned)(targetsize >> 32));
 		chip->chip_shift += 32 - 1;
 	}
 
@@ -4848,7 +4847,7 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
 	pr_info("%s %s\n", nand_manufacturer_name(manufacturer),
 		chip->parameters.model);
 	pr_info("%d MiB, %s, erase size: %d KiB, page size: %d, OOB size: %d\n",
-		(int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC",
+		(int)(targetsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC",
 		mtd->erasesize >> 10, mtd->writesize, mtd->oobsize);
 	return 0;
 
@@ -5093,7 +5092,7 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips,
 	/* Store the number of chips and calc total size for mtd */
 	memorg->ntargets = i;
 	chip->numchips = i;
-	mtd->size = i * chip->chipsize;
+	mtd->size = i * nanddev_target_size(&chip->base);
 
 	return 0;
 }
diff --git a/drivers/mtd/nand/raw/nand_bbt.c b/drivers/mtd/nand/raw/nand_bbt.c
index 0b96c4cab967..e3308857b2ee 100644
--- a/drivers/mtd/nand/raw/nand_bbt.c
+++ b/drivers/mtd/nand/raw/nand_bbt.c
@@ -264,6 +264,7 @@ static int read_abs_bbt(struct nand_chip *this, uint8_t *buf,
 			struct nand_bbt_descr *td, int chip)
 {
 	struct mtd_info *mtd = nand_to_mtd(this);
+	u64 targetsize = nanddev_target_size(&this->base);
 	int res = 0, i;
 
 	if (td->options & NAND_BBT_PERCHIP) {
@@ -271,11 +272,11 @@ static int read_abs_bbt(struct nand_chip *this, uint8_t *buf,
 		for (i = 0; i < this->numchips; i++) {
 			if (chip == -1 || chip == i)
 				res = read_bbt(this, buf, td->pages[i],
-					this->chipsize >> this->bbt_erase_shift,
+					targetsize >> this->bbt_erase_shift,
 					td, offs);
 			if (res)
 				return res;
-			offs += this->chipsize >> this->bbt_erase_shift;
+			offs += targetsize >> this->bbt_erase_shift;
 		}
 	} else {
 		res = read_bbt(this, buf, td->pages[0],
@@ -459,6 +460,7 @@ static int scan_block_fast(struct nand_chip *this, struct nand_bbt_descr *bd,
 static int create_bbt(struct nand_chip *this, uint8_t *buf,
 		      struct nand_bbt_descr *bd, int chip)
 {
+	u64 targetsize = nanddev_target_size(&this->base);
 	struct mtd_info *mtd = nand_to_mtd(this);
 	int i, numblocks, numpages;
 	int startblock;
@@ -481,7 +483,7 @@ static int create_bbt(struct nand_chip *this, uint8_t *buf,
 			       chip + 1, this->numchips);
 			return -EINVAL;
 		}
-		numblocks = this->chipsize >> this->bbt_erase_shift;
+		numblocks = targetsize >> this->bbt_erase_shift;
 		startblock = chip * numblocks;
 		numblocks += startblock;
 		from = (loff_t)startblock << this->bbt_erase_shift;
@@ -529,6 +531,7 @@ static int create_bbt(struct nand_chip *this, uint8_t *buf,
 static int search_bbt(struct nand_chip *this, uint8_t *buf,
 		      struct nand_bbt_descr *td)
 {
+	u64 targetsize = nanddev_target_size(&this->base);
 	struct mtd_info *mtd = nand_to_mtd(this);
 	int i, chips;
 	int startblock, block, dir;
@@ -548,7 +551,7 @@ static int search_bbt(struct nand_chip *this, uint8_t *buf,
 	/* Do we have a bbt per chip? */
 	if (td->options & NAND_BBT_PERCHIP) {
 		chips = this->numchips;
-		bbtblocks = this->chipsize >> this->bbt_erase_shift;
+		bbtblocks = targetsize >> this->bbt_erase_shift;
 		startblock &= bbtblocks - 1;
 	} else {
 		chips = 1;
@@ -576,7 +579,7 @@ static int search_bbt(struct nand_chip *this, uint8_t *buf,
 				break;
 			}
 		}
-		startblock += this->chipsize >> this->bbt_erase_shift;
+		startblock += targetsize >> this->bbt_erase_shift;
 	}
 	/* Check, if we found a bbt for each requested chip */
 	for (i = 0; i < chips; i++) {
@@ -626,6 +629,7 @@ static void search_read_bbts(struct nand_chip *this, uint8_t *buf,
 static int get_bbt_block(struct nand_chip *this, struct nand_bbt_descr *td,
 			 struct nand_bbt_descr *md, int chip)
 {
+	u64 targetsize = nanddev_target_size(&this->base);
 	int startblock, dir, page, numblocks, i;
 
 	/*
@@ -637,7 +641,7 @@ static int get_bbt_block(struct nand_chip *this, struct nand_bbt_descr *td,
 		return td->pages[chip] >>
 				(this->bbt_erase_shift - this->page_shift);
 
-	numblocks = (int)(this->chipsize >> this->bbt_erase_shift);
+	numblocks = (int)(targetsize >> this->bbt_erase_shift);
 	if (!(td->options & NAND_BBT_PERCHIP))
 		numblocks *= this->numchips;
 
@@ -717,6 +721,7 @@ static int write_bbt(struct nand_chip *this, uint8_t *buf,
 		     struct nand_bbt_descr *td, struct nand_bbt_descr *md,
 		     int chipsel)
 {
+	u64 targetsize = nanddev_target_size(&this->base);
 	struct mtd_info *mtd = nand_to_mtd(this);
 	struct erase_info einfo;
 	int i, res, chip = 0;
@@ -737,7 +742,7 @@ static int write_bbt(struct nand_chip *this, uint8_t *buf,
 		rcode = 0xff;
 	/* Write bad block table per chip rather than per device? */
 	if (td->options & NAND_BBT_PERCHIP) {
-		numblocks = (int)(this->chipsize >> this->bbt_erase_shift);
+		numblocks = (int)(targetsize >> this->bbt_erase_shift);
 		/* Full device write or specific chip? */
 		if (chipsel == -1) {
 			nrchips = this->numchips;
@@ -1099,6 +1104,7 @@ static int nand_update_bbt(struct nand_chip *this, loff_t offs)
  */
 static void mark_bbt_region(struct nand_chip *this, struct nand_bbt_descr *td)
 {
+	u64 targetsize = nanddev_target_size(&this->base);
 	struct mtd_info *mtd = nand_to_mtd(this);
 	int i, j, chips, block, nrblocks, update;
 	uint8_t oldval;
@@ -1106,7 +1112,7 @@ static void mark_bbt_region(struct nand_chip *this, struct nand_bbt_descr *td)
 	/* Do we have a bbt per chip? */
 	if (td->options & NAND_BBT_PERCHIP) {
 		chips = this->numchips;
-		nrblocks = (int)(this->chipsize >> this->bbt_erase_shift);
+		nrblocks = (int)(targetsize >> this->bbt_erase_shift);
 	} else {
 		chips = 1;
 		nrblocks = (int)(mtd->size >> this->bbt_erase_shift);
@@ -1159,6 +1165,7 @@ static void mark_bbt_region(struct nand_chip *this, struct nand_bbt_descr *td)
  */
 static void verify_bbt_descr(struct nand_chip *this, struct nand_bbt_descr *bd)
 {
+	u64 targetsize = nanddev_target_size(&this->base);
 	struct mtd_info *mtd = nand_to_mtd(this);
 	u32 pattern_len;
 	u32 bits;
@@ -1187,7 +1194,7 @@ static void verify_bbt_descr(struct nand_chip *this, struct nand_bbt_descr *bd)
 	}
 
 	if (bd->options & NAND_BBT_PERCHIP)
-		table_size = this->chipsize >> this->bbt_erase_shift;
+		table_size = targetsize >> this->bbt_erase_shift;
 	else
 		table_size = mtd->size >> this->bbt_erase_shift;
 	table_size >>= 3;
diff --git a/drivers/mtd/nand/raw/nand_jedec.c b/drivers/mtd/nand/raw/nand_jedec.c
index 030f178c7a97..99e2f017c79b 100644
--- a/drivers/mtd/nand/raw/nand_jedec.c
+++ b/drivers/mtd/nand/raw/nand_jedec.c
@@ -101,8 +101,6 @@ int nand_jedec_detect(struct nand_chip *chip)
 	/* Please reference to the comment for nand_flash_detect_onfi. */
 	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;
 
 	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 a6b9fc9a335b..7b468e7214c7 100644
--- a/drivers/mtd/nand/raw/nand_onfi.c
+++ b/drivers/mtd/nand/raw/nand_onfi.c
@@ -246,8 +246,6 @@ int nand_onfi_detect(struct nand_chip *chip)
 	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;
 
 	if (le16_to_cpu(p->features) & ONFI_FEATURE_16_BIT_BUS)
diff --git a/drivers/mtd/nand/raw/nandsim.c b/drivers/mtd/nand/raw/nandsim.c
index 07144c992d54..670abe8d59ca 100644
--- a/drivers/mtd/nand/raw/nandsim.c
+++ b/drivers/mtd/nand/raw/nandsim.c
@@ -2303,6 +2303,7 @@ 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;
 
 		memorg = nanddev_get_memorg(&chip->base);
 
@@ -2311,12 +2312,13 @@ static int __init ns_init_module(void)
 			retval = -EINVAL;
 			goto err_exit;
 		}
+
 		/* 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;
+		targetsize = nanddev_target_size(&chip->base);
 		chip->chip_shift = ffs(nsmtd->erasesize) + overridesize - 1;
-		chip->pagemask = (chip->chipsize >> chip->page_shift) - 1;
+		chip->pagemask = (targetsize >> chip->page_shift) - 1;
 	}
 
 	if ((retval = setup_wear_reporting(nsmtd)) != 0)
diff --git a/drivers/mtd/nand/raw/sh_flctl.c b/drivers/mtd/nand/raw/sh_flctl.c
index cf6b1be1cf9c..3f610040f0c3 100644
--- a/drivers/mtd/nand/raw/sh_flctl.c
+++ b/drivers/mtd/nand/raw/sh_flctl.c
@@ -986,6 +986,7 @@ static void flctl_read_buf(struct nand_chip *chip, uint8_t *buf, int len)
 
 static int flctl_chip_attach_chip(struct nand_chip *chip)
 {
+	u64 targetsize = nanddev_target_size(&chip->base);
 	struct mtd_info *mtd = nand_to_mtd(chip);
 	struct sh_flctl *flctl = mtd_to_flctl(mtd);
 
@@ -998,11 +999,11 @@ static int flctl_chip_attach_chip(struct nand_chip *chip)
 
 	if (mtd->writesize == 512) {
 		flctl->page_size = 0;
-		if (chip->chipsize > (32 << 20)) {
+		if (targetsize > (32 << 20)) {
 			/* big than 32MB */
 			flctl->rw_ADRCNT = ADRCNT_4;
 			flctl->erase_ADRCNT = ADRCNT_3;
-		} else if (chip->chipsize > (2 << 16)) {
+		} else if (targetsize > (2 << 16)) {
 			/* big than 128KB */
 			flctl->rw_ADRCNT = ADRCNT_3;
 			flctl->erase_ADRCNT = ADRCNT_2;
@@ -1012,11 +1013,11 @@ static int flctl_chip_attach_chip(struct nand_chip *chip)
 		}
 	} else {
 		flctl->page_size = 1;
-		if (chip->chipsize > (128 << 20)) {
+		if (targetsize > (128 << 20)) {
 			/* big than 128MB */
 			flctl->rw_ADRCNT = ADRCNT2_E;
 			flctl->erase_ADRCNT = ADRCNT_3;
-		} else if (chip->chipsize > (8 << 16)) {
+		} else if (targetsize > (8 << 16)) {
 			/* big than 512KB */
 			flctl->rw_ADRCNT = ADRCNT_4;
 			flctl->erase_ADRCNT = ADRCNT_2;
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index 24ecd9a4f952..a127eb773b1a 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -1015,7 +1015,6 @@ struct nand_legacy {
  *			      ONFI compliant or deduced from the datasheet if
  *			      the NAND chip is not ONFI compliant.
  * @numchips:		[INTERN] number of physical chips
- * @chipsize:		[INTERN] the size of one chip for multichip arrays
  * @pagemask:		[INTERN] page number mask = number of (pages / chip) - 1
  * @data_buf:		[INTERN] buffer for data, size is (page size + oobsize).
  * @pagecache:		Structure containing page cache related fields
@@ -1062,7 +1061,6 @@ struct nand_chip {
 	int bbt_erase_shift;
 	int chip_shift;
 	int numchips;
-	uint64_t chipsize;
 	int pagemask;
 	u8 *data_buf;
 
-- 
2.19.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 14/15] mtd: rawnand: Get rid of chip->numchips
  2019-03-04 20:15 ` Miquel Raynal
@ 2019-03-04 20:15   ` Miquel Raynal
  -1 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

The same information is provided by nanddev_ntargets().

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/diskonchip.c    |  2 +-
 drivers/mtd/nand/raw/fsl_elbc_nand.c |  2 +-
 drivers/mtd/nand/raw/fsl_ifc_nand.c  |  2 +-
 drivers/mtd/nand/raw/hisi504_nand.c  |  2 +-
 drivers/mtd/nand/raw/internals.h     |  2 +-
 drivers/mtd/nand/raw/jz4740_nand.c   |  1 -
 drivers/mtd/nand/raw/nand_base.c     | 15 ++++-----------
 drivers/mtd/nand/raw/nand_bbt.c      | 16 ++++++++--------
 include/linux/mtd/rawnand.h          |  7 +++----
 9 files changed, 20 insertions(+), 29 deletions(-)

diff --git a/drivers/mtd/nand/raw/diskonchip.c b/drivers/mtd/nand/raw/diskonchip.c
index e9767e06415d..3cee832716ec 100644
--- a/drivers/mtd/nand/raw/diskonchip.c
+++ b/drivers/mtd/nand/raw/diskonchip.c
@@ -1291,7 +1291,7 @@ static int __init inftl_scan_bbt(struct mtd_info *mtd)
 	struct doc_priv *doc = nand_get_controller_data(this);
 	struct mtd_partition parts[5];
 
-	if (this->numchips > doc->chips_per_floor) {
+	if (nanddev_ntargets(&this->base) > doc->chips_per_floor) {
 		pr_err("Multi-floor INFTL devices not yet supported.\n");
 		return -EIO;
 	}
diff --git a/drivers/mtd/nand/raw/fsl_elbc_nand.c b/drivers/mtd/nand/raw/fsl_elbc_nand.c
index 1d960a6cd691..293a5b71833a 100644
--- a/drivers/mtd/nand/raw/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/raw/fsl_elbc_nand.c
@@ -653,7 +653,7 @@ static int fsl_elbc_attach_chip(struct nand_chip *chip)
 	priv->fmr |= al << FMR_AL_SHIFT;
 
 	dev_dbg(priv->dev, "fsl_elbc_init: nand->numchips = %d\n",
-	        chip->numchips);
+	        nanddev_ntargets(&chip->base));
 	dev_dbg(priv->dev, "fsl_elbc_init: nand->chipsize = %lld\n",
 	        nanddev_target_size(&chip->base));
 	dev_dbg(priv->dev, "fsl_elbc_init: nand->pagemask = %8x\n",
diff --git a/drivers/mtd/nand/raw/fsl_ifc_nand.c b/drivers/mtd/nand/raw/fsl_ifc_nand.c
index a9e8f89aeebd..04a3dcd675bf 100644
--- a/drivers/mtd/nand/raw/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/raw/fsl_ifc_nand.c
@@ -722,7 +722,7 @@ static int fsl_ifc_attach_chip(struct nand_chip *chip)
 	struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
 
 	dev_dbg(priv->dev, "%s: nand->numchips = %d\n", __func__,
-							chip->numchips);
+		nanddev_ntargets(&chip->base));
 	dev_dbg(priv->dev, "%s: nand->chipsize = %lld\n", __func__,
 	        nanddev_target_size(&chip->base));
 	dev_dbg(priv->dev, "%s: nand->pagemask = %8x\n", __func__,
diff --git a/drivers/mtd/nand/raw/hisi504_nand.c b/drivers/mtd/nand/raw/hisi504_nand.c
index f3f9aa160cff..e4526fff9da4 100644
--- a/drivers/mtd/nand/raw/hisi504_nand.c
+++ b/drivers/mtd/nand/raw/hisi504_nand.c
@@ -849,7 +849,7 @@ static int hisi_nfc_resume(struct device *dev)
 	struct hinfc_host *host = dev_get_drvdata(dev);
 	struct nand_chip *chip = &host->chip;
 
-	for (cs = 0; cs < chip->numchips; cs++)
+	for (cs = 0; cs < nanddev_ntargets(&chip->base); cs++)
 		hisi_nfc_send_cmd_reset(host, cs);
 	hinfc_write(host, SET_HINFC504_PWIDTH(HINFC504_W_LATCH,
 		    HINFC504_R_LATCH, HINFC504_RW_LATCH), HINFC504_PWIDTH);
diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h
index fbf6ca015cd7..a204f9d7e123 100644
--- a/drivers/mtd/nand/raw/internals.h
+++ b/drivers/mtd/nand/raw/internals.h
@@ -110,7 +110,7 @@ static inline int nand_exec_op(struct nand_chip *chip,
 	if (!nand_has_exec_op(chip))
 		return -ENOTSUPP;
 
-	if (WARN_ON(op->cs >= chip->numchips))
+	if (WARN_ON(op->cs >= nanddev_ntargets(&chip->base)))
 		return -EINVAL;
 
 	return chip->controller->ops->exec_op(chip, op, false);
diff --git a/drivers/mtd/nand/raw/jz4740_nand.c b/drivers/mtd/nand/raw/jz4740_nand.c
index 06690b3603b1..c992a664bdee 100644
--- a/drivers/mtd/nand/raw/jz4740_nand.c
+++ b/drivers/mtd/nand/raw/jz4740_nand.c
@@ -354,7 +354,6 @@ static int jz_nand_detect_bank(struct platform_device *pdev,
 		}
 
 		/* Update size of the MTD. */
-		chip->numchips++;
 		memorg->ntargets++;
 		mtd->size += nanddev_target_size(&chip->base);
 	}
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 427c80abef3f..ce01824dcc62 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -240,10 +240,10 @@ static int check_offs_len(struct nand_chip *chip, loff_t ofs, uint64_t len)
 void nand_select_target(struct nand_chip *chip, unsigned int cs)
 {
 	/*
-	 * cs should always lie between 0 and chip->numchips, when that's not
-	 * the case it's a bug and the caller should be fixed.
+	 * cs should always lie between 0 and nanddev_ntargets(), when that's
+	 * not the case it's a bug and the caller should be fixed.
 	 */
-	if (WARN_ON(cs > chip->numchips))
+	if (WARN_ON(cs > nanddev_ntargets(&chip->base)))
 		return;
 
 	chip->cur_cs = cs;
@@ -5042,12 +5042,6 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips,
 	if (!mtd->name && mtd->dev.parent)
 		mtd->name = dev_name(mtd->dev.parent);
 
-	/*
-	 * Start with chips->numchips = maxchips to let nand_select_target() do
-	 * its job. chip->numchips will be adjusted after.
-	 */
-	chip->numchips = maxchips;
-
 	/* Set the default functions */
 	nand_set_defaults(chip);
 
@@ -5091,7 +5085,6 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips,
 
 	/* Store the number of chips and calc total size for mtd */
 	memorg->ntargets = i;
-	chip->numchips = i;
 	mtd->size = i * nanddev_target_size(&chip->base);
 
 	return 0;
@@ -5833,7 +5826,7 @@ static int nand_scan_tail(struct nand_chip *chip)
 		goto err_nanddev_cleanup;
 
 	/* Enter fastest possible mode on all dies. */
-	for (i = 0; i < chip->numchips; i++) {
+	for (i = 0; i < nanddev_ntargets(&chip->base); i++) {
 		ret = nand_setup_data_interface(chip, i);
 		if (ret)
 			goto err_nanddev_cleanup;
diff --git a/drivers/mtd/nand/raw/nand_bbt.c b/drivers/mtd/nand/raw/nand_bbt.c
index e3308857b2ee..303408039650 100644
--- a/drivers/mtd/nand/raw/nand_bbt.c
+++ b/drivers/mtd/nand/raw/nand_bbt.c
@@ -269,7 +269,7 @@ static int read_abs_bbt(struct nand_chip *this, uint8_t *buf,
 
 	if (td->options & NAND_BBT_PERCHIP) {
 		int offs = 0;
-		for (i = 0; i < this->numchips; i++) {
+		for (i = 0; i < nanddev_ntargets(&this->base); i++) {
 			if (chip == -1 || chip == i)
 				res = read_bbt(this, buf, td->pages[i],
 					targetsize >> this->bbt_erase_shift,
@@ -478,9 +478,9 @@ static int create_bbt(struct nand_chip *this, uint8_t *buf,
 		startblock = 0;
 		from = 0;
 	} else {
-		if (chip >= this->numchips) {
+		if (chip >= nanddev_ntargets(&this->base)) {
 			pr_warn("create_bbt(): chipnr (%d) > available chips (%d)\n",
-			       chip + 1, this->numchips);
+			        chip + 1, nanddev_ntargets(&this->base));
 			return -EINVAL;
 		}
 		numblocks = targetsize >> this->bbt_erase_shift;
@@ -550,7 +550,7 @@ static int search_bbt(struct nand_chip *this, uint8_t *buf,
 
 	/* Do we have a bbt per chip? */
 	if (td->options & NAND_BBT_PERCHIP) {
-		chips = this->numchips;
+		chips = nanddev_ntargets(&this->base);
 		bbtblocks = targetsize >> this->bbt_erase_shift;
 		startblock &= bbtblocks - 1;
 	} else {
@@ -643,7 +643,7 @@ static int get_bbt_block(struct nand_chip *this, struct nand_bbt_descr *td,
 
 	numblocks = (int)(targetsize >> this->bbt_erase_shift);
 	if (!(td->options & NAND_BBT_PERCHIP))
-		numblocks *= this->numchips;
+		numblocks *= nanddev_ntargets(&this->base);
 
 	/*
 	 * Automatic placement of the bad block table. Search direction
@@ -745,7 +745,7 @@ static int write_bbt(struct nand_chip *this, uint8_t *buf,
 		numblocks = (int)(targetsize >> this->bbt_erase_shift);
 		/* Full device write or specific chip? */
 		if (chipsel == -1) {
-			nrchips = this->numchips;
+			nrchips = nanddev_ntargets(&this->base);
 		} else {
 			nrchips = chipsel + 1;
 			chip = chipsel;
@@ -932,7 +932,7 @@ static int check_create(struct nand_chip *this, uint8_t *buf,
 
 	/* Do we have a bbt per chip? */
 	if (td->options & NAND_BBT_PERCHIP)
-		chips = this->numchips;
+		chips = nanddev_ntargets(&this->base);
 	else
 		chips = 1;
 
@@ -1111,7 +1111,7 @@ static void mark_bbt_region(struct nand_chip *this, struct nand_bbt_descr *td)
 
 	/* Do we have a bbt per chip? */
 	if (td->options & NAND_BBT_PERCHIP) {
-		chips = this->numchips;
+		chips = nanddev_ntargets(&this->base);
 		nrblocks = (int)(targetsize >> this->bbt_erase_shift);
 	} else {
 		chips = 1;
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index a127eb773b1a..e5a25ba75211 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -1014,7 +1014,6 @@ struct nand_legacy {
  *			      set to the actually used ONFI mode if the chip is
  *			      ONFI compliant or deduced from the datasheet if
  *			      the NAND chip is not ONFI compliant.
- * @numchips:		[INTERN] number of physical chips
  * @pagemask:		[INTERN] page number mask = number of (pages / chip) - 1
  * @data_buf:		[INTERN] buffer for data, size is (page size + oobsize).
  * @pagecache:		Structure containing page cache related fields
@@ -1028,8 +1027,9 @@ struct nand_legacy {
  * @data_interface:	[INTERN] NAND interface timing information
  * @cur_cs:		currently selected target. -1 means no target selected,
  *			otherwise we should always have cur_cs >= 0 &&
- *			cur_cs < numchips. NAND Controller drivers should not
- *			modify this value, but they're allowed to read it.
+ *			cur_cs < nanddev_ntargets(). NAND Controller drivers
+ *			should not modify this value, but they're allowed to
+ *			read it.
  * @read_retries:	[INTERN] the number of read retry modes supported
  * @bbt:		[INTERN] bad block table pointer
  * @bbt_td:		[REPLACEABLE] bad block table descriptor for flash
@@ -1060,7 +1060,6 @@ struct nand_chip {
 	int phys_erase_shift;
 	int bbt_erase_shift;
 	int chip_shift;
-	int numchips;
 	int pagemask;
 	u8 *data_buf;
 
-- 
2.19.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 14/15] mtd: rawnand: Get rid of chip->numchips
@ 2019-03-04 20:15   ` Miquel Raynal
  0 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

The same information is provided by nanddev_ntargets().

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/diskonchip.c    |  2 +-
 drivers/mtd/nand/raw/fsl_elbc_nand.c |  2 +-
 drivers/mtd/nand/raw/fsl_ifc_nand.c  |  2 +-
 drivers/mtd/nand/raw/hisi504_nand.c  |  2 +-
 drivers/mtd/nand/raw/internals.h     |  2 +-
 drivers/mtd/nand/raw/jz4740_nand.c   |  1 -
 drivers/mtd/nand/raw/nand_base.c     | 15 ++++-----------
 drivers/mtd/nand/raw/nand_bbt.c      | 16 ++++++++--------
 include/linux/mtd/rawnand.h          |  7 +++----
 9 files changed, 20 insertions(+), 29 deletions(-)

diff --git a/drivers/mtd/nand/raw/diskonchip.c b/drivers/mtd/nand/raw/diskonchip.c
index e9767e06415d..3cee832716ec 100644
--- a/drivers/mtd/nand/raw/diskonchip.c
+++ b/drivers/mtd/nand/raw/diskonchip.c
@@ -1291,7 +1291,7 @@ static int __init inftl_scan_bbt(struct mtd_info *mtd)
 	struct doc_priv *doc = nand_get_controller_data(this);
 	struct mtd_partition parts[5];
 
-	if (this->numchips > doc->chips_per_floor) {
+	if (nanddev_ntargets(&this->base) > doc->chips_per_floor) {
 		pr_err("Multi-floor INFTL devices not yet supported.\n");
 		return -EIO;
 	}
diff --git a/drivers/mtd/nand/raw/fsl_elbc_nand.c b/drivers/mtd/nand/raw/fsl_elbc_nand.c
index 1d960a6cd691..293a5b71833a 100644
--- a/drivers/mtd/nand/raw/fsl_elbc_nand.c
+++ b/drivers/mtd/nand/raw/fsl_elbc_nand.c
@@ -653,7 +653,7 @@ static int fsl_elbc_attach_chip(struct nand_chip *chip)
 	priv->fmr |= al << FMR_AL_SHIFT;
 
 	dev_dbg(priv->dev, "fsl_elbc_init: nand->numchips = %d\n",
-	        chip->numchips);
+	        nanddev_ntargets(&chip->base));
 	dev_dbg(priv->dev, "fsl_elbc_init: nand->chipsize = %lld\n",
 	        nanddev_target_size(&chip->base));
 	dev_dbg(priv->dev, "fsl_elbc_init: nand->pagemask = %8x\n",
diff --git a/drivers/mtd/nand/raw/fsl_ifc_nand.c b/drivers/mtd/nand/raw/fsl_ifc_nand.c
index a9e8f89aeebd..04a3dcd675bf 100644
--- a/drivers/mtd/nand/raw/fsl_ifc_nand.c
+++ b/drivers/mtd/nand/raw/fsl_ifc_nand.c
@@ -722,7 +722,7 @@ static int fsl_ifc_attach_chip(struct nand_chip *chip)
 	struct fsl_ifc_mtd *priv = nand_get_controller_data(chip);
 
 	dev_dbg(priv->dev, "%s: nand->numchips = %d\n", __func__,
-							chip->numchips);
+		nanddev_ntargets(&chip->base));
 	dev_dbg(priv->dev, "%s: nand->chipsize = %lld\n", __func__,
 	        nanddev_target_size(&chip->base));
 	dev_dbg(priv->dev, "%s: nand->pagemask = %8x\n", __func__,
diff --git a/drivers/mtd/nand/raw/hisi504_nand.c b/drivers/mtd/nand/raw/hisi504_nand.c
index f3f9aa160cff..e4526fff9da4 100644
--- a/drivers/mtd/nand/raw/hisi504_nand.c
+++ b/drivers/mtd/nand/raw/hisi504_nand.c
@@ -849,7 +849,7 @@ static int hisi_nfc_resume(struct device *dev)
 	struct hinfc_host *host = dev_get_drvdata(dev);
 	struct nand_chip *chip = &host->chip;
 
-	for (cs = 0; cs < chip->numchips; cs++)
+	for (cs = 0; cs < nanddev_ntargets(&chip->base); cs++)
 		hisi_nfc_send_cmd_reset(host, cs);
 	hinfc_write(host, SET_HINFC504_PWIDTH(HINFC504_W_LATCH,
 		    HINFC504_R_LATCH, HINFC504_RW_LATCH), HINFC504_PWIDTH);
diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h
index fbf6ca015cd7..a204f9d7e123 100644
--- a/drivers/mtd/nand/raw/internals.h
+++ b/drivers/mtd/nand/raw/internals.h
@@ -110,7 +110,7 @@ static inline int nand_exec_op(struct nand_chip *chip,
 	if (!nand_has_exec_op(chip))
 		return -ENOTSUPP;
 
-	if (WARN_ON(op->cs >= chip->numchips))
+	if (WARN_ON(op->cs >= nanddev_ntargets(&chip->base)))
 		return -EINVAL;
 
 	return chip->controller->ops->exec_op(chip, op, false);
diff --git a/drivers/mtd/nand/raw/jz4740_nand.c b/drivers/mtd/nand/raw/jz4740_nand.c
index 06690b3603b1..c992a664bdee 100644
--- a/drivers/mtd/nand/raw/jz4740_nand.c
+++ b/drivers/mtd/nand/raw/jz4740_nand.c
@@ -354,7 +354,6 @@ static int jz_nand_detect_bank(struct platform_device *pdev,
 		}
 
 		/* Update size of the MTD. */
-		chip->numchips++;
 		memorg->ntargets++;
 		mtd->size += nanddev_target_size(&chip->base);
 	}
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index 427c80abef3f..ce01824dcc62 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -240,10 +240,10 @@ static int check_offs_len(struct nand_chip *chip, loff_t ofs, uint64_t len)
 void nand_select_target(struct nand_chip *chip, unsigned int cs)
 {
 	/*
-	 * cs should always lie between 0 and chip->numchips, when that's not
-	 * the case it's a bug and the caller should be fixed.
+	 * cs should always lie between 0 and nanddev_ntargets(), when that's
+	 * not the case it's a bug and the caller should be fixed.
 	 */
-	if (WARN_ON(cs > chip->numchips))
+	if (WARN_ON(cs > nanddev_ntargets(&chip->base)))
 		return;
 
 	chip->cur_cs = cs;
@@ -5042,12 +5042,6 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips,
 	if (!mtd->name && mtd->dev.parent)
 		mtd->name = dev_name(mtd->dev.parent);
 
-	/*
-	 * Start with chips->numchips = maxchips to let nand_select_target() do
-	 * its job. chip->numchips will be adjusted after.
-	 */
-	chip->numchips = maxchips;
-
 	/* Set the default functions */
 	nand_set_defaults(chip);
 
@@ -5091,7 +5085,6 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips,
 
 	/* Store the number of chips and calc total size for mtd */
 	memorg->ntargets = i;
-	chip->numchips = i;
 	mtd->size = i * nanddev_target_size(&chip->base);
 
 	return 0;
@@ -5833,7 +5826,7 @@ static int nand_scan_tail(struct nand_chip *chip)
 		goto err_nanddev_cleanup;
 
 	/* Enter fastest possible mode on all dies. */
-	for (i = 0; i < chip->numchips; i++) {
+	for (i = 0; i < nanddev_ntargets(&chip->base); i++) {
 		ret = nand_setup_data_interface(chip, i);
 		if (ret)
 			goto err_nanddev_cleanup;
diff --git a/drivers/mtd/nand/raw/nand_bbt.c b/drivers/mtd/nand/raw/nand_bbt.c
index e3308857b2ee..303408039650 100644
--- a/drivers/mtd/nand/raw/nand_bbt.c
+++ b/drivers/mtd/nand/raw/nand_bbt.c
@@ -269,7 +269,7 @@ static int read_abs_bbt(struct nand_chip *this, uint8_t *buf,
 
 	if (td->options & NAND_BBT_PERCHIP) {
 		int offs = 0;
-		for (i = 0; i < this->numchips; i++) {
+		for (i = 0; i < nanddev_ntargets(&this->base); i++) {
 			if (chip == -1 || chip == i)
 				res = read_bbt(this, buf, td->pages[i],
 					targetsize >> this->bbt_erase_shift,
@@ -478,9 +478,9 @@ static int create_bbt(struct nand_chip *this, uint8_t *buf,
 		startblock = 0;
 		from = 0;
 	} else {
-		if (chip >= this->numchips) {
+		if (chip >= nanddev_ntargets(&this->base)) {
 			pr_warn("create_bbt(): chipnr (%d) > available chips (%d)\n",
-			       chip + 1, this->numchips);
+			        chip + 1, nanddev_ntargets(&this->base));
 			return -EINVAL;
 		}
 		numblocks = targetsize >> this->bbt_erase_shift;
@@ -550,7 +550,7 @@ static int search_bbt(struct nand_chip *this, uint8_t *buf,
 
 	/* Do we have a bbt per chip? */
 	if (td->options & NAND_BBT_PERCHIP) {
-		chips = this->numchips;
+		chips = nanddev_ntargets(&this->base);
 		bbtblocks = targetsize >> this->bbt_erase_shift;
 		startblock &= bbtblocks - 1;
 	} else {
@@ -643,7 +643,7 @@ static int get_bbt_block(struct nand_chip *this, struct nand_bbt_descr *td,
 
 	numblocks = (int)(targetsize >> this->bbt_erase_shift);
 	if (!(td->options & NAND_BBT_PERCHIP))
-		numblocks *= this->numchips;
+		numblocks *= nanddev_ntargets(&this->base);
 
 	/*
 	 * Automatic placement of the bad block table. Search direction
@@ -745,7 +745,7 @@ static int write_bbt(struct nand_chip *this, uint8_t *buf,
 		numblocks = (int)(targetsize >> this->bbt_erase_shift);
 		/* Full device write or specific chip? */
 		if (chipsel == -1) {
-			nrchips = this->numchips;
+			nrchips = nanddev_ntargets(&this->base);
 		} else {
 			nrchips = chipsel + 1;
 			chip = chipsel;
@@ -932,7 +932,7 @@ static int check_create(struct nand_chip *this, uint8_t *buf,
 
 	/* Do we have a bbt per chip? */
 	if (td->options & NAND_BBT_PERCHIP)
-		chips = this->numchips;
+		chips = nanddev_ntargets(&this->base);
 	else
 		chips = 1;
 
@@ -1111,7 +1111,7 @@ static void mark_bbt_region(struct nand_chip *this, struct nand_bbt_descr *td)
 
 	/* Do we have a bbt per chip? */
 	if (td->options & NAND_BBT_PERCHIP) {
-		chips = this->numchips;
+		chips = nanddev_ntargets(&this->base);
 		nrblocks = (int)(targetsize >> this->bbt_erase_shift);
 	} else {
 		chips = 1;
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index a127eb773b1a..e5a25ba75211 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -1014,7 +1014,6 @@ struct nand_legacy {
  *			      set to the actually used ONFI mode if the chip is
  *			      ONFI compliant or deduced from the datasheet if
  *			      the NAND chip is not ONFI compliant.
- * @numchips:		[INTERN] number of physical chips
  * @pagemask:		[INTERN] page number mask = number of (pages / chip) - 1
  * @data_buf:		[INTERN] buffer for data, size is (page size + oobsize).
  * @pagecache:		Structure containing page cache related fields
@@ -1028,8 +1027,9 @@ struct nand_legacy {
  * @data_interface:	[INTERN] NAND interface timing information
  * @cur_cs:		currently selected target. -1 means no target selected,
  *			otherwise we should always have cur_cs >= 0 &&
- *			cur_cs < numchips. NAND Controller drivers should not
- *			modify this value, but they're allowed to read it.
+ *			cur_cs < nanddev_ntargets(). NAND Controller drivers
+ *			should not modify this value, but they're allowed to
+ *			read it.
  * @read_retries:	[INTERN] the number of read retry modes supported
  * @bbt:		[INTERN] bad block table pointer
  * @bbt_td:		[REPLACEABLE] bad block table descriptor for flash
@@ -1060,7 +1060,6 @@ struct nand_chip {
 	int phys_erase_shift;
 	int bbt_erase_shift;
 	int chip_shift;
-	int numchips;
 	int pagemask;
 	u8 *data_buf;
 
-- 
2.19.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 15/15] mtd: rawnand: Get rid of chip->ecc_{strength, step}_ds
  2019-03-04 20:15 ` Miquel Raynal
@ 2019-03-04 20:15   ` Miquel Raynal
  -1 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

nand_device embeds a nand_ecc_req object which contains the minimum
strength and step-size required by the NAND device.

Drop the chip->ecc_{strength,step}_ds fields and use
chip->base.eccreq.{strength,step_size} instead.

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/atmel/nand-controller.c |  8 ++--
 drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c   | 11 ++++--
 drivers/mtd/nand/raw/marvell_nand.c          |  6 +--
 drivers/mtd/nand/raw/mtk_nand.c              |  4 +-
 drivers/mtd/nand/raw/nand_base.c             | 15 ++++----
 drivers/mtd/nand/raw/nand_esmt.c             | 10 ++---
 drivers/mtd/nand/raw/nand_hynix.c            | 40 ++++++++++----------
 drivers/mtd/nand/raw/nand_jedec.c            |  4 +-
 drivers/mtd/nand/raw/nand_micron.c           | 12 +++---
 drivers/mtd/nand/raw/nand_onfi.c             |  8 ++--
 drivers/mtd/nand/raw/nand_samsung.c          | 18 ++++-----
 drivers/mtd/nand/raw/nand_toshiba.c          | 10 ++---
 drivers/mtd/nand/raw/sunxi_nand.c            |  4 +-
 drivers/mtd/nand/raw/tegra_nand.c            |  8 ++--
 include/linux/mtd/rawnand.h                  |  8 ----
 15 files changed, 81 insertions(+), 85 deletions(-)

diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
index 5781fcf6b76c..9867e9115399 100644
--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
+++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
@@ -1068,15 +1068,15 @@ static int atmel_nand_pmecc_init(struct nand_chip *chip)
 		req.ecc.strength = ATMEL_PMECC_MAXIMIZE_ECC_STRENGTH;
 	else if (chip->ecc.strength)
 		req.ecc.strength = chip->ecc.strength;
-	else if (chip->ecc_strength_ds)
-		req.ecc.strength = chip->ecc_strength_ds;
+	else if (chip->base.eccreq.strength)
+		req.ecc.strength = chip->base.eccreq.strength;
 	else
 		req.ecc.strength = ATMEL_PMECC_MAXIMIZE_ECC_STRENGTH;
 
 	if (chip->ecc.size)
 		req.ecc.sectorsize = chip->ecc.size;
-	else if (chip->ecc_step_ds)
-		req.ecc.sectorsize = chip->ecc_step_ds;
+	else if (chip->base.eccreq.step_size)
+		req.ecc.sectorsize = chip->base.eccreq.step_size;
 	else
 		req.ecc.sectorsize = ATMEL_PMECC_SECTOR_SIZE_AUTO;
 
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
index 6151214eddec..dbefb6bac5c9 100644
--- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
@@ -204,7 +204,8 @@ static int set_geometry_by_ecc_info(struct gpmi_nand_data *this,
 	default:
 		dev_err(this->dev,
 			"unsupported nand chip. ecc bits : %d, ecc size : %d\n",
-			chip->ecc_strength_ds, chip->ecc_step_ds);
+			chip->base.eccreq.strength,
+			chip->base.eccreq.step_size);
 		return -EINVAL;
 	}
 	geo->ecc_chunk_size = ecc_step;
@@ -417,11 +418,13 @@ int common_nfc_set_geometry(struct gpmi_nand_data *this)
 
 	if ((of_property_read_bool(this->dev->of_node, "fsl,use-minimum-ecc"))
 				|| legacy_set_geometry(this)) {
-		if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0))
+		if (!(chip->base.eccreq.strength > 0 &&
+		      chip->base.eccreq.step_size > 0))
 			return -EINVAL;
 
-		return set_geometry_by_ecc_info(this, chip->ecc_strength_ds,
-						chip->ecc_step_ds);
+		return set_geometry_by_ecc_info(this,
+						chip->base.eccreq.strength,
+						chip->base.eccreq.step_size);
 	}
 
 	return 0;
diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c
index e8023b32be93..d21e808bb075 100644
--- a/drivers/mtd/nand/raw/marvell_nand.c
+++ b/drivers/mtd/nand/raw/marvell_nand.c
@@ -2248,9 +2248,9 @@ static int marvell_nand_ecc_init(struct mtd_info *mtd,
 	int ret;
 
 	if (ecc->mode != NAND_ECC_NONE && (!ecc->size || !ecc->strength)) {
-		if (chip->ecc_step_ds && chip->ecc_strength_ds) {
-			ecc->size = chip->ecc_step_ds;
-			ecc->strength = chip->ecc_strength_ds;
+		if (chip->base.eccreq.step_size && chip->base.eccreq.strength) {
+			ecc->size = chip->base.eccreq.step_size;
+			ecc->strength = chip->base.eccreq.strength;
 		} else {
 			dev_info(nfc->dev,
 				 "No minimum ECC strength, using 1b/512B\n");
diff --git a/drivers/mtd/nand/raw/mtk_nand.c b/drivers/mtd/nand/raw/mtk_nand.c
index b6b4602f5132..bfb89aca4155 100644
--- a/drivers/mtd/nand/raw/mtk_nand.c
+++ b/drivers/mtd/nand/raw/mtk_nand.c
@@ -1197,8 +1197,8 @@ static int mtk_nfc_ecc_init(struct device *dev, struct mtd_info *mtd)
 	/* if optional dt settings not present */
 	if (!nand->ecc.size || !nand->ecc.strength) {
 		/* use datasheet requirements */
-		nand->ecc.strength = nand->ecc_strength_ds;
-		nand->ecc.size = nand->ecc_step_ds;
+		nand->ecc.strength = nand->base.eccreq.strength;
+		nand->ecc.size = nand->base.eccreq.step_size;
 
 		/*
 		 * align eccstrength and eccsize
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index ce01824dcc62..1b4df8b851f8 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -4592,8 +4592,8 @@ static bool find_full_id_nand(struct nand_chip *chip,
 					   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);
+		chip->base.eccreq.strength = NAND_ECC_STRENGTH(type);
+		chip->base.eccreq.step_size = NAND_ECC_STEP(type);
 		chip->onfi_timing_mode_default =
 					type->onfi_timing_mode_default;
 
@@ -5266,8 +5266,8 @@ nand_match_ecc_req(struct nand_chip *chip,
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
 	const struct nand_ecc_step_info *stepinfo;
-	int req_step = chip->ecc_step_ds;
-	int req_strength = chip->ecc_strength_ds;
+	int req_step = chip->base.eccreq.step_size;
+	int req_strength = chip->base.eccreq.strength;
 	int req_corr, step_size, strength, nsteps, ecc_bytes, ecc_bytes_total;
 	int best_step, best_strength, best_ecc_bytes;
 	int best_ecc_bytes_total = INT_MAX;
@@ -5460,7 +5460,7 @@ static bool nand_ecc_strength_good(struct nand_chip *chip)
 	struct nand_ecc_ctrl *ecc = &chip->ecc;
 	int corr, ds_corr;
 
-	if (ecc->size == 0 || chip->ecc_step_ds == 0)
+	if (ecc->size == 0 || chip->base.eccreq.step_size == 0)
 		/* Not enough information */
 		return true;
 
@@ -5469,9 +5469,10 @@ static bool nand_ecc_strength_good(struct nand_chip *chip)
 	 * the correction density.
 	 */
 	corr = (mtd->writesize * ecc->strength) / ecc->size;
-	ds_corr = (mtd->writesize * chip->ecc_strength_ds) / chip->ecc_step_ds;
+	ds_corr = (mtd->writesize * chip->base.eccreq.strength) /
+		  chip->base.eccreq.step_size;
 
-	return corr >= ds_corr && ecc->strength >= chip->ecc_strength_ds;
+	return corr >= ds_corr && ecc->strength >= chip->base.eccreq.strength;
 }
 
 static int rawnand_erase(struct nand_device *nand, const struct nand_pos *pos)
diff --git a/drivers/mtd/nand/raw/nand_esmt.c b/drivers/mtd/nand/raw/nand_esmt.c
index 96f039a83bc8..3de5e89482f5 100644
--- a/drivers/mtd/nand/raw/nand_esmt.c
+++ b/drivers/mtd/nand/raw/nand_esmt.c
@@ -14,20 +14,20 @@ static void esmt_nand_decode_id(struct nand_chip *chip)
 
 	/* Extract ECC requirements from 5th id byte. */
 	if (chip->id.len >= 5 && nand_is_slc(chip)) {
-		chip->ecc_step_ds = 512;
+		chip->base.eccreq.step_size = 512;
 		switch (chip->id.data[4] & 0x3) {
 		case 0x0:
-			chip->ecc_strength_ds = 4;
+			chip->base.eccreq.strength = 4;
 			break;
 		case 0x1:
-			chip->ecc_strength_ds = 2;
+			chip->base.eccreq.strength = 2;
 			break;
 		case 0x2:
-			chip->ecc_strength_ds = 1;
+			chip->base.eccreq.strength = 1;
 			break;
 		default:
 			WARN(1, "Could not get ECC info");
-			chip->ecc_step_ds = 0;
+			chip->base.eccreq.step_size = 0;
 			break;
 		}
 	}
diff --git a/drivers/mtd/nand/raw/nand_hynix.c b/drivers/mtd/nand/raw/nand_hynix.c
index 272b934dffb7..821d221b83eb 100644
--- a/drivers/mtd/nand/raw/nand_hynix.c
+++ b/drivers/mtd/nand/raw/nand_hynix.c
@@ -508,30 +508,30 @@ static void hynix_nand_extract_ecc_requirements(struct nand_chip *chip,
 
 	if (valid_jedecid) {
 		/* Reference: H27UCG8T2E datasheet */
-		chip->ecc_step_ds = 1024;
+		chip->base.eccreq.step_size = 1024;
 
 		switch (ecc_level) {
 		case 0:
-			chip->ecc_step_ds = 0;
-			chip->ecc_strength_ds = 0;
+			chip->base.eccreq.step_size = 0;
+			chip->base.eccreq.strength = 0;
 			break;
 		case 1:
-			chip->ecc_strength_ds = 4;
+			chip->base.eccreq.strength = 4;
 			break;
 		case 2:
-			chip->ecc_strength_ds = 24;
+			chip->base.eccreq.strength = 24;
 			break;
 		case 3:
-			chip->ecc_strength_ds = 32;
+			chip->base.eccreq.strength = 32;
 			break;
 		case 4:
-			chip->ecc_strength_ds = 40;
+			chip->base.eccreq.strength = 40;
 			break;
 		case 5:
-			chip->ecc_strength_ds = 50;
+			chip->base.eccreq.strength = 50;
 			break;
 		case 6:
-			chip->ecc_strength_ds = 60;
+			chip->base.eccreq.strength = 60;
 			break;
 		default:
 			/*
@@ -552,14 +552,14 @@ static void hynix_nand_extract_ecc_requirements(struct nand_chip *chip,
 		if (nand_tech < 3) {
 			/* > 26nm, reference: H27UBG8T2A datasheet */
 			if (ecc_level < 5) {
-				chip->ecc_step_ds = 512;
-				chip->ecc_strength_ds = 1 << ecc_level;
+				chip->base.eccreq.step_size = 512;
+				chip->base.eccreq.strength = 1 << ecc_level;
 			} else if (ecc_level < 7) {
 				if (ecc_level == 5)
-					chip->ecc_step_ds = 2048;
+					chip->base.eccreq.step_size = 2048;
 				else
-					chip->ecc_step_ds = 1024;
-				chip->ecc_strength_ds = 24;
+					chip->base.eccreq.step_size = 1024;
+				chip->base.eccreq.strength = 24;
 			} else {
 				/*
 				 * We should never reach this case, but if that
@@ -572,14 +572,14 @@ static void hynix_nand_extract_ecc_requirements(struct nand_chip *chip,
 		} else {
 			/* <= 26nm, reference: H27UBG8T2B datasheet */
 			if (!ecc_level) {
-				chip->ecc_step_ds = 0;
-				chip->ecc_strength_ds = 0;
+				chip->base.eccreq.step_size = 0;
+				chip->base.eccreq.strength = 0;
 			} else if (ecc_level < 5) {
-				chip->ecc_step_ds = 512;
-				chip->ecc_strength_ds = 1 << (ecc_level - 1);
+				chip->base.eccreq.step_size = 512;
+				chip->base.eccreq.strength = 1 << (ecc_level - 1);
 			} else {
-				chip->ecc_step_ds = 1024;
-				chip->ecc_strength_ds = 24 +
+				chip->base.eccreq.step_size = 1024;
+				chip->base.eccreq.strength = 24 +
 							(8 * (ecc_level - 5));
 			}
 		}
diff --git a/drivers/mtd/nand/raw/nand_jedec.c b/drivers/mtd/nand/raw/nand_jedec.c
index 99e2f017c79b..9b540e76f84f 100644
--- a/drivers/mtd/nand/raw/nand_jedec.c
+++ b/drivers/mtd/nand/raw/nand_jedec.c
@@ -110,8 +110,8 @@ int nand_jedec_detect(struct nand_chip *chip)
 	ecc = &p->ecc_info[0];
 
 	if (ecc->codeword_size >= 9) {
-		chip->ecc_strength_ds = ecc->ecc_bits;
-		chip->ecc_step_ds = 1 << ecc->codeword_size;
+		chip->base.eccreq.strength = ecc->ecc_bits;
+		chip->base.eccreq.step_size = 1 << ecc->codeword_size;
 	} else {
 		pr_warn("Invalid codeword size\n");
 	}
diff --git a/drivers/mtd/nand/raw/nand_micron.c b/drivers/mtd/nand/raw/nand_micron.c
index 98ce6575aa64..7a2cef02eacd 100644
--- a/drivers/mtd/nand/raw/nand_micron.c
+++ b/drivers/mtd/nand/raw/nand_micron.c
@@ -391,7 +391,7 @@ static int micron_supports_on_die_ecc(struct nand_chip *chip)
 	/*
 	 * We only support on-die ECC of 4/512 or 8/512
 	 */
-	if  (chip->ecc_strength_ds != 4 && chip->ecc_strength_ds != 8)
+	if  (chip->base.eccreq.strength != 4 && chip->base.eccreq.strength != 8)
 		return MICRON_ON_DIE_UNSUPPORTED;
 
 	/* 0x2 means on-die ECC is available. */
@@ -424,7 +424,7 @@ static int micron_supports_on_die_ecc(struct nand_chip *chip)
 	/*
 	 * We only support on-die ECC of 4/512 or 8/512
 	 */
-	if  (chip->ecc_strength_ds != 4 && chip->ecc_strength_ds != 8)
+	if  (chip->base.eccreq.strength != 4 && chip->base.eccreq.strength != 8)
 		return MICRON_ON_DIE_UNSUPPORTED;
 
 	return MICRON_ON_DIE_SUPPORTED;
@@ -479,7 +479,7 @@ static int micron_nand_init(struct nand_chip *chip)
 		 * That's not needed for 8-bit ECC, because the status expose
 		 * a better approximation of the number of bitflips in a page.
 		 */
-		if (chip->ecc_strength_ds == 4) {
+		if (chip->base.eccreq.strength == 4) {
 			micron->ecc.rawbuf = kmalloc(mtd->writesize +
 						     mtd->oobsize,
 						     GFP_KERNEL);
@@ -489,16 +489,16 @@ static int micron_nand_init(struct nand_chip *chip)
 			}
 		}
 
-		if (chip->ecc_strength_ds == 4)
+		if (chip->base.eccreq.strength == 4)
 			mtd_set_ooblayout(mtd,
 					  &micron_nand_on_die_4_ooblayout_ops);
 		else
 			mtd_set_ooblayout(mtd,
 					  &micron_nand_on_die_8_ooblayout_ops);
 
-		chip->ecc.bytes = chip->ecc_strength_ds * 2;
+		chip->ecc.bytes = chip->base.eccreq.strength * 2;
 		chip->ecc.size = 512;
-		chip->ecc.strength = chip->ecc_strength_ds;
+		chip->ecc.strength = chip->base.eccreq.strength;
 		chip->ecc.algo = NAND_ECC_BCH;
 		chip->ecc.read_page = micron_nand_read_page_on_die_ecc;
 		chip->ecc.write_page = micron_nand_write_page_on_die_ecc;
diff --git a/drivers/mtd/nand/raw/nand_onfi.c b/drivers/mtd/nand/raw/nand_onfi.c
index 7b468e7214c7..0b879bd0a68c 100644
--- a/drivers/mtd/nand/raw/nand_onfi.c
+++ b/drivers/mtd/nand/raw/nand_onfi.c
@@ -94,8 +94,8 @@ static int nand_flash_detect_ext_param_page(struct nand_chip *chip,
 		goto ext_out;
 	}
 
-	chip->ecc_strength_ds = ecc->ecc_bits;
-	chip->ecc_step_ds = 1 << ecc->codeword_size;
+	chip->base.eccreq.strength = ecc->ecc_bits;
+	chip->base.eccreq.step_size = 1 << ecc->codeword_size;
 	ret = 0;
 
 ext_out:
@@ -252,8 +252,8 @@ int nand_onfi_detect(struct nand_chip *chip)
 		chip->options |= NAND_BUSWIDTH_16;
 
 	if (p->ecc_bits != 0xff) {
-		chip->ecc_strength_ds = p->ecc_bits;
-		chip->ecc_step_ds = 512;
+		chip->base.eccreq.strength = p->ecc_bits;
+		chip->base.eccreq.step_size = 512;
 	} else if (onfi_version >= 21 &&
 		(le16_to_cpu(p->features) & ONFI_FEATURE_EXT_PARAM_PAGE)) {
 
diff --git a/drivers/mtd/nand/raw/nand_samsung.c b/drivers/mtd/nand/raw/nand_samsung.c
index 9a9ad43cc97d..f7d7041b6213 100644
--- a/drivers/mtd/nand/raw/nand_samsung.c
+++ b/drivers/mtd/nand/raw/nand_samsung.c
@@ -80,23 +80,23 @@ static void samsung_nand_decode_id(struct nand_chip *chip)
 		/* Extract ECC requirements from 5th id byte*/
 		extid = (chip->id.data[4] >> 4) & 0x07;
 		if (extid < 5) {
-			chip->ecc_step_ds = 512;
-			chip->ecc_strength_ds = 1 << extid;
+			chip->base.eccreq.step_size = 512;
+			chip->base.eccreq.strength = 1 << extid;
 		} else {
-			chip->ecc_step_ds = 1024;
+			chip->base.eccreq.step_size = 1024;
 			switch (extid) {
 			case 5:
-				chip->ecc_strength_ds = 24;
+				chip->base.eccreq.strength = 24;
 				break;
 			case 6:
-				chip->ecc_strength_ds = 40;
+				chip->base.eccreq.strength = 40;
 				break;
 			case 7:
-				chip->ecc_strength_ds = 60;
+				chip->base.eccreq.strength = 60;
 				break;
 			default:
 				WARN(1, "Could not decode ECC info");
-				chip->ecc_step_ds = 0;
+				chip->base.eccreq.step_size = 0;
 			}
 		}
 	} else {
@@ -106,8 +106,8 @@ static void samsung_nand_decode_id(struct nand_chip *chip)
 			switch (chip->id.data[1]) {
 			/* K9F4G08U0D-S[I|C]B0(T00) */
 			case 0xDC:
-				chip->ecc_step_ds = 512;
-				chip->ecc_strength_ds = 1;
+				chip->base.eccreq.step_size = 512;
+				chip->base.eccreq.strength = 1;
 				break;
 
 			/* K9F1G08U0E 21nm chips do not support subpage write */
diff --git a/drivers/mtd/nand/raw/nand_toshiba.c b/drivers/mtd/nand/raw/nand_toshiba.c
index d8465049dfd6..13f9632f1cb4 100644
--- a/drivers/mtd/nand/raw/nand_toshiba.c
+++ b/drivers/mtd/nand/raw/nand_toshiba.c
@@ -130,20 +130,20 @@ static void toshiba_nand_decode_id(struct nand_chip *chip)
 	 *  - 24nm: 8 bit ECC for each 512Byte is required.
 	 */
 	if (chip->id.len >= 6 && nand_is_slc(chip)) {
-		chip->ecc_step_ds = 512;
+		chip->base.eccreq.step_size = 512;
 		switch (chip->id.data[5] & 0x7) {
 		case 0x4:
-			chip->ecc_strength_ds = 1;
+			chip->base.eccreq.strength = 1;
 			break;
 		case 0x5:
-			chip->ecc_strength_ds = 4;
+			chip->base.eccreq.strength = 4;
 			break;
 		case 0x6:
-			chip->ecc_strength_ds = 8;
+			chip->base.eccreq.strength = 8;
 			break;
 		default:
 			WARN(1, "Could not get ECC info");
-			chip->ecc_step_ds = 0;
+			chip->base.eccreq.step_size = 0;
 			break;
 		}
 	}
diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c
index d5de0a7114bc..69599854fdd6 100644
--- a/drivers/mtd/nand/raw/sunxi_nand.c
+++ b/drivers/mtd/nand/raw/sunxi_nand.c
@@ -1821,8 +1821,8 @@ static int sunxi_nand_attach_chip(struct nand_chip *nand)
 	nand->options |= NAND_SUBPAGE_READ;
 
 	if (!ecc->size) {
-		ecc->size = nand->ecc_step_ds;
-		ecc->strength = nand->ecc_strength_ds;
+		ecc->size = nand->base.eccreq.step_size;
+		ecc->strength = nand->base.eccreq.strength;
 	}
 
 	if (!ecc->size || !ecc->strength)
diff --git a/drivers/mtd/nand/raw/tegra_nand.c b/drivers/mtd/nand/raw/tegra_nand.c
index 13be32c38194..3cc9a4c41443 100644
--- a/drivers/mtd/nand/raw/tegra_nand.c
+++ b/drivers/mtd/nand/raw/tegra_nand.c
@@ -853,7 +853,7 @@ static int tegra_nand_get_strength(struct nand_chip *chip, const int *strength,
 		} else {
 			strength_sel = strength[i];
 
-			if (strength_sel < chip->ecc_strength_ds)
+			if (strength_sel < chip->base.eccreq.strength)
 				continue;
 		}
 
@@ -917,9 +917,9 @@ static int tegra_nand_attach_chip(struct nand_chip *chip)
 	chip->ecc.mode = NAND_ECC_HW;
 	chip->ecc.size = 512;
 	chip->ecc.steps = mtd->writesize / chip->ecc.size;
-	if (chip->ecc_step_ds != 512) {
+	if (chip->base.eccreq.step_size != 512) {
 		dev_err(ctrl->dev, "Unsupported step size %d\n",
-			chip->ecc_step_ds);
+			chip->base.eccreq.step_size);
 		return -EINVAL;
 	}
 
@@ -950,7 +950,7 @@ static int tegra_nand_attach_chip(struct nand_chip *chip)
 		if (ret < 0) {
 			dev_err(ctrl->dev,
 				"No valid strength found, minimum %d\n",
-				chip->ecc_strength_ds);
+				chip->base.eccreq.strength);
 			return ret;
 		}
 
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index e5a25ba75211..14748183508b 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -1004,12 +1004,6 @@ struct nand_legacy {
  * @badblockbits:	[INTERN] minimum number of set bits in a good block's
  *			bad block marker position; i.e., BBM == 11110111b is
  *			not bad when badblockbits == 7
- * @ecc_strength_ds:	[INTERN] ECC correctability from the datasheet.
- *			Minimum amount of bit errors per @ecc_step_ds guaranteed
- *			to be correctable. If unknown, set to zero.
- * @ecc_step_ds:	[INTERN] ECC step required by the @ecc_strength_ds,
- *			also from the datasheet. It is the recommended ECC step
- *			size, if known; if unknown, set to zero.
  * @onfi_timing_mode_default: [INTERN] default ONFI timing mode. This field is
  *			      set to the actually used ONFI mode if the chip is
  *			      ONFI compliant or deduced from the datasheet if
@@ -1069,8 +1063,6 @@ struct nand_chip {
 	} pagecache;
 
 	int subpagesize;
-	uint16_t ecc_strength_ds;
-	uint16_t ecc_step_ds;
 	int onfi_timing_mode_default;
 	int badblockpos;
 	int badblockbits;
-- 
2.19.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* [PATCH v2 15/15] mtd: rawnand: Get rid of chip->ecc_{strength, step}_ds
@ 2019-03-04 20:15   ` Miquel Raynal
  0 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-03-04 20:15 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Tudor Ambarus, Julien Su, Schrempf Frieder,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Mason Yang, linux-arm-kernel

From: Boris Brezillon <bbrezillon@kernel.org>

nand_device embeds a nand_ecc_req object which contains the minimum
strength and step-size required by the NAND device.

Drop the chip->ecc_{strength,step}_ds fields and use
chip->base.eccreq.{strength,step_size} instead.

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/atmel/nand-controller.c |  8 ++--
 drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c   | 11 ++++--
 drivers/mtd/nand/raw/marvell_nand.c          |  6 +--
 drivers/mtd/nand/raw/mtk_nand.c              |  4 +-
 drivers/mtd/nand/raw/nand_base.c             | 15 ++++----
 drivers/mtd/nand/raw/nand_esmt.c             | 10 ++---
 drivers/mtd/nand/raw/nand_hynix.c            | 40 ++++++++++----------
 drivers/mtd/nand/raw/nand_jedec.c            |  4 +-
 drivers/mtd/nand/raw/nand_micron.c           | 12 +++---
 drivers/mtd/nand/raw/nand_onfi.c             |  8 ++--
 drivers/mtd/nand/raw/nand_samsung.c          | 18 ++++-----
 drivers/mtd/nand/raw/nand_toshiba.c          | 10 ++---
 drivers/mtd/nand/raw/sunxi_nand.c            |  4 +-
 drivers/mtd/nand/raw/tegra_nand.c            |  8 ++--
 include/linux/mtd/rawnand.h                  |  8 ----
 15 files changed, 81 insertions(+), 85 deletions(-)

diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c
index 5781fcf6b76c..9867e9115399 100644
--- a/drivers/mtd/nand/raw/atmel/nand-controller.c
+++ b/drivers/mtd/nand/raw/atmel/nand-controller.c
@@ -1068,15 +1068,15 @@ static int atmel_nand_pmecc_init(struct nand_chip *chip)
 		req.ecc.strength = ATMEL_PMECC_MAXIMIZE_ECC_STRENGTH;
 	else if (chip->ecc.strength)
 		req.ecc.strength = chip->ecc.strength;
-	else if (chip->ecc_strength_ds)
-		req.ecc.strength = chip->ecc_strength_ds;
+	else if (chip->base.eccreq.strength)
+		req.ecc.strength = chip->base.eccreq.strength;
 	else
 		req.ecc.strength = ATMEL_PMECC_MAXIMIZE_ECC_STRENGTH;
 
 	if (chip->ecc.size)
 		req.ecc.sectorsize = chip->ecc.size;
-	else if (chip->ecc_step_ds)
-		req.ecc.sectorsize = chip->ecc_step_ds;
+	else if (chip->base.eccreq.step_size)
+		req.ecc.sectorsize = chip->base.eccreq.step_size;
 	else
 		req.ecc.sectorsize = ATMEL_PMECC_SECTOR_SIZE_AUTO;
 
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
index 6151214eddec..dbefb6bac5c9 100644
--- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
@@ -204,7 +204,8 @@ static int set_geometry_by_ecc_info(struct gpmi_nand_data *this,
 	default:
 		dev_err(this->dev,
 			"unsupported nand chip. ecc bits : %d, ecc size : %d\n",
-			chip->ecc_strength_ds, chip->ecc_step_ds);
+			chip->base.eccreq.strength,
+			chip->base.eccreq.step_size);
 		return -EINVAL;
 	}
 	geo->ecc_chunk_size = ecc_step;
@@ -417,11 +418,13 @@ int common_nfc_set_geometry(struct gpmi_nand_data *this)
 
 	if ((of_property_read_bool(this->dev->of_node, "fsl,use-minimum-ecc"))
 				|| legacy_set_geometry(this)) {
-		if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0))
+		if (!(chip->base.eccreq.strength > 0 &&
+		      chip->base.eccreq.step_size > 0))
 			return -EINVAL;
 
-		return set_geometry_by_ecc_info(this, chip->ecc_strength_ds,
-						chip->ecc_step_ds);
+		return set_geometry_by_ecc_info(this,
+						chip->base.eccreq.strength,
+						chip->base.eccreq.step_size);
 	}
 
 	return 0;
diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c
index e8023b32be93..d21e808bb075 100644
--- a/drivers/mtd/nand/raw/marvell_nand.c
+++ b/drivers/mtd/nand/raw/marvell_nand.c
@@ -2248,9 +2248,9 @@ static int marvell_nand_ecc_init(struct mtd_info *mtd,
 	int ret;
 
 	if (ecc->mode != NAND_ECC_NONE && (!ecc->size || !ecc->strength)) {
-		if (chip->ecc_step_ds && chip->ecc_strength_ds) {
-			ecc->size = chip->ecc_step_ds;
-			ecc->strength = chip->ecc_strength_ds;
+		if (chip->base.eccreq.step_size && chip->base.eccreq.strength) {
+			ecc->size = chip->base.eccreq.step_size;
+			ecc->strength = chip->base.eccreq.strength;
 		} else {
 			dev_info(nfc->dev,
 				 "No minimum ECC strength, using 1b/512B\n");
diff --git a/drivers/mtd/nand/raw/mtk_nand.c b/drivers/mtd/nand/raw/mtk_nand.c
index b6b4602f5132..bfb89aca4155 100644
--- a/drivers/mtd/nand/raw/mtk_nand.c
+++ b/drivers/mtd/nand/raw/mtk_nand.c
@@ -1197,8 +1197,8 @@ static int mtk_nfc_ecc_init(struct device *dev, struct mtd_info *mtd)
 	/* if optional dt settings not present */
 	if (!nand->ecc.size || !nand->ecc.strength) {
 		/* use datasheet requirements */
-		nand->ecc.strength = nand->ecc_strength_ds;
-		nand->ecc.size = nand->ecc_step_ds;
+		nand->ecc.strength = nand->base.eccreq.strength;
+		nand->ecc.size = nand->base.eccreq.step_size;
 
 		/*
 		 * align eccstrength and eccsize
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
index ce01824dcc62..1b4df8b851f8 100644
--- a/drivers/mtd/nand/raw/nand_base.c
+++ b/drivers/mtd/nand/raw/nand_base.c
@@ -4592,8 +4592,8 @@ static bool find_full_id_nand(struct nand_chip *chip,
 					   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);
+		chip->base.eccreq.strength = NAND_ECC_STRENGTH(type);
+		chip->base.eccreq.step_size = NAND_ECC_STEP(type);
 		chip->onfi_timing_mode_default =
 					type->onfi_timing_mode_default;
 
@@ -5266,8 +5266,8 @@ nand_match_ecc_req(struct nand_chip *chip,
 {
 	struct mtd_info *mtd = nand_to_mtd(chip);
 	const struct nand_ecc_step_info *stepinfo;
-	int req_step = chip->ecc_step_ds;
-	int req_strength = chip->ecc_strength_ds;
+	int req_step = chip->base.eccreq.step_size;
+	int req_strength = chip->base.eccreq.strength;
 	int req_corr, step_size, strength, nsteps, ecc_bytes, ecc_bytes_total;
 	int best_step, best_strength, best_ecc_bytes;
 	int best_ecc_bytes_total = INT_MAX;
@@ -5460,7 +5460,7 @@ static bool nand_ecc_strength_good(struct nand_chip *chip)
 	struct nand_ecc_ctrl *ecc = &chip->ecc;
 	int corr, ds_corr;
 
-	if (ecc->size == 0 || chip->ecc_step_ds == 0)
+	if (ecc->size == 0 || chip->base.eccreq.step_size == 0)
 		/* Not enough information */
 		return true;
 
@@ -5469,9 +5469,10 @@ static bool nand_ecc_strength_good(struct nand_chip *chip)
 	 * the correction density.
 	 */
 	corr = (mtd->writesize * ecc->strength) / ecc->size;
-	ds_corr = (mtd->writesize * chip->ecc_strength_ds) / chip->ecc_step_ds;
+	ds_corr = (mtd->writesize * chip->base.eccreq.strength) /
+		  chip->base.eccreq.step_size;
 
-	return corr >= ds_corr && ecc->strength >= chip->ecc_strength_ds;
+	return corr >= ds_corr && ecc->strength >= chip->base.eccreq.strength;
 }
 
 static int rawnand_erase(struct nand_device *nand, const struct nand_pos *pos)
diff --git a/drivers/mtd/nand/raw/nand_esmt.c b/drivers/mtd/nand/raw/nand_esmt.c
index 96f039a83bc8..3de5e89482f5 100644
--- a/drivers/mtd/nand/raw/nand_esmt.c
+++ b/drivers/mtd/nand/raw/nand_esmt.c
@@ -14,20 +14,20 @@ static void esmt_nand_decode_id(struct nand_chip *chip)
 
 	/* Extract ECC requirements from 5th id byte. */
 	if (chip->id.len >= 5 && nand_is_slc(chip)) {
-		chip->ecc_step_ds = 512;
+		chip->base.eccreq.step_size = 512;
 		switch (chip->id.data[4] & 0x3) {
 		case 0x0:
-			chip->ecc_strength_ds = 4;
+			chip->base.eccreq.strength = 4;
 			break;
 		case 0x1:
-			chip->ecc_strength_ds = 2;
+			chip->base.eccreq.strength = 2;
 			break;
 		case 0x2:
-			chip->ecc_strength_ds = 1;
+			chip->base.eccreq.strength = 1;
 			break;
 		default:
 			WARN(1, "Could not get ECC info");
-			chip->ecc_step_ds = 0;
+			chip->base.eccreq.step_size = 0;
 			break;
 		}
 	}
diff --git a/drivers/mtd/nand/raw/nand_hynix.c b/drivers/mtd/nand/raw/nand_hynix.c
index 272b934dffb7..821d221b83eb 100644
--- a/drivers/mtd/nand/raw/nand_hynix.c
+++ b/drivers/mtd/nand/raw/nand_hynix.c
@@ -508,30 +508,30 @@ static void hynix_nand_extract_ecc_requirements(struct nand_chip *chip,
 
 	if (valid_jedecid) {
 		/* Reference: H27UCG8T2E datasheet */
-		chip->ecc_step_ds = 1024;
+		chip->base.eccreq.step_size = 1024;
 
 		switch (ecc_level) {
 		case 0:
-			chip->ecc_step_ds = 0;
-			chip->ecc_strength_ds = 0;
+			chip->base.eccreq.step_size = 0;
+			chip->base.eccreq.strength = 0;
 			break;
 		case 1:
-			chip->ecc_strength_ds = 4;
+			chip->base.eccreq.strength = 4;
 			break;
 		case 2:
-			chip->ecc_strength_ds = 24;
+			chip->base.eccreq.strength = 24;
 			break;
 		case 3:
-			chip->ecc_strength_ds = 32;
+			chip->base.eccreq.strength = 32;
 			break;
 		case 4:
-			chip->ecc_strength_ds = 40;
+			chip->base.eccreq.strength = 40;
 			break;
 		case 5:
-			chip->ecc_strength_ds = 50;
+			chip->base.eccreq.strength = 50;
 			break;
 		case 6:
-			chip->ecc_strength_ds = 60;
+			chip->base.eccreq.strength = 60;
 			break;
 		default:
 			/*
@@ -552,14 +552,14 @@ static void hynix_nand_extract_ecc_requirements(struct nand_chip *chip,
 		if (nand_tech < 3) {
 			/* > 26nm, reference: H27UBG8T2A datasheet */
 			if (ecc_level < 5) {
-				chip->ecc_step_ds = 512;
-				chip->ecc_strength_ds = 1 << ecc_level;
+				chip->base.eccreq.step_size = 512;
+				chip->base.eccreq.strength = 1 << ecc_level;
 			} else if (ecc_level < 7) {
 				if (ecc_level == 5)
-					chip->ecc_step_ds = 2048;
+					chip->base.eccreq.step_size = 2048;
 				else
-					chip->ecc_step_ds = 1024;
-				chip->ecc_strength_ds = 24;
+					chip->base.eccreq.step_size = 1024;
+				chip->base.eccreq.strength = 24;
 			} else {
 				/*
 				 * We should never reach this case, but if that
@@ -572,14 +572,14 @@ static void hynix_nand_extract_ecc_requirements(struct nand_chip *chip,
 		} else {
 			/* <= 26nm, reference: H27UBG8T2B datasheet */
 			if (!ecc_level) {
-				chip->ecc_step_ds = 0;
-				chip->ecc_strength_ds = 0;
+				chip->base.eccreq.step_size = 0;
+				chip->base.eccreq.strength = 0;
 			} else if (ecc_level < 5) {
-				chip->ecc_step_ds = 512;
-				chip->ecc_strength_ds = 1 << (ecc_level - 1);
+				chip->base.eccreq.step_size = 512;
+				chip->base.eccreq.strength = 1 << (ecc_level - 1);
 			} else {
-				chip->ecc_step_ds = 1024;
-				chip->ecc_strength_ds = 24 +
+				chip->base.eccreq.step_size = 1024;
+				chip->base.eccreq.strength = 24 +
 							(8 * (ecc_level - 5));
 			}
 		}
diff --git a/drivers/mtd/nand/raw/nand_jedec.c b/drivers/mtd/nand/raw/nand_jedec.c
index 99e2f017c79b..9b540e76f84f 100644
--- a/drivers/mtd/nand/raw/nand_jedec.c
+++ b/drivers/mtd/nand/raw/nand_jedec.c
@@ -110,8 +110,8 @@ int nand_jedec_detect(struct nand_chip *chip)
 	ecc = &p->ecc_info[0];
 
 	if (ecc->codeword_size >= 9) {
-		chip->ecc_strength_ds = ecc->ecc_bits;
-		chip->ecc_step_ds = 1 << ecc->codeword_size;
+		chip->base.eccreq.strength = ecc->ecc_bits;
+		chip->base.eccreq.step_size = 1 << ecc->codeword_size;
 	} else {
 		pr_warn("Invalid codeword size\n");
 	}
diff --git a/drivers/mtd/nand/raw/nand_micron.c b/drivers/mtd/nand/raw/nand_micron.c
index 98ce6575aa64..7a2cef02eacd 100644
--- a/drivers/mtd/nand/raw/nand_micron.c
+++ b/drivers/mtd/nand/raw/nand_micron.c
@@ -391,7 +391,7 @@ static int micron_supports_on_die_ecc(struct nand_chip *chip)
 	/*
 	 * We only support on-die ECC of 4/512 or 8/512
 	 */
-	if  (chip->ecc_strength_ds != 4 && chip->ecc_strength_ds != 8)
+	if  (chip->base.eccreq.strength != 4 && chip->base.eccreq.strength != 8)
 		return MICRON_ON_DIE_UNSUPPORTED;
 
 	/* 0x2 means on-die ECC is available. */
@@ -424,7 +424,7 @@ static int micron_supports_on_die_ecc(struct nand_chip *chip)
 	/*
 	 * We only support on-die ECC of 4/512 or 8/512
 	 */
-	if  (chip->ecc_strength_ds != 4 && chip->ecc_strength_ds != 8)
+	if  (chip->base.eccreq.strength != 4 && chip->base.eccreq.strength != 8)
 		return MICRON_ON_DIE_UNSUPPORTED;
 
 	return MICRON_ON_DIE_SUPPORTED;
@@ -479,7 +479,7 @@ static int micron_nand_init(struct nand_chip *chip)
 		 * That's not needed for 8-bit ECC, because the status expose
 		 * a better approximation of the number of bitflips in a page.
 		 */
-		if (chip->ecc_strength_ds == 4) {
+		if (chip->base.eccreq.strength == 4) {
 			micron->ecc.rawbuf = kmalloc(mtd->writesize +
 						     mtd->oobsize,
 						     GFP_KERNEL);
@@ -489,16 +489,16 @@ static int micron_nand_init(struct nand_chip *chip)
 			}
 		}
 
-		if (chip->ecc_strength_ds == 4)
+		if (chip->base.eccreq.strength == 4)
 			mtd_set_ooblayout(mtd,
 					  &micron_nand_on_die_4_ooblayout_ops);
 		else
 			mtd_set_ooblayout(mtd,
 					  &micron_nand_on_die_8_ooblayout_ops);
 
-		chip->ecc.bytes = chip->ecc_strength_ds * 2;
+		chip->ecc.bytes = chip->base.eccreq.strength * 2;
 		chip->ecc.size = 512;
-		chip->ecc.strength = chip->ecc_strength_ds;
+		chip->ecc.strength = chip->base.eccreq.strength;
 		chip->ecc.algo = NAND_ECC_BCH;
 		chip->ecc.read_page = micron_nand_read_page_on_die_ecc;
 		chip->ecc.write_page = micron_nand_write_page_on_die_ecc;
diff --git a/drivers/mtd/nand/raw/nand_onfi.c b/drivers/mtd/nand/raw/nand_onfi.c
index 7b468e7214c7..0b879bd0a68c 100644
--- a/drivers/mtd/nand/raw/nand_onfi.c
+++ b/drivers/mtd/nand/raw/nand_onfi.c
@@ -94,8 +94,8 @@ static int nand_flash_detect_ext_param_page(struct nand_chip *chip,
 		goto ext_out;
 	}
 
-	chip->ecc_strength_ds = ecc->ecc_bits;
-	chip->ecc_step_ds = 1 << ecc->codeword_size;
+	chip->base.eccreq.strength = ecc->ecc_bits;
+	chip->base.eccreq.step_size = 1 << ecc->codeword_size;
 	ret = 0;
 
 ext_out:
@@ -252,8 +252,8 @@ int nand_onfi_detect(struct nand_chip *chip)
 		chip->options |= NAND_BUSWIDTH_16;
 
 	if (p->ecc_bits != 0xff) {
-		chip->ecc_strength_ds = p->ecc_bits;
-		chip->ecc_step_ds = 512;
+		chip->base.eccreq.strength = p->ecc_bits;
+		chip->base.eccreq.step_size = 512;
 	} else if (onfi_version >= 21 &&
 		(le16_to_cpu(p->features) & ONFI_FEATURE_EXT_PARAM_PAGE)) {
 
diff --git a/drivers/mtd/nand/raw/nand_samsung.c b/drivers/mtd/nand/raw/nand_samsung.c
index 9a9ad43cc97d..f7d7041b6213 100644
--- a/drivers/mtd/nand/raw/nand_samsung.c
+++ b/drivers/mtd/nand/raw/nand_samsung.c
@@ -80,23 +80,23 @@ static void samsung_nand_decode_id(struct nand_chip *chip)
 		/* Extract ECC requirements from 5th id byte*/
 		extid = (chip->id.data[4] >> 4) & 0x07;
 		if (extid < 5) {
-			chip->ecc_step_ds = 512;
-			chip->ecc_strength_ds = 1 << extid;
+			chip->base.eccreq.step_size = 512;
+			chip->base.eccreq.strength = 1 << extid;
 		} else {
-			chip->ecc_step_ds = 1024;
+			chip->base.eccreq.step_size = 1024;
 			switch (extid) {
 			case 5:
-				chip->ecc_strength_ds = 24;
+				chip->base.eccreq.strength = 24;
 				break;
 			case 6:
-				chip->ecc_strength_ds = 40;
+				chip->base.eccreq.strength = 40;
 				break;
 			case 7:
-				chip->ecc_strength_ds = 60;
+				chip->base.eccreq.strength = 60;
 				break;
 			default:
 				WARN(1, "Could not decode ECC info");
-				chip->ecc_step_ds = 0;
+				chip->base.eccreq.step_size = 0;
 			}
 		}
 	} else {
@@ -106,8 +106,8 @@ static void samsung_nand_decode_id(struct nand_chip *chip)
 			switch (chip->id.data[1]) {
 			/* K9F4G08U0D-S[I|C]B0(T00) */
 			case 0xDC:
-				chip->ecc_step_ds = 512;
-				chip->ecc_strength_ds = 1;
+				chip->base.eccreq.step_size = 512;
+				chip->base.eccreq.strength = 1;
 				break;
 
 			/* K9F1G08U0E 21nm chips do not support subpage write */
diff --git a/drivers/mtd/nand/raw/nand_toshiba.c b/drivers/mtd/nand/raw/nand_toshiba.c
index d8465049dfd6..13f9632f1cb4 100644
--- a/drivers/mtd/nand/raw/nand_toshiba.c
+++ b/drivers/mtd/nand/raw/nand_toshiba.c
@@ -130,20 +130,20 @@ static void toshiba_nand_decode_id(struct nand_chip *chip)
 	 *  - 24nm: 8 bit ECC for each 512Byte is required.
 	 */
 	if (chip->id.len >= 6 && nand_is_slc(chip)) {
-		chip->ecc_step_ds = 512;
+		chip->base.eccreq.step_size = 512;
 		switch (chip->id.data[5] & 0x7) {
 		case 0x4:
-			chip->ecc_strength_ds = 1;
+			chip->base.eccreq.strength = 1;
 			break;
 		case 0x5:
-			chip->ecc_strength_ds = 4;
+			chip->base.eccreq.strength = 4;
 			break;
 		case 0x6:
-			chip->ecc_strength_ds = 8;
+			chip->base.eccreq.strength = 8;
 			break;
 		default:
 			WARN(1, "Could not get ECC info");
-			chip->ecc_step_ds = 0;
+			chip->base.eccreq.step_size = 0;
 			break;
 		}
 	}
diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c
index d5de0a7114bc..69599854fdd6 100644
--- a/drivers/mtd/nand/raw/sunxi_nand.c
+++ b/drivers/mtd/nand/raw/sunxi_nand.c
@@ -1821,8 +1821,8 @@ static int sunxi_nand_attach_chip(struct nand_chip *nand)
 	nand->options |= NAND_SUBPAGE_READ;
 
 	if (!ecc->size) {
-		ecc->size = nand->ecc_step_ds;
-		ecc->strength = nand->ecc_strength_ds;
+		ecc->size = nand->base.eccreq.step_size;
+		ecc->strength = nand->base.eccreq.strength;
 	}
 
 	if (!ecc->size || !ecc->strength)
diff --git a/drivers/mtd/nand/raw/tegra_nand.c b/drivers/mtd/nand/raw/tegra_nand.c
index 13be32c38194..3cc9a4c41443 100644
--- a/drivers/mtd/nand/raw/tegra_nand.c
+++ b/drivers/mtd/nand/raw/tegra_nand.c
@@ -853,7 +853,7 @@ static int tegra_nand_get_strength(struct nand_chip *chip, const int *strength,
 		} else {
 			strength_sel = strength[i];
 
-			if (strength_sel < chip->ecc_strength_ds)
+			if (strength_sel < chip->base.eccreq.strength)
 				continue;
 		}
 
@@ -917,9 +917,9 @@ static int tegra_nand_attach_chip(struct nand_chip *chip)
 	chip->ecc.mode = NAND_ECC_HW;
 	chip->ecc.size = 512;
 	chip->ecc.steps = mtd->writesize / chip->ecc.size;
-	if (chip->ecc_step_ds != 512) {
+	if (chip->base.eccreq.step_size != 512) {
 		dev_err(ctrl->dev, "Unsupported step size %d\n",
-			chip->ecc_step_ds);
+			chip->base.eccreq.step_size);
 		return -EINVAL;
 	}
 
@@ -950,7 +950,7 @@ static int tegra_nand_attach_chip(struct nand_chip *chip)
 		if (ret < 0) {
 			dev_err(ctrl->dev,
 				"No valid strength found, minimum %d\n",
-				chip->ecc_strength_ds);
+				chip->base.eccreq.strength);
 			return ret;
 		}
 
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
index e5a25ba75211..14748183508b 100644
--- a/include/linux/mtd/rawnand.h
+++ b/include/linux/mtd/rawnand.h
@@ -1004,12 +1004,6 @@ struct nand_legacy {
  * @badblockbits:	[INTERN] minimum number of set bits in a good block's
  *			bad block marker position; i.e., BBM == 11110111b is
  *			not bad when badblockbits == 7
- * @ecc_strength_ds:	[INTERN] ECC correctability from the datasheet.
- *			Minimum amount of bit errors per @ecc_step_ds guaranteed
- *			to be correctable. If unknown, set to zero.
- * @ecc_step_ds:	[INTERN] ECC step required by the @ecc_strength_ds,
- *			also from the datasheet. It is the recommended ECC step
- *			size, if known; if unknown, set to zero.
  * @onfi_timing_mode_default: [INTERN] default ONFI timing mode. This field is
  *			      set to the actually used ONFI mode if the chip is
  *			      ONFI compliant or deduced from the datasheet if
@@ -1069,8 +1063,6 @@ struct nand_chip {
 	} pagecache;
 
 	int subpagesize;
-	uint16_t ecc_strength_ds;
-	uint16_t ecc_step_ds;
 	int onfi_timing_mode_default;
 	int badblockpos;
 	int badblockbits;
-- 
2.19.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 07/15] mtd: rawnand: Fill memorg during detection
  2019-03-04 20:15   ` Miquel Raynal
@ 2019-03-21  9:03     ` Schrempf Frieder
  -1 siblings, 0 replies; 66+ messages in thread
From: Schrempf Frieder @ 2019-03-21  9:03 UTC (permalink / raw)
  To: Miquel Raynal, Boris Brezillon, Richard Weinberger,
	David Woodhouse, Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Julien Su, Masahiro Yamada, linux-mtd,
	Thomas Petazzoni, Mason Yang, linux-arm-kernel

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;
> 
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 07/15] mtd: rawnand: Fill memorg during detection
@ 2019-03-21  9:03     ` Schrempf Frieder
  0 siblings, 0 replies; 66+ messages in thread
From: Schrempf Frieder @ 2019-03-21  9:03 UTC (permalink / raw)
  To: Miquel Raynal, Boris Brezillon, Richard Weinberger,
	David Woodhouse, Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Julien Su, Masahiro Yamada, linux-mtd,
	Thomas Petazzoni, Mason Yang, linux-arm-kernel

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;
> 
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 13/15] mtd: rawnand: Get rid of chip->chipsize
  2019-03-04 20:15   ` Miquel Raynal
@ 2019-03-21  9:03     ` Schrempf Frieder
  -1 siblings, 0 replies; 66+ messages in thread
From: Schrempf Frieder @ 2019-03-21  9:03 UTC (permalink / raw)
  To: Miquel Raynal, Boris Brezillon, Richard Weinberger,
	David Woodhouse, Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Julien Su, Masahiro Yamada, linux-mtd,
	Thomas Petazzoni, Mason Yang, linux-arm-kernel

On 04.03.19 21:15, Miquel Raynal wrote:
> From: Boris Brezillon <bbrezillon@kernel.org>
> 
> The target size can now be returned by nanddev_get_targetsize(). Get
> rid of the chip->chipsize field and use this helper instead.
> 
> 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>

> ---
>   .../mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c  |  2 +-
>   drivers/mtd/nand/raw/denali.c                 |  1 -
>   drivers/mtd/nand/raw/fsl_elbc_nand.c          |  2 +-
>   drivers/mtd/nand/raw/fsl_ifc_nand.c           |  2 +-
>   drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c    |  2 +-
>   drivers/mtd/nand/raw/jz4740_nand.c            |  2 +-
>   drivers/mtd/nand/raw/nand_base.c              | 17 ++++++-------
>   drivers/mtd/nand/raw/nand_bbt.c               | 25 ++++++++++++-------
>   drivers/mtd/nand/raw/nand_jedec.c             |  2 --
>   drivers/mtd/nand/raw/nand_onfi.c              |  2 --
>   drivers/mtd/nand/raw/nandsim.c                |  6 +++--
>   drivers/mtd/nand/raw/sh_flctl.c               |  9 ++++---
>   include/linux/mtd/rawnand.h                   |  2 --
>   13 files changed, 38 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c b/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c
> index a37cbfe56567..a53ffb3d64b0 100644
> --- a/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c
> +++ b/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c
> @@ -428,7 +428,7 @@ int bcm47xxnflash_ops_bcm4706_init(struct bcm47xxnflash *b47n)
>   	}
>   
>   	/* Configure FLASH */
> -	chipsize = b47n->nand_chip.chipsize >> 20;
> +	chipsize = nanddev_target_size(&b47n->nand_chip.base) >> 20;
>   	tbits = ffs(chipsize); /* find first bit set */
>   	if (!tbits || tbits != fls(chipsize)) {
>   		pr_err("Invalid flash size: 0x%lX\n", chipsize);
> diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c
> index 86e5df403beb..3ec0242b0aa2 100644
> --- a/drivers/mtd/nand/raw/denali.c
> +++ b/drivers/mtd/nand/raw/denali.c
> @@ -1157,7 +1157,6 @@ static int denali_multidev_fixup(struct denali_nand_info *denali)
>   	mtd->erasesize <<= 1;
>   	mtd->writesize <<= 1;
>   	mtd->oobsize <<= 1;
> -	chip->chipsize <<= 1;
>   	chip->page_shift += 1;
>   	chip->phys_erase_shift += 1;
>   	chip->bbt_erase_shift += 1;
> diff --git a/drivers/mtd/nand/raw/fsl_elbc_nand.c b/drivers/mtd/nand/raw/fsl_elbc_nand.c
> index 70f0d2b450ea..1d960a6cd691 100644
> --- a/drivers/mtd/nand/raw/fsl_elbc_nand.c
> +++ b/drivers/mtd/nand/raw/fsl_elbc_nand.c
> @@ -655,7 +655,7 @@ static int fsl_elbc_attach_chip(struct nand_chip *chip)
>   	dev_dbg(priv->dev, "fsl_elbc_init: nand->numchips = %d\n",
>   	        chip->numchips);
>   	dev_dbg(priv->dev, "fsl_elbc_init: nand->chipsize = %lld\n",
> -	        chip->chipsize);
> +	        nanddev_target_size(&chip->base));
>   	dev_dbg(priv->dev, "fsl_elbc_init: nand->pagemask = %8x\n",
>   	        chip->pagemask);
>   	dev_dbg(priv->dev, "fsl_elbc_init: nand->legacy.chip_delay = %d\n",
> diff --git a/drivers/mtd/nand/raw/fsl_ifc_nand.c b/drivers/mtd/nand/raw/fsl_ifc_nand.c
> index e65d274399f9..a9e8f89aeebd 100644
> --- a/drivers/mtd/nand/raw/fsl_ifc_nand.c
> +++ b/drivers/mtd/nand/raw/fsl_ifc_nand.c
> @@ -724,7 +724,7 @@ static int fsl_ifc_attach_chip(struct nand_chip *chip)
>   	dev_dbg(priv->dev, "%s: nand->numchips = %d\n", __func__,
>   							chip->numchips);
>   	dev_dbg(priv->dev, "%s: nand->chipsize = %lld\n", __func__,
> -							chip->chipsize);
> +	        nanddev_target_size(&chip->base));
>   	dev_dbg(priv->dev, "%s: nand->pagemask = %8x\n", __func__,
>   							chip->pagemask);
>   	dev_dbg(priv->dev, "%s: nand->legacy.chip_delay = %d\n", __func__,
> diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
> index 05f6f68e4e0d..6151214eddec 100644
> --- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
> +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
> @@ -1753,7 +1753,7 @@ static int mx23_boot_init(struct gpmi_nand_data  *this)
>   	dev_dbg(dev, "Transcribing bad block marks...\n");
>   
>   	/* Compute the number of blocks in the entire medium. */
> -	block_count = chip->chipsize >> chip->phys_erase_shift;
> +	block_count = nanddev_eraseblocks_per_target(&chip->base);
>   
>   	/*
>   	 * Loop over all the blocks in the medium, transcribing block marks as
> diff --git a/drivers/mtd/nand/raw/jz4740_nand.c b/drivers/mtd/nand/raw/jz4740_nand.c
> index 76a32ad2cf83..06690b3603b1 100644
> --- a/drivers/mtd/nand/raw/jz4740_nand.c
> +++ b/drivers/mtd/nand/raw/jz4740_nand.c
> @@ -356,7 +356,7 @@ static int jz_nand_detect_bank(struct platform_device *pdev,
>   		/* Update size of the MTD. */
>   		chip->numchips++;
>   		memorg->ntargets++;
> -		mtd->size += chip->chipsize;
> +		mtd->size += nanddev_target_size(&chip->base);
>   	}
>   
>   	dev_info(&pdev->dev, "Found chip %zu on bank %i\n", chipnr, bank);
> diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
> index 91fd508cf406..427c80abef3f 100644
> --- a/drivers/mtd/nand/raw/nand_base.c
> +++ b/drivers/mtd/nand/raw/nand_base.c
> @@ -4587,7 +4587,6 @@ static bool find_full_id_nand(struct nand_chip *chip,
>   		mtd->oobsize = memorg->oobsize;
>   
>   		memorg->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 *
> @@ -4678,6 +4677,7 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
>   	int busw, ret;
>   	u8 *id_data = chip->id.data;
>   	u8 maf_id, dev_id;
> +	u64 targetsize;
>   
>   	/*
>   	 * Let's start by initializing memorg fields that might be left
> @@ -4782,8 +4782,6 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
>   	if (!chip->parameters.model)
>   		return -ENOMEM;
>   
> -	chip->chipsize = (uint64_t)type->chipsize << 20;
> -
>   	if (!type->pagesize)
>   		nand_manufacturer_detect(chip);
>   	else
> @@ -4825,14 +4823,15 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
>   	/* Calculate the address shift from the page size */
>   	chip->page_shift = ffs(mtd->writesize) - 1;
>   	/* Convert chipsize to number of pages per chip -1 */
> -	chip->pagemask = (chip->chipsize >> chip->page_shift) - 1;
> +	targetsize = nanddev_target_size(&chip->base);
> +	chip->pagemask = (targetsize >> chip->page_shift) - 1;
>   
>   	chip->bbt_erase_shift = chip->phys_erase_shift =
>   		ffs(mtd->erasesize) - 1;
> -	if (chip->chipsize & 0xffffffff)
> -		chip->chip_shift = ffs((unsigned)chip->chipsize) - 1;
> +	if (targetsize & 0xffffffff)
> +		chip->chip_shift = ffs((unsigned)targetsize) - 1;
>   	else {
> -		chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32));
> +		chip->chip_shift = ffs((unsigned)(targetsize >> 32));
>   		chip->chip_shift += 32 - 1;
>   	}
>   
> @@ -4848,7 +4847,7 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
>   	pr_info("%s %s\n", nand_manufacturer_name(manufacturer),
>   		chip->parameters.model);
>   	pr_info("%d MiB, %s, erase size: %d KiB, page size: %d, OOB size: %d\n",
> -		(int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC",
> +		(int)(targetsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC",
>   		mtd->erasesize >> 10, mtd->writesize, mtd->oobsize);
>   	return 0;
>   
> @@ -5093,7 +5092,7 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips,
>   	/* Store the number of chips and calc total size for mtd */
>   	memorg->ntargets = i;
>   	chip->numchips = i;
> -	mtd->size = i * chip->chipsize;
> +	mtd->size = i * nanddev_target_size(&chip->base);
>   
>   	return 0;
>   }
> diff --git a/drivers/mtd/nand/raw/nand_bbt.c b/drivers/mtd/nand/raw/nand_bbt.c
> index 0b96c4cab967..e3308857b2ee 100644
> --- a/drivers/mtd/nand/raw/nand_bbt.c
> +++ b/drivers/mtd/nand/raw/nand_bbt.c
> @@ -264,6 +264,7 @@ static int read_abs_bbt(struct nand_chip *this, uint8_t *buf,
>   			struct nand_bbt_descr *td, int chip)
>   {
>   	struct mtd_info *mtd = nand_to_mtd(this);
> +	u64 targetsize = nanddev_target_size(&this->base);
>   	int res = 0, i;
>   
>   	if (td->options & NAND_BBT_PERCHIP) {
> @@ -271,11 +272,11 @@ static int read_abs_bbt(struct nand_chip *this, uint8_t *buf,
>   		for (i = 0; i < this->numchips; i++) {
>   			if (chip == -1 || chip == i)
>   				res = read_bbt(this, buf, td->pages[i],
> -					this->chipsize >> this->bbt_erase_shift,
> +					targetsize >> this->bbt_erase_shift,
>   					td, offs);
>   			if (res)
>   				return res;
> -			offs += this->chipsize >> this->bbt_erase_shift;
> +			offs += targetsize >> this->bbt_erase_shift;
>   		}
>   	} else {
>   		res = read_bbt(this, buf, td->pages[0],
> @@ -459,6 +460,7 @@ static int scan_block_fast(struct nand_chip *this, struct nand_bbt_descr *bd,
>   static int create_bbt(struct nand_chip *this, uint8_t *buf,
>   		      struct nand_bbt_descr *bd, int chip)
>   {
> +	u64 targetsize = nanddev_target_size(&this->base);
>   	struct mtd_info *mtd = nand_to_mtd(this);
>   	int i, numblocks, numpages;
>   	int startblock;
> @@ -481,7 +483,7 @@ static int create_bbt(struct nand_chip *this, uint8_t *buf,
>   			       chip + 1, this->numchips);
>   			return -EINVAL;
>   		}
> -		numblocks = this->chipsize >> this->bbt_erase_shift;
> +		numblocks = targetsize >> this->bbt_erase_shift;
>   		startblock = chip * numblocks;
>   		numblocks += startblock;
>   		from = (loff_t)startblock << this->bbt_erase_shift;
> @@ -529,6 +531,7 @@ static int create_bbt(struct nand_chip *this, uint8_t *buf,
>   static int search_bbt(struct nand_chip *this, uint8_t *buf,
>   		      struct nand_bbt_descr *td)
>   {
> +	u64 targetsize = nanddev_target_size(&this->base);
>   	struct mtd_info *mtd = nand_to_mtd(this);
>   	int i, chips;
>   	int startblock, block, dir;
> @@ -548,7 +551,7 @@ static int search_bbt(struct nand_chip *this, uint8_t *buf,
>   	/* Do we have a bbt per chip? */
>   	if (td->options & NAND_BBT_PERCHIP) {
>   		chips = this->numchips;
> -		bbtblocks = this->chipsize >> this->bbt_erase_shift;
> +		bbtblocks = targetsize >> this->bbt_erase_shift;
>   		startblock &= bbtblocks - 1;
>   	} else {
>   		chips = 1;
> @@ -576,7 +579,7 @@ static int search_bbt(struct nand_chip *this, uint8_t *buf,
>   				break;
>   			}
>   		}
> -		startblock += this->chipsize >> this->bbt_erase_shift;
> +		startblock += targetsize >> this->bbt_erase_shift;
>   	}
>   	/* Check, if we found a bbt for each requested chip */
>   	for (i = 0; i < chips; i++) {
> @@ -626,6 +629,7 @@ static void search_read_bbts(struct nand_chip *this, uint8_t *buf,
>   static int get_bbt_block(struct nand_chip *this, struct nand_bbt_descr *td,
>   			 struct nand_bbt_descr *md, int chip)
>   {
> +	u64 targetsize = nanddev_target_size(&this->base);
>   	int startblock, dir, page, numblocks, i;
>   
>   	/*
> @@ -637,7 +641,7 @@ static int get_bbt_block(struct nand_chip *this, struct nand_bbt_descr *td,
>   		return td->pages[chip] >>
>   				(this->bbt_erase_shift - this->page_shift);
>   
> -	numblocks = (int)(this->chipsize >> this->bbt_erase_shift);
> +	numblocks = (int)(targetsize >> this->bbt_erase_shift);
>   	if (!(td->options & NAND_BBT_PERCHIP))
>   		numblocks *= this->numchips;
>   
> @@ -717,6 +721,7 @@ static int write_bbt(struct nand_chip *this, uint8_t *buf,
>   		     struct nand_bbt_descr *td, struct nand_bbt_descr *md,
>   		     int chipsel)
>   {
> +	u64 targetsize = nanddev_target_size(&this->base);
>   	struct mtd_info *mtd = nand_to_mtd(this);
>   	struct erase_info einfo;
>   	int i, res, chip = 0;
> @@ -737,7 +742,7 @@ static int write_bbt(struct nand_chip *this, uint8_t *buf,
>   		rcode = 0xff;
>   	/* Write bad block table per chip rather than per device? */
>   	if (td->options & NAND_BBT_PERCHIP) {
> -		numblocks = (int)(this->chipsize >> this->bbt_erase_shift);
> +		numblocks = (int)(targetsize >> this->bbt_erase_shift);
>   		/* Full device write or specific chip? */
>   		if (chipsel == -1) {
>   			nrchips = this->numchips;
> @@ -1099,6 +1104,7 @@ static int nand_update_bbt(struct nand_chip *this, loff_t offs)
>    */
>   static void mark_bbt_region(struct nand_chip *this, struct nand_bbt_descr *td)
>   {
> +	u64 targetsize = nanddev_target_size(&this->base);
>   	struct mtd_info *mtd = nand_to_mtd(this);
>   	int i, j, chips, block, nrblocks, update;
>   	uint8_t oldval;
> @@ -1106,7 +1112,7 @@ static void mark_bbt_region(struct nand_chip *this, struct nand_bbt_descr *td)
>   	/* Do we have a bbt per chip? */
>   	if (td->options & NAND_BBT_PERCHIP) {
>   		chips = this->numchips;
> -		nrblocks = (int)(this->chipsize >> this->bbt_erase_shift);
> +		nrblocks = (int)(targetsize >> this->bbt_erase_shift);
>   	} else {
>   		chips = 1;
>   		nrblocks = (int)(mtd->size >> this->bbt_erase_shift);
> @@ -1159,6 +1165,7 @@ static void mark_bbt_region(struct nand_chip *this, struct nand_bbt_descr *td)
>    */
>   static void verify_bbt_descr(struct nand_chip *this, struct nand_bbt_descr *bd)
>   {
> +	u64 targetsize = nanddev_target_size(&this->base);
>   	struct mtd_info *mtd = nand_to_mtd(this);
>   	u32 pattern_len;
>   	u32 bits;
> @@ -1187,7 +1194,7 @@ static void verify_bbt_descr(struct nand_chip *this, struct nand_bbt_descr *bd)
>   	}
>   
>   	if (bd->options & NAND_BBT_PERCHIP)
> -		table_size = this->chipsize >> this->bbt_erase_shift;
> +		table_size = targetsize >> this->bbt_erase_shift;
>   	else
>   		table_size = mtd->size >> this->bbt_erase_shift;
>   	table_size >>= 3;
> diff --git a/drivers/mtd/nand/raw/nand_jedec.c b/drivers/mtd/nand/raw/nand_jedec.c
> index 030f178c7a97..99e2f017c79b 100644
> --- a/drivers/mtd/nand/raw/nand_jedec.c
> +++ b/drivers/mtd/nand/raw/nand_jedec.c
> @@ -101,8 +101,6 @@ int nand_jedec_detect(struct nand_chip *chip)
>   	/* Please reference to the comment for nand_flash_detect_onfi. */
>   	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;
>   
>   	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 a6b9fc9a335b..7b468e7214c7 100644
> --- a/drivers/mtd/nand/raw/nand_onfi.c
> +++ b/drivers/mtd/nand/raw/nand_onfi.c
> @@ -246,8 +246,6 @@ int nand_onfi_detect(struct nand_chip *chip)
>   	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;
>   
>   	if (le16_to_cpu(p->features) & ONFI_FEATURE_16_BIT_BUS)
> diff --git a/drivers/mtd/nand/raw/nandsim.c b/drivers/mtd/nand/raw/nandsim.c
> index 07144c992d54..670abe8d59ca 100644
> --- a/drivers/mtd/nand/raw/nandsim.c
> +++ b/drivers/mtd/nand/raw/nandsim.c
> @@ -2303,6 +2303,7 @@ 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;
>   
>   		memorg = nanddev_get_memorg(&chip->base);
>   
> @@ -2311,12 +2312,13 @@ static int __init ns_init_module(void)
>   			retval = -EINVAL;
>   			goto err_exit;
>   		}
> +
>   		/* 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;
> +		targetsize = nanddev_target_size(&chip->base);
>   		chip->chip_shift = ffs(nsmtd->erasesize) + overridesize - 1;
> -		chip->pagemask = (chip->chipsize >> chip->page_shift) - 1;
> +		chip->pagemask = (targetsize >> chip->page_shift) - 1;
>   	}
>   
>   	if ((retval = setup_wear_reporting(nsmtd)) != 0)
> diff --git a/drivers/mtd/nand/raw/sh_flctl.c b/drivers/mtd/nand/raw/sh_flctl.c
> index cf6b1be1cf9c..3f610040f0c3 100644
> --- a/drivers/mtd/nand/raw/sh_flctl.c
> +++ b/drivers/mtd/nand/raw/sh_flctl.c
> @@ -986,6 +986,7 @@ static void flctl_read_buf(struct nand_chip *chip, uint8_t *buf, int len)
>   
>   static int flctl_chip_attach_chip(struct nand_chip *chip)
>   {
> +	u64 targetsize = nanddev_target_size(&chip->base);
>   	struct mtd_info *mtd = nand_to_mtd(chip);
>   	struct sh_flctl *flctl = mtd_to_flctl(mtd);
>   
> @@ -998,11 +999,11 @@ static int flctl_chip_attach_chip(struct nand_chip *chip)
>   
>   	if (mtd->writesize == 512) {
>   		flctl->page_size = 0;
> -		if (chip->chipsize > (32 << 20)) {
> +		if (targetsize > (32 << 20)) {
>   			/* big than 32MB */
>   			flctl->rw_ADRCNT = ADRCNT_4;
>   			flctl->erase_ADRCNT = ADRCNT_3;
> -		} else if (chip->chipsize > (2 << 16)) {
> +		} else if (targetsize > (2 << 16)) {
>   			/* big than 128KB */
>   			flctl->rw_ADRCNT = ADRCNT_3;
>   			flctl->erase_ADRCNT = ADRCNT_2;
> @@ -1012,11 +1013,11 @@ static int flctl_chip_attach_chip(struct nand_chip *chip)
>   		}
>   	} else {
>   		flctl->page_size = 1;
> -		if (chip->chipsize > (128 << 20)) {
> +		if (targetsize > (128 << 20)) {
>   			/* big than 128MB */
>   			flctl->rw_ADRCNT = ADRCNT2_E;
>   			flctl->erase_ADRCNT = ADRCNT_3;
> -		} else if (chip->chipsize > (8 << 16)) {
> +		} else if (targetsize > (8 << 16)) {
>   			/* big than 512KB */
>   			flctl->rw_ADRCNT = ADRCNT_4;
>   			flctl->erase_ADRCNT = ADRCNT_2;
> diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
> index 24ecd9a4f952..a127eb773b1a 100644
> --- a/include/linux/mtd/rawnand.h
> +++ b/include/linux/mtd/rawnand.h
> @@ -1015,7 +1015,6 @@ struct nand_legacy {
>    *			      ONFI compliant or deduced from the datasheet if
>    *			      the NAND chip is not ONFI compliant.
>    * @numchips:		[INTERN] number of physical chips
> - * @chipsize:		[INTERN] the size of one chip for multichip arrays
>    * @pagemask:		[INTERN] page number mask = number of (pages / chip) - 1
>    * @data_buf:		[INTERN] buffer for data, size is (page size + oobsize).
>    * @pagecache:		Structure containing page cache related fields
> @@ -1062,7 +1061,6 @@ struct nand_chip {
>   	int bbt_erase_shift;
>   	int chip_shift;
>   	int numchips;
> -	uint64_t chipsize;
>   	int pagemask;
>   	u8 *data_buf;
>   
> 
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 13/15] mtd: rawnand: Get rid of chip->chipsize
@ 2019-03-21  9:03     ` Schrempf Frieder
  0 siblings, 0 replies; 66+ messages in thread
From: Schrempf Frieder @ 2019-03-21  9:03 UTC (permalink / raw)
  To: Miquel Raynal, Boris Brezillon, Richard Weinberger,
	David Woodhouse, Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Julien Su, Masahiro Yamada, linux-mtd,
	Thomas Petazzoni, Mason Yang, linux-arm-kernel

On 04.03.19 21:15, Miquel Raynal wrote:
> From: Boris Brezillon <bbrezillon@kernel.org>
> 
> The target size can now be returned by nanddev_get_targetsize(). Get
> rid of the chip->chipsize field and use this helper instead.
> 
> 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>

> ---
>   .../mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c  |  2 +-
>   drivers/mtd/nand/raw/denali.c                 |  1 -
>   drivers/mtd/nand/raw/fsl_elbc_nand.c          |  2 +-
>   drivers/mtd/nand/raw/fsl_ifc_nand.c           |  2 +-
>   drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c    |  2 +-
>   drivers/mtd/nand/raw/jz4740_nand.c            |  2 +-
>   drivers/mtd/nand/raw/nand_base.c              | 17 ++++++-------
>   drivers/mtd/nand/raw/nand_bbt.c               | 25 ++++++++++++-------
>   drivers/mtd/nand/raw/nand_jedec.c             |  2 --
>   drivers/mtd/nand/raw/nand_onfi.c              |  2 --
>   drivers/mtd/nand/raw/nandsim.c                |  6 +++--
>   drivers/mtd/nand/raw/sh_flctl.c               |  9 ++++---
>   include/linux/mtd/rawnand.h                   |  2 --
>   13 files changed, 38 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c b/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c
> index a37cbfe56567..a53ffb3d64b0 100644
> --- a/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c
> +++ b/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c
> @@ -428,7 +428,7 @@ int bcm47xxnflash_ops_bcm4706_init(struct bcm47xxnflash *b47n)
>   	}
>   
>   	/* Configure FLASH */
> -	chipsize = b47n->nand_chip.chipsize >> 20;
> +	chipsize = nanddev_target_size(&b47n->nand_chip.base) >> 20;
>   	tbits = ffs(chipsize); /* find first bit set */
>   	if (!tbits || tbits != fls(chipsize)) {
>   		pr_err("Invalid flash size: 0x%lX\n", chipsize);
> diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c
> index 86e5df403beb..3ec0242b0aa2 100644
> --- a/drivers/mtd/nand/raw/denali.c
> +++ b/drivers/mtd/nand/raw/denali.c
> @@ -1157,7 +1157,6 @@ static int denali_multidev_fixup(struct denali_nand_info *denali)
>   	mtd->erasesize <<= 1;
>   	mtd->writesize <<= 1;
>   	mtd->oobsize <<= 1;
> -	chip->chipsize <<= 1;
>   	chip->page_shift += 1;
>   	chip->phys_erase_shift += 1;
>   	chip->bbt_erase_shift += 1;
> diff --git a/drivers/mtd/nand/raw/fsl_elbc_nand.c b/drivers/mtd/nand/raw/fsl_elbc_nand.c
> index 70f0d2b450ea..1d960a6cd691 100644
> --- a/drivers/mtd/nand/raw/fsl_elbc_nand.c
> +++ b/drivers/mtd/nand/raw/fsl_elbc_nand.c
> @@ -655,7 +655,7 @@ static int fsl_elbc_attach_chip(struct nand_chip *chip)
>   	dev_dbg(priv->dev, "fsl_elbc_init: nand->numchips = %d\n",
>   	        chip->numchips);
>   	dev_dbg(priv->dev, "fsl_elbc_init: nand->chipsize = %lld\n",
> -	        chip->chipsize);
> +	        nanddev_target_size(&chip->base));
>   	dev_dbg(priv->dev, "fsl_elbc_init: nand->pagemask = %8x\n",
>   	        chip->pagemask);
>   	dev_dbg(priv->dev, "fsl_elbc_init: nand->legacy.chip_delay = %d\n",
> diff --git a/drivers/mtd/nand/raw/fsl_ifc_nand.c b/drivers/mtd/nand/raw/fsl_ifc_nand.c
> index e65d274399f9..a9e8f89aeebd 100644
> --- a/drivers/mtd/nand/raw/fsl_ifc_nand.c
> +++ b/drivers/mtd/nand/raw/fsl_ifc_nand.c
> @@ -724,7 +724,7 @@ static int fsl_ifc_attach_chip(struct nand_chip *chip)
>   	dev_dbg(priv->dev, "%s: nand->numchips = %d\n", __func__,
>   							chip->numchips);
>   	dev_dbg(priv->dev, "%s: nand->chipsize = %lld\n", __func__,
> -							chip->chipsize);
> +	        nanddev_target_size(&chip->base));
>   	dev_dbg(priv->dev, "%s: nand->pagemask = %8x\n", __func__,
>   							chip->pagemask);
>   	dev_dbg(priv->dev, "%s: nand->legacy.chip_delay = %d\n", __func__,
> diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
> index 05f6f68e4e0d..6151214eddec 100644
> --- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
> +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c
> @@ -1753,7 +1753,7 @@ static int mx23_boot_init(struct gpmi_nand_data  *this)
>   	dev_dbg(dev, "Transcribing bad block marks...\n");
>   
>   	/* Compute the number of blocks in the entire medium. */
> -	block_count = chip->chipsize >> chip->phys_erase_shift;
> +	block_count = nanddev_eraseblocks_per_target(&chip->base);
>   
>   	/*
>   	 * Loop over all the blocks in the medium, transcribing block marks as
> diff --git a/drivers/mtd/nand/raw/jz4740_nand.c b/drivers/mtd/nand/raw/jz4740_nand.c
> index 76a32ad2cf83..06690b3603b1 100644
> --- a/drivers/mtd/nand/raw/jz4740_nand.c
> +++ b/drivers/mtd/nand/raw/jz4740_nand.c
> @@ -356,7 +356,7 @@ static int jz_nand_detect_bank(struct platform_device *pdev,
>   		/* Update size of the MTD. */
>   		chip->numchips++;
>   		memorg->ntargets++;
> -		mtd->size += chip->chipsize;
> +		mtd->size += nanddev_target_size(&chip->base);
>   	}
>   
>   	dev_info(&pdev->dev, "Found chip %zu on bank %i\n", chipnr, bank);
> diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
> index 91fd508cf406..427c80abef3f 100644
> --- a/drivers/mtd/nand/raw/nand_base.c
> +++ b/drivers/mtd/nand/raw/nand_base.c
> @@ -4587,7 +4587,6 @@ static bool find_full_id_nand(struct nand_chip *chip,
>   		mtd->oobsize = memorg->oobsize;
>   
>   		memorg->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 *
> @@ -4678,6 +4677,7 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
>   	int busw, ret;
>   	u8 *id_data = chip->id.data;
>   	u8 maf_id, dev_id;
> +	u64 targetsize;
>   
>   	/*
>   	 * Let's start by initializing memorg fields that might be left
> @@ -4782,8 +4782,6 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
>   	if (!chip->parameters.model)
>   		return -ENOMEM;
>   
> -	chip->chipsize = (uint64_t)type->chipsize << 20;
> -
>   	if (!type->pagesize)
>   		nand_manufacturer_detect(chip);
>   	else
> @@ -4825,14 +4823,15 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
>   	/* Calculate the address shift from the page size */
>   	chip->page_shift = ffs(mtd->writesize) - 1;
>   	/* Convert chipsize to number of pages per chip -1 */
> -	chip->pagemask = (chip->chipsize >> chip->page_shift) - 1;
> +	targetsize = nanddev_target_size(&chip->base);
> +	chip->pagemask = (targetsize >> chip->page_shift) - 1;
>   
>   	chip->bbt_erase_shift = chip->phys_erase_shift =
>   		ffs(mtd->erasesize) - 1;
> -	if (chip->chipsize & 0xffffffff)
> -		chip->chip_shift = ffs((unsigned)chip->chipsize) - 1;
> +	if (targetsize & 0xffffffff)
> +		chip->chip_shift = ffs((unsigned)targetsize) - 1;
>   	else {
> -		chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32));
> +		chip->chip_shift = ffs((unsigned)(targetsize >> 32));
>   		chip->chip_shift += 32 - 1;
>   	}
>   
> @@ -4848,7 +4847,7 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
>   	pr_info("%s %s\n", nand_manufacturer_name(manufacturer),
>   		chip->parameters.model);
>   	pr_info("%d MiB, %s, erase size: %d KiB, page size: %d, OOB size: %d\n",
> -		(int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC",
> +		(int)(targetsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC",
>   		mtd->erasesize >> 10, mtd->writesize, mtd->oobsize);
>   	return 0;
>   
> @@ -5093,7 +5092,7 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips,
>   	/* Store the number of chips and calc total size for mtd */
>   	memorg->ntargets = i;
>   	chip->numchips = i;
> -	mtd->size = i * chip->chipsize;
> +	mtd->size = i * nanddev_target_size(&chip->base);
>   
>   	return 0;
>   }
> diff --git a/drivers/mtd/nand/raw/nand_bbt.c b/drivers/mtd/nand/raw/nand_bbt.c
> index 0b96c4cab967..e3308857b2ee 100644
> --- a/drivers/mtd/nand/raw/nand_bbt.c
> +++ b/drivers/mtd/nand/raw/nand_bbt.c
> @@ -264,6 +264,7 @@ static int read_abs_bbt(struct nand_chip *this, uint8_t *buf,
>   			struct nand_bbt_descr *td, int chip)
>   {
>   	struct mtd_info *mtd = nand_to_mtd(this);
> +	u64 targetsize = nanddev_target_size(&this->base);
>   	int res = 0, i;
>   
>   	if (td->options & NAND_BBT_PERCHIP) {
> @@ -271,11 +272,11 @@ static int read_abs_bbt(struct nand_chip *this, uint8_t *buf,
>   		for (i = 0; i < this->numchips; i++) {
>   			if (chip == -1 || chip == i)
>   				res = read_bbt(this, buf, td->pages[i],
> -					this->chipsize >> this->bbt_erase_shift,
> +					targetsize >> this->bbt_erase_shift,
>   					td, offs);
>   			if (res)
>   				return res;
> -			offs += this->chipsize >> this->bbt_erase_shift;
> +			offs += targetsize >> this->bbt_erase_shift;
>   		}
>   	} else {
>   		res = read_bbt(this, buf, td->pages[0],
> @@ -459,6 +460,7 @@ static int scan_block_fast(struct nand_chip *this, struct nand_bbt_descr *bd,
>   static int create_bbt(struct nand_chip *this, uint8_t *buf,
>   		      struct nand_bbt_descr *bd, int chip)
>   {
> +	u64 targetsize = nanddev_target_size(&this->base);
>   	struct mtd_info *mtd = nand_to_mtd(this);
>   	int i, numblocks, numpages;
>   	int startblock;
> @@ -481,7 +483,7 @@ static int create_bbt(struct nand_chip *this, uint8_t *buf,
>   			       chip + 1, this->numchips);
>   			return -EINVAL;
>   		}
> -		numblocks = this->chipsize >> this->bbt_erase_shift;
> +		numblocks = targetsize >> this->bbt_erase_shift;
>   		startblock = chip * numblocks;
>   		numblocks += startblock;
>   		from = (loff_t)startblock << this->bbt_erase_shift;
> @@ -529,6 +531,7 @@ static int create_bbt(struct nand_chip *this, uint8_t *buf,
>   static int search_bbt(struct nand_chip *this, uint8_t *buf,
>   		      struct nand_bbt_descr *td)
>   {
> +	u64 targetsize = nanddev_target_size(&this->base);
>   	struct mtd_info *mtd = nand_to_mtd(this);
>   	int i, chips;
>   	int startblock, block, dir;
> @@ -548,7 +551,7 @@ static int search_bbt(struct nand_chip *this, uint8_t *buf,
>   	/* Do we have a bbt per chip? */
>   	if (td->options & NAND_BBT_PERCHIP) {
>   		chips = this->numchips;
> -		bbtblocks = this->chipsize >> this->bbt_erase_shift;
> +		bbtblocks = targetsize >> this->bbt_erase_shift;
>   		startblock &= bbtblocks - 1;
>   	} else {
>   		chips = 1;
> @@ -576,7 +579,7 @@ static int search_bbt(struct nand_chip *this, uint8_t *buf,
>   				break;
>   			}
>   		}
> -		startblock += this->chipsize >> this->bbt_erase_shift;
> +		startblock += targetsize >> this->bbt_erase_shift;
>   	}
>   	/* Check, if we found a bbt for each requested chip */
>   	for (i = 0; i < chips; i++) {
> @@ -626,6 +629,7 @@ static void search_read_bbts(struct nand_chip *this, uint8_t *buf,
>   static int get_bbt_block(struct nand_chip *this, struct nand_bbt_descr *td,
>   			 struct nand_bbt_descr *md, int chip)
>   {
> +	u64 targetsize = nanddev_target_size(&this->base);
>   	int startblock, dir, page, numblocks, i;
>   
>   	/*
> @@ -637,7 +641,7 @@ static int get_bbt_block(struct nand_chip *this, struct nand_bbt_descr *td,
>   		return td->pages[chip] >>
>   				(this->bbt_erase_shift - this->page_shift);
>   
> -	numblocks = (int)(this->chipsize >> this->bbt_erase_shift);
> +	numblocks = (int)(targetsize >> this->bbt_erase_shift);
>   	if (!(td->options & NAND_BBT_PERCHIP))
>   		numblocks *= this->numchips;
>   
> @@ -717,6 +721,7 @@ static int write_bbt(struct nand_chip *this, uint8_t *buf,
>   		     struct nand_bbt_descr *td, struct nand_bbt_descr *md,
>   		     int chipsel)
>   {
> +	u64 targetsize = nanddev_target_size(&this->base);
>   	struct mtd_info *mtd = nand_to_mtd(this);
>   	struct erase_info einfo;
>   	int i, res, chip = 0;
> @@ -737,7 +742,7 @@ static int write_bbt(struct nand_chip *this, uint8_t *buf,
>   		rcode = 0xff;
>   	/* Write bad block table per chip rather than per device? */
>   	if (td->options & NAND_BBT_PERCHIP) {
> -		numblocks = (int)(this->chipsize >> this->bbt_erase_shift);
> +		numblocks = (int)(targetsize >> this->bbt_erase_shift);
>   		/* Full device write or specific chip? */
>   		if (chipsel == -1) {
>   			nrchips = this->numchips;
> @@ -1099,6 +1104,7 @@ static int nand_update_bbt(struct nand_chip *this, loff_t offs)
>    */
>   static void mark_bbt_region(struct nand_chip *this, struct nand_bbt_descr *td)
>   {
> +	u64 targetsize = nanddev_target_size(&this->base);
>   	struct mtd_info *mtd = nand_to_mtd(this);
>   	int i, j, chips, block, nrblocks, update;
>   	uint8_t oldval;
> @@ -1106,7 +1112,7 @@ static void mark_bbt_region(struct nand_chip *this, struct nand_bbt_descr *td)
>   	/* Do we have a bbt per chip? */
>   	if (td->options & NAND_BBT_PERCHIP) {
>   		chips = this->numchips;
> -		nrblocks = (int)(this->chipsize >> this->bbt_erase_shift);
> +		nrblocks = (int)(targetsize >> this->bbt_erase_shift);
>   	} else {
>   		chips = 1;
>   		nrblocks = (int)(mtd->size >> this->bbt_erase_shift);
> @@ -1159,6 +1165,7 @@ static void mark_bbt_region(struct nand_chip *this, struct nand_bbt_descr *td)
>    */
>   static void verify_bbt_descr(struct nand_chip *this, struct nand_bbt_descr *bd)
>   {
> +	u64 targetsize = nanddev_target_size(&this->base);
>   	struct mtd_info *mtd = nand_to_mtd(this);
>   	u32 pattern_len;
>   	u32 bits;
> @@ -1187,7 +1194,7 @@ static void verify_bbt_descr(struct nand_chip *this, struct nand_bbt_descr *bd)
>   	}
>   
>   	if (bd->options & NAND_BBT_PERCHIP)
> -		table_size = this->chipsize >> this->bbt_erase_shift;
> +		table_size = targetsize >> this->bbt_erase_shift;
>   	else
>   		table_size = mtd->size >> this->bbt_erase_shift;
>   	table_size >>= 3;
> diff --git a/drivers/mtd/nand/raw/nand_jedec.c b/drivers/mtd/nand/raw/nand_jedec.c
> index 030f178c7a97..99e2f017c79b 100644
> --- a/drivers/mtd/nand/raw/nand_jedec.c
> +++ b/drivers/mtd/nand/raw/nand_jedec.c
> @@ -101,8 +101,6 @@ int nand_jedec_detect(struct nand_chip *chip)
>   	/* Please reference to the comment for nand_flash_detect_onfi. */
>   	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;
>   
>   	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 a6b9fc9a335b..7b468e7214c7 100644
> --- a/drivers/mtd/nand/raw/nand_onfi.c
> +++ b/drivers/mtd/nand/raw/nand_onfi.c
> @@ -246,8 +246,6 @@ int nand_onfi_detect(struct nand_chip *chip)
>   	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;
>   
>   	if (le16_to_cpu(p->features) & ONFI_FEATURE_16_BIT_BUS)
> diff --git a/drivers/mtd/nand/raw/nandsim.c b/drivers/mtd/nand/raw/nandsim.c
> index 07144c992d54..670abe8d59ca 100644
> --- a/drivers/mtd/nand/raw/nandsim.c
> +++ b/drivers/mtd/nand/raw/nandsim.c
> @@ -2303,6 +2303,7 @@ 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;
>   
>   		memorg = nanddev_get_memorg(&chip->base);
>   
> @@ -2311,12 +2312,13 @@ static int __init ns_init_module(void)
>   			retval = -EINVAL;
>   			goto err_exit;
>   		}
> +
>   		/* 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;
> +		targetsize = nanddev_target_size(&chip->base);
>   		chip->chip_shift = ffs(nsmtd->erasesize) + overridesize - 1;
> -		chip->pagemask = (chip->chipsize >> chip->page_shift) - 1;
> +		chip->pagemask = (targetsize >> chip->page_shift) - 1;
>   	}
>   
>   	if ((retval = setup_wear_reporting(nsmtd)) != 0)
> diff --git a/drivers/mtd/nand/raw/sh_flctl.c b/drivers/mtd/nand/raw/sh_flctl.c
> index cf6b1be1cf9c..3f610040f0c3 100644
> --- a/drivers/mtd/nand/raw/sh_flctl.c
> +++ b/drivers/mtd/nand/raw/sh_flctl.c
> @@ -986,6 +986,7 @@ static void flctl_read_buf(struct nand_chip *chip, uint8_t *buf, int len)
>   
>   static int flctl_chip_attach_chip(struct nand_chip *chip)
>   {
> +	u64 targetsize = nanddev_target_size(&chip->base);
>   	struct mtd_info *mtd = nand_to_mtd(chip);
>   	struct sh_flctl *flctl = mtd_to_flctl(mtd);
>   
> @@ -998,11 +999,11 @@ static int flctl_chip_attach_chip(struct nand_chip *chip)
>   
>   	if (mtd->writesize == 512) {
>   		flctl->page_size = 0;
> -		if (chip->chipsize > (32 << 20)) {
> +		if (targetsize > (32 << 20)) {
>   			/* big than 32MB */
>   			flctl->rw_ADRCNT = ADRCNT_4;
>   			flctl->erase_ADRCNT = ADRCNT_3;
> -		} else if (chip->chipsize > (2 << 16)) {
> +		} else if (targetsize > (2 << 16)) {
>   			/* big than 128KB */
>   			flctl->rw_ADRCNT = ADRCNT_3;
>   			flctl->erase_ADRCNT = ADRCNT_2;
> @@ -1012,11 +1013,11 @@ static int flctl_chip_attach_chip(struct nand_chip *chip)
>   		}
>   	} else {
>   		flctl->page_size = 1;
> -		if (chip->chipsize > (128 << 20)) {
> +		if (targetsize > (128 << 20)) {
>   			/* big than 128MB */
>   			flctl->rw_ADRCNT = ADRCNT2_E;
>   			flctl->erase_ADRCNT = ADRCNT_3;
> -		} else if (chip->chipsize > (8 << 16)) {
> +		} else if (targetsize > (8 << 16)) {
>   			/* big than 512KB */
>   			flctl->rw_ADRCNT = ADRCNT_4;
>   			flctl->erase_ADRCNT = ADRCNT_2;
> diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h
> index 24ecd9a4f952..a127eb773b1a 100644
> --- a/include/linux/mtd/rawnand.h
> +++ b/include/linux/mtd/rawnand.h
> @@ -1015,7 +1015,6 @@ struct nand_legacy {
>    *			      ONFI compliant or deduced from the datasheet if
>    *			      the NAND chip is not ONFI compliant.
>    * @numchips:		[INTERN] number of physical chips
> - * @chipsize:		[INTERN] the size of one chip for multichip arrays
>    * @pagemask:		[INTERN] page number mask = number of (pages / chip) - 1
>    * @data_buf:		[INTERN] buffer for data, size is (page size + oobsize).
>    * @pagecache:		Structure containing page cache related fields
> @@ -1062,7 +1061,6 @@ struct nand_chip {
>   	int bbt_erase_shift;
>   	int chip_shift;
>   	int numchips;
> -	uint64_t chipsize;
>   	int pagemask;
>   	u8 *data_buf;
>   
> 
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 00/15] mtd: rawnand: 5th batch of cleanups
  2019-03-04 20:15 ` Miquel Raynal
@ 2019-04-01 15:28   ` Miquel Raynal
  -1 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-04-01 15:28 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Julien Su, Schrempf Frieder, Masahiro Yamada,
	linux-mtd, Thomas Petazzoni, Mason Yang, linux-arm-kernel

Hello,

Miquel Raynal <miquel.raynal@bootlin.com> wrote on Mon,  4 Mar 2019
21:15:07 +0100:

> Hello,
> 
> This time I am the one who send the cleanups on behalf of Boris, I
> just took his patches because I needed them for my 'generic ECC
> engine' work. Between this cleanup series and the ECC engine series
> there will be an additional one, to prepare the field.
> 
> Patch 1 adds a field to the memorg structure, patch 2 & 3 add helpers
> in the raw NAND core, following patches are general cleanups in the
> raw NAND area that prepares the use of the (generic) NAND core shared
> between raw NANDs and SPI-NANDs and finally a few nand_chip entries
> are dropped.
> 
> Regards,
> Miquèl
> 
> Changs for v2
> =============
> * Fixed the inconsistencies between patch 7 and 13 pointed out by Frieder.
> * Fixed the derivation of memorg->pages_per_eraseblock.
> * Added Frieder Reviewed-by tags.
> 
> 
> Boris Brezillon (15):
>   mtd: nand: Add max_bad_eraseblocks_per_lun info to memorg
>   mtd: nand: Add a helper returning the number of eraseblocks per target
>   mtd: nand: Add a helper to retrieve the number of pages per target
>   mtd: spinand: Implement mtd->_max_bad_blocks
>   mtd: rawnand: Use nand_to_mtd() in nand_{set,get}_flash_node()
>   mtd: rawnand: Prepare things to reuse the generic NAND layer
>   mtd: rawnand: Fill memorg during detection
>   mtd: rawnand: Initialize the nand_device object
>   mtd: rawnand: Provide a helper to get chip->data_buf
>   mtd: rawnand: Move all page cache related fields to a sub-struct
>   mtd: rawnand: Use nanddev_mtd_max_bad_blocks()
>   mtd: rawnand: Get rid of chip->bits_per_cell
>   mtd: rawnand: Get rid of chip->chipsize
>   mtd: rawnand: Get rid of chip->numchips
>   mtd: rawnand: Get rid of chip->ecc_{strength,step}_ds
> 
>  drivers/mtd/nand/core.c                       |  34 +++
>  drivers/mtd/nand/raw/Kconfig                  |   1 +
>  drivers/mtd/nand/raw/atmel/nand-controller.c  |   8 +-
>  .../mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c  |   2 +-
>  drivers/mtd/nand/raw/brcmnand/brcmnand.c      |   7 +-
>  drivers/mtd/nand/raw/denali.c                 |   6 +-
>  drivers/mtd/nand/raw/diskonchip.c             |   6 +-
>  drivers/mtd/nand/raw/fsl_elbc_nand.c          |   4 +-
>  drivers/mtd/nand/raw/fsl_ifc_nand.c           |   4 +-
>  drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c    |  17 +-
>  drivers/mtd/nand/raw/hisi504_nand.c           |   2 +-
>  drivers/mtd/nand/raw/internals.h              |   2 +-
>  drivers/mtd/nand/raw/jz4740_nand.c            |   7 +-
>  drivers/mtd/nand/raw/marvell_nand.c           |  49 ++--
>  drivers/mtd/nand/raw/mtk_nand.c               |   4 +-
>  drivers/mtd/nand/raw/nand_amd.c               |  11 +-
>  drivers/mtd/nand/raw/nand_base.c              | 253 +++++++++++-------
>  drivers/mtd/nand/raw/nand_bbt.c               |  45 ++--
>  drivers/mtd/nand/raw/nand_esmt.c              |  10 +-
>  drivers/mtd/nand/raw/nand_hynix.c             |  90 ++++---
>  drivers/mtd/nand/raw/nand_jedec.c             |  27 +-
>  drivers/mtd/nand/raw/nand_micron.c            |  14 +-
>  drivers/mtd/nand/raw/nand_onfi.c              |  35 ++-
>  drivers/mtd/nand/raw/nand_samsung.c           |  42 +--
>  drivers/mtd/nand/raw/nand_toshiba.c           |  19 +-
>  drivers/mtd/nand/raw/nandsim.c                |  11 +-
>  drivers/mtd/nand/raw/qcom_nandc.c             |   8 +-
>  drivers/mtd/nand/raw/sh_flctl.c               |   9 +-
>  drivers/mtd/nand/raw/sunxi_nand.c             |  15 +-
>  drivers/mtd/nand/raw/tegra_nand.c             |   8 +-
>  drivers/mtd/nand/spi/core.c                   |   1 +
>  drivers/mtd/nand/spi/gigadevice.c             |   6 +-
>  drivers/mtd/nand/spi/macronix.c               |   4 +-
>  drivers/mtd/nand/spi/micron.c                 |   2 +-
>  drivers/mtd/nand/spi/toshiba.c                |   2 +-
>  drivers/mtd/nand/spi/winbond.c                |   4 +-
>  include/linux/mtd/nand.h                      |  32 ++-
>  include/linux/mtd/rawnand.h                   |  97 ++++---
>  38 files changed, 548 insertions(+), 350 deletions(-)
> 

Applied to git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git
on nand/next.


Thanks,
Miquèl

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 00/15] mtd: rawnand: 5th batch of cleanups
@ 2019-04-01 15:28   ` Miquel Raynal
  0 siblings, 0 replies; 66+ messages in thread
From: Miquel Raynal @ 2019-04-01 15:28 UTC (permalink / raw)
  To: Boris Brezillon, Richard Weinberger, David Woodhouse,
	Brian Norris, Marek Vasut, Tudor Ambarus
  Cc: Vignesh R, Julien Su, Schrempf Frieder, Masahiro Yamada,
	linux-mtd, Thomas Petazzoni, Mason Yang, linux-arm-kernel

Hello,

Miquel Raynal <miquel.raynal@bootlin.com> wrote on Mon,  4 Mar 2019
21:15:07 +0100:

> Hello,
> 
> This time I am the one who send the cleanups on behalf of Boris, I
> just took his patches because I needed them for my 'generic ECC
> engine' work. Between this cleanup series and the ECC engine series
> there will be an additional one, to prepare the field.
> 
> Patch 1 adds a field to the memorg structure, patch 2 & 3 add helpers
> in the raw NAND core, following patches are general cleanups in the
> raw NAND area that prepares the use of the (generic) NAND core shared
> between raw NANDs and SPI-NANDs and finally a few nand_chip entries
> are dropped.
> 
> Regards,
> Miquèl
> 
> Changs for v2
> =============
> * Fixed the inconsistencies between patch 7 and 13 pointed out by Frieder.
> * Fixed the derivation of memorg->pages_per_eraseblock.
> * Added Frieder Reviewed-by tags.
> 
> 
> Boris Brezillon (15):
>   mtd: nand: Add max_bad_eraseblocks_per_lun info to memorg
>   mtd: nand: Add a helper returning the number of eraseblocks per target
>   mtd: nand: Add a helper to retrieve the number of pages per target
>   mtd: spinand: Implement mtd->_max_bad_blocks
>   mtd: rawnand: Use nand_to_mtd() in nand_{set,get}_flash_node()
>   mtd: rawnand: Prepare things to reuse the generic NAND layer
>   mtd: rawnand: Fill memorg during detection
>   mtd: rawnand: Initialize the nand_device object
>   mtd: rawnand: Provide a helper to get chip->data_buf
>   mtd: rawnand: Move all page cache related fields to a sub-struct
>   mtd: rawnand: Use nanddev_mtd_max_bad_blocks()
>   mtd: rawnand: Get rid of chip->bits_per_cell
>   mtd: rawnand: Get rid of chip->chipsize
>   mtd: rawnand: Get rid of chip->numchips
>   mtd: rawnand: Get rid of chip->ecc_{strength,step}_ds
> 
>  drivers/mtd/nand/core.c                       |  34 +++
>  drivers/mtd/nand/raw/Kconfig                  |   1 +
>  drivers/mtd/nand/raw/atmel/nand-controller.c  |   8 +-
>  .../mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c  |   2 +-
>  drivers/mtd/nand/raw/brcmnand/brcmnand.c      |   7 +-
>  drivers/mtd/nand/raw/denali.c                 |   6 +-
>  drivers/mtd/nand/raw/diskonchip.c             |   6 +-
>  drivers/mtd/nand/raw/fsl_elbc_nand.c          |   4 +-
>  drivers/mtd/nand/raw/fsl_ifc_nand.c           |   4 +-
>  drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c    |  17 +-
>  drivers/mtd/nand/raw/hisi504_nand.c           |   2 +-
>  drivers/mtd/nand/raw/internals.h              |   2 +-
>  drivers/mtd/nand/raw/jz4740_nand.c            |   7 +-
>  drivers/mtd/nand/raw/marvell_nand.c           |  49 ++--
>  drivers/mtd/nand/raw/mtk_nand.c               |   4 +-
>  drivers/mtd/nand/raw/nand_amd.c               |  11 +-
>  drivers/mtd/nand/raw/nand_base.c              | 253 +++++++++++-------
>  drivers/mtd/nand/raw/nand_bbt.c               |  45 ++--
>  drivers/mtd/nand/raw/nand_esmt.c              |  10 +-
>  drivers/mtd/nand/raw/nand_hynix.c             |  90 ++++---
>  drivers/mtd/nand/raw/nand_jedec.c             |  27 +-
>  drivers/mtd/nand/raw/nand_micron.c            |  14 +-
>  drivers/mtd/nand/raw/nand_onfi.c              |  35 ++-
>  drivers/mtd/nand/raw/nand_samsung.c           |  42 +--
>  drivers/mtd/nand/raw/nand_toshiba.c           |  19 +-
>  drivers/mtd/nand/raw/nandsim.c                |  11 +-
>  drivers/mtd/nand/raw/qcom_nandc.c             |   8 +-
>  drivers/mtd/nand/raw/sh_flctl.c               |   9 +-
>  drivers/mtd/nand/raw/sunxi_nand.c             |  15 +-
>  drivers/mtd/nand/raw/tegra_nand.c             |   8 +-
>  drivers/mtd/nand/spi/core.c                   |   1 +
>  drivers/mtd/nand/spi/gigadevice.c             |   6 +-
>  drivers/mtd/nand/spi/macronix.c               |   4 +-
>  drivers/mtd/nand/spi/micron.c                 |   2 +-
>  drivers/mtd/nand/spi/toshiba.c                |   2 +-
>  drivers/mtd/nand/spi/winbond.c                |   4 +-
>  include/linux/mtd/nand.h                      |  32 ++-
>  include/linux/mtd/rawnand.h                   |  97 ++++---
>  38 files changed, 548 insertions(+), 350 deletions(-)
> 

Applied to git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git
on nand/next.


Thanks,
Miquèl

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 14/15] mtd: rawnand: Get rid of chip->numchips
  2019-03-04 20:15   ` Miquel Raynal
@ 2019-05-21  6:59     ` Sascha Hauer
  -1 siblings, 0 replies; 66+ messages in thread
From: Sascha Hauer @ 2019-05-21  6:59 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Mason Yang, Vignesh R, Tudor Ambarus, Julien Su,
	Richard Weinberger, Boris Brezillon, Schrempf Frieder,
	Marek Vasut, Masahiro Yamada, linux-mtd, Thomas Petazzoni,
	Brian Norris, David Woodhouse, linux-arm-kernel

Hi,

On Mon, Mar 04, 2019 at 09:15:21PM +0100, Miquel Raynal wrote:
> diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h
> index fbf6ca015cd7..a204f9d7e123 100644
> --- a/drivers/mtd/nand/raw/internals.h
> +++ b/drivers/mtd/nand/raw/internals.h
> @@ -110,7 +110,7 @@ static inline int nand_exec_op(struct nand_chip *chip,
>  	if (!nand_has_exec_op(chip))
>  		return -ENOTSUPP;
>  
> -	if (WARN_ON(op->cs >= chip->numchips))
> +	if (WARN_ON(op->cs >= nanddev_ntargets(&chip->base)))
>  		return -EINVAL;

This warning triggers when I apply my gpmi nand exec_op series.

The gpmi driver calls:

	ret = nand_scan(chip, GPMI_IS_MX6(this) ? 2 : 1);

This ends up in nand_scan_ident() with maxchips = 2. Here nand_detect()
is called which sets memorg->ntargets = 1; Later in nand_scan_ident() we
have:

	for (i = 1; i < maxchips; i++) {
		u8 id[2];

		/* See comment in nand_get_flash_type for reset */
		ret = nand_reset(chip, i);
		if (ret)
			break;
		....

this nand_reset() calls nand_exec_op() with op->cs = 1, nanddev_ntargets() = 1
and boom.

I can't see how this can work with anything else but maxchips = 1. Do you
have an idea how this is supposed to work?

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 14/15] mtd: rawnand: Get rid of chip->numchips
@ 2019-05-21  6:59     ` Sascha Hauer
  0 siblings, 0 replies; 66+ messages in thread
From: Sascha Hauer @ 2019-05-21  6:59 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Mason Yang, Vignesh R, Tudor Ambarus, Julien Su,
	Richard Weinberger, Boris Brezillon, Schrempf Frieder,
	Marek Vasut, Masahiro Yamada, linux-mtd, Thomas Petazzoni,
	Brian Norris, David Woodhouse, linux-arm-kernel

Hi,

On Mon, Mar 04, 2019 at 09:15:21PM +0100, Miquel Raynal wrote:
> diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h
> index fbf6ca015cd7..a204f9d7e123 100644
> --- a/drivers/mtd/nand/raw/internals.h
> +++ b/drivers/mtd/nand/raw/internals.h
> @@ -110,7 +110,7 @@ static inline int nand_exec_op(struct nand_chip *chip,
>  	if (!nand_has_exec_op(chip))
>  		return -ENOTSUPP;
>  
> -	if (WARN_ON(op->cs >= chip->numchips))
> +	if (WARN_ON(op->cs >= nanddev_ntargets(&chip->base)))
>  		return -EINVAL;

This warning triggers when I apply my gpmi nand exec_op series.

The gpmi driver calls:

	ret = nand_scan(chip, GPMI_IS_MX6(this) ? 2 : 1);

This ends up in nand_scan_ident() with maxchips = 2. Here nand_detect()
is called which sets memorg->ntargets = 1; Later in nand_scan_ident() we
have:

	for (i = 1; i < maxchips; i++) {
		u8 id[2];

		/* See comment in nand_get_flash_type for reset */
		ret = nand_reset(chip, i);
		if (ret)
			break;
		....

this nand_reset() calls nand_exec_op() with op->cs = 1, nanddev_ntargets() = 1
and boom.

I can't see how this can work with anything else but maxchips = 1. Do you
have an idea how this is supposed to work?

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 14/15] mtd: rawnand: Get rid of chip->numchips
  2019-05-21  6:59     ` Sascha Hauer
@ 2019-05-21  7:33       ` Boris Brezillon
  -1 siblings, 0 replies; 66+ messages in thread
From: Boris Brezillon @ 2019-05-21  7:33 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: Mason Yang, Vignesh R, Boris Brezillon, Julien Su,
	Richard Weinberger, Tudor Ambarus, Schrempf Frieder, Marek Vasut,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Brian Norris, David Woodhouse, linux-arm-kernel

On Tue, 21 May 2019 08:59:48 +0200
Sascha Hauer <s.hauer@pengutronix.de> wrote:

> Hi,
> 
> On Mon, Mar 04, 2019 at 09:15:21PM +0100, Miquel Raynal wrote:
> > diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h
> > index fbf6ca015cd7..a204f9d7e123 100644
> > --- a/drivers/mtd/nand/raw/internals.h
> > +++ b/drivers/mtd/nand/raw/internals.h
> > @@ -110,7 +110,7 @@ static inline int nand_exec_op(struct nand_chip *chip,
> >  	if (!nand_has_exec_op(chip))
> >  		return -ENOTSUPP;
> >  
> > -	if (WARN_ON(op->cs >= chip->numchips))
> > +	if (WARN_ON(op->cs >= nanddev_ntargets(&chip->base)))
> >  		return -EINVAL;  
> 
> This warning triggers when I apply my gpmi nand exec_op series.
> 
> The gpmi driver calls:
> 
> 	ret = nand_scan(chip, GPMI_IS_MX6(this) ? 2 : 1);
> 
> This ends up in nand_scan_ident() with maxchips = 2. Here nand_detect()
> is called which sets memorg->ntargets = 1; Later in nand_scan_ident() we
> have:
> 
> 	for (i = 1; i < maxchips; i++) {

This loop should be fixed to test against nanddev_ntargets() instead of
maxchips.

> 		u8 id[2];
> 
> 		/* See comment in nand_get_flash_type for reset */
> 		ret = nand_reset(chip, i);
> 		if (ret)
> 			break;
> 		....
> 
> this nand_reset() calls nand_exec_op() with op->cs = 1, nanddev_ntargets() = 1
> and boom.
> 
> I can't see how this can work with anything else but maxchips = 1. Do you
> have an idea how this is supposed to work?
> 
> Sascha
> 
> 


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 14/15] mtd: rawnand: Get rid of chip->numchips
@ 2019-05-21  7:33       ` Boris Brezillon
  0 siblings, 0 replies; 66+ messages in thread
From: Boris Brezillon @ 2019-05-21  7:33 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: Mason Yang, Vignesh R, Boris Brezillon, Julien Su,
	Richard Weinberger, Tudor Ambarus, Schrempf Frieder, Marek Vasut,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Brian Norris, David Woodhouse, linux-arm-kernel

On Tue, 21 May 2019 08:59:48 +0200
Sascha Hauer <s.hauer@pengutronix.de> wrote:

> Hi,
> 
> On Mon, Mar 04, 2019 at 09:15:21PM +0100, Miquel Raynal wrote:
> > diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h
> > index fbf6ca015cd7..a204f9d7e123 100644
> > --- a/drivers/mtd/nand/raw/internals.h
> > +++ b/drivers/mtd/nand/raw/internals.h
> > @@ -110,7 +110,7 @@ static inline int nand_exec_op(struct nand_chip *chip,
> >  	if (!nand_has_exec_op(chip))
> >  		return -ENOTSUPP;
> >  
> > -	if (WARN_ON(op->cs >= chip->numchips))
> > +	if (WARN_ON(op->cs >= nanddev_ntargets(&chip->base)))
> >  		return -EINVAL;  
> 
> This warning triggers when I apply my gpmi nand exec_op series.
> 
> The gpmi driver calls:
> 
> 	ret = nand_scan(chip, GPMI_IS_MX6(this) ? 2 : 1);
> 
> This ends up in nand_scan_ident() with maxchips = 2. Here nand_detect()
> is called which sets memorg->ntargets = 1; Later in nand_scan_ident() we
> have:
> 
> 	for (i = 1; i < maxchips; i++) {

This loop should be fixed to test against nanddev_ntargets() instead of
maxchips.

> 		u8 id[2];
> 
> 		/* See comment in nand_get_flash_type for reset */
> 		ret = nand_reset(chip, i);
> 		if (ret)
> 			break;
> 		....
> 
> this nand_reset() calls nand_exec_op() with op->cs = 1, nanddev_ntargets() = 1
> and boom.
> 
> I can't see how this can work with anything else but maxchips = 1. Do you
> have an idea how this is supposed to work?
> 
> Sascha
> 
> 


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 14/15] mtd: rawnand: Get rid of chip->numchips
  2019-05-21  7:33       ` Boris Brezillon
@ 2019-05-21  7:43         ` Boris Brezillon
  -1 siblings, 0 replies; 66+ messages in thread
From: Boris Brezillon @ 2019-05-21  7:43 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: Mason Yang, Vignesh R, Boris Brezillon, Julien Su,
	Richard Weinberger, Tudor Ambarus, Schrempf Frieder, Marek Vasut,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Brian Norris, David Woodhouse, linux-arm-kernel

On Tue, 21 May 2019 09:33:02 +0200
Boris Brezillon <boris.brezillon@collabora.com> wrote:

> On Tue, 21 May 2019 08:59:48 +0200
> Sascha Hauer <s.hauer@pengutronix.de> wrote:
> 
> > Hi,
> > 
> > On Mon, Mar 04, 2019 at 09:15:21PM +0100, Miquel Raynal wrote:  
> > > diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h
> > > index fbf6ca015cd7..a204f9d7e123 100644
> > > --- a/drivers/mtd/nand/raw/internals.h
> > > +++ b/drivers/mtd/nand/raw/internals.h
> > > @@ -110,7 +110,7 @@ static inline int nand_exec_op(struct nand_chip *chip,
> > >  	if (!nand_has_exec_op(chip))
> > >  		return -ENOTSUPP;
> > >  
> > > -	if (WARN_ON(op->cs >= chip->numchips))
> > > +	if (WARN_ON(op->cs >= nanddev_ntargets(&chip->base)))
> > >  		return -EINVAL;    
> > 
> > This warning triggers when I apply my gpmi nand exec_op series.
> > 
> > The gpmi driver calls:
> > 
> > 	ret = nand_scan(chip, GPMI_IS_MX6(this) ? 2 : 1);
> > 
> > This ends up in nand_scan_ident() with maxchips = 2. Here nand_detect()
> > is called which sets memorg->ntargets = 1; Later in nand_scan_ident() we
> > have:
> > 
> > 	for (i = 1; i < maxchips; i++) {  
> 
> This loop should be fixed to test against nanddev_ntargets() instead of
> maxchips.
> 
> > 		u8 id[2];
> > 
> > 		/* See comment in nand_get_flash_type for reset */
> > 		ret = nand_reset(chip, i);
> > 		if (ret)
> > 			break;
> > 		....
> > 
> > this nand_reset() calls nand_exec_op() with op->cs = 1, nanddev_ntargets() = 1
> > and boom.
> > 
> > I can't see how this can work with anything else but maxchips = 1. Do you
> > have an idea how this is supposed to work?

Forgot to reply to that one. ->ntargets is set to the number of
dies/tartgets actually detected here [1], so it's not always 1 (can
also be extracted from the ONFI table IIRC).
Note that I've never been a big fan of this maxchip param, and I've
asked that new drivers pass the actual number of CS connected to the
NAND chip being initialized (which should be part of the HW desc, be it
DT based or board-file based). So, ideally this argument should be named
num_dies or num_targets and the function should return an error when
one of the die returns a different ID. Unfortunately, that's not
something we can do, because a lot of drivers rely on the old
semantic...

[1]https://elixir.bootlin.com/linux/v5.2-rc1/source/drivers/mtd/nand/raw/nand_base.c#L5073

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 14/15] mtd: rawnand: Get rid of chip->numchips
@ 2019-05-21  7:43         ` Boris Brezillon
  0 siblings, 0 replies; 66+ messages in thread
From: Boris Brezillon @ 2019-05-21  7:43 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: Mason Yang, Vignesh R, Boris Brezillon, Julien Su,
	Richard Weinberger, Tudor Ambarus, Schrempf Frieder, Marek Vasut,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Brian Norris, David Woodhouse, linux-arm-kernel

On Tue, 21 May 2019 09:33:02 +0200
Boris Brezillon <boris.brezillon@collabora.com> wrote:

> On Tue, 21 May 2019 08:59:48 +0200
> Sascha Hauer <s.hauer@pengutronix.de> wrote:
> 
> > Hi,
> > 
> > On Mon, Mar 04, 2019 at 09:15:21PM +0100, Miquel Raynal wrote:  
> > > diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h
> > > index fbf6ca015cd7..a204f9d7e123 100644
> > > --- a/drivers/mtd/nand/raw/internals.h
> > > +++ b/drivers/mtd/nand/raw/internals.h
> > > @@ -110,7 +110,7 @@ static inline int nand_exec_op(struct nand_chip *chip,
> > >  	if (!nand_has_exec_op(chip))
> > >  		return -ENOTSUPP;
> > >  
> > > -	if (WARN_ON(op->cs >= chip->numchips))
> > > +	if (WARN_ON(op->cs >= nanddev_ntargets(&chip->base)))
> > >  		return -EINVAL;    
> > 
> > This warning triggers when I apply my gpmi nand exec_op series.
> > 
> > The gpmi driver calls:
> > 
> > 	ret = nand_scan(chip, GPMI_IS_MX6(this) ? 2 : 1);
> > 
> > This ends up in nand_scan_ident() with maxchips = 2. Here nand_detect()
> > is called which sets memorg->ntargets = 1; Later in nand_scan_ident() we
> > have:
> > 
> > 	for (i = 1; i < maxchips; i++) {  
> 
> This loop should be fixed to test against nanddev_ntargets() instead of
> maxchips.
> 
> > 		u8 id[2];
> > 
> > 		/* See comment in nand_get_flash_type for reset */
> > 		ret = nand_reset(chip, i);
> > 		if (ret)
> > 			break;
> > 		....
> > 
> > this nand_reset() calls nand_exec_op() with op->cs = 1, nanddev_ntargets() = 1
> > and boom.
> > 
> > I can't see how this can work with anything else but maxchips = 1. Do you
> > have an idea how this is supposed to work?

Forgot to reply to that one. ->ntargets is set to the number of
dies/tartgets actually detected here [1], so it's not always 1 (can
also be extracted from the ONFI table IIRC).
Note that I've never been a big fan of this maxchip param, and I've
asked that new drivers pass the actual number of CS connected to the
NAND chip being initialized (which should be part of the HW desc, be it
DT based or board-file based). So, ideally this argument should be named
num_dies or num_targets and the function should return an error when
one of the die returns a different ID. Unfortunately, that's not
something we can do, because a lot of drivers rely on the old
semantic...

[1]https://elixir.bootlin.com/linux/v5.2-rc1/source/drivers/mtd/nand/raw/nand_base.c#L5073

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 14/15] mtd: rawnand: Get rid of chip->numchips
  2019-05-21  7:33       ` Boris Brezillon
@ 2019-05-21  7:51         ` Boris Brezillon
  -1 siblings, 0 replies; 66+ messages in thread
From: Boris Brezillon @ 2019-05-21  7:51 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: Mason Yang, Vignesh R, Boris Brezillon, Julien Su,
	Richard Weinberger, Tudor Ambarus, Schrempf Frieder, Marek Vasut,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Brian Norris, David Woodhouse, linux-arm-kernel

On Tue, 21 May 2019 09:33:02 +0200
Boris Brezillon <boris.brezillon@collabora.com> wrote:

> On Tue, 21 May 2019 08:59:48 +0200
> Sascha Hauer <s.hauer@pengutronix.de> wrote:
> 
> > Hi,
> > 
> > On Mon, Mar 04, 2019 at 09:15:21PM +0100, Miquel Raynal wrote:  
> > > diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h
> > > index fbf6ca015cd7..a204f9d7e123 100644
> > > --- a/drivers/mtd/nand/raw/internals.h
> > > +++ b/drivers/mtd/nand/raw/internals.h
> > > @@ -110,7 +110,7 @@ static inline int nand_exec_op(struct nand_chip *chip,
> > >  	if (!nand_has_exec_op(chip))
> > >  		return -ENOTSUPP;
> > >  
> > > -	if (WARN_ON(op->cs >= chip->numchips))
> > > +	if (WARN_ON(op->cs >= nanddev_ntargets(&chip->base)))
> > >  		return -EINVAL;    
> > 
> > This warning triggers when I apply my gpmi nand exec_op series.
> > 
> > The gpmi driver calls:
> > 
> > 	ret = nand_scan(chip, GPMI_IS_MX6(this) ? 2 : 1);
> > 
> > This ends up in nand_scan_ident() with maxchips = 2. Here nand_detect()
> > is called which sets memorg->ntargets = 1; Later in nand_scan_ident() we
> > have:
> > 
> > 	for (i = 1; i < maxchips; i++) {  
> 
> This loop should be fixed to test against nanddev_ntargets() instead of
> maxchips.

Nevermind, I see what you mean. I guess we should set ->ntargets to
maxchips before entering this loop.

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 14/15] mtd: rawnand: Get rid of chip->numchips
@ 2019-05-21  7:51         ` Boris Brezillon
  0 siblings, 0 replies; 66+ messages in thread
From: Boris Brezillon @ 2019-05-21  7:51 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: Mason Yang, Vignesh R, Boris Brezillon, Julien Su,
	Richard Weinberger, Tudor Ambarus, Schrempf Frieder, Marek Vasut,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Brian Norris, David Woodhouse, linux-arm-kernel

On Tue, 21 May 2019 09:33:02 +0200
Boris Brezillon <boris.brezillon@collabora.com> wrote:

> On Tue, 21 May 2019 08:59:48 +0200
> Sascha Hauer <s.hauer@pengutronix.de> wrote:
> 
> > Hi,
> > 
> > On Mon, Mar 04, 2019 at 09:15:21PM +0100, Miquel Raynal wrote:  
> > > diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h
> > > index fbf6ca015cd7..a204f9d7e123 100644
> > > --- a/drivers/mtd/nand/raw/internals.h
> > > +++ b/drivers/mtd/nand/raw/internals.h
> > > @@ -110,7 +110,7 @@ static inline int nand_exec_op(struct nand_chip *chip,
> > >  	if (!nand_has_exec_op(chip))
> > >  		return -ENOTSUPP;
> > >  
> > > -	if (WARN_ON(op->cs >= chip->numchips))
> > > +	if (WARN_ON(op->cs >= nanddev_ntargets(&chip->base)))
> > >  		return -EINVAL;    
> > 
> > This warning triggers when I apply my gpmi nand exec_op series.
> > 
> > The gpmi driver calls:
> > 
> > 	ret = nand_scan(chip, GPMI_IS_MX6(this) ? 2 : 1);
> > 
> > This ends up in nand_scan_ident() with maxchips = 2. Here nand_detect()
> > is called which sets memorg->ntargets = 1; Later in nand_scan_ident() we
> > have:
> > 
> > 	for (i = 1; i < maxchips; i++) {  
> 
> This loop should be fixed to test against nanddev_ntargets() instead of
> maxchips.

Nevermind, I see what you mean. I guess we should set ->ntargets to
maxchips before entering this loop.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 14/15] mtd: rawnand: Get rid of chip->numchips
  2019-05-21  7:33       ` Boris Brezillon
@ 2019-05-21  7:56         ` Sascha Hauer
  -1 siblings, 0 replies; 66+ messages in thread
From: Sascha Hauer @ 2019-05-21  7:56 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Mason Yang, Vignesh R, Boris Brezillon, Julien Su,
	Richard Weinberger, Tudor Ambarus, Schrempf Frieder, Marek Vasut,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Brian Norris, David Woodhouse, linux-arm-kernel

On Tue, May 21, 2019 at 09:33:02AM +0200, Boris Brezillon wrote:
> On Tue, 21 May 2019 08:59:48 +0200
> Sascha Hauer <s.hauer@pengutronix.de> wrote:
> 
> > Hi,
> > 
> > On Mon, Mar 04, 2019 at 09:15:21PM +0100, Miquel Raynal wrote:
> > > diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h
> > > index fbf6ca015cd7..a204f9d7e123 100644
> > > --- a/drivers/mtd/nand/raw/internals.h
> > > +++ b/drivers/mtd/nand/raw/internals.h
> > > @@ -110,7 +110,7 @@ static inline int nand_exec_op(struct nand_chip *chip,
> > >  	if (!nand_has_exec_op(chip))
> > >  		return -ENOTSUPP;
> > >  
> > > -	if (WARN_ON(op->cs >= chip->numchips))
> > > +	if (WARN_ON(op->cs >= nanddev_ntargets(&chip->base)))
> > >  		return -EINVAL;  
> > 
> > This warning triggers when I apply my gpmi nand exec_op series.
> > 
> > The gpmi driver calls:
> > 
> > 	ret = nand_scan(chip, GPMI_IS_MX6(this) ? 2 : 1);
> > 
> > This ends up in nand_scan_ident() with maxchips = 2. Here nand_detect()
> > is called which sets memorg->ntargets = 1; Later in nand_scan_ident() we
> > have:
> > 
> > 	for (i = 1; i < maxchips; i++) {
> 
> This loop should be fixed to test against nanddev_ntargets() instead of
> maxchips.

This makes the maxchips argument to nand_scan() unused. A lot of drivers
are calling nand_scan() with maxchips > 1. How are these working then?

Or should there be a memorg->ntargets = maxchips before the loop?

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 14/15] mtd: rawnand: Get rid of chip->numchips
@ 2019-05-21  7:56         ` Sascha Hauer
  0 siblings, 0 replies; 66+ messages in thread
From: Sascha Hauer @ 2019-05-21  7:56 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Mason Yang, Vignesh R, Boris Brezillon, Julien Su,
	Richard Weinberger, Tudor Ambarus, Schrempf Frieder, Marek Vasut,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Brian Norris, David Woodhouse, linux-arm-kernel

On Tue, May 21, 2019 at 09:33:02AM +0200, Boris Brezillon wrote:
> On Tue, 21 May 2019 08:59:48 +0200
> Sascha Hauer <s.hauer@pengutronix.de> wrote:
> 
> > Hi,
> > 
> > On Mon, Mar 04, 2019 at 09:15:21PM +0100, Miquel Raynal wrote:
> > > diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h
> > > index fbf6ca015cd7..a204f9d7e123 100644
> > > --- a/drivers/mtd/nand/raw/internals.h
> > > +++ b/drivers/mtd/nand/raw/internals.h
> > > @@ -110,7 +110,7 @@ static inline int nand_exec_op(struct nand_chip *chip,
> > >  	if (!nand_has_exec_op(chip))
> > >  		return -ENOTSUPP;
> > >  
> > > -	if (WARN_ON(op->cs >= chip->numchips))
> > > +	if (WARN_ON(op->cs >= nanddev_ntargets(&chip->base)))
> > >  		return -EINVAL;  
> > 
> > This warning triggers when I apply my gpmi nand exec_op series.
> > 
> > The gpmi driver calls:
> > 
> > 	ret = nand_scan(chip, GPMI_IS_MX6(this) ? 2 : 1);
> > 
> > This ends up in nand_scan_ident() with maxchips = 2. Here nand_detect()
> > is called which sets memorg->ntargets = 1; Later in nand_scan_ident() we
> > have:
> > 
> > 	for (i = 1; i < maxchips; i++) {
> 
> This loop should be fixed to test against nanddev_ntargets() instead of
> maxchips.

This makes the maxchips argument to nand_scan() unused. A lot of drivers
are calling nand_scan() with maxchips > 1. How are these working then?

Or should there be a memorg->ntargets = maxchips before the loop?

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 14/15] mtd: rawnand: Get rid of chip->numchips
  2019-05-21  7:51         ` Boris Brezillon
@ 2019-05-21  7:58           ` Sascha Hauer
  -1 siblings, 0 replies; 66+ messages in thread
From: Sascha Hauer @ 2019-05-21  7:58 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Mason Yang, Vignesh R, Boris Brezillon, Julien Su,
	Richard Weinberger, Tudor Ambarus, Schrempf Frieder, Marek Vasut,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Brian Norris, David Woodhouse, linux-arm-kernel

On Tue, May 21, 2019 at 09:51:30AM +0200, Boris Brezillon wrote:
> On Tue, 21 May 2019 09:33:02 +0200
> Boris Brezillon <boris.brezillon@collabora.com> wrote:
> 
> > On Tue, 21 May 2019 08:59:48 +0200
> > Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > 
> > > Hi,
> > > 
> > > On Mon, Mar 04, 2019 at 09:15:21PM +0100, Miquel Raynal wrote:  
> > > > diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h
> > > > index fbf6ca015cd7..a204f9d7e123 100644
> > > > --- a/drivers/mtd/nand/raw/internals.h
> > > > +++ b/drivers/mtd/nand/raw/internals.h
> > > > @@ -110,7 +110,7 @@ static inline int nand_exec_op(struct nand_chip *chip,
> > > >  	if (!nand_has_exec_op(chip))
> > > >  		return -ENOTSUPP;
> > > >  
> > > > -	if (WARN_ON(op->cs >= chip->numchips))
> > > > +	if (WARN_ON(op->cs >= nanddev_ntargets(&chip->base)))
> > > >  		return -EINVAL;    
> > > 
> > > This warning triggers when I apply my gpmi nand exec_op series.
> > > 
> > > The gpmi driver calls:
> > > 
> > > 	ret = nand_scan(chip, GPMI_IS_MX6(this) ? 2 : 1);
> > > 
> > > This ends up in nand_scan_ident() with maxchips = 2. Here nand_detect()
> > > is called which sets memorg->ntargets = 1; Later in nand_scan_ident() we
> > > have:
> > > 
> > > 	for (i = 1; i < maxchips; i++) {  
> > 
> > This loop should be fixed to test against nanddev_ntargets() instead of
> > maxchips.
> 
> Nevermind, I see what you mean. I guess we should set ->ntargets to
> maxchips before entering this loop.

Okay, you got the same conclusion in the meantime ;)

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 14/15] mtd: rawnand: Get rid of chip->numchips
@ 2019-05-21  7:58           ` Sascha Hauer
  0 siblings, 0 replies; 66+ messages in thread
From: Sascha Hauer @ 2019-05-21  7:58 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Mason Yang, Vignesh R, Boris Brezillon, Julien Su,
	Richard Weinberger, Tudor Ambarus, Schrempf Frieder, Marek Vasut,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Brian Norris, David Woodhouse, linux-arm-kernel

On Tue, May 21, 2019 at 09:51:30AM +0200, Boris Brezillon wrote:
> On Tue, 21 May 2019 09:33:02 +0200
> Boris Brezillon <boris.brezillon@collabora.com> wrote:
> 
> > On Tue, 21 May 2019 08:59:48 +0200
> > Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > 
> > > Hi,
> > > 
> > > On Mon, Mar 04, 2019 at 09:15:21PM +0100, Miquel Raynal wrote:  
> > > > diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h
> > > > index fbf6ca015cd7..a204f9d7e123 100644
> > > > --- a/drivers/mtd/nand/raw/internals.h
> > > > +++ b/drivers/mtd/nand/raw/internals.h
> > > > @@ -110,7 +110,7 @@ static inline int nand_exec_op(struct nand_chip *chip,
> > > >  	if (!nand_has_exec_op(chip))
> > > >  		return -ENOTSUPP;
> > > >  
> > > > -	if (WARN_ON(op->cs >= chip->numchips))
> > > > +	if (WARN_ON(op->cs >= nanddev_ntargets(&chip->base)))
> > > >  		return -EINVAL;    
> > > 
> > > This warning triggers when I apply my gpmi nand exec_op series.
> > > 
> > > The gpmi driver calls:
> > > 
> > > 	ret = nand_scan(chip, GPMI_IS_MX6(this) ? 2 : 1);
> > > 
> > > This ends up in nand_scan_ident() with maxchips = 2. Here nand_detect()
> > > is called which sets memorg->ntargets = 1; Later in nand_scan_ident() we
> > > have:
> > > 
> > > 	for (i = 1; i < maxchips; i++) {  
> > 
> > This loop should be fixed to test against nanddev_ntargets() instead of
> > maxchips.
> 
> Nevermind, I see what you mean. I guess we should set ->ntargets to
> maxchips before entering this loop.

Okay, you got the same conclusion in the meantime ;)

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 14/15] mtd: rawnand: Get rid of chip->numchips
  2019-05-21  7:58           ` Sascha Hauer
@ 2019-05-21  8:01             ` Boris Brezillon
  -1 siblings, 0 replies; 66+ messages in thread
From: Boris Brezillon @ 2019-05-21  8:01 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: Mason Yang, Vignesh R, Boris Brezillon, Julien Su,
	Richard Weinberger, Tudor Ambarus, Schrempf Frieder, Marek Vasut,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Brian Norris, David Woodhouse, linux-arm-kernel

On Tue, 21 May 2019 09:58:25 +0200
Sascha Hauer <s.hauer@pengutronix.de> wrote:

> On Tue, May 21, 2019 at 09:51:30AM +0200, Boris Brezillon wrote:
> > On Tue, 21 May 2019 09:33:02 +0200
> > Boris Brezillon <boris.brezillon@collabora.com> wrote:
> >   
> > > On Tue, 21 May 2019 08:59:48 +0200
> > > Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > >   
> > > > Hi,
> > > > 
> > > > On Mon, Mar 04, 2019 at 09:15:21PM +0100, Miquel Raynal wrote:    
> > > > > diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h
> > > > > index fbf6ca015cd7..a204f9d7e123 100644
> > > > > --- a/drivers/mtd/nand/raw/internals.h
> > > > > +++ b/drivers/mtd/nand/raw/internals.h
> > > > > @@ -110,7 +110,7 @@ static inline int nand_exec_op(struct nand_chip *chip,
> > > > >  	if (!nand_has_exec_op(chip))
> > > > >  		return -ENOTSUPP;
> > > > >  
> > > > > -	if (WARN_ON(op->cs >= chip->numchips))
> > > > > +	if (WARN_ON(op->cs >= nanddev_ntargets(&chip->base)))
> > > > >  		return -EINVAL;      
> > > > 
> > > > This warning triggers when I apply my gpmi nand exec_op series.
> > > > 
> > > > The gpmi driver calls:
> > > > 
> > > > 	ret = nand_scan(chip, GPMI_IS_MX6(this) ? 2 : 1);
> > > > 
> > > > This ends up in nand_scan_ident() with maxchips = 2. Here nand_detect()
> > > > is called which sets memorg->ntargets = 1; Later in nand_scan_ident() we
> > > > have:
> > > > 
> > > > 	for (i = 1; i < maxchips; i++) {    
> > > 
> > > This loop should be fixed to test against nanddev_ntargets() instead of
> > > maxchips.  
> > 
> > Nevermind, I see what you mean. I guess we should set ->ntargets to
> > maxchips before entering this loop.  
> 
> Okay, you got the same conclusion in the meantime ;)

Actually, you can just replace

	memorg->ntargets = 1;

by

	memorg->ntargers = maxchips;

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 14/15] mtd: rawnand: Get rid of chip->numchips
@ 2019-05-21  8:01             ` Boris Brezillon
  0 siblings, 0 replies; 66+ messages in thread
From: Boris Brezillon @ 2019-05-21  8:01 UTC (permalink / raw)
  To: Sascha Hauer
  Cc: Mason Yang, Vignesh R, Boris Brezillon, Julien Su,
	Richard Weinberger, Tudor Ambarus, Schrempf Frieder, Marek Vasut,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Brian Norris, David Woodhouse, linux-arm-kernel

On Tue, 21 May 2019 09:58:25 +0200
Sascha Hauer <s.hauer@pengutronix.de> wrote:

> On Tue, May 21, 2019 at 09:51:30AM +0200, Boris Brezillon wrote:
> > On Tue, 21 May 2019 09:33:02 +0200
> > Boris Brezillon <boris.brezillon@collabora.com> wrote:
> >   
> > > On Tue, 21 May 2019 08:59:48 +0200
> > > Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > >   
> > > > Hi,
> > > > 
> > > > On Mon, Mar 04, 2019 at 09:15:21PM +0100, Miquel Raynal wrote:    
> > > > > diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h
> > > > > index fbf6ca015cd7..a204f9d7e123 100644
> > > > > --- a/drivers/mtd/nand/raw/internals.h
> > > > > +++ b/drivers/mtd/nand/raw/internals.h
> > > > > @@ -110,7 +110,7 @@ static inline int nand_exec_op(struct nand_chip *chip,
> > > > >  	if (!nand_has_exec_op(chip))
> > > > >  		return -ENOTSUPP;
> > > > >  
> > > > > -	if (WARN_ON(op->cs >= chip->numchips))
> > > > > +	if (WARN_ON(op->cs >= nanddev_ntargets(&chip->base)))
> > > > >  		return -EINVAL;      
> > > > 
> > > > This warning triggers when I apply my gpmi nand exec_op series.
> > > > 
> > > > The gpmi driver calls:
> > > > 
> > > > 	ret = nand_scan(chip, GPMI_IS_MX6(this) ? 2 : 1);
> > > > 
> > > > This ends up in nand_scan_ident() with maxchips = 2. Here nand_detect()
> > > > is called which sets memorg->ntargets = 1; Later in nand_scan_ident() we
> > > > have:
> > > > 
> > > > 	for (i = 1; i < maxchips; i++) {    
> > > 
> > > This loop should be fixed to test against nanddev_ntargets() instead of
> > > maxchips.  
> > 
> > Nevermind, I see what you mean. I guess we should set ->ntargets to
> > maxchips before entering this loop.  
> 
> Okay, you got the same conclusion in the meantime ;)

Actually, you can just replace

	memorg->ntargets = 1;

by

	memorg->ntargers = maxchips;

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 01/15] mtd: nand: Add max_bad_eraseblocks_per_lun info to memorg
  2019-03-04 20:15   ` Miquel Raynal
@ 2019-06-04  8:01     ` Emil Lenngren
  -1 siblings, 0 replies; 66+ messages in thread
From: Emil Lenngren @ 2019-06-04  8:01 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Mason Yang, Vignesh R, Tudor Ambarus, Julien Su,
	Richard Weinberger, Boris Brezillon, Schrempf Frieder,
	Marek Vasut, Masahiro Yamada, linux-mtd, Thomas Petazzoni,
	Brian Norris, David Woodhouse, linux-arm-kernel

Hi Miquel,

>  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,
> @@ -103,7 +103,7 @@ static const struct spinand_info macronix_spinand_table[] = {
>                      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),

Maybe a bit late to the discussion, but shouldn't 20 and 40 be swapped
here, i.e. isn't it the larger flash that has more max bad blocks than
the smaller one?

/Emil

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 01/15] mtd: nand: Add max_bad_eraseblocks_per_lun info to memorg
@ 2019-06-04  8:01     ` Emil Lenngren
  0 siblings, 0 replies; 66+ messages in thread
From: Emil Lenngren @ 2019-06-04  8:01 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Mason Yang, Vignesh R, Tudor Ambarus, Julien Su,
	Richard Weinberger, Boris Brezillon, Schrempf Frieder,
	Marek Vasut, Masahiro Yamada, linux-mtd, Thomas Petazzoni,
	Brian Norris, David Woodhouse, linux-arm-kernel

Hi Miquel,

>  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,
> @@ -103,7 +103,7 @@ static const struct spinand_info macronix_spinand_table[] = {
>                      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),

Maybe a bit late to the discussion, but shouldn't 20 and 40 be swapped
here, i.e. isn't it the larger flash that has more max bad blocks than
the smaller one?

/Emil

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 01/15] mtd: nand: Add max_bad_eraseblocks_per_lun info to memorg
  2019-06-04  8:01     ` Emil Lenngren
@ 2019-06-06  8:27       ` Schrempf Frieder
  -1 siblings, 0 replies; 66+ messages in thread
From: Schrempf Frieder @ 2019-06-06  8:27 UTC (permalink / raw)
  To: Emil Lenngren, Miquel Raynal
  Cc: Mason Yang, Vignesh R, Tudor Ambarus, Julien Su,
	Richard Weinberger, Boris Brezillon, Marek Vasut,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Brian Norris,
	David Woodhouse, linux-arm-kernel

Hi Emil,

On 04.06.19 10:01, Emil Lenngren wrote:
> Hi Miquel,
> 
>>   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,
>> @@ -103,7 +103,7 @@ static const struct spinand_info macronix_spinand_table[] = {
>>                       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),
> 
> Maybe a bit late to the discussion, but shouldn't 20 and 40 be swapped
> here, i.e. isn't it the larger flash that has more max bad blocks than
> the smaller one?

I think Miquel is out of office for some days, so I just checked and you 
are right, the maximum number of bad blocks should be swapped.

Actually there is also a wrong value in the GigaDevice driver: For the 
GD5F4GQ4xA it should be 80 instead of 40.

Would you mind sending a patch with a "Fixes:" tag, that fixes both, the 
Macronix and the GigaDevice driver? Or should I send one?

Thanks,
Frieder
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 01/15] mtd: nand: Add max_bad_eraseblocks_per_lun info to memorg
@ 2019-06-06  8:27       ` Schrempf Frieder
  0 siblings, 0 replies; 66+ messages in thread
From: Schrempf Frieder @ 2019-06-06  8:27 UTC (permalink / raw)
  To: Emil Lenngren, Miquel Raynal
  Cc: Mason Yang, Vignesh R, Tudor Ambarus, Julien Su,
	Richard Weinberger, Boris Brezillon, Marek Vasut,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Brian Norris,
	David Woodhouse, linux-arm-kernel

Hi Emil,

On 04.06.19 10:01, Emil Lenngren wrote:
> Hi Miquel,
> 
>>   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,
>> @@ -103,7 +103,7 @@ static const struct spinand_info macronix_spinand_table[] = {
>>                       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),
> 
> Maybe a bit late to the discussion, but shouldn't 20 and 40 be swapped
> here, i.e. isn't it the larger flash that has more max bad blocks than
> the smaller one?

I think Miquel is out of office for some days, so I just checked and you 
are right, the maximum number of bad blocks should be swapped.

Actually there is also a wrong value in the GigaDevice driver: For the 
GD5F4GQ4xA it should be 80 instead of 40.

Would you mind sending a patch with a "Fixes:" tag, that fixes both, the 
Macronix and the GigaDevice driver? Or should I send one?

Thanks,
Frieder
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 01/15] mtd: nand: Add max_bad_eraseblocks_per_lun info to memorg
  2019-06-06  8:27       ` Schrempf Frieder
@ 2019-06-06  8:39         ` Boris Brezillon
  -1 siblings, 0 replies; 66+ messages in thread
From: Boris Brezillon @ 2019-06-06  8:39 UTC (permalink / raw)
  To: Schrempf Frieder
  Cc: Mason Yang, Vignesh R, Boris Brezillon, Julien Su,
	Richard Weinberger, Emil Lenngren, Tudor Ambarus, Marek Vasut,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Brian Norris, David Woodhouse, linux-arm-kernel

On Thu, 6 Jun 2019 08:27:11 +0000
Schrempf Frieder <frieder.schrempf@kontron.de> wrote:

> Hi Emil,
> 
> On 04.06.19 10:01, Emil Lenngren wrote:
> > Hi Miquel,
> >   
> >>   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,
> >> @@ -103,7 +103,7 @@ static const struct spinand_info macronix_spinand_table[] = {
> >>                       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),  
> > 
> > Maybe a bit late to the discussion, but shouldn't 20 and 40 be swapped
> > here, i.e. isn't it the larger flash that has more max bad blocks than
> > the smaller one?  
> 
> I think Miquel is out of office for some days, so I just checked and you 
> are right, the maximum number of bad blocks should be swapped.
> 
> Actually there is also a wrong value in the GigaDevice driver: For the 
> GD5F4GQ4xA it should be 80 instead of 40.

Haven't checked the datasheet, but keep in mind that this is the max
number of eraseblock per LUN.

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 01/15] mtd: nand: Add max_bad_eraseblocks_per_lun info to memorg
@ 2019-06-06  8:39         ` Boris Brezillon
  0 siblings, 0 replies; 66+ messages in thread
From: Boris Brezillon @ 2019-06-06  8:39 UTC (permalink / raw)
  To: Schrempf Frieder
  Cc: Mason Yang, Vignesh R, Boris Brezillon, Julien Su,
	Richard Weinberger, Emil Lenngren, Tudor Ambarus, Marek Vasut,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Brian Norris, David Woodhouse, linux-arm-kernel

On Thu, 6 Jun 2019 08:27:11 +0000
Schrempf Frieder <frieder.schrempf@kontron.de> wrote:

> Hi Emil,
> 
> On 04.06.19 10:01, Emil Lenngren wrote:
> > Hi Miquel,
> >   
> >>   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,
> >> @@ -103,7 +103,7 @@ static const struct spinand_info macronix_spinand_table[] = {
> >>                       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),  
> > 
> > Maybe a bit late to the discussion, but shouldn't 20 and 40 be swapped
> > here, i.e. isn't it the larger flash that has more max bad blocks than
> > the smaller one?  
> 
> I think Miquel is out of office for some days, so I just checked and you 
> are right, the maximum number of bad blocks should be swapped.
> 
> Actually there is also a wrong value in the GigaDevice driver: For the 
> GD5F4GQ4xA it should be 80 instead of 40.

Haven't checked the datasheet, but keep in mind that this is the max
number of eraseblock per LUN.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 01/15] mtd: nand: Add max_bad_eraseblocks_per_lun info to memorg
  2019-06-06  8:39         ` Boris Brezillon
@ 2019-06-06  8:52           ` Schrempf Frieder
  -1 siblings, 0 replies; 66+ messages in thread
From: Schrempf Frieder @ 2019-06-06  8:52 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Mason Yang, Vignesh R, Boris Brezillon, Julien Su,
	Richard Weinberger, Emil Lenngren, Tudor Ambarus, Marek Vasut,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Brian Norris, David Woodhouse, linux-arm-kernel

On 06.06.19 10:39, Boris Brezillon wrote:
> On Thu, 6 Jun 2019 08:27:11 +0000
> Schrempf Frieder <frieder.schrempf@kontron.de> wrote:
> 
>> Hi Emil,
>>
>> On 04.06.19 10:01, Emil Lenngren wrote:
>>> Hi Miquel,
>>>    
>>>>    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,
>>>> @@ -103,7 +103,7 @@ static const struct spinand_info macronix_spinand_table[] = {
>>>>                        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),
>>>
>>> Maybe a bit late to the discussion, but shouldn't 20 and 40 be swapped
>>> here, i.e. isn't it the larger flash that has more max bad blocks than
>>> the smaller one?
>>
>> I think Miquel is out of office for some days, so I just checked and you
>> are right, the maximum number of bad blocks should be swapped.
>>
>> Actually there is also a wrong value in the GigaDevice driver: For the
>> GD5F4GQ4xA it should be 80 instead of 40.
> 
> Haven't checked the datasheet, but keep in mind that this is the max
> number of eraseblock per LUN.

The datasheet gives 20 for the 1G type and 40 for the 2G type. Both 
types have only one LUN. Only the 2G type has 2 planes, but that 
shouldn't make a difference, right?
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 01/15] mtd: nand: Add max_bad_eraseblocks_per_lun info to memorg
@ 2019-06-06  8:52           ` Schrempf Frieder
  0 siblings, 0 replies; 66+ messages in thread
From: Schrempf Frieder @ 2019-06-06  8:52 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Mason Yang, Vignesh R, Boris Brezillon, Julien Su,
	Richard Weinberger, Emil Lenngren, Tudor Ambarus, Marek Vasut,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Brian Norris, David Woodhouse, linux-arm-kernel

On 06.06.19 10:39, Boris Brezillon wrote:
> On Thu, 6 Jun 2019 08:27:11 +0000
> Schrempf Frieder <frieder.schrempf@kontron.de> wrote:
> 
>> Hi Emil,
>>
>> On 04.06.19 10:01, Emil Lenngren wrote:
>>> Hi Miquel,
>>>    
>>>>    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,
>>>> @@ -103,7 +103,7 @@ static const struct spinand_info macronix_spinand_table[] = {
>>>>                        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),
>>>
>>> Maybe a bit late to the discussion, but shouldn't 20 and 40 be swapped
>>> here, i.e. isn't it the larger flash that has more max bad blocks than
>>> the smaller one?
>>
>> I think Miquel is out of office for some days, so I just checked and you
>> are right, the maximum number of bad blocks should be swapped.
>>
>> Actually there is also a wrong value in the GigaDevice driver: For the
>> GD5F4GQ4xA it should be 80 instead of 40.
> 
> Haven't checked the datasheet, but keep in mind that this is the max
> number of eraseblock per LUN.

The datasheet gives 20 for the 1G type and 40 for the 2G type. Both 
types have only one LUN. Only the 2G type has 2 planes, but that 
shouldn't make a difference, right?
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 01/15] mtd: nand: Add max_bad_eraseblocks_per_lun info to memorg
  2019-06-06  8:52           ` Schrempf Frieder
@ 2019-06-06  8:57             ` Schrempf Frieder
  -1 siblings, 0 replies; 66+ messages in thread
From: Schrempf Frieder @ 2019-06-06  8:57 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Mason Yang, Vignesh R, Boris Brezillon, Julien Su,
	Richard Weinberger, Emil Lenngren, Tudor Ambarus, Marek Vasut,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Brian Norris, David Woodhouse, linux-arm-kernel

On 06.06.19 10:52, Frieder Schrempf wrote:
> On 06.06.19 10:39, Boris Brezillon wrote:
>> On Thu, 6 Jun 2019 08:27:11 +0000
>> Schrempf Frieder <frieder.schrempf@kontron.de> wrote:
>>
>>> Hi Emil,
>>>
>>> On 04.06.19 10:01, Emil Lenngren wrote:
>>>> Hi Miquel,
>>>>>    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,
>>>>> @@ -103,7 +103,7 @@ static const struct spinand_info 
>>>>> macronix_spinand_table[] = {
>>>>>                        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),
>>>>
>>>> Maybe a bit late to the discussion, but shouldn't 20 and 40 be swapped
>>>> here, i.e. isn't it the larger flash that has more max bad blocks than
>>>> the smaller one?
>>>
>>> I think Miquel is out of office for some days, so I just checked and you
>>> are right, the maximum number of bad blocks should be swapped.
>>>
>>> Actually there is also a wrong value in the GigaDevice driver: For the
>>> GD5F4GQ4xA it should be 80 instead of 40.
>>
>> Haven't checked the datasheet, but keep in mind that this is the max
>> number of eraseblock per LUN.
> 
> The datasheet gives 20 for the 1G type and 40 for the 2G type. Both 
> types have only one LUN. Only the 2G type has 2 planes, but that 
> shouldn't make a difference, right?

Sorry, I was referring to the Macronix chips. You were probably talking 
about the GigaDevice. But they all have only one LUN, too. So I think I 
got it right.
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 01/15] mtd: nand: Add max_bad_eraseblocks_per_lun info to memorg
@ 2019-06-06  8:57             ` Schrempf Frieder
  0 siblings, 0 replies; 66+ messages in thread
From: Schrempf Frieder @ 2019-06-06  8:57 UTC (permalink / raw)
  To: Boris Brezillon
  Cc: Mason Yang, Vignesh R, Boris Brezillon, Julien Su,
	Richard Weinberger, Emil Lenngren, Tudor Ambarus, Marek Vasut,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Brian Norris, David Woodhouse, linux-arm-kernel

On 06.06.19 10:52, Frieder Schrempf wrote:
> On 06.06.19 10:39, Boris Brezillon wrote:
>> On Thu, 6 Jun 2019 08:27:11 +0000
>> Schrempf Frieder <frieder.schrempf@kontron.de> wrote:
>>
>>> Hi Emil,
>>>
>>> On 04.06.19 10:01, Emil Lenngren wrote:
>>>> Hi Miquel,
>>>>>    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,
>>>>> @@ -103,7 +103,7 @@ static const struct spinand_info 
>>>>> macronix_spinand_table[] = {
>>>>>                        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),
>>>>
>>>> Maybe a bit late to the discussion, but shouldn't 20 and 40 be swapped
>>>> here, i.e. isn't it the larger flash that has more max bad blocks than
>>>> the smaller one?
>>>
>>> I think Miquel is out of office for some days, so I just checked and you
>>> are right, the maximum number of bad blocks should be swapped.
>>>
>>> Actually there is also a wrong value in the GigaDevice driver: For the
>>> GD5F4GQ4xA it should be 80 instead of 40.
>>
>> Haven't checked the datasheet, but keep in mind that this is the max
>> number of eraseblock per LUN.
> 
> The datasheet gives 20 for the 1G type and 40 for the 2G type. Both 
> types have only one LUN. Only the 2G type has 2 planes, but that 
> shouldn't make a difference, right?

Sorry, I was referring to the Macronix chips. You were probably talking 
about the GigaDevice. But they all have only one LUN, too. So I think I 
got it right.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 01/15] mtd: nand: Add max_bad_eraseblocks_per_lun info to memorg
  2019-06-06  8:57             ` Schrempf Frieder
@ 2019-06-06  9:05               ` Boris Brezillon
  -1 siblings, 0 replies; 66+ messages in thread
From: Boris Brezillon @ 2019-06-06  9:05 UTC (permalink / raw)
  To: Schrempf Frieder
  Cc: Mason Yang, Vignesh R, Boris Brezillon, Julien Su,
	Richard Weinberger, Emil Lenngren, Tudor Ambarus, Marek Vasut,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Brian Norris, David Woodhouse, linux-arm-kernel

On Thu, 6 Jun 2019 08:57:32 +0000
Schrempf Frieder <frieder.schrempf@kontron.de> wrote:

> On 06.06.19 10:52, Frieder Schrempf wrote:
> > On 06.06.19 10:39, Boris Brezillon wrote:  
> >> On Thu, 6 Jun 2019 08:27:11 +0000
> >> Schrempf Frieder <frieder.schrempf@kontron.de> wrote:
> >>  
> >>> Hi Emil,
> >>>
> >>> On 04.06.19 10:01, Emil Lenngren wrote:  
> >>>> Hi Miquel,  
> >>>>>    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,
> >>>>> @@ -103,7 +103,7 @@ static const struct spinand_info 
> >>>>> macronix_spinand_table[] = {
> >>>>>                        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),  
> >>>>
> >>>> Maybe a bit late to the discussion, but shouldn't 20 and 40 be swapped
> >>>> here, i.e. isn't it the larger flash that has more max bad blocks than
> >>>> the smaller one?  
> >>>
> >>> I think Miquel is out of office for some days, so I just checked and you
> >>> are right, the maximum number of bad blocks should be swapped.
> >>>
> >>> Actually there is also a wrong value in the GigaDevice driver: For the
> >>> GD5F4GQ4xA it should be 80 instead of 40.  
> >>
> >> Haven't checked the datasheet, but keep in mind that this is the max
> >> number of eraseblock per LUN.  
> > 
> > The datasheet gives 20 for the 1G type and 40 for the 2G type. Both 
> > types have only one LUN. Only the 2G type has 2 planes, but that 
> > shouldn't make a difference, right?  
> 
> Sorry, I was referring to the Macronix chips. You were probably talking 
> about the GigaDevice. But they all have only one LUN, too. So I think I 
> got it right.

Good, just wanted to make sure you were aware of that fact. As I said,
I didn't check the datasheet, so I trust you on this one.

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 01/15] mtd: nand: Add max_bad_eraseblocks_per_lun info to memorg
@ 2019-06-06  9:05               ` Boris Brezillon
  0 siblings, 0 replies; 66+ messages in thread
From: Boris Brezillon @ 2019-06-06  9:05 UTC (permalink / raw)
  To: Schrempf Frieder
  Cc: Mason Yang, Vignesh R, Boris Brezillon, Julien Su,
	Richard Weinberger, Emil Lenngren, Tudor Ambarus, Marek Vasut,
	Masahiro Yamada, linux-mtd, Thomas Petazzoni, Miquel Raynal,
	Brian Norris, David Woodhouse, linux-arm-kernel

On Thu, 6 Jun 2019 08:57:32 +0000
Schrempf Frieder <frieder.schrempf@kontron.de> wrote:

> On 06.06.19 10:52, Frieder Schrempf wrote:
> > On 06.06.19 10:39, Boris Brezillon wrote:  
> >> On Thu, 6 Jun 2019 08:27:11 +0000
> >> Schrempf Frieder <frieder.schrempf@kontron.de> wrote:
> >>  
> >>> Hi Emil,
> >>>
> >>> On 04.06.19 10:01, Emil Lenngren wrote:  
> >>>> Hi Miquel,  
> >>>>>    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,
> >>>>> @@ -103,7 +103,7 @@ static const struct spinand_info 
> >>>>> macronix_spinand_table[] = {
> >>>>>                        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),  
> >>>>
> >>>> Maybe a bit late to the discussion, but shouldn't 20 and 40 be swapped
> >>>> here, i.e. isn't it the larger flash that has more max bad blocks than
> >>>> the smaller one?  
> >>>
> >>> I think Miquel is out of office for some days, so I just checked and you
> >>> are right, the maximum number of bad blocks should be swapped.
> >>>
> >>> Actually there is also a wrong value in the GigaDevice driver: For the
> >>> GD5F4GQ4xA it should be 80 instead of 40.  
> >>
> >> Haven't checked the datasheet, but keep in mind that this is the max
> >> number of eraseblock per LUN.  
> > 
> > The datasheet gives 20 for the 1G type and 40 for the 2G type. Both 
> > types have only one LUN. Only the 2G type has 2 planes, but that 
> > shouldn't make a difference, right?  
> 
> Sorry, I was referring to the Macronix chips. You were probably talking 
> about the GigaDevice. But they all have only one LUN, too. So I think I 
> got it right.

Good, just wanted to make sure you were aware of that fact. As I said,
I didn't check the datasheet, so I trust you on this one.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 01/15] mtd: nand: Add max_bad_eraseblocks_per_lun info to memorg
  2019-06-06  8:27       ` Schrempf Frieder
@ 2019-06-06 13:06         ` Emil Lenngren
  -1 siblings, 0 replies; 66+ messages in thread
From: Emil Lenngren @ 2019-06-06 13:06 UTC (permalink / raw)
  To: Schrempf Frieder
  Cc: Mason Yang, Vignesh R, Boris Brezillon, Julien Su,
	Richard Weinberger, Tudor Ambarus, Marek Vasut, Masahiro Yamada,
	linux-mtd, Thomas Petazzoni, Miquel Raynal, Brian Norris,
	David Woodhouse, linux-arm-kernel

Hi Schrempf,

Den tors 6 juni 2019 kl 10:27 skrev Schrempf Frieder
<frieder.schrempf@kontron.de>:
>
> Hi Emil,
>
> On 04.06.19 10:01, Emil Lenngren wrote:
> > Hi Miquel,
> >
> >>   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,
> >> @@ -103,7 +103,7 @@ static const struct spinand_info macronix_spinand_table[] = {
> >>                       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),
> >
> > Maybe a bit late to the discussion, but shouldn't 20 and 40 be swapped
> > here, i.e. isn't it the larger flash that has more max bad blocks than
> > the smaller one?
>
> I think Miquel is out of office for some days, so I just checked and you
> are right, the maximum number of bad blocks should be swapped.
>
> Actually there is also a wrong value in the GigaDevice driver: For the
> GD5F4GQ4xA it should be 80 instead of 40.
>
> Would you mind sending a patch with a "Fixes:" tag, that fixes both, the
> Macronix and the GigaDevice driver? Or should I send one?

Please go ahead :)

/Emil

______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

^ permalink raw reply	[flat|nested] 66+ messages in thread

* Re: [PATCH v2 01/15] mtd: nand: Add max_bad_eraseblocks_per_lun info to memorg
@ 2019-06-06 13:06         ` Emil Lenngren
  0 siblings, 0 replies; 66+ messages in thread
From: Emil Lenngren @ 2019-06-06 13:06 UTC (permalink / raw)
  To: Schrempf Frieder
  Cc: Mason Yang, Vignesh R, Boris Brezillon, Julien Su,
	Richard Weinberger, Tudor Ambarus, Marek Vasut, Masahiro Yamada,
	linux-mtd, Thomas Petazzoni, Miquel Raynal, Brian Norris,
	David Woodhouse, linux-arm-kernel

Hi Schrempf,

Den tors 6 juni 2019 kl 10:27 skrev Schrempf Frieder
<frieder.schrempf@kontron.de>:
>
> Hi Emil,
>
> On 04.06.19 10:01, Emil Lenngren wrote:
> > Hi Miquel,
> >
> >>   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,
> >> @@ -103,7 +103,7 @@ static const struct spinand_info macronix_spinand_table[] = {
> >>                       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),
> >
> > Maybe a bit late to the discussion, but shouldn't 20 and 40 be swapped
> > here, i.e. isn't it the larger flash that has more max bad blocks than
> > the smaller one?
>
> I think Miquel is out of office for some days, so I just checked and you
> are right, the maximum number of bad blocks should be swapped.
>
> Actually there is also a wrong value in the GigaDevice driver: For the
> GD5F4GQ4xA it should be 80 instead of 40.
>
> Would you mind sending a patch with a "Fixes:" tag, that fixes both, the
> Macronix and the GigaDevice driver? Or should I send one?

Please go ahead :)

/Emil

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 66+ messages in thread

end of thread, other threads:[~2019-06-06 13:06 UTC | newest]

Thread overview: 66+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-03-04 20:15 [PATCH v2 00/15] mtd: rawnand: 5th batch of cleanups Miquel Raynal
2019-03-04 20:15 ` Miquel Raynal
2019-03-04 20:15 ` [PATCH v2 01/15] mtd: nand: Add max_bad_eraseblocks_per_lun info to memorg Miquel Raynal
2019-03-04 20:15   ` Miquel Raynal
2019-06-04  8:01   ` Emil Lenngren
2019-06-04  8:01     ` Emil Lenngren
2019-06-06  8:27     ` Schrempf Frieder
2019-06-06  8:27       ` Schrempf Frieder
2019-06-06  8:39       ` Boris Brezillon
2019-06-06  8:39         ` Boris Brezillon
2019-06-06  8:52         ` Schrempf Frieder
2019-06-06  8:52           ` Schrempf Frieder
2019-06-06  8:57           ` Schrempf Frieder
2019-06-06  8:57             ` Schrempf Frieder
2019-06-06  9:05             ` Boris Brezillon
2019-06-06  9:05               ` Boris Brezillon
2019-06-06 13:06       ` Emil Lenngren
2019-06-06 13:06         ` Emil Lenngren
2019-03-04 20:15 ` [PATCH v2 02/15] mtd: nand: Add a helper returning the number of eraseblocks per target Miquel Raynal
2019-03-04 20:15   ` Miquel Raynal
2019-03-04 20:15 ` [PATCH v2 03/15] mtd: nand: Add a helper to retrieve the number of pages " Miquel Raynal
2019-03-04 20:15   ` Miquel Raynal
2019-03-04 20:15 ` [PATCH v2 04/15] mtd: spinand: Implement mtd->_max_bad_blocks Miquel Raynal
2019-03-04 20:15   ` Miquel Raynal
2019-03-04 20:15 ` [PATCH v2 05/15] mtd: rawnand: Use nand_to_mtd() in nand_{set, get}_flash_node() Miquel Raynal
2019-03-04 20:15   ` Miquel Raynal
2019-03-04 20:15 ` [PATCH v2 06/15] mtd: rawnand: Prepare things to reuse the generic NAND layer Miquel Raynal
2019-03-04 20:15   ` Miquel Raynal
2019-03-04 20:15 ` [PATCH v2 07/15] mtd: rawnand: Fill memorg during detection Miquel Raynal
2019-03-04 20:15   ` Miquel Raynal
2019-03-21  9:03   ` Schrempf Frieder
2019-03-21  9:03     ` Schrempf Frieder
2019-03-04 20:15 ` [PATCH v2 08/15] mtd: rawnand: Initialize the nand_device object Miquel Raynal
2019-03-04 20:15   ` Miquel Raynal
2019-03-04 20:15 ` [PATCH v2 09/15] mtd: rawnand: Provide a helper to get chip->data_buf Miquel Raynal
2019-03-04 20:15   ` Miquel Raynal
2019-03-04 20:15 ` [PATCH v2 10/15] mtd: rawnand: Move all page cache related fields to a sub-struct Miquel Raynal
2019-03-04 20:15   ` Miquel Raynal
2019-03-04 20:15 ` [PATCH v2 11/15] mtd: rawnand: Use nanddev_mtd_max_bad_blocks() Miquel Raynal
2019-03-04 20:15   ` Miquel Raynal
2019-03-04 20:15 ` [PATCH v2 12/15] mtd: rawnand: Get rid of chip->bits_per_cell Miquel Raynal
2019-03-04 20:15   ` Miquel Raynal
2019-03-04 20:15 ` [PATCH v2 13/15] mtd: rawnand: Get rid of chip->chipsize Miquel Raynal
2019-03-04 20:15   ` Miquel Raynal
2019-03-21  9:03   ` Schrempf Frieder
2019-03-21  9:03     ` Schrempf Frieder
2019-03-04 20:15 ` [PATCH v2 14/15] mtd: rawnand: Get rid of chip->numchips Miquel Raynal
2019-03-04 20:15   ` Miquel Raynal
2019-05-21  6:59   ` Sascha Hauer
2019-05-21  6:59     ` Sascha Hauer
2019-05-21  7:33     ` Boris Brezillon
2019-05-21  7:33       ` Boris Brezillon
2019-05-21  7:43       ` Boris Brezillon
2019-05-21  7:43         ` Boris Brezillon
2019-05-21  7:51       ` Boris Brezillon
2019-05-21  7:51         ` Boris Brezillon
2019-05-21  7:58         ` Sascha Hauer
2019-05-21  7:58           ` Sascha Hauer
2019-05-21  8:01           ` Boris Brezillon
2019-05-21  8:01             ` Boris Brezillon
2019-05-21  7:56       ` Sascha Hauer
2019-05-21  7:56         ` Sascha Hauer
2019-03-04 20:15 ` [PATCH v2 15/15] mtd: rawnand: Get rid of chip->ecc_{strength, step}_ds Miquel Raynal
2019-03-04 20:15   ` Miquel Raynal
2019-04-01 15:28 ` [PATCH v2 00/15] mtd: rawnand: 5th batch of cleanups Miquel Raynal
2019-04-01 15:28   ` Miquel Raynal

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.