diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-13 11:25:54 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-13 11:25:54 -0800 |
commit | ac53b2e053fffc74372da94e734b92f37e70d32c (patch) | |
tree | cda82af0fcded5d230e9f56104d3988b7a75c8aa /drivers/mtd/mtdcore.c | |
parent | cf09112d160e6db21ff8427ce696f819b957423b (diff) | |
parent | 9146cbd52b11d4ade62dba8f238ec5e421c3fa2b (diff) |
Merge tag 'for-linus-20160112' of git://git.infradead.org/linux-mtd
Pull MTD updates from Brian Norris:
"Generic MTD:
- populate the MTD device 'of_node' field (and get a proper 'of_node'
symlink in sysfs)
This yielded some new helper functions, and changes across a
variety of drivers
- partitioning cleanups, to prepare for better device-tree based
partitioning in the future
Eliminate a lot of boilerplate for drivers that want to use
OF-based partition parsing
The DT bindings for this didn't settle yet, so most non-cleanup
portions are deferred for a future release
NAND:
- embed a struct mtd_info inside struct nand_chip
This is really long overdue; too many drivers have to do the same
silly boilerplate to allocate and link up two "independent"
structs, when in fact, everyone is assuming there is an exact 1:1
relationship between a NAND chips struct and its underlying MTD.
This aids improved helpers and should make certain abstractions
easier in the future.
Also causes a lot of churn, helped along by some automated code
transformations
- add more core support for detecting (and "correcting") bitflips in
erased pages; requires opt-in by drivers, but at least we kill a
few bad implementations and hopefully stave off future ones
- pxa3xx_nand: cleanups, a few fixes, and PM improvements
- new JZ4780 NAND driver
SPI NOR:
- provide default erase function, for controllers that just want to
send the SECTOR_ERASE command directly
- fix some module auto-loading issues with device tree
("jedec,spi-nor")
- error handling fixes
- new Mediatek QSPI flash driver
Other:
- cfi: force valid geometry Kconfig (finally!)
This one used to trip up randconfigs occasionally, since bots
aren't deterred by big scary "advanced configuration" menus
More? Probably. See the commit logs"
* tag 'for-linus-20160112' of git://git.infradead.org/linux-mtd: (168 commits)
mtd: jz4780_nand: replace if/else blocks with switch/case
mtd: nand: jz4780: Update ecc correction error codes
mtd: nandsim: use nand_get_controller_data()
mtd: jz4780_nand: remove useless mtd->priv = chip assignment
staging: mt29f_spinand: make use of nand_set/get_controller_data() helpers
mtd: nand: make use of nand_set/get_controller_data() helpers
ARM: make use of nand_set/get_controller_data() helpers
mtd: nand: add helpers to access ->priv
mtd: nand: jz4780: driver for NAND devices on JZ4780 SoCs
mtd: nand: jz4740: remove custom 'erased check' implementation
mtd: nand: diskonchip: remove custom 'erased check' implementation
mtd: nand: davinci: remove custom 'erased check' implementation
mtd: nand: use nand_check_erased_ecc_chunk in default ECC read functions
mtd: nand: return consistent error codes in ecc.correct() implementations
doc: dt: mtd: new binding for jz4780-{nand,bch}
mtd: cfi_cmdset_0001: fixing memory leak and handling failed kmalloc
mtd: spi-nor: wait until lock/unlock operations are ready
mtd: tests: consolidate kmalloc/memset 0 call to kzalloc
jffs2: use to_delayed_work
mtd: nand: assign reasonable default name for NAND drivers
...
Diffstat (limited to 'drivers/mtd/mtdcore.c')
-rw-r--r-- | drivers/mtd/mtdcore.c | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index ffa288474820..309625130b21 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -32,6 +32,7 @@ #include <linux/err.h> #include <linux/ioctl.h> #include <linux/init.h> +#include <linux/of.h> #include <linux/proc_fs.h> #include <linux/idr.h> #include <linux/backing-dev.h> @@ -445,6 +446,7 @@ int add_mtd_device(struct mtd_info *mtd) mtd->dev.devt = MTD_DEVT(i); dev_set_name(&mtd->dev, "mtd%d", i); dev_set_drvdata(&mtd->dev, mtd); + of_node_get(mtd_get_of_node(mtd)); error = device_register(&mtd->dev); if (error) goto fail_added; @@ -467,6 +469,7 @@ int add_mtd_device(struct mtd_info *mtd) return 0; fail_added: + of_node_put(mtd_get_of_node(mtd)); idr_remove(&mtd_idr, i); fail_locked: mutex_unlock(&mtd_table_mutex); @@ -508,6 +511,7 @@ int del_mtd_device(struct mtd_info *mtd) device_unregister(&mtd->dev); idr_remove(&mtd_idr, mtd->index); + of_node_put(mtd_get_of_node(mtd)); module_put(THIS_MODULE); ret = 0; @@ -519,9 +523,10 @@ out_error: } static int mtd_add_device_partitions(struct mtd_info *mtd, - struct mtd_partition *real_parts, - int nbparts) + struct mtd_partitions *parts) { + const struct mtd_partition *real_parts = parts->parts; + int nbparts = parts->nr_parts; int ret; if (nbparts == 0 || IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) { @@ -590,29 +595,29 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, const struct mtd_partition *parts, int nr_parts) { + struct mtd_partitions parsed; int ret; - struct mtd_partition *real_parts = NULL; mtd_set_dev_defaults(mtd); - ret = parse_mtd_partitions(mtd, types, &real_parts, parser_data); - if (ret <= 0 && nr_parts && parts) { - real_parts = kmemdup(parts, sizeof(*parts) * nr_parts, - GFP_KERNEL); - if (!real_parts) - ret = -ENOMEM; - else - ret = nr_parts; - } - /* Didn't come up with either parsed OR fallback partitions */ - if (ret < 0) { + memset(&parsed, 0, sizeof(parsed)); + + ret = parse_mtd_partitions(mtd, types, &parsed, parser_data); + if ((ret < 0 || parsed.nr_parts == 0) && parts && nr_parts) { + /* Fall back to driver-provided partitions */ + parsed = (struct mtd_partitions){ + .parts = parts, + .nr_parts = nr_parts, + }; + } else if (ret < 0) { + /* Didn't come up with parsed OR fallback partitions */ pr_info("mtd: failed to find partitions; one or more parsers reports errors (%d)\n", ret); /* Don't abort on errors; we can still use unpartitioned MTD */ - ret = 0; + memset(&parsed, 0, sizeof(parsed)); } - ret = mtd_add_device_partitions(mtd, real_parts, ret); + ret = mtd_add_device_partitions(mtd, &parsed); if (ret) goto out; @@ -632,7 +637,8 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, } out: - kfree(real_parts); + /* Cleanup any parsed partitions */ + mtd_part_parser_cleanup(&parsed); return ret; } EXPORT_SYMBOL_GPL(mtd_device_parse_register); |