diff options
Diffstat (limited to 'drivers/mtd/nand/raw/nand_base.c')
-rw-r--r-- | drivers/mtd/nand/raw/nand_base.c | 80 |
1 files changed, 50 insertions, 30 deletions
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index 172852a29a50..4b406b0f783c 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c @@ -5041,28 +5041,45 @@ static const char * const nand_ecc_modes[] = { [NAND_ECC_ON_DIE] = "on-die", }; -static int of_get_nand_ecc_mode(struct device_node *np) +static enum nand_ecc_engine_type +of_get_nand_ecc_engine_type(struct device_node *np) { + enum nand_ecc_mode eng_type; const char *pm; - int err, i; + int err; err = of_property_read_string(np, "nand-ecc-mode", &pm); - if (err < 0) - return err; - - for (i = NAND_ECC_NONE; i < ARRAY_SIZE(nand_ecc_modes); i++) - if (!strcasecmp(pm, nand_ecc_modes[i])) - return i; + if (err) + return NAND_ECC_ENGINE_TYPE_INVALID; + + for (eng_type = NAND_ECC_NONE; + eng_type < ARRAY_SIZE(nand_ecc_modes); eng_type++) { + if (!strcasecmp(pm, nand_ecc_modes[eng_type])) { + switch (eng_type) { + case NAND_ECC_NONE: + return NAND_ECC_ENGINE_TYPE_NONE; + case NAND_ECC_SOFT: + return NAND_ECC_ENGINE_TYPE_SOFT; + case NAND_ECC_HW: + case NAND_ECC_HW_SYNDROME: + return NAND_ECC_ENGINE_TYPE_ON_HOST; + case NAND_ECC_ON_DIE: + return NAND_ECC_ENGINE_TYPE_ON_DIE; + default: + break; + } + } + } /* * For backward compatibility we support few obsoleted values that don't - * have their mappings into the nand_ecc_mode enum anymore (they were - * merged with other enums). + * have their mappings into the nand_ecc_engine_providers enum anymore + * (they were merged with other enums). */ if (!strcasecmp(pm, "soft_bch")) - return NAND_ECC_SOFT; + return NAND_ECC_ENGINE_TYPE_SOFT; - return -ENODEV; + return NAND_ECC_ENGINE_TYPE_INVALID; } static const char * const nand_ecc_algos[] = { @@ -5144,8 +5161,9 @@ static bool of_get_nand_on_flash_bbt(struct device_node *np) static int nand_dt_init(struct nand_chip *chip) { struct device_node *dn = nand_get_flash_node(chip); + enum nand_ecc_engine_type ecc_type; enum nand_ecc_algo ecc_algo; - int ecc_mode, ecc_strength, ecc_step; + int ecc_strength, ecc_step; if (!dn) return 0; @@ -5159,13 +5177,13 @@ static int nand_dt_init(struct nand_chip *chip) if (of_get_nand_on_flash_bbt(dn)) chip->bbt_options |= NAND_BBT_USE_FLASH; - ecc_mode = of_get_nand_ecc_mode(dn); + ecc_type = of_get_nand_ecc_engine_type(dn); ecc_algo = of_get_nand_ecc_algo(dn); ecc_strength = of_get_nand_ecc_strength(dn); ecc_step = of_get_nand_ecc_step_size(dn); - if (ecc_mode >= 0) - chip->ecc.mode = ecc_mode; + if (ecc_type != NAND_ECC_ENGINE_TYPE_INVALID) + chip->ecc.engine_type = ecc_type; if (ecc_algo != NAND_ECC_ALGO_UNKNOWN) chip->ecc.algo = ecc_algo; @@ -5287,7 +5305,7 @@ static int nand_set_ecc_soft_ops(struct nand_chip *chip) struct mtd_info *mtd = nand_to_mtd(chip); struct nand_ecc_ctrl *ecc = &chip->ecc; - if (WARN_ON(ecc->mode != NAND_ECC_SOFT)) + if (WARN_ON(ecc->engine_type != NAND_ECC_ENGINE_TYPE_SOFT)) return -EINVAL; switch (ecc->algo) { @@ -5752,7 +5770,8 @@ static int nand_scan_tail(struct nand_chip *chip) * If no default placement scheme is given, select an appropriate one. */ if (!mtd->ooblayout && - !(ecc->mode == NAND_ECC_SOFT && ecc->algo == NAND_ECC_ALGO_BCH)) { + !(ecc->engine_type == NAND_ECC_ENGINE_TYPE_SOFT && + ecc->algo == NAND_ECC_ALGO_BCH)) { switch (mtd->oobsize) { case 8: case 16: @@ -5770,7 +5789,7 @@ static int nand_scan_tail(struct nand_chip *chip) * page with ECC layout when ->oobsize <= 128 for * compatibility reasons. */ - if (ecc->mode == NAND_ECC_NONE) { + if (ecc->engine_type == NAND_ECC_ENGINE_TYPE_NONE) { mtd_set_ooblayout(mtd, &nand_ooblayout_lp_ops); break; @@ -5788,8 +5807,9 @@ static int nand_scan_tail(struct nand_chip *chip) * selected and we have 256 byte pagesize fallback to software ECC */ - switch (ecc->mode) { - case NAND_ECC_HW: + switch (ecc->engine_type) { + case NAND_ECC_ENGINE_TYPE_ON_HOST: + switch (ecc->placement) { case NAND_ECC_PLACEMENT_UNKNOWN: case NAND_ECC_PLACEMENT_OOB: @@ -5854,11 +5874,11 @@ static int nand_scan_tail(struct nand_chip *chip) } pr_warn("%d byte HW ECC not possible on %d byte page size, fallback to SW ECC\n", ecc->size, mtd->writesize); - ecc->mode = NAND_ECC_SOFT; + ecc->engine_type = NAND_ECC_ENGINE_TYPE_SOFT; ecc->algo = NAND_ECC_ALGO_HAMMING; fallthrough; - case NAND_ECC_SOFT: + case NAND_ECC_ENGINE_TYPE_SOFT: ret = nand_set_ecc_soft_ops(chip); if (ret) { ret = -EINVAL; @@ -5866,7 +5886,7 @@ static int nand_scan_tail(struct nand_chip *chip) } break; - case NAND_ECC_ON_DIE: + case NAND_ECC_ENGINE_TYPE_ON_DIE: if (!ecc->read_page || !ecc->write_page) { WARN(1, "No ECC functions supplied; on-die ECC not possible\n"); ret = -EINVAL; @@ -5878,8 +5898,8 @@ static int nand_scan_tail(struct nand_chip *chip) ecc->write_oob = nand_write_oob_std; break; - case NAND_ECC_NONE: - pr_warn("NAND_ECC_NONE selected by board driver. This is not recommended!\n"); + case NAND_ECC_ENGINE_TYPE_NONE: + pr_warn("NAND_ECC_ENGINE_TYPE_NONE selected by board driver. This is not recommended!\n"); ecc->read_page = nand_read_page_raw; ecc->write_page = nand_write_page_raw; ecc->read_oob = nand_read_oob_std; @@ -5892,7 +5912,7 @@ static int nand_scan_tail(struct nand_chip *chip) break; default: - WARN(1, "Invalid NAND_ECC_MODE %d\n", ecc->mode); + WARN(1, "Invalid NAND_ECC_MODE %d\n", ecc->engine_type); ret = -EINVAL; goto err_nand_manuf_cleanup; } @@ -5969,8 +5989,8 @@ static int nand_scan_tail(struct nand_chip *chip) chip->pagecache.page = -1; /* Large page NAND with SOFT_ECC should support subpage reads */ - switch (ecc->mode) { - case NAND_ECC_SOFT: + switch (ecc->engine_type) { + case NAND_ECC_ENGINE_TYPE_SOFT: if (chip->page_shift > 9) chip->options |= NAND_SUBPAGE_READ; break; @@ -6114,7 +6134,7 @@ EXPORT_SYMBOL(nand_scan_with_ids); */ void nand_cleanup(struct nand_chip *chip) { - if (chip->ecc.mode == NAND_ECC_SOFT && + if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_SOFT && chip->ecc.algo == NAND_ECC_ALGO_BCH) nand_bch_free((struct nand_bch_control *)chip->ecc.priv); |