diff options
author | Aaron Sierra <asierra@xes-inc.com> | 2015-01-14 18:41:31 -0500 |
---|---|---|
committer | Brian Norris <computersforpeace@gmail.com> | 2015-02-02 00:10:58 -0500 |
commit | e0377cdebaf3913bff693c9eea17ff6eb4d7abc8 (patch) | |
tree | 4af65d7984f566492e043f4376757fbcf726c03d | |
parent | 240181fd0ffa69cac08d6b06c94e843707370f5f (diff) |
mtd: nand: Request strength instead of bytes for soft BCH
Previously, we requested that drivers pass ecc.size and ecc.bytes when
using NAND_ECC_SOFT_BCH. However, a driver is likely to only know the ECC
strength required for its NAND, so each driver would need to perform a
strength-to-bytes calculation.
Avoid duplicating this calculation in each driver by asking drivers to
pass ecc.size and ecc.strength so that the strength-to-bytes calculation
need only be implemented once.
This reverts/generalizes this commit:
mtd: nand: Base BCH ECC bytes on required strength
Signed-off-by: Aaron Sierra <asierra@xes-inc.com>
Reviewed-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 14 | ||||
-rw-r--r-- | drivers/mtd/nand/nandsim.c | 1 | ||||
-rw-r--r-- | drivers/mtd/nand/sunxi_nand.c | 2 |
3 files changed, 9 insertions, 8 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 3f24b587304f..f6af96926f00 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -4037,22 +4037,24 @@ int nand_scan_tail(struct mtd_info *mtd) | |||
4037 | ecc->read_oob = nand_read_oob_std; | 4037 | ecc->read_oob = nand_read_oob_std; |
4038 | ecc->write_oob = nand_write_oob_std; | 4038 | ecc->write_oob = nand_write_oob_std; |
4039 | /* | 4039 | /* |
4040 | * Board driver should supply ecc.size and ecc.bytes values to | 4040 | * Board driver should supply ecc.size and ecc.strength values |
4041 | * select how many bits are correctable; see nand_bch_init() | 4041 | * to select how many bits are correctable. Otherwise, default |
4042 | * for details. Otherwise, default to 4 bits for large page | 4042 | * to 4 bits for large page devices. |
4043 | * devices. | ||
4044 | */ | 4043 | */ |
4045 | if (!ecc->size && (mtd->oobsize >= 64)) { | 4044 | if (!ecc->size && (mtd->oobsize >= 64)) { |
4046 | ecc->size = 512; | 4045 | ecc->size = 512; |
4047 | ecc->bytes = DIV_ROUND_UP(13 * ecc->strength, 8); | 4046 | ecc->strength = 4; |
4048 | } | 4047 | } |
4048 | |||
4049 | /* See nand_bch_init() for details. */ | ||
4050 | ecc->bytes = DIV_ROUND_UP( | ||
4051 | ecc->strength * fls(8 * ecc->size), 8); | ||
4049 | ecc->priv = nand_bch_init(mtd, ecc->size, ecc->bytes, | 4052 | ecc->priv = nand_bch_init(mtd, ecc->size, ecc->bytes, |
4050 | &ecc->layout); | 4053 | &ecc->layout); |
4051 | if (!ecc->priv) { | 4054 | if (!ecc->priv) { |
4052 | pr_warn("BCH ECC initialization failed!\n"); | 4055 | pr_warn("BCH ECC initialization failed!\n"); |
4053 | BUG(); | 4056 | BUG(); |
4054 | } | 4057 | } |
4055 | ecc->strength = ecc->bytes * 8 / fls(8 * ecc->size); | ||
4056 | break; | 4058 | break; |
4057 | 4059 | ||
4058 | case NAND_ECC_NONE: | 4060 | case NAND_ECC_NONE: |
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index a8fa8dad9b23..f2324271b94e 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c | |||
@@ -2337,6 +2337,7 @@ static int __init ns_init_module(void) | |||
2337 | } | 2337 | } |
2338 | chip->ecc.mode = NAND_ECC_SOFT_BCH; | 2338 | chip->ecc.mode = NAND_ECC_SOFT_BCH; |
2339 | chip->ecc.size = 512; | 2339 | chip->ecc.size = 512; |
2340 | chip->ecc.strength = bch; | ||
2340 | chip->ecc.bytes = eccbytes; | 2341 | chip->ecc.bytes = eccbytes; |
2341 | NS_INFO("using %u-bit/%u bytes BCH ECC\n", bch, chip->ecc.size); | 2342 | NS_INFO("using %u-bit/%u bytes BCH ECC\n", bch, chip->ecc.size); |
2342 | } | 2343 | } |
diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c index ccaa8e283388..6f93b2990d25 100644 --- a/drivers/mtd/nand/sunxi_nand.c +++ b/drivers/mtd/nand/sunxi_nand.c | |||
@@ -1110,8 +1110,6 @@ static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc, | |||
1110 | 1110 | ||
1111 | switch (ecc->mode) { | 1111 | switch (ecc->mode) { |
1112 | case NAND_ECC_SOFT_BCH: | 1112 | case NAND_ECC_SOFT_BCH: |
1113 | ecc->bytes = DIV_ROUND_UP(ecc->strength * fls(8 * ecc->size), | ||
1114 | 8); | ||
1115 | break; | 1113 | break; |
1116 | case NAND_ECC_HW: | 1114 | case NAND_ECC_HW: |
1117 | ret = sunxi_nand_hw_ecc_ctrl_init(mtd, ecc, np); | 1115 | ret = sunxi_nand_hw_ecc_ctrl_init(mtd, ecc, np); |