Merge "Add device support for reading OTP."
diff --git a/drivers/mtd/nand/comcerto_nand.c b/drivers/mtd/nand/comcerto_nand.c
index d5ca078..7a1c161 100644
--- a/drivers/mtd/nand/comcerto_nand.c
+++ b/drivers/mtd/nand/comcerto_nand.c
@@ -262,9 +262,8 @@
 static int comcerto_correct_ecc(struct mtd_info *mtd, uint8_t *dat,
 		uint8_t *read_ecc, uint8_t *calc_ecc)
 {
-#if !defined (CONFIG_NAND_COMCERTO_ECC_8_HW_BCH) && !defined (CONFIG_NAND_COMCERTO_ECC_24_HW_BCH)
 	struct nand_chip *nand_device = mtd->priv;
-#else
+#if defined (CONFIG_NAND_COMCERTO_ECC_8_HW_BCH) || defined (CONFIG_NAND_COMCERTO_ECC_24_HW_BCH)
 	uint8_t err_count = 0;
 	uint32_t err_corr_data_prev;
 #endif
@@ -274,11 +273,13 @@
 	unsigned long timeo = jiffies + 2;
 
 	 /* Wait for syndrome calculation to complete */
-	do {
-		if ((readl_relaxed(ecc_base_addr + ECC_IDLE_STAT)) & ECC_IDLE)
-			break;
+	while (!(readl_relaxed(ecc_base_addr + ECC_IDLE_STAT) & ECC_IDLE)) {
 		touch_softlockup_watchdog();
-	} while (time_before(jiffies, timeo));
+		if (time_after_eq(jiffies, timeo)) {
+			pr_warn_ratelimited("Timeout waiting for parity module to become idle");
+			return -EIO;
+		}
+	}
 
 	 /* If no correction is required */
 	if (likely(!((readl_relaxed(ecc_base_addr + ECC_POLY_STAT)) & ECC_CORR_REQ))) {
@@ -292,15 +293,20 @@
 
 	udelay(25);
 
+	timeo = jiffies + 2;
 	err_corr_data_prev = 0;
 	/* Read Correction data status register till header is 0x7FD */
-	do {
+	while(1) {
 		err_corr_data_prev = readl_relaxed(ecc_base_addr + ECC_CORR_DATA_STAT);
 		if ((err_corr_data_prev >> ECC_BCH_INDEX_SHIFT) == 0x87FD)
 			break;
 
 		touch_softlockup_watchdog();
-	} while (time_before(jiffies, timeo));
+		if (time_after_eq(jiffies, timeo)) {
+			pr_warn_ratelimited("Timeout waiting for ECC correction data");
+			return -EIO;
+		}
+	}
 
 	udelay(25);
 	err_corr_data = 0x0;
@@ -314,6 +320,12 @@
 		err_corr_data_prev = err_corr_data;
 		index = (err_corr_data >> 16) & 0x7FF;
 		mask = err_corr_data & 0xFFFF;
+		if (index * 2 >= nand_device->ecc.size) {
+			pr_warn_ratelimited("ECC correction index out of "
+					"bounds. ECC_CORR_DATA_STAT %08x",
+					err_corr_data);
+			continue;
+		}
 		*((uint16_t *)(dat + (index * 2))) ^= mask;
 		while (mask) {
 			if (mask & 1)