aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/nand/mxc_nand.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
index 6d0fa4cd1ddf..f5fd25461a09 100644
--- a/drivers/mtd/nand/mxc_nand.c
+++ b/drivers/mtd/nand/mxc_nand.c
@@ -94,6 +94,7 @@ struct mxc_nand_host {
94 struct clk *clk; 94 struct clk *clk;
95 int clk_act; 95 int clk_act;
96 int irq; 96 int irq;
97 int eccsize;
97 98
98 wait_queue_head_t irq_waitq; 99 wait_queue_head_t irq_waitq;
99 100
@@ -342,7 +343,7 @@ static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode)
342 */ 343 */
343} 344}
344 345
345static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat, 346static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat,
346 u_char *read_ecc, u_char *calc_ecc) 347 u_char *read_ecc, u_char *calc_ecc)
347{ 348{
348 struct nand_chip *nand_chip = mtd->priv; 349 struct nand_chip *nand_chip = mtd->priv;
@@ -364,6 +365,40 @@ static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
364 return 0; 365 return 0;
365} 366}
366 367
368static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
369 u_char *read_ecc, u_char *calc_ecc)
370{
371 struct nand_chip *nand_chip = mtd->priv;
372 struct mxc_nand_host *host = nand_chip->priv;
373 u32 ecc_stat, err;
374 int no_subpages = 1;
375 int ret = 0;
376 u8 ecc_bit_mask, err_limit;
377
378 ecc_bit_mask = (host->eccsize == 4) ? 0x7 : 0xf;
379 err_limit = (host->eccsize == 4) ? 0x4 : 0x8;
380
381 no_subpages = mtd->writesize >> 9;
382
383 ecc_stat = readl(NFC_V1_V2_ECC_STATUS_RESULT);
384
385 do {
386 err = ecc_stat & ecc_bit_mask;
387 if (err > err_limit) {
388 printk(KERN_WARNING "UnCorrectable RS-ECC Error\n");
389 return -1;
390 } else {
391 ret += err;
392 }
393 ecc_stat >>= 4;
394 } while (--no_subpages);
395
396 mtd->ecc_stats.corrected += ret;
397 pr_debug("%d Symbol Correctable RS-ECC Error\n", ret);
398
399 return ret;
400}
401
367static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, 402static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
368 u_char *ecc_code) 403 u_char *ecc_code)
369{ 404{
@@ -790,7 +825,10 @@ static int __init mxcnd_probe(struct platform_device *pdev)
790 if (pdata->hw_ecc) { 825 if (pdata->hw_ecc) {
791 this->ecc.calculate = mxc_nand_calculate_ecc; 826 this->ecc.calculate = mxc_nand_calculate_ecc;
792 this->ecc.hwctl = mxc_nand_enable_hwecc; 827 this->ecc.hwctl = mxc_nand_enable_hwecc;
793 this->ecc.correct = mxc_nand_correct_data; 828 if (nfc_is_v1())
829 this->ecc.correct = mxc_nand_correct_data_v1;
830 else
831 this->ecc.correct = mxc_nand_correct_data_v2_v3;
794 this->ecc.mode = NAND_ECC_HW; 832 this->ecc.mode = NAND_ECC_HW;
795 } else { 833 } else {
796 this->ecc.mode = NAND_ECC_SOFT; 834 this->ecc.mode = NAND_ECC_SOFT;