From 9c7d4b029e1546d6903afbcebcc1daac8cac1d57 Mon Sep 17 00:00:00 2001 From: Sai Krishna Potthuri Date: Tue, 8 Mar 2022 20:33:56 +0530 Subject: [PATCH] mtd: spi-nor: Avoid updating the flash_info struct in dual and stacked modes flash_info structure is declared as const by default but the const declaration is removed to support dual parallel and stacked modes where page size, sector size and number of sectors information updating in the flash_info structure based on the connection mode. This patch avoid/removed updating page size, sector size and number of sectors information in the flash_info structure and bring back the const declaration to the flash_info structures. Based on the 'isparallel' and 'isstacked' flags, page size, sector size and number of sectors information is handled wherever they are being used. Signed-off-by: Sai Krishna Potthuri --- drivers/mtd/spi-nor/core.c | 37 +++++++++++++++++++++++---------- drivers/mtd/spi-nor/issi.c | 2 +- drivers/mtd/spi-nor/macronix.c | 8 +++++-- drivers/mtd/spi-nor/micron-st.c | 2 +- drivers/mtd/spi-nor/spansion.c | 9 ++++++-- drivers/mtd/spi-nor/swp.c | 14 ++++++++++--- drivers/mtd/spi-nor/winbond.c | 2 +- 7 files changed, 53 insertions(+), 21 deletions(-) diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c index 1207eb2fcd5f58..4fda2aa11707ef 100644 --- a/drivers/mtd/spi-nor/core.c +++ b/drivers/mtd/spi-nor/core.c @@ -1361,12 +1361,17 @@ static bool spi_nor_has_uniform_erase(const struct spi_nor *nor) static void spi_nor_set_4byte_opcodes(struct spi_nor *nor) { + u32 sector_size = nor->info->sector_size; + /* Do some manufacturer fixups first */ switch (nor->jedec_id) { case CFI_MFR_AMD: /* No small sector erase for 4-byte command set */ nor->erase_opcode = SPINOR_OP_SE; - nor->mtd.erasesize = nor->info->sector_size; + if (nor->isparallel) + sector_size <<= 1; + + nor->mtd.erasesize = sector_size; break; default: break; @@ -2689,6 +2694,9 @@ static int spi_nor_select_erase(struct spi_nor *nor) u32 wanted_size = nor->info->sector_size; int i; + if (nor->isparallel) + wanted_size <<= 1; + if (mtd->erasesize && nor->jedec_id != CFI_MFR_AMD) return 0; @@ -2853,6 +2861,9 @@ static void spi_nor_info_init_params(struct spi_nor *nor) const struct flash_info *info = nor->info; struct device_node *np = spi_nor_get_flash_node(nor); u8 i, erase_mask; + u32 n_sectors = info->n_sectors; + u32 sector_size = info->sector_size; + u32 page_size = info->page_size; /* Initialize default flash parameters and settings. */ params->quad_enable = spi_nor_sr2_bit1_quad_enable; @@ -2865,8 +2876,16 @@ static void spi_nor_info_init_params(struct spi_nor *nor) /* Set SPI NOR sizes. */ params->writesize = 1; - params->size = (u64)info->sector_size * info->n_sectors; - params->page_size = info->page_size; + if (nor->isstacked) + n_sectors <<= 1; + + if (nor->isparallel) { + sector_size <<= 1; + page_size <<= 1; + } + + params->size = (u64)sector_size * n_sectors; + params->page_size = page_size; if (!(info->flags & SPI_NOR_NO_FR)) { /* Default to Fast Read for DT and non-DT platform devices. */ @@ -2949,7 +2968,7 @@ static void spi_nor_info_init_params(struct spi_nor *nor) i++; } erase_mask |= BIT(i); - spi_nor_set_erase_type(&map->erase_type[i], info->sector_size, + spi_nor_set_erase_type(&map->erase_type[i], sector_size, SPINOR_OP_SE); spi_nor_init_uniform_erase_map(map, erase_mask, params->size); } @@ -3480,7 +3499,7 @@ static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor, int spi_nor_scan(struct spi_nor *nor, const char *name, const struct spi_nor_hwcaps *hwcaps) { - struct flash_info *info = NULL; + const struct flash_info *info = NULL; struct device *dev = nor->dev; struct mtd_info *mtd = &nor->mtd; struct device_node *np = spi_nor_get_flash_node(nor); @@ -3512,7 +3531,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, if (!nor->bouncebuf) return -ENOMEM; - info = (struct flash_info *)spi_nor_get_flash_info(nor, name); + info = spi_nor_get_flash_info(nor, name); if (IS_ERR(info)) return PTR_ERR(info); @@ -3574,9 +3593,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, if (is_dual == 1) { /* dual parallel */ nor->shift = 1; - info->sector_size <<= nor->shift; - info->page_size <<= nor->shift; - nor->page_size = info->page_size; + nor->page_size = info->page_size << nor->shift; mtd->size <<= nor->shift; nor->isparallel = 1; nor->isstacked = 0; @@ -3588,7 +3605,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, /* dual stacked */ nor->shift = 0; mtd->size <<= 1; - info->n_sectors <<= 1; nor->isstacked = 1; nor->isparallel = 0; #else @@ -3603,7 +3619,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, /* dual stacked */ nor->shift = 0; mtd->size <<= 1; - info->n_sectors <<= 1; nor->isstacked = 1; nor->isparallel = 0; } else { diff --git a/drivers/mtd/spi-nor/issi.c b/drivers/mtd/spi-nor/issi.c index 52f9e350acac4c..9583f6b2e947c8 100644 --- a/drivers/mtd/spi-nor/issi.c +++ b/drivers/mtd/spi-nor/issi.c @@ -159,7 +159,7 @@ static struct spi_nor_fixups is25lp256_fixups = { .post_bfpt = is25lp256_post_bfpt_fixups, }; -static struct flash_info issi_parts[] = { +static const struct flash_info issi_parts[] = { /* ISSI */ { "is25wp080d", INFO(0x9d7014, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_HAS_LOCK) }, diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c index f93bdd579ba4ee..6fb13fac0375fd 100644 --- a/drivers/mtd/spi-nor/macronix.c +++ b/drivers/mtd/spi-nor/macronix.c @@ -83,6 +83,7 @@ static int mx25um51345g_set_4byte(struct spi_nor *nor, bool enable) static void mx25um51345g_default_init_fixups(struct spi_nor *nor) { u8 id_byte1, id_byte2; + u32 sector_size = nor->info->sector_size; nor->params->set_4byte_addr_mode = mx25um51345g_set_4byte; @@ -99,8 +100,11 @@ static void mx25um51345g_default_init_fixups(struct spi_nor *nor) nor->spimem->device_id[4] = id_byte2; nor->spimem->device_id[5] = id_byte2; + if (nor->isparallel) + sector_size <<= 1; + spi_nor_set_erase_type(&nor->params->erase_map.erase_type[1], - nor->info->sector_size, SPINOR_OP_BE_4K_4B); + sector_size, SPINOR_OP_BE_4K_4B); nor->params->page_programs[SNOR_CMD_PP_8_8_8_DTR].opcode = SPINOR_OP_PP_4B; @@ -156,7 +160,7 @@ static struct spi_nor_fixups mx25l25635_fixups = { .post_bfpt = mx25l25635_post_bfpt_fixups, }; -static struct flash_info macronix_parts[] = { +static const struct flash_info macronix_parts[] = { /* Macronix */ { "mx25l512e", INFO(0xc22010, 0, 64 * 1024, 1, SECT_4K) }, { "mx25l2005a", INFO(0xc22012, 0, 64 * 1024, 4, SECT_4K) }, diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c index c4705103c4ace0..b83b33b6f7d16c 100644 --- a/drivers/mtd/spi-nor/micron-st.c +++ b/drivers/mtd/spi-nor/micron-st.c @@ -143,7 +143,7 @@ static const struct flash_info micron_parts[] = { .fixups = &mt35xu512aba_fixups}, }; -static struct flash_info st_parts[] = { +static const struct flash_info st_parts[] = { { "n25q016a", INFO(0x20bb15, 0, 64 * 1024, 32, SECT_4K | SPI_NOR_QUAD_READ) }, { "n25q032", INFO(0x20ba16, 0, 64 * 1024, 64, diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c index 6bab0cae298ee4..806794b2d8f2c9 100644 --- a/drivers/mtd/spi-nor/spansion.c +++ b/drivers/mtd/spi-nor/spansion.c @@ -194,7 +194,7 @@ static struct spi_nor_fixups s25fs_s_fixups = { .post_bfpt = s25fs_s_post_bfpt_fixups, }; -static struct flash_info spansion_parts[] = { +static const struct flash_info spansion_parts[] = { /* Spansion/Cypress -- single (large) sector size only, at least * for the chips listed here (without boot sectors). */ @@ -278,13 +278,18 @@ static struct flash_info spansion_parts[] = { static void spansion_post_sfdp_fixups(struct spi_nor *nor) { + u32 sector_size = nor->info->sector_size; + if (nor->params->size <= SZ_16M) return; + if (nor->isparallel) + sector_size <<= 1; + nor->flags |= SNOR_F_4B_OPCODES; /* No small sector erase for 4-byte command set */ nor->erase_opcode = SPINOR_OP_SE; - nor->mtd.erasesize = nor->info->sector_size; + nor->mtd.erasesize = sector_size; } static const struct spi_nor_fixups spansion_fixups = { diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c index 96118dc97dd006..ce79963dee8add 100644 --- a/drivers/mtd/spi-nor/swp.c +++ b/drivers/mtd/spi-nor/swp.c @@ -37,16 +37,24 @@ static u64 spi_nor_get_min_prot_length_sr(struct spi_nor *nor) { unsigned int bp_slots, bp_slots_needed; u8 mask = spi_nor_get_sr_bp_mask(nor); + u32 n_sectors = nor->info->n_sectors; + u32 sector_size = nor->info->sector_size; + + if (nor->isstacked) + n_sectors <<= 1; + + if (nor->isparallel) + sector_size <<= 1; /* Reserved one for "protect none" and one for "protect all". */ bp_slots = (1 << hweight8(mask)) - 2; - bp_slots_needed = ilog2(nor->info->n_sectors); + bp_slots_needed = ilog2(n_sectors); if (bp_slots_needed > bp_slots) - return nor->info->sector_size << + return sector_size << (bp_slots_needed - bp_slots); else - return nor->info->sector_size; + return sector_size; } static void spi_nor_get_locked_range_sr(struct spi_nor *nor, u8 sr, loff_t *ofs, diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c index 57a13f2d233b53..32710b76244acf 100644 --- a/drivers/mtd/spi-nor/winbond.c +++ b/drivers/mtd/spi-nor/winbond.c @@ -32,7 +32,7 @@ static struct spi_nor_fixups w25q256_fixups = { .post_bfpt = w25q256_post_bfpt_fixups, }; -static struct flash_info winbond_parts[] = { +static const struct flash_info winbond_parts[] = { /* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */ { "w25x05", INFO(0xef3010, 0, 64 * 1024, 1, SECT_4K) }, { "w25x10", INFO(0xef3011, 0, 64 * 1024, 2, SECT_4K) },