diff options
author | Brian Norris <computersforpeace@gmail.com> | 2016-11-29 21:28:30 -0500 |
---|---|---|
committer | Brian Norris <computersforpeace@gmail.com> | 2016-11-29 21:28:30 -0500 |
commit | 0989b0909c1f86b8a4a76c0bee101cd017c4e259 (patch) | |
tree | e12d6ba197340410a94b7a2c476d5549d4f6b90e | |
parent | b2c4ba5cf712fede57dd3e15922ae647dde55a82 (diff) | |
parent | 8fcfba072420518fda4b2fe00a3f3c9c3e2774e2 (diff) |
Merge tag 'nand/for-4.10' of github.com:linux-nand/linux
From Boris Brezillon:
"""
This pull request contains the following notable changes:
- new tango NAND controller driver
- new ox820 NAND controller driver
- addition of a new full-ID entry in the nand_ids table
- rework of the s3c240 driver to support DT
- extension of the nand_sdr_timings to expose tCCS, tPROG and tR
- addition of a new flag to ask the core to wait for tCCS when sending
a RNDIN/RNDOUT command
- addition of a new flag to ask the core to let the controller driver
send the READ/PROGPAGE command
This pull request also contains minor fixes/cleanup/cosmetic changes:
- properly support 512 ECC step size in the sunxi driver
- improve the error messages in the pxa probe path
- fix module autoload in the omap2 driver
- cleanup of several nand drivers to return nand_scan{_tail}() error
code instead of returning -EIO
- various cleanups in the denali driver
- cleanups in the ooblayout handling (MTD core)
- fix an error check in nandsim
"""
57 files changed, 1477 insertions, 319 deletions
diff --git a/Documentation/devicetree/bindings/mtd/oxnas-nand.txt b/Documentation/devicetree/bindings/mtd/oxnas-nand.txt new file mode 100644 index 000000000000..56d5c19da41d --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/oxnas-nand.txt | |||
@@ -0,0 +1,41 @@ | |||
1 | * Oxford Semiconductor OXNAS NAND Controller | ||
2 | |||
3 | Please refer to nand.txt for generic information regarding MTD NAND bindings. | ||
4 | |||
5 | Required properties: | ||
6 | - compatible: "oxsemi,ox820-nand" | ||
7 | - reg: Base address and length for NAND mapped memory. | ||
8 | |||
9 | Optional Properties: | ||
10 | - clocks: phandle to the NAND gate clock if needed. | ||
11 | - resets: phandle to the NAND reset control if needed. | ||
12 | |||
13 | Example: | ||
14 | |||
15 | nandc: nand-controller@41000000 { | ||
16 | compatible = "oxsemi,ox820-nand"; | ||
17 | reg = <0x41000000 0x100000>; | ||
18 | clocks = <&stdclk CLK_820_NAND>; | ||
19 | resets = <&reset RESET_NAND>; | ||
20 | #address-cells = <1>; | ||
21 | #size-cells = <0>; | ||
22 | |||
23 | nand@0 { | ||
24 | reg = <0>; | ||
25 | #address-cells = <1>; | ||
26 | #size-cells = <1>; | ||
27 | nand-ecc-mode = "soft"; | ||
28 | nand-ecc-algo = "hamming"; | ||
29 | |||
30 | partition@0 { | ||
31 | label = "boot"; | ||
32 | reg = <0x00000000 0x00e00000>; | ||
33 | read-only; | ||
34 | }; | ||
35 | |||
36 | partition@e00000 { | ||
37 | label = "ubi"; | ||
38 | reg = <0x00e00000 0x07200000>; | ||
39 | }; | ||
40 | }; | ||
41 | }; | ||
diff --git a/Documentation/devicetree/bindings/mtd/samsung-s3c2410.txt b/Documentation/devicetree/bindings/mtd/samsung-s3c2410.txt new file mode 100644 index 000000000000..0040eb8895e0 --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/samsung-s3c2410.txt | |||
@@ -0,0 +1,56 @@ | |||
1 | * Samsung S3C2410 and compatible NAND flash controller | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : The possible values are: | ||
5 | "samsung,s3c2410-nand" | ||
6 | "samsung,s3c2412-nand" | ||
7 | "samsung,s3c2440-nand" | ||
8 | - reg : register's location and length. | ||
9 | - #address-cells, #size-cells : see nand.txt | ||
10 | - clocks : phandle to the nand controller clock | ||
11 | - clock-names : must contain "nand" | ||
12 | |||
13 | Optional child nodes: | ||
14 | Child nodes representing the available nand chips. | ||
15 | |||
16 | Optional child properties: | ||
17 | - nand-ecc-mode : see nand.txt | ||
18 | - nand-on-flash-bbt : see nand.txt | ||
19 | |||
20 | Each child device node may optionally contain a 'partitions' sub-node, | ||
21 | which further contains sub-nodes describing the flash partition mapping. | ||
22 | See partition.txt for more detail. | ||
23 | |||
24 | Example: | ||
25 | |||
26 | nand-controller@4e000000 { | ||
27 | compatible = "samsung,s3c2440-nand"; | ||
28 | reg = <0x4e000000 0x40>; | ||
29 | |||
30 | #address-cells = <1>; | ||
31 | #size-cells = <0>; | ||
32 | |||
33 | clocks = <&clocks HCLK_NAND>; | ||
34 | clock-names = "nand"; | ||
35 | |||
36 | nand { | ||
37 | nand-ecc-mode = "soft"; | ||
38 | nand-on-flash-bbt; | ||
39 | |||
40 | partitions { | ||
41 | compatible = "fixed-partitions"; | ||
42 | #address-cells = <1>; | ||
43 | #size-cells = <1>; | ||
44 | |||
45 | partition@0 { | ||
46 | label = "u-boot"; | ||
47 | reg = <0 0x040000>; | ||
48 | }; | ||
49 | |||
50 | partition@40000 { | ||
51 | label = "kernel"; | ||
52 | reg = <0x040000 0x500000>; | ||
53 | }; | ||
54 | }; | ||
55 | }; | ||
56 | }; | ||
diff --git a/Documentation/devicetree/bindings/mtd/tango-nand.txt b/Documentation/devicetree/bindings/mtd/tango-nand.txt new file mode 100644 index 000000000000..ad5a02f2ac8c --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/tango-nand.txt | |||
@@ -0,0 +1,38 @@ | |||
1 | Sigma Designs Tango4 NAND Flash Controller (NFC) | ||
2 | |||
3 | Required properties: | ||
4 | |||
5 | - compatible: "sigma,smp8758-nand" | ||
6 | - reg: address/size of nfc_reg, nfc_mem, and pbus_reg | ||
7 | - dmas: reference to the DMA channel used by the controller | ||
8 | - dma-names: "nfc_sbox" | ||
9 | - clocks: reference to the system clock | ||
10 | - #address-cells: <1> | ||
11 | - #size-cells: <0> | ||
12 | |||
13 | Children nodes represent the available NAND chips. | ||
14 | See Documentation/devicetree/bindings/mtd/nand.txt for generic bindings. | ||
15 | |||
16 | Example: | ||
17 | |||
18 | nandc: nand-controller@2c000 { | ||
19 | compatible = "sigma,smp8758-nand"; | ||
20 | reg = <0x2c000 0x30 0x2d000 0x800 0x20000 0x1000>; | ||
21 | dmas = <&dma0 3>; | ||
22 | dma-names = "nfc_sbox"; | ||
23 | clocks = <&clkgen SYS_CLK>; | ||
24 | #address-cells = <1>; | ||
25 | #size-cells = <0>; | ||
26 | |||
27 | nand@0 { | ||
28 | reg = <0>; /* CS0 */ | ||
29 | nand-ecc-strength = <14>; | ||
30 | nand-ecc-step-size = <1024>; | ||
31 | }; | ||
32 | |||
33 | nand@1 { | ||
34 | reg = <1>; /* CS1 */ | ||
35 | nand-ecc-strength = <14>; | ||
36 | nand-ecc-step-size = <1024>; | ||
37 | }; | ||
38 | }; | ||
diff --git a/arch/arm/mach-s3c24xx/common-smdk.c b/arch/arm/mach-s3c24xx/common-smdk.c index e9fbcc91c5c0..9e0bc46e90ec 100644 --- a/arch/arm/mach-s3c24xx/common-smdk.c +++ b/arch/arm/mach-s3c24xx/common-smdk.c | |||
@@ -171,6 +171,7 @@ static struct s3c2410_platform_nand smdk_nand_info = { | |||
171 | .twrph1 = 20, | 171 | .twrph1 = 20, |
172 | .nr_sets = ARRAY_SIZE(smdk_nand_sets), | 172 | .nr_sets = ARRAY_SIZE(smdk_nand_sets), |
173 | .sets = smdk_nand_sets, | 173 | .sets = smdk_nand_sets, |
174 | .ecc_mode = NAND_ECC_SOFT, | ||
174 | }; | 175 | }; |
175 | 176 | ||
176 | /* devices we initialise */ | 177 | /* devices we initialise */ |
diff --git a/arch/arm/mach-s3c24xx/mach-anubis.c b/arch/arm/mach-s3c24xx/mach-anubis.c index d03df0df01fa..029ef1b58925 100644 --- a/arch/arm/mach-s3c24xx/mach-anubis.c +++ b/arch/arm/mach-s3c24xx/mach-anubis.c | |||
@@ -223,6 +223,7 @@ static struct s3c2410_platform_nand __initdata anubis_nand_info = { | |||
223 | .nr_sets = ARRAY_SIZE(anubis_nand_sets), | 223 | .nr_sets = ARRAY_SIZE(anubis_nand_sets), |
224 | .sets = anubis_nand_sets, | 224 | .sets = anubis_nand_sets, |
225 | .select_chip = anubis_nand_select, | 225 | .select_chip = anubis_nand_select, |
226 | .ecc_mode = NAND_ECC_SOFT, | ||
226 | }; | 227 | }; |
227 | 228 | ||
228 | /* IDE channels */ | 229 | /* IDE channels */ |
diff --git a/arch/arm/mach-s3c24xx/mach-at2440evb.c b/arch/arm/mach-s3c24xx/mach-at2440evb.c index 9ae170fef2a7..7b28eb623fc1 100644 --- a/arch/arm/mach-s3c24xx/mach-at2440evb.c +++ b/arch/arm/mach-s3c24xx/mach-at2440evb.c | |||
@@ -114,6 +114,7 @@ static struct s3c2410_platform_nand __initdata at2440evb_nand_info = { | |||
114 | .twrph1 = 40, | 114 | .twrph1 = 40, |
115 | .nr_sets = ARRAY_SIZE(at2440evb_nand_sets), | 115 | .nr_sets = ARRAY_SIZE(at2440evb_nand_sets), |
116 | .sets = at2440evb_nand_sets, | 116 | .sets = at2440evb_nand_sets, |
117 | .ecc_mode = NAND_ECC_SOFT, | ||
117 | }; | 118 | }; |
118 | 119 | ||
119 | /* DM9000AEP 10/100 ethernet controller */ | 120 | /* DM9000AEP 10/100 ethernet controller */ |
diff --git a/arch/arm/mach-s3c24xx/mach-bast.c b/arch/arm/mach-s3c24xx/mach-bast.c index ed07cf392d4b..5185036765db 100644 --- a/arch/arm/mach-s3c24xx/mach-bast.c +++ b/arch/arm/mach-s3c24xx/mach-bast.c | |||
@@ -299,6 +299,7 @@ static struct s3c2410_platform_nand __initdata bast_nand_info = { | |||
299 | .nr_sets = ARRAY_SIZE(bast_nand_sets), | 299 | .nr_sets = ARRAY_SIZE(bast_nand_sets), |
300 | .sets = bast_nand_sets, | 300 | .sets = bast_nand_sets, |
301 | .select_chip = bast_nand_select, | 301 | .select_chip = bast_nand_select, |
302 | .ecc_mode = NAND_ECC_SOFT, | ||
302 | }; | 303 | }; |
303 | 304 | ||
304 | /* DM9000 */ | 305 | /* DM9000 */ |
diff --git a/arch/arm/mach-s3c24xx/mach-gta02.c b/arch/arm/mach-s3c24xx/mach-gta02.c index 27ae6877550f..b0ed401da3a3 100644 --- a/arch/arm/mach-s3c24xx/mach-gta02.c +++ b/arch/arm/mach-s3c24xx/mach-gta02.c | |||
@@ -443,6 +443,7 @@ static struct s3c2410_platform_nand __initdata gta02_nand_info = { | |||
443 | .twrph1 = 15, | 443 | .twrph1 = 15, |
444 | .nr_sets = ARRAY_SIZE(gta02_nand_sets), | 444 | .nr_sets = ARRAY_SIZE(gta02_nand_sets), |
445 | .sets = gta02_nand_sets, | 445 | .sets = gta02_nand_sets, |
446 | .ecc_mode = NAND_ECC_SOFT, | ||
446 | }; | 447 | }; |
447 | 448 | ||
448 | 449 | ||
diff --git a/arch/arm/mach-s3c24xx/mach-jive.c b/arch/arm/mach-s3c24xx/mach-jive.c index 7d99fe8f6157..895aca225952 100644 --- a/arch/arm/mach-s3c24xx/mach-jive.c +++ b/arch/arm/mach-s3c24xx/mach-jive.c | |||
@@ -232,6 +232,7 @@ static struct s3c2410_platform_nand __initdata jive_nand_info = { | |||
232 | .twrph1 = 40, | 232 | .twrph1 = 40, |
233 | .sets = jive_nand_sets, | 233 | .sets = jive_nand_sets, |
234 | .nr_sets = ARRAY_SIZE(jive_nand_sets), | 234 | .nr_sets = ARRAY_SIZE(jive_nand_sets), |
235 | .ecc_mode = NAND_ECC_SOFT, | ||
235 | }; | 236 | }; |
236 | 237 | ||
237 | static int __init jive_mtdset(char *options) | 238 | static int __init jive_mtdset(char *options) |
diff --git a/arch/arm/mach-s3c24xx/mach-mini2440.c b/arch/arm/mach-s3c24xx/mach-mini2440.c index ec60bd4a1646..71af8d2fd320 100644 --- a/arch/arm/mach-s3c24xx/mach-mini2440.c +++ b/arch/arm/mach-s3c24xx/mach-mini2440.c | |||
@@ -287,6 +287,7 @@ static struct s3c2410_platform_nand mini2440_nand_info __initdata = { | |||
287 | .nr_sets = ARRAY_SIZE(mini2440_nand_sets), | 287 | .nr_sets = ARRAY_SIZE(mini2440_nand_sets), |
288 | .sets = mini2440_nand_sets, | 288 | .sets = mini2440_nand_sets, |
289 | .ignore_unset_ecc = 1, | 289 | .ignore_unset_ecc = 1, |
290 | .ecc_mode = NAND_ECC_SOFT, | ||
290 | }; | 291 | }; |
291 | 292 | ||
292 | /* DM9000AEP 10/100 ethernet controller */ | 293 | /* DM9000AEP 10/100 ethernet controller */ |
diff --git a/arch/arm/mach-s3c24xx/mach-osiris.c b/arch/arm/mach-s3c24xx/mach-osiris.c index 2f6fdc326835..70b0eb7d3134 100644 --- a/arch/arm/mach-s3c24xx/mach-osiris.c +++ b/arch/arm/mach-s3c24xx/mach-osiris.c | |||
@@ -238,6 +238,7 @@ static struct s3c2410_platform_nand __initdata osiris_nand_info = { | |||
238 | .nr_sets = ARRAY_SIZE(osiris_nand_sets), | 238 | .nr_sets = ARRAY_SIZE(osiris_nand_sets), |
239 | .sets = osiris_nand_sets, | 239 | .sets = osiris_nand_sets, |
240 | .select_chip = osiris_nand_select, | 240 | .select_chip = osiris_nand_select, |
241 | .ecc_mode = NAND_ECC_SOFT, | ||
241 | }; | 242 | }; |
242 | 243 | ||
243 | /* PCMCIA control and configuration */ | 244 | /* PCMCIA control and configuration */ |
diff --git a/arch/arm/mach-s3c24xx/mach-qt2410.c b/arch/arm/mach-s3c24xx/mach-qt2410.c index 984516e8307a..868c82087403 100644 --- a/arch/arm/mach-s3c24xx/mach-qt2410.c +++ b/arch/arm/mach-s3c24xx/mach-qt2410.c | |||
@@ -284,6 +284,7 @@ static struct s3c2410_platform_nand __initdata qt2410_nand_info = { | |||
284 | .twrph1 = 20, | 284 | .twrph1 = 20, |
285 | .nr_sets = ARRAY_SIZE(qt2410_nand_sets), | 285 | .nr_sets = ARRAY_SIZE(qt2410_nand_sets), |
286 | .sets = qt2410_nand_sets, | 286 | .sets = qt2410_nand_sets, |
287 | .ecc_mode = NAND_ECC_SOFT, | ||
287 | }; | 288 | }; |
288 | 289 | ||
289 | /* UDC */ | 290 | /* UDC */ |
diff --git a/arch/arm/mach-s3c24xx/mach-rx1950.c b/arch/arm/mach-s3c24xx/mach-rx1950.c index 25a139bb9826..e86ad6a68a0b 100644 --- a/arch/arm/mach-s3c24xx/mach-rx1950.c +++ b/arch/arm/mach-s3c24xx/mach-rx1950.c | |||
@@ -611,6 +611,7 @@ static struct s3c2410_platform_nand rx1950_nand_info = { | |||
611 | .twrph1 = 15, | 611 | .twrph1 = 15, |
612 | .nr_sets = ARRAY_SIZE(rx1950_nand_sets), | 612 | .nr_sets = ARRAY_SIZE(rx1950_nand_sets), |
613 | .sets = rx1950_nand_sets, | 613 | .sets = rx1950_nand_sets, |
614 | .ecc_mode = NAND_ECC_SOFT, | ||
614 | }; | 615 | }; |
615 | 616 | ||
616 | static struct s3c2410_udc_mach_info rx1950_udc_cfg __initdata = { | 617 | static struct s3c2410_udc_mach_info rx1950_udc_cfg __initdata = { |
diff --git a/arch/arm/mach-s3c24xx/mach-rx3715.c b/arch/arm/mach-s3c24xx/mach-rx3715.c index cf55196f89ca..a39fb9780dd3 100644 --- a/arch/arm/mach-s3c24xx/mach-rx3715.c +++ b/arch/arm/mach-s3c24xx/mach-rx3715.c | |||
@@ -164,6 +164,7 @@ static struct s3c2410_platform_nand __initdata rx3715_nand_info = { | |||
164 | .twrph1 = 15, | 164 | .twrph1 = 15, |
165 | .nr_sets = ARRAY_SIZE(rx3715_nand_sets), | 165 | .nr_sets = ARRAY_SIZE(rx3715_nand_sets), |
166 | .sets = rx3715_nand_sets, | 166 | .sets = rx3715_nand_sets, |
167 | .ecc_mode = NAND_ECC_SOFT, | ||
167 | }; | 168 | }; |
168 | 169 | ||
169 | static struct platform_device *rx3715_devices[] __initdata = { | 170 | static struct platform_device *rx3715_devices[] __initdata = { |
diff --git a/arch/arm/mach-s3c24xx/mach-vstms.c b/arch/arm/mach-s3c24xx/mach-vstms.c index b4460d5f7011..f5e6322145fa 100644 --- a/arch/arm/mach-s3c24xx/mach-vstms.c +++ b/arch/arm/mach-s3c24xx/mach-vstms.c | |||
@@ -117,6 +117,7 @@ static struct s3c2410_platform_nand __initdata vstms_nand_info = { | |||
117 | .twrph1 = 20, | 117 | .twrph1 = 20, |
118 | .nr_sets = ARRAY_SIZE(vstms_nand_sets), | 118 | .nr_sets = ARRAY_SIZE(vstms_nand_sets), |
119 | .sets = vstms_nand_sets, | 119 | .sets = vstms_nand_sets, |
120 | .ecc_mode = NAND_ECC_SOFT, | ||
120 | }; | 121 | }; |
121 | 122 | ||
122 | static struct platform_device *vstms_devices[] __initdata = { | 123 | static struct platform_device *vstms_devices[] __initdata = { |
diff --git a/arch/arm/mach-s3c64xx/mach-hmt.c b/arch/arm/mach-s3c64xx/mach-hmt.c index bc7dc1fcbf7d..59b5531f1987 100644 --- a/arch/arm/mach-s3c64xx/mach-hmt.c +++ b/arch/arm/mach-s3c64xx/mach-hmt.c | |||
@@ -204,6 +204,7 @@ static struct s3c2410_platform_nand hmt_nand_info = { | |||
204 | .twrph1 = 40, | 204 | .twrph1 = 40, |
205 | .nr_sets = ARRAY_SIZE(hmt_nand_sets), | 205 | .nr_sets = ARRAY_SIZE(hmt_nand_sets), |
206 | .sets = hmt_nand_sets, | 206 | .sets = hmt_nand_sets, |
207 | .ecc_mode = NAND_ECC_SOFT, | ||
207 | }; | 208 | }; |
208 | 209 | ||
209 | static struct gpio_led hmt_leds[] = { | 210 | static struct gpio_led hmt_leds[] = { |
diff --git a/arch/arm/mach-s3c64xx/mach-mini6410.c b/arch/arm/mach-s3c64xx/mach-mini6410.c index ae999fb3fe6d..a3e3e25728b4 100644 --- a/arch/arm/mach-s3c64xx/mach-mini6410.c +++ b/arch/arm/mach-s3c64xx/mach-mini6410.c | |||
@@ -142,6 +142,7 @@ static struct s3c2410_platform_nand mini6410_nand_info = { | |||
142 | .twrph1 = 40, | 142 | .twrph1 = 40, |
143 | .nr_sets = ARRAY_SIZE(mini6410_nand_sets), | 143 | .nr_sets = ARRAY_SIZE(mini6410_nand_sets), |
144 | .sets = mini6410_nand_sets, | 144 | .sets = mini6410_nand_sets, |
145 | .ecc_mode = NAND_ECC_SOFT, | ||
145 | }; | 146 | }; |
146 | 147 | ||
147 | static struct s3c_fb_pd_win mini6410_lcd_type0_fb_win = { | 148 | static struct s3c_fb_pd_win mini6410_lcd_type0_fb_win = { |
diff --git a/arch/arm/mach-s3c64xx/mach-real6410.c b/arch/arm/mach-s3c64xx/mach-real6410.c index 4e240ffa7ac7..d6b3ffd7704b 100644 --- a/arch/arm/mach-s3c64xx/mach-real6410.c +++ b/arch/arm/mach-s3c64xx/mach-real6410.c | |||
@@ -194,6 +194,7 @@ static struct s3c2410_platform_nand real6410_nand_info = { | |||
194 | .twrph1 = 40, | 194 | .twrph1 = 40, |
195 | .nr_sets = ARRAY_SIZE(real6410_nand_sets), | 195 | .nr_sets = ARRAY_SIZE(real6410_nand_sets), |
196 | .sets = real6410_nand_sets, | 196 | .sets = real6410_nand_sets, |
197 | .ecc_mode = NAND_ECC_SOFT, | ||
197 | }; | 198 | }; |
198 | 199 | ||
199 | static struct platform_device *real6410_devices[] __initdata = { | 200 | static struct platform_device *real6410_devices[] __initdata = { |
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index d46e4adf6d2b..ca661cee9b77 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c | |||
@@ -1274,8 +1274,8 @@ static int mtd_ooblayout_get_bytes(struct mtd_info *mtd, u8 *buf, | |||
1274 | int section, | 1274 | int section, |
1275 | struct mtd_oob_region *oobregion)) | 1275 | struct mtd_oob_region *oobregion)) |
1276 | { | 1276 | { |
1277 | struct mtd_oob_region oobregion = { }; | 1277 | struct mtd_oob_region oobregion; |
1278 | int section = 0, ret; | 1278 | int section, ret; |
1279 | 1279 | ||
1280 | ret = mtd_ooblayout_find_region(mtd, start, §ion, | 1280 | ret = mtd_ooblayout_find_region(mtd, start, §ion, |
1281 | &oobregion, iter); | 1281 | &oobregion, iter); |
@@ -1283,7 +1283,7 @@ static int mtd_ooblayout_get_bytes(struct mtd_info *mtd, u8 *buf, | |||
1283 | while (!ret) { | 1283 | while (!ret) { |
1284 | int cnt; | 1284 | int cnt; |
1285 | 1285 | ||
1286 | cnt = oobregion.length > nbytes ? nbytes : oobregion.length; | 1286 | cnt = min_t(int, nbytes, oobregion.length); |
1287 | memcpy(buf, oobbuf + oobregion.offset, cnt); | 1287 | memcpy(buf, oobbuf + oobregion.offset, cnt); |
1288 | buf += cnt; | 1288 | buf += cnt; |
1289 | nbytes -= cnt; | 1289 | nbytes -= cnt; |
@@ -1317,8 +1317,8 @@ static int mtd_ooblayout_set_bytes(struct mtd_info *mtd, const u8 *buf, | |||
1317 | int section, | 1317 | int section, |
1318 | struct mtd_oob_region *oobregion)) | 1318 | struct mtd_oob_region *oobregion)) |
1319 | { | 1319 | { |
1320 | struct mtd_oob_region oobregion = { }; | 1320 | struct mtd_oob_region oobregion; |
1321 | int section = 0, ret; | 1321 | int section, ret; |
1322 | 1322 | ||
1323 | ret = mtd_ooblayout_find_region(mtd, start, §ion, | 1323 | ret = mtd_ooblayout_find_region(mtd, start, §ion, |
1324 | &oobregion, iter); | 1324 | &oobregion, iter); |
@@ -1326,7 +1326,7 @@ static int mtd_ooblayout_set_bytes(struct mtd_info *mtd, const u8 *buf, | |||
1326 | while (!ret) { | 1326 | while (!ret) { |
1327 | int cnt; | 1327 | int cnt; |
1328 | 1328 | ||
1329 | cnt = oobregion.length > nbytes ? nbytes : oobregion.length; | 1329 | cnt = min_t(int, nbytes, oobregion.length); |
1330 | memcpy(oobbuf + oobregion.offset, buf, cnt); | 1330 | memcpy(oobbuf + oobregion.offset, buf, cnt); |
1331 | buf += cnt; | 1331 | buf += cnt; |
1332 | nbytes -= cnt; | 1332 | nbytes -= cnt; |
@@ -1354,7 +1354,7 @@ static int mtd_ooblayout_count_bytes(struct mtd_info *mtd, | |||
1354 | int section, | 1354 | int section, |
1355 | struct mtd_oob_region *oobregion)) | 1355 | struct mtd_oob_region *oobregion)) |
1356 | { | 1356 | { |
1357 | struct mtd_oob_region oobregion = { }; | 1357 | struct mtd_oob_region oobregion; |
1358 | int section = 0, ret, nbytes = 0; | 1358 | int section = 0, ret, nbytes = 0; |
1359 | 1359 | ||
1360 | while (1) { | 1360 | while (1) { |
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 7b7a887b4709..353a9ddf6b97 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
@@ -179,15 +179,6 @@ config MTD_NAND_S3C2410_DEBUG | |||
179 | help | 179 | help |
180 | Enable debugging of the S3C NAND driver | 180 | Enable debugging of the S3C NAND driver |
181 | 181 | ||
182 | config MTD_NAND_S3C2410_HWECC | ||
183 | bool "Samsung S3C NAND Hardware ECC" | ||
184 | depends on MTD_NAND_S3C2410 | ||
185 | help | ||
186 | Enable the use of the controller's internal ECC generator when | ||
187 | using NAND. Early versions of the chips have had problems with | ||
188 | incorrect ECC generation, and if using these, the default of | ||
189 | software ECC is preferable. | ||
190 | |||
191 | config MTD_NAND_NDFC | 182 | config MTD_NAND_NDFC |
192 | tristate "NDFC NanD Flash Controller" | 183 | tristate "NDFC NanD Flash Controller" |
193 | depends on 4xx | 184 | depends on 4xx |
@@ -205,6 +196,13 @@ config MTD_NAND_S3C2410_CLKSTOP | |||
205 | when the is NAND chip selected or released, but will save | 196 | when the is NAND chip selected or released, but will save |
206 | approximately 5mA of power when there is nothing happening. | 197 | approximately 5mA of power when there is nothing happening. |
207 | 198 | ||
199 | config MTD_NAND_TANGO | ||
200 | tristate "NAND Flash support for Tango chips" | ||
201 | depends on ARCH_TANGO || COMPILE_TEST | ||
202 | depends on HAS_DMA | ||
203 | help | ||
204 | Enables the NAND Flash controller on Tango chips. | ||
205 | |||
208 | config MTD_NAND_DISKONCHIP | 206 | config MTD_NAND_DISKONCHIP |
209 | tristate "DiskOnChip 2000, Millennium and Millennium Plus (NAND reimplementation)" | 207 | tristate "DiskOnChip 2000, Millennium and Millennium Plus (NAND reimplementation)" |
210 | depends on HAS_IOMEM | 208 | depends on HAS_IOMEM |
@@ -426,6 +424,11 @@ config MTD_NAND_ORION | |||
426 | No board specific support is done by this driver, each board | 424 | No board specific support is done by this driver, each board |
427 | must advertise a platform_device for the driver to attach. | 425 | must advertise a platform_device for the driver to attach. |
428 | 426 | ||
427 | config MTD_NAND_OXNAS | ||
428 | tristate "NAND Flash support for Oxford Semiconductor SoC" | ||
429 | help | ||
430 | This enables the NAND flash controller on Oxford Semiconductor SoCs. | ||
431 | |||
429 | config MTD_NAND_FSL_ELBC | 432 | config MTD_NAND_FSL_ELBC |
430 | tristate "NAND support for Freescale eLBC controllers" | 433 | tristate "NAND support for Freescale eLBC controllers" |
431 | depends on FSL_SOC | 434 | depends on FSL_SOC |
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index cafde6f3d957..19a66e404d5b 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile | |||
@@ -16,6 +16,7 @@ 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_S3C2410) += s3c2410.o | 18 | obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o |
19 | obj-$(CONFIG_MTD_NAND_TANGO) += tango_nand.o | ||
19 | obj-$(CONFIG_MTD_NAND_DAVINCI) += davinci_nand.o | 20 | obj-$(CONFIG_MTD_NAND_DAVINCI) += davinci_nand.o |
20 | obj-$(CONFIG_MTD_NAND_DISKONCHIP) += diskonchip.o | 21 | obj-$(CONFIG_MTD_NAND_DISKONCHIP) += diskonchip.o |
21 | obj-$(CONFIG_MTD_NAND_DOCG4) += docg4.o | 22 | obj-$(CONFIG_MTD_NAND_DOCG4) += docg4.o |
@@ -35,6 +36,7 @@ obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o | |||
35 | obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o | 36 | obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o |
36 | obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o | 37 | obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o |
37 | obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o | 38 | obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o |
39 | obj-$(CONFIG_MTD_NAND_OXNAS) += oxnas_nand.o | ||
38 | obj-$(CONFIG_MTD_NAND_FSL_ELBC) += fsl_elbc_nand.o | 40 | obj-$(CONFIG_MTD_NAND_FSL_ELBC) += fsl_elbc_nand.o |
39 | obj-$(CONFIG_MTD_NAND_FSL_IFC) += fsl_ifc_nand.o | 41 | obj-$(CONFIG_MTD_NAND_FSL_IFC) += fsl_ifc_nand.o |
40 | obj-$(CONFIG_MTD_NAND_FSL_UPM) += fsl_upm.o | 42 | obj-$(CONFIG_MTD_NAND_FSL_UPM) += fsl_upm.o |
diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c index 78e12cc8bac2..5d6c26f3cf7f 100644 --- a/drivers/mtd/nand/ams-delta.c +++ b/drivers/mtd/nand/ams-delta.c | |||
@@ -234,10 +234,9 @@ static int ams_delta_init(struct platform_device *pdev) | |||
234 | goto out_gpio; | 234 | goto out_gpio; |
235 | 235 | ||
236 | /* Scan to find existence of the device */ | 236 | /* Scan to find existence of the device */ |
237 | if (nand_scan(ams_delta_mtd, 1)) { | 237 | err = nand_scan(ams_delta_mtd, 1); |
238 | err = -ENXIO; | 238 | if (err) |
239 | goto out_mtd; | 239 | goto out_mtd; |
240 | } | ||
241 | 240 | ||
242 | /* Register the partitions */ | 241 | /* Register the partitions */ |
243 | mtd_device_register(ams_delta_mtd, partition_info, | 242 | mtd_device_register(ams_delta_mtd, partition_info, |
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 68b9160108c9..9ebd5ecefea6 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c | |||
@@ -2267,10 +2267,9 @@ static int atmel_nand_probe(struct platform_device *pdev) | |||
2267 | dev_info(host->dev, "No DMA support for NAND access.\n"); | 2267 | dev_info(host->dev, "No DMA support for NAND access.\n"); |
2268 | 2268 | ||
2269 | /* first scan to find the device and get the page size */ | 2269 | /* first scan to find the device and get the page size */ |
2270 | if (nand_scan_ident(mtd, 1, NULL)) { | 2270 | res = nand_scan_ident(mtd, 1, NULL); |
2271 | res = -ENXIO; | 2271 | if (res) |
2272 | goto err_scan_ident; | 2272 | goto err_scan_ident; |
2273 | } | ||
2274 | 2273 | ||
2275 | if (host->board.on_flash_bbt || on_flash_bbt) | 2274 | if (host->board.on_flash_bbt || on_flash_bbt) |
2276 | nand_chip->bbt_options |= NAND_BBT_USE_FLASH; | 2275 | nand_chip->bbt_options |= NAND_BBT_USE_FLASH; |
@@ -2304,10 +2303,9 @@ static int atmel_nand_probe(struct platform_device *pdev) | |||
2304 | } | 2303 | } |
2305 | 2304 | ||
2306 | /* second phase scan */ | 2305 | /* second phase scan */ |
2307 | if (nand_scan_tail(mtd)) { | 2306 | res = nand_scan_tail(mtd); |
2308 | res = -ENXIO; | 2307 | if (res) |
2309 | goto err_scan_tail; | 2308 | goto err_scan_tail; |
2310 | } | ||
2311 | 2309 | ||
2312 | mtd->name = "atmel_nand"; | 2310 | mtd->name = "atmel_nand"; |
2313 | res = mtd_device_register(mtd, host->board.parts, | 2311 | res = mtd_device_register(mtd, host->board.parts, |
diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index 9d2424bfdbf5..42ebd73f821d 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c | |||
@@ -2209,8 +2209,9 @@ static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn) | |||
2209 | nand_writereg(ctrl, cfg_offs, | 2209 | nand_writereg(ctrl, cfg_offs, |
2210 | nand_readreg(ctrl, cfg_offs) & ~CFG_BUS_WIDTH); | 2210 | nand_readreg(ctrl, cfg_offs) & ~CFG_BUS_WIDTH); |
2211 | 2211 | ||
2212 | if (nand_scan_ident(mtd, 1, NULL)) | 2212 | ret = nand_scan_ident(mtd, 1, NULL); |
2213 | return -ENXIO; | 2213 | if (ret) |
2214 | return ret; | ||
2214 | 2215 | ||
2215 | chip->options |= NAND_NO_SUBPAGE_WRITE; | 2216 | chip->options |= NAND_NO_SUBPAGE_WRITE; |
2216 | /* | 2217 | /* |
@@ -2234,8 +2235,9 @@ static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn) | |||
2234 | if (ret) | 2235 | if (ret) |
2235 | return ret; | 2236 | return ret; |
2236 | 2237 | ||
2237 | if (nand_scan_tail(mtd)) | 2238 | ret = nand_scan_tail(mtd); |
2238 | return -ENXIO; | 2239 | if (ret) |
2240 | return ret; | ||
2239 | 2241 | ||
2240 | return mtd_device_register(mtd, NULL, 0); | 2242 | return mtd_device_register(mtd, NULL, 0); |
2241 | } | 2243 | } |
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index 0b0c93702abb..d40c32d311d8 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c | |||
@@ -725,10 +725,9 @@ static int cafe_nand_probe(struct pci_dev *pdev, | |||
725 | usedma = 0; | 725 | usedma = 0; |
726 | 726 | ||
727 | /* Scan to find existence of the device */ | 727 | /* Scan to find existence of the device */ |
728 | if (nand_scan_ident(mtd, 2, NULL)) { | 728 | err = nand_scan_ident(mtd, 2, NULL); |
729 | err = -ENXIO; | 729 | if (err) |
730 | goto out_irq; | 730 | goto out_irq; |
731 | } | ||
732 | 731 | ||
733 | cafe->dmabuf = dma_alloc_coherent(&cafe->pdev->dev, | 732 | cafe->dmabuf = dma_alloc_coherent(&cafe->pdev->dev, |
734 | 2112 + sizeof(struct nand_buffers) + | 733 | 2112 + sizeof(struct nand_buffers) + |
diff --git a/drivers/mtd/nand/cmx270_nand.c b/drivers/mtd/nand/cmx270_nand.c index 49133783ca53..226ac0bcafc6 100644 --- a/drivers/mtd/nand/cmx270_nand.c +++ b/drivers/mtd/nand/cmx270_nand.c | |||
@@ -195,9 +195,9 @@ static int __init cmx270_init(void) | |||
195 | this->write_buf = cmx270_write_buf; | 195 | this->write_buf = cmx270_write_buf; |
196 | 196 | ||
197 | /* Scan to find existence of the device */ | 197 | /* Scan to find existence of the device */ |
198 | if (nand_scan (cmx270_nand_mtd, 1)) { | 198 | ret = nand_scan(cmx270_nand_mtd, 1); |
199 | if (ret) { | ||
199 | pr_notice("No NAND device\n"); | 200 | pr_notice("No NAND device\n"); |
200 | ret = -ENXIO; | ||
201 | goto err_scan; | 201 | goto err_scan; |
202 | } | 202 | } |
203 | 203 | ||
diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/cs553x_nand.c index a65e4e0f57a1..594b28684138 100644 --- a/drivers/mtd/nand/cs553x_nand.c +++ b/drivers/mtd/nand/cs553x_nand.c | |||
@@ -242,10 +242,9 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr) | |||
242 | } | 242 | } |
243 | 243 | ||
244 | /* Scan to find existence of the device */ | 244 | /* Scan to find existence of the device */ |
245 | if (nand_scan(new_mtd, 1)) { | 245 | err = nand_scan(new_mtd, 1); |
246 | err = -ENXIO; | 246 | if (err) |
247 | goto out_free; | 247 | goto out_free; |
248 | } | ||
249 | 248 | ||
250 | cs553x_mtd[cs] = new_mtd; | 249 | cs553x_mtd[cs] = new_mtd; |
251 | goto out; | 250 | goto out; |
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index 0476ae8776d9..73b9d4e2dca0 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/dma-mapping.h> | 21 | #include <linux/dma-mapping.h> |
22 | #include <linux/wait.h> | 22 | #include <linux/wait.h> |
23 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
24 | #include <linux/slab.h> | ||
25 | #include <linux/mtd/mtd.h> | 24 | #include <linux/mtd/mtd.h> |
26 | #include <linux/module.h> | 25 | #include <linux/module.h> |
27 | 26 | ||
@@ -182,9 +181,6 @@ static uint16_t denali_nand_reset(struct denali_nand_info *denali) | |||
182 | { | 181 | { |
183 | int i; | 182 | int i; |
184 | 183 | ||
185 | dev_dbg(denali->dev, "%s, Line %d, Function: %s\n", | ||
186 | __FILE__, __LINE__, __func__); | ||
187 | |||
188 | for (i = 0; i < denali->max_banks; i++) | 184 | for (i = 0; i < denali->max_banks; i++) |
189 | iowrite32(INTR_STATUS__RST_COMP | INTR_STATUS__TIME_OUT, | 185 | iowrite32(INTR_STATUS__RST_COMP | INTR_STATUS__TIME_OUT, |
190 | denali->flash_reg + INTR_STATUS(i)); | 186 | denali->flash_reg + INTR_STATUS(i)); |
@@ -234,9 +230,6 @@ static void nand_onfi_timing_set(struct denali_nand_info *denali, | |||
234 | uint16_t acc_clks; | 230 | uint16_t acc_clks; |
235 | uint16_t addr_2_data, re_2_we, re_2_re, we_2_re, cs_cnt; | 231 | uint16_t addr_2_data, re_2_we, re_2_re, we_2_re, cs_cnt; |
236 | 232 | ||
237 | dev_dbg(denali->dev, "%s, Line %d, Function: %s\n", | ||
238 | __FILE__, __LINE__, __func__); | ||
239 | |||
240 | en_lo = CEIL_DIV(Trp[mode], CLK_X); | 233 | en_lo = CEIL_DIV(Trp[mode], CLK_X); |
241 | en_hi = CEIL_DIV(Treh[mode], CLK_X); | 234 | en_hi = CEIL_DIV(Treh[mode], CLK_X); |
242 | #if ONFI_BLOOM_TIME | 235 | #if ONFI_BLOOM_TIME |
@@ -403,7 +396,7 @@ static void get_hynix_nand_para(struct denali_nand_info *denali, | |||
403 | break; | 396 | break; |
404 | default: | 397 | default: |
405 | dev_warn(denali->dev, | 398 | dev_warn(denali->dev, |
406 | "Spectra: Unknown Hynix NAND (Device ID: 0x%x).\n" | 399 | "Unknown Hynix NAND (Device ID: 0x%x).\n" |
407 | "Will use default parameter values instead.\n", | 400 | "Will use default parameter values instead.\n", |
408 | device_id); | 401 | device_id); |
409 | } | 402 | } |
@@ -474,33 +467,6 @@ static void detect_max_banks(struct denali_nand_info *denali) | |||
474 | denali->max_banks = 1 << (features & FEATURES__N_BANKS); | 467 | denali->max_banks = 1 << (features & FEATURES__N_BANKS); |
475 | } | 468 | } |
476 | 469 | ||
477 | static void detect_partition_feature(struct denali_nand_info *denali) | ||
478 | { | ||
479 | /* | ||
480 | * For MRST platform, denali->fwblks represent the | ||
481 | * number of blocks firmware is taken, | ||
482 | * FW is in protect partition and MTD driver has no | ||
483 | * permission to access it. So let driver know how many | ||
484 | * blocks it can't touch. | ||
485 | */ | ||
486 | if (ioread32(denali->flash_reg + FEATURES) & FEATURES__PARTITION) { | ||
487 | if ((ioread32(denali->flash_reg + PERM_SRC_ID(1)) & | ||
488 | PERM_SRC_ID__SRCID) == SPECTRA_PARTITION_ID) { | ||
489 | denali->fwblks = | ||
490 | ((ioread32(denali->flash_reg + MIN_MAX_BANK(1)) & | ||
491 | MIN_MAX_BANK__MIN_VALUE) * | ||
492 | denali->blksperchip) | ||
493 | + | ||
494 | (ioread32(denali->flash_reg + MIN_BLK_ADDR(1)) & | ||
495 | MIN_BLK_ADDR__VALUE); | ||
496 | } else { | ||
497 | denali->fwblks = SPECTRA_START_BLOCK; | ||
498 | } | ||
499 | } else { | ||
500 | denali->fwblks = SPECTRA_START_BLOCK; | ||
501 | } | ||
502 | } | ||
503 | |||
504 | static uint16_t denali_nand_timing_set(struct denali_nand_info *denali) | 470 | static uint16_t denali_nand_timing_set(struct denali_nand_info *denali) |
505 | { | 471 | { |
506 | uint16_t status = PASS; | 472 | uint16_t status = PASS; |
@@ -508,9 +474,6 @@ static uint16_t denali_nand_timing_set(struct denali_nand_info *denali) | |||
508 | uint8_t maf_id, device_id; | 474 | uint8_t maf_id, device_id; |
509 | int i; | 475 | int i; |
510 | 476 | ||
511 | dev_dbg(denali->dev, "%s, Line %d, Function: %s\n", | ||
512 | __FILE__, __LINE__, __func__); | ||
513 | |||
514 | /* | 477 | /* |
515 | * Use read id method to get device ID and other params. | 478 | * Use read id method to get device ID and other params. |
516 | * For some NAND chips, controller can't report the correct | 479 | * For some NAND chips, controller can't report the correct |
@@ -552,8 +515,6 @@ static uint16_t denali_nand_timing_set(struct denali_nand_info *denali) | |||
552 | 515 | ||
553 | find_valid_banks(denali); | 516 | find_valid_banks(denali); |
554 | 517 | ||
555 | detect_partition_feature(denali); | ||
556 | |||
557 | /* | 518 | /* |
558 | * If the user specified to override the default timings | 519 | * If the user specified to override the default timings |
559 | * with a specific ONFI mode, we apply those changes here. | 520 | * with a specific ONFI mode, we apply those changes here. |
@@ -567,9 +528,6 @@ static uint16_t denali_nand_timing_set(struct denali_nand_info *denali) | |||
567 | static void denali_set_intr_modes(struct denali_nand_info *denali, | 528 | static void denali_set_intr_modes(struct denali_nand_info *denali, |
568 | uint16_t INT_ENABLE) | 529 | uint16_t INT_ENABLE) |
569 | { | 530 | { |
570 | dev_dbg(denali->dev, "%s, Line %d, Function: %s\n", | ||
571 | __FILE__, __LINE__, __func__); | ||
572 | |||
573 | if (INT_ENABLE) | 531 | if (INT_ENABLE) |
574 | iowrite32(1, denali->flash_reg + GLOBAL_INT_ENABLE); | 532 | iowrite32(1, denali->flash_reg + GLOBAL_INT_ENABLE); |
575 | else | 533 | else |
@@ -605,7 +563,6 @@ static void denali_irq_init(struct denali_nand_info *denali) | |||
605 | static void denali_irq_cleanup(int irqnum, struct denali_nand_info *denali) | 563 | static void denali_irq_cleanup(int irqnum, struct denali_nand_info *denali) |
606 | { | 564 | { |
607 | denali_set_intr_modes(denali, false); | 565 | denali_set_intr_modes(denali, false); |
608 | free_irq(irqnum, denali); | ||
609 | } | 566 | } |
610 | 567 | ||
611 | static void denali_irq_enable(struct denali_nand_info *denali, | 568 | static void denali_irq_enable(struct denali_nand_info *denali, |
@@ -1437,9 +1394,6 @@ static struct nand_bbt_descr bbt_mirror_descr = { | |||
1437 | /* initialize driver data structures */ | 1394 | /* initialize driver data structures */ |
1438 | static void denali_drv_init(struct denali_nand_info *denali) | 1395 | static void denali_drv_init(struct denali_nand_info *denali) |
1439 | { | 1396 | { |
1440 | denali->idx = 0; | ||
1441 | |||
1442 | /* setup interrupt handler */ | ||
1443 | /* | 1397 | /* |
1444 | * the completion object will be used to notify | 1398 | * the completion object will be used to notify |
1445 | * the callee that the interrupt is done | 1399 | * the callee that the interrupt is done |
@@ -1485,14 +1439,12 @@ int denali_init(struct denali_nand_info *denali) | |||
1485 | denali_hw_init(denali); | 1439 | denali_hw_init(denali); |
1486 | denali_drv_init(denali); | 1440 | denali_drv_init(denali); |
1487 | 1441 | ||
1488 | /* | 1442 | /* Request IRQ after all the hardware initialization is finished */ |
1489 | * denali_isr register is done after all the hardware | 1443 | ret = devm_request_irq(denali->dev, denali->irq, denali_isr, |
1490 | * initilization is finished | 1444 | IRQF_SHARED, DENALI_NAND_NAME, denali); |
1491 | */ | 1445 | if (ret) { |
1492 | if (request_irq(denali->irq, denali_isr, IRQF_SHARED, | 1446 | dev_err(denali->dev, "Unable to request IRQ\n"); |
1493 | DENALI_NAND_NAME, denali)) { | 1447 | return ret; |
1494 | pr_err("Spectra: Unable to allocate IRQ\n"); | ||
1495 | return -ENODEV; | ||
1496 | } | 1448 | } |
1497 | 1449 | ||
1498 | /* now that our ISR is registered, we can enable interrupts */ | 1450 | /* now that our ISR is registered, we can enable interrupts */ |
@@ -1510,10 +1462,9 @@ int denali_init(struct denali_nand_info *denali) | |||
1510 | * this is the first stage in a two step process to register | 1462 | * this is the first stage in a two step process to register |
1511 | * with the nand subsystem | 1463 | * with the nand subsystem |
1512 | */ | 1464 | */ |
1513 | if (nand_scan_ident(mtd, denali->max_banks, NULL)) { | 1465 | ret = nand_scan_ident(mtd, denali->max_banks, NULL); |
1514 | ret = -ENXIO; | 1466 | if (ret) |
1515 | goto failed_req_irq; | 1467 | goto failed_req_irq; |
1516 | } | ||
1517 | 1468 | ||
1518 | /* allocate the right size buffer now */ | 1469 | /* allocate the right size buffer now */ |
1519 | devm_kfree(denali->dev, denali->buf.buf); | 1470 | devm_kfree(denali->dev, denali->buf.buf); |
@@ -1528,7 +1479,7 @@ int denali_init(struct denali_nand_info *denali) | |||
1528 | /* Is 32-bit DMA supported? */ | 1479 | /* Is 32-bit DMA supported? */ |
1529 | ret = dma_set_mask(denali->dev, DMA_BIT_MASK(32)); | 1480 | ret = dma_set_mask(denali->dev, DMA_BIT_MASK(32)); |
1530 | if (ret) { | 1481 | if (ret) { |
1531 | pr_err("Spectra: no usable DMA configuration\n"); | 1482 | dev_err(denali->dev, "No usable DMA configuration\n"); |
1532 | goto failed_req_irq; | 1483 | goto failed_req_irq; |
1533 | } | 1484 | } |
1534 | 1485 | ||
@@ -1536,7 +1487,7 @@ int denali_init(struct denali_nand_info *denali) | |||
1536 | mtd->writesize + mtd->oobsize, | 1487 | mtd->writesize + mtd->oobsize, |
1537 | DMA_BIDIRECTIONAL); | 1488 | DMA_BIDIRECTIONAL); |
1538 | if (dma_mapping_error(denali->dev, denali->buf.dma_buf)) { | 1489 | if (dma_mapping_error(denali->dev, denali->buf.dma_buf)) { |
1539 | dev_err(denali->dev, "Spectra: failed to map DMA buffer\n"); | 1490 | dev_err(denali->dev, "Failed to map DMA buffer\n"); |
1540 | ret = -EIO; | 1491 | ret = -EIO; |
1541 | goto failed_req_irq; | 1492 | goto failed_req_irq; |
1542 | } | 1493 | } |
@@ -1547,16 +1498,16 @@ int denali_init(struct denali_nand_info *denali) | |||
1547 | * the real pagesize and anything necessery | 1498 | * the real pagesize and anything necessery |
1548 | */ | 1499 | */ |
1549 | denali->devnum = ioread32(denali->flash_reg + DEVICES_CONNECTED); | 1500 | denali->devnum = ioread32(denali->flash_reg + DEVICES_CONNECTED); |
1550 | denali->nand.chipsize <<= (denali->devnum - 1); | 1501 | denali->nand.chipsize <<= denali->devnum - 1; |
1551 | denali->nand.page_shift += (denali->devnum - 1); | 1502 | denali->nand.page_shift += denali->devnum - 1; |
1552 | denali->nand.pagemask = (denali->nand.chipsize >> | 1503 | denali->nand.pagemask = (denali->nand.chipsize >> |
1553 | denali->nand.page_shift) - 1; | 1504 | denali->nand.page_shift) - 1; |
1554 | denali->nand.bbt_erase_shift += (denali->devnum - 1); | 1505 | denali->nand.bbt_erase_shift += denali->devnum - 1; |
1555 | denali->nand.phys_erase_shift = denali->nand.bbt_erase_shift; | 1506 | denali->nand.phys_erase_shift = denali->nand.bbt_erase_shift; |
1556 | denali->nand.chip_shift += (denali->devnum - 1); | 1507 | denali->nand.chip_shift += denali->devnum - 1; |
1557 | mtd->writesize <<= (denali->devnum - 1); | 1508 | mtd->writesize <<= denali->devnum - 1; |
1558 | mtd->oobsize <<= (denali->devnum - 1); | 1509 | mtd->oobsize <<= denali->devnum - 1; |
1559 | mtd->erasesize <<= (denali->devnum - 1); | 1510 | mtd->erasesize <<= denali->devnum - 1; |
1560 | mtd->size = denali->nand.numchips * denali->nand.chipsize; | 1511 | mtd->size = denali->nand.numchips * denali->nand.chipsize; |
1561 | denali->bbtskipbytes *= denali->devnum; | 1512 | denali->bbtskipbytes *= denali->devnum; |
1562 | 1513 | ||
@@ -1606,14 +1557,6 @@ int denali_init(struct denali_nand_info *denali) | |||
1606 | denali->nand.ecc.bytes *= denali->devnum; | 1557 | denali->nand.ecc.bytes *= denali->devnum; |
1607 | denali->nand.ecc.strength *= denali->devnum; | 1558 | denali->nand.ecc.strength *= denali->devnum; |
1608 | 1559 | ||
1609 | /* | ||
1610 | * Let driver know the total blocks number and how many blocks | ||
1611 | * contained by each nand chip. blksperchip will help driver to | ||
1612 | * know how many blocks is taken by FW. | ||
1613 | */ | ||
1614 | denali->totalblks = mtd->size >> denali->nand.phys_erase_shift; | ||
1615 | denali->blksperchip = denali->totalblks / denali->nand.numchips; | ||
1616 | |||
1617 | /* override the default read operations */ | 1560 | /* override the default read operations */ |
1618 | denali->nand.ecc.size = ECC_SECTOR_SIZE * denali->devnum; | 1561 | denali->nand.ecc.size = ECC_SECTOR_SIZE * denali->devnum; |
1619 | denali->nand.ecc.read_page = denali_read_page; | 1562 | denali->nand.ecc.read_page = denali_read_page; |
@@ -1624,15 +1567,13 @@ int denali_init(struct denali_nand_info *denali) | |||
1624 | denali->nand.ecc.write_oob = denali_write_oob; | 1567 | denali->nand.ecc.write_oob = denali_write_oob; |
1625 | denali->nand.erase = denali_erase; | 1568 | denali->nand.erase = denali_erase; |
1626 | 1569 | ||
1627 | if (nand_scan_tail(mtd)) { | 1570 | ret = nand_scan_tail(mtd); |
1628 | ret = -ENXIO; | 1571 | if (ret) |
1629 | goto failed_req_irq; | 1572 | goto failed_req_irq; |
1630 | } | ||
1631 | 1573 | ||
1632 | ret = mtd_device_register(mtd, NULL, 0); | 1574 | ret = mtd_device_register(mtd, NULL, 0); |
1633 | if (ret) { | 1575 | if (ret) { |
1634 | dev_err(denali->dev, "Spectra: Failed to register MTD: %d\n", | 1576 | dev_err(denali->dev, "Failed to register MTD: %d\n", ret); |
1635 | ret); | ||
1636 | goto failed_req_irq; | 1577 | goto failed_req_irq; |
1637 | } | 1578 | } |
1638 | return 0; | 1579 | return 0; |
diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h index e7ab4866a5da..ea22191e8515 100644 --- a/drivers/mtd/nand/denali.h +++ b/drivers/mtd/nand/denali.h | |||
@@ -383,14 +383,6 @@ | |||
383 | #define CLK_X 5 | 383 | #define CLK_X 5 |
384 | #define CLK_MULTI 4 | 384 | #define CLK_MULTI 4 |
385 | 385 | ||
386 | /* spectraswconfig.h */ | ||
387 | #define CMD_DMA 0 | ||
388 | |||
389 | #define SPECTRA_PARTITION_ID 0 | ||
390 | /**** Block Table and Reserved Block Parameters *****/ | ||
391 | #define SPECTRA_START_BLOCK 3 | ||
392 | #define NUM_FREE_BLOCKS_GATE 30 | ||
393 | |||
394 | /* KBV - Updated to LNW scratch register address */ | 386 | /* KBV - Updated to LNW scratch register address */ |
395 | #define SCRATCH_REG_ADDR CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR | 387 | #define SCRATCH_REG_ADDR CONFIG_MTD_NAND_DENALI_SCRATCH_REG_ADDR |
396 | #define SCRATCH_REG_SIZE 64 | 388 | #define SCRATCH_REG_SIZE 64 |
@@ -467,13 +459,9 @@ struct denali_nand_info { | |||
467 | spinlock_t irq_lock; | 459 | spinlock_t irq_lock; |
468 | uint32_t irq_status; | 460 | uint32_t irq_status; |
469 | int irq_debug_array[32]; | 461 | int irq_debug_array[32]; |
470 | int idx; | ||
471 | int irq; | 462 | int irq; |
472 | 463 | ||
473 | uint32_t devnum; /* represent how many nands connected */ | 464 | uint32_t devnum; /* represent how many nands connected */ |
474 | uint32_t fwblks; /* represent how many blocks FW used */ | ||
475 | uint32_t totalblks; | ||
476 | uint32_t blksperchip; | ||
477 | uint32_t bbtskipbytes; | 465 | uint32_t bbtskipbytes; |
478 | uint32_t max_banks; | 466 | uint32_t max_banks; |
479 | }; | 467 | }; |
diff --git a/drivers/mtd/nand/denali_dt.c b/drivers/mtd/nand/denali_dt.c index 0cb1e8d9fbfc..5607fcd3b8ed 100644 --- a/drivers/mtd/nand/denali_dt.c +++ b/drivers/mtd/nand/denali_dt.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/of.h> | 22 | #include <linux/of.h> |
23 | #include <linux/of_device.h> | 23 | #include <linux/of_device.h> |
24 | #include <linux/slab.h> | ||
25 | 24 | ||
26 | #include "denali.h" | 25 | #include "denali.h" |
27 | 26 | ||
@@ -110,7 +109,7 @@ static int denali_dt_remove(struct platform_device *ofdev) | |||
110 | struct denali_dt *dt = platform_get_drvdata(ofdev); | 109 | struct denali_dt *dt = platform_get_drvdata(ofdev); |
111 | 110 | ||
112 | denali_remove(&dt->denali); | 111 | denali_remove(&dt->denali); |
113 | clk_disable(dt->clk); | 112 | clk_disable_unprepare(dt->clk); |
114 | 113 | ||
115 | return 0; | 114 | return 0; |
116 | } | 115 | } |
diff --git a/drivers/mtd/nand/denali_pci.c b/drivers/mtd/nand/denali_pci.c index de31514df282..ac843238b77e 100644 --- a/drivers/mtd/nand/denali_pci.c +++ b/drivers/mtd/nand/denali_pci.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/pci.h> | 16 | #include <linux/pci.h> |
17 | #include <linux/slab.h> | ||
18 | 17 | ||
19 | #include "denali.h" | 18 | #include "denali.h" |
20 | 19 | ||
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index d4f454a4b35e..4924b43977ef 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c | |||
@@ -926,8 +926,8 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
926 | /* | 926 | /* |
927 | * Scan to find existence of the device | 927 | * Scan to find existence of the device |
928 | */ | 928 | */ |
929 | if (nand_scan_ident(mtd, 1, NULL)) { | 929 | ret = nand_scan_ident(mtd, 1, NULL); |
930 | ret = -ENXIO; | 930 | if (ret) { |
931 | dev_err(&pdev->dev, "No NAND Device found!\n"); | 931 | dev_err(&pdev->dev, "No NAND Device found!\n"); |
932 | goto err_scan_ident; | 932 | goto err_scan_ident; |
933 | } | 933 | } |
@@ -992,10 +992,9 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
992 | } | 992 | } |
993 | 993 | ||
994 | /* Second stage of scan to fill MTD data-structures */ | 994 | /* Second stage of scan to fill MTD data-structures */ |
995 | if (nand_scan_tail(mtd)) { | 995 | ret = nand_scan_tail(mtd); |
996 | ret = -ENXIO; | 996 | if (ret) |
997 | goto err_probe; | 997 | goto err_probe; |
998 | } | ||
999 | 998 | ||
1000 | /* | 999 | /* |
1001 | * The partition information can is accessed by (in the same precedence) | 1000 | * The partition information can is accessed by (in the same precedence) |
diff --git a/drivers/mtd/nand/gpio.c b/drivers/mtd/nand/gpio.c index 6317f6836022..0d24857469ab 100644 --- a/drivers/mtd/nand/gpio.c +++ b/drivers/mtd/nand/gpio.c | |||
@@ -286,10 +286,9 @@ static int gpio_nand_probe(struct platform_device *pdev) | |||
286 | if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) | 286 | if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) |
287 | gpio_direction_output(gpiomtd->plat.gpio_nwp, 1); | 287 | gpio_direction_output(gpiomtd->plat.gpio_nwp, 1); |
288 | 288 | ||
289 | if (nand_scan(mtd, 1)) { | 289 | ret = nand_scan(mtd, 1); |
290 | ret = -ENXIO; | 290 | if (ret) |
291 | goto err_wp; | 291 | goto err_wp; |
292 | } | ||
293 | 292 | ||
294 | if (gpiomtd->plat.adjust_parts) | 293 | if (gpiomtd->plat.adjust_parts) |
295 | gpiomtd->plat.adjust_parts(&gpiomtd->plat, mtd->size); | 294 | gpiomtd->plat.adjust_parts(&gpiomtd->plat, mtd->size); |
diff --git a/drivers/mtd/nand/hisi504_nand.c b/drivers/mtd/nand/hisi504_nand.c index 9432546f4cd4..e40364eeb556 100644 --- a/drivers/mtd/nand/hisi504_nand.c +++ b/drivers/mtd/nand/hisi504_nand.c | |||
@@ -774,10 +774,8 @@ static int hisi_nfc_probe(struct platform_device *pdev) | |||
774 | } | 774 | } |
775 | 775 | ||
776 | ret = nand_scan_ident(mtd, max_chips, NULL); | 776 | ret = nand_scan_ident(mtd, max_chips, NULL); |
777 | if (ret) { | 777 | if (ret) |
778 | ret = -ENODEV; | ||
779 | goto err_res; | 778 | goto err_res; |
780 | } | ||
781 | 779 | ||
782 | host->buffer = dmam_alloc_coherent(dev, mtd->writesize + mtd->oobsize, | 780 | host->buffer = dmam_alloc_coherent(dev, mtd->writesize + mtd->oobsize, |
783 | &host->dma_buffer, GFP_KERNEL); | 781 | &host->dma_buffer, GFP_KERNEL); |
diff --git a/drivers/mtd/nand/lpc32xx_mlc.c b/drivers/mtd/nand/lpc32xx_mlc.c index 852388171f20..5553a5d9efd1 100644 --- a/drivers/mtd/nand/lpc32xx_mlc.c +++ b/drivers/mtd/nand/lpc32xx_mlc.c | |||
@@ -747,10 +747,9 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
747 | * Scan to find existance of the device and | 747 | * Scan to find existance of the device and |
748 | * Get the type of NAND device SMALL block or LARGE block | 748 | * Get the type of NAND device SMALL block or LARGE block |
749 | */ | 749 | */ |
750 | if (nand_scan_ident(mtd, 1, NULL)) { | 750 | res = nand_scan_ident(mtd, 1, NULL); |
751 | res = -ENXIO; | 751 | if (res) |
752 | goto err_exit3; | 752 | goto err_exit3; |
753 | } | ||
754 | 753 | ||
755 | host->dma_buf = devm_kzalloc(&pdev->dev, mtd->writesize, GFP_KERNEL); | 754 | host->dma_buf = devm_kzalloc(&pdev->dev, mtd->writesize, GFP_KERNEL); |
756 | if (!host->dma_buf) { | 755 | if (!host->dma_buf) { |
@@ -793,10 +792,9 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
793 | * Fills out all the uninitialized function pointers with the defaults | 792 | * Fills out all the uninitialized function pointers with the defaults |
794 | * And scans for a bad block table if appropriate. | 793 | * And scans for a bad block table if appropriate. |
795 | */ | 794 | */ |
796 | if (nand_scan_tail(mtd)) { | 795 | res = nand_scan_tail(mtd); |
797 | res = -ENXIO; | 796 | if (res) |
798 | goto err_exit4; | 797 | goto err_exit4; |
799 | } | ||
800 | 798 | ||
801 | mtd->name = DRV_NAME; | 799 | mtd->name = DRV_NAME; |
802 | 800 | ||
diff --git a/drivers/mtd/nand/lpc32xx_slc.c b/drivers/mtd/nand/lpc32xx_slc.c index 8d3edc34958e..53bafe23ab39 100644 --- a/drivers/mtd/nand/lpc32xx_slc.c +++ b/drivers/mtd/nand/lpc32xx_slc.c | |||
@@ -894,10 +894,9 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
894 | } | 894 | } |
895 | 895 | ||
896 | /* Find NAND device */ | 896 | /* Find NAND device */ |
897 | if (nand_scan_ident(mtd, 1, NULL)) { | 897 | res = nand_scan_ident(mtd, 1, NULL); |
898 | res = -ENXIO; | 898 | if (res) |
899 | goto err_exit3; | 899 | goto err_exit3; |
900 | } | ||
901 | 900 | ||
902 | /* OOB and ECC CPU and DMA work areas */ | 901 | /* OOB and ECC CPU and DMA work areas */ |
903 | host->ecc_buf = (uint32_t *)(host->data_buf + LPC32XX_DMA_DATA_SIZE); | 902 | host->ecc_buf = (uint32_t *)(host->data_buf + LPC32XX_DMA_DATA_SIZE); |
@@ -929,10 +928,9 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
929 | /* | 928 | /* |
930 | * Fills out all the uninitialized function pointers with the defaults | 929 | * Fills out all the uninitialized function pointers with the defaults |
931 | */ | 930 | */ |
932 | if (nand_scan_tail(mtd)) { | 931 | res = nand_scan_tail(mtd); |
933 | res = -ENXIO; | 932 | if (res) |
934 | goto err_exit3; | 933 | goto err_exit3; |
935 | } | ||
936 | 934 | ||
937 | mtd->name = "nxp_lpc3220_slc"; | 935 | mtd->name = "nxp_lpc3220_slc"; |
938 | res = mtd_device_register(mtd, host->ncfg->parts, | 936 | res = mtd_device_register(mtd, host->ncfg->parts, |
diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c index 7eacb2f545f5..6d6eaed2d20c 100644 --- a/drivers/mtd/nand/mpc5121_nfc.c +++ b/drivers/mtd/nand/mpc5121_nfc.c | |||
@@ -777,9 +777,9 @@ static int mpc5121_nfc_probe(struct platform_device *op) | |||
777 | } | 777 | } |
778 | 778 | ||
779 | /* Detect NAND chips */ | 779 | /* Detect NAND chips */ |
780 | if (nand_scan(mtd, be32_to_cpup(chips_no))) { | 780 | retval = nand_scan(mtd, be32_to_cpup(chips_no)); |
781 | if (retval) { | ||
781 | dev_err(dev, "NAND Flash not found !\n"); | 782 | dev_err(dev, "NAND Flash not found !\n"); |
782 | retval = -ENXIO; | ||
783 | goto error; | 783 | goto error; |
784 | } | 784 | } |
785 | 785 | ||
diff --git a/drivers/mtd/nand/mtk_nand.c b/drivers/mtd/nand/mtk_nand.c index 5223a2182ee4..6c3eed3c2094 100644 --- a/drivers/mtd/nand/mtk_nand.c +++ b/drivers/mtd/nand/mtk_nand.c | |||
@@ -1297,7 +1297,7 @@ static int mtk_nfc_nand_chip_init(struct device *dev, struct mtk_nfc *nfc, | |||
1297 | 1297 | ||
1298 | ret = nand_scan_ident(mtd, nsels, NULL); | 1298 | ret = nand_scan_ident(mtd, nsels, NULL); |
1299 | if (ret) | 1299 | if (ret) |
1300 | return -ENODEV; | 1300 | return ret; |
1301 | 1301 | ||
1302 | /* store bbt magic in page, cause OOB is not protected */ | 1302 | /* store bbt magic in page, cause OOB is not protected */ |
1303 | if (nand->bbt_options & NAND_BBT_USE_FLASH) | 1303 | if (nand->bbt_options & NAND_BBT_USE_FLASH) |
@@ -1323,7 +1323,7 @@ static int mtk_nfc_nand_chip_init(struct device *dev, struct mtk_nfc *nfc, | |||
1323 | 1323 | ||
1324 | ret = nand_scan_tail(mtd); | 1324 | ret = nand_scan_tail(mtd); |
1325 | if (ret) | 1325 | if (ret) |
1326 | return -ENODEV; | 1326 | return ret; |
1327 | 1327 | ||
1328 | ret = mtd_device_parse_register(mtd, NULL, NULL, NULL, 0); | 1328 | ret = mtd_device_parse_register(mtd, NULL, NULL, NULL, 0); |
1329 | if (ret) { | 1329 | if (ret) { |
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index d7f724b24fd7..61ca020c5272 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c | |||
@@ -1747,10 +1747,9 @@ static int mxcnd_probe(struct platform_device *pdev) | |||
1747 | } | 1747 | } |
1748 | 1748 | ||
1749 | /* first scan to find the device and get the page size */ | 1749 | /* first scan to find the device and get the page size */ |
1750 | if (nand_scan_ident(mtd, is_imx25_nfc(host) ? 4 : 1, NULL)) { | 1750 | err = nand_scan_ident(mtd, is_imx25_nfc(host) ? 4 : 1, NULL); |
1751 | err = -ENXIO; | 1751 | if (err) |
1752 | goto escan; | 1752 | goto escan; |
1753 | } | ||
1754 | 1753 | ||
1755 | switch (this->ecc.mode) { | 1754 | switch (this->ecc.mode) { |
1756 | case NAND_ECC_HW: | 1755 | case NAND_ECC_HW: |
@@ -1808,10 +1807,9 @@ static int mxcnd_probe(struct platform_device *pdev) | |||
1808 | } | 1807 | } |
1809 | 1808 | ||
1810 | /* second phase scan */ | 1809 | /* second phase scan */ |
1811 | if (nand_scan_tail(mtd)) { | 1810 | err = nand_scan_tail(mtd); |
1812 | err = -ENXIO; | 1811 | if (err) |
1813 | goto escan; | 1812 | goto escan; |
1814 | } | ||
1815 | 1813 | ||
1816 | /* Register the partitions */ | 1814 | /* Register the partitions */ |
1817 | mtd_device_parse_register(mtd, part_probes, | 1815 | mtd_device_parse_register(mtd, part_probes, |
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 3bde96a3f7bf..ec1c28aaaf23 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -709,6 +709,25 @@ static void nand_command(struct mtd_info *mtd, unsigned int command, | |||
709 | nand_wait_ready(mtd); | 709 | nand_wait_ready(mtd); |
710 | } | 710 | } |
711 | 711 | ||
712 | static void nand_ccs_delay(struct nand_chip *chip) | ||
713 | { | ||
714 | /* | ||
715 | * The controller already takes care of waiting for tCCS when the RNDIN | ||
716 | * or RNDOUT command is sent, return directly. | ||
717 | */ | ||
718 | if (!(chip->options & NAND_WAIT_TCCS)) | ||
719 | return; | ||
720 | |||
721 | /* | ||
722 | * Wait tCCS_min if it is correctly defined, otherwise wait 500ns | ||
723 | * (which should be safe for all NANDs). | ||
724 | */ | ||
725 | if (chip->data_interface && chip->data_interface->timings.sdr.tCCS_min) | ||
726 | ndelay(chip->data_interface->timings.sdr.tCCS_min / 1000); | ||
727 | else | ||
728 | ndelay(500); | ||
729 | } | ||
730 | |||
712 | /** | 731 | /** |
713 | * nand_command_lp - [DEFAULT] Send command to NAND large page device | 732 | * nand_command_lp - [DEFAULT] Send command to NAND large page device |
714 | * @mtd: MTD device structure | 733 | * @mtd: MTD device structure |
@@ -773,10 +792,13 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command, | |||
773 | case NAND_CMD_ERASE1: | 792 | case NAND_CMD_ERASE1: |
774 | case NAND_CMD_ERASE2: | 793 | case NAND_CMD_ERASE2: |
775 | case NAND_CMD_SEQIN: | 794 | case NAND_CMD_SEQIN: |
776 | case NAND_CMD_RNDIN: | ||
777 | case NAND_CMD_STATUS: | 795 | case NAND_CMD_STATUS: |
778 | return; | 796 | return; |
779 | 797 | ||
798 | case NAND_CMD_RNDIN: | ||
799 | nand_ccs_delay(chip); | ||
800 | return; | ||
801 | |||
780 | case NAND_CMD_RESET: | 802 | case NAND_CMD_RESET: |
781 | if (chip->dev_ready) | 803 | if (chip->dev_ready) |
782 | break; | 804 | break; |
@@ -795,6 +817,8 @@ static void nand_command_lp(struct mtd_info *mtd, unsigned int command, | |||
795 | NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE); | 817 | NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE); |
796 | chip->cmd_ctrl(mtd, NAND_CMD_NONE, | 818 | chip->cmd_ctrl(mtd, NAND_CMD_NONE, |
797 | NAND_NCE | NAND_CTRL_CHANGE); | 819 | NAND_NCE | NAND_CTRL_CHANGE); |
820 | |||
821 | nand_ccs_delay(chip); | ||
798 | return; | 822 | return; |
799 | 823 | ||
800 | case NAND_CMD_READ0: | 824 | case NAND_CMD_READ0: |
@@ -1946,7 +1970,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
1946 | __func__, buf); | 1970 | __func__, buf); |
1947 | 1971 | ||
1948 | read_retry: | 1972 | read_retry: |
1949 | chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); | 1973 | if (nand_standard_page_accessors(&chip->ecc)) |
1974 | chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); | ||
1950 | 1975 | ||
1951 | /* | 1976 | /* |
1952 | * Now read the page into the buffer. Absent an error, | 1977 | * Now read the page into the buffer. Absent an error, |
@@ -2634,7 +2659,8 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
2634 | else | 2659 | else |
2635 | subpage = 0; | 2660 | subpage = 0; |
2636 | 2661 | ||
2637 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); | 2662 | if (nand_standard_page_accessors(&chip->ecc)) |
2663 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); | ||
2638 | 2664 | ||
2639 | if (unlikely(raw)) | 2665 | if (unlikely(raw)) |
2640 | status = chip->ecc.write_page_raw(mtd, chip, buf, | 2666 | status = chip->ecc.write_page_raw(mtd, chip, buf, |
@@ -2657,7 +2683,8 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
2657 | 2683 | ||
2658 | if (!cached || !NAND_HAS_CACHEPROG(chip)) { | 2684 | if (!cached || !NAND_HAS_CACHEPROG(chip)) { |
2659 | 2685 | ||
2660 | chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); | 2686 | if (nand_standard_page_accessors(&chip->ecc)) |
2687 | chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); | ||
2661 | status = chip->waitfunc(mtd, chip); | 2688 | status = chip->waitfunc(mtd, chip); |
2662 | /* | 2689 | /* |
2663 | * See if operation failed and additional status checks are | 2690 | * See if operation failed and additional status checks are |
@@ -3985,10 +4012,9 @@ static bool find_full_id_nand(struct mtd_info *mtd, struct nand_chip *chip, | |||
3985 | /* | 4012 | /* |
3986 | * Get the flash and manufacturer id and lookup if the type is supported. | 4013 | * Get the flash and manufacturer id and lookup if the type is supported. |
3987 | */ | 4014 | */ |
3988 | static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | 4015 | static int nand_get_flash_type(struct mtd_info *mtd, struct nand_chip *chip, |
3989 | struct nand_chip *chip, | 4016 | int *maf_id, int *dev_id, |
3990 | int *maf_id, int *dev_id, | 4017 | struct nand_flash_dev *type) |
3991 | struct nand_flash_dev *type) | ||
3992 | { | 4018 | { |
3993 | int busw; | 4019 | int busw; |
3994 | int i, maf_idx; | 4020 | int i, maf_idx; |
@@ -4026,7 +4052,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
4026 | if (id_data[0] != *maf_id || id_data[1] != *dev_id) { | 4052 | if (id_data[0] != *maf_id || id_data[1] != *dev_id) { |
4027 | pr_info("second ID read did not match %02x,%02x against %02x,%02x\n", | 4053 | pr_info("second ID read did not match %02x,%02x against %02x,%02x\n", |
4028 | *maf_id, *dev_id, id_data[0], id_data[1]); | 4054 | *maf_id, *dev_id, id_data[0], id_data[1]); |
4029 | return ERR_PTR(-ENODEV); | 4055 | return -ENODEV; |
4030 | } | 4056 | } |
4031 | 4057 | ||
4032 | if (!type) | 4058 | if (!type) |
@@ -4053,7 +4079,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
4053 | } | 4079 | } |
4054 | 4080 | ||
4055 | if (!type->name) | 4081 | if (!type->name) |
4056 | return ERR_PTR(-ENODEV); | 4082 | return -ENODEV; |
4057 | 4083 | ||
4058 | if (!mtd->name) | 4084 | if (!mtd->name) |
4059 | mtd->name = type->name; | 4085 | mtd->name = type->name; |
@@ -4098,7 +4124,7 @@ ident_done: | |||
4098 | pr_warn("bus width %d instead %d bit\n", | 4124 | pr_warn("bus width %d instead %d bit\n", |
4099 | (chip->options & NAND_BUSWIDTH_16) ? 16 : 8, | 4125 | (chip->options & NAND_BUSWIDTH_16) ? 16 : 8, |
4100 | busw ? 16 : 8); | 4126 | busw ? 16 : 8); |
4101 | return ERR_PTR(-EINVAL); | 4127 | return -EINVAL; |
4102 | } | 4128 | } |
4103 | 4129 | ||
4104 | nand_decode_bbm_options(mtd, chip, id_data); | 4130 | nand_decode_bbm_options(mtd, chip, id_data); |
@@ -4140,7 +4166,7 @@ ident_done: | |||
4140 | pr_info("%d MiB, %s, erase size: %d KiB, page size: %d, OOB size: %d\n", | 4166 | pr_info("%d MiB, %s, erase size: %d KiB, page size: %d, OOB size: %d\n", |
4141 | (int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC", | 4167 | (int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC", |
4142 | mtd->erasesize >> 10, mtd->writesize, mtd->oobsize); | 4168 | mtd->erasesize >> 10, mtd->writesize, mtd->oobsize); |
4143 | return type; | 4169 | return 0; |
4144 | } | 4170 | } |
4145 | 4171 | ||
4146 | static const char * const nand_ecc_modes[] = { | 4172 | static const char * const nand_ecc_modes[] = { |
@@ -4306,7 +4332,6 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, | |||
4306 | { | 4332 | { |
4307 | int i, nand_maf_id, nand_dev_id; | 4333 | int i, nand_maf_id, nand_dev_id; |
4308 | struct nand_chip *chip = mtd_to_nand(mtd); | 4334 | struct nand_chip *chip = mtd_to_nand(mtd); |
4309 | struct nand_flash_dev *type; | ||
4310 | int ret; | 4335 | int ret; |
4311 | 4336 | ||
4312 | ret = nand_dt_init(chip); | 4337 | ret = nand_dt_init(chip); |
@@ -4329,14 +4354,12 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, | |||
4329 | nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16); | 4354 | nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16); |
4330 | 4355 | ||
4331 | /* Read the flash type */ | 4356 | /* Read the flash type */ |
4332 | type = nand_get_flash_type(mtd, chip, &nand_maf_id, | 4357 | ret = nand_get_flash_type(mtd, chip, &nand_maf_id, &nand_dev_id, table); |
4333 | &nand_dev_id, table); | 4358 | if (ret) { |
4334 | |||
4335 | if (IS_ERR(type)) { | ||
4336 | if (!(chip->options & NAND_SCAN_SILENT_NODEV)) | 4359 | if (!(chip->options & NAND_SCAN_SILENT_NODEV)) |
4337 | pr_warn("No NAND device found\n"); | 4360 | pr_warn("No NAND device found\n"); |
4338 | chip->select_chip(mtd, -1); | 4361 | chip->select_chip(mtd, -1); |
4339 | return PTR_ERR(type); | 4362 | return ret; |
4340 | } | 4363 | } |
4341 | 4364 | ||
4342 | /* Initialize the ->data_interface field. */ | 4365 | /* Initialize the ->data_interface field. */ |
@@ -4515,6 +4538,26 @@ static bool nand_ecc_strength_good(struct mtd_info *mtd) | |||
4515 | return corr >= ds_corr && ecc->strength >= chip->ecc_strength_ds; | 4538 | return corr >= ds_corr && ecc->strength >= chip->ecc_strength_ds; |
4516 | } | 4539 | } |
4517 | 4540 | ||
4541 | static bool invalid_ecc_page_accessors(struct nand_chip *chip) | ||
4542 | { | ||
4543 | struct nand_ecc_ctrl *ecc = &chip->ecc; | ||
4544 | |||
4545 | if (nand_standard_page_accessors(ecc)) | ||
4546 | return false; | ||
4547 | |||
4548 | /* | ||
4549 | * NAND_ECC_CUSTOM_PAGE_ACCESS flag is set, make sure the NAND | ||
4550 | * controller driver implements all the page accessors because | ||
4551 | * default helpers are not suitable when the core does not | ||
4552 | * send the READ0/PAGEPROG commands. | ||
4553 | */ | ||
4554 | return (!ecc->read_page || !ecc->write_page || | ||
4555 | !ecc->read_page_raw || !ecc->write_page_raw || | ||
4556 | (NAND_HAS_SUBPAGE_READ(chip) && !ecc->read_subpage) || | ||
4557 | (NAND_HAS_SUBPAGE_WRITE(chip) && !ecc->write_subpage && | ||
4558 | ecc->hwctl && ecc->calculate)); | ||
4559 | } | ||
4560 | |||
4518 | /** | 4561 | /** |
4519 | * nand_scan_tail - [NAND Interface] Scan for the NAND device | 4562 | * nand_scan_tail - [NAND Interface] Scan for the NAND device |
4520 | * @mtd: MTD device structure | 4563 | * @mtd: MTD device structure |
@@ -4535,6 +4578,11 @@ int nand_scan_tail(struct mtd_info *mtd) | |||
4535 | !(chip->bbt_options & NAND_BBT_USE_FLASH))) | 4578 | !(chip->bbt_options & NAND_BBT_USE_FLASH))) |
4536 | return -EINVAL; | 4579 | return -EINVAL; |
4537 | 4580 | ||
4581 | if (invalid_ecc_page_accessors(chip)) { | ||
4582 | pr_err("Invalid ECC page accessors setup\n"); | ||
4583 | return -EINVAL; | ||
4584 | } | ||
4585 | |||
4538 | if (!(chip->options & NAND_OWN_BUFFERS)) { | 4586 | if (!(chip->options & NAND_OWN_BUFFERS)) { |
4539 | nbuf = kzalloc(sizeof(*nbuf) + mtd->writesize | 4587 | nbuf = kzalloc(sizeof(*nbuf) + mtd->writesize |
4540 | + mtd->oobsize * 3, GFP_KERNEL); | 4588 | + mtd->oobsize * 3, GFP_KERNEL); |
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c index 2af9869a115e..b3a332f37e14 100644 --- a/drivers/mtd/nand/nand_ids.c +++ b/drivers/mtd/nand/nand_ids.c | |||
@@ -36,6 +36,9 @@ struct nand_flash_dev nand_flash_ids[] = { | |||
36 | {"TC58NVG2S0F 4G 3.3V 8-bit", | 36 | {"TC58NVG2S0F 4G 3.3V 8-bit", |
37 | { .id = {0x98, 0xdc, 0x90, 0x26, 0x76, 0x15, 0x01, 0x08} }, | 37 | { .id = {0x98, 0xdc, 0x90, 0x26, 0x76, 0x15, 0x01, 0x08} }, |
38 | SZ_4K, SZ_512, SZ_256K, 0, 8, 224, NAND_ECC_INFO(4, SZ_512) }, | 38 | SZ_4K, SZ_512, SZ_256K, 0, 8, 224, NAND_ECC_INFO(4, SZ_512) }, |
39 | {"TC58NVG2S0H 4G 3.3V 8-bit", | ||
40 | { .id = {0x98, 0xdc, 0x90, 0x26, 0x76, 0x16, 0x08, 0x00} }, | ||
41 | SZ_4K, SZ_512, SZ_256K, 0, 8, 256, NAND_ECC_INFO(8, SZ_512) }, | ||
39 | {"TC58NVG3S0F 8G 3.3V 8-bit", | 42 | {"TC58NVG3S0F 8G 3.3V 8-bit", |
40 | { .id = {0x98, 0xd3, 0x90, 0x26, 0x76, 0x15, 0x02, 0x08} }, | 43 | { .id = {0x98, 0xd3, 0x90, 0x26, 0x76, 0x15, 0x02, 0x08} }, |
41 | SZ_4K, SZ_1K, SZ_256K, 0, 8, 232, NAND_ECC_INFO(4, SZ_512) }, | 44 | SZ_4K, SZ_1K, SZ_256K, 0, 8, 232, NAND_ECC_INFO(4, SZ_512) }, |
diff --git a/drivers/mtd/nand/nand_timings.c b/drivers/mtd/nand/nand_timings.c index 13a587407be3..f06312df3669 100644 --- a/drivers/mtd/nand/nand_timings.c +++ b/drivers/mtd/nand/nand_timings.c | |||
@@ -18,6 +18,8 @@ static const struct nand_data_interface onfi_sdr_timings[] = { | |||
18 | { | 18 | { |
19 | .type = NAND_SDR_IFACE, | 19 | .type = NAND_SDR_IFACE, |
20 | .timings.sdr = { | 20 | .timings.sdr = { |
21 | .tCCS_min = 500000, | ||
22 | .tR_max = 200000000, | ||
21 | .tADL_min = 400000, | 23 | .tADL_min = 400000, |
22 | .tALH_min = 20000, | 24 | .tALH_min = 20000, |
23 | .tALS_min = 50000, | 25 | .tALS_min = 50000, |
@@ -58,6 +60,8 @@ static const struct nand_data_interface onfi_sdr_timings[] = { | |||
58 | { | 60 | { |
59 | .type = NAND_SDR_IFACE, | 61 | .type = NAND_SDR_IFACE, |
60 | .timings.sdr = { | 62 | .timings.sdr = { |
63 | .tCCS_min = 500000, | ||
64 | .tR_max = 200000000, | ||
61 | .tADL_min = 400000, | 65 | .tADL_min = 400000, |
62 | .tALH_min = 10000, | 66 | .tALH_min = 10000, |
63 | .tALS_min = 25000, | 67 | .tALS_min = 25000, |
@@ -98,6 +102,8 @@ static const struct nand_data_interface onfi_sdr_timings[] = { | |||
98 | { | 102 | { |
99 | .type = NAND_SDR_IFACE, | 103 | .type = NAND_SDR_IFACE, |
100 | .timings.sdr = { | 104 | .timings.sdr = { |
105 | .tCCS_min = 500000, | ||
106 | .tR_max = 200000000, | ||
101 | .tADL_min = 400000, | 107 | .tADL_min = 400000, |
102 | .tALH_min = 10000, | 108 | .tALH_min = 10000, |
103 | .tALS_min = 15000, | 109 | .tALS_min = 15000, |
@@ -138,6 +144,8 @@ static const struct nand_data_interface onfi_sdr_timings[] = { | |||
138 | { | 144 | { |
139 | .type = NAND_SDR_IFACE, | 145 | .type = NAND_SDR_IFACE, |
140 | .timings.sdr = { | 146 | .timings.sdr = { |
147 | .tCCS_min = 500000, | ||
148 | .tR_max = 200000000, | ||
141 | .tADL_min = 400000, | 149 | .tADL_min = 400000, |
142 | .tALH_min = 5000, | 150 | .tALH_min = 5000, |
143 | .tALS_min = 10000, | 151 | .tALS_min = 10000, |
@@ -178,6 +186,8 @@ static const struct nand_data_interface onfi_sdr_timings[] = { | |||
178 | { | 186 | { |
179 | .type = NAND_SDR_IFACE, | 187 | .type = NAND_SDR_IFACE, |
180 | .timings.sdr = { | 188 | .timings.sdr = { |
189 | .tCCS_min = 500000, | ||
190 | .tR_max = 200000000, | ||
181 | .tADL_min = 400000, | 191 | .tADL_min = 400000, |
182 | .tALH_min = 5000, | 192 | .tALH_min = 5000, |
183 | .tALS_min = 10000, | 193 | .tALS_min = 10000, |
@@ -218,6 +228,8 @@ static const struct nand_data_interface onfi_sdr_timings[] = { | |||
218 | { | 228 | { |
219 | .type = NAND_SDR_IFACE, | 229 | .type = NAND_SDR_IFACE, |
220 | .timings.sdr = { | 230 | .timings.sdr = { |
231 | .tCCS_min = 500000, | ||
232 | .tR_max = 200000000, | ||
221 | .tADL_min = 400000, | 233 | .tADL_min = 400000, |
222 | .tALH_min = 5000, | 234 | .tALH_min = 5000, |
223 | .tALS_min = 10000, | 235 | .tALS_min = 10000, |
@@ -290,10 +302,22 @@ int onfi_init_data_interface(struct nand_chip *chip, | |||
290 | *iface = onfi_sdr_timings[timing_mode]; | 302 | *iface = onfi_sdr_timings[timing_mode]; |
291 | 303 | ||
292 | /* | 304 | /* |
293 | * TODO: initialize timings that cannot be deduced from timing mode: | 305 | * Initialize timings that cannot be deduced from timing mode: |
294 | * tR, tPROG, tCCS, ... | 306 | * tR, tPROG, tCCS, ... |
295 | * These information are part of the ONFI parameter page. | 307 | * These information are part of the ONFI parameter page. |
296 | */ | 308 | */ |
309 | if (chip->onfi_version) { | ||
310 | struct nand_onfi_params *params = &chip->onfi_params; | ||
311 | struct nand_sdr_timings *timings = &iface->timings.sdr; | ||
312 | |||
313 | /* microseconds -> picoseconds */ | ||
314 | timings->tPROG_max = 1000000UL * le16_to_cpu(params->t_prog); | ||
315 | timings->tBERS_max = 1000000UL * le16_to_cpu(params->t_bers); | ||
316 | timings->tR_max = 1000000UL * le16_to_cpu(params->t_r); | ||
317 | |||
318 | /* nanoseconds -> picoseconds */ | ||
319 | timings->tCCS_min = 1000UL * le16_to_cpu(params->t_ccs); | ||
320 | } | ||
297 | 321 | ||
298 | return 0; | 322 | return 0; |
299 | } | 323 | } |
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index 1eb934414eb5..c84742671a5f 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c | |||
@@ -525,24 +525,20 @@ static int nandsim_debugfs_create(struct nandsim *dev) | |||
525 | { | 525 | { |
526 | struct nandsim_debug_info *dbg = &dev->dbg; | 526 | struct nandsim_debug_info *dbg = &dev->dbg; |
527 | struct dentry *dent; | 527 | struct dentry *dent; |
528 | int err; | ||
529 | 528 | ||
530 | if (!IS_ENABLED(CONFIG_DEBUG_FS)) | 529 | if (!IS_ENABLED(CONFIG_DEBUG_FS)) |
531 | return 0; | 530 | return 0; |
532 | 531 | ||
533 | dent = debugfs_create_dir("nandsim", NULL); | 532 | dent = debugfs_create_dir("nandsim", NULL); |
534 | if (IS_ERR_OR_NULL(dent)) { | 533 | if (!dent) { |
535 | int err = dent ? -ENODEV : PTR_ERR(dent); | 534 | NS_ERR("cannot create \"nandsim\" debugfs directory\n"); |
536 | 535 | return -ENODEV; | |
537 | NS_ERR("cannot create \"nandsim\" debugfs directory, err %d\n", | ||
538 | err); | ||
539 | return err; | ||
540 | } | 536 | } |
541 | dbg->dfs_root = dent; | 537 | dbg->dfs_root = dent; |
542 | 538 | ||
543 | dent = debugfs_create_file("wear_report", S_IRUSR, | 539 | dent = debugfs_create_file("wear_report", S_IRUSR, |
544 | dbg->dfs_root, dev, &dfs_fops); | 540 | dbg->dfs_root, dev, &dfs_fops); |
545 | if (IS_ERR_OR_NULL(dent)) | 541 | if (!dent) |
546 | goto out_remove; | 542 | goto out_remove; |
547 | dbg->dfs_wear_report = dent; | 543 | dbg->dfs_wear_report = dent; |
548 | 544 | ||
@@ -550,8 +546,7 @@ static int nandsim_debugfs_create(struct nandsim *dev) | |||
550 | 546 | ||
551 | out_remove: | 547 | out_remove: |
552 | debugfs_remove_recursive(dbg->dfs_root); | 548 | debugfs_remove_recursive(dbg->dfs_root); |
553 | err = dent ? PTR_ERR(dent) : -ENODEV; | 549 | return -ENODEV; |
554 | return err; | ||
555 | } | 550 | } |
556 | 551 | ||
557 | /** | 552 | /** |
@@ -2313,8 +2308,6 @@ static int __init ns_init_module(void) | |||
2313 | retval = nand_scan_ident(nsmtd, 1, NULL); | 2308 | retval = nand_scan_ident(nsmtd, 1, NULL); |
2314 | if (retval) { | 2309 | if (retval) { |
2315 | NS_ERR("cannot scan NAND Simulator device\n"); | 2310 | NS_ERR("cannot scan NAND Simulator device\n"); |
2316 | if (retval > 0) | ||
2317 | retval = -ENXIO; | ||
2318 | goto error; | 2311 | goto error; |
2319 | } | 2312 | } |
2320 | 2313 | ||
@@ -2350,8 +2343,6 @@ static int __init ns_init_module(void) | |||
2350 | retval = nand_scan_tail(nsmtd); | 2343 | retval = nand_scan_tail(nsmtd); |
2351 | if (retval) { | 2344 | if (retval) { |
2352 | NS_ERR("can't register NAND Simulator\n"); | 2345 | NS_ERR("can't register NAND Simulator\n"); |
2353 | if (retval > 0) | ||
2354 | retval = -ENXIO; | ||
2355 | goto error; | 2346 | goto error; |
2356 | } | 2347 | } |
2357 | 2348 | ||
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 5513bfd9cdc9..2a52101120d4 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
@@ -1895,10 +1895,10 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1895 | 1895 | ||
1896 | /* scan NAND device connected to chip controller */ | 1896 | /* scan NAND device connected to chip controller */ |
1897 | nand_chip->options |= info->devsize & NAND_BUSWIDTH_16; | 1897 | nand_chip->options |= info->devsize & NAND_BUSWIDTH_16; |
1898 | if (nand_scan_ident(mtd, 1, NULL)) { | 1898 | err = nand_scan_ident(mtd, 1, NULL); |
1899 | if (err) { | ||
1899 | dev_err(&info->pdev->dev, | 1900 | dev_err(&info->pdev->dev, |
1900 | "scan failed, may be bus-width mismatch\n"); | 1901 | "scan failed, may be bus-width mismatch\n"); |
1901 | err = -ENXIO; | ||
1902 | goto return_error; | 1902 | goto return_error; |
1903 | } | 1903 | } |
1904 | 1904 | ||
@@ -2154,10 +2154,9 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
2154 | 2154 | ||
2155 | scan_tail: | 2155 | scan_tail: |
2156 | /* second phase scan */ | 2156 | /* second phase scan */ |
2157 | if (nand_scan_tail(mtd)) { | 2157 | err = nand_scan_tail(mtd); |
2158 | err = -ENXIO; | 2158 | if (err) |
2159 | goto return_error; | 2159 | goto return_error; |
2160 | } | ||
2161 | 2160 | ||
2162 | if (dev->of_node) | 2161 | if (dev->of_node) |
2163 | mtd_device_register(mtd, NULL, 0); | 2162 | mtd_device_register(mtd, NULL, 0); |
@@ -2197,6 +2196,7 @@ static const struct of_device_id omap_nand_ids[] = { | |||
2197 | { .compatible = "ti,omap2-nand", }, | 2196 | { .compatible = "ti,omap2-nand", }, |
2198 | {}, | 2197 | {}, |
2199 | }; | 2198 | }; |
2199 | MODULE_DEVICE_TABLE(of, omap_nand_ids); | ||
2200 | 2200 | ||
2201 | static struct platform_driver omap_nand_driver = { | 2201 | static struct platform_driver omap_nand_driver = { |
2202 | .probe = omap_nand_probe, | 2202 | .probe = omap_nand_probe, |
diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index 40a7c4a2cf0d..4a91c5d000be 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c | |||
@@ -155,10 +155,9 @@ static int __init orion_nand_probe(struct platform_device *pdev) | |||
155 | clk_put(clk); | 155 | clk_put(clk); |
156 | } | 156 | } |
157 | 157 | ||
158 | if (nand_scan(mtd, 1)) { | 158 | ret = nand_scan(mtd, 1); |
159 | ret = -ENXIO; | 159 | if (ret) |
160 | goto no_dev; | 160 | goto no_dev; |
161 | } | ||
162 | 161 | ||
163 | mtd->name = "orion_nand"; | 162 | mtd->name = "orion_nand"; |
164 | ret = mtd_device_register(mtd, board->parts, board->nr_parts); | 163 | ret = mtd_device_register(mtd, board->parts, board->nr_parts); |
diff --git a/drivers/mtd/nand/oxnas_nand.c b/drivers/mtd/nand/oxnas_nand.c new file mode 100644 index 000000000000..3e3bf3b364d2 --- /dev/null +++ b/drivers/mtd/nand/oxnas_nand.c | |||
@@ -0,0 +1,195 @@ | |||
1 | /* | ||
2 | * Oxford Semiconductor OXNAS NAND driver | ||
3 | |||
4 | * Copyright (C) 2016 Neil Armstrong <narmstrong@baylibre.com> | ||
5 | * Heavily based on plat_nand.c : | ||
6 | * Author: Vitaly Wool <vitalywool@gmail.com> | ||
7 | * Copyright (C) 2013 Ma Haijun <mahaijuns@gmail.com> | ||
8 | * Copyright (C) 2012 John Crispin <blogic@openwrt.org> | ||
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 | */ | ||
15 | |||
16 | #include <linux/err.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/clk.h> | ||
22 | #include <linux/reset.h> | ||
23 | #include <linux/mtd/mtd.h> | ||
24 | #include <linux/mtd/nand.h> | ||
25 | #include <linux/mtd/partitions.h> | ||
26 | #include <linux/of.h> | ||
27 | |||
28 | /* Nand commands */ | ||
29 | #define OXNAS_NAND_CMD_ALE BIT(18) | ||
30 | #define OXNAS_NAND_CMD_CLE BIT(19) | ||
31 | |||
32 | #define OXNAS_NAND_MAX_CHIPS 1 | ||
33 | |||
34 | struct oxnas_nand_ctrl { | ||
35 | struct nand_hw_control base; | ||
36 | void __iomem *io_base; | ||
37 | struct clk *clk; | ||
38 | struct nand_chip *chips[OXNAS_NAND_MAX_CHIPS]; | ||
39 | }; | ||
40 | |||
41 | static uint8_t oxnas_nand_read_byte(struct mtd_info *mtd) | ||
42 | { | ||
43 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
44 | struct oxnas_nand_ctrl *oxnas = nand_get_controller_data(chip); | ||
45 | |||
46 | return readb(oxnas->io_base); | ||
47 | } | ||
48 | |||
49 | static void oxnas_nand_read_buf(struct mtd_info *mtd, u8 *buf, int len) | ||
50 | { | ||
51 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
52 | struct oxnas_nand_ctrl *oxnas = nand_get_controller_data(chip); | ||
53 | |||
54 | ioread8_rep(oxnas->io_base, buf, len); | ||
55 | } | ||
56 | |||
57 | static void oxnas_nand_write_buf(struct mtd_info *mtd, const u8 *buf, int len) | ||
58 | { | ||
59 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
60 | struct oxnas_nand_ctrl *oxnas = nand_get_controller_data(chip); | ||
61 | |||
62 | iowrite8_rep(oxnas->io_base, buf, len); | ||
63 | } | ||
64 | |||
65 | /* Single CS command control */ | ||
66 | static void oxnas_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, | ||
67 | unsigned int ctrl) | ||
68 | { | ||
69 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
70 | struct oxnas_nand_ctrl *oxnas = nand_get_controller_data(chip); | ||
71 | |||
72 | if (ctrl & NAND_CLE) | ||
73 | writeb(cmd, oxnas->io_base + OXNAS_NAND_CMD_CLE); | ||
74 | else if (ctrl & NAND_ALE) | ||
75 | writeb(cmd, oxnas->io_base + OXNAS_NAND_CMD_ALE); | ||
76 | } | ||
77 | |||
78 | /* | ||
79 | * Probe for the NAND device. | ||
80 | */ | ||
81 | static int oxnas_nand_probe(struct platform_device *pdev) | ||
82 | { | ||
83 | struct device_node *np = pdev->dev.of_node; | ||
84 | struct device_node *nand_np; | ||
85 | struct oxnas_nand_ctrl *oxnas; | ||
86 | struct nand_chip *chip; | ||
87 | struct mtd_info *mtd; | ||
88 | struct resource *res; | ||
89 | int nchips = 0; | ||
90 | int count = 0; | ||
91 | int err = 0; | ||
92 | |||
93 | /* Allocate memory for the device structure (and zero it) */ | ||
94 | oxnas = devm_kzalloc(&pdev->dev, sizeof(struct nand_chip), | ||
95 | GFP_KERNEL); | ||
96 | if (!oxnas) | ||
97 | return -ENOMEM; | ||
98 | |||
99 | nand_hw_control_init(&oxnas->base); | ||
100 | |||
101 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
102 | oxnas->io_base = devm_ioremap_resource(&pdev->dev, res); | ||
103 | if (IS_ERR(oxnas->io_base)) | ||
104 | return PTR_ERR(oxnas->io_base); | ||
105 | |||
106 | oxnas->clk = devm_clk_get(&pdev->dev, NULL); | ||
107 | if (IS_ERR(oxnas->clk)) | ||
108 | oxnas->clk = NULL; | ||
109 | |||
110 | /* Only a single chip node is supported */ | ||
111 | count = of_get_child_count(np); | ||
112 | if (count > 1) | ||
113 | return -EINVAL; | ||
114 | |||
115 | clk_prepare_enable(oxnas->clk); | ||
116 | device_reset_optional(&pdev->dev); | ||
117 | |||
118 | for_each_child_of_node(np, nand_np) { | ||
119 | chip = devm_kzalloc(&pdev->dev, sizeof(struct nand_chip), | ||
120 | GFP_KERNEL); | ||
121 | if (!chip) | ||
122 | return -ENOMEM; | ||
123 | |||
124 | chip->controller = &oxnas->base; | ||
125 | |||
126 | nand_set_flash_node(chip, nand_np); | ||
127 | nand_set_controller_data(chip, oxnas); | ||
128 | |||
129 | mtd = nand_to_mtd(chip); | ||
130 | mtd->dev.parent = &pdev->dev; | ||
131 | mtd->priv = chip; | ||
132 | |||
133 | chip->cmd_ctrl = oxnas_nand_cmd_ctrl; | ||
134 | chip->read_buf = oxnas_nand_read_buf; | ||
135 | chip->read_byte = oxnas_nand_read_byte; | ||
136 | chip->write_buf = oxnas_nand_write_buf; | ||
137 | chip->chip_delay = 30; | ||
138 | |||
139 | /* Scan to find existence of the device */ | ||
140 | err = nand_scan(mtd, 1); | ||
141 | if (err) | ||
142 | return err; | ||
143 | |||
144 | err = mtd_device_register(mtd, NULL, 0); | ||
145 | if (err) { | ||
146 | nand_release(mtd); | ||
147 | return err; | ||
148 | } | ||
149 | |||
150 | oxnas->chips[nchips] = chip; | ||
151 | ++nchips; | ||
152 | } | ||
153 | |||
154 | /* Exit if no chips found */ | ||
155 | if (!nchips) | ||
156 | return -ENODEV; | ||
157 | |||
158 | platform_set_drvdata(pdev, oxnas); | ||
159 | |||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | static int oxnas_nand_remove(struct platform_device *pdev) | ||
164 | { | ||
165 | struct oxnas_nand_ctrl *oxnas = platform_get_drvdata(pdev); | ||
166 | |||
167 | if (oxnas->chips[0]) | ||
168 | nand_release(nand_to_mtd(oxnas->chips[0])); | ||
169 | |||
170 | clk_disable_unprepare(oxnas->clk); | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static const struct of_device_id oxnas_nand_match[] = { | ||
176 | { .compatible = "oxsemi,ox820-nand" }, | ||
177 | {}, | ||
178 | }; | ||
179 | MODULE_DEVICE_TABLE(of, oxnas_nand_match); | ||
180 | |||
181 | static struct platform_driver oxnas_nand_driver = { | ||
182 | .probe = oxnas_nand_probe, | ||
183 | .remove = oxnas_nand_remove, | ||
184 | .driver = { | ||
185 | .name = "oxnas_nand", | ||
186 | .of_match_table = oxnas_nand_match, | ||
187 | }, | ||
188 | }; | ||
189 | |||
190 | module_platform_driver(oxnas_nand_driver); | ||
191 | |||
192 | MODULE_LICENSE("GPL"); | ||
193 | MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>"); | ||
194 | MODULE_DESCRIPTION("Oxnas NAND driver"); | ||
195 | MODULE_ALIAS("platform:oxnas_nand"); | ||
diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index 5de7591b0510..074b8b01289e 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c | |||
@@ -156,10 +156,9 @@ static int pasemi_nand_probe(struct platform_device *ofdev) | |||
156 | chip->bbt_options = NAND_BBT_USE_FLASH; | 156 | chip->bbt_options = NAND_BBT_USE_FLASH; |
157 | 157 | ||
158 | /* Scan to find existence of the device */ | 158 | /* Scan to find existence of the device */ |
159 | if (nand_scan(pasemi_nand_mtd, 1)) { | 159 | err = nand_scan(pasemi_nand_mtd, 1); |
160 | err = -ENXIO; | 160 | if (err) |
161 | goto out_lpc; | 161 | goto out_lpc; |
162 | } | ||
163 | 162 | ||
164 | if (mtd_device_register(pasemi_nand_mtd, NULL, 0)) { | 163 | if (mtd_device_register(pasemi_nand_mtd, NULL, 0)) { |
165 | dev_err(dev, "Unable to register MTD device\n"); | 164 | dev_err(dev, "Unable to register MTD device\n"); |
diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c index 415a53a0deeb..791de3e4bbb6 100644 --- a/drivers/mtd/nand/plat_nand.c +++ b/drivers/mtd/nand/plat_nand.c | |||
@@ -86,10 +86,9 @@ static int plat_nand_probe(struct platform_device *pdev) | |||
86 | } | 86 | } |
87 | 87 | ||
88 | /* Scan to find existence of the device */ | 88 | /* Scan to find existence of the device */ |
89 | if (nand_scan(mtd, pdata->chip.nr_chips)) { | 89 | err = nand_scan(mtd, pdata->chip.nr_chips); |
90 | err = -ENXIO; | 90 | if (err) |
91 | goto out; | 91 | goto out; |
92 | } | ||
93 | 92 | ||
94 | part_types = pdata->chip.part_probe_types; | 93 | part_types = pdata->chip.part_probe_types; |
95 | 94 | ||
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index b121bf4ed73a..649ba8200832 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c | |||
@@ -1680,8 +1680,9 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) | |||
1680 | chip->ecc.strength = pdata->ecc_strength; | 1680 | chip->ecc.strength = pdata->ecc_strength; |
1681 | chip->ecc.size = pdata->ecc_step_size; | 1681 | chip->ecc.size = pdata->ecc_step_size; |
1682 | 1682 | ||
1683 | if (nand_scan_ident(mtd, 1, NULL)) | 1683 | ret = nand_scan_ident(mtd, 1, NULL); |
1684 | return -ENODEV; | 1684 | if (ret) |
1685 | return ret; | ||
1685 | 1686 | ||
1686 | if (!pdata->keep_config) { | 1687 | if (!pdata->keep_config) { |
1687 | ret = pxa3xx_nand_init(host); | 1688 | ret = pxa3xx_nand_init(host); |
@@ -1774,8 +1775,11 @@ static int alloc_nand_resource(struct platform_device *pdev) | |||
1774 | int ret, irq, cs; | 1775 | int ret, irq, cs; |
1775 | 1776 | ||
1776 | pdata = dev_get_platdata(&pdev->dev); | 1777 | pdata = dev_get_platdata(&pdev->dev); |
1777 | if (pdata->num_cs <= 0) | 1778 | if (pdata->num_cs <= 0) { |
1779 | dev_err(&pdev->dev, "invalid number of chip selects\n"); | ||
1778 | return -ENODEV; | 1780 | return -ENODEV; |
1781 | } | ||
1782 | |||
1779 | info = devm_kzalloc(&pdev->dev, | 1783 | info = devm_kzalloc(&pdev->dev, |
1780 | sizeof(*info) + sizeof(*host) * pdata->num_cs, | 1784 | sizeof(*info) + sizeof(*host) * pdata->num_cs, |
1781 | GFP_KERNEL); | 1785 | GFP_KERNEL); |
@@ -1813,8 +1817,9 @@ static int alloc_nand_resource(struct platform_device *pdev) | |||
1813 | nand_hw_control_init(chip->controller); | 1817 | nand_hw_control_init(chip->controller); |
1814 | info->clk = devm_clk_get(&pdev->dev, NULL); | 1818 | info->clk = devm_clk_get(&pdev->dev, NULL); |
1815 | if (IS_ERR(info->clk)) { | 1819 | if (IS_ERR(info->clk)) { |
1816 | dev_err(&pdev->dev, "failed to get nand clock\n"); | 1820 | ret = PTR_ERR(info->clk); |
1817 | return PTR_ERR(info->clk); | 1821 | dev_err(&pdev->dev, "failed to get nand clock: %d\n", ret); |
1822 | return ret; | ||
1818 | } | 1823 | } |
1819 | ret = clk_prepare_enable(info->clk); | 1824 | ret = clk_prepare_enable(info->clk); |
1820 | if (ret < 0) | 1825 | if (ret < 0) |
@@ -1842,6 +1847,7 @@ static int alloc_nand_resource(struct platform_device *pdev) | |||
1842 | info->mmio_base = devm_ioremap_resource(&pdev->dev, r); | 1847 | info->mmio_base = devm_ioremap_resource(&pdev->dev, r); |
1843 | if (IS_ERR(info->mmio_base)) { | 1848 | if (IS_ERR(info->mmio_base)) { |
1844 | ret = PTR_ERR(info->mmio_base); | 1849 | ret = PTR_ERR(info->mmio_base); |
1850 | dev_err(&pdev->dev, "failed to map register space: %d\n", ret); | ||
1845 | goto fail_disable_clk; | 1851 | goto fail_disable_clk; |
1846 | } | 1852 | } |
1847 | info->mmio_phys = r->start; | 1853 | info->mmio_phys = r->start; |
@@ -1861,7 +1867,7 @@ static int alloc_nand_resource(struct platform_device *pdev) | |||
1861 | pxa3xx_nand_irq_thread, IRQF_ONESHOT, | 1867 | pxa3xx_nand_irq_thread, IRQF_ONESHOT, |
1862 | pdev->name, info); | 1868 | pdev->name, info); |
1863 | if (ret < 0) { | 1869 | if (ret < 0) { |
1864 | dev_err(&pdev->dev, "failed to request IRQ\n"); | 1870 | dev_err(&pdev->dev, "failed to request IRQ: %d\n", ret); |
1865 | goto fail_free_buf; | 1871 | goto fail_free_buf; |
1866 | } | 1872 | } |
1867 | 1873 | ||
@@ -1960,10 +1966,8 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) | |||
1960 | } | 1966 | } |
1961 | 1967 | ||
1962 | ret = alloc_nand_resource(pdev); | 1968 | ret = alloc_nand_resource(pdev); |
1963 | if (ret) { | 1969 | if (ret) |
1964 | dev_err(&pdev->dev, "alloc nand resource failed\n"); | ||
1965 | return ret; | 1970 | return ret; |
1966 | } | ||
1967 | 1971 | ||
1968 | info = platform_get_drvdata(pdev); | 1972 | info = platform_get_drvdata(pdev); |
1969 | probe_success = 0; | 1973 | probe_success = 0; |
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index d459c19d78de..f0b030d44f71 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c | |||
@@ -39,6 +39,8 @@ | |||
39 | #include <linux/slab.h> | 39 | #include <linux/slab.h> |
40 | #include <linux/clk.h> | 40 | #include <linux/clk.h> |
41 | #include <linux/cpufreq.h> | 41 | #include <linux/cpufreq.h> |
42 | #include <linux/of.h> | ||
43 | #include <linux/of_device.h> | ||
42 | 44 | ||
43 | #include <linux/mtd/mtd.h> | 45 | #include <linux/mtd/mtd.h> |
44 | #include <linux/mtd/nand.h> | 46 | #include <linux/mtd/nand.h> |
@@ -185,6 +187,22 @@ struct s3c2410_nand_info { | |||
185 | #endif | 187 | #endif |
186 | }; | 188 | }; |
187 | 189 | ||
190 | struct s3c24XX_nand_devtype_data { | ||
191 | enum s3c_cpu_type type; | ||
192 | }; | ||
193 | |||
194 | static const struct s3c24XX_nand_devtype_data s3c2410_nand_devtype_data = { | ||
195 | .type = TYPE_S3C2410, | ||
196 | }; | ||
197 | |||
198 | static const struct s3c24XX_nand_devtype_data s3c2412_nand_devtype_data = { | ||
199 | .type = TYPE_S3C2412, | ||
200 | }; | ||
201 | |||
202 | static const struct s3c24XX_nand_devtype_data s3c2440_nand_devtype_data = { | ||
203 | .type = TYPE_S3C2440, | ||
204 | }; | ||
205 | |||
188 | /* conversion functions */ | 206 | /* conversion functions */ |
189 | 207 | ||
190 | static struct s3c2410_nand_mtd *s3c2410_nand_mtd_toours(struct mtd_info *mtd) | 208 | static struct s3c2410_nand_mtd *s3c2410_nand_mtd_toours(struct mtd_info *mtd) |
@@ -497,7 +515,6 @@ static int s3c2412_nand_devready(struct mtd_info *mtd) | |||
497 | 515 | ||
498 | /* ECC handling functions */ | 516 | /* ECC handling functions */ |
499 | 517 | ||
500 | #ifdef CONFIG_MTD_NAND_S3C2410_HWECC | ||
501 | static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, | 518 | static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat, |
502 | u_char *read_ecc, u_char *calc_ecc) | 519 | u_char *read_ecc, u_char *calc_ecc) |
503 | { | 520 | { |
@@ -649,7 +666,6 @@ static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, | |||
649 | 666 | ||
650 | return 0; | 667 | return 0; |
651 | } | 668 | } |
652 | #endif | ||
653 | 669 | ||
654 | /* over-ride the standard functions for a little more speed. We can | 670 | /* over-ride the standard functions for a little more speed. We can |
655 | * use read/write block to move the data buffers to/from the controller | 671 | * use read/write block to move the data buffers to/from the controller |
@@ -796,6 +812,30 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info, | |||
796 | return -ENODEV; | 812 | return -ENODEV; |
797 | } | 813 | } |
798 | 814 | ||
815 | static int s3c2410_nand_setup_data_interface(struct mtd_info *mtd, | ||
816 | const struct nand_data_interface *conf, | ||
817 | bool check_only) | ||
818 | { | ||
819 | struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); | ||
820 | struct s3c2410_platform_nand *pdata = info->platform; | ||
821 | const struct nand_sdr_timings *timings; | ||
822 | int tacls; | ||
823 | |||
824 | timings = nand_get_sdr_timings(conf); | ||
825 | if (IS_ERR(timings)) | ||
826 | return -ENOTSUPP; | ||
827 | |||
828 | tacls = timings->tCLS_min - timings->tWP_min; | ||
829 | if (tacls < 0) | ||
830 | tacls = 0; | ||
831 | |||
832 | pdata->tacls = DIV_ROUND_UP(tacls, 1000); | ||
833 | pdata->twrph0 = DIV_ROUND_UP(timings->tWP_min, 1000); | ||
834 | pdata->twrph1 = DIV_ROUND_UP(timings->tCLH_min, 1000); | ||
835 | |||
836 | return s3c2410_nand_setrate(info); | ||
837 | } | ||
838 | |||
799 | /** | 839 | /** |
800 | * s3c2410_nand_init_chip - initialise a single instance of an chip | 840 | * s3c2410_nand_init_chip - initialise a single instance of an chip |
801 | * @info: The base NAND controller the chip is on. | 841 | * @info: The base NAND controller the chip is on. |
@@ -810,9 +850,12 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, | |||
810 | struct s3c2410_nand_mtd *nmtd, | 850 | struct s3c2410_nand_mtd *nmtd, |
811 | struct s3c2410_nand_set *set) | 851 | struct s3c2410_nand_set *set) |
812 | { | 852 | { |
853 | struct device_node *np = info->device->of_node; | ||
813 | struct nand_chip *chip = &nmtd->chip; | 854 | struct nand_chip *chip = &nmtd->chip; |
814 | void __iomem *regs = info->regs; | 855 | void __iomem *regs = info->regs; |
815 | 856 | ||
857 | nand_set_flash_node(chip, set->of_node); | ||
858 | |||
816 | chip->write_buf = s3c2410_nand_write_buf; | 859 | chip->write_buf = s3c2410_nand_write_buf; |
817 | chip->read_buf = s3c2410_nand_read_buf; | 860 | chip->read_buf = s3c2410_nand_read_buf; |
818 | chip->select_chip = s3c2410_nand_select_chip; | 861 | chip->select_chip = s3c2410_nand_select_chip; |
@@ -821,6 +864,13 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, | |||
821 | chip->options = set->options; | 864 | chip->options = set->options; |
822 | chip->controller = &info->controller; | 865 | chip->controller = &info->controller; |
823 | 866 | ||
867 | /* | ||
868 | * let's keep behavior unchanged for legacy boards booting via pdata and | ||
869 | * auto-detect timings only when booting with a device tree. | ||
870 | */ | ||
871 | if (np) | ||
872 | chip->setup_data_interface = s3c2410_nand_setup_data_interface; | ||
873 | |||
824 | switch (info->cpu_type) { | 874 | switch (info->cpu_type) { |
825 | case TYPE_S3C2410: | 875 | case TYPE_S3C2410: |
826 | chip->IO_ADDR_W = regs + S3C2410_NFDATA; | 876 | chip->IO_ADDR_W = regs + S3C2410_NFDATA; |
@@ -858,58 +908,14 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, | |||
858 | nmtd->info = info; | 908 | nmtd->info = info; |
859 | nmtd->set = set; | 909 | nmtd->set = set; |
860 | 910 | ||
861 | #ifdef CONFIG_MTD_NAND_S3C2410_HWECC | 911 | chip->ecc.mode = info->platform->ecc_mode; |
862 | chip->ecc.calculate = s3c2410_nand_calculate_ecc; | ||
863 | chip->ecc.correct = s3c2410_nand_correct_data; | ||
864 | chip->ecc.mode = NAND_ECC_HW; | ||
865 | chip->ecc.strength = 1; | ||
866 | 912 | ||
867 | switch (info->cpu_type) { | 913 | /* |
868 | case TYPE_S3C2410: | 914 | * If you use u-boot BBT creation code, specifying this flag will |
869 | chip->ecc.hwctl = s3c2410_nand_enable_hwecc; | 915 | * let the kernel fish out the BBT from the NAND. |
870 | chip->ecc.calculate = s3c2410_nand_calculate_ecc; | 916 | */ |
871 | break; | 917 | if (set->flash_bbt) |
872 | |||
873 | case TYPE_S3C2412: | ||
874 | chip->ecc.hwctl = s3c2412_nand_enable_hwecc; | ||
875 | chip->ecc.calculate = s3c2412_nand_calculate_ecc; | ||
876 | break; | ||
877 | |||
878 | case TYPE_S3C2440: | ||
879 | chip->ecc.hwctl = s3c2440_nand_enable_hwecc; | ||
880 | chip->ecc.calculate = s3c2440_nand_calculate_ecc; | ||
881 | break; | ||
882 | } | ||
883 | #else | ||
884 | chip->ecc.mode = NAND_ECC_SOFT; | ||
885 | chip->ecc.algo = NAND_ECC_HAMMING; | ||
886 | #endif | ||
887 | |||
888 | if (set->disable_ecc) | ||
889 | chip->ecc.mode = NAND_ECC_NONE; | ||
890 | |||
891 | switch (chip->ecc.mode) { | ||
892 | case NAND_ECC_NONE: | ||
893 | dev_info(info->device, "NAND ECC disabled\n"); | ||
894 | break; | ||
895 | case NAND_ECC_SOFT: | ||
896 | dev_info(info->device, "NAND soft ECC\n"); | ||
897 | break; | ||
898 | case NAND_ECC_HW: | ||
899 | dev_info(info->device, "NAND hardware ECC\n"); | ||
900 | break; | ||
901 | default: | ||
902 | dev_info(info->device, "NAND ECC UNKNOWN\n"); | ||
903 | break; | ||
904 | } | ||
905 | |||
906 | /* If you use u-boot BBT creation code, specifying this flag will | ||
907 | * let the kernel fish out the BBT from the NAND, and also skip the | ||
908 | * full NAND scan that can take 1/2s or so. Little things... */ | ||
909 | if (set->flash_bbt) { | ||
910 | chip->bbt_options |= NAND_BBT_USE_FLASH; | 918 | chip->bbt_options |= NAND_BBT_USE_FLASH; |
911 | chip->options |= NAND_SKIP_BBTSCAN; | ||
912 | } | ||
913 | } | 919 | } |
914 | 920 | ||
915 | /** | 921 | /** |
@@ -923,28 +929,146 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, | |||
923 | * | 929 | * |
924 | * The internal state is currently limited to the ECC state information. | 930 | * The internal state is currently limited to the ECC state information. |
925 | */ | 931 | */ |
926 | static void s3c2410_nand_update_chip(struct s3c2410_nand_info *info, | 932 | static int s3c2410_nand_update_chip(struct s3c2410_nand_info *info, |
927 | struct s3c2410_nand_mtd *nmtd) | 933 | struct s3c2410_nand_mtd *nmtd) |
928 | { | 934 | { |
929 | struct nand_chip *chip = &nmtd->chip; | 935 | struct nand_chip *chip = &nmtd->chip; |
930 | 936 | ||
931 | dev_dbg(info->device, "chip %p => page shift %d\n", | 937 | switch (chip->ecc.mode) { |
932 | chip, chip->page_shift); | ||
933 | 938 | ||
934 | if (chip->ecc.mode != NAND_ECC_HW) | 939 | case NAND_ECC_NONE: |
935 | return; | 940 | dev_info(info->device, "ECC disabled\n"); |
941 | break; | ||
942 | |||
943 | case NAND_ECC_SOFT: | ||
944 | /* | ||
945 | * This driver expects Hamming based ECC when ecc_mode is set | ||
946 | * to NAND_ECC_SOFT. Force ecc.algo to NAND_ECC_HAMMING to | ||
947 | * avoid adding an extra ecc_algo field to | ||
948 | * s3c2410_platform_nand. | ||
949 | */ | ||
950 | chip->ecc.algo = NAND_ECC_HAMMING; | ||
951 | dev_info(info->device, "soft ECC\n"); | ||
952 | break; | ||
953 | |||
954 | case NAND_ECC_HW: | ||
955 | chip->ecc.calculate = s3c2410_nand_calculate_ecc; | ||
956 | chip->ecc.correct = s3c2410_nand_correct_data; | ||
957 | chip->ecc.strength = 1; | ||
958 | |||
959 | switch (info->cpu_type) { | ||
960 | case TYPE_S3C2410: | ||
961 | chip->ecc.hwctl = s3c2410_nand_enable_hwecc; | ||
962 | chip->ecc.calculate = s3c2410_nand_calculate_ecc; | ||
963 | break; | ||
964 | |||
965 | case TYPE_S3C2412: | ||
966 | chip->ecc.hwctl = s3c2412_nand_enable_hwecc; | ||
967 | chip->ecc.calculate = s3c2412_nand_calculate_ecc; | ||
968 | break; | ||
969 | |||
970 | case TYPE_S3C2440: | ||
971 | chip->ecc.hwctl = s3c2440_nand_enable_hwecc; | ||
972 | chip->ecc.calculate = s3c2440_nand_calculate_ecc; | ||
973 | break; | ||
974 | } | ||
975 | |||
976 | dev_dbg(info->device, "chip %p => page shift %d\n", | ||
977 | chip, chip->page_shift); | ||
936 | 978 | ||
937 | /* change the behaviour depending on whether we are using | 979 | /* change the behaviour depending on whether we are using |
938 | * the large or small page nand device */ | 980 | * the large or small page nand device */ |
981 | if (chip->page_shift > 10) { | ||
982 | chip->ecc.size = 256; | ||
983 | chip->ecc.bytes = 3; | ||
984 | } else { | ||
985 | chip->ecc.size = 512; | ||
986 | chip->ecc.bytes = 3; | ||
987 | mtd_set_ooblayout(nand_to_mtd(chip), | ||
988 | &s3c2410_ooblayout_ops); | ||
989 | } | ||
939 | 990 | ||
940 | if (chip->page_shift > 10) { | 991 | dev_info(info->device, "hardware ECC\n"); |
941 | chip->ecc.size = 256; | 992 | break; |
942 | chip->ecc.bytes = 3; | 993 | |
943 | } else { | 994 | default: |
944 | chip->ecc.size = 512; | 995 | dev_err(info->device, "invalid ECC mode!\n"); |
945 | chip->ecc.bytes = 3; | 996 | return -EINVAL; |
946 | mtd_set_ooblayout(nand_to_mtd(chip), &s3c2410_ooblayout_ops); | ||
947 | } | 997 | } |
998 | |||
999 | if (chip->bbt_options & NAND_BBT_USE_FLASH) | ||
1000 | chip->options |= NAND_SKIP_BBTSCAN; | ||
1001 | |||
1002 | return 0; | ||
1003 | } | ||
1004 | |||
1005 | static const struct of_device_id s3c24xx_nand_dt_ids[] = { | ||
1006 | { | ||
1007 | .compatible = "samsung,s3c2410-nand", | ||
1008 | .data = &s3c2410_nand_devtype_data, | ||
1009 | }, { | ||
1010 | /* also compatible with s3c6400 */ | ||
1011 | .compatible = "samsung,s3c2412-nand", | ||
1012 | .data = &s3c2412_nand_devtype_data, | ||
1013 | }, { | ||
1014 | .compatible = "samsung,s3c2440-nand", | ||
1015 | .data = &s3c2440_nand_devtype_data, | ||
1016 | }, | ||
1017 | { /* sentinel */ } | ||
1018 | }; | ||
1019 | MODULE_DEVICE_TABLE(of, s3c24xx_nand_dt_ids); | ||
1020 | |||
1021 | static int s3c24xx_nand_probe_dt(struct platform_device *pdev) | ||
1022 | { | ||
1023 | const struct s3c24XX_nand_devtype_data *devtype_data; | ||
1024 | struct s3c2410_platform_nand *pdata; | ||
1025 | struct s3c2410_nand_info *info = platform_get_drvdata(pdev); | ||
1026 | struct device_node *np = pdev->dev.of_node, *child; | ||
1027 | struct s3c2410_nand_set *sets; | ||
1028 | |||
1029 | devtype_data = of_device_get_match_data(&pdev->dev); | ||
1030 | if (!devtype_data) | ||
1031 | return -ENODEV; | ||
1032 | |||
1033 | info->cpu_type = devtype_data->type; | ||
1034 | |||
1035 | pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); | ||
1036 | if (!pdata) | ||
1037 | return -ENOMEM; | ||
1038 | |||
1039 | pdev->dev.platform_data = pdata; | ||
1040 | |||
1041 | pdata->nr_sets = of_get_child_count(np); | ||
1042 | if (!pdata->nr_sets) | ||
1043 | return 0; | ||
1044 | |||
1045 | sets = devm_kzalloc(&pdev->dev, sizeof(*sets) * pdata->nr_sets, | ||
1046 | GFP_KERNEL); | ||
1047 | if (!sets) | ||
1048 | return -ENOMEM; | ||
1049 | |||
1050 | pdata->sets = sets; | ||
1051 | |||
1052 | for_each_available_child_of_node(np, child) { | ||
1053 | sets->name = (char *)child->name; | ||
1054 | sets->of_node = child; | ||
1055 | sets->nr_chips = 1; | ||
1056 | |||
1057 | of_node_get(child); | ||
1058 | |||
1059 | sets++; | ||
1060 | } | ||
1061 | |||
1062 | return 0; | ||
1063 | } | ||
1064 | |||
1065 | static int s3c24xx_nand_probe_pdata(struct platform_device *pdev) | ||
1066 | { | ||
1067 | struct s3c2410_nand_info *info = platform_get_drvdata(pdev); | ||
1068 | |||
1069 | info->cpu_type = platform_get_device_id(pdev)->driver_data; | ||
1070 | |||
1071 | return 0; | ||
948 | } | 1072 | } |
949 | 1073 | ||
950 | /* s3c24xx_nand_probe | 1074 | /* s3c24xx_nand_probe |
@@ -956,8 +1080,7 @@ static void s3c2410_nand_update_chip(struct s3c2410_nand_info *info, | |||
956 | */ | 1080 | */ |
957 | static int s3c24xx_nand_probe(struct platform_device *pdev) | 1081 | static int s3c24xx_nand_probe(struct platform_device *pdev) |
958 | { | 1082 | { |
959 | struct s3c2410_platform_nand *plat = to_nand_plat(pdev); | 1083 | struct s3c2410_platform_nand *plat; |
960 | enum s3c_cpu_type cpu_type; | ||
961 | struct s3c2410_nand_info *info; | 1084 | struct s3c2410_nand_info *info; |
962 | struct s3c2410_nand_mtd *nmtd; | 1085 | struct s3c2410_nand_mtd *nmtd; |
963 | struct s3c2410_nand_set *sets; | 1086 | struct s3c2410_nand_set *sets; |
@@ -967,8 +1090,6 @@ static int s3c24xx_nand_probe(struct platform_device *pdev) | |||
967 | int nr_sets; | 1090 | int nr_sets; |
968 | int setno; | 1091 | int setno; |
969 | 1092 | ||
970 | cpu_type = platform_get_device_id(pdev)->driver_data; | ||
971 | |||
972 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); | 1093 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); |
973 | if (info == NULL) { | 1094 | if (info == NULL) { |
974 | err = -ENOMEM; | 1095 | err = -ENOMEM; |
@@ -990,6 +1111,16 @@ static int s3c24xx_nand_probe(struct platform_device *pdev) | |||
990 | 1111 | ||
991 | s3c2410_nand_clk_set_state(info, CLOCK_ENABLE); | 1112 | s3c2410_nand_clk_set_state(info, CLOCK_ENABLE); |
992 | 1113 | ||
1114 | if (pdev->dev.of_node) | ||
1115 | err = s3c24xx_nand_probe_dt(pdev); | ||
1116 | else | ||
1117 | err = s3c24xx_nand_probe_pdata(pdev); | ||
1118 | |||
1119 | if (err) | ||
1120 | goto exit_error; | ||
1121 | |||
1122 | plat = to_nand_plat(pdev); | ||
1123 | |||
993 | /* allocate and map the resource */ | 1124 | /* allocate and map the resource */ |
994 | 1125 | ||
995 | /* currently we assume we have the one resource */ | 1126 | /* currently we assume we have the one resource */ |
@@ -998,7 +1129,6 @@ static int s3c24xx_nand_probe(struct platform_device *pdev) | |||
998 | 1129 | ||
999 | info->device = &pdev->dev; | 1130 | info->device = &pdev->dev; |
1000 | info->platform = plat; | 1131 | info->platform = plat; |
1001 | info->cpu_type = cpu_type; | ||
1002 | 1132 | ||
1003 | info->regs = devm_ioremap_resource(&pdev->dev, res); | 1133 | info->regs = devm_ioremap_resource(&pdev->dev, res); |
1004 | if (IS_ERR(info->regs)) { | 1134 | if (IS_ERR(info->regs)) { |
@@ -1008,12 +1138,6 @@ static int s3c24xx_nand_probe(struct platform_device *pdev) | |||
1008 | 1138 | ||
1009 | dev_dbg(&pdev->dev, "mapped registers at %p\n", info->regs); | 1139 | dev_dbg(&pdev->dev, "mapped registers at %p\n", info->regs); |
1010 | 1140 | ||
1011 | /* initialise the hardware */ | ||
1012 | |||
1013 | err = s3c2410_nand_inithw(info); | ||
1014 | if (err != 0) | ||
1015 | goto exit_error; | ||
1016 | |||
1017 | sets = (plat != NULL) ? plat->sets : NULL; | 1141 | sets = (plat != NULL) ? plat->sets : NULL; |
1018 | nr_sets = (plat != NULL) ? plat->nr_sets : 1; | 1142 | nr_sets = (plat != NULL) ? plat->nr_sets : 1; |
1019 | 1143 | ||
@@ -1046,7 +1170,9 @@ static int s3c24xx_nand_probe(struct platform_device *pdev) | |||
1046 | NULL); | 1170 | NULL); |
1047 | 1171 | ||
1048 | if (nmtd->scan_res == 0) { | 1172 | if (nmtd->scan_res == 0) { |
1049 | s3c2410_nand_update_chip(info, nmtd); | 1173 | err = s3c2410_nand_update_chip(info, nmtd); |
1174 | if (err < 0) | ||
1175 | goto exit_error; | ||
1050 | nand_scan_tail(mtd); | 1176 | nand_scan_tail(mtd); |
1051 | s3c2410_nand_add_partition(info, nmtd, sets); | 1177 | s3c2410_nand_add_partition(info, nmtd, sets); |
1052 | } | 1178 | } |
@@ -1055,6 +1181,11 @@ static int s3c24xx_nand_probe(struct platform_device *pdev) | |||
1055 | sets++; | 1181 | sets++; |
1056 | } | 1182 | } |
1057 | 1183 | ||
1184 | /* initialise the hardware */ | ||
1185 | err = s3c2410_nand_inithw(info); | ||
1186 | if (err != 0) | ||
1187 | goto exit_error; | ||
1188 | |||
1058 | err = s3c2410_nand_cpufreq_register(info); | 1189 | err = s3c2410_nand_cpufreq_register(info); |
1059 | if (err < 0) { | 1190 | if (err < 0) { |
1060 | dev_err(&pdev->dev, "failed to init cpufreq support\n"); | 1191 | dev_err(&pdev->dev, "failed to init cpufreq support\n"); |
@@ -1155,6 +1286,7 @@ static struct platform_driver s3c24xx_nand_driver = { | |||
1155 | .id_table = s3c24xx_driver_ids, | 1286 | .id_table = s3c24xx_driver_ids, |
1156 | .driver = { | 1287 | .driver = { |
1157 | .name = "s3c24xx-nand", | 1288 | .name = "s3c24xx-nand", |
1289 | .of_match_table = s3c24xx_nand_dt_ids, | ||
1158 | }, | 1290 | }, |
1159 | }; | 1291 | }; |
1160 | 1292 | ||
diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c index 888fd314c62a..72369bd079af 100644 --- a/drivers/mtd/nand/socrates_nand.c +++ b/drivers/mtd/nand/socrates_nand.c | |||
@@ -187,17 +187,9 @@ static int socrates_nand_probe(struct platform_device *ofdev) | |||
187 | 187 | ||
188 | dev_set_drvdata(&ofdev->dev, host); | 188 | dev_set_drvdata(&ofdev->dev, host); |
189 | 189 | ||
190 | /* first scan to find the device and get the page size */ | 190 | res = nand_scan(mtd, 1); |
191 | if (nand_scan_ident(mtd, 1, NULL)) { | 191 | if (res) |
192 | res = -ENXIO; | ||
193 | goto out; | 192 | goto out; |
194 | } | ||
195 | |||
196 | /* second phase scan */ | ||
197 | if (nand_scan_tail(mtd)) { | ||
198 | res = -ENXIO; | ||
199 | goto out; | ||
200 | } | ||
201 | 193 | ||
202 | res = mtd_device_register(mtd, NULL, 0); | 194 | res = mtd_device_register(mtd, NULL, 0); |
203 | if (!res) | 195 | if (!res) |
diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c index 8b8470c4e6d0..e40482a65de6 100644 --- a/drivers/mtd/nand/sunxi_nand.c +++ b/drivers/mtd/nand/sunxi_nand.c | |||
@@ -145,6 +145,7 @@ | |||
145 | #define NFC_ECC_PIPELINE BIT(3) | 145 | #define NFC_ECC_PIPELINE BIT(3) |
146 | #define NFC_ECC_EXCEPTION BIT(4) | 146 | #define NFC_ECC_EXCEPTION BIT(4) |
147 | #define NFC_ECC_BLOCK_SIZE_MSK BIT(5) | 147 | #define NFC_ECC_BLOCK_SIZE_MSK BIT(5) |
148 | #define NFC_ECC_BLOCK_512 BIT(5) | ||
148 | #define NFC_RANDOM_EN BIT(9) | 149 | #define NFC_RANDOM_EN BIT(9) |
149 | #define NFC_RANDOM_DIRECTION BIT(10) | 150 | #define NFC_RANDOM_DIRECTION BIT(10) |
150 | #define NFC_ECC_MODE_MSK GENMASK(15, 12) | 151 | #define NFC_ECC_MODE_MSK GENMASK(15, 12) |
@@ -817,6 +818,9 @@ static void sunxi_nfc_hw_ecc_enable(struct mtd_info *mtd) | |||
817 | ecc_ctl |= NFC_ECC_EN | NFC_ECC_MODE(data->mode) | NFC_ECC_EXCEPTION | | 818 | ecc_ctl |= NFC_ECC_EN | NFC_ECC_MODE(data->mode) | NFC_ECC_EXCEPTION | |
818 | NFC_ECC_PIPELINE; | 819 | NFC_ECC_PIPELINE; |
819 | 820 | ||
821 | if (nand->ecc.size == 512) | ||
822 | ecc_ctl |= NFC_ECC_BLOCK_512; | ||
823 | |||
820 | writel(ecc_ctl, nfc->regs + NFC_REG_ECC_CTL); | 824 | writel(ecc_ctl, nfc->regs + NFC_REG_ECC_CTL); |
821 | } | 825 | } |
822 | 826 | ||
diff --git a/drivers/mtd/nand/tango_nand.c b/drivers/mtd/nand/tango_nand.c new file mode 100644 index 000000000000..ec87516b87f5 --- /dev/null +++ b/drivers/mtd/nand/tango_nand.c | |||
@@ -0,0 +1,668 @@ | |||
1 | #include <linux/io.h> | ||
2 | #include <linux/of.h> | ||
3 | #include <linux/clk.h> | ||
4 | #include <linux/iopoll.h> | ||
5 | #include <linux/module.h> | ||
6 | #include <linux/mtd/nand.h> | ||
7 | #include <linux/dmaengine.h> | ||
8 | #include <linux/dma-mapping.h> | ||
9 | #include <linux/platform_device.h> | ||
10 | |||
11 | /* Offsets relative to chip->base */ | ||
12 | #define PBUS_CMD 0 | ||
13 | #define PBUS_ADDR 4 | ||
14 | #define PBUS_DATA 8 | ||
15 | |||
16 | /* Offsets relative to reg_base */ | ||
17 | #define NFC_STATUS 0x00 | ||
18 | #define NFC_FLASH_CMD 0x04 | ||
19 | #define NFC_DEVICE_CFG 0x08 | ||
20 | #define NFC_TIMING1 0x0c | ||
21 | #define NFC_TIMING2 0x10 | ||
22 | #define NFC_XFER_CFG 0x14 | ||
23 | #define NFC_PKT_0_CFG 0x18 | ||
24 | #define NFC_PKT_N_CFG 0x1c | ||
25 | #define NFC_BB_CFG 0x20 | ||
26 | #define NFC_ADDR_PAGE 0x24 | ||
27 | #define NFC_ADDR_OFFSET 0x28 | ||
28 | #define NFC_XFER_STATUS 0x2c | ||
29 | |||
30 | /* NFC_STATUS values */ | ||
31 | #define CMD_READY BIT(31) | ||
32 | |||
33 | /* NFC_FLASH_CMD values */ | ||
34 | #define NFC_READ 1 | ||
35 | #define NFC_WRITE 2 | ||
36 | |||
37 | /* NFC_XFER_STATUS values */ | ||
38 | #define PAGE_IS_EMPTY BIT(16) | ||
39 | |||
40 | /* Offsets relative to mem_base */ | ||
41 | #define METADATA 0x000 | ||
42 | #define ERROR_REPORT 0x1c0 | ||
43 | |||
44 | /* | ||
45 | * Error reports are split in two bytes: | ||
46 | * byte 0 for the first packet in the page (PKT_0) | ||
47 | * byte 1 for other packets in the page (PKT_N, for N > 0) | ||
48 | * ERR_COUNT_PKT_N is the max error count over all but the first packet. | ||
49 | */ | ||
50 | #define DECODE_OK_PKT_0(v) ((v) & BIT(7)) | ||
51 | #define DECODE_OK_PKT_N(v) ((v) & BIT(15)) | ||
52 | #define ERR_COUNT_PKT_0(v) (((v) >> 0) & 0x3f) | ||
53 | #define ERR_COUNT_PKT_N(v) (((v) >> 8) & 0x3f) | ||
54 | |||
55 | /* Offsets relative to pbus_base */ | ||
56 | #define PBUS_CS_CTRL 0x83c | ||
57 | #define PBUS_PAD_MODE 0x8f0 | ||
58 | |||
59 | /* PBUS_CS_CTRL values */ | ||
60 | #define PBUS_IORDY BIT(31) | ||
61 | |||
62 | /* | ||
63 | * PBUS_PAD_MODE values | ||
64 | * In raw mode, the driver communicates directly with the NAND chips. | ||
65 | * In NFC mode, the NAND Flash controller manages the communication. | ||
66 | * We use NFC mode for read and write; raw mode for everything else. | ||
67 | */ | ||
68 | #define MODE_RAW 0 | ||
69 | #define MODE_NFC BIT(31) | ||
70 | |||
71 | #define METADATA_SIZE 4 | ||
72 | #define BBM_SIZE 6 | ||
73 | #define FIELD_ORDER 15 | ||
74 | |||
75 | #define MAX_CS 4 | ||
76 | |||
77 | struct tango_nfc { | ||
78 | struct nand_hw_control hw; | ||
79 | void __iomem *reg_base; | ||
80 | void __iomem *mem_base; | ||
81 | void __iomem *pbus_base; | ||
82 | struct tango_chip *chips[MAX_CS]; | ||
83 | struct dma_chan *chan; | ||
84 | int freq_kHz; | ||
85 | }; | ||
86 | |||
87 | #define to_tango_nfc(ptr) container_of(ptr, struct tango_nfc, hw) | ||
88 | |||
89 | struct tango_chip { | ||
90 | struct nand_chip nand_chip; | ||
91 | void __iomem *base; | ||
92 | u32 timing1; | ||
93 | u32 timing2; | ||
94 | u32 xfer_cfg; | ||
95 | u32 pkt_0_cfg; | ||
96 | u32 pkt_n_cfg; | ||
97 | u32 bb_cfg; | ||
98 | }; | ||
99 | |||
100 | #define to_tango_chip(ptr) container_of(ptr, struct tango_chip, nand_chip) | ||
101 | |||
102 | #define XFER_CFG(cs, page_count, steps, metadata_size) \ | ||
103 | ((cs) << 24 | (page_count) << 16 | (steps) << 8 | (metadata_size)) | ||
104 | |||
105 | #define PKT_CFG(size, strength) ((size) << 16 | (strength)) | ||
106 | |||
107 | #define BB_CFG(bb_offset, bb_size) ((bb_offset) << 16 | (bb_size)) | ||
108 | |||
109 | #define TIMING(t0, t1, t2, t3) ((t0) << 24 | (t1) << 16 | (t2) << 8 | (t3)) | ||
110 | |||
111 | static void tango_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl) | ||
112 | { | ||
113 | struct tango_chip *tchip = to_tango_chip(mtd_to_nand(mtd)); | ||
114 | |||
115 | if (ctrl & NAND_CLE) | ||
116 | writeb_relaxed(dat, tchip->base + PBUS_CMD); | ||
117 | |||
118 | if (ctrl & NAND_ALE) | ||
119 | writeb_relaxed(dat, tchip->base + PBUS_ADDR); | ||
120 | } | ||
121 | |||
122 | static int tango_dev_ready(struct mtd_info *mtd) | ||
123 | { | ||
124 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
125 | struct tango_nfc *nfc = to_tango_nfc(chip->controller); | ||
126 | |||
127 | return readl_relaxed(nfc->pbus_base + PBUS_CS_CTRL) & PBUS_IORDY; | ||
128 | } | ||
129 | |||
130 | static u8 tango_read_byte(struct mtd_info *mtd) | ||
131 | { | ||
132 | struct tango_chip *tchip = to_tango_chip(mtd_to_nand(mtd)); | ||
133 | |||
134 | return readb_relaxed(tchip->base + PBUS_DATA); | ||
135 | } | ||
136 | |||
137 | static void tango_read_buf(struct mtd_info *mtd, u8 *buf, int len) | ||
138 | { | ||
139 | struct tango_chip *tchip = to_tango_chip(mtd_to_nand(mtd)); | ||
140 | |||
141 | ioread8_rep(tchip->base + PBUS_DATA, buf, len); | ||
142 | } | ||
143 | |||
144 | static void tango_write_buf(struct mtd_info *mtd, const u8 *buf, int len) | ||
145 | { | ||
146 | struct tango_chip *tchip = to_tango_chip(mtd_to_nand(mtd)); | ||
147 | |||
148 | iowrite8_rep(tchip->base + PBUS_DATA, buf, len); | ||
149 | } | ||
150 | |||
151 | static void tango_select_chip(struct mtd_info *mtd, int idx) | ||
152 | { | ||
153 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
154 | struct tango_nfc *nfc = to_tango_nfc(chip->controller); | ||
155 | struct tango_chip *tchip = to_tango_chip(chip); | ||
156 | |||
157 | if (idx < 0) | ||
158 | return; /* No "chip unselect" function */ | ||
159 | |||
160 | writel_relaxed(tchip->timing1, nfc->reg_base + NFC_TIMING1); | ||
161 | writel_relaxed(tchip->timing2, nfc->reg_base + NFC_TIMING2); | ||
162 | writel_relaxed(tchip->xfer_cfg, nfc->reg_base + NFC_XFER_CFG); | ||
163 | writel_relaxed(tchip->pkt_0_cfg, nfc->reg_base + NFC_PKT_0_CFG); | ||
164 | writel_relaxed(tchip->pkt_n_cfg, nfc->reg_base + NFC_PKT_N_CFG); | ||
165 | writel_relaxed(tchip->bb_cfg, nfc->reg_base + NFC_BB_CFG); | ||
166 | } | ||
167 | |||
168 | /* | ||
169 | * The controller does not check for bitflips in erased pages, | ||
170 | * therefore software must check instead. | ||
171 | */ | ||
172 | static int check_erased_page(struct nand_chip *chip, u8 *buf) | ||
173 | { | ||
174 | struct mtd_info *mtd = nand_to_mtd(chip); | ||
175 | u8 *meta = chip->oob_poi + BBM_SIZE; | ||
176 | u8 *ecc = chip->oob_poi + BBM_SIZE + METADATA_SIZE; | ||
177 | const int ecc_size = chip->ecc.bytes; | ||
178 | const int pkt_size = chip->ecc.size; | ||
179 | int i, res, meta_len, bitflips = 0; | ||
180 | |||
181 | for (i = 0; i < chip->ecc.steps; ++i) { | ||
182 | meta_len = i ? 0 : METADATA_SIZE; | ||
183 | res = nand_check_erased_ecc_chunk(buf, pkt_size, ecc, ecc_size, | ||
184 | meta, meta_len, | ||
185 | chip->ecc.strength); | ||
186 | if (res < 0) | ||
187 | mtd->ecc_stats.failed++; | ||
188 | |||
189 | bitflips = max(res, bitflips); | ||
190 | buf += pkt_size; | ||
191 | ecc += ecc_size; | ||
192 | } | ||
193 | |||
194 | return bitflips; | ||
195 | } | ||
196 | |||
197 | static int decode_error_report(struct tango_nfc *nfc) | ||
198 | { | ||
199 | u32 status, res; | ||
200 | |||
201 | status = readl_relaxed(nfc->reg_base + NFC_XFER_STATUS); | ||
202 | if (status & PAGE_IS_EMPTY) | ||
203 | return 0; | ||
204 | |||
205 | res = readl_relaxed(nfc->mem_base + ERROR_REPORT); | ||
206 | |||
207 | if (DECODE_OK_PKT_0(res) && DECODE_OK_PKT_N(res)) | ||
208 | return max(ERR_COUNT_PKT_0(res), ERR_COUNT_PKT_N(res)); | ||
209 | |||
210 | return -EBADMSG; | ||
211 | } | ||
212 | |||
213 | static void tango_dma_callback(void *arg) | ||
214 | { | ||
215 | complete(arg); | ||
216 | } | ||
217 | |||
218 | static int do_dma(struct tango_nfc *nfc, int dir, int cmd, const void *buf, | ||
219 | int len, int page) | ||
220 | { | ||
221 | void __iomem *addr = nfc->reg_base + NFC_STATUS; | ||
222 | struct dma_chan *chan = nfc->chan; | ||
223 | struct dma_async_tx_descriptor *desc; | ||
224 | struct scatterlist sg; | ||
225 | struct completion tx_done; | ||
226 | int err = -EIO; | ||
227 | u32 res, val; | ||
228 | |||
229 | sg_init_one(&sg, buf, len); | ||
230 | if (dma_map_sg(chan->device->dev, &sg, 1, dir) != 1) | ||
231 | return -EIO; | ||
232 | |||
233 | desc = dmaengine_prep_slave_sg(chan, &sg, 1, dir, DMA_PREP_INTERRUPT); | ||
234 | if (!desc) | ||
235 | goto dma_unmap; | ||
236 | |||
237 | desc->callback = tango_dma_callback; | ||
238 | desc->callback_param = &tx_done; | ||
239 | init_completion(&tx_done); | ||
240 | |||
241 | writel_relaxed(MODE_NFC, nfc->pbus_base + PBUS_PAD_MODE); | ||
242 | |||
243 | writel_relaxed(page, nfc->reg_base + NFC_ADDR_PAGE); | ||
244 | writel_relaxed(0, nfc->reg_base + NFC_ADDR_OFFSET); | ||
245 | writel_relaxed(cmd, nfc->reg_base + NFC_FLASH_CMD); | ||
246 | |||
247 | dmaengine_submit(desc); | ||
248 | dma_async_issue_pending(chan); | ||
249 | |||
250 | res = wait_for_completion_timeout(&tx_done, HZ); | ||
251 | if (res > 0) | ||
252 | err = readl_poll_timeout(addr, val, val & CMD_READY, 0, 1000); | ||
253 | |||
254 | writel_relaxed(MODE_RAW, nfc->pbus_base + PBUS_PAD_MODE); | ||
255 | |||
256 | dma_unmap: | ||
257 | dma_unmap_sg(chan->device->dev, &sg, 1, dir); | ||
258 | |||
259 | return err; | ||
260 | } | ||
261 | |||
262 | static int tango_read_page(struct mtd_info *mtd, struct nand_chip *chip, | ||
263 | u8 *buf, int oob_required, int page) | ||
264 | { | ||
265 | struct tango_nfc *nfc = to_tango_nfc(chip->controller); | ||
266 | int err, res, len = mtd->writesize; | ||
267 | |||
268 | if (oob_required) | ||
269 | chip->ecc.read_oob(mtd, chip, page); | ||
270 | |||
271 | err = do_dma(nfc, DMA_FROM_DEVICE, NFC_READ, buf, len, page); | ||
272 | if (err) | ||
273 | return err; | ||
274 | |||
275 | res = decode_error_report(nfc); | ||
276 | if (res < 0) { | ||
277 | chip->ecc.read_oob_raw(mtd, chip, page); | ||
278 | res = check_erased_page(chip, buf); | ||
279 | } | ||
280 | |||
281 | return res; | ||
282 | } | ||
283 | |||
284 | static int tango_write_page(struct mtd_info *mtd, struct nand_chip *chip, | ||
285 | const u8 *buf, int oob_required, int page) | ||
286 | { | ||
287 | struct tango_nfc *nfc = to_tango_nfc(chip->controller); | ||
288 | int err, len = mtd->writesize; | ||
289 | |||
290 | /* Calling tango_write_oob() would send PAGEPROG twice */ | ||
291 | if (oob_required) | ||
292 | return -ENOTSUPP; | ||
293 | |||
294 | writel_relaxed(0xffffffff, nfc->mem_base + METADATA); | ||
295 | err = do_dma(nfc, DMA_TO_DEVICE, NFC_WRITE, buf, len, page); | ||
296 | if (err) | ||
297 | return err; | ||
298 | |||
299 | return 0; | ||
300 | } | ||
301 | |||
302 | static void aux_read(struct nand_chip *chip, u8 **buf, int len, int *pos) | ||
303 | { | ||
304 | struct mtd_info *mtd = nand_to_mtd(chip); | ||
305 | |||
306 | *pos += len; | ||
307 | |||
308 | if (!*buf) { | ||
309 | /* skip over "len" bytes */ | ||
310 | chip->cmdfunc(mtd, NAND_CMD_RNDOUT, *pos, -1); | ||
311 | } else { | ||
312 | tango_read_buf(mtd, *buf, len); | ||
313 | *buf += len; | ||
314 | } | ||
315 | } | ||
316 | |||
317 | static void aux_write(struct nand_chip *chip, const u8 **buf, int len, int *pos) | ||
318 | { | ||
319 | struct mtd_info *mtd = nand_to_mtd(chip); | ||
320 | |||
321 | *pos += len; | ||
322 | |||
323 | if (!*buf) { | ||
324 | /* skip over "len" bytes */ | ||
325 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, *pos, -1); | ||
326 | } else { | ||
327 | tango_write_buf(mtd, *buf, len); | ||
328 | *buf += len; | ||
329 | } | ||
330 | } | ||
331 | |||
332 | /* | ||
333 | * Physical page layout (not drawn to scale) | ||
334 | * | ||
335 | * NB: Bad Block Marker area splits PKT_N in two (N1, N2). | ||
336 | * | ||
337 | * +---+-----------------+-------+-----+-----------+-----+----+-------+ | ||
338 | * | M | PKT_0 | ECC_0 | ... | N1 | BBM | N2 | ECC_N | | ||
339 | * +---+-----------------+-------+-----+-----------+-----+----+-------+ | ||
340 | * | ||
341 | * Logical page layout: | ||
342 | * | ||
343 | * +-----+---+-------+-----+-------+ | ||
344 | * oob = | BBM | M | ECC_0 | ... | ECC_N | | ||
345 | * +-----+---+-------+-----+-------+ | ||
346 | * | ||
347 | * +-----------------+-----+-----------------+ | ||
348 | * buf = | PKT_0 | ... | PKT_N | | ||
349 | * +-----------------+-----+-----------------+ | ||
350 | */ | ||
351 | static void raw_read(struct nand_chip *chip, u8 *buf, u8 *oob) | ||
352 | { | ||
353 | struct mtd_info *mtd = nand_to_mtd(chip); | ||
354 | u8 *oob_orig = oob; | ||
355 | const int page_size = mtd->writesize; | ||
356 | const int ecc_size = chip->ecc.bytes; | ||
357 | const int pkt_size = chip->ecc.size; | ||
358 | int pos = 0; /* position within physical page */ | ||
359 | int rem = page_size; /* bytes remaining until BBM area */ | ||
360 | |||
361 | if (oob) | ||
362 | oob += BBM_SIZE; | ||
363 | |||
364 | aux_read(chip, &oob, METADATA_SIZE, &pos); | ||
365 | |||
366 | while (rem > pkt_size) { | ||
367 | aux_read(chip, &buf, pkt_size, &pos); | ||
368 | aux_read(chip, &oob, ecc_size, &pos); | ||
369 | rem = page_size - pos; | ||
370 | } | ||
371 | |||
372 | aux_read(chip, &buf, rem, &pos); | ||
373 | aux_read(chip, &oob_orig, BBM_SIZE, &pos); | ||
374 | aux_read(chip, &buf, pkt_size - rem, &pos); | ||
375 | aux_read(chip, &oob, ecc_size, &pos); | ||
376 | } | ||
377 | |||
378 | static void raw_write(struct nand_chip *chip, const u8 *buf, const u8 *oob) | ||
379 | { | ||
380 | struct mtd_info *mtd = nand_to_mtd(chip); | ||
381 | const u8 *oob_orig = oob; | ||
382 | const int page_size = mtd->writesize; | ||
383 | const int ecc_size = chip->ecc.bytes; | ||
384 | const int pkt_size = chip->ecc.size; | ||
385 | int pos = 0; /* position within physical page */ | ||
386 | int rem = page_size; /* bytes remaining until BBM area */ | ||
387 | |||
388 | if (oob) | ||
389 | oob += BBM_SIZE; | ||
390 | |||
391 | aux_write(chip, &oob, METADATA_SIZE, &pos); | ||
392 | |||
393 | while (rem > pkt_size) { | ||
394 | aux_write(chip, &buf, pkt_size, &pos); | ||
395 | aux_write(chip, &oob, ecc_size, &pos); | ||
396 | rem = page_size - pos; | ||
397 | } | ||
398 | |||
399 | aux_write(chip, &buf, rem, &pos); | ||
400 | aux_write(chip, &oob_orig, BBM_SIZE, &pos); | ||
401 | aux_write(chip, &buf, pkt_size - rem, &pos); | ||
402 | aux_write(chip, &oob, ecc_size, &pos); | ||
403 | } | ||
404 | |||
405 | static int tango_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, | ||
406 | u8 *buf, int oob_required, int page) | ||
407 | { | ||
408 | chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page); | ||
409 | raw_read(chip, buf, chip->oob_poi); | ||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | static int tango_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip, | ||
414 | const u8 *buf, int oob_required, int page) | ||
415 | { | ||
416 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0, page); | ||
417 | raw_write(chip, buf, chip->oob_poi); | ||
418 | chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); | ||
419 | return 0; | ||
420 | } | ||
421 | |||
422 | static int tango_read_oob(struct mtd_info *mtd, struct nand_chip *chip, | ||
423 | int page) | ||
424 | { | ||
425 | chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page); | ||
426 | raw_read(chip, NULL, chip->oob_poi); | ||
427 | return 0; | ||
428 | } | ||
429 | |||
430 | static int tango_write_oob(struct mtd_info *mtd, struct nand_chip *chip, | ||
431 | int page) | ||
432 | { | ||
433 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0, page); | ||
434 | raw_write(chip, NULL, chip->oob_poi); | ||
435 | chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); | ||
436 | chip->waitfunc(mtd, chip); | ||
437 | return 0; | ||
438 | } | ||
439 | |||
440 | static int oob_ecc(struct mtd_info *mtd, int idx, struct mtd_oob_region *res) | ||
441 | { | ||
442 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
443 | struct nand_ecc_ctrl *ecc = &chip->ecc; | ||
444 | |||
445 | if (idx >= ecc->steps) | ||
446 | return -ERANGE; | ||
447 | |||
448 | res->offset = BBM_SIZE + METADATA_SIZE + ecc->bytes * idx; | ||
449 | res->length = ecc->bytes; | ||
450 | |||
451 | return 0; | ||
452 | } | ||
453 | |||
454 | static int oob_free(struct mtd_info *mtd, int idx, struct mtd_oob_region *res) | ||
455 | { | ||
456 | return -ERANGE; /* no free space in spare area */ | ||
457 | } | ||
458 | |||
459 | static const struct mtd_ooblayout_ops tango_nand_ooblayout_ops = { | ||
460 | .ecc = oob_ecc, | ||
461 | .free = oob_free, | ||
462 | }; | ||
463 | |||
464 | static u32 to_ticks(int kHz, int ps) | ||
465 | { | ||
466 | return DIV_ROUND_UP_ULL((u64)kHz * ps, NSEC_PER_SEC); | ||
467 | } | ||
468 | |||
469 | static int tango_set_timings(struct mtd_info *mtd, | ||
470 | const struct nand_data_interface *conf, | ||
471 | bool check_only) | ||
472 | { | ||
473 | const struct nand_sdr_timings *sdr = nand_get_sdr_timings(conf); | ||
474 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
475 | struct tango_nfc *nfc = to_tango_nfc(chip->controller); | ||
476 | struct tango_chip *tchip = to_tango_chip(chip); | ||
477 | u32 Trdy, Textw, Twc, Twpw, Tacc, Thold, Trpw, Textr; | ||
478 | int kHz = nfc->freq_kHz; | ||
479 | |||
480 | if (IS_ERR(sdr)) | ||
481 | return PTR_ERR(sdr); | ||
482 | |||
483 | if (check_only) | ||
484 | return 0; | ||
485 | |||
486 | Trdy = to_ticks(kHz, sdr->tCEA_max - sdr->tREA_max); | ||
487 | Textw = to_ticks(kHz, sdr->tWB_max); | ||
488 | Twc = to_ticks(kHz, sdr->tWC_min); | ||
489 | Twpw = to_ticks(kHz, sdr->tWC_min - sdr->tWP_min); | ||
490 | |||
491 | Tacc = to_ticks(kHz, sdr->tREA_max); | ||
492 | Thold = to_ticks(kHz, sdr->tREH_min); | ||
493 | Trpw = to_ticks(kHz, sdr->tRC_min - sdr->tREH_min); | ||
494 | Textr = to_ticks(kHz, sdr->tRHZ_max); | ||
495 | |||
496 | tchip->timing1 = TIMING(Trdy, Textw, Twc, Twpw); | ||
497 | tchip->timing2 = TIMING(Tacc, Thold, Trpw, Textr); | ||
498 | |||
499 | return 0; | ||
500 | } | ||
501 | |||
502 | static int chip_init(struct device *dev, struct device_node *np) | ||
503 | { | ||
504 | u32 cs; | ||
505 | int err, res; | ||
506 | struct mtd_info *mtd; | ||
507 | struct nand_chip *chip; | ||
508 | struct tango_chip *tchip; | ||
509 | struct nand_ecc_ctrl *ecc; | ||
510 | struct tango_nfc *nfc = dev_get_drvdata(dev); | ||
511 | |||
512 | tchip = devm_kzalloc(dev, sizeof(*tchip), GFP_KERNEL); | ||
513 | if (!tchip) | ||
514 | return -ENOMEM; | ||
515 | |||
516 | res = of_property_count_u32_elems(np, "reg"); | ||
517 | if (res < 0) | ||
518 | return res; | ||
519 | |||
520 | if (res != 1) | ||
521 | return -ENOTSUPP; /* Multi-CS chips are not supported */ | ||
522 | |||
523 | err = of_property_read_u32_index(np, "reg", 0, &cs); | ||
524 | if (err) | ||
525 | return err; | ||
526 | |||
527 | if (cs >= MAX_CS) | ||
528 | return -EINVAL; | ||
529 | |||
530 | chip = &tchip->nand_chip; | ||
531 | ecc = &chip->ecc; | ||
532 | mtd = nand_to_mtd(chip); | ||
533 | |||
534 | chip->read_byte = tango_read_byte; | ||
535 | chip->write_buf = tango_write_buf; | ||
536 | chip->read_buf = tango_read_buf; | ||
537 | chip->select_chip = tango_select_chip; | ||
538 | chip->cmd_ctrl = tango_cmd_ctrl; | ||
539 | chip->dev_ready = tango_dev_ready; | ||
540 | chip->setup_data_interface = tango_set_timings; | ||
541 | chip->options = NAND_USE_BOUNCE_BUFFER | | ||
542 | NAND_NO_SUBPAGE_WRITE | | ||
543 | NAND_WAIT_TCCS; | ||
544 | chip->controller = &nfc->hw; | ||
545 | tchip->base = nfc->pbus_base + (cs * 256); | ||
546 | |||
547 | nand_set_flash_node(chip, np); | ||
548 | mtd_set_ooblayout(mtd, &tango_nand_ooblayout_ops); | ||
549 | mtd->dev.parent = dev; | ||
550 | |||
551 | err = nand_scan_ident(mtd, 1, NULL); | ||
552 | if (err) | ||
553 | return err; | ||
554 | |||
555 | ecc->mode = NAND_ECC_HW; | ||
556 | ecc->algo = NAND_ECC_BCH; | ||
557 | ecc->bytes = DIV_ROUND_UP(ecc->strength * FIELD_ORDER, BITS_PER_BYTE); | ||
558 | |||
559 | ecc->read_page_raw = tango_read_page_raw; | ||
560 | ecc->write_page_raw = tango_write_page_raw; | ||
561 | ecc->read_page = tango_read_page; | ||
562 | ecc->write_page = tango_write_page; | ||
563 | ecc->read_oob = tango_read_oob; | ||
564 | ecc->write_oob = tango_write_oob; | ||
565 | ecc->options = NAND_ECC_CUSTOM_PAGE_ACCESS; | ||
566 | |||
567 | err = nand_scan_tail(mtd); | ||
568 | if (err) | ||
569 | return err; | ||
570 | |||
571 | tchip->xfer_cfg = XFER_CFG(cs, 1, ecc->steps, METADATA_SIZE); | ||
572 | tchip->pkt_0_cfg = PKT_CFG(ecc->size + METADATA_SIZE, ecc->strength); | ||
573 | tchip->pkt_n_cfg = PKT_CFG(ecc->size, ecc->strength); | ||
574 | tchip->bb_cfg = BB_CFG(mtd->writesize, BBM_SIZE); | ||
575 | |||
576 | err = mtd_device_register(mtd, NULL, 0); | ||
577 | if (err) | ||
578 | return err; | ||
579 | |||
580 | nfc->chips[cs] = tchip; | ||
581 | |||
582 | return 0; | ||
583 | } | ||
584 | |||
585 | static int tango_nand_remove(struct platform_device *pdev) | ||
586 | { | ||
587 | int cs; | ||
588 | struct tango_nfc *nfc = platform_get_drvdata(pdev); | ||
589 | |||
590 | dma_release_channel(nfc->chan); | ||
591 | |||
592 | for (cs = 0; cs < MAX_CS; ++cs) { | ||
593 | if (nfc->chips[cs]) | ||
594 | nand_release(nand_to_mtd(&nfc->chips[cs]->nand_chip)); | ||
595 | } | ||
596 | |||
597 | return 0; | ||
598 | } | ||
599 | |||
600 | static int tango_nand_probe(struct platform_device *pdev) | ||
601 | { | ||
602 | int err; | ||
603 | struct clk *clk; | ||
604 | struct resource *res; | ||
605 | struct tango_nfc *nfc; | ||
606 | struct device_node *np; | ||
607 | |||
608 | nfc = devm_kzalloc(&pdev->dev, sizeof(*nfc), GFP_KERNEL); | ||
609 | if (!nfc) | ||
610 | return -ENOMEM; | ||
611 | |||
612 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
613 | nfc->reg_base = devm_ioremap_resource(&pdev->dev, res); | ||
614 | if (IS_ERR(nfc->reg_base)) | ||
615 | return PTR_ERR(nfc->reg_base); | ||
616 | |||
617 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
618 | nfc->mem_base = devm_ioremap_resource(&pdev->dev, res); | ||
619 | if (IS_ERR(nfc->mem_base)) | ||
620 | return PTR_ERR(nfc->mem_base); | ||
621 | |||
622 | res = platform_get_resource(pdev, IORESOURCE_MEM, 2); | ||
623 | nfc->pbus_base = devm_ioremap_resource(&pdev->dev, res); | ||
624 | if (IS_ERR(nfc->pbus_base)) | ||
625 | return PTR_ERR(nfc->pbus_base); | ||
626 | |||
627 | clk = clk_get(&pdev->dev, NULL); | ||
628 | if (IS_ERR(clk)) | ||
629 | return PTR_ERR(clk); | ||
630 | |||
631 | nfc->chan = dma_request_chan(&pdev->dev, "nfc_sbox"); | ||
632 | if (IS_ERR(nfc->chan)) | ||
633 | return PTR_ERR(nfc->chan); | ||
634 | |||
635 | platform_set_drvdata(pdev, nfc); | ||
636 | nand_hw_control_init(&nfc->hw); | ||
637 | nfc->freq_kHz = clk_get_rate(clk) / 1000; | ||
638 | |||
639 | for_each_child_of_node(pdev->dev.of_node, np) { | ||
640 | err = chip_init(&pdev->dev, np); | ||
641 | if (err) { | ||
642 | tango_nand_remove(pdev); | ||
643 | return err; | ||
644 | } | ||
645 | } | ||
646 | |||
647 | return 0; | ||
648 | } | ||
649 | |||
650 | static const struct of_device_id tango_nand_ids[] = { | ||
651 | { .compatible = "sigma,smp8758-nand" }, | ||
652 | { /* sentinel */ } | ||
653 | }; | ||
654 | |||
655 | static struct platform_driver tango_nand_driver = { | ||
656 | .probe = tango_nand_probe, | ||
657 | .remove = tango_nand_remove, | ||
658 | .driver = { | ||
659 | .name = "tango-nand", | ||
660 | .of_match_table = tango_nand_ids, | ||
661 | }, | ||
662 | }; | ||
663 | |||
664 | module_platform_driver(tango_nand_driver); | ||
665 | |||
666 | MODULE_LICENSE("GPL"); | ||
667 | MODULE_AUTHOR("Sigma Designs"); | ||
668 | MODULE_DESCRIPTION("Tango4 NAND Flash controller driver"); | ||
diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/tmio_nand.c index 08b30549ec0a..fc5e773f8b60 100644 --- a/drivers/mtd/nand/tmio_nand.c +++ b/drivers/mtd/nand/tmio_nand.c | |||
@@ -435,10 +435,10 @@ static int tmio_probe(struct platform_device *dev) | |||
435 | nand_chip->waitfunc = tmio_nand_wait; | 435 | nand_chip->waitfunc = tmio_nand_wait; |
436 | 436 | ||
437 | /* Scan to find existence of the device */ | 437 | /* Scan to find existence of the device */ |
438 | if (nand_scan(mtd, 1)) { | 438 | retval = nand_scan(mtd, 1); |
439 | retval = -ENODEV; | 439 | if (retval) |
440 | goto err_irq; | 440 | goto err_irq; |
441 | } | 441 | |
442 | /* Register the partitions */ | 442 | /* Register the partitions */ |
443 | retval = mtd_device_parse_register(mtd, NULL, NULL, | 443 | retval = mtd_device_parse_register(mtd, NULL, NULL, |
444 | data ? data->partition : NULL, | 444 | data ? data->partition : NULL, |
diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c index 3ad514c44dcb..3ea4bb19e12d 100644 --- a/drivers/mtd/nand/vf610_nfc.c +++ b/drivers/mtd/nand/vf610_nfc.c | |||
@@ -717,10 +717,9 @@ static int vf610_nfc_probe(struct platform_device *pdev) | |||
717 | vf610_nfc_preinit_controller(nfc); | 717 | vf610_nfc_preinit_controller(nfc); |
718 | 718 | ||
719 | /* first scan to find the device and get the page size */ | 719 | /* first scan to find the device and get the page size */ |
720 | if (nand_scan_ident(mtd, 1, NULL)) { | 720 | err = nand_scan_ident(mtd, 1, NULL); |
721 | err = -ENXIO; | 721 | if (err) |
722 | goto error; | 722 | goto error; |
723 | } | ||
724 | 723 | ||
725 | vf610_nfc_init_controller(nfc); | 724 | vf610_nfc_init_controller(nfc); |
726 | 725 | ||
@@ -775,10 +774,9 @@ static int vf610_nfc_probe(struct platform_device *pdev) | |||
775 | } | 774 | } |
776 | 775 | ||
777 | /* second phase scan */ | 776 | /* second phase scan */ |
778 | if (nand_scan_tail(mtd)) { | 777 | err = nand_scan_tail(mtd); |
779 | err = -ENXIO; | 778 | if (err) |
780 | goto error; | 779 | goto error; |
781 | } | ||
782 | 780 | ||
783 | platform_set_drvdata(pdev, mtd); | 781 | platform_set_drvdata(pdev, mtd); |
784 | 782 | ||
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index d8905a229f34..c5f3a012ae62 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h | |||
@@ -142,6 +142,12 @@ enum nand_ecc_algo { | |||
142 | */ | 142 | */ |
143 | #define NAND_ECC_GENERIC_ERASED_CHECK BIT(0) | 143 | #define NAND_ECC_GENERIC_ERASED_CHECK BIT(0) |
144 | #define NAND_ECC_MAXIMIZE BIT(1) | 144 | #define NAND_ECC_MAXIMIZE BIT(1) |
145 | /* | ||
146 | * If your controller already sends the required NAND commands when | ||
147 | * reading or writing a page, then the framework is not supposed to | ||
148 | * send READ0 and SEQIN/PAGEPROG respectively. | ||
149 | */ | ||
150 | #define NAND_ECC_CUSTOM_PAGE_ACCESS BIT(2) | ||
145 | 151 | ||
146 | /* Bit mask for flags passed to do_nand_read_ecc */ | 152 | /* Bit mask for flags passed to do_nand_read_ecc */ |
147 | #define NAND_GET_DEVICE 0x80 | 153 | #define NAND_GET_DEVICE 0x80 |
@@ -186,6 +192,7 @@ enum nand_ecc_algo { | |||
186 | /* Macros to identify the above */ | 192 | /* Macros to identify the above */ |
187 | #define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG)) | 193 | #define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG)) |
188 | #define NAND_HAS_SUBPAGE_READ(chip) ((chip->options & NAND_SUBPAGE_READ)) | 194 | #define NAND_HAS_SUBPAGE_READ(chip) ((chip->options & NAND_SUBPAGE_READ)) |
195 | #define NAND_HAS_SUBPAGE_WRITE(chip) !((chip)->options & NAND_NO_SUBPAGE_WRITE) | ||
189 | 196 | ||
190 | /* Non chip related options */ | 197 | /* Non chip related options */ |
191 | /* This option skips the bbt scan during initialization. */ | 198 | /* This option skips the bbt scan during initialization. */ |
@@ -210,6 +217,16 @@ enum nand_ecc_algo { | |||
210 | */ | 217 | */ |
211 | #define NAND_USE_BOUNCE_BUFFER 0x00100000 | 218 | #define NAND_USE_BOUNCE_BUFFER 0x00100000 |
212 | 219 | ||
220 | /* | ||
221 | * In case your controller is implementing ->cmd_ctrl() and is relying on the | ||
222 | * default ->cmdfunc() implementation, you may want to let the core handle the | ||
223 | * tCCS delay which is required when a column change (RNDIN or RNDOUT) is | ||
224 | * requested. | ||
225 | * If your controller already takes care of this delay, you don't need to set | ||
226 | * this flag. | ||
227 | */ | ||
228 | #define NAND_WAIT_TCCS 0x00200000 | ||
229 | |||
213 | /* Options set by nand scan */ | 230 | /* Options set by nand scan */ |
214 | /* Nand scan has allocated controller struct */ | 231 | /* Nand scan has allocated controller struct */ |
215 | #define NAND_CONTROLLER_ALLOC 0x80000000 | 232 | #define NAND_CONTROLLER_ALLOC 0x80000000 |
@@ -558,6 +575,11 @@ struct nand_ecc_ctrl { | |||
558 | int page); | 575 | int page); |
559 | }; | 576 | }; |
560 | 577 | ||
578 | static inline int nand_standard_page_accessors(struct nand_ecc_ctrl *ecc) | ||
579 | { | ||
580 | return !(ecc->options & NAND_ECC_CUSTOM_PAGE_ACCESS); | ||
581 | } | ||
582 | |||
561 | /** | 583 | /** |
562 | * struct nand_buffers - buffer structure for read/write | 584 | * struct nand_buffers - buffer structure for read/write |
563 | * @ecccalc: buffer pointer for calculated ECC, size is oobsize. | 585 | * @ecccalc: buffer pointer for calculated ECC, size is oobsize. |
@@ -584,6 +606,10 @@ struct nand_buffers { | |||
584 | * | 606 | * |
585 | * All these timings are expressed in picoseconds. | 607 | * All these timings are expressed in picoseconds. |
586 | * | 608 | * |
609 | * @tBERS_max: Block erase time | ||
610 | * @tCCS_min: Change column setup time | ||
611 | * @tPROG_max: Page program time | ||
612 | * @tR_max: Page read time | ||
587 | * @tALH_min: ALE hold time | 613 | * @tALH_min: ALE hold time |
588 | * @tADL_min: ALE to data loading time | 614 | * @tADL_min: ALE to data loading time |
589 | * @tALS_min: ALE setup time | 615 | * @tALS_min: ALE setup time |
@@ -621,6 +647,10 @@ struct nand_buffers { | |||
621 | * @tWW_min: WP# transition to WE# low | 647 | * @tWW_min: WP# transition to WE# low |
622 | */ | 648 | */ |
623 | struct nand_sdr_timings { | 649 | struct nand_sdr_timings { |
650 | u32 tBERS_max; | ||
651 | u32 tCCS_min; | ||
652 | u32 tPROG_max; | ||
653 | u32 tR_max; | ||
624 | u32 tALH_min; | 654 | u32 tALH_min; |
625 | u32 tADL_min; | 655 | u32 tADL_min; |
626 | u32 tALS_min; | 656 | u32 tALS_min; |
diff --git a/include/linux/platform_data/mtd-nand-s3c2410.h b/include/linux/platform_data/mtd-nand-s3c2410.h index c55e42ee57fa..f01659026b26 100644 --- a/include/linux/platform_data/mtd-nand-s3c2410.h +++ b/include/linux/platform_data/mtd-nand-s3c2410.h | |||
@@ -12,9 +12,10 @@ | |||
12 | #ifndef __MTD_NAND_S3C2410_H | 12 | #ifndef __MTD_NAND_S3C2410_H |
13 | #define __MTD_NAND_S3C2410_H | 13 | #define __MTD_NAND_S3C2410_H |
14 | 14 | ||
15 | #include <linux/mtd/nand.h> | ||
16 | |||
15 | /** | 17 | /** |
16 | * struct s3c2410_nand_set - define a set of one or more nand chips | 18 | * struct s3c2410_nand_set - define a set of one or more nand chips |
17 | * @disable_ecc: Entirely disable ECC - Dangerous | ||
18 | * @flash_bbt: Openmoko u-boot can create a Bad Block Table | 19 | * @flash_bbt: Openmoko u-boot can create a Bad Block Table |
19 | * Setting this flag will allow the kernel to | 20 | * Setting this flag will allow the kernel to |
20 | * look for it at boot time and also skip the NAND | 21 | * look for it at boot time and also skip the NAND |
@@ -31,7 +32,6 @@ | |||
31 | * a warning at boot time. | 32 | * a warning at boot time. |
32 | */ | 33 | */ |
33 | struct s3c2410_nand_set { | 34 | struct s3c2410_nand_set { |
34 | unsigned int disable_ecc:1; | ||
35 | unsigned int flash_bbt:1; | 35 | unsigned int flash_bbt:1; |
36 | 36 | ||
37 | unsigned int options; | 37 | unsigned int options; |
@@ -40,6 +40,7 @@ struct s3c2410_nand_set { | |||
40 | char *name; | 40 | char *name; |
41 | int *nr_map; | 41 | int *nr_map; |
42 | struct mtd_partition *partitions; | 42 | struct mtd_partition *partitions; |
43 | struct device_node *of_node; | ||
43 | }; | 44 | }; |
44 | 45 | ||
45 | struct s3c2410_platform_nand { | 46 | struct s3c2410_platform_nand { |
@@ -51,6 +52,8 @@ struct s3c2410_platform_nand { | |||
51 | 52 | ||
52 | unsigned int ignore_unset_ecc:1; | 53 | unsigned int ignore_unset_ecc:1; |
53 | 54 | ||
55 | nand_ecc_modes_t ecc_mode; | ||
56 | |||
54 | int nr_sets; | 57 | int nr_sets; |
55 | struct s3c2410_nand_set *sets; | 58 | struct s3c2410_nand_set *sets; |
56 | 59 | ||