diff options
-rw-r--r-- | .mailmap | 7 | ||||
-rw-r--r-- | Documentation/arm/Samsung-S3C24XX/S3C2412.txt | 2 | ||||
-rw-r--r-- | Documentation/driver-api/mtdnand.rst | 8 | ||||
-rw-r--r-- | Documentation/gpio/drivers-on-gpio.txt | 4 | ||||
-rw-r--r-- | MAINTAINERS | 32 | ||||
-rw-r--r-- | arch/cris/arch-v32/drivers/mach-a3/nandflash.c | 2 | ||||
-rw-r--r-- | arch/cris/arch-v32/drivers/mach-fs/nandflash.c | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/Kconfig | 569 | ||||
-rw-r--r-- | drivers/mtd/nand/Makefile | 70 | ||||
-rw-r--r-- | drivers/mtd/nand/bbt.c | 130 | ||||
-rw-r--r-- | drivers/mtd/nand/core.c | 244 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/Kconfig | 569 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/Makefile | 67 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/ams-delta.c (renamed from drivers/mtd/nand/ams-delta.c) | 9 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/atmel/Makefile (renamed from drivers/mtd/nand/atmel/Makefile) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/atmel/nand-controller.c (renamed from drivers/mtd/nand/atmel/nand-controller.c) | 4 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/atmel/pmecc.c (renamed from drivers/mtd/nand/atmel/pmecc.c) | 4 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/atmel/pmecc.h (renamed from drivers/mtd/nand/atmel/pmecc.h) | 4 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/au1550nd.c (renamed from drivers/mtd/nand/au1550nd.c) | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/bcm47xxnflash/Makefile (renamed from drivers/mtd/nand/bcm47xxnflash/Makefile) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/bcm47xxnflash/bcm47xxnflash.h (renamed from drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/bcm47xxnflash/main.c (renamed from drivers/mtd/nand/bcm47xxnflash/main.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c (renamed from drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/bf5xx_nand.c (renamed from drivers/mtd/nand/bf5xx_nand.c) | 7 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/brcmnand/Makefile (renamed from drivers/mtd/nand/brcmnand/Makefile) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c (renamed from drivers/mtd/nand/brcmnand/bcm63138_nand.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/brcmnand/bcm6368_nand.c (renamed from drivers/mtd/nand/brcmnand/bcm6368_nand.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/brcmnand/brcmnand.c (renamed from drivers/mtd/nand/brcmnand/brcmnand.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/brcmnand/brcmnand.h (renamed from drivers/mtd/nand/brcmnand/brcmnand.h) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/brcmnand/brcmstb_nand.c (renamed from drivers/mtd/nand/brcmnand/brcmstb_nand.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/brcmnand/iproc_nand.c (renamed from drivers/mtd/nand/brcmnand/iproc_nand.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/cafe_nand.c (renamed from drivers/mtd/nand/cafe_nand.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/cmx270_nand.c (renamed from drivers/mtd/nand/cmx270_nand.c) | 4 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/cs553x_nand.c (renamed from drivers/mtd/nand/cs553x_nand.c) | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/davinci_nand.c (renamed from drivers/mtd/nand/davinci_nand.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/denali.c (renamed from drivers/mtd/nand/denali.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/denali.h (renamed from drivers/mtd/nand/denali.h) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/denali_dt.c (renamed from drivers/mtd/nand/denali_dt.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/denali_pci.c (renamed from drivers/mtd/nand/denali_pci.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/diskonchip.c (renamed from drivers/mtd/nand/diskonchip.c) | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/docg4.c (renamed from drivers/mtd/nand/docg4.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/fsl_elbc_nand.c (renamed from drivers/mtd/nand/fsl_elbc_nand.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/fsl_ifc_nand.c (renamed from drivers/mtd/nand/fsl_ifc_nand.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/fsl_upm.c (renamed from drivers/mtd/nand/fsl_upm.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/fsmc_nand.c (renamed from drivers/mtd/nand/fsmc_nand.c) | 252 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/gpio.c (renamed from drivers/mtd/nand/gpio.c) | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/gpmi-nand/Makefile (renamed from drivers/mtd/nand/gpmi-nand/Makefile) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/gpmi-nand/bch-regs.h (renamed from drivers/mtd/nand/gpmi-nand/bch-regs.h) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c (renamed from drivers/mtd/nand/gpmi-nand/gpmi-lib.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c (renamed from drivers/mtd/nand/gpmi-nand/gpmi-nand.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h (renamed from drivers/mtd/nand/gpmi-nand/gpmi-nand.h) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/gpmi-nand/gpmi-regs.h (renamed from drivers/mtd/nand/gpmi-nand/gpmi-regs.h) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/hisi504_nand.c (renamed from drivers/mtd/nand/hisi504_nand.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/jz4740_nand.c (renamed from drivers/mtd/nand/jz4740_nand.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/jz4780_bch.c (renamed from drivers/mtd/nand/jz4780_bch.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/jz4780_bch.h (renamed from drivers/mtd/nand/jz4780_bch.h) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/jz4780_nand.c (renamed from drivers/mtd/nand/jz4780_nand.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/lpc32xx_mlc.c (renamed from drivers/mtd/nand/lpc32xx_mlc.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/lpc32xx_slc.c (renamed from drivers/mtd/nand/lpc32xx_slc.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/marvell_nand.c (renamed from drivers/mtd/nand/marvell_nand.c) | 39 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/mpc5121_nfc.c (renamed from drivers/mtd/nand/mpc5121_nfc.c) | 5 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/mtk_ecc.c (renamed from drivers/mtd/nand/mtk_ecc.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/mtk_ecc.h (renamed from drivers/mtd/nand/mtk_ecc.h) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/mtk_nand.c (renamed from drivers/mtd/nand/mtk_nand.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/mxc_nand.c (renamed from drivers/mtd/nand/mxc_nand.c) | 509 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/nand_amd.c (renamed from drivers/mtd/nand/nand_amd.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/nand_base.c (renamed from drivers/mtd/nand/nand_base.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/nand_bbt.c (renamed from drivers/mtd/nand/nand_bbt.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/nand_bch.c (renamed from drivers/mtd/nand/nand_bch.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/nand_ecc.c (renamed from drivers/mtd/nand/nand_ecc.c) | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/nand_hynix.c (renamed from drivers/mtd/nand/nand_hynix.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/nand_ids.c (renamed from drivers/mtd/nand/nand_ids.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/nand_macronix.c (renamed from drivers/mtd/nand/nand_macronix.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/nand_micron.c (renamed from drivers/mtd/nand/nand_micron.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/nand_samsung.c (renamed from drivers/mtd/nand/nand_samsung.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/nand_timings.c (renamed from drivers/mtd/nand/nand_timings.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/nand_toshiba.c (renamed from drivers/mtd/nand/nand_toshiba.c) | 26 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/nandsim.c (renamed from drivers/mtd/nand/nandsim.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/ndfc.c (renamed from drivers/mtd/nand/ndfc.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/nuc900_nand.c (renamed from drivers/mtd/nand/nuc900_nand.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/omap2.c (renamed from drivers/mtd/nand/omap2.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/omap_elm.c (renamed from drivers/mtd/nand/omap_elm.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/orion_nand.c (renamed from drivers/mtd/nand/orion_nand.c) | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/oxnas_nand.c (renamed from drivers/mtd/nand/oxnas_nand.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/pasemi_nand.c (renamed from drivers/mtd/nand/pasemi_nand.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/plat_nand.c (renamed from drivers/mtd/nand/plat_nand.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/qcom_nandc.c (renamed from drivers/mtd/nand/qcom_nandc.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/r852.c (renamed from drivers/mtd/nand/r852.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/r852.h (renamed from drivers/mtd/nand/r852.h) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/s3c2410.c (renamed from drivers/mtd/nand/s3c2410.c) | 3 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/sh_flctl.c (renamed from drivers/mtd/nand/sh_flctl.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/sharpsl.c (renamed from drivers/mtd/nand/sharpsl.c) | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/sm_common.c (renamed from drivers/mtd/nand/sm_common.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/sm_common.h (renamed from drivers/mtd/nand/sm_common.h) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/socrates_nand.c (renamed from drivers/mtd/nand/socrates_nand.c) | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/sunxi_nand.c (renamed from drivers/mtd/nand/sunxi_nand.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/tango_nand.c (renamed from drivers/mtd/nand/tango_nand.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/tmio_nand.c (renamed from drivers/mtd/nand/tmio_nand.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/txx9ndfmc.c (renamed from drivers/mtd/nand/txx9ndfmc.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/vf610_nfc.c (renamed from drivers/mtd/nand/vf610_nfc.c) | 44 | ||||
-rw-r--r-- | drivers/mtd/nand/raw/xway_nand.c (renamed from drivers/mtd/nand/xway_nand.c) | 0 | ||||
-rw-r--r-- | drivers/mtd/sm_ftl.c | 2 | ||||
-rw-r--r-- | include/linux/mtd/bbm.h | 2 | ||||
-rw-r--r-- | include/linux/mtd/nand.h | 731 | ||||
-rw-r--r-- | include/linux/mtd/nand_ecc.h | 2 | ||||
-rw-r--r-- | include/linux/mtd/ndfc.h | 2 |
106 files changed, 2318 insertions, 1053 deletions
@@ -33,9 +33,9 @@ Axel Lin <[email protected]> Ben Gardner <[email protected]> Ben M Cahill <[email protected]> Björn Steinbrink <[email protected]> -Boris Brezillon <[email protected]> -Boris Brezillon <[email protected]> <[email protected]> -Boris Brezillon <[email protected]> <[email protected]> +Boris Brezillon <[email protected]> <[email protected]> +Boris Brezillon <[email protected]> <[email protected]> +Boris Brezillon <[email protected]> <[email protected]> Brian Avery <[email protected]> Brian King <[email protected]> Christoph Hellwig <[email protected]> @@ -126,6 +126,7 @@ Mayuresh Janorkar <[email protected]> Michael Buesch <[email protected]> Michel Dänzer <[email protected]> Miodrag Dinic <[email protected]> <[email protected]> +Miquel Raynal <[email protected]> <[email protected]> Mitesh shah <[email protected]> Mohit Kumar <[email protected]> <[email protected]> Morten Welinder <[email protected]> diff --git a/Documentation/arm/Samsung-S3C24XX/S3C2412.txt b/Documentation/arm/Samsung-S3C24XX/S3C2412.txt index f057876b920b..dc1fd362d3c1 100644 --- a/Documentation/arm/Samsung-S3C24XX/S3C2412.txt +++ b/Documentation/arm/Samsung-S3C24XX/S3C2412.txt @@ -46,7 +46,7 @@ NAND ---- The NAND hardware is similar to the S3C2440, and is supported by the - s3c2410 driver in the drivers/mtd/nand directory. + s3c2410 driver in the drivers/mtd/nand/raw directory. USB Host diff --git a/Documentation/driver-api/mtdnand.rst b/Documentation/driver-api/mtdnand.rst index 2a5191b6d445..dcd63599f700 100644 --- a/Documentation/driver-api/mtdnand.rst +++ b/Documentation/driver-api/mtdnand.rst @@ -967,10 +967,10 @@ API functions which are exported. Each function has a short description which is marked with an [XXX] identifier. See the chapter "Documentation hints" for an explanation. -.. kernel-doc:: drivers/mtd/nand/nand_base.c +.. kernel-doc:: drivers/mtd/nand/raw/nand_base.c :export: -.. kernel-doc:: drivers/mtd/nand/nand_ecc.c +.. kernel-doc:: drivers/mtd/nand/raw/nand_ecc.c :export: Internal Functions Provided @@ -982,10 +982,10 @@ marked with an [XXX] identifier. See the chapter "Documentation hints" for an explanation. The functions marked with [DEFAULT] might be relevant for a board driver developer. -.. kernel-doc:: drivers/mtd/nand/nand_base.c +.. kernel-doc:: drivers/mtd/nand/raw/nand_base.c :internal: -.. kernel-doc:: drivers/mtd/nand/nand_bbt.c +.. kernel-doc:: drivers/mtd/nand/raw/nand_bbt.c :internal: Credits diff --git a/Documentation/gpio/drivers-on-gpio.txt b/Documentation/gpio/drivers-on-gpio.txt index a2ccbab12eb7..a3e612f55bc7 100644 --- a/Documentation/gpio/drivers-on-gpio.txt +++ b/Documentation/gpio/drivers-on-gpio.txt @@ -74,8 +74,8 @@ hardware descriptions such as device tree or ACPI: it from 1-to-0-to-1. If that hardware does not receive its "ping" periodically, it will reset the system. -- gpio-nand: drivers/mtd/nand/gpio.c is used to connect a NAND flash chip to - a set of simple GPIO lines: RDY, NCE, ALE, CLE, NWP. It interacts with the +- gpio-nand: drivers/mtd/nand/raw/gpio.c is used to connect a NAND flash chip + to a set of simple GPIO lines: RDY, NCE, ALE, CLE, NWP. It interacts with the NAND flash MTD subsystem and provides chip access and partition parsing like any other NAND driving hardware. diff --git a/MAINTAINERS b/MAINTAINERS index 0b32e3c2f511..d5ebb8a1a7c2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1232,7 +1232,7 @@ F: arch/arm/boot/dts/aspeed-* F: drivers/*/*aspeed* ARM/ATMEL AT91 Clock Support -M: Boris Brezillon <[email protected]> +M: Boris Brezillon <[email protected]> S: Maintained F: drivers/clk/at91 @@ -1710,7 +1710,7 @@ F: drivers/input/keyboard/w90p910_keypad.c F: drivers/input/touchscreen/w90p910_ts.c F: drivers/watchdog/nuc900_wdt.c F: drivers/net/ethernet/nuvoton/w90p910_ether.c -F: drivers/mtd/nand/nuc900_nand.c +F: drivers/mtd/nand/raw/nuc900_nand.c F: drivers/rtc/rtc-nuc900.c F: drivers/spi/spi-nuc900.c F: drivers/usb/host/ehci-w90x900.c @@ -3014,7 +3014,7 @@ M: Kamal Dasu <[email protected]> S: Maintained -F: drivers/mtd/nand/brcmnand/ +F: drivers/mtd/nand/raw/brcmnand/ BROADCOM STB DPFE DRIVER M: Markus Mayer <[email protected]> @@ -4116,7 +4116,7 @@ DENALI NAND DRIVER M: Masahiro Yamada <[email protected]> S: Supported -F: drivers/mtd/nand/denali* +F: drivers/mtd/nand/raw/denali* DESIGNWARE USB2 DRD IP DRIVER M: John Youn <[email protected]> @@ -4644,7 +4644,7 @@ F: Documentation/gpu/meson.rst T: git git://anongit.freedesktop.org/drm/drm-misc DRM DRIVERS FOR ATMEL HLCDC -M: Boris Brezillon <[email protected]> +M: Boris Brezillon <[email protected]> S: Supported F: drivers/gpu/drm/atmel-hlcdc/ @@ -5646,7 +5646,7 @@ FREESCALE GPMI NAND DRIVER M: Han Xu <[email protected]> S: Maintained -F: drivers/mtd/nand/gpmi-nand/* +F: drivers/mtd/nand/raw/gpmi-nand/* FREESCALE I2C CPM DRIVER M: Jochen Friedrich <[email protected]> @@ -6955,7 +6955,7 @@ INGENIC JZ4780 NAND DRIVER M: Harvey Hunt <[email protected]> S: Maintained -F: drivers/mtd/nand/jz4780_* +F: drivers/mtd/nand/raw/jz4780_* INOTIFY M: Jan Kara <[email protected]> @@ -8412,7 +8412,7 @@ F: include/uapi/drm/armada_drm.h F: Documentation/devicetree/bindings/display/armada/ MARVELL CRYPTO DRIVER -M: Boris Brezillon <[email protected]> +M: Boris Brezillon <[email protected]> M: Arnaud Ebalard <[email protected]> F: drivers/crypto/marvell/ S: Maintained @@ -8471,10 +8471,10 @@ S: Odd Fixes F: drivers/net/wireless/marvell/mwl8k.c MARVELL NAND CONTROLLER DRIVER -M: Miquel Raynal <[email protected]> +M: Miquel Raynal <[email protected]> S: Maintained -F: drivers/mtd/nand/marvell_nand.c +F: drivers/mtd/nand/raw/marvell_nand.c F: Documentation/devicetree/bindings/mtd/marvell-nand.txt MARVELL SOC MMC/SD/SDIO CONTROLLER DRIVER @@ -9034,7 +9034,7 @@ F: mm/ MEMORY TECHNOLOGY DEVICES (MTD) M: David Woodhouse <[email protected]> M: Brian Norris <[email protected]> -M: Boris Brezillon <[email protected]> +M: Boris Brezillon <[email protected]> M: Marek Vasut <[email protected]> M: Richard Weinberger <[email protected]> M: Cyrille Pitchen <[email protected]> @@ -9136,7 +9136,7 @@ M: Wenyou Yang <[email protected]> M: Josh Wu <[email protected]> S: Supported -F: drivers/mtd/nand/atmel/* +F: drivers/mtd/nand/raw/atmel/* F: Documentation/devicetree/bindings/mtd/atmel-nand.txt MICROCHIP KSZ SERIES ETHERNET SWITCH DRIVER @@ -9452,7 +9452,7 @@ S: Supported F: drivers/net/ethernet/myricom/myri10ge/ NAND FLASH SUBSYSTEM -M: Boris Brezillon <[email protected]> +M: Boris Brezillon <[email protected]> R: Richard Weinberger <[email protected]> W: http://www.linux-mtd.infradead.org/ @@ -11809,8 +11809,8 @@ F: drivers/memstick/host/r592.* RICOH SMARTMEDIA/XD DRIVER M: Maxim Levitsky <[email protected]> S: Maintained -F: drivers/mtd/nand/r852.c -F: drivers/mtd/nand/r852.h +F: drivers/mtd/nand/raw/r852.c +F: drivers/mtd/nand/raw/r852.h RISC-V ARCHITECTURE M: Palmer Dabbelt <[email protected]> @@ -14629,7 +14629,7 @@ VF610 NAND DRIVER M: Stefan Agner <[email protected]> S: Supported -F: drivers/mtd/nand/vf610_nfc.c +F: drivers/mtd/nand/raw/vf610_nfc.c VFAT/FAT/MSDOS FILESYSTEM M: OGAWA Hirofumi <[email protected]> diff --git a/arch/cris/arch-v32/drivers/mach-a3/nandflash.c b/arch/cris/arch-v32/drivers/mach-a3/nandflash.c index 925a98eb6d68..7ec29d2d3661 100644 --- a/arch/cris/arch-v32/drivers/mach-a3/nandflash.c +++ b/arch/cris/arch-v32/drivers/mach-a3/nandflash.c @@ -3,7 +3,7 @@ * * Copyright (c) 2007 * - * Derived from drivers/mtd/nand/spia.c + * Derived from drivers/mtd/nand/spia.c (removed in v3.8) * Copyright (C) 2000 Steven J. Hill ([email protected]) * * This program is free software; you can redistribute it and/or modify diff --git a/arch/cris/arch-v32/drivers/mach-fs/nandflash.c b/arch/cris/arch-v32/drivers/mach-fs/nandflash.c index 53b56a429dde..7ce72906039a 100644 --- a/arch/cris/arch-v32/drivers/mach-fs/nandflash.c +++ b/arch/cris/arch-v32/drivers/mach-fs/nandflash.c @@ -3,7 +3,7 @@ * * Copyright (c) 2004 * - * Derived from drivers/mtd/nand/spia.c + * Derived from drivers/mtd/nand/spia.c (removed in v3.8) * Copyright (C) 2000 Steven J. Hill ([email protected]) * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 2c6ecb7ae753..1c1a1f487e20 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig @@ -1,569 +1,4 @@ -config MTD_NAND_ECC +config MTD_NAND_CORE tristate -config MTD_NAND_ECC_SMC - bool "NAND ECC Smart Media byte order" - depends on MTD_NAND_ECC - default n - help - Software ECC according to the Smart Media Specification. - The original Linux implementation had byte 0 and 1 swapped. - - -menuconfig MTD_NAND - tristate "NAND Device Support" - depends on MTD - select MTD_NAND_ECC - help - This enables support for accessing all type of NAND flash - devices. For further information see - <http://www.linux-mtd.infradead.org/doc/nand.html>. - -if MTD_NAND - -config MTD_NAND_BCH - tristate - select BCH - depends on MTD_NAND_ECC_BCH - default MTD_NAND - -config MTD_NAND_ECC_BCH - bool "Support software BCH ECC" - default n - help - This enables support for software BCH error correction. Binary BCH - codes are more powerful and cpu intensive than traditional Hamming - ECC codes. They are used with NAND devices requiring more than 1 bit - of error correction. - -config MTD_SM_COMMON - tristate - default n - -config MTD_NAND_DENALI - tristate - -config MTD_NAND_DENALI_PCI - tristate "Support Denali NAND controller on Intel Moorestown" - select MTD_NAND_DENALI - depends on HAS_DMA && PCI - help - Enable the driver for NAND flash on Intel Moorestown, using the - Denali NAND controller core. - -config MTD_NAND_DENALI_DT - tristate "Support Denali NAND controller as a DT device" - select MTD_NAND_DENALI - depends on HAS_DMA && HAVE_CLK && OF - help - Enable the driver for NAND flash on platforms using a Denali NAND - controller as a DT device. - -config MTD_NAND_GPIO - tristate "GPIO assisted NAND Flash driver" - depends on GPIOLIB || COMPILE_TEST - depends on HAS_IOMEM - help - This enables a NAND flash driver where control signals are - connected to GPIO pins, and commands and data are communicated - via a memory mapped interface. - -config MTD_NAND_AMS_DELTA - tristate "NAND Flash device on Amstrad E3" - depends on MACH_AMS_DELTA - default y - help - Support for NAND flash on Amstrad E3 (Delta). - -config MTD_NAND_OMAP2 - tristate "NAND Flash device on OMAP2, OMAP3, OMAP4 and Keystone" - depends on (ARCH_OMAP2PLUS || ARCH_KEYSTONE) - help - Support for NAND flash on Texas Instruments OMAP2, OMAP3, OMAP4 - and Keystone platforms. - -config MTD_NAND_OMAP_BCH - depends on MTD_NAND_OMAP2 - bool "Support hardware based BCH error correction" - default n - select BCH - help - This config enables the ELM hardware engine, which can be used to - locate and correct errors when using BCH ECC scheme. This offloads - the cpu from doing ECC error searching and correction. However some - legacy OMAP families like OMAP2xxx, OMAP3xxx do not have ELM engine - so this is optional for them. - -config MTD_NAND_OMAP_BCH_BUILD - def_tristate MTD_NAND_OMAP2 && MTD_NAND_OMAP_BCH - -config MTD_NAND_RICOH - tristate "Ricoh xD card reader" - default n - depends on PCI - select MTD_SM_COMMON - help - Enable support for Ricoh R5C852 xD card reader - You also need to enable ether - NAND SSFDC (SmartMedia) read only translation layer' or new - expermental, readwrite - 'SmartMedia/xD new translation layer' - -config MTD_NAND_AU1550 - tristate "Au1550/1200 NAND support" - depends on MIPS_ALCHEMY - help - This enables the driver for the NAND flash controller on the - AMD/Alchemy 1550 SOC. - -config MTD_NAND_BF5XX - tristate "Blackfin on-chip NAND Flash Controller driver" - depends on BF54x || BF52x - help - This enables the Blackfin on-chip NAND flash controller - - No board specific support is done by this driver, each board - must advertise a platform_device for the driver to attach. - - This driver can also be built as a module. If so, the module - will be called bf5xx-nand. - -config MTD_NAND_BF5XX_HWECC - bool "BF5XX NAND Hardware ECC" - default y - depends on MTD_NAND_BF5XX - help - Enable the use of the BF5XX's internal ECC generator when - using NAND. - -config MTD_NAND_BF5XX_BOOTROM_ECC - bool "Use Blackfin BootROM ECC Layout" - default n - depends on MTD_NAND_BF5XX_HWECC - help - If you wish to modify NAND pages and allow the Blackfin on-chip - BootROM to boot from them, say Y here. This is only necessary - if you are booting U-Boot out of NAND and you wish to update - U-Boot from Linux' userspace. Otherwise, you should say N here. - - If unsure, say N. - -config MTD_NAND_S3C2410 - tristate "NAND Flash support for Samsung S3C SoCs" - depends on ARCH_S3C24XX || ARCH_S3C64XX - help - This enables the NAND flash controller on the S3C24xx and S3C64xx - SoCs - - No board specific support is done by this driver, each board - must advertise a platform_device for the driver to attach. - -config MTD_NAND_S3C2410_DEBUG - bool "Samsung S3C NAND driver debug" - depends on MTD_NAND_S3C2410 - help - Enable debugging of the S3C NAND driver - -config MTD_NAND_NDFC - tristate "NDFC NanD Flash Controller" - depends on 4xx - select MTD_NAND_ECC_SMC - help - NDFC Nand Flash Controllers are integrated in IBM/AMCC's 4xx SoCs - -config MTD_NAND_S3C2410_CLKSTOP - bool "Samsung S3C NAND IDLE clock stop" - depends on MTD_NAND_S3C2410 - default n - help - Stop the clock to the NAND controller when there is no chip - selected to save power. This will mean there is a small delay - when the is NAND chip selected or released, but will save - approximately 5mA of power when there is nothing happening. - -config MTD_NAND_TANGO - tristate "NAND Flash support for Tango chips" - depends on ARCH_TANGO || COMPILE_TEST - depends on HAS_DMA - help - Enables the NAND Flash controller on Tango chips. - -config MTD_NAND_DISKONCHIP - tristate "DiskOnChip 2000, Millennium and Millennium Plus (NAND reimplementation)" - depends on HAS_IOMEM - select REED_SOLOMON - select REED_SOLOMON_DEC16 - help - This is a reimplementation of M-Systems DiskOnChip 2000, - Millennium and Millennium Plus as a standard NAND device driver, - as opposed to the earlier self-contained MTD device drivers. - This should enable, among other things, proper JFFS2 operation on - these devices. - -config MTD_NAND_DISKONCHIP_PROBE_ADVANCED - bool "Advanced detection options for DiskOnChip" - depends on MTD_NAND_DISKONCHIP - help - This option allows you to specify nonstandard address at which to - probe for a DiskOnChip, or to change the detection options. You - are unlikely to need any of this unless you are using LinuxBIOS. - Say 'N'. - -config MTD_NAND_DISKONCHIP_PROBE_ADDRESS - hex "Physical address of DiskOnChip" if MTD_NAND_DISKONCHIP_PROBE_ADVANCED - depends on MTD_NAND_DISKONCHIP - default "0" - ---help--- - By default, the probe for DiskOnChip devices will look for a - DiskOnChip at every multiple of 0x2000 between 0xC8000 and 0xEE000. - This option allows you to specify a single address at which to probe - for the device, which is useful if you have other devices in that - range which get upset when they are probed. - - (Note that on PowerPC, the normal probe will only check at - 0xE4000000.) - - Normally, you should leave this set to zero, to allow the probe at - the normal addresses. - -config MTD_NAND_DISKONCHIP_PROBE_HIGH - bool "Probe high addresses" - depends on MTD_NAND_DISKONCHIP_PROBE_ADVANCED - help - By default, the probe for DiskOnChip devices will look for a - DiskOnChip at every multiple of 0x2000 between 0xC8000 and 0xEE000. - This option changes to make it probe between 0xFFFC8000 and - 0xFFFEE000. Unless you are using LinuxBIOS, this is unlikely to be - useful to you. Say 'N'. - -config MTD_NAND_DISKONCHIP_BBTWRITE - bool "Allow BBT writes on DiskOnChip Millennium and 2000TSOP" - depends on MTD_NAND_DISKONCHIP - help - On DiskOnChip devices shipped with the INFTL filesystem (Millennium - and 2000 TSOP/Alon), Linux reserves some space at the end of the - device for the Bad Block Table (BBT). If you have existing INFTL - data on your device (created by non-Linux tools such as M-Systems' - DOS drivers), your data might overlap the area Linux wants to use for - the BBT. If this is a concern for you, leave this option disabled and - Linux will not write BBT data into this area. - The downside of leaving this option disabled is that if bad blocks - are detected by Linux, they will not be recorded in the BBT, which - could cause future problems. - Once you enable this option, new filesystems (INFTL or others, created - in Linux or other operating systems) will not use the reserved area. - The only reason not to enable this option is to prevent damage to - preexisting filesystems. - Even if you leave this disabled, you can enable BBT writes at module - load time (assuming you build diskonchip as a module) with the module - parameter "inftl_bbt_write=1". - -config MTD_NAND_DOCG4 - tristate "Support for DiskOnChip G4" - depends on HAS_IOMEM - select BCH - select BITREVERSE - help - Support for diskonchip G4 nand flash, found in various smartphones and - PDAs, among them the Palm Treo680, HTC Prophet and Wizard, Toshiba - Portege G900, Asus P526, and O2 XDA Zinc. - - With this driver you will be able to use UBI and create a ubifs on the - device, so you may wish to consider enabling UBI and UBIFS as well. - - These devices ship with the Mys/Sandisk SAFTL formatting, for which - there is currently no mtd parser, so you may want to use command line - partitioning to segregate write-protected blocks. On the Treo680, the - first five erase blocks (256KiB each) are write-protected, followed - by the block containing the saftl partition table. This is probably - typical. - -config MTD_NAND_SHARPSL - tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)" - depends on ARCH_PXA - -config MTD_NAND_CAFE - tristate "NAND support for OLPC CAFÉ chip" - depends on PCI - select REED_SOLOMON - select REED_SOLOMON_DEC16 - help - Use NAND flash attached to the CAFÉ chip designed for the OLPC - laptop. - -config MTD_NAND_CS553X - tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)" - depends on X86_32 - depends on !UML && HAS_IOMEM - help - The CS553x companion chips for the AMD Geode processor - include NAND flash controllers with built-in hardware ECC - capabilities; enabling this option will allow you to use - these. The driver will check the MSRs to verify that the - controller is enabled for NAND, and currently requires that - the controller be in MMIO mode. - - If you say "m", the module will be called cs553x_nand. - -config MTD_NAND_ATMEL - tristate "Support for NAND Flash / SmartMedia on AT91" - depends on ARCH_AT91 - select MFD_ATMEL_SMC - help - Enables support for NAND Flash / Smart Media Card interface - on Atmel AT91 processors. - -config MTD_NAND_MARVELL - tristate "NAND controller support on Marvell boards" - depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU || \ - COMPILE_TEST - depends on HAS_IOMEM - help - This enables the NAND flash controller driver for Marvell boards, - including: - - PXA3xx processors (NFCv1) - - 32-bit Armada platforms (XP, 37x, 38x, 39x) (NFCv2) - - 64-bit Aramda platforms (7k, 8k) (NFCv2) - -config MTD_NAND_SLC_LPC32XX - tristate "NXP LPC32xx SLC Controller" - depends on ARCH_LPC32XX - help - Enables support for NXP's LPC32XX SLC (i.e. for Single Level Cell - chips) NAND controller. This is the default for the PHYTEC 3250 - reference board which contains a NAND256R3A2CZA6 chip. - - Please check the actual NAND chip connected and its support - by the SLC NAND controller. - -config MTD_NAND_MLC_LPC32XX - tristate "NXP LPC32xx MLC Controller" - depends on ARCH_LPC32XX - help - Uses the LPC32XX MLC (i.e. for Multi Level Cell chips) NAND - controller. This is the default for the WORK92105 controller - board. - - Please check the actual NAND chip connected and its support - by the MLC NAND controller. - -config MTD_NAND_CM_X270 - tristate "Support for NAND Flash on CM-X270 modules" - depends on MACH_ARMCORE - -config MTD_NAND_PASEMI - tristate "NAND support for PA Semi PWRficient" - depends on PPC_PASEMI - help - Enables support for NAND Flash interface on PA Semi PWRficient - based boards - -config MTD_NAND_TMIO - tristate "NAND Flash device on Toshiba Mobile IO Controller" - depends on MFD_TMIO - help - Support for NAND flash connected to a Toshiba Mobile IO - Controller in some PDAs, including the Sharp SL6000x. - -config MTD_NAND_NANDSIM - tristate "Support for NAND Flash Simulator" - help - The simulator may simulate various NAND flash chips for the - MTD nand layer. - -config MTD_NAND_GPMI_NAND - tristate "GPMI NAND Flash Controller driver" - depends on MTD_NAND && MXS_DMA - help - Enables NAND Flash support for IMX23, IMX28 or IMX6. - The GPMI controller is very powerful, with the help of BCH - module, it can do the hardware ECC. The GPMI supports several - NAND flashs at the same time. - -config MTD_NAND_BRCMNAND - tristate "Broadcom STB NAND controller" - depends on ARM || ARM64 || MIPS - help - Enables the Broadcom NAND controller driver. The controller was - originally designed for Set-Top Box but is used on various BCM7xxx, - BCM3xxx, BCM63xxx, iProc/Cygnus and more. - -config MTD_NAND_BCM47XXNFLASH - tristate "Support for NAND flash on BCM4706 BCMA bus" - depends on BCMA_NFLASH - help - BCMA bus can have various flash memories attached, they are - registered by bcma as platform devices. This enables driver for - NAND flash memories. For now only BCM4706 is supported. - -config MTD_NAND_PLATFORM - tristate "Support for generic platform NAND driver" - depends on HAS_IOMEM - help - This implements a generic NAND driver for on-SOC platform - devices. You will need to provide platform-specific functions - via platform_data. - -config MTD_NAND_ORION - tristate "NAND Flash support for Marvell Orion SoC" - depends on PLAT_ORION - help - This enables the NAND flash controller on Orion machines. - - No board specific support is done by this driver, each board - must advertise a platform_device for the driver to attach. - -config MTD_NAND_OXNAS - tristate "NAND Flash support for Oxford Semiconductor SoC" - depends on ARCH_OXNAS || COMPILE_TEST - depends on HAS_IOMEM - help - This enables the NAND flash controller on Oxford Semiconductor SoCs. - -config MTD_NAND_FSL_ELBC - tristate "NAND support for Freescale eLBC controllers" - depends on FSL_SOC - select FSL_LBC - help - Various Freescale chips, including the 8313, include a NAND Flash - Controller Module with built-in hardware ECC capabilities. - Enabling this option will enable you to use this to control - external NAND devices. - -config MTD_NAND_FSL_IFC - tristate "NAND support for Freescale IFC controller" - depends on FSL_SOC || ARCH_LAYERSCAPE || SOC_LS1021A - select FSL_IFC - select MEMORY - help - Various Freescale chips e.g P1010, include a NAND Flash machine - with built-in hardware ECC capabilities. - Enabling this option will enable you to use this to control - external NAND devices. - -config MTD_NAND_FSL_UPM - tristate "Support for NAND on Freescale UPM" - depends on PPC_83xx || PPC_85xx - select FSL_LBC - help - Enables support for NAND Flash chips wired onto Freescale PowerPC - processor localbus with User-Programmable Machine support. - -config MTD_NAND_MPC5121_NFC - tristate "MPC5121 built-in NAND Flash Controller support" - depends on PPC_MPC512x - help - This enables the driver for the NAND flash controller on the - MPC5121 SoC. - -config MTD_NAND_VF610_NFC - tristate "Support for Freescale NFC for VF610/MPC5125" - depends on (SOC_VF610 || COMPILE_TEST) - depends on HAS_IOMEM - help - Enables support for NAND Flash Controller on some Freescale - processors like the VF610, MPC5125, MCF54418 or Kinetis K70. - The driver supports a maximum 2k page size. With 2k pages and - 64 bytes or more of OOB, hardware ECC with up to 32-bit error - correction is supported. Hardware ECC is only enabled through - device tree. - -config MTD_NAND_MXC - tristate "MXC NAND support" - depends on ARCH_MXC - help - This enables the driver for the NAND flash controller on the - MXC processors. - -config MTD_NAND_SH_FLCTL - tristate "Support for NAND on Renesas SuperH FLCTL" - depends on SUPERH || COMPILE_TEST - depends on HAS_IOMEM - depends on HAS_DMA - help - Several Renesas SuperH CPU has FLCTL. This option enables support - for NAND Flash using FLCTL. - -config MTD_NAND_DAVINCI - tristate "Support NAND on DaVinci/Keystone SoC" - depends on ARCH_DAVINCI || (ARCH_KEYSTONE && TI_AEMIF) - help - Enable the driver for NAND flash chips on Texas Instruments - DaVinci/Keystone processors. - -config MTD_NAND_TXX9NDFMC - tristate "NAND Flash support for TXx9 SoC" - depends on SOC_TX4938 || SOC_TX4939 - help - This enables the NAND flash controller on the TXx9 SoCs. - -config MTD_NAND_SOCRATES - tristate "Support for NAND on Socrates board" - depends on SOCRATES - help - Enables support for NAND Flash chips wired onto Socrates board. - -config MTD_NAND_NUC900 - tristate "Support for NAND on Nuvoton NUC9xx/w90p910 evaluation boards." - depends on ARCH_W90X900 - help - This enables the driver for the NAND Flash on evaluation board based - on w90p910 / NUC9xx. - -config MTD_NAND_JZ4740 - tristate "Support for JZ4740 SoC NAND controller" - depends on MACH_JZ4740 - help - Enables support for NAND Flash on JZ4740 SoC based boards. - -config MTD_NAND_JZ4780 - tristate "Support for NAND on JZ4780 SoC" - depends on MACH_JZ4780 && JZ4780_NEMC - help - Enables support for NAND Flash connected to the NEMC on JZ4780 SoC - based boards, using the BCH controller for hardware error correction. - -config MTD_NAND_FSMC - tristate "Support for NAND on ST Micros FSMC" - depends on OF - depends on PLAT_SPEAR || ARCH_NOMADIK || ARCH_U8500 || MACH_U300 - help - Enables support for NAND Flash chips on the ST Microelectronics - Flexible Static Memory Controller (FSMC) - -config MTD_NAND_XWAY - bool "Support for NAND on Lantiq XWAY SoC" - depends on LANTIQ && SOC_TYPE_XWAY - help - Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached - to the External Bus Unit (EBU). - -config MTD_NAND_SUNXI - tristate "Support for NAND on Allwinner SoCs" - depends on ARCH_SUNXI - help - Enables support for NAND Flash chips on Allwinner SoCs. - -config MTD_NAND_HISI504 - tristate "Support for NAND controller on Hisilicon SoC Hip04" - depends on ARCH_HISI || COMPILE_TEST - depends on HAS_DMA - help - Enables support for NAND controller on Hisilicon SoC Hip04. - -config MTD_NAND_QCOM - tristate "Support for NAND on QCOM SoCs" - depends on ARCH_QCOM - help - Enables support for NAND flash chips on SoCs containing the EBI2 NAND - controller. This controller is found on IPQ806x SoC. - -config MTD_NAND_MTK - tristate "Support for NAND controller on MTK SoCs" - depends on ARCH_MEDIATEK || COMPILE_TEST - depends on HAS_DMA - help - Enables support for NAND controller on MTK SoCs. - This controller is found on mt27xx, mt81xx, mt65xx SoCs. - -endif # MTD_NAND +source "drivers/mtd/nand/raw/Kconfig" diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index c882d5ef192a..a72d3cb0f325 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -1,70 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 -# -# linux/drivers/nand/Makefile -# -obj-$(CONFIG_MTD_NAND) += nand.o -obj-$(CONFIG_MTD_NAND_ECC) += nand_ecc.o -obj-$(CONFIG_MTD_NAND_BCH) += nand_bch.o -obj-$(CONFIG_MTD_SM_COMMON) += sm_common.o +nandcore-objs := core.o bbt.o +obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o -obj-$(CONFIG_MTD_NAND_CAFE) += cafe_nand.o -obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o -obj-$(CONFIG_MTD_NAND_DENALI) += denali.o -obj-$(CONFIG_MTD_NAND_DENALI_PCI) += denali_pci.o -obj-$(CONFIG_MTD_NAND_DENALI_DT) += denali_dt.o -obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o -obj-$(CONFIG_MTD_NAND_BF5XX) += bf5xx_nand.o -obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o -obj-$(CONFIG_MTD_NAND_TANGO) += tango_nand.o -obj-$(CONFIG_MTD_NAND_DAVINCI) += davinci_nand.o -obj-$(CONFIG_MTD_NAND_DISKONCHIP) += diskonchip.o -obj-$(CONFIG_MTD_NAND_DOCG4) += docg4.o -obj-$(CONFIG_MTD_NAND_FSMC) += fsmc_nand.o -obj-$(CONFIG_MTD_NAND_SHARPSL) += sharpsl.o -obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o -obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o -obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o -obj-$(CONFIG_MTD_NAND_ATMEL) += atmel/ -obj-$(CONFIG_MTD_NAND_GPIO) += gpio.o -omap2_nand-objs := omap2.o -obj-$(CONFIG_MTD_NAND_OMAP2) += omap2_nand.o -obj-$(CONFIG_MTD_NAND_OMAP_BCH_BUILD) += omap_elm.o -obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o -obj-$(CONFIG_MTD_NAND_MARVELL) += marvell_nand.o -obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o -obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o -obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o -obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o -obj-$(CONFIG_MTD_NAND_OXNAS) += oxnas_nand.o -obj-$(CONFIG_MTD_NAND_FSL_ELBC) += fsl_elbc_nand.o -obj-$(CONFIG_MTD_NAND_FSL_IFC) += fsl_ifc_nand.o -obj-$(CONFIG_MTD_NAND_FSL_UPM) += fsl_upm.o -obj-$(CONFIG_MTD_NAND_SLC_LPC32XX) += lpc32xx_slc.o -obj-$(CONFIG_MTD_NAND_MLC_LPC32XX) += lpc32xx_mlc.o -obj-$(CONFIG_MTD_NAND_SH_FLCTL) += sh_flctl.o -obj-$(CONFIG_MTD_NAND_MXC) += mxc_nand.o -obj-$(CONFIG_MTD_NAND_SOCRATES) += socrates_nand.o -obj-$(CONFIG_MTD_NAND_TXX9NDFMC) += txx9ndfmc.o -obj-$(CONFIG_MTD_NAND_NUC900) += nuc900_nand.o -obj-$(CONFIG_MTD_NAND_MPC5121_NFC) += mpc5121_nfc.o -obj-$(CONFIG_MTD_NAND_VF610_NFC) += vf610_nfc.o -obj-$(CONFIG_MTD_NAND_RICOH) += r852.o -obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o -obj-$(CONFIG_MTD_NAND_JZ4780) += jz4780_nand.o jz4780_bch.o -obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/ -obj-$(CONFIG_MTD_NAND_XWAY) += xway_nand.o -obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash/ -obj-$(CONFIG_MTD_NAND_SUNXI) += sunxi_nand.o -obj-$(CONFIG_MTD_NAND_HISI504) += hisi504_nand.o -obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand/ -obj-$(CONFIG_MTD_NAND_QCOM) += qcom_nandc.o -obj-$(CONFIG_MTD_NAND_MTK) += mtk_ecc.o mtk_nand.o - -nand-objs := nand_base.o nand_bbt.o nand_timings.o nand_ids.o -nand-objs += nand_amd.o -nand-objs += nand_hynix.o -nand-objs += nand_macronix.o -nand-objs += nand_micron.o -nand-objs += nand_samsung.o -nand-objs += nand_toshiba.o +obj-y += raw/ diff --git a/drivers/mtd/nand/bbt.c b/drivers/mtd/nand/bbt.c new file mode 100644 index 000000000000..56cde38b92c0 --- /dev/null +++ b/drivers/mtd/nand/bbt.c @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2017 Free Electrons + * + * Authors: + * Boris Brezillon <[email protected]> + * Peter Pan <[email protected]> + */ + +#define pr_fmt(fmt) "nand-bbt: " fmt + +#include <linux/mtd/nand.h> +#include <linux/slab.h> + +/** + * nanddev_bbt_init() - Initialize the BBT (Bad Block Table) + * @nand: NAND device + * + * Initialize the in-memory BBT. + * + * Return: 0 in case of success, a negative error code otherwise. + */ +int nanddev_bbt_init(struct nand_device *nand) +{ + unsigned int bits_per_block = fls(NAND_BBT_BLOCK_NUM_STATUS); + unsigned int nblocks = nanddev_neraseblocks(nand); + unsigned int nwords = DIV_ROUND_UP(nblocks * bits_per_block, + BITS_PER_LONG); + + nand->bbt.cache = kzalloc(nwords, GFP_KERNEL); + if (!nand->bbt.cache) + return -ENOMEM; + + return 0; +} +EXPORT_SYMBOL_GPL(nanddev_bbt_init); + +/** + * nanddev_bbt_cleanup() - Cleanup the BBT (Bad Block Table) + * @nand: NAND device + * + * Undoes what has been done in nanddev_bbt_init() + */ +void nanddev_bbt_cleanup(struct nand_device *nand) +{ + kfree(nand->bbt.cache); +} +EXPORT_SYMBOL_GPL(nanddev_bbt_cleanup); + +/** + * nanddev_bbt_update() - Update a BBT + * @nand: nand device + * + * Update the BBT. Currently a NOP function since on-flash bbt is not yet + * supported. + * + * Return: 0 in case of success, a negative error code otherwise. + */ +int nanddev_bbt_update(struct nand_device *nand) +{ + return 0; +} +EXPORT_SYMBOL_GPL(nanddev_bbt_update); + +/** + * nanddev_bbt_get_block_status() - Return the status of an eraseblock + * @nand: nand device + * @entry: the BBT entry + * + * Return: a positive number nand_bbt_block_status status or -%ERANGE if @entry + * is bigger than the BBT size. + */ +int nanddev_bbt_get_block_status(const struct nand_device *nand, + unsigned int entry) +{ + unsigned int bits_per_block = fls(NAND_BBT_BLOCK_NUM_STATUS); + unsigned long *pos = nand->bbt.cache + + ((entry * bits_per_block) / BITS_PER_LONG); + unsigned int offs = (entry * bits_per_block) % BITS_PER_LONG; + unsigned long status; + + if (entry >= nanddev_neraseblocks(nand)) + return -ERANGE; + + status = pos[0] >> offs; + if (bits_per_block + offs > BITS_PER_LONG) + status |= pos[1] << (BITS_PER_LONG - offs); + + return status & GENMASK(bits_per_block - 1, 0); +} +EXPORT_SYMBOL_GPL(nanddev_bbt_get_block_status); + +/** + * nanddev_bbt_set_block_status() - Update the status of an eraseblock in the + * in-memory BBT + * @nand: nand device + * @entry: the BBT entry to update + * @status: the new status + * + * Update an entry of the in-memory BBT. If you want to push the updated BBT + * the NAND you should call nanddev_bbt_update(). + * + * Return: 0 in case of success or -%ERANGE if @entry is bigger than the BBT + * size. + */ +int nanddev_bbt_set_block_status(struct nand_device *nand, unsigned int entry, + enum nand_bbt_block_status status) +{ + unsigned int bits_per_block = fls(NAND_BBT_BLOCK_NUM_STATUS); + unsigned long *pos = nand->bbt.cache + + ((entry * bits_per_block) / BITS_PER_LONG); + unsigned int offs = (entry * bits_per_block) % BITS_PER_LONG; + unsigned long val = status & GENMASK(bits_per_block - 1, 0); + + if (entry >= nanddev_neraseblocks(nand)) + return -ERANGE; + + pos[0] &= ~GENMASK(offs + bits_per_block - 1, offs); + pos[0] |= val << offs; + + if (bits_per_block + offs > BITS_PER_LONG) { + unsigned int rbits = bits_per_block + offs - BITS_PER_LONG; + + pos[1] &= ~GENMASK(rbits - 1, 0); + pos[1] |= val >> rbits; + } + + return 0; +} +EXPORT_SYMBOL_GPL(nanddev_bbt_set_block_status); diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c new file mode 100644 index 000000000000..f237a688f8e9 --- /dev/null +++ b/drivers/mtd/nand/core.c @@ -0,0 +1,244 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2017 Free Electrons + * + * Authors: + * Boris Brezillon <[email protected]> + * Peter Pan <[email protected]> + */ + +#define pr_fmt(fmt) "nand: " fmt + +#include <linux/module.h> +#include <linux/mtd/nand.h> + +/** + * nanddev_isbad() - Check if a block is bad + * @nand: NAND device + * @pos: position pointing to the block we want to check + * + * Return: true if the block is bad, false otherwise. + */ +bool nanddev_isbad(struct nand_device *nand, const struct nand_pos *pos) +{ + if (nanddev_bbt_is_initialized(nand)) { + unsigned int entry; + int status; + + entry = nanddev_bbt_pos_to_entry(nand, pos); + status = nanddev_bbt_get_block_status(nand, entry); + /* Lazy block status retrieval */ + if (status == NAND_BBT_BLOCK_STATUS_UNKNOWN) { + if (nand->ops->isbad(nand, pos)) + status = NAND_BBT_BLOCK_FACTORY_BAD; + else + status = NAND_BBT_BLOCK_GOOD; + + nanddev_bbt_set_block_status(nand, entry, status); + } + + if (status == NAND_BBT_BLOCK_WORN || + status == NAND_BBT_BLOCK_FACTORY_BAD) + return true; + + return false; + } + + return nand->ops->isbad(nand, pos); +} +EXPORT_SYMBOL_GPL(nanddev_isbad); + +/** + * nanddev_markbad() - Mark a block as bad + * @nand: NAND device + * @block: block to mark bad + * + * Mark a block bad. This function is updating the BBT if available and + * calls the low-level markbad hook (nand->ops->markbad()). + * + * Return: 0 in case of success, a negative error code otherwise. + */ +int nanddev_markbad(struct nand_device *nand, const struct nand_pos *pos) +{ + struct mtd_info *mtd = nanddev_to_mtd(nand); + unsigned int entry; + int ret = 0; + + if (nanddev_isbad(nand, pos)) + return 0; + + ret = nand->ops->markbad(nand, pos); + if (ret) + pr_warn("failed to write BBM to block @%llx (err = %d)\n", + nanddev_pos_to_offs(nand, pos), ret); + + if (!nanddev_bbt_is_initialized(nand)) + goto out; + + entry = nanddev_bbt_pos_to_entry(nand, pos); + ret = nanddev_bbt_set_block_status(nand, entry, NAND_BBT_BLOCK_WORN); + if (ret) + goto out; + + ret = nanddev_bbt_update(nand); + +out: + if (!ret) + mtd->ecc_stats.badblocks++; + + return ret; +} +EXPORT_SYMBOL_GPL(nanddev_markbad); + +/** + * nanddev_isreserved() - Check whether an eraseblock is reserved or not + * @nand: NAND device + * @pos: NAND position to test + * + * Checks whether the eraseblock pointed by @pos is reserved or not. + * + * Return: true if the eraseblock is reserved, false otherwise. + */ +bool nanddev_isreserved(struct nand_device *nand, const struct nand_pos *pos) +{ + unsigned int entry; + int status; + + if (!nanddev_bbt_is_initialized(nand)) + return false; + + /* Return info from the table */ + entry = nanddev_bbt_pos_to_entry(nand, pos); + status = nanddev_bbt_get_block_status(nand, entry); + return status == NAND_BBT_BLOCK_RESERVED; +} +EXPORT_SYMBOL_GPL(nanddev_isreserved); + +/** + * nanddev_erase() - Erase a NAND portion + * @nand: NAND device + * @block: eraseblock to erase + * + * Erases @block if it's not bad. + * + * Return: 0 in case of success, a negative error code otherwise. + */ +int nanddev_erase(struct nand_device *nand, const struct nand_pos *pos) +{ + if (nanddev_isbad(nand, pos) || nanddev_isreserved(nand, pos)) { + pr_warn("attempt to erase a bad/reserved block @%llx\n", + nanddev_pos_to_offs(nand, pos)); + return -EIO; + } + + return nand->ops->erase(nand, pos); +} +EXPORT_SYMBOL_GPL(nanddev_erase); + +/** + * nanddev_mtd_erase() - Generic mtd->_erase() implementation for NAND devices + * @mtd: MTD device + * @einfo: erase request + * + * This is a simple mtd->_erase() implementation iterating over all blocks + * concerned by @einfo and calling nand->ops->erase() on each of them. + * + * Note that mtd->_erase should not be directly assigned to this helper, + * because there's no locking here. NAND specialized layers should instead + * implement there own wrapper around nanddev_mtd_erase() taking the + * appropriate lock before calling nanddev_mtd_erase(). + * + * Return: 0 in case of success, a negative error code otherwise. + */ +int nanddev_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo) +{ + struct nand_device *nand = mtd_to_nanddev(mtd); + struct nand_pos pos, last; + int ret; + + nanddev_offs_to_pos(nand, einfo->addr, &pos); + nanddev_offs_to_pos(nand, einfo->addr + einfo->len - 1, &last); + while (nanddev_pos_cmp(&pos, &last) <= 0) { + ret = nanddev_erase(nand, &pos); + if (ret) { + einfo->fail_addr = nanddev_pos_to_offs(nand, &pos); + einfo->state = MTD_ERASE_FAILED; + + return ret; + } + + nanddev_pos_next_eraseblock(nand, &pos); + } + + einfo->state = MTD_ERASE_DONE; + + return 0; +} +EXPORT_SYMBOL_GPL(nanddev_mtd_erase); + +/** + * nanddev_init() - Initialize a NAND device + * @nand: NAND device + * @memorg: NAND memory organization descriptor + * @ops: NAND device operations + * + * Initializes a NAND device object. Consistency checks are done on @memorg and + * @ops. Also takes care of initializing the BBT. + * + * Return: 0 in case of success, a negative error code otherwise. + */ +int nanddev_init(struct nand_device *nand, const struct nand_ops *ops, + struct module *owner) +{ + struct mtd_info *mtd = nanddev_to_mtd(nand); + struct nand_memory_organization *memorg = nanddev_get_memorg(nand); + + if (!nand || !ops) + return -EINVAL; + + if (!ops->erase || !ops->markbad || !ops->isbad) + return -EINVAL; + + if (!memorg->bits_per_cell || !memorg->pagesize || + !memorg->pages_per_eraseblock || !memorg->eraseblocks_per_lun || + !memorg->planes_per_lun || !memorg->luns_per_target || + !memorg->ntargets) + return -EINVAL; + + nand->rowconv.eraseblock_addr_shift = + fls(memorg->pages_per_eraseblock - 1); + nand->rowconv.lun_addr_shift = fls(memorg->eraseblocks_per_lun - 1) + + nand->rowconv.eraseblock_addr_shift; + + nand->ops = ops; + + mtd->type = memorg->bits_per_cell == 1 ? + MTD_NANDFLASH : MTD_MLCNANDFLASH; + mtd->flags = MTD_CAP_NANDFLASH; + mtd->erasesize = memorg->pagesize * memorg->pages_per_eraseblock; + mtd->writesize = memorg->pagesize; + mtd->writebufsize = memorg->pagesize; + mtd->oobsize = memorg->oobsize; + mtd->size = nanddev_size(nand); + mtd->owner = owner; + + return nanddev_bbt_init(nand); +} +EXPORT_SYMBOL_GPL(nanddev_init); + +/** + * nanddev_cleanup() - Release resources allocated in nanddev_init() + * @nand: NAND device + * + * Basically undoes what has been done in nanddev_init(). + */ +void nanddev_cleanup(struct nand_device *nand) +{ + if (nanddev_bbt_is_initialized(nand)) + nanddev_bbt_cleanup(nand); +} +EXPORT_SYMBOL_GPL(nanddev_cleanup); + +MODULE_DESCRIPTION("Generic NAND framework"); +MODULE_AUTHOR("Boris Brezillon <[email protected]>"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig new file mode 100644 index 000000000000..2c6ecb7ae753 --- /dev/null +++ b/drivers/mtd/nand/raw/Kconfig @@ -0,0 +1,569 @@ +config MTD_NAND_ECC + tristate + +config MTD_NAND_ECC_SMC + bool "NAND ECC Smart Media byte order" + depends on MTD_NAND_ECC + default n + help + Software ECC according to the Smart Media Specification. + The original Linux implementation had byte 0 and 1 swapped. + + +menuconfig MTD_NAND + tristate "NAND Device Support" + depends on MTD + select MTD_NAND_ECC + help + This enables support for accessing all type of NAND flash + devices. For further information see + <http://www.linux-mtd.infradead.org/doc/nand.html>. + +if MTD_NAND + +config MTD_NAND_BCH + tristate + select BCH + depends on MTD_NAND_ECC_BCH + default MTD_NAND + +config MTD_NAND_ECC_BCH + bool "Support software BCH ECC" + default n + help + This enables support for software BCH error correction. Binary BCH + codes are more powerful and cpu intensive than traditional Hamming + ECC codes. They are used with NAND devices requiring more than 1 bit + of error correction. + +config MTD_SM_COMMON + tristate + default n + +config MTD_NAND_DENALI + tristate + +config MTD_NAND_DENALI_PCI + tristate "Support Denali NAND controller on Intel Moorestown" + select MTD_NAND_DENALI + depends on HAS_DMA && PCI + help + Enable the driver for NAND flash on Intel Moorestown, using the + Denali NAND controller core. + +config MTD_NAND_DENALI_DT + tristate "Support Denali NAND controller as a DT device" + select MTD_NAND_DENALI + depends on HAS_DMA && HAVE_CLK && OF + help + Enable the driver for NAND flash on platforms using a Denali NAND + controller as a DT device. + +config MTD_NAND_GPIO + tristate "GPIO assisted NAND Flash driver" + depends on GPIOLIB || COMPILE_TEST + depends on HAS_IOMEM + help + This enables a NAND flash driver where control signals are + connected to GPIO pins, and commands and data are communicated + via a memory mapped interface. + +config MTD_NAND_AMS_DELTA + tristate "NAND Flash device on Amstrad E3" + depends on MACH_AMS_DELTA + default y + help + Support for NAND flash on Amstrad E3 (Delta). + +config MTD_NAND_OMAP2 + tristate "NAND Flash device on OMAP2, OMAP3, OMAP4 and Keystone" + depends on (ARCH_OMAP2PLUS || ARCH_KEYSTONE) + help + Support for NAND flash on Texas Instruments OMAP2, OMAP3, OMAP4 + and Keystone platforms. + +config MTD_NAND_OMAP_BCH + depends on MTD_NAND_OMAP2 + bool "Support hardware based BCH error correction" + default n + select BCH + help + This config enables the ELM hardware engine, which can be used to + locate and correct errors when using BCH ECC scheme. This offloads + the cpu from doing ECC error searching and correction. However some + legacy OMAP families like OMAP2xxx, OMAP3xxx do not have ELM engine + so this is optional for them. + +config MTD_NAND_OMAP_BCH_BUILD + def_tristate MTD_NAND_OMAP2 && MTD_NAND_OMAP_BCH + +config MTD_NAND_RICOH + tristate "Ricoh xD card reader" + default n + depends on PCI + select MTD_SM_COMMON + help + Enable support for Ricoh R5C852 xD card reader + You also need to enable ether + NAND SSFDC (SmartMedia) read only translation layer' or new + expermental, readwrite + 'SmartMedia/xD new translation layer' + +config MTD_NAND_AU1550 + tristate "Au1550/1200 NAND support" + depends on MIPS_ALCHEMY + help + This enables the driver for the NAND flash controller on the + AMD/Alchemy 1550 SOC. + +config MTD_NAND_BF5XX + tristate "Blackfin on-chip NAND Flash Controller driver" + depends on BF54x || BF52x + help + This enables the Blackfin on-chip NAND flash controller + + No board specific support is done by this driver, each board + must advertise a platform_device for the driver to attach. + + This driver can also be built as a module. If so, the module + will be called bf5xx-nand. + +config MTD_NAND_BF5XX_HWECC + bool "BF5XX NAND Hardware ECC" + default y + depends on MTD_NAND_BF5XX + help + Enable the use of the BF5XX's internal ECC generator when + using NAND. + +config MTD_NAND_BF5XX_BOOTROM_ECC + bool "Use Blackfin BootROM ECC Layout" + default n + depends on MTD_NAND_BF5XX_HWECC + help + If you wish to modify NAND pages and allow the Blackfin on-chip + BootROM to boot from them, say Y here. This is only necessary + if you are booting U-Boot out of NAND and you wish to update + U-Boot from Linux' userspace. Otherwise, you should say N here. + + If unsure, say N. + +config MTD_NAND_S3C2410 + tristate "NAND Flash support for Samsung S3C SoCs" + depends on ARCH_S3C24XX || ARCH_S3C64XX + help + This enables the NAND flash controller on the S3C24xx and S3C64xx + SoCs + + No board specific support is done by this driver, each board + must advertise a platform_device for the driver to attach. + +config MTD_NAND_S3C2410_DEBUG + bool "Samsung S3C NAND driver debug" + depends on MTD_NAND_S3C2410 + help + Enable debugging of the S3C NAND driver + +config MTD_NAND_NDFC + tristate "NDFC NanD Flash Controller" + depends on 4xx + select MTD_NAND_ECC_SMC + help + NDFC Nand Flash Controllers are integrated in IBM/AMCC's 4xx SoCs + +config MTD_NAND_S3C2410_CLKSTOP + bool "Samsung S3C NAND IDLE clock stop" + depends on MTD_NAND_S3C2410 + default n + help + Stop the clock to the NAND controller when there is no chip + selected to save power. This will mean there is a small delay + when the is NAND chip selected or released, but will save + approximately 5mA of power when there is nothing happening. + +config MTD_NAND_TANGO + tristate "NAND Flash support for Tango chips" + depends on ARCH_TANGO || COMPILE_TEST + depends on HAS_DMA + help + Enables the NAND Flash controller on Tango chips. + +config MTD_NAND_DISKONCHIP + tristate "DiskOnChip 2000, Millennium and Millennium Plus (NAND reimplementation)" + depends on HAS_IOMEM + select REED_SOLOMON + select REED_SOLOMON_DEC16 + help + This is a reimplementation of M-Systems DiskOnChip 2000, + Millennium and Millennium Plus as a standard NAND device driver, + as opposed to the earlier self-contained MTD device drivers. + This should enable, among other things, proper JFFS2 operation on + these devices. + +config MTD_NAND_DISKONCHIP_PROBE_ADVANCED + bool "Advanced detection options for DiskOnChip" + depends on MTD_NAND_DISKONCHIP + help + This option allows you to specify nonstandard address at which to + probe for a DiskOnChip, or to change the detection options. You + are unlikely to need any of this unless you are using LinuxBIOS. + Say 'N'. + +config MTD_NAND_DISKONCHIP_PROBE_ADDRESS + hex "Physical address of DiskOnChip" if MTD_NAND_DISKONCHIP_PROBE_ADVANCED + depends on MTD_NAND_DISKONCHIP + default "0" + ---help--- + By default, the probe for DiskOnChip devices will look for a + DiskOnChip at every multiple of 0x2000 between 0xC8000 and 0xEE000. + This option allows you to specify a single address at which to probe + for the device, which is useful if you have other devices in that + range which get upset when they are probed. + + (Note that on PowerPC, the normal probe will only check at + 0xE4000000.) + + Normally, you should leave this set to zero, to allow the probe at + the normal addresses. + +config MTD_NAND_DISKONCHIP_PROBE_HIGH + bool "Probe high addresses" + depends on MTD_NAND_DISKONCHIP_PROBE_ADVANCED + help + By default, the probe for DiskOnChip devices will look for a + DiskOnChip at every multiple of 0x2000 between 0xC8000 and 0xEE000. + This option changes to make it probe between 0xFFFC8000 and + 0xFFFEE000. Unless you are using LinuxBIOS, this is unlikely to be + useful to you. Say 'N'. + +config MTD_NAND_DISKONCHIP_BBTWRITE + bool "Allow BBT writes on DiskOnChip Millennium and 2000TSOP" + depends on MTD_NAND_DISKONCHIP + help + On DiskOnChip devices shipped with the INFTL filesystem (Millennium + and 2000 TSOP/Alon), Linux reserves some space at the end of the + device for the Bad Block Table (BBT). If you have existing INFTL + data on your device (created by non-Linux tools such as M-Systems' + DOS drivers), your data might overlap the area Linux wants to use for + the BBT. If this is a concern for you, leave this option disabled and + Linux will not write BBT data into this area. + The downside of leaving this option disabled is that if bad blocks + are detected by Linux, they will not be recorded in the BBT, which + could cause future problems. + Once you enable this option, new filesystems (INFTL or others, created + in Linux or other operating systems) will not use the reserved area. + The only reason not to enable this option is to prevent damage to + preexisting filesystems. + Even if you leave this disabled, you can enable BBT writes at module + load time (assuming you build diskonchip as a module) with the module + parameter "inftl_bbt_write=1". + +config MTD_NAND_DOCG4 + tristate "Support for DiskOnChip G4" + depends on HAS_IOMEM + select BCH + select BITREVERSE + help + Support for diskonchip G4 nand flash, found in various smartphones and + PDAs, among them the Palm Treo680, HTC Prophet and Wizard, Toshiba + Portege G900, Asus P526, and O2 XDA Zinc. + + With this driver you will be able to use UBI and create a ubifs on the + device, so you may wish to consider enabling UBI and UBIFS as well. + + These devices ship with the Mys/Sandisk SAFTL formatting, for which + there is currently no mtd parser, so you may want to use command line + partitioning to segregate write-protected blocks. On the Treo680, the + first five erase blocks (256KiB each) are write-protected, followed + by the block containing the saftl partition table. This is probably + typical. + +config MTD_NAND_SHARPSL + tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)" + depends on ARCH_PXA + +config MTD_NAND_CAFE + tristate "NAND support for OLPC CAFÉ chip" + depends on PCI + select REED_SOLOMON + select REED_SOLOMON_DEC16 + help + Use NAND flash attached to the CAFÉ chip designed for the OLPC + laptop. + +config MTD_NAND_CS553X + tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)" + depends on X86_32 + depends on !UML && HAS_IOMEM + help + The CS553x companion chips for the AMD Geode processor + include NAND flash controllers with built-in hardware ECC + capabilities; enabling this option will allow you to use + these. The driver will check the MSRs to verify that the + controller is enabled for NAND, and currently requires that + the controller be in MMIO mode. + + If you say "m", the module will be called cs553x_nand. + +config MTD_NAND_ATMEL + tristate "Support for NAND Flash / SmartMedia on AT91" + depends on ARCH_AT91 + select MFD_ATMEL_SMC + help + Enables support for NAND Flash / Smart Media Card interface + on Atmel AT91 processors. + +config MTD_NAND_MARVELL + tristate "NAND controller support on Marvell boards" + depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU || \ + COMPILE_TEST + depends on HAS_IOMEM + help + This enables the NAND flash controller driver for Marvell boards, + including: + - PXA3xx processors (NFCv1) + - 32-bit Armada platforms (XP, 37x, 38x, 39x) (NFCv2) + - 64-bit Aramda platforms (7k, 8k) (NFCv2) + +config MTD_NAND_SLC_LPC32XX + tristate "NXP LPC32xx SLC Controller" + depends on ARCH_LPC32XX + help + Enables support for NXP's LPC32XX SLC (i.e. for Single Level Cell + chips) NAND controller. This is the default for the PHYTEC 3250 + reference board which contains a NAND256R3A2CZA6 chip. + + Please check the actual NAND chip connected and its support + by the SLC NAND controller. + +config MTD_NAND_MLC_LPC32XX + tristate "NXP LPC32xx MLC Controller" + depends on ARCH_LPC32XX + help + Uses the LPC32XX MLC (i.e. for Multi Level Cell chips) NAND + controller. This is the default for the WORK92105 controller + board. + + Please check the actual NAND chip connected and its support + by the MLC NAND controller. + +config MTD_NAND_CM_X270 + tristate "Support for NAND Flash on CM-X270 modules" + depends on MACH_ARMCORE + +config MTD_NAND_PASEMI + tristate "NAND support for PA Semi PWRficient" + depends on PPC_PASEMI + help + Enables support for NAND Flash interface on PA Semi PWRficient + based boards + +config MTD_NAND_TMIO + tristate "NAND Flash device on Toshiba Mobile IO Controller" + depends on MFD_TMIO + help + Support for NAND flash connected to a Toshiba Mobile IO + Controller in some PDAs, including the Sharp SL6000x. + +config MTD_NAND_NANDSIM + tristate "Support for NAND Flash Simulator" + help + The simulator may simulate various NAND flash chips for the + MTD nand layer. + +config MTD_NAND_GPMI_NAND + tristate "GPMI NAND Flash Controller driver" + depends on MTD_NAND && MXS_DMA + help + Enables NAND Flash support for IMX23, IMX28 or IMX6. + The GPMI controller is very powerful, with the help of BCH + module, it can do the hardware ECC. The GPMI supports several + NAND flashs at the same time. + +config MTD_NAND_BRCMNAND + tristate "Broadcom STB NAND controller" + depends on ARM || ARM64 || MIPS + help + Enables the Broadcom NAND controller driver. The controller was + originally designed for Set-Top Box but is used on various BCM7xxx, + BCM3xxx, BCM63xxx, iProc/Cygnus and more. + +config MTD_NAND_BCM47XXNFLASH + tristate "Support for NAND flash on BCM4706 BCMA bus" + depends on BCMA_NFLASH + help + BCMA bus can have various flash memories attached, they are + registered by bcma as platform devices. This enables driver for + NAND flash memories. For now only BCM4706 is supported. + +config MTD_NAND_PLATFORM + tristate "Support for generic platform NAND driver" + depends on HAS_IOMEM + help + This implements a generic NAND driver for on-SOC platform + devices. You will need to provide platform-specific functions + via platform_data. + +config MTD_NAND_ORION + tristate "NAND Flash support for Marvell Orion SoC" + depends on PLAT_ORION + help + This enables the NAND flash controller on Orion machines. + + No board specific support is done by this driver, each board + must advertise a platform_device for the driver to attach. + +config MTD_NAND_OXNAS + tristate "NAND Flash support for Oxford Semiconductor SoC" + depends on ARCH_OXNAS || COMPILE_TEST + depends on HAS_IOMEM + help + This enables the NAND flash controller on Oxford Semiconductor SoCs. + +config MTD_NAND_FSL_ELBC + tristate "NAND support for Freescale eLBC controllers" + depends on FSL_SOC + select FSL_LBC + help + Various Freescale chips, including the 8313, include a NAND Flash + Controller Module with built-in hardware ECC capabilities. + Enabling this option will enable you to use this to control + external NAND devices. + +config MTD_NAND_FSL_IFC + tristate "NAND support for Freescale IFC controller" + depends on FSL_SOC || ARCH_LAYERSCAPE || SOC_LS1021A + select FSL_IFC + select MEMORY + help + Various Freescale chips e.g P1010, include a NAND Flash machine + with built-in hardware ECC capabilities. + Enabling this option will enable you to use this to control + external NAND devices. + +config MTD_NAND_FSL_UPM + tristate "Support for NAND on Freescale UPM" + depends on PPC_83xx || PPC_85xx + select FSL_LBC + help + Enables support for NAND Flash chips wired onto Freescale PowerPC + processor localbus with User-Programmable Machine support. + +config MTD_NAND_MPC5121_NFC + tristate "MPC5121 built-in NAND Flash Controller support" + depends on PPC_MPC512x + help + This enables the driver for the NAND flash controller on the + MPC5121 SoC. + +config MTD_NAND_VF610_NFC + tristate "Support for Freescale NFC for VF610/MPC5125" + depends on (SOC_VF610 || COMPILE_TEST) + depends on HAS_IOMEM + help + Enables support for NAND Flash Controller on some Freescale + processors like the VF610, MPC5125, MCF54418 or Kinetis K70. + The driver supports a maximum 2k page size. With 2k pages and + 64 bytes or more of OOB, hardware ECC with up to 32-bit error + correction is supported. Hardware ECC is only enabled through + device tree. + +config MTD_NAND_MXC + tristate "MXC NAND support" + depends on ARCH_MXC + help + This enables the driver for the NAND flash controller on the + MXC processors. + +config MTD_NAND_SH_FLCTL + tristate "Support for NAND on Renesas SuperH FLCTL" + depends on SUPERH || COMPILE_TEST + depends on HAS_IOMEM + depends on HAS_DMA + help + Several Renesas SuperH CPU has FLCTL. This option enables support + for NAND Flash using FLCTL. + +config MTD_NAND_DAVINCI + tristate "Support NAND on DaVinci/Keystone SoC" + depends on ARCH_DAVINCI || (ARCH_KEYSTONE && TI_AEMIF) + help + Enable the driver for NAND flash chips on Texas Instruments + DaVinci/Keystone processors. + +config MTD_NAND_TXX9NDFMC + tristate "NAND Flash support for TXx9 SoC" + depends on SOC_TX4938 || SOC_TX4939 + help + This enables the NAND flash controller on the TXx9 SoCs. + +config MTD_NAND_SOCRATES + tristate "Support for NAND on Socrates board" + depends on SOCRATES + help + Enables support for NAND Flash chips wired onto Socrates board. + +config MTD_NAND_NUC900 + tristate "Support for NAND on Nuvoton NUC9xx/w90p910 evaluation boards." + depends on ARCH_W90X900 + help + This enables the driver for the NAND Flash on evaluation board based + on w90p910 / NUC9xx. + +config MTD_NAND_JZ4740 + tristate "Support for JZ4740 SoC NAND controller" + depends on MACH_JZ4740 + help + Enables support for NAND Flash on JZ4740 SoC based boards. + +config MTD_NAND_JZ4780 + tristate "Support for NAND on JZ4780 SoC" + depends on MACH_JZ4780 && JZ4780_NEMC + help + Enables support for NAND Flash connected to the NEMC on JZ4780 SoC + based boards, using the BCH controller for hardware error correction. + +config MTD_NAND_FSMC + tristate "Support for NAND on ST Micros FSMC" + depends on OF + depends on PLAT_SPEAR || ARCH_NOMADIK || ARCH_U8500 || MACH_U300 + help + Enables support for NAND Flash chips on the ST Microelectronics + Flexible Static Memory Controller (FSMC) + +config MTD_NAND_XWAY + bool "Support for NAND on Lantiq XWAY SoC" + depends on LANTIQ && SOC_TYPE_XWAY + help + Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached + to the External Bus Unit (EBU). + +config MTD_NAND_SUNXI + tristate "Support for NAND on Allwinner SoCs" + depends on ARCH_SUNXI + help + Enables support for NAND Flash chips on Allwinner SoCs. + +config MTD_NAND_HISI504 + tristate "Support for NAND controller on Hisilicon SoC Hip04" + depends on ARCH_HISI || COMPILE_TEST + depends on HAS_DMA + help + Enables support for NAND controller on Hisilicon SoC Hip04. + +config MTD_NAND_QCOM + tristate "Support for NAND on QCOM SoCs" + depends on ARCH_QCOM + help + Enables support for NAND flash chips on SoCs containing the EBI2 NAND + controller. This controller is found on IPQ806x SoC. + +config MTD_NAND_MTK + tristate "Support for NAND controller on MTK SoCs" + depends on ARCH_MEDIATEK || COMPILE_TEST + depends on HAS_DMA + help + Enables support for NAND controller on MTK SoCs. + This controller is found on mt27xx, mt81xx, mt65xx SoCs. + +endif # MTD_NAND diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile new file mode 100644 index 000000000000..f16f59a197a3 --- /dev/null +++ b/drivers/mtd/nand/raw/Makefile @@ -0,0 +1,67 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_MTD_NAND) += nand.o +obj-$(CONFIG_MTD_NAND_ECC) += nand_ecc.o +obj-$(CONFIG_MTD_NAND_BCH) += nand_bch.o +obj-$(CONFIG_MTD_SM_COMMON) += sm_common.o + +obj-$(CONFIG_MTD_NAND_CAFE) += cafe_nand.o +obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o +obj-$(CONFIG_MTD_NAND_DENALI) += denali.o +obj-$(CONFIG_MTD_NAND_DENALI_PCI) += denali_pci.o +obj-$(CONFIG_MTD_NAND_DENALI_DT) += denali_dt.o +obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o +obj-$(CONFIG_MTD_NAND_BF5XX) += bf5xx_nand.o +obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o +obj-$(CONFIG_MTD_NAND_TANGO) += tango_nand.o +obj-$(CONFIG_MTD_NAND_DAVINCI) += davinci_nand.o +obj-$(CONFIG_MTD_NAND_DISKONCHIP) += diskonchip.o +obj-$(CONFIG_MTD_NAND_DOCG4) += docg4.o +obj-$(CONFIG_MTD_NAND_FSMC) += fsmc_nand.o +obj-$(CONFIG_MTD_NAND_SHARPSL) += sharpsl.o +obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o +obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o +obj-$(CONFIG_MTD_NAND_NDFC) += ndfc.o +obj-$(CONFIG_MTD_NAND_ATMEL) += atmel/ +obj-$(CONFIG_MTD_NAND_GPIO) += gpio.o +omap2_nand-objs := omap2.o +obj-$(CONFIG_MTD_NAND_OMAP2) += omap2_nand.o +obj-$(CONFIG_MTD_NAND_OMAP_BCH_BUILD) += omap_elm.o +obj-$(CONFIG_MTD_NAND_CM_X270) += cmx270_nand.o +obj-$(CONFIG_MTD_NAND_MARVELL) += marvell_nand.o +obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o +obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o +obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o +obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o +obj-$(CONFIG_MTD_NAND_OXNAS) += oxnas_nand.o +obj-$(CONFIG_MTD_NAND_FSL_ELBC) += fsl_elbc_nand.o +obj-$(CONFIG_MTD_NAND_FSL_IFC) += fsl_ifc_nand.o +obj-$(CONFIG_MTD_NAND_FSL_UPM) += fsl_upm.o +obj-$(CONFIG_MTD_NAND_SLC_LPC32XX) += lpc32xx_slc.o +obj-$(CONFIG_MTD_NAND_MLC_LPC32XX) += lpc32xx_mlc.o +obj-$(CONFIG_MTD_NAND_SH_FLCTL) += sh_flctl.o +obj-$(CONFIG_MTD_NAND_MXC) += mxc_nand.o +obj-$(CONFIG_MTD_NAND_SOCRATES) += socrates_nand.o +obj-$(CONFIG_MTD_NAND_TXX9NDFMC) += txx9ndfmc.o +obj-$(CONFIG_MTD_NAND_NUC900) += nuc900_nand.o +obj-$(CONFIG_MTD_NAND_MPC5121_NFC) += mpc5121_nfc.o +obj-$(CONFIG_MTD_NAND_VF610_NFC) += vf610_nfc.o +obj-$(CONFIG_MTD_NAND_RICOH) += r852.o +obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o +obj-$(CONFIG_MTD_NAND_JZ4780) += jz4780_nand.o jz4780_bch.o +obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/ +obj-$(CONFIG_MTD_NAND_XWAY) += xway_nand.o +obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash/ +obj-$(CONFIG_MTD_NAND_SUNXI) += sunxi_nand.o +obj-$(CONFIG_MTD_NAND_HISI504) += hisi504_nand.o +obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand/ +obj-$(CONFIG_MTD_NAND_QCOM) += qcom_nandc.o +obj-$(CONFIG_MTD_NAND_MTK) += mtk_ecc.o mtk_nand.o + +nand-objs := nand_base.o nand_bbt.o nand_timings.o nand_ids.o +nand-objs += nand_amd.o +nand-objs += nand_hynix.o +nand-objs += nand_macronix.o +nand-objs += nand_micron.o +nand-objs += nand_samsung.o +nand-objs += nand_toshiba.o diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/raw/ams-delta.c index d60ada45c549..35f80523e52e 100644 --- a/drivers/mtd/nand/ams-delta.c +++ b/drivers/mtd/nand/raw/ams-delta.c @@ -1,11 +1,12 @@ /* - * drivers/mtd/nand/ams-delta.c - * * Copyright (C) 2006 Jonathan McDowell <[email protected]> * - * Derived from drivers/mtd/toto.c + * Derived from drivers/mtd/nand/toto.c (removed in v2.6.28) + * Copyright (c) 2003 Texas Instruments + * Copyright (c) 2002 Thomas Gleixner <[email protected]> + * * Converted to platform driver by Janusz Krzysztofik <[email protected]> - * Partially stolen from drivers/mtd/nand/plat_nand.c + * Partially stolen from plat_nand.c * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as diff --git a/drivers/mtd/nand/atmel/Makefile b/drivers/mtd/nand/raw/atmel/Makefile index 288db4f38a8f..288db4f38a8f 100644 --- a/drivers/mtd/nand/atmel/Makefile +++ b/drivers/mtd/nand/raw/atmel/Makefile diff --git a/drivers/mtd/nand/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c index b2f00b398490..12f6753d47ae 100644 --- a/drivers/mtd/nand/atmel/nand-controller.c +++ b/drivers/mtd/nand/raw/atmel/nand-controller.c @@ -9,10 +9,10 @@ * * Copyright 2003 Rick Bronson * - * Derived from drivers/mtd/nand/autcpu12.c + * Derived from drivers/mtd/nand/autcpu12.c (removed in v3.8) * Copyright 2001 Thomas Gleixner ([email protected]) * - * Derived from drivers/mtd/spia.c + * Derived from drivers/mtd/spia.c (removed in v3.8) * Copyright 2000 Steven J. Hill ([email protected]) * * diff --git a/drivers/mtd/nand/atmel/pmecc.c b/drivers/mtd/nand/raw/atmel/pmecc.c index fcbe4fd6e684..9de29c9afb0c 100644 --- a/drivers/mtd/nand/atmel/pmecc.c +++ b/drivers/mtd/nand/raw/atmel/pmecc.c @@ -9,10 +9,10 @@ * * Copyright 2003 Rick Bronson * - * Derived from drivers/mtd/nand/autcpu12.c + * Derived from drivers/mtd/nand/autcpu12.c (removed in v3.8) * Copyright 2001 Thomas Gleixner ([email protected]) * - * Derived from drivers/mtd/spia.c + * Derived from drivers/mtd/spia.c (removed in v3.8) * Copyright 2000 Steven J. Hill ([email protected]) * * Add Hardware ECC support for AT91SAM9260 / AT91SAM9263 diff --git a/drivers/mtd/nand/atmel/pmecc.h b/drivers/mtd/nand/raw/atmel/pmecc.h index 817e0dd9fd15..808f1be0d6ad 100644 --- a/drivers/mtd/nand/atmel/pmecc.h +++ b/drivers/mtd/nand/raw/atmel/pmecc.h @@ -9,10 +9,10 @@ * * Copyright © 2003 Rick Bronson * - * Derived from drivers/mtd/nand/autcpu12.c + * Derived from drivers/mtd/nand/autcpu12.c (removed in v3.8) * Copyright © 2001 Thomas Gleixner ([email protected]) * - * Derived from drivers/mtd/spia.c + * Derived from drivers/mtd/spia.c (removed in v3.8) * Copyright © 2000 Steven J. Hill ([email protected]) * * diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/raw/au1550nd.c index 8ab827edf94e..df0ef1f1e2f5 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/raw/au1550nd.c @@ -1,6 +1,4 @@ /* - * drivers/mtd/nand/au1550nd.c - * * Copyright (C) 2004 Embedded Edge, LLC * * This program is free software; you can redistribute it and/or modify diff --git a/drivers/mtd/nand/bcm47xxnflash/Makefile b/drivers/mtd/nand/raw/bcm47xxnflash/Makefile index f05b119e134b..f05b119e134b 100644 --- a/drivers/mtd/nand/bcm47xxnflash/Makefile +++ b/drivers/mtd/nand/raw/bcm47xxnflash/Makefile diff --git a/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h b/drivers/mtd/nand/raw/bcm47xxnflash/bcm47xxnflash.h index 201b9baa52a0..201b9baa52a0 100644 --- a/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h +++ b/drivers/mtd/nand/raw/bcm47xxnflash/bcm47xxnflash.h diff --git a/drivers/mtd/nand/bcm47xxnflash/main.c b/drivers/mtd/nand/raw/bcm47xxnflash/main.c index fb31429b70a9..fb31429b70a9 100644 --- a/drivers/mtd/nand/bcm47xxnflash/main.c +++ b/drivers/mtd/nand/raw/bcm47xxnflash/main.c diff --git a/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c b/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c index 54bac5b73f0a..54bac5b73f0a 100644 --- a/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c +++ b/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/raw/bf5xx_nand.c index 87bbd177b3e5..9a1d8d104570 100644 --- a/drivers/mtd/nand/bf5xx_nand.c +++ b/drivers/mtd/nand/raw/bf5xx_nand.c @@ -1,15 +1,14 @@ -/* linux/drivers/mtd/nand/bf5xx_nand.c - * +/* * Copyright 2006-2008 Analog Devices Inc. * http://blackfin.uclinux.org/ * Bryan Wu <[email protected]> * * Blackfin BF5xx on-chip NAND flash controller driver * - * Derived from drivers/mtd/nand/s3c2410.c + * Derived from s3c2410.c * Copyright (c) 2007 Ben Dooks <[email protected]> * - * Derived from drivers/mtd/nand/cafe.c + * Derived from cafe.c * Copyright © 2006 Red Hat, Inc. * Copyright © 2006 David Woodhouse <[email protected]> * diff --git a/drivers/mtd/nand/brcmnand/Makefile b/drivers/mtd/nand/raw/brcmnand/Makefile index 195b845e48b8..195b845e48b8 100644 --- a/drivers/mtd/nand/brcmnand/Makefile +++ b/drivers/mtd/nand/raw/brcmnand/Makefile diff --git a/drivers/mtd/nand/brcmnand/bcm63138_nand.c b/drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c index 59444b3a697d..59444b3a697d 100644 --- a/drivers/mtd/nand/brcmnand/bcm63138_nand.c +++ b/drivers/mtd/nand/raw/brcmnand/bcm63138_nand.c diff --git a/drivers/mtd/nand/brcmnand/bcm6368_nand.c b/drivers/mtd/nand/raw/brcmnand/bcm6368_nand.c index 34c91b0e1e69..34c91b0e1e69 100644 --- a/drivers/mtd/nand/brcmnand/bcm6368_nand.c +++ b/drivers/mtd/nand/raw/brcmnand/bcm6368_nand.c diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c index c28fd2bc1a84..c28fd2bc1a84 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c diff --git a/drivers/mtd/nand/brcmnand/brcmnand.h b/drivers/mtd/nand/raw/brcmnand/brcmnand.h index 5c44cd4aba87..5c44cd4aba87 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.h +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.h diff --git a/drivers/mtd/nand/brcmnand/brcmstb_nand.c b/drivers/mtd/nand/raw/brcmnand/brcmstb_nand.c index 5c271077ac87..5c271077ac87 100644 --- a/drivers/mtd/nand/brcmnand/brcmstb_nand.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmstb_nand.c diff --git a/drivers/mtd/nand/brcmnand/iproc_nand.c b/drivers/mtd/nand/raw/brcmnand/iproc_nand.c index 4c6ae113664d..4c6ae113664d 100644 --- a/drivers/mtd/nand/brcmnand/iproc_nand.c +++ b/drivers/mtd/nand/raw/brcmnand/iproc_nand.c diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/raw/cafe_nand.c index 567ff972d5fc..567ff972d5fc 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/raw/cafe_nand.c diff --git a/drivers/mtd/nand/cmx270_nand.c b/drivers/mtd/nand/raw/cmx270_nand.c index b01c9804590e..02d6751e9efe 100644 --- a/drivers/mtd/nand/cmx270_nand.c +++ b/drivers/mtd/nand/raw/cmx270_nand.c @@ -1,10 +1,8 @@ /* - * linux/drivers/mtd/nand/cmx270-nand.c - * * Copyright (C) 2006 Compulab, Ltd. * Mike Rapoport <[email protected]> * - * Derived from drivers/mtd/nand/h1910.c + * Derived from drivers/mtd/nand/h1910.c (removed in v3.10) * Copyright (C) 2002 Marius Gröger ([email protected]) * Copyright (c) 2001 Thomas Gleixner ([email protected]) * diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/raw/cs553x_nand.c index d48877540f14..be1f28fc7363 100644 --- a/drivers/mtd/nand/cs553x_nand.c +++ b/drivers/mtd/nand/raw/cs553x_nand.c @@ -1,6 +1,4 @@ /* - * drivers/mtd/nand/cs553x_nand.c - * * (C) 2005, 2006 Red Hat Inc. * * Author: David Woodhouse <[email protected]> diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/raw/davinci_nand.c index ccc8c43abcff..ccc8c43abcff 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/raw/davinci_nand.c diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/raw/denali.c index 313c7f50621b..313c7f50621b 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/raw/denali.c diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/raw/denali.h index 9ad33d237378..9ad33d237378 100644 --- a/drivers/mtd/nand/denali.h +++ b/drivers/mtd/nand/raw/denali.h diff --git a/drivers/mtd/nand/denali_dt.c b/drivers/mtd/nand/raw/denali_dt.c index cfd33e6ca77f..cfd33e6ca77f 100644 --- a/drivers/mtd/nand/denali_dt.c +++ b/drivers/mtd/nand/raw/denali_dt.c diff --git a/drivers/mtd/nand/denali_pci.c b/drivers/mtd/nand/raw/denali_pci.c index 49cb3e1f8bd0..49cb3e1f8bd0 100644 --- a/drivers/mtd/nand/denali_pci.c +++ b/drivers/mtd/nand/raw/denali_pci.c diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/raw/diskonchip.c index 6bc93ea66f50..1af77f798fe5 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/raw/diskonchip.c @@ -1,6 +1,4 @@ /* - * drivers/mtd/nand/diskonchip.c - * * (C) 2003 Red Hat, Inc. * (C) 2004 Dan Brown <[email protected]> * (C) 2004 Kalev Lember <[email protected]> diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/raw/docg4.c index 72f1327c4430..72f1327c4430 100644 --- a/drivers/mtd/nand/docg4.c +++ b/drivers/mtd/nand/raw/docg4.c diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/raw/fsl_elbc_nand.c index 8b6dcd739ecb..8b6dcd739ecb 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/raw/fsl_elbc_nand.c diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/raw/fsl_ifc_nand.c index 4872a7ba6503..4872a7ba6503 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/raw/fsl_ifc_nand.c diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/raw/fsl_upm.c index a88e2cf66e0f..a88e2cf66e0f 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/raw/fsl_upm.c diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/raw/fsmc_nand.c index f49ed46fa770..28c48dcc514e 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/raw/fsmc_nand.c @@ -1,6 +1,4 @@ /* - * drivers/mtd/nand/fsmc_nand.c - * * ST Microelectronics * Flexible Static Memory Controller (FSMC) * Driver for NAND portions @@ -9,7 +7,9 @@ * Vipin Kumar <[email protected]> * Ashish Priyadarshi * - * Based on drivers/mtd/nand/nomadik_nand.c + * Based on drivers/mtd/nand/nomadik_nand.c (removed in v3.8) + * Copyright © 2007 STMicroelectronics Pvt. Ltd. + * Copyright © 2009 Alessandro Rubini * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any @@ -103,10 +103,6 @@ #define ECC3 0x1C #define FSMC_NAND_BANK_SZ 0x20 -#define FSMC_NAND_REG(base, bank, reg) (base + FSMC_NOR_REG_SIZE + \ - (FSMC_NAND_BANK_SZ * (bank)) + \ - reg) - #define FSMC_BUSY_WAIT_TIMEOUT (1 * HZ) struct fsmc_nand_timings { @@ -143,7 +139,7 @@ enum access_mode { * @data_va: NAND port for Data. * @cmd_va: NAND port for Command. * @addr_va: NAND port for Address. - * @regs_va: FSMC regs base address. + * @regs_va: Registers base address for a given bank. */ struct fsmc_nand_data { u32 pid; @@ -258,45 +254,6 @@ static inline struct fsmc_nand_data *mtd_to_fsmc(struct mtd_info *mtd) } /* - * fsmc_cmd_ctrl - For facilitaing Hardware access - * This routine allows hardware specific access to control-lines(ALE,CLE) - */ -static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) -{ - struct nand_chip *this = mtd_to_nand(mtd); - struct fsmc_nand_data *host = mtd_to_fsmc(mtd); - void __iomem *regs = host->regs_va; - unsigned int bank = host->bank; - - if (ctrl & NAND_CTRL_CHANGE) { - u32 pc; - - if (ctrl & NAND_CLE) { - this->IO_ADDR_R = host->cmd_va; - this->IO_ADDR_W = host->cmd_va; - } else if (ctrl & NAND_ALE) { - this->IO_ADDR_R = host->addr_va; - this->IO_ADDR_W = host->addr_va; - } else { - this->IO_ADDR_R = host->data_va; - this->IO_ADDR_W = host->data_va; - } - - pc = readl(FSMC_NAND_REG(regs, bank, PC)); - if (ctrl & NAND_NCE) - pc |= FSMC_ENABLE; - else - pc &= ~FSMC_ENABLE; - writel_relaxed(pc, FSMC_NAND_REG(regs, bank, PC)); - } - - mb(); - - if (cmd != NAND_CMD_NONE) - writeb_relaxed(cmd, this->IO_ADDR_W); -} - -/* * fsmc_nand_setup - FSMC (Flexible Static Memory Controller) init routine * * This routine initializes timing parameters related to NAND memory access in @@ -307,8 +264,6 @@ static void fsmc_nand_setup(struct fsmc_nand_data *host, { uint32_t value = FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON; uint32_t tclr, tar, thiz, thold, twait, tset; - unsigned int bank = host->bank; - void __iomem *regs = host->regs_va; tclr = (tims->tclr & FSMC_TCLR_MASK) << FSMC_TCLR_SHIFT; tar = (tims->tar & FSMC_TAR_MASK) << FSMC_TAR_SHIFT; @@ -318,18 +273,14 @@ static void fsmc_nand_setup(struct fsmc_nand_data *host, tset = (tims->tset & FSMC_TSET_MASK) << FSMC_TSET_SHIFT; if (host->nand.options & NAND_BUSWIDTH_16) - writel_relaxed(value | FSMC_DEVWID_16, - FSMC_NAND_REG(regs, bank, PC)); + writel_relaxed(value | FSMC_DEVWID_16, host->regs_va + PC); else - writel_relaxed(value | FSMC_DEVWID_8, - FSMC_NAND_REG(regs, bank, PC)); - - writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) | tclr | tar, - FSMC_NAND_REG(regs, bank, PC)); - writel_relaxed(thiz | thold | twait | tset, - FSMC_NAND_REG(regs, bank, COMM)); - writel_relaxed(thiz | thold | twait | tset, - FSMC_NAND_REG(regs, bank, ATTRIB)); + writel_relaxed(value | FSMC_DEVWID_8, host->regs_va + PC); + + writel_relaxed(readl(host->regs_va + PC) | tclr | tar, + host->regs_va + PC); + writel_relaxed(thiz | thold | twait | tset, host->regs_va + COMM); + writel_relaxed(thiz | thold | twait | tset, host->regs_va + ATTRIB); } static int fsmc_calc_timings(struct fsmc_nand_data *host, @@ -419,15 +370,13 @@ static int fsmc_setup_data_interface(struct mtd_info *mtd, int csline, static void fsmc_enable_hwecc(struct mtd_info *mtd, int mode) { struct fsmc_nand_data *host = mtd_to_fsmc(mtd); - void __iomem *regs = host->regs_va; - uint32_t bank = host->bank; - - writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCPLEN_256, - FSMC_NAND_REG(regs, bank, PC)); - writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCEN, - FSMC_NAND_REG(regs, bank, PC)); - writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) | FSMC_ECCEN, - FSMC_NAND_REG(regs, bank, PC)); + + writel_relaxed(readl(host->regs_va + PC) & ~FSMC_ECCPLEN_256, + host->regs_va + PC); + writel_relaxed(readl(host->regs_va + PC) & ~FSMC_ECCEN, + host->regs_va + PC); + writel_relaxed(readl(host->regs_va + PC) | FSMC_ECCEN, + host->regs_va + PC); } /* @@ -439,13 +388,11 @@ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data, uint8_t *ecc) { struct fsmc_nand_data *host = mtd_to_fsmc(mtd); - void __iomem *regs = host->regs_va; - uint32_t bank = host->bank; uint32_t ecc_tmp; unsigned long deadline = jiffies + FSMC_BUSY_WAIT_TIMEOUT; do { - if (readl_relaxed(FSMC_NAND_REG(regs, bank, STS)) & FSMC_CODE_RDY) + if (readl_relaxed(host->regs_va + STS) & FSMC_CODE_RDY) break; else cond_resched(); @@ -456,25 +403,25 @@ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data, return -ETIMEDOUT; } - ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1)); + ecc_tmp = readl_relaxed(host->regs_va + ECC1); ecc[0] = (uint8_t) (ecc_tmp >> 0); ecc[1] = (uint8_t) (ecc_tmp >> 8); ecc[2] = (uint8_t) (ecc_tmp >> 16); ecc[3] = (uint8_t) (ecc_tmp >> 24); - ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC2)); + ecc_tmp = readl_relaxed(host->regs_va + ECC2); ecc[4] = (uint8_t) (ecc_tmp >> 0); ecc[5] = (uint8_t) (ecc_tmp >> 8); ecc[6] = (uint8_t) (ecc_tmp >> 16); ecc[7] = (uint8_t) (ecc_tmp >> 24); - ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC3)); + ecc_tmp = readl_relaxed(host->regs_va + ECC3); ecc[8] = (uint8_t) (ecc_tmp >> 0); ecc[9] = (uint8_t) (ecc_tmp >> 8); ecc[10] = (uint8_t) (ecc_tmp >> 16); ecc[11] = (uint8_t) (ecc_tmp >> 24); - ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, STS)); + ecc_tmp = readl_relaxed(host->regs_va + STS); ecc[12] = (uint8_t) (ecc_tmp >> 16); return 0; @@ -489,11 +436,9 @@ static int fsmc_read_hwecc_ecc1(struct mtd_info *mtd, const uint8_t *data, uint8_t *ecc) { struct fsmc_nand_data *host = mtd_to_fsmc(mtd); - void __iomem *regs = host->regs_va; - uint32_t bank = host->bank; uint32_t ecc_tmp; - ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1)); + ecc_tmp = readl_relaxed(host->regs_va + ECC1); ecc[0] = (uint8_t) (ecc_tmp >> 0); ecc[1] = (uint8_t) (ecc_tmp >> 8); ecc[2] = (uint8_t) (ecc_tmp >> 16); @@ -598,18 +543,18 @@ unmap_dma: */ static void fsmc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { + struct fsmc_nand_data *host = mtd_to_fsmc(mtd); int i; - struct nand_chip *chip = mtd_to_nand(mtd); if (IS_ALIGNED((uint32_t)buf, sizeof(uint32_t)) && IS_ALIGNED(len, sizeof(uint32_t))) { uint32_t *p = (uint32_t *)buf; len = len >> 2; for (i = 0; i < len; i++) - writel_relaxed(p[i], chip->IO_ADDR_W); + writel_relaxed(p[i], host->data_va); } else { for (i = 0; i < len; i++) - writeb_relaxed(buf[i], chip->IO_ADDR_W); + writeb_relaxed(buf[i], host->data_va); } } @@ -621,18 +566,18 @@ static void fsmc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) */ static void fsmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { + struct fsmc_nand_data *host = mtd_to_fsmc(mtd); int i; - struct nand_chip *chip = mtd_to_nand(mtd); if (IS_ALIGNED((uint32_t)buf, sizeof(uint32_t)) && IS_ALIGNED(len, sizeof(uint32_t))) { uint32_t *p = (uint32_t *)buf; len = len >> 2; for (i = 0; i < len; i++) - p[i] = readl_relaxed(chip->IO_ADDR_R); + p[i] = readl_relaxed(host->data_va); } else { for (i = 0; i < len; i++) - buf[i] = readb_relaxed(chip->IO_ADDR_R); + buf[i] = readb_relaxed(host->data_va); } } @@ -663,6 +608,102 @@ static void fsmc_write_buf_dma(struct mtd_info *mtd, const uint8_t *buf, dma_xfer(host, (void *)buf, len, DMA_TO_DEVICE); } +/* fsmc_select_chip - assert or deassert nCE */ +static void fsmc_select_chip(struct mtd_info *mtd, int chipnr) +{ + struct fsmc_nand_data *host = mtd_to_fsmc(mtd); + u32 pc; + + /* Support only one CS */ + if (chipnr > 0) + return; + + pc = readl(host->regs_va + PC); + if (chipnr < 0) + writel_relaxed(pc & ~FSMC_ENABLE, host->regs_va + PC); + else + writel_relaxed(pc | FSMC_ENABLE, host->regs_va + PC); + + /* nCE line must be asserted before starting any operation */ + mb(); +} + +/* + * fsmc_exec_op - hook called by the core to execute NAND operations + * + * This controller is simple enough and thus does not need to use the parser + * provided by the core, instead, handle every situation here. + */ +static int fsmc_exec_op(struct nand_chip *chip, const struct nand_operation *op, + bool check_only) +{ + struct mtd_info *mtd = nand_to_mtd(chip); + struct fsmc_nand_data *host = mtd_to_fsmc(mtd); + const struct nand_op_instr *instr = NULL; + int ret = 0; + unsigned int op_id; + int i; + + pr_debug("Executing operation [%d instructions]:\n", op->ninstrs); + for (op_id = 0; op_id < op->ninstrs; op_id++) { + instr = &op->instrs[op_id]; + + switch (instr->type) { + case NAND_OP_CMD_INSTR: + pr_debug(" ->CMD [0x%02x]\n", + instr->ctx.cmd.opcode); + + writeb_relaxed(instr->ctx.cmd.opcode, host->cmd_va); + break; + + case NAND_OP_ADDR_INSTR: + pr_debug(" ->ADDR [%d cyc]", + instr->ctx.addr.naddrs); + + for (i = 0; i < instr->ctx.addr.naddrs; i++) + writeb_relaxed(instr->ctx.addr.addrs[i], + host->addr_va); + break; + + case NAND_OP_DATA_IN_INSTR: + pr_debug(" ->DATA_IN [%d B%s]\n", instr->ctx.data.len, + instr->ctx.data.force_8bit ? + ", force 8-bit" : ""); + + if (host->mode == USE_DMA_ACCESS) + fsmc_read_buf_dma(mtd, instr->ctx.data.buf.in, + instr->ctx.data.len); + else + fsmc_read_buf(mtd, instr->ctx.data.buf.in, + instr->ctx.data.len); + break; + + case NAND_OP_DATA_OUT_INSTR: + pr_debug(" ->DATA_OUT [%d B%s]\n", instr->ctx.data.len, + instr->ctx.data.force_8bit ? + ", force 8-bit" : ""); + + if (host->mode == USE_DMA_ACCESS) + fsmc_write_buf_dma(mtd, instr->ctx.data.buf.out, + instr->ctx.data.len); + else + fsmc_write_buf(mtd, instr->ctx.data.buf.out, + instr->ctx.data.len); + break; + + case NAND_OP_WAITRDY_INSTR: + pr_debug(" ->WAITRDY [max %d ms]\n", + instr->ctx.waitrdy.timeout_ms); + + ret = nand_soft_waitrdy(chip, + instr->ctx.waitrdy.timeout_ms); + break; + } + } + + return ret; +} + /* * fsmc_read_page_hwecc * @mtd: mtd info structure @@ -754,13 +795,11 @@ static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat, { struct nand_chip *chip = mtd_to_nand(mtd); struct fsmc_nand_data *host = mtd_to_fsmc(mtd); - void __iomem *regs = host->regs_va; - unsigned int bank = host->bank; uint32_t err_idx[8]; uint32_t num_err, i; uint32_t ecc1, ecc2, ecc3, ecc4; - num_err = (readl_relaxed(FSMC_NAND_REG(regs, bank, STS)) >> 10) & 0xF; + num_err = (readl_relaxed(host->regs_va + STS) >> 10) & 0xF; /* no bit flipping */ if (likely(num_err == 0)) @@ -803,10 +842,10 @@ static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat, * uint64_t array and error offset indexes are populated in err_idx * array */ - ecc1 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1)); - ecc2 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC2)); - ecc3 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC3)); - ecc4 = readl_relaxed(FSMC_NAND_REG(regs, bank, STS)); + ecc1 = readl_relaxed(host->regs_va + ECC1); + ecc2 = readl_relaxed(host->regs_va + ECC2); + ecc3 = readl_relaxed(host->regs_va + ECC3); + ecc4 = readl_relaxed(host->regs_va + STS); err_idx[0] = (ecc1 >> 0) & 0x1FFF; err_idx[1] = (ecc1 >> 13) & 0x1FFF; @@ -889,6 +928,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) struct mtd_info *mtd; struct nand_chip *nand; struct resource *res; + void __iomem *base; dma_cap_mask_t mask; int ret = 0; u32 pid; @@ -923,9 +963,12 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) return PTR_ERR(host->cmd_va); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fsmc_regs"); - host->regs_va = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(host->regs_va)) - return PTR_ERR(host->regs_va); + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + host->regs_va = base + FSMC_NOR_REG_SIZE + + (host->bank * FSMC_NAND_BANK_SZ); host->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(host->clk)) { @@ -942,7 +985,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) * AMBA PrimeCell bus. However it is not a PrimeCell. */ for (pid = 0, i = 0; i < 4; i++) - pid |= (readl(host->regs_va + resource_size(res) - 0x20 + 4 * i) & 255) << (i * 8); + pid |= (readl(base + resource_size(res) - 0x20 + 4 * i) & 255) << (i * 8); host->pid = pid; dev_info(&pdev->dev, "FSMC device partno %03x, manufacturer %02x, " "revision %02x, config %02x\n", @@ -960,9 +1003,8 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) nand_set_flash_node(nand, pdev->dev.of_node); mtd->dev.parent = &pdev->dev; - nand->IO_ADDR_R = host->data_va; - nand->IO_ADDR_W = host->data_va; - nand->cmd_ctrl = fsmc_cmd_ctrl; + nand->exec_op = fsmc_exec_op; + nand->select_chip = fsmc_select_chip; nand->chip_delay = 30; /* @@ -974,8 +1016,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) nand->ecc.size = 512; nand->badblockbits = 7; - switch (host->mode) { - case USE_DMA_ACCESS: + if (host->mode == USE_DMA_ACCESS) { dma_cap_zero(mask); dma_cap_set(DMA_MEMCPY, mask); host->read_dma_chan = dma_request_channel(mask, filter, NULL); @@ -988,15 +1029,6 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Unable to get write dma channel\n"); goto err_req_write_chnl; } - nand->read_buf = fsmc_read_buf_dma; - nand->write_buf = fsmc_write_buf_dma; - break; - - default: - case USE_WORD_ACCESS: - nand->read_buf = fsmc_read_buf; - nand->write_buf = fsmc_write_buf; - break; } if (host->dev_timings) diff --git a/drivers/mtd/nand/gpio.c b/drivers/mtd/nand/raw/gpio.c index a8bde6665c24..2780af26d9ab 100644 --- a/drivers/mtd/nand/gpio.c +++ b/drivers/mtd/nand/raw/gpio.c @@ -1,6 +1,4 @@ /* - * drivers/mtd/nand/gpio.c - * * Updated, and converted to generic GPIO based driver by Russell King. * * Written by Ben Dooks <[email protected]> diff --git a/drivers/mtd/nand/gpmi-nand/Makefile b/drivers/mtd/nand/raw/gpmi-nand/Makefile index 3a462487c35e..3a462487c35e 100644 --- a/drivers/mtd/nand/gpmi-nand/Makefile +++ b/drivers/mtd/nand/raw/gpmi-nand/Makefile diff --git a/drivers/mtd/nand/gpmi-nand/bch-regs.h b/drivers/mtd/nand/raw/gpmi-nand/bch-regs.h index 05bb91f2f4c4..05bb91f2f4c4 100644 --- a/drivers/mtd/nand/gpmi-nand/bch-regs.h +++ b/drivers/mtd/nand/raw/gpmi-nand/bch-regs.h diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c index 97787246af41..97787246af41 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c index 61fdd733492f..61fdd733492f 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h index 06c1f993912c..06c1f993912c 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-regs.h b/drivers/mtd/nand/raw/gpmi-nand/gpmi-regs.h index 82114cdc8330..82114cdc8330 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-regs.h +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-regs.h diff --git a/drivers/mtd/nand/hisi504_nand.c b/drivers/mtd/nand/raw/hisi504_nand.c index cb862793ab6d..cb862793ab6d 100644 --- a/drivers/mtd/nand/hisi504_nand.c +++ b/drivers/mtd/nand/raw/hisi504_nand.c diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/raw/jz4740_nand.c index 613b00a9604b..613b00a9604b 100644 --- a/drivers/mtd/nand/jz4740_nand.c +++ b/drivers/mtd/nand/raw/jz4740_nand.c diff --git a/drivers/mtd/nand/jz4780_bch.c b/drivers/mtd/nand/raw/jz4780_bch.c index 731c6051d91e..731c6051d91e 100644 --- a/drivers/mtd/nand/jz4780_bch.c +++ b/drivers/mtd/nand/raw/jz4780_bch.c diff --git a/drivers/mtd/nand/jz4780_bch.h b/drivers/mtd/nand/raw/jz4780_bch.h index bf4718088a3a..bf4718088a3a 100644 --- a/drivers/mtd/nand/jz4780_bch.h +++ b/drivers/mtd/nand/raw/jz4780_bch.h diff --git a/drivers/mtd/nand/jz4780_nand.c b/drivers/mtd/nand/raw/jz4780_nand.c index e69f6ae4c539..e69f6ae4c539 100644 --- a/drivers/mtd/nand/jz4780_nand.c +++ b/drivers/mtd/nand/raw/jz4780_nand.c diff --git a/drivers/mtd/nand/lpc32xx_mlc.c b/drivers/mtd/nand/raw/lpc32xx_mlc.c index e357948a7505..e357948a7505 100644 --- a/drivers/mtd/nand/lpc32xx_mlc.c +++ b/drivers/mtd/nand/raw/lpc32xx_mlc.c diff --git a/drivers/mtd/nand/lpc32xx_slc.c b/drivers/mtd/nand/raw/lpc32xx_slc.c index 5f7cc6da0a7f..5f7cc6da0a7f 100644 --- a/drivers/mtd/nand/lpc32xx_slc.c +++ b/drivers/mtd/nand/raw/lpc32xx_slc.c diff --git a/drivers/mtd/nand/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c index 03805f9669da..528a8e0342bd 100644 --- a/drivers/mtd/nand/marvell_nand.c +++ b/drivers/mtd/nand/raw/marvell_nand.c @@ -379,6 +379,8 @@ struct marvell_nfc_timings { * return the number of clock periods. */ #define TO_CYCLES(ps, period_ns) (DIV_ROUND_UP(ps / 1000, period_ns)) +#define TO_CYCLES64(ps, period_ns) (DIV_ROUND_UP_ULL(div_u64(ps, 1000), \ + period_ns)) /** * NAND driver structure filled during the parsing of the ->exec_op() subop @@ -2236,8 +2238,20 @@ static int marvell_nfc_setup_data_interface(struct mtd_info *mtd, int chipnr, nfc_tmg.tRHW = TO_CYCLES(max_t(int, sdr->tRHW_min, sdr->tCCS_min), period_ns); - /* Use WAIT_MODE (wait for RB line) instead of only relying on delays */ - nfc_tmg.tR = TO_CYCLES(sdr->tWB_max, period_ns); + /* + * NFCv2: Use WAIT_MODE (wait for RB line), do not rely only on delays. + * NFCv1: No WAIT_MODE, tR must be maximal. + */ + if (nfc->caps->is_nfcv2) { + nfc_tmg.tR = TO_CYCLES(sdr->tWB_max, period_ns); + } else { + nfc_tmg.tR = TO_CYCLES64(sdr->tWB_max + sdr->tR_max, + period_ns); + if (nfc_tmg.tR + 3 > nfc_tmg.tCH) + nfc_tmg.tR = nfc_tmg.tCH - 3; + else + nfc_tmg.tR = 0; + } if (chipnr < 0) return 0; @@ -2249,18 +2263,24 @@ static int marvell_nfc_setup_data_interface(struct mtd_info *mtd, int chipnr, NDTR0_TWP(nfc_tmg.tWP) | NDTR0_TWH(nfc_tmg.tWH) | NDTR0_TCS(nfc_tmg.tCS) | - NDTR0_TCH(nfc_tmg.tCH) | - NDTR0_RD_CNT_DEL(read_delay) | - NDTR0_SELCNTR | - NDTR0_TADL(nfc_tmg.tADL); + NDTR0_TCH(nfc_tmg.tCH); marvell_nand->ndtr1 = NDTR1_TAR(nfc_tmg.tAR) | NDTR1_TWHR(nfc_tmg.tWHR) | - NDTR1_TRHW(nfc_tmg.tRHW) | - NDTR1_WAIT_MODE | NDTR1_TR(nfc_tmg.tR); + if (nfc->caps->is_nfcv2) { + marvell_nand->ndtr0 |= + NDTR0_RD_CNT_DEL(read_delay) | + NDTR0_SELCNTR | + NDTR0_TADL(nfc_tmg.tADL); + + marvell_nand->ndtr1 |= + NDTR1_TRHW(nfc_tmg.tRHW) | + NDTR1_WAIT_MODE; + } + return 0; } @@ -2395,8 +2415,7 @@ static int marvell_nand_chip_init(struct device *dev, struct marvell_nfc *nfc, chip->exec_op = marvell_nfc_exec_op; chip->select_chip = marvell_nfc_select_chip; - if (nfc->caps->is_nfcv2 && - !of_property_read_bool(np, "marvell,nand-keep-config")) + if (!of_property_read_bool(np, "marvell,nand-keep-config")) chip->setup_data_interface = marvell_nfc_setup_data_interface; mtd = nand_to_mtd(chip); diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/raw/mpc5121_nfc.c index b6b97cc9fba6..913b9d1225c6 100644 --- a/drivers/mtd/nand/mpc5121_nfc.c +++ b/drivers/mtd/nand/raw/mpc5121_nfc.c @@ -6,9 +6,8 @@ * by OSADL membership fees in 2009; for details see www.osadl.org. * * Based on original driver from Freescale Semiconductor - * written by John Rigby <[email protected]> on basis - * of drivers/mtd/nand/mxc_nand.c. Reworked and extended - * Piotr Ziecik <[email protected]>. + * written by John Rigby <[email protected]> on basis of mxc_nand.c. + * Reworked and extended by Piotr Ziecik <[email protected]>. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License diff --git a/drivers/mtd/nand/mtk_ecc.c b/drivers/mtd/nand/raw/mtk_ecc.c index 40d86a861a70..40d86a861a70 100644 --- a/drivers/mtd/nand/mtk_ecc.c +++ b/drivers/mtd/nand/raw/mtk_ecc.c diff --git a/drivers/mtd/nand/mtk_ecc.h b/drivers/mtd/nand/raw/mtk_ecc.h index a455df080952..a455df080952 100644 --- a/drivers/mtd/nand/mtk_ecc.h +++ b/drivers/mtd/nand/raw/mtk_ecc.h diff --git a/drivers/mtd/nand/mtk_nand.c b/drivers/mtd/nand/raw/mtk_nand.c index 6977da3a26aa..6977da3a26aa 100644 --- a/drivers/mtd/nand/mtk_nand.c +++ b/drivers/mtd/nand/raw/mtk_nand.c diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/raw/mxc_nand.c index f3be0b2a8869..87b5ee66e501 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/raw/mxc_nand.c @@ -140,6 +140,8 @@ struct mxc_nand_host; struct mxc_nand_devtype_data { void (*preset)(struct mtd_info *); + int (*read_page)(struct nand_chip *chip, void *buf, void *oob, bool ecc, + int page); void (*send_cmd)(struct mxc_nand_host *, uint16_t, int); void (*send_addr)(struct mxc_nand_host *, uint16_t, int); void (*send_page)(struct mtd_info *, unsigned int); @@ -150,10 +152,9 @@ struct mxc_nand_devtype_data { u32 (*get_ecc_status)(struct mxc_nand_host *); const struct mtd_ooblayout_ops *ooblayout; void (*select_chip)(struct mtd_info *mtd, int chip); - int (*correct_data)(struct mtd_info *mtd, u_char *dat, - u_char *read_ecc, u_char *calc_ecc); int (*setup_data_interface)(struct mtd_info *mtd, int csline, const struct nand_data_interface *conf); + void (*enable_hwecc)(struct nand_chip *chip, bool enable); /* * On i.MX21 the CONFIG2:INT bit cannot be read if interrupts are masked @@ -252,6 +253,109 @@ static void memcpy16_toio(void __iomem *trg, const void *src, int size) __raw_writew(*s++, t++); } +/* + * The controller splits a page into data chunks of 512 bytes + partial oob. + * There are writesize / 512 such chunks, the size of the partial oob parts is + * oobsize / #chunks rounded down to a multiple of 2. The last oob chunk then + * contains additionally the byte lost by rounding (if any). + * This function handles the needed shuffling between host->data_buf (which + * holds a page in natural order, i.e. writesize bytes data + oobsize bytes + * spare) and the NFC buffer. + */ +static void copy_spare(struct mtd_info *mtd, bool bfrom, void *buf) +{ + struct nand_chip *this = mtd_to_nand(mtd); + struct mxc_nand_host *host = nand_get_controller_data(this); + u16 i, oob_chunk_size; + u16 num_chunks = mtd->writesize / 512; + + u8 *d = buf; + u8 __iomem *s = host->spare0; + u16 sparebuf_size = host->devtype_data->spare_len; + + /* size of oob chunk for all but possibly the last one */ + oob_chunk_size = (host->used_oobsize / num_chunks) & ~1; + + if (bfrom) { + for (i = 0; i < num_chunks - 1; i++) + memcpy16_fromio(d + i * oob_chunk_size, + s + i * sparebuf_size, + oob_chunk_size); + + /* the last chunk */ + memcpy16_fromio(d + i * oob_chunk_size, + s + i * sparebuf_size, + host->used_oobsize - i * oob_chunk_size); + } else { + for (i = 0; i < num_chunks - 1; i++) + memcpy16_toio(&s[i * sparebuf_size], + &d[i * oob_chunk_size], + oob_chunk_size); + + /* the last chunk */ + memcpy16_toio(&s[i * sparebuf_size], + &d[i * oob_chunk_size], + host->used_oobsize - i * oob_chunk_size); + } +} + +/* + * MXC NANDFC can only perform full page+spare or spare-only read/write. When + * the upper layers perform a read/write buf operation, the saved column address + * is used to index into the full page. So usually this function is called with + * column == 0 (unless no column cycle is needed indicated by column == -1) + */ +static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr) +{ + struct nand_chip *nand_chip = mtd_to_nand(mtd); + struct mxc_nand_host *host = nand_get_controller_data(nand_chip); + + /* Write out column address, if necessary */ + if (column != -1) { + host->devtype_data->send_addr(host, column & 0xff, + page_addr == -1); + if (mtd->writesize > 512) + /* another col addr cycle for 2k page */ + host->devtype_data->send_addr(host, + (column >> 8) & 0xff, + false); + } + + /* Write out page address, if necessary */ + if (page_addr != -1) { + /* paddr_0 - p_addr_7 */ + host->devtype_data->send_addr(host, (page_addr & 0xff), false); + + if (mtd->writesize > 512) { + if (mtd->size >= 0x10000000) { + /* paddr_8 - paddr_15 */ + host->devtype_data->send_addr(host, + (page_addr >> 8) & 0xff, + false); + host->devtype_data->send_addr(host, + (page_addr >> 16) & 0xff, + true); + } else + /* paddr_8 - paddr_15 */ + host->devtype_data->send_addr(host, + (page_addr >> 8) & 0xff, true); + } else { + if (nand_chip->options & NAND_ROW_ADDR_3) { + /* paddr_8 - paddr_15 */ + host->devtype_data->send_addr(host, + (page_addr >> 8) & 0xff, + false); + host->devtype_data->send_addr(host, + (page_addr >> 16) & 0xff, + true); + } else + /* paddr_8 - paddr_15 */ + host->devtype_data->send_addr(host, + (page_addr >> 8) & 0xff, true); + } + } +} + static int check_int_v3(struct mxc_nand_host *host) { uint32_t tmp; @@ -575,6 +679,42 @@ static uint16_t get_dev_status_v1_v2(struct mxc_nand_host *host) return ret; } +static void mxc_nand_enable_hwecc_v1_v2(struct nand_chip *chip, bool enable) +{ + struct mxc_nand_host *host = nand_get_controller_data(chip); + uint16_t config1; + + if (chip->ecc.mode != NAND_ECC_HW) + return; + + config1 = readw(NFC_V1_V2_CONFIG1); + + if (enable) + config1 |= NFC_V1_V2_CONFIG1_ECC_EN; + else + config1 &= ~NFC_V1_V2_CONFIG1_ECC_EN; + + writew(config1, NFC_V1_V2_CONFIG1); +} + +static void mxc_nand_enable_hwecc_v3(struct nand_chip *chip, bool enable) +{ + struct mxc_nand_host *host = nand_get_controller_data(chip); + uint32_t config2; + + if (chip->ecc.mode != NAND_ECC_HW) + return; + + config2 = readl(NFC_V3_CONFIG2); + + if (enable) + config2 |= NFC_V3_CONFIG2_ECC_EN; + else + config2 &= ~NFC_V3_CONFIG2_ECC_EN; + + writel(config2, NFC_V3_CONFIG2); +} + /* This functions is used by upper layer to checks if device is ready */ static int mxc_nand_dev_ready(struct mtd_info *mtd) { @@ -585,45 +725,90 @@ static int mxc_nand_dev_ready(struct mtd_info *mtd) return 1; } -static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode) +static int mxc_nand_read_page_v1(struct nand_chip *chip, void *buf, void *oob, + bool ecc, int page) { - /* - * If HW ECC is enabled, we turn it on during init. There is - * no need to enable again here. - */ -} + struct mtd_info *mtd = nand_to_mtd(chip); + struct mxc_nand_host *host = nand_get_controller_data(chip); + unsigned int bitflips_corrected = 0; + int no_subpages; + int i; -static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat, - u_char *read_ecc, u_char *calc_ecc) -{ - struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct mxc_nand_host *host = nand_get_controller_data(nand_chip); + host->devtype_data->enable_hwecc(chip, ecc); - /* - * 1-Bit errors are automatically corrected in HW. No need for - * additional correction. 2-Bit errors cannot be corrected by - * HW ECC, so we need to return failure - */ - uint16_t ecc_status = get_ecc_status_v1(host); + host->devtype_data->send_cmd(host, NAND_CMD_READ0, false); + mxc_do_addr_cycle(mtd, 0, page); + + if (mtd->writesize > 512) + host->devtype_data->send_cmd(host, NAND_CMD_READSTART, true); + + no_subpages = mtd->writesize >> 9; + + for (i = 0; i < no_subpages; i++) { + uint16_t ecc_stats; + + /* NANDFC buffer 0 is used for page read/write */ + writew((host->active_cs << 4) | i, NFC_V1_V2_BUF_ADDR); + + writew(NFC_OUTPUT, NFC_V1_V2_CONFIG2); + + /* Wait for operation to complete */ + wait_op_done(host, true); - if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) { - dev_dbg(host->dev, "HWECC uncorrectable 2-bit ECC error\n"); - return -EBADMSG; + ecc_stats = get_ecc_status_v1(host); + + ecc_stats >>= 2; + + if (buf && ecc) { + switch (ecc_stats & 0x3) { + case 0: + default: + break; + case 1: + mtd->ecc_stats.corrected++; + bitflips_corrected = 1; + break; + case 2: + mtd->ecc_stats.failed++; + break; + } + } } - return 0; + if (buf) + memcpy32_fromio(buf, host->main_area0, mtd->writesize); + if (oob) + copy_spare(mtd, true, oob); + + return bitflips_corrected; } -static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat, - u_char *read_ecc, u_char *calc_ecc) +static int mxc_nand_read_page_v2_v3(struct nand_chip *chip, void *buf, + void *oob, bool ecc, int page) { - struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct mxc_nand_host *host = nand_get_controller_data(nand_chip); + struct mtd_info *mtd = nand_to_mtd(chip); + struct mxc_nand_host *host = nand_get_controller_data(chip); + unsigned int max_bitflips = 0; u32 ecc_stat, err; - int no_subpages = 1; - int ret = 0; + int no_subpages; u8 ecc_bit_mask, err_limit; + host->devtype_data->enable_hwecc(chip, ecc); + + host->devtype_data->send_cmd(host, NAND_CMD_READ0, false); + mxc_do_addr_cycle(mtd, 0, page); + + if (mtd->writesize > 512) + host->devtype_data->send_cmd(host, + NAND_CMD_READSTART, true); + + host->devtype_data->send_page(mtd, NFC_OUTPUT); + + if (buf) + memcpy32_fromio(buf, host->main_area0, mtd->writesize); + if (oob) + copy_spare(mtd, true, oob); + ecc_bit_mask = (host->eccsize == 4) ? 0x7 : 0xf; err_limit = (host->eccsize == 4) ? 0x4 : 0x8; @@ -634,25 +819,99 @@ static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat, do { err = ecc_stat & ecc_bit_mask; if (err > err_limit) { - dev_dbg(host->dev, "UnCorrectable RS-ECC Error\n"); - return -EBADMSG; + mtd->ecc_stats.failed++; } else { - ret += err; + mtd->ecc_stats.corrected += err; + max_bitflips = max_t(unsigned int, max_bitflips, err); } + ecc_stat >>= 4; } while (--no_subpages); - dev_dbg(host->dev, "%d Symbol Correctable RS-ECC Error\n", ret); + return max_bitflips; +} - return ret; +static int mxc_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip, + uint8_t *buf, int oob_required, int page) +{ + struct mxc_nand_host *host = nand_get_controller_data(chip); + void *oob_buf; + + if (oob_required) + oob_buf = chip->oob_poi; + else + oob_buf = NULL; + + return host->devtype_data->read_page(chip, buf, oob_buf, 1, page); } -static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, - u_char *ecc_code) +static int mxc_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, + uint8_t *buf, int oob_required, int page) { + struct mxc_nand_host *host = nand_get_controller_data(chip); + void *oob_buf; + + if (oob_required) + oob_buf = chip->oob_poi; + else + oob_buf = NULL; + + return host->devtype_data->read_page(chip, buf, oob_buf, 0, page); +} + +static int mxc_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip, + int page) +{ + struct mxc_nand_host *host = nand_get_controller_data(chip); + + return host->devtype_data->read_page(chip, NULL, chip->oob_poi, 0, + page); +} + +static int mxc_nand_write_page(struct nand_chip *chip, const uint8_t *buf, + bool ecc, int page) +{ + struct mtd_info *mtd = nand_to_mtd(chip); + struct mxc_nand_host *host = nand_get_controller_data(chip); + + host->devtype_data->enable_hwecc(chip, ecc); + + host->devtype_data->send_cmd(host, NAND_CMD_SEQIN, false); + mxc_do_addr_cycle(mtd, 0, page); + + memcpy32_toio(host->main_area0, buf, mtd->writesize); + copy_spare(mtd, false, chip->oob_poi); + + host->devtype_data->send_page(mtd, NFC_INPUT); + host->devtype_data->send_cmd(host, NAND_CMD_PAGEPROG, true); + mxc_do_addr_cycle(mtd, 0, page); + return 0; } +static int mxc_nand_write_page_ecc(struct mtd_info *mtd, struct nand_chip *chip, + const uint8_t *buf, int oob_required, + int page) +{ + return mxc_nand_write_page(chip, buf, true, page); +} + +static int mxc_nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, + const uint8_t *buf, int oob_required, int page) +{ + return mxc_nand_write_page(chip, buf, false, page); +} + +static int mxc_nand_write_oob(struct mtd_info *mtd, struct nand_chip *chip, + int page) +{ + struct mxc_nand_host *host = nand_get_controller_data(chip); + + memset(host->data_buf, 0xff, mtd->writesize); + + return mxc_nand_write_page(chip, host->data_buf, false, page); +} + static u_char mxc_nand_read_byte(struct mtd_info *mtd) { struct nand_chip *nand_chip = mtd_to_nand(mtd); @@ -772,109 +1031,6 @@ static void mxc_nand_select_chip_v2(struct mtd_info *mtd, int chip) writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR); } -/* - * The controller splits a page into data chunks of 512 bytes + partial oob. - * There are writesize / 512 such chunks, the size of the partial oob parts is - * oobsize / #chunks rounded down to a multiple of 2. The last oob chunk then - * contains additionally the byte lost by rounding (if any). - * This function handles the needed shuffling between host->data_buf (which - * holds a page in natural order, i.e. writesize bytes data + oobsize bytes - * spare) and the NFC buffer. - */ -static void copy_spare(struct mtd_info *mtd, bool bfrom) -{ - struct nand_chip *this = mtd_to_nand(mtd); - struct mxc_nand_host *host = nand_get_controller_data(this); - u16 i, oob_chunk_size; - u16 num_chunks = mtd->writesize / 512; - - u8 *d = host->data_buf + mtd->writesize; - u8 __iomem *s = host->spare0; - u16 sparebuf_size = host->devtype_data->spare_len; - - /* size of oob chunk for all but possibly the last one */ - oob_chunk_size = (host->used_oobsize / num_chunks) & ~1; - - if (bfrom) { - for (i = 0; i < num_chunks - 1; i++) - memcpy16_fromio(d + i * oob_chunk_size, - s + i * sparebuf_size, - oob_chunk_size); - - /* the last chunk */ - memcpy16_fromio(d + i * oob_chunk_size, - s + i * sparebuf_size, - host->used_oobsize - i * oob_chunk_size); - } else { - for (i = 0; i < num_chunks - 1; i++) - memcpy16_toio(&s[i * sparebuf_size], - &d[i * oob_chunk_size], - oob_chunk_size); - - /* the last chunk */ - memcpy16_toio(&s[i * sparebuf_size], - &d[i * oob_chunk_size], - host->used_oobsize - i * oob_chunk_size); - } -} - -/* - * MXC NANDFC can only perform full page+spare or spare-only read/write. When - * the upper layers perform a read/write buf operation, the saved column address - * is used to index into the full page. So usually this function is called with - * column == 0 (unless no column cycle is needed indicated by column == -1) - */ -static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr) -{ - struct nand_chip *nand_chip = mtd_to_nand(mtd); - struct mxc_nand_host *host = nand_get_controller_data(nand_chip); - - /* Write out column address, if necessary */ - if (column != -1) { - host->devtype_data->send_addr(host, column & 0xff, - page_addr == -1); - if (mtd->writesize > 512) - /* another col addr cycle for 2k page */ - host->devtype_data->send_addr(host, - (column >> 8) & 0xff, - false); - } - - /* Write out page address, if necessary */ - if (page_addr != -1) { - /* paddr_0 - p_addr_7 */ - host->devtype_data->send_addr(host, (page_addr & 0xff), false); - - if (mtd->writesize > 512) { - if (mtd->size >= 0x10000000) { - /* paddr_8 - paddr_15 */ - host->devtype_data->send_addr(host, - (page_addr >> 8) & 0xff, - false); - host->devtype_data->send_addr(host, - (page_addr >> 16) & 0xff, - true); - } else - /* paddr_8 - paddr_15 */ - host->devtype_data->send_addr(host, - (page_addr >> 8) & 0xff, true); - } else { - if (nand_chip->options & NAND_ROW_ADDR_3) { - /* paddr_8 - paddr_15 */ - host->devtype_data->send_addr(host, - (page_addr >> 8) & 0xff, - false); - host->devtype_data->send_addr(host, - (page_addr >> 16) & 0xff, - true); - } else - /* paddr_8 - paddr_15 */ - host->devtype_data->send_addr(host, - (page_addr >> 8) & 0xff, true); - } - } -} - #define MXC_V1_ECCBYTES 5 static int mxc_v1_ooblayout_ecc(struct mtd_info *mtd, int section, @@ -1235,57 +1391,6 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, mxc_do_addr_cycle(mtd, column, page_addr); break; - case NAND_CMD_READ0: - case NAND_CMD_READOOB: - if (command == NAND_CMD_READ0) - host->buf_start = column; - else - host->buf_start = column + mtd->writesize; - - command = NAND_CMD_READ0; /* only READ0 is valid */ - - host->devtype_data->send_cmd(host, command, false); - WARN_ONCE(column < 0, - "Unexpected column/row value (cmd=%u, col=%d, row=%d)\n", - command, column, page_addr); - mxc_do_addr_cycle(mtd, 0, page_addr); - - if (mtd->writesize > 512) - host->devtype_data->send_cmd(host, - NAND_CMD_READSTART, true); - - host->devtype_data->send_page(mtd, NFC_OUTPUT); - - memcpy32_fromio(host->data_buf, host->main_area0, - mtd->writesize); - copy_spare(mtd, true); - break; - - case NAND_CMD_SEQIN: - if (column >= mtd->writesize) - /* call ourself to read a page */ - mxc_nand_command(mtd, NAND_CMD_READ0, 0, page_addr); - - host->buf_start = column; - - host->devtype_data->send_cmd(host, command, false); - WARN_ONCE(column < -1, - "Unexpected column/row value (cmd=%u, col=%d, row=%d)\n", - command, column, page_addr); - mxc_do_addr_cycle(mtd, 0, page_addr); - break; - - case NAND_CMD_PAGEPROG: - memcpy32_toio(host->main_area0, host->data_buf, mtd->writesize); - copy_spare(mtd, false); - host->devtype_data->send_page(mtd, NFC_INPUT); - host->devtype_data->send_cmd(host, command, true); - WARN_ONCE(column != -1 || page_addr != -1, - "Unexpected column/row value (cmd=%u, col=%d, row=%d)\n", - command, column, page_addr); - mxc_do_addr_cycle(mtd, column, page_addr); - break; - case NAND_CMD_READID: host->devtype_data->send_cmd(host, command, true); mxc_do_addr_cycle(mtd, column, page_addr); @@ -1397,6 +1502,7 @@ static struct nand_bbt_descr bbt_mirror_descr = { /* v1 + irqpending_quirk: i.MX21 */ static const struct mxc_nand_devtype_data imx21_nand_devtype_data = { .preset = preset_v1, + .read_page = mxc_nand_read_page_v1, .send_cmd = send_cmd_v1_v2, .send_addr = send_addr_v1_v2, .send_page = send_page_v1, @@ -1407,7 +1513,7 @@ static const struct mxc_nand_devtype_data imx21_nand_devtype_data = { .get_ecc_status = get_ecc_status_v1, .ooblayout = &mxc_v1_ooblayout_ops, .select_chip = mxc_nand_select_chip_v1_v3, - .correct_data = mxc_nand_correct_data_v1, + .enable_hwecc = mxc_nand_enable_hwecc_v1_v2, .irqpending_quirk = 1, .needs_ip = 0, .regs_offset = 0xe00, @@ -1420,6 +1526,7 @@ static const struct mxc_nand_devtype_data imx21_nand_devtype_data = { /* v1 + !irqpending_quirk: i.MX27, i.MX31 */ static const struct mxc_nand_devtype_data imx27_nand_devtype_data = { .preset = preset_v1, + .read_page = mxc_nand_read_page_v1, .send_cmd = send_cmd_v1_v2, .send_addr = send_addr_v1_v2, .send_page = send_page_v1, @@ -1430,7 +1537,7 @@ static const struct mxc_nand_devtype_data imx27_nand_devtype_data = { .get_ecc_status = get_ecc_status_v1, .ooblayout = &mxc_v1_ooblayout_ops, .select_chip = mxc_nand_select_chip_v1_v3, - .correct_data = mxc_nand_correct_data_v1, + .enable_hwecc = mxc_nand_enable_hwecc_v1_v2, .irqpending_quirk = 0, .needs_ip = 0, .regs_offset = 0xe00, @@ -1444,6 +1551,7 @@ static const struct mxc_nand_devtype_data imx27_nand_devtype_data = { /* v21: i.MX25, i.MX35 */ static const struct mxc_nand_devtype_data imx25_nand_devtype_data = { .preset = preset_v2, + .read_page = mxc_nand_read_page_v2_v3, .send_cmd = send_cmd_v1_v2, .send_addr = send_addr_v1_v2, .send_page = send_page_v2, @@ -1454,8 +1562,8 @@ static const struct mxc_nand_devtype_data imx25_nand_devtype_data = { .get_ecc_status = get_ecc_status_v2, .ooblayout = &mxc_v2_ooblayout_ops, .select_chip = mxc_nand_select_chip_v2, - .correct_data = mxc_nand_correct_data_v2_v3, .setup_data_interface = mxc_nand_v2_setup_data_interface, + .enable_hwecc = mxc_nand_enable_hwecc_v1_v2, .irqpending_quirk = 0, .needs_ip = 0, .regs_offset = 0x1e00, @@ -1469,6 +1577,7 @@ static const struct mxc_nand_devtype_data imx25_nand_devtype_data = { /* v3.2a: i.MX51 */ static const struct mxc_nand_devtype_data imx51_nand_devtype_data = { .preset = preset_v3, + .read_page = mxc_nand_read_page_v2_v3, .send_cmd = send_cmd_v3, .send_addr = send_addr_v3, .send_page = send_page_v3, @@ -1479,7 +1588,7 @@ static const struct mxc_nand_devtype_data imx51_nand_devtype_data = { .get_ecc_status = get_ecc_status_v3, .ooblayout = &mxc_v2_ooblayout_ops, .select_chip = mxc_nand_select_chip_v1_v3, - .correct_data = mxc_nand_correct_data_v2_v3, + .enable_hwecc = mxc_nand_enable_hwecc_v3, .irqpending_quirk = 0, .needs_ip = 1, .regs_offset = 0, @@ -1494,6 +1603,7 @@ static const struct mxc_nand_devtype_data imx51_nand_devtype_data = { /* v3.2b: i.MX53 */ static const struct mxc_nand_devtype_data imx53_nand_devtype_data = { .preset = preset_v3, + .read_page = mxc_nand_read_page_v2_v3, .send_cmd = send_cmd_v3, .send_addr = send_addr_v3, .send_page = send_page_v3, @@ -1504,7 +1614,7 @@ static const struct mxc_nand_devtype_data imx53_nand_devtype_data = { .get_ecc_status = get_ecc_status_v3, .ooblayout = &mxc_v2_ooblayout_ops, .select_chip = mxc_nand_select_chip_v1_v3, - .correct_data = mxc_nand_correct_data_v2_v3, + .enable_hwecc = mxc_nand_enable_hwecc_v3, .irqpending_quirk = 0, .needs_ip = 1, .regs_offset = 0, @@ -1751,9 +1861,12 @@ static int mxcnd_probe(struct platform_device *pdev) switch (this->ecc.mode) { case NAND_ECC_HW: - this->ecc.calculate = mxc_nand_calculate_ecc; - this->ecc.hwctl = mxc_nand_enable_hwecc; - this->ecc.correct = host->devtype_data->correct_data; + this->ecc.read_page = mxc_nand_read_page; + this->ecc.read_page_raw = mxc_nand_read_page_raw; + this->ecc.read_oob = mxc_nand_read_oob; + this->ecc.write_page = mxc_nand_write_page_ecc; + this->ecc.write_page_raw = mxc_nand_write_page_raw; + this->ecc.write_oob = mxc_nand_write_oob; break; case NAND_ECC_SOFT: diff --git a/drivers/mtd/nand/nand_amd.c b/drivers/mtd/nand/raw/nand_amd.c index 22f060f38123..22f060f38123 100644 --- a/drivers/mtd/nand/nand_amd.c +++ b/drivers/mtd/nand/raw/nand_amd.c diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index e70ca16a5118..e70ca16a5118 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/raw/nand_bbt.c index 36092850be2c..36092850be2c 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/raw/nand_bbt.c diff --git a/drivers/mtd/nand/nand_bch.c b/drivers/mtd/nand/raw/nand_bch.c index 505441c9373b..505441c9373b 100644 --- a/drivers/mtd/nand/nand_bch.c +++ b/drivers/mtd/nand/raw/nand_bch.c diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/raw/nand_ecc.c index 7613a0388044..3630f0fe8fa4 100644 --- a/drivers/mtd/nand/nand_ecc.c +++ b/drivers/mtd/nand/raw/nand_ecc.c @@ -2,8 +2,6 @@ * This file contains an ECC algorithm that detects and corrects 1 bit * errors in a 256 byte block of data. * - * drivers/mtd/nand/nand_ecc.c - * * Copyright © 2008 Koninklijke Philips Electronics NV. * Author: Frans Meulenbroeks * diff --git a/drivers/mtd/nand/nand_hynix.c b/drivers/mtd/nand/raw/nand_hynix.c index d542908a0ebb..d542908a0ebb 100644 --- a/drivers/mtd/nand/nand_hynix.c +++ b/drivers/mtd/nand/raw/nand_hynix.c diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/raw/nand_ids.c index 5423c3bb388e..5423c3bb388e 100644 --- a/drivers/mtd/nand/nand_ids.c +++ b/drivers/mtd/nand/raw/nand_ids.c diff --git a/drivers/mtd/nand/nand_macronix.c b/drivers/mtd/nand/raw/nand_macronix.c index d290ff2a6d2f..d290ff2a6d2f 100644 --- a/drivers/mtd/nand/nand_macronix.c +++ b/drivers/mtd/nand/raw/nand_macronix.c diff --git a/drivers/mtd/nand/nand_micron.c b/drivers/mtd/nand/raw/nand_micron.c index 02e109ae73f1..02e109ae73f1 100644 --- a/drivers/mtd/nand/nand_micron.c +++ b/drivers/mtd/nand/raw/nand_micron.c diff --git a/drivers/mtd/nand/nand_samsung.c b/drivers/mtd/nand/raw/nand_samsung.c index ef022f62f74c..ef022f62f74c 100644 --- a/drivers/mtd/nand/nand_samsung.c +++ b/drivers/mtd/nand/raw/nand_samsung.c diff --git a/drivers/mtd/nand/nand_timings.c b/drivers/mtd/nand/raw/nand_timings.c index 9400d039ddbd..9400d039ddbd 100644 --- a/drivers/mtd/nand/nand_timings.c +++ b/drivers/mtd/nand/raw/nand_timings.c diff --git a/drivers/mtd/nand/nand_toshiba.c b/drivers/mtd/nand/raw/nand_toshiba.c index 57df857074e6..ab43f027cd23 100644 --- a/drivers/mtd/nand/nand_toshiba.c +++ b/drivers/mtd/nand/raw/nand_toshiba.c @@ -35,6 +35,32 @@ static void toshiba_nand_decode_id(struct nand_chip *chip) (chip->id.data[5] & 0x7) == 0x6 /* 24nm */ && !(chip->id.data[4] & 0x80) /* !BENAND */) mtd->oobsize = 32 * mtd->writesize >> 9; + + /* + * Extract ECC requirements from 6th id byte. + * For Toshiba SLC, ecc requrements are as follows: + * - 43nm: 1 bit ECC for each 512Byte is required. + * - 32nm: 4 bit ECC for each 512Byte is required. + * - 24nm: 8 bit ECC for each 512Byte is required. + */ + if (chip->id.len >= 6 && nand_is_slc(chip)) { + chip->ecc_step_ds = 512; + switch (chip->id.data[5] & 0x7) { + case 0x4: + chip->ecc_strength_ds = 1; + break; + case 0x5: + chip->ecc_strength_ds = 4; + break; + case 0x6: + chip->ecc_strength_ds = 8; + break; + default: + WARN(1, "Could not get ECC info"); + chip->ecc_step_ds = 0; + break; + } + } } static int toshiba_nand_init(struct nand_chip *chip) diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/raw/nandsim.c index 44322a363ba5..44322a363ba5 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/raw/nandsim.c diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/raw/ndfc.c index d8a806894937..d8a806894937 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/raw/ndfc.c diff --git a/drivers/mtd/nand/nuc900_nand.c b/drivers/mtd/nand/raw/nuc900_nand.c index af5b32c9a791..af5b32c9a791 100644 --- a/drivers/mtd/nand/nuc900_nand.c +++ b/drivers/mtd/nand/raw/nuc900_nand.c diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/raw/omap2.c index 8cdf7d3d8fa7..8cdf7d3d8fa7 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/raw/omap2.c diff --git a/drivers/mtd/nand/omap_elm.c b/drivers/mtd/nand/raw/omap_elm.c index a3f32f939cc1..a3f32f939cc1 100644 --- a/drivers/mtd/nand/omap_elm.c +++ b/drivers/mtd/nand/raw/omap_elm.c diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/raw/orion_nand.c index 5a5aa1f07d07..7825fd3ce66b 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/raw/orion_nand.c @@ -1,6 +1,4 @@ /* - * drivers/mtd/nand/orion_nand.c - * * NAND support for Marvell Orion SoC platforms * * Tzachi Perelstein <[email protected]> diff --git a/drivers/mtd/nand/oxnas_nand.c b/drivers/mtd/nand/raw/oxnas_nand.c index d649d5944826..d649d5944826 100644 --- a/drivers/mtd/nand/oxnas_nand.c +++ b/drivers/mtd/nand/raw/oxnas_nand.c diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/raw/pasemi_nand.c index a47a7e4bd25a..a47a7e4bd25a 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/raw/pasemi_nand.c diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/raw/plat_nand.c index 925a1323604d..925a1323604d 100644 --- a/drivers/mtd/nand/plat_nand.c +++ b/drivers/mtd/nand/raw/plat_nand.c diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c index 563b759ffca6..563b759ffca6 100644 --- a/drivers/mtd/nand/qcom_nandc.c +++ b/drivers/mtd/nand/raw/qcom_nandc.c diff --git a/drivers/mtd/nand/r852.c b/drivers/mtd/nand/raw/r852.c index 595635b9e9de..595635b9e9de 100644 --- a/drivers/mtd/nand/r852.c +++ b/drivers/mtd/nand/raw/r852.c diff --git a/drivers/mtd/nand/r852.h b/drivers/mtd/nand/raw/r852.h index 8713c57f6207..8713c57f6207 100644 --- a/drivers/mtd/nand/r852.h +++ b/drivers/mtd/nand/raw/r852.h diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/raw/s3c2410.c index 4c383eeec6f6..b5bc5f106c09 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/raw/s3c2410.c @@ -1,5 +1,4 @@ -/* linux/drivers/mtd/nand/s3c2410.c - * +/* * Copyright © 2004-2008 Simtec Electronics * http://armlinux.simtec.co.uk/ * Ben Dooks <[email protected]> diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/raw/sh_flctl.c index c4e7755448e6..c4e7755448e6 100644 --- a/drivers/mtd/nand/sh_flctl.c +++ b/drivers/mtd/nand/raw/sh_flctl.c diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/raw/sharpsl.c index f59c455d9f51..e93df02c825e 100644 --- a/drivers/mtd/nand/sharpsl.c +++ b/drivers/mtd/nand/raw/sharpsl.c @@ -1,6 +1,4 @@ /* - * drivers/mtd/nand/sharpsl.c - * * Copyright (C) 2004 Richard Purdie * Copyright (C) 2008 Dmitry Baryshkov * diff --git a/drivers/mtd/nand/sm_common.c b/drivers/mtd/nand/raw/sm_common.c index c378705c6e2b..c378705c6e2b 100644 --- a/drivers/mtd/nand/sm_common.c +++ b/drivers/mtd/nand/raw/sm_common.c diff --git a/drivers/mtd/nand/sm_common.h b/drivers/mtd/nand/raw/sm_common.h index 1581671b05ae..1581671b05ae 100644 --- a/drivers/mtd/nand/sm_common.h +++ b/drivers/mtd/nand/raw/sm_common.h diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/raw/socrates_nand.c index 575997d0ef8a..9824a9923583 100644 --- a/drivers/mtd/nand/socrates_nand.c +++ b/drivers/mtd/nand/raw/socrates_nand.c @@ -1,6 +1,4 @@ /* - * drivers/mtd/nand/socrates_nand.c - * * Copyright © 2008 Ilya Yanok, Emcraft Systems * * diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index f5a55c63935c..f5a55c63935c 100644 --- a/drivers/mtd/nand/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c diff --git a/drivers/mtd/nand/tango_nand.c b/drivers/mtd/nand/raw/tango_nand.c index c5bee00b7f5e..c5bee00b7f5e 100644 --- a/drivers/mtd/nand/tango_nand.c +++ b/drivers/mtd/nand/raw/tango_nand.c diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/raw/tmio_nand.c index dcaa924502de..dcaa924502de 100644 --- a/drivers/mtd/nand/tmio_nand.c +++ b/drivers/mtd/nand/raw/tmio_nand.c diff --git a/drivers/mtd/nand/txx9ndfmc.c b/drivers/mtd/nand/raw/txx9ndfmc.c index b567d212fe7d..b567d212fe7d 100644 --- a/drivers/mtd/nand/txx9ndfmc.c +++ b/drivers/mtd/nand/raw/txx9ndfmc.c diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/raw/vf610_nfc.c index 80d31a58e558..5d7a1f8f580f 100644 --- a/drivers/mtd/nand/vf610_nfc.c +++ b/drivers/mtd/nand/raw/vf610_nfc.c @@ -511,21 +511,6 @@ static void vf610_nfc_select_chip(struct mtd_info *mtd, int chip) vf610_nfc_write(nfc, NFC_ROW_ADDR, tmp); } -/* Count the number of 0's in buff up to max_bits */ -static inline int count_written_bits(uint8_t *buff, int size, int max_bits) -{ - uint32_t *buff32 = (uint32_t *)buff; - int k, written_bits = 0; - - for (k = 0; k < (size / 4); k++) { - written_bits += hweight32(~buff32[k]); - if (unlikely(written_bits > max_bits)) - break; - } - - return written_bits; -} - static inline int vf610_nfc_correct_data(struct mtd_info *mtd, uint8_t *dat, uint8_t *oob, int page) { @@ -682,7 +667,7 @@ static int vf610_nfc_probe(struct platform_device *pdev) dev_err(nfc->dev, "Only one NAND chip supported!\n"); err = -EINVAL; - goto error; + goto err_disable_clk; } nand_set_flash_node(chip, child); @@ -692,7 +677,7 @@ static int vf610_nfc_probe(struct platform_device *pdev) if (!nand_get_flash_node(chip)) { dev_err(nfc->dev, "NAND chip sub-node missing!\n"); err = -ENODEV; - goto err_clk; + goto err_disable_clk; } chip->dev_ready = vf610_nfc_dev_ready; @@ -712,7 +697,7 @@ static int vf610_nfc_probe(struct platform_device *pdev) err = devm_request_irq(nfc->dev, irq, vf610_nfc_irq, 0, DRV_NAME, mtd); if (err) { dev_err(nfc->dev, "Error requesting IRQ!\n"); - goto error; + goto err_disable_clk; } vf610_nfc_preinit_controller(nfc); @@ -720,7 +705,7 @@ static int vf610_nfc_probe(struct platform_device *pdev) /* first scan to find the device and get the page size */ err = nand_scan_ident(mtd, 1, NULL); if (err) - goto error; + goto err_disable_clk; vf610_nfc_init_controller(nfc); @@ -732,20 +717,20 @@ static int vf610_nfc_probe(struct platform_device *pdev) if (mtd->writesize + mtd->oobsize > PAGE_2K + OOB_MAX - 8) { dev_err(nfc->dev, "Unsupported flash page size\n"); err = -ENXIO; - goto error; + goto err_disable_clk; } if (chip->ecc.mode == NAND_ECC_HW) { if (mtd->writesize != PAGE_2K && mtd->oobsize < 64) { dev_err(nfc->dev, "Unsupported flash with hwecc\n"); err = -ENXIO; - goto error; + goto err_disable_clk; } if (chip->ecc.size != mtd->writesize) { dev_err(nfc->dev, "Step size needs to be page size\n"); err = -ENXIO; - goto error; + goto err_disable_clk; } /* Only 64 byte ECC layouts known */ @@ -765,7 +750,7 @@ static int vf610_nfc_probe(struct platform_device *pdev) } else { dev_err(nfc->dev, "Unsupported ECC strength\n"); err = -ENXIO; - goto error; + goto err_disable_clk; } chip->ecc.read_page = vf610_nfc_read_page; @@ -777,16 +762,19 @@ static int vf610_nfc_probe(struct platform_device *pdev) /* second phase scan */ err = nand_scan_tail(mtd); if (err) - goto error; + goto err_disable_clk; platform_set_drvdata(pdev, mtd); /* Register device in MTD */ - return mtd_device_register(mtd, NULL, 0); + err = mtd_device_register(mtd, NULL, 0); + if (err) + goto err_cleanup_nand; + return 0; -error: - of_node_put(nand_get_flash_node(chip)); -err_clk: +err_cleanup_nand: + nand_cleanup(chip); +err_disable_clk: clk_disable_unprepare(nfc->clk); return err; } diff --git a/drivers/mtd/nand/xway_nand.c b/drivers/mtd/nand/raw/xway_nand.c index 9926b4e3d69d..9926b4e3d69d 100644 --- a/drivers/mtd/nand/xway_nand.c +++ b/drivers/mtd/nand/raw/xway_nand.c diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c index 4237c7cebf02..fa176f5937bb 100644 --- a/drivers/mtd/sm_ftl.c +++ b/drivers/mtd/sm_ftl.c @@ -17,7 +17,7 @@ #include <linux/bitops.h> #include <linux/slab.h> #include <linux/mtd/nand_ecc.h> -#include "nand/sm_common.h" +#include "nand/raw/sm_common.h" #include "sm_ftl.h" diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h index 3bf8f954b642..3102bd754d18 100644 --- a/include/linux/mtd/bbm.h +++ b/include/linux/mtd/bbm.h @@ -1,6 +1,4 @@ /* - * linux/include/linux/mtd/bbm.h - * * NAND family Bad Block Management (BBM) header file * - Bad Block Table (BBT) implementation * diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h new file mode 100644 index 000000000000..792ea5c26329 --- /dev/null +++ b/include/linux/mtd/nand.h @@ -0,0 +1,731 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2017 - Free Electrons + * + * Authors: + * Boris Brezillon <[email protected]> + * Peter Pan <[email protected]> + */ + +#ifndef __LINUX_MTD_NAND_H +#define __LINUX_MTD_NAND_H + +#include <linux/mtd/mtd.h> + +/** + * struct nand_memory_organization - Memory organization structure + * @bits_per_cell: number of bits per NAND cell + * @pagesize: page size + * @oobsize: OOB area size + * @pages_per_eraseblock: number of pages per eraseblock + * @eraseblocks_per_lun: number of eraseblocks per LUN (Logical Unit Number) + * @planes_per_lun: number of planes per LUN + * @luns_per_target: number of LUN per target (target is a synonym for die) + * @ntargets: total number of targets exposed by the NAND device + */ +struct nand_memory_organization { + unsigned int bits_per_cell; + unsigned int pagesize; + unsigned int oobsize; + unsigned int pages_per_eraseblock; + unsigned int eraseblocks_per_lun; + unsigned int planes_per_lun; + unsigned int luns_per_target; + unsigned int ntargets; +}; + +#define NAND_MEMORG(bpc, ps, os, ppe, epl, ppl, lpt, nt) \ + { \ + .bits_per_cell = (bpc), \ + .pagesize = (ps), \ + .oobsize = (os), \ + .pages_per_eraseblock = (ppe), \ + .eraseblocks_per_lun = (epl), \ + .planes_per_lun = (ppl), \ + .luns_per_target = (lpt), \ + .ntargets = (nt), \ + } + +/** + * struct nand_row_converter - Information needed to convert an absolute offset + * into a row address + * @lun_addr_shift: position of the LUN identifier in the row address + * @eraseblock_addr_shift: position of the eraseblock identifier in the row + * address + */ +struct nand_row_converter { + unsigned int lun_addr_shift; + unsigned int eraseblock_addr_shift; +}; + +/** + * struct nand_pos - NAND position object + * @target: the NAND target/die + * @lun: the LUN identifier + * @plane: the plane within the LUN + * @eraseblock: the eraseblock within the LUN + * @page: the page within the LUN + * + * These information are usually used by specific sub-layers to select the + * appropriate target/die and generate a row address to pass to the device. + */ +struct nand_pos { + unsigned int target; + unsigned int lun; + unsigned int plane; + unsigned int eraseblock; + unsigned int page; +}; + +/** + * struct nand_page_io_req - NAND I/O request object + * @pos: the position this I/O request is targeting + * @dataoffs: the offset within the page + * @datalen: number of data bytes to read from/write to this page + * @databuf: buffer to store data in or get data from + * @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 + * + * 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 + * specific NAND layers can focus on translating these information into + * specific commands/operations. + */ +struct nand_page_io_req { + struct nand_pos pos; + unsigned int dataoffs; + unsigned int datalen; + union { + const void *out; + void *in; + } databuf; + unsigned int ooboffs; + unsigned int ooblen; + union { + const void *out; + void *in; + } oobbuf; +}; + +/** + * struct nand_ecc_req - NAND ECC requirements + * @strength: ECC strength + * @step_size: ECC step/block size + */ +struct nand_ecc_req { + unsigned int strength; + unsigned int step_size; +}; + +#define NAND_ECCREQ(str, stp) { .strength = (str), .step_size = (stp) } + +/** + * struct nand_bbt - bad block table object + * @cache: in memory BBT cache + */ +struct nand_bbt { + unsigned long *cache; +}; + +struct nand_device; + +/** + * struct nand_ops - NAND operations + * @erase: erase a specific block. No need to check if the block is bad before + * erasing, this has been taken care of by the generic NAND layer + * @markbad: mark a specific block bad. No need to check if the block is + * already marked bad, this has been taken care of by the generic + * NAND layer. This method should just write the BBM (Bad Block + * Marker) so that future call to struct_nand_ops->isbad() return + * true + * @isbad: check whether a block is bad or not. This method should just read + * the BBM and return whether the block is bad or not based on what it + * reads + * + * These are all low level operations that should be implemented by specialized + * NAND layers (SPI NAND, raw NAND, ...). + */ +struct nand_ops { + int (*erase)(struct nand_device *nand, const struct nand_pos *pos); + int (*markbad)(struct nand_device *nand, const struct nand_pos *pos); + bool (*isbad)(struct nand_device *nand, const struct nand_pos *pos); +}; + +/** + * struct nand_device - NAND device + * @mtd: MTD instance attached to the NAND device + * @memorg: memory layout + * @eccreq: ECC requirements + * @rowconv: position to row address converter + * @bbt: bad block table info + * @ops: NAND operations attached to the NAND device + * + * Generic NAND object. Specialized NAND layers (raw NAND, SPI NAND, OneNAND) + * should declare their own NAND object embedding a nand_device struct (that's + * how inheritance is done). + * struct_nand_device->memorg and struct_nand_device->eccreq should be filled + * at device detection time to reflect the NAND device + * capabilities/requirements. Once this is done nanddev_init() can be called. + * It will take care of converting NAND information into MTD ones, which means + * the specialized NAND layers should never manually tweak + * struct_nand_device->mtd except for the ->_read/write() hooks. + */ +struct nand_device { + struct mtd_info mtd; + struct nand_memory_organization memorg; + struct nand_ecc_req eccreq; + struct nand_row_converter rowconv; + struct nand_bbt bbt; + const struct nand_ops *ops; +}; + +/** + * struct nand_io_iter - NAND I/O iterator + * @req: current I/O request + * @oobbytes_per_page: maximum number of OOB bytes per page + * @dataleft: remaining number of data bytes to read/write + * @oobleft: remaining number of OOB bytes to read/write + * + * Can be used by specialized NAND layers to iterate over all pages covered + * by an MTD I/O request, which should greatly simplifies the boiler-plate + * code needed to read/write data from/to a NAND device. + */ +struct nand_io_iter { + struct nand_page_io_req req; + unsigned int oobbytes_per_page; + unsigned int dataleft; + unsigned int oobleft; +}; + +/** + * mtd_to_nanddev() - Get the NAND device attached to the MTD instance + * @mtd: MTD instance + * + * Return: the NAND device embedding @mtd. + */ +static inline struct nand_device *mtd_to_nanddev(struct mtd_info *mtd) +{ + return container_of(mtd, struct nand_device, mtd); +} + +/** + * nanddev_to_mtd() - Get the MTD device attached to a NAND device + * @nand: NAND device + * + * Return: the MTD device embedded in @nand. + */ +static inline struct mtd_info *nanddev_to_mtd(struct nand_device *nand) +{ + return &nand->mtd; +} + +/* + * nanddev_bits_per_cell() - Get the number of bits per cell + * @nand: NAND device + * + * Return: the number of bits per cell. + */ +static inline unsigned int nanddev_bits_per_cell(const struct nand_device *nand) +{ + return nand->memorg.bits_per_cell; +} + +/** + * nanddev_page_size() - Get NAND page size + * @nand: NAND device + * + * Return: the page size. + */ +static inline size_t nanddev_page_size(const struct nand_device *nand) +{ + return nand->memorg.pagesize; +} + +/** + * nanddev_per_page_oobsize() - Get NAND OOB size + * @nand: NAND device + * + * Return: the OOB size. + */ +static inline unsigned int +nanddev_per_page_oobsize(const struct nand_device *nand) +{ + return nand->memorg.oobsize; +} + +/** + * nanddev_pages_per_eraseblock() - Get the number of pages per eraseblock + * @nand: NAND device + * + * Return: the number of pages per eraseblock. + */ +static inline unsigned int +nanddev_pages_per_eraseblock(const struct nand_device *nand) +{ + return nand->memorg.pages_per_eraseblock; +} + +/** + * nanddev_per_page_oobsize() - Get NAND erase block size + * @nand: NAND device + * + * Return: the eraseblock size. + */ +static inline size_t nanddev_eraseblock_size(const struct nand_device *nand) +{ + return nand->memorg.pagesize * nand->memorg.pages_per_eraseblock; +} + +/** + * nanddev_eraseblocks_per_lun() - Get the number of eraseblocks per LUN + * @nand: NAND device + * + * Return: the number of eraseblocks per LUN. + */ +static inline unsigned int +nanddev_eraseblocks_per_lun(const struct nand_device *nand) +{ + return nand->memorg.eraseblocks_per_lun; +} + +/** + * nanddev_target_size() - Get the total size provided by a single target/die + * @nand: NAND device + * + * Return: the total size exposed by a single target/die in bytes. + */ +static inline u64 nanddev_target_size(const struct nand_device *nand) +{ + return (u64)nand->memorg.luns_per_target * + nand->memorg.eraseblocks_per_lun * + nand->memorg.pages_per_eraseblock * + nand->memorg.pagesize; +} + +/** + * nanddev_ntarget() - Get the total of targets + * @nand: NAND device + * + * Return: the number of targets/dies exposed by @nand. + */ +static inline unsigned int nanddev_ntargets(const struct nand_device *nand) +{ + return nand->memorg.ntargets; +} + +/** + * nanddev_neraseblocks() - Get the total number of erasablocks + * @nand: NAND device + * + * Return: the total number of eraseblocks exposed by @nand. + */ +static inline unsigned int nanddev_neraseblocks(const struct nand_device *nand) +{ + return (u64)nand->memorg.luns_per_target * + nand->memorg.eraseblocks_per_lun * + nand->memorg.pages_per_eraseblock; +} + +/** + * nanddev_size() - Get NAND size + * @nand: NAND device + * + * Return: the total size (in bytes) exposed by @nand. + */ +static inline u64 nanddev_size(const struct nand_device *nand) +{ + return nanddev_target_size(nand) * nanddev_ntargets(nand); +} + +/** + * nanddev_get_memorg() - Extract memory organization info from a NAND device + * @nand: NAND device + * + * This can be used by the upper layer to fill the memorg info before calling + * nanddev_init(). + * + * Return: the memorg object embedded in the NAND device. + */ +static inline struct nand_memory_organization * +nanddev_get_memorg(struct nand_device *nand) +{ + return &nand->memorg; +} + +int nanddev_init(struct nand_device *nand, const struct nand_ops *ops, + struct module *owner); +void nanddev_cleanup(struct nand_device *nand); + +/** + * nanddev_register() - Register a NAND device + * @nand: NAND device + * + * Register a NAND device. + * This function is just a wrapper around mtd_device_register() + * registering the MTD device embedded in @nand. + * + * Return: 0 in case of success, a negative error code otherwise. + */ +static inline int nanddev_register(struct nand_device *nand) +{ + return mtd_device_register(&nand->mtd, NULL, 0); +} + +/** + * nanddev_unregister() - Unregister a NAND device + * @nand: NAND device + * + * Unregister a NAND device. + * This function is just a wrapper around mtd_device_unregister() + * unregistering the MTD device embedded in @nand. + * + * Return: 0 in case of success, a negative error code otherwise. + */ +static inline int nanddev_unregister(struct nand_device *nand) +{ + return mtd_device_unregister(&nand->mtd); +} + +/** + * nanddev_set_of_node() - Attach a DT node to a NAND device + * @nand: NAND device + * @np: DT node + * + * Attach a DT node to a NAND device. + */ +static inline void nanddev_set_of_node(struct nand_device *nand, + struct device_node *np) +{ + mtd_set_of_node(&nand->mtd, np); +} + +/** + * nanddev_get_of_node() - Retrieve the DT node attached to a NAND device + * @nand: NAND device + * + * Return: the DT node attached to @nand. + */ +static inline struct device_node *nanddev_get_of_node(struct nand_device *nand) +{ + return mtd_get_of_node(&nand->mtd); +} + +/** + * nanddev_offs_to_pos() - Convert an absolute NAND offset into a NAND position + * @nand: NAND device + * @offs: absolute NAND offset (usually passed by the MTD layer) + * @pos: a NAND position object to fill in + * + * Converts @offs into a nand_pos representation. + * + * Return: the offset within the NAND page pointed by @pos. + */ +static inline unsigned int nanddev_offs_to_pos(struct nand_device *nand, + loff_t offs, + struct nand_pos *pos) +{ + unsigned int pageoffs; + u64 tmp = offs; + + pageoffs = do_div(tmp, nand->memorg.pagesize); + pos->page = do_div(tmp, nand->memorg.pages_per_eraseblock); + pos->eraseblock = do_div(tmp, nand->memorg.eraseblocks_per_lun); + pos->plane = pos->eraseblock % nand->memorg.planes_per_lun; + pos->lun = do_div(tmp, nand->memorg.luns_per_target); + pos->target = tmp; + + return pageoffs; +} + +/** + * nanddev_pos_cmp() - Compare two NAND positions + * @a: First NAND position + * @b: Second NAND position + * + * Compares two NAND positions. + * + * Return: -1 if @a < @b, 0 if @a == @b and 1 if @a > @b. + */ +static inline int nanddev_pos_cmp(const struct nand_pos *a, + const struct nand_pos *b) +{ + if (a->target != b->target) + return a->target < b->target ? -1 : 1; + + if (a->lun != b->lun) + return a->lun < b->lun ? -1 : 1; + + if (a->eraseblock != b->eraseblock) + return a->eraseblock < b->eraseblock ? -1 : 1; + + if (a->page != b->page) + return a->page < b->page ? -1 : 1; + + return 0; +} + +/** + * nanddev_pos_to_offs() - Convert a NAND position into an absolute offset + * @nand: NAND device + * @pos: the NAND position to convert + * + * Converts @pos NAND position into an absolute offset. + * + * Return: the absolute offset. Note that @pos points to the beginning of a + * page, if one wants to point to a specific offset within this page + * the returned offset has to be adjusted manually. + */ +static inline loff_t nanddev_pos_to_offs(struct nand_device *nand, + const struct nand_pos *pos) +{ + unsigned int npages; + + npages = pos->page + + ((pos->eraseblock + + (pos->lun + + (pos->target * nand->memorg.luns_per_target)) * + nand->memorg.eraseblocks_per_lun) * + nand->memorg.pages_per_eraseblock); + + return (loff_t)npages * nand->memorg.pagesize; +} + +/** + * nanddev_pos_to_row() - Extract a row address from a NAND position + * @nand: NAND device + * @pos: the position to convert + * + * Converts a NAND position into a row address that can then be passed to the + * device. + * + * Return: the row address extracted from @pos. + */ +static inline unsigned int nanddev_pos_to_row(struct nand_device *nand, + const struct nand_pos *pos) +{ + return (pos->lun << nand->rowconv.lun_addr_shift) | + (pos->eraseblock << nand->rowconv.eraseblock_addr_shift) | + pos->page; +} + +/** + * nanddev_pos_next_target() - Move a position to the next target/die + * @nand: NAND device + * @pos: the position to update + * + * Updates @pos to point to the start of the next target/die. Useful when you + * want to iterate over all targets/dies of a NAND device. + */ +static inline void nanddev_pos_next_target(struct nand_device *nand, + struct nand_pos *pos) +{ + pos->page = 0; + pos->plane = 0; + pos->eraseblock = 0; + pos->lun = 0; + pos->target++; +} + +/** + * nanddev_pos_next_lun() - Move a position to the next LUN + * @nand: NAND device + * @pos: the position to update + * + * Updates @pos to point to the start of the next LUN. Useful when you want to + * iterate over all LUNs of a NAND device. + */ +static inline void nanddev_pos_next_lun(struct nand_device *nand, + struct nand_pos *pos) +{ + if (pos->lun >= nand->memorg.luns_per_target - 1) + return nanddev_pos_next_target(nand, pos); + + pos->lun++; + pos->page = 0; + pos->plane = 0; + pos->eraseblock = 0; +} + +/** + * nanddev_pos_next_eraseblock() - Move a position to the next eraseblock + * @nand: NAND device + * @pos: the position to update + * + * Updates @pos to point to the start of the next eraseblock. Useful when you + * want to iterate over all eraseblocks of a NAND device. + */ +static inline void nanddev_pos_next_eraseblock(struct nand_device *nand, + struct nand_pos *pos) +{ + if (pos->eraseblock >= nand->memorg.eraseblocks_per_lun - 1) + return nanddev_pos_next_lun(nand, pos); + + pos->eraseblock++; + pos->page = 0; + pos->plane = pos->eraseblock % nand->memorg.planes_per_lun; +} + +/** + * nanddev_pos_next_eraseblock() - Move a position to the next page + * @nand: NAND device + * @pos: the position to update + * + * Updates @pos to point to the start of the next page. Useful when you want to + * iterate over all pages of a NAND device. + */ +static inline void nanddev_pos_next_page(struct nand_device *nand, + struct nand_pos *pos) +{ + if (pos->page >= nand->memorg.pages_per_eraseblock - 1) + return nanddev_pos_next_eraseblock(nand, pos); + + pos->page++; +} + +/** + * nand_io_iter_init - Initialize a NAND I/O iterator + * @nand: NAND device + * @offs: absolute offset + * @req: MTD request + * @iter: NAND I/O iterator + * + * Initializes a NAND iterator based on the information passed by the MTD + * layer. + */ +static inline void nanddev_io_iter_init(struct nand_device *nand, + loff_t offs, struct mtd_oob_ops *req, + struct nand_io_iter *iter) +{ + struct mtd_info *mtd = nanddev_to_mtd(nand); + + 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); + iter->dataleft = req->len; + iter->oobleft = req->ooblen; + iter->req.databuf.in = req->datbuf; + iter->req.datalen = min_t(unsigned int, + nand->memorg.pagesize - iter->req.dataoffs, + iter->dataleft); + iter->req.oobbuf.in = req->oobbuf; + iter->req.ooblen = min_t(unsigned int, + iter->oobbytes_per_page - iter->req.ooboffs, + iter->oobleft); +} + +/** + * nand_io_iter_next_page - Move to the next page + * @nand: NAND device + * @iter: NAND I/O iterator + * + * Updates the @iter to point to the next page. + */ +static inline void nanddev_io_iter_next_page(struct nand_device *nand, + struct nand_io_iter *iter) +{ + nanddev_pos_next_page(nand, &iter->req.pos); + iter->dataleft -= iter->req.datalen; + iter->req.databuf.in += iter->req.datalen; + iter->oobleft -= iter->req.ooblen; + iter->req.oobbuf.in += iter->req.ooblen; + iter->req.dataoffs = 0; + iter->req.ooboffs = 0; + iter->req.datalen = min_t(unsigned int, nand->memorg.pagesize, + iter->dataleft); + iter->req.ooblen = min_t(unsigned int, iter->oobbytes_per_page, + iter->oobleft); +} + +/** + * nand_io_iter_end - Should end iteration or not + * @nand: NAND device + * @iter: NAND I/O iterator + * + * Check whether @iter has reached the end of the NAND portion it was asked to + * iterate on or not. + * + * Return: true if @iter has reached the end of the iteration request, false + * otherwise. + */ +static inline bool nanddev_io_iter_end(struct nand_device *nand, + const struct nand_io_iter *iter) +{ + if (iter->dataleft || iter->oobleft) + return false; + + return true; +} + +/** + * nand_io_for_each_page - Iterate over all NAND pages contained in an MTD I/O + * request + * @nand: NAND device + * @start: start address to read/write from + * @req: MTD I/O request + * @iter: NAND I/O iterator + * + * Should be used for iterate over pages that are contained in an MTD request. + */ +#define nanddev_io_for_each_page(nand, start, req, iter) \ + for (nanddev_io_iter_init(nand, start, req, iter); \ + !nanddev_io_iter_end(nand, iter); \ + nanddev_io_iter_next_page(nand, iter)) + +bool nanddev_isbad(struct nand_device *nand, const struct nand_pos *pos); +bool nanddev_isreserved(struct nand_device *nand, const struct nand_pos *pos); +int nanddev_erase(struct nand_device *nand, const struct nand_pos *pos); +int nanddev_markbad(struct nand_device *nand, const struct nand_pos *pos); + +/* BBT related functions */ +enum nand_bbt_block_status { + NAND_BBT_BLOCK_STATUS_UNKNOWN, + NAND_BBT_BLOCK_GOOD, + NAND_BBT_BLOCK_WORN, + NAND_BBT_BLOCK_RESERVED, + NAND_BBT_BLOCK_FACTORY_BAD, + NAND_BBT_BLOCK_NUM_STATUS, +}; + +int nanddev_bbt_init(struct nand_device *nand); +void nanddev_bbt_cleanup(struct nand_device *nand); +int nanddev_bbt_update(struct nand_device *nand); +int nanddev_bbt_get_block_status(const struct nand_device *nand, + unsigned int entry); +int nanddev_bbt_set_block_status(struct nand_device *nand, unsigned int entry, + enum nand_bbt_block_status status); +int nanddev_bbt_markbad(struct nand_device *nand, unsigned int block); + +/** + * nanddev_bbt_pos_to_entry() - Convert a NAND position into a BBT entry + * @nand: NAND device + * @pos: the NAND position we want to get BBT entry for + * + * Return the BBT entry used to store information about the eraseblock pointed + * by @pos. + * + * Return: the BBT entry storing information about eraseblock pointed by @pos. + */ +static inline unsigned int nanddev_bbt_pos_to_entry(struct nand_device *nand, + const struct nand_pos *pos) +{ + return pos->eraseblock + + ((pos->lun + (pos->target * nand->memorg.luns_per_target)) * + nand->memorg.eraseblocks_per_lun); +} + +/** + * nanddev_bbt_is_initialized() - Check if the BBT has been initialized + * @nand: NAND device + * + * Return: true if the BBT has been initialized, false otherwise. + */ +static inline bool nanddev_bbt_is_initialized(struct nand_device *nand) +{ + return !!nand->bbt.cache; +} + +/* MTD -> NAND helper functions. */ +int nanddev_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo); + +#endif /* __LINUX_MTD_NAND_H */ diff --git a/include/linux/mtd/nand_ecc.h b/include/linux/mtd/nand_ecc.h index 4d8406c81652..8a2decf7462c 100644 --- a/include/linux/mtd/nand_ecc.h +++ b/include/linux/mtd/nand_ecc.h @@ -1,6 +1,4 @@ /* - * drivers/mtd/nand_ecc.h - * * Copyright (C) 2000-2010 Steven J. Hill <[email protected]> * David Woodhouse <[email protected]> * Thomas Gleixner <[email protected]> diff --git a/include/linux/mtd/ndfc.h b/include/linux/mtd/ndfc.h index d0558a982628..357e88b3263a 100644 --- a/include/linux/mtd/ndfc.h +++ b/include/linux/mtd/ndfc.h @@ -1,6 +1,4 @@ /* - * linux/include/linux/mtd/ndfc.h - * * Copyright (c) 2006 Thomas Gleixner <[email protected]> * * This program is free software; you can redistribute it and/or modify |