[PATCH 2/4] mtd: spi-nor: import manufacturer driver concept from Linux
Takahiro Kuwano via B4 Relay
devnull+takahiro.kuwano.infineon.com at kernel.org
Fri Jun 12 07:40:50 CEST 2026
From: Takahiro Kuwano <takahiro.kuwano at infineon.com>
Port spi_nor_manufacturer struct from Linux but ommit 'name' as we don't
print manufacturer name in u-boot, and add 'set_fixups' function pointer
to assign chip specific fixups in manufacturer drivers.Since the u-boot
has size constraint, we should keep having chip-specific fixups in
struct spi_nor instead of flash_info. The 'fixups' and 'set_fixups' are
excluded for tiny.
The manufacturers array and match_id helper are placed in spi-nor-ids.c
as those need to be referred from both core and tiny.
Signed-off-by: Takahiro Kuwano <takahiro.kuwano at infineon.com>
---
drivers/mtd/spi/sf_internal.h | 18 ++++++++++++++++++
drivers/mtd/spi/sfdp.c | 9 +++++++++
drivers/mtd/spi/spi-nor-core.c | 13 +++++++++++++
drivers/mtd/spi/spi-nor-ids.c | 21 +++++++++++++++++++++
drivers/mtd/spi/spi-nor-tiny.c | 4 ++++
include/linux/mtd/spi-nor.h | 2 ++
6 files changed, 67 insertions(+)
diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
index 576617beb70..3b6b51cb11c 100644
--- a/drivers/mtd/spi/sf_internal.h
+++ b/drivers/mtd/spi/sf_internal.h
@@ -97,6 +97,22 @@ struct flash_info {
#define SPI_NOR_OCTAL_DTR_READ BIT(17) /* Flash supports Octal DTR Read */
};
+/**
+ * struct spi_nor_manufacturer - SPI NOR manufacturer object
+ * @parts: array of parts supported by this manufacturer
+ * @nparts: number of entries in the parts array
+ * @fixups: hooks called at various points in time during spi_nor_scan()
+ * @set_fixups: called to assign chip-specific fixups
+ */
+struct spi_nor_manufacturer {
+ const struct flash_info *parts;
+ unsigned int nparts;
+#if !CONFIG_IS_ENABLED(SPI_FLASH_TINY)
+ const struct spi_nor_fixups *fixups;
+ void (*set_fixups)(struct spi_nor *nor);
+#endif
+};
+
extern const struct flash_info spi_nor_ids[];
#define JEDEC_MFR(info) ((info)->id[0])
@@ -143,4 +159,6 @@ int macronix_quad_enable(struct spi_nor *nor);
int spi_nor_hwcaps_read2cmd(u32 hwcaps);
int spansion_no_read_cr_quad_enable(struct spi_nor *nor);
+const struct flash_info *spi_nor_match_id(struct spi_nor *nor, const u8 *id);
+
#endif /* _SF_INTERNAL_H_ */
diff --git a/drivers/mtd/spi/sfdp.c b/drivers/mtd/spi/sfdp.c
index fd545796d50..db9dda12e27 100644
--- a/drivers/mtd/spi/sfdp.c
+++ b/drivers/mtd/spi/sfdp.c
@@ -219,6 +219,15 @@ spi_nor_post_bfpt_fixups(struct spi_nor *nor,
const struct sfdp_bfpt *bfpt,
struct spi_nor_flash_parameter *params)
{
+ int ret;
+
+ if (nor->manufacturer->fixups && nor->manufacturer->fixups->post_bfpt) {
+ ret = nor->manufacturer->fixups->post_bfpt(nor, bfpt_header,
+ bfpt, params);
+ if (ret)
+ return ret;
+ }
+
if (nor->fixups && nor->fixups->post_bfpt)
return nor->fixups->post_bfpt(nor, bfpt_header, bfpt, params);
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index b99a1a45d8f..697e443bf5a 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -1405,6 +1405,10 @@ static const struct flash_info *spi_nor_read_id(struct spi_nor *nor)
return ERR_PTR(tmp);
}
+ info = spi_nor_match_id(nor, id);
+ if (info)
+ return info;
+
info = spi_nor_ids;
for (; info->name; info++) {
if (info->id_len) {
@@ -2190,6 +2194,9 @@ spi_nor_set_pp_settings(struct spi_nor_pp_command *pp,
static void spi_nor_post_sfdp_fixups(struct spi_nor *nor,
struct spi_nor_flash_parameter *params)
{
+ if (nor->manufacturer->fixups && nor->manufacturer->fixups->post_sfdp)
+ nor->manufacturer->fixups->post_sfdp(nor, params);
+
if (nor->fixups && nor->fixups->post_sfdp)
nor->fixups->post_sfdp(nor, params);
}
@@ -2197,6 +2204,9 @@ static void spi_nor_post_sfdp_fixups(struct spi_nor *nor,
static void spi_nor_late_init_fixups(struct spi_nor *nor,
struct spi_nor_flash_parameter *params)
{
+ if (nor->manufacturer->fixups && nor->manufacturer->fixups->late_init)
+ nor->manufacturer->fixups->late_init(nor, params);
+
if (nor->fixups && nor->fixups->late_init)
nor->fixups->late_init(nor, params);
}
@@ -3640,6 +3650,9 @@ int spi_nor_remove(struct spi_nor *nor)
void spi_nor_set_fixups(struct spi_nor *nor)
{
+ if (nor->manufacturer->set_fixups)
+ nor->manufacturer->set_fixups(nor);
+
#ifdef CONFIG_SPI_FLASH_SPANSION
if (JEDEC_MFR(nor->info) == SNOR_MFR_CYPRESS) {
switch (nor->info->id[1]) {
diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c
index c0fa98424aa..45e9b866795 100644
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -723,3 +723,24 @@ const struct flash_info spi_nor_ids[] = {
#endif
{ },
};
+
+static const struct spi_nor_manufacturer *manufacturers[] = {
+};
+
+const struct flash_info *spi_nor_match_id(struct spi_nor *nor, const u8 *id)
+{
+ const struct flash_info *part;
+ unsigned int i, j;
+
+ for (i = 0; i < ARRAY_SIZE(manufacturers); i++) {
+ for (j = 0; j < manufacturers[i]->nparts; j++) {
+ part = &manufacturers[i]->parts[j];
+ if (!memcmp(part->id, id, part->id_len)) {
+ nor->manufacturer = manufacturers[i];
+ return part;
+ }
+ }
+ }
+
+ return NULL;
+}
diff --git a/drivers/mtd/spi/spi-nor-tiny.c b/drivers/mtd/spi/spi-nor-tiny.c
index cf00473ee83..c7824285191 100644
--- a/drivers/mtd/spi/spi-nor-tiny.c
+++ b/drivers/mtd/spi/spi-nor-tiny.c
@@ -383,6 +383,10 @@ static const struct flash_info *spi_nor_read_id(struct spi_nor *nor)
return ERR_PTR(tmp);
}
+ info = spi_nor_match_id(nor, id);
+ if (info)
+ return info;
+
info = spi_nor_ids;
for (; info->sector_size != 0; info++) {
if (info->id_len) {
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 4eef4ab0488..08567a80472 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -508,6 +508,7 @@ struct spi_flash {
* @lock: the lock for the read/write/erase/lock/unlock operations
* @dev: point to a spi device, or a spi nor controller device.
* @info: spi-nor part JDEC MFR id and other info
+ * @manufacturer: SPI NOR manufacturer
* @manufacturer_sfdp: manufacturer specific SFDP table
* @page_size: the page size of the SPI NOR
* @addr_width: number of address bytes
@@ -559,6 +560,7 @@ struct spi_nor {
struct udevice *dev;
struct spi_slave *spi;
const struct flash_info *info;
+ const struct spi_nor_manufacturer *manufacturer;
u8 *manufacturer_sfdp;
u32 page_size;
u8 addr_width;
--
2.43.0
More information about the U-Boot
mailing list