Pull MTD updates from Miquel Raynal: "MTD core changes: - Fix issue where write_cached_data() fails but write() still returns success - maps: sa1100-flash: Replace zero-length array with flexible-array member - phram: Fix a double free issue in error path - Convert fallthrough comments into statements - MAINTAINERS: Add the IRC channel to the MTD related subsystems Raw NAND core changes: - Add support for manufacturer specific suspend/resume operation - Add support for manufacturer specific lock/unlock operation - Replace zero-length array with flexible-array member - Fix a typo ("manufecturer") - Ensure nand_soft_waitrdy wait period is enough Raw NAND controller driver changes: - Brcmnand: * Add support for flash-edu for dma transfers (+ bindings) - Cadence: * Reinit completion before executing a new command * Change bad block marker size * Fix the calculation of the avaialble OOB size * Get meta data size from registers - Qualcom: * Use dma_request_chan() instead dma_request_slave_channel() * Release resources on failure within qcom_nandc_alloc() - Allwinner: * Use dma_request_chan() instead dma_request_slave_channel() - Marvell: * Use dma_request_chan() instead dma_request_slave_channel() * Release DMA channel on error - Freescale: * Use dma_request_chan() instead dma_request_slave_channel() - Macronix: * Add support for Macronix NAND randomizer (+ bindings) - Ams-delta: * Rename structures and functions to gpio_nand* * Make the driver custom I/O ready * Drop useless local variable * Support custom driver initialisation * Add module device tables * Handle more GPIO pins as optional * Make read pulses optional * Don't hardcode read/write pulse widths * Push inversion handling to gpiolib * Enable OF partition info support * Drop board specific partition info * Use struct gpio_nand_platdata * Write protect device during probe - Ingenic: * Use devm_platform_ioremap_resource() * Add dependency on MIPS || COMPILE_TEST - Denali: * Deassert write protect pin - ST: * Use dma_request_chan() instead dma_request_slave_channel() Raw NAND chip driver changes: - Toshiba: * Support reading the number of bitflips for BENAND (Built-in ECC NAND) - Macronix: * Add support for deep power down mode * Add support for block protection SPI-NAND core changes: - Do not erase the block before writing a bad block marker - Explicitly use MTD_OPS_RAW to write the bad block marker to OOB - Stop using spinand->oobbuf for buffering bad block markers - Rework detect procedure for different READ_ID operation SPI-NAND driver changes: - Toshiba: * Support for new Kioxia Serial NAND * Rename function name to change suffix and prefix (8Gbit) * Add comment about Kioxia ID - Micron: * Add new Micron SPI NAND devices with multiple dies * Add M70A series Micron SPI NAND devices * identify SPI NAND device with Continuous Read mode * Add new Micron SPI NAND devices * Describe the SPI NAND device MT29F2G01ABAGD * Generalize the OOB layout structure and function names SPI NOR core changes: - Move all the manufacturer specific quirks/code out of the core, to make the core logic more readable and thus ease maintenance. - Move the SFDP logic out of the core, it provides a better separation between the SFDP parsing and core logic. - Trim what is exposed in spi-nor.h. The SPI NOR controllers drivers must not be able to use structures that are meant just for the SPI NOR core. - Use the spi-mem direct mapping API to let advanced controllers optimize the read/write operations when they support direct mapping. - Add generic formula for the Status Register block protection handling. It fixes some long standing locking limitations and eases the addition of the 4bit block protection support. - Add block protection support for flashes with 4 block protection bits in the Status Register. SPI NOR controller drivers changes: - The mtk-quadspi driver is replaced by the new spi-mem spi-mtk-nor driver. - Merge tag 'mtk-mtd-spi-move' into spi-nor/next to avoid conflicts. HyperBus changes: - Print error msg when compatible is wrong or missing - Move mapping of direct access window from core to individual drivers" * tag 'mtd/for-5.7' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux: (103 commits) mtd: Convert fallthrough comments into statements mtd: rawnand: toshiba: Support reading the number of bitflips for BENAND (Built-in ECC NAND) MAINTAINERS: Add the IRC channel to the MTD related subsystems mtd: Fix issue where write_cached_data() fails but write() still returns success mtd: maps: sa1100-flash: Replace zero-length array with flexible-array member mtd: phram: fix a double free issue in error path mtd: spinand: toshiba: Support for new Kioxia Serial NAND mtd: spinand: toshiba: Rename function name to change suffix and prefix (8Gbit) mtd: rawnand: macronix: Add support for deep power down mode mtd: rawnand: Add support for manufacturer specific suspend/resume operation mtd: spi-nor: Enable locking for n25q512ax3/n25q512a mtd: spi-nor: Add SR 4bit block protection support mtd: spi-nor: Add generic formula for SR block protection handling mtd: spi-nor: Set all BP bits to one when lock_len == mtd->size mtd: spi-nor: controllers: aspeed-smc: Replace zero-length array with flexible-array member mtd: spi-nor: Clear WEL bit when erase or program errors occur MAINTAINERS: update entry after SPI NOR controller move mtd: spi-nor: Trim what is exposed in spi-nor.h mtd: spi-nor: Drop the MFR definitions mtd: spi-nor: Get rid of the now empty spi_nor_ids[] table ...
Showing the changes to include/linux (5 of 95 files). Show all
Unified · Split
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | |
| 9 | 9 | #include <linux/types.h> |
| 10 | 10 | #include <linux/uio.h> |
| 11 | +#include <linux/list.h> | |
| 11 | 12 | #include <linux/notifier.h> |
| 12 | 13 | #include <linux/device.h> |
| 13 | 14 | #include <linux/of.h> |
| @@ -194,10 +195,43 @@ struct mtd_debug_info { · 180 unmodified lines | ||
| 194 | 195 | const char *partid; |
| 195 | 196 | }; |
| 196 | 197 | |
| 198 | +/** | |
| 199 | + * struct mtd_part - MTD partition specific fields | |
| 200 | + * | |
| 201 | + * @node: list node used to add an MTD partition to the parent partition list | |
| 202 | + * @offset: offset of the partition relatively to the parent offset | |
| 203 | + * @flags: original flags (before the mtdpart logic decided to tweak them based | |
| 204 | + * on flash constraints, like eraseblock/pagesize alignment) | |
| 205 | + * | |
| 206 | + * This struct is embedded in mtd_info and contains partition-specific | |
| 207 | + * properties/fields. | |
| 208 | + */ | |
| 209 | +struct mtd_part { | |
| 210 | + struct list_head node; | |
| 211 | + u64 offset; | |
| 212 | + u32 flags; | |
| 213 | +}; | |
| 214 | + | |
| 215 | +/** | |
| 216 | + * struct mtd_master - MTD master specific fields | |
| 217 | + * | |
| 218 | + * @partitions_lock: lock protecting accesses to the partition list. Protects | |
| 219 | + * not only the master partition list, but also all | |
| 220 | + * sub-partitions. | |
| 221 | + * @suspended: et to 1 when the device is suspended, 0 otherwise | |
| 222 | + * | |
| 223 | + * This struct is embedded in mtd_info and contains master-specific | |
| 224 | + * properties/fields. The master is the root MTD device from the MTD partition | |
| 225 | + * point of view. | |
| 226 | + */ | |
| 227 | +struct mtd_master { | |
| 228 | + struct mutex partitions_lock; | |
| 229 | + unsigned int suspended : 1; | |
| 230 | +}; | |
| 231 | + | |
| 197 | 232 | struct mtd_info { |
| 198 | 233 | u_char type; |
| 199 | 234 | uint32_t flags; |
| 200 | − uint32_t orig_flags; /* Flags as before running mtd checks */ | |
| 201 | 235 | uint64_t size; // Total size of the MTD |
| 202 | 236 | |
| 203 | 237 | /* "Major" erase size for the device. Naïve users may take this |
| @@ -339,8 +373,52 @@ struct mtd_info { · 135 unmodified lines | ||
| 339 | 373 | int usecount; |
| 340 | 374 | struct mtd_debug_info dbg; |
| 341 | 375 | struct nvmem_device *nvmem; |
| 376 | + | |
| 377 | + /* | |
| 378 | + * Parent device from the MTD partition point of view. | |
| 379 | + * | |
| 380 | + * MTD masters do not have any parent, MTD partitions do. The parent | |
| 381 | + * MTD device can itself be a partition. | |
| 382 | + */ | |
| 383 | + struct mtd_info *parent; | |
| 384 | + | |
| 385 | + /* List of partitions attached to this MTD device */ | |
| 386 | + struct list_head partitions; | |
| 387 | + | |
| 388 | + union { | |
| 389 | + struct mtd_part part; | |
| 390 | + struct mtd_master master; | |
| 391 | + }; | |
| 342 | 392 | }; |
| 343 | 393 | |
| 394 | +static inline struct mtd_info *mtd_get_master(struct mtd_info *mtd) | |
| 395 | +{ | |
| 396 | + while (mtd->parent) | |
| 397 | + mtd = mtd->parent; | |
| 398 | + | |
| 399 | + return mtd; | |
| 400 | +} | |
| 401 | + | |
| 402 | +static inline u64 mtd_get_master_ofs(struct mtd_info *mtd, u64 ofs) | |
| 403 | +{ | |
| 404 | + while (mtd->parent) { | |
| 405 | + ofs += mtd->part.offset; | |
| 406 | + mtd = mtd->parent; | |
| 407 | + } | |
| 408 | + | |
| 409 | + return ofs; | |
| 410 | +} | |
| 411 | + | |
| 412 | +static inline bool mtd_is_partition(const struct mtd_info *mtd) | |
| 413 | +{ | |
| 414 | + return mtd->parent; | |
| 415 | +} | |
| 416 | + | |
| 417 | +static inline bool mtd_has_partitions(const struct mtd_info *mtd) | |
| 418 | +{ | |
| 419 | + return !list_empty(&mtd->partitions); | |
| 420 | +} | |
| 421 | + | |
| 344 | 422 | int mtd_ooblayout_ecc(struct mtd_info *mtd, int section, |
| 345 | 423 | struct mtd_oob_region *oobecc); |
| 346 | 424 | int mtd_ooblayout_find_eccregion(struct mtd_info *mtd, int eccbyte, |
| @@ -392,13 +470,16 @@ static inline u32 mtd_oobavail(struct mtd_info *mtd, struct mtd_oob_ops *ops) · 45 unmodified lines | ||
| 392 | 470 | static inline int mtd_max_bad_blocks(struct mtd_info *mtd, |
| 393 | 471 | loff_t ofs, size_t len) |
| 394 | 472 | { |
| 395 | − if (!mtd->_max_bad_blocks) | |
| 473 | + struct mtd_info *master = mtd_get_master(mtd); | |
| 474 | + | |
| 475 | + if (!master->_max_bad_blocks) | |
| 396 | 476 | return -ENOTSUPP; |
| 397 | 477 | |
| 398 | 478 | if (mtd->size < (len + ofs) || ofs < 0) |
| 399 | 479 | return -EINVAL; |
| 400 | 480 | |
| 401 | − return mtd->_max_bad_blocks(mtd, ofs, len); | |
| 481 | + return master->_max_bad_blocks(master, mtd_get_master_ofs(mtd, ofs), | |
| 482 | + len); | |
| 402 | 483 | } |
| 403 | 484 | |
| 404 | 485 | int mtd_wunit_to_pairing_info(struct mtd_info *mtd, int wunit, |
| @@ -439,8 +520,10 @@ int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, · 34 unmodified lines | ||
| 439 | 520 | |
| 440 | 521 | static inline void mtd_sync(struct mtd_info *mtd) |
| 441 | 522 | { |
| 442 | − if (mtd->_sync) | |
| 443 | − mtd->_sync(mtd); | |
| 523 | + struct mtd_info *master = mtd_get_master(mtd); | |
| 524 | + | |
| 525 | + if (master->_sync) | |
| 526 | + master->_sync(master); | |
| 444 | 527 | } |
| 445 | 528 | |
| 446 | 529 | int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len); |
| @@ -452,13 +535,31 @@ int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs); · 5 unmodified lines | ||
| 452 | 535 | |
| 453 | 536 | static inline int mtd_suspend(struct mtd_info *mtd) |
| 454 | 537 | { |
| 455 | − return mtd->_suspend ? mtd->_suspend(mtd) : 0; | |
| 538 | + struct mtd_info *master = mtd_get_master(mtd); | |
| 539 | + int ret; | |
| 540 | + | |
| 541 | + if (master->master.suspended) | |
| 542 | + return 0; | |
| 543 | + | |
| 544 | + ret = master->_suspend ? master->_suspend(master) : 0; | |
| 545 | + if (ret) | |
| 546 | + return ret; | |
| 547 | + | |
| 548 | + master->master.suspended = 1; | |
| 549 | + return 0; | |
| 456 | 550 | } |
| 457 | 551 | |
| 458 | 552 | static inline void mtd_resume(struct mtd_info *mtd) |
| 459 | 553 | { |
| 460 | − if (mtd->_resume) | |
| 461 | − mtd->_resume(mtd); | |
| 554 | + struct mtd_info *master = mtd_get_master(mtd); | |
| 555 | + | |
| 556 | + if (!master->master.suspended) | |
| 557 | + return; | |
| 558 | + | |
| 559 | + if (master->_resume) | |
| 560 | + master->_resume(master); | |
| 561 | + | |
| 562 | + master->master.suspended = 0; | |
| 462 | 563 | } |
| 463 | 564 | |
| 464 | 565 | static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd) |
| @@ -538,7 +639,9 @@ static inline loff_t mtd_wunit_to_offset(struct mtd_info *mtd, loff_t base, · 73 unmodified lines | ||
| 538 | 639 | |
| 539 | 640 | static inline int mtd_has_oob(const struct mtd_info *mtd) |
| 540 | 641 | { |
| 541 | − return mtd->_read_oob && mtd->_write_oob; | |
| 642 | + struct mtd_info *master = mtd_get_master((struct mtd_info *)mtd); | |
| 643 | + | |
| 644 | + return master->_read_oob && master->_write_oob; | |
| 542 | 645 | } |
| 543 | 646 | |
| 544 | 647 | static inline int mtd_type_is_nand(const struct mtd_info *mtd) |
| @@ -548,7 +651,9 @@ static inline int mtd_type_is_nand(const struct mtd_info *mtd) · 3 unmodified lines | ||
| 548 | 651 | |
| 549 | 652 | static inline int mtd_can_have_bb(const struct mtd_info *mtd) |
| 550 | 653 | { |
| 551 | − return !!mtd->_block_isbad; | |
| 654 | + struct mtd_info *master = mtd_get_master((struct mtd_info *)mtd); | |
| 655 | + | |
| 656 | + return !!master->_block_isbad; | |
| 552 | 657 | } |
| 553 | 658 | |
| 554 | 659 | /* Kernel-side ioctl definitions */ |
| @@ -105,7 +105,6 @@ extern void deregister_mtd_parser(struct mtd_part_parser *parser); · 104 unmodified lines | ||
| 105 | 105 | module_driver(__mtd_part_parser, register_mtd_parser, \ |
| 106 | 106 | deregister_mtd_parser) |
| 107 | 107 | |
| 108 | −int mtd_is_partition(const struct mtd_info *mtd); | |
| 109 | 108 | int mtd_add_partition(struct mtd_info *master, const char *name, |
| 110 | 109 | long long offset, long long length); |
| 111 | 110 | int mtd_del_partition(struct mtd_info *master, int partno); |
| @@ -1064,6 +1064,8 @@ struct nand_legacy { · 1063 unmodified lines | ||
| 1064 | 1064 | * @lock: lock protecting the suspended field. Also used to |
| 1065 | 1065 | * serialize accesses to the NAND device. |
| 1066 | 1066 | * @suspended: set to 1 when the device is suspended, 0 when it's not. |
| 1067 | + * @suspend: [REPLACEABLE] specific NAND device suspend operation | |
| 1068 | + * @resume: [REPLACEABLE] specific NAND device resume operation | |
| 1067 | 1069 | * @bbt: [INTERN] bad block table pointer |
| 1068 | 1070 | * @bbt_td: [REPLACEABLE] bad block table descriptor for flash |
| 1069 | 1071 | * lookup. |
| @@ -1077,6 +1079,8 @@ struct nand_legacy { · 7 unmodified lines | ||
| 1077 | 1079 | * @manufacturer: [INTERN] Contains manufacturer information |
| 1078 | 1080 | * @manufacturer.desc: [INTERN] Contains manufacturer's description |
| 1079 | 1081 | * @manufacturer.priv: [INTERN] Contains manufacturer private information |
| 1082 | + * @lock_area: [REPLACEABLE] specific NAND chip lock operation | |
| 1083 | + * @unlock_area: [REPLACEABLE] specific NAND chip unlock operation | |
| 1080 | 1084 | */ |
| 1081 | 1085 | |
| 1082 | 1086 | struct nand_chip { |
| @@ -1117,6 +1121,8 @@ struct nand_chip { · 34 unmodified lines | ||
| 1117 | 1121 | |
| 1118 | 1122 | struct mutex lock; |
| 1119 | 1123 | unsigned int suspended : 1; |
| 1124 | + int (*suspend)(struct nand_chip *chip); | |
| 1125 | + void (*resume)(struct nand_chip *chip); | |
| 1120 | 1126 | |
| 1121 | 1127 | uint8_t *oob_poi; |
| 1122 | 1128 | struct nand_controller *controller; |
| @@ -1136,6 +1142,9 @@ struct nand_chip { · 13 unmodified lines | ||
| 1136 | 1142 | const struct nand_manufacturer *desc; |
| 1137 | 1143 | void *priv; |
| 1138 | 1144 | } manufacturer; |
| 1145 | + | |
| 1146 | + int (*lock_area)(struct nand_chip *chip, loff_t ofs, uint64_t len); | |
| 1147 | + int (*unlock_area)(struct nand_chip *chip, loff_t ofs, uint64_t len); | |
| 1139 | 1148 | }; |
| 1140 | 1149 | |
| 1141 | 1150 | extern const struct mtd_ooblayout_ops nand_ooblayout_sp_ops; |
| @@ -1215,7 +1224,7 @@ static inline struct device_node *nand_get_flash_node(struct nand_chip *chip) · 73 unmodified lines | ||
| 1215 | 1224 | * struct nand_flash_dev - NAND Flash Device ID Structure |
| 1216 | 1225 | * @name: a human-readable name of the NAND chip |
| 1217 | 1226 | * @dev_id: the device ID (the second byte of the full chip ID array) |
| 1218 | − * @mfr_id: manufecturer ID part of the full chip ID array (refers the same | |
| 1227 | + * @mfr_id: manufacturer ID part of the full chip ID array (refers the same | |
| 1219 | 1228 | * memory address as ``id[0]``) |
| 1220 | 1229 | * @dev_id: device ID part of the full chip ID array (refers the same memory |
| 1221 | 1230 | * address as ``id[1]``) |
| @@ -11,23 +11,6 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/mtd/mtd.h> |
| 12 | 12 | #include <linux/spi/spi-mem.h> |
| 13 | 13 | |
| 14 | −/* | |
| 15 | − * Manufacturer IDs | |
| 16 | − * | |
| 17 | − * The first byte returned from the flash after sending opcode SPINOR_OP_RDID. | |
| 18 | − * Sometimes these are the same as CFI IDs, but sometimes they aren't. | |
| 19 | − */ | |
| 20 | −#define SNOR_MFR_ATMEL CFI_MFR_ATMEL | |
| 21 | −#define SNOR_MFR_GIGADEVICE 0xc8 | |
| 22 | −#define SNOR_MFR_INTEL CFI_MFR_INTEL | |
| 23 | −#define SNOR_MFR_ST CFI_MFR_ST /* ST Micro */ | |
| 24 | −#define SNOR_MFR_MICRON CFI_MFR_MICRON /* Micron */ | |
| 25 | −#define SNOR_MFR_ISSI CFI_MFR_PMC | |
| 26 | −#define SNOR_MFR_MACRONIX CFI_MFR_MACRONIX | |
| 27 | −#define SNOR_MFR_SPANSION CFI_MFR_AMD | |
| 28 | −#define SNOR_MFR_SST CFI_MFR_SST | |
| 29 | −#define SNOR_MFR_WINBOND 0xef /* Also used by some Spansion */ | |
| 30 | − | |
| 31 | 14 | /* |
| 32 | 15 | * Note on opcode nomenclature: some opcodes have a format like |
| 33 | 16 | * SPINOR_OP_FUNCTION{4,}_x_y_z. The numbers x, y, and z stand for the number |
| @@ -128,7 +111,9 @@ · 94 unmodified lines | ||
| 128 | 111 | #define SR_BP0 BIT(2) /* Block protect 0 */ |
| 129 | 112 | #define SR_BP1 BIT(3) /* Block protect 1 */ |
| 130 | 113 | #define SR_BP2 BIT(4) /* Block protect 2 */ |
| 114 | +#define SR_BP3 BIT(5) /* Block protect 3 */ | |
| 131 | 115 | #define SR_TB_BIT5 BIT(5) /* Top/Bottom protect */ |
| 116 | +#define SR_BP3_BIT6 BIT(6) /* Block protect 3 */ | |
| 132 | 117 | #define SR_TB_BIT6 BIT(6) /* Top/Bottom protect */ |
| 133 | 118 | #define SR_SRWD BIT(7) /* SR write protect */ |
| 134 | 119 | /* Spansion/Cypress specific status bits */ |
| @@ -137,6 +122,8 @@ · 2 unmodified lines | ||
| 137 | 122 | |
| 138 | 123 | #define SR1_QUAD_EN_BIT6 BIT(6) |
| 139 | 124 | |
| 125 | +#define SR_BP_SHIFT 2 | |
| 126 | + | |
| 140 | 127 | /* Enhanced Volatile Configuration Register bits */ |
| 141 | 128 | #define EVCR_QUAD_EN_MICRON BIT(7) /* Micron Quad I/O */ |
| 142 | 129 | |
| @@ -225,110 +212,6 @@ static inline u8 spi_nor_get_protocol_width(enum spi_nor_protocol proto) · 82 unmodified lines | ||
| 225 | 212 | return spi_nor_get_protocol_data_nbits(proto); |
| 226 | 213 | } |
| 227 | 214 | |
| 228 | −enum spi_nor_option_flags { | |
| 229 | − SNOR_F_USE_FSR = BIT(0), | |
| 230 | − SNOR_F_HAS_SR_TB = BIT(1), | |
| 231 | − SNOR_F_NO_OP_CHIP_ERASE = BIT(2), | |
| 232 | − SNOR_F_READY_XSR_RDY = BIT(3), | |
| 233 | − SNOR_F_USE_CLSR = BIT(4), | |
| 234 | − SNOR_F_BROKEN_RESET = BIT(5), | |
| 235 | − SNOR_F_4B_OPCODES = BIT(6), | |
| 236 | − SNOR_F_HAS_4BAIT = BIT(7), | |
| 237 | − SNOR_F_HAS_LOCK = BIT(8), | |
| 238 | − SNOR_F_HAS_16BIT_SR = BIT(9), | |
| 239 | − SNOR_F_NO_READ_CR = BIT(10), | |
| 240 | − SNOR_F_HAS_SR_TB_BIT6 = BIT(11), | |
| 241 | − | |
| 242 | −}; | |
| 243 | − | |
| 244 | −/** | |
| 245 | − * struct spi_nor_erase_type - Structure to describe a SPI NOR erase type | |
| 246 | − * @size: the size of the sector/block erased by the erase type. | |
| 247 | − * JEDEC JESD216B imposes erase sizes to be a power of 2. | |
| 248 | − * @size_shift: @size is a power of 2, the shift is stored in | |
| 249 | − * @size_shift. | |
| 250 | − * @size_mask: the size mask based on @size_shift. | |
| 251 | − * @opcode: the SPI command op code to erase the sector/block. | |
| 252 | − * @idx: Erase Type index as sorted in the Basic Flash Parameter | |
| 253 | − * Table. It will be used to synchronize the supported | |
| 254 | − * Erase Types with the ones identified in the SFDP | |
| 255 | − * optional tables. | |
| 256 | − */ | |
| 257 | −struct spi_nor_erase_type { | |
| 258 | − u32 size; | |
| 259 | − u32 size_shift; | |
| 260 | − u32 size_mask; | |
| 261 | − u8 opcode; | |
| 262 | − u8 idx; | |
| 263 | −}; | |
| 264 | − | |
| 265 | −/** | |
| 266 | − * struct spi_nor_erase_command - Used for non-uniform erases | |
| 267 | − * The structure is used to describe a list of erase commands to be executed | |
| 268 | − * once we validate that the erase can be performed. The elements in the list | |
| 269 | − * are run-length encoded. | |
| 270 | − * @list: for inclusion into the list of erase commands. | |
| 271 | − * @count: how many times the same erase command should be | |
| 272 | − * consecutively used. | |
| 273 | − * @size: the size of the sector/block erased by the command. | |
| 274 | − * @opcode: the SPI command op code to erase the sector/block. | |
| 275 | − */ | |
| 276 | −struct spi_nor_erase_command { | |
| 277 | − struct list_head list; | |
| 278 | − u32 count; | |
| 279 | − u32 size; | |
| 280 | − u8 opcode; | |
| 281 | −}; | |
| 282 | − | |
| 283 | −/** | |
| 284 | − * struct spi_nor_erase_region - Structure to describe a SPI NOR erase region | |
| 285 | − * @offset: the offset in the data array of erase region start. | |
| 286 | − * LSB bits are used as a bitmask encoding flags to | |
| 287 | − * determine if this region is overlaid, if this region is | |
| 288 | − * the last in the SPI NOR flash memory and to indicate | |
| 289 | − * all the supported erase commands inside this region. | |
| 290 | − * The erase types are sorted in ascending order with the | |
| 291 | − * smallest Erase Type size being at BIT(0). | |
| 292 | − * @size: the size of the region in bytes. | |
| 293 | − */ | |
| 294 | −struct spi_nor_erase_region { | |
| 295 | − u64 offset; | |
| 296 | − u64 size; | |
| 297 | −}; | |
| 298 | − | |
| 299 | −#define SNOR_ERASE_TYPE_MAX 4 | |
| 300 | −#define SNOR_ERASE_TYPE_MASK GENMASK_ULL(SNOR_ERASE_TYPE_MAX - 1, 0) | |
| 301 | − | |
| 302 | −#define SNOR_LAST_REGION BIT(4) | |
| 303 | −#define SNOR_OVERLAID_REGION BIT(5) | |
| 304 | − | |
| 305 | −#define SNOR_ERASE_FLAGS_MAX 6 | |
| 306 | −#define SNOR_ERASE_FLAGS_MASK GENMASK_ULL(SNOR_ERASE_FLAGS_MAX - 1, 0) | |
| 307 | − | |
| 308 | −/** | |
| 309 | − * struct spi_nor_erase_map - Structure to describe the SPI NOR erase map | |
| 310 | − * @regions: array of erase regions. The regions are consecutive in | |
| 311 | − * address space. Walking through the regions is done | |
| 312 | − * incrementally. | |
| 313 | − * @uniform_region: a pre-allocated erase region for SPI NOR with a uniform | |
| 314 | − * sector size (legacy implementation). | |
| 315 | − * @erase_type: an array of erase types shared by all the regions. | |
| 316 | − * The erase types are sorted in ascending order, with the | |
| 317 | − * smallest Erase Type size being the first member in the | |
| 318 | − * erase_type array. | |
| 319 | − * @uniform_erase_type: bitmask encoding erase types that can erase the | |
| 320 | − * entire memory. This member is completed at init by | |
| 321 | − * uniform and non-uniform SPI NOR flash memories if they | |
| 322 | − * support at least one erase type that can erase the | |
| 323 | − * entire memory. | |
| 324 | − */ | |
| 325 | −struct spi_nor_erase_map { | |
| 326 | − struct spi_nor_erase_region *regions; | |
| 327 | − struct spi_nor_erase_region uniform_region; | |
| 328 | − struct spi_nor_erase_type erase_type[SNOR_ERASE_TYPE_MAX]; | |
| 329 | − u8 uniform_erase_type; | |
| 330 | −}; | |
| 331 | − | |
| 332 | 215 | /** |
| 333 | 216 | * struct spi_nor_hwcaps - Structure for describing the hardware capabilies |
| 334 | 217 | * supported by the SPI controller (bus master). |
| @@ -404,61 +287,7 @@ struct spi_nor_hwcaps { · 69 unmodified lines | ||
| 404 | 287 | #define SNOR_HWCAPS_ALL (SNOR_HWCAPS_READ_MASK | \ |
| 405 | 288 | SNOR_HWCAPS_PP_MASK) |
| 406 | 289 | |
| 407 | −struct spi_nor_read_command { | |
| 408 | − u8 num_mode_clocks; | |
| 409 | − u8 num_wait_states; | |
| 410 | − u8 opcode; | |
| 411 | − enum spi_nor_protocol proto; | |
| 412 | −}; | |
| 413 | − | |
| 414 | −struct spi_nor_pp_command { | |
| 415 | − u8 opcode; | |
| 416 | − enum spi_nor_protocol proto; | |
| 417 | −}; | |
| 418 | − | |
| 419 | −enum spi_nor_read_command_index { | |
| 420 | − SNOR_CMD_READ, | |
| 421 | − SNOR_CMD_READ_FAST, | |
| 422 | − SNOR_CMD_READ_1_1_1_DTR, | |
| 423 | − | |
| 424 | − /* Dual SPI */ | |
| 425 | − SNOR_CMD_READ_1_1_2, | |
| 426 | − SNOR_CMD_READ_1_2_2, | |
| 427 | − SNOR_CMD_READ_2_2_2, | |
| 428 | − SNOR_CMD_READ_1_2_2_DTR, | |
| 429 | − | |
| 430 | − /* Quad SPI */ | |
| 431 | − SNOR_CMD_READ_1_1_4, | |
| 432 | − SNOR_CMD_READ_1_4_4, | |
| 433 | − SNOR_CMD_READ_4_4_4, | |
| 434 | − SNOR_CMD_READ_1_4_4_DTR, | |
| 435 | − | |
| 436 | − /* Octal SPI */ | |
| 437 | − SNOR_CMD_READ_1_1_8, | |
| 438 | − SNOR_CMD_READ_1_8_8, | |
| 439 | − SNOR_CMD_READ_8_8_8, | |
| 440 | − SNOR_CMD_READ_1_8_8_DTR, | |
| 441 | − | |
| 442 | − SNOR_CMD_READ_MAX | |
| 443 | −}; | |
| 444 | − | |
| 445 | −enum spi_nor_pp_command_index { | |
| 446 | − SNOR_CMD_PP, | |
| 447 | − | |
| 448 | − /* Quad SPI */ | |
| 449 | − SNOR_CMD_PP_1_1_4, | |
| 450 | − SNOR_CMD_PP_1_4_4, | |
| 451 | − SNOR_CMD_PP_4_4_4, | |
| 452 | − | |
| 453 | − /* Octal SPI */ | |
| 454 | − SNOR_CMD_PP_1_1_8, | |
| 455 | − SNOR_CMD_PP_1_8_8, | |
| 456 | − SNOR_CMD_PP_8_8_8, | |
| 457 | − | |
| 458 | − SNOR_CMD_PP_MAX | |
| 459 | −}; | |
| 460 | − | |
| 461 | −/* Forward declaration that will be used in 'struct spi_nor_flash_parameter' */ | |
| 290 | +/* Forward declaration that is used in 'struct spi_nor_controller_ops' */ | |
| 462 | 291 | struct spi_nor; |
| 463 | 292 | |
| 464 | 293 | /** |
| @@ -489,68 +318,13 @@ struct spi_nor_controller_ops { · 24 unmodified lines | ||
| 489 | 318 | int (*erase)(struct spi_nor *nor, loff_t offs); |
| 490 | 319 | }; |
| 491 | 320 | |
| 492 | −/** | |
| 493 | − * struct spi_nor_locking_ops - SPI NOR locking methods | |
| 494 | − * @lock: lock a region of the SPI NOR. | |
| 495 | − * @unlock: unlock a region of the SPI NOR. | |
| 496 | − * @is_locked: check if a region of the SPI NOR is completely locked | |
| 497 | − */ | |
| 498 | −struct spi_nor_locking_ops { | |
| 499 | − int (*lock)(struct spi_nor *nor, loff_t ofs, uint64_t len); | |
| 500 | − int (*unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len); | |
| 501 | − int (*is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len); | |
| 502 | −}; | |
| 503 | − | |
| 504 | −/** | |
| 505 | − * struct spi_nor_flash_parameter - SPI NOR flash parameters and settings. | |
| 506 | − * Includes legacy flash parameters and settings that can be overwritten | |
| 507 | − * by the spi_nor_fixups hooks, or dynamically when parsing the JESD216 | |
| 508 | − * Serial Flash Discoverable Parameters (SFDP) tables. | |
| 509 | − * | |
| 510 | − * @size: the flash memory density in bytes. | |
| 511 | − * @page_size: the page size of the SPI NOR flash memory. | |
| 512 | − * @hwcaps: describes the read and page program hardware | |
| 513 | − * capabilities. | |
| 514 | − * @reads: read capabilities ordered by priority: the higher index | |
| 515 | − * in the array, the higher priority. | |
| 516 | − * @page_programs: page program capabilities ordered by priority: the | |
| 517 | − * higher index in the array, the higher priority. | |
| 518 | − * @erase_map: the erase map parsed from the SFDP Sector Map Parameter | |
| 519 | − * Table. | |
| 520 | − * @quad_enable: enables SPI NOR quad mode. | |
| 521 | − * @set_4byte: puts the SPI NOR in 4 byte addressing mode. | |
| 522 | − * @convert_addr: converts an absolute address into something the flash | |
| 523 | − * will understand. Particularly useful when pagesize is | |
| 524 | − * not a power-of-2. | |
| 525 | − * @setup: configures the SPI NOR memory. Useful for SPI NOR | |
| 526 | − * flashes that have peculiarities to the SPI NOR standard | |
| 527 | − * e.g. different opcodes, specific address calculation, | |
| 528 | − * page size, etc. | |
| 529 | − * @locking_ops: SPI NOR locking methods. | |
| 530 | − */ | |
| 531 | −struct spi_nor_flash_parameter { | |
| 532 | − u64 size; | |
| 533 | − u32 page_size; | |
| 534 | − | |
| 535 | − struct spi_nor_hwcaps hwcaps; | |
| 536 | − struct spi_nor_read_command reads[SNOR_CMD_READ_MAX]; | |
| 537 | − struct spi_nor_pp_command page_programs[SNOR_CMD_PP_MAX]; | |
| 538 | − | |
| 539 | − struct spi_nor_erase_map erase_map; | |
| 540 | − | |
| 541 | − int (*quad_enable)(struct spi_nor *nor); | |
| 542 | − int (*set_4byte)(struct spi_nor *nor, bool enable); | |
| 543 | − u32 (*convert_addr)(struct spi_nor *nor, u32 addr); | |
| 544 | − int (*setup)(struct spi_nor *nor, const struct spi_nor_hwcaps *hwcaps); | |
| 545 | − | |
| 546 | − const struct spi_nor_locking_ops *locking_ops; | |
| 547 | −}; | |
| 548 | − | |
| 549 | −/** | |
| 550 | − * struct flash_info - Forward declaration of a structure used internally by | |
| 551 | − * spi_nor_scan() | |
| 321 | +/* | |
| 322 | + * Forward declarations that are used internally by the core and manufacturer | |
| 323 | + * drivers. | |
| 552 | 324 | */ |
| 553 | 325 | struct flash_info; |
| 326 | +struct spi_nor_manufacturer; | |
| 327 | +struct spi_nor_flash_parameter; | |
| 554 | 328 | |
| 555 | 329 | /** |
| 556 | 330 | * struct spi_nor - Structure for defining a the SPI NOR layer |
| @@ -562,6 +336,7 @@ struct flash_info; · 5 unmodified lines | ||
| 562 | 336 | * layer is not DMA-able |
| 563 | 337 | * @bouncebuf_size: size of the bounce buffer |
| 564 | 338 | * @info: spi-nor part JDEC MFR id and other info |
| 339 | + * @manufacturer: spi-nor manufacturer | |
| 565 | 340 | * @page_size: the page size of the SPI NOR |
| 566 | 341 | * @addr_width: number of address bytes |
| 567 | 342 | * @erase_opcode: the opcode for erasing a sector |
| @@ -578,6 +353,7 @@ struct flash_info; · 10 unmodified lines | ||
| 578 | 353 | * The structure includes legacy flash parameters and |
| 579 | 354 | * settings that can be overwritten by the spi_nor_fixups |
| 580 | 355 | * hooks, or dynamically when parsing the SFDP tables. |
| 356 | + * @dirmap: pointers to struct spi_mem_dirmap_desc for reads/writes. | |
| 581 | 357 | * @priv: the private data |
| 582 | 358 | */ |
| 583 | 359 | struct spi_nor { |
| @@ -588,6 +364,7 @@ struct spi_nor { · 4 unmodified lines | ||
| 588 | 364 | u8 *bouncebuf; |
| 589 | 365 | size_t bouncebuf_size; |
| 590 | 366 | const struct flash_info *info; |
| 367 | + const struct spi_nor_manufacturer *manufacturer; | |
| 591 | 368 | u32 page_size; |
| 592 | 369 | u8 addr_width; |
| 593 | 370 | u8 erase_opcode; |
| @@ -602,40 +379,16 @@ struct spi_nor { · 8 unmodified lines | ||
| 602 | 379 | |
| 603 | 380 | const struct spi_nor_controller_ops *controller_ops; |
| 604 | 381 | |
| 605 | − struct spi_nor_flash_parameter params; | |
| 382 | + struct spi_nor_flash_parameter *params; | |
| 383 | + | |
| 384 | + struct { | |
| 385 | + struct spi_mem_dirmap_desc *rdesc; | |
| 386 | + struct spi_mem_dirmap_desc *wdesc; | |
| 387 | + } dirmap; | |
| 606 | 388 | |
| 607 | 389 | void *priv; |
| 608 | 390 | }; |
| 609 | 391 | |
| 610 | −static u64 __maybe_unused | |
| 611 | −spi_nor_region_is_last(const struct spi_nor_erase_region *region) | |
| 612 | −{ | |
| 613 | − return region->offset & SNOR_LAST_REGION; | |
| 614 | −} | |
| 615 | − | |
| 616 | −static u64 __maybe_unused | |
| 617 | −spi_nor_region_end(const struct spi_nor_erase_region *region) | |
| 618 | −{ | |
| 619 | − return (region->offset & ~SNOR_ERASE_FLAGS_MASK) + region->size; | |
| 620 | −} | |
| 621 | − | |
| 622 | −static void __maybe_unused | |
| 623 | −spi_nor_region_mark_end(struct spi_nor_erase_region *region) | |
| 624 | −{ | |
| 625 | − region->offset |= SNOR_LAST_REGION; | |
| 626 | −} | |
| 627 | − | |
| 628 | −static void __maybe_unused | |
| 629 | −spi_nor_region_mark_overlay(struct spi_nor_erase_region *region) | |
| 630 | −{ | |
| 631 | − region->offset |= SNOR_OVERLAID_REGION; | |
| 632 | −} | |
| 633 | − | |
| 634 | −static bool __maybe_unused spi_nor_has_uniform_erase(const struct spi_nor *nor) | |
| 635 | −{ | |
| 636 | − return !!nor->params.erase_map.uniform_erase_type; | |
| 637 | −} | |
| 638 | − | |
| 639 | 392 | static inline void spi_nor_set_flash_node(struct spi_nor *nor, |
| 640 | 393 | struct device_node *np) |
| 641 | 394 | { |
| @@ -32,9 +32,9 @@ · 31 unmodified lines | ||
| 32 | 32 | SPI_MEM_OP_NO_DUMMY, \ |
| 33 | 33 | SPI_MEM_OP_NO_DATA) |
| 34 | 34 | |
| 35 | −#define SPINAND_READID_OP(ndummy, buf, len) \ | |
| 35 | +#define SPINAND_READID_OP(naddr, ndummy, buf, len) \ | |
| 36 | 36 | SPI_MEM_OP(SPI_MEM_OP_CMD(0x9f, 1), \ |
| 37 | − SPI_MEM_OP_NO_ADDR, \ | |
| 37 | + SPI_MEM_OP_ADDR(naddr, 0, 1), \ | |
| 38 | 38 | SPI_MEM_OP_DUMMY(ndummy, 1), \ |
| 39 | 39 | SPI_MEM_OP_DATA_IN(len, buf, 1)) |
| 40 | 40 | |
| @@ -176,37 +176,46 @@ struct spinand_device; · 135 unmodified lines | ||
| 176 | 176 | * @data: buffer containing the id bytes. Currently 4 bytes large, but can |
| 177 | 177 | * be extended if required |
| 178 | 178 | * @len: ID length |
| 179 | − * | |
| 180 | − * struct_spinand_id->data contains all bytes returned after a READ_ID command, | |
| 181 | − * including dummy bytes if the chip does not emit ID bytes right after the | |
| 182 | − * READ_ID command. The responsibility to extract real ID bytes is left to | |
| 183 | − * struct_manufacurer_ops->detect(). | |
| 184 | 179 | */ |
| 185 | 180 | struct spinand_id { |
| 186 | 181 | u8 data[SPINAND_MAX_ID_LEN]; |
| 187 | 182 | int len; |
| 188 | 183 | }; |
| 189 | 184 | |
| 185 | +enum spinand_readid_method { | |
| 186 | + SPINAND_READID_METHOD_OPCODE, | |
| 187 | + SPINAND_READID_METHOD_OPCODE_ADDR, | |
| 188 | + SPINAND_READID_METHOD_OPCODE_DUMMY, | |
| 189 | +}; | |
| 190 | + | |
| 191 | +/** | |
| 192 | + * struct spinand_devid - SPI NAND device id structure | |
| 193 | + * @id: device id of current chip | |
| 194 | + * @len: number of bytes in device id | |
| 195 | + * @method: method to read chip id | |
| 196 | + * There are 3 possible variants: | |
| 197 | + * SPINAND_READID_METHOD_OPCODE: chip id is returned immediately | |
| 198 | + * after read_id opcode. | |
| 199 | + * SPINAND_READID_METHOD_OPCODE_ADDR: chip id is returned after | |
| 200 | + * read_id opcode + 1-byte address. | |
| 201 | + * SPINAND_READID_METHOD_OPCODE_DUMMY: chip id is returned after | |
| 202 | + * read_id opcode + 1 dummy byte. | |
| 203 | + */ | |
| 204 | +struct spinand_devid { | |
| 205 | + const u8 *id; | |
| 206 | + const u8 len; | |
| 207 | + const enum spinand_readid_method method; | |
| 208 | +}; | |
| 209 | + | |
| 190 | 210 | /** |
| 191 | 211 | * struct manufacurer_ops - SPI NAND manufacturer specific operations |
| 192 | − * @detect: detect a SPI NAND device. Every time a SPI NAND device is probed | |
| 193 | − * the core calls the struct_manufacurer_ops->detect() hook of each | |
| 194 | − * registered manufacturer until one of them return 1. Note that | |
| 195 | − * the first thing to check in this hook is that the manufacturer ID | |
| 196 | − * in struct_spinand_device->id matches the manufacturer whose | |
| 197 | − * ->detect() hook has been called. Should return 1 if there's a | |
| 198 | − * match, 0 if the manufacturer ID does not match and a negative | |
| 199 | − * error code otherwise. When true is returned, the core assumes | |
| 200 | − * that properties of the NAND chip (spinand->base.memorg and | |
| 201 | − * spinand->base.eccreq) have been filled | |
| 202 | 212 | * @init: initialize a SPI NAND device |
| 203 | 213 | * @cleanup: cleanup a SPI NAND device |
| 204 | 214 | * |
| 205 | 215 | * Each SPI NAND manufacturer driver should implement this interface so that |
| 206 | − * NAND chips coming from this vendor can be detected and initialized properly. | |
| 216 | + * NAND chips coming from this vendor can be initialized properly. | |
| 207 | 217 | */ |
| 208 | 218 | struct spinand_manufacturer_ops { |
| 209 | − int (*detect)(struct spinand_device *spinand); | |
| 210 | 219 | int (*init)(struct spinand_device *spinand); |
| 211 | 220 | void (*cleanup)(struct spinand_device *spinand); |
| 212 | 221 | }; |
| @@ -215,11 +224,16 @@ struct spinand_manufacturer_ops { · 2 unmodified lines | ||
| 215 | 224 | * struct spinand_manufacturer - SPI NAND manufacturer instance |
| 216 | 225 | * @id: manufacturer ID |
| 217 | 226 | * @name: manufacturer name |
| 227 | + * @devid_len: number of bytes in device ID | |
| 228 | + * @chips: supported SPI NANDs under current manufacturer | |
| 229 | + * @nchips: number of SPI NANDs available in chips array | |
| 218 | 230 | * @ops: manufacturer operations |
| 219 | 231 | */ |
| 220 | 232 | struct spinand_manufacturer { |
| 221 | 233 | u8 id; |
| 222 | 234 | char *name; |
| 235 | + const struct spinand_info *chips; | |
| 236 | + const size_t nchips; | |
| 223 | 237 | const struct spinand_manufacturer_ops *ops; |
| 224 | 238 | }; |
| 225 | 239 | |
| @@ -270,6 +284,7 @@ struct spinand_ecc_info { · 44 unmodified lines | ||
| 270 | 284 | }; |
| 271 | 285 | |
| 272 | 286 | #define SPINAND_HAS_QE_BIT BIT(0) |
| 287 | +#define SPINAND_HAS_CR_FEAT_BIT BIT(1) | |
| 273 | 288 | |
| 274 | 289 | /** |
| 275 | 290 | * struct spinand_info - Structure used to describe SPI NAND chips |
| @@ -291,7 +306,7 @@ struct spinand_ecc_info { · 15 unmodified lines | ||
| 291 | 306 | */ |
| 292 | 307 | struct spinand_info { |
| 293 | 308 | const char *model; |
| 294 | − u16 devid; | |
| 309 | + struct spinand_devid devid; | |
| 295 | 310 | u32 flags; |
| 296 | 311 | struct nand_memory_organization memorg; |
| 297 | 312 | struct nand_ecc_req eccreq; |
| @@ -305,6 +320,13 @@ struct spinand_info { · 7 unmodified lines | ||
| 305 | 320 | unsigned int target); |
| 306 | 321 | }; |
| 307 | 322 | |
| 323 | +#define SPINAND_ID(__method, ...) \ | |
| 324 | + { \ | |
| 325 | + .id = (const u8[]){ __VA_ARGS__ }, \ | |
| 326 | + .len = sizeof((u8[]){ __VA_ARGS__ }), \ | |
| 327 | + .method = __method, \ | |
| 328 | + } | |
| 329 | + | |
| 308 | 330 | #define SPINAND_INFO_OP_VARIANTS(__read, __write, __update) \ |
| 309 | 331 | { \ |
| 310 | 332 | .read_cache = __read, \ |
| @@ -451,9 +473,10 @@ static inline void spinand_set_of_node(struct spinand_device *spinand, · 140 unmodified lines | ||
| 451 | 473 | nanddev_set_of_node(&spinand->base, np); |
| 452 | 474 | } |
| 453 | 475 | |
| 454 | −int spinand_match_and_init(struct spinand_device *dev, | |
| 476 | +int spinand_match_and_init(struct spinand_device *spinand, | |
| 455 | 477 | const struct spinand_info *table, |
| 456 | − unsigned int table_size, u16 devid); | |
| 478 | + unsigned int table_size, | |
| 479 | + enum spinand_readid_method rdid_method); | |
| 457 | 480 | |
| 458 | 481 | int spinand_upd_cfg(struct spinand_device *spinand, u8 mask, u8 val); |
| 459 | 482 | int spinand_select_target(struct spinand_device *spinand, unsigned int target); |