Skip to content

Commit d7157ff

Browse files
committed
mtd: rawnand: Use the ECC framework user input parsing bits
Many helpers are generic to all NAND chips, they should not be raw-NAND specific, so use the generic ones. To avoid moving all the raw NAND core "history" into the generic NAND layer, we keep a part of this parsing in the raw NAND core to ensure backward compatibility. Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com> Link: https://lore.kernel.org/linux-mtd/20200827085208.16276-20-miquel.raynal@bootlin.com
1 parent 8c12672 commit d7157ff

File tree

2 files changed

+70
-84
lines changed

2 files changed

+70
-84
lines changed

drivers/mtd/nand/raw/nand_base.c

Lines changed: 70 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -4877,18 +4877,27 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
48774877
return ret;
48784878
}
48794879

4880-
static const char * const nand_ecc_modes[] = {
4881-
[NAND_ECC_NONE] = "none",
4882-
[NAND_ECC_SOFT] = "soft",
4883-
[NAND_ECC_HW] = "hw",
4884-
[NAND_ECC_HW_SYNDROME] = "hw_syndrome",
4885-
[NAND_ECC_ON_DIE] = "on-die",
4886-
};
4887-
48884880
static enum nand_ecc_engine_type
4889-
of_get_nand_ecc_engine_type(struct device_node *np)
4890-
{
4891-
enum nand_ecc_mode eng_type;
4881+
of_get_rawnand_ecc_engine_type_legacy(struct device_node *np)
4882+
{
4883+
enum nand_ecc_legacy_mode {
4884+
NAND_ECC_INVALID,
4885+
NAND_ECC_NONE,
4886+
NAND_ECC_SOFT,
4887+
NAND_ECC_SOFT_BCH,
4888+
NAND_ECC_HW,
4889+
NAND_ECC_HW_SYNDROME,
4890+
NAND_ECC_ON_DIE,
4891+
};
4892+
const char * const nand_ecc_legacy_modes[] = {
4893+
[NAND_ECC_NONE] = "none",
4894+
[NAND_ECC_SOFT] = "soft",
4895+
[NAND_ECC_SOFT_BCH] = "soft_bch",
4896+
[NAND_ECC_HW] = "hw",
4897+
[NAND_ECC_HW_SYNDROME] = "hw_syndrome",
4898+
[NAND_ECC_ON_DIE] = "on-die",
4899+
};
4900+
enum nand_ecc_legacy_mode eng_type;
48924901
const char *pm;
48934902
int err;
48944903

@@ -4897,12 +4906,13 @@ of_get_nand_ecc_engine_type(struct device_node *np)
48974906
return NAND_ECC_ENGINE_TYPE_INVALID;
48984907

48994908
for (eng_type = NAND_ECC_NONE;
4900-
eng_type < ARRAY_SIZE(nand_ecc_modes); eng_type++) {
4901-
if (!strcasecmp(pm, nand_ecc_modes[eng_type])) {
4909+
eng_type < ARRAY_SIZE(nand_ecc_legacy_modes); eng_type++) {
4910+
if (!strcasecmp(pm, nand_ecc_legacy_modes[eng_type])) {
49024911
switch (eng_type) {
49034912
case NAND_ECC_NONE:
49044913
return NAND_ECC_ENGINE_TYPE_NONE;
49054914
case NAND_ECC_SOFT:
4915+
case NAND_ECC_SOFT_BCH:
49064916
return NAND_ECC_ENGINE_TYPE_SOFT;
49074917
case NAND_ECC_HW:
49084918
case NAND_ECC_HW_SYNDROME:
@@ -4915,43 +4925,29 @@ of_get_nand_ecc_engine_type(struct device_node *np)
49154925
}
49164926
}
49174927

4918-
/*
4919-
* For backward compatibility we support few obsoleted values that don't
4920-
* have their mappings into the nand_ecc_engine_providers enum anymore
4921-
* (they were merged with other enums).
4922-
*/
4923-
if (!strcasecmp(pm, "soft_bch"))
4924-
return NAND_ECC_ENGINE_TYPE_SOFT;
4925-
49264928
return NAND_ECC_ENGINE_TYPE_INVALID;
49274929
}
49284930

4929-
static const char * const nand_ecc_algos[] = {
4930-
[NAND_ECC_ALGO_HAMMING] = "hamming",
4931-
[NAND_ECC_ALGO_BCH] = "bch",
4932-
[NAND_ECC_ALGO_RS] = "rs",
4933-
};
4934-
4935-
static enum nand_ecc_algo of_get_nand_ecc_algo(struct device_node *np)
4931+
static enum nand_ecc_placement
4932+
of_get_rawnand_ecc_placement_legacy(struct device_node *np)
49364933
{
4937-
enum nand_ecc_algo ecc_algo;
49384934
const char *pm;
49394935
int err;
49404936

4941-
err = of_property_read_string(np, "nand-ecc-algo", &pm);
4937+
err = of_property_read_string(np, "nand-ecc-mode", &pm);
49424938
if (!err) {
4943-
for (ecc_algo = NAND_ECC_ALGO_HAMMING;
4944-
ecc_algo < ARRAY_SIZE(nand_ecc_algos);
4945-
ecc_algo++) {
4946-
if (!strcasecmp(pm, nand_ecc_algos[ecc_algo]))
4947-
return ecc_algo;
4948-
}
4939+
if (!strcasecmp(pm, "hw_syndrome"))
4940+
return NAND_ECC_PLACEMENT_INTERLEAVED;
49494941
}
49504942

4951-
/*
4952-
* For backward compatibility we also read "nand-ecc-mode" checking
4953-
* for some obsoleted values that were specifying ECC algorithm.
4954-
*/
4943+
return NAND_ECC_PLACEMENT_UNKNOWN;
4944+
}
4945+
4946+
static enum nand_ecc_algo of_get_rawnand_ecc_algo_legacy(struct device_node *np)
4947+
{
4948+
const char *pm;
4949+
int err;
4950+
49554951
err = of_property_read_string(np, "nand-ecc-mode", &pm);
49564952
if (!err) {
49574953
if (!strcasecmp(pm, "soft"))
@@ -4963,22 +4959,19 @@ static enum nand_ecc_algo of_get_nand_ecc_algo(struct device_node *np)
49634959
return NAND_ECC_ALGO_UNKNOWN;
49644960
}
49654961

4966-
static int of_get_nand_ecc_step_size(struct device_node *np)
4962+
static void of_get_nand_ecc_legacy_user_config(struct nand_chip *chip)
49674963
{
4968-
int ret;
4969-
u32 val;
4964+
struct device_node *dn = nand_get_flash_node(chip);
4965+
struct nand_ecc_props *user_conf = &chip->base.ecc.user_conf;
49704966

4971-
ret = of_property_read_u32(np, "nand-ecc-step-size", &val);
4972-
return ret ? ret : val;
4973-
}
4967+
if (user_conf->engine_type == NAND_ECC_ENGINE_TYPE_INVALID)
4968+
user_conf->engine_type = of_get_rawnand_ecc_engine_type_legacy(dn);
49744969

4975-
static int of_get_nand_ecc_strength(struct device_node *np)
4976-
{
4977-
int ret;
4978-
u32 val;
4970+
if (user_conf->algo == NAND_ECC_ALGO_UNKNOWN)
4971+
user_conf->algo = of_get_rawnand_ecc_algo_legacy(dn);
49794972

4980-
ret = of_property_read_u32(np, "nand-ecc-strength", &val);
4981-
return ret ? ret : val;
4973+
if (user_conf->placement == NAND_ECC_PLACEMENT_UNKNOWN)
4974+
user_conf->placement = of_get_rawnand_ecc_placement_legacy(dn);
49824975
}
49834976

49844977
static int of_get_nand_bus_width(struct device_node *np)
@@ -5002,12 +4995,10 @@ static bool of_get_nand_on_flash_bbt(struct device_node *np)
50024995
return of_property_read_bool(np, "nand-on-flash-bbt");
50034996
}
50044997

5005-
static int nand_dt_init(struct nand_chip *chip)
4998+
static int rawnand_dt_init(struct nand_chip *chip)
50064999
{
5000+
struct nand_device *nand = mtd_to_nanddev(nand_to_mtd(chip));
50075001
struct device_node *dn = nand_get_flash_node(chip);
5008-
enum nand_ecc_engine_type ecc_type;
5009-
enum nand_ecc_algo ecc_algo;
5010-
int ecc_strength, ecc_step;
50115002

50125003
if (!dn)
50135004
return 0;
@@ -5021,25 +5012,32 @@ static int nand_dt_init(struct nand_chip *chip)
50215012
if (of_get_nand_on_flash_bbt(dn))
50225013
chip->bbt_options |= NAND_BBT_USE_FLASH;
50235014

5024-
ecc_type = of_get_nand_ecc_engine_type(dn);
5025-
ecc_algo = of_get_nand_ecc_algo(dn);
5026-
ecc_strength = of_get_nand_ecc_strength(dn);
5027-
ecc_step = of_get_nand_ecc_step_size(dn);
5028-
5029-
if (ecc_type != NAND_ECC_ENGINE_TYPE_INVALID)
5030-
chip->ecc.engine_type = ecc_type;
5015+
if (of_property_read_bool(dn, "nand-ecc-maximize"))
5016+
chip->ecc.options |= NAND_ECC_MAXIMIZE;
50315017

5032-
if (ecc_algo != NAND_ECC_ALGO_UNKNOWN)
5033-
chip->ecc.algo = ecc_algo;
5018+
of_get_nand_ecc_user_config(nand);
5019+
of_get_nand_ecc_legacy_user_config(chip);
50345020

5035-
if (ecc_strength >= 0)
5036-
chip->ecc.strength = ecc_strength;
5021+
/*
5022+
* If neither the user nor the NAND controller have requested a specific
5023+
* ECC engine type, we will default to NAND_ECC_ENGINE_TYPE_ON_HOST.
5024+
*/
5025+
nand->ecc.defaults.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST;
50375026

5038-
if (ecc_step > 0)
5039-
chip->ecc.size = ecc_step;
5027+
/*
5028+
* Use the user requested engine type, unless there is none, in this
5029+
* case default to the NAND controller choice, otherwise fallback to
5030+
* the raw NAND default one.
5031+
*/
5032+
if (nand->ecc.user_conf.engine_type != NAND_ECC_ENGINE_TYPE_INVALID)
5033+
chip->ecc.engine_type = nand->ecc.user_conf.engine_type;
5034+
if (chip->ecc.engine_type == NAND_ECC_ENGINE_TYPE_INVALID)
5035+
chip->ecc.engine_type = nand->ecc.defaults.engine_type;
50405036

5041-
if (of_property_read_bool(dn, "nand-ecc-maximize"))
5042-
chip->ecc.options |= NAND_ECC_MAXIMIZE;
5037+
chip->ecc.placement = nand->ecc.user_conf.placement;
5038+
chip->ecc.algo = nand->ecc.user_conf.algo;
5039+
chip->ecc.strength = nand->ecc.user_conf.strength;
5040+
chip->ecc.size = nand->ecc.user_conf.step_size;
50435041

50445042
return 0;
50455043
}
@@ -5077,7 +5075,7 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips,
50775075
/* Enforce the right timings for reset/detection */
50785076
chip->current_interface_config = nand_get_reset_interface_config();
50795077

5080-
ret = nand_dt_init(chip);
5078+
ret = rawnand_dt_init(chip);
50815079
if (ret)
50825080
return ret;
50835081

include/linux/mtd/rawnand.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -81,18 +81,6 @@ struct nand_chip;
8181

8282
#define NAND_DATA_IFACE_CHECK_ONLY -1
8383

84-
/*
85-
* Constants for ECC_MODES
86-
*/
87-
enum nand_ecc_mode {
88-
NAND_ECC_INVALID,
89-
NAND_ECC_NONE,
90-
NAND_ECC_SOFT,
91-
NAND_ECC_HW,
92-
NAND_ECC_HW_SYNDROME,
93-
NAND_ECC_ON_DIE,
94-
};
95-
9684
/*
9785
* Constants for Hardware ECC
9886
*/

0 commit comments

Comments
 (0)