All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] m25p80: Use a 512 byte page size for Spansion flash s25fl512s
@ 2017-01-24 13:52 mark.marshall
  2017-01-24 16:48 ` Marek Vasut
  0 siblings, 1 reply; 12+ messages in thread
From: mark.marshall @ 2017-01-24 13:52 UTC (permalink / raw)
  To: computersforpeace, linux-mtd
  Cc: markmarshall14, cyrille.pitchen, marek.vasut, dwmw2,
	boris.brezillon, richard, Mark Marshall

From: Mark Marshall <mark.marshall@omicronenergy.com>

The s25fl512s flash from Spansion has a 512 byte write page size,
which means that we can write 512 bytes at a time (instead of 256).

This single change makes writing to the flash about 2x faster.

Signed-off-by: Mark Marshall <mark.marshall@omicronenergy.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index da7cd69..c9ac0bf 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -775,6 +775,21 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 		.page_size = 256,					\
 		.flags = (_flags),
 
+/* Used to set a custom (non 256) page_size */
+#define INFOP(_jedec_id, _ext_id, _sector_size, _n_sectors, _pg_sz, _flags) \
+		.id = {							\
+			((_jedec_id) >> 16) & 0xff,			\
+			((_jedec_id) >> 8) & 0xff,			\
+			(_jedec_id) & 0xff,				\
+			((_ext_id) >> 8) & 0xff,			\
+			(_ext_id) & 0xff,				\
+			},						\
+		.id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))), \
+		.sector_size = (_sector_size),				\
+		.n_sectors = (_n_sectors),				\
+		.page_size = (_pg_sz),					\
+		.flags = (_flags),					\
+
 #define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width, _flags)	\
 		.sector_size = (_sector_size),				\
 		.n_sectors = (_n_sectors),				\
@@ -905,7 +920,7 @@ static const struct flash_info spi_nor_ids[] = {
 	{ "s25sl064p",  INFO(0x010216, 0x4d00,  64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 	{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
 	{ "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-	{ "s25fl512s",  INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25fl512s",  INFOP(0x010220, 0x4d00, 256 * 1024, 256, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
 	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
 	{ "s25sl12801", INFO(0x012018, 0x0301,  64 * 1024, 256, 0) },
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH] m25p80: Use a 512 byte page size for Spansion flash s25fl512s
  2017-01-24 13:52 [PATCH] m25p80: Use a 512 byte page size for Spansion flash s25fl512s mark.marshall
@ 2017-01-24 16:48 ` Marek Vasut
  2017-01-26 14:58   ` Mark Marshall
  0 siblings, 1 reply; 12+ messages in thread
From: Marek Vasut @ 2017-01-24 16:48 UTC (permalink / raw)
  To: mark.marshall, computersforpeace, linux-mtd
  Cc: markmarshall14, cyrille.pitchen, dwmw2, boris.brezillon, richard

On 01/24/2017 02:52 PM, mark.marshall@omicronenergy.com wrote:
> From: Mark Marshall <mark.marshall@omicronenergy.com>
> 
> The s25fl512s flash from Spansion has a 512 byte write page size,
> which means that we can write 512 bytes at a time (instead of 256).
> 
> This single change makes writing to the flash about 2x faster.
> 
> Signed-off-by: Mark Marshall <mark.marshall@omicronenergy.com>
> ---
>  drivers/mtd/spi-nor/spi-nor.c | 17 ++++++++++++++++-
>  1 file changed, 16 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index da7cd69..c9ac0bf 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -775,6 +775,21 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
>  		.page_size = 256,					\
>  		.flags = (_flags),
>  
> +/* Used to set a custom (non 256) page_size */
> +#define INFOP(_jedec_id, _ext_id, _sector_size, _n_sectors, _pg_sz, _flags) \
> +		.id = {							\
> +			((_jedec_id) >> 16) & 0xff,			\
> +			((_jedec_id) >> 8) & 0xff,			\
> +			(_jedec_id) & 0xff,				\
> +			((_ext_id) >> 8) & 0xff,			\
> +			(_ext_id) & 0xff,				\
> +			},						\
> +		.id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))), \
> +		.sector_size = (_sector_size),				\
> +		.n_sectors = (_n_sectors),				\
> +		.page_size = (_pg_sz),					\
> +		.flags = (_flags),					\
> +

Maybe it's time to introduce INFO_FULL() instead, where you could
specify the page size and ID length. Adding more and more custom INFOx()
doesn't scale. The INFOx() could then be easily converted
over to INFO_FULL().

One minor bit which could be slightly problematic is the .id_len
field, which is precomputed now, but maybe there is a way to handle
that too.

Thoughts ?

>  #define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width, _flags)	\
>  		.sector_size = (_sector_size),				\
>  		.n_sectors = (_n_sectors),				\
> @@ -905,7 +920,7 @@ static const struct flash_info spi_nor_ids[] = {
>  	{ "s25sl064p",  INFO(0x010216, 0x4d00,  64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>  	{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
>  	{ "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> -	{ "s25fl512s",  INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> +	{ "s25fl512s",  INFOP(0x010220, 0x4d00, 256 * 1024, 256, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>  	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
>  	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
>  	{ "s25sl12801", INFO(0x012018, 0x0301,  64 * 1024, 256, 0) },
> 


-- 
Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] m25p80: Use a 512 byte page size for Spansion flash s25fl512s
  2017-01-24 16:48 ` Marek Vasut
@ 2017-01-26 14:58   ` Mark Marshall
  2017-02-04 22:25     ` Marek Vasut
  0 siblings, 1 reply; 12+ messages in thread
From: Mark Marshall @ 2017-01-26 14:58 UTC (permalink / raw)
  To: Marek Vasut
  Cc: mark.marshall, computersforpeace, linux-mtd, cyrille.pitchen,
	David Woodhouse, boris.brezillon, richard

On 24 January 2017 at 17:48, Marek Vasut <marek.vasut@gmail.com> wrote:
> On 01/24/2017 02:52 PM, mark.marshall@omicronenergy.com wrote:
>> From: Mark Marshall <mark.marshall@omicronenergy.com>
>>
>> The s25fl512s flash from Spansion has a 512 byte write page size,
>> which means that we can write 512 bytes at a time (instead of 256).
>>
>> This single change makes writing to the flash about 2x faster.
>>
>> Signed-off-by: Mark Marshall <mark.marshall@omicronenergy.com>
>> ---
>>  drivers/mtd/spi-nor/spi-nor.c | 17 ++++++++++++++++-
>>  1 file changed, 16 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
>> index da7cd69..c9ac0bf 100644
>> --- a/drivers/mtd/spi-nor/spi-nor.c
>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>> @@ -775,6 +775,21 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
>>               .page_size = 256,                                       \
>>               .flags = (_flags),
>>
>> +/* Used to set a custom (non 256) page_size */
>> +#define INFOP(_jedec_id, _ext_id, _sector_size, _n_sectors, _pg_sz, _flags) \
>> +             .id = {                                                 \
>> +                     ((_jedec_id) >> 16) & 0xff,                     \
>> +                     ((_jedec_id) >> 8) & 0xff,                      \
>> +                     (_jedec_id) & 0xff,                             \
>> +                     ((_ext_id) >> 8) & 0xff,                        \
>> +                     (_ext_id) & 0xff,                               \
>> +                     },                                              \
>> +             .id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))), \
>> +             .sector_size = (_sector_size),                          \
>> +             .n_sectors = (_n_sectors),                              \
>> +             .page_size = (_pg_sz),                                  \
>> +             .flags = (_flags),                                      \
>> +
>
> Maybe it's time to introduce INFO_FULL() instead, where you could
> specify the page size and ID length. Adding more and more custom INFOx()
> doesn't scale. The INFOx() could then be easily converted
> over to INFO_FULL().
>
> One minor bit which could be slightly problematic is the .id_len
> field, which is precomputed now, but maybe there is a way to handle
> that too.
>
> Thoughts ?

I had a go at this, and my preferred method would be to use some token
pasting, but I'm not sure how popular this will be?  Below is the macro's I
came up with and a few representative lines of the table.  If no one objects
I'll prepare a complete patch.  (I've done this on a branch, and the table has
changed slightly, where should I be basing a patch like this from?).

I've checked by building the file both before and after my change, and the
table doesn't change.

#define _ID_NONE                \
    .id = {},                \
    .id_len = 0

#define _ID_JEDEC(_jedec_id)                        \
    .id = {                                \
        ((_jedec_id) >> 16) & 0xff,                \
        ((_jedec_id) >> 8) & 0xff,                \
        (_jedec_id) & 0xff,                    \
    },                                \
    .id_len = 3

#define _ID_JEDEC_EXT2(_jedec_id, _ext_id)                \
    .id = {                                \
        ((_jedec_id) >> 16) & 0xff,                \
        ((_jedec_id) >> 8) & 0xff,                \
        (_jedec_id) & 0xff,                    \
        ((_ext_id) >> 8) & 0xff,                \
        (_ext_id) & 0xff,                    \
    },                                \
    .id_len = 5

#define _ID_JEDEC_EXT3(_jedec_id, _ext_id)                \
    .id = {                                \
        ((_jedec_id) >> 16) & 0xff,                \
        ((_jedec_id) >> 8) & 0xff,                \
        (_jedec_id) & 0xff,                    \
        ((_ext_id) >> 16) & 0xff,                \
        ((_ext_id) >> 8) & 0xff,                \
        (_ext_id) & 0xff,                    \
    },                                \
    .id_len = 6

#define INFO_FULL(_id, _sector_size, _n_sectors, _pg_sz, _addr_width, _flags) \
    _ID_ ## _id,                            \
    .sector_size = (_sector_size),                    \
    .n_sectors = (_n_sectors),                    \
    .page_size = (_pg_sz),                        \
    .addr_width = (_addr_width),                    \
    .flags = (_flags),

#define INFO(_id, _sector_size, _n_sectors, _flags)    \
    INFO_FULL(_id, _sector_size, _n_sectors, 256, 0, _flags)

