aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/nand_ecc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand/nand_ecc.c')
-rw-r--r--drivers/mtd/nand/nand_ecc.c29
1 files changed, 12 insertions, 17 deletions
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c
index 40ac909150a3..101892985b02 100644
--- a/drivers/mtd/nand/nand_ecc.c
+++ b/drivers/mtd/nand/nand_ecc.c
@@ -62,7 +62,6 @@ static const u_char nand_ecc_precalc_table[] = {
62 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00 62 0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00
63}; 63};
64 64
65
66/** 65/**
67 * nand_trans_result - [GENERIC] create non-inverted ECC 66 * nand_trans_result - [GENERIC] create non-inverted ECC
68 * @reg2: line parity reg 2 67 * @reg2: line parity reg 2
@@ -71,8 +70,7 @@ static const u_char nand_ecc_precalc_table[] = {
71 * 70 *
72 * Creates non-inverted ECC code from line parity 71 * Creates non-inverted ECC code from line parity
73 */ 72 */
74static void nand_trans_result(u_char reg2, u_char reg3, 73static void nand_trans_result(u_char reg2, u_char reg3, u_char *ecc_code)
75 u_char *ecc_code)
76{ 74{
77 u_char a, b, i, tmp1, tmp2; 75 u_char a, b, i, tmp1, tmp2;
78 76
@@ -82,10 +80,10 @@ static void nand_trans_result(u_char reg2, u_char reg3,
82 80
83 /* Calculate first ECC byte */ 81 /* Calculate first ECC byte */
84 for (i = 0; i < 4; i++) { 82 for (i = 0; i < 4; i++) {
85 if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */ 83 if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */
86 tmp1 |= b; 84 tmp1 |= b;
87 b >>= 1; 85 b >>= 1;
88 if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */ 86 if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */
89 tmp1 |= b; 87 tmp1 |= b;
90 b >>= 1; 88 b >>= 1;
91 a >>= 1; 89 a >>= 1;
@@ -94,10 +92,10 @@ static void nand_trans_result(u_char reg2, u_char reg3,
94 /* Calculate second ECC byte */ 92 /* Calculate second ECC byte */
95 b = 0x80; 93 b = 0x80;
96 for (i = 0; i < 4; i++) { 94 for (i = 0; i < 4; i++) {
97 if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */ 95 if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */
98 tmp2 |= b; 96 tmp2 |= b;
99 b >>= 1; 97 b >>= 1;
100 if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */ 98 if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */
101 tmp2 |= b; 99 tmp2 |= b;
102 b >>= 1; 100 b >>= 1;
103 a >>= 1; 101 a >>= 1;
@@ -124,7 +122,7 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code
124 ecc_code[0] = ecc_code[1] = ecc_code[2] = 0; 122 ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
125 123
126 /* Build up column parity */ 124 /* Build up column parity */
127 for(j = 0; j < 256; j++) { 125 for (j = 0; j < 256; j++) {
128 126
129 /* Get CP0 - CP5 from table */ 127 /* Get CP0 - CP5 from table */
130 idx = nand_ecc_precalc_table[dat[j]]; 128 idx = nand_ecc_precalc_table[dat[j]];
@@ -168,8 +166,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
168 if ((d1 | d2 | d3) == 0) { 166 if ((d1 | d2 | d3) == 0) {
169 /* No errors */ 167 /* No errors */
170 return 0; 168 return 0;
171 } 169 } else {
172 else {
173 a = (d1 ^ (d1 >> 1)) & 0x55; 170 a = (d1 ^ (d1 >> 1)) & 0x55;
174 b = (d2 ^ (d2 >> 1)) & 0x55; 171 b = (d2 ^ (d2 >> 1)) & 0x55;
175 c = (d3 ^ (d3 >> 1)) & 0x54; 172 c = (d3 ^ (d3 >> 1)) & 0x54;
@@ -179,14 +176,14 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
179 c = 0x80; 176 c = 0x80;
180 add = 0; 177 add = 0;
181 a = 0x80; 178 a = 0x80;
182 for (i=0; i<4; i++) { 179 for (i = 0; i < 4; i++) {
183 if (d1 & c) 180 if (d1 & c)
184 add |= a; 181 add |= a;
185 c >>= 2; 182 c >>= 2;
186 a >>= 1; 183 a >>= 1;
187 } 184 }
188 c = 0x80; 185 c = 0x80;
189 for (i=0; i<4; i++) { 186 for (i = 0; i < 4; i++) {
190 if (d2 & c) 187 if (d2 & c)
191 add |= a; 188 add |= a;
192 c >>= 2; 189 c >>= 2;
@@ -195,7 +192,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
195 bit = 0; 192 bit = 0;
196 b = 0x04; 193 b = 0x04;
197 c = 0x80; 194 c = 0x80;
198 for (i=0; i<3; i++) { 195 for (i = 0; i < 3; i++) {
199 if (d3 & c) 196 if (d3 & c)
200 bit |= b; 197 bit |= b;
201 c >>= 2; 198 c >>= 2;
@@ -206,8 +203,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
206 a ^= (b << bit); 203 a ^= (b << bit);
207 dat[add] = a; 204 dat[add] = a;
208 return 1; 205 return 1;
209 } 206 } else {
210 else {
211 i = 0; 207 i = 0;
212 while (d1) { 208 while (d1) {
213 if (d1 & 0x01) 209 if (d1 & 0x01)
@@ -230,8 +226,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
230 read_ecc[1] = calc_ecc[1]; 226 read_ecc[1] = calc_ecc[1];
231 read_ecc[2] = calc_ecc[2]; 227 read_ecc[2] = calc_ecc[2];
232 return 2; 228 return 2;
233 } 229 } else {
234 else {
235 /* Uncorrectable Error */ 230 /* Uncorrectable Error */
236 return -1; 231 return -1;
237 } 232 }