diff options
author | Thomas Gleixner <tglx@cruncher.tec.linutronix.de> | 2006-05-23 17:25:53 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@cruncher.tec.linutronix.de> | 2006-05-23 17:25:53 -0400 |
commit | 7abd3ef9875eb2afcdcd4f450680298a2983a55e (patch) | |
tree | 64c19d2e5ecca182938acfcb8a172efb7d907d85 | |
parent | 3821720d51b5f304d2c33021a82c8da70f6d6ac9 (diff) |
[MTD] Refactor NAND hwcontrol to cmd_ctrl
The hwcontrol function enforced a step by step state machine
for any kind of hardware chip access. Let the hardware driver
know which control bits are set and inform it about a change
of the control lines. Let the hardware driver write out the
command and address bytes directly. This gives a peformance
advantage for address bus controlled chips and simplifies the
quirks in the hardware drivers.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | drivers/mtd/nand/ams-delta.c | 56 | ||||
-rw-r--r-- | drivers/mtd/nand/au1550nd.c | 25 | ||||
-rw-r--r-- | drivers/mtd/nand/autcpu12.c | 77 | ||||
-rw-r--r-- | drivers/mtd/nand/cs553x_nand.c | 32 | ||||
-rw-r--r-- | drivers/mtd/nand/diskonchip.c | 77 | ||||
-rw-r--r-- | drivers/mtd/nand/edb7312.c | 42 | ||||
-rw-r--r-- | drivers/mtd/nand/h1910.c | 40 | ||||
-rw-r--r-- | drivers/mtd/nand/nand_base.c | 115 | ||||
-rw-r--r-- | drivers/mtd/nand/nandsim.c | 76 | ||||
-rw-r--r-- | drivers/mtd/nand/ndfc.c | 23 | ||||
-rw-r--r-- | drivers/mtd/nand/ppchameleonevb.c | 102 | ||||
-rw-r--r-- | drivers/mtd/nand/rtc_from4.c | 34 | ||||
-rw-r--r-- | drivers/mtd/nand/s3c2410.c | 64 | ||||
-rw-r--r-- | drivers/mtd/nand/sharpsl.c | 41 | ||||
-rw-r--r-- | drivers/mtd/nand/spia.c | 27 | ||||
-rw-r--r-- | drivers/mtd/nand/toto.c | 65 | ||||
-rw-r--r-- | drivers/mtd/nand/ts7250.c | 44 | ||||
-rw-r--r-- | include/linux/mtd/nand.h | 33 |
18 files changed, 430 insertions, 543 deletions
diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c index aeaf2dece095..c0e96860686e 100644 --- a/drivers/mtd/nand/ams-delta.c +++ b/drivers/mtd/nand/ams-delta.c | |||
@@ -34,13 +34,6 @@ static struct mtd_info *ams_delta_mtd = NULL; | |||
34 | 34 | ||
35 | #define NAND_MASK (AMS_DELTA_LATCH2_NAND_NRE | AMS_DELTA_LATCH2_NAND_NWE | AMS_DELTA_LATCH2_NAND_CLE | AMS_DELTA_LATCH2_NAND_ALE | AMS_DELTA_LATCH2_NAND_NCE | AMS_DELTA_LATCH2_NAND_NWP) | 35 | #define NAND_MASK (AMS_DELTA_LATCH2_NAND_NRE | AMS_DELTA_LATCH2_NAND_NWE | AMS_DELTA_LATCH2_NAND_CLE | AMS_DELTA_LATCH2_NAND_ALE | AMS_DELTA_LATCH2_NAND_NCE | AMS_DELTA_LATCH2_NAND_NWP) |
36 | 36 | ||
37 | #define T_NAND_CTL_CLRALE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_ALE, 0) | ||
38 | #define T_NAND_CTL_SETALE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_ALE, AMS_DELTA_LATCH2_NAND_ALE) | ||
39 | #define T_NAND_CTL_CLRCLE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_CLE, 0) | ||
40 | #define T_NAND_CTL_SETCLE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_CLE, AMS_DELTA_LATCH2_NAND_CLE) | ||
41 | #define T_NAND_CTL_SETNCE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NCE, 0) | ||
42 | #define T_NAND_CTL_CLRNCE(iob) ams_delta_latch2_write(AMS_DELTA_LATCH2_NAND_NCE, AMS_DELTA_LATCH2_NAND_NCE) | ||
43 | |||
44 | /* | 37 | /* |
45 | * Define partitions for flash devices | 38 | * Define partitions for flash devices |
46 | */ | 39 | */ |
@@ -66,25 +59,6 @@ static struct mtd_partition partition_info[] = { | |||
66 | .size = 3 * SZ_256K }, | 59 | .size = 3 * SZ_256K }, |
67 | }; | 60 | }; |
68 | 61 | ||
69 | /* | ||
70 | * hardware specific access to control-lines | ||
71 | */ | ||
72 | |||
73 | static void ams_delta_hwcontrol(struct mtd_info *mtd, int cmd) | ||
74 | { | ||
75 | switch (cmd) { | ||
76 | |||
77 | case NAND_CTL_SETCLE: T_NAND_CTL_SETCLE(cmd); break; | ||
78 | case NAND_CTL_CLRCLE: T_NAND_CTL_CLRCLE(cmd); break; | ||
79 | |||
80 | case NAND_CTL_SETALE: T_NAND_CTL_SETALE(cmd); break; | ||
81 | case NAND_CTL_CLRALE: T_NAND_CTL_CLRALE(cmd); break; | ||
82 | |||
83 | case NAND_CTL_SETNCE: T_NAND_CTL_SETNCE(cmd); break; | ||
84 | case NAND_CTL_CLRNCE: T_NAND_CTL_CLRNCE(cmd); break; | ||
85 | } | ||
86 | } | ||
87 | |||
88 | static void ams_delta_write_byte(struct mtd_info *mtd, u_char byte) | 62 | static void ams_delta_write_byte(struct mtd_info *mtd, u_char byte) |
89 | { | 63 | { |
90 | struct nand_chip *this = mtd->priv; | 64 | struct nand_chip *this = mtd->priv; |
@@ -141,6 +115,32 @@ static int ams_delta_verify_buf(struct mtd_info *mtd, const u_char *buf, | |||
141 | return 0; | 115 | return 0; |
142 | } | 116 | } |
143 | 117 | ||
118 | /* | ||
119 | * Command control function | ||
120 | * | ||
121 | * ctrl: | ||
122 | * NAND_NCE: bit 0 -> bit 2 | ||
123 | * NAND_CLE: bit 1 -> bit 7 | ||
124 | * NAND_ALE: bit 2 -> bit 6 | ||
125 | */ | ||
126 | static void ams_delta_hwcontrol(struct mtd_info *mtd, int cmd, | ||
127 | unsigned int ctrl) | ||
128 | { | ||
129 | |||
130 | if (ctrl & NAND_CTRL_CHANGE) { | ||
131 | unsigned long bits; | ||
132 | |||
133 | bits = (~ctrl & NAND_NCE) << 2; | ||
134 | bits |= (ctrl & NAND_CLE) << 7; | ||
135 | bits |= (ctrl & NAND_ALE) << 6; | ||
136 | |||
137 | ams_delta_latch2_write(0xC2, bits); | ||
138 | } | ||
139 | |||
140 | if (cmd != NAND_CMD_NONE) | ||
141 | ams_delta_write_byte(mtd, cmd); | ||
142 | } | ||
143 | |||
144 | static int ams_delta_nand_ready(struct mtd_info *mtd) | 144 | static int ams_delta_nand_ready(struct mtd_info *mtd) |
145 | { | 145 | { |
146 | return omap_get_gpio_datain(AMS_DELTA_GPIO_PIN_NAND_RB); | 146 | return omap_get_gpio_datain(AMS_DELTA_GPIO_PIN_NAND_RB); |
@@ -183,7 +183,7 @@ static int __init ams_delta_init(void) | |||
183 | this->write_buf = ams_delta_write_buf; | 183 | this->write_buf = ams_delta_write_buf; |
184 | this->read_buf = ams_delta_read_buf; | 184 | this->read_buf = ams_delta_read_buf; |
185 | this->verify_buf = ams_delta_verify_buf; | 185 | this->verify_buf = ams_delta_verify_buf; |
186 | this->hwcontrol = ams_delta_hwcontrol; | 186 | this->cmd_ctrl = ams_delta_hwcontrol; |
187 | if (!omap_request_gpio(AMS_DELTA_GPIO_PIN_NAND_RB)) { | 187 | if (!omap_request_gpio(AMS_DELTA_GPIO_PIN_NAND_RB)) { |
188 | this->dev_ready = ams_delta_nand_ready; | 188 | this->dev_ready = ams_delta_nand_ready; |
189 | } else { | 189 | } else { |
@@ -200,7 +200,7 @@ static int __init ams_delta_init(void) | |||
200 | AMS_DELTA_LATCH2_NAND_NCE | | 200 | AMS_DELTA_LATCH2_NAND_NCE | |
201 | AMS_DELTA_LATCH2_NAND_NWP); | 201 | AMS_DELTA_LATCH2_NAND_NWP); |
202 | 202 | ||
203 | /* Scan to find existance of the device */ | 203 | /* Scan to find existance of the device */ |
204 | if (nand_scan(ams_delta_mtd, 1)) { | 204 | if (nand_scan(ams_delta_mtd, 1)) { |
205 | err = -ENXIO; | 205 | err = -ENXIO; |
206 | goto out_mtd; | 206 | goto out_mtd; |
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c index 29dde7dcafa1..275453ea7a71 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/au1550nd.c | |||
@@ -269,6 +269,18 @@ static int au_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len) | |||
269 | return 0; | 269 | return 0; |
270 | } | 270 | } |
271 | 271 | ||
272 | /* Select the chip by setting nCE to low */ | ||
273 | #define NAND_CTL_SETNCE 1 | ||
274 | /* Deselect the chip by setting nCE to high */ | ||
275 | #define NAND_CTL_CLRNCE 2 | ||
276 | /* Select the command latch by setting CLE to high */ | ||
277 | #define NAND_CTL_SETCLE 3 | ||
278 | /* Deselect the command latch by setting CLE to low */ | ||
279 | #define NAND_CTL_CLRCLE 4 | ||
280 | /* Select the address latch by setting ALE to high */ | ||
281 | #define NAND_CTL_SETALE 5 | ||
282 | /* Deselect the address latch by setting ALE to low */ | ||
283 | #define NAND_CTL_CLRALE 6 | ||
272 | 284 | ||
273 | static void au1550_hwcontrol(struct mtd_info *mtd, int cmd) | 285 | static void au1550_hwcontrol(struct mtd_info *mtd, int cmd) |
274 | { | 286 | { |
@@ -349,7 +361,7 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i | |||
349 | ulong flags; | 361 | ulong flags; |
350 | 362 | ||
351 | /* Begin command latch cycle */ | 363 | /* Begin command latch cycle */ |
352 | this->hwcontrol(mtd, NAND_CTL_SETCLE); | 364 | au1550_hwcontrol(mtd, NAND_CTL_SETCLE); |
353 | /* | 365 | /* |
354 | * Write out the command to the device. | 366 | * Write out the command to the device. |
355 | */ | 367 | */ |
@@ -372,10 +384,10 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i | |||
372 | this->write_byte(mtd, command); | 384 | this->write_byte(mtd, command); |
373 | 385 | ||
374 | /* Set ALE and clear CLE to start address cycle */ | 386 | /* Set ALE and clear CLE to start address cycle */ |
375 | this->hwcontrol(mtd, NAND_CTL_CLRCLE); | 387 | au1550_hwcontrol(mtd, NAND_CTL_CLRCLE); |
376 | 388 | ||
377 | if (column != -1 || page_addr != -1) { | 389 | if (column != -1 || page_addr != -1) { |
378 | this->hwcontrol(mtd, NAND_CTL_SETALE); | 390 | au1550_hwcontrol(mtd, NAND_CTL_SETALE); |
379 | 391 | ||
380 | /* Serially input address */ | 392 | /* Serially input address */ |
381 | if (column != -1) { | 393 | if (column != -1) { |
@@ -400,7 +412,7 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i | |||
400 | */ | 412 | */ |
401 | ce_override = 1; | 413 | ce_override = 1; |
402 | local_irq_save(flags); | 414 | local_irq_save(flags); |
403 | this->hwcontrol(mtd, NAND_CTL_SETNCE); | 415 | au1550_hwcontrol(mtd, NAND_CTL_SETNCE); |
404 | } | 416 | } |
405 | 417 | ||
406 | this->write_byte(mtd, (u8)(page_addr >> 8)); | 418 | this->write_byte(mtd, (u8)(page_addr >> 8)); |
@@ -410,7 +422,7 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i | |||
410 | this->write_byte(mtd, (u8)((page_addr >> 16) & 0x0f)); | 422 | this->write_byte(mtd, (u8)((page_addr >> 16) & 0x0f)); |
411 | } | 423 | } |
412 | /* Latch in address */ | 424 | /* Latch in address */ |
413 | this->hwcontrol(mtd, NAND_CTL_CLRALE); | 425 | au1550_hwcontrol(mtd, NAND_CTL_CLRALE); |
414 | } | 426 | } |
415 | 427 | ||
416 | /* | 428 | /* |
@@ -443,7 +455,7 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i | |||
443 | udelay(1); | 455 | udelay(1); |
444 | 456 | ||
445 | /* Release -CE and re-enable interrupts. */ | 457 | /* Release -CE and re-enable interrupts. */ |
446 | this->hwcontrol(mtd, NAND_CTL_CLRNCE); | 458 | au1550_hwcontrol(mtd, NAND_CTL_CLRNCE); |
447 | local_irq_restore(flags); | 459 | local_irq_restore(flags); |
448 | return; | 460 | return; |
449 | } | 461 | } |
@@ -571,7 +583,6 @@ static int __init au1xxx_nand_init(void) | |||
571 | nand_width = au_readl(MEM_STCFG3) & (1 << 22); | 583 | nand_width = au_readl(MEM_STCFG3) & (1 << 22); |
572 | 584 | ||
573 | /* Set address of hardware control function */ | 585 | /* Set address of hardware control function */ |
574 | this->hwcontrol = au1550_hwcontrol; | ||
575 | this->dev_ready = au1550_device_ready; | 586 | this->dev_ready = au1550_device_ready; |
576 | this->select_chip = au1550_select_chip; | 587 | this->select_chip = au1550_select_chip; |
577 | this->cmdfunc = au1550_command; | 588 | this->cmdfunc = au1550_command; |
diff --git a/drivers/mtd/nand/autcpu12.c b/drivers/mtd/nand/autcpu12.c index dbb1b6267ade..fe94ae9ae1f2 100644 --- a/drivers/mtd/nand/autcpu12.c +++ b/drivers/mtd/nand/autcpu12.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright (c) 2002 Thomas Gleixner <tgxl@linutronix.de> | 4 | * Copyright (c) 2002 Thomas Gleixner <tgxl@linutronix.de> |
5 | * | 5 | * |
6 | * Derived from drivers/mtd/spia.c | 6 | * Derived from drivers/mtd/spia.c |
7 | * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) | 7 | * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) |
8 | * | 8 | * |
9 | * $Id: autcpu12.c,v 1.23 2005/11/07 11:14:30 gleixner Exp $ | 9 | * $Id: autcpu12.c,v 1.23 2005/11/07 11:14:30 gleixner Exp $ |
10 | * | 10 | * |
@@ -42,11 +42,6 @@ | |||
42 | * MTD structure for AUTCPU12 board | 42 | * MTD structure for AUTCPU12 board |
43 | */ | 43 | */ |
44 | static struct mtd_info *autcpu12_mtd = NULL; | 44 | static struct mtd_info *autcpu12_mtd = NULL; |
45 | |||
46 | static int autcpu12_io_base = CS89712_VIRT_BASE; | ||
47 | static int autcpu12_fio_pbase = AUTCPU12_PHYS_SMC; | ||
48 | static int autcpu12_fio_ctrl = AUTCPU12_SMC_SELECT_OFFSET; | ||
49 | static int autcpu12_pedr = AUTCPU12_SMC_PORT_OFFSET; | ||
50 | static void __iomem *autcpu12_fio_base; | 45 | static void __iomem *autcpu12_fio_base; |
51 | 46 | ||
52 | /* | 47 | /* |
@@ -94,31 +89,42 @@ static struct mtd_partition partition_info128k[] = { | |||
94 | #define NUM_PARTITIONS128K 2 | 89 | #define NUM_PARTITIONS128K 2 |
95 | /* | 90 | /* |
96 | * hardware specific access to control-lines | 91 | * hardware specific access to control-lines |
97 | */ | 92 | * |
98 | 93 | * ALE bit 4 autcpu12_pedr | |
99 | static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd) | 94 | * CLE bit 5 autcpu12_pedr |
95 | * NCE bit 0 fio_ctrl | ||
96 | * | ||
97 | */ | ||
98 | static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd, | ||
99 | unsigned int ctrl) | ||
100 | { | 100 | { |
101 | switch (cmd) { | 101 | struct nand_chip *chip = mtd->priv; |
102 | 102 | ||
103 | case NAND_CTL_SETCLE: (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) |= AUTCPU12_SMC_CLE; break; | 103 | if (ctrl & NAND_CTRL_CHANGE) { |
104 | case NAND_CTL_CLRCLE: (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) &= ~AUTCPU12_SMC_CLE; break; | 104 | void __iomem *addr |
105 | unsigned char bits; | ||
105 | 106 | ||
106 | case NAND_CTL_SETALE: (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) |= AUTCPU12_SMC_ALE; break; | 107 | addr = CS89712_VIRT_BASE + AUTCPU12_SMC_PORT_OFFSET; |
107 | case NAND_CTL_CLRALE: (*(volatile unsigned char *) (autcpu12_io_base + autcpu12_pedr)) &= ~AUTCPU12_SMC_ALE; break; | 108 | bits = (ctrl & NAND_CLE) << 4; |
109 | bits |= (ctrl & NAND_ALE) << 2; | ||
110 | writeb((readb(addr) & ~0x30) | bits, addr); | ||
108 | 111 | ||
109 | case NAND_CTL_SETNCE: (*(volatile unsigned char *) (autcpu12_fio_base + autcpu12_fio_ctrl)) = 0x01; break; | 112 | addr = autcpu12_fio_base + AUTCPU12_SMC_SELECT_OFFSET; |
110 | case NAND_CTL_CLRNCE: (*(volatile unsigned char *) (autcpu12_fio_base + autcpu12_fio_ctrl)) = 0x00; break; | 113 | writeb((readb(addr) & ~0x1) | (ctrl & NAND_NCE), addr); |
111 | } | 114 | } |
115 | |||
116 | if (cmd != NAND_CMD_NONE) | ||
117 | writeb(cmd, chip->IO_ADDR_W); | ||
112 | } | 118 | } |
113 | 119 | ||
114 | /* | 120 | /* |
115 | * read device ready pin | 121 | * read device ready pin |
116 | */ | 122 | */ |
117 | int autcpu12_device_ready(struct mtd_info *mtd) | 123 | int autcpu12_device_ready(struct mtd_info *mtd) |
118 | { | 124 | { |
125 | void __iomem *addr = CS89712_VIRT_BASE + AUTCPU12_SMC_PORT_OFFSET; | ||
119 | 126 | ||
120 | return ((*(volatile unsigned char *)(autcpu12_io_base + autcpu12_pedr)) & AUTCPU12_SMC_RDY) ? 1 : 0; | 127 | return readb(addr) & AUTCPU12_SMC_RDY; |
121 | |||
122 | } | 128 | } |
123 | 129 | ||
124 | /* | 130 | /* |
@@ -130,7 +136,8 @@ static int __init autcpu12_init(void) | |||
130 | int err = 0; | 136 | int err = 0; |
131 | 137 | ||
132 | /* Allocate memory for MTD device structure and private data */ | 138 | /* Allocate memory for MTD device structure and private data */ |
133 | autcpu12_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); | 139 | autcpu12_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), |
140 | GFP_KERNEL); | ||
134 | if (!autcpu12_mtd) { | 141 | if (!autcpu12_mtd) { |
135 | printk("Unable to allocate AUTCPU12 NAND MTD device structure.\n"); | 142 | printk("Unable to allocate AUTCPU12 NAND MTD device structure.\n"); |
136 | err = -ENOMEM; | 143 | err = -ENOMEM; |
@@ -138,7 +145,7 @@ static int __init autcpu12_init(void) | |||
138 | } | 145 | } |
139 | 146 | ||
140 | /* map physical adress */ | 147 | /* map physical adress */ |
141 | autcpu12_fio_base = ioremap(autcpu12_fio_pbase, SZ_1K); | 148 | autcpu12_fio_base = ioremap(AUTCPU12_PHYS_SMC, SZ_1K); |
142 | if (!autcpu12_fio_base) { | 149 | if (!autcpu12_fio_base) { |
143 | printk("Ioremap autcpu12 SmartMedia Card failed\n"); | 150 | printk("Ioremap autcpu12 SmartMedia Card failed\n"); |
144 | err = -EIO; | 151 | err = -EIO; |
@@ -159,7 +166,7 @@ static int __init autcpu12_init(void) | |||
159 | /* Set address of NAND IO lines */ | 166 | /* Set address of NAND IO lines */ |
160 | this->IO_ADDR_R = autcpu12_fio_base; | 167 | this->IO_ADDR_R = autcpu12_fio_base; |
161 | this->IO_ADDR_W = autcpu12_fio_base; | 168 | this->IO_ADDR_W = autcpu12_fio_base; |
162 | this->hwcontrol = autcpu12_hwcontrol; | 169 | this->cmd_ctrl = autcpu12_hwcontrol; |
163 | this->dev_ready = autcpu12_device_ready; | 170 | this->dev_ready = autcpu12_device_ready; |
164 | /* 20 us command delay time */ | 171 | /* 20 us command delay time */ |
165 | this->chip_delay = 20; | 172 | this->chip_delay = 20; |
@@ -179,10 +186,22 @@ static int __init autcpu12_init(void) | |||
179 | 186 | ||
180 | /* Register the partitions */ | 187 | /* Register the partitions */ |
181 | switch (autcpu12_mtd->size) { | 188 | switch (autcpu12_mtd->size) { |
182 | case SZ_16M: add_mtd_partitions(autcpu12_mtd, partition_info16k, NUM_PARTITIONS16K); break; | 189 | case SZ_16M: |
183 | case SZ_32M: add_mtd_partitions(autcpu12_mtd, partition_info32k, NUM_PARTITIONS32K); break; | 190 | add_mtd_partitions(autcpu12_mtd, partition_info16k, |
184 | case SZ_64M: add_mtd_partitions(autcpu12_mtd, partition_info64k, NUM_PARTITIONS64K); break; | 191 | NUM_PARTITIONS16K); |
185 | case SZ_128M: add_mtd_partitions(autcpu12_mtd, partition_info128k, NUM_PARTITIONS128K); break; | 192 | break; |
193 | case SZ_32M: | ||
194 | add_mtd_partitions(autcpu12_mtd, partition_info32k, | ||
195 | NUM_PARTITIONS32K); | ||
196 | break; | ||
197 | case SZ_64M: | ||
198 | add_mtd_partitions(autcpu12_mtd, partition_info64k, | ||
199 | NUM_PARTITIONS64K); | ||
200 | break; | ||
201 | case SZ_128M: | ||
202 | add_mtd_partitions(autcpu12_mtd, partition_info128k, | ||
203 | NUM_PARTITIONS128K); | ||
204 | break; | ||
186 | default: | 205 | default: |
187 | printk("Unsupported SmartMedia device\n"); | 206 | printk("Unsupported SmartMedia device\n"); |
188 | err = -ENXIO; | 207 | err = -ENXIO; |
@@ -191,7 +210,7 @@ static int __init autcpu12_init(void) | |||
191 | goto out; | 210 | goto out; |
192 | 211 | ||
193 | out_ior: | 212 | out_ior: |
194 | iounmap((void *)autcpu12_fio_base); | 213 | iounmap(autcpu12_fio_base); |
195 | out_mtd: | 214 | out_mtd: |
196 | kfree(autcpu12_mtd); | 215 | kfree(autcpu12_mtd); |
197 | out: | 216 | out: |
@@ -209,7 +228,7 @@ static void __exit autcpu12_cleanup(void) | |||
209 | nand_release(autcpu12_mtd); | 228 | nand_release(autcpu12_mtd); |
210 | 229 | ||
211 | /* unmap physical adress */ | 230 | /* unmap physical adress */ |
212 | iounmap((void *)autcpu12_fio_base); | 231 | iounmap(autcpu12_fio_base); |
213 | 232 | ||
214 | /* Free the MTD device structure */ | 233 | /* Free the MTD device structure */ |
215 | kfree(autcpu12_mtd); | 234 | kfree(autcpu12_mtd); |
diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/cs553x_nand.c index 064f3feadf53..cd3d7eb132f9 100644 --- a/drivers/mtd/nand/cs553x_nand.c +++ b/drivers/mtd/nand/cs553x_nand.c | |||
@@ -131,33 +131,17 @@ static void cs553x_write_byte(struct mtd_info *mtd, u_char byte) | |||
131 | writeb(byte, this->IO_ADDR_W + 0x801); | 131 | writeb(byte, this->IO_ADDR_W + 0x801); |
132 | } | 132 | } |
133 | 133 | ||
134 | static void cs553x_hwcontrol(struct mtd_info *mtd, int cmd) | 134 | static void cs553x_hwcontrol(struct mtd_info *mtd, int cmd, |
135 | unsigned int ctrl) | ||
135 | { | 136 | { |
136 | struct nand_chip *this = mtd->priv; | 137 | struct nand_chip *this = mtd->priv; |
137 | void __iomem *mmio_base = this->IO_ADDR_R; | 138 | void __iomem *mmio_base = this->IO_ADDR_R; |
138 | unsigned char ctl; | 139 | if (ctrl & NAND_CTRL_CHANGE) { |
139 | 140 | unsigned char ctl = (ctrl & ~NAND_CTRL_CHANGE ) ^ 0x01; | |
140 | switch (cmd) { | 141 | writeb(ctl, mmio_base + MM_NAND_CTL); |
141 | case NAND_CTL_SETCLE: | ||
142 | ctl = CS_NAND_CTL_CLE; | ||
143 | break; | ||
144 | |||
145 | case NAND_CTL_CLRCLE: | ||
146 | case NAND_CTL_CLRALE: | ||
147 | case NAND_CTL_SETNCE: | ||
148 | ctl = 0; | ||
149 | break; | ||
150 | |||
151 | case NAND_CTL_SETALE: | ||
152 | ctl = CS_NAND_CTL_ALE; | ||
153 | break; | ||
154 | |||
155 | default: | ||
156 | case NAND_CTL_CLRNCE: | ||
157 | ctl = CS_NAND_CTL_CE; | ||
158 | break; | ||
159 | } | 142 | } |
160 | writeb(ctl, mmio_base + MM_NAND_CTL); | 143 | if (cmd != NAND_CMD_NONE) |
144 | cs553x_write_byte(mtd, cmd); | ||
161 | } | 145 | } |
162 | 146 | ||
163 | static int cs553x_device_ready(struct mtd_info *mtd) | 147 | static int cs553x_device_ready(struct mtd_info *mtd) |
@@ -233,7 +217,7 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr) | |||
233 | goto out_mtd; | 217 | goto out_mtd; |
234 | } | 218 | } |
235 | 219 | ||
236 | this->hwcontrol = cs553x_hwcontrol; | 220 | this->cmd_ctrl = cs553x_hwcontrol; |
237 | this->dev_ready = cs553x_device_ready; | 221 | this->dev_ready = cs553x_device_ready; |
238 | this->read_byte = cs553x_read_byte; | 222 | this->read_byte = cs553x_read_byte; |
239 | this->write_byte = cs553x_write_byte; | 223 | this->write_byte = cs553x_write_byte; |
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index f77298f3af60..e4bb6b429f87 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c | |||
@@ -95,7 +95,8 @@ static u_char empty_write_ecc[6] = { 0x4b, 0x00, 0xe2, 0x0e, 0x93, 0xf7 }; | |||
95 | #define DoC_is_Millennium(doc) ((doc)->ChipID == DOC_ChipID_DocMil) | 95 | #define DoC_is_Millennium(doc) ((doc)->ChipID == DOC_ChipID_DocMil) |
96 | #define DoC_is_2000(doc) ((doc)->ChipID == DOC_ChipID_Doc2k) | 96 | #define DoC_is_2000(doc) ((doc)->ChipID == DOC_ChipID_Doc2k) |
97 | 97 | ||
98 | static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd); | 98 | static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd, |
99 | unsigned int bitmask); | ||
99 | static void doc200x_select_chip(struct mtd_info *mtd, int chip); | 100 | static void doc200x_select_chip(struct mtd_info *mtd, int chip); |
100 | 101 | ||
101 | static int debug = 0; | 102 | static int debug = 0; |
@@ -402,12 +403,10 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr) | |||
402 | uint16_t ret; | 403 | uint16_t ret; |
403 | 404 | ||
404 | doc200x_select_chip(mtd, nr); | 405 | doc200x_select_chip(mtd, nr); |
405 | doc200x_hwcontrol(mtd, NAND_CTL_SETCLE); | 406 | doc200x_hwcontrol(mtd, NAND_CMD_READID, |
406 | this->write_byte(mtd, NAND_CMD_READID); | 407 | NAND_CTRL_CLE | NAND_CTRL_CHANGE); |
407 | doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE); | 408 | doc200x_hwcontrol(mtd, 0, NAND_CTRL_ALE | NAND_CTRL_CHANGE); |
408 | doc200x_hwcontrol(mtd, NAND_CTL_SETALE); | 409 | doc200x_hwcontrol(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); |
409 | this->write_byte(mtd, 0); | ||
410 | doc200x_hwcontrol(mtd, NAND_CTL_CLRALE); | ||
411 | 410 | ||
412 | /* We cant' use dev_ready here, but at least we wait for the | 411 | /* We cant' use dev_ready here, but at least we wait for the |
413 | * command to complete | 412 | * command to complete |
@@ -425,12 +424,11 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr) | |||
425 | } ident; | 424 | } ident; |
426 | void __iomem *docptr = doc->virtadr; | 425 | void __iomem *docptr = doc->virtadr; |
427 | 426 | ||
428 | doc200x_hwcontrol(mtd, NAND_CTL_SETCLE); | 427 | doc200x_hwcontrol(mtd, NAND_CMD_READID, |
429 | doc2000_write_byte(mtd, NAND_CMD_READID); | 428 | NAND_CTRL_CLE | NAND_CTRL_CHANGE); |
430 | doc200x_hwcontrol(mtd, NAND_CTL_CLRCLE); | 429 | doc200x_hwcontrol(mtd, 0, NAND_CTRL_ALE | NAND_CTRL_CHANGE); |
431 | doc200x_hwcontrol(mtd, NAND_CTL_SETALE); | 430 | doc200x_hwcontrol(mtd, NAND_CMD_NONE, |
432 | doc2000_write_byte(mtd, 0); | 431 | NAND_NCE | NAND_CTRL_CHANGE); |
433 | doc200x_hwcontrol(mtd, NAND_CTL_CLRALE); | ||
434 | 432 | ||
435 | udelay(50); | 433 | udelay(50); |
436 | 434 | ||
@@ -690,54 +688,37 @@ static void doc200x_select_chip(struct mtd_info *mtd, int chip) | |||
690 | chip -= (floor * doc->chips_per_floor); | 688 | chip -= (floor * doc->chips_per_floor); |
691 | 689 | ||
692 | /* 11.4.4 -- deassert CE before changing chip */ | 690 | /* 11.4.4 -- deassert CE before changing chip */ |
693 | doc200x_hwcontrol(mtd, NAND_CTL_CLRNCE); | 691 | doc200x_hwcontrol(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE); |
694 | 692 | ||
695 | WriteDOC(floor, docptr, FloorSelect); | 693 | WriteDOC(floor, docptr, FloorSelect); |
696 | WriteDOC(chip, docptr, CDSNDeviceSelect); | 694 | WriteDOC(chip, docptr, CDSNDeviceSelect); |
697 | 695 | ||
698 | doc200x_hwcontrol(mtd, NAND_CTL_SETNCE); | 696 | doc200x_hwcontrol(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); |
699 | 697 | ||
700 | doc->curchip = chip; | 698 | doc->curchip = chip; |
701 | doc->curfloor = floor; | 699 | doc->curfloor = floor; |
702 | } | 700 | } |
703 | 701 | ||
704 | static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd) | 702 | #define CDSN_CTRL_MSK (CDSN_CTRL_CE | CDSN_CTRL_CLE | CDSN_CTRL_ALE) |
703 | |||
704 | static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd, | ||
705 | unsigned int ctrl) | ||
705 | { | 706 | { |
706 | struct nand_chip *this = mtd->priv; | 707 | struct nand_chip *this = mtd->priv; |
707 | struct doc_priv *doc = this->priv; | 708 | struct doc_priv *doc = this->priv; |
708 | void __iomem *docptr = doc->virtadr; | 709 | void __iomem *docptr = doc->virtadr; |
709 | 710 | ||
710 | switch (cmd) { | 711 | if (ctrl & NAND_CTRL_CHANGE) { |
711 | case NAND_CTL_SETNCE: | 712 | doc->CDSNControl &= ~CDSN_CTRL_MSK; |
712 | doc->CDSNControl |= CDSN_CTRL_CE; | 713 | doc->CDSNControl |= ctrl & CDSN_CTRL_MSK; |
713 | break; | 714 | if (debug) |
714 | case NAND_CTL_CLRNCE: | 715 | printk("hwcontrol(%d): %02x\n", cmd, doc->CDSNControl); |
715 | doc->CDSNControl &= ~CDSN_CTRL_CE; | 716 | WriteDOC(doc->CDSNControl, docptr, CDSNControl); |
716 | break; | 717 | /* 11.4.3 -- 4 NOPs after CSDNControl write */ |
717 | case NAND_CTL_SETCLE: | 718 | DoC_Delay(doc, 4); |
718 | doc->CDSNControl |= CDSN_CTRL_CLE; | ||
719 | break; | ||
720 | case NAND_CTL_CLRCLE: | ||
721 | doc->CDSNControl &= ~CDSN_CTRL_CLE; | ||
722 | break; | ||
723 | case NAND_CTL_SETALE: | ||
724 | doc->CDSNControl |= CDSN_CTRL_ALE; | ||
725 | break; | ||
726 | case NAND_CTL_CLRALE: | ||
727 | doc->CDSNControl &= ~CDSN_CTRL_ALE; | ||
728 | break; | ||
729 | case NAND_CTL_SETWP: | ||
730 | doc->CDSNControl |= CDSN_CTRL_WP; | ||
731 | break; | ||
732 | case NAND_CTL_CLRWP: | ||
733 | doc->CDSNControl &= ~CDSN_CTRL_WP; | ||
734 | break; | ||
735 | } | 719 | } |
736 | if (debug) | 720 | if (cmd != NAND_CMD_NONE) |
737 | printk("hwcontrol(%d): %02x\n", cmd, doc->CDSNControl); | 721 | this->write_byte(mtd, cmd); |
738 | WriteDOC(doc->CDSNControl, docptr, CDSNControl); | ||
739 | /* 11.4.3 -- 4 NOPs after CSDNControl write */ | ||
740 | DoC_Delay(doc, 4); | ||
741 | } | 722 | } |
742 | 723 | ||
743 | static void doc2001plus_command(struct mtd_info *mtd, unsigned command, int column, int page_addr) | 724 | static void doc2001plus_command(struct mtd_info *mtd, unsigned command, int column, int page_addr) |
@@ -1510,7 +1491,7 @@ static inline int __init doc2001plus_init(struct mtd_info *mtd) | |||
1510 | this->read_buf = doc2001plus_readbuf; | 1491 | this->read_buf = doc2001plus_readbuf; |
1511 | this->verify_buf = doc2001plus_verifybuf; | 1492 | this->verify_buf = doc2001plus_verifybuf; |
1512 | this->scan_bbt = inftl_scan_bbt; | 1493 | this->scan_bbt = inftl_scan_bbt; |
1513 | this->hwcontrol = NULL; | 1494 | this->cmd_ctrl = NULL; |
1514 | this->select_chip = doc2001plus_select_chip; | 1495 | this->select_chip = doc2001plus_select_chip; |
1515 | this->cmdfunc = doc2001plus_command; | 1496 | this->cmdfunc = doc2001plus_command; |
1516 | this->ecc.hwctl = doc2001plus_enable_hwecc; | 1497 | this->ecc.hwctl = doc2001plus_enable_hwecc; |
@@ -1670,7 +1651,7 @@ static int __init doc_probe(unsigned long physadr) | |||
1670 | 1651 | ||
1671 | nand->priv = doc; | 1652 | nand->priv = doc; |
1672 | nand->select_chip = doc200x_select_chip; | 1653 | nand->select_chip = doc200x_select_chip; |
1673 | nand->hwcontrol = doc200x_hwcontrol; | 1654 | nand->cmd_ctrl = doc200x_hwcontrol; |
1674 | nand->dev_ready = doc200x_dev_ready; | 1655 | nand->dev_ready = doc200x_dev_ready; |
1675 | nand->waitfunc = doc200x_wait; | 1656 | nand->waitfunc = doc200x_wait; |
1676 | nand->block_bad = doc200x_block_bad; | 1657 | nand->block_bad = doc200x_block_bad; |
diff --git a/drivers/mtd/nand/edb7312.c b/drivers/mtd/nand/edb7312.c index 8e56570af91f..ba5a2174a408 100644 --- a/drivers/mtd/nand/edb7312.c +++ b/drivers/mtd/nand/edb7312.c | |||
@@ -73,32 +73,26 @@ static struct mtd_partition partition_info[] = { | |||
73 | 73 | ||
74 | /* | 74 | /* |
75 | * hardware specific access to control-lines | 75 | * hardware specific access to control-lines |
76 | * | ||
77 | * NAND_NCE: bit 0 -> bit 7 | ||
78 | * NAND_CLE: bit 1 -> bit 4 | ||
79 | * NAND_ALE: bit 2 -> bit 5 | ||
76 | */ | 80 | */ |
77 | static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd) | 81 | static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
78 | { | 82 | { |
79 | switch (cmd) { | 83 | struct nand_chip *chip = mtd->priv; |
80 | 84 | ||
81 | case NAND_CTL_SETCLE: | 85 | if (ctrl & NAND_CTRL_CHANGE) { |
82 | clps_writeb(clps_readb(ep7312_pxdr) | 0x10, ep7312_pxdr); | 86 | unsigned char bits; |
83 | break; | 87 | |
84 | case NAND_CTL_CLRCLE: | 88 | bits = (ctrl & (NAND_CLE | NAND_ALE)) << 3; |
85 | clps_writeb(clps_readb(ep7312_pxdr) & ~0x10, ep7312_pxdr); | 89 | bits = (ctrl & NAND_NCE) << 7; |
86 | break; | 90 | |
87 | 91 | clps_writeb((clps_readb(ep7312_pxdr) & 0xB0) | 0x10, | |
88 | case NAND_CTL_SETALE: | 92 | ep7312_pxdr); |
89 | clps_writeb(clps_readb(ep7312_pxdr) | 0x20, ep7312_pxdr); | ||
90 | break; | ||
91 | case NAND_CTL_CLRALE: | ||
92 | clps_writeb(clps_readb(ep7312_pxdr) & ~0x20, ep7312_pxdr); | ||
93 | break; | ||
94 | |||
95 | case NAND_CTL_SETNCE: | ||
96 | clps_writeb((clps_readb(ep7312_pxdr) | 0x80) & ~0x40, ep7312_pxdr); | ||
97 | break; | ||
98 | case NAND_CTL_CLRNCE: | ||
99 | clps_writeb((clps_readb(ep7312_pxdr) | 0x80) | 0x40, ep7312_pxdr); | ||
100 | break; | ||
101 | } | 93 | } |
94 | if (cmd != NAND_CMD_NONE) | ||
95 | writeb(cmd, chip->IO_ADDR_W); | ||
102 | } | 96 | } |
103 | 97 | ||
104 | /* | 98 | /* |
@@ -159,7 +153,7 @@ static int __init ep7312_init(void) | |||
159 | /* insert callbacks */ | 153 | /* insert callbacks */ |
160 | this->IO_ADDR_R = ep7312_fio_base; | 154 | this->IO_ADDR_R = ep7312_fio_base; |
161 | this->IO_ADDR_W = ep7312_fio_base; | 155 | this->IO_ADDR_W = ep7312_fio_base; |
162 | this->hwcontrol = ep7312_hwcontrol; | 156 | this->cmd_ctrl = ep7312_hwcontrol; |
163 | this->dev_ready = ep7312_device_ready; | 157 | this->dev_ready = ep7312_device_ready; |
164 | /* 15 us command delay time */ | 158 | /* 15 us command delay time */ |
165 | this->chip_delay = 15; | 159 | this->chip_delay = 15; |
diff --git a/drivers/mtd/nand/h1910.c b/drivers/mtd/nand/h1910.c index 06e91fa11b34..2d585d2d090c 100644 --- a/drivers/mtd/nand/h1910.c +++ b/drivers/mtd/nand/h1910.c | |||
@@ -56,36 +56,18 @@ static struct mtd_partition partition_info[] = { | |||
56 | 56 | ||
57 | /* | 57 | /* |
58 | * hardware specific access to control-lines | 58 | * hardware specific access to control-lines |
59 | * | ||
60 | * NAND_NCE: bit 0 - don't care | ||
61 | * NAND_CLE: bit 1 - address bit 2 | ||
62 | * NAND_ALE: bit 2 - address bit 3 | ||
59 | */ | 63 | */ |
60 | static void h1910_hwcontrol(struct mtd_info *mtd, int cmd) | 64 | static void h1910_hwcontrol(struct mtd_info *mtd, int cmd, |
65 | unsigned int ctrl) | ||
61 | { | 66 | { |
62 | struct nand_chip *this = (struct nand_chip *)(mtd->priv); | 67 | struct nand_chip *chip = mtd->priv; |
63 | 68 | ||
64 | switch (cmd) { | 69 | if (cmd != NAND_CMD_NONE) |
65 | 70 | writeb(cmd, chip->IO_ADDR_W | ((ctrl & 0x6) << 1)); | |
66 | case NAND_CTL_SETCLE: | ||
67 | this->IO_ADDR_R |= (1 << 2); | ||
68 | this->IO_ADDR_W |= (1 << 2); | ||
69 | break; | ||
70 | case NAND_CTL_CLRCLE: | ||
71 | this->IO_ADDR_R &= ~(1 << 2); | ||
72 | this->IO_ADDR_W &= ~(1 << 2); | ||
73 | break; | ||
74 | |||
75 | case NAND_CTL_SETALE: | ||
76 | this->IO_ADDR_R |= (1 << 3); | ||
77 | this->IO_ADDR_W |= (1 << 3); | ||
78 | break; | ||
79 | case NAND_CTL_CLRALE: | ||
80 | this->IO_ADDR_R &= ~(1 << 3); | ||
81 | this->IO_ADDR_W &= ~(1 << 3); | ||
82 | break; | ||
83 | |||
84 | case NAND_CTL_SETNCE: | ||
85 | break; | ||
86 | case NAND_CTL_CLRNCE: | ||
87 | break; | ||
88 | } | ||
89 | } | 71 | } |
90 | 72 | ||
91 | /* | 73 | /* |
@@ -145,7 +127,7 @@ static int __init h1910_init(void) | |||
145 | /* insert callbacks */ | 127 | /* insert callbacks */ |
146 | this->IO_ADDR_R = nandaddr; | 128 | this->IO_ADDR_R = nandaddr; |
147 | this->IO_ADDR_W = nandaddr; | 129 | this->IO_ADDR_W = nandaddr; |
148 | this->hwcontrol = h1910_hwcontrol; | 130 | this->cmd_ctrl = h1910_hwcontrol; |
149 | this->dev_ready = NULL; /* unknown whether that was correct or not so we will just do it like this */ | 131 | this->dev_ready = NULL; /* unknown whether that was correct or not so we will just do it like this */ |
150 | /* 15 us command delay time */ | 132 | /* 15 us command delay time */ |
151 | this->chip_delay = 50; | 133 | this->chip_delay = 50; |
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index aa2e14538bf4..f6997fb77b91 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -276,10 +276,10 @@ static void nand_select_chip(struct mtd_info *mtd, int chip) | |||
276 | struct nand_chip *this = mtd->priv; | 276 | struct nand_chip *this = mtd->priv; |
277 | switch (chip) { | 277 | switch (chip) { |
278 | case -1: | 278 | case -1: |
279 | this->hwcontrol(mtd, NAND_CTL_CLRNCE); | 279 | this->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE); |
280 | break; | 280 | break; |
281 | case 0: | 281 | case 0: |
282 | this->hwcontrol(mtd, NAND_CTL_SETNCE); | 282 | this->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); |
283 | break; | 283 | break; |
284 | 284 | ||
285 | default: | 285 | default: |
@@ -548,13 +548,12 @@ static void nand_wait_ready(struct mtd_info *mtd) | |||
548 | * Send command to NAND device. This function is used for small page | 548 | * Send command to NAND device. This function is used for small page |
549 | * devices (256/512 Bytes per page) | 549 | * devices (256/512 Bytes per page) |
550 | */ | 550 | */ |
551 | static void nand_command(struct mtd_info *mtd, unsigned command, int column, | 551 | static void nand_command(struct mtd_info *mtd, unsigned int command, |
552 | int page_addr) | 552 | int column, int page_addr) |
553 | { | 553 | { |
554 | register struct nand_chip *this = mtd->priv; | 554 | register struct nand_chip *this = mtd->priv; |
555 | int ctrl = NAND_CTRL_CLE | NAND_CTRL_CHANGE; | ||
555 | 556 | ||
556 | /* Begin command latch cycle */ | ||
557 | this->hwcontrol(mtd, NAND_CTL_SETCLE); | ||
558 | /* | 557 | /* |
559 | * Write out the command to the device. | 558 | * Write out the command to the device. |
560 | */ | 559 | */ |
@@ -572,33 +571,32 @@ static void nand_command(struct mtd_info *mtd, unsigned command, int column, | |||
572 | column -= 256; | 571 | column -= 256; |
573 | readcmd = NAND_CMD_READ1; | 572 | readcmd = NAND_CMD_READ1; |
574 | } | 573 | } |
575 | this->write_byte(mtd, readcmd); | 574 | this->cmd_ctrl(mtd, readcmd, ctrl); |
575 | ctrl &= ~NAND_CTRL_CHANGE; | ||
576 | } | 576 | } |
577 | this->write_byte(mtd, command); | 577 | this->cmd_ctrl(mtd, command, ctrl); |
578 | 578 | ||
579 | /* Set ALE and clear CLE to start address cycle */ | 579 | /* |
580 | this->hwcontrol(mtd, NAND_CTL_CLRCLE); | 580 | * Address cycle, when necessary |
581 | 581 | */ | |
582 | if (column != -1 || page_addr != -1) { | 582 | ctrl = NAND_CTRL_ALE | NAND_CTRL_CHANGE; |
583 | this->hwcontrol(mtd, NAND_CTL_SETALE); | 583 | /* Serially input address */ |
584 | 584 | if (column != -1) { | |
585 | /* Serially input address */ | 585 | /* Adjust columns for 16 bit buswidth */ |
586 | if (column != -1) { | 586 | if (this->options & NAND_BUSWIDTH_16) |
587 | /* Adjust columns for 16 bit buswidth */ | 587 | column >>= 1; |
588 | if (this->options & NAND_BUSWIDTH_16) | 588 | this->cmd_ctrl(mtd, column, ctrl); |
589 | column >>= 1; | 589 | ctrl &= ~NAND_CTRL_CHANGE; |
590 | this->write_byte(mtd, column); | 590 | } |
591 | } | 591 | if (page_addr != -1) { |
592 | if (page_addr != -1) { | 592 | this->cmd_ctrl(mtd, page_addr, ctrl); |
593 | this->write_byte(mtd, (uint8_t)(page_addr & 0xff)); | 593 | ctrl &= ~NAND_CTRL_CHANGE; |
594 | this->write_byte(mtd, (uint8_t)((page_addr >> 8) & 0xff)); | 594 | this->cmd_ctrl(mtd, page_addr >> 8, ctrl); |
595 | /* One more address cycle for devices > 32MiB */ | 595 | /* One more address cycle for devices > 32MiB */ |
596 | if (this->chipsize > (32 << 20)) | 596 | if (this->chipsize > (32 << 20)) |
597 | this->write_byte(mtd, (uint8_t)((page_addr >> 16) & 0x0f)); | 597 | this->cmd_ctrl(mtd, page_addr >> 16, ctrl); |
598 | } | ||
599 | /* Latch in address */ | ||
600 | this->hwcontrol(mtd, NAND_CTL_CLRALE); | ||
601 | } | 598 | } |
599 | this->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); | ||
602 | 600 | ||
603 | /* | 601 | /* |
604 | * program and erase have their own busy handlers | 602 | * program and erase have their own busy handlers |
@@ -611,15 +609,16 @@ static void nand_command(struct mtd_info *mtd, unsigned command, int column, | |||
611 | case NAND_CMD_ERASE2: | 609 | case NAND_CMD_ERASE2: |
612 | case NAND_CMD_SEQIN: | 610 | case NAND_CMD_SEQIN: |
613 | case NAND_CMD_STATUS: | 611 | case NAND_CMD_STATUS: |
612 | this->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE); | ||
614 | return; | 613 | return; |
615 | 614 | ||
616 | case NAND_CMD_RESET: | 615 | case NAND_CMD_RESET: |
617 | if (this->dev_ready) | 616 | if (this->dev_ready) |
618 | break; | 617 | break; |
619 | udelay(this->chip_delay); | 618 | udelay(this->chip_delay); |
620 | this->hwcontrol(mtd, NAND_CTL_SETCLE); | 619 | this->cmd_ctrl(mtd, NAND_CMD_STATUS, |
621 | this->write_byte(mtd, NAND_CMD_STATUS); | 620 | NAND_CTRL_CLE | NAND_CTRL_CHANGE); |
622 | this->hwcontrol(mtd, NAND_CTL_CLRCLE); | 621 | this->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE); |
623 | while (!(this->read_byte(mtd) & NAND_STATUS_READY)) ; | 622 | while (!(this->read_byte(mtd) & NAND_STATUS_READY)) ; |
624 | return; | 623 | return; |
625 | 624 | ||
@@ -648,12 +647,13 @@ static void nand_command(struct mtd_info *mtd, unsigned command, int column, | |||
648 | * @column: the column address for this command, -1 if none | 647 | * @column: the column address for this command, -1 if none |
649 | * @page_addr: the page address for this command, -1 if none | 648 | * @page_addr: the page address for this command, -1 if none |
650 | * | 649 | * |
651 | * Send command to NAND device. This is the version for the new large page devices | 650 | * Send command to NAND device. This is the version for the new large page |
652 | * We dont have the separate regions as we have in the small page devices. | 651 | * devices We dont have the separate regions as we have in the small page |
653 | * We must emulate NAND_CMD_READOOB to keep the code compatible. | 652 | * devices. We must emulate NAND_CMD_READOOB to keep the code compatible. |
654 | * | 653 | * |
655 | */ | 654 | */ |
656 | static void nand_command_lp(struct mtd_info *mtd, unsigned command, int column, int page_addr) | 655 | static void nand_command_lp(struct mtd_info *mtd, unsigned int command, |
656 | int column, int page_addr) | ||
657 | { | 657 | { |
658 | register struct nand_chip *this = mtd->priv; | 658 | register struct nand_chip *this = mtd->priv; |
659 | 659 | ||
@@ -663,34 +663,33 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned command, int column, | |||
663 | command = NAND_CMD_READ0; | 663 | command = NAND_CMD_READ0; |
664 | } | 664 | } |
665 | 665 | ||
666 | /* Begin command latch cycle */ | 666 | /* Command latch cycle */ |
667 | this->hwcontrol(mtd, NAND_CTL_SETCLE); | 667 | this->cmd_ctrl(mtd, command & 0xff, |
668 | /* Write out the command to the device. */ | 668 | NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE); |
669 | this->write_byte(mtd, (command & 0xff)); | ||
670 | /* End command latch cycle */ | ||
671 | this->hwcontrol(mtd, NAND_CTL_CLRCLE); | ||
672 | 669 | ||
673 | if (column != -1 || page_addr != -1) { | 670 | if (column != -1 || page_addr != -1) { |
674 | this->hwcontrol(mtd, NAND_CTL_SETALE); | 671 | int ctrl = NAND_CTRL_CHANGE | NAND_NCE | NAND_ALE; |
675 | 672 | ||
676 | /* Serially input address */ | 673 | /* Serially input address */ |
677 | if (column != -1) { | 674 | if (column != -1) { |
678 | /* Adjust columns for 16 bit buswidth */ | 675 | /* Adjust columns for 16 bit buswidth */ |
679 | if (this->options & NAND_BUSWIDTH_16) | 676 | if (this->options & NAND_BUSWIDTH_16) |
680 | column >>= 1; | 677 | column >>= 1; |
681 | this->write_byte(mtd, column & 0xff); | 678 | this->cmd_ctrl(mtd, column, ctrl); |
682 | this->write_byte(mtd, column >> 8); | 679 | ctrl &= ~NAND_CTRL_CHANGE; |
680 | this->cmd_ctrl(mtd, column >> 8, ctrl); | ||
683 | } | 681 | } |
684 | if (page_addr != -1) { | 682 | if (page_addr != -1) { |
685 | this->write_byte(mtd, (uint8_t)(page_addr & 0xff)); | 683 | this->cmd_ctrl(mtd, page_addr, ctrl); |
686 | this->write_byte(mtd, (uint8_t)((page_addr >> 8) & 0xff)); | 684 | this->cmd_ctrl(mtd, page_addr >> 8, |
685 | NAND_NCE | NAND_ALE); | ||
687 | /* One more address cycle for devices > 128MiB */ | 686 | /* One more address cycle for devices > 128MiB */ |
688 | if (this->chipsize > (128 << 20)) | 687 | if (this->chipsize > (128 << 20)) |
689 | this->write_byte(mtd, (uint8_t)((page_addr >> 16) & 0xff)); | 688 | this->cmd_ctrl(mtd, page_addr >> 16, |
689 | NAND_NCE | NAND_ALE); | ||
690 | } | 690 | } |
691 | /* Latch in address */ | ||
692 | this->hwcontrol(mtd, NAND_CTL_CLRALE); | ||
693 | } | 691 | } |
692 | this->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); | ||
694 | 693 | ||
695 | /* | 694 | /* |
696 | * program and erase have their own busy handlers | 695 | * program and erase have their own busy handlers |
@@ -722,20 +721,14 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned command, int column, | |||
722 | if (this->dev_ready) | 721 | if (this->dev_ready) |
723 | break; | 722 | break; |
724 | udelay(this->chip_delay); | 723 | udelay(this->chip_delay); |
725 | this->hwcontrol(mtd, NAND_CTL_SETCLE); | 724 | this->cmd_ctrl(mtd, NAND_CMD_STATUS, NAND_NCE | NAND_CLE); |
726 | this->write_byte(mtd, NAND_CMD_STATUS); | 725 | this->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE); |
727 | this->hwcontrol(mtd, NAND_CTL_CLRCLE); | ||
728 | while (!(this->read_byte(mtd) & NAND_STATUS_READY)) ; | 726 | while (!(this->read_byte(mtd) & NAND_STATUS_READY)) ; |
729 | return; | 727 | return; |
730 | 728 | ||
731 | case NAND_CMD_READ0: | 729 | case NAND_CMD_READ0: |
732 | /* Begin command latch cycle */ | 730 | this->cmd_ctrl(mtd, NAND_CMD_READSTART, NAND_NCE | NAND_CLE); |
733 | this->hwcontrol(mtd, NAND_CTL_SETCLE); | 731 | this->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE); |
734 | /* Write out the start read command */ | ||
735 | this->write_byte(mtd, NAND_CMD_READSTART); | ||
736 | /* End command latch cycle */ | ||
737 | this->hwcontrol(mtd, NAND_CTL_CLRCLE); | ||
738 | /* Fall through into ready check */ | ||
739 | 732 | ||
740 | /* This applies to read commands */ | 733 | /* This applies to read commands */ |
741 | default: | 734 | default: |
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index 22af9b29d2bf..ecf727b32dec 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c | |||
@@ -1071,68 +1071,6 @@ switch_state(struct nandsim *ns) | |||
1071 | } | 1071 | } |
1072 | } | 1072 | } |
1073 | 1073 | ||
1074 | static void | ||
1075 | ns_hwcontrol(struct mtd_info *mtd, int cmd) | ||
1076 | { | ||
1077 | struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; | ||
1078 | |||
1079 | switch (cmd) { | ||
1080 | |||
1081 | /* set CLE line high */ | ||
1082 | case NAND_CTL_SETCLE: | ||
1083 | NS_DBG("ns_hwcontrol: start command latch cycles\n"); | ||
1084 | ns->lines.cle = 1; | ||
1085 | break; | ||
1086 | |||
1087 | /* set CLE line low */ | ||
1088 | case NAND_CTL_CLRCLE: | ||
1089 | NS_DBG("ns_hwcontrol: stop command latch cycles\n"); | ||
1090 | ns->lines.cle = 0; | ||
1091 | break; | ||
1092 | |||
1093 | /* set ALE line high */ | ||
1094 | case NAND_CTL_SETALE: | ||
1095 | NS_DBG("ns_hwcontrol: start address latch cycles\n"); | ||
1096 | ns->lines.ale = 1; | ||
1097 | break; | ||
1098 | |||
1099 | /* set ALE line low */ | ||
1100 | case NAND_CTL_CLRALE: | ||
1101 | NS_DBG("ns_hwcontrol: stop address latch cycles\n"); | ||
1102 | ns->lines.ale = 0; | ||
1103 | break; | ||
1104 | |||
1105 | /* set WP line high */ | ||
1106 | case NAND_CTL_SETWP: | ||
1107 | NS_DBG("ns_hwcontrol: enable write protection\n"); | ||
1108 | ns->lines.wp = 1; | ||
1109 | break; | ||
1110 | |||
1111 | /* set WP line low */ | ||
1112 | case NAND_CTL_CLRWP: | ||
1113 | NS_DBG("ns_hwcontrol: disable write protection\n"); | ||
1114 | ns->lines.wp = 0; | ||
1115 | break; | ||
1116 | |||
1117 | /* set CE line low */ | ||
1118 | case NAND_CTL_SETNCE: | ||
1119 | NS_DBG("ns_hwcontrol: enable chip\n"); | ||
1120 | ns->lines.ce = 1; | ||
1121 | break; | ||
1122 | |||
1123 | /* set CE line high */ | ||
1124 | case NAND_CTL_CLRNCE: | ||
1125 | NS_DBG("ns_hwcontrol: disable chip\n"); | ||
1126 | ns->lines.ce = 0; | ||
1127 | break; | ||
1128 | |||
1129 | default: | ||
1130 | NS_ERR("hwcontrol: unknown command\n"); | ||
1131 | } | ||
1132 | |||
1133 | return; | ||
1134 | } | ||
1135 | |||
1136 | static u_char | 1074 | static u_char |
1137 | ns_nand_read_byte(struct mtd_info *mtd) | 1075 | ns_nand_read_byte(struct mtd_info *mtd) |
1138 | { | 1076 | { |
@@ -1359,6 +1297,18 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte) | |||
1359 | return; | 1297 | return; |
1360 | } | 1298 | } |
1361 | 1299 | ||
1300 | static void ns_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int bitmask) | ||
1301 | { | ||
1302 | struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv; | ||
1303 | |||
1304 | ns->lines.cle = bitmask & NAND_CLE ? 1 : 0; | ||
1305 | ns->lines.ale = bitmask & NAND_ALE ? 1 : 0; | ||
1306 | ns->lines.ce = bitmask & NAND_NCE ? 1 : 0; | ||
1307 | |||
1308 | if (cmd != NAND_CMD_NONE) | ||
1309 | ns_nand_write_byte(mtd, cmd); | ||
1310 | } | ||
1311 | |||
1362 | static int | 1312 | static int |
1363 | ns_device_ready(struct mtd_info *mtd) | 1313 | ns_device_ready(struct mtd_info *mtd) |
1364 | { | 1314 | { |
@@ -1514,7 +1464,7 @@ static int __init ns_init_module(void) | |||
1514 | /* | 1464 | /* |
1515 | * Register simulator's callbacks. | 1465 | * Register simulator's callbacks. |
1516 | */ | 1466 | */ |
1517 | chip->hwcontrol = ns_hwcontrol; | 1467 | chip->cmd_ctrl = ns_hwcontrol; |
1518 | chip->read_byte = ns_nand_read_byte; | 1468 | chip->read_byte = ns_nand_read_byte; |
1519 | chip->dev_ready = ns_device_ready; | 1469 | chip->dev_ready = ns_device_ready; |
1520 | chip->write_byte = ns_nand_write_byte; | 1470 | chip->write_byte = ns_nand_write_byte; |
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index e2dc81de106a..481541a683ca 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c | |||
@@ -60,22 +60,17 @@ static void ndfc_select_chip(struct mtd_info *mtd, int chip) | |||
60 | writel(ccr, ndfc->ndfcbase + NDFC_CCR); | 60 | writel(ccr, ndfc->ndfcbase + NDFC_CCR); |
61 | } | 61 | } |
62 | 62 | ||
63 | static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd) | 63 | static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
64 | { | 64 | { |
65 | struct ndfc_controller *ndfc = &ndfc_ctrl; | ||
66 | struct nand_chip *chip = mtd->priv; | 65 | struct nand_chip *chip = mtd->priv; |
67 | 66 | ||
68 | switch (cmd) { | 67 | if (cmd == NAND_CMD_NONE) |
69 | case NAND_CTL_SETCLE: | 68 | return; |
70 | chip->IO_ADDR_W = ndfc->ndfcbase + NDFC_CMD; | 69 | |
71 | break; | 70 | if (ctrl & NAND_CLE) |
72 | case NAND_CTL_SETALE: | 71 | writel(cmd & 0xFF, chip->IO_ADDR_W + NDFC_CMD); |
73 | chip->IO_ADDR_W = ndfc->ndfcbase + NDFC_ALE; | 72 | else |
74 | break; | 73 | writel(cmd & 0xFF, chip->IO_ADDR_W + NDFC_ALE); |
75 | default: | ||
76 | chip->IO_ADDR_W = ndfc->ndfcbase + NDFC_DATA; | ||
77 | break; | ||
78 | } | ||
79 | } | 74 | } |
80 | 75 | ||
81 | static int ndfc_ready(struct mtd_info *mtd) | 76 | static int ndfc_ready(struct mtd_info *mtd) |
@@ -158,7 +153,7 @@ static void ndfc_chip_init(struct ndfc_nand_mtd *mtd) | |||
158 | 153 | ||
159 | chip->IO_ADDR_R = ndfc->ndfcbase + NDFC_DATA; | 154 | chip->IO_ADDR_R = ndfc->ndfcbase + NDFC_DATA; |
160 | chip->IO_ADDR_W = ndfc->ndfcbase + NDFC_DATA; | 155 | chip->IO_ADDR_W = ndfc->ndfcbase + NDFC_DATA; |
161 | chip->hwcontrol = ndfc_hwcontrol; | 156 | chip->cmd_ctrl = ndfc_hwcontrol; |
162 | chip->dev_ready = ndfc_ready; | 157 | chip->dev_ready = ndfc_ready; |
163 | chip->select_chip = ndfc_select_chip; | 158 | chip->select_chip = ndfc_select_chip; |
164 | chip->chip_delay = 50; | 159 | chip->chip_delay = 50; |
diff --git a/drivers/mtd/nand/ppchameleonevb.c b/drivers/mtd/nand/ppchameleonevb.c index 9fab0998524d..22fa65c12ab9 100644 --- a/drivers/mtd/nand/ppchameleonevb.c +++ b/drivers/mtd/nand/ppchameleonevb.c | |||
@@ -108,54 +108,68 @@ extern int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partitio | |||
108 | /* | 108 | /* |
109 | * hardware specific access to control-lines | 109 | * hardware specific access to control-lines |
110 | */ | 110 | */ |
111 | static void ppchameleon_hwcontrol(struct mtd_info *mtdinfo, int cmd) | 111 | static void ppchameleon_hwcontrol(struct mtd_info *mtdinfo, int cmd, |
112 | unsigned int ctrl) | ||
112 | { | 113 | { |
113 | switch (cmd) { | 114 | struct nand_chip *chip = mtd->priv; |
114 | 115 | ||
115 | case NAND_CTL_SETCLE: | 116 | if (ctrl & NAND_CTRL_CHANGE) { |
116 | MACRO_NAND_CTL_SETCLE((unsigned long)CFG_NAND0_PADDR); | 117 | #error Missing headerfiles. No way to fix this. -tglx |
117 | break; | 118 | switch (cmd) { |
118 | case NAND_CTL_CLRCLE: | 119 | case NAND_CTL_SETCLE: |
119 | MACRO_NAND_CTL_CLRCLE((unsigned long)CFG_NAND0_PADDR); | 120 | MACRO_NAND_CTL_SETCLE((unsigned long)CFG_NAND0_PADDR); |
120 | break; | 121 | break; |
121 | case NAND_CTL_SETALE: | 122 | case NAND_CTL_CLRCLE: |
122 | MACRO_NAND_CTL_SETALE((unsigned long)CFG_NAND0_PADDR); | 123 | MACRO_NAND_CTL_CLRCLE((unsigned long)CFG_NAND0_PADDR); |
123 | break; | 124 | break; |
124 | case NAND_CTL_CLRALE: | 125 | case NAND_CTL_SETALE: |
125 | MACRO_NAND_CTL_CLRALE((unsigned long)CFG_NAND0_PADDR); | 126 | MACRO_NAND_CTL_SETALE((unsigned long)CFG_NAND0_PADDR); |
126 | break; | 127 | break; |
127 | case NAND_CTL_SETNCE: | 128 | case NAND_CTL_CLRALE: |
128 | MACRO_NAND_ENABLE_CE((unsigned long)CFG_NAND0_PADDR); | 129 | MACRO_NAND_CTL_CLRALE((unsigned long)CFG_NAND0_PADDR); |
129 | break; | 130 | break; |
130 | case NAND_CTL_CLRNCE: | 131 | case NAND_CTL_SETNCE: |
131 | MACRO_NAND_DISABLE_CE((unsigned long)CFG_NAND0_PADDR); | 132 | MACRO_NAND_ENABLE_CE((unsigned long)CFG_NAND0_PADDR); |
132 | break; | 133 | break; |
134 | case NAND_CTL_CLRNCE: | ||
135 | MACRO_NAND_DISABLE_CE((unsigned long)CFG_NAND0_PADDR); | ||
136 | break; | ||
137 | } | ||
133 | } | 138 | } |
139 | if (cmd != NAND_CMD_NONE) | ||
140 | writeb(cmd, chip->IO_ADDR_W); | ||
134 | } | 141 | } |
135 | 142 | ||
136 | static void ppchameleonevb_hwcontrol(struct mtd_info *mtdinfo, int cmd) | 143 | static void ppchameleonevb_hwcontrol(struct mtd_info *mtdinfo, int cmd, |
144 | unsigned int ctrl) | ||
137 | { | 145 | { |
138 | switch (cmd) { | 146 | struct nand_chip *chip = mtd->priv; |
139 | 147 | ||
140 | case NAND_CTL_SETCLE: | 148 | if (ctrl & NAND_CTRL_CHANGE) { |
141 | MACRO_NAND_CTL_SETCLE((unsigned long)CFG_NAND1_PADDR); | 149 | #error Missing headerfiles. No way to fix this. -tglx |
142 | break; | 150 | switch (cmd) { |
143 | case NAND_CTL_CLRCLE: | 151 | case NAND_CTL_SETCLE: |
144 | MACRO_NAND_CTL_CLRCLE((unsigned long)CFG_NAND1_PADDR); | 152 | MACRO_NAND_CTL_SETCLE((unsigned long)CFG_NAND1_PADDR); |
145 | break; | 153 | break; |
146 | case NAND_CTL_SETALE: | 154 | case NAND_CTL_CLRCLE: |
147 | MACRO_NAND_CTL_SETALE((unsigned long)CFG_NAND1_PADDR); | 155 | MACRO_NAND_CTL_CLRCLE((unsigned long)CFG_NAND1_PADDR); |
148 | break; | 156 | break; |
149 | case NAND_CTL_CLRALE: | 157 | case NAND_CTL_SETALE: |
150 | MACRO_NAND_CTL_CLRALE((unsigned long)CFG_NAND1_PADDR); | 158 | MACRO_NAND_CTL_SETALE((unsigned long)CFG_NAND1_PADDR); |
151 | break; | 159 | break; |
152 | case NAND_CTL_SETNCE: | 160 | case NAND_CTL_CLRALE: |
153 | MACRO_NAND_ENABLE_CE((unsigned long)CFG_NAND1_PADDR); | 161 | MACRO_NAND_CTL_CLRALE((unsigned long)CFG_NAND1_PADDR); |
154 | break; | 162 | break; |
155 | case NAND_CTL_CLRNCE: | 163 | case NAND_CTL_SETNCE: |
156 | MACRO_NAND_DISABLE_CE((unsigned long)CFG_NAND1_PADDR); | 164 | MACRO_NAND_ENABLE_CE((unsigned long)CFG_NAND1_PADDR); |
157 | break; | 165 | break; |
166 | case NAND_CTL_CLRNCE: | ||
167 | MACRO_NAND_DISABLE_CE((unsigned long)CFG_NAND1_PADDR); | ||
168 | break; | ||
169 | } | ||
158 | } | 170 | } |
171 | if (cmd != NAND_CMD_NONE) | ||
172 | writeb(cmd, chip->IO_ADDR_W); | ||
159 | } | 173 | } |
160 | 174 | ||
161 | #ifdef USE_READY_BUSY_PIN | 175 | #ifdef USE_READY_BUSY_PIN |
@@ -251,7 +265,7 @@ static int __init ppchameleonevb_init(void) | |||
251 | /* insert callbacks */ | 265 | /* insert callbacks */ |
252 | this->IO_ADDR_R = ppchameleon_fio_base; | 266 | this->IO_ADDR_R = ppchameleon_fio_base; |
253 | this->IO_ADDR_W = ppchameleon_fio_base; | 267 | this->IO_ADDR_W = ppchameleon_fio_base; |
254 | this->hwcontrol = ppchameleon_hwcontrol; | 268 | this->cmd_ctrl = ppchameleon_hwcontrol; |
255 | #ifdef USE_READY_BUSY_PIN | 269 | #ifdef USE_READY_BUSY_PIN |
256 | this->dev_ready = ppchameleon_device_ready; | 270 | this->dev_ready = ppchameleon_device_ready; |
257 | #endif | 271 | #endif |
@@ -351,7 +365,7 @@ static int __init ppchameleonevb_init(void) | |||
351 | /* insert callbacks */ | 365 | /* insert callbacks */ |
352 | this->IO_ADDR_R = ppchameleonevb_fio_base; | 366 | this->IO_ADDR_R = ppchameleonevb_fio_base; |
353 | this->IO_ADDR_W = ppchameleonevb_fio_base; | 367 | this->IO_ADDR_W = ppchameleonevb_fio_base; |
354 | this->hwcontrol = ppchameleonevb_hwcontrol; | 368 | this->cmd_ctrl = ppchameleonevb_hwcontrol; |
355 | #ifdef USE_READY_BUSY_PIN | 369 | #ifdef USE_READY_BUSY_PIN |
356 | this->dev_ready = ppchameleonevb_device_ready; | 370 | this->dev_ready = ppchameleonevb_device_ready; |
357 | #endif | 371 | #endif |
diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c index f8e631c89a60..6c97bfaea19a 100644 --- a/drivers/mtd/nand/rtc_from4.c +++ b/drivers/mtd/nand/rtc_from4.c | |||
@@ -208,32 +208,18 @@ static uint8_t revbits[256] = { | |||
208 | * Address lines (A24-A22), so no action is required here. | 208 | * Address lines (A24-A22), so no action is required here. |
209 | * | 209 | * |
210 | */ | 210 | */ |
211 | static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd) | 211 | static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd, |
212 | unsigned int ctrl) | ||
212 | { | 213 | { |
213 | struct nand_chip *this = (struct nand_chip *)(mtd->priv); | 214 | struct nand_chip *chip = (mtd->priv); |
214 | 215 | ||
215 | switch (cmd) { | 216 | if (cmd == NAND_CMD_NONE) |
217 | return; | ||
216 | 218 | ||
217 | case NAND_CTL_SETCLE: | 219 | if (ctrl & NAND_CLE) |
218 | this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_CLE); | 220 | writeb(cmd, chip->IO_ADDR_W | RTC_FROM4_CLE); |
219 | break; | 221 | else |
220 | case NAND_CTL_CLRCLE: | 222 | writeb(cmd, chip->IO_ADDR_W | RTC_FROM4_ALE); |
221 | this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_CLE); | ||
222 | break; | ||
223 | |||
224 | case NAND_CTL_SETALE: | ||
225 | this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_ALE); | ||
226 | break; | ||
227 | case NAND_CTL_CLRALE: | ||
228 | this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_ALE); | ||
229 | break; | ||
230 | |||
231 | case NAND_CTL_SETNCE: | ||
232 | break; | ||
233 | case NAND_CTL_CLRNCE: | ||
234 | break; | ||
235 | |||
236 | } | ||
237 | } | 223 | } |
238 | 224 | ||
239 | /* | 225 | /* |
@@ -559,7 +545,7 @@ static int __init rtc_from4_init(void) | |||
559 | this->IO_ADDR_R = rtc_from4_fio_base; | 545 | this->IO_ADDR_R = rtc_from4_fio_base; |
560 | this->IO_ADDR_W = rtc_from4_fio_base; | 546 | this->IO_ADDR_W = rtc_from4_fio_base; |
561 | /* Set address of hardware control function */ | 547 | /* Set address of hardware control function */ |
562 | this->hwcontrol = rtc_from4_hwcontrol; | 548 | this->cmd_ctrl = rtc_from4_hwcontrol; |
563 | /* Set address of chip select function */ | 549 | /* Set address of chip select function */ |
564 | this->select_chip = rtc_from4_nand_select_chip; | 550 | this->select_chip = rtc_from4_nand_select_chip; |
565 | /* command delay time (in us) */ | 551 | /* command delay time (in us) */ |
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 608340a25278..215227d1a65c 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c | |||
@@ -256,60 +256,36 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) | |||
256 | * | 256 | * |
257 | */ | 257 | */ |
258 | 258 | ||
259 | static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd) | 259 | static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd, |
260 | unsigend int ctrl) | ||
260 | { | 261 | { |
261 | struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); | 262 | struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); |
262 | struct nand_chip *chip = mtd->priv; | 263 | struct nand_chip *chip = mtd->priv; |
263 | 264 | ||
264 | switch (cmd) { | 265 | if (cmd == NAND_CMD_NONE) |
265 | case NAND_CTL_SETNCE: | 266 | return; |
266 | case NAND_CTL_CLRNCE: | 267 | |
267 | printk(KERN_ERR "%s: called for NCE\n", __FUNCTION__); | 268 | if (cmd & NAND_CLE) |
268 | break; | 269 | writeb(cmd, info->regs + S3C2410_NFCMD); |
269 | 270 | else | |
270 | case NAND_CTL_SETCLE: | 271 | writeb(cmd, info->regs + S3C2410_NFADDR); |
271 | chip->IO_ADDR_W = info->regs + S3C2410_NFCMD; | ||
272 | break; | ||
273 | |||
274 | case NAND_CTL_SETALE: | ||
275 | chip->IO_ADDR_W = info->regs + S3C2410_NFADDR; | ||
276 | break; | ||
277 | |||
278 | /* NAND_CTL_CLRCLE: */ | ||
279 | /* NAND_CTL_CLRALE: */ | ||
280 | default: | ||
281 | chip->IO_ADDR_W = info->regs + S3C2410_NFDATA; | ||
282 | break; | ||
283 | } | ||
284 | } | 272 | } |
285 | 273 | ||
286 | /* command and control functions */ | 274 | /* command and control functions */ |
287 | 275 | ||
288 | static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd) | 276 | static void s3c2410_nand_hwcontrol(struct mtd_info *mtd, int cmd, |
277 | unsigend int ctrl) | ||
289 | { | 278 | { |
290 | struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); | 279 | struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); |
291 | struct nand_chip *chip = mtd->priv; | 280 | struct nand_chip *chip = mtd->priv; |
292 | 281 | ||
293 | switch (cmd) { | 282 | if (cmd == NAND_CMD_NONE) |
294 | case NAND_CTL_SETNCE: | 283 | return; |
295 | case NAND_CTL_CLRNCE: | 284 | |
296 | printk(KERN_ERR "%s: called for NCE\n", __FUNCTION__); | 285 | if (cmd & NAND_CLE) |
297 | break; | 286 | writeb(cmd, info->regs + S3C2440_NFCMD); |
298 | 287 | else | |
299 | case NAND_CTL_SETCLE: | 288 | writeb(cmd, info->regs + S3C2440_NFADDR); |
300 | chip->IO_ADDR_W = info->regs + S3C2440_NFCMD; | ||
301 | break; | ||
302 | |||
303 | case NAND_CTL_SETALE: | ||
304 | chip->IO_ADDR_W = info->regs + S3C2440_NFADDR; | ||
305 | break; | ||
306 | |||
307 | /* NAND_CTL_CLRCLE: */ | ||
308 | /* NAND_CTL_CLRALE: */ | ||
309 | default: | ||
310 | chip->IO_ADDR_W = info->regs + S3C2440_NFDATA; | ||
311 | break; | ||
312 | } | ||
313 | } | 289 | } |
314 | 290 | ||
315 | /* s3c2410_nand_devready() | 291 | /* s3c2410_nand_devready() |
@@ -498,7 +474,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, | |||
498 | 474 | ||
499 | chip->IO_ADDR_R = info->regs + S3C2410_NFDATA; | 475 | chip->IO_ADDR_R = info->regs + S3C2410_NFDATA; |
500 | chip->IO_ADDR_W = info->regs + S3C2410_NFDATA; | 476 | chip->IO_ADDR_W = info->regs + S3C2410_NFDATA; |
501 | chip->hwcontrol = s3c2410_nand_hwcontrol; | 477 | chip->cmd_ctrl = s3c2410_nand_hwcontrol; |
502 | chip->dev_ready = s3c2410_nand_devready; | 478 | chip->dev_ready = s3c2410_nand_devready; |
503 | chip->write_buf = s3c2410_nand_write_buf; | 479 | chip->write_buf = s3c2410_nand_write_buf; |
504 | chip->read_buf = s3c2410_nand_read_buf; | 480 | chip->read_buf = s3c2410_nand_read_buf; |
@@ -511,7 +487,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, | |||
511 | if (info->is_s3c2440) { | 487 | if (info->is_s3c2440) { |
512 | chip->IO_ADDR_R = info->regs + S3C2440_NFDATA; | 488 | chip->IO_ADDR_R = info->regs + S3C2440_NFDATA; |
513 | chip->IO_ADDR_W = info->regs + S3C2440_NFDATA; | 489 | chip->IO_ADDR_W = info->regs + S3C2440_NFDATA; |
514 | chip->hwcontrol = s3c2440_nand_hwcontrol; | 490 | chip->cmd_ctrl = s3c2440_nand_hwcontrol; |
515 | } | 491 | } |
516 | 492 | ||
517 | nmtd->info = info; | 493 | nmtd->info = info; |
diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c index 5554d0b97c8c..45a1da724bff 100644 --- a/drivers/mtd/nand/sharpsl.c +++ b/drivers/mtd/nand/sharpsl.c | |||
@@ -77,31 +77,26 @@ static struct mtd_partition sharpsl_nand_default_partition_info[] = { | |||
77 | 77 | ||
78 | /* | 78 | /* |
79 | * hardware specific access to control-lines | 79 | * hardware specific access to control-lines |
80 | * ctrl: | ||
81 | * NAND_CNE: bit 0 -> bit 0 & 4 | ||
82 | * NAND_CLE: bit 1 -> bit 1 | ||
83 | * NAND_ALE: bit 2 -> bit 2 | ||
84 | * | ||
80 | */ | 85 | */ |
81 | static void sharpsl_nand_hwcontrol(struct mtd_info *mtd, int cmd) | 86 | static void sharpsl_nand_hwcontrol(struct mtd_info *mtd, int cmd, |
87 | unsigned int ctrl) | ||
82 | { | 88 | { |
83 | switch (cmd) { | 89 | struct nand_chip *chip = mtd->priv; |
84 | case NAND_CTL_SETCLE: | 90 | |
85 | writeb(readb(FLASHCTL) | FLCLE, FLASHCTL); | 91 | if (ctrl & NAND_CTRL_CHANGE) { |
86 | break; | 92 | unsigned char bits = ctrl & 0x07; |
87 | case NAND_CTL_CLRCLE: | 93 | |
88 | writeb(readb(FLASHCTL) & ~FLCLE, FLASHCTL); | 94 | bits |= (ctrl & 0x01) << 4; |
89 | break; | 95 | writeb((readb(FLASHCTL) & 0x17) | bits, FLASHCTL); |
90 | |||
91 | case NAND_CTL_SETALE: | ||
92 | writeb(readb(FLASHCTL) | FLALE, FLASHCTL); | ||
93 | break; | ||
94 | case NAND_CTL_CLRALE: | ||
95 | writeb(readb(FLASHCTL) & ~FLALE, FLASHCTL); | ||
96 | break; | ||
97 | |||
98 | case NAND_CTL_SETNCE: | ||
99 | writeb(readb(FLASHCTL) & ~(FLCE0 | FLCE1), FLASHCTL); | ||
100 | break; | ||
101 | case NAND_CTL_CLRNCE: | ||
102 | writeb(readb(FLASHCTL) | (FLCE0 | FLCE1), FLASHCTL); | ||
103 | break; | ||
104 | } | 96 | } |
97 | |||
98 | if (cmd != NAND_CMD_NONE) | ||
99 | writeb(cmd, chip->IO_ADDR_W); | ||
105 | } | 100 | } |
106 | 101 | ||
107 | static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; | 102 | static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; |
@@ -196,7 +191,7 @@ static int __init sharpsl_nand_init(void) | |||
196 | this->IO_ADDR_R = FLASHIO; | 191 | this->IO_ADDR_R = FLASHIO; |
197 | this->IO_ADDR_W = FLASHIO; | 192 | this->IO_ADDR_W = FLASHIO; |
198 | /* Set address of hardware control function */ | 193 | /* Set address of hardware control function */ |
199 | this->hwcontrol = sharpsl_nand_hwcontrol; | 194 | this->cmd_ctrl = sharpsl_nand_hwcontrol; |
200 | this->dev_ready = sharpsl_nand_dev_ready; | 195 | this->dev_ready = sharpsl_nand_dev_ready; |
201 | /* 15 us command delay time */ | 196 | /* 15 us command delay time */ |
202 | this->chip_delay = 15; | 197 | this->chip_delay = 15; |
diff --git a/drivers/mtd/nand/spia.c b/drivers/mtd/nand/spia.c index 9737f1d67c3c..1f6d429b1583 100644 --- a/drivers/mtd/nand/spia.c +++ b/drivers/mtd/nand/spia.c | |||
@@ -82,20 +82,27 @@ static const struct mtd_partition partition_info[] = { | |||
82 | 82 | ||
83 | /* | 83 | /* |
84 | * hardware specific access to control-lines | 84 | * hardware specific access to control-lines |
85 | */ | 85 | * |
86 | * ctrl: | ||
87 | * NAND_CNE: bit 0 -> bit 2 | ||
88 | * NAND_CLE: bit 1 -> bit 0 | ||
89 | * NAND_ALE: bit 2 -> bit 1 | ||
90 | */ | ||
86 | static void spia_hwcontrol(struct mtd_info *mtd, int cmd) | 91 | static void spia_hwcontrol(struct mtd_info *mtd, int cmd) |
87 | { | 92 | { |
88 | switch (cmd) { | 93 | struct nand_chip *chip = mtd->priv; |
89 | 94 | ||
90 | case NAND_CTL_SETCLE: (*(volatile unsigned char *) (spia_io_base + spia_pedr)) |= 0x01; break; | 95 | if (ctrl & NAND_CTRL_CHANGE) { |
91 | case NAND_CTL_CLRCLE: (*(volatile unsigned char *) (spia_io_base + spia_pedr)) &= ~0x01; break; | 96 | void __iomem *addr = spia_io_base + spia_pedr; |
97 | unsigned char bits; | ||
92 | 98 | ||
93 | case NAND_CTL_SETALE: (*(volatile unsigned char *) (spia_io_base + spia_pedr)) |= 0x02; break; | 99 | bits = (ctrl & NAND_CNE) << 2; |
94 | case NAND_CTL_CLRALE: (*(volatile unsigned char *) (spia_io_base + spia_pedr)) &= ~0x02; break; | 100 | bits |= (ctrl & NAND_CLE | NAND_ALE) >> 1; |
95 | 101 | writeb((readb(addr) & ~0x7) | bits, addr); | |
96 | case NAND_CTL_SETNCE: (*(volatile unsigned char *) (spia_io_base + spia_pedr)) &= ~0x04; break; | ||
97 | case NAND_CTL_CLRNCE: (*(volatile unsigned char *) (spia_io_base + spia_pedr)) |= 0x04; break; | ||
98 | } | 102 | } |
103 | |||
104 | if (cmd != NAND_CMD_NONE) | ||
105 | writeb(cmd, chip->IO_ADDR_W); | ||
99 | } | 106 | } |
100 | 107 | ||
101 | /* | 108 | /* |
@@ -133,7 +140,7 @@ static int __init spia_init(void) | |||
133 | this->IO_ADDR_R = (void __iomem *)spia_fio_base; | 140 | this->IO_ADDR_R = (void __iomem *)spia_fio_base; |
134 | this->IO_ADDR_W = (void __iomem *)spia_fio_base; | 141 | this->IO_ADDR_W = (void __iomem *)spia_fio_base; |
135 | /* Set address of hardware control function */ | 142 | /* Set address of hardware control function */ |
136 | this->hwcontrol = spia_hwcontrol; | 143 | this->cmd_ctrl = spia_hwcontrol; |
137 | /* 15 us command delay time */ | 144 | /* 15 us command delay time */ |
138 | this->chip_delay = 15; | 145 | this->chip_delay = 15; |
139 | 146 | ||
diff --git a/drivers/mtd/nand/toto.c b/drivers/mtd/nand/toto.c index 50aa6a46911f..a9cf0190c27a 100644 --- a/drivers/mtd/nand/toto.c +++ b/drivers/mtd/nand/toto.c | |||
@@ -32,6 +32,8 @@ | |||
32 | #include <asm/arch-omap1510/hardware.h> | 32 | #include <asm/arch-omap1510/hardware.h> |
33 | #include <asm/arch/gpio.h> | 33 | #include <asm/arch/gpio.h> |
34 | 34 | ||
35 | #define CONFIG_NAND_WORKAROUND 1 | ||
36 | |||
35 | /* | 37 | /* |
36 | * MTD structure for TOTO board | 38 | * MTD structure for TOTO board |
37 | */ | 39 | */ |
@@ -39,25 +41,6 @@ static struct mtd_info *toto_mtd = NULL; | |||
39 | 41 | ||
40 | static unsigned long toto_io_base = OMAP_FLASH_1_BASE; | 42 | static unsigned long toto_io_base = OMAP_FLASH_1_BASE; |
41 | 43 | ||
42 | #define CONFIG_NAND_WORKAROUND 1 | ||
43 | |||
44 | #define NAND_NCE 0x4000 | ||
45 | #define NAND_CLE 0x1000 | ||
46 | #define NAND_ALE 0x0002 | ||
47 | #define NAND_MASK (NAND_CLE | NAND_ALE | NAND_NCE) | ||
48 | |||
49 | #define T_NAND_CTL_CLRALE(iob) gpiosetout(NAND_ALE, 0) | ||
50 | #define T_NAND_CTL_SETALE(iob) gpiosetout(NAND_ALE, NAND_ALE) | ||
51 | #ifdef CONFIG_NAND_WORKAROUND /* "some" dev boards busted, blue wired to rts2 :( */ | ||
52 | #define T_NAND_CTL_CLRCLE(iob) gpiosetout(NAND_CLE, 0); rts2setout(2, 2) | ||
53 | #define T_NAND_CTL_SETCLE(iob) gpiosetout(NAND_CLE, NAND_CLE); rts2setout(2, 0) | ||
54 | #else | ||
55 | #define T_NAND_CTL_CLRCLE(iob) gpiosetout(NAND_CLE, 0) | ||
56 | #define T_NAND_CTL_SETCLE(iob) gpiosetout(NAND_CLE, NAND_CLE) | ||
57 | #endif | ||
58 | #define T_NAND_CTL_SETNCE(iob) gpiosetout(NAND_NCE, 0) | ||
59 | #define T_NAND_CTL_CLRNCE(iob) gpiosetout(NAND_NCE, NAND_NCE) | ||
60 | |||
61 | /* | 44 | /* |
62 | * Define partitions for flash devices | 45 | * Define partitions for flash devices |
63 | */ | 46 | */ |
@@ -91,25 +74,43 @@ static struct mtd_partition partition_info32M[] = { | |||
91 | 74 | ||
92 | #define NUM_PARTITIONS32M 3 | 75 | #define NUM_PARTITIONS32M 3 |
93 | #define NUM_PARTITIONS64M 4 | 76 | #define NUM_PARTITIONS64M 4 |
77 | |||
94 | /* | 78 | /* |
95 | * hardware specific access to control-lines | 79 | * hardware specific access to control-lines |
96 | */ | 80 | * |
97 | 81 | * ctrl: | |
98 | static void toto_hwcontrol(struct mtd_info *mtd, int cmd) | 82 | * NAND_NCE: bit 0 -> bit 14 (0x4000) |
83 | * NAND_CLE: bit 1 -> bit 12 (0x1000) | ||
84 | * NAND_ALE: bit 2 -> bit 1 (0x0002) | ||
85 | */ | ||
86 | static void toto_hwcontrol(struct mtd_info *mtd, int cmd, | ||
87 | unsigned int ctrl) | ||
99 | { | 88 | { |
89 | struct nand_chip *chip = mtd->priv; | ||
90 | |||
91 | if (ctrl & NAND_CTRL_CHANGE) { | ||
92 | unsigned long bits; | ||
100 | 93 | ||
101 | udelay(1); /* hopefully enough time for tc make proceding write to clear */ | 94 | /* hopefully enough time for tc make proceding write to clear */ |
102 | switch (cmd) { | 95 | udelay(1); |
103 | case NAND_CTL_SETCLE: T_NAND_CTL_SETCLE(cmd); break; | ||
104 | case NAND_CTL_CLRCLE: T_NAND_CTL_CLRCLE(cmd); break; | ||
105 | 96 | ||
106 | case NAND_CTL_SETALE: T_NAND_CTL_SETALE(cmd); break; | 97 | bits = (~ctrl & NAND_NCE) << 14; |
107 | case NAND_CTL_CLRALE: T_NAND_CTL_CLRALE(cmd); break; | 98 | bits |= (ctrl & NAND_CLE) << 12; |
99 | bits |= (ctrl & NAND_ALE) >> 1; | ||
108 | 100 | ||
109 | case NAND_CTL_SETNCE: T_NAND_CTL_SETNCE(cmd); break; | 101 | #warning Wild guess as gpiosetout() is nowhere defined in the kernel source - tglx |
110 | case NAND_CTL_CLRNCE: T_NAND_CTL_CLRNCE(cmd); break; | 102 | gpiosetout(0x5002, bits); |
103 | |||
104 | #ifdef CONFIG_NAND_WORKAROUND | ||
105 | /* "some" dev boards busted, blue wired to rts2 :( */ | ||
106 | rts2setout(2, (ctrl & NAND_CLE) << 1); | ||
107 | #endif | ||
108 | /* allow time to ensure gpio state to over take memory write */ | ||
109 | udelay(1); | ||
111 | } | 110 | } |
112 | udelay(1); /* allow time to ensure gpio state to over take memory write */ | 111 | |
112 | if (cmd != NAND_CMD_NONE) | ||
113 | writeb(cmd, chip->IO_ADDR_W); | ||
113 | } | 114 | } |
114 | 115 | ||
115 | /* | 116 | /* |
@@ -142,7 +143,7 @@ static int __init toto_init(void) | |||
142 | /* Set address of NAND IO lines */ | 143 | /* Set address of NAND IO lines */ |
143 | this->IO_ADDR_R = toto_io_base; | 144 | this->IO_ADDR_R = toto_io_base; |
144 | this->IO_ADDR_W = toto_io_base; | 145 | this->IO_ADDR_W = toto_io_base; |
145 | this->hwcontrol = toto_hwcontrol; | 146 | this->cmd_ctrl = toto_hwcontrol; |
146 | this->dev_ready = NULL; | 147 | this->dev_ready = NULL; |
147 | /* 25 us command delay time */ | 148 | /* 25 us command delay time */ |
148 | this->chip_delay = 30; | 149 | this->chip_delay = 30; |
diff --git a/drivers/mtd/nand/ts7250.c b/drivers/mtd/nand/ts7250.c index 70bce1b0326c..a0b4b1edcb0d 100644 --- a/drivers/mtd/nand/ts7250.c +++ b/drivers/mtd/nand/ts7250.c | |||
@@ -83,31 +83,29 @@ static struct mtd_partition partition_info128[] = { | |||
83 | 83 | ||
84 | /* | 84 | /* |
85 | * hardware specific access to control-lines | 85 | * hardware specific access to control-lines |
86 | * | ||
87 | * ctrl: | ||
88 | * NAND_NCE: bit 0 -> bit 2 | ||
89 | * NAND_CLE: bit 1 -> bit 1 | ||
90 | * NAND_ALE: bit 2 -> bit 0 | ||
86 | */ | 91 | */ |
87 | static void ts7250_hwcontrol(struct mtd_info *mtd, int cmd) | 92 | static void ts7250_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
88 | { | 93 | { |
89 | unsigned long ctrl = TS72XX_NAND_CONTROL_VIRT_BASE; | 94 | struct nand_chip *chip = mtd->priv; |
90 | 95 | ||
91 | switch (cmd) { | 96 | if (ctrl & NAND_CTRL_CHANGE) { |
92 | case NAND_CTL_SETCLE: | 97 | unsigned long addr = TS72XX_NAND_CONTROL_VIRT_BASE; |
93 | __raw_writeb(__raw_readb(ctrl) | 0x2, ctrl); | 98 | unsigned char bits; |
94 | break; | 99 | |
95 | case NAND_CTL_CLRCLE: | 100 | bits = (ctrl & NAND_CNE) << 2; |
96 | __raw_writeb(__raw_readb(ctrl) & ~0x2, ctrl); | 101 | bits |= ctrl & NAND_CLE; |
97 | break; | 102 | bits |= (ctrl & NAND_ALE) >> 2; |
98 | case NAND_CTL_SETALE: | 103 | |
99 | __raw_writeb(__raw_readb(ctrl) | 0x1, ctrl); | 104 | __raw_writeb((__raw_readb(addr) & ~0x7) | bits, addr); |
100 | break; | ||
101 | case NAND_CTL_CLRALE: | ||
102 | __raw_writeb(__raw_readb(ctrl) & ~0x1, ctrl); | ||
103 | break; | ||
104 | case NAND_CTL_SETNCE: | ||
105 | __raw_writeb(__raw_readb(ctrl) | 0x4, ctrl); | ||
106 | break; | ||
107 | case NAND_CTL_CLRNCE: | ||
108 | __raw_writeb(__raw_readb(ctrl) & ~0x4, ctrl); | ||
109 | break; | ||
110 | } | 105 | } |
106 | |||
107 | if (cmd != NAND_CMD_NONE) | ||
108 | writeb(cmd, chip->IO_ADDR_W); | ||
111 | } | 109 | } |
112 | 110 | ||
113 | /* | 111 | /* |
@@ -152,7 +150,7 @@ static int __init ts7250_init(void) | |||
152 | /* insert callbacks */ | 150 | /* insert callbacks */ |
153 | this->IO_ADDR_R = (void *)TS72XX_NAND_DATA_VIRT_BASE; | 151 | this->IO_ADDR_R = (void *)TS72XX_NAND_DATA_VIRT_BASE; |
154 | this->IO_ADDR_W = (void *)TS72XX_NAND_DATA_VIRT_BASE; | 152 | this->IO_ADDR_W = (void *)TS72XX_NAND_DATA_VIRT_BASE; |
155 | this->hwcontrol = ts7250_hwcontrol; | 153 | this->cmd_ctrl = ts7250_hwcontrol; |
156 | this->dev_ready = ts7250_device_ready; | 154 | this->dev_ready = ts7250_device_ready; |
157 | this->chip_delay = 15; | 155 | this->chip_delay = 15; |
158 | this->ecc.mode = NAND_ECC_SOFT; | 156 | this->ecc.mode = NAND_ECC_SOFT; |
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 8362b466df3a..e9a935263151 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h | |||
@@ -50,23 +50,20 @@ extern int nand_write_raw(struct mtd_info *mtd, loff_t to, size_t len, | |||
50 | 50 | ||
51 | /* | 51 | /* |
52 | * Constants for hardware specific CLE/ALE/NCE function | 52 | * Constants for hardware specific CLE/ALE/NCE function |
53 | */ | 53 | * |
54 | * These are bits which can be or'ed to set/clear multiple | ||
55 | * bits in one go. | ||
56 | */ | ||
54 | /* Select the chip by setting nCE to low */ | 57 | /* Select the chip by setting nCE to low */ |
55 | #define NAND_CTL_SETNCE 1 | 58 | #define NAND_NCE 0x01 |
56 | /* Deselect the chip by setting nCE to high */ | ||
57 | #define NAND_CTL_CLRNCE 2 | ||
58 | /* Select the command latch by setting CLE to high */ | 59 | /* Select the command latch by setting CLE to high */ |
59 | #define NAND_CTL_SETCLE 3 | 60 | #define NAND_CLE 0x02 |
60 | /* Deselect the command latch by setting CLE to low */ | ||
61 | #define NAND_CTL_CLRCLE 4 | ||
62 | /* Select the address latch by setting ALE to high */ | 61 | /* Select the address latch by setting ALE to high */ |
63 | #define NAND_CTL_SETALE 5 | 62 | #define NAND_ALE 0x04 |
64 | /* Deselect the address latch by setting ALE to low */ | 63 | |
65 | #define NAND_CTL_CLRALE 6 | 64 | #define NAND_CTRL_CLE (NAND_NCE | NAND_CLE) |
66 | /* Set write protection by setting WP to high. Not used! */ | 65 | #define NAND_CTRL_ALE (NAND_NCE | NAND_ALE) |
67 | #define NAND_CTL_SETWP 7 | 66 | #define NAND_CTRL_CHANGE 0x80 |
68 | /* Clear write protection by setting WP to low. Not used! */ | ||
69 | #define NAND_CTL_CLRWP 8 | ||
70 | 67 | ||
71 | /* | 68 | /* |
72 | * Standard NAND flash commands | 69 | * Standard NAND flash commands |
@@ -106,6 +103,8 @@ extern int nand_write_raw(struct mtd_info *mtd, loff_t to, size_t len, | |||
106 | #define NAND_CMD_STATUS_RESET 0x7f | 103 | #define NAND_CMD_STATUS_RESET 0x7f |
107 | #define NAND_CMD_STATUS_CLEAR 0xff | 104 | #define NAND_CMD_STATUS_CLEAR 0xff |
108 | 105 | ||
106 | #define NAND_CMD_NONE -1 | ||
107 | |||
109 | /* Status bits */ | 108 | /* Status bits */ |
110 | #define NAND_STATUS_FAIL 0x01 | 109 | #define NAND_STATUS_FAIL 0x01 |
111 | #define NAND_STATUS_FAIL_N1 0x02 | 110 | #define NAND_STATUS_FAIL_N1 0x02 |
@@ -263,7 +262,8 @@ struct nand_ecc_ctrl { | |||
263 | * @select_chip: [REPLACEABLE] select chip nr | 262 | * @select_chip: [REPLACEABLE] select chip nr |
264 | * @block_bad: [REPLACEABLE] check, if the block is bad | 263 | * @block_bad: [REPLACEABLE] check, if the block is bad |
265 | * @block_markbad: [REPLACEABLE] mark the block bad | 264 | * @block_markbad: [REPLACEABLE] mark the block bad |
266 | * @hwcontrol: [BOARDSPECIFIC] hardwarespecific function for accesing control-lines | 265 | * @cmd_ctrl: [BOARDSPECIFIC] hardwarespecific funtion for controlling |
266 | * ALE/CLE/nCE. Also used to write command and address | ||
267 | * @dev_ready: [BOARDSPECIFIC] hardwarespecific function for accesing device ready/busy line | 267 | * @dev_ready: [BOARDSPECIFIC] hardwarespecific function for accesing device ready/busy line |
268 | * If set to NULL no access to ready/busy is available and the ready/busy information | 268 | * If set to NULL no access to ready/busy is available and the ready/busy information |
269 | * is read from the chip status register | 269 | * is read from the chip status register |
@@ -317,7 +317,8 @@ struct nand_chip { | |||
317 | void (*select_chip)(struct mtd_info *mtd, int chip); | 317 | void (*select_chip)(struct mtd_info *mtd, int chip); |
318 | int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip); | 318 | int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip); |
319 | int (*block_markbad)(struct mtd_info *mtd, loff_t ofs); | 319 | int (*block_markbad)(struct mtd_info *mtd, loff_t ofs); |
320 | void (*hwcontrol)(struct mtd_info *mtd, int cmd); | 320 | void (*cmd_ctrl)(struct mtd_info *mtd, int dat, |
321 | unsigned int ctrl); | ||
321 | int (*dev_ready)(struct mtd_info *mtd); | 322 | int (*dev_ready)(struct mtd_info *mtd); |
322 | void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr); | 323 | void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr); |
323 | int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state); | 324 | int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state); |