aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/nand/ndfc.c52
1 files changed, 35 insertions, 17 deletions
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c
index bbe6d451290d..7ba65553d6ad 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;
@@ -46,12 +47,13 @@ struct ndfc_controller {
46#endif 47#endif
47}; 48};
48 49
49static struct ndfc_controller ndfc_ctrl; 50static struct ndfc_controller ndfc_ctrl[NDFC_MAX_CS];
50 51
51static void ndfc_select_chip(struct mtd_info *mtd, int chip) 52static void ndfc_select_chip(struct mtd_info *mtd, int chip)
52{ 53{
53 uint32_t ccr; 54 uint32_t ccr;
54 struct ndfc_controller *ndfc = &ndfc_ctrl; 55 struct nand_chip *nchip = mtd->priv;
56 struct ndfc_controller *ndfc = nchip->priv;
55 57
56 ccr = in_be32(ndfc->ndfcbase + NDFC_CCR); 58 ccr = in_be32(ndfc->ndfcbase + NDFC_CCR);
57 if (chip >= 0) { 59 if (chip >= 0) {
@@ -64,7 +66,8 @@ static void ndfc_select_chip(struct mtd_info *mtd, int chip)
64 66
65static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) 67static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
66{ 68{
67 struct ndfc_controller *ndfc = &ndfc_ctrl; 69 struct nand_chip *chip = mtd->priv;
70 struct ndfc_controller *ndfc = chip->priv;
68 71
69 if (cmd == NAND_CMD_NONE) 72 if (cmd == NAND_CMD_NONE)
70 return; 73 return;
@@ -77,7 +80,8 @@ static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
77 80
78static int ndfc_ready(struct mtd_info *mtd) 81static int ndfc_ready(struct mtd_info *mtd)
79{ 82{
80 struct ndfc_controller *ndfc = &ndfc_ctrl; 83 struct nand_chip *chip = mtd->priv;
84 struct ndfc_controller *ndfc = chip->priv;
81 85
82 return in_be32(ndfc->ndfcbase + NDFC_STAT) & NDFC_STAT_IS_READY; 86 return in_be32(ndfc->ndfcbase + NDFC_STAT) & NDFC_STAT_IS_READY;
83} 87}
@@ -85,7 +89,8 @@ static int ndfc_ready(struct mtd_info *mtd)
85static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode) 89static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode)
86{ 90{
87 uint32_t ccr; 91 uint32_t ccr;
88 struct ndfc_controller *ndfc = &ndfc_ctrl; 92 struct nand_chip *chip = mtd->priv;
93 struct ndfc_controller *ndfc = chip->priv;
89 94
90 ccr = in_be32(ndfc->ndfcbase + NDFC_CCR); 95 ccr = in_be32(ndfc->ndfcbase + NDFC_CCR);
91 ccr |= NDFC_CCR_RESET_ECC; 96 ccr |= NDFC_CCR_RESET_ECC;
@@ -96,7 +101,8 @@ static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode)
96static int ndfc_calculate_ecc(struct mtd_info *mtd, 101static int ndfc_calculate_ecc(struct mtd_info *mtd,
97 const u_char *dat, u_char *ecc_code) 102 const u_char *dat, u_char *ecc_code)
98{ 103{
99 struct ndfc_controller *ndfc = &ndfc_ctrl; 104 struct nand_chip *chip = mtd->priv;
105 struct ndfc_controller *ndfc = chip->priv;
100 uint32_t ecc; 106 uint32_t ecc;
101 uint8_t *p = (uint8_t *)&ecc; 107 uint8_t *p = (uint8_t *)&ecc;
102 108
@@ -119,7 +125,8 @@ static int ndfc_calculate_ecc(struct mtd_info *mtd,
119 */ 125 */
120static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) 126static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
121{ 127{
122 struct ndfc_controller *ndfc = &ndfc_ctrl; 128 struct nand_chip *chip = mtd->priv;
129 struct ndfc_controller *ndfc = chip->priv;
123 uint32_t *p = (uint32_t *) buf; 130 uint32_t *p = (uint32_t *) buf;
124 131
125 for(;len > 0; len -= 4) 132 for(;len > 0; len -= 4)
@@ -128,7 +135,8 @@ static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
128 135
129static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) 136static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
130{ 137{
131 struct ndfc_controller *ndfc = &ndfc_ctrl; 138 struct nand_chip *chip = mtd->priv;
139 struct ndfc_controller *ndfc = chip->priv;
132 uint32_t *p = (uint32_t *) buf; 140 uint32_t *p = (uint32_t *) buf;
133 141
134 for(;len > 0; len -= 4) 142 for(;len > 0; len -= 4)
@@ -137,7 +145,8 @@ static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
137 145
138static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len) 146static int ndfc_verify_buf(struct mtd_info *mtd, const uint8_t *buf, int len)
139{ 147{
140 struct ndfc_controller *ndfc = &ndfc_ctrl; 148 struct nand_chip *chip = mtd->priv;
149 struct ndfc_controller *ndfc = chip->priv;
141 uint32_t *p = (uint32_t *) buf; 150 uint32_t *p = (uint32_t *) buf;
142 151
143 for(;len > 0; len -= 4) 152 for(;len > 0; len -= 4)
@@ -179,6 +188,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc,
179 chip->ecc.mode = NAND_ECC_HW; 188 chip->ecc.mode = NAND_ECC_HW;
180 chip->ecc.size = 256; 189 chip->ecc.size = 256;
181 chip->ecc.bytes = 3; 190 chip->ecc.bytes = 3;
191 chip->priv = ndfc;
182 192
183 ndfc->mtd.priv = chip; 193 ndfc->mtd.priv = chip;
184 ndfc->mtd.owner = THIS_MODULE; 194 ndfc->mtd.owner = THIS_MODULE;
@@ -227,15 +237,10 @@ err:
227 237
228static int __devinit ndfc_probe(struct platform_device *ofdev) 238static int __devinit ndfc_probe(struct platform_device *ofdev)
229{ 239{
230 struct ndfc_controller *ndfc = &ndfc_ctrl; 240 struct ndfc_controller *ndfc;
231 const __be32 *reg; 241 const __be32 *reg;
232 u32 ccr; 242 u32 ccr;
233 int err, len; 243 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 244
240 /* Read the reg property to get the chip select */ 245 /* Read the reg property to get the chip select */
241 reg = of_get_property(ofdev->dev.of_node, "reg", &len); 246 reg = of_get_property(ofdev->dev.of_node, "reg", &len);
@@ -243,7 +248,20 @@ static int __devinit ndfc_probe(struct platform_device *ofdev)
243 dev_err(&ofdev->dev, "unable read reg property (%d)\n", len); 248 dev_err(&ofdev->dev, "unable read reg property (%d)\n", len);
244 return -ENOENT; 249 return -ENOENT;
245 } 250 }
246 ndfc->chip_select = be32_to_cpu(reg[0]); 251
252 cs = be32_to_cpu(reg[0]);
253 if (cs >= NDFC_MAX_CS) {
254 dev_err(&ofdev->dev, "invalid CS number (%d)\n", cs);
255 return -EINVAL;
256 }
257
258 ndfc = &ndfc_ctrl[cs];
259 ndfc->chip_select = cs;
260
261 spin_lock_init(&ndfc->ndfc_control.lock);
262 init_waitqueue_head(&ndfc->ndfc_control.wq);
263 ndfc->ofdev = ofdev;
264 dev_set_drvdata(&ofdev->dev, ndfc);
247 265
248 ndfc->ndfcbase = of_iomap(ofdev->dev.of_node, 0); 266 ndfc->ndfcbase = of_iomap(ofdev->dev.of_node, 0);
249 if (!ndfc->ndfcbase) { 267 if (!ndfc->ndfcbase) {