mtd: spi-nor: add Kconfig option to disable 4K sectors

Current situation with 4K sectors is quite messy. First of all, some
MTD "users" don't work with such small size. An example may be UBIFS
which requires 15 KiB erase blocks as a minimum. In theory spi-nor
should provide multiple erase regions and MTD "users" should use the
one they need. Unforunately that is not implemented.

In the result our flashes database in spi-nor is hackish. For some
flashes we pretend they don't support 4K sectors just because some
distribution uses UBIFS on it. This ofc leads to conflicts, like
Samsung using w25q128 with 4K sectors vs. OpenWrt requiring it to
pretend it's 64 KiB blocks only.

My idea (plan?) for fixing this situation:
1) Use real hw info (this requires a way for disabling 4K for now)
2) Provide detailed info about erase regions
3) Make UBIFS work with devices that support 4K sectors

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>

authored by

Rafał Miłecki and committed by
Brian Norris
57cf26c1 6d178ef2

+18 -1
+14
drivers/mtd/spi-nor/Kconfig
··· 7 8 if MTD_SPI_NOR 9 10 config SPI_FSL_QUADSPI 11 tristate "Freescale Quad SPI controller" 12 depends on ARCH_MXC
··· 7 8 if MTD_SPI_NOR 9 10 + config MTD_SPI_NOR_USE_4K_SECTORS 11 + bool "Use small 4096 B erase sectors" 12 + default y 13 + help 14 + Many flash memories support erasing small (4096 B) sectors. Depending 15 + on the usage this feature may provide performance gain in comparison 16 + to erasing whole blocks (32/64 KiB). 17 + Changing a small part of the flash's contents is usually faster with 18 + small sectors. On the other hand erasing should be faster when using 19 + 64 KiB block instead of 16 × 4 KiB sectors. 20 + 21 + Please note that some tools/drivers/filesystems may not work with 22 + 4096 B erase size (e.g. UBIFS requires 15 KiB as a minimum). 23 + 24 config SPI_FSL_QUADSPI 25 tristate "Freescale Quad SPI controller" 26 depends on ARCH_MXC
+4 -1
drivers/mtd/spi-nor/spi-nor.c
··· 1013 nor->wait_till_ready == spi_nor_wait_till_ready) 1014 nor->wait_till_ready = spi_nor_wait_till_fsr_ready; 1015 1016 /* prefer "small sector" erase if possible */ 1017 if (info->flags & SECT_4K) { 1018 nor->erase_opcode = SPINOR_OP_BE_4K; ··· 1021 } else if (info->flags & SECT_4K_PMC) { 1022 nor->erase_opcode = SPINOR_OP_BE_4K_PMC; 1023 mtd->erasesize = 4096; 1024 - } else { 1025 nor->erase_opcode = SPINOR_OP_SE; 1026 mtd->erasesize = info->sector_size; 1027 }
··· 1013 nor->wait_till_ready == spi_nor_wait_till_ready) 1014 nor->wait_till_ready = spi_nor_wait_till_fsr_ready; 1015 1016 + #ifdef CONFIG_MTD_SPI_NOR_USE_4K_SECTORS 1017 /* prefer "small sector" erase if possible */ 1018 if (info->flags & SECT_4K) { 1019 nor->erase_opcode = SPINOR_OP_BE_4K; ··· 1020 } else if (info->flags & SECT_4K_PMC) { 1021 nor->erase_opcode = SPINOR_OP_BE_4K_PMC; 1022 mtd->erasesize = 4096; 1023 + } else 1024 + #endif 1025 + { 1026 nor->erase_opcode = SPINOR_OP_SE; 1027 mtd->erasesize = info->sector_size; 1028 }