It turns out that most of the special status register handling is
specific for a particular vendor. I.e. Xilinx has some different
opcodes for the status register read, Micron has an additional FSR
register and Spansion has these flags integrated into the SR.
Create a callback to ready() where a flash chip can register its
own function. This will let us move all the vendor specific stuff
out of the core into the vendor modules.
As a preparation step, unify all function and object names in the
vendor modules. For the sake of consistency and better readability
of the code flow, I also converted the setup() callback to be
optional.
Please note that this is only compile-time tested.
Changes since v1:
- rename/unify function names inside the vendor modules.
- make local functions static
- fix function doc typo
- use late_init hook to set fsr_ready op
- Use uppercase and period in comments
- Add comments for the vendor flags
- move coding style change in spi_nor_sr_ready() into own patch
- new patch to add missing parenthesis in S3AN_INFO()
- add missing function prefix rename patch for the spansion module
Michael Walle (32):
mtd: spi-nor: atmel: unify function names
mtd: spi-nor: catalyst: unify function names
mtd: spi-nor: eon: unify function names
mtd: spi-nor: esmt: unify function names
mtd: spi-nor: everspin: unify function names
mtd: spi-nor: fujitsu: unify function names
mtd: spi-nor: gigadevice: unify function names
mtd: spi-nor: intel: unify function names
mtd: spi-nor: issi: unify function names
mtd: spi-nor: macronix: unify function names
mtd: spi-nor: micron-st: unify function names
mtd: spi-nor: spansion: unify function names
mtd: spi-nor: sst: unify function names
mtd: spi-nor: winbond: unify function names
mtd: spi-nor: xilinx: unify function names
mtd: spi-nor: xmc: unify function names
mtd: spi-nor: slightly refactor the spi_nor_setup()
mtd: spi-nor: allow a flash to define its own ready() function
mtd: spi-nor: export more function to be used in vendor modules
mtd: spi-nor: guard _page_size parameter in S3AN_INFO()
mtd: spi-nor: move all xilinx specifics into xilinx.c
mtd: spi-nor: xilinx: rename vendor specific functions and defines
mtd: spi-nor: xilinx: correct the debug message
mtd: spi-nor: move all micron-st specifics into micron-st.c
mtd: spi-nor: micron-st: convert USE_FSR to a manufacturer flag
mtd: spi-nor: micron-st: rename vendor specific functions and defines
mtd: spi-nor: spansion: slightly rework control flow in late_init()
mtd: spi-nor: move all spansion specifics into spansion.c
mtd: spi-nor: spansion: convert USE_CLSR to a manufacturer flag
mtd: spi-nor: spansion: rename vendor specific functions and defines
mtd: spi-nor: slightly change code style in spi_nor_sr_ready()
mtd: spi-nor: renumber flags
drivers/mtd/spi-nor/atmel.c | 81 +++++-----
drivers/mtd/spi-nor/catalyst.c | 6 +-
drivers/mtd/spi-nor/core.c | 265 ++-----------------------------
drivers/mtd/spi-nor/core.h | 70 ++++----
drivers/mtd/spi-nor/eon.c | 6 +-
drivers/mtd/spi-nor/esmt.c | 6 +-
drivers/mtd/spi-nor/everspin.c | 6 +-
drivers/mtd/spi-nor/fujitsu.c | 6 +-
drivers/mtd/spi-nor/gigadevice.c | 6 +-
drivers/mtd/spi-nor/intel.c | 6 +-
drivers/mtd/spi-nor/issi.c | 10 +-
drivers/mtd/spi-nor/macronix.c | 14 +-
drivers/mtd/spi-nor/micron-st.c | 258 ++++++++++++++++++++++++------
drivers/mtd/spi-nor/spansion.c | 154 +++++++++++++-----
drivers/mtd/spi-nor/sst.c | 20 +--
drivers/mtd/spi-nor/winbond.c | 26 +--
drivers/mtd/spi-nor/xilinx.c | 93 +++++++++--
drivers/mtd/spi-nor/xmc.c | 6 +-
include/linux/mtd/spi-nor.h | 18 ---
19 files changed, 555 insertions(+), 502 deletions(-)
--
2.30.2
To avoid name clashes unify all the function and static object names and
use one of the following prefixes which should be sufficiently unique:
- <vendor>_nor_
- <flash_family>_
- <flash_part>_
There are no functional changes.
Signed-off-by: Michael Walle <[email protected]>
---
drivers/mtd/spi-nor/everspin.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/mtd/spi-nor/everspin.c b/drivers/mtd/spi-nor/everspin.c
index f6c6fb36a428..84a07c2e0536 100644
--- a/drivers/mtd/spi-nor/everspin.c
+++ b/drivers/mtd/spi-nor/everspin.c
@@ -8,7 +8,7 @@
#include "core.h"
-static const struct flash_info everspin_parts[] = {
+static const struct flash_info everspin_nor_parts[] = {
/* Everspin */
{ "mr25h128", CAT25_INFO(16 * 1024, 1, 256, 2) },
{ "mr25h256", CAT25_INFO(32 * 1024, 1, 256, 2) },
@@ -18,6 +18,6 @@ static const struct flash_info everspin_parts[] = {
const struct spi_nor_manufacturer spi_nor_everspin = {
.name = "everspin",
- .parts = everspin_parts,
- .nparts = ARRAY_SIZE(everspin_parts),
+ .parts = everspin_nor_parts,
+ .nparts = ARRAY_SIZE(everspin_nor_parts),
};
--
2.30.2
As we have deleted some flag, lets renumber them so there are no holes.
Signed-off-by: Michael Walle <[email protected]>
Reviewed-by: Tudor Ambarus <[email protected]>
Reviewed-by: Pratyush Yadav <[email protected]>
---
drivers/mtd/spi-nor/core.h | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 2130a96e2044..b7fd760e3b47 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -12,20 +12,20 @@
#define SPI_NOR_MAX_ID_LEN 6
enum spi_nor_option_flags {
- SNOR_F_HAS_SR_TB = BIT(1),
- SNOR_F_NO_OP_CHIP_ERASE = BIT(2),
- SNOR_F_BROKEN_RESET = BIT(5),
- SNOR_F_4B_OPCODES = BIT(6),
- SNOR_F_HAS_4BAIT = BIT(7),
- SNOR_F_HAS_LOCK = BIT(8),
- SNOR_F_HAS_16BIT_SR = BIT(9),
- SNOR_F_NO_READ_CR = BIT(10),
- SNOR_F_HAS_SR_TB_BIT6 = BIT(11),
- SNOR_F_HAS_4BIT_BP = BIT(12),
- SNOR_F_HAS_SR_BP3_BIT6 = BIT(13),
- SNOR_F_IO_MODE_EN_VOLATILE = BIT(14),
- SNOR_F_SOFT_RESET = BIT(15),
- SNOR_F_SWP_IS_VOLATILE = BIT(16),
+ SNOR_F_HAS_SR_TB = BIT(0),
+ SNOR_F_NO_OP_CHIP_ERASE = BIT(1),
+ SNOR_F_BROKEN_RESET = BIT(2),
+ SNOR_F_4B_OPCODES = BIT(3),
+ SNOR_F_HAS_4BAIT = BIT(4),
+ SNOR_F_HAS_LOCK = BIT(5),
+ SNOR_F_HAS_16BIT_SR = BIT(6),
+ SNOR_F_NO_READ_CR = BIT(7),
+ SNOR_F_HAS_SR_TB_BIT6 = BIT(8),
+ SNOR_F_HAS_4BIT_BP = BIT(9),
+ SNOR_F_HAS_SR_BP3_BIT6 = BIT(10),
+ SNOR_F_IO_MODE_EN_VOLATILE = BIT(11),
+ SNOR_F_SOFT_RESET = BIT(12),
+ SNOR_F_SWP_IS_VOLATILE = BIT(13),
};
struct spi_nor_read_command {
--
2.30.2
To avoid name clashes unify all the function and static object names and
use one of the following prefixes which should be sufficiently unique:
- <vendor>_nor_
- <flash_family>_
- <flash_part>_
There are no functional changes.
Signed-off-by: Michael Walle <[email protected]>
---
drivers/mtd/spi-nor/atmel.c | 81 +++++++++++++++++++------------------
1 file changed, 42 insertions(+), 39 deletions(-)
diff --git a/drivers/mtd/spi-nor/atmel.c b/drivers/mtd/spi-nor/atmel.c
index d6d889ce8876..19fbad841e2f 100644
--- a/drivers/mtd/spi-nor/atmel.c
+++ b/drivers/mtd/spi-nor/atmel.c
@@ -16,12 +16,12 @@
* is to unlock the whole flash array on startup. Therefore, we have to support
* exactly this operation.
*/
-static int atmel_at25fs_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
+static int at25fs_lock(struct spi_nor *nor, loff_t ofs, uint64_t len)
{
return -EOPNOTSUPP;
}
-static int atmel_at25fs_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
+static int at25fs_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
{
int ret;
@@ -37,28 +37,28 @@ static int atmel_at25fs_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len)
return ret;
}
-static int atmel_at25fs_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len)
+static int at25fs_is_locked(struct spi_nor *nor, loff_t ofs, uint64_t len)
{
return -EOPNOTSUPP;
}
-static const struct spi_nor_locking_ops atmel_at25fs_locking_ops = {
- .lock = atmel_at25fs_lock,
- .unlock = atmel_at25fs_unlock,
- .is_locked = atmel_at25fs_is_locked,
+static const struct spi_nor_locking_ops at25fs_locking_ops = {
+ .lock = at25fs_lock,
+ .unlock = at25fs_unlock,
+ .is_locked = at25fs_is_locked,
};
-static void atmel_at25fs_late_init(struct spi_nor *nor)
+static void at25fs_late_init(struct spi_nor *nor)
{
- nor->params->locking_ops = &atmel_at25fs_locking_ops;
+ nor->params->locking_ops = &at25fs_locking_ops;
}
-static const struct spi_nor_fixups atmel_at25fs_fixups = {
- .late_init = atmel_at25fs_late_init,
+static const struct spi_nor_fixups at25fs_fixups = {
+ .late_init = at25fs_late_init,
};
/**
- * atmel_set_global_protection - Do a Global Protect or Unprotect command
+ * atmel_nor_set_global_protection - Do a Global Protect or Unprotect command
* @nor: pointer to 'struct spi_nor'
* @ofs: offset in bytes
* @len: len in bytes
@@ -66,8 +66,8 @@ static const struct spi_nor_fixups atmel_at25fs_fixups = {
*
* Return: 0 on success, -error otherwise.
*/
-static int atmel_set_global_protection(struct spi_nor *nor, loff_t ofs,
- uint64_t len, bool is_protect)
+static int atmel_nor_set_global_protection(struct spi_nor *nor, loff_t ofs,
+ uint64_t len, bool is_protect)
{
int ret;
u8 sr;
@@ -116,17 +116,20 @@ static int atmel_set_global_protection(struct spi_nor *nor, loff_t ofs,
return spi_nor_write_sr(nor, nor->bouncebuf, 1);
}
-static int atmel_global_protect(struct spi_nor *nor, loff_t ofs, uint64_t len)
+static int atmel_nor_global_protect(struct spi_nor *nor, loff_t ofs,
+ uint64_t len)
{
- return atmel_set_global_protection(nor, ofs, len, true);
+ return atmel_nor_set_global_protection(nor, ofs, len, true);
}
-static int atmel_global_unprotect(struct spi_nor *nor, loff_t ofs, uint64_t len)
+static int atmel_nor_global_unprotect(struct spi_nor *nor, loff_t ofs,
+ uint64_t len)
{
- return atmel_set_global_protection(nor, ofs, len, false);
+ return atmel_nor_set_global_protection(nor, ofs, len, false);
}
-static int atmel_is_global_protected(struct spi_nor *nor, loff_t ofs, uint64_t len)
+static int atmel_nor_is_global_protected(struct spi_nor *nor, loff_t ofs,
+ uint64_t len)
{
int ret;
@@ -140,47 +143,47 @@ static int atmel_is_global_protected(struct spi_nor *nor, loff_t ofs, uint64_t l
return ((nor->bouncebuf[0] & ATMEL_SR_GLOBAL_PROTECT_MASK) == ATMEL_SR_GLOBAL_PROTECT_MASK);
}
-static const struct spi_nor_locking_ops atmel_global_protection_ops = {
- .lock = atmel_global_protect,
- .unlock = atmel_global_unprotect,
- .is_locked = atmel_is_global_protected,
+static const struct spi_nor_locking_ops atmel_nor_global_protection_ops = {
+ .lock = atmel_nor_global_protect,
+ .unlock = atmel_nor_global_unprotect,
+ .is_locked = atmel_nor_is_global_protected,
};
-static void atmel_global_protection_late_init(struct spi_nor *nor)
+static void atmel_nor_global_protection_late_init(struct spi_nor *nor)
{
- nor->params->locking_ops = &atmel_global_protection_ops;
+ nor->params->locking_ops = &atmel_nor_global_protection_ops;
}
-static const struct spi_nor_fixups atmel_global_protection_fixups = {
- .late_init = atmel_global_protection_late_init,
+static const struct spi_nor_fixups atmel_nor_global_protection_fixups = {
+ .late_init = atmel_nor_global_protection_late_init,
};
-static const struct flash_info atmel_parts[] = {
+static const struct flash_info atmel_nor_parts[] = {
/* Atmel -- some are (confusingly) marketed as "DataFlash" */
{ "at25fs010", INFO(0x1f6601, 0, 32 * 1024, 4)
FLAGS(SPI_NOR_HAS_LOCK)
NO_SFDP_FLAGS(SECT_4K)
- .fixups = &atmel_at25fs_fixups },
+ .fixups = &at25fs_fixups },
{ "at25fs040", INFO(0x1f6604, 0, 64 * 1024, 8)
FLAGS(SPI_NOR_HAS_LOCK)
NO_SFDP_FLAGS(SECT_4K)
- .fixups = &atmel_at25fs_fixups },
+ .fixups = &at25fs_fixups },
{ "at25df041a", INFO(0x1f4401, 0, 64 * 1024, 8)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K)
- .fixups = &atmel_global_protection_fixups },
+ .fixups = &atmel_nor_global_protection_fixups },
{ "at25df321", INFO(0x1f4700, 0, 64 * 1024, 64)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K)
- .fixups = &atmel_global_protection_fixups },
+ .fixups = &atmel_nor_global_protection_fixups },
{ "at25df321a", INFO(0x1f4701, 0, 64 * 1024, 64)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K)
- .fixups = &atmel_global_protection_fixups },
+ .fixups = &atmel_nor_global_protection_fixups },
{ "at25df641", INFO(0x1f4800, 0, 64 * 1024, 128)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K)
- .fixups = &atmel_global_protection_fixups },
+ .fixups = &atmel_nor_global_protection_fixups },
{ "at25sl321", INFO(0x1f4216, 0, 64 * 1024, 64)
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "at26f004", INFO(0x1f0400, 0, 64 * 1024, 8)
@@ -188,21 +191,21 @@ static const struct flash_info atmel_parts[] = {
{ "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K)
- .fixups = &atmel_global_protection_fixups },
+ .fixups = &atmel_nor_global_protection_fixups },
{ "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K)
- .fixups = &atmel_global_protection_fixups },
+ .fixups = &atmel_nor_global_protection_fixups },
{ "at26df321", INFO(0x1f4700, 0, 64 * 1024, 64)
FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
NO_SFDP_FLAGS(SECT_4K)
- .fixups = &atmel_global_protection_fixups },
+ .fixups = &atmel_nor_global_protection_fixups },
{ "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16)
NO_SFDP_FLAGS(SECT_4K) },
};
const struct spi_nor_manufacturer spi_nor_atmel = {
.name = "atmel",
- .parts = atmel_parts,
- .nparts = ARRAY_SIZE(atmel_parts),
+ .parts = atmel_nor_parts,
+ .nparts = ARRAY_SIZE(atmel_nor_parts),
};
--
2.30.2
Xilinx and Micron flashes have their own implementation of the
spi_nor_ready() function. At the moment, the core will figure out
which one to call according to some flags. Lay the foundation to
make it possible that a flash can register its own ready()
function.
Signed-off-by: Michael Walle <[email protected]>
Reviewed-by: Tudor Ambarus <[email protected]>
Reviewed-by: Pratyush Yadav <[email protected]>
---
drivers/mtd/spi-nor/core.c | 4 ++++
drivers/mtd/spi-nor/core.h | 4 ++++
2 files changed, 8 insertions(+)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 4d2036cdce42..390a9ab413b7 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -794,6 +794,10 @@ static int spi_nor_ready(struct spi_nor *nor)
{
int sr, fsr;
+ /* Flashes might override the standard routine. */
+ if (nor->params->ready)
+ return nor->params->ready(nor);
+
if (nor->flags & SNOR_F_READY_XSR_RDY)
sr = spi_nor_xsr_ready(nor);
else
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 4fe16b5aa3f5..fdc8c0f31f5c 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -261,6 +261,9 @@ struct spi_nor_otp {
* SPI NOR flashes that have peculiarities to the SPI NOR
* standard e.g. different opcodes, specific address
* calculation, page size, etc.
+ * @ready: (optional) flashes might use a different mechanism
+ * than reading the status register to indicate they
+ * are ready for a new command
* @locking_ops: SPI NOR locking methods.
*/
struct spi_nor_flash_parameter {
@@ -282,6 +285,7 @@ struct spi_nor_flash_parameter {
int (*set_4byte_addr_mode)(struct spi_nor *nor, bool enable);
u32 (*convert_addr)(struct spi_nor *nor, u32 addr);
int (*setup)(struct spi_nor *nor, const struct spi_nor_hwcaps *hwcaps);
+ int (*ready)(struct spi_nor *nor);
const struct spi_nor_locking_ops *locking_ops;
};
--
2.30.2