aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/fsmc_nand.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand/fsmc_nand.c')
-rw-r--r--drivers/mtd/nand/fsmc_nand.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c
index 1b8330e1155a..38d26240d8b1 100644
--- a/drivers/mtd/nand/fsmc_nand.c
+++ b/drivers/mtd/nand/fsmc_nand.c
@@ -692,6 +692,7 @@ static void fsmc_write_buf_dma(struct mtd_info *mtd, const uint8_t *buf,
692 * @mtd: mtd info structure 692 * @mtd: mtd info structure
693 * @chip: nand chip info structure 693 * @chip: nand chip info structure
694 * @buf: buffer to store read data 694 * @buf: buffer to store read data
695 * @oob_required: caller expects OOB data read to chip->oob_poi
695 * @page: page number to read 696 * @page: page number to read
696 * 697 *
697 * This routine is needed for fsmc version 8 as reading from NAND chip has to be 698 * This routine is needed for fsmc version 8 as reading from NAND chip has to be
@@ -701,7 +702,7 @@ static void fsmc_write_buf_dma(struct mtd_info *mtd, const uint8_t *buf,
701 * max of 8 bits) 702 * max of 8 bits)
702 */ 703 */
703static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, 704static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
704 uint8_t *buf, int page) 705 uint8_t *buf, int oob_required, int page)
705{ 706{
706 struct fsmc_nand_data *host = container_of(mtd, 707 struct fsmc_nand_data *host = container_of(mtd,
707 struct fsmc_nand_data, mtd); 708 struct fsmc_nand_data, mtd);
@@ -720,6 +721,7 @@ static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
720 */ 721 */
721 uint16_t ecc_oob[7]; 722 uint16_t ecc_oob[7];
722 uint8_t *oob = (uint8_t *)&ecc_oob[0]; 723 uint8_t *oob = (uint8_t *)&ecc_oob[0];
724 unsigned int max_bitflips = 0;
723 725
724 for (i = 0, s = 0; s < eccsteps; s++, i += eccbytes, p += eccsize) { 726 for (i = 0, s = 0; s < eccsteps; s++, i += eccbytes, p += eccsize) {
725 chip->cmdfunc(mtd, NAND_CMD_READ0, s * eccsize, page); 727 chip->cmdfunc(mtd, NAND_CMD_READ0, s * eccsize, page);
@@ -748,13 +750,15 @@ static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
748 chip->ecc.calculate(mtd, p, &ecc_calc[i]); 750 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
749 751
750 stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); 752 stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
751 if (stat < 0) 753 if (stat < 0) {
752 mtd->ecc_stats.failed++; 754 mtd->ecc_stats.failed++;
753 else 755 } else {
754 mtd->ecc_stats.corrected += stat; 756 mtd->ecc_stats.corrected += stat;
757 max_bitflips = max_t(unsigned int, max_bitflips, stat);
758 }
755 } 759 }
756 760
757 return 0; 761 return max_bitflips;
758} 762}
759 763
760/* 764/*
@@ -994,9 +998,9 @@ static int __init fsmc_nand_probe(struct platform_device *pdev)
994 return PTR_ERR(host->clk); 998 return PTR_ERR(host->clk);
995 } 999 }
996 1000
997 ret = clk_enable(host->clk); 1001 ret = clk_prepare_enable(host->clk);
998 if (ret) 1002 if (ret)
999 goto err_clk_enable; 1003 goto err_clk_prepare_enable;
1000 1004
1001 /* 1005 /*
1002 * This device ID is actually a common AMBA ID as used on the 1006 * This device ID is actually a common AMBA ID as used on the
@@ -1176,8 +1180,8 @@ err_req_write_chnl:
1176 if (host->mode == USE_DMA_ACCESS) 1180 if (host->mode == USE_DMA_ACCESS)
1177 dma_release_channel(host->read_dma_chan); 1181 dma_release_channel(host->read_dma_chan);
1178err_req_read_chnl: 1182err_req_read_chnl:
1179 clk_disable(host->clk); 1183 clk_disable_unprepare(host->clk);
1180err_clk_enable: 1184err_clk_prepare_enable:
1181 clk_put(host->clk); 1185 clk_put(host->clk);
1182 return ret; 1186 return ret;
1183} 1187}
@@ -1198,7 +1202,7 @@ static int fsmc_nand_remove(struct platform_device *pdev)
1198 dma_release_channel(host->write_dma_chan); 1202 dma_release_channel(host->write_dma_chan);
1199 dma_release_channel(host->read_dma_chan); 1203 dma_release_channel(host->read_dma_chan);
1200 } 1204 }
1201 clk_disable(host->clk); 1205 clk_disable_unprepare(host->clk);
1202 clk_put(host->clk); 1206 clk_put(host->clk);
1203 } 1207 }
1204 1208
@@ -1210,7 +1214,7 @@ static int fsmc_nand_suspend(struct device *dev)
1210{ 1214{
1211 struct fsmc_nand_data *host = dev_get_drvdata(dev); 1215 struct fsmc_nand_data *host = dev_get_drvdata(dev);
1212 if (host) 1216 if (host)
1213 clk_disable(host->clk); 1217 clk_disable_unprepare(host->clk);
1214 return 0; 1218 return 0;
1215} 1219}
1216 1220
@@ -1218,7 +1222,7 @@ static int fsmc_nand_resume(struct device *dev)
1218{ 1222{
1219 struct fsmc_nand_data *host = dev_get_drvdata(dev); 1223 struct fsmc_nand_data *host = dev_get_drvdata(dev);
1220 if (host) { 1224 if (host) {
1221 clk_enable(host->clk); 1225 clk_prepare_enable(host->clk);
1222 fsmc_nand_setup(host->regs_va, host->bank, 1226 fsmc_nand_setup(host->regs_va, host->bank,
1223 host->nand.options & NAND_BUSWIDTH_16, 1227 host->nand.options & NAND_BUSWIDTH_16,
1224 host->dev_timings); 1228 host->dev_timings);