diff options
Diffstat (limited to 'meta/packages/linux/linux-cmx270-2.6.17/mtd_fixes-r0.patch')
-rw-r--r-- | meta/packages/linux/linux-cmx270-2.6.17/mtd_fixes-r0.patch | 599 |
1 files changed, 599 insertions, 0 deletions
diff --git a/meta/packages/linux/linux-cmx270-2.6.17/mtd_fixes-r0.patch b/meta/packages/linux/linux-cmx270-2.6.17/mtd_fixes-r0.patch new file mode 100644 index 0000000000..d77e9d8fbd --- /dev/null +++ b/meta/packages/linux/linux-cmx270-2.6.17/mtd_fixes-r0.patch | |||
@@ -0,0 +1,599 @@ | |||
1 | Index: linux-2.6.17/drivers/mtd/nand/cm-x270.c | ||
2 | =================================================================== | ||
3 | --- linux-2.6.17.orig/drivers/mtd/nand/cm-x270.c 2006-07-18 15:40:10.000000000 +0100 | ||
4 | +++ linux-2.6.17/drivers/mtd/nand/cm-x270.c 2006-07-19 15:35:18.000000000 +0100 | ||
5 | @@ -1,7 +1,13 @@ | ||
6 | /* | ||
7 | - * drivers/mtd/nand/cm-x270.c | ||
8 | + * linux/drivers/mtd/nand/cmx270-nand.c | ||
9 | + * | ||
10 | + * Copyright (C) 2006 Compulab, Ltd. | ||
11 | + * Mike Rapoport <mike@compulab.co.il> | ||
12 | + * | ||
13 | + * Derived from drivers/mtd/nand/h1910.c | ||
14 | + * Copyright (C) 2002 Marius Gröger (mag@sysgo.de) | ||
15 | + * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) | ||
16 | * | ||
17 | - * Copyright (c) 2006, 8D Technologies inc. | ||
18 | * | ||
19 | * This program is free software; you can redistribute it and/or modify | ||
20 | * it under the terms of the GNU General Public License version 2 as | ||
21 | @@ -9,397 +15,269 @@ | ||
22 | * | ||
23 | * Overview: | ||
24 | * This is a device driver for the NAND flash device found on the | ||
25 | - * cm-x270 compulab SBC. | ||
26 | - * | ||
27 | - * Changelog: | ||
28 | - * - April 2006, Raphael Assenat <raph@8d.com>: | ||
29 | - * Creation of the driver. | ||
30 | + * CM-X270 board. | ||
31 | */ | ||
32 | |||
33 | -#include <linux/delay.h> | ||
34 | +#include <linux/slab.h> | ||
35 | +#include <linux/init.h> | ||
36 | +#include <linux/module.h> | ||
37 | #include <linux/mtd/mtd.h> | ||
38 | #include <linux/mtd/nand.h> | ||
39 | #include <linux/mtd/partitions.h> | ||
40 | -#include <asm/hardware.h> | ||
41 | + | ||
42 | #include <asm/io.h> | ||
43 | +#include <asm/irq.h> | ||
44 | + | ||
45 | +#include <asm/arch/hardware.h> | ||
46 | #include <asm/arch/pxa-regs.h> | ||
47 | -#include <asm/arch/cm-x270.h> | ||
48 | |||
49 | +#define GPIO_NAND_CS (11) | ||
50 | +#define GPIO_NAND_RB (89) | ||
51 | |||
52 | -static struct mtd_info *cmx270_mtd = NULL; | ||
53 | -static void *cmx270_nand_io_base; | ||
54 | -#define OFFSET_BASE 0 | ||
55 | -#define OFFSET_CLE 4 | ||
56 | -#define OFFSET_ALE 8 | ||
57 | - | ||
58 | -#define DEFAULT_NUM_PARTITIONS 1 | ||
59 | -static int nr_partitions; | ||
60 | -static struct mtd_partition cmx270_default_partition_info[] = { | ||
61 | - { | ||
62 | - .name = "rootfs", | ||
63 | - .offset = 0, | ||
64 | - .size = MTDPART_SIZ_FULL, | ||
65 | - }, | ||
66 | -}; | ||
67 | +/* This macro needed to ensure in-order operation of GPIO and local | ||
68 | + * bus. Without both asm command and dummy uncached read there're | ||
69 | + * states when NAND access is broken. I've looked for such macro(s) in | ||
70 | + * include/asm-arm but found nothing approptiate. | ||
71 | + * dmac_clean_range is close, but is makes cache invalidation | ||
72 | + * unnecessary here and it cannot be used in module | ||
73 | + */ | ||
74 | +#define DRAIN_WB() \ | ||
75 | + do { \ | ||
76 | + unsigned char dummy; \ | ||
77 | + asm volatile ("mcr p15, 0, r0, c7, c10, 4":::"r0"); \ | ||
78 | + dummy=*((unsigned char*)UNCACHED_ADDR); \ | ||
79 | + } while(0) | ||
80 | |||
81 | -static void cmx270_nand_hwcontrol(struct mtd_info *mtd, int cmd) | ||
82 | -{ | ||
83 | - udelay(1); | ||
84 | - switch(cmd) | ||
85 | +/* MTD structure for CM-X270 board */ | ||
86 | +static struct mtd_info *cmx270_nand_mtd; | ||
87 | + | ||
88 | +/* remaped IO address of the device */ | ||
89 | +static void __iomem *cmx270_nand_io; | ||
90 | + | ||
91 | +/* | ||
92 | + * Define static partitions for flash device | ||
93 | + */ | ||
94 | +static struct mtd_partition partition_info[] = { | ||
95 | { | ||
96 | - case NAND_CTL_SETNCE: | ||
97 | - GPCR(CM_X270_GPIO_NAND_CS) = GPIO_bit(CM_X270_GPIO_NAND_CS); | ||
98 | - break; | ||
99 | - case NAND_CTL_CLRNCE: | ||
100 | - GPSR(CM_X270_GPIO_NAND_CS) = GPIO_bit(CM_X270_GPIO_NAND_CS); | ||
101 | - break; | ||
102 | + .name = "cmx270-0", | ||
103 | + .offset = 0, | ||
104 | + .size = MTDPART_SIZ_FULL | ||
105 | } | ||
106 | - udelay(1); | ||
107 | -} | ||
108 | - | ||
109 | -static int cmx270_nand_device_ready(struct mtd_info *mtd) | ||
110 | -{ | ||
111 | - /* I was getting ecc errors on reads, but adding this delay | ||
112 | - made the problem disappear. There is probably a timing | ||
113 | - issue somewhere. */ | ||
114 | - //ndelay (500); | ||
115 | - udelay (25); | ||
116 | +}; | ||
117 | +#define NUM_PARTITIONS (ARRAY_SIZE(partition_info)) | ||
118 | |||
119 | - return GPLR(CM_X270_GPIO_NAND_RB) & GPIO_bit(CM_X270_GPIO_NAND_RB); | ||
120 | -} | ||
121 | +const char *part_probes[] = { "cmdlinepart", NULL }; | ||
122 | |||
123 | -static u_char cmx270_nand_read_byte(struct mtd_info *mtd) | ||
124 | +static u_char cmx270_read_byte(struct mtd_info *mtd) | ||
125 | { | ||
126 | struct nand_chip *this = mtd->priv; | ||
127 | -// unsigned long raw = readl(this->IO_ADDR_R); | ||
128 | - unsigned char res = ( readl(this->IO_ADDR_R) >> 16 ) & 0xff; | ||
129 | - return res; | ||
130 | -} | ||
131 | |||
132 | -static void cmx270_nand_write_byte(struct mtd_info *mtd, u_char byte) | ||
133 | -{ | ||
134 | - struct nand_chip *this = mtd->priv; | ||
135 | - writel( (byte<<16), this->IO_ADDR_W ); | ||
136 | - udelay(1); | ||
137 | + return (readl(this->IO_ADDR_R) >> 16); | ||
138 | } | ||
139 | |||
140 | -static void cmx270_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) | ||
141 | +static void cmx270_write_buf(struct mtd_info *mtd, const u_char *buf, int len) | ||
142 | { | ||
143 | int i; | ||
144 | struct nand_chip *this = mtd->priv; | ||
145 | |||
146 | for (i=0; i<len; i++) | ||
147 | - writel((buf[i]<<16), this->IO_ADDR_W); | ||
148 | - udelay(1); | ||
149 | + writel((*buf++ << 16), this->IO_ADDR_W); | ||
150 | } | ||
151 | |||
152 | -static void cmx270_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) | ||
153 | +static void cmx270_read_buf(struct mtd_info *mtd, u_char *buf, int len) | ||
154 | { | ||
155 | int i; | ||
156 | struct nand_chip *this = mtd->priv; | ||
157 | |||
158 | for (i=0; i<len; i++) | ||
159 | - buf[i] = (readl(this->IO_ADDR_R) >> 16 ) & 0xff; | ||
160 | - udelay(1); | ||
161 | + *buf++ = readl(this->IO_ADDR_R) >> 16; | ||
162 | } | ||
163 | |||
164 | -static int cmx270_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) | ||
165 | +static int cmx270_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) | ||
166 | { | ||
167 | int i; | ||
168 | struct nand_chip *this = mtd->priv; | ||
169 | |||
170 | for (i=0; i<len; i++) | ||
171 | - if (buf[i] != ((readl(this->IO_ADDR_R) >> 16) & 0xff)) | ||
172 | + if (buf[i] != (u_char)(readl(this->IO_ADDR_R) >> 16)) | ||
173 | return -EFAULT; | ||
174 | - udelay(1); | ||
175 | |||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | -static void cmx270_nand_write_ALE(struct mtd_info *mtd, const u_char byte) | ||
180 | +static inline void nand_cs_on(void) | ||
181 | { | ||
182 | - struct nand_chip *this = mtd->priv; | ||
183 | - writel( byte << 16 , this->IO_ADDR_W + OFFSET_ALE); | ||
184 | - udelay(1); | ||
185 | + GPCR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS); | ||
186 | } | ||
187 | |||
188 | -static void cmx270_nand_write_CLE(struct mtd_info *mtd, const u_char byte) | ||
189 | +static void nand_cs_off(void) | ||
190 | { | ||
191 | - struct nand_chip *this = mtd->priv; | ||
192 | - writel( byte << 16 , this->IO_ADDR_W + OFFSET_CLE); | ||
193 | - udelay(1); | ||
194 | + DRAIN_WB(); | ||
195 | + | ||
196 | + GPSR(GPIO_NAND_CS) = GPIO_bit(GPIO_NAND_CS); | ||
197 | } | ||
198 | |||
199 | -/* Same as nand_core:nand_command() but with different memory | ||
200 | - * addresses for writing to ALE and CLE and without 16 bit support. | ||
201 | +/* | ||
202 | + * hardware specific access to control-lines | ||
203 | */ | ||
204 | -static void cmx270_nand_command(struct mtd_info *mtd, unsigned command, int column, int page_addr) | ||
205 | +static void cmx270_hwcontrol(struct mtd_info *mtd, int cmd) | ||
206 | { | ||
207 | - register struct nand_chip *this = mtd->priv; | ||
208 | + struct nand_chip* this = (struct nand_chip *) (mtd->priv); | ||
209 | + unsigned int nandaddr = (unsigned int)this->IO_ADDR_R; | ||
210 | |||
211 | -// printk("cmd: 0x%02x col: 0x%x page_addr: 0x%x\n", | ||
212 | -// command, column, page_addr); | ||
213 | - | ||
214 | - if (command == NAND_CMD_SEQIN) { | ||
215 | - int readcmd; | ||
216 | - | ||
217 | - if (column >= mtd->oobblock) { | ||
218 | - /* OOB area */ | ||
219 | - column -= mtd->oobblock; | ||
220 | - readcmd = NAND_CMD_READOOB; | ||
221 | - } else if (column < 256) { | ||
222 | - /* First 256 bytes --> READ0 */ | ||
223 | - readcmd = NAND_CMD_READ0; | ||
224 | - } else { | ||
225 | - column -= 256; | ||
226 | - readcmd = NAND_CMD_READ1; | ||
227 | - } | ||
228 | - cmx270_nand_write_CLE(mtd, readcmd); | ||
229 | - } | ||
230 | - cmx270_nand_write_CLE(mtd, command); | ||
231 | + DRAIN_WB(); | ||
232 | |||
233 | - if (column != -1 || page_addr != -1) { | ||
234 | - | ||
235 | - /* Serially input address */ | ||
236 | - if (column != -1) { | ||
237 | - cmx270_nand_write_ALE(mtd, column); | ||
238 | - } | ||
239 | - if (page_addr != -1) { | ||
240 | - cmx270_nand_write_ALE(mtd, (unsigned char) (page_addr & 0xff)); | ||
241 | - cmx270_nand_write_ALE(mtd, (unsigned char) ((page_addr >> 8) & 0xff)); | ||
242 | - /* One more address cycle for devices > 32MiB */ | ||
243 | - if (this->chipsize > (32 << 20)) | ||
244 | - cmx270_nand_write_ALE(mtd, (unsigned char) ((page_addr >> 16) & 0x0f)); | ||
245 | - } | ||
246 | - } | ||
247 | + switch(cmd) { | ||
248 | |||
249 | - /* | ||
250 | - * program and erase have their own busy handlers | ||
251 | - * status and sequential in needs no delay | ||
252 | - */ | ||
253 | - switch (command) { | ||
254 | - | ||
255 | - case NAND_CMD_PAGEPROG: | ||
256 | - case NAND_CMD_ERASE1: | ||
257 | - case NAND_CMD_ERASE2: | ||
258 | - case NAND_CMD_SEQIN: | ||
259 | - case NAND_CMD_STATUS: | ||
260 | - return; | ||
261 | - | ||
262 | - case NAND_CMD_RESET: | ||
263 | - if (this->dev_ready) | ||
264 | - break; | ||
265 | - udelay(this->chip_delay); | ||
266 | - cmx270_nand_write_CLE(mtd, NAND_CMD_STATUS); | ||
267 | - while ( !(this->read_byte(mtd) & 0x40)); | ||
268 | - return; | ||
269 | - | ||
270 | - /* This applies to read commands */ | ||
271 | - default: | ||
272 | - /* | ||
273 | - * If we don't have access to the busy pin, we apply the given | ||
274 | - * command delay | ||
275 | - */ | ||
276 | - if (!this->dev_ready) { | ||
277 | - udelay(this->chip_delay); | ||
278 | - return; | ||
279 | - } | ||
280 | - } | ||
281 | - | ||
282 | - /* Apply this short delay always to ensure that we do wait tWB in | ||
283 | - * any case on any machine. */ | ||
284 | - ndelay (100); | ||
285 | - /* wait until command is processed */ | ||
286 | - while (!this->dev_ready(mtd)); | ||
287 | - ndelay (100); | ||
288 | + case NAND_CTL_SETCLE: | ||
289 | + nandaddr |= (1 << 2); | ||
290 | + this->IO_ADDR_R = (void __iomem*)nandaddr; | ||
291 | + this->IO_ADDR_W = (void __iomem*)nandaddr; | ||
292 | + break; | ||
293 | + case NAND_CTL_CLRCLE: | ||
294 | + nandaddr &= ~(1 << 2); | ||
295 | + this->IO_ADDR_R = (void __iomem*)nandaddr; | ||
296 | + this->IO_ADDR_W = (void __iomem*)nandaddr; | ||
297 | + break; | ||
298 | + | ||
299 | + case NAND_CTL_SETALE: | ||
300 | + nandaddr |= (1 << 3); | ||
301 | + this->IO_ADDR_R = (void __iomem*)nandaddr; | ||
302 | + this->IO_ADDR_W = (void __iomem*)nandaddr; | ||
303 | + break; | ||
304 | + case NAND_CTL_CLRALE: | ||
305 | + nandaddr &= ~(1 << 3); | ||
306 | + this->IO_ADDR_R = (void __iomem*)nandaddr; | ||
307 | + this->IO_ADDR_W = (void __iomem*)nandaddr; | ||
308 | + break; | ||
309 | + | ||
310 | + case NAND_CTL_SETNCE: | ||
311 | + nand_cs_on(); | ||
312 | + break; | ||
313 | + case NAND_CTL_CLRNCE: | ||
314 | + nand_cs_off(); | ||
315 | + break; | ||
316 | + } | ||
317 | + | ||
318 | + DRAIN_WB(); | ||
319 | } | ||
320 | |||
321 | -/* Same as nand_core:nand_command_lp() but with different memory | ||
322 | - * addresses for writing to ALE and CLE and without 16 bit support. | ||
323 | + | ||
324 | +/* | ||
325 | + * read device ready pin | ||
326 | */ | ||
327 | -static void cmx270_nand_command_lp (struct mtd_info *mtd, unsigned command, int column, int page_addr) | ||
328 | +static int cmx270_device_ready(struct mtd_info *mtd) | ||
329 | { | ||
330 | - register struct nand_chip *this = mtd->priv; | ||
331 | - | ||
332 | - /* Emulate NAND_CMD_READOOB */ | ||
333 | - if (command == NAND_CMD_READOOB) { | ||
334 | - column += mtd->oobblock; | ||
335 | - command = NAND_CMD_READ0; | ||
336 | -// printk("Read OOB: column: $%x, page: $%x\n", column, page_addr); | ||
337 | - } | ||
338 | - | ||
339 | - /* Write out the command to the device. */ | ||
340 | - cmx270_nand_write_CLE(mtd, command); | ||
341 | - | ||
342 | - if (column != -1 || page_addr != -1) { | ||
343 | - | ||
344 | - /* Serially input address */ | ||
345 | - if (column != -1) { | ||
346 | - cmx270_nand_write_ALE(mtd, column & 0xff); | ||
347 | - cmx270_nand_write_ALE(mtd, column >> 8); | ||
348 | - if ((column >> 8) > 0xf) { | ||
349 | - printk("out of range column\n"); | ||
350 | - } | ||
351 | - } | ||
352 | - if (page_addr != -1) { | ||
353 | - cmx270_nand_write_ALE(mtd, (unsigned char) (page_addr & 0xff)); | ||
354 | - cmx270_nand_write_ALE(mtd, (unsigned char) ((page_addr >> 8) & 0xff)); | ||
355 | - /* One more address cycle for devices > 128MiB */ | ||
356 | - if (this->chipsize > (128 << 20)) { | ||
357 | - cmx270_nand_write_ALE(mtd, (unsigned char) ((page_addr >> 16) & 0xff)); | ||
358 | - } | ||
359 | - } | ||
360 | - } | ||
361 | + DRAIN_WB(); | ||
362 | |||
363 | - udelay(1); | ||
364 | - | ||
365 | - /* | ||
366 | - * program and erase have their own busy handlers | ||
367 | - * status and sequential in needs no delay | ||
368 | - */ | ||
369 | - switch (command) { | ||
370 | - | ||
371 | - case NAND_CMD_CACHEDPROG: | ||
372 | - case NAND_CMD_PAGEPROG: | ||
373 | - case NAND_CMD_ERASE1: | ||
374 | - case NAND_CMD_ERASE2: | ||
375 | - case NAND_CMD_SEQIN: | ||
376 | - case NAND_CMD_STATUS: | ||
377 | - case NAND_CMD_DEPLETE1: | ||
378 | - return; | ||
379 | - | ||
380 | - /* | ||
381 | - * read error status commands require only a short delay | ||
382 | - */ | ||
383 | - case NAND_CMD_STATUS_ERROR: | ||
384 | - case NAND_CMD_STATUS_ERROR0: | ||
385 | - case NAND_CMD_STATUS_ERROR1: | ||
386 | - case NAND_CMD_STATUS_ERROR2: | ||
387 | - case NAND_CMD_STATUS_ERROR3: | ||
388 | - udelay(this->chip_delay); | ||
389 | - return; | ||
390 | - | ||
391 | - case NAND_CMD_RESET: | ||
392 | - if (this->dev_ready) | ||
393 | - break; | ||
394 | - udelay(this->chip_delay); | ||
395 | - cmx270_nand_write_CLE(mtd, NAND_CMD_STATUS); | ||
396 | - while ( !(this->read_byte(mtd) & NAND_STATUS_READY)); | ||
397 | - return; | ||
398 | - | ||
399 | - case NAND_CMD_READ0: | ||
400 | - /* Write out the start read command */ | ||
401 | - cmx270_nand_write_CLE(mtd, NAND_CMD_READSTART); | ||
402 | - /* Fall through into ready check */ | ||
403 | - | ||
404 | - /* This applies to read commands */ | ||
405 | - default: | ||
406 | - /* | ||
407 | - * If we don't have access to the busy pin, we apply the given | ||
408 | - * command delay | ||
409 | - */ | ||
410 | - if (!this->dev_ready) { | ||
411 | - udelay (this->chip_delay); | ||
412 | - return; | ||
413 | - } | ||
414 | - } | ||
415 | - | ||
416 | - /* Apply this short delay always to ensure that we do wait tWB in | ||
417 | - * any case on any machine. */ | ||
418 | - ndelay (100); | ||
419 | - /* wait until command is processed */ | ||
420 | - while (!this->dev_ready(mtd)); | ||
421 | + return (GPLR(GPIO_NAND_RB) & GPIO_bit(GPIO_NAND_RB)); | ||
422 | } | ||
423 | |||
424 | - | ||
425 | -#ifdef CONFIG_MTD_PARTITIONS | ||
426 | -const char *part_probes[] = { "cmdlinepart", NULL }; | ||
427 | -#endif | ||
428 | - | ||
429 | -int __init cmx270_nand_init(void) | ||
430 | +/* | ||
431 | + * Main initialization routine | ||
432 | + */ | ||
433 | +static int __devinit cmx270_init(void) | ||
434 | { | ||
435 | struct nand_chip *this; | ||
436 | - struct mtd_partition* cmx270_partition_info; | ||
437 | - int err = 0; | ||
438 | - | ||
439 | - pxa_gpio_mode(CM_X270_GPIO_NAND_RB); | ||
440 | + const char *part_type; | ||
441 | + struct mtd_partition *mtd_parts; | ||
442 | + int mtd_parts_nb = 0; | ||
443 | + int ret; | ||
444 | |||
445 | - GPSR(CM_X270_GPIO_NAND_CS) = GPIO_bit(CM_X270_GPIO_NAND_CS); | ||
446 | - pxa_gpio_mode(CM_X270_GPIO_NAND_CS | GPIO_OUT); | ||
447 | - | ||
448 | /* Allocate memory for MTD device structure and private data */ | ||
449 | - cmx270_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), | ||
450 | - GFP_KERNEL); | ||
451 | - if (!cmx270_mtd) { | ||
452 | - printk(KERN_WARNING "Unable to allocate cm-x270 NAND mtd device structure.\n"); | ||
453 | - err = -ENOMEM; | ||
454 | - goto out; | ||
455 | + cmx270_nand_mtd = kzalloc(sizeof(struct mtd_info) + | ||
456 | + sizeof(struct nand_chip), | ||
457 | + GFP_KERNEL); | ||
458 | + if (!cmx270_nand_mtd) { | ||
459 | + printk("Unable to allocate CM-X270 NAND MTD device structure.\n"); | ||
460 | + return -ENOMEM; | ||
461 | } | ||
462 | |||
463 | - /* map physical address */ | ||
464 | - cmx270_nand_io_base = ioremap(CM_X270_NAND_PHYS, 0x100); | ||
465 | - if (!cmx270_nand_io_base) { | ||
466 | - err = -EIO; | ||
467 | - goto out_mtd; | ||
468 | + cmx270_nand_io = ioremap(PXA_CS1_PHYS, 12); | ||
469 | + if (!cmx270_nand_io) { | ||
470 | + printk("Unable to ioremap NAND device\n"); | ||
471 | + ret = -EINVAL; | ||
472 | + goto err1; | ||
473 | } | ||
474 | |||
475 | /* Get pointer to private data */ | ||
476 | - this = (struct nand_chip *)(&cmx270_mtd[1]); | ||
477 | - | ||
478 | - /* Initialize structures */ | ||
479 | - memset((char *) cmx270_mtd, 0, sizeof(struct mtd_info)); | ||
480 | - memset((char *) this, 0, sizeof(struct nand_chip)); | ||
481 | + this = (struct nand_chip *)(&cmx270_nand_mtd[1]); | ||
482 | |||
483 | /* Link the private data with the MTD structure */ | ||
484 | - cmx270_mtd->priv = this; | ||
485 | + cmx270_nand_mtd->owner = THIS_MODULE; | ||
486 | + cmx270_nand_mtd->priv = this; | ||
487 | |||
488 | - this->IO_ADDR_R = cmx270_nand_io_base; | ||
489 | - this->IO_ADDR_W = cmx270_nand_io_base; | ||
490 | - this->read_byte = cmx270_nand_read_byte; | ||
491 | - this->write_byte = cmx270_nand_write_byte; | ||
492 | - this->write_buf = cmx270_nand_write_buf; | ||
493 | - this->read_buf = cmx270_nand_read_buf; | ||
494 | - this->verify_buf = cmx270_nand_verify_buf; | ||
495 | - this->hwcontrol = cmx270_nand_hwcontrol; | ||
496 | - this->dev_ready = cmx270_nand_device_ready; | ||
497 | - this->cmdfunc = cmx270_nand_command_lp; | ||
498 | - this->chip_delay = 25; | ||
499 | + /* insert callbacks */ | ||
500 | + this->IO_ADDR_R = cmx270_nand_io; | ||
501 | + this->IO_ADDR_W = cmx270_nand_io; | ||
502 | + this->hwcontrol = cmx270_hwcontrol; | ||
503 | + this->dev_ready = cmx270_device_ready; | ||
504 | + | ||
505 | + /* 15 us command delay time */ | ||
506 | + this->chip_delay = 20; | ||
507 | this->eccmode = NAND_ECC_SOFT; | ||
508 | |||
509 | - /* Scan to find existance of the device */ | ||
510 | - if (nand_scan(cmx270_mtd, 1)) { | ||
511 | - err = -ENXIO; | ||
512 | - goto out_ior; | ||
513 | + /* read/write functions */ | ||
514 | + this->read_byte = cmx270_read_byte; | ||
515 | + this->read_buf = cmx270_read_buf; | ||
516 | + this->write_buf = cmx270_write_buf; | ||
517 | + this->verify_buf = cmx270_verify_buf; | ||
518 | + | ||
519 | + /* Scan to find existence of the device */ | ||
520 | + if (nand_scan (cmx270_nand_mtd, 1)) { | ||
521 | + printk(KERN_NOTICE "No NAND device\n"); | ||
522 | + ret = -ENXIO; | ||
523 | + goto err2; | ||
524 | + } | ||
525 | + | ||
526 | +#ifdef CONFIG_MTD_CMDLINE_PARTS | ||
527 | + mtd_parts_nb = parse_mtd_partitions(cmx270_nand_mtd, part_probes, | ||
528 | + &mtd_parts, 0); | ||
529 | + if (mtd_parts_nb > 0) | ||
530 | + part_type = "command line"; | ||
531 | + else | ||
532 | + mtd_parts_nb = 0; | ||
533 | +#endif | ||
534 | + if (!mtd_parts_nb) { | ||
535 | + mtd_parts = partition_info; | ||
536 | + mtd_parts_nb = NUM_PARTITIONS; | ||
537 | + part_type = "static"; | ||
538 | } | ||
539 | |||
540 | /* Register the partitions */ | ||
541 | - cmx270_mtd->name = "cmx270-mtd"; | ||
542 | - nr_partitions = parse_mtd_partitions(cmx270_mtd, part_probes, &cmx270_partition_info, 0); | ||
543 | - if (nr_partitions <= 0) { | ||
544 | - nr_partitions = DEFAULT_NUM_PARTITIONS; | ||
545 | - cmx270_partition_info = cmx270_default_partition_info; | ||
546 | - } | ||
547 | + printk(KERN_NOTICE "Using %s partition definition\n", part_type); | ||
548 | + ret = add_mtd_partitions(cmx270_nand_mtd, mtd_parts, mtd_parts_nb); | ||
549 | + if (ret) | ||
550 | + goto err2; | ||
551 | + | ||
552 | + /* Return happy */ | ||
553 | + return 0; | ||
554 | + | ||
555 | +err2: | ||
556 | + iounmap(cmx270_nand_io); | ||
557 | +err1: | ||
558 | + kfree(cmx270_nand_mtd); | ||
559 | + | ||
560 | + return ret; | ||
561 | |||
562 | - add_mtd_partitions(cmx270_mtd, cmx270_partition_info, nr_partitions); | ||
563 | - | ||
564 | - goto out; | ||
565 | - | ||
566 | -out_ior: | ||
567 | - iounmap((void*) cmx270_nand_io_base); | ||
568 | -out_mtd: | ||
569 | - kfree(cmx270_mtd); | ||
570 | -out: | ||
571 | - return err; | ||
572 | } | ||
573 | -module_init(cmx270_nand_init); | ||
574 | +module_init(cmx270_init); | ||
575 | |||
576 | -static void __exit cmx270_nand_cleanup(void) | ||
577 | +/* | ||
578 | + * Clean up routine | ||
579 | + */ | ||
580 | +static void __devexit cmx270_cleanup(void) | ||
581 | { | ||
582 | - nand_release(cmx270_mtd); | ||
583 | - kfree(cmx270_mtd); | ||
584 | + /* Release resources, unregister device */ | ||
585 | + nand_release(cmx270_nand_mtd); | ||
586 | + | ||
587 | + iounmap(cmx270_nand_io); | ||
588 | + | ||
589 | + /* Free the MTD device structure */ | ||
590 | + kfree (cmx270_nand_mtd); | ||
591 | } | ||
592 | +module_exit(cmx270_cleanup); | ||
593 | |||
594 | MODULE_LICENSE("GPL"); | ||
595 | -MODULE_AUTHOR("Raphael Assenat <raph@8d.com>"); | ||
596 | -MODULE_DESCRIPTION("NAND flash driver for cm-x270 boards"); | ||
597 | - | ||
598 | +MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>"); | ||
599 | +MODULE_DESCRIPTION("NAND flash driver for Compulab CM-X270 Module"); | ||