diff options
65 files changed, 925 insertions, 984 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-mtd b/Documentation/ABI/testing/sysfs-class-mtd index bfd119ace6a..1399bb2da3e 100644 --- a/Documentation/ABI/testing/sysfs-class-mtd +++ b/Documentation/ABI/testing/sysfs-class-mtd @@ -104,7 +104,7 @@ Description: One of the following ASCII strings, representing the device type: - absent, ram, rom, nor, nand, dataflash, ubi, unknown + absent, ram, rom, nor, nand, mlc-nand, dataflash, ubi, unknown What: /sys/class/mtd/mtdX/writesize Date: April 2009 diff --git a/Documentation/DocBook/mtdnand.tmpl b/Documentation/DocBook/mtdnand.tmpl index a248f42a121..cd11926e07c 100644 --- a/Documentation/DocBook/mtdnand.tmpl +++ b/Documentation/DocBook/mtdnand.tmpl @@ -1222,8 +1222,6 @@ in this page</entry> #define NAND_BBT_VERSION 0x00000100 /* Create a bbt if none axists */ #define NAND_BBT_CREATE 0x00000200 -/* Search good / bad pattern through all pages of a block */ -#define NAND_BBT_SCANALLPAGES 0x00000400 /* Write bbt if neccecary */ #define NAND_BBT_WRITE 0x00001000 /* Read and write back block contents when writing bbt */ diff --git a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt index df338cb5059..5e1f31b5ff7 100644 --- a/Documentation/devicetree/bindings/mtd/gpmc-nand.txt +++ b/Documentation/devicetree/bindings/mtd/gpmc-nand.txt @@ -22,10 +22,10 @@ Optional properties: width of 8 is assumed. - ti,nand-ecc-opt: A string setting the ECC layout to use. One of: - - "sw" Software method (default) - "hw" Hardware method - "hw-romcode" gpmc hamming mode method & romcode layout + "sw" <deprecated> use "ham1" instead + "hw" <deprecated> use "ham1" instead + "hw-romcode" <deprecated> use "ham1" instead + "ham1" 1-bit Hamming ecc code "bch4" 4-bit BCH ecc code "bch8" 8-bit BCH ecc code @@ -36,8 +36,12 @@ Optional properties: "prefetch-dma" Prefetch enabled sDMA mode "prefetch-irq" Prefetch enabled irq mode - - elm_id: Specifies elm device node. This is required to support BCH - error correction using ELM module. + - elm_id: <deprecated> use "ti,elm-id" instead + - ti,elm-id: Specifies phandle of the ELM devicetree node. + ELM is an on-chip hardware engine on TI SoC which is used for + locating ECC errors for BCHx algorithms. SoC devices which have + ELM hardware engines should specify this device node in .dtsi + Using ELM for ECC error correction frees some CPU cycles. For inline partiton table parsing (optional): diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index fc20a61f6b2..ac82512b9c8 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c @@ -142,7 +142,7 @@ __init board_nand_init(struct mtd_partition *nand_parts, u8 nr_parts, u8 cs, board_nand_data.nr_parts = nr_parts; board_nand_data.devsize = nand_type; - board_nand_data.ecc_opt = OMAP_ECC_HAMMING_CODE_DEFAULT; + board_nand_data.ecc_opt = OMAP_ECC_BCH8_CODE_HW; gpmc_nand_init(&board_nand_data, gpmc_t); } #endif /* CONFIG_MTD_NAND_OMAP2 || CONFIG_MTD_NAND_OMAP2_MODULE */ diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 51525faa0ae..81de5625195 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c @@ -1341,14 +1341,6 @@ static void __maybe_unused gpmc_read_timings_dt(struct device_node *np, #ifdef CONFIG_MTD_NAND -static const char * const nand_ecc_opts[] = { - [OMAP_ECC_HAMMING_CODE_DEFAULT] = "sw", - [OMAP_ECC_HAMMING_CODE_HW] = "hw", - [OMAP_ECC_HAMMING_CODE_HW_ROMCODE] = "hw-romcode", - [OMAP_ECC_BCH4_CODE_HW] = "bch4", - [OMAP_ECC_BCH8_CODE_HW] = "bch8", -}; - static const char * const nand_xfer_types[] = { [NAND_OMAP_PREFETCH_POLLED] = "prefetch-polled", [NAND_OMAP_POLLED] = "polled", @@ -1378,13 +1370,41 @@ static int gpmc_probe_nand_child(struct platform_device *pdev, gpmc_nand_data->cs = val; gpmc_nand_data->of_node = child; - if (!of_property_read_string(child, "ti,nand-ecc-opt", &s)) - for (val = 0; val < ARRAY_SIZE(nand_ecc_opts); val++) - if (!strcasecmp(s, nand_ecc_opts[val])) { - gpmc_nand_data->ecc_opt = val; - break; - } + /* Detect availability of ELM module */ + gpmc_nand_data->elm_of_node = of_parse_phandle(child, "ti,elm-id", 0); + if (gpmc_nand_data->elm_of_node == NULL) + gpmc_nand_data->elm_of_node = + of_parse_phandle(child, "elm_id", 0); + if (gpmc_nand_data->elm_of_node == NULL) + pr_warn("%s: ti,elm-id property not found\n", __func__); + + /* select ecc-scheme for NAND */ + if (of_property_read_string(child, "ti,nand-ecc-opt", &s)) { + pr_err("%s: ti,nand-ecc-opt not found\n", __func__); + return -ENODEV; + } + if (!strcmp(s, "ham1") || !strcmp(s, "sw") || + !strcmp(s, "hw") || !strcmp(s, "hw-romcode")) + gpmc_nand_data->ecc_opt = + OMAP_ECC_HAM1_CODE_HW; + else if (!strcmp(s, "bch4")) + if (gpmc_nand_data->elm_of_node) + gpmc_nand_data->ecc_opt = + OMAP_ECC_BCH4_CODE_HW; + else + gpmc_nand_data->ecc_opt = + OMAP_ECC_BCH4_CODE_HW_DETECTION_SW; + else if (!strcmp(s, "bch8")) + if (gpmc_nand_data->elm_of_node) + gpmc_nand_data->ecc_opt = + OMAP_ECC_BCH8_CODE_HW; + else + gpmc_nand_data->ecc_opt = + OMAP_ECC_BCH8_CODE_HW_DETECTION_SW; + else + pr_err("%s: ti,nand-ecc-opt invalid value\n", __func__); + /* select data transfer mode for NAND controller */ if (!of_property_read_string(child, "ti,nand-xfer-type", &s)) for (val = 0; val < ARRAY_SIZE(nand_xfer_types); val++) if (!strcasecmp(s, nand_xfer_types[val])) { diff --git a/arch/powerpc/include/asm/fsl_ifc.h b/arch/powerpc/include/asm/fsl_ifc.h index b8a4b9bc50b..f49ddb1b227 100644 --- a/arch/powerpc/include/asm/fsl_ifc.h +++ b/arch/powerpc/include/asm/fsl_ifc.h @@ -93,6 +93,7 @@ #define CSOR_NAND_PGS_512 0x00000000 #define CSOR_NAND_PGS_2K 0x00080000 #define CSOR_NAND_PGS_4K 0x00100000 +#define CSOR_NAND_PGS_8K 0x00180000 /* Spare region Size */ #define CSOR_NAND_SPRZ_MASK 0x0000E000 #define CSOR_NAND_SPRZ_SHIFT 13 @@ -102,6 +103,7 @@ #define CSOR_NAND_SPRZ_210 0x00006000 #define CSOR_NAND_SPRZ_218 0x00008000 #define CSOR_NAND_SPRZ_224 0x0000A000 +#define CSOR_NAND_SPRZ_CSOR_EXT 0x0000C000 /* Pages Per Block */ #define CSOR_NAND_PB_MASK 0x00000700 #define CSOR_NAND_PB_SHIFT 8 diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c index 9279a9174f8..7a6384b0962 100644 --- a/drivers/mtd/bcm47xxpart.c +++ b/drivers/mtd/bcm47xxpart.c @@ -27,11 +27,13 @@ /* Magics */ #define BOARD_DATA_MAGIC 0x5246504D /* MPFR */ +#define FACTORY_MAGIC 0x59544346 /* FCTY */ #define POT_MAGIC1 0x54544f50 /* POTT */ #define POT_MAGIC2 0x504f /* OP */ #define ML_MAGIC1 0x39685a42 #define ML_MAGIC2 0x26594131 #define TRX_MAGIC 0x30524448 +#define SQSH_MAGIC 0x71736873 /* shsq */ struct trx_header { uint32_t magic; @@ -71,7 +73,14 @@ static int bcm47xxpart_parse(struct mtd_info *master, /* Alloc */ parts = kzalloc(sizeof(struct mtd_partition) * BCM47XXPART_MAX_PARTS, GFP_KERNEL); + if (!parts) + return -ENOMEM; + buf = kzalloc(BCM47XXPART_BYTES_TO_READ, GFP_KERNEL); + if (!buf) { + kfree(parts); + return -ENOMEM; + } /* Parse block by block looking for magics */ for (offset = 0; offset <= master->size - blocksize; @@ -110,6 +119,13 @@ static int bcm47xxpart_parse(struct mtd_info *master, continue; } + /* Found on Huawei E970 */ + if (buf[0x000 / 4] == FACTORY_MAGIC) { + bcm47xxpart_add_part(&parts[curr_part++], "factory", + offset, MTD_WRITEABLE); + continue; + } + /* POT(TOP) */ if (buf[0x000 / 4] == POT_MAGIC1 && (buf[0x004 / 4] & 0xFFFF) == POT_MAGIC2) { @@ -167,6 +183,13 @@ static int bcm47xxpart_parse(struct mtd_info *master, offset = rounddown(offset + trx->length, blocksize); continue; } + + /* Squashfs on devices not using TRX */ + if (buf[0x000 / 4] == SQSH_MAGIC) { + bcm47xxpart_add_part(&parts[curr_part++], "rootfs", + offset, 0); + continue; + } } /* Look for NVRAM at the end of the last block. */ diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig index 74ab4b7e523..01281382180 100644 --- a/drivers/mtd/devices/Kconfig +++ b/drivers/mtd/devices/Kconfig @@ -95,13 +95,6 @@ config MTD_M25P80 if you want to specify device partitioning or to use a device which doesn't support the JEDEC ID instruction. -config M25PXX_USE_FAST_READ - bool "Use FAST_READ OPCode allowing SPI CLK >= 50MHz" - depends on MTD_M25P80 - default y - help - This option enables FAST_READ access supported by ST M25Pxx. - config MTD_SPEAR_SMI tristate "SPEAR MTD NOR Support through SMI controller" depends on PLAT_SPEAR diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index 5cb4c04726b..d9fd87a4c8d 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -20,6 +20,7 @@ #include <linux/mutex.h> #include <linux/mount.h> #include <linux/slab.h> +#include <linux/major.h> /* Info for the block device */ struct block2mtd_dev { diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index 3e1b0a0ef4d..4f091c1a998 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c @@ -2097,7 +2097,7 @@ notfound: ret = -ENODEV; dev_info(dev, "No supported DiskOnChip found\n"); err_probe: - kfree(cascade->bch); + free_bch(cascade->bch); for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) if (cascade->floors[floor]) doc_release_device(cascade->floors[floor]); diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 6bc9618af09..7eda71dbc18 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -78,7 +78,7 @@ /* Define max times to check status register before we give up. */ #define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */ -#define MAX_CMD_SIZE 5 +#define MAX_CMD_SIZE 6 #define JEDEC_MFR(_jedec_id) ((_jedec_id) >> 16) @@ -367,10 +367,6 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, spi_message_init(&m); memset(t, 0, (sizeof t)); - /* NOTE: - * OPCODE_FAST_READ (if available) is faster. - * Should add 1 byte DUMMY_BYTE. - */ t[0].tx_buf = flash->command; t[0].len = m25p_cmdsz(flash) + (flash->fast_read ? 1 : 0); spi_message_add_tail(&t[0], &m); @@ -388,11 +384,6 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, return 1; } - /* FIXME switch to OPCODE_FAST_READ. It's required for higher - * clocks; and at this writing, every chip this driver handles - * supports that opcode. - */ - /* Set up the write data buffer. */ opcode = flash->read_opcode; flash->command[0] = opcode; @@ -749,16 +740,19 @@ static const struct spi_device_id m25p_ids[] = { { "at45db081d", INFO(0x1f2500, 0, 64 * 1024, 16, SECT_4K) }, /* EON -- en25xxx */ - { "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64, SECT_4K) }, - { "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) }, - { "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, 0) }, - { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) }, - { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) }, - { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) }, + { "en25f32", INFO(0x1c3116, 0, 64 * 1024, 64, SECT_4K) }, + { "en25p32", INFO(0x1c2016, 0, 64 * 1024, 64, 0) }, + { "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, 0) }, + { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) }, + { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) }, + { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) }, + + /* ESMT */ + { "f25l32pa", INFO(0x8c2016, 0, 64 * 1024, 64, SECT_4K) }, /* Everspin */ - { "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, M25P_NO_ERASE | M25P_NO_FR) }, - { "mr25h10", CAT25_INFO(128 * 1024, 1, 256, 3, M25P_NO_ERASE | M25P_NO_FR) }, + { "mr25h256", CAT25_INFO( 32 * 1024, 1, 256, 2, M25P_NO_ERASE | M25P_NO_FR) }, + { "mr25h10", CAT25_INFO(128 * 1024, 1, 256, 3, M25P_NO_ERASE | M25P_NO_FR) }, /* GigaDevice */ { "gd25q32", INFO(0xc84016, 0, 64 * 1024, 64, SECT_4K) }, @@ -775,6 +769,7 @@ static const struct spi_device_id m25p_ids[] = { { "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16, 0) }, { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, SECT_4K) }, { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, 0) }, + { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) }, { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, 0) }, { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, @@ -783,15 +778,16 @@ static const struct spi_device_id m25p_ids[] = { { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, 0) }, /* Micron */ - { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, 0) }, - { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, 0) }, - { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, 0) }, - { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) }, + { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, 0) }, + { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, 0) }, + { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, 0) }, + { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) }, + { "n25q512a", INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K) }, /* PMC */ - { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) }, - { "pm25lv010", INFO(0, 0, 32 * 1024, 4, SECT_4K_PMC) }, - { "pm25lq032", INFO(0x7f9d46, 0, 64 * 1024, 64, SECT_4K) }, + { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) }, + { "pm25lv010", INFO(0, 0, 32 * 1024, 4, SECT_4K_PMC) }, + { "pm25lq032", INFO(0x7f9d46, 0, 64 * 1024, 64, SECT_4K) }, /* Spansion -- single (large) sector size only, at least * for the chips listed here (without boot sectors). @@ -940,12 +936,7 @@ static int m25p_probe(struct spi_device *spi) struct flash_info *info; unsigned i; struct mtd_part_parser_data ppdata; - struct device_node __maybe_unused *np = spi->dev.of_node; - -#ifdef CONFIG_MTD_OF_PARTS - if (!of_device_is_available(np)) - return -ENODEV; -#endif + struct device_node *np = spi->dev.of_node; /* Platform data helps sort out which chip type we have, as * well as how this board partitions it. If we don't have @@ -992,15 +983,13 @@ static int m25p_probe(struct spi_device *spi) } } - flash = kzalloc(sizeof *flash, GFP_KERNEL); + flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL); if (!flash) return -ENOMEM; - flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 : 0), - GFP_KERNEL); - if (!flash->command) { - kfree(flash); + + flash->command = devm_kzalloc(&spi->dev, MAX_CMD_SIZE, GFP_KERNEL); + if (!flash->command) return -ENOMEM; - } flash->spi = spi; mutex_init(&flash->lock); @@ -1062,13 +1051,14 @@ static int m25p_probe(struct spi_device *spi) flash->page_size = info->page_size; flash->mtd.writebufsize = flash->page_size; - flash->fast_read = false; - if (np && of_property_read_bool(np, "m25p,fast-read")) + if (np) + /* If we were instantiated by DT, use it */ + flash->fast_read = of_property_read_bool(np, "m25p,fast-read"); + else + /* If we weren't instantiated by DT, default to fast-read */ flash->fast_read = true; -#ifdef CONFIG_M25PXX_USE_FAST_READ - flash->fast_read = true; -#endif + /* Some devices cannot do fast-read, no matter what DT tells us */ if (info->flags & M25P_NO_FR) flash->fast_read = false; @@ -1133,15 +1123,9 @@ static int m25p_probe(struct spi_device *spi) static int m25p_remove(struct spi_device *spi) { struct m25p *flash = spi_get_drvdata(spi); - int status; /* Clean up MTD stuff. */ - status = mtd_device_unregister(&flash->mtd); - if (status == 0) { - kfree(flash->command); - kfree(flash); - } - return 0; + return mtd_device_unregister(&flash->mtd); } diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index 0e8cbfeba11..4a47b0266d4 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c @@ -88,8 +88,6 @@ struct dataflash { uint8_t command[4]; char name[24]; - unsigned partitioned:1; - unsigned short page_offset; /* offset in flash address */ unsigned int page_size; /* of bytes per page */ @@ -881,7 +879,7 @@ static int dataflash_probe(struct spi_device *spi) break; /* obsolete AT45DB1282 not (yet?) supported */ default: - pr_debug("%s: unsupported device (%x)\n", dev_name(&spi->dev), + dev_info(&spi->dev, "unsupported device (%x)\n", status & 0x3c); status = -ENODEV; } diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index 67823de68db..e1f2aebaa48 100644 --- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c @@ -94,7 +94,7 @@ static void unregister_devices(void) } } -static int register_device(char *name, unsigned long start, unsigned long len) +static int register_device(char *name, phys_addr_t start, size_t len) { struct phram_mtd_list *new; int ret = -ENOMEM; @@ -141,35 +141,35 @@ out0: return ret; } -static int ustrtoul(const char *cp, char **endp, unsigned int base) +static int parse_num64(uint64_t *num64, char *token) { - unsigned long result = simple_strtoul(cp, endp, base); - - switch (**endp) { - case 'G': - result *= 1024; - case 'M': - result *= 1024; - case 'k': - result *= 1024; + size_t len; + int shift = 0; + int ret; + + len = strlen(token); /* By dwmw2 editorial decree, "ki", "Mi" or "Gi" are to be used. */ - if ((*endp)[1] == 'i') - (*endp) += 2; + if (len > 2) { + if (token[len - 1] == 'i') { + switch (token[len - 2]) { + case 'G': + shift += 10; + case 'M': + shift += 10; + case 'k': + shift += 10; + token[len - 2] = 0; + break; + default: + return -EINVAL; + } + } } - return result; -} -static int parse_num32(uint32_t *num32, const char *token) -{ - char *endp; - unsigned long n; + ret = kstrtou64(token, 0, num64); + *num64 <<= shift; - n = ustrtoul(token, &endp, 0); - if (*endp) - return -EINVAL; - - *num32 = n; - return 0; + return ret; } static int parse_name(char **pname, const char *token) @@ -209,19 +209,19 @@ static inline void kill_final_newline(char *str) * This shall contain the module parameter if any. It is of the form: * - phram=<device>,<address>,<size> for module case * - phram.phram=<device>,<address>,<size> for built-in case - * We leave 64 bytes for the device name, 12 for the address and 12 for the + * We leave 64 bytes for the device name, 20 for the address and 20 for the * size. * Example: phram.phram=rootfs,0xa0000000,512Mi */ -static __initdata char phram_paramline[64+12+12]; +static __initdata char phram_paramline[64 + 20 + 20]; static int __init phram_setup(const char *val) { - char buf[6 |