diff options
author | Wolfgang Grandegger <wg@grandegger.com> | 2008-06-09 04:19:08 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2008-10-10 02:29:00 -0400 |
commit | 13f5369704d3c27a07936999f063be3a8a905398 (patch) | |
tree | 3476e63f12d214b157756946aac0ff4516a98160 | |
parent | 95ebffd749c8e6c8cbb746bc0833a5738cc23321 (diff) |
[MTD] [NAND] driver extension to support NAND on TQM85xx modules
This patch extends the FSL UPM NAND driver from Anton Vorontsov to
support hardware which does not have the R/B pin of the NAND chip
connected, like the TQM8548 module:
- The OF_GPIO dependency has been removed from the Kconfig option
because GPIO is not needed. The relevant gpio_* function are then
stubbed out in <linux/gpio.h>.
- It re-introduces the chip-delay property to define an appropriate
maximum delay time (tR) required for read operations. The binding
will be documented in a separate patch.
Signed-off-by: Wolfgang Grandegger <wg@grandegger.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
-rw-r--r-- | drivers/mtd/nand/Kconfig | 2 | ||||
-rw-r--r-- | drivers/mtd/nand/fsl_upm.c | 17 |
2 files changed, 14 insertions, 5 deletions
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 7153854eb83a..18b9ffeabc98 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
@@ -401,7 +401,7 @@ config MTD_NAND_FSL_ELBC | |||
401 | 401 | ||
402 | config MTD_NAND_FSL_UPM | 402 | config MTD_NAND_FSL_UPM |
403 | tristate "Support for NAND on Freescale UPM" | 403 | tristate "Support for NAND on Freescale UPM" |
404 | depends on MTD_NAND && OF_GPIO && (PPC_83xx || PPC_85xx) | 404 | depends on MTD_NAND && (PPC_83xx || PPC_85xx) |
405 | select FSL_LBC | 405 | select FSL_LBC |
406 | help | 406 | help |
407 | Enables support for NAND Flash chips wired onto Freescale PowerPC | 407 | Enables support for NAND Flash chips wired onto Freescale PowerPC |
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index 3af5ef399a0f..024e3fffd4bb 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/delay.h> | ||
16 | #include <linux/mtd/nand.h> | 17 | #include <linux/mtd/nand.h> |
17 | #include <linux/mtd/nand_ecc.h> | 18 | #include <linux/mtd/nand_ecc.h> |
18 | #include <linux/mtd/partitions.h> | 19 | #include <linux/mtd/partitions.h> |
@@ -36,6 +37,7 @@ struct fsl_upm_nand { | |||
36 | uint8_t upm_cmd_offset; | 37 | uint8_t upm_cmd_offset; |
37 | void __iomem *io_base; | 38 | void __iomem *io_base; |
38 | int rnb_gpio; | 39 | int rnb_gpio; |
40 | int chip_delay; | ||
39 | }; | 41 | }; |
40 | 42 | ||
41 | #define to_fsl_upm_nand(mtd) container_of(mtd, struct fsl_upm_nand, mtd) | 43 | #define to_fsl_upm_nand(mtd) container_of(mtd, struct fsl_upm_nand, mtd) |
@@ -58,10 +60,11 @@ static void fun_wait_rnb(struct fsl_upm_nand *fun) | |||
58 | if (fun->rnb_gpio >= 0) { | 60 | if (fun->rnb_gpio >= 0) { |
59 | while (--cnt && !fun_chip_ready(&fun->mtd)) | 61 | while (--cnt && !fun_chip_ready(&fun->mtd)) |
60 | cpu_relax(); | 62 | cpu_relax(); |
63 | if (!cnt) | ||
64 | dev_err(fun->dev, "tired waiting for RNB\n"); | ||
65 | } else { | ||
66 | ndelay(100); | ||
61 | } | 67 | } |
62 | |||
63 | if (!cnt) | ||
64 | dev_err(fun->dev, "tired waiting for RNB\n"); | ||
65 | } | 68 | } |
66 | 69 | ||
67 | static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 70 | static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
@@ -129,7 +132,7 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun, | |||
129 | fun->chip.IO_ADDR_R = fun->io_base; | 132 | fun->chip.IO_ADDR_R = fun->io_base; |
130 | fun->chip.IO_ADDR_W = fun->io_base; | 133 | fun->chip.IO_ADDR_W = fun->io_base; |
131 | fun->chip.cmd_ctrl = fun_cmd_ctrl; | 134 | fun->chip.cmd_ctrl = fun_cmd_ctrl; |
132 | fun->chip.chip_delay = 50; | 135 | fun->chip.chip_delay = fun->chip_delay; |
133 | fun->chip.read_byte = fun_read_byte; | 136 | fun->chip.read_byte = fun_read_byte; |
134 | fun->chip.read_buf = fun_read_buf; | 137 | fun->chip.read_buf = fun_read_buf; |
135 | fun->chip.write_buf = fun_write_buf; | 138 | fun->chip.write_buf = fun_write_buf; |
@@ -228,6 +231,12 @@ static int __devinit fun_probe(struct of_device *ofdev, | |||
228 | goto err2; | 231 | goto err2; |
229 | } | 232 | } |
230 | 233 | ||
234 | prop = of_get_property(ofdev->node, "chip-delay", NULL); | ||
235 | if (prop) | ||
236 | fun->chip_delay = *prop; | ||
237 | else | ||
238 | fun->chip_delay = 50; | ||
239 | |||
231 | fun->io_base = devm_ioremap_nocache(&ofdev->dev, io_res.start, | 240 | fun->io_base = devm_ioremap_nocache(&ofdev->dev, io_res.start, |
232 | io_res.end - io_res.start + 1); | 241 | io_res.end - io_res.start + 1); |
233 | if (!fun->io_base) { | 242 | if (!fun->io_base) { |