diff options
author | Anton Vorontsov <avorontsov@ru.mvista.com> | 2008-09-18 12:50:26 -0400 |
---|---|---|
committer | David Woodhouse <David.Woodhouse@intel.com> | 2008-10-10 02:24:05 -0400 |
commit | 95ebffd749c8e6c8cbb746bc0833a5738cc23321 (patch) | |
tree | e05f6b9f4272c047896a4c0e4e9a145695cb6e04 /drivers/mtd | |
parent | 63fd7f30f328f99956d3c774d17219c3c8d54131 (diff) |
[MTD] [NAND] fsl_upm: update driver for the new OF bindings
- Get rid of fsl,wait-pattern and fsl,wait-write. I think this isn't
chip-specific, and we should always do waits. I saw one board that
didn't need fsl,wait-pattern, but I assume this was the exception
that proves the rule;
- Get rid of chip-delay. Today there are no users for this, and if
anyone really need this they should push the OF bindings beforehand;
- Now flash chips should be child nodes of the FSL UPM NAND controller;
- Implement OF partition parsing.
Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/nand/fsl_upm.c | 57 |
1 files changed, 33 insertions, 24 deletions
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index 1ebfd87f00b4..3af5ef399a0f 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c | |||
@@ -36,9 +36,6 @@ struct fsl_upm_nand { | |||
36 | uint8_t upm_cmd_offset; | 36 | uint8_t upm_cmd_offset; |
37 | void __iomem *io_base; | 37 | void __iomem *io_base; |
38 | int rnb_gpio; | 38 | int rnb_gpio; |
39 | const uint32_t *wait_pattern; | ||
40 | const uint32_t *wait_write; | ||
41 | int chip_delay; | ||
42 | }; | 39 | }; |
43 | 40 | ||
44 | #define to_fsl_upm_nand(mtd) container_of(mtd, struct fsl_upm_nand, mtd) | 41 | #define to_fsl_upm_nand(mtd) container_of(mtd, struct fsl_upm_nand, mtd) |
@@ -89,8 +86,7 @@ static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | |||
89 | 86 | ||
90 | fsl_upm_run_pattern(&fun->upm, fun->io_base, cmd); | 87 | fsl_upm_run_pattern(&fun->upm, fun->io_base, cmd); |
91 | 88 | ||
92 | if (fun->wait_pattern) | 89 | fun_wait_rnb(fun); |
93 | fun_wait_rnb(fun); | ||
94 | } | 90 | } |
95 | 91 | ||
96 | static uint8_t fun_read_byte(struct mtd_info *mtd) | 92 | static uint8_t fun_read_byte(struct mtd_info *mtd) |
@@ -116,14 +112,16 @@ static void fun_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | |||
116 | 112 | ||
117 | for (i = 0; i < len; i++) { | 113 | for (i = 0; i < len; i++) { |
118 | out_8(fun->chip.IO_ADDR_W, buf[i]); | 114 | out_8(fun->chip.IO_ADDR_W, buf[i]); |
119 | if (fun->wait_write) | 115 | fun_wait_rnb(fun); |
120 | fun_wait_rnb(fun); | ||
121 | } | 116 | } |
122 | } | 117 | } |
123 | 118 | ||
124 | static int __devinit fun_chip_init(struct fsl_upm_nand *fun) | 119 | static int __devinit fun_chip_init(struct fsl_upm_nand *fun, |
120 | const struct device_node *upm_np, | ||
121 | const struct resource *io_res) | ||
125 | { | 122 | { |
126 | int ret; | 123 | int ret; |
124 | struct device_node *flash_np; | ||
127 | #ifdef CONFIG_MTD_PARTITIONS | 125 | #ifdef CONFIG_MTD_PARTITIONS |
128 | static const char *part_types[] = { "cmdlinepart", NULL, }; | 126 | static const char *part_types[] = { "cmdlinepart", NULL, }; |
129 | #endif | 127 | #endif |
@@ -131,7 +129,7 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun) | |||
131 | fun->chip.IO_ADDR_R = fun->io_base; | 129 | fun->chip.IO_ADDR_R = fun->io_base; |
132 | fun->chip.IO_ADDR_W = fun->io_base; | 130 | fun->chip.IO_ADDR_W = fun->io_base; |
133 | fun->chip.cmd_ctrl = fun_cmd_ctrl; | 131 | fun->chip.cmd_ctrl = fun_cmd_ctrl; |
134 | fun->chip.chip_delay = fun->chip_delay; | 132 | fun->chip.chip_delay = 50; |
135 | fun->chip.read_byte = fun_read_byte; | 133 | fun->chip.read_byte = fun_read_byte; |
136 | fun->chip.read_buf = fun_read_buf; | 134 | fun->chip.read_buf = fun_read_buf; |
137 | fun->chip.write_buf = fun_write_buf; | 135 | fun->chip.write_buf = fun_write_buf; |
@@ -143,18 +141,37 @@ static int __devinit fun_chip_init(struct fsl_upm_nand *fun) | |||
143 | fun->mtd.priv = &fun->chip; | 141 | fun->mtd.priv = &fun->chip; |
144 | fun->mtd.owner = THIS_MODULE; | 142 | fun->mtd.owner = THIS_MODULE; |
145 | 143 | ||
144 | flash_np = of_get_next_child(upm_np, NULL); | ||
145 | if (!flash_np) | ||
146 | return -ENODEV; | ||
147 | |||
148 | fun->mtd.name = kasprintf(GFP_KERNEL, "%x.%s", io_res->start, | ||
149 | flash_np->name); | ||
150 | if (!fun->mtd.name) { | ||
151 | ret = -ENOMEM; | ||
152 | goto err; | ||
153 | } | ||
154 | |||
146 | ret = nand_scan(&fun->mtd, 1); | 155 | ret = nand_scan(&fun->mtd, 1); |
147 | if (ret) | 156 | if (ret) |
148 | return ret; | 157 | goto err; |
149 | |||
150 | fun->mtd.name = fun->dev->bus_id; | ||
151 | 158 | ||
152 | #ifdef CONFIG_MTD_PARTITIONS | 159 | #ifdef CONFIG_MTD_PARTITIONS |
153 | ret = parse_mtd_partitions(&fun->mtd, part_types, &fun->parts, 0); | 160 | ret = parse_mtd_partitions(&fun->mtd, part_types, &fun->parts, 0); |
161 | |||
162 | #ifdef CONFIG_MTD_OF_PARTS | ||
163 | if (ret == 0) | ||
164 | ret = of_mtd_parse_partitions(fun->dev, &fun->mtd, | ||
165 | flash_np, &fun->parts); | ||
166 | #endif | ||
154 | if (ret > 0) | 167 | if (ret > 0) |
155 | return add_mtd_partitions(&fun->mtd, fun->parts, ret); | 168 | ret = add_mtd_partitions(&fun->mtd, fun->parts, ret); |
169 | else | ||
156 | #endif | 170 | #endif |
157 | return add_mtd_device(&fun->mtd); | 171 | ret = add_mtd_device(&fun->mtd); |
172 | err: | ||
173 | of_node_put(flash_np); | ||
174 | return ret; | ||
158 | } | 175 | } |
159 | 176 | ||
160 | static int __devinit fun_probe(struct of_device *ofdev, | 177 | static int __devinit fun_probe(struct of_device *ofdev, |
@@ -220,17 +237,8 @@ static int __devinit fun_probe(struct of_device *ofdev, | |||
220 | 237 | ||
221 | fun->dev = &ofdev->dev; | 238 | fun->dev = &ofdev->dev; |
222 | fun->last_ctrl = NAND_CLE; | 239 | fun->last_ctrl = NAND_CLE; |
223 | fun->wait_pattern = of_get_property(ofdev->node, "fsl,wait-pattern", | ||
224 | NULL); | ||
225 | fun->wait_write = of_get_property(ofdev->node, "fsl,wait-write", NULL); | ||
226 | |||
227 | prop = of_get_property(ofdev->node, "chip-delay", NULL); | ||
228 | if (prop) | ||
229 | fun->chip_delay = *prop; | ||
230 | else | ||
231 | fun->chip_delay = 50; | ||
232 | 240 | ||
233 | ret = fun_chip_init(fun); | 241 | ret = fun_chip_init(fun, ofdev->node, &io_res); |
234 | if (ret) | 242 | if (ret) |
235 | goto err2; | 243 | goto err2; |
236 | 244 | ||
@@ -251,6 +259,7 @@ static int __devexit fun_remove(struct of_device *ofdev) | |||
251 | struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev); | 259 | struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev); |
252 | 260 | ||
253 | nand_release(&fun->mtd); | 261 | nand_release(&fun->mtd); |
262 | kfree(fun->mtd.name); | ||
254 | 263 | ||
255 | if (fun->rnb_gpio >= 0) | 264 | if (fun->rnb_gpio >= 0) |
256 | gpio_free(fun->rnb_gpio); | 265 | gpio_free(fun->rnb_gpio); |