static const struct flash_info spi_nor_ids[] = {
    { "at25fs010",  INFO(JEDEC(0x1f6601), 32 * 1024,   4, SECT_4K) },
    { "at25fs040",  INFO(JEDEC(0x1f6604), 64 * 1024,   8, SECT_4K) },
    { "mr25h256", INFO_FULL(NONE,  32 * 1024, 1, 256, 2,
SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
    { "s25sl032p",  INFO(JEDEC_EXT2(0x010215, 0x4d00),  64 * 1024,
64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
    { "s25fl512s",  INFO_FULL(JEDEC_EXT2(0x010220, 0x4d00), 256 *
1024, 256, 256, 0, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
    { "s25fl128s",    INFO(JEDEC_EXT3(0x012018, 0x4d0180), 64 * 1024,
256, SECT_4K | SPI_NOR_QUAD_READ) },
    { "cat25c11", INFO_FULL(NONE,   16, 8, 16, 1, SPI_NOR_NO_ERASE |
SPI_NOR_NO_FR) },

Regards,

Mark

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] m25p80: Use a 512 byte page size for Spansion flash s25fl512s
  2017-01-26 14:58   ` Mark Marshall
@ 2017-02-04 22:25     ` Marek Vasut
  2017-02-13 13:53       ` [PATCH] mtd: spi-nor: flash_info table, use a u64 for the ID mark.marshall
  0 siblings, 1 reply; 12+ messages in thread
From: Marek Vasut @ 2017-02-04 22:25 UTC (permalink / raw)
  To: Mark Marshall
  Cc: mark.marshall, computersforpeace, linux-mtd, cyrille.pitchen,
	David Woodhouse, boris.brezillon, richard

On 01/26/2017 03:58 PM, Mark Marshall wrote:
> On 24 January 2017 at 17:48, Marek Vasut <marek.vasut@gmail.com> wrote:
>> On 01/24/2017 02:52 PM, mark.marshall@omicronenergy.com wrote:
>>> From: Mark Marshall <mark.marshall@omicronenergy.com>
>>>
>>> The s25fl512s flash from Spansion has a 512 byte write page size,
>>> which means that we can write 512 bytes at a time (instead of 256).
>>>
>>> This single change makes writing to the flash about 2x faster.
>>>
>>> Signed-off-by: Mark Marshall <mark.marshall@omicronenergy.com>
>>> ---
>>>  drivers/mtd/spi-nor/spi-nor.c | 17 ++++++++++++++++-
>>>  1 file changed, 16 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
>>> index da7cd69..c9ac0bf 100644
>>> --- a/drivers/mtd/spi-nor/spi-nor.c
>>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>>> @@ -775,6 +775,21 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
>>>               .page_size = 256,                                       \
>>>               .flags = (_flags),
>>>
>>> +/* Used to set a custom (non 256) page_size */
>>> +#define INFOP(_jedec_id, _ext_id, _sector_size, _n_sectors, _pg_sz, _flags) \
>>> +             .id = {                                                 \
>>> +                     ((_jedec_id) >> 16) & 0xff,                     \
>>> +                     ((_jedec_id) >> 8) & 0xff,                      \
>>> +                     (_jedec_id) & 0xff,                             \
>>> +                     ((_ext_id) >> 8) & 0xff,                        \
>>> +                     (_ext_id) & 0xff,                               \
>>> +                     },                                              \
>>> +             .id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))), \
>>> +             .sector_size = (_sector_size),                          \
>>> +             .n_sectors = (_n_sectors),                              \
>>> +             .page_size = (_pg_sz),                                  \
>>> +             .flags = (_flags),                                      \
>>> +
>>
>> Maybe it's time to introduce INFO_FULL() instead, where you could
>> specify the page size and ID length. Adding more and more custom INFOx()
>> doesn't scale. The INFOx() could then be easily converted
>> over to INFO_FULL().
>>
>> One minor bit which could be slightly problematic is the .id_len
>> field, which is precomputed now, but maybe there is a way to handle
>> that too.
>>
>> Thoughts ?

Sorry for the late reply, I've been traveling a lot recently.

> I had a go at this, and my preferred method would be to use some token
> pasting, but I'm not sure how popular this will be?

IMO not much.

> Below is the macro's I
> came up with and a few representative lines of the table.  If no one objects
> I'll prepare a complete patch.  (I've done this on a branch, and the table has
> changed slightly, where should I be basing a patch like this from?).

This makes me kinda wonder (and this might be a totally wrong idea), why
don't we replace the 6-byte ID table with an u64 id and u64 mask ?
_ID_JEDEC_EXT2 would then look something like:

#define _ID_JEDEC_EXT2(_jedec_id, _ext_id)		\
{							\
	.id = ((_ext_id) << 32) | (_jedec_id),		\
	.mask = GENMASK(47, 32) | GENMASK(23, 0),	\
},

The match would then also be much easier, that is.
->id & ->mask == ->id
instead of all the memcmp() tests. id_len would go
away too. And the matching would allow more precise
control over the test. We could even handle the n25q256(a)
specialty jedec ID 0x20baxx/0x20bbxx with this.

I don't think there'll ever be a SPI NOR with 8byte JEDEC
ID, so u64 should be good enough.

The macros below could be reworked to use a generic macro
to define the ID/extID entry and it's width, ie:

#define _ID_JEDEC(_jedec_id, _jedec_id_width, 			\
		  _ext_id, _ext_id_width)			\
{								\
	.id = ((_ext_id) << 32) | (_jedec_id),			\
	.mask = GENMASK(32 + ((_ext_id_width * 8) - 1), 32) |	\
		GENMASK(((_id_width * 8) - 1), 0),		\
},

> I've checked by building the file both before and after my change, and the
> table doesn't change.
> 
> #define _ID_NONE                \
>     .id = {},                \
>     .id_len = 0
> 
> #define _ID_JEDEC(_jedec_id)                        \
>     .id = {                                \
>         ((_jedec_id) >> 16) & 0xff,                \
>         ((_jedec_id) >> 8) & 0xff,                \
>         (_jedec_id) & 0xff,                    \
>     },                                \
>     .id_len = 3
> 
> #define _ID_JEDEC_EXT2(_jedec_id, _ext_id)                \
>     .id = {                                \
>         ((_jedec_id) >> 16) & 0xff,                \
>         ((_jedec_id) >> 8) & 0xff,                \
>         (_jedec_id) & 0xff,                    \
>         ((_ext_id) >> 8) & 0xff,                \
>         (_ext_id) & 0xff,                    \
>     },                                \
>     .id_len = 5
> 
> #define _ID_JEDEC_EXT3(_jedec_id, _ext_id)                \
>     .id = {                                \
>         ((_jedec_id) >> 16) & 0xff,                \
>         ((_jedec_id) >> 8) & 0xff,                \
>         (_jedec_id) & 0xff,                    \
>         ((_ext_id) >> 16) & 0xff,                \
>         ((_ext_id) >> 8) & 0xff,                \
>         (_ext_id) & 0xff,                    \
>     },                                \
>     .id_len = 6
> 
> #define INFO_FULL(_id, _sector_size, _n_sectors, _pg_sz, _addr_width, _flags) \
>     _ID_ ## _id,                            \
>     .sector_size = (_sector_size),                    \
>     .n_sectors = (_n_sectors),                    \
>     .page_size = (_pg_sz),                        \
>     .addr_width = (_addr_width),                    \
>     .flags = (_flags),
> 
> #define INFO(_id, _sector_size, _n_sectors, _flags)    \
>     INFO_FULL(_id, _sector_size, _n_sectors, 256, 0, _flags)
> 
> static const struct flash_info spi_nor_ids[] = {
>     { "at25fs010",  INFO(JEDEC(0x1f6601), 32 * 1024,   4, SECT_4K) },
>     { "at25fs040",  INFO(JEDEC(0x1f6604), 64 * 1024,   8, SECT_4K) },
>     { "mr25h256", INFO_FULL(NONE,  32 * 1024, 1, 256, 2,
> SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
>     { "s25sl032p",  INFO(JEDEC_EXT2(0x010215, 0x4d00),  64 * 1024,
> 64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>     { "s25fl512s",  INFO_FULL(JEDEC_EXT2(0x010220, 0x4d00), 256 *
> 1024, 256, 256, 0, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>     { "s25fl128s",    INFO(JEDEC_EXT3(0x012018, 0x4d0180), 64 * 1024,
> 256, SECT_4K | SPI_NOR_QUAD_READ) },
>     { "cat25c11", INFO_FULL(NONE,   16, 8, 16, 1, SPI_NOR_NO_ERASE |
> SPI_NOR_NO_FR) },
> 
> Regards,
> 
> Mark
> 


-- 
Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH] mtd: spi-nor: flash_info table, use a u64 for the ID
  2017-02-04 22:25     ` Marek Vasut
@ 2017-02-13 13:53       ` mark.marshall
  2017-02-14  5:02         ` Marek Vasut
  0 siblings, 1 reply; 12+ messages in thread
From: mark.marshall @ 2017-02-13 13:53 UTC (permalink / raw)
  To: computersforpeace, linux-mtd, marek.vasut
  Cc: markmarshall14, cyrille.pitchen, dwmw2, richard, boris.brezillon,
	Mark Marshall

From: Mark Marshall <mark.marshall@omicronenergy.com>

The flash_info ID matching table is getting more complex as different
chips are added.  Some chips require different amounts of the response
to the RDID command to be matched.  Replace the current u8 array and
length with a u64 id and a u64 id_mask.  This allows us to simplify the
macros used to generate the flash_info table without loosing the ability
to generate "unusual" entries.

--

This patch replaces "m25p80: Use a 512 byte page size for Spansion
flash s25fl512s".  It is based on for-linus-20170212, from the
linux-mtd tree.


Signed-off-by: Mark Marshall <mark.marshall@omicronenergy.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 458 +++++++++++++++++++++---------------------
 1 file changed, 231 insertions(+), 227 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 1ae872b..c7ff237 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -41,15 +41,20 @@
 #define SPI_NOR_MAX_ADDR_WIDTH	4
 
 struct flash_info {
-	char		*name;
+	const char	*name;
 
 	/*
-	 * This array stores the ID bytes.
-	 * The first three bytes are the JEDIC ID.
-	 * JEDEC ID zero means "no ID" (mostly older chips).
+	 * This u64 stores the ID bytes.
+	 * The bytes are stored in big-endian order.
+	 * The upper three bytes are the JEDIC ID, the lower bytes are
+	 * the extension.
 	 */
-	u8		id[SPI_NOR_MAX_ID_LEN];
-	u8		id_len;
+	u64		id;
+
+	/*
+	 * An id_mask of zero means "no ID" (mostly older chips).
+	 */
+	u64		id_mask;
 
 	/* The size listed here is what works with SPINOR_OP_SE, which isn't
 	 * necessarily called a "sector" by the vendor.
@@ -87,7 +92,7 @@ struct flash_info {
 					 */
 };
 
-#define JEDEC_MFR(info)	((info)->id[0])
+#define JEDEC_MFR(info)	((u8)((info)->id >> 56) & 0xff)
 
 static const struct flash_info *spi_nor_match_id(const char *name);
 
@@ -870,55 +875,49 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 	return ret;
 }
 
-/* Used when the "_ext_id" is two bytes at most */
-#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
-		.id = {							\
-			((_jedec_id) >> 16) & 0xff,			\
-			((_jedec_id) >> 8) & 0xff,			\
-			(_jedec_id) & 0xff,				\
-			((_ext_id) >> 8) & 0xff,			\
-			(_ext_id) & 0xff,				\
-			},						\
-		.id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))),	\
-		.sector_size = (_sector_size),				\
-		.n_sectors = (_n_sectors),				\
-		.page_size = 256,					\
-		.flags = (_flags),
-
-#define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
-		.id = {							\
-			((_jedec_id) >> 16) & 0xff,			\
-			((_jedec_id) >> 8) & 0xff,			\
-			(_jedec_id) & 0xff,				\
-			((_ext_id) >> 16) & 0xff,			\
-			((_ext_id) >> 8) & 0xff,			\
-			(_ext_id) & 0xff,				\
-			},						\
-		.id_len = 6,						\
-		.sector_size = (_sector_size),				\
-		.n_sectors = (_n_sectors),				\
-		.page_size = 256,					\
-		.flags = (_flags),
-
-#define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width, _flags)	\
-		.sector_size = (_sector_size),				\
-		.n_sectors = (_n_sectors),				\
-		.page_size = (_page_size),				\
-		.addr_width = (_addr_width),				\
-		.flags = (_flags),
-
-#define S3AN_INFO(_jedec_id, _n_sectors, _page_size)			\
-		.id = {							\
-			((_jedec_id) >> 16) & 0xff,			\
-			((_jedec_id) >> 8) & 0xff,			\
-			(_jedec_id) & 0xff				\
-			},						\
-		.id_len = 3,						\
-		.sector_size = (8*_page_size),				\
-		.n_sectors = (_n_sectors),				\
-		.page_size = _page_size,				\
-		.addr_width = 3,					\
-		.flags = SPI_NOR_NO_FR | SPI_S3AN,
+/* Used to provide the full information about a device.
+ */
+#define INFO_FULL(_id, _id_mask, _sector_size, _n_sectors, _pg_sz, _addr_width, _flags)	\
+	.id = (_id),							\
+	.id_mask = (_id_mask),						\
+	.sector_size = (_sector_size),					\
+	.n_sectors = (_n_sectors),					\
+	.page_size = (_pg_sz),						\
+	.addr_width = (_addr_width),					\
+	.flags = (_flags),
+
+/* Used to provide information for a standard JEDEC device.  All
+ * devices created with this macro have a three octet JEDEC identifier
+ * and an optional extension identifier (normally 0, 2 or 3 octets
+ * long).
+ */
+#define INFO(_jedec_id, _ext_id, _ext_len, _sector_size, _n_sectors, _flags) \
+	INFO_FULL(((u64)(_jedec_id) << (64 - (8 * 3))) |		\
+		  ((u64)(_ext_id) << (64 - (8 * (3 + _ext_len)))),	\
+		  GENMASK_ULL(63, 64 - (8 * (3 + _ext_len))),		\
+		  (_sector_size),					\
+		  (_n_sectors),						\
+		  256,							\
+		  0,							\
+		  (_flags))
+
+#define INFO_NOID(_sector_size, _n_sectors, _page_size, _addr_width, _flags)	\
+	INFO_FULL(0,							\
+		  0,							\
+		  (_sector_size),					\
+		  (_n_sectors),						\
+		  (_page_size),						\
+		  (_addr_width),					\
+		  (_flags))
+
+#define INFO_S3AN(_jedec_id, _n_sectors, _page_size)			\
+	INFO_FULL(((u64)(_jedec_id) << (64 - (8 * 3))),			\
+		  GENMASK_ULL(63, 64 - (8 * 3)),			\
+		  (8*_page_size),					\
+		  (_n_sectors),						\
+		  (_page_size),						\
+		  3,							\
+		  SPI_NOR_NO_FR | SPI_S3AN)
 
 /* NOTE: double check command sets and memory organization when you add
  * more nor chips.  This current list focusses on newer chips, which
@@ -933,261 +932,266 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
  */
 static const struct flash_info spi_nor_ids[] = {
 	/* Atmel -- some are (confusingly) marketed as "DataFlash" */
-	{ "at25fs010",  INFO(0x1f6601, 0, 32 * 1024,   4, SECT_4K) },
-	{ "at25fs040",  INFO(0x1f6604, 0, 64 * 1024,   8, SECT_4K) },
+	{ "at25fs010",  INFO(0x1f6601, 0, 0, 32 * 1024,   4, SECT_4K) },
+	{ "at25fs040",  INFO(0x1f6604, 0, 0, 64 * 1024,   8, SECT_4K) },
 
-	{ "at25df041a", INFO(0x1f4401, 0, 64 * 1024,   8, SECT_4K) },
-	{ "at25df321",  INFO(0x1f4700, 0, 64 * 1024,  64, SECT_4K) },
-	{ "at25df321a", INFO(0x1f4701, 0, 64 * 1024,  64, SECT_4K) },
-	{ "at25df641",  INFO(0x1f4800, 0, 64 * 1024, 128, SECT_4K) },
+	{ "at25df041a", INFO(0x1f4401, 0, 0, 64 * 1024,   8, SECT_4K) },
+	{ "at25df321",  INFO(0x1f4700, 0, 0, 64 * 1024,  64, SECT_4K) },
+	{ "at25df321a", INFO(0x1f4701, 0, 0, 64 * 1024,  64, SECT_4K) },
+	{ "at25df641",  INFO(0x1f4800, 0, 0, 64 * 1024, 128, SECT_4K) },
 
-	{ "at26f004",   INFO(0x1f0400, 0, 64 * 1024,  8, SECT_4K) },
-	{ "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16, SECT_4K) },
-	{ "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) },
-	{ "at26df321",  INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) },
+	{ "at26f004",   INFO(0x1f0400, 0, 0, 64 * 1024,  8, SECT_4K) },
+	{ "at26df081a", INFO(0x1f4501, 0, 0, 64 * 1024, 16, SECT_4K) },
+	{ "at26df161a", INFO(0x1f4601, 0, 0, 64 * 1024, 32, SECT_4K) },
+	{ "at26df321",  INFO(0x1f4700, 0, 0, 64 * 1024, 64, SECT_4K) },
 
-	{ "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) },
+	{ "at45db081d", INFO(0x1f2500, 0, 0, 64 * 1024, 16, SECT_4K) },
 
 	/* EON -- en25xxx */
-	{ "en25f32",    INFO(0x1c3116, 0, 64 * 1024,   64, SECT_4K) },
-	{ "en25p32",    INFO(0x1c2016, 0, 64 * 1024,   64, 0) },
-	{ "en25q32b",   INFO(0x1c3016, 0, 64 * 1024,   64, 0) },
-	{ "en25p64",    INFO(0x1c2017, 0, 64 * 1024,  128, 0) },
-	{ "en25q64",    INFO(0x1c3017, 0, 64 * 1024,  128, SECT_4K) },
-	{ "en25qh128",  INFO(0x1c7018, 0, 64 * 1024,  256, 0) },
-	{ "en25qh256",  INFO(0x1c7019, 0, 64 * 1024,  512, 0) },
-	{ "en25s64",	INFO(0x1c3817, 0, 64 * 1024,  128, SECT_4K) },
+	{ "en25f32",    INFO(0x1c3116, 0, 0, 64 * 1024,   64, SECT_4K) },
+	{ "en25p32",    INFO(0x1c2016, 0, 0, 64 * 1024,   64, 0) },
+	{ "en25q32b",   INFO(0x1c3016, 0, 0, 64 * 1024,   64, 0) },
+	{ "en25p64",    INFO(0x1c2017, 0, 0, 64 * 1024,  128, 0) },
+	{ "en25q64",    INFO(0x1c3017, 0, 0, 64 * 1024,  128, SECT_4K) },
+	{ "en25qh128",  INFO(0x1c7018, 0, 0, 64 * 1024,  256, 0) },
+	{ "en25qh256",  INFO(0x1c7019, 0, 0, 64 * 1024,  512, 0) },
+	{ "en25s64",	INFO(0x1c3817, 0, 0, 64 * 1024,  128, SECT_4K) },
 
 	/* ESMT */
-	{ "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) },
+	{ "f25l32pa", INFO(0x8c2016, 0, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) },
 
 	/* Everspin */
-	{ "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
-	{ "mr25h10",  CAT25_INFO(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
-	{ "mr25h40",  CAT25_INFO(512 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "mr25h256", INFO_NOID( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "mr25h10",  INFO_NOID(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "mr25h40",  INFO_NOID(512 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
 
 	/* Fujitsu */
-	{ "mb85rs1mt", INFO(0x047f27, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) },
+	{ "mb85rs1mt", INFO(0x047f27, 0, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) },
 
 	/* GigaDevice */
 	{
-		"gd25q16", INFO(0xc84015, 0, 64 * 1024,  32,
+		"gd25q16", INFO(0xc84015, 0, 0, 64 * 1024,  32,
 			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
 	},
 	{
-		"gd25q32", INFO(0xc84016, 0, 64 * 1024,  64,
+		"gd25q32", INFO(0xc84016, 0, 0, 64 * 1024,  64,
 			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
 	},
 	{
-		"gd25q64", INFO(0xc84017, 0, 64 * 1024, 128,
+		"gd25q64", INFO(0xc84017, 0, 0, 64 * 1024, 128,
 			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
 	},
 	{
-		"gd25lq64c", INFO(0xc86017, 0, 64 * 1024, 128,
+		"gd25lq64c", INFO(0xc86017, 0, 0, 64 * 1024, 128,
 			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
 	},
 	{
-		"gd25q128", INFO(0xc84018, 0, 64 * 1024, 256,
+		"gd25q128", INFO(0xc84018, 0, 0, 64 * 1024, 256,
 			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
 	},
 
 	/* Intel/Numonyx -- xxxs33b */
-	{ "160s33b",  INFO(0x898911, 0, 64 * 1024,  32, 0) },
-	{ "320s33b",  INFO(0x898912, 0, 64 * 1024,  64, 0) },
-	{ "640s33b",  INFO(0x898913, 0, 64 * 1024, 128, 0) },
+	{ "160s33b",  INFO(0x898911, 0, 0, 64 * 1024,  32, 0) },
+	{ "320s33b",  INFO(0x898912, 0, 0, 64 * 1024,  64, 0) },
+	{ "640s33b",  INFO(0x898913, 0, 0, 64 * 1024, 128, 0) },
 
 	/* ISSI */
-	{ "is25cd512", INFO(0x7f9d20, 0, 32 * 1024,   2, SECT_4K) },
+	{ "is25cd512", INFO(0x7f9d20, 0, 0, 32 * 1024,   2, SECT_4K) },
 
 	/* Macronix */
-	{ "mx25l512e",   INFO(0xc22010, 0, 64 * 1024,   1, SECT_4K) },
-	{ "mx25l2005a",  INFO(0xc22012, 0, 64 * 1024,   4, SECT_4K) },
-	{ "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) },
-	{ "mx25l3255e",  INFO(0xc29e16, 0, 64 * 1024,  64, SECT_4K) },
-	{ "mx25l6405d",  INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) },
-	{ "mx25u6435f",  INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) },
-	{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
-	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
-	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
-	{ "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K) },
-	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
-	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) },
-	{ "mx66l1g55g",  INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) },
+	{ "mx25l512e",   INFO(0xc22010, 0, 0, 64 * 1024,   1, SECT_4K) },
+	{ "mx25l2005a",  INFO(0xc22012, 0, 0, 64 * 1024,   4, SECT_4K) },
+	{ "mx25l4005a",  INFO(0xc22013, 0, 0, 64 * 1024,   8, SECT_4K) },
+	{ "mx25l8005",   INFO(0xc22014, 0, 0, 64 * 1024,  16, 0) },
+	{ "mx25l1606e",  INFO(0xc22015, 0, 0, 64 * 1024,  32, SECT_4K) },
+	{ "mx25l3205d",  INFO(0xc22016, 0, 0, 64 * 1024,  64, SECT_4K) },
+	{ "mx25l3255e",  INFO(0xc29e16, 0, 0, 64 * 1024,  64, SECT_4K) },
+	{ "mx25l6405d",  INFO(0xc22017, 0, 0, 64 * 1024, 128, SECT_4K) },
+	{ "mx25u6435f",  INFO(0xc22537, 0, 0, 64 * 1024, 128, SECT_4K) },
+	{ "mx25l12805d", INFO(0xc22018, 0, 0, 64 * 1024, 256, 0) },
+	{ "mx25l12855e", INFO(0xc22618, 0, 0, 64 * 1024, 256, 0) },
+	{ "mx25l25635e", INFO(0xc22019, 0, 0, 64 * 1024, 512, 0) },
+	{ "mx25u25635f", INFO(0xc22539, 0, 0, 64 * 1024, 512, SECT_4K) },
+	{ "mx25l25655e", INFO(0xc22619, 0, 0, 64 * 1024, 512, 0) },
+	{ "mx66l51235l", INFO(0xc2201a, 0, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) },
+	{ "mx66l1g55g",  INFO(0xc2261b, 0, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) },
 
 	/* Micron */
-	{ "n25q016a",	 INFO(0x20bb15, 0, 64 * 1024,   32, SECT_4K | SPI_NOR_QUAD_READ) },
-	{ "n25q032",	 INFO(0x20ba16, 0, 64 * 1024,   64, SPI_NOR_QUAD_READ) },
-	{ "n25q032a",	 INFO(0x20bb16, 0, 64 * 1024,   64, SPI_NOR_QUAD_READ) },
-	{ "n25q064",     INFO(0x20ba17, 0, 64 * 1024,  128, SECT_4K | SPI_NOR_QUAD_READ) },
-	{ "n25q064a",    INFO(0x20bb17, 0, 64 * 1024,  128, SECT_4K | SPI_NOR_QUAD_READ) },
-	{ "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024,  256, SECT_4K | SPI_NOR_QUAD_READ) },
-	{ "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024,  256, SECT_4K | SPI_NOR_QUAD_READ) },
-	{ "n25q256a",    INFO(0x20ba19, 0, 64 * 1024,  512, SECT_4K | SPI_NOR_QUAD_READ) },
-	{ "n25q512a",    INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
-	{ "n25q512ax3",  INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
-	{ "n25q00",      INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
-	{ "n25q00a",     INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
+	{ "n25q016a",	 INFO(0x20bb15, 0, 0, 64 * 1024,   32, SECT_4K | SPI_NOR_QUAD_READ) },
+	{ "n25q032",	 INFO(0x20ba16, 0, 0, 64 * 1024,   64, SPI_NOR_QUAD_READ) },
+	{ "n25q032a",	 INFO(0x20bb16, 0, 0, 64 * 1024,   64, SPI_NOR_QUAD_READ) },
+	{ "n25q064",     INFO(0x20ba17, 0, 0, 64 * 1024,  128, SECT_4K | SPI_NOR_QUAD_READ) },
+	{ "n25q064a",    INFO(0x20bb17, 0, 0, 64 * 1024,  128, SECT_4K | SPI_NOR_QUAD_READ) },
+	{ "n25q128a11",  INFO(0x20bb18, 0, 0, 64 * 1024,  256, SECT_4K | SPI_NOR_QUAD_READ) },
+	{ "n25q128a13",  INFO(0x20ba18, 0, 0, 64 * 1024,  256, SECT_4K | SPI_NOR_QUAD_READ) },
+	{ "n25q256a",    INFO(0x20ba19, 0, 0, 64 * 1024,  512, SECT_4K | SPI_NOR_QUAD_READ) },
+	{ "n25q512a",    INFO(0x20bb20, 0, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
+	{ "n25q512ax3",  INFO(0x20ba20, 0, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
+	{ "n25q00",      INFO(0x20ba21, 0, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
+	{ "n25q00a",     INFO(0x20bb21, 0, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
 
 	/* PMC */
-	{ "pm25lv512",   INFO(0,        0, 32 * 1024,    2, SECT_4K_PMC) },
-	{ "pm25lv010",   INFO(0,        0, 32 * 1024,    4, SECT_4K_PMC) },
-	{ "pm25lq032",   INFO(0x7f9d46, 0, 64 * 1024,   64, SECT_4K) },
+	{ "pm25lv512",   INFO_NOID(32 * 1024,    2, 256, 0, SECT_4K_PMC) },
+	{ "pm25lv010",   INFO_NOID(32 * 1024,    4, 256, 0, SECT_4K_PMC) },
+	{ "pm25lq032",   INFO(0x7f9d46, 0, 0, 64 * 1024,   64, SECT_4K) },
 
 	/* Spansion -- single (large) sector size only, at least
 	 * for the chips listed here (without boot sectors).
 	 */
-	{ "s25sl032p",  INFO(0x010215, 0x4d00,  64 * 1024,  64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-	{ "s25sl064p",  INFO(0x010216, 0x4d00,  64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-	{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
-	{ "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-	{ "s25fl512s",  INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
-	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
-	{ "s25sl12801", INFO(0x012018, 0x0301,  64 * 1024, 256, 0) },
-	{ "s25fl128s",	INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-	{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024,  64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-	{ "s25fl129p1", INFO(0x012018, 0x4d01,  64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-	{ "s25sl004a",  INFO(0x010212,      0,  64 * 1024,   8, 0) },
-	{ "s25sl008a",  INFO(0x010213,      0,  64 * 1024,  16, 0) },
-	{ "s25sl016a",  INFO(0x010214,      0,  64 * 1024,  32, 0) },
-	{ "s25sl032a",  INFO(0x010215,      0,  64 * 1024,  64, 0) },
-	{ "s25sl064a",  INFO(0x010216,      0,  64 * 1024, 128, 0) },
-	{ "s25fl004k",  INFO(0xef4013,      0,  64 * 1024,   8, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-	{ "s25fl008k",  INFO(0xef4014,      0,  64 * 1024,  16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-	{ "s25fl016k",  INFO(0xef4015,      0,  64 * 1024,  32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-	{ "s25fl064k",  INFO(0xef4017,      0,  64 * 1024, 128, SECT_4K) },
-	{ "s25fl116k",  INFO(0x014015,      0,  64 * 1024,  32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-	{ "s25fl132k",  INFO(0x014016,      0,  64 * 1024,  64, SECT_4K) },
-	{ "s25fl164k",  INFO(0x014017,      0,  64 * 1024, 128, SECT_4K) },
-	{ "s25fl204k",  INFO(0x014013,      0,  64 * 1024,   8, SECT_4K | SPI_NOR_DUAL_READ) },
-	{ "s25fl208k",  INFO(0x014014,      0,  64 * 1024,  16, SECT_4K | SPI_NOR_DUAL_READ) },
+	{ "s25sl032p",  INFO(0x010215, 0x4d00, 2,  64 * 1024,  64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25sl064p",  INFO(0x010216, 0x4d00, 2,  64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25fl256s0", INFO(0x010219, 0x4d00, 2, 256 * 1024, 128, 0) },
+	{ "s25fl256s1", INFO(0x010219, 0x4d01, 2,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25fl512s",  INFO_FULL(0x0102204d00uLL << 24, GENMASK_ULL(63, 24),
+				  256 * 1024, 256, 512, 0, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 2, 256 * 1024, 256, 0) },
+	{ "s25sl12800", INFO(0x012018, 0x0300, 2, 256 * 1024,  64, 0) },
+	{ "s25sl12801", INFO(0x012018, 0x0301, 2,  64 * 1024, 256, 0) },
+	{ "s25fl128s",	INFO(0x012018, 0x4d0180, 3, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25fl129p0", INFO(0x012018, 0x4d00, 2, 256 * 1024,  64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25fl129p1", INFO(0x012018, 0x4d01, 2,  64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25sl004a",  INFO(0x010212, 0, 0,  64 * 1024,   8, 0) },
+	{ "s25sl008a",  INFO(0x010213, 0, 0,  64 * 1024,  16, 0) },
+	{ "s25sl016a",  INFO(0x010214, 0, 0,  64 * 1024,  32, 0) },
+	{ "s25sl032a",  INFO(0x010215, 0, 0,  64 * 1024,  64, 0) },
+	{ "s25sl064a",  INFO(0x010216, 0, 0,  64 * 1024, 128, 0) },
+	{ "s25fl004k",  INFO(0xef4013, 0, 0,  64 * 1024,   8, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25fl008k",  INFO(0xef4014, 0, 0,  64 * 1024,  16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25fl016k",  INFO(0xef4015, 0, 0,  64 * 1024,  32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25fl064k",  INFO(0xef4017, 0, 0,  64 * 1024, 128, SECT_4K) },
+	{ "s25fl116k",  INFO(0x014015, 0, 0,  64 * 1024,  32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25fl132k",  INFO(0x014016, 0, 0,  64 * 1024,  64, SECT_4K) },
+	{ "s25fl164k",  INFO(0x014017, 0, 0,  64 * 1024, 128, SECT_4K) },
+	{ "s25fl204k",  INFO(0x014013, 0, 0,  64 * 1024,   8, SECT_4K | SPI_NOR_DUAL_READ) },
+	{ "s25fl208k",  INFO(0x014014, 0, 0,  64 * 1024,  16, SECT_4K | SPI_NOR_DUAL_READ) },
 
 	/* SST -- large erase sizes are "overlays", "sectors" are 4K */
-	{ "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) },
-	{ "sst25vf080b", INFO(0xbf258e, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },
-	{ "sst25vf016b", INFO(0xbf2541, 0, 64 * 1024, 32, SECT_4K | SST_WRITE) },
-	{ "sst25vf032b", INFO(0xbf254a, 0, 64 * 1024, 64, SECT_4K | SST_WRITE) },
-	{ "sst25vf064c", INFO(0xbf254b, 0, 64 * 1024, 128, SECT_4K) },
-	{ "sst25wf512",  INFO(0xbf2501, 0, 64 * 1024,  1, SECT_4K | SST_WRITE) },
-	{ "sst25wf010",  INFO(0xbf2502, 0, 64 * 1024,  2, SECT_4K | SST_WRITE) },
-	{ "sst25wf020",  INFO(0xbf2503, 0, 64 * 1024,  4, SECT_4K | SST_WRITE) },
-	{ "sst25wf020a", INFO(0x621612, 0, 64 * 1024,  4, SECT_4K) },
-	{ "sst25wf040b", INFO(0x621613, 0, 64 * 1024,  8, SECT_4K) },
-	{ "sst25wf040",  INFO(0xbf2504, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) },
-	{ "sst25wf080",  INFO(0xbf2505, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },
+	{ "sst25vf040b", INFO(0xbf258d, 0, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) },
+	{ "sst25vf080b", INFO(0xbf258e, 0, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },
+	{ "sst25vf016b", INFO(0xbf2541, 0, 0, 64 * 1024, 32, SECT_4K | SST_WRITE) },
+	{ "sst25vf032b", INFO(0xbf254a, 0, 0, 64 * 1024, 64, SECT_4K | SST_WRITE) },
+	{ "sst25vf064c", INFO(0xbf254b, 0, 0, 64 * 1024, 128, SECT_4K) },
+	{ "sst25wf512",  INFO(0xbf2501, 0, 0, 64 * 1024,  1, SECT_4K | SST_WRITE) },
+	{ "sst25wf010",  INFO(0xbf2502, 0, 0, 64 * 1024,  2, SECT_4K | SST_WRITE) },
+	{ "sst25wf020",  INFO(0xbf2503, 0, 0, 64 * 1024,  4, SECT_4K | SST_WRITE) },
+	{ "sst25wf020a", INFO(0x621612, 0, 0, 64 * 1024,  4, SECT_4K) },
+	{ "sst25wf040b", INFO(0x621613, 0, 0, 64 * 1024,  8, SECT_4K) },
+	{ "sst25wf040",  INFO(0xbf2504, 0, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) },
+	{ "sst25wf080",  INFO(0xbf2505, 0, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },
 
 	/* ST Microelectronics -- newer production may have feature updates */
-	{ "m25p05",  INFO(0x202010,  0,  32 * 1024,   2, 0) },
-	{ "m25p10",  INFO(0x202011,  0,  32 * 1024,   4, 0) },
-	{ "m25p20",  INFO(0x202012,  0,  64 * 1024,   4, 0) },
-	{ "m25p40",  INFO(0x202013,  0,  64 * 1024,   8, 0) },
-	{ "m25p80",  INFO(0x202014,  0,  64 * 1024,  16, 0) },
-	{ "m25p16",  INFO(0x202015,  0,  64 * 1024,  32, 0) },
-	{ "m25p32",  INFO(0x202016,  0,  64 * 1024,  64, 0) },
-	{ "m25p64",  INFO(0x202017,  0,  64 * 1024, 128, 0) },
-	{ "m25p128", INFO(0x202018,  0, 256 * 1024,  64, 0) },
-
-	{ "m25p05-nonjedec",  INFO(0, 0,  32 * 1024,   2, 0) },
-	{ "m25p10-nonjedec",  INFO(0, 0,  32 * 1024,   4, 0) },
-	{ "m25p20-nonjedec",  INFO(0, 0,  64 * 1024,   4, 0) },
-	{ "m25p40-nonjedec",  INFO(0, 0,  64 * 1024,   8, 0) },
-	{ "m25p80-nonjedec",  INFO(0, 0,  64 * 1024,  16, 0) },
-	{ "m25p16-nonjedec",  INFO(0, 0,  64 * 1024,  32, 0) },
-	{ "m25p32-nonjedec",  INFO(0, 0,  64 * 1024,  64, 0) },
-	{ "m25p64-nonjedec",  INFO(0, 0,  64 * 1024, 128, 0) },
-	{ "m25p128-nonjedec", INFO(0, 0, 256 * 1024,  64, 0) },
-
-	{ "m45pe10", INFO(0x204011,  0, 64 * 1024,    2, 0) },
-	{ "m45pe80", INFO(0x204014,  0, 64 * 1024,   16, 0) },
-	{ "m45pe16", INFO(0x204015,  0, 64 * 1024,   32, 0) },
-
-	{ "m25pe20", INFO(0x208012,  0, 64 * 1024,  4,       0) },
-	{ "m25pe80", INFO(0x208014,  0, 64 * 1024, 16,       0) },
-	{ "m25pe16", INFO(0x208015,  0, 64 * 1024, 32, SECT_4K) },
-
-	{ "m25px16",    INFO(0x207115,  0, 64 * 1024, 32, SECT_4K) },
-	{ "m25px32",    INFO(0x207116,  0, 64 * 1024, 64, SECT_4K) },
-	{ "m25px32-s0", INFO(0x207316,  0, 64 * 1024, 64, SECT_4K) },
-	{ "m25px32-s1", INFO(0x206316,  0, 64 * 1024, 64, SECT_4K) },
-	{ "m25px64",    INFO(0x207117,  0, 64 * 1024, 128, 0) },
-	{ "m25px80",    INFO(0x207114,  0, 64 * 1024, 16, 0) },
+	{ "m25p05",  INFO(0x202010, 0, 0,  32 * 1024,   2, 0) },
+	{ "m25p10",  INFO(0x202011, 0, 0,  32 * 1024,   4, 0) },
+	{ "m25p20",  INFO(0x202012, 0, 0,  64 * 1024,   4, 0) },
+	{ "m25p40",  INFO(0x202013, 0, 0,  64 * 1024,   8, 0) },
+	{ "m25p80",  INFO(0x202014, 0, 0,  64 * 1024,  16, 0) },
+	{ "m25p16",  INFO(0x202015, 0, 0,  64 * 1024,  32, 0) },
+	{ "m25p32",  INFO(0x202016, 0, 0,  64 * 1024,  64, 0) },
+	{ "m25p64",  INFO(0x202017, 0, 0,  64 * 1024, 128, 0) },
+	{ "m25p128", INFO(0x202018, 0, 0, 256 * 1024,  64, 0) },
+
+	{ "m25p05-nonjedec",  INFO_NOID( 32 * 1024,   2, 256, 0, 0) },
+	{ "m25p10-nonjedec",  INFO_NOID( 32 * 1024,   4, 256, 0, 0) },
+	{ "m25p20-nonjedec",  INFO_NOID( 64 * 1024,   4, 256, 0, 0) },
+	{ "m25p40-nonjedec",  INFO_NOID( 64 * 1024,   8, 256, 0, 0) },
+	{ "m25p80-nonjedec",  INFO_NOID( 64 * 1024,  16, 256, 0, 0) },
+	{ "m25p16-nonjedec",  INFO_NOID( 64 * 1024,  32, 256, 0, 0) },
+	{ "m25p32-nonjedec",  INFO_NOID( 64 * 1024,  64, 256, 0, 0) },
+	{ "m25p64-nonjedec",  INFO_NOID( 64 * 1024, 128, 256, 0, 0) },
+	{ "m25p128-nonjedec", INFO_NOID(256 * 1024,  64, 256, 0, 0) },
+
+	{ "m45pe10", INFO(0x204011, 0, 0, 64 * 1024,    2, 0) },
+	{ "m45pe80", INFO(0x204014, 0, 0, 64 * 1024,   16, 0) },
+	{ "m45pe16", INFO(0x204015, 0, 0, 64 * 1024,   32, 0) },
+
+	{ "m25pe20", INFO(0x208012, 0, 0, 64 * 1024,  4,       0) },
+	{ "m25pe80", INFO(0x208014, 0, 0, 64 * 1024, 16,       0) },
+	{ "m25pe16", INFO(0x208015, 0, 0, 64 * 1024, 32, SECT_4K) },
+
+	{ "m25px16",    INFO(0x207115, 0, 0, 64 * 1024, 32, SECT_4K) },
+	{ "m25px32",    INFO(0x207116, 0, 0, 64 * 1024, 64, SECT_4K) },
+	{ "m25px32-s0", INFO(0x207316, 0, 0, 64 * 1024, 64, SECT_4K) },
+	{ "m25px32-s1", INFO(0x206316, 0, 0, 64 * 1024, 64, SECT_4K) },
+	{ "m25px64",    INFO(0x207117, 0, 0, 64 * 1024, 128, 0) },
+	{ "m25px80",    INFO(0x207114, 0, 0, 64 * 1024, 16, 0) },
 
 	/* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
-	{ "w25x05", INFO(0xef3010, 0, 64 * 1024,  1,  SECT_4K) },
-	{ "w25x10", INFO(0xef3011, 0, 64 * 1024,  2,  SECT_4K) },
-	{ "w25x20", INFO(0xef3012, 0, 64 * 1024,  4,  SECT_4K) },
-	{ "w25x40", INFO(0xef3013, 0, 64 * 1024,  8,  SECT_4K) },
-	{ "w25x80", INFO(0xef3014, 0, 64 * 1024,  16, SECT_4K) },
-	{ "w25x16", INFO(0xef3015, 0, 64 * 1024,  32, SECT_4K) },
-	{ "w25x32", INFO(0xef3016, 0, 64 * 1024,  64, SECT_4K) },
-	{ "w25q32", INFO(0xef4016, 0, 64 * 1024,  64, SECT_4K) },
+	{ "w25x05", INFO(0xef3010, 0, 0, 64 * 1024,  1,  SECT_4K) },
+	{ "w25x10", INFO(0xef3011, 0, 0, 64 * 1024,  2,  SECT_4K) },
+	{ "w25x20", INFO(0xef3012, 0, 0, 64 * 1024,  4,  SECT_4K) },
+	{ "w25x40", INFO(0xef3013, 0, 0, 64 * 1024,  8,  SECT_4K) },
+	{ "w25x80", INFO(0xef3014, 0, 0, 64 * 1024,  16, SECT_4K) },
+	{ "w25x16", INFO(0xef3015, 0, 0, 64 * 1024,  32, SECT_4K) },
+	{ "w25x32", INFO(0xef3016, 0, 0, 64 * 1024,  64, SECT_4K) },
+	{ "w25q32", INFO(0xef4016, 0, 0, 64 * 1024,  64, SECT_4K) },
 	{
-		"w25q32dw", INFO(0xef6016, 0, 64 * 1024,  64,
+		"w25q32dw", INFO(0xef6016, 0, 0, 64 * 1024,  64,
 			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
 	},
-	{ "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
-	{ "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
+	{ "w25x64", INFO(0xef3017, 0, 0, 64 * 1024, 128, SECT_4K) },
+	{ "w25q64", INFO(0xef4017, 0, 0, 64 * 1024, 128, SECT_4K) },
 	{
-		"w25q64dw", INFO(0xef6017, 0, 64 * 1024, 128,
+		"w25q64dw", INFO(0xef6017, 0, 0, 64 * 1024, 128,
 			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
 	},
 	{
-		"w25q128fw", INFO(0xef6018, 0, 64 * 1024, 256,
+		"w25q128fw", INFO(0xef6018, 0, 0, 64 * 1024, 256,
 			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
 	},
-	{ "w25q80", INFO(0xef5014, 0, 64 * 1024,  16, SECT_4K) },
-	{ "w25q80bl", INFO(0xef4014, 0, 64 * 1024,  16, SECT_4K) },
-	{ "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
-	{ "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K) },
+	{ "w25q80",   INFO(0xef5014, 0, 0, 64 * 1024,  16, SECT_4K) },
+	{ "w25q80bl", INFO(0xef4014, 0, 0, 64 * 1024,  16, SECT_4K) },
+	{ "w25q128",  INFO(0xef4018, 0, 0, 64 * 1024, 256, SECT_4K) },
+	{ "w25q256",  INFO(0xef4019, 0, 0, 64 * 1024, 512, SECT_4K) },
 
 	/* Catalyst / On Semiconductor -- non-JEDEC */
-	{ "cat25c11", CAT25_INFO(  16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
-	{ "cat25c03", CAT25_INFO(  32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
-	{ "cat25c09", CAT25_INFO( 128, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
-	{ "cat25c17", CAT25_INFO( 256, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
-	{ "cat25128", CAT25_INFO(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "cat25c11", INFO_NOID(  16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "cat25c03", INFO_NOID(  32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "cat25c09", INFO_NOID( 128, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "cat25c17", INFO_NOID( 256, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "cat25128", INFO_NOID(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
 
 	/* Xilinx S3AN Internal Flash */
-	{ "3S50AN", S3AN_INFO(0x1f2200, 64, 264) },
-	{ "3S200AN", S3AN_INFO(0x1f2400, 256, 264) },
-	{ "3S400AN", S3AN_INFO(0x1f2400, 256, 264) },
-	{ "3S700AN", S3AN_INFO(0x1f2500, 512, 264) },
-	{ "3S1400AN", S3AN_INFO(0x1f2600, 512, 528) },
+	{ "3S50AN",   INFO_S3AN(0x1f2200, 64, 264) },
+	{ "3S200AN",  INFO_S3AN(0x1f2400, 256, 264) },
+	{ "3S400AN",  INFO_S3AN(0x1f2400, 256, 264) },
+	{ "3S700AN",  INFO_S3AN(0x1f2500, 512, 264) },
+	{ "3S1400AN", INFO_S3AN(0x1f2600, 512, 528) },
 	{ },
 };
 
 static const struct flash_info *spi_nor_read_id(struct spi_nor *nor)
 {
 	int			tmp;
-	u8			id[SPI_NOR_MAX_ID_LEN];
+	u8			id_bytes[sizeof(u64)];
+	u64			id;
 	const struct flash_info	*info;
 
-	tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
+	BUILD_BUG_ON(SPI_NOR_MAX_ID_LEN > sizeof(u64));
+
+	memset(id_bytes, 0, sizeof(id_bytes));
+	tmp = nor->read_reg(nor, SPINOR_OP_RDID, id_bytes, SPI_NOR_MAX_ID_LEN);
 	if (tmp < 0) {
 		dev_dbg(nor->dev, "error %d reading JEDEC ID\n", tmp);
 		return ERR_PTR(tmp);
 	}
 
+	id = get_unaligned_be64(id_bytes);
+
 	for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) {
 		info = &spi_nor_ids[tmp];
-		if (info->id_len) {
-			if (!memcmp(info->id, id, info->id_len))
-				return &spi_nor_ids[tmp];
-		}
+		if (info->id_mask && (id & info->id_mask) == info->id)
+			return info;
 	}
-	dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %02x, %02x\n",
-		id[0], id[1], id[2]);
+	dev_err(nor->dev, "unrecognized JEDEC id bytes: %*ph\n",
+		SPI_NOR_MAX_ID_LEN, id_bytes);
 	return ERR_PTR(-ENODEV);
 }
 
@@ -1551,7 +1555,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
 	 * If caller has specified name of flash model that can normally be
 	 * detected using JEDEC, let's verify it.
 	 */
-	if (name && info->id_len) {
+	if (name && info->id_mask) {
 		const struct flash_info *jinfo;
 
 		jinfo = spi_nor_read_id(nor);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH] mtd: spi-nor: flash_info table, use a u64 for the ID
  2017-02-13 13:53       ` [PATCH] mtd: spi-nor: flash_info table, use a u64 for the ID mark.marshall
@ 2017-02-14  5:02         ` Marek Vasut
  2017-02-14 10:22           ` Cyrille Pitchen
  0 siblings, 1 reply; 12+ messages in thread
From: Marek Vasut @ 2017-02-14  5:02 UTC (permalink / raw)
  To: mark.marshall, computersforpeace, linux-mtd
  Cc: markmarshall14, cyrille.pitchen, dwmw2, richard, boris.brezillon

On 02/13/2017 02:53 PM, mark.marshall@omicronenergy.com wrote:
> From: Mark Marshall <mark.marshall@omicronenergy.com>
> 
> The flash_info ID matching table is getting more complex as different
> chips are added.  Some chips require different amounts of the response
> to the RDID command to be matched.  Replace the current u8 array and
> length with a u64 id and a u64 id_mask.  This allows us to simplify the
> macros used to generate the flash_info table without loosing the ability
> to generate "unusual" entries.
> 
> --
> 
> This patch replaces "m25p80: Use a 512 byte page size for Spansion
> flash s25fl512s".  It is based on for-linus-20170212, from the
> linux-mtd tree.
> 
> 
> Signed-off-by: Mark Marshall <mark.marshall@omicronenergy.com>

Minor nits below, looks good IMO. I'd still like someone else to review
this whole idea though. Cyrille ?

> ---
>  drivers/mtd/spi-nor/spi-nor.c | 458 +++++++++++++++++++++---------------------
>  1 file changed, 231 insertions(+), 227 deletions(-)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index 1ae872b..c7ff237 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -41,15 +41,20 @@
>  #define SPI_NOR_MAX_ADDR_WIDTH	4
>  
>  struct flash_info {
> -	char		*name;
> +	const char	*name;
>  
>  	/*
> -	 * This array stores the ID bytes.
> -	 * The first three bytes are the JEDIC ID.
> -	 * JEDEC ID zero means "no ID" (mostly older chips).
> +	 * This u64 stores the ID bytes.
> +	 * The bytes are stored in big-endian order.
> +	 * The upper three bytes are the JEDIC ID, the lower bytes are
> +	 * the extension.
>  	 */
> -	u8		id[SPI_NOR_MAX_ID_LEN];
> -	u8		id_len;
> +	u64		id;
> +
> +	/*
> +	 * An id_mask of zero means "no ID" (mostly older chips).
> +	 */
> +	u64		id_mask;
>  
>  	/* The size listed here is what works with SPINOR_OP_SE, which isn't
>  	 * necessarily called a "sector" by the vendor.
> @@ -87,7 +92,7 @@ struct flash_info {
>  					 */
>  };
>  
> -#define JEDEC_MFR(info)	((info)->id[0])
> +#define JEDEC_MFR(info)	((u8)((info)->id >> 56) & 0xff)
>  
>  static const struct flash_info *spi_nor_match_id(const char *name);
>  
> @@ -870,55 +875,49 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
>  	return ret;
>  }
>  
> -/* Used when the "_ext_id" is two bytes at most */
> -#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
> -		.id = {							\
> -			((_jedec_id) >> 16) & 0xff,			\
> -			((_jedec_id) >> 8) & 0xff,			\
> -			(_jedec_id) & 0xff,				\
> -			((_ext_id) >> 8) & 0xff,			\
> -			(_ext_id) & 0xff,				\
> -			},						\
> -		.id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))),	\
> -		.sector_size = (_sector_size),				\
> -		.n_sectors = (_n_sectors),				\
> -		.page_size = 256,					\
> -		.flags = (_flags),
> -
> -#define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
> -		.id = {							\
> -			((_jedec_id) >> 16) & 0xff,			\
> -			((_jedec_id) >> 8) & 0xff,			\
> -			(_jedec_id) & 0xff,				\
> -			((_ext_id) >> 16) & 0xff,			\
> -			((_ext_id) >> 8) & 0xff,			\
> -			(_ext_id) & 0xff,				\
> -			},						\
> -		.id_len = 6,						\
> -		.sector_size = (_sector_size),				\
> -		.n_sectors = (_n_sectors),				\
> -		.page_size = 256,					\
> -		.flags = (_flags),
> -
> -#define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width, _flags)	\
> -		.sector_size = (_sector_size),				\
> -		.n_sectors = (_n_sectors),				\
> -		.page_size = (_page_size),				\
> -		.addr_width = (_addr_width),				\
> -		.flags = (_flags),
> -
> -#define S3AN_INFO(_jedec_id, _n_sectors, _page_size)			\
> -		.id = {							\
> -			((_jedec_id) >> 16) & 0xff,			\
> -			((_jedec_id) >> 8) & 0xff,			\
> -			(_jedec_id) & 0xff				\
> -			},						\
> -		.id_len = 3,						\
> -		.sector_size = (8*_page_size),				\
> -		.n_sectors = (_n_sectors),				\
> -		.page_size = _page_size,				\
> -		.addr_width = 3,					\
> -		.flags = SPI_NOR_NO_FR | SPI_S3AN,
> +/* Used to provide the full information about a device.
> + */

Fix the comment format here , single line comment is enough
( /* comment */ )

> +#define INFO_FULL(_id, _id_mask, _sector_size, _n_sectors, _pg_sz, _addr_width, _flags)	\
> +	.id = (_id),							\
> +	.id_mask = (_id_mask),						\
> +	.sector_size = (_sector_size),					\
> +	.n_sectors = (_n_sectors),					\
> +	.page_size = (_pg_sz),						\
> +	.addr_width = (_addr_width),					\
> +	.flags = (_flags),
> +
> +/* Used to provide information for a standard JEDEC device.  All
> + * devices created with this macro have a three octet JEDEC identifier
> + * and an optional extension identifier (normally 0, 2 or 3 octets
> + * long).
> + */

Multi-line comment looks like this:

/*
 * foo
 * bar
 */

> +#define INFO(_jedec_id, _ext_id, _ext_len, _sector_size, _n_sectors, _flags) \
> +	INFO_FULL(((u64)(_jedec_id) << (64 - (8 * 3))) |		\
> +		  ((u64)(_ext_id) << (64 - (8 * (3 + _ext_len)))),	\

Is the u64 cast needed ? I don't think so.

> +		  GENMASK_ULL(63, 64 - (8 * (3 + _ext_len))),		\

You need parenthesis around _ext_len

> +		  (_sector_size),					\
> +		  (_n_sectors),						\
> +		  256,							\
> +		  0,							\
> +		  (_flags))
> +
> +#define INFO_NOID(_sector_size, _n_sectors, _page_size, _addr_width, _flags)	\
> +	INFO_FULL(0,							\
> +		  0,							\
> +		  (_sector_size),					\
> +		  (_n_sectors),						\
> +		  (_page_size),						\
> +		  (_addr_width),					\
> +		  (_flags))
> +
> +#define INFO_S3AN(_jedec_id, _n_sectors, _page_size)			\
> +	INFO_FULL(((u64)(_jedec_id) << (64 - (8 * 3))),			\
> +		  GENMASK_ULL(63, 64 - (8 * 3)),			\
> +		  (8*_page_size),					\
> +		  (_n_sectors),						\
> +		  (_page_size),						\
> +		  3,							\
> +		  SPI_NOR_NO_FR | SPI_S3AN)
>  
>  /* NOTE: double check command sets and memory organization when you add
>   * more nor chips.  This current list focusses on newer chips, which
> @@ -933,261 +932,266 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
>   */
>  static const struct flash_info spi_nor_ids[] = {
>  	/* Atmel -- some are (confusingly) marketed as "DataFlash" */
> -	{ "at25fs010",  INFO(0x1f6601, 0, 32 * 1024,   4, SECT_4K) },
> -	{ "at25fs040",  INFO(0x1f6604, 0, 64 * 1024,   8, SECT_4K) },
> +	{ "at25fs010",  INFO(0x1f6601, 0, 0, 32 * 1024,   4, SECT_4K) },
> +	{ "at25fs040",  INFO(0x1f6604, 0, 0, 64 * 1024,   8, SECT_4K) },
>  
> -	{ "at25df041a", INFO(0x1f4401, 0, 64 * 1024,   8, SECT_4K) },
> -	{ "at25df321",  INFO(0x1f4700, 0, 64 * 1024,  64, SECT_4K) },
> -	{ "at25df321a", INFO(0x1f4701, 0, 64 * 1024,  64, SECT_4K) },
> -	{ "at25df641",  INFO(0x1f4800, 0, 64 * 1024, 128, SECT_4K) },
> +	{ "at25df041a", INFO(0x1f4401, 0, 0, 64 * 1024,   8, SECT_4K) },
> +	{ "at25df321",  INFO(0x1f4700, 0, 0, 64 * 1024,  64, SECT_4K) },
> +	{ "at25df321a", INFO(0x1f4701, 0, 0, 64 * 1024,  64, SECT_4K) },
> +	{ "at25df641",  INFO(0x1f4800, 0, 0, 64 * 1024, 128, SECT_4K) },
>  
> -	{ "at26f004",   INFO(0x1f0400, 0, 64 * 1024,  8, SECT_4K) },
> -	{ "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16, SECT_4K) },
> -	{ "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) },
> -	{ "at26df321",  INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) },
> +	{ "at26f004",   INFO(0x1f0400, 0, 0, 64 * 1024,  8, SECT_4K) },
> +	{ "at26df081a", INFO(0x1f4501, 0, 0, 64 * 1024, 16, SECT_4K) },
> +	{ "at26df161a", INFO(0x1f4601, 0, 0, 64 * 1024, 32, SECT_4K) },
> +	{ "at26df321",  INFO(0x1f4700, 0, 0, 64 * 1024, 64, SECT_4K) },
>  
> -	{ "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) },
> +	{ "at45db081d", INFO(0x1f2500, 0, 0, 64 * 1024, 16, SECT_4K) },
>  
>  	/* EON -- en25xxx */
> -	{ "en25f32",    INFO(0x1c3116, 0, 64 * 1024,   64, SECT_4K) },
> -	{ "en25p32",    INFO(0x1c2016, 0, 64 * 1024,   64, 0) },
> -	{ "en25q32b",   INFO(0x1c3016, 0, 64 * 1024,   64, 0) },
> -	{ "en25p64",    INFO(0x1c2017, 0, 64 * 1024,  128, 0) },
> -	{ "en25q64",    INFO(0x1c3017, 0, 64 * 1024,  128, SECT_4K) },
> -	{ "en25qh128",  INFO(0x1c7018, 0, 64 * 1024,  256, 0) },
> -	{ "en25qh256",  INFO(0x1c7019, 0, 64 * 1024,  512, 0) },
> -	{ "en25s64",	INFO(0x1c3817, 0, 64 * 1024,  128, SECT_4K) },
> +	{ "en25f32",    INFO(0x1c3116, 0, 0, 64 * 1024,   64, SECT_4K) },
> +	{ "en25p32",    INFO(0x1c2016, 0, 0, 64 * 1024,   64, 0) },
> +	{ "en25q32b",   INFO(0x1c3016, 0, 0, 64 * 1024,   64, 0) },
> +	{ "en25p64",    INFO(0x1c2017, 0, 0, 64 * 1024,  128, 0) },
> +	{ "en25q64",    INFO(0x1c3017, 0, 0, 64 * 1024,  128, SECT_4K) },
> +	{ "en25qh128",  INFO(0x1c7018, 0, 0, 64 * 1024,  256, 0) },
> +	{ "en25qh256",  INFO(0x1c7019, 0, 0, 64 * 1024,  512, 0) },
> +	{ "en25s64",	INFO(0x1c3817, 0, 0, 64 * 1024,  128, SECT_4K) },
>  
>  	/* ESMT */
> -	{ "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) },
> +	{ "f25l32pa", INFO(0x8c2016, 0, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) },
>  
>  	/* Everspin */
> -	{ "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
> -	{ "mr25h10",  CAT25_INFO(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
> -	{ "mr25h40",  CAT25_INFO(512 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
> +	{ "mr25h256", INFO_NOID( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
> +	{ "mr25h10",  INFO_NOID(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
> +	{ "mr25h40",  INFO_NOID(512 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
>  
>  	/* Fujitsu */
> -	{ "mb85rs1mt", INFO(0x047f27, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) },
> +	{ "mb85rs1mt", INFO(0x047f27, 0, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) },
>  
>  	/* GigaDevice */
>  	{
> -		"gd25q16", INFO(0xc84015, 0, 64 * 1024,  32,
> +		"gd25q16", INFO(0xc84015, 0, 0, 64 * 1024,  32,
>  			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>  			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
>  	},
>  	{
> -		"gd25q32", INFO(0xc84016, 0, 64 * 1024,  64,
> +		"gd25q32", INFO(0xc84016, 0, 0, 64 * 1024,  64,
>  			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>  			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
>  	},
>  	{
> -		"gd25q64", INFO(0xc84017, 0, 64 * 1024, 128,
> +		"gd25q64", INFO(0xc84017, 0, 0, 64 * 1024, 128,
>  			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>  			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
>  	},
>  	{
> -		"gd25lq64c", INFO(0xc86017, 0, 64 * 1024, 128,
> +		"gd25lq64c", INFO(0xc86017, 0, 0, 64 * 1024, 128,
>  			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>  			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
>  	},
>  	{
> -		"gd25q128", INFO(0xc84018, 0, 64 * 1024, 256,
> +		"gd25q128", INFO(0xc84018, 0, 0, 64 * 1024, 256,
>  			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>  			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
>  	},
>  
>  	/* Intel/Numonyx -- xxxs33b */
> -	{ "160s33b",  INFO(0x898911, 0, 64 * 1024,  32, 0) },
> -	{ "320s33b",  INFO(0x898912, 0, 64 * 1024,  64, 0) },
> -	{ "640s33b",  INFO(0x898913, 0, 64 * 1024, 128, 0) },
> +	{ "160s33b",  INFO(0x898911, 0, 0, 64 * 1024,  32, 0) },
> +	{ "320s33b",  INFO(0x898912, 0, 0, 64 * 1024,  64, 0) },
> +	{ "640s33b",  INFO(0x898913, 0, 0, 64 * 1024, 128, 0) },
>  
>  	/* ISSI */
> -	{ "is25cd512", INFO(0x7f9d20, 0, 32 * 1024,   2, SECT_4K) },
> +	{ "is25cd512", INFO(0x7f9d20, 0, 0, 32 * 1024,   2, SECT_4K) },
>  
>  	/* Macronix */
> -	{ "mx25l512e",   INFO(0xc22010, 0, 64 * 1024,   1, SECT_4K) },
> -	{ "mx25l2005a",  INFO(0xc22012, 0, 64 * 1024,   4, SECT_4K) },
> -	{ "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) },
> -	{ "mx25l3255e",  INFO(0xc29e16, 0, 64 * 1024,  64, SECT_4K) },
> -	{ "mx25l6405d",  INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) },
> -	{ "mx25u6435f",  INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) },
> -	{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
> -	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
> -	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
> -	{ "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K) },
> -	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
> -	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) },
> -	{ "mx66l1g55g",  INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) },
> +	{ "mx25l512e",   INFO(0xc22010, 0, 0, 64 * 1024,   1, SECT_4K) },
> +	{ "mx25l2005a",  INFO(0xc22012, 0, 0, 64 * 1024,   4, SECT_4K) },
> +	{ "mx25l4005a",  INFO(0xc22013, 0, 0, 64 * 1024,   8, SECT_4K) },
> +	{ "mx25l8005",   INFO(0xc22014, 0, 0, 64 * 1024,  16, 0) },
> +	{ "mx25l1606e",  INFO(0xc22015, 0, 0, 64 * 1024,  32, SECT_4K) },
> +	{ "mx25l3205d",  INFO(0xc22016, 0, 0, 64 * 1024,  64, SECT_4K) },
> +	{ "mx25l3255e",  INFO(0xc29e16, 0, 0, 64 * 1024,  64, SECT_4K) },
> +	{ "mx25l6405d",  INFO(0xc22017, 0, 0, 64 * 1024, 128, SECT_4K) },
> +	{ "mx25u6435f",  INFO(0xc22537, 0, 0, 64 * 1024, 128, SECT_4K) },
> +	{ "mx25l12805d", INFO(0xc22018, 0, 0, 64 * 1024, 256, 0) },
> +	{ "mx25l12855e", INFO(0xc22618, 0, 0, 64 * 1024, 256, 0) },
> +	{ "mx25l25635e", INFO(0xc22019, 0, 0, 64 * 1024, 512, 0) },
> +	{ "mx25u25635f", INFO(0xc22539, 0, 0, 64 * 1024, 512, SECT_4K) },
> +	{ "mx25l25655e", INFO(0xc22619, 0, 0, 64 * 1024, 512, 0) },
> +	{ "mx66l51235l", INFO(0xc2201a, 0, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) },
> +	{ "mx66l1g55g",  INFO(0xc2261b, 0, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) },
>  
>  	/* Micron */
> -	{ "n25q016a",	 INFO(0x20bb15, 0, 64 * 1024,   32, SECT_4K | SPI_NOR_QUAD_READ) },
> -	{ "n25q032",	 INFO(0x20ba16, 0, 64 * 1024,   64, SPI_NOR_QUAD_READ) },
> -	{ "n25q032a",	 INFO(0x20bb16, 0, 64 * 1024,   64, SPI_NOR_QUAD_READ) },
> -	{ "n25q064",     INFO(0x20ba17, 0, 64 * 1024,  128, SECT_4K | SPI_NOR_QUAD_READ) },
> -	{ "n25q064a",    INFO(0x20bb17, 0, 64 * 1024,  128, SECT_4K | SPI_NOR_QUAD_READ) },
> -	{ "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024,  256, SECT_4K | SPI_NOR_QUAD_READ) },
> -	{ "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024,  256, SECT_4K | SPI_NOR_QUAD_READ) },
> -	{ "n25q256a",    INFO(0x20ba19, 0, 64 * 1024,  512, SECT_4K | SPI_NOR_QUAD_READ) },
> -	{ "n25q512a",    INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
> -	{ "n25q512ax3",  INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
> -	{ "n25q00",      INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
> -	{ "n25q00a",     INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
> +	{ "n25q016a",	 INFO(0x20bb15, 0, 0, 64 * 1024,   32, SECT_4K | SPI_NOR_QUAD_READ) },
> +	{ "n25q032",	 INFO(0x20ba16, 0, 0, 64 * 1024,   64, SPI_NOR_QUAD_READ) },
> +	{ "n25q032a",	 INFO(0x20bb16, 0, 0, 64 * 1024,   64, SPI_NOR_QUAD_READ) },
> +	{ "n25q064",     INFO(0x20ba17, 0, 0, 64 * 1024,  128, SECT_4K | SPI_NOR_QUAD_READ) },
> +	{ "n25q064a",    INFO(0x20bb17, 0, 0, 64 * 1024,  128, SECT_4K | SPI_NOR_QUAD_READ) },
> +	{ "n25q128a11",  INFO(0x20bb18, 0, 0, 64 * 1024,  256, SECT_4K | SPI_NOR_QUAD_READ) },
> +	{ "n25q128a13",  INFO(0x20ba18, 0, 0, 64 * 1024,  256, SECT_4K | SPI_NOR_QUAD_READ) },
> +	{ "n25q256a",    INFO(0x20ba19, 0, 0, 64 * 1024,  512, SECT_4K | SPI_NOR_QUAD_READ) },
> +	{ "n25q512a",    INFO(0x20bb20, 0, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
> +	{ "n25q512ax3",  INFO(0x20ba20, 0, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
> +	{ "n25q00",      INFO(0x20ba21, 0, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
> +	{ "n25q00a",     INFO(0x20bb21, 0, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
>  
>  	/* PMC */
> -	{ "pm25lv512",   INFO(0,        0, 32 * 1024,    2, SECT_4K_PMC) },
> -	{ "pm25lv010",   INFO(0,        0, 32 * 1024,    4, SECT_4K_PMC) },
> -	{ "pm25lq032",   INFO(0x7f9d46, 0, 64 * 1024,   64, SECT_4K) },
> +	{ "pm25lv512",   INFO_NOID(32 * 1024,    2, 256, 0, SECT_4K_PMC) },
> +	{ "pm25lv010",   INFO_NOID(32 * 1024,    4, 256, 0, SECT_4K_PMC) },
> +	{ "pm25lq032",   INFO(0x7f9d46, 0, 0, 64 * 1024,   64, SECT_4K) },
>  
>  	/* Spansion -- single (large) sector size only, at least
>  	 * for the chips listed here (without boot sectors).
>  	 */
> -	{ "s25sl032p",  INFO(0x010215, 0x4d00,  64 * 1024,  64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> -	{ "s25sl064p",  INFO(0x010216, 0x4d00,  64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> -	{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
> -	{ "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> -	{ "s25fl512s",  INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> -	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
> -	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
> -	{ "s25sl12801", INFO(0x012018, 0x0301,  64 * 1024, 256, 0) },
> -	{ "s25fl128s",	INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> -	{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024,  64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> -	{ "s25fl129p1", INFO(0x012018, 0x4d01,  64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> -	{ "s25sl004a",  INFO(0x010212,      0,  64 * 1024,   8, 0) },
> -	{ "s25sl008a",  INFO(0x010213,      0,  64 * 1024,  16, 0) },
> -	{ "s25sl016a",  INFO(0x010214,      0,  64 * 1024,  32, 0) },
> -	{ "s25sl032a",  INFO(0x010215,      0,  64 * 1024,  64, 0) },
> -	{ "s25sl064a",  INFO(0x010216,      0,  64 * 1024, 128, 0) },
> -	{ "s25fl004k",  INFO(0xef4013,      0,  64 * 1024,   8, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> -	{ "s25fl008k",  INFO(0xef4014,      0,  64 * 1024,  16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> -	{ "s25fl016k",  INFO(0xef4015,      0,  64 * 1024,  32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> -	{ "s25fl064k",  INFO(0xef4017,      0,  64 * 1024, 128, SECT_4K) },
> -	{ "s25fl116k",  INFO(0x014015,      0,  64 * 1024,  32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> -	{ "s25fl132k",  INFO(0x014016,      0,  64 * 1024,  64, SECT_4K) },
> -	{ "s25fl164k",  INFO(0x014017,      0,  64 * 1024, 128, SECT_4K) },
> -	{ "s25fl204k",  INFO(0x014013,      0,  64 * 1024,   8, SECT_4K | SPI_NOR_DUAL_READ) },
> -	{ "s25fl208k",  INFO(0x014014,      0,  64 * 1024,  16, SECT_4K | SPI_NOR_DUAL_READ) },
> +	{ "s25sl032p",  INFO(0x010215, 0x4d00, 2,  64 * 1024,  64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> +	{ "s25sl064p",  INFO(0x010216, 0x4d00, 2,  64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> +	{ "s25fl256s0", INFO(0x010219, 0x4d00, 2, 256 * 1024, 128, 0) },
> +	{ "s25fl256s1", INFO(0x010219, 0x4d01, 2,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> +	{ "s25fl512s",  INFO_FULL(0x0102204d00uLL << 24, GENMASK_ULL(63, 24),
> +				  256 * 1024, 256, 512, 0, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },

Hm, this syntax here could use some improvement ... ideas welcome.

> +	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 2, 256 * 1024, 256, 0) },
> +	{ "s25sl12800", INFO(0x012018, 0x0300, 2, 256 * 1024,  64, 0) },
> +	{ "s25sl12801", INFO(0x012018, 0x0301, 2,  64 * 1024, 256, 0) },
> +	{ "s25fl128s",	INFO(0x012018, 0x4d0180, 3, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> +	{ "s25fl129p0", INFO(0x012018, 0x4d00, 2, 256 * 1024,  64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> +	{ "s25fl129p1", INFO(0x012018, 0x4d01, 2,  64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> +	{ "s25sl004a",  INFO(0x010212, 0, 0,  64 * 1024,   8, 0) },
> +	{ "s25sl008a",  INFO(0x010213, 0, 0,  64 * 1024,  16, 0) },
> +	{ "s25sl016a",  INFO(0x010214, 0, 0,  64 * 1024,  32, 0) },
> +	{ "s25sl032a",  INFO(0x010215, 0, 0,  64 * 1024,  64, 0) },
> +	{ "s25sl064a",  INFO(0x010216, 0, 0,  64 * 1024, 128, 0) },
> +	{ "s25fl004k",  INFO(0xef4013, 0, 0,  64 * 1024,   8, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> +	{ "s25fl008k",  INFO(0xef4014, 0, 0,  64 * 1024,  16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> +	{ "s25fl016k",  INFO(0xef4015, 0, 0,  64 * 1024,  32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> +	{ "s25fl064k",  INFO(0xef4017, 0, 0,  64 * 1024, 128, SECT_4K) },
> +	{ "s25fl116k",  INFO(0x014015, 0, 0,  64 * 1024,  32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> +	{ "s25fl132k",  INFO(0x014016, 0, 0,  64 * 1024,  64, SECT_4K) },
> +	{ "s25fl164k",  INFO(0x014017, 0, 0,  64 * 1024, 128, SECT_4K) },
> +	{ "s25fl204k",  INFO(0x014013, 0, 0,  64 * 1024,   8, SECT_4K | SPI_NOR_DUAL_READ) },
> +	{ "s25fl208k",  INFO(0x014014, 0, 0,  64 * 1024,  16, SECT_4K | SPI_NOR_DUAL_READ) },
>  
>  	/* SST -- large erase sizes are "overlays", "sectors" are 4K */
> -	{ "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) },
> -	{ "sst25vf080b", INFO(0xbf258e, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },
> -	{ "sst25vf016b", INFO(0xbf2541, 0, 64 * 1024, 32, SECT_4K | SST_WRITE) },
> -	{ "sst25vf032b", INFO(0xbf254a, 0, 64 * 1024, 64, SECT_4K | SST_WRITE) },
> -	{ "sst25vf064c", INFO(0xbf254b, 0, 64 * 1024, 128, SECT_4K) },
> -	{ "sst25wf512",  INFO(0xbf2501, 0, 64 * 1024,  1, SECT_4K | SST_WRITE) },
> -	{ "sst25wf010",  INFO(0xbf2502, 0, 64 * 1024,  2, SECT_4K | SST_WRITE) },
> -	{ "sst25wf020",  INFO(0xbf2503, 0, 64 * 1024,  4, SECT_4K | SST_WRITE) },
> -	{ "sst25wf020a", INFO(0x621612, 0, 64 * 1024,  4, SECT_4K) },
> -	{ "sst25wf040b", INFO(0x621613, 0, 64 * 1024,  8, SECT_4K) },
> -	{ "sst25wf040",  INFO(0xbf2504, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) },
> -	{ "sst25wf080",  INFO(0xbf2505, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },
> +	{ "sst25vf040b", INFO(0xbf258d, 0, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) },
> +	{ "sst25vf080b", INFO(0xbf258e, 0, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },
> +	{ "sst25vf016b", INFO(0xbf2541, 0, 0, 64 * 1024, 32, SECT_4K | SST_WRITE) },
> +	{ "sst25vf032b", INFO(0xbf254a, 0, 0, 64 * 1024, 64, SECT_4K | SST_WRITE) },
> +	{ "sst25vf064c", INFO(0xbf254b, 0, 0, 64 * 1024, 128, SECT_4K) },
> +	{ "sst25wf512",  INFO(0xbf2501, 0, 0, 64 * 1024,  1, SECT_4K | SST_WRITE) },
> +	{ "sst25wf010",  INFO(0xbf2502, 0, 0, 64 * 1024,  2, SECT_4K | SST_WRITE) },
> +	{ "sst25wf020",  INFO(0xbf2503, 0, 0, 64 * 1024,  4, SECT_4K | SST_WRITE) },
> +	{ "sst25wf020a", INFO(0x621612, 0, 0, 64 * 1024,  4, SECT_4K) },
> +	{ "sst25wf040b", INFO(0x621613, 0, 0, 64 * 1024,  8, SECT_4K) },
> +	{ "sst25wf040",  INFO(0xbf2504, 0, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) },
> +	{ "sst25wf080",  INFO(0xbf2505, 0, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },
>  
>  	/* ST Microelectronics -- newer production may have feature updates */
> -	{ "m25p05",  INFO(0x202010,  0,  32 * 1024,   2, 0) },
> -	{ "m25p10",  INFO(0x202011,  0,  32 * 1024,   4, 0) },
> -	{ "m25p20",  INFO(0x202012,  0,  64 * 1024,   4, 0) },
> -	{ "m25p40",  INFO(0x202013,  0,  64 * 1024,   8, 0) },
> -	{ "m25p80",  INFO(0x202014,  0,  64 * 1024,  16, 0) },
> -	{ "m25p16",  INFO(0x202015,  0,  64 * 1024,  32, 0) },
> -	{ "m25p32",  INFO(0x202016,  0,  64 * 1024,  64, 0) },
> -	{ "m25p64",  INFO(0x202017,  0,  64 * 1024, 128, 0) },
> -	{ "m25p128", INFO(0x202018,  0, 256 * 1024,  64, 0) },
> -
> -	{ "m25p05-nonjedec",  INFO(0, 0,  32 * 1024,   2, 0) },
> -	{ "m25p10-nonjedec",  INFO(0, 0,  32 * 1024,   4, 0) },
> -	{ "m25p20-nonjedec",  INFO(0, 0,  64 * 1024,   4, 0) },
> -	{ "m25p40-nonjedec",  INFO(0, 0,  64 * 1024,   8, 0) },
> -	{ "m25p80-nonjedec",  INFO(0, 0,  64 * 1024,  16, 0) },
> -	{ "m25p16-nonjedec",  INFO(0, 0,  64 * 1024,  32, 0) },
> -	{ "m25p32-nonjedec",  INFO(0, 0,  64 * 1024,  64, 0) },
> -	{ "m25p64-nonjedec",  INFO(0, 0,  64 * 1024, 128, 0) },
> -	{ "m25p128-nonjedec", INFO(0, 0, 256 * 1024,  64, 0) },
> -
> -	{ "m45pe10", INFO(0x204011,  0, 64 * 1024,    2, 0) },
> -	{ "m45pe80", INFO(0x204014,  0, 64 * 1024,   16, 0) },
> -	{ "m45pe16", INFO(0x204015,  0, 64 * 1024,   32, 0) },
> -
> -	{ "m25pe20", INFO(0x208012,  0, 64 * 1024,  4,       0) },
> -	{ "m25pe80", INFO(0x208014,  0, 64 * 1024, 16,       0) },
> -	{ "m25pe16", INFO(0x208015,  0, 64 * 1024, 32, SECT_4K) },
> -
> -	{ "m25px16",    INFO(0x207115,  0, 64 * 1024, 32, SECT_4K) },
> -	{ "m25px32",    INFO(0x207116,  0, 64 * 1024, 64, SECT_4K) },
> -	{ "m25px32-s0", INFO(0x207316,  0, 64 * 1024, 64, SECT_4K) },
> -	{ "m25px32-s1", INFO(0x206316,  0, 64 * 1024, 64, SECT_4K) },
> -	{ "m25px64",    INFO(0x207117,  0, 64 * 1024, 128, 0) },
> -	{ "m25px80",    INFO(0x207114,  0, 64 * 1024, 16, 0) },
> +	{ "m25p05",  INFO(0x202010, 0, 0,  32 * 1024,   2, 0) },
> +	{ "m25p10",  INFO(0x202011, 0, 0,  32 * 1024,   4, 0) },
> +	{ "m25p20",  INFO(0x202012, 0, 0,  64 * 1024,   4, 0) },
> +	{ "m25p40",  INFO(0x202013, 0, 0,  64 * 1024,   8, 0) },
> +	{ "m25p80",  INFO(0x202014, 0, 0,  64 * 1024,  16, 0) },
> +	{ "m25p16",  INFO(0x202015, 0, 0,  64 * 1024,  32, 0) },
> +	{ "m25p32",  INFO(0x202016, 0, 0,  64 * 1024,  64, 0) },
> +	{ "m25p64",  INFO(0x202017, 0, 0,  64 * 1024, 128, 0) },
> +	{ "m25p128", INFO(0x202018, 0, 0, 256 * 1024,  64, 0) },
> +
> +	{ "m25p05-nonjedec",  INFO_NOID( 32 * 1024,   2, 256, 0, 0) },
> +	{ "m25p10-nonjedec",  INFO_NOID( 32 * 1024,   4, 256, 0, 0) },
> +	{ "m25p20-nonjedec",  INFO_NOID( 64 * 1024,   4, 256, 0, 0) },
> +	{ "m25p40-nonjedec",  INFO_NOID( 64 * 1024,   8, 256, 0, 0) },
> +	{ "m25p80-nonjedec",  INFO_NOID( 64 * 1024,  16, 256, 0, 0) },
> +	{ "m25p16-nonjedec",  INFO_NOID( 64 * 1024,  32, 256, 0, 0) },
> +	{ "m25p32-nonjedec",  INFO_NOID( 64 * 1024,  64, 256, 0, 0) },
> +	{ "m25p64-nonjedec",  INFO_NOID( 64 * 1024, 128, 256, 0, 0) },
> +	{ "m25p128-nonjedec", INFO_NOID(256 * 1024,  64, 256, 0, 0) },
> +
> +	{ "m45pe10", INFO(0x204011, 0, 0, 64 * 1024,    2, 0) },
> +	{ "m45pe80", INFO(0x204014, 0, 0, 64 * 1024,   16, 0) },
> +	{ "m45pe16", INFO(0x204015, 0, 0, 64 * 1024,   32, 0) },
> +
> +	{ "m25pe20", INFO(0x208012, 0, 0, 64 * 1024,  4,       0) },
> +	{ "m25pe80", INFO(0x208014, 0, 0, 64 * 1024, 16,       0) },
> +	{ "m25pe16", INFO(0x208015, 0, 0, 64 * 1024, 32, SECT_4K) },
> +
> +	{ "m25px16",    INFO(0x207115, 0, 0, 64 * 1024, 32, SECT_4K) },
> +	{ "m25px32",    INFO(0x207116, 0, 0, 64 * 1024, 64, SECT_4K) },
> +	{ "m25px32-s0", INFO(0x207316, 0, 0, 64 * 1024, 64, SECT_4K) },
> +	{ "m25px32-s1", INFO(0x206316, 0, 0, 64 * 1024, 64, SECT_4K) },
> +	{ "m25px64",    INFO(0x207117, 0, 0, 64 * 1024, 128, 0) },
> +	{ "m25px80",    INFO(0x207114, 0, 0, 64 * 1024, 16, 0) },
>  
>  	/* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
> -	{ "w25x05", INFO(0xef3010, 0, 64 * 1024,  1,  SECT_4K) },
> -	{ "w25x10", INFO(0xef3011, 0, 64 * 1024,  2,  SECT_4K) },
> -	{ "w25x20", INFO(0xef3012, 0, 64 * 1024,  4,  SECT_4K) },
> -	{ "w25x40", INFO(0xef3013, 0, 64 * 1024,  8,  SECT_4K) },
> -	{ "w25x80", INFO(0xef3014, 0, 64 * 1024,  16, SECT_4K) },
> -	{ "w25x16", INFO(0xef3015, 0, 64 * 1024,  32, SECT_4K) },
> -	{ "w25x32", INFO(0xef3016, 0, 64 * 1024,  64, SECT_4K) },
> -	{ "w25q32", INFO(0xef4016, 0, 64 * 1024,  64, SECT_4K) },
> +	{ "w25x05", INFO(0xef3010, 0, 0, 64 * 1024,  1,  SECT_4K) },
> +	{ "w25x10", INFO(0xef3011, 0, 0, 64 * 1024,  2,  SECT_4K) },
> +	{ "w25x20", INFO(0xef3012, 0, 0, 64 * 1024,  4,  SECT_4K) },
> +	{ "w25x40", INFO(0xef3013, 0, 0, 64 * 1024,  8,  SECT_4K) },
> +	{ "w25x80", INFO(0xef3014, 0, 0, 64 * 1024,  16, SECT_4K) },
> +	{ "w25x16", INFO(0xef3015, 0, 0, 64 * 1024,  32, SECT_4K) },
> +	{ "w25x32", INFO(0xef3016, 0, 0, 64 * 1024,  64, SECT_4K) },
> +	{ "w25q32", INFO(0xef4016, 0, 0, 64 * 1024,  64, SECT_4K) },
>  	{
> -		"w25q32dw", INFO(0xef6016, 0, 64 * 1024,  64,
> +		"w25q32dw", INFO(0xef6016, 0, 0, 64 * 1024,  64,
>  			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>  			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
>  	},
> -	{ "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
> -	{ "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
> +	{ "w25x64", INFO(0xef3017, 0, 0, 64 * 1024, 128, SECT_4K) },
> +	{ "w25q64", INFO(0xef4017, 0, 0, 64 * 1024, 128, SECT_4K) },
>  	{
> -		"w25q64dw", INFO(0xef6017, 0, 64 * 1024, 128,
> +		"w25q64dw", INFO(0xef6017, 0, 0, 64 * 1024, 128,
>  			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>  			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
>  	},
>  	{
> -		"w25q128fw", INFO(0xef6018, 0, 64 * 1024, 256,
> +		"w25q128fw", INFO(0xef6018, 0, 0, 64 * 1024, 256,
>  			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>  			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
>  	},
> -	{ "w25q80", INFO(0xef5014, 0, 64 * 1024,  16, SECT_4K) },
> -	{ "w25q80bl", INFO(0xef4014, 0, 64 * 1024,  16, SECT_4K) },
> -	{ "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
> -	{ "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K) },
> +	{ "w25q80",   INFO(0xef5014, 0, 0, 64 * 1024,  16, SECT_4K) },
> +	{ "w25q80bl", INFO(0xef4014, 0, 0, 64 * 1024,  16, SECT_4K) },
> +	{ "w25q128",  INFO(0xef4018, 0, 0, 64 * 1024, 256, SECT_4K) },
> +	{ "w25q256",  INFO(0xef4019, 0, 0, 64 * 1024, 512, SECT_4K) },
>  
>  	/* Catalyst / On Semiconductor -- non-JEDEC */
> -	{ "cat25c11", CAT25_INFO(  16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
> -	{ "cat25c03", CAT25_INFO(  32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
> -	{ "cat25c09", CAT25_INFO( 128, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
> -	{ "cat25c17", CAT25_INFO( 256, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
> -	{ "cat25128", CAT25_INFO(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
> +	{ "cat25c11", INFO_NOID(  16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
> +	{ "cat25c03", INFO_NOID(  32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
> +	{ "cat25c09", INFO_NOID( 128, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
> +	{ "cat25c17", INFO_NOID( 256, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
> +	{ "cat25128", INFO_NOID(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
>  
>  	/* Xilinx S3AN Internal Flash */
> -	{ "3S50AN", S3AN_INFO(0x1f2200, 64, 264) },
> -	{ "3S200AN", S3AN_INFO(0x1f2400, 256, 264) },
> -	{ "3S400AN", S3AN_INFO(0x1f2400, 256, 264) },
> -	{ "3S700AN", S3AN_INFO(0x1f2500, 512, 264) },
> -	{ "3S1400AN", S3AN_INFO(0x1f2600, 512, 528) },
> +	{ "3S50AN",   INFO_S3AN(0x1f2200, 64, 264) },
> +	{ "3S200AN",  INFO_S3AN(0x1f2400, 256, 264) },
> +	{ "3S400AN",  INFO_S3AN(0x1f2400, 256, 264) },
> +	{ "3S700AN",  INFO_S3AN(0x1f2500, 512, 264) },
> +	{ "3S1400AN", INFO_S3AN(0x1f2600, 512, 528) },
>  	{ },
>  };
>  
>  static const struct flash_info *spi_nor_read_id(struct spi_nor *nor)
>  {
>  	int			tmp;
> -	u8			id[SPI_NOR_MAX_ID_LEN];
> +	u8			id_bytes[sizeof(u64)];
> +	u64			id;
>  	const struct flash_info	*info;
>  
> -	tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
> +	BUILD_BUG_ON(SPI_NOR_MAX_ID_LEN > sizeof(u64));
> +
> +	memset(id_bytes, 0, sizeof(id_bytes));
> +	tmp = nor->read_reg(nor, SPINOR_OP_RDID, id_bytes, SPI_NOR_MAX_ID_LEN);
>  	if (tmp < 0) {
>  		dev_dbg(nor->dev, "error %d reading JEDEC ID\n", tmp);
>  		return ERR_PTR(tmp);
>  	}
>  
> +	id = get_unaligned_be64(id_bytes);
> +
>  	for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) {
>  		info = &spi_nor_ids[tmp];
> -		if (info->id_len) {
> -			if (!memcmp(info->id, id, info->id_len))
> -				return &spi_nor_ids[tmp];
> -		}
> +		if (info->id_mask && (id & info->id_mask) == info->id)
> +			return info;
>  	}
> -	dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %02x, %02x\n",
> -		id[0], id[1], id[2]);
> +	dev_err(nor->dev, "unrecognized JEDEC id bytes: %*ph\n",
> +		SPI_NOR_MAX_ID_LEN, id_bytes);
>  	return ERR_PTR(-ENODEV);
>  }
>  
> @@ -1551,7 +1555,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
>  	 * If caller has specified name of flash model that can normally be
>  	 * detected using JEDEC, let's verify it.
>  	 */
> -	if (name && info->id_len) {
> +	if (name && info->id_mask) {
>  		const struct flash_info *jinfo;
>  
>  		jinfo = spi_nor_read_id(nor);
> 


-- 
Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] mtd: spi-nor: flash_info table, use a u64 for the ID
  2017-02-14  5:02         ` Marek Vasut
@ 2017-02-14 10:22           ` Cyrille Pitchen
  2017-02-14 15:35             ` [PATCH v2 0/3] " mark.marshall
  0 siblings, 1 reply; 12+ messages in thread
From: Cyrille Pitchen @ 2017-02-14 10:22 UTC (permalink / raw)
  To: Marek Vasut, mark.marshall, computersforpeace, linux-mtd
  Cc: markmarshall14, dwmw2, richard, boris.brezillon

Hi all,

Le 14/02/2017 à 06:02, Marek Vasut a écrit :
> On 02/13/2017 02:53 PM, mark.marshall@omicronenergy.com wrote:
>> From: Mark Marshall <mark.marshall@omicronenergy.com>
>>
>> The flash_info ID matching table is getting more complex as different
>> chips are added.  Some chips require different amounts of the response
>> to the RDID command to be matched.  Replace the current u8 array and
>> length with a u64 id and a u64 id_mask.  This allows us to simplify the
>> macros used to generate the flash_info table without loosing the ability
>> to generate "unusual" entries.
>>
>> --
>>
>> This patch replaces "m25p80: Use a 512 byte page size for Spansion
>> flash s25fl512s".  It is based on for-linus-20170212, from the
>> linux-mtd tree.
>>

This part should not appear in the commit message hence has to be moved
after the "---" line (after your Signed-off-by tag).

>>
>> Signed-off-by: Mark Marshall <mark.marshall@omicronenergy.com>
> 
> Minor nits below, looks good IMO. I'd still like someone else to review
> this whole idea though. Cyrille ?
> 
>> ---
>>  drivers/mtd/spi-nor/spi-nor.c | 458 +++++++++++++++++++++---------------------
>>  1 file changed, 231 insertions(+), 227 deletions(-)
>>
>> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
>> index 1ae872b..c7ff237 100644
>> --- a/drivers/mtd/spi-nor/spi-nor.c
>> +++ b/drivers/mtd/spi-nor/spi-nor.c
>> @@ -41,15 +41,20 @@
>>  #define SPI_NOR_MAX_ADDR_WIDTH	4
>>  
>>  struct flash_info {
>> -	char		*name;
>> +	const char	*name;
>>  
>>  	/*
>> -	 * This array stores the ID bytes.
>> -	 * The first three bytes are the JEDIC ID.
>> -	 * JEDEC ID zero means "no ID" (mostly older chips).
>> +	 * This u64 stores the ID bytes.
>> +	 * The bytes are stored in big-endian order.

I don't agree with this comment: looking at the code, id stores a number
in the CPU order byte, not necessarily in big-endian.

Below in the patch we can find:
#define JEDEC_MFR(info)	((u8)((info)->id >> 56) & 0xff)

So you use the CPU order byte. Also that's why you call
get_unaligned_be64(): to convert the big-endian number read from the SPI
bus into a cpu-ordered u64.

Or maybe I didn't understand what you meant in your comment.

>> +	 * The upper three bytes are the JEDIC ID, the lower bytes are
>> +	 * the extension.
>>  	 */
>> -	u8		id[SPI_NOR_MAX_ID_LEN];
>> -	u8		id_len;
>> +	u64		id;
>> +
>> +	/*
>> +	 * An id_mask of zero means "no ID" (mostly older chips).
>> +	 */
>> +	u64		id_mask;
>>  
>>  	/* The size listed here is what works with SPINOR_OP_SE, which isn't
>>  	 * necessarily called a "sector" by the vendor.
>> @@ -87,7 +92,7 @@ struct flash_info {
>>  					 */
>>  };
>>  
>> -#define JEDEC_MFR(info)	((info)->id[0])
>> +#define JEDEC_MFR(info)	((u8)((info)->id >> 56) & 0xff)
>>  
>>  static const struct flash_info *spi_nor_match_id(const char *name);
>>  
>> @@ -870,55 +875,49 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
>>  	return ret;
>>  }
>>  
>> -/* Used when the "_ext_id" is two bytes at most */
>> -#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
>> -		.id = {							\
>> -			((_jedec_id) >> 16) & 0xff,			\
>> -			((_jedec_id) >> 8) & 0xff,			\
>> -			(_jedec_id) & 0xff,				\
>> -			((_ext_id) >> 8) & 0xff,			\
>> -			(_ext_id) & 0xff,				\
>> -			},						\
>> -		.id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))),	\
>> -		.sector_size = (_sector_size),				\
>> -		.n_sectors = (_n_sectors),				\
>> -		.page_size = 256,					\
>> -		.flags = (_flags),
>> -
>> -#define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
>> -		.id = {							\
>> -			((_jedec_id) >> 16) & 0xff,			\
>> -			((_jedec_id) >> 8) & 0xff,			\
>> -			(_jedec_id) & 0xff,				\
>> -			((_ext_id) >> 16) & 0xff,			\
>> -			((_ext_id) >> 8) & 0xff,			\
>> -			(_ext_id) & 0xff,				\
>> -			},						\
>> -		.id_len = 6,						\
>> -		.sector_size = (_sector_size),				\
>> -		.n_sectors = (_n_sectors),				\
>> -		.page_size = 256,					\
>> -		.flags = (_flags),
>> -
>> -#define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width, _flags)	\
>> -		.sector_size = (_sector_size),				\
>> -		.n_sectors = (_n_sectors),				\
>> -		.page_size = (_page_size),				\
>> -		.addr_width = (_addr_width),				\
>> -		.flags = (_flags),
>> -
>> -#define S3AN_INFO(_jedec_id, _n_sectors, _page_size)			\
>> -		.id = {							\
>> -			((_jedec_id) >> 16) & 0xff,			\
>> -			((_jedec_id) >> 8) & 0xff,			\
>> -			(_jedec_id) & 0xff				\
>> -			},						\
>> -		.id_len = 3,						\
>> -		.sector_size = (8*_page_size),				\
>> -		.n_sectors = (_n_sectors),				\
>> -		.page_size = _page_size,				\
>> -		.addr_width = 3,					\
>> -		.flags = SPI_NOR_NO_FR | SPI_S3AN,
>> +/* Used to provide the full information about a device.
>> + */
> 
> Fix the comment format here , single line comment is enough
> ( /* comment */ )
> 
>> +#define INFO_FULL(_id, _id_mask, _sector_size, _n_sectors, _pg_sz, _addr_width, _flags)	\
>> +	.id = (_id),							\
>> +	.id_mask = (_id_mask),						\
>> +	.sector_size = (_sector_size),					\
>> +	.n_sectors = (_n_sectors),					\
>> +	.page_size = (_pg_sz),						\
>> +	.addr_width = (_addr_width),					\
>> +	.flags = (_flags),
>> +
>> +/* Used to provide information for a standard JEDEC device.  All
>> + * devices created with this macro have a three octet JEDEC identifier
>> + * and an optional extension identifier (normally 0, 2 or 3 octets
>> + * long).
>> + */
> 
> Multi-line comment looks like this:
> 
> /*
>  * foo
>  * bar
>  */
> 
>> +#define INFO(_jedec_id, _ext_id, _ext_len, _sector_size, _n_sectors, _flags) \
>> +	INFO_FULL(((u64)(_jedec_id) << (64 - (8 * 3))) |		\
>> +		  ((u64)(_ext_id) << (64 - (8 * (3 + _ext_len)))),	\

Could it be possible, in the first time at least, to keep the very same
prototype for the INFO() macro as before but still defining it using
your new INFO_FULL() macro?

#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)

so as if _ext_len is always 3. For different _ext_len values, new
entries can directly use your INFO_FULL() macro.

Also keep CAT25_INFO() for now and simply make it an alias for INFO_NOID().

I would like this patch not to modify any entry of the spi_nor_ids[]
array for now. So if some issue is reported, it would be more easy to
revert and also it would avoid, or at least reduce, conflict with other
patches adding support to new memories.

> 
> Is the u64 cast needed ? I don't think so.
>

Indeed, I'm pretty sure the u64 is needed. For instance long time ago on
x86_64 I wrote something like that (userspace code):

uint64_t v;

v = 1 << 32;

but it didn't provide the right result. So yesterday I tried to have a
look at why it failed and whether things like (info)->id >> 56 would
work on all architectures.

To be confirmed but I found out that for a (var1 << var2) operation, it
seems that the result as the same type as var1. Hence is var1 is a
signed integer like 1 and var2 is greater than 31 the actual result is
unpredictable since the expected result can't be represented with a
signed int. That why I should have written something like:

uint64_t v;

v = 1ull << 32;

That why I think that the u64 cast is actually needed since the INFO()
macro is used with values such as 0x1f6601, which is a signed int too.


>> +		  GENMASK_ULL(63, 64 - (8 * (3 + _ext_len))),		\
> 
> You need parenthesis around _ext_len
> 
>> +		  (_sector_size),					\
>> +		  (_n_sectors),						\
>> +		  256,							\
>> +		  0,							\
>> +		  (_flags))
>> +
>> +#define INFO_NOID(_sector_size, _n_sectors, _page_size, _addr_width, _flags)	\
>> +	INFO_FULL(0,							\
>> +		  0,							\
>> +		  (_sector_size),					\
>> +		  (_n_sectors),						\
>> +		  (_page_size),						\
>> +		  (_addr_width),					\
>> +		  (_flags))
>> +
>> +#define INFO_S3AN(_jedec_id, _n_sectors, _page_size)			\
>> +	INFO_FULL(((u64)(_jedec_id) << (64 - (8 * 3))),			\
>> +		  GENMASK_ULL(63, 64 - (8 * 3)),			\
>> +		  (8*_page_size),					\
>> +		  (_n_sectors),						\
>> +		  (_page_size),						\
>> +		  3,							\
>> +		  SPI_NOR_NO_FR | SPI_S3AN)
>>  
>>  /* NOTE: double check command sets and memory organization when you add
>>   * more nor chips.  This current list focusses on newer chips, which
>> @@ -933,261 +932,266 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
>>   */
>>  static const struct flash_info spi_nor_ids[] = {
>>  	/* Atmel -- some are (confusingly) marketed as "DataFlash" */
>> -	{ "at25fs010",  INFO(0x1f6601, 0, 32 * 1024,   4, SECT_4K) },
>> -	{ "at25fs040",  INFO(0x1f6604, 0, 64 * 1024,   8, SECT_4K) },
>> +	{ "at25fs010",  INFO(0x1f6601, 0, 0, 32 * 1024,   4, SECT_4K) },
>> +	{ "at25fs040",  INFO(0x1f6604, 0, 0, 64 * 1024,   8, SECT_4K) },
>>  
>> -	{ "at25df041a", INFO(0x1f4401, 0, 64 * 1024,   8, SECT_4K) },
>> -	{ "at25df321",  INFO(0x1f4700, 0, 64 * 1024,  64, SECT_4K) },
>> -	{ "at25df321a", INFO(0x1f4701, 0, 64 * 1024,  64, SECT_4K) },
>> -	{ "at25df641",  INFO(0x1f4800, 0, 64 * 1024, 128, SECT_4K) },
>> +	{ "at25df041a", INFO(0x1f4401, 0, 0, 64 * 1024,   8, SECT_4K) },
>> +	{ "at25df321",  INFO(0x1f4700, 0, 0, 64 * 1024,  64, SECT_4K) },
>> +	{ "at25df321a", INFO(0x1f4701, 0, 0, 64 * 1024,  64, SECT_4K) },
>> +	{ "at25df641",  INFO(0x1f4800, 0, 0, 64 * 1024, 128, SECT_4K) },
>>  
>> -	{ "at26f004",   INFO(0x1f0400, 0, 64 * 1024,  8, SECT_4K) },
>> -	{ "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16, SECT_4K) },
>> -	{ "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) },
>> -	{ "at26df321",  INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) },
>> +	{ "at26f004",   INFO(0x1f0400, 0, 0, 64 * 1024,  8, SECT_4K) },
>> +	{ "at26df081a", INFO(0x1f4501, 0, 0, 64 * 1024, 16, SECT_4K) },
>> +	{ "at26df161a", INFO(0x1f4601, 0, 0, 64 * 1024, 32, SECT_4K) },
>> +	{ "at26df321",  INFO(0x1f4700, 0, 0, 64 * 1024, 64, SECT_4K) },
>>  
>> -	{ "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) },
>> +	{ "at45db081d", INFO(0x1f2500, 0, 0, 64 * 1024, 16, SECT_4K) },
>>  
>>  	/* EON -- en25xxx */
>> -	{ "en25f32",    INFO(0x1c3116, 0, 64 * 1024,   64, SECT_4K) },
>> -	{ "en25p32",    INFO(0x1c2016, 0, 64 * 1024,   64, 0) },
>> -	{ "en25q32b",   INFO(0x1c3016, 0, 64 * 1024,   64, 0) },
>> -	{ "en25p64",    INFO(0x1c2017, 0, 64 * 1024,  128, 0) },
>> -	{ "en25q64",    INFO(0x1c3017, 0, 64 * 1024,  128, SECT_4K) },
>> -	{ "en25qh128",  INFO(0x1c7018, 0, 64 * 1024,  256, 0) },
>> -	{ "en25qh256",  INFO(0x1c7019, 0, 64 * 1024,  512, 0) },
>> -	{ "en25s64",	INFO(0x1c3817, 0, 64 * 1024,  128, SECT_4K) },
>> +	{ "en25f32",    INFO(0x1c3116, 0, 0, 64 * 1024,   64, SECT_4K) },
>> +	{ "en25p32",    INFO(0x1c2016, 0, 0, 64 * 1024,   64, 0) },
>> +	{ "en25q32b",   INFO(0x1c3016, 0, 0, 64 * 1024,   64, 0) },
>> +	{ "en25p64",    INFO(0x1c2017, 0, 0, 64 * 1024,  128, 0) },
>> +	{ "en25q64",    INFO(0x1c3017, 0, 0, 64 * 1024,  128, SECT_4K) },
>> +	{ "en25qh128",  INFO(0x1c7018, 0, 0, 64 * 1024,  256, 0) },
>> +	{ "en25qh256",  INFO(0x1c7019, 0, 0, 64 * 1024,  512, 0) },
>> +	{ "en25s64",	INFO(0x1c3817, 0, 0, 64 * 1024,  128, SECT_4K) },
>>  
>>  	/* ESMT */
>> -	{ "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) },
>> +	{ "f25l32pa", INFO(0x8c2016, 0, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) },
>>  
>>  	/* Everspin */
>> -	{ "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
>> -	{ "mr25h10",  CAT25_INFO(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
>> -	{ "mr25h40",  CAT25_INFO(512 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
>> +	{ "mr25h256", INFO_NOID( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
>> +	{ "mr25h10",  INFO_NOID(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
>> +	{ "mr25h40",  INFO_NOID(512 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
>>  
>>  	/* Fujitsu */
>> -	{ "mb85rs1mt", INFO(0x047f27, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) },
>> +	{ "mb85rs1mt", INFO(0x047f27, 0, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) },
>>  
>>  	/* GigaDevice */
>>  	{
>> -		"gd25q16", INFO(0xc84015, 0, 64 * 1024,  32,
>> +		"gd25q16", INFO(0xc84015, 0, 0, 64 * 1024,  32,
>>  			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>>  			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
>>  	},
>>  	{
>> -		"gd25q32", INFO(0xc84016, 0, 64 * 1024,  64,
>> +		"gd25q32", INFO(0xc84016, 0, 0, 64 * 1024,  64,
>>  			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>>  			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
>>  	},
>>  	{
>> -		"gd25q64", INFO(0xc84017, 0, 64 * 1024, 128,
>> +		"gd25q64", INFO(0xc84017, 0, 0, 64 * 1024, 128,
>>  			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>>  			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
>>  	},
>>  	{
>> -		"gd25lq64c", INFO(0xc86017, 0, 64 * 1024, 128,
>> +		"gd25lq64c", INFO(0xc86017, 0, 0, 64 * 1024, 128,
>>  			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>>  			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
>>  	},
>>  	{
>> -		"gd25q128", INFO(0xc84018, 0, 64 * 1024, 256,
>> +		"gd25q128", INFO(0xc84018, 0, 0, 64 * 1024, 256,
>>  			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>>  			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
>>  	},
>>  
>>  	/* Intel/Numonyx -- xxxs33b */
>> -	{ "160s33b",  INFO(0x898911, 0, 64 * 1024,  32, 0) },
>> -	{ "320s33b",  INFO(0x898912, 0, 64 * 1024,  64, 0) },
>> -	{ "640s33b",  INFO(0x898913, 0, 64 * 1024, 128, 0) },
>> +	{ "160s33b",  INFO(0x898911, 0, 0, 64 * 1024,  32, 0) },
>> +	{ "320s33b",  INFO(0x898912, 0, 0, 64 * 1024,  64, 0) },
>> +	{ "640s33b",  INFO(0x898913, 0, 0, 64 * 1024, 128, 0) },
>>  
>>  	/* ISSI */
>> -	{ "is25cd512", INFO(0x7f9d20, 0, 32 * 1024,   2, SECT_4K) },
>> +	{ "is25cd512", INFO(0x7f9d20, 0, 0, 32 * 1024,   2, SECT_4K) },
>>  
>>  	/* Macronix */
>> -	{ "mx25l512e",   INFO(0xc22010, 0, 64 * 1024,   1, SECT_4K) },
>> -	{ "mx25l2005a",  INFO(0xc22012, 0, 64 * 1024,   4, SECT_4K) },
>> -	{ "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) },
>> -	{ "mx25l3255e",  INFO(0xc29e16, 0, 64 * 1024,  64, SECT_4K) },
>> -	{ "mx25l6405d",  INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) },
>> -	{ "mx25u6435f",  INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) },
>> -	{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
>> -	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
>> -	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
>> -	{ "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K) },
>> -	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
>> -	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) },
>> -	{ "mx66l1g55g",  INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) },
>> +	{ "mx25l512e",   INFO(0xc22010, 0, 0, 64 * 1024,   1, SECT_4K) },
>> +	{ "mx25l2005a",  INFO(0xc22012, 0, 0, 64 * 1024,   4, SECT_4K) },
>> +	{ "mx25l4005a",  INFO(0xc22013, 0, 0, 64 * 1024,   8, SECT_4K) },
>> +	{ "mx25l8005",   INFO(0xc22014, 0, 0, 64 * 1024,  16, 0) },
>> +	{ "mx25l1606e",  INFO(0xc22015, 0, 0, 64 * 1024,  32, SECT_4K) },
>> +	{ "mx25l3205d",  INFO(0xc22016, 0, 0, 64 * 1024,  64, SECT_4K) },
>> +	{ "mx25l3255e",  INFO(0xc29e16, 0, 0, 64 * 1024,  64, SECT_4K) },
>> +	{ "mx25l6405d",  INFO(0xc22017, 0, 0, 64 * 1024, 128, SECT_4K) },
>> +	{ "mx25u6435f",  INFO(0xc22537, 0, 0, 64 * 1024, 128, SECT_4K) },
>> +	{ "mx25l12805d", INFO(0xc22018, 0, 0, 64 * 1024, 256, 0) },
>> +	{ "mx25l12855e", INFO(0xc22618, 0, 0, 64 * 1024, 256, 0) },
>> +	{ "mx25l25635e", INFO(0xc22019, 0, 0, 64 * 1024, 512, 0) },
>> +	{ "mx25u25635f", INFO(0xc22539, 0, 0, 64 * 1024, 512, SECT_4K) },
>> +	{ "mx25l25655e", INFO(0xc22619, 0, 0, 64 * 1024, 512, 0) },
>> +	{ "mx66l51235l", INFO(0xc2201a, 0, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) },
>> +	{ "mx66l1g55g",  INFO(0xc2261b, 0, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) },
>>  
>>  	/* Micron */
>> -	{ "n25q016a",	 INFO(0x20bb15, 0, 64 * 1024,   32, SECT_4K | SPI_NOR_QUAD_READ) },
>> -	{ "n25q032",	 INFO(0x20ba16, 0, 64 * 1024,   64, SPI_NOR_QUAD_READ) },
>> -	{ "n25q032a",	 INFO(0x20bb16, 0, 64 * 1024,   64, SPI_NOR_QUAD_READ) },
>> -	{ "n25q064",     INFO(0x20ba17, 0, 64 * 1024,  128, SECT_4K | SPI_NOR_QUAD_READ) },
>> -	{ "n25q064a",    INFO(0x20bb17, 0, 64 * 1024,  128, SECT_4K | SPI_NOR_QUAD_READ) },
>> -	{ "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024,  256, SECT_4K | SPI_NOR_QUAD_READ) },
>> -	{ "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024,  256, SECT_4K | SPI_NOR_QUAD_READ) },
>> -	{ "n25q256a",    INFO(0x20ba19, 0, 64 * 1024,  512, SECT_4K | SPI_NOR_QUAD_READ) },
>> -	{ "n25q512a",    INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
>> -	{ "n25q512ax3",  INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
>> -	{ "n25q00",      INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
>> -	{ "n25q00a",     INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
>> +	{ "n25q016a",	 INFO(0x20bb15, 0, 0, 64 * 1024,   32, SECT_4K | SPI_NOR_QUAD_READ) },
>> +	{ "n25q032",	 INFO(0x20ba16, 0, 0, 64 * 1024,   64, SPI_NOR_QUAD_READ) },
>> +	{ "n25q032a",	 INFO(0x20bb16, 0, 0, 64 * 1024,   64, SPI_NOR_QUAD_READ) },
>> +	{ "n25q064",     INFO(0x20ba17, 0, 0, 64 * 1024,  128, SECT_4K | SPI_NOR_QUAD_READ) },
>> +	{ "n25q064a",    INFO(0x20bb17, 0, 0, 64 * 1024,  128, SECT_4K | SPI_NOR_QUAD_READ) },
>> +	{ "n25q128a11",  INFO(0x20bb18, 0, 0, 64 * 1024,  256, SECT_4K | SPI_NOR_QUAD_READ) },
>> +	{ "n25q128a13",  INFO(0x20ba18, 0, 0, 64 * 1024,  256, SECT_4K | SPI_NOR_QUAD_READ) },
>> +	{ "n25q256a",    INFO(0x20ba19, 0, 0, 64 * 1024,  512, SECT_4K | SPI_NOR_QUAD_READ) },
>> +	{ "n25q512a",    INFO(0x20bb20, 0, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
>> +	{ "n25q512ax3",  INFO(0x20ba20, 0, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
>> +	{ "n25q00",      INFO(0x20ba21, 0, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
>> +	{ "n25q00a",     INFO(0x20bb21, 0, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
>>  
>>  	/* PMC */
>> -	{ "pm25lv512",   INFO(0,        0, 32 * 1024,    2, SECT_4K_PMC) },
>> -	{ "pm25lv010",   INFO(0,        0, 32 * 1024,    4, SECT_4K_PMC) },
>> -	{ "pm25lq032",   INFO(0x7f9d46, 0, 64 * 1024,   64, SECT_4K) },
>> +	{ "pm25lv512",   INFO_NOID(32 * 1024,    2, 256, 0, SECT_4K_PMC) },
>> +	{ "pm25lv010",   INFO_NOID(32 * 1024,    4, 256, 0, SECT_4K_PMC) },
>> +	{ "pm25lq032",   INFO(0x7f9d46, 0, 0, 64 * 1024,   64, SECT_4K) },
>>  
>>  	/* Spansion -- single (large) sector size only, at least
>>  	 * for the chips listed here (without boot sectors).
>>  	 */
>> -	{ "s25sl032p",  INFO(0x010215, 0x4d00,  64 * 1024,  64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>> -	{ "s25sl064p",  INFO(0x010216, 0x4d00,  64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>> -	{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
>> -	{ "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>> -	{ "s25fl512s",  INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>> -	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
>> -	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
>> -	{ "s25sl12801", INFO(0x012018, 0x0301,  64 * 1024, 256, 0) },
>> -	{ "s25fl128s",	INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>> -	{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024,  64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>> -	{ "s25fl129p1", INFO(0x012018, 0x4d01,  64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>> -	{ "s25sl004a",  INFO(0x010212,      0,  64 * 1024,   8, 0) },
>> -	{ "s25sl008a",  INFO(0x010213,      0,  64 * 1024,  16, 0) },
>> -	{ "s25sl016a",  INFO(0x010214,      0,  64 * 1024,  32, 0) },
>> -	{ "s25sl032a",  INFO(0x010215,      0,  64 * 1024,  64, 0) },
>> -	{ "s25sl064a",  INFO(0x010216,      0,  64 * 1024, 128, 0) },
>> -	{ "s25fl004k",  INFO(0xef4013,      0,  64 * 1024,   8, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>> -	{ "s25fl008k",  INFO(0xef4014,      0,  64 * 1024,  16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>> -	{ "s25fl016k",  INFO(0xef4015,      0,  64 * 1024,  32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>> -	{ "s25fl064k",  INFO(0xef4017,      0,  64 * 1024, 128, SECT_4K) },
>> -	{ "s25fl116k",  INFO(0x014015,      0,  64 * 1024,  32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>> -	{ "s25fl132k",  INFO(0x014016,      0,  64 * 1024,  64, SECT_4K) },
>> -	{ "s25fl164k",  INFO(0x014017,      0,  64 * 1024, 128, SECT_4K) },
>> -	{ "s25fl204k",  INFO(0x014013,      0,  64 * 1024,   8, SECT_4K | SPI_NOR_DUAL_READ) },
>> -	{ "s25fl208k",  INFO(0x014014,      0,  64 * 1024,  16, SECT_4K | SPI_NOR_DUAL_READ) },
>> +	{ "s25sl032p",  INFO(0x010215, 0x4d00, 2,  64 * 1024,  64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>> +	{ "s25sl064p",  INFO(0x010216, 0x4d00, 2,  64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>> +	{ "s25fl256s0", INFO(0x010219, 0x4d00, 2, 256 * 1024, 128, 0) },
>> +	{ "s25fl256s1", INFO(0x010219, 0x4d01, 2,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>> +	{ "s25fl512s",  INFO_FULL(0x0102204d00uLL << 24, GENMASK_ULL(63, 24),
>> +				  256 * 1024, 256, 512, 0, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> 
> Hm, this syntax here could use some improvement ... ideas welcome.
> 
>> +	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 2, 256 * 1024, 256, 0) },
>> +	{ "s25sl12800", INFO(0x012018, 0x0300, 2, 256 * 1024,  64, 0) },
>> +	{ "s25sl12801", INFO(0x012018, 0x0301, 2,  64 * 1024, 256, 0) },
>> +	{ "s25fl128s",	INFO(0x012018, 0x4d0180, 3, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>> +	{ "s25fl129p0", INFO(0x012018, 0x4d00, 2, 256 * 1024,  64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>> +	{ "s25fl129p1", INFO(0x012018, 0x4d01, 2,  64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>> +	{ "s25sl004a",  INFO(0x010212, 0, 0,  64 * 1024,   8, 0) },
>> +	{ "s25sl008a",  INFO(0x010213, 0, 0,  64 * 1024,  16, 0) },
>> +	{ "s25sl016a",  INFO(0x010214, 0, 0,  64 * 1024,  32, 0) },
>> +	{ "s25sl032a",  INFO(0x010215, 0, 0,  64 * 1024,  64, 0) },
>> +	{ "s25sl064a",  INFO(0x010216, 0, 0,  64 * 1024, 128, 0) },
>> +	{ "s25fl004k",  INFO(0xef4013, 0, 0,  64 * 1024,   8, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>> +	{ "s25fl008k",  INFO(0xef4014, 0, 0,  64 * 1024,  16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>> +	{ "s25fl016k",  INFO(0xef4015, 0, 0,  64 * 1024,  32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>> +	{ "s25fl064k",  INFO(0xef4017, 0, 0,  64 * 1024, 128, SECT_4K) },
>> +	{ "s25fl116k",  INFO(0x014015, 0, 0,  64 * 1024,  32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>> +	{ "s25fl132k",  INFO(0x014016, 0, 0,  64 * 1024,  64, SECT_4K) },
>> +	{ "s25fl164k",  INFO(0x014017, 0, 0,  64 * 1024, 128, SECT_4K) },
>> +	{ "s25fl204k",  INFO(0x014013, 0, 0,  64 * 1024,   8, SECT_4K | SPI_NOR_DUAL_READ) },
>> +	{ "s25fl208k",  INFO(0x014014, 0, 0,  64 * 1024,  16, SECT_4K | SPI_NOR_DUAL_READ) },
>>  
>>  	/* SST -- large erase sizes are "overlays", "sectors" are 4K */
>> -	{ "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) },
>> -	{ "sst25vf080b", INFO(0xbf258e, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },
>> -	{ "sst25vf016b", INFO(0xbf2541, 0, 64 * 1024, 32, SECT_4K | SST_WRITE) },
>> -	{ "sst25vf032b", INFO(0xbf254a, 0, 64 * 1024, 64, SECT_4K | SST_WRITE) },
>> -	{ "sst25vf064c", INFO(0xbf254b, 0, 64 * 1024, 128, SECT_4K) },
>> -	{ "sst25wf512",  INFO(0xbf2501, 0, 64 * 1024,  1, SECT_4K | SST_WRITE) },
>> -	{ "sst25wf010",  INFO(0xbf2502, 0, 64 * 1024,  2, SECT_4K | SST_WRITE) },
>> -	{ "sst25wf020",  INFO(0xbf2503, 0, 64 * 1024,  4, SECT_4K | SST_WRITE) },
>> -	{ "sst25wf020a", INFO(0x621612, 0, 64 * 1024,  4, SECT_4K) },
>> -	{ "sst25wf040b", INFO(0x621613, 0, 64 * 1024,  8, SECT_4K) },
>> -	{ "sst25wf040",  INFO(0xbf2504, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) },
>> -	{ "sst25wf080",  INFO(0xbf2505, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },
>> +	{ "sst25vf040b", INFO(0xbf258d, 0, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) },
>> +	{ "sst25vf080b", INFO(0xbf258e, 0, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },
>> +	{ "sst25vf016b", INFO(0xbf2541, 0, 0, 64 * 1024, 32, SECT_4K | SST_WRITE) },
>> +	{ "sst25vf032b", INFO(0xbf254a, 0, 0, 64 * 1024, 64, SECT_4K | SST_WRITE) },
>> +	{ "sst25vf064c", INFO(0xbf254b, 0, 0, 64 * 1024, 128, SECT_4K) },
>> +	{ "sst25wf512",  INFO(0xbf2501, 0, 0, 64 * 1024,  1, SECT_4K | SST_WRITE) },
>> +	{ "sst25wf010",  INFO(0xbf2502, 0, 0, 64 * 1024,  2, SECT_4K | SST_WRITE) },
>> +	{ "sst25wf020",  INFO(0xbf2503, 0, 0, 64 * 1024,  4, SECT_4K | SST_WRITE) },
>> +	{ "sst25wf020a", INFO(0x621612, 0, 0, 64 * 1024,  4, SECT_4K) },
>> +	{ "sst25wf040b", INFO(0x621613, 0, 0, 64 * 1024,  8, SECT_4K) },
>> +	{ "sst25wf040",  INFO(0xbf2504, 0, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) },
>> +	{ "sst25wf080",  INFO(0xbf2505, 0, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },
>>  
>>  	/* ST Microelectronics -- newer production may have feature updates */
>> -	{ "m25p05",  INFO(0x202010,  0,  32 * 1024,   2, 0) },
>> -	{ "m25p10",  INFO(0x202011,  0,  32 * 1024,   4, 0) },
>> -	{ "m25p20",  INFO(0x202012,  0,  64 * 1024,   4, 0) },
>> -	{ "m25p40",  INFO(0x202013,  0,  64 * 1024,   8, 0) },
>> -	{ "m25p80",  INFO(0x202014,  0,  64 * 1024,  16, 0) },
>> -	{ "m25p16",  INFO(0x202015,  0,  64 * 1024,  32, 0) },
>> -	{ "m25p32",  INFO(0x202016,  0,  64 * 1024,  64, 0) },
>> -	{ "m25p64",  INFO(0x202017,  0,  64 * 1024, 128, 0) },
>> -	{ "m25p128", INFO(0x202018,  0, 256 * 1024,  64, 0) },
>> -
>> -	{ "m25p05-nonjedec",  INFO(0, 0,  32 * 1024,   2, 0) },
>> -	{ "m25p10-nonjedec",  INFO(0, 0,  32 * 1024,   4, 0) },
>> -	{ "m25p20-nonjedec",  INFO(0, 0,  64 * 1024,   4, 0) },
>> -	{ "m25p40-nonjedec",  INFO(0, 0,  64 * 1024,   8, 0) },
>> -	{ "m25p80-nonjedec",  INFO(0, 0,  64 * 1024,  16, 0) },
>> -	{ "m25p16-nonjedec",  INFO(0, 0,  64 * 1024,  32, 0) },
>> -	{ "m25p32-nonjedec",  INFO(0, 0,  64 * 1024,  64, 0) },
>> -	{ "m25p64-nonjedec",  INFO(0, 0,  64 * 1024, 128, 0) },
>> -	{ "m25p128-nonjedec", INFO(0, 0, 256 * 1024,  64, 0) },
>> -
>> -	{ "m45pe10", INFO(0x204011,  0, 64 * 1024,    2, 0) },
>> -	{ "m45pe80", INFO(0x204014,  0, 64 * 1024,   16, 0) },
>> -	{ "m45pe16", INFO(0x204015,  0, 64 * 1024,   32, 0) },
>> -
>> -	{ "m25pe20", INFO(0x208012,  0, 64 * 1024,  4,       0) },
>> -	{ "m25pe80", INFO(0x208014,  0, 64 * 1024, 16,       0) },
>> -	{ "m25pe16", INFO(0x208015,  0, 64 * 1024, 32, SECT_4K) },
>> -
>> -	{ "m25px16",    INFO(0x207115,  0, 64 * 1024, 32, SECT_4K) },
>> -	{ "m25px32",    INFO(0x207116,  0, 64 * 1024, 64, SECT_4K) },
>> -	{ "m25px32-s0", INFO(0x207316,  0, 64 * 1024, 64, SECT_4K) },
>> -	{ "m25px32-s1", INFO(0x206316,  0, 64 * 1024, 64, SECT_4K) },
>> -	{ "m25px64",    INFO(0x207117,  0, 64 * 1024, 128, 0) },
>> -	{ "m25px80",    INFO(0x207114,  0, 64 * 1024, 16, 0) },
>> +	{ "m25p05",  INFO(0x202010, 0, 0,  32 * 1024,   2, 0) },
>> +	{ "m25p10",  INFO(0x202011, 0, 0,  32 * 1024,   4, 0) },
>> +	{ "m25p20",  INFO(0x202012, 0, 0,  64 * 1024,   4, 0) },
>> +	{ "m25p40",  INFO(0x202013, 0, 0,  64 * 1024,   8, 0) },
>> +	{ "m25p80",  INFO(0x202014, 0, 0,  64 * 1024,  16, 0) },
>> +	{ "m25p16",  INFO(0x202015, 0, 0,  64 * 1024,  32, 0) },
>> +	{ "m25p32",  INFO(0x202016, 0, 0,  64 * 1024,  64, 0) },
>> +	{ "m25p64",  INFO(0x202017, 0, 0,  64 * 1024, 128, 0) },
>> +	{ "m25p128", INFO(0x202018, 0, 0, 256 * 1024,  64, 0) },
>> +
>> +	{ "m25p05-nonjedec",  INFO_NOID( 32 * 1024,   2, 256, 0, 0) },
>> +	{ "m25p10-nonjedec",  INFO_NOID( 32 * 1024,   4, 256, 0, 0) },
>> +	{ "m25p20-nonjedec",  INFO_NOID( 64 * 1024,   4, 256, 0, 0) },
>> +	{ "m25p40-nonjedec",  INFO_NOID( 64 * 1024,   8, 256, 0, 0) },
>> +	{ "m25p80-nonjedec",  INFO_NOID( 64 * 1024,  16, 256, 0, 0) },
>> +	{ "m25p16-nonjedec",  INFO_NOID( 64 * 1024,  32, 256, 0, 0) },
>> +	{ "m25p32-nonjedec",  INFO_NOID( 64 * 1024,  64, 256, 0, 0) },
>> +	{ "m25p64-nonjedec",  INFO_NOID( 64 * 1024, 128, 256, 0, 0) },
>> +	{ "m25p128-nonjedec", INFO_NOID(256 * 1024,  64, 256, 0, 0) },
>> +
>> +	{ "m45pe10", INFO(0x204011, 0, 0, 64 * 1024,    2, 0) },
>> +	{ "m45pe80", INFO(0x204014, 0, 0, 64 * 1024,   16, 0) },
>> +	{ "m45pe16", INFO(0x204015, 0, 0, 64 * 1024,   32, 0) },
>> +
>> +	{ "m25pe20", INFO(0x208012, 0, 0, 64 * 1024,  4,       0) },
>> +	{ "m25pe80", INFO(0x208014, 0, 0, 64 * 1024, 16,       0) },
>> +	{ "m25pe16", INFO(0x208015, 0, 0, 64 * 1024, 32, SECT_4K) },
>> +
>> +	{ "m25px16",    INFO(0x207115, 0, 0, 64 * 1024, 32, SECT_4K) },
>> +	{ "m25px32",    INFO(0x207116, 0, 0, 64 * 1024, 64, SECT_4K) },
>> +	{ "m25px32-s0", INFO(0x207316, 0, 0, 64 * 1024, 64, SECT_4K) },
>> +	{ "m25px32-s1", INFO(0x206316, 0, 0, 64 * 1024, 64, SECT_4K) },
>> +	{ "m25px64",    INFO(0x207117, 0, 0, 64 * 1024, 128, 0) },
>> +	{ "m25px80",    INFO(0x207114, 0, 0, 64 * 1024, 16, 0) },
>>  
>>  	/* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
>> -	{ "w25x05", INFO(0xef3010, 0, 64 * 1024,  1,  SECT_4K) },
>> -	{ "w25x10", INFO(0xef3011, 0, 64 * 1024,  2,  SECT_4K) },
>> -	{ "w25x20", INFO(0xef3012, 0, 64 * 1024,  4,  SECT_4K) },
>> -	{ "w25x40", INFO(0xef3013, 0, 64 * 1024,  8,  SECT_4K) },
>> -	{ "w25x80", INFO(0xef3014, 0, 64 * 1024,  16, SECT_4K) },
>> -	{ "w25x16", INFO(0xef3015, 0, 64 * 1024,  32, SECT_4K) },
>> -	{ "w25x32", INFO(0xef3016, 0, 64 * 1024,  64, SECT_4K) },
>> -	{ "w25q32", INFO(0xef4016, 0, 64 * 1024,  64, SECT_4K) },
>> +	{ "w25x05", INFO(0xef3010, 0, 0, 64 * 1024,  1,  SECT_4K) },
>> +	{ "w25x10", INFO(0xef3011, 0, 0, 64 * 1024,  2,  SECT_4K) },
>> +	{ "w25x20", INFO(0xef3012, 0, 0, 64 * 1024,  4,  SECT_4K) },
>> +	{ "w25x40", INFO(0xef3013, 0, 0, 64 * 1024,  8,  SECT_4K) },
>> +	{ "w25x80", INFO(0xef3014, 0, 0, 64 * 1024,  16, SECT_4K) },
>> +	{ "w25x16", INFO(0xef3015, 0, 0, 64 * 1024,  32, SECT_4K) },
>> +	{ "w25x32", INFO(0xef3016, 0, 0, 64 * 1024,  64, SECT_4K) },
>> +	{ "w25q32", INFO(0xef4016, 0, 0, 64 * 1024,  64, SECT_4K) },
>>  	{
>> -		"w25q32dw", INFO(0xef6016, 0, 64 * 1024,  64,
>> +		"w25q32dw", INFO(0xef6016, 0, 0, 64 * 1024,  64,
>>  			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>>  			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
>>  	},
>> -	{ "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
>> -	{ "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
>> +	{ "w25x64", INFO(0xef3017, 0, 0, 64 * 1024, 128, SECT_4K) },
>> +	{ "w25q64", INFO(0xef4017, 0, 0, 64 * 1024, 128, SECT_4K) },
>>  	{
>> -		"w25q64dw", INFO(0xef6017, 0, 64 * 1024, 128,
>> +		"w25q64dw", INFO(0xef6017, 0, 0, 64 * 1024, 128,
>>  			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>>  			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
>>  	},
>>  	{
>> -		"w25q128fw", INFO(0xef6018, 0, 64 * 1024, 256,
>> +		"w25q128fw", INFO(0xef6018, 0, 0, 64 * 1024, 256,
>>  			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
>>  			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
>>  	},
>> -	{ "w25q80", INFO(0xef5014, 0, 64 * 1024,  16, SECT_4K) },
>> -	{ "w25q80bl", INFO(0xef4014, 0, 64 * 1024,  16, SECT_4K) },
>> -	{ "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
>> -	{ "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K) },
>> +	{ "w25q80",   INFO(0xef5014, 0, 0, 64 * 1024,  16, SECT_4K) },
>> +	{ "w25q80bl", INFO(0xef4014, 0, 0, 64 * 1024,  16, SECT_4K) },
>> +	{ "w25q128",  INFO(0xef4018, 0, 0, 64 * 1024, 256, SECT_4K) },
>> +	{ "w25q256",  INFO(0xef4019, 0, 0, 64 * 1024, 512, SECT_4K) },
>>  
>>  	/* Catalyst / On Semiconductor -- non-JEDEC */
>> -	{ "cat25c11", CAT25_INFO(  16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
>> -	{ "cat25c03", CAT25_INFO(  32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
>> -	{ "cat25c09", CAT25_INFO( 128, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
>> -	{ "cat25c17", CAT25_INFO( 256, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
>> -	{ "cat25128", CAT25_INFO(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
>> +	{ "cat25c11", INFO_NOID(  16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
>> +	{ "cat25c03", INFO_NOID(  32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
>> +	{ "cat25c09", INFO_NOID( 128, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
>> +	{ "cat25c17", INFO_NOID( 256, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
>> +	{ "cat25128", INFO_NOID(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
>>  
>>  	/* Xilinx S3AN Internal Flash */
>> -	{ "3S50AN", S3AN_INFO(0x1f2200, 64, 264) },
>> -	{ "3S200AN", S3AN_INFO(0x1f2400, 256, 264) },
>> -	{ "3S400AN", S3AN_INFO(0x1f2400, 256, 264) },
>> -	{ "3S700AN", S3AN_INFO(0x1f2500, 512, 264) },
>> -	{ "3S1400AN", S3AN_INFO(0x1f2600, 512, 528) },
>> +	{ "3S50AN",   INFO_S3AN(0x1f2200, 64, 264) },
>> +	{ "3S200AN",  INFO_S3AN(0x1f2400, 256, 264) },
>> +	{ "3S400AN",  INFO_S3AN(0x1f2400, 256, 264) },
>> +	{ "3S700AN",  INFO_S3AN(0x1f2500, 512, 264) },
>> +	{ "3S1400AN", INFO_S3AN(0x1f2600, 512, 528) },
>>  	{ },
>>  };
>>  
>>  static const struct flash_info *spi_nor_read_id(struct spi_nor *nor)
>>  {
>>  	int			tmp;
>> -	u8			id[SPI_NOR_MAX_ID_LEN];
>> +	u8			id_bytes[sizeof(u64)];
>> +	u64			id;
>>  	const struct flash_info	*info;
>>  
>> -	tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
>> +	BUILD_BUG_ON(SPI_NOR_MAX_ID_LEN > sizeof(u64));
>> +
>> +	memset(id_bytes, 0, sizeof(id_bytes));
>> +	tmp = nor->read_reg(nor, SPINOR_OP_RDID, id_bytes, SPI_NOR_MAX_ID_LEN);
>>  	if (tmp < 0) {
>>  		dev_dbg(nor->dev, "error %d reading JEDEC ID\n", tmp);
>>  		return ERR_PTR(tmp);
>>  	}
>>  
>> +	id = get_unaligned_be64(id_bytes);
>> +
>>  	for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) {
>>  		info = &spi_nor_ids[tmp];
>> -		if (info->id_len) {
>> -			if (!memcmp(info->id, id, info->id_len))
>> -				return &spi_nor_ids[tmp];
>> -		}
>> +		if (info->id_mask && (id & info->id_mask) == info->id)
>> +			return info;
>>  	}
>> -	dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %02x, %02x\n",
>> -		id[0], id[1], id[2]);
>> +	dev_err(nor->dev, "unrecognized JEDEC id bytes: %*ph\n",
>> +		SPI_NOR_MAX_ID_LEN, id_bytes);
>>  	return ERR_PTR(-ENODEV);
>>  }
>>  
>> @@ -1551,7 +1555,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
>>  	 * If caller has specified name of flash model that can normally be
>>  	 * detected using JEDEC, let's verify it.
>>  	 */
>> -	if (name && info->id_len) {
>> +	if (name && info->id_mask) {
>>  		const struct flash_info *jinfo;
>>  
>>  		jinfo = spi_nor_read_id(nor);
>>
> 
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v2 0/3] mtd: spi-nor: flash_info table, use a u64 for the ID
  2017-02-14 10:22           ` Cyrille Pitchen
@ 2017-02-14 15:35             ` mark.marshall
  2017-02-14 15:35               ` [PATCH v2 1/3] " mark.marshall
                                 ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: mark.marshall @ 2017-02-14 15:35 UTC (permalink / raw)
  To: computersforpeace, linux-mtd, cyrille.pitchen, marek.vasut
  Cc: markmarshall14, dwmw2, richard, boris.brezillon, Mark Marshall

From: Mark Marshall <mark.marshall@omicronenergy.com>

This is a minor re-write of my previous patch to change the flash_info
table to contain a u64 for the RDID bytes.  It's now split into three
patches, the first changes the flash_info structure and massages the
currently named macros to generate the new table.  The second replaces
the macros in the table with slightly more explicit ones, and the third
patch makes the actual change to the table that I wanted.

I now use macro called JEDEC_ID(_jedec_id, _ext_id, _ext_len) to generate
the IDs.  This could be different, of course.

Mark Marshall (3):
  mtd: spi-nor: flash_info table, use a u64 for the ID
  mtd: spi-nor: Use more explicit macros to generate the flash_info
    table
  mtd: spi-nor: s25fl512s: Set a page size of 512

 drivers/mtd/spi-nor/spi-nor.c | 467 ++++++++++++++++++++++--------------------
 1 file changed, 240 insertions(+), 227 deletions(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v2 1/3] mtd: spi-nor: flash_info table, use a u64 for the ID
  2017-02-14 15:35             ` [PATCH v2 0/3] " mark.marshall
@ 2017-02-14 15:35               ` mark.marshall
  2017-02-14 15:35               ` [PATCH v2 2/3] mtd: spi-nor: Use more explicit macros to generate the flash_info table mark.marshall
  2017-02-14 15:35               ` [PATCH v2 3/3] mtd: spi-nor: s25fl512s: Set a page size of 512 mark.marshall
  2 siblings, 0 replies; 12+ messages in thread
From: mark.marshall @ 2017-02-14 15:35 UTC (permalink / raw)
  To: computersforpeace, linux-mtd, cyrille.pitchen, marek.vasut
  Cc: markmarshall14, dwmw2, richard, boris.brezillon, Mark Marshall

From: Mark Marshall <mark.marshall@omicronenergy.com>

The flash_info ID matching table is getting more complex as different
chips are added.  Some chips require different amounts of the response
to the RDID command to be matched.  Replace the current u8 array and
length with a u64 id and a u64 id_mask.  This allows us to simplify the
macros used to generate the flash_info table without loosing the ability
to generate "unusual" entries.

Signed-off-by: Mark Marshall <mark.marshall@omicronenergy.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 119 ++++++++++++++++++++++--------------------
 1 file changed, 62 insertions(+), 57 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 1ae872b..ab3f380 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -41,15 +41,22 @@
 #define SPI_NOR_MAX_ADDR_WIDTH	4
 
 struct flash_info {
-	char		*name;
+	const char	*name;
 
 	/*
-	 * This array stores the ID bytes.
-	 * The first three bytes are the JEDIC ID.
-	 * JEDEC ID zero means "no ID" (mostly older chips).
+	 * This u64 stores the ID bytes.
+	 * The bytes are stored in big-endian order (that is, the
+	 * first byte of the RDID result is the MSB of the value.  The
+	 * u64 is stored in host endian).
+	 * The upper three bytes are the JEDEC ID, the lower bytes are
+	 * the extension.
 	 */
-	u8		id[SPI_NOR_MAX_ID_LEN];
-	u8		id_len;
+	u64		id;
+
+	/*
+	 * An id_mask of zero means "no ID" (mostly older chips).
+	 */
+	u64		id_mask;
 
 	/* The size listed here is what works with SPINOR_OP_SE, which isn't
 	 * necessarily called a "sector" by the vendor.
@@ -87,7 +94,7 @@ struct flash_info {
 					 */
 };
 
-#define JEDEC_MFR(info)	((info)->id[0])
+#define JEDEC_MFR(info)	((u8)((info)->id >> 56) & 0xff)
 
 static const struct flash_info *spi_nor_match_id(const char *name);
 
@@ -870,55 +877,49 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 	return ret;
 }
 
+#define INFO_RAW(_id, _id_mask, _sector_size, _n_sectors, _page_size, _addr_width, _flags) \
+	.id = (_id),							\
+	.id_mask = (_id_mask),						\
+	.sector_size = (_sector_size),					\
+	.n_sectors = (_n_sectors),					\
+	.page_size = (_page_size),					\
+	.addr_width = (_addr_width),					\
+	.flags = (_flags),
+
 /* Used when the "_ext_id" is two bytes at most */
 #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
-		.id = {							\
-			((_jedec_id) >> 16) & 0xff,			\
-			((_jedec_id) >> 8) & 0xff,			\
-			(_jedec_id) & 0xff,				\
-			((_ext_id) >> 8) & 0xff,			\
-			(_ext_id) & 0xff,				\
-			},						\
-		.id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))),	\
-		.sector_size = (_sector_size),				\
-		.n_sectors = (_n_sectors),				\
-		.page_size = 256,					\
-		.flags = (_flags),
+	INFO_RAW(!(_jedec_id) ? 0 :					\
+		 (((u64)(_jedec_id) << (64 - (8 * 3))) |		\
+		  ((u64)(_ext_id) << (64 - (40)))),			\
+		 !(_jedec_id) ? 0 :					\
+		 GENMASK_ULL(63, 64 - (8 * (3 + ((_ext_id) ? 2 : 0)))),	\
+		 (_sector_size),					\
+		 (_n_sectors),						\
+		 256,							\
+		 0,							\
+		 (_flags))
 
 #define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
-		.id = {							\
-			((_jedec_id) >> 16) & 0xff,			\
-			((_jedec_id) >> 8) & 0xff,			\
-			(_jedec_id) & 0xff,				\
-			((_ext_id) >> 16) & 0xff,			\
-			((_ext_id) >> 8) & 0xff,			\
-			(_ext_id) & 0xff,				\
-			},						\
-		.id_len = 6,						\
-		.sector_size = (_sector_size),				\
-		.n_sectors = (_n_sectors),				\
-		.page_size = 256,					\
-		.flags = (_flags),
+	INFO_RAW((((u64)(_jedec_id) << (64 - (8 * 3))) |		\
+		  ((u64)(_ext_id) << (64 - (48)))),			\
+		 GENMASK_ULL(63, 64 - (8 * (3 + ((_ext_id) ? 3 : 0)))),	\
+		 (_sector_size),					\
+		 (_n_sectors),						\
+		 256,							\
+		 0,							\
+		 (_flags))
 
 #define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width, _flags)	\
-		.sector_size = (_sector_size),				\
-		.n_sectors = (_n_sectors),				\
-		.page_size = (_page_size),				\
-		.addr_width = (_addr_width),				\
-		.flags = (_flags),
+	INFO_RAW(0, 0, (_sector_size), (_n_sectors), (_page_size), (_addr_width), (_flags))
 
 #define S3AN_INFO(_jedec_id, _n_sectors, _page_size)			\
-		.id = {							\
-			((_jedec_id) >> 16) & 0xff,			\
-			((_jedec_id) >> 8) & 0xff,			\
-			(_jedec_id) & 0xff				\
-			},						\
-		.id_len = 3,						\
-		.sector_size = (8*_page_size),				\
-		.n_sectors = (_n_sectors),				\
-		.page_size = _page_size,				\
-		.addr_width = 3,					\
-		.flags = SPI_NOR_NO_FR | SPI_S3AN,
+	INFO_RAW((((u64)(_jedec_id) << (64 - (8 * 3)))),		\
+		 GENMASK_ULL(63, 64 - (8 * (3))),			\
+		 8 * (_page_size),					\
+		 (_n_sectors),						\
+		 (_page_size),						\
+		 3,							\
+		 SPI_NOR_NO_FR | SPI_S3AN)
 
 /* NOTE: double check command sets and memory organization when you add
  * more nor chips.  This current list focusses on newer chips, which
@@ -1170,24 +1171,28 @@ static const struct flash_info spi_nor_ids[] = {
 static const struct flash_info *spi_nor_read_id(struct spi_nor *nor)
 {
 	int			tmp;
-	u8			id[SPI_NOR_MAX_ID_LEN];
+	u8			id_bytes[sizeof(u64)];
+	u64			id;
 	const struct flash_info	*info;
 
-	tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN);
+	BUILD_BUG_ON(SPI_NOR_MAX_ID_LEN > sizeof(u64));
+
+	memset(id_bytes, 0, sizeof(id_bytes));
+	tmp = nor->read_reg(nor, SPINOR_OP_RDID, id_bytes, SPI_NOR_MAX_ID_LEN);
 	if (tmp < 0) {
 		dev_dbg(nor->dev, "error %d reading JEDEC ID\n", tmp);
 		return ERR_PTR(tmp);
 	}
 
+	id = get_unaligned_be64(id_bytes);
+
 	for (tmp = 0; tmp < ARRAY_SIZE(spi_nor_ids) - 1; tmp++) {
 		info = &spi_nor_ids[tmp];
-		if (info->id_len) {
-			if (!memcmp(info->id, id, info->id_len))
-				return &spi_nor_ids[tmp];
-		}
+		if (info->id_mask && (id & info->id_mask) == info->id)
+			return info;
 	}
-	dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %02x, %02x\n",
-		id[0], id[1], id[2]);
+	dev_err(nor->dev, "unrecognized JEDEC id bytes: %*ph\n",
+		SPI_NOR_MAX_ID_LEN, id_bytes);
 	return ERR_PTR(-ENODEV);
 }
 
@@ -1551,7 +1556,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode)
 	 * If caller has specified name of flash model that can normally be
 	 * detected using JEDEC, let's verify it.
 	 */
-	if (name && info->id_len) {
+	if (name && info->id_mask) {
 		const struct flash_info *jinfo;
 
 		jinfo = spi_nor_read_id(nor);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 2/3] mtd: spi-nor: Use more explicit macros to generate the flash_info table
  2017-02-14 15:35             ` [PATCH v2 0/3] " mark.marshall
  2017-02-14 15:35               ` [PATCH v2 1/3] " mark.marshall
@ 2017-02-14 15:35               ` mark.marshall
  2017-02-14 15:35               ` [PATCH v2 3/3] mtd: spi-nor: s25fl512s: Set a page size of 512 mark.marshall
  2 siblings, 0 replies; 12+ messages in thread
From: mark.marshall @ 2017-02-14 15:35 UTC (permalink / raw)
  To: computersforpeace, linux-mtd, cyrille.pitchen, marek.vasut
  Cc: markmarshall14, dwmw2, richard, boris.brezillon, Mark Marshall

From: Mark Marshall <mark.marshall@omicronenergy.com>

Now that we are storing the RDID id as a u64 we can try to reduce the
number of special INFO macros that we need, but also add the possibility
of setting all of the fields of the structure, if we need to.

Signed-off-by: Mark Marshall <mark.marshall@omicronenergy.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 374 +++++++++++++++++++++---------------------
 1 file changed, 190 insertions(+), 184 deletions(-)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index ab3f380..467dc93 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -886,36 +886,42 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
 	.addr_width = (_addr_width),					\
 	.flags = (_flags),
 
-/* Used when the "_ext_id" is two bytes at most */
-#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
-	INFO_RAW(!(_jedec_id) ? 0 :					\
-		 (((u64)(_jedec_id) << (64 - (8 * 3))) |		\
-		  ((u64)(_ext_id) << (64 - (40)))),			\
-		 !(_jedec_id) ? 0 :					\
-		 GENMASK_ULL(63, 64 - (8 * (3 + ((_ext_id) ? 2 : 0)))),	\
-		 (_sector_size),					\
-		 (_n_sectors),						\
-		 256,							\
-		 0,							\
-		 (_flags))
+/*
+ * This is used to produce the "id" and "id_mask" fields.  The
+ * _jedec_id is expected to be a 24 bit number containing the first
+ * three octets of the RDID response, in "big endian" order (that is,
+ * the first octet of the RDID response is in the MS position).
+ *
+ * If more of the RDID response should be checked than these octets
+ * should be in _ext_id, and should be _ext_len octets long, again, in
+ * "big endian" order.
+ *
+ * NB. This macro expands into something like "X, Z", which is
+ * expected to become the first two parameters to INFO_RAW.
+ */
+#define JEDEC_ID(_jedec_id, _ext_id, _ext_len)				\
+	(((u64)(_jedec_id) << (64 - (8 * 3))) |				\
+	 ((u64)(_ext_id) << (64 - (8 * (3 + (_ext_len)))))),		\
+	GENMASK_ULL(63, 64 - (8 * (3 + (_ext_len))))
+
+#define NONE_ID() 0, 0
 
-#define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)	\
-	INFO_RAW((((u64)(_jedec_id) << (64 - (8 * 3))) |		\
-		  ((u64)(_ext_id) << (64 - (48)))),			\
-		 GENMASK_ULL(63, 64 - (8 * (3 + ((_ext_id) ? 3 : 0)))),	\
+/* Used to provide information for a standard JEDEC device. */
+#define INFO(_ID, _sector_size, _n_sectors, _flags)			\
+	INFO_RAW(_ID,							\
 		 (_sector_size),					\
 		 (_n_sectors),						\
 		 256,							\
 		 0,							\
 		 (_flags))
 
-#define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_width, _flags)	\
-	INFO_RAW(0, 0, (_sector_size), (_n_sectors), (_page_size), (_addr_width), (_flags))
+/* Used to provide the full information about a device. */
+#define INFO_FULL(_ID, _sector_size, _n_sectors, _pg_sz, _addr_width, _flags) \
+	INFO_RAW(_ID, (_sector_size), (_n_sectors), (_pg_sz), (_addr_width), (_flags))
 
-#define S3AN_INFO(_jedec_id, _n_sectors, _page_size)			\
-	INFO_RAW((((u64)(_jedec_id) << (64 - (8 * 3)))),		\
-		 GENMASK_ULL(63, 64 - (8 * (3))),			\
-		 8 * (_page_size),					\
+#define INFO_S3AN(_ID, _n_sectors, _page_size)				\
+	INFO_RAW(_ID,							\
+		 8*(_page_size),					\
 		 (_n_sectors),						\
 		 (_page_size),						\
 		 3,							\
@@ -934,237 +940,237 @@ static int spi_nor_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len)
  */
 static const struct flash_info spi_nor_ids[] = {
 	/* Atmel -- some are (confusingly) marketed as "DataFlash" */
-	{ "at25fs010",  INFO(0x1f6601, 0, 32 * 1024,   4, SECT_4K) },
-	{ "at25fs040",  INFO(0x1f6604, 0, 64 * 1024,   8, SECT_4K) },
+	{ "at25fs010",  INFO(JEDEC_ID(0x1f6601, 0, 0), 32 * 1024,   4, SECT_4K) },
+	{ "at25fs040",  INFO(JEDEC_ID(0x1f6604, 0, 0), 64 * 1024,   8, SECT_4K) },
 
-	{ "at25df041a", INFO(0x1f4401, 0, 64 * 1024,   8, SECT_4K) },
-	{ "at25df321",  INFO(0x1f4700, 0, 64 * 1024,  64, SECT_4K) },
-	{ "at25df321a", INFO(0x1f4701, 0, 64 * 1024,  64, SECT_4K) },
-	{ "at25df641",  INFO(0x1f4800, 0, 64 * 1024, 128, SECT_4K) },
+	{ "at25df041a", INFO(JEDEC_ID(0x1f4401, 0, 0), 64 * 1024,   8, SECT_4K) },
+	{ "at25df321",  INFO(JEDEC_ID(0x1f4700, 0, 0), 64 * 1024,  64, SECT_4K) },
+	{ "at25df321a", INFO(JEDEC_ID(0x1f4701, 0, 0), 64 * 1024,  64, SECT_4K) },
+	{ "at25df641",  INFO(JEDEC_ID(0x1f4800, 0, 0), 64 * 1024, 128, SECT_4K) },
 
-	{ "at26f004",   INFO(0x1f0400, 0, 64 * 1024,  8, SECT_4K) },
-	{ "at26df081a", INFO(0x1f4501, 0, 64 * 1024, 16, SECT_4K) },
-	{ "at26df161a", INFO(0x1f4601, 0, 64 * 1024, 32, SECT_4K) },
-	{ "at26df321",  INFO(0x1f4700, 0, 64 * 1024, 64, SECT_4K) },
+	{ "at26f004",   INFO(JEDEC_ID(0x1f0400, 0, 0), 64 * 1024,  8, SECT_4K) },
+	{ "at26df081a", INFO(JEDEC_ID(0x1f4501, 0, 0), 64 * 1024, 16, SECT_4K) },
+	{ "at26df161a", INFO(JEDEC_ID(0x1f4601, 0, 0), 64 * 1024, 32, SECT_4K) },
+	{ "at26df321",  INFO(JEDEC_ID(0x1f4700, 0, 0), 64 * 1024, 64, SECT_4K) },
 
-	{ "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) },
+	{ "at45db081d", INFO(JEDEC_ID(0x1f2500, 0, 0), 64 * 1024, 16, SECT_4K) },
 
 	/* EON -- en25xxx */
-	{ "en25f32",    INFO(0x1c3116, 0, 64 * 1024,   64, SECT_4K) },
-	{ "en25p32",    INFO(0x1c2016, 0, 64 * 1024,   64, 0) },
-	{ "en25q32b",   INFO(0x1c3016, 0, 64 * 1024,   64, 0) },
-	{ "en25p64",    INFO(0x1c2017, 0, 64 * 1024,  128, 0) },
-	{ "en25q64",    INFO(0x1c3017, 0, 64 * 1024,  128, SECT_4K) },
-	{ "en25qh128",  INFO(0x1c7018, 0, 64 * 1024,  256, 0) },
-	{ "en25qh256",  INFO(0x1c7019, 0, 64 * 1024,  512, 0) },
-	{ "en25s64",	INFO(0x1c3817, 0, 64 * 1024,  128, SECT_4K) },
+	{ "en25f32",    INFO(JEDEC_ID(0x1c3116, 0, 0), 64 * 1024,   64, SECT_4K) },
+	{ "en25p32",    INFO(JEDEC_ID(0x1c2016, 0, 0), 64 * 1024,   64, 0) },
+	{ "en25q32b",   INFO(JEDEC_ID(0x1c3016, 0, 0), 64 * 1024,   64, 0) },
+	{ "en25p64",    INFO(JEDEC_ID(0x1c2017, 0, 0), 64 * 1024,  128, 0) },
+	{ "en25q64",    INFO(JEDEC_ID(0x1c3017, 0, 0), 64 * 1024,  128, SECT_4K) },
+	{ "en25qh128",  INFO(JEDEC_ID(0x1c7018, 0, 0), 64 * 1024,  256, 0) },
+	{ "en25qh256",  INFO(JEDEC_ID(0x1c7019, 0, 0), 64 * 1024,  512, 0) },
+	{ "en25s64",	INFO(JEDEC_ID(0x1c3817, 0, 0), 64 * 1024,  128, SECT_4K) },
 
 	/* ESMT */
-	{ "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) },
+	{ "f25l32pa", INFO(JEDEC_ID(0x8c2016, 0, 0), 64 * 1024, 64, SECT_4K | SPI_NOR_HAS_LOCK) },
 
 	/* Everspin */
-	{ "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
-	{ "mr25h10",  CAT25_INFO(128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
-	{ "mr25h40",  CAT25_INFO(512 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "mr25h256", INFO_FULL(NONE_ID(),  32 * 1024, 1, 256, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "mr25h10",  INFO_FULL(NONE_ID(), 128 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "mr25h40",  INFO_FULL(NONE_ID(), 512 * 1024, 1, 256, 3, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
 
 	/* Fujitsu */
-	{ "mb85rs1mt", INFO(0x047f27, 0, 128 * 1024, 1, SPI_NOR_NO_ERASE) },
+	{ "mb85rs1mt", INFO(JEDEC_ID(0x047f27, 0, 0), 128 * 1024, 1, SPI_NOR_NO_ERASE) },
 
 	/* GigaDevice */
 	{
-		"gd25q16", INFO(0xc84015, 0, 64 * 1024,  32,
+		"gd25q16", INFO(JEDEC_ID(0xc84015, 0, 0), 64 * 1024,  32,
 			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
 	},
 	{
-		"gd25q32", INFO(0xc84016, 0, 64 * 1024,  64,
+		"gd25q32", INFO(JEDEC_ID(0xc84016, 0, 0), 64 * 1024,  64,
 			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
 	},
 	{
-		"gd25q64", INFO(0xc84017, 0, 64 * 1024, 128,
+		"gd25q64", INFO(JEDEC_ID(0xc84017, 0, 0), 64 * 1024, 128,
 			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
 	},
 	{
-		"gd25lq64c", INFO(0xc86017, 0, 64 * 1024, 128,
+		"gd25lq64c", INFO(JEDEC_ID(0xc86017, 0, 0), 64 * 1024, 128,
 			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
 	},
 	{
-		"gd25q128", INFO(0xc84018, 0, 64 * 1024, 256,
+		"gd25q128", INFO(JEDEC_ID(0xc84018, 0, 0), 64 * 1024, 256,
 			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
 	},
 
 	/* Intel/Numonyx -- xxxs33b */
-	{ "160s33b",  INFO(0x898911, 0, 64 * 1024,  32, 0) },
-	{ "320s33b",  INFO(0x898912, 0, 64 * 1024,  64, 0) },
-	{ "640s33b",  INFO(0x898913, 0, 64 * 1024, 128, 0) },
+	{ "160s33b",  INFO(JEDEC_ID(0x898911, 0, 0), 64 * 1024,  32, 0) },
+	{ "320s33b",  INFO(JEDEC_ID(0x898912, 0, 0), 64 * 1024,  64, 0) },
+	{ "640s33b",  INFO(JEDEC_ID(0x898913, 0, 0), 64 * 1024, 128, 0) },
 
 	/* ISSI */
-	{ "is25cd512", INFO(0x7f9d20, 0, 32 * 1024,   2, SECT_4K) },
+	{ "is25cd512", INFO(JEDEC_ID(0x7f9d20, 0, 0), 32 * 1024,   2, SECT_4K) },
 
 	/* Macronix */
-	{ "mx25l512e",   INFO(0xc22010, 0, 64 * 1024,   1, SECT_4K) },
-	{ "mx25l2005a",  INFO(0xc22012, 0, 64 * 1024,   4, SECT_4K) },
-	{ "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) },
-	{ "mx25l3255e",  INFO(0xc29e16, 0, 64 * 1024,  64, SECT_4K) },
-	{ "mx25l6405d",  INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) },
-	{ "mx25u6435f",  INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) },
-	{ "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) },
-	{ "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) },
-	{ "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) },
-	{ "mx25u25635f", INFO(0xc22539, 0, 64 * 1024, 512, SECT_4K) },
-	{ "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) },
-	{ "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, SPI_NOR_QUAD_READ) },
-	{ "mx66l1g55g",  INFO(0xc2261b, 0, 64 * 1024, 2048, SPI_NOR_QUAD_READ) },
+	{ "mx25l512e",   INFO(JEDEC_ID(0xc22010, 0, 0), 64 * 1024,   1, SECT_4K) },
+	{ "mx25l2005a",  INFO(JEDEC_ID(0xc22012, 0, 0), 64 * 1024,   4, SECT_4K) },
+	{ "mx25l4005a",  INFO(JEDEC_ID(0xc22013, 0, 0), 64 * 1024,   8, SECT_4K) },
+	{ "mx25l8005",   INFO(JEDEC_ID(0xc22014, 0, 0), 64 * 1024,  16, 0) },
+	{ "mx25l1606e",  INFO(JEDEC_ID(0xc22015, 0, 0), 64 * 1024,  32, SECT_4K) },
+	{ "mx25l3205d",  INFO(JEDEC_ID(0xc22016, 0, 0), 64 * 1024,  64, SECT_4K) },
+	{ "mx25l3255e",  INFO(JEDEC_ID(0xc29e16, 0, 0), 64 * 1024,  64, SECT_4K) },
+	{ "mx25l6405d",  INFO(JEDEC_ID(0xc22017, 0, 0), 64 * 1024, 128, SECT_4K) },
+	{ "mx25u6435f",  INFO(JEDEC_ID(0xc22537, 0, 0), 64 * 1024, 128, SECT_4K) },
+	{ "mx25l12805d", INFO(JEDEC_ID(0xc22018, 0, 0), 64 * 1024, 256, 0) },
+	{ "mx25l12855e", INFO(JEDEC_ID(0xc22618, 0, 0), 64 * 1024, 256, 0) },
+	{ "mx25l25635e", INFO(JEDEC_ID(0xc22019, 0, 0), 64 * 1024, 512, 0) },
+	{ "mx25u25635f", INFO(JEDEC_ID(0xc22539, 0, 0), 64 * 1024, 512, SECT_4K) },
+	{ "mx25l25655e", INFO(JEDEC_ID(0xc22619, 0, 0), 64 * 1024, 512, 0) },
+	{ "mx66l51235l", INFO(JEDEC_ID(0xc2201a, 0, 0), 64 * 1024, 1024, SPI_NOR_QUAD_READ) },
+	{ "mx66l1g55g",  INFO(JEDEC_ID(0xc2261b, 0, 0), 64 * 1024, 2048, SPI_NOR_QUAD_READ) },
 
 	/* Micron */
-	{ "n25q016a",	 INFO(0x20bb15, 0, 64 * 1024,   32, SECT_4K | SPI_NOR_QUAD_READ) },
-	{ "n25q032",	 INFO(0x20ba16, 0, 64 * 1024,   64, SPI_NOR_QUAD_READ) },
-	{ "n25q032a",	 INFO(0x20bb16, 0, 64 * 1024,   64, SPI_NOR_QUAD_READ) },
-	{ "n25q064",     INFO(0x20ba17, 0, 64 * 1024,  128, SECT_4K | SPI_NOR_QUAD_READ) },
-	{ "n25q064a",    INFO(0x20bb17, 0, 64 * 1024,  128, SECT_4K | SPI_NOR_QUAD_READ) },
-	{ "n25q128a11",  INFO(0x20bb18, 0, 64 * 1024,  256, SECT_4K | SPI_NOR_QUAD_READ) },
-	{ "n25q128a13",  INFO(0x20ba18, 0, 64 * 1024,  256, SECT_4K | SPI_NOR_QUAD_READ) },
-	{ "n25q256a",    INFO(0x20ba19, 0, 64 * 1024,  512, SECT_4K | SPI_NOR_QUAD_READ) },
-	{ "n25q512a",    INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
-	{ "n25q512ax3",  INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
-	{ "n25q00",      INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
-	{ "n25q00a",     INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
+	{ "n25q016a",	 INFO(JEDEC_ID(0x20bb15, 0, 0), 64 * 1024,   32, SECT_4K | SPI_NOR_QUAD_READ) },
+	{ "n25q032",	 INFO(JEDEC_ID(0x20ba16, 0, 0), 64 * 1024,   64, SPI_NOR_QUAD_READ) },
+	{ "n25q032a",	 INFO(JEDEC_ID(0x20bb16, 0, 0), 64 * 1024,   64, SPI_NOR_QUAD_READ) },
+	{ "n25q064",     INFO(JEDEC_ID(0x20ba17, 0, 0), 64 * 1024,  128, SECT_4K | SPI_NOR_QUAD_READ) },
+	{ "n25q064a",    INFO(JEDEC_ID(0x20bb17, 0, 0), 64 * 1024,  128, SECT_4K | SPI_NOR_QUAD_READ) },
+	{ "n25q128a11",  INFO(JEDEC_ID(0x20bb18, 0, 0), 64 * 1024,  256, SECT_4K | SPI_NOR_QUAD_READ) },
+	{ "n25q128a13",  INFO(JEDEC_ID(0x20ba18, 0, 0), 64 * 1024,  256, SECT_4K | SPI_NOR_QUAD_READ) },
+	{ "n25q256a",    INFO(JEDEC_ID(0x20ba19, 0, 0), 64 * 1024,  512, SECT_4K | SPI_NOR_QUAD_READ) },
+	{ "n25q512a",    INFO(JEDEC_ID(0x20bb20, 0, 0), 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
+	{ "n25q512ax3",  INFO(JEDEC_ID(0x20ba20, 0, 0), 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
+	{ "n25q00",      INFO(JEDEC_ID(0x20ba21, 0, 0), 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
+	{ "n25q00a",     INFO(JEDEC_ID(0x20bb21, 0, 0), 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) },
 
 	/* PMC */
-	{ "pm25lv512",   INFO(0,        0, 32 * 1024,    2, SECT_4K_PMC) },
-	{ "pm25lv010",   INFO(0,        0, 32 * 1024,    4, SECT_4K_PMC) },
-	{ "pm25lq032",   INFO(0x7f9d46, 0, 64 * 1024,   64, SECT_4K) },
+	{ "pm25lv512",   INFO_FULL(NONE_ID(), 32 * 1024,    2, 256, 0, SECT_4K_PMC) },
+	{ "pm25lv010",   INFO_FULL(NONE_ID(), 32 * 1024,    4, 256, 0, SECT_4K_PMC) },
+	{ "pm25lq032",   INFO(JEDEC_ID(0x7f9d46, 0, 0), 64 * 1024,   64, SECT_4K) },
 
 	/* Spansion -- single (large) sector size only, at least
 	 * for the chips listed here (without boot sectors).
 	 */
-	{ "s25sl032p",  INFO(0x010215, 0x4d00,  64 * 1024,  64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-	{ "s25sl064p",  INFO(0x010216, 0x4d00,  64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-	{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
-	{ "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-	{ "s25fl512s",  INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-	{ "s70fl01gs",  INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) },
-	{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024,  64, 0) },
-	{ "s25sl12801", INFO(0x012018, 0x0301,  64 * 1024, 256, 0) },
-	{ "s25fl128s",	INFO6(0x012018, 0x4d0180, 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-	{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024,  64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-	{ "s25fl129p1", INFO(0x012018, 0x4d01,  64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-	{ "s25sl004a",  INFO(0x010212,      0,  64 * 1024,   8, 0) },
-	{ "s25sl008a",  INFO(0x010213,      0,  64 * 1024,  16, 0) },
-	{ "s25sl016a",  INFO(0x010214,      0,  64 * 1024,  32, 0) },
-	{ "s25sl032a",  INFO(0x010215,      0,  64 * 1024,  64, 0) },
-	{ "s25sl064a",  INFO(0x010216,      0,  64 * 1024, 128, 0) },
-	{ "s25fl004k",  INFO(0xef4013,      0,  64 * 1024,   8, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-	{ "s25fl008k",  INFO(0xef4014,      0,  64 * 1024,  16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-	{ "s25fl016k",  INFO(0xef4015,      0,  64 * 1024,  32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-	{ "s25fl064k",  INFO(0xef4017,      0,  64 * 1024, 128, SECT_4K) },
-	{ "s25fl116k",  INFO(0x014015,      0,  64 * 1024,  32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
-	{ "s25fl132k",  INFO(0x014016,      0,  64 * 1024,  64, SECT_4K) },
-	{ "s25fl164k",  INFO(0x014017,      0,  64 * 1024, 128, SECT_4K) },
-	{ "s25fl204k",  INFO(0x014013,      0,  64 * 1024,   8, SECT_4K | SPI_NOR_DUAL_READ) },
-	{ "s25fl208k",  INFO(0x014014,      0,  64 * 1024,  16, SECT_4K | SPI_NOR_DUAL_READ) },
+	{ "s25sl032p",  INFO(JEDEC_ID(0x010215, 0x4d00, 2),  64 * 1024,  64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25sl064p",  INFO(JEDEC_ID(0x010216, 0x4d00, 2),  64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25fl256s0", INFO(JEDEC_ID(0x010219, 0x4d00, 2), 256 * 1024, 128, 0) },
+	{ "s25fl256s1", INFO(JEDEC_ID(0x010219, 0x4d01, 2),  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25fl512s",  INFO(JEDEC_ID(0x010220, 0x4d00, 2), 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s70fl01gs",  INFO(JEDEC_ID(0x010221, 0x4d00, 2), 256 * 1024, 256, 0) },
+	{ "s25sl12800", INFO(JEDEC_ID(0x012018, 0x0300, 2), 256 * 1024,  64, 0) },
+	{ "s25sl12801", INFO(JEDEC_ID(0x012018, 0x0301, 2),  64 * 1024, 256, 0) },
+	{ "s25fl128s",	INFO(JEDEC_ID(0x012018, 0x4d0180, 3), 64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25fl129p0", INFO(JEDEC_ID(0x012018, 0x4d00, 2), 256 * 1024,  64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25fl129p1", INFO(JEDEC_ID(0x012018, 0x4d01, 2),  64 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25sl004a",  INFO(JEDEC_ID(0x010212, 0, 0),  64 * 1024,   8, 0) },
+	{ "s25sl008a",  INFO(JEDEC_ID(0x010213, 0, 0),  64 * 1024,  16, 0) },
+	{ "s25sl016a",  INFO(JEDEC_ID(0x010214, 0, 0),  64 * 1024,  32, 0) },
+	{ "s25sl032a",  INFO(JEDEC_ID(0x010215, 0, 0),  64 * 1024,  64, 0) },
+	{ "s25sl064a",  INFO(JEDEC_ID(0x010216, 0, 0),  64 * 1024, 128, 0) },
+	{ "s25fl004k",  INFO(JEDEC_ID(0xef4013, 0, 0),  64 * 1024,   8, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25fl008k",  INFO(JEDEC_ID(0xef4014, 0, 0),  64 * 1024,  16, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25fl016k",  INFO(JEDEC_ID(0xef4015, 0, 0),  64 * 1024,  32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25fl064k",  INFO(JEDEC_ID(0xef4017, 0, 0),  64 * 1024, 128, SECT_4K) },
+	{ "s25fl116k",  INFO(JEDEC_ID(0x014015, 0, 0),  64 * 1024,  32, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25fl132k",  INFO(JEDEC_ID(0x014016, 0, 0),  64 * 1024,  64, SECT_4K) },
+	{ "s25fl164k",  INFO(JEDEC_ID(0x014017, 0, 0),  64 * 1024, 128, SECT_4K) },
+	{ "s25fl204k",  INFO(JEDEC_ID(0x014013, 0, 0),  64 * 1024,   8, SECT_4K | SPI_NOR_DUAL_READ) },
+	{ "s25fl208k",  INFO(JEDEC_ID(0x014014, 0, 0),  64 * 1024,  16, SECT_4K | SPI_NOR_DUAL_READ) },
 
 	/* SST -- large erase sizes are "overlays", "sectors" are 4K */
-	{ "sst25vf040b", INFO(0xbf258d, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) },
-	{ "sst25vf080b", INFO(0xbf258e, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },
-	{ "sst25vf016b", INFO(0xbf2541, 0, 64 * 1024, 32, SECT_4K | SST_WRITE) },
-	{ "sst25vf032b", INFO(0xbf254a, 0, 64 * 1024, 64, SECT_4K | SST_WRITE) },
-	{ "sst25vf064c", INFO(0xbf254b, 0, 64 * 1024, 128, SECT_4K) },
-	{ "sst25wf512",  INFO(0xbf2501, 0, 64 * 1024,  1, SECT_4K | SST_WRITE) },
-	{ "sst25wf010",  INFO(0xbf2502, 0, 64 * 1024,  2, SECT_4K | SST_WRITE) },
-	{ "sst25wf020",  INFO(0xbf2503, 0, 64 * 1024,  4, SECT_4K | SST_WRITE) },
-	{ "sst25wf020a", INFO(0x621612, 0, 64 * 1024,  4, SECT_4K) },
-	{ "sst25wf040b", INFO(0x621613, 0, 64 * 1024,  8, SECT_4K) },
-	{ "sst25wf040",  INFO(0xbf2504, 0, 64 * 1024,  8, SECT_4K | SST_WRITE) },
-	{ "sst25wf080",  INFO(0xbf2505, 0, 64 * 1024, 16, SECT_4K | SST_WRITE) },
+	{ "sst25vf040b", INFO(JEDEC_ID(0xbf258d, 0, 0), 64 * 1024,  8, SECT_4K | SST_WRITE) },
+	{ "sst25vf080b", INFO(JEDEC_ID(0xbf258e, 0, 0), 64 * 1024, 16, SECT_4K | SST_WRITE) },
+	{ "sst25vf016b", INFO(JEDEC_ID(0xbf2541, 0, 0), 64 * 1024, 32, SECT_4K | SST_WRITE) },
+	{ "sst25vf032b", INFO(JEDEC_ID(0xbf254a, 0, 0), 64 * 1024, 64, SECT_4K | SST_WRITE) },
+	{ "sst25vf064c", INFO(JEDEC_ID(0xbf254b, 0, 0), 64 * 1024, 128, SECT_4K) },
+	{ "sst25wf512",  INFO(JEDEC_ID(0xbf2501, 0, 0), 64 * 1024,  1, SECT_4K | SST_WRITE) },
+	{ "sst25wf010",  INFO(JEDEC_ID(0xbf2502, 0, 0), 64 * 1024,  2, SECT_4K | SST_WRITE) },
+	{ "sst25wf020",  INFO(JEDEC_ID(0xbf2503, 0, 0), 64 * 1024,  4, SECT_4K | SST_WRITE) },
+	{ "sst25wf020a", INFO(JEDEC_ID(0x621612, 0, 0), 64 * 1024,  4, SECT_4K) },
+	{ "sst25wf040b", INFO(JEDEC_ID(0x621613, 0, 0), 64 * 1024,  8, SECT_4K) },
+	{ "sst25wf040",  INFO(JEDEC_ID(0xbf2504, 0, 0), 64 * 1024,  8, SECT_4K | SST_WRITE) },
+	{ "sst25wf080",  INFO(JEDEC_ID(0xbf2505, 0, 0), 64 * 1024, 16, SECT_4K | SST_WRITE) },
 
 	/* ST Microelectronics -- newer production may have feature updates */
-	{ "m25p05",  INFO(0x202010,  0,  32 * 1024,   2, 0) },
-	{ "m25p10",  INFO(0x202011,  0,  32 * 1024,   4, 0) },
-	{ "m25p20",  INFO(0x202012,  0,  64 * 1024,   4, 0) },
-	{ "m25p40",  INFO(0x202013,  0,  64 * 1024,   8, 0) },
-	{ "m25p80",  INFO(0x202014,  0,  64 * 1024,  16, 0) },
-	{ "m25p16",  INFO(0x202015,  0,  64 * 1024,  32, 0) },
-	{ "m25p32",  INFO(0x202016,  0,  64 * 1024,  64, 0) },
-	{ "m25p64",  INFO(0x202017,  0,  64 * 1024, 128, 0) },
-	{ "m25p128", INFO(0x202018,  0, 256 * 1024,  64, 0) },
-
-	{ "m25p05-nonjedec",  INFO(0, 0,  32 * 1024,   2, 0) },
-	{ "m25p10-nonjedec",  INFO(0, 0,  32 * 1024,   4, 0) },
-	{ "m25p20-nonjedec",  INFO(0, 0,  64 * 1024,   4, 0) },
-	{ "m25p40-nonjedec",  INFO(0, 0,  64 * 1024,   8, 0) },
-	{ "m25p80-nonjedec",  INFO(0, 0,  64 * 1024,  16, 0) },
-	{ "m25p16-nonjedec",  INFO(0, 0,  64 * 1024,  32, 0) },
-	{ "m25p32-nonjedec",  INFO(0, 0,  64 * 1024,  64, 0) },
-	{ "m25p64-nonjedec",  INFO(0, 0,  64 * 1024, 128, 0) },
-	{ "m25p128-nonjedec", INFO(0, 0, 256 * 1024,  64, 0) },
-
-	{ "m45pe10", INFO(0x204011,  0, 64 * 1024,    2, 0) },
-	{ "m45pe80", INFO(0x204014,  0, 64 * 1024,   16, 0) },
-	{ "m45pe16", INFO(0x204015,  0, 64 * 1024,   32, 0) },
-
-	{ "m25pe20", INFO(0x208012,  0, 64 * 1024,  4,       0) },
-	{ "m25pe80", INFO(0x208014,  0, 64 * 1024, 16,       0) },
-	{ "m25pe16", INFO(0x208015,  0, 64 * 1024, 32, SECT_4K) },
-
-	{ "m25px16",    INFO(0x207115,  0, 64 * 1024, 32, SECT_4K) },
-	{ "m25px32",    INFO(0x207116,  0, 64 * 1024, 64, SECT_4K) },
-	{ "m25px32-s0", INFO(0x207316,  0, 64 * 1024, 64, SECT_4K) },
-	{ "m25px32-s1", INFO(0x206316,  0, 64 * 1024, 64, SECT_4K) },
-	{ "m25px64",    INFO(0x207117,  0, 64 * 1024, 128, 0) },
-	{ "m25px80",    INFO(0x207114,  0, 64 * 1024, 16, 0) },
+	{ "m25p05",  INFO(JEDEC_ID(0x202010, 0, 0),  32 * 1024,   2, 0) },
+	{ "m25p10",  INFO(JEDEC_ID(0x202011, 0, 0),  32 * 1024,   4, 0) },
+	{ "m25p20",  INFO(JEDEC_ID(0x202012, 0, 0),  64 * 1024,   4, 0) },
+	{ "m25p40",  INFO(JEDEC_ID(0x202013, 0, 0),  64 * 1024,   8, 0) },
+	{ "m25p80",  INFO(JEDEC_ID(0x202014, 0, 0),  64 * 1024,  16, 0) },
+	{ "m25p16",  INFO(JEDEC_ID(0x202015, 0, 0),  64 * 1024,  32, 0) },
+	{ "m25p32",  INFO(JEDEC_ID(0x202016, 0, 0),  64 * 1024,  64, 0) },
+	{ "m25p64",  INFO(JEDEC_ID(0x202017, 0, 0),  64 * 1024, 128, 0) },
+	{ "m25p128", INFO(JEDEC_ID(0x202018, 0, 0), 256 * 1024,  64, 0) },
+
+	{ "m25p05-nonjedec",  INFO_FULL(NONE_ID(),  32 * 1024,   2, 256, 0, 0) },
+	{ "m25p10-nonjedec",  INFO_FULL(NONE_ID(),  32 * 1024,   4, 256, 0, 0) },
+	{ "m25p20-nonjedec",  INFO_FULL(NONE_ID(),  64 * 1024,   4, 256, 0, 0) },
+	{ "m25p40-nonjedec",  INFO_FULL(NONE_ID(),  64 * 1024,   8, 256, 0, 0) },
+	{ "m25p80-nonjedec",  INFO_FULL(NONE_ID(),  64 * 1024,  16, 256, 0, 0) },
+	{ "m25p16-nonjedec",  INFO_FULL(NONE_ID(),  64 * 1024,  32, 256, 0, 0) },
+	{ "m25p32-nonjedec",  INFO_FULL(NONE_ID(),  64 * 1024,  64, 256, 0, 0) },
+	{ "m25p64-nonjedec",  INFO_FULL(NONE_ID(),  64 * 1024, 128, 256, 0, 0) },
+	{ "m25p128-nonjedec", INFO_FULL(NONE_ID(), 256 * 1024,  64, 256, 0, 0) },
+
+	{ "m45pe10", INFO(JEDEC_ID(0x204011, 0, 0), 64 * 1024,    2, 0) },
+	{ "m45pe80", INFO(JEDEC_ID(0x204014, 0, 0), 64 * 1024,   16, 0) },
+	{ "m45pe16", INFO(JEDEC_ID(0x204015, 0, 0), 64 * 1024,   32, 0) },
+
+	{ "m25pe20", INFO(JEDEC_ID(0x208012, 0, 0), 64 * 1024,  4,       0) },
+	{ "m25pe80", INFO(JEDEC_ID(0x208014, 0, 0), 64 * 1024, 16,       0) },
+	{ "m25pe16", INFO(JEDEC_ID(0x208015, 0, 0), 64 * 1024, 32, SECT_4K) },
+
+	{ "m25px16",    INFO(JEDEC_ID(0x207115, 0, 0), 64 * 1024, 32, SECT_4K) },
+	{ "m25px32",    INFO(JEDEC_ID(0x207116, 0, 0), 64 * 1024, 64, SECT_4K) },
+	{ "m25px32-s0", INFO(JEDEC_ID(0x207316, 0, 0), 64 * 1024, 64, SECT_4K) },
+	{ "m25px32-s1", INFO(JEDEC_ID(0x206316, 0, 0), 64 * 1024, 64, SECT_4K) },
+	{ "m25px64",    INFO(JEDEC_ID(0x207117, 0, 0), 64 * 1024, 128, 0) },
+	{ "m25px80",    INFO(JEDEC_ID(0x207114, 0, 0), 64 * 1024, 16, 0) },
 
 	/* Winbond -- w25x "blocks" are 64K, "sectors" are 4KiB */
-	{ "w25x05", INFO(0xef3010, 0, 64 * 1024,  1,  SECT_4K) },
-	{ "w25x10", INFO(0xef3011, 0, 64 * 1024,  2,  SECT_4K) },
-	{ "w25x20", INFO(0xef3012, 0, 64 * 1024,  4,  SECT_4K) },
-	{ "w25x40", INFO(0xef3013, 0, 64 * 1024,  8,  SECT_4K) },
-	{ "w25x80", INFO(0xef3014, 0, 64 * 1024,  16, SECT_4K) },
-	{ "w25x16", INFO(0xef3015, 0, 64 * 1024,  32, SECT_4K) },
-	{ "w25x32", INFO(0xef3016, 0, 64 * 1024,  64, SECT_4K) },
-	{ "w25q32", INFO(0xef4016, 0, 64 * 1024,  64, SECT_4K) },
+	{ "w25x05", INFO(JEDEC_ID(0xef3010, 0, 0), 64 * 1024,  1,  SECT_4K) },
+	{ "w25x10", INFO(JEDEC_ID(0xef3011, 0, 0), 64 * 1024,  2,  SECT_4K) },
+	{ "w25x20", INFO(JEDEC_ID(0xef3012, 0, 0), 64 * 1024,  4,  SECT_4K) },
+	{ "w25x40", INFO(JEDEC_ID(0xef3013, 0, 0), 64 * 1024,  8,  SECT_4K) },
+	{ "w25x80", INFO(JEDEC_ID(0xef3014, 0, 0), 64 * 1024,  16, SECT_4K) },
+	{ "w25x16", INFO(JEDEC_ID(0xef3015, 0, 0), 64 * 1024,  32, SECT_4K) },
+	{ "w25x32", INFO(JEDEC_ID(0xef3016, 0, 0), 64 * 1024,  64, SECT_4K) },
+	{ "w25q32", INFO(JEDEC_ID(0xef4016, 0, 0), 64 * 1024,  64, SECT_4K) },
 	{
-		"w25q32dw", INFO(0xef6016, 0, 64 * 1024,  64,
+		"w25q32dw", INFO(JEDEC_ID(0xef6016, 0, 0), 64 * 1024,  64,
 			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
 	},
-	{ "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) },
-	{ "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) },
+	{ "w25x64", INFO(JEDEC_ID(0xef3017, 0, 0), 64 * 1024, 128, SECT_4K) },
+	{ "w25q64", INFO(JEDEC_ID(0xef4017, 0, 0), 64 * 1024, 128, SECT_4K) },
 	{
-		"w25q64dw", INFO(0xef6017, 0, 64 * 1024, 128,
+		"w25q64dw", INFO(JEDEC_ID(0xef6017, 0, 0), 64 * 1024, 128,
 			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
 	},
 	{
-		"w25q128fw", INFO(0xef6018, 0, 64 * 1024, 256,
+		"w25q128fw", INFO(JEDEC_ID(0xef6018, 0, 0), 64 * 1024, 256,
 			SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
 			SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB)
 	},
-	{ "w25q80", INFO(0xef5014, 0, 64 * 1024,  16, SECT_4K) },
-	{ "w25q80bl", INFO(0xef4014, 0, 64 * 1024,  16, SECT_4K) },
-	{ "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
-	{ "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K) },
+	{ "w25q80",   INFO(JEDEC_ID(0xef5014, 0, 0), 64 * 1024,  16, SECT_4K) },
+	{ "w25q80bl", INFO(JEDEC_ID(0xef4014, 0, 0), 64 * 1024,  16, SECT_4K) },
+	{ "w25q128",  INFO(JEDEC_ID(0xef4018, 0, 0), 64 * 1024, 256, SECT_4K) },
+	{ "w25q256",  INFO(JEDEC_ID(0xef4019, 0, 0), 64 * 1024, 512, SECT_4K) },
 
 	/* Catalyst / On Semiconductor -- non-JEDEC */
-	{ "cat25c11", CAT25_INFO(  16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
-	{ "cat25c03", CAT25_INFO(  32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
-	{ "cat25c09", CAT25_INFO( 128, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
-	{ "cat25c17", CAT25_INFO( 256, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
-	{ "cat25128", CAT25_INFO(2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "cat25c11", INFO_FULL(NONE_ID(),   16, 8, 16, 1, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "cat25c03", INFO_FULL(NONE_ID(),   32, 8, 16, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "cat25c09", INFO_FULL(NONE_ID(),  128, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "cat25c17", INFO_FULL(NONE_ID(),  256, 8, 32, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
+	{ "cat25128", INFO_FULL(NONE_ID(), 2048, 8, 64, 2, SPI_NOR_NO_ERASE | SPI_NOR_NO_FR) },
 
 	/* Xilinx S3AN Internal Flash */
-	{ "3S50AN", S3AN_INFO(0x1f2200, 64, 264) },
-	{ "3S200AN", S3AN_INFO(0x1f2400, 256, 264) },
-	{ "3S400AN", S3AN_INFO(0x1f2400, 256, 264) },
-	{ "3S700AN", S3AN_INFO(0x1f2500, 512, 264) },
-	{ "3S1400AN", S3AN_INFO(0x1f2600, 512, 528) },
+	{ "3S50AN",   INFO_S3AN(JEDEC_ID(0x1f2200, 0, 0), 64, 264) },
+	{ "3S200AN",  INFO_S3AN(JEDEC_ID(0x1f2400, 0, 0), 256, 264) },
+	{ "3S400AN",  INFO_S3AN(JEDEC_ID(0x1f2400, 0, 0), 256, 264) },
+	{ "3S700AN",  INFO_S3AN(JEDEC_ID(0x1f2500, 0, 0), 512, 264) },
+	{ "3S1400AN", INFO_S3AN(JEDEC_ID(0x1f2600, 0, 0), 512, 528) },
 	{ },
 };
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 3/3] mtd: spi-nor: s25fl512s: Set a page size of 512
  2017-02-14 15:35             ` [PATCH v2 0/3] " mark.marshall
  2017-02-14 15:35               ` [PATCH v2 1/3] " mark.marshall
  2017-02-14 15:35               ` [PATCH v2 2/3] mtd: spi-nor: Use more explicit macros to generate the flash_info table mark.marshall
@ 2017-02-14 15:35               ` mark.marshall
  2017-08-01 16:49                 ` Cyrille Pitchen
  2 siblings, 1 reply; 12+ messages in thread
From: mark.marshall @ 2017-02-14 15:35 UTC (permalink / raw)
  To: computersforpeace, linux-mtd, cyrille.pitchen, marek.vasut
  Cc: markmarshall14, dwmw2, richard, boris.brezillon, Mark Marshall

From: Mark Marshall <mark.marshall@omicronenergy.com>

This device has a write page size of 512.  Changing this from 256 to 512
almost doubles the write performance of the flash.

Signed-off-by: Mark Marshall <mark.marshall@omicronenergy.com>
---
 drivers/mtd/spi-nor/spi-nor.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
index 467dc93..ba4d7b7 100644
--- a/drivers/mtd/spi-nor/spi-nor.c
+++ b/drivers/mtd/spi-nor/spi-nor.c
@@ -1056,6 +1056,8 @@ static const struct flash_info spi_nor_ids[] = {
 	{ "s25fl256s0", INFO(JEDEC_ID(0x010219, 0x4d00, 2), 256 * 1024, 128, 0) },
 	{ "s25fl256s1", INFO(JEDEC_ID(0x010219, 0x4d01, 2),  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 	{ "s25fl512s",  INFO(JEDEC_ID(0x010220, 0x4d00, 2), 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
+	{ "s25fl512s",  INFO_FULL(JEDEC_ID(0x010220, 0x4d00, 2),
+				  256 * 1024, 256, 512, 0, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 	{ "s70fl01gs",  INFO(JEDEC_ID(0x010221, 0x4d00, 2), 256 * 1024, 256, 0) },
 	{ "s25sl12800", INFO(JEDEC_ID(0x012018, 0x0300, 2), 256 * 1024,  64, 0) },
 	{ "s25sl12801", INFO(JEDEC_ID(0x012018, 0x0301, 2),  64 * 1024, 256, 0) },
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 3/3] mtd: spi-nor: s25fl512s: Set a page size of 512
  2017-02-14 15:35               ` [PATCH v2 3/3] mtd: spi-nor: s25fl512s: Set a page size of 512 mark.marshall
@ 2017-08-01 16:49                 ` Cyrille Pitchen
  0 siblings, 0 replies; 12+ messages in thread
From: Cyrille Pitchen @ 2017-08-01 16:49 UTC (permalink / raw)
  To: mark.marshall, computersforpeace, linux-mtd, cyrille.pitchen,
	marek.vasut
  Cc: richard, dwmw2, markmarshall14, boris.brezillon

Hi Mark,

Le 14/02/2017 à 16:35, mark.marshall@omicronenergy.com a écrit :
> From: Mark Marshall <mark.marshall@omicronenergy.com>
> 
> This device has a write page size of 512.  Changing this from 256 to 512
> almost doubles the write performance of the flash.

This issue should be fixed now parsing the SFDP tables of the s25fl512s
memory part. Indeed bits[7:4] of DWORD11 in the Basic Flash Parameter
Table encode the actual page size for Page Program operations.

This value overrides the one read from info->page_size.

Best regards,

Cyrille

> 
> Signed-off-by: Mark Marshall <mark.marshall@omicronenergy.com>
> ---
>  drivers/mtd/spi-nor/spi-nor.c | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c
> index 467dc93..ba4d7b7 100644
> --- a/drivers/mtd/spi-nor/spi-nor.c
> +++ b/drivers/mtd/spi-nor/spi-nor.c
> @@ -1056,6 +1056,8 @@ static const struct flash_info spi_nor_ids[] = {
>  	{ "s25fl256s0", INFO(JEDEC_ID(0x010219, 0x4d00, 2), 256 * 1024, 128, 0) },
>  	{ "s25fl256s1", INFO(JEDEC_ID(0x010219, 0x4d01, 2),  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>  	{ "s25fl512s",  INFO(JEDEC_ID(0x010220, 0x4d00, 2), 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
> +	{ "s25fl512s",  INFO_FULL(JEDEC_ID(0x010220, 0x4d00, 2),
> +				  256 * 1024, 256, 512, 0, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
>  	{ "s70fl01gs",  INFO(JEDEC_ID(0x010221, 0x4d00, 2), 256 * 1024, 256, 0) },
>  	{ "s25sl12800", INFO(JEDEC_ID(0x012018, 0x0300, 2), 256 * 1024,  64, 0) },
>  	{ "s25sl12801", INFO(JEDEC_ID(0x012018, 0x0301, 2),  64 * 1024, 256, 0) },
> 

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2017-08-01 16:49 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-01-24 13:52 [PATCH] m25p80: Use a 512 byte page size for Spansion flash s25fl512s mark.marshall
2017-01-24 16:48 ` Marek Vasut
2017-01-26 14:58   ` Mark Marshall
2017-02-04 22:25     ` Marek Vasut
2017-02-13 13:53       ` [PATCH] mtd: spi-nor: flash_info table, use a u64 for the ID mark.marshall
2017-02-14  5:02         ` Marek Vasut
2017-02-14 10:22           ` Cyrille Pitchen
2017-02-14 15:35             ` [PATCH v2 0/3] " mark.marshall
2017-02-14 15:35               ` [PATCH v2 1/3] " mark.marshall
2017-02-14 15:35               ` [PATCH v2 2/3] mtd: spi-nor: Use more explicit macros to generate the flash_info table mark.marshall
2017-02-14 15:35               ` [PATCH v2 3/3] mtd: spi-nor: s25fl512s: Set a page size of 512 mark.marshall
2017-08-01 16:49                 ` Cyrille Pitchen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.