Driver core: platform_driver_probe(), can save codespace
[safe/jmp/linux-2.6] / drivers / mtd / nand / rtc_from4.c
index 6c97bfa..f8c4964 100644 (file)
@@ -142,8 +142,7 @@ static struct rs_control *rs_decoder;
 /*
  *      hardware specific Out Of Band information
  */
-static struct nand_oobinfo rtc_from4_nand_oobinfo = {
-       .useecc = MTD_NANDECC_AUTOPLACE,
+static struct nand_ecclayout rtc_from4_nand_oobinfo = {
        .eccbytes = 32,
        .eccpos = {
                   0, 1, 2, 3, 4, 5, 6, 7,
@@ -444,7 +443,8 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
  * note: see pages 34..37 of data sheet for details.
  *
  */
-static int rtc_from4_errstat(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page)
+static int rtc_from4_errstat(struct mtd_info *mtd, struct nand_chip *this,
+                            int state, int status, int page)
 {
        int er_stat = 0;
        int rtn, retlen;
@@ -455,39 +455,50 @@ static int rtc_from4_errstat(struct mtd_info *mtd, struct nand_chip *this, int s
        this->cmdfunc(mtd, NAND_CMD_STATUS_CLEAR, -1, -1);
 
        if (state == FL_ERASING) {
+
                for (i = 0; i < 4; i++) {
-                       if (status & 1 << (i + 1)) {
-                               this->cmdfunc(mtd, (NAND_CMD_STATUS_ERROR + i + 1), -1, -1);
-                               rtn = this->read_byte(mtd);
-                               this->cmdfunc(mtd, NAND_CMD_STATUS_RESET, -1, -1);
-                               if (!(rtn & ERR_STAT_ECC_AVAILABLE)) {
-                                       er_stat |= 1 << (i + 1);        /* err_ecc_not_avail */
-                               }
-                       }
+                       if (!(status & 1 << (i + 1)))
+                               continue;
+                       this->cmdfunc(mtd, (NAND_CMD_STATUS_ERROR + i + 1),
+                                     -1, -1);
+                       rtn = this->read_byte(mtd);
+                       this->cmdfunc(mtd, NAND_CMD_STATUS_RESET, -1, -1);
+
+                       /* err_ecc_not_avail */
+                       if (!(rtn & ERR_STAT_ECC_AVAILABLE))
+                               er_stat |= 1 << (i + 1);
                }
+
        } else if (state == FL_WRITING) {
+
+               unsigned long corrected = mtd->ecc_stats.corrected;
+
                /* single bank write logic */
                this->cmdfunc(mtd, NAND_CMD_STATUS_ERROR, -1, -1);
                rtn = this->read_byte(mtd);
                this->cmdfunc(mtd, NAND_CMD_STATUS_RESET, -1, -1);
+
                if (!(rtn & ERR_STAT_ECC_AVAILABLE)) {
-                       er_stat |= 1 << 1;      /* err_ecc_not_avail */
-               } else {
-                       len = mtd->writesize;
-                       buf = kmalloc(len, GFP_KERNEL);
-                       if (!buf) {
-                               printk(KERN_ERR "rtc_from4_errstat: Out of memory!\n");
-                               er_stat = 1;    /* if we can't check, assume failed */
-                       } else {
-                               /* recovery read */
-                               /* page read */
-                               rtn = nand_do_read_ecc(mtd, page, len, &retlen, buf, NULL, this->autooob, 1);
-                               if (rtn) {      /* if read failed or > 1-bit error corrected */
-                                       er_stat |= 1 << 1;      /* ECC read failed */
-                               }
-                               kfree(buf);
-                       }
+                       /* err_ecc_not_avail */
+                       er_stat |= 1 << 1;
+                       goto out;
                }
+
+               len = mtd->writesize;
+               buf = kmalloc(len, GFP_KERNEL);
+               if (!buf) {
+                       printk(KERN_ERR "rtc_from4_errstat: Out of memory!\n");
+                       er_stat = 1;
+                       goto out;
+               }
+
+               /* recovery read */
+               rtn = nand_do_read(mtd, page, len, &retlen, buf);
+
+               /* if read failed or > 1-bit error corrected */
+               if (rtn || (mtd->ecc_stats.corrected - corrected) > 1) {
+                       er_stat |= 1 << 1;
+               kfree(buf);
        }
 
        rtn = status;
@@ -559,11 +570,10 @@ static int __init rtc_from4_init(void)
        this->ecc.mode = NAND_ECC_HW_SYNDROME;
        this->ecc.size = 512;
        this->ecc.bytes = 8;
-       this->options |= NAND_HWECC_SYNDROME;
        /* return the status of extra status and ECC checks */
        this->errstat = rtc_from4_errstat;
        /* set the nand_oobinfo to support FPGA H/W error detection */
-       this->autooob = &rtc_from4_nand_oobinfo;
+       this->ecc.layout = &rtc_from4_nand_oobinfo;
        this->ecc.hwctl = rtc_from4_enable_hwecc;
        this->ecc.calculate = rtc_from4_calculate_ecc;
        this->ecc.correct = rtc_from4_correct_data;