• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * drivers/mtd/nand/gpio.c
3  *
4  * Updated, and converted to generic GPIO based driver by Russell King.
5  *
6  * Written by Ben Dooks <ben@simtec.co.uk>
7  *   Based on 2.4 version by Mark Whittaker
8  *
9  * © 2004 Simtec Electronics
10  *
11  * Device driver for NAND connected via GPIO
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License version 2 as
15  * published by the Free Software Foundation.
16  *
17  */
18 
19 #include <linux/kernel.h>
20 #include <linux/init.h>
21 #include <linux/slab.h>
22 #include <linux/module.h>
23 #include <linux/platform_device.h>
24 #include <linux/gpio.h>
25 #include <linux/io.h>
26 #include <linux/mtd/mtd.h>
27 #include <linux/mtd/nand.h>
28 #include <linux/mtd/partitions.h>
29 #include <linux/mtd/nand-gpio.h>
30 #include <linux/of.h>
31 #include <linux/of_address.h>
32 #include <linux/of_gpio.h>
33 
34 struct gpiomtd {
35 	void __iomem		*io_sync;
36 	struct mtd_info		mtd_info;
37 	struct nand_chip	nand_chip;
38 	struct gpio_nand_platdata plat;
39 };
40 
41 #define gpio_nand_getpriv(x) container_of(x, struct gpiomtd, mtd_info)
42 
43 
44 #ifdef CONFIG_ARM
45 /* gpio_nand_dosync()
46  *
47  * Make sure the GPIO state changes occur in-order with writes to NAND
48  * memory region.
49  * Needed on PXA due to bus-reordering within the SoC itself (see section on
50  * I/O ordering in PXA manual (section 2.3, p35)
51  */
gpio_nand_dosync(struct gpiomtd * gpiomtd)52 static void gpio_nand_dosync(struct gpiomtd *gpiomtd)
53 {
54 	unsigned long tmp;
55 
56 	if (gpiomtd->io_sync) {
57 		/*
58 		 * Linux memory barriers don't cater for what's required here.
59 		 * What's required is what's here - a read from a separate
60 		 * region with a dependency on that read.
61 		 */
62 		tmp = readl(gpiomtd->io_sync);
63 		asm volatile("mov %1, %0\n" : "=r" (tmp) : "r" (tmp));
64 	}
65 }
66 #else
gpio_nand_dosync(struct gpiomtd * gpiomtd)67 static inline void gpio_nand_dosync(struct gpiomtd *gpiomtd) {}
68 #endif
69 
gpio_nand_cmd_ctrl(struct mtd_info * mtd,int cmd,unsigned int ctrl)70 static void gpio_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
71 {
72 	struct gpiomtd *gpiomtd = gpio_nand_getpriv(mtd);
73 
74 	gpio_nand_dosync(gpiomtd);
75 
76 	if (ctrl & NAND_CTRL_CHANGE) {
77 		gpio_set_value(gpiomtd->plat.gpio_nce, !(ctrl & NAND_NCE));
78 		gpio_set_value(gpiomtd->plat.gpio_cle, !!(ctrl & NAND_CLE));
79 		gpio_set_value(gpiomtd->plat.gpio_ale, !!(ctrl & NAND_ALE));
80 		gpio_nand_dosync(gpiomtd);
81 	}
82 	if (cmd == NAND_CMD_NONE)
83 		return;
84 
85 	writeb(cmd, gpiomtd->nand_chip.IO_ADDR_W);
86 	gpio_nand_dosync(gpiomtd);
87 }
88 
gpio_nand_writebuf(struct mtd_info * mtd,const u_char * buf,int len)89 static void gpio_nand_writebuf(struct mtd_info *mtd, const u_char *buf, int len)
90 {
91 	struct nand_chip *this = mtd->priv;
92 
93 	writesb(this->IO_ADDR_W, buf, len);
94 }
95 
gpio_nand_readbuf(struct mtd_info * mtd,u_char * buf,int len)96 static void gpio_nand_readbuf(struct mtd_info *mtd, u_char *buf, int len)
97 {
98 	struct nand_chip *this = mtd->priv;
99 
100 	readsb(this->IO_ADDR_R, buf, len);
101 }
102 
gpio_nand_verifybuf(struct mtd_info * mtd,const u_char * buf,int len)103 static int gpio_nand_verifybuf(struct mtd_info *mtd, const u_char *buf, int len)
104 {
105 	struct nand_chip *this = mtd->priv;
106 	unsigned char read, *p = (unsigned char *) buf;
107 	int i, err = 0;
108 
109 	for (i = 0; i < len; i++) {
110 		read = readb(this->IO_ADDR_R);
111 		if (read != p[i]) {
112 			pr_debug("%s: err at %d (read %04x vs %04x)\n",
113 			       __func__, i, read, p[i]);
114 			err = -EFAULT;
115 		}
116 	}
117 	return err;
118 }
119 
gpio_nand_writebuf16(struct mtd_info * mtd,const u_char * buf,int len)120 static void gpio_nand_writebuf16(struct mtd_info *mtd, const u_char *buf,
121 				 int len)
122 {
123 	struct nand_chip *this = mtd->priv;
124 
125 	if (IS_ALIGNED((unsigned long)buf, 2)) {
126 		writesw(this->IO_ADDR_W, buf, len>>1);
127 	} else {
128 		int i;
129 		unsigned short *ptr = (unsigned short *)buf;
130 
131 		for (i = 0; i < len; i += 2, ptr++)
132 			writew(*ptr, this->IO_ADDR_W);
133 	}
134 }
135 
gpio_nand_readbuf16(struct mtd_info * mtd,u_char * buf,int len)136 static void gpio_nand_readbuf16(struct mtd_info *mtd, u_char *buf, int len)
137 {
138 	struct nand_chip *this = mtd->priv;
139 
140 	if (IS_ALIGNED((unsigned long)buf, 2)) {
141 		readsw(this->IO_ADDR_R, buf, len>>1);
142 	} else {
143 		int i;
144 		unsigned short *ptr = (unsigned short *)buf;
145 
146 		for (i = 0; i < len; i += 2, ptr++)
147 			*ptr = readw(this->IO_ADDR_R);
148 	}
149 }
150 
gpio_nand_verifybuf16(struct mtd_info * mtd,const u_char * buf,int len)151 static int gpio_nand_verifybuf16(struct mtd_info *mtd, const u_char *buf,
152 				 int len)
153 {
154 	struct nand_chip *this = mtd->priv;
155 	unsigned short read, *p = (unsigned short *) buf;
156 	int i, err = 0;
157 	len >>= 1;
158 
159 	for (i = 0; i < len; i++) {
160 		read = readw(this->IO_ADDR_R);
161 		if (read != p[i]) {
162 			pr_debug("%s: err at %d (read %04x vs %04x)\n",
163 			       __func__, i, read, p[i]);
164 			err = -EFAULT;
165 		}
166 	}
167 	return err;
168 }
169 
170 
gpio_nand_devready(struct mtd_info * mtd)171 static int gpio_nand_devready(struct mtd_info *mtd)
172 {
173 	struct gpiomtd *gpiomtd = gpio_nand_getpriv(mtd);
174 	return gpio_get_value(gpiomtd->plat.gpio_rdy);
175 }
176 
177 #ifdef CONFIG_OF
178 static const struct of_device_id gpio_nand_id_table[] = {
179 	{ .compatible = "gpio-control-nand" },
180 	{}
181 };
182 MODULE_DEVICE_TABLE(of, gpio_nand_id_table);
183 
gpio_nand_get_config_of(const struct device * dev,struct gpio_nand_platdata * plat)184 static int gpio_nand_get_config_of(const struct device *dev,
185 				   struct gpio_nand_platdata *plat)
186 {
187 	u32 val;
188 
189 	if (!of_property_read_u32(dev->of_node, "bank-width", &val)) {
190 		if (val == 2) {
191 			plat->options |= NAND_BUSWIDTH_16;
192 		} else if (val != 1) {
193 			dev_err(dev, "invalid bank-width %u\n", val);
194 			return -EINVAL;
195 		}
196 	}
197 
198 	plat->gpio_rdy = of_get_gpio(dev->of_node, 0);
199 	plat->gpio_nce = of_get_gpio(dev->of_node, 1);
200 	plat->gpio_ale = of_get_gpio(dev->of_node, 2);
201 	plat->gpio_cle = of_get_gpio(dev->of_node, 3);
202 	plat->gpio_nwp = of_get_gpio(dev->of_node, 4);
203 
204 	if (!of_property_read_u32(dev->of_node, "chip-delay", &val))
205 		plat->chip_delay = val;
206 
207 	return 0;
208 }
209 
gpio_nand_get_io_sync_of(struct platform_device * pdev)210 static struct resource *gpio_nand_get_io_sync_of(struct platform_device *pdev)
211 {
212 	struct resource *r = devm_kzalloc(&pdev->dev, sizeof(*r), GFP_KERNEL);
213 	u64 addr;
214 
215 	if (!r || of_property_read_u64(pdev->dev.of_node,
216 				       "gpio-control-nand,io-sync-reg", &addr))
217 		return NULL;
218 
219 	r->start = addr;
220 	r->end = r->start + 0x3;
221 	r->flags = IORESOURCE_MEM;
222 
223 	return r;
224 }
225 #else /* CONFIG_OF */
226 #define gpio_nand_id_table NULL
gpio_nand_get_config_of(const struct device * dev,struct gpio_nand_platdata * plat)227 static inline int gpio_nand_get_config_of(const struct device *dev,
228 					  struct gpio_nand_platdata *plat)
229 {
230 	return -ENOSYS;
231 }
232 
233 static inline struct resource *
gpio_nand_get_io_sync_of(struct platform_device * pdev)234 gpio_nand_get_io_sync_of(struct platform_device *pdev)
235 {
236 	return NULL;
237 }
238 #endif /* CONFIG_OF */
239 
gpio_nand_get_config(const struct device * dev,struct gpio_nand_platdata * plat)240 static inline int gpio_nand_get_config(const struct device *dev,
241 				       struct gpio_nand_platdata *plat)
242 {
243 	int ret = gpio_nand_get_config_of(dev, plat);
244 
245 	if (!ret)
246 		return ret;
247 
248 	if (dev->platform_data) {
249 		memcpy(plat, dev->platform_data, sizeof(*plat));
250 		return 0;
251 	}
252 
253 	return -EINVAL;
254 }
255 
256 static inline struct resource *
gpio_nand_get_io_sync(struct platform_device * pdev)257 gpio_nand_get_io_sync(struct platform_device *pdev)
258 {
259 	struct resource *r = gpio_nand_get_io_sync_of(pdev);
260 
261 	if (r)
262 		return r;
263 
264 	return platform_get_resource(pdev, IORESOURCE_MEM, 1);
265 }
266 
gpio_nand_remove(struct platform_device * dev)267 static int __devexit gpio_nand_remove(struct platform_device *dev)
268 {
269 	struct gpiomtd *gpiomtd = platform_get_drvdata(dev);
270 	struct resource *res;
271 
272 	nand_release(&gpiomtd->mtd_info);
273 
274 	res = gpio_nand_get_io_sync(dev);
275 	iounmap(gpiomtd->io_sync);
276 	if (res)
277 		release_mem_region(res->start, resource_size(res));
278 
279 	res = platform_get_resource(dev, IORESOURCE_MEM, 0);
280 	iounmap(gpiomtd->nand_chip.IO_ADDR_R);
281 	release_mem_region(res->start, resource_size(res));
282 
283 	if (gpio_is_valid(gpiomtd->plat.gpio_nwp))
284 		gpio_set_value(gpiomtd->plat.gpio_nwp, 0);
285 	gpio_set_value(gpiomtd->plat.gpio_nce, 1);
286 
287 	gpio_free(gpiomtd->plat.gpio_cle);
288 	gpio_free(gpiomtd->plat.gpio_ale);
289 	gpio_free(gpiomtd->plat.gpio_nce);
290 	if (gpio_is_valid(gpiomtd->plat.gpio_nwp))
291 		gpio_free(gpiomtd->plat.gpio_nwp);
292 	gpio_free(gpiomtd->plat.gpio_rdy);
293 
294 	kfree(gpiomtd);
295 
296 	return 0;
297 }
298 
request_and_remap(struct resource * res,size_t size,const char * name,int * err)299 static void __iomem *request_and_remap(struct resource *res, size_t size,
300 					const char *name, int *err)
301 {
302 	void __iomem *ptr;
303 
304 	if (!request_mem_region(res->start, resource_size(res), name)) {
305 		*err = -EBUSY;
306 		return NULL;
307 	}
308 
309 	ptr = ioremap(res->start, size);
310 	if (!ptr) {
311 		release_mem_region(res->start, resource_size(res));
312 		*err = -ENOMEM;
313 	}
314 	return ptr;
315 }
316 
gpio_nand_probe(struct platform_device * dev)317 static int __devinit gpio_nand_probe(struct platform_device *dev)
318 {
319 	struct gpiomtd *gpiomtd;
320 	struct nand_chip *this;
321 	struct resource *res0, *res1;
322 	struct mtd_part_parser_data ppdata = {};
323 	int ret = 0;
324 
325 	if (!dev->dev.of_node && !dev->dev.platform_data)
326 		return -EINVAL;
327 
328 	res0 = platform_get_resource(dev, IORESOURCE_MEM, 0);
329 	if (!res0)
330 		return -EINVAL;
331 
332 	gpiomtd = kzalloc(sizeof(*gpiomtd), GFP_KERNEL);
333 	if (gpiomtd == NULL) {
334 		dev_err(&dev->dev, "failed to create NAND MTD\n");
335 		return -ENOMEM;
336 	}
337 
338 	this = &gpiomtd->nand_chip;
339 	this->IO_ADDR_R = request_and_remap(res0, 2, "NAND", &ret);
340 	if (!this->IO_ADDR_R) {
341 		dev_err(&dev->dev, "unable to map NAND\n");
342 		goto err_map;
343 	}
344 
345 	res1 = gpio_nand_get_io_sync(dev);
346 	if (res1) {
347 		gpiomtd->io_sync = request_and_remap(res1, 4, "NAND sync", &ret);
348 		if (!gpiomtd->io_sync) {
349 			dev_err(&dev->dev, "unable to map sync NAND\n");
350 			goto err_sync;
351 		}
352 	}
353 
354 	ret = gpio_nand_get_config(&dev->dev, &gpiomtd->plat);
355 	if (ret)
356 		goto err_nce;
357 
358 	ret = gpio_request(gpiomtd->plat.gpio_nce, "NAND NCE");
359 	if (ret)
360 		goto err_nce;
361 	gpio_direction_output(gpiomtd->plat.gpio_nce, 1);
362 	if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) {
363 		ret = gpio_request(gpiomtd->plat.gpio_nwp, "NAND NWP");
364 		if (ret)
365 			goto err_nwp;
366 		gpio_direction_output(gpiomtd->plat.gpio_nwp, 1);
367 	}
368 	ret = gpio_request(gpiomtd->plat.gpio_ale, "NAND ALE");
369 	if (ret)
370 		goto err_ale;
371 	gpio_direction_output(gpiomtd->plat.gpio_ale, 0);
372 	ret = gpio_request(gpiomtd->plat.gpio_cle, "NAND CLE");
373 	if (ret)
374 		goto err_cle;
375 	gpio_direction_output(gpiomtd->plat.gpio_cle, 0);
376 	ret = gpio_request(gpiomtd->plat.gpio_rdy, "NAND RDY");
377 	if (ret)
378 		goto err_rdy;
379 	gpio_direction_input(gpiomtd->plat.gpio_rdy);
380 
381 
382 	this->IO_ADDR_W  = this->IO_ADDR_R;
383 	this->ecc.mode   = NAND_ECC_SOFT;
384 	this->options    = gpiomtd->plat.options;
385 	this->chip_delay = gpiomtd->plat.chip_delay;
386 
387 	/* install our routines */
388 	this->cmd_ctrl   = gpio_nand_cmd_ctrl;
389 	this->dev_ready  = gpio_nand_devready;
390 
391 	if (this->options & NAND_BUSWIDTH_16) {
392 		this->read_buf   = gpio_nand_readbuf16;
393 		this->write_buf  = gpio_nand_writebuf16;
394 		this->verify_buf = gpio_nand_verifybuf16;
395 	} else {
396 		this->read_buf   = gpio_nand_readbuf;
397 		this->write_buf  = gpio_nand_writebuf;
398 		this->verify_buf = gpio_nand_verifybuf;
399 	}
400 
401 	/* set the mtd private data for the nand driver */
402 	gpiomtd->mtd_info.priv = this;
403 	gpiomtd->mtd_info.owner = THIS_MODULE;
404 
405 	if (nand_scan(&gpiomtd->mtd_info, 1)) {
406 		dev_err(&dev->dev, "no nand chips found?\n");
407 		ret = -ENXIO;
408 		goto err_wp;
409 	}
410 
411 	if (gpiomtd->plat.adjust_parts)
412 		gpiomtd->plat.adjust_parts(&gpiomtd->plat,
413 					   gpiomtd->mtd_info.size);
414 
415 	ppdata.of_node = dev->dev.of_node;
416 	ret = mtd_device_parse_register(&gpiomtd->mtd_info, NULL, &ppdata,
417 					gpiomtd->plat.parts,
418 					gpiomtd->plat.num_parts);
419 	if (ret)
420 		goto err_wp;
421 	platform_set_drvdata(dev, gpiomtd);
422 
423 	return 0;
424 
425 err_wp:
426 	if (gpio_is_valid(gpiomtd->plat.gpio_nwp))
427 		gpio_set_value(gpiomtd->plat.gpio_nwp, 0);
428 	gpio_free(gpiomtd->plat.gpio_rdy);
429 err_rdy:
430 	gpio_free(gpiomtd->plat.gpio_cle);
431 err_cle:
432 	gpio_free(gpiomtd->plat.gpio_ale);
433 err_ale:
434 	if (gpio_is_valid(gpiomtd->plat.gpio_nwp))
435 		gpio_free(gpiomtd->plat.gpio_nwp);
436 err_nwp:
437 	gpio_free(gpiomtd->plat.gpio_nce);
438 err_nce:
439 	iounmap(gpiomtd->io_sync);
440 	if (res1)
441 		release_mem_region(res1->start, resource_size(res1));
442 err_sync:
443 	iounmap(gpiomtd->nand_chip.IO_ADDR_R);
444 	release_mem_region(res0->start, resource_size(res0));
445 err_map:
446 	kfree(gpiomtd);
447 	return ret;
448 }
449 
450 static struct platform_driver gpio_nand_driver = {
451 	.probe		= gpio_nand_probe,
452 	.remove		= gpio_nand_remove,
453 	.driver		= {
454 		.name	= "gpio-nand",
455 		.of_match_table = gpio_nand_id_table,
456 	},
457 };
458 
gpio_nand_init(void)459 static int __init gpio_nand_init(void)
460 {
461 	printk(KERN_INFO "GPIO NAND driver, © 2004 Simtec Electronics\n");
462 
463 	return platform_driver_register(&gpio_nand_driver);
464 }
465 
gpio_nand_exit(void)466 static void __exit gpio_nand_exit(void)
467 {
468 	platform_driver_unregister(&gpio_nand_driver);
469 }
470 
471 module_init(gpio_nand_init);
472 module_exit(gpio_nand_exit);
473 
474 MODULE_LICENSE("GPL");
475 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
476 MODULE_DESCRIPTION("GPIO NAND Driver");
477