diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-28 06:40:56 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-28 06:40:56 +0400 |
commit | a17d47300b4042a3893217c0c3f2d806fe1faa3b (patch) | |
tree | 91964353354d358cbafc350421e2bddb9455c73c /drivers/mtd/nand/nand_base.c | |
parent | 04a6553f0766df3f56830c89b7da2f618b7ef0b0 (diff) | |
parent | 7bf7e370d5919112c223a269462cd0b546903829 (diff) | |
download | linux-a17d47300b4042a3893217c0c3f2d806fe1faa3b.tar.xz |
Merge branch 'for-linus-1' of git://git.infradead.org/mtd-2.6
* 'for-linus-1' of git://git.infradead.org/mtd-2.6: (49 commits)
mtd: mtdswap: fix compilation warning
mtdswap: kill strict error handling option
mtd: nand: enable software BCH ECC in nand simulator
mtd: nand: add software BCH ECC support
mtd: fix printf format warnings, mostly lack of %zd for size_t, in mtdswap
mtd: sm_rtl: check kmalloc return value
mtd: cfi: add support for AMIC flashes (e.g. A29L160AT)
lib: add shared BCH ECC library
mtd: mxc_nand: fix OOB corruption when page size > 2KiB
mtd: DaVinci: Removed header file that is not required
mtd: pxa3xx_nand: clean the keep configure code
mtd: pxa3xx_nand: mtd scan id process could be defined by driver itself
mtd: pxa3xx_nand: unify prepare command
mtd: pxa3xx_nand: discard wait_for_event,write_cmd,__readid function
mtd: pxa3xx_nand: rework irq logic
mtd: pxa3xx_nand: make scan procedure more clear
mtd: speedtest: fix integer overflow
mtd: mxc_nand: fix read past buffer end
mtd: omap3: nand: report corrected ecc errors
jffs2: remove a trailing white space in commentaries
...
Diffstat (limited to 'drivers/mtd/nand/nand_base.c')
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index a9c6ce745767..85cfc061d41c 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -42,6 +42,7 @@ #include <linux/mtd/mtd.h> #include <linux/mtd/nand.h> #include <linux/mtd/nand_ecc.h> +#include <linux/mtd/nand_bch.h> #include <linux/interrupt.h> #include <linux/bitops.h> #include <linux/leds.h> @@ -2377,7 +2378,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, return -EINVAL; } - /* Do not allow reads past end of device */ + /* Do not allow write past end of device */ if (unlikely(to >= mtd->size || ops->ooboffs + ops->ooblen > ((mtd->size >> chip->page_shift) - @@ -3248,7 +3249,7 @@ int nand_scan_tail(struct mtd_info *mtd) /* * If no default placement scheme is given, select an appropriate one */ - if (!chip->ecc.layout) { + if (!chip->ecc.layout && (chip->ecc.mode != NAND_ECC_SOFT_BCH)) { switch (mtd->oobsize) { case 8: chip->ecc.layout = &nand_oob_8; @@ -3351,6 +3352,40 @@ int nand_scan_tail(struct mtd_info *mtd) chip->ecc.bytes = 3; break; + case NAND_ECC_SOFT_BCH: + if (!mtd_nand_has_bch()) { + printk(KERN_WARNING "CONFIG_MTD_ECC_BCH not enabled\n"); + BUG(); + } + chip->ecc.calculate = nand_bch_calculate_ecc; + chip->ecc.correct = nand_bch_correct_data; + chip->ecc.read_page = nand_read_page_swecc; + chip->ecc.read_subpage = nand_read_subpage; + chip->ecc.write_page = nand_write_page_swecc; + chip->ecc.read_page_raw = nand_read_page_raw; + chip->ecc.write_page_raw = nand_write_page_raw; + chip->ecc.read_oob = nand_read_oob_std; + chip->ecc.write_oob = nand_write_oob_std; + /* + * Board driver should supply ecc.size and ecc.bytes values to + * select how many bits are correctable; see nand_bch_init() + * for details. + * Otherwise, default to 4 bits for large page devices + */ + if (!chip->ecc.size && (mtd->oobsize >= 64)) { + chip->ecc.size = 512; + chip->ecc.bytes = 7; + } + chip->ecc.priv = nand_bch_init(mtd, + chip->ecc.size, + chip->ecc.bytes, + &chip->ecc.layout); + if (!chip->ecc.priv) { + printk(KERN_WARNING "BCH ECC initialization failed!\n"); + BUG(); + } + break; + case NAND_ECC_NONE: printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. " "This is not recommended !!\n"); @@ -3501,6 +3536,9 @@ void nand_release(struct mtd_info *mtd) { struct nand_chip *chip = mtd->priv; + if (chip->ecc.mode == NAND_ECC_SOFT_BCH) + nand_bch_free((struct nand_bch_control *)chip->ecc.priv); + #ifdef CONFIG_MTD_PARTITIONS /* Deregister partitions */ del_mtd_partitions(mtd); |