diff options
author | Wolfgang Grandegger <wg@grandegger.com> | 2009-03-30 06:02:43 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2009-04-06 10:17:59 -0400 |
commit | ade92a636f15d7e5b92e2df22e8fcb6c7640cd4f (patch) | |
tree | a1b481b9145a5e95f190ded835ef11c5e7ae2556 | |
parent | b6e0e8c07754c8aefd6ff3536463fed5f71405a0 (diff) |
[MTD] [NAND] FSL-UPM: Add wait flags to support board/chip specific delays
The NAND flash on the TQM8548_BE modules requires a short delay after
running the UPM pattern. The TQM8548_BE requires a further short delay
after writing out a buffer. Normally the R/B pin should be checked, but
it's not connected on the TQM8548_BE. The existing driver uses similar
fixed delay points. To manage these extra delays in a more general way,
I introduced the "fsl,ump-wait-flags" property allowing the board-
specific driver to specify various types of extra delay.
Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
Acked-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
-rw-r--r-- | drivers/mtd/nand/fsl_upm.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index 430de6de9ac6..d120cd8d7267 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c | |||
@@ -23,6 +23,10 @@ | |||
23 | #include <linux/io.h> | 23 | #include <linux/io.h> |
24 | #include <asm/fsl_lbc.h> | 24 | #include <asm/fsl_lbc.h> |
25 | 25 | ||
26 | #define FSL_UPM_WAIT_RUN_PATTERN 0x1 | ||
27 | #define FSL_UPM_WAIT_WRITE_BYTE 0x2 | ||
28 | #define FSL_UPM_WAIT_WRITE_BUFFER 0x4 | ||
29 | |||
26 | struct fsl_upm_nand { | 30 | struct fsl_upm_nand { |
27 | struct device *dev; | 31 | struct device *dev; |
28 | struct mtd_info mtd; | 32 | struct mtd_info mtd; |
@@ -41,6 +45,7 @@ struct fsl_upm_nand { | |||
41 | uint32_t mchip_count; | 45 | uint32_t mchip_count; |
42 | uint32_t mchip_number; | 46 | uint32_t mchip_number; |
43 | int chip_delay; | 47 | int chip_delay; |
48 | uint32_t wait_flags; | ||
44 | }; | 49 | }; |
45 | 50 | ||
46 | #define to_fsl_upm_nand(mtd) container_of(mtd, struct fsl_upm_nand, mtd) | 51 | #define to_fsl_upm_nand(mtd) container_of(mtd, struct fsl_upm_nand, mtd) |
@@ -96,7 +101,8 @@ static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | |||
96 | fun->mchip_offsets[fun->mchip_number]; | 101 | fun->mchip_offsets[fun->mchip_number]; |
97 | fsl_upm_run_pattern(&fun->upm, chip->IO_ADDR_R, mar); | 102 | fsl_upm_run_pattern(&fun->upm, chip->IO_ADDR_R, mar); |
98 | 103 | ||
99 | fun_wait_rnb(fun); | 104 | if (fun->wait_flags & FSL_UPM_WAIT_RUN_PATTERN) |
105 | fun_wait_rnb(fun); | ||
100 | } | 106 | } |
101 | 107 | ||
102 | static void fun_select_chip(struct mtd_info *mtd, int mchip_nr) | 108 | static void fun_select_chip(struct mtd_info *mtd, int mchip_nr) |
@@ -138,8 +144,11 @@ static void fun_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | |||
138 | 144 | ||
139 | for (i = 0; i < len; i++) { | 145 | for (i = 0; i < len; i++) { |
140 | out_8(fun->chip.IO_ADDR_W, buf[i]); | 146 | out_8(fun->chip.IO_ADDR_W, buf[i]); |
141 | fun_wait_rnb(fun); | 147 | if (fun->wait_flags & FSL_UPM_WAIT_WRITE_BYTE) |
148 | fun_wait_rnb(fun); | ||
142 | } | 149 | } |
150 | if (fun->wait_flags & FSL_UPM_WAIT_WRITE_BUFFER) | ||
151 | fun_wait_rnb(fun); | ||
143 | } | 152 | } |
144 | 153 | ||
145 | static int __devinit fun_chip_init(struct fsl_upm_nand *fun, | 154 | static int __devinit fun_chip_init(struct fsl_upm_nand *fun, |
@@ -285,6 +294,13 @@ static int __devinit fun_probe(struct of_device *ofdev, | |||
285 | else | 294 | else |
286 | fun->chip_delay = 50; | 295 | fun->chip_delay = 50; |
287 | 296 | ||
297 | prop = of_get_property(ofdev->node, "fsl,upm-wait-flags", &size); | ||
298 | if (prop && size == sizeof(uint32_t)) | ||
299 | fun->wait_flags = *prop; | ||
300 | else | ||
301 | fun->wait_flags = FSL_UPM_WAIT_RUN_PATTERN | | ||
302 | FSL_UPM_WAIT_WRITE_BYTE; | ||
303 | |||
288 | fun->io_base = devm_ioremap_nocache(&ofdev->dev, io_res.start, | 304 | fun->io_base = devm_ioremap_nocache(&ofdev->dev, io_res.start, |
289 | io_res.end - io_res.start + 1); | 305 | io_res.end - io_res.start + 1); |
290 | if (!fun->io_base) { | 306 | if (!fun->io_base) { |