From 981d1aa0697ce1393e00933f154d181e965703d0 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 24 Jan 2019 15:56:43 +0100 Subject: mtd: spinand: Use the spi-mem dirmap API Make use of the spi-mem direct mapping API to let advanced controllers optimize read/write operations when they support direct mapping. Signed-off-by: Boris Brezillon Cc: Stefan Roese Signed-off-by: Miquel Raynal Tested-by: Stefan Roese --- include/linux/mtd/spinand.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include') diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h index b92e2aa955b6..507f7e289bd1 100644 --- a/include/linux/mtd/spinand.h +++ b/include/linux/mtd/spinand.h @@ -302,6 +302,11 @@ struct spinand_info { __VA_ARGS__ \ } +struct spinand_dirmap { + struct spi_mem_dirmap_desc *wdesc; + struct spi_mem_dirmap_desc *rdesc; +}; + /** * struct spinand_device - SPI NAND device instance * @base: NAND device instance @@ -341,6 +346,8 @@ struct spinand_device { const struct spi_mem_op *update_cache; } op_templates; + struct spinand_dirmap *dirmaps; + int (*select_target)(struct spinand_device *spinand, unsigned int target); unsigned int cur_target; -- cgit v1.2.3-58-ga151 From b309df2422c052330a2411c827eb697ee0114ac6 Mon Sep 17 00:00:00 2001 From: Tudor Ambarus Date: Wed, 13 Feb 2019 08:59:44 +0000 Subject: ARM: at91: add sam9x60 SFR definitions Keep generic names, as there are no conflicts with previous SFR definitions. While touching bits, update AT91_OHCIICR_USB_SUSPEND to use GENMASK, replace unused AT91_OHCIICR_SUSPEND_A/B/C with a more generic macro, align values on tab-width. Signed-off-by: Tudor Ambarus Acked-by: Alexandre Belloni Signed-off-by: Miquel Raynal --- include/soc/at91/atmel-sfr.h | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/soc/at91/atmel-sfr.h b/include/soc/at91/atmel-sfr.h index 482337af06b8..532fd784e86c 100644 --- a/include/soc/at91/atmel-sfr.h +++ b/include/soc/at91/atmel-sfr.h @@ -14,21 +14,41 @@ #define _LINUX_MFD_SYSCON_ATMEL_SFR_H #define AT91_SFR_DDRCFG 0x04 /* DDR Configuration Register */ +#define AT91_SFR_CCFG_EBICSA 0x04 /* EBI Chip Select Register */ /* 0x08 ~ 0x0c: Reserved */ #define AT91_SFR_OHCIICR 0x10 /* OHCI INT Configuration Register */ #define AT91_SFR_OHCIISR 0x14 /* OHCI INT Status Register */ #define AT91_SFR_UTMICKTRIM 0x30 /* UTMI Clock Trimming Register */ +#define AT91_SFR_UTMISWAP 0x3c /* UTMI DP/DM Pin Swapping Register */ +#define AT91_SFR_LS 0x7c /* Light Sleep Register */ #define AT91_SFR_I2SCLKSEL 0x90 /* I2SC Register */ +#define AT91_SFR_WPMR 0xe4 /* Write Protection Mode Register */ /* Field definitions */ -#define AT91_OHCIICR_SUSPEND_A BIT(8) -#define AT91_OHCIICR_SUSPEND_B BIT(9) -#define AT91_OHCIICR_SUSPEND_C BIT(10) +#define AT91_SFR_CCFG_EBI_CSA(cs, val) ((val) << (cs)) +#define AT91_SFR_CCFG_EBI_DBPUC BIT(8) +#define AT91_SFR_CCFG_EBI_DBPDC BIT(9) +#define AT91_SFR_CCFG_EBI_DRIVE BIT(17) +#define AT91_SFR_CCFG_NFD0_ON_D16 BIT(24) +#define AT91_SFR_CCFG_DDR_MP_EN BIT(25) -#define AT91_OHCIICR_USB_SUSPEND (AT91_OHCIICR_SUSPEND_A | \ - AT91_OHCIICR_SUSPEND_B | \ - AT91_OHCIICR_SUSPEND_C) +#define AT91_SFR_OHCIICR_RES(x) BIT(x) +#define AT91_SFR_OHCIICR_ARIE BIT(4) +#define AT91_SFR_OHCIICR_APPSTART BIT(5) +#define AT91_SFR_OHCIICR_USB_SUSP(x) BIT(8 + (x)) +#define AT91_SFR_OHCIICR_UDPPUDIS BIT(23) +#define AT91_OHCIICR_USB_SUSPEND GENMASK(10, 8) -#define AT91_UTMICKTRIM_FREQ GENMASK(1, 0) +#define AT91_SFR_OHCIISR_RIS(x) BIT(x) + +#define AT91_UTMICKTRIM_FREQ GENMASK(1, 0) + +#define AT91_SFR_UTMISWAP_PORT(x) BIT(x) + +#define AT91_SFR_LS_VALUE(x) BIT(x) +#define AT91_SFR_LS_MEM_POWER_GATING_ULP1_EN BIT(16) + +#define AT91_SFR_WPMR_WPEN BIT(0) +#define AT91_SFR_WPMR_WPKEY_MASK GENMASK(31, 8) #endif /* _LINUX_MFD_SYSCON_ATMEL_SFR_H */ -- cgit v1.2.3-58-ga151 From 377e517b5fa53590418a7b4c2206082d92434fa3 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Sun, 4 Nov 2018 14:43:37 +0100 Subject: mtd: nand: Add max_bad_eraseblocks_per_lun info to memorg 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 Signed-off-by: Miquel Raynal Reviewed-by: Frieder Schrempf --- drivers/mtd/nand/core.c | 34 ++++++++++++++++++++++++++++++++++ drivers/mtd/nand/spi/gigadevice.c | 8 ++++---- drivers/mtd/nand/spi/macronix.c | 4 ++-- drivers/mtd/nand/spi/micron.c | 2 +- drivers/mtd/nand/spi/toshiba.c | 12 ++++++------ drivers/mtd/nand/spi/winbond.c | 4 ++-- include/linux/mtd/nand.h | 6 +++++- 7 files changed, 54 insertions(+), 16 deletions(-) (limited to 'include') diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c index 9c9f8936b63b..b6de955ac8bf 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 0b49d8264bef..e5586390026a 100644 --- a/drivers/mtd/nand/spi/gigadevice.c +++ b/drivers/mtd/nand/spi/gigadevice.c @@ -162,7 +162,7 @@ static const struct mtd_ooblayout_ops gd5fxgq4uexxg_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, @@ -171,7 +171,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, @@ -180,7 +180,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, @@ -189,7 +189,7 @@ static const struct spinand_info gigadevice_spinand_table[] = { SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, gd5fxgq4xa_ecc_get_status)), SPINAND_INFO("GD5F1GQ4UExxG", 0xd1, - NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 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 d16b57081c95..6502727049a8 100644 --- a/drivers/mtd/nand/spi/macronix.c +++ b/drivers/mtd/nand/spi/macronix.c @@ -100,7 +100,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, @@ -109,7 +109,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 db8021da45b5..1cb3760ff779 100644 --- a/drivers/mtd/nand/spi/toshiba.c +++ b/drivers/mtd/nand/spi/toshiba.c @@ -96,7 +96,7 @@ static int tc58cxgxsx_ecc_get_status(struct spinand_device *spinand, static const struct spinand_info toshiba_spinand_table[] = { /* 3.3V 1Gb */ SPINAND_INFO("TC58CVG0S3", 0xC2, - NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 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 toshiba_spinand_table[] = { tc58cxgxsx_ecc_get_status)), /* 3.3V 2Gb */ SPINAND_INFO("TC58CVG1S3", 0xCB, - NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1), + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), NAND_ECCREQ(8, 512), SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, @@ -116,7 +116,7 @@ static const struct spinand_info toshiba_spinand_table[] = { tc58cxgxsx_ecc_get_status)), /* 3.3V 4Gb */ SPINAND_INFO("TC58CVG2S0", 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, @@ -126,7 +126,7 @@ static const struct spinand_info toshiba_spinand_table[] = { tc58cxgxsx_ecc_get_status)), /* 1.8V 1Gb */ SPINAND_INFO("TC58CYG0S3", 0xB2, - NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), + NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), NAND_ECCREQ(8, 512), SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, @@ -136,7 +136,7 @@ static const struct spinand_info toshiba_spinand_table[] = { tc58cxgxsx_ecc_get_status)), /* 1.8V 2Gb */ SPINAND_INFO("TC58CYG1S3", 0xBB, - NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1), + NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), NAND_ECCREQ(8, 512), SPINAND_INFO_OP_VARIANTS(&read_cache_variants, &write_cache_variants, @@ -146,7 +146,7 @@ static const struct spinand_info toshiba_spinand_table[] = { tc58cxgxsx_ecc_get_status)), /* 1.8V 4Gb */ SPINAND_INFO("TC58CYG2S0", 0xBD, - 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 */ -- cgit v1.2.3-58-ga151 From 7c4ecca103b3d70c50adc693c9f5d39d292e13e0 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Mon, 29 Oct 2018 10:29:48 +0100 Subject: mtd: nand: Add a helper returning the number of eraseblocks per target 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 Signed-off-by: Miquel Raynal Reviewed-by: Frieder Schrempf --- include/linux/mtd/nand.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'include') 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 -- cgit v1.2.3-58-ga151 From 46b01d7efda29356d4dff88825e5ef51dd9f6bae Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Mon, 29 Oct 2018 17:18:39 +0100 Subject: mtd: nand: Add a helper to retrieve the number of pages per target Will be used by the raw NAND framework. Signed-off-by: Boris Brezillon Signed-off-by: Miquel Raynal Reviewed-by: Frieder Schrempf --- include/linux/mtd/nand.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'include') 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 -- cgit v1.2.3-58-ga151 From 080d66e94d69a5b1d197ac411db6c27700868af8 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 25 Oct 2018 15:05:39 +0200 Subject: mtd: rawnand: Use nand_to_mtd() in nand_{set,get}_flash_node() Use the nand_to_mtd() helper to access chip->mtd as done everywhere else. Signed-off-by: Boris Brezillon Signed-off-by: Miquel Raynal Reviewed-by: Frieder Schrempf --- include/linux/mtd/rawnand.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index b7445a44a814..d5c7741c0901 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -1105,17 +1105,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); @@ -1147,6 +1136,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 -- cgit v1.2.3-58-ga151 From 3020e30af6f81beedfeb4cf4eecc693bba55a6c2 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 25 Oct 2018 15:21:08 +0200 Subject: mtd: rawnand: Prepare things to reuse the generic NAND layer 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 Signed-off-by: Miquel Raynal Reviewed-by: Frieder Schrempf --- include/linux/mtd/rawnand.h | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index d5c7741c0901..58887cb2c7ea 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -860,6 +861,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 * @@ -962,7 +964,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 @@ -1041,7 +1043,7 @@ struct nand_legacy { */ struct nand_chip { - struct mtd_info mtd; + struct nand_device base; struct nand_legacy legacy; @@ -1107,12 +1109,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) -- cgit v1.2.3-58-ga151 From eeab717483e5fb529c8001d36fbda14011905e5f Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Sun, 28 Oct 2018 15:27:55 +0100 Subject: mtd: rawnand: Provide a helper to get chip->data_buf 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 Signed-off-by: Miquel Raynal Reviewed-by: Frieder Schrempf --- 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(-) (limited to 'include') 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 bcf5328cf239..df7071e6da5b 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 f38e5c1b87e4..e81d401ee16c 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(chip->data_buf, 0xFF, mtd->writesize); + memset(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(chip->data_buf, 0xFF, mtd->writesize); + memset(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 071a0c658bfe..fe8119c6cd61 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4004,10 +4004,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 19a2b563acdf..fff803695b2d 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 920e7375084f..6ead55e05b80 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 4282bc477761..d206819c962a 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1313,20 +1313,19 @@ pio_fallback: static int sunxi_nfc_hw_ecc_read_oob(struct nand_chip *nand, int page) { - nand->pagebuf = -1; + u8 *buf = nand_get_data_buf(nand); - return nand->ecc.read_page(nand, nand->data_buf, 1, page); + return nand->ecc.read_page(nand, buf, 1, page); } static int sunxi_nfc_hw_ecc_write_oob(struct nand_chip *nand, int page) { struct mtd_info *mtd = nand_to_mtd(nand); + u8 *buf = nand_get_data_buf(nand); int ret; - nand->pagebuf = -1; - - memset(nand->data_buf, 0xff, mtd->writesize); - ret = nand->ecc.write_page(nand, nand->data_buf, 1, page); + memset(buf, 0xff, mtd->writesize); + ret = nand->ecc.write_page(nand, buf, 1, page); if (ret) return ret; diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index 58887cb2c7ea..253f9942a919 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -1350,4 +1350,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 */ -- cgit v1.2.3-58-ga151 From d974541e23791e189c5faa0462223d29352cecc6 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Sun, 28 Oct 2018 16:12:45 +0100 Subject: mtd: rawnand: Move all page cache related fields to a sub-struct 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 Signed-off-by: Miquel Raynal Reviewed-by: Frieder Schrempf --- drivers/mtd/nand/raw/nand_base.c | 28 ++++++++++++++-------------- include/linux/mtd/rawnand.h | 18 +++++++++++------- 2 files changed, 25 insertions(+), 21 deletions(-) (limited to 'include') diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index fe8119c6cd61..26aeea06035b 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -459,8 +459,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); @@ -3173,7 +3173,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) @@ -3199,7 +3199,7 @@ read_retry: if (ret < 0) { if (use_bufpoi) /* Invalidate page cache */ - chip->pagebuf = -1; + chip->pagecache.page = -1; break; } @@ -3208,11 +3208,11 @@ read_retry: 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); } @@ -3252,7 +3252,7 @@ read_retry: 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; @@ -3973,9 +3973,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)) { @@ -4196,9 +4196,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; ret = nand_erase_op(chip, (page & chip->pagemask) >> (chip->phys_erase_shift - chip->page_shift)); @@ -5782,7 +5782,7 @@ static int nand_scan_tail(struct nand_chip *chip) chip->subpagesize = mtd->writesize >> mtd->subpage_sft; /* 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 253f9942a919..99250dc848e8 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -1007,10 +1007,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 @@ -1060,8 +1060,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; @@ -1366,7 +1370,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; } -- cgit v1.2.3-58-ga151 From 7beb37e5f0d29d7d23aec0e47900ff4dfa8c2e55 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Sun, 4 Nov 2018 14:50:28 +0100 Subject: mtd: rawnand: Use nanddev_mtd_max_bad_blocks() 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 Signed-off-by: Miquel Raynal Reviewed-by: Frieder Schrempf --- 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(-) (limited to 'include') diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 26aeea06035b..035b9cf327a6 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4297,42 +4297,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 @@ -5819,7 +5783,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 99250dc848e8..9d0cdae4e204 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -1015,9 +1015,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 && @@ -1076,8 +1073,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; -- cgit v1.2.3-58-ga151 From 298151689b33e04eaf09cf22e1d42396f7723690 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Thu, 25 Oct 2018 17:16:47 +0200 Subject: mtd: rawnand: Get rid of chip->bits_per_cell 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 Signed-off-by: Miquel Raynal Reviewed-by: Frieder Schrempf --- 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(-) (limited to 'include') diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 035b9cf327a6..77c0e0ef61b1 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4457,7 +4457,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]; @@ -4501,7 +4500,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; } /* @@ -4544,7 +4542,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, @@ -4584,7 +4581,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 9d0cdae4e204..b2570adab911 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -992,7 +992,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. @@ -1064,7 +1063,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; @@ -1236,9 +1234,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; } /** -- cgit v1.2.3-58-ga151 From 6c836d515ff85e333488692c67969f714654a1c6 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Mon, 29 Oct 2018 11:22:16 +0100 Subject: mtd: rawnand: Get rid of chip->chipsize 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 Reviewed-by: Frieder Schrempf Signed-off-by: Miquel Raynal --- drivers/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/ingenic/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(-) (limited to 'include') 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 e99d59d85197..be1cc064bdb4 100644 --- a/drivers/mtd/nand/raw/denali.c +++ b/drivers/mtd/nand/raw/denali.c @@ -1134,7 +1134,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 df7071e6da5b..eec39615bc6f 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/ingenic/jz4740_nand.c b/drivers/mtd/nand/raw/ingenic/jz4740_nand.c index d5715dde4237..27e16c44a94d 100644 --- a/drivers/mtd/nand/raw/ingenic/jz4740_nand.c +++ b/drivers/mtd/nand/raw/ingenic/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 77c0e0ef61b1..f89cc8be5ce4 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4542,7 +4542,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 * @@ -4633,6 +4632,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 @@ -4737,8 +4737,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 @@ -4780,14 +4778,15 @@ ident_done: /* 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; } @@ -4803,7 +4802,7 @@ ident_done: 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; @@ -5054,7 +5053,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 fff803695b2d..42399a32d34a 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 bf54733f8b5b..0f86dd283769 100644 --- a/drivers/mtd/nand/raw/nandsim.c +++ b/drivers/mtd/nand/raw/nandsim.c @@ -2305,6 +2305,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); @@ -2313,12 +2314,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 b2570adab911..02657591c3fc 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -1003,7 +1003,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 @@ -1053,7 +1052,6 @@ struct nand_chip { int bbt_erase_shift; int chip_shift; int numchips; - uint64_t chipsize; int pagemask; u8 *data_buf; -- cgit v1.2.3-58-ga151 From 32813e288414fecce18f37f8f0d0414a64b45c56 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Mon, 29 Oct 2018 11:58:29 +0100 Subject: mtd: rawnand: Get rid of chip->numchips The same information is provided by nanddev_ntargets(). Signed-off-by: Boris Brezillon Signed-off-by: Miquel Raynal Reviewed-by: Frieder Schrempf --- 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/ingenic/jz4740_nand.c | 1 - drivers/mtd/nand/raw/internals.h | 2 +- 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(-) (limited to 'include') diff --git a/drivers/mtd/nand/raw/diskonchip.c b/drivers/mtd/nand/raw/diskonchip.c index 2e0da6a24bfd..f430c4bf0323 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/ingenic/jz4740_nand.c b/drivers/mtd/nand/raw/ingenic/jz4740_nand.c index 27e16c44a94d..f759f1672855 100644 --- a/drivers/mtd/nand/raw/ingenic/jz4740_nand.c +++ b/drivers/mtd/nand/raw/ingenic/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/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/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index f89cc8be5ce4..73eb23b5cdad 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; @@ -4999,12 +4999,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); @@ -5052,7 +5046,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; @@ -5794,7 +5787,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 42399a32d34a..9a7855839f81 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 02657591c3fc..27c968d370bf 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -1002,7 +1002,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 @@ -1016,8 +1015,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 * @lock: lock protecting the suspended field. Also used to * serialize accesses to the NAND device. @@ -1051,7 +1051,6 @@ struct nand_chip { int phys_erase_shift; int bbt_erase_shift; int chip_shift; - int numchips; int pagemask; u8 *data_buf; -- cgit v1.2.3-58-ga151 From 6a1b66d6c8d691b1395d5c3b660ac4469c25bc28 Mon Sep 17 00:00:00 2001 From: Boris Brezillon Date: Sun, 4 Nov 2018 16:09:42 +0100 Subject: mtd: rawnand: Get rid of chip->ecc_{strength,step}_ds 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 Signed-off-by: Miquel Raynal Reviewed-by: Frieder Schrempf --- 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(-) (limited to 'include') diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c index 3205b705d734..80d14ba06245 100644 --- a/drivers/mtd/nand/raw/atmel/nand-controller.c +++ b/drivers/mtd/nand/raw/atmel/nand-controller.c @@ -1072,15 +1072,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 eec39615bc6f..40df20d1adf5 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 e81d401ee16c..825c47b3fa0d 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 2c0e09187773..b17619f30b1b 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 73eb23b5cdad..4646add22114 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -4547,8 +4547,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; @@ -5227,8 +5227,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; @@ -5421,7 +5421,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; @@ -5430,9 +5430,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, µn_nand_on_die_4_ooblayout_ops); else mtd_set_ooblayout(mtd, µn_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 d206819c962a..13f03324d36a 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1723,8 +1723,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 27c968d370bf..c0589f82c1f8 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -992,12 +992,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 @@ -1060,8 +1054,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; -- cgit v1.2.3-58-ga151 From e90a619fb7e1acb5e18f1ab618c6d10b08f0fc70 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Thu, 7 Feb 2019 15:28:24 +0100 Subject: mtd: nand: omap: Fix comment in platform data using wrong Kconfig symbol The symbol that is being used in the #if/#endif block is not the one which is mentioned at the bottom. Fixes: 93af53b8633c ("nand: omap2: Remove horrible ifdefs to fix module probe") Signed-off-by: Miquel Raynal --- include/linux/platform_data/elm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/linux/platform_data/elm.h b/include/linux/platform_data/elm.h index b8686c00f15f..fef4b081b736 100644 --- a/include/linux/platform_data/elm.h +++ b/include/linux/platform_data/elm.h @@ -60,6 +60,6 @@ static inline int elm_config(struct device *dev, enum bch_ecc bch_type, { return -ENOSYS; } -#endif /* CONFIG_MTD_NAND_ECC_BCH */ +#endif /* CONFIG_MTD_NAND_OMAP_BCH */ #endif /* __ELM_H */ -- cgit v1.2.3-58-ga151 From 714c068228d3275da6d36f29e544f7e5ae648849 Mon Sep 17 00:00:00 2001 From: Miquel Raynal Date: Wed, 6 Feb 2019 15:12:27 +0100 Subject: mtd: nand: Clarify Kconfig entry for software BCH ECC algorithm There is no point in having two distinct entries, merge them and rename the symbol for more clarity: MTD_NAND_ECC_SW_BCH Signed-off-by: Miquel Raynal --- arch/arm/configs/omap2plus_defconfig | 2 +- arch/arm/configs/pxa_defconfig | 2 +- arch/mips/configs/db1xxx_defconfig | 2 +- arch/mips/configs/generic/board-ni169445.config | 2 +- drivers/mtd/devices/Kconfig | 2 +- drivers/mtd/nand/raw/Kconfig | 9 ++------- drivers/mtd/nand/raw/Makefile | 2 +- drivers/mtd/nand/raw/nand_base.c | 2 +- drivers/mtd/nand/raw/omap2.c | 4 ++-- include/linux/mtd/nand_bch.h | 6 +++--- 10 files changed, 14 insertions(+), 19 deletions(-) (limited to 'include') diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index 3f03ec6d2644..7dc2ac9175de 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -144,7 +144,7 @@ CONFIG_MTD_ONENAND=y CONFIG_MTD_ONENAND_VERIFY_WRITE=y CONFIG_MTD_ONENAND_OMAP2=y CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_ECC_BCH=y +CONFIG_MTD_NAND_ECC_SW_BCH=y CONFIG_MTD_NAND_OMAP2=y CONFIG_MTD_NAND_OMAP_BCH=y CONFIG_MTD_SPI_NOR=m diff --git a/arch/arm/configs/pxa_defconfig b/arch/arm/configs/pxa_defconfig index d4654755b09c..d91adb49ae11 100644 --- a/arch/arm/configs/pxa_defconfig +++ b/arch/arm/configs/pxa_defconfig @@ -186,7 +186,7 @@ CONFIG_MTD_M25P80=m CONFIG_MTD_BLOCK2MTD=y CONFIG_MTD_DOCG3=m CONFIG_MTD_NAND=m -CONFIG_MTD_NAND_ECC_BCH=y +CONFIG_MTD_NAND_ECC_SW_BCH=y CONFIG_MTD_NAND_GPIO=m CONFIG_MTD_NAND_DISKONCHIP=m CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y diff --git a/arch/mips/configs/db1xxx_defconfig b/arch/mips/configs/db1xxx_defconfig index 34633b7611cb..c5a2c6f234d4 100644 --- a/arch/mips/configs/db1xxx_defconfig +++ b/arch/mips/configs/db1xxx_defconfig @@ -96,7 +96,7 @@ CONFIG_MTD_PHYSMAP=y CONFIG_MTD_M25P80=y CONFIG_MTD_SST25L=y CONFIG_MTD_NAND=y -CONFIG_MTD_NAND_ECC_BCH=y +CONFIG_MTD_NAND_ECC_SW_BCH=y CONFIG_MTD_NAND_AU1550=y CONFIG_MTD_NAND_PLATFORM=y CONFIG_MTD_SPI_NOR=y diff --git a/arch/mips/configs/generic/board-ni169445.config b/arch/mips/configs/generic/board-ni169445.config index f72223b366ca..01f6ab0d47d5 100644 --- a/arch/mips/configs/generic/board-ni169445.config +++ b/arch/mips/configs/generic/board-ni169445.config @@ -16,7 +16,7 @@ CONFIG_MTD_BLOCK=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_NAND_ECC=y -CONFIG_MTD_NAND_ECC_BCH=y +CONFIG_MTD_NAND_ECC_SW_BCH=y CONFIG_MTD_NAND=y CONFIG_MTD_NAND_GPIO=y CONFIG_MTD_NAND_IDS=y diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig index aa983422aa97..f9258d666846 100644 --- a/drivers/mtd/devices/Kconfig +++ b/drivers/mtd/devices/Kconfig @@ -207,7 +207,7 @@ comment "Disk-On-Chip Device Drivers" config MTD_DOCG3 tristate "M-Systems Disk-On-Chip G3" select BCH - select BCH_CONST_PARAMS if !MTD_NAND_BCH + select BCH_CONST_PARAMS if !MTD_NAND_ECC_SW_BCH select BITREVERSE help This provides an MTD device driver for the M-Systems DiskOnChip diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index 80b5fec1f75a..7a1bde4fe9f6 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -22,14 +22,9 @@ menuconfig MTD_NAND if MTD_NAND -config MTD_NAND_BCH - tristate +config MTD_NAND_ECC_SW_BCH + tristate "Support software BCH ECC" select BCH - depends on MTD_NAND_ECC_BCH - default MTD_NAND - -config MTD_NAND_ECC_BCH - bool "Support software BCH ECC" default n help This enables support for software BCH error correction. Binary BCH diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile index 5552c4a9f2cf..9749ff00f9e4 100644 --- a/drivers/mtd/nand/raw/Makefile +++ b/drivers/mtd/nand/raw/Makefile @@ -2,7 +2,7 @@ obj-$(CONFIG_MTD_NAND) += nand.o obj-$(CONFIG_MTD_NAND_ECC) += nand_ecc.o -obj-$(CONFIG_MTD_NAND_BCH) += nand_bch.o +obj-$(CONFIG_MTD_NAND_ECC_SW_BCH) += nand_bch.o obj-$(CONFIG_MTD_SM_COMMON) += sm_common.o obj-$(CONFIG_MTD_NAND_CAFE) += cafe_nand.o diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 4646add22114..95fac92d6b82 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -5087,7 +5087,7 @@ static int nand_set_ecc_soft_ops(struct nand_chip *chip) return 0; case NAND_ECC_BCH: if (!mtd_nand_has_bch()) { - WARN(1, "CONFIG_MTD_NAND_ECC_BCH not enabled\n"); + WARN(1, "CONFIG_MTD_NAND_ECC_SW_BCH not enabled\n"); return -EINVAL; } ecc->calculate = nand_bch_calculate_ecc; diff --git a/drivers/mtd/nand/raw/omap2.c b/drivers/mtd/nand/raw/omap2.c index 8f280a2962c8..a9a275342a41 100644 --- a/drivers/mtd/nand/raw/omap2.c +++ b/drivers/mtd/nand/raw/omap2.c @@ -1725,9 +1725,9 @@ static bool omap2_nand_ecc_check(struct omap_nand_info *info) break; } - if (ecc_needs_bch && !IS_ENABLED(CONFIG_MTD_NAND_ECC_BCH)) { + if (ecc_needs_bch && !IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_BCH)) { dev_err(&info->pdev->dev, - "CONFIG_MTD_NAND_ECC_BCH not enabled\n"); + "CONFIG_MTD_NAND_ECC_SW_BCH not enabled\n"); return false; } if (ecc_needs_omap_bch && !IS_ENABLED(CONFIG_MTD_NAND_OMAP_BCH)) { diff --git a/include/linux/mtd/nand_bch.h b/include/linux/mtd/nand_bch.h index b8106651f807..a8a6909b594e 100644 --- a/include/linux/mtd/nand_bch.h +++ b/include/linux/mtd/nand_bch.h @@ -15,7 +15,7 @@ struct mtd_info; struct nand_chip; struct nand_bch_control; -#if defined(CONFIG_MTD_NAND_ECC_BCH) +#if IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_BCH) static inline int mtd_nand_has_bch(void) { return 1; } @@ -39,7 +39,7 @@ struct nand_bch_control *nand_bch_init(struct mtd_info *mtd); */ void nand_bch_free(struct nand_bch_control *nbc); -#else /* !CONFIG_MTD_NAND_ECC_BCH */ +#else /* !CONFIG_MTD_NAND_ECC_SW_BCH */ static inline int mtd_nand_has_bch(void) { return 0; } @@ -64,6 +64,6 @@ static inline struct nand_bch_control *nand_bch_init(struct mtd_info *mtd) static inline void nand_bch_free(struct nand_bch_control *nbc) {} -#endif /* CONFIG_MTD_NAND_ECC_BCH */ +#endif /* CONFIG_MTD_NAND_ECC_SW_BCH */ #endif /* __MTD_NAND_BCH_H__ */ -- cgit v1.2.3-58-ga151 From 7e8afca5cf1aeeec183a221c6fc07faf4cc380df Mon Sep 17 00:00:00 2001 From: Jonathan Neuschäfer Date: Fri, 22 Mar 2019 00:52:41 +0100 Subject: mtd: rawnand: Fix sphinx syntax MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sphinx doesn't handle expressions in identifier references. This fixes the following warnings: ./include/linux/mtd/rawnand.h:1184: WARNING: Inline strong start-string without end-string. ./include/linux/mtd/rawnand.h:1186: WARNING: Inline strong start-string without end-string. Signed-off-by: Jonathan Neuschäfer Signed-off-by: Miquel Raynal --- include/linux/mtd/rawnand.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index c0589f82c1f8..7c0ccd3a2772 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -1168,9 +1168,9 @@ static inline struct device_node *nand_get_flash_node(struct nand_chip *chip) * @name: a human-readable name of the NAND chip * @dev_id: the device ID (the second byte of the full chip ID array) * @mfr_id: manufecturer ID part of the full chip ID array (refers the same - * memory address as @id[0]) + * memory address as ``id[0]``) * @dev_id: device ID part of the full chip ID array (refers the same memory - * address as @id[1]) + * address as ``id[1]``) * @id: full device ID array * @pagesize: size of the NAND page in bytes; if 0, then the real page size (as * well as the eraseblock size) is determined from the extended NAND -- cgit v1.2.3-58-ga151 From f56cad5fd6cd876d0cab9d13d9df7bebf6fddf59 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 9 Apr 2019 13:53:32 +0900 Subject: mtd: rawnand: constify elements of NAND_OP_PARSER(_PATTERN) Currently, drivers are able to constify a nand_op_parser array, but not nand_op_parser_pattern and nand_op_parser_pattern_elem since they are instantiated by using the NAND_OP_PARSER(_PATTERN). Add 'const' to them in order to move more driver data from .data to .rodata section. Signed-off-by: Masahiro Yamada Reviewed-by: Boris Brezillon Signed-off-by: Miquel Raynal --- include/linux/mtd/rawnand.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index 7c0ccd3a2772..39f6c62b0ede 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -806,7 +806,7 @@ struct nand_op_parser_pattern { #define NAND_OP_PARSER_PATTERN(_exec, ...) \ { \ .exec = _exec, \ - .elems = (struct nand_op_parser_pattern_elem[]) { __VA_ARGS__ }, \ + .elems = (const struct nand_op_parser_pattern_elem[]) { __VA_ARGS__ }, \ .nelems = sizeof((struct nand_op_parser_pattern_elem[]) { __VA_ARGS__ }) / \ sizeof(struct nand_op_parser_pattern_elem), \ } @@ -832,7 +832,7 @@ struct nand_op_parser { #define NAND_OP_PARSER(...) \ { \ - .patterns = (struct nand_op_parser_pattern[]) { __VA_ARGS__ }, \ + .patterns = (const struct nand_op_parser_pattern[]) { __VA_ARGS__ }, \ .npatterns = sizeof((struct nand_op_parser_pattern[]) { __VA_ARGS__ }) / \ sizeof(struct nand_op_parser_pattern), \ } -- cgit v1.2.3-58-ga151 From 04649ec1335f2289c230f080e52e09f7b9c95c4a Mon Sep 17 00:00:00 2001 From: Frieder Schrempf Date: Wed, 17 Apr 2019 12:36:34 +0000 Subject: mtd: rawnand: Always store info about bad block markers in chip struct The information about where the manufacturer puts the bad block markers inside the bad block and in the OOB data is stored in different places. Let's move this information to nand_chip.options and nand_chip.badblockpos. As this chip-specific information is not directly related to the bad block table (BBT), we also rename the flags to NAND_BBM_*. Signed-off-by: Frieder Schrempf Reviewed-by: Miquel Raynal Signed-off-by: Miquel Raynal --- drivers/mtd/nand/raw/nand_amd.c | 2 +- drivers/mtd/nand/raw/nand_base.c | 12 ++++++------ drivers/mtd/nand/raw/nand_bbt.c | 4 ++-- drivers/mtd/nand/raw/nand_esmt.c | 2 +- drivers/mtd/nand/raw/nand_hynix.c | 4 ++-- drivers/mtd/nand/raw/nand_macronix.c | 2 +- drivers/mtd/nand/raw/nand_micron.c | 2 +- drivers/mtd/nand/raw/nand_samsung.c | 4 ++-- drivers/mtd/nand/raw/nand_toshiba.c | 2 +- drivers/mtd/nand/raw/sh_flctl.c | 4 ++-- include/linux/mtd/rawnand.h | 16 +++++++++++++++- 11 files changed, 34 insertions(+), 20 deletions(-) (limited to 'include') diff --git a/drivers/mtd/nand/raw/nand_amd.c b/drivers/mtd/nand/raw/nand_amd.c index e008fd662ee6..9051e4e41eee 100644 --- a/drivers/mtd/nand/raw/nand_amd.c +++ b/drivers/mtd/nand/raw/nand_amd.c @@ -45,7 +45,7 @@ static void amd_nand_decode_id(struct nand_chip *chip) static int amd_nand_init(struct nand_chip *chip) { if (nand_is_slc(chip)) - chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; + chip->options |= NAND_BBM_SECONDPAGE; return 0; } diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index fd7ce5b929c0..e1111291389a 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -295,11 +295,11 @@ static int nand_block_bad(struct nand_chip *chip, loff_t ofs) int page, page_end, res; u8 bad; - if (chip->bbt_options & NAND_BBT_SCANLASTPAGE) + if (chip->options & NAND_BBM_LASTPAGE) ofs += mtd->erasesize - mtd->writesize; page = (int)(ofs >> chip->page_shift) & chip->pagemask; - page_end = page + (chip->bbt_options & NAND_BBT_SCAN2NDPAGE ? 2 : 1); + page_end = page + ((chip->options & NAND_BBM_SECONDPAGE) ? 2 : 1); for (; page < page_end; page++) { res = chip->ecc.read_oob(chip, page); @@ -507,7 +507,7 @@ static int nand_default_block_markbad(struct nand_chip *chip, loff_t ofs) ops.mode = MTD_OPS_PLACE_OOB; /* Write to first/last page(s) if necessary */ - if (chip->bbt_options & NAND_BBT_SCANLASTPAGE) + if (chip->options & NAND_BBM_LASTPAGE) ofs += mtd->erasesize - mtd->writesize; do { res = nand_do_write_oob(chip, ofs, &ops); @@ -516,7 +516,7 @@ static int nand_default_block_markbad(struct nand_chip *chip, loff_t ofs) i++; ofs += mtd->writesize; - } while ((chip->bbt_options & NAND_BBT_SCAN2NDPAGE) && i < 2); + } while ((chip->options & NAND_BBM_SECONDPAGE) && i < 2); return ret; } @@ -4513,9 +4513,9 @@ static void nand_decode_bbm_options(struct nand_chip *chip) /* Set the bad block position */ if (mtd->writesize > 512 || (chip->options & NAND_BUSWIDTH_16)) - chip->badblockpos = NAND_LARGE_BADBLOCK_POS; + chip->badblockpos = NAND_BBM_POS_LARGE; else - chip->badblockpos = NAND_SMALL_BADBLOCK_POS; + chip->badblockpos = NAND_BBM_POS_SMALL; } static inline bool is_full_id_nand(struct nand_flash_dev *type) diff --git a/drivers/mtd/nand/raw/nand_bbt.c b/drivers/mtd/nand/raw/nand_bbt.c index 9a7855839f81..4915dd7283bb 100644 --- a/drivers/mtd/nand/raw/nand_bbt.c +++ b/drivers/mtd/nand/raw/nand_bbt.c @@ -468,7 +468,7 @@ static int create_bbt(struct nand_chip *this, uint8_t *buf, pr_info("Scanning device for bad blocks\n"); - if (bd->options & NAND_BBT_SCAN2NDPAGE) + if (this->options & NAND_BBM_SECONDPAGE) numpages = 2; else numpages = 1; @@ -489,7 +489,7 @@ static int create_bbt(struct nand_chip *this, uint8_t *buf, from = (loff_t)startblock << this->bbt_erase_shift; } - if (this->bbt_options & NAND_BBT_SCANLASTPAGE) + if (this->options & NAND_BBM_LASTPAGE) from += mtd->erasesize - (mtd->writesize * numpages); for (i = startblock; i < numblocks; i++) { diff --git a/drivers/mtd/nand/raw/nand_esmt.c b/drivers/mtd/nand/raw/nand_esmt.c index 3de5e89482f5..4320d4c6a7cd 100644 --- a/drivers/mtd/nand/raw/nand_esmt.c +++ b/drivers/mtd/nand/raw/nand_esmt.c @@ -36,7 +36,7 @@ static void esmt_nand_decode_id(struct nand_chip *chip) static int esmt_nand_init(struct nand_chip *chip) { if (nand_is_slc(chip)) - chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; + chip->options |= NAND_BBM_SECONDPAGE; return 0; } diff --git a/drivers/mtd/nand/raw/nand_hynix.c b/drivers/mtd/nand/raw/nand_hynix.c index 821d221b83eb..33cb10df65b8 100644 --- a/drivers/mtd/nand/raw/nand_hynix.c +++ b/drivers/mtd/nand/raw/nand_hynix.c @@ -688,9 +688,9 @@ static int hynix_nand_init(struct nand_chip *chip) int ret; if (!nand_is_slc(chip)) - chip->bbt_options |= NAND_BBT_SCANLASTPAGE; + chip->options |= NAND_BBM_LASTPAGE; else - chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; + chip->options |= NAND_BBM_SECONDPAGE; hynix = kzalloc(sizeof(*hynix), GFP_KERNEL); if (!hynix) diff --git a/drivers/mtd/nand/raw/nand_macronix.c b/drivers/mtd/nand/raw/nand_macronix.c index 47d8cda547cf..6db7ced4b96b 100644 --- a/drivers/mtd/nand/raw/nand_macronix.c +++ b/drivers/mtd/nand/raw/nand_macronix.c @@ -62,7 +62,7 @@ static void macronix_nand_fix_broken_get_timings(struct nand_chip *chip) static int macronix_nand_init(struct nand_chip *chip) { if (nand_is_slc(chip)) - chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; + chip->options |= NAND_BBM_SECONDPAGE; macronix_nand_fix_broken_get_timings(chip); diff --git a/drivers/mtd/nand/raw/nand_micron.c b/drivers/mtd/nand/raw/nand_micron.c index 7a2cef02eacd..d43e15772f73 100644 --- a/drivers/mtd/nand/raw/nand_micron.c +++ b/drivers/mtd/nand/raw/nand_micron.c @@ -448,7 +448,7 @@ static int micron_nand_init(struct nand_chip *chip) goto err_free_manuf_data; if (mtd->writesize == 2048) - chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; + chip->options |= NAND_BBM_SECONDPAGE; ondie = micron_supports_on_die_ecc(chip); diff --git a/drivers/mtd/nand/raw/nand_samsung.c b/drivers/mtd/nand/raw/nand_samsung.c index f7d7041b6213..f4db72329b7b 100644 --- a/drivers/mtd/nand/raw/nand_samsung.c +++ b/drivers/mtd/nand/raw/nand_samsung.c @@ -131,9 +131,9 @@ static int samsung_nand_init(struct nand_chip *chip) chip->options |= NAND_SAMSUNG_LP_OPTIONS; if (!nand_is_slc(chip)) - chip->bbt_options |= NAND_BBT_SCANLASTPAGE; + chip->options |= NAND_BBM_LASTPAGE; else - chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; + chip->options |= NAND_BBM_SECONDPAGE; return 0; } diff --git a/drivers/mtd/nand/raw/nand_toshiba.c b/drivers/mtd/nand/raw/nand_toshiba.c index 13f9632f1cb4..67f01cef5651 100644 --- a/drivers/mtd/nand/raw/nand_toshiba.c +++ b/drivers/mtd/nand/raw/nand_toshiba.c @@ -152,7 +152,7 @@ static void toshiba_nand_decode_id(struct nand_chip *chip) static int toshiba_nand_init(struct nand_chip *chip) { if (nand_is_slc(chip)) - chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; + chip->options |= NAND_BBM_SECONDPAGE; /* Check that chip is BENAND and ECC mode is on-die */ if (nand_is_slc(chip) && chip->ecc.mode == NAND_ECC_ON_DIE && diff --git a/drivers/mtd/nand/raw/sh_flctl.c b/drivers/mtd/nand/raw/sh_flctl.c index 3f610040f0c3..02a6768ab13f 100644 --- a/drivers/mtd/nand/raw/sh_flctl.c +++ b/drivers/mtd/nand/raw/sh_flctl.c @@ -101,14 +101,12 @@ static const struct mtd_ooblayout_ops flctl_4secc_oob_largepage_ops = { static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; static struct nand_bbt_descr flctl_4secc_smallpage = { - .options = NAND_BBT_SCAN2NDPAGE, .offs = 11, .len = 1, .pattern = scan_ff_pattern, }; static struct nand_bbt_descr flctl_4secc_largepage = { - .options = NAND_BBT_SCAN2NDPAGE, .offs = 0, .len = 2, .pattern = scan_ff_pattern, @@ -1179,6 +1177,8 @@ static int flctl_probe(struct platform_device *pdev) if (pdata->flcmncr_val & SEL_16BIT) nand->options |= NAND_BUSWIDTH_16; + nand->options |= NAND_BBM_SECONDPAGE; + pm_runtime_enable(&pdev->dev); pm_runtime_resume(&pdev->dev); diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index 39f6c62b0ede..8b3e28ef75ce 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -169,6 +169,20 @@ enum nand_ecc_algo { /* Macros to identify the above */ #define NAND_HAS_SUBPAGE_READ(chip) ((chip->options & NAND_SUBPAGE_READ)) +/* + * There are different places where the manufacturer stores the factory bad + * block markers. + * + * Position within the block: Each of these pages needs to be checked for a + * bad block marking pattern. + */ +#define NAND_BBM_SECONDPAGE 0x02000000 +#define NAND_BBM_LASTPAGE 0x04000000 + +/* Position within the OOB data of the page */ +#define NAND_BBM_POS_SMALL 5 +#define NAND_BBM_POS_LARGE 0 + /* Non chip related options */ /* This option skips the bbt scan during initialization. */ #define NAND_SKIP_BBTSCAN 0x00010000 @@ -1055,7 +1069,7 @@ struct nand_chip { int subpagesize; int onfi_timing_mode_default; - int badblockpos; + unsigned int badblockpos; int badblockbits; struct nand_id id; -- cgit v1.2.3-58-ga151 From bfd15c904ac584dfacfafb1e382c158f6db73d2a Mon Sep 17 00:00:00 2001 From: Frieder Schrempf Date: Wed, 17 Apr 2019 12:36:35 +0000 Subject: mtd: onenand: Store bad block marker position in chip struct The information about where the manufacturer puts the bad block markers inside the bad block and in the OOB data is stored in different places. Let's move this information to the chip struct, as we did it for rawnand. Signed-off-by: Frieder Schrempf Reviewed-by: Miquel Raynal Signed-off-by: Miquel Raynal --- drivers/mtd/nand/onenand/onenand_base.c | 5 ++++- drivers/mtd/nand/onenand/onenand_bbt.c | 3 --- include/linux/mtd/onenand.h | 3 +++ 3 files changed, 7 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/drivers/mtd/nand/onenand/onenand_base.c b/drivers/mtd/nand/onenand/onenand_base.c index 4ca4b194e7d7..f41d76248550 100644 --- a/drivers/mtd/nand/onenand/onenand_base.c +++ b/drivers/mtd/nand/onenand/onenand_base.c @@ -2458,7 +2458,7 @@ static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) bbm->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); /* We write two bytes, so we don't have to mess with 16-bit access */ - ofs += mtd->oobsize + (bbm->badblockpos & ~0x01); + ofs += mtd->oobsize + (this->badblockpos & ~0x01); /* FIXME : What to do when marking SLC block in partition * with MLC erasesize? For now, it is not advisable to * create partitions containing both SLC and MLC regions. @@ -3967,6 +3967,9 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) if (!(this->options & ONENAND_SKIP_INITIAL_UNLOCKING)) this->unlock_all(mtd); + /* Set the bad block marker position */ + this->badblockpos = ONENAND_BADBLOCK_POS; + ret = this->scan_bbt(mtd); if ((!FLEXONENAND(this)) || ret) return ret; diff --git a/drivers/mtd/nand/onenand/onenand_bbt.c b/drivers/mtd/nand/onenand/onenand_bbt.c index dde20487937d..57c31c81be18 100644 --- a/drivers/mtd/nand/onenand/onenand_bbt.c +++ b/drivers/mtd/nand/onenand/onenand_bbt.c @@ -190,9 +190,6 @@ static int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) if (!bbm->bbt) return -ENOMEM; - /* Set the bad block position */ - bbm->badblockpos = ONENAND_BADBLOCK_POS; - /* Set erase shift */ bbm->bbt_erase_shift = this->erase_shift; diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h index 0aaa98b219a4..bfe9e10fae04 100644 --- a/include/linux/mtd/onenand.h +++ b/include/linux/mtd/onenand.h @@ -94,6 +94,7 @@ struct onenand_chip { unsigned int technology; unsigned int density_mask; unsigned int options; + unsigned int badblockpos; unsigned int erase_shift; unsigned int page_shift; @@ -188,6 +189,8 @@ struct onenand_chip { /* Check byte access in OneNAND */ #define ONENAND_CHECK_BYTE_ACCESS(addr) (addr & 0x1) +#define ONENAND_BADBLOCK_POS 0 + /* * Options bits */ -- cgit v1.2.3-58-ga151 From c902467cda2d927dba0d6bd2c2efc1988720b8d6 Mon Sep 17 00:00:00 2001 From: Frieder Schrempf Date: Wed, 17 Apr 2019 12:36:35 +0000 Subject: mtd: nand: Cleanup flags and fields for bad block marker position Now that we have moved the information to the chip level, let's remove all the unused flags and fields. Signed-off-by: Frieder Schrempf Reviewed-by: Miquel Raynal Signed-off-by: Miquel Raynal --- include/linux/mtd/bbm.h | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'include') diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h index 3102bd754d18..010bc5544c54 100644 --- a/include/linux/mtd/bbm.h +++ b/include/linux/mtd/bbm.h @@ -93,10 +93,7 @@ struct nand_bbt_descr { #define NAND_BBT_WRITE 0x00002000 /* Read and write back block contents when writing bbt */ #define NAND_BBT_SAVECONTENT 0x00004000 -/* Search good / bad pattern on the first and the second page */ -#define NAND_BBT_SCAN2NDPAGE 0x00008000 -/* Search good / bad pattern on the last page of the eraseblock */ -#define NAND_BBT_SCANLASTPAGE 0x00010000 + /* * Use a flash based bad block table. By default, OOB identifier is saved in * OOB area. This option is passed to the default bad block table function. @@ -123,13 +120,6 @@ struct nand_bbt_descr { /* The maximum number of blocks to scan for a bbt */ #define NAND_BBT_SCAN_MAXBLOCKS 4 -/* - * Constants for oob configuration - */ -#define NAND_SMALL_BADBLOCK_POS 5 -#define NAND_LARGE_BADBLOCK_POS 0 -#define ONENAND_BADBLOCK_POS 0 - /* * Bad block scanning errors */ @@ -140,7 +130,6 @@ struct nand_bbt_descr { /** * struct bbm_info - [GENERIC] Bad Block Table data structure * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry - * @badblockpos: [INTERN] position of the bad block marker in the oob area * @options: options for this descriptor * @bbt: [INTERN] bad block table pointer * @isbad_bbt: function to determine if a block is bad @@ -150,7 +139,6 @@ struct nand_bbt_descr { */ struct bbm_info { int bbt_erase_shift; - int badblockpos; int options; uint8_t *bbt; -- cgit v1.2.3-58-ga151 From bb5925480b13f52ad2e29ab20695c7f27e10f382 Mon Sep 17 00:00:00 2001 From: Frieder Schrempf Date: Wed, 17 Apr 2019 12:36:36 +0000 Subject: mtd: nand: Make flags for bad block marker position more granular To be able to check and set bad block markers in the first and second page of a block independently of each other, we create separate flags for both cases. Previously NAND_BBM_SECONDPAGE meant, that both, the first and the second page were used. With this patch NAND_BBM_FIRSTPAGE stands for using the first page and NAND_BBM_SECONDPAGE for using the second page. This patch is only for preparation of subsequent changes and does not implement the logic to actually handle both flags separately. Signed-off-by: Frieder Schrempf Reviewed-by: Boris Brezillon Reviewed-by: Miquel Raynal Signed-off-by: Miquel Raynal --- drivers/mtd/nand/raw/nand_amd.c | 2 +- drivers/mtd/nand/raw/nand_base.c | 6 ++++-- drivers/mtd/nand/raw/nand_bbt.c | 3 ++- drivers/mtd/nand/raw/nand_esmt.c | 2 +- drivers/mtd/nand/raw/nand_hynix.c | 2 +- drivers/mtd/nand/raw/nand_macronix.c | 2 +- drivers/mtd/nand/raw/nand_micron.c | 2 +- drivers/mtd/nand/raw/nand_samsung.c | 2 +- drivers/mtd/nand/raw/nand_toshiba.c | 2 +- drivers/mtd/nand/raw/sh_flctl.c | 2 +- include/linux/mtd/rawnand.h | 1 + 11 files changed, 15 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/drivers/mtd/nand/raw/nand_amd.c b/drivers/mtd/nand/raw/nand_amd.c index 9051e4e41eee..1417559d3057 100644 --- a/drivers/mtd/nand/raw/nand_amd.c +++ b/drivers/mtd/nand/raw/nand_amd.c @@ -45,7 +45,7 @@ static void amd_nand_decode_id(struct nand_chip *chip) static int amd_nand_init(struct nand_chip *chip) { if (nand_is_slc(chip)) - chip->options |= NAND_BBM_SECONDPAGE; + chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE; return 0; } diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index e1111291389a..6e2d728d2fd9 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -299,7 +299,8 @@ static int nand_block_bad(struct nand_chip *chip, loff_t ofs) ofs += mtd->erasesize - mtd->writesize; page = (int)(ofs >> chip->page_shift) & chip->pagemask; - page_end = page + ((chip->options & NAND_BBM_SECONDPAGE) ? 2 : 1); + page_end = page + (((chip->options & NAND_BBM_FIRSTPAGE) && + (chip->options & NAND_BBM_SECONDPAGE)) ? 2 : 1); for (; page < page_end; page++) { res = chip->ecc.read_oob(chip, page); @@ -516,7 +517,8 @@ static int nand_default_block_markbad(struct nand_chip *chip, loff_t ofs) i++; ofs += mtd->writesize; - } while ((chip->options & NAND_BBM_SECONDPAGE) && i < 2); + } while ((chip->options & NAND_BBM_FIRSTPAGE) && + (chip->options & NAND_BBM_SECONDPAGE) && i < 2); return ret; } diff --git a/drivers/mtd/nand/raw/nand_bbt.c b/drivers/mtd/nand/raw/nand_bbt.c index 4915dd7283bb..4cb664847ef5 100644 --- a/drivers/mtd/nand/raw/nand_bbt.c +++ b/drivers/mtd/nand/raw/nand_bbt.c @@ -468,7 +468,8 @@ static int create_bbt(struct nand_chip *this, uint8_t *buf, pr_info("Scanning device for bad blocks\n"); - if (this->options & NAND_BBM_SECONDPAGE) + if ((this->options & NAND_BBM_FIRSTPAGE) && + (this->options & NAND_BBM_SECONDPAGE)) numpages = 2; else numpages = 1; diff --git a/drivers/mtd/nand/raw/nand_esmt.c b/drivers/mtd/nand/raw/nand_esmt.c index 4320d4c6a7cd..58646ed663ac 100644 --- a/drivers/mtd/nand/raw/nand_esmt.c +++ b/drivers/mtd/nand/raw/nand_esmt.c @@ -36,7 +36,7 @@ static void esmt_nand_decode_id(struct nand_chip *chip) static int esmt_nand_init(struct nand_chip *chip) { if (nand_is_slc(chip)) - chip->options |= NAND_BBM_SECONDPAGE; + chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE; return 0; } diff --git a/drivers/mtd/nand/raw/nand_hynix.c b/drivers/mtd/nand/raw/nand_hynix.c index 33cb10df65b8..7c600c4d5ec8 100644 --- a/drivers/mtd/nand/raw/nand_hynix.c +++ b/drivers/mtd/nand/raw/nand_hynix.c @@ -690,7 +690,7 @@ static int hynix_nand_init(struct nand_chip *chip) if (!nand_is_slc(chip)) chip->options |= NAND_BBM_LASTPAGE; else - chip->options |= NAND_BBM_SECONDPAGE; + chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE; hynix = kzalloc(sizeof(*hynix), GFP_KERNEL); if (!hynix) diff --git a/drivers/mtd/nand/raw/nand_macronix.c b/drivers/mtd/nand/raw/nand_macronix.c index 6db7ced4b96b..e287e71347c5 100644 --- a/drivers/mtd/nand/raw/nand_macronix.c +++ b/drivers/mtd/nand/raw/nand_macronix.c @@ -62,7 +62,7 @@ static void macronix_nand_fix_broken_get_timings(struct nand_chip *chip) static int macronix_nand_init(struct nand_chip *chip) { if (nand_is_slc(chip)) - chip->options |= NAND_BBM_SECONDPAGE; + chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE; macronix_nand_fix_broken_get_timings(chip); diff --git a/drivers/mtd/nand/raw/nand_micron.c b/drivers/mtd/nand/raw/nand_micron.c index d43e15772f73..cbd4f09ac178 100644 --- a/drivers/mtd/nand/raw/nand_micron.c +++ b/drivers/mtd/nand/raw/nand_micron.c @@ -448,7 +448,7 @@ static int micron_nand_init(struct nand_chip *chip) goto err_free_manuf_data; if (mtd->writesize == 2048) - chip->options |= NAND_BBM_SECONDPAGE; + chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE; ondie = micron_supports_on_die_ecc(chip); diff --git a/drivers/mtd/nand/raw/nand_samsung.c b/drivers/mtd/nand/raw/nand_samsung.c index f4db72329b7b..5552ce20ede0 100644 --- a/drivers/mtd/nand/raw/nand_samsung.c +++ b/drivers/mtd/nand/raw/nand_samsung.c @@ -133,7 +133,7 @@ static int samsung_nand_init(struct nand_chip *chip) if (!nand_is_slc(chip)) chip->options |= NAND_BBM_LASTPAGE; else - chip->options |= NAND_BBM_SECONDPAGE; + chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE; return 0; } diff --git a/drivers/mtd/nand/raw/nand_toshiba.c b/drivers/mtd/nand/raw/nand_toshiba.c index 67f01cef5651..74ffcae48726 100644 --- a/drivers/mtd/nand/raw/nand_toshiba.c +++ b/drivers/mtd/nand/raw/nand_toshiba.c @@ -152,7 +152,7 @@ static void toshiba_nand_decode_id(struct nand_chip *chip) static int toshiba_nand_init(struct nand_chip *chip) { if (nand_is_slc(chip)) - chip->options |= NAND_BBM_SECONDPAGE; + chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE; /* Check that chip is BENAND and ECC mode is on-die */ if (nand_is_slc(chip) && chip->ecc.mode == NAND_ECC_ON_DIE && diff --git a/drivers/mtd/nand/raw/sh_flctl.c b/drivers/mtd/nand/raw/sh_flctl.c index 02a6768ab13f..e509c93737c4 100644 --- a/drivers/mtd/nand/raw/sh_flctl.c +++ b/drivers/mtd/nand/raw/sh_flctl.c @@ -1177,7 +1177,7 @@ static int flctl_probe(struct platform_device *pdev) if (pdata->flcmncr_val & SEL_16BIT) nand->options |= NAND_BUSWIDTH_16; - nand->options |= NAND_BBM_SECONDPAGE; + nand->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE; pm_runtime_enable(&pdev->dev); pm_runtime_resume(&pdev->dev); diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index 8b3e28ef75ce..dbfffa5bec7b 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h @@ -176,6 +176,7 @@ enum nand_ecc_algo { * Position within the block: Each of these pages needs to be checked for a * bad block marking pattern. */ +#define NAND_BBM_FIRSTPAGE 0x01000000 #define NAND_BBM_SECONDPAGE 0x02000000 #define NAND_BBM_LASTPAGE 0x04000000 -- cgit v1.2.3-58-ga151