[PATCH v2 00/35] mtd: spi-nor: Handle ID collisions and clean params init

STALE1768d

133 messages, 5 authors, 2021-11-06 · page 1 of 2 · open the first message on its own page

[PATCH v2 00/35] mtd: spi-nor: Handle ID collisions and clean params init

From: Tudor Ambarus <hidden>
Date: 2021-07-27 04:55:38

Handle flash ID collisions. Clean spi_nor_scan() and the flash
parameters initialization. Add guideliness on how to submit a new
flash proposal. An overview of the patch set can be seen in the
documentation patch, the last in the series.
Documentation/driver-api/mtd/spi-nor.rst is obsolete and must be
updated, but the series is getting big, and I though submitting
what I have to speed the review process. Will handle the documentation
afterwards.

Tested with sst26vf064b, w25q256jvm, is25lp256, s25fl256s0, gd25q256,
n25q256a and mx25l25635e.

Changes in v2: address Pratyush's comments on initial patch set.

Tudor Ambarus (35):
  mtd: spi-nor: core: Introduce SPI_NOR_PARSE_SFDP
  mtd: spi-nor: core: Report correct name in case of ID collisions
  mtd: spi-nor: macronix: Handle ID collision b/w MX25L3233F and
    MX25L3205D
  mtd: spi-nor: macronix: Handle ID collision b/w MX25L12805D and
    MX25L12835F
  mtd: spi-nor: Introduce Manufacturer ID collisions driver
  mtd: spi-nor: manuf-id-collisions: Add support for xt25f128b
  mtd: spi-nor: manuf-id-collisions: Add support for xm25qh64c
  mtd: spi-nor: core: Introduce the ate_init() hook
  mtd: spi-nor: atmel: Use flash late_init() for locking
  mtd: spi-nor: sst: Use flash late_init() for locking
  mtd: spi-nor: winbond: Use manufacturer late_init() for OTP ops
  mtd: spi-nor: xilinx: Use manufacturer late_init() to set setup method
  mtd: spi-nor: sst: Use manufacturer late_init() to set _write()
  mtd: spi-nor: spansion: Use manufacturer late_init()
  mtd: spi-nor: core: Call spi_nor_post_sfdp_fixups() only when SFDP is
    defined
  mtd: spi-nor: core: Mark default_init() as deprecated
  mtd: spi-nor: Introduce spi_nor_nonsfdp_flags_init()
  mtd: spi-nor: Get rid of SPI_NOR_4B_OPCODES flag
  mtd: spi-nor: Get rid of SPI_NOR_IO_MODE_EN_VOLATILE flag
  mtd: spi-nor: core: Use container_of to get the pointer to struct
    spi_nor
  mtd: spi-nor: Introduce spi_nor_set_mtd_info()
  mtd: spi-nor: core: Use common naming scheme for setting mtd_info
    fields
  mtd: spi-nor: Get rid of nor->page_size
  mtd: spi-nor: core: Fix spi_nor_flash_parameter otp description
  mtd: spi-nor: core: Move spi_nor_set_addr_width() in spi_nor_setup()
  mtd: spi-nor: core: Introduce spi_nor_init_default_params()
  mtd: spi-nor: core: Init flash params based on SFDP first for new
    flash additions
  mtd: spi-nor: sst: sst26vf064b: Use SPI_NOR_PARSE_SFDP
  mtd: spi-nor: winbond: w25q256jvm: Use SPI_NOR_PARSE_SFDP
  mtd: spi-nor: issi: is25lp256: Use SPI_NOR_PARSE_SFDP
  mtd: spi-nor: spansion: s25fl256s0: Skip SFDP parsing
  mtd: spi-nor: gigadevice: gd25q256: Use SPI_NOR_PARSE_SFDP
  mtd: spi-nor: micron-st: n25q256a: Use SPI_NOR_PARSE_SFDP
  mtd: spi-nor: macronix: mx25l25635e: Use SPI_NOR_PARSE_SFDP
  docs: mtd: spi-nor: Add details about how to propose a new flash
    addition

 Documentation/driver-api/mtd/spi-nor.rst  |  65 +++
 drivers/mtd/spi-nor/Makefile              |   1 +
 drivers/mtd/spi-nor/atmel.c               |  30 +-
 drivers/mtd/spi-nor/core.c                | 482 ++++++++++++----------
 drivers/mtd/spi-nor/core.h                |  60 +--
 drivers/mtd/spi-nor/gigadevice.c          |   6 +-
 drivers/mtd/spi-nor/issi.c                |  12 +-
 drivers/mtd/spi-nor/macronix.c            |  67 ++-
 drivers/mtd/spi-nor/manuf-id-collisions.c |  29 ++
 drivers/mtd/spi-nor/micron-st.c           |  34 +-
 drivers/mtd/spi-nor/otp.c                 |   2 +-
 drivers/mtd/spi-nor/spansion.c            |  24 +-
 drivers/mtd/spi-nor/sst.c                 |  19 +-
 drivers/mtd/spi-nor/swp.c                 |   2 +-
 drivers/mtd/spi-nor/sysfs.c               |   2 +-
 drivers/mtd/spi-nor/winbond.c             |  11 +-
 drivers/mtd/spi-nor/xilinx.c              |  25 +-
 include/linux/mtd/spi-nor.h               |   4 +-
 18 files changed, 539 insertions(+), 336 deletions(-)
 create mode 100644 drivers/mtd/spi-nor/manuf-id-collisions.c

-- 
2.25.1


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

[PATCH v2 01/35] mtd: spi-nor: core: Introduce SPI_NOR_PARSE_SFDP

From: Tudor Ambarus <hidden>
Date: 2021-07-27 04:56:54

SPI NOR flashes that statically declare one of the
SPI_NOR_{DUAL, QUAD, OCTAL, OCTAL_DTR}_READ flags and do not support
the RDSFDP command are gratuiously receiving the RDSFDP command
in the attempt of parsing the SFDP tables. It is not desirable to issue
commands that are not supported, so introduce a flag to help on this
situation.

New flash additions that support the SFDP standard should be declared
using SPI_NOR_PARSE_SFDP. Support that can be discovered when parsing
SFDP should not be duplicated by explicit flags at flash declaration.
All the flash parameters will be discovered when parsing SFDP.
Sometimes manufacturers wrongly define some fields in the SFDP tables.
If that's the case, SFDP data can be amended with the fixups() hooks.
It is not common, but if the SFDP tables are entirely wrong, and it
does not worth the hassle to tweak the SFDP parameters by using the
fixups hooks, or if the flash does not define the SFDP tables at all,
then statically init the flash with the SPI_NOR_SKIP_SFDP flag and
specify the rest of flash capabilities with the flash info flags.

With time, we want to convert all flashes to SPI_NOR_PARSE_SFDP and
stop triggering the SFDP parsing with the
SPI_NOR_{DUAL, QUAD, OCTAL*}_READ flags. Getting rid of the
SPI_NOR_{OCTAL, OCTAL_DTR}_READ trigger is easily achievable, the rest
are a long term goal.

Signed-off-by: Tudor Ambarus <redacted>
Reviewed-by: Heiko Thiery <redacted>
---
 drivers/mtd/spi-nor/core.c | 3 ++-
 drivers/mtd/spi-nor/core.h | 4 ++++
 2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index cc08bd707378..3d9f3698fb7b 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2726,7 +2726,8 @@ static int spi_nor_init_params(struct spi_nor *nor)
 
 	spi_nor_manufacturer_init_params(nor);
 
