diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-12 17:57:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-05-12 17:57:52 -0400 |
commit | 4dbf09fea60d158e60a30c419e0cfa1ea138dd57 (patch) | |
tree | 9530efcb3ca37e6664b9df41e8a33ea7286dba50 | |
parent | 983dfa4b6ee556563f7963348e4e2f97fc8a15b8 (diff) | |
parent | 3008ba87093852f3756c5d33f584602e5e2a4aa4 (diff) |
Merge tag 'mtd/for-5.2' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/mtd/linux
Pull MTD updates from Richard Weinberger:
"MTD core changes:
- New AFS partition parser
- Update MAINTAINERS entry
- Use of fall-throughs markers
NAND core changes:
- Support having the bad block markers in either the first, second or
last page of a block. The combination of all three location is now
possible.
- Constification of NAND_OP_PARSER(_PATTERN) elements.
- Generic NAND DT bindings changed to yaml format (can be used to
check the proposed bindings. First platform to be fully supported:
sunxi.
- Stopped using several legacy hooks.
- Preparation to use the generic NAND layer with the addition of
several helpers and the removal of the struct nand_chip from
generic functions.
- Kconfig cleanup to prepare the introduction of external ECC engines
support.
- Fallthrough comments.
- Introduction of the SPI-mem dirmap API for SPI-NAND devices.
Raw NAND controller drivers changes:
- nandsim:
- Switch to ->exec-op().
- meson:
- Misc cleanups and fixes.
- New OOB layout.
- Sunxi:
- A23/A33 NAND DMA support.
- Ingenic:
- Full reorganization and cleanup.
- Clear separation between NAND controller and ECC engine.
- Support JZ4740 an JZ4725B.
- Denali:
- Clear controller/chip separation.
- ->exec_op() migration.
- Various cleanups.
- fsl_elbc:
- Enable software ECC support.
- Atmel:
- Sam9x60 support.
- GPMI:
- Introduce the GPMI_IS_MXS() macro.
- Various trivial/spelling/coding style fixes.
SPI NOR core changes:
- Print all JEDEC ID bytes on error
- Fix comment of spi_nor_find_best_erase_type()
- Add region locking flags for s25fl512s
SPI NOR controller drivers changes:
- intel-spi:
- Avoid crossing 4K address boundary on read/write
- Add support for Intel Comet Lake SPI serial flash"
* tag 'mtd/for-5.2' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/mtd/linux: (120 commits)
mtd: part: fix incorrect format specifier for an unsigned long long
mtd: lpddr_cmds: Mark expected switch fall-through
mtd: phram: Mark expected switch fall-throughs
mtd: cfi_cmdset_0002: Mark expected switch fall-throughs
mtd: cfi_util: mark expected switch fall-throughs
MAINTAINERS: MTD Git repository is hosted on kernel.org
MAINTAINERS: Update jffs2 entry
mtd: afs: add v2 partition parsing
mtd: afs: factor the IIS read into partition parser
mtd: afs: factor footer parsing into the v1 part parsing
mtd: factor out v1 partition parsing
mtd: afs: simplify partition detection
mtd: afs: simplify partition parsing
mtd: partitions: Add OF support to AFS partitions
mtd: partitions: Add AFS partitions DT bindings
mtd: afs: Move AFS partition parser to parsers subdir
mtd: maps: Make uclinux_ram_map static
mtd: maps: Allow MTD_PHYSMAP with MTD_RAM
MAINTAINERS: Add myself as MTD maintainer
MAINTAINERS: Remove my name from the MTD and NAND entries
...
187 files changed, 4763 insertions, 2862 deletions
diff --git a/Documentation/devicetree/bindings/memory-controllers/atmel,ebi.txt b/Documentation/devicetree/bindings/memory-controllers/atmel,ebi.txt index 9bb5f57e2066..94bf7896a688 100644 --- a/Documentation/devicetree/bindings/memory-controllers/atmel,ebi.txt +++ b/Documentation/devicetree/bindings/memory-controllers/atmel,ebi.txt | |||
@@ -15,6 +15,7 @@ Required properties: | |||
15 | "atmel,at91sam9g45-ebi" | 15 | "atmel,at91sam9g45-ebi" |
16 | "atmel,at91sam9x5-ebi" | 16 | "atmel,at91sam9x5-ebi" |
17 | "atmel,sama5d3-ebi" | 17 | "atmel,sama5d3-ebi" |
18 | "microchip,sam9x60-ebi" | ||
18 | 19 | ||
19 | - reg: Contains offset/length value for EBI memory mapping. | 20 | - reg: Contains offset/length value for EBI memory mapping. |
20 | This property might contain several entries if the EBI | 21 | This property might contain several entries if the EBI |
diff --git a/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml b/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml new file mode 100644 index 000000000000..fbd4da3684fc --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/allwinner,sun4i-a10-nand.yaml | |||
@@ -0,0 +1,97 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | %YAML 1.2 | ||
3 | --- | ||
4 | $id: http://devicetree.org/schemas/mtd/allwinner,sun4i-a10-nand.yaml# | ||
5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
6 | |||
7 | title: Allwinner A10 NAND Controller Device Tree Bindings | ||
8 | |||
9 | allOf: | ||
10 | - $ref: "nand-controller.yaml" | ||
11 | |||
12 | maintainers: | ||
13 | - Chen-Yu Tsai <wens@csie.org> | ||
14 | - Maxime Ripard <maxime.ripard@bootlin.com> | ||
15 | |||
16 | properties: | ||
17 | "#address-cells": true | ||
18 | "#size-cells": true | ||
19 | |||
20 | compatible: | ||
21 | enum: | ||
22 | - allwinner,sun4i-a10-nand | ||
23 | - allwinner,sun8i-a23-nand-controller | ||
24 | reg: | ||
25 | maxItems: 1 | ||
26 | |||
27 | interrupts: | ||
28 | maxItems: 1 | ||
29 | |||
30 | clocks: | ||
31 | items: | ||
32 | - description: Bus Clock | ||
33 | - description: Module Clock | ||
34 | |||
35 | clock-names: | ||
36 | items: | ||
37 | - const: ahb | ||
38 | - const: mod | ||
39 | |||
40 | resets: | ||
41 | maxItems: 1 | ||
42 | |||
43 | reset-names: | ||
44 | const: ahb | ||
45 | |||
46 | dmas: | ||
47 | maxItems: 1 | ||
48 | |||
49 | dma-names: | ||
50 | const: rxtx | ||
51 | |||
52 | pinctrl-names: true | ||
53 | |||
54 | patternProperties: | ||
55 | "^pinctrl-[0-9]+$": true | ||
56 | |||
57 | "^nand@[a-f0-9]+$": | ||
58 | properties: | ||
59 | reg: | ||
60 | maxItems: 1 | ||
61 | minimum: 0 | ||
62 | maximum: 7 | ||
63 | |||
64 | nand-ecc-mode: true | ||
65 | |||
66 | nand-ecc-algo: | ||
67 | const: bch | ||
68 | |||
69 | nand-ecc-step-size: | ||
70 | enum: [ 512, 1024 ] | ||
71 | |||
72 | nand-ecc-strength: | ||
73 | maximum: 80 | ||
74 | |||
75 | allwinner,rb: | ||
76 | description: | ||
77 | Contains the native Ready/Busy IDs. | ||
78 | allOf: | ||
79 | - $ref: /schemas/types.yaml#/definitions/uint32-array | ||
80 | - minItems: 1 | ||
81 | maxItems: 2 | ||
82 | items: | ||
83 | minimum: 0 | ||
84 | maximum: 1 | ||
85 | |||
86 | additionalProperties: false | ||
87 | |||
88 | required: | ||
89 | - compatible | ||
90 | - reg | ||
91 | - interrupts | ||
92 | - clocks | ||
93 | - clock-names | ||
94 | |||
95 | additionalProperties: false | ||
96 | |||
97 | ... | ||
diff --git a/Documentation/devicetree/bindings/mtd/atmel-nand.txt b/Documentation/devicetree/bindings/mtd/atmel-nand.txt index 9bb66e476672..68b51dc58816 100644 --- a/Documentation/devicetree/bindings/mtd/atmel-nand.txt +++ b/Documentation/devicetree/bindings/mtd/atmel-nand.txt | |||
@@ -14,6 +14,7 @@ Required properties: | |||
14 | "atmel,at91sam9261-nand-controller" | 14 | "atmel,at91sam9261-nand-controller" |
15 | "atmel,at91sam9g45-nand-controller" | 15 | "atmel,at91sam9g45-nand-controller" |
16 | "atmel,sama5d3-nand-controller" | 16 | "atmel,sama5d3-nand-controller" |
17 | "microchip,sam9x60-nand-controller" | ||
17 | - ranges: empty ranges property to forward EBI ranges definitions. | 18 | - ranges: empty ranges property to forward EBI ranges definitions. |
18 | - #address-cells: should be set to 2. | 19 | - #address-cells: should be set to 2. |
19 | - #size-cells: should be set to 1. | 20 | - #size-cells: should be set to 1. |
diff --git a/Documentation/devicetree/bindings/mtd/denali-nand.txt b/Documentation/devicetree/bindings/mtd/denali-nand.txt index f33da8782741..b14b6751c2f3 100644 --- a/Documentation/devicetree/bindings/mtd/denali-nand.txt +++ b/Documentation/devicetree/bindings/mtd/denali-nand.txt | |||
@@ -7,34 +7,48 @@ Required properties: | |||
7 | "socionext,uniphier-denali-nand-v5b" - for Socionext UniPhier (v5b) | 7 | "socionext,uniphier-denali-nand-v5b" - for Socionext UniPhier (v5b) |
8 | - reg : should contain registers location and length for data and reg. | 8 | - reg : should contain registers location and length for data and reg. |
9 | - reg-names: Should contain the reg names "nand_data" and "denali_reg" | 9 | - reg-names: Should contain the reg names "nand_data" and "denali_reg" |
10 | - #address-cells: should be 1. The cell encodes the chip select connection. | ||
11 | - #size-cells : should be 0. | ||
10 | - interrupts : The interrupt number. | 12 | - interrupts : The interrupt number. |
11 | - clocks: should contain phandle of the controller core clock, the bus | 13 | - clocks: should contain phandle of the controller core clock, the bus |
12 | interface clock, and the ECC circuit clock. | 14 | interface clock, and the ECC circuit clock. |
13 | - clock-names: should contain "nand", "nand_x", "ecc" | 15 | - clock-names: should contain "nand", "nand_x", "ecc" |
14 | 16 | ||
15 | Optional properties: | 17 | Sub-nodes: |
16 | - nand-ecc-step-size: see nand.txt for details. If present, the value must be | 18 | Sub-nodes represent available NAND chips. |
17 | 512 for "altr,socfpga-denali-nand" | 19 | |
18 | 1024 for "socionext,uniphier-denali-nand-v5a" | 20 | Required properties: |
19 | 1024 for "socionext,uniphier-denali-nand-v5b" | 21 | - reg: should contain the bank ID of the controller to which each chip |
20 | - nand-ecc-strength: see nand.txt for details. Valid values are: | 22 | select is connected. |
21 | 8, 15 for "altr,socfpga-denali-nand" | 23 | |
22 | 8, 16, 24 for "socionext,uniphier-denali-nand-v5a" | 24 | Optional properties: |
23 | 8, 16 for "socionext,uniphier-denali-nand-v5b" | 25 | - nand-ecc-step-size: see nand.txt for details. |
24 | - nand-ecc-maximize: see nand.txt for details | 26 | If present, the value must be |
25 | 27 | 512 for "altr,socfpga-denali-nand" | |
26 | The device tree may optionally contain sub-nodes describing partitions of the | 28 | 1024 for "socionext,uniphier-denali-nand-v5a" |
29 | 1024 for "socionext,uniphier-denali-nand-v5b" | ||
30 | - nand-ecc-strength: see nand.txt for details. Valid values are: | ||
31 | 8, 15 for "altr,socfpga-denali-nand" | ||
32 | 8, 16, 24 for "socionext,uniphier-denali-nand-v5a" | ||
33 | 8, 16 for "socionext,uniphier-denali-nand-v5b" | ||
34 | - nand-ecc-maximize: see nand.txt for details | ||
35 | |||
36 | The chip nodes may optionally contain sub-nodes describing partitions of the | ||
27 | address space. See partition.txt for more detail. | 37 | address space. See partition.txt for more detail. |
28 | 38 | ||
29 | Examples: | 39 | Examples: |
30 | 40 | ||
31 | nand: nand@ff900000 { | 41 | nand: nand@ff900000 { |
32 | #address-cells = <1>; | 42 | #address-cells = <1>; |
33 | #size-cells = <1>; | 43 | #size-cells = <0>; |
34 | compatible = "altr,socfpga-denali-nand"; | 44 | compatible = "altr,socfpga-denali-nand"; |
35 | reg = <0xff900000 0x20>, <0xffb80000 0x1000>; | 45 | reg = <0xff900000 0x20>, <0xffb80000 0x1000>; |
36 | reg-names = "nand_data", "denali_reg"; | 46 | reg-names = "nand_data", "denali_reg"; |
37 | clocks = <&nand_clk>, <&nand_x_clk>, <&nand_ecc_clk>; | 47 | clocks = <&nand_clk>, <&nand_x_clk>, <&nand_ecc_clk>; |
38 | clock-names = "nand", "nand_x", "ecc"; | 48 | clock-names = "nand", "nand_x", "ecc"; |
39 | interrupts = <0 144 4>; | 49 | interrupts = <0 144 4>; |
50 | |||
51 | nand@0 { | ||
52 | reg = <0>; | ||
53 | } | ||
40 | }; | 54 | }; |
diff --git a/Documentation/devicetree/bindings/mtd/ingenic,jz4780-nand.txt b/Documentation/devicetree/bindings/mtd/ingenic,jz4780-nand.txt index 29ea5853ca91..c02259353327 100644 --- a/Documentation/devicetree/bindings/mtd/ingenic,jz4780-nand.txt +++ b/Documentation/devicetree/bindings/mtd/ingenic,jz4780-nand.txt | |||
@@ -1,4 +1,4 @@ | |||
1 | * Ingenic JZ4780 NAND/BCH | 1 | * Ingenic JZ4780 NAND/ECC |
2 | 2 | ||
3 | This file documents the device tree bindings for NAND flash devices on the | 3 | This file documents the device tree bindings for NAND flash devices on the |
4 | JZ4780. NAND devices are connected to the NEMC controller (described in | 4 | JZ4780. NAND devices are connected to the NEMC controller (described in |
@@ -6,15 +6,18 @@ memory-controllers/ingenic,jz4780-nemc.txt), and thus NAND device nodes must | |||
6 | be children of the NEMC node. | 6 | be children of the NEMC node. |
7 | 7 | ||
8 | Required NAND controller device properties: | 8 | Required NAND controller device properties: |
9 | - compatible: Should be set to "ingenic,jz4780-nand". | 9 | - compatible: Should be one of: |
10 | * ingenic,jz4740-nand | ||
11 | * ingenic,jz4725b-nand | ||
12 | * ingenic,jz4780-nand | ||
10 | - reg: For each bank with a NAND chip attached, should specify a bank number, | 13 | - reg: For each bank with a NAND chip attached, should specify a bank number, |
11 | an offset of 0 and a size of 0x1000000 (i.e. the whole NEMC bank). | 14 | an offset of 0 and a size of 0x1000000 (i.e. the whole NEMC bank). |
12 | 15 | ||
13 | Optional NAND controller device properties: | 16 | Optional NAND controller device properties: |
14 | - ingenic,bch-controller: To make use of the hardware BCH controller, this | 17 | - ecc-engine: To make use of the hardware ECC controller, this |
15 | property must contain a phandle for the BCH controller node. The required | 18 | property must contain a phandle for the ECC controller node. The required |
16 | properties for this node are described below. If this is not specified, | 19 | properties for this node are described below. If this is not specified, |
17 | software BCH will be used instead. | 20 | software ECC will be used instead. |
18 | 21 | ||
19 | Optional children nodes: | 22 | Optional children nodes: |
20 | - Individual NAND chips are children of the NAND controller node. | 23 | - Individual NAND chips are children of the NAND controller node. |
@@ -45,7 +48,7 @@ nemc: nemc@13410000 { | |||
45 | #address-cells = <1>; | 48 | #address-cells = <1>; |
46 | #size-cells = <0>; | 49 | #size-cells = <0>; |
47 | 50 | ||
48 | ingenic,bch-controller = <&bch>; | 51 | ecc-engine = <&bch>; |
49 | 52 | ||
50 | nand@1 { | 53 | nand@1 { |
51 | reg = <1>; | 54 | reg = <1>; |
@@ -67,14 +70,17 @@ nemc: nemc@13410000 { | |||
67 | }; | 70 | }; |
68 | }; | 71 | }; |
69 | 72 | ||
70 | The BCH controller is a separate SoC component used for error correction on | 73 | The ECC controller is a separate SoC component used for error correction on |
71 | NAND devices. The following is a description of the device properties for a | 74 | NAND devices. The following is a description of the device properties for a |
72 | BCH controller. | 75 | ECC controller. |
73 | 76 | ||
74 | Required BCH properties: | 77 | Required ECC properties: |
75 | - compatible: Should be set to "ingenic,jz4780-bch". | 78 | - compatible: Should be one of: |
76 | - reg: Should specify the BCH controller registers location and length. | 79 | * ingenic,jz4740-ecc |
77 | - clocks: Clock for the BCH controller. | 80 | * ingenic,jz4725b-bch |
81 | * ingenic,jz4780-bch | ||
82 | - reg: Should specify the ECC controller registers location and length. | ||
83 | - clocks: Clock for the ECC controller. | ||
78 | 84 | ||
79 | Example: | 85 | Example: |
80 | 86 | ||
diff --git a/Documentation/devicetree/bindings/mtd/mtd-physmap.txt b/Documentation/devicetree/bindings/mtd/mtd-physmap.txt index 7df0dcaccb7d..c69f4f065d23 100644 --- a/Documentation/devicetree/bindings/mtd/mtd-physmap.txt +++ b/Documentation/devicetree/bindings/mtd/mtd-physmap.txt | |||
@@ -96,3 +96,19 @@ An example using SRAM: | |||
96 | bank-width = <2>; | 96 | bank-width = <2>; |
97 | }; | 97 | }; |
98 | 98 | ||
99 | An example using gpio-addrs | ||
100 | |||
101 | flash@20000000 { | ||
102 | #address-cells = <1>; | ||
103 | #size-cells = <1>; | ||
104 | compatible = "cfi-flash", "jedec-flash"; | ||
105 | reg = <0x20000000 0x02000000>; | ||
106 | ranges = <0 0x00000000 0x02000000 | ||
107 | 1 0x02000000 0x02000000>; | ||
108 | bank-width = <2>; | ||
109 | addr-gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>; | ||
110 | partition@0 { | ||
111 | label = "test-part1"; | ||
112 | reg = <0 0x04000000>; | ||
113 | }; | ||
114 | }; | ||
diff --git a/Documentation/devicetree/bindings/mtd/nand-controller.yaml b/Documentation/devicetree/bindings/mtd/nand-controller.yaml new file mode 100644 index 000000000000..199ba5ac2a06 --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/nand-controller.yaml | |||
@@ -0,0 +1,143 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | %YAML 1.2 | ||
3 | --- | ||
4 | $id: http://devicetree.org/schemas/mtd/nand-controller.yaml# | ||
5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | ||
6 | |||
7 | title: NAND Chip and NAND Controller Generic Binding | ||
8 | |||
9 | maintainers: | ||
10 | - Miquel Raynal <miquel.raynal@bootlin.com> | ||
11 | - Richard Weinberger <richard@nod.at> | ||
12 | |||
13 | description: | | ||
14 | The NAND controller should be represented with its own DT node, and | ||
15 | all NAND chips attached to this controller should be defined as | ||
16 | children nodes of the NAND controller. This representation should be | ||
17 | enforced even for simple controllers supporting only one chip. | ||
18 | |||
19 | The ECC strength and ECC step size properties define the user | ||
20 | desires in terms of correction capability of a controller. Together, | ||
21 | they request the ECC engine to correct {strength} bit errors per | ||
22 | {size} bytes. | ||
23 | |||
24 | The interpretation of these parameters is implementation-defined, so | ||
25 | not all implementations must support all possible | ||
26 | combinations. However, implementations are encouraged to further | ||
27 | specify the value(s) they support. | ||
28 | |||
29 | properties: | ||
30 | $nodename: | ||
31 | pattern: "^nand-controller(@.*)?" | ||
32 | |||
33 | "#address-cells": | ||
34 | const: 1 | ||
35 | |||
36 | "#size-cells": | ||
37 | const: 0 | ||
38 | |||
39 | ranges: true | ||
40 | |||
41 | patternProperties: | ||
42 | "^nand@[a-f0-9]$": | ||
43 | properties: | ||
44 | reg: | ||
45 | description: | ||
46 | Contains the native Ready/Busy IDs. | ||
47 | |||
48 | nand-ecc-mode: | ||
49 | allOf: | ||
50 | - $ref: /schemas/types.yaml#/definitions/string | ||
51 | - enum: [ none, soft, hw, hw_syndrome, hw_oob_first, on-die ] | ||
52 | description: | ||
53 | Desired ECC engine, either hardware (most of the time | ||
54 | embedded in the NAND controller) or software correction | ||
55 | (Linux will handle the calculations). soft_bch is deprecated | ||
56 | and should be replaced by soft and nand-ecc-algo. | ||
57 | |||
58 | nand-ecc-algo: | ||
59 | allOf: | ||
60 | - $ref: /schemas/types.yaml#/definitions/string | ||
61 | - enum: [ hamming, bch, rs ] | ||
62 | description: | ||
63 | Desired ECC algorithm. | ||
64 | |||
65 | nand-bus-width: | ||
66 | allOf: | ||
67 | - $ref: /schemas/types.yaml#/definitions/uint32 | ||
68 | - enum: [ 8, 16 ] | ||
69 | - default: 8 | ||
70 | description: | ||
71 | Bus width to the NAND chip | ||
72 | |||
73 | nand-on-flash-bbt: | ||
74 | $ref: /schemas/types.yaml#/definitions/flag | ||
75 | description: | ||
76 | With this property, the OS will search the device for a Bad | ||
77 | Block Table (BBT). If not found, it will create one, reserve | ||
78 | a few blocks at the end of the device to store it and update | ||
79 | it as the device ages. Otherwise, the out-of-band area of a | ||
80 | few pages of all the blocks will be scanned at boot time to | ||
81 | find Bad Block Markers (BBM). These markers will help to | ||
82 | build a volatile BBT in RAM. | ||
83 | |||
84 | nand-ecc-strength: | ||
85 | allOf: | ||
86 | - $ref: /schemas/types.yaml#/definitions/uint32 | ||
87 | - minimum: 1 | ||
88 | description: | ||
89 | Maximum number of bits that can be corrected per ECC step. | ||
90 | |||
91 | nand-ecc-step-size: | ||
92 | allOf: | ||
93 | - $ref: /schemas/types.yaml#/definitions/uint32 | ||
94 | - minimum: 1 | ||
95 | description: | ||
96 | Number of data bytes covered by a single ECC step. | ||
97 | |||
98 | nand-ecc-maximize: | ||
99 | $ref: /schemas/types.yaml#/definitions/flag | ||
100 | description: | ||
101 | Whether or not the ECC strength should be maximized. The | ||
102 | maximum ECC strength is both controller and chip | ||
103 | dependent. The ECC engine has to select the ECC config | ||
104 | providing the best strength and taking the OOB area size | ||
105 | constraint into account. This is particularly useful when | ||
106 | only the in-band area is used by the upper layers, and you | ||
107 | want to make your NAND as reliable as possible. | ||
108 | |||
109 | nand-is-boot-medium: | ||
110 | $ref: /schemas/types.yaml#/definitions/flag | ||
111 | description: | ||
112 | Whether or not the NAND chip is a boot medium. Drivers might | ||
113 | use this information to select ECC algorithms supported by | ||
114 | the boot ROM or similar restrictions. | ||
115 | |||
116 | nand-rb: | ||
117 | $ref: /schemas/types.yaml#/definitions/uint32-array | ||
118 | description: | ||
119 | Contains the native Ready/Busy IDs. | ||
120 | |||
121 | required: | ||
122 | - reg | ||
123 | |||
124 | required: | ||
125 | - "#address-cells" | ||
126 | - "#size-cells" | ||
127 | |||
128 | examples: | ||
129 | - | | ||
130 | nand-controller { | ||
131 | #address-cells = <1>; | ||
132 | #size-cells = <0>; | ||
133 | |||
134 | /* controller specific properties */ | ||
135 | |||
136 | nand@0 { | ||
137 | reg = <0>; | ||
138 | nand-ecc-mode = "soft"; | ||
139 | nand-ecc-algo = "bch"; | ||
140 | |||
141 | /* controller specific properties */ | ||
142 | }; | ||
143 | }; | ||
diff --git a/Documentation/devicetree/bindings/mtd/nand.txt b/Documentation/devicetree/bindings/mtd/nand.txt deleted file mode 100644 index e949c778e983..000000000000 --- a/Documentation/devicetree/bindings/mtd/nand.txt +++ /dev/null | |||
@@ -1,75 +0,0 @@ | |||
1 | * NAND chip and NAND controller generic binding | ||
2 | |||
3 | NAND controller/NAND chip representation: | ||
4 | |||
5 | The NAND controller should be represented with its own DT node, and all | ||
6 | NAND chips attached to this controller should be defined as children nodes | ||
7 | of the NAND controller. This representation should be enforced even for | ||
8 | simple controllers supporting only one chip. | ||
9 | |||
10 | Mandatory NAND controller properties: | ||
11 | - #address-cells: depends on your controller. Should at least be 1 to | ||
12 | encode the CS line id. | ||
13 | - #size-cells: depends on your controller. Put zero unless you need a | ||
14 | mapping between CS lines and dedicated memory regions | ||
15 | |||
16 | Optional NAND controller properties | ||
17 | - ranges: only needed if you need to define a mapping between CS lines and | ||
18 | memory regions | ||
19 | |||
20 | Optional NAND chip properties: | ||
21 | |||
22 | - nand-ecc-mode : String, operation mode of the NAND ecc mode. | ||
23 | Supported values are: "none", "soft", "hw", "hw_syndrome", | ||
24 | "hw_oob_first", "on-die". | ||
25 | Deprecated values: | ||
26 | "soft_bch": use "soft" and nand-ecc-algo instead | ||
27 | - nand-ecc-algo: string, algorithm of NAND ECC. | ||
28 | Valid values are: "hamming", "bch", "rs". | ||
29 | - nand-bus-width : 8 or 16 bus width if not present 8 | ||
30 | - nand-on-flash-bbt: boolean to enable on flash bbt option if not present false | ||
31 | |||
32 | - nand-ecc-strength: integer representing the number of bits to correct | ||
33 | per ECC step. | ||
34 | |||
35 | - nand-ecc-step-size: integer representing the number of data bytes | ||
36 | that are covered by a single ECC step. | ||
37 | |||
38 | - nand-ecc-maximize: boolean used to specify that you want to maximize ECC | ||
39 | strength. The maximum ECC strength is both controller and | ||
40 | chip dependent. The controller side has to select the ECC | ||
41 | config providing the best strength and taking the OOB area | ||
42 | size constraint into account. | ||
43 | This is particularly useful when only the in-band area is | ||
44 | used by the upper layers, and you want to make your NAND | ||
45 | as reliable as possible. | ||
46 | - nand-is-boot-medium: Whether the NAND chip is a boot medium. Drivers might use | ||
47 | this information to select ECC algorithms supported by | ||
48 | the boot ROM or similar restrictions. | ||
49 | |||
50 | - nand-rb: shall contain the native Ready/Busy ids. | ||
51 | |||
52 | The ECC strength and ECC step size properties define the correction capability | ||
53 | of a controller. Together, they say a controller can correct "{strength} bit | ||
54 | errors per {size} bytes". | ||
55 | |||
56 | The interpretation of these parameters is implementation-defined, so not all | ||
57 | implementations must support all possible combinations. However, implementations | ||
58 | are encouraged to further specify the value(s) they support. | ||
59 | |||
60 | Example: | ||
61 | |||
62 | nand-controller { | ||
63 | #address-cells = <1>; | ||
64 | #size-cells = <0>; | ||
65 | |||
66 | /* controller specific properties */ | ||
67 | |||
68 | nand@0 { | ||
69 | reg = <0>; | ||
70 | nand-ecc-mode = "soft"; | ||
71 | nand-ecc-algo = "bch"; | ||
72 | |||
73 | /* controller specific properties */ | ||
74 | }; | ||
75 | }; | ||
diff --git a/Documentation/devicetree/bindings/mtd/partitions/arm,arm-firmware-suite.txt b/Documentation/devicetree/bindings/mtd/partitions/arm,arm-firmware-suite.txt new file mode 100644 index 000000000000..d5c5616f6db5 --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/partitions/arm,arm-firmware-suite.txt | |||
@@ -0,0 +1,17 @@ | |||
1 | ARM AFS - ARM Firmware Suite Partitions | ||
2 | ======================================= | ||
3 | |||
4 | The ARM Firmware Suite is a flash partitioning system found on the | ||
5 | ARM reference designs: Integrator AP, Integrator CP, Versatile AB, | ||
6 | Versatile PB, the RealView family, Versatile Express and Juno. | ||
7 | |||
8 | Required properties: | ||
9 | - compatible : (required) must be "arm,arm-firmware-suite" | ||
10 | |||
11 | Example: | ||
12 | |||
13 | flash@0 { | ||
14 | partitions { | ||
15 | compatible = "arm,arm-firmware-suite"; | ||
16 | }; | ||
17 | }; | ||
diff --git a/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm963xx-cfe-nor-partitions.txt b/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm963xx-cfe-nor-partitions.txt new file mode 100644 index 000000000000..9f630e95f180 --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm963xx-cfe-nor-partitions.txt | |||
@@ -0,0 +1,24 @@ | |||
1 | Broadcom BCM963XX CFE Loader NOR Flash Partitions | ||
2 | ================================================= | ||
3 | |||
4 | Most Broadcom BCM63XX SoC based devices follow the Broadcom reference layout for | ||
5 | NOR. The first erase block used for the CFE bootloader, the last for an | ||
6 | NVRAM partition, and the remainder in-between for one to two firmware partitions | ||
7 | at fixed offsets. A valid firmware partition is identified by the ImageTag | ||
8 | header found at beginning of the second erase block, containing the rootfs and | ||
9 | kernel offsets and sizes within the firmware partition. | ||
10 | |||
11 | Required properties: | ||
12 | - compatible : must be "brcm,bcm963xx-cfe-nor-partitions" | ||
13 | |||
14 | Example: | ||
15 | |||
16 | flash@1fc00000 { | ||
17 | compatible = "cfi-flash"; | ||
18 | reg = <0x1fc00000 0x400000>; | ||
19 | bank-width = <2>; | ||
20 | |||
21 | partitions { | ||
22 | compatible = "brcm,bcm963xx-cfe-nor-partitions"; | ||
23 | }; | ||
24 | }; | ||
diff --git a/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm963xx-imagetag.txt b/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm963xx-imagetag.txt new file mode 100644 index 000000000000..f8b7418ed817 --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm963xx-imagetag.txt | |||
@@ -0,0 +1,45 @@ | |||
1 | Broadcom BCM963XX ImageTag Partition Container | ||
2 | ============================================== | ||
3 | |||
4 | Some Broadcom BCM63XX SoC based devices contain additional, non discoverable | ||
5 | partitions or non standard bootloader partition sizes. For these a mixed layout | ||
6 | needs to be used with an explicit firmware partition. | ||
7 | |||
8 | The BCM963XX ImageTag is a simple firmware header describing the offsets and | ||
9 | sizes of the rootfs and kernel parts contained in the firmware. | ||
10 | |||
11 | Required properties: | ||
12 | - compatible : must be "brcm,bcm963xx-imagetag" | ||
13 | |||
14 | Example: | ||
15 | |||
16 | flash@1e000000 { | ||
17 | compatible = "cfi-flash"; | ||
18 | reg = <0x1e000000 0x2000000>; | ||
19 | bank-width = <2>; | ||
20 | |||
21 | partitions { | ||
22 | compatible = "fixed-partitions"; | ||
23 | #address-cells = <1>; | ||
24 | #size-cells = <1>; | ||
25 | |||
26 | cfe@0 { | ||
27 | reg = <0x0 0x10000>; | ||
28 | read-only; | ||
29 | }; | ||
30 | |||
31 | firmware@10000 { | ||
32 | reg = <0x10000 0x7d0000>; | ||
33 | compatible = "brcm,bcm963xx-imagetag"; | ||
34 | }; | ||
35 | |||
36 | caldata@7e0000 { | ||
37 | reg = <0x7e0000 0x10000>; | ||
38 | read-only; | ||
39 | }; | ||
40 | |||
41 | nvram@7f0000 { | ||
42 | reg = <0x7f0000 0x10000>; | ||
43 | }; | ||
44 | }; | ||
45 | }; | ||
diff --git a/Documentation/devicetree/bindings/mtd/sunxi-nand.txt b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt deleted file mode 100644 index dcd5a5d80dc0..000000000000 --- a/Documentation/devicetree/bindings/mtd/sunxi-nand.txt +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | Allwinner NAND Flash Controller (NFC) | ||
2 | |||
3 | Required properties: | ||
4 | - compatible : "allwinner,sun4i-a10-nand". | ||
5 | - reg : shall contain registers location and length for data and reg. | ||
6 | - interrupts : shall define the nand controller interrupt. | ||
7 | - #address-cells: shall be set to 1. Encode the nand CS. | ||
8 | - #size-cells : shall be set to 0. | ||
9 | - clocks : shall reference nand controller clocks. | ||
10 | - clock-names : nand controller internal clock names. Shall contain : | ||
11 | * "ahb" : AHB gating clock | ||
12 | * "mod" : nand controller clock | ||
13 | |||
14 | Optional properties: | ||
15 | - dmas : shall reference DMA channel associated to the NAND controller. | ||
16 | - dma-names : shall be "rxtx". | ||
17 | |||
18 | Optional children nodes: | ||
19 | Children nodes represent the available nand chips. | ||
20 | |||
21 | Optional properties: | ||
22 | - reset : phandle + reset specifier pair | ||
23 | - reset-names : must contain "ahb" | ||
24 | - allwinner,rb : shall contain the native Ready/Busy ids. | ||
25 | - nand-ecc-mode : one of the supported ECC modes ("hw", "soft", "soft_bch" or | ||
26 | "none") | ||
27 | |||
28 | see Documentation/devicetree/bindings/mtd/nand.txt for generic bindings. | ||
29 | |||
30 | |||
31 | Examples: | ||
32 | nfc: nand@1c03000 { | ||
33 | compatible = "allwinner,sun4i-a10-nand"; | ||
34 | reg = <0x01c03000 0x1000>; | ||
35 | interrupts = <0 37 1>; | ||
36 | clocks = <&ahb_gates 13>, <&nand_clk>; | ||
37 | clock-names = "ahb", "mod"; | ||
38 | #address-cells = <1>; | ||
39 | #size-cells = <0>; | ||
40 | pinctrl-names = "default"; | ||
41 | pinctrl-0 = <&nand_pins_a &nand_cs0_pins_a &nand_rb0_pins_a>; | ||
42 | |||
43 | nand@0 { | ||
44 | reg = <0>; | ||
45 | allwinner,rb = <0>; | ||
46 | nand-ecc-mode = "soft_bch"; | ||
47 | }; | ||
48 | }; | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 3c65228e93c5..fb9f9d71f7a2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -8418,9 +8418,11 @@ F: drivers/net/ethernet/jme.* | |||
8418 | 8418 | ||
8419 | JOURNALLING FLASH FILE SYSTEM V2 (JFFS2) | 8419 | JOURNALLING FLASH FILE SYSTEM V2 (JFFS2) |
8420 | M: David Woodhouse <dwmw2@infradead.org> | 8420 | M: David Woodhouse <dwmw2@infradead.org> |
8421 | M: Richard Weinberger <richard@nod.at> | ||
8421 | L: linux-mtd@lists.infradead.org | 8422 | L: linux-mtd@lists.infradead.org |
8422 | W: http://www.linux-mtd.infradead.org/doc/jffs2.html | 8423 | W: http://www.linux-mtd.infradead.org/doc/jffs2.html |
8423 | S: Maintained | 8424 | T: git git://git.infradead.org/ubifs-2.6.git |
8425 | S: Odd Fixes | ||
8424 | F: fs/jffs2/ | 8426 | F: fs/jffs2/ |
8425 | F: include/uapi/linux/jffs2.h | 8427 | F: include/uapi/linux/jffs2.h |
8426 | 8428 | ||
@@ -10114,14 +10116,15 @@ F: mm/ | |||
10114 | MEMORY TECHNOLOGY DEVICES (MTD) | 10116 | MEMORY TECHNOLOGY DEVICES (MTD) |
10115 | M: David Woodhouse <dwmw2@infradead.org> | 10117 | M: David Woodhouse <dwmw2@infradead.org> |
10116 | M: Brian Norris <computersforpeace@gmail.com> | 10118 | M: Brian Norris <computersforpeace@gmail.com> |
10117 | M: Boris Brezillon <bbrezillon@kernel.org> | ||
10118 | M: Marek Vasut <marek.vasut@gmail.com> | 10119 | M: Marek Vasut <marek.vasut@gmail.com> |
10120 | M: Miquel Raynal <miquel.raynal@bootlin.com> | ||
10119 | M: Richard Weinberger <richard@nod.at> | 10121 | M: Richard Weinberger <richard@nod.at> |
10122 | M: Vignesh Raghavendra <vigneshr@ti.com> | ||
10120 | L: linux-mtd@lists.infradead.org | 10123 | L: linux-mtd@lists.infradead.org |
10121 | W: http://www.linux-mtd.infradead.org/ | 10124 | W: http://www.linux-mtd.infradead.org/ |
10122 | Q: http://patchwork.ozlabs.org/project/linux-mtd/list/ | 10125 | Q: http://patchwork.ozlabs.org/project/linux-mtd/list/ |
10123 | T: git git://git.infradead.org/linux-mtd.git master | 10126 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git mtd/fixes |
10124 | T: git git://git.infradead.org/linux-mtd.git mtd/next | 10127 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git mtd/next |
10125 | S: Maintained | 10128 | S: Maintained |
10126 | F: Documentation/devicetree/bindings/mtd/ | 10129 | F: Documentation/devicetree/bindings/mtd/ |
10127 | F: drivers/mtd/ | 10130 | F: drivers/mtd/ |
@@ -10730,14 +10733,12 @@ S: Supported | |||
10730 | F: drivers/net/ethernet/myricom/myri10ge/ | 10733 | F: drivers/net/ethernet/myricom/myri10ge/ |
10731 | 10734 | ||
10732 | NAND FLASH SUBSYSTEM | 10735 | NAND FLASH SUBSYSTEM |
10733 | M: Boris Brezillon <bbrezillon@kernel.org> | ||
10734 | M: Miquel Raynal <miquel.raynal@bootlin.com> | 10736 | M: Miquel Raynal <miquel.raynal@bootlin.com> |
10735 | R: Richard Weinberger <richard@nod.at> | 10737 | R: Richard Weinberger <richard@nod.at> |
10736 | L: linux-mtd@lists.infradead.org | 10738 | L: linux-mtd@lists.infradead.org |
10737 | W: http://www.linux-mtd.infradead.org/ | 10739 | W: http://www.linux-mtd.infradead.org/ |
10738 | Q: http://patchwork.ozlabs.org/project/linux-mtd/list/ | 10740 | Q: http://patchwork.ozlabs.org/project/linux-mtd/list/ |
10739 | T: git git://git.infradead.org/linux-mtd.git nand/fixes | 10741 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next |
10740 | T: git git://git.infradead.org/linux-mtd.git nand/next | ||
10741 | S: Maintained | 10742 | S: Maintained |
10742 | F: drivers/mtd/nand/ | 10743 | F: drivers/mtd/nand/ |
10743 | F: include/linux/mtd/*nand*.h | 10744 | F: include/linux/mtd/*nand*.h |
@@ -14751,8 +14752,7 @@ M: Tudor Ambarus <tudor.ambarus@microchip.com> | |||
14751 | L: linux-mtd@lists.infradead.org | 14752 | L: linux-mtd@lists.infradead.org |
14752 | W: http://www.linux-mtd.infradead.org/ | 14753 | W: http://www.linux-mtd.infradead.org/ |
14753 | Q: http://patchwork.ozlabs.org/project/linux-mtd/list/ | 14754 | Q: http://patchwork.ozlabs.org/project/linux-mtd/list/ |
14754 | T: git git://git.infradead.org/linux-mtd.git spi-nor/fixes | 14755 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git spi-nor/next |
14755 | T: git git://git.infradead.org/linux-mtd.git spi-nor/next | ||
14756 | S: Maintained | 14756 | S: Maintained |
14757 | F: drivers/mtd/spi-nor/ | 14757 | F: drivers/mtd/spi-nor/ |
14758 | F: include/linux/mtd/spi-nor.h | 14758 | F: include/linux/mtd/spi-nor.h |
diff --git a/arch/arm/configs/at91_dt_defconfig b/arch/arm/configs/at91_dt_defconfig index b7752929975c..a88e31449880 100644 --- a/arch/arm/configs/at91_dt_defconfig +++ b/arch/arm/configs/at91_dt_defconfig | |||
@@ -55,7 +55,7 @@ CONFIG_MTD=y | |||
55 | CONFIG_MTD_CMDLINE_PARTS=y | 55 | CONFIG_MTD_CMDLINE_PARTS=y |
56 | CONFIG_MTD_BLOCK=y | 56 | CONFIG_MTD_BLOCK=y |
57 | CONFIG_MTD_DATAFLASH=y | 57 | CONFIG_MTD_DATAFLASH=y |
58 | CONFIG_MTD_NAND=y | 58 | CONFIG_MTD_RAW_NAND=y |
59 | CONFIG_MTD_NAND_ATMEL=y | 59 | CONFIG_MTD_NAND_ATMEL=y |
60 | CONFIG_MTD_UBI=y | 60 | CONFIG_MTD_UBI=y |
61 | CONFIG_MTD_UBI_GLUEBI=y | 61 | CONFIG_MTD_UBI_GLUEBI=y |
diff --git a/arch/arm/configs/clps711x_defconfig b/arch/arm/configs/clps711x_defconfig index 09ae750164e0..c255dab36bde 100644 --- a/arch/arm/configs/clps711x_defconfig +++ b/arch/arm/configs/clps711x_defconfig | |||
@@ -35,7 +35,7 @@ CONFIG_MTD_CFI_INTELEXT=y | |||
35 | CONFIG_MTD_CFI_AMDSTD=y | 35 | CONFIG_MTD_CFI_AMDSTD=y |
36 | CONFIG_MTD_CFI_STAA=y | 36 | CONFIG_MTD_CFI_STAA=y |
37 | CONFIG_MTD_PLATRAM=y | 37 | CONFIG_MTD_PLATRAM=y |
38 | CONFIG_MTD_NAND=y | 38 | CONFIG_MTD_RAW_NAND=y |
39 | CONFIG_MTD_NAND_GPIO=y | 39 | CONFIG_MTD_NAND_GPIO=y |
40 | CONFIG_NETDEVICES=y | 40 | CONFIG_NETDEVICES=y |
41 | # CONFIG_NET_CADENCE is not set | 41 | # CONFIG_NET_CADENCE is not set |
diff --git a/arch/arm/configs/cm_x2xx_defconfig b/arch/arm/configs/cm_x2xx_defconfig index fb45b4983d3c..5344434df652 100644 --- a/arch/arm/configs/cm_x2xx_defconfig +++ b/arch/arm/configs/cm_x2xx_defconfig | |||
@@ -58,7 +58,7 @@ CONFIG_MTD_CFI_AMDSTD=y | |||
58 | CONFIG_MTD_CFI_STAA=y | 58 | CONFIG_MTD_CFI_STAA=y |
59 | CONFIG_MTD_PHYSMAP=y | 59 | CONFIG_MTD_PHYSMAP=y |
60 | CONFIG_MTD_PXA2XX=y | 60 | CONFIG_MTD_PXA2XX=y |
61 | CONFIG_MTD_NAND=y | 61 | CONFIG_MTD_RAW_NAND=y |
62 | CONFIG_MTD_NAND_GPIO=m | 62 | CONFIG_MTD_NAND_GPIO=m |
63 | CONFIG_MTD_NAND_CM_X270=y | 63 | CONFIG_MTD_NAND_CM_X270=y |
64 | CONFIG_MTD_NAND_PLATFORM=y | 64 | CONFIG_MTD_NAND_PLATFORM=y |
diff --git a/arch/arm/configs/cm_x300_defconfig b/arch/arm/configs/cm_x300_defconfig index 5e349c625b71..3707a014cbc4 100644 --- a/arch/arm/configs/cm_x300_defconfig +++ b/arch/arm/configs/cm_x300_defconfig | |||
@@ -48,7 +48,7 @@ CONFIG_LIB80211=m | |||
48 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 48 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
49 | CONFIG_MTD=y | 49 | CONFIG_MTD=y |
50 | CONFIG_MTD_BLOCK=y | 50 | CONFIG_MTD_BLOCK=y |
51 | CONFIG_MTD_NAND=y | 51 | CONFIG_MTD_RAW_NAND=y |
52 | CONFIG_MTD_NAND_MARVELL=y | 52 | CONFIG_MTD_NAND_MARVELL=y |
53 | CONFIG_MTD_UBI=y | 53 | CONFIG_MTD_UBI=y |
54 | CONFIG_BLK_DEV_LOOP=y | 54 | CONFIG_BLK_DEV_LOOP=y |
diff --git a/arch/arm/configs/colibri_pxa270_defconfig b/arch/arm/configs/colibri_pxa270_defconfig index 8995695fc118..8d484e4d51cc 100644 --- a/arch/arm/configs/colibri_pxa270_defconfig +++ b/arch/arm/configs/colibri_pxa270_defconfig | |||
@@ -64,7 +64,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y | |||
64 | CONFIG_MTD_PHYSMAP=y | 64 | CONFIG_MTD_PHYSMAP=y |
65 | CONFIG_MTD_PXA2XX=y | 65 | CONFIG_MTD_PXA2XX=y |
66 | CONFIG_MTD_BLOCK2MTD=y | 66 | CONFIG_MTD_BLOCK2MTD=y |
67 | CONFIG_MTD_NAND=y | 67 | CONFIG_MTD_RAW_NAND=y |
68 | CONFIG_MTD_NAND_DISKONCHIP=y | 68 | CONFIG_MTD_NAND_DISKONCHIP=y |
69 | CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y | 69 | CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y |
70 | CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0x4000000 | 70 | CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0x4000000 |
diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig index 09e1672777c9..d99725984947 100644 --- a/arch/arm/configs/corgi_defconfig +++ b/arch/arm/configs/corgi_defconfig | |||
@@ -87,7 +87,7 @@ CONFIG_MTD_CMDLINE_PARTS=y | |||
87 | CONFIG_MTD_BLOCK=y | 87 | CONFIG_MTD_BLOCK=y |
88 | CONFIG_MTD_ROM=y | 88 | CONFIG_MTD_ROM=y |
89 | CONFIG_MTD_COMPLEX_MAPPINGS=y | 89 | CONFIG_MTD_COMPLEX_MAPPINGS=y |
90 | CONFIG_MTD_NAND=y | 90 | CONFIG_MTD_RAW_NAND=y |
91 | CONFIG_MTD_NAND_SHARPSL=y | 91 | CONFIG_MTD_NAND_SHARPSL=y |
92 | CONFIG_BLK_DEV_LOOP=y | 92 | CONFIG_BLK_DEV_LOOP=y |
93 | CONFIG_BLK_DEV_SD=y | 93 | CONFIG_BLK_DEV_SD=y |
diff --git a/arch/arm/configs/davinci_all_defconfig b/arch/arm/configs/davinci_all_defconfig index 207962a656a2..4a8cad4d3707 100644 --- a/arch/arm/configs/davinci_all_defconfig +++ b/arch/arm/configs/davinci_all_defconfig | |||
@@ -74,7 +74,7 @@ CONFIG_MTD_CFI_INTELEXT=m | |||
74 | CONFIG_MTD_CFI_AMDSTD=m | 74 | CONFIG_MTD_CFI_AMDSTD=m |
75 | CONFIG_MTD_PHYSMAP=m | 75 | CONFIG_MTD_PHYSMAP=m |
76 | CONFIG_MTD_M25P80=m | 76 | CONFIG_MTD_M25P80=m |
77 | CONFIG_MTD_NAND=m | 77 | CONFIG_MTD_RAW_NAND=m |
78 | CONFIG_MTD_NAND_DAVINCI=m | 78 | CONFIG_MTD_NAND_DAVINCI=m |
79 | CONFIG_MTD_SPI_NOR=m | 79 | CONFIG_MTD_SPI_NOR=m |
80 | CONFIG_MTD_UBI=m | 80 | CONFIG_MTD_UBI=m |
diff --git a/arch/arm/configs/em_x270_defconfig b/arch/arm/configs/em_x270_defconfig index 30a67523f860..61228a25ba8d 100644 --- a/arch/arm/configs/em_x270_defconfig +++ b/arch/arm/configs/em_x270_defconfig | |||
@@ -54,7 +54,7 @@ CONFIG_MTD_CFI_AMDSTD=y | |||
54 | CONFIG_MTD_CFI_STAA=y | 54 | CONFIG_MTD_CFI_STAA=y |
55 | CONFIG_MTD_PHYSMAP=y | 55 | CONFIG_MTD_PHYSMAP=y |
56 | CONFIG_MTD_PXA2XX=y | 56 | CONFIG_MTD_PXA2XX=y |
57 | CONFIG_MTD_NAND=y | 57 | CONFIG_MTD_RAW_NAND=y |
58 | CONFIG_MTD_NAND_PLATFORM=y | 58 | CONFIG_MTD_NAND_PLATFORM=y |
59 | CONFIG_BLK_DEV_LOOP=y | 59 | CONFIG_BLK_DEV_LOOP=y |
60 | CONFIG_BLK_DEV_RAM=y | 60 | CONFIG_BLK_DEV_RAM=y |
diff --git a/arch/arm/configs/ep93xx_defconfig b/arch/arm/configs/ep93xx_defconfig index 78cd73d1c795..14889a785f07 100644 --- a/arch/arm/configs/ep93xx_defconfig +++ b/arch/arm/configs/ep93xx_defconfig | |||
@@ -63,7 +63,7 @@ CONFIG_MTD_CFI_AMDSTD=y | |||
63 | CONFIG_MTD_CFI_STAA=y | 63 | CONFIG_MTD_CFI_STAA=y |
64 | CONFIG_MTD_ROM=y | 64 | CONFIG_MTD_ROM=y |
65 | CONFIG_MTD_PHYSMAP=y | 65 | CONFIG_MTD_PHYSMAP=y |
66 | CONFIG_MTD_NAND=y | 66 | CONFIG_MTD_RAW_NAND=y |
67 | CONFIG_BLK_DEV_NBD=y | 67 | CONFIG_BLK_DEV_NBD=y |
68 | CONFIG_EEPROM_LEGACY=y | 68 | CONFIG_EEPROM_LEGACY=y |
69 | CONFIG_SCSI=y | 69 | CONFIG_SCSI=y |
diff --git a/arch/arm/configs/eseries_pxa_defconfig b/arch/arm/configs/eseries_pxa_defconfig index eabb784cf7da..b85575867d21 100644 --- a/arch/arm/configs/eseries_pxa_defconfig +++ b/arch/arm/configs/eseries_pxa_defconfig | |||
@@ -43,7 +43,7 @@ CONFIG_MAC80211_RC_PID=y | |||
43 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 43 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
44 | # CONFIG_STANDALONE is not set | 44 | # CONFIG_STANDALONE is not set |
45 | CONFIG_MTD=m | 45 | CONFIG_MTD=m |
46 | CONFIG_MTD_NAND=m | 46 | CONFIG_MTD_RAW_NAND=m |
47 | CONFIG_MTD_NAND_TMIO=m | 47 | CONFIG_MTD_NAND_TMIO=m |
48 | CONFIG_BLK_DEV_LOOP=m | 48 | CONFIG_BLK_DEV_LOOP=m |
49 | # CONFIG_SCSI_PROC_FS is not set | 49 | # CONFIG_SCSI_PROC_FS is not set |
diff --git a/arch/arm/configs/imx_v4_v5_defconfig b/arch/arm/configs/imx_v4_v5_defconfig index b37f8e675e40..f2cf0722e8e1 100644 --- a/arch/arm/configs/imx_v4_v5_defconfig +++ b/arch/arm/configs/imx_v4_v5_defconfig | |||
@@ -61,7 +61,7 @@ CONFIG_MTD_CFI_GEOMETRY=y | |||
61 | # CONFIG_MTD_CFI_I2 is not set | 61 | # CONFIG_MTD_CFI_I2 is not set |
62 | CONFIG_MTD_CFI_INTELEXT=y | 62 | CONFIG_MTD_CFI_INTELEXT=y |
63 | CONFIG_MTD_PHYSMAP=y | 63 | CONFIG_MTD_PHYSMAP=y |
64 | CONFIG_MTD_NAND=y | 64 | CONFIG_MTD_RAW_NAND=y |
65 | CONFIG_MTD_NAND_MXC=y | 65 | CONFIG_MTD_NAND_MXC=y |
66 | CONFIG_MTD_UBI=y | 66 | CONFIG_MTD_UBI=y |
67 | CONFIG_EEPROM_AT24=y | 67 | CONFIG_EEPROM_AT24=y |
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index 50fb01d70b10..8116648a8efd 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig | |||
@@ -110,7 +110,7 @@ CONFIG_MTD_PHYSMAP_OF=y | |||
110 | CONFIG_MTD_DATAFLASH=y | 110 | CONFIG_MTD_DATAFLASH=y |
111 | CONFIG_MTD_M25P80=y | 111 | CONFIG_MTD_M25P80=y |
112 | CONFIG_MTD_SST25L=y | 112 | CONFIG_MTD_SST25L=y |
113 | CONFIG_MTD_NAND=y | 113 | CONFIG_MTD_RAW_NAND=y |
114 | CONFIG_MTD_NAND_GPMI_NAND=y | 114 | CONFIG_MTD_NAND_GPMI_NAND=y |
115 | CONFIG_MTD_NAND_VF610_NFC=y | 115 | CONFIG_MTD_NAND_VF610_NFC=y |
116 | CONFIG_MTD_NAND_MXC=y | 116 | CONFIG_MTD_NAND_MXC=y |
diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig index 8c3c99cd6de9..39ebcce3bc2f 100644 --- a/arch/arm/configs/ixp4xx_defconfig +++ b/arch/arm/configs/ixp4xx_defconfig | |||
@@ -112,7 +112,7 @@ CONFIG_MTD_CFI=y | |||
112 | CONFIG_MTD_CFI_INTELEXT=y | 112 | CONFIG_MTD_CFI_INTELEXT=y |
113 | CONFIG_MTD_COMPLEX_MAPPINGS=y | 113 | CONFIG_MTD_COMPLEX_MAPPINGS=y |
114 | CONFIG_MTD_IXP4XX=y | 114 | CONFIG_MTD_IXP4XX=y |
115 | CONFIG_MTD_NAND=m | 115 | CONFIG_MTD_RAW_NAND=m |
116 | CONFIG_BLK_DEV_LOOP=y | 116 | CONFIG_BLK_DEV_LOOP=y |
117 | CONFIG_BLK_DEV_RAM=y | 117 | CONFIG_BLK_DEV_RAM=y |
118 | CONFIG_BLK_DEV_RAM_SIZE=8192 | 118 | CONFIG_BLK_DEV_RAM_SIZE=8192 |
diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig index 3ded35a07f45..72fee57aad2f 100644 --- a/arch/arm/configs/keystone_defconfig +++ b/arch/arm/configs/keystone_defconfig | |||
@@ -124,7 +124,7 @@ CONFIG_MTD_CMDLINE_PARTS=y | |||
124 | CONFIG_MTD_BLOCK=y | 124 | CONFIG_MTD_BLOCK=y |
125 | CONFIG_MTD_PLATRAM=y | 125 | CONFIG_MTD_PLATRAM=y |
126 | CONFIG_MTD_M25P80=y | 126 | CONFIG_MTD_M25P80=y |
127 | CONFIG_MTD_NAND=y | 127 | CONFIG_MTD_RAW_NAND=y |
128 | CONFIG_MTD_NAND_DAVINCI=y | 128 | CONFIG_MTD_NAND_DAVINCI=y |
129 | CONFIG_MTD_SPI_NOR=y | 129 | CONFIG_MTD_SPI_NOR=y |
130 | CONFIG_MTD_UBI=y | 130 | CONFIG_MTD_UBI=y |
diff --git a/arch/arm/configs/lpc32xx_defconfig b/arch/arm/configs/lpc32xx_defconfig index e752fb704df0..4b3b2c693c29 100644 --- a/arch/arm/configs/lpc32xx_defconfig +++ b/arch/arm/configs/lpc32xx_defconfig | |||
@@ -47,7 +47,7 @@ CONFIG_DEVTMPFS_MOUNT=y | |||
47 | CONFIG_MTD=y | 47 | CONFIG_MTD=y |
48 | CONFIG_MTD_CMDLINE_PARTS=y | 48 | CONFIG_MTD_CMDLINE_PARTS=y |
49 | CONFIG_MTD_BLOCK=y | 49 | CONFIG_MTD_BLOCK=y |
50 | CONFIG_MTD_NAND=y | 50 | CONFIG_MTD_RAW_NAND=y |
51 | CONFIG_MTD_NAND_SLC_LPC32XX=y | 51 | CONFIG_MTD_NAND_SLC_LPC32XX=y |
52 | CONFIG_MTD_NAND_MLC_LPC32XX=y | 52 | CONFIG_MTD_NAND_MLC_LPC32XX=y |
53 | CONFIG_MTD_UBI=y | 53 | CONFIG_MTD_UBI=y |
diff --git a/arch/arm/configs/mini2440_defconfig b/arch/arm/configs/mini2440_defconfig index d95a8059d30b..8b0f7c4c3f09 100644 --- a/arch/arm/configs/mini2440_defconfig +++ b/arch/arm/configs/mini2440_defconfig | |||
@@ -92,7 +92,7 @@ CONFIG_MTD_CFI_AMDSTD=y | |||
92 | CONFIG_MTD_CFI_STAA=y | 92 | CONFIG_MTD_CFI_STAA=y |
93 | CONFIG_MTD_RAM=y | 93 | CONFIG_MTD_RAM=y |
94 | CONFIG_MTD_ROM=y | 94 | CONFIG_MTD_ROM=y |
95 | CONFIG_MTD_NAND=y | 95 | CONFIG_MTD_RAW_NAND=y |
96 | CONFIG_MTD_NAND_S3C2410=y | 96 | CONFIG_MTD_NAND_S3C2410=y |
97 | CONFIG_MTD_NAND_PLATFORM=y | 97 | CONFIG_MTD_NAND_PLATFORM=y |
98 | CONFIG_MTD_LPDDR=y | 98 | CONFIG_MTD_LPDDR=y |
diff --git a/arch/arm/configs/mmp2_defconfig b/arch/arm/configs/mmp2_defconfig index 1eeee7f11d91..94deb0ed0541 100644 --- a/arch/arm/configs/mmp2_defconfig +++ b/arch/arm/configs/mmp2_defconfig | |||
@@ -28,7 +28,7 @@ CONFIG_IP_PNP=y | |||
28 | CONFIG_MTD=y | 28 | CONFIG_MTD=y |
29 | CONFIG_MTD_CMDLINE_PARTS=y | 29 | CONFIG_MTD_CMDLINE_PARTS=y |
30 | CONFIG_MTD_BLOCK=y | 30 | CONFIG_MTD_BLOCK=y |
31 | CONFIG_MTD_NAND=y | 31 | CONFIG_MTD_RAW_NAND=y |
32 | CONFIG_MTD_ONENAND=y | 32 | CONFIG_MTD_ONENAND=y |
33 | CONFIG_MTD_ONENAND_GENERIC=y | 33 | CONFIG_MTD_ONENAND_GENERIC=y |
34 | # CONFIG_BLK_DEV is not set | 34 | # CONFIG_BLK_DEV is not set |
diff --git a/arch/arm/configs/multi_v4t_defconfig b/arch/arm/configs/multi_v4t_defconfig index eeea0c41138b..0b42bddfbc82 100644 --- a/arch/arm/configs/multi_v4t_defconfig +++ b/arch/arm/configs/multi_v4t_defconfig | |||
@@ -38,7 +38,7 @@ CONFIG_MTD_CFI_INTELEXT=y | |||
38 | CONFIG_MTD_CFI_AMDSTD=y | 38 | CONFIG_MTD_CFI_AMDSTD=y |
39 | CONFIG_MTD_CFI_STAA=y | 39 | CONFIG_MTD_CFI_STAA=y |
40 | CONFIG_MTD_PLATRAM=y | 40 | CONFIG_MTD_PLATRAM=y |
41 | CONFIG_MTD_NAND=y | 41 | CONFIG_MTD_RAW_NAND=y |
42 | CONFIG_MTD_NAND_GPIO=y | 42 | CONFIG_MTD_NAND_GPIO=y |
43 | # CONFIG_INPUT is not set | 43 | # CONFIG_INPUT is not set |
44 | # CONFIG_SERIO is not set | 44 | # CONFIG_SERIO is not set |
diff --git a/arch/arm/configs/multi_v5_defconfig b/arch/arm/configs/multi_v5_defconfig index 318b76fa26d1..63b5a8824f0f 100644 --- a/arch/arm/configs/multi_v5_defconfig +++ b/arch/arm/configs/multi_v5_defconfig | |||
@@ -87,7 +87,7 @@ CONFIG_MTD_CFI_GEOMETRY=y | |||
87 | CONFIG_MTD_CFI_INTELEXT=y | 87 | CONFIG_MTD_CFI_INTELEXT=y |
88 | CONFIG_MTD_CFI_STAA=y | 88 | CONFIG_MTD_CFI_STAA=y |
89 | CONFIG_MTD_PHYSMAP=y | 89 | CONFIG_MTD_PHYSMAP=y |
90 | CONFIG_MTD_NAND=y | 90 | CONFIG_MTD_RAW_NAND=y |
91 | CONFIG_MTD_NAND_ATMEL=y | 91 | CONFIG_MTD_NAND_ATMEL=y |
92 | CONFIG_MTD_NAND_ORION=y | 92 | CONFIG_MTD_NAND_ORION=y |
93 | CONFIG_MTD_SPI_NOR=y | 93 | CONFIG_MTD_SPI_NOR=y |
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index c75051b9392c..b7b1cd00a294 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig | |||
@@ -184,7 +184,7 @@ CONFIG_MTD=y | |||
184 | CONFIG_MTD_CMDLINE_PARTS=y | 184 | CONFIG_MTD_CMDLINE_PARTS=y |
185 | CONFIG_MTD_BLOCK=y | 185 | CONFIG_MTD_BLOCK=y |
186 | CONFIG_MTD_M25P80=y | 186 | CONFIG_MTD_M25P80=y |
187 | CONFIG_MTD_NAND=y | 187 | CONFIG_MTD_RAW_NAND=y |
188 | CONFIG_MTD_NAND_DENALI_DT=y | 188 | CONFIG_MTD_NAND_DENALI_DT=y |
189 | CONFIG_MTD_NAND_OMAP2=y | 189 | CONFIG_MTD_NAND_OMAP2=y |
190 | CONFIG_MTD_NAND_OMAP_BCH=y | 190 | CONFIG_MTD_NAND_OMAP_BCH=y |
diff --git a/arch/arm/configs/mv78xx0_defconfig b/arch/arm/configs/mv78xx0_defconfig index 0448bd8075ac..e9567513f068 100644 --- a/arch/arm/configs/mv78xx0_defconfig +++ b/arch/arm/configs/mv78xx0_defconfig | |||
@@ -47,7 +47,7 @@ CONFIG_MTD_CFI_GEOMETRY=y | |||
47 | CONFIG_MTD_CFI_INTELEXT=y | 47 | CONFIG_MTD_CFI_INTELEXT=y |
48 | CONFIG_MTD_CFI_AMDSTD=y | 48 | CONFIG_MTD_CFI_AMDSTD=y |
49 | CONFIG_MTD_PHYSMAP=y | 49 | CONFIG_MTD_PHYSMAP=y |
50 | CONFIG_MTD_NAND=y | 50 | CONFIG_MTD_RAW_NAND=y |
51 | CONFIG_MTD_NAND_ORION=y | 51 | CONFIG_MTD_NAND_ORION=y |
52 | CONFIG_BLK_DEV_LOOP=y | 52 | CONFIG_BLK_DEV_LOOP=y |
53 | # CONFIG_SCSI_PROC_FS is not set | 53 | # CONFIG_SCSI_PROC_FS is not set |
diff --git a/arch/arm/configs/mvebu_v5_defconfig b/arch/arm/configs/mvebu_v5_defconfig index 4b598da0d086..0e5577a31851 100644 --- a/arch/arm/configs/mvebu_v5_defconfig +++ b/arch/arm/configs/mvebu_v5_defconfig | |||
@@ -77,7 +77,7 @@ CONFIG_MTD_CFI_INTELEXT=y | |||
77 | CONFIG_MTD_CFI_STAA=y | 77 | CONFIG_MTD_CFI_STAA=y |
78 | CONFIG_MTD_PHYSMAP=y | 78 | CONFIG_MTD_PHYSMAP=y |
79 | CONFIG_MTD_M25P80=y | 79 | CONFIG_MTD_M25P80=y |
80 | CONFIG_MTD_NAND=y | 80 | CONFIG_MTD_RAW_NAND=y |
81 | CONFIG_MTD_NAND_ORION=y | 81 | CONFIG_MTD_NAND_ORION=y |
82 | CONFIG_MTD_SPI_NOR=y | 82 | CONFIG_MTD_SPI_NOR=y |
83 | CONFIG_BLK_DEV_LOOP=y | 83 | CONFIG_BLK_DEV_LOOP=y |
diff --git a/arch/arm/configs/mvebu_v7_defconfig b/arch/arm/configs/mvebu_v7_defconfig index 55140219ab11..48f7b4277b8d 100644 --- a/arch/arm/configs/mvebu_v7_defconfig +++ b/arch/arm/configs/mvebu_v7_defconfig | |||
@@ -52,7 +52,7 @@ CONFIG_MTD_CFI_AMDSTD=y | |||
52 | CONFIG_MTD_CFI_STAA=y | 52 | CONFIG_MTD_CFI_STAA=y |
53 | CONFIG_MTD_PHYSMAP_OF=y | 53 | CONFIG_MTD_PHYSMAP_OF=y |
54 | CONFIG_MTD_M25P80=y | 54 | CONFIG_MTD_M25P80=y |
55 | CONFIG_MTD_NAND=y | 55 | CONFIG_MTD_RAW_NAND=y |
56 | CONFIG_MTD_NAND_MARVELL=y | 56 | CONFIG_MTD_NAND_MARVELL=y |
57 | CONFIG_MTD_SPI_NOR=y | 57 | CONFIG_MTD_SPI_NOR=y |
58 | CONFIG_MTD_UBI=y | 58 | CONFIG_MTD_UBI=y |
diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig index 38480596c449..ed570a0d1f2a 100644 --- a/arch/arm/configs/mxs_defconfig +++ b/arch/arm/configs/mxs_defconfig | |||
@@ -50,7 +50,7 @@ CONFIG_MTD_BLOCK=y | |||
50 | CONFIG_MTD_DATAFLASH=y | 50 | CONFIG_MTD_DATAFLASH=y |
51 | CONFIG_MTD_M25P80=y | 51 | CONFIG_MTD_M25P80=y |
52 | CONFIG_MTD_SST25L=y | 52 | CONFIG_MTD_SST25L=y |
53 | CONFIG_MTD_NAND=y | 53 | CONFIG_MTD_RAW_NAND=y |
54 | CONFIG_MTD_NAND_GPMI_NAND=y | 54 | CONFIG_MTD_NAND_GPMI_NAND=y |
55 | CONFIG_MTD_SPI_NOR=y | 55 | CONFIG_MTD_SPI_NOR=y |
56 | CONFIG_MTD_UBI=y | 56 | CONFIG_MTD_UBI=y |
diff --git a/arch/arm/configs/nhk8815_defconfig b/arch/arm/configs/nhk8815_defconfig index 5f4c6aaa07f6..cfc094189d09 100644 --- a/arch/arm/configs/nhk8815_defconfig +++ b/arch/arm/configs/nhk8815_defconfig | |||
@@ -53,8 +53,8 @@ CONFIG_MTD_BLOCK=y | |||
53 | CONFIG_MTD_ONENAND=y | 53 | CONFIG_MTD_ONENAND=y |
54 | CONFIG_MTD_ONENAND_VERIFY_WRITE=y | 54 | CONFIG_MTD_ONENAND_VERIFY_WRITE=y |
55 | CONFIG_MTD_ONENAND_GENERIC=y | 55 | CONFIG_MTD_ONENAND_GENERIC=y |
56 | CONFIG_MTD_NAND_ECC_SMC=y | 56 | CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC=y |
57 | CONFIG_MTD_NAND=y | 57 | CONFIG_MTD_RAW_NAND=y |
58 | CONFIG_MTD_NAND_FSMC=y | 58 | CONFIG_MTD_NAND_FSMC=y |
59 | CONFIG_BLK_DEV_LOOP=y | 59 | CONFIG_BLK_DEV_LOOP=y |
60 | CONFIG_BLK_DEV_CRYPTOLOOP=y | 60 | CONFIG_BLK_DEV_CRYPTOLOOP=y |
diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig index 8448a7f407a4..82af77c093f1 100644 --- a/arch/arm/configs/omap1_defconfig +++ b/arch/arm/configs/omap1_defconfig | |||
@@ -89,7 +89,7 @@ CONFIG_MTD_CMDLINE_PARTS=y | |||
89 | CONFIG_MTD_BLOCK=y | 89 | CONFIG_MTD_BLOCK=y |
90 | CONFIG_MTD_CFI=y | 90 | CONFIG_MTD_CFI=y |
91 | CONFIG_MTD_CFI_INTELEXT=y | 91 | CONFIG_MTD_CFI_INTELEXT=y |
92 | CONFIG_MTD_NAND=y | 92 | CONFIG_MTD_RAW_NAND=y |
93 | CONFIG_BLK_DEV_LOOP=y | 93 | CONFIG_BLK_DEV_LOOP=y |
94 | CONFIG_BLK_DEV_RAM=y | 94 | CONFIG_BLK_DEV_RAM=y |
95 | CONFIG_BLK_DEV_RAM_COUNT=2 | 95 | CONFIG_BLK_DEV_RAM_COUNT=2 |
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index 3f03ec6d2644..c7bf9c493646 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig | |||
@@ -143,8 +143,8 @@ CONFIG_MTD_M25P80=m | |||
143 | CONFIG_MTD_ONENAND=y | 143 | CONFIG_MTD_ONENAND=y |
144 | CONFIG_MTD_ONENAND_VERIFY_WRITE=y | 144 | CONFIG_MTD_ONENAND_VERIFY_WRITE=y |
145 | CONFIG_MTD_ONENAND_OMAP2=y | 145 | CONFIG_MTD_ONENAND_OMAP2=y |
146 | CONFIG_MTD_NAND=y | 146 | CONFIG_MTD_RAW_NAND=y |
147 | CONFIG_MTD_NAND_ECC_BCH=y | 147 | CONFIG_MTD_NAND_ECC_SW_BCH=y |
148 | CONFIG_MTD_NAND_OMAP2=y | 148 | CONFIG_MTD_NAND_OMAP2=y |
149 | CONFIG_MTD_NAND_OMAP_BCH=y | 149 | CONFIG_MTD_NAND_OMAP_BCH=y |
150 | CONFIG_MTD_SPI_NOR=m | 150 | CONFIG_MTD_SPI_NOR=m |
diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig index bf9046331f6e..077e0fde1ff9 100644 --- a/arch/arm/configs/orion5x_defconfig +++ b/arch/arm/configs/orion5x_defconfig | |||
@@ -70,7 +70,7 @@ CONFIG_MTD_CFI_GEOMETRY=y | |||
70 | CONFIG_MTD_CFI_INTELEXT=y | 70 | CONFIG_MTD_CFI_INTELEXT=y |
71 | CONFIG_MTD_CFI_AMDSTD=y | 71 | CONFIG_MTD_CFI_AMDSTD=y |
72 | CONFIG_MTD_PHYSMAP=y | 72 | CONFIG_MTD_PHYSMAP=y |
73 | CONFIG_MTD_NAND=y | 73 | CONFIG_MTD_RAW_NAND=y |
74 | CONFIG_MTD_NAND_PLATFORM=y | 74 | CONFIG_MTD_NAND_PLATFORM=y |
75 | CONFIG_MTD_NAND_ORION=y | 75 | CONFIG_MTD_NAND_ORION=y |
76 | CONFIG_BLK_DEV_LOOP=y | 76 | CONFIG_BLK_DEV_LOOP=y |
diff --git a/arch/arm/configs/oxnas_v6_defconfig b/arch/arm/configs/oxnas_v6_defconfig index f6ba32c9d173..cae0db6b4eaf 100644 --- a/arch/arm/configs/oxnas_v6_defconfig +++ b/arch/arm/configs/oxnas_v6_defconfig | |||
@@ -50,7 +50,7 @@ CONFIG_SIMPLE_PM_BUS=y | |||
50 | CONFIG_MTD=y | 50 | CONFIG_MTD=y |
51 | CONFIG_MTD_CMDLINE_PARTS=y | 51 | CONFIG_MTD_CMDLINE_PARTS=y |
52 | CONFIG_MTD_BLOCK=y | 52 | CONFIG_MTD_BLOCK=y |
53 | CONFIG_MTD_NAND=y | 53 | CONFIG_MTD_RAW_NAND=y |
54 | CONFIG_MTD_NAND_OXNAS=y | 54 | CONFIG_MTD_NAND_OXNAS=y |
55 | CONFIG_MTD_UBI=y | 55 | CONFIG_MTD_UBI=y |
56 | CONFIG_BLK_DEV_LOOP=y | 56 | CONFIG_BLK_DEV_LOOP=y |
diff --git a/arch/arm/configs/pxa3xx_defconfig b/arch/arm/configs/pxa3xx_defconfig index 3e0de035ab77..7681eea60127 100644 --- a/arch/arm/configs/pxa3xx_defconfig +++ b/arch/arm/configs/pxa3xx_defconfig | |||
@@ -31,7 +31,7 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | |||
31 | # CONFIG_PREVENT_FIRMWARE_BUILD is not set | 31 | # CONFIG_PREVENT_FIRMWARE_BUILD is not set |
32 | CONFIG_MTD=y | 32 | CONFIG_MTD=y |
33 | CONFIG_MTD_BLOCK=y | 33 | CONFIG_MTD_BLOCK=y |
34 | CONFIG_MTD_NAND=y | 34 | CONFIG_MTD_RAW_NAND=y |
35 | CONFIG_MTD_NAND_MARVELL=y | 35 | CONFIG_MTD_NAND_MARVELL=y |
36 | CONFIG_MTD_ONENAND=y | 36 | CONFIG_MTD_ONENAND=y |
37 | CONFIG_MTD_ONENAND_VERIFY_WRITE=y | 37 | CONFIG_MTD_ONENAND_VERIFY_WRITE=y |
diff --git a/arch/arm/configs/pxa_defconfig b/arch/arm/configs/pxa_defconfig index d4654755b09c..f6d24d762a7f 100644 --- a/arch/arm/configs/pxa_defconfig +++ b/arch/arm/configs/pxa_defconfig | |||
@@ -185,8 +185,8 @@ CONFIG_MTD_PXA2XX=m | |||
185 | CONFIG_MTD_M25P80=m | 185 | CONFIG_MTD_M25P80=m |
186 | CONFIG_MTD_BLOCK2MTD=y | 186 | CONFIG_MTD_BLOCK2MTD=y |
187 | CONFIG_MTD_DOCG3=m | 187 | CONFIG_MTD_DOCG3=m |
188 | CONFIG_MTD_NAND=m | 188 | CONFIG_MTD_RAW_NAND=m |
189 | CONFIG_MTD_NAND_ECC_BCH=y | 189 | CONFIG_MTD_NAND_ECC_SW_BCH=y |
190 | CONFIG_MTD_NAND_GPIO=m | 190 | CONFIG_MTD_NAND_GPIO=m |
191 | CONFIG_MTD_NAND_DISKONCHIP=m | 191 | CONFIG_MTD_NAND_DISKONCHIP=m |
192 | CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y | 192 | CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y |
diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig index bd6440f23493..4c50b5337cf6 100644 --- a/arch/arm/configs/qcom_defconfig +++ b/arch/arm/configs/qcom_defconfig | |||
@@ -57,7 +57,7 @@ CONFIG_DEVTMPFS_MOUNT=y | |||
57 | CONFIG_MTD=y | 57 | CONFIG_MTD=y |
58 | CONFIG_MTD_BLOCK=y | 58 | CONFIG_MTD_BLOCK=y |
59 | CONFIG_MTD_M25P80=y | 59 | CONFIG_MTD_M25P80=y |
60 | CONFIG_MTD_NAND=y | 60 | CONFIG_MTD_RAW_NAND=y |
61 | CONFIG_MTD_NAND_QCOM=y | 61 | CONFIG_MTD_NAND_QCOM=y |
62 | CONFIG_MTD_SPI_NOR=y | 62 | CONFIG_MTD_SPI_NOR=y |
63 | CONFIG_BLK_DEV_LOOP=y | 63 | CONFIG_BLK_DEV_LOOP=y |
diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig index 2afb359f3168..39c648594d93 100644 --- a/arch/arm/configs/s3c2410_defconfig +++ b/arch/arm/configs/s3c2410_defconfig | |||
@@ -192,7 +192,7 @@ CONFIG_MTD_JEDECPROBE=y | |||
192 | CONFIG_MTD_CFI_INTELEXT=y | 192 | CONFIG_MTD_CFI_INTELEXT=y |
193 | CONFIG_MTD_CFI_AMDSTD=y | 193 | CONFIG_MTD_CFI_AMDSTD=y |
194 | CONFIG_MTD_ROM=y | 194 | CONFIG_MTD_ROM=y |
195 | CONFIG_MTD_NAND=y | 195 | CONFIG_MTD_RAW_NAND=y |
196 | CONFIG_MTD_NAND_S3C2410=y | 196 | CONFIG_MTD_NAND_S3C2410=y |
197 | CONFIG_PARPORT=y | 197 | CONFIG_PARPORT=y |
198 | CONFIG_PARPORT_PC=m | 198 | CONFIG_PARPORT_PC=m |
diff --git a/arch/arm/configs/s3c6400_defconfig b/arch/arm/configs/s3c6400_defconfig index 507d7ad7523a..6e2656567da6 100644 --- a/arch/arm/configs/s3c6400_defconfig +++ b/arch/arm/configs/s3c6400_defconfig | |||
@@ -23,7 +23,7 @@ CONFIG_CMDLINE="console=ttySAC0,115200 root=/dev/ram init=/linuxrc initrd=0x5100 | |||
23 | CONFIG_VFP=y | 23 | CONFIG_VFP=y |
24 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 24 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
25 | CONFIG_MTD=y | 25 | CONFIG_MTD=y |
26 | CONFIG_MTD_NAND=y | 26 | CONFIG_MTD_RAW_NAND=y |
27 | CONFIG_MTD_NAND_S3C2410=y | 27 | CONFIG_MTD_NAND_S3C2410=y |
28 | CONFIG_BLK_DEV_LOOP=y | 28 | CONFIG_BLK_DEV_LOOP=y |
29 | CONFIG_BLK_DEV_RAM=y | 29 | CONFIG_BLK_DEV_RAM=y |
diff --git a/arch/arm/configs/sama5_defconfig b/arch/arm/configs/sama5_defconfig index b0026f73083d..515cb37eeab6 100644 --- a/arch/arm/configs/sama5_defconfig +++ b/arch/arm/configs/sama5_defconfig | |||
@@ -66,7 +66,7 @@ CONFIG_MTD_CMDLINE_PARTS=y | |||
66 | CONFIG_MTD_BLOCK=y | 66 | CONFIG_MTD_BLOCK=y |
67 | CONFIG_MTD_CFI=y | 67 | CONFIG_MTD_CFI=y |
68 | CONFIG_MTD_M25P80=y | 68 | CONFIG_MTD_M25P80=y |
69 | CONFIG_MTD_NAND=y | 69 | CONFIG_MTD_RAW_NAND=y |
70 | CONFIG_MTD_NAND_ATMEL=y | 70 | CONFIG_MTD_NAND_ATMEL=y |
71 | CONFIG_MTD_SPI_NOR=y | 71 | CONFIG_MTD_SPI_NOR=y |
72 | CONFIG_MTD_UBI=y | 72 | CONFIG_MTD_UBI=y |
diff --git a/arch/arm/configs/socfpga_defconfig b/arch/arm/configs/socfpga_defconfig index 08d1b3e11d68..3b42e0d597bd 100644 --- a/arch/arm/configs/socfpga_defconfig +++ b/arch/arm/configs/socfpga_defconfig | |||
@@ -51,7 +51,7 @@ CONFIG_DEVTMPFS_MOUNT=y | |||
51 | CONFIG_MTD=y | 51 | CONFIG_MTD=y |
52 | CONFIG_MTD_BLOCK=y | 52 | CONFIG_MTD_BLOCK=y |
53 | CONFIG_MTD_M25P80=y | 53 | CONFIG_MTD_M25P80=y |
54 | CONFIG_MTD_NAND=y | 54 | CONFIG_MTD_RAW_NAND=y |
55 | CONFIG_MTD_NAND_DENALI_DT=y | 55 | CONFIG_MTD_NAND_DENALI_DT=y |
56 | CONFIG_MTD_SPI_NOR=y | 56 | CONFIG_MTD_SPI_NOR=y |
57 | # CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set | 57 | # CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set |
diff --git a/arch/arm/configs/spear13xx_defconfig b/arch/arm/configs/spear13xx_defconfig index 7b36eeb928bb..8ee3679ca8b2 100644 --- a/arch/arm/configs/spear13xx_defconfig +++ b/arch/arm/configs/spear13xx_defconfig | |||
@@ -32,7 +32,7 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | |||
32 | CONFIG_MTD=y | 32 | CONFIG_MTD=y |
33 | CONFIG_MTD_OF_PARTS=y | 33 | CONFIG_MTD_OF_PARTS=y |
34 | CONFIG_MTD_BLOCK=y | 34 | CONFIG_MTD_BLOCK=y |
35 | CONFIG_MTD_NAND=y | 35 | CONFIG_MTD_RAW_NAND=y |
36 | CONFIG_MTD_NAND_FSMC=y | 36 | CONFIG_MTD_NAND_FSMC=y |
37 | CONFIG_BLK_DEV_RAM=y | 37 | CONFIG_BLK_DEV_RAM=y |
38 | CONFIG_BLK_DEV_RAM_SIZE=16384 | 38 | CONFIG_BLK_DEV_RAM_SIZE=16384 |
diff --git a/arch/arm/configs/spear3xx_defconfig b/arch/arm/configs/spear3xx_defconfig index f1b52fb3461b..ddd73b25f75e 100644 --- a/arch/arm/configs/spear3xx_defconfig +++ b/arch/arm/configs/spear3xx_defconfig | |||
@@ -17,7 +17,7 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | |||
17 | CONFIG_MTD=y | 17 | CONFIG_MTD=y |
18 | CONFIG_MTD_OF_PARTS=y | 18 | CONFIG_MTD_OF_PARTS=y |
19 | CONFIG_MTD_BLOCK=y | 19 | CONFIG_MTD_BLOCK=y |
20 | CONFIG_MTD_NAND=y | 20 | CONFIG_MTD_RAW_NAND=y |
21 | CONFIG_MTD_NAND_FSMC=y | 21 | CONFIG_MTD_NAND_FSMC=y |
22 | CONFIG_BLK_DEV_RAM=y | 22 | CONFIG_BLK_DEV_RAM=y |
23 | CONFIG_BLK_DEV_RAM_SIZE=16384 | 23 | CONFIG_BLK_DEV_RAM_SIZE=16384 |
diff --git a/arch/arm/configs/spear6xx_defconfig b/arch/arm/configs/spear6xx_defconfig index 124c244d8df1..5b410f0a365b 100644 --- a/arch/arm/configs/spear6xx_defconfig +++ b/arch/arm/configs/spear6xx_defconfig | |||
@@ -14,7 +14,7 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | |||
14 | CONFIG_MTD=y | 14 | CONFIG_MTD=y |
15 | CONFIG_MTD_OF_PARTS=y | 15 | CONFIG_MTD_OF_PARTS=y |
16 | CONFIG_MTD_BLOCK=y | 16 | CONFIG_MTD_BLOCK=y |
17 | CONFIG_MTD_NAND=y | 17 | CONFIG_MTD_RAW_NAND=y |
18 | CONFIG_MTD_NAND_FSMC=y | 18 | CONFIG_MTD_NAND_FSMC=y |
19 | CONFIG_BLK_DEV_RAM=y | 19 | CONFIG_BLK_DEV_RAM=y |
20 | CONFIG_BLK_DEV_RAM_SIZE=16384 | 20 | CONFIG_BLK_DEV_RAM_SIZE=16384 |
diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig index 9ea82c118661..f6d2f674517c 100644 --- a/arch/arm/configs/spitz_defconfig +++ b/arch/arm/configs/spitz_defconfig | |||
@@ -84,7 +84,7 @@ CONFIG_MTD_CMDLINE_PARTS=y | |||
84 | CONFIG_MTD_BLOCK=y | 84 | CONFIG_MTD_BLOCK=y |
85 | CONFIG_MTD_ROM=y | 85 | CONFIG_MTD_ROM=y |
86 | CONFIG_MTD_COMPLEX_MAPPINGS=y | 86 | CONFIG_MTD_COMPLEX_MAPPINGS=y |
87 | CONFIG_MTD_NAND=y | 87 | CONFIG_MTD_RAW_NAND=y |
88 | CONFIG_MTD_NAND_SHARPSL=y | 88 | CONFIG_MTD_NAND_SHARPSL=y |
89 | CONFIG_BLK_DEV_LOOP=y | 89 | CONFIG_BLK_DEV_LOOP=y |
90 | CONFIG_BLK_DEV_SD=y | 90 | CONFIG_BLK_DEV_SD=y |
diff --git a/arch/arm/configs/tango4_defconfig b/arch/arm/configs/tango4_defconfig index 68725d4eae45..68eb16e583ac 100644 --- a/arch/arm/configs/tango4_defconfig +++ b/arch/arm/configs/tango4_defconfig | |||
@@ -39,7 +39,7 @@ CONFIG_DEVTMPFS_MOUNT=y | |||
39 | CONFIG_MTD=y | 39 | CONFIG_MTD=y |
40 | CONFIG_MTD_TESTS=m | 40 | CONFIG_MTD_TESTS=m |
41 | CONFIG_MTD_CMDLINE_PARTS=y | 41 | CONFIG_MTD_CMDLINE_PARTS=y |
42 | CONFIG_MTD_NAND=y | 42 | CONFIG_MTD_RAW_NAND=y |
43 | CONFIG_MTD_NAND_TANGO=y | 43 | CONFIG_MTD_NAND_TANGO=y |
44 | CONFIG_BLK_DEV_LOOP=y | 44 | CONFIG_BLK_DEV_LOOP=y |
45 | CONFIG_SCSI=y | 45 | CONFIG_SCSI=y |
diff --git a/arch/arm/configs/trizeps4_defconfig b/arch/arm/configs/trizeps4_defconfig index 2b5a224d2da1..ecad22501b48 100644 --- a/arch/arm/configs/trizeps4_defconfig +++ b/arch/arm/configs/trizeps4_defconfig | |||
@@ -76,7 +76,7 @@ CONFIG_MTD_DOC2001PLUS=y | |||
76 | CONFIG_MTD_DOCPROBE_ADVANCED=y | 76 | CONFIG_MTD_DOCPROBE_ADVANCED=y |
77 | CONFIG_MTD_DOCPROBE_ADDRESS=0x4000000 | 77 | CONFIG_MTD_DOCPROBE_ADDRESS=0x4000000 |
78 | CONFIG_MTD_DOCPROBE_HIGH=y | 78 | CONFIG_MTD_DOCPROBE_HIGH=y |
79 | CONFIG_MTD_NAND=y | 79 | CONFIG_MTD_RAW_NAND=y |
80 | CONFIG_MTD_NAND_DISKONCHIP=y | 80 | CONFIG_MTD_NAND_DISKONCHIP=y |
81 | CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y | 81 | CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADVANCED=y |
82 | CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0x4000000 | 82 | CONFIG_MTD_NAND_DISKONCHIP_PROBE_ADDRESS=0x4000000 |
diff --git a/arch/arm/configs/u300_defconfig b/arch/arm/configs/u300_defconfig index 831ba6a9ee8b..bedf397c75de 100644 --- a/arch/arm/configs/u300_defconfig +++ b/arch/arm/configs/u300_defconfig | |||
@@ -26,7 +26,7 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | |||
26 | # CONFIG_PREVENT_FIRMWARE_BUILD is not set | 26 | # CONFIG_PREVENT_FIRMWARE_BUILD is not set |
27 | CONFIG_MTD=y | 27 | CONFIG_MTD=y |
28 | CONFIG_MTD_CMDLINE_PARTS=y | 28 | CONFIG_MTD_CMDLINE_PARTS=y |
29 | CONFIG_MTD_NAND=y | 29 | CONFIG_MTD_RAW_NAND=y |
30 | CONFIG_MTD_NAND_FSMC=y | 30 | CONFIG_MTD_NAND_FSMC=y |
31 | # CONFIG_INPUT_MOUSEDEV is not set | 31 | # CONFIG_INPUT_MOUSEDEV is not set |
32 | CONFIG_INPUT_EVDEV=y | 32 | CONFIG_INPUT_EVDEV=y |
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 2d9c39033c1a..9a8718bbf6ba 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig | |||
@@ -206,7 +206,7 @@ CONFIG_SIMPLE_PM_BUS=y | |||
206 | CONFIG_MTD=y | 206 | CONFIG_MTD=y |
207 | CONFIG_MTD_BLOCK=y | 207 | CONFIG_MTD_BLOCK=y |
208 | CONFIG_MTD_M25P80=y | 208 | CONFIG_MTD_M25P80=y |
209 | CONFIG_MTD_NAND=y | 209 | CONFIG_MTD_RAW_NAND=y |
210 | CONFIG_MTD_NAND_DENALI_DT=y | 210 | CONFIG_MTD_NAND_DENALI_DT=y |
211 | CONFIG_MTD_NAND_MARVELL=y | 211 | CONFIG_MTD_NAND_MARVELL=y |
212 | CONFIG_MTD_NAND_QCOM=y | 212 | CONFIG_MTD_NAND_QCOM=y |
diff --git a/arch/mips/configs/bcm47xx_defconfig b/arch/mips/configs/bcm47xx_defconfig index 249f5285e343..91ce75edbfb4 100644 --- a/arch/mips/configs/bcm47xx_defconfig +++ b/arch/mips/configs/bcm47xx_defconfig | |||
@@ -41,7 +41,7 @@ CONFIG_MTD_CFI_AMDSTD=y | |||
41 | CONFIG_MTD_COMPLEX_MAPPINGS=y | 41 | CONFIG_MTD_COMPLEX_MAPPINGS=y |
42 | CONFIG_MTD_PHYSMAP=y | 42 | CONFIG_MTD_PHYSMAP=y |
43 | CONFIG_MTD_BCM47XXSFLASH=y | 43 | CONFIG_MTD_BCM47XXSFLASH=y |
44 | CONFIG_MTD_NAND=y | 44 | CONFIG_MTD_RAW_NAND=y |
45 | CONFIG_MTD_NAND_BCM47XXNFLASH=y | 45 | CONFIG_MTD_NAND_BCM47XXNFLASH=y |
46 | CONFIG_NETDEVICES=y | 46 | CONFIG_NETDEVICES=y |
47 | CONFIG_B44=y | 47 | CONFIG_B44=y |
diff --git a/arch/mips/configs/ci20_defconfig b/arch/mips/configs/ci20_defconfig index 412800d5d7e0..50bebce28500 100644 --- a/arch/mips/configs/ci20_defconfig +++ b/arch/mips/configs/ci20_defconfig | |||
@@ -51,7 +51,7 @@ CONFIG_DEVTMPFS=y | |||
51 | CONFIG_DMA_CMA=y | 51 | CONFIG_DMA_CMA=y |
52 | CONFIG_CMA_SIZE_MBYTES=32 | 52 | CONFIG_CMA_SIZE_MBYTES=32 |
53 | CONFIG_MTD=y | 53 | CONFIG_MTD=y |
54 | CONFIG_MTD_NAND=y | 54 | CONFIG_MTD_RAW_NAND=y |
55 | CONFIG_MTD_NAND_JZ4780=y | 55 | CONFIG_MTD_NAND_JZ4780=y |
56 | CONFIG_MTD_UBI=y | 56 | CONFIG_MTD_UBI=y |
57 | CONFIG_MTD_UBI_FASTMAP=y | 57 | CONFIG_MTD_UBI_FASTMAP=y |
diff --git a/arch/mips/configs/db1xxx_defconfig b/arch/mips/configs/db1xxx_defconfig index 34633b7611cb..bc9b6ae046b2 100644 --- a/arch/mips/configs/db1xxx_defconfig +++ b/arch/mips/configs/db1xxx_defconfig | |||
@@ -95,8 +95,8 @@ CONFIG_MTD_CFI_AMDSTD=y | |||
95 | CONFIG_MTD_PHYSMAP=y | 95 | CONFIG_MTD_PHYSMAP=y |
96 | CONFIG_MTD_M25P80=y | 96 | CONFIG_MTD_M25P80=y |
97 | CONFIG_MTD_SST25L=y | 97 | CONFIG_MTD_SST25L=y |
98 | CONFIG_MTD_NAND=y | 98 | CONFIG_MTD_RAW_NAND=y |
99 | CONFIG_MTD_NAND_ECC_BCH=y | 99 | CONFIG_MTD_NAND_ECC_SW_BCH=y |
100 | CONFIG_MTD_NAND_AU1550=y | 100 | CONFIG_MTD_NAND_AU1550=y |
101 | CONFIG_MTD_NAND_PLATFORM=y | 101 | CONFIG_MTD_NAND_PLATFORM=y |
102 | CONFIG_MTD_SPI_NOR=y | 102 | CONFIG_MTD_SPI_NOR=y |
diff --git a/arch/mips/configs/generic/board-ni169445.config b/arch/mips/configs/generic/board-ni169445.config index f72223b366ca..1ed0d3e8715e 100644 --- a/arch/mips/configs/generic/board-ni169445.config +++ b/arch/mips/configs/generic/board-ni169445.config | |||
@@ -15,9 +15,9 @@ CONFIG_MTD=y | |||
15 | CONFIG_MTD_BLOCK=y | 15 | CONFIG_MTD_BLOCK=y |
16 | CONFIG_MTD_CMDLINE_PARTS=y | 16 | CONFIG_MTD_CMDLINE_PARTS=y |
17 | 17 | ||
18 | CONFIG_MTD_NAND_ECC=y | 18 | CONFIG_MTD_NAND_ECC_SW_HAMMING=y |
19 | CONFIG_MTD_NAND_ECC_BCH=y | 19 | CONFIG_MTD_NAND_ECC_SW_BCH=y |
20 | CONFIG_MTD_NAND=y | 20 | CONFIG_MTD_RAW_NAND=y |
21 | CONFIG_MTD_NAND_GPIO=y | 21 | CONFIG_MTD_NAND_GPIO=y |
22 | CONFIG_MTD_NAND_IDS=y | 22 | CONFIG_MTD_NAND_IDS=y |
23 | 23 | ||
diff --git a/arch/mips/configs/generic/board-ocelot.config b/arch/mips/configs/generic/board-ocelot.config index 184eb65a6ba7..1134fbb99fc2 100644 --- a/arch/mips/configs/generic/board-ocelot.config +++ b/arch/mips/configs/generic/board-ocelot.config | |||
@@ -10,7 +10,7 @@ CONFIG_MTD=y | |||
10 | CONFIG_MTD_CMDLINE_PARTS=y | 10 | CONFIG_MTD_CMDLINE_PARTS=y |
11 | CONFIG_MTD_BLOCK=y | 11 | CONFIG_MTD_BLOCK=y |
12 | CONFIG_MTD_M25P80=y | 12 | CONFIG_MTD_M25P80=y |
13 | CONFIG_MTD_NAND=y | 13 | CONFIG_MTD_RAW_NAND=y |
14 | CONFIG_MTD_NAND_PLATFORM=y | 14 | CONFIG_MTD_NAND_PLATFORM=y |
15 | CONFIG_MTD_SPI_NOR=y | 15 | CONFIG_MTD_SPI_NOR=y |
16 | CONFIG_MTD_UBI=y | 16 | CONFIG_MTD_UBI=y |
diff --git a/arch/mips/configs/loongson1b_defconfig b/arch/mips/configs/loongson1b_defconfig index aa7e98c5f5fc..3d390a7494d6 100644 --- a/arch/mips/configs/loongson1b_defconfig +++ b/arch/mips/configs/loongson1b_defconfig | |||
@@ -41,7 +41,7 @@ CONFIG_DEVTMPFS_MOUNT=y | |||
41 | CONFIG_MTD=y | 41 | CONFIG_MTD=y |
42 | CONFIG_MTD_CMDLINE_PARTS=y | 42 | CONFIG_MTD_CMDLINE_PARTS=y |
43 | CONFIG_MTD_BLOCK=y | 43 | CONFIG_MTD_BLOCK=y |
44 | CONFIG_MTD_NAND=y | 44 | CONFIG_MTD_RAW_NAND=y |
45 | CONFIG_MTD_UBI=y | 45 | CONFIG_MTD_UBI=y |
46 | CONFIG_BLK_DEV_LOOP=y | 46 | CONFIG_BLK_DEV_LOOP=y |
47 | CONFIG_SCSI=m | 47 | CONFIG_SCSI=m |
diff --git a/arch/mips/configs/loongson1c_defconfig b/arch/mips/configs/loongson1c_defconfig index 520e7ef35383..247d56e94c0a 100644 --- a/arch/mips/configs/loongson1c_defconfig +++ b/arch/mips/configs/loongson1c_defconfig | |||
@@ -42,7 +42,7 @@ CONFIG_DEVTMPFS_MOUNT=y | |||
42 | CONFIG_MTD=y | 42 | CONFIG_MTD=y |
43 | CONFIG_MTD_CMDLINE_PARTS=y | 43 | CONFIG_MTD_CMDLINE_PARTS=y |
44 | CONFIG_MTD_BLOCK=y | 44 | CONFIG_MTD_BLOCK=y |
45 | CONFIG_MTD_NAND=y | 45 | CONFIG_MTD_RAW_NAND=y |
46 | CONFIG_MTD_UBI=y | 46 | CONFIG_MTD_UBI=y |
47 | CONFIG_BLK_DEV_LOOP=y | 47 | CONFIG_BLK_DEV_LOOP=y |
48 | CONFIG_SCSI=m | 48 | CONFIG_SCSI=m |
diff --git a/arch/mips/configs/qi_lb60_defconfig b/arch/mips/configs/qi_lb60_defconfig index 7671fe6a8042..1a0677d04982 100644 --- a/arch/mips/configs/qi_lb60_defconfig +++ b/arch/mips/configs/qi_lb60_defconfig | |||
@@ -44,7 +44,7 @@ CONFIG_TCP_CONG_WESTWOOD=y | |||
44 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | 44 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" |
45 | CONFIG_MTD=y | 45 | CONFIG_MTD=y |
46 | CONFIG_MTD_BLOCK=y | 46 | CONFIG_MTD_BLOCK=y |
47 | CONFIG_MTD_NAND=y | 47 | CONFIG_MTD_RAW_NAND=y |
48 | CONFIG_MTD_NAND_JZ4740=y | 48 | CONFIG_MTD_NAND_JZ4740=y |
49 | CONFIG_MTD_UBI=y | 49 | CONFIG_MTD_UBI=y |
50 | CONFIG_NETDEVICES=y | 50 | CONFIG_NETDEVICES=y |
diff --git a/arch/mips/configs/rb532_defconfig b/arch/mips/configs/rb532_defconfig index ed1038f62a2c..50632a3103dd 100644 --- a/arch/mips/configs/rb532_defconfig +++ b/arch/mips/configs/rb532_defconfig | |||
@@ -109,7 +109,7 @@ CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | |||
109 | CONFIG_MTD=y | 109 | CONFIG_MTD=y |
110 | CONFIG_MTD_BLOCK=y | 110 | CONFIG_MTD_BLOCK=y |
111 | CONFIG_MTD_BLOCK2MTD=y | 111 | CONFIG_MTD_BLOCK2MTD=y |
112 | CONFIG_MTD_NAND=y | 112 | CONFIG_MTD_RAW_NAND=y |
113 | CONFIG_MTD_NAND_PLATFORM=y | 113 | CONFIG_MTD_NAND_PLATFORM=y |
114 | CONFIG_ATA=y | 114 | CONFIG_ATA=y |
115 | # CONFIG_ATA_VERBOSE_ERROR is not set | 115 | # CONFIG_ATA_VERBOSE_ERROR is not set |
diff --git a/arch/mips/configs/rbtx49xx_defconfig b/arch/mips/configs/rbtx49xx_defconfig index b0f0c5f9ad9d..5e389db35fa7 100644 --- a/arch/mips/configs/rbtx49xx_defconfig +++ b/arch/mips/configs/rbtx49xx_defconfig | |||
@@ -39,7 +39,7 @@ CONFIG_MTD_CFI_AMDSTD=y | |||
39 | CONFIG_MTD_COMPLEX_MAPPINGS=y | 39 | CONFIG_MTD_COMPLEX_MAPPINGS=y |
40 | CONFIG_MTD_PHYSMAP=y | 40 | CONFIG_MTD_PHYSMAP=y |
41 | CONFIG_MTD_RBTX4939=y | 41 | CONFIG_MTD_RBTX4939=y |
42 | CONFIG_MTD_NAND=m | 42 | CONFIG_MTD_RAW_NAND=m |
43 | CONFIG_MTD_NAND_TXX9NDFMC=m | 43 | CONFIG_MTD_NAND_TXX9NDFMC=m |
44 | CONFIG_BLK_DEV_LOOP=y | 44 | CONFIG_BLK_DEV_LOOP=y |
45 | CONFIG_BLK_DEV_RAM=y | 45 | CONFIG_BLK_DEV_RAM=y |
diff --git a/arch/mips/configs/xway_defconfig b/arch/mips/configs/xway_defconfig index 2bb02ea9fb4e..203db83c3ee9 100644 --- a/arch/mips/configs/xway_defconfig +++ b/arch/mips/configs/xway_defconfig | |||
@@ -81,7 +81,7 @@ CONFIG_MTD_COMPLEX_MAPPINGS=y | |||
81 | CONFIG_MTD_PHYSMAP=y | 81 | CONFIG_MTD_PHYSMAP=y |
82 | CONFIG_MTD_PHYSMAP_OF=y | 82 | CONFIG_MTD_PHYSMAP_OF=y |
83 | CONFIG_MTD_LANTIQ=y | 83 | CONFIG_MTD_LANTIQ=y |
84 | CONFIG_MTD_NAND=y | 84 | CONFIG_MTD_RAW_NAND=y |
85 | CONFIG_MTD_NAND_XWAY=y | 85 | CONFIG_MTD_NAND_XWAY=y |
86 | CONFIG_EEPROM_93CX6=m | 86 | CONFIG_EEPROM_93CX6=m |
87 | CONFIG_SCSI=y | 87 | CONFIG_SCSI=y |
diff --git a/arch/powerpc/configs/40x/kilauea_defconfig b/arch/powerpc/configs/40x/kilauea_defconfig index b5cc7426c21f..3da091f651d6 100644 --- a/arch/powerpc/configs/40x/kilauea_defconfig +++ b/arch/powerpc/configs/40x/kilauea_defconfig | |||
@@ -33,7 +33,7 @@ CONFIG_MTD_CFI=y | |||
33 | CONFIG_MTD_JEDECPROBE=y | 33 | CONFIG_MTD_JEDECPROBE=y |
34 | CONFIG_MTD_CFI_AMDSTD=y | 34 | CONFIG_MTD_CFI_AMDSTD=y |
35 | CONFIG_MTD_PHYSMAP_OF=y | 35 | CONFIG_MTD_PHYSMAP_OF=y |
36 | CONFIG_MTD_NAND=y | 36 | CONFIG_MTD_RAW_NAND=y |
37 | CONFIG_MTD_NAND_NDFC=y | 37 | CONFIG_MTD_NAND_NDFC=y |
38 | CONFIG_BLK_DEV_RAM=y | 38 | CONFIG_BLK_DEV_RAM=y |
39 | CONFIG_BLK_DEV_RAM_SIZE=35000 | 39 | CONFIG_BLK_DEV_RAM_SIZE=35000 |
diff --git a/arch/powerpc/configs/40x/obs600_defconfig b/arch/powerpc/configs/40x/obs600_defconfig index aac06d2ad01a..38d3d7769a2f 100644 --- a/arch/powerpc/configs/40x/obs600_defconfig +++ b/arch/powerpc/configs/40x/obs600_defconfig | |||
@@ -33,7 +33,7 @@ CONFIG_MTD_CFI=y | |||
33 | CONFIG_MTD_JEDECPROBE=y | 33 | CONFIG_MTD_JEDECPROBE=y |
34 | CONFIG_MTD_CFI_AMDSTD=y | 34 | CONFIG_MTD_CFI_AMDSTD=y |
35 | CONFIG_MTD_PHYSMAP_OF=y | 35 | CONFIG_MTD_PHYSMAP_OF=y |
36 | CONFIG_MTD_NAND=y | 36 | CONFIG_MTD_RAW_NAND=y |
37 | CONFIG_MTD_NAND_NDFC=y | 37 | CONFIG_MTD_NAND_NDFC=y |
38 | CONFIG_BLK_DEV_RAM=y | 38 | CONFIG_BLK_DEV_RAM=y |
39 | CONFIG_BLK_DEV_RAM_SIZE=35000 | 39 | CONFIG_BLK_DEV_RAM_SIZE=35000 |
diff --git a/arch/powerpc/configs/44x/canyonlands_defconfig b/arch/powerpc/configs/44x/canyonlands_defconfig index c8e6f048a122..d427cee027a6 100644 --- a/arch/powerpc/configs/44x/canyonlands_defconfig +++ b/arch/powerpc/configs/44x/canyonlands_defconfig | |||
@@ -32,7 +32,7 @@ CONFIG_MTD_BLOCK=y | |||
32 | CONFIG_MTD_CFI=y | 32 | CONFIG_MTD_CFI=y |
33 | CONFIG_MTD_CFI_AMDSTD=y | 33 | CONFIG_MTD_CFI_AMDSTD=y |
34 | CONFIG_MTD_PHYSMAP_OF=y | 34 | CONFIG_MTD_PHYSMAP_OF=y |
35 | CONFIG_MTD_NAND=y | 35 | CONFIG_MTD_RAW_NAND=y |
36 | CONFIG_MTD_NAND_NDFC=y | 36 | CONFIG_MTD_NAND_NDFC=y |
37 | CONFIG_BLK_DEV_RAM=y | 37 | CONFIG_BLK_DEV_RAM=y |
38 | CONFIG_BLK_DEV_RAM_SIZE=35000 | 38 | CONFIG_BLK_DEV_RAM_SIZE=35000 |
diff --git a/arch/powerpc/configs/44x/eiger_defconfig b/arch/powerpc/configs/44x/eiger_defconfig index f6dc23fef683..f593258806ad 100644 --- a/arch/powerpc/configs/44x/eiger_defconfig +++ b/arch/powerpc/configs/44x/eiger_defconfig | |||
@@ -33,7 +33,7 @@ CONFIG_MTD_BLOCK=y | |||
33 | CONFIG_MTD_CFI=y | 33 | CONFIG_MTD_CFI=y |
34 | CONFIG_MTD_CFI_AMDSTD=y | 34 | CONFIG_MTD_CFI_AMDSTD=y |
35 | CONFIG_MTD_PHYSMAP_OF=y | 35 | CONFIG_MTD_PHYSMAP_OF=y |
36 | CONFIG_MTD_NAND=y | 36 | CONFIG_MTD_RAW_NAND=y |
37 | CONFIG_MTD_NAND_NDFC=y | 37 | CONFIG_MTD_NAND_NDFC=y |
38 | CONFIG_BLK_DEV_RAM=y | 38 | CONFIG_BLK_DEV_RAM=y |
39 | CONFIG_BLK_DEV_RAM_SIZE=35000 | 39 | CONFIG_BLK_DEV_RAM_SIZE=35000 |
diff --git a/arch/powerpc/configs/44x/sequoia_defconfig b/arch/powerpc/configs/44x/sequoia_defconfig index 1e04122912f3..f34fee9464e5 100644 --- a/arch/powerpc/configs/44x/sequoia_defconfig +++ b/arch/powerpc/configs/44x/sequoia_defconfig | |||
@@ -33,7 +33,7 @@ CONFIG_MTD_JEDECPROBE=y | |||
33 | CONFIG_MTD_CFI_INTELEXT=y | 33 | CONFIG_MTD_CFI_INTELEXT=y |
34 | CONFIG_MTD_CFI_AMDSTD=y | 34 | CONFIG_MTD_CFI_AMDSTD=y |
35 | CONFIG_MTD_PHYSMAP_OF=y | 35 | CONFIG_MTD_PHYSMAP_OF=y |
36 | CONFIG_MTD_NAND=y | 36 | CONFIG_MTD_RAW_NAND=y |
37 | CONFIG_MTD_NAND_NDFC=y | 37 | CONFIG_MTD_NAND_NDFC=y |
38 | CONFIG_BLK_DEV_RAM=y | 38 | CONFIG_BLK_DEV_RAM=y |
39 | CONFIG_BLK_DEV_RAM_SIZE=35000 | 39 | CONFIG_BLK_DEV_RAM_SIZE=35000 |
diff --git a/arch/powerpc/configs/44x/warp_defconfig b/arch/powerpc/configs/44x/warp_defconfig index 6c02f53271cd..6ae88d4879bf 100644 --- a/arch/powerpc/configs/44x/warp_defconfig +++ b/arch/powerpc/configs/44x/warp_defconfig | |||
@@ -34,7 +34,7 @@ CONFIG_MTD_BLOCK=y | |||
34 | CONFIG_MTD_CFI=y | 34 | CONFIG_MTD_CFI=y |
35 | CONFIG_MTD_CFI_AMDSTD=y | 35 | CONFIG_MTD_CFI_AMDSTD=y |
36 | CONFIG_MTD_PHYSMAP_OF=y | 36 | CONFIG_MTD_PHYSMAP_OF=y |
37 | CONFIG_MTD_NAND=y | 37 | CONFIG_MTD_RAW_NAND=y |
38 | CONFIG_MTD_NAND_NDFC=y | 38 | CONFIG_MTD_NAND_NDFC=y |
39 | CONFIG_MTD_UBI=y | 39 | CONFIG_MTD_UBI=y |
40 | CONFIG_BLK_DEV_RAM=y | 40 | CONFIG_BLK_DEV_RAM=y |
diff --git a/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig b/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig index 1f69f4edf074..9dffb2e7f735 100644 --- a/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig +++ b/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig | |||
@@ -31,7 +31,7 @@ CONFIG_MTD_BLOCK=y | |||
31 | CONFIG_MTD_CFI=y | 31 | CONFIG_MTD_CFI=y |
32 | CONFIG_MTD_CFI_AMDSTD=y | 32 | CONFIG_MTD_CFI_AMDSTD=y |
33 | CONFIG_MTD_PHYSMAP_OF=y | 33 | CONFIG_MTD_PHYSMAP_OF=y |
34 | CONFIG_MTD_NAND=y | 34 | CONFIG_MTD_RAW_NAND=y |
35 | CONFIG_MTD_NAND_FSL_ELBC=y | 35 | CONFIG_MTD_NAND_FSL_ELBC=y |
36 | CONFIG_BLK_DEV_LOOP=y | 36 | CONFIG_BLK_DEV_LOOP=y |
37 | CONFIG_BLK_DEV_RAM=y | 37 | CONFIG_BLK_DEV_RAM=y |
diff --git a/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig b/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig index 797fc3ffddee..a42232732c6d 100644 --- a/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig +++ b/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig | |||
@@ -31,7 +31,7 @@ CONFIG_MTD_BLOCK=y | |||
31 | CONFIG_MTD_CFI=y | 31 | CONFIG_MTD_CFI=y |
32 | CONFIG_MTD_CFI_AMDSTD=y | 32 | CONFIG_MTD_CFI_AMDSTD=y |
33 | CONFIG_MTD_PHYSMAP_OF=y | 33 | CONFIG_MTD_PHYSMAP_OF=y |
34 | CONFIG_MTD_NAND=y | 34 | CONFIG_MTD_RAW_NAND=y |
35 | CONFIG_BLK_DEV_LOOP=y | 35 | CONFIG_BLK_DEV_LOOP=y |
36 | CONFIG_BLK_DEV_RAM=y | 36 | CONFIG_BLK_DEV_RAM=y |
37 | CONFIG_BLK_DEV_RAM_SIZE=32768 | 37 | CONFIG_BLK_DEV_RAM_SIZE=32768 |
diff --git a/arch/powerpc/configs/85xx-hw.config b/arch/powerpc/configs/85xx-hw.config index c03d0fb16665..9575a38c9155 100644 --- a/arch/powerpc/configs/85xx-hw.config +++ b/arch/powerpc/configs/85xx-hw.config | |||
@@ -71,7 +71,7 @@ CONFIG_MTD_CMDLINE_PARTS=y | |||
71 | CONFIG_MTD_M25P80=y | 71 | CONFIG_MTD_M25P80=y |
72 | CONFIG_MTD_NAND_FSL_ELBC=y | 72 | CONFIG_MTD_NAND_FSL_ELBC=y |
73 | CONFIG_MTD_NAND_FSL_IFC=y | 73 | CONFIG_MTD_NAND_FSL_IFC=y |
74 | CONFIG_MTD_NAND=y | 74 | CONFIG_MTD_RAW_NAND=y |
75 | CONFIG_MTD_PHYSMAP_OF=y | 75 | CONFIG_MTD_PHYSMAP_OF=y |
76 | CONFIG_MTD_PHYSMAP=y | 76 | CONFIG_MTD_PHYSMAP=y |
77 | CONFIG_MTD_PLATRAM=y | 77 | CONFIG_MTD_PLATRAM=y |
diff --git a/arch/powerpc/configs/85xx/ge_imp3a_defconfig b/arch/powerpc/configs/85xx/ge_imp3a_defconfig index dd98f43b2fb8..d70b60314dad 100644 --- a/arch/powerpc/configs/85xx/ge_imp3a_defconfig +++ b/arch/powerpc/configs/85xx/ge_imp3a_defconfig | |||
@@ -73,7 +73,7 @@ CONFIG_MTD_JEDECPROBE=y | |||
73 | CONFIG_MTD_CFI_INTELEXT=y | 73 | CONFIG_MTD_CFI_INTELEXT=y |
74 | CONFIG_MTD_CFI_AMDSTD=y | 74 | CONFIG_MTD_CFI_AMDSTD=y |
75 | CONFIG_MTD_PHYSMAP_OF=y | 75 | CONFIG_MTD_PHYSMAP_OF=y |
76 | CONFIG_MTD_NAND=y | 76 | CONFIG_MTD_RAW_NAND=y |
77 | CONFIG_MTD_NAND_FSL_ELBC=y | 77 | CONFIG_MTD_NAND_FSL_ELBC=y |
78 | CONFIG_BLK_DEV_LOOP=m | 78 | CONFIG_BLK_DEV_LOOP=m |
79 | CONFIG_BLK_DEV_CRYPTOLOOP=m | 79 | CONFIG_BLK_DEV_CRYPTOLOOP=m |
diff --git a/arch/powerpc/configs/85xx/socrates_defconfig b/arch/powerpc/configs/85xx/socrates_defconfig index 6106fadbbd8b..7037a6d8018c 100644 --- a/arch/powerpc/configs/85xx/socrates_defconfig +++ b/arch/powerpc/configs/85xx/socrates_defconfig | |||
@@ -31,7 +31,7 @@ CONFIG_MTD_CFI=y | |||
31 | CONFIG_MTD_JEDECPROBE=y | 31 | CONFIG_MTD_JEDECPROBE=y |
32 | CONFIG_MTD_CFI_AMDSTD=y | 32 | CONFIG_MTD_CFI_AMDSTD=y |
33 | CONFIG_MTD_PHYSMAP_OF=y | 33 | CONFIG_MTD_PHYSMAP_OF=y |
34 | CONFIG_MTD_NAND=y | 34 | CONFIG_MTD_RAW_NAND=y |
35 | CONFIG_MTD_NAND_SOCRATES=y | 35 | CONFIG_MTD_NAND_SOCRATES=y |
36 | CONFIG_BLK_DEV_LOOP=y | 36 | CONFIG_BLK_DEV_LOOP=y |
37 | CONFIG_BLK_DEV_RAM=y | 37 | CONFIG_BLK_DEV_RAM=y |
diff --git a/arch/powerpc/configs/85xx/tqm8548_defconfig b/arch/powerpc/configs/85xx/tqm8548_defconfig index 2697e4e8a761..1c63cbdc3211 100644 --- a/arch/powerpc/configs/85xx/tqm8548_defconfig +++ b/arch/powerpc/configs/85xx/tqm8548_defconfig | |||
@@ -35,8 +35,8 @@ CONFIG_MTD=y | |||
35 | CONFIG_MTD_CFI=y | 35 | CONFIG_MTD_CFI=y |
36 | CONFIG_MTD_CFI_AMDSTD=y | 36 | CONFIG_MTD_CFI_AMDSTD=y |
37 | CONFIG_MTD_PHYSMAP_OF=y | 37 | CONFIG_MTD_PHYSMAP_OF=y |
38 | CONFIG_MTD_NAND_ECC_SMC=y | 38 | CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC=y |
39 | CONFIG_MTD_NAND=y | 39 | CONFIG_MTD_RAW_NAND=y |
40 | CONFIG_MTD_NAND_FSL_UPM=y | 40 | CONFIG_MTD_NAND_FSL_UPM=y |
41 | CONFIG_BLK_DEV_LOOP=y | 41 | CONFIG_BLK_DEV_LOOP=y |
42 | CONFIG_BLK_DEV_RAM=y | 42 | CONFIG_BLK_DEV_RAM=y |
diff --git a/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig b/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig index 6531139a8a8d..78f5beb2928c 100644 --- a/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig +++ b/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig | |||
@@ -65,7 +65,7 @@ CONFIG_MTD_CFI_INTELEXT=y | |||
65 | CONFIG_MTD_CFI_AMDSTD=y | 65 | CONFIG_MTD_CFI_AMDSTD=y |
66 | CONFIG_MTD_CFI_STAA=y | 66 | CONFIG_MTD_CFI_STAA=y |
67 | CONFIG_MTD_PHYSMAP_OF=y | 67 | CONFIG_MTD_PHYSMAP_OF=y |
68 | CONFIG_MTD_NAND=y | 68 | CONFIG_MTD_RAW_NAND=y |
69 | CONFIG_MTD_NAND_FSL_ELBC=y | 69 | CONFIG_MTD_NAND_FSL_ELBC=y |
70 | CONFIG_MTD_NAND_FSL_UPM=y | 70 | CONFIG_MTD_NAND_FSL_UPM=y |
71 | CONFIG_BLK_DEV_LOOP=y | 71 | CONFIG_BLK_DEV_LOOP=y |
diff --git a/arch/powerpc/configs/86xx-hw.config b/arch/powerpc/configs/86xx-hw.config index d3dd6b8865c0..151164cf8cb3 100644 --- a/arch/powerpc/configs/86xx-hw.config +++ b/arch/powerpc/configs/86xx-hw.config | |||
@@ -47,7 +47,7 @@ CONFIG_MTD_CFI=y | |||
47 | CONFIG_MTD_CMDLINE_PARTS=y | 47 | CONFIG_MTD_CMDLINE_PARTS=y |
48 | CONFIG_MTD_JEDECPROBE=y | 48 | CONFIG_MTD_JEDECPROBE=y |
49 | CONFIG_MTD_NAND_FSL_ELBC=y | 49 | CONFIG_MTD_NAND_FSL_ELBC=y |
50 | CONFIG_MTD_NAND=y | 50 | CONFIG_MTD_RAW_NAND=y |
51 | CONFIG_MTD_PHYSMAP_OF=y | 51 | CONFIG_MTD_PHYSMAP_OF=y |
52 | CONFIG_NETDEVICES=y | 52 | CONFIG_NETDEVICES=y |
53 | CONFIG_NET_TULIP=y | 53 | CONFIG_NET_TULIP=y |
diff --git a/arch/powerpc/configs/mpc512x_defconfig b/arch/powerpc/configs/mpc512x_defconfig index e4bfb1101c0e..e4bf8aa87e60 100644 --- a/arch/powerpc/configs/mpc512x_defconfig +++ b/arch/powerpc/configs/mpc512x_defconfig | |||
@@ -46,7 +46,7 @@ CONFIG_MTD_CFI=y | |||
46 | CONFIG_MTD_CFI_AMDSTD=y | 46 | CONFIG_MTD_CFI_AMDSTD=y |
47 | CONFIG_MTD_ROM=y | 47 | CONFIG_MTD_ROM=y |
48 | CONFIG_MTD_PHYSMAP_OF=y | 48 | CONFIG_MTD_PHYSMAP_OF=y |
49 | CONFIG_MTD_NAND=y | 49 | CONFIG_MTD_RAW_NAND=y |
50 | CONFIG_MTD_NAND_MPC5121_NFC=y | 50 | CONFIG_MTD_NAND_MPC5121_NFC=y |
51 | CONFIG_MTD_UBI=y | 51 | CONFIG_MTD_UBI=y |
52 | CONFIG_BLK_DEV_RAM=y | 52 | CONFIG_BLK_DEV_RAM=y |
diff --git a/arch/powerpc/configs/mpc83xx_defconfig b/arch/powerpc/configs/mpc83xx_defconfig index d1b82035d35f..005d00020fb9 100644 --- a/arch/powerpc/configs/mpc83xx_defconfig +++ b/arch/powerpc/configs/mpc83xx_defconfig | |||
@@ -46,7 +46,7 @@ CONFIG_MTD_BLOCK=y | |||
46 | CONFIG_MTD_CFI=y | 46 | CONFIG_MTD_CFI=y |
47 | CONFIG_MTD_CFI_AMDSTD=y | 47 | CONFIG_MTD_CFI_AMDSTD=y |
48 | CONFIG_MTD_PHYSMAP_OF=y | 48 | CONFIG_MTD_PHYSMAP_OF=y |
49 | CONFIG_MTD_NAND=y | 49 | CONFIG_MTD_RAW_NAND=y |
50 | CONFIG_MTD_NAND_FSL_ELBC=y | 50 | CONFIG_MTD_NAND_FSL_ELBC=y |
51 | CONFIG_BLK_DEV_LOOP=y | 51 | CONFIG_BLK_DEV_LOOP=y |
52 | CONFIG_BLK_DEV_RAM=y | 52 | CONFIG_BLK_DEV_RAM=y |
diff --git a/arch/powerpc/configs/pasemi_defconfig b/arch/powerpc/configs/pasemi_defconfig index 6daa56f8895c..c0423b2cf7c0 100644 --- a/arch/powerpc/configs/pasemi_defconfig +++ b/arch/powerpc/configs/pasemi_defconfig | |||
@@ -51,7 +51,7 @@ CONFIG_MTD=y | |||
51 | CONFIG_MTD_BLOCK=y | 51 | CONFIG_MTD_BLOCK=y |
52 | CONFIG_MTD_SLRAM=y | 52 | CONFIG_MTD_SLRAM=y |
53 | CONFIG_MTD_PHRAM=y | 53 | CONFIG_MTD_PHRAM=y |
54 | CONFIG_MTD_NAND=y | 54 | CONFIG_MTD_RAW_NAND=y |
55 | CONFIG_MTD_NAND_PASEMI=y | 55 | CONFIG_MTD_NAND_PASEMI=y |
56 | CONFIG_BLK_DEV_LOOP=y | 56 | CONFIG_BLK_DEV_LOOP=y |
57 | CONFIG_BLK_DEV_RAM=y | 57 | CONFIG_BLK_DEV_RAM=y |
diff --git a/arch/powerpc/configs/ppc44x_defconfig b/arch/powerpc/configs/ppc44x_defconfig index 66dd6bf45cde..db48039e0b11 100644 --- a/arch/powerpc/configs/ppc44x_defconfig +++ b/arch/powerpc/configs/ppc44x_defconfig | |||
@@ -44,7 +44,7 @@ CONFIG_MTD_CFI=y | |||
44 | CONFIG_MTD_JEDECPROBE=y | 44 | CONFIG_MTD_JEDECPROBE=y |
45 | CONFIG_MTD_CFI_AMDSTD=y | 45 | CONFIG_MTD_CFI_AMDSTD=y |
46 | CONFIG_MTD_PHYSMAP_OF=y | 46 | CONFIG_MTD_PHYSMAP_OF=y |
47 | CONFIG_MTD_NAND=m | 47 | CONFIG_MTD_RAW_NAND=m |
48 | CONFIG_MTD_NAND_NDFC=m | 48 | CONFIG_MTD_NAND_NDFC=m |
49 | CONFIG_MTD_UBI=m | 49 | CONFIG_MTD_UBI=m |
50 | CONFIG_MTD_UBI_GLUEBI=m | 50 | CONFIG_MTD_UBI_GLUEBI=m |
diff --git a/arch/sh/configs/ap325rxa_defconfig b/arch/sh/configs/ap325rxa_defconfig index 72b72e50a92e..0ef3f1f9de5c 100644 --- a/arch/sh/configs/ap325rxa_defconfig +++ b/arch/sh/configs/ap325rxa_defconfig | |||
@@ -35,7 +35,7 @@ CONFIG_MTD_BLOCK=y | |||
35 | CONFIG_MTD_CFI=y | 35 | CONFIG_MTD_CFI=y |
36 | CONFIG_MTD_CFI_AMDSTD=y | 36 | CONFIG_MTD_CFI_AMDSTD=y |
37 | CONFIG_MTD_PHYSMAP=y | 37 | CONFIG_MTD_PHYSMAP=y |
38 | CONFIG_MTD_NAND=y | 38 | CONFIG_MTD_RAW_NAND=y |
39 | CONFIG_MTD_NAND_SH_FLCTL=y | 39 | CONFIG_MTD_NAND_SH_FLCTL=y |
40 | CONFIG_MTD_UBI=y | 40 | CONFIG_MTD_UBI=y |
41 | CONFIG_BLK_DEV_RAM=y | 41 | CONFIG_BLK_DEV_RAM=y |
diff --git a/arch/sh/configs/ecovec24_defconfig b/arch/sh/configs/ecovec24_defconfig index 3568310c2c2f..ba67e3752938 100644 --- a/arch/sh/configs/ecovec24_defconfig +++ b/arch/sh/configs/ecovec24_defconfig | |||
@@ -38,7 +38,7 @@ CONFIG_MTD_BLOCK=y | |||
38 | CONFIG_MTD_CFI=y | 38 | CONFIG_MTD_CFI=y |
39 | CONFIG_MTD_CFI_AMDSTD=y | 39 | CONFIG_MTD_CFI_AMDSTD=y |
40 | CONFIG_MTD_PHYSMAP=y | 40 | CONFIG_MTD_PHYSMAP=y |
41 | CONFIG_MTD_NAND=y | 41 | CONFIG_MTD_RAW_NAND=y |
42 | CONFIG_MTD_UBI=y | 42 | CONFIG_MTD_UBI=y |
43 | CONFIG_BLK_DEV_RAM=y | 43 | CONFIG_BLK_DEV_RAM=y |
44 | CONFIG_BLK_DEV_RAM_COUNT=4 | 44 | CONFIG_BLK_DEV_RAM_COUNT=4 |
diff --git a/arch/sh/configs/migor_defconfig b/arch/sh/configs/migor_defconfig index e04f21be0756..121a75d65fb4 100644 --- a/arch/sh/configs/migor_defconfig +++ b/arch/sh/configs/migor_defconfig | |||
@@ -34,7 +34,7 @@ CONFIG_MTD_BLOCK=y | |||
34 | CONFIG_MTD_CFI=y | 34 | CONFIG_MTD_CFI=y |
35 | CONFIG_MTD_CFI_AMDSTD=y | 35 | CONFIG_MTD_CFI_AMDSTD=y |
36 | CONFIG_MTD_PHYSMAP=y | 36 | CONFIG_MTD_PHYSMAP=y |
37 | CONFIG_MTD_NAND=y | 37 | CONFIG_MTD_RAW_NAND=y |
38 | CONFIG_MTD_NAND_PLATFORM=y | 38 | CONFIG_MTD_NAND_PLATFORM=y |
39 | CONFIG_BLK_DEV_RAM=y | 39 | CONFIG_BLK_DEV_RAM=y |
40 | CONFIG_SCSI=y | 40 | CONFIG_SCSI=y |
diff --git a/arch/sh/configs/sdk7786_defconfig b/arch/sh/configs/sdk7786_defconfig index d16e9334cd98..5209889765ad 100644 --- a/arch/sh/configs/sdk7786_defconfig +++ b/arch/sh/configs/sdk7786_defconfig | |||
@@ -108,7 +108,7 @@ CONFIG_MTD_ROM=m | |||
108 | CONFIG_MTD_ABSENT=m | 108 | CONFIG_MTD_ABSENT=m |
109 | CONFIG_MTD_PLATRAM=y | 109 | CONFIG_MTD_PLATRAM=y |
110 | CONFIG_MTD_PHRAM=y | 110 | CONFIG_MTD_PHRAM=y |
111 | CONFIG_MTD_NAND=y | 111 | CONFIG_MTD_RAW_NAND=y |
112 | CONFIG_MTD_NAND_PLATFORM=y | 112 | CONFIG_MTD_NAND_PLATFORM=y |
113 | CONFIG_MTD_NAND_SH_FLCTL=m | 113 | CONFIG_MTD_NAND_SH_FLCTL=m |
114 | CONFIG_MTD_UBI=y | 114 | CONFIG_MTD_UBI=y |
diff --git a/arch/sh/configs/se7724_defconfig b/arch/sh/configs/se7724_defconfig index aedb3a2d9a10..9f6d46d58554 100644 --- a/arch/sh/configs/se7724_defconfig +++ b/arch/sh/configs/se7724_defconfig | |||
@@ -37,7 +37,7 @@ CONFIG_MTD_BLOCK=y | |||
37 | CONFIG_MTD_CFI=y | 37 | CONFIG_MTD_CFI=y |
38 | CONFIG_MTD_CFI_AMDSTD=y | 38 | CONFIG_MTD_CFI_AMDSTD=y |
39 | CONFIG_MTD_PHYSMAP=y | 39 | CONFIG_MTD_PHYSMAP=y |
40 | CONFIG_MTD_NAND=y | 40 | CONFIG_MTD_RAW_NAND=y |
41 | CONFIG_MTD_UBI=y | 41 | CONFIG_MTD_UBI=y |
42 | CONFIG_BLK_DEV_RAM=y | 42 | CONFIG_BLK_DEV_RAM=y |
43 | CONFIG_BLK_DEV_RAM_COUNT=4 | 43 | CONFIG_BLK_DEV_RAM_COUNT=4 |
diff --git a/arch/sh/configs/titan_defconfig b/arch/sh/configs/titan_defconfig index ceb48e9b70f4..822fa9e96f74 100644 --- a/arch/sh/configs/titan_defconfig +++ b/arch/sh/configs/titan_defconfig | |||
@@ -155,7 +155,7 @@ CONFIG_INFTL=m | |||
155 | CONFIG_RFD_FTL=m | 155 | CONFIG_RFD_FTL=m |
156 | CONFIG_MTD_CFI=m | 156 | CONFIG_MTD_CFI=m |
157 | CONFIG_MTD_JEDECPROBE=m | 157 | CONFIG_MTD_JEDECPROBE=m |
158 | CONFIG_MTD_NAND=m | 158 | CONFIG_MTD_RAW_NAND=m |
159 | CONFIG_BLK_DEV_LOOP=m | 159 | CONFIG_BLK_DEV_LOOP=m |
160 | CONFIG_BLK_DEV_CRYPTOLOOP=m | 160 | CONFIG_BLK_DEV_CRYPTOLOOP=m |
161 | CONFIG_BLK_DEV_RAM=y | 161 | CONFIG_BLK_DEV_RAM=y |
diff --git a/drivers/memory/atmel-ebi.c b/drivers/memory/atmel-ebi.c index c3748b414c27..0322df9dc249 100644 --- a/drivers/memory/atmel-ebi.c +++ b/drivers/memory/atmel-ebi.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/of_device.h> | 18 | #include <linux/of_device.h> |
19 | #include <linux/regmap.h> | 19 | #include <linux/regmap.h> |
20 | #include <soc/at91/atmel-sfr.h> | ||
20 | 21 | ||
21 | struct atmel_ebi_dev_config { | 22 | struct atmel_ebi_dev_config { |
22 | int cs; | 23 | int cs; |
@@ -36,6 +37,7 @@ struct atmel_ebi_dev { | |||
36 | struct atmel_ebi_caps { | 37 | struct atmel_ebi_caps { |
37 | unsigned int available_cs; | 38 | unsigned int available_cs; |
38 | unsigned int ebi_csa_offs; | 39 | unsigned int ebi_csa_offs; |
40 | const char *regmap_name; | ||
39 | void (*get_config)(struct atmel_ebi_dev *ebid, | 41 | void (*get_config)(struct atmel_ebi_dev *ebid, |
40 | struct atmel_ebi_dev_config *conf); | 42 | struct atmel_ebi_dev_config *conf); |
41 | int (*xlate_config)(struct atmel_ebi_dev *ebid, | 43 | int (*xlate_config)(struct atmel_ebi_dev *ebid, |
@@ -47,7 +49,7 @@ struct atmel_ebi_caps { | |||
47 | 49 | ||
48 | struct atmel_ebi { | 50 | struct atmel_ebi { |
49 | struct clk *clk; | 51 | struct clk *clk; |
50 | struct regmap *matrix; | 52 | struct regmap *regmap; |
51 | struct { | 53 | struct { |
52 | struct regmap *regmap; | 54 | struct regmap *regmap; |
53 | struct clk *clk; | 55 | struct clk *clk; |
@@ -357,7 +359,7 @@ static int atmel_ebi_dev_setup(struct atmel_ebi *ebi, struct device_node *np, | |||
357 | * one "atmel,smc-" property is present. | 359 | * one "atmel,smc-" property is present. |
358 | */ | 360 | */ |
359 | if (ebi->caps->ebi_csa_offs && apply) | 361 | if (ebi->caps->ebi_csa_offs && apply) |
360 | regmap_update_bits(ebi->matrix, | 362 | regmap_update_bits(ebi->regmap, |
361 | ebi->caps->ebi_csa_offs, | 363 | ebi->caps->ebi_csa_offs, |
362 | BIT(cs), 0); | 364 | BIT(cs), 0); |
363 | 365 | ||
@@ -372,6 +374,7 @@ static int atmel_ebi_dev_setup(struct atmel_ebi *ebi, struct device_node *np, | |||
372 | static const struct atmel_ebi_caps at91sam9260_ebi_caps = { | 374 | static const struct atmel_ebi_caps at91sam9260_ebi_caps = { |
373 | .available_cs = 0xff, | 375 | .available_cs = 0xff, |
374 | .ebi_csa_offs = AT91SAM9260_MATRIX_EBICSA, | 376 | .ebi_csa_offs = AT91SAM9260_MATRIX_EBICSA, |
377 | .regmap_name = "atmel,matrix", | ||
375 | .get_config = at91sam9_ebi_get_config, | 378 | .get_config = at91sam9_ebi_get_config, |
376 | .xlate_config = atmel_ebi_xslate_smc_config, | 379 | .xlate_config = atmel_ebi_xslate_smc_config, |
377 | .apply_config = at91sam9_ebi_apply_config, | 380 | .apply_config = at91sam9_ebi_apply_config, |
@@ -380,6 +383,7 @@ static const struct atmel_ebi_caps at91sam9260_ebi_caps = { | |||
380 | static const struct atmel_ebi_caps at91sam9261_ebi_caps = { | 383 | static const struct atmel_ebi_caps at91sam9261_ebi_caps = { |
381 | .available_cs = 0xff, | 384 | .available_cs = 0xff, |
382 | .ebi_csa_offs = AT91SAM9261_MATRIX_EBICSA, | 385 | .ebi_csa_offs = AT91SAM9261_MATRIX_EBICSA, |
386 | .regmap_name = "atmel,matrix", | ||
383 | .get_config = at91sam9_ebi_get_config, | 387 | .get_config = at91sam9_ebi_get_config, |
384 | .xlate_config = atmel_ebi_xslate_smc_config, | 388 | .xlate_config = atmel_ebi_xslate_smc_config, |
385 | .apply_config = at91sam9_ebi_apply_config, | 389 | .apply_config = at91sam9_ebi_apply_config, |
@@ -388,6 +392,7 @@ static const struct atmel_ebi_caps at91sam9261_ebi_caps = { | |||
388 | static const struct atmel_ebi_caps at91sam9263_ebi0_caps = { | 392 | static const struct atmel_ebi_caps at91sam9263_ebi0_caps = { |
389 | .available_cs = 0x3f, | 393 | .available_cs = 0x3f, |
390 | .ebi_csa_offs = AT91SAM9263_MATRIX_EBI0CSA, | 394 | .ebi_csa_offs = AT91SAM9263_MATRIX_EBI0CSA, |
395 | .regmap_name = "atmel,matrix", | ||
391 | .get_config = at91sam9_ebi_get_config, | 396 | .get_config = at91sam9_ebi_get_config, |
392 | .xlate_config = atmel_ebi_xslate_smc_config, | 397 | .xlate_config = atmel_ebi_xslate_smc_config, |
393 | .apply_config = at91sam9_ebi_apply_config, | 398 | .apply_config = at91sam9_ebi_apply_config, |
@@ -396,6 +401,7 @@ static const struct atmel_ebi_caps at91sam9263_ebi0_caps = { | |||
396 | static const struct atmel_ebi_caps at91sam9263_ebi1_caps = { | 401 | static const struct atmel_ebi_caps at91sam9263_ebi1_caps = { |
397 | .available_cs = 0x7, | 402 | .available_cs = 0x7, |
398 | .ebi_csa_offs = AT91SAM9263_MATRIX_EBI1CSA, | 403 | .ebi_csa_offs = AT91SAM9263_MATRIX_EBI1CSA, |
404 | .regmap_name = "atmel,matrix", | ||
399 | .get_config = at91sam9_ebi_get_config, | 405 | .get_config = at91sam9_ebi_get_config, |
400 | .xlate_config = atmel_ebi_xslate_smc_config, | 406 | .xlate_config = atmel_ebi_xslate_smc_config, |
401 | .apply_config = at91sam9_ebi_apply_config, | 407 | .apply_config = at91sam9_ebi_apply_config, |
@@ -404,6 +410,7 @@ static const struct atmel_ebi_caps at91sam9263_ebi1_caps = { | |||
404 | static const struct atmel_ebi_caps at91sam9rl_ebi_caps = { | 410 | static const struct atmel_ebi_caps at91sam9rl_ebi_caps = { |
405 | .available_cs = 0x3f, | 411 | .available_cs = 0x3f, |
406 | .ebi_csa_offs = AT91SAM9RL_MATRIX_EBICSA, | 412 | .ebi_csa_offs = AT91SAM9RL_MATRIX_EBICSA, |
413 | .regmap_name = "atmel,matrix", | ||
407 | .get_config = at91sam9_ebi_get_config, | 414 | .get_config = at91sam9_ebi_get_config, |
408 | .xlate_config = atmel_ebi_xslate_smc_config, | 415 | .xlate_config = atmel_ebi_xslate_smc_config, |
409 | .apply_config = at91sam9_ebi_apply_config, | 416 | .apply_config = at91sam9_ebi_apply_config, |
@@ -412,6 +419,7 @@ static const struct atmel_ebi_caps at91sam9rl_ebi_caps = { | |||
412 | static const struct atmel_ebi_caps at91sam9g45_ebi_caps = { | 419 | static const struct atmel_ebi_caps at91sam9g45_ebi_caps = { |
413 | .available_cs = 0x3f, | 420 | .available_cs = 0x3f, |
414 | .ebi_csa_offs = AT91SAM9G45_MATRIX_EBICSA, | 421 | .ebi_csa_offs = AT91SAM9G45_MATRIX_EBICSA, |
422 | .regmap_name = "atmel,matrix", | ||
415 | .get_config = at91sam9_ebi_get_config, | 423 | .get_config = at91sam9_ebi_get_config, |
416 | .xlate_config = atmel_ebi_xslate_smc_config, | 424 | .xlate_config = atmel_ebi_xslate_smc_config, |
417 | .apply_config = at91sam9_ebi_apply_config, | 425 | .apply_config = at91sam9_ebi_apply_config, |
@@ -420,6 +428,7 @@ static const struct atmel_ebi_caps at91sam9g45_ebi_caps = { | |||
420 | static const struct atmel_ebi_caps at91sam9x5_ebi_caps = { | 428 | static const struct atmel_ebi_caps at91sam9x5_ebi_caps = { |
421 | .available_cs = 0x3f, | 429 | .available_cs = 0x3f, |
422 | .ebi_csa_offs = AT91SAM9X5_MATRIX_EBICSA, | 430 | .ebi_csa_offs = AT91SAM9X5_MATRIX_EBICSA, |
431 | .regmap_name = "atmel,matrix", | ||
423 | .get_config = at91sam9_ebi_get_config, | 432 | .get_config = at91sam9_ebi_get_config, |
424 | .xlate_config = atmel_ebi_xslate_smc_config, | 433 | .xlate_config = atmel_ebi_xslate_smc_config, |
425 | .apply_config = at91sam9_ebi_apply_config, | 434 | .apply_config = at91sam9_ebi_apply_config, |
@@ -432,6 +441,15 @@ static const struct atmel_ebi_caps sama5d3_ebi_caps = { | |||
432 | .apply_config = sama5_ebi_apply_config, | 441 | .apply_config = sama5_ebi_apply_config, |
433 | }; | 442 | }; |
434 | 443 | ||
444 | static const struct atmel_ebi_caps sam9x60_ebi_caps = { | ||
445 | .available_cs = 0x3f, | ||
446 | .ebi_csa_offs = AT91_SFR_CCFG_EBICSA, | ||
447 | .regmap_name = "microchip,sfr", | ||
448 | .get_config = at91sam9_ebi_get_config, | ||
449 | .xlate_config = atmel_ebi_xslate_smc_config, | ||
450 | .apply_config = at91sam9_ebi_apply_config, | ||
451 | }; | ||
452 | |||
435 | static const struct of_device_id atmel_ebi_id_table[] = { | 453 | static const struct of_device_id atmel_ebi_id_table[] = { |
436 | { | 454 | { |
437 | .compatible = "atmel,at91sam9260-ebi", | 455 | .compatible = "atmel,at91sam9260-ebi", |
@@ -465,6 +483,10 @@ static const struct of_device_id atmel_ebi_id_table[] = { | |||
465 | .compatible = "atmel,sama5d3-ebi", | 483 | .compatible = "atmel,sama5d3-ebi", |
466 | .data = &sama5d3_ebi_caps, | 484 | .data = &sama5d3_ebi_caps, |
467 | }, | 485 | }, |
486 | { | ||
487 | .compatible = "microchip,sam9x60-ebi", | ||
488 | .data = &sam9x60_ebi_caps, | ||
489 | }, | ||
468 | { /* sentinel */ } | 490 | { /* sentinel */ } |
469 | }; | 491 | }; |
470 | 492 | ||
@@ -543,13 +565,14 @@ static int atmel_ebi_probe(struct platform_device *pdev) | |||
543 | 565 | ||
544 | /* | 566 | /* |
545 | * The sama5d3 does not provide an EBICSA register and thus does need | 567 | * The sama5d3 does not provide an EBICSA register and thus does need |
546 | * to access the matrix registers. | 568 | * to access it. |
547 | */ | 569 | */ |
548 | if (ebi->caps->ebi_csa_offs) { | 570 | if (ebi->caps->ebi_csa_offs) { |
549 | ebi->matrix = | 571 | ebi->regmap = |
550 | syscon_regmap_lookup_by_phandle(np, "atmel,matrix"); | 572 | syscon_regmap_lookup_by_phandle(np, |
551 | if (IS_ERR(ebi->matrix)) | 573 | ebi->caps->regmap_name); |
552 | return PTR_ERR(ebi->matrix); | 574 | if (IS_ERR(ebi->regmap)) |
575 | return PTR_ERR(ebi->regmap); | ||
553 | } | 576 | } |
554 | 577 | ||
555 | ret = of_property_read_u32(np, "#address-cells", &val); | 578 | ret = of_property_read_u32(np, "#address-cells", &val); |
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 79a8ff542883..fb31a7f649a3 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig | |||
@@ -60,22 +60,6 @@ config MTD_CMDLINE_PARTS | |||
60 | 60 | ||
61 | If unsure, say 'N'. | 61 | If unsure, say 'N'. |
62 | 62 | ||
63 | config MTD_AFS_PARTS | ||
64 | tristate "ARM Firmware Suite partition parsing" | ||
65 | depends on (ARM || ARM64) | ||
66 | help | ||
67 | The ARM Firmware Suite allows the user to divide flash devices into | ||
68 | multiple 'images'. Each such image has a header containing its name | ||
69 | and offset/size etc. | ||
70 | |||
71 | If you need code which can detect and parse these tables, and | ||
72 | register MTD 'partitions' corresponding to each image detected, | ||
73 | enable this option. | ||
74 | |||
75 | You will still need the parsing functions to be called by the driver | ||
76 | for your particular device. It won't happen automatically. The | ||
77 | 'physmap' map driver (CONFIG_MTD_PHYSMAP) does this, for example. | ||
78 | |||
79 | config MTD_OF_PARTS | 63 | config MTD_OF_PARTS |
80 | tristate "OpenFirmware partitioning information support" | 64 | tristate "OpenFirmware partitioning information support" |
81 | default y | 65 | default y |
@@ -94,6 +78,7 @@ config MTD_BCM63XX_PARTS | |||
94 | tristate "BCM63XX CFE partitioning support" | 78 | tristate "BCM63XX CFE partitioning support" |
95 | depends on BCM63XX || BMIPS_GENERIC || COMPILE_TEST | 79 | depends on BCM63XX || BMIPS_GENERIC || COMPILE_TEST |
96 | select CRC32 | 80 | select CRC32 |
81 | select MTD_PARSER_IMAGETAG | ||
97 | help | 82 | help |
98 | This provides partition parsing for BCM63xx devices with CFE | 83 | This provides partition parsing for BCM63xx devices with CFE |
99 | bootloaders. | 84 | bootloaders. |
@@ -230,12 +215,11 @@ config SSFDC | |||
230 | This enables read only access to SmartMedia formatted NAND | 215 | This enables read only access to SmartMedia formatted NAND |
231 | flash. You can mount it with FAT file system. | 216 | flash. You can mount it with FAT file system. |
232 | 217 | ||
233 | |||
234 | config SM_FTL | 218 | config SM_FTL |
235 | tristate "SmartMedia/xD new translation layer" | 219 | tristate "SmartMedia/xD new translation layer" |
236 | depends on BLOCK | 220 | depends on BLOCK |
237 | select MTD_BLKDEVS | 221 | select MTD_BLKDEVS |
238 | select MTD_NAND_ECC | 222 | select MTD_NAND_ECC_SW_HAMMING |
239 | help | 223 | help |
240 | This enables EXPERIMENTAL R/W support for SmartMedia/xD | 224 | This enables EXPERIMENTAL R/W support for SmartMedia/xD |
241 | FTL (Flash translation layer). | 225 | FTL (Flash translation layer). |
diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index 58fc327a5276..806287e80e84 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile | |||
@@ -9,7 +9,6 @@ mtd-y := mtdcore.o mtdsuper.o mtdconcat.o mtdpart.o mtdchar.o | |||
9 | 9 | ||
10 | obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o | 10 | obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o |
11 | obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o | 11 | obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o |
12 | obj-$(CONFIG_MTD_AFS_PARTS) += afs.o | ||
13 | obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o | 12 | obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o |
14 | obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o | 13 | obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o |
15 | obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o | 14 | obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o |
diff --git a/drivers/mtd/afs.c b/drivers/mtd/afs.c deleted file mode 100644 index d61b7edfc938..000000000000 --- a/drivers/mtd/afs.c +++ /dev/null | |||
@@ -1,266 +0,0 @@ | |||
1 | /*====================================================================== | ||
2 | |||
3 | drivers/mtd/afs.c: ARM Flash Layout/Partitioning | ||
4 | |||
5 | Copyright © 2000 ARM Limited | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify | ||
8 | it under the terms of the GNU General Public License as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (at your option) any later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | |||
21 | This is access code for flashes using ARM's flash partitioning | ||
22 | standards. | ||
23 | |||
24 | ======================================================================*/ | ||
25 | |||
26 | #include <linux/module.h> | ||
27 | #include <linux/types.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/string.h> | ||
31 | #include <linux/init.h> | ||
32 | |||
33 | #include <linux/mtd/mtd.h> | ||
34 | #include <linux/mtd/map.h> | ||
35 | #include <linux/mtd/partitions.h> | ||
36 | |||
37 | #define AFSV1_FOOTER_MAGIC 0xA0FFFF9F | ||
38 | |||
39 | struct footer_v1 { | ||
40 | u32 image_info_base; /* Address of first word of ImageFooter */ | ||
41 | u32 image_start; /* Start of area reserved by this footer */ | ||
42 | u32 signature; /* 'Magic' number proves it's a footer */ | ||
43 | u32 type; /* Area type: ARM Image, SIB, customer */ | ||
44 | u32 checksum; /* Just this structure */ | ||
45 | }; | ||
46 | |||
47 | struct image_info_v1 { | ||
48 | u32 bootFlags; /* Boot flags, compression etc. */ | ||
49 | u32 imageNumber; /* Unique number, selects for boot etc. */ | ||
50 | u32 loadAddress; /* Address program should be loaded to */ | ||
51 | u32 length; /* Actual size of image */ | ||
52 | u32 address; /* Image is executed from here */ | ||
53 | char name[16]; /* Null terminated */ | ||
54 | u32 headerBase; /* Flash Address of any stripped header */ | ||
55 | u32 header_length; /* Length of header in memory */ | ||
56 | u32 headerType; /* AIF, RLF, s-record etc. */ | ||
57 | u32 checksum; /* Image checksum (inc. this struct) */ | ||
58 | }; | ||
59 | |||
60 | static u32 word_sum(void *words, int num) | ||
61 | { | ||
62 | u32 *p = words; | ||
63 | u32 sum = 0; | ||
64 | |||
65 | while (num--) | ||
66 | sum += *p++; | ||
67 | |||
68 | return sum; | ||
69 | } | ||
70 | |||
71 | static int | ||
72 | afs_read_footer_v1(struct mtd_info *mtd, u_int *img_start, u_int *iis_start, | ||
73 | u_int off, u_int mask) | ||
74 | { | ||
75 | struct footer_v1 fs; | ||
76 | u_int ptr = off + mtd->erasesize - sizeof(fs); | ||
77 | size_t sz; | ||
78 | int ret; | ||
79 | |||
80 | ret = mtd_read(mtd, ptr, sizeof(fs), &sz, (u_char *)&fs); | ||
81 | if (ret >= 0 && sz != sizeof(fs)) | ||
82 | ret = -EINVAL; | ||
83 | |||
84 | if (ret < 0) { | ||
85 | printk(KERN_ERR "AFS: mtd read failed at 0x%x: %d\n", | ||
86 | ptr, ret); | ||
87 | return ret; | ||
88 | } | ||
89 | |||
90 | /* | ||
91 | * Does it contain the magic number? | ||
92 | */ | ||
93 | if (fs.signature != AFSV1_FOOTER_MAGIC) | ||
94 | return 0; | ||
95 | |||
96 | /* | ||
97 | * Check the checksum. | ||
98 | */ | ||
99 | if (word_sum(&fs, sizeof(fs) / sizeof(u32)) != 0xffffffff) | ||
100 | return 0; | ||
101 | |||
102 | /* | ||
103 | * Don't touch the SIB. | ||
104 | */ | ||
105 | if (fs.type == 2) | ||
106 | return 0; | ||
107 | |||
108 | *iis_start = fs.image_info_base & mask; | ||
109 | *img_start = fs.image_start & mask; | ||
110 | |||
111 | /* | ||
112 | * Check the image info base. This can not | ||
113 | * be located after the footer structure. | ||
114 | */ | ||
115 | if (*iis_start >= ptr) | ||
116 | return 0; | ||
117 | |||
118 | /* | ||
119 | * Check the start of this image. The image | ||
120 | * data can not be located after this block. | ||
121 | */ | ||
122 | if (*img_start > off) | ||
123 | return 0; | ||
124 | |||
125 | return 1; | ||
126 | } | ||
127 | |||
128 | static int | ||
129 | afs_read_iis_v1(struct mtd_info *mtd, struct image_info_v1 *iis, u_int ptr) | ||
130 | { | ||
131 | size_t sz; | ||
132 | int ret, i; | ||
133 | |||
134 | memset(iis, 0, sizeof(*iis)); | ||
135 | ret = mtd_read(mtd, ptr, sizeof(*iis), &sz, (u_char *)iis); | ||
136 | if (ret < 0) | ||
137 | goto failed; | ||
138 | |||
139 | if (sz != sizeof(*iis)) { | ||
140 | ret = -EINVAL; | ||
141 | goto failed; | ||
142 | } | ||
143 | |||
144 | ret = 0; | ||
145 | |||
146 | /* | ||
147 | * Validate the name - it must be NUL terminated. | ||
148 | */ | ||
149 | for (i = 0; i < sizeof(iis->name); i++) | ||
150 | if (iis->name[i] == '\0') | ||
151 | break; | ||
152 | |||
153 | if (i < sizeof(iis->name)) | ||
154 | ret = 1; | ||
155 | |||
156 | return ret; | ||
157 | |||
158 | failed: | ||
159 | printk(KERN_ERR "AFS: mtd read failed at 0x%x: %d\n", | ||
160 | ptr, ret); | ||
161 | return ret; | ||
162 | } | ||
163 | |||
164 | static int parse_afs_partitions(struct mtd_info *mtd, | ||
165 | const struct mtd_partition **pparts, | ||
166 | struct mtd_part_parser_data *data) | ||
167 | { | ||
168 | struct mtd_partition *parts; | ||
169 | u_int mask, off, idx, sz; | ||
170 | int ret = 0; | ||
171 | char *str; | ||
172 | |||
173 | /* | ||
174 | * This is the address mask; we use this to mask off out of | ||
175 | * range address bits. | ||
176 | */ | ||
177 | mask = mtd->size - 1; | ||
178 | |||
179 | /* | ||
180 | * First, calculate the size of the array we need for the | ||
181 | * partition information. We include in this the size of | ||
182 | * the strings. | ||
183 | */ | ||
184 | for (idx = off = sz = 0; off < mtd->size; off += mtd->erasesize) { | ||
185 | struct image_info_v1 iis; | ||
186 | u_int iis_ptr, img_ptr; | ||
187 | |||
188 | ret = afs_read_footer_v1(mtd, &img_ptr, &iis_ptr, off, mask); | ||
189 | if (ret < 0) | ||
190 | break; | ||
191 | if (ret) { | ||
192 | ret = afs_read_iis_v1(mtd, &iis, iis_ptr); | ||
193 | if (ret < 0) | ||
194 | break; | ||
195 | if (ret == 0) | ||
196 | continue; | ||
197 | |||
198 | sz += sizeof(struct mtd_partition); | ||
199 | sz += strlen(iis.name) + 1; | ||
200 | idx += 1; | ||
201 | } | ||
202 | } | ||
203 | |||
204 | if (!sz) | ||
205 | return ret; | ||
206 | |||
207 | parts = kzalloc(sz, GFP_KERNEL); | ||
208 | if (!parts) | ||
209 | return -ENOMEM; | ||
210 | |||
211 | str = (char *)(parts + idx); | ||
212 | |||
213 | /* | ||
214 | * Identify the partitions | ||
215 | */ | ||
216 | for (idx = off = 0; off < mtd->size; off += mtd->erasesize) { | ||
217 | struct image_info_v1 iis; | ||
218 | u_int iis_ptr, img_ptr; | ||
219 | |||
220 | /* Read the footer. */ | ||
221 | ret = afs_read_footer_v1(mtd, &img_ptr, &iis_ptr, off, mask); | ||
222 | if (ret < 0) | ||
223 | break; | ||
224 | if (ret == 0) | ||
225 | continue; | ||
226 | |||
227 | /* Read the image info block */ | ||
228 | ret = afs_read_iis_v1(mtd, &iis, iis_ptr); | ||
229 | if (ret < 0) | ||
230 | break; | ||
231 | if (ret == 0) | ||
232 | continue; | ||
233 | |||
234 | strcpy(str, iis.name); | ||
235 | |||
236 | parts[idx].name = str; | ||
237 | parts[idx].size = (iis.length + mtd->erasesize - 1) & ~(mtd->erasesize - 1); | ||
238 | parts[idx].offset = img_ptr; | ||
239 | parts[idx].mask_flags = 0; | ||
240 | |||
241 | printk(" mtd%d: at 0x%08x, %5lluKiB, %8u, %s\n", | ||
242 | idx, img_ptr, parts[idx].size / 1024, | ||
243 | iis.imageNumber, str); | ||
244 | |||
245 | idx += 1; | ||
246 | str = str + strlen(iis.name) + 1; | ||
247 | } | ||
248 | |||
249 | if (!idx) { | ||
250 | kfree(parts); | ||
251 | parts = NULL; | ||
252 | } | ||
253 | |||
254 | *pparts = parts; | ||
255 | return idx ? idx : ret; | ||
256 | } | ||
257 | |||
258 | static struct mtd_part_parser afs_parser = { | ||
259 | .parse_fn = parse_afs_partitions, | ||
260 | .name = "afs", | ||
261 | }; | ||
262 | module_mtd_part_parser(afs_parser); | ||
263 | |||
264 | MODULE_AUTHOR("ARM Ltd"); | ||
265 | MODULE_DESCRIPTION("ARM Firmware Suite partition parser"); | ||
266 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c index 41d1d3149c61..b2bd04764e95 100644 --- a/drivers/mtd/bcm63xxpart.c +++ b/drivers/mtd/bcm63xxpart.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/vmalloc.h> | 34 | #include <linux/vmalloc.h> |
35 | #include <linux/mtd/mtd.h> | 35 | #include <linux/mtd/mtd.h> |
36 | #include <linux/mtd/partitions.h> | 36 | #include <linux/mtd/partitions.h> |
37 | #include <linux/of.h> | ||
37 | 38 | ||
38 | #define BCM963XX_CFE_BLOCK_SIZE SZ_64K /* always at least 64KiB */ | 39 | #define BCM963XX_CFE_BLOCK_SIZE SZ_64K /* always at least 64KiB */ |
39 | 40 | ||
@@ -93,51 +94,19 @@ static int bcm63xx_read_nvram(struct mtd_info *master, | |||
93 | return 0; | 94 | return 0; |
94 | } | 95 | } |
95 | 96 | ||
96 | static int bcm63xx_read_image_tag(struct mtd_info *master, const char *name, | 97 | static const char * const bcm63xx_cfe_part_types[] = { |
97 | loff_t tag_offset, struct bcm_tag *buf) | 98 | "bcm963xx-imagetag", |
98 | { | 99 | NULL, |
99 | int ret; | 100 | }; |
100 | size_t retlen; | ||
101 | u32 computed_crc; | ||
102 | |||
103 | ret = mtd_read(master, tag_offset, sizeof(*buf), &retlen, (void *)buf); | ||
104 | if (ret) | ||
105 | return ret; | ||
106 | |||
107 | if (retlen != sizeof(*buf)) | ||
108 | return -EIO; | ||
109 | |||
110 | computed_crc = crc32_le(IMAGETAG_CRC_START, (u8 *)buf, | ||
111 | offsetof(struct bcm_tag, header_crc)); | ||
112 | if (computed_crc == buf->header_crc) { | ||
113 | STR_NULL_TERMINATE(buf->board_id); | ||
114 | STR_NULL_TERMINATE(buf->tag_version); | ||
115 | |||
116 | pr_info("%s: CFE image tag found at 0x%llx with version %s, board type %s\n", | ||
117 | name, tag_offset, buf->tag_version, buf->board_id); | ||
118 | |||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | pr_warn("%s: CFE image tag at 0x%llx CRC invalid (expected %08x, actual %08x)\n", | ||
123 | name, tag_offset, buf->header_crc, computed_crc); | ||
124 | return 1; | ||
125 | } | ||
126 | 101 | ||
127 | static int bcm63xx_parse_cfe_nor_partitions(struct mtd_info *master, | 102 | static int bcm63xx_parse_cfe_nor_partitions(struct mtd_info *master, |
128 | const struct mtd_partition **pparts, struct bcm963xx_nvram *nvram) | 103 | const struct mtd_partition **pparts, struct bcm963xx_nvram *nvram) |
129 | { | 104 | { |
130 | /* CFE, NVRAM and global Linux are always present */ | ||
131 | int nrparts = 3, curpart = 0; | ||
132 | struct bcm_tag *buf = NULL; | ||
133 | struct mtd_partition *parts; | 105 | struct mtd_partition *parts; |
134 | int ret; | 106 | int nrparts = 3, curpart = 0; |
135 | unsigned int rootfsaddr, kerneladdr, spareaddr; | ||
136 | unsigned int rootfslen, kernellen, sparelen, totallen; | ||
137 | unsigned int cfelen, nvramlen; | 107 | unsigned int cfelen, nvramlen; |
138 | unsigned int cfe_erasesize; | 108 | unsigned int cfe_erasesize; |
139 | int i; | 109 | int i; |
140 | bool rootfs_first = false; | ||
141 | 110 | ||
142 | cfe_erasesize = max_t(uint32_t, master->erasesize, | 111 | cfe_erasesize = max_t(uint32_t, master->erasesize, |
143 | BCM963XX_CFE_BLOCK_SIZE); | 112 | BCM963XX_CFE_BLOCK_SIZE); |
@@ -146,83 +115,9 @@ static int bcm63xx_parse_cfe_nor_partitions(struct mtd_info *master, | |||
146 | nvramlen = nvram->psi_size * SZ_1K; | 115 | nvramlen = nvram->psi_size * SZ_1K; |
147 | nvramlen = roundup(nvramlen, cfe_erasesize); | 116 | nvramlen = roundup(nvramlen, cfe_erasesize); |
148 | 117 | ||
149 | buf = vmalloc(sizeof(struct bcm_tag)); | ||
150 | if (!buf) | ||
151 | return -ENOMEM; | ||
152 | |||
153 | /* Get the tag */ | ||
154 | ret = bcm63xx_read_image_tag(master, "rootfs", cfelen, buf); | ||
155 | if (!ret) { | ||
156 | STR_NULL_TERMINATE(buf->flash_image_start); | ||
157 | if (kstrtouint(buf->flash_image_start, 10, &rootfsaddr) || | ||
158 | rootfsaddr < BCM963XX_EXTENDED_SIZE) { | ||
159 | pr_err("invalid rootfs address: %*ph\n", | ||
160 | (int)sizeof(buf->flash_image_start), | ||
161 | buf->flash_image_start); | ||
162 | goto invalid_tag; | ||
163 | } | ||
164 | |||
165 | STR_NULL_TERMINATE(buf->kernel_address); | ||
166 | if (kstrtouint(buf->kernel_address, 10, &kerneladdr) || | ||
167 | kerneladdr < BCM963XX_EXTENDED_SIZE) { | ||
168 | pr_err("invalid kernel address: %*ph\n", | ||
169 | (int)sizeof(buf->kernel_address), | ||
170 | buf->kernel_address); | ||
171 | goto invalid_tag; | ||
172 | } | ||
173 | |||
174 | STR_NULL_TERMINATE(buf->kernel_length); | ||
175 | if (kstrtouint(buf->kernel_length, 10, &kernellen)) { | ||
176 | pr_err("invalid kernel length: %*ph\n", | ||
177 | (int)sizeof(buf->kernel_length), | ||
178 | buf->kernel_length); | ||
179 | goto invalid_tag; | ||
180 | } | ||
181 | |||
182 | STR_NULL_TERMINATE(buf->total_length); | ||
183 | if (kstrtouint(buf->total_length, 10, &totallen)) { | ||
184 | pr_err("invalid total length: %*ph\n", | ||
185 | (int)sizeof(buf->total_length), | ||
186 | buf->total_length); | ||
187 | goto invalid_tag; | ||
188 | } | ||
189 | |||
190 | kerneladdr = kerneladdr - BCM963XX_EXTENDED_SIZE; | ||
191 | rootfsaddr = rootfsaddr - BCM963XX_EXTENDED_SIZE; | ||
192 | spareaddr = roundup(totallen, master->erasesize) + cfelen; | ||
193 | |||
194 | if (rootfsaddr < kerneladdr) { | ||
195 | /* default Broadcom layout */ | ||
196 | rootfslen = kerneladdr - rootfsaddr; | ||
197 | rootfs_first = true; | ||
198 | } else { | ||
199 | /* OpenWrt layout */ | ||
200 | rootfsaddr = kerneladdr + kernellen; | ||
201 | rootfslen = spareaddr - rootfsaddr; | ||
202 | } | ||
203 | } else if (ret > 0) { | ||
204 | invalid_tag: | ||
205 | kernellen = 0; | ||
206 | rootfslen = 0; | ||
207 | rootfsaddr = 0; | ||
208 | spareaddr = cfelen; | ||
209 | } else { | ||
210 | goto out; | ||
211 | } | ||
212 | sparelen = master->size - spareaddr - nvramlen; | ||
213 | |||
214 | /* Determine number of partitions */ | ||
215 | if (rootfslen > 0) | ||
216 | nrparts++; | ||
217 | |||
218 | if (kernellen > 0) | ||
219 | nrparts++; | ||
220 | |||
221 | parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL); | 118 | parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL); |
222 | if (!parts) { | 119 | if (!parts) |
223 | ret = -ENOMEM; | 120 | return -ENOMEM; |
224 | goto out; | ||
225 | } | ||
226 | 121 | ||
227 | /* Start building partition list */ | 122 | /* Start building partition list */ |
228 | parts[curpart].name = "CFE"; | 123 | parts[curpart].name = "CFE"; |
@@ -230,30 +125,6 @@ invalid_tag: | |||
230 | parts[curpart].size = cfelen; | 125 | parts[curpart].size = cfelen; |
231 | curpart++; | 126 | curpart++; |
232 | 127 | ||
233 | if (kernellen > 0) { | ||
234 | int kernelpart = curpart; | ||
235 | |||
236 | if (rootfslen > 0 && rootfs_first) | ||
237 | kernelpart++; | ||
238 | parts[kernelpart].name = "kernel"; | ||
239 | parts[kernelpart].offset = kerneladdr; | ||
240 | parts[kernelpart].size = kernellen; | ||
241 | curpart++; | ||
242 | } | ||
243 | |||
244 | if (rootfslen > 0) { | ||
245 | int rootfspart = curpart; | ||
246 | |||
247 | if (kernellen > 0 && rootfs_first) | ||
248 | rootfspart--; | ||
249 | parts[rootfspart].name = "rootfs"; | ||
250 | parts[rootfspart].offset = rootfsaddr; | ||
251 | parts[rootfspart].size = rootfslen; | ||
252 | if (sparelen > 0 && !rootfs_first) | ||
253 | parts[rootfspart].size += sparelen; | ||
254 | curpart++; | ||
255 | } | ||
256 | |||
257 | parts[curpart].name = "nvram"; | 128 | parts[curpart].name = "nvram"; |
258 | parts[curpart].offset = master->size - nvramlen; | 129 | parts[curpart].offset = master->size - nvramlen; |
259 | parts[curpart].size = nvramlen; | 130 | parts[curpart].size = nvramlen; |
@@ -263,22 +134,13 @@ invalid_tag: | |||
263 | parts[curpart].name = "linux"; | 134 | parts[curpart].name = "linux"; |
264 | parts[curpart].offset = cfelen; | 135 | parts[curpart].offset = cfelen; |
265 | parts[curpart].size = master->size - cfelen - nvramlen; | 136 | parts[curpart].size = master->size - cfelen - nvramlen; |
137 | parts[curpart].types = bcm63xx_cfe_part_types; | ||
266 | 138 | ||
267 | for (i = 0; i < nrparts; i++) | 139 | for (i = 0; i < nrparts; i++) |
268 | pr_info("Partition %d is %s offset %llx and length %llx\n", i, | 140 | pr_info("Partition %d is %s offset %llx and length %llx\n", i, |
269 | parts[i].name, parts[i].offset, parts[i].size); | 141 | parts[i].name, parts[i].offset, parts[i].size); |
270 | 142 | ||
271 | pr_info("Spare partition is offset %x and length %x\n", spareaddr, | ||
272 | sparelen); | ||
273 | |||
274 | *pparts = parts; | 143 | *pparts = parts; |
275 | ret = 0; | ||
276 | |||
277 | out: | ||
278 | vfree(buf); | ||
279 | |||
280 | if (ret) | ||
281 | return ret; | ||
282 | 144 | ||
283 | return nrparts; | 145 | return nrparts; |
284 | } | 146 | } |
@@ -311,9 +173,16 @@ out: | |||
311 | return ret; | 173 | return ret; |
312 | }; | 174 | }; |
313 | 175 | ||
176 | static const struct of_device_id parse_bcm63xx_cfe_match_table[] = { | ||
177 | { .compatible = "brcm,bcm963xx-cfe-nor-partitions" }, | ||
178 | {}, | ||
179 | }; | ||
180 | MODULE_DEVICE_TABLE(of, parse_bcm63xx_cfe_match_table); | ||
181 | |||
314 | static struct mtd_part_parser bcm63xx_cfe_parser = { | 182 | static struct mtd_part_parser bcm63xx_cfe_parser = { |
315 | .parse_fn = bcm63xx_parse_cfe_partitions, | 183 | .parse_fn = bcm63xx_parse_cfe_partitions, |
316 | .name = "bcm63xxpart", | 184 | .name = "bcm63xxpart", |
185 | .of_match_table = parse_bcm63xx_cfe_match_table, | ||
317 | }; | 186 | }; |
318 | module_mtd_part_parser(bcm63xx_cfe_parser); | 187 | module_mtd_part_parser(bcm63xx_cfe_parser); |
319 | 188 | ||
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 7b7286b4d81e..c8fa5906bdf9 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c | |||
@@ -869,6 +869,7 @@ static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr | |||
869 | /* Only if there's no operation suspended... */ | 869 | /* Only if there's no operation suspended... */ |
870 | if (mode == FL_READY && chip->oldstate == FL_READY) | 870 | if (mode == FL_READY && chip->oldstate == FL_READY) |
871 | return 0; | 871 | return 0; |
872 | /* fall through */ | ||
872 | 873 | ||
873 | default: | 874 | default: |
874 | sleep: | 875 | sleep: |
@@ -2751,6 +2752,7 @@ static void cfi_amdstd_sync (struct mtd_info *mtd) | |||
2751 | * as the whole point is that nobody can do anything | 2752 | * as the whole point is that nobody can do anything |
2752 | * with the chip now anyway. | 2753 | * with the chip now anyway. |
2753 | */ | 2754 | */ |
2755 | /* fall through */ | ||
2754 | case FL_SYNCING: | 2756 | case FL_SYNCING: |
2755 | mutex_unlock(&chip->mutex); | 2757 | mutex_unlock(&chip->mutex); |
2756 | break; | 2758 | break; |
diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c index 6f16552cd59f..e3b266ee06af 100644 --- a/drivers/mtd/chips/cfi_util.c +++ b/drivers/mtd/chips/cfi_util.c | |||
@@ -109,10 +109,13 @@ map_word cfi_build_cmd(u_long cmd, struct map_info *map, struct cfi_private *cfi | |||
109 | case 8: | 109 | case 8: |
110 | onecmd |= (onecmd << (chip_mode * 32)); | 110 | onecmd |= (onecmd << (chip_mode * 32)); |
111 | #endif | 111 | #endif |
112 | /* fall through */ | ||
112 | case 4: | 113 | case 4: |
113 | onecmd |= (onecmd << (chip_mode * 16)); | 114 | onecmd |= (onecmd << (chip_mode * 16)); |
115 | /* fall through */ | ||
114 | case 2: | 116 | case 2: |
115 | onecmd |= (onecmd << (chip_mode * 8)); | 117 | onecmd |= (onecmd << (chip_mode * 8)); |
118 | /* fall through */ | ||
116 | case 1: | 119 | case 1: |
117 | ; | 120 | ; |
118 | } | 121 | } |
@@ -162,10 +165,13 @@ unsigned long cfi_merge_status(map_word val, struct map_info *map, | |||
162 | case 8: | 165 | case 8: |
163 | res |= (onestat >> (chip_mode * 32)); | 166 | res |= (onestat >> (chip_mode * 32)); |
164 | #endif | 167 | #endif |
168 | /* fall through */ | ||
165 | case 4: | 169 | case 4: |
166 | res |= (onestat >> (chip_mode * 16)); | 170 | res |= (onestat >> (chip_mode * 16)); |
171 | /* fall through */ | ||
167 | case 2: | 172 | case 2: |
168 | res |= (onestat >> (chip_mode * 8)); | 173 | res |= (onestat >> (chip_mode * 8)); |
174 | /* fall through */ | ||
169 | case 1: | 175 | case 1: |
170 | ; | 176 | ; |
171 | } | 177 | } |
diff --git a/drivers/mtd/devices/Kconfig b/drivers/mtd/devices/Kconfig index aa983422aa97..f9258d666846 100644 --- a/drivers/mtd/devices/Kconfig +++ b/drivers/mtd/devices/Kconfig | |||
@@ -207,7 +207,7 @@ comment "Disk-On-Chip Device Drivers" | |||
207 | config MTD_DOCG3 | 207 | config MTD_DOCG3 |
208 | tristate "M-Systems Disk-On-Chip G3" | 208 | tristate "M-Systems Disk-On-Chip G3" |
209 | select BCH | 209 | select BCH |
210 | select BCH_CONST_PARAMS if !MTD_NAND_BCH | 210 | select BCH_CONST_PARAMS if !MTD_NAND_ECC_SW_BCH |
211 | select BITREVERSE | 211 | select BITREVERSE |
212 | help | 212 | help |
213 | This provides an MTD device driver for the M-Systems DiskOnChip | 213 | This provides an MTD device driver for the M-Systems DiskOnChip |
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index 9ee04b5f9311..8a8627c30aed 100644 --- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c | |||
@@ -147,8 +147,10 @@ static int parse_num64(uint64_t *num64, char *token) | |||
147 | switch (token[len - 2]) { | 147 | switch (token[len - 2]) { |
148 | case 'G': | 148 | case 'G': |
149 | shift += 10; | 149 | shift += 10; |
150 | /* fall through */ | ||
150 | case 'M': | 151 | case 'M': |
151 | shift += 10; | 152 | shift += 10; |
153 | /* fall through */ | ||
152 | case 'k': | 154 | case 'k': |
153 | shift += 10; | 155 | shift += 10; |
154 | token[len - 2] = 0; | 156 | token[len - 2] = 0; |
diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c index b13557fe52bd..76a4c73e100e 100644 --- a/drivers/mtd/lpddr/lpddr_cmds.c +++ b/drivers/mtd/lpddr/lpddr_cmds.c | |||
@@ -318,6 +318,7 @@ static int chip_ready(struct map_info *map, struct flchip *chip, int mode) | |||
318 | /* Only if there's no operation suspended... */ | 318 | /* Only if there's no operation suspended... */ |
319 | if (mode == FL_READY && chip->oldstate == FL_READY) | 319 | if (mode == FL_READY && chip->oldstate == FL_READY) |
320 | return 0; | 320 | return 0; |
321 | /* fall through */ | ||
321 | 322 | ||
322 | default: | 323 | default: |
323 | sleep: | 324 | sleep: |
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index e0cf869c8544..544ed1931843 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig | |||
@@ -10,7 +10,7 @@ config MTD_COMPLEX_MAPPINGS | |||
10 | 10 | ||
11 | config MTD_PHYSMAP | 11 | config MTD_PHYSMAP |
12 | tristate "Flash device in physical memory map" | 12 | tristate "Flash device in physical memory map" |
13 | depends on MTD_CFI || MTD_JEDECPROBE || MTD_ROM || MTD_LPDDR | 13 | depends on MTD_CFI || MTD_JEDECPROBE || MTD_ROM || MTD_RAM || MTD_LPDDR |
14 | help | 14 | help |
15 | This provides a 'mapping' driver which allows the NOR Flash and | 15 | This provides a 'mapping' driver which allows the NOR Flash and |
16 | ROM driver code to communicate with chips which are mapped | 16 | ROM driver code to communicate with chips which are mapped |
diff --git a/drivers/mtd/maps/physmap-core.c b/drivers/mtd/maps/physmap-core.c index d9a3e4bebe5d..21b556afc305 100644 --- a/drivers/mtd/maps/physmap-core.c +++ b/drivers/mtd/maps/physmap-core.c | |||
@@ -132,6 +132,8 @@ static void physmap_set_addr_gpios(struct physmap_flash_info *info, | |||
132 | 132 | ||
133 | gpiod_set_value(info->gpios->desc[i], !!(BIT(i) & ofs)); | 133 | gpiod_set_value(info->gpios->desc[i], !!(BIT(i) & ofs)); |
134 | } | 134 | } |
135 | |||
136 | info->gpio_values = ofs; | ||
135 | } | 137 | } |
136 | 138 | ||
137 | #define win_mask(order) (BIT(order) - 1) | 139 | #define win_mask(order) (BIT(order) - 1) |
diff --git a/drivers/mtd/maps/physmap-gemini.c b/drivers/mtd/maps/physmap-gemini.c index 60775b208fc9..a289c8b5cabf 100644 --- a/drivers/mtd/maps/physmap-gemini.c +++ b/drivers/mtd/maps/physmap-gemini.c | |||
@@ -86,7 +86,7 @@ static void gemini_flash_disable_pins(void) | |||
86 | static map_word __xipram gemini_flash_map_read(struct map_info *map, | 86 | static map_word __xipram gemini_flash_map_read(struct map_info *map, |
87 | unsigned long ofs) | 87 | unsigned long ofs) |
88 | { | 88 | { |
89 | map_word __xipram ret; | 89 | map_word ret; |
90 | 90 | ||
91 | gemini_flash_enable_pins(); | 91 | gemini_flash_enable_pins(); |
92 | ret = inline_map_read(map, ofs); | 92 | ret = inline_map_read(map, ofs); |
diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c index aef030ca8601..de4c46318abb 100644 --- a/drivers/mtd/maps/uclinux.c +++ b/drivers/mtd/maps/uclinux.c | |||
@@ -31,13 +31,7 @@ | |||
31 | #define MAP_NAME "ram" | 31 | #define MAP_NAME "ram" |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | /* | 34 | static struct map_info uclinux_ram_map = { |
35 | * Blackfin uses uclinux_ram_map during startup, so it must not be static. | ||
36 | * Provide a dummy declaration to make sparse happy. | ||
37 | */ | ||
38 | extern struct map_info uclinux_ram_map; | ||
39 | |||
40 | struct map_info uclinux_ram_map = { | ||
41 | .name = MAP_NAME, | 35 | .name = MAP_NAME, |
42 | .size = 0, | 36 | .size = 0, |
43 | }; | 37 | }; |
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 37f174ccbcec..dfa241ad018b 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c | |||
@@ -572,7 +572,7 @@ static ssize_t mtd_partition_offset_show(struct device *dev, | |||
572 | { | 572 | { |
573 | struct mtd_info *mtd = dev_get_drvdata(dev); | 573 | struct mtd_info *mtd = dev_get_drvdata(dev); |
574 | struct mtd_part *part = mtd_to_part(mtd); | 574 | struct mtd_part *part = mtd_to_part(mtd); |
575 | return snprintf(buf, PAGE_SIZE, "%lld\n", part->offset); | 575 | return snprintf(buf, PAGE_SIZE, "%llu\n", part->offset); |
576 | } | 576 | } |
577 | 577 | ||
578 | static DEVICE_ATTR(offset, S_IRUGO, mtd_partition_offset_show, NULL); | 578 | static DEVICE_ATTR(offset, S_IRUGO, mtd_partition_offset_show, NULL); |
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 9033215e62ea..495751ed3fd7 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
@@ -2,6 +2,5 @@ config MTD_NAND_CORE | |||
2 | tristate | 2 | tristate |
3 | 3 | ||
4 | source "drivers/mtd/nand/onenand/Kconfig" | 4 | source "drivers/mtd/nand/onenand/Kconfig" |
5 | |||
6 | source "drivers/mtd/nand/raw/Kconfig" | 5 | source "drivers/mtd/nand/raw/Kconfig" |
7 | source "drivers/mtd/nand/spi/Kconfig" | 6 | source "drivers/mtd/nand/spi/Kconfig" |
diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c index 9c9f8936b63b..b6de955ac8bf 100644 --- a/drivers/mtd/nand/core.c +++ b/drivers/mtd/nand/core.c | |||
@@ -174,6 +174,40 @@ int nanddev_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo) | |||
174 | EXPORT_SYMBOL_GPL(nanddev_mtd_erase); | 174 | EXPORT_SYMBOL_GPL(nanddev_mtd_erase); |
175 | 175 | ||
176 | /** | 176 | /** |
177 | * nanddev_mtd_max_bad_blocks() - Get the maximum number of bad eraseblock on | ||
178 | * a specific region of the NAND device | ||
179 | * @mtd: MTD device | ||
180 | * @offs: offset of the NAND region | ||
181 | * @len: length of the NAND region | ||
182 | * | ||
183 | * Default implementation for mtd->_max_bad_blocks(). Only works if | ||
184 | * nand->memorg.max_bad_eraseblocks_per_lun is > 0. | ||
185 | * | ||
186 | * Return: a positive number encoding the maximum number of eraseblocks on a | ||
187 | * portion of memory, a negative error code otherwise. | ||
188 | */ | ||
189 | int nanddev_mtd_max_bad_blocks(struct mtd_info *mtd, loff_t offs, size_t len) | ||
190 | { | ||
191 | struct nand_device *nand = mtd_to_nanddev(mtd); | ||
192 | struct nand_pos pos, end; | ||
193 | unsigned int max_bb = 0; | ||
194 | |||
195 | if (!nand->memorg.max_bad_eraseblocks_per_lun) | ||
196 | return -ENOTSUPP; | ||
197 | |||
198 | nanddev_offs_to_pos(nand, offs, &pos); | ||
199 | nanddev_offs_to_pos(nand, offs + len, &end); | ||
200 | |||
201 | for (nanddev_offs_to_pos(nand, offs, &pos); | ||
202 | nanddev_pos_cmp(&pos, &end) < 0; | ||
203 | nanddev_pos_next_lun(nand, &pos)) | ||
204 | max_bb += nand->memorg.max_bad_eraseblocks_per_lun; | ||
205 | |||
206 | return max_bb; | ||
207 | } | ||
208 | EXPORT_SYMBOL_GPL(nanddev_mtd_max_bad_blocks); | ||
209 | |||
210 | /** | ||
177 | * nanddev_init() - Initialize a NAND device | 211 | * nanddev_init() - Initialize a NAND device |
178 | * @nand: NAND device | 212 | * @nand: NAND device |
179 | * @ops: NAND device operations | 213 | * @ops: NAND device operations |
diff --git a/drivers/mtd/nand/onenand/onenand_base.c b/drivers/mtd/nand/onenand/onenand_base.c index 4ca4b194e7d7..f41d76248550 100644 --- a/drivers/mtd/nand/onenand/onenand_base.c +++ b/drivers/mtd/nand/onenand/onenand_base.c | |||
@@ -2458,7 +2458,7 @@ static int onenand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) | |||
2458 | bbm->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); | 2458 | bbm->bbt[block >> 2] |= 0x01 << ((block & 0x03) << 1); |
2459 | 2459 | ||
2460 | /* We write two bytes, so we don't have to mess with 16-bit access */ | 2460 | /* We write two bytes, so we don't have to mess with 16-bit access */ |
2461 | ofs += mtd->oobsize + (bbm->badblockpos & ~0x01); | 2461 | ofs += mtd->oobsize + (this->badblockpos & ~0x01); |
2462 | /* FIXME : What to do when marking SLC block in partition | 2462 | /* FIXME : What to do when marking SLC block in partition |
2463 | * with MLC erasesize? For now, it is not advisable to | 2463 | * with MLC erasesize? For now, it is not advisable to |
2464 | * create partitions containing both SLC and MLC regions. | 2464 | * create partitions containing both SLC and MLC regions. |
@@ -3967,6 +3967,9 @@ int onenand_scan(struct mtd_info *mtd, int maxchips) | |||
3967 | if (!(this->options & ONENAND_SKIP_INITIAL_UNLOCKING)) | 3967 | if (!(this->options & ONENAND_SKIP_INITIAL_UNLOCKING)) |
3968 | this->unlock_all(mtd); | 3968 | this->unlock_all(mtd); |
3969 | 3969 | ||
3970 | /* Set the bad block marker position */ | ||
3971 | this->badblockpos = ONENAND_BADBLOCK_POS; | ||
3972 | |||
3970 | ret = this->scan_bbt(mtd); | 3973 | ret = this->scan_bbt(mtd); |
3971 | if ((!FLEXONENAND(this)) || ret) | 3974 | if ((!FLEXONENAND(this)) || ret) |
3972 | return ret; | 3975 | return ret; |
diff --git a/drivers/mtd/nand/onenand/onenand_bbt.c b/drivers/mtd/nand/onenand/onenand_bbt.c index dde20487937d..57c31c81be18 100644 --- a/drivers/mtd/nand/onenand/onenand_bbt.c +++ b/drivers/mtd/nand/onenand/onenand_bbt.c | |||
@@ -190,9 +190,6 @@ static int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) | |||
190 | if (!bbm->bbt) | 190 | if (!bbm->bbt) |
191 | return -ENOMEM; | 191 | return -ENOMEM; |
192 | 192 | ||
193 | /* Set the bad block position */ | ||
194 | bbm->badblockpos = ONENAND_BADBLOCK_POS; | ||
195 | |||
196 | /* Set erase shift */ | 193 | /* Set erase shift */ |
197 | bbm->bbt_erase_shift = this->erase_shift; | 194 | bbm->bbt_erase_shift = this->erase_shift; |
198 | 195 | ||
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index e604625e2dfa..0500c42f31cb 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig | |||
@@ -1,34 +1,29 @@ | |||
1 | config MTD_NAND_ECC | 1 | config MTD_NAND_ECC_SW_HAMMING |
2 | tristate | 2 | tristate |
3 | 3 | ||
4 | config MTD_NAND_ECC_SMC | 4 | config MTD_NAND_ECC_SW_HAMMING_SMC |
5 | bool "NAND ECC Smart Media byte order" | 5 | bool "NAND ECC Smart Media byte order" |
6 | depends on MTD_NAND_ECC | 6 | depends on MTD_NAND_ECC_SW_HAMMING |
7 | default n | 7 | default n |
8 | help | 8 | help |
9 | Software ECC according to the Smart Media Specification. | 9 | Software ECC according to the Smart Media Specification. |
10 | The original Linux implementation had byte 0 and 1 swapped. | 10 | The original Linux implementation had byte 0 and 1 swapped. |
11 | 11 | ||
12 | 12 | menuconfig MTD_RAW_NAND | |
13 | menuconfig MTD_NAND | ||
14 | tristate "Raw/Parallel NAND Device Support" | 13 | tristate "Raw/Parallel NAND Device Support" |
15 | depends on MTD | 14 | depends on MTD |
16 | select MTD_NAND_ECC | 15 | select MTD_NAND_CORE |
16 | select MTD_NAND_ECC_SW_HAMMING | ||
17 | help | 17 | help |
18 | This enables support for accessing all type of raw/parallel | 18 | This enables support for accessing all type of raw/parallel |
19 | NAND flash devices. For further information see | 19 | NAND flash devices. For further information see |
20 | <http://www.linux-mtd.infradead.org/doc/nand.html>. | 20 | <http://www.linux-mtd.infradead.org/doc/nand.html>. |
21 | 21 | ||
22 | if MTD_NAND | 22 | if MTD_RAW_NAND |
23 | 23 | ||
24 | config MTD_NAND_BCH | 24 | config MTD_NAND_ECC_SW_BCH |
25 | tristate | ||
26 | select BCH | ||
27 | depends on MTD_NAND_ECC_BCH | ||
28 | default MTD_NAND | ||
29 | |||
30 | config MTD_NAND_ECC_BCH | ||
31 | bool "Support software BCH ECC" | 25 | bool "Support software BCH ECC" |
26 | select BCH | ||
32 | default n | 27 | default n |
33 | help | 28 | help |
34 | This enables support for software BCH error correction. Binary BCH | 29 | This enables support for software BCH error correction. Binary BCH |
@@ -36,15 +31,13 @@ config MTD_NAND_ECC_BCH | |||
36 | ECC codes. They are used with NAND devices requiring more than 1 bit | 31 | ECC codes. They are used with NAND devices requiring more than 1 bit |
37 | of error correction. | 32 | of error correction. |
38 | 33 | ||
39 | config MTD_SM_COMMON | 34 | comment "Raw/parallel NAND flash controllers" |
40 | tristate | ||
41 | default n | ||
42 | 35 | ||
43 | config MTD_NAND_DENALI | 36 | config MTD_NAND_DENALI |
44 | tristate | 37 | tristate |
45 | 38 | ||
46 | config MTD_NAND_DENALI_PCI | 39 | config MTD_NAND_DENALI_PCI |
47 | tristate "Support Denali NAND controller on Intel Moorestown" | 40 | tristate "Denali NAND controller on Intel Moorestown" |
48 | select MTD_NAND_DENALI | 41 | select MTD_NAND_DENALI |
49 | depends on PCI | 42 | depends on PCI |
50 | help | 43 | help |
@@ -52,31 +45,22 @@ config MTD_NAND_DENALI_PCI | |||
52 | Denali NAND controller core. | 45 | Denali NAND controller core. |
53 | 46 | ||
54 | config MTD_NAND_DENALI_DT | 47 | config MTD_NAND_DENALI_DT |
55 | tristate "Support Denali NAND controller as a DT device" | 48 | tristate "Denali NAND controller as a DT device" |
56 | select MTD_NAND_DENALI | 49 | select MTD_NAND_DENALI |
57 | depends on HAS_DMA && HAVE_CLK && OF | 50 | depends on HAS_DMA && HAVE_CLK && OF |
58 | help | 51 | help |
59 | Enable the driver for NAND flash on platforms using a Denali NAND | 52 | Enable the driver for NAND flash on platforms using a Denali NAND |
60 | controller as a DT device. | 53 | controller as a DT device. |
61 | 54 | ||
62 | config MTD_NAND_GPIO | ||
63 | tristate "GPIO assisted NAND Flash driver" | ||
64 | depends on GPIOLIB || COMPILE_TEST | ||
65 | depends on HAS_IOMEM | ||
66 | help | ||
67 | This enables a NAND flash driver where control signals are | ||
68 | connected to GPIO pins, and commands and data are communicated | ||
69 | via a memory mapped interface. | ||
70 | |||
71 | config MTD_NAND_AMS_DELTA | 55 | config MTD_NAND_AMS_DELTA |
72 | tristate "NAND Flash device on Amstrad E3" | 56 | tristate "Amstrad E3 NAND controller" |
73 | depends on MACH_AMS_DELTA || COMPILE_TEST | 57 | depends on MACH_AMS_DELTA || COMPILE_TEST |
74 | default y | 58 | default y |
75 | help | 59 | help |
76 | Support for NAND flash on Amstrad E3 (Delta). | 60 | Support for NAND flash on Amstrad E3 (Delta). |
77 | 61 | ||
78 | config MTD_NAND_OMAP2 | 62 | config MTD_NAND_OMAP2 |
79 | tristate "NAND Flash device on OMAP2, OMAP3, OMAP4 and Keystone" | 63 | tristate "OMAP2, OMAP3, OMAP4 and Keystone NAND controller" |
80 | depends on ARCH_OMAP2PLUS || ARCH_KEYSTONE || COMPILE_TEST | 64 | depends on ARCH_OMAP2PLUS || ARCH_KEYSTONE || COMPILE_TEST |
81 | depends on HAS_IOMEM | 65 | depends on HAS_IOMEM |
82 | help | 66 | help |
@@ -98,18 +82,6 @@ config MTD_NAND_OMAP_BCH | |||
98 | config MTD_NAND_OMAP_BCH_BUILD | 82 | config MTD_NAND_OMAP_BCH_BUILD |
99 | def_tristate MTD_NAND_OMAP2 && MTD_NAND_OMAP_BCH | 83 | def_tristate MTD_NAND_OMAP2 && MTD_NAND_OMAP_BCH |
100 | 84 | ||
101 | config MTD_NAND_RICOH | ||
102 | tristate "Ricoh xD card reader" | ||
103 | default n | ||
104 | depends on PCI | ||
105 | select MTD_SM_COMMON | ||
106 | help | ||
107 | Enable support for Ricoh R5C852 xD card reader | ||
108 | You also need to enable ether | ||
109 | NAND SSFDC (SmartMedia) read only translation layer' or new | ||
110 | expermental, readwrite | ||
111 | 'SmartMedia/xD new translation layer' | ||
112 | |||
113 | config MTD_NAND_AU1550 | 85 | config MTD_NAND_AU1550 |
114 | tristate "Au1550/1200 NAND support" | 86 | tristate "Au1550/1200 NAND support" |
115 | depends on MIPS_ALCHEMY | 87 | depends on MIPS_ALCHEMY |
@@ -117,8 +89,15 @@ config MTD_NAND_AU1550 | |||
117 | This enables the driver for the NAND flash controller on the | 89 | This enables the driver for the NAND flash controller on the |
118 | AMD/Alchemy 1550 SOC. | 90 | AMD/Alchemy 1550 SOC. |
119 | 91 | ||
92 | config MTD_NAND_NDFC | ||
93 | tristate "IBM/MCC 4xx NAND controller" | ||
94 | depends on 4xx | ||
95 | select MTD_NAND_ECC_SW_HAMMING_SMC | ||
96 | help | ||
97 | NDFC Nand Flash Controllers are integrated in IBM/AMCC's 4xx SoCs | ||
98 | |||
120 | config MTD_NAND_S3C2410 | 99 | config MTD_NAND_S3C2410 |
121 | tristate "NAND Flash support for Samsung S3C SoCs" | 100 | tristate "Samsung S3C NAND controller" |
122 | depends on ARCH_S3C24XX || ARCH_S3C64XX | 101 | depends on ARCH_S3C24XX || ARCH_S3C64XX |
123 | help | 102 | help |
124 | This enables the NAND flash controller on the S3C24xx and S3C64xx | 103 | This enables the NAND flash controller on the S3C24xx and S3C64xx |
@@ -128,18 +107,11 @@ config MTD_NAND_S3C2410 | |||
128 | must advertise a platform_device for the driver to attach. | 107 | must advertise a platform_device for the driver to attach. |
129 | 108 | ||
130 | config MTD_NAND_S3C2410_DEBUG | 109 | config MTD_NAND_S3C2410_DEBUG |
131 | bool "Samsung S3C NAND driver debug" | 110 | bool "Samsung S3C NAND controller debug" |
132 | depends on MTD_NAND_S3C2410 | 111 | depends on MTD_NAND_S3C2410 |
133 | help | 112 | help |
134 | Enable debugging of the S3C NAND driver | 113 | Enable debugging of the S3C NAND driver |
135 | 114 | ||
136 | config MTD_NAND_NDFC | ||
137 | tristate "NDFC NanD Flash Controller" | ||
138 | depends on 4xx | ||
139 | select MTD_NAND_ECC_SMC | ||
140 | help | ||
141 | NDFC Nand Flash Controllers are integrated in IBM/AMCC's 4xx SoCs | ||
142 | |||
143 | config MTD_NAND_S3C2410_CLKSTOP | 115 | config MTD_NAND_S3C2410_CLKSTOP |
144 | bool "Samsung S3C NAND IDLE clock stop" | 116 | bool "Samsung S3C NAND IDLE clock stop" |
145 | depends on MTD_NAND_S3C2410 | 117 | depends on MTD_NAND_S3C2410 |
@@ -151,89 +123,19 @@ config MTD_NAND_S3C2410_CLKSTOP | |||
151 | approximately 5mA of power when there is nothing happening. | 123 | approximately 5mA of power when there is nothing happening. |
152 | 124 | ||
153 | config MTD_NAND_TANGO | 125 | config MTD_NAND_TANGO |
154 | tristate "NAND Flash support for Tango chips" | 126 | tristate "Tango NAND controller" |
155 | depends on ARCH_TANGO || COMPILE_TEST | 127 | depends on ARCH_TANGO || COMPILE_TEST |
156 | depends on HAS_IOMEM | 128 | depends on HAS_IOMEM |
157 | help | 129 | help |
158 | Enables the NAND Flash controller on Tango chips. | 130 | Enables the NAND Flash controller on Tango chips. |
159 | 131 | ||
160 | config MTD_NAND_DISKONCHIP | ||
161 | tristate "DiskOnChip 2000, Millennium and Millennium Plus (NAND reimplementation)" | ||
162 | depends on HAS_IOMEM | ||
163 | select REED_SOLOMON | ||
164 | select REED_SOLOMON_DEC16 | ||
165 | help | ||
166 | This is a reimplementation of M-Systems DiskOnChip 2000, | ||
167 | Millennium and Millennium Plus as a standard NAND device driver, | ||
168 | as opposed to the earlier self-contained MTD device drivers. | ||
169 | This should enable, among other things, proper JFFS2 operation on | ||
170 | these devices. | ||
171 | |||
172 | config MTD_NAND_DISKONCHIP_PROBE_ADVANCED | ||
173 | bool "Advanced detection options for DiskOnChip" | ||
174 | depends on MTD_NAND_DISKONCHIP | ||
175 | help | ||
176 | This option allows you to specify nonstandard address at which to | ||
177 | probe for a DiskOnChip, or to change the detection options. You | ||
178 | are unlikely to need any of this unless you are using LinuxBIOS. | ||
179 | Say 'N'. | ||
180 | |||
181 | config MTD_NAND_DISKONCHIP_PROBE_ADDRESS | ||
182 | hex "Physical address of DiskOnChip" if MTD_NAND_DISKONCHIP_PROBE_ADVANCED | ||
183 | depends on MTD_NAND_DISKONCHIP | ||
184 | default "0" | ||
185 | help | ||
186 | By default, the probe for DiskOnChip devices will look for a | ||
187 | DiskOnChip at every multiple of 0x2000 between 0xC8000 and 0xEE000. | ||
188 | This option allows you to specify a single address at which to probe | ||
189 | for the device, which is useful if you have other devices in that | ||
190 | range which get upset when they are probed. | ||
191 | |||
192 | (Note that on PowerPC, the normal probe will only check at | ||
193 | 0xE4000000.) | ||
194 | |||
195 | Normally, you should leave this set to zero, to allow the probe at | ||
196 | the normal addresses. | ||
197 | |||
198 | config MTD_NAND_DISKONCHIP_PROBE_HIGH | ||
199 | bool "Probe high addresses" | ||
200 | depends on MTD_NAND_DISKONCHIP_PROBE_ADVANCED | ||
201 | help | ||
202 | By default, the probe for DiskOnChip devices will look for a | ||
203 | DiskOnChip at every multiple of 0x2000 between 0xC8000 and 0xEE000. | ||
204 | This option changes to make it probe between 0xFFFC8000 and | ||
205 | 0xFFFEE000. Unless you are using LinuxBIOS, this is unlikely to be | ||
206 | useful to you. Say 'N'. | ||
207 | |||
208 | config MTD_NAND_DISKONCHIP_BBTWRITE | ||
209 | bool "Allow BBT writes on DiskOnChip Millennium and 2000TSOP" | ||
210 | depends on MTD_NAND_DISKONCHIP | ||
211 | help | ||
212 | On DiskOnChip devices shipped with the INFTL filesystem (Millennium | ||
213 | and 2000 TSOP/Alon), Linux reserves some space at the end of the | ||
214 | device for the Bad Block Table (BBT). If you have existing INFTL | ||
215 | data on your device (created by non-Linux tools such as M-Systems' | ||
216 | DOS drivers), your data might overlap the area Linux wants to use for | ||
217 | the BBT. If this is a concern for you, leave this option disabled and | ||
218 | Linux will not write BBT data into this area. | ||
219 | The downside of leaving this option disabled is that if bad blocks | ||
220 | are detected by Linux, they will not be recorded in the BBT, which | ||
221 | could cause future problems. | ||
222 | Once you enable this option, new filesystems (INFTL or others, created | ||
223 | in Linux or other operating systems) will not use the reserved area. | ||
224 | The only reason not to enable this option is to prevent damage to | ||
225 | preexisting filesystems. | ||
226 | Even if you leave this disabled, you can enable BBT writes at module | ||
227 | load time (assuming you build diskonchip as a module) with the module | ||
228 | parameter "inftl_bbt_write=1". | ||
229 | |||
230 | config MTD_NAND_SHARPSL | 132 | config MTD_NAND_SHARPSL |
231 | tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)" | 133 | tristate "Sharp SL Series (C7xx + others) NAND controller" |
232 | depends on ARCH_PXA || COMPILE_TEST | 134 | depends on ARCH_PXA || COMPILE_TEST |
233 | depends on HAS_IOMEM | 135 | depends on HAS_IOMEM |
234 | 136 | ||
235 | config MTD_NAND_CAFE | 137 | config MTD_NAND_CAFE |
236 | tristate "NAND support for OLPC CAFÉ chip" | 138 | tristate "OLPC CAFÉ NAND controller" |
237 | depends on PCI | 139 | depends on PCI |
238 | select REED_SOLOMON | 140 | select REED_SOLOMON |
239 | select REED_SOLOMON_DEC16 | 141 | select REED_SOLOMON_DEC16 |
@@ -242,7 +144,7 @@ config MTD_NAND_CAFE | |||
242 | laptop. | 144 | laptop. |
243 | 145 | ||
244 | config MTD_NAND_CS553X | 146 | config MTD_NAND_CS553X |
245 | tristate "NAND support for CS5535/CS5536 (AMD Geode companion chip)" | 147 | tristate "CS5535/CS5536 (AMD Geode companion) NAND controller" |
246 | depends on X86_32 | 148 | depends on X86_32 |
247 | depends on !UML && HAS_IOMEM | 149 | depends on !UML && HAS_IOMEM |
248 | help | 150 | help |
@@ -256,7 +158,7 @@ config MTD_NAND_CS553X | |||
256 | If you say "m", the module will be called cs553x_nand. | 158 | If you say "m", the module will be called cs553x_nand. |
257 | 159 | ||
258 | config MTD_NAND_ATMEL | 160 | config MTD_NAND_ATMEL |
259 | tristate "Support for NAND Flash / SmartMedia on AT91" | 161 | tristate "Atmel AT91 NAND Flash/SmartMedia NAND controller" |
260 | depends on ARCH_AT91 || COMPILE_TEST | 162 | depends on ARCH_AT91 || COMPILE_TEST |
261 | depends on HAS_IOMEM | 163 | depends on HAS_IOMEM |
262 | select GENERIC_ALLOCATOR | 164 | select GENERIC_ALLOCATOR |
@@ -265,8 +167,17 @@ config MTD_NAND_ATMEL | |||
265 | Enables support for NAND Flash / Smart Media Card interface | 167 | Enables support for NAND Flash / Smart Media Card interface |
266 | on Atmel AT91 processors. | 168 | on Atmel AT91 processors. |
267 | 169 | ||
170 | config MTD_NAND_ORION | ||
171 | tristate "Marvell Orion NAND controller" | ||
172 | depends on PLAT_ORION | ||
173 | help | ||
174 | This enables the NAND flash controller on Orion machines. | ||
175 | |||
176 | No board specific support is done by this driver, each board | ||
177 | must advertise a platform_device for the driver to attach. | ||
178 | |||
268 | config MTD_NAND_MARVELL | 179 | config MTD_NAND_MARVELL |
269 | tristate "NAND controller support on Marvell boards" | 180 | tristate "Marvell EBU NAND controller" |
270 | depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU || \ | 181 | depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU || \ |
271 | COMPILE_TEST | 182 | COMPILE_TEST |
272 | depends on HAS_IOMEM | 183 | depends on HAS_IOMEM |
@@ -278,7 +189,7 @@ config MTD_NAND_MARVELL | |||
278 | - 64-bit Aramda platforms (7k, 8k) (NFCv2) | 189 | - 64-bit Aramda platforms (7k, 8k) (NFCv2) |
279 | 190 | ||
280 | config MTD_NAND_SLC_LPC32XX | 191 | config MTD_NAND_SLC_LPC32XX |
281 | tristate "NXP LPC32xx SLC Controller" | 192 | tristate "NXP LPC32xx SLC NAND controller" |
282 | depends on ARCH_LPC32XX || COMPILE_TEST | 193 | depends on ARCH_LPC32XX || COMPILE_TEST |
283 | depends on HAS_IOMEM | 194 | depends on HAS_IOMEM |
284 | help | 195 | help |
@@ -290,7 +201,7 @@ config MTD_NAND_SLC_LPC32XX | |||
290 | by the SLC NAND controller. | 201 | by the SLC NAND controller. |
291 | 202 | ||
292 | config MTD_NAND_MLC_LPC32XX | 203 | config MTD_NAND_MLC_LPC32XX |
293 | tristate "NXP LPC32xx MLC Controller" | 204 | tristate "NXP LPC32xx MLC NAND controller" |
294 | depends on ARCH_LPC32XX || COMPILE_TEST | 205 | depends on ARCH_LPC32XX || COMPILE_TEST |
295 | depends on HAS_IOMEM | 206 | depends on HAS_IOMEM |
296 | help | 207 | help |
@@ -302,38 +213,23 @@ config MTD_NAND_MLC_LPC32XX | |||
302 | by the MLC NAND controller. | 213 | by the MLC NAND controller. |
303 | 214 | ||
304 | config MTD_NAND_CM_X270 | 215 | config MTD_NAND_CM_X270 |
305 | tristate "Support for NAND Flash on CM-X270 modules" | 216 | tristate "CM-X270 modules NAND controller" |
306 | depends on MACH_ARMCORE | 217 | depends on MACH_ARMCORE |
307 | 218 | ||
308 | config MTD_NAND_PASEMI | 219 | config MTD_NAND_PASEMI |
309 | tristate "NAND support for PA Semi PWRficient" | 220 | tristate "PA Semi PWRficient NAND controller" |
310 | depends on PPC_PASEMI | 221 | depends on PPC_PASEMI |
311 | help | 222 | help |
312 | Enables support for NAND Flash interface on PA Semi PWRficient | 223 | Enables support for NAND Flash interface on PA Semi PWRficient |
313 | based boards | 224 | based boards |
314 | 225 | ||
315 | config MTD_NAND_TMIO | 226 | config MTD_NAND_TMIO |
316 | tristate "NAND Flash device on Toshiba Mobile IO Controller" | 227 | tristate "Toshiba Mobile IO NAND controller" |
317 | depends on MFD_TMIO | 228 | depends on MFD_TMIO |
318 | help | 229 | help |
319 | Support for NAND flash connected to a Toshiba Mobile IO | 230 | Support for NAND flash connected to a Toshiba Mobile IO |
320 | Controller in some PDAs, including the Sharp SL6000x. | 231 | Controller in some PDAs, including the Sharp SL6000x. |
321 | 232 | ||
322 | config MTD_NAND_NANDSIM | ||
323 | tristate "Support for NAND Flash Simulator" | ||
324 | help | ||
325 | The simulator may simulate various NAND flash chips for the | ||
326 | MTD nand layer. | ||
327 | |||
328 | config MTD_NAND_GPMI_NAND | ||
329 | tristate "GPMI NAND Flash Controller driver" | ||
330 | depends on MXS_DMA | ||
331 | help | ||
332 | Enables NAND Flash support for IMX23, IMX28 or IMX6. | ||
333 | The GPMI controller is very powerful, with the help of BCH | ||
334 | module, it can do the hardware ECC. The GPMI supports several | ||
335 | NAND flashs at the same time. | ||
336 | |||
337 | config MTD_NAND_BRCMNAND | 233 | config MTD_NAND_BRCMNAND |
338 | tristate "Broadcom STB NAND controller" | 234 | tristate "Broadcom STB NAND controller" |
339 | depends on ARM || ARM64 || MIPS || COMPILE_TEST | 235 | depends on ARM || ARM64 || MIPS || COMPILE_TEST |
@@ -344,7 +240,7 @@ config MTD_NAND_BRCMNAND | |||
344 | BCM3xxx, BCM63xxx, iProc/Cygnus and more. | 240 | BCM3xxx, BCM63xxx, iProc/Cygnus and more. |
345 | 241 | ||
346 | config MTD_NAND_BCM47XXNFLASH | 242 | config MTD_NAND_BCM47XXNFLASH |
347 | tristate "Support for NAND flash on BCM4706 BCMA bus" | 243 | tristate "BCM4706 BCMA NAND controller" |
348 | depends on BCMA_NFLASH | 244 | depends on BCMA_NFLASH |
349 | depends on BCMA | 245 | depends on BCMA |
350 | help | 246 | help |
@@ -352,32 +248,31 @@ config MTD_NAND_BCM47XXNFLASH | |||
352 | registered by bcma as platform devices. This enables driver for | 248 | registered by bcma as platform devices. This enables driver for |
353 | NAND flash memories. For now only BCM4706 is supported. | 249 | NAND flash memories. For now only BCM4706 is supported. |
354 | 250 | ||
355 | config MTD_NAND_PLATFORM | 251 | config MTD_NAND_OXNAS |
356 | tristate "Support for generic platform NAND driver" | 252 | tristate "Oxford Semiconductor NAND controller" |
253 | depends on ARCH_OXNAS || COMPILE_TEST | ||
357 | depends on HAS_IOMEM | 254 | depends on HAS_IOMEM |
358 | help | 255 | help |
359 | This implements a generic NAND driver for on-SOC platform | 256 | This enables the NAND flash controller on Oxford Semiconductor SoCs. |
360 | devices. You will need to provide platform-specific functions | ||
361 | via platform_data. | ||
362 | 257 | ||
363 | config MTD_NAND_ORION | 258 | config MTD_NAND_MPC5121_NFC |
364 | tristate "NAND Flash support for Marvell Orion SoC" | 259 | tristate "MPC5121 NAND controller" |
365 | depends on PLAT_ORION | 260 | depends on PPC_MPC512x |
366 | help | 261 | help |
367 | This enables the NAND flash controller on Orion machines. | 262 | This enables the driver for the NAND flash controller on the |
368 | 263 | MPC5121 SoC. | |
369 | No board specific support is done by this driver, each board | ||
370 | must advertise a platform_device for the driver to attach. | ||
371 | 264 | ||
372 | config MTD_NAND_OXNAS | 265 | config MTD_NAND_GPMI_NAND |
373 | tristate "NAND Flash support for Oxford Semiconductor SoC" | 266 | tristate "Freescale GPMI NAND controller" |
374 | depends on ARCH_OXNAS || COMPILE_TEST | 267 | depends on MXS_DMA |
375 | depends on HAS_IOMEM | ||
376 | help | 268 | help |
377 | This enables the NAND flash controller on Oxford Semiconductor SoCs. | 269 | Enables NAND Flash support for IMX23, IMX28 or IMX6. |
270 | The GPMI controller is very powerful, with the help of BCH | ||
271 | module, it can do the hardware ECC. The GPMI supports several | ||
272 | NAND flashs at the same time. | ||
378 | 273 | ||
379 | config MTD_NAND_FSL_ELBC | 274 | config MTD_NAND_FSL_ELBC |
380 | tristate "NAND support for Freescale eLBC controllers" | 275 | tristate "Freescale eLBC NAND controller" |
381 | depends on FSL_SOC | 276 | depends on FSL_SOC |
382 | select FSL_LBC | 277 | select FSL_LBC |
383 | help | 278 | help |
@@ -387,7 +282,7 @@ config MTD_NAND_FSL_ELBC | |||
387 | external NAND devices. | 282 | external NAND devices. |
388 | 283 | ||
389 | config MTD_NAND_FSL_IFC | 284 | config MTD_NAND_FSL_IFC |
390 | tristate "NAND support for Freescale IFC controller" | 285 | tristate "Freescale IFC NAND controller" |
391 | depends on FSL_SOC || ARCH_LAYERSCAPE || SOC_LS1021A || COMPILE_TEST | 286 | depends on FSL_SOC || ARCH_LAYERSCAPE || SOC_LS1021A || COMPILE_TEST |
392 | depends on HAS_IOMEM | 287 | depends on HAS_IOMEM |
393 | select FSL_IFC | 288 | select FSL_IFC |
@@ -399,22 +294,15 @@ config MTD_NAND_FSL_IFC | |||
399 | external NAND devices. | 294 | external NAND devices. |
400 | 295 | ||
401 | config MTD_NAND_FSL_UPM | 296 | config MTD_NAND_FSL_UPM |
402 | tristate "Support for NAND on Freescale UPM" | 297 | tristate "Freescale UPM NAND controller" |
403 | depends on PPC_83xx || PPC_85xx | 298 | depends on PPC_83xx || PPC_85xx |
404 | select FSL_LBC | 299 | select FSL_LBC |
405 | help | 300 | help |
406 | Enables support for NAND Flash chips wired onto Freescale PowerPC | 301 | Enables support for NAND Flash chips wired onto Freescale PowerPC |
407 | processor localbus with User-Programmable Machine support. | 302 | processor localbus with User-Programmable Machine support. |
408 | 303 | ||
409 | config MTD_NAND_MPC5121_NFC | ||
410 | tristate "MPC5121 built-in NAND Flash Controller support" | ||
411 | depends on PPC_MPC512x | ||
412 | help | ||
413 | This enables the driver for the NAND flash controller on the | ||
414 | MPC5121 SoC. | ||
415 | |||
416 | config MTD_NAND_VF610_NFC | 304 | config MTD_NAND_VF610_NFC |
417 | tristate "Support for Freescale NFC for VF610/MPC5125" | 305 | tristate "Freescale VF610/MPC5125 NAND controller" |
418 | depends on (SOC_VF610 || COMPILE_TEST) | 306 | depends on (SOC_VF610 || COMPILE_TEST) |
419 | depends on HAS_IOMEM | 307 | depends on HAS_IOMEM |
420 | help | 308 | help |
@@ -426,7 +314,7 @@ config MTD_NAND_VF610_NFC | |||
426 | device tree. | 314 | device tree. |
427 | 315 | ||
428 | config MTD_NAND_MXC | 316 | config MTD_NAND_MXC |
429 | tristate "MXC NAND support" | 317 | tristate "Freescale MXC NAND controller" |
430 | depends on ARCH_MXC || COMPILE_TEST | 318 | depends on ARCH_MXC || COMPILE_TEST |
431 | depends on HAS_IOMEM | 319 | depends on HAS_IOMEM |
432 | help | 320 | help |
@@ -434,7 +322,7 @@ config MTD_NAND_MXC | |||
434 | MXC processors. | 322 | MXC processors. |
435 | 323 | ||
436 | config MTD_NAND_SH_FLCTL | 324 | config MTD_NAND_SH_FLCTL |
437 | tristate "Support for NAND on Renesas SuperH FLCTL" | 325 | tristate "Renesas SuperH FLCTL NAND controller" |
438 | depends on SUPERH || COMPILE_TEST | 326 | depends on SUPERH || COMPILE_TEST |
439 | depends on HAS_IOMEM | 327 | depends on HAS_IOMEM |
440 | help | 328 | help |
@@ -442,7 +330,7 @@ config MTD_NAND_SH_FLCTL | |||
442 | for NAND Flash using FLCTL. | 330 | for NAND Flash using FLCTL. |
443 | 331 | ||
444 | config MTD_NAND_DAVINCI | 332 | config MTD_NAND_DAVINCI |
445 | tristate "Support NAND on DaVinci/Keystone SoC" | 333 | tristate "DaVinci/Keystone NAND controller" |
446 | depends on ARCH_DAVINCI || (ARCH_KEYSTONE && TI_AEMIF) || COMPILE_TEST | 334 | depends on ARCH_DAVINCI || (ARCH_KEYSTONE && TI_AEMIF) || COMPILE_TEST |
447 | depends on HAS_IOMEM | 335 | depends on HAS_IOMEM |
448 | help | 336 | help |
@@ -450,42 +338,30 @@ config MTD_NAND_DAVINCI | |||
450 | DaVinci/Keystone processors. | 338 | DaVinci/Keystone processors. |
451 | 339 | ||
452 | config MTD_NAND_TXX9NDFMC | 340 | config MTD_NAND_TXX9NDFMC |
453 | tristate "NAND Flash support for TXx9 SoC" | 341 | tristate "TXx9 NAND controller" |
454 | depends on SOC_TX4938 || SOC_TX4939 || COMPILE_TEST | 342 | depends on SOC_TX4938 || SOC_TX4939 || COMPILE_TEST |
455 | depends on HAS_IOMEM | 343 | depends on HAS_IOMEM |
456 | help | 344 | help |
457 | This enables the NAND flash controller on the TXx9 SoCs. | 345 | This enables the NAND flash controller on the TXx9 SoCs. |
458 | 346 | ||
459 | config MTD_NAND_SOCRATES | 347 | config MTD_NAND_SOCRATES |
460 | tristate "Support for NAND on Socrates board" | 348 | tristate "Socrates NAND controller" |
461 | depends on SOCRATES | 349 | depends on SOCRATES |
462 | help | 350 | help |
463 | Enables support for NAND Flash chips wired onto Socrates board. | 351 | Enables support for NAND Flash chips wired onto Socrates board. |
464 | 352 | ||
465 | config MTD_NAND_NUC900 | 353 | config MTD_NAND_NUC900 |
466 | tristate "Support for NAND on Nuvoton NUC9xx/w90p910 evaluation boards." | 354 | tristate "Nuvoton NUC9xx/w90p910 NAND controller" |
467 | depends on ARCH_W90X900 || COMPILE_TEST | 355 | depends on ARCH_W90X900 || COMPILE_TEST |
468 | depends on HAS_IOMEM | 356 | depends on HAS_IOMEM |
469 | help | 357 | help |
470 | This enables the driver for the NAND Flash on evaluation board based | 358 | This enables the driver for the NAND Flash on evaluation board based |
471 | on w90p910 / NUC9xx. | 359 | on w90p910 / NUC9xx. |
472 | 360 | ||
473 | config MTD_NAND_JZ4740 | 361 | source "drivers/mtd/nand/raw/ingenic/Kconfig" |
474 | tristate "Support for JZ4740 SoC NAND controller" | ||
475 | depends on MACH_JZ4740 || COMPILE_TEST | ||
476 | depends on HAS_IOMEM | ||
477 | help | ||
478 | Enables support for NAND Flash on JZ4740 SoC based boards. | ||
479 | |||
480 | config MTD_NAND_JZ4780 | ||
481 | tristate "Support for NAND on JZ4780 SoC" | ||
482 | depends on JZ4780_NEMC | ||
483 | help | ||
484 | Enables support for NAND Flash connected to the NEMC on JZ4780 SoC | ||
485 | based boards, using the BCH controller for hardware error correction. | ||
486 | 362 | ||
487 | config MTD_NAND_FSMC | 363 | config MTD_NAND_FSMC |
488 | tristate "Support for NAND on ST Micros FSMC" | 364 | tristate "ST Micros FSMC NAND controller" |
489 | depends on OF && HAS_IOMEM | 365 | depends on OF && HAS_IOMEM |
490 | depends on PLAT_SPEAR || ARCH_NOMADIK || ARCH_U8500 || MACH_U300 || \ | 366 | depends on PLAT_SPEAR || ARCH_NOMADIK || ARCH_U8500 || MACH_U300 || \ |
491 | COMPILE_TEST | 367 | COMPILE_TEST |
@@ -494,28 +370,28 @@ config MTD_NAND_FSMC | |||
494 | Flexible Static Memory Controller (FSMC) | 370 | Flexible Static Memory Controller (FSMC) |
495 | 371 | ||
496 | config MTD_NAND_XWAY | 372 | config MTD_NAND_XWAY |
497 | bool "Support for NAND on Lantiq XWAY SoC" | 373 | bool "Lantiq XWAY NAND controller" |
498 | depends on LANTIQ && SOC_TYPE_XWAY | 374 | depends on LANTIQ && SOC_TYPE_XWAY |
499 | help | 375 | help |
500 | Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached | 376 | Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached |
501 | to the External Bus Unit (EBU). | 377 | to the External Bus Unit (EBU). |
502 | 378 | ||
503 | config MTD_NAND_SUNXI | 379 | config MTD_NAND_SUNXI |
504 | tristate "Support for NAND on Allwinner SoCs" | 380 | tristate "Allwinner NAND controller" |
505 | depends on ARCH_SUNXI || COMPILE_TEST | 381 | depends on ARCH_SUNXI || COMPILE_TEST |
506 | depends on HAS_IOMEM | 382 | depends on HAS_IOMEM |
507 | help | 383 | help |
508 | Enables support for NAND Flash chips on Allwinner SoCs. | 384 | Enables support for NAND Flash chips on Allwinner SoCs. |
509 | 385 | ||
510 | config MTD_NAND_HISI504 | 386 | config MTD_NAND_HISI504 |
511 | tristate "Support for NAND controller on Hisilicon SoC Hip04" | 387 | tristate "Hisilicon Hip04 NAND controller" |
512 | depends on ARCH_HISI || COMPILE_TEST | 388 | depends on ARCH_HISI || COMPILE_TEST |
513 | depends on HAS_IOMEM | 389 | depends on HAS_IOMEM |
514 | help | 390 | help |
515 | Enables support for NAND controller on Hisilicon SoC Hip04. | 391 | Enables support for NAND controller on Hisilicon SoC Hip04. |
516 | 392 | ||
517 | config MTD_NAND_QCOM | 393 | config MTD_NAND_QCOM |
518 | tristate "Support for NAND on QCOM SoCs" | 394 | tristate "QCOM NAND controller" |
519 | depends on ARCH_QCOM || COMPILE_TEST | 395 | depends on ARCH_QCOM || COMPILE_TEST |
520 | depends on HAS_IOMEM | 396 | depends on HAS_IOMEM |
521 | help | 397 | help |
@@ -523,7 +399,7 @@ config MTD_NAND_QCOM | |||
523 | controller. This controller is found on IPQ806x SoC. | 399 | controller. This controller is found on IPQ806x SoC. |
524 | 400 | ||
525 | config MTD_NAND_MTK | 401 | config MTD_NAND_MTK |
526 | tristate "Support for NAND controller on MTK SoCs" | 402 | tristate "MTK NAND controller" |
527 | depends on ARCH_MEDIATEK || COMPILE_TEST | 403 | depends on ARCH_MEDIATEK || COMPILE_TEST |
528 | depends on HAS_IOMEM | 404 | depends on HAS_IOMEM |
529 | help | 405 | help |
@@ -531,7 +407,7 @@ config MTD_NAND_MTK | |||
531 | This controller is found on mt27xx, mt81xx, mt65xx SoCs. | 407 | This controller is found on mt27xx, mt81xx, mt65xx SoCs. |
532 | 408 | ||
533 | config MTD_NAND_TEGRA | 409 | config MTD_NAND_TEGRA |
534 | tristate "Support for NAND controller on NVIDIA Tegra" | 410 | tristate "NVIDIA Tegra NAND controller" |
535 | depends on ARCH_TEGRA || COMPILE_TEST | 411 | depends on ARCH_TEGRA || COMPILE_TEST |
536 | depends on HAS_IOMEM | 412 | depends on HAS_IOMEM |
537 | help | 413 | help |
@@ -558,4 +434,115 @@ config MTD_NAND_MESON | |||
558 | Enables support for NAND controller on Amlogic's Meson SoCs. | 434 | Enables support for NAND controller on Amlogic's Meson SoCs. |
559 | This controller is found on Meson SoCs. | 435 | This controller is found on Meson SoCs. |
560 | 436 | ||
561 | endif # MTD_NAND | 437 | config MTD_NAND_GPIO |
438 | tristate "GPIO assisted NAND controller" | ||
439 | depends on GPIOLIB || COMPILE_TEST | ||
440 | depends on HAS_IOMEM | ||
441 | help | ||
442 | This enables a NAND flash driver where control signals are | ||
443 | connected to GPIO pins, and commands and data are communicated | ||
444 | via a memory mapped interface. | ||
445 | |||
446 | config MTD_NAND_PLATFORM | ||
447 | tristate "Generic NAND controller" | ||
448 | depends on HAS_IOMEM | ||
449 | help | ||
450 | This implements a generic NAND driver for on-SOC platform | ||
451 | devices. You will need to provide platform-specific functions | ||
452 | via platform_data. | ||
453 | |||
454 | comment "Misc" | ||
455 | |||
456 | config MTD_SM_COMMON | ||
457 | tristate | ||
458 | default n | ||
459 | |||
460 | config MTD_NAND_NANDSIM | ||
461 | tristate "Support for NAND Flash Simulator" | ||
462 | help | ||
463 | The simulator may simulate various NAND flash chips for the | ||
464 | MTD nand layer. | ||
465 | |||
466 | config MTD_NAND_RICOH | ||
467 | tristate "Ricoh xD card reader" | ||
468 | default n | ||
469 | depends on PCI | ||
470 | select MTD_SM_COMMON | ||
471 | help | ||
472 | Enable support for Ricoh R5C852 xD card reader | ||
473 | You also need to enable ether | ||
474 | NAND SSFDC (SmartMedia) read only translation layer' or new | ||
475 | expermental, readwrite | ||
476 | 'SmartMedia/xD new translation layer' | ||
477 | |||
478 | config MTD_NAND_DISKONCHIP | ||
479 | tristate "DiskOnChip 2000, Millennium and Millennium Plus (NAND reimplementation)" | ||
480 | depends on HAS_IOMEM | ||
481 | select REED_SOLOMON | ||
482 | select REED_SOLOMON_DEC16 | ||
483 | help | ||
484 | This is a reimplementation of M-Systems DiskOnChip 2000, | ||
485 | Millennium and Millennium Plus as a standard NAND device driver, | ||
486 | as opposed to the earlier self-contained MTD device drivers. | ||
487 | This should enable, among other things, proper JFFS2 operation on | ||
488 | these devices. | ||
489 | |||
490 | config MTD_NAND_DISKONCHIP_PROBE_ADVANCED | ||
491 | bool "Advanced detection options for DiskOnChip" | ||
492 | depends on MTD_NAND_DISKONCHIP | ||
493 | help | ||
494 | This option allows you to specify nonstandard address at which to | ||
495 | probe for a DiskOnChip, or to change the detection options. You | ||
496 | are unlikely to need any of this unless you are using LinuxBIOS. | ||
497 | Say 'N'. | ||
498 | |||
499 | config MTD_NAND_DISKONCHIP_PROBE_ADDRESS | ||
500 | hex "Physical address of DiskOnChip" if MTD_NAND_DISKONCHIP_PROBE_ADVANCED | ||
501 | depends on MTD_NAND_DISKONCHIP | ||
502 | default "0" | ||
503 | help | ||
504 | By default, the probe for DiskOnChip devices will look for a | ||
505 | DiskOnChip at every multiple of 0x2000 between 0xC8000 and 0xEE000. | ||
506 | This option allows you to specify a single address at which to probe | ||
507 | for the device, which is useful if you have other devices in that | ||
508 | range which get upset when they are probed. | ||
509 | |||
510 | (Note that on PowerPC, the normal probe will only check at | ||
511 | 0xE4000000.) | ||
512 | |||
513 | Normally, you should leave this set to zero, to allow the probe at | ||
514 | the normal addresses. | ||
515 | |||
516 | config MTD_NAND_DISKONCHIP_PROBE_HIGH | ||
517 | bool "Probe high addresses" | ||
518 | depends on MTD_NAND_DISKONCHIP_PROBE_ADVANCED | ||
519 | help | ||
520 | By default, the probe for DiskOnChip devices will look for a | ||
521 | DiskOnChip at every multiple of 0x2000 between 0xC8000 and 0xEE000. | ||
522 | This option changes to make it probe between 0xFFFC8000 and | ||
523 | 0xFFFEE000. Unless you are using LinuxBIOS, this is unlikely to be | ||
524 | useful to you. Say 'N'. | ||
525 | |||
526 | config MTD_NAND_DISKONCHIP_BBTWRITE | ||
527 | bool "Allow BBT writes on DiskOnChip Millennium and 2000TSOP" | ||
528 | depends on MTD_NAND_DISKONCHIP | ||
529 | help | ||
530 | On DiskOnChip devices shipped with the INFTL filesystem (Millennium | ||
531 | and 2000 TSOP/Alon), Linux reserves some space at the end of the | ||
532 | device for the Bad Block Table (BBT). If you have existing INFTL | ||
533 | data on your device (created by non-Linux tools such as M-Systems' | ||
534 | DOS drivers), your data might overlap the area Linux wants to use for | ||
535 | the BBT. If this is a concern for you, leave this option disabled and | ||
536 | Linux will not write BBT data into this area. | ||
537 | The downside of leaving this option disabled is that if bad blocks | ||
538 | are detected by Linux, they will not be recorded in the BBT, which | ||
539 | could cause future problems. | ||
540 | Once you enable this option, new filesystems (INFTL or others, created | ||
541 | in Linux or other operating systems) will not use the reserved area. | ||
542 | The only reason not to enable this option is to prevent damage to | ||
543 | preexisting filesystems. | ||
544 | Even if you leave this disabled, you can enable BBT writes at module | ||
545 | load time (assuming you build diskonchip as a module) with the module | ||
546 | parameter "inftl_bbt_write=1". | ||
547 | |||
548 | endif # MTD_RAW_NAND | ||
diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile index 5a5a72f0793e..efaf5cd25edc 100644 --- a/drivers/mtd/nand/raw/Makefile +++ b/drivers/mtd/nand/raw/Makefile | |||
@@ -1,8 +1,8 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
2 | 2 | ||
3 | obj-$(CONFIG_MTD_NAND) += nand.o | 3 | obj-$(CONFIG_MTD_RAW_NAND) += nand.o |
4 | obj-$(CONFIG_MTD_NAND_ECC) += nand_ecc.o | 4 | obj-$(CONFIG_MTD_NAND_ECC_SW_HAMMING) += nand_ecc.o |
5 | obj-$(CONFIG_MTD_NAND_BCH) += nand_bch.o | 5 | nand-$(CONFIG_MTD_NAND_ECC_SW_BCH) += nand_bch.o |
6 | obj-$(CONFIG_MTD_SM_COMMON) += sm_common.o | 6 | obj-$(CONFIG_MTD_SM_COMMON) += sm_common.o |
7 | 7 | ||
8 | obj-$(CONFIG_MTD_NAND_CAFE) += cafe_nand.o | 8 | obj-$(CONFIG_MTD_NAND_CAFE) += cafe_nand.o |
@@ -45,8 +45,7 @@ obj-$(CONFIG_MTD_NAND_NUC900) += nuc900_nand.o | |||
45 | obj-$(CONFIG_MTD_NAND_MPC5121_NFC) += mpc5121_nfc.o | 45 | obj-$(CONFIG_MTD_NAND_MPC5121_NFC) += mpc5121_nfc.o |
46 | obj-$(CONFIG_MTD_NAND_VF610_NFC) += vf610_nfc.o | 46 | obj-$(CONFIG_MTD_NAND_VF610_NFC) += vf610_nfc.o |
47 | obj-$(CONFIG_MTD_NAND_RICOH) += r852.o | 47 | obj-$(CONFIG_MTD_NAND_RICOH) += r852.o |
48 | obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o | 48 | obj-y += ingenic/ |
49 | obj-$(CONFIG_MTD_NAND_JZ4780) += jz4780_nand.o jz4780_bch.o | ||
50 | obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/ | 49 | obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/ |
51 | obj-$(CONFIG_MTD_NAND_XWAY) += xway_nand.o | 50 | obj-$(CONFIG_MTD_NAND_XWAY) += xway_nand.o |
52 | obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash/ | 51 | obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash/ |
diff --git a/drivers/mtd/nand/raw/atmel/nand-controller.c b/drivers/mtd/nand/raw/atmel/nand-controller.c index 5781fcf6b76c..8d6be90a6fe8 100644 --- a/drivers/mtd/nand/raw/atmel/nand-controller.c +++ b/drivers/mtd/nand/raw/atmel/nand-controller.c | |||
@@ -1,3 +1,4 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * Copyright 2017 ATMEL | 3 | * Copyright 2017 ATMEL |
3 | * Copyright 2017 Free Electrons | 4 | * Copyright 2017 Free Electrons |
@@ -29,10 +30,6 @@ | |||
29 | * Add Nand Flash Controller support for SAMA5 SoC | 30 | * Add Nand Flash Controller support for SAMA5 SoC |
30 | * Copyright 2013 ATMEL, Josh Wu (josh.wu@atmel.com) | 31 | * Copyright 2013 ATMEL, Josh Wu (josh.wu@atmel.com) |
31 | * | 32 | * |
32 | * This program is free software; you can redistribute it and/or modify | ||
33 | * it under the terms of the GNU General Public License version 2 as | ||
34 | * published by the Free Software Foundation. | ||
35 | * | ||
36 | * A few words about the naming convention in this file. This convention | 33 | * A few words about the naming convention in this file. This convention |
37 | * applies to structure and function names. | 34 | * applies to structure and function names. |
38 | * | 35 | * |
@@ -65,6 +62,7 @@ | |||
65 | #include <linux/iopoll.h> | 62 | #include <linux/iopoll.h> |
66 | #include <linux/platform_device.h> | 63 | #include <linux/platform_device.h> |
67 | #include <linux/regmap.h> | 64 | #include <linux/regmap.h> |
65 | #include <soc/at91/atmel-sfr.h> | ||
68 | 66 | ||
69 | #include "pmecc.h" | 67 | #include "pmecc.h" |
70 | 68 | ||
@@ -211,6 +209,7 @@ struct atmel_nand_controller_caps { | |||
211 | bool legacy_of_bindings; | 209 | bool legacy_of_bindings; |
212 | u32 ale_offs; | 210 | u32 ale_offs; |
213 | u32 cle_offs; | 211 | u32 cle_offs; |
212 | const char *ebi_csa_regmap_name; | ||
214 | const struct atmel_nand_controller_ops *ops; | 213 | const struct atmel_nand_controller_ops *ops; |
215 | }; | 214 | }; |
216 | 215 | ||
@@ -231,10 +230,15 @@ to_nand_controller(struct nand_controller *ctl) | |||
231 | return container_of(ctl, struct atmel_nand_controller, base); | 230 | return container_of(ctl, struct atmel_nand_controller, base); |
232 | } | 231 | } |
233 | 232 | ||
233 | struct atmel_smc_nand_ebi_csa_cfg { | ||
234 | u32 offs; | ||
235 | u32 nfd0_on_d16; | ||
236 | }; | ||
237 | |||
234 | struct atmel_smc_nand_controller { | 238 | struct atmel_smc_nand_controller { |
235 | struct atmel_nand_controller base; | 239 | struct atmel_nand_controller base; |
236 | struct regmap *matrix; | 240 | struct regmap *ebi_csa_regmap; |
237 | unsigned int ebi_csa_offs; | 241 | struct atmel_smc_nand_ebi_csa_cfg *ebi_csa; |
238 | }; | 242 | }; |
239 | 243 | ||
240 | static inline struct atmel_smc_nand_controller * | 244 | static inline struct atmel_smc_nand_controller * |
@@ -1068,15 +1072,15 @@ static int atmel_nand_pmecc_init(struct nand_chip *chip) | |||
1068 | req.ecc.strength = ATMEL_PMECC_MAXIMIZE_ECC_STRENGTH; | 1072 | req.ecc.strength = ATMEL_PMECC_MAXIMIZE_ECC_STRENGTH; |
1069 | else if (chip->ecc.strength) | 1073 | else if (chip->ecc.strength) |
1070 | req.ecc.strength = chip->ecc.strength; | 1074 | req.ecc.strength = chip->ecc.strength; |
1071 | else if (chip->ecc_strength_ds) | 1075 | else if (chip->base.eccreq.strength) |
1072 | req.ecc.strength = chip->ecc_strength_ds; | 1076 | req.ecc.strength = chip->base.eccreq.strength; |
1073 | else | 1077 | else |
1074 | req.ecc.strength = ATMEL_PMECC_MAXIMIZE_ECC_STRENGTH; | 1078 | req.ecc.strength = ATMEL_PMECC_MAXIMIZE_ECC_STRENGTH; |
1075 | 1079 | ||
1076 | if (chip->ecc.size) | 1080 | if (chip->ecc.size) |
1077 | req.ecc.sectorsize = chip->ecc.size; | 1081 | req.ecc.sectorsize = chip->ecc.size; |
1078 | else if (chip->ecc_step_ds) | 1082 | else if (chip->base.eccreq.step_size) |
1079 | req.ecc.sectorsize = chip->ecc_step_ds; | 1083 | req.ecc.sectorsize = chip->base.eccreq.step_size; |
1080 | else | 1084 | else |
1081 | req.ecc.sectorsize = ATMEL_PMECC_SECTOR_SIZE_AUTO; | 1085 | req.ecc.sectorsize = ATMEL_PMECC_SECTOR_SIZE_AUTO; |
1082 | 1086 | ||
@@ -1507,13 +1511,20 @@ static void atmel_smc_nand_init(struct atmel_nand_controller *nc, | |||
1507 | atmel_nand_init(nc, nand); | 1511 | atmel_nand_init(nc, nand); |
1508 | 1512 | ||
1509 | smc_nc = to_smc_nand_controller(chip->controller); | 1513 | smc_nc = to_smc_nand_controller(chip->controller); |
1510 | if (!smc_nc->matrix) | 1514 | if (!smc_nc->ebi_csa_regmap) |
1511 | return; | 1515 | return; |
1512 | 1516 | ||
1513 | /* Attach the CS to the NAND Flash logic. */ | 1517 | /* Attach the CS to the NAND Flash logic. */ |
1514 | for (i = 0; i < nand->numcs; i++) | 1518 | for (i = 0; i < nand->numcs; i++) |
1515 | regmap_update_bits(smc_nc->matrix, smc_nc->ebi_csa_offs, | 1519 | regmap_update_bits(smc_nc->ebi_csa_regmap, |
1520 | smc_nc->ebi_csa->offs, | ||
1516 | BIT(nand->cs[i].id), BIT(nand->cs[i].id)); | 1521 | BIT(nand->cs[i].id), BIT(nand->cs[i].id)); |
1522 | |||
1523 | if (smc_nc->ebi_csa->nfd0_on_d16) | ||
1524 | regmap_update_bits(smc_nc->ebi_csa_regmap, | ||
1525 | smc_nc->ebi_csa->offs, | ||
1526 | smc_nc->ebi_csa->nfd0_on_d16, | ||
1527 | smc_nc->ebi_csa->nfd0_on_d16); | ||
1517 | } | 1528 | } |
1518 | 1529 | ||
1519 | static void atmel_hsmc_nand_init(struct atmel_nand_controller *nc, | 1530 | static void atmel_hsmc_nand_init(struct atmel_nand_controller *nc, |
@@ -1797,7 +1808,7 @@ static int atmel_nand_controller_add_nands(struct atmel_nand_controller *nc) | |||
1797 | 1808 | ||
1798 | ret = of_property_read_u32(np, "#size-cells", &val); | 1809 | ret = of_property_read_u32(np, "#size-cells", &val); |
1799 | if (ret) { | 1810 | if (ret) { |
1800 | dev_err(dev, "missing #address-cells property\n"); | 1811 | dev_err(dev, "missing #size-cells property\n"); |
1801 | return ret; | 1812 | return ret; |
1802 | } | 1813 | } |
1803 | 1814 | ||
@@ -1833,34 +1844,71 @@ static void atmel_nand_controller_cleanup(struct atmel_nand_controller *nc) | |||
1833 | clk_put(nc->mck); | 1844 | clk_put(nc->mck); |
1834 | } | 1845 | } |
1835 | 1846 | ||
1836 | static const struct of_device_id atmel_matrix_of_ids[] = { | 1847 | static const struct atmel_smc_nand_ebi_csa_cfg at91sam9260_ebi_csa = { |
1848 | .offs = AT91SAM9260_MATRIX_EBICSA, | ||
1849 | }; | ||
1850 | |||
1851 | static const struct atmel_smc_nand_ebi_csa_cfg at91sam9261_ebi_csa = { | ||
1852 | .offs = AT91SAM9261_MATRIX_EBICSA, | ||
1853 | }; | ||
1854 | |||
1855 | static const struct atmel_smc_nand_ebi_csa_cfg at91sam9263_ebi_csa = { | ||
1856 | .offs = AT91SAM9263_MATRIX_EBI0CSA, | ||
1857 | }; | ||
1858 | |||
1859 | static const struct atmel_smc_nand_ebi_csa_cfg at91sam9rl_ebi_csa = { | ||
1860 | .offs = AT91SAM9RL_MATRIX_EBICSA, | ||
1861 | }; | ||
1862 | |||
1863 | static const struct atmel_smc_nand_ebi_csa_cfg at91sam9g45_ebi_csa = { | ||
1864 | .offs = AT91SAM9G45_MATRIX_EBICSA, | ||
1865 | }; | ||
1866 | |||
1867 | static const struct atmel_smc_nand_ebi_csa_cfg at91sam9n12_ebi_csa = { | ||
1868 | .offs = AT91SAM9N12_MATRIX_EBICSA, | ||
1869 | }; | ||
1870 | |||
1871 | static const struct atmel_smc_nand_ebi_csa_cfg at91sam9x5_ebi_csa = { | ||
1872 | .offs = AT91SAM9X5_MATRIX_EBICSA, | ||
1873 | }; | ||
1874 | |||
1875 | static const struct atmel_smc_nand_ebi_csa_cfg sam9x60_ebi_csa = { | ||
1876 | .offs = AT91_SFR_CCFG_EBICSA, | ||
1877 | .nfd0_on_d16 = AT91_SFR_CCFG_NFD0_ON_D16, | ||
1878 | }; | ||
1879 | |||
1880 | static const struct of_device_id atmel_ebi_csa_regmap_of_ids[] = { | ||
1837 | { | 1881 | { |
1838 | .compatible = "atmel,at91sam9260-matrix", | 1882 | .compatible = "atmel,at91sam9260-matrix", |
1839 | .data = (void *)AT91SAM9260_MATRIX_EBICSA, | 1883 | .data = &at91sam9260_ebi_csa, |
1840 | }, | 1884 | }, |
1841 | { | 1885 | { |
1842 | .compatible = "atmel,at91sam9261-matrix", | 1886 | .compatible = "atmel,at91sam9261-matrix", |
1843 | .data = (void *)AT91SAM9261_MATRIX_EBICSA, | 1887 | .data = &at91sam9261_ebi_csa, |
1844 | }, | 1888 | }, |
1845 | { | 1889 | { |
1846 | .compatible = "atmel,at91sam9263-matrix", | 1890 | .compatible = "atmel,at91sam9263-matrix", |
1847 | .data = (void *)AT91SAM9263_MATRIX_EBI0CSA, | 1891 | .data = &at91sam9263_ebi_csa, |
1848 | }, | 1892 | }, |
1849 | { | 1893 | { |
1850 | .compatible = "atmel,at91sam9rl-matrix", | 1894 | .compatible = "atmel,at91sam9rl-matrix", |
1851 | .data = (void *)AT91SAM9RL_MATRIX_EBICSA, | 1895 | .data = &at91sam9rl_ebi_csa, |
1852 | }, | 1896 | }, |
1853 | { | 1897 | { |
1854 | .compatible = "atmel,at91sam9g45-matrix", | 1898 | .compatible = "atmel,at91sam9g45-matrix", |
1855 | .data = (void *)AT91SAM9G45_MATRIX_EBICSA, | 1899 | .data = &at91sam9g45_ebi_csa, |
1856 | }, | 1900 | }, |
1857 | { | 1901 | { |
1858 | .compatible = "atmel,at91sam9n12-matrix", | 1902 | .compatible = "atmel,at91sam9n12-matrix", |
1859 | .data = (void *)AT91SAM9N12_MATRIX_EBICSA, | 1903 | .data = &at91sam9n12_ebi_csa, |
1860 | }, | 1904 | }, |
1861 | { | 1905 | { |
1862 | .compatible = "atmel,at91sam9x5-matrix", | 1906 | .compatible = "atmel,at91sam9x5-matrix", |
1863 | .data = (void *)AT91SAM9X5_MATRIX_EBICSA, | 1907 | .data = &at91sam9x5_ebi_csa, |
1908 | }, | ||
1909 | { | ||
1910 | .compatible = "microchip,sam9x60-sfr", | ||
1911 | .data = &sam9x60_ebi_csa, | ||
1864 | }, | 1912 | }, |
1865 | { /* sentinel */ }, | 1913 | { /* sentinel */ }, |
1866 | }; | 1914 | }; |
@@ -1982,37 +2030,38 @@ atmel_smc_nand_controller_init(struct atmel_smc_nand_controller *nc) | |||
1982 | struct device_node *np; | 2030 | struct device_node *np; |
1983 | int ret; | 2031 | int ret; |
1984 | 2032 | ||
1985 | /* We do not retrieve the matrix syscon when parsing old DTs. */ | 2033 | /* We do not retrieve the EBICSA regmap when parsing old DTs. */ |
1986 | if (nc->base.caps->legacy_of_bindings) | 2034 | if (nc->base.caps->legacy_of_bindings) |
1987 | return 0; | 2035 | return 0; |
1988 | 2036 | ||
1989 | np = of_parse_phandle(dev->parent->of_node, "atmel,matrix", 0); | 2037 | np = of_parse_phandle(dev->parent->of_node, |
2038 | nc->base.caps->ebi_csa_regmap_name, 0); | ||
1990 | if (!np) | 2039 | if (!np) |
1991 | return 0; | 2040 | return 0; |
1992 | 2041 | ||
1993 | match = of_match_node(atmel_matrix_of_ids, np); | 2042 | match = of_match_node(atmel_ebi_csa_regmap_of_ids, np); |
1994 | if (!match) { | 2043 | if (!match) { |
1995 | of_node_put(np); | 2044 | of_node_put(np); |
1996 | return 0; | 2045 | return 0; |
1997 | } | 2046 | } |
1998 | 2047 | ||
1999 | nc->matrix = syscon_node_to_regmap(np); | 2048 | nc->ebi_csa_regmap = syscon_node_to_regmap(np); |
2000 | of_node_put(np); | 2049 | of_node_put(np); |
2001 | if (IS_ERR(nc->matrix)) { | 2050 | if (IS_ERR(nc->ebi_csa_regmap)) { |
2002 | ret = PTR_ERR(nc->matrix); | 2051 | ret = PTR_ERR(nc->ebi_csa_regmap); |
2003 | dev_err(dev, "Could not get Matrix regmap (err = %d)\n", ret); | 2052 | dev_err(dev, "Could not get EBICSA regmap (err = %d)\n", ret); |
2004 | return ret; | 2053 | return ret; |
2005 | } | 2054 | } |
2006 | 2055 | ||
2007 | nc->ebi_csa_offs = (uintptr_t)match->data; | 2056 | nc->ebi_csa = (struct atmel_smc_nand_ebi_csa_cfg *)match->data; |
2008 | 2057 | ||
2009 | /* | 2058 | /* |
2010 | * The at91sam9263 has 2 EBIs, if the NAND controller is under EBI1 | 2059 | * The at91sam9263 has 2 EBIs, if the NAND controller is under EBI1 |
2011 | * add 4 to ->ebi_csa_offs. | 2060 | * add 4 to ->ebi_csa->offs. |
2012 | */ | 2061 | */ |
2013 | if (of_device_is_compatible(dev->parent->of_node, | 2062 | if (of_device_is_compatible(dev->parent->of_node, |
2014 | "atmel,at91sam9263-ebi1")) | 2063 | "atmel,at91sam9263-ebi1")) |
2015 | nc->ebi_csa_offs += 4; | 2064 | nc->ebi_csa->offs += 4; |
2016 | 2065 | ||
2017 | return 0; | 2066 | return 0; |
2018 | } | 2067 | } |
@@ -2341,6 +2390,7 @@ static const struct atmel_nand_controller_ops at91rm9200_nc_ops = { | |||
2341 | static const struct atmel_nand_controller_caps atmel_rm9200_nc_caps = { | 2390 | static const struct atmel_nand_controller_caps atmel_rm9200_nc_caps = { |
2342 | .ale_offs = BIT(21), | 2391 | .ale_offs = BIT(21), |
2343 | .cle_offs = BIT(22), | 2392 | .cle_offs = BIT(22), |
2393 | .ebi_csa_regmap_name = "atmel,matrix", | ||
2344 | .ops = &at91rm9200_nc_ops, | 2394 | .ops = &at91rm9200_nc_ops, |
2345 | }; | 2395 | }; |
2346 | 2396 | ||
@@ -2355,12 +2405,14 @@ static const struct atmel_nand_controller_ops atmel_smc_nc_ops = { | |||
2355 | static const struct atmel_nand_controller_caps atmel_sam9260_nc_caps = { | 2405 | static const struct atmel_nand_controller_caps atmel_sam9260_nc_caps = { |
2356 | .ale_offs = BIT(21), | 2406 | .ale_offs = BIT(21), |
2357 | .cle_offs = BIT(22), | 2407 | .cle_offs = BIT(22), |
2408 | .ebi_csa_regmap_name = "atmel,matrix", | ||
2358 | .ops = &atmel_smc_nc_ops, | 2409 | .ops = &atmel_smc_nc_ops, |
2359 | }; | 2410 | }; |
2360 | 2411 | ||
2361 | static const struct atmel_nand_controller_caps atmel_sam9261_nc_caps = { | 2412 | static const struct atmel_nand_controller_caps atmel_sam9261_nc_caps = { |
2362 | .ale_offs = BIT(22), | 2413 | .ale_offs = BIT(22), |
2363 | .cle_offs = BIT(21), | 2414 | .cle_offs = BIT(21), |
2415 | .ebi_csa_regmap_name = "atmel,matrix", | ||
2364 | .ops = &atmel_smc_nc_ops, | 2416 | .ops = &atmel_smc_nc_ops, |
2365 | }; | 2417 | }; |
2366 | 2418 | ||
@@ -2368,6 +2420,15 @@ static const struct atmel_nand_controller_caps atmel_sam9g45_nc_caps = { | |||
2368 | .has_dma = true, | 2420 | .has_dma = true, |
2369 | .ale_offs = BIT(21), | 2421 | .ale_offs = BIT(21), |
2370 | .cle_offs = BIT(22), | 2422 | .cle_offs = BIT(22), |
2423 | .ebi_csa_regmap_name = "atmel,matrix", | ||
2424 | .ops = &atmel_smc_nc_ops, | ||
2425 | }; | ||
2426 | |||
2427 | static const struct atmel_nand_controller_caps microchip_sam9x60_nc_caps = { | ||
2428 | .has_dma = true, | ||
2429 | .ale_offs = BIT(21), | ||
2430 | .cle_offs = BIT(22), | ||
2431 | .ebi_csa_regmap_name = "microchip,sfr", | ||
2371 | .ops = &atmel_smc_nc_ops, | 2432 | .ops = &atmel_smc_nc_ops, |
2372 | }; | 2433 | }; |
2373 | 2434 | ||
@@ -2415,6 +2476,10 @@ static const struct of_device_id atmel_nand_controller_of_ids[] = { | |||
2415 | .compatible = "atmel,sama5d3-nand-controller", | 2476 | .compatible = "atmel,sama5d3-nand-controller", |
2416 | .data = &atmel_sama5_nc_caps, | 2477 | .data = &atmel_sama5_nc_caps, |
2417 | }, | 2478 | }, |
2479 | { | ||
2480 | .compatible = "microchip,sam9x60-nand-controller", | ||
2481 | .data = µchip_sam9x60_nc_caps, | ||
2482 | }, | ||
2418 | /* Support for old/deprecated bindings: */ | 2483 | /* Support for old/deprecated bindings: */ |
2419 | { | 2484 | { |
2420 | .compatible = "atmel,at91rm9200-nand", | 2485 | .compatible = "atmel,at91rm9200-nand", |
diff --git a/drivers/mtd/nand/raw/atmel/pmecc.c b/drivers/mtd/nand/raw/atmel/pmecc.c index 9d3997840889..cbb023bf00f7 100644 --- a/drivers/mtd/nand/raw/atmel/pmecc.c +++ b/drivers/mtd/nand/raw/atmel/pmecc.c | |||
@@ -1,3 +1,4 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * Copyright 2017 ATMEL | 3 | * Copyright 2017 ATMEL |
3 | * Copyright 2017 Free Electrons | 4 | * Copyright 2017 Free Electrons |
@@ -28,10 +29,6 @@ | |||
28 | * Add Nand Flash Controller support for SAMA5 SoC | 29 | * Add Nand Flash Controller support for SAMA5 SoC |
29 | * Copyright 2013 ATMEL, Josh Wu (josh.wu@atmel.com) | 30 | * Copyright 2013 ATMEL, Josh Wu (josh.wu@atmel.com) |
30 | * | 31 | * |
31 | * This program is free software; you can redistribute it and/or modify | ||
32 | * it under the terms of the GNU General Public License version 2 as | ||
33 | * published by the Free Software Foundation. | ||
34 | * | ||
35 | * The PMECC is an hardware assisted BCH engine, which means part of the | 32 | * The PMECC is an hardware assisted BCH engine, which means part of the |
36 | * ECC algorithm is left to the software. The hardware/software repartition | 33 | * ECC algorithm is left to the software. The hardware/software repartition |
37 | * is explained in the "PMECC Controller Functional Description" chapter in | 34 | * is explained in the "PMECC Controller Functional Description" chapter in |
diff --git a/drivers/mtd/nand/raw/atmel/pmecc.h b/drivers/mtd/nand/raw/atmel/pmecc.h index 808f1be0d6ad..7851c05126cf 100644 --- a/drivers/mtd/nand/raw/atmel/pmecc.h +++ b/drivers/mtd/nand/raw/atmel/pmecc.h | |||
@@ -1,3 +1,4 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
1 | /* | 2 | /* |
2 | * © Copyright 2016 ATMEL | 3 | * © Copyright 2016 ATMEL |
3 | * © Copyright 2016 Free Electrons | 4 | * © Copyright 2016 Free Electrons |
@@ -28,11 +29,6 @@ | |||
28 | * | 29 | * |
29 | * Add Nand Flash Controller support for SAMA5 SoC | 30 | * Add Nand Flash Controller support for SAMA5 SoC |
30 | * © Copyright 2013 ATMEL, Josh Wu (josh.wu@atmel.com) | 31 | * © Copyright 2013 ATMEL, Josh Wu (josh.wu@atmel.com) |
31 | * | ||
32 | * This program is free software; you can redistribute it and/or modify | ||
33 | * it under the terms of the GNU General Public License version 2 as | ||
34 | * published by the Free Software Foundation. | ||
35 | * | ||
36 | */ | 32 | */ |
37 | 33 | ||
38 | #ifndef ATMEL_PMECC_H | 34 | #ifndef ATMEL_PMECC_H |
diff --git a/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c b/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c index a37cbfe56567..a53ffb3d64b0 100644 --- a/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c +++ b/drivers/mtd/nand/raw/bcm47xxnflash/ops_bcm4706.c | |||
@@ -428,7 +428,7 @@ int bcm47xxnflash_ops_bcm4706_init(struct bcm47xxnflash *b47n) | |||
428 | } | 428 | } |
429 | 429 | ||
430 | /* Configure FLASH */ | 430 | /* Configure FLASH */ |
431 | chipsize = b47n->nand_chip.chipsize >> 20; | 431 | chipsize = nanddev_target_size(&b47n->nand_chip.base) >> 20; |
432 | tbits = ffs(chipsize); /* find first bit set */ | 432 | tbits = ffs(chipsize); /* find first bit set */ |
433 | if (!tbits || tbits != fls(chipsize)) { | 433 | if (!tbits || tbits != fls(chipsize)) { |
434 | pr_err("Invalid flash size: 0x%lX\n", chipsize); | 434 | pr_err("Invalid flash size: 0x%lX\n", chipsize); |
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c index 482c6f093f99..ce0b8ffc7812 100644 --- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c | |||
@@ -1676,11 +1676,8 @@ static int brcmstb_nand_verify_erased_page(struct mtd_info *mtd, | |||
1676 | int page = addr >> chip->page_shift; | 1676 | int page = addr >> chip->page_shift; |
1677 | int ret; | 1677 | int ret; |
1678 | 1678 | ||
1679 | if (!buf) { | 1679 | if (!buf) |
1680 | buf = chip->data_buf; | 1680 | buf = nand_get_data_buf(chip); |
1681 | /* Invalidate page cache */ | ||
1682 | chip->pagebuf = -1; | ||
1683 | } | ||
1684 | 1681 | ||
1685 | sas = mtd->oobsize / chip->ecc.steps; | 1682 | sas = mtd->oobsize / chip->ecc.steps; |
1686 | 1683 | ||
diff --git a/drivers/mtd/nand/raw/denali.c b/drivers/mtd/nand/raw/denali.c index 24aeafc67cd4..3102ddbd8abd 100644 --- a/drivers/mtd/nand/raw/denali.c +++ b/drivers/mtd/nand/raw/denali.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * NAND Flash Controller Device Driver | 3 | * NAND Flash Controller Device Driver |
4 | * Copyright © 2009-2010, Intel Corporation and its suppliers. | 4 | * Copyright © 2009-2010, Intel Corporation and its suppliers. |
5 | * | 5 | * |
6 | * Copyright (c) 2017 Socionext Inc. | 6 | * Copyright (c) 2017-2019 Socionext Inc. |
7 | * Reworked by Masahiro Yamada <yamada.masahiro@socionext.com> | 7 | * Reworked by Masahiro Yamada <yamada.masahiro@socionext.com> |
8 | */ | 8 | */ |
9 | 9 | ||
@@ -40,11 +40,16 @@ | |||
40 | #define DENALI_BANK(denali) ((denali)->active_bank << 24) | 40 | #define DENALI_BANK(denali) ((denali)->active_bank << 24) |
41 | 41 | ||
42 | #define DENALI_INVALID_BANK -1 | 42 | #define DENALI_INVALID_BANK -1 |
43 | #define DENALI_NR_BANKS 4 | ||
44 | 43 | ||
45 | static inline struct denali_nand_info *mtd_to_denali(struct mtd_info *mtd) | 44 | static struct denali_chip *to_denali_chip(struct nand_chip *chip) |
46 | { | 45 | { |
47 | return container_of(mtd_to_nand(mtd), struct denali_nand_info, nand); | 46 | return container_of(chip, struct denali_chip, chip); |
47 | } | ||
48 | |||
49 | static struct denali_controller *to_denali_controller(struct nand_chip *chip) | ||
50 | { | ||
51 | return container_of(chip->controller, struct denali_controller, | ||
52 | controller); | ||
48 | } | 53 | } |
49 | 54 | ||
50 | /* | 55 | /* |
@@ -52,12 +57,12 @@ static inline struct denali_nand_info *mtd_to_denali(struct mtd_info *mtd) | |||
52 | * type, bank, block, and page address). The slave data is the actual data to | 57 | * type, bank, block, and page address). The slave data is the actual data to |
53 | * be transferred. This mode requires 28 bits of address region allocated. | 58 | * be transferred. This mode requires 28 bits of address region allocated. |
54 | */ | 59 | */ |
55 | static u32 denali_direct_read(struct denali_nand_info *denali, u32 addr) | 60 | static u32 denali_direct_read(struct denali_controller *denali, u32 addr) |
56 | { | 61 | { |
57 | return ioread32(denali->host + addr); | 62 | return ioread32(denali->host + addr); |
58 | } | 63 | } |
59 | 64 | ||
60 | static void denali_direct_write(struct denali_nand_info *denali, u32 addr, | 65 | static void denali_direct_write(struct denali_controller *denali, u32 addr, |
61 | u32 data) | 66 | u32 data) |
62 | { | 67 | { |
63 | iowrite32(data, denali->host + addr); | 68 | iowrite32(data, denali->host + addr); |
@@ -69,77 +74,62 @@ static void denali_direct_write(struct denali_nand_info *denali, u32 addr, | |||
69 | * control information and transferred data are latched by the registers in | 74 | * control information and transferred data are latched by the registers in |
70 | * the translation module. | 75 | * the translation module. |
71 | */ | 76 | */ |
72 | static u32 denali_indexed_read(struct denali_nand_info *denali, u32 addr) | 77 | static u32 denali_indexed_read(struct denali_controller *denali, u32 addr) |
73 | { | 78 | { |
74 | iowrite32(addr, denali->host + DENALI_INDEXED_CTRL); | 79 | iowrite32(addr, denali->host + DENALI_INDEXED_CTRL); |
75 | return ioread32(denali->host + DENALI_INDEXED_DATA); | 80 | return ioread32(denali->host + DENALI_INDEXED_DATA); |
76 | } | 81 | } |
77 | 82 | ||
78 | static void denali_indexed_write(struct denali_nand_info *denali, u32 addr, | 83 | static void denali_indexed_write(struct denali_controller *denali, u32 addr, |
79 | u32 data) | 84 | u32 data) |
80 | { | 85 | { |
81 | iowrite32(addr, denali->host + DENALI_INDEXED_CTRL); | 86 | iowrite32(addr, denali->host + DENALI_INDEXED_CTRL); |
82 | iowrite32(data, denali->host + DENALI_INDEXED_DATA); | 87 | iowrite32(data, denali->host + DENALI_INDEXED_DATA); |
83 | } | 88 | } |
84 | 89 | ||
85 | /* | 90 | static void denali_enable_irq(struct denali_controller *denali) |
86 | * Use the configuration feature register to determine the maximum number of | ||
87 | * banks that the hardware supports. | ||
88 | */ | ||
89 | static void denali_detect_max_banks(struct denali_nand_info *denali) | ||
90 | { | ||
91 | uint32_t features = ioread32(denali->reg + FEATURES); | ||
92 | |||
93 | denali->max_banks = 1 << FIELD_GET(FEATURES__N_BANKS, features); | ||
94 | |||
95 | /* the encoding changed from rev 5.0 to 5.1 */ | ||
96 | if (denali->revision < 0x0501) | ||
97 | denali->max_banks <<= 1; | ||
98 | } | ||
99 | |||
100 | static void denali_enable_irq(struct denali_nand_info *denali) | ||
101 | { | 91 | { |
102 | int i; | 92 | int i; |
103 | 93 | ||
104 | for (i = 0; i < DENALI_NR_BANKS; i++) | 94 | for (i = 0; i < denali->nbanks; i++) |
105 | iowrite32(U32_MAX, denali->reg + INTR_EN(i)); | 95 | iowrite32(U32_MAX, denali->reg + INTR_EN(i)); |
106 | iowrite32(GLOBAL_INT_EN_FLAG, denali->reg + GLOBAL_INT_ENABLE); | 96 | iowrite32(GLOBAL_INT_EN_FLAG, denali->reg + GLOBAL_INT_ENABLE); |
107 | } | 97 | } |
108 | 98 | ||
109 | static void denali_disable_irq(struct denali_nand_info *denali) | 99 | static void denali_disable_irq(struct denali_controller *denali) |
110 | { | 100 | { |
111 | int i; | 101 | int i; |
112 | 102 | ||
113 | for (i = 0; i < DENALI_NR_BANKS; i++) | 103 | for (i = 0; i < denali->nbanks; i++) |
114 | iowrite32(0, denali->reg + INTR_EN(i)); | 104 | iowrite32(0, denali->reg + INTR_EN(i)); |
115 | iowrite32(0, denali->reg + GLOBAL_INT_ENABLE); | 105 | iowrite32(0, denali->reg + GLOBAL_INT_ENABLE); |
116 | } | 106 | } |
117 | 107 | ||
118 | static void denali_clear_irq(struct denali_nand_info *denali, | 108 | static void denali_clear_irq(struct denali_controller *denali, |
119 | int bank, uint32_t irq_status) | 109 | int bank, u32 irq_status) |
120 | { | 110 | { |
121 | /* write one to clear bits */ | 111 | /* write one to clear bits */ |
122 | iowrite32(irq_status, denali->reg + INTR_STATUS(bank)); | 112 | iowrite32(irq_status, denali->reg + INTR_STATUS(bank)); |
123 | } | 113 | } |
124 | 114 | ||
125 | static void denali_clear_irq_all(struct denali_nand_info *denali) | 115 | static void denali_clear_irq_all(struct denali_controller *denali) |
126 | { | 116 | { |
127 | int i; | 117 | int i; |
128 | 118 | ||
129 | for (i = 0; i < DENALI_NR_BANKS; i++) | 119 | for (i = 0; i < denali->nbanks; i++) |
130 | denali_clear_irq(denali, i, U32_MAX); | 120 | denali_clear_irq(denali, i, U32_MAX); |
131 | } | 121 | } |
132 | 122 | ||
133 | static irqreturn_t denali_isr(int irq, void *dev_id) | 123 | static irqreturn_t denali_isr(int irq, void *dev_id) |
134 | { | 124 | { |
135 | struct denali_nand_info *denali = dev_id; | 125 | struct denali_controller *denali = dev_id; |
136 | irqreturn_t ret = IRQ_NONE; | 126 | irqreturn_t ret = IRQ_NONE; |
137 | uint32_t irq_status; | 127 | u32 irq_status; |
138 | int i; | 128 | int i; |
139 | 129 | ||
140 | spin_lock(&denali->irq_lock); | 130 | spin_lock(&denali->irq_lock); |
141 | 131 | ||
142 | for (i = 0; i < DENALI_NR_BANKS; i++) { | 132 | for (i = 0; i < denali->nbanks; i++) { |
143 | irq_status = ioread32(denali->reg + INTR_STATUS(i)); | 133 | irq_status = ioread32(denali->reg + INTR_STATUS(i)); |
144 | if (irq_status) | 134 | if (irq_status) |
145 | ret = IRQ_HANDLED; | 135 | ret = IRQ_HANDLED; |
@@ -160,7 +150,7 @@ static irqreturn_t denali_isr(int irq, void *dev_id) | |||
160 | return ret; | 150 | return ret; |
161 | } | 151 | } |
162 | 152 | ||
163 | static void denali_reset_irq(struct denali_nand_info *denali) | 153 | static void denali_reset_irq(struct denali_controller *denali) |
164 | { | 154 | { |
165 | unsigned long flags; | 155 | unsigned long flags; |
166 | 156 | ||
@@ -170,11 +160,10 @@ static void denali_reset_irq(struct denali_nand_info *denali) | |||
170 | spin_unlock_irqrestore(&denali->irq_lock, flags); | 160 | spin_unlock_irqrestore(&denali->irq_lock, flags); |
171 | } | 161 | } |
172 | 162 | ||
173 | static uint32_t denali_wait_for_irq(struct denali_nand_info *denali, | 163 | static u32 denali_wait_for_irq(struct denali_controller *denali, u32 irq_mask) |
174 | uint32_t irq_mask) | ||
175 | { | 164 | { |
176 | unsigned long time_left, flags; | 165 | unsigned long time_left, flags; |
177 | uint32_t irq_status; | 166 | u32 irq_status; |
178 | 167 | ||
179 | spin_lock_irqsave(&denali->irq_lock, flags); | 168 | spin_lock_irqsave(&denali->irq_lock, flags); |
180 | 169 | ||
@@ -201,128 +190,259 @@ static uint32_t denali_wait_for_irq(struct denali_nand_info *denali, | |||
201 | return denali->irq_status; | 190 | return denali->irq_status; |
202 | } | 191 | } |
203 | 192 | ||
204 | static void denali_read_buf(struct nand_chip *chip, uint8_t *buf, int len) | 193 | static void denali_select_target(struct nand_chip *chip, int cs) |
205 | { | 194 | { |
195 | struct denali_controller *denali = to_denali_controller(chip); | ||
196 | struct denali_chip_sel *sel = &to_denali_chip(chip)->sels[cs]; | ||
206 | struct mtd_info *mtd = nand_to_mtd(chip); | 197 | struct mtd_info *mtd = nand_to_mtd(chip); |
207 | struct denali_nand_info *denali = mtd_to_denali(mtd); | ||
208 | u32 addr = DENALI_MAP11_DATA | DENALI_BANK(denali); | ||
209 | int i; | ||
210 | 198 | ||
211 | for (i = 0; i < len; i++) | 199 | denali->active_bank = sel->bank; |
212 | buf[i] = denali->host_read(denali, addr); | 200 | |
201 | iowrite32(1 << (chip->phys_erase_shift - chip->page_shift), | ||
202 | denali->reg + PAGES_PER_BLOCK); | ||
203 | iowrite32(chip->options & NAND_BUSWIDTH_16 ? 1 : 0, | ||
204 | denali->reg + DEVICE_WIDTH); | ||
205 | iowrite32(mtd->writesize, denali->reg + DEVICE_MAIN_AREA_SIZE); | ||
206 | iowrite32(mtd->oobsize, denali->reg + DEVICE_SPARE_AREA_SIZE); | ||
207 | iowrite32(chip->options & NAND_ROW_ADDR_3 ? | ||
208 | 0 : TWO_ROW_ADDR_CYCLES__FLAG, | ||
209 | denali->reg + TWO_ROW_ADDR_CYCLES); | ||
210 | iowrite32(FIELD_PREP(ECC_CORRECTION__ERASE_THRESHOLD, 1) | | ||
211 | FIELD_PREP(ECC_CORRECTION__VALUE, chip->ecc.strength), | ||
212 | denali->reg + ECC_CORRECTION); | ||
213 | iowrite32(chip->ecc.size, denali->reg + CFG_DATA_BLOCK_SIZE); | ||
214 | iowrite32(chip->ecc.size, denali->reg + CFG_LAST_DATA_BLOCK_SIZE); | ||
215 | iowrite32(chip->ecc.steps, denali->reg + CFG_NUM_DATA_BLOCKS); | ||
216 | |||
217 | if (chip->options & NAND_KEEP_TIMINGS) | ||
218 | return; | ||
219 | |||
220 | /* update timing registers unless NAND_KEEP_TIMINGS is set */ | ||
221 | iowrite32(sel->hwhr2_and_we_2_re, denali->reg + TWHR2_AND_WE_2_RE); | ||
222 | iowrite32(sel->tcwaw_and_addr_2_data, | ||
223 | denali->reg + TCWAW_AND_ADDR_2_DATA); | ||
224 | iowrite32(sel->re_2_we, denali->reg + RE_2_WE); | ||
225 | iowrite32(sel->acc_clks, denali->reg + ACC_CLKS); | ||
226 | iowrite32(sel->rdwr_en_lo_cnt, denali->reg + RDWR_EN_LO_CNT); | ||
227 | iowrite32(sel->rdwr_en_hi_cnt, denali->reg + RDWR_EN_HI_CNT); | ||
228 | iowrite32(sel->cs_setup_cnt, denali->reg + CS_SETUP_CNT); | ||
229 | iowrite32(sel->re_2_re, denali->reg + RE_2_RE); | ||
213 | } | 230 | } |
214 | 231 | ||
215 | static void denali_write_buf(struct nand_chip *chip, const uint8_t *buf, | 232 | static int denali_change_column(struct nand_chip *chip, unsigned int offset, |
216 | int len) | 233 | void *buf, unsigned int len, bool write) |
217 | { | 234 | { |
218 | struct denali_nand_info *denali = mtd_to_denali(nand_to_mtd(chip)); | 235 | if (write) |
219 | u32 addr = DENALI_MAP11_DATA | DENALI_BANK(denali); | 236 | return nand_change_write_column_op(chip, offset, buf, len, |
220 | int i; | 237 | false); |
221 | 238 | else | |
222 | for (i = 0; i < len; i++) | 239 | return nand_change_read_column_op(chip, offset, buf, len, |
223 | denali->host_write(denali, addr, buf[i]); | 240 | false); |
224 | } | 241 | } |
225 | 242 | ||
226 | static void denali_read_buf16(struct nand_chip *chip, uint8_t *buf, int len) | 243 | static int denali_payload_xfer(struct nand_chip *chip, void *buf, bool write) |
227 | { | 244 | { |
228 | struct denali_nand_info *denali = mtd_to_denali(nand_to_mtd(chip)); | 245 | struct denali_controller *denali = to_denali_controller(chip); |
229 | u32 addr = DENALI_MAP11_DATA | DENALI_BANK(denali); | 246 | struct mtd_info *mtd = nand_to_mtd(chip); |
230 | uint16_t *buf16 = (uint16_t *)buf; | 247 | struct nand_ecc_ctrl *ecc = &chip->ecc; |
231 | int i; | 248 | int writesize = mtd->writesize; |
249 | int oob_skip = denali->oob_skip_bytes; | ||
250 | int ret, i, pos, len; | ||
251 | |||
252 | for (i = 0; i < ecc->steps; i++) { | ||
253 | pos = i * (ecc->size + ecc->bytes); | ||
254 | len = ecc->size; | ||
255 | |||
256 | if (pos >= writesize) { | ||
257 | pos += oob_skip; | ||
258 | } else if (pos + len > writesize) { | ||
259 | /* This chunk overwraps the BBM area. Must be split */ | ||
260 | ret = denali_change_column(chip, pos, buf, | ||
261 | writesize - pos, write); | ||
262 | if (ret) | ||
263 | return ret; | ||
264 | |||
265 | buf += writesize - pos; | ||
266 | len -= writesize - pos; | ||
267 | pos = writesize + oob_skip; | ||
268 | } | ||
269 | |||
270 | ret = denali_change_column(chip, pos, buf, len, write); | ||
271 | if (ret) | ||
272 | return ret; | ||
232 | 273 | ||
233 | for (i = 0; i < len / 2; i++) | 274 | buf += len; |
234 | buf16[i] = denali->host_read(denali, addr); | 275 | } |
276 | |||
277 | return 0; | ||
235 | } | 278 | } |
236 | 279 | ||
237 | static void denali_write_buf16(struct nand_chip *chip, const uint8_t *buf, | 280 | static int denali_oob_xfer(struct nand_chip *chip, void *buf, bool write) |
238 | int len) | ||
239 | { | 281 | { |
240 | struct denali_nand_info *denali = mtd_to_denali(nand_to_mtd(chip)); | 282 | struct denali_controller *denali = to_denali_controller(chip); |
241 | u32 addr = DENALI_MAP11_DATA | DENALI_BANK(denali); | 283 | struct mtd_info *mtd = nand_to_mtd(chip); |
242 | const uint16_t *buf16 = (const uint16_t *)buf; | 284 | struct nand_ecc_ctrl *ecc = &chip->ecc; |
243 | int i; | 285 | int writesize = mtd->writesize; |
286 | int oobsize = mtd->oobsize; | ||
287 | int oob_skip = denali->oob_skip_bytes; | ||
288 | int ret, i, pos, len; | ||
244 | 289 | ||
245 | for (i = 0; i < len / 2; i++) | 290 | /* BBM at the beginning of the OOB area */ |
246 | denali->host_write(denali, addr, buf16[i]); | 291 | ret = denali_change_column(chip, writesize, buf, oob_skip, write); |
292 | if (ret) | ||
293 | return ret; | ||
294 | |||
295 | buf += oob_skip; | ||
296 | |||
297 | for (i = 0; i < ecc->steps; i++) { | ||
298 | pos = ecc->size + i * (ecc->size + ecc->bytes); | ||
299 | |||
300 | if (i == ecc->steps - 1) | ||
301 | /* The last chunk includes OOB free */ | ||
302 | len = writesize + oobsize - pos - oob_skip; | ||
303 | else | ||
304 | len = ecc->bytes; | ||
305 | |||
306 | if (pos >= writesize) { | ||
307 | pos += oob_skip; | ||
308 | } else if (pos + len > writesize) { | ||
309 | /* This chunk overwraps the BBM area. Must be split */ | ||
310 | ret = denali_change_column(chip, pos, buf, | ||
311 | writesize - pos, write); | ||
312 | if (ret) | ||
313 | return ret; | ||
314 | |||
315 | buf += writesize - pos; | ||
316 | len -= writesize - pos; | ||
317 | pos = writesize + oob_skip; | ||
318 | } | ||
319 | |||
320 | ret = denali_change_column(chip, pos, buf, len, write); | ||
321 | if (ret) | ||
322 | return ret; | ||
323 | |||
324 | buf += len; | ||
325 | } | ||
326 | |||
327 | return 0; | ||
247 | } | 328 | } |
248 | 329 | ||
249 | static uint8_t denali_read_byte(struct nand_chip *chip) | 330 | static int denali_read_raw(struct nand_chip *chip, void *buf, void *oob_buf, |
331 | int page) | ||
250 | { | 332 | { |
251 | uint8_t byte; | 333 | int ret; |
334 | |||
335 | if (!buf && !oob_buf) | ||
336 | return -EINVAL; | ||
252 | 337 | ||
253 | denali_read_buf(chip, &byte, 1); | 338 | ret = nand_read_page_op(chip, page, 0, NULL, 0); |
339 | if (ret) | ||
340 | return ret; | ||
254 | 341 | ||
255 | return byte; | 342 | if (buf) { |
343 | ret = denali_payload_xfer(chip, buf, false); | ||
344 | if (ret) | ||
345 | return ret; | ||
346 | } | ||
347 | |||
348 | if (oob_buf) { | ||
349 | ret = denali_oob_xfer(chip, oob_buf, false); | ||
350 | if (ret) | ||
351 | return ret; | ||
352 | } | ||
353 | |||
354 | return 0; | ||
256 | } | 355 | } |
257 | 356 | ||
258 | static void denali_write_byte(struct nand_chip *chip, uint8_t byte) | 357 | static int denali_write_raw(struct nand_chip *chip, const void *buf, |
358 | const void *oob_buf, int page) | ||
259 | { | 359 | { |
260 | denali_write_buf(chip, &byte, 1); | 360 | int ret; |
361 | |||
362 | if (!buf && !oob_buf) | ||
363 | return -EINVAL; | ||
364 | |||
365 | ret = nand_prog_page_begin_op(chip, page, 0, NULL, 0); | ||
366 | if (ret) | ||
367 | return ret; | ||
368 | |||
369 | if (buf) { | ||
370 | ret = denali_payload_xfer(chip, (void *)buf, true); | ||
371 | if (ret) | ||
372 | return ret; | ||
373 | } | ||
374 | |||
375 | if (oob_buf) { | ||
376 | ret = denali_oob_xfer(chip, (void *)oob_buf, true); | ||
377 | if (ret) | ||
378 | return ret; | ||
379 | } | ||
380 | |||
381 | return nand_prog_page_end_op(chip); | ||
261 | } | 382 | } |
262 | 383 | ||
263 | static void denali_cmd_ctrl(struct nand_chip *chip, int dat, unsigned int ctrl) | 384 | static int denali_read_page_raw(struct nand_chip *chip, u8 *buf, |
385 | int oob_required, int page) | ||
264 | { | 386 | { |
265 | struct denali_nand_info *denali = mtd_to_denali(nand_to_mtd(chip)); | 387 | return denali_read_raw(chip, buf, oob_required ? chip->oob_poi : NULL, |
266 | uint32_t type; | 388 | page); |
389 | } | ||
267 | 390 | ||
268 | if (ctrl & NAND_CLE) | 391 | static int denali_write_page_raw(struct nand_chip *chip, const u8 *buf, |
269 | type = DENALI_MAP11_CMD; | 392 | int oob_required, int page) |
270 | else if (ctrl & NAND_ALE) | 393 | { |
271 | type = DENALI_MAP11_ADDR; | 394 | return denali_write_raw(chip, buf, oob_required ? chip->oob_poi : NULL, |
272 | else | 395 | page); |
273 | return; | 396 | } |
274 | 397 | ||
275 | /* | 398 | static int denali_read_oob(struct nand_chip *chip, int page) |
276 | * Some commands are followed by chip->legacy.waitfunc. | 399 | { |
277 | * irq_status must be cleared here to catch the R/B# interrupt later. | 400 | return denali_read_raw(chip, NULL, chip->oob_poi, page); |
278 | */ | 401 | } |
279 | if (ctrl & NAND_CTRL_CHANGE) | ||
280 | denali_reset_irq(denali); | ||
281 | 402 | ||
282 | denali->host_write(denali, DENALI_BANK(denali) | type, dat); | 403 | static int denali_write_oob(struct nand_chip *chip, int page) |
404 | { | ||
405 | return denali_write_raw(chip, NULL, chip->oob_poi, page); | ||
283 | } | 406 | } |
284 | 407 | ||
285 | static int denali_check_erased_page(struct mtd_info *mtd, | 408 | static int denali_check_erased_page(struct nand_chip *chip, u8 *buf, |
286 | struct nand_chip *chip, uint8_t *buf, | ||
287 | unsigned long uncor_ecc_flags, | 409 | unsigned long uncor_ecc_flags, |
288 | unsigned int max_bitflips) | 410 | unsigned int max_bitflips) |
289 | { | 411 | { |
290 | struct denali_nand_info *denali = mtd_to_denali(mtd); | 412 | struct denali_controller *denali = to_denali_controller(chip); |
291 | uint8_t *ecc_code = chip->oob_poi + denali->oob_skip_bytes; | 413 | struct mtd_ecc_stats *ecc_stats = &nand_to_mtd(chip)->ecc_stats; |
292 | int ecc_steps = chip->ecc.steps; | 414 | struct nand_ecc_ctrl *ecc = &chip->ecc; |
293 | int ecc_size = chip->ecc.size; | 415 | u8 *ecc_code = chip->oob_poi + denali->oob_skip_bytes; |
294 | int ecc_bytes = chip->ecc.bytes; | ||
295 | int i, stat; | 416 | int i, stat; |
296 | 417 | ||
297 | for (i = 0; i < ecc_steps; i++) { | 418 | for (i = 0; i < ecc->steps; i++) { |
298 | if (!(uncor_ecc_flags & BIT(i))) | 419 | if (!(uncor_ecc_flags & BIT(i))) |
299 | continue; | 420 | continue; |
300 | 421 | ||
301 | stat = nand_check_erased_ecc_chunk(buf, ecc_size, | 422 | stat = nand_check_erased_ecc_chunk(buf, ecc->size, ecc_code, |
302 | ecc_code, ecc_bytes, | 423 | ecc->bytes, NULL, 0, |
303 | NULL, 0, | 424 | ecc->strength); |
304 | chip->ecc.strength); | ||
305 | if (stat < 0) { | 425 | if (stat < 0) { |
306 | mtd->ecc_stats.failed++; | 426 | ecc_stats->failed++; |
307 | } else { | 427 | } else { |
308 | mtd->ecc_stats.corrected += stat; | 428 | ecc_stats->corrected += stat; |
309 | max_bitflips = max_t(unsigned int, max_bitflips, stat); | 429 | max_bitflips = max_t(unsigned int, max_bitflips, stat); |
310 | } | 430 | } |
311 | 431 | ||
312 | buf += ecc_size; | 432 | buf += ecc->size; |
313 | ecc_code += ecc_bytes; | 433 | ecc_code += ecc->bytes; |
314 | } | 434 | } |
315 | 435 | ||
316 | return max_bitflips; | 436 | return max_bitflips; |
317 | } | 437 | } |
318 | 438 | ||
319 | static int denali_hw_ecc_fixup(struct mtd_info *mtd, | 439 | static int denali_hw_ecc_fixup(struct nand_chip *chip, |
320 | struct denali_nand_info *denali, | ||
321 | unsigned long *uncor_ecc_flags) | 440 | unsigned long *uncor_ecc_flags) |
322 | { | 441 | { |
323 | struct nand_chip *chip = mtd_to_nand(mtd); | 442 | struct denali_controller *denali = to_denali_controller(chip); |
443 | struct mtd_ecc_stats *ecc_stats = &nand_to_mtd(chip)->ecc_stats; | ||
324 | int bank = denali->active_bank; | 444 | int bank = denali->active_bank; |
325 | uint32_t ecc_cor; | 445 | u32 ecc_cor; |
326 | unsigned int max_bitflips; | 446 | unsigned int max_bitflips; |
327 | 447 | ||
328 | ecc_cor = ioread32(denali->reg + ECC_COR_INFO(bank)); | 448 | ecc_cor = ioread32(denali->reg + ECC_COR_INFO(bank)); |
@@ -346,23 +466,24 @@ static int denali_hw_ecc_fixup(struct mtd_info *mtd, | |||
346 | * Unfortunately, we can not know the total number of corrected bits in | 466 | * Unfortunately, we can not know the total number of corrected bits in |
347 | * the page. Increase the stats by max_bitflips. (compromised solution) | 467 | * the page. Increase the stats by max_bitflips. (compromised solution) |
348 | */ | 468 | */ |
349 | mtd->ecc_stats.corrected += max_bitflips; | 469 | ecc_stats->corrected += max_bitflips; |
350 | 470 | ||
351 | return max_bitflips; | 471 | return max_bitflips; |
352 | } | 472 | } |
353 | 473 | ||
354 | static int denali_sw_ecc_fixup(struct mtd_info *mtd, | 474 | static int denali_sw_ecc_fixup(struct nand_chip *chip, |
355 | struct denali_nand_info *denali, | 475 | unsigned long *uncor_ecc_flags, u8 *buf) |
356 | unsigned long *uncor_ecc_flags, uint8_t *buf) | ||
357 | { | 476 | { |
358 | unsigned int ecc_size = denali->nand.ecc.size; | 477 | struct denali_controller *denali = to_denali_controller(chip); |
478 | struct mtd_ecc_stats *ecc_stats = &nand_to_mtd(chip)->ecc_stats; | ||
479 | unsigned int ecc_size = chip->ecc.size; | ||
359 | unsigned int bitflips = 0; | 480 | unsigned int bitflips = 0; |
360 | unsigned int max_bitflips = 0; | 481 | unsigned int max_bitflips = 0; |
361 | uint32_t err_addr, err_cor_info; | 482 | u32 err_addr, err_cor_info; |
362 | unsigned int err_byte, err_sector, err_device; | 483 | unsigned int err_byte, err_sector, err_device; |
363 | uint8_t err_cor_value; | 484 | u8 err_cor_value; |
364 | unsigned int prev_sector = 0; | 485 | unsigned int prev_sector = 0; |
365 | uint32_t irq_status; | 486 | u32 irq_status; |
366 | 487 | ||
367 | denali_reset_irq(denali); | 488 | denali_reset_irq(denali); |
368 | 489 | ||
@@ -404,7 +525,7 @@ static int denali_sw_ecc_fixup(struct mtd_info *mtd, | |||
404 | /* correct the ECC error */ | 525 | /* correct the ECC error */ |
405 | flips_in_byte = hweight8(buf[offset] ^ err_cor_value); | 526 | flips_in_byte = hweight8(buf[offset] ^ err_cor_value); |
406 | buf[offset] ^= err_cor_value; | 527 | buf[offset] ^= err_cor_value; |
407 | mtd->ecc_stats.corrected += flips_in_byte; | 528 | ecc_stats->corrected += flips_in_byte; |
408 | bitflips += flips_in_byte; | 529 | bitflips += flips_in_byte; |
409 | 530 | ||
410 | max_bitflips = max(max_bitflips, bitflips); | 531 | max_bitflips = max(max_bitflips, bitflips); |
@@ -424,10 +545,10 @@ static int denali_sw_ecc_fixup(struct mtd_info *mtd, | |||
424 | return max_bitflips; | 545 | return max_bitflips; |
425 | } | 546 | } |
426 | 547 | ||
427 | static void denali_setup_dma64(struct denali_nand_info *denali, | 548 | static void denali_setup_dma64(struct denali_controller *denali, |
428 | dma_addr_t dma_addr, int page, int write) | 549 | dma_addr_t dma_addr, int page, bool write) |
429 | { | 550 | { |
430 | uint32_t mode; | 551 | u32 mode; |
431 | const int page_count = 1; | 552 | const int page_count = 1; |
432 | 553 | ||
433 | mode = DENALI_MAP10 | DENALI_BANK(denali) | page; | 554 | mode = DENALI_MAP10 | DENALI_BANK(denali) | page; |
@@ -439,7 +560,8 @@ static void denali_setup_dma64(struct denali_nand_info *denali, | |||
439 | * burst len = 64 bytes, the number of pages | 560 | * burst len = 64 bytes, the number of pages |
440 | */ | 561 | */ |
441 | denali->host_write(denali, mode, | 562 | denali->host_write(denali, mode, |
442 | 0x01002000 | (64 << 16) | (write << 8) | page_count); | 563 | 0x01002000 | (64 << 16) | |
564 | (write ? BIT(8) : 0) | page_count); | ||
443 | 565 | ||
444 | /* 2. set memory low address */ | 566 | /* 2. set memory low address */ |
445 | denali->host_write(denali, mode, lower_32_bits(dma_addr)); | 567 | denali->host_write(denali, mode, lower_32_bits(dma_addr)); |
@@ -448,10 +570,10 @@ static void denali_setup_dma64(struct denali_nand_info *denali, | |||
448 | denali->host_write(denali, mode, upper_32_bits(dma_addr)); | 570 | denali->host_write(denali, mode, upper_32_bits(dma_addr)); |
449 | } | 571 | } |
450 | 572 | ||
451 | static void denali_setup_dma32(struct denali_nand_info *denali, | 573 | static void denali_setup_dma32(struct denali_controller *denali, |
452 | dma_addr_t dma_addr, int page, int write) | 574 | dma_addr_t dma_addr, int page, bool write) |
453 | { | 575 | { |
454 | uint32_t mode; | 576 | u32 mode; |
455 | const int page_count = 1; | 577 | const int page_count = 1; |
456 | 578 | ||
457 | mode = DENALI_MAP10 | DENALI_BANK(denali); | 579 | mode = DENALI_MAP10 | DENALI_BANK(denali); |
@@ -460,7 +582,7 @@ static void denali_setup_dma32(struct denali_nand_info *denali, | |||
460 | 582 | ||
461 | /* 1. setup transfer type and # of pages */ | 583 | /* 1. setup transfer type and # of pages */ |
462 | denali->host_write(denali, mode | page, | 584 | denali->host_write(denali, mode | page, |
463 | 0x2000 | (write << 8) | page_count); | 585 | 0x2000 | (write ? BIT(8) : 0) | page_count); |
464 | 586 | ||
465 | /* 2. set memory high address bits 23:8 */ | 587 | /* 2. set memory high address bits 23:8 */ |
466 | denali->host_write(denali, mode | ((dma_addr >> 16) << 8), 0x2200); | 588 | denali->host_write(denali, mode | ((dma_addr >> 16) << 8), 0x2200); |
@@ -472,12 +594,11 @@ static void denali_setup_dma32(struct denali_nand_info *denali, | |||
472 | denali->host_write(denali, mode | 0x14000, 0x2400); | 594 | denali->host_write(denali, mode | 0x14000, 0x2400); |
473 | } | 595 | } |
474 | 596 | ||
475 | static int denali_pio_read(struct denali_nand_info *denali, void *buf, | 597 | static int denali_pio_read(struct denali_controller *denali, u32 *buf, |
476 | size_t size, int page) | 598 | size_t size, int page) |
477 | { | 599 | { |
478 | u32 addr = DENALI_MAP01 | DENALI_BANK(denali) | page; | 600 | u32 addr = DENALI_MAP01 | DENALI_BANK(denali) | page; |
479 | uint32_t *buf32 = (uint32_t *)buf; | 601 | u32 irq_status, ecc_err_mask; |
480 | uint32_t irq_status, ecc_err_mask; | ||
481 | int i; | 602 | int i; |
482 | 603 | ||
483 | if (denali->caps & DENALI_CAP_HW_ECC_FIXUP) | 604 | if (denali->caps & DENALI_CAP_HW_ECC_FIXUP) |
@@ -488,7 +609,7 @@ static int denali_pio_read(struct denali_nand_info *denali, void *buf, | |||
488 | denali_reset_irq(denali); | 609 | denali_reset_irq(denali); |
489 | 610 | ||
490 | for (i = 0; i < size / 4; i++) | 611 | for (i = 0; i < size / 4; i++) |
491 | *buf32++ = denali->host_read(denali, addr); | 612 | buf[i] = denali->host_read(denali, addr); |
492 | 613 | ||
493 | irq_status = denali_wait_for_irq(denali, INTR__PAGE_XFER_INC); | 614 | irq_status = denali_wait_for_irq(denali, INTR__PAGE_XFER_INC); |
494 | if (!(irq_status & INTR__PAGE_XFER_INC)) | 615 | if (!(irq_status & INTR__PAGE_XFER_INC)) |
@@ -500,29 +621,29 @@ static int denali_pio_read(struct denali_nand_info *denali, void *buf, | |||
500 | return irq_status & ecc_err_mask ? -EBADMSG : 0; | 621 | return irq_status & ecc_err_mask ? -EBADMSG : 0; |
501 | } | 622 | } |
502 | 623 | ||
503 | static int denali_pio_write(struct denali_nand_info *denali, | 624 | static int denali_pio_write(struct denali_controller *denali, const u32 *buf, |
504 | const void *buf, size_t size, int page) | 625 | size_t size, int page) |
505 | { | 626 | { |
506 | u32 addr = DENALI_MAP01 | DENALI_BANK(denali) | page; | 627 | u32 addr = DENALI_MAP01 | DENALI_BANK(denali) | page; |
507 | const uint32_t *buf32 = (uint32_t *)buf; | 628 | u32 irq_status; |
508 | uint32_t irq_status; | ||
509 | int i; | 629 | int i; |
510 | 630 | ||
511 | denali_reset_irq(denali); | 631 | denali_reset_irq(denali); |
512 | 632 | ||
513 | for (i = 0; i < size / 4; i++) | 633 | for (i = 0; i < size / 4; i++) |
514 | denali->host_write(denali, addr, *buf32++); | 634 | denali->host_write(denali, addr, buf[i]); |
515 | 635 | ||
516 | irq_status = denali_wait_for_irq(denali, | 636 | irq_status = denali_wait_for_irq(denali, |
517 | INTR__PROGRAM_COMP | INTR__PROGRAM_FAIL); | 637 | INTR__PROGRAM_COMP | |
638 | INTR__PROGRAM_FAIL); | ||
518 | if (!(irq_status & INTR__PROGRAM_COMP)) | 639 | if (!(irq_status & INTR__PROGRAM_COMP)) |
519 | return -EIO; | 640 | return -EIO; |
520 | 641 | ||
521 | return 0; | 642 | return 0; |
522 | } | 643 | } |
523 | 644 | ||
524 | static int denali_pio_xfer(struct denali_nand_info *denali, void *buf, | 645 | static int denali_pio_xfer(struct denali_controller *denali, void *buf, |
525 | size_t size, int page, int write) | 646 | size_t size, int page, bool write) |
526 | { | 647 | { |
527 | if (write) | 648 | if (write) |
528 | return denali_pio_write(denali, buf, size, page); | 649 | return denali_pio_write(denali, buf, size, page); |
@@ -530,11 +651,11 @@ static int denali_pio_xfer(struct denali_nand_info *denali, void *buf, | |||
530 | return denali_pio_read(denali, buf, size, page); | 651 | return denali_pio_read(denali, buf, size, page); |
531 | } | 652 | } |
532 | 653 | ||
533 | static int denali_dma_xfer(struct denali_nand_info *denali, void *buf, | 654 | static int denali_dma_xfer(struct denali_controller *denali, void *buf, |
534 | size_t size, int page, int write) | 655 | size_t size, int page, bool write) |
535 | { | 656 | { |
536 | dma_addr_t dma_addr; | 657 | dma_addr_t dma_addr; |
537 | uint32_t irq_mask, irq_status, ecc_err_mask; | 658 | u32 irq_mask, irq_status, ecc_err_mask; |
538 | enum dma_data_direction dir = write ? DMA_TO_DEVICE : DMA_FROM_DEVICE; | 659 | enum dma_data_direction dir = write ? DMA_TO_DEVICE : DMA_FROM_DEVICE; |
539 | int ret = 0; | 660 | int ret = 0; |
540 | 661 | ||
@@ -587,12 +708,12 @@ static int denali_dma_xfer(struct denali_nand_info *denali, void *buf, | |||
587 | return ret; | 708 | return ret; |
588 | } | 709 | } |
589 | 710 | ||
590 | static int denali_data_xfer(struct denali_nand_info *denali, void *buf, | 711 | static int denali_page_xfer(struct nand_chip *chip, void *buf, size_t size, |
591 | size_t size, int page, int raw, int write) | 712 | int page, bool write) |
592 | { | 713 | { |
593 | iowrite32(raw ? 0 : ECC_ENABLE__FLAG, denali->reg + ECC_ENABLE); | 714 | struct denali_controller *denali = to_denali_controller(chip); |
594 | iowrite32(raw ? TRANSFER_SPARE_REG__FLAG : 0, | 715 | |
595 | denali->reg + TRANSFER_SPARE_REG); | 716 | denali_select_target(chip, chip->cur_cs); |
596 | 717 | ||
597 | if (denali->dma_avail) | 718 | if (denali->dma_avail) |
598 | return denali_dma_xfer(denali, buf, size, page, write); | 719 | return denali_dma_xfer(denali, buf, size, page, write); |
@@ -600,180 +721,23 @@ static int denali_data_xfer(struct denali_nand_info *denali, void *buf, | |||
600 | return denali_pio_xfer(denali, buf, size, page, write); | 721 | return denali_pio_xfer(denali, buf, size, page, write); |
601 | } | 722 | } |
602 | 723 | ||
603 | static void denali_oob_xfer(struct mtd_info *mtd, struct nand_chip *chip, | 724 | static int denali_read_page(struct nand_chip *chip, u8 *buf, |
604 | int page, int write) | ||
605 | { | ||
606 | struct denali_nand_info *denali = mtd_to_denali(mtd); | ||
607 | int writesize = mtd->writesize; | ||
608 | int oobsize = mtd->oobsize; | ||
609 | uint8_t *bufpoi = chip->oob_poi; | ||
610 | int ecc_steps = chip->ecc.steps; | ||
611 | int ecc_size = chip->ecc.size; | ||
612 | int ecc_bytes = chip->ecc.bytes; | ||
613 | int oob_skip = denali->oob_skip_bytes; | ||
614 | size_t size = writesize + oobsize; | ||
615 | int i, pos, len; | ||
616 | |||
617 | /* BBM at the beginning of the OOB area */ | ||
618 | if (write) | ||
619 | nand_prog_page_begin_op(chip, page, writesize, bufpoi, | ||
620 | oob_skip); | ||
621 | else | ||
622 | nand_read_page_op(chip, page, writesize, bufpoi, oob_skip); | ||
623 | bufpoi += oob_skip; | ||
624 | |||
625 | /* OOB ECC */ | ||
626 | for (i = 0; i < ecc_steps; i++) { | ||
627 | pos = ecc_size + i * (ecc_size + ecc_bytes); | ||
628 | len = ecc_bytes; | ||
629 | |||
630 | if (pos >= writesize) | ||
631 | pos += oob_skip; | ||
632 | else if (pos + len > writesize) | ||
633 | len = writesize - pos; | ||
634 | |||
635 | if (write) | ||
636 | nand_change_write_column_op(chip, pos, bufpoi, len, | ||
637 | false); | ||
638 | else | ||
639 | nand_change_read_column_op(chip, pos, bufpoi, len, | ||
640 | false); | ||
641 | bufpoi += len; | ||
642 | if (len < ecc_bytes) { | ||
643 | len = ecc_bytes - len; | ||
644 | if (write) | ||
645 | nand_change_write_column_op(chip, writesize + | ||
646 | oob_skip, bufpoi, | ||
647 | len, false); | ||
648 | else | ||
649 | nand_change_read_column_op(chip, writesize + | ||
650 | oob_skip, bufpoi, | ||
651 | len, false); | ||
652 | bufpoi += len; | ||
653 | } | ||
654 | } | ||
655 | |||
656 | /* OOB free */ | ||
657 | len = oobsize - (bufpoi - chip->oob_poi); | ||
658 | if (write) | ||
659 | nand_change_write_column_op(chip, size - len, bufpoi, len, | ||
660 | false); | ||
661 | else | ||
662 | nand_change_read_column_op(chip, size - len, bufpoi, len, | ||
663 | false); | ||
664 | } | ||
665 | |||
666 | static int denali_read_page_raw(struct nand_chip *chip, uint8_t *buf, | ||
667 | int oob_required, int page) | ||
668 | { | ||
669 | struct mtd_info *mtd = nand_to_mtd(chip); | ||
670 | struct denali_nand_info *denali = mtd_to_denali(mtd); | ||
671 | int writesize = mtd->writesize; | ||
672 | int oobsize = mtd->oobsize; | ||
673 | int ecc_steps = chip->ecc.steps; | ||
674 | int ecc_size = chip->ecc.size; | ||
675 | int ecc_bytes = chip->ecc.bytes; | ||
676 | void *tmp_buf = denali->buf; | ||
677 | int oob_skip = denali->oob_skip_bytes; | ||
678 | size_t size = writesize + oobsize; | ||
679 | int ret, i, pos, len; | ||
680 | |||
681 | ret = denali_data_xfer(denali, tmp_buf, size, page, 1, 0); | ||
682 | if (ret) | ||
683 | return ret; | ||
684 | |||
685 | /* Arrange the buffer for syndrome payload/ecc layout */ | ||
686 | if (buf) { | ||
687 | for (i = 0; i < ecc_steps; i++) { | ||
688 | pos = i * (ecc_size + ecc_bytes); | ||
689 | len = ecc_size; | ||
690 | |||
691 | if (pos >= writesize) | ||
692 | pos += oob_skip; | ||
693 | else if (pos + len > writesize) | ||
694 | len = writesize - pos; | ||
695 | |||
696 | memcpy(buf, tmp_buf + pos, len); | ||
697 | buf += len; | ||
698 | if (len < ecc_size) { | ||
699 | len = ecc_size - len; | ||
700 | memcpy(buf, tmp_buf + writesize + oob_skip, | ||
701 | len); | ||
702 | buf += len; | ||
703 | } | ||
704 | } | ||
705 | } | ||
706 | |||
707 | if (oob_required) { | ||
708 | uint8_t *oob = chip->oob_poi; | ||
709 | |||
710 | /* BBM at the beginning of the OOB area */ | ||
711 | memcpy(oob, tmp_buf + writesize, oob_skip); | ||
712 | oob += oob_skip; | ||
713 | |||
714 | /* OOB ECC */ | ||
715 | for (i = 0; i < ecc_steps; i++) { | ||
716 | pos = ecc_size + i * (ecc_size + ecc_bytes); | ||
717 | len = ecc_bytes; | ||
718 | |||
719 | if (pos >= writesize) | ||
720 | pos += oob_skip; | ||
721 | else if (pos + len > writesize) | ||
722 | len = writesize - pos; | ||
723 | |||
724 | memcpy(oob, tmp_buf + pos, len); | ||
725 | oob += len; | ||
726 | if (len < ecc_bytes) { | ||
727 | len = ecc_bytes - len; | ||
728 | memcpy(oob, tmp_buf + writesize + oob_skip, | ||
729 | len); | ||
730 | oob += len; | ||
731 | } | ||
732 | } | ||
733 | |||
734 | /* OOB free */ | ||
735 | len = oobsize - (oob - chip->oob_poi); | ||
736 | memcpy(oob, tmp_buf + size - len, len); | ||
737 | } | ||
738 | |||
739 | return 0; | ||
740 | } | ||
741 | |||
742 | static int denali_read_oob(struct nand_chip *chip, int page) | ||
743 | { | ||
744 | struct mtd_info *mtd = nand_to_mtd(chip); | ||
745 | |||
746 | denali_oob_xfer(mtd, chip, page, 0); | ||
747 | |||
748 | return 0; | ||
749 | } | ||
750 | |||
751 | static int denali_write_oob(struct nand_chip *chip, int page) | ||
752 | { | ||
753 | struct mtd_info *mtd = nand_to_mtd(chip); | ||
754 | |||
755 | denali_oob_xfer(mtd, chip, page, 1); | ||
756 | |||
757 | return nand_prog_page_end_op(chip); | ||
758 | } | ||
759 | |||
760 | static int denali_read_page(struct nand_chip *chip, uint8_t *buf, | ||
761 | int oob_required, int page) | 725 | int oob_required, int page) |
762 | { | 726 | { |
727 | struct denali_controller *denali = to_denali_controller(chip); | ||
763 | struct mtd_info *mtd = nand_to_mtd(chip); | 728 | struct mtd_info *mtd = nand_to_mtd(chip); |
764 | struct denali_nand_info *denali = mtd_to_denali(mtd); | ||
765 | unsigned long uncor_ecc_flags = 0; | 729 | unsigned long uncor_ecc_flags = 0; |
766 | int stat = 0; | 730 | int stat = 0; |
767 | int ret; | 731 | int ret; |
768 | 732 | ||
769 | ret = denali_data_xfer(denali, buf, mtd->writesize, page, 0, 0); | 733 | ret = denali_page_xfer(chip, buf, mtd->writesize, page, false); |
770 | if (ret && ret != -EBADMSG) | 734 | if (ret && ret != -EBADMSG) |
771 | return ret; | 735 | return ret; |
772 | 736 | ||
773 | if (denali->caps & DENALI_CAP_HW_ECC_FIXUP) | 737 | if (denali->caps & DENALI_CAP_HW_ECC_FIXUP) |
774 | stat = denali_hw_ecc_fixup(mtd, denali, &uncor_ecc_flags); | 738 | stat = denali_hw_ecc_fixup(chip, &uncor_ecc_flags); |
775 | else if (ret == -EBADMSG) | 739 | else if (ret == -EBADMSG) |
776 | stat = denali_sw_ecc_fixup(mtd, denali, &uncor_ecc_flags, buf); | 740 | stat = denali_sw_ecc_fixup(chip, &uncor_ecc_flags, buf); |
777 | 741 | ||
778 | if (stat < 0) | 742 | if (stat < 0) |
779 | return stat; | 743 | return stat; |
@@ -783,130 +747,32 @@ static int denali_read_page(struct nand_chip *chip, uint8_t *buf, | |||
783 | if (ret) | 747 | if (ret) |
784 | return ret; | 748 | return ret; |
785 | 749 | ||
786 | stat = denali_check_erased_page(mtd, chip, buf, | 750 | stat = denali_check_erased_page(chip, buf, |
787 | uncor_ecc_flags, stat); | 751 | uncor_ecc_flags, stat); |
788 | } | 752 | } |
789 | 753 | ||
790 | return stat; | 754 | return stat; |
791 | } | 755 | } |
792 | 756 | ||
793 | static int denali_write_page_raw(struct nand_chip *chip, const uint8_t *buf, | 757 | static int denali_write_page(struct nand_chip *chip, const u8 *buf, |
794 | int oob_required, int page) | ||
795 | { | ||
796 | struct mtd_info *mtd = nand_to_mtd(chip); | ||
797 | struct denali_nand_info *denali = mtd_to_denali(mtd); | ||
798 | int writesize = mtd->writesize; | ||
799 | int oobsize = mtd->oobsize; | ||
800 | int ecc_steps = chip->ecc.steps; | ||
801 | int ecc_size = chip->ecc.size; | ||
802 | int ecc_bytes = chip->ecc.bytes; | ||
803 | void *tmp_buf = denali->buf; | ||
804 | int oob_skip = denali->oob_skip_bytes; | ||
805 | size_t size = writesize + oobsize; | ||
806 | int i, pos, len; | ||
807 | |||
808 | /* | ||
809 | * Fill the buffer with 0xff first except the full page transfer. | ||
810 | * This simplifies the logic. | ||
811 | */ | ||
812 | if (!buf || !oob_required) | ||
813 | memset(tmp_buf, 0xff, size); | ||
814 | |||
815 | /* Arrange the buffer for syndrome payload/ecc layout */ | ||
816 | if (buf) { | ||
817 | for (i = 0; i < ecc_steps; i++) { | ||
818 | pos = i * (ecc_size + ecc_bytes); | ||
819 | len = ecc_size; | ||
820 | |||
821 | if (pos >= writesize) | ||
822 | pos += oob_skip; | ||
823 | else if (pos + len > writesize) | ||
824 | len = writesize - pos; | ||
825 | |||
826 | memcpy(tmp_buf + pos, buf, len); | ||
827 | buf += len; | ||
828 | if (len < ecc_size) { | ||
829 | len = ecc_size - len; | ||
830 | memcpy(tmp_buf + writesize + oob_skip, buf, | ||
831 | len); | ||
832 | buf += len; | ||
833 | } | ||
834 | } | ||
835 | } | ||
836 | |||
837 | if (oob_required) { | ||
838 | const uint8_t *oob = chip->oob_poi; | ||
839 | |||
840 | /* BBM at the beginning of the OOB area */ | ||
841 | memcpy(tmp_buf + writesize, oob, oob_skip); | ||
842 | oob += oob_skip; | ||
843 | |||
844 | /* OOB ECC */ | ||
845 | for (i = 0; i < ecc_steps; i++) { | ||
846 | pos = ecc_size + i * (ecc_size + ecc_bytes); | ||
847 | len = ecc_bytes; | ||
848 | |||
849 | if (pos >= writesize) | ||
850 | pos += oob_skip; | ||
851 | else if (pos + len > writesize) | ||
852 | len = writesize - pos; | ||
853 | |||
854 | memcpy(tmp_buf + pos, oob, len); | ||
855 | oob += len; | ||
856 | if (len < ecc_bytes) { | ||
857 | len = ecc_bytes - len; | ||
858 | memcpy(tmp_buf + writesize + oob_skip, oob, | ||
859 | len); | ||
860 | oob += len; | ||
861 | } | ||
862 | } | ||
863 | |||
864 | /* OOB free */ | ||
865 | len = oobsize - (oob - chip->oob_poi); | ||
866 | memcpy(tmp_buf + size - len, oob, len); | ||
867 | } | ||
868 | |||
869 | return denali_data_xfer(denali, tmp_buf, size, page, 1, 1); | ||
870 | } | ||
871 | |||
872 | static int denali_write_page(struct nand_chip *chip, const uint8_t *buf, | ||
873 | int oob_required, int page) | 758 | int oob_required, int page) |
874 | { | 759 | { |
875 | struct mtd_info *mtd = nand_to_mtd(chip); | 760 | struct mtd_info *mtd = nand_to_mtd(chip); |
876 | struct denali_nand_info *denali = mtd_to_denali(mtd); | ||
877 | 761 | ||
878 | return denali_data_xfer(denali, (void *)buf, mtd->writesize, | 762 | return denali_page_xfer(chip, (void *)buf, mtd->writesize, page, true); |
879 | page, 0, 1); | ||
880 | } | ||
881 | |||
882 | static void denali_select_chip(struct nand_chip *chip, int cs) | ||
883 | { | ||
884 | struct denali_nand_info *denali = mtd_to_denali(nand_to_mtd(chip)); | ||
885 | |||
886 | denali->active_bank = cs; | ||
887 | } | ||
888 | |||
889 | static int denali_waitfunc(struct nand_chip *chip) | ||
890 | { | ||
891 | struct denali_nand_info *denali = mtd_to_denali(nand_to_mtd(chip)); | ||
892 | uint32_t irq_status; | ||
893 | |||
894 | /* R/B# pin transitioned from low to high? */ | ||
895 | irq_status = denali_wait_for_irq(denali, INTR__INT_ACT); | ||
896 | |||
897 | return irq_status & INTR__INT_ACT ? 0 : NAND_STATUS_FAIL; | ||
898 | } | 763 | } |
899 | 764 | ||
900 | static int denali_setup_data_interface(struct nand_chip *chip, int chipnr, | 765 | static int denali_setup_data_interface(struct nand_chip *chip, int chipnr, |
901 | const struct nand_data_interface *conf) | 766 | const struct nand_data_interface *conf) |
902 | { | 767 | { |
903 | struct denali_nand_info *denali = mtd_to_denali(nand_to_mtd(chip)); | 768 | struct denali_controller *denali = to_denali_controller(chip); |
769 | struct denali_chip_sel *sel; | ||
904 | const struct nand_sdr_timings *timings; | 770 | const struct nand_sdr_timings *timings; |
905 | unsigned long t_x, mult_x; | 771 | unsigned long t_x, mult_x; |
906 | int acc_clks, re_2_we, re_2_re, we_2_re, addr_2_data; | 772 | int acc_clks, re_2_we, re_2_re, we_2_re, addr_2_data; |
907 | int rdwr_en_lo, rdwr_en_hi, rdwr_en_lo_hi, cs_setup; | 773 | int rdwr_en_lo, rdwr_en_hi, rdwr_en_lo_hi, cs_setup; |
908 | int addr_2_data_mask; | 774 | int addr_2_data_mask; |
909 | uint32_t tmp; | 775 | u32 tmp; |
910 | 776 | ||
911 | timings = nand_get_sdr_timings(conf); | 777 | timings = nand_get_sdr_timings(conf); |
912 | if (IS_ERR(timings)) | 778 | if (IS_ERR(timings)) |
@@ -929,6 +795,8 @@ static int denali_setup_data_interface(struct nand_chip *chip, int chipnr, | |||
929 | if (chipnr == NAND_DATA_IFACE_CHECK_ONLY) | 795 | if (chipnr == NAND_DATA_IFACE_CHECK_ONLY) |
930 | return 0; | 796 | return 0; |
931 | 797 | ||
798 | sel = &to_denali_chip(chip)->sels[chipnr]; | ||
799 | |||
932 | /* tREA -> ACC_CLKS */ | 800 | /* tREA -> ACC_CLKS */ |
933 | acc_clks = DIV_ROUND_UP(timings->tREA_max, t_x); | 801 | acc_clks = DIV_ROUND_UP(timings->tREA_max, t_x); |
934 | acc_clks = min_t(int, acc_clks, ACC_CLKS__VALUE); | 802 | acc_clks = min_t(int, acc_clks, ACC_CLKS__VALUE); |
@@ -936,7 +804,7 @@ static int denali_setup_data_interface(struct nand_chip *chip, int chipnr, | |||
936 | tmp = ioread32(denali->reg + ACC_CLKS); | 804 | tmp = ioread32(denali->reg + ACC_CLKS); |
937 | tmp &= ~ACC_CLKS__VALUE; | 805 | tmp &= ~ACC_CLKS__VALUE; |
938 | tmp |= FIELD_PREP(ACC_CLKS__VALUE, acc_clks); | 806 | tmp |= FIELD_PREP(ACC_CLKS__VALUE, acc_clks); |
939 | iowrite32(tmp, denali->reg + ACC_CLKS); | 807 | sel->acc_clks = tmp; |
940 | 808 | ||
941 | /* tRWH -> RE_2_WE */ | 809 | /* tRWH -> RE_2_WE */ |
942 | re_2_we = DIV_ROUND_UP(timings->tRHW_min, t_x); | 810 | re_2_we = DIV_ROUND_UP(timings->tRHW_min, t_x); |
@@ -945,7 +813,7 @@ static int denali_setup_data_interface(struct nand_chip *chip, int chipnr, | |||
945 | tmp = ioread32(denali->reg + RE_2_WE); | 813 | tmp = ioread32(denali->reg + RE_2_WE); |
946 | tmp &= ~RE_2_WE__VALUE; | 814 | tmp &= ~RE_2_WE__VALUE; |
947 | tmp |= FIELD_PREP(RE_2_WE__VALUE, re_2_we); | 815 | tmp |= FIELD_PREP(RE_2_WE__VALUE, re_2_we); |
948 | iowrite32(tmp, denali->reg + RE_2_WE); | 816 | sel->re_2_we = tmp; |
949 | 817 | ||
950 | /* tRHZ -> RE_2_RE */ | 818 | /* tRHZ -> RE_2_RE */ |
951 | re_2_re = DIV_ROUND_UP(timings->tRHZ_max, t_x); | 819 | re_2_re = DIV_ROUND_UP(timings->tRHZ_max, t_x); |
@@ -954,7 +822,7 @@ static int denali_setup_data_interface(struct nand_chip *chip, int chipnr, | |||
954 | tmp = ioread32(denali->reg + RE_2_RE); | 822 | tmp = ioread32(denali->reg + RE_2_RE); |
955 | tmp &= ~RE_2_RE__VALUE; | 823 | tmp &= ~RE_2_RE__VALUE; |
956 | tmp |= FIELD_PREP(RE_2_RE__VALUE, re_2_re); | 824 | tmp |= FIELD_PREP(RE_2_RE__VALUE, re_2_re); |
957 | iowrite32(tmp, denali->reg + RE_2_RE); | 825 | sel->re_2_re = tmp; |
958 | 826 | ||
959 | /* | 827 | /* |
960 | * tCCS, tWHR -> WE_2_RE | 828 | * tCCS, tWHR -> WE_2_RE |
@@ -968,7 +836,7 @@ static int denali_setup_data_interface(struct nand_chip *chip, int chipnr, | |||
968 | tmp = ioread32(denali->reg + TWHR2_AND_WE_2_RE); | 836 | tmp = ioread32(denali->reg + TWHR2_AND_WE_2_RE); |
969 | tmp &= ~TWHR2_AND_WE_2_RE__WE_2_RE; | 837 | tmp &= ~TWHR2_AND_WE_2_RE__WE_2_RE; |
970 | tmp |= FIELD_PREP(TWHR2_AND_WE_2_RE__WE_2_RE, we_2_re); | 838 | tmp |= FIELD_PREP(TWHR2_AND_WE_2_RE__WE_2_RE, we_2_re); |
971 | iowrite32(tmp, denali->reg + TWHR2_AND_WE_2_RE); | 839 | sel->hwhr2_and_we_2_re = tmp; |
972 | 840 | ||
973 | /* tADL -> ADDR_2_DATA */ | 841 | /* tADL -> ADDR_2_DATA */ |
974 | 842 | ||
@@ -983,7 +851,7 @@ static int denali_setup_data_interface(struct nand_chip *chip, int chipnr, | |||
983 | tmp = ioread32(denali->reg + TCWAW_AND_ADDR_2_DATA); | 851 | tmp = ioread32(denali->reg + TCWAW_AND_ADDR_2_DATA); |
984 | tmp &= ~TCWAW_AND_ADDR_2_DATA__ADDR_2_DATA; | 852 | tmp &= ~TCWAW_AND_ADDR_2_DATA__ADDR_2_DATA; |
985 | tmp |= FIELD_PREP(TCWAW_AND_ADDR_2_DATA__ADDR_2_DATA, addr_2_data); | 853 | tmp |= FIELD_PREP(TCWAW_AND_ADDR_2_DATA__ADDR_2_DATA, addr_2_data); |
986 | iowrite32(tmp, denali->reg + TCWAW_AND_ADDR_2_DATA); | 854 | sel->tcwaw_and_addr_2_data = tmp; |
987 | 855 | ||
988 | /* tREH, tWH -> RDWR_EN_HI_CNT */ | 856 | /* tREH, tWH -> RDWR_EN_HI_CNT */ |
989 | rdwr_en_hi = DIV_ROUND_UP(max(timings->tREH_min, timings->tWH_min), | 857 | rdwr_en_hi = DIV_ROUND_UP(max(timings->tREH_min, timings->tWH_min), |
@@ -993,7 +861,7 @@ static int denali_setup_data_interface(struct nand_chip *chip, int chipnr, | |||
993 | tmp = ioread32(denali->reg + RDWR_EN_HI_CNT); | 861 | tmp = ioread32(denali->reg + RDWR_EN_HI_CNT); |
994 | tmp &= ~RDWR_EN_HI_CNT__VALUE; | 862 | tmp &= ~RDWR_EN_HI_CNT__VALUE; |
995 | tmp |= FIELD_PREP(RDWR_EN_HI_CNT__VALUE, rdwr_en_hi); | 863 | tmp |= FIELD_PREP(RDWR_EN_HI_CNT__VALUE, rdwr_en_hi); |
996 | iowrite32(tmp, denali->reg + RDWR_EN_HI_CNT); | 864 | sel->rdwr_en_hi_cnt = tmp; |
997 | 865 | ||
998 | /* tRP, tWP -> RDWR_EN_LO_CNT */ | 866 | /* tRP, tWP -> RDWR_EN_LO_CNT */ |
999 | rdwr_en_lo = DIV_ROUND_UP(max(timings->tRP_min, timings->tWP_min), t_x); | 867 | rdwr_en_lo = DIV_ROUND_UP(max(timings->tRP_min, timings->tWP_min), t_x); |
@@ -1006,7 +874,7 @@ static int denali_setup_data_interface(struct nand_chip *chip, int chipnr, | |||
1006 | tmp = ioread32(denali->reg + RDWR_EN_LO_CNT); | 874 | tmp = ioread32(denali->reg + RDWR_EN_LO_CNT); |
1007 | tmp &= ~RDWR_EN_LO_CNT__VALUE; | 875 | tmp &= ~RDWR_EN_LO_CNT__VALUE; |
1008 | tmp |= FIELD_PREP(RDWR_EN_LO_CNT__VALUE, rdwr_en_lo); | 876 | tmp |= FIELD_PREP(RDWR_EN_LO_CNT__VALUE, rdwr_en_lo); |
1009 | iowrite32(tmp, denali->reg + RDWR_EN_LO_CNT); | 877 | sel->rdwr_en_lo_cnt = tmp; |
1010 | 878 | ||
1011 | /* tCS, tCEA -> CS_SETUP_CNT */ | 879 | /* tCS, tCEA -> CS_SETUP_CNT */ |
1012 | cs_setup = max3((int)DIV_ROUND_UP(timings->tCS_min, t_x) - rdwr_en_lo, | 880 | cs_setup = max3((int)DIV_ROUND_UP(timings->tCS_min, t_x) - rdwr_en_lo, |
@@ -1017,39 +885,11 @@ static int denali_setup_data_interface(struct nand_chip *chip, int chipnr, | |||
1017 | tmp = ioread32(denali->reg + CS_SETUP_CNT); | 885 | tmp = ioread32(denali->reg + CS_SETUP_CNT); |
1018 | tmp &= ~CS_SETUP_CNT__VALUE; | 886 | tmp &= ~CS_SETUP_CNT__VALUE; |
1019 | tmp |= FIELD_PREP(CS_SETUP_CNT__VALUE, cs_setup); | 887 | tmp |= FIELD_PREP(CS_SETUP_CNT__VALUE, cs_setup); |
1020 | iowrite32(tmp, denali->reg + CS_SETUP_CNT); | 888 | sel->cs_setup_cnt = tmp; |
1021 | 889 | ||
1022 | return 0; | 890 | return 0; |
1023 | } | 891 | } |
1024 | 892 | ||
1025 | static void denali_hw_init(struct denali_nand_info *denali) | ||
1026 | { | ||
1027 | /* | ||
1028 | * The REVISION register may not be reliable. Platforms are allowed to | ||
1029 | * override it. | ||
1030 | */ | ||
1031 | if (!denali->revision) | ||
1032 | denali->revision = swab16(ioread32(denali->reg + REVISION)); | ||
1033 | |||
1034 | /* | ||
1035 | * Set how many bytes should be skipped before writing data in OOB. | ||
1036 | * If a non-zero value has already been set (by firmware or something), | ||
1037 | * just use it. Otherwise, set the driver default. | ||
1038 | */ | ||
1039 | denali->oob_skip_bytes = ioread32(denali->reg + SPARE_AREA_SKIP_BYTES); | ||
1040 | if (!denali->oob_skip_bytes) { | ||
1041 | denali->oob_skip_bytes = DENALI_DEFAULT_OOB_SKIP_BYTES; | ||
1042 | iowrite32(denali->oob_skip_bytes, | ||
1043 | denali->reg + SPARE_AREA_SKIP_BYTES); | ||
1044 | } | ||
1045 | |||
1046 | denali_detect_max_banks(denali); | ||
1047 | iowrite32(0x0F, denali->reg + RB_PIN_ENABLED); | ||
1048 | iowrite32(CHIP_EN_DONT_CARE__FLAG, denali->reg + CHIP_ENABLE_DONT_CARE); | ||
1049 | |||
1050 | iowrite32(0xffff, denali->reg + SPARE_AREA_MARKER); | ||
1051 | } | ||
1052 | |||
1053 | int denali_calc_ecc_bytes(int step_size, int strength) | 893 | int denali_calc_ecc_bytes(int step_size, int strength) |
1054 | { | 894 | { |
1055 | /* BCH code. Denali requires ecc.bytes to be multiple of 2 */ | 895 | /* BCH code. Denali requires ecc.bytes to be multiple of 2 */ |
@@ -1060,10 +900,10 @@ EXPORT_SYMBOL(denali_calc_ecc_bytes); | |||
1060 | static int denali_ooblayout_ecc(struct mtd_info *mtd, int section, | 900 | static int denali_ooblayout_ecc(struct mtd_info *mtd, int section, |
1061 | struct mtd_oob_region *oobregion) | 901 | struct mtd_oob_region *oobregion) |
1062 | { | 902 | { |
1063 | struct denali_nand_info *denali = mtd_to_denali(mtd); | ||
1064 | struct nand_chip *chip = mtd_to_nand(mtd); | 903 | struct nand_chip *chip = mtd_to_nand(mtd); |
904 | struct denali_controller *denali = to_denali_controller(chip); | ||
1065 | 905 | ||
1066 | if (section) | 906 | if (section > 0) |
1067 | return -ERANGE; | 907 | return -ERANGE; |
1068 | 908 | ||
1069 | oobregion->offset = denali->oob_skip_bytes; | 909 | oobregion->offset = denali->oob_skip_bytes; |
@@ -1075,10 +915,10 @@ static int denali_ooblayout_ecc(struct mtd_info *mtd, int section, | |||
1075 | static int denali_ooblayout_free(struct mtd_info *mtd, int section, | 915 | static int denali_ooblayout_free(struct mtd_info *mtd, int section, |
1076 | struct mtd_oob_region *oobregion) | 916 | struct mtd_oob_region *oobregion) |
1077 | { | 917 | { |
1078 | struct denali_nand_info *denali = mtd_to_denali(mtd); | ||
1079 | struct nand_chip *chip = mtd_to_nand(mtd); | 918 | struct nand_chip *chip = mtd_to_nand(mtd); |
919 | struct denali_controller *denali = to_denali_controller(chip); | ||
1080 | 920 | ||
1081 | if (section) | 921 | if (section > 0) |
1082 | return -ERANGE; | 922 | return -ERANGE; |
1083 | 923 | ||
1084 | oobregion->offset = chip->ecc.total + denali->oob_skip_bytes; | 924 | oobregion->offset = chip->ecc.total + denali->oob_skip_bytes; |
@@ -1092,10 +932,13 @@ static const struct mtd_ooblayout_ops denali_ooblayout_ops = { | |||
1092 | .free = denali_ooblayout_free, | 932 | .free = denali_ooblayout_free, |
1093 | }; | 933 | }; |
1094 | 934 | ||
1095 | static int denali_multidev_fixup(struct denali_nand_info *denali) | 935 | static int denali_multidev_fixup(struct nand_chip *chip) |
1096 | { | 936 | { |
1097 | struct nand_chip *chip = &denali->nand; | 937 | struct denali_controller *denali = to_denali_controller(chip); |
1098 | struct mtd_info *mtd = nand_to_mtd(chip); | 938 | struct mtd_info *mtd = nand_to_mtd(chip); |
939 | struct nand_memory_organization *memorg; | ||
940 | |||
941 | memorg = nanddev_get_memorg(&chip->base); | ||
1099 | 942 | ||
1100 | /* | 943 | /* |
1101 | * Support for multi device: | 944 | * Support for multi device: |
@@ -1125,11 +968,12 @@ static int denali_multidev_fixup(struct denali_nand_info *denali) | |||
1125 | } | 968 | } |
1126 | 969 | ||
1127 | /* 2 chips in parallel */ | 970 | /* 2 chips in parallel */ |
971 | memorg->pagesize <<= 1; | ||
972 | memorg->oobsize <<= 1; | ||
1128 | mtd->size <<= 1; | 973 | mtd->size <<= 1; |
1129 | mtd->erasesize <<= 1; | 974 | mtd->erasesize <<= 1; |
1130 | mtd->writesize <<= 1; | 975 | mtd->writesize <<= 1; |
1131 | mtd->oobsize <<= 1; | 976 | mtd->oobsize <<= 1; |
1132 | chip->chipsize <<= 1; | ||
1133 | chip->page_shift += 1; | 977 | chip->page_shift += 1; |
1134 | chip->phys_erase_shift += 1; | 978 | chip->phys_erase_shift += 1; |
1135 | chip->bbt_erase_shift += 1; | 979 | chip->bbt_erase_shift += 1; |
@@ -1145,38 +989,10 @@ static int denali_multidev_fixup(struct denali_nand_info *denali) | |||
1145 | 989 | ||
1146 | static int denali_attach_chip(struct nand_chip *chip) | 990 | static int denali_attach_chip(struct nand_chip *chip) |
1147 | { | 991 | { |
992 | struct denali_controller *denali = to_denali_controller(chip); | ||
1148 | struct mtd_info *mtd = nand_to_mtd(chip); | 993 | struct mtd_info *mtd = nand_to_mtd(chip); |
1149 | struct denali_nand_info *denali = mtd_to_denali(mtd); | ||
1150 | int ret; | 994 | int ret; |
1151 | 995 | ||
1152 | if (ioread32(denali->reg + FEATURES) & FEATURES__DMA) | ||
1153 | denali->dma_avail = 1; | ||
1154 | |||
1155 | if (denali->dma_avail) { | ||
1156 | int dma_bit = denali->caps & DENALI_CAP_DMA_64BIT ? 64 : 32; | ||
1157 | |||
1158 | ret = dma_set_mask(denali->dev, DMA_BIT_MASK(dma_bit)); | ||
1159 | if (ret) { | ||
1160 | dev_info(denali->dev, | ||
1161 | "Failed to set DMA mask. Disabling DMA.\n"); | ||
1162 | denali->dma_avail = 0; | ||
1163 | } | ||
1164 | } | ||
1165 | |||
1166 | if (denali->dma_avail) { | ||
1167 | chip->options |= NAND_USE_BOUNCE_BUFFER; | ||
1168 | chip->buf_align = 16; | ||
1169 | if (denali->caps & DENALI_CAP_DMA_64BIT) | ||
1170 | denali->setup_dma = denali_setup_dma64; | ||
1171 | else | ||
1172 | denali->setup_dma = denali_setup_dma32; | ||
1173 | } | ||
1174 | |||
1175 | chip->bbt_options |= NAND_BBT_USE_FLASH; | ||
1176 | chip->bbt_options |= NAND_BBT_NO_OOB; | ||
1177 | chip->ecc.mode = NAND_ECC_HW_SYNDROME; | ||
1178 | chip->options |= NAND_NO_SUBPAGE_WRITE; | ||
1179 | |||
1180 | ret = nand_ecc_choose_conf(chip, denali->ecc_caps, | 996 | ret = nand_ecc_choose_conf(chip, denali->ecc_caps, |
1181 | mtd->oobsize - denali->oob_skip_bytes); | 997 | mtd->oobsize - denali->oob_skip_bytes); |
1182 | if (ret) { | 998 | if (ret) { |
@@ -1188,123 +1004,230 @@ static int denali_attach_chip(struct nand_chip *chip) | |||
1188 | "chosen ECC settings: step=%d, strength=%d, bytes=%d\n", | 1004 | "chosen ECC settings: step=%d, strength=%d, bytes=%d\n", |
1189 | chip->ecc.size, chip->ecc.strength, chip->ecc.bytes); | 1005 | chip->ecc.size, chip->ecc.strength, chip->ecc.bytes); |
1190 | 1006 | ||
1191 | iowrite32(FIELD_PREP(ECC_CORRECTION__ERASE_THRESHOLD, 1) | | 1007 | ret = denali_multidev_fixup(chip); |
1192 | FIELD_PREP(ECC_CORRECTION__VALUE, chip->ecc.strength), | 1008 | if (ret) |
1193 | denali->reg + ECC_CORRECTION); | 1009 | return ret; |
1194 | iowrite32(mtd->erasesize / mtd->writesize, | ||
1195 | denali->reg + PAGES_PER_BLOCK); | ||
1196 | iowrite32(chip->options & NAND_BUSWIDTH_16 ? 1 : 0, | ||
1197 | denali->reg + DEVICE_WIDTH); | ||
1198 | iowrite32(chip->options & NAND_ROW_ADDR_3 ? 0 : TWO_ROW_ADDR_CYCLES__FLAG, | ||
1199 | denali->reg + TWO_ROW_ADDR_CYCLES); | ||
1200 | iowrite32(mtd->writesize, denali->reg + DEVICE_MAIN_AREA_SIZE); | ||
1201 | iowrite32(mtd->oobsize, denali->reg + DEVICE_SPARE_AREA_SIZE); | ||
1202 | 1010 | ||
1203 | iowrite32(chip->ecc.size, denali->reg + CFG_DATA_BLOCK_SIZE); | 1011 | return 0; |
1204 | iowrite32(chip->ecc.size, denali->reg + CFG_LAST_DATA_BLOCK_SIZE); | 1012 | } |
1205 | /* chip->ecc.steps is set by nand_scan_tail(); not available here */ | ||
1206 | iowrite32(mtd->writesize / chip->ecc.size, | ||
1207 | denali->reg + CFG_NUM_DATA_BLOCKS); | ||
1208 | 1013 | ||
1209 | mtd_set_ooblayout(mtd, &denali_ooblayout_ops); | 1014 | static void denali_exec_in8(struct denali_controller *denali, u32 type, |
1015 | u8 *buf, unsigned int len) | ||
1016 | { | ||
1017 | int i; | ||
1210 | 1018 | ||
1211 | if (chip->options & NAND_BUSWIDTH_16) { | 1019 | for (i = 0; i < len; i++) |
1212 | chip->legacy.read_buf = denali_read_buf16; | 1020 | buf[i] = denali->host_read(denali, type | DENALI_BANK(denali)); |
1213 | chip->legacy.write_buf = denali_write_buf16; | 1021 | } |
1214 | } else { | 1022 | |
1215 | chip->legacy.read_buf = denali_read_buf; | 1023 | static void denali_exec_in16(struct denali_controller *denali, u32 type, |
1216 | chip->legacy.write_buf = denali_write_buf; | 1024 | u8 *buf, unsigned int len) |
1025 | { | ||
1026 | u32 data; | ||
1027 | int i; | ||
1028 | |||
1029 | for (i = 0; i < len; i += 2) { | ||
1030 | data = denali->host_read(denali, type | DENALI_BANK(denali)); | ||
1031 | /* bit 31:24 and 15:8 are used for DDR */ | ||
1032 | buf[i] = data; | ||
1033 | buf[i + 1] = data >> 16; | ||
1217 | } | 1034 | } |
1218 | chip->ecc.read_page = denali_read_page; | 1035 | } |
1219 | chip->ecc.read_page_raw = denali_read_page_raw; | ||
1220 | chip->ecc.write_page = denali_write_page; | ||
1221 | chip->ecc.write_page_raw = denali_write_page_raw; | ||
1222 | chip->ecc.read_oob = denali_read_oob; | ||
1223 | chip->ecc.write_oob = denali_write_oob; | ||
1224 | 1036 | ||
1225 | ret = denali_multidev_fixup(denali); | 1037 | static void denali_exec_in(struct denali_controller *denali, u32 type, |
1226 | if (ret) | 1038 | u8 *buf, unsigned int len, bool width16) |
1227 | return ret; | 1039 | { |
1040 | if (width16) | ||
1041 | denali_exec_in16(denali, type, buf, len); | ||
1042 | else | ||
1043 | denali_exec_in8(denali, type, buf, len); | ||
1044 | } | ||
1228 | 1045 | ||
1229 | /* | 1046 | static void denali_exec_out8(struct denali_controller *denali, u32 type, |
1230 | * This buffer is DMA-mapped by denali_{read,write}_page_raw. Do not | 1047 | const u8 *buf, unsigned int len) |
1231 | * use devm_kmalloc() because the memory allocated by devm_ does not | 1048 | { |
1232 | * guarantee DMA-safe alignment. | 1049 | int i; |
1233 | */ | ||
1234 | denali->buf = kmalloc(mtd->writesize + mtd->oobsize, GFP_KERNEL); | ||
1235 | if (!denali->buf) | ||
1236 | return -ENOMEM; | ||
1237 | 1050 | ||
1238 | return 0; | 1051 | for (i = 0; i < len; i++) |
1052 | denali->host_write(denali, type | DENALI_BANK(denali), buf[i]); | ||
1239 | } | 1053 | } |
1240 | 1054 | ||
1241 | static void denali_detach_chip(struct nand_chip *chip) | 1055 | static void denali_exec_out16(struct denali_controller *denali, u32 type, |
1056 | const u8 *buf, unsigned int len) | ||
1242 | { | 1057 | { |
1243 | struct mtd_info *mtd = nand_to_mtd(chip); | 1058 | int i; |
1244 | struct denali_nand_info *denali = mtd_to_denali(mtd); | 1059 | |
1060 | for (i = 0; i < len; i += 2) | ||
1061 | denali->host_write(denali, type | DENALI_BANK(denali), | ||
1062 | buf[i + 1] << 16 | buf[i]); | ||
1063 | } | ||
1245 | 1064 | ||
1246 | kfree(denali->buf); | 1065 | static void denali_exec_out(struct denali_controller *denali, u32 type, |
1066 | const u8 *buf, unsigned int len, bool width16) | ||
1067 | { | ||
1068 | if (width16) | ||
1069 | denali_exec_out16(denali, type, buf, len); | ||
1070 | else | ||
1071 | denali_exec_out8(denali, type, buf, len); | ||
1072 | } | ||
1073 | |||
1074 | static int denali_exec_waitrdy(struct denali_controller *denali) | ||
1075 | { | ||
1076 | u32 irq_stat; | ||
1077 | |||
1078 | /* R/B# pin transitioned from low to high? */ | ||
1079 | irq_stat = denali_wait_for_irq(denali, INTR__INT_ACT); | ||
1080 | |||
1081 | /* Just in case nand_operation has multiple NAND_OP_WAITRDY_INSTR. */ | ||
1082 | denali_reset_irq(denali); | ||
1083 | |||
1084 | return irq_stat & INTR__INT_ACT ? 0 : -EIO; | ||
1085 | } | ||
1086 | |||
1087 | static int denali_exec_instr(struct nand_chip *chip, | ||
1088 | const struct nand_op_instr *instr) | ||
1089 | { | ||
1090 | struct denali_controller *denali = to_denali_controller(chip); | ||
1091 | |||
1092 | switch (instr->type) { | ||
1093 | case NAND_OP_CMD_INSTR: | ||
1094 | denali_exec_out8(denali, DENALI_MAP11_CMD, | ||
1095 | &instr->ctx.cmd.opcode, 1); | ||
1096 | return 0; | ||
1097 | case NAND_OP_ADDR_INSTR: | ||
1098 | denali_exec_out8(denali, DENALI_MAP11_ADDR, | ||
1099 | instr->ctx.addr.addrs, | ||
1100 | instr->ctx.addr.naddrs); | ||
1101 | return 0; | ||
1102 | case NAND_OP_DATA_IN_INSTR: | ||
1103 | denali_exec_in(denali, DENALI_MAP11_DATA, | ||
1104 | instr->ctx.data.buf.in, | ||
1105 | instr->ctx.data.len, | ||
1106 | !instr->ctx.data.force_8bit && | ||
1107 | chip->options & NAND_BUSWIDTH_16); | ||
1108 | return 0; | ||
1109 | case NAND_OP_DATA_OUT_INSTR: | ||
1110 | denali_exec_out(denali, DENALI_MAP11_DATA, | ||
1111 | instr->ctx.data.buf.out, | ||
1112 | instr->ctx.data.len, | ||
1113 | !instr->ctx.data.force_8bit && | ||
1114 | chip->options & NAND_BUSWIDTH_16); | ||
1115 | return 0; | ||
1116 | case NAND_OP_WAITRDY_INSTR: | ||
1117 | return denali_exec_waitrdy(denali); | ||
1118 | default: | ||
1119 | WARN_ONCE(1, "unsupported NAND instruction type: %d\n", | ||
1120 | instr->type); | ||
1121 | |||
1122 | return -EINVAL; | ||
1123 | } | ||
1124 | } | ||
1125 | |||
1126 | static int denali_exec_op(struct nand_chip *chip, | ||
1127 | const struct nand_operation *op, bool check_only) | ||
1128 | { | ||
1129 | int i, ret; | ||
1130 | |||
1131 | if (check_only) | ||
1132 | return 0; | ||
1133 | |||
1134 | denali_select_target(chip, op->cs); | ||
1135 | |||
1136 | /* | ||
1137 | * Some commands contain NAND_OP_WAITRDY_INSTR. | ||
1138 | * irq must be cleared here to catch the R/B# interrupt there. | ||
1139 | */ | ||
1140 | denali_reset_irq(to_denali_controller(chip)); | ||
1141 | |||
1142 | for (i = 0; i < op->ninstrs; i++) { | ||
1143 | ret = denali_exec_instr(chip, &op->instrs[i]); | ||
1144 | if (ret) | ||
1145 | return ret; | ||
1146 | } | ||
1147 | |||
1148 | return 0; | ||
1247 | } | 1149 | } |
1248 | 1150 | ||
1249 | static const struct nand_controller_ops denali_controller_ops = { | 1151 | static const struct nand_controller_ops denali_controller_ops = { |
1250 | .attach_chip = denali_attach_chip, | 1152 | .attach_chip = denali_attach_chip, |
1251 | .detach_chip = denali_detach_chip, | 1153 | .exec_op = denali_exec_op, |
1252 | .setup_data_interface = denali_setup_data_interface, | 1154 | .setup_data_interface = denali_setup_data_interface, |
1253 | }; | 1155 | }; |
1254 | 1156 | ||
1255 | int denali_init(struct denali_nand_info *denali) | 1157 | int denali_chip_init(struct denali_controller *denali, |
1158 | struct denali_chip *dchip) | ||
1256 | { | 1159 | { |
1257 | struct nand_chip *chip = &denali->nand; | 1160 | struct nand_chip *chip = &dchip->chip; |
1258 | struct mtd_info *mtd = nand_to_mtd(chip); | 1161 | struct mtd_info *mtd = nand_to_mtd(chip); |
1259 | u32 features = ioread32(denali->reg + FEATURES); | 1162 | struct denali_chip *dchip2; |
1260 | int ret; | 1163 | int i, j, ret; |
1261 | 1164 | ||
1262 | mtd->dev.parent = denali->dev; | 1165 | chip->controller = &denali->controller; |
1263 | denali_hw_init(denali); | ||
1264 | 1166 | ||
1265 | init_completion(&denali->complete); | 1167 | /* sanity checks for bank numbers */ |
1266 | spin_lock_init(&denali->irq_lock); | 1168 | for (i = 0; i < dchip->nsels; i++) { |
1169 | unsigned int bank = dchip->sels[i].bank; | ||
1267 | 1170 | ||
1268 | denali_clear_irq_all(denali); | 1171 | if (bank >= denali->nbanks) { |
1172 | dev_err(denali->dev, "unsupported bank %d\n", bank); | ||
1173 | return -EINVAL; | ||
1174 | } | ||
1269 | 1175 | ||
1270 | ret = devm_request_irq(denali->dev, denali->irq, denali_isr, | 1176 | for (j = 0; j < i; j++) { |
1271 | IRQF_SHARED, DENALI_NAND_NAME, denali); | 1177 | if (bank == dchip->sels[j].bank) { |
1272 | if (ret) { | 1178 | dev_err(denali->dev, |
1273 | dev_err(denali->dev, "Unable to request IRQ\n"); | 1179 | "bank %d is assigned twice in the same chip\n", |
1274 | return ret; | 1180 | bank); |
1275 | } | 1181 | return -EINVAL; |
1182 | } | ||
1183 | } | ||
1276 | 1184 | ||
1277 | denali_enable_irq(denali); | 1185 | list_for_each_entry(dchip2, &denali->chips, node) { |
1186 | for (j = 0; j < dchip2->nsels; j++) { | ||
1187 | if (bank == dchip2->sels[j].bank) { | ||
1188 | dev_err(denali->dev, | ||
1189 | "bank %d is already used\n", | ||
1190 | bank); | ||
1191 | return -EINVAL; | ||
1192 | } | ||
1193 | } | ||
1194 | } | ||
1195 | } | ||
1278 | 1196 | ||
1279 | denali->active_bank = DENALI_INVALID_BANK; | 1197 | mtd->dev.parent = denali->dev; |
1280 | 1198 | ||
1281 | nand_set_flash_node(chip, denali->dev->of_node); | 1199 | /* |
1282 | /* Fallback to the default name if DT did not give "label" property */ | 1200 | * Fallback to the default name if DT did not give "label" property. |
1283 | if (!mtd->name) | 1201 | * Use "label" property if multiple chips are connected. |
1202 | */ | ||
1203 | if (!mtd->name && list_empty(&denali->chips)) | ||
1284 | mtd->name = "denali-nand"; | 1204 | mtd->name = "denali-nand"; |
1285 | 1205 | ||
1286 | chip->legacy.select_chip = denali_select_chip; | 1206 | if (denali->dma_avail) { |
1287 | chip->legacy.read_byte = denali_read_byte; | 1207 | chip->options |= NAND_USE_BOUNCE_BUFFER; |
1288 | chip->legacy.write_byte = denali_write_byte; | 1208 | chip->buf_align = 16; |
1289 | chip->legacy.cmd_ctrl = denali_cmd_ctrl; | ||
1290 | chip->legacy.waitfunc = denali_waitfunc; | ||
1291 | |||
1292 | if (features & FEATURES__INDEX_ADDR) { | ||
1293 | denali->host_read = denali_indexed_read; | ||
1294 | denali->host_write = denali_indexed_write; | ||
1295 | } else { | ||
1296 | denali->host_read = denali_direct_read; | ||
1297 | denali->host_write = denali_direct_write; | ||
1298 | } | 1209 | } |
1299 | 1210 | ||
1300 | /* clk rate info is needed for setup_data_interface */ | 1211 | /* clk rate info is needed for setup_data_interface */ |
1301 | if (!denali->clk_rate || !denali->clk_x_rate) | 1212 | if (!denali->clk_rate || !denali->clk_x_rate) |
1302 | chip->options |= NAND_KEEP_TIMINGS; | 1213 | chip->options |= NAND_KEEP_TIMINGS; |
1303 | 1214 | ||
1304 | chip->legacy.dummy_controller.ops = &denali_controller_ops; | 1215 | chip->bbt_options |= NAND_BBT_USE_FLASH; |
1305 | ret = nand_scan(chip, denali->max_banks); | 1216 | chip->bbt_options |= NAND_BBT_NO_OOB; |
1217 | chip->options |= NAND_NO_SUBPAGE_WRITE; | ||
1218 | chip->ecc.mode = NAND_ECC_HW_SYNDROME; | ||
1219 | chip->ecc.read_page = denali_read_page; | ||
1220 | chip->ecc.write_page = denali_write_page; | ||
1221 | chip->ecc.read_page_raw = denali_read_page_raw; | ||
1222 | chip->ecc.write_page_raw = denali_write_page_raw; | ||
1223 | chip->ecc.read_oob = denali_read_oob; | ||
1224 | chip->ecc.write_oob = denali_write_oob; | ||
1225 | |||
1226 | mtd_set_ooblayout(mtd, &denali_ooblayout_ops); | ||
1227 | |||
1228 | ret = nand_scan(chip, dchip->nsels); | ||
1306 | if (ret) | 1229 | if (ret) |
1307 | goto disable_irq; | 1230 | return ret; |
1308 | 1231 | ||
1309 | ret = mtd_device_register(mtd, NULL, 0); | 1232 | ret = mtd_device_register(mtd, NULL, 0); |
1310 | if (ret) { | 1233 | if (ret) { |
@@ -1312,20 +1235,111 @@ int denali_init(struct denali_nand_info *denali) | |||
1312 | goto cleanup_nand; | 1235 | goto cleanup_nand; |
1313 | } | 1236 | } |
1314 | 1237 | ||
1238 | list_add_tail(&dchip->node, &denali->chips); | ||
1239 | |||
1315 | return 0; | 1240 | return 0; |
1316 | 1241 | ||
1317 | cleanup_nand: | 1242 | cleanup_nand: |
1318 | nand_cleanup(chip); | 1243 | nand_cleanup(chip); |
1319 | disable_irq: | ||
1320 | denali_disable_irq(denali); | ||
1321 | 1244 | ||
1322 | return ret; | 1245 | return ret; |
1323 | } | 1246 | } |
1247 | EXPORT_SYMBOL_GPL(denali_chip_init); | ||
1248 | |||
1249 | int denali_init(struct denali_controller *denali) | ||
1250 | { | ||
1251 | u32 features = ioread32(denali->reg + FEATURES); | ||
1252 | int ret; | ||
1253 | |||
1254 | nand_controller_init(&denali->controller); | ||
1255 | denali->controller.ops = &denali_controller_ops; | ||
1256 | init_completion(&denali->complete); | ||
1257 | spin_lock_init(&denali->irq_lock); | ||
1258 | INIT_LIST_HEAD(&denali->chips); | ||
1259 | denali->active_bank = DENALI_INVALID_BANK; | ||
1260 | |||
1261 | /* | ||
1262 | * The REVISION register may not be reliable. Platforms are allowed to | ||
1263 | * override it. | ||
1264 | */ | ||
1265 | if (!denali->revision) | ||
1266 | denali->revision = swab16(ioread32(denali->reg + REVISION)); | ||
1267 | |||
1268 | denali->nbanks = 1 << FIELD_GET(FEATURES__N_BANKS, features); | ||
1269 | |||
1270 | /* the encoding changed from rev 5.0 to 5.1 */ | ||
1271 | if (denali->revision < 0x0501) | ||
1272 | denali->nbanks <<= 1; | ||
1273 | |||
1274 | if (features & FEATURES__DMA) | ||
1275 | denali->dma_avail = true; | ||
1276 | |||
1277 | if (denali->dma_avail) { | ||
1278 | int dma_bit = denali->caps & DENALI_CAP_DMA_64BIT ? 64 : 32; | ||
1279 | |||
1280 | ret = dma_set_mask(denali->dev, DMA_BIT_MASK(dma_bit)); | ||
1281 | if (ret) { | ||
1282 | dev_info(denali->dev, | ||
1283 | "Failed to set DMA mask. Disabling DMA.\n"); | ||
1284 | denali->dma_avail = false; | ||
1285 | } | ||
1286 | } | ||
1287 | |||
1288 | if (denali->dma_avail) { | ||
1289 | if (denali->caps & DENALI_CAP_DMA_64BIT) | ||
1290 | denali->setup_dma = denali_setup_dma64; | ||
1291 | else | ||
1292 | denali->setup_dma = denali_setup_dma32; | ||
1293 | } | ||
1294 | |||
1295 | if (features & FEATURES__INDEX_ADDR) { | ||
1296 | denali->host_read = denali_indexed_read; | ||
1297 | denali->host_write = denali_indexed_write; | ||
1298 | } else { | ||
1299 | denali->host_read = denali_direct_read; | ||
1300 | denali->host_write = denali_direct_write; | ||
1301 | } | ||
1302 | |||
1303 | /* | ||
1304 | * Set how many bytes should be skipped before writing data in OOB. | ||
1305 | * If a non-zero value has already been set (by firmware or something), | ||
1306 | * just use it. Otherwise, set the driver's default. | ||
1307 | */ | ||
1308 | denali->oob_skip_bytes = ioread32(denali->reg + SPARE_AREA_SKIP_BYTES); | ||
1309 | if (!denali->oob_skip_bytes) { | ||
1310 | denali->oob_skip_bytes = DENALI_DEFAULT_OOB_SKIP_BYTES; | ||
1311 | iowrite32(denali->oob_skip_bytes, | ||
1312 | denali->reg + SPARE_AREA_SKIP_BYTES); | ||
1313 | } | ||
1314 | |||
1315 | iowrite32(0, denali->reg + TRANSFER_SPARE_REG); | ||
1316 | iowrite32(GENMASK(denali->nbanks - 1, 0), denali->reg + RB_PIN_ENABLED); | ||
1317 | iowrite32(CHIP_EN_DONT_CARE__FLAG, denali->reg + CHIP_ENABLE_DONT_CARE); | ||
1318 | iowrite32(ECC_ENABLE__FLAG, denali->reg + ECC_ENABLE); | ||
1319 | iowrite32(0xffff, denali->reg + SPARE_AREA_MARKER); | ||
1320 | |||
1321 | denali_clear_irq_all(denali); | ||
1322 | |||
1323 | ret = devm_request_irq(denali->dev, denali->irq, denali_isr, | ||
1324 | IRQF_SHARED, DENALI_NAND_NAME, denali); | ||
1325 | if (ret) { | ||
1326 | dev_err(denali->dev, "Unable to request IRQ\n"); | ||
1327 | return ret; | ||
1328 | } | ||
1329 | |||
1330 | denali_enable_irq(denali); | ||
1331 | |||
1332 | return 0; | ||
1333 | } | ||
1324 | EXPORT_SYMBOL(denali_init); | 1334 | EXPORT_SYMBOL(denali_init); |
1325 | 1335 | ||
1326 | void denali_remove(struct denali_nand_info *denali) | 1336 | void denali_remove(struct denali_controller *denali) |
1327 | { | 1337 | { |
1328 | nand_release(&denali->nand); | 1338 | struct denali_chip *dchip; |
1339 | |||
1340 | list_for_each_entry(dchip, &denali->chips, node) | ||
1341 | nand_release(&dchip->chip); | ||
1342 | |||
1329 | denali_disable_irq(denali); | 1343 | denali_disable_irq(denali); |
1330 | } | 1344 | } |
1331 | EXPORT_SYMBOL(denali_remove); | 1345 | EXPORT_SYMBOL(denali_remove); |
diff --git a/drivers/mtd/nand/raw/denali.h b/drivers/mtd/nand/raw/denali.h index c8c2620fc736..e5cdcda56d14 100644 --- a/drivers/mtd/nand/raw/denali.h +++ b/drivers/mtd/nand/raw/denali.h | |||
@@ -9,6 +9,7 @@ | |||
9 | 9 | ||
10 | #include <linux/bits.h> | 10 | #include <linux/bits.h> |
11 | #include <linux/completion.h> | 11 | #include <linux/completion.h> |
12 | #include <linux/list.h> | ||
12 | #include <linux/mtd/rawnand.h> | 13 | #include <linux/mtd/rawnand.h> |
13 | #include <linux/spinlock_types.h> | 14 | #include <linux/spinlock_types.h> |
14 | #include <linux/types.h> | 15 | #include <linux/types.h> |
@@ -290,38 +291,108 @@ | |||
290 | #define CHNL_ACTIVE__CHANNEL2 BIT(2) | 291 | #define CHNL_ACTIVE__CHANNEL2 BIT(2) |
291 | #define CHNL_ACTIVE__CHANNEL3 BIT(3) | 292 | #define CHNL_ACTIVE__CHANNEL3 BIT(3) |
292 | 293 | ||
293 | struct denali_nand_info { | 294 | /** |
294 | struct nand_chip nand; | 295 | * struct denali_chip_sel - per-CS data of Denali NAND |
295 | unsigned long clk_rate; /* core clock rate */ | 296 | * |
296 | unsigned long clk_x_rate; /* bus interface clock rate */ | 297 | * @bank: bank id of the controller this CS is connected to |
297 | int active_bank; /* currently selected bank */ | 298 | * @hwhr2_and_we_2_re: value of timing register HWHR2_AND_WE_2_RE |
299 | * @tcwaw_and_addr_2_data: value of timing register TCWAW_AND_ADDR_2_DATA | ||
300 | * @re_2_we: value of timing register RE_2_WE | ||
301 | * @acc_clks: value of timing register ACC_CLKS | ||
302 | * @rdwr_en_lo_cnt: value of timing register RDWR_EN_LO_CNT | ||
303 | * @rdwr_en_hi_cnt: value of timing register RDWR_EN_HI_CNT | ||
304 | * @cs_setup_cnt: value of timing register CS_SETUP_CNT | ||
305 | * @re_2_re: value of timing register RE_2_RE | ||
306 | */ | ||
307 | struct denali_chip_sel { | ||
308 | int bank; | ||
309 | u32 hwhr2_and_we_2_re; | ||
310 | u32 tcwaw_and_addr_2_data; | ||
311 | u32 re_2_we; | ||
312 | u32 acc_clks; | ||
313 | u32 rdwr_en_lo_cnt; | ||
314 | u32 rdwr_en_hi_cnt; | ||
315 | u32 cs_setup_cnt; | ||
316 | u32 re_2_re; | ||
317 | }; | ||
318 | |||
319 | /** | ||
320 | * struct denali_chip - per-chip data of Denali NAND | ||
321 | * | ||
322 | * @chip: base NAND chip structure | ||
323 | * @node: node to be used to associate this chip with the controller | ||
324 | * @nsels: the number of CS lines of this chip | ||
325 | * @sels: the array of per-cs data | ||
326 | */ | ||
327 | struct denali_chip { | ||
328 | struct nand_chip chip; | ||
329 | struct list_head node; | ||
330 | unsigned int nsels; | ||
331 | struct denali_chip_sel sels[0]; | ||
332 | }; | ||
333 | |||
334 | /** | ||
335 | * struct denali_controller - Denali NAND controller data | ||
336 | * | ||
337 | * @controller: base NAND controller structure | ||
338 | * @dev: device | ||
339 | * @chips: the list of chips attached to this controller | ||
340 | * @clk_rate: frequency of core clock | ||
341 | * @clk_x_rate: frequency of bus interface clock | ||
342 | * @reg: base of Register Interface | ||
343 | * @host: base of Host Data/Command interface | ||
344 | * @complete: completion used to wait for interrupts | ||
345 | * @irq: interrupt number | ||
346 | * @irq_mask: interrupt bits the controller is waiting for | ||
347 | * @irq_status: interrupt bits of events that have happened | ||
348 | * @irq_lock: lock to protect @irq_mask and @irq_status | ||
349 | * @dma_avail: set if DMA engine is available | ||
350 | * @devs_per_cs: number of devices connected in parallel | ||
351 | * @oob_skip_bytes: number of bytes in OOB skipped by the ECC engine | ||
352 | * @active_bank: active bank id | ||
353 | * @nbanks: the number of banks supported by this controller | ||
354 | * @revision: IP revision | ||
355 | * @caps: controller capabilities that cannot be detected run-time | ||
356 | * @ecc_caps: ECC engine capabilities | ||
357 | * @host_read: callback for read access of Host Data/Command Interface | ||
358 | * @host_write: callback for write access of Host Data/Command Interface | ||
359 | * @setup_dma: callback for setup of the Data DMA | ||
360 | */ | ||
361 | struct denali_controller { | ||
362 | struct nand_controller controller; | ||
298 | struct device *dev; | 363 | struct device *dev; |
299 | void __iomem *reg; /* Register Interface */ | 364 | struct list_head chips; |
300 | void __iomem *host; /* Host Data/Command Interface */ | 365 | unsigned long clk_rate; |
366 | unsigned long clk_x_rate; | ||
367 | void __iomem *reg; | ||
368 | void __iomem *host; | ||
301 | struct completion complete; | 369 | struct completion complete; |
302 | spinlock_t irq_lock; /* protect irq_mask and irq_status */ | ||
303 | u32 irq_mask; /* interrupts we are waiting for */ | ||
304 | u32 irq_status; /* interrupts that have happened */ | ||
305 | int irq; | 370 | int irq; |
306 | void *buf; /* for syndrome layout conversion */ | 371 | u32 irq_mask; |
307 | int dma_avail; /* can support DMA? */ | 372 | u32 irq_status; |
308 | int devs_per_cs; /* devices connected in parallel */ | 373 | spinlock_t irq_lock; |
309 | int oob_skip_bytes; /* number of bytes reserved for BBM */ | 374 | bool dma_avail; |
310 | int max_banks; | 375 | int devs_per_cs; |
311 | unsigned int revision; /* IP revision */ | 376 | int oob_skip_bytes; |
312 | unsigned int caps; /* IP capability (or quirk) */ | 377 | int active_bank; |
378 | int nbanks; | ||
379 | unsigned int revision; | ||
380 | unsigned int caps; | ||
313 | const struct nand_ecc_caps *ecc_caps; | 381 | const struct nand_ecc_caps *ecc_caps; |
314 | u32 (*host_read)(struct denali_nand_info *denali, u32 addr); | 382 | u32 (*host_read)(struct denali_controller *denali, u32 addr); |
315 | void (*host_write)(struct denali_nand_info *denali, u32 addr, u32 data); | 383 | void (*host_write)(struct denali_controller *denali, u32 addr, |
316 | void (*setup_dma)(struct denali_nand_info *denali, dma_addr_t dma_addr, | 384 | u32 data); |
317 | int page, int write); | 385 | void (*setup_dma)(struct denali_controller *denali, dma_addr_t dma_addr, |
386 | int page, bool write); | ||
318 | }; | 387 | }; |
319 | 388 | ||
320 | #define DENALI_CAP_HW_ECC_FIXUP BIT(0) | 389 | #define DENALI_CAP_HW_ECC_FIXUP BIT(0) |
321 | #define DENALI_CAP_DMA_64BIT BIT(1) | 390 | #define DENALI_CAP_DMA_64BIT BIT(1) |
322 | 391 | ||
323 | int denali_calc_ecc_bytes(int step_size, int strength); | 392 | int denali_calc_ecc_bytes(int step_size, int strength); |
324 | int denali_init(struct denali_nand_info *denali); | 393 | int denali_chip_init(struct denali_controller *denali, |
325 | void denali_remove(struct denali_nand_info *denali); | 394 | struct denali_chip *dchip); |
395 | int denali_init(struct denali_controller *denali); | ||
396 | void denali_remove(struct denali_controller *denali); | ||
326 | 397 | ||
327 | #endif /* __DENALI_H__ */ | 398 | #endif /* __DENALI_H__ */ |
diff --git a/drivers/mtd/nand/raw/denali_dt.c b/drivers/mtd/nand/raw/denali_dt.c index 0b5ae2418815..5e14836f6bd5 100644 --- a/drivers/mtd/nand/raw/denali_dt.c +++ b/drivers/mtd/nand/raw/denali_dt.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include "denali.h" | 18 | #include "denali.h" |
19 | 19 | ||
20 | struct denali_dt { | 20 | struct denali_dt { |
21 | struct denali_nand_info denali; | 21 | struct denali_controller controller; |
22 | struct clk *clk; /* core clock */ | 22 | struct clk *clk; /* core clock */ |
23 | struct clk *clk_x; /* bus interface clock */ | 23 | struct clk *clk_x; /* bus interface clock */ |
24 | struct clk *clk_ecc; /* ECC circuit clock */ | 24 | struct clk *clk_ecc; /* ECC circuit clock */ |
@@ -71,19 +71,92 @@ static const struct of_device_id denali_nand_dt_ids[] = { | |||
71 | }; | 71 | }; |
72 | MODULE_DEVICE_TABLE(of, denali_nand_dt_ids); | 72 | MODULE_DEVICE_TABLE(of, denali_nand_dt_ids); |
73 | 73 | ||
74 | static int denali_dt_chip_init(struct denali_controller *denali, | ||
75 | struct device_node *chip_np) | ||
76 | { | ||
77 | struct denali_chip *dchip; | ||
78 | u32 bank; | ||
79 | int nsels, i, ret; | ||
80 | |||
81 | nsels = of_property_count_u32_elems(chip_np, "reg"); | ||
82 | if (nsels < 0) | ||
83 | return nsels; | ||
84 | |||
85 | dchip = devm_kzalloc(denali->dev, struct_size(dchip, sels, nsels), | ||
86 | GFP_KERNEL); | ||
87 | if (!dchip) | ||
88 | return -ENOMEM; | ||
89 | |||
90 | dchip->nsels = nsels; | ||
91 | |||
92 | for (i = 0; i < nsels; i++) { | ||
93 | ret = of_property_read_u32_index(chip_np, "reg", i, &bank); | ||
94 | if (ret) | ||
95 | return ret; | ||
96 | |||
97 | dchip->sels[i].bank = bank; | ||
98 | |||
99 | nand_set_flash_node(&dchip->chip, chip_np); | ||
100 | } | ||
101 | |||
102 | return denali_chip_init(denali, dchip); | ||
103 | } | ||
104 | |||
105 | /* Backward compatibility for old platforms */ | ||
106 | static int denali_dt_legacy_chip_init(struct denali_controller *denali) | ||
107 | { | ||
108 | struct denali_chip *dchip; | ||
109 | int nsels, i; | ||
110 | |||
111 | nsels = denali->nbanks; | ||
112 | |||
113 | dchip = devm_kzalloc(denali->dev, struct_size(dchip, sels, nsels), | ||
114 | GFP_KERNEL); | ||
115 | if (!dchip) | ||
116 | return -ENOMEM; | ||
117 | |||
118 | dchip->nsels = nsels; | ||
119 | |||
120 | for (i = 0; i < nsels; i++) | ||
121 | dchip->sels[i].bank = i; | ||
122 | |||
123 | nand_set_flash_node(&dchip->chip, denali->dev->of_node); | ||
124 | |||
125 | return denali_chip_init(denali, dchip); | ||
126 | } | ||
127 | |||
128 | /* | ||
129 | * Check the DT binding. | ||
130 | * The new binding expects chip subnodes in the controller node. | ||
131 | * So, #address-cells = <1>; #size-cells = <0>; are required. | ||
132 | * Check the #size-cells to distinguish the binding. | ||
133 | */ | ||
134 | static bool denali_dt_is_legacy_binding(struct device_node *np) | ||
135 | { | ||
136 | u32 cells; | ||
137 | int ret; | ||
138 | |||
139 | ret = of_property_read_u32(np, "#size-cells", &cells); | ||
140 | if (ret) | ||
141 | return true; | ||
142 | |||
143 | return cells != 0; | ||
144 | } | ||
145 | |||
74 | static int denali_dt_probe(struct platform_device *pdev) | 146 | static int denali_dt_probe(struct platform_device *pdev) |
75 | { | 147 | { |
76 | struct device *dev = &pdev->dev; | 148 | struct device *dev = &pdev->dev; |
77 | struct resource *res; | 149 | struct resource *res; |
78 | struct denali_dt *dt; | 150 | struct denali_dt *dt; |
79 | const struct denali_dt_data *data; | 151 | const struct denali_dt_data *data; |
80 | struct denali_nand_info *denali; | 152 | struct denali_controller *denali; |
153 | struct device_node *np; | ||
81 | int ret; | 154 | int ret; |
82 | 155 | ||
83 | dt = devm_kzalloc(dev, sizeof(*dt), GFP_KERNEL); | 156 | dt = devm_kzalloc(dev, sizeof(*dt), GFP_KERNEL); |
84 | if (!dt) | 157 | if (!dt) |
85 | return -ENOMEM; | 158 | return -ENOMEM; |
86 | denali = &dt->denali; | 159 | denali = &dt->controller; |
87 | 160 | ||
88 | data = of_device_get_match_data(dev); | 161 | data = of_device_get_match_data(dev); |
89 | if (data) { | 162 | if (data) { |
@@ -140,9 +213,26 @@ static int denali_dt_probe(struct platform_device *pdev) | |||
140 | if (ret) | 213 | if (ret) |
141 | goto out_disable_clk_ecc; | 214 | goto out_disable_clk_ecc; |
142 | 215 | ||
216 | if (denali_dt_is_legacy_binding(dev->of_node)) { | ||
217 | ret = denali_dt_legacy_chip_init(denali); | ||
218 | if (ret) | ||
219 | goto out_remove_denali; | ||
220 | } else { | ||
221 | for_each_child_of_node(dev->of_node, np) { | ||
222 | ret = denali_dt_chip_init(denali, np); | ||
223 | if (ret) { | ||
224 | of_node_put(np); | ||
225 | goto out_remove_denali; | ||
226 | } | ||
227 | } | ||
228 | } | ||
229 | |||
143 | platform_set_drvdata(pdev, dt); | 230 | platform_set_drvdata(pdev, dt); |
231 | |||
144 | return 0; | 232 | return 0; |
145 | 233 | ||
234 | out_remove_denali: | ||
235 | denali_remove(denali); | ||
146 | out_disable_clk_ecc: | 236 | out_disable_clk_ecc: |
147 | clk_disable_unprepare(dt->clk_ecc); | 237 | clk_disable_unprepare(dt->clk_ecc); |
148 | out_disable_clk_x: | 238 | out_disable_clk_x: |
@@ -157,7 +247,7 @@ static int denali_dt_remove(struct platform_device *pdev) | |||
157 | { | 247 | { |
158 | struct denali_dt *dt = platform_get_drvdata(pdev); | 248 | struct denali_dt *dt = platform_get_drvdata(pdev); |
159 | 249 | ||
160 | denali_remove(&dt->denali); | 250 | denali_remove(&dt->controller); |
161 | clk_disable_unprepare(dt->clk_ecc); | 251 | clk_disable_unprepare(dt->clk_ecc); |
162 | clk_disable_unprepare(dt->clk_x); | 252 | clk_disable_unprepare(dt->clk_x); |
163 | clk_disable_unprepare(dt->clk); | 253 | clk_disable_unprepare(dt->clk); |
diff --git a/drivers/mtd/nand/raw/denali_pci.c b/drivers/mtd/nand/raw/denali_pci.c index 48e9ac54ad53..d62aa5271753 100644 --- a/drivers/mtd/nand/raw/denali_pci.c +++ b/drivers/mtd/nand/raw/denali_pci.c | |||
@@ -29,10 +29,11 @@ NAND_ECC_CAPS_SINGLE(denali_pci_ecc_caps, denali_calc_ecc_bytes, 512, 8, 15); | |||
29 | 29 | ||
30 | static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | 30 | static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) |
31 | { | 31 | { |
32 | int ret; | ||
33 | resource_size_t csr_base, mem_base; | 32 | resource_size_t csr_base, mem_base; |
34 | unsigned long csr_len, mem_len; | 33 | unsigned long csr_len, mem_len; |
35 | struct denali_nand_info *denali; | 34 | struct denali_controller *denali; |
35 | struct denali_chip *dchip; | ||
36 | int nsels, ret, i; | ||
36 | 37 | ||
37 | denali = devm_kzalloc(&dev->dev, sizeof(*denali), GFP_KERNEL); | 38 | denali = devm_kzalloc(&dev->dev, sizeof(*denali), GFP_KERNEL); |
38 | if (!denali) | 39 | if (!denali) |
@@ -64,7 +65,6 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
64 | denali->dev = &dev->dev; | 65 | denali->dev = &dev->dev; |
65 | denali->irq = dev->irq; | 66 | denali->irq = dev->irq; |
66 | denali->ecc_caps = &denali_pci_ecc_caps; | 67 | denali->ecc_caps = &denali_pci_ecc_caps; |
67 | denali->nand.ecc.options |= NAND_ECC_MAXIMIZE; | ||
68 | denali->clk_rate = 50000000; /* 50 MHz */ | 68 | denali->clk_rate = 50000000; /* 50 MHz */ |
69 | denali->clk_x_rate = 200000000; /* 200 MHz */ | 69 | denali->clk_x_rate = 200000000; /* 200 MHz */ |
70 | 70 | ||
@@ -84,27 +84,49 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
84 | if (!denali->host) { | 84 | if (!denali->host) { |
85 | dev_err(&dev->dev, "Spectra: ioremap_nocache failed!"); | 85 | dev_err(&dev->dev, "Spectra: ioremap_nocache failed!"); |
86 | ret = -ENOMEM; | 86 | ret = -ENOMEM; |
87 | goto failed_remap_reg; | 87 | goto out_unmap_reg; |
88 | } | 88 | } |
89 | 89 | ||
90 | ret = denali_init(denali); | 90 | ret = denali_init(denali); |
91 | if (ret) | 91 | if (ret) |
92 | goto failed_remap_mem; | 92 | goto out_unmap_host; |
93 | |||
94 | nsels = denali->nbanks; | ||
95 | |||
96 | dchip = devm_kzalloc(denali->dev, struct_size(dchip, sels, nsels), | ||
97 | GFP_KERNEL); | ||
98 | if (!dchip) { | ||
99 | ret = -ENOMEM; | ||
100 | goto out_remove_denali; | ||
101 | } | ||
102 | |||
103 | dchip->chip.ecc.options |= NAND_ECC_MAXIMIZE; | ||
104 | |||
105 | dchip->nsels = nsels; | ||
106 | |||
107 | for (i = 0; i < nsels; i++) | ||
108 | dchip->sels[i].bank = i; | ||
109 | |||
110 | ret = denali_chip_init(denali, dchip); | ||
111 | if (ret) | ||
112 | goto out_remove_denali; | ||
93 | 113 | ||
94 | pci_set_drvdata(dev, denali); | 114 | pci_set_drvdata(dev, denali); |
95 | 115 | ||
96 | return 0; | 116 | return 0; |
97 | 117 | ||
98 | failed_remap_mem: | 118 | out_remove_denali: |
119 | denali_remove(denali); | ||
120 | out_unmap_host: | ||
99 | iounmap(denali->host); | 121 | iounmap(denali->host); |
100 | failed_remap_reg: | 122 | out_unmap_reg: |
101 | iounmap(denali->reg); | 123 | iounmap(denali->reg); |
102 | return ret; | 124 | return ret; |
103 | } | 125 | } |
104 | 126 | ||
105 | static void denali_pci_remove(struct pci_dev *dev) | 127 | static void denali_pci_remove(struct pci_dev *dev) |
106 | { | 128 | { |
107 | struct denali_nand_info *denali = pci_get_drvdata(dev); | 129 | struct denali_controller *denali = pci_get_drvdata(dev); |
108 | 130 | ||
109 | denali_remove(denali); | 131 | denali_remove(denali); |
110 | iounmap(denali->reg); | 132 | iounmap(denali->reg); |
diff --git a/drivers/mtd/nand/raw/diskonchip.c b/drivers/mtd/nand/raw/diskonchip.c index 53f57e0f007e..f430c4bf0323 100644 --- a/drivers/mtd/nand/raw/diskonchip.c +++ b/drivers/mtd/nand/raw/diskonchip.c | |||
@@ -1028,6 +1028,7 @@ static inline int __init nftl_partscan(struct mtd_info *mtd, struct mtd_partitio | |||
1028 | { | 1028 | { |
1029 | struct nand_chip *this = mtd_to_nand(mtd); | 1029 | struct nand_chip *this = mtd_to_nand(mtd); |
1030 | struct doc_priv *doc = nand_get_controller_data(this); | 1030 | struct doc_priv *doc = nand_get_controller_data(this); |
1031 | struct nand_memory_organization *memorg; | ||
1031 | int ret = 0; | 1032 | int ret = 0; |
1032 | u_char *buf; | 1033 | u_char *buf; |
1033 | struct NFTLMediaHeader *mh; | 1034 | struct NFTLMediaHeader *mh; |
@@ -1036,6 +1037,8 @@ static inline int __init nftl_partscan(struct mtd_info *mtd, struct mtd_partitio | |||
1036 | unsigned blocks, maxblocks; | 1037 | unsigned blocks, maxblocks; |
1037 | int offs, numheaders; | 1038 | int offs, numheaders; |
1038 | 1039 | ||
1040 | memorg = nanddev_get_memorg(&this->base); | ||
1041 | |||
1039 | buf = kmalloc(mtd->writesize, GFP_KERNEL); | 1042 | buf = kmalloc(mtd->writesize, GFP_KERNEL); |
1040 | if (!buf) { | 1043 | if (!buf) { |
1041 | return 0; | 1044 | return 0; |
@@ -1082,6 +1085,7 @@ static inline int __init nftl_partscan(struct mtd_info *mtd, struct mtd_partitio | |||
1082 | implementation of the NAND layer. */ | 1085 | implementation of the NAND layer. */ |
1083 | if (mh->UnitSizeFactor != 0xff) { | 1086 | if (mh->UnitSizeFactor != 0xff) { |
1084 | this->bbt_erase_shift += (0xff - mh->UnitSizeFactor); | 1087 | this->bbt_erase_shift += (0xff - mh->UnitSizeFactor); |
1088 | memorg->pages_per_eraseblock <<= (0xff - mh->UnitSizeFactor); | ||
1085 | mtd->erasesize <<= (0xff - mh->UnitSizeFactor); | 1089 | mtd->erasesize <<= (0xff - mh->UnitSizeFactor); |
1086 | pr_info("Setting virtual erase size to %d\n", mtd->erasesize); | 1090 | pr_info("Setting virtual erase size to %d\n", mtd->erasesize); |
1087 | blocks = mtd->size >> this->bbt_erase_shift; | 1091 | blocks = mtd->size >> this->bbt_erase_shift; |
@@ -1287,7 +1291,7 @@ static int __init inftl_scan_bbt(struct mtd_info *mtd) | |||
1287 | struct doc_priv *doc = nand_get_controller_data(this); | 1291 | struct doc_priv *doc = nand_get_controller_data(this); |
1288 | struct mtd_partition parts[5]; | 1292 | struct mtd_partition parts[5]; |
1289 | 1293 | ||
1290 | if (this->numchips > doc->chips_per_floor) { | 1294 | if (nanddev_ntargets(&this->base) > doc->chips_per_floor) { |
1291 | pr_err("Multi-floor INFTL devices not yet supported.\n"); | 1295 | pr_err("Multi-floor INFTL devices not yet supported.\n"); |
1292 | return -EIO; | 1296 | return -EIO; |
1293 | } | 1297 | } |
@@ -1477,6 +1481,7 @@ static int __init doc_probe(unsigned long physadr) | |||
1477 | break; | 1481 | break; |
1478 | case DOC_ChipID_DocMilPlus32: | 1482 | case DOC_ChipID_DocMilPlus32: |
1479 | pr_err("DiskOnChip Millennium Plus 32MB is not supported, ignoring.\n"); | 1483 | pr_err("DiskOnChip Millennium Plus 32MB is not supported, ignoring.\n"); |
1484 | /* fall through */ | ||
1480 | default: | 1485 | default: |
1481 | ret = -ENODEV; | 1486 | ret = -ENODEV; |
1482 | goto notfound; | 1487 | goto notfound; |
diff --git a/drivers/mtd/nand/raw/fsl_elbc_nand.c b/drivers/mtd/nand/raw/fsl_elbc_nand.c index 70f0d2b450ea..423828ff68e6 100644 --- a/drivers/mtd/nand/raw/fsl_elbc_nand.c +++ b/drivers/mtd/nand/raw/fsl_elbc_nand.c | |||
@@ -355,6 +355,15 @@ static void fsl_elbc_cmdfunc(struct nand_chip *chip, unsigned int command, | |||
355 | fsl_elbc_run_command(mtd); | 355 | fsl_elbc_run_command(mtd); |
356 | return; | 356 | return; |
357 | 357 | ||
358 | /* RNDOUT moves the pointer inside the page */ | ||
359 | case NAND_CMD_RNDOUT: | ||
360 | dev_dbg(priv->dev, | ||
361 | "fsl_elbc_cmdfunc: NAND_CMD_RNDOUT, column: 0x%x.\n", | ||
362 | column); | ||
363 | |||
364 | elbc_fcm_ctrl->index = column; | ||
365 | return; | ||
366 | |||
358 | /* READOOB reads only the OOB because no ECC is performed. */ | 367 | /* READOOB reads only the OOB because no ECC is performed. */ |
359 | case NAND_CMD_READOOB: | 368 | case NAND_CMD_READOOB: |
360 | dev_vdbg(priv->dev, | 369 | dev_vdbg(priv->dev, |
@@ -635,79 +644,6 @@ static int fsl_elbc_wait(struct nand_chip *chip) | |||
635 | return (elbc_fcm_ctrl->mdr & 0xff) | NAND_STATUS_WP; | 644 | return (elbc_fcm_ctrl->mdr & 0xff) | NAND_STATUS_WP; |
636 | } | 645 | } |
637 | 646 | ||
638 | static int fsl_elbc_attach_chip(struct nand_chip *chip) | ||
639 | { | ||
640 | struct mtd_info *mtd = nand_to_mtd(chip); | ||
641 | struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); | ||
642 | struct fsl_lbc_ctrl *ctrl = priv->ctrl; | ||
643 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; | ||
644 | unsigned int al; | ||
645 | |||
646 | /* calculate FMR Address Length field */ | ||
647 | al = 0; | ||
648 | if (chip->pagemask & 0xffff0000) | ||
649 | al++; | ||
650 | if (chip->pagemask & 0xff000000) | ||
651 | al++; | ||
652 | |||
653 | priv->fmr |= al << FMR_AL_SHIFT; | ||
654 | |||
655 | dev_dbg(priv->dev, "fsl_elbc_init: nand->numchips = %d\n", | ||
656 | chip->numchips); | ||
657 | dev_dbg(priv->dev, "fsl_elbc_init: nand->chipsize = %lld\n", | ||
658 | chip->chipsize); | ||
659 | dev_dbg(priv->dev, "fsl_elbc_init: nand->pagemask = %8x\n", | ||
660 | chip->pagemask); | ||
661 | dev_dbg(priv->dev, "fsl_elbc_init: nand->legacy.chip_delay = %d\n", | ||
662 | chip->legacy.chip_delay); | ||
663 | dev_dbg(priv->dev, "fsl_elbc_init: nand->badblockpos = %d\n", | ||
664 | chip->badblockpos); | ||
665 | dev_dbg(priv->dev, "fsl_elbc_init: nand->chip_shift = %d\n", | ||
666 | chip->chip_shift); | ||
667 | dev_dbg(priv->dev, "fsl_elbc_init: nand->page_shift = %d\n", | ||
668 | chip->page_shift); | ||
669 | dev_dbg(priv->dev, "fsl_elbc_init: nand->phys_erase_shift = %d\n", | ||
670 | chip->phys_erase_shift); | ||
671 | dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.mode = %d\n", | ||
672 | chip->ecc.mode); | ||
673 | dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.steps = %d\n", | ||
674 | chip->ecc.steps); | ||
675 | dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.bytes = %d\n", | ||
676 | chip->ecc.bytes); | ||
677 | dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.total = %d\n", | ||
678 | chip->ecc.total); | ||
679 | dev_dbg(priv->dev, "fsl_elbc_init: mtd->ooblayout = %p\n", | ||
680 | mtd->ooblayout); | ||
681 | dev_dbg(priv->dev, "fsl_elbc_init: mtd->flags = %08x\n", mtd->flags); | ||
682 | dev_dbg(priv->dev, "fsl_elbc_init: mtd->size = %lld\n", mtd->size); | ||
683 | dev_dbg(priv->dev, "fsl_elbc_init: mtd->erasesize = %d\n", | ||
684 | mtd->erasesize); | ||
685 | dev_dbg(priv->dev, "fsl_elbc_init: mtd->writesize = %d\n", | ||
686 | mtd->writesize); | ||
687 | dev_dbg(priv->dev, "fsl_elbc_init: mtd->oobsize = %d\n", | ||
688 | mtd->oobsize); | ||
689 | |||
690 | /* adjust Option Register and ECC to match Flash page size */ | ||
691 | if (mtd->writesize == 512) { | ||
692 | priv->page_size = 0; | ||
693 | clrbits32(&lbc->bank[priv->bank].or, OR_FCM_PGS); | ||
694 | } else if (mtd->writesize == 2048) { | ||
695 | priv->page_size = 1; | ||
696 | setbits32(&lbc->bank[priv->bank].or, OR_FCM_PGS); | ||
697 | } else { | ||
698 | dev_err(priv->dev, | ||
699 | "fsl_elbc_init: page size %d is not supported\n", | ||
700 | mtd->writesize); | ||
701 | return -ENOTSUPP; | ||
702 | } | ||
703 | |||
704 | return 0; | ||
705 | } | ||
706 | |||
707 | static const struct nand_controller_ops fsl_elbc_controller_ops = { | ||
708 | .attach_chip = fsl_elbc_attach_chip, | ||
709 | }; | ||
710 | |||
711 | static int fsl_elbc_read_page(struct nand_chip *chip, uint8_t *buf, | 647 | static int fsl_elbc_read_page(struct nand_chip *chip, uint8_t *buf, |
712 | int oob_required, int page) | 648 | int oob_required, int page) |
713 | { | 649 | { |
@@ -794,27 +730,116 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv) | |||
794 | chip->controller = &elbc_fcm_ctrl->controller; | 730 | chip->controller = &elbc_fcm_ctrl->controller; |
795 | nand_set_controller_data(chip, priv); | 731 | nand_set_controller_data(chip, priv); |
796 | 732 | ||
797 | chip->ecc.read_page = fsl_elbc_read_page; | 733 | return 0; |
798 | chip->ecc.write_page = fsl_elbc_write_page; | 734 | } |
799 | chip->ecc.write_subpage = fsl_elbc_write_subpage; | 735 | |
800 | 736 | static int fsl_elbc_attach_chip(struct nand_chip *chip) | |
801 | /* If CS Base Register selects full hardware ECC then use it */ | 737 | { |
802 | if ((in_be32(&lbc->bank[priv->bank].br) & BR_DECC) == | 738 | struct mtd_info *mtd = nand_to_mtd(chip); |
803 | BR_DECC_CHK_GEN) { | 739 | struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); |
804 | chip->ecc.mode = NAND_ECC_HW; | 740 | struct fsl_lbc_ctrl *ctrl = priv->ctrl; |
805 | mtd_set_ooblayout(mtd, &fsl_elbc_ooblayout_ops); | 741 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; |
806 | chip->ecc.size = 512; | 742 | unsigned int al; |
807 | chip->ecc.bytes = 3; | 743 | |
808 | chip->ecc.strength = 1; | 744 | switch (chip->ecc.mode) { |
745 | /* | ||
746 | * if ECC was not chosen in DT, decide whether to use HW or SW ECC from | ||
747 | * CS Base Register | ||
748 | */ | ||
749 | case NAND_ECC_NONE: | ||
750 | /* If CS Base Register selects full hardware ECC then use it */ | ||
751 | if ((in_be32(&lbc->bank[priv->bank].br) & BR_DECC) == | ||
752 | BR_DECC_CHK_GEN) { | ||
753 | chip->ecc.read_page = fsl_elbc_read_page; | ||
754 | chip->ecc.write_page = fsl_elbc_write_page; | ||
755 | chip->ecc.write_subpage = fsl_elbc_write_subpage; | ||
756 | |||
757 | chip->ecc.mode = NAND_ECC_HW; | ||
758 | mtd_set_ooblayout(mtd, &fsl_elbc_ooblayout_ops); | ||
759 | chip->ecc.size = 512; | ||
760 | chip->ecc.bytes = 3; | ||
761 | chip->ecc.strength = 1; | ||
762 | } else { | ||
763 | /* otherwise fall back to default software ECC */ | ||
764 | chip->ecc.mode = NAND_ECC_SOFT; | ||
765 | chip->ecc.algo = NAND_ECC_HAMMING; | ||
766 | } | ||
767 | break; | ||
768 | |||
769 | /* if SW ECC was chosen in DT, we do not need to set anything here */ | ||
770 | case NAND_ECC_SOFT: | ||
771 | break; | ||
772 | |||
773 | /* should we also implement NAND_ECC_HW to do as the code above? */ | ||
774 | default: | ||
775 | return -EINVAL; | ||
776 | } | ||
777 | |||
778 | /* calculate FMR Address Length field */ | ||
779 | al = 0; | ||
780 | if (chip->pagemask & 0xffff0000) | ||
781 | al++; | ||
782 | if (chip->pagemask & 0xff000000) | ||
783 | al++; | ||
784 | |||
785 | priv->fmr |= al << FMR_AL_SHIFT; | ||
786 | |||
787 | dev_dbg(priv->dev, "fsl_elbc_init: nand->numchips = %d\n", | ||
788 | nanddev_ntargets(&chip->base)); | ||
789 | dev_dbg(priv->dev, "fsl_elbc_init: nand->chipsize = %lld\n", | ||
790 | nanddev_target_size(&chip->base)); | ||
791 | dev_dbg(priv->dev, "fsl_elbc_init: nand->pagemask = %8x\n", | ||
792 | chip->pagemask); | ||
793 | dev_dbg(priv->dev, "fsl_elbc_init: nand->legacy.chip_delay = %d\n", | ||
794 | chip->legacy.chip_delay); | ||
795 | dev_dbg(priv->dev, "fsl_elbc_init: nand->badblockpos = %d\n", | ||
796 | chip->badblockpos); | ||
797 | dev_dbg(priv->dev, "fsl_elbc_init: nand->chip_shift = %d\n", | ||
798 | chip->chip_shift); | ||
799 | dev_dbg(priv->dev, "fsl_elbc_init: nand->page_shift = %d\n", | ||
800 | chip->page_shift); | ||
801 | dev_dbg(priv->dev, "fsl_elbc_init: nand->phys_erase_shift = %d\n", | ||
802 | chip->phys_erase_shift); | ||
803 | dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.mode = %d\n", | ||
804 | chip->ecc.mode); | ||
805 | dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.steps = %d\n", | ||
806 | chip->ecc.steps); | ||
807 | dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.bytes = %d\n", | ||
808 | chip->ecc.bytes); | ||
809 | dev_dbg(priv->dev, "fsl_elbc_init: nand->ecc.total = %d\n", | ||
810 | chip->ecc.total); | ||
811 | dev_dbg(priv->dev, "fsl_elbc_init: mtd->ooblayout = %p\n", | ||
812 | mtd->ooblayout); | ||
813 | dev_dbg(priv->dev, "fsl_elbc_init: mtd->flags = %08x\n", mtd->flags); | ||
814 | dev_dbg(priv->dev, "fsl_elbc_init: mtd->size = %lld\n", mtd->size); | ||
815 | dev_dbg(priv->dev, "fsl_elbc_init: mtd->erasesize = %d\n", | ||
816 | mtd->erasesize); | ||
817 | dev_dbg(priv->dev, "fsl_elbc_init: mtd->writesize = %d\n", | ||
818 | mtd->writesize); | ||
819 | dev_dbg(priv->dev, "fsl_elbc_init: mtd->oobsize = %d\n", | ||
820 | mtd->oobsize); | ||
821 | |||
822 | /* adjust Option Register and ECC to match Flash page size */ | ||
823 | if (mtd->writesize == 512) { | ||
824 | priv->page_size = 0; | ||
825 | clrbits32(&lbc->bank[priv->bank].or, OR_FCM_PGS); | ||
826 | } else if (mtd->writesize == 2048) { | ||
827 | priv->page_size = 1; | ||
828 | setbits32(&lbc->bank[priv->bank].or, OR_FCM_PGS); | ||
809 | } else { | 829 | } else { |
810 | /* otherwise fall back to default software ECC */ | 830 | dev_err(priv->dev, |
811 | chip->ecc.mode = NAND_ECC_SOFT; | 831 | "fsl_elbc_init: page size %d is not supported\n", |
812 | chip->ecc.algo = NAND_ECC_HAMMING; | 832 | mtd->writesize); |
833 | return -ENOTSUPP; | ||
813 | } | 834 | } |
814 | 835 | ||
815 | return 0; | 836 | return 0; |
816 | } | 837 | } |
817 | 838 | ||
839 | static const struct nand_controller_ops fsl_elbc_controller_ops = { | ||
840 | .attach_chip = fsl_elbc_attach_chip, | ||
841 | }; | ||
842 | |||
818 | static int fsl_elbc_chip_remove(struct fsl_elbc_mtd *priv) | 843 | static int fsl_elbc_chip_remove(struct fsl_elbc_mtd *priv) |
819 | { | 844 | { |
820 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; | 845 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; |
diff --git a/drivers/mtd/nand/raw/fsl_ifc_nand.c b/drivers/mtd/nand/raw/fsl_ifc_nand.c index e65d274399f9..04a3dcd675bf 100644 --- a/drivers/mtd/nand/raw/fsl_ifc_nand.c +++ b/drivers/mtd/nand/raw/fsl_ifc_nand.c | |||
@@ -722,9 +722,9 @@ static int fsl_ifc_attach_chip(struct nand_chip *chip) | |||
722 | struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); | 722 | struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); |
723 | 723 | ||
724 | dev_dbg(priv->dev, "%s: nand->numchips = %d\n", __func__, | 724 | dev_dbg(priv->dev, "%s: nand->numchips = %d\n", __func__, |
725 | chip->numchips); | 725 | nanddev_ntargets(&chip->base)); |
726 | dev_dbg(priv->dev, "%s: nand->chipsize = %lld\n", __func__, | 726 | dev_dbg(priv->dev, "%s: nand->chipsize = %lld\n", __func__, |
727 | chip->chipsize); | 727 | nanddev_target_size(&chip->base)); |
728 | dev_dbg(priv->dev, "%s: nand->pagemask = %8x\n", __func__, | 728 | dev_dbg(priv->dev, "%s: nand->pagemask = %8x\n", __func__, |
729 | chip->pagemask); | 729 | chip->pagemask); |
730 | dev_dbg(priv->dev, "%s: nand->legacy.chip_delay = %d\n", __func__, | 730 | dev_dbg(priv->dev, "%s: nand->legacy.chip_delay = %d\n", __func__, |
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c index a4768df5083f..a8b26d2e793c 100644 --- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c | |||
@@ -157,8 +157,7 @@ int gpmi_init(struct gpmi_nand_data *this) | |||
157 | * Reset BCH here, too. We got failures otherwise :( | 157 | * Reset BCH here, too. We got failures otherwise :( |
158 | * See later BCH reset for explanation of MX23 and MX28 handling | 158 | * See later BCH reset for explanation of MX23 and MX28 handling |
159 | */ | 159 | */ |
160 | ret = gpmi_reset_block(r->bch_regs, | 160 | ret = gpmi_reset_block(r->bch_regs, GPMI_IS_MXS(this)); |
161 | GPMI_IS_MX23(this) || GPMI_IS_MX28(this)); | ||
162 | if (ret) | 161 | if (ret) |
163 | goto err_out; | 162 | goto err_out; |
164 | 163 | ||
@@ -266,8 +265,7 @@ int bch_set_geometry(struct gpmi_nand_data *this) | |||
266 | * chip, otherwise it will lock up. So we skip resetting BCH on the MX23. | 265 | * chip, otherwise it will lock up. So we skip resetting BCH on the MX23. |
267 | * and MX28. | 266 | * and MX28. |
268 | */ | 267 | */ |
269 | ret = gpmi_reset_block(r->bch_regs, | 268 | ret = gpmi_reset_block(r->bch_regs, GPMI_IS_MXS(this)); |
270 | GPMI_IS_MX23(this) || GPMI_IS_MX28(this)); | ||
271 | if (ret) | 269 | if (ret) |
272 | goto err_out; | 270 | goto err_out; |
273 | 271 | ||
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c index ed405c9434fe..40df20d1adf5 100644 --- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | |||
@@ -171,7 +171,7 @@ static inline bool gpmi_check_ecc(struct gpmi_nand_data *this) | |||
171 | struct bch_geometry *geo = &this->bch_geometry; | 171 | struct bch_geometry *geo = &this->bch_geometry; |
172 | 172 | ||
173 | /* Do the sanity check. */ | 173 | /* Do the sanity check. */ |
174 | if (GPMI_IS_MX23(this) || GPMI_IS_MX28(this)) { | 174 | if (GPMI_IS_MXS(this)) { |
175 | /* The mx23/mx28 only support the GF13. */ | 175 | /* The mx23/mx28 only support the GF13. */ |
176 | if (geo->gf_len == 14) | 176 | if (geo->gf_len == 14) |
177 | return false; | 177 | return false; |
@@ -204,7 +204,8 @@ static int set_geometry_by_ecc_info(struct gpmi_nand_data *this, | |||
204 | default: | 204 | default: |
205 | dev_err(this->dev, | 205 | dev_err(this->dev, |
206 | "unsupported nand chip. ecc bits : %d, ecc size : %d\n", | 206 | "unsupported nand chip. ecc bits : %d, ecc size : %d\n", |
207 | chip->ecc_strength_ds, chip->ecc_step_ds); | 207 | chip->base.eccreq.strength, |
208 | chip->base.eccreq.step_size); | ||
208 | return -EINVAL; | 209 | return -EINVAL; |
209 | } | 210 | } |
210 | geo->ecc_chunk_size = ecc_step; | 211 | geo->ecc_chunk_size = ecc_step; |
@@ -417,11 +418,13 @@ int common_nfc_set_geometry(struct gpmi_nand_data *this) | |||
417 | 418 | ||
418 | if ((of_property_read_bool(this->dev->of_node, "fsl,use-minimum-ecc")) | 419 | if ((of_property_read_bool(this->dev->of_node, "fsl,use-minimum-ecc")) |
419 | || legacy_set_geometry(this)) { | 420 | || legacy_set_geometry(this)) { |
420 | if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0)) | 421 | if (!(chip->base.eccreq.strength > 0 && |
422 | chip->base.eccreq.step_size > 0)) | ||
421 | return -EINVAL; | 423 | return -EINVAL; |
422 | 424 | ||
423 | return set_geometry_by_ecc_info(this, chip->ecc_strength_ds, | 425 | return set_geometry_by_ecc_info(this, |
424 | chip->ecc_step_ds); | 426 | chip->base.eccreq.strength, |
427 | chip->base.eccreq.step_size); | ||
425 | } | 428 | } |
426 | 429 | ||
427 | return 0; | 430 | return 0; |
@@ -1602,7 +1605,7 @@ static int mx23_check_transcription_stamp(struct gpmi_nand_data *this) | |||
1602 | unsigned int search_area_size_in_strides; | 1605 | unsigned int search_area_size_in_strides; |
1603 | unsigned int stride; | 1606 | unsigned int stride; |
1604 | unsigned int page; | 1607 | unsigned int page; |
1605 | uint8_t *buffer = chip->data_buf; | 1608 | u8 *buffer = nand_get_data_buf(chip); |
1606 | int saved_chip_number; | 1609 | int saved_chip_number; |
1607 | int found_an_ncb_fingerprint = false; | 1610 | int found_an_ncb_fingerprint = false; |
1608 | 1611 | ||
@@ -1664,7 +1667,7 @@ static int mx23_write_transcription_stamp(struct gpmi_nand_data *this) | |||
1664 | unsigned int block; | 1667 | unsigned int block; |
1665 | unsigned int stride; | 1668 | unsigned int stride; |
1666 | unsigned int page; | 1669 | unsigned int page; |
1667 | uint8_t *buffer = chip->data_buf; | 1670 | u8 *buffer = nand_get_data_buf(chip); |
1668 | int saved_chip_number; | 1671 | int saved_chip_number; |
1669 | int status; | 1672 | int status; |
1670 | 1673 | ||
@@ -1753,7 +1756,7 @@ static int mx23_boot_init(struct gpmi_nand_data *this) | |||
1753 | dev_dbg(dev, "Transcribing bad block marks...\n"); | 1756 | dev_dbg(dev, "Transcribing bad block marks...\n"); |
1754 | 1757 | ||
1755 | /* Compute the number of blocks in the entire medium. */ | 1758 | /* Compute the number of blocks in the entire medium. */ |
1756 | block_count = chip->chipsize >> chip->phys_erase_shift; | 1759 | block_count = nanddev_eraseblocks_per_target(&chip->base); |
1757 | 1760 | ||
1758 | /* | 1761 | /* |
1759 | * Loop over all the blocks in the medium, transcribing block marks as | 1762 | * Loop over all the blocks in the medium, transcribing block marks as |
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h index d0b79bac2728..a804a4a5bd46 100644 --- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h | |||
@@ -207,4 +207,5 @@ void gpmi_copy_bits(u8 *dst, size_t dst_bit_off, | |||
207 | 207 | ||
208 | #define GPMI_IS_MX6(x) (GPMI_IS_MX6Q(x) || GPMI_IS_MX6SX(x) || \ | 208 | #define GPMI_IS_MX6(x) (GPMI_IS_MX6Q(x) || GPMI_IS_MX6SX(x) || \ |
209 | GPMI_IS_MX7D(x)) | 209 | GPMI_IS_MX7D(x)) |
210 | #define GPMI_IS_MXS(x) (GPMI_IS_MX23(x) || GPMI_IS_MX28(x)) | ||
210 | #endif | 211 | #endif |
diff --git a/drivers/mtd/nand/raw/hisi504_nand.c b/drivers/mtd/nand/raw/hisi504_nand.c index f3f9aa160cff..e4526fff9da4 100644 --- a/drivers/mtd/nand/raw/hisi504_nand.c +++ b/drivers/mtd/nand/raw/hisi504_nand.c | |||
@@ -849,7 +849,7 @@ static int hisi_nfc_resume(struct device *dev) | |||
849 | struct hinfc_host *host = dev_get_drvdata(dev); | 849 | struct hinfc_host *host = dev_get_drvdata(dev); |
850 | struct nand_chip *chip = &host->chip; | 850 | struct nand_chip *chip = &host->chip; |
851 | 851 | ||
852 | for (cs = 0; cs < chip->numchips; cs++) | 852 | for (cs = 0; cs < nanddev_ntargets(&chip->base); cs++) |
853 | hisi_nfc_send_cmd_reset(host, cs); | 853 | hisi_nfc_send_cmd_reset(host, cs); |
854 | hinfc_write(host, SET_HINFC504_PWIDTH(HINFC504_W_LATCH, | 854 | hinfc_write(host, SET_HINFC504_PWIDTH(HINFC504_W_LATCH, |
855 | HINFC504_R_LATCH, HINFC504_RW_LATCH), HINFC504_PWIDTH); | 855 | HINFC504_R_LATCH, HINFC504_RW_LATCH), HINFC504_PWIDTH); |
diff --git a/drivers/mtd/nand/raw/ingenic/Kconfig b/drivers/mtd/nand/raw/ingenic/Kconfig new file mode 100644 index 000000000000..7cfc77021154 --- /dev/null +++ b/drivers/mtd/nand/raw/ingenic/Kconfig | |||
@@ -0,0 +1,50 @@ | |||
1 | config MTD_NAND_JZ4740 | ||
2 | tristate "JZ4740 NAND controller" | ||
3 | depends on MACH_JZ4740 || COMPILE_TEST | ||
4 | depends on HAS_IOMEM | ||
5 | help | ||
6 | Enables support for NAND Flash on JZ4740 SoC based boards. | ||
7 | |||
8 | config MTD_NAND_JZ4780 | ||
9 | tristate "JZ4780 NAND controller" | ||
10 | depends on JZ4780_NEMC | ||
11 | help | ||
12 | Enables support for NAND Flash connected to the NEMC on JZ4780 SoC | ||
13 | based boards, using the BCH controller for hardware error correction. | ||
14 | |||
15 | if MTD_NAND_JZ4780 | ||
16 | |||
17 | config MTD_NAND_INGENIC_ECC | ||
18 | tristate | ||
19 | |||
20 | config MTD_NAND_JZ4740_ECC | ||
21 | tristate "Hardware BCH support for JZ4740 SoC" | ||
22 | select MTD_NAND_INGENIC_ECC | ||
23 | help | ||
24 | Enable this driver to support the Reed-Solomon error-correction | ||
25 | hardware present on the JZ4740 SoC from Ingenic. | ||
26 | |||
27 | This driver can also be built as a module. If so, the module | ||
28 | will be called jz4740-ecc. | ||
29 | |||
30 | config MTD_NAND_JZ4725B_BCH | ||
31 | tristate "Hardware BCH support for JZ4725B SoC" | ||
32 | select MTD_NAND_INGENIC_ECC | ||
33 | help | ||
34 | Enable this driver to support the BCH error-correction hardware | ||
35 | present on the JZ4725B SoC from Ingenic. | ||
36 | |||
37 | This driver can also be built as a module. If so, the module | ||
38 | will be called jz4725b-bch. | ||
39 | |||
40 | config MTD_NAND_JZ4780_BCH | ||
41 | tristate "Hardware BCH support for JZ4780 SoC" | ||
42 | select MTD_NAND_INGENIC_ECC | ||
43 | help | ||
44 | Enable this driver to support the BCH error-correction hardware | ||
45 | present on the JZ4780 SoC from Ingenic. | ||
46 | |||
47 | This driver can also be built as a module. If so, the module | ||
48 | will be called jz4780-bch. | ||
49 | |||
50 | endif # MTD_NAND_JZ4780 | ||
diff --git a/drivers/mtd/nand/raw/ingenic/Makefile b/drivers/mtd/nand/raw/ingenic/Makefile new file mode 100644 index 000000000000..ab2c5f47e5b7 --- /dev/null +++ b/drivers/mtd/nand/raw/ingenic/Makefile | |||
@@ -0,0 +1,7 @@ | |||
1 | obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o | ||
2 | obj-$(CONFIG_MTD_NAND_JZ4780) += ingenic_nand.o | ||
3 | |||
4 | obj-$(CONFIG_MTD_NAND_INGENIC_ECC) += ingenic_ecc.o | ||
5 | obj-$(CONFIG_MTD_NAND_JZ4740_ECC) += jz4740_ecc.o | ||
6 | obj-$(CONFIG_MTD_NAND_JZ4725B_BCH) += jz4725b_bch.o | ||
7 | obj-$(CONFIG_MTD_NAND_JZ4780_BCH) += jz4780_bch.o | ||
diff --git a/drivers/mtd/nand/raw/ingenic/ingenic_ecc.c b/drivers/mtd/nand/raw/ingenic/ingenic_ecc.c new file mode 100644 index 000000000000..d3e085c5685a --- /dev/null +++ b/drivers/mtd/nand/raw/ingenic/ingenic_ecc.c | |||
@@ -0,0 +1,166 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * JZ47xx ECC common code | ||
4 | * | ||
5 | * Copyright (c) 2015 Imagination Technologies | ||
6 | * Author: Alex Smith <alex.smith@imgtec.com> | ||
7 | */ | ||
8 | |||
9 | #include <linux/clk.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/of_platform.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | |||
15 | #include "ingenic_ecc.h" | ||
16 | |||
17 | /** | ||
18 | * ingenic_ecc_calculate() - calculate ECC for a data buffer | ||
19 | * @ecc: ECC device. | ||
20 | * @params: ECC parameters. | ||
21 | * @buf: input buffer with raw data. | ||
22 | * @ecc_code: output buffer with ECC. | ||
23 | * | ||
24 | * Return: 0 on success, -ETIMEDOUT if timed out while waiting for ECC | ||
25 | * controller. | ||
26 | */ | ||
27 | int ingenic_ecc_calculate(struct ingenic_ecc *ecc, | ||
28 | struct ingenic_ecc_params *params, | ||
29 | const u8 *buf, u8 *ecc_code) | ||
30 | { | ||
31 | return ecc->ops->calculate(ecc, params, buf, ecc_code); | ||
32 | } | ||
33 | EXPORT_SYMBOL(ingenic_ecc_calculate); | ||
34 | |||
35 | /** | ||
36 | * ingenic_ecc_correct() - detect and correct bit errors | ||
37 | * @ecc: ECC device. | ||
38 | * @params: ECC parameters. | ||
39 | * @buf: raw data read from the chip. | ||
40 | * @ecc_code: ECC read from the chip. | ||
41 | * | ||
42 | * Given the raw data and the ECC read from the NAND device, detects and | ||
43 | * corrects errors in the data. | ||
44 | * | ||
45 | * Return: the number of bit errors corrected, -EBADMSG if there are too many | ||
46 | * errors to correct or -ETIMEDOUT if we timed out waiting for the controller. | ||
47 | */ | ||
48 | int ingenic_ecc_correct(struct ingenic_ecc *ecc, | ||
49 | struct ingenic_ecc_params *params, | ||
50 | u8 *buf, u8 *ecc_code) | ||
51 | { | ||
52 | return ecc->ops->correct(ecc, params, buf, ecc_code); | ||
53 | } | ||
54 | EXPORT_SYMBOL(ingenic_ecc_correct); | ||
55 | |||
56 | /** | ||
57 | * ingenic_ecc_get() - get the ECC controller device | ||
58 | * @np: ECC device tree node. | ||
59 | * | ||
60 | * Gets the ECC controller device from the specified device tree node. The | ||
61 | * device must be released with ingenic_ecc_release() when it is no longer being | ||
62 | * used. | ||
63 | * | ||
64 | * Return: a pointer to ingenic_ecc, errors are encoded into the pointer. | ||
65 | * PTR_ERR(-EPROBE_DEFER) if the device hasn't been initialised yet. | ||
66 | */ | ||
67 | static struct ingenic_ecc *ingenic_ecc_get(struct device_node *np) | ||
68 | { | ||
69 | struct platform_device *pdev; | ||
70 | struct ingenic_ecc *ecc; | ||
71 | |||
72 | pdev = of_find_device_by_node(np); | ||
73 | if (!pdev || !platform_get_drvdata(pdev)) | ||
74 | return ERR_PTR(-EPROBE_DEFER); | ||
75 | |||
76 | get_device(&pdev->dev); | ||
77 | |||
78 | ecc = platform_get_drvdata(pdev); | ||
79 | clk_prepare_enable(ecc->clk); | ||
80 | |||
81 | return ecc; | ||
82 | } | ||
83 | |||
84 | /** | ||
85 | * of_ingenic_ecc_get() - get the ECC controller from a DT node | ||
86 | * @of_node: the node that contains an ecc-engine property. | ||
87 | * | ||
88 | * Get the ecc-engine property from the given device tree | ||
89 | * node and pass it to ingenic_ecc_get to do the work. | ||
90 | * | ||
91 | * Return: a pointer to ingenic_ecc, errors are encoded into the pointer. | ||
92 | * PTR_ERR(-EPROBE_DEFER) if the device hasn't been initialised yet. | ||
93 | */ | ||
94 | struct ingenic_ecc *of_ingenic_ecc_get(struct device_node *of_node) | ||
95 | { | ||
96 | struct ingenic_ecc *ecc = NULL; | ||
97 | struct device_node *np; | ||
98 | |||
99 | np = of_parse_phandle(of_node, "ecc-engine", 0); | ||
100 | |||
101 | /* | ||
102 | * If the ecc-engine property is not found, check for the deprecated | ||
103 | * ingenic,bch-controller property | ||
104 | */ | ||
105 | if (!np) | ||
106 | np = of_parse_phandle(of_node, "ingenic,bch-controller", 0); | ||
107 | |||
108 | if (np) { | ||
109 | ecc = ingenic_ecc_get(np); | ||
110 | of_node_put(np); | ||
111 | } | ||
112 | return ecc; | ||
113 | } | ||
114 | EXPORT_SYMBOL(of_ingenic_ecc_get); | ||
115 | |||
116 | /** | ||
117 | * ingenic_ecc_release() - release the ECC controller device | ||
118 | * @ecc: ECC device. | ||
119 | */ | ||
120 | void ingenic_ecc_release(struct ingenic_ecc *ecc) | ||
121 | { | ||
122 | clk_disable_unprepare(ecc->clk); | ||
123 | put_device(ecc->dev); | ||
124 | } | ||
125 | EXPORT_SYMBOL(ingenic_ecc_release); | ||
126 | |||
127 | int ingenic_ecc_probe(struct platform_device *pdev) | ||
128 | { | ||
129 | struct device *dev = &pdev->dev; | ||
130 | struct ingenic_ecc *ecc; | ||
131 | struct resource *res; | ||
132 | |||
133 | ecc = devm_kzalloc(dev, sizeof(*ecc), GFP_KERNEL); | ||
134 | if (!ecc) | ||
135 | return -ENOMEM; | ||
136 | |||
137 | ecc->ops = device_get_match_data(dev); | ||
138 | if (!ecc->ops) | ||
139 | return -EINVAL; | ||
140 | |||
141 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
142 | ecc->base = devm_ioremap_resource(dev, res); | ||
143 | if (IS_ERR(ecc->base)) | ||
144 | return PTR_ERR(ecc->base); | ||
145 | |||
146 | ecc->ops->disable(ecc); | ||
147 | |||
148 | ecc->clk = devm_clk_get(dev, NULL); | ||
149 | if (IS_ERR(ecc->clk)) { | ||
150 | dev_err(dev, "failed to get clock: %ld\n", PTR_ERR(ecc->clk)); | ||
151 | return PTR_ERR(ecc->clk); | ||
152 | } | ||
153 | |||
154 | mutex_init(&ecc->lock); | ||
155 | |||
156 | ecc->dev = dev; | ||
157 | platform_set_drvdata(pdev, ecc); | ||
158 | |||
159 | return 0; | ||
160 | } | ||
161 | EXPORT_SYMBOL(ingenic_ecc_probe); | ||
162 | |||
163 | MODULE_AUTHOR("Alex Smith <alex@alex-smith.me.uk>"); | ||
164 | MODULE_AUTHOR("Harvey Hunt <harveyhuntnexus@gmail.com>"); | ||
165 | MODULE_DESCRIPTION("Ingenic ECC common driver"); | ||
166 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mtd/nand/raw/ingenic/ingenic_ecc.h b/drivers/mtd/nand/raw/ingenic/ingenic_ecc.h new file mode 100644 index 000000000000..2cda439b5e11 --- /dev/null +++ b/drivers/mtd/nand/raw/ingenic/ingenic_ecc.h | |||
@@ -0,0 +1,83 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | #ifndef __DRIVERS_MTD_NAND_INGENIC_ECC_INTERNAL_H__ | ||
3 | #define __DRIVERS_MTD_NAND_INGENIC_ECC_INTERNAL_H__ | ||
4 | |||
5 | #include <linux/compiler_types.h> | ||
6 | #include <linux/err.h> | ||
7 | #include <linux/mutex.h> | ||
8 | #include <linux/types.h> | ||
9 | #include <uapi/asm-generic/errno-base.h> | ||
10 | |||
11 | struct clk; | ||
12 | struct device; | ||
13 | struct ingenic_ecc; | ||
14 | struct platform_device; | ||
15 | |||
16 | /** | ||
17 | * struct ingenic_ecc_params - ECC parameters | ||
18 | * @size: data bytes per ECC step. | ||
19 | * @bytes: ECC bytes per step. | ||
20 | * @strength: number of correctable bits per ECC step. | ||
21 | */ | ||
22 | struct ingenic_ecc_params { | ||
23 | int size; | ||
24 | int bytes; | ||
25 | int strength; | ||
26 | }; | ||
27 | |||
28 | #if IS_ENABLED(CONFIG_MTD_NAND_INGENIC_ECC) | ||
29 | int ingenic_ecc_calculate(struct ingenic_ecc *ecc, | ||
30 | struct ingenic_ecc_params *params, | ||
31 | const u8 *buf, u8 *ecc_code); | ||
32 | int ingenic_ecc_correct(struct ingenic_ecc *ecc, | ||
33 | struct ingenic_ecc_params *params, u8 *buf, | ||
34 | u8 *ecc_code); | ||
35 | |||
36 | void ingenic_ecc_release(struct ingenic_ecc *ecc); | ||
37 | struct ingenic_ecc *of_ingenic_ecc_get(struct device_node *np); | ||
38 | #else /* CONFIG_MTD_NAND_INGENIC_ECC */ | ||
39 | int ingenic_ecc_calculate(struct ingenic_ecc *ecc, | ||
40 | struct ingenic_ecc_params *params, | ||
41 | const u8 *buf, u8 *ecc_code) | ||
42 | { | ||
43 | return -ENODEV; | ||
44 | } | ||
45 | |||
46 | int ingenic_ecc_correct(struct ingenic_ecc *ecc, | ||
47 | struct ingenic_ecc_params *params, u8 *buf, | ||
48 | u8 *ecc_code) | ||
49 | { | ||
50 | return -ENODEV; | ||
51 | } | ||
52 | |||
53 | void ingenic_ecc_release(struct ingenic_ecc *ecc) | ||
54 | { | ||
55 | } | ||
56 | |||
57 | struct ingenic_ecc *of_ingenic_ecc_get(struct device_node *np) | ||
58 | { | ||
59 | return ERR_PTR(-ENODEV); | ||
60 | } | ||
61 | #endif /* CONFIG_MTD_NAND_INGENIC_ECC */ | ||
62 | |||
63 | struct ingenic_ecc_ops { | ||
64 | void (*disable)(struct ingenic_ecc *ecc); | ||
65 | int (*calculate)(struct ingenic_ecc *ecc, | ||
66 | struct ingenic_ecc_params *params, | ||
67 | const u8 *buf, u8 *ecc_code); | ||
68 | int (*correct)(struct ingenic_ecc *ecc, | ||
69 | struct ingenic_ecc_params *params, | ||
70 | u8 *buf, u8 *ecc_code); | ||
71 | }; | ||
72 | |||
73 | struct ingenic_ecc { | ||
74 | struct device *dev; | ||
75 | const struct ingenic_ecc_ops *ops; | ||
76 | void __iomem *base; | ||
77 | struct clk *clk; | ||
78 | struct mutex lock; | ||
79 | }; | ||
80 | |||
81 | int ingenic_ecc_probe(struct platform_device *pdev); | ||
82 | |||
83 | #endif /* __DRIVERS_MTD_NAND_INGENIC_ECC_INTERNAL_H__ */ | ||
diff --git a/drivers/mtd/nand/raw/ingenic/ingenic_nand.c b/drivers/mtd/nand/raw/ingenic/ingenic_nand.c new file mode 100644 index 000000000000..d7b7c0f13909 --- /dev/null +++ b/drivers/mtd/nand/raw/ingenic/ingenic_nand.c | |||
@@ -0,0 +1,530 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * Ingenic JZ47xx NAND driver | ||
4 | * | ||
5 | * Copyright (c) 2015 Imagination Technologies | ||
6 | * Author: Alex Smith <alex.smith@imgtec.com> | ||
7 | */ | ||
8 | |||
9 | #include <linux/delay.h> | ||
10 | #include <linux/init.h> | ||
11 | #include <linux/io.h> | ||
12 | #include <linux/list.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/of.h> | ||
15 | #include <linux/of_address.h> | ||
16 | #include <linux/of_device.h> | ||
17 | #include <linux/gpio/consumer.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/mtd/mtd.h> | ||
21 | #include <linux/mtd/rawnand.h> | ||
22 | #include <linux/mtd/partitions.h> | ||
23 | |||
24 | #include <linux/jz4780-nemc.h> | ||
25 | |||
26 | #include "ingenic_ecc.h" | ||
27 | |||
28 | #define DRV_NAME "ingenic-nand" | ||
29 | |||
30 | /* Command delay when there is no R/B pin. */ | ||
31 | #define RB_DELAY_US 100 | ||
32 | |||
33 | struct jz_soc_info { | ||
34 | unsigned long data_offset; | ||
35 | unsigned long addr_offset; | ||
36 | unsigned long cmd_offset; | ||
37 | const struct mtd_ooblayout_ops *oob_layout; | ||
38 | }; | ||
39 | |||
40 | struct ingenic_nand_cs { | ||
41 | unsigned int bank; | ||
42 | void __iomem *base; | ||
43 | }; | ||
44 | |||
45 | struct ingenic_nfc { | ||
46 | struct device *dev; | ||
47 | struct ingenic_ecc *ecc; | ||
48 | const struct jz_soc_info *soc_info; | ||
49 | struct nand_controller controller; | ||
50 | unsigned int num_banks; | ||
51 | struct list_head chips; | ||
52 | int selected; | ||
53 | struct ingenic_nand_cs cs[]; | ||
54 | }; | ||
55 | |||
56 | struct ingenic_nand { | ||
57 | struct nand_chip chip; | ||
58 | struct list_head chip_list; | ||
59 | |||
60 | struct gpio_desc *busy_gpio; | ||
61 | struct gpio_desc *wp_gpio; | ||
62 | unsigned int reading: 1; | ||
63 | }; | ||
64 | |||
65 | static inline struct ingenic_nand *to_ingenic_nand(struct mtd_info *mtd) | ||
66 | { | ||
67 | return container_of(mtd_to_nand(mtd), struct ingenic_nand, chip); | ||
68 | } | ||
69 | |||
70 | static inline struct ingenic_nfc *to_ingenic_nfc(struct nand_controller *ctrl) | ||
71 | { | ||
72 | return container_of(ctrl, struct ingenic_nfc, controller); | ||
73 | } | ||
74 | |||
75 | static int qi_lb60_ooblayout_ecc(struct mtd_info *mtd, int section, | ||
76 | struct mtd_oob_region *oobregion) | ||
77 | { | ||
78 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
79 | struct nand_ecc_ctrl *ecc = &chip->ecc; | ||
80 | |||
81 | if (section || !ecc->total) | ||
82 | return -ERANGE; | ||
83 | |||
84 | oobregion->length = ecc->total; | ||
85 | oobregion->offset = 12; | ||
86 | |||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | static int qi_lb60_ooblayout_free(struct mtd_info *mtd, int section, | ||
91 | struct mtd_oob_region *oobregion) | ||
92 | { | ||
93 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
94 | struct nand_ecc_ctrl *ecc = &chip->ecc; | ||
95 | |||
96 | if (section) | ||
97 | return -ERANGE; | ||
98 | |||
99 | oobregion->length = mtd->oobsize - ecc->total - 12; | ||
100 | oobregion->offset = 12 + ecc->total; | ||
101 | |||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | const struct mtd_ooblayout_ops qi_lb60_ooblayout_ops = { | ||
106 | .ecc = qi_lb60_ooblayout_ecc, | ||
107 | .free = qi_lb60_ooblayout_free, | ||
108 | }; | ||
109 | |||
110 | static int jz4725b_ooblayout_ecc(struct mtd_info *mtd, int section, | ||
111 | struct mtd_oob_region *oobregion) | ||
112 | { | ||
113 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
114 | struct nand_ecc_ctrl *ecc = &chip->ecc; | ||
115 | |||
116 | if (section || !ecc->total) | ||
117 | return -ERANGE; | ||
118 | |||
119 | oobregion->length = ecc->total; | ||
120 | oobregion->offset = 3; | ||
121 | |||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | static int jz4725b_ooblayout_free(struct mtd_info *mtd, int section, | ||
126 | struct mtd_oob_region *oobregion) | ||
127 | { | ||
128 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
129 | struct nand_ecc_ctrl *ecc = &chip->ecc; | ||
130 | |||
131 | if (section) | ||
132 | return -ERANGE; | ||
133 | |||
134 | oobregion->length = mtd->oobsize - ecc->total - 3; | ||
135 | oobregion->offset = 3 + ecc->total; | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | static const struct mtd_ooblayout_ops jz4725b_ooblayout_ops = { | ||
141 | .ecc = jz4725b_ooblayout_ecc, | ||
142 | .free = jz4725b_ooblayout_free, | ||
143 | }; | ||
144 | |||
145 | static void ingenic_nand_select_chip(struct nand_chip *chip, int chipnr) | ||
146 | { | ||
147 | struct ingenic_nand *nand = to_ingenic_nand(nand_to_mtd(chip)); | ||
148 | struct ingenic_nfc *nfc = to_ingenic_nfc(nand->chip.controller); | ||
149 | struct ingenic_nand_cs *cs; | ||
150 | |||
151 | /* Ensure the currently selected chip is deasserted. */ | ||
152 | if (chipnr == -1 && nfc->selected >= 0) { | ||
153 | cs = &nfc->cs[nfc->selected]; | ||
154 | jz4780_nemc_assert(nfc->dev, cs->bank, false); | ||
155 | } | ||
156 | |||
157 | nfc->selected = chipnr; | ||
158 | } | ||
159 | |||
160 | static void ingenic_nand_cmd_ctrl(struct nand_chip *chip, int cmd, | ||
161 | unsigned int ctrl) | ||
162 | { | ||
163 | struct ingenic_nand *nand = to_ingenic_nand(nand_to_mtd(chip)); | ||
164 | struct ingenic_nfc *nfc = to_ingenic_nfc(nand->chip.controller); | ||
165 | struct ingenic_nand_cs *cs; | ||
166 | |||
167 | if (WARN_ON(nfc->selected < 0)) | ||
168 | return; | ||
169 | |||
170 | cs = &nfc->cs[nfc->selected]; | ||
171 | |||
172 | jz4780_nemc_assert(nfc->dev, cs->bank, ctrl & NAND_NCE); | ||
173 | |||
174 | if (cmd == NAND_CMD_NONE) | ||
175 | return; | ||
176 | |||
177 | if (ctrl & NAND_ALE) | ||
178 | writeb(cmd, cs->base + nfc->soc_info->addr_offset); | ||
179 | else if (ctrl & NAND_CLE) | ||
180 | writeb(cmd, cs->base + nfc->soc_info->cmd_offset); | ||
181 | } | ||
182 | |||
183 | static int ingenic_nand_dev_ready(struct nand_chip *chip) | ||
184 | { | ||
185 | struct ingenic_nand *nand = to_ingenic_nand(nand_to_mtd(chip)); | ||
186 | |||
187 | return !gpiod_get_value_cansleep(nand->busy_gpio); | ||
188 | } | ||
189 | |||
190 | static void ingenic_nand_ecc_hwctl(struct nand_chip *chip, int mode) | ||
191 | { | ||
192 | struct ingenic_nand *nand = to_ingenic_nand(nand_to_mtd(chip)); | ||
193 | |||
194 | nand->reading = (mode == NAND_ECC_READ); | ||
195 | } | ||
196 | |||
197 | static int ingenic_nand_ecc_calculate(struct nand_chip *chip, const u8 *dat, | ||
198 | u8 *ecc_code) | ||
199 | { | ||
200 | struct ingenic_nand *nand = to_ingenic_nand(nand_to_mtd(chip)); | ||
201 | struct ingenic_nfc *nfc = to_ingenic_nfc(nand->chip.controller); | ||
202 | struct ingenic_ecc_params params; | ||
203 | |||
204 | /* | ||
205 | * Don't need to generate the ECC when reading, the ECC engine does it | ||
206 | * for us as part of decoding/correction. | ||
207 | */ | ||
208 | if (nand->reading) | ||
209 | return 0; | ||
210 | |||
211 | params.size = nand->chip.ecc.size; | ||
212 | params.bytes = nand->chip.ecc.bytes; | ||
213 | params.strength = nand->chip.ecc.strength; | ||
214 | |||
215 | return ingenic_ecc_calculate(nfc->ecc, ¶ms, dat, ecc_code); | ||
216 | } | ||
217 | |||
218 | static int ingenic_nand_ecc_correct(struct nand_chip *chip, u8 *dat, | ||
219 | u8 *read_ecc, u8 *calc_ecc) | ||
220 | { | ||
221 | struct ingenic_nand *nand = to_ingenic_nand(nand_to_mtd(chip)); | ||
222 | struct ingenic_nfc *nfc = to_ingenic_nfc(nand->chip.controller); | ||
223 | struct ingenic_ecc_params params; | ||
224 | |||
225 | params.size = nand->chip.ecc.size; | ||
226 | params.bytes = nand->chip.ecc.bytes; | ||
227 | params.strength = nand->chip.ecc.strength; | ||
228 | |||
229 | return ingenic_ecc_correct(nfc->ecc, ¶ms, dat, read_ecc); | ||
230 | } | ||
231 | |||
232 | static int ingenic_nand_attach_chip(struct nand_chip *chip) | ||
233 | { | ||
234 | struct mtd_info *mtd = nand_to_mtd(chip); | ||
235 | struct ingenic_nfc *nfc = to_ingenic_nfc(chip->controller); | ||
236 | int eccbytes; | ||
237 | |||
238 | if (chip->ecc.strength == 4) { | ||
239 | /* JZ4740 uses 9 bytes of ECC to correct maximum 4 errors */ | ||
240 | chip->ecc.bytes = 9; | ||
241 | } else { | ||
242 | chip->ecc.bytes = fls((1 + 8) * chip->ecc.size) * | ||
243 | (chip->ecc.strength / 8); | ||
244 | } | ||
245 | |||
246 | switch (chip->ecc.mode) { | ||
247 | case NAND_ECC_HW: | ||
248 | if (!nfc->ecc) { | ||
249 | dev_err(nfc->dev, "HW ECC selected, but ECC controller not found\n"); | ||
250 | return -ENODEV; | ||
251 | } | ||
252 | |||
253 | chip->ecc.hwctl = ingenic_nand_ecc_hwctl; | ||
254 | chip->ecc.calculate = ingenic_nand_ecc_calculate; | ||
255 | chip->ecc.correct = ingenic_nand_ecc_correct; | ||
256 | /* fall through */ | ||
257 | case NAND_ECC_SOFT: | ||
258 | dev_info(nfc->dev, "using %s (strength %d, size %d, bytes %d)\n", | ||
259 | (nfc->ecc) ? "hardware ECC" : "software ECC", | ||
260 | chip->ecc.strength, chip->ecc.size, chip->ecc.bytes); | ||
261 | break; | ||
262 | case NAND_ECC_NONE: | ||
263 | dev_info(nfc->dev, "not using ECC\n"); | ||
264 | break; | ||
265 | default: | ||
266 | dev_err(nfc->dev, "ECC mode %d not supported\n", | ||
267 | chip->ecc.mode); | ||
268 | return -EINVAL; | ||
269 | } | ||
270 | |||
271 | /* The NAND core will generate the ECC layout for SW ECC */ | ||
272 | if (chip->ecc.mode != NAND_ECC_HW) | ||
273 | return 0; | ||
274 | |||
275 | /* Generate ECC layout. ECC codes are right aligned in the OOB area. */ | ||
276 | eccbytes = mtd->writesize / chip->ecc.size * chip->ecc.bytes; | ||
277 | |||
278 | if (eccbytes > mtd->oobsize - 2) { | ||
279 | dev_err(nfc->dev, | ||
280 | "invalid ECC config: required %d ECC bytes, but only %d are available", | ||
281 | eccbytes, mtd->oobsize - 2); | ||
282 | return -EINVAL; | ||
283 | } | ||
284 | |||
285 | /* | ||
286 | * The generic layout for BBT markers will most likely overlap with our | ||
287 | * ECC bytes in the OOB, so move the BBT markers outside the OOB area. | ||
288 | */ | ||
289 | if (chip->bbt_options & NAND_BBT_USE_FLASH) | ||
290 | chip->bbt_options |= NAND_BBT_NO_OOB; | ||
291 | |||
292 | /* For legacy reasons we use a different layout on the qi,lb60 board. */ | ||
293 | if (of_machine_is_compatible("qi,lb60")) | ||
294 | mtd_set_ooblayout(mtd, &qi_lb60_ooblayout_ops); | ||
295 | else | ||
296 | mtd_set_ooblayout(mtd, nfc->soc_info->oob_layout); | ||
297 | |||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | static const struct nand_controller_ops ingenic_nand_controller_ops = { | ||
302 | .attach_chip = ingenic_nand_attach_chip, | ||
303 | }; | ||
304 | |||
305 | static int ingenic_nand_init_chip(struct platform_device *pdev, | ||
306 | struct ingenic_nfc *nfc, | ||
307 | struct device_node *np, | ||
308 | unsigned int chipnr) | ||
309 | { | ||
310 | struct device *dev = &pdev->dev; | ||
311 | struct ingenic_nand *nand; | ||
312 | struct ingenic_nand_cs *cs; | ||
313 | struct resource *res; | ||
314 | struct nand_chip *chip; | ||
315 | struct mtd_info *mtd; | ||
316 | const __be32 *reg; | ||
317 | int ret = 0; | ||
318 | |||
319 | cs = &nfc->cs[chipnr]; | ||
320 | |||
321 | reg = of_get_property(np, "reg", NULL); | ||
322 | if (!reg) | ||
323 | return -EINVAL; | ||
324 | |||
325 | cs->bank = be32_to_cpu(*reg); | ||
326 | |||
327 | jz4780_nemc_set_type(nfc->dev, cs->bank, JZ4780_NEMC_BANK_NAND); | ||
328 | |||
329 | res = platform_get_resource(pdev, IORESOURCE_MEM, chipnr); | ||
330 | cs->base = devm_ioremap_resource(dev, res); | ||
331 | if (IS_ERR(cs->base)) | ||
332 | return PTR_ERR(cs->base); | ||
333 | |||
334 | nand = devm_kzalloc(dev, sizeof(*nand), GFP_KERNEL); | ||
335 | if (!nand) | ||
336 | return -ENOMEM; | ||
337 | |||
338 | nand->busy_gpio = devm_gpiod_get_optional(dev, "rb", GPIOD_IN); | ||
339 | |||
340 | if (IS_ERR(nand->busy_gpio)) { | ||
341 | ret = PTR_ERR(nand->busy_gpio); | ||
342 | dev_err(dev, "failed to request busy GPIO: %d\n", ret); | ||
343 | return ret; | ||
344 | } else if (nand->busy_gpio) { | ||
345 | nand->chip.legacy.dev_ready = ingenic_nand_dev_ready; | ||
346 | } | ||
347 | |||
348 | nand->wp_gpio = devm_gpiod_get_optional(dev, "wp", GPIOD_OUT_LOW); | ||
349 | |||
350 | if (IS_ERR(nand->wp_gpio)) { | ||
351 | ret = PTR_ERR(nand->wp_gpio); | ||
352 | dev_err(dev, "failed to request WP GPIO: %d\n", ret); | ||
353 | return ret; | ||
354 | } | ||
355 | |||
356 | chip = &nand->chip; | ||
357 | mtd = nand_to_mtd(chip); | ||
358 | mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%s.%d", dev_name(dev), | ||
359 | cs->bank); | ||
360 | if (!mtd->name) | ||
361 | return -ENOMEM; | ||
362 | mtd->dev.parent = dev; | ||
363 | |||
364 | chip->legacy.IO_ADDR_R = cs->base + nfc->soc_info->data_offset; | ||
365 | chip->legacy.IO_ADDR_W = cs->base + nfc->soc_info->data_offset; | ||
366 | chip->legacy.chip_delay = RB_DELAY_US; | ||
367 | chip->options = NAND_NO_SUBPAGE_WRITE; | ||
368 | chip->legacy.select_chip = ingenic_nand_select_chip; | ||
369 | chip->legacy.cmd_ctrl = ingenic_nand_cmd_ctrl; | ||
370 | chip->ecc.mode = NAND_ECC_HW; | ||
371 | chip->controller = &nfc->controller; | ||
372 | nand_set_flash_node(chip, np); | ||
373 | |||
374 | chip->controller->ops = &ingenic_nand_controller_ops; | ||
375 | ret = nand_scan(chip, 1); | ||
376 | if (ret) | ||
377 | return ret; | ||
378 | |||
379 | ret = mtd_device_register(mtd, NULL, 0); | ||
380 | if (ret) { | ||
381 | nand_release(chip); | ||
382 | return ret; | ||
383 | } | ||
384 | |||
385 | list_add_tail(&nand->chip_list, &nfc->chips); | ||
386 | |||
387 | return 0; | ||
388 | } | ||
389 | |||
390 | static void ingenic_nand_cleanup_chips(struct ingenic_nfc *nfc) | ||
391 | { | ||
392 | struct ingenic_nand *chip; | ||
393 | |||
394 | while (!list_empty(&nfc->chips)) { | ||
395 | chip = list_first_entry(&nfc->chips, | ||
396 | struct ingenic_nand, chip_list); | ||
397 | nand_release(&chip->chip); | ||
398 | list_del(&chip->chip_list); | ||
399 | } | ||
400 | } | ||
401 | |||
402 | static int ingenic_nand_init_chips(struct ingenic_nfc *nfc, | ||
403 | struct platform_device *pdev) | ||
404 | { | ||
405 | struct device *dev = &pdev->dev; | ||
406 | struct device_node *np; | ||
407 | int i = 0; | ||
408 | int ret; | ||
409 | int num_chips = of_get_child_count(dev->of_node); | ||
410 | |||
411 | if (num_chips > nfc->num_banks) { | ||
412 | dev_err(dev, "found %d chips but only %d banks\n", | ||
413 | num_chips, nfc->num_banks); | ||
414 | return -EINVAL; | ||
415 | } | ||
416 | |||
417 | for_each_child_of_node(dev->of_node, np) { | ||
418 | ret = ingenic_nand_init_chip(pdev, nfc, np, i); | ||
419 | if (ret) { | ||
420 | ingenic_nand_cleanup_chips(nfc); | ||
421 | return ret; | ||
422 | } | ||
423 | |||
424 | i++; | ||
425 | } | ||
426 | |||
427 | return 0; | ||
428 | } | ||
429 | |||
430 | static int ingenic_nand_probe(struct platform_device *pdev) | ||
431 | { | ||
432 | struct device *dev = &pdev->dev; | ||
433 | unsigned int num_banks; | ||
434 | struct ingenic_nfc *nfc; | ||
435 | int ret; | ||
436 | |||
437 | num_banks = jz4780_nemc_num_banks(dev); | ||
438 | if (num_banks == 0) { | ||
439 | dev_err(dev, "no banks found\n"); | ||
440 | return -ENODEV; | ||
441 | } | ||
442 | |||
443 | nfc = devm_kzalloc(dev, struct_size(nfc, cs, num_banks), GFP_KERNEL); | ||
444 | if (!nfc) | ||
445 | return -ENOMEM; | ||
446 | |||
447 | nfc->soc_info = device_get_match_data(dev); | ||
448 | if (!nfc->soc_info) | ||
449 | return -EINVAL; | ||
450 | |||
451 | /* | ||
452 | * Check for ECC HW before we call nand_scan_ident, to prevent us from | ||
453 | * having to call it again if the ECC driver returns -EPROBE_DEFER. | ||
454 | */ | ||
455 | nfc->ecc = of_ingenic_ecc_get(dev->of_node); | ||
456 | if (IS_ERR(nfc->ecc)) | ||
457 | return PTR_ERR(nfc->ecc); | ||
458 | |||
459 | nfc->dev = dev; | ||
460 | nfc->num_banks = num_banks; | ||
461 | |||
462 | nand_controller_init(&nfc->controller); | ||
463 | INIT_LIST_HEAD(&nfc->chips); | ||
464 | |||
465 | ret = ingenic_nand_init_chips(nfc, pdev); | ||
466 | if (ret) { | ||
467 | if (nfc->ecc) | ||
468 | ingenic_ecc_release(nfc->ecc); | ||
469 | return ret; | ||
470 | } | ||
471 | |||
472 | platform_set_drvdata(pdev, nfc); | ||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | static int ingenic_nand_remove(struct platform_device *pdev) | ||
477 | { | ||
478 | struct ingenic_nfc *nfc = platform_get_drvdata(pdev); | ||
479 | |||
480 | if (nfc->ecc) | ||
481 | ingenic_ecc_release(nfc->ecc); | ||
482 | |||
483 | ingenic_nand_cleanup_chips(nfc); | ||
484 | |||
485 | return 0; | ||
486 | } | ||
487 | |||
488 | static const struct jz_soc_info jz4740_soc_info = { | ||
489 | .data_offset = 0x00000000, | ||
490 | .cmd_offset = 0x00008000, | ||
491 | .addr_offset = 0x00010000, | ||
492 | .oob_layout = &nand_ooblayout_lp_ops, | ||
493 | }; | ||
494 | |||
495 | static const struct jz_soc_info jz4725b_soc_info = { | ||
496 | .data_offset = 0x00000000, | ||
497 | .cmd_offset = 0x00008000, | ||
498 | .addr_offset = 0x00010000, | ||
499 | .oob_layout = &jz4725b_ooblayout_ops, | ||
500 | }; | ||
501 | |||
502 | static const struct jz_soc_info jz4780_soc_info = { | ||
503 | .data_offset = 0x00000000, | ||
504 | .cmd_offset = 0x00400000, | ||
505 | .addr_offset = 0x00800000, | ||
506 | .oob_layout = &nand_ooblayout_lp_ops, | ||
507 | }; | ||
508 | |||
509 | static const struct of_device_id ingenic_nand_dt_match[] = { | ||
510 | { .compatible = "ingenic,jz4740-nand", .data = &jz4740_soc_info }, | ||
511 | { .compatible = "ingenic,jz4725b-nand", .data = &jz4725b_soc_info }, | ||
512 | { .compatible = "ingenic,jz4780-nand", .data = &jz4780_soc_info }, | ||
513 | {}, | ||
514 | }; | ||
515 | MODULE_DEVICE_TABLE(of, ingenic_nand_dt_match); | ||
516 | |||
517 | static struct platform_driver ingenic_nand_driver = { | ||
518 | .probe = ingenic_nand_probe, | ||
519 | .remove = ingenic_nand_remove, | ||
520 | .driver = { | ||
521 | .name = DRV_NAME, | ||
522 | .of_match_table = of_match_ptr(ingenic_nand_dt_match), | ||
523 | }, | ||
524 | }; | ||
525 | module_platform_driver(ingenic_nand_driver); | ||
526 | |||
527 | MODULE_AUTHOR("Alex Smith <alex@alex-smith.me.uk>"); | ||
528 | MODULE_AUTHOR("Harvey Hunt <harveyhuntnexus@gmail.com>"); | ||
529 | MODULE_DESCRIPTION("Ingenic JZ47xx NAND driver"); | ||
530 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mtd/nand/raw/ingenic/jz4725b_bch.c b/drivers/mtd/nand/raw/ingenic/jz4725b_bch.c new file mode 100644 index 000000000000..6c852eae09cf --- /dev/null +++ b/drivers/mtd/nand/raw/ingenic/jz4725b_bch.c | |||
@@ -0,0 +1,295 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * JZ4725B BCH controller driver | ||
4 | * | ||
5 | * Copyright (C) 2019 Paul Cercueil <paul@crapouillou.net> | ||
6 | * | ||
7 | * Based on jz4780_bch.c | ||
8 | */ | ||
9 | |||
10 | #include <linux/bitops.h> | ||
11 | #include <linux/device.h> | ||
12 | #include <linux/io.h> | ||
13 | #include <linux/iopoll.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/mutex.h> | ||
16 | #include <linux/of_platform.h> | ||
17 | #include <linux/platform_device.h> | ||
18 | |||
19 | #include "ingenic_ecc.h" | ||
20 | |||
21 | #define BCH_BHCR 0x0 | ||
22 | #define BCH_BHCSR 0x4 | ||
23 | #define BCH_BHCCR 0x8 | ||
24 | #define BCH_BHCNT 0xc | ||
25 | #define BCH_BHDR 0x10 | ||
26 | #define BCH_BHPAR0 0x14 | ||
27 | #define BCH_BHERR0 0x28 | ||
28 | #define BCH_BHINT 0x24 | ||
29 | #define BCH_BHINTES 0x3c | ||
30 | #define BCH_BHINTEC 0x40 | ||
31 | #define BCH_BHINTE 0x38 | ||
32 | |||
33 | #define BCH_BHCR_ENCE BIT(3) | ||
34 | #define BCH_BHCR_BSEL BIT(2) | ||
35 | #define BCH_BHCR_INIT BIT(1) | ||
36 | #define BCH_BHCR_BCHE BIT(0) | ||
37 | |||
38 | #define BCH_BHCNT_DEC_COUNT_SHIFT 16 | ||
39 | #define BCH_BHCNT_DEC_COUNT_MASK (0x3ff << BCH_BHCNT_DEC_COUNT_SHIFT) | ||
40 | #define BCH_BHCNT_ENC_COUNT_SHIFT 0 | ||
41 | #define BCH_BHCNT_ENC_COUNT_MASK (0x3ff << BCH_BHCNT_ENC_COUNT_SHIFT) | ||
42 | |||
43 | #define BCH_BHERR_INDEX0_SHIFT 0 | ||
44 | #define BCH_BHERR_INDEX0_MASK (0x1fff << BCH_BHERR_INDEX0_SHIFT) | ||
45 | #define BCH_BHERR_INDEX1_SHIFT 16 | ||
46 | #define BCH_BHERR_INDEX1_MASK (0x1fff << BCH_BHERR_INDEX1_SHIFT) | ||
47 | |||
48 | #define BCH_BHINT_ERRC_SHIFT 28 | ||
49 | #define BCH_BHINT_ERRC_MASK (0xf << BCH_BHINT_ERRC_SHIFT) | ||
50 | #define BCH_BHINT_TERRC_SHIFT 16 | ||
51 | #define BCH_BHINT_TERRC_MASK (0x7f << BCH_BHINT_TERRC_SHIFT) | ||
52 | #define BCH_BHINT_ALL_0 BIT(5) | ||
53 | #define BCH_BHINT_ALL_F BIT(4) | ||
54 | #define BCH_BHINT_DECF BIT(3) | ||
55 | #define BCH_BHINT_ENCF BIT(2) | ||
56 | #define BCH_BHINT_UNCOR BIT(1) | ||
57 | #define BCH_BHINT_ERR BIT(0) | ||
58 | |||
59 | /* Timeout for BCH calculation/correction. */ | ||
60 | #define BCH_TIMEOUT_US 100000 | ||
61 | |||
62 | static inline void jz4725b_bch_config_set(struct ingenic_ecc *bch, u32 cfg) | ||
63 | { | ||
64 | writel(cfg, bch->base + BCH_BHCSR); | ||
65 | } | ||
66 | |||
67 | static inline void jz4725b_bch_config_clear(struct ingenic_ecc *bch, u32 cfg) | ||
68 | { | ||
69 | writel(cfg, bch->base + BCH_BHCCR); | ||
70 | } | ||
71 | |||
72 | static int jz4725b_bch_reset(struct ingenic_ecc *bch, | ||
73 | struct ingenic_ecc_params *params, bool calc_ecc) | ||
74 | { | ||
75 | u32 reg, max_value; | ||
76 | |||
77 | /* Clear interrupt status. */ | ||
78 | writel(readl(bch->base + BCH_BHINT), bch->base + BCH_BHINT); | ||
79 | |||
80 | /* Initialise and enable BCH. */ | ||
81 | jz4725b_bch_config_clear(bch, 0x1f); | ||
82 | jz4725b_bch_config_set(bch, BCH_BHCR_BCHE); | ||
83 | |||
84 | if (params->strength == 8) | ||
85 | jz4725b_bch_config_set(bch, BCH_BHCR_BSEL); | ||
86 | else | ||
87 | jz4725b_bch_config_clear(bch, BCH_BHCR_BSEL); | ||
88 | |||
89 | if (calc_ecc) /* calculate ECC from data */ | ||
90 | jz4725b_bch_config_set(bch, BCH_BHCR_ENCE); | ||
91 | else /* correct data from ECC */ | ||
92 | jz4725b_bch_config_clear(bch, BCH_BHCR_ENCE); | ||
93 | |||
94 | jz4725b_bch_config_set(bch, BCH_BHCR_INIT); | ||
95 | |||
96 | max_value = BCH_BHCNT_ENC_COUNT_MASK >> BCH_BHCNT_ENC_COUNT_SHIFT; | ||
97 | if (params->size > max_value) | ||
98 | return -EINVAL; | ||
99 | |||
100 | max_value = BCH_BHCNT_DEC_COUNT_MASK >> BCH_BHCNT_DEC_COUNT_SHIFT; | ||
101 | if (params->size + params->bytes > max_value) | ||
102 | return -EINVAL; | ||
103 | |||
104 | /* Set up BCH count register. */ | ||
105 | reg = params->size << BCH_BHCNT_ENC_COUNT_SHIFT; | ||
106 | reg |= (params->size + params->bytes) << BCH_BHCNT_DEC_COUNT_SHIFT; | ||
107 | writel(reg, bch->base + BCH_BHCNT); | ||
108 | |||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | static void jz4725b_bch_disable(struct ingenic_ecc *bch) | ||
113 | { | ||
114 | /* Clear interrupts */ | ||
115 | writel(readl(bch->base + BCH_BHINT), bch->base + BCH_BHINT); | ||
116 | |||
117 | /* Disable the hardware */ | ||
118 | jz4725b_bch_config_clear(bch, BCH_BHCR_BCHE); | ||
119 | } | ||
120 | |||
121 | static void jz4725b_bch_write_data(struct ingenic_ecc *bch, const u8 *buf, | ||
122 | size_t size) | ||
123 | { | ||
124 | while (size--) | ||
125 | writeb(*buf++, bch->base + BCH_BHDR); | ||
126 | } | ||
127 | |||
128 | static void jz4725b_bch_read_parity(struct ingenic_ecc *bch, u8 *buf, | ||
129 | size_t size) | ||
130 | { | ||
131 | size_t size32 = size / sizeof(u32); | ||
132 | size_t size8 = size % sizeof(u32); | ||
133 | u32 *dest32; | ||
134 | u8 *dest8; | ||
135 | u32 val, offset = 0; | ||
136 | |||
137 | dest32 = (u32 *)buf; | ||
138 | while (size32--) { | ||
139 | *dest32++ = readl_relaxed(bch->base + BCH_BHPAR0 + offset); | ||
140 | offset += sizeof(u32); | ||
141 | } | ||
142 | |||
143 | dest8 = (u8 *)dest32; | ||
144 | val = readl_relaxed(bch->base + BCH_BHPAR0 + offset); | ||
145 | switch (size8) { | ||
146 | case 3: | ||
147 | dest8[2] = (val >> 16) & 0xff; | ||
148 | /* fall-through */ | ||
149 | case 2: | ||
150 | dest8[1] = (val >> 8) & 0xff; | ||
151 | /* fall-through */ | ||
152 | case 1: | ||
153 | dest8[0] = val & 0xff; | ||
154 | break; | ||
155 | } | ||
156 | } | ||
157 | |||
158 | static int jz4725b_bch_wait_complete(struct ingenic_ecc *bch, unsigned int irq, | ||
159 | u32 *status) | ||
160 | { | ||
161 | u32 reg; | ||
162 | int ret; | ||
163 | |||
164 | /* | ||
165 | * While we could use interrupts here and sleep until the operation | ||
166 | * completes, the controller works fairly quickly (usually a few | ||
167 | * microseconds) and so the overhead of sleeping until we get an | ||
168 | * interrupt quite noticeably decreases performance. | ||
169 | */ | ||
170 | ret = readl_relaxed_poll_timeout(bch->base + BCH_BHINT, reg, | ||
171 | reg & irq, 0, BCH_TIMEOUT_US); | ||
172 | if (ret) | ||
173 | return ret; | ||
174 | |||
175 | if (status) | ||
176 | *status = reg; | ||
177 | |||
178 | writel(reg, bch->base + BCH_BHINT); | ||
179 | |||
180 | return 0; | ||
181 | } | ||
182 | |||
183 | static int jz4725b_calculate(struct ingenic_ecc *bch, | ||
184 | struct ingenic_ecc_params *params, | ||
185 | const u8 *buf, u8 *ecc_code) | ||
186 | { | ||
187 | int ret; | ||
188 | |||
189 | mutex_lock(&bch->lock); | ||
190 | |||
191 | ret = jz4725b_bch_reset(bch, params, true); | ||
192 | if (ret) { | ||
193 | dev_err(bch->dev, "Unable to init BCH with given parameters\n"); | ||
194 | goto out_disable; | ||
195 | } | ||
196 | |||
197 | jz4725b_bch_write_data(bch, buf, params->size); | ||
198 | |||
199 | ret = jz4725b_bch_wait_complete(bch, BCH_BHINT_ENCF, NULL); | ||
200 | if (ret) { | ||
201 | dev_err(bch->dev, "timed out while calculating ECC\n"); | ||
202 | goto out_disable; | ||
203 | } | ||
204 | |||
205 | jz4725b_bch_read_parity(bch, ecc_code, params->bytes); | ||
206 | |||
207 | out_disable: | ||
208 | jz4725b_bch_disable(bch); | ||
209 | mutex_unlock(&bch->lock); | ||
210 | |||
211 | return ret; | ||
212 | } | ||
213 | |||
214 | static int jz4725b_correct(struct ingenic_ecc *bch, | ||
215 | struct ingenic_ecc_params *params, | ||
216 | u8 *buf, u8 *ecc_code) | ||
217 | { | ||
218 | u32 reg, errors, bit; | ||
219 | unsigned int i; | ||
220 | int ret; | ||
221 | |||
222 | mutex_lock(&bch->lock); | ||
223 | |||
224 | ret = jz4725b_bch_reset(bch, params, false); | ||
225 | if (ret) { | ||
226 | dev_err(bch->dev, "Unable to init BCH with given parameters\n"); | ||
227 | goto out; | ||
228 | } | ||
229 | |||
230 | jz4725b_bch_write_data(bch, buf, params->size); | ||
231 | jz4725b_bch_write_data(bch, ecc_code, params->bytes); | ||
232 | |||
233 | ret = jz4725b_bch_wait_complete(bch, BCH_BHINT_DECF, ®); | ||
234 | if (ret) { | ||
235 | dev_err(bch->dev, "timed out while correcting data\n"); | ||
236 | goto out; | ||
237 | } | ||
238 | |||
239 | if (reg & (BCH_BHINT_ALL_F | BCH_BHINT_ALL_0)) { | ||
240 | /* Data and ECC is all 0xff or 0x00 - nothing to correct */ | ||
241 | ret = 0; | ||
242 | goto out; | ||
243 | } | ||
244 | |||
245 | if (reg & BCH_BHINT_UNCOR) { | ||
246 | /* Uncorrectable ECC error */ | ||
247 | ret = -EBADMSG; | ||
248 | goto out; | ||
249 | } | ||
250 | |||
251 | errors = (reg & BCH_BHINT_ERRC_MASK) >> BCH_BHINT_ERRC_SHIFT; | ||
252 | |||
253 | /* Correct any detected errors. */ | ||
254 | for (i = 0; i < errors; i++) { | ||
255 | if (i & 1) { | ||
256 | bit = (reg & BCH_BHERR_INDEX1_MASK) >> BCH_BHERR_INDEX1_SHIFT; | ||
257 | } else { | ||
258 | reg = readl(bch->base + BCH_BHERR0 + (i * 4)); | ||
259 | bit = (reg & BCH_BHERR_INDEX0_MASK) >> BCH_BHERR_INDEX0_SHIFT; | ||
260 | } | ||
261 | |||
262 | buf[(bit >> 3)] ^= BIT(bit & 0x7); | ||
263 | } | ||
264 | |||
265 | out: | ||
266 | jz4725b_bch_disable(bch); | ||
267 | mutex_unlock(&bch->lock); | ||
268 | |||
269 | return ret; | ||
270 | } | ||
271 | |||
272 | static const struct ingenic_ecc_ops jz4725b_bch_ops = { | ||
273 | .disable = jz4725b_bch_disable, | ||
274 | .calculate = jz4725b_calculate, | ||
275 | .correct = jz4725b_correct, | ||
276 | }; | ||
277 | |||
278 | static const struct of_device_id jz4725b_bch_dt_match[] = { | ||
279 | { .compatible = "ingenic,jz4725b-bch", .data = &jz4725b_bch_ops }, | ||
280 | {}, | ||
281 | }; | ||
282 | MODULE_DEVICE_TABLE(of, jz4725b_bch_dt_match); | ||
283 | |||
284 | static struct platform_driver jz4725b_bch_driver = { | ||
285 | .probe = ingenic_ecc_probe, | ||
286 | .driver = { | ||
287 | .name = "jz4725b-bch", | ||
288 | .of_match_table = jz4725b_bch_dt_match, | ||
289 | }, | ||
290 | }; | ||
291 | module_platform_driver(jz4725b_bch_driver); | ||
292 | |||
293 | MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>"); | ||
294 | MODULE_DESCRIPTION("Ingenic JZ4725B BCH controller driver"); | ||
295 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mtd/nand/raw/ingenic/jz4740_ecc.c b/drivers/mtd/nand/raw/ingenic/jz4740_ecc.c new file mode 100644 index 000000000000..13fea645c7f0 --- /dev/null +++ b/drivers/mtd/nand/raw/ingenic/jz4740_ecc.c | |||
@@ -0,0 +1,197 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | /* | ||
3 | * JZ4740 ECC controller driver | ||
4 | * | ||
5 | * Copyright (c) 2019 Paul Cercueil <paul@crapouillou.net> | ||
6 | * | ||
7 | * based on jz4740-nand.c | ||
8 | */ | ||
9 | |||
10 | #include <linux/bitops.h> | ||
11 | #include <linux/device.h> | ||
12 | #include <linux/io.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/of_platform.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | |||
17 | #include "ingenic_ecc.h" | ||
18 | |||
19 | #define JZ_REG_NAND_ECC_CTRL 0x00 | ||
20 | #define JZ_REG_NAND_DATA 0x04 | ||
21 | #define JZ_REG_NAND_PAR0 0x08 | ||
22 | #define JZ_REG_NAND_PAR1 0x0C | ||
23 | #define JZ_REG_NAND_PAR2 0x10 | ||
24 | #define JZ_REG_NAND_IRQ_STAT 0x14 | ||
25 | #define JZ_REG_NAND_IRQ_CTRL 0x18 | ||
26 | #define JZ_REG_NAND_ERR(x) (0x1C + ((x) << 2)) | ||
27 | |||
28 | #define JZ_NAND_ECC_CTRL_PAR_READY BIT(4) | ||
29 | #define JZ_NAND_ECC_CTRL_ENCODING BIT(3) | ||
30 | #define JZ_NAND_ECC_CTRL_RS BIT(2) | ||
31 | #define JZ_NAND_ECC_CTRL_RESET BIT(1) | ||
32 | #define JZ_NAND_ECC_CTRL_ENABLE BIT(0) | ||
33 | |||
34 | #define JZ_NAND_STATUS_ERR_COUNT (BIT(31) | BIT(30) | BIT(29)) | ||
35 | #define JZ_NAND_STATUS_PAD_FINISH BIT(4) | ||
36 | #define JZ_NAND_STATUS_DEC_FINISH BIT(3) | ||
37 | #define JZ_NAND_STATUS_ENC_FINISH BIT(2) | ||
38 | #define JZ_NAND_STATUS_UNCOR_ERROR BIT(1) | ||
39 | #define JZ_NAND_STATUS_ERROR BIT(0) | ||
40 | |||
41 | static const uint8_t empty_block_ecc[] = { | ||
42 | 0xcd, 0x9d, 0x90, 0x58, 0xf4, 0x8b, 0xff, 0xb7, 0x6f | ||
43 | }; | ||
44 | |||
45 | static void jz4740_ecc_reset(struct ingenic_ecc *ecc, bool calc_ecc) | ||
46 | { | ||
47 | uint32_t reg; | ||
48 | |||
49 | /* Clear interrupt status */ | ||
50 | writel(0, ecc->base + JZ_REG_NAND_IRQ_STAT); | ||
51 | |||
52 | /* Initialize and enable ECC hardware */ | ||
53 | reg = readl(ecc->base + JZ_REG_NAND_ECC_CTRL); | ||
54 | reg |= JZ_NAND_ECC_CTRL_RESET; | ||
55 | reg |= JZ_NAND_ECC_CTRL_ENABLE; | ||
56 | reg |= JZ_NAND_ECC_CTRL_RS; | ||
57 | if (calc_ecc) /* calculate ECC from data */ | ||
58 | reg |= JZ_NAND_ECC_CTRL_ENCODING; | ||
59 | else /* correct data from ECC */ | ||
60 | reg &= ~JZ_NAND_ECC_CTRL_ENCODING; | ||
61 | |||
62 | writel(reg, ecc->base + JZ_REG_NAND_ECC_CTRL); | ||
63 | } | ||
64 | |||
65 | static int jz4740_ecc_calculate(struct ingenic_ecc *ecc, | ||
66 | struct ingenic_ecc_params *params, | ||
67 | const u8 *buf, u8 *ecc_code) | ||
68 | { | ||
69 | uint32_t reg, status; | ||
70 | unsigned int timeout = 1000; | ||
71 | int i; | ||
72 | |||
73 | jz4740_ecc_reset(ecc, true); | ||
74 | |||
75 | do { | ||
76 | status = readl(ecc->base + JZ_REG_NAND_IRQ_STAT); | ||
77 | } while (!(status & JZ_NAND_STATUS_ENC_FINISH) && --timeout); | ||
78 | |||
79 | if (timeout == 0) | ||
80 | return -ETIMEDOUT; | ||
81 | |||
82 | reg = readl(ecc->base + JZ_REG_NAND_ECC_CTRL); | ||
83 | reg &= ~JZ_NAND_ECC_CTRL_ENABLE; | ||
84 | writel(reg, ecc->base + JZ_REG_NAND_ECC_CTRL); | ||
85 | |||
86 | for (i = 0; i < params->bytes; ++i) | ||
87 | ecc_code[i] = readb(ecc->base + JZ_REG_NAND_PAR0 + i); | ||
88 | |||
89 | /* | ||
90 | * If the written data is completely 0xff, we also want to write 0xff as | ||
91 | * ECC, otherwise we will get in trouble when doing subpage writes. | ||
92 | */ | ||
93 | if (memcmp(ecc_code, empty_block_ecc, ARRAY_SIZE(empty_block_ecc)) == 0) | ||
94 | memset(ecc_code, 0xff, ARRAY_SIZE(empty_block_ecc)); | ||
95 | |||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | static void jz_nand_correct_data(uint8_t *buf, int index, int mask) | ||
100 | { | ||
101 | int offset = index & 0x7; | ||
102 | uint16_t data; | ||
103 | |||
104 | index += (index >> 3); | ||
105 | |||
106 | data = buf[index]; | ||
107 | data |= buf[index + 1] << 8; | ||
108 | |||
109 | mask ^= (data >> offset) & 0x1ff; | ||
110 | data &= ~(0x1ff << offset); | ||
111 | data |= (mask << offset); | ||
112 | |||
113 | buf[index] = data & 0xff; | ||
114 | buf[index + 1] = (data >> 8) & 0xff; | ||
115 | } | ||
116 | |||
117 | static int jz4740_ecc_correct(struct ingenic_ecc *ecc, | ||
118 | struct ingenic_ecc_params *params, | ||
119 | u8 *buf, u8 *ecc_code) | ||
120 | { | ||
121 | int i, error_count, index; | ||
122 | uint32_t reg, status, error; | ||
123 | unsigned int timeout = 1000; | ||
124 | |||
125 | jz4740_ecc_reset(ecc, false); | ||
126 | |||
127 | for (i = 0; i < params->bytes; ++i) | ||
128 | writeb(ecc_code[i], ecc->base + JZ_REG_NAND_PAR0 + i); | ||
129 | |||
130 | reg = readl(ecc->base + JZ_REG_NAND_ECC_CTRL); | ||
131 | reg |= JZ_NAND_ECC_CTRL_PAR_READY; | ||
132 | writel(reg, ecc->base + JZ_REG_NAND_ECC_CTRL); | ||
133 | |||
134 | do { | ||
135 | status = readl(ecc->base + JZ_REG_NAND_IRQ_STAT); | ||
136 | } while (!(status & JZ_NAND_STATUS_DEC_FINISH) && --timeout); | ||
137 | |||
138 | if (timeout == 0) | ||
139 | return -ETIMEDOUT; | ||
140 | |||
141 | reg = readl(ecc->base + JZ_REG_NAND_ECC_CTRL); | ||
142 | reg &= ~JZ_NAND_ECC_CTRL_ENABLE; | ||
143 | writel(reg, ecc->base + JZ_REG_NAND_ECC_CTRL); | ||
144 | |||
145 | if (status & JZ_NAND_STATUS_ERROR) { | ||
146 | if (status & JZ_NAND_STATUS_UNCOR_ERROR) | ||
147 | return -EBADMSG; | ||
148 | |||
149 | error_count = (status & JZ_NAND_STATUS_ERR_COUNT) >> 29; | ||
150 | |||
151 | for (i = 0; i < error_count; ++i) { | ||
152 | error = readl(ecc->base + JZ_REG_NAND_ERR(i)); | ||
153 | index = ((error >> 16) & 0x1ff) - 1; | ||
154 | if (index >= 0 && index < params->size) | ||
155 | jz_nand_correct_data(buf, index, error & 0x1ff); | ||
156 | } | ||
157 | |||
158 | return error_count; | ||
159 | } | ||
160 | |||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static void jz4740_ecc_disable(struct ingenic_ecc *ecc) | ||
165 | { | ||
166 | u32 reg; | ||
167 | |||
168 | writel(0, ecc->base + JZ_REG_NAND_IRQ_STAT); | ||
169 | reg = readl(ecc->base + JZ_REG_NAND_ECC_CTRL); | ||
170 | reg &= ~JZ_NAND_ECC_CTRL_ENABLE; | ||
171 | writel(reg, ecc->base + JZ_REG_NAND_ECC_CTRL); | ||
172 | } | ||
173 | |||
174 | static const struct ingenic_ecc_ops jz4740_ecc_ops = { | ||
175 | .disable = jz4740_ecc_disable, | ||
176 | .calculate = jz4740_ecc_calculate, | ||
177 | .correct = jz4740_ecc_correct, | ||
178 | }; | ||
179 | |||
180 | static const struct of_device_id jz4740_ecc_dt_match[] = { | ||
181 | { .compatible = "ingenic,jz4740-ecc", .data = &jz4740_ecc_ops }, | ||
182 | {}, | ||
183 | }; | ||
184 | MODULE_DEVICE_TABLE(of, jz4740_ecc_dt_match); | ||
185 | |||
186 | static struct platform_driver jz4740_ecc_driver = { | ||
187 | .probe = ingenic_ecc_probe, | ||
188 | .driver = { | ||
189 | .name = "jz4740-ecc", | ||
190 | .of_match_table = jz4740_ecc_dt_match, | ||
191 | }, | ||
192 | }; | ||
193 | module_platform_driver(jz4740_ecc_driver); | ||
194 | |||
195 | MODULE_AUTHOR("Paul Cercueil <paul@crapouillou.net>"); | ||
196 | MODULE_DESCRIPTION("Ingenic JZ4740 ECC controller driver"); | ||
197 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mtd/nand/raw/jz4740_nand.c b/drivers/mtd/nand/raw/ingenic/jz4740_nand.c index 9526d5b23c80..f759f1672855 100644 --- a/drivers/mtd/nand/raw/jz4740_nand.c +++ b/drivers/mtd/nand/raw/ingenic/jz4740_nand.c | |||
@@ -313,8 +313,11 @@ static int jz_nand_detect_bank(struct platform_device *pdev, | |||
313 | uint32_t ctrl; | 313 | uint32_t ctrl; |
314 | struct nand_chip *chip = &nand->chip; | 314 | struct nand_chip *chip = &nand->chip; |
315 | struct mtd_info *mtd = nand_to_mtd(chip); | 315 | struct mtd_info *mtd = nand_to_mtd(chip); |
316 | struct nand_memory_organization *memorg; | ||
316 | u8 id[2]; | 317 | u8 id[2]; |
317 | 318 | ||
319 | memorg = nanddev_get_memorg(&chip->base); | ||
320 | |||
318 | /* Request I/O resource. */ | 321 | /* Request I/O resource. */ |
319 | sprintf(res_name, "bank%d", bank); | 322 | sprintf(res_name, "bank%d", bank); |
320 | ret = jz_nand_ioremap_resource(pdev, res_name, | 323 | ret = jz_nand_ioremap_resource(pdev, res_name, |
@@ -351,8 +354,8 @@ static int jz_nand_detect_bank(struct platform_device *pdev, | |||
351 | } | 354 | } |
352 | 355 | ||
353 | /* Update size of the MTD. */ | 356 | /* Update size of the MTD. */ |
354 | chip->numchips++; | 357 | memorg->ntargets++; |
355 | mtd->size += chip->chipsize; | 358 | mtd->size += nanddev_target_size(&chip->base); |
356 | } | 359 | } |
357 | 360 | ||
358 | dev_info(&pdev->dev, "Found chip %zu on bank %i\n", chipnr, bank); | 361 | dev_info(&pdev->dev, "Found chip %zu on bank %i\n", chipnr, bank); |
diff --git a/drivers/mtd/nand/raw/jz4780_bch.c b/drivers/mtd/nand/raw/ingenic/jz4780_bch.c index c5f74ed85862..079266a0d6cf 100644 --- a/drivers/mtd/nand/raw/jz4780_bch.c +++ b/drivers/mtd/nand/raw/ingenic/jz4780_bch.c | |||
@@ -1,28 +1,22 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
1 | /* | 2 | /* |
2 | * JZ4780 BCH controller | 3 | * JZ4780 BCH controller driver |
3 | * | 4 | * |
4 | * Copyright (c) 2015 Imagination Technologies | 5 | * Copyright (c) 2015 Imagination Technologies |
5 | * Author: Alex Smith <alex.smith@imgtec.com> | 6 | * Author: Alex Smith <alex.smith@imgtec.com> |
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published | ||
9 | * by the Free Software Foundation. | ||
10 | */ | 7 | */ |
11 | 8 | ||
12 | #include <linux/bitops.h> | 9 | #include <linux/bitops.h> |
13 | #include <linux/clk.h> | 10 | #include <linux/clk.h> |
14 | #include <linux/delay.h> | 11 | #include <linux/device.h> |
15 | #include <linux/init.h> | 12 | #include <linux/io.h> |
16 | #include <linux/iopoll.h> | 13 | #include <linux/iopoll.h> |
17 | #include <linux/module.h> | 14 | #include <linux/module.h> |
18 | #include <linux/mutex.h> | 15 | #include <linux/mutex.h> |
19 | #include <linux/of.h> | ||
20 | #include <linux/of_platform.h> | 16 | #include <linux/of_platform.h> |
21 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
22 | #include <linux/sched.h> | ||
23 | #include <linux/slab.h> | ||
24 | 18 | ||
25 | #include "jz4780_bch.h" | 19 | #include "ingenic_ecc.h" |
26 | 20 | ||
27 | #define BCH_BHCR 0x0 | 21 | #define BCH_BHCR 0x0 |
28 | #define BCH_BHCCR 0x8 | 22 | #define BCH_BHCCR 0x8 |
@@ -65,15 +59,8 @@ | |||
65 | /* Timeout for BCH calculation/correction. */ | 59 | /* Timeout for BCH calculation/correction. */ |
66 | #define BCH_TIMEOUT_US 100000 | 60 | #define BCH_TIMEOUT_US 100000 |
67 | 61 | ||
68 | struct jz4780_bch { | 62 | static void jz4780_bch_reset(struct ingenic_ecc *bch, |
69 | struct device *dev; | 63 | struct ingenic_ecc_params *params, bool encode) |
70 | void __iomem *base; | ||
71 | struct clk *clk; | ||
72 | struct mutex lock; | ||
73 | }; | ||
74 | |||
75 | static void jz4780_bch_init(struct jz4780_bch *bch, | ||
76 | struct jz4780_bch_params *params, bool encode) | ||
77 | { | 64 | { |
78 | u32 reg; | 65 | u32 reg; |
79 | 66 | ||
@@ -93,13 +80,13 @@ static void jz4780_bch_init(struct jz4780_bch *bch, | |||
93 | writel(reg, bch->base + BCH_BHCR); | 80 | writel(reg, bch->base + BCH_BHCR); |
94 | } | 81 | } |
95 | 82 | ||
96 | static void jz4780_bch_disable(struct jz4780_bch *bch) | 83 | static void jz4780_bch_disable(struct ingenic_ecc *bch) |
97 | { | 84 | { |
98 | writel(readl(bch->base + BCH_BHINT), bch->base + BCH_BHINT); | 85 | writel(readl(bch->base + BCH_BHINT), bch->base + BCH_BHINT); |
99 | writel(BCH_BHCR_BCHE, bch->base + BCH_BHCCR); | 86 | writel(BCH_BHCR_BCHE, bch->base + BCH_BHCCR); |
100 | } | 87 | } |
101 | 88 | ||
102 | static void jz4780_bch_write_data(struct jz4780_bch *bch, const void *buf, | 89 | static void jz4780_bch_write_data(struct ingenic_ecc *bch, const void *buf, |
103 | size_t size) | 90 | size_t size) |
104 | { | 91 | { |
105 | size_t size32 = size / sizeof(u32); | 92 | size_t size32 = size / sizeof(u32); |
@@ -116,7 +103,7 @@ static void jz4780_bch_write_data(struct jz4780_bch *bch, const void *buf, | |||
116 | writeb(*src8++, bch->base + BCH_BHDR); | 103 | writeb(*src8++, bch->base + BCH_BHDR); |
117 | } | 104 | } |
118 | 105 | ||
119 | static void jz4780_bch_read_parity(struct jz4780_bch *bch, void *buf, | 106 | static void jz4780_bch_read_parity(struct ingenic_ecc *bch, void *buf, |
120 | size_t size) | 107 | size_t size) |
121 | { | 108 | { |
122 | size_t size32 = size / sizeof(u32); | 109 | size_t size32 = size / sizeof(u32); |
@@ -146,7 +133,7 @@ static void jz4780_bch_read_parity(struct jz4780_bch *bch, void *buf, | |||
146 | } | 133 | } |
147 | } | 134 | } |
148 | 135 | ||
149 | static bool jz4780_bch_wait_complete(struct jz4780_bch *bch, unsigned int irq, | 136 | static bool jz4780_bch_wait_complete(struct ingenic_ecc *bch, unsigned int irq, |
150 | u32 *status) | 137 | u32 *status) |
151 | { | 138 | { |
152 | u32 reg; | 139 | u32 reg; |
@@ -170,23 +157,15 @@ static bool jz4780_bch_wait_complete(struct jz4780_bch *bch, unsigned int irq, | |||
170 | return true; | 157 | return true; |
171 | } | 158 | } |
172 | 159 | ||
173 | /** | 160 | static int jz4780_calculate(struct ingenic_ecc *bch, |
174 | * jz4780_bch_calculate() - calculate ECC for a data buffer | 161 | struct ingenic_ecc_params *params, |
175 | * @bch: BCH device. | 162 | const u8 *buf, u8 *ecc_code) |
176 | * @params: BCH parameters. | ||
177 | * @buf: input buffer with raw data. | ||
178 | * @ecc_code: output buffer with ECC. | ||
179 | * | ||
180 | * Return: 0 on success, -ETIMEDOUT if timed out while waiting for BCH | ||
181 | * controller. | ||
182 | */ | ||
183 | int jz4780_bch_calculate(struct jz4780_bch *bch, struct jz4780_bch_params *params, | ||
184 | const u8 *buf, u8 *ecc_code) | ||
185 | { | 163 | { |
186 | int ret = 0; | 164 | int ret = 0; |
187 | 165 | ||
188 | mutex_lock(&bch->lock); | 166 | mutex_lock(&bch->lock); |
189 | jz4780_bch_init(bch, params, true); | 167 | |
168 | jz4780_bch_reset(bch, params, true); | ||
190 | jz4780_bch_write_data(bch, buf, params->size); | 169 | jz4780_bch_write_data(bch, buf, params->size); |
191 | 170 | ||
192 | if (jz4780_bch_wait_complete(bch, BCH_BHINT_ENCF, NULL)) { | 171 | if (jz4780_bch_wait_complete(bch, BCH_BHINT_ENCF, NULL)) { |
@@ -200,30 +179,17 @@ int jz4780_bch_calculate(struct jz4780_bch *bch, struct jz4780_bch_params *param | |||
200 | mutex_unlock(&bch->lock); | 179 | mutex_unlock(&bch->lock); |
201 | return ret; | 180 | return ret; |
202 | } | 181 | } |
203 | EXPORT_SYMBOL(jz4780_bch_calculate); | 182 | |
204 | 183 | static int jz4780_correct(struct ingenic_ecc *bch, | |
205 | /** | 184 | struct ingenic_ecc_params *params, |
206 | * jz4780_bch_correct() - detect and correct bit errors | 185 | u8 *buf, u8 *ecc_code) |
207 | * @bch: BCH device. | ||
208 | * @params: BCH parameters. | ||
209 | * @buf: raw data read from the chip. | ||
210 | * @ecc_code: ECC read from the chip. | ||
211 | * | ||
212 | * Given the raw data and the ECC read from the NAND device, detects and | ||
213 | * corrects errors in the data. | ||
214 | * | ||
215 | * Return: the number of bit errors corrected, -EBADMSG if there are too many | ||
216 | * errors to correct or -ETIMEDOUT if we timed out waiting for the controller. | ||
217 | */ | ||
218 | int jz4780_bch_correct(struct jz4780_bch *bch, struct jz4780_bch_params *params, | ||
219 | u8 *buf, u8 *ecc_code) | ||
220 | { | 186 | { |
221 | u32 reg, mask, index; | 187 | u32 reg, mask, index; |
222 | int i, ret, count; | 188 | int i, ret, count; |
223 | 189 | ||
224 | mutex_lock(&bch->lock); | 190 | mutex_lock(&bch->lock); |
225 | 191 | ||
226 | jz4780_bch_init(bch, params, false); | 192 | jz4780_bch_reset(bch, params, false); |
227 | jz4780_bch_write_data(bch, buf, params->size); | 193 | jz4780_bch_write_data(bch, buf, params->size); |
228 | jz4780_bch_write_data(bch, ecc_code, params->bytes); | 194 | jz4780_bch_write_data(bch, ecc_code, params->bytes); |
229 | 195 | ||
@@ -262,110 +228,30 @@ out: | |||
262 | mutex_unlock(&bch->lock); | 228 | mutex_unlock(&bch->lock); |
263 | return ret; | 229 | return ret; |
264 | } | 230 | } |
265 | EXPORT_SYMBOL(jz4780_bch_correct); | ||
266 | |||
267 | /** | ||
268 | * jz4780_bch_get() - get the BCH controller device | ||
269 | * @np: BCH device tree node. | ||
270 | * | ||
271 | * Gets the BCH controller device from the specified device tree node. The | ||
272 | * device must be released with jz4780_bch_release() when it is no longer being | ||
273 | * used. | ||
274 | * | ||
275 | * Return: a pointer to jz4780_bch, errors are encoded into the pointer. | ||
276 | * PTR_ERR(-EPROBE_DEFER) if the device hasn't been initialised yet. | ||
277 | */ | ||
278 | static struct jz4780_bch *jz4780_bch_get(struct device_node *np) | ||
279 | { | ||
280 | struct platform_device *pdev; | ||
281 | struct jz4780_bch *bch; | ||
282 | |||
283 | pdev = of_find_device_by_node(np); | ||
284 | if (!pdev) | ||
285 | return ERR_PTR(-EPROBE_DEFER); | ||
286 | |||
287 | bch = platform_get_drvdata(pdev); | ||
288 | if (!bch) { | ||
289 | put_device(&pdev->dev); | ||
290 | return ERR_PTR(-EPROBE_DEFER); | ||
291 | } | ||
292 | |||
293 | clk_prepare_enable(bch->clk); | ||
294 | |||
295 | return bch; | ||
296 | } | ||
297 | |||
298 | /** | ||
299 | * of_jz4780_bch_get() - get the BCH controller from a DT node | ||
300 | * @of_node: the node that contains a bch-controller property. | ||
301 | * | ||
302 | * Get the bch-controller property from the given device tree | ||
303 | * node and pass it to jz4780_bch_get to do the work. | ||
304 | * | ||
305 | * Return: a pointer to jz4780_bch, errors are encoded into the pointer. | ||
306 | * PTR_ERR(-EPROBE_DEFER) if the device hasn't been initialised yet. | ||
307 | */ | ||
308 | struct jz4780_bch *of_jz4780_bch_get(struct device_node *of_node) | ||
309 | { | ||
310 | struct jz4780_bch *bch = NULL; | ||
311 | struct device_node *np; | ||
312 | |||
313 | np = of_parse_phandle(of_node, "ingenic,bch-controller", 0); | ||
314 | |||
315 | if (np) { | ||
316 | bch = jz4780_bch_get(np); | ||
317 | of_node_put(np); | ||
318 | } | ||
319 | return bch; | ||
320 | } | ||
321 | EXPORT_SYMBOL(of_jz4780_bch_get); | ||
322 | |||
323 | /** | ||
324 | * jz4780_bch_release() - release the BCH controller device | ||
325 | * @bch: BCH device. | ||
326 | */ | ||
327 | void jz4780_bch_release(struct jz4780_bch *bch) | ||
328 | { | ||
329 | clk_disable_unprepare(bch->clk); | ||
330 | put_device(bch->dev); | ||
331 | } | ||
332 | EXPORT_SYMBOL(jz4780_bch_release); | ||
333 | 231 | ||
334 | static int jz4780_bch_probe(struct platform_device *pdev) | 232 | static int jz4780_bch_probe(struct platform_device *pdev) |
335 | { | 233 | { |
336 | struct device *dev = &pdev->dev; | 234 | struct ingenic_ecc *bch; |
337 | struct jz4780_bch *bch; | 235 | int ret; |
338 | struct resource *res; | ||
339 | |||
340 | bch = devm_kzalloc(dev, sizeof(*bch), GFP_KERNEL); | ||
341 | if (!bch) | ||
342 | return -ENOMEM; | ||
343 | |||
344 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
345 | bch->base = devm_ioremap_resource(dev, res); | ||
346 | if (IS_ERR(bch->base)) | ||
347 | return PTR_ERR(bch->base); | ||
348 | |||
349 | jz4780_bch_disable(bch); | ||
350 | 236 | ||
351 | bch->clk = devm_clk_get(dev, NULL); | 237 | ret = ingenic_ecc_probe(pdev); |
352 | if (IS_ERR(bch->clk)) { | 238 | if (ret) |
353 | dev_err(dev, "failed to get clock: %ld\n", PTR_ERR(bch->clk)); | 239 | return ret; |
354 | return PTR_ERR(bch->clk); | ||
355 | } | ||
356 | 240 | ||
241 | bch = platform_get_drvdata(pdev); | ||
357 | clk_set_rate(bch->clk, BCH_CLK_RATE); | 242 | clk_set_rate(bch->clk, BCH_CLK_RATE); |
358 | 243 | ||
359 | mutex_init(&bch->lock); | ||
360 | |||
361 | bch->dev = dev; | ||
362 | platform_set_drvdata(pdev, bch); | ||
363 | |||
364 | return 0; | 244 | return 0; |
365 | } | 245 | } |
366 | 246 | ||
247 | static const struct ingenic_ecc_ops jz4780_bch_ops = { | ||
248 | .disable = jz4780_bch_disable, | ||
249 | .calculate = jz4780_calculate, | ||
250 | .correct = jz4780_correct, | ||
251 | }; | ||
252 | |||
367 | static const struct of_device_id jz4780_bch_dt_match[] = { | 253 | static const struct of_device_id jz4780_bch_dt_match[] = { |
368 | { .compatible = "ingenic,jz4780-bch" }, | 254 | { .compatible = "ingenic,jz4780-bch", .data = &jz4780_bch_ops }, |
369 | {}, | 255 | {}, |
370 | }; | 256 | }; |
371 | MODULE_DEVICE_TABLE(of, jz4780_bch_dt_match); | 257 | MODULE_DEVICE_TABLE(of, jz4780_bch_dt_match); |
diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h index fbf6ca015cd7..cba6fe7dd8c4 100644 --- a/drivers/mtd/nand/raw/internals.h +++ b/drivers/mtd/nand/raw/internals.h | |||
@@ -76,6 +76,7 @@ extern const struct nand_manufacturer_ops toshiba_nand_manuf_ops; | |||
76 | 76 | ||
77 | /* Core functions */ | 77 | /* Core functions */ |
78 | const struct nand_manufacturer *nand_get_manufacturer(u8 id); | 78 | const struct nand_manufacturer *nand_get_manufacturer(u8 id); |
79 | int nand_bbm_get_next_page(struct nand_chip *chip, int page); | ||
79 | int nand_markbad_bbm(struct nand_chip *chip, loff_t ofs); | 80 | int nand_markbad_bbm(struct nand_chip *chip, loff_t ofs); |
80 | int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr, | 81 | int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr, |
81 | int allowbbt); | 82 | int allowbbt); |
@@ -110,7 +111,7 @@ static inline int nand_exec_op(struct nand_chip *chip, | |||
110 | if (!nand_has_exec_op(chip)) | 111 | if (!nand_has_exec_op(chip)) |
111 | return -ENOTSUPP; | 112 | return -ENOTSUPP; |
112 | 113 | ||
113 | if (WARN_ON(op->cs >= chip->numchips)) | 114 | if (WARN_ON(op->cs >= nanddev_ntargets(&chip->base))) |
114 | return -EINVAL; | 115 | return -EINVAL; |
115 | 116 | ||
116 | return chip->controller->ops->exec_op(chip, op, false); | 117 | return chip->controller->ops->exec_op(chip, op, false); |
diff --git a/drivers/mtd/nand/raw/jz4780_bch.h b/drivers/mtd/nand/raw/jz4780_bch.h deleted file mode 100644 index bf4718088a3a..000000000000 --- a/drivers/mtd/nand/raw/jz4780_bch.h +++ /dev/null | |||
@@ -1,43 +0,0 @@ | |||
1 | /* | ||
2 | * JZ4780 BCH controller | ||
3 | * | ||
4 | * Copyright (c) 2015 Imagination Technologies | ||
5 | * Author: Alex Smith <alex.smith@imgtec.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published | ||
9 | * by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #ifndef __DRIVERS_MTD_NAND_JZ4780_BCH_H__ | ||
13 | #define __DRIVERS_MTD_NAND_JZ4780_BCH_H__ | ||
14 | |||
15 | #include <linux/types.h> | ||
16 | |||
17 | struct device; | ||
18 | struct device_node; | ||
19 | struct jz4780_bch; | ||
20 | |||
21 | /** | ||
22 | * struct jz4780_bch_params - BCH parameters | ||
23 | * @size: data bytes per ECC step. | ||
24 | * @bytes: ECC bytes per step. | ||
25 | * @strength: number of correctable bits per ECC step. | ||
26 | */ | ||
27 | struct jz4780_bch_params { | ||
28 | int size; | ||
29 | int bytes; | ||
30 | int strength; | ||
31 | }; | ||
32 | |||
33 | int jz4780_bch_calculate(struct jz4780_bch *bch, | ||
34 | struct jz4780_bch_params *params, | ||
35 | const u8 *buf, u8 *ecc_code); | ||
36 | int jz4780_bch_correct(struct jz4780_bch *bch, | ||
37 | struct jz4780_bch_params *params, u8 *buf, | ||
38 | u8 *ecc_code); | ||
39 | |||
40 | void jz4780_bch_release(struct jz4780_bch *bch); | ||
41 | struct jz4780_bch *of_jz4780_bch_get(struct device_node *np); | ||
42 | |||
43 | #endif /* __DRIVERS_MTD_NAND_JZ4780_BCH_H__ */ | ||
diff --git a/drivers/mtd/nand/raw/jz4780_nand.c b/drivers/mtd/nand/raw/jz4780_nand.c deleted file mode 100644 index 22e58975f0d5..000000000000 --- a/drivers/mtd/nand/raw/jz4780_nand.c +++ /dev/null | |||
@@ -1,415 +0,0 @@ | |||
1 | /* | ||
2 | * JZ4780 NAND driver | ||
3 | * | ||
4 | * Copyright (c) 2015 Imagination Technologies | ||
5 | * Author: Alex Smith <alex.smith@imgtec.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published | ||
9 | * by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/delay.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/list.h> | ||
16 | #include <linux/module.h> | ||
17 | #include <linux/of.h> | ||
18 | #include <linux/of_address.h> | ||
19 | #include <linux/gpio/consumer.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/mtd/mtd.h> | ||
23 | #include <linux/mtd/rawnand.h> | ||
24 | #include <linux/mtd/partitions.h> | ||
25 | |||
26 | #include <linux/jz4780-nemc.h> | ||
27 | |||
28 | #include "jz4780_bch.h" | ||
29 | |||
30 | #define DRV_NAME "jz4780-nand" | ||
31 | |||
32 | #define OFFSET_DATA 0x00000000 | ||
33 | #define OFFSET_CMD 0x00400000 | ||
34 | #define OFFSET_ADDR 0x00800000 | ||
35 | |||
36 | /* Command delay when there is no R/B pin. */ | ||
37 | #define RB_DELAY_US 100 | ||
38 | |||
39 | struct jz4780_nand_cs { | ||
40 | unsigned int bank; | ||
41 | void __iomem *base; | ||
42 | }; | ||
43 | |||
44 | struct jz4780_nand_controller { | ||
45 | struct device *dev; | ||
46 | struct jz4780_bch *bch; | ||
47 | struct nand_controller controller; | ||
48 | unsigned int num_banks; | ||
49 | struct list_head chips; | ||
50 | int selected; | ||
51 | struct jz4780_nand_cs cs[]; | ||
52 | }; | ||
53 | |||
54 | struct jz4780_nand_chip { | ||
55 | struct nand_chip chip; | ||
56 | struct list_head chip_list; | ||
57 | |||
58 | struct gpio_desc *busy_gpio; | ||
59 | struct gpio_desc *wp_gpio; | ||
60 | unsigned int reading: 1; | ||
61 | }; | ||
62 | |||
63 | static inline struct jz4780_nand_chip *to_jz4780_nand_chip(struct mtd_info *mtd) | ||
64 | { | ||
65 | return container_of(mtd_to_nand(mtd), struct jz4780_nand_chip, chip); | ||
66 | } | ||
67 | |||
68 | static inline struct jz4780_nand_controller | ||
69 | *to_jz4780_nand_controller(struct nand_controller *ctrl) | ||
70 | { | ||
71 | return container_of(ctrl, struct jz4780_nand_controller, controller); | ||
72 | } | ||
73 | |||
74 | static void jz4780_nand_select_chip(struct nand_chip *chip, int chipnr) | ||
75 | { | ||
76 | struct jz4780_nand_chip *nand = to_jz4780_nand_chip(nand_to_mtd(chip)); | ||
77 | struct jz4780_nand_controller *nfc = to_jz4780_nand_controller(nand->chip.controller); | ||
78 | struct jz4780_nand_cs *cs; | ||
79 | |||
80 | /* Ensure the currently selected chip is deasserted. */ | ||
81 | if (chipnr == -1 && nfc->selected >= 0) { | ||
82 | cs = &nfc->cs[nfc->selected]; | ||
83 | jz4780_nemc_assert(nfc->dev, cs->bank, false); | ||
84 | } | ||
85 | |||
86 | nfc->selected = chipnr; | ||
87 | } | ||
88 | |||
89 | static void jz4780_nand_cmd_ctrl(struct nand_chip *chip, int cmd, | ||
90 | unsigned int ctrl) | ||
91 | { | ||
92 | struct jz4780_nand_chip *nand = to_jz4780_nand_chip(nand_to_mtd(chip)); | ||
93 | struct jz4780_nand_controller *nfc = to_jz4780_nand_controller(nand->chip.controller); | ||
94 | struct jz4780_nand_cs *cs; | ||
95 | |||
96 | if (WARN_ON(nfc->selected < 0)) | ||
97 | return; | ||
98 | |||
99 | cs = &nfc->cs[nfc->selected]; | ||
100 | |||
101 | jz4780_nemc_assert(nfc->dev, cs->bank, ctrl & NAND_NCE); | ||
102 | |||
103 | if (cmd == NAND_CMD_NONE) | ||
104 | return; | ||
105 | |||
106 | if (ctrl & NAND_ALE) | ||
107 | writeb(cmd, cs->base + OFFSET_ADDR); | ||
108 | else if (ctrl & NAND_CLE) | ||
109 | writeb(cmd, cs->base + OFFSET_CMD); | ||
110 | } | ||
111 | |||
112 | static int jz4780_nand_dev_ready(struct nand_chip *chip) | ||
113 | { | ||
114 | struct jz4780_nand_chip *nand = to_jz4780_nand_chip(nand_to_mtd(chip)); | ||
115 | |||
116 | return !gpiod_get_value_cansleep(nand->busy_gpio); | ||
117 | } | ||
118 | |||
119 | static void jz4780_nand_ecc_hwctl(struct nand_chip *chip, int mode) | ||
120 | { | ||
121 | struct jz4780_nand_chip *nand = to_jz4780_nand_chip(nand_to_mtd(chip)); | ||
122 | |||
123 | nand->reading = (mode == NAND_ECC_READ); | ||
124 | } | ||
125 | |||
126 | static int jz4780_nand_ecc_calculate(struct nand_chip *chip, const u8 *dat, | ||
127 | u8 *ecc_code) | ||
128 | { | ||
129 | struct jz4780_nand_chip *nand = to_jz4780_nand_chip(nand_to_mtd(chip)); | ||
130 | struct jz4780_nand_controller *nfc = to_jz4780_nand_controller(nand->chip.controller); | ||
131 | struct jz4780_bch_params params; | ||
132 | |||
133 | /* | ||
134 | * Don't need to generate the ECC when reading, BCH does it for us as | ||
135 | * part of decoding/correction. | ||
136 | */ | ||
137 | if (nand->reading) | ||
138 | return 0; | ||
139 | |||
140 | params.size = nand->chip.ecc.size; | ||
141 | params.bytes = nand->chip.ecc.bytes; | ||
142 | params.strength = nand->chip.ecc.strength; | ||
143 | |||
144 | return jz4780_bch_calculate(nfc->bch, ¶ms, dat, ecc_code); | ||
145 | } | ||
146 | |||
147 | static int jz4780_nand_ecc_correct(struct nand_chip *chip, u8 *dat, | ||
148 | u8 *read_ecc, u8 *calc_ecc) | ||
149 | { | ||
150 | struct jz4780_nand_chip *nand = to_jz4780_nand_chip(nand_to_mtd(chip)); | ||
151 | struct jz4780_nand_controller *nfc = to_jz4780_nand_controller(nand->chip.controller); | ||
152 | struct jz4780_bch_params params; | ||
153 | |||
154 | params.size = nand->chip.ecc.size; | ||
155 | params.bytes = nand->chip.ecc.bytes; | ||
156 | params.strength = nand->chip.ecc.strength; | ||
157 | |||
158 | return jz4780_bch_correct(nfc->bch, ¶ms, dat, read_ecc); | ||
159 | } | ||
160 | |||
161 | static int jz4780_nand_attach_chip(struct nand_chip *chip) | ||
162 | { | ||
163 | struct mtd_info *mtd = nand_to_mtd(chip); | ||
164 | struct jz4780_nand_controller *nfc = to_jz4780_nand_controller(chip->controller); | ||
165 | int eccbytes; | ||
166 | |||
167 | chip->ecc.bytes = fls((1 + 8) * chip->ecc.size) * | ||
168 | (chip->ecc.strength / 8); | ||
169 | |||
170 | switch (chip->ecc.mode) { | ||
171 | case NAND_ECC_HW: | ||
172 | if (!nfc->bch) { | ||
173 | dev_err(nfc->dev, | ||
174 | "HW BCH selected, but BCH controller not found\n"); | ||
175 | return -ENODEV; | ||
176 | } | ||
177 | |||
178 | chip->ecc.hwctl = jz4780_nand_ecc_hwctl; | ||
179 | chip->ecc.calculate = jz4780_nand_ecc_calculate; | ||
180 | chip->ecc.correct = jz4780_nand_ecc_correct; | ||
181 | /* fall through */ | ||
182 | case NAND_ECC_SOFT: | ||
183 | dev_info(nfc->dev, "using %s (strength %d, size %d, bytes %d)\n", | ||
184 | (nfc->bch) ? "hardware BCH" : "software ECC", | ||
185 | chip->ecc.strength, chip->ecc.size, chip->ecc.bytes); | ||
186 | break; | ||
187 | case NAND_ECC_NONE: | ||
188 | dev_info(nfc->dev, "not using ECC\n"); | ||
189 | break; | ||
190 | default: | ||
191 | dev_err(nfc->dev, "ECC mode %d not supported\n", | ||
192 | chip->ecc.mode); | ||
193 | return -EINVAL; | ||
194 | } | ||
195 | |||
196 | /* The NAND core will generate the ECC layout for SW ECC */ | ||
197 | if (chip->ecc.mode != NAND_ECC_HW) | ||
198 | return 0; | ||
199 | |||
200 | /* Generate ECC layout. ECC codes are right aligned in the OOB area. */ | ||
201 | eccbytes = mtd->writesize / chip->ecc.size * chip->ecc.bytes; | ||
202 | |||
203 | if (eccbytes > mtd->oobsize - 2) { | ||
204 | dev_err(nfc->dev, | ||
205 | "invalid ECC config: required %d ECC bytes, but only %d are available", | ||
206 | eccbytes, mtd->oobsize - 2); | ||
207 | return -EINVAL; | ||
208 | } | ||
209 | |||
210 | mtd_set_ooblayout(mtd, &nand_ooblayout_lp_ops); | ||
211 | |||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | static const struct nand_controller_ops jz4780_nand_controller_ops = { | ||
216 | .attach_chip = jz4780_nand_attach_chip, | ||
217 | }; | ||
218 | |||
219 | static int jz4780_nand_init_chip(struct platform_device *pdev, | ||
220 | struct jz4780_nand_controller *nfc, | ||
221 | struct device_node *np, | ||
222 | unsigned int chipnr) | ||
223 | { | ||
224 | struct device *dev = &pdev->dev; | ||
225 | struct jz4780_nand_chip *nand; | ||
226 | struct jz4780_nand_cs *cs; | ||
227 | struct resource *res; | ||
228 | struct nand_chip *chip; | ||
229 | struct mtd_info *mtd; | ||
230 | const __be32 *reg; | ||
231 | int ret = 0; | ||
232 | |||
233 | cs = &nfc->cs[chipnr]; | ||
234 | |||
235 | reg = of_get_property(np, "reg", NULL); | ||
236 | if (!reg) | ||
237 | return -EINVAL; | ||
238 | |||
239 | cs->bank = be32_to_cpu(*reg); | ||
240 | |||
241 | jz4780_nemc_set_type(nfc->dev, cs->bank, JZ4780_NEMC_BANK_NAND); | ||
242 | |||
243 | res = platform_get_resource(pdev, IORESOURCE_MEM, chipnr); | ||
244 | cs->base = devm_ioremap_resource(dev, res); | ||
245 | if (IS_ERR(cs->base)) | ||
246 | return PTR_ERR(cs->base); | ||
247 | |||
248 | nand = devm_kzalloc(dev, sizeof(*nand), GFP_KERNEL); | ||
249 | if (!nand) | ||
250 | return -ENOMEM; | ||
251 | |||
252 | nand->busy_gpio = devm_gpiod_get_optional(dev, "rb", GPIOD_IN); | ||
253 | |||
254 | if (IS_ERR(nand->busy_gpio)) { | ||
255 | ret = PTR_ERR(nand->busy_gpio); | ||
256 | dev_err(dev, "failed to request busy GPIO: %d\n", ret); | ||
257 | return ret; | ||
258 | } else if (nand->busy_gpio) { | ||
259 | nand->chip.legacy.dev_ready = jz4780_nand_dev_ready; | ||
260 | } | ||
261 | |||
262 | nand->wp_gpio = devm_gpiod_get_optional(dev, "wp", GPIOD_OUT_LOW); | ||
263 | |||
264 | if (IS_ERR(nand->wp_gpio)) { | ||
265 | ret = PTR_ERR(nand->wp_gpio); | ||
266 | dev_err(dev, "failed to request WP GPIO: %d\n", ret); | ||
267 | return ret; | ||
268 | } | ||
269 | |||
270 | chip = &nand->chip; | ||
271 | mtd = nand_to_mtd(chip); | ||
272 | mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%s.%d", dev_name(dev), | ||
273 | cs->bank); | ||
274 | if (!mtd->name) | ||
275 | return -ENOMEM; | ||
276 | mtd->dev.parent = dev; | ||
277 | |||
278 | chip->legacy.IO_ADDR_R = cs->base + OFFSET_DATA; | ||
279 | chip->legacy.IO_ADDR_W = cs->base + OFFSET_DATA; | ||
280 | chip->legacy.chip_delay = RB_DELAY_US; | ||
281 | chip->options = NAND_NO_SUBPAGE_WRITE; | ||
282 | chip->legacy.select_chip = jz4780_nand_select_chip; | ||
283 | chip->legacy.cmd_ctrl = jz4780_nand_cmd_ctrl; | ||
284 | chip->ecc.mode = NAND_ECC_HW; | ||
285 | chip->controller = &nfc->controller; | ||
286 | nand_set_flash_node(chip, np); | ||
287 | |||
288 | chip->controller->ops = &jz4780_nand_controller_ops; | ||
289 | ret = nand_scan(chip, 1); | ||
290 | if (ret) | ||
291 | return ret; | ||
292 | |||
293 | ret = mtd_device_register(mtd, NULL, 0); | ||
294 | if (ret) { | ||
295 | nand_release(chip); | ||
296 | return ret; | ||
297 | } | ||
298 | |||
299 | list_add_tail(&nand->chip_list, &nfc->chips); | ||
300 | |||
301 | return 0; | ||
302 | } | ||
303 | |||
304 | static void jz4780_nand_cleanup_chips(struct jz4780_nand_controller *nfc) | ||
305 | { | ||
306 | struct jz4780_nand_chip *chip; | ||
307 | |||
308 | while (!list_empty(&nfc->chips)) { | ||
309 | chip = list_first_entry(&nfc->chips, struct jz4780_nand_chip, chip_list); | ||
310 | nand_release(&chip->chip); | ||
311 | list_del(&chip->chip_list); | ||
312 | } | ||
313 | } | ||
314 | |||
315 | static int jz4780_nand_init_chips(struct jz4780_nand_controller *nfc, | ||
316 | struct platform_device *pdev) | ||
317 | { | ||
318 | struct device *dev = &pdev->dev; | ||
319 | struct device_node *np; | ||
320 | int i = 0; | ||
321 | int ret; | ||
322 | int num_chips = of_get_child_count(dev->of_node); | ||
323 | |||
324 | if (num_chips > nfc->num_banks) { | ||
325 | dev_err(dev, "found %d chips but only %d banks\n", num_chips, nfc->num_banks); | ||
326 | return -EINVAL; | ||
327 | } | ||
328 | |||
329 | for_each_child_of_node(dev->of_node, np) { | ||
330 | ret = jz4780_nand_init_chip(pdev, nfc, np, i); | ||
331 | if (ret) { | ||
332 | jz4780_nand_cleanup_chips(nfc); | ||
333 | return ret; | ||
334 | } | ||
335 | |||
336 | i++; | ||
337 | } | ||
338 | |||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | static int jz4780_nand_probe(struct platform_device *pdev) | ||
343 | { | ||
344 | struct device *dev = &pdev->dev; | ||
345 | unsigned int num_banks; | ||
346 | struct jz4780_nand_controller *nfc; | ||
347 | int ret; | ||
348 | |||
349 | num_banks = jz4780_nemc_num_banks(dev); | ||
350 | if (num_banks == 0) { | ||
351 | dev_err(dev, "no banks found\n"); | ||
352 | return -ENODEV; | ||
353 | } | ||
354 | |||
355 | nfc = devm_kzalloc(dev, struct_size(nfc, cs, num_banks), GFP_KERNEL); | ||
356 | if (!nfc) | ||
357 | return -ENOMEM; | ||
358 | |||
359 | /* | ||
360 | * Check for BCH HW before we call nand_scan_ident, to prevent us from | ||
361 | * having to call it again if the BCH driver returns -EPROBE_DEFER. | ||
362 | */ | ||
363 | nfc->bch = of_jz4780_bch_get(dev->of_node); | ||
364 | if (IS_ERR(nfc->bch)) | ||
365 | return PTR_ERR(nfc->bch); | ||
366 | |||
367 | nfc->dev = dev; | ||
368 | nfc->num_banks = num_banks; | ||
369 | |||
370 | nand_controller_init(&nfc->controller); | ||
371 | INIT_LIST_HEAD(&nfc->chips); | ||
372 | |||
373 | ret = jz4780_nand_init_chips(nfc, pdev); | ||
374 | if (ret) { | ||
375 | if (nfc->bch) | ||
376 | jz4780_bch_release(nfc->bch); | ||
377 | return ret; | ||
378 | } | ||
379 | |||
380 | platform_set_drvdata(pdev, nfc); | ||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | static int jz4780_nand_remove(struct platform_device *pdev) | ||
385 | { | ||
386 | struct jz4780_nand_controller *nfc = platform_get_drvdata(pdev); | ||
387 | |||
388 | if (nfc->bch) | ||
389 | jz4780_bch_release(nfc->bch); | ||
390 | |||
391 | jz4780_nand_cleanup_chips(nfc); | ||
392 | |||
393 | return 0; | ||
394 | } | ||
395 | |||
396 | static const struct of_device_id jz4780_nand_dt_match[] = { | ||
397 | { .compatible = "ingenic,jz4780-nand" }, | ||
398 | {}, | ||
399 | }; | ||
400 | MODULE_DEVICE_TABLE(of, jz4780_nand_dt_match); | ||
401 | |||
402 | static struct platform_driver jz4780_nand_driver = { | ||
403 | .probe = jz4780_nand_probe, | ||
404 | .remove = jz4780_nand_remove, | ||
405 | .driver = { | ||
406 | .name = DRV_NAME, | ||
407 | .of_match_table = of_match_ptr(jz4780_nand_dt_match), | ||
408 | }, | ||
409 | }; | ||
410 | module_platform_driver(jz4780_nand_driver); | ||
411 | |||
412 | MODULE_AUTHOR("Alex Smith <alex@alex-smith.me.uk>"); | ||
413 | MODULE_AUTHOR("Harvey Hunt <harveyhuntnexus@gmail.com>"); | ||
414 | MODULE_DESCRIPTION("Ingenic JZ4780 NAND driver"); | ||
415 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mtd/nand/raw/marvell_nand.c b/drivers/mtd/nand/raw/marvell_nand.c index d984538980e2..fc49e13d81ec 100644 --- a/drivers/mtd/nand/raw/marvell_nand.c +++ b/drivers/mtd/nand/raw/marvell_nand.c | |||
@@ -1083,12 +1083,11 @@ static int marvell_nfc_hw_ecc_hmg_read_page(struct nand_chip *chip, u8 *buf, | |||
1083 | */ | 1083 | */ |
1084 | static int marvell_nfc_hw_ecc_hmg_read_oob_raw(struct nand_chip *chip, int page) | 1084 | static int marvell_nfc_hw_ecc_hmg_read_oob_raw(struct nand_chip *chip, int page) |
1085 | { | 1085 | { |
1086 | /* Invalidate page cache */ | 1086 | u8 *buf = nand_get_data_buf(chip); |
1087 | chip->pagebuf = -1; | ||
1088 | 1087 | ||
1089 | marvell_nfc_select_target(chip, chip->cur_cs); | 1088 | marvell_nfc_select_target(chip, chip->cur_cs); |
1090 | return marvell_nfc_hw_ecc_hmg_do_read_page(chip, chip->data_buf, | 1089 | return marvell_nfc_hw_ecc_hmg_do_read_page(chip, buf, chip->oob_poi, |
1091 | chip->oob_poi, true, page); | 1090 | true, page); |
1092 | } | 1091 | } |
1093 | 1092 | ||
1094 | /* Hamming write helpers */ | 1093 | /* Hamming write helpers */ |
@@ -1179,15 +1178,13 @@ static int marvell_nfc_hw_ecc_hmg_write_oob_raw(struct nand_chip *chip, | |||
1179 | int page) | 1178 | int page) |
1180 | { | 1179 | { |
1181 | struct mtd_info *mtd = nand_to_mtd(chip); | 1180 | struct mtd_info *mtd = nand_to_mtd(chip); |
1181 | u8 *buf = nand_get_data_buf(chip); | ||
1182 | 1182 | ||
1183 | /* Invalidate page cache */ | 1183 | memset(buf, 0xFF, mtd->writesize); |
1184 | chip->pagebuf = -1; | ||
1185 | |||
1186 | memset(chip->data_buf, 0xFF, mtd->writesize); | ||
1187 | 1184 | ||
1188 | marvell_nfc_select_target(chip, chip->cur_cs); | 1185 | marvell_nfc_select_target(chip, chip->cur_cs); |
1189 | return marvell_nfc_hw_ecc_hmg_do_write_page(chip, chip->data_buf, | 1186 | return marvell_nfc_hw_ecc_hmg_do_write_page(chip, buf, chip->oob_poi, |
1190 | chip->oob_poi, true, page); | 1187 | true, page); |
1191 | } | 1188 | } |
1192 | 1189 | ||
1193 | /* BCH read helpers */ | 1190 | /* BCH read helpers */ |
@@ -1434,18 +1431,16 @@ static int marvell_nfc_hw_ecc_bch_read_page(struct nand_chip *chip, | |||
1434 | 1431 | ||
1435 | static int marvell_nfc_hw_ecc_bch_read_oob_raw(struct nand_chip *chip, int page) | 1432 | static int marvell_nfc_hw_ecc_bch_read_oob_raw(struct nand_chip *chip, int page) |
1436 | { | 1433 | { |
1437 | /* Invalidate page cache */ | 1434 | u8 *buf = nand_get_data_buf(chip); |
1438 | chip->pagebuf = -1; | ||
1439 | 1435 | ||
1440 | return chip->ecc.read_page_raw(chip, chip->data_buf, true, page); | 1436 | return chip->ecc.read_page_raw(chip, buf, true, page); |
1441 | } | 1437 | } |
1442 | 1438 | ||
1443 | static int marvell_nfc_hw_ecc_bch_read_oob(struct nand_chip *chip, int page) | 1439 | static int marvell_nfc_hw_ecc_bch_read_oob(struct nand_chip *chip, int page) |
1444 | { | 1440 | { |
1445 | /* Invalidate page cache */ | 1441 | u8 *buf = nand_get_data_buf(chip); |
1446 | chip->pagebuf = -1; | ||
1447 | 1442 | ||
1448 | return chip->ecc.read_page(chip, chip->data_buf, true, page); | 1443 | return chip->ecc.read_page(chip, buf, true, page); |
1449 | } | 1444 | } |
1450 | 1445 | ||
1451 | /* BCH write helpers */ | 1446 | /* BCH write helpers */ |
@@ -1619,25 +1614,21 @@ static int marvell_nfc_hw_ecc_bch_write_oob_raw(struct nand_chip *chip, | |||
1619 | int page) | 1614 | int page) |
1620 | { | 1615 | { |
1621 | struct mtd_info *mtd = nand_to_mtd(chip); | 1616 | struct mtd_info *mtd = nand_to_mtd(chip); |
1617 | u8 *buf = nand_get_data_buf(chip); | ||
1622 | 1618 | ||
1623 | /* Invalidate page cache */ | 1619 | memset(buf, 0xFF, mtd->writesize); |
1624 | chip->pagebuf = -1; | ||
1625 | |||
1626 | memset(chip->data_buf, 0xFF, mtd->writesize); | ||
1627 | 1620 | ||
1628 | return chip->ecc.write_page_raw(chip, chip->data_buf, true, page); | 1621 | return chip->ecc.write_page_raw(chip, buf, true, page); |
1629 | } | 1622 | } |
1630 | 1623 | ||
1631 | static int marvell_nfc_hw_ecc_bch_write_oob(struct nand_chip *chip, int page) | 1624 | static int marvell_nfc_hw_ecc_bch_write_oob(struct nand_chip *chip, int page) |
1632 | { | 1625 | { |
1633 | struct mtd_info *mtd = nand_to_mtd(chip); | 1626 | struct mtd_info *mtd = nand_to_mtd(chip); |
1627 | u8 *buf = nand_get_data_buf(chip); | ||
1634 | 1628 | ||
1635 | /* Invalidate page cache */ | 1629 | memset(buf, 0xFF, mtd->writesize); |
1636 | chip->pagebuf = -1; | ||
1637 | |||
1638 | memset(chip->data_buf, 0xFF, mtd->writesize); | ||
1639 | 1630 | ||
1640 | return chip->ecc.write_page(chip, chip->data_buf, true, page); | 1631 | return chip->ecc.write_page(chip, buf, true, page); |
1641 | } | 1632 | } |
1642 | 1633 | ||
1643 | /* NAND framework ->exec_op() hooks and related helpers */ | 1634 | /* NAND framework ->exec_op() hooks and related helpers */ |
@@ -2257,9 +2248,9 @@ static int marvell_nand_ecc_init(struct mtd_info *mtd, | |||
2257 | int ret; | 2248 | int ret; |
2258 | 2249 | ||
2259 | if (ecc->mode != NAND_ECC_NONE && (!ecc->size || !ecc->strength)) { | 2250 | if (ecc->mode != NAND_ECC_NONE && (!ecc->size || !ecc->strength)) { |
2260 | if (chip->ecc_step_ds && chip->ecc_strength_ds) { | 2251 | if (chip->base.eccreq.step_size && chip->base.eccreq.strength) { |
2261 | ecc->size = chip->ecc_step_ds; | 2252 | ecc->size = chip->base.eccreq.step_size; |
2262 | ecc->strength = chip->ecc_strength_ds; | 2253 | ecc->strength = chip->base.eccreq.strength; |
2263 | } else { | 2254 | } else { |
2264 | dev_info(nfc->dev, | 2255 | dev_info(nfc->dev, |
2265 | "No minimum ECC strength, using 1b/512B\n"); | 2256 | "No minimum ECC strength, using 1b/512B\n"); |
@@ -2989,7 +2980,7 @@ static int __maybe_unused marvell_nfc_resume(struct device *dev) | |||
2989 | 2980 | ||
2990 | /* | 2981 | /* |
2991 | * Reset nfc->selected_chip so the next command will cause the timing | 2982 | * Reset nfc->selected_chip so the next command will cause the timing |
2992 | * registers to be restored in marvell_nfc_select_chip(). | 2983 | * registers to be restored in marvell_nfc_select_target(). |
2993 | */ | 2984 | */ |
2994 | nfc->selected_chip = NULL; | 2985 | nfc->selected_chip = NULL; |
2995 | 2986 | ||
diff --git a/drivers/mtd/nand/raw/meson_nand.c b/drivers/mtd/nand/raw/meson_nand.c index 3e8aa71407b5..ea57ddcec41e 100644 --- a/drivers/mtd/nand/raw/meson_nand.c +++ b/drivers/mtd/nand/raw/meson_nand.c | |||
@@ -400,7 +400,7 @@ static int meson_nfc_queue_rb(struct meson_nfc *nfc, int timeout_ms) | |||
400 | cfg |= NFC_RB_IRQ_EN; | 400 | cfg |= NFC_RB_IRQ_EN; |
401 | writel(cfg, nfc->reg_base + NFC_REG_CFG); | 401 | writel(cfg, nfc->reg_base + NFC_REG_CFG); |
402 | 402 | ||
403 | init_completion(&nfc->completion); | 403 | reinit_completion(&nfc->completion); |
404 | 404 | ||
405 | /* use the max erase time as the maximum clock for waiting R/B */ | 405 | /* use the max erase time as the maximum clock for waiting R/B */ |
406 | cmd = NFC_CMD_RB | NFC_CMD_RB_INT | 406 | cmd = NFC_CMD_RB | NFC_CMD_RB_INT |
@@ -470,15 +470,15 @@ static int meson_nfc_ecc_correct(struct nand_chip *nand, u32 *bitflips, | |||
470 | return ret; | 470 | return ret; |
471 | } | 471 | } |
472 | 472 | ||
473 | static int meson_nfc_dma_buffer_setup(struct nand_chip *nand, u8 *databuf, | 473 | static int meson_nfc_dma_buffer_setup(struct nand_chip *nand, void *databuf, |
474 | int datalen, u8 *infobuf, int infolen, | 474 | int datalen, void *infobuf, int infolen, |
475 | enum dma_data_direction dir) | 475 | enum dma_data_direction dir) |
476 | { | 476 | { |
477 | struct meson_nfc *nfc = nand_get_controller_data(nand); | 477 | struct meson_nfc *nfc = nand_get_controller_data(nand); |
478 | u32 cmd; | 478 | u32 cmd; |
479 | int ret = 0; | 479 | int ret = 0; |
480 | 480 | ||
481 | nfc->daddr = dma_map_single(nfc->dev, (void *)databuf, datalen, dir); | 481 | nfc->daddr = dma_map_single(nfc->dev, databuf, datalen, dir); |
482 | ret = dma_mapping_error(nfc->dev, nfc->daddr); | 482 | ret = dma_mapping_error(nfc->dev, nfc->daddr); |
483 | if (ret) { | 483 | if (ret) { |
484 | dev_err(nfc->dev, "DMA mapping error\n"); | 484 | dev_err(nfc->dev, "DMA mapping error\n"); |
@@ -528,10 +528,13 @@ static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len) | |||
528 | u8 *info; | 528 | u8 *info; |
529 | 529 | ||
530 | info = kzalloc(PER_INFO_BYTE, GFP_KERNEL); | 530 | info = kzalloc(PER_INFO_BYTE, GFP_KERNEL); |
531 | if (!info) | ||
532 | return -ENOMEM; | ||
533 | |||
531 | ret = meson_nfc_dma_buffer_setup(nand, buf, len, info, | 534 | ret = meson_nfc_dma_buffer_setup(nand, buf, len, info, |
532 | PER_INFO_BYTE, DMA_FROM_DEVICE); | 535 | PER_INFO_BYTE, DMA_FROM_DEVICE); |
533 | if (ret) | 536 | if (ret) |
534 | return ret; | 537 | goto out; |
535 | 538 | ||
536 | cmd = NFC_CMD_N2M | (len & GENMASK(5, 0)); | 539 | cmd = NFC_CMD_N2M | (len & GENMASK(5, 0)); |
537 | writel(cmd, nfc->reg_base + NFC_REG_CMD); | 540 | writel(cmd, nfc->reg_base + NFC_REG_CMD); |
@@ -539,6 +542,8 @@ static int meson_nfc_read_buf(struct nand_chip *nand, u8 *buf, int len) | |||
539 | meson_nfc_drain_cmd(nfc); | 542 | meson_nfc_drain_cmd(nfc); |
540 | meson_nfc_wait_cmd_finish(nfc, 1000); | 543 | meson_nfc_wait_cmd_finish(nfc, 1000); |
541 | meson_nfc_dma_buffer_release(nand, len, PER_INFO_BYTE, DMA_FROM_DEVICE); | 544 | meson_nfc_dma_buffer_release(nand, len, PER_INFO_BYTE, DMA_FROM_DEVICE); |
545 | |||
546 | out: | ||
542 | kfree(info); | 547 | kfree(info); |
543 | 548 | ||
544 | return ret; | 549 | return ret; |
@@ -640,7 +645,7 @@ static int meson_nfc_write_page_sub(struct nand_chip *nand, | |||
640 | return ret; | 645 | return ret; |
641 | 646 | ||
642 | ret = meson_nfc_dma_buffer_setup(nand, meson_chip->data_buf, | 647 | ret = meson_nfc_dma_buffer_setup(nand, meson_chip->data_buf, |
643 | data_len, (u8 *)meson_chip->info_buf, | 648 | data_len, meson_chip->info_buf, |
644 | info_len, DMA_TO_DEVICE); | 649 | info_len, DMA_TO_DEVICE); |
645 | if (ret) | 650 | if (ret) |
646 | return ret; | 651 | return ret; |
@@ -724,7 +729,7 @@ static int meson_nfc_read_page_sub(struct nand_chip *nand, | |||
724 | return ret; | 729 | return ret; |
725 | 730 | ||
726 | ret = meson_nfc_dma_buffer_setup(nand, meson_chip->data_buf, | 731 | ret = meson_nfc_dma_buffer_setup(nand, meson_chip->data_buf, |
727 | data_len, (u8 *)meson_chip->info_buf, | 732 | data_len, meson_chip->info_buf, |
728 | info_len, DMA_FROM_DEVICE); | 733 | info_len, DMA_FROM_DEVICE); |
729 | if (ret) | 734 | if (ret) |
730 | return ret; | 735 | return ret; |
@@ -1183,6 +1188,8 @@ static int meson_nand_attach_chip(struct nand_chip *nand) | |||
1183 | return -EINVAL; | 1188 | return -EINVAL; |
1184 | } | 1189 | } |
1185 | 1190 | ||
1191 | mtd_set_ooblayout(mtd, &meson_ooblayout_ops); | ||
1192 | |||
1186 | ret = meson_nand_bch_mode(nand); | 1193 | ret = meson_nand_bch_mode(nand); |
1187 | if (ret) | 1194 | if (ret) |
1188 | return -EINVAL; | 1195 | return -EINVAL; |
@@ -1226,17 +1233,13 @@ meson_nfc_nand_chip_init(struct device *dev, | |||
1226 | int ret, i; | 1233 | int ret, i; |
1227 | u32 tmp, nsels; | 1234 | u32 tmp, nsels; |
1228 | 1235 | ||
1229 | if (!of_get_property(np, "reg", &nsels)) | 1236 | nsels = of_property_count_elems_of_size(np, "reg", sizeof(u32)); |
1230 | return -EINVAL; | ||
1231 | |||
1232 | nsels /= sizeof(u32); | ||
1233 | if (!nsels || nsels > MAX_CE_NUM) { | 1237 | if (!nsels || nsels > MAX_CE_NUM) { |
1234 | dev_err(dev, "invalid register property size\n"); | 1238 | dev_err(dev, "invalid register property size\n"); |
1235 | return -EINVAL; | 1239 | return -EINVAL; |
1236 | } | 1240 | } |
1237 | 1241 | ||
1238 | meson_chip = devm_kzalloc(dev, | 1242 | meson_chip = devm_kzalloc(dev, struct_size(meson_chip, sels, nsels), |
1239 | sizeof(*meson_chip) + (nsels * sizeof(u8)), | ||
1240 | GFP_KERNEL); | 1243 | GFP_KERNEL); |
1241 | if (!meson_chip) | 1244 | if (!meson_chip) |
1242 | return -ENOMEM; | 1245 | return -ENOMEM; |
@@ -1377,6 +1380,7 @@ static int meson_nfc_probe(struct platform_device *pdev) | |||
1377 | 1380 | ||
1378 | nand_controller_init(&nfc->controller); | 1381 | nand_controller_init(&nfc->controller); |
1379 | INIT_LIST_HEAD(&nfc->chips); | 1382 | INIT_LIST_HEAD(&nfc->chips); |
1383 | init_completion(&nfc->completion); | ||
1380 | 1384 | ||
1381 | nfc->dev = dev; | 1385 | nfc->dev = dev; |
1382 | 1386 | ||
diff --git a/drivers/mtd/nand/raw/mtk_nand.c b/drivers/mtd/nand/raw/mtk_nand.c index 2c0e09187773..b17619f30b1b 100644 --- a/drivers/mtd/nand/raw/mtk_nand.c +++ b/drivers/mtd/nand/raw/mtk_nand.c | |||
@@ -1197,8 +1197,8 @@ static int mtk_nfc_ecc_init(struct device *dev, struct mtd_info *mtd) | |||
1197 | /* if optional dt settings not present */ | 1197 | /* if optional dt settings not present */ |
1198 | if (!nand->ecc.size || !nand->ecc.strength) { | 1198 | if (!nand->ecc.size || !nand->ecc.strength) { |
1199 | /* use datasheet requirements */ | 1199 | /* use datasheet requirements */ |
1200 | nand->ecc.strength = nand->ecc_strength_ds; | 1200 | nand->ecc.strength = nand->base.eccreq.strength; |
1201 | nand->ecc.size = nand->ecc_step_ds; | 1201 | nand->ecc.size = nand->base.eccreq.step_size; |
1202 | 1202 | ||
1203 | /* | 1203 | /* |
1204 | * align eccstrength and eccsize | 1204 | * align eccstrength and eccsize |
diff --git a/drivers/mtd/nand/raw/nand_amd.c b/drivers/mtd/nand/raw/nand_amd.c index 890c5b43e03c..6217555c19a6 100644 --- a/drivers/mtd/nand/raw/nand_amd.c +++ b/drivers/mtd/nand/raw/nand_amd.c | |||
@@ -20,6 +20,9 @@ | |||
20 | static void amd_nand_decode_id(struct nand_chip *chip) | 20 | static void amd_nand_decode_id(struct nand_chip *chip) |
21 | { | 21 | { |
22 | struct mtd_info *mtd = nand_to_mtd(chip); | 22 | struct mtd_info *mtd = nand_to_mtd(chip); |
23 | struct nand_memory_organization *memorg; | ||
24 | |||
25 | memorg = nanddev_get_memorg(&chip->base); | ||
23 | 26 | ||
24 | nand_decode_ext_id(chip); | 27 | nand_decode_ext_id(chip); |
25 | 28 | ||
@@ -31,16 +34,24 @@ static void amd_nand_decode_id(struct nand_chip *chip) | |||
31 | */ | 34 | */ |
32 | if (chip->id.data[4] != 0x00 && chip->id.data[5] == 0x00 && | 35 | if (chip->id.data[4] != 0x00 && chip->id.data[5] == 0x00 && |
33 | chip->id.data[6] == 0x00 && chip->id.data[7] == 0x00 && | 36 | chip->id.data[6] == 0x00 && chip->id.data[7] == 0x00 && |
34 | mtd->writesize == 512) { | 37 | memorg->pagesize == 512) { |
35 | mtd->erasesize = 128 * 1024; | 38 | memorg->pages_per_eraseblock = 256; |
36 | mtd->erasesize <<= ((chip->id.data[3] & 0x03) << 1); | 39 | memorg->pages_per_eraseblock <<= ((chip->id.data[3] & 0x03) << 1); |
40 | mtd->erasesize = memorg->pages_per_eraseblock * | ||
41 | memorg->pagesize; | ||
37 | } | 42 | } |
38 | } | 43 | } |
39 | 44 | ||
40 | static int amd_nand_init(struct nand_chip *chip) | 45 | static int amd_nand_init(struct nand_chip *chip) |
41 | { | 46 | { |
42 | if (nand_is_slc(chip)) | 47 | if (nand_is_slc(chip)) |
43 | chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; | 48 | /* |
49 | * According to the datasheet of some Cypress SLC NANDs, | ||
50 | * the bad block markers can be in the first, second or last | ||
51 | * page of a block. So let's check all three locations. | ||
52 | */ | ||
53 | chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE | | ||
54 | NAND_BBM_LASTPAGE; | ||
44 | 55 | ||
45 | return 0; | 56 | return 0; |
46 | } | 57 | } |
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index ddd396e93e32..2cf71060d6f8 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c | |||
@@ -240,10 +240,10 @@ static int check_offs_len(struct nand_chip *chip, loff_t ofs, uint64_t len) | |||
240 | void nand_select_target(struct nand_chip *chip, unsigned int cs) | 240 | void nand_select_target(struct nand_chip *chip, unsigned int cs) |
241 | { | 241 | { |
242 | /* | 242 | /* |
243 | * cs should always lie between 0 and chip->numchips, when that's not | 243 | * cs should always lie between 0 and nanddev_ntargets(), when that's |
244 | * the case it's a bug and the caller should be fixed. | 244 | * not the case it's a bug and the caller should be fixed. |
245 | */ | 245 | */ |
246 | if (WARN_ON(cs > chip->numchips)) | 246 | if (WARN_ON(cs > nanddev_ntargets(&chip->base))) |
247 | return; | 247 | return; |
248 | 248 | ||
249 | chip->cur_cs = cs; | 249 | chip->cur_cs = cs; |
@@ -283,6 +283,31 @@ static void nand_release_device(struct nand_chip *chip) | |||
283 | } | 283 | } |
284 | 284 | ||
285 | /** | 285 | /** |
286 | * nand_bbm_get_next_page - Get the next page for bad block markers | ||
287 | * @chip: NAND chip object | ||
288 | * @page: First page to start checking for bad block marker usage | ||
289 | * | ||
290 | * Returns an integer that corresponds to the page offset within a block, for | ||
291 | * a page that is used to store bad block markers. If no more pages are | ||
292 | * available, -EINVAL is returned. | ||
293 | */ | ||
294 | int nand_bbm_get_next_page(struct nand_chip *chip, int page) | ||
295 | { | ||
296 | struct mtd_info *mtd = nand_to_mtd(chip); | ||
297 | int last_page = ((mtd->erasesize - mtd->writesize) >> | ||
298 | chip->page_shift) & chip->pagemask; | ||
299 | |||
300 | if (page == 0 && chip->options & NAND_BBM_FIRSTPAGE) | ||
301 | return 0; | ||
302 | else if (page <= 1 && chip->options & NAND_BBM_SECONDPAGE) | ||
303 | return 1; | ||
304 | else if (page <= last_page && chip->options & NAND_BBM_LASTPAGE) | ||
305 | return last_page; | ||
306 | |||
307 | return -EINVAL; | ||
308 | } | ||
309 | |||
310 | /** | ||
286 | * nand_block_bad - [DEFAULT] Read bad block marker from the chip | 311 | * nand_block_bad - [DEFAULT] Read bad block marker from the chip |
287 | * @chip: NAND chip object | 312 | * @chip: NAND chip object |
288 | * @ofs: offset from device start | 313 | * @ofs: offset from device start |
@@ -291,18 +316,15 @@ static void nand_release_device(struct nand_chip *chip) | |||
291 | */ | 316 | */ |
292 | static int nand_block_bad(struct nand_chip *chip, loff_t ofs) | 317 | static int nand_block_bad(struct nand_chip *chip, loff_t ofs) |
293 | { | 318 | { |
294 | struct mtd_info *mtd = nand_to_mtd(chip); | 319 | int first_page, page_offset; |
295 | int page, page_end, res; | 320 | int res; |
296 | u8 bad; | 321 | u8 bad; |
297 | 322 | ||
298 | if (chip->bbt_options & NAND_BBT_SCANLASTPAGE) | 323 | first_page = (int)(ofs >> chip->page_shift) & chip->pagemask; |
299 | ofs += mtd->erasesize - mtd->writesize; | 324 | page_offset = nand_bbm_get_next_page(chip, 0); |
300 | |||
301 | page = (int)(ofs >> chip->page_shift) & chip->pagemask; | ||
302 | page_end = page + (chip->bbt_options & NAND_BBT_SCAN2NDPAGE ? 2 : 1); | ||
303 | 325 | ||
304 | for (; page < page_end; page++) { | 326 | while (page_offset >= 0) { |
305 | res = chip->ecc.read_oob(chip, page); | 327 | res = chip->ecc.read_oob(chip, first_page + page_offset); |
306 | if (res < 0) | 328 | if (res < 0) |
307 | return res; | 329 | return res; |
308 | 330 | ||
@@ -314,6 +336,8 @@ static int nand_block_bad(struct nand_chip *chip, loff_t ofs) | |||
314 | res = hweight8(bad) < chip->badblockbits; | 336 | res = hweight8(bad) < chip->badblockbits; |
315 | if (res) | 337 | if (res) |
316 | return res; | 338 | return res; |
339 | |||
340 | page_offset = nand_bbm_get_next_page(chip, page_offset + 1); | ||
317 | } | 341 | } |
318 | 342 | ||
319 | return 0; | 343 | return 0; |
@@ -459,8 +483,8 @@ static int nand_do_write_oob(struct nand_chip *chip, loff_t to, | |||
459 | } | 483 | } |
460 | 484 | ||
461 | /* Invalidate the page cache, if we write to the cached page */ | 485 | /* Invalidate the page cache, if we write to the cached page */ |
462 | if (page == chip->pagebuf) | 486 | if (page == chip->pagecache.page) |
463 | chip->pagebuf = -1; | 487 | chip->pagecache.page = -1; |
464 | 488 | ||
465 | nand_fill_oob(chip, ops->oobbuf, ops->ooblen, ops); | 489 | nand_fill_oob(chip, ops->oobbuf, ops->ooblen, ops); |
466 | 490 | ||
@@ -493,7 +517,7 @@ static int nand_default_block_markbad(struct nand_chip *chip, loff_t ofs) | |||
493 | struct mtd_info *mtd = nand_to_mtd(chip); | 517 | struct mtd_info *mtd = nand_to_mtd(chip); |
494 | struct mtd_oob_ops ops; | 518 | struct mtd_oob_ops ops; |
495 | uint8_t buf[2] = { 0, 0 }; | 519 | uint8_t buf[2] = { 0, 0 }; |
496 | int ret = 0, res, i = 0; | 520 | int ret = 0, res, page_offset; |
497 | 521 | ||
498 | memset(&ops, 0, sizeof(ops)); | 522 | memset(&ops, 0, sizeof(ops)); |
499 | ops.oobbuf = buf; | 523 | ops.oobbuf = buf; |
@@ -506,17 +530,18 @@ static int nand_default_block_markbad(struct nand_chip *chip, loff_t ofs) | |||
506 | } | 530 | } |
507 | ops.mode = MTD_OPS_PLACE_OOB; | 531 | ops.mode = MTD_OPS_PLACE_OOB; |
508 | 532 | ||
509 | /* Write to first/last page(s) if necessary */ | 533 | page_offset = nand_bbm_get_next_page(chip, 0); |
510 | if (chip->bbt_options & NAND_BBT_SCANLASTPAGE) | 534 | |
511 | ofs += mtd->erasesize - mtd->writesize; | 535 | while (page_offset >= 0) { |
512 | do { | 536 | res = nand_do_write_oob(chip, |
513 | res = nand_do_write_oob(chip, ofs, &ops); | 537 | ofs + (page_offset * mtd->writesize), |
538 | &ops); | ||
539 | |||
514 | if (!ret) | 540 | if (!ret) |
515 | ret = res; | 541 | ret = res; |
516 | 542 | ||
517 | i++; | 543 | page_offset = nand_bbm_get_next_page(chip, page_offset + 1); |
518 | ofs += mtd->writesize; | 544 | } |
519 | } while ((chip->bbt_options & NAND_BBT_SCAN2NDPAGE) && i < 2); | ||
520 | 545 | ||
521 | return ret; | 546 | return ret; |
522 | } | 547 | } |
@@ -3173,7 +3198,7 @@ static int nand_do_read_ops(struct nand_chip *chip, loff_t from, | |||
3173 | use_bufpoi = 0; | 3198 | use_bufpoi = 0; |
3174 | 3199 | ||
3175 | /* Is the current page in the buffer? */ | 3200 | /* Is the current page in the buffer? */ |
3176 | if (realpage != chip->pagebuf || oob) { | 3201 | if (realpage != chip->pagecache.page || oob) { |
3177 | bufpoi = use_bufpoi ? chip->data_buf : buf; | 3202 | bufpoi = use_bufpoi ? chip->data_buf : buf; |
3178 | 3203 | ||
3179 | if (use_bufpoi && aligned) | 3204 | if (use_bufpoi && aligned) |
@@ -3199,7 +3224,7 @@ read_retry: | |||
3199 | if (ret < 0) { | 3224 | if (ret < 0) { |
3200 | if (use_bufpoi) | 3225 | if (use_bufpoi) |
3201 | /* Invalidate page cache */ | 3226 | /* Invalidate page cache */ |
3202 | chip->pagebuf = -1; | 3227 | chip->pagecache.page = -1; |
3203 | break; | 3228 | break; |
3204 | } | 3229 | } |
3205 | 3230 | ||
@@ -3208,11 +3233,11 @@ read_retry: | |||
3208 | if (!NAND_HAS_SUBPAGE_READ(chip) && !oob && | 3233 | if (!NAND_HAS_SUBPAGE_READ(chip) && !oob && |
3209 | !(mtd->ecc_stats.failed - ecc_failures) && | 3234 | !(mtd->ecc_stats.failed - ecc_failures) && |
3210 | (ops->mode != MTD_OPS_RAW)) { | 3235 | (ops->mode != MTD_OPS_RAW)) { |
3211 | chip->pagebuf = realpage; | 3236 | chip->pagecache.page = realpage; |
3212 | chip->pagebuf_bitflips = ret; | 3237 | chip->pagecache.bitflips = ret; |
3213 | } else { | 3238 | } else { |
3214 | /* Invalidate page cache */ | 3239 | /* Invalidate page cache */ |
3215 | chip->pagebuf = -1; | 3240 | chip->pagecache.page = -1; |
3216 | } | 3241 | } |
3217 | memcpy(buf, chip->data_buf + col, bytes); | 3242 | memcpy(buf, chip->data_buf + col, bytes); |
3218 | } | 3243 | } |
@@ -3252,7 +3277,7 @@ read_retry: | |||
3252 | memcpy(buf, chip->data_buf + col, bytes); | 3277 | memcpy(buf, chip->data_buf + col, bytes); |
3253 | buf += bytes; | 3278 | buf += bytes; |
3254 | max_bitflips = max_t(unsigned int, max_bitflips, | 3279 | max_bitflips = max_t(unsigned int, max_bitflips, |
3255 | chip->pagebuf_bitflips); | 3280 | chip->pagecache.bitflips); |
3256 | } | 3281 | } |
3257 | 3282 | ||
3258 | readlen -= bytes; | 3283 | readlen -= bytes; |
@@ -3973,9 +3998,9 @@ static int nand_do_write_ops(struct nand_chip *chip, loff_t to, | |||
3973 | page = realpage & chip->pagemask; | 3998 | page = realpage & chip->pagemask; |
3974 | 3999 | ||
3975 | /* Invalidate the page cache, when we write to the cached page */ | 4000 | /* Invalidate the page cache, when we write to the cached page */ |
3976 | if (to <= ((loff_t)chip->pagebuf << chip->page_shift) && | 4001 | if (to <= ((loff_t)chip->pagecache.page << chip->page_shift) && |
3977 | ((loff_t)chip->pagebuf << chip->page_shift) < (to + ops->len)) | 4002 | ((loff_t)chip->pagecache.page << chip->page_shift) < (to + ops->len)) |
3978 | chip->pagebuf = -1; | 4003 | chip->pagecache.page = -1; |
3979 | 4004 | ||
3980 | /* Don't allow multipage oob writes with offset */ | 4005 | /* Don't allow multipage oob writes with offset */ |
3981 | if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen)) { | 4006 | if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen)) { |
@@ -4004,10 +4029,9 @@ static int nand_do_write_ops(struct nand_chip *chip, loff_t to, | |||
4004 | __func__, buf); | 4029 | __func__, buf); |
4005 | if (part_pagewr) | 4030 | if (part_pagewr) |
4006 | bytes = min_t(int, bytes - column, writelen); | 4031 | bytes = min_t(int, bytes - column, writelen); |
4007 | chip->pagebuf = -1; | 4032 | wbuf = nand_get_data_buf(chip); |
4008 | memset(chip->data_buf, 0xff, mtd->writesize); | 4033 | memset(wbuf, 0xff, mtd->writesize); |
4009 | memcpy(&chip->data_buf[column], buf, bytes); | 4034 | memcpy(&wbuf[column], buf, bytes); |
4010 | wbuf = chip->data_buf; | ||
4011 | } | 4035 | } |
4012 | 4036 | ||
4013 | if (unlikely(oob)) { | 4037 | if (unlikely(oob)) { |
@@ -4197,9 +4221,9 @@ int nand_erase_nand(struct nand_chip *chip, struct erase_info *instr, | |||
4197 | * Invalidate the page cache, if we erase the block which | 4221 | * Invalidate the page cache, if we erase the block which |
4198 | * contains the current cached page. | 4222 | * contains the current cached page. |
4199 | */ | 4223 | */ |
4200 | if (page <= chip->pagebuf && chip->pagebuf < | 4224 | if (page <= chip->pagecache.page && chip->pagecache.page < |
4201 | (page + pages_per_block)) | 4225 | (page + pages_per_block)) |
4202 | chip->pagebuf = -1; | 4226 | chip->pagecache.page = -1; |
4203 | 4227 | ||
4204 | ret = nand_erase_op(chip, (page & chip->pagemask) >> | 4228 | ret = nand_erase_op(chip, (page & chip->pagemask) >> |
4205 | (chip->phys_erase_shift - chip->page_shift)); | 4229 | (chip->phys_erase_shift - chip->page_shift)); |
@@ -4299,42 +4323,6 @@ static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs) | |||
4299 | } | 4323 | } |
4300 | 4324 | ||
4301 | /** | 4325 | /** |
4302 | * nand_max_bad_blocks - [MTD Interface] Max number of bad blocks for an mtd | ||
4303 | * @mtd: MTD device structure | ||
4304 | * @ofs: offset relative to mtd start | ||
4305 | * @len: length of mtd | ||
4306 | */ | ||
4307 | static int nand_max_bad_blocks(struct mtd_info *mtd, loff_t ofs, size_t len) | ||
4308 | { | ||
4309 | struct nand_chip *chip = mtd_to_nand(mtd); | ||
4310 | u32 part_start_block; | ||
4311 | u32 part_end_block; | ||
4312 | u32 part_start_die; | ||
4313 | u32 part_end_die; | ||
4314 | |||
4315 | /* | ||
4316 | * max_bb_per_die and blocks_per_die used to determine | ||
4317 | * the maximum bad block count. | ||
4318 | */ | ||
4319 | if (!chip->max_bb_per_die || !chip->blocks_per_die) | ||
4320 | return -ENOTSUPP; | ||
4321 | |||
4322 | /* Get the start and end of the partition in erase blocks. */ | ||
4323 | part_start_block = mtd_div_by_eb(ofs, mtd); | ||
4324 | part_end_block = mtd_div_by_eb(len, mtd) + part_start_block - 1; | ||
4325 | |||
4326 | /* Get the start and end LUNs of the partition. */ | ||
4327 | part_start_die = part_start_block / chip->blocks_per_die; | ||
4328 | part_end_die = part_end_block / chip->blocks_per_die; | ||
4329 | |||
4330 | /* | ||
4331 | * Look up the bad blocks per unit and multiply by the number of units | ||
4332 | * that the partition spans. | ||
4333 | */ | ||
4334 | return chip->max_bb_per_die * (part_end_die - part_start_die + 1); | ||
4335 | } | ||
4336 | |||
4337 | /** | ||
4338 | * nand_suspend - [MTD Interface] Suspend the NAND flash | 4326 | * nand_suspend - [MTD Interface] Suspend the NAND flash |
4339 | * @mtd: MTD device structure | 4327 | * @mtd: MTD device structure |
4340 | */ | 4328 | */ |
@@ -4485,21 +4473,29 @@ static int nand_get_bits_per_cell(u8 cellinfo) | |||
4485 | */ | 4473 | */ |
4486 | void nand_decode_ext_id(struct nand_chip *chip) | 4474 | void nand_decode_ext_id(struct nand_chip *chip) |
4487 | { | 4475 | { |
4476 | struct nand_memory_organization *memorg; | ||
4488 | struct mtd_info *mtd = nand_to_mtd(chip); | 4477 | struct mtd_info *mtd = nand_to_mtd(chip); |
4489 | int extid; | 4478 | int extid; |
4490 | u8 *id_data = chip->id.data; | 4479 | u8 *id_data = chip->id.data; |
4480 | |||
4481 | memorg = nanddev_get_memorg(&chip->base); | ||
4482 | |||
4491 | /* The 3rd id byte holds MLC / multichip data */ | 4483 | /* The 3rd id byte holds MLC / multichip data */ |
4492 | chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]); | 4484 | memorg->bits_per_cell = nand_get_bits_per_cell(id_data[2]); |
4493 | /* The 4th id byte is the important one */ | 4485 | /* The 4th id byte is the important one */ |
4494 | extid = id_data[3]; | 4486 | extid = id_data[3]; |
4495 | 4487 | ||
4496 | /* Calc pagesize */ | 4488 | /* Calc pagesize */ |
4497 | mtd->writesize = 1024 << (extid & 0x03); | 4489 | memorg->pagesize = 1024 << (extid & 0x03); |
4490 | mtd->writesize = memorg->pagesize; | ||
4498 | extid >>= 2; | 4491 | extid >>= 2; |
4499 | /* Calc oobsize */ | 4492 | /* Calc oobsize */ |
4500 | mtd->oobsize = (8 << (extid & 0x01)) * (mtd->writesize >> 9); | 4493 | memorg->oobsize = (8 << (extid & 0x01)) * (mtd->writesize >> 9); |
4494 | mtd->oobsize = memorg->oobsize; | ||
4501 | extid >>= 2; | 4495 | extid >>= 2; |
4502 | /* Calc blocksize. Blocksize is multiples of 64KiB */ | 4496 | /* Calc blocksize. Blocksize is multiples of 64KiB */ |
4497 | memorg->pages_per_eraseblock = ((64 * 1024) << (extid & 0x03)) / | ||
4498 | memorg->pagesize; | ||
4503 | mtd->erasesize = (64 * 1024) << (extid & 0x03); | 4499 | mtd->erasesize = (64 * 1024) << (extid & 0x03); |
4504 | extid >>= 2; | 4500 | extid >>= 2; |
4505 | /* Get buswidth information */ | 4501 | /* Get buswidth information */ |
@@ -4516,13 +4512,19 @@ EXPORT_SYMBOL_GPL(nand_decode_ext_id); | |||
4516 | static void nand_decode_id(struct nand_chip *chip, struct nand_flash_dev *type) | 4512 | static void nand_decode_id(struct nand_chip *chip, struct nand_flash_dev *type) |
4517 | { | 4513 | { |
4518 | struct mtd_info *mtd = nand_to_mtd(chip); | 4514 | struct mtd_info *mtd = nand_to_mtd(chip); |
4515 | struct nand_memory_organization *memorg; | ||
4516 | |||
4517 | memorg = nanddev_get_memorg(&chip->base); | ||
4519 | 4518 | ||
4519 | memorg->pages_per_eraseblock = type->erasesize / type->pagesize; | ||
4520 | mtd->erasesize = type->erasesize; | 4520 | mtd->erasesize = type->erasesize; |
4521 | mtd->writesize = type->pagesize; | 4521 | memorg->pagesize = type->pagesize; |
4522 | mtd->oobsize = mtd->writesize / 32; | 4522 | mtd->writesize = memorg->pagesize; |
4523 | memorg->oobsize = memorg->pagesize / 32; | ||
4524 | mtd->oobsize = memorg->oobsize; | ||
4523 | 4525 | ||
4524 | /* All legacy ID NAND are small-page, SLC */ | 4526 | /* All legacy ID NAND are small-page, SLC */ |
4525 | chip->bits_per_cell = 1; | 4527 | memorg->bits_per_cell = 1; |
4526 | } | 4528 | } |
4527 | 4529 | ||
4528 | /* | 4530 | /* |
@@ -4536,9 +4538,9 @@ static void nand_decode_bbm_options(struct nand_chip *chip) | |||
4536 | 4538 | ||
4537 | /* Set the bad block position */ | 4539 | /* Set the bad block position */ |
4538 | if (mtd->writesize > 512 || (chip->options & NAND_BUSWIDTH_16)) | 4540 | if (mtd->writesize > 512 || (chip->options & NAND_BUSWIDTH_16)) |
4539 | chip->badblockpos = NAND_LARGE_BADBLOCK_POS; | 4541 | chip->badblockpos = NAND_BBM_POS_LARGE; |
4540 | else | 4542 | else |
4541 | chip->badblockpos = NAND_SMALL_BADBLOCK_POS; | 4543 | chip->badblockpos = NAND_BBM_POS_SMALL; |
4542 | } | 4544 | } |
4543 | 4545 | ||
4544 | static inline bool is_full_id_nand(struct nand_flash_dev *type) | 4546 | static inline bool is_full_id_nand(struct nand_flash_dev *type) |
@@ -4550,18 +4552,28 @@ static bool find_full_id_nand(struct nand_chip *chip, | |||
4550 | struct nand_flash_dev *type) | 4552 | struct nand_flash_dev *type) |
4551 | { | 4553 | { |
4552 | struct mtd_info *mtd = nand_to_mtd(chip); | 4554 | struct mtd_info *mtd = nand_to_mtd(chip); |
4555 | struct nand_memory_organization *memorg; | ||
4553 | u8 *id_data = chip->id.data; | 4556 | u8 *id_data = chip->id.data; |
4554 | 4557 | ||
4558 | memorg = nanddev_get_memorg(&chip->base); | ||
4559 | |||
4555 | if (!strncmp(type->id, id_data, type->id_len)) { | 4560 | if (!strncmp(type->id, id_data, type->id_len)) { |
4556 | mtd->writesize = type->pagesize; | 4561 | memorg->pagesize = type->pagesize; |
4562 | mtd->writesize = memorg->pagesize; | ||
4563 | memorg->pages_per_eraseblock = type->erasesize / | ||
4564 | type->pagesize; | ||
4557 | mtd->erasesize = type->erasesize; | 4565 | mtd->erasesize = type->erasesize; |
4558 | mtd->oobsize = type->oobsize; | 4566 | memorg->oobsize = type->oobsize; |
4559 | 4567 | mtd->oobsize = memorg->oobsize; | |
4560 | chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]); | 4568 | |
4561 | chip->chipsize = (uint64_t)type->chipsize << 20; | 4569 | memorg->bits_per_cell = nand_get_bits_per_cell(id_data[2]); |
4570 | memorg->eraseblocks_per_lun = | ||
4571 | DIV_ROUND_DOWN_ULL((u64)type->chipsize << 20, | ||
4572 | memorg->pagesize * | ||
4573 | memorg->pages_per_eraseblock); | ||
4562 | chip->options |= type->options; | 4574 | chip->options |= type->options; |
4563 | chip->ecc_strength_ds = NAND_ECC_STRENGTH(type); | 4575 | chip->base.eccreq.strength = NAND_ECC_STRENGTH(type); |
4564 | chip->ecc_step_ds = NAND_ECC_STEP(type); | 4576 | chip->base.eccreq.step_size = NAND_ECC_STEP(type); |
4565 | chip->onfi_timing_mode_default = | 4577 | chip->onfi_timing_mode_default = |
4566 | type->onfi_timing_mode_default; | 4578 | type->onfi_timing_mode_default; |
4567 | 4579 | ||
@@ -4587,8 +4599,12 @@ static void nand_manufacturer_detect(struct nand_chip *chip) | |||
4587 | */ | 4599 | */ |
4588 | if (chip->manufacturer.desc && chip->manufacturer.desc->ops && | 4600 | if (chip->manufacturer.desc && chip->manufacturer.desc->ops && |
4589 | chip->manufacturer.desc->ops->detect) { | 4601 | chip->manufacturer.desc->ops->detect) { |
4602 | struct nand_memory_organization *memorg; | ||
4603 | |||
4604 | memorg = nanddev_get_memorg(&chip->base); | ||
4605 | |||
4590 | /* The 3rd id byte holds MLC / multichip data */ | 4606 | /* The 3rd id byte holds MLC / multichip data */ |
4591 | chip->bits_per_cell = nand_get_bits_per_cell(chip->id.data[2]); | 4607 | memorg->bits_per_cell = nand_get_bits_per_cell(chip->id.data[2]); |
4592 | chip->manufacturer.desc->ops->detect(chip); | 4608 | chip->manufacturer.desc->ops->detect(chip); |
4593 | } else { | 4609 | } else { |
4594 | nand_decode_ext_id(chip); | 4610 | nand_decode_ext_id(chip); |
@@ -4637,9 +4653,20 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type) | |||
4637 | { | 4653 | { |
4638 | const struct nand_manufacturer *manufacturer; | 4654 | const struct nand_manufacturer *manufacturer; |
4639 | struct mtd_info *mtd = nand_to_mtd(chip); | 4655 | struct mtd_info *mtd = nand_to_mtd(chip); |
4656 | struct nand_memory_organization *memorg; | ||
4640 | int busw, ret; | 4657 | int busw, ret; |
4641 | u8 *id_data = chip->id.data; | 4658 | u8 *id_data = chip->id.data; |
4642 | u8 maf_id, dev_id; | 4659 | u8 maf_id, dev_id; |
4660 | u64 targetsize; | ||
4661 | |||
4662 | /* | ||
4663 | * Let's start by initializing memorg fields that might be left | ||
4664 | * unassigned by the ID-based detection logic. | ||
4665 | */ | ||
4666 | memorg = nanddev_get_memorg(&chip->base); | ||
4667 | memorg->planes_per_lun = 1; | ||
4668 | memorg->luns_per_target = 1; | ||
4669 | memorg->ntargets = 1; | ||
4643 | 4670 | ||
4644 | /* | 4671 | /* |
4645 | * Reset the chip, required by some chips (e.g. Micron MT29FxGxxxxx) | 4672 | * Reset the chip, required by some chips (e.g. Micron MT29FxGxxxxx) |
@@ -4735,8 +4762,6 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type) | |||
4735 | if (!chip->parameters.model) | 4762 | if (!chip->parameters.model) |
4736 | return -ENOMEM; | 4763 | return -ENOMEM; |
4737 | 4764 | ||
4738 | chip->chipsize = (uint64_t)type->chipsize << 20; | ||
4739 | |||
4740 | if (!type->pagesize) | 4765 | if (!type->pagesize) |
4741 | nand_manufacturer_detect(chip); | 4766 | nand_manufacturer_detect(chip); |
4742 | else | 4767 | else |
@@ -4745,6 +4770,11 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type) | |||
4745 | /* Get chip options */ | 4770 | /* Get chip options */ |
4746 | chip->options |= type->options; | 4771 | chip->options |= type->options; |
4747 | 4772 | ||
4773 | memorg->eraseblocks_per_lun = | ||
4774 | DIV_ROUND_DOWN_ULL((u64)type->chipsize << 20, | ||
4775 | memorg->pagesize * | ||
4776 | memorg->pages_per_eraseblock); | ||
4777 | |||
4748 | ident_done: | 4778 | ident_done: |
4749 | if (!mtd->name) | 4779 | if (!mtd->name) |
4750 | mtd->name = chip->parameters.model; | 4780 | mtd->name = chip->parameters.model; |
@@ -4773,14 +4803,15 @@ ident_done: | |||
4773 | /* Calculate the address shift from the page size */ | 4803 | /* Calculate the address shift from the page size */ |
4774 | chip->page_shift = ffs(mtd->writesize) - 1; | 4804 | chip->page_shift = ffs(mtd->writesize) - 1; |
4775 | /* Convert chipsize to number of pages per chip -1 */ | 4805 | /* Convert chipsize to number of pages per chip -1 */ |
4776 | chip->pagemask = (chip->chipsize >> chip->page_shift) - 1; | 4806 | targetsize = nanddev_target_size(&chip->base); |
4807 | chip->pagemask = (targetsize >> chip->page_shift) - 1; | ||
4777 | 4808 | ||
4778 | chip->bbt_erase_shift = chip->phys_erase_shift = | 4809 | chip->bbt_erase_shift = chip->phys_erase_shift = |
4779 | ffs(mtd->erasesize) - 1; | 4810 | ffs(mtd->erasesize) - 1; |
4780 | if (chip->chipsize & 0xffffffff) | 4811 | if (targetsize & 0xffffffff) |
4781 | chip->chip_shift = ffs((unsigned)chip->chipsize) - 1; | 4812 | chip->chip_shift = ffs((unsigned)targetsize) - 1; |
4782 | else { | 4813 | else { |
4783 | chip->chip_shift = ffs((unsigned)(chip->chipsize >> 32)); | 4814 | chip->chip_shift = ffs((unsigned)(targetsize >> 32)); |
4784 | chip->chip_shift += 32 - 1; | 4815 | chip->chip_shift += 32 - 1; |
4785 | } | 4816 | } |
4786 | 4817 | ||
@@ -4796,7 +4827,7 @@ ident_done: | |||
4796 | pr_info("%s %s\n", nand_manufacturer_name(manufacturer), | 4827 | pr_info("%s %s\n", nand_manufacturer_name(manufacturer), |
4797 | chip->parameters.model); | 4828 | chip->parameters.model); |
4798 | pr_info("%d MiB, %s, erase size: %d KiB, page size: %d, OOB size: %d\n", | 4829 | pr_info("%d MiB, %s, erase size: %d KiB, page size: %d, OOB size: %d\n", |
4799 | (int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC", | 4830 | (int)(targetsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC", |
4800 | mtd->erasesize >> 10, mtd->writesize, mtd->oobsize); | 4831 | mtd->erasesize >> 10, mtd->writesize, mtd->oobsize); |
4801 | return 0; | 4832 | return 0; |
4802 | 4833 | ||
@@ -4971,10 +5002,13 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips, | |||
4971 | struct nand_flash_dev *table) | 5002 | struct nand_flash_dev *table) |
4972 | { | 5003 | { |
4973 | struct mtd_info *mtd = nand_to_mtd(chip); | 5004 | struct mtd_info *mtd = nand_to_mtd(chip); |
5005 | struct nand_memory_organization *memorg; | ||
4974 | int nand_maf_id, nand_dev_id; | 5006 | int nand_maf_id, nand_dev_id; |
4975 | unsigned int i; | 5007 | unsigned int i; |
4976 | int ret; | 5008 | int ret; |
4977 | 5009 | ||
5010 | memorg = nanddev_get_memorg(&chip->base); | ||
5011 | |||
4978 | /* Assume all dies are deselected when we enter nand_scan_ident(). */ | 5012 | /* Assume all dies are deselected when we enter nand_scan_ident(). */ |
4979 | chip->cur_cs = -1; | 5013 | chip->cur_cs = -1; |
4980 | 5014 | ||
@@ -4990,12 +5024,6 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips, | |||
4990 | if (!mtd->name && mtd->dev.parent) | 5024 | if (!mtd->name && mtd->dev.parent) |
4991 | mtd->name = dev_name(mtd->dev.parent); | 5025 | mtd->name = dev_name(mtd->dev.parent); |
4992 | 5026 | ||
4993 | /* | ||
4994 | * Start with chips->numchips = maxchips to let nand_select_target() do | ||
4995 | * its job. chip->numchips will be adjusted after. | ||
4996 | */ | ||
4997 | chip->numchips = maxchips; | ||
4998 | |||
4999 | /* Set the default functions */ | 5027 | /* Set the default functions */ |
5000 | nand_set_defaults(chip); | 5028 | nand_set_defaults(chip); |
5001 | 5029 | ||
@@ -5042,8 +5070,8 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips, | |||
5042 | pr_info("%d chips detected\n", i); | 5070 | pr_info("%d chips detected\n", i); |
5043 | 5071 | ||
5044 | /* Store the number of chips and calc total size for mtd */ | 5072 | /* Store the number of chips and calc total size for mtd */ |
5045 | chip->numchips = i; | 5073 | memorg->ntargets = i; |
5046 | mtd->size = i * chip->chipsize; | 5074 | mtd->size = i * nanddev_target_size(&chip->base); |
5047 | 5075 | ||
5048 | return 0; | 5076 | return 0; |
5049 | } | 5077 | } |
@@ -5078,13 +5106,13 @@ static int nand_set_ecc_soft_ops(struct nand_chip *chip) | |||
5078 | ecc->bytes = 3; | 5106 | ecc->bytes = 3; |
5079 | ecc->strength = 1; | 5107 | ecc->strength = 1; |
5080 | 5108 | ||
5081 | if (IS_ENABLED(CONFIG_MTD_NAND_ECC_SMC)) | 5109 | if (IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC)) |
5082 | ecc->options |= NAND_ECC_SOFT_HAMMING_SM_ORDER; | 5110 | ecc->options |= NAND_ECC_SOFT_HAMMING_SM_ORDER; |
5083 | 5111 | ||
5084 | return 0; | 5112 | return 0; |
5085 | case NAND_ECC_BCH: | 5113 | case NAND_ECC_BCH: |
5086 | if (!mtd_nand_has_bch()) { | 5114 | if (!mtd_nand_has_bch()) { |
5087 | WARN(1, "CONFIG_MTD_NAND_ECC_BCH not enabled\n"); | 5115 | WARN(1, "CONFIG_MTD_NAND_ECC_SW_BCH not enabled\n"); |
5088 | return -EINVAL; | 5116 | return -EINVAL; |
5089 | } | 5117 | } |
5090 | ecc->calculate = nand_bch_calculate_ecc; | 5118 | ecc->calculate = nand_bch_calculate_ecc; |
@@ -5224,8 +5252,8 @@ nand_match_ecc_req(struct nand_chip *chip, | |||
5224 | { | 5252 | { |
5225 | struct mtd_info *mtd = nand_to_mtd(chip); | 5253 | struct mtd_info *mtd = nand_to_mtd(chip); |
5226 | const struct nand_ecc_step_info *stepinfo; | 5254 | const struct nand_ecc_step_info *stepinfo; |
5227 | int req_step = chip->ecc_step_ds; | 5255 | int req_step = chip->base.eccreq.step_size; |
5228 | int req_strength = chip->ecc_strength_ds; | 5256 | int req_strength = chip->base.eccreq.strength; |
5229 | int req_corr, step_size, strength, nsteps, ecc_bytes, ecc_bytes_total; | 5257 | int req_corr, step_size, strength, nsteps, ecc_bytes, ecc_bytes_total; |
5230 | int best_step, best_strength, best_ecc_bytes; | 5258 | int best_step, best_strength, best_ecc_bytes; |
5231 | int best_ecc_bytes_total = INT_MAX; | 5259 | int best_ecc_bytes_total = INT_MAX; |
@@ -5418,7 +5446,7 @@ static bool nand_ecc_strength_good(struct nand_chip *chip) | |||
5418 | struct nand_ecc_ctrl *ecc = &chip->ecc; | 5446 | struct nand_ecc_ctrl *ecc = &chip->ecc; |
5419 | int corr, ds_corr; | 5447 | int corr, ds_corr; |
5420 | 5448 | ||
5421 | if (ecc->size == 0 || chip->ecc_step_ds == 0) | 5449 | if (ecc->size == 0 || chip->base.eccreq.step_size == 0) |
5422 | /* Not enough information */ | 5450 | /* Not enough information */ |
5423 | return true; | 5451 | return true; |
5424 | 5452 | ||
@@ -5427,11 +5455,56 @@ static bool nand_ecc_strength_good(struct nand_chip *chip) | |||
5427 | * the correction density. | 5455 | * the correction density. |
5428 | */ | 5456 | */ |
5429 | corr = (mtd->writesize * ecc->strength) / ecc->size; | 5457 | corr = (mtd->writesize * ecc->strength) / ecc->size; |
5430 | ds_corr = (mtd->writesize * chip->ecc_strength_ds) / chip->ecc_step_ds; | 5458 | ds_corr = (mtd->writesize * chip->base.eccreq.strength) / |
5459 | chip->base.eccreq.step_size; | ||
5431 | 5460 | ||
5432 | return corr >= ds_corr && ecc->strength >= chip->ecc_strength_ds; | 5461 | return corr >= ds_corr && ecc->strength >= chip->base.eccreq.strength; |
5433 | } | 5462 | } |
5434 | 5463 | ||
5464 | static int rawnand_erase(struct nand_device *nand, const struct nand_pos *pos) | ||
5465 | { | ||
5466 | struct nand_chip *chip = container_of(nand, struct nand_chip, | ||
5467 | base); | ||
5468 | unsigned int eb = nanddev_pos_to_row(nand, pos); | ||
5469 | int ret; | ||
5470 | |||
5471 | eb >>= nand->rowconv.eraseblock_addr_shift; | ||
5472 | |||
5473 | nand_select_target(chip, pos->target); | ||
5474 | ret = nand_erase_op(chip, eb); | ||
5475 | nand_deselect_target(chip); | ||
5476 | |||
5477 | return ret; | ||
5478 | } | ||
5479 | |||
5480 | static int rawnand_markbad(struct nand_device *nand, | ||
5481 | const struct nand_pos *pos) | ||
5482 | { | ||
5483 | struct nand_chip *chip = container_of(nand, struct nand_chip, | ||
5484 | base); | ||
5485 | |||
5486 | return nand_markbad_bbm(chip, nanddev_pos_to_offs(nand, pos)); | ||
5487 | } | ||
5488 | |||
5489 | static bool rawnand_isbad(struct nand_device *nand, const struct nand_pos *pos) | ||
5490 | { | ||
5491 | struct nand_chip *chip = container_of(nand, struct nand_chip, | ||
5492 | base); | ||
5493 | int ret; | ||
5494 | |||
5495 | nand_select_target(chip, pos->target); | ||
5496 | ret = nand_isbad_bbm(chip, nanddev_pos_to_offs(nand, pos)); | ||
5497 | nand_deselect_target(chip); | ||
5498 | |||
5499 | return ret; | ||
5500 | } | ||
5501 | |||
5502 | static const struct nand_ops rawnand_ops = { | ||
5503 | .erase = rawnand_erase, | ||
5504 | .markbad = rawnand_markbad, | ||
5505 | .isbad = rawnand_isbad, | ||
5506 | }; | ||
5507 | |||
5435 | /** | 5508 | /** |
5436 | * nand_scan_tail - Scan for the NAND device | 5509 | * nand_scan_tail - Scan for the NAND device |
5437 | * @chip: NAND chip object | 5510 | * @chip: NAND chip object |
@@ -5687,7 +5760,7 @@ static int nand_scan_tail(struct nand_chip *chip) | |||
5687 | chip->subpagesize = mtd->writesize >> mtd->subpage_sft; | 5760 | chip->subpagesize = mtd->writesize >> mtd->subpage_sft; |
5688 | 5761 | ||
5689 | /* Invalidate the pagebuffer reference */ | 5762 | /* Invalidate the pagebuffer reference */ |
5690 | chip->pagebuf = -1; | 5763 | chip->pagecache.page = -1; |
5691 | 5764 | ||
5692 | /* Large page NAND with SOFT_ECC should support subpage reads */ | 5765 | /* Large page NAND with SOFT_ECC should support subpage reads */ |
5693 | switch (ecc->mode) { | 5766 | switch (ecc->mode) { |
@@ -5700,10 +5773,15 @@ static int nand_scan_tail(struct nand_chip *chip) | |||
5700 | break; | 5773 | break; |
5701 | } | 5774 | } |
5702 | 5775 | ||
5776 | ret = nanddev_init(&chip->base, &rawnand_ops, mtd->owner); | ||
5777 | if (ret) | ||
5778 | goto err_nand_manuf_cleanup; | ||
5779 | |||
5780 | /* Adjust the MTD_CAP_ flags when NAND_ROM is set. */ | ||
5781 | if (chip->options & NAND_ROM) | ||
5782 | mtd->flags = MTD_CAP_ROM; | ||
5783 | |||
5703 | /* Fill in remaining MTD driver data */ | 5784 | /* Fill in remaining MTD driver data */ |
5704 | mtd->type = nand_is_slc(chip) ? MTD_NANDFLASH : MTD_MLCNANDFLASH; | ||
5705 | mtd->flags = (chip->options & NAND_ROM) ? MTD_CAP_ROM : | ||
5706 | MTD_CAP_NANDFLASH; | ||
5707 | mtd->_erase = nand_erase; | 5785 | mtd->_erase = nand_erase; |
5708 | mtd->_point = NULL; | 5786 | mtd->_point = NULL; |
5709 | mtd->_unpoint = NULL; | 5787 | mtd->_unpoint = NULL; |
@@ -5719,8 +5797,7 @@ static int nand_scan_tail(struct nand_chip *chip) | |||
5719 | mtd->_block_isreserved = nand_block_isreserved; | 5797 | mtd->_block_isreserved = nand_block_isreserved; |
5720 | mtd->_block_isbad = nand_block_isbad; | 5798 | mtd->_block_isbad = nand_block_isbad; |
5721 | mtd->_block_markbad = nand_block_markbad; | 5799 | mtd->_block_markbad = nand_block_markbad; |
5722 | mtd->_max_bad_blocks = nand_max_bad_blocks; | 5800 | mtd->_max_bad_blocks = nanddev_mtd_max_bad_blocks; |
5723 | mtd->writebufsize = mtd->writesize; | ||
5724 | 5801 | ||
5725 | /* | 5802 | /* |
5726 | * Initialize bitflip_threshold to its default prior scan_bbt() call. | 5803 | * Initialize bitflip_threshold to its default prior scan_bbt() call. |
@@ -5733,13 +5810,13 @@ static int nand_scan_tail(struct nand_chip *chip) | |||
5733 | /* Initialize the ->data_interface field. */ | 5810 | /* Initialize the ->data_interface field. */ |
5734 | ret = nand_init_data_interface(chip); | 5811 | ret = nand_init_data_interface(chip); |
5735 | if (ret) | 5812 | if (ret) |
5736 | goto err_nand_manuf_cleanup; | 5813 | goto err_nanddev_cleanup; |
5737 | 5814 | ||
5738 | /* Enter fastest possible mode on all dies. */ | 5815 | /* Enter fastest possible mode on all dies. */ |
5739 | for (i = 0; i < chip->numchips; i++) { | 5816 | for (i = 0; i < nanddev_ntargets(&chip->base); i++) { |
5740 | ret = nand_setup_data_interface(chip, i); | 5817 | ret = nand_setup_data_interface(chip, i); |
5741 | if (ret) | 5818 | if (ret) |
5742 | goto err_nand_manuf_cleanup; | 5819 | goto err_nanddev_cleanup; |
5743 | } | 5820 | } |
5744 | 5821 | ||
5745 | /* Check, if we should skip the bad block table scan */ | 5822 | /* Check, if we should skip the bad block table scan */ |
@@ -5749,11 +5826,14 @@ static int nand_scan_tail(struct nand_chip *chip) | |||
5749 | /* Build bad block table */ | 5826 | /* Build bad block table */ |
5750 | ret = nand_create_bbt(chip); | 5827 | ret = nand_create_bbt(chip); |
5751 | if (ret) | 5828 | if (ret) |
5752 | goto err_nand_manuf_cleanup; | 5829 | goto err_nanddev_cleanup; |
5753 | 5830 | ||
5754 | return 0; | 5831 | return 0; |
5755 | 5832 | ||
5756 | 5833 | ||
5834 | err_nanddev_cleanup: | ||
5835 | nanddev_cleanup(&chip->base); | ||
5836 | |||
5757 | err_nand_manuf_cleanup: | 5837 | err_nand_manuf_cleanup: |
5758 | nand_manufacturer_cleanup(chip); | 5838 | nand_manufacturer_cleanup(chip); |
5759 | 5839 | ||
diff --git a/drivers/mtd/nand/raw/nand_bbt.c b/drivers/mtd/nand/raw/nand_bbt.c index 19a2b563acdf..fd3c10216eda 100644 --- a/drivers/mtd/nand/raw/nand_bbt.c +++ b/drivers/mtd/nand/raw/nand_bbt.c | |||
@@ -264,18 +264,19 @@ static int read_abs_bbt(struct nand_chip *this, uint8_t *buf, | |||
264 | struct nand_bbt_descr *td, int chip) | 264 | struct nand_bbt_descr *td, int chip) |
265 | { | 265 | { |
266 | struct mtd_info *mtd = nand_to_mtd(this); | 266 | struct mtd_info *mtd = nand_to_mtd(this); |
267 | u64 targetsize = nanddev_target_size(&this->base); | ||
267 | int res = 0, i; | 268 | int res = 0, i; |
268 | 269 | ||
269 | if (td->options & NAND_BBT_PERCHIP) { | 270 | if (td->options & NAND_BBT_PERCHIP) { |
270 | int offs = 0; | 271 | int offs = 0; |
271 | for (i = 0; i < this->numchips; i++) { | 272 | for (i = 0; i < nanddev_ntargets(&this->base); i++) { |
272 | if (chip == -1 || chip == i) | 273 | if (chip == -1 || chip == i) |
273 | res = read_bbt(this, buf, td->pages[i], | 274 | res = read_bbt(this, buf, td->pages[i], |
274 | this->chipsize >> this->bbt_erase_shift, | 275 | targetsize >> this->bbt_erase_shift, |
275 | td, offs); | 276 | td, offs); |
276 | if (res) | 277 | if (res) |
277 | return res; | 278 | return res; |
278 | offs += this->chipsize >> this->bbt_erase_shift; | 279 | offs += targetsize >> this->bbt_erase_shift; |
279 | } | 280 | } |
280 | } else { | 281 | } else { |
281 | res = read_bbt(this, buf, td->pages[0], | 282 | res = read_bbt(this, buf, td->pages[0], |
@@ -415,11 +416,12 @@ static void read_abs_bbts(struct nand_chip *this, uint8_t *buf, | |||
415 | 416 | ||
416 | /* Scan a given block partially */ | 417 | /* Scan a given block partially */ |
417 | static int scan_block_fast(struct nand_chip *this, struct nand_bbt_descr *bd, | 418 | static int scan_block_fast(struct nand_chip *this, struct nand_bbt_descr *bd, |
418 | loff_t offs, uint8_t *buf, int numpages) | 419 | loff_t offs, uint8_t *buf) |
419 | { | 420 | { |
420 | struct mtd_info *mtd = nand_to_mtd(this); | 421 | struct mtd_info *mtd = nand_to_mtd(this); |
422 | |||
421 | struct mtd_oob_ops ops; | 423 | struct mtd_oob_ops ops; |
422 | int j, ret; | 424 | int ret, page_offset; |
423 | 425 | ||
424 | ops.ooblen = mtd->oobsize; | 426 | ops.ooblen = mtd->oobsize; |
425 | ops.oobbuf = buf; | 427 | ops.oobbuf = buf; |
@@ -427,12 +429,15 @@ static int scan_block_fast(struct nand_chip *this, struct nand_bbt_descr *bd, | |||
427 | ops.datbuf = NULL; | 429 | ops.datbuf = NULL; |
428 | ops.mode = MTD_OPS_PLACE_OOB; | 430 | ops.mode = MTD_OPS_PLACE_OOB; |
429 | 431 | ||
430 | for (j = 0; j < numpages; j++) { | 432 | page_offset = nand_bbm_get_next_page(this, 0); |
433 | |||
434 | while (page_offset >= 0) { | ||
431 | /* | 435 | /* |
432 | * Read the full oob until read_oob is fixed to handle single | 436 | * Read the full oob until read_oob is fixed to handle single |
433 | * byte reads for 16 bit buswidth. | 437 | * byte reads for 16 bit buswidth. |
434 | */ | 438 | */ |
435 | ret = mtd_read_oob(mtd, offs, &ops); | 439 | ret = mtd_read_oob(mtd, offs + (page_offset * mtd->writesize), |
440 | &ops); | ||
436 | /* Ignore ECC errors when checking for BBM */ | 441 | /* Ignore ECC errors when checking for BBM */ |
437 | if (ret && !mtd_is_bitflip_or_eccerr(ret)) | 442 | if (ret && !mtd_is_bitflip_or_eccerr(ret)) |
438 | return ret; | 443 | return ret; |
@@ -440,8 +445,9 @@ static int scan_block_fast(struct nand_chip *this, struct nand_bbt_descr *bd, | |||
440 | if (check_short_pattern(buf, bd)) | 445 | if (check_short_pattern(buf, bd)) |
441 | return 1; | 446 | return 1; |
442 | 447 | ||
443 | offs += mtd->writesize; | 448 | page_offset = nand_bbm_get_next_page(this, page_offset + 1); |
444 | } | 449 | } |
450 | |||
445 | return 0; | 451 | return 0; |
446 | } | 452 | } |
447 | 453 | ||
@@ -459,43 +465,35 @@ static int scan_block_fast(struct nand_chip *this, struct nand_bbt_descr *bd, | |||
459 | static int create_bbt(struct nand_chip *this, uint8_t *buf, | 465 | static int create_bbt(struct nand_chip *this, uint8_t *buf, |
460 | struct nand_bbt_descr *bd, int chip) | 466 | struct nand_bbt_descr *bd, int chip) |
461 | { | 467 | { |
468 | u64 targetsize = nanddev_target_size(&this->base); | ||
462 | struct mtd_info *mtd = nand_to_mtd(this); | 469 | struct mtd_info *mtd = nand_to_mtd(this); |
463 | int i, numblocks, numpages; | 470 | int i, numblocks, startblock; |
464 | int startblock; | ||
465 | loff_t from; | 471 | loff_t from; |
466 | 472 | ||
467 | pr_info("Scanning device for bad blocks\n"); | 473 | pr_info("Scanning device for bad blocks\n"); |
468 | 474 | ||
469 | if (bd->options & NAND_BBT_SCAN2NDPAGE) | ||
470 | numpages = 2; | ||
471 | else | ||
472 | numpages = 1; | ||
473 | |||
474 | if (chip == -1) { | 475 | if (chip == -1) { |
475 | numblocks = mtd->size >> this->bbt_erase_shift; | 476 | numblocks = mtd->size >> this->bbt_erase_shift; |
476 | startblock = 0; | 477 | startblock = 0; |
477 | from = 0; | 478 | from = 0; |
478 | } else { | 479 | } else { |
479 | if (chip >= this->numchips) { | 480 | if (chip >= nanddev_ntargets(&this->base)) { |
480 | pr_warn("create_bbt(): chipnr (%d) > available chips (%d)\n", | 481 | pr_warn("create_bbt(): chipnr (%d) > available chips (%d)\n", |
481 | chip + 1, this->numchips); | 482 | chip + 1, nanddev_ntargets(&this->base)); |
482 | return -EINVAL; | 483 | return -EINVAL; |
483 | } | 484 | } |
484 | numblocks = this->chipsize >> this->bbt_erase_shift; | 485 | numblocks = targetsize >> this->bbt_erase_shift; |
485 | startblock = chip * numblocks; | 486 | startblock = chip * numblocks; |
486 | numblocks += startblock; | 487 | numblocks += startblock; |
487 | from = (loff_t)startblock << this->bbt_erase_shift; | 488 | from = (loff_t)startblock << this->bbt_erase_shift; |
488 | } | 489 | } |
489 | 490 | ||
490 | if (this->bbt_options & NAND_BBT_SCANLASTPAGE) | ||
491 | from += mtd->erasesize - (mtd->writesize * numpages); | ||
492 | |||
493 | for (i = startblock; i < numblocks; i++) { | 491 | for (i = startblock; i < numblocks; i++) { |
494 | int ret; | 492 | int ret; |
495 | 493 | ||
496 | BUG_ON(bd->options & NAND_BBT_NO_OOB); | 494 | BUG_ON(bd->options & NAND_BBT_NO_OOB); |
497 | 495 | ||
498 | ret = scan_block_fast(this, bd, from, buf, numpages); | 496 | ret = scan_block_fast(this, bd, from, buf); |
499 | if (ret < 0) | 497 | if (ret < 0) |
500 | return ret; | 498 | return ret; |
501 | 499 | ||
@@ -529,6 +527,7 @@ static int create_bbt(struct nand_chip *this, uint8_t *buf, | |||
529 | static int search_bbt(struct nand_chip *this, uint8_t *buf, | 527 | static int search_bbt(struct nand_chip *this, uint8_t *buf, |
530 | struct nand_bbt_descr *td) | 528 | struct nand_bbt_descr *td) |
531 | { | 529 | { |
530 | u64 targetsize = nanddev_target_size(&this->base); | ||
532 | struct mtd_info *mtd = nand_to_mtd(this); | 531 | struct mtd_info *mtd = nand_to_mtd(this); |
533 | int i, chips; | 532 | int i, chips; |
534 | int startblock, block, dir; | 533 | int startblock, block, dir; |
@@ -547,8 +546,8 @@ static int search_bbt(struct nand_chip *this, uint8_t *buf, | |||
547 | 546 | ||
548 | /* Do we have a bbt per chip? */ | 547 | /* Do we have a bbt per chip? */ |
549 | if (td->options & NAND_BBT_PERCHIP) { | 548 | if (td->options & NAND_BBT_PERCHIP) { |
550 | chips = this->numchips; | 549 | chips = nanddev_ntargets(&this->base); |
551 | bbtblocks = this->chipsize >> this->bbt_erase_shift; | 550 | bbtblocks = targetsize >> this->bbt_erase_shift; |
552 | startblock &= bbtblocks - 1; | 551 | startblock &= bbtblocks - 1; |
553 | } else { | 552 | } else { |
554 | chips = 1; | 553 | chips = 1; |
@@ -576,7 +575,7 @@ static int search_bbt(struct nand_chip *this, uint8_t *buf, | |||
576 | break; | 575 | break; |
577 | } | 576 | } |
578 | } | 577 | } |
579 | startblock += this->chipsize >> this->bbt_erase_shift; | 578 | startblock += targetsize >> this->bbt_erase_shift; |
580 | } | 579 | } |
581 | /* Check, if we found a bbt for each requested chip */ | 580 | /* Check, if we found a bbt for each requested chip */ |
582 | for (i = 0; i < chips; i++) { | 581 | for (i = 0; i < chips; i++) { |
@@ -626,6 +625,7 @@ static void search_read_bbts(struct nand_chip *this, uint8_t *buf, | |||
626 | static int get_bbt_block(struct nand_chip *this, struct nand_bbt_descr *td, | 625 | static int get_bbt_block(struct nand_chip *this, struct nand_bbt_descr *td, |
627 | struct nand_bbt_descr *md, int chip) | 626 | struct nand_bbt_descr *md, int chip) |
628 | { | 627 | { |
628 | u64 targetsize = nanddev_target_size(&this->base); | ||
629 | int startblock, dir, page, numblocks, i; | 629 | int startblock, dir, page, numblocks, i; |
630 | 630 | ||
631 | /* | 631 | /* |
@@ -637,9 +637,9 @@ static int get_bbt_block(struct nand_chip *this, struct nand_bbt_descr *td, | |||
637 | return td->pages[chip] >> | 637 | return td->pages[chip] >> |
638 | (this->bbt_erase_shift - this->page_shift); | 638 | (this->bbt_erase_shift - this->page_shift); |
639 | 639 | ||
640 | numblocks = (int)(this->chipsize >> this->bbt_erase_shift); | 640 | numblocks = (int)(targetsize >> this->bbt_erase_shift); |
641 | if (!(td->options & NAND_BBT_PERCHIP)) | 641 | if (!(td->options & NAND_BBT_PERCHIP)) |
642 | numblocks *= this->numchips; | 642 | numblocks *= nanddev_ntargets(&this->base); |
643 | 643 | ||
644 | /* | 644 | /* |
645 | * Automatic placement of the bad block table. Search direction | 645 | * Automatic placement of the bad block table. Search direction |
@@ -717,6 +717,7 @@ static int write_bbt(struct nand_chip *this, uint8_t *buf, | |||
717 | struct nand_bbt_descr *td, struct nand_bbt_descr *md, | 717 | struct nand_bbt_descr *td, struct nand_bbt_descr *md, |
718 | int chipsel) | 718 | int chipsel) |
719 | { | 719 | { |
720 | u64 targetsize = nanddev_target_size(&this->base); | ||
720 | struct mtd_info *mtd = nand_to_mtd(this); | 721 | struct mtd_info *mtd = nand_to_mtd(this); |
721 | struct erase_info einfo; | 722 | struct erase_info einfo; |
722 | int i, res, chip = 0; | 723 | int i, res, chip = 0; |
@@ -737,10 +738,10 @@ static int write_bbt(struct nand_chip *this, uint8_t *buf, | |||
737 | rcode = 0xff; | 738 | rcode = 0xff; |
738 | /* Write bad block table per chip rather than per device? */ | 739 | /* Write bad block table per chip rather than per device? */ |
739 | if (td->options & NAND_BBT_PERCHIP) { | 740 | if (td->options & NAND_BBT_PERCHIP) { |
740 | numblocks = (int)(this->chipsize >> this->bbt_erase_shift); | 741 | numblocks = (int)(targetsize >> this->bbt_erase_shift); |
741 | /* Full device write or specific chip? */ | 742 | /* Full device write or specific chip? */ |
742 | if (chipsel == -1) { | 743 | if (chipsel == -1) { |
743 | nrchips = this->numchips; | 744 | nrchips = nanddev_ntargets(&this->base); |
744 | } else { | 745 | } else { |
745 | nrchips = chipsel + 1; | 746 | nrchips = chipsel + 1; |
746 | chip = chipsel; | 747 | chip = chipsel; |
@@ -901,7 +902,9 @@ static int write_bbt(struct nand_chip *this, uint8_t *buf, | |||
901 | static inline int nand_memory_bbt(struct nand_chip *this, | 902 | static inline int nand_memory_bbt(struct nand_chip *this, |
902 | struct nand_bbt_descr *bd) | 903 | struct nand_bbt_descr *bd) |
903 | { | 904 | { |
904 | return create_bbt(this, this->data_buf, bd, -1); | 905 | u8 *pagebuf = nand_get_data_buf(this); |
906 | |||
907 | return create_bbt(this, pagebuf, bd, -1); | ||
905 | } | 908 | } |
906 | 909 | ||
907 | /** | 910 | /** |
@@ -925,7 +928,7 @@ static int check_create(struct nand_chip *this, uint8_t *buf, | |||
925 | 928 | ||
926 | /* Do we have a bbt per chip? */ | 929 | /* Do we have a bbt per chip? */ |
927 | if (td->options & NAND_BBT_PERCHIP) | 930 | if (td->options & NAND_BBT_PERCHIP) |
928 | chips = this->numchips; | 931 | chips = nanddev_ntargets(&this->base); |
929 | else | 932 | else |
930 | chips = 1; | 933 | chips = 1; |
931 | 934 | ||
@@ -1097,14 +1100,15 @@ static int nand_update_bbt(struct nand_chip *this, loff_t offs) | |||
1097 | */ | 1100 | */ |
1098 | static void mark_bbt_region(struct nand_chip *this, struct nand_bbt_descr *td) | 1101 | static void mark_bbt_region(struct nand_chip *this, struct nand_bbt_descr *td) |
1099 | { | 1102 | { |
1103 | u64 targetsize = nanddev_target_size(&this->base); | ||
1100 | struct mtd_info *mtd = nand_to_mtd(this); | 1104 | struct mtd_info *mtd = nand_to_mtd(this); |
1101 | int i, j, chips, block, nrblocks, update; | 1105 | int i, j, chips, block, nrblocks, update; |
1102 | uint8_t oldval; | 1106 | uint8_t oldval; |
1103 | 1107 | ||
1104 | /* Do we have a bbt per chip? */ | 1108 | /* Do we have a bbt per chip? */ |
1105 | if (td->options & NAND_BBT_PERCHIP) { | 1109 | if (td->options & NAND_BBT_PERCHIP) { |
1106 | chips = this->numchips; | 1110 | chips = nanddev_ntargets(&this->base); |
1107 | nrblocks = (int)(this->chipsize >> this->bbt_erase_shift); | 1111 | nrblocks = (int)(targetsize >> this->bbt_erase_shift); |
1108 | } else { | 1112 | } else { |
1109 | chips = 1; | 1113 | chips = 1; |
1110 | nrblocks = (int)(mtd->size >> this->bbt_erase_shift); | 1114 | nrblocks = (int)(mtd->size >> this->bbt_erase_shift); |
@@ -1157,6 +1161,7 @@ static void mark_bbt_region(struct nand_chip *this, struct nand_bbt_descr *td) | |||
1157 | */ | 1161 | */ |
1158 | static void verify_bbt_descr(struct nand_chip *this, struct nand_bbt_descr *bd) | 1162 | static void verify_bbt_descr(struct nand_chip *this, struct nand_bbt_descr *bd) |
1159 | { | 1163 | { |
1164 | u64 targetsize = nanddev_target_size(&this->base); | ||
1160 | struct mtd_info *mtd = nand_to_mtd(this); | 1165 | struct mtd_info *mtd = nand_to_mtd(this); |
1161 | u32 pattern_len; | 1166 | u32 pattern_len; |
1162 | u32 bits; | 1167 | u32 bits; |
@@ -1185,7 +1190,7 @@ static void verify_bbt_descr(struct nand_chip *this, struct nand_bbt_descr *bd) | |||
1185 | } | 1190 | } |
1186 | 1191 | ||
1187 | if (bd->options & NAND_BBT_PERCHIP) | 1192 | if (bd->options & NAND_BBT_PERCHIP) |
1188 | table_size = this->chipsize >> this->bbt_erase_shift; | 1193 | table_size = targetsize >> this->bbt_erase_shift; |
1189 | else | 1194 | else |
1190 | table_size = mtd->size >> this->bbt_erase_shift; | 1195 | table_size = mtd->size >> this->bbt_erase_shift; |
1191 | table_size >>= 3; | 1196 | table_size >>= 3; |
diff --git a/drivers/mtd/nand/raw/nand_esmt.c b/drivers/mtd/nand/raw/nand_esmt.c index 96f039a83bc8..3338c68aaaf1 100644 --- a/drivers/mtd/nand/raw/nand_esmt.c +++ b/drivers/mtd/nand/raw/nand_esmt.c | |||
@@ -14,20 +14,20 @@ static void esmt_nand_decode_id(struct nand_chip *chip) | |||
14 | 14 | ||
15 | /* Extract ECC requirements from 5th id byte. */ | 15 | /* Extract ECC requirements from 5th id byte. */ |
16 | if (chip->id.len >= 5 && nand_is_slc(chip)) { | 16 | if (chip->id.len >= 5 && nand_is_slc(chip)) { |
17 | chip->ecc_step_ds = 512; | 17 | chip->base.eccreq.step_size = 512; |
18 | switch (chip->id.data[4] & 0x3) { | 18 | switch (chip->id.data[4] & 0x3) { |
19 | case 0x0: | 19 | case 0x0: |
20 | chip->ecc_strength_ds = 4; | 20 | chip->base.eccreq.strength = 4; |
21 | break; | 21 | break; |
22 | case 0x1: | 22 | case 0x1: |
23 | chip->ecc_strength_ds = 2; | 23 | chip->base.eccreq.strength = 2; |
24 | break; | 24 | break; |
25 | case 0x2: | 25 | case 0x2: |
26 | chip->ecc_strength_ds = 1; | 26 | chip->base.eccreq.strength = 1; |
27 | break; | 27 | break; |
28 | default: | 28 | default: |
29 | WARN(1, "Could not get ECC info"); | 29 | WARN(1, "Could not get ECC info"); |
30 | chip->ecc_step_ds = 0; | 30 | chip->base.eccreq.step_size = 0; |
31 | break; | 31 | break; |
32 | } | 32 | } |
33 | } | 33 | } |
@@ -36,7 +36,14 @@ static void esmt_nand_decode_id(struct nand_chip *chip) | |||
36 | static int esmt_nand_init(struct nand_chip *chip) | 36 | static int esmt_nand_init(struct nand_chip *chip) |
37 | { | 37 | { |
38 | if (nand_is_slc(chip)) | 38 | if (nand_is_slc(chip)) |
39 | chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; | 39 | /* |
40 | * It is known that some ESMT SLC NANDs have been shipped | ||
41 | * with the factory bad block markers in the first or last page | ||
42 | * of the block, instead of the first or second page. To be on | ||
43 | * the safe side, let's check all three locations. | ||
44 | */ | ||
45 | chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE | | ||
46 | NAND_BBM_LASTPAGE; | ||
40 | 47 | ||
41 | return 0; | 48 | return 0; |
42 | } | 49 | } |
diff --git a/drivers/mtd/nand/raw/nand_hynix.c b/drivers/mtd/nand/raw/nand_hynix.c index 343f477362d1..7c600c4d5ec8 100644 --- a/drivers/mtd/nand/raw/nand_hynix.c +++ b/drivers/mtd/nand/raw/nand_hynix.c | |||
@@ -418,24 +418,27 @@ static void hynix_nand_extract_oobsize(struct nand_chip *chip, | |||
418 | bool valid_jedecid) | 418 | bool valid_jedecid) |
419 | { | 419 | { |
420 | struct mtd_info *mtd = nand_to_mtd(chip); | 420 | struct mtd_info *mtd = nand_to_mtd(chip); |
421 | struct nand_memory_organization *memorg; | ||
421 | u8 oobsize; | 422 | u8 oobsize; |
422 | 423 | ||
424 | memorg = nanddev_get_memorg(&chip->base); | ||
425 | |||
423 | oobsize = ((chip->id.data[3] >> 2) & 0x3) | | 426 | oobsize = ((chip->id.data[3] >> 2) & 0x3) | |
424 | ((chip->id.data[3] >> 4) & 0x4); | 427 | ((chip->id.data[3] >> 4) & 0x4); |
425 | 428 | ||
426 | if (valid_jedecid) { | 429 | if (valid_jedecid) { |
427 | switch (oobsize) { | 430 | switch (oobsize) { |
428 | case 0: | 431 | case 0: |
429 | mtd->oobsize = 2048; | 432 | memorg->oobsize = 2048; |
430 | break; | 433 | break; |
431 | case 1: | 434 | case 1: |
432 | mtd->oobsize = 1664; | 435 | memorg->oobsize = 1664; |
433 | break; | 436 | break; |
434 | case 2: | 437 | case 2: |
435 | mtd->oobsize = 1024; | 438 | memorg->oobsize = 1024; |
436 | break; | 439 | break; |
437 | case 3: | 440 | case 3: |
438 | mtd->oobsize = 640; | 441 | memorg->oobsize = 640; |
439 | break; | 442 | break; |
440 | default: | 443 | default: |
441 | /* | 444 | /* |
@@ -450,25 +453,25 @@ static void hynix_nand_extract_oobsize(struct nand_chip *chip, | |||
450 | } else { | 453 | } else { |
451 | switch (oobsize) { | 454 | switch (oobsize) { |
452 | case 0: | 455 | case 0: |
453 | mtd->oobsize = 128; | 456 | memorg->oobsize = 128; |
454 | break; | 457 | break; |
455 | case 1: | 458 | case 1: |
456 | mtd->oobsize = 224; | 459 | memorg->oobsize = 224; |
457 | break; | 460 | break; |
458 | case 2: | 461 | case 2: |
459 | mtd->oobsize = 448; | 462 | memorg->oobsize = 448; |
460 | break; | 463 | break; |
461 | case 3: | 464 | case 3: |
462 | mtd->oobsize = 64; | 465 | memorg->oobsize = 64; |
463 | break; | 466 | break; |
464 | case 4: | 467 | case 4: |
465 | mtd->oobsize = 32; | 468 | memorg->oobsize = 32; |
466 | break; | 469 | break; |
467 | case 5: | 470 | case 5: |
468 | mtd->oobsize = 16; | 471 | memorg->oobsize = 16; |
469 | break; | 472 | break; |
470 | case 6: | 473 | case 6: |
471 | mtd->oobsize = 640; | 474 | memorg->oobsize = 640; |
472 | break; | 475 | break; |
473 | default: | 476 | default: |
474 | /* | 477 | /* |
@@ -492,8 +495,10 @@ static void hynix_nand_extract_oobsize(struct nand_chip *chip, | |||
492 | * the actual OOB size for this chip is: 640 * 16k / 8k). | 495 | * the actual OOB size for this chip is: 640 * 16k / 8k). |
493 | */ | 496 | */ |
494 | if (chip->id.data[1] == 0xde) | 497 | if (chip->id.data[1] == 0xde) |
495 | mtd->oobsize *= mtd->writesize / SZ_8K; | 498 | memorg->oobsize *= memorg->pagesize / SZ_8K; |
496 | } | 499 | } |
500 | |||
501 | mtd->oobsize = memorg->oobsize; | ||
497 | } | 502 | } |
498 | 503 | ||
499 | static void hynix_nand_extract_ecc_requirements(struct nand_chip *chip, | 504 | static void hynix_nand_extract_ecc_requirements(struct nand_chip *chip, |
@@ -503,30 +508,30 @@ static void hynix_nand_extract_ecc_requirements(struct nand_chip *chip, | |||
503 | 508 | ||
504 | if (valid_jedecid) { | 509 | if (valid_jedecid) { |
505 | /* Reference: H27UCG8T2E datasheet */ | 510 | /* Reference: H27UCG8T2E datasheet */ |
506 | chip->ecc_step_ds = 1024; | 511 | chip->base.eccreq.step_size = 1024; |
507 | 512 | ||
508 | switch (ecc_level) { | 513 | switch (ecc_level) { |
509 | case 0: | 514 | case 0: |
510 | chip->ecc_step_ds = 0; | 515 | chip->base.eccreq.step_size = 0; |
511 | chip->ecc_strength_ds = 0; | 516 | chip->base.eccreq.strength = 0; |
512 | break; | 517 | break; |
513 | case 1: | 518 | case 1: |
514 | chip->ecc_strength_ds = 4; | 519 | chip->base.eccreq.strength = 4; |
515 | break; | 520 | break; |
516 | case 2: | 521 | case 2: |
517 | chip->ecc_strength_ds = 24; | 522 | chip->base.eccreq.strength = 24; |
518 | break; | 523 | break; |
519 | case 3: | 524 | case 3: |
520 | chip->ecc_strength_ds = 32; | 525 | chip->base.eccreq.strength = 32; |
521 | break; | 526 | break; |
522 | case 4: | 527 | case 4: |
523 | chip->ecc_strength_ds = 40; | 528 | chip->base.eccreq.strength = 40; |
524 | break; | 529 | break; |
525 | case 5: | 530 | case 5: |
526 | chip->ecc_strength_ds = 50; | 531 | chip->base.eccreq.strength = 50; |
527 | break; | 532 | break; |
528 | case 6: | 533 | case 6: |
529 | chip->ecc_strength_ds = 60; | 534 | chip->base.eccreq.strength = 60; |
530 | break; | 535 | break; |
531 | default: | 536 | default: |
532 | /* | 537 | /* |
@@ -547,14 +552,14 @@ static void hynix_nand_extract_ecc_requirements(struct nand_chip *chip, | |||
547 | if (nand_tech < 3) { | 552 | if (nand_tech < 3) { |
548 | /* > 26nm, reference: H27UBG8T2A datasheet */ | 553 | /* > 26nm, reference: H27UBG8T2A datasheet */ |
549 | if (ecc_level < 5) { | 554 | if (ecc_level < 5) { |
550 | chip->ecc_step_ds = 512; | 555 | chip->base.eccreq.step_size = 512; |
551 | chip->ecc_strength_ds = 1 << ecc_level; | 556 | chip->base.eccreq.strength = 1 << ecc_level; |
552 | } else if (ecc_level < 7) { | 557 | } else if (ecc_level < 7) { |
553 | if (ecc_level == 5) | 558 | if (ecc_level == 5) |
554 | chip->ecc_step_ds = 2048; | 559 | chip->base.eccreq.step_size = 2048; |
555 | else | 560 | else |
556 | chip->ecc_step_ds = 1024; | 561 | chip->base.eccreq.step_size = 1024; |
557 | chip->ecc_strength_ds = 24; | 562 | chip->base.eccreq.strength = 24; |
558 | } else { | 563 | } else { |
559 | /* | 564 | /* |
560 | * We should never reach this case, but if that | 565 | * We should never reach this case, but if that |
@@ -567,14 +572,14 @@ static void hynix_nand_extract_ecc_requirements(struct nand_chip *chip, | |||
567 | } else { | 572 | } else { |
568 | /* <= 26nm, reference: H27UBG8T2B datasheet */ | 573 | /* <= 26nm, reference: H27UBG8T2B datasheet */ |
569 | if (!ecc_level) { | 574 | if (!ecc_level) { |
570 | chip->ecc_step_ds = 0; | 575 | chip->base.eccreq.step_size = 0; |
571 | chip->ecc_strength_ds = 0; | 576 | chip->base.eccreq.strength = 0; |
572 | } else if (ecc_level < 5) { | 577 | } else if (ecc_level < 5) { |
573 | chip->ecc_step_ds = 512; | 578 | chip->base.eccreq.step_size = 512; |
574 | chip->ecc_strength_ds = 1 << (ecc_level - 1); | 579 | chip->base.eccreq.strength = 1 << (ecc_level - 1); |
575 | } else { | 580 | } else { |
576 | chip->ecc_step_ds = 1024; | 581 | chip->base.eccreq.step_size = 1024; |
577 | chip->ecc_strength_ds = 24 + | 582 | chip->base.eccreq.strength = 24 + |
578 | (8 * (ecc_level - 5)); | 583 | (8 * (ecc_level - 5)); |
579 | } | 584 | } |
580 | } | 585 | } |
@@ -587,7 +592,7 @@ static void hynix_nand_extract_scrambling_requirements(struct nand_chip *chip, | |||
587 | u8 nand_tech; | 592 | u8 nand_tech; |
588 | 593 | ||
589 | /* We need scrambling on all TLC NANDs*/ | 594 | /* We need scrambling on all TLC NANDs*/ |
590 | if (chip->bits_per_cell > 2) | 595 | if (nanddev_bits_per_cell(&chip->base) > 2) |
591 | chip->options |= NAND_NEED_SCRAMBLING; | 596 | chip->options |= NAND_NEED_SCRAMBLING; |
592 | 597 | ||
593 | /* And on MLC NANDs with sub-3xnm process */ | 598 | /* And on MLC NANDs with sub-3xnm process */ |
@@ -609,9 +614,12 @@ static void hynix_nand_extract_scrambling_requirements(struct nand_chip *chip, | |||
609 | static void hynix_nand_decode_id(struct nand_chip *chip) | 614 | static void hynix_nand_decode_id(struct nand_chip *chip) |
610 | { | 615 | { |
611 | struct mtd_info *mtd = nand_to_mtd(chip); | 616 | struct mtd_info *mtd = nand_to_mtd(chip); |
617 | struct nand_memory_organization *memorg; | ||
612 | bool valid_jedecid; | 618 | bool valid_jedecid; |
613 | u8 tmp; | 619 | u8 tmp; |
614 | 620 | ||
621 | memorg = nanddev_get_memorg(&chip->base); | ||
622 | |||
615 | /* | 623 | /* |
616 | * Exclude all SLC NANDs from this advanced detection scheme. | 624 | * Exclude all SLC NANDs from this advanced detection scheme. |
617 | * According to the ranges defined in several datasheets, it might | 625 | * According to the ranges defined in several datasheets, it might |
@@ -625,7 +633,8 @@ static void hynix_nand_decode_id(struct nand_chip *chip) | |||
625 | } | 633 | } |
626 | 634 | ||
627 | /* Extract pagesize */ | 635 | /* Extract pagesize */ |
628 | mtd->writesize = 2048 << (chip->id.data[3] & 0x03); | 636 | memorg->pagesize = 2048 << (chip->id.data[3] & 0x03); |
637 | mtd->writesize = memorg->pagesize; | ||
629 | 638 | ||
630 | tmp = (chip->id.data[3] >> 4) & 0x3; | 639 | tmp = (chip->id.data[3] >> 4) & 0x3; |
631 | /* | 640 | /* |
@@ -635,12 +644,19 @@ static void hynix_nand_decode_id(struct nand_chip *chip) | |||
635 | * The only exception is when ID[3][4:5] == 3 and ID[3][7] == 0, in | 644 | * The only exception is when ID[3][4:5] == 3 and ID[3][7] == 0, in |
636 | * this case the erasesize is set to 768KiB. | 645 | * this case the erasesize is set to 768KiB. |
637 | */ | 646 | */ |
638 | if (chip->id.data[3] & 0x80) | 647 | if (chip->id.data[3] & 0x80) { |
648 | memorg->pages_per_eraseblock = (SZ_1M << tmp) / | ||
649 | memorg->pagesize; | ||
639 | mtd->erasesize = SZ_1M << tmp; | 650 | mtd->erasesize = SZ_1M << tmp; |
640 | else if (tmp == 3) | 651 | } else if (tmp == 3) { |
652 | memorg->pages_per_eraseblock = (SZ_512K + SZ_256K) / | ||
653 | memorg->pagesize; | ||
641 | mtd->erasesize = SZ_512K + SZ_256K; | 654 | mtd->erasesize = SZ_512K + SZ_256K; |
642 | else | 655 | } else { |
656 | memorg->pages_per_eraseblock = (SZ_128K << tmp) / | ||
657 | memorg->pagesize; | ||
643 | mtd->erasesize = SZ_128K << tmp; | 658 | mtd->erasesize = SZ_128K << tmp; |
659 | } | ||
644 | 660 | ||
645 | /* | 661 | /* |
646 | * Modern Toggle DDR NANDs have a valid JEDECID even though they are | 662 | * Modern Toggle DDR NANDs have a valid JEDECID even though they are |
@@ -672,9 +688,9 @@ static int hynix_nand_init(struct nand_chip *chip) | |||
672 | int ret; | 688 | int ret; |
673 | 689 | ||
674 | if (!nand_is_slc(chip)) | 690 | if (!nand_is_slc(chip)) |
675 | chip->bbt_options |= NAND_BBT_SCANLASTPAGE; | 691 | chip->options |= NAND_BBM_LASTPAGE; |
676 | else | 692 | else |
677 | chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; | 693 | chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE; |
678 | 694 | ||
679 | hynix = kzalloc(sizeof(*hynix), GFP_KERNEL); | 695 | hynix = kzalloc(sizeof(*hynix), GFP_KERNEL); |
680 | if (!hynix) | 696 | if (!hynix) |
diff --git a/drivers/mtd/nand/raw/nand_jedec.c b/drivers/mtd/nand/raw/nand_jedec.c index 38b5dc22cb30..9b540e76f84f 100644 --- a/drivers/mtd/nand/raw/nand_jedec.c +++ b/drivers/mtd/nand/raw/nand_jedec.c | |||
@@ -22,12 +22,15 @@ | |||
22 | int nand_jedec_detect(struct nand_chip *chip) | 22 | int nand_jedec_detect(struct nand_chip *chip) |
23 | { | 23 | { |
24 | struct mtd_info *mtd = nand_to_mtd(chip); | 24 | struct mtd_info *mtd = nand_to_mtd(chip); |
25 | struct nand_memory_organization *memorg; | ||
25 | struct nand_jedec_params *p; | 26 | struct nand_jedec_params *p; |
26 | struct jedec_ecc_info *ecc; | 27 | struct jedec_ecc_info *ecc; |
27 | int jedec_version = 0; | 28 | int jedec_version = 0; |
28 | char id[5]; | 29 | char id[5]; |
29 | int i, val, ret; | 30 | int i, val, ret; |
30 | 31 | ||
32 | memorg = nanddev_get_memorg(&chip->base); | ||
33 | |||
31 | /* Try JEDEC for unknown chip or LP */ | 34 | /* Try JEDEC for unknown chip or LP */ |
32 | ret = nand_readid_op(chip, 0x40, id, sizeof(id)); | 35 | ret = nand_readid_op(chip, 0x40, id, sizeof(id)); |
33 | if (ret || strncmp(id, "JEDEC", sizeof(id))) | 36 | if (ret || strncmp(id, "JEDEC", sizeof(id))) |
@@ -81,18 +84,24 @@ int nand_jedec_detect(struct nand_chip *chip) | |||
81 | goto free_jedec_param_page; | 84 | goto free_jedec_param_page; |
82 | } | 85 | } |
83 | 86 | ||
84 | mtd->writesize = le32_to_cpu(p->byte_per_page); | 87 | memorg->pagesize = le32_to_cpu(p->byte_per_page); |
88 | mtd->writesize = memorg->pagesize; | ||
85 | 89 | ||
86 | /* Please reference to the comment for nand_flash_detect_onfi. */ | 90 | /* Please reference to the comment for nand_flash_detect_onfi. */ |
87 | mtd->erasesize = 1 << (fls(le32_to_cpu(p->pages_per_block)) - 1); | 91 | memorg->pages_per_eraseblock = |
88 | mtd->erasesize *= mtd->writesize; | 92 | 1 << (fls(le32_to_cpu(p->pages_per_block)) - 1); |
93 | mtd->erasesize = memorg->pages_per_eraseblock * memorg->pagesize; | ||
94 | |||
95 | memorg->oobsize = le16_to_cpu(p->spare_bytes_per_page); | ||
96 | mtd->oobsize = memorg->oobsize; | ||
89 | 97 | ||
90 | mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page); | 98 | memorg->luns_per_target = p->lun_count; |
99 | memorg->planes_per_lun = 1 << p->multi_plane_addr; | ||
91 | 100 | ||
92 | /* Please reference to the comment for nand_flash_detect_onfi. */ | 101 | /* Please reference to the comment for nand_flash_detect_onfi. */ |
93 | chip->chipsize = 1 << (fls(le32_to_cpu(p->blocks_per_lun)) - 1); | 102 | memorg->eraseblocks_per_lun = |
94 | chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count; | 103 | 1 << (fls(le32_to_cpu(p->blocks_per_lun)) - 1); |
95 | chip->bits_per_cell = p->bits_per_cell; | 104 | memorg->bits_per_cell = p->bits_per_cell; |
96 | 105 | ||
97 | if (le16_to_cpu(p->features) & JEDEC_FEATURE_16_BIT_BUS) | 106 | if (le16_to_cpu(p->features) & JEDEC_FEATURE_16_BIT_BUS) |
98 | chip->options |= NAND_BUSWIDTH_16; | 107 | chip->options |= NAND_BUSWIDTH_16; |
@@ -101,8 +110,8 @@ int nand_jedec_detect(struct nand_chip *chip) | |||
101 | ecc = &p->ecc_info[0]; | 110 | ecc = &p->ecc_info[0]; |
102 | 111 | ||
103 | if (ecc->codeword_size >= 9) { | 112 | if (ecc->codeword_size >= 9) { |
104 | chip->ecc_strength_ds = ecc->ecc_bits; | 113 | chip->base.eccreq.strength = ecc->ecc_bits; |
105 | chip->ecc_step_ds = 1 << ecc->codeword_size; | 114 | chip->base.eccreq.step_size = 1 << ecc->codeword_size; |
106 | } else { | 115 | } else { |
107 | pr_warn("Invalid codeword size\n"); | 116 | pr_warn("Invalid codeword size\n"); |
108 | } | 117 | } |
diff --git a/drivers/mtd/nand/raw/nand_macronix.c b/drivers/mtd/nand/raw/nand_macronix.c index 47d8cda547cf..e287e71347c5 100644 --- a/drivers/mtd/nand/raw/nand_macronix.c +++ b/drivers/mtd/nand/raw/nand_macronix.c | |||
@@ -62,7 +62,7 @@ static void macronix_nand_fix_broken_get_timings(struct nand_chip *chip) | |||
62 | static int macronix_nand_init(struct nand_chip *chip) | 62 | static int macronix_nand_init(struct nand_chip *chip) |
63 | { | 63 | { |
64 | if (nand_is_slc(chip)) | 64 | if (nand_is_slc(chip)) |
65 | chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; | 65 | chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE; |
66 | 66 | ||
67 | macronix_nand_fix_broken_get_timings(chip); | 67 | macronix_nand_fix_broken_get_timings(chip); |
68 | 68 | ||
diff --git a/drivers/mtd/nand/raw/nand_micron.c b/drivers/mtd/nand/raw/nand_micron.c index b85e1c13b79e..cbd4f09ac178 100644 --- a/drivers/mtd/nand/raw/nand_micron.c +++ b/drivers/mtd/nand/raw/nand_micron.c | |||
@@ -385,13 +385,13 @@ static int micron_supports_on_die_ecc(struct nand_chip *chip) | |||
385 | if (!chip->parameters.onfi) | 385 | if (!chip->parameters.onfi) |
386 | return MICRON_ON_DIE_UNSUPPORTED; | 386 | return MICRON_ON_DIE_UNSUPPORTED; |
387 | 387 | ||
388 | if (chip->bits_per_cell != 1) | 388 | if (nanddev_bits_per_cell(&chip->base) != 1) |
389 | return MICRON_ON_DIE_UNSUPPORTED; | 389 | return MICRON_ON_DIE_UNSUPPORTED; |
390 | 390 | ||
391 | /* | 391 | /* |
392 | * We only support on-die ECC of 4/512 or 8/512 | 392 | * We only support on-die ECC of 4/512 or 8/512 |
393 | */ | 393 | */ |
394 | if (chip->ecc_strength_ds != 4 && chip->ecc_strength_ds != 8) | 394 | if (chip->base.eccreq.strength != 4 && chip->base.eccreq.strength != 8) |
395 | return MICRON_ON_DIE_UNSUPPORTED; | 395 | return MICRON_ON_DIE_UNSUPPORTED; |
396 | 396 | ||
397 | /* 0x2 means on-die ECC is available. */ | 397 | /* 0x2 means on-die ECC is available. */ |
@@ -424,7 +424,7 @@ static int micron_supports_on_die_ecc(struct nand_chip *chip) | |||
424 | /* | 424 | /* |
425 | * We only support on-die ECC of 4/512 or 8/512 | 425 | * We only support on-die ECC of 4/512 or 8/512 |
426 | */ | 426 | */ |
427 | if (chip->ecc_strength_ds != 4 && chip->ecc_strength_ds != 8) | 427 | if (chip->base.eccreq.strength != 4 && chip->base.eccreq.strength != 8) |
428 | return MICRON_ON_DIE_UNSUPPORTED; | 428 | return MICRON_ON_DIE_UNSUPPORTED; |
429 | 429 | ||
430 | return MICRON_ON_DIE_SUPPORTED; | 430 | return MICRON_ON_DIE_SUPPORTED; |
@@ -448,7 +448,7 @@ static int micron_nand_init(struct nand_chip *chip) | |||
448 | goto err_free_manuf_data; | 448 | goto err_free_manuf_data; |
449 | 449 | ||
450 | if (mtd->writesize == 2048) | 450 | if (mtd->writesize == 2048) |
451 | chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; | 451 | chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE; |
452 | 452 | ||
453 | ondie = micron_supports_on_die_ecc(chip); | 453 | ondie = micron_supports_on_die_ecc(chip); |
454 | 454 | ||
@@ -479,7 +479,7 @@ static int micron_nand_init(struct nand_chip *chip) | |||
479 | * That's not needed for 8-bit ECC, because the status expose | 479 | * That's not needed for 8-bit ECC, because the status expose |
480 | * a better approximation of the number of bitflips in a page. | 480 | * a better approximation of the number of bitflips in a page. |
481 | */ | 481 | */ |
482 | if (chip->ecc_strength_ds == 4) { | 482 | if (chip->base.eccreq.strength == 4) { |
483 | micron->ecc.rawbuf = kmalloc(mtd->writesize + | 483 | micron->ecc.rawbuf = kmalloc(mtd->writesize + |
484 | mtd->oobsize, | 484 | mtd->oobsize, |
485 | GFP_KERNEL); | 485 | GFP_KERNEL); |
@@ -489,16 +489,16 @@ static int micron_nand_init(struct nand_chip *chip) | |||
489 | } | 489 | } |
490 | } | 490 | } |
491 | 491 | ||
492 | if (chip->ecc_strength_ds == 4) | 492 | if (chip->base.eccreq.strength == 4) |
493 | mtd_set_ooblayout(mtd, | 493 | mtd_set_ooblayout(mtd, |
494 | µn_nand_on_die_4_ooblayout_ops); | 494 | µn_nand_on_die_4_ooblayout_ops); |
495 | else | 495 | else |
496 | mtd_set_ooblayout(mtd, | 496 | mtd_set_ooblayout(mtd, |
497 | µn_nand_on_die_8_ooblayout_ops); | 497 | µn_nand_on_die_8_ooblayout_ops); |
498 | 498 | ||
499 | chip->ecc.bytes = chip->ecc_strength_ds * 2; | 499 | chip->ecc.bytes = chip->base.eccreq.strength * 2; |
500 | chip->ecc.size = 512; | 500 | chip->ecc.size = 512; |
501 | chip->ecc.strength = chip->ecc_strength_ds; | 501 | chip->ecc.strength = chip->base.eccreq.strength; |
502 | chip->ecc.algo = NAND_ECC_BCH; | 502 | chip->ecc.algo = NAND_ECC_BCH; |
503 | chip->ecc.read_page = micron_nand_read_page_on_die_ecc; | 503 | chip->ecc.read_page = micron_nand_read_page_on_die_ecc; |
504 | chip->ecc.write_page = micron_nand_write_page_on_die_ecc; | 504 | chip->ecc.write_page = micron_nand_write_page_on_die_ecc; |
diff --git a/drivers/mtd/nand/raw/nand_onfi.c b/drivers/mtd/nand/raw/nand_onfi.c index d8184cf591ad..0b879bd0a68c 100644 --- a/drivers/mtd/nand/raw/nand_onfi.c +++ b/drivers/mtd/nand/raw/nand_onfi.c | |||
@@ -94,8 +94,8 @@ static int nand_flash_detect_ext_param_page(struct nand_chip *chip, | |||
94 | goto ext_out; | 94 | goto ext_out; |
95 | } | 95 | } |
96 | 96 | ||
97 | chip->ecc_strength_ds = ecc->ecc_bits; | 97 | chip->base.eccreq.strength = ecc->ecc_bits; |
98 | chip->ecc_step_ds = 1 << ecc->codeword_size; | 98 | chip->base.eccreq.step_size = 1 << ecc->codeword_size; |
99 | ret = 0; | 99 | ret = 0; |
100 | 100 | ||
101 | ext_out: | 101 | ext_out: |
@@ -140,12 +140,15 @@ static void nand_bit_wise_majority(const void **srcbufs, | |||
140 | int nand_onfi_detect(struct nand_chip *chip) | 140 | int nand_onfi_detect(struct nand_chip *chip) |
141 | { | 141 | { |
142 | struct mtd_info *mtd = nand_to_mtd(chip); | 142 | struct mtd_info *mtd = nand_to_mtd(chip); |
143 | struct nand_memory_organization *memorg; | ||
143 | struct nand_onfi_params *p; | 144 | struct nand_onfi_params *p; |
144 | struct onfi_params *onfi; | 145 | struct onfi_params *onfi; |
145 | int onfi_version = 0; | 146 | int onfi_version = 0; |
146 | char id[4]; | 147 | char id[4]; |
147 | int i, ret, val; | 148 | int i, ret, val; |
148 | 149 | ||
150 | memorg = nanddev_get_memorg(&chip->base); | ||
151 | |||
149 | /* Try ONFI for unknown chip or LP */ | 152 | /* Try ONFI for unknown chip or LP */ |
150 | ret = nand_readid_op(chip, 0x20, id, sizeof(id)); | 153 | ret = nand_readid_op(chip, 0x20, id, sizeof(id)); |
151 | if (ret || strncmp(id, "ONFI", 4)) | 154 | if (ret || strncmp(id, "ONFI", 4)) |
@@ -221,32 +224,36 @@ int nand_onfi_detect(struct nand_chip *chip) | |||
221 | goto free_onfi_param_page; | 224 | goto free_onfi_param_page; |
222 | } | 225 | } |
223 | 226 | ||
224 | mtd->writesize = le32_to_cpu(p->byte_per_page); | 227 | memorg->pagesize = le32_to_cpu(p->byte_per_page); |
228 | mtd->writesize = memorg->pagesize; | ||
225 | 229 | ||
226 | /* | 230 | /* |
227 | * pages_per_block and blocks_per_lun may not be a power-of-2 size | 231 | * pages_per_block and blocks_per_lun may not be a power-of-2 size |
228 | * (don't ask me who thought of this...). MTD assumes that these | 232 | * (don't ask me who thought of this...). MTD assumes that these |
229 | * dimensions will be power-of-2, so just truncate the remaining area. | 233 | * dimensions will be power-of-2, so just truncate the remaining area. |
230 | */ | 234 | */ |
231 | mtd->erasesize = 1 << (fls(le32_to_cpu(p->pages_per_block)) - 1); | 235 | memorg->pages_per_eraseblock = |
232 | mtd->erasesize *= mtd->writesize; | 236 | 1 << (fls(le32_to_cpu(p->pages_per_block)) - 1); |
237 | mtd->erasesize = memorg->pages_per_eraseblock * memorg->pagesize; | ||
233 | 238 | ||
234 | mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page); | 239 | memorg->oobsize = le16_to_cpu(p->spare_bytes_per_page); |
240 | mtd->oobsize = memorg->oobsize; | ||
235 | 241 | ||
236 | /* See erasesize comment */ | 242 | memorg->luns_per_target = p->lun_count; |
237 | chip->chipsize = 1 << (fls(le32_to_cpu(p->blocks_per_lun)) - 1); | 243 | memorg->planes_per_lun = 1 << p->interleaved_bits; |
238 | chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count; | ||
239 | chip->bits_per_cell = p->bits_per_cell; | ||
240 | 244 | ||
241 | chip->max_bb_per_die = le16_to_cpu(p->bb_per_lun); | 245 | /* See erasesize comment */ |
242 | chip->blocks_per_die = le32_to_cpu(p->blocks_per_lun); | 246 | memorg->eraseblocks_per_lun = |
247 | 1 << (fls(le32_to_cpu(p->blocks_per_lun)) - 1); | ||
248 | memorg->max_bad_eraseblocks_per_lun = le32_to_cpu(p->blocks_per_lun); | ||
249 | memorg->bits_per_cell = p->bits_per_cell; | ||
243 | 250 | ||
244 | if (le16_to_cpu(p->features) & ONFI_FEATURE_16_BIT_BUS) | 251 | if (le16_to_cpu(p->features) & ONFI_FEATURE_16_BIT_BUS) |
245 | chip->options |= NAND_BUSWIDTH_16; | 252 | chip->options |= NAND_BUSWIDTH_16; |
246 | 253 | ||
247 | if (p->ecc_bits != 0xff) { | 254 | if (p->ecc_bits != 0xff) { |
248 | chip->ecc_strength_ds = p->ecc_bits; | 255 | chip->base.eccreq.strength = p->ecc_bits; |
249 | chip->ecc_step_ds = 512; | 256 | chip->base.eccreq.step_size = 512; |
250 | } else if (onfi_version >= 21 && | 257 | } else if (onfi_version >= 21 && |
251 | (le16_to_cpu(p->features) & ONFI_FEATURE_EXT_PARAM_PAGE)) { | 258 | (le16_to_cpu(p->features) & ONFI_FEATURE_EXT_PARAM_PAGE)) { |
252 | 259 | ||
diff --git a/drivers/mtd/nand/raw/nand_samsung.c b/drivers/mtd/nand/raw/nand_samsung.c index e46d4c492ad8..5552ce20ede0 100644 --- a/drivers/mtd/nand/raw/nand_samsung.c +++ b/drivers/mtd/nand/raw/nand_samsung.c | |||
@@ -20,6 +20,9 @@ | |||
20 | static void samsung_nand_decode_id(struct nand_chip *chip) | 20 | static void samsung_nand_decode_id(struct nand_chip *chip) |
21 | { | 21 | { |
22 | struct mtd_info *mtd = nand_to_mtd(chip); | 22 | struct mtd_info *mtd = nand_to_mtd(chip); |
23 | struct nand_memory_organization *memorg; | ||
24 | |||
25 | memorg = nanddev_get_memorg(&chip->base); | ||
23 | 26 | ||
24 | /* New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44) */ | 27 | /* New Samsung (6 byte ID): Samsung K9GAG08U0F (p.44) */ |
25 | if (chip->id.len == 6 && !nand_is_slc(chip) && | 28 | if (chip->id.len == 6 && !nand_is_slc(chip) && |
@@ -27,29 +30,30 @@ static void samsung_nand_decode_id(struct nand_chip *chip) | |||
27 | u8 extid = chip->id.data[3]; | 30 | u8 extid = chip->id.data[3]; |
28 | 31 | ||
29 | /* Get pagesize */ | 32 | /* Get pagesize */ |
30 | mtd->writesize = 2048 << (extid & 0x03); | 33 | memorg->pagesize = 2048 << (extid & 0x03); |
34 | mtd->writesize = memorg->pagesize; | ||
31 | 35 | ||
32 | extid >>= 2; | 36 | extid >>= 2; |
33 | 37 | ||
34 | /* Get oobsize */ | 38 | /* Get oobsize */ |
35 | switch (((extid >> 2) & 0x4) | (extid & 0x3)) { | 39 | switch (((extid >> 2) & 0x4) | (extid & 0x3)) { |
36 | case 1: | 40 | case 1: |
37 | mtd->oobsize = 128; | 41 | memorg->oobsize = 128; |
38 | break; | 42 | break; |
39 | case 2: | 43 | case 2: |
40 | mtd->oobsize = 218; | 44 | memorg->oobsize = 218; |
41 | break; | 45 | break; |
42 | case 3: | 46 | case 3: |
43 | mtd->oobsize = 400; | 47 | memorg->oobsize = 400; |
44 | break; | 48 | break; |
45 | case 4: | 49 | case 4: |
46 | mtd->oobsize = 436; | 50 | memorg->oobsize = 436; |
47 | break; | 51 | break; |
48 | case 5: | 52 | case 5: |
49 | mtd->oobsize = 512; | 53 | memorg->oobsize = 512; |
50 | break; | 54 | break; |
51 | case 6: | 55 | case 6: |
52 | mtd->oobsize = 640; | 56 | memorg->oobsize = 640; |
53 | break; | 57 | break; |
54 | default: | 58 | default: |
55 | /* | 59 | /* |
@@ -62,31 +66,37 @@ static void samsung_nand_decode_id(struct nand_chip *chip) | |||
62 | break; | 66 | break; |
63 | } | 67 | } |
64 | 68 | ||
69 | mtd->oobsize = memorg->oobsize; | ||
70 | |||
65 | /* Get blocksize */ | 71 | /* Get blocksize */ |
66 | extid >>= 2; | 72 | extid >>= 2; |
73 | memorg->pages_per_eraseblock = (128 * 1024) << | ||
74 | (((extid >> 1) & 0x04) | | ||
75 | (extid & 0x03)) / | ||
76 | memorg->pagesize; | ||
67 | mtd->erasesize = (128 * 1024) << | 77 | mtd->erasesize = (128 * 1024) << |
68 | (((extid >> 1) & 0x04) | (extid & 0x03)); | 78 | (((extid >> 1) & 0x04) | (extid & 0x03)); |
69 | 79 | ||
70 | /* Extract ECC requirements from 5th id byte*/ | 80 | /* Extract ECC requirements from 5th id byte*/ |
71 | extid = (chip->id.data[4] >> 4) & 0x07; | 81 | extid = (chip->id.data[4] >> 4) & 0x07; |
72 | if (extid < 5) { | 82 | if (extid < 5) { |
73 | chip->ecc_step_ds = 512; | 83 | chip->base.eccreq.step_size = 512; |
74 | chip->ecc_strength_ds = 1 << extid; | 84 | chip->base.eccreq.strength = 1 << extid; |
75 | } else { | 85 | } else { |
76 | chip->ecc_step_ds = 1024; | 86 | chip->base.eccreq.step_size = 1024; |
77 | switch (extid) { | 87 | switch (extid) { |
78 | case 5: | 88 | case 5: |
79 | chip->ecc_strength_ds = 24; | 89 | chip->base.eccreq.strength = 24; |
80 | break; | 90 | break; |
81 | case 6: | 91 | case 6: |
82 | chip->ecc_strength_ds = 40; | 92 | chip->base.eccreq.strength = 40; |
83 | break; | 93 | break; |
84 | case 7: | 94 | case 7: |
85 | chip->ecc_strength_ds = 60; | 95 | chip->base.eccreq.strength = 60; |
86 | break; | 96 | break; |
87 | default: | 97 | default: |
88 | WARN(1, "Could not decode ECC info"); | 98 | WARN(1, "Could not decode ECC info"); |
89 | chip->ecc_step_ds = 0; | 99 | chip->base.eccreq.step_size = 0; |
90 | } | 100 | } |
91 | } | 101 | } |
92 | } else { | 102 | } else { |
@@ -96,8 +106,8 @@ static void samsung_nand_decode_id(struct nand_chip *chip) | |||
96 | switch (chip->id.data[1]) { | 106 | switch (chip->id.data[1]) { |
97 | /* K9F4G08U0D-S[I|C]B0(T00) */ | 107 | /* K9F4G08U0D-S[I|C]B0(T00) */ |
98 | case 0xDC: | 108 | case 0xDC: |
99 | chip->ecc_step_ds = 512; | 109 | chip->base.eccreq.step_size = 512; |
100 | chip->ecc_strength_ds = 1; | 110 | chip->base.eccreq.strength = 1; |
101 | break; | 111 | break; |
102 | 112 | ||
103 | /* K9F1G08U0E 21nm chips do not support subpage write */ | 113 | /* K9F1G08U0E 21nm chips do not support subpage write */ |
@@ -121,9 +131,9 @@ static int samsung_nand_init(struct nand_chip *chip) | |||
121 | chip->options |= NAND_SAMSUNG_LP_OPTIONS; | 131 | chip->options |= NAND_SAMSUNG_LP_OPTIONS; |
122 | 132 | ||
123 | if (!nand_is_slc(chip)) | 133 | if (!nand_is_slc(chip)) |
124 | chip->bbt_options |= NAND_BBT_SCANLASTPAGE; | 134 | chip->options |= NAND_BBM_LASTPAGE; |
125 | else | 135 | else |
126 | chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; | 136 | chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE; |
127 | 137 | ||
128 | return 0; | 138 | return 0; |
129 | } | 139 | } |
diff --git a/drivers/mtd/nand/raw/nand_toshiba.c b/drivers/mtd/nand/raw/nand_toshiba.c index d068163b64b3..74ffcae48726 100644 --- a/drivers/mtd/nand/raw/nand_toshiba.c +++ b/drivers/mtd/nand/raw/nand_toshiba.c | |||
@@ -101,6 +101,9 @@ static void toshiba_nand_benand_init(struct nand_chip *chip) | |||
101 | static void toshiba_nand_decode_id(struct nand_chip *chip) | 101 | static void toshiba_nand_decode_id(struct nand_chip *chip) |
102 | { | 102 | { |
103 | struct mtd_info *mtd = nand_to_mtd(chip); | 103 | struct mtd_info *mtd = nand_to_mtd(chip); |
104 | struct nand_memory_organization *memorg; | ||
105 | |||
106 | memorg = nanddev_get_memorg(&chip->base); | ||
104 | 107 | ||
105 | nand_decode_ext_id(chip); | 108 | nand_decode_ext_id(chip); |
106 | 109 | ||
@@ -114,8 +117,10 @@ static void toshiba_nand_decode_id(struct nand_chip *chip) | |||
114 | */ | 117 | */ |
115 | if (chip->id.len >= 6 && nand_is_slc(chip) && | 118 | if (chip->id.len >= 6 && nand_is_slc(chip) && |
116 | (chip->id.data[5] & 0x7) == 0x6 /* 24nm */ && | 119 | (chip->id.data[5] & 0x7) == 0x6 /* 24nm */ && |
117 | !(chip->id.data[4] & 0x80) /* !BENAND */) | 120 | !(chip->id.data[4] & 0x80) /* !BENAND */) { |
118 | mtd->oobsize = 32 * mtd->writesize >> 9; | 121 | memorg->oobsize = 32 * memorg->pagesize >> 9; |
122 | mtd->oobsize = memorg->oobsize; | ||
123 | } | ||
119 | 124 | ||
120 | /* | 125 | /* |
121 | * Extract ECC requirements from 6th id byte. | 126 | * Extract ECC requirements from 6th id byte. |
@@ -125,20 +130,20 @@ static void toshiba_nand_decode_id(struct nand_chip *chip) | |||
125 | * - 24nm: 8 bit ECC for each 512Byte is required. | 130 | * - 24nm: 8 bit ECC for each 512Byte is required. |
126 | */ | 131 | */ |
127 | if (chip->id.len >= 6 && nand_is_slc(chip)) { | 132 | if (chip->id.len >= 6 && nand_is_slc(chip)) { |
128 | chip->ecc_step_ds = 512; | 133 | chip->base.eccreq.step_size = 512; |
129 | switch (chip->id.data[5] & 0x7) { | 134 | switch (chip->id.data[5] & 0x7) { |
130 | case 0x4: | 135 | case 0x4: |
131 | chip->ecc_strength_ds = 1; | 136 | chip->base.eccreq.strength = 1; |
132 | break; | 137 | break; |
133 | case 0x5: | 138 | case 0x5: |
134 | chip->ecc_strength_ds = 4; | 139 | chip->base.eccreq.strength = 4; |
135 | break; | 140 | break; |
136 | case 0x6: | 141 | case 0x6: |
137 | chip->ecc_strength_ds = 8; | 142 | chip->base.eccreq.strength = 8; |
138 | break; | 143 | break; |
139 | default: | 144 | default: |
140 | WARN(1, "Could not get ECC info"); | 145 | WARN(1, "Could not get ECC info"); |
141 | chip->ecc_step_ds = 0; | 146 | chip->base.eccreq.step_size = 0; |
142 | break; | 147 | break; |
143 | } | 148 | } |
144 | } | 149 | } |
@@ -147,7 +152,7 @@ static void toshiba_nand_decode_id(struct nand_chip *chip) | |||
147 | static int toshiba_nand_init(struct nand_chip *chip) | 152 | static int toshiba_nand_init(struct nand_chip *chip) |
148 | { | 153 | { |
149 | if (nand_is_slc(chip)) | 154 | if (nand_is_slc(chip)) |
150 | chip->bbt_options |= NAND_BBT_SCAN2NDPAGE; | 155 | chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE; |
151 | 156 | ||
152 | /* Check that chip is BENAND and ECC mode is on-die */ | 157 | /* Check that chip is BENAND and ECC mode is on-die */ |
153 | if (nand_is_slc(chip) && chip->ecc.mode == NAND_ECC_ON_DIE && | 158 | if (nand_is_slc(chip) && chip->ecc.mode == NAND_ECC_ON_DIE && |
diff --git a/drivers/mtd/nand/raw/nandsim.c b/drivers/mtd/nand/raw/nandsim.c index 933d1a629c51..df63fa564082 100644 --- a/drivers/mtd/nand/raw/nandsim.c +++ b/drivers/mtd/nand/raw/nandsim.c | |||
@@ -298,6 +298,8 @@ union ns_mem { | |||
298 | * The structure which describes all the internal simulator data. | 298 | * The structure which describes all the internal simulator data. |
299 | */ | 299 | */ |
300 | struct nandsim { | 300 | struct nandsim { |
301 | struct nand_chip chip; | ||
302 | struct nand_controller base; | ||
301 | struct mtd_partition partitions[CONFIG_NANDSIM_MAX_PARTS]; | 303 | struct mtd_partition partitions[CONFIG_NANDSIM_MAX_PARTS]; |
302 | unsigned int nbparts; | 304 | unsigned int nbparts; |
303 | 305 | ||
@@ -644,9 +646,6 @@ static int __init init_nandsim(struct mtd_info *mtd) | |||
644 | return -EIO; | 646 | return -EIO; |
645 | } | 647 | } |
646 | 648 | ||
647 | /* Force mtd to not do delays */ | ||
648 | chip->legacy.chip_delay = 0; | ||
649 | |||
650 | /* Initialize the NAND flash parameters */ | 649 | /* Initialize the NAND flash parameters */ |
651 | ns->busw = chip->options & NAND_BUSWIDTH_16 ? 16 : 8; | 650 | ns->busw = chip->options & NAND_BUSWIDTH_16 ? 16 : 8; |
652 | ns->geom.totsz = mtd->size; | 651 | ns->geom.totsz = mtd->size; |
@@ -2076,24 +2075,6 @@ static void ns_nand_write_byte(struct nand_chip *chip, u_char byte) | |||
2076 | return; | 2075 | return; |
2077 | } | 2076 | } |
2078 | 2077 | ||
2079 | static void ns_hwcontrol(struct nand_chip *chip, int cmd, unsigned int bitmask) | ||
2080 | { | ||
2081 | struct nandsim *ns = nand_get_controller_data(chip); | ||
2082 | |||
2083 | ns->lines.cle = bitmask & NAND_CLE ? 1 : 0; | ||
2084 | ns->lines.ale = bitmask & NAND_ALE ? 1 : 0; | ||
2085 | ns->lines.ce = bitmask & NAND_NCE ? 1 : 0; | ||
2086 | |||
2087 | if (cmd != NAND_CMD_NONE) | ||
2088 | ns_nand_write_byte(chip, cmd); | ||
2089 | } | ||
2090 | |||
2091 | static int ns_device_ready(struct nand_chip *chip) | ||
2092 | { | ||
2093 | NS_DBG("device_ready\n"); | ||
2094 | return 1; | ||
2095 | } | ||
2096 | |||
2097 | static void ns_nand_write_buf(struct nand_chip *chip, const u_char *buf, | 2078 | static void ns_nand_write_buf(struct nand_chip *chip, const u_char *buf, |
2098 | int len) | 2079 | int len) |
2099 | { | 2080 | { |
@@ -2145,7 +2126,7 @@ static void ns_nand_read_buf(struct nand_chip *chip, u_char *buf, int len) | |||
2145 | int i; | 2126 | int i; |
2146 | 2127 | ||
2147 | for (i = 0; i < len; i++) | 2128 | for (i = 0; i < len; i++) |
2148 | buf[i] = chip->legacy.read_byte(chip); | 2129 | buf[i] = ns_nand_read_byte(chip); |
2149 | 2130 | ||
2150 | return; | 2131 | return; |
2151 | } | 2132 | } |
@@ -2168,6 +2149,46 @@ static void ns_nand_read_buf(struct nand_chip *chip, u_char *buf, int len) | |||
2168 | return; | 2149 | return; |
2169 | } | 2150 | } |
2170 | 2151 | ||
2152 | static int ns_exec_op(struct nand_chip *chip, const struct nand_operation *op, | ||
2153 | bool check_only) | ||
2154 | { | ||
2155 | int i; | ||
2156 | unsigned int op_id; | ||
2157 | const struct nand_op_instr *instr = NULL; | ||
2158 | struct nandsim *ns = nand_get_controller_data(chip); | ||
2159 | |||
2160 | ns->lines.ce = 1; | ||
2161 | |||
2162 | for (op_id = 0; op_id < op->ninstrs; op_id++) { | ||
2163 | instr = &op->instrs[op_id]; | ||
2164 | ns->lines.cle = 0; | ||
2165 | ns->lines.ale = 0; | ||
2166 | |||
2167 | switch (instr->type) { | ||
2168 | case NAND_OP_CMD_INSTR: | ||
2169 | ns->lines.cle = 1; | ||
2170 | ns_nand_write_byte(chip, instr->ctx.cmd.opcode); | ||
2171 | break; | ||
2172 | case NAND_OP_ADDR_INSTR: | ||
2173 | ns->lines.ale = 1; | ||
2174 | for (i = 0; i < instr->ctx.addr.naddrs; i++) | ||
2175 | ns_nand_write_byte(chip, instr->ctx.addr.addrs[i]); | ||
2176 | break; | ||
2177 | case NAND_OP_DATA_IN_INSTR: | ||
2178 | ns_nand_read_buf(chip, instr->ctx.data.buf.in, instr->ctx.data.len); | ||
2179 | break; | ||
2180 | case NAND_OP_DATA_OUT_INSTR: | ||
2181 | ns_nand_write_buf(chip, instr->ctx.data.buf.out, instr->ctx.data.len); | ||
2182 | break; | ||
2183 | case NAND_OP_WAITRDY_INSTR: | ||
2184 | /* we are always ready */ | ||
2185 | break; | ||
2186 | } | ||
2187 | } | ||
2188 | |||
2189 | return 0; | ||
2190 | } | ||
2191 | |||
2171 | static int ns_attach_chip(struct nand_chip *chip) | 2192 | static int ns_attach_chip(struct nand_chip *chip) |
2172 | { | 2193 | { |
2173 | unsigned int eccsteps, eccbytes; | 2194 | unsigned int eccsteps, eccbytes; |
@@ -2208,6 +2229,7 @@ static int ns_attach_chip(struct nand_chip *chip) | |||
2208 | 2229 | ||
2209 | static const struct nand_controller_ops ns_controller_ops = { | 2230 | static const struct nand_controller_ops ns_controller_ops = { |
2210 | .attach_chip = ns_attach_chip, | 2231 | .attach_chip = ns_attach_chip, |
2232 | .exec_op = ns_exec_op, | ||
2211 | }; | 2233 | }; |
2212 | 2234 | ||
2213 | /* | 2235 | /* |
@@ -2216,7 +2238,7 @@ static const struct nand_controller_ops ns_controller_ops = { | |||
2216 | static int __init ns_init_module(void) | 2238 | static int __init ns_init_module(void) |
2217 | { | 2239 | { |
2218 | struct nand_chip *chip; | 2240 | struct nand_chip *chip; |
2219 | struct nandsim *nand; | 2241 | struct nandsim *ns; |
2220 | int retval = -ENOMEM, i; | 2242 | int retval = -ENOMEM, i; |
2221 | 2243 | ||
2222 | if (bus_width != 8 && bus_width != 16) { | 2244 | if (bus_width != 8 && bus_width != 16) { |
@@ -2224,25 +2246,15 @@ static int __init ns_init_module(void) | |||
2224 | return -EINVAL; | 2246 | return -EINVAL; |
2225 | } | 2247 | } |
2226 | 2248 | ||
2227 | /* Allocate and initialize mtd_info, nand_chip and nandsim structures */ | 2249 | ns = kzalloc(sizeof(struct nandsim), GFP_KERNEL); |
2228 | chip = kzalloc(sizeof(struct nand_chip) + sizeof(struct nandsim), | 2250 | if (!ns) { |
2229 | GFP_KERNEL); | ||
2230 | if (!chip) { | ||
2231 | NS_ERR("unable to allocate core structures.\n"); | 2251 | NS_ERR("unable to allocate core structures.\n"); |
2232 | return -ENOMEM; | 2252 | return -ENOMEM; |
2233 | } | 2253 | } |
2254 | chip = &ns->chip; | ||
2234 | nsmtd = nand_to_mtd(chip); | 2255 | nsmtd = nand_to_mtd(chip); |
2235 | nand = (struct nandsim *)(chip + 1); | 2256 | nand_set_controller_data(chip, (void *)ns); |
2236 | nand_set_controller_data(chip, (void *)nand); | ||
2237 | 2257 | ||
2238 | /* | ||
2239 | * Register simulator's callbacks. | ||
2240 | */ | ||
2241 | chip->legacy.cmd_ctrl = ns_hwcontrol; | ||
2242 | chip->legacy.read_byte = ns_nand_read_byte; | ||
2243 | chip->legacy.dev_ready = ns_device_ready; | ||
2244 | chip->legacy.write_buf = ns_nand_write_buf; | ||
2245 | chip->legacy.read_buf = ns_nand_read_buf; | ||
2246 | chip->ecc.mode = NAND_ECC_SOFT; | 2258 | chip->ecc.mode = NAND_ECC_SOFT; |
2247 | chip->ecc.algo = NAND_ECC_HAMMING; | 2259 | chip->ecc.algo = NAND_ECC_HAMMING; |
2248 | /* The NAND_SKIP_BBTSCAN option is necessary for 'overridesize' */ | 2260 | /* The NAND_SKIP_BBTSCAN option is necessary for 'overridesize' */ |
@@ -2251,9 +2263,11 @@ static int __init ns_init_module(void) | |||
2251 | 2263 | ||
2252 | switch (bbt) { | 2264 | switch (bbt) { |
2253 | case 2: | 2265 | case 2: |
2254 | chip->bbt_options |= NAND_BBT_NO_OOB; | 2266 | chip->bbt_options |= NAND_BBT_NO_OOB; |
2267 | /* fall through */ | ||
2255 | case 1: | 2268 | case 1: |
2256 | chip->bbt_options |= NAND_BBT_USE_FLASH; | 2269 | chip->bbt_options |= NAND_BBT_USE_FLASH; |
2270 | /* fall through */ | ||
2257 | case 0: | 2271 | case 0: |
2258 | break; | 2272 | break; |
2259 | default: | 2273 | default: |
@@ -2266,19 +2280,19 @@ static int __init ns_init_module(void) | |||
2266 | * the initial ID read command correctly | 2280 | * the initial ID read command correctly |
2267 | */ | 2281 | */ |
2268 | if (id_bytes[6] != 0xFF || id_bytes[7] != 0xFF) | 2282 | if (id_bytes[6] != 0xFF || id_bytes[7] != 0xFF) |
2269 | nand->geom.idbytes = 8; | 2283 | ns->geom.idbytes = 8; |
2270 | else if (id_bytes[4] != 0xFF || id_bytes[5] != 0xFF) | 2284 | else if (id_bytes[4] != 0xFF || id_bytes[5] != 0xFF) |
2271 | nand->geom.idbytes = 6; | 2285 | ns->geom.idbytes = 6; |
2272 | else if (id_bytes[2] != 0xFF || id_bytes[3] != 0xFF) | 2286 | else if (id_bytes[2] != 0xFF || id_bytes[3] != 0xFF) |
2273 | nand->geom.idbytes = 4; | 2287 | ns->geom.idbytes = 4; |
2274 | else | 2288 | else |
2275 | nand->geom.idbytes = 2; | 2289 | ns->geom.idbytes = 2; |
2276 | nand->regs.status = NS_STATUS_OK(nand); | 2290 | ns->regs.status = NS_STATUS_OK(ns); |
2277 | nand->nxstate = STATE_UNKNOWN; | 2291 | ns->nxstate = STATE_UNKNOWN; |
2278 | nand->options |= OPT_PAGE512; /* temporary value */ | 2292 | ns->options |= OPT_PAGE512; /* temporary value */ |
2279 | memcpy(nand->ids, id_bytes, sizeof(nand->ids)); | 2293 | memcpy(ns->ids, id_bytes, sizeof(ns->ids)); |
2280 | if (bus_width == 16) { | 2294 | if (bus_width == 16) { |
2281 | nand->busw = 16; | 2295 | ns->busw = 16; |
2282 | chip->options |= NAND_BUSWIDTH_16; | 2296 | chip->options |= NAND_BUSWIDTH_16; |
2283 | } | 2297 | } |
2284 | 2298 | ||
@@ -2293,7 +2307,10 @@ static int __init ns_init_module(void) | |||
2293 | if ((retval = parse_gravepages()) != 0) | 2307 | if ((retval = parse_gravepages()) != 0) |
2294 | goto error; | 2308 | goto error; |
2295 | 2309 | ||
2296 | chip->legacy.dummy_controller.ops = &ns_controller_ops; | 2310 | nand_controller_init(&ns->base); |
2311 | ns->base.ops = &ns_controller_ops; | ||
2312 | chip->controller = &ns->base; | ||
2313 | |||
2297 | retval = nand_scan(chip, 1); | 2314 | retval = nand_scan(chip, 1); |
2298 | if (retval) { | 2315 | if (retval) { |
2299 | NS_ERR("Could not scan NAND Simulator device\n"); | 2316 | NS_ERR("Could not scan NAND Simulator device\n"); |
@@ -2302,16 +2319,23 @@ static int __init ns_init_module(void) | |||
2302 | 2319 | ||
2303 | if (overridesize) { | 2320 | if (overridesize) { |
2304 | uint64_t new_size = (uint64_t)nsmtd->erasesize << overridesize; | 2321 | uint64_t new_size = (uint64_t)nsmtd->erasesize << overridesize; |
2322 | struct nand_memory_organization *memorg; | ||
2323 | u64 targetsize; | ||
2324 | |||
2325 | memorg = nanddev_get_memorg(&chip->base); | ||
2326 | |||
2305 | if (new_size >> overridesize != nsmtd->erasesize) { | 2327 | if (new_size >> overridesize != nsmtd->erasesize) { |
2306 | NS_ERR("overridesize is too big\n"); | 2328 | NS_ERR("overridesize is too big\n"); |
2307 | retval = -EINVAL; | 2329 | retval = -EINVAL; |
2308 | goto err_exit; | 2330 | goto err_exit; |
2309 | } | 2331 | } |
2332 | |||
2310 | /* N.B. This relies on nand_scan not doing anything with the size before we change it */ | 2333 | /* N.B. This relies on nand_scan not doing anything with the size before we change it */ |
2311 | nsmtd->size = new_size; | 2334 | nsmtd->size = new_size; |
2312 | chip->chipsize = new_size; | 2335 | memorg->eraseblocks_per_lun = 1 << overridesize; |
2336 | targetsize = nanddev_target_size(&chip->base); | ||
2313 | chip->chip_shift = ffs(nsmtd->erasesize) + overridesize - 1; | 2337 | chip->chip_shift = ffs(nsmtd->erasesize) + overridesize - 1; |
2314 | chip->pagemask = (chip->chipsize >> chip->page_shift) - 1; | 2338 | chip->pagemask = (targetsize >> chip->page_shift) - 1; |
2315 | } | 2339 | } |
2316 | 2340 | ||
2317 | if ((retval = setup_wear_reporting(nsmtd)) != 0) | 2341 | if ((retval = setup_wear_reporting(nsmtd)) != 0) |
@@ -2323,27 +2347,27 @@ static int __init ns_init_module(void) | |||
2323 | if ((retval = nand_create_bbt(chip)) != 0) | 2347 | if ((retval = nand_create_bbt(chip)) != 0) |
2324 | goto err_exit; | 2348 | goto err_exit; |
2325 | 2349 | ||
2326 | if ((retval = parse_badblocks(nand, nsmtd)) != 0) | 2350 | if ((retval = parse_badblocks(ns, nsmtd)) != 0) |
2327 | goto err_exit; | 2351 | goto err_exit; |
2328 | 2352 | ||
2329 | /* Register NAND partitions */ | 2353 | /* Register NAND partitions */ |
2330 | retval = mtd_device_register(nsmtd, &nand->partitions[0], | 2354 | retval = mtd_device_register(nsmtd, &ns->partitions[0], |
2331 | nand->nbparts); | 2355 | ns->nbparts); |
2332 | if (retval != 0) | 2356 | if (retval != 0) |
2333 | goto err_exit; | 2357 | goto err_exit; |
2334 | 2358 | ||
2335 | if ((retval = nandsim_debugfs_create(nand)) != 0) | 2359 | if ((retval = nandsim_debugfs_create(ns)) != 0) |
2336 | goto err_exit; | 2360 | goto err_exit; |
2337 | 2361 | ||
2338 | return 0; | 2362 | return 0; |
2339 | 2363 | ||
2340 | err_exit: | 2364 | err_exit: |
2341 | free_nandsim(nand); | 2365 | free_nandsim(ns); |
2342 | nand_release(chip); | 2366 | nand_release(chip); |
2343 | for (i = 0;i < ARRAY_SIZE(nand->partitions); ++i) | 2367 | for (i = 0;i < ARRAY_SIZE(ns->partitions); ++i) |
2344 | kfree(nand->partitions[i].name); | 2368 | kfree(ns->partitions[i].name); |
2345 | error: | 2369 | error: |
2346 | kfree(chip); | 2370 | kfree(ns); |
2347 | free_lists(); | 2371 | free_lists(); |
2348 | 2372 | ||
2349 | return retval; | 2373 | return retval; |
@@ -2364,7 +2388,7 @@ static void __exit ns_cleanup_module(void) | |||
2364 | nand_release(chip); /* Unregister driver */ | 2388 | nand_release(chip); /* Unregister driver */ |
2365 | for (i = 0;i < ARRAY_SIZE(ns->partitions); ++i) | 2389 | for (i = 0;i < ARRAY_SIZE(ns->partitions); ++i) |
2366 | kfree(ns->partitions[i].name); | 2390 | kfree(ns->partitions[i].name); |
2367 | kfree(mtd_to_nand(nsmtd)); /* Free other structures */ | 2391 | kfree(ns); /* Free other structures */ |
2368 | free_lists(); | 2392 | free_lists(); |
2369 | } | 2393 | } |
2370 | 2394 | ||
diff --git a/drivers/mtd/nand/raw/nuc900_nand.c b/drivers/mtd/nand/raw/nuc900_nand.c index 38b1994e7ed3..56fa84029482 100644 --- a/drivers/mtd/nand/raw/nuc900_nand.c +++ b/drivers/mtd/nand/raw/nuc900_nand.c | |||
@@ -192,8 +192,9 @@ static void nuc900_nand_command_lp(struct nand_chip *chip, | |||
192 | return; | 192 | return; |
193 | 193 | ||
194 | case NAND_CMD_READ0: | 194 | case NAND_CMD_READ0: |
195 | |||
196 | write_cmd_reg(nand, NAND_CMD_READSTART); | 195 | write_cmd_reg(nand, NAND_CMD_READSTART); |
196 | /* fall through */ | ||
197 | |||
197 | default: | 198 | default: |
198 | 199 | ||
199 | if (!chip->legacy.dev_ready) { | 200 | if (!chip->legacy.dev_ready) { |
diff --git a/drivers/mtd/nand/raw/omap2.c b/drivers/mtd/nand/raw/omap2.c index 8f280a2962c8..a9a275342a41 100644 --- a/drivers/mtd/nand/raw/omap2.c +++ b/drivers/mtd/nand/raw/omap2.c | |||
@@ -1725,9 +1725,9 @@ static bool omap2_nand_ecc_check(struct omap_nand_info *info) | |||
1725 | break; | 1725 | break; |
1726 | } | 1726 | } |
1727 | 1727 | ||
1728 | if (ecc_needs_bch && !IS_ENABLED(CONFIG_MTD_NAND_ECC_BCH)) { | 1728 | if (ecc_needs_bch && !IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_BCH)) { |
1729 | dev_err(&info->pdev->dev, | 1729 | dev_err(&info->pdev->dev, |
1730 | "CONFIG_MTD_NAND_ECC_BCH not enabled\n"); | 1730 | "CONFIG_MTD_NAND_ECC_SW_BCH not enabled\n"); |
1731 | return false; | 1731 | return false; |
1732 | } | 1732 | } |
1733 | if (ecc_needs_omap_bch && !IS_ENABLED(CONFIG_MTD_NAND_OMAP_BCH)) { | 1733 | if (ecc_needs_omap_bch && !IS_ENABLED(CONFIG_MTD_NAND_OMAP_BCH)) { |
diff --git a/drivers/mtd/nand/raw/omap_elm.c b/drivers/mtd/nand/raw/omap_elm.c index a3f32f939cc1..94c6401ef32f 100644 --- a/drivers/mtd/nand/raw/omap_elm.c +++ b/drivers/mtd/nand/raw/omap_elm.c | |||
@@ -465,11 +465,13 @@ static int elm_context_save(struct elm_info *info) | |||
465 | ELM_SYNDROME_FRAGMENT_5 + offset); | 465 | ELM_SYNDROME_FRAGMENT_5 + offset); |
466 | regs->elm_syndrome_fragment_4[i] = elm_read_reg(info, | 466 | regs->elm_syndrome_fragment_4[i] = elm_read_reg(info, |
467 | ELM_SYNDROME_FRAGMENT_4 + offset); | 467 | ELM_SYNDROME_FRAGMENT_4 + offset); |
468 | /* fall through */ | ||
468 | case BCH8_ECC: | 469 | case BCH8_ECC: |
469 | regs->elm_syndrome_fragment_3[i] = elm_read_reg(info, | 470 | regs->elm_syndrome_fragment_3[i] = elm_read_reg(info, |
470 | ELM_SYNDROME_FRAGMENT_3 + offset); | 471 | ELM_SYNDROME_FRAGMENT_3 + offset); |
471 | regs->elm_syndrome_fragment_2[i] = elm_read_reg(info, | 472 | regs->elm_syndrome_fragment_2[i] = elm_read_reg(info, |
472 | ELM_SYNDROME_FRAGMENT_2 + offset); | 473 | ELM_SYNDROME_FRAGMENT_2 + offset); |
474 | /* fall through */ | ||
473 | case BCH4_ECC: | 475 | case BCH4_ECC: |
474 | regs->elm_syndrome_fragment_1[i] = elm_read_reg(info, | 476 | regs->elm_syndrome_fragment_1[i] = elm_read_reg(info, |
475 | ELM_SYNDROME_FRAGMENT_1 + offset); | 477 | ELM_SYNDROME_FRAGMENT_1 + offset); |
@@ -511,11 +513,13 @@ static int elm_context_restore(struct elm_info *info) | |||
511 | regs->elm_syndrome_fragment_5[i]); | 513 | regs->elm_syndrome_fragment_5[i]); |
512 | elm_write_reg(info, ELM_SYNDROME_FRAGMENT_4 + offset, | 514 | elm_write_reg(info, ELM_SYNDROME_FRAGMENT_4 + offset, |
513 | regs->elm_syndrome_fragment_4[i]); | 515 | regs->elm_syndrome_fragment_4[i]); |
516 | /* fall through */ | ||
514 | case BCH8_ECC: | 517 | case BCH8_ECC: |
515 | elm_write_reg(info, ELM_SYNDROME_FRAGMENT_3 + offset, | 518 | elm_write_reg(info, ELM_SYNDROME_FRAGMENT_3 + offset, |
516 | regs->elm_syndrome_fragment_3[i]); | 519 | regs->elm_syndrome_fragment_3[i]); |
517 | elm_write_reg(info, ELM_SYNDROME_FRAGMENT_2 + offset, | 520 | elm_write_reg(info, ELM_SYNDROME_FRAGMENT_2 + offset, |
518 | regs->elm_syndrome_fragment_2[i]); | 521 | regs->elm_syndrome_fragment_2[i]); |
522 | /* fall through */ | ||
519 | case BCH4_ECC: | 523 | case BCH4_ECC: |
520 | elm_write_reg(info, ELM_SYNDROME_FRAGMENT_1 + offset, | 524 | elm_write_reg(info, ELM_SYNDROME_FRAGMENT_1 + offset, |
521 | regs->elm_syndrome_fragment_1[i]); | 525 | regs->elm_syndrome_fragment_1[i]); |
diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c index 920e7375084f..6ead55e05b80 100644 --- a/drivers/mtd/nand/raw/qcom_nandc.c +++ b/drivers/mtd/nand/raw/qcom_nandc.c | |||
@@ -1680,14 +1680,12 @@ check_for_erased_page(struct qcom_nand_host *host, u8 *data_buf, | |||
1680 | u8 *cw_data_buf, *cw_oob_buf; | 1680 | u8 *cw_data_buf, *cw_oob_buf; |
1681 | int cw, data_size, oob_size, ret = 0; | 1681 | int cw, data_size, oob_size, ret = 0; |
1682 | 1682 | ||
1683 | if (!data_buf) { | 1683 | if (!data_buf) |
1684 | data_buf = chip->data_buf; | 1684 | data_buf = nand_get_data_buf(chip); |
1685 | chip->pagebuf = -1; | ||
1686 | } | ||
1687 | 1685 | ||
1688 | if (!oob_buf) { | 1686 | if (!oob_buf) { |
1687 | nand_get_data_buf(chip); | ||
1689 | oob_buf = chip->oob_poi; | 1688 | oob_buf = chip->oob_poi; |
1690 | chip->pagebuf = -1; | ||
1691 | } | 1689 | } |
1692 | 1690 | ||
1693 | for_each_set_bit(cw, &uncorrectable_cws, ecc->steps) { | 1691 | for_each_set_bit(cw, &uncorrectable_cws, ecc->steps) { |
diff --git a/drivers/mtd/nand/raw/sh_flctl.c b/drivers/mtd/nand/raw/sh_flctl.c index cf6b1be1cf9c..e509c93737c4 100644 --- a/drivers/mtd/nand/raw/sh_flctl.c +++ b/drivers/mtd/nand/raw/sh_flctl.c | |||
@@ -101,14 +101,12 @@ static const struct mtd_ooblayout_ops flctl_4secc_oob_largepage_ops = { | |||
101 | static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; | 101 | static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; |
102 | 102 | ||
103 | static struct nand_bbt_descr flctl_4secc_smallpage = { | 103 | static struct nand_bbt_descr flctl_4secc_smallpage = { |
104 | .options = NAND_BBT_SCAN2NDPAGE, | ||
105 | .offs = 11, | 104 | .offs = 11, |
106 | .len = 1, | 105 | .len = 1, |
107 | .pattern = scan_ff_pattern, | 106 | .pattern = scan_ff_pattern, |
108 | }; | 107 | }; |
109 | 108 | ||
110 | static struct nand_bbt_descr flctl_4secc_largepage = { | 109 | static struct nand_bbt_descr flctl_4secc_largepage = { |
111 | .options = NAND_BBT_SCAN2NDPAGE, | ||
112 | .offs = 0, | 110 | .offs = 0, |
113 | .len = 2, | 111 | .len = 2, |
114 | .pattern = scan_ff_pattern, | 112 | .pattern = scan_ff_pattern, |
@@ -986,6 +984,7 @@ static void flctl_read_buf(struct nand_chip *chip, uint8_t *buf, int len) | |||
986 | 984 | ||
987 | static int flctl_chip_attach_chip(struct nand_chip *chip) | 985 | static int flctl_chip_attach_chip(struct nand_chip *chip) |
988 | { | 986 | { |
987 | u64 targetsize = nanddev_target_size(&chip->base); | ||
989 | struct mtd_info *mtd = nand_to_mtd(chip); | 988 | struct mtd_info *mtd = nand_to_mtd(chip); |
990 | struct sh_flctl *flctl = mtd_to_flctl(mtd); | 989 | struct sh_flctl *flctl = mtd_to_flctl(mtd); |
991 | 990 | ||
@@ -998,11 +997,11 @@ static int flctl_chip_attach_chip(struct nand_chip *chip) | |||
998 | 997 | ||
999 | if (mtd->writesize == 512) { | 998 | if (mtd->writesize == 512) { |
1000 | flctl->page_size = 0; | 999 | flctl->page_size = 0; |
1001 | if (chip->chipsize > (32 << 20)) { | 1000 | if (targetsize > (32 << 20)) { |
1002 | /* big than 32MB */ | 1001 | /* big than 32MB */ |
1003 | flctl->rw_ADRCNT = ADRCNT_4; | 1002 | flctl->rw_ADRCNT = ADRCNT_4; |
1004 | flctl->erase_ADRCNT = ADRCNT_3; | 1003 | flctl->erase_ADRCNT = ADRCNT_3; |
1005 | } else if (chip->chipsize > (2 << 16)) { | 1004 | } else if (targetsize > (2 << 16)) { |
1006 | /* big than 128KB */ | 1005 | /* big than 128KB */ |
1007 | flctl->rw_ADRCNT = ADRCNT_3; | 1006 | flctl->rw_ADRCNT = ADRCNT_3; |
1008 | flctl->erase_ADRCNT = ADRCNT_2; | 1007 | flctl->erase_ADRCNT = ADRCNT_2; |
@@ -1012,11 +1011,11 @@ static int flctl_chip_attach_chip(struct nand_chip *chip) | |||
1012 | } | 1011 | } |
1013 | } else { | 1012 | } else { |
1014 | flctl->page_size = 1; | 1013 | flctl->page_size = 1; |
1015 | if (chip->chipsize > (128 << 20)) { | 1014 | if (targetsize > (128 << 20)) { |
1016 | /* big than 128MB */ | 1015 | /* big than 128MB */ |
1017 | flctl->rw_ADRCNT = ADRCNT2_E; | 1016 | flctl->rw_ADRCNT = ADRCNT2_E; |
1018 | flctl->erase_ADRCNT = ADRCNT_3; | 1017 | flctl->erase_ADRCNT = ADRCNT_3; |
1019 | } else if (chip->chipsize > (8 << 16)) { | 1018 | } else if (targetsize > (8 << 16)) { |
1020 | /* big than 512KB */ | 1019 | /* big than 512KB */ |
1021 | flctl->rw_ADRCNT = ADRCNT_4; | 1020 | flctl->rw_ADRCNT = ADRCNT_4; |
1022 | flctl->erase_ADRCNT = ADRCNT_2; | 1021 | flctl->erase_ADRCNT = ADRCNT_2; |
@@ -1178,6 +1177,8 @@ static int flctl_probe(struct platform_device *pdev) | |||
1178 | if (pdata->flcmncr_val & SEL_16BIT) | 1177 | if (pdata->flcmncr_val & SEL_16BIT) |
1179 | nand->options |= NAND_BUSWIDTH_16; | 1178 | nand->options |= NAND_BUSWIDTH_16; |
1180 | 1179 | ||
1180 | nand->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE; | ||
1181 | |||
1181 | pm_runtime_enable(&pdev->dev); | 1182 | pm_runtime_enable(&pdev->dev); |
1182 | pm_runtime_resume(&pdev->dev); | 1183 | pm_runtime_resume(&pdev->dev); |
1183 | 1184 | ||
diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index 4282bc477761..b021a5720b42 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c | |||
@@ -42,7 +42,8 @@ | |||
42 | #define NFC_REG_CMD 0x0024 | 42 | #define NFC_REG_CMD 0x0024 |
43 | #define NFC_REG_RCMD_SET 0x0028 | 43 | #define NFC_REG_RCMD_SET 0x0028 |
44 | #define NFC_REG_WCMD_SET 0x002C | 44 | #define NFC_REG_WCMD_SET 0x002C |
45 | #define NFC_REG_IO_DATA 0x0030 | 45 | #define NFC_REG_A10_IO_DATA 0x0030 |
46 | #define NFC_REG_A23_IO_DATA 0x0300 | ||
46 | #define NFC_REG_ECC_CTL 0x0034 | 47 | #define NFC_REG_ECC_CTL 0x0034 |
47 | #define NFC_REG_ECC_ST 0x0038 | 48 | #define NFC_REG_ECC_ST 0x0038 |
48 | #define NFC_REG_DEBUG 0x003C | 49 | #define NFC_REG_DEBUG 0x003C |
@@ -200,6 +201,22 @@ static inline struct sunxi_nand_chip *to_sunxi_nand(struct nand_chip *nand) | |||
200 | return container_of(nand, struct sunxi_nand_chip, nand); | 201 | return container_of(nand, struct sunxi_nand_chip, nand); |
201 | } | 202 | } |
202 | 203 | ||
204 | /* | ||
205 | * NAND Controller capabilities structure: stores NAND controller capabilities | ||
206 | * for distinction between compatible strings. | ||
207 | * | ||
208 | * @sram_through_ahb: On A23, we choose to access the internal RAM through AHB | ||
209 | * instead of MBUS (less configuration). A10, A10s, A13 and | ||
210 | * A20 use the MBUS but no extra configuration is needed. | ||
211 | * @reg_io_data: I/O data register | ||
212 | * @dma_maxburst: DMA maxburst | ||
213 | */ | ||
214 | struct sunxi_nfc_caps { | ||
215 | bool sram_through_ahb; | ||
216 | unsigned int reg_io_data; | ||
217 | unsigned int dma_maxburst; | ||
218 | }; | ||
219 | |||
203 | /** | 220 | /** |
204 | * struct sunxi_nfc - stores sunxi NAND controller information | 221 | * struct sunxi_nfc - stores sunxi NAND controller information |
205 | * | 222 | * |
@@ -228,6 +245,7 @@ struct sunxi_nfc { | |||
228 | struct list_head chips; | 245 | struct list_head chips; |
229 | struct completion complete; | 246 | struct completion complete; |
230 | struct dma_chan *dmac; | 247 | struct dma_chan *dmac; |
248 | const struct sunxi_nfc_caps *caps; | ||
231 | }; | 249 | }; |
232 | 250 | ||
233 | static inline struct sunxi_nfc *to_sunxi_nfc(struct nand_controller *ctrl) | 251 | static inline struct sunxi_nfc *to_sunxi_nfc(struct nand_controller *ctrl) |
@@ -350,10 +368,29 @@ static int sunxi_nfc_dma_op_prepare(struct sunxi_nfc *nfc, const void *buf, | |||
350 | goto err_unmap_buf; | 368 | goto err_unmap_buf; |
351 | } | 369 | } |
352 | 370 | ||
353 | writel(readl(nfc->regs + NFC_REG_CTL) | NFC_RAM_METHOD, | 371 | /* |
354 | nfc->regs + NFC_REG_CTL); | 372 | * On A23, we suppose the "internal RAM" (p.12 of the NFC user manual) |
373 | * refers to the NAND controller's internal SRAM. This memory is mapped | ||
374 | * and so is accessible from the AHB. It seems that it can also be | ||
375 | * accessed by the MBUS. MBUS accesses are mandatory when using the | ||
376 | * internal DMA instead of the external DMA engine. | ||
377 | * | ||
378 | * During DMA I/O operation, either we access this memory from the AHB | ||
379 | * by clearing the NFC_RAM_METHOD bit, or we set the bit and use the | ||
380 | * MBUS. In this case, we should also configure the MBUS DMA length | ||
381 | * NFC_REG_MDMA_CNT(0xC4) to be chunksize * nchunks. NAND I/O over MBUS | ||
382 | * are also limited to 32kiB pages. | ||
383 | */ | ||
384 | if (nfc->caps->sram_through_ahb) | ||
385 | writel(readl(nfc->regs + NFC_REG_CTL) & ~NFC_RAM_METHOD, | ||
386 | nfc->regs + NFC_REG_CTL); | ||
387 | else | ||
388 | writel(readl(nfc->regs + NFC_REG_CTL) | NFC_RAM_METHOD, | ||
389 | nfc->regs + NFC_REG_CTL); | ||
390 | |||
355 | writel(nchunks, nfc->regs + NFC_REG_SECTOR_NUM); | 391 | writel(nchunks, nfc->regs + NFC_REG_SECTOR_NUM); |
356 | writel(chunksize, nfc->regs + NFC_REG_CNT); | 392 | writel(chunksize, nfc->regs + NFC_REG_CNT); |
393 | |||
357 | dmat = dmaengine_submit(dmad); | 394 | dmat = dmaengine_submit(dmad); |
358 | 395 | ||
359 | ret = dma_submit_error(dmat); | 396 | ret = dma_submit_error(dmat); |
@@ -1313,20 +1350,19 @@ pio_fallback: | |||
1313 | 1350 | ||
1314 | static int sunxi_nfc_hw_ecc_read_oob(struct nand_chip *nand, int page) | 1351 | static int sunxi_nfc_hw_ecc_read_oob(struct nand_chip *nand, int page) |
1315 | { | 1352 | { |
1316 | nand->pagebuf = -1; | 1353 | u8 *buf = nand_get_data_buf(nand); |
1317 | 1354 | ||
1318 | return nand->ecc.read_page(nand, nand->data_buf, 1, page); | 1355 | return nand->ecc.read_page(nand, buf, 1, page); |
1319 | } | 1356 | } |
1320 | 1357 | ||
1321 | static int sunxi_nfc_hw_ecc_write_oob(struct nand_chip *nand, int page) | 1358 | static int sunxi_nfc_hw_ecc_write_oob(struct nand_chip *nand, int page) |
1322 | { | 1359 | { |
1323 | struct mtd_info *mtd = nand_to_mtd(nand); | 1360 | struct mtd_info *mtd = nand_to_mtd(nand); |
1361 | u8 *buf = nand_get_data_buf(nand); | ||
1324 | int ret; | 1362 | int ret; |
1325 | 1363 | ||
1326 | nand->pagebuf = -1; | 1364 | memset(buf, 0xff, mtd->writesize); |
1327 | 1365 | ret = nand->ecc.write_page(nand, buf, 1, page); | |
1328 | memset(nand->data_buf, 0xff, mtd->writesize); | ||
1329 | ret = nand->ecc.write_page(nand, nand->data_buf, 1, page); | ||
1330 | if (ret) | 1366 | if (ret) |
1331 | return ret; | 1367 | return ret; |
1332 | 1368 | ||
@@ -1724,8 +1760,8 @@ static int sunxi_nand_attach_chip(struct nand_chip *nand) | |||
1724 | nand->options |= NAND_SUBPAGE_READ; | 1760 | nand->options |= NAND_SUBPAGE_READ; |
1725 | 1761 | ||
1726 | if (!ecc->size) { | 1762 | if (!ecc->size) { |
1727 | ecc->size = nand->ecc_step_ds; | 1763 | ecc->size = nand->base.eccreq.step_size; |
1728 | ecc->strength = nand->ecc_strength_ds; | 1764 | ecc->strength = nand->base.eccreq.strength; |
1729 | } | 1765 | } |
1730 | 1766 | ||
1731 | if (!ecc->size || !ecc->strength) | 1767 | if (!ecc->size || !ecc->strength) |
@@ -2088,6 +2124,12 @@ static int sunxi_nfc_probe(struct platform_device *pdev) | |||
2088 | goto out_mod_clk_unprepare; | 2124 | goto out_mod_clk_unprepare; |
2089 | } | 2125 | } |
2090 | 2126 | ||
2127 | nfc->caps = of_device_get_match_data(&pdev->dev); | ||
2128 | if (!nfc->caps) { | ||
2129 | ret = -EINVAL; | ||
2130 | goto out_ahb_reset_reassert; | ||
2131 | } | ||
2132 | |||
2091 | ret = sunxi_nfc_rst(nfc); | 2133 | ret = sunxi_nfc_rst(nfc); |
2092 | if (ret) | 2134 | if (ret) |
2093 | goto out_ahb_reset_reassert; | 2135 | goto out_ahb_reset_reassert; |
@@ -2102,12 +2144,12 @@ static int sunxi_nfc_probe(struct platform_device *pdev) | |||
2102 | if (nfc->dmac) { | 2144 | if (nfc->dmac) { |
2103 | struct dma_slave_config dmac_cfg = { }; | 2145 | struct dma_slave_config dmac_cfg = { }; |
2104 | 2146 | ||
2105 | dmac_cfg.src_addr = r->start + NFC_REG_IO_DATA; | 2147 | dmac_cfg.src_addr = r->start + nfc->caps->reg_io_data; |
2106 | dmac_cfg.dst_addr = dmac_cfg.src_addr; | 2148 | dmac_cfg.dst_addr = dmac_cfg.src_addr; |
2107 | dmac_cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | 2149 | dmac_cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; |
2108 | dmac_cfg.dst_addr_width = dmac_cfg.src_addr_width; | 2150 | dmac_cfg.dst_addr_width = dmac_cfg.src_addr_width; |
2109 | dmac_cfg.src_maxburst = 4; | 2151 | dmac_cfg.src_maxburst = nfc->caps->dma_maxburst; |
2110 | dmac_cfg.dst_maxburst = 4; | 2152 | dmac_cfg.dst_maxburst = nfc->caps->dma_maxburst; |
2111 | dmaengine_slave_config(nfc->dmac, &dmac_cfg); | 2153 | dmaengine_slave_config(nfc->dmac, &dmac_cfg); |
2112 | } else { | 2154 | } else { |
2113 | dev_warn(dev, "failed to request rxtx DMA channel\n"); | 2155 | dev_warn(dev, "failed to request rxtx DMA channel\n"); |
@@ -2152,8 +2194,26 @@ static int sunxi_nfc_remove(struct platform_device *pdev) | |||
2152 | return 0; | 2194 | return 0; |
2153 | } | 2195 | } |
2154 | 2196 | ||
2197 | static const struct sunxi_nfc_caps sunxi_nfc_a10_caps = { | ||
2198 | .reg_io_data = NFC_REG_A10_IO_DATA, | ||
2199 | .dma_maxburst = 4, | ||
2200 | }; | ||
2201 | |||
2202 | static const struct sunxi_nfc_caps sunxi_nfc_a23_caps = { | ||
2203 | .sram_through_ahb = true, | ||
2204 | .reg_io_data = NFC_REG_A23_IO_DATA, | ||
2205 | .dma_maxburst = 8, | ||
2206 | }; | ||
2207 | |||
2155 | static const struct of_device_id sunxi_nfc_ids[] = { | 2208 | static const struct of_device_id sunxi_nfc_ids[] = { |
2156 | { .compatible = "allwinner,sun4i-a10-nand" }, | 2209 | { |
2210 | .compatible = "allwinner,sun4i-a10-nand", | ||
2211 | .data = &sunxi_nfc_a10_caps, | ||
2212 | }, | ||
2213 | { | ||
2214 | .compatible = "allwinner,sun8i-a23-nand-controller", | ||
2215 | .data = &sunxi_nfc_a23_caps, | ||
2216 | }, | ||
2157 | { /* sentinel */ } | 2217 | { /* sentinel */ } |
2158 | }; | 2218 | }; |
2159 | MODULE_DEVICE_TABLE(of, sunxi_nfc_ids); | 2219 | MODULE_DEVICE_TABLE(of, sunxi_nfc_ids); |
diff --git a/drivers/mtd/nand/raw/tegra_nand.c b/drivers/mtd/nand/raw/tegra_nand.c index 13be32c38194..3cc9a4c41443 100644 --- a/drivers/mtd/nand/raw/tegra_nand.c +++ b/drivers/mtd/nand/raw/tegra_nand.c | |||
@@ -853,7 +853,7 @@ static int tegra_nand_get_strength(struct nand_chip *chip, const int *strength, | |||
853 | } else { | 853 | } else { |
854 | strength_sel = strength[i]; | 854 | strength_sel = strength[i]; |
855 | 855 | ||
856 | if (strength_sel < chip->ecc_strength_ds) | 856 | if (strength_sel < chip->base.eccreq.strength) |
857 | continue; | 857 | continue; |
858 | } | 858 | } |
859 | 859 | ||
@@ -917,9 +917,9 @@ static int tegra_nand_attach_chip(struct nand_chip *chip) | |||
917 | chip->ecc.mode = NAND_ECC_HW; | 917 | chip->ecc.mode = NAND_ECC_HW; |
918 | chip->ecc.size = 512; | 918 | chip->ecc.size = 512; |
919 | chip->ecc.steps = mtd->writesize / chip->ecc.size; | 919 | chip->ecc.steps = mtd->writesize / chip->ecc.size; |
920 | if (chip->ecc_step_ds != 512) { | 920 | if (chip->base.eccreq.step_size != 512) { |
921 | dev_err(ctrl->dev, "Unsupported step size %d\n", | 921 | dev_err(ctrl->dev, "Unsupported step size %d\n", |
922 | chip->ecc_step_ds); | 922 | chip->base.eccreq.step_size); |
923 | return -EINVAL; | 923 | return -EINVAL; |
924 | } | 924 | } |
925 | 925 | ||
@@ -950,7 +950,7 @@ static int tegra_nand_attach_chip(struct nand_chip *chip) | |||
950 | if (ret < 0) { | 950 | if (ret < 0) { |
951 | dev_err(ctrl->dev, | 951 | dev_err(ctrl->dev, |
952 | "No valid strength found, minimum %d\n", | 952 | "No valid strength found, minimum %d\n", |
953 | chip->ecc_strength_ds); | 953 | chip->base.eccreq.strength); |
954 | return ret; | 954 | return ret; |
955 | } | 955 | } |
956 | 956 | ||
diff --git a/drivers/mtd/nand/raw/vf610_nfc.c b/drivers/mtd/nand/raw/vf610_nfc.c index a662ca1970e5..6d43ddb3332f 100644 --- a/drivers/mtd/nand/raw/vf610_nfc.c +++ b/drivers/mtd/nand/raw/vf610_nfc.c | |||
@@ -850,6 +850,9 @@ static int vf610_nfc_probe(struct platform_device *pdev) | |||
850 | } | 850 | } |
851 | 851 | ||
852 | of_id = of_match_device(vf610_nfc_dt_ids, &pdev->dev); | 852 | of_id = of_match_device(vf610_nfc_dt_ids, &pdev->dev); |
853 | if (!of_id) | ||
854 | return -ENODEV; | ||
855 | |||
853 | nfc->variant = (enum vf610_nfc_variant)of_id->data; | 856 | nfc->variant = (enum vf610_nfc_variant)of_id->data; |
854 | 857 | ||
855 | for_each_available_child_of_node(nfc->dev->of_node, child) { | 858 | for_each_available_child_of_node(nfc->dev->of_node, child) { |
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c index fa87ae28cdfe..4c15bb58c623 100644 --- a/drivers/mtd/nand/spi/core.c +++ b/drivers/mtd/nand/spi/core.c | |||
@@ -19,21 +19,6 @@ | |||
19 | #include <linux/spi/spi.h> | 19 | #include <linux/spi/spi.h> |
20 | #include <linux/spi/spi-mem.h> | 20 | #include <linux/spi/spi-mem.h> |
21 | 21 | ||
22 | static void spinand_cache_op_adjust_colum(struct spinand_device *spinand, | ||
23 | const struct nand_page_io_req *req, | ||
24 | u16 *column) | ||
25 | { | ||
26 | struct nand_device *nand = spinand_to_nand(spinand); | ||
27 | unsigned int shift; | ||
28 | |||
29 | if (nand->memorg.planes_per_lun < 2) | ||
30 | return; | ||
31 | |||
32 | /* The plane number is passed in MSB just above the column address */ | ||
33 | shift = fls(nand->memorg.pagesize); | ||
34 | *column |= req->pos.plane << shift; | ||
35 | } | ||
36 | |||
37 | static int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val) | 22 | static int spinand_read_reg_op(struct spinand_device *spinand, u8 reg, u8 *val) |
38 | { | 23 | { |
39 | struct spi_mem_op op = SPINAND_GET_FEATURE_OP(reg, | 24 | struct spi_mem_op op = SPINAND_GET_FEATURE_OP(reg, |
@@ -227,27 +212,21 @@ static int spinand_load_page_op(struct spinand_device *spinand, | |||
227 | static int spinand_read_from_cache_op(struct spinand_device *spinand, | 212 | static int spinand_read_from_cache_op(struct spinand_device *spinand, |
228 | const struct nand_page_io_req *req) | 213 | const struct nand_page_io_req *req) |
229 | { | 214 | { |
230 | struct spi_mem_op op = *spinand->op_templates.read_cache; | ||
231 | struct nand_device *nand = spinand_to_nand(spinand); | 215 | struct nand_device *nand = spinand_to_nand(spinand); |
232 | struct mtd_info *mtd = nanddev_to_mtd(nand); | 216 | struct mtd_info *mtd = nanddev_to_mtd(nand); |
233 | struct nand_page_io_req adjreq = *req; | 217 | struct spi_mem_dirmap_desc *rdesc; |
234 | unsigned int nbytes = 0; | 218 | unsigned int nbytes = 0; |
235 | void *buf = NULL; | 219 | void *buf = NULL; |
236 | u16 column = 0; | 220 | u16 column = 0; |
237 | int ret; | 221 | ssize_t ret; |
238 | 222 | ||
239 | if (req->datalen) { | 223 | if (req->datalen) { |
240 | adjreq.datalen = nanddev_page_size(nand); | ||
241 | adjreq.dataoffs = 0; | ||
242 | adjreq.databuf.in = spinand->databuf; | ||
243 | buf = spinand->databuf; | 224 | buf = spinand->databuf; |
244 | nbytes = adjreq.datalen; | 225 | nbytes = nanddev_page_size(nand); |
226 | column = 0; | ||
245 | } | 227 | } |
246 | 228 | ||
247 | if (req->ooblen) { | 229 | if (req->ooblen) { |
248 | adjreq.ooblen = nanddev_per_page_oobsize(nand); | ||
249 | adjreq.ooboffs = 0; | ||
250 | adjreq.oobbuf.in = spinand->oobbuf; | ||
251 | nbytes += nanddev_per_page_oobsize(nand); | 230 | nbytes += nanddev_per_page_oobsize(nand); |
252 | if (!buf) { | 231 | if (!buf) { |
253 | buf = spinand->oobbuf; | 232 | buf = spinand->oobbuf; |
@@ -255,28 +234,19 @@ static int spinand_read_from_cache_op(struct spinand_device *spinand, | |||
255 | } | 234 | } |
256 | } | 235 | } |
257 | 236 | ||
258 | spinand_cache_op_adjust_colum(spinand, &adjreq, &column); | 237 | rdesc = spinand->dirmaps[req->pos.plane].rdesc; |
259 | op.addr.val = column; | ||
260 | 238 | ||
261 | /* | ||
262 | * Some controllers are limited in term of max RX data size. In this | ||
263 | * case, just repeat the READ_CACHE operation after updating the | ||
264 | * column. | ||
265 | */ | ||
266 | while (nbytes) { | 239 | while (nbytes) { |
267 | op.data.buf.in = buf; | 240 | ret = spi_mem_dirmap_read(rdesc, column, nbytes, buf); |
268 | op.data.nbytes = nbytes; | 241 | if (ret < 0) |
269 | ret = spi_mem_adjust_op_size(spinand->spimem, &op); | ||
270 | if (ret) | ||
271 | return ret; | 242 | return ret; |
272 | 243 | ||
273 | ret = spi_mem_exec_op(spinand->spimem, &op); | 244 | if (!ret || ret > nbytes) |
274 | if (ret) | 245 | return -EIO; |
275 | return ret; | ||
276 | 246 | ||
277 | buf += op.data.nbytes; | 247 | nbytes -= ret; |
278 | nbytes -= op.data.nbytes; | 248 | column += ret; |
279 | op.addr.val += op.data.nbytes; | 249 | buf += ret; |
280 | } | 250 | } |
281 | 251 | ||
282 | if (req->datalen) | 252 | if (req->datalen) |
@@ -300,14 +270,12 @@ static int spinand_read_from_cache_op(struct spinand_device *spinand, | |||
300 | static int spinand_write_to_cache_op(struct spinand_device *spinand, | 270 | static int spinand_write_to_cache_op(struct spinand_device *spinand, |
301 | const struct nand_page_io_req *req) | 271 | const struct nand_page_io_req *req) |
302 | { | 272 | { |
303 | struct spi_mem_op op = *spinand->op_templates.write_cache; | ||
304 | struct nand_device *nand = spinand_to_nand(spinand); | 273 | struct nand_device *nand = spinand_to_nand(spinand); |
305 | struct mtd_info *mtd = nanddev_to_mtd(nand); | 274 | struct mtd_info *mtd = nanddev_to_mtd(nand); |
306 | struct nand_page_io_req adjreq = *req; | 275 | struct spi_mem_dirmap_desc *wdesc; |
276 | unsigned int nbytes, column = 0; | ||
307 | void *buf = spinand->databuf; | 277 | void *buf = spinand->databuf; |
308 | unsigned int nbytes; | 278 | ssize_t ret; |
309 | u16 column = 0; | ||
310 | int ret; | ||
311 | 279 | ||
312 | /* | 280 | /* |
313 | * Looks like PROGRAM LOAD (AKA write cache) does not necessarily reset | 281 | * Looks like PROGRAM LOAD (AKA write cache) does not necessarily reset |
@@ -318,12 +286,6 @@ static int spinand_write_to_cache_op(struct spinand_device *spinand, | |||
318 | */ | 286 | */ |
319 | nbytes = nanddev_page_size(nand) + nanddev_per_page_oobsize(nand); | 287 | nbytes = nanddev_page_size(nand) + nanddev_per_page_oobsize(nand); |
320 | memset(spinand->databuf, 0xff, nbytes); | 288 | memset(spinand->databuf, 0xff, nbytes); |
321 | adjreq.dataoffs = 0; | ||
322 | adjreq.datalen = nanddev_page_size(nand); | ||
323 | adjreq.databuf.out = spinand->databuf; | ||
324 | adjreq.ooblen = nanddev_per_page_oobsize(nand); | ||
325 | adjreq.ooboffs = 0; | ||
326 | adjreq.oobbuf.out = spinand->oobbuf; | ||
327 | 289 | ||
328 | if (req->datalen) | 290 | if (req->datalen) |
329 | memcpy(spinand->databuf + req->dataoffs, req->databuf.out, | 291 | memcpy(spinand->databuf + req->dataoffs, req->databuf.out, |
@@ -340,42 +302,19 @@ static int spinand_write_to_cache_op(struct spinand_device *spinand, | |||
340 | req->ooblen); | 302 | req->ooblen); |
341 | } | 303 | } |
342 | 304 | ||
343 | spinand_cache_op_adjust_colum(spinand, &adjreq, &column); | 305 | wdesc = spinand->dirmaps[req->pos.plane].wdesc; |
344 | 306 | ||
345 | op = *spinand->op_templates.write_cache; | ||
346 | op.addr.val = column; | ||
347 | |||
348 | /* | ||
349 | * Some controllers are limited in term of max TX data size. In this | ||
350 | * case, split the operation into one LOAD CACHE and one or more | ||
351 | * LOAD RANDOM CACHE. | ||
352 | */ | ||
353 | while (nbytes) { | 307 | while (nbytes) { |
354 | op.data.buf.out = buf; | 308 | ret = spi_mem_dirmap_write(wdesc, column, nbytes, buf); |
355 | op.data.nbytes = nbytes; | 309 | if (ret < 0) |
356 | |||
357 | ret = spi_mem_adjust_op_size(spinand->spimem, &op); | ||
358 | if (ret) | ||
359 | return ret; | ||
360 | |||
361 | ret = spi_mem_exec_op(spinand->spimem, &op); | ||
362 | if (ret) | ||
363 | return ret; | 310 | return ret; |
364 | 311 | ||
365 | buf += op.data.nbytes; | 312 | if (!ret || ret > nbytes) |
366 | nbytes -= op.data.nbytes; | 313 | return -EIO; |
367 | op.addr.val += op.data.nbytes; | ||
368 | 314 | ||
369 | /* | 315 | nbytes -= ret; |
370 | * We need to use the RANDOM LOAD CACHE operation if there's | 316 | column += ret; |
371 | * more than one iteration, because the LOAD operation might | 317 | buf += ret; |
372 | * reset the cache to 0xff. | ||
373 | */ | ||
374 | if (nbytes) { | ||
375 | column = op.addr.val; | ||
376 | op = *spinand->op_templates.update_cache; | ||
377 | op.addr.val = column; | ||
378 | } | ||
379 | } | 318 | } |
380 | 319 | ||
381 | return 0; | 320 | return 0; |
@@ -755,6 +694,59 @@ static int spinand_mtd_block_isreserved(struct mtd_info *mtd, loff_t offs) | |||
755 | return ret; | 694 | return ret; |
756 | } | 695 | } |
757 | 696 | ||
697 | static int spinand_create_dirmap(struct spinand_device *spinand, | ||
698 | unsigned int plane) | ||
699 | { | ||
700 | struct nand_device *nand = spinand_to_nand(spinand); | ||
701 | struct spi_mem_dirmap_info info = { | ||
702 | .length = nanddev_page_size(nand) + | ||
703 | nanddev_per_page_oobsize(nand), | ||
704 | }; | ||
705 | struct spi_mem_dirmap_desc *desc; | ||
706 | |||
707 | /* The plane number is passed in MSB just above the column address */ | ||
708 | info.offset = plane << fls(nand->memorg.pagesize); | ||
709 | |||
710 | info.op_tmpl = *spinand->op_templates.update_cache; | ||
711 | desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, | ||
712 | spinand->spimem, &info); | ||
713 | if (IS_ERR(desc)) | ||
714 | return PTR_ERR(desc); | ||
715 | |||
716 | spinand->dirmaps[plane].wdesc = desc; | ||
717 | |||
718 | info.op_tmpl = *spinand->op_templates.read_cache; | ||
719 | desc = devm_spi_mem_dirmap_create(&spinand->spimem->spi->dev, | ||
720 | spinand->spimem, &info); | ||
721 | if (IS_ERR(desc)) | ||
722 | return PTR_ERR(desc); | ||
723 | |||
724 | spinand->dirmaps[plane].rdesc = desc; | ||
725 | |||
726 | return 0; | ||
727 | } | ||
728 | |||
729 | static int spinand_create_dirmaps(struct spinand_device *spinand) | ||
730 | { | ||
731 | struct nand_device *nand = spinand_to_nand(spinand); | ||
732 | int i, ret; | ||
733 | |||
734 | spinand->dirmaps = devm_kzalloc(&spinand->spimem->spi->dev, | ||
735 | sizeof(*spinand->dirmaps) * | ||
736 | nand->memorg.planes_per_lun, | ||
737 | GFP_KERNEL); | ||
738 | if (!spinand->dirmaps) | ||
739 | return -ENOMEM; | ||
740 | |||
741 | for (i = 0; i < nand->memorg.planes_per_lun; i++) { | ||
742 | ret = spinand_create_dirmap(spinand, i); | ||
743 | if (ret) | ||
744 | return ret; | ||
745 | } | ||
746 | |||
747 | return 0; | ||
748 | } | ||
749 | |||
758 | static const struct nand_ops spinand_ops = { | 750 | static const struct nand_ops spinand_ops = { |
759 | .erase = spinand_erase, | 751 | .erase = spinand_erase, |
760 | .markbad = spinand_markbad, | 752 | .markbad = spinand_markbad, |
@@ -1012,6 +1004,14 @@ static int spinand_init(struct spinand_device *spinand) | |||
1012 | goto err_free_bufs; | 1004 | goto err_free_bufs; |
1013 | } | 1005 | } |
1014 | 1006 | ||
1007 | ret = spinand_create_dirmaps(spinand); | ||
1008 | if (ret) { | ||
1009 | dev_err(dev, | ||
1010 | "Failed to create direct mappings for read/write operations (err = %d)\n", | ||
1011 | ret); | ||
1012 | goto err_manuf_cleanup; | ||
1013 | } | ||
1014 | |||
1015 | /* After power up, all blocks are locked, so unlock them here. */ | 1015 | /* After power up, all blocks are locked, so unlock them here. */ |
1016 | for (i = 0; i < nand->memorg.ntargets; i++) { | 1016 | for (i = 0; i < nand->memorg.ntargets; i++) { |
1017 | ret = spinand_select_target(spinand, i); | 1017 | ret = spinand_select_target(spinand, i); |
@@ -1037,6 +1037,7 @@ static int spinand_init(struct spinand_device *spinand) | |||
1037 | mtd->_block_markbad = spinand_mtd_block_markbad; | 1037 | mtd->_block_markbad = spinand_mtd_block_markbad; |
1038 | mtd->_block_isreserved = spinand_mtd_block_isreserved; | 1038 | mtd->_block_isreserved = spinand_mtd_block_isreserved; |
1039 | mtd->_erase = spinand_mtd_erase; | 1039 | mtd->_erase = spinand_mtd_erase; |
1040 | mtd->_max_bad_blocks = nanddev_mtd_max_bad_blocks; | ||
1040 | 1041 | ||
1041 | if (spinand->eccinfo.ooblayout) | 1042 | if (spinand->eccinfo.ooblayout) |
1042 | mtd_set_ooblayout(mtd, spinand->eccinfo.ooblayout); | 1043 | mtd_set_ooblayout(mtd, spinand->eccinfo.ooblayout); |
diff --git a/drivers/mtd/nand/spi/gigadevice.c b/drivers/mtd/nand/spi/gigadevice.c index 0b49d8264bef..e5586390026a 100644 --- a/drivers/mtd/nand/spi/gigadevice.c +++ b/drivers/mtd/nand/spi/gigadevice.c | |||
@@ -162,7 +162,7 @@ static const struct mtd_ooblayout_ops gd5fxgq4uexxg_ooblayout = { | |||
162 | 162 | ||
163 | static const struct spinand_info gigadevice_spinand_table[] = { | 163 | static const struct spinand_info gigadevice_spinand_table[] = { |
164 | SPINAND_INFO("GD5F1GQ4xA", 0xF1, | 164 | SPINAND_INFO("GD5F1GQ4xA", 0xF1, |
165 | NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1), | 165 | NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), |
166 | NAND_ECCREQ(8, 512), | 166 | NAND_ECCREQ(8, 512), |
167 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, | 167 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
168 | &write_cache_variants, | 168 | &write_cache_variants, |
@@ -171,7 +171,7 @@ static const struct spinand_info gigadevice_spinand_table[] = { | |||
171 | SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, | 171 | SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, |
172 | gd5fxgq4xa_ecc_get_status)), | 172 | gd5fxgq4xa_ecc_get_status)), |
173 | SPINAND_INFO("GD5F2GQ4xA", 0xF2, | 173 | SPINAND_INFO("GD5F2GQ4xA", 0xF2, |
174 | NAND_MEMORG(1, 2048, 64, 64, 2048, 1, 1, 1), | 174 | NAND_MEMORG(1, 2048, 64, 64, 2048, 40, 1, 1, 1), |
175 | NAND_ECCREQ(8, 512), | 175 | NAND_ECCREQ(8, 512), |
176 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, | 176 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
177 | &write_cache_variants, | 177 | &write_cache_variants, |
@@ -180,7 +180,7 @@ static const struct spinand_info gigadevice_spinand_table[] = { | |||
180 | SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, | 180 | SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, |
181 | gd5fxgq4xa_ecc_get_status)), | 181 | gd5fxgq4xa_ecc_get_status)), |
182 | SPINAND_INFO("GD5F4GQ4xA", 0xF4, | 182 | SPINAND_INFO("GD5F4GQ4xA", 0xF4, |
183 | NAND_MEMORG(1, 2048, 64, 64, 4096, 1, 1, 1), | 183 | NAND_MEMORG(1, 2048, 64, 64, 4096, 40, 1, 1, 1), |
184 | NAND_ECCREQ(8, 512), | 184 | NAND_ECCREQ(8, 512), |
185 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, | 185 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
186 | &write_cache_variants, | 186 | &write_cache_variants, |
@@ -189,7 +189,7 @@ static const struct spinand_info gigadevice_spinand_table[] = { | |||
189 | SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, | 189 | SPINAND_ECCINFO(&gd5fxgq4xa_ooblayout, |
190 | gd5fxgq4xa_ecc_get_status)), | 190 | gd5fxgq4xa_ecc_get_status)), |
191 | SPINAND_INFO("GD5F1GQ4UExxG", 0xd1, | 191 | SPINAND_INFO("GD5F1GQ4UExxG", 0xd1, |
192 | NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), | 192 | NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), |
193 | NAND_ECCREQ(8, 512), | 193 | NAND_ECCREQ(8, 512), |
194 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, | 194 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
195 | &write_cache_variants, | 195 | &write_cache_variants, |
diff --git a/drivers/mtd/nand/spi/macronix.c b/drivers/mtd/nand/spi/macronix.c index d16b57081c95..6502727049a8 100644 --- a/drivers/mtd/nand/spi/macronix.c +++ b/drivers/mtd/nand/spi/macronix.c | |||
@@ -100,7 +100,7 @@ static int mx35lf1ge4ab_ecc_get_status(struct spinand_device *spinand, | |||
100 | 100 | ||
101 | static const struct spinand_info macronix_spinand_table[] = { | 101 | static const struct spinand_info macronix_spinand_table[] = { |
102 | SPINAND_INFO("MX35LF1GE4AB", 0x12, | 102 | SPINAND_INFO("MX35LF1GE4AB", 0x12, |
103 | NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1), | 103 | NAND_MEMORG(1, 2048, 64, 64, 1024, 40, 1, 1, 1), |
104 | NAND_ECCREQ(4, 512), | 104 | NAND_ECCREQ(4, 512), |
105 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, | 105 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
106 | &write_cache_variants, | 106 | &write_cache_variants, |
@@ -109,7 +109,7 @@ static const struct spinand_info macronix_spinand_table[] = { | |||
109 | SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, | 109 | SPINAND_ECCINFO(&mx35lfxge4ab_ooblayout, |
110 | mx35lf1ge4ab_ecc_get_status)), | 110 | mx35lf1ge4ab_ecc_get_status)), |
111 | SPINAND_INFO("MX35LF2GE4AB", 0x22, | 111 | SPINAND_INFO("MX35LF2GE4AB", 0x22, |
112 | NAND_MEMORG(1, 2048, 64, 64, 2048, 2, 1, 1), | 112 | NAND_MEMORG(1, 2048, 64, 64, 2048, 20, 2, 1, 1), |
113 | NAND_ECCREQ(4, 512), | 113 | NAND_ECCREQ(4, 512), |
114 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, | 114 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
115 | &write_cache_variants, | 115 | &write_cache_variants, |
diff --git a/drivers/mtd/nand/spi/micron.c b/drivers/mtd/nand/spi/micron.c index 9c4381d6847b..7d7b1f7fcf71 100644 --- a/drivers/mtd/nand/spi/micron.c +++ b/drivers/mtd/nand/spi/micron.c | |||
@@ -92,7 +92,7 @@ static int mt29f2g01abagd_ecc_get_status(struct spinand_device *spinand, | |||
92 | 92 | ||
93 | static const struct spinand_info micron_spinand_table[] = { | 93 | static const struct spinand_info micron_spinand_table[] = { |
94 | SPINAND_INFO("MT29F2G01ABAGD", 0x24, | 94 | SPINAND_INFO("MT29F2G01ABAGD", 0x24, |
95 | NAND_MEMORG(1, 2048, 128, 64, 2048, 2, 1, 1), | 95 | NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 2, 1, 1), |
96 | NAND_ECCREQ(8, 512), | 96 | NAND_ECCREQ(8, 512), |
97 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, | 97 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
98 | &write_cache_variants, | 98 | &write_cache_variants, |
diff --git a/drivers/mtd/nand/spi/toshiba.c b/drivers/mtd/nand/spi/toshiba.c index db8021da45b5..1cb3760ff779 100644 --- a/drivers/mtd/nand/spi/toshiba.c +++ b/drivers/mtd/nand/spi/toshiba.c | |||
@@ -96,7 +96,7 @@ static int tc58cxgxsx_ecc_get_status(struct spinand_device *spinand, | |||
96 | static const struct spinand_info toshiba_spinand_table[] = { | 96 | static const struct spinand_info toshiba_spinand_table[] = { |
97 | /* 3.3V 1Gb */ | 97 | /* 3.3V 1Gb */ |
98 | SPINAND_INFO("TC58CVG0S3", 0xC2, | 98 | SPINAND_INFO("TC58CVG0S3", 0xC2, |
99 | NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), | 99 | NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), |
100 | NAND_ECCREQ(8, 512), | 100 | NAND_ECCREQ(8, 512), |
101 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, | 101 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
102 | &write_cache_variants, | 102 | &write_cache_variants, |
@@ -106,7 +106,7 @@ static const struct spinand_info toshiba_spinand_table[] = { | |||
106 | tc58cxgxsx_ecc_get_status)), | 106 | tc58cxgxsx_ecc_get_status)), |
107 | /* 3.3V 2Gb */ | 107 | /* 3.3V 2Gb */ |
108 | SPINAND_INFO("TC58CVG1S3", 0xCB, | 108 | SPINAND_INFO("TC58CVG1S3", 0xCB, |
109 | NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1), | 109 | NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), |
110 | NAND_ECCREQ(8, 512), | 110 | NAND_ECCREQ(8, 512), |
111 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, | 111 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
112 | &write_cache_variants, | 112 | &write_cache_variants, |
@@ -116,7 +116,7 @@ static const struct spinand_info toshiba_spinand_table[] = { | |||
116 | tc58cxgxsx_ecc_get_status)), | 116 | tc58cxgxsx_ecc_get_status)), |
117 | /* 3.3V 4Gb */ | 117 | /* 3.3V 4Gb */ |
118 | SPINAND_INFO("TC58CVG2S0", 0xCD, | 118 | SPINAND_INFO("TC58CVG2S0", 0xCD, |
119 | NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1), | 119 | NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), |
120 | NAND_ECCREQ(8, 512), | 120 | NAND_ECCREQ(8, 512), |
121 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, | 121 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
122 | &write_cache_variants, | 122 | &write_cache_variants, |
@@ -126,7 +126,7 @@ static const struct spinand_info toshiba_spinand_table[] = { | |||
126 | tc58cxgxsx_ecc_get_status)), | 126 | tc58cxgxsx_ecc_get_status)), |
127 | /* 1.8V 1Gb */ | 127 | /* 1.8V 1Gb */ |
128 | SPINAND_INFO("TC58CYG0S3", 0xB2, | 128 | SPINAND_INFO("TC58CYG0S3", 0xB2, |
129 | NAND_MEMORG(1, 2048, 128, 64, 1024, 1, 1, 1), | 129 | NAND_MEMORG(1, 2048, 128, 64, 1024, 20, 1, 1, 1), |
130 | NAND_ECCREQ(8, 512), | 130 | NAND_ECCREQ(8, 512), |
131 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, | 131 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
132 | &write_cache_variants, | 132 | &write_cache_variants, |
@@ -136,7 +136,7 @@ static const struct spinand_info toshiba_spinand_table[] = { | |||
136 | tc58cxgxsx_ecc_get_status)), | 136 | tc58cxgxsx_ecc_get_status)), |
137 | /* 1.8V 2Gb */ | 137 | /* 1.8V 2Gb */ |
138 | SPINAND_INFO("TC58CYG1S3", 0xBB, | 138 | SPINAND_INFO("TC58CYG1S3", 0xBB, |
139 | NAND_MEMORG(1, 2048, 128, 64, 2048, 1, 1, 1), | 139 | NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1), |
140 | NAND_ECCREQ(8, 512), | 140 | NAND_ECCREQ(8, 512), |
141 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, | 141 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
142 | &write_cache_variants, | 142 | &write_cache_variants, |
@@ -146,7 +146,7 @@ static const struct spinand_info toshiba_spinand_table[] = { | |||
146 | tc58cxgxsx_ecc_get_status)), | 146 | tc58cxgxsx_ecc_get_status)), |
147 | /* 1.8V 4Gb */ | 147 | /* 1.8V 4Gb */ |
148 | SPINAND_INFO("TC58CYG2S0", 0xBD, | 148 | SPINAND_INFO("TC58CYG2S0", 0xBD, |
149 | NAND_MEMORG(1, 4096, 256, 64, 2048, 1, 1, 1), | 149 | NAND_MEMORG(1, 4096, 256, 64, 2048, 40, 1, 1, 1), |
150 | NAND_ECCREQ(8, 512), | 150 | NAND_ECCREQ(8, 512), |
151 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, | 151 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
152 | &write_cache_variants, | 152 | &write_cache_variants, |
diff --git a/drivers/mtd/nand/spi/winbond.c b/drivers/mtd/nand/spi/winbond.c index 5d944580b898..a6c17e0cace8 100644 --- a/drivers/mtd/nand/spi/winbond.c +++ b/drivers/mtd/nand/spi/winbond.c | |||
@@ -76,7 +76,7 @@ static int w25m02gv_select_target(struct spinand_device *spinand, | |||
76 | 76 | ||
77 | static const struct spinand_info winbond_spinand_table[] = { | 77 | static const struct spinand_info winbond_spinand_table[] = { |
78 | SPINAND_INFO("W25M02GV", 0xAB, | 78 | SPINAND_INFO("W25M02GV", 0xAB, |
79 | NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 2), | 79 | NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 2), |
80 | NAND_ECCREQ(1, 512), | 80 | NAND_ECCREQ(1, 512), |
81 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, | 81 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
82 | &write_cache_variants, | 82 | &write_cache_variants, |
@@ -85,7 +85,7 @@ static const struct spinand_info winbond_spinand_table[] = { | |||
85 | SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL), | 85 | SPINAND_ECCINFO(&w25m02gv_ooblayout, NULL), |
86 | SPINAND_SELECT_TARGET(w25m02gv_select_target)), | 86 | SPINAND_SELECT_TARGET(w25m02gv_select_target)), |
87 | SPINAND_INFO("W25N01GV", 0xAA, | 87 | SPINAND_INFO("W25N01GV", 0xAA, |
88 | NAND_MEMORG(1, 2048, 64, 64, 1024, 1, 1, 1), | 88 | NAND_MEMORG(1, 2048, 64, 64, 1024, 20, 1, 1, 1), |
89 | NAND_ECCREQ(1, 512), | 89 | NAND_ECCREQ(1, 512), |
90 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, | 90 | SPINAND_INFO_OP_VARIANTS(&read_cache_variants, |
91 | &write_cache_variants, | 91 | &write_cache_variants, |
diff --git a/drivers/mtd/parsers/Kconfig b/drivers/mtd/parsers/Kconfig index fccf1950e92d..bc201327dda0 100644 --- a/drivers/mtd/parsers/Kconfig +++ b/drivers/mtd/parsers/Kconfig | |||
@@ -1,3 +1,30 @@ | |||
1 | config MTD_PARSER_IMAGETAG | ||
2 | tristate "Parser for BCM963XX Image Tag format partitions" | ||
3 | depends on BCM63XX || BMIPS_GENERIC || COMPILE_TEST | ||
4 | select CRC32 | ||
5 | help | ||
6 | Image Tag is the firmware header used by broadcom on their xDSL line | ||
7 | of devices. It is used to describe the offsets and lengths of kernel | ||
8 | and rootfs partitions. | ||
9 | This driver adds support for parsing a partition with an Image Tag | ||
10 | header and creates up to two partitions, kernel and rootfs. | ||
11 | |||
12 | config MTD_AFS_PARTS | ||
13 | tristate "ARM Firmware Suite partition parsing" | ||
14 | depends on (ARM || ARM64) | ||
15 | help | ||
16 | The ARM Firmware Suite allows the user to divide flash devices into | ||
17 | multiple 'images'. Each such image has a header containing its name | ||
18 | and offset/size etc. | ||
19 | |||
20 | If you need code which can detect and parse these tables, and | ||
21 | register MTD 'partitions' corresponding to each image detected, | ||
22 | enable this option. | ||
23 | |||
24 | You will still need the parsing functions to be called by the driver | ||
25 | for your particular device. It won't happen automatically. The | ||
26 | 'physmap' map driver (CONFIG_MTD_PHYSMAP) does this, for example. | ||
27 | |||
1 | config MTD_PARSER_TRX | 28 | config MTD_PARSER_TRX |
2 | tristate "Parser for TRX format partitions" | 29 | tristate "Parser for TRX format partitions" |
3 | depends on MTD && (BCM47XX || ARCH_BCM_5301X || COMPILE_TEST) | 30 | depends on MTD && (BCM47XX || ARCH_BCM_5301X || COMPILE_TEST) |
diff --git a/drivers/mtd/parsers/Makefile b/drivers/mtd/parsers/Makefile index d8418bf6804a..cddc8f35a856 100644 --- a/drivers/mtd/parsers/Makefile +++ b/drivers/mtd/parsers/Makefile | |||
@@ -1,3 +1,5 @@ | |||
1 | obj-$(CONFIG_MTD_PARSER_IMAGETAG) += parser_imagetag.o | ||
2 | obj-$(CONFIG_MTD_AFS_PARTS) += afs.o | ||
1 | obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o | 3 | obj-$(CONFIG_MTD_PARSER_TRX) += parser_trx.o |
2 | obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o | 4 | obj-$(CONFIG_MTD_SHARPSL_PARTS) += sharpslpart.o |
3 | obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o | 5 | obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o |
diff --git a/drivers/mtd/parsers/afs.c b/drivers/mtd/parsers/afs.c new file mode 100644 index 000000000000..0c730024f806 --- /dev/null +++ b/drivers/mtd/parsers/afs.c | |||
@@ -0,0 +1,410 @@ | |||
1 | /*====================================================================== | ||
2 | |||
3 | drivers/mtd/afs.c: ARM Flash Layout/Partitioning | ||
4 | |||
5 | Copyright © 2000 ARM Limited | ||
6 | Copyright (C) 2019 Linus Walleij | ||
7 | |||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation; either version 2 of the License, or | ||
11 | (at your option) any later version. | ||
12 | |||
13 | This program is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | GNU General Public License for more details. | ||
17 | |||
18 | You should have received a copy of the GNU General Public License | ||
19 | along with this program; if not, write to the Free Software | ||
20 | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | |||
22 | This is access code for flashes using ARM's flash partitioning | ||
23 | standards. | ||
24 | |||
25 | ======================================================================*/ | ||
26 | |||
27 | #include <linux/module.h> | ||
28 | #include <linux/types.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/slab.h> | ||
31 | #include <linux/string.h> | ||
32 | #include <linux/init.h> | ||
33 | |||
34 | #include <linux/mtd/mtd.h> | ||
35 | #include <linux/mtd/map.h> | ||
36 | #include <linux/mtd/partitions.h> | ||
37 | |||
38 | #define AFSV1_FOOTER_MAGIC 0xA0FFFF9F | ||
39 | #define AFSV2_FOOTER_MAGIC1 0x464C5348 /* "FLSH" */ | ||
40 | #define AFSV2_FOOTER_MAGIC2 0x464F4F54 /* "FOOT" */ | ||
41 | |||
42 | struct footer_v1 { | ||
43 | u32 image_info_base; /* Address of first word of ImageFooter */ | ||
44 | u32 image_start; /* Start of area reserved by this footer */ | ||
45 | u32 signature; /* 'Magic' number proves it's a footer */ | ||
46 | u32 type; /* Area type: ARM Image, SIB, customer */ | ||
47 | u32 checksum; /* Just this structure */ | ||
48 | }; | ||
49 | |||
50 | struct image_info_v1 { | ||
51 | u32 bootFlags; /* Boot flags, compression etc. */ | ||
52 | u32 imageNumber; /* Unique number, selects for boot etc. */ | ||
53 | u32 loadAddress; /* Address program should be loaded to */ | ||
54 | u32 length; /* Actual size of image */ | ||
55 | u32 address; /* Image is executed from here */ | ||
56 | char name[16]; /* Null terminated */ | ||
57 | u32 headerBase; /* Flash Address of any stripped header */ | ||
58 | u32 header_length; /* Length of header in memory */ | ||
59 | u32 headerType; /* AIF, RLF, s-record etc. */ | ||
60 | u32 checksum; /* Image checksum (inc. this struct) */ | ||
61 | }; | ||
62 | |||
63 | static u32 word_sum(void *words, int num) | ||
64 | { | ||
65 | u32 *p = words; | ||
66 | u32 sum = 0; | ||
67 | |||
68 | while (num--) | ||
69 | sum += *p++; | ||
70 | |||
71 | return sum; | ||
72 | } | ||
73 | |||
74 | static u32 word_sum_v2(u32 *p, u32 num) | ||
75 | { | ||
76 | u32 sum = 0; | ||
77 | int i; | ||
78 | |||
79 | for (i = 0; i < num; i++) { | ||
80 | u32 val; | ||
81 | |||
82 | val = p[i]; | ||
83 | if (val > ~sum) | ||
84 | sum++; | ||
85 | sum += val; | ||
86 | } | ||
87 | return ~sum; | ||
88 | } | ||
89 | |||
90 | static bool afs_is_v1(struct mtd_info *mtd, u_int off) | ||
91 | { | ||
92 | /* The magic is 12 bytes from the end of the erase block */ | ||
93 | u_int ptr = off + mtd->erasesize - 12; | ||
94 | u32 magic; | ||
95 | size_t sz; | ||
96 | int ret; | ||
97 | |||
98 | ret = mtd_read(mtd, ptr, 4, &sz, (u_char *)&magic); | ||
99 | if (ret < 0) { | ||
100 | printk(KERN_ERR "AFS: mtd read failed at 0x%x: %d\n", | ||
101 | ptr, ret); | ||
102 | return false; | ||
103 | } | ||
104 | if (ret >= 0 && sz != 4) | ||
105 | return false; | ||
106 | |||
107 | return (magic == AFSV1_FOOTER_MAGIC); | ||
108 | } | ||
109 | |||
110 | static bool afs_is_v2(struct mtd_info *mtd, u_int off) | ||
111 | { | ||
112 | /* The magic is the 8 last bytes of the erase block */ | ||
113 | u_int ptr = off + mtd->erasesize - 8; | ||
114 | u32 foot[2]; | ||
115 | size_t sz; | ||
116 | int ret; | ||
117 | |||
118 | ret = mtd_read(mtd, ptr, 8, &sz, (u_char *)foot); | ||
119 | if (ret < 0) { | ||
120 | printk(KERN_ERR "AFS: mtd read failed at 0x%x: %d\n", | ||
121 | ptr, ret); | ||
122 | return false; | ||
123 | } | ||
124 | if (ret >= 0 && sz != 8) | ||
125 | return false; | ||
126 | |||
127 | return (foot[0] == AFSV2_FOOTER_MAGIC1 && | ||
128 | foot[1] == AFSV2_FOOTER_MAGIC2); | ||
129 | } | ||
130 | |||
131 | static int afs_parse_v1_partition(struct mtd_info *mtd, | ||
132 | u_int off, struct mtd_partition *part) | ||
133 | { | ||
134 | struct footer_v1 fs; | ||
135 | struct image_info_v1 iis; | ||
136 | u_int mask; | ||
137 | /* | ||
138 | * Static checks cannot see that we bail out if we have an error | ||
139 | * reading the footer. | ||
140 | */ | ||
141 | u_int uninitialized_var(iis_ptr); | ||
142 | u_int uninitialized_var(img_ptr); | ||
143 | u_int ptr; | ||
144 | size_t sz; | ||
145 | int ret; | ||
146 | int i; | ||
147 | |||
148 | /* | ||
149 | * This is the address mask; we use this to mask off out of | ||
150 | * range address bits. | ||
151 | */ | ||
152 | mask = mtd->size - 1; | ||
153 | |||
154 | ptr = off + mtd->erasesize - sizeof(fs); | ||
155 | ret = mtd_read(mtd, ptr, sizeof(fs), &sz, (u_char *)&fs); | ||
156 | if (ret >= 0 && sz != sizeof(fs)) | ||
157 | ret = -EINVAL; | ||
158 | if (ret < 0) { | ||
159 | printk(KERN_ERR "AFS: mtd read failed at 0x%x: %d\n", | ||
160 | ptr, ret); | ||
161 | return ret; | ||
162 | } | ||
163 | /* | ||
164 | * Check the checksum. | ||
165 | */ | ||
166 | if (word_sum(&fs, sizeof(fs) / sizeof(u32)) != 0xffffffff) | ||
167 | return -EINVAL; | ||
168 | |||
169 | /* | ||
170 | * Hide the SIB (System Information Block) | ||
171 | */ | ||
172 | if (fs.type == 2) | ||
173 | return 0; | ||
174 | |||
175 | iis_ptr = fs.image_info_base & mask; | ||
176 | img_ptr = fs.image_start & mask; | ||
177 | |||
178 | /* | ||
179 | * Check the image info base. This can not | ||
180 | * be located after the footer structure. | ||
181 | */ | ||
182 | if (iis_ptr >= ptr) | ||
183 | return 0; | ||
184 | |||
185 | /* | ||
186 | * Check the start of this image. The image | ||
187 | * data can not be located after this block. | ||
188 | */ | ||
189 | if (img_ptr > off) | ||
190 | return 0; | ||
191 | |||
192 | /* Read the image info block */ | ||
193 | memset(&iis, 0, sizeof(iis)); | ||
194 | ret = mtd_read(mtd, iis_ptr, sizeof(iis), &sz, (u_char *)&iis); | ||
195 | if (ret < 0) { | ||
196 | printk(KERN_ERR "AFS: mtd read failed at 0x%x: %d\n", | ||
197 | iis_ptr, ret); | ||
198 | return -EINVAL; | ||
199 | } | ||
200 | |||
201 | if (sz != sizeof(iis)) | ||
202 | return -EINVAL; | ||
203 | |||
204 | /* | ||
205 | * Validate the name - it must be NUL terminated. | ||
206 | */ | ||
207 | for (i = 0; i < sizeof(iis.name); i++) | ||
208 | if (iis.name[i] == '\0') | ||
209 | break; | ||
210 | if (i > sizeof(iis.name)) | ||
211 | return -EINVAL; | ||
212 | |||
213 | part->name = kstrdup(iis.name, GFP_KERNEL); | ||
214 | if (!part->name) | ||
215 | return -ENOMEM; | ||
216 | |||
217 | part->size = (iis.length + mtd->erasesize - 1) & ~(mtd->erasesize - 1); | ||
218 | part->offset = img_ptr; | ||
219 | part->mask_flags = 0; | ||
220 | |||
221 | printk(" mtd: at 0x%08x, %5lluKiB, %8u, %s\n", | ||
222 | img_ptr, part->size / 1024, | ||
223 | iis.imageNumber, part->name); | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | static int afs_parse_v2_partition(struct mtd_info *mtd, | ||
229 | u_int off, struct mtd_partition *part) | ||
230 | { | ||
231 | u_int ptr; | ||
232 | u32 footer[12]; | ||
233 | u32 imginfo[36]; | ||
234 | char *name; | ||
235 | u32 version; | ||
236 | u32 entrypoint; | ||
237 | u32 attributes; | ||
238 | u32 region_count; | ||
239 | u32 block_start; | ||
240 | u32 block_end; | ||
241 | u32 crc; | ||
242 | size_t sz; | ||
243 | int ret; | ||
244 | int i; | ||
245 | int pad = 0; | ||
246 | |||
247 | pr_debug("Parsing v2 partition @%08x-%08x\n", | ||
248 | off, off + mtd->erasesize); | ||
249 | |||
250 | /* First read the footer */ | ||
251 | ptr = off + mtd->erasesize - sizeof(footer); | ||
252 | ret = mtd_read(mtd, ptr, sizeof(footer), &sz, (u_char *)footer); | ||
253 | if ((ret < 0) || (ret >= 0 && sz != sizeof(footer))) { | ||
254 | pr_err("AFS: mtd read failed at 0x%x: %d\n", | ||
255 | ptr, ret); | ||
256 | return -EIO; | ||
257 | } | ||
258 | name = (char *) &footer[0]; | ||
259 | version = footer[9]; | ||
260 | ptr = off + mtd->erasesize - sizeof(footer) - footer[8]; | ||
261 | |||
262 | pr_debug("found image \"%s\", version %08x, info @%08x\n", | ||
263 | name, version, ptr); | ||
264 | |||
265 | /* Then read the image information */ | ||
266 | ret = mtd_read(mtd, ptr, sizeof(imginfo), &sz, (u_char *)imginfo); | ||
267 | if ((ret < 0) || (ret >= 0 && sz != sizeof(imginfo))) { | ||
268 | pr_err("AFS: mtd read failed at 0x%x: %d\n", | ||
269 | ptr, ret); | ||
270 | return -EIO; | ||
271 | } | ||
272 | |||
273 | /* 32bit platforms have 4 bytes padding */ | ||
274 | crc = word_sum_v2(&imginfo[1], 34); | ||
275 | if (!crc) { | ||
276 | pr_debug("Padding 1 word (4 bytes)\n"); | ||
277 | pad = 1; | ||
278 | } else { | ||
279 | /* 64bit platforms have 8 bytes padding */ | ||
280 | crc = word_sum_v2(&imginfo[2], 34); | ||
281 | if (!crc) { | ||
282 | pr_debug("Padding 2 words (8 bytes)\n"); | ||
283 | pad = 2; | ||
284 | } | ||
285 | } | ||
286 | if (crc) { | ||
287 | pr_err("AFS: bad checksum on v2 image info: %08x\n", crc); | ||
288 | return -EINVAL; | ||
289 | } | ||
290 | entrypoint = imginfo[pad]; | ||
291 | attributes = imginfo[pad+1]; | ||
292 | region_count = imginfo[pad+2]; | ||
293 | block_start = imginfo[20]; | ||
294 | block_end = imginfo[21]; | ||
295 | |||
296 | pr_debug("image entry=%08x, attr=%08x, regions=%08x, " | ||
297 | "bs=%08x, be=%08x\n", | ||
298 | entrypoint, attributes, region_count, | ||
299 | block_start, block_end); | ||
300 | |||
301 | for (i = 0; i < region_count; i++) { | ||
302 | u32 region_load_addr = imginfo[pad + 3 + i*4]; | ||
303 | u32 region_size = imginfo[pad + 4 + i*4]; | ||
304 | u32 region_offset = imginfo[pad + 5 + i*4]; | ||
305 | u32 region_start; | ||
306 | u32 region_end; | ||
307 | |||
308 | pr_debug(" region %d: address: %08x, size: %08x, " | ||
309 | "offset: %08x\n", | ||
310 | i, | ||
311 | region_load_addr, | ||
312 | region_size, | ||
313 | region_offset); | ||
314 | |||
315 | region_start = off + region_offset; | ||
316 | region_end = region_start + region_size; | ||
317 | /* Align partition to end of erase block */ | ||
318 | region_end += (mtd->erasesize - 1); | ||
319 | region_end &= ~(mtd->erasesize -1); | ||
320 | pr_debug(" partition start = %08x, partition end = %08x\n", | ||
321 | region_start, region_end); | ||
322 | |||
323 | /* Create one partition per region */ | ||
324 | part->name = kstrdup(name, GFP_KERNEL); | ||
325 | if (!part->name) | ||
326 | return -ENOMEM; | ||
327 | part->offset = region_start; | ||
328 | part->size = region_end - region_start; | ||
329 | part->mask_flags = 0; | ||
330 | } | ||
331 | |||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | static int parse_afs_partitions(struct mtd_info *mtd, | ||
336 | const struct mtd_partition **pparts, | ||
337 | struct mtd_part_parser_data *data) | ||
338 | { | ||
339 | struct mtd_partition *parts; | ||
340 | u_int off, sz; | ||
341 | int ret = 0; | ||
342 | int i; | ||
343 | |||
344 | /* Count the partitions by looping over all erase blocks */ | ||
345 | for (i = off = sz = 0; off < mtd->size; off += mtd->erasesize) { | ||
346 | if (afs_is_v1(mtd, off)) { | ||
347 | sz += sizeof(struct mtd_partition); | ||
348 | i += 1; | ||
349 | } | ||
350 | if (afs_is_v2(mtd, off)) { | ||
351 | sz += sizeof(struct mtd_partition); | ||
352 | i += 1; | ||
353 | } | ||
354 | } | ||
355 | |||
356 | if (!i) | ||
357 | return 0; | ||
358 | |||
359 | parts = kzalloc(sz, GFP_KERNEL); | ||
360 | if (!parts) | ||
361 | return -ENOMEM; | ||
362 | |||
363 | /* | ||
364 | * Identify the partitions | ||
365 | */ | ||
366 | for (i = off = 0; off < mtd->size; off += mtd->erasesize) { | ||
367 | if (afs_is_v1(mtd, off)) { | ||
368 | ret = afs_parse_v1_partition(mtd, off, &parts[i]); | ||
369 | if (ret) | ||
370 | goto out_free_parts; | ||
371 | i++; | ||
372 | } | ||
373 | if (afs_is_v2(mtd, off)) { | ||
374 | ret = afs_parse_v2_partition(mtd, off, &parts[i]); | ||
375 | if (ret) | ||
376 | goto out_free_parts; | ||
377 | i++; | ||
378 | } | ||
379 | } | ||
380 | |||
381 | *pparts = parts; | ||
382 | return i; | ||
383 | |||
384 | out_free_parts: | ||
385 | while (i >= 0) { | ||
386 | if (parts[i].name) | ||
387 | kfree(parts[i].name); | ||
388 | i--; | ||
389 | } | ||
390 | kfree(parts); | ||
391 | *pparts = NULL; | ||
392 | return ret; | ||
393 | } | ||
394 | |||
395 | static const struct of_device_id mtd_parser_afs_of_match_table[] = { | ||
396 | { .compatible = "arm,arm-firmware-suite" }, | ||
397 | {}, | ||
398 | }; | ||
399 | MODULE_DEVICE_TABLE(of, mtd_parser_afs_of_match_table); | ||
400 | |||
401 | static struct mtd_part_parser afs_parser = { | ||
402 | .parse_fn = parse_afs_partitions, | ||
403 | .name = "afs", | ||
404 | .of_match_table = mtd_parser_afs_of_match_table, | ||
405 | }; | ||
406 | module_mtd_part_parser(afs_parser); | ||
407 | |||
408 | MODULE_AUTHOR("ARM Ltd"); | ||
409 | MODULE_DESCRIPTION("ARM Firmware Suite partition parser"); | ||
410 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/mtd/parsers/parser_imagetag.c b/drivers/mtd/parsers/parser_imagetag.c new file mode 100644 index 000000000000..9537c183a3be --- /dev/null +++ b/drivers/mtd/parsers/parser_imagetag.c | |||
@@ -0,0 +1,222 @@ | |||
1 | /* | ||
2 | * BCM63XX CFE image tag parser | ||
3 | * | ||
4 | * Copyright © 2006-2008 Florian Fainelli <florian@openwrt.org> | ||
5 | * Mike Albon <malbon@openwrt.org> | ||
6 | * Copyright © 2009-2010 Daniel Dickinson <openwrt@cshore.neomailbox.net> | ||
7 | * Copyright © 2011-2013 Jonas Gorski <jonas.gorski@gmail.com> | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
17 | |||
18 | #include <linux/bcm963xx_tag.h> | ||
19 | #include <linux/crc32.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/sizes.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/vmalloc.h> | ||
25 | #include <linux/mtd/mtd.h> | ||
26 | #include <linux/mtd/partitions.h> | ||
27 | #include <linux/of.h> | ||
28 | |||
29 | /* Ensure strings read from flash structs are null terminated */ | ||
30 | #define STR_NULL_TERMINATE(x) \ | ||
31 | do { char *_str = (x); _str[sizeof(x) - 1] = 0; } while (0) | ||
32 | |||
33 | static int bcm963xx_read_imagetag(struct mtd_info *master, const char *name, | ||
34 | loff_t tag_offset, struct bcm_tag *buf) | ||
35 | { | ||
36 | int ret; | ||
37 | size_t retlen; | ||
38 | u32 computed_crc; | ||
39 | |||
40 | ret = mtd_read(master, tag_offset, sizeof(*buf), &retlen, (void *)buf); | ||
41 | if (ret) | ||
42 | return ret; | ||
43 | |||
44 | if (retlen != sizeof(*buf)) | ||
45 | return -EIO; | ||
46 | |||
47 | computed_crc = crc32_le(IMAGETAG_CRC_START, (u8 *)buf, | ||
48 | offsetof(struct bcm_tag, header_crc)); | ||
49 | if (computed_crc == buf->header_crc) { | ||
50 | STR_NULL_TERMINATE(buf->board_id); | ||
51 | STR_NULL_TERMINATE(buf->tag_version); | ||
52 | |||
53 | pr_info("%s: CFE image tag found at 0x%llx with version %s, board type %s\n", | ||
54 | name, tag_offset, buf->tag_version, buf->board_id); | ||
55 | |||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | pr_warn("%s: CFE image tag at 0x%llx CRC invalid (expected %08x, actual %08x)\n", | ||
60 | name, tag_offset, buf->header_crc, computed_crc); | ||
61 | return -EINVAL; | ||
62 | } | ||
63 | |||
64 | static int bcm963xx_parse_imagetag_partitions(struct mtd_info *master, | ||
65 | const struct mtd_partition **pparts, | ||
66 | struct mtd_part_parser_data *data) | ||
67 | { | ||
68 | /* CFE, NVRAM and global Linux are always present */ | ||
69 | int nrparts = 0, curpart = 0; | ||
70 | struct bcm_tag *buf = NULL; | ||
71 | struct mtd_partition *parts; | ||
72 | int ret; | ||
73 | unsigned int rootfsaddr, kerneladdr, spareaddr, offset; | ||
74 | unsigned int rootfslen, kernellen, sparelen, totallen; | ||
75 | int i; | ||
76 | bool rootfs_first = false; | ||
77 | |||
78 | buf = vmalloc(sizeof(struct bcm_tag)); | ||
79 | if (!buf) | ||
80 | return -ENOMEM; | ||
81 | |||
82 | /* Get the tag */ | ||
83 | ret = bcm963xx_read_imagetag(master, "rootfs", 0, buf); | ||
84 | if (!ret) { | ||
85 | STR_NULL_TERMINATE(buf->flash_image_start); | ||
86 | if (kstrtouint(buf->flash_image_start, 10, &rootfsaddr) || | ||
87 | rootfsaddr < BCM963XX_EXTENDED_SIZE) { | ||
88 | pr_err("invalid rootfs address: %*ph\n", | ||
89 | (int)sizeof(buf->flash_image_start), | ||
90 | buf->flash_image_start); | ||
91 | goto out; | ||
92 | } | ||
93 | |||
94 | STR_NULL_TERMINATE(buf->kernel_address); | ||
95 | if (kstrtouint(buf->kernel_address, 10, &kerneladdr) || | ||
96 | kerneladdr < BCM963XX_EXTENDED_SIZE) { | ||
97 | pr_err("invalid kernel address: %*ph\n", | ||
98 | (int)sizeof(buf->kernel_address), | ||
99 | buf->kernel_address); | ||
100 | goto out; | ||
101 | } | ||
102 | |||
103 | STR_NULL_TERMINATE(buf->kernel_length); | ||
104 | if (kstrtouint(buf->kernel_length, 10, &kernellen)) { | ||
105 | pr_err("invalid kernel length: %*ph\n", | ||
106 | (int)sizeof(buf->kernel_length), | ||
107 | buf->kernel_length); | ||
108 | goto out; | ||
109 | } | ||
110 | |||
111 | STR_NULL_TERMINATE(buf->total_length); | ||
112 | if (kstrtouint(buf->total_length, 10, &totallen)) { | ||
113 | pr_err("invalid total length: %*ph\n", | ||
114 | (int)sizeof(buf->total_length), | ||
115 | buf->total_length); | ||
116 | goto out; | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | * Addresses are flash absolute, so convert to partition | ||
121 | * relative addresses. Assume either kernel or rootfs will | ||
122 | * directly follow the image tag. | ||
123 | */ | ||
124 | if (rootfsaddr < kerneladdr) | ||
125 | offset = rootfsaddr - sizeof(struct bcm_tag); | ||
126 | else | ||
127 | offset = kerneladdr - sizeof(struct bcm_tag); | ||
128 | |||
129 | kerneladdr = kerneladdr - offset; | ||
130 | rootfsaddr = rootfsaddr - offset; | ||
131 | spareaddr = roundup(totallen, master->erasesize); | ||
132 | |||
133 | if (rootfsaddr < kerneladdr) { | ||
134 | /* default Broadcom layout */ | ||
135 | rootfslen = kerneladdr - rootfsaddr; | ||
136 | rootfs_first = true; | ||
137 | } else { | ||
138 | /* OpenWrt layout */ | ||
139 | rootfsaddr = kerneladdr + kernellen; | ||
140 | rootfslen = spareaddr - rootfsaddr; | ||
141 | } | ||
142 | } else { | ||
143 | goto out; | ||
144 | } | ||
145 | sparelen = master->size - spareaddr; | ||
146 | |||
147 | /* Determine number of partitions */ | ||
148 | if (rootfslen > 0) | ||
149 | nrparts++; | ||
150 | |||
151 | if (kernellen > 0) | ||
152 | nrparts++; | ||
153 | |||
154 | parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL); | ||
155 | if (!parts) { | ||
156 | ret = -ENOMEM; | ||
157 | goto out; | ||
158 | } | ||
159 | |||
160 | /* Start building partition list */ | ||
161 | if (kernellen > 0) { | ||
162 | int kernelpart = curpart; | ||
163 | |||
164 | if (rootfslen > 0 && rootfs_first) | ||
165 | kernelpart++; | ||
166 | parts[kernelpart].name = "kernel"; | ||
167 | parts[kernelpart].offset = kerneladdr; | ||
168 | parts[kernelpart].size = kernellen; | ||
169 | curpart++; | ||
170 | } | ||
171 | |||
172 | if (rootfslen > 0) { | ||
173 | int rootfspart = curpart; | ||
174 | |||
175 | if (kernellen > 0 && rootfs_first) | ||
176 | rootfspart--; | ||
177 | parts[rootfspart].name = "rootfs"; | ||
178 | parts[rootfspart].offset = rootfsaddr; | ||
179 | parts[rootfspart].size = rootfslen; | ||
180 | if (sparelen > 0 && !rootfs_first) | ||
181 | parts[rootfspart].size += sparelen; | ||
182 | curpart++; | ||
183 | } | ||
184 | |||
185 | for (i = 0; i < nrparts; i++) | ||
186 | pr_info("Partition %d is %s offset %llx and length %llx\n", i, | ||
187 | parts[i].name, parts[i].offset, parts[i].size); | ||
188 | |||
189 | pr_info("Spare partition is offset %x and length %x\n", spareaddr, | ||
190 | sparelen); | ||
191 | |||
192 | *pparts = parts; | ||
193 | ret = 0; | ||
194 | |||
195 | out: | ||
196 | vfree(buf); | ||
197 | |||
198 | if (ret) | ||
199 | return ret; | ||
200 | |||
201 | return nrparts; | ||
202 | } | ||
203 | |||
204 | static const struct of_device_id parse_bcm963xx_imagetag_match_table[] = { | ||
205 | { .compatible = "brcm,bcm963xx-imagetag" }, | ||
206 | {}, | ||
207 | }; | ||
208 | MODULE_DEVICE_TABLE(of, parse_bcm963xx_imagetag_match_table); | ||
209 | |||
210 | static struct mtd_part_parser bcm963xx_imagetag_parser = { | ||
211 | .parse_fn = bcm963xx_parse_imagetag_partitions, | ||
212 | .name = "bcm963xx-imagetag", | ||
213 | .of_match_table = parse_bcm963xx_imagetag_match_table, | ||
214 | }; | ||
215 | module_mtd_part_parser(bcm963xx_imagetag_parser); | ||
216 | |||
217 | MODULE_LICENSE("GPL"); | ||
218 | MODULE_AUTHOR("Daniel Dickinson <openwrt@cshore.neomailbox.net>"); | ||
219 | MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>"); | ||
220 | MODULE_AUTHOR("Mike Albon <malbon@openwrt.org>"); | ||
221 | MODULE_AUTHOR("Jonas Gorski <jonas.gorski@gmail.com>"); | ||
222 | MODULE_DESCRIPTION("MTD parser for BCM963XX CFE Image Tag partitions"); | ||
diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c index 89227b1d036a..e0955a98a0f4 100644 --- a/drivers/mtd/sm_ftl.c +++ b/drivers/mtd/sm_ftl.c | |||
@@ -222,17 +222,17 @@ static int sm_correct_sector(uint8_t *buffer, struct sm_oob *oob) | |||
222 | uint8_t ecc[3]; | 222 | uint8_t ecc[3]; |
223 | 223 | ||
224 | __nand_calculate_ecc(buffer, SM_SMALL_PAGE, ecc, | 224 | __nand_calculate_ecc(buffer, SM_SMALL_PAGE, ecc, |
225 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SMC)); | 225 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC)); |
226 | if (__nand_correct_data(buffer, ecc, oob->ecc1, SM_SMALL_PAGE, | 226 | if (__nand_correct_data(buffer, ecc, oob->ecc1, SM_SMALL_PAGE, |
227 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SMC)) < 0) | 227 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC)) < 0) |
228 | return -EIO; | 228 | return -EIO; |
229 | 229 | ||
230 | buffer += SM_SMALL_PAGE; | 230 | buffer += SM_SMALL_PAGE; |
231 | 231 | ||
232 | __nand_calculate_ecc(buffer, SM_SMALL_PAGE, ecc, | 232 | __nand_calculate_ecc(buffer, SM_SMALL_PAGE, ecc, |
233 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SMC)); | 233 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC)); |
234 | if (__nand_correct_data(buffer, ecc, oob->ecc2, SM_SMALL_PAGE, | 234 | if (__nand_correct_data(buffer, ecc, oob->ecc2, SM_SMALL_PAGE, |
235 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SMC)) < 0) | 235 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC)) < 0) |
236 | return -EIO; | 236 | return -EIO; |
237 | return 0; | 237 | return 0; |
238 | } | 238 | } |
@@ -399,11 +399,11 @@ restart: | |||
399 | if (ftl->smallpagenand) { | 399 | if (ftl->smallpagenand) { |
400 | __nand_calculate_ecc(buf + boffset, SM_SMALL_PAGE, | 400 | __nand_calculate_ecc(buf + boffset, SM_SMALL_PAGE, |
401 | oob.ecc1, | 401 | oob.ecc1, |
402 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SMC)); | 402 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC)); |
403 | 403 | ||
404 | __nand_calculate_ecc(buf + boffset + SM_SMALL_PAGE, | 404 | __nand_calculate_ecc(buf + boffset + SM_SMALL_PAGE, |
405 | SM_SMALL_PAGE, oob.ecc2, | 405 | SM_SMALL_PAGE, oob.ecc2, |
406 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SMC)); | 406 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC)); |
407 | } | 407 | } |
408 | if (!sm_write_sector(ftl, zone, block, boffset, | 408 | if (!sm_write_sector(ftl, zone, block, boffset, |
409 | buf + boffset, &oob)) | 409 | buf + boffset, &oob)) |
diff --git a/drivers/mtd/spi-nor/intel-spi-pci.c b/drivers/mtd/spi-nor/intel-spi-pci.c index 872b40922608..bfbfc17ed6aa 100644 --- a/drivers/mtd/spi-nor/intel-spi-pci.c +++ b/drivers/mtd/spi-nor/intel-spi-pci.c | |||
@@ -63,6 +63,7 @@ static void intel_spi_pci_remove(struct pci_dev *pdev) | |||
63 | } | 63 | } |
64 | 64 | ||
65 | static const struct pci_device_id intel_spi_pci_ids[] = { | 65 | static const struct pci_device_id intel_spi_pci_ids[] = { |
66 | { PCI_VDEVICE(INTEL, 0x02a4), (unsigned long)&bxt_info }, | ||
66 | { PCI_VDEVICE(INTEL, 0x18e0), (unsigned long)&bxt_info }, | 67 | { PCI_VDEVICE(INTEL, 0x18e0), (unsigned long)&bxt_info }, |
67 | { PCI_VDEVICE(INTEL, 0x19e0), (unsigned long)&bxt_info }, | 68 | { PCI_VDEVICE(INTEL, 0x19e0), (unsigned long)&bxt_info }, |
68 | { PCI_VDEVICE(INTEL, 0x34a4), (unsigned long)&bxt_info }, | 69 | { PCI_VDEVICE(INTEL, 0x34a4), (unsigned long)&bxt_info }, |
diff --git a/drivers/mtd/spi-nor/intel-spi.c b/drivers/mtd/spi-nor/intel-spi.c index af0a22019516..d60cbf23d9aa 100644 --- a/drivers/mtd/spi-nor/intel-spi.c +++ b/drivers/mtd/spi-nor/intel-spi.c | |||
@@ -632,6 +632,10 @@ static ssize_t intel_spi_read(struct spi_nor *nor, loff_t from, size_t len, | |||
632 | while (len > 0) { | 632 | while (len > 0) { |
633 | block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ); | 633 | block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ); |
634 | 634 | ||
635 | /* Read cannot cross 4K boundary */ | ||
636 | block_size = min_t(loff_t, from + block_size, | ||
637 | round_up(from + 1, SZ_4K)) - from; | ||
638 | |||
635 | writel(from, ispi->base + FADDR); | 639 | writel(from, ispi->base + FADDR); |
636 | 640 | ||
637 | val = readl(ispi->base + HSFSTS_CTL); | 641 | val = readl(ispi->base + HSFSTS_CTL); |
@@ -685,6 +689,10 @@ static ssize_t intel_spi_write(struct spi_nor *nor, loff_t to, size_t len, | |||
685 | while (len > 0) { | 689 | while (len > 0) { |
686 | block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ); | 690 | block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ); |
687 | 691 | ||
692 | /* Write cannot cross 4K boundary */ | ||
693 | block_size = min_t(loff_t, to + block_size, | ||
694 | round_up(to + 1, SZ_4K)) - to; | ||
695 | |||
688 | writel(to, ispi->base + FADDR); | 696 | writel(to, ispi->base + FADDR); |
689 | 697 | ||
690 | val = readl(ispi->base + HSFSTS_CTL); | 698 | val = readl(ispi->base + HSFSTS_CTL); |
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index fae147452aff..73172d7f512b 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c | |||
@@ -744,7 +744,7 @@ spi_nor_find_best_erase_type(const struct spi_nor_erase_map *map, | |||
744 | u8 erase_mask = region->offset & SNOR_ERASE_TYPE_MASK; | 744 | u8 erase_mask = region->offset & SNOR_ERASE_TYPE_MASK; |
745 | 745 | ||
746 | /* | 746 | /* |
747 | * Erase types are ordered by size, with the biggest erase type at | 747 | * Erase types are ordered by size, with the smallest erase type at |
748 | * index 0. | 748 | * index 0. |
749 | */ | 749 | */ |
750 | for (i = SNOR_ERASE_TYPE_MAX - 1; i >= 0; i--) { | 750 | for (i = SNOR_ERASE_TYPE_MAX - 1; i >= 0; i--) { |
@@ -1905,7 +1905,9 @@ static const struct flash_info spi_nor_ids[] = { | |||
1905 | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) }, | 1905 | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) }, |
1906 | { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, USE_CLSR) }, | 1906 | { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, USE_CLSR) }, |
1907 | { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) }, | 1907 | { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) }, |
1908 | { "s25fl512s", INFO6(0x010220, 0x4d0080, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) }, | 1908 | { "s25fl512s", INFO6(0x010220, 0x4d0080, 256 * 1024, 256, |
1909 | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | | ||
1910 | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB | USE_CLSR) }, | ||
1909 | { "s25fs512s", INFO6(0x010220, 0x4d0081, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) }, | 1911 | { "s25fs512s", INFO6(0x010220, 0x4d0081, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | USE_CLSR) }, |
1910 | { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, | 1912 | { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, |
1911 | { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, | 1913 | { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, |
@@ -2071,8 +2073,8 @@ static const struct flash_info *spi_nor_read_id(struct spi_nor *nor) | |||
2071 | return &spi_nor_ids[tmp]; | 2073 | return &spi_nor_ids[tmp]; |
2072 | } | 2074 | } |
2073 | } | 2075 | } |
2074 | dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %02x, %02x\n", | 2076 | dev_err(nor->dev, "unrecognized JEDEC id bytes: %*ph\n", |
2075 | id[0], id[1], id[2]); | 2077 | SPI_NOR_MAX_ID_LEN, id); |
2076 | return ERR_PTR(-ENODEV); | 2078 | return ERR_PTR(-ENODEV); |
2077 | } | 2079 | } |
2078 | 2080 | ||
diff --git a/drivers/mtd/tests/mtd_nandecctest.c b/drivers/mtd/tests/mtd_nandecctest.c index c71523e94580..73b06304c975 100644 --- a/drivers/mtd/tests/mtd_nandecctest.c +++ b/drivers/mtd/tests/mtd_nandecctest.c | |||
@@ -21,7 +21,7 @@ | |||
21 | * or detected. | 21 | * or detected. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #if IS_ENABLED(CONFIG_MTD_NAND) | 24 | #if IS_ENABLED(CONFIG_MTD_RAW_NAND) |
25 | 25 | ||
26 | struct nand_ecc_test { | 26 | struct nand_ecc_test { |
27 | const char *name; | 27 | const char *name; |
@@ -122,9 +122,9 @@ static int no_bit_error_verify(void *error_data, void *error_ecc, | |||
122 | int ret; | 122 | int ret; |
123 | 123 | ||
124 | __nand_calculate_ecc(error_data, size, calc_ecc, | 124 | __nand_calculate_ecc(error_data, size, calc_ecc, |
125 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SMC)); | 125 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC)); |
126 | ret = __nand_correct_data(error_data, error_ecc, calc_ecc, size, | 126 | ret = __nand_correct_data(error_data, error_ecc, calc_ecc, size, |
127 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SMC)); | 127 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC)); |
128 | if (ret == 0 && !memcmp(correct_data, error_data, size)) | 128 | if (ret == 0 && !memcmp(correct_data, error_data, size)) |
129 | return 0; | 129 | return 0; |
130 | 130 | ||
@@ -152,9 +152,9 @@ static int single_bit_error_correct(void *error_data, void *error_ecc, | |||
152 | int ret; | 152 | int ret; |
153 | 153 | ||
154 | __nand_calculate_ecc(error_data, size, calc_ecc, | 154 | __nand_calculate_ecc(error_data, size, calc_ecc, |
155 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SMC)); | 155 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC)); |
156 | ret = __nand_correct_data(error_data, error_ecc, calc_ecc, size, | 156 | ret = __nand_correct_data(error_data, error_ecc, calc_ecc, size, |
157 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SMC)); | 157 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC)); |
158 | if (ret == 1 && !memcmp(correct_data, error_data, size)) | 158 | if (ret == 1 && !memcmp(correct_data, error_data, size)) |
159 | return 0; | 159 | return 0; |
160 | 160 | ||
@@ -189,9 +189,9 @@ static int double_bit_error_detect(void *error_data, void *error_ecc, | |||
189 | int ret; | 189 | int ret; |
190 | 190 | ||
191 | __nand_calculate_ecc(error_data, size, calc_ecc, | 191 | __nand_calculate_ecc(error_data, size, calc_ecc, |
192 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SMC)); | 192 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC)); |
193 | ret = __nand_correct_data(error_data, error_ecc, calc_ecc, size, | 193 | ret = __nand_correct_data(error_data, error_ecc, calc_ecc, size, |
194 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SMC)); | 194 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC)); |
195 | 195 | ||
196 | return (ret == -EBADMSG) ? 0 : -EINVAL; | 196 | return (ret == -EBADMSG) ? 0 : -EINVAL; |
197 | } | 197 | } |
@@ -266,7 +266,7 @@ static int nand_ecc_test_run(const size_t size) | |||
266 | 266 | ||
267 | prandom_bytes(correct_data, size); | 267 | prandom_bytes(correct_data, size); |
268 | __nand_calculate_ecc(correct_data, size, correct_ecc, | 268 | __nand_calculate_ecc(correct_data, size, correct_ecc, |
269 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SMC)); | 269 | IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_HAMMING_SMC)); |
270 | 270 | ||
271 | for (i = 0; i < ARRAY_SIZE(nand_ecc_test); i++) { | 271 | for (i = 0; i < ARRAY_SIZE(nand_ecc_test); i++) { |
272 | nand_ecc_test[i].prepare(error_data, error_ecc, | 272 | nand_ecc_test[i].prepare(error_data, error_ecc, |
diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h index 3102bd754d18..010bc5544c54 100644 --- a/include/linux/mtd/bbm.h +++ b/include/linux/mtd/bbm.h | |||
@@ -93,10 +93,7 @@ struct nand_bbt_descr { | |||
93 | #define NAND_BBT_WRITE 0x00002000 | 93 | #define NAND_BBT_WRITE 0x00002000 |
94 | /* Read and write back block contents when writing bbt */ | 94 | /* Read and write back block contents when writing bbt */ |
95 | #define NAND_BBT_SAVECONTENT 0x00004000 | 95 | #define NAND_BBT_SAVECONTENT 0x00004000 |
96 | /* Search good / bad pattern on the first and the second page */ | 96 | |
97 | #define NAND_BBT_SCAN2NDPAGE 0x00008000 | ||
98 | /* Search good / bad pattern on the last page of the eraseblock */ | ||
99 | #define NAND_BBT_SCANLASTPAGE 0x00010000 | ||
100 | /* | 97 | /* |
101 | * Use a flash based bad block table. By default, OOB identifier is saved in | 98 | * Use a flash based bad block table. By default, OOB identifier is saved in |
102 | * OOB area. This option is passed to the default bad block table function. | 99 | * OOB area. This option is passed to the default bad block table function. |
@@ -124,13 +121,6 @@ struct nand_bbt_descr { | |||
124 | #define NAND_BBT_SCAN_MAXBLOCKS 4 | 121 | #define NAND_BBT_SCAN_MAXBLOCKS 4 |
125 | 122 | ||
126 | /* | 123 | /* |
127 | * Constants for oob configuration | ||
128 | */ | ||
129 | #define NAND_SMALL_BADBLOCK_POS 5 | ||
130 | #define NAND_LARGE_BADBLOCK_POS 0 | ||
131 | #define ONENAND_BADBLOCK_POS 0 | ||
132 | |||
133 | /* | ||
134 | * Bad block scanning errors | 124 | * Bad block scanning errors |
135 | */ | 125 | */ |
136 | #define ONENAND_BBT_READ_ERROR 1 | 126 | #define ONENAND_BBT_READ_ERROR 1 |
@@ -140,7 +130,6 @@ struct nand_bbt_descr { | |||
140 | /** | 130 | /** |
141 | * struct bbm_info - [GENERIC] Bad Block Table data structure | 131 | * struct bbm_info - [GENERIC] Bad Block Table data structure |
142 | * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry | 132 | * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry |
143 | * @badblockpos: [INTERN] position of the bad block marker in the oob area | ||
144 | * @options: options for this descriptor | 133 | * @options: options for this descriptor |
145 | * @bbt: [INTERN] bad block table pointer | 134 | * @bbt: [INTERN] bad block table pointer |
146 | * @isbad_bbt: function to determine if a block is bad | 135 | * @isbad_bbt: function to determine if a block is bad |
@@ -150,7 +139,6 @@ struct nand_bbt_descr { | |||
150 | */ | 139 | */ |
151 | struct bbm_info { | 140 | struct bbm_info { |
152 | int bbt_erase_shift; | 141 | int bbt_erase_shift; |
153 | int badblockpos; | ||
154 | int options; | 142 | int options; |
155 | 143 | ||
156 | uint8_t *bbt; | 144 | uint8_t *bbt; |
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 7f53ece2c039..cebc38b6d6f5 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h | |||
@@ -19,6 +19,7 @@ | |||
19 | * @oobsize: OOB area size | 19 | * @oobsize: OOB area size |
20 | * @pages_per_eraseblock: number of pages per eraseblock | 20 | * @pages_per_eraseblock: number of pages per eraseblock |
21 | * @eraseblocks_per_lun: number of eraseblocks per LUN (Logical Unit Number) | 21 | * @eraseblocks_per_lun: number of eraseblocks per LUN (Logical Unit Number) |
22 | * @max_bad_eraseblocks_per_lun: maximum number of eraseblocks per LUN | ||
22 | * @planes_per_lun: number of planes per LUN | 23 | * @planes_per_lun: number of planes per LUN |
23 | * @luns_per_target: number of LUN per target (target is a synonym for die) | 24 | * @luns_per_target: number of LUN per target (target is a synonym for die) |
24 | * @ntargets: total number of targets exposed by the NAND device | 25 | * @ntargets: total number of targets exposed by the NAND device |
@@ -29,18 +30,20 @@ struct nand_memory_organization { | |||
29 | unsigned int oobsize; | 30 | unsigned int oobsize; |
30 | unsigned int pages_per_eraseblock; | 31 | unsigned int pages_per_eraseblock; |
31 | unsigned int eraseblocks_per_lun; | 32 | unsigned int eraseblocks_per_lun; |
33 | unsigned int max_bad_eraseblocks_per_lun; | ||
32 | unsigned int planes_per_lun; | 34 | unsigned int planes_per_lun; |
33 | unsigned int luns_per_target; | 35 | unsigned int luns_per_target; |
34 | unsigned int ntargets; | 36 | unsigned int ntargets; |
35 | }; | 37 | }; |
36 | 38 | ||
37 | #define NAND_MEMORG(bpc, ps, os, ppe, epl, ppl, lpt, nt) \ | 39 | #define NAND_MEMORG(bpc, ps, os, ppe, epl, mbb, ppl, lpt, nt) \ |
38 | { \ | 40 | { \ |
39 | .bits_per_cell = (bpc), \ | 41 | .bits_per_cell = (bpc), \ |
40 | .pagesize = (ps), \ | 42 | .pagesize = (ps), \ |
41 | .oobsize = (os), \ | 43 | .oobsize = (os), \ |
42 | .pages_per_eraseblock = (ppe), \ | 44 | .pages_per_eraseblock = (ppe), \ |
43 | .eraseblocks_per_lun = (epl), \ | 45 | .eraseblocks_per_lun = (epl), \ |
46 | .max_bad_eraseblocks_per_lun = (mbb), \ | ||
44 | .planes_per_lun = (ppl), \ | 47 | .planes_per_lun = (ppl), \ |
45 | .luns_per_target = (lpt), \ | 48 | .luns_per_target = (lpt), \ |
46 | .ntargets = (nt), \ | 49 | .ntargets = (nt), \ |
@@ -269,6 +272,20 @@ nanddev_pages_per_eraseblock(const struct nand_device *nand) | |||
269 | } | 272 | } |
270 | 273 | ||
271 | /** | 274 | /** |
275 | * nanddev_pages_per_target() - Get the number of pages per target | ||
276 | * @nand: NAND device | ||
277 | * | ||
278 | * Return: the number of pages per target. | ||
279 | */ | ||
280 | static inline unsigned int | ||
281 | nanddev_pages_per_target(const struct nand_device *nand) | ||
282 | { | ||
283 | return nand->memorg.pages_per_eraseblock * | ||
284 | nand->memorg.eraseblocks_per_lun * | ||
285 | nand->memorg.luns_per_target; | ||
286 | } | ||
287 | |||
288 | /** | ||
272 | * nanddev_per_page_oobsize() - Get NAND erase block size | 289 | * nanddev_per_page_oobsize() - Get NAND erase block size |
273 | * @nand: NAND device | 290 | * @nand: NAND device |
274 | * | 291 | * |
@@ -292,6 +309,18 @@ nanddev_eraseblocks_per_lun(const struct nand_device *nand) | |||
292 | } | 309 | } |
293 | 310 | ||
294 | /** | 311 | /** |
312 | * nanddev_eraseblocks_per_target() - Get the number of eraseblocks per target | ||
313 | * @nand: NAND device | ||
314 | * | ||
315 | * Return: the number of eraseblocks per target. | ||
316 | */ | ||
317 | static inline unsigned int | ||
318 | nanddev_eraseblocks_per_target(const struct nand_device *nand) | ||
319 | { | ||
320 | return nand->memorg.eraseblocks_per_lun * nand->memorg.luns_per_target; | ||
321 | } | ||
322 | |||
323 | /** | ||
295 | * nanddev_target_size() - Get the total size provided by a single target/die | 324 | * nanddev_target_size() - Get the total size provided by a single target/die |
296 | * @nand: NAND device | 325 | * @nand: NAND device |
297 | * | 326 | * |
@@ -729,5 +758,6 @@ static inline bool nanddev_bbt_is_initialized(struct nand_device *nand) | |||
729 | 758 | ||
730 | /* MTD -> NAND helper functions. */ | 759 | /* MTD -> NAND helper functions. */ |
731 | int nanddev_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo); | 760 | int nanddev_mtd_erase(struct mtd_info *mtd, struct erase_info *einfo); |
761 | int nanddev_mtd_max_bad_blocks(struct mtd_info *mtd, loff_t offs, size_t len); | ||
732 | 762 | ||
733 | #endif /* __LINUX_MTD_NAND_H */ | 763 | #endif /* __LINUX_MTD_NAND_H */ |
diff --git a/include/linux/mtd/nand_bch.h b/include/linux/mtd/nand_bch.h index b8106651f807..a8a6909b594e 100644 --- a/include/linux/mtd/nand_bch.h +++ b/include/linux/mtd/nand_bch.h | |||
@@ -15,7 +15,7 @@ struct mtd_info; | |||
15 | struct nand_chip; | 15 | struct nand_chip; |
16 | struct nand_bch_control; | 16 | struct nand_bch_control; |
17 | 17 | ||
18 | #if defined(CONFIG_MTD_NAND_ECC_BCH) | 18 | #if IS_ENABLED(CONFIG_MTD_NAND_ECC_SW_BCH) |
19 | 19 | ||
20 | static inline int mtd_nand_has_bch(void) { return 1; } | 20 | static inline int mtd_nand_has_bch(void) { return 1; } |
21 | 21 | ||
@@ -39,7 +39,7 @@ struct nand_bch_control *nand_bch_init(struct mtd_info *mtd); | |||
39 | */ | 39 | */ |
40 | void nand_bch_free(struct nand_bch_control *nbc); | 40 | void nand_bch_free(struct nand_bch_control *nbc); |
41 | 41 | ||
42 | #else /* !CONFIG_MTD_NAND_ECC_BCH */ | 42 | #else /* !CONFIG_MTD_NAND_ECC_SW_BCH */ |
43 | 43 | ||
44 | static inline int mtd_nand_has_bch(void) { return 0; } | 44 | static inline int mtd_nand_has_bch(void) { return 0; } |
45 | 45 | ||
@@ -64,6 +64,6 @@ static inline struct nand_bch_control *nand_bch_init(struct mtd_info *mtd) | |||
64 | 64 | ||
65 | static inline void nand_bch_free(struct nand_bch_control *nbc) {} | 65 | static inline void nand_bch_free(struct nand_bch_control *nbc) {} |
66 | 66 | ||
67 | #endif /* CONFIG_MTD_NAND_ECC_BCH */ | 67 | #endif /* CONFIG_MTD_NAND_ECC_SW_BCH */ |
68 | 68 | ||
69 | #endif /* __MTD_NAND_BCH_H__ */ | 69 | #endif /* __MTD_NAND_BCH_H__ */ |
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h index 0aaa98b219a4..bfe9e10fae04 100644 --- a/include/linux/mtd/onenand.h +++ b/include/linux/mtd/onenand.h | |||
@@ -94,6 +94,7 @@ struct onenand_chip { | |||
94 | unsigned int technology; | 94 | unsigned int technology; |
95 | unsigned int density_mask; | 95 | unsigned int density_mask; |
96 | unsigned int options; | 96 | unsigned int options; |
97 | unsigned int badblockpos; | ||
97 | 98 | ||
98 | unsigned int erase_shift; | 99 | unsigned int erase_shift; |
99 | unsigned int page_shift; | 100 | unsigned int page_shift; |
@@ -188,6 +189,8 @@ struct onenand_chip { | |||
188 | /* Check byte access in OneNAND */ | 189 | /* Check byte access in OneNAND */ |
189 | #define ONENAND_CHECK_BYTE_ACCESS(addr) (addr & 0x1) | 190 | #define ONENAND_CHECK_BYTE_ACCESS(addr) (addr & 0x1) |
190 | 191 | ||
192 | #define ONENAND_BADBLOCK_POS 0 | ||
193 | |||
191 | /* | 194 | /* |
192 | * Options bits | 195 | * Options bits |
193 | */ | 196 | */ |
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index b7445a44a814..dbfffa5bec7b 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/mtd/flashchip.h> | 20 | #include <linux/mtd/flashchip.h> |
21 | #include <linux/mtd/bbm.h> | 21 | #include <linux/mtd/bbm.h> |
22 | #include <linux/mtd/jedec.h> | 22 | #include <linux/mtd/jedec.h> |
23 | #include <linux/mtd/nand.h> | ||
23 | #include <linux/mtd/onfi.h> | 24 | #include <linux/mtd/onfi.h> |
24 | #include <linux/mutex.h> | 25 | #include <linux/mutex.h> |
25 | #include <linux/of.h> | 26 | #include <linux/of.h> |
@@ -168,6 +169,21 @@ enum nand_ecc_algo { | |||
168 | /* Macros to identify the above */ | 169 | /* Macros to identify the above */ |
169 | #define NAND_HAS_SUBPAGE_READ(chip) ((chip->options & NAND_SUBPAGE_READ)) | 170 | #define NAND_HAS_SUBPAGE_READ(chip) ((chip->options & NAND_SUBPAGE_READ)) |
170 | 171 | ||
172 | /* | ||
173 | * There are different places where the manufacturer stores the factory bad | ||
174 | * block markers. | ||
175 | * | ||
176 | * Position within the block: Each of these pages needs to be checked for a | ||
177 | * bad block marking pattern. | ||
178 | */ | ||
179 | #define NAND_BBM_FIRSTPAGE 0x01000000 | ||
180 | #define NAND_BBM_SECONDPAGE 0x02000000 | ||
181 | #define NAND_BBM_LASTPAGE 0x04000000 | ||
182 | |||
183 | /* Position within the OOB data of the page */ | ||
184 | #define NAND_BBM_POS_SMALL 5 | ||
185 | #define NAND_BBM_POS_LARGE 0 | ||
186 | |||
171 | /* Non chip related options */ | 187 | /* Non chip related options */ |
172 | /* This option skips the bbt scan during initialization. */ | 188 | /* This option skips the bbt scan during initialization. */ |
173 | #define NAND_SKIP_BBTSCAN 0x00010000 | 189 | #define NAND_SKIP_BBTSCAN 0x00010000 |
@@ -805,7 +821,7 @@ struct nand_op_parser_pattern { | |||
805 | #define NAND_OP_PARSER_PATTERN(_exec, ...) \ | 821 | #define NAND_OP_PARSER_PATTERN(_exec, ...) \ |
806 | { \ | 822 | { \ |
807 | .exec = _exec, \ | 823 | .exec = _exec, \ |
808 | .elems = (struct nand_op_parser_pattern_elem[]) { __VA_ARGS__ }, \ | 824 | .elems = (const struct nand_op_parser_pattern_elem[]) { __VA_ARGS__ }, \ |
809 | .nelems = sizeof((struct nand_op_parser_pattern_elem[]) { __VA_ARGS__ }) / \ | 825 | .nelems = sizeof((struct nand_op_parser_pattern_elem[]) { __VA_ARGS__ }) / \ |
810 | sizeof(struct nand_op_parser_pattern_elem), \ | 826 | sizeof(struct nand_op_parser_pattern_elem), \ |
811 | } | 827 | } |
@@ -831,7 +847,7 @@ struct nand_op_parser { | |||
831 | 847 | ||
832 | #define NAND_OP_PARSER(...) \ | 848 | #define NAND_OP_PARSER(...) \ |
833 | { \ | 849 | { \ |
834 | .patterns = (struct nand_op_parser_pattern[]) { __VA_ARGS__ }, \ | 850 | .patterns = (const struct nand_op_parser_pattern[]) { __VA_ARGS__ }, \ |
835 | .npatterns = sizeof((struct nand_op_parser_pattern[]) { __VA_ARGS__ }) / \ | 851 | .npatterns = sizeof((struct nand_op_parser_pattern[]) { __VA_ARGS__ }) / \ |
836 | sizeof(struct nand_op_parser_pattern), \ | 852 | sizeof(struct nand_op_parser_pattern), \ |
837 | } | 853 | } |
@@ -860,6 +876,7 @@ struct nand_operation { | |||
860 | int nand_op_parser_exec_op(struct nand_chip *chip, | 876 | int nand_op_parser_exec_op(struct nand_chip *chip, |
861 | const struct nand_op_parser *parser, | 877 | const struct nand_op_parser *parser, |
862 | const struct nand_operation *op, bool check_only); | 878 | const struct nand_operation *op, bool check_only); |
879 | |||
863 | /** | 880 | /** |
864 | * struct nand_controller_ops - Controller operations | 881 | * struct nand_controller_ops - Controller operations |
865 | * | 882 | * |
@@ -962,7 +979,7 @@ struct nand_legacy { | |||
962 | 979 | ||
963 | /** | 980 | /** |
964 | * struct nand_chip - NAND Private Flash Chip Data | 981 | * struct nand_chip - NAND Private Flash Chip Data |
965 | * @mtd: MTD device registered to the MTD framework | 982 | * @base: Inherit from the generic NAND device |
966 | * @legacy: All legacy fields/hooks. If you develop a new driver, | 983 | * @legacy: All legacy fields/hooks. If you develop a new driver, |
967 | * don't even try to use any of these fields/hooks, and if | 984 | * don't even try to use any of these fields/hooks, and if |
968 | * you're modifying an existing driver that is using those | 985 | * you're modifying an existing driver that is using those |
@@ -990,37 +1007,26 @@ struct nand_legacy { | |||
990 | * @badblockbits: [INTERN] minimum number of set bits in a good block's | 1007 | * @badblockbits: [INTERN] minimum number of set bits in a good block's |
991 | * bad block marker position; i.e., BBM == 11110111b is | 1008 | * bad block marker position; i.e., BBM == 11110111b is |
992 | * not bad when badblockbits == 7 | 1009 | * not bad when badblockbits == 7 |
993 | * @bits_per_cell: [INTERN] number of bits per cell. i.e., 1 means SLC. | ||
994 | * @ecc_strength_ds: [INTERN] ECC correctability from the datasheet. | ||
995 | * Minimum amount of bit errors per @ecc_step_ds guaranteed | ||
996 | * to be correctable. If unknown, set to zero. | ||
997 | * @ecc_step_ds: [INTERN] ECC step required by the @ecc_strength_ds, | ||
998 | * also from the datasheet. It is the recommended ECC step | ||
999 | * size, if known; if unknown, set to zero. | ||
1000 | * @onfi_timing_mode_default: [INTERN] default ONFI timing mode. This field is | 1010 | * @onfi_timing_mode_default: [INTERN] default ONFI timing mode. This field is |
1001 | * set to the actually used ONFI mode if the chip is | 1011 | * set to the actually used ONFI mode if the chip is |
1002 | * ONFI compliant or deduced from the datasheet if | 1012 | * ONFI compliant or deduced from the datasheet if |
1003 | * the NAND chip is not ONFI compliant. | 1013 | * the NAND chip is not ONFI compliant. |
1004 | * @numchips: [INTERN] number of physical chips | ||
1005 | * @chipsize: [INTERN] the size of one chip for multichip arrays | ||
1006 | * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1 | 1014 | * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1 |
1007 | * @data_buf: [INTERN] buffer for data, size is (page size + oobsize). | 1015 | * @data_buf: [INTERN] buffer for data, size is (page size + oobsize). |
1008 | * @pagebuf: [INTERN] holds the pagenumber which is currently in | 1016 | * @pagecache: Structure containing page cache related fields |
1009 | * data_buf. | 1017 | * @pagecache.bitflips: Number of bitflips of the cached page |
1010 | * @pagebuf_bitflips: [INTERN] holds the bitflip count for the page which is | 1018 | * @pagecache.page: Page number currently in the cache. -1 means no page is |
1011 | * currently in data_buf. | 1019 | * currently cached |
1012 | * @subpagesize: [INTERN] holds the subpagesize | 1020 | * @subpagesize: [INTERN] holds the subpagesize |
1013 | * @id: [INTERN] holds NAND ID | 1021 | * @id: [INTERN] holds NAND ID |
1014 | * @parameters: [INTERN] holds generic parameters under an easily | 1022 | * @parameters: [INTERN] holds generic parameters under an easily |
1015 | * readable form. | 1023 | * readable form. |
1016 | * @max_bb_per_die: [INTERN] the max number of bad blocks each die of a | ||
1017 | * this nand device will encounter their life times. | ||
1018 | * @blocks_per_die: [INTERN] The number of PEBs in a die | ||
1019 | * @data_interface: [INTERN] NAND interface timing information | 1024 | * @data_interface: [INTERN] NAND interface timing information |
1020 | * @cur_cs: currently selected target. -1 means no target selected, | 1025 | * @cur_cs: currently selected target. -1 means no target selected, |
1021 | * otherwise we should always have cur_cs >= 0 && | 1026 | * otherwise we should always have cur_cs >= 0 && |
1022 | * cur_cs < numchips. NAND Controller drivers should not | 1027 | * cur_cs < nanddev_ntargets(). NAND Controller drivers |
1023 | * modify this value, but they're allowed to read it. | 1028 | * should not modify this value, but they're allowed to |
1029 | * read it. | ||
1024 | * @read_retries: [INTERN] the number of read retry modes supported | 1030 | * @read_retries: [INTERN] the number of read retry modes supported |
1025 | * @lock: lock protecting the suspended field. Also used to | 1031 | * @lock: lock protecting the suspended field. Also used to |
1026 | * serialize accesses to the NAND device. | 1032 | * serialize accesses to the NAND device. |
@@ -1041,7 +1047,7 @@ struct nand_legacy { | |||
1041 | */ | 1047 | */ |
1042 | 1048 | ||
1043 | struct nand_chip { | 1049 | struct nand_chip { |
1044 | struct mtd_info mtd; | 1050 | struct nand_device base; |
1045 | 1051 | ||
1046 | struct nand_legacy legacy; | 1052 | struct nand_legacy legacy; |
1047 | 1053 | ||
@@ -1054,24 +1060,21 @@ struct nand_chip { | |||
1054 | int phys_erase_shift; | 1060 | int phys_erase_shift; |
1055 | int bbt_erase_shift; | 1061 | int bbt_erase_shift; |
1056 | int chip_shift; | 1062 | int chip_shift; |
1057 | int numchips; | ||
1058 | uint64_t chipsize; | ||
1059 | int pagemask; | 1063 | int pagemask; |
1060 | u8 *data_buf; | 1064 | u8 *data_buf; |
1061 | int pagebuf; | 1065 | |
1062 | unsigned int pagebuf_bitflips; | 1066 | struct { |
1067 | unsigned int bitflips; | ||
1068 | int page; | ||
1069 | } pagecache; | ||
1070 | |||
1063 | int subpagesize; | 1071 | int subpagesize; |
1064 | uint8_t bits_per_cell; | ||
1065 | uint16_t ecc_strength_ds; | ||
1066 | uint16_t ecc_step_ds; | ||
1067 | int onfi_timing_mode_default; | 1072 | int onfi_timing_mode_default; |
1068 | int badblockpos; | 1073 | unsigned int badblockpos; |
1069 | int badblockbits; | 1074 | int badblockbits; |
1070 | 1075 | ||
1071 | struct nand_id id; | 1076 | struct nand_id id; |
1072 | struct nand_parameters parameters; | 1077 | struct nand_parameters parameters; |
1073 | u16 max_bb_per_die; | ||
1074 | u32 blocks_per_die; | ||
1075 | 1078 | ||
1076 | struct nand_data_interface data_interface; | 1079 | struct nand_data_interface data_interface; |
1077 | 1080 | ||
@@ -1105,25 +1108,14 @@ struct nand_chip { | |||
1105 | extern const struct mtd_ooblayout_ops nand_ooblayout_sp_ops; | 1108 | extern const struct mtd_ooblayout_ops nand_ooblayout_sp_ops; |
1106 | extern const struct mtd_ooblayout_ops nand_ooblayout_lp_ops; | 1109 | extern const struct mtd_ooblayout_ops nand_ooblayout_lp_ops; |
1107 | 1110 | ||
1108 | static inline void nand_set_flash_node(struct nand_chip *chip, | ||
1109 | struct device_node *np) | ||
1110 | { | ||
1111 | mtd_set_of_node(&chip->mtd, np); | ||
1112 | } | ||
1113 | |||
1114 | static inline struct device_node *nand_get_flash_node(struct nand_chip *chip) | ||
1115 | { | ||
1116 | return mtd_get_of_node(&chip->mtd); | ||
1117 | } | ||
1118 | |||
1119 | static inline struct nand_chip *mtd_to_nand(struct mtd_info *mtd) | 1111 | static inline struct nand_chip *mtd_to_nand(struct mtd_info *mtd) |
1120 | { | 1112 | { |
1121 | return container_of(mtd, struct nand_chip, mtd); | 1113 | return container_of(mtd, struct nand_chip, base.mtd); |
1122 | } | 1114 | } |
1123 | 1115 | ||
1124 | static inline struct mtd_info *nand_to_mtd(struct nand_chip *chip) | 1116 | static inline struct mtd_info *nand_to_mtd(struct nand_chip *chip) |
1125 | { | 1117 | { |
1126 | return &chip->mtd; | 1118 | return &chip->base.mtd; |
1127 | } | 1119 | } |
1128 | 1120 | ||
1129 | static inline void *nand_get_controller_data(struct nand_chip *chip) | 1121 | static inline void *nand_get_controller_data(struct nand_chip *chip) |
@@ -1147,6 +1139,17 @@ static inline void *nand_get_manufacturer_data(struct nand_chip *chip) | |||
1147 | return chip->manufacturer.priv; | 1139 | return chip->manufacturer.priv; |
1148 | } | 1140 | } |
1149 | 1141 | ||
1142 | static inline void nand_set_flash_node(struct nand_chip *chip, | ||
1143 | struct device_node *np) | ||
1144 | { | ||
1145 | mtd_set_of_node(nand_to_mtd(chip), np); | ||
1146 | } | ||
1147 | |||
1148 | static inline struct device_node *nand_get_flash_node(struct nand_chip *chip) | ||
1149 | { | ||
1150 | return mtd_get_of_node(nand_to_mtd(chip)); | ||
1151 | } | ||
1152 | |||
1150 | /* | 1153 | /* |
1151 | * A helper for defining older NAND chips where the second ID byte fully | 1154 | * A helper for defining older NAND chips where the second ID byte fully |
1152 | * defined the chip, including the geometry (chip size, eraseblock size, page | 1155 | * defined the chip, including the geometry (chip size, eraseblock size, page |
@@ -1180,9 +1183,9 @@ static inline void *nand_get_manufacturer_data(struct nand_chip *chip) | |||
1180 | * @name: a human-readable name of the NAND chip | 1183 | * @name: a human-readable name of the NAND chip |
1181 | * @dev_id: the device ID (the second byte of the full chip ID array) | 1184 | * @dev_id: the device ID (the second byte of the full chip ID array) |
1182 | * @mfr_id: manufecturer ID part of the full chip ID array (refers the same | 1185 | * @mfr_id: manufecturer ID part of the full chip ID array (refers the same |
1183 | * memory address as @id[0]) | 1186 | * memory address as ``id[0]``) |
1184 | * @dev_id: device ID part of the full chip ID array (refers the same memory | 1187 | * @dev_id: device ID part of the full chip ID array (refers the same memory |
1185 | * address as @id[1]) | 1188 | * address as ``id[1]``) |
1186 | * @id: full device ID array | 1189 | * @id: full device ID array |
1187 | * @pagesize: size of the NAND page in bytes; if 0, then the real page size (as | 1190 | * @pagesize: size of the NAND page in bytes; if 0, then the real page size (as |
1188 | * well as the eraseblock size) is determined from the extended NAND | 1191 | * well as the eraseblock size) is determined from the extended NAND |
@@ -1235,9 +1238,9 @@ int nand_create_bbt(struct nand_chip *chip); | |||
1235 | */ | 1238 | */ |
1236 | static inline bool nand_is_slc(struct nand_chip *chip) | 1239 | static inline bool nand_is_slc(struct nand_chip *chip) |
1237 | { | 1240 | { |
1238 | WARN(chip->bits_per_cell == 0, | 1241 | WARN(nanddev_bits_per_cell(&chip->base) == 0, |
1239 | "chip->bits_per_cell is used uninitialized\n"); | 1242 | "chip->bits_per_cell is used uninitialized\n"); |
1240 | return chip->bits_per_cell == 1; | 1243 | return nanddev_bits_per_cell(&chip->base) == 1; |
1241 | } | 1244 | } |
1242 | 1245 | ||
1243 | /** | 1246 | /** |
@@ -1348,4 +1351,25 @@ int nand_gpio_waitrdy(struct nand_chip *chip, struct gpio_desc *gpiod, | |||
1348 | void nand_select_target(struct nand_chip *chip, unsigned int cs); | 1351 | void nand_select_target(struct nand_chip *chip, unsigned int cs); |
1349 | void nand_deselect_target(struct nand_chip *chip); | 1352 | void nand_deselect_target(struct nand_chip *chip); |
1350 | 1353 | ||
1354 | /** | ||
1355 | * nand_get_data_buf() - Get the internal page buffer | ||
1356 | * @chip: NAND chip object | ||
1357 | * | ||
1358 | * Returns the pre-allocated page buffer after invalidating the cache. This | ||
1359 | * function should be used by drivers that do not want to allocate their own | ||
1360 | * bounce buffer and still need such a buffer for specific operations (most | ||
1361 | * commonly when reading OOB data only). | ||
1362 | * | ||
1363 | * Be careful to never call this function in the write/write_oob path, because | ||
1364 | * the core may have placed the data to be written out in this buffer. | ||
1365 | * | ||
1366 | * Return: pointer to the page cache buffer | ||
1367 | */ | ||
1368 | static inline void *nand_get_data_buf(struct nand_chip *chip) | ||
1369 | { | ||
1370 | chip->pagecache.page = -1; | ||
1371 | |||
1372 | return chip->data_buf; | ||
1373 | } | ||
1374 | |||
1351 | #endif /* __LINUX_MTD_RAWNAND_H */ | 1375 | #endif /* __LINUX_MTD_RAWNAND_H */ |
diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h index b92e2aa955b6..507f7e289bd1 100644 --- a/include/linux/mtd/spinand.h +++ b/include/linux/mtd/spinand.h | |||
@@ -302,6 +302,11 @@ struct spinand_info { | |||
302 | __VA_ARGS__ \ | 302 | __VA_ARGS__ \ |
303 | } | 303 | } |
304 | 304 | ||
305 | struct spinand_dirmap { | ||
306 | struct spi_mem_dirmap_desc *wdesc; | ||
307 | struct spi_mem_dirmap_desc *rdesc; | ||
308 | }; | ||
309 | |||
305 | /** | 310 | /** |
306 | * struct spinand_device - SPI NAND device instance | 311 | * struct spinand_device - SPI NAND device instance |
307 | * @base: NAND device instance | 312 | * @base: NAND device instance |
@@ -341,6 +346,8 @@ struct spinand_device { | |||
341 | const struct spi_mem_op *update_cache; | 346 | const struct spi_mem_op *update_cache; |
342 | } op_templates; | 347 | } op_templates; |
343 | 348 | ||
349 | struct spinand_dirmap *dirmaps; | ||
350 | |||
344 | int (*select_target)(struct spinand_device *spinand, | 351 | int (*select_target)(struct spinand_device *spinand, |
345 | unsigned int target); | 352 | unsigned int target); |
346 | unsigned int cur_target; | 353 | unsigned int cur_target; |
diff --git a/include/linux/platform_data/elm.h b/include/linux/platform_data/elm.h index b8686c00f15f..fef4b081b736 100644 --- a/include/linux/platform_data/elm.h +++ b/include/linux/platform_data/elm.h | |||
@@ -60,6 +60,6 @@ static inline int elm_config(struct device *dev, enum bch_ecc bch_type, | |||
60 | { | 60 | { |
61 | return -ENOSYS; | 61 | return -ENOSYS; |
62 | } | 62 | } |
63 | #endif /* CONFIG_MTD_NAND_ECC_BCH */ | 63 | #endif /* CONFIG_MTD_NAND_OMAP_BCH */ |
64 | 64 | ||
65 | #endif /* __ELM_H */ | 65 | #endif /* __ELM_H */ |
diff --git a/include/soc/at91/atmel-sfr.h b/include/soc/at91/atmel-sfr.h index 482337af06b8..532fd784e86c 100644 --- a/include/soc/at91/atmel-sfr.h +++ b/include/soc/at91/atmel-sfr.h | |||
@@ -14,21 +14,41 @@ | |||
14 | #define _LINUX_MFD_SYSCON_ATMEL_SFR_H | 14 | #define _LINUX_MFD_SYSCON_ATMEL_SFR_H |
15 | 15 | ||
16 | #define AT91_SFR_DDRCFG 0x04 /* DDR Configuration Register */ | 16 | #define AT91_SFR_DDRCFG 0x04 /* DDR Configuration Register */ |
17 | #define AT91_SFR_CCFG_EBICSA 0x04 /* EBI Chip Select Register */ | ||
17 | /* 0x08 ~ 0x0c: Reserved */ | 18 | /* 0x08 ~ 0x0c: Reserved */ |
18 | #define AT91_SFR_OHCIICR 0x10 /* OHCI INT Configuration Register */ | 19 | #define AT91_SFR_OHCIICR 0x10 /* OHCI INT Configuration Register */ |
19 | #define AT91_SFR_OHCIISR 0x14 /* OHCI INT Status Register */ | 20 | #define AT91_SFR_OHCIISR 0x14 /* OHCI INT Status Register */ |
20 | #define AT91_SFR_UTMICKTRIM 0x30 /* UTMI Clock Trimming Register */ | 21 | #define AT91_SFR_UTMICKTRIM 0x30 /* UTMI Clock Trimming Register */ |
22 | #define AT91_SFR_UTMISWAP 0x3c /* UTMI DP/DM Pin Swapping Register */ | ||
23 | #define AT91_SFR_LS 0x7c /* Light Sleep Register */ | ||
21 | #define AT91_SFR_I2SCLKSEL 0x90 /* I2SC Register */ | 24 | #define AT91_SFR_I2SCLKSEL 0x90 /* I2SC Register */ |
25 | #define AT91_SFR_WPMR 0xe4 /* Write Protection Mode Register */ | ||
22 | 26 | ||
23 | /* Field definitions */ | 27 | /* Field definitions */ |
24 | #define AT91_OHCIICR_SUSPEND_A BIT(8) | 28 | #define AT91_SFR_CCFG_EBI_CSA(cs, val) ((val) << (cs)) |
25 | #define AT91_OHCIICR_SUSPEND_B BIT(9) | 29 | #define AT91_SFR_CCFG_EBI_DBPUC BIT(8) |
26 | #define AT91_OHCIICR_SUSPEND_C BIT(10) | 30 | #define AT91_SFR_CCFG_EBI_DBPDC BIT(9) |
31 | #define AT91_SFR_CCFG_EBI_DRIVE BIT(17) | ||
32 | #define AT91_SFR_CCFG_NFD0_ON_D16 BIT(24) | ||
33 | #define AT91_SFR_CCFG_DDR_MP_EN BIT(25) | ||
27 | 34 | ||
28 | #define AT91_OHCIICR_USB_SUSPEND (AT91_OHCIICR_SUSPEND_A | \ | 35 | #define AT91_SFR_OHCIICR_RES(x) BIT(x) |
29 | AT91_OHCIICR_SUSPEND_B | \ | 36 | #define AT91_SFR_OHCIICR_ARIE BIT(4) |
30 | AT91_OHCIICR_SUSPEND_C) | 37 | #define AT91_SFR_OHCIICR_APPSTART BIT(5) |
38 | #define AT91_SFR_OHCIICR_USB_SUSP(x) BIT(8 + (x)) | ||
39 | #define AT91_SFR_OHCIICR_UDPPUDIS BIT(23) | ||
40 | #define AT91_OHCIICR_USB_SUSPEND GENMASK(10, 8) | ||
31 | 41 | ||
32 | #define AT91_UTMICKTRIM_FREQ GENMASK(1, 0) | 42 | #define AT91_SFR_OHCIISR_RIS(x) BIT(x) |
43 | |||
44 | #define AT91_UTMICKTRIM_FREQ GENMASK(1, 0) | ||
45 | |||
46 | #define AT91_SFR_UTMISWAP_PORT(x) BIT(x) | ||
47 | |||
48 | #define AT91_SFR_LS_VALUE(x) BIT(x) | ||
49 | #define AT91_SFR_LS_MEM_POWER_GATING_ULP1_EN BIT(16) | ||
50 | |||
51 | #define AT91_SFR_WPMR_WPEN BIT(0) | ||
52 | #define AT91_SFR_WPMR_WPKEY_MASK GENMASK(31, 8) | ||
33 | 53 | ||
34 | #endif /* _LINUX_MFD_SYSCON_ATMEL_SFR_H */ | 54 | #endif /* _LINUX_MFD_SYSCON_ATMEL_SFR_H */ |