diff options
author | David Brownell <david-b@pacbell.net> | 2008-07-04 02:40:16 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2008-07-11 09:51:21 -0400 |
commit | 23a346ca4a5a6f50f81062456af955155f68e313 (patch) | |
tree | d2e37dfb9bdc350aab668ee0cac9168a43cc78ea /drivers/mtd/nand/atmel_nand.c | |
parent | 175428b2b3eeacf90dcc171d5915d6b4dc86e917 (diff) |
[MTD] [NAND] atmel_nand speedup via {read,write}s{b,w}()
This uses __raw_{read,write}s{b,w}() primitives to access data on NAND
chips for more efficient I/O.
On an arm926 with memory clocked at 100 MHz, this reduced the elapsed time
for a 64 MiB read by 16%. ("dd" /dev/mtd0 to /dev/null, with an 8-bit
NAND using hardware ECC and 128KiB blocksize.)
Also some minor section tweaks:
- Use platform_driver_probe() so no pointer to probe() lingers
after that code has been removed at run-time.
- Use __exit and __exit_p so the remove() code will normally be
removed by the linker.
Since these buffer read/write calls are new, this increases the runtime
code footprint (by 88 bytes on my build, after the section tweaks).
[haavard.skinnemoen@atmel.com: rebase onto atmel_nand rename]
Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: HÃ¥vard Skinnemoen <haavard.skinnemoen@atmel.com>
Acked-by: Andrew Victor <linux@maxim.org.za>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd/nand/atmel_nand.c')
-rw-r--r-- | drivers/mtd/nand/atmel_nand.c | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 50700ab5a57a..4814fc9b237b 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c | |||
@@ -142,6 +142,37 @@ static int atmel_nand_device_ready(struct mtd_info *mtd) | |||
142 | } | 142 | } |
143 | 143 | ||
144 | /* | 144 | /* |
145 | * Minimal-overhead PIO for data access. | ||
146 | */ | ||
147 | static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len) | ||
148 | { | ||
149 | struct nand_chip *nand_chip = mtd->priv; | ||
150 | |||
151 | __raw_readsb(nand_chip->IO_ADDR_R, buf, len); | ||
152 | } | ||
153 | |||
154 | static void atmel_read_buf16(struct mtd_info *mtd, u8 *buf, int len) | ||
155 | { | ||
156 | struct nand_chip *nand_chip = mtd->priv; | ||
157 | |||
158 | __raw_readsw(nand_chip->IO_ADDR_R, buf, len / 2); | ||
159 | } | ||
160 | |||
161 | static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len) | ||
162 | { | ||
163 | struct nand_chip *nand_chip = mtd->priv; | ||
164 | |||
165 | __raw_writesb(nand_chip->IO_ADDR_W, buf, len); | ||
166 | } | ||
167 | |||
168 | static void atmel_write_buf16(struct mtd_info *mtd, const u8 *buf, int len) | ||
169 | { | ||
170 | struct nand_chip *nand_chip = mtd->priv; | ||
171 | |||
172 | __raw_writesw(nand_chip->IO_ADDR_W, buf, len / 2); | ||
173 | } | ||
174 | |||
175 | /* | ||
145 | * write oob for small pages | 176 | * write oob for small pages |
146 | */ | 177 | */ |
147 | static int atmel_nand_write_oob_512(struct mtd_info *mtd, | 178 | static int atmel_nand_write_oob_512(struct mtd_info *mtd, |
@@ -436,8 +467,14 @@ static int __init atmel_nand_probe(struct platform_device *pdev) | |||
436 | 467 | ||
437 | nand_chip->chip_delay = 20; /* 20us command delay time */ | 468 | nand_chip->chip_delay = 20; /* 20us command delay time */ |
438 | 469 | ||
439 | if (host->board->bus_width_16) /* 16-bit bus width */ | 470 | if (host->board->bus_width_16) { /* 16-bit bus width */ |
440 | nand_chip->options |= NAND_BUSWIDTH_16; | 471 | nand_chip->options |= NAND_BUSWIDTH_16; |
472 | nand_chip->read_buf = atmel_read_buf16; | ||
473 | nand_chip->write_buf = atmel_write_buf16; | ||
474 | } else { | ||
475 | nand_chip->read_buf = atmel_read_buf; | ||
476 | nand_chip->write_buf = atmel_write_buf; | ||
477 | } | ||
441 | 478 | ||
442 | platform_set_drvdata(pdev, host); | 479 | platform_set_drvdata(pdev, host); |
443 | atmel_nand_enable(host); | 480 | atmel_nand_enable(host); |
@@ -546,7 +583,7 @@ err_nand_ioremap: | |||
546 | /* | 583 | /* |
547 | * Remove a NAND device. | 584 | * Remove a NAND device. |
548 | */ | 585 | */ |
549 | static int __devexit atmel_nand_remove(struct platform_device *pdev) | 586 | static int __exit atmel_nand_remove(struct platform_device *pdev) |
550 | { | 587 | { |
551 | struct atmel_nand_host *host = platform_get_drvdata(pdev); | 588 | struct atmel_nand_host *host = platform_get_drvdata(pdev); |
552 | struct mtd_info *mtd = &host->mtd; | 589 | struct mtd_info *mtd = &host->mtd; |
@@ -564,8 +601,7 @@ static int __devexit atmel_nand_remove(struct platform_device *pdev) | |||
564 | } | 601 | } |
565 | 602 | ||
566 | static struct platform_driver atmel_nand_driver = { | 603 | static struct platform_driver atmel_nand_driver = { |
567 | .probe = atmel_nand_probe, | 604 | .remove = __exit_p(atmel_nand_remove), |
568 | .remove = atmel_nand_remove, | ||
569 | .driver = { | 605 | .driver = { |
570 | .name = "atmel_nand", | 606 | .name = "atmel_nand", |
571 | .owner = THIS_MODULE, | 607 | .owner = THIS_MODULE, |
@@ -574,7 +610,7 @@ static struct platform_driver atmel_nand_driver = { | |||
574 | 610 | ||
575 | static int __init atmel_nand_init(void) | 611 | static int __init atmel_nand_init(void) |
576 | { | 612 | { |
577 | return platform_driver_register(&atmel_nand_driver); | 613 | return platform_driver_probe(&atmel_nand_driver, atmel_nand_probe); |
578 | } | 614 | } |
579 | 615 | ||
580 | 616 | ||