diff options
| -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); |
