diff options
Diffstat (limited to 'drivers/mtd/nand/fsmc_nand.c')
| -rw-r--r-- | drivers/mtd/nand/fsmc_nand.c | 26 |
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 | */ |
| 703 | static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | 704 | static 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); |
| 1178 | err_req_read_chnl: | 1182 | err_req_read_chnl: |
| 1179 | clk_disable(host->clk); | 1183 | clk_disable_unprepare(host->clk); |
| 1180 | err_clk_enable: | 1184 | err_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); |
