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 | #include <linux/types.h> | 9 | #include <linux/types.h> |
| 10 | #include <linux/uio.h> | 10 | #include <linux/uio.h> |
| 11 | #include <linux/list.h> | ||
| 11 | #include <linux/notifier.h> | 12 | #include <linux/notifier.h> |
| 12 | #include <linux/device.h> | 13 | #include <linux/device.h> |
| 13 | #include <linux/of.h> | 14 | #include <linux/of.h> |
| @@ -194,10 +195,43 @@ struct mtd_debug_info { · 180 unmodified lines | |||
| 194 | const char *partid; | 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 | struct mtd_info { | 232 | struct mtd_info { |
| 198 | u_char type; | 233 | u_char type; |
| 199 | uint32_t flags; | 234 | uint32_t flags; |
| 200 | uint32_t orig_flags; /* Flags as before running mtd checks */ | ||
| 201 | uint64_t size; // Total size of the MTD | 235 | uint64_t size; // Total size of the MTD |
| 202 | 236 | ||
| 203 | /* "Major" erase size for the device. Naïve users may take this | 237 | /* "Major" erase size for the device. Naïve users may take this |
| @@ -339,8 +373,52 @@ struct mtd_info { · 135 unmodified lines | |||
| 339 | int usecount; | 373 | int usecount; |
| 340 | struct mtd_debug_info dbg; | 374 | struct mtd_debug_info dbg; |
| 341 | struct nvmem_device *nvmem; | 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 | int mtd_ooblayout_ecc(struct mtd_info *mtd, int section, | 422 | int mtd_ooblayout_ecc(struct mtd_info *mtd, int section, |
| 345 | struct mtd_oob_region *oobecc); | 423 | struct mtd_oob_region *oobecc); |
| 346 | int mtd_ooblayout_find_eccregion(struct mtd_info *mtd, int eccbyte, | 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 | static inline int mtd_max_bad_blocks(struct mtd_info *mtd, | 470 | static inline int mtd_max_bad_blocks(struct mtd_info *mtd, |
| 393 | loff_t ofs, size_t len) | 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 | return -ENOTSUPP; | 476 | return -ENOTSUPP; |
| 397 | 477 | ||
| 398 | if (mtd->size < (len + ofs) || ofs < 0) | 478 | if (mtd->size < (len + ofs) || ofs < 0) |
| 399 | return -EINVAL; | 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 | int mtd_wunit_to_pairing_info(struct mtd_info *mtd, int wunit, | 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 | static inline void mtd_sync(struct mtd_info *mtd) | 521 | static inline void mtd_sync(struct mtd_info *mtd) |
| 441 | { | 522 | { |
| 442 | if (mtd->_sync) | 523 | struct mtd_info *master = mtd_get_master(mtd); |
| 443 | mtd->_sync(mtd); | 524 | |
| 525 | if (master->_sync) | ||
| 526 | master->_sync(master); | ||
| 444 | } | 527 | } |
| 445 | 528 | ||
| 446 | int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len); | 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 | static inline int mtd_suspend(struct mtd_info *mtd) | 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 | static inline void mtd_resume(struct mtd_info *mtd) | 552 | static inline void mtd_resume(struct mtd_info *mtd) |
| 459 | { | 553 | { |
| 460 | if (mtd->_resume) | 554 | struct mtd_info *master = mtd_get_master(mtd); |
| 461 | mtd->_resume(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 | static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd) | 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 | static inline int mtd_has_oob(const struct mtd_info *mtd) | 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 | static inline int mtd_type_is_nand(const struct mtd_info *mtd) | 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 | static inline int mtd_can_have_bb(const struct mtd_info *mtd) | 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 | /* Kernel-side ioctl definitions */ | 659 | /* Kernel-side ioctl definitions */ |
| @@ -105,7 +105,6 @@ extern void deregister_mtd_parser(struct mtd_part_parser *parser); · 104 unmodified lines | |||
| 105 | module_driver(__mtd_part_parser, register_mtd_parser, \ | 105 | module_driver(__mtd_part_parser, register_mtd_parser, \ |
| 106 | deregister_mtd_parser) | 106 | deregister_mtd_parser) |
| 107 | 107 | ||
| 108 | int mtd_is_partition(const struct mtd_info *mtd); | ||
| 109 | int mtd_add_partition(struct mtd_info *master, const char *name, | 108 | int mtd_add_partition(struct mtd_info *master, const char *name, |
| 110 | long long offset, long long length); | 109 | long long offset, long long length); |
| 111 | int mtd_del_partition(struct mtd_info *master, int partno); | 110 | int mtd_del_partition(struct mtd_info *master, int partno); |
| @@ -1064,6 +1064,8 @@ struct nand_legacy { · 1063 unmodified lines | |||
| 1064 | * @lock: lock protecting the suspended field. Also used to | 1064 | * @lock: lock protecting the suspended field. Also used to |
| 1065 | * serialize accesses to the NAND device. | 1065 | * serialize accesses to the NAND device. |
| 1066 | * @suspended: set to 1 when the device is suspended, 0 when it's not. | 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 | * @bbt: [INTERN] bad block table pointer | 1069 | * @bbt: [INTERN] bad block table pointer |
| 1068 | * @bbt_td: [REPLACEABLE] bad block table descriptor for flash | 1070 | * @bbt_td: [REPLACEABLE] bad block table descriptor for flash |
| 1069 | * lookup. | 1071 | * lookup. |
| @@ -1077,6 +1079,8 @@ struct nand_legacy { · 7 unmodified lines | |||
| 1077 | * @manufacturer: [INTERN] Contains manufacturer information | 1079 | * @manufacturer: [INTERN] Contains manufacturer information |
| 1078 | * @manufacturer.desc: [INTERN] Contains manufacturer's description | 1080 | * @manufacturer.desc: [INTERN] Contains manufacturer's description |
| 1079 | * @manufacturer.priv: [INTERN] Contains manufacturer private information | 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 | struct nand_chip { | 1086 | struct nand_chip { |
| @@ -1117,6 +1121,8 @@ struct nand_chip { · 34 unmodified lines | |||
| 1117 | 1121 | ||
| 1118 | struct mutex lock; | 1122 | struct mutex lock; |
| 1119 | unsigned int suspended : 1; | 1123 | unsigned int suspended : 1; |
| 1124 | int (*suspend)(struct nand_chip *chip); | ||
| 1125 | void (*resume)(struct nand_chip *chip); | ||
| 1120 | 1126 | ||
| 1121 | uint8_t *oob_poi; | 1127 | uint8_t *oob_poi; |
| 1122 | struct nand_controller *controller; | 1128 | struct nand_controller *controller; |
| @@ -1136,6 +1142,9 @@ struct nand_chip { · 13 unmodified lines | |||
| 1136 | const struct nand_manufacturer *desc; | 1142 | const struct nand_manufacturer *desc; |
| 1137 | void *priv; | 1143 | void *priv; |
| 1138 | } manufacturer; | 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 | extern const struct mtd_ooblayout_ops nand_ooblayout_sp_ops; | 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 | * struct nand_flash_dev - NAND Flash Device ID Structure | 1224 | * struct nand_flash_dev - NAND Flash Device ID Structure |
| 1216 | * @name: a human-readable name of the NAND chip | 1225 | * @name: a human-readable name of the NAND chip |
| 1217 | * @dev_id: the device ID (the second byte of the full chip ID array) | 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 | * memory address as ``id[0]``) | 1228 | * memory address as ``id[0]``) |
| 1220 | * @dev_id: device ID part of the full chip ID array (refers the same memory | 1229 | * @dev_id: device ID part of the full chip ID array (refers the same memory |
| 1221 | * address as ``id[1]``) | 1230 | * address as ``id[1]``) |
| @@ -11,23 +11,6 @@ · 10 unmodified lines | |||
| 11 | #include <linux/mtd/mtd.h> | 11 | #include <linux/mtd/mtd.h> |
| 12 | #include <linux/spi/spi-mem.h> | 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 | * Note on opcode nomenclature: some opcodes have a format like | 15 | * Note on opcode nomenclature: some opcodes have a format like |
| 33 | * SPINOR_OP_FUNCTION{4,}_x_y_z. The numbers x, y, and z stand for the number | 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 | #define SR_BP0 BIT(2) /* Block protect 0 */ | 111 | #define SR_BP0 BIT(2) /* Block protect 0 */ |
| 129 | #define SR_BP1 BIT(3) /* Block protect 1 */ | 112 | #define SR_BP1 BIT(3) /* Block protect 1 */ |
| 130 | #define SR_BP2 BIT(4) /* Block protect 2 */ | 113 | #define SR_BP2 BIT(4) /* Block protect 2 */ |
| 114 | #define SR_BP3 BIT(5) /* Block protect 3 */ | ||
| 131 | #define SR_TB_BIT5 BIT(5) /* Top/Bottom protect */ | 115 | #define SR_TB_BIT5 BIT(5) /* Top/Bottom protect */ |
| 116 | #define SR_BP3_BIT6 BIT(6) /* Block protect 3 */ | ||
| 132 | #define SR_TB_BIT6 BIT(6) /* Top/Bottom protect */ | 117 | #define SR_TB_BIT6 BIT(6) /* Top/Bottom protect */ |
| 133 | #define SR_SRWD BIT(7) /* SR write protect */ | 118 | #define SR_SRWD BIT(7) /* SR write protect */ |
| 134 | /* Spansion/Cypress specific status bits */ | 119 | /* Spansion/Cypress specific status bits */ |
| @@ -137,6 +122,8 @@ · 2 unmodified lines | |||
| 137 | 122 | ||
| 138 | #define SR1_QUAD_EN_BIT6 BIT(6) | 123 | #define SR1_QUAD_EN_BIT6 BIT(6) |
| 139 | 124 | ||
| 125 | #define SR_BP_SHIFT 2 | ||
| 126 | |||
| 140 | /* Enhanced Volatile Configuration Register bits */ | 127 | /* Enhanced Volatile Configuration Register bits */ |
| 141 | #define EVCR_QUAD_EN_MICRON BIT(7) /* Micron Quad I/O */ | 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 | return spi_nor_get_protocol_data_nbits(proto); | 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 | * struct spi_nor_hwcaps - Structure for describing the hardware capabilies | 216 | * struct spi_nor_hwcaps - Structure for describing the hardware capabilies |
| 334 | * supported by the SPI controller (bus master). | 217 | * supported by the SPI controller (bus master). |
| @@ -404,61 +287,7 @@ struct spi_nor_hwcaps { · 69 unmodified lines | |||
| 404 | #define SNOR_HWCAPS_ALL (SNOR_HWCAPS_READ_MASK | \ | 287 | #define SNOR_HWCAPS_ALL (SNOR_HWCAPS_READ_MASK | \ |
| 405 | SNOR_HWCAPS_PP_MASK) | 288 | SNOR_HWCAPS_PP_MASK) |
| 406 | 289 | ||
| 407 | struct spi_nor_read_command { | 290 | /* Forward declaration that is used in 'struct spi_nor_controller_ops' */ |
| 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' */ | ||
| 462 | struct spi_nor; | 291 | struct spi_nor; |
| 463 | 292 | ||
| 464 | /** | 293 | /** |
| @@ -489,68 +318,13 @@ struct spi_nor_controller_ops { · 24 unmodified lines | |||
| 489 | int (*erase)(struct spi_nor *nor, loff_t offs); | 318 | int (*erase)(struct spi_nor *nor, loff_t offs); |
| 490 | }; | 319 | }; |
| 491 | 320 | ||
| 492 | /** | 321 | /* |
| 493 | * struct spi_nor_locking_ops - SPI NOR locking methods | 322 | * Forward declarations that are used internally by the core and manufacturer |
| 494 | * @lock: lock a region of the SPI NOR. | 323 | * drivers. |
| 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() | ||
| 552 | */ | 324 | */ |
| 553 | struct flash_info; | 325 | struct flash_info; |
| 326 | struct spi_nor_manufacturer; | ||
| 327 | struct spi_nor_flash_parameter; | ||
| 554 | 328 | ||
| 555 | /** | 329 | /** |
| 556 | * struct spi_nor - Structure for defining a the SPI NOR layer | 330 | * struct spi_nor - Structure for defining a the SPI NOR layer |
| @@ -562,6 +336,7 @@ struct flash_info; · 5 unmodified lines | |||
| 562 | * layer is not DMA-able | 336 | * layer is not DMA-able |
| 563 | * @bouncebuf_size: size of the bounce buffer | 337 | * @bouncebuf_size: size of the bounce buffer |
| 564 | * @info: spi-nor part JDEC MFR id and other info | 338 | * @info: spi-nor part JDEC MFR id and other info |
| 339 | * @manufacturer: spi-nor manufacturer | ||
| 565 | * @page_size: the page size of the SPI NOR | 340 | * @page_size: the page size of the SPI NOR |
| 566 | * @addr_width: number of address bytes | 341 | * @addr_width: number of address bytes |
| 567 | * @erase_opcode: the opcode for erasing a sector | 342 | * @erase_opcode: the opcode for erasing a sector |
| @@ -578,6 +353,7 @@ struct flash_info; · 10 unmodified lines | |||
| 578 | * The structure includes legacy flash parameters and | 353 | * The structure includes legacy flash parameters and |
| 579 | * settings that can be overwritten by the spi_nor_fixups | 354 | * settings that can be overwritten by the spi_nor_fixups |
| 580 | * hooks, or dynamically when parsing the SFDP tables. | 355 | * hooks, or dynamically when parsing the SFDP tables. |
| 356 | * @dirmap: pointers to struct spi_mem_dirmap_desc for reads/writes. | ||
| 581 | * @priv: the private data | 357 | * @priv: the private data |
| 582 | */ | 358 | */ |
| 583 | struct spi_nor { | 359 | struct spi_nor { |
| @@ -588,6 +364,7 @@ struct spi_nor { · 4 unmodified lines | |||
| 588 | u8 *bouncebuf; | 364 | u8 *bouncebuf; |
| 589 | size_t bouncebuf_size; | 365 | size_t bouncebuf_size; |
| 590 | const struct flash_info *info; | 366 | const struct flash_info *info; |
| 367 | const struct spi_nor_manufacturer *manufacturer; | ||
| 591 | u32 page_size; | 368 | u32 page_size; |
| 592 | u8 addr_width; | 369 | u8 addr_width; |
| 593 | u8 erase_opcode; | 370 | u8 erase_opcode; |
| @@ -602,40 +379,16 @@ struct spi_nor { · 8 unmodified lines | |||
| 602 | 379 | ||
| 603 | const struct spi_nor_controller_ops *controller_ops; | 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 | void *priv; | 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 | static inline void spi_nor_set_flash_node(struct spi_nor *nor, | 392 | static inline void spi_nor_set_flash_node(struct spi_nor *nor, |
| 640 | struct device_node *np) | 393 | struct device_node *np) |
| 641 | { | 394 | { |
| @@ -32,9 +32,9 @@ · 31 unmodified lines | |||
| 32 | SPI_MEM_OP_NO_DUMMY, \ | 32 | SPI_MEM_OP_NO_DUMMY, \ |
| 33 | SPI_MEM_OP_NO_DATA) | 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 | SPI_MEM_OP(SPI_MEM_OP_CMD(0x9f, 1), \ | 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 | SPI_MEM_OP_DUMMY(ndummy, 1), \ | 38 | SPI_MEM_OP_DUMMY(ndummy, 1), \ |
| 39 | SPI_MEM_OP_DATA_IN(len, buf, 1)) | 39 | SPI_MEM_OP_DATA_IN(len, buf, 1)) |
| 40 | 40 | ||
| @@ -176,37 +176,46 @@ struct spinand_device; · 135 unmodified lines | |||
| 176 | * @data: buffer containing the id bytes. Currently 4 bytes large, but can | 176 | * @data: buffer containing the id bytes. Currently 4 bytes large, but can |
| 177 | * be extended if required | 177 | * be extended if required |
| 178 | * @len: ID length | 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 | struct spinand_id { | 180 | struct spinand_id { |
| 186 | u8 data[SPINAND_MAX_ID_LEN]; | 181 | u8 data[SPINAND_MAX_ID_LEN]; |
| 187 | int len; | 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 | * struct manufacurer_ops - SPI NAND manufacturer specific operations | 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 | * @init: initialize a SPI NAND device | 212 | * @init: initialize a SPI NAND device |
| 203 | * @cleanup: cleanup a SPI NAND device | 213 | * @cleanup: cleanup a SPI NAND device |
| 204 | * | 214 | * |
| 205 | * Each SPI NAND manufacturer driver should implement this interface so that | 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 | struct spinand_manufacturer_ops { | 218 | struct spinand_manufacturer_ops { |
| 209 | int (*detect)(struct spinand_device *spinand); | ||
| 210 | int (*init)(struct spinand_device *spinand); | 219 | int (*init)(struct spinand_device *spinand); |
| 211 | void (*cleanup)(struct spinand_device *spinand); | 220 | void (*cleanup)(struct spinand_device *spinand); |
| 212 | }; | 221 | }; |
| @@ -215,11 +224,16 @@ struct spinand_manufacturer_ops { · 2 unmodified lines | |||
| 215 | * struct spinand_manufacturer - SPI NAND manufacturer instance | 224 | * struct spinand_manufacturer - SPI NAND manufacturer instance |
| 216 | * @id: manufacturer ID | 225 | * @id: manufacturer ID |
| 217 | * @name: manufacturer name | 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 | * @ops: manufacturer operations | 230 | * @ops: manufacturer operations |
| 219 | */ | 231 | */ |
| 220 | struct spinand_manufacturer { | 232 | struct spinand_manufacturer { |
| 221 | u8 id; | 233 | u8 id; |
| 222 | char *name; | 234 | char *name; |
| 235 | const struct spinand_info *chips; | ||
| 236 | const size_t nchips; | ||
| 223 | const struct spinand_manufacturer_ops *ops; | 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 | #define SPINAND_HAS_QE_BIT BIT(0) | 286 | #define SPINAND_HAS_QE_BIT BIT(0) |
| 287 | #define SPINAND_HAS_CR_FEAT_BIT BIT(1) | ||
| 273 | 288 | ||
| 274 | /** | 289 | /** |
| 275 | * struct spinand_info - Structure used to describe SPI NAND chips | 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 | struct spinand_info { | 307 | struct spinand_info { |
| 293 | const char *model; | 308 | const char *model; |
| 294 | u16 devid; | 309 | struct spinand_devid devid; |
| 295 | u32 flags; | 310 | u32 flags; |
| 296 | struct nand_memory_organization memorg; | 311 | struct nand_memory_organization memorg; |
| 297 | struct nand_ecc_req eccreq; | 312 | struct nand_ecc_req eccreq; |
| @@ -305,6 +320,13 @@ struct spinand_info { · 7 unmodified lines | |||
| 305 | unsigned int target); | 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 | #define SPINAND_INFO_OP_VARIANTS(__read, __write, __update) \ | 330 | #define SPINAND_INFO_OP_VARIANTS(__read, __write, __update) \ |
| 309 | { \ | 331 | { \ |
| 310 | .read_cache = __read, \ | 332 | .read_cache = __read, \ |
| @@ -451,9 +473,10 @@ static inline void spinand_set_of_node(struct spinand_device *spinand, · 140 unmodified lines | |||
| 451 | nanddev_set_of_node(&spinand->base, np); | 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 | const struct spinand_info *table, | 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 | int spinand_upd_cfg(struct spinand_device *spinand, u8 mask, u8 val); | 481 | int spinand_upd_cfg(struct spinand_device *spinand, u8 mask, u8 val); |
| 459 | int spinand_select_target(struct spinand_device *spinand, unsigned int target); | 482 | int spinand_select_target(struct spinand_device *spinand, unsigned int target); |