aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/atmel_nand.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand/atmel_nand.c')
-rw-r--r--drivers/mtd/nand/atmel_nand.c28
1 files changed, 17 insertions, 11 deletions
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c
index 92623ac2015a..90bdca61c797 100644
--- a/drivers/mtd/nand/atmel_nand.c
+++ b/drivers/mtd/nand/atmel_nand.c
@@ -331,13 +331,13 @@ static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len)
331 * 12-bits 20-bytes 21-bytes 331 * 12-bits 20-bytes 21-bytes
332 * 24-bits 39-bytes 42-bytes 332 * 24-bits 39-bytes 42-bytes
333 */ 333 */
334static int __devinit pmecc_get_ecc_bytes(int cap, int sector_size) 334static int pmecc_get_ecc_bytes(int cap, int sector_size)
335{ 335{
336 int m = 12 + sector_size / 512; 336 int m = 12 + sector_size / 512;
337 return (m * cap + 7) / 8; 337 return (m * cap + 7) / 8;
338} 338}
339 339
340static void __devinit pmecc_config_ecc_layout(struct nand_ecclayout *layout, 340static void pmecc_config_ecc_layout(struct nand_ecclayout *layout,
341 int oobsize, int ecc_len) 341 int oobsize, int ecc_len)
342{ 342{
343 int i; 343 int i;
@@ -353,7 +353,7 @@ static void __devinit pmecc_config_ecc_layout(struct nand_ecclayout *layout,
353 oobsize - ecc_len - layout->oobfree[0].offset; 353 oobsize - ecc_len - layout->oobfree[0].offset;
354} 354}
355 355
356static void __devinit __iomem *pmecc_get_alpha_to(struct atmel_nand_host *host) 356static void __iomem *pmecc_get_alpha_to(struct atmel_nand_host *host)
357{ 357{
358 int table_size; 358 int table_size;
359 359
@@ -375,7 +375,7 @@ static void pmecc_data_free(struct atmel_nand_host *host)
375 kfree(host->pmecc_delta); 375 kfree(host->pmecc_delta);
376} 376}
377 377
378static int __devinit pmecc_data_alloc(struct atmel_nand_host *host) 378static int pmecc_data_alloc(struct atmel_nand_host *host)
379{ 379{
380 const int cap = host->pmecc_corr_cap; 380 const int cap = host->pmecc_corr_cap;
381 381
@@ -724,6 +724,7 @@ static int pmecc_correction(struct mtd_info *mtd, u32 pmecc_stat, uint8_t *buf,
724 struct atmel_nand_host *host = nand_chip->priv; 724 struct atmel_nand_host *host = nand_chip->priv;
725 int i, err_nbr, eccbytes; 725 int i, err_nbr, eccbytes;
726 uint8_t *buf_pos; 726 uint8_t *buf_pos;
727 int total_err = 0;
727 728
728 eccbytes = nand_chip->ecc.bytes; 729 eccbytes = nand_chip->ecc.bytes;
729 for (i = 0; i < eccbytes; i++) 730 for (i = 0; i < eccbytes; i++)
@@ -751,12 +752,13 @@ normal_check:
751 pmecc_correct_data(mtd, buf_pos, ecc, i, 752 pmecc_correct_data(mtd, buf_pos, ecc, i,
752 host->pmecc_bytes_per_sector, err_nbr); 753 host->pmecc_bytes_per_sector, err_nbr);
753 mtd->ecc_stats.corrected += err_nbr; 754 mtd->ecc_stats.corrected += err_nbr;
755 total_err += err_nbr;
754 } 756 }
755 } 757 }
756 pmecc_stat >>= 1; 758 pmecc_stat >>= 1;
757 } 759 }
758 760
759 return 0; 761 return total_err;
760} 762}
761 763
762static int atmel_nand_pmecc_read_page(struct mtd_info *mtd, 764static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
@@ -768,6 +770,7 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
768 uint32_t *eccpos = chip->ecc.layout->eccpos; 770 uint32_t *eccpos = chip->ecc.layout->eccpos;
769 uint32_t stat; 771 uint32_t stat;
770 unsigned long end_time; 772 unsigned long end_time;
773 int bitflips = 0;
771 774
772 pmecc_writel(host->ecc, CTRL, PMECC_CTRL_RST); 775 pmecc_writel(host->ecc, CTRL, PMECC_CTRL_RST);
773 pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE); 776 pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE);
@@ -790,11 +793,14 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd,
790 } 793 }
791 794
792 stat = pmecc_readl_relaxed(host->ecc, ISR); 795 stat = pmecc_readl_relaxed(host->ecc, ISR);
793 if (stat != 0) 796 if (stat != 0) {
794 if (pmecc_correction(mtd, stat, buf, &oob[eccpos[0]]) != 0) 797 bitflips = pmecc_correction(mtd, stat, buf, &oob[eccpos[0]]);
795 return -EIO; 798 if (bitflips < 0)
799 /* uncorrectable errors */
800 return 0;
801 }
796 802
797 return 0; 803 return bitflips;
798} 804}
799 805
800static int atmel_nand_pmecc_write_page(struct mtd_info *mtd, 806static int atmel_nand_pmecc_write_page(struct mtd_info *mtd,
@@ -1206,7 +1212,7 @@ static void atmel_nand_hwctl(struct mtd_info *mtd, int mode)
1206} 1212}
1207 1213
1208#if defined(CONFIG_OF) 1214#if defined(CONFIG_OF)
1209static int __devinit atmel_of_init_port(struct atmel_nand_host *host, 1215static int atmel_of_init_port(struct atmel_nand_host *host,
1210 struct device_node *np) 1216 struct device_node *np)
1211{ 1217{
1212 u32 val, table_offset; 1218 u32 val, table_offset;
@@ -1293,7 +1299,7 @@ static int __devinit atmel_of_init_port(struct atmel_nand_host *host,
1293 return 0; 1299 return 0;
1294} 1300}
1295#else 1301#else
1296static int __devinit atmel_of_init_port(struct atmel_nand_host *host, 1302static int atmel_of_init_port(struct atmel_nand_host *host,
1297 struct device_node *np) 1303 struct device_node *np)
1298{ 1304{
1299 return -EINVAL; 1305 return -EINVAL;