diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-26 20:30:56 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-26 20:30:56 -0700 |
commit | 9ee08c2df47c10ba624ff05a6c0f2500748bcb69 (patch) | |
tree | 0a2788abb3b5547b83965e0b3132eec8b196bd81 /drivers/mtd/nand/fsl_elbc_nand.c | |
parent | eaf0ba5ef69538b6913525294a3a0fcb0e0992e0 (diff) | |
parent | 3d45955962496879dead8d4dd70bb9a23b07154b (diff) |
Merge git://git.infradead.org/mtd-2.6
* git://git.infradead.org/mtd-2.6: (57 commits)
[MTD] [NAND] subpage read feature as a way to increase performance.
CPUFREQ: S3C24XX NAND driver frequency scaling support.
[MTD][NAND] au1550nd: remove unused variable
[MTD] jedec_probe: Fix SST 16-bit chip detection
[MTD][MTDPART] Fix a division by zero bug
[MTD][MTDPART] Cleanup and document the erase region handling
[MTD][MTDPART] Handle most checkpatch findings
[MTD][MTDPART] Seperate main loop from per-partition code in add_mtd_partition
[MTD] physmap: resume already suspended chips on failure to suspend
[MTD] physmap: Fix suspend/resume/shutdown bugs.
[MTD] [NOR] Fix -ETIMEO errors in CFI driver
[MTD] [NAND] fsl_elbc_nand: fix section mismatch with CONFIG_MTD_OF_PARTS=y
[JFFS2] Use .unlocked_ioctl
[MTD] Fix const assignment in the MTD command line partitioning driver
[MTD] [NOR] gen_probe: No debug message when debugging is disabled
[MTD] [NAND] remove __PPC__ hardcoded address from DiskOnChip drivers
[MTD] [MAPS] Remove the bast-flash driver.
[MTD] [NAND] fsl_elbc_nand: ecclayout cleanups
[MTD] [NAND] fsl_elbc_nand: implement support for flash-based BBT
[MTD] [NAND] fsl_elbc_nand: fix OOB workability for large page NAND chips
...
Diffstat (limited to 'drivers/mtd/nand/fsl_elbc_nand.c')
-rw-r--r-- | drivers/mtd/nand/fsl_elbc_nand.c | 63 |
1 files changed, 52 insertions, 11 deletions
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 4b69aacdf5c..9dff51351f4 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -89,7 +89,6 @@ static struct nand_ecclayout fsl_elbc_oob_sp_eccm0 = { .eccbytes = 3, .eccpos = {6, 7, 8}, .oobfree = { {0, 5}, {9, 7} }, - .oobavail = 12, }; /* Small Page FLASH with FMR[ECCM] = 1 */ @@ -97,7 +96,6 @@ static struct nand_ecclayout fsl_elbc_oob_sp_eccm1 = { .eccbytes = 3, .eccpos = {8, 9, 10}, .oobfree = { {0, 5}, {6, 2}, {11, 5} }, - .oobavail = 12, }; /* Large Page FLASH with FMR[ECCM] = 0 */ @@ -105,7 +103,6 @@ static struct nand_ecclayout fsl_elbc_oob_lp_eccm0 = { .eccbytes = 12, .eccpos = {6, 7, 8, 22, 23, 24, 38, 39, 40, 54, 55, 56}, .oobfree = { {1, 5}, {9, 13}, {25, 13}, {41, 13}, {57, 7} }, - .oobavail = 48, }; /* Large Page FLASH with FMR[ECCM] = 1 */ @@ -113,7 +110,48 @@ static struct nand_ecclayout fsl_elbc_oob_lp_eccm1 = { .eccbytes = 12, .eccpos = {8, 9, 10, 24, 25, 26, 40, 41, 42, 56, 57, 58}, .oobfree = { {1, 7}, {11, 13}, {27, 13}, {43, 13}, {59, 5} }, - .oobavail = 48, +}; + +/* + * fsl_elbc_oob_lp_eccm* specify that LP NAND's OOB free area starts at offset + * 1, so we have to adjust bad block pattern. This pattern should be used for + * x8 chips only. So far hardware does not support x16 chips anyway. + */ +static u8 scan_ff_pattern[] = { 0xff, }; + +static struct nand_bbt_descr largepage_memorybased = { + .options = 0, + .offs = 0, + .len = 1, + .pattern = scan_ff_pattern, +}; + +/* + * ELBC may use HW ECC, so that OOB offsets, that NAND core uses for bbt, + * interfere with ECC positions, that's why we implement our own descriptors. + * OOB {11, 5}, works for both SP and LP chips, with ECCM = 1 and ECCM = 0. + */ +static u8 bbt_pattern[] = {'B', 'b', 't', '0' }; +static u8 mirror_pattern[] = {'1', 't', 'b', 'B' }; + +static struct nand_bbt_descr bbt_main_descr = { + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | + NAND_BBT_2BIT | NAND_BBT_VERSION, + .offs = 11, + .len = 4, + .veroffs = 15, + .maxblocks = 4, + .pattern = bbt_pattern, +}; + +static struct nand_bbt_descr bbt_mirror_descr = { + .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | + NAND_BBT_2BIT | NAND_BBT_VERSION, + .offs = 11, + .len = 4, + .veroffs = 15, + .maxblocks = 4, + .pattern = mirror_pattern, }; /*=================================*/ @@ -687,8 +725,7 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) chip->ecc.layout = (priv->fmr & FMR_ECCM) ? &fsl_elbc_oob_lp_eccm1 : &fsl_elbc_oob_lp_eccm0; - mtd->ecclayout = chip->ecc.layout; - mtd->oobavail = chip->ecc.layout->oobavail; + chip->badblock_pattern = &largepage_memorybased; } } else { dev_err(ctrl->dev, @@ -752,8 +789,12 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv) chip->cmdfunc = fsl_elbc_cmdfunc; chip->waitfunc = fsl_elbc_wait; + chip->bbt_td = &bbt_main_descr; + chip->bbt_md = &bbt_mirror_descr; + /* set up nand options */ - chip->options = NAND_NO_READRDY | NAND_NO_AUTOINCR; + chip->options = NAND_NO_READRDY | NAND_NO_AUTOINCR | + NAND_USE_FLASH_BBT; chip->controller = &ctrl->controller; chip->priv = priv; @@ -795,8 +836,8 @@ static int fsl_elbc_chip_remove(struct fsl_elbc_mtd *priv) return 0; } -static int fsl_elbc_chip_probe(struct fsl_elbc_ctrl *ctrl, - struct device_node *node) +static int __devinit fsl_elbc_chip_probe(struct fsl_elbc_ctrl *ctrl, + struct device_node *node) { struct fsl_lbc_regs __iomem *lbc = ctrl->regs; struct fsl_elbc_mtd *priv; @@ -917,7 +958,7 @@ static int __devinit fsl_elbc_ctrl_init(struct fsl_elbc_ctrl *ctrl) return 0; } -static int __devexit fsl_elbc_ctrl_remove(struct of_device *ofdev) +static int fsl_elbc_ctrl_remove(struct of_device *ofdev) { struct fsl_elbc_ctrl *ctrl = dev_get_drvdata(&ofdev->dev); int i; @@ -1041,7 +1082,7 @@ static struct of_platform_driver fsl_elbc_ctrl_driver = { }, .match_table = fsl_elbc_match, .probe = fsl_elbc_ctrl_probe, - .remove = __devexit_p(fsl_elbc_ctrl_remove), + .remove = fsl_elbc_ctrl_remove, }; static int __init fsl_elbc_init(void) |