summaryrefslogtreecommitdiff
path: root/drivers/mtd/spi-nor/core.h
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2023-11-04 11:04:30 -1000
committerLinus Torvalds <torvalds@linux-foundation.org>2023-11-04 11:04:30 -1000
commitb1dfbda8636b54cde21f9f5d352fd25c4deff584 (patch)
tree98b3527c78f1d87488f7dc6fca0921aafd42fe92 /drivers/mtd/spi-nor/core.h
parente70703890b2586bc3567365d391c260d23fb7a94 (diff)
parent6d55d31e927eec68ba6db344688044ed253223e9 (diff)
Merge tag 'mtd/for-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux
Pull mtd updates from Miquel Raynal: "The main set of changes is related to Uwe's work converting platform remove callbacks to return void. Comes next (in number of changes) Kees' additional structures annotations to improve the sanitizers. The usual amount of cleanups apply. About the more substancial contribution, one main function of the partitions core could return an error which was not checked, this is now fixed. On the bindings side, fixed partitions can now have a compression property. Finally, an erroneous situation is now always avoided in the MAP RAM driver. CFI: - A several years old byte swap has been fixed. NAND: - The subsystem has, as usual, seen a bit of cleanup being done this cycle, typically return values of platform_get_irq() and devm_kasprintf(). There is also a better ECC check in the Arasan driver. This comes with smaller misc changes. - In the SPI-NAND world there is now support for Foresee F35SQA002G, Winbond W25N and XTX XT26 chips. SPI NOR: - For SPI NOR we cleaned the flash info entries in order to have them slimmer and self explanatory. In order to make the entries as slim as possible, we introduced sane default values so that the actual flash entries don't need to specify them. We now use a flexible macro to specify the flash ID instead of the previous INFOx() macros that had hardcoded ID lengths. Instead of: { "w25q512nwm", INFO(0xef8020, 0, 64 * 1024, 0) OTP_INFO(256, 3, 0x1000, 0x1000) }, We now use: .id = SNOR_ID(0xef, 0x80, 0x20), .name = "w25q512nwm", .otp = SNOR_OTP(256, 3, 0x1000, 0x1000), - We also removed some flash entries: the very old Catalyst SPI EEPROMs that were introduced once with the SPI-NOR subsystem, and a Fujitsu MRAM. Both should use the at25 EEPROM driver. The latter even has device tree bindings for the at25 driver. - We made sure that the conversion didn't introduce any unwanted changes by comparing the .rodata segment before and after the conversion. The patches landed in linux-next immediately after v6.6-rc2, we haven't seen any regressions yet. - Apart of the autumn cleaning we introduced a new flash entry, at25ff321a, and added block protection support for mt25qu512a" * tag 'mtd/for-6.7' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux: (91 commits) mtd: cfi_cmdset_0001: Byte swap OTP info mtd: rawnand: meson: check return value of devm_kasprintf() mtd: rawnand: intel: check return value of devm_kasprintf() mtd: rawnand: sh_flctl: Convert to module_platform_driver() mtd: spi-nor: micron-st: use SFDP table for mt25qu512a mtd: spi-nor: micron-st: enable lock/unlock for mt25qu512a mtd: rawnand: Remove unused of_gpio.h inclusion mtd: spinand: Add support for XTX XT26xxxDxxxxx mtd: spinand: winbond: add support for serial NAND flash mtd: rawnand: cadence: Annotate struct cdns_nand_chip with __counted_by mtd: rawnand: Annotate struct mtk_nfc_nand_chip with __counted_by mtd: spinand: add support for FORESEE F35SQA002G mtd: rawnand: rockchip: Use struct_size() mtd: rawnand: arasan: Include ECC syndrome along with in-band data while checking for ECC failure mtd: Use device_get_match_data() mtd: spi-nor: nxp-spifi: Convert to platform remove callback returning void mtd: spi-nor: hisi-sfc: Convert to platform remove callback returning void mtd: maps: sun_uflash: Convert to platform remove callback returning void mtd: maps: sa1100-flash: Convert to platform remove callback returning void mtd: maps: pxa2xx-flash: Convert to platform remove callback returning void ...
Diffstat (limited to 'drivers/mtd/spi-nor/core.h')
-rw-r--r--drivers/mtd/spi-nor/core.h138
1 files changed, 61 insertions, 77 deletions
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 9217379b9cfe..93cd2fc3606d 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -10,6 +10,13 @@
#include "sfdp.h"
#define SPI_NOR_MAX_ID_LEN 6
+/*
+ * 256 bytes is a sane default for most older flashes. Newer flashes will
+ * have the page size defined within their SFDP tables.
+ */
+#define SPI_NOR_DEFAULT_PAGE_SIZE 256
+#define SPI_NOR_DEFAULT_N_BANKS 1
+#define SPI_NOR_DEFAULT_SECTOR_SIZE SZ_64K
/* Standard SPI NOR flash operations. */
#define SPI_NOR_READID_OP(naddr, ndummy, buf, len) \
@@ -353,6 +360,7 @@ struct spi_nor_otp {
* in octal DTR mode.
* @rdsr_addr_nbytes: dummy address bytes needed for Read Status Register
* command in octal DTR mode.
+ * @n_banks: number of banks.
* @n_dice: number of dice in the flash memory.
* @vreg_offset: volatile register offset for each die.
* @hwcaps: describes the read and page program hardware
@@ -389,6 +397,7 @@ struct spi_nor_flash_parameter {
u8 addr_mode_nbytes;
u8 rdsr_dummy;
u8 rdsr_addr_nbytes;
+ u8 n_banks;
u8 n_dice;
u32 *vreg_offset;
@@ -438,21 +447,31 @@ struct spi_nor_fixups {
};
/**
+ * struct spi_nor_id - SPI NOR flash ID.
+ *
+ * @bytes: the bytes returned by the flash when issuing command 9F. Typically,
+ * the first byte is the manufacturer ID code (see JEP106) and the next
+ * two bytes are a flash part specific ID.
+ * @len: the number of bytes of ID.
+ */
+struct spi_nor_id {
+ const u8 *bytes;
+ u8 len;
+};
+
+/**
* struct flash_info - SPI NOR flash_info entry.
+ * @id: pointer to struct spi_nor_id or NULL, which means "no ID" (mostly
+ * older chips).
* @name: the name of the flash.
- * @id: the flash's ID bytes. The first three bytes are the
- * JEDIC ID. JEDEC ID zero means "no ID" (mostly older chips).
- * @id_len: the number of bytes of ID.
- * @sector_size: the size listed here is what works with SPINOR_OP_SE, which
- * isn't necessarily called a "sector" by the vendor.
- * @n_sectors: the number of sectors.
- * @n_banks: the number of banks.
- * @page_size: the flash's page size.
+ * @size: the size of the flash in bytes.
+ * @sector_size: (optional) the size listed here is what works with
+ * SPINOR_OP_SE, which isn't necessarily called a "sector" by
+ * the vendor. Defaults to 64k.
+ * @n_banks: (optional) the number of banks. Defaults to 1.
+ * @page_size: (optional) the flash's page size. Defaults to 256.
* @addr_nbytes: number of address bytes to send.
*
- * @parse_sfdp: true when flash supports SFDP tables. The false value has no
- * meaning. If one wants to skip the SFDP tables, one should
- * instead use the SPI_NOR_SKIP_SFDP sfdp_flag.
* @flags: flags that indicate support that is not defined by the
* JESD216 standard in its SFDP tables. Flag meanings:
* SPI_NOR_HAS_LOCK: flash supports lock/unlock via SR
@@ -503,15 +522,13 @@ struct spi_nor_fixups {
*/
struct flash_info {
char *name;
- u8 id[SPI_NOR_MAX_ID_LEN];
- u8 id_len;
+ const struct spi_nor_id *id;
+ size_t size;
unsigned sector_size;
- u16 n_sectors;
u16 page_size;
u8 n_banks;
u8 addr_nbytes;
- bool parse_sfdp;
u16 flags;
#define SPI_NOR_HAS_LOCK BIT(0)
#define SPI_NOR_HAS_TB BIT(1)
@@ -540,70 +557,23 @@ struct flash_info {
u8 mfr_flags;
- const struct spi_nor_otp_organization otp_org;
+ const struct spi_nor_otp_organization *otp;
const struct spi_nor_fixups *fixups;
};
-#define SPI_NOR_ID_2ITEMS(_id) ((_id) >> 8) & 0xff, (_id) & 0xff
-#define SPI_NOR_ID_3ITEMS(_id) ((_id) >> 16) & 0xff, SPI_NOR_ID_2ITEMS(_id)
-
-#define SPI_NOR_ID(_jedec_id, _ext_id) \
- .id = { SPI_NOR_ID_3ITEMS(_jedec_id), SPI_NOR_ID_2ITEMS(_ext_id) }, \
- .id_len = !(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))
-
-#define SPI_NOR_ID6(_jedec_id, _ext_id) \
- .id = { SPI_NOR_ID_3ITEMS(_jedec_id), SPI_NOR_ID_3ITEMS(_ext_id) }, \
- .id_len = 6
-
-#define SPI_NOR_GEOMETRY(_sector_size, _n_sectors, _n_banks) \
- .sector_size = (_sector_size), \
- .n_sectors = (_n_sectors), \
- .page_size = 256, \
- .n_banks = (_n_banks)
-
-/* Used when the "_ext_id" is two bytes at most */
-#define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors) \
- SPI_NOR_ID((_jedec_id), (_ext_id)), \
- SPI_NOR_GEOMETRY((_sector_size), (_n_sectors), 1),
-
-#define INFOB(_jedec_id, _ext_id, _sector_size, _n_sectors, _n_banks) \
- SPI_NOR_ID((_jedec_id), (_ext_id)), \
- SPI_NOR_GEOMETRY((_sector_size), (_n_sectors), (_n_banks)),
-
-#define INFO6(_jedec_id, _ext_id, _sector_size, _n_sectors) \
- SPI_NOR_ID6((_jedec_id), (_ext_id)), \
- SPI_NOR_GEOMETRY((_sector_size), (_n_sectors), 1),
+#define SNOR_ID(...) \
+ (&(const struct spi_nor_id){ \
+ .bytes = (const u8[]){ __VA_ARGS__ }, \
+ .len = sizeof((u8[]){ __VA_ARGS__ }), \
+ })
-#define CAT25_INFO(_sector_size, _n_sectors, _page_size, _addr_nbytes) \
- .sector_size = (_sector_size), \
- .n_sectors = (_n_sectors), \
- .page_size = (_page_size), \
- .n_banks = 1, \
- .addr_nbytes = (_addr_nbytes), \
- .flags = SPI_NOR_NO_ERASE | SPI_NOR_NO_FR, \
-
-#define OTP_INFO(_len, _n_regions, _base, _offset) \
- .otp_org = { \
- .len = (_len), \
- .base = (_base), \
- .offset = (_offset), \
- .n_regions = (_n_regions), \
- },
-
-#define PARSE_SFDP \
- .parse_sfdp = true, \
-
-#define FLAGS(_flags) \
- .flags = (_flags), \
-
-#define NO_SFDP_FLAGS(_no_sfdp_flags) \
- .no_sfdp_flags = (_no_sfdp_flags), \
-
-#define FIXUP_FLAGS(_fixup_flags) \
- .fixup_flags = (_fixup_flags), \
-
-#define MFR_FLAGS(_mfr_flags) \
- .mfr_flags = (_mfr_flags), \
+#define SNOR_OTP(_len, _n_regions, _base, _offset) \
+ (&(const struct spi_nor_otp_organization){ \
+ .len = (_len), \
+ .base = (_base), \
+ .offset = (_offset), \
+ .n_regions = (_n_regions), \
+ })
/**
* struct spi_nor_manufacturer - SPI NOR manufacturer object
@@ -631,11 +601,9 @@ struct sfdp {
/* Manufacturer drivers. */
extern const struct spi_nor_manufacturer spi_nor_atmel;
-extern const struct spi_nor_manufacturer spi_nor_catalyst;
extern const struct spi_nor_manufacturer spi_nor_eon;
extern const struct spi_nor_manufacturer spi_nor_esmt;
extern const struct spi_nor_manufacturer spi_nor_everspin;
-extern const struct spi_nor_manufacturer spi_nor_fujitsu;
extern const struct spi_nor_manufacturer spi_nor_gigadevice;
extern const struct spi_nor_manufacturer spi_nor_intel;
extern const struct spi_nor_manufacturer spi_nor_issi;
@@ -734,6 +702,22 @@ static inline struct spi_nor *mtd_to_spi_nor(struct mtd_info *mtd)
return container_of(mtd, struct spi_nor, mtd);
}
+/**
+ * spi_nor_needs_sfdp() - returns true if SFDP parsing is used for this flash.
+ *
+ * Return: true if SFDP parsing is needed
+ */
+static inline bool spi_nor_needs_sfdp(const struct spi_nor *nor)
+{
+ /*
+ * The flash size is one property parsed by the SFDP. We use it as an
+ * indicator whether we need SFDP parsing for a particular flash. I.e.
+ * non-legacy flash entries in flash_info will have a size of zero iff
+ * SFDP should be used.
+ */
+ return !nor->info->size;
+}
+
#ifdef CONFIG_DEBUG_FS
void spi_nor_debugfs_register(struct spi_nor *nor);
void spi_nor_debugfs_shutdown(void);