mtd: msm_nand: Fix wrong uncorrectable error bit check
For the Nand controller on 7x30 and 7x27a, the
uncorrectable error bit in the NANDC_BUFFER_STATUS
register is changed to BIT(8) from BIT(3) (in legacy
targets) due to change in the ECC requirements. Currently,
this is handled only in dual nandc mode (default for 7x30
and 7x27a). In case, if only single nandc is used, the
uncorrectable bit check is broken and the driver wouldn't
detect any ECC errors.
Add software version info in platform data to differentiate
between the targets that have different register interface.
CRs-Fixed: 365433
Change-Id: I3c33ccb0e936e262116dd20798d56530dbae900f
Signed-off-by: Sujit Reddy Thumma <sthumma@codeaurora.org>
diff --git a/drivers/mtd/devices/msm_nand.c b/drivers/mtd/devices/msm_nand.c
index 3675d2c..798e9e2 100644
--- a/drivers/mtd/devices/msm_nand.c
+++ b/drivers/mtd/devices/msm_nand.c
@@ -76,6 +76,8 @@
uint32_t ecc_bch_cfg;
uint32_t ecc_parity_bytes;
unsigned cw_size;
+ unsigned int uncorrectable_bit_mask;
+ unsigned int num_err_mask;
};
#define CFG1_WIDE_FLASH (1U << 1)
@@ -1111,9 +1113,8 @@
}
if (pageerr) {
for (n = start_sector; n < cwperpage; n++) {
- if (enable_bch_ecc ?
- (dma_buffer->data.result[n].buffer_status & 0x10) :
- (dma_buffer->data.result[n].buffer_status & 0x8)) {
+ if (dma_buffer->data.result[n].buffer_status &
+ chip->uncorrectable_bit_mask) {
/* not thread safe */
mtd->ecc_stats.failed++;
pageerr = -EBADMSG;
@@ -1123,9 +1124,9 @@
}
if (!rawerr) { /* check for corretable errors */
for (n = start_sector; n < cwperpage; n++) {
- ecc_errors = enable_bch_ecc ?
- (dma_buffer->data.result[n].buffer_status & 0xF) :
- (dma_buffer->data.result[n].buffer_status & 0x7);
+ ecc_errors =
+ (dma_buffer->data.result[n].buffer_status
+ & chip->num_err_mask);
if (ecc_errors) {
total_ecc_errors += ecc_errors;
/* not thread safe */
@@ -1893,7 +1894,7 @@
if (pageerr) {
for (n = start_sector; n < cwperpage; n++) {
if (dma_buffer->data.result[n].buffer_status
- & MSM_NAND_BUF_STAT_UNCRCTBL_ERR) {
+ & chip->uncorrectable_bit_mask) {
/* not thread safe */
mtd->ecc_stats.failed++;
pageerr = -EBADMSG;
@@ -1905,7 +1906,7 @@
for (n = start_sector; n < cwperpage; n++) {
ecc_errors = dma_buffer->data.
result[n].buffer_status
- & MSM_NAND_BUF_STAT_NUM_ERR_MASK;
+ & chip->num_err_mask;
if (ecc_errors) {
total_ecc_errors += ecc_errors;
/* not thread safe */
@@ -7043,6 +7044,15 @@
pr_info("%s: allocated dma buffer at %p, dma_addr %x\n",
__func__, info->msm_nand.dma_buffer, info->msm_nand.dma_addr);
+ /* Let default be VERSION_1 for backward compatibility */
+ info->msm_nand.uncorrectable_bit_mask = BIT(3);
+ info->msm_nand.num_err_mask = 0x7;
+
+ if (plat_data && (plat_data->version == VERSION_2)) {
+ info->msm_nand.uncorrectable_bit_mask = BIT(8);
+ info->msm_nand.num_err_mask = 0x1F;
+ }
+
info->mtd.name = dev_name(&pdev->dev);
info->mtd.priv = &info->msm_nand;
info->mtd.owner = THIS_MODULE;