Commit 725a2277f8b537a932bffb4c4bb2288d05c84a74
Committed by
David Woodhouse
1 parent
a6fb35d379
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
mtd: doc: use module_platform_driver_probe()
This patch uses module_platform_driver_probe() macro which makes the code smaller and simpler. Signed-off-by: Jingoo Han <jg1.han@samsung.com> Signed-off-by: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Showing 2 changed files with 2 additions and 24 deletions Inline Diff
drivers/mtd/devices/docg3.c
1 | /* | 1 | /* |
2 | * Handles the M-Systems DiskOnChip G3 chip | 2 | * Handles the M-Systems DiskOnChip G3 chip |
3 | * | 3 | * |
4 | * Copyright (C) 2011 Robert Jarzmik | 4 | * Copyright (C) 2011 Robert Jarzmik |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License, or | 8 | * the Free Software Foundation; either version 2 of the License, or |
9 | * (at your option) any later version. | 9 | * (at your option) any later version. |
10 | * | 10 | * |
11 | * This program is distributed in the hope that it will be useful, | 11 | * This program is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * You should have received a copy of the GNU General Public License |
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | * | 19 | * |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/kernel.h> | 22 | #include <linux/kernel.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
26 | #include <linux/string.h> | 26 | #include <linux/string.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/io.h> | 28 | #include <linux/io.h> |
29 | #include <linux/delay.h> | 29 | #include <linux/delay.h> |
30 | #include <linux/mtd/mtd.h> | 30 | #include <linux/mtd/mtd.h> |
31 | #include <linux/mtd/partitions.h> | 31 | #include <linux/mtd/partitions.h> |
32 | #include <linux/bitmap.h> | 32 | #include <linux/bitmap.h> |
33 | #include <linux/bitrev.h> | 33 | #include <linux/bitrev.h> |
34 | #include <linux/bch.h> | 34 | #include <linux/bch.h> |
35 | 35 | ||
36 | #include <linux/debugfs.h> | 36 | #include <linux/debugfs.h> |
37 | #include <linux/seq_file.h> | 37 | #include <linux/seq_file.h> |
38 | 38 | ||
39 | #define CREATE_TRACE_POINTS | 39 | #define CREATE_TRACE_POINTS |
40 | #include "docg3.h" | 40 | #include "docg3.h" |
41 | 41 | ||
42 | /* | 42 | /* |
43 | * This driver handles the DiskOnChip G3 flash memory. | 43 | * This driver handles the DiskOnChip G3 flash memory. |
44 | * | 44 | * |
45 | * As no specification is available from M-Systems/Sandisk, this drivers lacks | 45 | * As no specification is available from M-Systems/Sandisk, this drivers lacks |
46 | * several functions available on the chip, as : | 46 | * several functions available on the chip, as : |
47 | * - IPL write | 47 | * - IPL write |
48 | * | 48 | * |
49 | * The bus data width (8bits versus 16bits) is not handled (if_cfg flag), and | 49 | * The bus data width (8bits versus 16bits) is not handled (if_cfg flag), and |
50 | * the driver assumes a 16bits data bus. | 50 | * the driver assumes a 16bits data bus. |
51 | * | 51 | * |
52 | * DocG3 relies on 2 ECC algorithms, which are handled in hardware : | 52 | * DocG3 relies on 2 ECC algorithms, which are handled in hardware : |
53 | * - a 1 byte Hamming code stored in the OOB for each page | 53 | * - a 1 byte Hamming code stored in the OOB for each page |
54 | * - a 7 bytes BCH code stored in the OOB for each page | 54 | * - a 7 bytes BCH code stored in the OOB for each page |
55 | * The BCH ECC is : | 55 | * The BCH ECC is : |
56 | * - BCH is in GF(2^14) | 56 | * - BCH is in GF(2^14) |
57 | * - BCH is over data of 520 bytes (512 page + 7 page_info bytes | 57 | * - BCH is over data of 520 bytes (512 page + 7 page_info bytes |
58 | * + 1 hamming byte) | 58 | * + 1 hamming byte) |
59 | * - BCH can correct up to 4 bits (t = 4) | 59 | * - BCH can correct up to 4 bits (t = 4) |
60 | * - BCH syndroms are calculated in hardware, and checked in hardware as well | 60 | * - BCH syndroms are calculated in hardware, and checked in hardware as well |
61 | * | 61 | * |
62 | */ | 62 | */ |
63 | 63 | ||
64 | static unsigned int reliable_mode; | 64 | static unsigned int reliable_mode; |
65 | module_param(reliable_mode, uint, 0); | 65 | module_param(reliable_mode, uint, 0); |
66 | MODULE_PARM_DESC(reliable_mode, "Set the docg3 mode (0=normal MLC, 1=fast, " | 66 | MODULE_PARM_DESC(reliable_mode, "Set the docg3 mode (0=normal MLC, 1=fast, " |
67 | "2=reliable) : MLC normal operations are in normal mode"); | 67 | "2=reliable) : MLC normal operations are in normal mode"); |
68 | 68 | ||
69 | /** | 69 | /** |
70 | * struct docg3_oobinfo - DiskOnChip G3 OOB layout | 70 | * struct docg3_oobinfo - DiskOnChip G3 OOB layout |
71 | * @eccbytes: 8 bytes are used (1 for Hamming ECC, 7 for BCH ECC) | 71 | * @eccbytes: 8 bytes are used (1 for Hamming ECC, 7 for BCH ECC) |
72 | * @eccpos: ecc positions (byte 7 is Hamming ECC, byte 8-14 are BCH ECC) | 72 | * @eccpos: ecc positions (byte 7 is Hamming ECC, byte 8-14 are BCH ECC) |
73 | * @oobfree: free pageinfo bytes (byte 0 until byte 6, byte 15 | 73 | * @oobfree: free pageinfo bytes (byte 0 until byte 6, byte 15 |
74 | * @oobavail: 8 available bytes remaining after ECC toll | 74 | * @oobavail: 8 available bytes remaining after ECC toll |
75 | */ | 75 | */ |
76 | static struct nand_ecclayout docg3_oobinfo = { | 76 | static struct nand_ecclayout docg3_oobinfo = { |
77 | .eccbytes = 8, | 77 | .eccbytes = 8, |
78 | .eccpos = {7, 8, 9, 10, 11, 12, 13, 14}, | 78 | .eccpos = {7, 8, 9, 10, 11, 12, 13, 14}, |
79 | .oobfree = {{0, 7}, {15, 1} }, | 79 | .oobfree = {{0, 7}, {15, 1} }, |
80 | .oobavail = 8, | 80 | .oobavail = 8, |
81 | }; | 81 | }; |
82 | 82 | ||
83 | static inline u8 doc_readb(struct docg3 *docg3, u16 reg) | 83 | static inline u8 doc_readb(struct docg3 *docg3, u16 reg) |
84 | { | 84 | { |
85 | u8 val = readb(docg3->cascade->base + reg); | 85 | u8 val = readb(docg3->cascade->base + reg); |
86 | 86 | ||
87 | trace_docg3_io(0, 8, reg, (int)val); | 87 | trace_docg3_io(0, 8, reg, (int)val); |
88 | return val; | 88 | return val; |
89 | } | 89 | } |
90 | 90 | ||
91 | static inline u16 doc_readw(struct docg3 *docg3, u16 reg) | 91 | static inline u16 doc_readw(struct docg3 *docg3, u16 reg) |
92 | { | 92 | { |
93 | u16 val = readw(docg3->cascade->base + reg); | 93 | u16 val = readw(docg3->cascade->base + reg); |
94 | 94 | ||
95 | trace_docg3_io(0, 16, reg, (int)val); | 95 | trace_docg3_io(0, 16, reg, (int)val); |
96 | return val; | 96 | return val; |
97 | } | 97 | } |
98 | 98 | ||
99 | static inline void doc_writeb(struct docg3 *docg3, u8 val, u16 reg) | 99 | static inline void doc_writeb(struct docg3 *docg3, u8 val, u16 reg) |
100 | { | 100 | { |
101 | writeb(val, docg3->cascade->base + reg); | 101 | writeb(val, docg3->cascade->base + reg); |
102 | trace_docg3_io(1, 8, reg, val); | 102 | trace_docg3_io(1, 8, reg, val); |
103 | } | 103 | } |
104 | 104 | ||
105 | static inline void doc_writew(struct docg3 *docg3, u16 val, u16 reg) | 105 | static inline void doc_writew(struct docg3 *docg3, u16 val, u16 reg) |
106 | { | 106 | { |
107 | writew(val, docg3->cascade->base + reg); | 107 | writew(val, docg3->cascade->base + reg); |
108 | trace_docg3_io(1, 16, reg, val); | 108 | trace_docg3_io(1, 16, reg, val); |
109 | } | 109 | } |
110 | 110 | ||
111 | static inline void doc_flash_command(struct docg3 *docg3, u8 cmd) | 111 | static inline void doc_flash_command(struct docg3 *docg3, u8 cmd) |
112 | { | 112 | { |
113 | doc_writeb(docg3, cmd, DOC_FLASHCOMMAND); | 113 | doc_writeb(docg3, cmd, DOC_FLASHCOMMAND); |
114 | } | 114 | } |
115 | 115 | ||
116 | static inline void doc_flash_sequence(struct docg3 *docg3, u8 seq) | 116 | static inline void doc_flash_sequence(struct docg3 *docg3, u8 seq) |
117 | { | 117 | { |
118 | doc_writeb(docg3, seq, DOC_FLASHSEQUENCE); | 118 | doc_writeb(docg3, seq, DOC_FLASHSEQUENCE); |
119 | } | 119 | } |
120 | 120 | ||
121 | static inline void doc_flash_address(struct docg3 *docg3, u8 addr) | 121 | static inline void doc_flash_address(struct docg3 *docg3, u8 addr) |
122 | { | 122 | { |
123 | doc_writeb(docg3, addr, DOC_FLASHADDRESS); | 123 | doc_writeb(docg3, addr, DOC_FLASHADDRESS); |
124 | } | 124 | } |
125 | 125 | ||
126 | static char const * const part_probes[] = { "cmdlinepart", "saftlpart", NULL }; | 126 | static char const * const part_probes[] = { "cmdlinepart", "saftlpart", NULL }; |
127 | 127 | ||
128 | static int doc_register_readb(struct docg3 *docg3, int reg) | 128 | static int doc_register_readb(struct docg3 *docg3, int reg) |
129 | { | 129 | { |
130 | u8 val; | 130 | u8 val; |
131 | 131 | ||
132 | doc_writew(docg3, reg, DOC_READADDRESS); | 132 | doc_writew(docg3, reg, DOC_READADDRESS); |
133 | val = doc_readb(docg3, reg); | 133 | val = doc_readb(docg3, reg); |
134 | doc_vdbg("Read register %04x : %02x\n", reg, val); | 134 | doc_vdbg("Read register %04x : %02x\n", reg, val); |
135 | return val; | 135 | return val; |
136 | } | 136 | } |
137 | 137 | ||
138 | static int doc_register_readw(struct docg3 *docg3, int reg) | 138 | static int doc_register_readw(struct docg3 *docg3, int reg) |
139 | { | 139 | { |
140 | u16 val; | 140 | u16 val; |
141 | 141 | ||
142 | doc_writew(docg3, reg, DOC_READADDRESS); | 142 | doc_writew(docg3, reg, DOC_READADDRESS); |
143 | val = doc_readw(docg3, reg); | 143 | val = doc_readw(docg3, reg); |
144 | doc_vdbg("Read register %04x : %04x\n", reg, val); | 144 | doc_vdbg("Read register %04x : %04x\n", reg, val); |
145 | return val; | 145 | return val; |
146 | } | 146 | } |
147 | 147 | ||
148 | /** | 148 | /** |
149 | * doc_delay - delay docg3 operations | 149 | * doc_delay - delay docg3 operations |
150 | * @docg3: the device | 150 | * @docg3: the device |
151 | * @nbNOPs: the number of NOPs to issue | 151 | * @nbNOPs: the number of NOPs to issue |
152 | * | 152 | * |
153 | * As no specification is available, the right timings between chip commands are | 153 | * As no specification is available, the right timings between chip commands are |
154 | * unknown. The only available piece of information are the observed nops on a | 154 | * unknown. The only available piece of information are the observed nops on a |
155 | * working docg3 chip. | 155 | * working docg3 chip. |
156 | * Therefore, doc_delay relies on a busy loop of NOPs, instead of scheduler | 156 | * Therefore, doc_delay relies on a busy loop of NOPs, instead of scheduler |
157 | * friendlier msleep() functions or blocking mdelay(). | 157 | * friendlier msleep() functions or blocking mdelay(). |
158 | */ | 158 | */ |
159 | static void doc_delay(struct docg3 *docg3, int nbNOPs) | 159 | static void doc_delay(struct docg3 *docg3, int nbNOPs) |
160 | { | 160 | { |
161 | int i; | 161 | int i; |
162 | 162 | ||
163 | doc_vdbg("NOP x %d\n", nbNOPs); | 163 | doc_vdbg("NOP x %d\n", nbNOPs); |
164 | for (i = 0; i < nbNOPs; i++) | 164 | for (i = 0; i < nbNOPs; i++) |
165 | doc_writeb(docg3, 0, DOC_NOP); | 165 | doc_writeb(docg3, 0, DOC_NOP); |
166 | } | 166 | } |
167 | 167 | ||
168 | static int is_prot_seq_error(struct docg3 *docg3) | 168 | static int is_prot_seq_error(struct docg3 *docg3) |
169 | { | 169 | { |
170 | int ctrl; | 170 | int ctrl; |
171 | 171 | ||
172 | ctrl = doc_register_readb(docg3, DOC_FLASHCONTROL); | 172 | ctrl = doc_register_readb(docg3, DOC_FLASHCONTROL); |
173 | return ctrl & (DOC_CTRL_PROTECTION_ERROR | DOC_CTRL_SEQUENCE_ERROR); | 173 | return ctrl & (DOC_CTRL_PROTECTION_ERROR | DOC_CTRL_SEQUENCE_ERROR); |
174 | } | 174 | } |
175 | 175 | ||
176 | static int doc_is_ready(struct docg3 *docg3) | 176 | static int doc_is_ready(struct docg3 *docg3) |
177 | { | 177 | { |
178 | int ctrl; | 178 | int ctrl; |
179 | 179 | ||
180 | ctrl = doc_register_readb(docg3, DOC_FLASHCONTROL); | 180 | ctrl = doc_register_readb(docg3, DOC_FLASHCONTROL); |
181 | return ctrl & DOC_CTRL_FLASHREADY; | 181 | return ctrl & DOC_CTRL_FLASHREADY; |
182 | } | 182 | } |
183 | 183 | ||
184 | static int doc_wait_ready(struct docg3 *docg3) | 184 | static int doc_wait_ready(struct docg3 *docg3) |
185 | { | 185 | { |
186 | int maxWaitCycles = 100; | 186 | int maxWaitCycles = 100; |
187 | 187 | ||
188 | do { | 188 | do { |
189 | doc_delay(docg3, 4); | 189 | doc_delay(docg3, 4); |
190 | cpu_relax(); | 190 | cpu_relax(); |
191 | } while (!doc_is_ready(docg3) && maxWaitCycles--); | 191 | } while (!doc_is_ready(docg3) && maxWaitCycles--); |
192 | doc_delay(docg3, 2); | 192 | doc_delay(docg3, 2); |
193 | if (maxWaitCycles > 0) | 193 | if (maxWaitCycles > 0) |
194 | return 0; | 194 | return 0; |
195 | else | 195 | else |
196 | return -EIO; | 196 | return -EIO; |
197 | } | 197 | } |
198 | 198 | ||
199 | static int doc_reset_seq(struct docg3 *docg3) | 199 | static int doc_reset_seq(struct docg3 *docg3) |
200 | { | 200 | { |
201 | int ret; | 201 | int ret; |
202 | 202 | ||
203 | doc_writeb(docg3, 0x10, DOC_FLASHCONTROL); | 203 | doc_writeb(docg3, 0x10, DOC_FLASHCONTROL); |
204 | doc_flash_sequence(docg3, DOC_SEQ_RESET); | 204 | doc_flash_sequence(docg3, DOC_SEQ_RESET); |
205 | doc_flash_command(docg3, DOC_CMD_RESET); | 205 | doc_flash_command(docg3, DOC_CMD_RESET); |
206 | doc_delay(docg3, 2); | 206 | doc_delay(docg3, 2); |
207 | ret = doc_wait_ready(docg3); | 207 | ret = doc_wait_ready(docg3); |
208 | 208 | ||
209 | doc_dbg("doc_reset_seq() -> isReady=%s\n", ret ? "false" : "true"); | 209 | doc_dbg("doc_reset_seq() -> isReady=%s\n", ret ? "false" : "true"); |
210 | return ret; | 210 | return ret; |
211 | } | 211 | } |
212 | 212 | ||
213 | /** | 213 | /** |
214 | * doc_read_data_area - Read data from data area | 214 | * doc_read_data_area - Read data from data area |
215 | * @docg3: the device | 215 | * @docg3: the device |
216 | * @buf: the buffer to fill in (might be NULL is dummy reads) | 216 | * @buf: the buffer to fill in (might be NULL is dummy reads) |
217 | * @len: the length to read | 217 | * @len: the length to read |
218 | * @first: first time read, DOC_READADDRESS should be set | 218 | * @first: first time read, DOC_READADDRESS should be set |
219 | * | 219 | * |
220 | * Reads bytes from flash data. Handles the single byte / even bytes reads. | 220 | * Reads bytes from flash data. Handles the single byte / even bytes reads. |
221 | */ | 221 | */ |
222 | static void doc_read_data_area(struct docg3 *docg3, void *buf, int len, | 222 | static void doc_read_data_area(struct docg3 *docg3, void *buf, int len, |
223 | int first) | 223 | int first) |
224 | { | 224 | { |
225 | int i, cdr, len4; | 225 | int i, cdr, len4; |
226 | u16 data16, *dst16; | 226 | u16 data16, *dst16; |
227 | u8 data8, *dst8; | 227 | u8 data8, *dst8; |
228 | 228 | ||
229 | doc_dbg("doc_read_data_area(buf=%p, len=%d)\n", buf, len); | 229 | doc_dbg("doc_read_data_area(buf=%p, len=%d)\n", buf, len); |
230 | cdr = len & 0x1; | 230 | cdr = len & 0x1; |
231 | len4 = len - cdr; | 231 | len4 = len - cdr; |
232 | 232 | ||
233 | if (first) | 233 | if (first) |
234 | doc_writew(docg3, DOC_IOSPACE_DATA, DOC_READADDRESS); | 234 | doc_writew(docg3, DOC_IOSPACE_DATA, DOC_READADDRESS); |
235 | dst16 = buf; | 235 | dst16 = buf; |
236 | for (i = 0; i < len4; i += 2) { | 236 | for (i = 0; i < len4; i += 2) { |
237 | data16 = doc_readw(docg3, DOC_IOSPACE_DATA); | 237 | data16 = doc_readw(docg3, DOC_IOSPACE_DATA); |
238 | if (dst16) { | 238 | if (dst16) { |
239 | *dst16 = data16; | 239 | *dst16 = data16; |
240 | dst16++; | 240 | dst16++; |
241 | } | 241 | } |
242 | } | 242 | } |
243 | 243 | ||
244 | if (cdr) { | 244 | if (cdr) { |
245 | doc_writew(docg3, DOC_IOSPACE_DATA | DOC_READADDR_ONE_BYTE, | 245 | doc_writew(docg3, DOC_IOSPACE_DATA | DOC_READADDR_ONE_BYTE, |
246 | DOC_READADDRESS); | 246 | DOC_READADDRESS); |
247 | doc_delay(docg3, 1); | 247 | doc_delay(docg3, 1); |
248 | dst8 = (u8 *)dst16; | 248 | dst8 = (u8 *)dst16; |
249 | for (i = 0; i < cdr; i++) { | 249 | for (i = 0; i < cdr; i++) { |
250 | data8 = doc_readb(docg3, DOC_IOSPACE_DATA); | 250 | data8 = doc_readb(docg3, DOC_IOSPACE_DATA); |
251 | if (dst8) { | 251 | if (dst8) { |
252 | *dst8 = data8; | 252 | *dst8 = data8; |
253 | dst8++; | 253 | dst8++; |
254 | } | 254 | } |
255 | } | 255 | } |
256 | } | 256 | } |
257 | } | 257 | } |
258 | 258 | ||
259 | /** | 259 | /** |
260 | * doc_write_data_area - Write data into data area | 260 | * doc_write_data_area - Write data into data area |
261 | * @docg3: the device | 261 | * @docg3: the device |
262 | * @buf: the buffer to get input bytes from | 262 | * @buf: the buffer to get input bytes from |
263 | * @len: the length to write | 263 | * @len: the length to write |
264 | * | 264 | * |
265 | * Writes bytes into flash data. Handles the single byte / even bytes writes. | 265 | * Writes bytes into flash data. Handles the single byte / even bytes writes. |
266 | */ | 266 | */ |
267 | static void doc_write_data_area(struct docg3 *docg3, const void *buf, int len) | 267 | static void doc_write_data_area(struct docg3 *docg3, const void *buf, int len) |
268 | { | 268 | { |
269 | int i, cdr, len4; | 269 | int i, cdr, len4; |
270 | u16 *src16; | 270 | u16 *src16; |
271 | u8 *src8; | 271 | u8 *src8; |
272 | 272 | ||
273 | doc_dbg("doc_write_data_area(buf=%p, len=%d)\n", buf, len); | 273 | doc_dbg("doc_write_data_area(buf=%p, len=%d)\n", buf, len); |
274 | cdr = len & 0x3; | 274 | cdr = len & 0x3; |
275 | len4 = len - cdr; | 275 | len4 = len - cdr; |
276 | 276 | ||
277 | doc_writew(docg3, DOC_IOSPACE_DATA, DOC_READADDRESS); | 277 | doc_writew(docg3, DOC_IOSPACE_DATA, DOC_READADDRESS); |
278 | src16 = (u16 *)buf; | 278 | src16 = (u16 *)buf; |
279 | for (i = 0; i < len4; i += 2) { | 279 | for (i = 0; i < len4; i += 2) { |
280 | doc_writew(docg3, *src16, DOC_IOSPACE_DATA); | 280 | doc_writew(docg3, *src16, DOC_IOSPACE_DATA); |
281 | src16++; | 281 | src16++; |
282 | } | 282 | } |
283 | 283 | ||
284 | src8 = (u8 *)src16; | 284 | src8 = (u8 *)src16; |
285 | for (i = 0; i < cdr; i++) { | 285 | for (i = 0; i < cdr; i++) { |
286 | doc_writew(docg3, DOC_IOSPACE_DATA | DOC_READADDR_ONE_BYTE, | 286 | doc_writew(docg3, DOC_IOSPACE_DATA | DOC_READADDR_ONE_BYTE, |
287 | DOC_READADDRESS); | 287 | DOC_READADDRESS); |
288 | doc_writeb(docg3, *src8, DOC_IOSPACE_DATA); | 288 | doc_writeb(docg3, *src8, DOC_IOSPACE_DATA); |
289 | src8++; | 289 | src8++; |
290 | } | 290 | } |
291 | } | 291 | } |
292 | 292 | ||
293 | /** | 293 | /** |
294 | * doc_set_data_mode - Sets the flash to normal or reliable data mode | 294 | * doc_set_data_mode - Sets the flash to normal or reliable data mode |
295 | * @docg3: the device | 295 | * @docg3: the device |
296 | * | 296 | * |
297 | * The reliable data mode is a bit slower than the fast mode, but less errors | 297 | * The reliable data mode is a bit slower than the fast mode, but less errors |
298 | * occur. Entering the reliable mode cannot be done without entering the fast | 298 | * occur. Entering the reliable mode cannot be done without entering the fast |
299 | * mode first. | 299 | * mode first. |
300 | * | 300 | * |
301 | * In reliable mode, pages 2*n and 2*n+1 are clones. Writing to page 0 of blocks | 301 | * In reliable mode, pages 2*n and 2*n+1 are clones. Writing to page 0 of blocks |
302 | * (4,5) make the hardware write also to page 1 of blocks blocks(4,5). Reading | 302 | * (4,5) make the hardware write also to page 1 of blocks blocks(4,5). Reading |
303 | * from page 0 of blocks (4,5) or from page 1 of blocks (4,5) gives the same | 303 | * from page 0 of blocks (4,5) or from page 1 of blocks (4,5) gives the same |
304 | * result, which is a logical and between bytes from page 0 and page 1 (which is | 304 | * result, which is a logical and between bytes from page 0 and page 1 (which is |
305 | * consistent with the fact that writing to a page is _clearing_ bits of that | 305 | * consistent with the fact that writing to a page is _clearing_ bits of that |
306 | * page). | 306 | * page). |
307 | */ | 307 | */ |
308 | static void doc_set_reliable_mode(struct docg3 *docg3) | 308 | static void doc_set_reliable_mode(struct docg3 *docg3) |
309 | { | 309 | { |
310 | static char *strmode[] = { "normal", "fast", "reliable", "invalid" }; | 310 | static char *strmode[] = { "normal", "fast", "reliable", "invalid" }; |
311 | 311 | ||
312 | doc_dbg("doc_set_reliable_mode(%s)\n", strmode[docg3->reliable]); | 312 | doc_dbg("doc_set_reliable_mode(%s)\n", strmode[docg3->reliable]); |
313 | switch (docg3->reliable) { | 313 | switch (docg3->reliable) { |
314 | case 0: | 314 | case 0: |
315 | break; | 315 | break; |
316 | case 1: | 316 | case 1: |
317 | doc_flash_sequence(docg3, DOC_SEQ_SET_FASTMODE); | 317 | doc_flash_sequence(docg3, DOC_SEQ_SET_FASTMODE); |
318 | doc_flash_command(docg3, DOC_CMD_FAST_MODE); | 318 | doc_flash_command(docg3, DOC_CMD_FAST_MODE); |
319 | break; | 319 | break; |
320 | case 2: | 320 | case 2: |
321 | doc_flash_sequence(docg3, DOC_SEQ_SET_RELIABLEMODE); | 321 | doc_flash_sequence(docg3, DOC_SEQ_SET_RELIABLEMODE); |
322 | doc_flash_command(docg3, DOC_CMD_FAST_MODE); | 322 | doc_flash_command(docg3, DOC_CMD_FAST_MODE); |
323 | doc_flash_command(docg3, DOC_CMD_RELIABLE_MODE); | 323 | doc_flash_command(docg3, DOC_CMD_RELIABLE_MODE); |
324 | break; | 324 | break; |
325 | default: | 325 | default: |
326 | doc_err("doc_set_reliable_mode(): invalid mode\n"); | 326 | doc_err("doc_set_reliable_mode(): invalid mode\n"); |
327 | break; | 327 | break; |
328 | } | 328 | } |
329 | doc_delay(docg3, 2); | 329 | doc_delay(docg3, 2); |
330 | } | 330 | } |
331 | 331 | ||
332 | /** | 332 | /** |
333 | * doc_set_asic_mode - Set the ASIC mode | 333 | * doc_set_asic_mode - Set the ASIC mode |
334 | * @docg3: the device | 334 | * @docg3: the device |
335 | * @mode: the mode | 335 | * @mode: the mode |
336 | * | 336 | * |
337 | * The ASIC can work in 3 modes : | 337 | * The ASIC can work in 3 modes : |
338 | * - RESET: all registers are zeroed | 338 | * - RESET: all registers are zeroed |
339 | * - NORMAL: receives and handles commands | 339 | * - NORMAL: receives and handles commands |
340 | * - POWERDOWN: minimal poweruse, flash parts shut off | 340 | * - POWERDOWN: minimal poweruse, flash parts shut off |
341 | */ | 341 | */ |
342 | static void doc_set_asic_mode(struct docg3 *docg3, u8 mode) | 342 | static void doc_set_asic_mode(struct docg3 *docg3, u8 mode) |
343 | { | 343 | { |
344 | int i; | 344 | int i; |
345 | 345 | ||
346 | for (i = 0; i < 12; i++) | 346 | for (i = 0; i < 12; i++) |
347 | doc_readb(docg3, DOC_IOSPACE_IPL); | 347 | doc_readb(docg3, DOC_IOSPACE_IPL); |
348 | 348 | ||
349 | mode |= DOC_ASICMODE_MDWREN; | 349 | mode |= DOC_ASICMODE_MDWREN; |
350 | doc_dbg("doc_set_asic_mode(%02x)\n", mode); | 350 | doc_dbg("doc_set_asic_mode(%02x)\n", mode); |
351 | doc_writeb(docg3, mode, DOC_ASICMODE); | 351 | doc_writeb(docg3, mode, DOC_ASICMODE); |
352 | doc_writeb(docg3, ~mode, DOC_ASICMODECONFIRM); | 352 | doc_writeb(docg3, ~mode, DOC_ASICMODECONFIRM); |
353 | doc_delay(docg3, 1); | 353 | doc_delay(docg3, 1); |
354 | } | 354 | } |
355 | 355 | ||
356 | /** | 356 | /** |
357 | * doc_set_device_id - Sets the devices id for cascaded G3 chips | 357 | * doc_set_device_id - Sets the devices id for cascaded G3 chips |
358 | * @docg3: the device | 358 | * @docg3: the device |
359 | * @id: the chip to select (amongst 0, 1, 2, 3) | 359 | * @id: the chip to select (amongst 0, 1, 2, 3) |
360 | * | 360 | * |
361 | * There can be 4 cascaded G3 chips. This function selects the one which will | 361 | * There can be 4 cascaded G3 chips. This function selects the one which will |
362 | * should be the active one. | 362 | * should be the active one. |
363 | */ | 363 | */ |
364 | static void doc_set_device_id(struct docg3 *docg3, int id) | 364 | static void doc_set_device_id(struct docg3 *docg3, int id) |
365 | { | 365 | { |
366 | u8 ctrl; | 366 | u8 ctrl; |
367 | 367 | ||
368 | doc_dbg("doc_set_device_id(%d)\n", id); | 368 | doc_dbg("doc_set_device_id(%d)\n", id); |
369 | doc_writeb(docg3, id, DOC_DEVICESELECT); | 369 | doc_writeb(docg3, id, DOC_DEVICESELECT); |
370 | ctrl = doc_register_readb(docg3, DOC_FLASHCONTROL); | 370 | ctrl = doc_register_readb(docg3, DOC_FLASHCONTROL); |
371 | 371 | ||
372 | ctrl &= ~DOC_CTRL_VIOLATION; | 372 | ctrl &= ~DOC_CTRL_VIOLATION; |
373 | ctrl |= DOC_CTRL_CE; | 373 | ctrl |= DOC_CTRL_CE; |
374 | doc_writeb(docg3, ctrl, DOC_FLASHCONTROL); | 374 | doc_writeb(docg3, ctrl, DOC_FLASHCONTROL); |
375 | } | 375 | } |
376 | 376 | ||
377 | /** | 377 | /** |
378 | * doc_set_extra_page_mode - Change flash page layout | 378 | * doc_set_extra_page_mode - Change flash page layout |
379 | * @docg3: the device | 379 | * @docg3: the device |
380 | * | 380 | * |
381 | * Normally, the flash page is split into the data (512 bytes) and the out of | 381 | * Normally, the flash page is split into the data (512 bytes) and the out of |
382 | * band data (16 bytes). For each, 4 more bytes can be accessed, where the wear | 382 | * band data (16 bytes). For each, 4 more bytes can be accessed, where the wear |
383 | * leveling counters are stored. To access this last area of 4 bytes, a special | 383 | * leveling counters are stored. To access this last area of 4 bytes, a special |
384 | * mode must be input to the flash ASIC. | 384 | * mode must be input to the flash ASIC. |
385 | * | 385 | * |
386 | * Returns 0 if no error occurred, -EIO else. | 386 | * Returns 0 if no error occurred, -EIO else. |
387 | */ | 387 | */ |
388 | static int doc_set_extra_page_mode(struct docg3 *docg3) | 388 | static int doc_set_extra_page_mode(struct docg3 *docg3) |
389 | { | 389 | { |
390 | int fctrl; | 390 | int fctrl; |
391 | 391 | ||
392 | doc_dbg("doc_set_extra_page_mode()\n"); | 392 | doc_dbg("doc_set_extra_page_mode()\n"); |
393 | doc_flash_sequence(docg3, DOC_SEQ_PAGE_SIZE_532); | 393 | doc_flash_sequence(docg3, DOC_SEQ_PAGE_SIZE_532); |
394 | doc_flash_command(docg3, DOC_CMD_PAGE_SIZE_532); | 394 | doc_flash_command(docg3, DOC_CMD_PAGE_SIZE_532); |
395 | doc_delay(docg3, 2); | 395 | doc_delay(docg3, 2); |
396 | 396 | ||
397 | fctrl = doc_register_readb(docg3, DOC_FLASHCONTROL); | 397 | fctrl = doc_register_readb(docg3, DOC_FLASHCONTROL); |
398 | if (fctrl & (DOC_CTRL_PROTECTION_ERROR | DOC_CTRL_SEQUENCE_ERROR)) | 398 | if (fctrl & (DOC_CTRL_PROTECTION_ERROR | DOC_CTRL_SEQUENCE_ERROR)) |
399 | return -EIO; | 399 | return -EIO; |
400 | else | 400 | else |
401 | return 0; | 401 | return 0; |
402 | } | 402 | } |
403 | 403 | ||
404 | /** | 404 | /** |
405 | * doc_setup_addr_sector - Setup blocks/page/ofs address for one plane | 405 | * doc_setup_addr_sector - Setup blocks/page/ofs address for one plane |
406 | * @docg3: the device | 406 | * @docg3: the device |
407 | * @sector: the sector | 407 | * @sector: the sector |
408 | */ | 408 | */ |
409 | static void doc_setup_addr_sector(struct docg3 *docg3, int sector) | 409 | static void doc_setup_addr_sector(struct docg3 *docg3, int sector) |
410 | { | 410 | { |
411 | doc_delay(docg3, 1); | 411 | doc_delay(docg3, 1); |
412 | doc_flash_address(docg3, sector & 0xff); | 412 | doc_flash_address(docg3, sector & 0xff); |
413 | doc_flash_address(docg3, (sector >> 8) & 0xff); | 413 | doc_flash_address(docg3, (sector >> 8) & 0xff); |
414 | doc_flash_address(docg3, (sector >> 16) & 0xff); | 414 | doc_flash_address(docg3, (sector >> 16) & 0xff); |
415 | doc_delay(docg3, 1); | 415 | doc_delay(docg3, 1); |
416 | } | 416 | } |
417 | 417 | ||
418 | /** | 418 | /** |
419 | * doc_setup_writeaddr_sector - Setup blocks/page/ofs address for one plane | 419 | * doc_setup_writeaddr_sector - Setup blocks/page/ofs address for one plane |
420 | * @docg3: the device | 420 | * @docg3: the device |
421 | * @sector: the sector | 421 | * @sector: the sector |
422 | * @ofs: the offset in the page, between 0 and (512 + 16 + 512) | 422 | * @ofs: the offset in the page, between 0 and (512 + 16 + 512) |
423 | */ | 423 | */ |
424 | static void doc_setup_writeaddr_sector(struct docg3 *docg3, int sector, int ofs) | 424 | static void doc_setup_writeaddr_sector(struct docg3 *docg3, int sector, int ofs) |
425 | { | 425 | { |
426 | ofs = ofs >> 2; | 426 | ofs = ofs >> 2; |
427 | doc_delay(docg3, 1); | 427 | doc_delay(docg3, 1); |
428 | doc_flash_address(docg3, ofs & 0xff); | 428 | doc_flash_address(docg3, ofs & 0xff); |
429 | doc_flash_address(docg3, sector & 0xff); | 429 | doc_flash_address(docg3, sector & 0xff); |
430 | doc_flash_address(docg3, (sector >> 8) & 0xff); | 430 | doc_flash_address(docg3, (sector >> 8) & 0xff); |
431 | doc_flash_address(docg3, (sector >> 16) & 0xff); | 431 | doc_flash_address(docg3, (sector >> 16) & 0xff); |
432 | doc_delay(docg3, 1); | 432 | doc_delay(docg3, 1); |
433 | } | 433 | } |
434 | 434 | ||
435 | /** | 435 | /** |
436 | * doc_seek - Set both flash planes to the specified block, page for reading | 436 | * doc_seek - Set both flash planes to the specified block, page for reading |
437 | * @docg3: the device | 437 | * @docg3: the device |
438 | * @block0: the first plane block index | 438 | * @block0: the first plane block index |
439 | * @block1: the second plane block index | 439 | * @block1: the second plane block index |
440 | * @page: the page index within the block | 440 | * @page: the page index within the block |
441 | * @wear: if true, read will occur on the 4 extra bytes of the wear area | 441 | * @wear: if true, read will occur on the 4 extra bytes of the wear area |
442 | * @ofs: offset in page to read | 442 | * @ofs: offset in page to read |
443 | * | 443 | * |
444 | * Programs the flash even and odd planes to the specific block and page. | 444 | * Programs the flash even and odd planes to the specific block and page. |
445 | * Alternatively, programs the flash to the wear area of the specified page. | 445 | * Alternatively, programs the flash to the wear area of the specified page. |
446 | */ | 446 | */ |
447 | static int doc_read_seek(struct docg3 *docg3, int block0, int block1, int page, | 447 | static int doc_read_seek(struct docg3 *docg3, int block0, int block1, int page, |
448 | int wear, int ofs) | 448 | int wear, int ofs) |
449 | { | 449 | { |
450 | int sector, ret = 0; | 450 | int sector, ret = 0; |
451 | 451 | ||
452 | doc_dbg("doc_seek(blocks=(%d,%d), page=%d, ofs=%d, wear=%d)\n", | 452 | doc_dbg("doc_seek(blocks=(%d,%d), page=%d, ofs=%d, wear=%d)\n", |
453 | block0, block1, page, ofs, wear); | 453 | block0, block1, page, ofs, wear); |
454 | 454 | ||
455 | if (!wear && (ofs < 2 * DOC_LAYOUT_PAGE_SIZE)) { | 455 | if (!wear && (ofs < 2 * DOC_LAYOUT_PAGE_SIZE)) { |
456 | doc_flash_sequence(docg3, DOC_SEQ_SET_PLANE1); | 456 | doc_flash_sequence(docg3, DOC_SEQ_SET_PLANE1); |
457 | doc_flash_command(docg3, DOC_CMD_READ_PLANE1); | 457 | doc_flash_command(docg3, DOC_CMD_READ_PLANE1); |
458 | doc_delay(docg3, 2); | 458 | doc_delay(docg3, 2); |
459 | } else { | 459 | } else { |
460 | doc_flash_sequence(docg3, DOC_SEQ_SET_PLANE2); | 460 | doc_flash_sequence(docg3, DOC_SEQ_SET_PLANE2); |
461 | doc_flash_command(docg3, DOC_CMD_READ_PLANE2); | 461 | doc_flash_command(docg3, DOC_CMD_READ_PLANE2); |
462 | doc_delay(docg3, 2); | 462 | doc_delay(docg3, 2); |
463 | } | 463 | } |
464 | 464 | ||
465 | doc_set_reliable_mode(docg3); | 465 | doc_set_reliable_mode(docg3); |
466 | if (wear) | 466 | if (wear) |
467 | ret = doc_set_extra_page_mode(docg3); | 467 | ret = doc_set_extra_page_mode(docg3); |
468 | if (ret) | 468 | if (ret) |
469 | goto out; | 469 | goto out; |
470 | 470 | ||
471 | doc_flash_sequence(docg3, DOC_SEQ_READ); | 471 | doc_flash_sequence(docg3, DOC_SEQ_READ); |
472 | sector = (block0 << DOC_ADDR_BLOCK_SHIFT) + (page & DOC_ADDR_PAGE_MASK); | 472 | sector = (block0 << DOC_ADDR_BLOCK_SHIFT) + (page & DOC_ADDR_PAGE_MASK); |
473 | doc_flash_command(docg3, DOC_CMD_PROG_BLOCK_ADDR); | 473 | doc_flash_command(docg3, DOC_CMD_PROG_BLOCK_ADDR); |
474 | doc_setup_addr_sector(docg3, sector); | 474 | doc_setup_addr_sector(docg3, sector); |
475 | 475 | ||
476 | sector = (block1 << DOC_ADDR_BLOCK_SHIFT) + (page & DOC_ADDR_PAGE_MASK); | 476 | sector = (block1 << DOC_ADDR_BLOCK_SHIFT) + (page & DOC_ADDR_PAGE_MASK); |
477 | doc_flash_command(docg3, DOC_CMD_PROG_BLOCK_ADDR); | 477 | doc_flash_command(docg3, DOC_CMD_PROG_BLOCK_ADDR); |
478 | doc_setup_addr_sector(docg3, sector); | 478 | doc_setup_addr_sector(docg3, sector); |
479 | doc_delay(docg3, 1); | 479 | doc_delay(docg3, 1); |
480 | 480 | ||
481 | out: | 481 | out: |
482 | return ret; | 482 | return ret; |
483 | } | 483 | } |
484 | 484 | ||
485 | /** | 485 | /** |
486 | * doc_write_seek - Set both flash planes to the specified block, page for writing | 486 | * doc_write_seek - Set both flash planes to the specified block, page for writing |
487 | * @docg3: the device | 487 | * @docg3: the device |
488 | * @block0: the first plane block index | 488 | * @block0: the first plane block index |
489 | * @block1: the second plane block index | 489 | * @block1: the second plane block index |
490 | * @page: the page index within the block | 490 | * @page: the page index within the block |
491 | * @ofs: offset in page to write | 491 | * @ofs: offset in page to write |
492 | * | 492 | * |
493 | * Programs the flash even and odd planes to the specific block and page. | 493 | * Programs the flash even and odd planes to the specific block and page. |
494 | * Alternatively, programs the flash to the wear area of the specified page. | 494 | * Alternatively, programs the flash to the wear area of the specified page. |
495 | */ | 495 | */ |
496 | static int doc_write_seek(struct docg3 *docg3, int block0, int block1, int page, | 496 | static int doc_write_seek(struct docg3 *docg3, int block0, int block1, int page, |
497 | int ofs) | 497 | int ofs) |
498 | { | 498 | { |
499 | int ret = 0, sector; | 499 | int ret = 0, sector; |
500 | 500 | ||
501 | doc_dbg("doc_write_seek(blocks=(%d,%d), page=%d, ofs=%d)\n", | 501 | doc_dbg("doc_write_seek(blocks=(%d,%d), page=%d, ofs=%d)\n", |
502 | block0, block1, page, ofs); | 502 | block0, block1, page, ofs); |
503 | 503 | ||
504 | doc_set_reliable_mode(docg3); | 504 | doc_set_reliable_mode(docg3); |
505 | 505 | ||
506 | if (ofs < 2 * DOC_LAYOUT_PAGE_SIZE) { | 506 | if (ofs < 2 * DOC_LAYOUT_PAGE_SIZE) { |
507 | doc_flash_sequence(docg3, DOC_SEQ_SET_PLANE1); | 507 | doc_flash_sequence(docg3, DOC_SEQ_SET_PLANE1); |
508 | doc_flash_command(docg3, DOC_CMD_READ_PLANE1); | 508 | doc_flash_command(docg3, DOC_CMD_READ_PLANE1); |
509 | doc_delay(docg3, 2); | 509 | doc_delay(docg3, 2); |
510 | } else { | 510 | } else { |
511 | doc_flash_sequence(docg3, DOC_SEQ_SET_PLANE2); | 511 | doc_flash_sequence(docg3, DOC_SEQ_SET_PLANE2); |
512 | doc_flash_command(docg3, DOC_CMD_READ_PLANE2); | 512 | doc_flash_command(docg3, DOC_CMD_READ_PLANE2); |
513 | doc_delay(docg3, 2); | 513 | doc_delay(docg3, 2); |
514 | } | 514 | } |
515 | 515 | ||
516 | doc_flash_sequence(docg3, DOC_SEQ_PAGE_SETUP); | 516 | doc_flash_sequence(docg3, DOC_SEQ_PAGE_SETUP); |
517 | doc_flash_command(docg3, DOC_CMD_PROG_CYCLE1); | 517 | doc_flash_command(docg3, DOC_CMD_PROG_CYCLE1); |
518 | 518 | ||
519 | sector = (block0 << DOC_ADDR_BLOCK_SHIFT) + (page & DOC_ADDR_PAGE_MASK); | 519 | sector = (block0 << DOC_ADDR_BLOCK_SHIFT) + (page & DOC_ADDR_PAGE_MASK); |
520 | doc_setup_writeaddr_sector(docg3, sector, ofs); | 520 | doc_setup_writeaddr_sector(docg3, sector, ofs); |
521 | 521 | ||
522 | doc_flash_command(docg3, DOC_CMD_PROG_CYCLE3); | 522 | doc_flash_command(docg3, DOC_CMD_PROG_CYCLE3); |
523 | doc_delay(docg3, 2); | 523 | doc_delay(docg3, 2); |
524 | ret = doc_wait_ready(docg3); | 524 | ret = doc_wait_ready(docg3); |
525 | if (ret) | 525 | if (ret) |
526 | goto out; | 526 | goto out; |
527 | 527 | ||
528 | doc_flash_command(docg3, DOC_CMD_PROG_CYCLE1); | 528 | doc_flash_command(docg3, DOC_CMD_PROG_CYCLE1); |
529 | sector = (block1 << DOC_ADDR_BLOCK_SHIFT) + (page & DOC_ADDR_PAGE_MASK); | 529 | sector = (block1 << DOC_ADDR_BLOCK_SHIFT) + (page & DOC_ADDR_PAGE_MASK); |
530 | doc_setup_writeaddr_sector(docg3, sector, ofs); | 530 | doc_setup_writeaddr_sector(docg3, sector, ofs); |
531 | doc_delay(docg3, 1); | 531 | doc_delay(docg3, 1); |
532 | 532 | ||
533 | out: | 533 | out: |
534 | return ret; | 534 | return ret; |
535 | } | 535 | } |
536 | 536 | ||
537 | 537 | ||
538 | /** | 538 | /** |
539 | * doc_read_page_ecc_init - Initialize hardware ECC engine | 539 | * doc_read_page_ecc_init - Initialize hardware ECC engine |
540 | * @docg3: the device | 540 | * @docg3: the device |
541 | * @len: the number of bytes covered by the ECC (BCH covered) | 541 | * @len: the number of bytes covered by the ECC (BCH covered) |
542 | * | 542 | * |
543 | * The function does initialize the hardware ECC engine to compute the Hamming | 543 | * The function does initialize the hardware ECC engine to compute the Hamming |
544 | * ECC (on 1 byte) and the BCH hardware ECC (on 7 bytes). | 544 | * ECC (on 1 byte) and the BCH hardware ECC (on 7 bytes). |
545 | * | 545 | * |
546 | * Return 0 if succeeded, -EIO on error | 546 | * Return 0 if succeeded, -EIO on error |
547 | */ | 547 | */ |
548 | static int doc_read_page_ecc_init(struct docg3 *docg3, int len) | 548 | static int doc_read_page_ecc_init(struct docg3 *docg3, int len) |
549 | { | 549 | { |
550 | doc_writew(docg3, DOC_ECCCONF0_READ_MODE | 550 | doc_writew(docg3, DOC_ECCCONF0_READ_MODE |
551 | | DOC_ECCCONF0_BCH_ENABLE | DOC_ECCCONF0_HAMMING_ENABLE | 551 | | DOC_ECCCONF0_BCH_ENABLE | DOC_ECCCONF0_HAMMING_ENABLE |
552 | | (len & DOC_ECCCONF0_DATA_BYTES_MASK), | 552 | | (len & DOC_ECCCONF0_DATA_BYTES_MASK), |
553 | DOC_ECCCONF0); | 553 | DOC_ECCCONF0); |
554 | doc_delay(docg3, 4); | 554 | doc_delay(docg3, 4); |
555 | doc_register_readb(docg3, DOC_FLASHCONTROL); | 555 | doc_register_readb(docg3, DOC_FLASHCONTROL); |
556 | return doc_wait_ready(docg3); | 556 | return doc_wait_ready(docg3); |
557 | } | 557 | } |
558 | 558 | ||
559 | /** | 559 | /** |
560 | * doc_write_page_ecc_init - Initialize hardware BCH ECC engine | 560 | * doc_write_page_ecc_init - Initialize hardware BCH ECC engine |
561 | * @docg3: the device | 561 | * @docg3: the device |
562 | * @len: the number of bytes covered by the ECC (BCH covered) | 562 | * @len: the number of bytes covered by the ECC (BCH covered) |
563 | * | 563 | * |
564 | * The function does initialize the hardware ECC engine to compute the Hamming | 564 | * The function does initialize the hardware ECC engine to compute the Hamming |
565 | * ECC (on 1 byte) and the BCH hardware ECC (on 7 bytes). | 565 | * ECC (on 1 byte) and the BCH hardware ECC (on 7 bytes). |
566 | * | 566 | * |
567 | * Return 0 if succeeded, -EIO on error | 567 | * Return 0 if succeeded, -EIO on error |
568 | */ | 568 | */ |
569 | static int doc_write_page_ecc_init(struct docg3 *docg3, int len) | 569 | static int doc_write_page_ecc_init(struct docg3 *docg3, int len) |
570 | { | 570 | { |
571 | doc_writew(docg3, DOC_ECCCONF0_WRITE_MODE | 571 | doc_writew(docg3, DOC_ECCCONF0_WRITE_MODE |
572 | | DOC_ECCCONF0_BCH_ENABLE | DOC_ECCCONF0_HAMMING_ENABLE | 572 | | DOC_ECCCONF0_BCH_ENABLE | DOC_ECCCONF0_HAMMING_ENABLE |
573 | | (len & DOC_ECCCONF0_DATA_BYTES_MASK), | 573 | | (len & DOC_ECCCONF0_DATA_BYTES_MASK), |
574 | DOC_ECCCONF0); | 574 | DOC_ECCCONF0); |
575 | doc_delay(docg3, 4); | 575 | doc_delay(docg3, 4); |
576 | doc_register_readb(docg3, DOC_FLASHCONTROL); | 576 | doc_register_readb(docg3, DOC_FLASHCONTROL); |
577 | return doc_wait_ready(docg3); | 577 | return doc_wait_ready(docg3); |
578 | } | 578 | } |
579 | 579 | ||
580 | /** | 580 | /** |
581 | * doc_ecc_disable - Disable Hamming and BCH ECC hardware calculator | 581 | * doc_ecc_disable - Disable Hamming and BCH ECC hardware calculator |
582 | * @docg3: the device | 582 | * @docg3: the device |
583 | * | 583 | * |
584 | * Disables the hardware ECC generator and checker, for unchecked reads (as when | 584 | * Disables the hardware ECC generator and checker, for unchecked reads (as when |
585 | * reading OOB only or write status byte). | 585 | * reading OOB only or write status byte). |
586 | */ | 586 | */ |
587 | static void doc_ecc_disable(struct docg3 *docg3) | 587 | static void doc_ecc_disable(struct docg3 *docg3) |
588 | { | 588 | { |
589 | doc_writew(docg3, DOC_ECCCONF0_READ_MODE, DOC_ECCCONF0); | 589 | doc_writew(docg3, DOC_ECCCONF0_READ_MODE, DOC_ECCCONF0); |
590 | doc_delay(docg3, 4); | 590 | doc_delay(docg3, 4); |
591 | } | 591 | } |
592 | 592 | ||
593 | /** | 593 | /** |
594 | * doc_hamming_ecc_init - Initialize hardware Hamming ECC engine | 594 | * doc_hamming_ecc_init - Initialize hardware Hamming ECC engine |
595 | * @docg3: the device | 595 | * @docg3: the device |
596 | * @nb_bytes: the number of bytes covered by the ECC (Hamming covered) | 596 | * @nb_bytes: the number of bytes covered by the ECC (Hamming covered) |
597 | * | 597 | * |
598 | * This function programs the ECC hardware to compute the hamming code on the | 598 | * This function programs the ECC hardware to compute the hamming code on the |
599 | * last provided N bytes to the hardware generator. | 599 | * last provided N bytes to the hardware generator. |
600 | */ | 600 | */ |
601 | static void doc_hamming_ecc_init(struct docg3 *docg3, int nb_bytes) | 601 | static void doc_hamming_ecc_init(struct docg3 *docg3, int nb_bytes) |
602 | { | 602 | { |
603 | u8 ecc_conf1; | 603 | u8 ecc_conf1; |
604 | 604 | ||
605 | ecc_conf1 = doc_register_readb(docg3, DOC_ECCCONF1); | 605 | ecc_conf1 = doc_register_readb(docg3, DOC_ECCCONF1); |
606 | ecc_conf1 &= ~DOC_ECCCONF1_HAMMING_BITS_MASK; | 606 | ecc_conf1 &= ~DOC_ECCCONF1_HAMMING_BITS_MASK; |
607 | ecc_conf1 |= (nb_bytes & DOC_ECCCONF1_HAMMING_BITS_MASK); | 607 | ecc_conf1 |= (nb_bytes & DOC_ECCCONF1_HAMMING_BITS_MASK); |
608 | doc_writeb(docg3, ecc_conf1, DOC_ECCCONF1); | 608 | doc_writeb(docg3, ecc_conf1, DOC_ECCCONF1); |
609 | } | 609 | } |
610 | 610 | ||
611 | /** | 611 | /** |
612 | * doc_ecc_bch_fix_data - Fix if need be read data from flash | 612 | * doc_ecc_bch_fix_data - Fix if need be read data from flash |
613 | * @docg3: the device | 613 | * @docg3: the device |
614 | * @buf: the buffer of read data (512 + 7 + 1 bytes) | 614 | * @buf: the buffer of read data (512 + 7 + 1 bytes) |
615 | * @hwecc: the hardware calculated ECC. | 615 | * @hwecc: the hardware calculated ECC. |
616 | * It's in fact recv_ecc ^ calc_ecc, where recv_ecc was read from OOB | 616 | * It's in fact recv_ecc ^ calc_ecc, where recv_ecc was read from OOB |
617 | * area data, and calc_ecc the ECC calculated by the hardware generator. | 617 | * area data, and calc_ecc the ECC calculated by the hardware generator. |
618 | * | 618 | * |
619 | * Checks if the received data matches the ECC, and if an error is detected, | 619 | * Checks if the received data matches the ECC, and if an error is detected, |
620 | * tries to fix the bit flips (at most 4) in the buffer buf. As the docg3 | 620 | * tries to fix the bit flips (at most 4) in the buffer buf. As the docg3 |
621 | * understands the (data, ecc, syndroms) in an inverted order in comparison to | 621 | * understands the (data, ecc, syndroms) in an inverted order in comparison to |
622 | * the BCH library, the function reverses the order of bits (ie. bit7 and bit0, | 622 | * the BCH library, the function reverses the order of bits (ie. bit7 and bit0, |
623 | * bit6 and bit 1, ...) for all ECC data. | 623 | * bit6 and bit 1, ...) for all ECC data. |
624 | * | 624 | * |
625 | * The hardware ecc unit produces oob_ecc ^ calc_ecc. The kernel's bch | 625 | * The hardware ecc unit produces oob_ecc ^ calc_ecc. The kernel's bch |
626 | * algorithm is used to decode this. However the hw operates on page | 626 | * algorithm is used to decode this. However the hw operates on page |
627 | * data in a bit order that is the reverse of that of the bch alg, | 627 | * data in a bit order that is the reverse of that of the bch alg, |
628 | * requiring that the bits be reversed on the result. Thanks to Ivan | 628 | * requiring that the bits be reversed on the result. Thanks to Ivan |
629 | * Djelic for his analysis. | 629 | * Djelic for his analysis. |
630 | * | 630 | * |
631 | * Returns number of fixed bits (0, 1, 2, 3, 4) or -EBADMSG if too many bit | 631 | * Returns number of fixed bits (0, 1, 2, 3, 4) or -EBADMSG if too many bit |
632 | * errors were detected and cannot be fixed. | 632 | * errors were detected and cannot be fixed. |
633 | */ | 633 | */ |
634 | static int doc_ecc_bch_fix_data(struct docg3 *docg3, void *buf, u8 *hwecc) | 634 | static int doc_ecc_bch_fix_data(struct docg3 *docg3, void *buf, u8 *hwecc) |
635 | { | 635 | { |
636 | u8 ecc[DOC_ECC_BCH_SIZE]; | 636 | u8 ecc[DOC_ECC_BCH_SIZE]; |
637 | int errorpos[DOC_ECC_BCH_T], i, numerrs; | 637 | int errorpos[DOC_ECC_BCH_T], i, numerrs; |
638 | 638 | ||
639 | for (i = 0; i < DOC_ECC_BCH_SIZE; i++) | 639 | for (i = 0; i < DOC_ECC_BCH_SIZE; i++) |
640 | ecc[i] = bitrev8(hwecc[i]); | 640 | ecc[i] = bitrev8(hwecc[i]); |
641 | numerrs = decode_bch(docg3->cascade->bch, NULL, | 641 | numerrs = decode_bch(docg3->cascade->bch, NULL, |
642 | DOC_ECC_BCH_COVERED_BYTES, | 642 | DOC_ECC_BCH_COVERED_BYTES, |
643 | NULL, ecc, NULL, errorpos); | 643 | NULL, ecc, NULL, errorpos); |
644 | BUG_ON(numerrs == -EINVAL); | 644 | BUG_ON(numerrs == -EINVAL); |
645 | if (numerrs < 0) | 645 | if (numerrs < 0) |
646 | goto out; | 646 | goto out; |
647 | 647 | ||
648 | for (i = 0; i < numerrs; i++) | 648 | for (i = 0; i < numerrs; i++) |
649 | errorpos[i] = (errorpos[i] & ~7) | (7 - (errorpos[i] & 7)); | 649 | errorpos[i] = (errorpos[i] & ~7) | (7 - (errorpos[i] & 7)); |
650 | for (i = 0; i < numerrs; i++) | 650 | for (i = 0; i < numerrs; i++) |
651 | if (errorpos[i] < DOC_ECC_BCH_COVERED_BYTES*8) | 651 | if (errorpos[i] < DOC_ECC_BCH_COVERED_BYTES*8) |
652 | /* error is located in data, correct it */ | 652 | /* error is located in data, correct it */ |
653 | change_bit(errorpos[i], buf); | 653 | change_bit(errorpos[i], buf); |
654 | out: | 654 | out: |
655 | doc_dbg("doc_ecc_bch_fix_data: flipped %d bits\n", numerrs); | 655 | doc_dbg("doc_ecc_bch_fix_data: flipped %d bits\n", numerrs); |
656 | return numerrs; | 656 | return numerrs; |
657 | } | 657 | } |
658 | 658 | ||
659 | 659 | ||
660 | /** | 660 | /** |
661 | * doc_read_page_prepare - Prepares reading data from a flash page | 661 | * doc_read_page_prepare - Prepares reading data from a flash page |
662 | * @docg3: the device | 662 | * @docg3: the device |
663 | * @block0: the first plane block index on flash memory | 663 | * @block0: the first plane block index on flash memory |
664 | * @block1: the second plane block index on flash memory | 664 | * @block1: the second plane block index on flash memory |
665 | * @page: the page index in the block | 665 | * @page: the page index in the block |
666 | * @offset: the offset in the page (must be a multiple of 4) | 666 | * @offset: the offset in the page (must be a multiple of 4) |
667 | * | 667 | * |
668 | * Prepares the page to be read in the flash memory : | 668 | * Prepares the page to be read in the flash memory : |
669 | * - tell ASIC to map the flash pages | 669 | * - tell ASIC to map the flash pages |
670 | * - tell ASIC to be in read mode | 670 | * - tell ASIC to be in read mode |
671 | * | 671 | * |
672 | * After a call to this method, a call to doc_read_page_finish is mandatory, | 672 | * After a call to this method, a call to doc_read_page_finish is mandatory, |
673 | * to end the read cycle of the flash. | 673 | * to end the read cycle of the flash. |
674 | * | 674 | * |
675 | * Read data from a flash page. The length to be read must be between 0 and | 675 | * Read data from a flash page. The length to be read must be between 0 and |
676 | * (page_size + oob_size + wear_size), ie. 532, and a multiple of 4 (because | 676 | * (page_size + oob_size + wear_size), ie. 532, and a multiple of 4 (because |
677 | * the extra bytes reading is not implemented). | 677 | * the extra bytes reading is not implemented). |
678 | * | 678 | * |
679 | * As pages are grouped by 2 (in 2 planes), reading from a page must be done | 679 | * As pages are grouped by 2 (in 2 planes), reading from a page must be done |
680 | * in two steps: | 680 | * in two steps: |
681 | * - one read of 512 bytes at offset 0 | 681 | * - one read of 512 bytes at offset 0 |
682 | * - one read of 512 bytes at offset 512 + 16 | 682 | * - one read of 512 bytes at offset 512 + 16 |
683 | * | 683 | * |
684 | * Returns 0 if successful, -EIO if a read error occurred. | 684 | * Returns 0 if successful, -EIO if a read error occurred. |
685 | */ | 685 | */ |
686 | static int doc_read_page_prepare(struct docg3 *docg3, int block0, int block1, | 686 | static int doc_read_page_prepare(struct docg3 *docg3, int block0, int block1, |
687 | int page, int offset) | 687 | int page, int offset) |
688 | { | 688 | { |
689 | int wear_area = 0, ret = 0; | 689 | int wear_area = 0, ret = 0; |
690 | 690 | ||
691 | doc_dbg("doc_read_page_prepare(blocks=(%d,%d), page=%d, ofsInPage=%d)\n", | 691 | doc_dbg("doc_read_page_prepare(blocks=(%d,%d), page=%d, ofsInPage=%d)\n", |
692 | block0, block1, page, offset); | 692 | block0, block1, page, offset); |
693 | if (offset >= DOC_LAYOUT_WEAR_OFFSET) | 693 | if (offset >= DOC_LAYOUT_WEAR_OFFSET) |
694 | wear_area = 1; | 694 | wear_area = 1; |
695 | if (!wear_area && offset > (DOC_LAYOUT_PAGE_OOB_SIZE * 2)) | 695 | if (!wear_area && offset > (DOC_LAYOUT_PAGE_OOB_SIZE * 2)) |
696 | return -EINVAL; | 696 | return -EINVAL; |
697 | 697 | ||
698 | doc_set_device_id(docg3, docg3->device_id); | 698 | doc_set_device_id(docg3, docg3->device_id); |
699 | ret = doc_reset_seq(docg3); | 699 | ret = doc_reset_seq(docg3); |
700 | if (ret) | 700 | if (ret) |
701 | goto err; | 701 | goto err; |
702 | 702 | ||
703 | /* Program the flash address block and page */ | 703 | /* Program the flash address block and page */ |
704 | ret = doc_read_seek(docg3, block0, block1, page, wear_area, offset); | 704 | ret = doc_read_seek(docg3, block0, block1, page, wear_area, offset); |
705 | if (ret) | 705 | if (ret) |
706 | goto err; | 706 | goto err; |
707 | 707 | ||
708 | doc_flash_command(docg3, DOC_CMD_READ_ALL_PLANES); | 708 | doc_flash_command(docg3, DOC_CMD_READ_ALL_PLANES); |
709 | doc_delay(docg3, 2); | 709 | doc_delay(docg3, 2); |
710 | doc_wait_ready(docg3); | 710 | doc_wait_ready(docg3); |
711 | 711 | ||
712 | doc_flash_command(docg3, DOC_CMD_SET_ADDR_READ); | 712 | doc_flash_command(docg3, DOC_CMD_SET_ADDR_READ); |
713 | doc_delay(docg3, 1); | 713 | doc_delay(docg3, 1); |
714 | if (offset >= DOC_LAYOUT_PAGE_SIZE * 2) | 714 | if (offset >= DOC_LAYOUT_PAGE_SIZE * 2) |
715 | offset -= 2 * DOC_LAYOUT_PAGE_SIZE; | 715 | offset -= 2 * DOC_LAYOUT_PAGE_SIZE; |
716 | doc_flash_address(docg3, offset >> 2); | 716 | doc_flash_address(docg3, offset >> 2); |
717 | doc_delay(docg3, 1); | 717 | doc_delay(docg3, 1); |
718 | doc_wait_ready(docg3); | 718 | doc_wait_ready(docg3); |
719 | 719 | ||
720 | doc_flash_command(docg3, DOC_CMD_READ_FLASH); | 720 | doc_flash_command(docg3, DOC_CMD_READ_FLASH); |
721 | 721 | ||
722 | return 0; | 722 | return 0; |
723 | err: | 723 | err: |
724 | doc_writeb(docg3, 0, DOC_DATAEND); | 724 | doc_writeb(docg3, 0, DOC_DATAEND); |
725 | doc_delay(docg3, 2); | 725 | doc_delay(docg3, 2); |
726 | return -EIO; | 726 | return -EIO; |
727 | } | 727 | } |
728 | 728 | ||
729 | /** | 729 | /** |
730 | * doc_read_page_getbytes - Reads bytes from a prepared page | 730 | * doc_read_page_getbytes - Reads bytes from a prepared page |
731 | * @docg3: the device | 731 | * @docg3: the device |
732 | * @len: the number of bytes to be read (must be a multiple of 4) | 732 | * @len: the number of bytes to be read (must be a multiple of 4) |
733 | * @buf: the buffer to be filled in (or NULL is forget bytes) | 733 | * @buf: the buffer to be filled in (or NULL is forget bytes) |
734 | * @first: 1 if first time read, DOC_READADDRESS should be set | 734 | * @first: 1 if first time read, DOC_READADDRESS should be set |
735 | * @last_odd: 1 if last read ended up on an odd byte | 735 | * @last_odd: 1 if last read ended up on an odd byte |
736 | * | 736 | * |
737 | * Reads bytes from a prepared page. There is a trickery here : if the last read | 737 | * Reads bytes from a prepared page. There is a trickery here : if the last read |
738 | * ended up on an odd offset in the 1024 bytes double page, ie. between the 2 | 738 | * ended up on an odd offset in the 1024 bytes double page, ie. between the 2 |
739 | * planes, the first byte must be read apart. If a word (16bit) read was used, | 739 | * planes, the first byte must be read apart. If a word (16bit) read was used, |
740 | * the read would return the byte of plane 2 as low *and* high endian, which | 740 | * the read would return the byte of plane 2 as low *and* high endian, which |
741 | * will mess the read. | 741 | * will mess the read. |
742 | * | 742 | * |
743 | */ | 743 | */ |
744 | static int doc_read_page_getbytes(struct docg3 *docg3, int len, u_char *buf, | 744 | static int doc_read_page_getbytes(struct docg3 *docg3, int len, u_char *buf, |
745 | int first, int last_odd) | 745 | int first, int last_odd) |
746 | { | 746 | { |
747 | if (last_odd && len > 0) { | 747 | if (last_odd && len > 0) { |
748 | doc_read_data_area(docg3, buf, 1, first); | 748 | doc_read_data_area(docg3, buf, 1, first); |
749 | doc_read_data_area(docg3, buf ? buf + 1 : buf, len - 1, 0); | 749 | doc_read_data_area(docg3, buf ? buf + 1 : buf, len - 1, 0); |
750 | } else { | 750 | } else { |
751 | doc_read_data_area(docg3, buf, len, first); | 751 | doc_read_data_area(docg3, buf, len, first); |
752 | } | 752 | } |
753 | doc_delay(docg3, 2); | 753 | doc_delay(docg3, 2); |
754 | return len; | 754 | return len; |
755 | } | 755 | } |
756 | 756 | ||
757 | /** | 757 | /** |
758 | * doc_write_page_putbytes - Writes bytes into a prepared page | 758 | * doc_write_page_putbytes - Writes bytes into a prepared page |
759 | * @docg3: the device | 759 | * @docg3: the device |
760 | * @len: the number of bytes to be written | 760 | * @len: the number of bytes to be written |
761 | * @buf: the buffer of input bytes | 761 | * @buf: the buffer of input bytes |
762 | * | 762 | * |
763 | */ | 763 | */ |
764 | static void doc_write_page_putbytes(struct docg3 *docg3, int len, | 764 | static void doc_write_page_putbytes(struct docg3 *docg3, int len, |
765 | const u_char *buf) | 765 | const u_char *buf) |
766 | { | 766 | { |
767 | doc_write_data_area(docg3, buf, len); | 767 | doc_write_data_area(docg3, buf, len); |
768 | doc_delay(docg3, 2); | 768 | doc_delay(docg3, 2); |
769 | } | 769 | } |
770 | 770 | ||
771 | /** | 771 | /** |
772 | * doc_get_bch_hw_ecc - Get hardware calculated BCH ECC | 772 | * doc_get_bch_hw_ecc - Get hardware calculated BCH ECC |
773 | * @docg3: the device | 773 | * @docg3: the device |
774 | * @hwecc: the array of 7 integers where the hardware ecc will be stored | 774 | * @hwecc: the array of 7 integers where the hardware ecc will be stored |
775 | */ | 775 | */ |
776 | static void doc_get_bch_hw_ecc(struct docg3 *docg3, u8 *hwecc) | 776 | static void doc_get_bch_hw_ecc(struct docg3 *docg3, u8 *hwecc) |
777 | { | 777 | { |
778 | int i; | 778 | int i; |
779 | 779 | ||
780 | for (i = 0; i < DOC_ECC_BCH_SIZE; i++) | 780 | for (i = 0; i < DOC_ECC_BCH_SIZE; i++) |
781 | hwecc[i] = doc_register_readb(docg3, DOC_BCH_HW_ECC(i)); | 781 | hwecc[i] = doc_register_readb(docg3, DOC_BCH_HW_ECC(i)); |
782 | } | 782 | } |
783 | 783 | ||
784 | /** | 784 | /** |
785 | * doc_page_finish - Ends reading/writing of a flash page | 785 | * doc_page_finish - Ends reading/writing of a flash page |
786 | * @docg3: the device | 786 | * @docg3: the device |
787 | */ | 787 | */ |
788 | static void doc_page_finish(struct docg3 *docg3) | 788 | static void doc_page_finish(struct docg3 *docg3) |
789 | { | 789 | { |
790 | doc_writeb(docg3, 0, DOC_DATAEND); | 790 | doc_writeb(docg3, 0, DOC_DATAEND); |
791 | doc_delay(docg3, 2); | 791 | doc_delay(docg3, 2); |
792 | } | 792 | } |
793 | 793 | ||
794 | /** | 794 | /** |
795 | * doc_read_page_finish - Ends reading of a flash page | 795 | * doc_read_page_finish - Ends reading of a flash page |
796 | * @docg3: the device | 796 | * @docg3: the device |
797 | * | 797 | * |
798 | * As a side effect, resets the chip selector to 0. This ensures that after each | 798 | * As a side effect, resets the chip selector to 0. This ensures that after each |
799 | * read operation, the floor 0 is selected. Therefore, if the systems halts, the | 799 | * read operation, the floor 0 is selected. Therefore, if the systems halts, the |
800 | * reboot will boot on floor 0, where the IPL is. | 800 | * reboot will boot on floor 0, where the IPL is. |
801 | */ | 801 | */ |
802 | static void doc_read_page_finish(struct docg3 *docg3) | 802 | static void doc_read_page_finish(struct docg3 *docg3) |
803 | { | 803 | { |
804 | doc_page_finish(docg3); | 804 | doc_page_finish(docg3); |
805 | doc_set_device_id(docg3, 0); | 805 | doc_set_device_id(docg3, 0); |
806 | } | 806 | } |
807 | 807 | ||
808 | /** | 808 | /** |
809 | * calc_block_sector - Calculate blocks, pages and ofs. | 809 | * calc_block_sector - Calculate blocks, pages and ofs. |
810 | 810 | ||
811 | * @from: offset in flash | 811 | * @from: offset in flash |
812 | * @block0: first plane block index calculated | 812 | * @block0: first plane block index calculated |
813 | * @block1: second plane block index calculated | 813 | * @block1: second plane block index calculated |
814 | * @page: page calculated | 814 | * @page: page calculated |
815 | * @ofs: offset in page | 815 | * @ofs: offset in page |
816 | * @reliable: 0 if docg3 in normal mode, 1 if docg3 in fast mode, 2 if docg3 in | 816 | * @reliable: 0 if docg3 in normal mode, 1 if docg3 in fast mode, 2 if docg3 in |
817 | * reliable mode. | 817 | * reliable mode. |
818 | * | 818 | * |
819 | * The calculation is based on the reliable/normal mode. In normal mode, the 64 | 819 | * The calculation is based on the reliable/normal mode. In normal mode, the 64 |
820 | * pages of a block are available. In reliable mode, as pages 2*n and 2*n+1 are | 820 | * pages of a block are available. In reliable mode, as pages 2*n and 2*n+1 are |
821 | * clones, only 32 pages per block are available. | 821 | * clones, only 32 pages per block are available. |
822 | */ | 822 | */ |
823 | static void calc_block_sector(loff_t from, int *block0, int *block1, int *page, | 823 | static void calc_block_sector(loff_t from, int *block0, int *block1, int *page, |
824 | int *ofs, int reliable) | 824 | int *ofs, int reliable) |
825 | { | 825 | { |
826 | uint sector, pages_biblock; | 826 | uint sector, pages_biblock; |
827 | 827 | ||
828 | pages_biblock = DOC_LAYOUT_PAGES_PER_BLOCK * DOC_LAYOUT_NBPLANES; | 828 | pages_biblock = DOC_LAYOUT_PAGES_PER_BLOCK * DOC_LAYOUT_NBPLANES; |
829 | if (reliable == 1 || reliable == 2) | 829 | if (reliable == 1 || reliable == 2) |
830 | pages_biblock /= 2; | 830 | pages_biblock /= 2; |
831 | 831 | ||
832 | sector = from / DOC_LAYOUT_PAGE_SIZE; | 832 | sector = from / DOC_LAYOUT_PAGE_SIZE; |
833 | *block0 = sector / pages_biblock * DOC_LAYOUT_NBPLANES; | 833 | *block0 = sector / pages_biblock * DOC_LAYOUT_NBPLANES; |
834 | *block1 = *block0 + 1; | 834 | *block1 = *block0 + 1; |
835 | *page = sector % pages_biblock; | 835 | *page = sector % pages_biblock; |
836 | *page /= DOC_LAYOUT_NBPLANES; | 836 | *page /= DOC_LAYOUT_NBPLANES; |
837 | if (reliable == 1 || reliable == 2) | 837 | if (reliable == 1 || reliable == 2) |
838 | *page *= 2; | 838 | *page *= 2; |
839 | if (sector % 2) | 839 | if (sector % 2) |
840 | *ofs = DOC_LAYOUT_PAGE_OOB_SIZE; | 840 | *ofs = DOC_LAYOUT_PAGE_OOB_SIZE; |
841 | else | 841 | else |
842 | *ofs = 0; | 842 | *ofs = 0; |
843 | } | 843 | } |
844 | 844 | ||
845 | /** | 845 | /** |
846 | * doc_read_oob - Read out of band bytes from flash | 846 | * doc_read_oob - Read out of band bytes from flash |
847 | * @mtd: the device | 847 | * @mtd: the device |
848 | * @from: the offset from first block and first page, in bytes, aligned on page | 848 | * @from: the offset from first block and first page, in bytes, aligned on page |
849 | * size | 849 | * size |
850 | * @ops: the mtd oob structure | 850 | * @ops: the mtd oob structure |
851 | * | 851 | * |
852 | * Reads flash memory OOB area of pages. | 852 | * Reads flash memory OOB area of pages. |
853 | * | 853 | * |
854 | * Returns 0 if read successful, of -EIO, -EINVAL if an error occurred | 854 | * Returns 0 if read successful, of -EIO, -EINVAL if an error occurred |
855 | */ | 855 | */ |
856 | static int doc_read_oob(struct mtd_info *mtd, loff_t from, | 856 | static int doc_read_oob(struct mtd_info *mtd, loff_t from, |
857 | struct mtd_oob_ops *ops) | 857 | struct mtd_oob_ops *ops) |
858 | { | 858 | { |
859 | struct docg3 *docg3 = mtd->priv; | 859 | struct docg3 *docg3 = mtd->priv; |
860 | int block0, block1, page, ret, skip, ofs = 0; | 860 | int block0, block1, page, ret, skip, ofs = 0; |
861 | u8 *oobbuf = ops->oobbuf; | 861 | u8 *oobbuf = ops->oobbuf; |
862 | u8 *buf = ops->datbuf; | 862 | u8 *buf = ops->datbuf; |
863 | size_t len, ooblen, nbdata, nboob; | 863 | size_t len, ooblen, nbdata, nboob; |
864 | u8 hwecc[DOC_ECC_BCH_SIZE], eccconf1; | 864 | u8 hwecc[DOC_ECC_BCH_SIZE], eccconf1; |
865 | int max_bitflips = 0; | 865 | int max_bitflips = 0; |
866 | 866 | ||
867 | if (buf) | 867 | if (buf) |
868 | len = ops->len; | 868 | len = ops->len; |
869 | else | 869 | else |
870 | len = 0; | 870 | len = 0; |
871 | if (oobbuf) | 871 | if (oobbuf) |
872 | ooblen = ops->ooblen; | 872 | ooblen = ops->ooblen; |
873 | else | 873 | else |
874 | ooblen = 0; | 874 | ooblen = 0; |
875 | 875 | ||
876 | if (oobbuf && ops->mode == MTD_OPS_PLACE_OOB) | 876 | if (oobbuf && ops->mode == MTD_OPS_PLACE_OOB) |
877 | oobbuf += ops->ooboffs; | 877 | oobbuf += ops->ooboffs; |
878 | 878 | ||
879 | doc_dbg("doc_read_oob(from=%lld, mode=%d, data=(%p:%zu), oob=(%p:%zu))\n", | 879 | doc_dbg("doc_read_oob(from=%lld, mode=%d, data=(%p:%zu), oob=(%p:%zu))\n", |
880 | from, ops->mode, buf, len, oobbuf, ooblen); | 880 | from, ops->mode, buf, len, oobbuf, ooblen); |
881 | if (ooblen % DOC_LAYOUT_OOB_SIZE) | 881 | if (ooblen % DOC_LAYOUT_OOB_SIZE) |
882 | return -EINVAL; | 882 | return -EINVAL; |
883 | 883 | ||
884 | if (from + len > mtd->size) | 884 | if (from + len > mtd->size) |
885 | return -EINVAL; | 885 | return -EINVAL; |
886 | 886 | ||
887 | ops->oobretlen = 0; | 887 | ops->oobretlen = 0; |
888 | ops->retlen = 0; | 888 | ops->retlen = 0; |
889 | ret = 0; | 889 | ret = 0; |
890 | skip = from % DOC_LAYOUT_PAGE_SIZE; | 890 | skip = from % DOC_LAYOUT_PAGE_SIZE; |
891 | mutex_lock(&docg3->cascade->lock); | 891 | mutex_lock(&docg3->cascade->lock); |
892 | while (ret >= 0 && (len > 0 || ooblen > 0)) { | 892 | while (ret >= 0 && (len > 0 || ooblen > 0)) { |
893 | calc_block_sector(from - skip, &block0, &block1, &page, &ofs, | 893 | calc_block_sector(from - skip, &block0, &block1, &page, &ofs, |
894 | docg3->reliable); | 894 | docg3->reliable); |
895 | nbdata = min_t(size_t, len, DOC_LAYOUT_PAGE_SIZE - skip); | 895 | nbdata = min_t(size_t, len, DOC_LAYOUT_PAGE_SIZE - skip); |
896 | nboob = min_t(size_t, ooblen, (size_t)DOC_LAYOUT_OOB_SIZE); | 896 | nboob = min_t(size_t, ooblen, (size_t)DOC_LAYOUT_OOB_SIZE); |
897 | ret = doc_read_page_prepare(docg3, block0, block1, page, ofs); | 897 | ret = doc_read_page_prepare(docg3, block0, block1, page, ofs); |
898 | if (ret < 0) | 898 | if (ret < 0) |
899 | goto out; | 899 | goto out; |
900 | ret = doc_read_page_ecc_init(docg3, DOC_ECC_BCH_TOTAL_BYTES); | 900 | ret = doc_read_page_ecc_init(docg3, DOC_ECC_BCH_TOTAL_BYTES); |
901 | if (ret < 0) | 901 | if (ret < 0) |
902 | goto err_in_read; | 902 | goto err_in_read; |
903 | ret = doc_read_page_getbytes(docg3, skip, NULL, 1, 0); | 903 | ret = doc_read_page_getbytes(docg3, skip, NULL, 1, 0); |
904 | if (ret < skip) | 904 | if (ret < skip) |
905 | goto err_in_read; | 905 | goto err_in_read; |
906 | ret = doc_read_page_getbytes(docg3, nbdata, buf, 0, skip % 2); | 906 | ret = doc_read_page_getbytes(docg3, nbdata, buf, 0, skip % 2); |
907 | if (ret < nbdata) | 907 | if (ret < nbdata) |
908 | goto err_in_read; | 908 | goto err_in_read; |
909 | doc_read_page_getbytes(docg3, | 909 | doc_read_page_getbytes(docg3, |
910 | DOC_LAYOUT_PAGE_SIZE - nbdata - skip, | 910 | DOC_LAYOUT_PAGE_SIZE - nbdata - skip, |
911 | NULL, 0, (skip + nbdata) % 2); | 911 | NULL, 0, (skip + nbdata) % 2); |
912 | ret = doc_read_page_getbytes(docg3, nboob, oobbuf, 0, 0); | 912 | ret = doc_read_page_getbytes(docg3, nboob, oobbuf, 0, 0); |
913 | if (ret < nboob) | 913 | if (ret < nboob) |
914 | goto err_in_read; | 914 | goto err_in_read; |
915 | doc_read_page_getbytes(docg3, DOC_LAYOUT_OOB_SIZE - nboob, | 915 | doc_read_page_getbytes(docg3, DOC_LAYOUT_OOB_SIZE - nboob, |
916 | NULL, 0, nboob % 2); | 916 | NULL, 0, nboob % 2); |
917 | 917 | ||
918 | doc_get_bch_hw_ecc(docg3, hwecc); | 918 | doc_get_bch_hw_ecc(docg3, hwecc); |
919 | eccconf1 = doc_register_readb(docg3, DOC_ECCCONF1); | 919 | eccconf1 = doc_register_readb(docg3, DOC_ECCCONF1); |
920 | 920 | ||
921 | if (nboob >= DOC_LAYOUT_OOB_SIZE) { | 921 | if (nboob >= DOC_LAYOUT_OOB_SIZE) { |
922 | doc_dbg("OOB - INFO: %*phC\n", 7, oobbuf); | 922 | doc_dbg("OOB - INFO: %*phC\n", 7, oobbuf); |
923 | doc_dbg("OOB - HAMMING: %02x\n", oobbuf[7]); | 923 | doc_dbg("OOB - HAMMING: %02x\n", oobbuf[7]); |
924 | doc_dbg("OOB - BCH_ECC: %*phC\n", 7, oobbuf + 8); | 924 | doc_dbg("OOB - BCH_ECC: %*phC\n", 7, oobbuf + 8); |
925 | doc_dbg("OOB - UNUSED: %02x\n", oobbuf[15]); | 925 | doc_dbg("OOB - UNUSED: %02x\n", oobbuf[15]); |
926 | } | 926 | } |
927 | doc_dbg("ECC checks: ECCConf1=%x\n", eccconf1); | 927 | doc_dbg("ECC checks: ECCConf1=%x\n", eccconf1); |
928 | doc_dbg("ECC HW_ECC: %*phC\n", 7, hwecc); | 928 | doc_dbg("ECC HW_ECC: %*phC\n", 7, hwecc); |
929 | 929 | ||
930 | ret = -EIO; | 930 | ret = -EIO; |
931 | if (is_prot_seq_error(docg3)) | 931 | if (is_prot_seq_error(docg3)) |
932 | goto err_in_read; | 932 | goto err_in_read; |
933 | ret = 0; | 933 | ret = 0; |
934 | if ((block0 >= DOC_LAYOUT_BLOCK_FIRST_DATA) && | 934 | if ((block0 >= DOC_LAYOUT_BLOCK_FIRST_DATA) && |
935 | (eccconf1 & DOC_ECCCONF1_BCH_SYNDROM_ERR) && | 935 | (eccconf1 & DOC_ECCCONF1_BCH_SYNDROM_ERR) && |
936 | (eccconf1 & DOC_ECCCONF1_PAGE_IS_WRITTEN) && | 936 | (eccconf1 & DOC_ECCCONF1_PAGE_IS_WRITTEN) && |
937 | (ops->mode != MTD_OPS_RAW) && | 937 | (ops->mode != MTD_OPS_RAW) && |
938 | (nbdata == DOC_LAYOUT_PAGE_SIZE)) { | 938 | (nbdata == DOC_LAYOUT_PAGE_SIZE)) { |
939 | ret = doc_ecc_bch_fix_data(docg3, buf, hwecc); | 939 | ret = doc_ecc_bch_fix_data(docg3, buf, hwecc); |
940 | if (ret < 0) { | 940 | if (ret < 0) { |
941 | mtd->ecc_stats.failed++; | 941 | mtd->ecc_stats.failed++; |
942 | ret = -EBADMSG; | 942 | ret = -EBADMSG; |
943 | } | 943 | } |
944 | if (ret > 0) { | 944 | if (ret > 0) { |
945 | mtd->ecc_stats.corrected += ret; | 945 | mtd->ecc_stats.corrected += ret; |
946 | max_bitflips = max(max_bitflips, ret); | 946 | max_bitflips = max(max_bitflips, ret); |
947 | ret = max_bitflips; | 947 | ret = max_bitflips; |
948 | } | 948 | } |
949 | } | 949 | } |
950 | 950 | ||
951 | doc_read_page_finish(docg3); | 951 | doc_read_page_finish(docg3); |
952 | ops->retlen += nbdata; | 952 | ops->retlen += nbdata; |
953 | ops->oobretlen += nboob; | 953 | ops->oobretlen += nboob; |
954 | buf += nbdata; | 954 | buf += nbdata; |
955 | oobbuf += nboob; | 955 | oobbuf += nboob; |
956 | len -= nbdata; | 956 | len -= nbdata; |
957 | ooblen -= nboob; | 957 | ooblen -= nboob; |
958 | from += DOC_LAYOUT_PAGE_SIZE; | 958 | from += DOC_LAYOUT_PAGE_SIZE; |
959 | skip = 0; | 959 | skip = 0; |
960 | } | 960 | } |
961 | 961 | ||
962 | out: | 962 | out: |
963 | mutex_unlock(&docg3->cascade->lock); | 963 | mutex_unlock(&docg3->cascade->lock); |
964 | return ret; | 964 | return ret; |
965 | err_in_read: | 965 | err_in_read: |
966 | doc_read_page_finish(docg3); | 966 | doc_read_page_finish(docg3); |
967 | goto out; | 967 | goto out; |
968 | } | 968 | } |
969 | 969 | ||
970 | /** | 970 | /** |
971 | * doc_read - Read bytes from flash | 971 | * doc_read - Read bytes from flash |
972 | * @mtd: the device | 972 | * @mtd: the device |
973 | * @from: the offset from first block and first page, in bytes, aligned on page | 973 | * @from: the offset from first block and first page, in bytes, aligned on page |
974 | * size | 974 | * size |
975 | * @len: the number of bytes to read (must be a multiple of 4) | 975 | * @len: the number of bytes to read (must be a multiple of 4) |
976 | * @retlen: the number of bytes actually read | 976 | * @retlen: the number of bytes actually read |
977 | * @buf: the filled in buffer | 977 | * @buf: the filled in buffer |
978 | * | 978 | * |
979 | * Reads flash memory pages. This function does not read the OOB chunk, but only | 979 | * Reads flash memory pages. This function does not read the OOB chunk, but only |
980 | * the page data. | 980 | * the page data. |
981 | * | 981 | * |
982 | * Returns 0 if read successful, of -EIO, -EINVAL if an error occurred | 982 | * Returns 0 if read successful, of -EIO, -EINVAL if an error occurred |
983 | */ | 983 | */ |
984 | static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, | 984 | static int doc_read(struct mtd_info *mtd, loff_t from, size_t len, |
985 | size_t *retlen, u_char *buf) | 985 | size_t *retlen, u_char *buf) |
986 | { | 986 | { |
987 | struct mtd_oob_ops ops; | 987 | struct mtd_oob_ops ops; |
988 | size_t ret; | 988 | size_t ret; |
989 | 989 | ||
990 | memset(&ops, 0, sizeof(ops)); | 990 | memset(&ops, 0, sizeof(ops)); |
991 | ops.datbuf = buf; | 991 | ops.datbuf = buf; |
992 | ops.len = len; | 992 | ops.len = len; |
993 | ops.mode = MTD_OPS_AUTO_OOB; | 993 | ops.mode = MTD_OPS_AUTO_OOB; |
994 | 994 | ||
995 | ret = doc_read_oob(mtd, from, &ops); | 995 | ret = doc_read_oob(mtd, from, &ops); |
996 | *retlen = ops.retlen; | 996 | *retlen = ops.retlen; |
997 | return ret; | 997 | return ret; |
998 | } | 998 | } |
999 | 999 | ||
1000 | static int doc_reload_bbt(struct docg3 *docg3) | 1000 | static int doc_reload_bbt(struct docg3 *docg3) |
1001 | { | 1001 | { |
1002 | int block = DOC_LAYOUT_BLOCK_BBT; | 1002 | int block = DOC_LAYOUT_BLOCK_BBT; |
1003 | int ret = 0, nbpages, page; | 1003 | int ret = 0, nbpages, page; |
1004 | u_char *buf = docg3->bbt; | 1004 | u_char *buf = docg3->bbt; |
1005 | 1005 | ||
1006 | nbpages = DIV_ROUND_UP(docg3->max_block + 1, 8 * DOC_LAYOUT_PAGE_SIZE); | 1006 | nbpages = DIV_ROUND_UP(docg3->max_block + 1, 8 * DOC_LAYOUT_PAGE_SIZE); |
1007 | for (page = 0; !ret && (page < nbpages); page++) { | 1007 | for (page = 0; !ret && (page < nbpages); page++) { |
1008 | ret = doc_read_page_prepare(docg3, block, block + 1, | 1008 | ret = doc_read_page_prepare(docg3, block, block + 1, |
1009 | page + DOC_LAYOUT_PAGE_BBT, 0); | 1009 | page + DOC_LAYOUT_PAGE_BBT, 0); |
1010 | if (!ret) | 1010 | if (!ret) |
1011 | ret = doc_read_page_ecc_init(docg3, | 1011 | ret = doc_read_page_ecc_init(docg3, |
1012 | DOC_LAYOUT_PAGE_SIZE); | 1012 | DOC_LAYOUT_PAGE_SIZE); |
1013 | if (!ret) | 1013 | if (!ret) |
1014 | doc_read_page_getbytes(docg3, DOC_LAYOUT_PAGE_SIZE, | 1014 | doc_read_page_getbytes(docg3, DOC_LAYOUT_PAGE_SIZE, |
1015 | buf, 1, 0); | 1015 | buf, 1, 0); |
1016 | buf += DOC_LAYOUT_PAGE_SIZE; | 1016 | buf += DOC_LAYOUT_PAGE_SIZE; |
1017 | } | 1017 | } |
1018 | doc_read_page_finish(docg3); | 1018 | doc_read_page_finish(docg3); |
1019 | return ret; | 1019 | return ret; |
1020 | } | 1020 | } |
1021 | 1021 | ||
1022 | /** | 1022 | /** |
1023 | * doc_block_isbad - Checks whether a block is good or not | 1023 | * doc_block_isbad - Checks whether a block is good or not |
1024 | * @mtd: the device | 1024 | * @mtd: the device |
1025 | * @from: the offset to find the correct block | 1025 | * @from: the offset to find the correct block |
1026 | * | 1026 | * |
1027 | * Returns 1 if block is bad, 0 if block is good | 1027 | * Returns 1 if block is bad, 0 if block is good |
1028 | */ | 1028 | */ |
1029 | static int doc_block_isbad(struct mtd_info *mtd, loff_t from) | 1029 | static int doc_block_isbad(struct mtd_info *mtd, loff_t from) |
1030 | { | 1030 | { |
1031 | struct docg3 *docg3 = mtd->priv; | 1031 | struct docg3 *docg3 = mtd->priv; |
1032 | int block0, block1, page, ofs, is_good; | 1032 | int block0, block1, page, ofs, is_good; |
1033 | 1033 | ||
1034 | calc_block_sector(from, &block0, &block1, &page, &ofs, | 1034 | calc_block_sector(from, &block0, &block1, &page, &ofs, |
1035 | docg3->reliable); | 1035 | docg3->reliable); |
1036 | doc_dbg("doc_block_isbad(from=%lld) => block=(%d,%d), page=%d, ofs=%d\n", | 1036 | doc_dbg("doc_block_isbad(from=%lld) => block=(%d,%d), page=%d, ofs=%d\n", |
1037 | from, block0, block1, page, ofs); | 1037 | from, block0, block1, page, ofs); |
1038 | 1038 | ||
1039 | if (block0 < DOC_LAYOUT_BLOCK_FIRST_DATA) | 1039 | if (block0 < DOC_LAYOUT_BLOCK_FIRST_DATA) |
1040 | return 0; | 1040 | return 0; |
1041 | if (block1 > docg3->max_block) | 1041 | if (block1 > docg3->max_block) |
1042 | return -EINVAL; | 1042 | return -EINVAL; |
1043 | 1043 | ||
1044 | is_good = docg3->bbt[block0 >> 3] & (1 << (block0 & 0x7)); | 1044 | is_good = docg3->bbt[block0 >> 3] & (1 << (block0 & 0x7)); |
1045 | return !is_good; | 1045 | return !is_good; |
1046 | } | 1046 | } |
1047 | 1047 | ||
1048 | #if 0 | 1048 | #if 0 |
1049 | /** | 1049 | /** |
1050 | * doc_get_erase_count - Get block erase count | 1050 | * doc_get_erase_count - Get block erase count |
1051 | * @docg3: the device | 1051 | * @docg3: the device |
1052 | * @from: the offset in which the block is. | 1052 | * @from: the offset in which the block is. |
1053 | * | 1053 | * |
1054 | * Get the number of times a block was erased. The number is the maximum of | 1054 | * Get the number of times a block was erased. The number is the maximum of |
1055 | * erase times between first and second plane (which should be equal normally). | 1055 | * erase times between first and second plane (which should be equal normally). |
1056 | * | 1056 | * |
1057 | * Returns The number of erases, or -EINVAL or -EIO on error. | 1057 | * Returns The number of erases, or -EINVAL or -EIO on error. |
1058 | */ | 1058 | */ |
1059 | static int doc_get_erase_count(struct docg3 *docg3, loff_t from) | 1059 | static int doc_get_erase_count(struct docg3 *docg3, loff_t from) |
1060 | { | 1060 | { |
1061 | u8 buf[DOC_LAYOUT_WEAR_SIZE]; | 1061 | u8 buf[DOC_LAYOUT_WEAR_SIZE]; |
1062 | int ret, plane1_erase_count, plane2_erase_count; | 1062 | int ret, plane1_erase_count, plane2_erase_count; |
1063 | int block0, block1, page, ofs; | 1063 | int block0, block1, page, ofs; |
1064 | 1064 | ||
1065 | doc_dbg("doc_get_erase_count(from=%lld, buf=%p)\n", from, buf); | 1065 | doc_dbg("doc_get_erase_count(from=%lld, buf=%p)\n", from, buf); |
1066 | if (from % DOC_LAYOUT_PAGE_SIZE) | 1066 | if (from % DOC_LAYOUT_PAGE_SIZE) |
1067 | return -EINVAL; | 1067 | return -EINVAL; |
1068 | calc_block_sector(from, &block0, &block1, &page, &ofs, docg3->reliable); | 1068 | calc_block_sector(from, &block0, &block1, &page, &ofs, docg3->reliable); |
1069 | if (block1 > docg3->max_block) | 1069 | if (block1 > docg3->max_block) |
1070 | return -EINVAL; | 1070 | return -EINVAL; |
1071 | 1071 | ||
1072 | ret = doc_reset_seq(docg3); | 1072 | ret = doc_reset_seq(docg3); |
1073 | if (!ret) | 1073 | if (!ret) |
1074 | ret = doc_read_page_prepare(docg3, block0, block1, page, | 1074 | ret = doc_read_page_prepare(docg3, block0, block1, page, |
1075 | ofs + DOC_LAYOUT_WEAR_OFFSET, 0); | 1075 | ofs + DOC_LAYOUT_WEAR_OFFSET, 0); |
1076 | if (!ret) | 1076 | if (!ret) |
1077 | ret = doc_read_page_getbytes(docg3, DOC_LAYOUT_WEAR_SIZE, | 1077 | ret = doc_read_page_getbytes(docg3, DOC_LAYOUT_WEAR_SIZE, |
1078 | buf, 1, 0); | 1078 | buf, 1, 0); |
1079 | doc_read_page_finish(docg3); | 1079 | doc_read_page_finish(docg3); |
1080 | 1080 | ||
1081 | if (ret || (buf[0] != DOC_ERASE_MARK) || (buf[2] != DOC_ERASE_MARK)) | 1081 | if (ret || (buf[0] != DOC_ERASE_MARK) || (buf[2] != DOC_ERASE_MARK)) |
1082 | return -EIO; | 1082 | return -EIO; |
1083 | plane1_erase_count = (u8)(~buf[1]) | ((u8)(~buf[4]) << 8) | 1083 | plane1_erase_count = (u8)(~buf[1]) | ((u8)(~buf[4]) << 8) |
1084 | | ((u8)(~buf[5]) << 16); | 1084 | | ((u8)(~buf[5]) << 16); |
1085 | plane2_erase_count = (u8)(~buf[3]) | ((u8)(~buf[6]) << 8) | 1085 | plane2_erase_count = (u8)(~buf[3]) | ((u8)(~buf[6]) << 8) |
1086 | | ((u8)(~buf[7]) << 16); | 1086 | | ((u8)(~buf[7]) << 16); |
1087 | 1087 | ||
1088 | return max(plane1_erase_count, plane2_erase_count); | 1088 | return max(plane1_erase_count, plane2_erase_count); |
1089 | } | 1089 | } |
1090 | #endif | 1090 | #endif |
1091 | 1091 | ||
1092 | /** | 1092 | /** |
1093 | * doc_get_op_status - get erase/write operation status | 1093 | * doc_get_op_status - get erase/write operation status |
1094 | * @docg3: the device | 1094 | * @docg3: the device |
1095 | * | 1095 | * |
1096 | * Queries the status from the chip, and returns it | 1096 | * Queries the status from the chip, and returns it |
1097 | * | 1097 | * |
1098 | * Returns the status (bits DOC_PLANES_STATUS_*) | 1098 | * Returns the status (bits DOC_PLANES_STATUS_*) |
1099 | */ | 1099 | */ |
1100 | static int doc_get_op_status(struct docg3 *docg3) | 1100 | static int doc_get_op_status(struct docg3 *docg3) |
1101 | { | 1101 | { |
1102 | u8 status; | 1102 | u8 status; |
1103 | 1103 | ||
1104 | doc_flash_sequence(docg3, DOC_SEQ_PLANES_STATUS); | 1104 | doc_flash_sequence(docg3, DOC_SEQ_PLANES_STATUS); |
1105 | doc_flash_command(docg3, DOC_CMD_PLANES_STATUS); | 1105 | doc_flash_command(docg3, DOC_CMD_PLANES_STATUS); |
1106 | doc_delay(docg3, 5); | 1106 | doc_delay(docg3, 5); |
1107 | 1107 | ||
1108 | doc_ecc_disable(docg3); | 1108 | doc_ecc_disable(docg3); |
1109 | doc_read_data_area(docg3, &status, 1, 1); | 1109 | doc_read_data_area(docg3, &status, 1, 1); |
1110 | return status; | 1110 | return status; |
1111 | } | 1111 | } |
1112 | 1112 | ||
1113 | /** | 1113 | /** |
1114 | * doc_write_erase_wait_status - wait for write or erase completion | 1114 | * doc_write_erase_wait_status - wait for write or erase completion |
1115 | * @docg3: the device | 1115 | * @docg3: the device |
1116 | * | 1116 | * |
1117 | * Wait for the chip to be ready again after erase or write operation, and check | 1117 | * Wait for the chip to be ready again after erase or write operation, and check |
1118 | * erase/write status. | 1118 | * erase/write status. |
1119 | * | 1119 | * |
1120 | * Returns 0 if erase successful, -EIO if erase/write issue, -ETIMEOUT if | 1120 | * Returns 0 if erase successful, -EIO if erase/write issue, -ETIMEOUT if |
1121 | * timeout | 1121 | * timeout |
1122 | */ | 1122 | */ |
1123 | static int doc_write_erase_wait_status(struct docg3 *docg3) | 1123 | static int doc_write_erase_wait_status(struct docg3 *docg3) |
1124 | { | 1124 | { |
1125 | int i, status, ret = 0; | 1125 | int i, status, ret = 0; |
1126 | 1126 | ||
1127 | for (i = 0; !doc_is_ready(docg3) && i < 5; i++) | 1127 | for (i = 0; !doc_is_ready(docg3) && i < 5; i++) |
1128 | msleep(20); | 1128 | msleep(20); |
1129 | if (!doc_is_ready(docg3)) { | 1129 | if (!doc_is_ready(docg3)) { |
1130 | doc_dbg("Timeout reached and the chip is still not ready\n"); | 1130 | doc_dbg("Timeout reached and the chip is still not ready\n"); |
1131 | ret = -EAGAIN; | 1131 | ret = -EAGAIN; |
1132 | goto out; | 1132 | goto out; |
1133 | } | 1133 | } |
1134 | 1134 | ||
1135 | status = doc_get_op_status(docg3); | 1135 | status = doc_get_op_status(docg3); |
1136 | if (status & DOC_PLANES_STATUS_FAIL) { | 1136 | if (status & DOC_PLANES_STATUS_FAIL) { |
1137 | doc_dbg("Erase/Write failed on (a) plane(s), status = %x\n", | 1137 | doc_dbg("Erase/Write failed on (a) plane(s), status = %x\n", |
1138 | status); | 1138 | status); |
1139 | ret = -EIO; | 1139 | ret = -EIO; |
1140 | } | 1140 | } |
1141 | 1141 | ||
1142 | out: | 1142 | out: |
1143 | doc_page_finish(docg3); | 1143 | doc_page_finish(docg3); |
1144 | return ret; | 1144 | return ret; |
1145 | } | 1145 | } |
1146 | 1146 | ||
1147 | /** | 1147 | /** |
1148 | * doc_erase_block - Erase a couple of blocks | 1148 | * doc_erase_block - Erase a couple of blocks |
1149 | * @docg3: the device | 1149 | * @docg3: the device |
1150 | * @block0: the first block to erase (leftmost plane) | 1150 | * @block0: the first block to erase (leftmost plane) |
1151 | * @block1: the second block to erase (rightmost plane) | 1151 | * @block1: the second block to erase (rightmost plane) |
1152 | * | 1152 | * |
1153 | * Erase both blocks, and return operation status | 1153 | * Erase both blocks, and return operation status |
1154 | * | 1154 | * |
1155 | * Returns 0 if erase successful, -EIO if erase issue, -ETIMEOUT if chip not | 1155 | * Returns 0 if erase successful, -EIO if erase issue, -ETIMEOUT if chip not |
1156 | * ready for too long | 1156 | * ready for too long |
1157 | */ | 1157 | */ |
1158 | static int doc_erase_block(struct docg3 *docg3, int block0, int block1) | 1158 | static int doc_erase_block(struct docg3 *docg3, int block0, int block1) |
1159 | { | 1159 | { |
1160 | int ret, sector; | 1160 | int ret, sector; |
1161 | 1161 | ||
1162 | doc_dbg("doc_erase_block(blocks=(%d,%d))\n", block0, block1); | 1162 | doc_dbg("doc_erase_block(blocks=(%d,%d))\n", block0, block1); |
1163 | ret = doc_reset_seq(docg3); | 1163 | ret = doc_reset_seq(docg3); |
1164 | if (ret) | 1164 | if (ret) |
1165 | return -EIO; | 1165 | return -EIO; |
1166 | 1166 | ||
1167 | doc_set_reliable_mode(docg3); | 1167 | doc_set_reliable_mode(docg3); |
1168 | doc_flash_sequence(docg3, DOC_SEQ_ERASE); | 1168 | doc_flash_sequence(docg3, DOC_SEQ_ERASE); |
1169 | 1169 | ||
1170 | sector = block0 << DOC_ADDR_BLOCK_SHIFT; | 1170 | sector = block0 << DOC_ADDR_BLOCK_SHIFT; |
1171 | doc_flash_command(docg3, DOC_CMD_PROG_BLOCK_ADDR); | 1171 | doc_flash_command(docg3, DOC_CMD_PROG_BLOCK_ADDR); |
1172 | doc_setup_addr_sector(docg3, sector); | 1172 | doc_setup_addr_sector(docg3, sector); |
1173 | sector = block1 << DOC_ADDR_BLOCK_SHIFT; | 1173 | sector = block1 << DOC_ADDR_BLOCK_SHIFT; |
1174 | doc_flash_command(docg3, DOC_CMD_PROG_BLOCK_ADDR); | 1174 | doc_flash_command(docg3, DOC_CMD_PROG_BLOCK_ADDR); |
1175 | doc_setup_addr_sector(docg3, sector); | 1175 | doc_setup_addr_sector(docg3, sector); |
1176 | doc_delay(docg3, 1); | 1176 | doc_delay(docg3, 1); |
1177 | 1177 | ||
1178 | doc_flash_command(docg3, DOC_CMD_ERASECYCLE2); | 1178 | doc_flash_command(docg3, DOC_CMD_ERASECYCLE2); |
1179 | doc_delay(docg3, 2); | 1179 | doc_delay(docg3, 2); |
1180 | 1180 | ||
1181 | if (is_prot_seq_error(docg3)) { | 1181 | if (is_prot_seq_error(docg3)) { |
1182 | doc_err("Erase blocks %d,%d error\n", block0, block1); | 1182 | doc_err("Erase blocks %d,%d error\n", block0, block1); |
1183 | return -EIO; | 1183 | return -EIO; |
1184 | } | 1184 | } |
1185 | 1185 | ||
1186 | return doc_write_erase_wait_status(docg3); | 1186 | return doc_write_erase_wait_status(docg3); |
1187 | } | 1187 | } |
1188 | 1188 | ||
1189 | /** | 1189 | /** |
1190 | * doc_erase - Erase a portion of the chip | 1190 | * doc_erase - Erase a portion of the chip |
1191 | * @mtd: the device | 1191 | * @mtd: the device |
1192 | * @info: the erase info | 1192 | * @info: the erase info |
1193 | * | 1193 | * |
1194 | * Erase a bunch of contiguous blocks, by pairs, as a "mtd" page of 1024 is | 1194 | * Erase a bunch of contiguous blocks, by pairs, as a "mtd" page of 1024 is |
1195 | * split into 2 pages of 512 bytes on 2 contiguous blocks. | 1195 | * split into 2 pages of 512 bytes on 2 contiguous blocks. |
1196 | * | 1196 | * |
1197 | * Returns 0 if erase successful, -EINVAL if addressing error, -EIO if erase | 1197 | * Returns 0 if erase successful, -EINVAL if addressing error, -EIO if erase |
1198 | * issue | 1198 | * issue |
1199 | */ | 1199 | */ |
1200 | static int doc_erase(struct mtd_info *mtd, struct erase_info *info) | 1200 | static int doc_erase(struct mtd_info *mtd, struct erase_info *info) |
1201 | { | 1201 | { |
1202 | struct docg3 *docg3 = mtd->priv; | 1202 | struct docg3 *docg3 = mtd->priv; |
1203 | uint64_t len; | 1203 | uint64_t len; |
1204 | int block0, block1, page, ret, ofs = 0; | 1204 | int block0, block1, page, ret, ofs = 0; |
1205 | 1205 | ||
1206 | doc_dbg("doc_erase(from=%lld, len=%lld\n", info->addr, info->len); | 1206 | doc_dbg("doc_erase(from=%lld, len=%lld\n", info->addr, info->len); |
1207 | 1207 | ||
1208 | info->state = MTD_ERASE_PENDING; | 1208 | info->state = MTD_ERASE_PENDING; |
1209 | calc_block_sector(info->addr + info->len, &block0, &block1, &page, | 1209 | calc_block_sector(info->addr + info->len, &block0, &block1, &page, |
1210 | &ofs, docg3->reliable); | 1210 | &ofs, docg3->reliable); |
1211 | ret = -EINVAL; | 1211 | ret = -EINVAL; |
1212 | if (info->addr + info->len > mtd->size || page || ofs) | 1212 | if (info->addr + info->len > mtd->size || page || ofs) |
1213 | goto reset_err; | 1213 | goto reset_err; |
1214 | 1214 | ||
1215 | ret = 0; | 1215 | ret = 0; |
1216 | calc_block_sector(info->addr, &block0, &block1, &page, &ofs, | 1216 | calc_block_sector(info->addr, &block0, &block1, &page, &ofs, |
1217 | docg3->reliable); | 1217 | docg3->reliable); |
1218 | mutex_lock(&docg3->cascade->lock); | 1218 | mutex_lock(&docg3->cascade->lock); |
1219 | doc_set_device_id(docg3, docg3->device_id); | 1219 | doc_set_device_id(docg3, docg3->device_id); |
1220 | doc_set_reliable_mode(docg3); | 1220 | doc_set_reliable_mode(docg3); |
1221 | for (len = info->len; !ret && len > 0; len -= mtd->erasesize) { | 1221 | for (len = info->len; !ret && len > 0; len -= mtd->erasesize) { |
1222 | info->state = MTD_ERASING; | 1222 | info->state = MTD_ERASING; |
1223 | ret = doc_erase_block(docg3, block0, block1); | 1223 | ret = doc_erase_block(docg3, block0, block1); |
1224 | block0 += 2; | 1224 | block0 += 2; |
1225 | block1 += 2; | 1225 | block1 += 2; |
1226 | } | 1226 | } |
1227 | mutex_unlock(&docg3->cascade->lock); | 1227 | mutex_unlock(&docg3->cascade->lock); |
1228 | 1228 | ||
1229 | if (ret) | 1229 | if (ret) |
1230 | goto reset_err; | 1230 | goto reset_err; |
1231 | 1231 | ||
1232 | info->state = MTD_ERASE_DONE; | 1232 | info->state = MTD_ERASE_DONE; |
1233 | return 0; | 1233 | return 0; |
1234 | 1234 | ||
1235 | reset_err: | 1235 | reset_err: |
1236 | info->state = MTD_ERASE_FAILED; | 1236 | info->state = MTD_ERASE_FAILED; |
1237 | return ret; | 1237 | return ret; |
1238 | } | 1238 | } |
1239 | 1239 | ||
1240 | /** | 1240 | /** |
1241 | * doc_write_page - Write a single page to the chip | 1241 | * doc_write_page - Write a single page to the chip |
1242 | * @docg3: the device | 1242 | * @docg3: the device |
1243 | * @to: the offset from first block and first page, in bytes, aligned on page | 1243 | * @to: the offset from first block and first page, in bytes, aligned on page |
1244 | * size | 1244 | * size |
1245 | * @buf: buffer to get bytes from | 1245 | * @buf: buffer to get bytes from |
1246 | * @oob: buffer to get out of band bytes from (can be NULL if no OOB should be | 1246 | * @oob: buffer to get out of band bytes from (can be NULL if no OOB should be |
1247 | * written) | 1247 | * written) |
1248 | * @autoecc: if 0, all 16 bytes from OOB are taken, regardless of HW Hamming or | 1248 | * @autoecc: if 0, all 16 bytes from OOB are taken, regardless of HW Hamming or |
1249 | * BCH computations. If 1, only bytes 0-7 and byte 15 are taken, | 1249 | * BCH computations. If 1, only bytes 0-7 and byte 15 are taken, |
1250 | * remaining ones are filled with hardware Hamming and BCH | 1250 | * remaining ones are filled with hardware Hamming and BCH |
1251 | * computations. Its value is not meaningfull is oob == NULL. | 1251 | * computations. Its value is not meaningfull is oob == NULL. |
1252 | * | 1252 | * |
1253 | * Write one full page (ie. 1 page split on two planes), of 512 bytes, with the | 1253 | * Write one full page (ie. 1 page split on two planes), of 512 bytes, with the |
1254 | * OOB data. The OOB ECC is automatically computed by the hardware Hamming and | 1254 | * OOB data. The OOB ECC is automatically computed by the hardware Hamming and |
1255 | * BCH generator if autoecc is not null. | 1255 | * BCH generator if autoecc is not null. |
1256 | * | 1256 | * |
1257 | * Returns 0 if write successful, -EIO if write error, -EAGAIN if timeout | 1257 | * Returns 0 if write successful, -EIO if write error, -EAGAIN if timeout |
1258 | */ | 1258 | */ |
1259 | static int doc_write_page(struct docg3 *docg3, loff_t to, const u_char *buf, | 1259 | static int doc_write_page(struct docg3 *docg3, loff_t to, const u_char *buf, |
1260 | const u_char *oob, int autoecc) | 1260 | const u_char *oob, int autoecc) |
1261 | { | 1261 | { |
1262 | int block0, block1, page, ret, ofs = 0; | 1262 | int block0, block1, page, ret, ofs = 0; |
1263 | u8 hwecc[DOC_ECC_BCH_SIZE], hamming; | 1263 | u8 hwecc[DOC_ECC_BCH_SIZE], hamming; |
1264 | 1264 | ||
1265 | doc_dbg("doc_write_page(to=%lld)\n", to); | 1265 | doc_dbg("doc_write_page(to=%lld)\n", to); |
1266 | calc_block_sector(to, &block0, &block1, &page, &ofs, docg3->reliable); | 1266 | calc_block_sector(to, &block0, &block1, &page, &ofs, docg3->reliable); |
1267 | 1267 | ||
1268 | doc_set_device_id(docg3, docg3->device_id); | 1268 | doc_set_device_id(docg3, docg3->device_id); |
1269 | ret = doc_reset_seq(docg3); | 1269 | ret = doc_reset_seq(docg3); |
1270 | if (ret) | 1270 | if (ret) |
1271 | goto err; | 1271 | goto err; |
1272 | 1272 | ||
1273 | /* Program the flash address block and page */ | 1273 | /* Program the flash address block and page */ |
1274 | ret = doc_write_seek(docg3, block0, block1, page, ofs); | 1274 | ret = doc_write_seek(docg3, block0, block1, page, ofs); |
1275 | if (ret) | 1275 | if (ret) |
1276 | goto err; | 1276 | goto err; |
1277 | 1277 | ||
1278 | doc_write_page_ecc_init(docg3, DOC_ECC_BCH_TOTAL_BYTES); | 1278 | doc_write_page_ecc_init(docg3, DOC_ECC_BCH_TOTAL_BYTES); |
1279 | doc_delay(docg3, 2); | 1279 | doc_delay(docg3, 2); |
1280 | doc_write_page_putbytes(docg3, DOC_LAYOUT_PAGE_SIZE, buf); | 1280 | doc_write_page_putbytes(docg3, DOC_LAYOUT_PAGE_SIZE, buf); |
1281 | 1281 | ||
1282 | if (oob && autoecc) { | 1282 | if (oob && autoecc) { |
1283 | doc_write_page_putbytes(docg3, DOC_LAYOUT_OOB_PAGEINFO_SZ, oob); | 1283 | doc_write_page_putbytes(docg3, DOC_LAYOUT_OOB_PAGEINFO_SZ, oob); |
1284 | doc_delay(docg3, 2); | 1284 | doc_delay(docg3, 2); |
1285 | oob += DOC_LAYOUT_OOB_UNUSED_OFS; | 1285 | oob += DOC_LAYOUT_OOB_UNUSED_OFS; |
1286 | 1286 | ||
1287 | hamming = doc_register_readb(docg3, DOC_HAMMINGPARITY); | 1287 | hamming = doc_register_readb(docg3, DOC_HAMMINGPARITY); |
1288 | doc_delay(docg3, 2); | 1288 | doc_delay(docg3, 2); |
1289 | doc_write_page_putbytes(docg3, DOC_LAYOUT_OOB_HAMMING_SZ, | 1289 | doc_write_page_putbytes(docg3, DOC_LAYOUT_OOB_HAMMING_SZ, |
1290 | &hamming); | 1290 | &hamming); |
1291 | doc_delay(docg3, 2); | 1291 | doc_delay(docg3, 2); |
1292 | 1292 | ||
1293 | doc_get_bch_hw_ecc(docg3, hwecc); | 1293 | doc_get_bch_hw_ecc(docg3, hwecc); |
1294 | doc_write_page_putbytes(docg3, DOC_LAYOUT_OOB_BCH_SZ, hwecc); | 1294 | doc_write_page_putbytes(docg3, DOC_LAYOUT_OOB_BCH_SZ, hwecc); |
1295 | doc_delay(docg3, 2); | 1295 | doc_delay(docg3, 2); |
1296 | 1296 | ||
1297 | doc_write_page_putbytes(docg3, DOC_LAYOUT_OOB_UNUSED_SZ, oob); | 1297 | doc_write_page_putbytes(docg3, DOC_LAYOUT_OOB_UNUSED_SZ, oob); |
1298 | } | 1298 | } |
1299 | if (oob && !autoecc) | 1299 | if (oob && !autoecc) |
1300 | doc_write_page_putbytes(docg3, DOC_LAYOUT_OOB_SIZE, oob); | 1300 | doc_write_page_putbytes(docg3, DOC_LAYOUT_OOB_SIZE, oob); |
1301 | 1301 | ||
1302 | doc_delay(docg3, 2); | 1302 | doc_delay(docg3, 2); |
1303 | doc_page_finish(docg3); | 1303 | doc_page_finish(docg3); |
1304 | doc_delay(docg3, 2); | 1304 | doc_delay(docg3, 2); |
1305 | doc_flash_command(docg3, DOC_CMD_PROG_CYCLE2); | 1305 | doc_flash_command(docg3, DOC_CMD_PROG_CYCLE2); |
1306 | doc_delay(docg3, 2); | 1306 | doc_delay(docg3, 2); |
1307 | 1307 | ||
1308 | /* | 1308 | /* |
1309 | * The wait status will perform another doc_page_finish() call, but that | 1309 | * The wait status will perform another doc_page_finish() call, but that |
1310 | * seems to please the docg3, so leave it. | 1310 | * seems to please the docg3, so leave it. |
1311 | */ | 1311 | */ |
1312 | ret = doc_write_erase_wait_status(docg3); | 1312 | ret = doc_write_erase_wait_status(docg3); |
1313 | return ret; | 1313 | return ret; |
1314 | err: | 1314 | err: |
1315 | doc_read_page_finish(docg3); | 1315 | doc_read_page_finish(docg3); |
1316 | return ret; | 1316 | return ret; |
1317 | } | 1317 | } |
1318 | 1318 | ||
1319 | /** | 1319 | /** |
1320 | * doc_guess_autoecc - Guess autoecc mode from mbd_oob_ops | 1320 | * doc_guess_autoecc - Guess autoecc mode from mbd_oob_ops |
1321 | * @ops: the oob operations | 1321 | * @ops: the oob operations |
1322 | * | 1322 | * |
1323 | * Returns 0 or 1 if success, -EINVAL if invalid oob mode | 1323 | * Returns 0 or 1 if success, -EINVAL if invalid oob mode |
1324 | */ | 1324 | */ |
1325 | static int doc_guess_autoecc(struct mtd_oob_ops *ops) | 1325 | static int doc_guess_autoecc(struct mtd_oob_ops *ops) |
1326 | { | 1326 | { |
1327 | int autoecc; | 1327 | int autoecc; |
1328 | 1328 | ||
1329 | switch (ops->mode) { | 1329 | switch (ops->mode) { |
1330 | case MTD_OPS_PLACE_OOB: | 1330 | case MTD_OPS_PLACE_OOB: |
1331 | case MTD_OPS_AUTO_OOB: | 1331 | case MTD_OPS_AUTO_OOB: |
1332 | autoecc = 1; | 1332 | autoecc = 1; |
1333 | break; | 1333 | break; |
1334 | case MTD_OPS_RAW: | 1334 | case MTD_OPS_RAW: |
1335 | autoecc = 0; | 1335 | autoecc = 0; |
1336 | break; | 1336 | break; |
1337 | default: | 1337 | default: |
1338 | autoecc = -EINVAL; | 1338 | autoecc = -EINVAL; |
1339 | } | 1339 | } |
1340 | return autoecc; | 1340 | return autoecc; |
1341 | } | 1341 | } |
1342 | 1342 | ||
1343 | /** | 1343 | /** |
1344 | * doc_fill_autooob - Fill a 16 bytes OOB from 8 non-ECC bytes | 1344 | * doc_fill_autooob - Fill a 16 bytes OOB from 8 non-ECC bytes |
1345 | * @dst: the target 16 bytes OOB buffer | 1345 | * @dst: the target 16 bytes OOB buffer |
1346 | * @oobsrc: the source 8 bytes non-ECC OOB buffer | 1346 | * @oobsrc: the source 8 bytes non-ECC OOB buffer |
1347 | * | 1347 | * |
1348 | */ | 1348 | */ |
1349 | static void doc_fill_autooob(u8 *dst, u8 *oobsrc) | 1349 | static void doc_fill_autooob(u8 *dst, u8 *oobsrc) |
1350 | { | 1350 | { |
1351 | memcpy(dst, oobsrc, DOC_LAYOUT_OOB_PAGEINFO_SZ); | 1351 | memcpy(dst, oobsrc, DOC_LAYOUT_OOB_PAGEINFO_SZ); |
1352 | dst[DOC_LAYOUT_OOB_UNUSED_OFS] = oobsrc[DOC_LAYOUT_OOB_PAGEINFO_SZ]; | 1352 | dst[DOC_LAYOUT_OOB_UNUSED_OFS] = oobsrc[DOC_LAYOUT_OOB_PAGEINFO_SZ]; |
1353 | } | 1353 | } |
1354 | 1354 | ||
1355 | /** | 1355 | /** |
1356 | * doc_backup_oob - Backup OOB into docg3 structure | 1356 | * doc_backup_oob - Backup OOB into docg3 structure |
1357 | * @docg3: the device | 1357 | * @docg3: the device |
1358 | * @to: the page offset in the chip | 1358 | * @to: the page offset in the chip |
1359 | * @ops: the OOB size and buffer | 1359 | * @ops: the OOB size and buffer |
1360 | * | 1360 | * |
1361 | * As the docg3 should write a page with its OOB in one pass, and some userland | 1361 | * As the docg3 should write a page with its OOB in one pass, and some userland |
1362 | * applications do write_oob() to setup the OOB and then write(), store the OOB | 1362 | * applications do write_oob() to setup the OOB and then write(), store the OOB |
1363 | * into a temporary storage. This is very dangerous, as 2 concurrent | 1363 | * into a temporary storage. This is very dangerous, as 2 concurrent |
1364 | * applications could store an OOB, and then write their pages (which will | 1364 | * applications could store an OOB, and then write their pages (which will |
1365 | * result into one having its OOB corrupted). | 1365 | * result into one having its OOB corrupted). |
1366 | * | 1366 | * |
1367 | * The only reliable way would be for userland to call doc_write_oob() with both | 1367 | * The only reliable way would be for userland to call doc_write_oob() with both |
1368 | * the page data _and_ the OOB area. | 1368 | * the page data _and_ the OOB area. |
1369 | * | 1369 | * |
1370 | * Returns 0 if success, -EINVAL if ops content invalid | 1370 | * Returns 0 if success, -EINVAL if ops content invalid |
1371 | */ | 1371 | */ |
1372 | static int doc_backup_oob(struct docg3 *docg3, loff_t to, | 1372 | static int doc_backup_oob(struct docg3 *docg3, loff_t to, |
1373 | struct mtd_oob_ops *ops) | 1373 | struct mtd_oob_ops *ops) |
1374 | { | 1374 | { |
1375 | int ooblen = ops->ooblen, autoecc; | 1375 | int ooblen = ops->ooblen, autoecc; |
1376 | 1376 | ||
1377 | if (ooblen != DOC_LAYOUT_OOB_SIZE) | 1377 | if (ooblen != DOC_LAYOUT_OOB_SIZE) |
1378 | return -EINVAL; | 1378 | return -EINVAL; |
1379 | autoecc = doc_guess_autoecc(ops); | 1379 | autoecc = doc_guess_autoecc(ops); |
1380 | if (autoecc < 0) | 1380 | if (autoecc < 0) |
1381 | return autoecc; | 1381 | return autoecc; |
1382 | 1382 | ||
1383 | docg3->oob_write_ofs = to; | 1383 | docg3->oob_write_ofs = to; |
1384 | docg3->oob_autoecc = autoecc; | 1384 | docg3->oob_autoecc = autoecc; |
1385 | if (ops->mode == MTD_OPS_AUTO_OOB) { | 1385 | if (ops->mode == MTD_OPS_AUTO_OOB) { |
1386 | doc_fill_autooob(docg3->oob_write_buf, ops->oobbuf); | 1386 | doc_fill_autooob(docg3->oob_write_buf, ops->oobbuf); |
1387 | ops->oobretlen = 8; | 1387 | ops->oobretlen = 8; |
1388 | } else { | 1388 | } else { |
1389 | memcpy(docg3->oob_write_buf, ops->oobbuf, DOC_LAYOUT_OOB_SIZE); | 1389 | memcpy(docg3->oob_write_buf, ops->oobbuf, DOC_LAYOUT_OOB_SIZE); |
1390 | ops->oobretlen = DOC_LAYOUT_OOB_SIZE; | 1390 | ops->oobretlen = DOC_LAYOUT_OOB_SIZE; |
1391 | } | 1391 | } |
1392 | return 0; | 1392 | return 0; |
1393 | } | 1393 | } |
1394 | 1394 | ||
1395 | /** | 1395 | /** |
1396 | * doc_write_oob - Write out of band bytes to flash | 1396 | * doc_write_oob - Write out of band bytes to flash |
1397 | * @mtd: the device | 1397 | * @mtd: the device |
1398 | * @ofs: the offset from first block and first page, in bytes, aligned on page | 1398 | * @ofs: the offset from first block and first page, in bytes, aligned on page |
1399 | * size | 1399 | * size |
1400 | * @ops: the mtd oob structure | 1400 | * @ops: the mtd oob structure |
1401 | * | 1401 | * |
1402 | * Either write OOB data into a temporary buffer, for the subsequent write | 1402 | * Either write OOB data into a temporary buffer, for the subsequent write |
1403 | * page. The provided OOB should be 16 bytes long. If a data buffer is provided | 1403 | * page. The provided OOB should be 16 bytes long. If a data buffer is provided |
1404 | * as well, issue the page write. | 1404 | * as well, issue the page write. |
1405 | * Or provide data without OOB, and then a all zeroed OOB will be used (ECC will | 1405 | * Or provide data without OOB, and then a all zeroed OOB will be used (ECC will |
1406 | * still be filled in if asked for). | 1406 | * still be filled in if asked for). |
1407 | * | 1407 | * |
1408 | * Returns 0 is successful, EINVAL if length is not 14 bytes | 1408 | * Returns 0 is successful, EINVAL if length is not 14 bytes |
1409 | */ | 1409 | */ |
1410 | static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, | 1410 | static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, |
1411 | struct mtd_oob_ops *ops) | 1411 | struct mtd_oob_ops *ops) |
1412 | { | 1412 | { |
1413 | struct docg3 *docg3 = mtd->priv; | 1413 | struct docg3 *docg3 = mtd->priv; |
1414 | int ret, autoecc, oobdelta; | 1414 | int ret, autoecc, oobdelta; |
1415 | u8 *oobbuf = ops->oobbuf; | 1415 | u8 *oobbuf = ops->oobbuf; |
1416 | u8 *buf = ops->datbuf; | 1416 | u8 *buf = ops->datbuf; |
1417 | size_t len, ooblen; | 1417 | size_t len, ooblen; |
1418 | u8 oob[DOC_LAYOUT_OOB_SIZE]; | 1418 | u8 oob[DOC_LAYOUT_OOB_SIZE]; |
1419 | 1419 | ||
1420 | if (buf) | 1420 | if (buf) |
1421 | len = ops->len; | 1421 | len = ops->len; |
1422 | else | 1422 | else |
1423 | len = 0; | 1423 | len = 0; |
1424 | if (oobbuf) | 1424 | if (oobbuf) |
1425 | ooblen = ops->ooblen; | 1425 | ooblen = ops->ooblen; |
1426 | else | 1426 | else |
1427 | ooblen = 0; | 1427 | ooblen = 0; |
1428 | 1428 | ||
1429 | if (oobbuf && ops->mode == MTD_OPS_PLACE_OOB) | 1429 | if (oobbuf && ops->mode == MTD_OPS_PLACE_OOB) |
1430 | oobbuf += ops->ooboffs; | 1430 | oobbuf += ops->ooboffs; |
1431 | 1431 | ||
1432 | doc_dbg("doc_write_oob(from=%lld, mode=%d, data=(%p:%zu), oob=(%p:%zu))\n", | 1432 | doc_dbg("doc_write_oob(from=%lld, mode=%d, data=(%p:%zu), oob=(%p:%zu))\n", |
1433 | ofs, ops->mode, buf, len, oobbuf, ooblen); | 1433 | ofs, ops->mode, buf, len, oobbuf, ooblen); |
1434 | switch (ops->mode) { | 1434 | switch (ops->mode) { |
1435 | case MTD_OPS_PLACE_OOB: | 1435 | case MTD_OPS_PLACE_OOB: |
1436 | case MTD_OPS_RAW: | 1436 | case MTD_OPS_RAW: |
1437 | oobdelta = mtd->oobsize; | 1437 | oobdelta = mtd->oobsize; |
1438 | break; | 1438 | break; |
1439 | case MTD_OPS_AUTO_OOB: | 1439 | case MTD_OPS_AUTO_OOB: |
1440 | oobdelta = mtd->ecclayout->oobavail; | 1440 | oobdelta = mtd->ecclayout->oobavail; |
1441 | break; | 1441 | break; |
1442 | default: | 1442 | default: |
1443 | return -EINVAL; | 1443 | return -EINVAL; |
1444 | } | 1444 | } |
1445 | if ((len % DOC_LAYOUT_PAGE_SIZE) || (ooblen % oobdelta) || | 1445 | if ((len % DOC_LAYOUT_PAGE_SIZE) || (ooblen % oobdelta) || |
1446 | (ofs % DOC_LAYOUT_PAGE_SIZE)) | 1446 | (ofs % DOC_LAYOUT_PAGE_SIZE)) |
1447 | return -EINVAL; | 1447 | return -EINVAL; |
1448 | if (len && ooblen && | 1448 | if (len && ooblen && |
1449 | (len / DOC_LAYOUT_PAGE_SIZE) != (ooblen / oobdelta)) | 1449 | (len / DOC_LAYOUT_PAGE_SIZE) != (ooblen / oobdelta)) |
1450 | return -EINVAL; | 1450 | return -EINVAL; |
1451 | if (ofs + len > mtd->size) | 1451 | if (ofs + len > mtd->size) |
1452 | return -EINVAL; | 1452 | return -EINVAL; |
1453 | 1453 | ||
1454 | ops->oobretlen = 0; | 1454 | ops->oobretlen = 0; |
1455 | ops->retlen = 0; | 1455 | ops->retlen = 0; |
1456 | ret = 0; | 1456 | ret = 0; |
1457 | if (len == 0 && ooblen == 0) | 1457 | if (len == 0 && ooblen == 0) |
1458 | return -EINVAL; | 1458 | return -EINVAL; |
1459 | if (len == 0 && ooblen > 0) | 1459 | if (len == 0 && ooblen > 0) |
1460 | return doc_backup_oob(docg3, ofs, ops); | 1460 | return doc_backup_oob(docg3, ofs, ops); |
1461 | 1461 | ||
1462 | autoecc = doc_guess_autoecc(ops); | 1462 | autoecc = doc_guess_autoecc(ops); |
1463 | if (autoecc < 0) | 1463 | if (autoecc < 0) |
1464 | return autoecc; | 1464 | return autoecc; |
1465 | 1465 | ||
1466 | mutex_lock(&docg3->cascade->lock); | 1466 | mutex_lock(&docg3->cascade->lock); |
1467 | while (!ret && len > 0) { | 1467 | while (!ret && len > 0) { |
1468 | memset(oob, 0, sizeof(oob)); | 1468 | memset(oob, 0, sizeof(oob)); |
1469 | if (ofs == docg3->oob_write_ofs) | 1469 | if (ofs == docg3->oob_write_ofs) |
1470 | memcpy(oob, docg3->oob_write_buf, DOC_LAYOUT_OOB_SIZE); | 1470 | memcpy(oob, docg3->oob_write_buf, DOC_LAYOUT_OOB_SIZE); |
1471 | else if (ooblen > 0 && ops->mode == MTD_OPS_AUTO_OOB) | 1471 | else if (ooblen > 0 && ops->mode == MTD_OPS_AUTO_OOB) |
1472 | doc_fill_autooob(oob, oobbuf); | 1472 | doc_fill_autooob(oob, oobbuf); |
1473 | else if (ooblen > 0) | 1473 | else if (ooblen > 0) |
1474 | memcpy(oob, oobbuf, DOC_LAYOUT_OOB_SIZE); | 1474 | memcpy(oob, oobbuf, DOC_LAYOUT_OOB_SIZE); |
1475 | ret = doc_write_page(docg3, ofs, buf, oob, autoecc); | 1475 | ret = doc_write_page(docg3, ofs, buf, oob, autoecc); |
1476 | 1476 | ||
1477 | ofs += DOC_LAYOUT_PAGE_SIZE; | 1477 | ofs += DOC_LAYOUT_PAGE_SIZE; |
1478 | len -= DOC_LAYOUT_PAGE_SIZE; | 1478 | len -= DOC_LAYOUT_PAGE_SIZE; |
1479 | buf += DOC_LAYOUT_PAGE_SIZE; | 1479 | buf += DOC_LAYOUT_PAGE_SIZE; |
1480 | if (ooblen) { | 1480 | if (ooblen) { |
1481 | oobbuf += oobdelta; | 1481 | oobbuf += oobdelta; |
1482 | ooblen -= oobdelta; | 1482 | ooblen -= oobdelta; |
1483 | ops->oobretlen += oobdelta; | 1483 | ops->oobretlen += oobdelta; |
1484 | } | 1484 | } |
1485 | ops->retlen += DOC_LAYOUT_PAGE_SIZE; | 1485 | ops->retlen += DOC_LAYOUT_PAGE_SIZE; |
1486 | } | 1486 | } |
1487 | 1487 | ||
1488 | doc_set_device_id(docg3, 0); | 1488 | doc_set_device_id(docg3, 0); |
1489 | mutex_unlock(&docg3->cascade->lock); | 1489 | mutex_unlock(&docg3->cascade->lock); |
1490 | return ret; | 1490 | return ret; |
1491 | } | 1491 | } |
1492 | 1492 | ||
1493 | /** | 1493 | /** |
1494 | * doc_write - Write a buffer to the chip | 1494 | * doc_write - Write a buffer to the chip |
1495 | * @mtd: the device | 1495 | * @mtd: the device |
1496 | * @to: the offset from first block and first page, in bytes, aligned on page | 1496 | * @to: the offset from first block and first page, in bytes, aligned on page |
1497 | * size | 1497 | * size |
1498 | * @len: the number of bytes to write (must be a full page size, ie. 512) | 1498 | * @len: the number of bytes to write (must be a full page size, ie. 512) |
1499 | * @retlen: the number of bytes actually written (0 or 512) | 1499 | * @retlen: the number of bytes actually written (0 or 512) |
1500 | * @buf: the buffer to get bytes from | 1500 | * @buf: the buffer to get bytes from |
1501 | * | 1501 | * |
1502 | * Writes data to the chip. | 1502 | * Writes data to the chip. |
1503 | * | 1503 | * |
1504 | * Returns 0 if write successful, -EIO if write error | 1504 | * Returns 0 if write successful, -EIO if write error |
1505 | */ | 1505 | */ |
1506 | static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, | 1506 | static int doc_write(struct mtd_info *mtd, loff_t to, size_t len, |
1507 | size_t *retlen, const u_char *buf) | 1507 | size_t *retlen, const u_char *buf) |
1508 | { | 1508 | { |
1509 | struct docg3 *docg3 = mtd->priv; | 1509 | struct docg3 *docg3 = mtd->priv; |
1510 | int ret; | 1510 | int ret; |
1511 | struct mtd_oob_ops ops; | 1511 | struct mtd_oob_ops ops; |
1512 | 1512 | ||
1513 | doc_dbg("doc_write(to=%lld, len=%zu)\n", to, len); | 1513 | doc_dbg("doc_write(to=%lld, len=%zu)\n", to, len); |
1514 | ops.datbuf = (char *)buf; | 1514 | ops.datbuf = (char *)buf; |
1515 | ops.len = len; | 1515 | ops.len = len; |
1516 | ops.mode = MTD_OPS_PLACE_OOB; | 1516 | ops.mode = MTD_OPS_PLACE_OOB; |
1517 | ops.oobbuf = NULL; | 1517 | ops.oobbuf = NULL; |
1518 | ops.ooblen = 0; | 1518 | ops.ooblen = 0; |
1519 | ops.ooboffs = 0; | 1519 | ops.ooboffs = 0; |
1520 | 1520 | ||
1521 | ret = doc_write_oob(mtd, to, &ops); | 1521 | ret = doc_write_oob(mtd, to, &ops); |
1522 | *retlen = ops.retlen; | 1522 | *retlen = ops.retlen; |
1523 | return ret; | 1523 | return ret; |
1524 | } | 1524 | } |
1525 | 1525 | ||
1526 | static struct docg3 *sysfs_dev2docg3(struct device *dev, | 1526 | static struct docg3 *sysfs_dev2docg3(struct device *dev, |
1527 | struct device_attribute *attr) | 1527 | struct device_attribute *attr) |
1528 | { | 1528 | { |
1529 | int floor; | 1529 | int floor; |
1530 | struct platform_device *pdev = to_platform_device(dev); | 1530 | struct platform_device *pdev = to_platform_device(dev); |
1531 | struct mtd_info **docg3_floors = platform_get_drvdata(pdev); | 1531 | struct mtd_info **docg3_floors = platform_get_drvdata(pdev); |
1532 | 1532 | ||
1533 | floor = attr->attr.name[1] - '0'; | 1533 | floor = attr->attr.name[1] - '0'; |
1534 | if (floor < 0 || floor >= DOC_MAX_NBFLOORS) | 1534 | if (floor < 0 || floor >= DOC_MAX_NBFLOORS) |
1535 | return NULL; | 1535 | return NULL; |
1536 | else | 1536 | else |
1537 | return docg3_floors[floor]->priv; | 1537 | return docg3_floors[floor]->priv; |
1538 | } | 1538 | } |
1539 | 1539 | ||
1540 | static ssize_t dps0_is_key_locked(struct device *dev, | 1540 | static ssize_t dps0_is_key_locked(struct device *dev, |
1541 | struct device_attribute *attr, char *buf) | 1541 | struct device_attribute *attr, char *buf) |
1542 | { | 1542 | { |
1543 | struct docg3 *docg3 = sysfs_dev2docg3(dev, attr); | 1543 | struct docg3 *docg3 = sysfs_dev2docg3(dev, attr); |
1544 | int dps0; | 1544 | int dps0; |
1545 | 1545 | ||
1546 | mutex_lock(&docg3->cascade->lock); | 1546 | mutex_lock(&docg3->cascade->lock); |
1547 | doc_set_device_id(docg3, docg3->device_id); | 1547 | doc_set_device_id(docg3, docg3->device_id); |
1548 | dps0 = doc_register_readb(docg3, DOC_DPS0_STATUS); | 1548 | dps0 = doc_register_readb(docg3, DOC_DPS0_STATUS); |
1549 | doc_set_device_id(docg3, 0); | 1549 | doc_set_device_id(docg3, 0); |
1550 | mutex_unlock(&docg3->cascade->lock); | 1550 | mutex_unlock(&docg3->cascade->lock); |
1551 | 1551 | ||
1552 | return sprintf(buf, "%d\n", !(dps0 & DOC_DPS_KEY_OK)); | 1552 | return sprintf(buf, "%d\n", !(dps0 & DOC_DPS_KEY_OK)); |
1553 | } | 1553 | } |
1554 | 1554 | ||
1555 | static ssize_t dps1_is_key_locked(struct device *dev, | 1555 | static ssize_t dps1_is_key_locked(struct device *dev, |
1556 | struct device_attribute *attr, char *buf) | 1556 | struct device_attribute *attr, char *buf) |
1557 | { | 1557 | { |
1558 | struct docg3 *docg3 = sysfs_dev2docg3(dev, attr); | 1558 | struct docg3 *docg3 = sysfs_dev2docg3(dev, attr); |
1559 | int dps1; | 1559 | int dps1; |
1560 | 1560 | ||
1561 | mutex_lock(&docg3->cascade->lock); | 1561 | mutex_lock(&docg3->cascade->lock); |
1562 | doc_set_device_id(docg3, docg3->device_id); | 1562 | doc_set_device_id(docg3, docg3->device_id); |
1563 | dps1 = doc_register_readb(docg3, DOC_DPS1_STATUS); | 1563 | dps1 = doc_register_readb(docg3, DOC_DPS1_STATUS); |
1564 | doc_set_device_id(docg3, 0); | 1564 | doc_set_device_id(docg3, 0); |
1565 | mutex_unlock(&docg3->cascade->lock); | 1565 | mutex_unlock(&docg3->cascade->lock); |
1566 | 1566 | ||
1567 | return sprintf(buf, "%d\n", !(dps1 & DOC_DPS_KEY_OK)); | 1567 | return sprintf(buf, "%d\n", !(dps1 & DOC_DPS_KEY_OK)); |
1568 | } | 1568 | } |
1569 | 1569 | ||
1570 | static ssize_t dps0_insert_key(struct device *dev, | 1570 | static ssize_t dps0_insert_key(struct device *dev, |
1571 | struct device_attribute *attr, | 1571 | struct device_attribute *attr, |
1572 | const char *buf, size_t count) | 1572 | const char *buf, size_t count) |
1573 | { | 1573 | { |
1574 | struct docg3 *docg3 = sysfs_dev2docg3(dev, attr); | 1574 | struct docg3 *docg3 = sysfs_dev2docg3(dev, attr); |
1575 | int i; | 1575 | int i; |
1576 | 1576 | ||
1577 | if (count != DOC_LAYOUT_DPS_KEY_LENGTH) | 1577 | if (count != DOC_LAYOUT_DPS_KEY_LENGTH) |
1578 | return -EINVAL; | 1578 | return -EINVAL; |
1579 | 1579 | ||
1580 | mutex_lock(&docg3->cascade->lock); | 1580 | mutex_lock(&docg3->cascade->lock); |
1581 | doc_set_device_id(docg3, docg3->device_id); | 1581 | doc_set_device_id(docg3, docg3->device_id); |
1582 | for (i = 0; i < DOC_LAYOUT_DPS_KEY_LENGTH; i++) | 1582 | for (i = 0; i < DOC_LAYOUT_DPS_KEY_LENGTH; i++) |
1583 | doc_writeb(docg3, buf[i], DOC_DPS0_KEY); | 1583 | doc_writeb(docg3, buf[i], DOC_DPS0_KEY); |
1584 | doc_set_device_id(docg3, 0); | 1584 | doc_set_device_id(docg3, 0); |
1585 | mutex_unlock(&docg3->cascade->lock); | 1585 | mutex_unlock(&docg3->cascade->lock); |
1586 | return count; | 1586 | return count; |
1587 | } | 1587 | } |
1588 | 1588 | ||
1589 | static ssize_t dps1_insert_key(struct device *dev, | 1589 | static ssize_t dps1_insert_key(struct device *dev, |
1590 | struct device_attribute *attr, | 1590 | struct device_attribute *attr, |
1591 | const char *buf, size_t count) | 1591 | const char *buf, size_t count) |
1592 | { | 1592 | { |
1593 | struct docg3 *docg3 = sysfs_dev2docg3(dev, attr); | 1593 | struct docg3 *docg3 = sysfs_dev2docg3(dev, attr); |
1594 | int i; | 1594 | int i; |
1595 | 1595 | ||
1596 | if (count != DOC_LAYOUT_DPS_KEY_LENGTH) | 1596 | if (count != DOC_LAYOUT_DPS_KEY_LENGTH) |
1597 | return -EINVAL; | 1597 | return -EINVAL; |
1598 | 1598 | ||
1599 | mutex_lock(&docg3->cascade->lock); | 1599 | mutex_lock(&docg3->cascade->lock); |
1600 | doc_set_device_id(docg3, docg3->device_id); | 1600 | doc_set_device_id(docg3, docg3->device_id); |
1601 | for (i = 0; i < DOC_LAYOUT_DPS_KEY_LENGTH; i++) | 1601 | for (i = 0; i < DOC_LAYOUT_DPS_KEY_LENGTH; i++) |
1602 | doc_writeb(docg3, buf[i], DOC_DPS1_KEY); | 1602 | doc_writeb(docg3, buf[i], DOC_DPS1_KEY); |
1603 | doc_set_device_id(docg3, 0); | 1603 | doc_set_device_id(docg3, 0); |
1604 | mutex_unlock(&docg3->cascade->lock); | 1604 | mutex_unlock(&docg3->cascade->lock); |
1605 | return count; | 1605 | return count; |
1606 | } | 1606 | } |
1607 | 1607 | ||
1608 | #define FLOOR_SYSFS(id) { \ | 1608 | #define FLOOR_SYSFS(id) { \ |
1609 | __ATTR(f##id##_dps0_is_keylocked, S_IRUGO, dps0_is_key_locked, NULL), \ | 1609 | __ATTR(f##id##_dps0_is_keylocked, S_IRUGO, dps0_is_key_locked, NULL), \ |
1610 | __ATTR(f##id##_dps1_is_keylocked, S_IRUGO, dps1_is_key_locked, NULL), \ | 1610 | __ATTR(f##id##_dps1_is_keylocked, S_IRUGO, dps1_is_key_locked, NULL), \ |
1611 | __ATTR(f##id##_dps0_protection_key, S_IWUGO, NULL, dps0_insert_key), \ | 1611 | __ATTR(f##id##_dps0_protection_key, S_IWUGO, NULL, dps0_insert_key), \ |
1612 | __ATTR(f##id##_dps1_protection_key, S_IWUGO, NULL, dps1_insert_key), \ | 1612 | __ATTR(f##id##_dps1_protection_key, S_IWUGO, NULL, dps1_insert_key), \ |
1613 | } | 1613 | } |
1614 | 1614 | ||
1615 | static struct device_attribute doc_sys_attrs[DOC_MAX_NBFLOORS][4] = { | 1615 | static struct device_attribute doc_sys_attrs[DOC_MAX_NBFLOORS][4] = { |
1616 | FLOOR_SYSFS(0), FLOOR_SYSFS(1), FLOOR_SYSFS(2), FLOOR_SYSFS(3) | 1616 | FLOOR_SYSFS(0), FLOOR_SYSFS(1), FLOOR_SYSFS(2), FLOOR_SYSFS(3) |
1617 | }; | 1617 | }; |
1618 | 1618 | ||
1619 | static int doc_register_sysfs(struct platform_device *pdev, | 1619 | static int doc_register_sysfs(struct platform_device *pdev, |
1620 | struct docg3_cascade *cascade) | 1620 | struct docg3_cascade *cascade) |
1621 | { | 1621 | { |
1622 | int ret = 0, floor, i = 0; | 1622 | int ret = 0, floor, i = 0; |
1623 | struct device *dev = &pdev->dev; | 1623 | struct device *dev = &pdev->dev; |
1624 | 1624 | ||
1625 | for (floor = 0; !ret && floor < DOC_MAX_NBFLOORS && | 1625 | for (floor = 0; !ret && floor < DOC_MAX_NBFLOORS && |
1626 | cascade->floors[floor]; floor++) | 1626 | cascade->floors[floor]; floor++) |
1627 | for (i = 0; !ret && i < 4; i++) | 1627 | for (i = 0; !ret && i < 4; i++) |
1628 | ret = device_create_file(dev, &doc_sys_attrs[floor][i]); | 1628 | ret = device_create_file(dev, &doc_sys_attrs[floor][i]); |
1629 | if (!ret) | 1629 | if (!ret) |
1630 | return 0; | 1630 | return 0; |
1631 | do { | 1631 | do { |
1632 | while (--i >= 0) | 1632 | while (--i >= 0) |
1633 | device_remove_file(dev, &doc_sys_attrs[floor][i]); | 1633 | device_remove_file(dev, &doc_sys_attrs[floor][i]); |
1634 | i = 4; | 1634 | i = 4; |
1635 | } while (--floor >= 0); | 1635 | } while (--floor >= 0); |
1636 | return ret; | 1636 | return ret; |
1637 | } | 1637 | } |
1638 | 1638 | ||
1639 | static void doc_unregister_sysfs(struct platform_device *pdev, | 1639 | static void doc_unregister_sysfs(struct platform_device *pdev, |
1640 | struct docg3_cascade *cascade) | 1640 | struct docg3_cascade *cascade) |
1641 | { | 1641 | { |
1642 | struct device *dev = &pdev->dev; | 1642 | struct device *dev = &pdev->dev; |
1643 | int floor, i; | 1643 | int floor, i; |
1644 | 1644 | ||
1645 | for (floor = 0; floor < DOC_MAX_NBFLOORS && cascade->floors[floor]; | 1645 | for (floor = 0; floor < DOC_MAX_NBFLOORS && cascade->floors[floor]; |
1646 | floor++) | 1646 | floor++) |
1647 | for (i = 0; i < 4; i++) | 1647 | for (i = 0; i < 4; i++) |
1648 | device_remove_file(dev, &doc_sys_attrs[floor][i]); | 1648 | device_remove_file(dev, &doc_sys_attrs[floor][i]); |
1649 | } | 1649 | } |
1650 | 1650 | ||
1651 | /* | 1651 | /* |
1652 | * Debug sysfs entries | 1652 | * Debug sysfs entries |
1653 | */ | 1653 | */ |
1654 | static int dbg_flashctrl_show(struct seq_file *s, void *p) | 1654 | static int dbg_flashctrl_show(struct seq_file *s, void *p) |
1655 | { | 1655 | { |
1656 | struct docg3 *docg3 = (struct docg3 *)s->private; | 1656 | struct docg3 *docg3 = (struct docg3 *)s->private; |
1657 | 1657 | ||
1658 | int pos = 0; | 1658 | int pos = 0; |
1659 | u8 fctrl; | 1659 | u8 fctrl; |
1660 | 1660 | ||
1661 | mutex_lock(&docg3->cascade->lock); | 1661 | mutex_lock(&docg3->cascade->lock); |
1662 | fctrl = doc_register_readb(docg3, DOC_FLASHCONTROL); | 1662 | fctrl = doc_register_readb(docg3, DOC_FLASHCONTROL); |
1663 | mutex_unlock(&docg3->cascade->lock); | 1663 | mutex_unlock(&docg3->cascade->lock); |
1664 | 1664 | ||
1665 | pos += seq_printf(s, | 1665 | pos += seq_printf(s, |
1666 | "FlashControl : 0x%02x (%s,CE# %s,%s,%s,flash %s)\n", | 1666 | "FlashControl : 0x%02x (%s,CE# %s,%s,%s,flash %s)\n", |
1667 | fctrl, | 1667 | fctrl, |
1668 | fctrl & DOC_CTRL_VIOLATION ? "protocol violation" : "-", | 1668 | fctrl & DOC_CTRL_VIOLATION ? "protocol violation" : "-", |
1669 | fctrl & DOC_CTRL_CE ? "active" : "inactive", | 1669 | fctrl & DOC_CTRL_CE ? "active" : "inactive", |
1670 | fctrl & DOC_CTRL_PROTECTION_ERROR ? "protection error" : "-", | 1670 | fctrl & DOC_CTRL_PROTECTION_ERROR ? "protection error" : "-", |
1671 | fctrl & DOC_CTRL_SEQUENCE_ERROR ? "sequence error" : "-", | 1671 | fctrl & DOC_CTRL_SEQUENCE_ERROR ? "sequence error" : "-", |
1672 | fctrl & DOC_CTRL_FLASHREADY ? "ready" : "not ready"); | 1672 | fctrl & DOC_CTRL_FLASHREADY ? "ready" : "not ready"); |
1673 | return pos; | 1673 | return pos; |
1674 | } | 1674 | } |
1675 | DEBUGFS_RO_ATTR(flashcontrol, dbg_flashctrl_show); | 1675 | DEBUGFS_RO_ATTR(flashcontrol, dbg_flashctrl_show); |
1676 | 1676 | ||
1677 | static int dbg_asicmode_show(struct seq_file *s, void *p) | 1677 | static int dbg_asicmode_show(struct seq_file *s, void *p) |
1678 | { | 1678 | { |
1679 | struct docg3 *docg3 = (struct docg3 *)s->private; | 1679 | struct docg3 *docg3 = (struct docg3 *)s->private; |
1680 | 1680 | ||
1681 | int pos = 0, pctrl, mode; | 1681 | int pos = 0, pctrl, mode; |
1682 | 1682 | ||
1683 | mutex_lock(&docg3->cascade->lock); | 1683 | mutex_lock(&docg3->cascade->lock); |
1684 | pctrl = doc_register_readb(docg3, DOC_ASICMODE); | 1684 | pctrl = doc_register_readb(docg3, DOC_ASICMODE); |
1685 | mode = pctrl & 0x03; | 1685 | mode = pctrl & 0x03; |
1686 | mutex_unlock(&docg3->cascade->lock); | 1686 | mutex_unlock(&docg3->cascade->lock); |
1687 | 1687 | ||
1688 | pos += seq_printf(s, | 1688 | pos += seq_printf(s, |
1689 | "%04x : RAM_WE=%d,RSTIN_RESET=%d,BDETCT_RESET=%d,WRITE_ENABLE=%d,POWERDOWN=%d,MODE=%d%d (", | 1689 | "%04x : RAM_WE=%d,RSTIN_RESET=%d,BDETCT_RESET=%d,WRITE_ENABLE=%d,POWERDOWN=%d,MODE=%d%d (", |
1690 | pctrl, | 1690 | pctrl, |
1691 | pctrl & DOC_ASICMODE_RAM_WE ? 1 : 0, | 1691 | pctrl & DOC_ASICMODE_RAM_WE ? 1 : 0, |
1692 | pctrl & DOC_ASICMODE_RSTIN_RESET ? 1 : 0, | 1692 | pctrl & DOC_ASICMODE_RSTIN_RESET ? 1 : 0, |
1693 | pctrl & DOC_ASICMODE_BDETCT_RESET ? 1 : 0, | 1693 | pctrl & DOC_ASICMODE_BDETCT_RESET ? 1 : 0, |
1694 | pctrl & DOC_ASICMODE_MDWREN ? 1 : 0, | 1694 | pctrl & DOC_ASICMODE_MDWREN ? 1 : 0, |
1695 | pctrl & DOC_ASICMODE_POWERDOWN ? 1 : 0, | 1695 | pctrl & DOC_ASICMODE_POWERDOWN ? 1 : 0, |
1696 | mode >> 1, mode & 0x1); | 1696 | mode >> 1, mode & 0x1); |
1697 | 1697 | ||
1698 | switch (mode) { | 1698 | switch (mode) { |
1699 | case DOC_ASICMODE_RESET: | 1699 | case DOC_ASICMODE_RESET: |
1700 | pos += seq_printf(s, "reset"); | 1700 | pos += seq_printf(s, "reset"); |
1701 | break; | 1701 | break; |
1702 | case DOC_ASICMODE_NORMAL: | 1702 | case DOC_ASICMODE_NORMAL: |
1703 | pos += seq_printf(s, "normal"); | 1703 | pos += seq_printf(s, "normal"); |
1704 | break; | 1704 | break; |
1705 | case DOC_ASICMODE_POWERDOWN: | 1705 | case DOC_ASICMODE_POWERDOWN: |
1706 | pos += seq_printf(s, "powerdown"); | 1706 | pos += seq_printf(s, "powerdown"); |
1707 | break; | 1707 | break; |
1708 | } | 1708 | } |
1709 | pos += seq_printf(s, ")\n"); | 1709 | pos += seq_printf(s, ")\n"); |
1710 | return pos; | 1710 | return pos; |
1711 | } | 1711 | } |
1712 | DEBUGFS_RO_ATTR(asic_mode, dbg_asicmode_show); | 1712 | DEBUGFS_RO_ATTR(asic_mode, dbg_asicmode_show); |
1713 | 1713 | ||
1714 | static int dbg_device_id_show(struct seq_file *s, void *p) | 1714 | static int dbg_device_id_show(struct seq_file *s, void *p) |
1715 | { | 1715 | { |
1716 | struct docg3 *docg3 = (struct docg3 *)s->private; | 1716 | struct docg3 *docg3 = (struct docg3 *)s->private; |
1717 | int pos = 0; | 1717 | int pos = 0; |
1718 | int id; | 1718 | int id; |
1719 | 1719 | ||
1720 | mutex_lock(&docg3->cascade->lock); | 1720 | mutex_lock(&docg3->cascade->lock); |
1721 | id = doc_register_readb(docg3, DOC_DEVICESELECT); | 1721 | id = doc_register_readb(docg3, DOC_DEVICESELECT); |
1722 | mutex_unlock(&docg3->cascade->lock); | 1722 | mutex_unlock(&docg3->cascade->lock); |
1723 | 1723 | ||
1724 | pos += seq_printf(s, "DeviceId = %d\n", id); | 1724 | pos += seq_printf(s, "DeviceId = %d\n", id); |
1725 | return pos; | 1725 | return pos; |
1726 | } | 1726 | } |
1727 | DEBUGFS_RO_ATTR(device_id, dbg_device_id_show); | 1727 | DEBUGFS_RO_ATTR(device_id, dbg_device_id_show); |
1728 | 1728 | ||
1729 | static int dbg_protection_show(struct seq_file *s, void *p) | 1729 | static int dbg_protection_show(struct seq_file *s, void *p) |
1730 | { | 1730 | { |
1731 | struct docg3 *docg3 = (struct docg3 *)s->private; | 1731 | struct docg3 *docg3 = (struct docg3 *)s->private; |
1732 | int pos = 0; | 1732 | int pos = 0; |
1733 | int protect, dps0, dps0_low, dps0_high, dps1, dps1_low, dps1_high; | 1733 | int protect, dps0, dps0_low, dps0_high, dps1, dps1_low, dps1_high; |
1734 | 1734 | ||
1735 | mutex_lock(&docg3->cascade->lock); | 1735 | mutex_lock(&docg3->cascade->lock); |
1736 | protect = doc_register_readb(docg3, DOC_PROTECTION); | 1736 | protect = doc_register_readb(docg3, DOC_PROTECTION); |
1737 | dps0 = doc_register_readb(docg3, DOC_DPS0_STATUS); | 1737 | dps0 = doc_register_readb(docg3, DOC_DPS0_STATUS); |
1738 | dps0_low = doc_register_readw(docg3, DOC_DPS0_ADDRLOW); | 1738 | dps0_low = doc_register_readw(docg3, DOC_DPS0_ADDRLOW); |
1739 | dps0_high = doc_register_readw(docg3, DOC_DPS0_ADDRHIGH); | 1739 | dps0_high = doc_register_readw(docg3, DOC_DPS0_ADDRHIGH); |
1740 | dps1 = doc_register_readb(docg3, DOC_DPS1_STATUS); | 1740 | dps1 = doc_register_readb(docg3, DOC_DPS1_STATUS); |
1741 | dps1_low = doc_register_readw(docg3, DOC_DPS1_ADDRLOW); | 1741 | dps1_low = doc_register_readw(docg3, DOC_DPS1_ADDRLOW); |
1742 | dps1_high = doc_register_readw(docg3, DOC_DPS1_ADDRHIGH); | 1742 | dps1_high = doc_register_readw(docg3, DOC_DPS1_ADDRHIGH); |
1743 | mutex_unlock(&docg3->cascade->lock); | 1743 | mutex_unlock(&docg3->cascade->lock); |
1744 | 1744 | ||
1745 | pos += seq_printf(s, "Protection = 0x%02x (", | 1745 | pos += seq_printf(s, "Protection = 0x%02x (", |
1746 | protect); | 1746 | protect); |
1747 | if (protect & DOC_PROTECT_FOUNDRY_OTP_LOCK) | 1747 | if (protect & DOC_PROTECT_FOUNDRY_OTP_LOCK) |
1748 | pos += seq_printf(s, "FOUNDRY_OTP_LOCK,"); | 1748 | pos += seq_printf(s, "FOUNDRY_OTP_LOCK,"); |
1749 | if (protect & DOC_PROTECT_CUSTOMER_OTP_LOCK) | 1749 | if (protect & DOC_PROTECT_CUSTOMER_OTP_LOCK) |
1750 | pos += seq_printf(s, "CUSTOMER_OTP_LOCK,"); | 1750 | pos += seq_printf(s, "CUSTOMER_OTP_LOCK,"); |
1751 | if (protect & DOC_PROTECT_LOCK_INPUT) | 1751 | if (protect & DOC_PROTECT_LOCK_INPUT) |
1752 | pos += seq_printf(s, "LOCK_INPUT,"); | 1752 | pos += seq_printf(s, "LOCK_INPUT,"); |
1753 | if (protect & DOC_PROTECT_STICKY_LOCK) | 1753 | if (protect & DOC_PROTECT_STICKY_LOCK) |
1754 | pos += seq_printf(s, "STICKY_LOCK,"); | 1754 | pos += seq_printf(s, "STICKY_LOCK,"); |
1755 | if (protect & DOC_PROTECT_PROTECTION_ENABLED) | 1755 | if (protect & DOC_PROTECT_PROTECTION_ENABLED) |
1756 | pos += seq_printf(s, "PROTECTION ON,"); | 1756 | pos += seq_printf(s, "PROTECTION ON,"); |
1757 | if (protect & DOC_PROTECT_IPL_DOWNLOAD_LOCK) | 1757 | if (protect & DOC_PROTECT_IPL_DOWNLOAD_LOCK) |
1758 | pos += seq_printf(s, "IPL_DOWNLOAD_LOCK,"); | 1758 | pos += seq_printf(s, "IPL_DOWNLOAD_LOCK,"); |
1759 | if (protect & DOC_PROTECT_PROTECTION_ERROR) | 1759 | if (protect & DOC_PROTECT_PROTECTION_ERROR) |
1760 | pos += seq_printf(s, "PROTECT_ERR,"); | 1760 | pos += seq_printf(s, "PROTECT_ERR,"); |
1761 | else | 1761 | else |
1762 | pos += seq_printf(s, "NO_PROTECT_ERR"); | 1762 | pos += seq_printf(s, "NO_PROTECT_ERR"); |
1763 | pos += seq_printf(s, ")\n"); | 1763 | pos += seq_printf(s, ")\n"); |
1764 | 1764 | ||
1765 | pos += seq_printf(s, "DPS0 = 0x%02x : " | 1765 | pos += seq_printf(s, "DPS0 = 0x%02x : " |
1766 | "Protected area [0x%x - 0x%x] : OTP=%d, READ=%d, " | 1766 | "Protected area [0x%x - 0x%x] : OTP=%d, READ=%d, " |
1767 | "WRITE=%d, HW_LOCK=%d, KEY_OK=%d\n", | 1767 | "WRITE=%d, HW_LOCK=%d, KEY_OK=%d\n", |
1768 | dps0, dps0_low, dps0_high, | 1768 | dps0, dps0_low, dps0_high, |
1769 | !!(dps0 & DOC_DPS_OTP_PROTECTED), | 1769 | !!(dps0 & DOC_DPS_OTP_PROTECTED), |
1770 | !!(dps0 & DOC_DPS_READ_PROTECTED), | 1770 | !!(dps0 & DOC_DPS_READ_PROTECTED), |
1771 | !!(dps0 & DOC_DPS_WRITE_PROTECTED), | 1771 | !!(dps0 & DOC_DPS_WRITE_PROTECTED), |
1772 | !!(dps0 & DOC_DPS_HW_LOCK_ENABLED), | 1772 | !!(dps0 & DOC_DPS_HW_LOCK_ENABLED), |
1773 | !!(dps0 & DOC_DPS_KEY_OK)); | 1773 | !!(dps0 & DOC_DPS_KEY_OK)); |
1774 | pos += seq_printf(s, "DPS1 = 0x%02x : " | 1774 | pos += seq_printf(s, "DPS1 = 0x%02x : " |
1775 | "Protected area [0x%x - 0x%x] : OTP=%d, READ=%d, " | 1775 | "Protected area [0x%x - 0x%x] : OTP=%d, READ=%d, " |
1776 | "WRITE=%d, HW_LOCK=%d, KEY_OK=%d\n", | 1776 | "WRITE=%d, HW_LOCK=%d, KEY_OK=%d\n", |
1777 | dps1, dps1_low, dps1_high, | 1777 | dps1, dps1_low, dps1_high, |
1778 | !!(dps1 & DOC_DPS_OTP_PROTECTED), | 1778 | !!(dps1 & DOC_DPS_OTP_PROTECTED), |
1779 | !!(dps1 & DOC_DPS_READ_PROTECTED), | 1779 | !!(dps1 & DOC_DPS_READ_PROTECTED), |
1780 | !!(dps1 & DOC_DPS_WRITE_PROTECTED), | 1780 | !!(dps1 & DOC_DPS_WRITE_PROTECTED), |
1781 | !!(dps1 & DOC_DPS_HW_LOCK_ENABLED), | 1781 | !!(dps1 & DOC_DPS_HW_LOCK_ENABLED), |
1782 | !!(dps1 & DOC_DPS_KEY_OK)); | 1782 | !!(dps1 & DOC_DPS_KEY_OK)); |
1783 | return pos; | 1783 | return pos; |
1784 | } | 1784 | } |
1785 | DEBUGFS_RO_ATTR(protection, dbg_protection_show); | 1785 | DEBUGFS_RO_ATTR(protection, dbg_protection_show); |
1786 | 1786 | ||
1787 | static int __init doc_dbg_register(struct docg3 *docg3) | 1787 | static int __init doc_dbg_register(struct docg3 *docg3) |
1788 | { | 1788 | { |
1789 | struct dentry *root, *entry; | 1789 | struct dentry *root, *entry; |
1790 | 1790 | ||
1791 | root = debugfs_create_dir("docg3", NULL); | 1791 | root = debugfs_create_dir("docg3", NULL); |
1792 | if (!root) | 1792 | if (!root) |
1793 | return -ENOMEM; | 1793 | return -ENOMEM; |
1794 | 1794 | ||
1795 | entry = debugfs_create_file("flashcontrol", S_IRUSR, root, docg3, | 1795 | entry = debugfs_create_file("flashcontrol", S_IRUSR, root, docg3, |
1796 | &flashcontrol_fops); | 1796 | &flashcontrol_fops); |
1797 | if (entry) | 1797 | if (entry) |
1798 | entry = debugfs_create_file("asic_mode", S_IRUSR, root, | 1798 | entry = debugfs_create_file("asic_mode", S_IRUSR, root, |
1799 | docg3, &asic_mode_fops); | 1799 | docg3, &asic_mode_fops); |
1800 | if (entry) | 1800 | if (entry) |
1801 | entry = debugfs_create_file("device_id", S_IRUSR, root, | 1801 | entry = debugfs_create_file("device_id", S_IRUSR, root, |
1802 | docg3, &device_id_fops); | 1802 | docg3, &device_id_fops); |
1803 | if (entry) | 1803 | if (entry) |
1804 | entry = debugfs_create_file("protection", S_IRUSR, root, | 1804 | entry = debugfs_create_file("protection", S_IRUSR, root, |
1805 | docg3, &protection_fops); | 1805 | docg3, &protection_fops); |
1806 | if (entry) { | 1806 | if (entry) { |
1807 | docg3->debugfs_root = root; | 1807 | docg3->debugfs_root = root; |
1808 | return 0; | 1808 | return 0; |
1809 | } else { | 1809 | } else { |
1810 | debugfs_remove_recursive(root); | 1810 | debugfs_remove_recursive(root); |
1811 | return -ENOMEM; | 1811 | return -ENOMEM; |
1812 | } | 1812 | } |
1813 | } | 1813 | } |
1814 | 1814 | ||
1815 | static void __exit doc_dbg_unregister(struct docg3 *docg3) | 1815 | static void __exit doc_dbg_unregister(struct docg3 *docg3) |
1816 | { | 1816 | { |
1817 | debugfs_remove_recursive(docg3->debugfs_root); | 1817 | debugfs_remove_recursive(docg3->debugfs_root); |
1818 | } | 1818 | } |
1819 | 1819 | ||
1820 | /** | 1820 | /** |
1821 | * doc_set_driver_info - Fill the mtd_info structure and docg3 structure | 1821 | * doc_set_driver_info - Fill the mtd_info structure and docg3 structure |
1822 | * @chip_id: The chip ID of the supported chip | 1822 | * @chip_id: The chip ID of the supported chip |
1823 | * @mtd: The structure to fill | 1823 | * @mtd: The structure to fill |
1824 | */ | 1824 | */ |
1825 | static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd) | 1825 | static void __init doc_set_driver_info(int chip_id, struct mtd_info *mtd) |
1826 | { | 1826 | { |
1827 | struct docg3 *docg3 = mtd->priv; | 1827 | struct docg3 *docg3 = mtd->priv; |
1828 | int cfg; | 1828 | int cfg; |
1829 | 1829 | ||
1830 | cfg = doc_register_readb(docg3, DOC_CONFIGURATION); | 1830 | cfg = doc_register_readb(docg3, DOC_CONFIGURATION); |
1831 | docg3->if_cfg = (cfg & DOC_CONF_IF_CFG ? 1 : 0); | 1831 | docg3->if_cfg = (cfg & DOC_CONF_IF_CFG ? 1 : 0); |
1832 | docg3->reliable = reliable_mode; | 1832 | docg3->reliable = reliable_mode; |
1833 | 1833 | ||
1834 | switch (chip_id) { | 1834 | switch (chip_id) { |
1835 | case DOC_CHIPID_G3: | 1835 | case DOC_CHIPID_G3: |
1836 | mtd->name = kasprintf(GFP_KERNEL, "docg3.%d", | 1836 | mtd->name = kasprintf(GFP_KERNEL, "docg3.%d", |
1837 | docg3->device_id); | 1837 | docg3->device_id); |
1838 | docg3->max_block = 2047; | 1838 | docg3->max_block = 2047; |
1839 | break; | 1839 | break; |
1840 | } | 1840 | } |
1841 | mtd->type = MTD_NANDFLASH; | 1841 | mtd->type = MTD_NANDFLASH; |
1842 | mtd->flags = MTD_CAP_NANDFLASH; | 1842 | mtd->flags = MTD_CAP_NANDFLASH; |
1843 | mtd->size = (docg3->max_block + 1) * DOC_LAYOUT_BLOCK_SIZE; | 1843 | mtd->size = (docg3->max_block + 1) * DOC_LAYOUT_BLOCK_SIZE; |
1844 | if (docg3->reliable == 2) | 1844 | if (docg3->reliable == 2) |
1845 | mtd->size /= 2; | 1845 | mtd->size /= 2; |
1846 | mtd->erasesize = DOC_LAYOUT_BLOCK_SIZE * DOC_LAYOUT_NBPLANES; | 1846 | mtd->erasesize = DOC_LAYOUT_BLOCK_SIZE * DOC_LAYOUT_NBPLANES; |
1847 | if (docg3->reliable == 2) | 1847 | if (docg3->reliable == 2) |
1848 | mtd->erasesize /= 2; | 1848 | mtd->erasesize /= 2; |
1849 | mtd->writebufsize = mtd->writesize = DOC_LAYOUT_PAGE_SIZE; | 1849 | mtd->writebufsize = mtd->writesize = DOC_LAYOUT_PAGE_SIZE; |
1850 | mtd->oobsize = DOC_LAYOUT_OOB_SIZE; | 1850 | mtd->oobsize = DOC_LAYOUT_OOB_SIZE; |
1851 | mtd->owner = THIS_MODULE; | 1851 | mtd->owner = THIS_MODULE; |
1852 | mtd->_erase = doc_erase; | 1852 | mtd->_erase = doc_erase; |
1853 | mtd->_read = doc_read; | 1853 | mtd->_read = doc_read; |
1854 | mtd->_write = doc_write; | 1854 | mtd->_write = doc_write; |
1855 | mtd->_read_oob = doc_read_oob; | 1855 | mtd->_read_oob = doc_read_oob; |
1856 | mtd->_write_oob = doc_write_oob; | 1856 | mtd->_write_oob = doc_write_oob; |
1857 | mtd->_block_isbad = doc_block_isbad; | 1857 | mtd->_block_isbad = doc_block_isbad; |
1858 | mtd->ecclayout = &docg3_oobinfo; | 1858 | mtd->ecclayout = &docg3_oobinfo; |
1859 | mtd->ecc_strength = DOC_ECC_BCH_T; | 1859 | mtd->ecc_strength = DOC_ECC_BCH_T; |
1860 | } | 1860 | } |
1861 | 1861 | ||
1862 | /** | 1862 | /** |
1863 | * doc_probe_device - Check if a device is available | 1863 | * doc_probe_device - Check if a device is available |
1864 | * @base: the io space where the device is probed | 1864 | * @base: the io space where the device is probed |
1865 | * @floor: the floor of the probed device | 1865 | * @floor: the floor of the probed device |
1866 | * @dev: the device | 1866 | * @dev: the device |
1867 | * @cascade: the cascade of chips this devices will belong to | 1867 | * @cascade: the cascade of chips this devices will belong to |
1868 | * | 1868 | * |
1869 | * Checks whether a device at the specified IO range, and floor is available. | 1869 | * Checks whether a device at the specified IO range, and floor is available. |
1870 | * | 1870 | * |
1871 | * Returns a mtd_info struct if there is a device, ENODEV if none found, ENOMEM | 1871 | * Returns a mtd_info struct if there is a device, ENODEV if none found, ENOMEM |
1872 | * if a memory allocation failed. If floor 0 is checked, a reset of the ASIC is | 1872 | * if a memory allocation failed. If floor 0 is checked, a reset of the ASIC is |
1873 | * launched. | 1873 | * launched. |
1874 | */ | 1874 | */ |
1875 | static struct mtd_info * __init | 1875 | static struct mtd_info * __init |
1876 | doc_probe_device(struct docg3_cascade *cascade, int floor, struct device *dev) | 1876 | doc_probe_device(struct docg3_cascade *cascade, int floor, struct device *dev) |
1877 | { | 1877 | { |
1878 | int ret, bbt_nbpages; | 1878 | int ret, bbt_nbpages; |
1879 | u16 chip_id, chip_id_inv; | 1879 | u16 chip_id, chip_id_inv; |
1880 | struct docg3 *docg3; | 1880 | struct docg3 *docg3; |
1881 | struct mtd_info *mtd; | 1881 | struct mtd_info *mtd; |
1882 | 1882 | ||
1883 | ret = -ENOMEM; | 1883 | ret = -ENOMEM; |
1884 | docg3 = kzalloc(sizeof(struct docg3), GFP_KERNEL); | 1884 | docg3 = kzalloc(sizeof(struct docg3), GFP_KERNEL); |
1885 | if (!docg3) | 1885 | if (!docg3) |
1886 | goto nomem1; | 1886 | goto nomem1; |
1887 | mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL); | 1887 | mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL); |
1888 | if (!mtd) | 1888 | if (!mtd) |
1889 | goto nomem2; | 1889 | goto nomem2; |
1890 | mtd->priv = docg3; | 1890 | mtd->priv = docg3; |
1891 | bbt_nbpages = DIV_ROUND_UP(docg3->max_block + 1, | 1891 | bbt_nbpages = DIV_ROUND_UP(docg3->max_block + 1, |
1892 | 8 * DOC_LAYOUT_PAGE_SIZE); | 1892 | 8 * DOC_LAYOUT_PAGE_SIZE); |
1893 | docg3->bbt = kzalloc(bbt_nbpages * DOC_LAYOUT_PAGE_SIZE, GFP_KERNEL); | 1893 | docg3->bbt = kzalloc(bbt_nbpages * DOC_LAYOUT_PAGE_SIZE, GFP_KERNEL); |
1894 | if (!docg3->bbt) | 1894 | if (!docg3->bbt) |
1895 | goto nomem3; | 1895 | goto nomem3; |
1896 | 1896 | ||
1897 | docg3->dev = dev; | 1897 | docg3->dev = dev; |
1898 | docg3->device_id = floor; | 1898 | docg3->device_id = floor; |
1899 | docg3->cascade = cascade; | 1899 | docg3->cascade = cascade; |
1900 | doc_set_device_id(docg3, docg3->device_id); | 1900 | doc_set_device_id(docg3, docg3->device_id); |
1901 | if (!floor) | 1901 | if (!floor) |
1902 | doc_set_asic_mode(docg3, DOC_ASICMODE_RESET); | 1902 | doc_set_asic_mode(docg3, DOC_ASICMODE_RESET); |
1903 | doc_set_asic_mode(docg3, DOC_ASICMODE_NORMAL); | 1903 | doc_set_asic_mode(docg3, DOC_ASICMODE_NORMAL); |
1904 | 1904 | ||
1905 | chip_id = doc_register_readw(docg3, DOC_CHIPID); | 1905 | chip_id = doc_register_readw(docg3, DOC_CHIPID); |
1906 | chip_id_inv = doc_register_readw(docg3, DOC_CHIPID_INV); | 1906 | chip_id_inv = doc_register_readw(docg3, DOC_CHIPID_INV); |
1907 | 1907 | ||
1908 | ret = 0; | 1908 | ret = 0; |
1909 | if (chip_id != (u16)(~chip_id_inv)) { | 1909 | if (chip_id != (u16)(~chip_id_inv)) { |
1910 | goto nomem3; | 1910 | goto nomem3; |
1911 | } | 1911 | } |
1912 | 1912 | ||
1913 | switch (chip_id) { | 1913 | switch (chip_id) { |
1914 | case DOC_CHIPID_G3: | 1914 | case DOC_CHIPID_G3: |
1915 | doc_info("Found a G3 DiskOnChip at addr %p, floor %d\n", | 1915 | doc_info("Found a G3 DiskOnChip at addr %p, floor %d\n", |
1916 | docg3->cascade->base, floor); | 1916 | docg3->cascade->base, floor); |
1917 | break; | 1917 | break; |
1918 | default: | 1918 | default: |
1919 | doc_err("Chip id %04x is not a DiskOnChip G3 chip\n", chip_id); | 1919 | doc_err("Chip id %04x is not a DiskOnChip G3 chip\n", chip_id); |
1920 | goto nomem3; | 1920 | goto nomem3; |
1921 | } | 1921 | } |
1922 | 1922 | ||
1923 | doc_set_driver_info(chip_id, mtd); | 1923 | doc_set_driver_info(chip_id, mtd); |
1924 | 1924 | ||
1925 | doc_hamming_ecc_init(docg3, DOC_LAYOUT_OOB_PAGEINFO_SZ); | 1925 | doc_hamming_ecc_init(docg3, DOC_LAYOUT_OOB_PAGEINFO_SZ); |
1926 | doc_reload_bbt(docg3); | 1926 | doc_reload_bbt(docg3); |
1927 | return mtd; | 1927 | return mtd; |
1928 | 1928 | ||
1929 | nomem3: | 1929 | nomem3: |
1930 | kfree(mtd); | 1930 | kfree(mtd); |
1931 | nomem2: | 1931 | nomem2: |
1932 | kfree(docg3); | 1932 | kfree(docg3); |
1933 | nomem1: | 1933 | nomem1: |
1934 | return ERR_PTR(ret); | 1934 | return ERR_PTR(ret); |
1935 | } | 1935 | } |
1936 | 1936 | ||
1937 | /** | 1937 | /** |
1938 | * doc_release_device - Release a docg3 floor | 1938 | * doc_release_device - Release a docg3 floor |
1939 | * @mtd: the device | 1939 | * @mtd: the device |
1940 | */ | 1940 | */ |
1941 | static void doc_release_device(struct mtd_info *mtd) | 1941 | static void doc_release_device(struct mtd_info *mtd) |
1942 | { | 1942 | { |
1943 | struct docg3 *docg3 = mtd->priv; | 1943 | struct docg3 *docg3 = mtd->priv; |
1944 | 1944 | ||
1945 | mtd_device_unregister(mtd); | 1945 | mtd_device_unregister(mtd); |
1946 | kfree(docg3->bbt); | 1946 | kfree(docg3->bbt); |
1947 | kfree(docg3); | 1947 | kfree(docg3); |
1948 | kfree(mtd->name); | 1948 | kfree(mtd->name); |
1949 | kfree(mtd); | 1949 | kfree(mtd); |
1950 | } | 1950 | } |
1951 | 1951 | ||
1952 | /** | 1952 | /** |
1953 | * docg3_resume - Awakens docg3 floor | 1953 | * docg3_resume - Awakens docg3 floor |
1954 | * @pdev: platfrom device | 1954 | * @pdev: platfrom device |
1955 | * | 1955 | * |
1956 | * Returns 0 (always successful) | 1956 | * Returns 0 (always successful) |
1957 | */ | 1957 | */ |
1958 | static int docg3_resume(struct platform_device *pdev) | 1958 | static int docg3_resume(struct platform_device *pdev) |
1959 | { | 1959 | { |
1960 | int i; | 1960 | int i; |
1961 | struct docg3_cascade *cascade; | 1961 | struct docg3_cascade *cascade; |
1962 | struct mtd_info **docg3_floors, *mtd; | 1962 | struct mtd_info **docg3_floors, *mtd; |
1963 | struct docg3 *docg3; | 1963 | struct docg3 *docg3; |
1964 | 1964 | ||
1965 | cascade = platform_get_drvdata(pdev); | 1965 | cascade = platform_get_drvdata(pdev); |
1966 | docg3_floors = cascade->floors; | 1966 | docg3_floors = cascade->floors; |
1967 | mtd = docg3_floors[0]; | 1967 | mtd = docg3_floors[0]; |
1968 | docg3 = mtd->priv; | 1968 | docg3 = mtd->priv; |
1969 | 1969 | ||
1970 | doc_dbg("docg3_resume()\n"); | 1970 | doc_dbg("docg3_resume()\n"); |
1971 | for (i = 0; i < 12; i++) | 1971 | for (i = 0; i < 12; i++) |
1972 | doc_readb(docg3, DOC_IOSPACE_IPL); | 1972 | doc_readb(docg3, DOC_IOSPACE_IPL); |
1973 | return 0; | 1973 | return 0; |
1974 | } | 1974 | } |
1975 | 1975 | ||
1976 | /** | 1976 | /** |
1977 | * docg3_suspend - Put in low power mode the docg3 floor | 1977 | * docg3_suspend - Put in low power mode the docg3 floor |
1978 | * @pdev: platform device | 1978 | * @pdev: platform device |
1979 | * @state: power state | 1979 | * @state: power state |
1980 | * | 1980 | * |
1981 | * Shuts off most of docg3 circuitery to lower power consumption. | 1981 | * Shuts off most of docg3 circuitery to lower power consumption. |
1982 | * | 1982 | * |
1983 | * Returns 0 if suspend succeeded, -EIO if chip refused suspend | 1983 | * Returns 0 if suspend succeeded, -EIO if chip refused suspend |
1984 | */ | 1984 | */ |
1985 | static int docg3_suspend(struct platform_device *pdev, pm_message_t state) | 1985 | static int docg3_suspend(struct platform_device *pdev, pm_message_t state) |
1986 | { | 1986 | { |
1987 | int floor, i; | 1987 | int floor, i; |
1988 | struct docg3_cascade *cascade; | 1988 | struct docg3_cascade *cascade; |
1989 | struct mtd_info **docg3_floors, *mtd; | 1989 | struct mtd_info **docg3_floors, *mtd; |
1990 | struct docg3 *docg3; | 1990 | struct docg3 *docg3; |
1991 | u8 ctrl, pwr_down; | 1991 | u8 ctrl, pwr_down; |
1992 | 1992 | ||
1993 | cascade = platform_get_drvdata(pdev); | 1993 | cascade = platform_get_drvdata(pdev); |
1994 | docg3_floors = cascade->floors; | 1994 | docg3_floors = cascade->floors; |
1995 | for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) { | 1995 | for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) { |
1996 | mtd = docg3_floors[floor]; | 1996 | mtd = docg3_floors[floor]; |
1997 | if (!mtd) | 1997 | if (!mtd) |
1998 | continue; | 1998 | continue; |
1999 | docg3 = mtd->priv; | 1999 | docg3 = mtd->priv; |
2000 | 2000 | ||
2001 | doc_writeb(docg3, floor, DOC_DEVICESELECT); | 2001 | doc_writeb(docg3, floor, DOC_DEVICESELECT); |
2002 | ctrl = doc_register_readb(docg3, DOC_FLASHCONTROL); | 2002 | ctrl = doc_register_readb(docg3, DOC_FLASHCONTROL); |
2003 | ctrl &= ~DOC_CTRL_VIOLATION & ~DOC_CTRL_CE; | 2003 | ctrl &= ~DOC_CTRL_VIOLATION & ~DOC_CTRL_CE; |
2004 | doc_writeb(docg3, ctrl, DOC_FLASHCONTROL); | 2004 | doc_writeb(docg3, ctrl, DOC_FLASHCONTROL); |
2005 | 2005 | ||
2006 | for (i = 0; i < 10; i++) { | 2006 | for (i = 0; i < 10; i++) { |
2007 | usleep_range(3000, 4000); | 2007 | usleep_range(3000, 4000); |
2008 | pwr_down = doc_register_readb(docg3, DOC_POWERMODE); | 2008 | pwr_down = doc_register_readb(docg3, DOC_POWERMODE); |
2009 | if (pwr_down & DOC_POWERDOWN_READY) | 2009 | if (pwr_down & DOC_POWERDOWN_READY) |
2010 | break; | 2010 | break; |
2011 | } | 2011 | } |
2012 | if (pwr_down & DOC_POWERDOWN_READY) { | 2012 | if (pwr_down & DOC_POWERDOWN_READY) { |
2013 | doc_dbg("docg3_suspend(): floor %d powerdown ok\n", | 2013 | doc_dbg("docg3_suspend(): floor %d powerdown ok\n", |
2014 | floor); | 2014 | floor); |
2015 | } else { | 2015 | } else { |
2016 | doc_err("docg3_suspend(): floor %d powerdown failed\n", | 2016 | doc_err("docg3_suspend(): floor %d powerdown failed\n", |
2017 | floor); | 2017 | floor); |
2018 | return -EIO; | 2018 | return -EIO; |
2019 | } | 2019 | } |
2020 | } | 2020 | } |
2021 | 2021 | ||
2022 | mtd = docg3_floors[0]; | 2022 | mtd = docg3_floors[0]; |
2023 | docg3 = mtd->priv; | 2023 | docg3 = mtd->priv; |
2024 | doc_set_asic_mode(docg3, DOC_ASICMODE_POWERDOWN); | 2024 | doc_set_asic_mode(docg3, DOC_ASICMODE_POWERDOWN); |
2025 | return 0; | 2025 | return 0; |
2026 | } | 2026 | } |
2027 | 2027 | ||
2028 | /** | 2028 | /** |
2029 | * doc_probe - Probe the IO space for a DiskOnChip G3 chip | 2029 | * doc_probe - Probe the IO space for a DiskOnChip G3 chip |
2030 | * @pdev: platform device | 2030 | * @pdev: platform device |
2031 | * | 2031 | * |
2032 | * Probes for a G3 chip at the specified IO space in the platform data | 2032 | * Probes for a G3 chip at the specified IO space in the platform data |
2033 | * ressources. The floor 0 must be available. | 2033 | * ressources. The floor 0 must be available. |
2034 | * | 2034 | * |
2035 | * Returns 0 on success, -ENOMEM, -ENXIO on error | 2035 | * Returns 0 on success, -ENOMEM, -ENXIO on error |
2036 | */ | 2036 | */ |
2037 | static int __init docg3_probe(struct platform_device *pdev) | 2037 | static int __init docg3_probe(struct platform_device *pdev) |
2038 | { | 2038 | { |
2039 | struct device *dev = &pdev->dev; | 2039 | struct device *dev = &pdev->dev; |
2040 | struct mtd_info *mtd; | 2040 | struct mtd_info *mtd; |
2041 | struct resource *ress; | 2041 | struct resource *ress; |
2042 | void __iomem *base; | 2042 | void __iomem *base; |
2043 | int ret, floor, found = 0; | 2043 | int ret, floor, found = 0; |
2044 | struct docg3_cascade *cascade; | 2044 | struct docg3_cascade *cascade; |
2045 | 2045 | ||
2046 | ret = -ENXIO; | 2046 | ret = -ENXIO; |
2047 | ress = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2047 | ress = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2048 | if (!ress) { | 2048 | if (!ress) { |
2049 | dev_err(dev, "No I/O memory resource defined\n"); | 2049 | dev_err(dev, "No I/O memory resource defined\n"); |
2050 | goto noress; | 2050 | goto noress; |
2051 | } | 2051 | } |
2052 | base = ioremap(ress->start, DOC_IOSPACE_SIZE); | 2052 | base = ioremap(ress->start, DOC_IOSPACE_SIZE); |
2053 | 2053 | ||
2054 | ret = -ENOMEM; | 2054 | ret = -ENOMEM; |
2055 | cascade = kzalloc(sizeof(*cascade) * DOC_MAX_NBFLOORS, | 2055 | cascade = kzalloc(sizeof(*cascade) * DOC_MAX_NBFLOORS, |
2056 | GFP_KERNEL); | 2056 | GFP_KERNEL); |
2057 | if (!cascade) | 2057 | if (!cascade) |
2058 | goto nomem1; | 2058 | goto nomem1; |
2059 | cascade->base = base; | 2059 | cascade->base = base; |
2060 | mutex_init(&cascade->lock); | 2060 | mutex_init(&cascade->lock); |
2061 | cascade->bch = init_bch(DOC_ECC_BCH_M, DOC_ECC_BCH_T, | 2061 | cascade->bch = init_bch(DOC_ECC_BCH_M, DOC_ECC_BCH_T, |
2062 | DOC_ECC_BCH_PRIMPOLY); | 2062 | DOC_ECC_BCH_PRIMPOLY); |
2063 | if (!cascade->bch) | 2063 | if (!cascade->bch) |
2064 | goto nomem2; | 2064 | goto nomem2; |
2065 | 2065 | ||
2066 | for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) { | 2066 | for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) { |
2067 | mtd = doc_probe_device(cascade, floor, dev); | 2067 | mtd = doc_probe_device(cascade, floor, dev); |
2068 | if (IS_ERR(mtd)) { | 2068 | if (IS_ERR(mtd)) { |
2069 | ret = PTR_ERR(mtd); | 2069 | ret = PTR_ERR(mtd); |
2070 | goto err_probe; | 2070 | goto err_probe; |
2071 | } | 2071 | } |
2072 | if (!mtd) { | 2072 | if (!mtd) { |
2073 | if (floor == 0) | 2073 | if (floor == 0) |
2074 | goto notfound; | 2074 | goto notfound; |
2075 | else | 2075 | else |
2076 | continue; | 2076 | continue; |
2077 | } | 2077 | } |
2078 | cascade->floors[floor] = mtd; | 2078 | cascade->floors[floor] = mtd; |
2079 | ret = mtd_device_parse_register(mtd, part_probes, NULL, NULL, | 2079 | ret = mtd_device_parse_register(mtd, part_probes, NULL, NULL, |
2080 | 0); | 2080 | 0); |
2081 | if (ret) | 2081 | if (ret) |
2082 | goto err_probe; | 2082 | goto err_probe; |
2083 | found++; | 2083 | found++; |
2084 | } | 2084 | } |
2085 | 2085 | ||
2086 | ret = doc_register_sysfs(pdev, cascade); | 2086 | ret = doc_register_sysfs(pdev, cascade); |
2087 | if (ret) | 2087 | if (ret) |
2088 | goto err_probe; | 2088 | goto err_probe; |
2089 | if (!found) | 2089 | if (!found) |
2090 | goto notfound; | 2090 | goto notfound; |
2091 | 2091 | ||
2092 | platform_set_drvdata(pdev, cascade); | 2092 | platform_set_drvdata(pdev, cascade); |
2093 | doc_dbg_register(cascade->floors[0]->priv); | 2093 | doc_dbg_register(cascade->floors[0]->priv); |
2094 | return 0; | 2094 | return 0; |
2095 | 2095 | ||
2096 | notfound: | 2096 | notfound: |
2097 | ret = -ENODEV; | 2097 | ret = -ENODEV; |
2098 | dev_info(dev, "No supported DiskOnChip found\n"); | 2098 | dev_info(dev, "No supported DiskOnChip found\n"); |
2099 | err_probe: | 2099 | err_probe: |
2100 | kfree(cascade->bch); | 2100 | kfree(cascade->bch); |
2101 | for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) | 2101 | for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) |
2102 | if (cascade->floors[floor]) | 2102 | if (cascade->floors[floor]) |
2103 | doc_release_device(cascade->floors[floor]); | 2103 | doc_release_device(cascade->floors[floor]); |
2104 | nomem2: | 2104 | nomem2: |
2105 | kfree(cascade); | 2105 | kfree(cascade); |
2106 | nomem1: | 2106 | nomem1: |
2107 | iounmap(base); | 2107 | iounmap(base); |
2108 | noress: | 2108 | noress: |
2109 | return ret; | 2109 | return ret; |
2110 | } | 2110 | } |
2111 | 2111 | ||
2112 | /** | 2112 | /** |
2113 | * docg3_release - Release the driver | 2113 | * docg3_release - Release the driver |
2114 | * @pdev: the platform device | 2114 | * @pdev: the platform device |
2115 | * | 2115 | * |
2116 | * Returns 0 | 2116 | * Returns 0 |
2117 | */ | 2117 | */ |
2118 | static int __exit docg3_release(struct platform_device *pdev) | 2118 | static int __exit docg3_release(struct platform_device *pdev) |
2119 | { | 2119 | { |
2120 | struct docg3_cascade *cascade = platform_get_drvdata(pdev); | 2120 | struct docg3_cascade *cascade = platform_get_drvdata(pdev); |
2121 | struct docg3 *docg3 = cascade->floors[0]->priv; | 2121 | struct docg3 *docg3 = cascade->floors[0]->priv; |
2122 | void __iomem *base = cascade->base; | 2122 | void __iomem *base = cascade->base; |
2123 | int floor; | 2123 | int floor; |
2124 | 2124 | ||
2125 | doc_unregister_sysfs(pdev, cascade); | 2125 | doc_unregister_sysfs(pdev, cascade); |
2126 | doc_dbg_unregister(docg3); | 2126 | doc_dbg_unregister(docg3); |
2127 | for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) | 2127 | for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) |
2128 | if (cascade->floors[floor]) | 2128 | if (cascade->floors[floor]) |
2129 | doc_release_device(cascade->floors[floor]); | 2129 | doc_release_device(cascade->floors[floor]); |
2130 | 2130 | ||
2131 | free_bch(docg3->cascade->bch); | 2131 | free_bch(docg3->cascade->bch); |
2132 | kfree(cascade); | 2132 | kfree(cascade); |
2133 | iounmap(base); | 2133 | iounmap(base); |
2134 | return 0; | 2134 | return 0; |
2135 | } | 2135 | } |
2136 | 2136 | ||
2137 | static struct platform_driver g3_driver = { | 2137 | static struct platform_driver g3_driver = { |
2138 | .driver = { | 2138 | .driver = { |
2139 | .name = "docg3", | 2139 | .name = "docg3", |
2140 | .owner = THIS_MODULE, | 2140 | .owner = THIS_MODULE, |
2141 | }, | 2141 | }, |
2142 | .suspend = docg3_suspend, | 2142 | .suspend = docg3_suspend, |
2143 | .resume = docg3_resume, | 2143 | .resume = docg3_resume, |
2144 | .remove = __exit_p(docg3_release), | 2144 | .remove = __exit_p(docg3_release), |
2145 | }; | 2145 | }; |
2146 | 2146 | ||
2147 | static int __init docg3_init(void) | 2147 | module_platform_driver_probe(g3_driver, docg3_probe); |
2148 | { | ||
2149 | return platform_driver_probe(&g3_driver, docg3_probe); | ||
2150 | } | ||
2151 | module_init(docg3_init); | ||
2152 | |||
2153 | |||
2154 | static void __exit docg3_exit(void) | ||
2155 | { | ||
2156 | platform_driver_unregister(&g3_driver); | ||
2157 | } | ||
2158 | module_exit(docg3_exit); | ||
2159 | 2148 | ||
2160 | MODULE_LICENSE("GPL"); | 2149 | MODULE_LICENSE("GPL"); |
2161 | MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>"); | 2150 | MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>"); |
2162 | MODULE_DESCRIPTION("MTD driver for DiskOnChip G3"); | 2151 | MODULE_DESCRIPTION("MTD driver for DiskOnChip G3"); |
2163 | 2152 |
drivers/mtd/nand/docg4.c
1 | /* | 1 | /* |
2 | * Copyright ยฉ 2012 Mike Dunn <mikedunn@newsguy.com> | 2 | * Copyright ยฉ 2012 Mike Dunn <mikedunn@newsguy.com> |
3 | * | 3 | * |
4 | * mtd nand driver for M-Systems DiskOnChip G4 | 4 | * mtd nand driver for M-Systems DiskOnChip G4 |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License, or | 8 | * the Free Software Foundation; either version 2 of the License, or |
9 | * (at your option) any later version. | 9 | * (at your option) any later version. |
10 | * | 10 | * |
11 | * Tested on the Palm Treo 680. The G4 is also present on Toshiba Portege, Asus | 11 | * Tested on the Palm Treo 680. The G4 is also present on Toshiba Portege, Asus |
12 | * P526, some HTC smartphones (Wizard, Prophet, ...), O2 XDA Zinc, maybe others. | 12 | * P526, some HTC smartphones (Wizard, Prophet, ...), O2 XDA Zinc, maybe others. |
13 | * Should work on these as well. Let me know! | 13 | * Should work on these as well. Let me know! |
14 | * | 14 | * |
15 | * TODO: | 15 | * TODO: |
16 | * | 16 | * |
17 | * Mechanism for management of password-protected areas | 17 | * Mechanism for management of password-protected areas |
18 | * | 18 | * |
19 | * Hamming ecc when reading oob only | 19 | * Hamming ecc when reading oob only |
20 | * | 20 | * |
21 | * According to the M-Sys documentation, this device is also available in a | 21 | * According to the M-Sys documentation, this device is also available in a |
22 | * "dual-die" configuration having a 256MB capacity, but no mechanism for | 22 | * "dual-die" configuration having a 256MB capacity, but no mechanism for |
23 | * detecting this variant is documented. Currently this driver assumes 128MB | 23 | * detecting this variant is documented. Currently this driver assumes 128MB |
24 | * capacity. | 24 | * capacity. |
25 | * | 25 | * |
26 | * Support for multiple cascaded devices ("floors"). Not sure which gadgets | 26 | * Support for multiple cascaded devices ("floors"). Not sure which gadgets |
27 | * contain multiple G4s in a cascaded configuration, if any. | 27 | * contain multiple G4s in a cascaded configuration, if any. |
28 | * | 28 | * |
29 | */ | 29 | */ |
30 | 30 | ||
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | #include <linux/string.h> | 34 | #include <linux/string.h> |
35 | #include <linux/sched.h> | 35 | #include <linux/sched.h> |
36 | #include <linux/delay.h> | 36 | #include <linux/delay.h> |
37 | #include <linux/module.h> | 37 | #include <linux/module.h> |
38 | #include <linux/export.h> | 38 | #include <linux/export.h> |
39 | #include <linux/platform_device.h> | 39 | #include <linux/platform_device.h> |
40 | #include <linux/io.h> | 40 | #include <linux/io.h> |
41 | #include <linux/bitops.h> | 41 | #include <linux/bitops.h> |
42 | #include <linux/mtd/partitions.h> | 42 | #include <linux/mtd/partitions.h> |
43 | #include <linux/mtd/mtd.h> | 43 | #include <linux/mtd/mtd.h> |
44 | #include <linux/mtd/nand.h> | 44 | #include <linux/mtd/nand.h> |
45 | #include <linux/bch.h> | 45 | #include <linux/bch.h> |
46 | #include <linux/bitrev.h> | 46 | #include <linux/bitrev.h> |
47 | 47 | ||
48 | /* | 48 | /* |
49 | * In "reliable mode" consecutive 2k pages are used in parallel (in some | 49 | * In "reliable mode" consecutive 2k pages are used in parallel (in some |
50 | * fashion) to store the same data. The data can be read back from the | 50 | * fashion) to store the same data. The data can be read back from the |
51 | * even-numbered pages in the normal manner; odd-numbered pages will appear to | 51 | * even-numbered pages in the normal manner; odd-numbered pages will appear to |
52 | * contain junk. Systems that boot from the docg4 typically write the secondary | 52 | * contain junk. Systems that boot from the docg4 typically write the secondary |
53 | * program loader (SPL) code in this mode. The SPL is loaded by the initial | 53 | * program loader (SPL) code in this mode. The SPL is loaded by the initial |
54 | * program loader (IPL, stored in the docg4's 2k NOR-like region that is mapped | 54 | * program loader (IPL, stored in the docg4's 2k NOR-like region that is mapped |
55 | * to the reset vector address). This module parameter enables you to use this | 55 | * to the reset vector address). This module parameter enables you to use this |
56 | * driver to write the SPL. When in this mode, no more than 2k of data can be | 56 | * driver to write the SPL. When in this mode, no more than 2k of data can be |
57 | * written at a time, because the addresses do not increment in the normal | 57 | * written at a time, because the addresses do not increment in the normal |
58 | * manner, and the starting offset must be within an even-numbered 2k region; | 58 | * manner, and the starting offset must be within an even-numbered 2k region; |
59 | * i.e., invalid starting offsets are 0x800, 0xa00, 0xc00, 0xe00, 0x1800, | 59 | * i.e., invalid starting offsets are 0x800, 0xa00, 0xc00, 0xe00, 0x1800, |
60 | * 0x1a00, ... Reliable mode is a special case and should not be used unless | 60 | * 0x1a00, ... Reliable mode is a special case and should not be used unless |
61 | * you know what you're doing. | 61 | * you know what you're doing. |
62 | */ | 62 | */ |
63 | static bool reliable_mode; | 63 | static bool reliable_mode; |
64 | module_param(reliable_mode, bool, 0); | 64 | module_param(reliable_mode, bool, 0); |
65 | MODULE_PARM_DESC(reliable_mode, "pages are programmed in reliable mode"); | 65 | MODULE_PARM_DESC(reliable_mode, "pages are programmed in reliable mode"); |
66 | 66 | ||
67 | /* | 67 | /* |
68 | * You'll want to ignore badblocks if you're reading a partition that contains | 68 | * You'll want to ignore badblocks if you're reading a partition that contains |
69 | * data written by the TrueFFS library (i.e., by PalmOS, Windows, etc), since | 69 | * data written by the TrueFFS library (i.e., by PalmOS, Windows, etc), since |
70 | * it does not use mtd nand's method for marking bad blocks (using oob area). | 70 | * it does not use mtd nand's method for marking bad blocks (using oob area). |
71 | * This will also skip the check of the "page written" flag. | 71 | * This will also skip the check of the "page written" flag. |
72 | */ | 72 | */ |
73 | static bool ignore_badblocks; | 73 | static bool ignore_badblocks; |
74 | module_param(ignore_badblocks, bool, 0); | 74 | module_param(ignore_badblocks, bool, 0); |
75 | MODULE_PARM_DESC(ignore_badblocks, "no badblock checking performed"); | 75 | MODULE_PARM_DESC(ignore_badblocks, "no badblock checking performed"); |
76 | 76 | ||
77 | struct docg4_priv { | 77 | struct docg4_priv { |
78 | struct mtd_info *mtd; | 78 | struct mtd_info *mtd; |
79 | struct device *dev; | 79 | struct device *dev; |
80 | void __iomem *virtadr; | 80 | void __iomem *virtadr; |
81 | int status; | 81 | int status; |
82 | struct { | 82 | struct { |
83 | unsigned int command; | 83 | unsigned int command; |
84 | int column; | 84 | int column; |
85 | int page; | 85 | int page; |
86 | } last_command; | 86 | } last_command; |
87 | uint8_t oob_buf[16]; | 87 | uint8_t oob_buf[16]; |
88 | uint8_t ecc_buf[7]; | 88 | uint8_t ecc_buf[7]; |
89 | int oob_page; | 89 | int oob_page; |
90 | struct bch_control *bch; | 90 | struct bch_control *bch; |
91 | }; | 91 | }; |
92 | 92 | ||
93 | /* | 93 | /* |
94 | * Defines prefixed with DOCG4 are unique to the diskonchip G4. All others are | 94 | * Defines prefixed with DOCG4 are unique to the diskonchip G4. All others are |
95 | * shared with other diskonchip devices (P3, G3 at least). | 95 | * shared with other diskonchip devices (P3, G3 at least). |
96 | * | 96 | * |
97 | * Functions with names prefixed with docg4_ are mtd / nand interface functions | 97 | * Functions with names prefixed with docg4_ are mtd / nand interface functions |
98 | * (though they may also be called internally). All others are internal. | 98 | * (though they may also be called internally). All others are internal. |
99 | */ | 99 | */ |
100 | 100 | ||
101 | #define DOC_IOSPACE_DATA 0x0800 | 101 | #define DOC_IOSPACE_DATA 0x0800 |
102 | 102 | ||
103 | /* register offsets */ | 103 | /* register offsets */ |
104 | #define DOC_CHIPID 0x1000 | 104 | #define DOC_CHIPID 0x1000 |
105 | #define DOC_DEVICESELECT 0x100a | 105 | #define DOC_DEVICESELECT 0x100a |
106 | #define DOC_ASICMODE 0x100c | 106 | #define DOC_ASICMODE 0x100c |
107 | #define DOC_DATAEND 0x101e | 107 | #define DOC_DATAEND 0x101e |
108 | #define DOC_NOP 0x103e | 108 | #define DOC_NOP 0x103e |
109 | 109 | ||
110 | #define DOC_FLASHSEQUENCE 0x1032 | 110 | #define DOC_FLASHSEQUENCE 0x1032 |
111 | #define DOC_FLASHCOMMAND 0x1034 | 111 | #define DOC_FLASHCOMMAND 0x1034 |
112 | #define DOC_FLASHADDRESS 0x1036 | 112 | #define DOC_FLASHADDRESS 0x1036 |
113 | #define DOC_FLASHCONTROL 0x1038 | 113 | #define DOC_FLASHCONTROL 0x1038 |
114 | #define DOC_ECCCONF0 0x1040 | 114 | #define DOC_ECCCONF0 0x1040 |
115 | #define DOC_ECCCONF1 0x1042 | 115 | #define DOC_ECCCONF1 0x1042 |
116 | #define DOC_HAMMINGPARITY 0x1046 | 116 | #define DOC_HAMMINGPARITY 0x1046 |
117 | #define DOC_BCH_SYNDROM(idx) (0x1048 + idx) | 117 | #define DOC_BCH_SYNDROM(idx) (0x1048 + idx) |
118 | 118 | ||
119 | #define DOC_ASICMODECONFIRM 0x1072 | 119 | #define DOC_ASICMODECONFIRM 0x1072 |
120 | #define DOC_CHIPID_INV 0x1074 | 120 | #define DOC_CHIPID_INV 0x1074 |
121 | #define DOC_POWERMODE 0x107c | 121 | #define DOC_POWERMODE 0x107c |
122 | 122 | ||
123 | #define DOCG4_MYSTERY_REG 0x1050 | 123 | #define DOCG4_MYSTERY_REG 0x1050 |
124 | 124 | ||
125 | /* apparently used only to write oob bytes 6 and 7 */ | 125 | /* apparently used only to write oob bytes 6 and 7 */ |
126 | #define DOCG4_OOB_6_7 0x1052 | 126 | #define DOCG4_OOB_6_7 0x1052 |
127 | 127 | ||
128 | /* DOC_FLASHSEQUENCE register commands */ | 128 | /* DOC_FLASHSEQUENCE register commands */ |
129 | #define DOC_SEQ_RESET 0x00 | 129 | #define DOC_SEQ_RESET 0x00 |
130 | #define DOCG4_SEQ_PAGE_READ 0x03 | 130 | #define DOCG4_SEQ_PAGE_READ 0x03 |
131 | #define DOCG4_SEQ_FLUSH 0x29 | 131 | #define DOCG4_SEQ_FLUSH 0x29 |
132 | #define DOCG4_SEQ_PAGEWRITE 0x16 | 132 | #define DOCG4_SEQ_PAGEWRITE 0x16 |
133 | #define DOCG4_SEQ_PAGEPROG 0x1e | 133 | #define DOCG4_SEQ_PAGEPROG 0x1e |
134 | #define DOCG4_SEQ_BLOCKERASE 0x24 | 134 | #define DOCG4_SEQ_BLOCKERASE 0x24 |
135 | #define DOCG4_SEQ_SETMODE 0x45 | 135 | #define DOCG4_SEQ_SETMODE 0x45 |
136 | 136 | ||
137 | /* DOC_FLASHCOMMAND register commands */ | 137 | /* DOC_FLASHCOMMAND register commands */ |
138 | #define DOCG4_CMD_PAGE_READ 0x00 | 138 | #define DOCG4_CMD_PAGE_READ 0x00 |
139 | #define DOC_CMD_ERASECYCLE2 0xd0 | 139 | #define DOC_CMD_ERASECYCLE2 0xd0 |
140 | #define DOCG4_CMD_FLUSH 0x70 | 140 | #define DOCG4_CMD_FLUSH 0x70 |
141 | #define DOCG4_CMD_READ2 0x30 | 141 | #define DOCG4_CMD_READ2 0x30 |
142 | #define DOC_CMD_PROG_BLOCK_ADDR 0x60 | 142 | #define DOC_CMD_PROG_BLOCK_ADDR 0x60 |
143 | #define DOCG4_CMD_PAGEWRITE 0x80 | 143 | #define DOCG4_CMD_PAGEWRITE 0x80 |
144 | #define DOC_CMD_PROG_CYCLE2 0x10 | 144 | #define DOC_CMD_PROG_CYCLE2 0x10 |
145 | #define DOCG4_CMD_FAST_MODE 0xa3 /* functionality guessed */ | 145 | #define DOCG4_CMD_FAST_MODE 0xa3 /* functionality guessed */ |
146 | #define DOC_CMD_RELIABLE_MODE 0x22 | 146 | #define DOC_CMD_RELIABLE_MODE 0x22 |
147 | #define DOC_CMD_RESET 0xff | 147 | #define DOC_CMD_RESET 0xff |
148 | 148 | ||
149 | /* DOC_POWERMODE register bits */ | 149 | /* DOC_POWERMODE register bits */ |
150 | #define DOC_POWERDOWN_READY 0x80 | 150 | #define DOC_POWERDOWN_READY 0x80 |
151 | 151 | ||
152 | /* DOC_FLASHCONTROL register bits */ | 152 | /* DOC_FLASHCONTROL register bits */ |
153 | #define DOC_CTRL_CE 0x10 | 153 | #define DOC_CTRL_CE 0x10 |
154 | #define DOC_CTRL_UNKNOWN 0x40 | 154 | #define DOC_CTRL_UNKNOWN 0x40 |
155 | #define DOC_CTRL_FLASHREADY 0x01 | 155 | #define DOC_CTRL_FLASHREADY 0x01 |
156 | 156 | ||
157 | /* DOC_ECCCONF0 register bits */ | 157 | /* DOC_ECCCONF0 register bits */ |
158 | #define DOC_ECCCONF0_READ_MODE 0x8000 | 158 | #define DOC_ECCCONF0_READ_MODE 0x8000 |
159 | #define DOC_ECCCONF0_UNKNOWN 0x2000 | 159 | #define DOC_ECCCONF0_UNKNOWN 0x2000 |
160 | #define DOC_ECCCONF0_ECC_ENABLE 0x1000 | 160 | #define DOC_ECCCONF0_ECC_ENABLE 0x1000 |
161 | #define DOC_ECCCONF0_DATA_BYTES_MASK 0x07ff | 161 | #define DOC_ECCCONF0_DATA_BYTES_MASK 0x07ff |
162 | 162 | ||
163 | /* DOC_ECCCONF1 register bits */ | 163 | /* DOC_ECCCONF1 register bits */ |
164 | #define DOC_ECCCONF1_BCH_SYNDROM_ERR 0x80 | 164 | #define DOC_ECCCONF1_BCH_SYNDROM_ERR 0x80 |
165 | #define DOC_ECCCONF1_ECC_ENABLE 0x07 | 165 | #define DOC_ECCCONF1_ECC_ENABLE 0x07 |
166 | #define DOC_ECCCONF1_PAGE_IS_WRITTEN 0x20 | 166 | #define DOC_ECCCONF1_PAGE_IS_WRITTEN 0x20 |
167 | 167 | ||
168 | /* DOC_ASICMODE register bits */ | 168 | /* DOC_ASICMODE register bits */ |
169 | #define DOC_ASICMODE_RESET 0x00 | 169 | #define DOC_ASICMODE_RESET 0x00 |
170 | #define DOC_ASICMODE_NORMAL 0x01 | 170 | #define DOC_ASICMODE_NORMAL 0x01 |
171 | #define DOC_ASICMODE_POWERDOWN 0x02 | 171 | #define DOC_ASICMODE_POWERDOWN 0x02 |
172 | #define DOC_ASICMODE_MDWREN 0x04 | 172 | #define DOC_ASICMODE_MDWREN 0x04 |
173 | #define DOC_ASICMODE_BDETCT_RESET 0x08 | 173 | #define DOC_ASICMODE_BDETCT_RESET 0x08 |
174 | #define DOC_ASICMODE_RSTIN_RESET 0x10 | 174 | #define DOC_ASICMODE_RSTIN_RESET 0x10 |
175 | #define DOC_ASICMODE_RAM_WE 0x20 | 175 | #define DOC_ASICMODE_RAM_WE 0x20 |
176 | 176 | ||
177 | /* good status values read after read/write/erase operations */ | 177 | /* good status values read after read/write/erase operations */ |
178 | #define DOCG4_PROGSTATUS_GOOD 0x51 | 178 | #define DOCG4_PROGSTATUS_GOOD 0x51 |
179 | #define DOCG4_PROGSTATUS_GOOD_2 0xe0 | 179 | #define DOCG4_PROGSTATUS_GOOD_2 0xe0 |
180 | 180 | ||
181 | /* | 181 | /* |
182 | * On read operations (page and oob-only), the first byte read from I/O reg is a | 182 | * On read operations (page and oob-only), the first byte read from I/O reg is a |
183 | * status. On error, it reads 0x73; otherwise, it reads either 0x71 (first read | 183 | * status. On error, it reads 0x73; otherwise, it reads either 0x71 (first read |
184 | * after reset only) or 0x51, so bit 1 is presumed to be an error indicator. | 184 | * after reset only) or 0x51, so bit 1 is presumed to be an error indicator. |
185 | */ | 185 | */ |
186 | #define DOCG4_READ_ERROR 0x02 /* bit 1 indicates read error */ | 186 | #define DOCG4_READ_ERROR 0x02 /* bit 1 indicates read error */ |
187 | 187 | ||
188 | /* anatomy of the device */ | 188 | /* anatomy of the device */ |
189 | #define DOCG4_CHIP_SIZE 0x8000000 | 189 | #define DOCG4_CHIP_SIZE 0x8000000 |
190 | #define DOCG4_PAGE_SIZE 0x200 | 190 | #define DOCG4_PAGE_SIZE 0x200 |
191 | #define DOCG4_PAGES_PER_BLOCK 0x200 | 191 | #define DOCG4_PAGES_PER_BLOCK 0x200 |
192 | #define DOCG4_BLOCK_SIZE (DOCG4_PAGES_PER_BLOCK * DOCG4_PAGE_SIZE) | 192 | #define DOCG4_BLOCK_SIZE (DOCG4_PAGES_PER_BLOCK * DOCG4_PAGE_SIZE) |
193 | #define DOCG4_NUMBLOCKS (DOCG4_CHIP_SIZE / DOCG4_BLOCK_SIZE) | 193 | #define DOCG4_NUMBLOCKS (DOCG4_CHIP_SIZE / DOCG4_BLOCK_SIZE) |
194 | #define DOCG4_OOB_SIZE 0x10 | 194 | #define DOCG4_OOB_SIZE 0x10 |
195 | #define DOCG4_CHIP_SHIFT 27 /* log_2(DOCG4_CHIP_SIZE) */ | 195 | #define DOCG4_CHIP_SHIFT 27 /* log_2(DOCG4_CHIP_SIZE) */ |
196 | #define DOCG4_PAGE_SHIFT 9 /* log_2(DOCG4_PAGE_SIZE) */ | 196 | #define DOCG4_PAGE_SHIFT 9 /* log_2(DOCG4_PAGE_SIZE) */ |
197 | #define DOCG4_ERASE_SHIFT 18 /* log_2(DOCG4_BLOCK_SIZE) */ | 197 | #define DOCG4_ERASE_SHIFT 18 /* log_2(DOCG4_BLOCK_SIZE) */ |
198 | 198 | ||
199 | /* all but the last byte is included in ecc calculation */ | 199 | /* all but the last byte is included in ecc calculation */ |
200 | #define DOCG4_BCH_SIZE (DOCG4_PAGE_SIZE + DOCG4_OOB_SIZE - 1) | 200 | #define DOCG4_BCH_SIZE (DOCG4_PAGE_SIZE + DOCG4_OOB_SIZE - 1) |
201 | 201 | ||
202 | #define DOCG4_USERDATA_LEN 520 /* 512 byte page plus 8 oob avail to user */ | 202 | #define DOCG4_USERDATA_LEN 520 /* 512 byte page plus 8 oob avail to user */ |
203 | 203 | ||
204 | /* expected values from the ID registers */ | 204 | /* expected values from the ID registers */ |
205 | #define DOCG4_IDREG1_VALUE 0x0400 | 205 | #define DOCG4_IDREG1_VALUE 0x0400 |
206 | #define DOCG4_IDREG2_VALUE 0xfbff | 206 | #define DOCG4_IDREG2_VALUE 0xfbff |
207 | 207 | ||
208 | /* primitive polynomial used to build the Galois field used by hw ecc gen */ | 208 | /* primitive polynomial used to build the Galois field used by hw ecc gen */ |
209 | #define DOCG4_PRIMITIVE_POLY 0x4443 | 209 | #define DOCG4_PRIMITIVE_POLY 0x4443 |
210 | 210 | ||
211 | #define DOCG4_M 14 /* Galois field is of order 2^14 */ | 211 | #define DOCG4_M 14 /* Galois field is of order 2^14 */ |
212 | #define DOCG4_T 4 /* BCH alg corrects up to 4 bit errors */ | 212 | #define DOCG4_T 4 /* BCH alg corrects up to 4 bit errors */ |
213 | 213 | ||
214 | #define DOCG4_FACTORY_BBT_PAGE 16 /* page where read-only factory bbt lives */ | 214 | #define DOCG4_FACTORY_BBT_PAGE 16 /* page where read-only factory bbt lives */ |
215 | #define DOCG4_REDUNDANT_BBT_PAGE 24 /* page where redundant factory bbt lives */ | 215 | #define DOCG4_REDUNDANT_BBT_PAGE 24 /* page where redundant factory bbt lives */ |
216 | 216 | ||
217 | /* | 217 | /* |
218 | * Bytes 0, 1 are used as badblock marker. | 218 | * Bytes 0, 1 are used as badblock marker. |
219 | * Bytes 2 - 6 are available to the user. | 219 | * Bytes 2 - 6 are available to the user. |
220 | * Byte 7 is hamming ecc for first 7 oob bytes only. | 220 | * Byte 7 is hamming ecc for first 7 oob bytes only. |
221 | * Bytes 8 - 14 are hw-generated ecc covering entire page + oob bytes 0 - 14. | 221 | * Bytes 8 - 14 are hw-generated ecc covering entire page + oob bytes 0 - 14. |
222 | * Byte 15 (the last) is used by the driver as a "page written" flag. | 222 | * Byte 15 (the last) is used by the driver as a "page written" flag. |
223 | */ | 223 | */ |
224 | static struct nand_ecclayout docg4_oobinfo = { | 224 | static struct nand_ecclayout docg4_oobinfo = { |
225 | .eccbytes = 9, | 225 | .eccbytes = 9, |
226 | .eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15}, | 226 | .eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15}, |
227 | .oobavail = 5, | 227 | .oobavail = 5, |
228 | .oobfree = { {.offset = 2, .length = 5} } | 228 | .oobfree = { {.offset = 2, .length = 5} } |
229 | }; | 229 | }; |
230 | 230 | ||
231 | /* | 231 | /* |
232 | * The device has a nop register which M-Sys claims is for the purpose of | 232 | * The device has a nop register which M-Sys claims is for the purpose of |
233 | * inserting precise delays. But beware; at least some operations fail if the | 233 | * inserting precise delays. But beware; at least some operations fail if the |
234 | * nop writes are replaced with a generic delay! | 234 | * nop writes are replaced with a generic delay! |
235 | */ | 235 | */ |
236 | static inline void write_nop(void __iomem *docptr) | 236 | static inline void write_nop(void __iomem *docptr) |
237 | { | 237 | { |
238 | writew(0, docptr + DOC_NOP); | 238 | writew(0, docptr + DOC_NOP); |
239 | } | 239 | } |
240 | 240 | ||
241 | static void docg4_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | 241 | static void docg4_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) |
242 | { | 242 | { |
243 | int i; | 243 | int i; |
244 | struct nand_chip *nand = mtd->priv; | 244 | struct nand_chip *nand = mtd->priv; |
245 | uint16_t *p = (uint16_t *) buf; | 245 | uint16_t *p = (uint16_t *) buf; |
246 | len >>= 1; | 246 | len >>= 1; |
247 | 247 | ||
248 | for (i = 0; i < len; i++) | 248 | for (i = 0; i < len; i++) |
249 | p[i] = readw(nand->IO_ADDR_R); | 249 | p[i] = readw(nand->IO_ADDR_R); |
250 | } | 250 | } |
251 | 251 | ||
252 | static void docg4_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) | 252 | static void docg4_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) |
253 | { | 253 | { |
254 | int i; | 254 | int i; |
255 | struct nand_chip *nand = mtd->priv; | 255 | struct nand_chip *nand = mtd->priv; |
256 | uint16_t *p = (uint16_t *) buf; | 256 | uint16_t *p = (uint16_t *) buf; |
257 | len >>= 1; | 257 | len >>= 1; |
258 | 258 | ||
259 | for (i = 0; i < len; i++) | 259 | for (i = 0; i < len; i++) |
260 | writew(p[i], nand->IO_ADDR_W); | 260 | writew(p[i], nand->IO_ADDR_W); |
261 | } | 261 | } |
262 | 262 | ||
263 | static int poll_status(struct docg4_priv *doc) | 263 | static int poll_status(struct docg4_priv *doc) |
264 | { | 264 | { |
265 | /* | 265 | /* |
266 | * Busy-wait for the FLASHREADY bit to be set in the FLASHCONTROL | 266 | * Busy-wait for the FLASHREADY bit to be set in the FLASHCONTROL |
267 | * register. Operations known to take a long time (e.g., block erase) | 267 | * register. Operations known to take a long time (e.g., block erase) |
268 | * should sleep for a while before calling this. | 268 | * should sleep for a while before calling this. |
269 | */ | 269 | */ |
270 | 270 | ||
271 | uint16_t flash_status; | 271 | uint16_t flash_status; |
272 | unsigned int timeo; | 272 | unsigned int timeo; |
273 | void __iomem *docptr = doc->virtadr; | 273 | void __iomem *docptr = doc->virtadr; |
274 | 274 | ||
275 | dev_dbg(doc->dev, "%s...\n", __func__); | 275 | dev_dbg(doc->dev, "%s...\n", __func__); |
276 | 276 | ||
277 | /* hardware quirk requires reading twice initially */ | 277 | /* hardware quirk requires reading twice initially */ |
278 | flash_status = readw(docptr + DOC_FLASHCONTROL); | 278 | flash_status = readw(docptr + DOC_FLASHCONTROL); |
279 | 279 | ||
280 | timeo = 1000; | 280 | timeo = 1000; |
281 | do { | 281 | do { |
282 | cpu_relax(); | 282 | cpu_relax(); |
283 | flash_status = readb(docptr + DOC_FLASHCONTROL); | 283 | flash_status = readb(docptr + DOC_FLASHCONTROL); |
284 | } while (!(flash_status & DOC_CTRL_FLASHREADY) && --timeo); | 284 | } while (!(flash_status & DOC_CTRL_FLASHREADY) && --timeo); |
285 | 285 | ||
286 | 286 | ||
287 | if (!timeo) { | 287 | if (!timeo) { |
288 | dev_err(doc->dev, "%s: timed out!\n", __func__); | 288 | dev_err(doc->dev, "%s: timed out!\n", __func__); |
289 | return NAND_STATUS_FAIL; | 289 | return NAND_STATUS_FAIL; |
290 | } | 290 | } |
291 | 291 | ||
292 | if (unlikely(timeo < 50)) | 292 | if (unlikely(timeo < 50)) |
293 | dev_warn(doc->dev, "%s: nearly timed out; %d remaining\n", | 293 | dev_warn(doc->dev, "%s: nearly timed out; %d remaining\n", |
294 | __func__, timeo); | 294 | __func__, timeo); |
295 | 295 | ||
296 | return 0; | 296 | return 0; |
297 | } | 297 | } |
298 | 298 | ||
299 | 299 | ||
300 | static int docg4_wait(struct mtd_info *mtd, struct nand_chip *nand) | 300 | static int docg4_wait(struct mtd_info *mtd, struct nand_chip *nand) |
301 | { | 301 | { |
302 | 302 | ||
303 | struct docg4_priv *doc = nand->priv; | 303 | struct docg4_priv *doc = nand->priv; |
304 | int status = NAND_STATUS_WP; /* inverse logic?? */ | 304 | int status = NAND_STATUS_WP; /* inverse logic?? */ |
305 | dev_dbg(doc->dev, "%s...\n", __func__); | 305 | dev_dbg(doc->dev, "%s...\n", __func__); |
306 | 306 | ||
307 | /* report any previously unreported error */ | 307 | /* report any previously unreported error */ |
308 | if (doc->status) { | 308 | if (doc->status) { |
309 | status |= doc->status; | 309 | status |= doc->status; |
310 | doc->status = 0; | 310 | doc->status = 0; |
311 | return status; | 311 | return status; |
312 | } | 312 | } |
313 | 313 | ||
314 | status |= poll_status(doc); | 314 | status |= poll_status(doc); |
315 | return status; | 315 | return status; |
316 | } | 316 | } |
317 | 317 | ||
318 | static void docg4_select_chip(struct mtd_info *mtd, int chip) | 318 | static void docg4_select_chip(struct mtd_info *mtd, int chip) |
319 | { | 319 | { |
320 | /* | 320 | /* |
321 | * Select among multiple cascaded chips ("floors"). Multiple floors are | 321 | * Select among multiple cascaded chips ("floors"). Multiple floors are |
322 | * not yet supported, so the only valid non-negative value is 0. | 322 | * not yet supported, so the only valid non-negative value is 0. |
323 | */ | 323 | */ |
324 | struct nand_chip *nand = mtd->priv; | 324 | struct nand_chip *nand = mtd->priv; |
325 | struct docg4_priv *doc = nand->priv; | 325 | struct docg4_priv *doc = nand->priv; |
326 | void __iomem *docptr = doc->virtadr; | 326 | void __iomem *docptr = doc->virtadr; |
327 | 327 | ||
328 | dev_dbg(doc->dev, "%s: chip %d\n", __func__, chip); | 328 | dev_dbg(doc->dev, "%s: chip %d\n", __func__, chip); |
329 | 329 | ||
330 | if (chip < 0) | 330 | if (chip < 0) |
331 | return; /* deselected */ | 331 | return; /* deselected */ |
332 | 332 | ||
333 | if (chip > 0) | 333 | if (chip > 0) |
334 | dev_warn(doc->dev, "multiple floors currently unsupported\n"); | 334 | dev_warn(doc->dev, "multiple floors currently unsupported\n"); |
335 | 335 | ||
336 | writew(0, docptr + DOC_DEVICESELECT); | 336 | writew(0, docptr + DOC_DEVICESELECT); |
337 | } | 337 | } |
338 | 338 | ||
339 | static void reset(struct mtd_info *mtd) | 339 | static void reset(struct mtd_info *mtd) |
340 | { | 340 | { |
341 | /* full device reset */ | 341 | /* full device reset */ |
342 | 342 | ||
343 | struct nand_chip *nand = mtd->priv; | 343 | struct nand_chip *nand = mtd->priv; |
344 | struct docg4_priv *doc = nand->priv; | 344 | struct docg4_priv *doc = nand->priv; |
345 | void __iomem *docptr = doc->virtadr; | 345 | void __iomem *docptr = doc->virtadr; |
346 | 346 | ||
347 | writew(DOC_ASICMODE_RESET | DOC_ASICMODE_MDWREN, | 347 | writew(DOC_ASICMODE_RESET | DOC_ASICMODE_MDWREN, |
348 | docptr + DOC_ASICMODE); | 348 | docptr + DOC_ASICMODE); |
349 | writew(~(DOC_ASICMODE_RESET | DOC_ASICMODE_MDWREN), | 349 | writew(~(DOC_ASICMODE_RESET | DOC_ASICMODE_MDWREN), |
350 | docptr + DOC_ASICMODECONFIRM); | 350 | docptr + DOC_ASICMODECONFIRM); |
351 | write_nop(docptr); | 351 | write_nop(docptr); |
352 | 352 | ||
353 | writew(DOC_ASICMODE_NORMAL | DOC_ASICMODE_MDWREN, | 353 | writew(DOC_ASICMODE_NORMAL | DOC_ASICMODE_MDWREN, |
354 | docptr + DOC_ASICMODE); | 354 | docptr + DOC_ASICMODE); |
355 | writew(~(DOC_ASICMODE_NORMAL | DOC_ASICMODE_MDWREN), | 355 | writew(~(DOC_ASICMODE_NORMAL | DOC_ASICMODE_MDWREN), |
356 | docptr + DOC_ASICMODECONFIRM); | 356 | docptr + DOC_ASICMODECONFIRM); |
357 | 357 | ||
358 | writew(DOC_ECCCONF1_ECC_ENABLE, docptr + DOC_ECCCONF1); | 358 | writew(DOC_ECCCONF1_ECC_ENABLE, docptr + DOC_ECCCONF1); |
359 | 359 | ||
360 | poll_status(doc); | 360 | poll_status(doc); |
361 | } | 361 | } |
362 | 362 | ||
363 | static void read_hw_ecc(void __iomem *docptr, uint8_t *ecc_buf) | 363 | static void read_hw_ecc(void __iomem *docptr, uint8_t *ecc_buf) |
364 | { | 364 | { |
365 | /* read the 7 hw-generated ecc bytes */ | 365 | /* read the 7 hw-generated ecc bytes */ |
366 | 366 | ||
367 | int i; | 367 | int i; |
368 | for (i = 0; i < 7; i++) { /* hw quirk; read twice */ | 368 | for (i = 0; i < 7; i++) { /* hw quirk; read twice */ |
369 | ecc_buf[i] = readb(docptr + DOC_BCH_SYNDROM(i)); | 369 | ecc_buf[i] = readb(docptr + DOC_BCH_SYNDROM(i)); |
370 | ecc_buf[i] = readb(docptr + DOC_BCH_SYNDROM(i)); | 370 | ecc_buf[i] = readb(docptr + DOC_BCH_SYNDROM(i)); |
371 | } | 371 | } |
372 | } | 372 | } |
373 | 373 | ||
374 | static int correct_data(struct mtd_info *mtd, uint8_t *buf, int page) | 374 | static int correct_data(struct mtd_info *mtd, uint8_t *buf, int page) |
375 | { | 375 | { |
376 | /* | 376 | /* |
377 | * Called after a page read when hardware reports bitflips. | 377 | * Called after a page read when hardware reports bitflips. |
378 | * Up to four bitflips can be corrected. | 378 | * Up to four bitflips can be corrected. |
379 | */ | 379 | */ |
380 | 380 | ||
381 | struct nand_chip *nand = mtd->priv; | 381 | struct nand_chip *nand = mtd->priv; |
382 | struct docg4_priv *doc = nand->priv; | 382 | struct docg4_priv *doc = nand->priv; |
383 | void __iomem *docptr = doc->virtadr; | 383 | void __iomem *docptr = doc->virtadr; |
384 | int i, numerrs, errpos[4]; | 384 | int i, numerrs, errpos[4]; |
385 | const uint8_t blank_read_hwecc[8] = { | 385 | const uint8_t blank_read_hwecc[8] = { |
386 | 0xcf, 0x72, 0xfc, 0x1b, 0xa9, 0xc7, 0xb9, 0 }; | 386 | 0xcf, 0x72, 0xfc, 0x1b, 0xa9, 0xc7, 0xb9, 0 }; |
387 | 387 | ||
388 | read_hw_ecc(docptr, doc->ecc_buf); /* read 7 hw-generated ecc bytes */ | 388 | read_hw_ecc(docptr, doc->ecc_buf); /* read 7 hw-generated ecc bytes */ |
389 | 389 | ||
390 | /* check if read error is due to a blank page */ | 390 | /* check if read error is due to a blank page */ |
391 | if (!memcmp(doc->ecc_buf, blank_read_hwecc, 7)) | 391 | if (!memcmp(doc->ecc_buf, blank_read_hwecc, 7)) |
392 | return 0; /* yes */ | 392 | return 0; /* yes */ |
393 | 393 | ||
394 | /* skip additional check of "written flag" if ignore_badblocks */ | 394 | /* skip additional check of "written flag" if ignore_badblocks */ |
395 | if (ignore_badblocks == false) { | 395 | if (ignore_badblocks == false) { |
396 | 396 | ||
397 | /* | 397 | /* |
398 | * If the hw ecc bytes are not those of a blank page, there's | 398 | * If the hw ecc bytes are not those of a blank page, there's |
399 | * still a chance that the page is blank, but was read with | 399 | * still a chance that the page is blank, but was read with |
400 | * errors. Check the "written flag" in last oob byte, which | 400 | * errors. Check the "written flag" in last oob byte, which |
401 | * is set to zero when a page is written. If more than half | 401 | * is set to zero when a page is written. If more than half |
402 | * the bits are set, assume a blank page. Unfortunately, the | 402 | * the bits are set, assume a blank page. Unfortunately, the |
403 | * bit flips(s) are not reported in stats. | 403 | * bit flips(s) are not reported in stats. |
404 | */ | 404 | */ |
405 | 405 | ||
406 | if (nand->oob_poi[15]) { | 406 | if (nand->oob_poi[15]) { |
407 | int bit, numsetbits = 0; | 407 | int bit, numsetbits = 0; |
408 | unsigned long written_flag = nand->oob_poi[15]; | 408 | unsigned long written_flag = nand->oob_poi[15]; |
409 | for_each_set_bit(bit, &written_flag, 8) | 409 | for_each_set_bit(bit, &written_flag, 8) |
410 | numsetbits++; | 410 | numsetbits++; |
411 | if (numsetbits > 4) { /* assume blank */ | 411 | if (numsetbits > 4) { /* assume blank */ |
412 | dev_warn(doc->dev, | 412 | dev_warn(doc->dev, |
413 | "error(s) in blank page " | 413 | "error(s) in blank page " |
414 | "at offset %08x\n", | 414 | "at offset %08x\n", |
415 | page * DOCG4_PAGE_SIZE); | 415 | page * DOCG4_PAGE_SIZE); |
416 | return 0; | 416 | return 0; |
417 | } | 417 | } |
418 | } | 418 | } |
419 | } | 419 | } |
420 | 420 | ||
421 | /* | 421 | /* |
422 | * The hardware ecc unit produces oob_ecc ^ calc_ecc. The kernel's bch | 422 | * The hardware ecc unit produces oob_ecc ^ calc_ecc. The kernel's bch |
423 | * algorithm is used to decode this. However the hw operates on page | 423 | * algorithm is used to decode this. However the hw operates on page |
424 | * data in a bit order that is the reverse of that of the bch alg, | 424 | * data in a bit order that is the reverse of that of the bch alg, |
425 | * requiring that the bits be reversed on the result. Thanks to Ivan | 425 | * requiring that the bits be reversed on the result. Thanks to Ivan |
426 | * Djelic for his analysis! | 426 | * Djelic for his analysis! |
427 | */ | 427 | */ |
428 | for (i = 0; i < 7; i++) | 428 | for (i = 0; i < 7; i++) |
429 | doc->ecc_buf[i] = bitrev8(doc->ecc_buf[i]); | 429 | doc->ecc_buf[i] = bitrev8(doc->ecc_buf[i]); |
430 | 430 | ||
431 | numerrs = decode_bch(doc->bch, NULL, DOCG4_USERDATA_LEN, NULL, | 431 | numerrs = decode_bch(doc->bch, NULL, DOCG4_USERDATA_LEN, NULL, |
432 | doc->ecc_buf, NULL, errpos); | 432 | doc->ecc_buf, NULL, errpos); |
433 | 433 | ||
434 | if (numerrs == -EBADMSG) { | 434 | if (numerrs == -EBADMSG) { |
435 | dev_warn(doc->dev, "uncorrectable errors at offset %08x\n", | 435 | dev_warn(doc->dev, "uncorrectable errors at offset %08x\n", |
436 | page * DOCG4_PAGE_SIZE); | 436 | page * DOCG4_PAGE_SIZE); |
437 | return -EBADMSG; | 437 | return -EBADMSG; |
438 | } | 438 | } |
439 | 439 | ||
440 | BUG_ON(numerrs < 0); /* -EINVAL, or anything other than -EBADMSG */ | 440 | BUG_ON(numerrs < 0); /* -EINVAL, or anything other than -EBADMSG */ |
441 | 441 | ||
442 | /* undo last step in BCH alg (modulo mirroring not needed) */ | 442 | /* undo last step in BCH alg (modulo mirroring not needed) */ |
443 | for (i = 0; i < numerrs; i++) | 443 | for (i = 0; i < numerrs; i++) |
444 | errpos[i] = (errpos[i] & ~7)|(7-(errpos[i] & 7)); | 444 | errpos[i] = (errpos[i] & ~7)|(7-(errpos[i] & 7)); |
445 | 445 | ||
446 | /* fix the errors */ | 446 | /* fix the errors */ |
447 | for (i = 0; i < numerrs; i++) { | 447 | for (i = 0; i < numerrs; i++) { |
448 | 448 | ||
449 | /* ignore if error within oob ecc bytes */ | 449 | /* ignore if error within oob ecc bytes */ |
450 | if (errpos[i] > DOCG4_USERDATA_LEN * 8) | 450 | if (errpos[i] > DOCG4_USERDATA_LEN * 8) |
451 | continue; | 451 | continue; |
452 | 452 | ||
453 | /* if error within oob area preceeding ecc bytes... */ | 453 | /* if error within oob area preceeding ecc bytes... */ |
454 | if (errpos[i] > DOCG4_PAGE_SIZE * 8) | 454 | if (errpos[i] > DOCG4_PAGE_SIZE * 8) |
455 | change_bit(errpos[i] - DOCG4_PAGE_SIZE * 8, | 455 | change_bit(errpos[i] - DOCG4_PAGE_SIZE * 8, |
456 | (unsigned long *)nand->oob_poi); | 456 | (unsigned long *)nand->oob_poi); |
457 | 457 | ||
458 | else /* error in page data */ | 458 | else /* error in page data */ |
459 | change_bit(errpos[i], (unsigned long *)buf); | 459 | change_bit(errpos[i], (unsigned long *)buf); |
460 | } | 460 | } |
461 | 461 | ||
462 | dev_notice(doc->dev, "%d error(s) corrected at offset %08x\n", | 462 | dev_notice(doc->dev, "%d error(s) corrected at offset %08x\n", |
463 | numerrs, page * DOCG4_PAGE_SIZE); | 463 | numerrs, page * DOCG4_PAGE_SIZE); |
464 | 464 | ||
465 | return numerrs; | 465 | return numerrs; |
466 | } | 466 | } |
467 | 467 | ||
468 | static uint8_t docg4_read_byte(struct mtd_info *mtd) | 468 | static uint8_t docg4_read_byte(struct mtd_info *mtd) |
469 | { | 469 | { |
470 | struct nand_chip *nand = mtd->priv; | 470 | struct nand_chip *nand = mtd->priv; |
471 | struct docg4_priv *doc = nand->priv; | 471 | struct docg4_priv *doc = nand->priv; |
472 | 472 | ||
473 | dev_dbg(doc->dev, "%s\n", __func__); | 473 | dev_dbg(doc->dev, "%s\n", __func__); |
474 | 474 | ||
475 | if (doc->last_command.command == NAND_CMD_STATUS) { | 475 | if (doc->last_command.command == NAND_CMD_STATUS) { |
476 | int status; | 476 | int status; |
477 | 477 | ||
478 | /* | 478 | /* |
479 | * Previous nand command was status request, so nand | 479 | * Previous nand command was status request, so nand |
480 | * infrastructure code expects to read the status here. If an | 480 | * infrastructure code expects to read the status here. If an |
481 | * error occurred in a previous operation, report it. | 481 | * error occurred in a previous operation, report it. |
482 | */ | 482 | */ |
483 | doc->last_command.command = 0; | 483 | doc->last_command.command = 0; |
484 | 484 | ||
485 | if (doc->status) { | 485 | if (doc->status) { |
486 | status = doc->status; | 486 | status = doc->status; |
487 | doc->status = 0; | 487 | doc->status = 0; |
488 | } | 488 | } |
489 | 489 | ||
490 | /* why is NAND_STATUS_WP inverse logic?? */ | 490 | /* why is NAND_STATUS_WP inverse logic?? */ |
491 | else | 491 | else |
492 | status = NAND_STATUS_WP | NAND_STATUS_READY; | 492 | status = NAND_STATUS_WP | NAND_STATUS_READY; |
493 | 493 | ||
494 | return status; | 494 | return status; |
495 | } | 495 | } |
496 | 496 | ||
497 | dev_warn(doc->dev, "unexpectd call to read_byte()\n"); | 497 | dev_warn(doc->dev, "unexpectd call to read_byte()\n"); |
498 | 498 | ||
499 | return 0; | 499 | return 0; |
500 | } | 500 | } |
501 | 501 | ||
502 | static void write_addr(struct docg4_priv *doc, uint32_t docg4_addr) | 502 | static void write_addr(struct docg4_priv *doc, uint32_t docg4_addr) |
503 | { | 503 | { |
504 | /* write the four address bytes packed in docg4_addr to the device */ | 504 | /* write the four address bytes packed in docg4_addr to the device */ |
505 | 505 | ||
506 | void __iomem *docptr = doc->virtadr; | 506 | void __iomem *docptr = doc->virtadr; |
507 | writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); | 507 | writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); |
508 | docg4_addr >>= 8; | 508 | docg4_addr >>= 8; |
509 | writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); | 509 | writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); |
510 | docg4_addr >>= 8; | 510 | docg4_addr >>= 8; |
511 | writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); | 511 | writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); |
512 | docg4_addr >>= 8; | 512 | docg4_addr >>= 8; |
513 | writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); | 513 | writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); |
514 | } | 514 | } |
515 | 515 | ||
516 | static int read_progstatus(struct docg4_priv *doc) | 516 | static int read_progstatus(struct docg4_priv *doc) |
517 | { | 517 | { |
518 | /* | 518 | /* |
519 | * This apparently checks the status of programming. Done after an | 519 | * This apparently checks the status of programming. Done after an |
520 | * erasure, and after page data is written. On error, the status is | 520 | * erasure, and after page data is written. On error, the status is |
521 | * saved, to be later retrieved by the nand infrastructure code. | 521 | * saved, to be later retrieved by the nand infrastructure code. |
522 | */ | 522 | */ |
523 | void __iomem *docptr = doc->virtadr; | 523 | void __iomem *docptr = doc->virtadr; |
524 | 524 | ||
525 | /* status is read from the I/O reg */ | 525 | /* status is read from the I/O reg */ |
526 | uint16_t status1 = readw(docptr + DOC_IOSPACE_DATA); | 526 | uint16_t status1 = readw(docptr + DOC_IOSPACE_DATA); |
527 | uint16_t status2 = readw(docptr + DOC_IOSPACE_DATA); | 527 | uint16_t status2 = readw(docptr + DOC_IOSPACE_DATA); |
528 | uint16_t status3 = readw(docptr + DOCG4_MYSTERY_REG); | 528 | uint16_t status3 = readw(docptr + DOCG4_MYSTERY_REG); |
529 | 529 | ||
530 | dev_dbg(doc->dev, "docg4: %s: %02x %02x %02x\n", | 530 | dev_dbg(doc->dev, "docg4: %s: %02x %02x %02x\n", |
531 | __func__, status1, status2, status3); | 531 | __func__, status1, status2, status3); |
532 | 532 | ||
533 | if (status1 != DOCG4_PROGSTATUS_GOOD | 533 | if (status1 != DOCG4_PROGSTATUS_GOOD |
534 | || status2 != DOCG4_PROGSTATUS_GOOD_2 | 534 | || status2 != DOCG4_PROGSTATUS_GOOD_2 |
535 | || status3 != DOCG4_PROGSTATUS_GOOD_2) { | 535 | || status3 != DOCG4_PROGSTATUS_GOOD_2) { |
536 | doc->status = NAND_STATUS_FAIL; | 536 | doc->status = NAND_STATUS_FAIL; |
537 | dev_warn(doc->dev, "read_progstatus failed: " | 537 | dev_warn(doc->dev, "read_progstatus failed: " |
538 | "%02x, %02x, %02x\n", status1, status2, status3); | 538 | "%02x, %02x, %02x\n", status1, status2, status3); |
539 | return -EIO; | 539 | return -EIO; |
540 | } | 540 | } |
541 | return 0; | 541 | return 0; |
542 | } | 542 | } |
543 | 543 | ||
544 | static int pageprog(struct mtd_info *mtd) | 544 | static int pageprog(struct mtd_info *mtd) |
545 | { | 545 | { |
546 | /* | 546 | /* |
547 | * Final step in writing a page. Writes the contents of its | 547 | * Final step in writing a page. Writes the contents of its |
548 | * internal buffer out to the flash array, or some such. | 548 | * internal buffer out to the flash array, or some such. |
549 | */ | 549 | */ |
550 | 550 | ||
551 | struct nand_chip *nand = mtd->priv; | 551 | struct nand_chip *nand = mtd->priv; |
552 | struct docg4_priv *doc = nand->priv; | 552 | struct docg4_priv *doc = nand->priv; |
553 | void __iomem *docptr = doc->virtadr; | 553 | void __iomem *docptr = doc->virtadr; |
554 | int retval = 0; | 554 | int retval = 0; |
555 | 555 | ||
556 | dev_dbg(doc->dev, "docg4: %s\n", __func__); | 556 | dev_dbg(doc->dev, "docg4: %s\n", __func__); |
557 | 557 | ||
558 | writew(DOCG4_SEQ_PAGEPROG, docptr + DOC_FLASHSEQUENCE); | 558 | writew(DOCG4_SEQ_PAGEPROG, docptr + DOC_FLASHSEQUENCE); |
559 | writew(DOC_CMD_PROG_CYCLE2, docptr + DOC_FLASHCOMMAND); | 559 | writew(DOC_CMD_PROG_CYCLE2, docptr + DOC_FLASHCOMMAND); |
560 | write_nop(docptr); | 560 | write_nop(docptr); |
561 | write_nop(docptr); | 561 | write_nop(docptr); |
562 | 562 | ||
563 | /* Just busy-wait; usleep_range() slows things down noticeably. */ | 563 | /* Just busy-wait; usleep_range() slows things down noticeably. */ |
564 | poll_status(doc); | 564 | poll_status(doc); |
565 | 565 | ||
566 | writew(DOCG4_SEQ_FLUSH, docptr + DOC_FLASHSEQUENCE); | 566 | writew(DOCG4_SEQ_FLUSH, docptr + DOC_FLASHSEQUENCE); |
567 | writew(DOCG4_CMD_FLUSH, docptr + DOC_FLASHCOMMAND); | 567 | writew(DOCG4_CMD_FLUSH, docptr + DOC_FLASHCOMMAND); |
568 | writew(DOC_ECCCONF0_READ_MODE | 4, docptr + DOC_ECCCONF0); | 568 | writew(DOC_ECCCONF0_READ_MODE | 4, docptr + DOC_ECCCONF0); |
569 | write_nop(docptr); | 569 | write_nop(docptr); |
570 | write_nop(docptr); | 570 | write_nop(docptr); |
571 | write_nop(docptr); | 571 | write_nop(docptr); |
572 | write_nop(docptr); | 572 | write_nop(docptr); |
573 | write_nop(docptr); | 573 | write_nop(docptr); |
574 | 574 | ||
575 | retval = read_progstatus(doc); | 575 | retval = read_progstatus(doc); |
576 | writew(0, docptr + DOC_DATAEND); | 576 | writew(0, docptr + DOC_DATAEND); |
577 | write_nop(docptr); | 577 | write_nop(docptr); |
578 | poll_status(doc); | 578 | poll_status(doc); |
579 | write_nop(docptr); | 579 | write_nop(docptr); |
580 | 580 | ||
581 | return retval; | 581 | return retval; |
582 | } | 582 | } |
583 | 583 | ||
584 | static void sequence_reset(struct mtd_info *mtd) | 584 | static void sequence_reset(struct mtd_info *mtd) |
585 | { | 585 | { |
586 | /* common starting sequence for all operations */ | 586 | /* common starting sequence for all operations */ |
587 | 587 | ||
588 | struct nand_chip *nand = mtd->priv; | 588 | struct nand_chip *nand = mtd->priv; |
589 | struct docg4_priv *doc = nand->priv; | 589 | struct docg4_priv *doc = nand->priv; |
590 | void __iomem *docptr = doc->virtadr; | 590 | void __iomem *docptr = doc->virtadr; |
591 | 591 | ||
592 | writew(DOC_CTRL_UNKNOWN | DOC_CTRL_CE, docptr + DOC_FLASHCONTROL); | 592 | writew(DOC_CTRL_UNKNOWN | DOC_CTRL_CE, docptr + DOC_FLASHCONTROL); |
593 | writew(DOC_SEQ_RESET, docptr + DOC_FLASHSEQUENCE); | 593 | writew(DOC_SEQ_RESET, docptr + DOC_FLASHSEQUENCE); |
594 | writew(DOC_CMD_RESET, docptr + DOC_FLASHCOMMAND); | 594 | writew(DOC_CMD_RESET, docptr + DOC_FLASHCOMMAND); |
595 | write_nop(docptr); | 595 | write_nop(docptr); |
596 | write_nop(docptr); | 596 | write_nop(docptr); |
597 | poll_status(doc); | 597 | poll_status(doc); |
598 | write_nop(docptr); | 598 | write_nop(docptr); |
599 | } | 599 | } |
600 | 600 | ||
601 | static void read_page_prologue(struct mtd_info *mtd, uint32_t docg4_addr) | 601 | static void read_page_prologue(struct mtd_info *mtd, uint32_t docg4_addr) |
602 | { | 602 | { |
603 | /* first step in reading a page */ | 603 | /* first step in reading a page */ |
604 | 604 | ||
605 | struct nand_chip *nand = mtd->priv; | 605 | struct nand_chip *nand = mtd->priv; |
606 | struct docg4_priv *doc = nand->priv; | 606 | struct docg4_priv *doc = nand->priv; |
607 | void __iomem *docptr = doc->virtadr; | 607 | void __iomem *docptr = doc->virtadr; |
608 | 608 | ||
609 | dev_dbg(doc->dev, | 609 | dev_dbg(doc->dev, |
610 | "docg4: %s: g4 page %08x\n", __func__, docg4_addr); | 610 | "docg4: %s: g4 page %08x\n", __func__, docg4_addr); |
611 | 611 | ||
612 | sequence_reset(mtd); | 612 | sequence_reset(mtd); |
613 | 613 | ||
614 | writew(DOCG4_SEQ_PAGE_READ, docptr + DOC_FLASHSEQUENCE); | 614 | writew(DOCG4_SEQ_PAGE_READ, docptr + DOC_FLASHSEQUENCE); |
615 | writew(DOCG4_CMD_PAGE_READ, docptr + DOC_FLASHCOMMAND); | 615 | writew(DOCG4_CMD_PAGE_READ, docptr + DOC_FLASHCOMMAND); |
616 | write_nop(docptr); | 616 | write_nop(docptr); |
617 | 617 | ||
618 | write_addr(doc, docg4_addr); | 618 | write_addr(doc, docg4_addr); |
619 | 619 | ||
620 | write_nop(docptr); | 620 | write_nop(docptr); |
621 | writew(DOCG4_CMD_READ2, docptr + DOC_FLASHCOMMAND); | 621 | writew(DOCG4_CMD_READ2, docptr + DOC_FLASHCOMMAND); |
622 | write_nop(docptr); | 622 | write_nop(docptr); |
623 | write_nop(docptr); | 623 | write_nop(docptr); |
624 | 624 | ||
625 | poll_status(doc); | 625 | poll_status(doc); |
626 | } | 626 | } |
627 | 627 | ||
628 | static void write_page_prologue(struct mtd_info *mtd, uint32_t docg4_addr) | 628 | static void write_page_prologue(struct mtd_info *mtd, uint32_t docg4_addr) |
629 | { | 629 | { |
630 | /* first step in writing a page */ | 630 | /* first step in writing a page */ |
631 | 631 | ||
632 | struct nand_chip *nand = mtd->priv; | 632 | struct nand_chip *nand = mtd->priv; |
633 | struct docg4_priv *doc = nand->priv; | 633 | struct docg4_priv *doc = nand->priv; |
634 | void __iomem *docptr = doc->virtadr; | 634 | void __iomem *docptr = doc->virtadr; |
635 | 635 | ||
636 | dev_dbg(doc->dev, | 636 | dev_dbg(doc->dev, |
637 | "docg4: %s: g4 addr: %x\n", __func__, docg4_addr); | 637 | "docg4: %s: g4 addr: %x\n", __func__, docg4_addr); |
638 | sequence_reset(mtd); | 638 | sequence_reset(mtd); |
639 | 639 | ||
640 | if (unlikely(reliable_mode)) { | 640 | if (unlikely(reliable_mode)) { |
641 | writew(DOCG4_SEQ_SETMODE, docptr + DOC_FLASHSEQUENCE); | 641 | writew(DOCG4_SEQ_SETMODE, docptr + DOC_FLASHSEQUENCE); |
642 | writew(DOCG4_CMD_FAST_MODE, docptr + DOC_FLASHCOMMAND); | 642 | writew(DOCG4_CMD_FAST_MODE, docptr + DOC_FLASHCOMMAND); |
643 | writew(DOC_CMD_RELIABLE_MODE, docptr + DOC_FLASHCOMMAND); | 643 | writew(DOC_CMD_RELIABLE_MODE, docptr + DOC_FLASHCOMMAND); |
644 | write_nop(docptr); | 644 | write_nop(docptr); |
645 | } | 645 | } |
646 | 646 | ||
647 | writew(DOCG4_SEQ_PAGEWRITE, docptr + DOC_FLASHSEQUENCE); | 647 | writew(DOCG4_SEQ_PAGEWRITE, docptr + DOC_FLASHSEQUENCE); |
648 | writew(DOCG4_CMD_PAGEWRITE, docptr + DOC_FLASHCOMMAND); | 648 | writew(DOCG4_CMD_PAGEWRITE, docptr + DOC_FLASHCOMMAND); |
649 | write_nop(docptr); | 649 | write_nop(docptr); |
650 | write_addr(doc, docg4_addr); | 650 | write_addr(doc, docg4_addr); |
651 | write_nop(docptr); | 651 | write_nop(docptr); |
652 | write_nop(docptr); | 652 | write_nop(docptr); |
653 | poll_status(doc); | 653 | poll_status(doc); |
654 | } | 654 | } |
655 | 655 | ||
656 | static uint32_t mtd_to_docg4_address(int page, int column) | 656 | static uint32_t mtd_to_docg4_address(int page, int column) |
657 | { | 657 | { |
658 | /* | 658 | /* |
659 | * Convert mtd address to format used by the device, 32 bit packed. | 659 | * Convert mtd address to format used by the device, 32 bit packed. |
660 | * | 660 | * |
661 | * Some notes on G4 addressing... The M-Sys documentation on this device | 661 | * Some notes on G4 addressing... The M-Sys documentation on this device |
662 | * claims that pages are 2K in length, and indeed, the format of the | 662 | * claims that pages are 2K in length, and indeed, the format of the |
663 | * address used by the device reflects that. But within each page are | 663 | * address used by the device reflects that. But within each page are |
664 | * four 512 byte "sub-pages", each with its own oob data that is | 664 | * four 512 byte "sub-pages", each with its own oob data that is |
665 | * read/written immediately after the 512 bytes of page data. This oob | 665 | * read/written immediately after the 512 bytes of page data. This oob |
666 | * data contains the ecc bytes for the preceeding 512 bytes. | 666 | * data contains the ecc bytes for the preceeding 512 bytes. |
667 | * | 667 | * |
668 | * Rather than tell the mtd nand infrastructure that page size is 2k, | 668 | * Rather than tell the mtd nand infrastructure that page size is 2k, |
669 | * with four sub-pages each, we engage in a little subterfuge and tell | 669 | * with four sub-pages each, we engage in a little subterfuge and tell |
670 | * the infrastructure code that pages are 512 bytes in size. This is | 670 | * the infrastructure code that pages are 512 bytes in size. This is |
671 | * done because during the course of reverse-engineering the device, I | 671 | * done because during the course of reverse-engineering the device, I |
672 | * never observed an instance where an entire 2K "page" was read or | 672 | * never observed an instance where an entire 2K "page" was read or |
673 | * written as a unit. Each "sub-page" is always addressed individually, | 673 | * written as a unit. Each "sub-page" is always addressed individually, |
674 | * its data read/written, and ecc handled before the next "sub-page" is | 674 | * its data read/written, and ecc handled before the next "sub-page" is |
675 | * addressed. | 675 | * addressed. |
676 | * | 676 | * |
677 | * This requires us to convert addresses passed by the mtd nand | 677 | * This requires us to convert addresses passed by the mtd nand |
678 | * infrastructure code to those used by the device. | 678 | * infrastructure code to those used by the device. |
679 | * | 679 | * |
680 | * The address that is written to the device consists of four bytes: the | 680 | * The address that is written to the device consists of four bytes: the |
681 | * first two are the 2k page number, and the second is the index into | 681 | * first two are the 2k page number, and the second is the index into |
682 | * the page. The index is in terms of 16-bit half-words and includes | 682 | * the page. The index is in terms of 16-bit half-words and includes |
683 | * the preceeding oob data, so e.g., the index into the second | 683 | * the preceeding oob data, so e.g., the index into the second |
684 | * "sub-page" is 0x108, and the full device address of the start of mtd | 684 | * "sub-page" is 0x108, and the full device address of the start of mtd |
685 | * page 0x201 is 0x00800108. | 685 | * page 0x201 is 0x00800108. |
686 | */ | 686 | */ |
687 | int g4_page = page / 4; /* device's 2K page */ | 687 | int g4_page = page / 4; /* device's 2K page */ |
688 | int g4_index = (page % 4) * 0x108 + column/2; /* offset into page */ | 688 | int g4_index = (page % 4) * 0x108 + column/2; /* offset into page */ |
689 | return (g4_page << 16) | g4_index; /* pack */ | 689 | return (g4_page << 16) | g4_index; /* pack */ |
690 | } | 690 | } |
691 | 691 | ||
692 | static void docg4_command(struct mtd_info *mtd, unsigned command, int column, | 692 | static void docg4_command(struct mtd_info *mtd, unsigned command, int column, |
693 | int page_addr) | 693 | int page_addr) |
694 | { | 694 | { |
695 | /* handle standard nand commands */ | 695 | /* handle standard nand commands */ |
696 | 696 | ||
697 | struct nand_chip *nand = mtd->priv; | 697 | struct nand_chip *nand = mtd->priv; |
698 | struct docg4_priv *doc = nand->priv; | 698 | struct docg4_priv *doc = nand->priv; |
699 | uint32_t g4_addr = mtd_to_docg4_address(page_addr, column); | 699 | uint32_t g4_addr = mtd_to_docg4_address(page_addr, column); |
700 | 700 | ||
701 | dev_dbg(doc->dev, "%s %x, page_addr=%x, column=%x\n", | 701 | dev_dbg(doc->dev, "%s %x, page_addr=%x, column=%x\n", |
702 | __func__, command, page_addr, column); | 702 | __func__, command, page_addr, column); |
703 | 703 | ||
704 | /* | 704 | /* |
705 | * Save the command and its arguments. This enables emulation of | 705 | * Save the command and its arguments. This enables emulation of |
706 | * standard flash devices, and also some optimizations. | 706 | * standard flash devices, and also some optimizations. |
707 | */ | 707 | */ |
708 | doc->last_command.command = command; | 708 | doc->last_command.command = command; |
709 | doc->last_command.column = column; | 709 | doc->last_command.column = column; |
710 | doc->last_command.page = page_addr; | 710 | doc->last_command.page = page_addr; |
711 | 711 | ||
712 | switch (command) { | 712 | switch (command) { |
713 | 713 | ||
714 | case NAND_CMD_RESET: | 714 | case NAND_CMD_RESET: |
715 | reset(mtd); | 715 | reset(mtd); |
716 | break; | 716 | break; |
717 | 717 | ||
718 | case NAND_CMD_READ0: | 718 | case NAND_CMD_READ0: |
719 | read_page_prologue(mtd, g4_addr); | 719 | read_page_prologue(mtd, g4_addr); |
720 | break; | 720 | break; |
721 | 721 | ||
722 | case NAND_CMD_STATUS: | 722 | case NAND_CMD_STATUS: |
723 | /* next call to read_byte() will expect a status */ | 723 | /* next call to read_byte() will expect a status */ |
724 | break; | 724 | break; |
725 | 725 | ||
726 | case NAND_CMD_SEQIN: | 726 | case NAND_CMD_SEQIN: |
727 | if (unlikely(reliable_mode)) { | 727 | if (unlikely(reliable_mode)) { |
728 | uint16_t g4_page = g4_addr >> 16; | 728 | uint16_t g4_page = g4_addr >> 16; |
729 | 729 | ||
730 | /* writes to odd-numbered 2k pages are invalid */ | 730 | /* writes to odd-numbered 2k pages are invalid */ |
731 | if (g4_page & 0x01) | 731 | if (g4_page & 0x01) |
732 | dev_warn(doc->dev, | 732 | dev_warn(doc->dev, |
733 | "invalid reliable mode address\n"); | 733 | "invalid reliable mode address\n"); |
734 | } | 734 | } |
735 | 735 | ||
736 | write_page_prologue(mtd, g4_addr); | 736 | write_page_prologue(mtd, g4_addr); |
737 | 737 | ||
738 | /* hack for deferred write of oob bytes */ | 738 | /* hack for deferred write of oob bytes */ |
739 | if (doc->oob_page == page_addr) | 739 | if (doc->oob_page == page_addr) |
740 | memcpy(nand->oob_poi, doc->oob_buf, 16); | 740 | memcpy(nand->oob_poi, doc->oob_buf, 16); |
741 | break; | 741 | break; |
742 | 742 | ||
743 | case NAND_CMD_PAGEPROG: | 743 | case NAND_CMD_PAGEPROG: |
744 | pageprog(mtd); | 744 | pageprog(mtd); |
745 | break; | 745 | break; |
746 | 746 | ||
747 | /* we don't expect these, based on review of nand_base.c */ | 747 | /* we don't expect these, based on review of nand_base.c */ |
748 | case NAND_CMD_READOOB: | 748 | case NAND_CMD_READOOB: |
749 | case NAND_CMD_READID: | 749 | case NAND_CMD_READID: |
750 | case NAND_CMD_ERASE1: | 750 | case NAND_CMD_ERASE1: |
751 | case NAND_CMD_ERASE2: | 751 | case NAND_CMD_ERASE2: |
752 | dev_warn(doc->dev, "docg4_command: " | 752 | dev_warn(doc->dev, "docg4_command: " |
753 | "unexpected nand command 0x%x\n", command); | 753 | "unexpected nand command 0x%x\n", command); |
754 | break; | 754 | break; |
755 | 755 | ||
756 | } | 756 | } |
757 | } | 757 | } |
758 | 758 | ||
759 | static int read_page(struct mtd_info *mtd, struct nand_chip *nand, | 759 | static int read_page(struct mtd_info *mtd, struct nand_chip *nand, |
760 | uint8_t *buf, int page, bool use_ecc) | 760 | uint8_t *buf, int page, bool use_ecc) |
761 | { | 761 | { |
762 | struct docg4_priv *doc = nand->priv; | 762 | struct docg4_priv *doc = nand->priv; |
763 | void __iomem *docptr = doc->virtadr; | 763 | void __iomem *docptr = doc->virtadr; |
764 | uint16_t status, edc_err, *buf16; | 764 | uint16_t status, edc_err, *buf16; |
765 | int bits_corrected = 0; | 765 | int bits_corrected = 0; |
766 | 766 | ||
767 | dev_dbg(doc->dev, "%s: page %08x\n", __func__, page); | 767 | dev_dbg(doc->dev, "%s: page %08x\n", __func__, page); |
768 | 768 | ||
769 | writew(DOC_ECCCONF0_READ_MODE | | 769 | writew(DOC_ECCCONF0_READ_MODE | |
770 | DOC_ECCCONF0_ECC_ENABLE | | 770 | DOC_ECCCONF0_ECC_ENABLE | |
771 | DOC_ECCCONF0_UNKNOWN | | 771 | DOC_ECCCONF0_UNKNOWN | |
772 | DOCG4_BCH_SIZE, | 772 | DOCG4_BCH_SIZE, |
773 | docptr + DOC_ECCCONF0); | 773 | docptr + DOC_ECCCONF0); |
774 | write_nop(docptr); | 774 | write_nop(docptr); |
775 | write_nop(docptr); | 775 | write_nop(docptr); |
776 | write_nop(docptr); | 776 | write_nop(docptr); |
777 | write_nop(docptr); | 777 | write_nop(docptr); |
778 | write_nop(docptr); | 778 | write_nop(docptr); |
779 | 779 | ||
780 | /* the 1st byte from the I/O reg is a status; the rest is page data */ | 780 | /* the 1st byte from the I/O reg is a status; the rest is page data */ |
781 | status = readw(docptr + DOC_IOSPACE_DATA); | 781 | status = readw(docptr + DOC_IOSPACE_DATA); |
782 | if (status & DOCG4_READ_ERROR) { | 782 | if (status & DOCG4_READ_ERROR) { |
783 | dev_err(doc->dev, | 783 | dev_err(doc->dev, |
784 | "docg4_read_page: bad status: 0x%02x\n", status); | 784 | "docg4_read_page: bad status: 0x%02x\n", status); |
785 | writew(0, docptr + DOC_DATAEND); | 785 | writew(0, docptr + DOC_DATAEND); |
786 | return -EIO; | 786 | return -EIO; |
787 | } | 787 | } |
788 | 788 | ||
789 | dev_dbg(doc->dev, "%s: status = 0x%x\n", __func__, status); | 789 | dev_dbg(doc->dev, "%s: status = 0x%x\n", __func__, status); |
790 | 790 | ||
791 | docg4_read_buf(mtd, buf, DOCG4_PAGE_SIZE); /* read the page data */ | 791 | docg4_read_buf(mtd, buf, DOCG4_PAGE_SIZE); /* read the page data */ |
792 | 792 | ||
793 | /* this device always reads oob after page data */ | 793 | /* this device always reads oob after page data */ |
794 | /* first 14 oob bytes read from I/O reg */ | 794 | /* first 14 oob bytes read from I/O reg */ |
795 | docg4_read_buf(mtd, nand->oob_poi, 14); | 795 | docg4_read_buf(mtd, nand->oob_poi, 14); |
796 | 796 | ||
797 | /* last 2 read from another reg */ | 797 | /* last 2 read from another reg */ |
798 | buf16 = (uint16_t *)(nand->oob_poi + 14); | 798 | buf16 = (uint16_t *)(nand->oob_poi + 14); |
799 | *buf16 = readw(docptr + DOCG4_MYSTERY_REG); | 799 | *buf16 = readw(docptr + DOCG4_MYSTERY_REG); |
800 | 800 | ||
801 | write_nop(docptr); | 801 | write_nop(docptr); |
802 | 802 | ||
803 | if (likely(use_ecc == true)) { | 803 | if (likely(use_ecc == true)) { |
804 | 804 | ||
805 | /* read the register that tells us if bitflip(s) detected */ | 805 | /* read the register that tells us if bitflip(s) detected */ |
806 | edc_err = readw(docptr + DOC_ECCCONF1); | 806 | edc_err = readw(docptr + DOC_ECCCONF1); |
807 | edc_err = readw(docptr + DOC_ECCCONF1); | 807 | edc_err = readw(docptr + DOC_ECCCONF1); |
808 | dev_dbg(doc->dev, "%s: edc_err = 0x%02x\n", __func__, edc_err); | 808 | dev_dbg(doc->dev, "%s: edc_err = 0x%02x\n", __func__, edc_err); |
809 | 809 | ||
810 | /* If bitflips are reported, attempt to correct with ecc */ | 810 | /* If bitflips are reported, attempt to correct with ecc */ |
811 | if (edc_err & DOC_ECCCONF1_BCH_SYNDROM_ERR) { | 811 | if (edc_err & DOC_ECCCONF1_BCH_SYNDROM_ERR) { |
812 | bits_corrected = correct_data(mtd, buf, page); | 812 | bits_corrected = correct_data(mtd, buf, page); |
813 | if (bits_corrected == -EBADMSG) | 813 | if (bits_corrected == -EBADMSG) |
814 | mtd->ecc_stats.failed++; | 814 | mtd->ecc_stats.failed++; |
815 | else | 815 | else |
816 | mtd->ecc_stats.corrected += bits_corrected; | 816 | mtd->ecc_stats.corrected += bits_corrected; |
817 | } | 817 | } |
818 | } | 818 | } |
819 | 819 | ||
820 | writew(0, docptr + DOC_DATAEND); | 820 | writew(0, docptr + DOC_DATAEND); |
821 | if (bits_corrected == -EBADMSG) /* uncorrectable errors */ | 821 | if (bits_corrected == -EBADMSG) /* uncorrectable errors */ |
822 | return 0; | 822 | return 0; |
823 | return bits_corrected; | 823 | return bits_corrected; |
824 | } | 824 | } |
825 | 825 | ||
826 | 826 | ||
827 | static int docg4_read_page_raw(struct mtd_info *mtd, struct nand_chip *nand, | 827 | static int docg4_read_page_raw(struct mtd_info *mtd, struct nand_chip *nand, |
828 | uint8_t *buf, int oob_required, int page) | 828 | uint8_t *buf, int oob_required, int page) |
829 | { | 829 | { |
830 | return read_page(mtd, nand, buf, page, false); | 830 | return read_page(mtd, nand, buf, page, false); |
831 | } | 831 | } |
832 | 832 | ||
833 | static int docg4_read_page(struct mtd_info *mtd, struct nand_chip *nand, | 833 | static int docg4_read_page(struct mtd_info *mtd, struct nand_chip *nand, |
834 | uint8_t *buf, int oob_required, int page) | 834 | uint8_t *buf, int oob_required, int page) |
835 | { | 835 | { |
836 | return read_page(mtd, nand, buf, page, true); | 836 | return read_page(mtd, nand, buf, page, true); |
837 | } | 837 | } |
838 | 838 | ||
839 | static int docg4_read_oob(struct mtd_info *mtd, struct nand_chip *nand, | 839 | static int docg4_read_oob(struct mtd_info *mtd, struct nand_chip *nand, |
840 | int page) | 840 | int page) |
841 | { | 841 | { |
842 | struct docg4_priv *doc = nand->priv; | 842 | struct docg4_priv *doc = nand->priv; |
843 | void __iomem *docptr = doc->virtadr; | 843 | void __iomem *docptr = doc->virtadr; |
844 | uint16_t status; | 844 | uint16_t status; |
845 | 845 | ||
846 | dev_dbg(doc->dev, "%s: page %x\n", __func__, page); | 846 | dev_dbg(doc->dev, "%s: page %x\n", __func__, page); |
847 | 847 | ||
848 | docg4_command(mtd, NAND_CMD_READ0, nand->ecc.size, page); | 848 | docg4_command(mtd, NAND_CMD_READ0, nand->ecc.size, page); |
849 | 849 | ||
850 | writew(DOC_ECCCONF0_READ_MODE | DOCG4_OOB_SIZE, docptr + DOC_ECCCONF0); | 850 | writew(DOC_ECCCONF0_READ_MODE | DOCG4_OOB_SIZE, docptr + DOC_ECCCONF0); |
851 | write_nop(docptr); | 851 | write_nop(docptr); |
852 | write_nop(docptr); | 852 | write_nop(docptr); |
853 | write_nop(docptr); | 853 | write_nop(docptr); |
854 | write_nop(docptr); | 854 | write_nop(docptr); |
855 | write_nop(docptr); | 855 | write_nop(docptr); |
856 | 856 | ||
857 | /* the 1st byte from the I/O reg is a status; the rest is oob data */ | 857 | /* the 1st byte from the I/O reg is a status; the rest is oob data */ |
858 | status = readw(docptr + DOC_IOSPACE_DATA); | 858 | status = readw(docptr + DOC_IOSPACE_DATA); |
859 | if (status & DOCG4_READ_ERROR) { | 859 | if (status & DOCG4_READ_ERROR) { |
860 | dev_warn(doc->dev, | 860 | dev_warn(doc->dev, |
861 | "docg4_read_oob failed: status = 0x%02x\n", status); | 861 | "docg4_read_oob failed: status = 0x%02x\n", status); |
862 | return -EIO; | 862 | return -EIO; |
863 | } | 863 | } |
864 | 864 | ||
865 | dev_dbg(doc->dev, "%s: status = 0x%x\n", __func__, status); | 865 | dev_dbg(doc->dev, "%s: status = 0x%x\n", __func__, status); |
866 | 866 | ||
867 | docg4_read_buf(mtd, nand->oob_poi, 16); | 867 | docg4_read_buf(mtd, nand->oob_poi, 16); |
868 | 868 | ||
869 | write_nop(docptr); | 869 | write_nop(docptr); |
870 | write_nop(docptr); | 870 | write_nop(docptr); |
871 | write_nop(docptr); | 871 | write_nop(docptr); |
872 | writew(0, docptr + DOC_DATAEND); | 872 | writew(0, docptr + DOC_DATAEND); |
873 | write_nop(docptr); | 873 | write_nop(docptr); |
874 | 874 | ||
875 | return 0; | 875 | return 0; |
876 | } | 876 | } |
877 | 877 | ||
878 | static void docg4_erase_block(struct mtd_info *mtd, int page) | 878 | static void docg4_erase_block(struct mtd_info *mtd, int page) |
879 | { | 879 | { |
880 | struct nand_chip *nand = mtd->priv; | 880 | struct nand_chip *nand = mtd->priv; |
881 | struct docg4_priv *doc = nand->priv; | 881 | struct docg4_priv *doc = nand->priv; |
882 | void __iomem *docptr = doc->virtadr; | 882 | void __iomem *docptr = doc->virtadr; |
883 | uint16_t g4_page; | 883 | uint16_t g4_page; |
884 | 884 | ||
885 | dev_dbg(doc->dev, "%s: page %04x\n", __func__, page); | 885 | dev_dbg(doc->dev, "%s: page %04x\n", __func__, page); |
886 | 886 | ||
887 | sequence_reset(mtd); | 887 | sequence_reset(mtd); |
888 | 888 | ||
889 | writew(DOCG4_SEQ_BLOCKERASE, docptr + DOC_FLASHSEQUENCE); | 889 | writew(DOCG4_SEQ_BLOCKERASE, docptr + DOC_FLASHSEQUENCE); |
890 | writew(DOC_CMD_PROG_BLOCK_ADDR, docptr + DOC_FLASHCOMMAND); | 890 | writew(DOC_CMD_PROG_BLOCK_ADDR, docptr + DOC_FLASHCOMMAND); |
891 | write_nop(docptr); | 891 | write_nop(docptr); |
892 | 892 | ||
893 | /* only 2 bytes of address are written to specify erase block */ | 893 | /* only 2 bytes of address are written to specify erase block */ |
894 | g4_page = (uint16_t)(page / 4); /* to g4's 2k page addressing */ | 894 | g4_page = (uint16_t)(page / 4); /* to g4's 2k page addressing */ |
895 | writeb(g4_page & 0xff, docptr + DOC_FLASHADDRESS); | 895 | writeb(g4_page & 0xff, docptr + DOC_FLASHADDRESS); |
896 | g4_page >>= 8; | 896 | g4_page >>= 8; |
897 | writeb(g4_page & 0xff, docptr + DOC_FLASHADDRESS); | 897 | writeb(g4_page & 0xff, docptr + DOC_FLASHADDRESS); |
898 | write_nop(docptr); | 898 | write_nop(docptr); |
899 | 899 | ||
900 | /* start the erasure */ | 900 | /* start the erasure */ |
901 | writew(DOC_CMD_ERASECYCLE2, docptr + DOC_FLASHCOMMAND); | 901 | writew(DOC_CMD_ERASECYCLE2, docptr + DOC_FLASHCOMMAND); |
902 | write_nop(docptr); | 902 | write_nop(docptr); |
903 | write_nop(docptr); | 903 | write_nop(docptr); |
904 | 904 | ||
905 | usleep_range(500, 1000); /* erasure is long; take a snooze */ | 905 | usleep_range(500, 1000); /* erasure is long; take a snooze */ |
906 | poll_status(doc); | 906 | poll_status(doc); |
907 | writew(DOCG4_SEQ_FLUSH, docptr + DOC_FLASHSEQUENCE); | 907 | writew(DOCG4_SEQ_FLUSH, docptr + DOC_FLASHSEQUENCE); |
908 | writew(DOCG4_CMD_FLUSH, docptr + DOC_FLASHCOMMAND); | 908 | writew(DOCG4_CMD_FLUSH, docptr + DOC_FLASHCOMMAND); |
909 | writew(DOC_ECCCONF0_READ_MODE | 4, docptr + DOC_ECCCONF0); | 909 | writew(DOC_ECCCONF0_READ_MODE | 4, docptr + DOC_ECCCONF0); |
910 | write_nop(docptr); | 910 | write_nop(docptr); |
911 | write_nop(docptr); | 911 | write_nop(docptr); |
912 | write_nop(docptr); | 912 | write_nop(docptr); |
913 | write_nop(docptr); | 913 | write_nop(docptr); |
914 | write_nop(docptr); | 914 | write_nop(docptr); |
915 | 915 | ||
916 | read_progstatus(doc); | 916 | read_progstatus(doc); |
917 | 917 | ||
918 | writew(0, docptr + DOC_DATAEND); | 918 | writew(0, docptr + DOC_DATAEND); |
919 | write_nop(docptr); | 919 | write_nop(docptr); |
920 | poll_status(doc); | 920 | poll_status(doc); |
921 | write_nop(docptr); | 921 | write_nop(docptr); |
922 | } | 922 | } |
923 | 923 | ||
924 | static int write_page(struct mtd_info *mtd, struct nand_chip *nand, | 924 | static int write_page(struct mtd_info *mtd, struct nand_chip *nand, |
925 | const uint8_t *buf, bool use_ecc) | 925 | const uint8_t *buf, bool use_ecc) |
926 | { | 926 | { |
927 | struct docg4_priv *doc = nand->priv; | 927 | struct docg4_priv *doc = nand->priv; |
928 | void __iomem *docptr = doc->virtadr; | 928 | void __iomem *docptr = doc->virtadr; |
929 | uint8_t ecc_buf[8]; | 929 | uint8_t ecc_buf[8]; |
930 | 930 | ||
931 | dev_dbg(doc->dev, "%s...\n", __func__); | 931 | dev_dbg(doc->dev, "%s...\n", __func__); |
932 | 932 | ||
933 | writew(DOC_ECCCONF0_ECC_ENABLE | | 933 | writew(DOC_ECCCONF0_ECC_ENABLE | |
934 | DOC_ECCCONF0_UNKNOWN | | 934 | DOC_ECCCONF0_UNKNOWN | |
935 | DOCG4_BCH_SIZE, | 935 | DOCG4_BCH_SIZE, |
936 | docptr + DOC_ECCCONF0); | 936 | docptr + DOC_ECCCONF0); |
937 | write_nop(docptr); | 937 | write_nop(docptr); |
938 | 938 | ||
939 | /* write the page data */ | 939 | /* write the page data */ |
940 | docg4_write_buf16(mtd, buf, DOCG4_PAGE_SIZE); | 940 | docg4_write_buf16(mtd, buf, DOCG4_PAGE_SIZE); |
941 | 941 | ||
942 | /* oob bytes 0 through 5 are written to I/O reg */ | 942 | /* oob bytes 0 through 5 are written to I/O reg */ |
943 | docg4_write_buf16(mtd, nand->oob_poi, 6); | 943 | docg4_write_buf16(mtd, nand->oob_poi, 6); |
944 | 944 | ||
945 | /* oob byte 6 written to a separate reg */ | 945 | /* oob byte 6 written to a separate reg */ |
946 | writew(nand->oob_poi[6], docptr + DOCG4_OOB_6_7); | 946 | writew(nand->oob_poi[6], docptr + DOCG4_OOB_6_7); |
947 | 947 | ||
948 | write_nop(docptr); | 948 | write_nop(docptr); |
949 | write_nop(docptr); | 949 | write_nop(docptr); |
950 | 950 | ||
951 | /* write hw-generated ecc bytes to oob */ | 951 | /* write hw-generated ecc bytes to oob */ |
952 | if (likely(use_ecc == true)) { | 952 | if (likely(use_ecc == true)) { |
953 | /* oob byte 7 is hamming code */ | 953 | /* oob byte 7 is hamming code */ |
954 | uint8_t hamming = readb(docptr + DOC_HAMMINGPARITY); | 954 | uint8_t hamming = readb(docptr + DOC_HAMMINGPARITY); |
955 | hamming = readb(docptr + DOC_HAMMINGPARITY); /* 2nd read */ | 955 | hamming = readb(docptr + DOC_HAMMINGPARITY); /* 2nd read */ |
956 | writew(hamming, docptr + DOCG4_OOB_6_7); | 956 | writew(hamming, docptr + DOCG4_OOB_6_7); |
957 | write_nop(docptr); | 957 | write_nop(docptr); |
958 | 958 | ||
959 | /* read the 7 bch bytes from ecc regs */ | 959 | /* read the 7 bch bytes from ecc regs */ |
960 | read_hw_ecc(docptr, ecc_buf); | 960 | read_hw_ecc(docptr, ecc_buf); |
961 | ecc_buf[7] = 0; /* clear the "page written" flag */ | 961 | ecc_buf[7] = 0; /* clear the "page written" flag */ |
962 | } | 962 | } |
963 | 963 | ||
964 | /* write user-supplied bytes to oob */ | 964 | /* write user-supplied bytes to oob */ |
965 | else { | 965 | else { |
966 | writew(nand->oob_poi[7], docptr + DOCG4_OOB_6_7); | 966 | writew(nand->oob_poi[7], docptr + DOCG4_OOB_6_7); |
967 | write_nop(docptr); | 967 | write_nop(docptr); |
968 | memcpy(ecc_buf, &nand->oob_poi[8], 8); | 968 | memcpy(ecc_buf, &nand->oob_poi[8], 8); |
969 | } | 969 | } |
970 | 970 | ||
971 | docg4_write_buf16(mtd, ecc_buf, 8); | 971 | docg4_write_buf16(mtd, ecc_buf, 8); |
972 | write_nop(docptr); | 972 | write_nop(docptr); |
973 | write_nop(docptr); | 973 | write_nop(docptr); |
974 | writew(0, docptr + DOC_DATAEND); | 974 | writew(0, docptr + DOC_DATAEND); |
975 | write_nop(docptr); | 975 | write_nop(docptr); |
976 | 976 | ||
977 | return 0; | 977 | return 0; |
978 | } | 978 | } |
979 | 979 | ||
980 | static int docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand, | 980 | static int docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand, |
981 | const uint8_t *buf, int oob_required) | 981 | const uint8_t *buf, int oob_required) |
982 | { | 982 | { |
983 | return write_page(mtd, nand, buf, false); | 983 | return write_page(mtd, nand, buf, false); |
984 | } | 984 | } |
985 | 985 | ||
986 | static int docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand, | 986 | static int docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand, |
987 | const uint8_t *buf, int oob_required) | 987 | const uint8_t *buf, int oob_required) |
988 | { | 988 | { |
989 | return write_page(mtd, nand, buf, true); | 989 | return write_page(mtd, nand, buf, true); |
990 | } | 990 | } |
991 | 991 | ||
992 | static int docg4_write_oob(struct mtd_info *mtd, struct nand_chip *nand, | 992 | static int docg4_write_oob(struct mtd_info *mtd, struct nand_chip *nand, |
993 | int page) | 993 | int page) |
994 | { | 994 | { |
995 | /* | 995 | /* |
996 | * Writing oob-only is not really supported, because MLC nand must write | 996 | * Writing oob-only is not really supported, because MLC nand must write |
997 | * oob bytes at the same time as page data. Nonetheless, we save the | 997 | * oob bytes at the same time as page data. Nonetheless, we save the |
998 | * oob buffer contents here, and then write it along with the page data | 998 | * oob buffer contents here, and then write it along with the page data |
999 | * if the same page is subsequently written. This allows user space | 999 | * if the same page is subsequently written. This allows user space |
1000 | * utilities that write the oob data prior to the page data to work | 1000 | * utilities that write the oob data prior to the page data to work |
1001 | * (e.g., nandwrite). The disdvantage is that, if the intention was to | 1001 | * (e.g., nandwrite). The disdvantage is that, if the intention was to |
1002 | * write oob only, the operation is quietly ignored. Also, oob can get | 1002 | * write oob only, the operation is quietly ignored. Also, oob can get |
1003 | * corrupted if two concurrent processes are running nandwrite. | 1003 | * corrupted if two concurrent processes are running nandwrite. |
1004 | */ | 1004 | */ |
1005 | 1005 | ||
1006 | /* note that bytes 7..14 are hw generated hamming/ecc and overwritten */ | 1006 | /* note that bytes 7..14 are hw generated hamming/ecc and overwritten */ |
1007 | struct docg4_priv *doc = nand->priv; | 1007 | struct docg4_priv *doc = nand->priv; |
1008 | doc->oob_page = page; | 1008 | doc->oob_page = page; |
1009 | memcpy(doc->oob_buf, nand->oob_poi, 16); | 1009 | memcpy(doc->oob_buf, nand->oob_poi, 16); |
1010 | return 0; | 1010 | return 0; |
1011 | } | 1011 | } |
1012 | 1012 | ||
1013 | static int __init read_factory_bbt(struct mtd_info *mtd) | 1013 | static int __init read_factory_bbt(struct mtd_info *mtd) |
1014 | { | 1014 | { |
1015 | /* | 1015 | /* |
1016 | * The device contains a read-only factory bad block table. Read it and | 1016 | * The device contains a read-only factory bad block table. Read it and |
1017 | * update the memory-based bbt accordingly. | 1017 | * update the memory-based bbt accordingly. |
1018 | */ | 1018 | */ |
1019 | 1019 | ||
1020 | struct nand_chip *nand = mtd->priv; | 1020 | struct nand_chip *nand = mtd->priv; |
1021 | struct docg4_priv *doc = nand->priv; | 1021 | struct docg4_priv *doc = nand->priv; |
1022 | uint32_t g4_addr = mtd_to_docg4_address(DOCG4_FACTORY_BBT_PAGE, 0); | 1022 | uint32_t g4_addr = mtd_to_docg4_address(DOCG4_FACTORY_BBT_PAGE, 0); |
1023 | uint8_t *buf; | 1023 | uint8_t *buf; |
1024 | int i, block; | 1024 | int i, block; |
1025 | __u32 eccfailed_stats = mtd->ecc_stats.failed; | 1025 | __u32 eccfailed_stats = mtd->ecc_stats.failed; |
1026 | 1026 | ||
1027 | buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL); | 1027 | buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL); |
1028 | if (buf == NULL) | 1028 | if (buf == NULL) |
1029 | return -ENOMEM; | 1029 | return -ENOMEM; |
1030 | 1030 | ||
1031 | read_page_prologue(mtd, g4_addr); | 1031 | read_page_prologue(mtd, g4_addr); |
1032 | docg4_read_page(mtd, nand, buf, 0, DOCG4_FACTORY_BBT_PAGE); | 1032 | docg4_read_page(mtd, nand, buf, 0, DOCG4_FACTORY_BBT_PAGE); |
1033 | 1033 | ||
1034 | /* | 1034 | /* |
1035 | * If no memory-based bbt was created, exit. This will happen if module | 1035 | * If no memory-based bbt was created, exit. This will happen if module |
1036 | * parameter ignore_badblocks is set. Then why even call this function? | 1036 | * parameter ignore_badblocks is set. Then why even call this function? |
1037 | * For an unknown reason, block erase always fails if it's the first | 1037 | * For an unknown reason, block erase always fails if it's the first |
1038 | * operation after device power-up. The above read ensures it never is. | 1038 | * operation after device power-up. The above read ensures it never is. |
1039 | * Ugly, I know. | 1039 | * Ugly, I know. |
1040 | */ | 1040 | */ |
1041 | if (nand->bbt == NULL) /* no memory-based bbt */ | 1041 | if (nand->bbt == NULL) /* no memory-based bbt */ |
1042 | goto exit; | 1042 | goto exit; |
1043 | 1043 | ||
1044 | if (mtd->ecc_stats.failed > eccfailed_stats) { | 1044 | if (mtd->ecc_stats.failed > eccfailed_stats) { |
1045 | /* | 1045 | /* |
1046 | * Whoops, an ecc failure ocurred reading the factory bbt. | 1046 | * Whoops, an ecc failure ocurred reading the factory bbt. |
1047 | * It is stored redundantly, so we get another chance. | 1047 | * It is stored redundantly, so we get another chance. |
1048 | */ | 1048 | */ |
1049 | eccfailed_stats = mtd->ecc_stats.failed; | 1049 | eccfailed_stats = mtd->ecc_stats.failed; |
1050 | docg4_read_page(mtd, nand, buf, 0, DOCG4_REDUNDANT_BBT_PAGE); | 1050 | docg4_read_page(mtd, nand, buf, 0, DOCG4_REDUNDANT_BBT_PAGE); |
1051 | if (mtd->ecc_stats.failed > eccfailed_stats) { | 1051 | if (mtd->ecc_stats.failed > eccfailed_stats) { |
1052 | dev_warn(doc->dev, | 1052 | dev_warn(doc->dev, |
1053 | "The factory bbt could not be read!\n"); | 1053 | "The factory bbt could not be read!\n"); |
1054 | goto exit; | 1054 | goto exit; |
1055 | } | 1055 | } |
1056 | } | 1056 | } |
1057 | 1057 | ||
1058 | /* | 1058 | /* |
1059 | * Parse factory bbt and update memory-based bbt. Factory bbt format is | 1059 | * Parse factory bbt and update memory-based bbt. Factory bbt format is |
1060 | * simple: one bit per block, block numbers increase left to right (msb | 1060 | * simple: one bit per block, block numbers increase left to right (msb |
1061 | * to lsb). Bit clear means bad block. | 1061 | * to lsb). Bit clear means bad block. |
1062 | */ | 1062 | */ |
1063 | for (i = block = 0; block < DOCG4_NUMBLOCKS; block += 8, i++) { | 1063 | for (i = block = 0; block < DOCG4_NUMBLOCKS; block += 8, i++) { |
1064 | int bitnum; | 1064 | int bitnum; |
1065 | unsigned long bits = ~buf[i]; | 1065 | unsigned long bits = ~buf[i]; |
1066 | for_each_set_bit(bitnum, &bits, 8) { | 1066 | for_each_set_bit(bitnum, &bits, 8) { |
1067 | int badblock = block + 7 - bitnum; | 1067 | int badblock = block + 7 - bitnum; |
1068 | nand->bbt[badblock / 4] |= | 1068 | nand->bbt[badblock / 4] |= |
1069 | 0x03 << ((badblock % 4) * 2); | 1069 | 0x03 << ((badblock % 4) * 2); |
1070 | mtd->ecc_stats.badblocks++; | 1070 | mtd->ecc_stats.badblocks++; |
1071 | dev_notice(doc->dev, "factory-marked bad block: %d\n", | 1071 | dev_notice(doc->dev, "factory-marked bad block: %d\n", |
1072 | badblock); | 1072 | badblock); |
1073 | } | 1073 | } |
1074 | } | 1074 | } |
1075 | exit: | 1075 | exit: |
1076 | kfree(buf); | 1076 | kfree(buf); |
1077 | return 0; | 1077 | return 0; |
1078 | } | 1078 | } |
1079 | 1079 | ||
1080 | static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs) | 1080 | static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs) |
1081 | { | 1081 | { |
1082 | /* | 1082 | /* |
1083 | * Mark a block as bad. Bad blocks are marked in the oob area of the | 1083 | * Mark a block as bad. Bad blocks are marked in the oob area of the |
1084 | * first page of the block. The default scan_bbt() in the nand | 1084 | * first page of the block. The default scan_bbt() in the nand |
1085 | * infrastructure code works fine for building the memory-based bbt | 1085 | * infrastructure code works fine for building the memory-based bbt |
1086 | * during initialization, as does the nand infrastructure function that | 1086 | * during initialization, as does the nand infrastructure function that |
1087 | * checks if a block is bad by reading the bbt. This function replaces | 1087 | * checks if a block is bad by reading the bbt. This function replaces |
1088 | * the nand default because writes to oob-only are not supported. | 1088 | * the nand default because writes to oob-only are not supported. |
1089 | */ | 1089 | */ |
1090 | 1090 | ||
1091 | int ret, i; | 1091 | int ret, i; |
1092 | uint8_t *buf; | 1092 | uint8_t *buf; |
1093 | struct nand_chip *nand = mtd->priv; | 1093 | struct nand_chip *nand = mtd->priv; |
1094 | struct docg4_priv *doc = nand->priv; | 1094 | struct docg4_priv *doc = nand->priv; |
1095 | struct nand_bbt_descr *bbtd = nand->badblock_pattern; | 1095 | struct nand_bbt_descr *bbtd = nand->badblock_pattern; |
1096 | int block = (int)(ofs >> nand->bbt_erase_shift); | 1096 | int block = (int)(ofs >> nand->bbt_erase_shift); |
1097 | int page = (int)(ofs >> nand->page_shift); | 1097 | int page = (int)(ofs >> nand->page_shift); |
1098 | uint32_t g4_addr = mtd_to_docg4_address(page, 0); | 1098 | uint32_t g4_addr = mtd_to_docg4_address(page, 0); |
1099 | 1099 | ||
1100 | dev_dbg(doc->dev, "%s: %08llx\n", __func__, ofs); | 1100 | dev_dbg(doc->dev, "%s: %08llx\n", __func__, ofs); |
1101 | 1101 | ||
1102 | if (unlikely(ofs & (DOCG4_BLOCK_SIZE - 1))) | 1102 | if (unlikely(ofs & (DOCG4_BLOCK_SIZE - 1))) |
1103 | dev_warn(doc->dev, "%s: ofs %llx not start of block!\n", | 1103 | dev_warn(doc->dev, "%s: ofs %llx not start of block!\n", |
1104 | __func__, ofs); | 1104 | __func__, ofs); |
1105 | 1105 | ||
1106 | /* allocate blank buffer for page data */ | 1106 | /* allocate blank buffer for page data */ |
1107 | buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL); | 1107 | buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL); |
1108 | if (buf == NULL) | 1108 | if (buf == NULL) |
1109 | return -ENOMEM; | 1109 | return -ENOMEM; |
1110 | 1110 | ||
1111 | /* update bbt in memory */ | 1111 | /* update bbt in memory */ |
1112 | nand->bbt[block / 4] |= 0x01 << ((block & 0x03) * 2); | 1112 | nand->bbt[block / 4] |= 0x01 << ((block & 0x03) * 2); |
1113 | 1113 | ||
1114 | /* write bit-wise negation of pattern to oob buffer */ | 1114 | /* write bit-wise negation of pattern to oob buffer */ |
1115 | memset(nand->oob_poi, 0xff, mtd->oobsize); | 1115 | memset(nand->oob_poi, 0xff, mtd->oobsize); |
1116 | for (i = 0; i < bbtd->len; i++) | 1116 | for (i = 0; i < bbtd->len; i++) |
1117 | nand->oob_poi[bbtd->offs + i] = ~bbtd->pattern[i]; | 1117 | nand->oob_poi[bbtd->offs + i] = ~bbtd->pattern[i]; |
1118 | 1118 | ||
1119 | /* write first page of block */ | 1119 | /* write first page of block */ |
1120 | write_page_prologue(mtd, g4_addr); | 1120 | write_page_prologue(mtd, g4_addr); |
1121 | docg4_write_page(mtd, nand, buf, 1); | 1121 | docg4_write_page(mtd, nand, buf, 1); |
1122 | ret = pageprog(mtd); | 1122 | ret = pageprog(mtd); |
1123 | if (!ret) | 1123 | if (!ret) |
1124 | mtd->ecc_stats.badblocks++; | 1124 | mtd->ecc_stats.badblocks++; |
1125 | 1125 | ||
1126 | kfree(buf); | 1126 | kfree(buf); |
1127 | 1127 | ||
1128 | return ret; | 1128 | return ret; |
1129 | } | 1129 | } |
1130 | 1130 | ||
1131 | static int docg4_block_neverbad(struct mtd_info *mtd, loff_t ofs, int getchip) | 1131 | static int docg4_block_neverbad(struct mtd_info *mtd, loff_t ofs, int getchip) |
1132 | { | 1132 | { |
1133 | /* only called when module_param ignore_badblocks is set */ | 1133 | /* only called when module_param ignore_badblocks is set */ |
1134 | return 0; | 1134 | return 0; |
1135 | } | 1135 | } |
1136 | 1136 | ||
1137 | static int docg4_suspend(struct platform_device *pdev, pm_message_t state) | 1137 | static int docg4_suspend(struct platform_device *pdev, pm_message_t state) |
1138 | { | 1138 | { |
1139 | /* | 1139 | /* |
1140 | * Put the device into "deep power-down" mode. Note that CE# must be | 1140 | * Put the device into "deep power-down" mode. Note that CE# must be |
1141 | * deasserted for this to take effect. The xscale, e.g., can be | 1141 | * deasserted for this to take effect. The xscale, e.g., can be |
1142 | * configured to float this signal when the processor enters power-down, | 1142 | * configured to float this signal when the processor enters power-down, |
1143 | * and a suitable pull-up ensures its deassertion. | 1143 | * and a suitable pull-up ensures its deassertion. |
1144 | */ | 1144 | */ |
1145 | 1145 | ||
1146 | int i; | 1146 | int i; |
1147 | uint8_t pwr_down; | 1147 | uint8_t pwr_down; |
1148 | struct docg4_priv *doc = platform_get_drvdata(pdev); | 1148 | struct docg4_priv *doc = platform_get_drvdata(pdev); |
1149 | void __iomem *docptr = doc->virtadr; | 1149 | void __iomem *docptr = doc->virtadr; |
1150 | 1150 | ||
1151 | dev_dbg(doc->dev, "%s...\n", __func__); | 1151 | dev_dbg(doc->dev, "%s...\n", __func__); |
1152 | 1152 | ||
1153 | /* poll the register that tells us we're ready to go to sleep */ | 1153 | /* poll the register that tells us we're ready to go to sleep */ |
1154 | for (i = 0; i < 10; i++) { | 1154 | for (i = 0; i < 10; i++) { |
1155 | pwr_down = readb(docptr + DOC_POWERMODE); | 1155 | pwr_down = readb(docptr + DOC_POWERMODE); |
1156 | if (pwr_down & DOC_POWERDOWN_READY) | 1156 | if (pwr_down & DOC_POWERDOWN_READY) |
1157 | break; | 1157 | break; |
1158 | usleep_range(1000, 4000); | 1158 | usleep_range(1000, 4000); |
1159 | } | 1159 | } |
1160 | 1160 | ||
1161 | if (pwr_down & DOC_POWERDOWN_READY) { | 1161 | if (pwr_down & DOC_POWERDOWN_READY) { |
1162 | dev_err(doc->dev, "suspend failed; " | 1162 | dev_err(doc->dev, "suspend failed; " |
1163 | "timeout polling DOC_POWERDOWN_READY\n"); | 1163 | "timeout polling DOC_POWERDOWN_READY\n"); |
1164 | return -EIO; | 1164 | return -EIO; |
1165 | } | 1165 | } |
1166 | 1166 | ||
1167 | writew(DOC_ASICMODE_POWERDOWN | DOC_ASICMODE_MDWREN, | 1167 | writew(DOC_ASICMODE_POWERDOWN | DOC_ASICMODE_MDWREN, |
1168 | docptr + DOC_ASICMODE); | 1168 | docptr + DOC_ASICMODE); |
1169 | writew(~(DOC_ASICMODE_POWERDOWN | DOC_ASICMODE_MDWREN), | 1169 | writew(~(DOC_ASICMODE_POWERDOWN | DOC_ASICMODE_MDWREN), |
1170 | docptr + DOC_ASICMODECONFIRM); | 1170 | docptr + DOC_ASICMODECONFIRM); |
1171 | 1171 | ||
1172 | write_nop(docptr); | 1172 | write_nop(docptr); |
1173 | 1173 | ||
1174 | return 0; | 1174 | return 0; |
1175 | } | 1175 | } |
1176 | 1176 | ||
1177 | static int docg4_resume(struct platform_device *pdev) | 1177 | static int docg4_resume(struct platform_device *pdev) |
1178 | { | 1178 | { |
1179 | 1179 | ||
1180 | /* | 1180 | /* |
1181 | * Exit power-down. Twelve consecutive reads of the address below | 1181 | * Exit power-down. Twelve consecutive reads of the address below |
1182 | * accomplishes this, assuming CE# has been asserted. | 1182 | * accomplishes this, assuming CE# has been asserted. |
1183 | */ | 1183 | */ |
1184 | 1184 | ||
1185 | struct docg4_priv *doc = platform_get_drvdata(pdev); | 1185 | struct docg4_priv *doc = platform_get_drvdata(pdev); |
1186 | void __iomem *docptr = doc->virtadr; | 1186 | void __iomem *docptr = doc->virtadr; |
1187 | int i; | 1187 | int i; |
1188 | 1188 | ||
1189 | dev_dbg(doc->dev, "%s...\n", __func__); | 1189 | dev_dbg(doc->dev, "%s...\n", __func__); |
1190 | 1190 | ||
1191 | for (i = 0; i < 12; i++) | 1191 | for (i = 0; i < 12; i++) |
1192 | readb(docptr + 0x1fff); | 1192 | readb(docptr + 0x1fff); |
1193 | 1193 | ||
1194 | return 0; | 1194 | return 0; |
1195 | } | 1195 | } |
1196 | 1196 | ||
1197 | static void __init init_mtd_structs(struct mtd_info *mtd) | 1197 | static void __init init_mtd_structs(struct mtd_info *mtd) |
1198 | { | 1198 | { |
1199 | /* initialize mtd and nand data structures */ | 1199 | /* initialize mtd and nand data structures */ |
1200 | 1200 | ||
1201 | /* | 1201 | /* |
1202 | * Note that some of the following initializations are not usually | 1202 | * Note that some of the following initializations are not usually |
1203 | * required within a nand driver because they are performed by the nand | 1203 | * required within a nand driver because they are performed by the nand |
1204 | * infrastructure code as part of nand_scan(). In this case they need | 1204 | * infrastructure code as part of nand_scan(). In this case they need |
1205 | * to be initialized here because we skip call to nand_scan_ident() (the | 1205 | * to be initialized here because we skip call to nand_scan_ident() (the |
1206 | * first half of nand_scan()). The call to nand_scan_ident() is skipped | 1206 | * first half of nand_scan()). The call to nand_scan_ident() is skipped |
1207 | * because for this device the chip id is not read in the manner of a | 1207 | * because for this device the chip id is not read in the manner of a |
1208 | * standard nand device. Unfortunately, nand_scan_ident() does other | 1208 | * standard nand device. Unfortunately, nand_scan_ident() does other |
1209 | * things as well, such as call nand_set_defaults(). | 1209 | * things as well, such as call nand_set_defaults(). |
1210 | */ | 1210 | */ |
1211 | 1211 | ||
1212 | struct nand_chip *nand = mtd->priv; | 1212 | struct nand_chip *nand = mtd->priv; |
1213 | struct docg4_priv *doc = nand->priv; | 1213 | struct docg4_priv *doc = nand->priv; |
1214 | 1214 | ||
1215 | mtd->size = DOCG4_CHIP_SIZE; | 1215 | mtd->size = DOCG4_CHIP_SIZE; |
1216 | mtd->name = "Msys_Diskonchip_G4"; | 1216 | mtd->name = "Msys_Diskonchip_G4"; |
1217 | mtd->writesize = DOCG4_PAGE_SIZE; | 1217 | mtd->writesize = DOCG4_PAGE_SIZE; |
1218 | mtd->erasesize = DOCG4_BLOCK_SIZE; | 1218 | mtd->erasesize = DOCG4_BLOCK_SIZE; |
1219 | mtd->oobsize = DOCG4_OOB_SIZE; | 1219 | mtd->oobsize = DOCG4_OOB_SIZE; |
1220 | nand->chipsize = DOCG4_CHIP_SIZE; | 1220 | nand->chipsize = DOCG4_CHIP_SIZE; |
1221 | nand->chip_shift = DOCG4_CHIP_SHIFT; | 1221 | nand->chip_shift = DOCG4_CHIP_SHIFT; |
1222 | nand->bbt_erase_shift = nand->phys_erase_shift = DOCG4_ERASE_SHIFT; | 1222 | nand->bbt_erase_shift = nand->phys_erase_shift = DOCG4_ERASE_SHIFT; |
1223 | nand->chip_delay = 20; | 1223 | nand->chip_delay = 20; |
1224 | nand->page_shift = DOCG4_PAGE_SHIFT; | 1224 | nand->page_shift = DOCG4_PAGE_SHIFT; |
1225 | nand->pagemask = 0x3ffff; | 1225 | nand->pagemask = 0x3ffff; |
1226 | nand->badblockpos = NAND_LARGE_BADBLOCK_POS; | 1226 | nand->badblockpos = NAND_LARGE_BADBLOCK_POS; |
1227 | nand->badblockbits = 8; | 1227 | nand->badblockbits = 8; |
1228 | nand->ecc.layout = &docg4_oobinfo; | 1228 | nand->ecc.layout = &docg4_oobinfo; |
1229 | nand->ecc.mode = NAND_ECC_HW_SYNDROME; | 1229 | nand->ecc.mode = NAND_ECC_HW_SYNDROME; |
1230 | nand->ecc.size = DOCG4_PAGE_SIZE; | 1230 | nand->ecc.size = DOCG4_PAGE_SIZE; |
1231 | nand->ecc.prepad = 8; | 1231 | nand->ecc.prepad = 8; |
1232 | nand->ecc.bytes = 8; | 1232 | nand->ecc.bytes = 8; |
1233 | nand->ecc.strength = DOCG4_T; | 1233 | nand->ecc.strength = DOCG4_T; |
1234 | nand->options = NAND_BUSWIDTH_16 | NAND_NO_SUBPAGE_WRITE; | 1234 | nand->options = NAND_BUSWIDTH_16 | NAND_NO_SUBPAGE_WRITE; |
1235 | nand->IO_ADDR_R = nand->IO_ADDR_W = doc->virtadr + DOC_IOSPACE_DATA; | 1235 | nand->IO_ADDR_R = nand->IO_ADDR_W = doc->virtadr + DOC_IOSPACE_DATA; |
1236 | nand->controller = &nand->hwcontrol; | 1236 | nand->controller = &nand->hwcontrol; |
1237 | spin_lock_init(&nand->controller->lock); | 1237 | spin_lock_init(&nand->controller->lock); |
1238 | init_waitqueue_head(&nand->controller->wq); | 1238 | init_waitqueue_head(&nand->controller->wq); |
1239 | 1239 | ||
1240 | /* methods */ | 1240 | /* methods */ |
1241 | nand->cmdfunc = docg4_command; | 1241 | nand->cmdfunc = docg4_command; |
1242 | nand->waitfunc = docg4_wait; | 1242 | nand->waitfunc = docg4_wait; |
1243 | nand->select_chip = docg4_select_chip; | 1243 | nand->select_chip = docg4_select_chip; |
1244 | nand->read_byte = docg4_read_byte; | 1244 | nand->read_byte = docg4_read_byte; |
1245 | nand->block_markbad = docg4_block_markbad; | 1245 | nand->block_markbad = docg4_block_markbad; |
1246 | nand->read_buf = docg4_read_buf; | 1246 | nand->read_buf = docg4_read_buf; |
1247 | nand->write_buf = docg4_write_buf16; | 1247 | nand->write_buf = docg4_write_buf16; |
1248 | nand->scan_bbt = nand_default_bbt; | 1248 | nand->scan_bbt = nand_default_bbt; |
1249 | nand->erase_cmd = docg4_erase_block; | 1249 | nand->erase_cmd = docg4_erase_block; |
1250 | nand->ecc.read_page = docg4_read_page; | 1250 | nand->ecc.read_page = docg4_read_page; |
1251 | nand->ecc.write_page = docg4_write_page; | 1251 | nand->ecc.write_page = docg4_write_page; |
1252 | nand->ecc.read_page_raw = docg4_read_page_raw; | 1252 | nand->ecc.read_page_raw = docg4_read_page_raw; |
1253 | nand->ecc.write_page_raw = docg4_write_page_raw; | 1253 | nand->ecc.write_page_raw = docg4_write_page_raw; |
1254 | nand->ecc.read_oob = docg4_read_oob; | 1254 | nand->ecc.read_oob = docg4_read_oob; |
1255 | nand->ecc.write_oob = docg4_write_oob; | 1255 | nand->ecc.write_oob = docg4_write_oob; |
1256 | 1256 | ||
1257 | /* | 1257 | /* |
1258 | * The way the nand infrastructure code is written, a memory-based bbt | 1258 | * The way the nand infrastructure code is written, a memory-based bbt |
1259 | * is not created if NAND_SKIP_BBTSCAN is set. With no memory bbt, | 1259 | * is not created if NAND_SKIP_BBTSCAN is set. With no memory bbt, |
1260 | * nand->block_bad() is used. So when ignoring bad blocks, we skip the | 1260 | * nand->block_bad() is used. So when ignoring bad blocks, we skip the |
1261 | * scan and define a dummy block_bad() which always returns 0. | 1261 | * scan and define a dummy block_bad() which always returns 0. |
1262 | */ | 1262 | */ |
1263 | if (ignore_badblocks) { | 1263 | if (ignore_badblocks) { |
1264 | nand->options |= NAND_SKIP_BBTSCAN; | 1264 | nand->options |= NAND_SKIP_BBTSCAN; |
1265 | nand->block_bad = docg4_block_neverbad; | 1265 | nand->block_bad = docg4_block_neverbad; |
1266 | } | 1266 | } |
1267 | 1267 | ||
1268 | } | 1268 | } |
1269 | 1269 | ||
1270 | static int __init read_id_reg(struct mtd_info *mtd) | 1270 | static int __init read_id_reg(struct mtd_info *mtd) |
1271 | { | 1271 | { |
1272 | struct nand_chip *nand = mtd->priv; | 1272 | struct nand_chip *nand = mtd->priv; |
1273 | struct docg4_priv *doc = nand->priv; | 1273 | struct docg4_priv *doc = nand->priv; |
1274 | void __iomem *docptr = doc->virtadr; | 1274 | void __iomem *docptr = doc->virtadr; |
1275 | uint16_t id1, id2; | 1275 | uint16_t id1, id2; |
1276 | 1276 | ||
1277 | /* check for presence of g4 chip by reading id registers */ | 1277 | /* check for presence of g4 chip by reading id registers */ |
1278 | id1 = readw(docptr + DOC_CHIPID); | 1278 | id1 = readw(docptr + DOC_CHIPID); |
1279 | id1 = readw(docptr + DOCG4_MYSTERY_REG); | 1279 | id1 = readw(docptr + DOCG4_MYSTERY_REG); |
1280 | id2 = readw(docptr + DOC_CHIPID_INV); | 1280 | id2 = readw(docptr + DOC_CHIPID_INV); |
1281 | id2 = readw(docptr + DOCG4_MYSTERY_REG); | 1281 | id2 = readw(docptr + DOCG4_MYSTERY_REG); |
1282 | 1282 | ||
1283 | if (id1 == DOCG4_IDREG1_VALUE && id2 == DOCG4_IDREG2_VALUE) { | 1283 | if (id1 == DOCG4_IDREG1_VALUE && id2 == DOCG4_IDREG2_VALUE) { |
1284 | dev_info(doc->dev, | 1284 | dev_info(doc->dev, |
1285 | "NAND device: 128MiB Diskonchip G4 detected\n"); | 1285 | "NAND device: 128MiB Diskonchip G4 detected\n"); |
1286 | return 0; | 1286 | return 0; |
1287 | } | 1287 | } |
1288 | 1288 | ||
1289 | return -ENODEV; | 1289 | return -ENODEV; |
1290 | } | 1290 | } |
1291 | 1291 | ||
1292 | static char const *part_probes[] = { "cmdlinepart", "saftlpart", NULL }; | 1292 | static char const *part_probes[] = { "cmdlinepart", "saftlpart", NULL }; |
1293 | 1293 | ||
1294 | static int __init probe_docg4(struct platform_device *pdev) | 1294 | static int __init probe_docg4(struct platform_device *pdev) |
1295 | { | 1295 | { |
1296 | struct mtd_info *mtd; | 1296 | struct mtd_info *mtd; |
1297 | struct nand_chip *nand; | 1297 | struct nand_chip *nand; |
1298 | void __iomem *virtadr; | 1298 | void __iomem *virtadr; |
1299 | struct docg4_priv *doc; | 1299 | struct docg4_priv *doc; |
1300 | int len, retval; | 1300 | int len, retval; |
1301 | struct resource *r; | 1301 | struct resource *r; |
1302 | struct device *dev = &pdev->dev; | 1302 | struct device *dev = &pdev->dev; |
1303 | 1303 | ||
1304 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1304 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1305 | if (r == NULL) { | 1305 | if (r == NULL) { |
1306 | dev_err(dev, "no io memory resource defined!\n"); | 1306 | dev_err(dev, "no io memory resource defined!\n"); |
1307 | return -ENODEV; | 1307 | return -ENODEV; |
1308 | } | 1308 | } |
1309 | 1309 | ||
1310 | virtadr = ioremap(r->start, resource_size(r)); | 1310 | virtadr = ioremap(r->start, resource_size(r)); |
1311 | if (!virtadr) { | 1311 | if (!virtadr) { |
1312 | dev_err(dev, "Diskonchip ioremap failed: %pR\n", r); | 1312 | dev_err(dev, "Diskonchip ioremap failed: %pR\n", r); |
1313 | return -EIO; | 1313 | return -EIO; |
1314 | } | 1314 | } |
1315 | 1315 | ||
1316 | len = sizeof(struct mtd_info) + sizeof(struct nand_chip) + | 1316 | len = sizeof(struct mtd_info) + sizeof(struct nand_chip) + |
1317 | sizeof(struct docg4_priv); | 1317 | sizeof(struct docg4_priv); |
1318 | mtd = kzalloc(len, GFP_KERNEL); | 1318 | mtd = kzalloc(len, GFP_KERNEL); |
1319 | if (mtd == NULL) { | 1319 | if (mtd == NULL) { |
1320 | retval = -ENOMEM; | 1320 | retval = -ENOMEM; |
1321 | goto fail; | 1321 | goto fail; |
1322 | } | 1322 | } |
1323 | nand = (struct nand_chip *) (mtd + 1); | 1323 | nand = (struct nand_chip *) (mtd + 1); |
1324 | doc = (struct docg4_priv *) (nand + 1); | 1324 | doc = (struct docg4_priv *) (nand + 1); |
1325 | mtd->priv = nand; | 1325 | mtd->priv = nand; |
1326 | nand->priv = doc; | 1326 | nand->priv = doc; |
1327 | mtd->owner = THIS_MODULE; | 1327 | mtd->owner = THIS_MODULE; |
1328 | doc->virtadr = virtadr; | 1328 | doc->virtadr = virtadr; |
1329 | doc->dev = dev; | 1329 | doc->dev = dev; |
1330 | 1330 | ||
1331 | init_mtd_structs(mtd); | 1331 | init_mtd_structs(mtd); |
1332 | 1332 | ||
1333 | /* initialize kernel bch algorithm */ | 1333 | /* initialize kernel bch algorithm */ |
1334 | doc->bch = init_bch(DOCG4_M, DOCG4_T, DOCG4_PRIMITIVE_POLY); | 1334 | doc->bch = init_bch(DOCG4_M, DOCG4_T, DOCG4_PRIMITIVE_POLY); |
1335 | if (doc->bch == NULL) { | 1335 | if (doc->bch == NULL) { |
1336 | retval = -EINVAL; | 1336 | retval = -EINVAL; |
1337 | goto fail; | 1337 | goto fail; |
1338 | } | 1338 | } |
1339 | 1339 | ||
1340 | platform_set_drvdata(pdev, doc); | 1340 | platform_set_drvdata(pdev, doc); |
1341 | 1341 | ||
1342 | reset(mtd); | 1342 | reset(mtd); |
1343 | retval = read_id_reg(mtd); | 1343 | retval = read_id_reg(mtd); |
1344 | if (retval == -ENODEV) { | 1344 | if (retval == -ENODEV) { |
1345 | dev_warn(dev, "No diskonchip G4 device found.\n"); | 1345 | dev_warn(dev, "No diskonchip G4 device found.\n"); |
1346 | goto fail; | 1346 | goto fail; |
1347 | } | 1347 | } |
1348 | 1348 | ||
1349 | retval = nand_scan_tail(mtd); | 1349 | retval = nand_scan_tail(mtd); |
1350 | if (retval) | 1350 | if (retval) |
1351 | goto fail; | 1351 | goto fail; |
1352 | 1352 | ||
1353 | retval = read_factory_bbt(mtd); | 1353 | retval = read_factory_bbt(mtd); |
1354 | if (retval) | 1354 | if (retval) |
1355 | goto fail; | 1355 | goto fail; |
1356 | 1356 | ||
1357 | retval = mtd_device_parse_register(mtd, part_probes, NULL, NULL, 0); | 1357 | retval = mtd_device_parse_register(mtd, part_probes, NULL, NULL, 0); |
1358 | if (retval) | 1358 | if (retval) |
1359 | goto fail; | 1359 | goto fail; |
1360 | 1360 | ||
1361 | doc->mtd = mtd; | 1361 | doc->mtd = mtd; |
1362 | return 0; | 1362 | return 0; |
1363 | 1363 | ||
1364 | fail: | 1364 | fail: |
1365 | iounmap(virtadr); | 1365 | iounmap(virtadr); |
1366 | if (mtd) { | 1366 | if (mtd) { |
1367 | /* re-declarations avoid compiler warning */ | 1367 | /* re-declarations avoid compiler warning */ |
1368 | struct nand_chip *nand = mtd->priv; | 1368 | struct nand_chip *nand = mtd->priv; |
1369 | struct docg4_priv *doc = nand->priv; | 1369 | struct docg4_priv *doc = nand->priv; |
1370 | nand_release(mtd); /* deletes partitions and mtd devices */ | 1370 | nand_release(mtd); /* deletes partitions and mtd devices */ |
1371 | platform_set_drvdata(pdev, NULL); | 1371 | platform_set_drvdata(pdev, NULL); |
1372 | free_bch(doc->bch); | 1372 | free_bch(doc->bch); |
1373 | kfree(mtd); | 1373 | kfree(mtd); |
1374 | } | 1374 | } |
1375 | 1375 | ||
1376 | return retval; | 1376 | return retval; |
1377 | } | 1377 | } |
1378 | 1378 | ||
1379 | static int __exit cleanup_docg4(struct platform_device *pdev) | 1379 | static int __exit cleanup_docg4(struct platform_device *pdev) |
1380 | { | 1380 | { |
1381 | struct docg4_priv *doc = platform_get_drvdata(pdev); | 1381 | struct docg4_priv *doc = platform_get_drvdata(pdev); |
1382 | nand_release(doc->mtd); | 1382 | nand_release(doc->mtd); |
1383 | platform_set_drvdata(pdev, NULL); | 1383 | platform_set_drvdata(pdev, NULL); |
1384 | free_bch(doc->bch); | 1384 | free_bch(doc->bch); |
1385 | kfree(doc->mtd); | 1385 | kfree(doc->mtd); |
1386 | iounmap(doc->virtadr); | 1386 | iounmap(doc->virtadr); |
1387 | return 0; | 1387 | return 0; |
1388 | } | 1388 | } |
1389 | 1389 | ||
1390 | static struct platform_driver docg4_driver = { | 1390 | static struct platform_driver docg4_driver = { |
1391 | .driver = { | 1391 | .driver = { |
1392 | .name = "docg4", | 1392 | .name = "docg4", |
1393 | .owner = THIS_MODULE, | 1393 | .owner = THIS_MODULE, |
1394 | }, | 1394 | }, |
1395 | .suspend = docg4_suspend, | 1395 | .suspend = docg4_suspend, |
1396 | .resume = docg4_resume, | 1396 | .resume = docg4_resume, |
1397 | .remove = __exit_p(cleanup_docg4), | 1397 | .remove = __exit_p(cleanup_docg4), |
1398 | }; | 1398 | }; |
1399 | 1399 | ||
1400 | static int __init docg4_init(void) | 1400 | module_platform_driver_probe(docg4_driver, probe_docg4); |
1401 | { | ||
1402 | return platform_driver_probe(&docg4_driver, probe_docg4); | ||
1403 | } | ||
1404 | |||
1405 | static void __exit docg4_exit(void) | ||
1406 | { | ||
1407 | platform_driver_unregister(&docg4_driver); | ||
1408 | } | ||
1409 | |||
1410 | module_init(docg4_init); | ||
1411 | module_exit(docg4_exit); | ||
1412 | 1401 | ||
1413 | MODULE_LICENSE("GPL"); | 1402 | MODULE_LICENSE("GPL"); |
1414 | MODULE_AUTHOR("Mike Dunn"); | 1403 | MODULE_AUTHOR("Mike Dunn"); |
1415 | MODULE_DESCRIPTION("M-Systems DiskOnChip G4 device driver"); | 1404 | MODULE_DESCRIPTION("M-Systems DiskOnChip G4 device driver"); |
1416 | 1405 |