aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd
diff options
context:
space:
mode:
authorZach Sadecki <zsadecki@itwatchdogs.com>2012-12-13 21:36:29 -0500
committerArtem Bityutskiy <artem.bityutskiy@linux.intel.com>2013-02-04 02:26:28 -0500
commitb23b746cdcb0792b1268bc338acf29ec27739527 (patch)
treee8cf39524350843987c9dae82d1f7db8c2d7ac1e /drivers/mtd
parente830342ef389b46160f223e6882b1e85bd7de708 (diff)
mtd: gpmi: Always report ECC stats and return max_bitflips
Always report corrected and failed ECC stats back up to the MTD layer. Also return max_bitflips from read_page() as is expected from NAND drivers now. Signed-off-by: Zach Sadecki <zsadecki@itwatchdogs.com> Acked-by: Huang Shijie <b32955@freescale.com> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.c27
1 files changed, 8 insertions, 19 deletions
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index e9b1c47e3cf9..631564d0bd46 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -920,8 +920,7 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
920 dma_addr_t auxiliary_phys; 920 dma_addr_t auxiliary_phys;
921 unsigned int i; 921 unsigned int i;
922 unsigned char *status; 922 unsigned char *status;
923 unsigned int failed; 923 unsigned int max_bitflips = 0;
924 unsigned int corrected;
925 int ret; 924 int ret;
926 925
927 pr_debug("page number is : %d\n", page); 926 pr_debug("page number is : %d\n", page);
@@ -945,35 +944,25 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
945 payload_virt, payload_phys); 944 payload_virt, payload_phys);
946 if (ret) { 945 if (ret) {
947 pr_err("Error in ECC-based read: %d\n", ret); 946 pr_err("Error in ECC-based read: %d\n", ret);
948 goto exit_nfc; 947 return ret;
949 } 948 }
950 949
951 /* handle the block mark swapping */ 950 /* handle the block mark swapping */
952 block_mark_swapping(this, payload_virt, auxiliary_virt); 951 block_mark_swapping(this, payload_virt, auxiliary_virt);
953 952
954 /* Loop over status bytes, accumulating ECC status. */ 953 /* Loop over status bytes, accumulating ECC status. */
955 failed = 0; 954 status = auxiliary_virt + nfc_geo->auxiliary_status_offset;
956 corrected = 0;
957 status = auxiliary_virt + nfc_geo->auxiliary_status_offset;
958 955
959 for (i = 0; i < nfc_geo->ecc_chunk_count; i++, status++) { 956 for (i = 0; i < nfc_geo->ecc_chunk_count; i++, status++) {
960 if ((*status == STATUS_GOOD) || (*status == STATUS_ERASED)) 957 if ((*status == STATUS_GOOD) || (*status == STATUS_ERASED))
961 continue; 958 continue;
962 959
963 if (*status == STATUS_UNCORRECTABLE) { 960 if (*status == STATUS_UNCORRECTABLE) {
964 failed++; 961 mtd->ecc_stats.failed++;
965 continue; 962 continue;
966 } 963 }
967 corrected += *status; 964 mtd->ecc_stats.corrected += *status;
968 } 965 max_bitflips = max_t(unsigned int, max_bitflips, *status);
969
970 /*
971 * Propagate ECC status to the owning MTD only when failed or
972 * corrected times nearly reaches our ECC correction threshold.
973 */
974 if (failed || corrected >= (nfc_geo->ecc_strength - 1)) {
975 mtd->ecc_stats.failed += failed;
976 mtd->ecc_stats.corrected += corrected;
977 } 966 }
978 967
979 if (oob_required) { 968 if (oob_required) {
@@ -995,8 +984,8 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip,
995 this->payload_virt, this->payload_phys, 984 this->payload_virt, this->payload_phys,
996 nfc_geo->payload_size, 985 nfc_geo->payload_size,
997 payload_virt, payload_phys); 986 payload_virt, payload_phys);
998exit_nfc: 987
999 return ret; 988 return max_bitflips;
1000} 989}
1001 990
1002static int gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip, 991static int gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip,