aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoger Quadros <rogerq@ti.com>2017-10-20 08:16:21 -0400
committerBoris Brezillon <boris.brezillon@free-electrons.com>2017-10-27 10:53:23 -0400
commit739c64414f01748a36e7d82c8e0611dea94412bd (patch)
tree92bbd573a2aae1eca85b20040e734c08e01dce23
parent1f3df4dc088d927683b292118cd8b4eaaf1af573 (diff)
mtd: nand: omap2: Fix subpage write
Since v4.12, NAND subpage writes were causing a NULL pointer dereference on OMAP platforms (omap2-nand) using OMAP_ECC_BCH4_CODE_HW, OMAP_ECC_BCH8_CODE_HW and OMAP_ECC_BCH16_CODE_HW. This is because for those ECC modes, omap_calculate_ecc_bch() generates ECC bytes for the entire (multi-sector) page and this can overflow the ECC buffer provided by nand_write_subpage_hwecc() as it expects ecc.calculate() to return ECC bytes for just one sector. However, the root cause of the problem is present since v3.9 but was not seen then as NAND buffers were being allocated as one big chunk prior to commit 3deb9979c731 ("mtd: nand: allocate aligned buffers if NAND_OWN_BUFFERS is unset"). Fix the issue by providing a OMAP optimized write_subpage() implementation. Fixes: 62116e5171e0 ("mtd: nand: omap2: Support for hardware BCH error correction.") Cc: <stable@vger.kernel.org> Signed-off-by: Roger Quadros <rogerq@ti.com> Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
-rw-r--r--drivers/mtd/nand/omap2.c339
1 files changed, 224 insertions, 115 deletions
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index a97c1aeed55e..dad438c4906a 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -1133,129 +1133,172 @@ static u8 bch8_polynomial[] = {0xef, 0x51, 0x2e, 0x09, 0xed, 0x93, 0x9a, 0xc2,
1133 0x97, 0x79, 0xe5, 0x24, 0xb5}; 1133 0x97, 0x79, 0xe5, 0x24, 0xb5};
1134 1134
1135/** 1135/**
1136 * omap_calculate_ecc_bch - Generate bytes of ECC bytes 1136 * _omap_calculate_ecc_bch - Generate ECC bytes for one sector
1137 * @mtd: MTD device structure 1137 * @mtd: MTD device structure
1138 * @dat: The pointer to data on which ecc is computed 1138 * @dat: The pointer to data on which ecc is computed
1139 * @ecc_code: The ecc_code buffer 1139 * @ecc_code: The ecc_code buffer
1140 * @i: The sector number (for a multi sector page)
1140 * 1141 *
1141 * Support calculating of BCH4/8 ecc vectors for the page 1142 * Support calculating of BCH4/8/16 ECC vectors for one sector
1143 * within a page. Sector number is in @i.
1142 */ 1144 */
1143static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd, 1145static int _omap_calculate_ecc_bch(struct mtd_info *mtd,
1144 const u_char *dat, u_char *ecc_calc) 1146 const u_char *dat, u_char *ecc_calc, int i)
1145{ 1147{
1146 struct omap_nand_info *info = mtd_to_omap(mtd); 1148 struct omap_nand_info *info = mtd_to_omap(mtd);
1147 int eccbytes = info->nand.ecc.bytes; 1149 int eccbytes = info->nand.ecc.bytes;
1148 struct gpmc_nand_regs *gpmc_regs = &info->reg; 1150 struct gpmc_nand_regs *gpmc_regs = &info->reg;
1149 u8 *ecc_code; 1151 u8 *ecc_code;
1150 unsigned long nsectors, bch_val1, bch_val2, bch_val3, bch_val4; 1152 unsigned long bch_val1, bch_val2, bch_val3, bch_val4;
1151 u32 val; 1153 u32 val;
1152 int i, j; 1154 int j;
1155
1156 ecc_code = ecc_calc;
1157 switch (info->ecc_opt) {
1158 case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
1159 case OMAP_ECC_BCH8_CODE_HW:
1160 bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]);
1161 bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]);
1162 bch_val3 = readl(gpmc_regs->gpmc_bch_result2[i]);
1163 bch_val4 = readl(gpmc_regs->gpmc_bch_result3[i]);
1164 *ecc_code++ = (bch_val4 & 0xFF);
1165 *ecc_code++ = ((bch_val3 >> 24) & 0xFF);
1166 *ecc_code++ = ((bch_val3 >> 16) & 0xFF);
1167 *ecc_code++ = ((bch_val3 >> 8) & 0xFF);
1168 *ecc_code++ = (bch_val3 & 0xFF);
1169 *ecc_code++ = ((bch_val2 >> 24) & 0xFF);
1170 *ecc_code++ = ((bch_val2 >> 16) & 0xFF);
1171 *ecc_code++ = ((bch_val2 >> 8) & 0xFF);
1172 *ecc_code++ = (bch_val2 & 0xFF);
1173 *ecc_code++ = ((bch_val1 >> 24) & 0xFF);
1174 *ecc_code++ = ((bch_val1 >> 16) & 0xFF);
1175 *ecc_code++ = ((bch_val1 >> 8) & 0xFF);
1176 *ecc_code++ = (bch_val1 & 0xFF);
1177 break;
1178 case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
1179 case OMAP_ECC_BCH4_CODE_HW:
1180 bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]);
1181 bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]);
1182 *ecc_code++ = ((bch_val2 >> 12) & 0xFF);
1183 *ecc_code++ = ((bch_val2 >> 4) & 0xFF);
1184 *ecc_code++ = ((bch_val2 & 0xF) << 4) |
1185 ((bch_val1 >> 28) & 0xF);
1186 *ecc_code++ = ((bch_val1 >> 20) & 0xFF);
1187 *ecc_code++ = ((bch_val1 >> 12) & 0xFF);
1188 *ecc_code++ = ((bch_val1 >> 4) & 0xFF);
1189 *ecc_code++ = ((bch_val1 & 0xF) << 4);
1190 break;
1191 case OMAP_ECC_BCH16_CODE_HW:
1192 val = readl(gpmc_regs->gpmc_bch_result6[i]);
1193 ecc_code[0] = ((val >> 8) & 0xFF);
1194 ecc_code[1] = ((val >> 0) & 0xFF);
1195 val = readl(gpmc_regs->gpmc_bch_result5[i]);
1196 ecc_code[2] = ((val >> 24) & 0xFF);
1197 ecc_code[3] = ((val >> 16) & 0xFF);
1198 ecc_code[4] = ((val >> 8) & 0xFF);
1199 ecc_code[5] = ((val >> 0) & 0xFF);
1200 val = readl(gpmc_regs->gpmc_bch_result4[i]);
1201 ecc_code[6] = ((val >> 24) & 0xFF);
1202 ecc_code[7] = ((val >> 16) & 0xFF);
1203 ecc_code[8] = ((val >> 8) & 0xFF);
1204 ecc_code[9] = ((val >> 0) & 0xFF);
1205 val = readl(gpmc_regs->gpmc_bch_result3[i]);
1206 ecc_code[10] = ((val >> 24) & 0xFF);
1207 ecc_code[11] = ((val >> 16) & 0xFF);
1208 ecc_code[12] = ((val >> 8) & 0xFF);
1209 ecc_code[13] = ((val >> 0) & 0xFF);
1210 val = readl(gpmc_regs->gpmc_bch_result2[i]);
1211 ecc_code[14] = ((val >> 24) & 0xFF);
1212 ecc_code[15] = ((val >> 16) & 0xFF);
1213 ecc_code[16] = ((val >> 8) & 0xFF);
1214 ecc_code[17] = ((val >> 0) & 0xFF);
1215 val = readl(gpmc_regs->gpmc_bch_result1[i]);
1216 ecc_code[18] = ((val >> 24) & 0xFF);
1217 ecc_code[19] = ((val >> 16) & 0xFF);
1218 ecc_code[20] = ((val >> 8) & 0xFF);
1219 ecc_code[21] = ((val >> 0) & 0xFF);
1220 val = readl(gpmc_regs->gpmc_bch_result0[i]);
1221 ecc_code[22] = ((val >> 24) & 0xFF);
1222 ecc_code[23] = ((val >> 16) & 0xFF);
1223 ecc_code[24] = ((val >> 8) & 0xFF);
1224 ecc_code[25] = ((val >> 0) & 0xFF);
1225 break;
1226 default:
1227 return -EINVAL;
1228 }
1229
1230 /* ECC scheme specific syndrome customizations */
1231 switch (info->ecc_opt) {
1232 case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
1233 /* Add constant polynomial to remainder, so that
1234 * ECC of blank pages results in 0x0 on reading back
1235 */
1236 for (j = 0; j < eccbytes; j++)
1237 ecc_calc[j] ^= bch4_polynomial[j];
1238 break;
1239 case OMAP_ECC_BCH4_CODE_HW:
1240 /* Set 8th ECC byte as 0x0 for ROM compatibility */
1241 ecc_calc[eccbytes - 1] = 0x0;
1242 break;
1243 case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
1244 /* Add constant polynomial to remainder, so that
1245 * ECC of blank pages results in 0x0 on reading back
1246 */
1247 for (j = 0; j < eccbytes; j++)
1248 ecc_calc[j] ^= bch8_polynomial[j];
1249 break;
1250 case OMAP_ECC_BCH8_CODE_HW:
1251 /* Set 14th ECC byte as 0x0 for ROM compatibility */
1252 ecc_calc[eccbytes - 1] = 0x0;
1253 break;
1254 case OMAP_ECC_BCH16_CODE_HW:
1255 break;
1256 default:
1257 return -EINVAL;
1258 }
1259
1260 return 0;
1261}
1262
1263/**
1264 * omap_calculate_ecc_bch_sw - ECC generator for sector for SW based correction
1265 * @mtd: MTD device structure
1266 * @dat: The pointer to data on which ecc is computed
1267 * @ecc_code: The ecc_code buffer
1268 *
1269 * Support calculating of BCH4/8/16 ECC vectors for one sector. This is used
1270 * when SW based correction is required as ECC is required for one sector
1271 * at a time.
1272 */
1273static int omap_calculate_ecc_bch_sw(struct mtd_info *mtd,
1274 const u_char *dat, u_char *ecc_calc)
1275{
1276 return _omap_calculate_ecc_bch(mtd, dat, ecc_calc, 0);
1277}
1278
1279/**
1280 * omap_calculate_ecc_bch_multi - Generate ECC for multiple sectors
1281 * @mtd: MTD device structure
1282 * @dat: The pointer to data on which ecc is computed
1283 * @ecc_code: The ecc_code buffer
1284 *
1285 * Support calculating of BCH4/8/16 ecc vectors for the entire page in one go.
1286 */
1287static int omap_calculate_ecc_bch_multi(struct mtd_info *mtd,
1288 const u_char *dat, u_char *ecc_calc)
1289{
1290 struct omap_nand_info *info = mtd_to_omap(mtd);
1291 int eccbytes = info->nand.ecc.bytes;
1292 unsigned long nsectors;
1293 int i, ret;
1153 1294
1154 nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1; 1295 nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1;
1155 for (i = 0; i < nsectors; i++) { 1296 for (i = 0; i < nsectors; i++) {
1156 ecc_code = ecc_calc; 1297 ret = _omap_calculate_ecc_bch(mtd, dat, ecc_calc, i);
1157 switch (info->ecc_opt) { 1298 if (ret)
1158 case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW: 1299 return ret;
1159 case OMAP_ECC_BCH8_CODE_HW:
1160 bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]);
1161 bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]);
1162 bch_val3 = readl(gpmc_regs->gpmc_bch_result2[i]);
1163 bch_val4 = readl(gpmc_regs->gpmc_bch_result3[i]);
1164 *ecc_code++ = (bch_val4 & 0xFF);
1165 *ecc_code++ = ((bch_val3 >> 24) & 0xFF);
1166 *ecc_code++ = ((bch_val3 >> 16) & 0xFF);
1167 *ecc_code++ = ((bch_val3 >> 8) & 0xFF);
1168 *ecc_code++ = (bch_val3 & 0xFF);
1169 *ecc_code++ = ((bch_val2 >> 24) & 0xFF);
1170 *ecc_code++ = ((bch_val2 >> 16) & 0xFF);
1171 *ecc_code++ = ((bch_val2 >> 8) & 0xFF);
1172 *ecc_code++ = (bch_val2 & 0xFF);
1173 *ecc_code++ = ((bch_val1 >> 24) & 0xFF);
1174 *ecc_code++ = ((bch_val1 >> 16) & 0xFF);
1175 *ecc_code++ = ((bch_val1 >> 8) & 0xFF);
1176 *ecc_code++ = (bch_val1 & 0xFF);
1177 break;
1178 case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
1179 case OMAP_ECC_BCH4_CODE_HW:
1180 bch_val1 = readl(gpmc_regs->gpmc_bch_result0[i]);
1181 bch_val2 = readl(gpmc_regs->gpmc_bch_result1[i]);
1182 *ecc_code++ = ((bch_val2 >> 12) & 0xFF);
1183 *ecc_code++ = ((bch_val2 >> 4) & 0xFF);
1184 *ecc_code++ = ((bch_val2 & 0xF) << 4) |
1185 ((bch_val1 >> 28) & 0xF);
1186 *ecc_code++ = ((bch_val1 >> 20) & 0xFF);
1187 *ecc_code++ = ((bch_val1 >> 12) & 0xFF);
1188 *ecc_code++ = ((bch_val1 >> 4) & 0xFF);
1189 *ecc_code++ = ((bch_val1 & 0xF) << 4);
1190 break;
1191 case OMAP_ECC_BCH16_CODE_HW:
1192 val = readl(gpmc_regs->gpmc_bch_result6[i]);
1193 ecc_code[0] = ((val >> 8) & 0xFF);
1194 ecc_code[1] = ((val >> 0) & 0xFF);
1195 val = readl(gpmc_regs->gpmc_bch_result5[i]);
1196 ecc_code[2] = ((val >> 24) & 0xFF);
1197 ecc_code[3] = ((val >> 16) & 0xFF);
1198 ecc_code[4] = ((val >> 8) & 0xFF);
1199 ecc_code[5] = ((val >> 0) & 0xFF);
1200 val = readl(gpmc_regs->gpmc_bch_result4[i]);
1201 ecc_code[6] = ((val >> 24) & 0xFF);
1202 ecc_code[7] = ((val >> 16) & 0xFF);
1203 ecc_code[8] = ((val >> 8) & 0xFF);
1204 ecc_code[9] = ((val >> 0) & 0xFF);
1205 val = readl(gpmc_regs->gpmc_bch_result3[i]);
1206 ecc_code[10] = ((val >> 24) & 0xFF);
1207 ecc_code[11] = ((val >> 16) & 0xFF);
1208 ecc_code[12] = ((val >> 8) & 0xFF);
1209 ecc_code[13] = ((val >> 0) & 0xFF);
1210 val = readl(gpmc_regs->gpmc_bch_result2[i]);
1211 ecc_code[14] = ((val >> 24) & 0xFF);
1212 ecc_code[15] = ((val >> 16) & 0xFF);
1213 ecc_code[16] = ((val >> 8) & 0xFF);
1214 ecc_code[17] = ((val >> 0) & 0xFF);
1215 val = readl(gpmc_regs->gpmc_bch_result1[i]);
1216 ecc_code[18] = ((val >> 24) & 0xFF);
1217 ecc_code[19] = ((val >> 16) & 0xFF);
1218 ecc_code[20] = ((val >> 8) & 0xFF);
1219 ecc_code[21] = ((val >> 0) & 0xFF);
1220 val = readl(gpmc_regs->gpmc_bch_result0[i]);
1221 ecc_code[22] = ((val >> 24) & 0xFF);
1222 ecc_code[23] = ((val >> 16) & 0xFF);
1223 ecc_code[24] = ((val >> 8) & 0xFF);
1224 ecc_code[25] = ((val >> 0) & 0xFF);
1225 break;
1226 default:
1227 return -EINVAL;
1228 }
1229 1300
1230 /* ECC scheme specific syndrome customizations */ 1301 ecc_calc += eccbytes;
1231 switch (info->ecc_opt) {
1232 case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
1233 /* Add constant polynomial to remainder, so that
1234 * ECC of blank pages results in 0x0 on reading back */
1235 for (j = 0; j < eccbytes; j++)
1236 ecc_calc[j] ^= bch4_polynomial[j];
1237 break;
1238 case OMAP_ECC_BCH4_CODE_HW:
1239 /* Set 8th ECC byte as 0x0 for ROM compatibility */
1240 ecc_calc[eccbytes - 1] = 0x0;
1241 break;
1242 case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
1243 /* Add constant polynomial to remainder, so that
1244 * ECC of blank pages results in 0x0 on reading back */
1245 for (j = 0; j < eccbytes; j++)
1246 ecc_calc[j] ^= bch8_polynomial[j];
1247 break;
1248 case OMAP_ECC_BCH8_CODE_HW:
1249 /* Set 14th ECC byte as 0x0 for ROM compatibility */
1250 ecc_calc[eccbytes - 1] = 0x0;
1251 break;
1252 case OMAP_ECC_BCH16_CODE_HW:
1253 break;
1254 default:
1255 return -EINVAL;
1256 }
1257
1258 ecc_calc += eccbytes;
1259 } 1302 }
1260 1303
1261 return 0; 1304 return 0;
@@ -1496,7 +1539,7 @@ static int omap_write_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
1496 chip->write_buf(mtd, buf, mtd->writesize); 1539 chip->write_buf(mtd, buf, mtd->writesize);
1497 1540
1498 /* Update ecc vector from GPMC result registers */ 1541 /* Update ecc vector from GPMC result registers */
1499 chip->ecc.calculate(mtd, buf, &ecc_calc[0]); 1542 omap_calculate_ecc_bch_multi(mtd, buf, &ecc_calc[0]);
1500 1543
1501 ret = mtd_ooblayout_set_eccbytes(mtd, ecc_calc, chip->oob_poi, 0, 1544 ret = mtd_ooblayout_set_eccbytes(mtd, ecc_calc, chip->oob_poi, 0,
1502 chip->ecc.total); 1545 chip->ecc.total);
@@ -1509,6 +1552,72 @@ static int omap_write_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
1509} 1552}
1510 1553
1511/** 1554/**
1555 * omap_write_subpage_bch - BCH hardware ECC based subpage write
1556 * @mtd: mtd info structure
1557 * @chip: nand chip info structure
1558 * @offset: column address of subpage within the page
1559 * @data_len: data length
1560 * @buf: data buffer
1561 * @oob_required: must write chip->oob_poi to OOB
1562 * @page: page number to write
1563 *
1564 * OMAP optimized subpage write method.
1565 */
1566static int omap_write_subpage_bch(struct mtd_info *mtd,
1567 struct nand_chip *chip, u32 offset,
1568 u32 data_len, const u8 *buf,
1569 int oob_required, int page)
1570{
1571 u8 *ecc_calc = chip->buffers->ecccalc;
1572 int ecc_size = chip->ecc.size;
1573 int ecc_bytes = chip->ecc.bytes;
1574 int ecc_steps = chip->ecc.steps;
1575 u32 start_step = offset / ecc_size;
1576 u32 end_step = (offset + data_len - 1) / ecc_size;
1577 int step, ret = 0;
1578
1579 /*
1580 * Write entire page at one go as it would be optimal
1581 * as ECC is calculated by hardware.
1582 * ECC is calculated for all subpages but we choose
1583 * only what we want.
1584 */
1585
1586 /* Enable GPMC ECC engine */
1587 chip->ecc.hwctl(mtd, NAND_ECC_WRITE);
1588
1589 /* Write data */
1590 chip->write_buf(mtd, buf, mtd->writesize);
1591
1592 for (step = 0; step < ecc_steps; step++) {
1593 /* mask ECC of un-touched subpages by padding 0xFF */
1594 if (step < start_step || step > end_step)
1595 memset(ecc_calc, 0xff, ecc_bytes);
1596 else
1597 ret = _omap_calculate_ecc_bch(mtd, buf, ecc_calc, step);
1598
1599 if (ret)
1600 return ret;
1601
1602 buf += ecc_size;
1603 ecc_calc += ecc_bytes;
1604 }
1605
1606 /* copy calculated ECC for whole page to chip->buffer->oob */
1607 /* this include masked-value(0xFF) for unwritten subpages */
1608 ecc_calc = chip->buffers->ecccalc;
1609 ret = mtd_ooblayout_set_eccbytes(mtd, ecc_calc, chip->oob_poi, 0,
1610 chip->ecc.total);
1611 if (ret)
1612 return ret;
1613
1614 /* write OOB buffer to NAND device */
1615 chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
1616
1617 return 0;
1618}
1619
1620/**
1512 * omap_read_page_bch - BCH ecc based page read function for entire page 1621 * omap_read_page_bch - BCH ecc based page read function for entire page
1513 * @mtd: mtd info structure 1622 * @mtd: mtd info structure
1514 * @chip: nand chip info structure 1623 * @chip: nand chip info structure
@@ -1544,7 +1653,7 @@ static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
1544 chip->ecc.total); 1653 chip->ecc.total);
1545 1654
1546 /* Calculate ecc bytes */ 1655 /* Calculate ecc bytes */
1547 chip->ecc.calculate(mtd, buf, ecc_calc); 1656 omap_calculate_ecc_bch_multi(mtd, buf, ecc_calc);
1548 1657
1549 ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0, 1658 ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0,
1550 chip->ecc.total); 1659 chip->ecc.total);
@@ -2023,7 +2132,7 @@ static int omap_nand_probe(struct platform_device *pdev)
2023 nand_chip->ecc.strength = 4; 2132 nand_chip->ecc.strength = 4;
2024 nand_chip->ecc.hwctl = omap_enable_hwecc_bch; 2133 nand_chip->ecc.hwctl = omap_enable_hwecc_bch;
2025 nand_chip->ecc.correct = nand_bch_correct_data; 2134 nand_chip->ecc.correct = nand_bch_correct_data;
2026 nand_chip->ecc.calculate = omap_calculate_ecc_bch; 2135 nand_chip->ecc.calculate = omap_calculate_ecc_bch_sw;
2027 mtd_set_ooblayout(mtd, &omap_sw_ooblayout_ops); 2136 mtd_set_ooblayout(mtd, &omap_sw_ooblayout_ops);
2028 /* Reserve one byte for the OMAP marker */ 2137 /* Reserve one byte for the OMAP marker */
2029 oobbytes_per_step = nand_chip->ecc.bytes + 1; 2138 oobbytes_per_step = nand_chip->ecc.bytes + 1;
@@ -2045,9 +2154,9 @@ static int omap_nand_probe(struct platform_device *pdev)
2045 nand_chip->ecc.strength = 4; 2154 nand_chip->ecc.strength = 4;
2046 nand_chip->ecc.hwctl = omap_enable_hwecc_bch; 2155 nand_chip->ecc.hwctl = omap_enable_hwecc_bch;
2047 nand_chip->ecc.correct = omap_elm_correct_data; 2156 nand_chip->ecc.correct = omap_elm_correct_data;
2048 nand_chip->ecc.calculate = omap_calculate_ecc_bch;
2049 nand_chip->ecc.read_page = omap_read_page_bch; 2157 nand_chip->ecc.read_page = omap_read_page_bch;
2050 nand_chip->ecc.write_page = omap_write_page_bch; 2158 nand_chip->ecc.write_page = omap_write_page_bch;
2159 nand_chip->ecc.write_subpage = omap_write_subpage_bch;
2051 mtd_set_ooblayout(mtd, &omap_ooblayout_ops); 2160 mtd_set_ooblayout(mtd, &omap_ooblayout_ops);
2052 oobbytes_per_step = nand_chip->ecc.bytes; 2161 oobbytes_per_step = nand_chip->ecc.bytes;
2053 2162
@@ -2066,7 +2175,7 @@ static int omap_nand_probe(struct platform_device *pdev)
2066 nand_chip->ecc.strength = 8; 2175 nand_chip->ecc.strength = 8;
2067 nand_chip->ecc.hwctl = omap_enable_hwecc_bch; 2176 nand_chip->ecc.hwctl = omap_enable_hwecc_bch;
2068 nand_chip->ecc.correct = nand_bch_correct_data; 2177 nand_chip->ecc.correct = nand_bch_correct_data;
2069 nand_chip->ecc.calculate = omap_calculate_ecc_bch; 2178 nand_chip->ecc.calculate = omap_calculate_ecc_bch_sw;
2070 mtd_set_ooblayout(mtd, &omap_sw_ooblayout_ops); 2179 mtd_set_ooblayout(mtd, &omap_sw_ooblayout_ops);
2071 /* Reserve one byte for the OMAP marker */ 2180 /* Reserve one byte for the OMAP marker */
2072 oobbytes_per_step = nand_chip->ecc.bytes + 1; 2181 oobbytes_per_step = nand_chip->ecc.bytes + 1;
@@ -2088,9 +2197,9 @@ static int omap_nand_probe(struct platform_device *pdev)
2088 nand_chip->ecc.strength = 8; 2197 nand_chip->ecc.strength = 8;
2089 nand_chip->ecc.hwctl = omap_enable_hwecc_bch; 2198 nand_chip->ecc.hwctl = omap_enable_hwecc_bch;
2090 nand_chip->ecc.correct = omap_elm_correct_data; 2199 nand_chip->ecc.correct = omap_elm_correct_data;
2091 nand_chip->ecc.calculate = omap_calculate_ecc_bch;
2092 nand_chip->ecc.read_page = omap_read_page_bch; 2200 nand_chip->ecc.read_page = omap_read_page_bch;
2093 nand_chip->ecc.write_page = omap_write_page_bch; 2201 nand_chip->ecc.write_page = omap_write_page_bch;
2202 nand_chip->ecc.write_subpage = omap_write_subpage_bch;
2094 mtd_set_ooblayout(mtd, &omap_ooblayout_ops); 2203 mtd_set_ooblayout(mtd, &omap_ooblayout_ops);
2095 oobbytes_per_step = nand_chip->ecc.bytes; 2204 oobbytes_per_step = nand_chip->ecc.bytes;
2096 2205
@@ -2110,9 +2219,9 @@ static int omap_nand_probe(struct platform_device *pdev)
2110 nand_chip->ecc.strength = 16; 2219 nand_chip->ecc.strength = 16;
2111 nand_chip->ecc.hwctl = omap_enable_hwecc_bch; 2220 nand_chip->ecc.hwctl = omap_enable_hwecc_bch;
2112 nand_chip->ecc.correct = omap_elm_correct_data; 2221 nand_chip->ecc.correct = omap_elm_correct_data;
2113 nand_chip->ecc.calculate = omap_calculate_ecc_bch;
2114 nand_chip->ecc.read_page = omap_read_page_bch; 2222 nand_chip->ecc.read_page = omap_read_page_bch;
2115 nand_chip->ecc.write_page = omap_write_page_bch; 2223 nand_chip->ecc.write_page = omap_write_page_bch;
2224 nand_chip->ecc.write_subpage = omap_write_subpage_bch;
2116 mtd_set_ooblayout(mtd, &omap_ooblayout_ops); 2225 mtd_set_ooblayout(mtd, &omap_ooblayout_ops);
2117 oobbytes_per_step = nand_chip->ecc.bytes; 2226 oobbytes_per_step = nand_chip->ecc.bytes;
2118 2227