diff options
Diffstat (limited to 'drivers/mtd/nand/denali.c')
-rw-r--r-- | drivers/mtd/nand/denali.c | 38 |
1 files changed, 14 insertions, 24 deletions
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index a9e57d686297..0650aafa0dd2 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c | |||
@@ -924,9 +924,10 @@ bool is_erased(uint8_t *buf, int len) | |||
924 | #define ECC_LAST_ERR(x) ((x) & ERR_CORRECTION_INFO__LAST_ERR_INFO) | 924 | #define ECC_LAST_ERR(x) ((x) & ERR_CORRECTION_INFO__LAST_ERR_INFO) |
925 | 925 | ||
926 | static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf, | 926 | static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf, |
927 | uint32_t irq_status) | 927 | uint32_t irq_status, unsigned int *max_bitflips) |
928 | { | 928 | { |
929 | bool check_erased_page = false; | 929 | bool check_erased_page = false; |
930 | unsigned int bitflips = 0; | ||
930 | 931 | ||
931 | if (irq_status & INTR_STATUS__ECC_ERR) { | 932 | if (irq_status & INTR_STATUS__ECC_ERR) { |
932 | /* read the ECC errors. we'll ignore them for now */ | 933 | /* read the ECC errors. we'll ignore them for now */ |
@@ -965,6 +966,7 @@ static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf, | |||
965 | /* correct the ECC error */ | 966 | /* correct the ECC error */ |
966 | buf[offset] ^= err_correction_value; | 967 | buf[offset] ^= err_correction_value; |
967 | denali->mtd.ecc_stats.corrected++; | 968 | denali->mtd.ecc_stats.corrected++; |
969 | bitflips++; | ||
968 | } | 970 | } |
969 | } else { | 971 | } else { |
970 | /* if the error is not correctable, need to | 972 | /* if the error is not correctable, need to |
@@ -984,6 +986,7 @@ static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf, | |||
984 | clear_interrupts(denali); | 986 | clear_interrupts(denali); |
985 | denali_set_intr_modes(denali, true); | 987 | denali_set_intr_modes(denali, true); |
986 | } | 988 | } |
989 | *max_bitflips = bitflips; | ||
987 | return check_erased_page; | 990 | return check_erased_page; |
988 | } | 991 | } |
989 | 992 | ||
@@ -1084,7 +1087,7 @@ static void write_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1084 | * by write_page above. | 1087 | * by write_page above. |
1085 | * */ | 1088 | * */ |
1086 | static void denali_write_page(struct mtd_info *mtd, struct nand_chip *chip, | 1089 | static void denali_write_page(struct mtd_info *mtd, struct nand_chip *chip, |
1087 | const uint8_t *buf) | 1090 | const uint8_t *buf, int oob_required) |
1088 | { | 1091 | { |
1089 | /* for regular page writes, we let HW handle all the ECC | 1092 | /* for regular page writes, we let HW handle all the ECC |
1090 | * data written to the device. */ | 1093 | * data written to the device. */ |
@@ -1096,7 +1099,7 @@ static void denali_write_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1096 | * write_page() function above. | 1099 | * write_page() function above. |
1097 | */ | 1100 | */ |
1098 | static void denali_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, | 1101 | static void denali_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, |
1099 | const uint8_t *buf) | 1102 | const uint8_t *buf, int oob_required) |
1100 | { | 1103 | { |
1101 | /* for raw page writes, we want to disable ECC and simply write | 1104 | /* for raw page writes, we want to disable ECC and simply write |
1102 | whatever data is in the buffer. */ | 1105 | whatever data is in the buffer. */ |
@@ -1110,17 +1113,17 @@ static int denali_write_oob(struct mtd_info *mtd, struct nand_chip *chip, | |||
1110 | } | 1113 | } |
1111 | 1114 | ||
1112 | static int denali_read_oob(struct mtd_info *mtd, struct nand_chip *chip, | 1115 | static int denali_read_oob(struct mtd_info *mtd, struct nand_chip *chip, |
1113 | int page, int sndcmd) | 1116 | int page) |
1114 | { | 1117 | { |
1115 | read_oob_data(mtd, chip->oob_poi, page); | 1118 | read_oob_data(mtd, chip->oob_poi, page); |
1116 | 1119 | ||
1117 | return 0; /* notify NAND core to send command to | 1120 | return 0; |
1118 | NAND device. */ | ||
1119 | } | 1121 | } |
1120 | 1122 | ||
1121 | static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, | 1123 | static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, |
1122 | uint8_t *buf, int page) | 1124 | uint8_t *buf, int oob_required, int page) |
1123 | { | 1125 | { |
1126 | unsigned int max_bitflips; | ||
1124 | struct denali_nand_info *denali = mtd_to_denali(mtd); | 1127 | struct denali_nand_info *denali = mtd_to_denali(mtd); |
1125 | 1128 | ||
1126 | dma_addr_t addr = denali->buf.dma_buf; | 1129 | dma_addr_t addr = denali->buf.dma_buf; |
@@ -1153,7 +1156,7 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1153 | 1156 | ||
1154 | memcpy(buf, denali->buf.buf, mtd->writesize); | 1157 | memcpy(buf, denali->buf.buf, mtd->writesize); |
1155 | 1158 | ||
1156 | check_erased_page = handle_ecc(denali, buf, irq_status); | 1159 | check_erased_page = handle_ecc(denali, buf, irq_status, &max_bitflips); |
1157 | denali_enable_dma(denali, false); | 1160 | denali_enable_dma(denali, false); |
1158 | 1161 | ||
1159 | if (check_erased_page) { | 1162 | if (check_erased_page) { |
@@ -1167,11 +1170,11 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1167 | denali->mtd.ecc_stats.failed++; | 1170 | denali->mtd.ecc_stats.failed++; |
1168 | } | 1171 | } |
1169 | } | 1172 | } |
1170 | return 0; | 1173 | return max_bitflips; |
1171 | } | 1174 | } |
1172 | 1175 | ||
1173 | static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, | 1176 | static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, |
1174 | uint8_t *buf, int page) | 1177 | uint8_t *buf, int oob_required, int page) |
1175 | { | 1178 | { |
1176 | struct denali_nand_info *denali = mtd_to_denali(mtd); | 1179 | struct denali_nand_info *denali = mtd_to_denali(mtd); |
1177 | 1180 | ||
@@ -1702,17 +1705,4 @@ static struct pci_driver denali_pci_driver = { | |||
1702 | .remove = denali_pci_remove, | 1705 | .remove = denali_pci_remove, |
1703 | }; | 1706 | }; |
1704 | 1707 | ||
1705 | static int __devinit denali_init(void) | 1708 | module_pci_driver(denali_pci_driver); |
1706 | { | ||
1707 | printk(KERN_INFO "Spectra MTD driver\n"); | ||
1708 | return pci_register_driver(&denali_pci_driver); | ||
1709 | } | ||
1710 | |||
1711 | /* Free memory */ | ||
1712 | static void __devexit denali_exit(void) | ||
1713 | { | ||
1714 | pci_unregister_driver(&denali_pci_driver); | ||
1715 | } | ||
1716 | |||
1717 | module_init(denali_init); | ||
1718 | module_exit(denali_exit); | ||