diff options
author | Huang Shijie <b32955@freescale.com> | 2013-01-28 20:23:38 -0500 |
---|---|---|
committer | Artem Bityutskiy <artem.bityutskiy@linux.intel.com> | 2013-02-04 03:28:02 -0500 |
commit | 92d0e09abeebdd3f699c9f12401a9e3998a20546 (patch) | |
tree | fa51378318368e5dd1471e2f82b061e007dfb6f8 | |
parent | 9ff16f0833806b6b59aaf0cc158fa6e42f24d7e4 (diff) |
mtd: gpmi: add sanity check for the ECC
We do the check based on the following two facts:
[1] The mx23/mx28 can only support 20-bits ECC, while the mx6
can supports 40-bits ECC.
[2] The mx23/mx28 can only support the GF13, while the mx6
can supports GF13 and GF14.
Signed-off-by: Huang Shijie <b32955@freescale.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com>
-rw-r--r-- | drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 28 | ||||
-rw-r--r-- | drivers/mtd/nand/gpmi-nand/gpmi-nand.h | 4 |
2 files changed, 30 insertions, 2 deletions
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index 25216785f180..717881a3d1b8 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c | |||
@@ -94,6 +94,25 @@ static inline int get_ecc_strength(struct gpmi_nand_data *this) | |||
94 | return round_down(ecc_strength, 2); | 94 | return round_down(ecc_strength, 2); |
95 | } | 95 | } |
96 | 96 | ||
97 | static inline bool gpmi_check_ecc(struct gpmi_nand_data *this) | ||
98 | { | ||
99 | struct bch_geometry *geo = &this->bch_geometry; | ||
100 | |||
101 | /* Do the sanity check. */ | ||
102 | if (GPMI_IS_MX23(this) || GPMI_IS_MX28(this)) { | ||
103 | /* The mx23/mx28 only support the GF13. */ | ||
104 | if (geo->gf_len == 14) | ||
105 | return false; | ||
106 | |||
107 | if (geo->ecc_strength > MXS_ECC_STRENGTH_MAX) | ||
108 | return false; | ||
109 | } else if (GPMI_IS_MX6Q(this)) { | ||
110 | if (geo->ecc_strength > MX6_ECC_STRENGTH_MAX) | ||
111 | return false; | ||
112 | } | ||
113 | return true; | ||
114 | } | ||
115 | |||
97 | int common_nfc_set_geometry(struct gpmi_nand_data *this) | 116 | int common_nfc_set_geometry(struct gpmi_nand_data *this) |
98 | { | 117 | { |
99 | struct bch_geometry *geo = &this->bch_geometry; | 118 | struct bch_geometry *geo = &this->bch_geometry; |
@@ -123,8 +142,13 @@ int common_nfc_set_geometry(struct gpmi_nand_data *this) | |||
123 | 142 | ||
124 | /* We use the same ECC strength for all chunks. */ | 143 | /* We use the same ECC strength for all chunks. */ |
125 | geo->ecc_strength = get_ecc_strength(this); | 144 | geo->ecc_strength = get_ecc_strength(this); |
126 | if (!geo->ecc_strength) { | 145 | if (!gpmi_check_ecc(this)) { |
127 | pr_err("wrong ECC strength.\n"); | 146 | dev_err(this->dev, |
147 | "We can not support this nand chip." | ||
148 | " Its required ecc strength(%d) is beyond our" | ||
149 | " capability(%d).\n", geo->ecc_strength, | ||
150 | (GPMI_IS_MX6Q(this) ? MX6_ECC_STRENGTH_MAX | ||
151 | : MXS_ECC_STRENGTH_MAX)); | ||
128 | return -EINVAL; | 152 | return -EINVAL; |
129 | } | 153 | } |
130 | 154 | ||
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h index 3d93a5e39090..072947731277 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h | |||
@@ -284,6 +284,10 @@ extern int gpmi_read_page(struct gpmi_nand_data *, | |||
284 | #define STATUS_ERASED 0xff | 284 | #define STATUS_ERASED 0xff |
285 | #define STATUS_UNCORRECTABLE 0xfe | 285 | #define STATUS_UNCORRECTABLE 0xfe |
286 | 286 | ||
287 | /* BCH's bit correction capability. */ | ||
288 | #define MXS_ECC_STRENGTH_MAX 20 /* mx23 and mx28 */ | ||
289 | #define MX6_ECC_STRENGTH_MAX 40 | ||
290 | |||
287 | /* Use the platform_id to distinguish different Archs. */ | 291 | /* Use the platform_id to distinguish different Archs. */ |
288 | #define IS_MX23 0x0 | 292 | #define IS_MX23 0x0 |
289 | #define IS_MX28 0x1 | 293 | #define IS_MX28 0x1 |