diff options
Diffstat (limited to 'drivers/mtd/nand')
25 files changed, 300 insertions, 1688 deletions
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 5d54ad32697f..a60f6c17f57b 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
@@ -41,14 +41,6 @@ config MTD_SM_COMMON | |||
41 | tristate | 41 | tristate |
42 | default n | 42 | default n |
43 | 43 | ||
44 | config MTD_NAND_MUSEUM_IDS | ||
45 | bool "Enable chip ids for obsolete ancient NAND devices" | ||
46 | default n | ||
47 | help | ||
48 | Enable this option only when your board has first generation | ||
49 | NAND chips (page size 256 byte, erase size 4-8KiB). The IDs | ||
50 | of these chips were reused by later, larger chips. | ||
51 | |||
52 | config MTD_NAND_DENALI | 44 | config MTD_NAND_DENALI |
53 | tristate "Support Denali NAND controller" | 45 | tristate "Support Denali NAND controller" |
54 | help | 46 | help |
@@ -81,12 +73,6 @@ config MTD_NAND_DENALI_SCRATCH_REG_ADDR | |||
81 | scratch register here to enable this feature. On Intel Moorestown | 73 | scratch register here to enable this feature. On Intel Moorestown |
82 | boards, the scratch register is at 0xFF108018. | 74 | boards, the scratch register is at 0xFF108018. |
83 | 75 | ||
84 | config MTD_NAND_H1900 | ||
85 | tristate "iPAQ H1900 flash" | ||
86 | depends on ARCH_PXA && BROKEN | ||
87 | help | ||
88 | This enables the driver for the iPAQ h1900 flash. | ||
89 | |||
90 | config MTD_NAND_GPIO | 76 | config MTD_NAND_GPIO |
91 | tristate "GPIO NAND Flash driver" | 77 | tristate "GPIO NAND Flash driver" |
92 | depends on GPIOLIB && ARM | 78 | depends on GPIOLIB && ARM |
@@ -201,22 +187,6 @@ config MTD_NAND_BF5XX_BOOTROM_ECC | |||
201 | 187 | ||
202 | If unsure, say N. | 188 | If unsure, say N. |
203 | 189 | ||
204 | config MTD_NAND_RTC_FROM4 | ||
205 | tristate "Renesas Flash ROM 4-slot interface board (FROM_BOARD4)" | ||
206 | depends on SH_SOLUTION_ENGINE | ||
207 | select REED_SOLOMON | ||
208 | select REED_SOLOMON_DEC8 | ||
209 | select BITREVERSE | ||
210 | help | ||
211 | This enables the driver for the Renesas Technology AG-AND | ||
212 | flash interface board (FROM_BOARD4) | ||
213 | |||
214 | config MTD_NAND_PPCHAMELEONEVB | ||
215 | tristate "NAND Flash device on PPChameleonEVB board" | ||
216 | depends on PPCHAMELEONEVB && BROKEN | ||
217 | help | ||
218 | This enables the NAND flash driver on the PPChameleon EVB Board. | ||
219 | |||
220 | config MTD_NAND_S3C2410 | 190 | config MTD_NAND_S3C2410 |
221 | tristate "NAND Flash support for Samsung S3C SoCs" | 191 | tristate "NAND Flash support for Samsung S3C SoCs" |
222 | depends on ARCH_S3C24XX || ARCH_S3C64XX | 192 | depends on ARCH_S3C24XX || ARCH_S3C64XX |
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index d76d91205691..bb8189172f62 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile | |||
@@ -15,14 +15,11 @@ obj-$(CONFIG_MTD_NAND_DENALI_PCI) += denali_pci.o | |||
15 | obj-$(CONFIG_MTD_NAND_DENALI_DT) += denali_dt.o | 15 | obj-$(CONFIG_MTD_NAND_DENALI_DT) += denali_dt.o |
16 | obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o | 16 | obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o |
17 | obj-$(CONFIG_MTD_NAND_BF5XX) += bf5xx_nand.o | 17 | obj-$(CONFIG_MTD_NAND_BF5XX) += bf5xx_nand.o |
18 | obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB) += ppchameleonevb.o | ||
19 | obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o | 18 | obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o |
20 | obj-$(CONFIG_MTD_NAND_DAVINCI) += davinci_nand.o | 19 | obj-$(CONFIG_MTD_NAND_DAVINCI) += davinci_nand.o |
21 | obj-$(CONFIG_MTD_NAND_DISKONCHIP) += diskonchip.o | 20 | obj-$(CONFIG_MTD_NAND_DISKONCHIP) += diskonchip.o |
22 | obj-$(CONFIG_MTD_NAND_DOCG4) += docg4.o | 21 | obj-$(CONFIG_MTD_NAND_DOCG4) += docg4.o |
23 | obj-$(CONFIG_MTD_NAND_FSMC) += fsmc_nand.o | 22 | obj-$(CONFIG_MTD_NAND_FSMC) += fsmc_nand.o |
24 | obj-$(CONFIG_MTD_NAND_H1900) += h1910.o | ||
25 | obj-$(CONFIG_MTD_NAND_RTC_FROM4) += rtc_from4.o | ||
26 | obj-$(CONFIG_MTD_NAND_SHARPSL) += sharpsl.o | 23 | obj-$(CONFIG_MTD_NAND_SHARPSL) += sharpsl.o |
27 | obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o | 24 | obj-$(CONFIG_MTD_NAND_NANDSIM) += nandsim.o |
28 | obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o | 25 | obj-$(CONFIG_MTD_NAND_CS553X) += cs553x_nand.o |
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index ffcbcca2fd2d..2d23d2929438 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c | |||
@@ -1737,20 +1737,7 @@ static struct platform_driver atmel_nand_driver = { | |||
1737 | }, | 1737 | }, |
1738 | }; | 1738 | }; |
1739 | 1739 | ||
1740 | static int __init atmel_nand_init(void) | 1740 | module_platform_driver_probe(atmel_nand_driver, atmel_nand_probe); |
1741 | { | ||
1742 | return platform_driver_probe(&atmel_nand_driver, atmel_nand_probe); | ||
1743 | } | ||
1744 | |||
1745 | |||
1746 | static void __exit atmel_nand_exit(void) | ||
1747 | { | ||
1748 | platform_driver_unregister(&atmel_nand_driver); | ||
1749 | } | ||
1750 | |||
1751 | |||
1752 | module_init(atmel_nand_init); | ||
1753 | module_exit(atmel_nand_exit); | ||
1754 | 1741 | ||
1755 | MODULE_LICENSE("GPL"); | 1742 | MODULE_LICENSE("GPL"); |
1756 | MODULE_AUTHOR("Rick Bronson"); | 1743 | MODULE_AUTHOR("Rick Bronson"); |
diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c index 4271e948d1e2..776df3694f75 100644 --- a/drivers/mtd/nand/bf5xx_nand.c +++ b/drivers/mtd/nand/bf5xx_nand.c | |||
@@ -874,21 +874,7 @@ static struct platform_driver bf5xx_nand_driver = { | |||
874 | }, | 874 | }, |
875 | }; | 875 | }; |
876 | 876 | ||
877 | static int __init bf5xx_nand_init(void) | 877 | module_platform_driver(bf5xx_nand_driver); |
878 | { | ||
879 | printk(KERN_INFO "%s, Version %s (c) 2007 Analog Devices, Inc.\n", | ||
880 | DRV_DESC, DRV_VERSION); | ||
881 | |||
882 | return platform_driver_register(&bf5xx_nand_driver); | ||
883 | } | ||
884 | |||
885 | static void __exit bf5xx_nand_exit(void) | ||
886 | { | ||
887 | platform_driver_unregister(&bf5xx_nand_driver); | ||
888 | } | ||
889 | |||
890 | module_init(bf5xx_nand_init); | ||
891 | module_exit(bf5xx_nand_exit); | ||
892 | 878 | ||
893 | MODULE_LICENSE("GPL"); | 879 | MODULE_LICENSE("GPL"); |
894 | MODULE_AUTHOR(DRV_AUTHOR); | 880 | MODULE_AUTHOR(DRV_AUTHOR); |
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index 010d61266536..c34985a55101 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c | |||
@@ -303,13 +303,7 @@ static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command, | |||
303 | case NAND_CMD_SEQIN: | 303 | case NAND_CMD_SEQIN: |
304 | case NAND_CMD_RNDIN: | 304 | case NAND_CMD_RNDIN: |
305 | case NAND_CMD_STATUS: | 305 | case NAND_CMD_STATUS: |
306 | case NAND_CMD_DEPLETE1: | ||
307 | case NAND_CMD_RNDOUT: | 306 | case NAND_CMD_RNDOUT: |
308 | case NAND_CMD_STATUS_ERROR: | ||
309 | case NAND_CMD_STATUS_ERROR0: | ||
310 | case NAND_CMD_STATUS_ERROR1: | ||
311 | case NAND_CMD_STATUS_ERROR2: | ||
312 | case NAND_CMD_STATUS_ERROR3: | ||
313 | cafe_writel(cafe, cafe->ctl2, NAND_CTRL2); | 307 | cafe_writel(cafe, cafe->ctl2, NAND_CTRL2); |
314 | return; | 308 | return; |
315 | } | 309 | } |
@@ -536,8 +530,8 @@ static int cafe_nand_write_page_lowlevel(struct mtd_info *mtd, | |||
536 | } | 530 | } |
537 | 531 | ||
538 | static int cafe_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, | 532 | static int cafe_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, |
539 | const uint8_t *buf, int oob_required, int page, | 533 | uint32_t offset, int data_len, const uint8_t *buf, |
540 | int cached, int raw) | 534 | int oob_required, int page, int cached, int raw) |
541 | { | 535 | { |
542 | int status; | 536 | int status; |
543 | 537 | ||
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index 94e17af8e450..c3e15a558173 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/mtd/partitions.h> | 34 | #include <linux/mtd/partitions.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/of_device.h> | 36 | #include <linux/of_device.h> |
37 | #include <linux/of.h> | ||
37 | 38 | ||
38 | #include <linux/platform_data/mtd-davinci.h> | 39 | #include <linux/platform_data/mtd-davinci.h> |
39 | #include <linux/platform_data/mtd-davinci-aemif.h> | 40 | #include <linux/platform_data/mtd-davinci-aemif.h> |
@@ -577,7 +578,6 @@ static struct davinci_nand_pdata | |||
577 | return pdev->dev.platform_data; | 578 | return pdev->dev.platform_data; |
578 | } | 579 | } |
579 | #else | 580 | #else |
580 | #define davinci_nand_of_match NULL | ||
581 | static struct davinci_nand_pdata | 581 | static struct davinci_nand_pdata |
582 | *nand_davinci_get_pdata(struct platform_device *pdev) | 582 | *nand_davinci_get_pdata(struct platform_device *pdev) |
583 | { | 583 | { |
@@ -878,22 +878,12 @@ static struct platform_driver nand_davinci_driver = { | |||
878 | .driver = { | 878 | .driver = { |
879 | .name = "davinci_nand", | 879 | .name = "davinci_nand", |
880 | .owner = THIS_MODULE, | 880 | .owner = THIS_MODULE, |
881 | .of_match_table = davinci_nand_of_match, | 881 | .of_match_table = of_match_ptr(davinci_nand_of_match), |
882 | }, | 882 | }, |
883 | }; | 883 | }; |
884 | MODULE_ALIAS("platform:davinci_nand"); | 884 | MODULE_ALIAS("platform:davinci_nand"); |
885 | 885 | ||
886 | static int __init nand_davinci_init(void) | 886 | module_platform_driver_probe(nand_davinci_driver, nand_davinci_probe); |
887 | { | ||
888 | return platform_driver_probe(&nand_davinci_driver, nand_davinci_probe); | ||
889 | } | ||
890 | module_init(nand_davinci_init); | ||
891 | |||
892 | static void __exit nand_davinci_exit(void) | ||
893 | { | ||
894 | platform_driver_unregister(&nand_davinci_driver); | ||
895 | } | ||
896 | module_exit(nand_davinci_exit); | ||
897 | 887 | ||
898 | MODULE_LICENSE("GPL"); | 888 | MODULE_LICENSE("GPL"); |
899 | MODULE_AUTHOR("Texas Instruments"); | 889 | MODULE_AUTHOR("Texas Instruments"); |
diff --git a/drivers/mtd/nand/denali_dt.c b/drivers/mtd/nand/denali_dt.c index 546f8cb5688d..92530244e2cb 100644 --- a/drivers/mtd/nand/denali_dt.c +++ b/drivers/mtd/nand/denali_dt.c | |||
@@ -42,7 +42,7 @@ static void __iomem *request_and_map(struct device *dev, | |||
42 | } | 42 | } |
43 | 43 | ||
44 | ptr = devm_ioremap_nocache(dev, res->start, resource_size(res)); | 44 | ptr = devm_ioremap_nocache(dev, res->start, resource_size(res)); |
45 | if (!res) | 45 | if (!ptr) |
46 | dev_err(dev, "ioremap_nocache of %s failed!", res->name); | 46 | dev_err(dev, "ioremap_nocache of %s failed!", res->name); |
47 | 47 | ||
48 | return ptr; | 48 | return ptr; |
@@ -90,7 +90,7 @@ static int denali_dt_probe(struct platform_device *ofdev) | |||
90 | denali->irq = platform_get_irq(ofdev, 0); | 90 | denali->irq = platform_get_irq(ofdev, 0); |
91 | if (denali->irq < 0) { | 91 | if (denali->irq < 0) { |
92 | dev_err(&ofdev->dev, "no irq defined\n"); | 92 | dev_err(&ofdev->dev, "no irq defined\n"); |
93 | return -ENXIO; | 93 | return denali->irq; |
94 | } | 94 | } |
95 | 95 | ||
96 | denali->flash_reg = request_and_map(&ofdev->dev, denali_reg); | 96 | denali->flash_reg = request_and_map(&ofdev->dev, denali_reg); |
@@ -146,21 +146,11 @@ static struct platform_driver denali_dt_driver = { | |||
146 | .driver = { | 146 | .driver = { |
147 | .name = "denali-nand-dt", | 147 | .name = "denali-nand-dt", |
148 | .owner = THIS_MODULE, | 148 | .owner = THIS_MODULE, |
149 | .of_match_table = of_match_ptr(denali_nand_dt_ids), | 149 | .of_match_table = denali_nand_dt_ids, |
150 | }, | 150 | }, |
151 | }; | 151 | }; |
152 | 152 | ||
153 | static int __init denali_init_dt(void) | 153 | module_platform_driver(denali_dt_driver); |
154 | { | ||
155 | return platform_driver_register(&denali_dt_driver); | ||
156 | } | ||
157 | module_init(denali_init_dt); | ||
158 | |||
159 | static void __exit denali_exit_dt(void) | ||
160 | { | ||
161 | platform_driver_unregister(&denali_dt_driver); | ||
162 | } | ||
163 | module_exit(denali_exit_dt); | ||
164 | 154 | ||
165 | MODULE_LICENSE("GPL"); | 155 | MODULE_LICENSE("GPL"); |
166 | MODULE_AUTHOR("Jamie Iles"); | 156 | MODULE_AUTHOR("Jamie Iles"); |
diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c index 18fa4489e52e..fa25e7a08134 100644 --- a/drivers/mtd/nand/docg4.c +++ b/drivers/mtd/nand/docg4.c | |||
@@ -1397,18 +1397,7 @@ static struct platform_driver docg4_driver = { | |||
1397 | .remove = __exit_p(cleanup_docg4), | 1397 | .remove = __exit_p(cleanup_docg4), |
1398 | }; | 1398 | }; |
1399 | 1399 | ||
1400 | static int __init docg4_init(void) | 1400 | module_platform_driver_probe(docg4_driver, probe_docg4); |
1401 | { | ||
1402 | return platform_driver_probe(&docg4_driver, probe_docg4); | ||
1403 | } | ||
1404 | |||
1405 | static void __exit docg4_exit(void) | ||
1406 | { | ||
1407 | platform_driver_unregister(&docg4_driver); | ||
1408 | } | ||
1409 | |||
1410 | module_init(docg4_init); | ||
1411 | module_exit(docg4_exit); | ||
1412 | 1401 | ||
1413 | MODULE_LICENSE("GPL"); | 1402 | MODULE_LICENSE("GPL"); |
1414 | MODULE_AUTHOR("Mike Dunn"); | 1403 | MODULE_AUTHOR("Mike Dunn"); |
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 05ba3f0c2d19..911e2433fe30 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c | |||
@@ -1235,18 +1235,7 @@ static struct platform_driver fsmc_nand_driver = { | |||
1235 | }, | 1235 | }, |
1236 | }; | 1236 | }; |
1237 | 1237 | ||
1238 | static int __init fsmc_nand_init(void) | 1238 | module_platform_driver_probe(fsmc_nand_driver, fsmc_nand_probe); |
1239 | { | ||
1240 | return platform_driver_probe(&fsmc_nand_driver, | ||
1241 | fsmc_nand_probe); | ||
1242 | } | ||
1243 | module_init(fsmc_nand_init); | ||
1244 | |||
1245 | static void __exit fsmc_nand_exit(void) | ||
1246 | { | ||
1247 | platform_driver_unregister(&fsmc_nand_driver); | ||
1248 | } | ||
1249 | module_exit(fsmc_nand_exit); | ||
1250 | 1239 | ||
1251 | MODULE_LICENSE("GPL"); | 1240 | MODULE_LICENSE("GPL"); |
1252 | MODULE_AUTHOR("Vipin Kumar <vipin.kumar@st.com>, Ashish Priyadarshi"); | 1241 | MODULE_AUTHOR("Vipin Kumar <vipin.kumar@st.com>, Ashish Priyadarshi"); |
diff --git a/drivers/mtd/nand/gpio.c b/drivers/mtd/nand/gpio.c index e789e3f51710..89065dd83d64 100644 --- a/drivers/mtd/nand/gpio.c +++ b/drivers/mtd/nand/gpio.c | |||
@@ -190,7 +190,6 @@ static struct resource *gpio_nand_get_io_sync_of(struct platform_device *pdev) | |||
190 | return r; | 190 | return r; |
191 | } | 191 | } |
192 | #else /* CONFIG_OF */ | 192 | #else /* CONFIG_OF */ |
193 | #define gpio_nand_id_table NULL | ||
194 | static inline int gpio_nand_get_config_of(const struct device *dev, | 193 | static inline int gpio_nand_get_config_of(const struct device *dev, |
195 | struct gpio_nand_platdata *plat) | 194 | struct gpio_nand_platdata *plat) |
196 | { | 195 | { |
@@ -259,8 +258,6 @@ static int gpio_nand_remove(struct platform_device *dev) | |||
259 | if (gpio_is_valid(gpiomtd->plat.gpio_rdy)) | 258 | if (gpio_is_valid(gpiomtd->plat.gpio_rdy)) |
260 | gpio_free(gpiomtd->plat.gpio_rdy); | 259 | gpio_free(gpiomtd->plat.gpio_rdy); |
261 | 260 | ||
262 | kfree(gpiomtd); | ||
263 | |||
264 | return 0; | 261 | return 0; |
265 | } | 262 | } |
266 | 263 | ||
@@ -297,7 +294,7 @@ static int gpio_nand_probe(struct platform_device *dev) | |||
297 | if (!res0) | 294 | if (!res0) |
298 | return -EINVAL; | 295 | return -EINVAL; |
299 | 296 | ||
300 | gpiomtd = kzalloc(sizeof(*gpiomtd), GFP_KERNEL); | 297 | gpiomtd = devm_kzalloc(&dev->dev, sizeof(*gpiomtd), GFP_KERNEL); |
301 | if (gpiomtd == NULL) { | 298 | if (gpiomtd == NULL) { |
302 | dev_err(&dev->dev, "failed to create NAND MTD\n"); | 299 | dev_err(&dev->dev, "failed to create NAND MTD\n"); |
303 | return -ENOMEM; | 300 | return -ENOMEM; |
@@ -412,7 +409,6 @@ err_sync: | |||
412 | iounmap(gpiomtd->nand_chip.IO_ADDR_R); | 409 | iounmap(gpiomtd->nand_chip.IO_ADDR_R); |
413 | release_mem_region(res0->start, resource_size(res0)); | 410 | release_mem_region(res0->start, resource_size(res0)); |
414 | err_map: | 411 | err_map: |
415 | kfree(gpiomtd); | ||
416 | return ret; | 412 | return ret; |
417 | } | 413 | } |
418 | 414 | ||
@@ -421,7 +417,7 @@ static struct platform_driver gpio_nand_driver = { | |||
421 | .remove = gpio_nand_remove, | 417 | .remove = gpio_nand_remove, |
422 | .driver = { | 418 | .driver = { |
423 | .name = "gpio-nand", | 419 | .name = "gpio-nand", |
424 | .of_match_table = gpio_nand_id_table, | 420 | .of_match_table = of_match_ptr(gpio_nand_id_table), |
425 | }, | 421 | }, |
426 | }; | 422 | }; |
427 | 423 | ||
diff --git a/drivers/mtd/nand/h1910.c b/drivers/mtd/nand/h1910.c deleted file mode 100644 index 50166e93ba96..000000000000 --- a/drivers/mtd/nand/h1910.c +++ /dev/null | |||
@@ -1,167 +0,0 @@ | |||
1 | /* | ||
2 | * drivers/mtd/nand/h1910.c | ||
3 | * | ||
4 | * Copyright (C) 2003 Joshua Wise (joshua@joshuawise.com) | ||
5 | * | ||
6 | * Derived from drivers/mtd/nand/edb7312.c | ||
7 | * Copyright (C) 2002 Marius Gröger (mag@sysgo.de) | ||
8 | * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * Overview: | ||
15 | * This is a device driver for the NAND flash device found on the | ||
16 | * iPAQ h1910 board which utilizes the Samsung K9F2808 part. This is | ||
17 | * a 128Mibit (16MiB x 8 bits) NAND flash device. | ||
18 | */ | ||
19 | |||
20 | #include <linux/slab.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/mtd/mtd.h> | ||
24 | #include <linux/mtd/nand.h> | ||
25 | #include <linux/mtd/partitions.h> | ||
26 | #include <asm/io.h> | ||
27 | #include <mach/hardware.h> | ||
28 | #include <asm/sizes.h> | ||
29 | #include <mach/h1900-gpio.h> | ||
30 | #include <mach/ipaq.h> | ||
31 | |||
32 | /* | ||
33 | * MTD structure for EDB7312 board | ||
34 | */ | ||
35 | static struct mtd_info *h1910_nand_mtd = NULL; | ||
36 | |||
37 | /* | ||
38 | * Module stuff | ||
39 | */ | ||
40 | |||
41 | /* | ||
42 | * Define static partitions for flash device | ||
43 | */ | ||
44 | static struct mtd_partition partition_info[] = { | ||
45 | {name:"h1910 NAND Flash", | ||
46 | offset:0, | ||
47 | size:16 * 1024 * 1024} | ||
48 | }; | ||
49 | |||
50 | #define NUM_PARTITIONS 1 | ||
51 | |||
52 | /* | ||
53 | * hardware specific access to control-lines | ||
54 | * | ||
55 | * NAND_NCE: bit 0 - don't care | ||
56 | * NAND_CLE: bit 1 - address bit 2 | ||
57 | * NAND_ALE: bit 2 - address bit 3 | ||
58 | */ | ||
59 | static void h1910_hwcontrol(struct mtd_info *mtd, int cmd, | ||
60 | unsigned int ctrl) | ||
61 | { | ||
62 | struct nand_chip *chip = mtd->priv; | ||
63 | |||
64 | if (cmd != NAND_CMD_NONE) | ||
65 | writeb(cmd, chip->IO_ADDR_W | ((ctrl & 0x6) << 1)); | ||
66 | } | ||
67 | |||
68 | /* | ||
69 | * read device ready pin | ||
70 | */ | ||
71 | #if 0 | ||
72 | static int h1910_device_ready(struct mtd_info *mtd) | ||
73 | { | ||
74 | return (GPLR(55) & GPIO_bit(55)); | ||
75 | } | ||
76 | #endif | ||
77 | |||
78 | /* | ||
79 | * Main initialization routine | ||
80 | */ | ||
81 | static int __init h1910_init(void) | ||
82 | { | ||
83 | struct nand_chip *this; | ||
84 | void __iomem *nandaddr; | ||
85 | |||
86 | if (!machine_is_h1900()) | ||
87 | return -ENODEV; | ||
88 | |||
89 | nandaddr = ioremap(0x08000000, 0x1000); | ||
90 | if (!nandaddr) { | ||
91 | printk("Failed to ioremap nand flash.\n"); | ||
92 | return -ENOMEM; | ||
93 | } | ||
94 | |||
95 | /* Allocate memory for MTD device structure and private data */ | ||
96 | h1910_nand_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); | ||
97 | if (!h1910_nand_mtd) { | ||
98 | printk("Unable to allocate h1910 NAND MTD device structure.\n"); | ||
99 | iounmap((void *)nandaddr); | ||
100 | return -ENOMEM; | ||
101 | } | ||
102 | |||
103 | /* Get pointer to private data */ | ||
104 | this = (struct nand_chip *)(&h1910_nand_mtd[1]); | ||
105 | |||
106 | /* Initialize structures */ | ||
107 | memset(h1910_nand_mtd, 0, sizeof(struct mtd_info)); | ||
108 | memset(this, 0, sizeof(struct nand_chip)); | ||
109 | |||
110 | /* Link the private data with the MTD structure */ | ||
111 | h1910_nand_mtd->priv = this; | ||
112 | h1910_nand_mtd->owner = THIS_MODULE; | ||
113 | |||
114 | /* | ||
115 | * Enable VPEN | ||
116 | */ | ||
117 | GPSR(37) = GPIO_bit(37); | ||
118 | |||
119 | /* insert callbacks */ | ||
120 | this->IO_ADDR_R = nandaddr; | ||
121 | this->IO_ADDR_W = nandaddr; | ||
122 | this->cmd_ctrl = h1910_hwcontrol; | ||
123 | this->dev_ready = NULL; /* unknown whether that was correct or not so we will just do it like this */ | ||
124 | /* 15 us command delay time */ | ||
125 | this->chip_delay = 50; | ||
126 | this->ecc.mode = NAND_ECC_SOFT; | ||
127 | |||
128 | /* Scan to find existence of the device */ | ||
129 | if (nand_scan(h1910_nand_mtd, 1)) { | ||
130 | printk(KERN_NOTICE "No NAND device - returning -ENXIO\n"); | ||
131 | kfree(h1910_nand_mtd); | ||
132 | iounmap((void *)nandaddr); | ||
133 | return -ENXIO; | ||
134 | } | ||
135 | |||
136 | /* Register the partitions */ | ||
137 | mtd_device_parse_register(h1910_nand_mtd, NULL, NULL, partition_info, | ||
138 | NUM_PARTITIONS); | ||
139 | |||
140 | /* Return happy */ | ||
141 | return 0; | ||
142 | } | ||
143 | |||
144 | module_init(h1910_init); | ||
145 | |||
146 | /* | ||
147 | * Clean up routine | ||
148 | */ | ||
149 | static void __exit h1910_cleanup(void) | ||
150 | { | ||
151 | struct nand_chip *this = (struct nand_chip *)&h1910_nand_mtd[1]; | ||
152 | |||
153 | /* Release resources, unregister device */ | ||
154 | nand_release(h1910_nand_mtd); | ||
155 | |||
156 | /* Release io resource */ | ||
157 | iounmap((void *)this->IO_ADDR_W); | ||
158 | |||
159 | /* Free the MTD device structure */ | ||
160 | kfree(h1910_nand_mtd); | ||
161 | } | ||
162 | |||
163 | module_exit(h1910_cleanup); | ||
164 | |||
165 | MODULE_LICENSE("GPL"); | ||
166 | MODULE_AUTHOR("Joshua Wise <joshua at joshuawise dot com>"); | ||
167 | MODULE_DESCRIPTION("NAND flash driver for iPAQ h1910"); | ||
diff --git a/drivers/mtd/nand/lpc32xx_mlc.c b/drivers/mtd/nand/lpc32xx_mlc.c index 0ca22ae9135c..a94facb46e5c 100644 --- a/drivers/mtd/nand/lpc32xx_mlc.c +++ b/drivers/mtd/nand/lpc32xx_mlc.c | |||
@@ -540,8 +540,8 @@ static int lpc32xx_write_page_lowlevel(struct mtd_info *mtd, | |||
540 | } | 540 | } |
541 | 541 | ||
542 | static int lpc32xx_write_page(struct mtd_info *mtd, struct nand_chip *chip, | 542 | static int lpc32xx_write_page(struct mtd_info *mtd, struct nand_chip *chip, |
543 | const uint8_t *buf, int oob_required, int page, | 543 | uint32_t offset, int data_len, const uint8_t *buf, |
544 | int cached, int raw) | 544 | int oob_required, int page, int cached, int raw) |
545 | { | 545 | { |
546 | int res; | 546 | int res; |
547 | 547 | ||
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 42c63927609d..dfcd0a565c5b 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -4,7 +4,6 @@ | |||
4 | * Overview: | 4 | * Overview: |
5 | * This is the generic MTD driver for NAND flash devices. It should be | 5 | * This is the generic MTD driver for NAND flash devices. It should be |
6 | * capable of working with almost all NAND chips currently available. | 6 | * capable of working with almost all NAND chips currently available. |
7 | * Basic support for AG-AND chips is provided. | ||
8 | * | 7 | * |
9 | * Additional technical information is available on | 8 | * Additional technical information is available on |
10 | * http://www.linux-mtd.infradead.org/doc/nand.html | 9 | * http://www.linux-mtd.infradead.org/doc/nand.html |
@@ -22,8 +21,6 @@ | |||
22 | * Enable cached programming for 2k page size chips | 21 | * Enable cached programming for 2k page size chips |
23 | * Check, if mtd->ecctype should be set to MTD_ECC_HW | 22 | * Check, if mtd->ecctype should be set to MTD_ECC_HW |
24 | * if we have HW ECC support. | 23 | * if we have HW ECC support. |
25 | * The AG-AND chips have nice features for speed improvement, | ||
26 | * which are not supported yet. Read / program 4 pages in one go. | ||
27 | * BBT table is not serialized, has to be fixed | 24 | * BBT table is not serialized, has to be fixed |
28 | * | 25 | * |
29 | * This program is free software; you can redistribute it and/or modify | 26 | * This program is free software; you can redistribute it and/or modify |
@@ -515,7 +512,7 @@ EXPORT_SYMBOL_GPL(nand_wait_ready); | |||
515 | * @page_addr: the page address for this command, -1 if none | 512 | * @page_addr: the page address for this command, -1 if none |
516 | * | 513 | * |
517 | * Send command to NAND device. This function is used for small page devices | 514 | * Send command to NAND device. This function is used for small page devices |
518 | * (256/512 Bytes per page). | 515 | * (512 Bytes per page). |
519 | */ | 516 | */ |
520 | static void nand_command(struct mtd_info *mtd, unsigned int command, | 517 | static void nand_command(struct mtd_info *mtd, unsigned int command, |
521 | int column, int page_addr) | 518 | int column, int page_addr) |
@@ -631,8 +628,7 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command, | |||
631 | } | 628 | } |
632 | 629 | ||
633 | /* Command latch cycle */ | 630 | /* Command latch cycle */ |
634 | chip->cmd_ctrl(mtd, command & 0xff, | 631 | chip->cmd_ctrl(mtd, command, NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE); |
635 | NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE); | ||
636 | 632 | ||
637 | if (column != -1 || page_addr != -1) { | 633 | if (column != -1 || page_addr != -1) { |
638 | int ctrl = NAND_CTRL_CHANGE | NAND_NCE | NAND_ALE; | 634 | int ctrl = NAND_CTRL_CHANGE | NAND_NCE | NAND_ALE; |
@@ -671,16 +667,6 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command, | |||
671 | case NAND_CMD_SEQIN: | 667 | case NAND_CMD_SEQIN: |
672 | case NAND_CMD_RNDIN: | 668 | case NAND_CMD_RNDIN: |
673 | case NAND_CMD_STATUS: | 669 | case NAND_CMD_STATUS: |
674 | case NAND_CMD_DEPLETE1: | ||
675 | return; | ||
676 | |||
677 | case NAND_CMD_STATUS_ERROR: | ||
678 | case NAND_CMD_STATUS_ERROR0: | ||
679 | case NAND_CMD_STATUS_ERROR1: | ||
680 | case NAND_CMD_STATUS_ERROR2: | ||
681 | case NAND_CMD_STATUS_ERROR3: | ||
682 | /* Read error status commands require only a short delay */ | ||
683 | udelay(chip->chip_delay); | ||
684 | return; | 670 | return; |
685 | 671 | ||
686 | case NAND_CMD_RESET: | 672 | case NAND_CMD_RESET: |
@@ -836,10 +822,7 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip) | |||
836 | */ | 822 | */ |
837 | ndelay(100); | 823 | ndelay(100); |
838 | 824 | ||
839 | if ((state == FL_ERASING) && (chip->options & NAND_IS_AND)) | 825 | chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); |
840 | chip->cmdfunc(mtd, NAND_CMD_STATUS_MULTI, -1, -1); | ||
841 | else | ||
842 | chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); | ||
843 | 826 | ||
844 | if (in_interrupt() || oops_in_progress) | 827 | if (in_interrupt() || oops_in_progress) |
845 | panic_nand_wait(mtd, chip, timeo); | 828 | panic_nand_wait(mtd, chip, timeo); |
@@ -1127,7 +1110,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
1127 | } | 1110 | } |
1128 | 1111 | ||
1129 | /** | 1112 | /** |
1130 | * nand_read_subpage - [REPLACEABLE] software ECC based sub-page read function | 1113 | * nand_read_subpage - [REPLACEABLE] ECC based sub-page read function |
1131 | * @mtd: mtd info structure | 1114 | * @mtd: mtd info structure |
1132 | * @chip: nand chip info structure | 1115 | * @chip: nand chip info structure |
1133 | * @data_offs: offset of requested data within the page | 1116 | * @data_offs: offset of requested data within the page |
@@ -1995,6 +1978,67 @@ static int nand_write_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
1995 | return 0; | 1978 | return 0; |
1996 | } | 1979 | } |
1997 | 1980 | ||
1981 | |||
1982 | /** | ||
1983 | * nand_write_subpage_hwecc - [REPLACABLE] hardware ECC based subpage write | ||
1984 | * @mtd: mtd info structure | ||
1985 | * @chip: nand chip info structure | ||
1986 | * @column: column address of subpage within the page | ||
1987 | * @data_len: data length | ||
1988 | * @oob_required: must write chip->oob_poi to OOB | ||
1989 | */ | ||
1990 | static int nand_write_subpage_hwecc(struct mtd_info *mtd, | ||
1991 | struct nand_chip *chip, uint32_t offset, | ||
1992 | uint32_t data_len, const uint8_t *data_buf, | ||
1993 | int oob_required) | ||
1994 | { | ||
1995 | uint8_t *oob_buf = chip->oob_poi; | ||
1996 | uint8_t *ecc_calc = chip->buffers->ecccalc; | ||
1997 | int ecc_size = chip->ecc.size; | ||
1998 | int ecc_bytes = chip->ecc.bytes; | ||
1999 | int ecc_steps = chip->ecc.steps; | ||
2000 | uint32_t *eccpos = chip->ecc.layout->eccpos; | ||
2001 | uint32_t start_step = offset / ecc_size; | ||
2002 | uint32_t end_step = (offset + data_len - 1) / ecc_size; | ||
2003 | int oob_bytes = mtd->oobsize / ecc_steps; | ||
2004 | int step, i; | ||
2005 | |||
2006 | for (step = 0; step < ecc_steps; step++) { | ||
2007 | /* configure controller for WRITE access */ | ||
2008 | chip->ecc.hwctl(mtd, NAND_ECC_WRITE); | ||
2009 | |||
2010 | /* write data (untouched subpages already masked by 0xFF) */ | ||
2011 | chip->write_buf(mtd, data_buf, ecc_size); | ||
2012 | |||
2013 | /* mask ECC of un-touched subpages by padding 0xFF */ | ||
2014 | if ((step < start_step) || (step > end_step)) | ||
2015 | memset(ecc_calc, 0xff, ecc_bytes); | ||
2016 | else | ||
2017 | chip->ecc.calculate(mtd, data_buf, ecc_calc); | ||
2018 | |||
2019 | /* mask OOB of un-touched subpages by padding 0xFF */ | ||
2020 | /* if oob_required, preserve OOB metadata of written subpage */ | ||
2021 | if (!oob_required || (step < start_step) || (step > end_step)) | ||
2022 | memset(oob_buf, 0xff, oob_bytes); | ||
2023 | |||
2024 | data_buf += ecc_size; | ||
2025 | ecc_calc += ecc_bytes; | ||
2026 | oob_buf += oob_bytes; | ||
2027 | } | ||
2028 | |||
2029 | /* copy calculated ECC for whole page to chip->buffer->oob */ | ||
2030 | /* this include masked-value(0xFF) for unwritten subpages */ | ||
2031 | ecc_calc = chip->buffers->ecccalc; | ||
2032 | for (i = 0; i < chip->ecc.total; i++) | ||
2033 | chip->oob_poi[eccpos[i]] = ecc_calc[i]; | ||
2034 | |||
2035 | /* write OOB buffer to NAND device */ | ||
2036 | chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); | ||
2037 | |||
2038 | return 0; | ||
2039 | } | ||
2040 | |||
2041 | |||
1998 | /** | 2042 | /** |
1999 | * nand_write_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page write | 2043 | * nand_write_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page write |
2000 | * @mtd: mtd info structure | 2044 | * @mtd: mtd info structure |
@@ -2047,6 +2091,8 @@ static int nand_write_page_syndrome(struct mtd_info *mtd, | |||
2047 | * nand_write_page - [REPLACEABLE] write one page | 2091 | * nand_write_page - [REPLACEABLE] write one page |
2048 | * @mtd: MTD device structure | 2092 | * @mtd: MTD device structure |
2049 | * @chip: NAND chip descriptor | 2093 | * @chip: NAND chip descriptor |
2094 | * @offset: address offset within the page | ||
2095 | * @data_len: length of actual data to be written | ||
2050 | * @buf: the data to write | 2096 | * @buf: the data to write |
2051 | * @oob_required: must write chip->oob_poi to OOB | 2097 | * @oob_required: must write chip->oob_poi to OOB |
2052 | * @page: page number to write | 2098 | * @page: page number to write |
@@ -2054,15 +2100,25 @@ static int nand_write_page_syndrome(struct mtd_info *mtd, | |||
2054 | * @raw: use _raw version of write_page | 2100 | * @raw: use _raw version of write_page |
2055 | */ | 2101 | */ |
2056 | static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, | 2102 | static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, |
2057 | const uint8_t *buf, int oob_required, int page, | 2103 | uint32_t offset, int data_len, const uint8_t *buf, |
2058 | int cached, int raw) | 2104 | int oob_required, int page, int cached, int raw) |
2059 | { | 2105 | { |
2060 | int status; | 2106 | int status, subpage; |
2107 | |||
2108 | if (!(chip->options & NAND_NO_SUBPAGE_WRITE) && | ||
2109 | chip->ecc.write_subpage) | ||
2110 | subpage = offset || (data_len < mtd->writesize); | ||
2111 | else | ||
2112 | subpage = 0; | ||
2061 | 2113 | ||
2062 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); | 2114 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); |
2063 | 2115 | ||
2064 | if (unlikely(raw)) | 2116 | if (unlikely(raw)) |
2065 | status = chip->ecc.write_page_raw(mtd, chip, buf, oob_required); | 2117 | status = chip->ecc.write_page_raw(mtd, chip, buf, |
2118 | oob_required); | ||
2119 | else if (subpage) | ||
2120 | status = chip->ecc.write_subpage(mtd, chip, offset, data_len, | ||
2121 | buf, oob_required); | ||
2066 | else | 2122 | else |
2067 | status = chip->ecc.write_page(mtd, chip, buf, oob_required); | 2123 | status = chip->ecc.write_page(mtd, chip, buf, oob_required); |
2068 | 2124 | ||
@@ -2075,7 +2131,7 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
2075 | */ | 2131 | */ |
2076 | cached = 0; | 2132 | cached = 0; |
2077 | 2133 | ||
2078 | if (!cached || !(chip->options & NAND_CACHEPRG)) { | 2134 | if (!cached || !NAND_HAS_CACHEPROG(chip)) { |
2079 | 2135 | ||
2080 | chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); | 2136 | chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); |
2081 | status = chip->waitfunc(mtd, chip); | 2137 | status = chip->waitfunc(mtd, chip); |
@@ -2176,7 +2232,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, | |||
2176 | 2232 | ||
2177 | uint8_t *oob = ops->oobbuf; | 2233 | uint8_t *oob = ops->oobbuf; |
2178 | uint8_t *buf = ops->datbuf; | 2234 | uint8_t *buf = ops->datbuf; |
2179 | int ret, subpage; | 2235 | int ret; |
2180 | int oob_required = oob ? 1 : 0; | 2236 | int oob_required = oob ? 1 : 0; |
2181 | 2237 | ||
2182 | ops->retlen = 0; | 2238 | ops->retlen = 0; |
@@ -2191,10 +2247,6 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, | |||
2191 | } | 2247 | } |
2192 | 2248 | ||
2193 | column = to & (mtd->writesize - 1); | 2249 | column = to & (mtd->writesize - 1); |
2194 | subpage = column || (writelen & (mtd->writesize - 1)); | ||
2195 | |||
2196 | if (subpage && oob) | ||
2197 | return -EINVAL; | ||
2198 | 2250 | ||
2199 | chipnr = (int)(to >> chip->chip_shift); | 2251 | chipnr = (int)(to >> chip->chip_shift); |
2200 | chip->select_chip(mtd, chipnr); | 2252 | chip->select_chip(mtd, chipnr); |
@@ -2243,9 +2295,9 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, | |||
2243 | /* We still need to erase leftover OOB data */ | 2295 | /* We still need to erase leftover OOB data */ |
2244 | memset(chip->oob_poi, 0xff, mtd->oobsize); | 2296 | memset(chip->oob_poi, 0xff, mtd->oobsize); |
2245 | } | 2297 | } |
2246 | 2298 | ret = chip->write_page(mtd, chip, column, bytes, wbuf, | |
2247 | ret = chip->write_page(mtd, chip, wbuf, oob_required, page, | 2299 | oob_required, page, cached, |
2248 | cached, (ops->mode == MTD_OPS_RAW)); | 2300 | (ops->mode == MTD_OPS_RAW)); |
2249 | if (ret) | 2301 | if (ret) |
2250 | break; | 2302 | break; |
2251 | 2303 | ||
@@ -2481,24 +2533,6 @@ static void single_erase_cmd(struct mtd_info *mtd, int page) | |||
2481 | } | 2533 | } |
2482 | 2534 | ||
2483 | /** | 2535 | /** |
2484 | * multi_erase_cmd - [GENERIC] AND specific block erase command function | ||
2485 | * @mtd: MTD device structure | ||
2486 | * @page: the page address of the block which will be erased | ||
2487 | * | ||
2488 | * AND multi block erase command function. Erase 4 consecutive blocks. | ||
2489 | */ | ||
2490 | static void multi_erase_cmd(struct mtd_info *mtd, int page) | ||
2491 | { | ||
2492 | struct nand_chip *chip = mtd->priv; | ||
2493 | /* Send commands to erase a block */ | ||
2494 | chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++); | ||
2495 | chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++); | ||
2496 | chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page++); | ||
2497 | chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page); | ||
2498 | chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1); | ||
2499 | } | ||
2500 | |||
2501 | /** | ||
2502 | * nand_erase - [MTD Interface] erase block(s) | 2536 | * nand_erase - [MTD Interface] erase block(s) |
2503 | * @mtd: MTD device structure | 2537 | * @mtd: MTD device structure |
2504 | * @instr: erase instruction | 2538 | * @instr: erase instruction |
@@ -2510,7 +2544,6 @@ static int nand_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
2510 | return nand_erase_nand(mtd, instr, 0); | 2544 | return nand_erase_nand(mtd, instr, 0); |
2511 | } | 2545 | } |
2512 | 2546 | ||
2513 | #define BBT_PAGE_MASK 0xffffff3f | ||
2514 | /** | 2547 | /** |
2515 | * nand_erase_nand - [INTERN] erase block(s) | 2548 | * nand_erase_nand - [INTERN] erase block(s) |
2516 | * @mtd: MTD device structure | 2549 | * @mtd: MTD device structure |
@@ -2524,8 +2557,6 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, | |||
2524 | { | 2557 | { |
2525 | int page, status, pages_per_block, ret, chipnr; | 2558 | int page, status, pages_per_block, ret, chipnr; |
2526 | struct nand_chip *chip = mtd->priv; | 2559 | struct nand_chip *chip = mtd->priv; |
2527 | loff_t rewrite_bbt[NAND_MAX_CHIPS] = {0}; | ||
2528 | unsigned int bbt_masked_page = 0xffffffff; | ||
2529 | loff_t len; | 2560 | loff_t len; |
2530 | 2561 | ||
2531 | pr_debug("%s: start = 0x%012llx, len = %llu\n", | 2562 | pr_debug("%s: start = 0x%012llx, len = %llu\n", |
@@ -2556,15 +2587,6 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, | |||
2556 | goto erase_exit; | 2587 | goto erase_exit; |
2557 | } | 2588 | } |
2558 | 2589 | ||
2559 | /* | ||
2560 | * If BBT requires refresh, set the BBT page mask to see if the BBT | ||
2561 | * should be rewritten. Otherwise the mask is set to 0xffffffff which | ||
2562 | * can not be matched. This is also done when the bbt is actually | ||
2563 | * erased to avoid recursive updates. | ||
2564 | */ | ||
2565 | if (chip->options & BBT_AUTO_REFRESH && !allowbbt) | ||
2566 | bbt_masked_page = chip->bbt_td->pages[chipnr] & BBT_PAGE_MASK; | ||
2567 | |||
2568 | /* Loop through the pages */ | 2590 | /* Loop through the pages */ |
2569 | len = instr->len; | 2591 | len = instr->len; |
2570 | 2592 | ||
@@ -2610,15 +2632,6 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, | |||
2610 | goto erase_exit; | 2632 | goto erase_exit; |
2611 | } | 2633 | } |
2612 | 2634 | ||
2613 | /* | ||
2614 | * If BBT requires refresh, set the BBT rewrite flag to the | ||
2615 | * page being erased. | ||
2616 | */ | ||
2617 | if (bbt_masked_page != 0xffffffff && | ||
2618 | (page & BBT_PAGE_MASK) == bbt_masked_page) | ||
2619 | rewrite_bbt[chipnr] = | ||
2620 | ((loff_t)page << chip->page_shift); | ||
2621 | |||
2622 | /* Increment page address and decrement length */ | 2635 | /* Increment page address and decrement length */ |
2623 | len -= (1 << chip->phys_erase_shift); | 2636 | len -= (1 << chip->phys_erase_shift); |
2624 | page += pages_per_block; | 2637 | page += pages_per_block; |
@@ -2628,15 +2641,6 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, | |||
2628 | chipnr++; | 2641 | chipnr++; |
2629 | chip->select_chip(mtd, -1); | 2642 | chip->select_chip(mtd, -1); |
2630 | chip->select_chip(mtd, chipnr); | 2643 | chip->select_chip(mtd, chipnr); |
2631 | |||
2632 | /* | ||
2633 | * If BBT requires refresh and BBT-PERCHIP, set the BBT | ||
2634 | * page mask to see if this BBT should be rewritten. | ||
2635 | */ | ||
2636 | if (bbt_masked_page != 0xffffffff && | ||
2637 | (chip->bbt_td->options & NAND_BBT_PERCHIP)) | ||
2638 | bbt_masked_page = chip->bbt_td->pages[chipnr] & | ||
2639 | BBT_PAGE_MASK; | ||
2640 | } | 2644 | } |
2641 | } | 2645 | } |
2642 | instr->state = MTD_ERASE_DONE; | 2646 | instr->state = MTD_ERASE_DONE; |
@@ -2653,23 +2657,6 @@ erase_exit: | |||
2653 | if (!ret) | 2657 | if (!ret) |
2654 | mtd_erase_callback(instr); | 2658 | mtd_erase_callback(instr); |
2655 | 2659 | ||
2656 | /* | ||
2657 | * If BBT requires refresh and erase was successful, rewrite any | ||
2658 | * selected bad block tables. | ||
2659 | */ | ||
2660 | if (bbt_masked_page == 0xffffffff || ret) | ||
2661 | return ret; | ||
2662 | |||
2663 | for (chipnr = 0; chipnr < chip->numchips; chipnr++) { | ||
2664 | if (!rewrite_bbt[chipnr]) | ||
2665 | continue; | ||
2666 | /* Update the BBT for chip */ | ||
2667 | pr_debug("%s: nand_update_bbt (%d:0x%0llx 0x%0x)\n", | ||
2668 | __func__, chipnr, rewrite_bbt[chipnr], | ||
2669 | chip->bbt_td->pages[chipnr]); | ||
2670 | nand_update_bbt(mtd, rewrite_bbt[chipnr]); | ||
2671 | } | ||
2672 | |||
2673 | /* Return more or less happy */ | 2660 | /* Return more or less happy */ |
2674 | return ret; | 2661 | return ret; |
2675 | } | 2662 | } |
@@ -2905,8 +2892,6 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, | |||
2905 | chip->onfi_version = 20; | 2892 | chip->onfi_version = 20; |
2906 | else if (val & (1 << 1)) | 2893 | else if (val & (1 << 1)) |
2907 | chip->onfi_version = 10; | 2894 | chip->onfi_version = 10; |
2908 | else | ||
2909 | chip->onfi_version = 0; | ||
2910 | 2895 | ||
2911 | if (!chip->onfi_version) { | 2896 | if (!chip->onfi_version) { |
2912 | pr_info("%s: unsupported ONFI version: %d\n", __func__, val); | 2897 | pr_info("%s: unsupported ONFI version: %d\n", __func__, val); |
@@ -3171,6 +3156,30 @@ static void nand_decode_bbm_options(struct mtd_info *mtd, | |||
3171 | chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; | 3156 | chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; |
3172 | } | 3157 | } |
3173 | 3158 | ||
3159 | static inline bool is_full_id_nand(struct nand_flash_dev *type) | ||
3160 | { | ||
3161 | return type->id_len; | ||
3162 | } | ||
3163 | |||
3164 | static bool find_full_id_nand(struct mtd_info *mtd, struct nand_chip *chip, | ||
3165 | struct nand_flash_dev *type, u8 *id_data, int *busw) | ||
3166 | { | ||
3167 | if (!strncmp(type->id, id_data, type->id_len)) { | ||
3168 | mtd->writesize = type->pagesize; | ||
3169 | mtd->erasesize = type->erasesize; | ||
3170 | mtd->oobsize = type->oobsize; | ||
3171 | |||
3172 | chip->cellinfo = id_data[2]; | ||
3173 | chip->chipsize = (uint64_t)type->chipsize << 20; | ||
3174 | chip->options |= type->options; | ||
3175 | |||
3176 | *busw = type->options & NAND_BUSWIDTH_16; | ||
3177 | |||
3178 | return true; | ||
3179 | } | ||
3180 | return false; | ||
3181 | } | ||
3182 | |||
3174 | /* | 3183 | /* |
3175 | * Get the flash and manufacturer id and lookup if the type is supported. | 3184 | * Get the flash and manufacturer id and lookup if the type is supported. |
3176 | */ | 3185 | */ |
@@ -3222,9 +3231,14 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
3222 | if (!type) | 3231 | if (!type) |
3223 | type = nand_flash_ids; | 3232 | type = nand_flash_ids; |
3224 | 3233 | ||
3225 | for (; type->name != NULL; type++) | 3234 | for (; type->name != NULL; type++) { |
3226 | if (*dev_id == type->id) | 3235 | if (is_full_id_nand(type)) { |
3227 | break; | 3236 | if (find_full_id_nand(mtd, chip, type, id_data, &busw)) |
3237 | goto ident_done; | ||
3238 | } else if (*dev_id == type->dev_id) { | ||
3239 | break; | ||
3240 | } | ||
3241 | } | ||
3228 | 3242 | ||
3229 | chip->onfi_version = 0; | 3243 | chip->onfi_version = 0; |
3230 | if (!type->name || !type->pagesize) { | 3244 | if (!type->name || !type->pagesize) { |
@@ -3302,12 +3316,7 @@ ident_done: | |||
3302 | } | 3316 | } |
3303 | 3317 | ||
3304 | chip->badblockbits = 8; | 3318 | chip->badblockbits = 8; |
3305 | 3319 | chip->erase_cmd = single_erase_cmd; | |
3306 | /* Check for AND chips with 4 page planes */ | ||
3307 | if (chip->options & NAND_4PAGE_ARRAY) | ||
3308 | chip->erase_cmd = multi_erase_cmd; | ||
3309 | else | ||
3310 | chip->erase_cmd = single_erase_cmd; | ||
3311 | 3320 | ||
3312 | /* Do not replace user supplied command function! */ | 3321 | /* Do not replace user supplied command function! */ |
3313 | if (mtd->writesize > 512 && chip->cmdfunc == nand_command) | 3322 | if (mtd->writesize > 512 && chip->cmdfunc == nand_command) |
@@ -3474,6 +3483,10 @@ int nand_scan_tail(struct mtd_info *mtd) | |||
3474 | chip->ecc.read_oob = nand_read_oob_std; | 3483 | chip->ecc.read_oob = nand_read_oob_std; |
3475 | if (!chip->ecc.write_oob) | 3484 | if (!chip->ecc.write_oob) |
3476 | chip->ecc.write_oob = nand_write_oob_std; | 3485 | chip->ecc.write_oob = nand_write_oob_std; |
3486 | if (!chip->ecc.read_subpage) | ||
3487 | chip->ecc.read_subpage = nand_read_subpage; | ||
3488 | if (!chip->ecc.write_subpage) | ||
3489 | chip->ecc.write_subpage = nand_write_subpage_hwecc; | ||
3477 | 3490 | ||
3478 | case NAND_ECC_HW_SYNDROME: | 3491 | case NAND_ECC_HW_SYNDROME: |
3479 | if ((!chip->ecc.calculate || !chip->ecc.correct || | 3492 | if ((!chip->ecc.calculate || !chip->ecc.correct || |
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 916d6e9c0ab1..267264320e06 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c | |||
@@ -1240,15 +1240,6 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs) | |||
1240 | */ | 1240 | */ |
1241 | static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; | 1241 | static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; |
1242 | 1242 | ||
1243 | static uint8_t scan_agand_pattern[] = { 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7 }; | ||
1244 | |||
1245 | static struct nand_bbt_descr agand_flashbased = { | ||
1246 | .options = NAND_BBT_SCANEMPTY | NAND_BBT_SCANALLPAGES, | ||
1247 | .offs = 0x20, | ||
1248 | .len = 6, | ||
1249 | .pattern = scan_agand_pattern | ||
1250 | }; | ||
1251 | |||
1252 | /* Generic flash bbt descriptors */ | 1243 | /* Generic flash bbt descriptors */ |
1253 | static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' }; | 1244 | static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' }; |
1254 | static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' }; | 1245 | static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' }; |
@@ -1333,22 +1324,6 @@ int nand_default_bbt(struct mtd_info *mtd) | |||
1333 | { | 1324 | { |
1334 | struct nand_chip *this = mtd->priv; | 1325 | struct nand_chip *this = mtd->priv; |
1335 | 1326 | ||
1336 | /* | ||
1337 | * Default for AG-AND. We must use a flash based bad block table as the | ||
1338 | * devices have factory marked _good_ blocks. Erasing those blocks | ||
1339 | * leads to loss of the good / bad information, so we _must_ store this | ||
1340 | * information in a good / bad table during startup. | ||
1341 | */ | ||
1342 | if (this->options & NAND_IS_AND) { | ||
1343 | /* Use the default pattern descriptors */ | ||
1344 | if (!this->bbt_td) { | ||
1345 | this->bbt_td = &bbt_main_descr; | ||
1346 | this->bbt_md = &bbt_mirror_descr; | ||
1347 | } | ||
1348 | this->bbt_options |= NAND_BBT_USE_FLASH; | ||
1349 | return nand_scan_bbt(mtd, &agand_flashbased); | ||
1350 | } | ||
1351 | |||
1352 | /* Is a flash based bad block table requested? */ | 1327 | /* Is a flash based bad block table requested? */ |
1353 | if (this->bbt_options & NAND_BBT_USE_FLASH) { | 1328 | if (this->bbt_options & NAND_BBT_USE_FLASH) { |
1354 | /* Use the default pattern descriptors */ | 1329 | /* Use the default pattern descriptors */ |
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c index 9c612388e5de..683813a46a90 100644 --- a/drivers/mtd/nand/nand_ids.c +++ b/drivers/mtd/nand/nand_ids.c | |||
@@ -10,163 +10,153 @@ | |||
10 | */ | 10 | */ |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/mtd/nand.h> | 12 | #include <linux/mtd/nand.h> |
13 | /* | 13 | #include <linux/sizes.h> |
14 | * Chip ID list | 14 | |
15 | * | 15 | #define LP_OPTIONS NAND_SAMSUNG_LP_OPTIONS |
16 | * Name. ID code, pagesize, chipsize in MegaByte, eraseblock size, | 16 | #define LP_OPTIONS16 (LP_OPTIONS | NAND_BUSWIDTH_16) |
17 | * options | 17 | |
18 | * | ||
19 | * Pagesize; 0, 256, 512 | ||
20 | * 0 get this information from the extended chip ID | ||
21 | + 256 256 Byte page size | ||
22 | * 512 512 Byte page size | ||
23 | */ | ||
24 | struct nand_flash_dev nand_flash_ids[] = { | ||
25 | #define SP_OPTIONS NAND_NEED_READRDY | 18 | #define SP_OPTIONS NAND_NEED_READRDY |
26 | #define SP_OPTIONS16 (SP_OPTIONS | NAND_BUSWIDTH_16) | 19 | #define SP_OPTIONS16 (SP_OPTIONS | NAND_BUSWIDTH_16) |
27 | 20 | ||
28 | #ifdef CONFIG_MTD_NAND_MUSEUM_IDS | 21 | /* |
29 | {"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, SP_OPTIONS}, | 22 | * The chip ID list: |
30 | {"NAND 2MiB 5V 8-bit", 0x64, 256, 2, 0x1000, SP_OPTIONS}, | 23 | * name, device ID, page size, chip size in MiB, eraseblock size, options |
31 | {"NAND 4MiB 5V 8-bit", 0x6b, 512, 4, 0x2000, SP_OPTIONS}, | 24 | * |
32 | {"NAND 1MiB 3,3V 8-bit", 0xe8, 256, 1, 0x1000, SP_OPTIONS}, | 25 | * If page size and eraseblock size are 0, the sizes are taken from the |
33 | {"NAND 1MiB 3,3V 8-bit", 0xec, 256, 1, 0x1000, SP_OPTIONS}, | 26 | * extended chip ID. |
34 | {"NAND 2MiB 3,3V 8-bit", 0xea, 256, 2, 0x1000, SP_OPTIONS}, | 27 | */ |
35 | {"NAND 4MiB 3,3V 8-bit", 0xd5, 512, 4, 0x2000, SP_OPTIONS}, | 28 | struct nand_flash_dev nand_flash_ids[] = { |
36 | {"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, SP_OPTIONS}, | 29 | /* |
37 | {"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, SP_OPTIONS}, | 30 | * Some incompatible NAND chips share device ID's and so must be |
38 | {"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, SP_OPTIONS}, | 31 | * listed by full ID. We list them first so that we can easily identify |
39 | 32 | * the most specific match. | |
40 | {"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, SP_OPTIONS}, | 33 | */ |
41 | {"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, SP_OPTIONS}, | 34 | {"TC58NVG2S0F 4G 3.3V 8-bit", |
42 | {"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, SP_OPTIONS16}, | 35 | { .id = {0x98, 0xdc, 0x90, 0x26, 0x76, 0x15, 0x01, 0x08} }, |
43 | {"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, SP_OPTIONS16}, | 36 | SZ_4K, SZ_512, SZ_256K, 0, 8, 224}, |
44 | #endif | 37 | {"TC58NVG3S0F 8G 3.3V 8-bit", |
45 | 38 | { .id = {0x98, 0xd3, 0x90, 0x26, 0x76, 0x15, 0x02, 0x08} }, | |
46 | {"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, SP_OPTIONS}, | 39 | SZ_4K, SZ_1K, SZ_256K, 0, 8, 232}, |
47 | {"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, SP_OPTIONS}, | 40 | {"TC58NVG5D2 32G 3.3V 8-bit", |
48 | {"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, SP_OPTIONS16}, | 41 | { .id = {0x98, 0xd7, 0x94, 0x32, 0x76, 0x56, 0x09, 0x00} }, |
49 | {"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, SP_OPTIONS16}, | 42 | SZ_8K, SZ_4K, SZ_1M, 0, 8, 640}, |
50 | 43 | {"TC58NVG6D2 64G 3.3V 8-bit", | |
51 | {"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, SP_OPTIONS}, | 44 | { .id = {0x98, 0xde, 0x94, 0x82, 0x76, 0x56, 0x04, 0x20} }, |
52 | {"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, SP_OPTIONS}, | 45 | SZ_8K, SZ_8K, SZ_2M, 0, 8, 640}, |
53 | {"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, SP_OPTIONS16}, | 46 | |
54 | {"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, SP_OPTIONS16}, | 47 | LEGACY_ID_NAND("NAND 4MiB 5V 8-bit", 0x6B, 4, SZ_8K, SP_OPTIONS), |
55 | 48 | LEGACY_ID_NAND("NAND 4MiB 3,3V 8-bit", 0xE3, 4, SZ_8K, SP_OPTIONS), | |
56 | {"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, SP_OPTIONS}, | 49 | LEGACY_ID_NAND("NAND 4MiB 3,3V 8-bit", 0xE5, 4, SZ_8K, SP_OPTIONS), |
57 | {"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, SP_OPTIONS}, | 50 | LEGACY_ID_NAND("NAND 8MiB 3,3V 8-bit", 0xD6, 8, SZ_8K, SP_OPTIONS), |
58 | {"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, SP_OPTIONS16}, | 51 | LEGACY_ID_NAND("NAND 8MiB 3,3V 8-bit", 0xE6, 8, SZ_8K, SP_OPTIONS), |
59 | {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, SP_OPTIONS16}, | 52 | |
60 | 53 | LEGACY_ID_NAND("NAND 16MiB 1,8V 8-bit", 0x33, 16, SZ_16K, SP_OPTIONS), | |
61 | {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, SP_OPTIONS}, | 54 | LEGACY_ID_NAND("NAND 16MiB 3,3V 8-bit", 0x73, 16, SZ_16K, SP_OPTIONS), |
62 | {"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, SP_OPTIONS}, | 55 | LEGACY_ID_NAND("NAND 16MiB 1,8V 16-bit", 0x43, 16, SZ_16K, SP_OPTIONS16), |
63 | {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, SP_OPTIONS}, | 56 | LEGACY_ID_NAND("NAND 16MiB 3,3V 16-bit", 0x53, 16, SZ_16K, SP_OPTIONS16), |
64 | {"NAND 128MiB 1,8V 16-bit", 0x72, 512, 128, 0x4000, SP_OPTIONS16}, | 57 | |
65 | {"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, SP_OPTIONS16}, | 58 | LEGACY_ID_NAND("NAND 32MiB 1,8V 8-bit", 0x35, 32, SZ_16K, SP_OPTIONS), |
66 | {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, SP_OPTIONS16}, | 59 | LEGACY_ID_NAND("NAND 32MiB 3,3V 8-bit", 0x75, 32, SZ_16K, SP_OPTIONS), |
67 | {"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, SP_OPTIONS16}, | 60 | LEGACY_ID_NAND("NAND 32MiB 1,8V 16-bit", 0x45, 32, SZ_16K, SP_OPTIONS16), |
68 | 61 | LEGACY_ID_NAND("NAND 32MiB 3,3V 16-bit", 0x55, 32, SZ_16K, SP_OPTIONS16), | |
69 | {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, SP_OPTIONS}, | 62 | |
63 | LEGACY_ID_NAND("NAND 64MiB 1,8V 8-bit", 0x36, 64, SZ_16K, SP_OPTIONS), | ||
64 | LEGACY_ID_NAND("NAND 64MiB 3,3V 8-bit", 0x76, 64, SZ_16K, SP_OPTIONS), | ||
65 | LEGACY_ID_NAND("NAND 64MiB 1,8V 16-bit", 0x46, 64, SZ_16K, SP_OPTIONS16), | ||
66 | LEGACY_ID_NAND("NAND 64MiB 3,3V 16-bit", 0x56, 64, SZ_16K, SP_OPTIONS16), | ||
67 | |||
68 | LEGACY_ID_NAND("NAND 128MiB 1,8V 8-bit", 0x78, 128, SZ_16K, SP_OPTIONS), | ||
69 | LEGACY_ID_NAND("NAND 128MiB 1,8V 8-bit", 0x39, 128, SZ_16K, SP_OPTIONS), | ||
70 | LEGACY_ID_NAND("NAND 128MiB 3,3V 8-bit", 0x79, 128, SZ_16K, SP_OPTIONS), | ||
71 | LEGACY_ID_NAND("NAND 128MiB 1,8V 16-bit", 0x72, 128, SZ_16K, SP_OPTIONS16), | ||
72 | LEGACY_ID_NAND("NAND 128MiB 1,8V 16-bit", 0x49, 128, SZ_16K, SP_OPTIONS16), | ||
73 | LEGACY_ID_NAND("NAND 128MiB 3,3V 16-bit", 0x74, 128, SZ_16K, SP_OPTIONS16), | ||
74 | LEGACY_ID_NAND("NAND 128MiB 3,3V 16-bit", 0x59, 128, SZ_16K, SP_OPTIONS16), | ||
75 | |||
76 | LEGACY_ID_NAND("NAND 256MiB 3,3V 8-bit", 0x71, 256, SZ_16K, SP_OPTIONS), | ||
70 | 77 | ||
71 | /* | 78 | /* |
72 | * These are the new chips with large page size. The pagesize and the | 79 | * These are the new chips with large page size. Their page size and |
73 | * erasesize is determined from the extended id bytes | 80 | * eraseblock size are determined from the extended ID bytes. |
74 | */ | 81 | */ |
75 | #define LP_OPTIONS NAND_SAMSUNG_LP_OPTIONS | ||
76 | #define LP_OPTIONS16 (LP_OPTIONS | NAND_BUSWIDTH_16) | ||
77 | 82 | ||
78 | /* 512 Megabit */ | 83 | /* 512 Megabit */ |
79 | {"NAND 64MiB 1,8V 8-bit", 0xA2, 0, 64, 0, LP_OPTIONS}, | 84 | EXTENDED_ID_NAND("NAND 64MiB 1,8V 8-bit", 0xA2, 64, LP_OPTIONS), |
80 | {"NAND 64MiB 1,8V 8-bit", 0xA0, 0, 64, 0, LP_OPTIONS}, | 85 | EXTENDED_ID_NAND("NAND 64MiB 1,8V 8-bit", 0xA0, 64, LP_OPTIONS), |
81 | {"NAND 64MiB 3,3V 8-bit", 0xF2, 0, 64, 0, LP_OPTIONS}, | 86 | EXTENDED_ID_NAND("NAND 64MiB 3,3V 8-bit", 0xF2, 64, LP_OPTIONS), |
82 | {"NAND 64MiB 3,3V 8-bit", 0xD0, 0, 64, 0, LP_OPTIONS}, | 87 | EXTENDED_ID_NAND("NAND 64MiB 3,3V 8-bit", 0xD0, 64, LP_OPTIONS), |
83 | {"NAND 64MiB 3,3V 8-bit", 0xF0, 0, 64, 0, LP_OPTIONS}, | 88 | EXTENDED_ID_NAND("NAND 64MiB 3,3V 8-bit", 0xF0, 64, LP_OPTIONS), |
84 | {"NAND 64MiB 1,8V 16-bit", 0xB2, 0, 64, 0, LP_OPTIONS16}, | 89 | EXTENDED_ID_NAND("NAND 64MiB 1,8V 16-bit", 0xB2, 64, LP_OPTIONS16), |
85 | {"NAND 64MiB 1,8V 16-bit", 0xB0, 0, 64, 0, LP_OPTIONS16}, | 90 | EXTENDED_ID_NAND("NAND 64MiB 1,8V 16-bit", 0xB0, 64, LP_OPTIONS16), |
86 | {"NAND 64MiB 3,3V 16-bit", 0xC2, 0, 64, 0, LP_OPTIONS16}, | 91 | EXTENDED_ID_NAND("NAND 64MiB 3,3V 16-bit", 0xC2, 64, LP_OPTIONS16), |
87 | {"NAND 64MiB 3,3V 16-bit", 0xC0, 0, 64, 0, LP_OPTIONS16}, | 92 | EXTENDED_ID_NAND("NAND 64MiB 3,3V 16-bit", 0xC0, 64, LP_OPTIONS16), |
88 | 93 | ||
89 | /* 1 Gigabit */ | 94 | /* 1 Gigabit */ |
90 | {"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, LP_OPTIONS}, | 95 | EXTENDED_ID_NAND("NAND 128MiB 1,8V 8-bit", 0xA1, 128, LP_OPTIONS), |
91 | {"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, LP_OPTIONS}, | 96 | EXTENDED_ID_NAND("NAND 128MiB 3,3V 8-bit", 0xF1, 128, LP_OPTIONS), |
92 | {"NAND 128MiB 3,3V 8-bit", 0xD1, 0, 128, 0, LP_OPTIONS}, | 97 | EXTENDED_ID_NAND("NAND 128MiB 3,3V 8-bit", 0xD1, 128, LP_OPTIONS), |
93 | {"NAND 128MiB 1,8V 16-bit", 0xB1, 0, 128, 0, LP_OPTIONS16}, | 98 | EXTENDED_ID_NAND("NAND 128MiB 1,8V 16-bit", 0xB1, 128, LP_OPTIONS16), |
94 | {"NAND 128MiB 3,3V 16-bit", 0xC1, 0, 128, 0, LP_OPTIONS16}, | 99 | EXTENDED_ID_NAND("NAND 128MiB 3,3V 16-bit", 0xC1, 128, LP_OPTIONS16), |
95 | {"NAND 128MiB 1,8V 16-bit", 0xAD, 0, 128, 0, LP_OPTIONS16}, | 100 | EXTENDED_ID_NAND("NAND 128MiB 1,8V 16-bit", 0xAD, 128, LP_OPTIONS16), |
96 | 101 | ||
97 | /* 2 Gigabit */ | 102 | /* 2 Gigabit */ |
98 | {"NAND 256MiB 1,8V 8-bit", 0xAA, 0, 256, 0, LP_OPTIONS}, | 103 | EXTENDED_ID_NAND("NAND 256MiB 1,8V 8-bit", 0xAA, 256, LP_OPTIONS), |
99 | {"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, LP_OPTIONS}, | 104 | EXTENDED_ID_NAND("NAND 256MiB 3,3V 8-bit", 0xDA, 256, LP_OPTIONS), |
100 | {"NAND 256MiB 1,8V 16-bit", 0xBA, 0, 256, 0, LP_OPTIONS16}, | 105 | EXTENDED_ID_NAND("NAND 256MiB 1,8V 16-bit", 0xBA, 256, LP_OPTIONS16), |
101 | {"NAND 256MiB 3,3V 16-bit", 0xCA, 0, 256, 0, LP_OPTIONS16}, | 106 | EXTENDED_ID_NAND("NAND 256MiB 3,3V 16-bit", 0xCA, 256, LP_OPTIONS16), |
102 | 107 | ||
103 | /* 4 Gigabit */ | 108 | /* 4 Gigabit */ |
104 | {"NAND 512MiB 1,8V 8-bit", 0xAC, 0, 512, 0, LP_OPTIONS}, | 109 | EXTENDED_ID_NAND("NAND 512MiB 1,8V 8-bit", 0xAC, 512, LP_OPTIONS), |
105 | {"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0, LP_OPTIONS}, | 110 | EXTENDED_ID_NAND("NAND 512MiB 3,3V 8-bit", 0xDC, 512, LP_OPTIONS), |
106 | {"NAND 512MiB 1,8V 16-bit", 0xBC, 0, 512, 0, LP_OPTIONS16}, | 111 | EXTENDED_ID_NAND("NAND 512MiB 1,8V 16-bit", 0xBC, 512, LP_OPTIONS16), |
107 | {"NAND 512MiB 3,3V 16-bit", 0xCC, 0, 512, 0, LP_OPTIONS16}, | 112 | EXTENDED_ID_NAND("NAND 512MiB 3,3V 16-bit", 0xCC, 512, LP_OPTIONS16), |
108 | 113 | ||
109 | /* 8 Gigabit */ | 114 | /* 8 Gigabit */ |
110 | {"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, LP_OPTIONS}, | 115 | EXTENDED_ID_NAND("NAND 1GiB 1,8V 8-bit", 0xA3, 1024, LP_OPTIONS), |
111 | {"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, LP_OPTIONS}, | 116 | EXTENDED_ID_NAND("NAND 1GiB 3,3V 8-bit", 0xD3, 1024, LP_OPTIONS), |
112 | {"NAND 1GiB 1,8V 16-bit", 0xB3, 0, 1024, 0, LP_OPTIONS16}, | 117 | EXTENDED_ID_NAND("NAND 1GiB 1,8V 16-bit", 0xB3, 1024, LP_OPTIONS16), |
113 | {"NAND 1GiB 3,3V 16-bit", 0xC3, 0, 1024, 0, LP_OPTIONS16}, | 118 | EXTENDED_ID_NAND("NAND 1GiB 3,3V 16-bit", 0xC3, 1024, LP_OPTIONS16), |
114 | 119 | ||
115 | /* 16 Gigabit */ | 120 | /* 16 Gigabit */ |
116 | {"NAND 2GiB 1,8V 8-bit", 0xA5, 0, 2048, 0, LP_OPTIONS}, | 121 | EXTENDED_ID_NAND("NAND 2GiB 1,8V 8-bit", 0xA5, 2048, LP_OPTIONS), |
117 | {"NAND 2GiB 3,3V 8-bit", 0xD5, 0, 2048, 0, LP_OPTIONS}, | 122 | EXTENDED_ID_NAND("NAND 2GiB 3,3V 8-bit", 0xD5, 2048, LP_OPTIONS), |
118 | {"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, LP_OPTIONS16}, | 123 | EXTENDED_ID_NAND("NAND 2GiB 1,8V 16-bit", 0xB5, 2048, LP_OPTIONS16), |
119 | {"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, LP_OPTIONS16}, | 124 | EXTENDED_ID_NAND("NAND 2GiB 3,3V 16-bit", 0xC5, 2048, LP_OPTIONS16), |
120 | 125 | ||
121 | /* 32 Gigabit */ | 126 | /* 32 Gigabit */ |
122 | {"NAND 4GiB 1,8V 8-bit", 0xA7, 0, 4096, 0, LP_OPTIONS}, | 127 | EXTENDED_ID_NAND("NAND 4GiB 1,8V 8-bit", 0xA7, 4096, LP_OPTIONS), |
123 | {"NAND 4GiB 3,3V 8-bit", 0xD7, 0, 4096, 0, LP_OPTIONS}, | 128 | EXTENDED_ID_NAND("NAND 4GiB 3,3V 8-bit", 0xD7, 4096, LP_OPTIONS), |
124 | {"NAND 4GiB 1,8V 16-bit", 0xB7, 0, 4096, 0, LP_OPTIONS16}, | 129 | EXTENDED_ID_NAND("NAND 4GiB 1,8V 16-bit", 0xB7, 4096, LP_OPTIONS16), |
125 | {"NAND 4GiB 3,3V 16-bit", 0xC7, 0, 4096, 0, LP_OPTIONS16}, | 130 | EXTENDED_ID_NAND("NAND 4GiB 3,3V 16-bit", 0xC7, 4096, LP_OPTIONS16), |
126 | 131 | ||
127 | /* 64 Gigabit */ | 132 | /* 64 Gigabit */ |
128 | {"NAND 8GiB 1,8V 8-bit", 0xAE, 0, 8192, 0, LP_OPTIONS}, | 133 | EXTENDED_ID_NAND("NAND 8GiB 1,8V 8-bit", 0xAE, 8192, LP_OPTIONS), |
129 | {"NAND 8GiB 3,3V 8-bit", 0xDE, 0, 8192, 0, LP_OPTIONS}, | 134 | EXTENDED_ID_NAND("NAND 8GiB 3,3V 8-bit", 0xDE, 8192, LP_OPTIONS), |
130 | {"NAND 8GiB 1,8V 16-bit", 0xBE, 0, 8192, 0, LP_OPTIONS16}, | 135 | EXTENDED_ID_NAND("NAND 8GiB 1,8V 16-bit", 0xBE, 8192, LP_OPTIONS16), |
131 | {"NAND 8GiB 3,3V 16-bit", 0xCE, 0, 8192, 0, LP_OPTIONS16}, | 136 | EXTENDED_ID_NAND("NAND 8GiB 3,3V 16-bit", 0xCE, 8192, LP_OPTIONS16), |
132 | 137 | ||
133 | /* 128 Gigabit */ | 138 | /* 128 Gigabit */ |
134 | {"NAND 16GiB 1,8V 8-bit", 0x1A, 0, 16384, 0, LP_OPTIONS}, | 139 | EXTENDED_ID_NAND("NAND 16GiB 1,8V 8-bit", 0x1A, 16384, LP_OPTIONS), |
135 | {"NAND 16GiB 3,3V 8-bit", 0x3A, 0, 16384, 0, LP_OPTIONS}, | 140 | EXTENDED_ID_NAND("NAND 16GiB 3,3V 8-bit", 0x3A, 16384, LP_OPTIONS), |
136 | {"NAND 16GiB 1,8V 16-bit", 0x2A, 0, 16384, 0, LP_OPTIONS16}, | 141 | EXTENDED_ID_NAND("NAND 16GiB 1,8V 16-bit", 0x2A, 16384, LP_OPTIONS16), |
137 | {"NAND 16GiB 3,3V 16-bit", 0x4A, 0, 16384, 0, LP_OPTIONS16}, | 142 | EXTENDED_ID_NAND("NAND 16GiB 3,3V 16-bit", 0x4A, 16384, LP_OPTIONS16), |
138 | 143 | ||
139 | /* 256 Gigabit */ | 144 | /* 256 Gigabit */ |
140 | {"NAND 32GiB 1,8V 8-bit", 0x1C, 0, 32768, 0, LP_OPTIONS}, | 145 | EXTENDED_ID_NAND("NAND 32GiB 1,8V 8-bit", 0x1C, 32768, LP_OPTIONS), |
141 | {"NAND 32GiB 3,3V 8-bit", 0x3C, 0, 32768, 0, LP_OPTIONS}, | 146 | EXTENDED_ID_NAND("NAND 32GiB 3,3V 8-bit", 0x3C, 32768, LP_OPTIONS), |
142 | {"NAND 32GiB 1,8V 16-bit", 0x2C, 0, 32768, 0, LP_OPTIONS16}, | 147 | EXTENDED_ID_NAND("NAND 32GiB 1,8V 16-bit", 0x2C, 32768, LP_OPTIONS16), |
143 | {"NAND 32GiB 3,3V 16-bit", 0x4C, 0, 32768, 0, LP_OPTIONS16}, | 148 | EXTENDED_ID_NAND("NAND 32GiB 3,3V 16-bit", 0x4C, 32768, LP_OPTIONS16), |
144 | 149 | ||
145 | /* 512 Gigabit */ | 150 | /* 512 Gigabit */ |
146 | {"NAND 64GiB 1,8V 8-bit", 0x1E, 0, 65536, 0, LP_OPTIONS}, | 151 | EXTENDED_ID_NAND("NAND 64GiB 1,8V 8-bit", 0x1E, 65536, LP_OPTIONS), |
147 | {"NAND 64GiB 3,3V 8-bit", 0x3E, 0, 65536, 0, LP_OPTIONS}, | 152 | EXTENDED_ID_NAND("NAND 64GiB 3,3V 8-bit", 0x3E, 65536, LP_OPTIONS), |
148 | {"NAND 64GiB 1,8V 16-bit", 0x2E, 0, 65536, 0, LP_OPTIONS16}, | 153 | EXTENDED_ID_NAND("NAND 64GiB 1,8V 16-bit", 0x2E, 65536, LP_OPTIONS16), |
149 | {"NAND 64GiB 3,3V 16-bit", 0x4E, 0, 65536, 0, LP_OPTIONS16}, | 154 | EXTENDED_ID_NAND("NAND 64GiB 3,3V 16-bit", 0x4E, 65536, LP_OPTIONS16), |
150 | 155 | ||
151 | /* | 156 | {NULL} |
152 | * Renesas AND 1 Gigabit. Those chips do not support extended id and | ||
153 | * have a strange page/block layout ! The chosen minimum erasesize is | ||
154 | * 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page | ||
155 | * planes 1 block = 2 pages, but due to plane arrangement the blocks | ||
156 | * 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7 Anyway JFFS2 would | ||
157 | * increase the eraseblock size so we chose a combined one which can be | ||
158 | * erased in one go There are more speed improvements for reads and | ||
159 | * writes possible, but not implemented now | ||
160 | */ | ||
161 | {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, | ||
162 | NAND_IS_AND | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH}, | ||
163 | |||
164 | {NULL,} | ||
165 | }; | 157 | }; |
166 | 158 | ||
167 | /* | 159 | /* Manufacturer IDs */ |
168 | * Manufacturer ID list | ||
169 | */ | ||
170 | struct nand_manufacturers nand_manuf_ids[] = { | 160 | struct nand_manufacturers nand_manuf_ids[] = { |
171 | {NAND_MFR_TOSHIBA, "Toshiba"}, | 161 | {NAND_MFR_TOSHIBA, "Toshiba"}, |
172 | {NAND_MFR_SAMSUNG, "Samsung"}, | 162 | {NAND_MFR_SAMSUNG, "Samsung"}, |
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index 891c52a30e6a..cb38f3d94218 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c | |||
@@ -218,7 +218,6 @@ MODULE_PARM_DESC(bch, "Enable BCH ecc and set how many bits should " | |||
218 | #define STATE_CMD_READOOB 0x00000005 /* read OOB area */ | 218 | #define STATE_CMD_READOOB 0x00000005 /* read OOB area */ |
219 | #define STATE_CMD_ERASE1 0x00000006 /* sector erase first command */ | 219 | #define STATE_CMD_ERASE1 0x00000006 /* sector erase first command */ |
220 | #define STATE_CMD_STATUS 0x00000007 /* read status */ | 220 | #define STATE_CMD_STATUS 0x00000007 /* read status */ |
221 | #define STATE_CMD_STATUS_M 0x00000008 /* read multi-plane status (isn't implemented) */ | ||
222 | #define STATE_CMD_SEQIN 0x00000009 /* sequential data input */ | 221 | #define STATE_CMD_SEQIN 0x00000009 /* sequential data input */ |
223 | #define STATE_CMD_READID 0x0000000A /* read ID */ | 222 | #define STATE_CMD_READID 0x0000000A /* read ID */ |
224 | #define STATE_CMD_ERASE2 0x0000000B /* sector erase second command */ | 223 | #define STATE_CMD_ERASE2 0x0000000B /* sector erase second command */ |
@@ -263,14 +262,13 @@ MODULE_PARM_DESC(bch, "Enable BCH ecc and set how many bits should " | |||
263 | #define NS_OPER_STATES 6 /* Maximum number of states in operation */ | 262 | #define NS_OPER_STATES 6 /* Maximum number of states in operation */ |
264 | 263 | ||
265 | #define OPT_ANY 0xFFFFFFFF /* any chip supports this operation */ | 264 | #define OPT_ANY 0xFFFFFFFF /* any chip supports this operation */ |
266 | #define OPT_PAGE256 0x00000001 /* 256-byte page chips */ | ||
267 | #define OPT_PAGE512 0x00000002 /* 512-byte page chips */ | 265 | #define OPT_PAGE512 0x00000002 /* 512-byte page chips */ |
268 | #define OPT_PAGE2048 0x00000008 /* 2048-byte page chips */ | 266 | #define OPT_PAGE2048 0x00000008 /* 2048-byte page chips */ |
269 | #define OPT_SMARTMEDIA 0x00000010 /* SmartMedia technology chips */ | 267 | #define OPT_SMARTMEDIA 0x00000010 /* SmartMedia technology chips */ |
270 | #define OPT_PAGE512_8BIT 0x00000040 /* 512-byte page chips with 8-bit bus width */ | 268 | #define OPT_PAGE512_8BIT 0x00000040 /* 512-byte page chips with 8-bit bus width */ |
271 | #define OPT_PAGE4096 0x00000080 /* 4096-byte page chips */ | 269 | #define OPT_PAGE4096 0x00000080 /* 4096-byte page chips */ |
272 | #define OPT_LARGEPAGE (OPT_PAGE2048 | OPT_PAGE4096) /* 2048 & 4096-byte page chips */ | 270 | #define OPT_LARGEPAGE (OPT_PAGE2048 | OPT_PAGE4096) /* 2048 & 4096-byte page chips */ |
273 | #define OPT_SMALLPAGE (OPT_PAGE256 | OPT_PAGE512) /* 256 and 512-byte page chips */ | 271 | #define OPT_SMALLPAGE (OPT_PAGE512) /* 512-byte page chips */ |
274 | 272 | ||
275 | /* Remove action bits from state */ | 273 | /* Remove action bits from state */ |
276 | #define NS_STATE(x) ((x) & ~ACTION_MASK) | 274 | #define NS_STATE(x) ((x) & ~ACTION_MASK) |
@@ -406,8 +404,6 @@ static struct nandsim_operations { | |||
406 | {OPT_ANY, {STATE_CMD_ERASE1, STATE_ADDR_SEC, STATE_CMD_ERASE2 | ACTION_SECERASE, STATE_READY}}, | 404 | {OPT_ANY, {STATE_CMD_ERASE1, STATE_ADDR_SEC, STATE_CMD_ERASE2 | ACTION_SECERASE, STATE_READY}}, |
407 | /* Read status */ | 405 | /* Read status */ |
408 | {OPT_ANY, {STATE_CMD_STATUS, STATE_DATAOUT_STATUS, STATE_READY}}, | 406 | {OPT_ANY, {STATE_CMD_STATUS, STATE_DATAOUT_STATUS, STATE_READY}}, |
409 | /* Read multi-plane status */ | ||
410 | {OPT_SMARTMEDIA, {STATE_CMD_STATUS_M, STATE_DATAOUT_STATUS_M, STATE_READY}}, | ||
411 | /* Read ID */ | 407 | /* Read ID */ |
412 | {OPT_ANY, {STATE_CMD_READID, STATE_ADDR_ZERO, STATE_DATAOUT_ID, STATE_READY}}, | 408 | {OPT_ANY, {STATE_CMD_READID, STATE_ADDR_ZERO, STATE_DATAOUT_ID, STATE_READY}}, |
413 | /* Large page devices read page */ | 409 | /* Large page devices read page */ |
@@ -699,10 +695,7 @@ static int init_nandsim(struct mtd_info *mtd) | |||
699 | ns->geom.secszoob = ns->geom.secsz + ns->geom.oobsz * ns->geom.pgsec; | 695 | ns->geom.secszoob = ns->geom.secsz + ns->geom.oobsz * ns->geom.pgsec; |
700 | ns->options = 0; | 696 | ns->options = 0; |
701 | 697 | ||
702 | if (ns->geom.pgsz == 256) { | 698 | if (ns->geom.pgsz == 512) { |
703 | ns->options |= OPT_PAGE256; | ||
704 | } | ||
705 | else if (ns->geom.pgsz == 512) { | ||
706 | ns->options |= OPT_PAGE512; | 699 | ns->options |= OPT_PAGE512; |
707 | if (ns->busw == 8) | 700 | if (ns->busw == 8) |
708 | ns->options |= OPT_PAGE512_8BIT; | 701 | ns->options |= OPT_PAGE512_8BIT; |
@@ -769,9 +762,9 @@ static int init_nandsim(struct mtd_info *mtd) | |||
769 | } | 762 | } |
770 | 763 | ||
771 | /* Detect how many ID bytes the NAND chip outputs */ | 764 | /* Detect how many ID bytes the NAND chip outputs */ |
772 | for (i = 0; nand_flash_ids[i].name != NULL; i++) { | 765 | for (i = 0; nand_flash_ids[i].name != NULL; i++) { |
773 | if (second_id_byte != nand_flash_ids[i].id) | 766 | if (second_id_byte != nand_flash_ids[i].dev_id) |
774 | continue; | 767 | continue; |
775 | } | 768 | } |
776 | 769 | ||
777 | if (ns->busw == 16) | 770 | if (ns->busw == 16) |
@@ -1079,8 +1072,6 @@ static char *get_state_name(uint32_t state) | |||
1079 | return "STATE_CMD_ERASE1"; | 1072 | return "STATE_CMD_ERASE1"; |
1080 | case STATE_CMD_STATUS: | 1073 | case STATE_CMD_STATUS: |
1081 | return "STATE_CMD_STATUS"; | 1074 | return "STATE_CMD_STATUS"; |
1082 | case STATE_CMD_STATUS_M: | ||
1083 | return "STATE_CMD_STATUS_M"; | ||
1084 | case STATE_CMD_SEQIN: | 1075 | case STATE_CMD_SEQIN: |
1085 | return "STATE_CMD_SEQIN"; | 1076 | return "STATE_CMD_SEQIN"; |
1086 | case STATE_CMD_READID: | 1077 | case STATE_CMD_READID: |
@@ -1145,7 +1136,6 @@ static int check_command(int cmd) | |||
1145 | case NAND_CMD_RNDOUTSTART: | 1136 | case NAND_CMD_RNDOUTSTART: |
1146 | return 0; | 1137 | return 0; |
1147 | 1138 | ||
1148 | case NAND_CMD_STATUS_MULTI: | ||
1149 | default: | 1139 | default: |
1150 | return 1; | 1140 | return 1; |
1151 | } | 1141 | } |
@@ -1171,8 +1161,6 @@ static uint32_t get_state_by_command(unsigned command) | |||
1171 | return STATE_CMD_ERASE1; | 1161 | return STATE_CMD_ERASE1; |
1172 | case NAND_CMD_STATUS: | 1162 | case NAND_CMD_STATUS: |
1173 | return STATE_CMD_STATUS; | 1163 | return STATE_CMD_STATUS; |
1174 | case NAND_CMD_STATUS_MULTI: | ||
1175 | return STATE_CMD_STATUS_M; | ||
1176 | case NAND_CMD_SEQIN: | 1164 | case NAND_CMD_SEQIN: |
1177 | return STATE_CMD_SEQIN; | 1165 | return STATE_CMD_SEQIN; |
1178 | case NAND_CMD_READID: | 1166 | case NAND_CMD_READID: |
@@ -2306,7 +2294,7 @@ static int __init ns_init_module(void) | |||
2306 | nand->geom.idbytes = 2; | 2294 | nand->geom.idbytes = 2; |
2307 | nand->regs.status = NS_STATUS_OK(nand); | 2295 | nand->regs.status = NS_STATUS_OK(nand); |
2308 | nand->nxstate = STATE_UNKNOWN; | 2296 | nand->nxstate = STATE_UNKNOWN; |
2309 | nand->options |= OPT_PAGE256; /* temporary value */ | 2297 | nand->options |= OPT_PAGE512; /* temporary value */ |
2310 | nand->ids[0] = first_id_byte; | 2298 | nand->ids[0] = first_id_byte; |
2311 | nand->ids[1] = second_id_byte; | 2299 | nand->ids[1] = second_id_byte; |
2312 | nand->ids[2] = third_id_byte; | 2300 | nand->ids[2] = third_id_byte; |
diff --git a/drivers/mtd/nand/nuc900_nand.c b/drivers/mtd/nand/nuc900_nand.c index a6191198d259..cd6be2ed53a8 100644 --- a/drivers/mtd/nand/nuc900_nand.c +++ b/drivers/mtd/nand/nuc900_nand.c | |||
@@ -177,15 +177,6 @@ static void nuc900_nand_command_lp(struct mtd_info *mtd, unsigned int command, | |||
177 | case NAND_CMD_SEQIN: | 177 | case NAND_CMD_SEQIN: |
178 | case NAND_CMD_RNDIN: | 178 | case NAND_CMD_RNDIN: |
179 | case NAND_CMD_STATUS: | 179 | case NAND_CMD_STATUS: |
180 | case NAND_CMD_DEPLETE1: | ||
181 | return; | ||
182 | |||
183 | case NAND_CMD_STATUS_ERROR: | ||
184 | case NAND_CMD_STATUS_ERROR0: | ||
185 | case NAND_CMD_STATUS_ERROR1: | ||
186 | case NAND_CMD_STATUS_ERROR2: | ||
187 | case NAND_CMD_STATUS_ERROR3: | ||
188 | udelay(chip->chip_delay); | ||
189 | return; | 180 | return; |
190 | 181 | ||
191 | case NAND_CMD_RESET: | 182 | case NAND_CMD_RESET: |
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 8e820ddf4e08..81b80af55872 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
@@ -1023,9 +1023,9 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip) | |||
1023 | int status, state = this->state; | 1023 | int status, state = this->state; |
1024 | 1024 | ||
1025 | if (state == FL_ERASING) | 1025 | if (state == FL_ERASING) |
1026 | timeo += (HZ * 400) / 1000; | 1026 | timeo += msecs_to_jiffies(400); |
1027 | else | 1027 | else |
1028 | timeo += (HZ * 20) / 1000; | 1028 | timeo += msecs_to_jiffies(20); |
1029 | 1029 | ||
1030 | writeb(NAND_CMD_STATUS & 0xFF, info->reg.gpmc_nand_command); | 1030 | writeb(NAND_CMD_STATUS & 0xFF, info->reg.gpmc_nand_command); |
1031 | while (time_before(jiffies, timeo)) { | 1031 | while (time_before(jiffies, timeo)) { |
@@ -1701,8 +1701,9 @@ static int omap3_init_bch(struct mtd_info *mtd, int ecc_opt) | |||
1701 | elm_node = of_find_node_by_phandle(be32_to_cpup(parp)); | 1701 | elm_node = of_find_node_by_phandle(be32_to_cpup(parp)); |
1702 | pdev = of_find_device_by_node(elm_node); | 1702 | pdev = of_find_device_by_node(elm_node); |
1703 | info->elm_dev = &pdev->dev; | 1703 | info->elm_dev = &pdev->dev; |
1704 | elm_config(info->elm_dev, bch_type); | 1704 | |
1705 | info->is_elm_used = true; | 1705 | if (elm_config(info->elm_dev, bch_type) == 0) |
1706 | info->is_elm_used = true; | ||
1706 | } | 1707 | } |
1707 | 1708 | ||
1708 | if (info->is_elm_used && (mtd->writesize <= 4096)) { | 1709 | if (info->is_elm_used && (mtd->writesize <= 4096)) { |
diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index cd72b9299f6b..8fbd00208610 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c | |||
@@ -231,18 +231,7 @@ static struct platform_driver orion_nand_driver = { | |||
231 | }, | 231 | }, |
232 | }; | 232 | }; |
233 | 233 | ||
234 | static int __init orion_nand_init(void) | 234 | module_platform_driver_probe(orion_nand_driver, orion_nand_probe); |
235 | { | ||
236 | return platform_driver_probe(&orion_nand_driver, orion_nand_probe); | ||
237 | } | ||
238 | |||
239 | static void __exit orion_nand_exit(void) | ||
240 | { | ||
241 | platform_driver_unregister(&orion_nand_driver); | ||
242 | } | ||
243 | |||
244 | module_init(orion_nand_init); | ||
245 | module_exit(orion_nand_exit); | ||
246 | 235 | ||
247 | MODULE_LICENSE("GPL"); | 236 | MODULE_LICENSE("GPL"); |
248 | MODULE_AUTHOR("Tzachi Perelstein"); | 237 | MODULE_AUTHOR("Tzachi Perelstein"); |
diff --git a/drivers/mtd/nand/ppchameleonevb.c b/drivers/mtd/nand/ppchameleonevb.c deleted file mode 100644 index 0ddd90e5788f..000000000000 --- a/drivers/mtd/nand/ppchameleonevb.c +++ /dev/null | |||
@@ -1,403 +0,0 @@ | |||
1 | /* | ||
2 | * drivers/mtd/nand/ppchameleonevb.c | ||
3 | * | ||
4 | * Copyright (C) 2003 DAVE Srl (info@wawnet.biz) | ||
5 | * | ||
6 | * Derived from drivers/mtd/nand/edb7312.c | ||
7 | * | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | * Overview: | ||
14 | * This is a device driver for the NAND flash devices found on the | ||
15 | * PPChameleon/PPChameleonEVB system. | ||
16 | * PPChameleon options (autodetected): | ||
17 | * - BA model: no NAND | ||
18 | * - ME model: 32MB (Samsung K9F5608U0B) | ||
19 | * - HI model: 128MB (Samsung K9F1G08UOM) | ||
20 | * PPChameleonEVB options: | ||
21 | * - 32MB (Samsung K9F5608U0B) | ||
22 | */ | ||
23 | |||
24 | #include <linux/init.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/mtd/mtd.h> | ||
28 | #include <linux/mtd/nand.h> | ||
29 | #include <linux/mtd/partitions.h> | ||
30 | #include <asm/io.h> | ||
31 | #include <platforms/PPChameleonEVB.h> | ||
32 | |||
33 | #undef USE_READY_BUSY_PIN | ||
34 | #define USE_READY_BUSY_PIN | ||
35 | /* see datasheets (tR) */ | ||
36 | #define NAND_BIG_DELAY_US 25 | ||
37 | #define NAND_SMALL_DELAY_US 10 | ||
38 | |||
39 | /* handy sizes */ | ||
40 | #define SZ_4M 0x00400000 | ||
41 | #define NAND_SMALL_SIZE 0x02000000 | ||
42 | #define NAND_MTD_NAME "ppchameleon-nand" | ||
43 | #define NAND_EVB_MTD_NAME "ppchameleonevb-nand" | ||
44 | |||
45 | /* GPIO pins used to drive NAND chip mounted on processor module */ | ||
46 | #define NAND_nCE_GPIO_PIN (0x80000000 >> 1) | ||
47 | #define NAND_CLE_GPIO_PIN (0x80000000 >> 2) | ||
48 | #define NAND_ALE_GPIO_PIN (0x80000000 >> 3) | ||
49 | #define NAND_RB_GPIO_PIN (0x80000000 >> 4) | ||
50 | /* GPIO pins used to drive NAND chip mounted on EVB */ | ||
51 | #define NAND_EVB_nCE_GPIO_PIN (0x80000000 >> 14) | ||
52 | #define NAND_EVB_CLE_GPIO_PIN (0x80000000 >> 15) | ||
53 | #define NAND_EVB_ALE_GPIO_PIN (0x80000000 >> 16) | ||
54 | #define NAND_EVB_RB_GPIO_PIN (0x80000000 >> 31) | ||
55 | |||
56 | /* | ||
57 | * MTD structure for PPChameleonEVB board | ||
58 | */ | ||
59 | static struct mtd_info *ppchameleon_mtd = NULL; | ||
60 | static struct mtd_info *ppchameleonevb_mtd = NULL; | ||
61 | |||
62 | /* | ||
63 | * Module stuff | ||
64 | */ | ||
65 | static unsigned long ppchameleon_fio_pbase = CFG_NAND0_PADDR; | ||
66 | static unsigned long ppchameleonevb_fio_pbase = CFG_NAND1_PADDR; | ||
67 | |||
68 | #ifdef MODULE | ||
69 | module_param(ppchameleon_fio_pbase, ulong, 0); | ||
70 | module_param(ppchameleonevb_fio_pbase, ulong, 0); | ||
71 | #else | ||
72 | __setup("ppchameleon_fio_pbase=", ppchameleon_fio_pbase); | ||
73 | __setup("ppchameleonevb_fio_pbase=", ppchameleonevb_fio_pbase); | ||
74 | #endif | ||
75 | |||
76 | /* | ||
77 | * Define static partitions for flash devices | ||
78 | */ | ||
79 | static struct mtd_partition partition_info_hi[] = { | ||
80 | { .name = "PPChameleon HI Nand Flash", | ||
81 | .offset = 0, | ||
82 | .size = 128 * 1024 * 1024 | ||
83 | } | ||
84 | }; | ||
85 | |||
86 | static struct mtd_partition partition_info_me[] = { | ||
87 | { .name = "PPChameleon ME Nand Flash", | ||
88 | .offset = 0, | ||
89 | .size = 32 * 1024 * 1024 | ||
90 | } | ||
91 | }; | ||
92 | |||
93 | static struct mtd_partition partition_info_evb[] = { | ||
94 | { .name = "PPChameleonEVB Nand Flash", | ||
95 | .offset = 0, | ||
96 | .size = 32 * 1024 * 1024 | ||
97 | } | ||
98 | }; | ||
99 | |||
100 | #define NUM_PARTITIONS 1 | ||
101 | |||
102 | /* | ||
103 | * hardware specific access to control-lines | ||
104 | */ | ||
105 | static void ppchameleon_hwcontrol(struct mtd_info *mtdinfo, int cmd, | ||
106 | unsigned int ctrl) | ||
107 | { | ||
108 | struct nand_chip *chip = mtd->priv; | ||
109 | |||
110 | if (ctrl & NAND_CTRL_CHANGE) { | ||
111 | #error Missing headerfiles. No way to fix this. -tglx | ||
112 | switch (cmd) { | ||
113 | case NAND_CTL_SETCLE: | ||
114 | MACRO_NAND_CTL_SETCLE((unsigned long)CFG_NAND0_PADDR); | ||
115 | break; | ||
116 | case NAND_CTL_CLRCLE: | ||
117 | MACRO_NAND_CTL_CLRCLE((unsigned long)CFG_NAND0_PADDR); | ||
118 | break; | ||
119 | case NAND_CTL_SETALE: | ||
120 | MACRO_NAND_CTL_SETALE((unsigned long)CFG_NAND0_PADDR); | ||
121 | break; | ||
122 | case NAND_CTL_CLRALE: | ||
123 | MACRO_NAND_CTL_CLRALE((unsigned long)CFG_NAND0_PADDR); | ||
124 | break; | ||
125 | case NAND_CTL_SETNCE: | ||
126 | MACRO_NAND_ENABLE_CE((unsigned long)CFG_NAND0_PADDR); | ||
127 | break; | ||
128 | case NAND_CTL_CLRNCE: | ||
129 | MACRO_NAND_DISABLE_CE((unsigned long)CFG_NAND0_PADDR); | ||
130 | break; | ||
131 | } | ||
132 | } | ||
133 | if (cmd != NAND_CMD_NONE) | ||
134 | writeb(cmd, chip->IO_ADDR_W); | ||
135 | } | ||
136 | |||
137 | static void ppchameleonevb_hwcontrol(struct mtd_info *mtdinfo, int cmd, | ||
138 | unsigned int ctrl) | ||
139 | { | ||
140 | struct nand_chip *chip = mtd->priv; | ||
141 | |||
142 | if (ctrl & NAND_CTRL_CHANGE) { | ||
143 | #error Missing headerfiles. No way to fix this. -tglx | ||
144 | switch (cmd) { | ||
145 | case NAND_CTL_SETCLE: | ||
146 | MACRO_NAND_CTL_SETCLE((unsigned long)CFG_NAND1_PADDR); | ||
147 | break; | ||
148 | case NAND_CTL_CLRCLE: | ||
149 | MACRO_NAND_CTL_CLRCLE((unsigned long)CFG_NAND1_PADDR); | ||
150 | break; | ||
151 | case NAND_CTL_SETALE: | ||
152 | MACRO_NAND_CTL_SETALE((unsigned long)CFG_NAND1_PADDR); | ||
153 | break; | ||
154 | case NAND_CTL_CLRALE: | ||
155 | MACRO_NAND_CTL_CLRALE((unsigned long)CFG_NAND1_PADDR); | ||
156 | break; | ||
157 | case NAND_CTL_SETNCE: | ||
158 | MACRO_NAND_ENABLE_CE((unsigned long)CFG_NAND1_PADDR); | ||
159 | break; | ||
160 | case NAND_CTL_CLRNCE: | ||
161 | MACRO_NAND_DISABLE_CE((unsigned long)CFG_NAND1_PADDR); | ||
162 | break; | ||
163 | } | ||
164 | } | ||
165 | if (cmd != NAND_CMD_NONE) | ||
166 | writeb(cmd, chip->IO_ADDR_W); | ||
167 | } | ||
168 | |||
169 | #ifdef USE_READY_BUSY_PIN | ||
170 | /* | ||
171 | * read device ready pin | ||
172 | */ | ||
173 | static int ppchameleon_device_ready(struct mtd_info *minfo) | ||
174 | { | ||
175 | if (in_be32((volatile unsigned *)GPIO0_IR) & NAND_RB_GPIO_PIN) | ||
176 | return 1; | ||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | static int ppchameleonevb_device_ready(struct mtd_info *minfo) | ||
181 | { | ||
182 | if (in_be32((volatile unsigned *)GPIO0_IR) & NAND_EVB_RB_GPIO_PIN) | ||
183 | return 1; | ||
184 | return 0; | ||
185 | } | ||
186 | #endif | ||
187 | |||
188 | /* | ||
189 | * Main initialization routine | ||
190 | */ | ||
191 | static int __init ppchameleonevb_init(void) | ||
192 | { | ||
193 | struct nand_chip *this; | ||
194 | void __iomem *ppchameleon_fio_base; | ||
195 | void __iomem *ppchameleonevb_fio_base; | ||
196 | |||
197 | /********************************* | ||
198 | * Processor module NAND (if any) * | ||
199 | *********************************/ | ||
200 | /* Allocate memory for MTD device structure and private data */ | ||
201 | ppchameleon_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); | ||
202 | if (!ppchameleon_mtd) { | ||
203 | printk("Unable to allocate PPChameleon NAND MTD device structure.\n"); | ||
204 | return -ENOMEM; | ||
205 | } | ||
206 | |||
207 | /* map physical address */ | ||
208 | ppchameleon_fio_base = ioremap(ppchameleon_fio_pbase, SZ_4M); | ||
209 | if (!ppchameleon_fio_base) { | ||
210 | printk("ioremap PPChameleon NAND flash failed\n"); | ||
211 | kfree(ppchameleon_mtd); | ||
212 | return -EIO; | ||
213 | } | ||
214 | |||
215 | /* Get pointer to private data */ | ||
216 | this = (struct nand_chip *)(&ppchameleon_mtd[1]); | ||
217 | |||
218 | /* Initialize structures */ | ||
219 | memset(ppchameleon_mtd, 0, sizeof(struct mtd_info)); | ||
220 | memset(this, 0, sizeof(struct nand_chip)); | ||
221 | |||
222 | /* Link the private data with the MTD structure */ | ||
223 | ppchameleon_mtd->priv = this; | ||
224 | ppchameleon_mtd->owner = THIS_MODULE; | ||
225 | |||
226 | /* Initialize GPIOs */ | ||
227 | /* Pin mapping for NAND chip */ | ||
228 | /* | ||
229 | CE GPIO_01 | ||
230 | CLE GPIO_02 | ||
231 | ALE GPIO_03 | ||
232 | R/B GPIO_04 | ||
233 | */ | ||
234 | /* output select */ | ||
235 | out_be32((volatile unsigned *)GPIO0_OSRH, in_be32((volatile unsigned *)GPIO0_OSRH) & 0xC0FFFFFF); | ||
236 | /* three-state select */ | ||
237 | out_be32((volatile unsigned *)GPIO0_TSRH, in_be32((volatile unsigned *)GPIO0_TSRH) & 0xC0FFFFFF); | ||
238 | /* enable output driver */ | ||
239 | out_be32((volatile unsigned *)GPIO0_TCR, | ||
240 | in_be32((volatile unsigned *)GPIO0_TCR) | NAND_nCE_GPIO_PIN | NAND_CLE_GPIO_PIN | NAND_ALE_GPIO_PIN); | ||
241 | #ifdef USE_READY_BUSY_PIN | ||
242 | /* three-state select */ | ||
243 | out_be32((volatile unsigned *)GPIO0_TSRH, in_be32((volatile unsigned *)GPIO0_TSRH) & 0xFF3FFFFF); | ||
244 | /* high-impedecence */ | ||
245 | out_be32((volatile unsigned *)GPIO0_TCR, in_be32((volatile unsigned *)GPIO0_TCR) & (~NAND_RB_GPIO_PIN)); | ||
246 | /* input select */ | ||
247 | out_be32((volatile unsigned *)GPIO0_ISR1H, | ||
248 | (in_be32((volatile unsigned *)GPIO0_ISR1H) & 0xFF3FFFFF) | 0x00400000); | ||
249 | #endif | ||
250 | |||
251 | /* insert callbacks */ | ||
252 | this->IO_ADDR_R = ppchameleon_fio_base; | ||
253 | this->IO_ADDR_W = ppchameleon_fio_base; | ||
254 | this->cmd_ctrl = ppchameleon_hwcontrol; | ||
255 | #ifdef USE_READY_BUSY_PIN | ||
256 | this->dev_ready = ppchameleon_device_ready; | ||
257 | #endif | ||
258 | this->chip_delay = NAND_BIG_DELAY_US; | ||
259 | /* ECC mode */ | ||
260 | this->ecc.mode = NAND_ECC_SOFT; | ||
261 | |||
262 | /* Scan to find existence of the device (it could not be mounted) */ | ||
263 | if (nand_scan(ppchameleon_mtd, 1)) { | ||
264 | iounmap((void *)ppchameleon_fio_base); | ||
265 | ppchameleon_fio_base = NULL; | ||
266 | kfree(ppchameleon_mtd); | ||
267 | goto nand_evb_init; | ||
268 | } | ||
269 | #ifndef USE_READY_BUSY_PIN | ||
270 | /* Adjust delay if necessary */ | ||
271 | if (ppchameleon_mtd->size == NAND_SMALL_SIZE) | ||
272 | this->chip_delay = NAND_SMALL_DELAY_US; | ||
273 | #endif | ||
274 | |||
275 | ppchameleon_mtd->name = "ppchameleon-nand"; | ||
276 | |||
277 | /* Register the partitions */ | ||
278 | mtd_device_parse_register(ppchameleon_mtd, NULL, NULL, | ||
279 | ppchameleon_mtd->size == NAND_SMALL_SIZE ? | ||
280 | partition_info_me : partition_info_hi, | ||
281 | NUM_PARTITIONS); | ||
282 | |||
283 | nand_evb_init: | ||
284 | /**************************** | ||
285 | * EVB NAND (always present) * | ||
286 | ****************************/ | ||
287 | /* Allocate memory for MTD device structure and private data */ | ||
288 | ppchameleonevb_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); | ||
289 | if (!ppchameleonevb_mtd) { | ||
290 | printk("Unable to allocate PPChameleonEVB NAND MTD device structure.\n"); | ||
291 | if (ppchameleon_fio_base) | ||
292 | iounmap(ppchameleon_fio_base); | ||
293 | return -ENOMEM; | ||
294 | } | ||
295 | |||
296 | /* map physical address */ | ||
297 | ppchameleonevb_fio_base = ioremap(ppchameleonevb_fio_pbase, SZ_4M); | ||
298 | if (!ppchameleonevb_fio_base) { | ||
299 | printk("ioremap PPChameleonEVB NAND flash failed\n"); | ||
300 | kfree(ppchameleonevb_mtd); | ||
301 | if (ppchameleon_fio_base) | ||
302 | iounmap(ppchameleon_fio_base); | ||
303 | return -EIO; | ||
304 | } | ||
305 | |||
306 | /* Get pointer to private data */ | ||
307 | this = (struct nand_chip *)(&ppchameleonevb_mtd[1]); | ||
308 | |||
309 | /* Initialize structures */ | ||
310 | memset(ppchameleonevb_mtd, 0, sizeof(struct mtd_info)); | ||
311 | memset(this, 0, sizeof(struct nand_chip)); | ||
312 | |||
313 | /* Link the private data with the MTD structure */ | ||
314 | ppchameleonevb_mtd->priv = this; | ||
315 | |||
316 | /* Initialize GPIOs */ | ||
317 | /* Pin mapping for NAND chip */ | ||
318 | /* | ||
319 | CE GPIO_14 | ||
320 | CLE GPIO_15 | ||
321 | ALE GPIO_16 | ||
322 | R/B GPIO_31 | ||
323 | */ | ||
324 | /* output select */ | ||
325 | out_be32((volatile unsigned *)GPIO0_OSRH, in_be32((volatile unsigned *)GPIO0_OSRH) & 0xFFFFFFF0); | ||
326 | out_be32((volatile unsigned *)GPIO0_OSRL, in_be32((volatile unsigned *)GPIO0_OSRL) & 0x3FFFFFFF); | ||
327 | /* three-state select */ | ||
328 | out_be32((volatile unsigned *)GPIO0_TSRH, in_be32((volatile unsigned *)GPIO0_TSRH) & 0xFFFFFFF0); | ||
329 | out_be32((volatile unsigned *)GPIO0_TSRL, in_be32((volatile unsigned *)GPIO0_TSRL) & 0x3FFFFFFF); | ||
330 | /* enable output driver */ | ||
331 | out_be32((volatile unsigned *)GPIO0_TCR, in_be32((volatile unsigned *)GPIO0_TCR) | NAND_EVB_nCE_GPIO_PIN | | ||
332 | NAND_EVB_CLE_GPIO_PIN | NAND_EVB_ALE_GPIO_PIN); | ||
333 | #ifdef USE_READY_BUSY_PIN | ||
334 | /* three-state select */ | ||
335 | out_be32((volatile unsigned *)GPIO0_TSRL, in_be32((volatile unsigned *)GPIO0_TSRL) & 0xFFFFFFFC); | ||
336 | /* high-impedecence */ | ||
337 | out_be32((volatile unsigned *)GPIO0_TCR, in_be32((volatile unsigned *)GPIO0_TCR) & (~NAND_EVB_RB_GPIO_PIN)); | ||
338 | /* input select */ | ||
339 | out_be32((volatile unsigned *)GPIO0_ISR1L, | ||
340 | (in_be32((volatile unsigned *)GPIO0_ISR1L) & 0xFFFFFFFC) | 0x00000001); | ||
341 | #endif | ||
342 | |||
343 | /* insert callbacks */ | ||
344 | this->IO_ADDR_R = ppchameleonevb_fio_base; | ||
345 | this->IO_ADDR_W = ppchameleonevb_fio_base; | ||
346 | this->cmd_ctrl = ppchameleonevb_hwcontrol; | ||
347 | #ifdef USE_READY_BUSY_PIN | ||
348 | this->dev_ready = ppchameleonevb_device_ready; | ||
349 | #endif | ||
350 | this->chip_delay = NAND_SMALL_DELAY_US; | ||
351 | |||
352 | /* ECC mode */ | ||
353 | this->ecc.mode = NAND_ECC_SOFT; | ||
354 | |||
355 | /* Scan to find existence of the device */ | ||
356 | if (nand_scan(ppchameleonevb_mtd, 1)) { | ||
357 | iounmap((void *)ppchameleonevb_fio_base); | ||
358 | kfree(ppchameleonevb_mtd); | ||
359 | if (ppchameleon_fio_base) | ||
360 | iounmap(ppchameleon_fio_base); | ||
361 | return -ENXIO; | ||
362 | } | ||
363 | |||
364 | ppchameleonevb_mtd->name = NAND_EVB_MTD_NAME; | ||
365 | |||
366 | /* Register the partitions */ | ||
367 | mtd_device_parse_register(ppchameleonevb_mtd, NULL, NULL, | ||
368 | ppchameleon_mtd->size == NAND_SMALL_SIZE ? | ||
369 | partition_info_me : partition_info_hi, | ||
370 | NUM_PARTITIONS); | ||
371 | |||
372 | /* Return happy */ | ||
373 | return 0; | ||
374 | } | ||
375 | |||
376 | module_init(ppchameleonevb_init); | ||
377 | |||
378 | /* | ||
379 | * Clean up routine | ||
380 | */ | ||
381 | static void __exit ppchameleonevb_cleanup(void) | ||
382 | { | ||
383 | struct nand_chip *this; | ||
384 | |||
385 | /* Release resources, unregister device(s) */ | ||
386 | nand_release(ppchameleon_mtd); | ||
387 | nand_release(ppchameleonevb_mtd); | ||
388 | |||
389 | /* Release iomaps */ | ||
390 | this = (struct nand_chip *) &ppchameleon_mtd[1]; | ||
391 | iounmap((void *) this->IO_ADDR_R); | ||
392 | this = (struct nand_chip *) &ppchameleonevb_mtd[1]; | ||
393 | iounmap((void *) this->IO_ADDR_R); | ||
394 | |||
395 | /* Free the MTD device structure */ | ||
396 | kfree (ppchameleon_mtd); | ||
397 | kfree (ppchameleonevb_mtd); | ||
398 | } | ||
399 | module_exit(ppchameleonevb_cleanup); | ||
400 | |||
401 | MODULE_LICENSE("GPL"); | ||
402 | MODULE_AUTHOR("DAVE Srl <support-ppchameleon@dave-tech.it>"); | ||
403 | MODULE_DESCRIPTION("MTD map driver for DAVE Srl PPChameleonEVB board"); | ||
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 37ee75c7bacb..dec80ca6a5ce 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c | |||
@@ -989,7 +989,7 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) | |||
989 | } | 989 | } |
990 | 990 | ||
991 | pxa3xx_flash_ids[0].name = f->name; | 991 | pxa3xx_flash_ids[0].name = f->name; |
992 | pxa3xx_flash_ids[0].id = (f->chip_id >> 8) & 0xffff; | 992 | pxa3xx_flash_ids[0].dev_id = (f->chip_id >> 8) & 0xffff; |
993 | pxa3xx_flash_ids[0].pagesize = f->page_size; | 993 | pxa3xx_flash_ids[0].pagesize = f->page_size; |
994 | chipsize = (uint64_t)f->num_blocks * f->page_per_block * f->page_size; | 994 | chipsize = (uint64_t)f->num_blocks * f->page_per_block * f->page_size; |
995 | pxa3xx_flash_ids[0].chipsize = chipsize >> 20; | 995 | pxa3xx_flash_ids[0].chipsize = chipsize >> 20; |
diff --git a/drivers/mtd/nand/rtc_from4.c b/drivers/mtd/nand/rtc_from4.c deleted file mode 100644 index e55b5cfbe145..000000000000 --- a/drivers/mtd/nand/rtc_from4.c +++ /dev/null | |||
@@ -1,624 +0,0 @@ | |||
1 | /* | ||
2 | * drivers/mtd/nand/rtc_from4.c | ||
3 | * | ||
4 | * Copyright (C) 2004 Red Hat, Inc. | ||
5 | * | ||
6 | * Derived from drivers/mtd/nand/spia.c | ||
7 | * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | * | ||
13 | * Overview: | ||
14 | * This is a device driver for the AG-AND flash device found on the | ||
15 | * Renesas Technology Corp. Flash ROM 4-slot interface board (FROM_BOARD4), | ||
16 | * which utilizes the Renesas HN29V1G91T-30 part. | ||
17 | * This chip is a 1 GBibit (128MiB x 8 bits) AG-AND flash device. | ||
18 | */ | ||
19 | |||
20 | #include <linux/delay.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/rslib.h> | ||
25 | #include <linux/bitrev.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/mtd/mtd.h> | ||
28 | #include <linux/mtd/nand.h> | ||
29 | #include <linux/mtd/partitions.h> | ||
30 | #include <asm/io.h> | ||
31 | |||
32 | /* | ||
33 | * MTD structure for Renesas board | ||
34 | */ | ||
35 | static struct mtd_info *rtc_from4_mtd = NULL; | ||
36 | |||
37 | #define RTC_FROM4_MAX_CHIPS 2 | ||
38 | |||
39 | /* HS77x9 processor register defines */ | ||
40 | #define SH77X9_BCR1 ((volatile unsigned short *)(0xFFFFFF60)) | ||
41 | #define SH77X9_BCR2 ((volatile unsigned short *)(0xFFFFFF62)) | ||
42 | #define SH77X9_WCR1 ((volatile unsigned short *)(0xFFFFFF64)) | ||
43 | #define SH77X9_WCR2 ((volatile unsigned short *)(0xFFFFFF66)) | ||
44 | #define SH77X9_MCR ((volatile unsigned short *)(0xFFFFFF68)) | ||
45 | #define SH77X9_PCR ((volatile unsigned short *)(0xFFFFFF6C)) | ||
46 | #define SH77X9_FRQCR ((volatile unsigned short *)(0xFFFFFF80)) | ||
47 | |||
48 | /* | ||
49 | * Values specific to the Renesas Technology Corp. FROM_BOARD4 (used with HS77x9 processor) | ||
50 | */ | ||
51 | /* Address where flash is mapped */ | ||
52 | #define RTC_FROM4_FIO_BASE 0x14000000 | ||
53 | |||
54 | /* CLE and ALE are tied to address lines 5 & 4, respectively */ | ||
55 | #define RTC_FROM4_CLE (1 << 5) | ||
56 | #define RTC_FROM4_ALE (1 << 4) | ||
57 | |||
58 | /* address lines A24-A22 used for chip selection */ | ||
59 | #define RTC_FROM4_NAND_ADDR_SLOT3 (0x00800000) | ||
60 | #define RTC_FROM4_NAND_ADDR_SLOT4 (0x00C00000) | ||
61 | #define RTC_FROM4_NAND_ADDR_FPGA (0x01000000) | ||
62 | /* mask address lines A24-A22 used for chip selection */ | ||
63 | #define RTC_FROM4_NAND_ADDR_MASK (RTC_FROM4_NAND_ADDR_SLOT3 | RTC_FROM4_NAND_ADDR_SLOT4 | RTC_FROM4_NAND_ADDR_FPGA) | ||
64 | |||
65 | /* FPGA status register for checking device ready (bit zero) */ | ||
66 | #define RTC_FROM4_FPGA_SR (RTC_FROM4_NAND_ADDR_FPGA | 0x00000002) | ||
67 | #define RTC_FROM4_DEVICE_READY 0x0001 | ||
68 | |||
69 | /* FPGA Reed-Solomon ECC Control register */ | ||
70 | |||
71 | #define RTC_FROM4_RS_ECC_CTL (RTC_FROM4_NAND_ADDR_FPGA | 0x00000050) | ||
72 | #define RTC_FROM4_RS_ECC_CTL_CLR (1 << 7) | ||
73 | #define RTC_FROM4_RS_ECC_CTL_GEN (1 << 6) | ||
74 | #define RTC_FROM4_RS_ECC_CTL_FD_E (1 << 5) | ||
75 | |||
76 | /* FPGA Reed-Solomon ECC code base */ | ||
77 | #define RTC_FROM4_RS_ECC (RTC_FROM4_NAND_ADDR_FPGA | 0x00000060) | ||
78 | #define RTC_FROM4_RS_ECCN (RTC_FROM4_NAND_ADDR_FPGA | 0x00000080) | ||
79 | |||
80 | /* FPGA Reed-Solomon ECC check register */ | ||
81 | #define RTC_FROM4_RS_ECC_CHK (RTC_FROM4_NAND_ADDR_FPGA | 0x00000070) | ||
82 | #define RTC_FROM4_RS_ECC_CHK_ERROR (1 << 7) | ||
83 | |||
84 | #define ERR_STAT_ECC_AVAILABLE 0x20 | ||
85 | |||
86 | /* Undefine for software ECC */ | ||
87 | #define RTC_FROM4_HWECC 1 | ||
88 | |||
89 | /* Define as 1 for no virtual erase blocks (in JFFS2) */ | ||
90 | #define RTC_FROM4_NO_VIRTBLOCKS 0 | ||
91 | |||
92 | /* | ||
93 | * Module stuff | ||
94 | */ | ||
95 | static void __iomem *rtc_from4_fio_base = (void *)P2SEGADDR(RTC_FROM4_FIO_BASE); | ||
96 | |||
97 | static const struct mtd_partition partition_info[] = { | ||
98 | { | ||
99 | .name = "Renesas flash partition 1", | ||
100 | .offset = 0, | ||
101 | .size = MTDPART_SIZ_FULL}, | ||
102 | }; | ||
103 | |||
104 | #define NUM_PARTITIONS 1 | ||
105 | |||
106 | /* | ||
107 | * hardware specific flash bbt decriptors | ||
108 | * Note: this is to allow debugging by disabling | ||
109 | * NAND_BBT_CREATE and/or NAND_BBT_WRITE | ||
110 | * | ||
111 | */ | ||
112 | static uint8_t bbt_pattern[] = { 'B', 'b', 't', '0' }; | ||
113 | static uint8_t mirror_pattern[] = { '1', 't', 'b', 'B' }; | ||
114 | |||
115 | static struct nand_bbt_descr rtc_from4_bbt_main_descr = { | ||
116 | .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | ||
117 | | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, | ||
118 | .offs = 40, | ||
119 | .len = 4, | ||
120 | .veroffs = 44, | ||
121 | .maxblocks = 4, | ||
122 | .pattern = bbt_pattern | ||
123 | }; | ||
124 | |||
125 | static struct nand_bbt_descr rtc_from4_bbt_mirror_descr = { | ||
126 | .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | ||
127 | | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, | ||
128 | .offs = 40, | ||
129 | .len = 4, | ||
130 | .veroffs = 44, | ||
131 | .maxblocks = 4, | ||
132 | .pattern = mirror_pattern | ||
133 | }; | ||
134 | |||
135 | #ifdef RTC_FROM4_HWECC | ||
136 | |||
137 | /* the Reed Solomon control structure */ | ||
138 | static struct rs_control *rs_decoder; | ||
139 | |||
140 | /* | ||
141 | * hardware specific Out Of Band information | ||
142 | */ | ||
143 | static struct nand_ecclayout rtc_from4_nand_oobinfo = { | ||
144 | .eccbytes = 32, | ||
145 | .eccpos = { | ||
146 | 0, 1, 2, 3, 4, 5, 6, 7, | ||
147 | 8, 9, 10, 11, 12, 13, 14, 15, | ||
148 | 16, 17, 18, 19, 20, 21, 22, 23, | ||
149 | 24, 25, 26, 27, 28, 29, 30, 31}, | ||
150 | .oobfree = {{32, 32}} | ||
151 | }; | ||
152 | |||
153 | #endif | ||
154 | |||
155 | /* | ||
156 | * rtc_from4_hwcontrol - hardware specific access to control-lines | ||
157 | * @mtd: MTD device structure | ||
158 | * @cmd: hardware control command | ||
159 | * | ||
160 | * Address lines (A5 and A4) are used to control Command and Address Latch | ||
161 | * Enable on this board, so set the read/write address appropriately. | ||
162 | * | ||
163 | * Chip Enable is also controlled by the Chip Select (CS5) and | ||
164 | * Address lines (A24-A22), so no action is required here. | ||
165 | * | ||
166 | */ | ||
167 | static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd, | ||
168 | unsigned int ctrl) | ||
169 | { | ||
170 | struct nand_chip *chip = (mtd->priv); | ||
171 | |||
172 | if (cmd == NAND_CMD_NONE) | ||
173 | return; | ||
174 | |||
175 | if (ctrl & NAND_CLE) | ||
176 | writeb(cmd, chip->IO_ADDR_W | RTC_FROM4_CLE); | ||
177 | else | ||
178 | writeb(cmd, chip->IO_ADDR_W | RTC_FROM4_ALE); | ||
179 | } | ||
180 | |||
181 | /* | ||
182 | * rtc_from4_nand_select_chip - hardware specific chip select | ||
183 | * @mtd: MTD device structure | ||
184 | * @chip: Chip to select (0 == slot 3, 1 == slot 4) | ||
185 | * | ||
186 | * The chip select is based on address lines A24-A22. | ||
187 | * This driver uses flash slots 3 and 4 (A23-A22). | ||
188 | * | ||
189 | */ | ||
190 | static void rtc_from4_nand_select_chip(struct mtd_info *mtd, int chip) | ||
191 | { | ||
192 | struct nand_chip *this = mtd->priv; | ||
193 | |||
194 | this->IO_ADDR_R = (void __iomem *)((unsigned long)this->IO_ADDR_R & ~RTC_FROM4_NAND_ADDR_MASK); | ||
195 | this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_NAND_ADDR_MASK); | ||
196 | |||
197 | switch (chip) { | ||
198 | |||
199 | case 0: /* select slot 3 chip */ | ||
200 | this->IO_ADDR_R = (void __iomem *)((unsigned long)this->IO_ADDR_R | RTC_FROM4_NAND_ADDR_SLOT3); | ||
201 | this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_NAND_ADDR_SLOT3); | ||
202 | break; | ||
203 | case 1: /* select slot 4 chip */ | ||
204 | this->IO_ADDR_R = (void __iomem *)((unsigned long)this->IO_ADDR_R | RTC_FROM4_NAND_ADDR_SLOT4); | ||
205 | this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_NAND_ADDR_SLOT4); | ||
206 | break; | ||
207 | |||
208 | } | ||
209 | } | ||
210 | |||
211 | /* | ||
212 | * rtc_from4_nand_device_ready - hardware specific ready/busy check | ||
213 | * @mtd: MTD device structure | ||
214 | * | ||
215 | * This board provides the Ready/Busy state in the status register | ||
216 | * of the FPGA. Bit zero indicates the RDY(1)/BSY(0) signal. | ||
217 | * | ||
218 | */ | ||
219 | static int rtc_from4_nand_device_ready(struct mtd_info *mtd) | ||
220 | { | ||
221 | unsigned short status; | ||
222 | |||
223 | status = *((volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_FPGA_SR)); | ||
224 | |||
225 | return (status & RTC_FROM4_DEVICE_READY); | ||
226 | |||
227 | } | ||
228 | |||
229 | /* | ||
230 | * deplete - code to perform device recovery in case there was a power loss | ||
231 | * @mtd: MTD device structure | ||
232 | * @chip: Chip to select (0 == slot 3, 1 == slot 4) | ||
233 | * | ||
234 | * If there was a sudden loss of power during an erase operation, a | ||
235 | * "device recovery" operation must be performed when power is restored | ||
236 | * to ensure correct operation. This routine performs the required steps | ||
237 | * for the requested chip. | ||
238 | * | ||
239 | * See page 86 of the data sheet for details. | ||
240 | * | ||
241 | */ | ||
242 | static void deplete(struct mtd_info *mtd, int chip) | ||
243 | { | ||
244 | struct nand_chip *this = mtd->priv; | ||
245 | |||
246 | /* wait until device is ready */ | ||
247 | while (!this->dev_ready(mtd)) ; | ||
248 | |||
249 | this->select_chip(mtd, chip); | ||
250 | |||
251 | /* Send the commands for device recovery, phase 1 */ | ||
252 | this->cmdfunc(mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000); | ||
253 | this->cmdfunc(mtd, NAND_CMD_DEPLETE2, -1, -1); | ||
254 | |||
255 | /* Send the commands for device recovery, phase 2 */ | ||
256 | this->cmdfunc(mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0004); | ||
257 | this->cmdfunc(mtd, NAND_CMD_DEPLETE2, -1, -1); | ||
258 | |||
259 | } | ||
260 | |||
261 | #ifdef RTC_FROM4_HWECC | ||
262 | /* | ||
263 | * rtc_from4_enable_hwecc - hardware specific hardware ECC enable function | ||
264 | * @mtd: MTD device structure | ||
265 | * @mode: I/O mode; read or write | ||
266 | * | ||
267 | * enable hardware ECC for data read or write | ||
268 | * | ||
269 | */ | ||
270 | static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode) | ||
271 | { | ||
272 | volatile unsigned short *rs_ecc_ctl = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC_CTL); | ||
273 | unsigned short status; | ||
274 | |||
275 | switch (mode) { | ||
276 | case NAND_ECC_READ: | ||
277 | status = RTC_FROM4_RS_ECC_CTL_CLR | RTC_FROM4_RS_ECC_CTL_FD_E; | ||
278 | |||
279 | *rs_ecc_ctl = status; | ||
280 | break; | ||
281 | |||
282 | case NAND_ECC_READSYN: | ||
283 | status = 0x00; | ||
284 | |||
285 | *rs_ecc_ctl = status; | ||
286 | break; | ||
287 | |||
288 | case NAND_ECC_WRITE: | ||
289 | status = RTC_FROM4_RS_ECC_CTL_CLR | RTC_FROM4_RS_ECC_CTL_GEN | RTC_FROM4_RS_ECC_CTL_FD_E; | ||
290 | |||
291 | *rs_ecc_ctl = status; | ||
292 | break; | ||
293 | |||
294 | default: | ||
295 | BUG(); | ||
296 | break; | ||
297 | } | ||
298 | |||
299 | } | ||
300 | |||
301 | /* | ||
302 | * rtc_from4_calculate_ecc - hardware specific code to read ECC code | ||
303 | * @mtd: MTD device structure | ||
304 | * @dat: buffer containing the data to generate ECC codes | ||
305 | * @ecc_code ECC codes calculated | ||
306 | * | ||
307 | * The ECC code is calculated by the FPGA. All we have to do is read the values | ||
308 | * from the FPGA registers. | ||
309 | * | ||
310 | * Note: We read from the inverted registers, since data is inverted before | ||
311 | * the code is calculated. So all 0xff data (blank page) results in all 0xff rs code | ||
312 | * | ||
313 | */ | ||
314 | static void rtc_from4_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) | ||
315 | { | ||
316 | volatile unsigned short *rs_eccn = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECCN); | ||
317 | unsigned short value; | ||
318 | int i; | ||
319 | |||
320 | for (i = 0; i < 8; i++) { | ||
321 | value = *rs_eccn; | ||
322 | ecc_code[i] = (unsigned char)value; | ||
323 | rs_eccn++; | ||
324 | } | ||
325 | ecc_code[7] |= 0x0f; /* set the last four bits (not used) */ | ||
326 | } | ||
327 | |||
328 | /* | ||
329 | * rtc_from4_correct_data - hardware specific code to correct data using ECC code | ||
330 | * @mtd: MTD device structure | ||
331 | * @buf: buffer containing the data to generate ECC codes | ||
332 | * @ecc1 ECC codes read | ||
333 | * @ecc2 ECC codes calculated | ||
334 | * | ||
335 | * The FPGA tells us fast, if there's an error or not. If no, we go back happy | ||
336 | * else we read the ecc results from the fpga and call the rs library to decode | ||
337 | * and hopefully correct the error. | ||
338 | * | ||
339 | */ | ||
340 | static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_char *ecc1, u_char *ecc2) | ||
341 | { | ||
342 | int i, j, res; | ||
343 | unsigned short status; | ||
344 | uint16_t par[6], syn[6]; | ||
345 | uint8_t ecc[8]; | ||
346 | volatile unsigned short *rs_ecc; | ||
347 | |||
348 | status = *((volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC_CHK)); | ||
349 | |||
350 | if (!(status & RTC_FROM4_RS_ECC_CHK_ERROR)) { | ||
351 | return 0; | ||
352 | } | ||
353 | |||
354 | /* Read the syndrome pattern from the FPGA and correct the bitorder */ | ||
355 | rs_ecc = (volatile unsigned short *)(rtc_from4_fio_base + RTC_FROM4_RS_ECC); | ||
356 | for (i = 0; i < 8; i++) { | ||
357 | ecc[i] = bitrev8(*rs_ecc); | ||
358 | rs_ecc++; | ||
359 | } | ||
360 | |||
361 | /* convert into 6 10bit syndrome fields */ | ||
362 | par[5] = rs_decoder->index_of[(((uint16_t) ecc[0] >> 0) & 0x0ff) | (((uint16_t) ecc[1] << 8) & 0x300)]; | ||
363 | par[4] = rs_decoder->index_of[(((uint16_t) ecc[1] >> 2) & 0x03f) | (((uint16_t) ecc[2] << 6) & 0x3c0)]; | ||
364 | par[3] = rs_decoder->index_of[(((uint16_t) ecc[2] >> 4) & 0x00f) | (((uint16_t) ecc[3] << 4) & 0x3f0)]; | ||
365 | par[2] = rs_decoder->index_of[(((uint16_t) ecc[3] >> 6) & 0x003) | (((uint16_t) ecc[4] << 2) & 0x3fc)]; | ||
366 | par[1] = rs_decoder->index_of[(((uint16_t) ecc[5] >> 0) & 0x0ff) | (((uint16_t) ecc[6] << 8) & 0x300)]; | ||
367 | par[0] = (((uint16_t) ecc[6] >> 2) & 0x03f) | (((uint16_t) ecc[7] << 6) & 0x3c0); | ||
368 | |||
369 | /* Convert to computable syndrome */ | ||
370 | for (i = 0; i < 6; i++) { | ||
371 | syn[i] = par[0]; | ||
372 | for (j = 1; j < 6; j++) | ||
373 | if (par[j] != rs_decoder->nn) | ||
374 | syn[i] ^= rs_decoder->alpha_to[rs_modnn(rs_decoder, par[j] + i * j)]; | ||
375 | |||
376 | /* Convert to index form */ | ||
377 | syn[i] = rs_decoder->index_of[syn[i]]; | ||
378 | } | ||
379 | |||
380 | /* Let the library code do its magic. */ | ||
381 | res = decode_rs8(rs_decoder, (uint8_t *) buf, par, 512, syn, 0, NULL, 0xff, NULL); | ||
382 | if (res > 0) { | ||
383 | pr_debug("rtc_from4_correct_data: " "ECC corrected %d errors on read\n", res); | ||
384 | } | ||
385 | return res; | ||
386 | } | ||
387 | |||
388 | /** | ||
389 | * rtc_from4_errstat - perform additional error status checks | ||
390 | * @mtd: MTD device structure | ||
391 | * @this: NAND chip structure | ||
392 | * @state: state or the operation | ||
393 | * @status: status code returned from read status | ||
394 | * @page: startpage inside the chip, must be called with (page & this->pagemask) | ||
395 | * | ||
396 | * Perform additional error status checks on erase and write failures | ||
397 | * to determine if errors are correctable. For this device, correctable | ||
398 | * 1-bit errors on erase and write are considered acceptable. | ||
399 | * | ||
400 | * note: see pages 34..37 of data sheet for details. | ||
401 | * | ||
402 | */ | ||
403 | static int rtc_from4_errstat(struct mtd_info *mtd, struct nand_chip *this, | ||
404 | int state, int status, int page) | ||
405 | { | ||
406 | int er_stat = 0; | ||
407 | int rtn, retlen; | ||
408 | size_t len; | ||
409 | uint8_t *buf; | ||
410 | int i; | ||
411 | |||
412 | this->cmdfunc(mtd, NAND_CMD_STATUS_CLEAR, -1, -1); | ||
413 | |||
414 | if (state == FL_ERASING) { | ||
415 | |||
416 | for (i = 0; i < 4; i++) { | ||
417 | if (!(status & 1 << (i + 1))) | ||
418 | continue; | ||
419 | this->cmdfunc(mtd, (NAND_CMD_STATUS_ERROR + i + 1), | ||
420 | -1, -1); | ||
421 | rtn = this->read_byte(mtd); | ||
422 | this->cmdfunc(mtd, NAND_CMD_STATUS_RESET, -1, -1); | ||
423 | |||
424 | /* err_ecc_not_avail */ | ||
425 | if (!(rtn & ERR_STAT_ECC_AVAILABLE)) | ||
426 | er_stat |= 1 << (i + 1); | ||
427 | } | ||
428 | |||
429 | } else if (state == FL_WRITING) { | ||
430 | |||
431 | unsigned long corrected = mtd->ecc_stats.corrected; | ||
432 | |||
433 | /* single bank write logic */ | ||
434 | this->cmdfunc(mtd, NAND_CMD_STATUS_ERROR, -1, -1); | ||
435 | rtn = this->read_byte(mtd); | ||
436 | this->cmdfunc(mtd, NAND_CMD_STATUS_RESET, -1, -1); | ||
437 | |||
438 | if (!(rtn & ERR_STAT_ECC_AVAILABLE)) { | ||
439 | /* err_ecc_not_avail */ | ||
440 | er_stat |= 1 << 1; | ||
441 | goto out; | ||
442 | } | ||
443 | |||
444 | len = mtd->writesize; | ||
445 | buf = kmalloc(len, GFP_KERNEL); | ||
446 | if (!buf) { | ||
447 | er_stat = 1; | ||
448 | goto out; | ||
449 | } | ||
450 | |||
451 | /* recovery read */ | ||
452 | rtn = nand_do_read(mtd, page, len, &retlen, buf); | ||
453 | |||
454 | /* if read failed or > 1-bit error corrected */ | ||
455 | if (rtn || (mtd->ecc_stats.corrected - corrected) > 1) | ||
456 | er_stat |= 1 << 1; | ||
457 | kfree(buf); | ||
458 | } | ||
459 | out: | ||
460 | rtn = status; | ||
461 | if (er_stat == 0) { /* if ECC is available */ | ||
462 | rtn = (status & ~NAND_STATUS_FAIL); /* clear the error bit */ | ||
463 | } | ||
464 | |||
465 | return rtn; | ||
466 | } | ||
467 | #endif | ||
468 | |||
469 | /* | ||
470 | * Main initialization routine | ||
471 | */ | ||
472 | static int __init rtc_from4_init(void) | ||
473 | { | ||
474 | struct nand_chip *this; | ||
475 | unsigned short bcr1, bcr2, wcr2; | ||
476 | int i; | ||
477 | int ret; | ||
478 | |||
479 | /* Allocate memory for MTD device structure and private data */ | ||
480 | rtc_from4_mtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); | ||
481 | if (!rtc_from4_mtd) { | ||
482 | printk("Unable to allocate Renesas NAND MTD device structure.\n"); | ||
483 | return -ENOMEM; | ||
484 | } | ||
485 | |||
486 | /* Get pointer to private data */ | ||
487 | this = (struct nand_chip *)(&rtc_from4_mtd[1]); | ||
488 | |||
489 | /* Initialize structures */ | ||
490 | memset(rtc_from4_mtd, 0, sizeof(struct mtd_info)); | ||
491 | memset(this, 0, sizeof(struct nand_chip)); | ||
492 | |||
493 | /* Link the private data with the MTD structure */ | ||
494 | rtc_from4_mtd->priv = this; | ||
495 | rtc_from4_mtd->owner = THIS_MODULE; | ||
496 | |||
497 | /* set area 5 as PCMCIA mode to clear the spec of tDH(Data hold time;9ns min) */ | ||
498 | bcr1 = *SH77X9_BCR1 & ~0x0002; | ||
499 | bcr1 |= 0x0002; | ||
500 | *SH77X9_BCR1 = bcr1; | ||
501 | |||
502 | /* set */ | ||
503 | bcr2 = *SH77X9_BCR2 & ~0x0c00; | ||
504 | bcr2 |= 0x0800; | ||
505 | *SH77X9_BCR2 = bcr2; | ||
506 | |||
507 | /* set area 5 wait states */ | ||
508 | wcr2 = *SH77X9_WCR2 & ~0x1c00; | ||
509 | wcr2 |= 0x1c00; | ||
510 | *SH77X9_WCR2 = wcr2; | ||
511 | |||
512 | /* Set address of NAND IO lines */ | ||
513 | this->IO_ADDR_R = rtc_from4_fio_base; | ||
514 | this->IO_ADDR_W = rtc_from4_fio_base; | ||
515 | /* Set address of hardware control function */ | ||
516 | this->cmd_ctrl = rtc_from4_hwcontrol; | ||
517 | /* Set address of chip select function */ | ||
518 | this->select_chip = rtc_from4_nand_select_chip; | ||
519 | /* command delay time (in us) */ | ||
520 | this->chip_delay = 100; | ||
521 | /* return the status of the Ready/Busy line */ | ||
522 | this->dev_ready = rtc_from4_nand_device_ready; | ||
523 | |||
524 | #ifdef RTC_FROM4_HWECC | ||
525 | printk(KERN_INFO "rtc_from4_init: using hardware ECC detection.\n"); | ||
526 | |||
527 | this->ecc.mode = NAND_ECC_HW_SYNDROME; | ||
528 | this->ecc.size = 512; | ||
529 | this->ecc.bytes = 8; | ||
530 | this->ecc.strength = 3; | ||
531 | /* return the status of extra status and ECC checks */ | ||
532 | this->errstat = rtc_from4_errstat; | ||
533 | /* set the nand_oobinfo to support FPGA H/W error detection */ | ||
534 | this->ecc.layout = &rtc_from4_nand_oobinfo; | ||
535 | this->ecc.hwctl = rtc_from4_enable_hwecc; | ||
536 | this->ecc.calculate = rtc_from4_calculate_ecc; | ||
537 | this->ecc.correct = rtc_from4_correct_data; | ||
538 | |||
539 | /* We could create the decoder on demand, if memory is a concern. | ||
540 | * This way we have it handy, if an error happens | ||
541 | * | ||
542 | * Symbolsize is 10 (bits) | ||
543 | * Primitve polynomial is x^10+x^3+1 | ||
544 | * first consecutive root is 0 | ||
545 | * primitve element to generate roots = 1 | ||
546 | * generator polinomial degree = 6 | ||
547 | */ | ||
548 | rs_decoder = init_rs(10, 0x409, 0, 1, 6); | ||
549 | if (!rs_decoder) { | ||
550 | printk(KERN_ERR "Could not create a RS decoder\n"); | ||
551 | ret = -ENOMEM; | ||
552 | goto err_1; | ||
553 | } | ||
554 | #else | ||
555 | printk(KERN_INFO "rtc_from4_init: using software ECC detection.\n"); | ||
556 | |||
557 | this->ecc.mode = NAND_ECC_SOFT; | ||
558 | #endif | ||
559 | |||
560 | /* set the bad block tables to support debugging */ | ||
561 | this->bbt_td = &rtc_from4_bbt_main_descr; | ||
562 | this->bbt_md = &rtc_from4_bbt_mirror_descr; | ||
563 | |||
564 | /* Scan to find existence of the device */ | ||
565 | if (nand_scan(rtc_from4_mtd, RTC_FROM4_MAX_CHIPS)) { | ||
566 | ret = -ENXIO; | ||
567 | goto err_2; | ||
568 | } | ||
569 | |||
570 | /* Perform 'device recovery' for each chip in case there was a power loss. */ | ||
571 | for (i = 0; i < this->numchips; i++) { | ||
572 | deplete(rtc_from4_mtd, i); | ||
573 | } | ||
574 | |||
575 | #if RTC_FROM4_NO_VIRTBLOCKS | ||
576 | /* use a smaller erase block to minimize wasted space when a block is bad */ | ||
577 | /* note: this uses eight times as much RAM as using the default and makes */ | ||
578 | /* mounts take four times as long. */ | ||
579 | rtc_from4_mtd->flags |= MTD_NO_VIRTBLOCKS; | ||
580 | #endif | ||
581 | |||
582 | /* Register the partitions */ | ||
583 | ret = mtd_device_register(rtc_from4_mtd, partition_info, | ||
584 | NUM_PARTITIONS); | ||
585 | if (ret) | ||
586 | goto err_3; | ||
587 | |||
588 | /* Return happy */ | ||
589 | return 0; | ||
590 | err_3: | ||
591 | nand_release(rtc_from4_mtd); | ||
592 | err_2: | ||
593 | free_rs(rs_decoder); | ||
594 | err_1: | ||
595 | kfree(rtc_from4_mtd); | ||
596 | return ret; | ||
597 | } | ||
598 | |||
599 | module_init(rtc_from4_init); | ||
600 | |||
601 | /* | ||
602 | * Clean up routine | ||
603 | */ | ||
604 | static void __exit rtc_from4_cleanup(void) | ||
605 | { | ||
606 | /* Release resource, unregister partitions */ | ||
607 | nand_release(rtc_from4_mtd); | ||
608 | |||
609 | /* Free the MTD device structure */ | ||
610 | kfree(rtc_from4_mtd); | ||
611 | |||
612 | #ifdef RTC_FROM4_HWECC | ||
613 | /* Free the reed solomon resources */ | ||
614 | if (rs_decoder) { | ||
615 | free_rs(rs_decoder); | ||
616 | } | ||
617 | #endif | ||
618 | } | ||
619 | |||
620 | module_exit(rtc_from4_cleanup); | ||
621 | |||
622 | MODULE_LICENSE("GPL"); | ||
623 | MODULE_AUTHOR("d.marlin <dmarlin@redhat.com"); | ||
624 | MODULE_DESCRIPTION("Board-specific glue layer for AG-AND flash on Renesas FROM_BOARD4"); | ||
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c index 57b3971c9c0a..e57e18e8c289 100644 --- a/drivers/mtd/nand/sh_flctl.c +++ b/drivers/mtd/nand/sh_flctl.c | |||
@@ -1081,7 +1081,6 @@ static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev) | |||
1081 | return pdata; | 1081 | return pdata; |
1082 | } | 1082 | } |
1083 | #else /* CONFIG_OF */ | 1083 | #else /* CONFIG_OF */ |
1084 | #define of_flctl_match NULL | ||
1085 | static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev) | 1084 | static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev) |
1086 | { | 1085 | { |
1087 | return NULL; | 1086 | return NULL; |
@@ -1219,22 +1218,11 @@ static struct platform_driver flctl_driver = { | |||
1219 | .driver = { | 1218 | .driver = { |
1220 | .name = "sh_flctl", | 1219 | .name = "sh_flctl", |
1221 | .owner = THIS_MODULE, | 1220 | .owner = THIS_MODULE, |
1222 | .of_match_table = of_flctl_match, | 1221 | .of_match_table = of_match_ptr(of_flctl_match), |
1223 | }, | 1222 | }, |
1224 | }; | 1223 | }; |
1225 | 1224 | ||
1226 | static int __init flctl_nand_init(void) | 1225 | module_platform_driver_probe(flctl_driver, flctl_probe); |
1227 | { | ||
1228 | return platform_driver_probe(&flctl_driver, flctl_probe); | ||
1229 | } | ||
1230 | |||
1231 | static void __exit flctl_nand_cleanup(void) | ||
1232 | { | ||
1233 | platform_driver_unregister(&flctl_driver); | ||
1234 | } | ||
1235 | |||
1236 | module_init(flctl_nand_init); | ||
1237 | module_exit(flctl_nand_cleanup); | ||
1238 | 1226 | ||
1239 | MODULE_LICENSE("GPL"); | 1227 | MODULE_LICENSE("GPL"); |
1240 | MODULE_AUTHOR("Yoshihiro Shimoda"); | 1228 | MODULE_AUTHOR("Yoshihiro Shimoda"); |
diff --git a/drivers/mtd/nand/sm_common.c b/drivers/mtd/nand/sm_common.c index 082bcdcd6bcf..e8181edebddd 100644 --- a/drivers/mtd/nand/sm_common.c +++ b/drivers/mtd/nand/sm_common.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
10 | #include <linux/mtd/nand.h> | 10 | #include <linux/mtd/nand.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/sizes.h> | ||
12 | #include "sm_common.h" | 13 | #include "sm_common.h" |
13 | 14 | ||
14 | static struct nand_ecclayout nand_oob_sm = { | 15 | static struct nand_ecclayout nand_oob_sm = { |
@@ -67,44 +68,37 @@ static int sm_block_markbad(struct mtd_info *mtd, loff_t ofs) | |||
67 | return error; | 68 | return error; |
68 | } | 69 | } |
69 | 70 | ||
70 | |||
71 | static struct nand_flash_dev nand_smartmedia_flash_ids[] = { | 71 | static struct nand_flash_dev nand_smartmedia_flash_ids[] = { |
72 | {"SmartMedia 1MiB 5V", 0x6e, 256, 1, 0x1000, 0}, | 72 | LEGACY_ID_NAND("SmartMedia 2MiB 3,3V ROM", 0x5d, 2, SZ_8K, NAND_ROM), |
73 | {"SmartMedia 1MiB 3,3V", 0xe8, 256, 1, 0x1000, 0}, | 73 | LEGACY_ID_NAND("SmartMedia 4MiB 3,3V", 0xe3, 4, SZ_8K, 0), |
74 | {"SmartMedia 1MiB 3,3V", 0xec, 256, 1, 0x1000, 0}, | 74 | LEGACY_ID_NAND("SmartMedia 4MiB 3,3/5V", 0xe5, 4, SZ_8K, 0), |
75 | {"SmartMedia 2MiB 3,3V", 0xea, 256, 2, 0x1000, 0}, | 75 | LEGACY_ID_NAND("SmartMedia 4MiB 5V", 0x6b, 4, SZ_8K, 0), |
76 | {"SmartMedia 2MiB 5V", 0x64, 256, 2, 0x1000, 0}, | 76 | LEGACY_ID_NAND("SmartMedia 4MiB 3,3V ROM", 0xd5, 4, SZ_8K, NAND_ROM), |
77 | {"SmartMedia 2MiB 3,3V ROM", 0x5d, 512, 2, 0x2000, NAND_ROM}, | 77 | LEGACY_ID_NAND("SmartMedia 8MiB 3,3V", 0xe6, 8, SZ_8K, 0), |
78 | {"SmartMedia 4MiB 3,3V", 0xe3, 512, 4, 0x2000, 0}, | 78 | LEGACY_ID_NAND("SmartMedia 8MiB 3,3V ROM", 0xd6, 8, SZ_8K, NAND_ROM), |
79 | {"SmartMedia 4MiB 3,3/5V", 0xe5, 512, 4, 0x2000, 0}, | 79 | LEGACY_ID_NAND("SmartMedia 16MiB 3,3V", 0x73, 16, SZ_16K, 0), |
80 | {"SmartMedia 4MiB 5V", 0x6b, 512, 4, 0x2000, 0}, | 80 | LEGACY_ID_NAND("SmartMedia 16MiB 3,3V ROM", 0x57, 16, SZ_16K, NAND_ROM), |
81 | {"SmartMedia 4MiB 3,3V ROM", 0xd5, 512, 4, 0x2000, NAND_ROM}, | 81 | LEGACY_ID_NAND("SmartMedia 32MiB 3,3V", 0x75, 32, SZ_16K, 0), |
82 | {"SmartMedia 8MiB 3,3V", 0xe6, 512, 8, 0x2000, 0}, | 82 | LEGACY_ID_NAND("SmartMedia 32MiB 3,3V ROM", 0x58, 32, SZ_16K, NAND_ROM), |
83 | {"SmartMedia 8MiB 3,3V ROM", 0xd6, 512, 8, 0x2000, NAND_ROM}, | 83 | LEGACY_ID_NAND("SmartMedia 64MiB 3,3V", 0x76, 64, SZ_16K, 0), |
84 | {"SmartMedia 16MiB 3,3V", 0x73, 512, 16, 0x4000, 0}, | 84 | LEGACY_ID_NAND("SmartMedia 64MiB 3,3V ROM", 0xd9, 64, SZ_16K, NAND_ROM), |
85 | {"SmartMedia 16MiB 3,3V ROM", 0x57, 512, 16, 0x4000, NAND_ROM}, | 85 | LEGACY_ID_NAND("SmartMedia 128MiB 3,3V", 0x79, 128, SZ_16K, 0), |
86 | {"SmartMedia 32MiB 3,3V", 0x75, 512, 32, 0x4000, 0}, | 86 | LEGACY_ID_NAND("SmartMedia 128MiB 3,3V ROM", 0xda, 128, SZ_16K, NAND_ROM), |
87 | {"SmartMedia 32MiB 3,3V ROM", 0x58, 512, 32, 0x4000, NAND_ROM}, | 87 | LEGACY_ID_NAND("SmartMedia 256MiB 3, 3V", 0x71, 256, SZ_16K, 0), |
88 | {"SmartMedia 64MiB 3,3V", 0x76, 512, 64, 0x4000, 0}, | 88 | LEGACY_ID_NAND("SmartMedia 256MiB 3,3V ROM", 0x5b, 256, SZ_16K, NAND_ROM), |
89 | {"SmartMedia 64MiB 3,3V ROM", 0xd9, 512, 64, 0x4000, NAND_ROM}, | 89 | {NULL} |
90 | {"SmartMedia 128MiB 3,3V", 0x79, 512, 128, 0x4000, 0}, | ||
91 | {"SmartMedia 128MiB 3,3V ROM", 0xda, 512, 128, 0x4000, NAND_ROM}, | ||
92 | {"SmartMedia 256MiB 3,3V", 0x71, 512, 256, 0x4000 }, | ||
93 | {"SmartMedia 256MiB 3,3V ROM", 0x5b, 512, 256, 0x4000, NAND_ROM}, | ||
94 | {NULL,} | ||
95 | }; | 90 | }; |
96 | 91 | ||
97 | static struct nand_flash_dev nand_xd_flash_ids[] = { | 92 | static struct nand_flash_dev nand_xd_flash_ids[] = { |
98 | 93 | LEGACY_ID_NAND("xD 16MiB 3,3V", 0x73, 16, SZ_16K, 0), | |
99 | {"xD 16MiB 3,3V", 0x73, 512, 16, 0x4000, 0}, | 94 | LEGACY_ID_NAND("xD 32MiB 3,3V", 0x75, 32, SZ_16K, 0), |
100 | {"xD 32MiB 3,3V", 0x75, 512, 32, 0x4000, 0}, | 95 | LEGACY_ID_NAND("xD 64MiB 3,3V", 0x76, 64, SZ_16K, 0), |
101 | {"xD 64MiB 3,3V", 0x76, 512, 64, 0x4000, 0}, | 96 | LEGACY_ID_NAND("xD 128MiB 3,3V", 0x79, 128, SZ_16K, 0), |
102 | {"xD 128MiB 3,3V", 0x79, 512, 128, 0x4000, 0}, | 97 | LEGACY_ID_NAND("xD 256MiB 3,3V", 0x71, 256, SZ_16K, NAND_BROKEN_XD), |
103 | {"xD 256MiB 3,3V", 0x71, 512, 256, 0x4000, NAND_BROKEN_XD}, | 98 | LEGACY_ID_NAND("xD 512MiB 3,3V", 0xdc, 512, SZ_16K, NAND_BROKEN_XD), |
104 | {"xD 512MiB 3,3V", 0xdc, 512, 512, 0x4000, NAND_BROKEN_XD}, | 99 | LEGACY_ID_NAND("xD 1GiB 3,3V", 0xd3, 1024, SZ_16K, NAND_BROKEN_XD), |
105 | {"xD 1GiB 3,3V", 0xd3, 512, 1024, 0x4000, NAND_BROKEN_XD}, | 100 | LEGACY_ID_NAND("xD 2GiB 3,3V", 0xd5, 2048, SZ_16K, NAND_BROKEN_XD), |
106 | {"xD 2GiB 3,3V", 0xd5, 512, 2048, 0x4000, NAND_BROKEN_XD}, | 101 | {NULL} |
107 | {NULL,} | ||
108 | }; | 102 | }; |
109 | 103 | ||
110 | int sm_register_device(struct mtd_info *mtd, int smartmedia) | 104 | int sm_register_device(struct mtd_info *mtd, int smartmedia) |
diff --git a/drivers/mtd/nand/txx9ndfmc.c b/drivers/mtd/nand/txx9ndfmc.c index e1e8748aa47b..7ed654c68b08 100644 --- a/drivers/mtd/nand/txx9ndfmc.c +++ b/drivers/mtd/nand/txx9ndfmc.c | |||
@@ -427,18 +427,7 @@ static struct platform_driver txx9ndfmc_driver = { | |||
427 | }, | 427 | }, |
428 | }; | 428 | }; |
429 | 429 | ||
430 | static int __init txx9ndfmc_init(void) | 430 | module_platform_driver_probe(txx9ndfmc_driver, txx9ndfmc_probe); |
431 | { | ||
432 | return platform_driver_probe(&txx9ndfmc_driver, txx9ndfmc_probe); | ||
433 | } | ||
434 | |||
435 | static void __exit txx9ndfmc_exit(void) | ||
436 | { | ||
437 | platform_driver_unregister(&txx9ndfmc_driver); | ||
438 | } | ||
439 | |||
440 | module_init(txx9ndfmc_init); | ||
441 | module_exit(txx9ndfmc_exit); | ||
442 | 431 | ||
443 | MODULE_LICENSE("GPL"); | 432 | MODULE_LICENSE("GPL"); |
444 | MODULE_DESCRIPTION("TXx9 SoC NAND flash controller driver"); | 433 | MODULE_DESCRIPTION("TXx9 SoC NAND flash controller driver"); |