aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand/ndfc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand/ndfc.c')
-rw-r--r--drivers/mtd/nand/ndfc.c65
1 files changed, 36 insertions, 29 deletions
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
index bbe6d451290d..ea2dea8a9c88 100644
--- a/drivers/mtd/nand/ndfc.c
+++ b/drivers/mtd/nand/ndfc.c
@@ -33,6 +33,7 @@
33#include <linux/of_platform.h> 33#include <linux/of_platform.h>
34#include <asm/io.h> 34#include <asm/io.h>
35 35
36#define NDFC_MAX_CS 4
36 37
37struct ndfc_controller { 38struct ndfc_controller {
38 struct platform_device *ofdev; 39 struct platform_device *ofdev;
@@ -41,17 +42,16 @@ struct ndfc_controller {
41 struct nand_chip chip; 42 struct nand_chip chip;
42 int chip_select; 43 int chip_select;
43 struct nand_hw_control ndfc_control; 44 struct nand_hw_control ndfc_control;
44#ifdef CONFIG_MTD_PARTITIONS
45 struct mtd_partition *parts; 45 struct mtd_partition *parts;
46#endif
47}; 46};
48 47
49static struct ndfc_controller ndfc_ctrl; 48static struct ndfc_controller ndfc_ctrl[NDFC_MAX_CS];
50 49
51static void ndfc_select_chip(struct mtd_info *mtd, int chip) 50static void ndfc_select_chip(struct mtd_info *mtd, int chip)
52{ 51{
53 uint32_t ccr; 52 uint32_t ccr;
54 struct ndfc_controller *ndfc = &ndfc_ctrl; 53 struct nand_chip *nchip = mtd->priv;
54 struct ndfc_controller *ndfc = nchip->priv;
55 55
56 ccr = in_be32(ndfc->ndfcbase + NDFC_CCR); 56 ccr = in_be32(ndfc->ndfcbase + NDFC_CCR);
57 if (chip >= 0) { 57 if (chip >= 0) {
@@ -64,7 +64,8 @@ static void ndfc_select_chip(struct mtd_info *mtd, int chip)
64 64
65static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) 65static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
66{ 66{
67 struct ndfc_controller *ndfc = &ndfc_ctrl; 67 struct nand_chip *chip = mtd->priv;
68 struct ndfc_controller *ndfc = chip->priv;
68 69
69 if (cmd == NAND_CMD_NONE) 70 if (cmd == NAND_CMD_NONE)
70 return; 71 return;
@@ -77,7 +78,8 @@ static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
77 78
78static int ndfc_ready(struct mtd_info *mtd) 79static int ndfc_ready(struct mtd_info *mtd)
79{ 80{
80 struct ndfc_controller *ndfc = &ndfc_ctrl; 81 struct nand_chip *chip = mtd->priv;
82 struct ndfc_controller *ndfc = chip->priv;
81 83
82 return in_be32(ndfc->ndfcbase + NDFC_STAT) & NDFC_STAT_IS_READY; 84 return in_be32(ndfc->ndfcbase + NDFC_STAT) & NDFC_STAT_IS_READY;
83} 85}
@@ -85,7 +87,8 @@ static int ndfc_ready(struct mtd_info *mtd)
85static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode) 87static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode)
86{ 88{
87 uint32_t ccr; 89 uint32_t ccr;
88 struct ndfc_controller *ndfc = &ndfc_ctrl; 90 struct nand_chip *chip = mtd->priv;
91 struct ndfc_controller *ndfc = chip->priv;
89 92
90 ccr = in_be32(ndfc->ndfcbase + NDFC_CCR); 93 ccr = in_be32(ndfc->ndfcbase + NDFC_CCR);
91 ccr |= NDFC_CCR_RESET_ECC; 94 ccr |= NDFC_CCR_RESET_ECC;
@@ -96,7 +99,8 @@ static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode)
96static int ndfc_calculate_ecc(struct mtd_info *mtd, 99static int ndfc_calculate_ecc(struct mtd_info *mtd,
97 const u_char *dat, u_char *ecc_code) 100 const u_char *dat, u_char *ecc_code)
98{ 101{
99 struct ndfc_controller *ndfc = &ndfc_ctrl; 102 struct nand_chip *chip = mtd->priv;
103 struct ndfc_controller *ndfc = chip->priv;
100 uint32_t ecc; 104 uint32_t ecc;
101 uint8_t *p = (uint8_t *)&ecc; 105 uint8_t *p = (uint8_t *)&ecc;
102 106
@@ -119,7 +123,8 @@ static int ndfc_calculate_ecc(struct mtd_info *mtd,
119 */ 123 */
120static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) 124static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
121{ 125{
122 struct ndfc_controller *ndfc = &ndfc_ctrl; 126 struct nand_chip *chip = mtd->priv;
127 struct ndfc_controller *ndfc = chip->priv;
123 uint32_t *p = (uint32_t *) buf; 128 uint32_t *p = (uint32_t *) buf;
124 129
125 for(;len > 0; len -= 4) 130 for(;len > 0; len -= 4)
@@ -128,7 +133,8 @@ static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
128 133
129static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) 134static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
130{ 135{
131 struct ndfc_controller *ndfc = &ndfc_ctrl; 136 struct nand_chip *chip = mtd->priv;
137 struct ndfc_controller *ndfc = chip->priv;
132 uint32_t *p = (uint32_t *) buf; 138 uint32_t *p = (uint32_t *) buf;
133 139
134 for(;len > 0; len -= 4) 140 for(;len > 0; len -= 4)
@@ -137,7 +143,8 @@ static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
137 143
138static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len) 144static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
139{ 145{
140 struct ndfc_controller *ndfc = &ndfc_ctrl; 146 struct nand_chip *chip = mtd->priv;
147 struct ndfc_controller *ndfc = chip->priv;
141 uint32_t *p = (uint32_t *) buf; 148 uint32_t *p = (uint32_t *) buf;
142 149
143 for(;len > 0; len -= 4) 150 for(;len > 0; len -= 4)
@@ -152,13 +159,11 @@ static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
152static int ndfc_chip_init(struct ndfc_controller *ndfc, 159static int ndfc_chip_init(struct ndfc_controller *ndfc,
153 struct device_node *node) 160 struct device_node *node)
154{ 161{
155#ifdef CONFIG_MTD_PARTITIONS
156#ifdef CONFIG_MTD_CMDLINE_PARTS 162#ifdef CONFIG_MTD_CMDLINE_PARTS
157 static const char *part_types[] = { "cmdlinepart", NULL }; 163 static const char *part_types[] = { "cmdlinepart", NULL };
158#else 164#else
159 static const char *part_types[] = { NULL }; 165 static const char *part_types[] = { NULL };
160#endif 166#endif
161#endif
162 struct device_node *flash_np; 167 struct device_node *flash_np;
163 struct nand_chip *chip = &ndfc->chip; 168 struct nand_chip *chip = &ndfc->chip;
164 int ret; 169 int ret;
@@ -179,6 +184,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc,
179 chip->ecc.mode = NAND_ECC_HW; 184 chip->ecc.mode = NAND_ECC_HW;
180 chip->ecc.size = 256; 185 chip->ecc.size = 256;
181 chip->ecc.bytes = 3; 186 chip->ecc.bytes = 3;
187 chip->priv = ndfc;
182 188
183 ndfc->mtd.priv = chip; 189 ndfc->mtd.priv = chip;
184 ndfc->mtd.owner = THIS_MODULE; 190 ndfc->mtd.owner = THIS_MODULE;
@@ -198,25 +204,18 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc,
198 if (ret) 204 if (ret)
199 goto err; 205 goto err;
200 206
201#ifdef CONFIG_MTD_PARTITIONS
202 ret = parse_mtd_partitions(&ndfc->mtd, part_types, &ndfc->parts, 0); 207 ret = parse_mtd_partitions(&ndfc->mtd, part_types, &ndfc->parts, 0);
203 if (ret < 0) 208 if (ret < 0)
204 goto err; 209 goto err;
205 210
206#ifdef CONFIG_MTD_OF_PARTS
207 if (ret == 0) { 211 if (ret == 0) {
208 ret = of_mtd_parse_partitions(&ndfc->ofdev->dev, flash_np, 212 ret = of_mtd_parse_partitions(&ndfc->ofdev->dev, flash_np,
209 &ndfc->parts); 213 &ndfc->parts);
210 if (ret < 0) 214 if (ret < 0)
211 goto err; 215 goto err;
212 } 216 }
213#endif
214 217
215 if (ret > 0) 218 ret = mtd_device_register(&ndfc->mtd, ndfc->parts, ret);
216 ret = add_mtd_partitions(&ndfc->mtd, ndfc->parts, ret);
217 else
218#endif
219 ret = add_mtd_device(&ndfc->mtd);
220 219
221err: 220err:
222 of_node_put(flash_np); 221 of_node_put(flash_np);
@@ -227,15 +226,10 @@ err:
227 226
228static int __devinit ndfc_probe(struct platform_device *ofdev) 227static int __devinit ndfc_probe(struct platform_device *ofdev)
229{ 228{
230 struct ndfc_controller *ndfc = &ndfc_ctrl; 229 struct ndfc_controller *ndfc;
231 const __be32 *reg; 230 const __be32 *reg;
232 u32 ccr; 231 u32 ccr;
233 int err, len; 232 int err, len, cs;
234
235 spin_lock_init(&ndfc->ndfc_control.lock);
236 init_waitqueue_head(&ndfc->ndfc_control.wq);
237 ndfc->ofdev = ofdev;
238 dev_set_drvdata(&ofdev->dev, ndfc);
239 233
240 /* Read the reg property to get the chip select */ 234 /* Read the reg property to get the chip select */
241 reg = of_get_property(ofdev->dev.of_node, "reg", &len); 235 reg = of_get_property(ofdev->dev.of_node, "reg", &len);
@@ -243,7 +237,20 @@ static int __devinit ndfc_probe(struct platform_device *ofdev)
243 dev_err(&ofdev->dev, "unable read reg property (%d)\n", len); 237 dev_err(&ofdev->dev, "unable read reg property (%d)\n", len);
244 return -ENOENT; 238 return -ENOENT;
245 } 239 }
246 ndfc->chip_select = be32_to_cpu(reg[0]); 240
241 cs = be32_to_cpu(reg[0]);
242 if (cs >= NDFC_MAX_CS) {
243 dev_err(&ofdev->dev, "invalid CS number (%d)\n", cs);
244 return -EINVAL;
245 }
246
247 ndfc = &ndfc_ctrl[cs];
248 ndfc->chip_select = cs;
249
250 spin_lock_init(&ndfc->ndfc_control.lock);
251 init_waitqueue_head(&ndfc->ndfc_control.wq);
252 ndfc->ofdev = ofdev;
253 dev_set_drvdata(&ofdev->dev, ndfc);
247 254
248 ndfc->ndfcbase = of_iomap(ofdev->dev.of_node, 0); 255 ndfc->ndfcbase = of_iomap(ofdev->dev.of_node, 0);
249 if (!ndfc->ndfcbase) { 256 if (!ndfc->ndfcbase) {