blob: 56b66197212228e764a1ba6e116aca78a8c930dc [file] [log] [blame]
Linus Walleij6c009ab2010-09-13 00:35:22 +02001/*
2 * drivers/mtd/nand/fsmc_nand.c
3 *
4 * ST Microelectronics
5 * Flexible Static Memory Controller (FSMC)
6 * Driver for NAND portions
7 *
8 * Copyright © 2010 ST Microelectronics
9 * Vipin Kumar <vipin.kumar@st.com>
10 * Ashish Priyadarshi
11 *
12 * Based on drivers/mtd/nand/nomadik_nand.c
13 *
14 * This file is licensed under the terms of the GNU General Public
15 * License version 2. This program is licensed "as is" without any
16 * warranty of any kind, whether express or implied.
17 */
18
19#include <linux/clk.h>
20#include <linux/err.h>
21#include <linux/init.h>
22#include <linux/module.h>
23#include <linux/resource.h>
24#include <linux/sched.h>
25#include <linux/types.h>
26#include <linux/mtd/mtd.h>
27#include <linux/mtd/nand.h>
28#include <linux/mtd/nand_ecc.h>
29#include <linux/platform_device.h>
30#include <linux/mtd/partitions.h>
31#include <linux/io.h>
32#include <linux/slab.h>
33#include <linux/mtd/fsmc.h>
Linus Walleij593cd872010-11-29 13:52:19 +010034#include <linux/amba/bus.h>
Linus Walleij6c009ab2010-09-13 00:35:22 +020035#include <mtd/mtd-abi.h>
36
Bhavna Yadave29ee572012-03-07 17:00:50 +053037static struct nand_ecclayout fsmc_ecc1_128_layout = {
Linus Walleij6c009ab2010-09-13 00:35:22 +020038 .eccbytes = 24,
39 .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52,
40 66, 67, 68, 82, 83, 84, 98, 99, 100, 114, 115, 116},
41 .oobfree = {
42 {.offset = 8, .length = 8},
43 {.offset = 24, .length = 8},
44 {.offset = 40, .length = 8},
45 {.offset = 56, .length = 8},
46 {.offset = 72, .length = 8},
47 {.offset = 88, .length = 8},
48 {.offset = 104, .length = 8},
49 {.offset = 120, .length = 8}
50 }
51};
52
Bhavna Yadave29ee572012-03-07 17:00:50 +053053static struct nand_ecclayout fsmc_ecc1_64_layout = {
54 .eccbytes = 12,
55 .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52},
56 .oobfree = {
57 {.offset = 8, .length = 8},
58 {.offset = 24, .length = 8},
59 {.offset = 40, .length = 8},
60 {.offset = 56, .length = 8},
61 }
62};
63
64static struct nand_ecclayout fsmc_ecc1_16_layout = {
65 .eccbytes = 3,
66 .eccpos = {2, 3, 4},
67 .oobfree = {
68 {.offset = 8, .length = 8},
69 }
70};
71
72/*
73 * ECC4 layout for NAND of pagesize 8192 bytes & OOBsize 256 bytes. 13*16 bytes
74 * of OB size is reserved for ECC, Byte no. 0 & 1 reserved for bad block and 46
75 * bytes are free for use.
76 */
77static struct nand_ecclayout fsmc_ecc4_256_layout = {
78 .eccbytes = 208,
79 .eccpos = { 2, 3, 4, 5, 6, 7, 8,
80 9, 10, 11, 12, 13, 14,
81 18, 19, 20, 21, 22, 23, 24,
82 25, 26, 27, 28, 29, 30,
83 34, 35, 36, 37, 38, 39, 40,
84 41, 42, 43, 44, 45, 46,
85 50, 51, 52, 53, 54, 55, 56,
86 57, 58, 59, 60, 61, 62,
87 66, 67, 68, 69, 70, 71, 72,
88 73, 74, 75, 76, 77, 78,
89 82, 83, 84, 85, 86, 87, 88,
90 89, 90, 91, 92, 93, 94,
91 98, 99, 100, 101, 102, 103, 104,
92 105, 106, 107, 108, 109, 110,
93 114, 115, 116, 117, 118, 119, 120,
94 121, 122, 123, 124, 125, 126,
95 130, 131, 132, 133, 134, 135, 136,
96 137, 138, 139, 140, 141, 142,
97 146, 147, 148, 149, 150, 151, 152,
98 153, 154, 155, 156, 157, 158,
99 162, 163, 164, 165, 166, 167, 168,
100 169, 170, 171, 172, 173, 174,
101 178, 179, 180, 181, 182, 183, 184,
102 185, 186, 187, 188, 189, 190,
103 194, 195, 196, 197, 198, 199, 200,
104 201, 202, 203, 204, 205, 206,
105 210, 211, 212, 213, 214, 215, 216,
106 217, 218, 219, 220, 221, 222,
107 226, 227, 228, 229, 230, 231, 232,
108 233, 234, 235, 236, 237, 238,
109 242, 243, 244, 245, 246, 247, 248,
110 249, 250, 251, 252, 253, 254
111 },
112 .oobfree = {
113 {.offset = 15, .length = 3},
114 {.offset = 31, .length = 3},
115 {.offset = 47, .length = 3},
116 {.offset = 63, .length = 3},
117 {.offset = 79, .length = 3},
118 {.offset = 95, .length = 3},
119 {.offset = 111, .length = 3},
120 {.offset = 127, .length = 3},
121 {.offset = 143, .length = 3},
122 {.offset = 159, .length = 3},
123 {.offset = 175, .length = 3},
124 {.offset = 191, .length = 3},
125 {.offset = 207, .length = 3},
126 {.offset = 223, .length = 3},
127 {.offset = 239, .length = 3},
128 {.offset = 255, .length = 1}
129 }
130};
131
132/*
Armando Visconti0c78e932012-03-07 17:00:55 +0530133 * ECC4 layout for NAND of pagesize 4096 bytes & OOBsize 224 bytes. 13*8 bytes
134 * of OOB size is reserved for ECC, Byte no. 0 & 1 reserved for bad block & 118
135 * bytes are free for use.
136 */
137static struct nand_ecclayout fsmc_ecc4_224_layout = {
138 .eccbytes = 104,
139 .eccpos = { 2, 3, 4, 5, 6, 7, 8,
140 9, 10, 11, 12, 13, 14,
141 18, 19, 20, 21, 22, 23, 24,
142 25, 26, 27, 28, 29, 30,
143 34, 35, 36, 37, 38, 39, 40,
144 41, 42, 43, 44, 45, 46,
145 50, 51, 52, 53, 54, 55, 56,
146 57, 58, 59, 60, 61, 62,
147 66, 67, 68, 69, 70, 71, 72,
148 73, 74, 75, 76, 77, 78,
149 82, 83, 84, 85, 86, 87, 88,
150 89, 90, 91, 92, 93, 94,
151 98, 99, 100, 101, 102, 103, 104,
152 105, 106, 107, 108, 109, 110,
153 114, 115, 116, 117, 118, 119, 120,
154 121, 122, 123, 124, 125, 126
155 },
156 .oobfree = {
157 {.offset = 15, .length = 3},
158 {.offset = 31, .length = 3},
159 {.offset = 47, .length = 3},
160 {.offset = 63, .length = 3},
161 {.offset = 79, .length = 3},
162 {.offset = 95, .length = 3},
163 {.offset = 111, .length = 3},
164 {.offset = 127, .length = 97}
165 }
166};
167
168/*
Bhavna Yadave29ee572012-03-07 17:00:50 +0530169 * ECC4 layout for NAND of pagesize 4096 bytes & OOBsize 128 bytes. 13*8 bytes
170 * of OOB size is reserved for ECC, Byte no. 0 & 1 reserved for bad block & 22
171 * bytes are free for use.
172 */
173static struct nand_ecclayout fsmc_ecc4_128_layout = {
Linus Walleij6c009ab2010-09-13 00:35:22 +0200174 .eccbytes = 104,
175 .eccpos = { 2, 3, 4, 5, 6, 7, 8,
176 9, 10, 11, 12, 13, 14,
177 18, 19, 20, 21, 22, 23, 24,
178 25, 26, 27, 28, 29, 30,
179 34, 35, 36, 37, 38, 39, 40,
180 41, 42, 43, 44, 45, 46,
181 50, 51, 52, 53, 54, 55, 56,
182 57, 58, 59, 60, 61, 62,
183 66, 67, 68, 69, 70, 71, 72,
184 73, 74, 75, 76, 77, 78,
185 82, 83, 84, 85, 86, 87, 88,
186 89, 90, 91, 92, 93, 94,
187 98, 99, 100, 101, 102, 103, 104,
188 105, 106, 107, 108, 109, 110,
189 114, 115, 116, 117, 118, 119, 120,
190 121, 122, 123, 124, 125, 126
191 },
192 .oobfree = {
193 {.offset = 15, .length = 3},
194 {.offset = 31, .length = 3},
195 {.offset = 47, .length = 3},
196 {.offset = 63, .length = 3},
197 {.offset = 79, .length = 3},
198 {.offset = 95, .length = 3},
199 {.offset = 111, .length = 3},
200 {.offset = 127, .length = 1}
201 }
202};
203
204/*
Bhavna Yadave29ee572012-03-07 17:00:50 +0530205 * ECC4 layout for NAND of pagesize 2048 bytes & OOBsize 64 bytes. 13*4 bytes of
206 * OOB size is reserved for ECC, Byte no. 0 & 1 reserved for bad block and 10
207 * bytes are free for use.
208 */
209static struct nand_ecclayout fsmc_ecc4_64_layout = {
210 .eccbytes = 52,
211 .eccpos = { 2, 3, 4, 5, 6, 7, 8,
212 9, 10, 11, 12, 13, 14,
213 18, 19, 20, 21, 22, 23, 24,
214 25, 26, 27, 28, 29, 30,
215 34, 35, 36, 37, 38, 39, 40,
216 41, 42, 43, 44, 45, 46,
217 50, 51, 52, 53, 54, 55, 56,
218 57, 58, 59, 60, 61, 62,
219 },
220 .oobfree = {
221 {.offset = 15, .length = 3},
222 {.offset = 31, .length = 3},
223 {.offset = 47, .length = 3},
224 {.offset = 63, .length = 1},
225 }
226};
227
228/*
229 * ECC4 layout for NAND of pagesize 512 bytes & OOBsize 16 bytes. 13 bytes of
230 * OOB size is reserved for ECC, Byte no. 4 & 5 reserved for bad block and One
231 * byte is free for use.
232 */
233static struct nand_ecclayout fsmc_ecc4_16_layout = {
234 .eccbytes = 13,
235 .eccpos = { 0, 1, 2, 3, 6, 7, 8,
236 9, 10, 11, 12, 13, 14
237 },
238 .oobfree = {
239 {.offset = 15, .length = 1},
240 }
241};
242
243/*
Linus Walleij6c009ab2010-09-13 00:35:22 +0200244 * ECC placement definitions in oobfree type format.
245 * There are 13 bytes of ecc for every 512 byte block and it has to be read
246 * consecutively and immediately after the 512 byte data block for hardware to
247 * generate the error bit offsets in 512 byte data.
248 * Managing the ecc bytes in the following way makes it easier for software to
249 * read ecc bytes consecutive to data bytes. This way is similar to
250 * oobfree structure maintained already in generic nand driver
251 */
252static struct fsmc_eccplace fsmc_ecc4_lp_place = {
253 .eccplace = {
254 {.offset = 2, .length = 13},
255 {.offset = 18, .length = 13},
256 {.offset = 34, .length = 13},
257 {.offset = 50, .length = 13},
258 {.offset = 66, .length = 13},
259 {.offset = 82, .length = 13},
260 {.offset = 98, .length = 13},
261 {.offset = 114, .length = 13}
262 }
263};
264
Linus Walleij6c009ab2010-09-13 00:35:22 +0200265static struct fsmc_eccplace fsmc_ecc4_sp_place = {
266 .eccplace = {
267 {.offset = 0, .length = 4},
268 {.offset = 6, .length = 9}
269 }
270};
271
Linus Walleij6c009ab2010-09-13 00:35:22 +0200272/**
Linus Walleij593cd872010-11-29 13:52:19 +0100273 * struct fsmc_nand_data - structure for FSMC NAND device state
Linus Walleij6c009ab2010-09-13 00:35:22 +0200274 *
Linus Walleij593cd872010-11-29 13:52:19 +0100275 * @pid: Part ID on the AMBA PrimeCell format
Linus Walleij6c009ab2010-09-13 00:35:22 +0200276 * @mtd: MTD info for a NAND flash.
277 * @nand: Chip related info for a NAND flash.
Vipin Kumar71470322012-03-14 11:47:07 +0530278 * @partitions: Partition info for a NAND Flash.
279 * @nr_partitions: Total number of partition of a NAND flash.
Linus Walleij6c009ab2010-09-13 00:35:22 +0200280 *
281 * @ecc_place: ECC placing locations in oobfree type format.
282 * @bank: Bank number for probed device.
283 * @clk: Clock structure for FSMC.
284 *
285 * @data_va: NAND port for Data.
286 * @cmd_va: NAND port for Command.
287 * @addr_va: NAND port for Address.
288 * @regs_va: FSMC regs base address.
289 */
290struct fsmc_nand_data {
Linus Walleij593cd872010-11-29 13:52:19 +0100291 u32 pid;
Linus Walleij6c009ab2010-09-13 00:35:22 +0200292 struct mtd_info mtd;
293 struct nand_chip nand;
Vipin Kumar71470322012-03-14 11:47:07 +0530294 struct mtd_partition *partitions;
295 unsigned int nr_partitions;
Linus Walleij6c009ab2010-09-13 00:35:22 +0200296
297 struct fsmc_eccplace *ecc_place;
298 unsigned int bank;
299 struct clk *clk;
300
Vipin Kumare2f6bce2012-03-14 11:47:14 +0530301 struct fsmc_nand_timings *dev_timings;
302
Linus Walleij6c009ab2010-09-13 00:35:22 +0200303 void __iomem *data_va;
304 void __iomem *cmd_va;
305 void __iomem *addr_va;
306 void __iomem *regs_va;
307
308 void (*select_chip)(uint32_t bank, uint32_t busw);
309};
310
311/* Assert CS signal based on chipnr */
312static void fsmc_select_chip(struct mtd_info *mtd, int chipnr)
313{
314 struct nand_chip *chip = mtd->priv;
315 struct fsmc_nand_data *host;
316
317 host = container_of(mtd, struct fsmc_nand_data, mtd);
318
319 switch (chipnr) {
320 case -1:
321 chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
322 break;
323 case 0:
324 case 1:
325 case 2:
326 case 3:
327 if (host->select_chip)
328 host->select_chip(chipnr,
329 chip->options & NAND_BUSWIDTH_16);
330 break;
331
332 default:
333 BUG();
334 }
335}
336
337/*
338 * fsmc_cmd_ctrl - For facilitaing Hardware access
339 * This routine allows hardware specific access to control-lines(ALE,CLE)
340 */
341static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
342{
343 struct nand_chip *this = mtd->priv;
344 struct fsmc_nand_data *host = container_of(mtd,
345 struct fsmc_nand_data, mtd);
346 struct fsmc_regs *regs = host->regs_va;
347 unsigned int bank = host->bank;
348
349 if (ctrl & NAND_CTRL_CHANGE) {
350 if (ctrl & NAND_CLE) {
351 this->IO_ADDR_R = (void __iomem *)host->cmd_va;
352 this->IO_ADDR_W = (void __iomem *)host->cmd_va;
353 } else if (ctrl & NAND_ALE) {
354 this->IO_ADDR_R = (void __iomem *)host->addr_va;
355 this->IO_ADDR_W = (void __iomem *)host->addr_va;
356 } else {
357 this->IO_ADDR_R = (void __iomem *)host->data_va;
358 this->IO_ADDR_W = (void __iomem *)host->data_va;
359 }
360
361 if (ctrl & NAND_NCE) {
362 writel(readl(&regs->bank_regs[bank].pc) | FSMC_ENABLE,
363 &regs->bank_regs[bank].pc);
364 } else {
365 writel(readl(&regs->bank_regs[bank].pc) & ~FSMC_ENABLE,
366 &regs->bank_regs[bank].pc);
367 }
368 }
369
370 mb();
371
372 if (cmd != NAND_CMD_NONE)
373 writeb(cmd, this->IO_ADDR_W);
374}
375
376/*
377 * fsmc_nand_setup - FSMC (Flexible Static Memory Controller) init routine
378 *
379 * This routine initializes timing parameters related to NAND memory access in
380 * FSMC registers
381 */
Shiraz Hashimf63acb72012-03-14 11:47:13 +0530382static void fsmc_nand_setup(struct fsmc_regs *regs, uint32_t bank,
Vipin Kumare2f6bce2012-03-14 11:47:14 +0530383 uint32_t busw, struct fsmc_nand_timings *timings)
Linus Walleij6c009ab2010-09-13 00:35:22 +0200384{
385 uint32_t value = FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON;
Vipin Kumare2f6bce2012-03-14 11:47:14 +0530386 uint32_t tclr, tar, thiz, thold, twait, tset;
387 struct fsmc_nand_timings *tims;
388 struct fsmc_nand_timings default_timings = {
389 .tclr = FSMC_TCLR_1,
390 .tar = FSMC_TAR_1,
391 .thiz = FSMC_THIZ_1,
392 .thold = FSMC_THOLD_4,
393 .twait = FSMC_TWAIT_6,
394 .tset = FSMC_TSET_0,
395 };
396
397 if (timings)
398 tims = timings;
399 else
400 tims = &default_timings;
401
402 tclr = (tims->tclr & FSMC_TCLR_MASK) << FSMC_TCLR_SHIFT;
403 tar = (tims->tar & FSMC_TAR_MASK) << FSMC_TAR_SHIFT;
404 thiz = (tims->thiz & FSMC_THIZ_MASK) << FSMC_THIZ_SHIFT;
405 thold = (tims->thold & FSMC_THOLD_MASK) << FSMC_THOLD_SHIFT;
406 twait = (tims->twait & FSMC_TWAIT_MASK) << FSMC_TWAIT_SHIFT;
407 tset = (tims->tset & FSMC_TSET_MASK) << FSMC_TSET_SHIFT;
Linus Walleij6c009ab2010-09-13 00:35:22 +0200408
409 if (busw)
410 writel(value | FSMC_DEVWID_16, &regs->bank_regs[bank].pc);
411 else
412 writel(value | FSMC_DEVWID_8, &regs->bank_regs[bank].pc);
413
Vipin Kumare2f6bce2012-03-14 11:47:14 +0530414 writel(readl(&regs->bank_regs[bank].pc) | tclr | tar,
Linus Walleij6c009ab2010-09-13 00:35:22 +0200415 &regs->bank_regs[bank].pc);
Vipin Kumare2f6bce2012-03-14 11:47:14 +0530416 writel(thiz | thold | twait | tset, &regs->bank_regs[bank].comm);
417 writel(thiz | thold | twait | tset, &regs->bank_regs[bank].attrib);
Linus Walleij6c009ab2010-09-13 00:35:22 +0200418}
419
420/*
421 * fsmc_enable_hwecc - Enables Hardware ECC through FSMC registers
422 */
423static void fsmc_enable_hwecc(struct mtd_info *mtd, int mode)
424{
425 struct fsmc_nand_data *host = container_of(mtd,
426 struct fsmc_nand_data, mtd);
427 struct fsmc_regs *regs = host->regs_va;
428 uint32_t bank = host->bank;
429
430 writel(readl(&regs->bank_regs[bank].pc) & ~FSMC_ECCPLEN_256,
431 &regs->bank_regs[bank].pc);
432 writel(readl(&regs->bank_regs[bank].pc) & ~FSMC_ECCEN,
433 &regs->bank_regs[bank].pc);
434 writel(readl(&regs->bank_regs[bank].pc) | FSMC_ECCEN,
435 &regs->bank_regs[bank].pc);
436}
437
438/*
439 * fsmc_read_hwecc_ecc4 - Hardware ECC calculator for ecc4 option supported by
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300440 * FSMC. ECC is 13 bytes for 512 bytes of data (supports error correction up to
Linus Walleij6c009ab2010-09-13 00:35:22 +0200441 * max of 8-bits)
442 */
443static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data,
444 uint8_t *ecc)
445{
446 struct fsmc_nand_data *host = container_of(mtd,
447 struct fsmc_nand_data, mtd);
448 struct fsmc_regs *regs = host->regs_va;
449 uint32_t bank = host->bank;
450 uint32_t ecc_tmp;
451 unsigned long deadline = jiffies + FSMC_BUSY_WAIT_TIMEOUT;
452
453 do {
454 if (readl(&regs->bank_regs[bank].sts) & FSMC_CODE_RDY)
455 break;
456 else
457 cond_resched();
458 } while (!time_after_eq(jiffies, deadline));
459
460 ecc_tmp = readl(&regs->bank_regs[bank].ecc1);
461 ecc[0] = (uint8_t) (ecc_tmp >> 0);
462 ecc[1] = (uint8_t) (ecc_tmp >> 8);
463 ecc[2] = (uint8_t) (ecc_tmp >> 16);
464 ecc[3] = (uint8_t) (ecc_tmp >> 24);
465
466 ecc_tmp = readl(&regs->bank_regs[bank].ecc2);
467 ecc[4] = (uint8_t) (ecc_tmp >> 0);
468 ecc[5] = (uint8_t) (ecc_tmp >> 8);
469 ecc[6] = (uint8_t) (ecc_tmp >> 16);
470 ecc[7] = (uint8_t) (ecc_tmp >> 24);
471
472 ecc_tmp = readl(&regs->bank_regs[bank].ecc3);
473 ecc[8] = (uint8_t) (ecc_tmp >> 0);
474 ecc[9] = (uint8_t) (ecc_tmp >> 8);
475 ecc[10] = (uint8_t) (ecc_tmp >> 16);
476 ecc[11] = (uint8_t) (ecc_tmp >> 24);
477
478 ecc_tmp = readl(&regs->bank_regs[bank].sts);
479 ecc[12] = (uint8_t) (ecc_tmp >> 16);
480
481 return 0;
482}
483
484/*
485 * fsmc_read_hwecc_ecc1 - Hardware ECC calculator for ecc1 option supported by
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300486 * FSMC. ECC is 3 bytes for 512 bytes of data (supports error correction up to
Linus Walleij6c009ab2010-09-13 00:35:22 +0200487 * max of 1-bit)
488 */
489static int fsmc_read_hwecc_ecc1(struct mtd_info *mtd, const uint8_t *data,
490 uint8_t *ecc)
491{
492 struct fsmc_nand_data *host = container_of(mtd,
493 struct fsmc_nand_data, mtd);
494 struct fsmc_regs *regs = host->regs_va;
495 uint32_t bank = host->bank;
496 uint32_t ecc_tmp;
497
498 ecc_tmp = readl(&regs->bank_regs[bank].ecc1);
499 ecc[0] = (uint8_t) (ecc_tmp >> 0);
500 ecc[1] = (uint8_t) (ecc_tmp >> 8);
501 ecc[2] = (uint8_t) (ecc_tmp >> 16);
502
503 return 0;
504}
505
Vipin Kumar519300c2012-03-07 17:00:49 +0530506/* Count the number of 0's in buff upto a max of max_bits */
507static int count_written_bits(uint8_t *buff, int size, int max_bits)
508{
509 int k, written_bits = 0;
510
511 for (k = 0; k < size; k++) {
512 written_bits += hweight8(~buff[k]);
513 if (written_bits > max_bits)
514 break;
515 }
516
517 return written_bits;
518}
519
Linus Walleij6c009ab2010-09-13 00:35:22 +0200520/*
521 * fsmc_read_page_hwecc
522 * @mtd: mtd info structure
523 * @chip: nand chip info structure
524 * @buf: buffer to store read data
525 * @page: page number to read
526 *
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300527 * This routine is needed for fsmc version 8 as reading from NAND chip has to be
Linus Walleij6c009ab2010-09-13 00:35:22 +0200528 * performed in a strict sequence as follows:
529 * data(512 byte) -> ecc(13 byte)
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300530 * After this read, fsmc hardware generates and reports error data bits(up to a
Linus Walleij6c009ab2010-09-13 00:35:22 +0200531 * max of 8 bits)
532 */
533static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip,
534 uint8_t *buf, int page)
535{
536 struct fsmc_nand_data *host = container_of(mtd,
537 struct fsmc_nand_data, mtd);
538 struct fsmc_eccplace *ecc_place = host->ecc_place;
539 int i, j, s, stat, eccsize = chip->ecc.size;
540 int eccbytes = chip->ecc.bytes;
541 int eccsteps = chip->ecc.steps;
542 uint8_t *p = buf;
543 uint8_t *ecc_calc = chip->buffers->ecccalc;
544 uint8_t *ecc_code = chip->buffers->ecccode;
545 int off, len, group = 0;
546 /*
547 * ecc_oob is intentionally taken as uint16_t. In 16bit devices, we
548 * end up reading 14 bytes (7 words) from oob. The local array is
549 * to maintain word alignment
550 */
551 uint16_t ecc_oob[7];
552 uint8_t *oob = (uint8_t *)&ecc_oob[0];
553
554 for (i = 0, s = 0; s < eccsteps; s++, i += eccbytes, p += eccsize) {
Linus Walleij6c009ab2010-09-13 00:35:22 +0200555 chip->cmdfunc(mtd, NAND_CMD_READ0, s * eccsize, page);
556 chip->ecc.hwctl(mtd, NAND_ECC_READ);
557 chip->read_buf(mtd, p, eccsize);
558
559 for (j = 0; j < eccbytes;) {
560 off = ecc_place->eccplace[group].offset;
561 len = ecc_place->eccplace[group].length;
562 group++;
563
564 /*
Vipin Kumar4cbe1bf02012-03-14 11:47:09 +0530565 * length is intentionally kept a higher multiple of 2
566 * to read at least 13 bytes even in case of 16 bit NAND
567 * devices
568 */
Vipin Kumaraea686b2012-03-14 11:47:10 +0530569 if (chip->options & NAND_BUSWIDTH_16)
570 len = roundup(len, 2);
571
Linus Walleij6c009ab2010-09-13 00:35:22 +0200572 chip->cmdfunc(mtd, NAND_CMD_READOOB, off, page);
573 chip->read_buf(mtd, oob + j, len);
574 j += len;
575 }
576
Vipin Kumar519300c2012-03-07 17:00:49 +0530577 memcpy(&ecc_code[i], oob, chip->ecc.bytes);
Linus Walleij6c009ab2010-09-13 00:35:22 +0200578 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
579
580 stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
581 if (stat < 0)
582 mtd->ecc_stats.failed++;
583 else
584 mtd->ecc_stats.corrected += stat;
585 }
586
587 return 0;
588}
589
590/*
Armando Visconti753e0132012-03-07 17:00:54 +0530591 * fsmc_bch8_correct_data
Linus Walleij6c009ab2010-09-13 00:35:22 +0200592 * @mtd: mtd info structure
593 * @dat: buffer of read data
594 * @read_ecc: ecc read from device spare area
595 * @calc_ecc: ecc calculated from read data
596 *
597 * calc_ecc is a 104 bit information containing maximum of 8 error
598 * offset informations of 13 bits each in 512 bytes of read data.
599 */
Armando Visconti753e0132012-03-07 17:00:54 +0530600static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat,
Linus Walleij6c009ab2010-09-13 00:35:22 +0200601 uint8_t *read_ecc, uint8_t *calc_ecc)
602{
603 struct fsmc_nand_data *host = container_of(mtd,
604 struct fsmc_nand_data, mtd);
Vipin Kumar519300c2012-03-07 17:00:49 +0530605 struct nand_chip *chip = mtd->priv;
Linus Walleij6c009ab2010-09-13 00:35:22 +0200606 struct fsmc_regs *regs = host->regs_va;
607 unsigned int bank = host->bank;
Armando Viscontia612c2a2012-03-07 17:00:53 +0530608 uint32_t err_idx[8];
Linus Walleij6c009ab2010-09-13 00:35:22 +0200609 uint32_t num_err, i;
Armando Visconti753e0132012-03-07 17:00:54 +0530610 uint32_t ecc1, ecc2, ecc3, ecc4;
Linus Walleij6c009ab2010-09-13 00:35:22 +0200611
Vipin Kumar519300c2012-03-07 17:00:49 +0530612 num_err = (readl(&regs->bank_regs[bank].sts) >> 10) & 0xF;
613
614 /* no bit flipping */
615 if (likely(num_err == 0))
616 return 0;
617
618 /* too many errors */
619 if (unlikely(num_err > 8)) {
620 /*
621 * This is a temporary erase check. A newly erased page read
622 * would result in an ecc error because the oob data is also
623 * erased to FF and the calculated ecc for an FF data is not
624 * FF..FF.
625 * This is a workaround to skip performing correction in case
626 * data is FF..FF
627 *
628 * Logic:
629 * For every page, each bit written as 0 is counted until these
630 * number of bits are greater than 8 (the maximum correction
631 * capability of FSMC for each 512 + 13 bytes)
632 */
633
634 int bits_ecc = count_written_bits(read_ecc, chip->ecc.bytes, 8);
635 int bits_data = count_written_bits(dat, chip->ecc.size, 8);
636
637 if ((bits_ecc + bits_data) <= 8) {
638 if (bits_data)
639 memset(dat, 0xff, chip->ecc.size);
640 return bits_data;
641 }
642
643 return -EBADMSG;
644 }
645
Linus Walleij6c009ab2010-09-13 00:35:22 +0200646 /*
647 * ------------------- calc_ecc[] bit wise -----------|--13 bits--|
648 * |---idx[7]--|--.....-----|---idx[2]--||---idx[1]--||---idx[0]--|
649 *
650 * calc_ecc is a 104 bit information containing maximum of 8 error
651 * offset informations of 13 bits each. calc_ecc is copied into a
652 * uint64_t array and error offset indexes are populated in err_idx
653 * array
654 */
Armando Visconti753e0132012-03-07 17:00:54 +0530655 ecc1 = readl(&regs->bank_regs[bank].ecc1);
656 ecc2 = readl(&regs->bank_regs[bank].ecc2);
657 ecc3 = readl(&regs->bank_regs[bank].ecc3);
658 ecc4 = readl(&regs->bank_regs[bank].sts);
Linus Walleij6c009ab2010-09-13 00:35:22 +0200659
Armando Visconti753e0132012-03-07 17:00:54 +0530660 err_idx[0] = (ecc1 >> 0) & 0x1FFF;
661 err_idx[1] = (ecc1 >> 13) & 0x1FFF;
662 err_idx[2] = (((ecc2 >> 0) & 0x7F) << 6) | ((ecc1 >> 26) & 0x3F);
663 err_idx[3] = (ecc2 >> 7) & 0x1FFF;
664 err_idx[4] = (((ecc3 >> 0) & 0x1) << 12) | ((ecc2 >> 20) & 0xFFF);
665 err_idx[5] = (ecc3 >> 1) & 0x1FFF;
666 err_idx[6] = (ecc3 >> 14) & 0x1FFF;
667 err_idx[7] = (((ecc4 >> 16) & 0xFF) << 5) | ((ecc3 >> 27) & 0x1F);
Linus Walleij6c009ab2010-09-13 00:35:22 +0200668
669 i = 0;
670 while (num_err--) {
671 change_bit(0, (unsigned long *)&err_idx[i]);
672 change_bit(1, (unsigned long *)&err_idx[i]);
673
Vipin Kumarb533f8d2012-03-14 11:47:11 +0530674 if (err_idx[i] < chip->ecc.size * 8) {
Linus Walleij6c009ab2010-09-13 00:35:22 +0200675 change_bit(err_idx[i], (unsigned long *)dat);
676 i++;
677 }
678 }
679 return i;
680}
681
682/*
683 * fsmc_nand_probe - Probe function
684 * @pdev: platform device structure
685 */
686static int __init fsmc_nand_probe(struct platform_device *pdev)
687{
688 struct fsmc_nand_platform_data *pdata = dev_get_platdata(&pdev->dev);
689 struct fsmc_nand_data *host;
690 struct mtd_info *mtd;
691 struct nand_chip *nand;
692 struct fsmc_regs *regs;
693 struct resource *res;
Linus Walleij4ad916b2010-11-29 13:52:06 +0100694 int ret = 0;
Linus Walleij593cd872010-11-29 13:52:19 +0100695 u32 pid;
696 int i;
Linus Walleij6c009ab2010-09-13 00:35:22 +0200697
698 if (!pdata) {
699 dev_err(&pdev->dev, "platform data is NULL\n");
700 return -EINVAL;
701 }
702
703 /* Allocate memory for the device structure (and zero it) */
Vipin Kumar82b9dbe2012-03-14 11:47:15 +0530704 host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL);
Linus Walleij6c009ab2010-09-13 00:35:22 +0200705 if (!host) {
706 dev_err(&pdev->dev, "failed to allocate device structure\n");
707 return -ENOMEM;
708 }
709
710 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_data");
Vipin Kumar82b9dbe2012-03-14 11:47:15 +0530711 if (!res)
712 return -EINVAL;
713
714 if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
715 pdev->name)) {
716 dev_err(&pdev->dev, "Failed to get memory data resourse\n");
717 return -ENOENT;
Linus Walleij6c009ab2010-09-13 00:35:22 +0200718 }
719
Vipin Kumar82b9dbe2012-03-14 11:47:15 +0530720 host->data_va = devm_ioremap(&pdev->dev, res->start,
721 resource_size(res));
Linus Walleij6c009ab2010-09-13 00:35:22 +0200722 if (!host->data_va) {
Vipin Kumar82b9dbe2012-03-14 11:47:15 +0530723 dev_err(&pdev->dev, "data ioremap failed\n");
724 return -ENOMEM;
Linus Walleij6c009ab2010-09-13 00:35:22 +0200725 }
726
Vipin Kumar82b9dbe2012-03-14 11:47:15 +0530727 if (!devm_request_mem_region(&pdev->dev, res->start + pdata->ale_off,
728 resource_size(res), pdev->name)) {
729 dev_err(&pdev->dev, "Failed to get memory ale resourse\n");
730 return -ENOENT;
Linus Walleij6c009ab2010-09-13 00:35:22 +0200731 }
732
Vipin Kumar82b9dbe2012-03-14 11:47:15 +0530733 host->addr_va = devm_ioremap(&pdev->dev, res->start + pdata->ale_off,
Shiraz Hashimb2acc922012-03-07 17:00:51 +0530734 resource_size(res));
Linus Walleij6c009ab2010-09-13 00:35:22 +0200735 if (!host->addr_va) {
Vipin Kumar82b9dbe2012-03-14 11:47:15 +0530736 dev_err(&pdev->dev, "ale ioremap failed\n");
737 return -ENOMEM;
Linus Walleij6c009ab2010-09-13 00:35:22 +0200738 }
739
Vipin Kumar82b9dbe2012-03-14 11:47:15 +0530740 if (!devm_request_mem_region(&pdev->dev, res->start + pdata->cle_off,
741 resource_size(res), pdev->name)) {
742 dev_err(&pdev->dev, "Failed to get memory cle resourse\n");
743 return -ENOENT;
Linus Walleij6c009ab2010-09-13 00:35:22 +0200744 }
745
Vipin Kumar82b9dbe2012-03-14 11:47:15 +0530746 host->cmd_va = devm_ioremap(&pdev->dev, res->start + pdata->cle_off,
747 resource_size(res));
Linus Walleij6c009ab2010-09-13 00:35:22 +0200748 if (!host->cmd_va) {
Vipin Kumar82b9dbe2012-03-14 11:47:15 +0530749 dev_err(&pdev->dev, "ale ioremap failed\n");
750 return -ENOMEM;
Linus Walleij6c009ab2010-09-13 00:35:22 +0200751 }
752
753 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fsmc_regs");
Vipin Kumar82b9dbe2012-03-14 11:47:15 +0530754 if (!res)
755 return -EINVAL;
756
757 if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
758 pdev->name)) {
759 dev_err(&pdev->dev, "Failed to get memory regs resourse\n");
760 return -ENOENT;
Linus Walleij6c009ab2010-09-13 00:35:22 +0200761 }
762
Vipin Kumar82b9dbe2012-03-14 11:47:15 +0530763 host->regs_va = devm_ioremap(&pdev->dev, res->start,
764 resource_size(res));
Linus Walleij6c009ab2010-09-13 00:35:22 +0200765 if (!host->regs_va) {
Vipin Kumar82b9dbe2012-03-14 11:47:15 +0530766 dev_err(&pdev->dev, "regs ioremap failed\n");
767 return -ENOMEM;
Linus Walleij6c009ab2010-09-13 00:35:22 +0200768 }
769
770 host->clk = clk_get(&pdev->dev, NULL);
771 if (IS_ERR(host->clk)) {
772 dev_err(&pdev->dev, "failed to fetch block clock\n");
Vipin Kumar82b9dbe2012-03-14 11:47:15 +0530773 return PTR_ERR(host->clk);
Linus Walleij6c009ab2010-09-13 00:35:22 +0200774 }
775
776 ret = clk_enable(host->clk);
777 if (ret)
Vipin Kumar82b9dbe2012-03-14 11:47:15 +0530778 goto err_clk_enable;
Linus Walleij6c009ab2010-09-13 00:35:22 +0200779
Linus Walleij593cd872010-11-29 13:52:19 +0100780 /*
781 * This device ID is actually a common AMBA ID as used on the
782 * AMBA PrimeCell bus. However it is not a PrimeCell.
783 */
784 for (pid = 0, i = 0; i < 4; i++)
785 pid |= (readl(host->regs_va + resource_size(res) - 0x20 + 4 * i) & 255) << (i * 8);
786 host->pid = pid;
787 dev_info(&pdev->dev, "FSMC device partno %03x, manufacturer %02x, "
788 "revision %02x, config %02x\n",
789 AMBA_PART_BITS(pid), AMBA_MANF_BITS(pid),
790 AMBA_REV_BITS(pid), AMBA_CONFIG_BITS(pid));
791
Linus Walleij6c009ab2010-09-13 00:35:22 +0200792 host->bank = pdata->bank;
793 host->select_chip = pdata->select_bank;
Vipin Kumar71470322012-03-14 11:47:07 +0530794 host->partitions = pdata->partitions;
795 host->nr_partitions = pdata->nr_partitions;
Vipin Kumare2f6bce2012-03-14 11:47:14 +0530796 host->dev_timings = pdata->nand_timings;
Linus Walleij6c009ab2010-09-13 00:35:22 +0200797 regs = host->regs_va;
798
799 /* Link all private pointers */
800 mtd = &host->mtd;
801 nand = &host->nand;
802 mtd->priv = nand;
803 nand->priv = host;
804
805 host->mtd.owner = THIS_MODULE;
806 nand->IO_ADDR_R = host->data_va;
807 nand->IO_ADDR_W = host->data_va;
808 nand->cmd_ctrl = fsmc_cmd_ctrl;
809 nand->chip_delay = 30;
810
811 nand->ecc.mode = NAND_ECC_HW;
812 nand->ecc.hwctl = fsmc_enable_hwecc;
813 nand->ecc.size = 512;
814 nand->options = pdata->options;
815 nand->select_chip = fsmc_select_chip;
Vipin Kumar467e6e72012-03-14 11:47:12 +0530816 nand->badblockbits = 7;
Linus Walleij6c009ab2010-09-13 00:35:22 +0200817
818 if (pdata->width == FSMC_NAND_BW16)
819 nand->options |= NAND_BUSWIDTH_16;
820
Vipin Kumare2f6bce2012-03-14 11:47:14 +0530821 fsmc_nand_setup(regs, host->bank, nand->options & NAND_BUSWIDTH_16,
822 host->dev_timings);
Linus Walleij6c009ab2010-09-13 00:35:22 +0200823
Linus Walleij593cd872010-11-29 13:52:19 +0100824 if (AMBA_REV_BITS(host->pid) >= 8) {
Linus Walleij6c009ab2010-09-13 00:35:22 +0200825 nand->ecc.read_page = fsmc_read_page_hwecc;
826 nand->ecc.calculate = fsmc_read_hwecc_ecc4;
Armando Visconti753e0132012-03-07 17:00:54 +0530827 nand->ecc.correct = fsmc_bch8_correct_data;
Linus Walleij6c009ab2010-09-13 00:35:22 +0200828 nand->ecc.bytes = 13;
Mike Dunn6a918ba2012-03-11 14:21:11 -0700829 nand->ecc.strength = 8;
Linus Walleij6c009ab2010-09-13 00:35:22 +0200830 } else {
831 nand->ecc.calculate = fsmc_read_hwecc_ecc1;
832 nand->ecc.correct = nand_correct_data;
833 nand->ecc.bytes = 3;
Mike Dunn6a918ba2012-03-11 14:21:11 -0700834 nand->ecc.strength = 1;
Linus Walleij6c009ab2010-09-13 00:35:22 +0200835 }
836
837 /*
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300838 * Scan to find existence of the device
Linus Walleij6c009ab2010-09-13 00:35:22 +0200839 */
840 if (nand_scan_ident(&host->mtd, 1, NULL)) {
841 ret = -ENXIO;
842 dev_err(&pdev->dev, "No NAND Device found!\n");
Vipin Kumar82b9dbe2012-03-14 11:47:15 +0530843 goto err_scan_ident;
Linus Walleij6c009ab2010-09-13 00:35:22 +0200844 }
845
Linus Walleij593cd872010-11-29 13:52:19 +0100846 if (AMBA_REV_BITS(host->pid) >= 8) {
Bhavna Yadave29ee572012-03-07 17:00:50 +0530847 switch (host->mtd.oobsize) {
848 case 16:
849 nand->ecc.layout = &fsmc_ecc4_16_layout;
Linus Walleij6c009ab2010-09-13 00:35:22 +0200850 host->ecc_place = &fsmc_ecc4_sp_place;
Bhavna Yadave29ee572012-03-07 17:00:50 +0530851 break;
852 case 64:
853 nand->ecc.layout = &fsmc_ecc4_64_layout;
Linus Walleij6c009ab2010-09-13 00:35:22 +0200854 host->ecc_place = &fsmc_ecc4_lp_place;
Bhavna Yadave29ee572012-03-07 17:00:50 +0530855 break;
856 case 128:
857 nand->ecc.layout = &fsmc_ecc4_128_layout;
858 host->ecc_place = &fsmc_ecc4_lp_place;
859 break;
Armando Visconti0c78e932012-03-07 17:00:55 +0530860 case 224:
861 nand->ecc.layout = &fsmc_ecc4_224_layout;
862 host->ecc_place = &fsmc_ecc4_lp_place;
863 break;
Bhavna Yadave29ee572012-03-07 17:00:50 +0530864 case 256:
865 nand->ecc.layout = &fsmc_ecc4_256_layout;
866 host->ecc_place = &fsmc_ecc4_lp_place;
867 break;
868 default:
869 printk(KERN_WARNING "No oob scheme defined for "
870 "oobsize %d\n", mtd->oobsize);
871 BUG();
Linus Walleij6c009ab2010-09-13 00:35:22 +0200872 }
873 } else {
Bhavna Yadave29ee572012-03-07 17:00:50 +0530874 switch (host->mtd.oobsize) {
875 case 16:
876 nand->ecc.layout = &fsmc_ecc1_16_layout;
877 break;
878 case 64:
879 nand->ecc.layout = &fsmc_ecc1_64_layout;
880 break;
881 case 128:
882 nand->ecc.layout = &fsmc_ecc1_128_layout;
883 break;
884 default:
885 printk(KERN_WARNING "No oob scheme defined for "
886 "oobsize %d\n", mtd->oobsize);
887 BUG();
888 }
Linus Walleij6c009ab2010-09-13 00:35:22 +0200889 }
890
891 /* Second stage of scan to fill MTD data-structures */
892 if (nand_scan_tail(&host->mtd)) {
893 ret = -ENXIO;
894 goto err_probe;
895 }
896
897 /*
898 * The partition information can is accessed by (in the same precedence)
899 *
900 * command line through Bootloader,
901 * platform data,
902 * default partition information present in driver.
903 */
Linus Walleij6c009ab2010-09-13 00:35:22 +0200904 /*
Dmitry Eremin-Solenikov8d3f8bb2011-05-29 20:16:57 +0400905 * Check for partition info passed
Linus Walleij6c009ab2010-09-13 00:35:22 +0200906 */
907 host->mtd.name = "nand";
Artem Bityutskiy42d7fbe2012-03-09 19:24:26 +0200908 ret = mtd_device_parse_register(&host->mtd, NULL, NULL,
Vipin Kumar71470322012-03-14 11:47:07 +0530909 host->partitions, host->nr_partitions);
Jamie Iles99335d02011-05-23 10:23:23 +0100910 if (ret)
Linus Walleij6c009ab2010-09-13 00:35:22 +0200911 goto err_probe;
Linus Walleij6c009ab2010-09-13 00:35:22 +0200912
913 platform_set_drvdata(pdev, host);
914 dev_info(&pdev->dev, "FSMC NAND driver registration successful\n");
915 return 0;
916
917err_probe:
Vipin Kumar82b9dbe2012-03-14 11:47:15 +0530918err_scan_ident:
Linus Walleij6c009ab2010-09-13 00:35:22 +0200919 clk_disable(host->clk);
Vipin Kumar82b9dbe2012-03-14 11:47:15 +0530920err_clk_enable:
921 clk_put(host->clk);
Linus Walleij6c009ab2010-09-13 00:35:22 +0200922 return ret;
923}
924
925/*
926 * Clean up routine
927 */
928static int fsmc_nand_remove(struct platform_device *pdev)
929{
930 struct fsmc_nand_data *host = platform_get_drvdata(pdev);
931
932 platform_set_drvdata(pdev, NULL);
933
934 if (host) {
Axel Lin82e023a2011-06-03 13:15:30 +0800935 nand_release(&host->mtd);
Linus Walleij6c009ab2010-09-13 00:35:22 +0200936 clk_disable(host->clk);
937 clk_put(host->clk);
Linus Walleij6c009ab2010-09-13 00:35:22 +0200938 }
Vipin Kumar82b9dbe2012-03-14 11:47:15 +0530939
Linus Walleij6c009ab2010-09-13 00:35:22 +0200940 return 0;
941}
942
943#ifdef CONFIG_PM
944static int fsmc_nand_suspend(struct device *dev)
945{
946 struct fsmc_nand_data *host = dev_get_drvdata(dev);
947 if (host)
948 clk_disable(host->clk);
949 return 0;
950}
951
952static int fsmc_nand_resume(struct device *dev)
953{
954 struct fsmc_nand_data *host = dev_get_drvdata(dev);
Shiraz Hashimf63acb72012-03-14 11:47:13 +0530955 if (host) {
Linus Walleij6c009ab2010-09-13 00:35:22 +0200956 clk_enable(host->clk);
Shiraz Hashimf63acb72012-03-14 11:47:13 +0530957 fsmc_nand_setup(host->regs_va, host->bank,
Vipin Kumare2f6bce2012-03-14 11:47:14 +0530958 host->nand.options & NAND_BUSWIDTH_16,
959 host->dev_timings);
Shiraz Hashimf63acb72012-03-14 11:47:13 +0530960 }
Linus Walleij6c009ab2010-09-13 00:35:22 +0200961 return 0;
962}
963
Shiraz Hashimf63acb72012-03-14 11:47:13 +0530964static SIMPLE_DEV_PM_OPS(fsmc_nand_pm_ops, fsmc_nand_suspend, fsmc_nand_resume);
Linus Walleij6c009ab2010-09-13 00:35:22 +0200965#endif
966
967static struct platform_driver fsmc_nand_driver = {
968 .remove = fsmc_nand_remove,
969 .driver = {
970 .owner = THIS_MODULE,
971 .name = "fsmc-nand",
972#ifdef CONFIG_PM
973 .pm = &fsmc_nand_pm_ops,
974#endif
975 },
976};
977
978static int __init fsmc_nand_init(void)
979{
980 return platform_driver_probe(&fsmc_nand_driver,
981 fsmc_nand_probe);
982}
983module_init(fsmc_nand_init);
984
985static void __exit fsmc_nand_exit(void)
986{
987 platform_driver_unregister(&fsmc_nand_driver);
988}
989module_exit(fsmc_nand_exit);
990
991MODULE_LICENSE("GPL");
992MODULE_AUTHOR("Vipin Kumar <vipin.kumar@st.com>, Ashish Priyadarshi");
993MODULE_DESCRIPTION("NAND driver for SPEAr Platforms");