SPI-NAND support
Subsystems (12)
Miquel Raynal
maintainerv3 cover SPI-NAND support
During the last months, Boris Brezillon shared his work to support serial flashes within Linux. First, he delivered (and merged) a new layer called spi-mem. He also initiated in Linux MTD subsystem the move of all 'raw' NAND related code to a raw/ subdirectory, adding at the same time a NAND core that would be shared with all NAND devices. Then, he contributed a generic SPI-NAND driver, making use of this NAND core, as well as some vendor code to drive a few chips.
On top of this work, I added an 'mtd' U-Boot command to handle all sort of MTD devices. This should become the default command instead of having one per flash flavor ('sf', 'nand', 'spi-nand' ?).
The series has been tested on an Ocelot board PCB123 (VSC7514), featuring a Macronix SPI NAND chip.
TL;DR: the series contains:
- A few patches from Linux to resynchronize some areas of the MTD layer.
- Various fixes and re-organization of the MTD subsystem.
- The introduction of the SPI-mem interface.
- The addition of the generic SPI-NAND driver (and its bindings).
- Several SPI NAND chip drivers (Macronix, Micron, Winbond).
- A new 'mtd' command.
Any comments on the code, the organization and the respect of U-Boot driver model will be welcome.
Thanks,
Miquèl
Changes since v2:
-----------------
* Rebased on u-boot master branch.
* Removed extra-parenthesis in
"mtd: Fallback to ->_read/write() when ->_read/write_oob() is missing"
* s/fiels/files/ in "mtd: move NAND fiels into a raw/ subdirectory"
* Do not describe generic SPI device properties in SPI NAND bindings.
* Changes in the mtd command:
* Printing more information in 'mtd list' (device type, device characteristics)
* Switch to do_div() instead of '(u32)value64b % value32b' which only worked because value32b was a power of 2.
* Removed erase.chip option.
* By default, erase/read/write happen on the full MTD device while a dump will only work on a single page.
Changes since v1:
-----------------
* Fixed the nand_memorg structure of the MX35LF2GE4AB chip.
* Added Reviewed-by tags from Jagan.
* Backported and squashed two patches fixing things in the SPI NAND core received on the Linux ML.
* Backported more changes in mtdcore.c from Linux.
* Added a patch to add a fallback on mtd->_read/_write() in mtdcore.c when mtd->_read/write_oob() is not supported.
* Removed the DT changes, useless as the DTs are not available in mainline yet.
* Addressed Boris/Stefan comments on the 'mtd' command.
* Added support for multi-pages OOB read/write.
Boris Brezillon (7):
mtd: Fallback to ->_read/write_oob() when ->_read/write() is missing
mtd: Add sanity checks in mtd_write/read_oob()
mtd: nand: Add core infrastructure to deal with NAND devices
mtd: nand: Pass mode information to nand_page_io_req
spi: Extend the core to ease integration of SPI memory controllers
mtd: spinand: Add initial support for the MX35LF1GE4AB chip
dt-bindings: Add bindings for SPI NAND devices
Brian Norris (1):
mtd: add get/set of_node/flash_node helpers
Ezequiel Garcia (1):
mtd: Uninline mtd_write_oob and move it to mtdcore.c
Frieder Schrempf (1):
mtd: spinand: Add initial support for Winbond W25M02GV
Miquel Raynal (9):
mtd: Fallback to ->_read/write() when ->_read/write_oob() is missing
mtd: fix build issue with includes
mtd: move definitions to enlarge their range
mtd: move all flash categories inside MTD submenu
mtd: move NAND files into a raw/ subdirectory
mtd: rename nand into rawnand in Kconfig prompt
mtd: spinand: Add initial support for the MX35LF2GE4AB chip
mtd: uclass: add probe function
cmd: mtd: add 'mtd' command
Peter Pan (2):
mtd: nand: Add core infrastructure to support SPI NANDs
mtd: spinand: Add initial support for Micron MT29F2G01ABAGD
cmd/Kconfig | 5 +
cmd/Makefile | 1 +
cmd/mtd.c | 334 +++++++
doc/device-tree-bindings/mtd/spi-nand.txt | 5 +
drivers/mtd/Kconfig | 4 +-
drivers/mtd/Makefile | 4 +-
drivers/mtd/mtd-uclass.c | 9 +
drivers/mtd/mtdcore.c | 106 ++-
drivers/mtd/mtdcore.h | 6 -
drivers/mtd/mtdpart.c | 6 +-
drivers/mtd/nand/Kconfig | 281 +-----
drivers/mtd/nand/Makefile | 79 +-
drivers/mtd/nand/bbt.c | 132 +++
drivers/mtd/nand/core.c | 243 +++++
drivers/mtd/nand/raw/Kconfig | 279 ++++++
drivers/mtd/nand/raw/Makefile | 77 ++
drivers/mtd/nand/{ => raw}/am335x_spl_bch.c | 0
drivers/mtd/nand/{ => raw}/arasan_nfc.c | 0
drivers/mtd/nand/{ => raw}/atmel_nand.c | 0
drivers/mtd/nand/{ => raw}/atmel_nand_ecc.h | 0
drivers/mtd/nand/{ => raw}/davinci_nand.c | 0
drivers/mtd/nand/{ => raw}/denali.c | 0
drivers/mtd/nand/{ => raw}/denali.h | 0
drivers/mtd/nand/{ => raw}/denali_dt.c | 0
drivers/mtd/nand/{ => raw}/denali_spl.c | 0
drivers/mtd/nand/{ => raw}/fsl_elbc_nand.c | 0
drivers/mtd/nand/{ => raw}/fsl_elbc_spl.c | 0
drivers/mtd/nand/{ => raw}/fsl_ifc_nand.c | 0
drivers/mtd/nand/{ => raw}/fsl_ifc_spl.c | 0
drivers/mtd/nand/{ => raw}/fsl_upm.c | 0
drivers/mtd/nand/{ => raw}/fsmc_nand.c | 0
drivers/mtd/nand/{ => raw}/kb9202_nand.c | 0
drivers/mtd/nand/{ => raw}/kirkwood_nand.c | 0
drivers/mtd/nand/{ => raw}/kmeter1_nand.c | 0
drivers/mtd/nand/{ => raw}/lpc32xx_nand_mlc.c | 0
drivers/mtd/nand/{ => raw}/lpc32xx_nand_slc.c | 0
drivers/mtd/nand/{ => raw}/mxc_nand.c | 0
drivers/mtd/nand/{ => raw}/mxc_nand.h | 0
drivers/mtd/nand/{ => raw}/mxc_nand_spl.c | 0
drivers/mtd/nand/{ => raw}/mxs_nand.c | 0
drivers/mtd/nand/{ => raw}/mxs_nand.h | 0
drivers/mtd/nand/{ => raw}/mxs_nand_dt.c | 0
drivers/mtd/nand/{ => raw}/mxs_nand_spl.c | 0
drivers/mtd/nand/{ => raw}/nand.c | 0
drivers/mtd/nand/{ => raw}/nand_base.c | 56 --
drivers/mtd/nand/{ => raw}/nand_bbt.c | 0
drivers/mtd/nand/{ => raw}/nand_bch.c | 0
drivers/mtd/nand/{ => raw}/nand_ecc.c | 0
drivers/mtd/nand/{ => raw}/nand_ids.c | 0
drivers/mtd/nand/{ => raw}/nand_plat.c | 0
drivers/mtd/nand/{ => raw}/nand_spl_load.c | 0
drivers/mtd/nand/{ => raw}/nand_spl_loaders.c | 0
drivers/mtd/nand/{ => raw}/nand_spl_simple.c | 0
drivers/mtd/nand/{ => raw}/nand_timings.c | 0
drivers/mtd/nand/{ => raw}/nand_util.c | 0
drivers/mtd/nand/{ => raw}/omap_elm.c | 0
drivers/mtd/nand/{ => raw}/omap_gpmc.c | 0
drivers/mtd/nand/{ => raw}/pxa3xx_nand.c | 0
drivers/mtd/nand/{ => raw}/pxa3xx_nand.h | 0
drivers/mtd/nand/{ => raw}/sunxi_nand.c | 0
drivers/mtd/nand/{ => raw}/sunxi_nand_spl.c | 0
drivers/mtd/nand/{ => raw}/tegra_nand.c | 0
drivers/mtd/nand/{ => raw}/tegra_nand.h | 0
drivers/mtd/nand/{ => raw}/vf610_nfc.c | 0
drivers/mtd/nand/{ => raw}/zynq_nand.c | 0
drivers/mtd/nand/spi/Kconfig | 7 +
drivers/mtd/nand/spi/Makefile | 4 +
drivers/mtd/nand/spi/core.c | 1254 +++++++++++++++++++++++++
drivers/mtd/nand/spi/macronix.c | 146 +++
drivers/mtd/nand/spi/micron.c | 135 +++
drivers/mtd/nand/spi/winbond.c | 143 +++
drivers/mtd/onenand/onenand_base.c | 60 --
drivers/spi/Kconfig | 7 +
drivers/spi/Makefile | 1 +
drivers/spi/spi-mem.c | 500 ++++++++++
include/linux/mtd/mtd.h | 33 +-
include/linux/mtd/nand.h | 734 +++++++++++++++
include/linux/mtd/spinand.h | 432 +++++++++
include/spi-mem.h | 258 +++++
include/spi.h | 11 +
80 files changed, 4858 insertions(+), 494 deletions(-)
create mode 100644 cmd/mtd.c
create mode 100644 doc/device-tree-bindings/mtd/spi-nand.txt
create mode 100644 drivers/mtd/nand/bbt.c
create mode 100644 drivers/mtd/nand/core.c
create mode 100644 drivers/mtd/nand/raw/Kconfig
create mode 100644 drivers/mtd/nand/raw/Makefile
rename drivers/mtd/nand/{ => raw}/am335x_spl_bch.c (100%)
rename drivers/mtd/nand/{ => raw}/arasan_nfc.c (100%)
rename drivers/mtd/nand/{ => raw}/atmel_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/atmel_nand_ecc.h (100%)
rename drivers/mtd/nand/{ => raw}/davinci_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/denali.c (100%)
rename drivers/mtd/nand/{ => raw}/denali.h (100%)
rename drivers/mtd/nand/{ => raw}/denali_dt.c (100%)
rename drivers/mtd/nand/{ => raw}/denali_spl.c (100%)
rename drivers/mtd/nand/{ => raw}/fsl_elbc_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/fsl_elbc_spl.c (100%)
rename drivers/mtd/nand/{ => raw}/fsl_ifc_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/fsl_ifc_spl.c (100%)
rename drivers/mtd/nand/{ => raw}/fsl_upm.c (100%)
rename drivers/mtd/nand/{ => raw}/fsmc_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/kb9202_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/kirkwood_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/kmeter1_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/lpc32xx_nand_mlc.c (100%)
rename drivers/mtd/nand/{ => raw}/lpc32xx_nand_slc.c (100%)
rename drivers/mtd/nand/{ => raw}/mxc_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/mxc_nand.h (100%)
rename drivers/mtd/nand/{ => raw}/mxc_nand_spl.c (100%)
rename drivers/mtd/nand/{ => raw}/mxs_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/mxs_nand.h (100%)
rename drivers/mtd/nand/{ => raw}/mxs_nand_dt.c (100%)
rename drivers/mtd/nand/{ => raw}/mxs_nand_spl.c (100%)
rename drivers/mtd/nand/{ => raw}/nand.c (100%)
rename drivers/mtd/nand/{ => raw}/nand_base.c (98%)
rename drivers/mtd/nand/{ => raw}/nand_bbt.c (100%)
rename drivers/mtd/nand/{ => raw}/nand_bch.c (100%)
rename drivers/mtd/nand/{ => raw}/nand_ecc.c (100%)
rename drivers/mtd/nand/{ => raw}/nand_ids.c (100%)
rename drivers/mtd/nand/{ => raw}/nand_plat.c (100%)
rename drivers/mtd/nand/{ => raw}/nand_spl_load.c (100%)
rename drivers/mtd/nand/{ => raw}/nand_spl_loaders.c (100%)
rename drivers/mtd/nand/{ => raw}/nand_spl_simple.c (100%)
rename drivers/mtd/nand/{ => raw}/nand_timings.c (100%)
rename drivers/mtd/nand/{ => raw}/nand_util.c (100%)
rename drivers/mtd/nand/{ => raw}/omap_elm.c (100%)
rename drivers/mtd/nand/{ => raw}/omap_gpmc.c (100%)
rename drivers/mtd/nand/{ => raw}/pxa3xx_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/pxa3xx_nand.h (100%)
rename drivers/mtd/nand/{ => raw}/sunxi_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/sunxi_nand_spl.c (100%)
rename drivers/mtd/nand/{ => raw}/tegra_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/tegra_nand.h (100%)
rename drivers/mtd/nand/{ => raw}/vf610_nfc.c (100%)
rename drivers/mtd/nand/{ => raw}/zynq_nand.c (100%)
create mode 100644 drivers/mtd/nand/spi/Kconfig
create mode 100644 drivers/mtd/nand/spi/Makefile
create mode 100644 drivers/mtd/nand/spi/core.c
create mode 100644 drivers/mtd/nand/spi/macronix.c
create mode 100644 drivers/mtd/nand/spi/micron.c
create mode 100644 drivers/mtd/nand/spi/winbond.c
create mode 100644 drivers/spi/spi-mem.c
create mode 100644 include/linux/mtd/nand.h
create mode 100644 include/linux/mtd/spinand.h
create mode 100644 include/spi-mem.hSignature · 1 line
2.14.1
Miquel Raynal
maintainerPATCH v3 1/21 mtd: Fallback to ->_read/write_oob() when ->_read/write() is missing
From: Boris Brezillon <[email protected]>
Some MTD sublayers/drivers are implementing ->_read/write_oob() and provide dummy wrappers for their ->_read/write() implementations. Let the core handle this case instead of duplicating the logic.
--- drivers/mtd/mtdcore.c | 31 ++++++++++++++++++-- drivers/mtd/mtdpart.c | 6 ++-- drivers/mtd/nand/nand_base.c | 56 ----------------------------------- drivers/mtd/onenand/onenand_base.c | 60 -------------------------------------- 4 files changed, 33 insertions(+), 120 deletions(-)
drivers/mtd/mtdcore.c +29 -2
@@ -937,7 +937,20 @@ int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen,* representing the maximum number of bitflips that were corrected on * any one ecc region (if applicable; zero otherwise). */ - ret_code = mtd->_read (mtd, from, len, retlen, buf); +if (mtd->_read) { + ret_code = mtd->_read (mtd, from, len, retlen, buf); + }else if (mtd->_read_oob) { +struct mtd_oob_ops ops = { + .len = len, + .datbuf = buf, + }; + + ret_code = mtd->_read_oob (mtd, from, &ops); + *retlen = ops.retlen; + }else { +return -ENOTSUPP ; + } +if (unlikely (ret_code <0 ))return ret_code;if (mtd->ecc_strength ==0 )
@@ -952,10 +965,24 @@ int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, *retlen =0 ;if (to <0 || to > mtd->size || len > mtd->size - to)return -EINVAL ; -if (!mtd->_write || !(mtd->flags &MTD_WRITEABLE )) +if ((!mtd->_write && !mtd->_write_oob) || + !(mtd->flags &MTD_WRITEABLE ))return -EROFS ;if (!len)return 0 ; + +if (!mtd->_write) { +struct mtd_oob_ops ops = { + .len = len, + .datbuf = (u8 *)buf, + }; +int ret; + + ret = mtd->_write_oob (mtd, to, &ops); + *retlen = ops.retlen; +return ret; + } +return mtd->_write (mtd, to, len, retlen, buf); }EXPORT_SYMBOL_GPL (mtd_write);
drivers/mtd/mtdpart.c +4 -2
@@ -417,8 +417,10 @@ static struct mtd_part *allocate_partition(struct mtd_info *master, slave->mtd.dev.parent = master->dev.parent;#endif - slave->mtd._read = part_read; - slave->mtd._write = part_write; +if (parent->_read) + slave->mtd._read = part_read; +if (parent->_write) + slave->mtd._write = part_write;if (master->_panic_write) slave->mtd._panic_write = part_panic_write;
drivers/mtd/nand/nand_base.c +0 -56
74 lines not on this page · raw message
drivers/mtd/onenand/onenand_base.c +0 -60
78 lines not on this page · raw message
Signature · 1 line
2.14.1
Miquel Raynal
maintainerPATCH v3 2/21 mtd: Uninline mtd_write_oob and move it to mtdcore.c
In reply to Miquel RaynalFrom: Ezequiel Garcia <[email protected]>
There's no reason for having mtd_write_oob inlined in mtd.h header. Move it to mtdcore.c where it belongs.
--- drivers/mtd/mtdcore.c | 12 ++++++++++++ include/linux/mtd/mtd.h | 12 +----------- 2 files changed, 13 insertions(+), 11 deletions(-)
drivers/mtd/mtdcore.c +12 -0
@@ -1031,6 +1031,18 @@ int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) }EXPORT_SYMBOL_GPL (mtd_read_oob); +int mtd_write_oob (struct mtd_info *mtd,loff_t to, +struct mtd_oob_ops *ops) +{ + ops->retlen = ops->oobretlen =0 ; +if (!mtd->_write_oob) +return -EOPNOTSUPP ; +if (!(mtd->flags &MTD_WRITEABLE )) +return -EROFS ; +return mtd->_write_oob (mtd, to, ops); +} +EXPORT_SYMBOL_GPL (mtd_write_oob); +/** * mtd_ooblayout_ecc - Get the OOB region definition of a specific ECC section * @mtd: MTD device structure
include/linux/mtd/mtd.h +1 -11
@@ -355,17 +355,7 @@ int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);int mtd_read_oob (struct mtd_info *mtd,loff_t from,struct mtd_oob_ops *ops); - -static inline int mtd_write_oob (struct mtd_info *mtd,loff_t to, -struct mtd_oob_ops *ops) -{ - ops->retlen = ops->oobretlen =0 ; -if (!mtd->_write_oob) -return -EOPNOTSUPP ; -if (!(mtd->flags &MTD_WRITEABLE )) -return -EROFS ; -return mtd->_write_oob (mtd, to, ops); -} +int mtd_write_oob (struct mtd_info *mtd,loff_t to,struct mtd_oob_ops *ops);int mtd_get_fact_prot_info (struct mtd_info *mtd,size_t len,size_t *retlen,struct otp_info *buf);
Signature · 1 line
2.14.1
Miquel Raynal
maintainerPATCH v3 3/21 mtd: Add sanity checks in mtd_write/read_oob()
In reply to Miquel RaynalFrom: Boris Brezillon <[email protected]>
Unlike what's done in mtd_read/write(), there are no checks to make sure the parameters passed to mtd_read/write_oob() are consistent, which forces implementers of ->_read/write_oob() to do it, which in turn leads to code duplication and possibly errors in the logic.
Do general sanity checks, like ops fields consistency and range checking.
--- drivers/mtd/mtdcore.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+)
drivers/mtd/mtdcore.c +45 -0
@@ -1010,12 +1010,50 @@ int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, }EXPORT_SYMBOL_GPL (mtd_panic_write); +static int mtd_check_oob_ops (struct mtd_info *mtd,loff_t offs, +struct mtd_oob_ops *ops) +{ +/* +* Some users are setting ->datbuf or ->oobbuf to NULL, but are leaving +* ->len or ->ooblen uninitialized. Force ->len and ->ooblen to 0 in +* this case. +*/ +if (!ops->datbuf) + ops->len =0 ; + +if (!ops->oobbuf) + ops->ooblen =0 ; + +if (offs <0 || offs + ops->len > mtd->size) +return -EINVAL ; + +if (ops->ooblen) { +u64 maxooblen; + +if (ops->ooboffs >=mtd_oobavail (mtd, ops)) +return -EINVAL ; + + maxooblen = ((mtd_div_by_ws (mtd->size, mtd) - +mtd_div_by_ws (offs, mtd)) * +mtd_oobavail (mtd, ops)) - ops->ooboffs; +if (ops->ooblen > maxooblen) +return -EINVAL ; + } + +return 0 ; +} +int mtd_read_oob (struct mtd_info *mtd,loff_t from,struct mtd_oob_ops *ops) {int ret_code; ops->retlen = ops->oobretlen =0 ;if (!mtd->_read_oob)return -EOPNOTSUPP ; + + ret_code =mtd_check_oob_ops (mtd, from, ops); +if (ret_code) +return ret_code; +/* * In cases where ops->datbuf != NULL, mtd->_read_oob() has semantics * similar to mtd->_read(), returning a non-negative integer
@@ -1034,11 +1072,18 @@ EXPORT_SYMBOL_GPL(mtd_read_oob);int mtd_write_oob (struct mtd_info *mtd,loff_t to,struct mtd_oob_ops *ops) { +int ret; + ops->retlen = ops->oobretlen =0 ;if (!mtd->_write_oob)return -EOPNOTSUPP ;if (!(mtd->flags &MTD_WRITEABLE ))return -EROFS ; + + ret =mtd_check_oob_ops (mtd, to, ops); +if (ret) +return ret; +return mtd->_write_oob (mtd, to, ops); }EXPORT_SYMBOL_GPL (mtd_write_oob);
Signature · 1 line
2.14.1
Miquel Raynal
maintainerPATCH v3 4/21 mtd: Fallback to ->_read/write() when ->_read/write_oob() is missing
In reply to Miquel RaynalSome MTD sublayers/drivers are implementing ->_read/write() and not ->_read/write_oob().
While for NAND devices both are usually valid, for NOR devices, using the _oob variant has no real meaning. But, as the MTD layer is supposed to hide as much as possible the flash complexity to the user, there is no reason to error out while it is just a matter of rewritting things internally.
Add a fallback on mtd->_read() (resp. mtd->_write()) when the user calls mtd_read_oob() (resp. mtd_write_oob()) while mtd->_read_oob() (resp. mtd->_write_oob) is not implemented. There is already a fallback on the _oob variant if the former is used.
--- drivers/mtd/mtdcore.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-)
drivers/mtd/mtdcore.c +20 -6
@@ -1047,20 +1047,27 @@ int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) {int ret_code; ops->retlen = ops->oobretlen =0 ; -if (!mtd->_read_oob) -return -EOPNOTSUPP ; ret_code =mtd_check_oob_ops (mtd, from, ops);if (ret_code)return ret_code; +/* Check the validity of a potential fallback on mtd->_read */ +if (!mtd->_read_oob && (!mtd->_read || ops->oobbuf)) +return -EOPNOTSUPP ; + +if (mtd->_read_oob) + ret_code = mtd->_read_oob (mtd, from, ops); +else + ret_code = mtd->_read (mtd, from, ops->len, &ops->retlen, + ops->datbuf); +/* * In cases where ops->datbuf != NULL, mtd->_read_oob() has semantics * similar to mtd->_read(), returning a non-negative integer * representing max bitflips. In other cases, mtd->_read_oob() may * return -EUCLEAN. In all cases, perform similar logic to mtd_read(). */ - ret_code = mtd->_read_oob (mtd, from, ops);if (unlikely (ret_code <0 ))return ret_code;if (mtd->ecc_strength ==0 )
@@ -1075,8 +1082,7 @@ int mtd_write_oob(struct mtd_info *mtd, loff_t to,int ret; ops->retlen = ops->oobretlen =0 ; -if (!mtd->_write_oob) -return -EOPNOTSUPP ; +if (!(mtd->flags &MTD_WRITEABLE ))return -EROFS ;
@@ -1084,7 +1090,15 @@ int mtd_write_oob(struct mtd_info *mtd, loff_t to,if (ret)return ret; -return mtd->_write_oob (mtd, to, ops); +/* Check the validity of a potential fallback on mtd->_write */ +if (!mtd->_write_oob && (!mtd->_write || ops->oobbuf)) +return -EOPNOTSUPP ; + +if (mtd->_write_oob) +return mtd->_write_oob (mtd, to, ops); +else +return mtd->_write (mtd, to, ops->len, &ops->retlen, + ops->datbuf); }EXPORT_SYMBOL_GPL (mtd_write_oob);
Signature · 1 line
2.14.1
Miquel Raynal
maintainerPATCH v3 5/21 mtd: add get/set of_node/flash_node helpers
In reply to Miquel RaynalFrom: Brian Norris <[email protected]>
We are going to begin using the mtd->dev.of_node field for MTD device nodes, so let's add helpers for it. Also, we'll be making some conversions on spi_nor (and nand_chip eventually) too, so get that ready with their own helpers.
--- include/linux/mtd/mtd.h | 11 +++++++++++ 1 file changed, 11 insertions(+)
include/linux/mtd/mtd.h +11 -0
@@ -310,6 +310,17 @@ struct mtd_info {int usecount; }; +static inline void mtd_set_of_node (struct mtd_info *mtd, +const struct device_node *np) +{ + mtd->dev->node.np = np; +} + +static inline const struct device_node *mtd_get_of_node (struct mtd_info *mtd) +{ +return mtd->dev->node.np; +} +int mtd_ooblayout_ecc (struct mtd_info *mtd,int section,struct mtd_oob_region *oobecc); int mtd_ooblayout_find_eccregion(struct mtd_info *mtd, int eccbyte,
Signature · 1 line
2.14.1
Miquel Raynal
maintainerPATCH v3 6/21 mtd: fix build issue with includes
In reply to Miquel RaynalFix build errors produced by mtd.h and dm/device.h if not included in the right order.
--- include/linux/mtd/mtd.h | 1 + 1 file changed, 1 insertion(+)
include/linux/mtd/mtd.h +1 -0
@@ -21,6 +21,7 @@#include <mtd/mtd-abi.h> #include <linux/errno.h> #include <div64.h> +#include <dm/device.h> #define MAX_MTD_DEVICES 32#endif
Signature · 1 line
2.14.1
Miquel Raynal
maintainerPATCH v3 7/21 mtd: move definitions to enlarge their range
In reply to Miquel RaynalSome helpers might be useful in a future 'mtd' U-Boot command to parse MTD device list.
--- drivers/mtd/mtdcore.h | 6 ------ include/linux/mtd/mtd.h | 6 ++++++ 2 files changed, 6 insertions(+), 6 deletions(-)
drivers/mtd/mtdcore.h +0 -6
@@ -5,7 +5,6 @@extern struct mutex mtd_table_mutex; -struct mtd_info *__mtd_next_device (int i);int add_mtd_device (struct mtd_info *mtd);int del_mtd_device (struct mtd_info *mtd);int add_mtd_partitions (struct mtd_info *,const struct mtd_partition *,int );
@@ -16,8 +15,3 @@ int parse_mtd_partitions(struct mtd_info *master, const char * const *types,int __init init_mtdchar (void ); void __exit cleanup_mtdchar(void); - -#define mtd_for_each_device (mtd) \ - for ((mtd) = __mtd_next_device(0); \ - (mtd) != NULL; \ - (mtd) = __mtd_next_device(mtd->index + 1))
include/linux/mtd/mtd.h +6 -0
@@ -521,6 +521,12 @@ int del_mtd_device(struct mtd_info *mtd);int add_mtd_partitions (struct mtd_info *,const struct mtd_partition *,int );int del_mtd_partitions (struct mtd_info *); +struct mtd_info *__mtd_next_device (int i); +#define mtd_for_each_device (mtd) \ + for ((mtd) = __mtd_next_device(0); \ + (mtd) != NULL; \ + (mtd) = __mtd_next_device(mtd->index + 1)) +int mtd_arg_off (const char *arg,int *idx,loff_t *off,loff_t *size,loff_t *maxsize,int devtype,uint64_t chipsize); int mtd_arg_off_size(int argc, char *const argv[], int *idx, loff_t *off,
Signature · 1 line
2.14.1
Miquel Raynal
maintainerPATCH v3 8/21 mtd: move all flash categories inside MTD submenu
In reply to Miquel RaynalThere is no reason to have NAND, SPI flashes and UBI sections outside of the MTD submenu in Kconfig.
--- drivers/mtd/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/mtd/Kconfig +2 -2
@@ -47,10 +47,10 @@ config RENESAS_RPC_HF This enables access to Hyperflash memory through the Renesas RCar Gen3 RPC controller. -endmenu - source "drivers/mtd/nand/Kconfig" source "drivers/mtd/spi/Kconfig" source "drivers/mtd/ubi/Kconfig" + +endmenu
Signature · 1 line
2.14.1
Miquel Raynal
maintainerPATCH v3 9/21 mtd: move NAND files into a raw/ subdirectory
In reply to Miquel RaynalNAND flavors, like serial and parallel, have a lot in common and would benefit to share code. Let's move raw (parallel) NAND specific code in a raw/ subdirectory, to ease the addition of a core file in nand/ and the introduction of a spi/ subdirectory specific to SPI NANDs.
---
drivers/mtd/Makefile | 2 +
drivers/mtd/nand/Kconfig | 280 +-------------------------
drivers/mtd/nand/Makefile | 76 +------
drivers/mtd/nand/raw/Kconfig | 279 +++++++++++++++++++++++++
drivers/mtd/nand/raw/Makefile | 77 +++++++
drivers/mtd/nand/{ => raw}/am335x_spl_bch.c | 0
drivers/mtd/nand/{ => raw}/arasan_nfc.c | 0
drivers/mtd/nand/{ => raw}/atmel_nand.c | 0
drivers/mtd/nand/{ => raw}/atmel_nand_ecc.h | 0
drivers/mtd/nand/{ => raw}/davinci_nand.c | 0
drivers/mtd/nand/{ => raw}/denali.c | 0
drivers/mtd/nand/{ => raw}/denali.h | 0
drivers/mtd/nand/{ => raw}/denali_dt.c | 0
drivers/mtd/nand/{ => raw}/denali_spl.c | 0
drivers/mtd/nand/{ => raw}/fsl_elbc_nand.c | 0
drivers/mtd/nand/{ => raw}/fsl_elbc_spl.c | 0
drivers/mtd/nand/{ => raw}/fsl_ifc_nand.c | 0
drivers/mtd/nand/{ => raw}/fsl_ifc_spl.c | 0
drivers/mtd/nand/{ => raw}/fsl_upm.c | 0
drivers/mtd/nand/{ => raw}/fsmc_nand.c | 0
drivers/mtd/nand/{ => raw}/kb9202_nand.c | 0
drivers/mtd/nand/{ => raw}/kirkwood_nand.c | 0
drivers/mtd/nand/{ => raw}/kmeter1_nand.c | 0
drivers/mtd/nand/{ => raw}/lpc32xx_nand_mlc.c | 0
drivers/mtd/nand/{ => raw}/lpc32xx_nand_slc.c | 0
drivers/mtd/nand/{ => raw}/mxc_nand.c | 0
drivers/mtd/nand/{ => raw}/mxc_nand.h | 0
drivers/mtd/nand/{ => raw}/mxc_nand_spl.c | 0
drivers/mtd/nand/{ => raw}/mxs_nand.c | 0
drivers/mtd/nand/{ => raw}/mxs_nand.h | 0
drivers/mtd/nand/{ => raw}/mxs_nand_dt.c | 0
drivers/mtd/nand/{ => raw}/mxs_nand_spl.c | 0
drivers/mtd/nand/{ => raw}/nand.c | 0
drivers/mtd/nand/{ => raw}/nand_base.c | 0
drivers/mtd/nand/{ => raw}/nand_bbt.c | 0
drivers/mtd/nand/{ => raw}/nand_bch.c | 0
drivers/mtd/nand/{ => raw}/nand_ecc.c | 0
drivers/mtd/nand/{ => raw}/nand_ids.c | 0
drivers/mtd/nand/{ => raw}/nand_plat.c | 0
drivers/mtd/nand/{ => raw}/nand_spl_load.c | 0
drivers/mtd/nand/{ => raw}/nand_spl_loaders.c | 0
drivers/mtd/nand/{ => raw}/nand_spl_simple.c | 0
drivers/mtd/nand/{ => raw}/nand_timings.c | 0
drivers/mtd/nand/{ => raw}/nand_util.c | 0
drivers/mtd/nand/{ => raw}/omap_elm.c | 0
drivers/mtd/nand/{ => raw}/omap_gpmc.c | 0
drivers/mtd/nand/{ => raw}/pxa3xx_nand.c | 0
drivers/mtd/nand/{ => raw}/pxa3xx_nand.h | 0
drivers/mtd/nand/{ => raw}/sunxi_nand.c | 0
drivers/mtd/nand/{ => raw}/sunxi_nand_spl.c | 0
drivers/mtd/nand/{ => raw}/tegra_nand.c | 0
drivers/mtd/nand/{ => raw}/tegra_nand.h | 0
drivers/mtd/nand/{ => raw}/vf610_nfc.c | 0
drivers/mtd/nand/{ => raw}/zynq_nand.c | 0
54 files changed, 360 insertions(+), 354 deletions(-)
create mode 100644 drivers/mtd/nand/raw/Kconfig
create mode 100644 drivers/mtd/nand/raw/Makefile
rename drivers/mtd/nand/{ => raw}/am335x_spl_bch.c (100%)
rename drivers/mtd/nand/{ => raw}/arasan_nfc.c (100%)
rename drivers/mtd/nand/{ => raw}/atmel_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/atmel_nand_ecc.h (100%)
rename drivers/mtd/nand/{ => raw}/davinci_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/denali.c (100%)
rename drivers/mtd/nand/{ => raw}/denali.h (100%)
rename drivers/mtd/nand/{ => raw}/denali_dt.c (100%)
rename drivers/mtd/nand/{ => raw}/denali_spl.c (100%)
rename drivers/mtd/nand/{ => raw}/fsl_elbc_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/fsl_elbc_spl.c (100%)
rename drivers/mtd/nand/{ => raw}/fsl_ifc_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/fsl_ifc_spl.c (100%)
rename drivers/mtd/nand/{ => raw}/fsl_upm.c (100%)
rename drivers/mtd/nand/{ => raw}/fsmc_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/kb9202_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/kirkwood_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/kmeter1_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/lpc32xx_nand_mlc.c (100%)
rename drivers/mtd/nand/{ => raw}/lpc32xx_nand_slc.c (100%)
rename drivers/mtd/nand/{ => raw}/mxc_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/mxc_nand.h (100%)
rename drivers/mtd/nand/{ => raw}/mxc_nand_spl.c (100%)
rename drivers/mtd/nand/{ => raw}/mxs_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/mxs_nand.h (100%)
rename drivers/mtd/nand/{ => raw}/mxs_nand_dt.c (100%)
rename drivers/mtd/nand/{ => raw}/mxs_nand_spl.c (100%)
rename drivers/mtd/nand/{ => raw}/nand.c (100%)
rename drivers/mtd/nand/{ => raw}/nand_base.c (100%)
rename drivers/mtd/nand/{ => raw}/nand_bbt.c (100%)
rename drivers/mtd/nand/{ => raw}/nand_bch.c (100%)
rename drivers/mtd/nand/{ => raw}/nand_ecc.c (100%)
rename drivers/mtd/nand/{ => raw}/nand_ids.c (100%)
rename drivers/mtd/nand/{ => raw}/nand_plat.c (100%)
rename drivers/mtd/nand/{ => raw}/nand_spl_load.c (100%)
rename drivers/mtd/nand/{ => raw}/nand_spl_loaders.c (100%)
rename drivers/mtd/nand/{ => raw}/nand_spl_simple.c (100%)
rename drivers/mtd/nand/{ => raw}/nand_timings.c (100%)
rename drivers/mtd/nand/{ => raw}/nand_util.c (100%)
rename drivers/mtd/nand/{ => raw}/omap_elm.c (100%)
rename drivers/mtd/nand/{ => raw}/omap_gpmc.c (100%)
rename drivers/mtd/nand/{ => raw}/pxa3xx_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/pxa3xx_nand.h (100%)
rename drivers/mtd/nand/{ => raw}/sunxi_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/sunxi_nand_spl.c (100%)
rename drivers/mtd/nand/{ => raw}/tegra_nand.c (100%)
rename drivers/mtd/nand/{ => raw}/tegra_nand.h (100%)
rename drivers/mtd/nand/{ => raw}/vf610_nfc.c (100%)
rename drivers/mtd/nand/{ => raw}/zynq_nand.c (100%)drivers/mtd/Makefile +2 -0
@@ -18,3 +18,5 @@ obj-$(CONFIG_FLASH_PIC32) += pic32_flash.o obj-$(CONFIG_ST_SMI) += st_smi.o obj-$(CONFIG_STM32_FLASH) += stm32_flash.o obj-$(CONFIG_RENESAS_RPC_HF) += renesas_rpc_hf.o + +obj-y += nand/
drivers/mtd/nand/Kconfig +1 -279
280 lines not on this page · raw message
drivers/mtd/nand/Makefile +1 -75
78 lines not on this page · raw message
drivers/mtd/nand/raw/Kconfig new file +279 -0
279 lines not on this page · raw message
drivers/mtd/nand/raw/Makefile new file +77 -0
77 lines not on this page · raw message
drivers/mtd/nand/raw/am335x_spl_bch.c renamed from drivers/mtd/nand/am335x_spl_bch.c +0 -0
drivers/mtd/nand/raw/arasan_nfc.c renamed from drivers/mtd/nand/arasan_nfc.c +0 -0
drivers/mtd/nand/raw/atmel_nand.c renamed from drivers/mtd/nand/atmel_nand.c +0 -0
drivers/mtd/nand/raw/atmel_nand_ecc.h renamed from drivers/mtd/nand/atmel_nand_ecc.h +0 -0
drivers/mtd/nand/raw/davinci_nand.c renamed from drivers/mtd/nand/davinci_nand.c +0 -0
drivers/mtd/nand/raw/denali.c renamed from drivers/mtd/nand/denali.c +0 -0
drivers/mtd/nand/raw/denali.h renamed from drivers/mtd/nand/denali.h +0 -0
drivers/mtd/nand/raw/denali_dt.c renamed from drivers/mtd/nand/denali_dt.c +0 -0
drivers/mtd/nand/raw/denali_spl.c renamed from drivers/mtd/nand/denali_spl.c +0 -0
drivers/mtd/nand/raw/fsl_elbc_nand.c renamed from drivers/mtd/nand/fsl_elbc_nand.c +0 -0
drivers/mtd/nand/raw/fsl_elbc_spl.c renamed from drivers/mtd/nand/fsl_elbc_spl.c +0 -0
drivers/mtd/nand/raw/fsl_ifc_nand.c renamed from drivers/mtd/nand/fsl_ifc_nand.c +0 -0
drivers/mtd/nand/raw/fsl_ifc_spl.c renamed from drivers/mtd/nand/fsl_ifc_spl.c +0 -0
drivers/mtd/nand/raw/fsl_upm.c renamed from drivers/mtd/nand/fsl_upm.c +0 -0
drivers/mtd/nand/raw/fsmc_nand.c renamed from drivers/mtd/nand/fsmc_nand.c +0 -0
drivers/mtd/nand/raw/kb9202_nand.c renamed from drivers/mtd/nand/kb9202_nand.c +0 -0
drivers/mtd/nand/raw/kirkwood_nand.c renamed from drivers/mtd/nand/kirkwood_nand.c +0 -0
drivers/mtd/nand/raw/kmeter1_nand.c renamed from drivers/mtd/nand/kmeter1_nand.c +0 -0
drivers/mtd/nand/raw/lpc32xx_nand_mlc.c renamed from drivers/mtd/nand/lpc32xx_nand_mlc.c +0 -0
drivers/mtd/nand/raw/lpc32xx_nand_slc.c renamed from drivers/mtd/nand/lpc32xx_nand_slc.c +0 -0
drivers/mtd/nand/raw/mxc_nand.c renamed from drivers/mtd/nand/mxc_nand.c +0 -0
drivers/mtd/nand/raw/mxc_nand.h renamed from drivers/mtd/nand/mxc_nand.h +0 -0
drivers/mtd/nand/raw/mxc_nand_spl.c renamed from drivers/mtd/nand/mxc_nand_spl.c +0 -0
drivers/mtd/nand/raw/mxs_nand.c renamed from drivers/mtd/nand/mxs_nand.c +0 -0
drivers/mtd/nand/raw/mxs_nand.h renamed from drivers/mtd/nand/mxs_nand.h +0 -0
drivers/mtd/nand/raw/mxs_nand_dt.c renamed from drivers/mtd/nand/mxs_nand_dt.c +0 -0
drivers/mtd/nand/raw/mxs_nand_spl.c renamed from drivers/mtd/nand/mxs_nand_spl.c +0 -0
drivers/mtd/nand/raw/nand.c renamed from drivers/mtd/nand/nand.c +0 -0
drivers/mtd/nand/raw/nand_base.c renamed from drivers/mtd/nand/nand_base.c +0 -0
drivers/mtd/nand/raw/nand_bbt.c renamed from drivers/mtd/nand/nand_bbt.c +0 -0
drivers/mtd/nand/raw/nand_bch.c renamed from drivers/mtd/nand/nand_bch.c +0 -0
drivers/mtd/nand/raw/nand_ecc.c renamed from drivers/mtd/nand/nand_ecc.c +0 -0
drivers/mtd/nand/raw/nand_ids.c renamed from drivers/mtd/nand/nand_ids.c +0 -0
drivers/mtd/nand/raw/nand_plat.c renamed from drivers/mtd/nand/nand_plat.c +0 -0
drivers/mtd/nand/raw/nand_spl_load.c renamed from drivers/mtd/nand/nand_spl_load.c +0 -0
drivers/mtd/nand/raw/nand_spl_loaders.c renamed from drivers/mtd/nand/nand_spl_loaders.c +0 -0
drivers/mtd/nand/raw/nand_spl_simple.c renamed from drivers/mtd/nand/nand_spl_simple.c +0 -0
drivers/mtd/nand/raw/nand_timings.c renamed from drivers/mtd/nand/nand_timings.c +0 -0
drivers/mtd/nand/raw/nand_util.c renamed from drivers/mtd/nand/nand_util.c +0 -0
drivers/mtd/nand/raw/omap_elm.c renamed from drivers/mtd/nand/omap_elm.c +0 -0
drivers/mtd/nand/raw/omap_gpmc.c renamed from drivers/mtd/nand/omap_gpmc.c +0 -0
drivers/mtd/nand/raw/pxa3xx_nand.c renamed from drivers/mtd/nand/pxa3xx_nand.c +0 -0
drivers/mtd/nand/raw/pxa3xx_nand.h renamed from drivers/mtd/nand/pxa3xx_nand.h +0 -0
drivers/mtd/nand/raw/sunxi_nand.c renamed from drivers/mtd/nand/sunxi_nand.c +0 -0
drivers/mtd/nand/raw/sunxi_nand_spl.c renamed from drivers/mtd/nand/sunxi_nand_spl.c +0 -0
drivers/mtd/nand/raw/tegra_nand.c renamed from drivers/mtd/nand/tegra_nand.c +0 -0
drivers/mtd/nand/raw/tegra_nand.h renamed from drivers/mtd/nand/tegra_nand.h +0 -0
drivers/mtd/nand/raw/vf610_nfc.c renamed from drivers/mtd/nand/vf610_nfc.c +0 -0
drivers/mtd/nand/raw/zynq_nand.c renamed from drivers/mtd/nand/zynq_nand.c +0 -0
Signature · 1 line
2.14.1
Miquel Raynal
maintainerPATCH v3 10/21 mtd: rename nand into rawnand in Kconfig prompt
In reply to Miquel RaynalSync the Kconfig raw NAND entry title with the code architecture.
--- drivers/mtd/nand/raw/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/mtd/nand/raw/Kconfig +1 -1
@@ -1,6 +1,6 @@ menuconfig NAND - bool "NAND Device Support" + bool "Raw NAND Device Support" if NAND config SYS_NAND_SELF_INIT
Signature · 1 line
2.14.1
Miquel Raynal
maintainerPATCH v3 11/21 mtd: nand: Add core infrastructure to deal with NAND devices
In reply to Miquel RaynalFrom: Boris Brezillon <[email protected]>
Add an intermediate layer to abstract NAND device interface so that some logic can be shared between SPI NANDs, parallel/raw NANDs, OneNANDs, ...
--- drivers/mtd/nand/Kconfig | 3 + drivers/mtd/nand/Makefile | 2 + drivers/mtd/nand/bbt.c | 132 +++++++++ drivers/mtd/nand/core.c | 243 +++++++++++++++ include/linux/mtd/nand.h | 731 ++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 1111 insertions(+) create mode 100644 drivers/mtd/nand/bbt.c create mode 100644 drivers/mtd/nand/core.c create mode 100644 include/linux/mtd/nand.h
drivers/mtd/nand/Kconfig +3 -0
@@ -1 +1,4 @@ +config MTD_NAND_CORE + tristate + source "drivers/mtd/nand/raw/Kconfig"
drivers/mtd/nand/Makefile +2 -0
@@ -1,3 +1,5 @@ # SPDX-License-Identifier: GPL-2.0+ +nandcore-objs := core.o bbt.o +obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o obj-$(CONFIG_MTD_NAND) += raw/
drivers/mtd/nand/bbt.c new file +132 -0
132 lines not on this page · raw message
drivers/mtd/nand/core.c new file +243 -0
243 lines not on this page · raw message
include/linux/mtd/nand.h new file +731 -0
731 lines not on this page · raw message
Signature · 1 line
2.14.1
Miquel Raynal
maintainerPATCH v3 12/21 mtd: nand: Pass mode information to nand_page_io_req
In reply to Miquel RaynalFrom: Boris Brezillon <[email protected]>
The NAND sub-layers are likely to need the MTD_OPS_XXX mode information in order to decide if they should enable/disable ECC or how they should place the OOB bytes in the provided OOB buffer.
Add a field to nand_page_io_req to pass this information.
--- include/linux/mtd/nand.h | 3 +++ 1 file changed, 3 insertions(+)
include/linux/mtd/nand.h +3 -0
@@ -86,6 +86,7 @@ struct nand_pos {* @ooboffs: the OOB offset within the page * @ooblen: the number of OOB bytes to read from/write to this page * @oobbuf: buffer to store OOB data in or get OOB data from +* @mode: one of the %MTD_OPS_XXX mode * * This object is used to pass per-page I/O requests to NAND sub-layers. This * way all useful information are already formatted in a useful way and
@@ -106,6 +107,7 @@ struct nand_page_io_req {const void *out;void *in; } oobbuf; +int mode; };/**
@@ -599,6 +601,7 @@ static inline void nanddev_io_iter_init(struct nand_device *nand, {struct mtd_info *mtd =nanddev_to_mtd (nand); + iter->req.mode = req->mode; iter->req.dataoffs =nanddev_offs_to_pos (nand, offs, &iter->req.pos); iter->req.ooboffs = req->ooboffs; iter->oobbytes_per_page =mtd_oobavail (mtd, req);
Signature · 1 line
2.14.1
Miquel Raynal
maintainerPATCH v3 13/21 spi: Extend the core to ease integration of SPI memory controllers
In reply to Miquel RaynalFrom: Boris Brezillon <[email protected]>
Some controllers are exposing high-level interfaces to access various kind of SPI memories. Unfortunately they do not fit in the current spi_controller model and usually have drivers placed in drivers/mtd/spi-nor which are only supporting SPI NORs and not SPI memories in general.
This is an attempt at defining a SPI memory interface which works for all kinds of SPI memories (NORs, NANDs, SRAMs).
--- drivers/spi/Kconfig | 7 + drivers/spi/Makefile | 1 + drivers/spi/spi-mem.c | 500 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/spi-mem.h | 258 ++++++++++++++++++++++++++ include/spi.h | 11 ++ 5 files changed, 777 insertions(+) create mode 100644 drivers/spi/spi-mem.c create mode 100644 include/spi-mem.h
drivers/spi/Kconfig +7 -0
@@ -18,6 +18,13 @@ config DM_SPI if DM_SPI +config SPI_MEM + bool "SPI memory extension" + help + Enable this option if you want to enable the SPI memory extension. + This extension is meant to simplify interaction with SPI memories + by providing an high-level interface to send memory-like commands. + config ALTERA_SPI bool "Altera SPI driver" help
drivers/spi/Makefile +1 -0
@@ -8,6 +8,7 @@ ifdef CONFIG_DM_SPI obj-y += spi-uclass.o obj-$(CONFIG_SANDBOX) += spi-emul-uclass.o obj-$(CONFIG_SOFT_SPI) += soft_spi.o +obj-$(CONFIG_SPI_MEM) += spi-mem.o else obj-y += spi.o obj-$(CONFIG_SOFT_SPI) += soft_spi_legacy.o
drivers/spi/spi-mem.c new file +500 -0
500 lines not on this page · raw message
include/spi-mem.h new file +258 -0
258 lines not on this page · raw message
include/spi.h +11 -0
@@ -9,6 +9,8 @@#ifndef _SPI_H_#define _SPI_H_ +#include <common.h> +/* SPI mode flags */ #define SPI_CPHA BIT(0)/* clock phase */ #define SPI_CPOL BIT(1)/* clock polarity */
@@ -402,6 +404,15 @@ struct dm_spi_ops {int (*xfer)(struct udevice *dev,unsigned int bitlen,const void *dout,void *din,unsigned long flags); +/** +* Optimized handlers for SPI memory-like operations. +* +* Optimized/dedicated operations for interactions with SPI memory. This +* field is optional and should only be implemented if the controller +* has native support for memory like operations. +*/ +const struct spi_controller_mem_ops *mem_ops; +/** * Set transfer speed. * This sets a new speed to be applied for next spi_xfer().
Signature · 1 line
2.14.1
Miquel Raynal
maintainerPATCH v3 14/21 mtd: nand: Add core infrastructure to support SPI NANDs
In reply to Miquel RaynalFrom: Peter Pan <[email protected]>
Add a SPI NAND framework based on the generic NAND framework and the spi-mem infrastructure.
In its current state, this framework supports the following features:
- single/dual/quad IO modes
- on-die ECC
--- drivers/mtd/nand/Kconfig | 2 + drivers/mtd/nand/Makefile | 1 + drivers/mtd/nand/spi/Kconfig | 7 + drivers/mtd/nand/spi/Makefile | 4 + drivers/mtd/nand/spi/core.c | 1235 +++++++++++++++++++++++++++++++++++++++++ include/linux/mtd/spinand.h | 427 ++++++++++++++ 6 files changed, 1676 insertions(+) create mode 100644 drivers/mtd/nand/spi/Kconfig create mode 100644 drivers/mtd/nand/spi/Makefile create mode 100644 drivers/mtd/nand/spi/core.c create mode 100644 include/linux/mtd/spinand.h
drivers/mtd/nand/Kconfig +2 -0
@@ -2,3 +2,5 @@ config MTD_NAND_CORE tristate source "drivers/mtd/nand/raw/Kconfig" + +source "drivers/mtd/nand/spi/Kconfig"
drivers/mtd/nand/Makefile +1 -0
@@ -3,3 +3,4 @@ nandcore-objs := core.o bbt.o obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o obj-$(CONFIG_MTD_NAND) += raw/ +obj-$(CONFIG_MTD_SPI_NAND) += spi/
drivers/mtd/nand/spi/Kconfig new file +7 -0
@@ -0,0 +1,7 @@ +menuconfig MTD_SPI_NAND + bool "SPI NAND device Support" + depends on MTD && DM_SPI + select MTD_NAND_CORE + select SPI_MEM + help + This is the framework for the SPI NAND device drivers.
drivers/mtd/nand/spi/Makefile new file +4 -0
@@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 + +spinand-objs := core.o +obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
drivers/mtd/nand/spi/core.c new file +1235 -0
1,235 lines not on this page · raw message
include/linux/mtd/spinand.h new file +427 -0
427 lines not on this page · raw message
Signature · 1 line
2.14.1
Miquel Raynal
maintainerPATCH v3 15/21 mtd: spinand: Add initial support for Micron MT29F2G01ABAGD
In reply to Miquel RaynalFrom: Peter Pan <[email protected]>
Add a basic driver for Micron SPI NANDs. Only one device is supported right now, but the driver will be extended to support more devices afterwards.
--- drivers/mtd/nand/spi/Makefile | 2 +- drivers/mtd/nand/spi/core.c | 17 ++++++ drivers/mtd/nand/spi/micron.c | 135 ++++++++++++++++++++++++++++++++++++++++++ include/linux/mtd/spinand.h | 3 + 4 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 drivers/mtd/nand/spi/micron.c
drivers/mtd/nand/spi/Makefile +1 -1
@@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -spinand-objs := core.o +spinand-objs := core.o micron.o obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
drivers/mtd/nand/spi/core.c +17 -0
@@ -829,8 +829,25 @@ static const struct nand_ops spinand_ops = { .isbad = spinand_isbad, }; +static const struct spinand_manufacturer *spinand_manufacturers[] = { + µn_spinand_manufacturer, +}; +static int spinand_manufacturer_detect (struct spinand_device *spinand) { +unsigned int i; +int ret; + +for (i =0 ; i <ARRAY_SIZE (spinand_manufacturers); i++) { + ret = spinand_manufacturers[i]->ops->detect (spinand); +if (ret >0 ) { + spinand->manufacturer = spinand_manufacturers[i]; +return 0 ; + }else if (ret <0 ) { +return ret; + } + } +return -ENOTSUPP ; }
drivers/mtd/nand/spi/micron.c new file +135 -0
135 lines not on this page · raw message
include/linux/mtd/spinand.h +3 -0
@@ -200,6 +200,9 @@ struct spinand_manufacturer {const struct spinand_manufacturer_ops *ops; }; +/* SPI NAND manufacturers */ +extern const struct spinand_manufacturer micron_spinand_manufacturer; +/** * struct spinand_op_variants - SPI NAND operation variants * @ops: the list of variants for a given operation
Signature · 1 line
2.14.1
Miquel Raynal
maintainerPATCH v3 16/21 mtd: spinand: Add initial support for Winbond W25M02GV
In reply to Miquel RaynalFrom: Frieder Schrempf <[email protected]>
Add support for the W25M02GV chip.
--- drivers/mtd/nand/spi/Makefile | 2 +- drivers/mtd/nand/spi/core.c | 1 + drivers/mtd/nand/spi/winbond.c | 143 +++++++++++++++++++++++++++++++++++++++++ include/linux/mtd/spinand.h | 1 + 4 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 drivers/mtd/nand/spi/winbond.c
drivers/mtd/nand/spi/Makefile +1 -1
@@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -spinand-objs := core.o micron.o +spinand-objs := core.o micron.o winbond.o obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
drivers/mtd/nand/spi/core.c +1 -0
@@ -831,6 +831,7 @@ static const struct nand_ops spinand_ops = {static const struct spinand_manufacturer *spinand_manufacturers[] = { µn_spinand_manufacturer, + &winbond_spinand_manufacturer, };static int spinand_manufacturer_detect (struct spinand_device *spinand)
drivers/mtd/nand/spi/winbond.c new file +143 -0
143 lines not on this page · raw message
include/linux/mtd/spinand.h +1 -0
@@ -202,6 +202,7 @@ struct spinand_manufacturer {/* SPI NAND manufacturers */ extern const struct spinand_manufacturer micron_spinand_manufacturer; +extern const struct spinand_manufacturer winbond_spinand_manufacturer;/** * struct spinand_op_variants - SPI NAND operation variants
Signature · 1 line
2.14.1
Miquel Raynal
maintainerPATCH v3 17/21 mtd: spinand: Add initial support for the MX35LF1GE4AB chip
In reply to Miquel RaynalFrom: Boris Brezillon <[email protected]>
Add minimal support for the MX35LF1GE4AB SPI NAND chip.
--- drivers/mtd/nand/spi/Makefile | 2 +- drivers/mtd/nand/spi/core.c | 1 + drivers/mtd/nand/spi/macronix.c | 138 ++++++++++++++++++++++++++++++++++++++++ include/linux/mtd/spinand.h | 1 + 4 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 drivers/mtd/nand/spi/macronix.c
drivers/mtd/nand/spi/Makefile +1 -1
@@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -spinand-objs := core.o micron.o winbond.o +spinand-objs := core.o macronix.o micron.o winbond.o obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
drivers/mtd/nand/spi/core.c +1 -0
@@ -830,6 +830,7 @@ static const struct nand_ops spinand_ops = { };static const struct spinand_manufacturer *spinand_manufacturers[] = { + ¯onix_spinand_manufacturer, µn_spinand_manufacturer, &winbond_spinand_manufacturer, };
drivers/mtd/nand/spi/macronix.c new file +138 -0
138 lines not on this page · raw message
include/linux/mtd/spinand.h +1 -0
@@ -201,6 +201,7 @@ struct spinand_manufacturer { };/* SPI NAND manufacturers */ +extern const struct spinand_manufacturer macronix_spinand_manufacturer;extern const struct spinand_manufacturer micron_spinand_manufacturer;extern const struct spinand_manufacturer winbond_spinand_manufacturer;
Signature · 1 line
2.14.1
Miquel Raynal
maintainerPATCH v3 18/21 mtd: spinand: Add initial support for the MX35LF2GE4AB chip
In reply to Miquel RaynalAdd support for the MX35LF2GE4AB chip, which is similar to its cousin MX35LF1GE4AB, with two planes instead of one.
--- drivers/mtd/nand/spi/macronix.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
drivers/mtd/nand/spi/macronix.c +14 -6
@@ -27,13 +27,13 @@ static SPINAND_OP_VARIANTS(update_cache_variants,SPINAND_PROG_LOAD_X4 (false,0 ,NULL ,0 ), SPINAND_PROG_LOAD(false, 0, NULL, 0)); -static int mx35lf1ge4ab_ooblayout_ecc (struct mtd_info *mtd,int section, +static int mx35lfxge4ab_ooblayout_ecc (struct mtd_info *mtd,int section,struct mtd_oob_region *region) {return -ERANGE ; } -static int mx35lf1ge4ab_ooblayout_free (struct mtd_info *mtd,int section, +static int mx35lfxge4ab_ooblayout_free (struct mtd_info *mtd,int section,struct mtd_oob_region *region) {if (section)
@@ -45,9 +45,9 @@ static int mx35lf1ge4ab_ooblayout_free(struct mtd_info *mtd, int section,return 0 ; } -static const struct mtd_ooblayout_ops mx35lf1ge4ab_ooblayout = { - .ecc = mx35lf1ge4ab_ooblayout_ecc, - .free = mx35lf1ge4ab_ooblayout_free, +static const struct mtd_ooblayout_ops mx35lfxge4ab_ooblayout = { + .ecc = mx35lfxge4ab_ooblayout_ecc, + .free = mx35lfxge4ab_ooblayout_free, };static int mx35lf1ge4ab_get_eccsr (struct spinand_device *spinand,u8 *eccsr)
@@ -102,8 +102,16 @@ static const struct spinand_info macronix_spinand_table[] = { &write_cache_variants, &update_cache_variants), SPINAND_HAS_QE_BIT, - SPINAND_ECCINFO(&mx35lf1ge4ab_ooblayout, + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, mx35lf1ge4ab_ecc_get_status)), +SPINAND_INFO ("MX35LF2GE4AB" ,0x22 , +NAND_MEMORG (1 ,2048 ,64 ,64 ,2048 ,2 ,1 ,1 ), +NAND_ECCREQ (4 ,512 ), +SPINAND_INFO_OP_VARIANTS (&read_cache_variants, + &write_cache_variants, + &update_cache_variants), +SPINAND_HAS_QE_BIT , + SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, NULL)), };static int macronix_spinand_detect (struct spinand_device *spinand)
Signature · 1 line
2.14.1
Miquel Raynal
maintainerPATCH v3 19/21 mtd: uclass: add probe function
In reply to Miquel RaynalThe user might want to trigger the probe of any MTD device, export these functions so they can be called from a command source file.
--- drivers/mtd/mtd-uclass.c | 9 +++++++++ include/linux/mtd/mtd.h | 3 +++ 2 files changed, 12 insertions(+)
drivers/mtd/mtd-uclass.c +9 -0
@@ -5,6 +5,7 @@#include <common.h> #include <dm.h> +#include <dm/device-internal.h> #include <errno.h> #include <mtd.h>
@@ -13,6 +14,14 @@* The uclass private is pointed to mtd_info. */ +int mtd_probe (struct udevice *dev) +{ +if (device_active (dev)) +return 0 ; + +return device_probe (dev); +} +UCLASS_DRIVER (mtd) = { .id =UCLASS_MTD , .name ="mtd" ,
include/linux/mtd/mtd.h +3 -0
@@ -537,5 +537,8 @@ int mtd_arg_off_size(int argc, char *const argv[], int *idx, loff_t *off,void mtd_get_len_incl_bad (struct mtd_info *mtd,uint64_t offset,const uint64_t length,uint64_t *len_incl_bad,int *truncated); + +int mtd_probe (struct udevice *dev); +#endif #endif /* __MTD_MTD_H__ */
Signature · 1 line
2.14.1
Miquel Raynal
maintainerPATCH v3 20/21 cmd: mtd: add 'mtd' command
In reply to Miquel RaynalThere should not be a 'nand' command, a 'sf' command and certainly not another 'spi-nand'. Write a 'mtd' command instead to manage all MTD devices at once. This should be the preferred way to access any MTD device.
--- cmd/Kconfig | 5 + cmd/Makefile | 1 + cmd/mtd.c | 334 +++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/mtd/Makefile | 2 +- 4 files changed, 341 insertions(+), 1 deletion(-) create mode 100644 cmd/mtd.c
cmd/Kconfig +5 -0
@@ -848,6 +848,11 @@ config CMD_MMC_SWRITE Enable support for the "mmc swrite" command to write Android sparse images to eMMC. +config CMD_MTD + bool "mtd" + help + MTD commands support. + config CMD_NAND bool "nand" default y if NAND_SUNXI
cmd/Makefile +1 -0
@@ -90,6 +90,7 @@ obj-$(CONFIG_CMD_MISC) += misc.o obj-$(CONFIG_CMD_MMC) += mmc.o obj-$(CONFIG_CMD_MMC_SPI) += mmc_spi.o obj-$(CONFIG_MP) += mp.o +obj-$(CONFIG_CMD_MTD) += mtd.o obj-$(CONFIG_CMD_MTDPARTS) += mtdparts.o obj-$(CONFIG_CMD_NAND) += nand.o obj-$(CONFIG_CMD_NET) += net.o
cmd/mtd.c new file +334 -0
334 lines not on this page · raw message
drivers/mtd/Makefile +1 -1
@@ -3,7 +3,7 @@ # (C) Copyright 2000-2007 # Wolfgang Denk, DENX Software Engineering, wd at denx.de. -ifneq (,$(findstring y,$(CONFIG_MTD_DEVICE)$(CONFIG_CMD_NAND)$(CONFIG_CMD_ONENAND)$(CONFIG_CMD_SF))) +ifneq (,$(findstring y,$(CONFIG_MTD_DEVICE)$(CONFIG_CMD_NAND)$(CONFIG_CMD_ONENAND)$(CONFIG_CMD_SF)$(CONFIG_CMD_MTD))) obj-y += mtdcore.o mtd_uboot.o endif obj-$(CONFIG_MTD) += mtd-uclass.o
Signature · 1 line
2.14.1
Miquel Raynal
maintainerPATCH v3 21/21 dt-bindings: Add bindings for SPI NAND devices
In reply to Miquel RaynalFrom: Boris Brezillon <[email protected]>
Add bindings for SPI NAND chips.
--- doc/device-tree-bindings/mtd/spi-nand.txt | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 doc/device-tree-bindings/mtd/spi-nand.txt
doc/device-tree-bindings/mtd/spi-nand.txt new file +5 -0
@@ -0,0 +1,5 @@ +SPI NAND flash + +Required properties: +- compatible: should be "spi-nand" +- reg: should encode the chip-select line used to access the NAND chip
Signature · 1 line
2.14.1
Miquel Raynal
maintainerv3 cover SPI-NAND support
In reply to Miquel RaynalHi Miquel,
Miquel Raynal <[email protected]> wrote on Thu, 12 Jul 2018 15:24:45 +0200:
Quoted 23 lines
During the last months, Boris Brezillon shared his work to support serial flashes within Linux. First, he delivered (and merged) a new layer called spi-mem. He also initiated in Linux MTD subsystem the move of all 'raw' NAND related code to a raw/ subdirectory, adding at the same time a NAND core that would be shared with all NAND devices. Then, he contributed a generic SPI-NAND driver, making use of this NAND core, as well as some vendor code to drive a few chips.
On top of this work, I added an 'mtd' U-Boot command to handle all sort of MTD devices. This should become the default command instead of having one per flash flavor ('sf', 'nand', 'spi-nand' ?).
The series has been tested on an Ocelot board PCB123 (VSC7514), featuring a Macronix SPI NAND chip.
TL;DR: the series contains:
- A few patches from Linux to resynchronize some areas of the MTD layer.
- Various fixes and re-organization of the MTD subsystem.
- The introduction of the SPI-mem interface.
- The addition of the generic SPI-NAND driver (and its bindings).
- Several SPI NAND chip drivers (Macronix, Micron, Winbond).
- A new 'mtd' command.
Quoted 6 lines
Any comments on the code, the organization and the respect of U-Boot driver model will be welcome.
Thanks,
Miquèl
Since this version, I tried to use UBI on top of this work and it failed because of the following:
- mtdpart driver was not actually compiled because a Kconfig symbol was missing
- mtdpart.c could not compile anyway because of an error when backporting the patch from Linux (did not see it because of the above mistake).
- SPI-NAND devices were not supported in mtdparts.
- The mtd command did not create MTD devices for each desired partition.
This is now fixed/done in the next version that I am about to send.
One can try it with:
Quoted 3 lines
setenv mtdparts mtdparts=spi-nand0:1m(foo),-(bar)
setenv mtdids spi-nand0=spi-nand0
ubi part bar
Thanks,
Miquèl