Skip to content

Commit

Permalink
mxc_nand: fix correct_data function
Browse files Browse the repository at this point in the history
The v2 controller has a totally different mechanism to check
whether the data we read had ecc errors or not. Implement this.
The mechanism in the v2 controller happens to be identical to
the v3 controller.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
  • Loading branch information
Sascha Hauer authored and David Woodhouse committed Aug 6, 2010
1 parent 1bc9918 commit 94f77e5
Showing 1 changed file with 40 additions and 2 deletions.
42 changes: 40 additions & 2 deletions drivers/mtd/nand/mxc_nand.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ struct mxc_nand_host {
struct clk *clk;
int clk_act;
int irq;
int eccsize;

wait_queue_head_t irq_waitq;

Expand Down Expand Up @@ -342,7 +343,7 @@ static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode)
*/
}

static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat,
u_char *read_ecc, u_char *calc_ecc)
{
struct nand_chip *nand_chip = mtd->priv;
Expand All @@ -364,6 +365,40 @@ static int mxc_nand_correct_data(struct mtd_info *mtd, u_char *dat,
return 0;
}

static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat,
u_char *read_ecc, u_char *calc_ecc)
{
struct nand_chip *nand_chip = mtd->priv;
struct mxc_nand_host *host = nand_chip->priv;
u32 ecc_stat, err;
int no_subpages = 1;
int ret = 0;
u8 ecc_bit_mask, err_limit;

ecc_bit_mask = (host->eccsize == 4) ? 0x7 : 0xf;
err_limit = (host->eccsize == 4) ? 0x4 : 0x8;

no_subpages = mtd->writesize >> 9;

ecc_stat = readl(NFC_V1_V2_ECC_STATUS_RESULT);

do {
err = ecc_stat & ecc_bit_mask;
if (err > err_limit) {
printk(KERN_WARNING "UnCorrectable RS-ECC Error\n");
return -1;
} else {
ret += err;
}
ecc_stat >>= 4;
} while (--no_subpages);

mtd->ecc_stats.corrected += ret;
pr_debug("%d Symbol Correctable RS-ECC Error\n", ret);

return ret;
}

static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
u_char *ecc_code)
{
Expand Down Expand Up @@ -790,7 +825,10 @@ static int __init mxcnd_probe(struct platform_device *pdev)
if (pdata->hw_ecc) {
this->ecc.calculate = mxc_nand_calculate_ecc;
this->ecc.hwctl = mxc_nand_enable_hwecc;
this->ecc.correct = mxc_nand_correct_data;
if (nfc_is_v1())
this->ecc.correct = mxc_nand_correct_data_v1;
else
this->ecc.correct = mxc_nand_correct_data_v2_v3;
this->ecc.mode = NAND_ECC_HW;
} else {
this->ecc.mode = NAND_ECC_SOFT;
Expand Down

0 comments on commit 94f77e5

Please sign in to comment.