diff options
-rw-r--r-- | drivers/mtd/nand/fsmc_nand.c | 55 | ||||
-rw-r--r-- | include/linux/mtd/fsmc.h | 6 |
2 files changed, 61 insertions, 0 deletions
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index c41f45faa09e..81fc8e6b8cb8 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c | |||
@@ -524,6 +524,52 @@ static int count_written_bits(uint8_t *buff, int size, int max_bits) | |||
524 | } | 524 | } |
525 | 525 | ||
526 | /* | 526 | /* |
527 | * fsmc_write_buf - write buffer to chip | ||
528 | * @mtd: MTD device structure | ||
529 | * @buf: data buffer | ||
530 | * @len: number of bytes to write | ||
531 | */ | ||
532 | static void fsmc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | ||
533 | { | ||
534 | int i; | ||
535 | struct nand_chip *chip = mtd->priv; | ||
536 | |||
537 | if (IS_ALIGNED((uint32_t)buf, sizeof(uint32_t)) && | ||
538 | IS_ALIGNED(len, sizeof(uint32_t))) { | ||
539 | uint32_t *p = (uint32_t *)buf; | ||
540 | len = len >> 2; | ||
541 | for (i = 0; i < len; i++) | ||
542 | writel(p[i], chip->IO_ADDR_W); | ||
543 | } else { | ||
544 | for (i = 0; i < len; i++) | ||
545 | writeb(buf[i], chip->IO_ADDR_W); | ||
546 | } | ||
547 | } | ||
548 | |||
549 | /* | ||
550 | * fsmc_read_buf - read chip data into buffer | ||
551 | * @mtd: MTD device structure | ||
552 | * @buf: buffer to store date | ||
553 | * @len: number of bytes to read | ||
554 | */ | ||
555 | static void fsmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | ||
556 | { | ||
557 | int i; | ||
558 | struct nand_chip *chip = mtd->priv; | ||
559 | |||
560 | if (IS_ALIGNED((uint32_t)buf, sizeof(uint32_t)) && | ||
561 | IS_ALIGNED(len, sizeof(uint32_t))) { | ||
562 | uint32_t *p = (uint32_t *)buf; | ||
563 | len = len >> 2; | ||
564 | for (i = 0; i < len; i++) | ||
565 | p[i] = readl(chip->IO_ADDR_R); | ||
566 | } else { | ||
567 | for (i = 0; i < len; i++) | ||
568 | buf[i] = readb(chip->IO_ADDR_R); | ||
569 | } | ||
570 | } | ||
571 | |||
572 | /* | ||
527 | * fsmc_read_page_hwecc | 573 | * fsmc_read_page_hwecc |
528 | * @mtd: mtd info structure | 574 | * @mtd: mtd info structure |
529 | * @chip: nand chip info structure | 575 | * @chip: nand chip info structure |
@@ -825,6 +871,15 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
825 | if (pdata->width == FSMC_NAND_BW16) | 871 | if (pdata->width == FSMC_NAND_BW16) |
826 | nand->options |= NAND_BUSWIDTH_16; | 872 | nand->options |= NAND_BUSWIDTH_16; |
827 | 873 | ||
874 | /* | ||
875 | * use customized (word by word) version of read_buf, write_buf if | ||
876 | * access_with_dev_width is reset supported | ||
877 | */ | ||
878 | if (pdata->mode == USE_WORD_ACCESS) { | ||
879 | nand->read_buf = fsmc_read_buf; | ||
880 | nand->write_buf = fsmc_write_buf; | ||
881 | } | ||
882 | |||
828 | fsmc_nand_setup(regs, host->bank, nand->options & NAND_BUSWIDTH_16, | 883 | fsmc_nand_setup(regs, host->bank, nand->options & NAND_BUSWIDTH_16, |
829 | host->dev_timings); | 884 | host->dev_timings); |
830 | 885 | ||
diff --git a/include/linux/mtd/fsmc.h b/include/linux/mtd/fsmc.h index c4ac07a19691..1edd2b3ac38e 100644 --- a/include/linux/mtd/fsmc.h +++ b/include/linux/mtd/fsmc.h | |||
@@ -141,6 +141,11 @@ struct fsmc_nand_timings { | |||
141 | uint8_t tset; | 141 | uint8_t tset; |
142 | }; | 142 | }; |
143 | 143 | ||
144 | enum access_mode { | ||
145 | USE_DMA_ACCESS = 1, | ||
146 | USE_WORD_ACCESS, | ||
147 | }; | ||
148 | |||
144 | /** | 149 | /** |
145 | * fsmc_nand_platform_data - platform specific NAND controller config | 150 | * fsmc_nand_platform_data - platform specific NAND controller config |
146 | * @partitions: partition table for the platform, use a default fallback | 151 | * @partitions: partition table for the platform, use a default fallback |
@@ -164,6 +169,7 @@ struct fsmc_nand_platform_data { | |||
164 | /* CLE, ALE offsets */ | 169 | /* CLE, ALE offsets */ |
165 | unsigned long cle_off; | 170 | unsigned long cle_off; |
166 | unsigned long ale_off; | 171 | unsigned long ale_off; |
172 | enum access_mode mode; | ||
167 | 173 | ||
168 | void (*select_bank)(uint32_t bank, uint32_t busw); | 174 | void (*select_bank)(uint32_t bank, uint32_t busw); |
169 | }; | 175 | }; |