-	if ((nor->info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+	if ((nor->info->flags & (SPI_NOR_PARSE_SFDP |
+				 SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 				 SPI_NOR_OCTAL_READ | SPI_NOR_OCTAL_DTR_READ)) &&
 	    !(nor->info->flags & SPI_NOR_SKIP_SFDP))
 		spi_nor_sfdp_init_params(nor);
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 3348e1dd1445..55fceb0ec894 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -382,6 +382,10 @@ struct flash_info {
 					 * protection bits. Usually these will
 					 * power-up in a write-protected state.
 					 */
+#define SPI_NOR_PARSE_SFDP	BIT(23) /*
+					 * Flash initialized based on the SFDP
+					 * tables.
+					 */
 
 	const struct spi_nor_otp_organization otp_org;
 
-- 
2.25.1


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

[PATCH v2 02/35] mtd: spi-nor: core: Report correct name in case of ID collisions

From: Tudor Ambarus <hidden>
Date: 2021-07-27 04:58:17

Provide a way to report the correct flash name in case of ID collisions.
There will be a single flash_info entry when flash IDs collide, and the
differentiation between the flash types will be made at runtime
if possible.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c  | 7 +++++--
 drivers/mtd/spi-nor/sysfs.c | 2 +-
 include/linux/mtd/spi-nor.h | 2 ++
 3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 3d9f3698fb7b..1a278d33b02d 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -3027,7 +3027,7 @@ static void spi_nor_debugfs_init(struct spi_nor *nor,
 {
 	struct mtd_info *mtd = &nor->mtd;
 
-	mtd->dbg.partname = info->name;
+	mtd->dbg.partname = nor->name;
 	mtd->dbg.partid = devm_kasprintf(nor->dev, GFP_KERNEL, "spi-nor:%*phN",
 					 info->id_len, info->id);
 }
@@ -3208,7 +3208,10 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 	/* Configure OTP parameters and ops */
 	spi_nor_otp_init(nor);
 
-	dev_info(dev, "%s (%lld Kbytes)\n", info->name,
+	if (!nor->name)
+		nor->name = info->name;
+
+	dev_info(dev, "%s (%lld Kbytes)\n", nor->name,
 			(long long)mtd->size >> 10);
 
 	dev_dbg(dev,
diff --git a/drivers/mtd/spi-nor/sysfs.c b/drivers/mtd/spi-nor/sysfs.c
index 9aec9d8a98ad..017119768f32 100644
--- a/drivers/mtd/spi-nor/sysfs.c
+++ b/drivers/mtd/spi-nor/sysfs.c
@@ -25,7 +25,7 @@ static ssize_t partname_show(struct device *dev,
 	struct spi_mem *spimem = spi_get_drvdata(spi);
 	struct spi_nor *nor = spi_mem_get_drvdata(spimem);
 
-	return sysfs_emit(buf, "%s\n", nor->info->name);
+	return sysfs_emit(buf, "%s\n", nor->name);
 }
 static DEVICE_ATTR_RO(partname);
 
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index f67457748ed8..bd92acdd1899 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -369,6 +369,7 @@ struct spi_nor_flash_parameter;
  * @bouncebuf:		bounce buffer used when the buffer passed by the MTD
  *                      layer is not DMA-able
  * @bouncebuf_size:	size of the bounce buffer
+ * @name:		used to point to correct name in case of ID collisions.
  * @info:		SPI NOR part JEDEC MFR ID and other info
  * @manufacturer:	SPI NOR manufacturer
  * @page_size:		the page size of the SPI NOR
@@ -399,6 +400,7 @@ struct spi_nor {
 	struct spi_mem		*spimem;
 	u8			*bouncebuf;
 	size_t			bouncebuf_size;
+	const char *name;
 	const struct flash_info	*info;
 	const struct spi_nor_manufacturer *manufacturer;
 	u32			page_size;
-- 
2.25.1


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

[PATCH v2 03/35] mtd: spi-nor: macronix: Handle ID collision b/w MX25L3233F and MX25L3205D

From: Tudor Ambarus <hidden>
Date: 2021-07-27 04:59:43

Macronix has a bad habbit of reusing flash IDs. While MX25L3233F supports
RDSFDP opcode, MX25L3205D does not support it and does not recommend
issuing opcodes that are not supported ("It is not recommended to adopt
any other code not in the command definition table, which will potentially
enter the hidden mode.").

We tested the RDSFDP on the MX25L3205D and the conclusion is that the
flash didn't reply anything. Given that it is unlikely that RDSFDP will
cause any problems for the old MX25L3205D, differentiate between the two
flashes by parsing SFDP.

Tested MX25L3233F. Generated a 256 Kbyte random data and did an erase,
write, read back and compare test. The flash uses for reads
SPINOR_OP_READ_1_4_4 0xeb, for erases SPINOR_OP_BE_4K 0x20, and for writes
SPINOR_OP_PP 0x02.

Signed-off-by: Tudor Ambarus <redacted>
Acked-by: Pratyush Yadav <redacted>
---
root@sama5d2-xplained:~# find / -iname spi-nor
/sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor
/sys/devices/platform/ahb/ahb:apb/f8000000.spi/spi_master/spi0/spi0.0/spi-nor
/sys/bus/spi/drivers/spi-nor
root@sama5d2-xplained:~# ls -al /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor
total 0
drwxr-xr-x 2 root root    0 Mar  9 14:51 .
drwxr-xr-x 6 root root    0 Mar  9 14:50 ..
-r--r--r-- 1 root root 4096 Mar  9 14:51 jedec_id
-r--r--r-- 1 root root 4096 Mar  9 14:51 manufacturer
-r--r--r-- 1 root root 4096 Mar  9 14:51 partname
-r--r--r-- 1 root root    0 Mar  9 14:51 sfdp
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/jedec_id
c22016
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/manufacturer
macronix
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/partname
mx25l3233f
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/sfdp > mx25l3233f-sfdp
root@sama5d2-xplained:~# hexdump mx25l3233f-sfdp
0000000 4653 5044 0100 ff01 0000 0901 0030 ff00
0000010 00c2 0401 0060 ff00 ffff ffff ffff ffff
0000020 ffff ffff ffff ffff ffff ffff ffff ffff
0000030 20e5 fff1 ffff 01ff eb44 6b08 3b08 bb04
0000040 ffee ffff ffff ff00 ffff ff00 200c 520f
0000050 d810 ff00 ffff ffff ffff ffff ffff ffff
0000060 3600 2650 f99c 6477 cffe ffff ffff ffff
0000070

 drivers/mtd/spi-nor/macronix.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c
index 27498ed0cc0d..68f6ac060bc6 100644
--- a/drivers/mtd/spi-nor/macronix.c
+++ b/drivers/mtd/spi-nor/macronix.c
@@ -8,6 +8,24 @@
 
 #include "core.h"
 
+static int mx25l3233f_post_bfpt_fixups(struct spi_nor *nor,
+				const struct sfdp_parameter_header *bfpt_header,
+				const struct sfdp_bfpt *bfpt)
+{
+	/*
+	 * Macronix has a bad habit of reusing flash IDs: MX25L3233F collides
+	 * with MX25L3205D. MX25L3233F defines SFDP tables, while the older
+	 * variant does not.
+	 */
+	nor->name = "mx25l3233f";
+
+	return 0;
+}
+
+static struct spi_nor_fixups mx25l3233f_fixups = {
+	.post_bfpt = mx25l3233f_post_bfpt_fixups,
+};
+
 static int
 mx25l25635_post_bfpt_fixups(struct spi_nor *nor,
 			    const struct sfdp_parameter_header *bfpt_header,
@@ -39,7 +57,10 @@ static const struct flash_info macronix_parts[] = {
 	{ "mx25l4005a",  INFO(0xc22013, 0, 64 * 1024,   8, SECT_4K) },
 	{ "mx25l8005",   INFO(0xc22014, 0, 64 * 1024,  16, 0) },
 	{ "mx25l1606e",  INFO(0xc22015, 0, 64 * 1024,  32, SECT_4K) },
-	{ "mx25l3205d",  INFO(0xc22016, 0, 64 * 1024,  64, SECT_4K) },
+	{ "mx25l3205d",  INFO(0xc22016, 0, 64 * 1024,  64, SPI_NOR_PARSE_SFDP |
+			      SECT_4K)
+		/* ID collision with mx25l3233f. */
+		.fixups = &mx25l3233f_fixups },
 	{ "mx25l3255e",  INFO(0xc29e16, 0, 64 * 1024,  64, SECT_4K) },
 	{ "mx25l6405d",  INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) },
 	{ "mx25u2033e",  INFO(0xc22532, 0, 64 * 1024,   4, SECT_4K) },
-- 
2.25.1


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

[PATCH v2 04/35] mtd: spi-nor: macronix: Handle ID collision b/w MX25L12805D and MX25L12835F

From: Tudor Ambarus <hidden>
Date: 2021-07-27 05:01:43

MX25L12835F define SFDP, while MX25L12805D does not.

Signed-off-by: Tudor Ambarus <redacted>
Testd-by: Heiko Thiery [off-list ref]
Acked-by: Pratyush Yadav <redacted>
---

# cat /sys/devices/platform/soc@0/30800000.bus/30bb0000.spi/spi_master/spi0/spi0
.0/spi-nor/sfdp | xxd -p
53464450000101ff00000109300000ffc2000104600000ffffffffffffff
ffffffffffffffffffffffffffffffffffffe520f1ffffffff0744eb086b
083b04bbfeffffffffff00ffffff44eb0c200f5210d800ffffffffffffff
ffffffffffff003600279df9c06485cbffffffffffff

 drivers/mtd/spi-nor/macronix.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c
index 68f6ac060bc6..fba85efafb47 100644
--- a/drivers/mtd/spi-nor/macronix.c
+++ b/drivers/mtd/spi-nor/macronix.c
@@ -8,6 +8,24 @@
 
 #include "core.h"
 
+static int mx25l12835f_post_bfpt_fixups(struct spi_nor *nor,
+				const struct sfdp_parameter_header *bfpt_header,
+				const struct sfdp_bfpt *bfpt)
+{
+	/*
+	 * Macronix has a bad habit of reusing flash IDs: MX25L12835F collides
+	 * with MX25L12805D. MX25L12835F defines SFDP tables, while the older
+	 * variant does not.
+	 */
+	nor->name = "mx25l12835f";
+
+	return 0;
+}
+
+static struct spi_nor_fixups mx25l12835f_fixups = {
+	.post_bfpt = mx25l12835f_post_bfpt_fixups,
+};
+
 static int mx25l3233f_post_bfpt_fixups(struct spi_nor *nor,
 				const struct sfdp_parameter_header *bfpt_header,
 				const struct sfdp_bfpt *bfpt)
@@ -70,8 +88,10 @@ static const struct flash_info macronix_parts[] = {
 	{ "mx25u4035",   INFO(0xc22533, 0, 64 * 1024,   8, SECT_4K) },
 	{ "mx25u8035",   INFO(0xc22534, 0, 64 * 1024,  16, SECT_4K) },
 	{ "mx25u6435f",  INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) },
-	{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, SECT_4K |
-			      SPI_NOR_HAS_LOCK | SPI_NOR_4BIT_BP) },
+	{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, SPI_NOR_PARSE_SFDP |
+			      SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_4BIT_BP)
+		/* ID collision with mx25l12835f. */
+		.fixups = &mx25l12835f_fixups },
 	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
 	{ "mx25r1635f",  INFO(0xc22815, 0, 64 * 1024,  32,
 			      SECT_4K | SPI_NOR_DUAL_READ |
-- 
2.25.1


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

[PATCH v2 05/35] mtd: spi-nor: Introduce Manufacturer ID collisions driver

From: Tudor Ambarus <hidden>
Date: 2021-07-27 05:03:58

Some manufacturers completely ignore the manufacturer's identification code
standard (JEP106) and do not define the manufacturer ID continuation
scheme. This will result in manufacturer ID collisions.

An an example, JEP106BA requires Boya that it's manufacturer ID to be
preceded by 8 continuation codes. Boya's identification code must be:
0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x68. But Boya ignores the
continuation scheme and its ID collides with the manufacturer defined in
bank one: Convex Computer.

Introduce the manuf-id-collisions driver in order to address ID collisions
between manufacturers. flash_info entries will be added in a first come,
first served manner. Differentiation between flashes will be done at
runtime if possible. Where runtime differentiation is not possible, new
compatibles will be introduced, but this will be done as a last resort.
Every new flash addition that define the SFDP tables, should dump its SFDP
tables in the patch's comment section below the --- line, so that we can
reference it in case of collisions.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/Makefile              |  1 +
 drivers/mtd/spi-nor/core.c                |  1 +
 drivers/mtd/spi-nor/core.h                |  1 +
 drivers/mtd/spi-nor/manuf-id-collisions.c | 22 ++++++++++++++++++++++
 4 files changed, 25 insertions(+)
 create mode 100644 drivers/mtd/spi-nor/manuf-id-collisions.c
diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile
index 6b904e439372..48763d10daad 100644
--- a/drivers/mtd/spi-nor/Makefile
+++ b/drivers/mtd/spi-nor/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 
 spi-nor-objs			:= core.o sfdp.o swp.o otp.o sysfs.o
+spi-nor-objs			+= manuf-id-collisions.o
 spi-nor-objs			+= atmel.o
 spi-nor-objs			+= catalyst.o
 spi-nor-objs			+= eon.o
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 1a278d33b02d..d30c8f350dc1 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -1829,6 +1829,7 @@ int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor)
 }
 
 static const struct spi_nor_manufacturer *manufacturers[] = {
+	&spi_nor_manuf_id_collisions,
 	&spi_nor_atmel,
 	&spi_nor_catalyst,
 	&spi_nor_eon,
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 55fceb0ec894..e9896cd60695 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -476,6 +476,7 @@ struct sfdp {
 };
 
 /* Manufacturer drivers. */
+extern const struct spi_nor_manufacturer spi_nor_manuf_id_collisions;
 extern const struct spi_nor_manufacturer spi_nor_atmel;
 extern const struct spi_nor_manufacturer spi_nor_catalyst;
 extern const struct spi_nor_manufacturer spi_nor_eon;
diff --git a/drivers/mtd/spi-nor/manuf-id-collisions.c b/drivers/mtd/spi-nor/manuf-id-collisions.c
new file mode 100644
index 000000000000..bf7dba34f018
--- /dev/null
+++ b/drivers/mtd/spi-nor/manuf-id-collisions.c
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Used to handle collisions between manufacturers, where manufacturers are
+ * ignorant enough to not implement the ID continuation scheme described in the
+ * JEP106 JEDEC standard.
+ */
+
+#include <linux/mtd/spi-nor.h>
+#include "core.h"
+
+static const struct flash_info id_collision_parts[] = {
+	/* Boya */
+	{ "by25q128as", INFO(0x684018, 0, 64 * 1024, 256, SPI_NOR_SKIP_SFDP |
+			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+			     SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
+};
+
+const struct spi_nor_manufacturer spi_nor_manuf_id_collisions = {
+	.name = "manufacturer ID collisions",
+	.parts = id_collision_parts,
+	.nparts = ARRAY_SIZE(id_collision_parts),
+};
-- 
2.25.1


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

[PATCH v2 06/35] mtd: spi-nor: manuf-id-collisions: Add support for xt25f128b

From: Tudor Ambarus <hidden>
Date: 2021-07-27 05:06:19

Flash does not support continuation codes and may collide with a flash
of other manufacturer, Intersil being an example .

Signed-off-by: Tudor Ambarus <redacted>
---
0000000 4653 5044 0100 ff01 0000 0901 0030 ff00
0000010 000b 0301 0060 ff00 ffff ffff ffff ffff
0000020 ffff ffff ffff ffff ffff ffff ffff ffff
0000030 20e5 fff1 ffff 07ff eb44 6b08 3b08 bb42
0000040 ffee ffff ffff ff00 ffff ff00 200c 520f
0000050 d810 ff00 ffff ffff ffff ffff ffff ffff
0000060 3600 2700 f99f 6477 e8d9 ffff

 drivers/mtd/spi-nor/manuf-id-collisions.c | 4 ++++
 1 file changed, 4 insertions(+)
diff --git a/drivers/mtd/spi-nor/manuf-id-collisions.c b/drivers/mtd/spi-nor/manuf-id-collisions.c
index bf7dba34f018..db31470ebf6a 100644
--- a/drivers/mtd/spi-nor/manuf-id-collisions.c
+++ b/drivers/mtd/spi-nor/manuf-id-collisions.c
@@ -13,6 +13,10 @@ static const struct flash_info id_collision_parts[] = {
 	{ "by25q128as", INFO(0x684018, 0, 64 * 1024, 256, SPI_NOR_SKIP_SFDP |
 			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			     SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
+
+	/* XTX (XTX Technology Limited) */
+	{ "xt25f128b", INFO(0x0b4018, 0, 64 * 1024, 256, SPI_NOR_PARSE_SFDP |
+			    SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
 };
 
 const struct spi_nor_manufacturer spi_nor_manuf_id_collisions = {
-- 
2.25.1


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

[PATCH v2 07/35] mtd: spi-nor: manuf-id-collisions: Add support for xm25qh64c

From: Tudor Ambarus <hidden>
Date: 2021-07-27 05:09:35

Flash ignores the manufacturer continuation codes and is likely to
collide with other manufacturers flashes.

Signed-off-by: Tudor Ambarus <redacted>
---
Do not apply without the SFDP tables hexdump.

 drivers/mtd/spi-nor/manuf-id-collisions.c | 3 +++
 1 file changed, 3 insertions(+)
diff --git a/drivers/mtd/spi-nor/manuf-id-collisions.c b/drivers/mtd/spi-nor/manuf-id-collisions.c
index db31470ebf6a..f3ba00d17c68 100644
--- a/drivers/mtd/spi-nor/manuf-id-collisions.c
+++ b/drivers/mtd/spi-nor/manuf-id-collisions.c
@@ -14,6 +14,9 @@ static const struct flash_info id_collision_parts[] = {
 			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			     SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
 
+	/* XMC (Wuhan Xinxin Semiconductor Manufacturing Corp.) */
+	{ "xm25qh64c", INFO(0x204017, 0, 64 * 1024, 128, SPI_NOR_PARSE_SFDP) },
+
 	/* XTX (XTX Technology Limited) */
 	{ "xt25f128b", INFO(0x0b4018, 0, 64 * 1024, 256, SPI_NOR_PARSE_SFDP |
 			    SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
-- 
2.25.1


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

[PATCH v2 08/35] mtd: spi-nor: core: Introduce the ate_init() hook

From: Tudor Ambarus <hidden>
Date: 2021-07-27 05:13:08

The goal is to get rid of the spaghetti way of initializing the flash
parameters and settings. late_init() hook will be used to tweak various
parameters that are not defined by the SFDP standard. Can be used by
non SFDP compliant flashes in order to tweak flash parameters that
are not/shouldn't be handled by the flash_info flags. Will replace the
default_init() hook.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c | 15 +++++++++++----
 drivers/mtd/spi-nor/core.h |  8 ++++++++
 2 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index d30c8f350dc1..15ccc9994215 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2667,11 +2667,18 @@ static void spi_nor_post_sfdp_fixups(struct spi_nor *nor)
  * spi_nor_late_init_params() - Late initialization of default flash parameters.
  * @nor:	pointer to a 'struct spi_nor'
  *
- * Used to set default flash parameters and settings when the ->default_init()
- * hook or the SFDP parser let voids.
+ * Used to tweak various flash parameters that are not defined by the SFDP
+ * standard. Can be used by non SFDP compliant flashes in order to tweek flash
+ * parameters that are not handled by the flash_info flags.
  */
 static void spi_nor_late_init_params(struct spi_nor *nor)
 {
+	if (nor->manufacturer && nor->manufacturer->late_init)
+		nor->manufacturer->late_init(nor);
+
+	if (nor->info->late_init)
+		nor->info->late_init(nor);
+
 	/*
 	 * NOR protection support. When locking_ops are not provided, we pick
 	 * the default ones.
@@ -2713,8 +2720,8 @@ static void spi_nor_late_init_params(struct spi_nor *nor)
  *    wrong).
  *		spi_nor_post_sfdp_fixups()
  *
- * 5/ Late default flash parameters initialization, used when the
- * ->default_init() hook or the SFDP parser do not set specific params.
+ * 5/ Late flash parameters initialization, used to initialize flash
+ * parameters that are not declared in the JESD216 SFDP standard.
  *		spi_nor_late_init_params()
  */
 static int spi_nor_init_params(struct spi_nor *nor)
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index e9896cd60695..13d5c5edfd27 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -391,6 +391,11 @@ struct flash_info {
 
 	/* Part specific fixup hooks. */
 	const struct spi_nor_fixups *fixups;
+	/*
+	 * Init flash parameters that are not declared in the JESD216 SFDP
+	 * standard.
+	 */
+	void (* const late_init)(struct spi_nor *nor);
 };
 
 /* Used when the "_ext_id" is two bytes at most */
@@ -457,12 +462,15 @@ struct flash_info {
  * @parts: array of parts supported by this manufacturer
  * @nparts: number of entries in the parts array
  * @fixups: hooks called at various points in time during spi_nor_scan()
+ * @late_init: used to init flash parameters that are not declared in the
+ *             JESD216 SFDP standard.
  */
 struct spi_nor_manufacturer {
 	const char *name;
 	const struct flash_info *parts;
 	unsigned int nparts;
 	const struct spi_nor_fixups *fixups;
+	void (* const late_init)(struct spi_nor *nor);
 };
 
 /**
-- 
2.25.1


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

[PATCH v2 09/35] mtd: spi-nor: atmel: Use flash late_init() for locking

From: Tudor Ambarus <hidden>
Date: 2021-07-27 05:16:36

Locking is not described in JESD216 SFDP standard, place the locking
init in late_init().

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/atmel.c | 30 +++++++++++-------------------
 1 file changed, 11 insertions(+), 19 deletions(-)
diff --git a/drivers/mtd/spi-nor/atmel.c b/drivers/mtd/spi-nor/atmel.c
index 1fea5cab492c..b937ef734e55 100644
--- a/drivers/mtd/spi-nor/atmel.c
+++ b/drivers/mtd/spi-nor/atmel.c
@@ -48,15 +48,11 @@ static const struct spi_nor_locking_ops atmel_at25fs_locking_ops = {
 	.is_locked = atmel_at25fs_is_locked,
 };
 
-static void atmel_at25fs_default_init(struct spi_nor *nor)
+static void atmel_at25fs_late_init(struct spi_nor *nor)
 {
 	nor->params->locking_ops = &atmel_at25fs_locking_ops;
 }
 
-static const struct spi_nor_fixups atmel_at25fs_fixups = {
-	.default_init = atmel_at25fs_default_init,
-};
-
 /**
  * atmel_set_global_protection - Do a Global Protect or Unprotect command
  * @nor:	pointer to 'struct spi_nor'
@@ -146,34 +142,30 @@ static const struct spi_nor_locking_ops atmel_global_protection_ops = {
 	.is_locked = atmel_is_global_protected,
 };
 
-static void atmel_global_protection_default_init(struct spi_nor *nor)
+static void atmel_global_protection_late_init(struct spi_nor *nor)
 {
 	nor->params->locking_ops = &atmel_global_protection_ops;
 }
 
-static const struct spi_nor_fixups atmel_global_protection_fixups = {
-	.default_init = atmel_global_protection_default_init,
-};
-
 static const struct flash_info atmel_parts[] = {
 	/* Atmel -- some are (confusingly) marketed as "DataFlash" */
 	{ "at25fs010",  INFO(0x1f6601, 0, 32 * 1024,   4, SECT_4K | SPI_NOR_HAS_LOCK)
-		.fixups = &atmel_at25fs_fixups },
+		.late_init = atmel_at25fs_late_init },
 	{ "at25fs040",  INFO(0x1f6604, 0, 64 * 1024,   8, SECT_4K | SPI_NOR_HAS_LOCK)
-		.fixups = &atmel_at25fs_fixups },
+		.late_init = atmel_at25fs_late_init },
 
 	{ "at25df041a", INFO(0x1f4401, 0, 64 * 1024,   8,
 			     SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
-			.fixups = &atmel_global_protection_fixups },
+		.late_init = atmel_global_protection_late_init },
 	{ "at25df321",  INFO(0x1f4700, 0, 64 * 1024,  64,
 			     SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
-			.fixups = &atmel_global_protection_fixups },
+		.late_init = atmel_global_protection_late_init },
 	{ "at25df321a", INFO(0x1f4701, 0, 64 * 1024,  64,
 			     SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
-			.fixups = &atmel_global_protection_fixups },
+		.late_init = atmel_global_protection_late_init },
 	{ "at25df641",  INFO(0x1f4800, 0, 64 * 1024, 128,
 			     SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
-			.fixups = &atmel_global_protection_fixups },
+		.late_init = atmel_global_protection_late_init },
 
 	{ "at25sl321",	INFO(0x1f4216, 0, 64 * 1024, 64,
 			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
@@ -181,13 +173,13 @@ static const struct flash_info atmel_parts[] = {
 	{ "at26f004",   INFO(0x1f0400, 0, 64 * 1024,  8, SECT_4K) },
 	{ "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16,
 			     SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
-			.fixups = &atmel_global_protection_fixups },
+		.late_init = atmel_global_protection_late_init },
 	{ "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32,
 			     SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
-			.fixups = &atmel_global_protection_fixups },
+		.late_init = atmel_global_protection_late_init },
 	{ "at26df321",  INFO(0x1f4700, 0, 64 * 1024, 64,
 			     SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
-			.fixups = &atmel_global_protection_fixups },
+		.late_init = atmel_global_protection_late_init },
 
 	{ "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) },
 };
-- 
2.25.1


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

[PATCH v2 10/35] mtd: spi-nor: sst: Use flash late_init() for locking

From: Tudor Ambarus <hidden>
Date: 2021-07-27 05:20:01

Locking ops are not discoverable via SFDP, use late_init() call.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/sst.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/mtd/spi-nor/sst.c b/drivers/mtd/spi-nor/sst.c
index 980f4c09c91d..29d100febdbf 100644
--- a/drivers/mtd/spi-nor/sst.c
+++ b/drivers/mtd/spi-nor/sst.c
@@ -46,15 +46,11 @@ static const struct spi_nor_locking_ops sst26vf_locking_ops = {
 	.is_locked = sst26vf_is_locked,
 };
 
-static void sst26vf_default_init(struct spi_nor *nor)
+static void sst26vf_late_init(struct spi_nor *nor)
 {
 	nor->params->locking_ops = &sst26vf_locking_ops;
 }
 
-static const struct spi_nor_fixups sst26vf_fixups = {
-	.default_init = sst26vf_default_init,
-};
-
 static const struct flash_info sst_parts[] = {
 	/* SST -- large erase sizes are "overlays", "sectors" are 4K */
 	{ "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024,  8,
@@ -88,7 +84,7 @@ static const struct flash_info sst_parts[] = {
 	{ "sst26vf064b", INFO(0xbf2643, 0, 64 * 1024, 128,
 			      SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			      SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
-		.fixups = &sst26vf_fixups },
+		.late_init = sst26vf_late_init},
 };
 
 static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
-- 
2.25.1


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

[PATCH v2 11/35] mtd: spi-nor: winbond: Use manufacturer late_init() for OTP ops

From: Tudor Ambarus <hidden>
Date: 2021-07-27 05:24:13

OTP info is not yet discoverable via SFDP, use late_init() to init
the OTP ops.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/winbond.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c
index 96573f61caf5..6be45d2291c6 100644
--- a/drivers/mtd/spi-nor/winbond.c
+++ b/drivers/mtd/spi-nor/winbond.c
@@ -147,17 +147,22 @@ static const struct spi_nor_otp_ops winbond_otp_ops = {
 static void winbond_default_init(struct spi_nor *nor)
 {
 	nor->params->set_4byte_addr_mode = winbond_set_4byte_addr_mode;
-	if (nor->params->otp.org->n_regions)
-		nor->params->otp.ops = &winbond_otp_ops;
 }
 
 static const struct spi_nor_fixups winbond_fixups = {
 	.default_init = winbond_default_init,
 };
 
+static void winbond_late_init(struct spi_nor *nor)
+{
+	if (nor->params->otp.org->n_regions)
+		nor->params->otp.ops = &winbond_otp_ops;
+}
+
 const struct spi_nor_manufacturer spi_nor_winbond = {
 	.name = "winbond",
 	.parts = winbond_parts,
 	.nparts = ARRAY_SIZE(winbond_parts),
 	.fixups = &winbond_fixups,
+	.late_init = winbond_late_init,
 };
-- 
2.25.1


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

[PATCH v2 12/35] mtd: spi-nor: xilinx: Use manufacturer late_init() to set setup method

From: Tudor Ambarus <hidden>
Date: 2021-07-27 05:28:11

post_sfdp was misleading in this case, as SFDP is not supported by
xilinx. Plus, there's no fixup here, just setting the correct
setup method, as required by xilinx parts.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/xilinx.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/mtd/spi-nor/xilinx.c b/drivers/mtd/spi-nor/xilinx.c
index 1138bdbf4199..a573c3cde414 100644
--- a/drivers/mtd/spi-nor/xilinx.c
+++ b/drivers/mtd/spi-nor/xilinx.c
@@ -77,18 +77,14 @@ static int xilinx_nor_setup(struct spi_nor *nor,
 	return 0;
 }
 
-static void xilinx_post_sfdp_fixups(struct spi_nor *nor)
+static void xilinx_late_init(struct spi_nor *nor)
 {
 	nor->params->setup = xilinx_nor_setup;
 }
 
-static const struct spi_nor_fixups xilinx_fixups = {
-	.post_sfdp = xilinx_post_sfdp_fixups,
-};
-
 const struct spi_nor_manufacturer spi_nor_xilinx = {
 	.name = "xilinx",
 	.parts = xilinx_parts,
 	.nparts = ARRAY_SIZE(xilinx_parts),
-	.fixups = &xilinx_fixups,
+	.late_init = xilinx_late_init,
 };
-- 
2.25.1


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

[PATCH v2 13/35] mtd: spi-nor: sst: Use manufacturer late_init() to set _write()

From: Tudor Ambarus <hidden>
Date: 2021-07-27 05:32:37

Setting the correct nor->mtd._write in a fixup hook was misleading,
since this is not a fixup, just a specific setting for SST, that differs
from the SPI NOR core default init.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/sst.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/mtd/spi-nor/sst.c b/drivers/mtd/spi-nor/sst.c
index 29d100febdbf..eeb10766b70e 100644
--- a/drivers/mtd/spi-nor/sst.c
+++ b/drivers/mtd/spi-nor/sst.c
@@ -173,19 +173,15 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 	return ret;
 }
 
-static void sst_post_sfdp_fixups(struct spi_nor *nor)
+static void sst_late_init(struct spi_nor *nor)
 {
 	if (nor->info->flags & SST_WRITE)
 		nor->mtd._write = sst_write;
 }
 
-static const struct spi_nor_fixups sst_fixups = {
-	.post_sfdp = sst_post_sfdp_fixups,
-};
-
 const struct spi_nor_manufacturer spi_nor_sst = {
 	.name = "sst",
 	.parts = sst_parts,
 	.nparts = ARRAY_SIZE(sst_parts),
-	.fixups = &sst_fixups,
+	.late_init = sst_late_init,
 };
-- 
2.25.1


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

[PATCH v2 14/35] mtd: spi-nor: spansion: Use manufacturer late_init()

From: Tudor Ambarus <hidden>
Date: 2021-07-27 05:38:24

spansion_post_sfdp_fixups() was called regardless if the flash defined
SFDP tables or not. A better place for this kind of parameters init is
in manufacturer's late_init() hook. post_sfdp() should be called only
when SFDP is defined. No functional change in this patch.

Instead of doing the 4b opcodes settings at manufacturer level, thus
also for every flash that will be introduced, this should be done
just where it is needed, per flash. I'll let this for other patch.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/spansion.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c
index ee82dcd75310..aad7170768b4 100644
--- a/drivers/mtd/spi-nor/spansion.c
+++ b/drivers/mtd/spi-nor/spansion.c
@@ -276,7 +276,7 @@ static const struct flash_info spansion_parts[] = {
 	},
 };
 
-static void spansion_post_sfdp_fixups(struct spi_nor *nor)
+static void spansion_late_init(struct spi_nor *nor)
 {
 	if (nor->params->size <= SZ_16M)
 		return;
@@ -287,13 +287,9 @@ static void spansion_post_sfdp_fixups(struct spi_nor *nor)
 	nor->mtd.erasesize = nor->info->sector_size;
 }
 
-static const struct spi_nor_fixups spansion_fixups = {
-	.post_sfdp = spansion_post_sfdp_fixups,
-};
-
 const struct spi_nor_manufacturer spi_nor_spansion = {
 	.name = "spansion",
 	.parts = spansion_parts,
 	.nparts = ARRAY_SIZE(spansion_parts),
-	.fixups = &spansion_fixups,
+	.late_init = spansion_late_init,
 };
-- 
2.25.1


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

[PATCH v2 15/35] mtd: spi-nor: core: Call spi_nor_post_sfdp_fixups() only when SFDP is defined

From: Tudor Ambarus <hidden>
Date: 2021-07-27 05:42:24

spi_nor_post_sfdp_fixups() was called even when there were no SFDP
tables defined and the function name was misleading.

We introduced the late_init() hook which is used to tweak various
parameters that could not be extracted by other means, i.e. when
parameters are not defined in the JESD216 SFDP standard, or when
the flash_info flags are incomplete.

Use spi_nor_post_sfdp_fixups() just to fix SFDP data. post_sfdp()
hook is as of now used just by s28hs512t, mt35xu512aba, and both
support SFDP, there's no functional change with this patch.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c | 66 +++++++++++++++++---------------------
 1 file changed, 29 insertions(+), 37 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 15ccc9994215..1f38fa8ab2fa 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2509,6 +2509,25 @@ static void spi_nor_manufacturer_init_params(struct spi_nor *nor)
 		nor->info->fixups->default_init(nor);
 }
 
+/**
+ * spi_nor_post_sfdp_fixups() - Updates the flash's parameters and settings
+ * after SFDP has been parsed.
+ * @nor:	pointer to a 'struct spi_nor'
+ *
+ * Typically used to tweak various parameters that could not be extracted by
+ * other means (i.e. when information provided by the SFDP tables are
+ * incomplete or wrong).
+ */
+static void spi_nor_post_sfdp_fixups(struct spi_nor *nor)
+{
+	if (nor->manufacturer && nor->manufacturer->fixups &&
+	    nor->manufacturer->fixups->post_sfdp)
+		nor->manufacturer->fixups->post_sfdp(nor);
+
+	if (nor->info->fixups && nor->info->fixups->post_sfdp)
+		nor->info->fixups->post_sfdp(nor);
+}
+
 /**
  * spi_nor_sfdp_init_params() - Initialize the flash's parameters and settings
  * based on JESD216 SFDP standard.
@@ -2523,11 +2542,12 @@ static void spi_nor_sfdp_init_params(struct spi_nor *nor)
 
 	memcpy(&sfdp_params, nor->params, sizeof(sfdp_params));
 
-	if (spi_nor_parse_sfdp(nor)) {
-		memcpy(nor->params, &sfdp_params, sizeof(*nor->params));
-		nor->addr_width = 0;
-		nor->flags &= ~SNOR_F_4B_OPCODES;
-	}
+	if (!spi_nor_parse_sfdp(nor))
+		return spi_nor_post_sfdp_fixups(nor);
+
+	memcpy(nor->params, &sfdp_params, sizeof(*nor->params));
+	nor->addr_width = 0;
+	nor->flags &= ~SNOR_F_4B_OPCODES;
 }
 
 /**
@@ -2643,26 +2663,6 @@ static void spi_nor_info_init_params(struct spi_nor *nor)
 	spi_nor_init_uniform_erase_map(map, erase_mask, params->size);
 }
 
-/**
- * spi_nor_post_sfdp_fixups() - Updates the flash's parameters and settings
- * after SFDP has been parsed (is also called for SPI NORs that do not
- * support RDSFDP).
- * @nor:	pointer to a 'struct spi_nor'
- *
- * Typically used to tweak various parameters that could not be extracted by
- * other means (i.e. when information provided by the SFDP/flash_info tables
- * are incomplete or wrong).
- */
-static void spi_nor_post_sfdp_fixups(struct spi_nor *nor)
-{
-	if (nor->manufacturer && nor->manufacturer->fixups &&
-	    nor->manufacturer->fixups->post_sfdp)
-		nor->manufacturer->fixups->post_sfdp(nor);
-
-	if (nor->info->fixups && nor->info->fixups->post_sfdp)
-		nor->info->fixups->post_sfdp(nor);
-}
-
 /**
  * spi_nor_late_init_params() - Late initialization of default flash parameters.
  * @nor:	pointer to a 'struct spi_nor'
@@ -2709,18 +2709,12 @@ static void spi_nor_late_init_params(struct spi_nor *nor)
  *    should be more accurate that the above.
  *		spi_nor_sfdp_init_params()
  *
- *    Please note that there is a ->post_bfpt() fixup hook that can overwrite
- *    the flash parameters and settings immediately after parsing the Basic
- *    Flash Parameter Table.
+ *    Please note that there are ->post_{bfpt, sfdp}() fixup hooks that can
+ *    overwrite the flash parameters and settings immediately after table
+ *    parsing.
  *
  * which can be overwritten by:
- * 4/ Post SFDP flash parameters initialization. Used to tweak various
- *    parameters that could not be extracted by other means (i.e. when
- *    information provided by the SFDP/flash_info tables are incomplete or
- *    wrong).
- *		spi_nor_post_sfdp_fixups()
- *
- * 5/ Late flash parameters initialization, used to initialize flash
+ * 4/ Late flash parameters initialization, used to initialize flash
  * parameters that are not declared in the JESD216 SFDP standard.
  *		spi_nor_late_init_params()
  */
@@ -2740,8 +2734,6 @@ static int spi_nor_init_params(struct spi_nor *nor)
 	    !(nor->info->flags & SPI_NOR_SKIP_SFDP))
 		spi_nor_sfdp_init_params(nor);
 
-	spi_nor_post_sfdp_fixups(nor);
-
 	spi_nor_late_init_params(nor);
 
 	return 0;
-- 
2.25.1


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

[PATCH v2 16/35] mtd: spi-nor: core: Mark default_init() as deprecated

From: Tudor Ambarus <hidden>
Date: 2021-07-27 05:46:44

The goal is to remove the spagetti init of params. The flash should
be initialized by the SFDP data, and when SFDP tables are not defined,
by the flash_info flags. SFDP data can be corrected by the
post_{bfpt, sfdp} when wrong, and in case of flash_info flags init,
we'll use the late_init() hook, where checking for the
SPI_NOR_SKIP_SFDP flag.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.h | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 13d5c5edfd27..625f4eed75f1 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -289,9 +289,8 @@ struct spi_nor_flash_parameter {
 
 /**
  * struct spi_nor_fixups - SPI NOR fixup hooks
- * @default_init: called after default flash parameters init. Used to tweak
- *                flash parameters when information provided by the flash_info
- *                table is incomplete or wrong.
+ * @default_init: Deprecated. Use the post_{bfpt, sfdp}, or the late_init()
+ *                hooks instead.
  * @post_bfpt: called after the BFPT table has been parsed
  * @post_sfdp: called after SFDP has been parsed (is also called for SPI NORs
  *             that do not support RDSFDP). Typically used to tweak various
-- 
2.25.1


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

[PATCH v2 17/35] mtd: spi-nor: Introduce spi_nor_nonsfdp_flags_init()

From: Tudor Ambarus <hidden>
Date: 2021-07-27 05:50:54

Used to initialize the NOR flags for settings that are not defined
in the JESD216 SFDP standard, thus can not be retrieved when parsing
SFDP. No functional change.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c | 88 ++++++++++++++++++++++----------------
 1 file changed, 52 insertions(+), 36 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 1f38fa8ab2fa..6a8617346764 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2687,6 +2687,56 @@ static void spi_nor_late_init_params(struct spi_nor *nor)
 		spi_nor_init_default_locking_ops(nor);
 }
 
+/**
+ * spi_nor_nonsfdp_flags_init() - Initialize NOR flags for settings that are not
+ * defined in the JESD216 SFDP standard, thus can not be retrieved when parsing
+ * SFDP.
+ * @nor:	pointer to a 'struct spi_nor'
+ */
+static void spi_nor_nonsfdp_flags_init(struct spi_nor *nor)
+{
+	const struct flash_info *info = nor->info;
+	struct device_node *np = spi_nor_get_flash_node(nor);
+
+	if (of_property_read_bool(np, "broken-flash-reset"))
+		nor->flags |= SNOR_F_BROKEN_RESET;
+
+	if (info->flags & SPI_NOR_SWP_IS_VOLATILE)
+		nor->flags |= SNOR_F_SWP_IS_VOLATILE;
+
+	if (info->flags & SPI_NOR_HAS_LOCK)
+		nor->flags |= SNOR_F_HAS_LOCK;
+
+	if (info->flags & SPI_NOR_HAS_TB) {
+		nor->flags |= SNOR_F_HAS_SR_TB;
+		if (info->flags & SPI_NOR_TB_SR_BIT6)
+			nor->flags |= SNOR_F_HAS_SR_TB_BIT6;
+	}
+
+	if (info->flags & SPI_NOR_4BIT_BP) {
+		nor->flags |= SNOR_F_HAS_4BIT_BP;
+		if (info->flags & SPI_NOR_BP3_SR_BIT6)
+			nor->flags |= SNOR_F_HAS_SR_BP3_BIT6;
+	}
+
+	if (info->flags & NO_CHIP_ERASE)
+		nor->flags |= SNOR_F_NO_OP_CHIP_ERASE;
+
+	if (info->flags & USE_FSR)
+		nor->flags |= SNOR_F_USE_FSR;
+
+	if (info->flags & USE_CLSR)
+		nor->flags |= SNOR_F_USE_CLSR;
+
+	/*
+	 * Make sure the XSR_RDY flag is set before calling
+	 * spi_nor_wait_till_ready(). Xilinx S3AN share MFR
+	 * with Atmel SPI NOR.
+	 */
+	if (info->flags & SPI_NOR_XSR_RDY)
+		nor->flags |=  SNOR_F_READY_XSR_RDY;
+}
+
 /**
  * spi_nor_init_params() - Initialize the flash's parameters and settings.
  * @nor:	pointer to a 'struct spi_nor'.
@@ -2736,6 +2786,8 @@ static int spi_nor_init_params(struct spi_nor *nor)
 
 	spi_nor_late_init_params(nor);
 
+	spi_nor_nonsfdp_flags_init(nor);
+
 	return 0;
 }
 
@@ -3078,7 +3130,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 	const struct flash_info *info;
 	struct device *dev = nor->dev;
 	struct mtd_info *mtd = &nor->mtd;
-	struct device_node *np = spi_nor_get_flash_node(nor);
 	int ret;
 	int i;
 
@@ -3115,17 +3166,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 
 	mutex_init(&nor->lock);
 
-	/*
-	 * Make sure the XSR_RDY flag is set before calling
-	 * spi_nor_wait_till_ready(). Xilinx S3AN share MFR
-	 * with Atmel SPI NOR.
-	 */
-	if (info->flags & SPI_NOR_XSR_RDY)
-		nor->flags |=  SNOR_F_READY_XSR_RDY;
-
-	if (info->flags & SPI_NOR_HAS_LOCK)
-		nor->flags |= SNOR_F_HAS_LOCK;
-
 	mtd->_write = spi_nor_write;
 
 	/* Init flash parameters based on flash_info struct and SFDP */
@@ -3147,27 +3187,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 	mtd->_get_device = spi_nor_get_device;
 	mtd->_put_device = spi_nor_put_device;
 
-	if (info->flags & USE_FSR)
-		nor->flags |= SNOR_F_USE_FSR;
-	if (info->flags & SPI_NOR_HAS_TB) {
-		nor->flags |= SNOR_F_HAS_SR_TB;
-		if (info->flags & SPI_NOR_TB_SR_BIT6)
-			nor->flags |= SNOR_F_HAS_SR_TB_BIT6;
-	}
-
-	if (info->flags & NO_CHIP_ERASE)
-		nor->flags |= SNOR_F_NO_OP_CHIP_ERASE;
-	if (info->flags & USE_CLSR)
-		nor->flags |= SNOR_F_USE_CLSR;
-	if (info->flags & SPI_NOR_SWP_IS_VOLATILE)
-		nor->flags |= SNOR_F_SWP_IS_VOLATILE;
-
-	if (info->flags & SPI_NOR_4BIT_BP) {
-		nor->flags |= SNOR_F_HAS_4BIT_BP;
-		if (info->flags & SPI_NOR_BP3_SR_BIT6)
-			nor->flags |= SNOR_F_HAS_SR_BP3_BIT6;
-	}
-
 	if (info->flags & SPI_NOR_NO_ERASE)
 		mtd->flags |= MTD_NO_ERASE;
 
@@ -3175,9 +3194,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 	nor->page_size = nor->params->page_size;
 	mtd->writebufsize = nor->page_size;
 
-	if (of_property_read_bool(np, "broken-flash-reset"))
-		nor->flags |= SNOR_F_BROKEN_RESET;
-
 	/*
 	 * Configure the SPI memory:
 	 * - select op codes for (Fast) Read, Page Program and Sector Erase.
-- 
2.25.1


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

[PATCH v2 18/35] mtd: spi-nor: Get rid of SPI_NOR_4B_OPCODES flag

From: Tudor Ambarus <hidden>
Date: 2021-07-27 05:56:22

Get rid of flash_info flags that indicate settings which can be
discovered when parsing SFDP. It will be clearer who sets what,
and we'll restrict the flash settings that a developer can choose to
only settings that are not SFDP discoverable.

Whether a flash supports 4byte opcodes or not, is discoverable when
parsing the optional 4-byte address instruction table. Flashes that
do not support the 4bait SFDP table should set the SNOR_F_4B_OPCODES
flag in the late_init() call. Flashes that define the 4bait SFDP table
but gets it wrong, should set the flag in a post_sfdp fixup hook.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c       |  3 ---
 drivers/mtd/spi-nor/core.h       | 32 ++++++++++++++++----------------
 drivers/mtd/spi-nor/gigadevice.c |  7 ++++---
 drivers/mtd/spi-nor/issi.c       | 12 ++++++------
 drivers/mtd/spi-nor/macronix.c   | 18 ++++++++++--------
 drivers/mtd/spi-nor/micron-st.c  | 22 +++++++++++++---------
 drivers/mtd/spi-nor/spansion.c   | 12 ++++++------
 7 files changed, 55 insertions(+), 51 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 6a8617346764..240d5c31af88 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -3204,9 +3204,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 	if (ret)
 		return ret;
 
-	if (info->flags & SPI_NOR_4B_OPCODES)
-		nor->flags |= SNOR_F_4B_OPCODES;
-
 	if (info->flags & SPI_NOR_IO_MODE_EN_VOLATILE)
 		nor->flags |= SNOR_F_IO_MODE_EN_VOLATILE;
 
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 625f4eed75f1..dfdc51a26cad 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -348,40 +348,36 @@ struct flash_info {
 					 * S3AN flashes have specific opcode to
 					 * read the status register.
 					 */
-#define SPI_NOR_4B_OPCODES	BIT(11)	/*
-					 * Use dedicated 4byte address op codes
-					 * to support memory size above 128Mib.
-					 */
-#define NO_CHIP_ERASE		BIT(12) /* Chip does not support chip erase */
-#define SPI_NOR_SKIP_SFDP	BIT(13)	/* Skip parsing of SFDP tables */
-#define USE_CLSR		BIT(14)	/* use CLSR command */
-#define SPI_NOR_OCTAL_READ	BIT(15)	/* Flash supports Octal Read */
-#define SPI_NOR_TB_SR_BIT6	BIT(16)	/*
+#define NO_CHIP_ERASE		BIT(11) /* Chip does not support chip erase */
+#define SPI_NOR_SKIP_SFDP	BIT(12)	/* Skip parsing of SFDP tables */
+#define USE_CLSR		BIT(13)	/* use CLSR command */
+#define SPI_NOR_OCTAL_READ	BIT(14)	/* Flash supports Octal Read */
+#define SPI_NOR_TB_SR_BIT6	BIT(15)	/*
 					 * Top/Bottom (TB) is bit 6 of
 					 * status register. Must be used with
 					 * SPI_NOR_HAS_TB.
 					 */
-#define SPI_NOR_4BIT_BP		BIT(17) /*
+#define SPI_NOR_4BIT_BP		BIT(16) /*
 					 * Flash SR has 4 bit fields (BP0-3)
 					 * for block protection.
 					 */
-#define SPI_NOR_BP3_SR_BIT6	BIT(18) /*
+#define SPI_NOR_BP3_SR_BIT6	BIT(17) /*
 					 * BP3 is bit 6 of status register.
 					 * Must be used with SPI_NOR_4BIT_BP.
 					 */
-#define SPI_NOR_OCTAL_DTR_READ	BIT(19) /* Flash supports octal DTR Read. */
-#define SPI_NOR_OCTAL_DTR_PP	BIT(20) /* Flash supports Octal DTR Page Program */
-#define SPI_NOR_IO_MODE_EN_VOLATILE	BIT(21) /*
+#define SPI_NOR_OCTAL_DTR_READ	BIT(18) /* Flash supports octal DTR Read. */
+#define SPI_NOR_OCTAL_DTR_PP	BIT(19) /* Flash supports Octal DTR Page Program */
+#define SPI_NOR_IO_MODE_EN_VOLATILE	BIT(20) /*
 						 * Flash enables the best
 						 * available I/O mode via a
 						 * volatile bit.
 						 */
-#define SPI_NOR_SWP_IS_VOLATILE	BIT(22)	/*
+#define SPI_NOR_SWP_IS_VOLATILE	BIT(21)	/*
 					 * Flash has volatile software write
 					 * protection bits. Usually these will
 					 * power-up in a write-protected state.
 					 */
-#define SPI_NOR_PARSE_SFDP	BIT(23) /*
+#define SPI_NOR_PARSE_SFDP	BIT(22) /*
 					 * Flash initialized based on the SFDP
 					 * tables.
 					 */
@@ -569,4 +565,8 @@ static struct spi_nor __maybe_unused *mtd_to_spi_nor(struct mtd_info *mtd)
 	return mtd->priv;
 }
 
+static inline void snor_f_4b_opcodes(struct spi_nor *nor)
+{
+	nor->flags |= SNOR_F_4B_OPCODES;
+}
 #endif /* __LINUX_MTD_SPI_NOR_INTERNAL_H */
diff --git a/drivers/mtd/spi-nor/gigadevice.c b/drivers/mtd/spi-nor/gigadevice.c
index 447d84bb2128..ff523fe734ef 100644
--- a/drivers/mtd/spi-nor/gigadevice.c
+++ b/drivers/mtd/spi-nor/gigadevice.c
@@ -47,9 +47,10 @@ static const struct flash_info gigadevice_parts[] = {
 			   SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
 	{ "gd25q256", INFO(0xc84019, 0, 64 * 1024, 512,
 			   SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-			   SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK |
-			   SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6)
-		.fixups = &gd25q256_fixups },
+			   SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB |
+			   SPI_NOR_TB_SR_BIT6)
+		.fixups = &gd25q256_fixups,
+		.late_init = snor_f_4b_opcodes,	},
 };
 
 const struct spi_nor_manufacturer spi_nor_gigadevice = {
diff --git a/drivers/mtd/spi-nor/issi.c b/drivers/mtd/spi-nor/issi.c
index 1e5bb5408b68..aeff8f60cbae 100644
--- a/drivers/mtd/spi-nor/issi.c
+++ b/drivers/mtd/spi-nor/issi.c
@@ -45,9 +45,9 @@ static const struct flash_info issi_parts[] = {
 	{ "is25lp128",  INFO(0x9d6018, 0, 64 * 1024, 256,
 			     SECT_4K | SPI_NOR_DUAL_READ) },
 	{ "is25lp256",  INFO(0x9d6019, 0, 64 * 1024, 512,
-			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-			     SPI_NOR_4B_OPCODES)
-		.fixups = &is25lp256_fixups },
+			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
+		.fixups = &is25lp256_fixups,
+		.late_init = snor_f_4b_opcodes, },
 	{ "is25wp032",  INFO(0x9d7016, 0, 64 * 1024,  64,
 			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 	{ "is25wp064",  INFO(0x9d7017, 0, 64 * 1024, 128,
@@ -55,9 +55,9 @@ static const struct flash_info issi_parts[] = {
 	{ "is25wp128",  INFO(0x9d7018, 0, 64 * 1024, 256,
 			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 	{ "is25wp256", INFO(0x9d7019, 0, 64 * 1024, 512,
-			    SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-			    SPI_NOR_4B_OPCODES)
-		.fixups = &is25lp256_fixups },
+			    SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
+		.fixups = &is25lp256_fixups,
+		.late_init = snor_f_4b_opcodes, },
 
 	/* PMC */
 	{ "pm25lv512",   INFO(0,        0, 32 * 1024,    2, SECT_4K_PMC) },
diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c
index fba85efafb47..9709eb68b613 100644
--- a/drivers/mtd/spi-nor/macronix.c
+++ b/drivers/mtd/spi-nor/macronix.c
@@ -105,29 +105,31 @@ static const struct flash_info macronix_parts[] = {
 	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512,
 			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
 		.fixups = &mx25l25635_fixups },
-	{ "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512,
-			      SECT_4K | SPI_NOR_4B_OPCODES) },
+	{ "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K)
+		.late_init = snor_f_4b_opcodes, },
 	{ "mx25u51245g", INFO(0xc2253a, 0, 64 * 1024, 1024,
 			      SECT_4K | SPI_NOR_DUAL_READ |
-			      SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+			      SPI_NOR_QUAD_READ)
+		.late_init = snor_f_4b_opcodes, },
 	{ "mx25v8035f",  INFO(0xc22314, 0, 64 * 1024,  16,
 			      SECT_4K | SPI_NOR_DUAL_READ |
 			      SPI_NOR_QUAD_READ) },
 	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
 	{ "mx66l51235f", INFO(0xc2201a, 0, 64 * 1024, 1024,
-			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-			      SPI_NOR_4B_OPCODES) },
+			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
+		.late_init = snor_f_4b_opcodes, },
 	{ "mx66u51235f", INFO(0xc2253a, 0, 64 * 1024, 1024,
 			      SECT_4K | SPI_NOR_DUAL_READ |
-			      SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+			      SPI_NOR_QUAD_READ)
+		.late_init = snor_f_4b_opcodes, },
 	{ "mx66l1g45g",  INFO(0xc2201b, 0, 64 * 1024, 2048,
 			      SECT_4K | SPI_NOR_DUAL_READ |
 			      SPI_NOR_QUAD_READ) },
 	{ "mx66l1g55g",  INFO(0xc2261b, 0, 64 * 1024, 2048,
 			      SPI_NOR_QUAD_READ) },
 	{ "mx66u2g45g",	 INFO(0xc2253c, 0, 64 * 1024, 4096,
-			      SECT_4K | SPI_NOR_DUAL_READ |
-			      SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+			      SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
+		.late_init = snor_f_4b_opcodes, },
 };
 
 static void macronix_default_init(struct spi_nor *nor)
diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c
index c224e59820a1..72cc4673bf88 100644
--- a/drivers/mtd/spi-nor/micron-st.c
+++ b/drivers/mtd/spi-nor/micron-st.c
@@ -121,13 +121,13 @@ static struct spi_nor_fixups mt35xu512aba_fixups = {
 static const struct flash_info micron_parts[] = {
 	{ "mt35xu512aba", INFO(0x2c5b1a, 0, 128 * 1024, 512,
 			       SECT_4K | USE_FSR | SPI_NOR_OCTAL_READ |
-			       SPI_NOR_4B_OPCODES | SPI_NOR_OCTAL_DTR_READ |
-			       SPI_NOR_OCTAL_DTR_PP |
+			       SPI_NOR_OCTAL_DTR_READ | SPI_NOR_OCTAL_DTR_PP |
 			       SPI_NOR_IO_MODE_EN_VOLATILE)
-	  .fixups = &mt35xu512aba_fixups},
+	  .fixups = &mt35xu512aba_fixups,
+	  .late_init = snor_f_4b_opcodes, },
 	{ "mt35xu02g", INFO(0x2c5b1c, 0, 128 * 1024, 2048,
-			    SECT_4K | USE_FSR | SPI_NOR_OCTAL_READ |
-			    SPI_NOR_4B_OPCODES) },
+			    SECT_4K | USE_FSR | SPI_NOR_OCTAL_READ)
+	  .late_init = snor_f_4b_opcodes, },
 };
 
 static const struct flash_info st_parts[] = {
@@ -149,25 +149,29 @@ static const struct flash_info st_parts[] = {
 			      SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
 	{ "mt25ql256a",  INFO6(0x20ba19, 0x104400, 64 * 1024,  512,
 			       SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
-			       SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+			       SPI_NOR_QUAD_READ)
+	  .late_init = snor_f_4b_opcodes, },
 	{ "n25q256a",    INFO(0x20ba19, 0, 64 * 1024,  512, SECT_4K |
 			      USE_FSR | SPI_NOR_DUAL_READ |
 			      SPI_NOR_QUAD_READ) },
 	{ "mt25qu256a",  INFO6(0x20bb19, 0x104400, 64 * 1024,  512,
 			       SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
-			       SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+			       SPI_NOR_QUAD_READ)
+	  .late_init = snor_f_4b_opcodes, },
 	{ "n25q256ax1",  INFO(0x20bb19, 0, 64 * 1024,  512,
 			      SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
 	{ "mt25ql512a",  INFO6(0x20ba20, 0x104400, 64 * 1024, 1024,
 			       SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
-			       SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+			       SPI_NOR_QUAD_READ)
+	  .late_init = snor_f_4b_opcodes, },
 	{ "n25q512ax3",  INFO(0x20ba20, 0, 64 * 1024, 1024,
 			      SECT_4K | USE_FSR | SPI_NOR_QUAD_READ |
 			      SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB |
 			      SPI_NOR_4BIT_BP | SPI_NOR_BP3_SR_BIT6) },
 	{ "mt25qu512a",  INFO6(0x20bb20, 0x104400, 64 * 1024, 1024,
 			       SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
-			       SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+			       SPI_NOR_QUAD_READ)
+	  .late_init = snor_f_4b_opcodes, },
 	{ "n25q512a",    INFO(0x20bb20, 0, 64 * 1024, 1024,
 			      SECT_4K | USE_FSR | SPI_NOR_QUAD_READ |
 			      SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB |
diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c
index aad7170768b4..af10833f56d8 100644
--- a/drivers/mtd/spi-nor/spansion.c
+++ b/drivers/mtd/spi-nor/spansion.c
@@ -259,14 +259,14 @@ static const struct flash_info spansion_parts[] = {
 	{ "s25fl208k",  INFO(0x014014,      0,  64 * 1024,  16,
 			     SECT_4K | SPI_NOR_DUAL_READ) },
 	{ "s25fl064l",  INFO(0x016017,      0,  64 * 1024, 128,
-			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-			     SPI_NOR_4B_OPCODES) },
+			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
+		.late_init = snor_f_4b_opcodes, },
 	{ "s25fl128l",  INFO(0x016018,      0,  64 * 1024, 256,
-			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-			     SPI_NOR_4B_OPCODES) },
+			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
+		.late_init = snor_f_4b_opcodes, },
 	{ "s25fl256l",  INFO(0x016019,      0,  64 * 1024, 512,
-			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-			     SPI_NOR_4B_OPCODES) },
+			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
+		.late_init = snor_f_4b_opcodes, },
 	{ "cy15x104q",  INFO6(0x042cc2, 0x7f7f7f, 512 * 1024, 1,
 			      SPI_NOR_NO_ERASE) },
 	{ "s28hs512t",   INFO(0x345b1a,      0, 256 * 1024, 256,
-- 
2.25.1


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

[PATCH v2 19/35] mtd: spi-nor: Get rid of SPI_NOR_IO_MODE_EN_VOLATILE flag

From: Tudor Ambarus <hidden>
Date: 2021-07-27 06:01:14

Get rid of flash_info flags that indicate settings which can be
discovered when parsing SFDP. It will be clearer who sets what,
and we'll restrict the flash settings that a developer can choose to
only settings that are not SFDP discoverable.

SNOR_F_IO_MODE_EN_VOLATILE is discoverable when parsing the optional
SCCR Map SFDP table. Flashes that do not define this table should set
the flag in the late_init() call. Flashes that define the SFDP optional
table but get the value wrong, should fix it in a post_sfdp fixup hook.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c      |  3 ---
 drivers/mtd/spi-nor/core.h      |  9 ++-------
 drivers/mtd/spi-nor/micron-st.c | 11 ++++++++---
 3 files changed, 10 insertions(+), 13 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 240d5c31af88..9885d434ea83 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -3204,9 +3204,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 	if (ret)
 		return ret;
 
-	if (info->flags & SPI_NOR_IO_MODE_EN_VOLATILE)
-		nor->flags |= SNOR_F_IO_MODE_EN_VOLATILE;
-
 	ret = spi_nor_set_addr_width(nor);
 	if (ret)
 		return ret;
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index dfdc51a26cad..987797a789c8 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -367,17 +367,12 @@ struct flash_info {
 					 */
 #define SPI_NOR_OCTAL_DTR_READ	BIT(18) /* Flash supports octal DTR Read. */
 #define SPI_NOR_OCTAL_DTR_PP	BIT(19) /* Flash supports Octal DTR Page Program */
-#define SPI_NOR_IO_MODE_EN_VOLATILE	BIT(20) /*
-						 * Flash enables the best
-						 * available I/O mode via a
-						 * volatile bit.
-						 */
-#define SPI_NOR_SWP_IS_VOLATILE	BIT(21)	/*
+#define SPI_NOR_SWP_IS_VOLATILE	BIT(20)	/*
 					 * Flash has volatile software write
 					 * protection bits. Usually these will
 					 * power-up in a write-protected state.
 					 */
-#define SPI_NOR_PARSE_SFDP	BIT(22) /*
+#define SPI_NOR_PARSE_SFDP	BIT(21) /*
 					 * Flash initialized based on the SFDP
 					 * tables.
 					 */
diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c
index 72cc4673bf88..31ebd4c9b431 100644
--- a/drivers/mtd/spi-nor/micron-st.c
+++ b/drivers/mtd/spi-nor/micron-st.c
@@ -118,13 +118,18 @@ static struct spi_nor_fixups mt35xu512aba_fixups = {
 	.post_sfdp = mt35xu512aba_post_sfdp_fixup,
 };
 
+static void mt35xu512aba_late_init(struct spi_nor *nor)
+{
+	nor->flags |= SNOR_F_4B_OPCODES;
+	nor->flags |= SNOR_F_IO_MODE_EN_VOLATILE;
+}
+
 static const struct flash_info micron_parts[] = {
 	{ "mt35xu512aba", INFO(0x2c5b1a, 0, 128 * 1024, 512,
 			       SECT_4K | USE_FSR | SPI_NOR_OCTAL_READ |
-			       SPI_NOR_OCTAL_DTR_READ | SPI_NOR_OCTAL_DTR_PP |
-			       SPI_NOR_IO_MODE_EN_VOLATILE)
+			       SPI_NOR_OCTAL_DTR_READ | SPI_NOR_OCTAL_DTR_PP)
 	  .fixups = &mt35xu512aba_fixups,
-	  .late_init = snor_f_4b_opcodes, },
+	  .late_init = mt35xu512aba_late_init, },
 	{ "mt35xu02g", INFO(0x2c5b1c, 0, 128 * 1024, 2048,
 			    SECT_4K | USE_FSR | SPI_NOR_OCTAL_READ)
 	  .late_init = snor_f_4b_opcodes, },
-- 
2.25.1


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

[PATCH v2 20/35] mtd: spi-nor: core: Use container_of to get the pointer to struct spi_nor

From: Tudor Ambarus <hidden>
Date: 2021-07-27 06:06:06

Get the pointer to the containing struct spi_nor by using container_of.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c | 1 -
 drivers/mtd/spi-nor/core.h | 2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 9885d434ea83..5c8cffb5e6f2 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -3175,7 +3175,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 
 	if (!mtd->name)
 		mtd->name = dev_name(dev);
-	mtd->priv = nor;
 	mtd->type = MTD_NORFLASH;
 	mtd->writesize = nor->params->writesize;
 	mtd->flags = MTD_CAP_NORFLASH;
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 987797a789c8..8fddc685d2d3 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -557,7 +557,7 @@ void spi_nor_otp_init(struct spi_nor *nor);
 
 static struct spi_nor __maybe_unused *mtd_to_spi_nor(struct mtd_info *mtd)
 {
-	return mtd->priv;
+	return container_of(mtd, struct spi_nor, mtd);
 }
 
 static inline void snor_f_4b_opcodes(struct spi_nor *nor)
-- 
2.25.1


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

[PATCH v2 21/35] mtd: spi-nor: Introduce spi_nor_set_mtd_info()

From: Tudor Ambarus <hidden>
Date: 2021-07-27 06:10:26

Used to init all the mtd_info fields. Move the mtd_info init
the last thing in the spi_nor_scan(), so that we avoid superfluous
initialization of the mtd_info fields in case of errors.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c | 55 +++++++++++++++++++++-----------------
 1 file changed, 31 insertions(+), 24 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 5c8cffb5e6f2..26acfc9901db 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -3124,6 +3124,36 @@ static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor,
 	return info;
 }
 
+static void spi_nor_set_mtd_info(struct spi_nor *nor)
+{
+	struct mtd_info *mtd = &nor->mtd;
+	struct device *dev = nor->dev;
+
+	spi_nor_register_locking_ops(nor);
+
+	/* Configure OTP parameters and ops */
+	spi_nor_otp_init(nor);
+
+	mtd->dev.parent = dev;
+	if (!mtd->name)
+		mtd->name = dev_name(dev);
+	mtd->priv = nor;
+	mtd->type = MTD_NORFLASH;
+	mtd->flags = MTD_CAP_NORFLASH;
+	if (nor->info->flags & SPI_NOR_NO_ERASE)
+		mtd->flags |= MTD_NO_ERASE;
+	mtd->writesize = nor->params->writesize;
+	mtd->writebufsize = nor->page_size;
+	mtd->size = nor->params->size;
+	mtd->_erase = spi_nor_erase;
+	mtd->_read = spi_nor_read;
+	mtd->_write = spi_nor_write;
+	mtd->_suspend = spi_nor_suspend;
+	mtd->_resume = spi_nor_resume;
+	mtd->_get_device = spi_nor_get_device;
+	mtd->_put_device = spi_nor_put_device;
+}
+
 int spi_nor_scan(struct spi_nor *nor, const char *name,
 		 const struct spi_nor_hwcaps *hwcaps)
 {
@@ -3166,32 +3196,12 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 
 	mutex_init(&nor->lock);
 
-	mtd->_write = spi_nor_write;
-
 	/* Init flash parameters based on flash_info struct and SFDP */
 	ret = spi_nor_init_params(nor);
 	if (ret)
 		return ret;
 
-	if (!mtd->name)
-		mtd->name = dev_name(dev);
-	mtd->type = MTD_NORFLASH;
-	mtd->writesize = nor->params->writesize;
-	mtd->flags = MTD_CAP_NORFLASH;
-	mtd->size = nor->params->size;
-	mtd->_erase = spi_nor_erase;
-	mtd->_read = spi_nor_read;
-	mtd->_suspend = spi_nor_suspend;
-	mtd->_resume = spi_nor_resume;
-	mtd->_get_device = spi_nor_get_device;
-	mtd->_put_device = spi_nor_put_device;
-
-	if (info->flags & SPI_NOR_NO_ERASE)
-		mtd->flags |= MTD_NO_ERASE;
-
-	mtd->dev.parent = dev;
 	nor->page_size = nor->params->page_size;
-	mtd->writebufsize = nor->page_size;
 
 	/*
 	 * Configure the SPI memory:
@@ -3207,15 +3217,12 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 	if (ret)
 		return ret;
 
-	spi_nor_register_locking_ops(nor);
-
 	/* Send all the required SPI flash commands to initialize device */
 	ret = spi_nor_init(nor);
 	if (ret)
 		return ret;
 
-	/* Configure OTP parameters and ops */
-	spi_nor_otp_init(nor);
+	spi_nor_set_mtd_info(nor);
 
 	if (!nor->name)
 		nor->name = info->name;
-- 
2.25.1


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

[PATCH v2 22/35] mtd: spi-nor: core: Use common naming scheme for setting mtd_info fields

From: Tudor Ambarus <hidden>
Date: 2021-07-27 06:12:50

The functions names are self explanatory, get rid of the comment
for the OTP function.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c | 6 ++----
 drivers/mtd/spi-nor/core.h | 4 ++--
 drivers/mtd/spi-nor/otp.c  | 2 +-
 drivers/mtd/spi-nor/swp.c  | 2 +-
 4 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 26acfc9901db..72dfe6274041 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -3129,10 +3129,8 @@ static void spi_nor_set_mtd_info(struct spi_nor *nor)
 	struct mtd_info *mtd = &nor->mtd;
 	struct device *dev = nor->dev;
 
-	spi_nor_register_locking_ops(nor);
-
-	/* Configure OTP parameters and ops */
-	spi_nor_otp_init(nor);
+	spi_nor_set_mtd_locking_ops(nor);
+	spi_nor_set_mtd_otp_ops(nor);
 
 	mtd->dev.parent = dev;
 	if (!mtd->name)
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 8fddc685d2d3..7fb0cfabe85a 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -552,8 +552,8 @@ int spi_nor_post_bfpt_fixups(struct spi_nor *nor,
 
 void spi_nor_init_default_locking_ops(struct spi_nor *nor);
 void spi_nor_try_unlock_all(struct spi_nor *nor);
-void spi_nor_register_locking_ops(struct spi_nor *nor);
-void spi_nor_otp_init(struct spi_nor *nor);
+void spi_nor_set_mtd_locking_ops(struct spi_nor *nor);
+void spi_nor_set_mtd_otp_ops(struct spi_nor *nor);
 
 static struct spi_nor __maybe_unused *mtd_to_spi_nor(struct mtd_info *mtd)
 {
diff --git a/drivers/mtd/spi-nor/otp.c b/drivers/mtd/spi-nor/otp.c
index 983e40b19134..fa63d8571218 100644
--- a/drivers/mtd/spi-nor/otp.c
+++ b/drivers/mtd/spi-nor/otp.c
@@ -480,7 +480,7 @@ static int spi_nor_mtd_otp_lock(struct mtd_info *mtd, loff_t from, size_t len)
 	return ret;
 }
 
-void spi_nor_otp_init(struct spi_nor *nor)
+void spi_nor_set_mtd_otp_ops(struct spi_nor *nor)
 {
 	struct mtd_info *mtd = &nor->mtd;
 
diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c
index 8594bcbb7dbe..1f178313ba8f 100644
--- a/drivers/mtd/spi-nor/swp.c
+++ b/drivers/mtd/spi-nor/swp.c
@@ -414,7 +414,7 @@ void spi_nor_try_unlock_all(struct spi_nor *nor)
 		dev_dbg(nor->dev, "Failed to unlock the entire flash memory array\n");
 }
 
-void spi_nor_register_locking_ops(struct spi_nor *nor)
+void spi_nor_set_mtd_locking_ops(struct spi_nor *nor)
 {
 	struct mtd_info *mtd = &nor->mtd;
 
-- 
2.25.1


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

[PATCH v2 23/35] mtd: spi-nor: Get rid of nor->page_size

From: Tudor Ambarus <hidden>
Date: 2021-07-27 06:19:20

nor->page_size duplicated what nor->params->page_size indicates
for no good reason. page_size is a flash parameter of fixed value
and it is better suited to be found in nor->params->page_size.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c   | 20 +++++++++-----------
 drivers/mtd/spi-nor/xilinx.c | 17 ++++++++++-------
 include/linux/mtd/spi-nor.h  |  2 --
 3 files changed, 19 insertions(+), 20 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 72dfe6274041..83f27405a000 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -1953,6 +1953,7 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
 	struct spi_nor *nor = mtd_to_spi_nor(mtd);
 	size_t page_offset, page_remain, i;
 	ssize_t ret;
+	u32 page_size = nor->params->page_size;
 
 	dev_dbg(nor->dev, "to 0x%08x, len %zd\n", (u32)to, len);
 
@@ -1969,16 +1970,15 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
 		 * calculated with an AND operation. On the other cases we
 		 * need to do a modulus operation (more expensive).
 		 */
-		if (is_power_of_2(nor->page_size)) {
-			page_offset = addr & (nor->page_size - 1);
+		if (is_power_of_2(page_size)) {
+			page_offset = addr & (page_size - 1);
 		} else {
 			uint64_t aux = addr;
 
-			page_offset = do_div(aux, nor->page_size);
+			page_offset = do_div(aux, page_size);
 		}
 		/* the size of data remaining on the first page */
-		page_remain = min_t(size_t,
-				    nor->page_size - page_offset, len - i);
+		page_remain = min_t(size_t, page_size - page_offset, len - i);
 
 		addr = spi_nor_convert_addr(nor, addr);
 
@@ -3141,7 +3141,7 @@ static void spi_nor_set_mtd_info(struct spi_nor *nor)
 	if (nor->info->flags & SPI_NOR_NO_ERASE)
 		mtd->flags |= MTD_NO_ERASE;
 	mtd->writesize = nor->params->writesize;
-	mtd->writebufsize = nor->page_size;
+	mtd->writebufsize = nor->params->page_size;
 	mtd->size = nor->params->size;
 	mtd->_erase = spi_nor_erase;
 	mtd->_read = spi_nor_read;
@@ -3174,7 +3174,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 	 * We need the bounce buffer early to read/write registers when going
 	 * through the spi-mem layer (buffers have to be DMA-able).
 	 * For spi-mem drivers, we'll reallocate a new buffer if
-	 * nor->page_size turns out to be greater than PAGE_SIZE (which
+	 * nor->params->page_size turns out to be greater than PAGE_SIZE (which
 	 * shouldn't happen before long since NOR pages are usually less
 	 * than 1KB) after spi_nor_scan() returns.
 	 */
@@ -3199,8 +3199,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 	if (ret)
 		return ret;
 
-	nor->page_size = nor->params->page_size;
-
 	/*
 	 * Configure the SPI memory:
 	 * - select op codes for (Fast) Read, Page Program and Sector Erase.
@@ -3359,8 +3357,8 @@ static int spi_nor_probe(struct spi_mem *spimem)
 	 * and add this logic so that if anyone ever adds support for such
 	 * a NOR we don't end up with buffer overflows.
 	 */
-	if (nor->page_size > PAGE_SIZE) {
-		nor->bouncebuf_size = nor->page_size;
+	if (nor->params->page_size > PAGE_SIZE) {
+		nor->bouncebuf_size = nor->params->page_size;
 		devm_kfree(nor->dev, nor->bouncebuf);
 		nor->bouncebuf = devm_kmalloc(nor->dev,
 					      nor->bouncebuf_size,
diff --git a/drivers/mtd/spi-nor/xilinx.c b/drivers/mtd/spi-nor/xilinx.c
index a573c3cde414..a5feb86b0a7e 100644
--- a/drivers/mtd/spi-nor/xilinx.c
+++ b/drivers/mtd/spi-nor/xilinx.c
@@ -28,11 +28,12 @@ static const struct flash_info xilinx_parts[] = {
  */
 static u32 s3an_convert_addr(struct spi_nor *nor, u32 addr)
 {
+	u32 page_size = nor->params->page_size;
 	u32 offset, page;
 
-	offset = addr % nor->page_size;
-	page = addr / nor->page_size;
-	page <<= (nor->page_size > 512) ? 10 : 9;
+	offset = addr % page_size;
+	page = addr / page_size;
+	page <<= (page_size > 512) ? 10 : 9;
 
 	return page | offset;
 }
@@ -40,6 +41,7 @@ static u32 s3an_convert_addr(struct spi_nor *nor, u32 addr)
 static int xilinx_nor_setup(struct spi_nor *nor,
 			    const struct spi_nor_hwcaps *hwcaps)
 {
+	u32 page_size;
 	int ret;
 
 	ret = spi_nor_xread_sr(nor, nor->bouncebuf);
@@ -64,10 +66,11 @@ static int xilinx_nor_setup(struct spi_nor *nor,
 	 */
 	if (nor->bouncebuf[0] & XSR_PAGESIZE) {
 		/* Flash in Power of 2 mode */
-		nor->page_size = (nor->page_size == 264) ? 256 : 512;
-		nor->mtd.writebufsize = nor->page_size;
-		nor->mtd.size = 8 * nor->page_size * nor->info->n_sectors;
-		nor->mtd.erasesize = 8 * nor->page_size;
+		page_size = (nor->params->page_size == 264) ? 256 : 512;
+		nor->params->page_size = page_size;
+		nor->mtd.writebufsize = page_size;
+		nor->mtd.size = 8 * page_size * nor->info->n_sectors;
+		nor->mtd.erasesize = 8 * page_size;
 	} else {
 		/* Flash in Default addressing mode */
 		nor->params->convert_addr = s3an_convert_addr;
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index bd92acdd1899..be7ebaf092fe 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -372,7 +372,6 @@ struct spi_nor_flash_parameter;
  * @name:		used to point to correct name in case of ID collisions.
  * @info:		SPI NOR part JEDEC MFR ID and other info
  * @manufacturer:	SPI NOR manufacturer
- * @page_size:		the page size of the SPI NOR
  * @addr_width:		number of address bytes
  * @erase_opcode:	the opcode for erasing a sector
  * @read_opcode:	the read opcode
@@ -403,7 +402,6 @@ struct spi_nor {
 	const char *name;
 	const struct flash_info	*info;
 	const struct spi_nor_manufacturer *manufacturer;
-	u32			page_size;
 	u8			addr_width;
 	u8			erase_opcode;
 	u8			read_opcode;
-- 
2.25.1


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

[PATCH v2 24/35] mtd: spi-nor: core: Fix spi_nor_flash_parameter otp description

From: Tudor Ambarus <hidden>
Date: 2021-07-27 06:25:30

Update the description of the otp member of the
struct spi_nor_flash_parameter.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 7fb0cfabe85a..501d9212ba9b 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -250,7 +250,7 @@ struct spi_nor_otp {
  *                      higher index in the array, the higher priority.
  * @erase_map:		the erase map parsed from the SFDP Sector Map Parameter
  *                      Table.
- * @otp_info:		describes the OTP regions.
+ * @otp:		SPI NOR OTP info.
  * @octal_dtr_enable:	enables SPI NOR octal DTR mode.
  * @quad_enable:	enables SPI NOR quad mode.
  * @set_4byte_addr_mode: puts the SPI NOR in 4 byte addressing mode.
@@ -262,7 +262,6 @@ struct spi_nor_otp {
  *                      e.g. different opcodes, specific address calculation,
  *                      page size, etc.
  * @locking_ops:	SPI NOR locking methods.
- * @otp:		SPI NOR OTP methods.
  */
 struct spi_nor_flash_parameter {
 	u64				size;
-- 
2.25.1


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

[PATCH v2 25/35] mtd: spi-nor: core: Move spi_nor_set_addr_width() in spi_nor_setup()

From: Tudor Ambarus <hidden>
Date: 2021-07-27 06:27:37

spi_nor_setup() configures the SPI NOR memory. Setting the addr width
is too a configuration, hence we can move the spi_nor_set_addr_width()
in spi_nor_setup().

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c | 101 +++++++++++++++++++------------------
 1 file changed, 52 insertions(+), 49 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 83f27405a000..b3a01d7d6f0b 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2485,13 +2485,62 @@ static int spi_nor_default_setup(struct spi_nor *nor,
 	return 0;
 }
 
+static int spi_nor_set_addr_width(struct spi_nor *nor)
+{
+	if (nor->addr_width) {
+		/* already configured from SFDP */
+	} else if (nor->read_proto == SNOR_PROTO_8_8_8_DTR) {
+		/*
+		 * In 8D-8D-8D mode, one byte takes half a cycle to transfer. So
+		 * in this protocol an odd address width cannot be used because
+		 * then the address phase would only span a cycle and a half.
+		 * Half a cycle would be left over. We would then have to start
+		 * the dummy phase in the middle of a cycle and so too the data
+		 * phase, and we will end the transaction with half a cycle left
+		 * over.
+		 *
+		 * Force all 8D-8D-8D flashes to use an address width of 4 to
+		 * avoid this situation.
+		 */
+		nor->addr_width = 4;
+	} else if (nor->info->addr_width) {
+		nor->addr_width = nor->info->addr_width;
+	} else {
+		nor->addr_width = 3;
+	}
+
+	if (nor->addr_width == 3 && nor->mtd.size > 0x1000000) {
+		/* enable 4-byte addressing if the device exceeds 16MiB */
+		nor->addr_width = 4;
+	}
+
+	if (nor->addr_width > SPI_NOR_MAX_ADDR_WIDTH) {
+		dev_dbg(nor->dev, "address width is too large: %u\n",
+			nor->addr_width);
+		return -EINVAL;
+	}
+
+	/* Set 4byte opcodes when possible. */
+	if (nor->addr_width == 4 && nor->flags & SNOR_F_4B_OPCODES &&
+	    !(nor->flags & SNOR_F_HAS_4BAIT))
+		spi_nor_set_4byte_opcodes(nor);
+
+	return 0;
+}
+
 static int spi_nor_setup(struct spi_nor *nor,
 			 const struct spi_nor_hwcaps *hwcaps)
 {
+	int ret;
+
 	if (!nor->params->setup)
-		return 0;
+		return spi_nor_set_addr_width(nor);
 
-	return nor->params->setup(nor, hwcaps);
+	ret = nor->params->setup(nor, hwcaps);
+	if (ret)
+		return ret;
+
+	return spi_nor_set_addr_width(nor);
 }
 
 /**
@@ -3031,49 +3080,6 @@ static const struct flash_info *spi_nor_match_id(struct spi_nor *nor,
 	return NULL;
 }
 
-static int spi_nor_set_addr_width(struct spi_nor *nor)
-{
-	if (nor->addr_width) {
-		/* already configured from SFDP */
-	} else if (nor->read_proto == SNOR_PROTO_8_8_8_DTR) {
-		/*
-		 * In 8D-8D-8D mode, one byte takes half a cycle to transfer. So
-		 * in this protocol an odd address width cannot be used because
-		 * then the address phase would only span a cycle and a half.
-		 * Half a cycle would be left over. We would then have to start
-		 * the dummy phase in the middle of a cycle and so too the data
-		 * phase, and we will end the transaction with half a cycle left
-		 * over.
-		 *
-		 * Force all 8D-8D-8D flashes to use an address width of 4 to
-		 * avoid this situation.
-		 */
-		nor->addr_width = 4;
-	} else if (nor->info->addr_width) {
-		nor->addr_width = nor->info->addr_width;
-	} else {
-		nor->addr_width = 3;
-	}
-
-	if (nor->addr_width == 3 && nor->mtd.size > 0x1000000) {
-		/* enable 4-byte addressing if the device exceeds 16MiB */
-		nor->addr_width = 4;
-	}
-
-	if (nor->addr_width > SPI_NOR_MAX_ADDR_WIDTH) {
-		dev_dbg(nor->dev, "address width is too large: %u\n",
-			nor->addr_width);
-		return -EINVAL;
-	}
-
-	/* Set 4byte opcodes when possible. */
-	if (nor->addr_width == 4 && nor->flags & SNOR_F_4B_OPCODES &&
-	    !(nor->flags & SNOR_F_HAS_4BAIT))
-		spi_nor_set_4byte_opcodes(nor);
-
-	return 0;
-}
-
 static void spi_nor_debugfs_init(struct spi_nor *nor,
 				 const struct flash_info *info)
 {
@@ -3204,15 +3210,12 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 	 * - select op codes for (Fast) Read, Page Program and Sector Erase.
 	 * - set the number of dummy cycles (mode cycles + wait states).
 	 * - set the SPI protocols for register and memory accesses.
+	 * - set the address width.
 	 */
 	ret = spi_nor_setup(nor, hwcaps);
 	if (ret)
 		return ret;
 
-	ret = spi_nor_set_addr_width(nor);
-	if (ret)
-		return ret;
-
 	/* Send all the required SPI flash commands to initialize device */
 	ret = spi_nor_init(nor);
 	if (ret)
-- 
2.25.1


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

[PATCH v2 26/35] mtd: spi-nor: core: Introduce spi_nor_init_default_params()

From: Tudor Ambarus <hidden>
Date: 2021-07-27 06:32:53

Called for all flashes, regardless if they define SFDP tables or not.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c | 92 +++++++++++++++++++++-----------------
 1 file changed, 52 insertions(+), 40 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index b3a01d7d6f0b..9193317f897d 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2543,6 +2543,56 @@ static int spi_nor_setup(struct spi_nor *nor,
 	return spi_nor_set_addr_width(nor);
 }
 
+/**
+ * spi_nor_init_default_params() - Default initialization of flash parameters
+ * and settings. Done for all flashes, regardless is they define SFDP tables
+ * or not.
+ * @nor:	pointer to a 'struct spi_nor'.
+ */
+static void spi_nor_init_default_params(struct spi_nor *nor)
+{
+	struct spi_nor_flash_parameter *params = nor->params;
+	const struct flash_info *info = nor->info;
+	struct device_node *np = spi_nor_get_flash_node(nor);
+
+	params->quad_enable = spi_nor_sr2_bit1_quad_enable;
+	params->set_4byte_addr_mode = spansion_set_4byte_addr_mode;
+	params->setup = spi_nor_default_setup;
+	params->otp.org = &info->otp_org;
+
+	/* Default to 16-bit Write Status (01h) Command */
+	nor->flags |= SNOR_F_HAS_16BIT_SR;
+
+	/* Set SPI NOR sizes. */
+	params->writesize = 1;
+	params->size = (u64)info->sector_size * info->n_sectors;
+	params->page_size = info->page_size;
+
+	if (!(info->flags & SPI_NOR_NO_FR)) {
+		/* Default to Fast Read for DT and non-DT platform devices. */
+		params->hwcaps.mask |= SNOR_HWCAPS_READ_FAST;
+
+		/* Mask out Fast Read if not requested at DT instantiation. */
+		if (np && !of_property_read_bool(np, "m25p,fast-read"))
+			params->hwcaps.mask &= ~SNOR_HWCAPS_READ_FAST;
+	}
+
+	/* (Fast) Read settings. */
+	params->hwcaps.mask |= SNOR_HWCAPS_READ;
+	spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ],
+				  0, 0, SPINOR_OP_READ,
+				  SNOR_PROTO_1_1_1);
+
+	if (params->hwcaps.mask & SNOR_HWCAPS_READ_FAST)
+		spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ_FAST],
+					  0, 8, SPINOR_OP_READ_FAST,
+					  SNOR_PROTO_1_1_1);
+	/* Page Program settings. */
+	params->hwcaps.mask |= SNOR_HWCAPS_PP;
+	spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP],
+				SPINOR_OP_PP, SNOR_PROTO_1_1_1);
+}
+
 /**
  * spi_nor_manufacturer_init_params() - Initialize the flash's parameters and
  * settings based on MFR register and ->default_init() hook.
@@ -2609,43 +2659,8 @@ static void spi_nor_info_init_params(struct spi_nor *nor)
 	struct spi_nor_flash_parameter *params = nor->params;
 	struct spi_nor_erase_map *map = &params->erase_map;
 	const struct flash_info *info = nor->info;
-	struct device_node *np = spi_nor_get_flash_node(nor);
 	u8 i, erase_mask;
 
-	/* Initialize default flash parameters and settings. */
-	params->quad_enable = spi_nor_sr2_bit1_quad_enable;
-	params->set_4byte_addr_mode = spansion_set_4byte_addr_mode;
-	params->setup = spi_nor_default_setup;
-	params->otp.org = &info->otp_org;
-
-	/* Default to 16-bit Write Status (01h) Command */
-	nor->flags |= SNOR_F_HAS_16BIT_SR;
-
-	/* Set SPI NOR sizes. */
-	params->writesize = 1;
-	params->size = (u64)info->sector_size * info->n_sectors;
-	params->page_size = info->page_size;
-
-	if (!(info->flags & SPI_NOR_NO_FR)) {
-		/* Default to Fast Read for DT and non-DT platform devices. */
-		params->hwcaps.mask |= SNOR_HWCAPS_READ_FAST;
-
-		/* Mask out Fast Read if not requested at DT instantiation. */
-		if (np && !of_property_read_bool(np, "m25p,fast-read"))
-			params->hwcaps.mask &= ~SNOR_HWCAPS_READ_FAST;
-	}
-
-	/* (Fast) Read settings. */
-	params->hwcaps.mask |= SNOR_HWCAPS_READ;
-	spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ],
-				  0, 0, SPINOR_OP_READ,
-				  SNOR_PROTO_1_1_1);
-
-	if (params->hwcaps.mask & SNOR_HWCAPS_READ_FAST)
-		spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ_FAST],
-					  0, 8, SPINOR_OP_READ_FAST,
-					  SNOR_PROTO_1_1_1);
-
 	if (info->flags & SPI_NOR_DUAL_READ) {
 		params->hwcaps.mask |= SNOR_HWCAPS_READ_1_1_2;
 		spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ_1_1_2],
@@ -2674,11 +2689,6 @@ static void spi_nor_info_init_params(struct spi_nor *nor)
 					  SNOR_PROTO_8_8_8_DTR);
 	}
 
-	/* Page Program settings. */
-	params->hwcaps.mask |= SNOR_HWCAPS_PP;
-	spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP],
-				SPINOR_OP_PP, SNOR_PROTO_1_1_1);
-
 	if (info->flags & SPI_NOR_OCTAL_DTR_PP) {
 		params->hwcaps.mask |= SNOR_HWCAPS_PP_8_8_8_DTR;
 		/*
@@ -2823,6 +2833,8 @@ static int spi_nor_init_params(struct spi_nor *nor)
 	if (!nor->params)
 		return -ENOMEM;
 
+	spi_nor_init_default_params(nor);
+
 	spi_nor_info_init_params(nor);
 
 	spi_nor_manufacturer_init_params(nor);
-- 
2.25.1


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

[PATCH v2 27/35] mtd: spi-nor: core: Init flash params based on SFDP first for new flash additions

From: Tudor Ambarus <hidden>
Date: 2021-07-27 06:38:01

Remove the spagetti way of initializing flash parameters and settings,
at least for the new flash additions (for now). All flash entries should
be converted to either use SPI_NOR_PARSE_SFDP or SPI_NOR_SKIP_SFDP.
SPI_NOR_SKIP_SFDP should be set either when the SFDP tables are completely
wrong and we can't parse relevant data, or when the SFDP tables are not
defined at all, or when RDSFDP command is not supported by the flash.
After all the flash entries will be converted to use these flags and after
the default_init() hook will be removed, the
spi_nor_init_params_deprecated() will be replaced by
spi_nor_info_init_params(). The flash parameters and settings will be
initialized either by parsing SFDP, or via the flash info flags.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c | 103 +++++++++++++++++++++++++------------
 1 file changed, 70 insertions(+), 33 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 9193317f897d..ef06a8d6abb8 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2627,28 +2627,6 @@ static void spi_nor_post_sfdp_fixups(struct spi_nor *nor)
 		nor->info->fixups->post_sfdp(nor);
 }
 
-/**
- * spi_nor_sfdp_init_params() - Initialize the flash's parameters and settings
- * based on JESD216 SFDP standard.
- * @nor:	pointer to a 'struct spi_nor'.
- *
- * The method has a roll-back mechanism: in case the SFDP parsing fails, the
- * legacy flash parameters and settings will be restored.
- */
-static void spi_nor_sfdp_init_params(struct spi_nor *nor)
-{
-	struct spi_nor_flash_parameter sfdp_params;
-
-	memcpy(&sfdp_params, nor->params, sizeof(sfdp_params));
-
-	if (!spi_nor_parse_sfdp(nor))
-		return spi_nor_post_sfdp_fixups(nor);
-
-	memcpy(nor->params, &sfdp_params, sizeof(*nor->params));
-	nor->addr_width = 0;
-	nor->flags &= ~SNOR_F_4B_OPCODES;
-}
-
 /**
  * spi_nor_info_init_params() - Initialize the flash's parameters and settings
  * based on nor->info data.
@@ -2722,6 +2700,39 @@ static void spi_nor_info_init_params(struct spi_nor *nor)
 	spi_nor_init_uniform_erase_map(map, erase_mask, params->size);
 }
 
+/**
+ * spi_nor_sfdp_init_params() - Initialize the flash's parameters and settings
+ * based on JESD216 SFDP standard.
+ * @nor:	pointer to a 'struct spi_nor'.
+ *
+ * The method has a roll-back mechanism: in case the SFDP parsing fails, the
+ * legacy flash parameters and settings will be restored.
+ */
+static void spi_nor_sfdp_init_params(struct spi_nor *nor,
+				     bool treat_id_collisions)
+{
+	struct spi_nor_flash_parameter sfdp_params;
+
+	memcpy(&sfdp_params, nor->params, sizeof(sfdp_params));
+
+	if (!spi_nor_parse_sfdp(nor))
+		return spi_nor_post_sfdp_fixups(nor);
+
+	memcpy(nor->params, &sfdp_params, sizeof(*nor->params));
+	nor->addr_width = 0;
+	nor->flags &= ~SNOR_F_4B_OPCODES;
+
+	if (!treat_id_collisions)
+		return;
+	/*
+	 * Fallback to flash info params init in case the SFDP parsing fails.
+	 * Used to handle ID collisions between flashes that define the SFDP
+	 * tables and flashes that don't.
+	 */
+	spi_nor_info_init_params(nor);
+	spi_nor_manufacturer_init_params(nor);
+}
+
 /**
  * spi_nor_late_init_params() - Late initialization of default flash parameters.
  * @nor:	pointer to a 'struct spi_nor'
@@ -2797,7 +2808,9 @@ static void spi_nor_nonsfdp_flags_init(struct spi_nor *nor)
 }
 
 /**
- * spi_nor_init_params() - Initialize the flash's parameters and settings.
+ * spi_nor_init_params_deprecated() - Initialize the flash's parameters and
+ * settings. The function is deprecated, it will be removed and replaced with
+ * spi_nor_info_init_params().
  * @nor:	pointer to a 'struct spi_nor'.
  *
  * The flash parameters and settings are initialized based on a sequence of
@@ -2821,11 +2834,40 @@ static void spi_nor_nonsfdp_flags_init(struct spi_nor *nor)
  *    Please note that there are ->post_{bfpt, sfdp}() fixup hooks that can
  *    overwrite the flash parameters and settings immediately after table
  *    parsing.
+ */
+static void spi_nor_init_params_deprecated(struct spi_nor *nor)
+{
+	spi_nor_info_init_params(nor);
+	spi_nor_manufacturer_init_params(nor);
+
+	if ((nor->info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+				 SPI_NOR_OCTAL_READ | SPI_NOR_OCTAL_DTR_READ)) &&
+	    !(nor->info->flags & SPI_NOR_SKIP_SFDP))
+		spi_nor_sfdp_init_params(nor, false);
+}
+
+/**
+ * spi_nor_init_params() - Initialize the flash's parameters and settings.
+ * @nor:	pointer to a 'struct spi_nor'.
+ *
+ * The flash parameters and settings are initialized based on a sequence of
+ * calls that are ordered by priority:
+ *
+ * 1/ Default flash parameters initialization. The initializations are done
+ *    for all the flashes, regardless if the support SFDP or not.
+ *		spi_nor_init_default_params()
+ * which can be overwritten by:
  *
+ * 2/ SFDP based or the deprecated way of initializing flash parameters.
+ * Ideally at this step the flash parameters init will be done either by
+ * parsing SFDP, where supported, or statically via flash_info flags.
+ *		spi_nor_sfdp_init_params() or spi_nor_init_params_deprecated()
  * which can be overwritten by:
- * 4/ Late flash parameters initialization, used to initialize flash
+ *
+ * 3/ Late flash parameters initialization, used to initialize flash
  * parameters that are not declared in the JESD216 SFDP standard.
  *		spi_nor_late_init_params()
+ *
  */
 static int spi_nor_init_params(struct spi_nor *nor)
 {
@@ -2835,15 +2877,10 @@ static int spi_nor_init_params(struct spi_nor *nor)
 
 	spi_nor_init_default_params(nor);
 
-	spi_nor_info_init_params(nor);
-
-	spi_nor_manufacturer_init_params(nor);
-
-	if ((nor->info->flags & (SPI_NOR_PARSE_SFDP |
-				 SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-				 SPI_NOR_OCTAL_READ | SPI_NOR_OCTAL_DTR_READ)) &&
-	    !(nor->info->flags & SPI_NOR_SKIP_SFDP))
-		spi_nor_sfdp_init_params(nor);
+	if (nor->info->flags & SPI_NOR_PARSE_SFDP)
+		spi_nor_sfdp_init_params(nor, true);
+	else
+		spi_nor_init_params_deprecated(nor);
 
 	spi_nor_late_init_params(nor);
 
-- 
2.25.1


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

[PATCH v2 28/35] mtd: spi-nor: sst: sst26vf064b: Use SPI_NOR_PARSE_SFDP

From: Tudor Ambarus <hidden>
Date: 2021-07-27 06:46:13

Get rid of the static initialization of the flash parameters and
init them when parsing SFDP.
Generated a 256 Kbyte random data and did an erase, write, read back
and compare test. The flash uses for reads SPINOR_OP_READ_1_4_4 0xeb,
for erases SPINOR_OP_BE_4K 0x20, and for writes SPINOR_OP_PP 0x02.

Signed-off-by: Tudor Ambarus <redacted>
---
root@sama5d2-xplained:~# find / -iname spi-nor
/sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor
/sys/devices/platform/ahb/ahb:apb/f8000000.spi/spi_master/spi0/spi0.0/spi-nor
/sys/bus/spi/drivers/spi-nor
root@sama5d2-xplained:~# ls -al /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor
total 0
drwxr-xr-x 2 root root    0 Mar  9 14:45 .
drwxr-xr-x 6 root root    0 Mar  9 14:34 ..
-r--r--r-- 1 root root 4096 Mar  9 14:45 jedec_id
-r--r--r-- 1 root root 4096 Mar  9 14:45 manufacturer
-r--r--r-- 1 root root 4096 Mar  9 14:45 partname
-r--r--r-- 1 root root    0 Mar  9 14:45 sfdp
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/jedec_id
bf2643
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/manufacturer
sst
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/partname
sst26vf064b
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/sfdp > sst26vf064b-sfdp
root@sama5d2-xplained:~# hexdump sst26vf064b-sfdp 
0000000 4653 5044 0106 ff02 0600 1001 0030 ff00
0000010 0081 0601 0100 ff00 00bf 1801 0200 0100
0000020 ffff ffff ffff ffff ffff ffff ffff ffff
0000030 20fd fff1 ffff 03ff eb44 6b08 3b08 bb80
0000040 fffe ffff ffff ff00 ffff 0b44 200c d80d
0000050 d80f d810 9120 2448 6f80 811d 0fed 3877
0000060 b030 b030 fff7 ffff c229 ff5c 30f0 80c0
0000070 ffff ffff ffff ffff ffff ffff ffff ffff
*
0000100 00ff ff04 7ff3 0000 7ff5 0000 fff9 007d
0000110 7ff5 0000 7ff3 0000 ffff ffff ffff ffff
0000120 ffff ffff ffff ffff ffff ffff ffff ffff
*
0000200 26bf ff43 5fb9 fffd f230 f360 ff32 120a
0000210 4623 0fff 3219 190f ff19 ffff ffff ffff
0000220 6600 3899 05ff 3501 0406 3202 30b0 4272
0000230 e88d 8898 85a5 9fc0 5aaf ffff ec06 0c06
0000240 0300 0b08 ffff ffff 07ff ffff 0202 06ff
0000250 0003 fdfd 0704 fc00 0003 fefe 0202 0e07
0000260

 drivers/mtd/spi-nor/sst.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/mtd/spi-nor/sst.c b/drivers/mtd/spi-nor/sst.c
index eeb10766b70e..c3bdaa6af2ec 100644
--- a/drivers/mtd/spi-nor/sst.c
+++ b/drivers/mtd/spi-nor/sst.c
@@ -81,8 +81,7 @@ static const struct flash_info sst_parts[] = {
 			      SPI_NOR_QUAD_READ) },
 	{ "sst26vf016b", INFO(0xbf2641, 0, 64 * 1024, 32,
 			      SECT_4K | SPI_NOR_DUAL_READ) },
-	{ "sst26vf064b", INFO(0xbf2643, 0, 64 * 1024, 128,
-			      SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+	{ "sst26vf064b", INFO(0xbf2643, 0, 64 * 1024, 128, SPI_NOR_PARSE_SFDP |
 			      SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
 		.late_init = sst26vf_late_init},
 };
-- 
2.25.1


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

[PATCH v2 29/35] mtd: spi-nor: winbond: w25q256jvm: Use SPI_NOR_PARSE_SFDP

From: Tudor Ambarus <hidden>
Date: 2021-07-27 06:47:22

Get rid of the static initialization of the flash parameters and
init them when parsing SFDP.
Generated a 256 Kbyte random data and did an erase, write, read back
and compare test. The flash uses for reads SPINOR_OP_READ_1_4_4 0xeb,
for erases SPINOR_OP_BE_4K 0x20, and for writes SPINOR_OP_PP 0x02.

Signed-off-by: Tudor Ambarus <redacted>
---
root@sama5d2-xplained:~# find / -iname spi-nor
find: '/proc/383': No such file or directory
/sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor
/sys/devices/platform/ahb/ahb:apb/f8000000.spi/spi_master/spi0/spi0.0/spi-nor
/sys/bus/spi/drivers/spi-nor
root@sama5d2-xplained:~# ls -al /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor
total 0
drwxr-xr-x 2 root root    0 Mar  9 14:16 .
drwxr-xr-x 6 root root    0 Mar  9 14:15 ..
-r--r--r-- 1 root root 4096 Mar  9 14:17 jedec_id
-r--r--r-- 1 root root 4096 Mar  9 14:17 manufacturer
-r--r--r-- 1 root root 4096 Mar  9 14:17 partname
-r--r--r-- 1 root root    0 Mar  9 14:17 sfdp
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/jedec_id
ef7019
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/manufacturer
winbond
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/partname
w25q256jvm
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/sfdp > sfdp-w25q256jvm
root@sama5d2-xplained:~# hexdump sfdp-w25q256jvm
0000000 4653 5044 0105 ff00 0500 1001 0080 ff00
0000010 ffff ffff ffff ffff ffff ffff ffff ffff
*
0000080 20e5 fffb ffff 0fff eb44 6b08 3b08 bb42
0000090 fffe ffff ffff 0000 ffff eb40 200c 520f
00000a0 d810 0000 0236 00a6 ea82 d314 63e9 3376
00000b0 757a 757a a2f7 5cd5 f719 ff4d 70e9 a5f9
00000c0

 drivers/mtd/spi-nor/winbond.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c
index 6be45d2291c6..cbfc41b261d7 100644
--- a/drivers/mtd/spi-nor/winbond.c
+++ b/drivers/mtd/spi-nor/winbond.c
@@ -95,7 +95,7 @@ static const struct flash_info winbond_parts[] = {
 			  SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
 	  .fixups = &w25q256_fixups },
 	{ "w25q256jvm", INFO(0xef7019, 0, 64 * 1024, 512,
-			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+			     SPI_NOR_PARSE_SFDP) },
 	{ "w25q256jw", INFO(0xef6019, 0, 64 * 1024, 512,
 			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 	{ "w25m512jv", INFO(0xef7119, 0, 64 * 1024, 1024,
-- 
2.25.1


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

[PATCH v2 30/35] mtd: spi-nor: issi: is25lp256: Use SPI_NOR_PARSE_SFDP

From: Tudor Ambarus <hidden>
Date: 2021-07-27 06:51:50

Get rid of the static initialization of the flash parameters and
init them when parsing SFDP.
Generated a 256 Kbyte random data and did an erase, write, read back
and compare test. The flash uses for reads SPINOR_OP_READ_1_4_4_4B 0xec,
for erases SPINOR_OP_BE_4K_4B 0x21, and for writes SPINOR_OP_PP_4B 0x12.

Signed-off-by: Tudor Ambarus <redacted>
---
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/jedec_id
9d6019
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/manufacturer
issi
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/partname
is25lp256
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/sfdp > sfdp-issi
root@sama5d2-xplained:~# hexdump sfdp-issi 
0000000 4653 5044 0106 ff01 0600 1001 0030 ff00
0000010 059d 0301 0080 0200 ffff ffff ffff ffff
0000020 ffff ffff ffff ffff ffff ffff ffff ffff
0000030 20e5 fff9 ffff 0fff eb44 6b08 3b08 bb80
0000040 fffe ffff ffff ff00 ffff eb44 200c 520f
0000050 d810 ff00 4a23 00c9 d882 ce11 cdcc 4668
0000060 757a 757a aef7 5cd5 424a ff2c 30f0 a9f2
0000070 ffff ffff ffff ffff ffff ffff ffff ffff
0000080 3600 2300 f99e 64c0 ef8f ffff          
000008c

 drivers/mtd/spi-nor/issi.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mtd/spi-nor/issi.c b/drivers/mtd/spi-nor/issi.c
index aeff8f60cbae..4f778f5d6adb 100644
--- a/drivers/mtd/spi-nor/issi.c
+++ b/drivers/mtd/spi-nor/issi.c
@@ -45,7 +45,7 @@ static const struct flash_info issi_parts[] = {
 	{ "is25lp128",  INFO(0x9d6018, 0, 64 * 1024, 256,
 			     SECT_4K | SPI_NOR_DUAL_READ) },
 	{ "is25lp256",  INFO(0x9d6019, 0, 64 * 1024, 512,
-			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
+			     SPI_NOR_PARSE_SFDP)
 		.fixups = &is25lp256_fixups,
 		.late_init = snor_f_4b_opcodes, },
 	{ "is25wp032",  INFO(0x9d7016, 0, 64 * 1024,  64,
-- 
2.25.1


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

[PATCH v2 31/35] mtd: spi-nor: spansion: s25fl256s0: Skip SFDP parsing

From: Tudor Ambarus <hidden>
Date: 2021-07-27 06:56:12

s25fl256s0 does not define the SFDP tables nor implements the
RDSFDP 0x5a command. Skip the SFDP parsing in order to avoid
issuing an unsupported command to the flash.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/spansion.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c
index af10833f56d8..7fe4e31f8c3e 100644
--- a/drivers/mtd/spi-nor/spansion.c
+++ b/drivers/mtd/spi-nor/spansion.c
@@ -209,8 +209,8 @@ static const struct flash_info spansion_parts[] = {
 			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			      USE_CLSR) },
 	{ "s25fl256s0", INFO6(0x010219, 0x4d0080, 256 * 1024, 128,
-			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-			      USE_CLSR) },
+			      SPI_NOR_SKIP_SFDP | SPI_NOR_DUAL_READ |
+			      SPI_NOR_QUAD_READ | USE_CLSR) },
 	{ "s25fl256s1", INFO6(0x010219, 0x4d0180, 64 * 1024, 512,
 			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			      USE_CLSR) },
-- 
2.25.1


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

[PATCH v2 32/35] mtd: spi-nor: gigadevice: gd25q256: Use SPI_NOR_PARSE_SFDP

From: Tudor Ambarus <hidden>
Date: 2021-07-27 07:00:35

Get rid of the static initialization of the flash parameters and
init them when parsing SFDP.
Generated a 256 Kbyte random data and did an erase, write, read back
and compare test. The flash uses for reads SPINOR_OP_READ_1_4_4_4B 0xec,
for erases SPINOR_OP_BE_4K_4B 0x21, and for writes SPINOR_OP_PP_1_1_4_4B
0x34.

Signed-off-by: Tudor Ambarus <redacted>
---
root@sama5d2-xplained:~# find / -iname spi-nor
/sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor
/sys/devices/platform/ahb/ahb:apb/f8000000.spi/spi_master/spi0/spi0.0/spi-nor
/sys/bus/spi/drivers/spi-nor
/sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-norroot@sama5d2-xplained:~# /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor^C
root@sama5d2-xplained:~# ls -al /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor
total 0
drwxr-xr-x 2 root root    0 Mar  9 15:57 .
drwxr-xr-x 6 root root    0 Mar  9 15:10 ..
-r--r--r-- 1 root root 4096 Mar  9 15:57 jedec_id
-r--r--r-- 1 root root 4096 Mar  9 15:57 manufacturer
-r--r--r-- 1 root root 4096 Mar  9 15:57 partname
-r--r--r-- 1 root root    0 Mar  9 15:57 sfdp
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/jedec_id
c84019
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/manufacturer
gigadevice
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/partname    
gd25q256
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/sfdp > gd25q256-sfdp
root@sama5d2-xplained:~# hexdump gd25q256-sfdp 
0000000 4653 5044 0106 ff02 0600 1001 0030 ff00
0000010 00c8 0301 0090 ff00 0084 0201 00c0 ff00
0000020 ffff ffff ffff ffff ffff ffff ffff ffff
0000030 20e5 fff3 ffff 0fff eb44 6b08 3b08 bb42
0000040 ffee ffff ffff ff00 ffff ff00 200c 520f
0000050 d810 ff00 6242 fec9 e982 5814 60ec 3306
0000060 757a 757a bd04 5cd5 0600 0044 5008 0100
0000070 ffff ffff ffff ffff ffff ffff ffff ffff
*
0000090 3600 2700 f99e 6477 cbfc ffff ffff ffff
00000a0 ffff ffff ffff ffff ffff ffff ffff ffff
*
00000c0 0eff fff0 5c21 ffdc                    
00000c8

 drivers/mtd/spi-nor/gigadevice.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/mtd/spi-nor/gigadevice.c b/drivers/mtd/spi-nor/gigadevice.c
index ff523fe734ef..f4cdd87893a7 100644
--- a/drivers/mtd/spi-nor/gigadevice.c
+++ b/drivers/mtd/spi-nor/gigadevice.c
@@ -46,9 +46,8 @@ static const struct flash_info gigadevice_parts[] = {
 			   SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			   SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
 	{ "gd25q256", INFO(0xc84019, 0, 64 * 1024, 512,
-			   SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-			   SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB |
-			   SPI_NOR_TB_SR_BIT6)
+			   SPI_NOR_PARSE_SFDP | SPI_NOR_HAS_LOCK |
+			   SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6)
 		.fixups = &gd25q256_fixups,
 		.late_init = snor_f_4b_opcodes,	},
 };
-- 
2.25.1


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

[PATCH v2 33/35] mtd: spi-nor: micron-st: n25q256a: Use SPI_NOR_PARSE_SFDP

From: Tudor Ambarus <hidden>
Date: 2021-07-27 07:05:18

Get rid of the static initialization of the flash parameters and
init them when parsing SFDP.
Generated a 256 Kbyte random data and did an erase, write, read back
and compare test. The flash uses for reads SPINOR_OP_READ_1_4_4 0xeb,
for erases SPINOR_OP_BE_4K 0x20, and for writes SPINOR_OP_PP 0x02.

Signed-off-by: Tudor Ambarus <redacted>
---
root@sama5d2-xplained:~# find / -iname spi-nor 
/sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor
/sys/devices/platform/ahb/ahb:apb/f8000000.spi/spi_master/spi0/spi0.0/spi-nor
/sys/bus/spi/drivers/spi-nor
^C
root@sama5d2-xplained:~# ls -al /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor
total 0
drwxr-xr-x 2 root root    0 Mar  9 16:14 .
drwxr-xr-x 6 root root    0 Mar  9 16:13 ..
-r--r--r-- 1 root root 4096 Mar  9 16:14 jedec_id
-r--r--r-- 1 root root 4096 Mar  9 16:14 manufacturer
-r--r--r-- 1 root root 4096 Mar  9 16:14 partname
-r--r--r-- 1 root root    0 Mar  9 16:14 sfdp
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/jedec_id
20ba19
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/manufacturer
st
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/partnme     
cat: '/sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/partnme': No such file or directory
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/partname
n25q256a
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/sfdp > n25q256a-sfdp
root@sama5d2-xplained:~# hexdump n25q256a-sfdp
0000000 4653 5044 0100 ff00 0000 0901 0030 ff00
0000010 ffff ffff ffff ffff ffff ffff ffff ffff
*
0000030 20e5 fffb ffff 0fff eb29 6b27 3b08 bb27
0000040 ffff ffff ffff bb27 ffff eb29 200c d810
0000050 0000 0000                              
0000054

 drivers/mtd/spi-nor/micron-st.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c
index 31ebd4c9b431..c685dc6c5aff 100644
--- a/drivers/mtd/spi-nor/micron-st.c
+++ b/drivers/mtd/spi-nor/micron-st.c
@@ -156,9 +156,8 @@ static const struct flash_info st_parts[] = {
 			       SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
 			       SPI_NOR_QUAD_READ)
 	  .late_init = snor_f_4b_opcodes, },
-	{ "n25q256a",    INFO(0x20ba19, 0, 64 * 1024,  512, SECT_4K |
-			      USE_FSR | SPI_NOR_DUAL_READ |
-			      SPI_NOR_QUAD_READ) },
+	{ "n25q256a",    INFO(0x20ba19, 0, 64 * 1024,  512,
+			      SPI_NOR_PARSE_SFDP | USE_FSR) },
 	{ "mt25qu256a",  INFO6(0x20bb19, 0x104400, 64 * 1024,  512,
 			       SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
 			       SPI_NOR_QUAD_READ)
-- 
2.25.1


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

[PATCH v2 34/35] mtd: spi-nor: macronix: mx25l25635e: Use SPI_NOR_PARSE_SFDP

From: Tudor Ambarus <hidden>
Date: 2021-07-27 07:10:14

Get rid of the static initialization of the flash parameters and
init them when parsing SFDP.
Generated a 256 Kbyte random data and did an erase, write, read back
and compare test. The flash uses for reads SPINOR_OP_READ_1_4_4_4B 0xec,
for erases SPINOR_OP_BE_4K_4B 0x21, and for writes SPINOR_OP_PP_1_4_4_4B
0x3e.

Signed-off-by: Tudor Ambarus <redacted>
---
root@sama5d2-xplained:~# find / -iname spi-nor
find: '/proc/381': No such file or directory
/sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor
/sys/devices/platform/ahb/ahb:apb/f8000000.spi/spi_master/spi0/spi0.0/spi-nor
/sys/bus/spi/drivers/spi-nor
root@sama5d2-xplained:~# ls -al /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor
total 0
drwxr-xr-x 2 root root    0 Mar  9 16:27 .
drwxr-xr-x 6 root root    0 Mar  9 16:26 ..
-r--r--r-- 1 root root 4096 Mar  9 16:27 jedec_id
-r--r--r-- 1 root root 4096 Mar  9 16:27 manufacturer
-r--r--r-- 1 root root 4096 Mar  9 16:27 partname
-r--r--r-- 1 root root    0 Mar  9 16:27 sfdp
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/jedec_id
c22019
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/manufacturer
macronix
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/partname    
mx25l25635e
root@sama5d2-xplained:~# cat /sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/sfdp > mx25l25635e-sfdp
root@sama5d2-xplained:~# hexdump mx25l25635e-sfdp
0000000 4653 5044 0106 ff02 0600 1001 0030 ff00
0000010 00c2 0401 0110 ff00 0084 0201 00c0 ff00
0000020 ffff ffff ffff ffff ffff ffff ffff ffff
0000030 20e5 fffb ffff 0fff eb44 6b08 3b08 bb04
0000040 fffe ffff ffff ff00 ffff eb44 200c 520f
0000050 d810 ff00 59d6 00dd 9f82 db03 0344 3867
0000060 b030 b030 bdf7 5cd5 9e4a ff29 50f0 85f9
0000070 ffff ffff ffff ffff ffff ffff ffff ffff
*
00000c0 8f7f ffff 5c21 ffdc ffff ffff ffff ffff
00000d0 ffff ffff ffff ffff ffff ffff ffff ffff
*
0000110 3600 2700 f99d 64c0 cb85 ffff ffff ffff
0000120

 drivers/mtd/spi-nor/macronix.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c
index 9709eb68b613..b4eaf22ee388 100644
--- a/drivers/mtd/spi-nor/macronix.c
+++ b/drivers/mtd/spi-nor/macronix.c
@@ -103,7 +103,7 @@ static const struct flash_info macronix_parts[] = {
 			      SECT_4K | SPI_NOR_DUAL_READ |
 			      SPI_NOR_QUAD_READ) },
 	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512,
-			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
+			      SPI_NOR_PARSE_SFDP)
 		.fixups = &mx25l25635_fixups },
 	{ "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K)
 		.late_init = snor_f_4b_opcodes, },
-- 
2.25.1


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

[PATCH v2 35/35] docs: mtd: spi-nor: Add details about how to propose a new flash addition

From: Tudor Ambarus <hidden>
Date: 2021-07-27 07:14:24

Add some guideliness on how to propose a new flash addition.

Signed-off-by: Tudor Ambarus <redacted>
---
 Documentation/driver-api/mtd/spi-nor.rst | 65 ++++++++++++++++++++++++
 1 file changed, 65 insertions(+)
diff --git a/Documentation/driver-api/mtd/spi-nor.rst b/Documentation/driver-api/mtd/spi-nor.rst
index 4a3adca417fd..ffb8d97a2766 100644
--- a/Documentation/driver-api/mtd/spi-nor.rst
+++ b/Documentation/driver-api/mtd/spi-nor.rst
@@ -66,3 +66,68 @@ when you want to write a new driver for a SPI NOR controller.
 Another API is spi_nor_restore(), this is used to restore the status of SPI
 flash chip such as addressing mode. Call it whenever detach the driver from
 device or reboot the system.
+
+Part IV - How to propose a new flash addition?
+----------------------------------------------
+
+First we have to clarify where the new flash_info entry will reside. Typically
+each manufacturer have their own driver and the new flash will be placed in that
+specific manufacturer driver. There are cases however, where special care has to
+be taken. In case of flash ID collisions between different manufacturers, the
+place to add the new flash is in the manuf-id-collisions.c driver. ID collisions
+between flashes of the same manufacturer should be handled in their own
+manufacturer driver, macronix being an example. There will be a single
+flash_info entry for all the ID collisions of the same ID.
+
+manuf-id-collisions.c is the place to add new flash additions where the
+manufacturer is ignorant enough to not implement the ID continuation scheme
+that is described in the JEP106 JEDEC Standard. One has to dump its flash ID and
+compare it with the flash's manufacturer identification code that is defined in
+the JEP106 JEDEC Standard. If the manufacturer ID is defined in bank two or
+higher and the manufacturer does not implement the ID continuation scheme, then
+it is likely that the flash ID will collide with a manufacturer from bank one or
+with other manufacturer from other bank that does not implement the ID
+continuation scheme as well.
+
+flash_info entries will be added in a first come, first served manner. If there
+are ID collisions, differentiation between flashes will be done at runtime if
+possible. Where runtime differentiation is not possible, new compatibles will be
+introduced, but this will be done as a last resort.
+
+New flash additions that support the SFDP standard should be declared using
+SPI_NOR_PARSE_SFDP. Support that can be discovered when parsing SFDP should not
+be duplicated by explicit flags at flash declaration. All the SFDP flash
+parameters and settings will be discovered when parsing SFDP. There are
+flash_info flags that indicate support that is not SFDP discoverable. These
+flags initialize non SFDP support in the spi_nor_nonsfdp_flags_init() method.
+SPI_NOR_PARSE_SFDP is usually followed by other flash_info flags from the
+aforementioned function. Sometimes manufacturers wrongly define some fields in
+the SFDP tables. If that's the case, SFDP data can be amended with the fixups()
+hooks. It is not common, but if the SFDP tables are entirely wrong, and it does
+not worth the hassle to tweak the SFDP parameters by using the fixups hooks, or
+if the flash does not define the SFDP tables at all, then one can statically
+init the flash with the SPI_NOR_SKIP_SFDP flag and specify the rest of the flash
+capabilities with the flash info flags.
+
+With time we want to convert all flashes to either use SPI_NOR_PARSE_SFDP or
+SPI_NOR_SKIP_SFDP and stop triggering the SFDP parsing with the
+SPI_NOR_{DUAL, QUAD, OCTAL*}_READ flags. There are flashes that support QUAD
+mode but do not support the RDSFDP command, we should avoid issuing unsupported
+commands to flashes where possible. It is unlikely that RDSFDP will cause any
+problems, but still, it's better to avoid it. There are cases however of flash
+ID collisions between flashes that define the SFDP tables and flashes that don't
+(again, macronix). We usually differentiate between the two by issuing the
+RDSFDP command. In such a case one has to declare the SPI_NOR_PARSE_SFDP
+together with all the relevant flags from spi_nor_nonsfdp_flags_init() for the
+SFDP compatible flash, but should also declare the relevant flags that are used
+in the spi_nor_info_init_params() method in order to init support that can't be
+discovered via SFDP for the non-SFDP compatible flash.
+
+Every new flash addition that define the SFDP tables, should hexdump its SFDP
+tables in the patch's comment section below the --- line, so that we can
+reference it in case of ID collisions.
+
+Every flash_info flag declared should be tested. Typically one uses the
+mtd-utils and does an erase, verify erase, write, read back and compare test.
+Locking and other flags that are declared in the flash_info entry and used in
+the spi_nor_nonsfdp_flags_init() should be tested as well.
-- 
2.25.1


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

Re: [PATCH v2 20/35] mtd: spi-nor: core: Use container_of to get the pointer to struct spi_nor

From: Rasmus Villemoes <linux@rasmusvillemoes.dk>
Date: 2021-07-27 07:46:29

On 27/07/2021 06.52, Tudor Ambarus wrote:
quoted hunk
Get the pointer to the containing struct spi_nor by using container_of.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c | 1 -
 drivers/mtd/spi-nor/core.h | 2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 9885d434ea83..5c8cffb5e6f2 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -3175,7 +3175,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 
 	if (!mtd->name)
 		mtd->name = dev_name(dev);
-	mtd->priv = nor;
 	mtd->type = MTD_NORFLASH;
 	mtd->writesize = nor->params->writesize;
 	mtd->flags = MTD_CAP_NORFLASH;
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 987797a789c8..8fddc685d2d3 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -557,7 +557,7 @@ void spi_nor_otp_init(struct spi_nor *nor);
 
 static struct spi_nor __maybe_unused *mtd_to_spi_nor(struct mtd_info *mtd)
 {
Somewhat unrelated, but while you're here, why not get rid of that
__maybe_unused and make this an ordinary "static inline"?

Rasmus

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

Re: [PATCH v2 35/35] docs: mtd: spi-nor: Add details about how to propose a new flash addition

From: Michael Walle <hidden>
Date: 2021-07-27 07:56:40

Am 2021-07-27 06:52, schrieb Tudor Ambarus:
quoted hunk
Add some guideliness on how to propose a new flash addition.

Signed-off-by: Tudor Ambarus <redacted>
---
 Documentation/driver-api/mtd/spi-nor.rst | 65 ++++++++++++++++++++++++
 1 file changed, 65 insertions(+)
diff --git a/Documentation/driver-api/mtd/spi-nor.rst
b/Documentation/driver-api/mtd/spi-nor.rst
index 4a3adca417fd..ffb8d97a2766 100644
--- a/Documentation/driver-api/mtd/spi-nor.rst
+++ b/Documentation/driver-api/mtd/spi-nor.rst
[..]
+Every new flash addition that define the SFDP tables, should hexdump 
its SFDP
+tables in the patch's comment section below the --- line, so that we 
can
+reference it in case of ID collisions.
Nice, but could you add some guidelines how to do it? That is the exact
commands, maybe with a notice one should use these whenever possible. I
want to prevent having all sorts of variations of the output and I want
to be able to reverse the operation and verify it.

# xxd -p /path/to/sfdp
# md5sum /path/to/sfdp
# cat /path/to/jedec_id
# cat /path/to/partname
# cat /path/to/manufacturer

-michael

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

Re: [PATCH v2 35/35] docs: mtd: spi-nor: Add details about how to propose a new flash addition

From: <hidden>
Date: 2021-07-27 08:15:23

On 7/27/21 10:22 AM, Michael Walle wrote:
EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe

Am 2021-07-27 06:52, schrieb Tudor Ambarus:
quoted
Add some guideliness on how to propose a new flash addition.

Signed-off-by: Tudor Ambarus <redacted>
---
 Documentation/driver-api/mtd/spi-nor.rst | 65 ++++++++++++++++++++++++
 1 file changed, 65 insertions(+)
diff --git a/Documentation/driver-api/mtd/spi-nor.rst
b/Documentation/driver-api/mtd/spi-nor.rst
index 4a3adca417fd..ffb8d97a2766 100644
--- a/Documentation/driver-api/mtd/spi-nor.rst
+++ b/Documentation/driver-api/mtd/spi-nor.rst
[..]
quoted
+Every new flash addition that define the SFDP tables, should hexdump
its SFDP
+tables in the patch's comment section below the --- line, so that we
can
+reference it in case of ID collisions.
Nice, but could you add some guidelines how to do it? That is the exact
commands, maybe with a notice one should use these whenever possible. I
want to prevent having all sorts of variations of the output and I want
to be able to reverse the operation and verify it.
ok, will do
# xxd -p /path/to/sfdp
# md5sum /path/to/sfdp
maybe sha1sum here?
# cat /path/to/jedec_id
# cat /path/to/partname
# cat /path/to/manufacturer
Will add some short examples of mtd_debug and the erase, verify, write, read back
and compare too.

Do you have some locking test examples? I'll have to check those too.

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

Re: [PATCH v2 35/35] docs: mtd: spi-nor: Add details about how to propose a new flash addition

From: Michael Walle <hidden>
Date: 2021-07-27 08:52:02

Am 2021-07-27 10:09, schrieb Tudor.Ambarus@microchip.com:
On 7/27/21 10:22 AM, Michael Walle wrote:
quoted
EXTERNAL EMAIL: Do not click links or open attachments unless you know 
the content is safe

Am 2021-07-27 06:52, schrieb Tudor Ambarus:
quoted
Add some guideliness on how to propose a new flash addition.

Signed-off-by: Tudor Ambarus <redacted>
---
 Documentation/driver-api/mtd/spi-nor.rst | 65 
++++++++++++++++++++++++
 1 file changed, 65 insertions(+)
diff --git a/Documentation/driver-api/mtd/spi-nor.rst
b/Documentation/driver-api/mtd/spi-nor.rst
index 4a3adca417fd..ffb8d97a2766 100644
--- a/Documentation/driver-api/mtd/spi-nor.rst
+++ b/Documentation/driver-api/mtd/spi-nor.rst
[..]
quoted
+Every new flash addition that define the SFDP tables, should hexdump
its SFDP
+tables in the patch's comment section below the --- line, so that we
can
+reference it in case of ID collisions.
Nice, but could you add some guidelines how to do it? That is the 
exact
commands, maybe with a notice one should use these whenever possible. 
I
want to prevent having all sorts of variations of the output and I 
want
to be able to reverse the operation and verify it.
ok, will do
quoted
# xxd -p /path/to/sfdp
# md5sum /path/to/sfdp
maybe sha1sum here?
sure, that one doesn't really matter. any *sum will work.
quoted
# cat /path/to/jedec_id
# cat /path/to/partname
# cat /path/to/manufacturer
Will add some short examples of mtd_debug and the erase, verify,
write, read back
and compare too.

Do you have some locking test examples? I'll have to check those too.
Not really, I usually check the locking by looking at the BP bits,
but there is no easy method to look at them in linux.

-michael

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

Re: [PATCH v2 06/35] mtd: spi-nor: manuf-id-collisions: Add support for xt25f128b

From: Chris Morgan <hidden>
Date: 2021-07-27 15:55:09

On Tue, Jul 27, 2021 at 07:51:53AM +0300, Tudor Ambarus wrote:
quoted hunk
Flash does not support continuation codes and may collide with a flash
of other manufacturer, Intersil being an example .

Signed-off-by: Tudor Ambarus <redacted>
---
0000000 4653 5044 0100 ff01 0000 0901 0030 ff00
0000010 000b 0301 0060 ff00 ffff ffff ffff ffff
0000020 ffff ffff ffff ffff ffff ffff ffff ffff
0000030 20e5 fff1 ffff 07ff eb44 6b08 3b08 bb42
0000040 ffee ffff ffff ff00 ffff ff00 200c 520f
0000050 d810 ff00 ffff ffff ffff ffff ffff ffff
0000060 3600 2700 f99f 6477 e8d9 ffff

 drivers/mtd/spi-nor/manuf-id-collisions.c | 4 ++++
 1 file changed, 4 insertions(+)
diff --git a/drivers/mtd/spi-nor/manuf-id-collisions.c b/drivers/mtd/spi-nor/manuf-id-collisions.c
index bf7dba34f018..db31470ebf6a 100644
--- a/drivers/mtd/spi-nor/manuf-id-collisions.c
+++ b/drivers/mtd/spi-nor/manuf-id-collisions.c
@@ -13,6 +13,10 @@ static const struct flash_info id_collision_parts[] = {
 	{ "by25q128as", INFO(0x684018, 0, 64 * 1024, 256, SPI_NOR_SKIP_SFDP |
 			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			     SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
+
+	/* XTX (XTX Technology Limited) */
+	{ "xt25f128b", INFO(0x0b4018, 0, 64 * 1024, 256, SPI_NOR_PARSE_SFDP |
+			    SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
My apologies for being ignorant of this, but I'm not 100% sure of these
two values (SPI_NOR_HAS_LOCK and SPI_NOR_HAS_TB), even though I
included them in my original commit. Looking at the datasheet for this
I can see that there are 5 block protect bits (BP0 - BP4) corresponding
to status registers SR2 through SR6. Status register bits SR7 and SR8
correspond to "status register protect 0 and status register protect 1"
bits as well. The Rockchip engineer I was testing the SFC with did
not have these flags as well on their driver they were using for this
chip too. I have tested with and without, and they seem to work
regardless. Is there a way to know for sure if these should or should
not be here?

Here is a link to the datasheet I was working off of:
https://datasheet.lcsc.com/szlcsc/2005251034_XTX-XT25F128BSSIGT_C558844.pdf

When this is confirmed I'll be glad to provide my "Tested-by" line.

Thank you.
 };
 
 const struct spi_nor_manufacturer spi_nor_manuf_id_collisions = {
-- 
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v2 06/35] mtd: spi-nor: manuf-id-collisions: Add support for xt25f128b

From: <hidden>
Date: 2021-07-28 04:13:36

On 7/27/21 6:52 PM, Chris Morgan wrote:
EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe

On Tue, Jul 27, 2021 at 07:51:53AM +0300, Tudor Ambarus wrote:
quoted
Flash does not support continuation codes and may collide with a flash
of other manufacturer, Intersil being an example .

Signed-off-by: Tudor Ambarus <redacted>
---
0000000 4653 5044 0100 ff01 0000 0901 0030 ff00
0000010 000b 0301 0060 ff00 ffff ffff ffff ffff
0000020 ffff ffff ffff ffff ffff ffff ffff ffff
0000030 20e5 fff1 ffff 07ff eb44 6b08 3b08 bb42
0000040 ffee ffff ffff ff00 ffff ff00 200c 520f
0000050 d810 ff00 ffff ffff ffff ffff ffff ffff
0000060 3600 2700 f99f 6477 e8d9 ffff

 drivers/mtd/spi-nor/manuf-id-collisions.c | 4 ++++
 1 file changed, 4 insertions(+)
diff --git a/drivers/mtd/spi-nor/manuf-id-collisions.c b/drivers/mtd/spi-nor/manuf-id-collisions.c
index bf7dba34f018..db31470ebf6a 100644
--- a/drivers/mtd/spi-nor/manuf-id-collisions.c
+++ b/drivers/mtd/spi-nor/manuf-id-collisions.c
@@ -13,6 +13,10 @@ static const struct flash_info id_collision_parts[] = {
      { "by25q128as", INFO(0x684018, 0, 64 * 1024, 256, SPI_NOR_SKIP_SFDP |
                           SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
                           SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
+
+     /* XTX (XTX Technology Limited) */
+     { "xt25f128b", INFO(0x0b4018, 0, 64 * 1024, 256, SPI_NOR_PARSE_SFDP |
+                         SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
My apologies for being ignorant of this, but I'm not 100% sure of these
two values (SPI_NOR_HAS_LOCK and SPI_NOR_HAS_TB), even though I
Oh yes, I forgot you have already mentioned this in the previous email thread.
included them in my original commit. Looking at the datasheet for this
I can see that there are 5 block protect bits (BP0 - BP4) corresponding
to status registers SR2 through SR6. Status register bits SR7 and SR8
correspond to "status register protect 0 and status register protect 1"
bits as well. The Rockchip engineer I was testing the SFC with did
not have these flags as well on their driver they were using for this
chip too. I have tested with and without, and they seem to work
regardless. Is there a way to know for sure if these should or should
not be here?
We should do some locking tests to verify if these flags are ok for
this flash.
Here is a link to the datasheet I was working off of:
https://datasheet.lcsc.com/szlcsc/2005251034_XTX-XT25F128BSSIGT_C558844.pdf
I'll take a look and try to provide some guidelines on how the locking part
can be tested.
When this is confirmed I'll be glad to provide my "Tested-by" line.
Cool, thanks! 
ta
Thank you.
quoted
 };

 const struct spi_nor_manufacturer spi_nor_manuf_id_collisions = {
--
2.25.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v2 01/35] mtd: spi-nor: core: Introduce SPI_NOR_PARSE_SFDP

From: Pratyush Yadav <hidden>
Date: 2021-08-04 08:12:31

On 27/07/21 07:51AM, Tudor Ambarus wrote:
SPI NOR flashes that statically declare one of the
SPI_NOR_{DUAL, QUAD, OCTAL, OCTAL_DTR}_READ flags and do not support
the RDSFDP command are gratuiously receiving the RDSFDP command
in the attempt of parsing the SFDP tables. It is not desirable to issue
commands that are not supported, so introduce a flag to help on this
situation.

New flash additions that support the SFDP standard should be declared
using SPI_NOR_PARSE_SFDP. Support that can be discovered when parsing
SFDP should not be duplicated by explicit flags at flash declaration.
All the flash parameters will be discovered when parsing SFDP.
Sometimes manufacturers wrongly define some fields in the SFDP tables.
If that's the case, SFDP data can be amended with the fixups() hooks.
It is not common, but if the SFDP tables are entirely wrong, and it
does not worth the hassle to tweak the SFDP parameters by using the
fixups hooks, or if the flash does not define the SFDP tables at all,
then statically init the flash with the SPI_NOR_SKIP_SFDP flag and
specify the rest of flash capabilities with the flash info flags.

With time, we want to convert all flashes to SPI_NOR_PARSE_SFDP and
stop triggering the SFDP parsing with the
SPI_NOR_{DUAL, QUAD, OCTAL*}_READ flags. Getting rid of the
SPI_NOR_{OCTAL, OCTAL_DTR}_READ trigger is easily achievable, the rest
are a long term goal.

Signed-off-by: Tudor Ambarus <redacted>
Reviewed-by: Heiko Thiery <redacted>
Reviewed-by: Pratyush Yadav <redacted>

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 02/35] mtd: spi-nor: core: Report correct name in case of ID collisions

From: Pratyush Yadav <hidden>
Date: 2021-08-04 08:26:28

On 27/07/21 07:51AM, Tudor Ambarus wrote:
Provide a way to report the correct flash name in case of ID collisions.
There will be a single flash_info entry when flash IDs collide, and the
differentiation between the flash types will be made at runtime
if possible.
I have the same comments as last time around. I am not convinced that 
this approach is better than having multiple entries, one for each 
colliding flash. I wonder how you will handle different fixups for the 
colliding flashes for example, since nor->info is const.

Maybe I will change my mind once I read through the rest of the series, 
in which case I will report back here.
quoted hunk
Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c  | 7 +++++--
 drivers/mtd/spi-nor/sysfs.c | 2 +-
 include/linux/mtd/spi-nor.h | 2 ++
 3 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 3d9f3698fb7b..1a278d33b02d 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -3027,7 +3027,7 @@ static void spi_nor_debugfs_init(struct spi_nor *nor,
 {
 	struct mtd_info *mtd = &nor->mtd;
 
-	mtd->dbg.partname = info->name;
+	mtd->dbg.partname = nor->name;
 	mtd->dbg.partid = devm_kasprintf(nor->dev, GFP_KERNEL, "spi-nor:%*phN",
 					 info->id_len, info->id);
 }
@@ -3208,7 +3208,10 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 	/* Configure OTP parameters and ops */
 	spi_nor_otp_init(nor);
 
-	dev_info(dev, "%s (%lld Kbytes)\n", info->name,
+	if (!nor->name)
+		nor->name = info->name;
+
+	dev_info(dev, "%s (%lld Kbytes)\n", nor->name,
 			(long long)mtd->size >> 10);
 
 	dev_dbg(dev,
diff --git a/drivers/mtd/spi-nor/sysfs.c b/drivers/mtd/spi-nor/sysfs.c
index 9aec9d8a98ad..017119768f32 100644
--- a/drivers/mtd/spi-nor/sysfs.c
+++ b/drivers/mtd/spi-nor/sysfs.c
@@ -25,7 +25,7 @@ static ssize_t partname_show(struct device *dev,
 	struct spi_mem *spimem = spi_get_drvdata(spi);
 	struct spi_nor *nor = spi_mem_get_drvdata(spimem);
 
-	return sysfs_emit(buf, "%s\n", nor->info->name);
+	return sysfs_emit(buf, "%s\n", nor->name);
 }
 static DEVICE_ATTR_RO(partname);
 
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index f67457748ed8..bd92acdd1899 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -369,6 +369,7 @@ struct spi_nor_flash_parameter;
  * @bouncebuf:		bounce buffer used when the buffer passed by the MTD
  *                      layer is not DMA-able
  * @bouncebuf_size:	size of the bounce buffer
+ * @name:		used to point to correct name in case of ID collisions.
  * @info:		SPI NOR part JEDEC MFR ID and other info
  * @manufacturer:	SPI NOR manufacturer
  * @page_size:		the page size of the SPI NOR
@@ -399,6 +400,7 @@ struct spi_nor {
 	struct spi_mem		*spimem;
 	u8			*bouncebuf;
 	size_t			bouncebuf_size;
+	const char *name;
 	const struct flash_info	*info;
 	const struct spi_nor_manufacturer *manufacturer;
 	u32			page_size;
-- 
2.25.1
-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 21/35] mtd: spi-nor: Introduce spi_nor_set_mtd_info()

From: <hidden>
Date: 2021-08-16 07:28:31

On 7/27/21 7:52 AM, Tudor Ambarus wrote:
quoted hunk
Used to init all the mtd_info fields. Move the mtd_info init
the last thing in the spi_nor_scan(), so that we avoid superfluous
initialization of the mtd_info fields in case of errors.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c | 55 +++++++++++++++++++++-----------------
 1 file changed, 31 insertions(+), 24 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 5c8cffb5e6f2..26acfc9901db 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -3124,6 +3124,36 @@ static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor,
 	return info;
 }
 
+static void spi_nor_set_mtd_info(struct spi_nor *nor)
+{
+	struct mtd_info *mtd = &nor->mtd;
+	struct device *dev = nor->dev;
+
+	spi_nor_register_locking_ops(nor);
+
+	/* Configure OTP parameters and ops */
+	spi_nor_otp_init(nor);
+
+	mtd->dev.parent = dev;
+	if (!mtd->name)
+		mtd->name = dev_name(dev);
+	mtd->priv = nor;
Rasmus sent me a heads up that I have a leftover here, probably from a rebase.
The priv assignment is no longer needed as per previous patch. Will update in v3.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v2 05/35] mtd: spi-nor: Introduce Manufacturer ID collisions driver

From: Pratyush Yadav <hidden>
Date: 2021-08-16 18:31:26

On 27/07/21 07:51AM, Tudor Ambarus wrote:
Some manufacturers completely ignore the manufacturer's identification code
standard (JEP106) and do not define the manufacturer ID continuation
scheme. This will result in manufacturer ID collisions.

An an example, JEP106BA requires Boya that it's manufacturer ID to be
preceded by 8 continuation codes. Boya's identification code must be:
0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x68. But Boya ignores the
continuation scheme and its ID collides with the manufacturer defined in
bank one: Convex Computer.

Introduce the manuf-id-collisions driver in order to address ID collisions
between manufacturers. flash_info entries will be added in a first come,
first served manner. Differentiation between flashes will be done at
runtime if possible. Where runtime differentiation is not possible, new
compatibles will be introduced, but this will be done as a last resort.
Every new flash addition that define the SFDP tables, should dump its SFDP
tables in the patch's comment section below the --- line, so that we can
reference it in case of collisions.

Signed-off-by: Tudor Ambarus <redacted>
Reviewed-by: Pratyush Yadav <redacted>

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 06/35] mtd: spi-nor: manuf-id-collisions: Add support for xt25f128b

From: Pratyush Yadav <hidden>
Date: 2021-08-16 18:46:24

On 27/07/21 07:51AM, Tudor Ambarus wrote:
Flash does not support continuation codes and may collide with a flash
of other manufacturer, Intersil being an example .
Nitpick:                                          ^ drop the extra space
Signed-off-by: Tudor Ambarus <redacted>
---
0000000 4653 5044 0100 ff01 0000 0901 0030 ff00
0000010 000b 0301 0060 ff00 ffff ffff ffff ffff
0000020 ffff ffff ffff ffff ffff ffff ffff ffff
0000030 20e5 fff1 ffff 07ff eb44 6b08 3b08 bb42
0000040 ffee ffff ffff ff00 ffff ff00 200c 520f
0000050 d810 ff00 ffff ffff ffff ffff ffff ffff
0000060 3600 2700 f99f 6477 e8d9 ffff
I think you should list all the other sysfs parameters as well. See 
Michael's comments on patch 35.
quoted hunk
 drivers/mtd/spi-nor/manuf-id-collisions.c | 4 ++++
 1 file changed, 4 insertions(+)
diff --git a/drivers/mtd/spi-nor/manuf-id-collisions.c b/drivers/mtd/spi-nor/manuf-id-collisions.c
index bf7dba34f018..db31470ebf6a 100644
--- a/drivers/mtd/spi-nor/manuf-id-collisions.c
+++ b/drivers/mtd/spi-nor/manuf-id-collisions.c
@@ -13,6 +13,10 @@ static const struct flash_info id_collision_parts[] = {
 	{ "by25q128as", INFO(0x684018, 0, 64 * 1024, 256, SPI_NOR_SKIP_SFDP |
 			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			     SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
+
+	/* XTX (XTX Technology Limited) */
+	{ "xt25f128b", INFO(0x0b4018, 0, 64 * 1024, 256, SPI_NOR_PARSE_SFDP |
+			    SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
I have not went and checked, but I assume these two flags can't be 
discovered via SFDP?
 };
 
 const struct spi_nor_manufacturer spi_nor_manuf_id_collisions = {
-- 
2.25.1
-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 07/35] mtd: spi-nor: manuf-id-collisions: Add support for xm25qh64c

From: Pratyush Yadav <hidden>
Date: 2021-08-16 18:47:49

On 27/07/21 07:51AM, Tudor Ambarus wrote:
Flash ignores the manufacturer continuation codes and is likely to
collide with other manufacturers flashes.

Signed-off-by: Tudor Ambarus <redacted>
---
Do not apply without the SFDP tables hexdump.
... and all the other sysfs params that we usually ask for. See 
Michael's replies on patch 35.
quoted hunk
 drivers/mtd/spi-nor/manuf-id-collisions.c | 3 +++
 1 file changed, 3 insertions(+)
diff --git a/drivers/mtd/spi-nor/manuf-id-collisions.c b/drivers/mtd/spi-nor/manuf-id-collisions.c
index db31470ebf6a..f3ba00d17c68 100644
--- a/drivers/mtd/spi-nor/manuf-id-collisions.c
+++ b/drivers/mtd/spi-nor/manuf-id-collisions.c
@@ -14,6 +14,9 @@ static const struct flash_info id_collision_parts[] = {
 			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			     SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
 
+	/* XMC (Wuhan Xinxin Semiconductor Manufacturing Corp.) */
+	{ "xm25qh64c", INFO(0x204017, 0, 64 * 1024, 128, SPI_NOR_PARSE_SFDP) },
+
 	/* XTX (XTX Technology Limited) */
 	{ "xt25f128b", INFO(0x0b4018, 0, 64 * 1024, 256, SPI_NOR_PARSE_SFDP |
 			    SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
-- 
2.25.1
-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 08/35] mtd: spi-nor: core: Introduce the ate_init() hook

From: Pratyush Yadav <hidden>
Date: 2021-08-16 18:57:23

Hi Tudor,
Subject: [PATCH v2 08/35] mtd: spi-nor: core: Introduce the ate_init() hook
                                                              ^^^^^^^^
You ate the 'l' ;-)

On 27/07/21 07:51AM, Tudor Ambarus wrote:
quoted hunk
The goal is to get rid of the spaghetti way of initializing the flash
parameters and settings. late_init() hook will be used to tweak various
parameters that are not defined by the SFDP standard. Can be used by
non SFDP compliant flashes in order to tweak flash parameters that
are not/shouldn't be handled by the flash_info flags. Will replace the
default_init() hook.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c | 15 +++++++++++----
 drivers/mtd/spi-nor/core.h |  8 ++++++++
 2 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index d30c8f350dc1..15ccc9994215 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2667,11 +2667,18 @@ static void spi_nor_post_sfdp_fixups(struct spi_nor *nor)
  * spi_nor_late_init_params() - Late initialization of default flash parameters.
  * @nor:	pointer to a 'struct spi_nor'
  *
- * Used to set default flash parameters and settings when the ->default_init()
- * hook or the SFDP parser let voids.
+ * Used to tweak various flash parameters that are not defined by the SFDP
+ * standard. Can be used by non SFDP compliant flashes in order to tweek flash
+ * parameters that are not handled by the flash_info flags.
What about flashes that do have the SFDP table, but not all of them? For 
example, the Micron MT35XU512ABA flash currently uses the post_sfdp() 
hook to populate 8D-8D-8D fast read settings, command extension type, 
etc. These are supposed to be obtained from the xSPI Profile 1.0 table 
(like we do for Spansion/Cypress S28HS512T). But the flash does not 
populate this table. Should these go into the late_init() hook or the 
post_sfdp() hook?

FWIW, I think it should go into late_init(). post_sfdp() should only be 
used for correcting info obtained from the SFDP table. For populating 
the info not present in SFDP at all, late_init() should be used.

Thoughts?
  */
 static void spi_nor_late_init_params(struct spi_nor *nor)
 {
+	if (nor->manufacturer && nor->manufacturer->late_init)
+		nor->manufacturer->late_init(nor);
+
+	if (nor->info->late_init)
+		nor->info->late_init(nor);
Manufacturer late_init goes before flash late_init. Makes sense.
quoted hunk
+
 	/*
 	 * NOR protection support. When locking_ops are not provided, we pick
 	 * the default ones.
@@ -2713,8 +2720,8 @@ static void spi_nor_late_init_params(struct spi_nor *nor)
  *    wrong).
  *		spi_nor_post_sfdp_fixups()
  *
- * 5/ Late default flash parameters initialization, used when the
- * ->default_init() hook or the SFDP parser do not set specific params.
+ * 5/ Late flash parameters initialization, used to initialize flash
+ * parameters that are not declared in the JESD216 SFDP standard.
  *		spi_nor_late_init_params()
  */
 static int spi_nor_init_params(struct spi_nor *nor)
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index e9896cd60695..13d5c5edfd27 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -391,6 +391,11 @@ struct flash_info {
 
 	/* Part specific fixup hooks. */
 	const struct spi_nor_fixups *fixups;
+	/*
+	 * Init flash parameters that are not declared in the JESD216 SFDP
+	 * standard.
+	 */
+	void (* const late_init)(struct spi_nor *nor);
 };
 
 /* Used when the "_ext_id" is two bytes at most */
@@ -457,12 +462,15 @@ struct flash_info {
  * @parts: array of parts supported by this manufacturer
  * @nparts: number of entries in the parts array
  * @fixups: hooks called at various points in time during spi_nor_scan()
+ * @late_init: used to init flash parameters that are not declared in the
+ *             JESD216 SFDP standard.
  */
 struct spi_nor_manufacturer {
 	const char *name;
 	const struct flash_info *parts;
 	unsigned int nparts;
 	const struct spi_nor_fixups *fixups;
+	void (* const late_init)(struct spi_nor *nor);
The patch looks good to me other than the comments above.
 };
 
 /**
-- 
2.25.1
-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 09/35] mtd: spi-nor: atmel: Use flash late_init() for locking

From: Pratyush Yadav <hidden>
Date: 2021-08-16 19:09:26

On 27/07/21 07:51AM, Tudor Ambarus wrote:
Locking is not described in JESD216 SFDP standard, place the locking
init in late_init().
You are chaning the order of setting the locking ops here. Earlier, they 
were set before we parsed SFDP. Now they are set after we parse SFDP. 
Though I don't see it making much of a difference.
quoted hunk
Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/atmel.c | 30 +++++++++++-------------------
 1 file changed, 11 insertions(+), 19 deletions(-)
diff --git a/drivers/mtd/spi-nor/atmel.c b/drivers/mtd/spi-nor/atmel.c
index 1fea5cab492c..b937ef734e55 100644
--- a/drivers/mtd/spi-nor/atmel.c
+++ b/drivers/mtd/spi-nor/atmel.c
@@ -48,15 +48,11 @@ static const struct spi_nor_locking_ops atmel_at25fs_locking_ops = {
 	.is_locked = atmel_at25fs_is_locked,
 };
 
-static void atmel_at25fs_default_init(struct spi_nor *nor)
+static void atmel_at25fs_late_init(struct spi_nor *nor)
 {
 	nor->params->locking_ops = &atmel_at25fs_locking_ops;
 }
 
-static const struct spi_nor_fixups atmel_at25fs_fixups = {
-	.default_init = atmel_at25fs_default_init,
-};
-
 /**
  * atmel_set_global_protection - Do a Global Protect or Unprotect command
  * @nor:	pointer to 'struct spi_nor'
@@ -146,34 +142,30 @@ static const struct spi_nor_locking_ops atmel_global_protection_ops = {
 	.is_locked = atmel_is_global_protected,
 };
 
-static void atmel_global_protection_default_init(struct spi_nor *nor)
+static void atmel_global_protection_late_init(struct spi_nor *nor)
 {
 	nor->params->locking_ops = &atmel_global_protection_ops;
 }
 
-static const struct spi_nor_fixups atmel_global_protection_fixups = {
-	.default_init = atmel_global_protection_default_init,
-};
-
 static const struct flash_info atmel_parts[] = {
 	/* Atmel -- some are (confusingly) marketed as "DataFlash" */
 	{ "at25fs010",  INFO(0x1f6601, 0, 32 * 1024,   4, SECT_4K | SPI_NOR_HAS_LOCK)
-		.fixups = &atmel_at25fs_fixups },
+		.late_init = atmel_at25fs_late_init },
 	{ "at25fs040",  INFO(0x1f6604, 0, 64 * 1024,   8, SECT_4K | SPI_NOR_HAS_LOCK)
-		.fixups = &atmel_at25fs_fixups },
+		.late_init = atmel_at25fs_late_init },
 
 	{ "at25df041a", INFO(0x1f4401, 0, 64 * 1024,   8,
 			     SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
-			.fixups = &atmel_global_protection_fixups },
+		.late_init = atmel_global_protection_late_init },
Won't you be better off setting this in the manufacturer late_init()? It 
seems common for most atmel flashes.

Of course, this would cause a problem for atmel flashes that don't have 
this at all, since we would set locking for those as well. But I think 
we can avoid that by checking for SNOR_F_HAS_LOCK in 
spi_nor_register_locking_ops().
quoted hunk
 	{ "at25df321",  INFO(0x1f4700, 0, 64 * 1024,  64,
 			     SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
-			.fixups = &atmel_global_protection_fixups },
+		.late_init = atmel_global_protection_late_init },
 	{ "at25df321a", INFO(0x1f4701, 0, 64 * 1024,  64,
 			     SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
-			.fixups = &atmel_global_protection_fixups },
+		.late_init = atmel_global_protection_late_init },
 	{ "at25df641",  INFO(0x1f4800, 0, 64 * 1024, 128,
 			     SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
-			.fixups = &atmel_global_protection_fixups },
+		.late_init = atmel_global_protection_late_init },
 
 	{ "at25sl321",	INFO(0x1f4216, 0, 64 * 1024, 64,
 			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
@@ -181,13 +173,13 @@ static const struct flash_info atmel_parts[] = {
 	{ "at26f004",   INFO(0x1f0400, 0, 64 * 1024,  8, SECT_4K) },
 	{ "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16,
 			     SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
-			.fixups = &atmel_global_protection_fixups },
+		.late_init = atmel_global_protection_late_init },
 	{ "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32,
 			     SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
-			.fixups = &atmel_global_protection_fixups },
+		.late_init = atmel_global_protection_late_init },
 	{ "at26df321",  INFO(0x1f4700, 0, 64 * 1024, 64,
 			     SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
-			.fixups = &atmel_global_protection_fixups },
+		.late_init = atmel_global_protection_late_init },
 
 	{ "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) },
 };
-- 
2.25.1
-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 10/35] mtd: spi-nor: sst: Use flash late_init() for locking

From: Pratyush Yadav <hidden>
Date: 2021-08-16 19:12:01

On 27/07/21 07:51AM, Tudor Ambarus wrote:
Locking ops are not discoverable via SFDP, use late_init() call.

Signed-off-by: Tudor Ambarus <redacted>
Reviewed-by: Pratyush Yadav <redacted>

One question though. Have you tested these flashes (this one and the 
ones in the previous patch) to make sure you are not causing any 
regressions? While I don't see anything wrong with the patches, it would 
be good to have some test reports.
quoted hunk
---
 drivers/mtd/spi-nor/sst.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/mtd/spi-nor/sst.c b/drivers/mtd/spi-nor/sst.c
index 980f4c09c91d..29d100febdbf 100644
--- a/drivers/mtd/spi-nor/sst.c
+++ b/drivers/mtd/spi-nor/sst.c
@@ -46,15 +46,11 @@ static const struct spi_nor_locking_ops sst26vf_locking_ops = {
 	.is_locked = sst26vf_is_locked,
 };
 
-static void sst26vf_default_init(struct spi_nor *nor)
+static void sst26vf_late_init(struct spi_nor *nor)
 {
 	nor->params->locking_ops = &sst26vf_locking_ops;
 }
 
-static const struct spi_nor_fixups sst26vf_fixups = {
-	.default_init = sst26vf_default_init,
-};
-
 static const struct flash_info sst_parts[] = {
 	/* SST -- large erase sizes are "overlays", "sectors" are 4K */
 	{ "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024,  8,
@@ -88,7 +84,7 @@ static const struct flash_info sst_parts[] = {
 	{ "sst26vf064b", INFO(0xbf2643, 0, 64 * 1024, 128,
 			      SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			      SPI_NOR_HAS_LOCK | SPI_NOR_SWP_IS_VOLATILE)
-		.fixups = &sst26vf_fixups },
+		.late_init = sst26vf_late_init},
 };
 
 static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
-- 
2.25.1
-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 11/35] mtd: spi-nor: winbond: Use manufacturer late_init() for OTP ops

From: Pratyush Yadav <hidden>
Date: 2021-08-16 19:20:24

On 27/07/21 07:51AM, Tudor Ambarus wrote:
OTP info is not yet discoverable via SFDP, use late_init() to init
the OTP ops.
What do you mean by the "yet"? Does it mean that OTP info is planned to 
be added to the next SFDP version? Or does it mean that it is possible 
to discover it via SFDP but we just don't support it yet?

If it is neither and it just means "SFDP does not mention OTP at all", 
like it is for locking, then you should just drop the "yet". I know this 
is very nitpicky but it just caught my eye.
quoted hunk
Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/winbond.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/spi-nor/winbond.c b/drivers/mtd/spi-nor/winbond.c
index 96573f61caf5..6be45d2291c6 100644
--- a/drivers/mtd/spi-nor/winbond.c
+++ b/drivers/mtd/spi-nor/winbond.c
@@ -147,17 +147,22 @@ static const struct spi_nor_otp_ops winbond_otp_ops = {
 static void winbond_default_init(struct spi_nor *nor)
 {
 	nor->params->set_4byte_addr_mode = winbond_set_4byte_addr_mode;
Why not move this to late_init() as well?
-	if (nor->params->otp.org->n_regions)
-		nor->params->otp.ops = &winbond_otp_ops;
 }
 
 static const struct spi_nor_fixups winbond_fixups = {
 	.default_init = winbond_default_init,
 };
 
+static void winbond_late_init(struct spi_nor *nor)
+{
+	if (nor->params->otp.org->n_regions)
+		nor->params->otp.ops = &winbond_otp_ops;
+}
+
 const struct spi_nor_manufacturer spi_nor_winbond = {
 	.name = "winbond",
 	.parts = winbond_parts,
 	.nparts = ARRAY_SIZE(winbond_parts),
 	.fixups = &winbond_fixups,
+	.late_init = winbond_late_init,
 };
-- 
2.25.1
-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 12/35] mtd: spi-nor: xilinx: Use manufacturer late_init() to set setup method

From: Pratyush Yadav <hidden>
Date: 2021-08-16 19:21:53

On 27/07/21 07:51AM, Tudor Ambarus wrote:
post_sfdp was misleading in this case, as SFDP is not supported by
xilinx. Plus, there's no fixup here, just setting the correct
setup method, as required by xilinx parts.

Signed-off-by: Tudor Ambarus <redacted>
Reviewed-by: Pratyush Yadav <redacted>
quoted hunk
---
 drivers/mtd/spi-nor/xilinx.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/mtd/spi-nor/xilinx.c b/drivers/mtd/spi-nor/xilinx.c
index 1138bdbf4199..a573c3cde414 100644
--- a/drivers/mtd/spi-nor/xilinx.c
+++ b/drivers/mtd/spi-nor/xilinx.c
@@ -77,18 +77,14 @@ static int xilinx_nor_setup(struct spi_nor *nor,
 	return 0;
 }
 
-static void xilinx_post_sfdp_fixups(struct spi_nor *nor)
+static void xilinx_late_init(struct spi_nor *nor)
 {
 	nor->params->setup = xilinx_nor_setup;
 }
 
-static const struct spi_nor_fixups xilinx_fixups = {
-	.post_sfdp = xilinx_post_sfdp_fixups,
-};
-
 const struct spi_nor_manufacturer spi_nor_xilinx = {
 	.name = "xilinx",
 	.parts = xilinx_parts,
 	.nparts = ARRAY_SIZE(xilinx_parts),
-	.fixups = &xilinx_fixups,
+	.late_init = xilinx_late_init,
 };
-- 
2.25.1
-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 13/35] mtd: spi-nor: sst: Use manufacturer late_init() to set _write()

From: Pratyush Yadav <hidden>
Date: 2021-08-16 19:23:25

On 27/07/21 07:52AM, Tudor Ambarus wrote:
Setting the correct nor->mtd._write in a fixup hook was misleading,
since this is not a fixup, just a specific setting for SST, that differs
from the SPI NOR core default init.

Signed-off-by: Tudor Ambarus <redacted>
Reviewed-by: Pratyush Yadav <redacted>
quoted hunk
---
 drivers/mtd/spi-nor/sst.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/mtd/spi-nor/sst.c b/drivers/mtd/spi-nor/sst.c
index 29d100febdbf..eeb10766b70e 100644
--- a/drivers/mtd/spi-nor/sst.c
+++ b/drivers/mtd/spi-nor/sst.c
@@ -173,19 +173,15 @@ static int sst_write(struct mtd_info *mtd, loff_t to, size_t len,
 	return ret;
 }
 
-static void sst_post_sfdp_fixups(struct spi_nor *nor)
+static void sst_late_init(struct spi_nor *nor)
 {
 	if (nor->info->flags & SST_WRITE)
 		nor->mtd._write = sst_write;
 }
 
-static const struct spi_nor_fixups sst_fixups = {
-	.post_sfdp = sst_post_sfdp_fixups,
-};
-
 const struct spi_nor_manufacturer spi_nor_sst = {
 	.name = "sst",
 	.parts = sst_parts,
 	.nparts = ARRAY_SIZE(sst_parts),
-	.fixups = &sst_fixups,
+	.late_init = sst_late_init,
 };
-- 
2.25.1
-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 14/35] mtd: spi-nor: spansion: Use manufacturer late_init()

From: Pratyush Yadav <hidden>
Date: 2021-08-16 19:25:16

On 27/07/21 07:52AM, Tudor Ambarus wrote:
spansion_post_sfdp_fixups() was called regardless if the flash defined
SFDP tables or not. A better place for this kind of parameters init is
in manufacturer's late_init() hook. post_sfdp() should be called only
when SFDP is defined. No functional change in this patch.

Instead of doing the 4b opcodes settings at manufacturer level, thus
also for every flash that will be introduced, this should be done
just where it is needed, per flash. I'll let this for other patch.
Yes, agreed.
Signed-off-by: Tudor Ambarus <redacted>
Reviewed-by: Pratyush Yadav <redacted>
quoted hunk
---
 drivers/mtd/spi-nor/spansion.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c
index ee82dcd75310..aad7170768b4 100644
--- a/drivers/mtd/spi-nor/spansion.c
+++ b/drivers/mtd/spi-nor/spansion.c
@@ -276,7 +276,7 @@ static const struct flash_info spansion_parts[] = {
 	},
 };
 
-static void spansion_post_sfdp_fixups(struct spi_nor *nor)
+static void spansion_late_init(struct spi_nor *nor)
 {
 	if (nor->params->size <= SZ_16M)
 		return;
@@ -287,13 +287,9 @@ static void spansion_post_sfdp_fixups(struct spi_nor *nor)
 	nor->mtd.erasesize = nor->info->sector_size;
 }
 
-static const struct spi_nor_fixups spansion_fixups = {
-	.post_sfdp = spansion_post_sfdp_fixups,
-};
-
 const struct spi_nor_manufacturer spi_nor_spansion = {
 	.name = "spansion",
 	.parts = spansion_parts,
 	.nparts = ARRAY_SIZE(spansion_parts),
-	.fixups = &spansion_fixups,
+	.late_init = spansion_late_init,
 };
-- 
2.25.1
-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 15/35] mtd: spi-nor: core: Call spi_nor_post_sfdp_fixups() only when SFDP is defined

From: Pratyush Yadav <hidden>
Date: 2021-08-16 19:34:32

On 27/07/21 07:52AM, Tudor Ambarus wrote:
quoted hunk
spi_nor_post_sfdp_fixups() was called even when there were no SFDP
tables defined and the function name was misleading.

We introduced the late_init() hook which is used to tweak various
parameters that could not be extracted by other means, i.e. when
parameters are not defined in the JESD216 SFDP standard, or when
the flash_info flags are incomplete.

Use spi_nor_post_sfdp_fixups() just to fix SFDP data. post_sfdp()
hook is as of now used just by s28hs512t, mt35xu512aba, and both
support SFDP, there's no functional change with this patch.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c | 66 +++++++++++++++++---------------------
 1 file changed, 29 insertions(+), 37 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 15ccc9994215..1f38fa8ab2fa 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2509,6 +2509,25 @@ static void spi_nor_manufacturer_init_params(struct spi_nor *nor)
 		nor->info->fixups->default_init(nor);
 }
 
+/**
+ * spi_nor_post_sfdp_fixups() - Updates the flash's parameters and settings
+ * after SFDP has been parsed.
+ * @nor:	pointer to a 'struct spi_nor'
+ *
+ * Typically used to tweak various parameters that could not be extracted by
+ * other means (i.e. when information provided by the SFDP tables are
+ * incomplete or wrong).
Do we want to keep the "incomplete" here? Wouldn't incomplete 
information (like missing parameter tables) be more suited for 
late_init()?
quoted hunk
+ */
+static void spi_nor_post_sfdp_fixups(struct spi_nor *nor)
+{
+	if (nor->manufacturer && nor->manufacturer->fixups &&
+	    nor->manufacturer->fixups->post_sfdp)
+		nor->manufacturer->fixups->post_sfdp(nor);
+
+	if (nor->info->fixups && nor->info->fixups->post_sfdp)
+		nor->info->fixups->post_sfdp(nor);
+}
+
 /**
  * spi_nor_sfdp_init_params() - Initialize the flash's parameters and settings
  * based on JESD216 SFDP standard.
@@ -2523,11 +2542,12 @@ static void spi_nor_sfdp_init_params(struct spi_nor *nor)
 
 	memcpy(&sfdp_params, nor->params, sizeof(sfdp_params));
 
-	if (spi_nor_parse_sfdp(nor)) {
-		memcpy(nor->params, &sfdp_params, sizeof(*nor->params));
-		nor->addr_width = 0;
-		nor->flags &= ~SNOR_F_4B_OPCODES;
-	}
+	if (!spi_nor_parse_sfdp(nor))
+		return spi_nor_post_sfdp_fixups(nor);
Huh. I didn't know you could do return foo() in a void function if foo() 
is also void. Dunno how I feel about this though. It definitely confused 
me for a bit.
+
+	memcpy(nor->params, &sfdp_params, sizeof(*nor->params));
+	nor->addr_width = 0;
+	nor->flags &= ~SNOR_F_4B_OPCODES;
I feel like the new flow makes these 3 lines more confusing. Earlier, 
these were called under if (spi_nor_parse_sfdp()) so it was a bit easier 
to make the connection that these are undoing the changes performed by 
that function. Now it is a little harder to spot. I think a comment is 
in order.
quoted hunk
 }
 
 /**
@@ -2643,26 +2663,6 @@ static void spi_nor_info_init_params(struct spi_nor *nor)
 	spi_nor_init_uniform_erase_map(map, erase_mask, params->size);
 }
 
-/**
- * spi_nor_post_sfdp_fixups() - Updates the flash's parameters and settings
- * after SFDP has been parsed (is also called for SPI NORs that do not
- * support RDSFDP).
- * @nor:	pointer to a 'struct spi_nor'
- *
- * Typically used to tweak various parameters that could not be extracted by
- * other means (i.e. when information provided by the SFDP/flash_info tables
- * are incomplete or wrong).
- */
-static void spi_nor_post_sfdp_fixups(struct spi_nor *nor)
-{
-	if (nor->manufacturer && nor->manufacturer->fixups &&
-	    nor->manufacturer->fixups->post_sfdp)
-		nor->manufacturer->fixups->post_sfdp(nor);
-
-	if (nor->info->fixups && nor->info->fixups->post_sfdp)
-		nor->info->fixups->post_sfdp(nor);
-}
-
 /**
  * spi_nor_late_init_params() - Late initialization of default flash parameters.
  * @nor:	pointer to a 'struct spi_nor'
@@ -2709,18 +2709,12 @@ static void spi_nor_late_init_params(struct spi_nor *nor)
  *    should be more accurate that the above.
  *		spi_nor_sfdp_init_params()
  *
- *    Please note that there is a ->post_bfpt() fixup hook that can overwrite
- *    the flash parameters and settings immediately after parsing the Basic
- *    Flash Parameter Table.
+ *    Please note that there are ->post_{bfpt, sfdp}() fixup hooks that can
+ *    overwrite the flash parameters and settings immediately after table
+ *    parsing.
  *
  * which can be overwritten by:
- * 4/ Post SFDP flash parameters initialization. Used to tweak various
- *    parameters that could not be extracted by other means (i.e. when
- *    information provided by the SFDP/flash_info tables are incomplete or
- *    wrong).
- *		spi_nor_post_sfdp_fixups()
- *
- * 5/ Late flash parameters initialization, used to initialize flash
+ * 4/ Late flash parameters initialization, used to initialize flash
  * parameters that are not declared in the JESD216 SFDP standard.
  *		spi_nor_late_init_params()
  */
@@ -2740,8 +2734,6 @@ static int spi_nor_init_params(struct spi_nor *nor)
 	    !(nor->info->flags & SPI_NOR_SKIP_SFDP))
 		spi_nor_sfdp_init_params(nor);
 
-	spi_nor_post_sfdp_fixups(nor);
-
 	spi_nor_late_init_params(nor);
 
 	return 0;
-- 
2.25.1
-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 16/35] mtd: spi-nor: core: Mark default_init() as deprecated

From: Pratyush Yadav <hidden>
Date: 2021-08-16 19:39:07

On 27/07/21 07:52AM, Tudor Ambarus wrote:
The goal is to remove the spagetti init of params. The flash should
be initialized by the SFDP data, and when SFDP tables are not defined,
by the flash_info flags. SFDP data can be corrected by the
post_{bfpt, sfdp} when wrong, and in case of flash_info flags init,
we'll use the late_init() hook, where checking for the
SPI_NOR_SKIP_SFDP flag.
Why depreciate it? It is not like we have external callers that we need 
to notify. We know and control all the users of this function. Just move 
all users to late_init() and delete this. You have already done a large 
part of that work in the previous patches. Why not convert all other 
callers as well? Is there some complicated piece of code that stops you 
from touching it for now?
quoted hunk
Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.h | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 13d5c5edfd27..625f4eed75f1 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -289,9 +289,8 @@ struct spi_nor_flash_parameter {
 
 /**
  * struct spi_nor_fixups - SPI NOR fixup hooks
- * @default_init: called after default flash parameters init. Used to tweak
- *                flash parameters when information provided by the flash_info
- *                table is incomplete or wrong.
+ * @default_init: Deprecated. Use the post_{bfpt, sfdp}, or the late_init()
+ *                hooks instead.
  * @post_bfpt: called after the BFPT table has been parsed
  * @post_sfdp: called after SFDP has been parsed (is also called for SPI NORs
  *             that do not support RDSFDP). Typically used to tweak various
-- 
2.25.1
-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 17/35] mtd: spi-nor: Introduce spi_nor_nonsfdp_flags_init()

From: Pratyush Yadav <hidden>
Date: 2021-08-17 10:27:11

On 27/07/21 07:52AM, Tudor Ambarus wrote:
Used to initialize the NOR flags for settings that are not defined
in the JESD216 SFDP standard, thus can not be retrieved when parsing
SFDP. No functional change.
I am worried if the order in which these flags are set can cause some 
subtle bugs.

I can see one instance of it with SNOR_F_HAS_LOCK. 
spi_nor_late_init_params() checks for SNOR_F_HAS_LOCK and if there are 
no locking ops specified, it sets the default locking ops. This works 
fine before this patch because the flag is set before the function is 
called. But now, the flag will be set _after_ the function is called, 
and so you will never be able to set the default flags.

This is one bug I can spot but I fear some others might be hiding 
somewhere as well. SPI NOR has accumulated a lot of spaghetti code over 
the years and I certainly felt it when working on my Octal DTR series. 
It caused an address width selection bug that was not obvious at all, 
and was not even caught during the rc cycles.

I think this series does clean up that spaghetti a lot. But you need to 
be careful of such bugs. I think you should definitely let this series 
cook in next for some time so it gets some exposure and hopefully some 
testing.
quoted hunk
Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c | 88 ++++++++++++++++++++++----------------
 1 file changed, 52 insertions(+), 36 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 1f38fa8ab2fa..6a8617346764 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2687,6 +2687,56 @@ static void spi_nor_late_init_params(struct spi_nor *nor)
 		spi_nor_init_default_locking_ops(nor);
 }
 
+/**
+ * spi_nor_nonsfdp_flags_init() - Initialize NOR flags for settings that are not
+ * defined in the JESD216 SFDP standard, thus can not be retrieved when parsing
+ * SFDP.
+ * @nor:	pointer to a 'struct spi_nor'
+ */
+static void spi_nor_nonsfdp_flags_init(struct spi_nor *nor)
+{
+	const struct flash_info *info = nor->info;
+	struct device_node *np = spi_nor_get_flash_node(nor);
+
+	if (of_property_read_bool(np, "broken-flash-reset"))
+		nor->flags |= SNOR_F_BROKEN_RESET;
+
+	if (info->flags & SPI_NOR_SWP_IS_VOLATILE)
+		nor->flags |= SNOR_F_SWP_IS_VOLATILE;
+
+	if (info->flags & SPI_NOR_HAS_LOCK)
+		nor->flags |= SNOR_F_HAS_LOCK;
As mentioned above, this would cause a bug.
quoted hunk
+
+	if (info->flags & SPI_NOR_HAS_TB) {
+		nor->flags |= SNOR_F_HAS_SR_TB;
+		if (info->flags & SPI_NOR_TB_SR_BIT6)
+			nor->flags |= SNOR_F_HAS_SR_TB_BIT6;
+	}
+
+	if (info->flags & SPI_NOR_4BIT_BP) {
+		nor->flags |= SNOR_F_HAS_4BIT_BP;
+		if (info->flags & SPI_NOR_BP3_SR_BIT6)
+			nor->flags |= SNOR_F_HAS_SR_BP3_BIT6;
+	}
+
+	if (info->flags & NO_CHIP_ERASE)
+		nor->flags |= SNOR_F_NO_OP_CHIP_ERASE;
+
+	if (info->flags & USE_FSR)
+		nor->flags |= SNOR_F_USE_FSR;
+
+	if (info->flags & USE_CLSR)
+		nor->flags |= SNOR_F_USE_CLSR;
+
+	/*
+	 * Make sure the XSR_RDY flag is set before calling
+	 * spi_nor_wait_till_ready(). Xilinx S3AN share MFR
+	 * with Atmel SPI NOR.
+	 */
+	if (info->flags & SPI_NOR_XSR_RDY)
+		nor->flags |=  SNOR_F_READY_XSR_RDY;
+}
+
 /**
  * spi_nor_init_params() - Initialize the flash's parameters and settings.
  * @nor:	pointer to a 'struct spi_nor'.
@@ -2736,6 +2786,8 @@ static int spi_nor_init_params(struct spi_nor *nor)
 
 	spi_nor_late_init_params(nor);
 
+	spi_nor_nonsfdp_flags_init(nor);
+
 	return 0;
 }
 
@@ -3078,7 +3130,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 	const struct flash_info *info;
 	struct device *dev = nor->dev;
 	struct mtd_info *mtd = &nor->mtd;
-	struct device_node *np = spi_nor_get_flash_node(nor);
 	int ret;
 	int i;
 
@@ -3115,17 +3166,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 
 	mutex_init(&nor->lock);
 
-	/*
-	 * Make sure the XSR_RDY flag is set before calling
-	 * spi_nor_wait_till_ready(). Xilinx S3AN share MFR
-	 * with Atmel SPI NOR.
-	 */
-	if (info->flags & SPI_NOR_XSR_RDY)
-		nor->flags |=  SNOR_F_READY_XSR_RDY;
-
-	if (info->flags & SPI_NOR_HAS_LOCK)
-		nor->flags |= SNOR_F_HAS_LOCK;
-
 	mtd->_write = spi_nor_write;
 
 	/* Init flash parameters based on flash_info struct and SFDP */
@@ -3147,27 +3187,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 	mtd->_get_device = spi_nor_get_device;
 	mtd->_put_device = spi_nor_put_device;
 
-	if (info->flags & USE_FSR)
-		nor->flags |= SNOR_F_USE_FSR;
-	if (info->flags & SPI_NOR_HAS_TB) {
-		nor->flags |= SNOR_F_HAS_SR_TB;
-		if (info->flags & SPI_NOR_TB_SR_BIT6)
-			nor->flags |= SNOR_F_HAS_SR_TB_BIT6;
-	}
-
-	if (info->flags & NO_CHIP_ERASE)
-		nor->flags |= SNOR_F_NO_OP_CHIP_ERASE;
-	if (info->flags & USE_CLSR)
-		nor->flags |= SNOR_F_USE_CLSR;
-	if (info->flags & SPI_NOR_SWP_IS_VOLATILE)
-		nor->flags |= SNOR_F_SWP_IS_VOLATILE;
-
-	if (info->flags & SPI_NOR_4BIT_BP) {
-		nor->flags |= SNOR_F_HAS_4BIT_BP;
-		if (info->flags & SPI_NOR_BP3_SR_BIT6)
-			nor->flags |= SNOR_F_HAS_SR_BP3_BIT6;
-	}
-
 	if (info->flags & SPI_NOR_NO_ERASE)
 		mtd->flags |= MTD_NO_ERASE;
 
@@ -3175,9 +3194,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 	nor->page_size = nor->params->page_size;
 	mtd->writebufsize = nor->page_size;
 
-	if (of_property_read_bool(np, "broken-flash-reset"))
-		nor->flags |= SNOR_F_BROKEN_RESET;
-
As I pointed out above, I think this patch is certainly going in the 
right direction. We just need to be careful of the bugs that slip 
through.
 	/*
 	 * Configure the SPI memory:
 	 * - select op codes for (Fast) Read, Page Program and Sector Erase.
-- 
2.25.1
-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 17/35] mtd: spi-nor: Introduce spi_nor_nonsfdp_flags_init()

From: <hidden>
Date: 2021-08-17 12:18:44

On 8/17/21 1:24 PM, Pratyush Yadav wrote:
EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe

On 27/07/21 07:52AM, Tudor Ambarus wrote:
quoted
Used to initialize the NOR flags for settings that are not defined
in the JESD216 SFDP standard, thus can not be retrieved when parsing
SFDP. No functional change.
I am worried if the order in which these flags are set can cause some
subtle bugs.

I can see one instance of it with SNOR_F_HAS_LOCK.
spi_nor_late_init_params() checks for SNOR_F_HAS_LOCK and if there are
no locking ops specified, it sets the default locking ops. This works
fine before this patch because the flag is set before the function is
called. But now, the flag will be set _after_ the function is called,
and so you will never be able to set the default flags.

This is one bug I can spot but I fear some others might be hiding
somewhere as well. SPI NOR has accumulated a lot of spaghetti code over
the years and I certainly felt it when working on my Octal DTR series.
It caused an address width selection bug that was not obvious at all,
and was not even caught during the rc cycles.

I think this series does clean up that spaghetti a lot. But you need to
be careful of such bugs. I think you should definitely let this series
cook in next for some time so it gets some exposure and hopefully some
testing.
quoted
Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c | 88 ++++++++++++++++++++++----------------
 1 file changed, 52 insertions(+), 36 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 1f38fa8ab2fa..6a8617346764 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2687,6 +2687,56 @@ static void spi_nor_late_init_params(struct spi_nor *nor)
              spi_nor_init_default_locking_ops(nor);
 }

+/**
+ * spi_nor_nonsfdp_flags_init() - Initialize NOR flags for settings that are not
+ * defined in the JESD216 SFDP standard, thus can not be retrieved when parsing
+ * SFDP.
+ * @nor:     pointer to a 'struct spi_nor'
+ */
+static void spi_nor_nonsfdp_flags_init(struct spi_nor *nor)
+{
+     const struct flash_info *info = nor->info;
+     struct device_node *np = spi_nor_get_flash_node(nor);
+
+     if (of_property_read_bool(np, "broken-flash-reset"))
+             nor->flags |= SNOR_F_BROKEN_RESET;
+
+     if (info->flags & SPI_NOR_SWP_IS_VOLATILE)
+             nor->flags |= SNOR_F_SWP_IS_VOLATILE;
+
+     if (info->flags & SPI_NOR_HAS_LOCK)
+             nor->flags |= SNOR_F_HAS_LOCK;
As mentioned above, this would cause a bug.
Good catch!
quoted
+
+     if (info->flags & SPI_NOR_HAS_TB) {
+             nor->flags |= SNOR_F_HAS_SR_TB;
+             if (info->flags & SPI_NOR_TB_SR_BIT6)
+                     nor->flags |= SNOR_F_HAS_SR_TB_BIT6;
+     }
+
+     if (info->flags & SPI_NOR_4BIT_BP) {
+             nor->flags |= SNOR_F_HAS_4BIT_BP;
+             if (info->flags & SPI_NOR_BP3_SR_BIT6)
+                     nor->flags |= SNOR_F_HAS_SR_BP3_BIT6;
+     }
+
+     if (info->flags & NO_CHIP_ERASE)
+             nor->flags |= SNOR_F_NO_OP_CHIP_ERASE;
+
+     if (info->flags & USE_FSR)
+             nor->flags |= SNOR_F_USE_FSR;
+
+     if (info->flags & USE_CLSR)
+             nor->flags |= SNOR_F_USE_CLSR;
+
+     /*
+      * Make sure the XSR_RDY flag is set before calling
+      * spi_nor_wait_till_ready(). Xilinx S3AN share MFR
+      * with Atmel SPI NOR.
+      */
+     if (info->flags & SPI_NOR_XSR_RDY)
+             nor->flags |=  SNOR_F_READY_XSR_RDY;
+}
+
 /**
  * spi_nor_init_params() - Initialize the flash's parameters and settings.
  * @nor:     pointer to a 'struct spi_nor'.
@@ -2736,6 +2786,8 @@ static int spi_nor_init_params(struct spi_nor *nor)

      spi_nor_late_init_params(nor);

+     spi_nor_nonsfdp_flags_init(nor);
+
      return 0;
 }
@@ -3078,7 +3130,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
      const struct flash_info *info;
      struct device *dev = nor->dev;
      struct mtd_info *mtd = &nor->mtd;
-     struct device_node *np = spi_nor_get_flash_node(nor);
      int ret;
      int i;
@@ -3115,17 +3166,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,

      mutex_init(&nor->lock);

-     /*
-      * Make sure the XSR_RDY flag is set before calling
-      * spi_nor_wait_till_ready(). Xilinx S3AN share MFR
-      * with Atmel SPI NOR.
-      */
-     if (info->flags & SPI_NOR_XSR_RDY)
-             nor->flags |=  SNOR_F_READY_XSR_RDY;
-
-     if (info->flags & SPI_NOR_HAS_LOCK)
-             nor->flags |= SNOR_F_HAS_LOCK;
-
      mtd->_write = spi_nor_write;

      /* Init flash parameters based on flash_info struct and SFDP */
@@ -3147,27 +3187,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
      mtd->_get_device = spi_nor_get_device;
      mtd->_put_device = spi_nor_put_device;

-     if (info->flags & USE_FSR)
-             nor->flags |= SNOR_F_USE_FSR;
-     if (info->flags & SPI_NOR_HAS_TB) {
-             nor->flags |= SNOR_F_HAS_SR_TB;
-             if (info->flags & SPI_NOR_TB_SR_BIT6)
-                     nor->flags |= SNOR_F_HAS_SR_TB_BIT6;
-     }
-
-     if (info->flags & NO_CHIP_ERASE)
-             nor->flags |= SNOR_F_NO_OP_CHIP_ERASE;
-     if (info->flags & USE_CLSR)
-             nor->flags |= SNOR_F_USE_CLSR;
-     if (info->flags & SPI_NOR_SWP_IS_VOLATILE)
-             nor->flags |= SNOR_F_SWP_IS_VOLATILE;
-
-     if (info->flags & SPI_NOR_4BIT_BP) {
-             nor->flags |= SNOR_F_HAS_4BIT_BP;
-             if (info->flags & SPI_NOR_BP3_SR_BIT6)
-                     nor->flags |= SNOR_F_HAS_SR_BP3_BIT6;
-     }
-
      if (info->flags & SPI_NOR_NO_ERASE)
              mtd->flags |= MTD_NO_ERASE;
@@ -3175,9 +3194,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
      nor->page_size = nor->params->page_size;
      mtd->writebufsize = nor->page_size;

-     if (of_property_read_bool(np, "broken-flash-reset"))
-             nor->flags |= SNOR_F_BROKEN_RESET;
-
As I pointed out above, I think this patch is certainly going in the
right direction. We just need to be careful of the bugs that slip
through.
Right, I'll self review all once I'll prepare v3. And I'll redo the testing,
this time trying to cover all the flash info flags. Would be great if Michael,
Vignesh and others can have a look on the series too. With 2 or 3 persons reviewing
and better test coverage, we should be fine. Would be great if we can have
these cleaning patches without introducing regressions, but if we introduce it's not
a tragedy, we will fix all once reported.

Cheers,
ta

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

Re: [PATCH v2 18/35] mtd: spi-nor: Get rid of SPI_NOR_4B_OPCODES flag

From: Pratyush Yadav <hidden>
Date: 2021-08-17 12:19:23

On 27/07/21 07:52AM, Tudor Ambarus wrote:
Get rid of flash_info flags that indicate settings which can be
discovered when parsing SFDP. It will be clearer who sets what,
and we'll restrict the flash settings that a developer can choose to
only settings that are not SFDP discoverable.

Whether a flash supports 4byte opcodes or not, is discoverable when
parsing the optional 4-byte address instruction table. Flashes that
do not support the 4bait SFDP table should set the SNOR_F_4B_OPCODES
flag in the late_init() call. Flashes that define the 4bait SFDP table
but gets it wrong, should set the flag in a post_sfdp fixup hook.
I like the idea, not so much the execution. More on this below.
quoted hunk
Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c       |  3 ---
 drivers/mtd/spi-nor/core.h       | 32 ++++++++++++++++----------------
 drivers/mtd/spi-nor/gigadevice.c |  7 ++++---
 drivers/mtd/spi-nor/issi.c       | 12 ++++++------
 drivers/mtd/spi-nor/macronix.c   | 18 ++++++++++--------
 drivers/mtd/spi-nor/micron-st.c  | 22 +++++++++++++---------
 drivers/mtd/spi-nor/spansion.c   | 12 ++++++------
 7 files changed, 55 insertions(+), 51 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 6a8617346764..240d5c31af88 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -3204,9 +3204,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 	if (ret)
 		return ret;
 
-	if (info->flags & SPI_NOR_4B_OPCODES)
-		nor->flags |= SNOR_F_4B_OPCODES;
-
 	if (info->flags & SPI_NOR_IO_MODE_EN_VOLATILE)
 		nor->flags |= SNOR_F_IO_MODE_EN_VOLATILE;
 
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 625f4eed75f1..dfdc51a26cad 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -348,40 +348,36 @@ struct flash_info {
 					 * S3AN flashes have specific opcode to
 					 * read the status register.
 					 */
-#define SPI_NOR_4B_OPCODES	BIT(11)	/*
-					 * Use dedicated 4byte address op codes
-					 * to support memory size above 128Mib.
-					 */
-#define NO_CHIP_ERASE		BIT(12) /* Chip does not support chip erase */
-#define SPI_NOR_SKIP_SFDP	BIT(13)	/* Skip parsing of SFDP tables */
-#define USE_CLSR		BIT(14)	/* use CLSR command */
-#define SPI_NOR_OCTAL_READ	BIT(15)	/* Flash supports Octal Read */
-#define SPI_NOR_TB_SR_BIT6	BIT(16)	/*
+#define NO_CHIP_ERASE		BIT(11) /* Chip does not support chip erase */
+#define SPI_NOR_SKIP_SFDP	BIT(12)	/* Skip parsing of SFDP tables */
+#define USE_CLSR		BIT(13)	/* use CLSR command */
+#define SPI_NOR_OCTAL_READ	BIT(14)	/* Flash supports Octal Read */
+#define SPI_NOR_TB_SR_BIT6	BIT(15)	/*
 					 * Top/Bottom (TB) is bit 6 of
 					 * status register. Must be used with
 					 * SPI_NOR_HAS_TB.
 					 */
-#define SPI_NOR_4BIT_BP		BIT(17) /*
+#define SPI_NOR_4BIT_BP		BIT(16) /*
 					 * Flash SR has 4 bit fields (BP0-3)
 					 * for block protection.
 					 */
-#define SPI_NOR_BP3_SR_BIT6	BIT(18) /*
+#define SPI_NOR_BP3_SR_BIT6	BIT(17) /*
 					 * BP3 is bit 6 of status register.
 					 * Must be used with SPI_NOR_4BIT_BP.
 					 */
-#define SPI_NOR_OCTAL_DTR_READ	BIT(19) /* Flash supports octal DTR Read. */
-#define SPI_NOR_OCTAL_DTR_PP	BIT(20) /* Flash supports Octal DTR Page Program */
-#define SPI_NOR_IO_MODE_EN_VOLATILE	BIT(21) /*
+#define SPI_NOR_OCTAL_DTR_READ	BIT(18) /* Flash supports octal DTR Read. */
+#define SPI_NOR_OCTAL_DTR_PP	BIT(19) /* Flash supports Octal DTR Page Program */
+#define SPI_NOR_IO_MODE_EN_VOLATILE	BIT(20) /*
 						 * Flash enables the best
 						 * available I/O mode via a
 						 * volatile bit.
 						 */
-#define SPI_NOR_SWP_IS_VOLATILE	BIT(22)	/*
+#define SPI_NOR_SWP_IS_VOLATILE	BIT(21)	/*
 					 * Flash has volatile software write
 					 * protection bits. Usually these will
 					 * power-up in a write-protected state.
 					 */
-#define SPI_NOR_PARSE_SFDP	BIT(23) /*
+#define SPI_NOR_PARSE_SFDP	BIT(22) /*
 					 * Flash initialized based on the SFDP
 					 * tables.
 					 */
@@ -569,4 +565,8 @@ static struct spi_nor __maybe_unused *mtd_to_spi_nor(struct mtd_info *mtd)
 	return mtd->priv;
 }
 
+static inline void snor_f_4b_opcodes(struct spi_nor *nor)
Maybe snor_set_f_4b_opcodes()?
quoted hunk
+{
+	nor->flags |= SNOR_F_4B_OPCODES;
+}
 #endif /* __LINUX_MTD_SPI_NOR_INTERNAL_H */
diff --git a/drivers/mtd/spi-nor/gigadevice.c b/drivers/mtd/spi-nor/gigadevice.c
index 447d84bb2128..ff523fe734ef 100644
--- a/drivers/mtd/spi-nor/gigadevice.c
+++ b/drivers/mtd/spi-nor/gigadevice.c
@@ -47,9 +47,10 @@ static const struct flash_info gigadevice_parts[] = {
 			   SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
 	{ "gd25q256", INFO(0xc84019, 0, 64 * 1024, 512,
 			   SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-			   SPI_NOR_4B_OPCODES | SPI_NOR_HAS_LOCK |
-			   SPI_NOR_HAS_TB | SPI_NOR_TB_SR_BIT6)
-		.fixups = &gd25q256_fixups },
+			   SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB |
+			   SPI_NOR_TB_SR_BIT6)
+		.fixups = &gd25q256_fixups,
+		.late_init = snor_f_4b_opcodes,	},
 };
 
 const struct spi_nor_manufacturer spi_nor_gigadevice = {
diff --git a/drivers/mtd/spi-nor/issi.c b/drivers/mtd/spi-nor/issi.c
index 1e5bb5408b68..aeff8f60cbae 100644
--- a/drivers/mtd/spi-nor/issi.c
+++ b/drivers/mtd/spi-nor/issi.c
@@ -45,9 +45,9 @@ static const struct flash_info issi_parts[] = {
 	{ "is25lp128",  INFO(0x9d6018, 0, 64 * 1024, 256,
 			     SECT_4K | SPI_NOR_DUAL_READ) },
 	{ "is25lp256",  INFO(0x9d6019, 0, 64 * 1024, 512,
-			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-			     SPI_NOR_4B_OPCODES)
-		.fixups = &is25lp256_fixups },
+			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
+		.fixups = &is25lp256_fixups,
+		.late_init = snor_f_4b_opcodes, },
 	{ "is25wp032",  INFO(0x9d7016, 0, 64 * 1024,  64,
 			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 	{ "is25wp064",  INFO(0x9d7017, 0, 64 * 1024, 128,
@@ -55,9 +55,9 @@ static const struct flash_info issi_parts[] = {
 	{ "is25wp128",  INFO(0x9d7018, 0, 64 * 1024, 256,
 			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 	{ "is25wp256", INFO(0x9d7019, 0, 64 * 1024, 512,
-			    SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-			    SPI_NOR_4B_OPCODES)
-		.fixups = &is25lp256_fixups },
+			    SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
+		.fixups = &is25lp256_fixups,
+		.late_init = snor_f_4b_opcodes, },
 
 	/* PMC */
 	{ "pm25lv512",   INFO(0,        0, 32 * 1024,    2, SECT_4K_PMC) },
diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c
index fba85efafb47..9709eb68b613 100644
--- a/drivers/mtd/spi-nor/macronix.c
+++ b/drivers/mtd/spi-nor/macronix.c
@@ -105,29 +105,31 @@ static const struct flash_info macronix_parts[] = {
 	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512,
 			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
 		.fixups = &mx25l25635_fixups },
-	{ "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512,
-			      SECT_4K | SPI_NOR_4B_OPCODES) },
+	{ "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K)
+		.late_init = snor_f_4b_opcodes, },
 	{ "mx25u51245g", INFO(0xc2253a, 0, 64 * 1024, 1024,
 			      SECT_4K | SPI_NOR_DUAL_READ |
-			      SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+			      SPI_NOR_QUAD_READ)
+		.late_init = snor_f_4b_opcodes, },
 	{ "mx25v8035f",  INFO(0xc22314, 0, 64 * 1024,  16,
 			      SECT_4K | SPI_NOR_DUAL_READ |
 			      SPI_NOR_QUAD_READ) },
 	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
 	{ "mx66l51235f", INFO(0xc2201a, 0, 64 * 1024, 1024,
-			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-			      SPI_NOR_4B_OPCODES) },
+			      SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
+		.late_init = snor_f_4b_opcodes, },
 	{ "mx66u51235f", INFO(0xc2253a, 0, 64 * 1024, 1024,
 			      SECT_4K | SPI_NOR_DUAL_READ |
-			      SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+			      SPI_NOR_QUAD_READ)
+		.late_init = snor_f_4b_opcodes, },
 	{ "mx66l1g45g",  INFO(0xc2201b, 0, 64 * 1024, 2048,
 			      SECT_4K | SPI_NOR_DUAL_READ |
 			      SPI_NOR_QUAD_READ) },
 	{ "mx66l1g55g",  INFO(0xc2261b, 0, 64 * 1024, 2048,
 			      SPI_NOR_QUAD_READ) },
 	{ "mx66u2g45g",	 INFO(0xc2253c, 0, 64 * 1024, 4096,
-			      SECT_4K | SPI_NOR_DUAL_READ |
-			      SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+			      SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
+		.late_init = snor_f_4b_opcodes, },
 };
 
 static void macronix_default_init(struct spi_nor *nor)
diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c
index c224e59820a1..72cc4673bf88 100644
--- a/drivers/mtd/spi-nor/micron-st.c
+++ b/drivers/mtd/spi-nor/micron-st.c
@@ -121,13 +121,13 @@ static struct spi_nor_fixups mt35xu512aba_fixups = {
 static const struct flash_info micron_parts[] = {
 	{ "mt35xu512aba", INFO(0x2c5b1a, 0, 128 * 1024, 512,
 			       SECT_4K | USE_FSR | SPI_NOR_OCTAL_READ |
-			       SPI_NOR_4B_OPCODES | SPI_NOR_OCTAL_DTR_READ |
-			       SPI_NOR_OCTAL_DTR_PP |
+			       SPI_NOR_OCTAL_DTR_READ | SPI_NOR_OCTAL_DTR_PP |
 			       SPI_NOR_IO_MODE_EN_VOLATILE)
-	  .fixups = &mt35xu512aba_fixups},
+	  .fixups = &mt35xu512aba_fixups,
+	  .late_init = snor_f_4b_opcodes, },
This flash populated the 4BAIT table, so you can simply drop the flag. 
No need for the late_init().

This makes me think that many other flashes might also have the 4BAIT 
table but the developers chose to add this flag here since at that time 
the norm was to populate all flash capabilities. I think we could be 
able to drop many more .late_init like this. But unfortunately someone 
needs to do the hard work of checking each flash, and most flash 
datasheets don't even list the SFDP contents.

So while I think in the ideal world we would go check each flash, I 
think this is an acceptable compromise. Let's not let perfection be the 
enemy of good.

While we are on this topic, I find this a bit "ugly". Having to set 
late_init() for setting these flags for each flash is not exactly very 
clean or readable. I don't know how the future will look like, but if 
each flash/family needs its own late_init() to set some flags, it won't 
be very readable. We seem to be trading one type of complexity for 
another. I dunno which is the lesser evil though...
quoted hunk
 	{ "mt35xu02g", INFO(0x2c5b1c, 0, 128 * 1024, 2048,
-			    SECT_4K | USE_FSR | SPI_NOR_OCTAL_READ |
-			    SPI_NOR_4B_OPCODES) },
+			    SECT_4K | USE_FSR | SPI_NOR_OCTAL_READ)
+	  .late_init = snor_f_4b_opcodes, },
 };
 
 static const struct flash_info st_parts[] = {
@@ -149,25 +149,29 @@ static const struct flash_info st_parts[] = {
 			      SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
 	{ "mt25ql256a",  INFO6(0x20ba19, 0x104400, 64 * 1024,  512,
 			       SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
-			       SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+			       SPI_NOR_QUAD_READ)
+	  .late_init = snor_f_4b_opcodes, },
 	{ "n25q256a",    INFO(0x20ba19, 0, 64 * 1024,  512, SECT_4K |
 			      USE_FSR | SPI_NOR_DUAL_READ |
 			      SPI_NOR_QUAD_READ) },
 	{ "mt25qu256a",  INFO6(0x20bb19, 0x104400, 64 * 1024,  512,
 			       SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
-			       SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+			       SPI_NOR_QUAD_READ)
+	  .late_init = snor_f_4b_opcodes, },
 	{ "n25q256ax1",  INFO(0x20bb19, 0, 64 * 1024,  512,
 			      SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
 	{ "mt25ql512a",  INFO6(0x20ba20, 0x104400, 64 * 1024, 1024,
 			       SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
-			       SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+			       SPI_NOR_QUAD_READ)
+	  .late_init = snor_f_4b_opcodes, },
 	{ "n25q512ax3",  INFO(0x20ba20, 0, 64 * 1024, 1024,
 			      SECT_4K | USE_FSR | SPI_NOR_QUAD_READ |
 			      SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB |
 			      SPI_NOR_4BIT_BP | SPI_NOR_BP3_SR_BIT6) },
 	{ "mt25qu512a",  INFO6(0x20bb20, 0x104400, 64 * 1024, 1024,
 			       SECT_4K | USE_FSR | SPI_NOR_DUAL_READ |
-			       SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) },
+			       SPI_NOR_QUAD_READ)
+	  .late_init = snor_f_4b_opcodes, },
 	{ "n25q512a",    INFO(0x20bb20, 0, 64 * 1024, 1024,
 			      SECT_4K | USE_FSR | SPI_NOR_QUAD_READ |
 			      SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB |
diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c
index aad7170768b4..af10833f56d8 100644
--- a/drivers/mtd/spi-nor/spansion.c
+++ b/drivers/mtd/spi-nor/spansion.c
@@ -259,14 +259,14 @@ static const struct flash_info spansion_parts[] = {
 	{ "s25fl208k",  INFO(0x014014,      0,  64 * 1024,  16,
 			     SECT_4K | SPI_NOR_DUAL_READ) },
 	{ "s25fl064l",  INFO(0x016017,      0,  64 * 1024, 128,
-			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-			     SPI_NOR_4B_OPCODES) },
+			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
+		.late_init = snor_f_4b_opcodes, },
 	{ "s25fl128l",  INFO(0x016018,      0,  64 * 1024, 256,
-			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-			     SPI_NOR_4B_OPCODES) },
+			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
+		.late_init = snor_f_4b_opcodes, },
 	{ "s25fl256l",  INFO(0x016019,      0,  64 * 1024, 512,
-			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-			     SPI_NOR_4B_OPCODES) },
+			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
+		.late_init = snor_f_4b_opcodes, },
 	{ "cy15x104q",  INFO6(0x042cc2, 0x7f7f7f, 512 * 1024, 1,
 			      SPI_NOR_NO_ERASE) },
 	{ "s28hs512t",   INFO(0x345b1a,      0, 256 * 1024, 256,
-- 
2.25.1
-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 19/35] mtd: spi-nor: Get rid of SPI_NOR_IO_MODE_EN_VOLATILE flag

From: Pratyush Yadav <hidden>
Date: 2021-08-17 12:24:14

On 27/07/21 07:52AM, Tudor Ambarus wrote:
quoted hunk
Get rid of flash_info flags that indicate settings which can be
discovered when parsing SFDP. It will be clearer who sets what,
and we'll restrict the flash settings that a developer can choose to
only settings that are not SFDP discoverable.

SNOR_F_IO_MODE_EN_VOLATILE is discoverable when parsing the optional
SCCR Map SFDP table. Flashes that do not define this table should set
the flag in the late_init() call. Flashes that define the SFDP optional
table but get the value wrong, should fix it in a post_sfdp fixup hook.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c      |  3 ---
 drivers/mtd/spi-nor/core.h      |  9 ++-------
 drivers/mtd/spi-nor/micron-st.c | 11 ++++++++---
 3 files changed, 10 insertions(+), 13 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 240d5c31af88..9885d434ea83 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -3204,9 +3204,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 	if (ret)
 		return ret;
 
-	if (info->flags & SPI_NOR_IO_MODE_EN_VOLATILE)
-		nor->flags |= SNOR_F_IO_MODE_EN_VOLATILE;
-
 	ret = spi_nor_set_addr_width(nor);
 	if (ret)
 		return ret;
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index dfdc51a26cad..987797a789c8 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -367,17 +367,12 @@ struct flash_info {
 					 */
 #define SPI_NOR_OCTAL_DTR_READ	BIT(18) /* Flash supports octal DTR Read. */
 #define SPI_NOR_OCTAL_DTR_PP	BIT(19) /* Flash supports Octal DTR Page Program */
-#define SPI_NOR_IO_MODE_EN_VOLATILE	BIT(20) /*
-						 * Flash enables the best
-						 * available I/O mode via a
-						 * volatile bit.
We are losing the information contained in the comment. I think you 
should move it to SNOR_F_IO_MODE_EN_VOLATILE's declaration.
quoted hunk
-						 */
-#define SPI_NOR_SWP_IS_VOLATILE	BIT(21)	/*
+#define SPI_NOR_SWP_IS_VOLATILE	BIT(20)	/*
 					 * Flash has volatile software write
 					 * protection bits. Usually these will
 					 * power-up in a write-protected state.
 					 */
-#define SPI_NOR_PARSE_SFDP	BIT(22) /*
+#define SPI_NOR_PARSE_SFDP	BIT(21) /*
 					 * Flash initialized based on the SFDP
 					 * tables.
 					 */
diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c
index 72cc4673bf88..31ebd4c9b431 100644
--- a/drivers/mtd/spi-nor/micron-st.c
+++ b/drivers/mtd/spi-nor/micron-st.c
@@ -118,13 +118,18 @@ static struct spi_nor_fixups mt35xu512aba_fixups = {
 	.post_sfdp = mt35xu512aba_post_sfdp_fixup,
 };
 
+static void mt35xu512aba_late_init(struct spi_nor *nor)
+{
+	nor->flags |= SNOR_F_4B_OPCODES;
Like I mentioned in the previous email, you can drop this since the 
flash populates the 4BAIT table.
+	nor->flags |= SNOR_F_IO_MODE_EN_VOLATILE;
+}
+
 static const struct flash_info micron_parts[] = {
 	{ "mt35xu512aba", INFO(0x2c5b1a, 0, 128 * 1024, 512,
 			       SECT_4K | USE_FSR | SPI_NOR_OCTAL_READ |
-			       SPI_NOR_OCTAL_DTR_READ | SPI_NOR_OCTAL_DTR_PP |
-			       SPI_NOR_IO_MODE_EN_VOLATILE)
+			       SPI_NOR_OCTAL_DTR_READ | SPI_NOR_OCTAL_DTR_PP)
 	  .fixups = &mt35xu512aba_fixups,
-	  .late_init = snor_f_4b_opcodes, },
+	  .late_init = mt35xu512aba_late_init, },
 	{ "mt35xu02g", INFO(0x2c5b1c, 0, 128 * 1024, 2048,
 			    SECT_4K | USE_FSR | SPI_NOR_OCTAL_READ)
 	  .late_init = snor_f_4b_opcodes, },
I forgot to say this in the previous email, but since this flash is the 
same family as the one above, it should also have the 4BAIT table, and 
should not need this late_init. But I don't have access to this part so 
I can't say with 100% certainty.
-- 
2.25.1
-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 20/35] mtd: spi-nor: core: Use container_of to get the pointer to struct spi_nor

From: Pratyush Yadav <hidden>
Date: 2021-08-17 12:27:17

On 27/07/21 07:52AM, Tudor Ambarus wrote:
Get the pointer to the containing struct spi_nor by using container_of.
Please add an explanation on _why_ you are doing this. I suspect it 
would be something boring like "because mtd is embedded in nor, no need 
to use mtd->priv", but good to have it here regardless.
quoted hunk
Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c | 1 -
 drivers/mtd/spi-nor/core.h | 2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 9885d434ea83..5c8cffb5e6f2 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -3175,7 +3175,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 
 	if (!mtd->name)
 		mtd->name = dev_name(dev);
-	mtd->priv = nor;
 	mtd->type = MTD_NORFLASH;
 	mtd->writesize = nor->params->writesize;
 	mtd->flags = MTD_CAP_NORFLASH;
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 987797a789c8..8fddc685d2d3 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -557,7 +557,7 @@ void spi_nor_otp_init(struct spi_nor *nor);
 
 static struct spi_nor __maybe_unused *mtd_to_spi_nor(struct mtd_info *mtd)
 {
-	return mtd->priv;
+	return container_of(mtd, struct spi_nor, mtd);
 }
 
 static inline void snor_f_4b_opcodes(struct spi_nor *nor)
-- 
2.25.1
-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 21/35] mtd: spi-nor: Introduce spi_nor_set_mtd_info()

From: Pratyush Yadav <hidden>
Date: 2021-08-17 16:26:32

On 27/07/21 07:52AM, Tudor Ambarus wrote:
quoted hunk
Used to init all the mtd_info fields. Move the mtd_info init
the last thing in the spi_nor_scan(), so that we avoid superfluous
initialization of the mtd_info fields in case of errors.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c | 55 +++++++++++++++++++++-----------------
 1 file changed, 31 insertions(+), 24 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 5c8cffb5e6f2..26acfc9901db 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -3124,6 +3124,36 @@ static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor,
 	return info;
 }
 
+static void spi_nor_set_mtd_info(struct spi_nor *nor)
+{
+	struct mtd_info *mtd = &nor->mtd;
+	struct device *dev = nor->dev;
+
+	spi_nor_register_locking_ops(nor);
+
+	/* Configure OTP parameters and ops */
+	spi_nor_otp_init(nor);
+
+	mtd->dev.parent = dev;
+	if (!mtd->name)
+		mtd->name = dev_name(dev);
+	mtd->priv = nor;
You remove the lines setting mtd->priv in the previous patch. Why add it 
back?

Other than this,

Reviewed-by: Pratyush Yadav <redacted>
quoted hunk
+	mtd->type = MTD_NORFLASH;
+	mtd->flags = MTD_CAP_NORFLASH;
+	if (nor->info->flags & SPI_NOR_NO_ERASE)
+		mtd->flags |= MTD_NO_ERASE;
+	mtd->writesize = nor->params->writesize;
+	mtd->writebufsize = nor->page_size;
+	mtd->size = nor->params->size;
+	mtd->_erase = spi_nor_erase;
+	mtd->_read = spi_nor_read;
+	mtd->_write = spi_nor_write;
+	mtd->_suspend = spi_nor_suspend;
+	mtd->_resume = spi_nor_resume;
+	mtd->_get_device = spi_nor_get_device;
+	mtd->_put_device = spi_nor_put_device;
+}
+
 int spi_nor_scan(struct spi_nor *nor, const char *name,
 		 const struct spi_nor_hwcaps *hwcaps)
 {
@@ -3166,32 +3196,12 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 
 	mutex_init(&nor->lock);
 
-	mtd->_write = spi_nor_write;
-
 	/* Init flash parameters based on flash_info struct and SFDP */
 	ret = spi_nor_init_params(nor);
 	if (ret)
 		return ret;
 
-	if (!mtd->name)
-		mtd->name = dev_name(dev);
-	mtd->type = MTD_NORFLASH;
-	mtd->writesize = nor->params->writesize;
-	mtd->flags = MTD_CAP_NORFLASH;
-	mtd->size = nor->params->size;
-	mtd->_erase = spi_nor_erase;
-	mtd->_read = spi_nor_read;
-	mtd->_suspend = spi_nor_suspend;
-	mtd->_resume = spi_nor_resume;
-	mtd->_get_device = spi_nor_get_device;
-	mtd->_put_device = spi_nor_put_device;
-
-	if (info->flags & SPI_NOR_NO_ERASE)
-		mtd->flags |= MTD_NO_ERASE;
-
-	mtd->dev.parent = dev;
 	nor->page_size = nor->params->page_size;
-	mtd->writebufsize = nor->page_size;
 
 	/*
 	 * Configure the SPI memory:
@@ -3207,15 +3217,12 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 	if (ret)
 		return ret;
 
-	spi_nor_register_locking_ops(nor);
-
 	/* Send all the required SPI flash commands to initialize device */
 	ret = spi_nor_init(nor);
 	if (ret)
 		return ret;
 
-	/* Configure OTP parameters and ops */
-	spi_nor_otp_init(nor);
+	spi_nor_set_mtd_info(nor);
 
 	if (!nor->name)
 		nor->name = info->name;
-- 
2.25.1
-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 22/35] mtd: spi-nor: core: Use common naming scheme for setting mtd_info fields

From: Pratyush Yadav <hidden>
Date: 2021-08-17 16:28:32

On 27/07/21 07:52AM, Tudor Ambarus wrote:
The functions names are self explanatory, get rid of the comment
for the OTP function.

Signed-off-by: Tudor Ambarus <redacted>
Reviewed-by: Pratyush Yadav <redacted>
quoted hunk
---
 drivers/mtd/spi-nor/core.c | 6 ++----
 drivers/mtd/spi-nor/core.h | 4 ++--
 drivers/mtd/spi-nor/otp.c  | 2 +-
 drivers/mtd/spi-nor/swp.c  | 2 +-
 4 files changed, 6 insertions(+), 8 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 26acfc9901db..72dfe6274041 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -3129,10 +3129,8 @@ static void spi_nor_set_mtd_info(struct spi_nor *nor)
 	struct mtd_info *mtd = &nor->mtd;
 	struct device *dev = nor->dev;
 
-	spi_nor_register_locking_ops(nor);
-
-	/* Configure OTP parameters and ops */
-	spi_nor_otp_init(nor);
+	spi_nor_set_mtd_locking_ops(nor);
+	spi_nor_set_mtd_otp_ops(nor);
 
 	mtd->dev.parent = dev;
 	if (!mtd->name)
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 8fddc685d2d3..7fb0cfabe85a 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -552,8 +552,8 @@ int spi_nor_post_bfpt_fixups(struct spi_nor *nor,
 
 void spi_nor_init_default_locking_ops(struct spi_nor *nor);
 void spi_nor_try_unlock_all(struct spi_nor *nor);
-void spi_nor_register_locking_ops(struct spi_nor *nor);
-void spi_nor_otp_init(struct spi_nor *nor);
+void spi_nor_set_mtd_locking_ops(struct spi_nor *nor);
+void spi_nor_set_mtd_otp_ops(struct spi_nor *nor);
 
 static struct spi_nor __maybe_unused *mtd_to_spi_nor(struct mtd_info *mtd)
 {
diff --git a/drivers/mtd/spi-nor/otp.c b/drivers/mtd/spi-nor/otp.c
index 983e40b19134..fa63d8571218 100644
--- a/drivers/mtd/spi-nor/otp.c
+++ b/drivers/mtd/spi-nor/otp.c
@@ -480,7 +480,7 @@ static int spi_nor_mtd_otp_lock(struct mtd_info *mtd, loff_t from, size_t len)
 	return ret;
 }
 
-void spi_nor_otp_init(struct spi_nor *nor)
+void spi_nor_set_mtd_otp_ops(struct spi_nor *nor)
 {
 	struct mtd_info *mtd = &nor->mtd;
 
diff --git a/drivers/mtd/spi-nor/swp.c b/drivers/mtd/spi-nor/swp.c
index 8594bcbb7dbe..1f178313ba8f 100644
--- a/drivers/mtd/spi-nor/swp.c
+++ b/drivers/mtd/spi-nor/swp.c
@@ -414,7 +414,7 @@ void spi_nor_try_unlock_all(struct spi_nor *nor)
 		dev_dbg(nor->dev, "Failed to unlock the entire flash memory array\n");
 }
 
-void spi_nor_register_locking_ops(struct spi_nor *nor)
+void spi_nor_set_mtd_locking_ops(struct spi_nor *nor)
 {
 	struct mtd_info *mtd = &nor->mtd;
 
-- 
2.25.1
-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 23/35] mtd: spi-nor: Get rid of nor->page_size

From: Pratyush Yadav <hidden>
Date: 2021-08-17 16:35:56

On 27/07/21 07:52AM, Tudor Ambarus wrote:
nor->page_size duplicated what nor->params->page_size indicates
for no good reason. page_size is a flash parameter of fixed value
and it is better suited to be found in nor->params->page_size.

Signed-off-by: Tudor Ambarus <redacted>
Reviewed-by: Pratyush Yadav <redacted>

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 24/35] mtd: spi-nor: core: Fix spi_nor_flash_parameter otp description

From: Pratyush Yadav <hidden>
Date: 2021-08-17 16:50:44

On 27/07/21 07:52AM, Tudor Ambarus wrote:
Update the description of the otp member of the
struct spi_nor_flash_parameter.

Signed-off-by: Tudor Ambarus <redacted>
Reviewed-by: Pratyush Yadav <redacted>
quoted hunk
---
 drivers/mtd/spi-nor/core.h | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 7fb0cfabe85a..501d9212ba9b 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -250,7 +250,7 @@ struct spi_nor_otp {
  *                      higher index in the array, the higher priority.
  * @erase_map:		the erase map parsed from the SFDP Sector Map Parameter
  *                      Table.
- * @otp_info:		describes the OTP regions.
+ * @otp:		SPI NOR OTP info.
  * @octal_dtr_enable:	enables SPI NOR octal DTR mode.
  * @quad_enable:	enables SPI NOR quad mode.
  * @set_4byte_addr_mode: puts the SPI NOR in 4 byte addressing mode.
@@ -262,7 +262,6 @@ struct spi_nor_otp {
  *                      e.g. different opcodes, specific address calculation,
  *                      page size, etc.
  * @locking_ops:	SPI NOR locking methods.
- * @otp:		SPI NOR OTP methods.
  */
 struct spi_nor_flash_parameter {
 	u64				size;
-- 
2.25.1
-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 25/35] mtd: spi-nor: core: Move spi_nor_set_addr_width() in spi_nor_setup()

From: Pratyush Yadav <hidden>
Date: 2021-08-17 16:56:59

On 27/07/21 07:52AM, Tudor Ambarus wrote:
spi_nor_setup() configures the SPI NOR memory. Setting the addr width
is too a configuration, hence we can move the spi_nor_set_addr_width()
in spi_nor_setup().

Signed-off-by: Tudor Ambarus <redacted>
Reviewed-by: Pratyush Yadav <redacted>

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 01/35] mtd: spi-nor: core: Introduce SPI_NOR_PARSE_SFDP

From: Michael Walle <hidden>
Date: 2021-08-23 22:20:21

Am 2021-07-27 06:51, schrieb Tudor Ambarus:
SPI NOR flashes that statically declare one of the
SPI_NOR_{DUAL, QUAD, OCTAL, OCTAL_DTR}_READ flags and do not support
the RDSFDP command are gratuiously receiving the RDSFDP command
in the attempt of parsing the SFDP tables. It is not desirable to issue
commands that are not supported, so introduce a flag to help on this
situation.

New flash additions that support the SFDP standard should be declared
using SPI_NOR_PARSE_SFDP. Support that can be discovered when parsing
SFDP should not be duplicated by explicit flags at flash declaration.
All the flash parameters will be discovered when parsing SFDP.
Sometimes manufacturers wrongly define some fields in the SFDP tables.
If that's the case, SFDP data can be amended with the fixups() hooks.
It is not common, but if the SFDP tables are entirely wrong, and it
does not worth the hassle to tweak the SFDP parameters by using the
fixups hooks, or if the flash does not define the SFDP tables at all,
then statically init the flash with the SPI_NOR_SKIP_SFDP flag and
specify the rest of flash capabilities with the flash info flags.

With time, we want to convert all flashes to SPI_NOR_PARSE_SFDP and
stop triggering the SFDP parsing with the
SPI_NOR_{DUAL, QUAD, OCTAL*}_READ flags. Getting rid of the
SPI_NOR_{OCTAL, OCTAL_DTR}_READ trigger is easily achievable, the rest
are a long term goal.

Signed-off-by: Tudor Ambarus <redacted>
Reviewed-by: Heiko Thiery <redacted>
Reviewed-by: Michael Walle <redacted>

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

Re: [PATCH v2 02/35] mtd: spi-nor: core: Report correct name in case of ID collisions

From: Michael Walle <hidden>
Date: 2021-08-23 22:34:56

Am 2021-08-04 10:23, schrieb Pratyush Yadav:
On 27/07/21 07:51AM, Tudor Ambarus wrote:
quoted
Provide a way to report the correct flash name in case of ID 
collisions.
There will be a single flash_info entry when flash IDs collide, and 
the
differentiation between the flash types will be made at runtime
if possible.
I have the same comments as last time around. I am not convinced that
this approach is better than having multiple entries, one for each
colliding flash. I wonder how you will handle different fixups for the
colliding flashes for example, since nor->info is const.
I thought of multple entries in xx_parts[], too. But how would you 
choose
between those? The flash id is the same, only the name would be 
different.
Searching by name seems cumbersome. Also, the fixup of the first match
will change the pointer (or maybe an additional pointer, so we still
have the original match), and thus also changes the pointer to the fixup
itself.

-michael

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

Re: [PATCH v2 03/35] mtd: spi-nor: macronix: Handle ID collision b/w MX25L3233F and MX25L3205D

From: Michael Walle <hidden>
Date: 2021-08-23 22:44:30

Am 2021-07-27 06:51, schrieb Tudor Ambarus:
Macronix has a bad habbit of reusing flash IDs. While MX25L3233F 
supports
RDSFDP opcode, MX25L3205D does not support it and does not recommend
issuing opcodes that are not supported ("It is not recommended to adopt
any other code not in the command definition table, which will 
potentially
enter the hidden mode.").

We tested the RDSFDP on the MX25L3205D and the conclusion is that the
flash didn't reply anything. Given that it is unlikely that RDSFDP will
cause any problems for the old MX25L3205D, differentiate between the 
two
flashes by parsing SFDP.

Tested MX25L3233F. Generated a 256 Kbyte random data and did an erase,
write, read back and compare test. The flash uses for reads
SPINOR_OP_READ_1_4_4 0xeb, for erases SPINOR_OP_BE_4K 0x20, and for 
writes
SPINOR_OP_PP 0x02.

Signed-off-by: Tudor Ambarus <redacted>
Acked-by: Pratyush Yadav <redacted>
---
root@sama5d2-xplained:~# find / -iname spi-nor
/sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor
/sys/devices/platform/ahb/ahb:apb/f8000000.spi/spi_master/spi0/spi0.0/spi-nor
/sys/bus/spi/drivers/spi-nor
root@sama5d2-xplained:~# ls -al
/sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor
total 0
drwxr-xr-x 2 root root    0 Mar  9 14:51 .
drwxr-xr-x 6 root root    0 Mar  9 14:50 ..
-r--r--r-- 1 root root 4096 Mar  9 14:51 jedec_id
-r--r--r-- 1 root root 4096 Mar  9 14:51 manufacturer
-r--r--r-- 1 root root 4096 Mar  9 14:51 partname
-r--r--r-- 1 root root    0 Mar  9 14:51 sfdp
root@sama5d2-xplained:~# cat
/sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/jedec_id
c22016
root@sama5d2-xplained:~# cat
/sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/manufacturer
macronix
root@sama5d2-xplained:~# cat
/sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/partname
mx25l3233f
root@sama5d2-xplained:~# cat
/sys/devices/platform/ahb/ahb:apb/f0020000.spi/spi_master/spi1/spi1.0/spi-nor/sfdp
quoted
mx25l3233f-sfdp
root@sama5d2-xplained:~# hexdump mx25l3233f-sfdp
use xxd if possible and the sha1sum/md5sum is missing.
quoted hunk
0000000 4653 5044 0100 ff01 0000 0901 0030 ff00
0000010 00c2 0401 0060 ff00 ffff ffff ffff ffff
0000020 ffff ffff ffff ffff ffff ffff ffff ffff
0000030 20e5 fff1 ffff 01ff eb44 6b08 3b08 bb04
0000040 ffee ffff ffff ff00 ffff ff00 200c 520f
0000050 d810 ff00 ffff ffff ffff ffff ffff ffff
0000060 3600 2650 f99c 6477 cffe ffff ffff ffff
0000070

 drivers/mtd/spi-nor/macronix.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/drivers/mtd/spi-nor/macronix.c 
b/drivers/mtd/spi-nor/macronix.c
index 27498ed0cc0d..68f6ac060bc6 100644
--- a/drivers/mtd/spi-nor/macronix.c
+++ b/drivers/mtd/spi-nor/macronix.c
@@ -8,6 +8,24 @@

 #include "core.h"

+static int mx25l3233f_post_bfpt_fixups(struct spi_nor *nor,
+				const struct sfdp_parameter_header *bfpt_header,
+				const struct sfdp_bfpt *bfpt)
+{
+	/*
+	 * Macronix has a bad habit of reusing flash IDs: MX25L3233F collides
+	 * with MX25L3205D. MX25L3233F defines SFDP tables, while the older
+	 * variant does not.
+	 */
+	nor->name = "mx25l3233f";
+
+	return 0;
+}
+
+static struct spi_nor_fixups mx25l3233f_fixups = {
+	.post_bfpt = mx25l3233f_post_bfpt_fixups,
+};
+
 static int
 mx25l25635_post_bfpt_fixups(struct spi_nor *nor,
 			    const struct sfdp_parameter_header *bfpt_header,
@@ -39,7 +57,10 @@ static const struct flash_info macronix_parts[] = {
 	{ "mx25l4005a",  INFO(0xc22013, 0, 64 * 1024,   8, SECT_4K) },
 	{ "mx25l8005",   INFO(0xc22014, 0, 64 * 1024,  16, 0) },
 	{ "mx25l1606e",  INFO(0xc22015, 0, 64 * 1024,  32, SECT_4K) },
-	{ "mx25l3205d",  INFO(0xc22016, 0, 64 * 1024,  64, SECT_4K) },
+	{ "mx25l3205d",  INFO(0xc22016, 0, 64 * 1024,  64, SPI_NOR_PARSE_SFDP 
|
+			      SECT_4K)
+		/* ID collision with mx25l3233f. */
+		.fixups = &mx25l3233f_fixups },
Shouldn't we use mx25l3205d_fixups as name here? What if there are more
flashes with the same id. Using the name of the colliding flash here
doesn't really scale.

-michael
 	{ "mx25l3255e",  INFO(0xc29e16, 0, 64 * 1024,  64, SECT_4K) },
 	{ "mx25l6405d",  INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) },
 	{ "mx25u2033e",  INFO(0xc22532, 0, 64 * 1024,   4, SECT_4K) },
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v2 04/35] mtd: spi-nor: macronix: Handle ID collision b/w MX25L12805D and MX25L12835F

From: Michael Walle <hidden>
Date: 2021-08-23 22:46:23

Am 2021-07-27 06:51, schrieb Tudor Ambarus:
MX25L12835F define SFDP, while MX25L12805D does not.

Signed-off-by: Tudor Ambarus <redacted>
Testd-by: Heiko Thiery [off-list ref]
Acked-by: Pratyush Yadav <redacted>
Same remarks as patch #3.

-michael
quoted hunk
# cat 
/sys/devices/platform/soc@0/30800000.bus/30bb0000.spi/spi_master/spi0/spi0
.0/spi-nor/sfdp | xxd -p
53464450000101ff00000109300000ffc2000104600000ffffffffffffff
ffffffffffffffffffffffffffffffffffffe520f1ffffffff0744eb086b
083b04bbfeffffffffff00ffffff44eb0c200f5210d800ffffffffffffff
ffffffffffff003600279df9c06485cbffffffffffff

 drivers/mtd/spi-nor/macronix.c | 24 ++++++++++++++++++++++--
 1 file changed, 22 insertions(+), 2 deletions(-)
diff --git a/drivers/mtd/spi-nor/macronix.c 
b/drivers/mtd/spi-nor/macronix.c
index 68f6ac060bc6..fba85efafb47 100644
--- a/drivers/mtd/spi-nor/macronix.c
+++ b/drivers/mtd/spi-nor/macronix.c
@@ -8,6 +8,24 @@

 #include "core.h"

+static int mx25l12835f_post_bfpt_fixups(struct spi_nor *nor,
+				const struct sfdp_parameter_header *bfpt_header,
+				const struct sfdp_bfpt *bfpt)
+{
+	/*
+	 * Macronix has a bad habit of reusing flash IDs: MX25L12835F 
collides
+	 * with MX25L12805D. MX25L12835F defines SFDP tables, while the older
+	 * variant does not.
+	 */
+	nor->name = "mx25l12835f";
+
+	return 0;
+}
+
+static struct spi_nor_fixups mx25l12835f_fixups = {
+	.post_bfpt = mx25l12835f_post_bfpt_fixups,
+};
+
 static int mx25l3233f_post_bfpt_fixups(struct spi_nor *nor,
 				const struct sfdp_parameter_header *bfpt_header,
 				const struct sfdp_bfpt *bfpt)
@@ -70,8 +88,10 @@ static const struct flash_info macronix_parts[] = {
 	{ "mx25u4035",   INFO(0xc22533, 0, 64 * 1024,   8, SECT_4K) },
 	{ "mx25u8035",   INFO(0xc22534, 0, 64 * 1024,  16, SECT_4K) },
 	{ "mx25u6435f",  INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) },
-	{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, SECT_4K |
-			      SPI_NOR_HAS_LOCK | SPI_NOR_4BIT_BP) },
+	{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, SPI_NOR_PARSE_SFDP 
|
+			      SECT_4K | SPI_NOR_HAS_LOCK | SPI_NOR_4BIT_BP)
+		/* ID collision with mx25l12835f. */
+		.fixups = &mx25l12835f_fixups },
 	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
 	{ "mx25r1635f",  INFO(0xc22815, 0, 64 * 1024,  32,
 			      SECT_4K | SPI_NOR_DUAL_READ |
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v2 05/35] mtd: spi-nor: Introduce Manufacturer ID collisions driver

From: Michael Walle <hidden>
Date: 2021-08-23 22:49:38

Am 2021-07-27 06:51, schrieb Tudor Ambarus:
quoted hunk
Some manufacturers completely ignore the manufacturer's identification 
code
standard (JEP106) and do not define the manufacturer ID continuation
scheme. This will result in manufacturer ID collisions.

An an example, JEP106BA requires Boya that it's manufacturer ID to be
preceded by 8 continuation codes. Boya's identification code must be:
0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x68. But Boya ignores 
the
continuation scheme and its ID collides with the manufacturer defined 
in
bank one: Convex Computer.

Introduce the manuf-id-collisions driver in order to address ID 
collisions
between manufacturers. flash_info entries will be added in a first 
come,
first served manner. Differentiation between flashes will be done at
runtime if possible. Where runtime differentiation is not possible, new
compatibles will be introduced, but this will be done as a last resort.
Every new flash addition that define the SFDP tables, should dump its 
SFDP
tables in the patch's comment section below the --- line, so that we 
can
reference it in case of collisions.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/Makefile              |  1 +
 drivers/mtd/spi-nor/core.c                |  1 +
 drivers/mtd/spi-nor/core.h                |  1 +
 drivers/mtd/spi-nor/manuf-id-collisions.c | 22 ++++++++++++++++++++++
 4 files changed, 25 insertions(+)
 create mode 100644 drivers/mtd/spi-nor/manuf-id-collisions.c
diff --git a/drivers/mtd/spi-nor/Makefile 
b/drivers/mtd/spi-nor/Makefile
index 6b904e439372..48763d10daad 100644
--- a/drivers/mtd/spi-nor/Makefile
+++ b/drivers/mtd/spi-nor/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0

 spi-nor-objs			:= core.o sfdp.o swp.o otp.o sysfs.o
+spi-nor-objs			+= manuf-id-collisions.o
 spi-nor-objs			+= atmel.o
 spi-nor-objs			+= catalyst.o
 spi-nor-objs			+= eon.o
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 1a278d33b02d..d30c8f350dc1 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -1829,6 +1829,7 @@ int spi_nor_sr2_bit7_quad_enable(struct spi_nor 
*nor)
 }

 static const struct spi_nor_manufacturer *manufacturers[] = {
+	&spi_nor_manuf_id_collisions,
Intentionally at the beginning of all the flashes? So these
might take precedence over "normal" ones? Shouldn't it be
the other way around?
quoted hunk
 	&spi_nor_atmel,
 	&spi_nor_catalyst,
 	&spi_nor_eon,
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 55fceb0ec894..e9896cd60695 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -476,6 +476,7 @@ struct sfdp {
 };

 /* Manufacturer drivers. */
+extern const struct spi_nor_manufacturer spi_nor_manuf_id_collisions;
 extern const struct spi_nor_manufacturer spi_nor_atmel;
 extern const struct spi_nor_manufacturer spi_nor_catalyst;
 extern const struct spi_nor_manufacturer spi_nor_eon;
diff --git a/drivers/mtd/spi-nor/manuf-id-collisions.c
b/drivers/mtd/spi-nor/manuf-id-collisions.c
new file mode 100644
index 000000000000..bf7dba34f018
--- /dev/null
+++ b/drivers/mtd/spi-nor/manuf-id-collisions.c
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Used to handle collisions between manufacturers, where 
manufacturers are
+ * ignorant enough to not implement the ID continuation scheme 
described in the
+ * JEP106 JEDEC standard.
+ */
+
+#include <linux/mtd/spi-nor.h>
+#include "core.h"
+
+static const struct flash_info id_collision_parts[] = {
+	/* Boya */
+	{ "by25q128as", INFO(0x684018, 0, 64 * 1024, 256, SPI_NOR_SKIP_SFDP |
+			     SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+			     SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) },
+};
+
+const struct spi_nor_manufacturer spi_nor_manuf_id_collisions = {
+	.name = "manufacturer ID collisions",
mhh, so we loose the manufacturer name. Doh. Can we do better?

-michael
+	.parts = id_collision_parts,
+	.nparts = ARRAY_SIZE(id_collision_parts),
+};
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Re: [PATCH v2 26/35] mtd: spi-nor: core: Introduce spi_nor_init_default_params()

From: Pratyush Yadav <hidden>
Date: 2021-08-24 17:33:09

On 27/07/21 07:52AM, Tudor Ambarus wrote:
quoted hunk
Called for all flashes, regardless if they define SFDP tables or not.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c | 92 +++++++++++++++++++++-----------------
 1 file changed, 52 insertions(+), 40 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index b3a01d7d6f0b..9193317f897d 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2543,6 +2543,56 @@ static int spi_nor_setup(struct spi_nor *nor,
 	return spi_nor_set_addr_width(nor);
 }
 
+/**
+ * spi_nor_init_default_params() - Default initialization of flash parameters
+ * and settings. Done for all flashes, regardless is they define SFDP tables
+ * or not.
+ * @nor:	pointer to a 'struct spi_nor'.
+ */
+static void spi_nor_init_default_params(struct spi_nor *nor)
+{
+	struct spi_nor_flash_parameter *params = nor->params;
+	const struct flash_info *info = nor->info;
+	struct device_node *np = spi_nor_get_flash_node(nor);
+
+	params->quad_enable = spi_nor_sr2_bit1_quad_enable;
+	params->set_4byte_addr_mode = spansion_set_4byte_addr_mode;
+	params->setup = spi_nor_default_setup;
+	params->otp.org = &info->otp_org;
+
+	/* Default to 16-bit Write Status (01h) Command */
+	nor->flags |= SNOR_F_HAS_16BIT_SR;
+
+	/* Set SPI NOR sizes. */
+	params->writesize = 1;
+	params->size = (u64)info->sector_size * info->n_sectors;
+	params->page_size = info->page_size;
I think these two lines should go in spi_nor_info_init_params() since 
you are using the nor info to initialize these parameters. Otherwise, 
what even is the difference between these two functions?
quoted hunk
+
+	if (!(info->flags & SPI_NOR_NO_FR)) {
+		/* Default to Fast Read for DT and non-DT platform devices. */
+		params->hwcaps.mask |= SNOR_HWCAPS_READ_FAST;
+
+		/* Mask out Fast Read if not requested at DT instantiation. */
+		if (np && !of_property_read_bool(np, "m25p,fast-read"))
+			params->hwcaps.mask &= ~SNOR_HWCAPS_READ_FAST;
+	}
+
+	/* (Fast) Read settings. */
+	params->hwcaps.mask |= SNOR_HWCAPS_READ;
+	spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ],
+				  0, 0, SPINOR_OP_READ,
+				  SNOR_PROTO_1_1_1);
+
+	if (params->hwcaps.mask & SNOR_HWCAPS_READ_FAST)
+		spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ_FAST],
+					  0, 8, SPINOR_OP_READ_FAST,
+					  SNOR_PROTO_1_1_1);
+	/* Page Program settings. */
+	params->hwcaps.mask |= SNOR_HWCAPS_PP;
+	spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP],
+				SPINOR_OP_PP, SNOR_PROTO_1_1_1);
+}
+
 /**
  * spi_nor_manufacturer_init_params() - Initialize the flash's parameters and
  * settings based on MFR register and ->default_init() hook.
@@ -2609,43 +2659,8 @@ static void spi_nor_info_init_params(struct spi_nor *nor)
 	struct spi_nor_flash_parameter *params = nor->params;
 	struct spi_nor_erase_map *map = &params->erase_map;
 	const struct flash_info *info = nor->info;
-	struct device_node *np = spi_nor_get_flash_node(nor);
 	u8 i, erase_mask;
 
-	/* Initialize default flash parameters and settings. */
-	params->quad_enable = spi_nor_sr2_bit1_quad_enable;
-	params->set_4byte_addr_mode = spansion_set_4byte_addr_mode;
-	params->setup = spi_nor_default_setup;
-	params->otp.org = &info->otp_org;
-
-	/* Default to 16-bit Write Status (01h) Command */
-	nor->flags |= SNOR_F_HAS_16BIT_SR;
-
-	/* Set SPI NOR sizes. */
-	params->writesize = 1;
-	params->size = (u64)info->sector_size * info->n_sectors;
-	params->page_size = info->page_size;
-
-	if (!(info->flags & SPI_NOR_NO_FR)) {
-		/* Default to Fast Read for DT and non-DT platform devices. */
-		params->hwcaps.mask |= SNOR_HWCAPS_READ_FAST;
-
-		/* Mask out Fast Read if not requested at DT instantiation. */
-		if (np && !of_property_read_bool(np, "m25p,fast-read"))
-			params->hwcaps.mask &= ~SNOR_HWCAPS_READ_FAST;
-	}
-
-	/* (Fast) Read settings. */
-	params->hwcaps.mask |= SNOR_HWCAPS_READ;
-	spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ],
-				  0, 0, SPINOR_OP_READ,
-				  SNOR_PROTO_1_1_1);
-
-	if (params->hwcaps.mask & SNOR_HWCAPS_READ_FAST)
-		spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ_FAST],
-					  0, 8, SPINOR_OP_READ_FAST,
-					  SNOR_PROTO_1_1_1);
-
 	if (info->flags & SPI_NOR_DUAL_READ) {
 		params->hwcaps.mask |= SNOR_HWCAPS_READ_1_1_2;
 		spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ_1_1_2],
@@ -2674,11 +2689,6 @@ static void spi_nor_info_init_params(struct spi_nor *nor)
 					  SNOR_PROTO_8_8_8_DTR);
 	}
 
-	/* Page Program settings. */
-	params->hwcaps.mask |= SNOR_HWCAPS_PP;
-	spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP],
-				SPINOR_OP_PP, SNOR_PROTO_1_1_1);
-
 	if (info->flags & SPI_NOR_OCTAL_DTR_PP) {
 		params->hwcaps.mask |= SNOR_HWCAPS_PP_8_8_8_DTR;
 		/*
@@ -2823,6 +2833,8 @@ static int spi_nor_init_params(struct spi_nor *nor)
 	if (!nor->params)
 		return -ENOMEM;
 
+	spi_nor_init_default_params(nor);
+
 	spi_nor_info_init_params(nor);
 
 	spi_nor_manufacturer_init_params(nor);
I am neutral towards this patch. I don't think it improves much, but at 
the same time it doesn't make anything worse either.

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 27/35] mtd: spi-nor: core: Init flash params based on SFDP first for new flash additions

From: Pratyush Yadav <hidden>
Date: 2021-08-24 17:53:57

On 27/07/21 07:52AM, Tudor Ambarus wrote:
quoted hunk
Remove the spagetti way of initializing flash parameters and settings,
at least for the new flash additions (for now). All flash entries should
be converted to either use SPI_NOR_PARSE_SFDP or SPI_NOR_SKIP_SFDP.
SPI_NOR_SKIP_SFDP should be set either when the SFDP tables are completely
wrong and we can't parse relevant data, or when the SFDP tables are not
defined at all, or when RDSFDP command is not supported by the flash.
After all the flash entries will be converted to use these flags and after
the default_init() hook will be removed, the
spi_nor_init_params_deprecated() will be replaced by
spi_nor_info_init_params(). The flash parameters and settings will be
initialized either by parsing SFDP, or via the flash info flags.

Signed-off-by: Tudor Ambarus <redacted>
---
 drivers/mtd/spi-nor/core.c | 103 +++++++++++++++++++++++++------------
 1 file changed, 70 insertions(+), 33 deletions(-)
diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 9193317f897d..ef06a8d6abb8 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2627,28 +2627,6 @@ static void spi_nor_post_sfdp_fixups(struct spi_nor *nor)
 		nor->info->fixups->post_sfdp(nor);
 }
 
-/**
- * spi_nor_sfdp_init_params() - Initialize the flash's parameters and settings
- * based on JESD216 SFDP standard.
- * @nor:	pointer to a 'struct spi_nor'.
- *
- * The method has a roll-back mechanism: in case the SFDP parsing fails, the
- * legacy flash parameters and settings will be restored.
- */
-static void spi_nor_sfdp_init_params(struct spi_nor *nor)
-{
-	struct spi_nor_flash_parameter sfdp_params;
-
-	memcpy(&sfdp_params, nor->params, sizeof(sfdp_params));
-
-	if (!spi_nor_parse_sfdp(nor))
-		return spi_nor_post_sfdp_fixups(nor);
-
-	memcpy(nor->params, &sfdp_params, sizeof(*nor->params));
-	nor->addr_width = 0;
-	nor->flags &= ~SNOR_F_4B_OPCODES;
-}
-
 /**
  * spi_nor_info_init_params() - Initialize the flash's parameters and settings
  * based on nor->info data.
@@ -2722,6 +2700,39 @@ static void spi_nor_info_init_params(struct spi_nor *nor)
 	spi_nor_init_uniform_erase_map(map, erase_mask, params->size);
 }
 
+/**
+ * spi_nor_sfdp_init_params() - Initialize the flash's parameters and settings
+ * based on JESD216 SFDP standard.
+ * @nor:	pointer to a 'struct spi_nor'.
Missing documentation for treat_id_collisions.

Also, I assume this will go away when we get rid of 
spi_nor_init_params_deprecated(), correct?
+ *
+ * The method has a roll-back mechanism: in case the SFDP parsing fails, the
+ * legacy flash parameters and settings will be restored.
+ */
+static void spi_nor_sfdp_init_params(struct spi_nor *nor,
+				     bool treat_id_collisions)
+{
+	struct spi_nor_flash_parameter sfdp_params;
+
+	memcpy(&sfdp_params, nor->params, sizeof(sfdp_params));
+
+	if (!spi_nor_parse_sfdp(nor))
+		return spi_nor_post_sfdp_fixups(nor);
+
+	memcpy(nor->params, &sfdp_params, sizeof(*nor->params));
+	nor->addr_width = 0;
+	nor->flags &= ~SNOR_F_4B_OPCODES;
+
+	if (!treat_id_collisions)
+		return;
No, this doesn't seem quite right. Why would you not want to treat ID 
collisions for flashes that use spi_nor_init_params_deprecated()? What 
makes this not possible for them?

Anyway, even if we don't want to treat ID collisions for those flashes, 
we can't just return here. In the previous code, nor->params is already 
initialized by spi_nor_info_init_params() so restoring that via memcpy() 
would make sense since it would restore the info-initialized state. Now 
it would be just 0, with no useful information in there. You are bound 
to run into errors somewhere down the line.

So I think you either need to make this function return an error and 
propagate it up the call chain or run spi_nor_info_init_params() for 
both type of flashes to make sure we do our best effort to initialize 
the flash.
quoted hunk
+	/*
+	 * Fallback to flash info params init in case the SFDP parsing fails.
+	 * Used to handle ID collisions between flashes that define the SFDP
+	 * tables and flashes that don't.
+	 */
+	spi_nor_info_init_params(nor);
+	spi_nor_manufacturer_init_params(nor);
+}
+
 /**
  * spi_nor_late_init_params() - Late initialization of default flash parameters.
  * @nor:	pointer to a 'struct spi_nor'
@@ -2797,7 +2808,9 @@ static void spi_nor_nonsfdp_flags_init(struct spi_nor *nor)
 }
 
 /**
- * spi_nor_init_params() - Initialize the flash's parameters and settings.
+ * spi_nor_init_params_deprecated() - Initialize the flash's parameters and
+ * settings. The function is deprecated, it will be removed and replaced with
+ * spi_nor_info_init_params().
  * @nor:	pointer to a 'struct spi_nor'.
  *
  * The flash parameters and settings are initialized based on a sequence of
@@ -2821,11 +2834,40 @@ static void spi_nor_nonsfdp_flags_init(struct spi_nor *nor)
  *    Please note that there are ->post_{bfpt, sfdp}() fixup hooks that can
  *    overwrite the flash parameters and settings immediately after table
  *    parsing.
+ */
+static void spi_nor_init_params_deprecated(struct spi_nor *nor)
+{
+	spi_nor_info_init_params(nor);
+	spi_nor_manufacturer_init_params(nor);
+
+	if ((nor->info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
+				 SPI_NOR_OCTAL_READ | SPI_NOR_OCTAL_DTR_READ)) &&
+	    !(nor->info->flags & SPI_NOR_SKIP_SFDP))
+		spi_nor_sfdp_init_params(nor, false);
+}
+
+/**
+ * spi_nor_init_params() - Initialize the flash's parameters and settings.
+ * @nor:	pointer to a 'struct spi_nor'.
+ *
+ * The flash parameters and settings are initialized based on a sequence of
+ * calls that are ordered by priority:
+ *
+ * 1/ Default flash parameters initialization. The initializations are done
+ *    for all the flashes, regardless if the support SFDP or not.
+ *		spi_nor_init_default_params()
+ * which can be overwritten by:
  *
+ * 2/ SFDP based or the deprecated way of initializing flash parameters.
+ * Ideally at this step the flash parameters init will be done either by
+ * parsing SFDP, where supported, or statically via flash_info flags.
+ *		spi_nor_sfdp_init_params() or spi_nor_init_params_deprecated()
  * which can be overwritten by:
- * 4/ Late flash parameters initialization, used to initialize flash
+ *
+ * 3/ Late flash parameters initialization, used to initialize flash
  * parameters that are not declared in the JESD216 SFDP standard.
  *		spi_nor_late_init_params()
+ *
Not really related to this patch, but we need to document the return 
value here as well.
quoted hunk
  */
 static int spi_nor_init_params(struct spi_nor *nor)
 {
@@ -2835,15 +2877,10 @@ static int spi_nor_init_params(struct spi_nor *nor)
 
 	spi_nor_init_default_params(nor);
 
-	spi_nor_info_init_params(nor);
-
-	spi_nor_manufacturer_init_params(nor);
-
-	if ((nor->info->flags & (SPI_NOR_PARSE_SFDP |
-				 SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-				 SPI_NOR_OCTAL_READ | SPI_NOR_OCTAL_DTR_READ)) &&
-	    !(nor->info->flags & SPI_NOR_SKIP_SFDP))
-		spi_nor_sfdp_init_params(nor);
+	if (nor->info->flags & SPI_NOR_PARSE_SFDP)
+		spi_nor_sfdp_init_params(nor, true);
+	else
+		spi_nor_init_params_deprecated(nor);
 
 	spi_nor_late_init_params(nor);
 
-- 
2.25.1
-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

Re: [PATCH v2 35/35] docs: mtd: spi-nor: Add details about how to propose a new flash addition

From: Pratyush Yadav <hidden>
Date: 2021-08-24 18:01:18

On 27/07/21 09:22AM, Michael Walle wrote:
Am 2021-07-27 06:52, schrieb Tudor Ambarus:
quoted
Add some guideliness on how to propose a new flash addition.

Signed-off-by: Tudor Ambarus <redacted>
---
 Documentation/driver-api/mtd/spi-nor.rst | 65 ++++++++++++++++++++++++
 1 file changed, 65 insertions(+)
diff --git a/Documentation/driver-api/mtd/spi-nor.rst
b/Documentation/driver-api/mtd/spi-nor.rst
index 4a3adca417fd..ffb8d97a2766 100644
--- a/Documentation/driver-api/mtd/spi-nor.rst
+++ b/Documentation/driver-api/mtd/spi-nor.rst
[..]
quoted
+Every new flash addition that define the SFDP tables, should hexdump
its SFDP
+tables in the patch's comment section below the --- line, so that we
can
+reference it in case of ID collisions.
Nice, but could you add some guidelines how to do it? That is the exact
commands, maybe with a notice one should use these whenever possible. I
want to prevent having all sorts of variations of the output and I want
to be able to reverse the operation and verify it.

# xxd -p /path/to/sfdp
# md5sum /path/to/sfdp
# cat /path/to/jedec_id
# cat /path/to/partname
# cat /path/to/manufacturer
It would be nice if we could have checkpatch.pl check for these. But I 
don't know how difficult that would be to add.

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Next 58 of 58 remaining
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help