diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-13 14:25:54 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-13 14:25:54 -0500 |
commit | ac53b2e053fffc74372da94e734b92f37e70d32c (patch) | |
tree | cda82af0fcded5d230e9f56104d3988b7a75c8aa | |
parent | cf09112d160e6db21ff8427ce696f819b957423b (diff) | |
parent | 9146cbd52b11d4ade62dba8f238ec5e421c3fa2b (diff) |
Merge tag 'for-linus-20160112' of git://git.infradead.org/linux-mtd
Pull MTD updates from Brian Norris:
"Generic MTD:
- populate the MTD device 'of_node' field (and get a proper 'of_node'
symlink in sysfs)
This yielded some new helper functions, and changes across a
variety of drivers
- partitioning cleanups, to prepare for better device-tree based
partitioning in the future
Eliminate a lot of boilerplate for drivers that want to use
OF-based partition parsing
The DT bindings for this didn't settle yet, so most non-cleanup
portions are deferred for a future release
NAND:
- embed a struct mtd_info inside struct nand_chip
This is really long overdue; too many drivers have to do the same
silly boilerplate to allocate and link up two "independent"
structs, when in fact, everyone is assuming there is an exact 1:1
relationship between a NAND chips struct and its underlying MTD.
This aids improved helpers and should make certain abstractions
easier in the future.
Also causes a lot of churn, helped along by some automated code
transformations
- add more core support for detecting (and "correcting") bitflips in
erased pages; requires opt-in by drivers, but at least we kill a
few bad implementations and hopefully stave off future ones
- pxa3xx_nand: cleanups, a few fixes, and PM improvements
- new JZ4780 NAND driver
SPI NOR:
- provide default erase function, for controllers that just want to
send the SECTOR_ERASE command directly
- fix some module auto-loading issues with device tree
("jedec,spi-nor")
- error handling fixes
- new Mediatek QSPI flash driver
Other:
- cfi: force valid geometry Kconfig (finally!)
This one used to trip up randconfigs occasionally, since bots
aren't deterred by big scary "advanced configuration" menus
More? Probably. See the commit logs"
* tag 'for-linus-20160112' of git://git.infradead.org/linux-mtd: (168 commits)
mtd: jz4780_nand: replace if/else blocks with switch/case
mtd: nand: jz4780: Update ecc correction error codes
mtd: nandsim: use nand_get_controller_data()
mtd: jz4780_nand: remove useless mtd->priv = chip assignment
staging: mt29f_spinand: make use of nand_set/get_controller_data() helpers
mtd: nand: make use of nand_set/get_controller_data() helpers
ARM: make use of nand_set/get_controller_data() helpers
mtd: nand: add helpers to access ->priv
mtd: nand: jz4780: driver for NAND devices on JZ4780 SoCs
mtd: nand: jz4740: remove custom 'erased check' implementation
mtd: nand: diskonchip: remove custom 'erased check' implementation
mtd: nand: davinci: remove custom 'erased check' implementation
mtd: nand: use nand_check_erased_ecc_chunk in default ECC read functions
mtd: nand: return consistent error codes in ecc.correct() implementations
doc: dt: mtd: new binding for jz4780-{nand,bch}
mtd: cfi_cmdset_0001: fixing memory leak and handling failed kmalloc
mtd: spi-nor: wait until lock/unlock operations are ready
mtd: tests: consolidate kmalloc/memset 0 call to kzalloc
jffs2: use to_delayed_work
mtd: nand: assign reasonable default name for NAND drivers
...
128 files changed, 3469 insertions, 1753 deletions
diff --git a/Documentation/DocBook/mtdnand.tmpl b/Documentation/DocBook/mtdnand.tmpl index 7da8f0402af5..b442921bca54 100644 --- a/Documentation/DocBook/mtdnand.tmpl +++ b/Documentation/DocBook/mtdnand.tmpl | |||
@@ -162,12 +162,15 @@ | |||
162 | <sect1 id="Basic_defines"> | 162 | <sect1 id="Basic_defines"> |
163 | <title>Basic defines</title> | 163 | <title>Basic defines</title> |
164 | <para> | 164 | <para> |
165 | At least you have to provide a mtd structure and | 165 | At least you have to provide a nand_chip structure |
166 | a storage for the ioremap'ed chip address. | 166 | and a storage for the ioremap'ed chip address. |
167 | You can allocate the mtd structure using kmalloc | 167 | You can allocate the nand_chip structure using |
168 | or you can allocate it statically. | 168 | kmalloc or you can allocate it statically. |
169 | In case of static allocation you have to allocate | 169 | The NAND chip structure embeds an mtd structure |
170 | a nand_chip structure too. | 170 | which will be registered to the MTD subsystem. |
171 | You can extract a pointer to the mtd structure | ||
172 | from a nand_chip pointer using the nand_to_mtd() | ||
173 | helper. | ||
171 | </para> | 174 | </para> |
172 | <para> | 175 | <para> |
173 | Kmalloc based example | 176 | Kmalloc based example |
@@ -180,7 +183,6 @@ static void __iomem *baseaddr; | |||
180 | Static example | 183 | Static example |
181 | </para> | 184 | </para> |
182 | <programlisting> | 185 | <programlisting> |
183 | static struct mtd_info board_mtd; | ||
184 | static struct nand_chip board_chip; | 186 | static struct nand_chip board_chip; |
185 | static void __iomem *baseaddr; | 187 | static void __iomem *baseaddr; |
186 | </programlisting> | 188 | </programlisting> |
@@ -235,7 +237,7 @@ static void board_hwcontrol(struct mtd_info *mtd, int cmd) | |||
235 | <programlisting> | 237 | <programlisting> |
236 | static void board_hwcontrol(struct mtd_info *mtd, int cmd) | 238 | static void board_hwcontrol(struct mtd_info *mtd, int cmd) |
237 | { | 239 | { |
238 | struct nand_chip *this = (struct nand_chip *) mtd->priv; | 240 | struct nand_chip *this = mtd_to_nand(mtd); |
239 | switch(cmd){ | 241 | switch(cmd){ |
240 | case NAND_CTL_SETCLE: this->IO_ADDR_W |= CLE_ADRR_BIT; break; | 242 | case NAND_CTL_SETCLE: this->IO_ADDR_W |= CLE_ADRR_BIT; break; |
241 | case NAND_CTL_CLRCLE: this->IO_ADDR_W &= ~CLE_ADRR_BIT; break; | 243 | case NAND_CTL_CLRCLE: this->IO_ADDR_W &= ~CLE_ADRR_BIT; break; |
@@ -274,13 +276,15 @@ static int __init board_init (void) | |||
274 | int err = 0; | 276 | int err = 0; |
275 | 277 | ||
276 | /* Allocate memory for MTD device structure and private data */ | 278 | /* Allocate memory for MTD device structure and private data */ |
277 | board_mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); | 279 | this = kzalloc(sizeof(struct nand_chip), GFP_KERNEL); |
278 | if (!board_mtd) { | 280 | if (!this) { |
279 | printk ("Unable to allocate NAND MTD device structure.\n"); | 281 | printk ("Unable to allocate NAND MTD device structure.\n"); |
280 | err = -ENOMEM; | 282 | err = -ENOMEM; |
281 | goto out; | 283 | goto out; |
282 | } | 284 | } |
283 | 285 | ||
286 | board_mtd = nand_to_mtd(this); | ||
287 | |||
284 | /* map physical address */ | 288 | /* map physical address */ |
285 | baseaddr = ioremap(CHIP_PHYSICAL_ADDRESS, 1024); | 289 | baseaddr = ioremap(CHIP_PHYSICAL_ADDRESS, 1024); |
286 | if (!baseaddr) { | 290 | if (!baseaddr) { |
@@ -289,11 +293,6 @@ static int __init board_init (void) | |||
289 | goto out_mtd; | 293 | goto out_mtd; |
290 | } | 294 | } |
291 | 295 | ||
292 | /* Get pointer to private data */ | ||
293 | this = (struct nand_chip *) (); | ||
294 | /* Link the private data with the MTD structure */ | ||
295 | board_mtd->priv = this; | ||
296 | |||
297 | /* Set address of NAND IO lines */ | 296 | /* Set address of NAND IO lines */ |
298 | this->IO_ADDR_R = baseaddr; | 297 | this->IO_ADDR_R = baseaddr; |
299 | this->IO_ADDR_W = baseaddr; | 298 | this->IO_ADDR_W = baseaddr; |
@@ -317,7 +316,7 @@ static int __init board_init (void) | |||
317 | out_ior: | 316 | out_ior: |
318 | iounmap(baseaddr); | 317 | iounmap(baseaddr); |
319 | out_mtd: | 318 | out_mtd: |
320 | kfree (board_mtd); | 319 | kfree (this); |
321 | out: | 320 | out: |
322 | return err; | 321 | return err; |
323 | } | 322 | } |
@@ -343,7 +342,7 @@ static void __exit board_cleanup (void) | |||
343 | iounmap(baseaddr); | 342 | iounmap(baseaddr); |
344 | 343 | ||
345 | /* Free the MTD device structure */ | 344 | /* Free the MTD device structure */ |
346 | kfree (board_mtd); | 345 | kfree (mtd_to_nand(board_mtd)); |
347 | } | 346 | } |
348 | module_exit(board_cleanup); | 347 | module_exit(board_cleanup); |
349 | #endif | 348 | #endif |
@@ -399,7 +398,7 @@ static void board_select_chip (struct mtd_info *mtd, int chip) | |||
399 | <programlisting> | 398 | <programlisting> |
400 | static void board_select_chip (struct mtd_info *mtd, int chip) | 399 | static void board_select_chip (struct mtd_info *mtd, int chip) |
401 | { | 400 | { |
402 | struct nand_chip *this = (struct nand_chip *) mtd->priv; | 401 | struct nand_chip *this = mtd_to_nand(mtd); |
403 | 402 | ||
404 | /* Deselect all chips */ | 403 | /* Deselect all chips */ |
405 | this->IO_ADDR_R &= ~BOARD_NAND_ADDR_MASK; | 404 | this->IO_ADDR_R &= ~BOARD_NAND_ADDR_MASK; |
diff --git a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt index 4ff7128ee3b2..c2546ced9c02 100644 --- a/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt +++ b/Documentation/devicetree/bindings/mtd/brcm,brcmnand.txt | |||
@@ -45,6 +45,8 @@ Required properties: | |||
45 | - #size-cells : <0> | 45 | - #size-cells : <0> |
46 | 46 | ||
47 | Optional properties: | 47 | Optional properties: |
48 | - clock : reference to the clock for the NAND controller | ||
49 | - clock-names : "nand" (required for the above clock) | ||
48 | - brcm,nand-has-wp : Some versions of this IP include a write-protect | 50 | - brcm,nand-has-wp : Some versions of this IP include a write-protect |
49 | (WP) control bit. It is always available on >= | 51 | (WP) control bit. It is always available on >= |
50 | v7.0. Use this property to describe the rare | 52 | v7.0. Use this property to describe the rare |
@@ -72,6 +74,12 @@ we define additional 'compatible' properties and associated register resources w | |||
72 | and enable registers | 74 | and enable registers |
73 | - reg-names: (required) "nand-int-base" | 75 | - reg-names: (required) "nand-int-base" |
74 | 76 | ||
77 | * "brcm,nand-bcm6368" | ||
78 | - compatible: should contain "brcm,nand-bcm<soc>", "brcm,nand-bcm6368" | ||
79 | - reg: (required) the 'NAND_INTR_BASE' register range, with combined status | ||
80 | and enable registers, and boot address registers | ||
81 | - reg-names: (required) "nand-int-base" | ||
82 | |||
75 | * "brcm,nand-iproc" | 83 | * "brcm,nand-iproc" |
76 | - reg: (required) the "IDM" register range, for interrupt enable and APB | 84 | - reg: (required) the "IDM" register range, for interrupt enable and APB |
77 | bus access endianness configuration, and the "EXT" register range, | 85 | bus access endianness configuration, and the "EXT" register range, |
@@ -148,3 +156,27 @@ nand@f0442800 { | |||
148 | }; | 156 | }; |
149 | }; | 157 | }; |
150 | }; | 158 | }; |
159 | |||
160 | nand@10000200 { | ||
161 | compatible = "brcm,nand-bcm63168", "brcm,nand-bcm6368", | ||
162 | "brcm,brcmnand-v4.0", "brcm,brcmnand"; | ||
163 | reg = <0x10000200 0x180>, | ||
164 | <0x10000600 0x200>, | ||
165 | <0x100000b0 0x10>; | ||
166 | reg-names = "nand", "nand-cache", "nand-int-base"; | ||
167 | interrupt-parent = <&periph_intc>; | ||
168 | interrupts = <50>; | ||
169 | clocks = <&periph_clk 20>; | ||
170 | clock-names = "nand"; | ||
171 | |||
172 | #address-cells = <1>; | ||
173 | #size-cells = <0>; | ||
174 | |||
175 | nand0: nandcs@0 { | ||
176 | compatible = "brcm,nandcs"; | ||
177 | reg = <0>; | ||
178 | nand-on-flash-bbt; | ||
179 | nand-ecc-strength = <1>; | ||
180 | nand-ecc-step-size = <512>; | ||
181 | }; | ||
182 | }; | ||
diff --git a/Documentation/devicetree/bindings/mtd/ingenic,jz4780-nand.txt b/Documentation/devicetree/bindings/mtd/ingenic,jz4780-nand.txt new file mode 100644 index 000000000000..29ea5853ca91 --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/ingenic,jz4780-nand.txt | |||
@@ -0,0 +1,86 @@ | |||
1 | * Ingenic JZ4780 NAND/BCH | ||
2 | |||
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 | ||
5 | memory-controllers/ingenic,jz4780-nemc.txt), and thus NAND device nodes must | ||
6 | be children of the NEMC node. | ||
7 | |||
8 | Required NAND controller device properties: | ||
9 | - compatible: Should be set to "ingenic,jz4780-nand". | ||
10 | - 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). | ||
12 | |||
13 | Optional NAND controller device properties: | ||
14 | - ingenic,bch-controller: To make use of the hardware BCH controller, this | ||
15 | property must contain a phandle for the BCH controller node. The required | ||
16 | properties for this node are described below. If this is not specified, | ||
17 | software BCH will be used instead. | ||
18 | |||
19 | Optional children nodes: | ||
20 | - Individual NAND chips are children of the NAND controller node. | ||
21 | |||
22 | Required children node properties: | ||
23 | - reg: An integer ranging from 1 to 6 representing the CS line to use. | ||
24 | |||
25 | Optional children node properties: | ||
26 | - nand-ecc-step-size: ECC block size in bytes. | ||
27 | - nand-ecc-strength: ECC strength (max number of correctable bits). | ||
28 | - nand-ecc-mode: String, operation mode of the NAND ecc mode. "hw" by default | ||
29 | - nand-on-flash-bbt: boolean to enable on flash bbt option, if not present false | ||
30 | - rb-gpios: GPIO specifier for the busy pin. | ||
31 | - wp-gpios: GPIO specifier for the write protect pin. | ||
32 | |||
33 | Optional child node of NAND chip nodes: | ||
34 | - partitions: see Documentation/devicetree/bindings/mtd/partition.txt | ||
35 | |||
36 | Example: | ||
37 | |||
38 | nemc: nemc@13410000 { | ||
39 | ... | ||
40 | |||
41 | nandc: nand-controller@1 { | ||
42 | compatible = "ingenic,jz4780-nand"; | ||
43 | reg = <1 0 0x1000000>; /* Bank 1 */ | ||
44 | |||
45 | #address-cells = <1>; | ||
46 | #size-cells = <0>; | ||
47 | |||
48 | ingenic,bch-controller = <&bch>; | ||
49 | |||
50 | nand@1 { | ||
51 | reg = <1>; | ||
52 | |||
53 | nand-ecc-step-size = <1024>; | ||
54 | nand-ecc-strength = <24>; | ||
55 | nand-ecc-mode = "hw"; | ||
56 | nand-on-flash-bbt; | ||
57 | |||
58 | rb-gpios = <&gpa 20 GPIO_ACTIVE_LOW>; | ||
59 | wp-gpios = <&gpf 22 GPIO_ACTIVE_LOW>; | ||
60 | |||
61 | partitions { | ||
62 | #address-cells = <2>; | ||
63 | #size-cells = <2>; | ||
64 | ... | ||
65 | } | ||
66 | }; | ||
67 | }; | ||
68 | }; | ||
69 | |||
70 | The BCH 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 | ||
72 | BCH controller. | ||
73 | |||
74 | Required BCH properties: | ||
75 | - compatible: Should be set to "ingenic,jz4780-bch". | ||
76 | - reg: Should specify the BCH controller registers location and length. | ||
77 | - clocks: Clock for the BCH controller. | ||
78 | |||
79 | Example: | ||
80 | |||
81 | bch: bch@134d0000 { | ||
82 | compatible = "ingenic,jz4780-bch"; | ||
83 | reg = <0x134d0000 0x10000>; | ||
84 | |||
85 | clocks = <&cgu JZ4780_CLK_BCH>; | ||
86 | }; | ||
diff --git a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt index 2bee68103b01..2c91c03e7eb0 100644 --- a/Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt +++ b/Documentation/devicetree/bindings/mtd/jedec,spi-nor.txt | |||
@@ -1,15 +1,61 @@ | |||
1 | * MTD SPI driver for ST M25Pxx (and similar) serial flash chips | 1 | * SPI NOR flash: ST M25Pxx (and similar) serial flash chips |
2 | 2 | ||
3 | Required properties: | 3 | Required properties: |
4 | - #address-cells, #size-cells : Must be present if the device has sub-nodes | 4 | - #address-cells, #size-cells : Must be present if the device has sub-nodes |
5 | representing partitions. | 5 | representing partitions. |
6 | - compatible : May include a device-specific string consisting of the | 6 | - compatible : May include a device-specific string consisting of the |
7 | manufacturer and name of the chip. Bear in mind the DT binding | 7 | manufacturer and name of the chip. A list of supported chip |
8 | is not Linux-only, but in case of Linux, see the "m25p_ids" | 8 | names follows. |
9 | table in drivers/mtd/devices/m25p80.c for the list of supported | ||
10 | chips. | ||
11 | Must also include "jedec,spi-nor" for any SPI NOR flash that can | 9 | Must also include "jedec,spi-nor" for any SPI NOR flash that can |
12 | be identified by the JEDEC READ ID opcode (0x9F). | 10 | be identified by the JEDEC READ ID opcode (0x9F). |
11 | |||
12 | Supported chip names: | ||
13 | at25df321a | ||
14 | at25df641 | ||
15 | at26df081a | ||
16 | mr25h256 | ||
17 | mx25l4005a | ||
18 | mx25l1606e | ||
19 | mx25l6405d | ||
20 | mx25l12805d | ||
21 | mx25l25635e | ||
22 | n25q064 | ||
23 | n25q128a11 | ||
24 | n25q128a13 | ||
25 | n25q512a | ||
26 | s25fl256s1 | ||
27 | s25fl512s | ||
28 | s25sl12801 | ||
29 | s25fl008k | ||
30 | s25fl064k | ||
31 | sst25vf040b | ||
32 | m25p40 | ||
33 | m25p80 | ||
34 | m25p16 | ||
35 | m25p32 | ||
36 | m25p64 | ||
37 | m25p128 | ||
38 | w25x80 | ||
39 | w25x32 | ||
40 | w25q32 | ||
41 | w25q32dw | ||
42 | w25q80bl | ||
43 | w25q128 | ||
44 | w25q256 | ||
45 | |||
46 | The following chip names have been used historically to | ||
47 | designate quirky versions of flash chips that do not support the | ||
48 | JEDEC READ ID opcode (0x9F): | ||
49 | m25p05-nonjedec | ||
50 | m25p10-nonjedec | ||
51 | m25p20-nonjedec | ||
52 | m25p40-nonjedec | ||
53 | m25p80-nonjedec | ||
54 | m25p16-nonjedec | ||
55 | m25p32-nonjedec | ||
56 | m25p64-nonjedec | ||
57 | m25p128-nonjedec | ||
58 | |||
13 | - reg : Chip-Select number | 59 | - reg : Chip-Select number |
14 | - spi-max-frequency : Maximum frequency of the SPI bus the chip can operate at | 60 | - spi-max-frequency : Maximum frequency of the SPI bus the chip can operate at |
15 | 61 | ||
diff --git a/Documentation/devicetree/bindings/mtd/mtk-quadspi.txt b/Documentation/devicetree/bindings/mtd/mtk-quadspi.txt new file mode 100644 index 000000000000..fb314f09861b --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/mtk-quadspi.txt | |||
@@ -0,0 +1,41 @@ | |||
1 | * Serial NOR flash controller for MTK MT81xx (and similar) | ||
2 | |||
3 | Required properties: | ||
4 | - compatible: should be "mediatek,mt8173-nor"; | ||
5 | - reg: physical base address and length of the controller's register | ||
6 | - clocks: the phandle of the clocks needed by the nor controller | ||
7 | - clock-names: the names of the clocks | ||
8 | the clocks should be named "spi" and "sf". "spi" is used for spi bus, | ||
9 | and "sf" is used for controller, these are the clocks witch | ||
10 | hardware needs to enabling nor flash and nor flash controller. | ||
11 | See Documentation/devicetree/bindings/clock/clock-bindings.txt for details. | ||
12 | - #address-cells: should be <1> | ||
13 | - #size-cells: should be <0> | ||
14 | |||
15 | The SPI flash must be a child of the nor_flash node and must have a | ||
16 | compatible property. Also see jedec,spi-nor.txt. | ||
17 | |||
18 | Required properties: | ||
19 | - compatible: May include a device-specific string consisting of the manufacturer | ||
20 | and name of the chip. Must also include "jedec,spi-nor" for any | ||
21 | SPI NOR flash that can be identified by the JEDEC READ ID opcode (0x9F). | ||
22 | - reg : Chip-Select number | ||
23 | |||
24 | Example: | ||
25 | |||
26 | nor_flash: spi@1100d000 { | ||
27 | compatible = "mediatek,mt8173-nor"; | ||
28 | reg = <0 0x1100d000 0 0xe0>; | ||
29 | clocks = <&pericfg CLK_PERI_SPI>, | ||
30 | <&topckgen CLK_TOP_SPINFI_IFR_SEL>; | ||
31 | clock-names = "spi", "sf"; | ||
32 | #address-cells = <1>; | ||
33 | #size-cells = <0>; | ||
34 | status = "disabled"; | ||
35 | |||
36 | flash@0 { | ||
37 | compatible = "jedec,spi-nor"; | ||
38 | reg = <0>; | ||
39 | }; | ||
40 | }; | ||
41 | |||
diff --git a/Documentation/devicetree/bindings/mtd/partition.txt b/Documentation/devicetree/bindings/mtd/partition.txt index 1c63e40659fc..81a224da63be 100644 --- a/Documentation/devicetree/bindings/mtd/partition.txt +++ b/Documentation/devicetree/bindings/mtd/partition.txt | |||
@@ -32,6 +32,8 @@ Optional properties: | |||
32 | partition should only be mounted read-only. This is usually used for flash | 32 | partition should only be mounted read-only. This is usually used for flash |
33 | partitions containing early-boot firmware images or data which should not be | 33 | partitions containing early-boot firmware images or data which should not be |
34 | clobbered. | 34 | clobbered. |
35 | - lock : Do not unlock the partition at initialization time (not supported on | ||
36 | all devices) | ||
35 | 37 | ||
36 | Examples: | 38 | Examples: |
37 | 39 | ||
diff --git a/Documentation/mtd/nand_ecc.txt b/Documentation/mtd/nand_ecc.txt index e129b2479ea8..f8c3284bf6a7 100644 --- a/Documentation/mtd/nand_ecc.txt +++ b/Documentation/mtd/nand_ecc.txt | |||
@@ -107,7 +107,7 @@ for (i = 0; i < 256; i++) | |||
107 | if (i & 0x01) | 107 | if (i & 0x01) |
108 | rp1 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp1; | 108 | rp1 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp1; |
109 | else | 109 | else |
110 | rp0 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp1; | 110 | rp0 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp0; |
111 | if (i & 0x02) | 111 | if (i & 0x02) |
112 | rp3 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp3; | 112 | rp3 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp3; |
113 | else | 113 | else |
@@ -127,7 +127,7 @@ for (i = 0; i < 256; i++) | |||
127 | if (i & 0x20) | 127 | if (i & 0x20) |
128 | rp11 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp11; | 128 | rp11 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp11; |
129 | else | 129 | else |
130 | rp10 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp10; | 130 | rp10 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp10; |
131 | if (i & 0x40) | 131 | if (i & 0x40) |
132 | rp13 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp13; | 132 | rp13 = bit7 ^ bit6 ^ bit5 ^ bit4 ^ bit3 ^ bit2 ^ bit1 ^ bit0 ^ rp13; |
133 | else | 133 | else |
@@ -158,7 +158,7 @@ the values in any order. So instead of calculating all the bits | |||
158 | individually, let us try to rearrange things. | 158 | individually, let us try to rearrange things. |
159 | For the column parity this is easy. We can just xor the bytes and in the | 159 | For the column parity this is easy. We can just xor the bytes and in the |
160 | end filter out the relevant bits. This is pretty nice as it will bring | 160 | end filter out the relevant bits. This is pretty nice as it will bring |
161 | all cp calculation out of the if loop. | 161 | all cp calculation out of the for loop. |
162 | 162 | ||
163 | Similarly we can first xor the bytes for the various rows. | 163 | Similarly we can first xor the bytes for the various rows. |
164 | This leads to: | 164 | This leads to: |
@@ -271,11 +271,11 @@ to write our code in such a way that we process data in 32 bit chunks. | |||
271 | Of course this means some modification as the row parity is byte by | 271 | Of course this means some modification as the row parity is byte by |
272 | byte. A quick analysis: | 272 | byte. A quick analysis: |
273 | for the column parity we use the par variable. When extending to 32 bits | 273 | for the column parity we use the par variable. When extending to 32 bits |
274 | we can in the end easily calculate p0 and p1 from it. | 274 | we can in the end easily calculate rp0 and rp1 from it. |
275 | (because par now consists of 4 bytes, contributing to rp1, rp0, rp1, rp0 | 275 | (because par now consists of 4 bytes, contributing to rp1, rp0, rp1, rp0 |
276 | respectively) | 276 | respectively, from MSB to LSB) |
277 | also rp2 and rp3 can be easily retrieved from par as rp3 covers the | 277 | also rp2 and rp3 can be easily retrieved from par as rp3 covers the |
278 | first two bytes and rp2 the last two bytes. | 278 | first two MSBs and rp2 covers the last two LSBs. |
279 | 279 | ||
280 | Note that of course now the loop is executed only 64 times (256/4). | 280 | Note that of course now the loop is executed only 64 times (256/4). |
281 | And note that care must taken wrt byte ordering. The way bytes are | 281 | And note that care must taken wrt byte ordering. The way bytes are |
@@ -387,11 +387,11 @@ Analysis 2 | |||
387 | 387 | ||
388 | The code (of course) works, and hurray: we are a little bit faster than | 388 | The code (of course) works, and hurray: we are a little bit faster than |
389 | the linux driver code (about 15%). But wait, don't cheer too quickly. | 389 | the linux driver code (about 15%). But wait, don't cheer too quickly. |
390 | THere is more to be gained. | 390 | There is more to be gained. |
391 | If we look at e.g. rp14 and rp15 we see that we either xor our data with | 391 | If we look at e.g. rp14 and rp15 we see that we either xor our data with |
392 | rp14 or with rp15. However we also have par which goes over all data. | 392 | rp14 or with rp15. However we also have par which goes over all data. |
393 | This means there is no need to calculate rp14 as it can be calculated from | 393 | This means there is no need to calculate rp14 as it can be calculated from |
394 | rp15 through rp14 = par ^ rp15; | 394 | rp15 through rp14 = par ^ rp15, because par = rp14 ^ rp15; |
395 | (or if desired we can avoid calculating rp15 and calculate it from | 395 | (or if desired we can avoid calculating rp15 and calculate it from |
396 | rp14). That is why some places refer to inverse parity. | 396 | rp14). That is why some places refer to inverse parity. |
397 | Of course the same thing holds for rp4/5, rp6/7, rp8/9, rp10/11 and rp12/13. | 397 | Of course the same thing holds for rp4/5, rp6/7, rp8/9, rp10/11 and rp12/13. |
@@ -419,12 +419,12 @@ with | |||
419 | if (i & 0x20) rp15 ^= cur; | 419 | if (i & 0x20) rp15 ^= cur; |
420 | 420 | ||
421 | and outside the loop added: | 421 | and outside the loop added: |
422 | rp4 = par ^ rp5; | 422 | rp4 = par ^ rp5; |
423 | rp6 = par ^ rp7; | 423 | rp6 = par ^ rp7; |
424 | rp8 = par ^ rp9; | 424 | rp8 = par ^ rp9; |
425 | rp10 = par ^ rp11; | 425 | rp10 = par ^ rp11; |
426 | rp12 = par ^ rp13; | 426 | rp12 = par ^ rp13; |
427 | rp14 = par ^ rp15; | 427 | rp14 = par ^ rp15; |
428 | 428 | ||
429 | And after that the code takes about 30% more time, although the number of | 429 | And after that the code takes about 30% more time, although the number of |
430 | statements is reduced. This is also reflected in the assembly code. | 430 | statements is reduced. This is also reflected in the assembly code. |
@@ -524,12 +524,12 @@ THe code within the for loop was changed to: | |||
524 | 524 | ||
525 | cur = *bp++; tmppar ^= cur; rp4 ^= cur; rp6 ^= cur; | 525 | cur = *bp++; tmppar ^= cur; rp4 ^= cur; rp6 ^= cur; |
526 | cur = *bp++; tmppar ^= cur; rp6 ^= cur; | 526 | cur = *bp++; tmppar ^= cur; rp6 ^= cur; |
527 | cur = *bp++; tmppar ^= cur; rp4 ^= cur; | 527 | cur = *bp++; tmppar ^= cur; rp4 ^= cur; |
528 | cur = *bp++; tmppar ^= cur; rp10 ^= tmppar; | 528 | cur = *bp++; tmppar ^= cur; rp10 ^= tmppar; |
529 | 529 | ||
530 | cur = *bp++; tmppar ^= cur; rp4 ^= cur; rp6 ^= cur; rp8 ^= cur; | 530 | cur = *bp++; tmppar ^= cur; rp4 ^= cur; rp6 ^= cur; rp8 ^= cur; |
531 | cur = *bp++; tmppar ^= cur; rp6 ^= cur; rp8 ^= cur; | 531 | cur = *bp++; tmppar ^= cur; rp6 ^= cur; rp8 ^= cur; |
532 | cur = *bp++; tmppar ^= cur; rp4 ^= cur; rp8 ^= cur; | 532 | cur = *bp++; tmppar ^= cur; rp4 ^= cur; rp8 ^= cur; |
533 | cur = *bp++; tmppar ^= cur; rp8 ^= cur; | 533 | cur = *bp++; tmppar ^= cur; rp8 ^= cur; |
534 | 534 | ||
535 | cur = *bp++; tmppar ^= cur; rp4 ^= cur; rp6 ^= cur; | 535 | cur = *bp++; tmppar ^= cur; rp4 ^= cur; rp6 ^= cur; |
@@ -537,7 +537,7 @@ THe code within the for loop was changed to: | |||
537 | cur = *bp++; tmppar ^= cur; rp4 ^= cur; | 537 | cur = *bp++; tmppar ^= cur; rp4 ^= cur; |
538 | cur = *bp++; tmppar ^= cur; | 538 | cur = *bp++; tmppar ^= cur; |
539 | 539 | ||
540 | par ^= tmppar; | 540 | par ^= tmppar; |
541 | if ((i & 0x1) == 0) rp12 ^= tmppar; | 541 | if ((i & 0x1) == 0) rp12 ^= tmppar; |
542 | if ((i & 0x2) == 0) rp14 ^= tmppar; | 542 | if ((i & 0x2) == 0) rp14 ^= tmppar; |
543 | } | 543 | } |
@@ -548,8 +548,8 @@ to rp12 and rp14. | |||
548 | 548 | ||
549 | While making the changes I also found that I could exploit that tmppar | 549 | While making the changes I also found that I could exploit that tmppar |
550 | contains the running parity for this iteration. So instead of having: | 550 | contains the running parity for this iteration. So instead of having: |
551 | rp4 ^= cur; rp6 = cur; | 551 | rp4 ^= cur; rp6 ^= cur; |
552 | I removed the rp6 = cur; statement and did rp6 ^= tmppar; on next | 552 | I removed the rp6 ^= cur; statement and did rp6 ^= tmppar; on next |
553 | statement. A similar change was done for rp8 and rp10 | 553 | statement. A similar change was done for rp8 and rp10 |
554 | 554 | ||
555 | 555 | ||
@@ -593,22 +593,22 @@ The new code now looks like: | |||
593 | 593 | ||
594 | cur = *bp++; tmppar ^= cur; rp4_6 ^= cur; | 594 | cur = *bp++; tmppar ^= cur; rp4_6 ^= cur; |
595 | cur = *bp++; tmppar ^= cur; rp6 ^= cur; | 595 | cur = *bp++; tmppar ^= cur; rp6 ^= cur; |
596 | cur = *bp++; tmppar ^= cur; rp4 ^= cur; | 596 | cur = *bp++; tmppar ^= cur; rp4 ^= cur; |
597 | cur = *bp++; tmppar ^= cur; rp10 ^= tmppar; | 597 | cur = *bp++; tmppar ^= cur; rp10 ^= tmppar; |
598 | 598 | ||
599 | notrp8 = tmppar; | 599 | notrp8 = tmppar; |
600 | cur = *bp++; tmppar ^= cur; rp4_6 ^= cur; | 600 | cur = *bp++; tmppar ^= cur; rp4_6 ^= cur; |
601 | cur = *bp++; tmppar ^= cur; rp6 ^= cur; | 601 | cur = *bp++; tmppar ^= cur; rp6 ^= cur; |
602 | cur = *bp++; tmppar ^= cur; rp4 ^= cur; | 602 | cur = *bp++; tmppar ^= cur; rp4 ^= cur; |
603 | cur = *bp++; tmppar ^= cur; | 603 | cur = *bp++; tmppar ^= cur; |
604 | rp8 = rp8 ^ tmppar ^ notrp8; | 604 | rp8 = rp8 ^ tmppar ^ notrp8; |
605 | 605 | ||
606 | cur = *bp++; tmppar ^= cur; rp4_6 ^= cur; | 606 | cur = *bp++; tmppar ^= cur; rp4_6 ^= cur; |
607 | cur = *bp++; tmppar ^= cur; rp6 ^= cur; | 607 | cur = *bp++; tmppar ^= cur; rp6 ^= cur; |
608 | cur = *bp++; tmppar ^= cur; rp4 ^= cur; | 608 | cur = *bp++; tmppar ^= cur; rp4 ^= cur; |
609 | cur = *bp++; tmppar ^= cur; | 609 | cur = *bp++; tmppar ^= cur; |
610 | 610 | ||
611 | par ^= tmppar; | 611 | par ^= tmppar; |
612 | if ((i & 0x1) == 0) rp12 ^= tmppar; | 612 | if ((i & 0x1) == 0) rp12 ^= tmppar; |
613 | if ((i & 0x2) == 0) rp14 ^= tmppar; | 613 | if ((i & 0x2) == 0) rp14 ^= tmppar; |
614 | } | 614 | } |
@@ -700,7 +700,7 @@ Conclusion | |||
700 | The gain when calculating the ecc is tremendous. Om my development hardware | 700 | The gain when calculating the ecc is tremendous. Om my development hardware |
701 | a speedup of a factor of 18 for ecc calculation was achieved. On a test on an | 701 | a speedup of a factor of 18 for ecc calculation was achieved. On a test on an |
702 | embedded system with a MIPS core a factor 7 was obtained. | 702 | embedded system with a MIPS core a factor 7 was obtained. |
703 | On a test with a Linksys NSLU2 (ARMv5TE processor) the speedup was a factor | 703 | On a test with a Linksys NSLU2 (ARMv5TE processor) the speedup was a factor |
704 | 5 (big endian mode, gcc 4.1.2, -O3) | 704 | 5 (big endian mode, gcc 4.1.2, -O3) |
705 | For correction not much gain could be obtained (as bitflips are rare). Then | 705 | For correction not much gain could be obtained (as bitflips are rare). Then |
706 | again there are also much less cycles spent there. | 706 | again there are also much less cycles spent there. |
diff --git a/arch/arm/mach-ep93xx/snappercl15.c b/arch/arm/mach-ep93xx/snappercl15.c index c4904264256a..b2db791b3b38 100644 --- a/arch/arm/mach-ep93xx/snappercl15.c +++ b/arch/arm/mach-ep93xx/snappercl15.c | |||
@@ -49,7 +49,7 @@ | |||
49 | static void snappercl15_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, | 49 | static void snappercl15_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, |
50 | unsigned int ctrl) | 50 | unsigned int ctrl) |
51 | { | 51 | { |
52 | struct nand_chip *chip = mtd->priv; | 52 | struct nand_chip *chip = mtd_to_nand(mtd); |
53 | static u16 nand_state = SNAPPERCL15_NAND_WPN; | 53 | static u16 nand_state = SNAPPERCL15_NAND_WPN; |
54 | u16 set; | 54 | u16 set; |
55 | 55 | ||
@@ -76,7 +76,7 @@ static void snappercl15_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, | |||
76 | 76 | ||
77 | static int snappercl15_nand_dev_ready(struct mtd_info *mtd) | 77 | static int snappercl15_nand_dev_ready(struct mtd_info *mtd) |
78 | { | 78 | { |
79 | struct nand_chip *chip = mtd->priv; | 79 | struct nand_chip *chip = mtd_to_nand(mtd); |
80 | 80 | ||
81 | return !!(__raw_readw(NAND_CTRL_ADDR(chip)) & SNAPPERCL15_NAND_RDY); | 81 | return !!(__raw_readw(NAND_CTRL_ADDR(chip)) & SNAPPERCL15_NAND_RDY); |
82 | } | 82 | } |
diff --git a/arch/arm/mach-ep93xx/ts72xx.c b/arch/arm/mach-ep93xx/ts72xx.c index 61f4b5dc4d7d..45b81a2bcd4b 100644 --- a/arch/arm/mach-ep93xx/ts72xx.c +++ b/arch/arm/mach-ep93xx/ts72xx.c | |||
@@ -74,7 +74,7 @@ static void __init ts72xx_map_io(void) | |||
74 | static void ts72xx_nand_hwcontrol(struct mtd_info *mtd, | 74 | static void ts72xx_nand_hwcontrol(struct mtd_info *mtd, |
75 | int cmd, unsigned int ctrl) | 75 | int cmd, unsigned int ctrl) |
76 | { | 76 | { |
77 | struct nand_chip *chip = mtd->priv; | 77 | struct nand_chip *chip = mtd_to_nand(mtd); |
78 | 78 | ||
79 | if (ctrl & NAND_CTRL_CHANGE) { | 79 | if (ctrl & NAND_CTRL_CHANGE) { |
80 | void __iomem *addr = chip->IO_ADDR_R; | 80 | void __iomem *addr = chip->IO_ADDR_R; |
@@ -96,7 +96,7 @@ static void ts72xx_nand_hwcontrol(struct mtd_info *mtd, | |||
96 | 96 | ||
97 | static int ts72xx_nand_device_ready(struct mtd_info *mtd) | 97 | static int ts72xx_nand_device_ready(struct mtd_info *mtd) |
98 | { | 98 | { |
99 | struct nand_chip *chip = mtd->priv; | 99 | struct nand_chip *chip = mtd_to_nand(mtd); |
100 | void __iomem *addr = chip->IO_ADDR_R; | 100 | void __iomem *addr = chip->IO_ADDR_R; |
101 | 101 | ||
102 | addr += (1 << TS72XX_NAND_BUSY_ADDR_LINE); | 102 | addr += (1 << TS72XX_NAND_BUSY_ADDR_LINE); |
diff --git a/arch/arm/mach-imx/mach-qong.c b/arch/arm/mach-imx/mach-qong.c index a213e7b9cb1c..5c2764604727 100644 --- a/arch/arm/mach-imx/mach-qong.c +++ b/arch/arm/mach-imx/mach-qong.c | |||
@@ -131,7 +131,7 @@ static void qong_init_nor_mtd(void) | |||
131 | */ | 131 | */ |
132 | static void qong_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 132 | static void qong_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
133 | { | 133 | { |
134 | struct nand_chip *nand_chip = mtd->priv; | 134 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
135 | 135 | ||
136 | if (cmd == NAND_CMD_NONE) | 136 | if (cmd == NAND_CMD_NONE) |
137 | return; | 137 | return; |
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c index e7b8befa8729..508c2d7786e2 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-setup.c +++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c | |||
@@ -76,8 +76,8 @@ static struct mtd_partition ixdp425_partitions[] = { | |||
76 | static void | 76 | static void |
77 | ixdp425_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 77 | ixdp425_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
78 | { | 78 | { |
79 | struct nand_chip *this = mtd->priv; | 79 | struct nand_chip *this = mtd_to_nand(mtd); |
80 | int offset = (int)this->priv; | 80 | int offset = (int)nand_get_controller_data(this); |
81 | 81 | ||
82 | if (ctrl & NAND_CTRL_CHANGE) { | 82 | if (ctrl & NAND_CTRL_CHANGE) { |
83 | if (ctrl & NAND_NCE) { | 83 | if (ctrl & NAND_NCE) { |
@@ -88,7 +88,7 @@ ixdp425_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | |||
88 | 88 | ||
89 | offset = (ctrl & NAND_CLE) ? IXDP425_NAND_CMD_BYTE : 0; | 89 | offset = (ctrl & NAND_CLE) ? IXDP425_NAND_CMD_BYTE : 0; |
90 | offset |= (ctrl & NAND_ALE) ? IXDP425_NAND_ADDR_BYTE : 0; | 90 | offset |= (ctrl & NAND_ALE) ? IXDP425_NAND_ADDR_BYTE : 0; |
91 | this->priv = (void *)offset; | 91 | nand_set_controller_data(this, (void *)offset); |
92 | } | 92 | } |
93 | 93 | ||
94 | if (cmd != NAND_CMD_NONE) | 94 | if (cmd != NAND_CMD_NONE) |
diff --git a/arch/arm/mach-omap1/board-nand.c b/arch/arm/mach-omap1/board-nand.c index 4d0835327d20..7684f9203474 100644 --- a/arch/arm/mach-omap1/board-nand.c +++ b/arch/arm/mach-omap1/board-nand.c | |||
@@ -22,7 +22,7 @@ | |||
22 | 22 | ||
23 | void omap1_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 23 | void omap1_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
24 | { | 24 | { |
25 | struct nand_chip *this = mtd->priv; | 25 | struct nand_chip *this = mtd_to_nand(mtd); |
26 | unsigned long mask; | 26 | unsigned long mask; |
27 | 27 | ||
28 | if (cmd == NAND_CMD_NONE) | 28 | if (cmd == NAND_CMD_NONE) |
diff --git a/arch/arm/mach-orion5x/ts78xx-setup.c b/arch/arm/mach-orion5x/ts78xx-setup.c index 1b704d35cf5b..96cf6b51eddc 100644 --- a/arch/arm/mach-orion5x/ts78xx-setup.c +++ b/arch/arm/mach-orion5x/ts78xx-setup.c | |||
@@ -176,7 +176,7 @@ static void ts78xx_ts_rtc_unload(void) | |||
176 | static void ts78xx_ts_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, | 176 | static void ts78xx_ts_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, |
177 | unsigned int ctrl) | 177 | unsigned int ctrl) |
178 | { | 178 | { |
179 | struct nand_chip *this = mtd->priv; | 179 | struct nand_chip *this = mtd_to_nand(mtd); |
180 | 180 | ||
181 | if (ctrl & NAND_CTRL_CHANGE) { | 181 | if (ctrl & NAND_CTRL_CHANGE) { |
182 | unsigned char bits; | 182 | unsigned char bits; |
@@ -200,7 +200,7 @@ static int ts78xx_ts_nand_dev_ready(struct mtd_info *mtd) | |||
200 | static void ts78xx_ts_nand_write_buf(struct mtd_info *mtd, | 200 | static void ts78xx_ts_nand_write_buf(struct mtd_info *mtd, |
201 | const uint8_t *buf, int len) | 201 | const uint8_t *buf, int len) |
202 | { | 202 | { |
203 | struct nand_chip *chip = mtd->priv; | 203 | struct nand_chip *chip = mtd_to_nand(mtd); |
204 | void __iomem *io_base = chip->IO_ADDR_W; | 204 | void __iomem *io_base = chip->IO_ADDR_W; |
205 | unsigned long off = ((unsigned long)buf & 3); | 205 | unsigned long off = ((unsigned long)buf & 3); |
206 | int sz; | 206 | int sz; |
@@ -227,7 +227,7 @@ static void ts78xx_ts_nand_write_buf(struct mtd_info *mtd, | |||
227 | static void ts78xx_ts_nand_read_buf(struct mtd_info *mtd, | 227 | static void ts78xx_ts_nand_read_buf(struct mtd_info *mtd, |
228 | uint8_t *buf, int len) | 228 | uint8_t *buf, int len) |
229 | { | 229 | { |
230 | struct nand_chip *chip = mtd->priv; | 230 | struct nand_chip *chip = mtd_to_nand(mtd); |
231 | void __iomem *io_base = chip->IO_ADDR_R; | 231 | void __iomem *io_base = chip->IO_ADDR_R; |
232 | unsigned long off = ((unsigned long)buf & 3); | 232 | unsigned long off = ((unsigned long)buf & 3); |
233 | int sz; | 233 | int sz; |
diff --git a/arch/arm/mach-pxa/balloon3.c b/arch/arm/mach-pxa/balloon3.c index a727282bfa99..7734ec4f1385 100644 --- a/arch/arm/mach-pxa/balloon3.c +++ b/arch/arm/mach-pxa/balloon3.c | |||
@@ -572,7 +572,7 @@ static inline void balloon3_i2c_init(void) {} | |||
572 | #if defined(CONFIG_MTD_NAND_PLATFORM)||defined(CONFIG_MTD_NAND_PLATFORM_MODULE) | 572 | #if defined(CONFIG_MTD_NAND_PLATFORM)||defined(CONFIG_MTD_NAND_PLATFORM_MODULE) |
573 | static void balloon3_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 573 | static void balloon3_nand_cmd_ctl(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
574 | { | 574 | { |
575 | struct nand_chip *this = mtd->priv; | 575 | struct nand_chip *this = mtd_to_nand(mtd); |
576 | uint8_t balloon3_ctl_set = 0, balloon3_ctl_clr = 0; | 576 | uint8_t balloon3_ctl_set = 0, balloon3_ctl_clr = 0; |
577 | 577 | ||
578 | if (ctrl & NAND_CTRL_CHANGE) { | 578 | if (ctrl & NAND_CTRL_CHANGE) { |
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index 8b1f89e096c6..2a76c4ef8d03 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c | |||
@@ -289,7 +289,7 @@ static void nand_cs_off(void) | |||
289 | static void em_x270_nand_cmd_ctl(struct mtd_info *mtd, int dat, | 289 | static void em_x270_nand_cmd_ctl(struct mtd_info *mtd, int dat, |
290 | unsigned int ctrl) | 290 | unsigned int ctrl) |
291 | { | 291 | { |
292 | struct nand_chip *this = mtd->priv; | 292 | struct nand_chip *this = mtd_to_nand(mtd); |
293 | unsigned long nandaddr = (unsigned long)this->IO_ADDR_W; | 293 | unsigned long nandaddr = (unsigned long)this->IO_ADDR_W; |
294 | 294 | ||
295 | dsb(); | 295 | dsb(); |
diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c index 83f830dd8ad8..d787dd17f6b2 100644 --- a/arch/arm/mach-pxa/palmtx.c +++ b/arch/arm/mach-pxa/palmtx.c | |||
@@ -250,7 +250,7 @@ static inline void palmtx_keys_init(void) {} | |||
250 | static void palmtx_nand_cmd_ctl(struct mtd_info *mtd, int cmd, | 250 | static void palmtx_nand_cmd_ctl(struct mtd_info *mtd, int cmd, |
251 | unsigned int ctrl) | 251 | unsigned int ctrl) |
252 | { | 252 | { |
253 | struct nand_chip *this = mtd->priv; | 253 | struct nand_chip *this = mtd_to_nand(mtd); |
254 | char __iomem *nandaddr = this->IO_ADDR_W; | 254 | char __iomem *nandaddr = this->IO_ADDR_W; |
255 | 255 | ||
256 | if (cmd == NAND_CMD_NONE) | 256 | if (cmd == NAND_CMD_NONE) |
diff --git a/arch/blackfin/mach-bf537/boards/stamp.c b/arch/blackfin/mach-bf537/boards/stamp.c index 88a19fc9844d..c181543a399a 100644 --- a/arch/blackfin/mach-bf537/boards/stamp.c +++ b/arch/blackfin/mach-bf537/boards/stamp.c | |||
@@ -404,7 +404,7 @@ static struct mtd_partition bfin_plat_nand_partitions[] = { | |||
404 | #define BFIN_NAND_PLAT_ALE 1 | 404 | #define BFIN_NAND_PLAT_ALE 1 |
405 | static void bfin_plat_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 405 | static void bfin_plat_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
406 | { | 406 | { |
407 | struct nand_chip *this = mtd->priv; | 407 | struct nand_chip *this = mtd_to_nand(mtd); |
408 | 408 | ||
409 | if (cmd == NAND_CMD_NONE) | 409 | if (cmd == NAND_CMD_NONE) |
410 | return; | 410 | return; |
diff --git a/arch/blackfin/mach-bf561/boards/acvilon.c b/arch/blackfin/mach-bf561/boards/acvilon.c index 6ab951534d79..37f8f25a1347 100644 --- a/arch/blackfin/mach-bf561/boards/acvilon.c +++ b/arch/blackfin/mach-bf561/boards/acvilon.c | |||
@@ -267,7 +267,7 @@ static struct mtd_partition bfin_plat_nand_partitions[] = { | |||
267 | static void bfin_plat_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, | 267 | static void bfin_plat_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, |
268 | unsigned int ctrl) | 268 | unsigned int ctrl) |
269 | { | 269 | { |
270 | struct nand_chip *this = mtd->priv; | 270 | struct nand_chip *this = mtd_to_nand(mtd); |
271 | 271 | ||
272 | if (cmd == NAND_CMD_NONE) | 272 | if (cmd == NAND_CMD_NONE) |
273 | return; | 273 | return; |
diff --git a/arch/cris/arch-v32/drivers/mach-a3/nandflash.c b/arch/cris/arch-v32/drivers/mach-a3/nandflash.c index 7fb52128ddc9..5aa3f5162310 100644 --- a/arch/cris/arch-v32/drivers/mach-a3/nandflash.c +++ b/arch/cris/arch-v32/drivers/mach-a3/nandflash.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #define CE_BIT 12 | 36 | #define CE_BIT 12 |
37 | 37 | ||
38 | struct mtd_info_wrapper { | 38 | struct mtd_info_wrapper { |
39 | struct mtd_info info; | ||
40 | struct nand_chip chip; | 39 | struct nand_chip chip; |
41 | }; | 40 | }; |
42 | 41 | ||
@@ -52,7 +51,7 @@ static void crisv32_hwcontrol(struct mtd_info *mtd, int cmd, | |||
52 | { | 51 | { |
53 | unsigned long flags; | 52 | unsigned long flags; |
54 | reg_pio_rw_dout dout; | 53 | reg_pio_rw_dout dout; |
55 | struct nand_chip *this = mtd->priv; | 54 | struct nand_chip *this = mtd_to_nand(mtd); |
56 | 55 | ||
57 | local_irq_save(flags); | 56 | local_irq_save(flags); |
58 | 57 | ||
@@ -148,10 +147,7 @@ struct mtd_info *__init crisv32_nand_flash_probe(void) | |||
148 | 147 | ||
149 | /* Get pointer to private data */ | 148 | /* Get pointer to private data */ |
150 | this = &wrapper->chip; | 149 | this = &wrapper->chip; |
151 | crisv32_mtd = &wrapper->info; | 150 | crisv32_mtd = nand_to_mtd(this); |
152 | |||
153 | /* Link the private data with the MTD structure */ | ||
154 | crisv32_mtd->priv = this; | ||
155 | 151 | ||
156 | /* Set address of NAND IO lines */ | 152 | /* Set address of NAND IO lines */ |
157 | this->IO_ADDR_R = read_cs; | 153 | this->IO_ADDR_R = read_cs; |
diff --git a/arch/cris/arch-v32/drivers/mach-fs/nandflash.c b/arch/cris/arch-v32/drivers/mach-fs/nandflash.c index e03238454b0e..a7c17b0f172a 100644 --- a/arch/cris/arch-v32/drivers/mach-fs/nandflash.c +++ b/arch/cris/arch-v32/drivers/mach-fs/nandflash.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #define BY_BIT 7 | 31 | #define BY_BIT 7 |
32 | 32 | ||
33 | struct mtd_info_wrapper { | 33 | struct mtd_info_wrapper { |
34 | struct mtd_info info; | ||
35 | struct nand_chip chip; | 34 | struct nand_chip chip; |
36 | }; | 35 | }; |
37 | 36 | ||
@@ -51,7 +50,7 @@ static void crisv32_hwcontrol(struct mtd_info *mtd, int cmd, | |||
51 | { | 50 | { |
52 | unsigned long flags; | 51 | unsigned long flags; |
53 | reg_gio_rw_pa_dout dout; | 52 | reg_gio_rw_pa_dout dout; |
54 | struct nand_chip *this = mtd->priv; | 53 | struct nand_chip *this = mtd_to_nand(mtd); |
55 | 54 | ||
56 | local_irq_save(flags); | 55 | local_irq_save(flags); |
57 | 56 | ||
@@ -129,7 +128,7 @@ struct mtd_info *__init crisv32_nand_flash_probe(void) | |||
129 | 128 | ||
130 | /* Get pointer to private data */ | 129 | /* Get pointer to private data */ |
131 | this = &wrapper->chip; | 130 | this = &wrapper->chip; |
132 | crisv32_mtd = &wrapper->info; | 131 | crisv32_mtd = nand_to_mtd(this); |
133 | 132 | ||
134 | pa_oe.oe |= 1 << CE_BIT; | 133 | pa_oe.oe |= 1 << CE_BIT; |
135 | pa_oe.oe |= 1 << ALE_BIT; | 134 | pa_oe.oe |= 1 << ALE_BIT; |
@@ -141,9 +140,6 @@ struct mtd_info *__init crisv32_nand_flash_probe(void) | |||
141 | bif_cfg.gated_csp1 = regk_bif_core_wr; | 140 | bif_cfg.gated_csp1 = regk_bif_core_wr; |
142 | REG_WR(bif_core, regi_bif_core, rw_grp3_cfg, bif_cfg); | 141 | REG_WR(bif_core, regi_bif_core, rw_grp3_cfg, bif_cfg); |
143 | 142 | ||
144 | /* Link the private data with the MTD structure */ | ||
145 | crisv32_mtd->priv = this; | ||
146 | |||
147 | /* Set address of NAND IO lines */ | 143 | /* Set address of NAND IO lines */ |
148 | this->IO_ADDR_R = read_cs; | 144 | this->IO_ADDR_R = read_cs; |
149 | this->IO_ADDR_W = write_cs; | 145 | this->IO_ADDR_W = write_cs; |
diff --git a/arch/mips/alchemy/devboards/db1200.c b/arch/mips/alchemy/devboards/db1200.c index 8c13675a12e7..992442a03d8b 100644 --- a/arch/mips/alchemy/devboards/db1200.c +++ b/arch/mips/alchemy/devboards/db1200.c | |||
@@ -200,7 +200,7 @@ static struct i2c_board_info db1200_i2c_devs[] __initdata = { | |||
200 | static void au1200_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, | 200 | static void au1200_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, |
201 | unsigned int ctrl) | 201 | unsigned int ctrl) |
202 | { | 202 | { |
203 | struct nand_chip *this = mtd->priv; | 203 | struct nand_chip *this = mtd_to_nand(mtd); |
204 | unsigned long ioaddr = (unsigned long)this->IO_ADDR_W; | 204 | unsigned long ioaddr = (unsigned long)this->IO_ADDR_W; |
205 | 205 | ||
206 | ioaddr &= 0xffffff00; | 206 | ioaddr &= 0xffffff00; |
diff --git a/arch/mips/alchemy/devboards/db1300.c b/arch/mips/alchemy/devboards/db1300.c index b58077008a53..d3c087f59f1a 100644 --- a/arch/mips/alchemy/devboards/db1300.c +++ b/arch/mips/alchemy/devboards/db1300.c | |||
@@ -150,7 +150,7 @@ static void __init db1300_gpio_config(void) | |||
150 | static void au1300_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, | 150 | static void au1300_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, |
151 | unsigned int ctrl) | 151 | unsigned int ctrl) |
152 | { | 152 | { |
153 | struct nand_chip *this = mtd->priv; | 153 | struct nand_chip *this = mtd_to_nand(mtd); |
154 | unsigned long ioaddr = (unsigned long)this->IO_ADDR_W; | 154 | unsigned long ioaddr = (unsigned long)this->IO_ADDR_W; |
155 | 155 | ||
156 | ioaddr &= 0xffffff00; | 156 | ioaddr &= 0xffffff00; |
diff --git a/arch/mips/alchemy/devboards/db1550.c b/arch/mips/alchemy/devboards/db1550.c index 5740bcfdfc7f..b518f029f5e7 100644 --- a/arch/mips/alchemy/devboards/db1550.c +++ b/arch/mips/alchemy/devboards/db1550.c | |||
@@ -128,7 +128,7 @@ static struct i2c_board_info db1550_i2c_devs[] __initdata = { | |||
128 | static void au1550_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, | 128 | static void au1550_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, |
129 | unsigned int ctrl) | 129 | unsigned int ctrl) |
130 | { | 130 | { |
131 | struct nand_chip *this = mtd->priv; | 131 | struct nand_chip *this = mtd_to_nand(mtd); |
132 | unsigned long ioaddr = (unsigned long)this->IO_ADDR_W; | 132 | unsigned long ioaddr = (unsigned long)this->IO_ADDR_W; |
133 | 133 | ||
134 | ioaddr &= 0xffffff00; | 134 | ioaddr &= 0xffffff00; |
diff --git a/arch/mips/pnx833x/common/platform.c b/arch/mips/pnx833x/common/platform.c index b4b774bc3178..3cd357737a26 100644 --- a/arch/mips/pnx833x/common/platform.c +++ b/arch/mips/pnx833x/common/platform.c | |||
@@ -180,7 +180,7 @@ static struct platform_device pnx833x_sata_device = { | |||
180 | static void | 180 | static void |
181 | pnx833x_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 181 | pnx833x_flash_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
182 | { | 182 | { |
183 | struct nand_chip *this = mtd->priv; | 183 | struct nand_chip *this = mtd_to_nand(mtd); |
184 | unsigned long nandaddr = (unsigned long)this->IO_ADDR_W; | 184 | unsigned long nandaddr = (unsigned long)this->IO_ADDR_W; |
185 | 185 | ||
186 | if (cmd == NAND_CMD_NONE) | 186 | if (cmd == NAND_CMD_NONE) |
diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c index 9bd7a2de0765..0966adccf520 100644 --- a/arch/mips/rb532/devices.c +++ b/arch/mips/rb532/devices.c | |||
@@ -148,7 +148,7 @@ static int rb532_dev_ready(struct mtd_info *mtd) | |||
148 | 148 | ||
149 | static void rb532_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 149 | static void rb532_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
150 | { | 150 | { |
151 | struct nand_chip *chip = mtd->priv; | 151 | struct nand_chip *chip = mtd_to_nand(mtd); |
152 | unsigned char orbits, nandbits; | 152 | unsigned char orbits, nandbits; |
153 | 153 | ||
154 | if (ctrl & NAND_CTRL_CHANGE) { | 154 | if (ctrl & NAND_CTRL_CHANGE) { |
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index 8f237a5bd9aa..7a04da3efce4 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c | |||
@@ -167,7 +167,7 @@ static struct mtd_partition migor_nand_flash_partitions[] = { | |||
167 | static void migor_nand_flash_cmd_ctl(struct mtd_info *mtd, int cmd, | 167 | static void migor_nand_flash_cmd_ctl(struct mtd_info *mtd, int cmd, |
168 | unsigned int ctrl) | 168 | unsigned int ctrl) |
169 | { | 169 | { |
170 | struct nand_chip *chip = mtd->priv; | 170 | struct nand_chip *chip = mtd_to_nand(mtd); |
171 | 171 | ||
172 | if (cmd == NAND_CMD_NONE) | 172 | if (cmd == NAND_CMD_NONE) |
173 | return; | 173 | return; |
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index a03ad2951c7b..42cc953309f1 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig | |||
@@ -112,7 +112,7 @@ config MTD_CMDLINE_PARTS | |||
112 | 112 | ||
113 | config MTD_AFS_PARTS | 113 | config MTD_AFS_PARTS |
114 | tristate "ARM Firmware Suite partition parsing" | 114 | tristate "ARM Firmware Suite partition parsing" |
115 | depends on ARM | 115 | depends on (ARM || ARM64) |
116 | ---help--- | 116 | ---help--- |
117 | The ARM Firmware Suite allows the user to divide flash devices into | 117 | The ARM Firmware Suite allows the user to divide flash devices into |
118 | multiple 'images'. Each such image has a header containing its name | 118 | multiple 'images'. Each such image has a header containing its name |
diff --git a/drivers/mtd/afs.c b/drivers/mtd/afs.c index 96a33e3f7b00..d61b7edfc938 100644 --- a/drivers/mtd/afs.c +++ b/drivers/mtd/afs.c | |||
@@ -34,7 +34,9 @@ | |||
34 | #include <linux/mtd/map.h> | 34 | #include <linux/mtd/map.h> |
35 | #include <linux/mtd/partitions.h> | 35 | #include <linux/mtd/partitions.h> |
36 | 36 | ||
37 | struct footer_struct { | 37 | #define AFSV1_FOOTER_MAGIC 0xA0FFFF9F |
38 | |||
39 | struct footer_v1 { | ||
38 | u32 image_info_base; /* Address of first word of ImageFooter */ | 40 | u32 image_info_base; /* Address of first word of ImageFooter */ |
39 | u32 image_start; /* Start of area reserved by this footer */ | 41 | u32 image_start; /* Start of area reserved by this footer */ |
40 | u32 signature; /* 'Magic' number proves it's a footer */ | 42 | u32 signature; /* 'Magic' number proves it's a footer */ |
@@ -42,7 +44,7 @@ struct footer_struct { | |||
42 | u32 checksum; /* Just this structure */ | 44 | u32 checksum; /* Just this structure */ |
43 | }; | 45 | }; |
44 | 46 | ||
45 | struct image_info_struct { | 47 | struct image_info_v1 { |
46 | u32 bootFlags; /* Boot flags, compression etc. */ | 48 | u32 bootFlags; /* Boot flags, compression etc. */ |
47 | u32 imageNumber; /* Unique number, selects for boot etc. */ | 49 | u32 imageNumber; /* Unique number, selects for boot etc. */ |
48 | u32 loadAddress; /* Address program should be loaded to */ | 50 | u32 loadAddress; /* Address program should be loaded to */ |
@@ -67,10 +69,10 @@ static u32 word_sum(void *words, int num) | |||
67 | } | 69 | } |
68 | 70 | ||
69 | static int | 71 | static int |
70 | afs_read_footer(struct mtd_info *mtd, u_int *img_start, u_int *iis_start, | 72 | afs_read_footer_v1(struct mtd_info *mtd, u_int *img_start, u_int *iis_start, |
71 | u_int off, u_int mask) | 73 | u_int off, u_int mask) |
72 | { | 74 | { |
73 | struct footer_struct fs; | 75 | struct footer_v1 fs; |
74 | u_int ptr = off + mtd->erasesize - sizeof(fs); | 76 | u_int ptr = off + mtd->erasesize - sizeof(fs); |
75 | size_t sz; | 77 | size_t sz; |
76 | int ret; | 78 | int ret; |
@@ -85,25 +87,23 @@ afs_read_footer(struct mtd_info *mtd, u_int *img_start, u_int *iis_start, | |||
85 | return ret; | 87 | return ret; |
86 | } | 88 | } |
87 | 89 | ||
88 | ret = 1; | ||
89 | |||
90 | /* | 90 | /* |
91 | * Does it contain the magic number? | 91 | * Does it contain the magic number? |
92 | */ | 92 | */ |
93 | if (fs.signature != 0xa0ffff9f) | 93 | if (fs.signature != AFSV1_FOOTER_MAGIC) |
94 | ret = 0; | 94 | return 0; |
95 | 95 | ||
96 | /* | 96 | /* |
97 | * Check the checksum. | 97 | * Check the checksum. |
98 | */ | 98 | */ |
99 | if (word_sum(&fs, sizeof(fs) / sizeof(u32)) != 0xffffffff) | 99 | if (word_sum(&fs, sizeof(fs) / sizeof(u32)) != 0xffffffff) |
100 | ret = 0; | 100 | return 0; |
101 | 101 | ||
102 | /* | 102 | /* |
103 | * Don't touch the SIB. | 103 | * Don't touch the SIB. |
104 | */ | 104 | */ |
105 | if (fs.type == 2) | 105 | if (fs.type == 2) |
106 | ret = 0; | 106 | return 0; |
107 | 107 | ||
108 | *iis_start = fs.image_info_base & mask; | 108 | *iis_start = fs.image_info_base & mask; |
109 | *img_start = fs.image_start & mask; | 109 | *img_start = fs.image_start & mask; |
@@ -113,20 +113,20 @@ afs_read_footer(struct mtd_info *mtd, u_int *img_start, u_int *iis_start, | |||
113 | * be located after the footer structure. | 113 | * be located after the footer structure. |
114 | */ | 114 | */ |
115 | if (*iis_start >= ptr) | 115 | if (*iis_start >= ptr) |
116 | ret = 0; | 116 | return 0; |
117 | 117 | ||
118 | /* | 118 | /* |
119 | * Check the start of this image. The image | 119 | * Check the start of this image. The image |
120 | * data can not be located after this block. | 120 | * data can not be located after this block. |
121 | */ | 121 | */ |
122 | if (*img_start > off) | 122 | if (*img_start > off) |
123 | ret = 0; | 123 | return 0; |
124 | 124 | ||
125 | return ret; | 125 | return 1; |
126 | } | 126 | } |
127 | 127 | ||
128 | static int | 128 | static int |
129 | afs_read_iis(struct mtd_info *mtd, struct image_info_struct *iis, u_int ptr) | 129 | afs_read_iis_v1(struct mtd_info *mtd, struct image_info_v1 *iis, u_int ptr) |
130 | { | 130 | { |
131 | size_t sz; | 131 | size_t sz; |
132 | int ret, i; | 132 | int ret, i; |
@@ -162,7 +162,7 @@ afs_read_iis(struct mtd_info *mtd, struct image_info_struct *iis, u_int ptr) | |||
162 | } | 162 | } |
163 | 163 | ||
164 | static int parse_afs_partitions(struct mtd_info *mtd, | 164 | static int parse_afs_partitions(struct mtd_info *mtd, |
165 | struct mtd_partition **pparts, | 165 | const struct mtd_partition **pparts, |
166 | struct mtd_part_parser_data *data) | 166 | struct mtd_part_parser_data *data) |
167 | { | 167 | { |
168 | struct mtd_partition *parts; | 168 | struct mtd_partition *parts; |
@@ -182,24 +182,23 @@ static int parse_afs_partitions(struct mtd_info *mtd, | |||
182 | * the strings. | 182 | * the strings. |
183 | */ | 183 | */ |
184 | for (idx = off = sz = 0; off < mtd->size; off += mtd->erasesize) { | 184 | for (idx = off = sz = 0; off < mtd->size; off += mtd->erasesize) { |
185 | struct image_info_struct iis; | 185 | struct image_info_v1 iis; |
186 | u_int iis_ptr, img_ptr; | 186 | u_int iis_ptr, img_ptr; |
187 | 187 | ||
188 | ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask); | 188 | ret = afs_read_footer_v1(mtd, &img_ptr, &iis_ptr, off, mask); |
189 | if (ret < 0) | ||
190 | break; | ||
191 | if (ret == 0) | ||
192 | continue; | ||
193 | |||
194 | ret = afs_read_iis(mtd, &iis, iis_ptr); | ||
195 | if (ret < 0) | 189 | if (ret < 0) |
196 | break; | 190 | break; |
197 | if (ret == 0) | 191 | if (ret) { |
198 | continue; | 192 | ret = afs_read_iis_v1(mtd, &iis, iis_ptr); |
199 | 193 | if (ret < 0) | |
200 | sz += sizeof(struct mtd_partition); | 194 | break; |
201 | sz += strlen(iis.name) + 1; | 195 | if (ret == 0) |
202 | idx += 1; | 196 | continue; |
197 | |||
198 | sz += sizeof(struct mtd_partition); | ||
199 | sz += strlen(iis.name) + 1; | ||
200 | idx += 1; | ||
201 | } | ||
203 | } | 202 | } |
204 | 203 | ||
205 | if (!sz) | 204 | if (!sz) |
@@ -215,18 +214,18 @@ static int parse_afs_partitions(struct mtd_info *mtd, | |||
215 | * Identify the partitions | 214 | * Identify the partitions |
216 | */ | 215 | */ |
217 | for (idx = off = 0; off < mtd->size; off += mtd->erasesize) { | 216 | for (idx = off = 0; off < mtd->size; off += mtd->erasesize) { |
218 | struct image_info_struct iis; | 217 | struct image_info_v1 iis; |
219 | u_int iis_ptr, img_ptr; | 218 | u_int iis_ptr, img_ptr; |
220 | 219 | ||
221 | /* Read the footer. */ | 220 | /* Read the footer. */ |
222 | ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask); | 221 | ret = afs_read_footer_v1(mtd, &img_ptr, &iis_ptr, off, mask); |
223 | if (ret < 0) | 222 | if (ret < 0) |
224 | break; | 223 | break; |
225 | if (ret == 0) | 224 | if (ret == 0) |
226 | continue; | 225 | continue; |
227 | 226 | ||
228 | /* Read the image info block */ | 227 | /* Read the image info block */ |
229 | ret = afs_read_iis(mtd, &iis, iis_ptr); | 228 | ret = afs_read_iis_v1(mtd, &iis, iis_ptr); |
230 | if (ret < 0) | 229 | if (ret < 0) |
231 | break; | 230 | break; |
232 | if (ret == 0) | 231 | if (ret == 0) |
@@ -257,25 +256,10 @@ static int parse_afs_partitions(struct mtd_info *mtd, | |||
257 | } | 256 | } |
258 | 257 | ||
259 | static struct mtd_part_parser afs_parser = { | 258 | static struct mtd_part_parser afs_parser = { |
260 | .owner = THIS_MODULE, | ||
261 | .parse_fn = parse_afs_partitions, | 259 | .parse_fn = parse_afs_partitions, |
262 | .name = "afs", | 260 | .name = "afs", |
263 | }; | 261 | }; |
264 | 262 | module_mtd_part_parser(afs_parser); | |
265 | static int __init afs_parser_init(void) | ||
266 | { | ||
267 | register_mtd_parser(&afs_parser); | ||
268 | return 0; | ||
269 | } | ||
270 | |||
271 | static void __exit afs_parser_exit(void) | ||
272 | { | ||
273 | deregister_mtd_parser(&afs_parser); | ||
274 | } | ||
275 | |||
276 | module_init(afs_parser_init); | ||
277 | module_exit(afs_parser_exit); | ||
278 | |||
279 | 263 | ||
280 | MODULE_AUTHOR("ARM Ltd"); | 264 | MODULE_AUTHOR("ARM Ltd"); |
281 | MODULE_DESCRIPTION("ARM Firmware Suite partition parser"); | 265 | MODULE_DESCRIPTION("ARM Firmware Suite partition parser"); |
diff --git a/drivers/mtd/ar7part.c b/drivers/mtd/ar7part.c index 7c9172ad2621..90575deff0ae 100644 --- a/drivers/mtd/ar7part.c +++ b/drivers/mtd/ar7part.c | |||
@@ -43,7 +43,7 @@ struct ar7_bin_rec { | |||
43 | }; | 43 | }; |
44 | 44 | ||
45 | static int create_mtd_partitions(struct mtd_info *master, | 45 | static int create_mtd_partitions(struct mtd_info *master, |
46 | struct mtd_partition **pparts, | 46 | const struct mtd_partition **pparts, |
47 | struct mtd_part_parser_data *data) | 47 | struct mtd_part_parser_data *data) |
48 | { | 48 | { |
49 | struct ar7_bin_rec header; | 49 | struct ar7_bin_rec header; |
@@ -132,24 +132,10 @@ static int create_mtd_partitions(struct mtd_info *master, | |||
132 | } | 132 | } |
133 | 133 | ||
134 | static struct mtd_part_parser ar7_parser = { | 134 | static struct mtd_part_parser ar7_parser = { |
135 | .owner = THIS_MODULE, | ||
136 | .parse_fn = create_mtd_partitions, | 135 | .parse_fn = create_mtd_partitions, |
137 | .name = "ar7part", | 136 | .name = "ar7part", |
138 | }; | 137 | }; |
139 | 138 | module_mtd_part_parser(ar7_parser); | |
140 | static int __init ar7_parser_init(void) | ||
141 | { | ||
142 | register_mtd_parser(&ar7_parser); | ||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | static void __exit ar7_parser_exit(void) | ||
147 | { | ||
148 | deregister_mtd_parser(&ar7_parser); | ||
149 | } | ||
150 | |||
151 | module_init(ar7_parser_init); | ||
152 | module_exit(ar7_parser_exit); | ||
153 | 139 | ||
154 | MODULE_LICENSE("GPL"); | 140 | MODULE_LICENSE("GPL"); |
155 | MODULE_AUTHOR( "Felix Fietkau <nbd@openwrt.org>, " | 141 | MODULE_AUTHOR( "Felix Fietkau <nbd@openwrt.org>, " |
diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c index c0720c1ee4c9..8282f47bcf5d 100644 --- a/drivers/mtd/bcm47xxpart.c +++ b/drivers/mtd/bcm47xxpart.c | |||
@@ -82,7 +82,7 @@ out_default: | |||
82 | } | 82 | } |
83 | 83 | ||
84 | static int bcm47xxpart_parse(struct mtd_info *master, | 84 | static int bcm47xxpart_parse(struct mtd_info *master, |
85 | struct mtd_partition **pparts, | 85 | const struct mtd_partition **pparts, |
86 | struct mtd_part_parser_data *data) | 86 | struct mtd_part_parser_data *data) |
87 | { | 87 | { |
88 | struct mtd_partition *parts; | 88 | struct mtd_partition *parts; |
@@ -313,24 +313,10 @@ static int bcm47xxpart_parse(struct mtd_info *master, | |||
313 | }; | 313 | }; |
314 | 314 | ||
315 | static struct mtd_part_parser bcm47xxpart_mtd_parser = { | 315 | static struct mtd_part_parser bcm47xxpart_mtd_parser = { |
316 | .owner = THIS_MODULE, | ||
317 | .parse_fn = bcm47xxpart_parse, | 316 | .parse_fn = bcm47xxpart_parse, |
318 | .name = "bcm47xxpart", | 317 | .name = "bcm47xxpart", |
319 | }; | 318 | }; |
320 | 319 | module_mtd_part_parser(bcm47xxpart_mtd_parser); | |
321 | static int __init bcm47xxpart_init(void) | ||
322 | { | ||
323 | register_mtd_parser(&bcm47xxpart_mtd_parser); | ||
324 | return 0; | ||
325 | } | ||
326 | |||
327 | static void __exit bcm47xxpart_exit(void) | ||
328 | { | ||
329 | deregister_mtd_parser(&bcm47xxpart_mtd_parser); | ||
330 | } | ||
331 | |||
332 | module_init(bcm47xxpart_init); | ||
333 | module_exit(bcm47xxpart_exit); | ||
334 | 320 | ||
335 | MODULE_LICENSE("GPL"); | 321 | MODULE_LICENSE("GPL"); |
336 | MODULE_DESCRIPTION("MTD partitioning for BCM47XX flash memories"); | 322 | MODULE_DESCRIPTION("MTD partitioning for BCM47XX flash memories"); |
diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c index b2443f7031c9..440936998593 100644 --- a/drivers/mtd/bcm63xxpart.c +++ b/drivers/mtd/bcm63xxpart.c | |||
@@ -68,7 +68,7 @@ static int bcm63xx_detect_cfe(struct mtd_info *master) | |||
68 | } | 68 | } |
69 | 69 | ||
70 | static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, | 70 | static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, |
71 | struct mtd_partition **pparts, | 71 | const struct mtd_partition **pparts, |
72 | struct mtd_part_parser_data *data) | 72 | struct mtd_part_parser_data *data) |
73 | { | 73 | { |
74 | /* CFE, NVRAM and global Linux are always present */ | 74 | /* CFE, NVRAM and global Linux are always present */ |
@@ -214,24 +214,10 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, | |||
214 | }; | 214 | }; |
215 | 215 | ||
216 | static struct mtd_part_parser bcm63xx_cfe_parser = { | 216 | static struct mtd_part_parser bcm63xx_cfe_parser = { |
217 | .owner = THIS_MODULE, | ||
218 | .parse_fn = bcm63xx_parse_cfe_partitions, | 217 | .parse_fn = bcm63xx_parse_cfe_partitions, |
219 | .name = "bcm63xxpart", | 218 | .name = "bcm63xxpart", |
220 | }; | 219 | }; |
221 | 220 | module_mtd_part_parser(bcm63xx_cfe_parser); | |
222 | static int __init bcm63xx_cfe_parser_init(void) | ||
223 | { | ||
224 | register_mtd_parser(&bcm63xx_cfe_parser); | ||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | static void __exit bcm63xx_cfe_parser_exit(void) | ||
229 | { | ||
230 | deregister_mtd_parser(&bcm63xx_cfe_parser); | ||
231 | } | ||
232 | |||
233 | module_init(bcm63xx_cfe_parser_init); | ||
234 | module_exit(bcm63xx_cfe_parser_exit); | ||
235 | 221 | ||
236 | MODULE_LICENSE("GPL"); | 222 | MODULE_LICENSE("GPL"); |
237 | MODULE_AUTHOR("Daniel Dickinson <openwrt@cshore.neomailbox.net>"); | 223 | MODULE_AUTHOR("Daniel Dickinson <openwrt@cshore.neomailbox.net>"); |
diff --git a/drivers/mtd/chips/Kconfig b/drivers/mtd/chips/Kconfig index 54479c481a7a..3b3dabce58de 100644 --- a/drivers/mtd/chips/Kconfig +++ b/drivers/mtd/chips/Kconfig | |||
@@ -67,6 +67,10 @@ endchoice | |||
67 | config MTD_CFI_GEOMETRY | 67 | config MTD_CFI_GEOMETRY |
68 | bool "Specific CFI Flash geometry selection" | 68 | bool "Specific CFI Flash geometry selection" |
69 | depends on MTD_CFI_ADV_OPTIONS | 69 | depends on MTD_CFI_ADV_OPTIONS |
70 | select MTD_MAP_BANK_WIDTH_1 if !(MTD_MAP_BANK_WIDTH_2 || \ | ||
71 | MTD_MAP_BANK_WIDTH_4 || MTD_MAP_BANK_WIDTH_8 || \ | ||
72 | MTD_MAP_BANK_WIDTH_16 || MTD_MAP_BANK_WIDTH_32) | ||
73 | select MTD_CFI_I1 if !(MTD_CFI_I2 || MTD_CFI_I4 || MTD_CFI_I8) | ||
70 | help | 74 | help |
71 | This option does not affect the code directly, but will enable | 75 | This option does not affect the code directly, but will enable |
72 | some other configuration options which would allow you to reduce | 76 | some other configuration options which would allow you to reduce |
diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 286b97a304cf..5e1b68cbcd0a 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c | |||
@@ -596,7 +596,7 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd) | |||
596 | mtd->size = devsize * cfi->numchips; | 596 | mtd->size = devsize * cfi->numchips; |
597 | 597 | ||
598 | mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; | 598 | mtd->numeraseregions = cfi->cfiq->NumEraseRegions * cfi->numchips; |
599 | mtd->eraseregions = kmalloc(sizeof(struct mtd_erase_region_info) | 599 | mtd->eraseregions = kzalloc(sizeof(struct mtd_erase_region_info) |
600 | * mtd->numeraseregions, GFP_KERNEL); | 600 | * mtd->numeraseregions, GFP_KERNEL); |
601 | if (!mtd->eraseregions) | 601 | if (!mtd->eraseregions) |
602 | goto setup_err; | 602 | goto setup_err; |
@@ -614,6 +614,8 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd) | |||
614 | mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize = ersize; | 614 | mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].erasesize = ersize; |
615 | mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks = ernum; | 615 | mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].numblocks = ernum; |
616 | mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].lockmap = kmalloc(ernum / 8 + 1, GFP_KERNEL); | 616 | mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].lockmap = kmalloc(ernum / 8 + 1, GFP_KERNEL); |
617 | if (!mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].lockmap) | ||
618 | goto setup_err; | ||
617 | } | 619 | } |
618 | offset += (ersize * ernum); | 620 | offset += (ersize * ernum); |
619 | } | 621 | } |
@@ -650,6 +652,10 @@ static struct mtd_info *cfi_intelext_setup(struct mtd_info *mtd) | |||
650 | return mtd; | 652 | return mtd; |
651 | 653 | ||
652 | setup_err: | 654 | setup_err: |
655 | if (mtd->eraseregions) | ||
656 | for (i=0; i<cfi->cfiq->NumEraseRegions; i++) | ||
657 | for (j=0; j<cfi->numchips; j++) | ||
658 | kfree(mtd->eraseregions[(j*cfi->cfiq->NumEraseRegions)+i].lockmap); | ||
653 | kfree(mtd->eraseregions); | 659 | kfree(mtd->eraseregions); |
654 | kfree(mtd); | 660 | kfree(mtd); |
655 | kfree(cfi->cmdset_priv); | 661 | kfree(cfi->cmdset_priv); |
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index c3624eb571d1..9dca881bb378 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c | |||
@@ -615,11 +615,9 @@ struct mtd_info *cfi_cmdset_0002(struct map_info *map, int primary) | |||
615 | 615 | ||
616 | for (i=0; i<cfi->cfiq->NumEraseRegions / 2; i++) { | 616 | for (i=0; i<cfi->cfiq->NumEraseRegions / 2; i++) { |
617 | int j = (cfi->cfiq->NumEraseRegions-1)-i; | 617 | int j = (cfi->cfiq->NumEraseRegions-1)-i; |
618 | __u32 swap; | ||
619 | 618 | ||
620 | swap = cfi->cfiq->EraseRegionInfo[i]; | 619 | swap(cfi->cfiq->EraseRegionInfo[i], |
621 | cfi->cfiq->EraseRegionInfo[i] = cfi->cfiq->EraseRegionInfo[j]; | 620 | cfi->cfiq->EraseRegionInfo[j]); |
622 | cfi->cfiq->EraseRegionInfo[j] = swap; | ||
623 | } | 621 | } |
624 | } | 622 | } |
625 | /* Set the default CFI lock/unlock addresses */ | 623 | /* Set the default CFI lock/unlock addresses */ |
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c index 08f62987cc37..fbd5affc0acf 100644 --- a/drivers/mtd/cmdlinepart.c +++ b/drivers/mtd/cmdlinepart.c | |||
@@ -304,7 +304,7 @@ static int mtdpart_setup_real(char *s) | |||
304 | * the first one in the chain if a NULL mtd_id is passed in. | 304 | * the first one in the chain if a NULL mtd_id is passed in. |
305 | */ | 305 | */ |
306 | static int parse_cmdline_partitions(struct mtd_info *master, | 306 | static int parse_cmdline_partitions(struct mtd_info *master, |
307 | struct mtd_partition **pparts, | 307 | const struct mtd_partition **pparts, |
308 | struct mtd_part_parser_data *data) | 308 | struct mtd_part_parser_data *data) |
309 | { | 309 | { |
310 | unsigned long long offset; | 310 | unsigned long long offset; |
@@ -382,7 +382,6 @@ static int __init mtdpart_setup(char *s) | |||
382 | __setup("mtdparts=", mtdpart_setup); | 382 | __setup("mtdparts=", mtdpart_setup); |
383 | 383 | ||
384 | static struct mtd_part_parser cmdline_parser = { | 384 | static struct mtd_part_parser cmdline_parser = { |
385 | .owner = THIS_MODULE, | ||
386 | .parse_fn = parse_cmdline_partitions, | 385 | .parse_fn = parse_cmdline_partitions, |
387 | .name = "cmdlinepart", | 386 | .name = "cmdlinepart", |
388 | }; | 387 | }; |
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index fe9ceb7b5405..c9c3b7fa3051 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c | |||
@@ -152,22 +152,6 @@ static int m25p80_read(struct spi_nor *nor, loff_t from, size_t len, | |||
152 | return 0; | 152 | return 0; |
153 | } | 153 | } |
154 | 154 | ||
155 | static int m25p80_erase(struct spi_nor *nor, loff_t offset) | ||
156 | { | ||
157 | struct m25p *flash = nor->priv; | ||
158 | |||
159 | dev_dbg(nor->dev, "%dKiB at 0x%08x\n", | ||
160 | flash->spi_nor.mtd.erasesize / 1024, (u32)offset); | ||
161 | |||
162 | /* Set up command buffer. */ | ||
163 | flash->command[0] = nor->erase_opcode; | ||
164 | m25p_addr2cmd(nor, offset, flash->command); | ||
165 | |||
166 | spi_write(flash->spi, flash->command, m25p_cmdsz(nor)); | ||
167 | |||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | /* | 155 | /* |
172 | * board specific setup should have ensured the SPI clock used here | 156 | * board specific setup should have ensured the SPI clock used here |
173 | * matches what the READ command supports, at least until this driver | 157 | * matches what the READ command supports, at least until this driver |
@@ -175,12 +159,11 @@ static int m25p80_erase(struct spi_nor *nor, loff_t offset) | |||
175 | */ | 159 | */ |
176 | static int m25p_probe(struct spi_device *spi) | 160 | static int m25p_probe(struct spi_device *spi) |
177 | { | 161 | { |
178 | struct mtd_part_parser_data ppdata; | ||
179 | struct flash_platform_data *data; | 162 | struct flash_platform_data *data; |
180 | struct m25p *flash; | 163 | struct m25p *flash; |
181 | struct spi_nor *nor; | 164 | struct spi_nor *nor; |
182 | enum read_mode mode = SPI_NOR_NORMAL; | 165 | enum read_mode mode = SPI_NOR_NORMAL; |
183 | char *flash_name = NULL; | 166 | char *flash_name; |
184 | int ret; | 167 | int ret; |
185 | 168 | ||
186 | data = dev_get_platdata(&spi->dev); | 169 | data = dev_get_platdata(&spi->dev); |
@@ -194,12 +177,11 @@ static int m25p_probe(struct spi_device *spi) | |||
194 | /* install the hooks */ | 177 | /* install the hooks */ |
195 | nor->read = m25p80_read; | 178 | nor->read = m25p80_read; |
196 | nor->write = m25p80_write; | 179 | nor->write = m25p80_write; |
197 | nor->erase = m25p80_erase; | ||
198 | nor->write_reg = m25p80_write_reg; | 180 | nor->write_reg = m25p80_write_reg; |
199 | nor->read_reg = m25p80_read_reg; | 181 | nor->read_reg = m25p80_read_reg; |
200 | 182 | ||
201 | nor->dev = &spi->dev; | 183 | nor->dev = &spi->dev; |
202 | nor->flash_node = spi->dev.of_node; | 184 | spi_nor_set_flash_node(nor, spi->dev.of_node); |
203 | nor->priv = flash; | 185 | nor->priv = flash; |
204 | 186 | ||
205 | spi_set_drvdata(spi, flash); | 187 | spi_set_drvdata(spi, flash); |
@@ -220,6 +202,8 @@ static int m25p_probe(struct spi_device *spi) | |||
220 | */ | 202 | */ |
221 | if (data && data->type) | 203 | if (data && data->type) |
222 | flash_name = data->type; | 204 | flash_name = data->type; |
205 | else if (!strcmp(spi->modalias, "spi-nor")) | ||
206 | flash_name = NULL; /* auto-detect */ | ||
223 | else | 207 | else |
224 | flash_name = spi->modalias; | 208 | flash_name = spi->modalias; |
225 | 209 | ||
@@ -227,11 +211,8 @@ static int m25p_probe(struct spi_device *spi) | |||
227 | if (ret) | 211 | if (ret) |
228 | return ret; | 212 | return ret; |
229 | 213 | ||
230 | ppdata.of_node = spi->dev.of_node; | 214 | return mtd_device_register(&nor->mtd, data ? data->parts : NULL, |
231 | 215 | data ? data->nr_parts : 0); | |
232 | return mtd_device_parse_register(&nor->mtd, NULL, &ppdata, | ||
233 | data ? data->parts : NULL, | ||
234 | data ? data->nr_parts : 0); | ||
235 | } | 216 | } |
236 | 217 | ||
237 | 218 | ||
@@ -257,14 +238,21 @@ static int m25p_remove(struct spi_device *spi) | |||
257 | */ | 238 | */ |
258 | static const struct spi_device_id m25p_ids[] = { | 239 | static const struct spi_device_id m25p_ids[] = { |
259 | /* | 240 | /* |
241 | * Allow non-DT platform devices to bind to the "spi-nor" modalias, and | ||
242 | * hack around the fact that the SPI core does not provide uevent | ||
243 | * matching for .of_match_table | ||
244 | */ | ||
245 | {"spi-nor"}, | ||
246 | |||
247 | /* | ||
260 | * Entries not used in DTs that should be safe to drop after replacing | 248 | * Entries not used in DTs that should be safe to drop after replacing |
261 | * them with "nor-jedec" in platform data. | 249 | * them with "spi-nor" in platform data. |
262 | */ | 250 | */ |
263 | {"s25sl064a"}, {"w25x16"}, {"m25p10"}, {"m25px64"}, | 251 | {"s25sl064a"}, {"w25x16"}, {"m25p10"}, {"m25px64"}, |
264 | 252 | ||
265 | /* | 253 | /* |
266 | * Entries that were used in DTs without "nor-jedec" fallback and should | 254 | * Entries that were used in DTs without "jedec,spi-nor" fallback and |
267 | * be kept for backward compatibility. | 255 | * should be kept for backward compatibility. |
268 | */ | 256 | */ |
269 | {"at25df321a"}, {"at25df641"}, {"at26df081a"}, | 257 | {"at25df321a"}, {"at25df641"}, {"at26df081a"}, |
270 | {"mr25h256"}, | 258 | {"mr25h256"}, |
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index e4a88715a844..f9e9bd1cfaa0 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c | |||
@@ -624,7 +624,6 @@ static int add_dataflash_otp(struct spi_device *spi, char *name, int nr_pages, | |||
624 | { | 624 | { |
625 | struct dataflash *priv; | 625 | struct dataflash *priv; |
626 | struct mtd_info *device; | 626 | struct mtd_info *device; |
627 | struct mtd_part_parser_data ppdata; | ||
628 | struct flash_platform_data *pdata = dev_get_platdata(&spi->dev); | 627 | struct flash_platform_data *pdata = dev_get_platdata(&spi->dev); |
629 | char *otp_tag = ""; | 628 | char *otp_tag = ""; |
630 | int err = 0; | 629 | int err = 0; |
@@ -656,6 +655,7 @@ static int add_dataflash_otp(struct spi_device *spi, char *name, int nr_pages, | |||
656 | device->priv = priv; | 655 | device->priv = priv; |
657 | 656 | ||
658 | device->dev.parent = &spi->dev; | 657 | device->dev.parent = &spi->dev; |
658 | mtd_set_of_node(device, spi->dev.of_node); | ||
659 | 659 | ||
660 | if (revision >= 'c') | 660 | if (revision >= 'c') |
661 | otp_tag = otp_setup(device, revision); | 661 | otp_tag = otp_setup(device, revision); |
@@ -665,8 +665,7 @@ static int add_dataflash_otp(struct spi_device *spi, char *name, int nr_pages, | |||
665 | pagesize, otp_tag); | 665 | pagesize, otp_tag); |
666 | spi_set_drvdata(spi, priv); | 666 | spi_set_drvdata(spi, priv); |
667 | 667 | ||
668 | ppdata.of_node = spi->dev.of_node; | 668 | err = mtd_device_register(device, |
669 | err = mtd_device_parse_register(device, NULL, &ppdata, | ||
670 | pdata ? pdata->parts : NULL, | 669 | pdata ? pdata->parts : NULL, |
671 | pdata ? pdata->nr_parts : 0); | 670 | pdata ? pdata->nr_parts : 0); |
672 | 671 | ||
diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c index 64c7458344d4..dd5069876537 100644 --- a/drivers/mtd/devices/spear_smi.c +++ b/drivers/mtd/devices/spear_smi.c | |||
@@ -810,7 +810,6 @@ static int spear_smi_setup_banks(struct platform_device *pdev, | |||
810 | u32 bank, struct device_node *np) | 810 | u32 bank, struct device_node *np) |
811 | { | 811 | { |
812 | struct spear_smi *dev = platform_get_drvdata(pdev); | 812 | struct spear_smi *dev = platform_get_drvdata(pdev); |
813 | struct mtd_part_parser_data ppdata = {}; | ||
814 | struct spear_smi_flash_info *flash_info; | 813 | struct spear_smi_flash_info *flash_info; |
815 | struct spear_smi_plat_data *pdata; | 814 | struct spear_smi_plat_data *pdata; |
816 | struct spear_snor_flash *flash; | 815 | struct spear_snor_flash *flash; |
@@ -855,6 +854,7 @@ static int spear_smi_setup_banks(struct platform_device *pdev, | |||
855 | flash->mtd.name = flash_devices[flash_index].name; | 854 | flash->mtd.name = flash_devices[flash_index].name; |
856 | 855 | ||
857 | flash->mtd.dev.parent = &pdev->dev; | 856 | flash->mtd.dev.parent = &pdev->dev; |
857 | mtd_set_of_node(&flash->mtd, np); | ||
858 | flash->mtd.type = MTD_NORFLASH; | 858 | flash->mtd.type = MTD_NORFLASH; |
859 | flash->mtd.writesize = 1; | 859 | flash->mtd.writesize = 1; |
860 | flash->mtd.flags = MTD_CAP_NORFLASH; | 860 | flash->mtd.flags = MTD_CAP_NORFLASH; |
@@ -881,10 +881,8 @@ static int spear_smi_setup_banks(struct platform_device *pdev, | |||
881 | count = flash_info->nr_partitions; | 881 | count = flash_info->nr_partitions; |
882 | } | 882 | } |
883 | #endif | 883 | #endif |
884 | ppdata.of_node = np; | ||
885 | 884 | ||
886 | ret = mtd_device_parse_register(&flash->mtd, NULL, &ppdata, parts, | 885 | ret = mtd_device_register(&flash->mtd, parts, count); |
887 | count); | ||
888 | if (ret) { | 886 | if (ret) { |
889 | dev_err(&dev->pdev->dev, "Err MTD partition=%d\n", ret); | 887 | dev_err(&dev->pdev->dev, "Err MTD partition=%d\n", ret); |
890 | return ret; | 888 | return ret; |
diff --git a/drivers/mtd/devices/st_spi_fsm.c b/drivers/mtd/devices/st_spi_fsm.c index 3060025c8af4..5454b4113589 100644 --- a/drivers/mtd/devices/st_spi_fsm.c +++ b/drivers/mtd/devices/st_spi_fsm.c | |||
@@ -2025,7 +2025,6 @@ boot_device_fail: | |||
2025 | static int stfsm_probe(struct platform_device *pdev) | 2025 | static int stfsm_probe(struct platform_device *pdev) |
2026 | { | 2026 | { |
2027 | struct device_node *np = pdev->dev.of_node; | 2027 | struct device_node *np = pdev->dev.of_node; |
2028 | struct mtd_part_parser_data ppdata; | ||
2029 | struct flash_info *info; | 2028 | struct flash_info *info; |
2030 | struct resource *res; | 2029 | struct resource *res; |
2031 | struct stfsm *fsm; | 2030 | struct stfsm *fsm; |
@@ -2035,7 +2034,6 @@ static int stfsm_probe(struct platform_device *pdev) | |||
2035 | dev_err(&pdev->dev, "No DT found\n"); | 2034 | dev_err(&pdev->dev, "No DT found\n"); |
2036 | return -EINVAL; | 2035 | return -EINVAL; |
2037 | } | 2036 | } |
2038 | ppdata.of_node = np; | ||
2039 | 2037 | ||
2040 | fsm = devm_kzalloc(&pdev->dev, sizeof(*fsm), GFP_KERNEL); | 2038 | fsm = devm_kzalloc(&pdev->dev, sizeof(*fsm), GFP_KERNEL); |
2041 | if (!fsm) | 2039 | if (!fsm) |
@@ -2106,6 +2104,7 @@ static int stfsm_probe(struct platform_device *pdev) | |||
2106 | 2104 | ||
2107 | fsm->mtd.name = info->name; | 2105 | fsm->mtd.name = info->name; |
2108 | fsm->mtd.dev.parent = &pdev->dev; | 2106 | fsm->mtd.dev.parent = &pdev->dev; |
2107 | mtd_set_of_node(&fsm->mtd, np); | ||
2109 | fsm->mtd.type = MTD_NORFLASH; | 2108 | fsm->mtd.type = MTD_NORFLASH; |
2110 | fsm->mtd.writesize = 4; | 2109 | fsm->mtd.writesize = 4; |
2111 | fsm->mtd.writebufsize = fsm->mtd.writesize; | 2110 | fsm->mtd.writebufsize = fsm->mtd.writesize; |
@@ -2124,7 +2123,7 @@ static int stfsm_probe(struct platform_device *pdev) | |||
2124 | (long long)fsm->mtd.size, (long long)(fsm->mtd.size >> 20), | 2123 | (long long)fsm->mtd.size, (long long)(fsm->mtd.size >> 20), |
2125 | fsm->mtd.erasesize, (fsm->mtd.erasesize >> 10)); | 2124 | fsm->mtd.erasesize, (fsm->mtd.erasesize >> 10)); |
2126 | 2125 | ||
2127 | return mtd_device_parse_register(&fsm->mtd, NULL, &ppdata, NULL, 0); | 2126 | return mtd_device_register(&fsm->mtd, NULL, 0); |
2128 | } | 2127 | } |
2129 | 2128 | ||
2130 | static int stfsm_remove(struct platform_device *pdev) | 2129 | static int stfsm_remove(struct platform_device *pdev) |
diff --git a/drivers/mtd/ftl.c b/drivers/mtd/ftl.c index dabf08450d0b..9fb3b0dcdac2 100644 --- a/drivers/mtd/ftl.c +++ b/drivers/mtd/ftl.c | |||
@@ -571,12 +571,8 @@ static int copy_erase_unit(partition_t *part, uint16_t srcunit, | |||
571 | 571 | ||
572 | 572 | ||
573 | /* Update the maps and usage stats*/ | 573 | /* Update the maps and usage stats*/ |
574 | i = xfer->EraseCount; | 574 | swap(xfer->EraseCount, eun->EraseCount); |
575 | xfer->EraseCount = eun->EraseCount; | 575 | swap(xfer->Offset, eun->Offset); |
576 | eun->EraseCount = i; | ||
577 | i = xfer->Offset; | ||
578 | xfer->Offset = eun->Offset; | ||
579 | eun->Offset = i; | ||
580 | part->FreeTotal -= eun->Free; | 576 | part->FreeTotal -= eun->Free; |
581 | part->FreeTotal += free; | 577 | part->FreeTotal += free; |
582 | eun->Free = free; | 578 | eun->Free = free; |
diff --git a/drivers/mtd/maps/lantiq-flash.c b/drivers/mtd/maps/lantiq-flash.c index 93852054977e..c8febb326fa6 100644 --- a/drivers/mtd/maps/lantiq-flash.c +++ b/drivers/mtd/maps/lantiq-flash.c | |||
@@ -110,7 +110,6 @@ ltq_copy_to(struct map_info *map, unsigned long to, | |||
110 | static int | 110 | static int |
111 | ltq_mtd_probe(struct platform_device *pdev) | 111 | ltq_mtd_probe(struct platform_device *pdev) |
112 | { | 112 | { |
113 | struct mtd_part_parser_data ppdata; | ||
114 | struct ltq_mtd *ltq_mtd; | 113 | struct ltq_mtd *ltq_mtd; |
115 | struct cfi_private *cfi; | 114 | struct cfi_private *cfi; |
116 | int err; | 115 | int err; |
@@ -161,13 +160,13 @@ ltq_mtd_probe(struct platform_device *pdev) | |||
161 | } | 160 | } |
162 | 161 | ||
163 | ltq_mtd->mtd->dev.parent = &pdev->dev; | 162 | ltq_mtd->mtd->dev.parent = &pdev->dev; |
163 | mtd_set_of_node(ltq_mtd->mtd, pdev->dev.of_node); | ||
164 | 164 | ||
165 | cfi = ltq_mtd->map->fldrv_priv; | 165 | cfi = ltq_mtd->map->fldrv_priv; |
166 | cfi->addr_unlock1 ^= 1; | 166 | cfi->addr_unlock1 ^= 1; |
167 | cfi->addr_unlock2 ^= 1; | 167 | cfi->addr_unlock2 ^= 1; |
168 | 168 | ||
169 | ppdata.of_node = pdev->dev.of_node; | 169 | err = mtd_device_register(ltq_mtd->mtd, NULL, 0); |
170 | err = mtd_device_parse_register(ltq_mtd->mtd, NULL, &ppdata, NULL, 0); | ||
171 | if (err) { | 170 | if (err) { |
172 | dev_err(&pdev->dev, "failed to add partitions\n"); | 171 | dev_err(&pdev->dev, "failed to add partitions\n"); |
173 | goto err_destroy; | 172 | goto err_destroy; |
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index e46b4e983666..70c453144f00 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c | |||
@@ -166,7 +166,6 @@ static int of_flash_probe(struct platform_device *dev) | |||
166 | int reg_tuple_size; | 166 | int reg_tuple_size; |
167 | struct mtd_info **mtd_list = NULL; | 167 | struct mtd_info **mtd_list = NULL; |
168 | resource_size_t res_size; | 168 | resource_size_t res_size; |
169 | struct mtd_part_parser_data ppdata; | ||
170 | bool map_indirect; | 169 | bool map_indirect; |
171 | const char *mtd_name = NULL; | 170 | const char *mtd_name = NULL; |
172 | 171 | ||
@@ -310,13 +309,14 @@ static int of_flash_probe(struct platform_device *dev) | |||
310 | if (err) | 309 | if (err) |
311 | goto err_out; | 310 | goto err_out; |
312 | 311 | ||
313 | ppdata.of_node = dp; | 312 | info->cmtd->dev.parent = &dev->dev; |
313 | mtd_set_of_node(info->cmtd, dp); | ||
314 | part_probe_types = of_get_probes(dp); | 314 | part_probe_types = of_get_probes(dp); |
315 | if (!part_probe_types) { | 315 | if (!part_probe_types) { |
316 | err = -ENOMEM; | 316 | err = -ENOMEM; |
317 | goto err_out; | 317 | goto err_out; |
318 | } | 318 | } |
319 | mtd_device_parse_register(info->cmtd, part_probe_types, &ppdata, | 319 | mtd_device_parse_register(info->cmtd, part_probe_types, NULL, |
320 | NULL, 0); | 320 | NULL, 0); |
321 | of_free_probes(part_probe_types); | 321 | of_free_probes(part_probe_types); |
322 | 322 | ||
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index ffa288474820..309625130b21 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/err.h> | 32 | #include <linux/err.h> |
33 | #include <linux/ioctl.h> | 33 | #include <linux/ioctl.h> |
34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
35 | #include <linux/of.h> | ||
35 | #include <linux/proc_fs.h> | 36 | #include <linux/proc_fs.h> |
36 | #include <linux/idr.h> | 37 | #include <linux/idr.h> |
37 | #include <linux/backing-dev.h> | 38 | #include <linux/backing-dev.h> |
@@ -445,6 +446,7 @@ int add_mtd_device(struct mtd_info *mtd) | |||
445 | mtd->dev.devt = MTD_DEVT(i); | 446 | mtd->dev.devt = MTD_DEVT(i); |
446 | dev_set_name(&mtd->dev, "mtd%d", i); | 447 | dev_set_name(&mtd->dev, "mtd%d", i); |
447 | dev_set_drvdata(&mtd->dev, mtd); | 448 | dev_set_drvdata(&mtd->dev, mtd); |
449 | of_node_get(mtd_get_of_node(mtd)); | ||
448 | error = device_register(&mtd->dev); | 450 | error = device_register(&mtd->dev); |
449 | if (error) | 451 | if (error) |
450 | goto fail_added; | 452 | goto fail_added; |
@@ -467,6 +469,7 @@ int add_mtd_device(struct mtd_info *mtd) | |||
467 | return 0; | 469 | return 0; |
468 | 470 | ||
469 | fail_added: | 471 | fail_added: |
472 | of_node_put(mtd_get_of_node(mtd)); | ||
470 | idr_remove(&mtd_idr, i); | 473 | idr_remove(&mtd_idr, i); |
471 | fail_locked: | 474 | fail_locked: |
472 | mutex_unlock(&mtd_table_mutex); | 475 | mutex_unlock(&mtd_table_mutex); |
@@ -508,6 +511,7 @@ int del_mtd_device(struct mtd_info *mtd) | |||
508 | device_unregister(&mtd->dev); | 511 | device_unregister(&mtd->dev); |
509 | 512 | ||
510 | idr_remove(&mtd_idr, mtd->index); | 513 | idr_remove(&mtd_idr, mtd->index); |
514 | of_node_put(mtd_get_of_node(mtd)); | ||
511 | 515 | ||
512 | module_put(THIS_MODULE); | 516 | module_put(THIS_MODULE); |
513 | ret = 0; | 517 | ret = 0; |
@@ -519,9 +523,10 @@ out_error: | |||
519 | } | 523 | } |
520 | 524 | ||
521 | static int mtd_add_device_partitions(struct mtd_info *mtd, | 525 | static int mtd_add_device_partitions(struct mtd_info *mtd, |
522 | struct mtd_partition *real_parts, | 526 | struct mtd_partitions *parts) |
523 | int nbparts) | ||
524 | { | 527 | { |
528 | const struct mtd_partition *real_parts = parts->parts; | ||
529 | int nbparts = parts->nr_parts; | ||
525 | int ret; | 530 | int ret; |
526 | 531 | ||
527 | if (nbparts == 0 || IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) { | 532 | if (nbparts == 0 || IS_ENABLED(CONFIG_MTD_PARTITIONED_MASTER)) { |
@@ -590,29 +595,29 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, | |||
590 | const struct mtd_partition *parts, | 595 | const struct mtd_partition *parts, |
591 | int nr_parts) | 596 | int nr_parts) |
592 | { | 597 | { |
598 | struct mtd_partitions parsed; | ||
593 | int ret; | 599 | int ret; |
594 | struct mtd_partition *real_parts = NULL; | ||
595 | 600 | ||
596 | mtd_set_dev_defaults(mtd); | 601 | mtd_set_dev_defaults(mtd); |
597 | 602 | ||
598 | ret = parse_mtd_partitions(mtd, types, &real_parts, parser_data); | 603 | memset(&parsed, 0, sizeof(parsed)); |
599 | if (ret <= 0 && nr_parts && parts) { | 604 | |
600 | real_parts = kmemdup(parts, sizeof(*parts) * nr_parts, | 605 | ret = parse_mtd_partitions(mtd, types, &parsed, parser_data); |
601 | GFP_KERNEL); | 606 | if ((ret < 0 || parsed.nr_parts == 0) && parts && nr_parts) { |
602 | if (!real_parts) | 607 | /* Fall back to driver-provided partitions */ |
603 | ret = -ENOMEM; | 608 | parsed = (struct mtd_partitions){ |
604 | else | 609 | .parts = parts, |
605 | ret = nr_parts; | 610 | .nr_parts = nr_parts, |
606 | } | 611 | }; |
607 | /* Didn't come up with either parsed OR fallback partitions */ | 612 | } else if (ret < 0) { |
608 | if (ret < 0) { | 613 | /* Didn't come up with parsed OR fallback partitions */ |
609 | pr_info("mtd: failed to find partitions; one or more parsers reports errors (%d)\n", | 614 | pr_info("mtd: failed to find partitions; one or more parsers reports errors (%d)\n", |
610 | ret); | 615 | ret); |
611 | /* Don't abort on errors; we can still use unpartitioned MTD */ | 616 | /* Don't abort on errors; we can still use unpartitioned MTD */ |
612 | ret = 0; | 617 | memset(&parsed, 0, sizeof(parsed)); |
613 | } | 618 | } |
614 | 619 | ||
615 | ret = mtd_add_device_partitions(mtd, real_parts, ret); | 620 | ret = mtd_add_device_partitions(mtd, &parsed); |
616 | if (ret) | 621 | if (ret) |
617 | goto out; | 622 | goto out; |
618 | 623 | ||
@@ -632,7 +637,8 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, | |||
632 | } | 637 | } |
633 | 638 | ||
634 | out: | 639 | out: |
635 | kfree(real_parts); | 640 | /* Cleanup any parsed partitions */ |
641 | mtd_part_parser_cleanup(&parsed); | ||
636 | return ret; | 642 | return ret; |
637 | } | 643 | } |
638 | EXPORT_SYMBOL_GPL(mtd_device_parse_register); | 644 | EXPORT_SYMBOL_GPL(mtd_device_parse_register); |
diff --git a/drivers/mtd/mtdcore.h b/drivers/mtd/mtdcore.h index 7b0353399a10..55fdb8e1fd2a 100644 --- a/drivers/mtd/mtdcore.h +++ b/drivers/mtd/mtdcore.h | |||
@@ -10,10 +10,15 @@ int add_mtd_device(struct mtd_info *mtd); | |||
10 | int del_mtd_device(struct mtd_info *mtd); | 10 | int del_mtd_device(struct mtd_info *mtd); |
11 | int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int); | 11 | int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int); |
12 | int del_mtd_partitions(struct mtd_info *); | 12 | int del_mtd_partitions(struct mtd_info *); |
13 | |||
14 | struct mtd_partitions; | ||
15 | |||
13 | int parse_mtd_partitions(struct mtd_info *master, const char * const *types, | 16 | int parse_mtd_partitions(struct mtd_info *master, const char * const *types, |
14 | struct mtd_partition **pparts, | 17 | struct mtd_partitions *pparts, |
15 | struct mtd_part_parser_data *data); | 18 | struct mtd_part_parser_data *data); |
16 | 19 | ||
20 | void mtd_part_parser_cleanup(struct mtd_partitions *parts); | ||
21 | |||
17 | int __init init_mtdchar(void); | 22 | int __init init_mtdchar(void); |
18 | void __exit cleanup_mtdchar(void); | 23 | void __exit cleanup_mtdchar(void); |
19 | 24 | ||
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index f8ba153f63bf..10bf304027dd 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c | |||
@@ -48,9 +48,12 @@ struct mtd_part { | |||
48 | 48 | ||
49 | /* | 49 | /* |
50 | * Given a pointer to the MTD object in the mtd_part structure, we can retrieve | 50 | * Given a pointer to the MTD object in the mtd_part structure, we can retrieve |
51 | * the pointer to that structure with this macro. | 51 | * the pointer to that structure. |
52 | */ | 52 | */ |
53 | #define PART(x) ((struct mtd_part *)(x)) | 53 | static inline struct mtd_part *mtd_to_part(const struct mtd_info *mtd) |
54 | { | ||
55 | return container_of(mtd, struct mtd_part, mtd); | ||
56 | } | ||
54 | 57 | ||
55 | 58 | ||
56 | /* | 59 | /* |
@@ -61,7 +64,7 @@ struct mtd_part { | |||
61 | static int part_read(struct mtd_info *mtd, loff_t from, size_t len, | 64 | static int part_read(struct mtd_info *mtd, loff_t from, size_t len, |
62 | size_t *retlen, u_char *buf) | 65 | size_t *retlen, u_char *buf) |
63 | { | 66 | { |
64 | struct mtd_part *part = PART(mtd); | 67 | struct mtd_part *part = mtd_to_part(mtd); |
65 | struct mtd_ecc_stats stats; | 68 | struct mtd_ecc_stats stats; |
66 | int res; | 69 | int res; |
67 | 70 | ||
@@ -80,7 +83,7 @@ static int part_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
80 | static int part_point(struct mtd_info *mtd, loff_t from, size_t len, | 83 | static int part_point(struct mtd_info *mtd, loff_t from, size_t len, |
81 | size_t *retlen, void **virt, resource_size_t *phys) | 84 | size_t *retlen, void **virt, resource_size_t *phys) |
82 | { | 85 | { |
83 | struct mtd_part *part = PART(mtd); | 86 | struct mtd_part *part = mtd_to_part(mtd); |
84 | 87 | ||
85 | return part->master->_point(part->master, from + part->offset, len, | 88 | return part->master->_point(part->master, from + part->offset, len, |
86 | retlen, virt, phys); | 89 | retlen, virt, phys); |
@@ -88,7 +91,7 @@ static int part_point(struct mtd_info *mtd, loff_t from, size_t len, | |||
88 | 91 | ||
89 | static int part_unpoint(struct mtd_info *mtd, loff_t from, size_t len) | 92 | static int part_unpoint(struct mtd_info *mtd, loff_t from, size_t len) |
90 | { | 93 | { |
91 | struct mtd_part *part = PART(mtd); | 94 | struct mtd_part *part = mtd_to_part(mtd); |
92 | 95 | ||
93 | return part->master->_unpoint(part->master, from + part->offset, len); | 96 | return part->master->_unpoint(part->master, from + part->offset, len); |
94 | } | 97 | } |
@@ -98,7 +101,7 @@ static unsigned long part_get_unmapped_area(struct mtd_info *mtd, | |||
98 | unsigned long offset, | 101 | unsigned long offset, |
99 | unsigned long flags) | 102 | unsigned long flags) |
100 | { | 103 | { |
101 | struct mtd_part *part = PART(mtd); | 104 | struct mtd_part *part = mtd_to_part(mtd); |
102 | 105 | ||
103 | offset += part->offset; | 106 | offset += part->offset; |
104 | return part->master->_get_unmapped_area(part->master, len, offset, | 107 | return part->master->_get_unmapped_area(part->master, len, offset, |
@@ -108,7 +111,7 @@ static unsigned long part_get_unmapped_area(struct mtd_info *mtd, | |||
108 | static int part_read_oob(struct mtd_info *mtd, loff_t from, | 111 | static int part_read_oob(struct mtd_info *mtd, loff_t from, |
109 | struct mtd_oob_ops *ops) | 112 | struct mtd_oob_ops *ops) |
110 | { | 113 | { |
111 | struct mtd_part *part = PART(mtd); | 114 | struct mtd_part *part = mtd_to_part(mtd); |
112 | int res; | 115 | int res; |
113 | 116 | ||
114 | if (from >= mtd->size) | 117 | if (from >= mtd->size) |
@@ -146,7 +149,7 @@ static int part_read_oob(struct mtd_info *mtd, loff_t from, | |||
146 | static int part_read_user_prot_reg(struct mtd_info *mtd, loff_t from, | 149 | static int part_read_user_prot_reg(struct mtd_info *mtd, loff_t from, |
147 | size_t len, size_t *retlen, u_char *buf) | 150 | size_t len, size_t *retlen, u_char *buf) |
148 | { | 151 | { |
149 | struct mtd_part *part = PART(mtd); | 152 | struct mtd_part *part = mtd_to_part(mtd); |
150 | return part->master->_read_user_prot_reg(part->master, from, len, | 153 | return part->master->_read_user_prot_reg(part->master, from, len, |
151 | retlen, buf); | 154 | retlen, buf); |
152 | } | 155 | } |
@@ -154,7 +157,7 @@ static int part_read_user_prot_reg(struct mtd_info *mtd, loff_t from, | |||
154 | static int part_get_user_prot_info(struct mtd_info *mtd, size_t len, | 157 | static int part_get_user_prot_info(struct mtd_info *mtd, size_t len, |
155 | size_t *retlen, struct otp_info *buf) | 158 | size_t *retlen, struct otp_info *buf) |
156 | { | 159 | { |
157 | struct mtd_part *part = PART(mtd); | 160 | struct mtd_part *part = mtd_to_part(mtd); |
158 | return part->master->_get_user_prot_info(part->master, len, retlen, | 161 | return part->master->_get_user_prot_info(part->master, len, retlen, |
159 | buf); | 162 | buf); |
160 | } | 163 | } |
@@ -162,7 +165,7 @@ static int part_get_user_prot_info(struct mtd_info *mtd, size_t len, | |||
162 | static int part_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, | 165 | static int part_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, |
163 | size_t len, size_t *retlen, u_char *buf) | 166 | size_t len, size_t *retlen, u_char *buf) |
164 | { | 167 | { |
165 | struct mtd_part *part = PART(mtd); | 168 | struct mtd_part *part = mtd_to_part(mtd); |
166 | return part->master->_read_fact_prot_reg(part->master, from, len, | 169 | return part->master->_read_fact_prot_reg(part->master, from, len, |
167 | retlen, buf); | 170 | retlen, buf); |
168 | } | 171 | } |
@@ -170,7 +173,7 @@ static int part_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, | |||
170 | static int part_get_fact_prot_info(struct mtd_info *mtd, size_t len, | 173 | static int part_get_fact_prot_info(struct mtd_info *mtd, size_t len, |
171 | size_t *retlen, struct otp_info *buf) | 174 | size_t *retlen, struct otp_info *buf) |
172 | { | 175 | { |
173 | struct mtd_part *part = PART(mtd); | 176 | struct mtd_part *part = mtd_to_part(mtd); |
174 | return part->master->_get_fact_prot_info(part->master, len, retlen, | 177 | return part->master->_get_fact_prot_info(part->master, len, retlen, |
175 | buf); | 178 | buf); |
176 | } | 179 | } |
@@ -178,7 +181,7 @@ static int part_get_fact_prot_info(struct mtd_info *mtd, size_t len, | |||
178 | static int part_write(struct mtd_info *mtd, loff_t to, size_t len, | 181 | static int part_write(struct mtd_info *mtd, loff_t to, size_t len, |
179 | size_t *retlen, const u_char *buf) | 182 | size_t *retlen, const u_char *buf) |
180 | { | 183 | { |
181 | struct mtd_part *part = PART(mtd); | 184 | struct mtd_part *part = mtd_to_part(mtd); |
182 | return part->master->_write(part->master, to + part->offset, len, | 185 | return part->master->_write(part->master, to + part->offset, len, |
183 | retlen, buf); | 186 | retlen, buf); |
184 | } | 187 | } |
@@ -186,7 +189,7 @@ static int part_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
186 | static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len, | 189 | static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len, |
187 | size_t *retlen, const u_char *buf) | 190 | size_t *retlen, const u_char *buf) |
188 | { | 191 | { |
189 | struct mtd_part *part = PART(mtd); | 192 | struct mtd_part *part = mtd_to_part(mtd); |
190 | return part->master->_panic_write(part->master, to + part->offset, len, | 193 | return part->master->_panic_write(part->master, to + part->offset, len, |
191 | retlen, buf); | 194 | retlen, buf); |
192 | } | 195 | } |
@@ -194,7 +197,7 @@ static int part_panic_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
194 | static int part_write_oob(struct mtd_info *mtd, loff_t to, | 197 | static int part_write_oob(struct mtd_info *mtd, loff_t to, |
195 | struct mtd_oob_ops *ops) | 198 | struct mtd_oob_ops *ops) |
196 | { | 199 | { |
197 | struct mtd_part *part = PART(mtd); | 200 | struct mtd_part *part = mtd_to_part(mtd); |
198 | 201 | ||
199 | if (to >= mtd->size) | 202 | if (to >= mtd->size) |
200 | return -EINVAL; | 203 | return -EINVAL; |
@@ -206,7 +209,7 @@ static int part_write_oob(struct mtd_info *mtd, loff_t to, | |||
206 | static int part_write_user_prot_reg(struct mtd_info *mtd, loff_t from, | 209 | static int part_write_user_prot_reg(struct mtd_info *mtd, loff_t from, |
207 | size_t len, size_t *retlen, u_char *buf) | 210 | size_t len, size_t *retlen, u_char *buf) |
208 | { | 211 | { |
209 | struct mtd_part *part = PART(mtd); | 212 | struct mtd_part *part = mtd_to_part(mtd); |
210 | return part->master->_write_user_prot_reg(part->master, from, len, | 213 | return part->master->_write_user_prot_reg(part->master, from, len, |
211 | retlen, buf); | 214 | retlen, buf); |
212 | } | 215 | } |
@@ -214,21 +217,21 @@ static int part_write_user_prot_reg(struct mtd_info *mtd, loff_t from, | |||
214 | static int part_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, | 217 | static int part_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, |
215 | size_t len) | 218 | size_t len) |
216 | { | 219 | { |
217 | struct mtd_part *part = PART(mtd); | 220 | struct mtd_part *part = mtd_to_part(mtd); |
218 | return part->master->_lock_user_prot_reg(part->master, from, len); | 221 | return part->master->_lock_user_prot_reg(part->master, from, len); |
219 | } | 222 | } |
220 | 223 | ||
221 | static int part_writev(struct mtd_info *mtd, const struct kvec *vecs, | 224 | static int part_writev(struct mtd_info *mtd, const struct kvec *vecs, |
222 | unsigned long count, loff_t to, size_t *retlen) | 225 | unsigned long count, loff_t to, size_t *retlen) |
223 | { | 226 | { |
224 | struct mtd_part *part = PART(mtd); | 227 | struct mtd_part *part = mtd_to_part(mtd); |
225 | return part->master->_writev(part->master, vecs, count, | 228 | return part->master->_writev(part->master, vecs, count, |
226 | to + part->offset, retlen); | 229 | to + part->offset, retlen); |
227 | } | 230 | } |
228 | 231 | ||
229 | static int part_erase(struct mtd_info *mtd, struct erase_info *instr) | 232 | static int part_erase(struct mtd_info *mtd, struct erase_info *instr) |
230 | { | 233 | { |
231 | struct mtd_part *part = PART(mtd); | 234 | struct mtd_part *part = mtd_to_part(mtd); |
232 | int ret; | 235 | int ret; |
233 | 236 | ||
234 | instr->addr += part->offset; | 237 | instr->addr += part->offset; |
@@ -244,7 +247,7 @@ static int part_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
244 | void mtd_erase_callback(struct erase_info *instr) | 247 | void mtd_erase_callback(struct erase_info *instr) |
245 | { | 248 | { |
246 | if (instr->mtd->_erase == part_erase) { | 249 | if (instr->mtd->_erase == part_erase) { |
247 | struct mtd_part *part = PART(instr->mtd); | 250 | struct mtd_part *part = mtd_to_part(instr->mtd); |
248 | 251 | ||
249 | if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) | 252 | if (instr->fail_addr != MTD_FAIL_ADDR_UNKNOWN) |
250 | instr->fail_addr -= part->offset; | 253 | instr->fail_addr -= part->offset; |
@@ -257,57 +260,57 @@ EXPORT_SYMBOL_GPL(mtd_erase_callback); | |||
257 | 260 | ||
258 | static int part_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) | 261 | static int part_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) |
259 | { | 262 | { |
260 | struct mtd_part *part = PART(mtd); | 263 | struct mtd_part *part = mtd_to_part(mtd); |
261 | return part->master->_lock(part->master, ofs + part->offset, len); | 264 | return part->master->_lock(part->master, ofs + part->offset, len); |
262 | } | 265 | } |
263 | 266 | ||
264 | static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) | 267 | static int part_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) |
265 | { | 268 | { |
266 | struct mtd_part *part = PART(mtd); | 269 | struct mtd_part *part = mtd_to_part(mtd); |
267 | return part->master->_unlock(part->master, ofs + part->offset, len); | 270 | return part->master->_unlock(part->master, ofs + part->offset, len); |
268 | } | 271 | } |
269 | 272 | ||
270 | static int part_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) | 273 | static int part_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) |
271 | { | 274 | { |
272 | struct mtd_part *part = PART(mtd); | 275 | struct mtd_part *part = mtd_to_part(mtd); |
273 | return part->master->_is_locked(part->master, ofs + part->offset, len); | 276 | return part->master->_is_locked(part->master, ofs + part->offset, len); |
274 | } | 277 | } |
275 | 278 | ||
276 | static void part_sync(struct mtd_info *mtd) | 279 | static void part_sync(struct mtd_info *mtd) |
277 | { | 280 | { |
278 | struct mtd_part *part = PART(mtd); | 281 | struct mtd_part *part = mtd_to_part(mtd); |
279 | part->master->_sync(part->master); | 282 | part->master->_sync(part->master); |
280 | } | 283 | } |
281 | 284 | ||
282 | static int part_suspend(struct mtd_info *mtd) | 285 | static int part_suspend(struct mtd_info *mtd) |
283 | { | 286 | { |
284 | struct mtd_part *part = PART(mtd); | 287 | struct mtd_part *part = mtd_to_part(mtd); |
285 | return part->master->_suspend(part->master); | 288 | return part->master->_suspend(part->master); |
286 | } | 289 | } |
287 | 290 | ||
288 | static void part_resume(struct mtd_info *mtd) | 291 | static void part_resume(struct mtd_info *mtd) |
289 | { | 292 | { |
290 | struct mtd_part *part = PART(mtd); | 293 | struct mtd_part *part = mtd_to_part(mtd); |
291 | part->master->_resume(part->master); | 294 | part->master->_resume(part->master); |
292 | } | 295 | } |
293 | 296 | ||
294 | static int part_block_isreserved(struct mtd_info *mtd, loff_t ofs) | 297 | static int part_block_isreserved(struct mtd_info *mtd, loff_t ofs) |
295 | { | 298 | { |
296 | struct mtd_part *part = PART(mtd); | 299 | struct mtd_part *part = mtd_to_part(mtd); |
297 | ofs += part->offset; | 300 | ofs += part->offset; |
298 | return part->master->_block_isreserved(part->master, ofs); | 301 | return part->master->_block_isreserved(part->master, ofs); |
299 | } | 302 | } |
300 | 303 | ||
301 | static int part_block_isbad(struct mtd_info *mtd, loff_t ofs) | 304 | static int part_block_isbad(struct mtd_info *mtd, loff_t ofs) |
302 | { | 305 | { |
303 | struct mtd_part *part = PART(mtd); | 306 | struct mtd_part *part = mtd_to_part(mtd); |
304 | ofs += part->offset; | 307 | ofs += part->offset; |
305 | return part->master->_block_isbad(part->master, ofs); | 308 | return part->master->_block_isbad(part->master, ofs); |
306 | } | 309 | } |
307 | 310 | ||
308 | static int part_block_markbad(struct mtd_info *mtd, loff_t ofs) | 311 | static int part_block_markbad(struct mtd_info *mtd, loff_t ofs) |
309 | { | 312 | { |
310 | struct mtd_part *part = PART(mtd); | 313 | struct mtd_part *part = mtd_to_part(mtd); |
311 | int res; | 314 | int res; |
312 | 315 | ||
313 | ofs += part->offset; | 316 | ofs += part->offset; |
@@ -558,7 +561,7 @@ static ssize_t mtd_partition_offset_show(struct device *dev, | |||
558 | struct device_attribute *attr, char *buf) | 561 | struct device_attribute *attr, char *buf) |
559 | { | 562 | { |
560 | struct mtd_info *mtd = dev_get_drvdata(dev); | 563 | struct mtd_info *mtd = dev_get_drvdata(dev); |
561 | struct mtd_part *part = PART(mtd); | 564 | struct mtd_part *part = mtd_to_part(mtd); |
562 | return snprintf(buf, PAGE_SIZE, "%lld\n", part->offset); | 565 | return snprintf(buf, PAGE_SIZE, "%lld\n", part->offset); |
563 | } | 566 | } |
564 | 567 | ||
@@ -596,11 +599,10 @@ int mtd_add_partition(struct mtd_info *master, const char *name, | |||
596 | if (length <= 0) | 599 | if (length <= 0) |
597 | return -EINVAL; | 600 | return -EINVAL; |
598 | 601 | ||
602 | memset(&part, 0, sizeof(part)); | ||
599 | part.name = name; | 603 | part.name = name; |
600 | part.size = length; | 604 | part.size = length; |
601 | part.offset = offset; | 605 | part.offset = offset; |
602 | part.mask_flags = 0; | ||
603 | part.ecclayout = NULL; | ||
604 | 606 | ||
605 | new = allocate_partition(master, &part, -1, offset); | 607 | new = allocate_partition(master, &part, -1, offset); |
606 | if (IS_ERR(new)) | 608 | if (IS_ERR(new)) |
@@ -685,7 +687,7 @@ int add_mtd_partitions(struct mtd_info *master, | |||
685 | static DEFINE_SPINLOCK(part_parser_lock); | 687 | static DEFINE_SPINLOCK(part_parser_lock); |
686 | static LIST_HEAD(part_parsers); | 688 | static LIST_HEAD(part_parsers); |
687 | 689 | ||
688 | static struct mtd_part_parser *get_partition_parser(const char *name) | 690 | static struct mtd_part_parser *mtd_part_parser_get(const char *name) |
689 | { | 691 | { |
690 | struct mtd_part_parser *p, *ret = NULL; | 692 | struct mtd_part_parser *p, *ret = NULL; |
691 | 693 | ||
@@ -702,15 +704,35 @@ static struct mtd_part_parser *get_partition_parser(const char *name) | |||
702 | return ret; | 704 | return ret; |
703 | } | 705 | } |
704 | 706 | ||
705 | #define put_partition_parser(p) do { module_put((p)->owner); } while (0) | 707 | static inline void mtd_part_parser_put(const struct mtd_part_parser *p) |
708 | { | ||
709 | module_put(p->owner); | ||
710 | } | ||
711 | |||
712 | /* | ||
713 | * Many partition parsers just expected the core to kfree() all their data in | ||
714 | * one chunk. Do that by default. | ||
715 | */ | ||
716 | static void mtd_part_parser_cleanup_default(const struct mtd_partition *pparts, | ||
717 | int nr_parts) | ||
718 | { | ||
719 | kfree(pparts); | ||
720 | } | ||
706 | 721 | ||
707 | void register_mtd_parser(struct mtd_part_parser *p) | 722 | int __register_mtd_parser(struct mtd_part_parser *p, struct module *owner) |
708 | { | 723 | { |
724 | p->owner = owner; | ||
725 | |||
726 | if (!p->cleanup) | ||
727 | p->cleanup = &mtd_part_parser_cleanup_default; | ||
728 | |||
709 | spin_lock(&part_parser_lock); | 729 | spin_lock(&part_parser_lock); |
710 | list_add(&p->list, &part_parsers); | 730 | list_add(&p->list, &part_parsers); |
711 | spin_unlock(&part_parser_lock); | 731 | spin_unlock(&part_parser_lock); |
732 | |||
733 | return 0; | ||
712 | } | 734 | } |
713 | EXPORT_SYMBOL_GPL(register_mtd_parser); | 735 | EXPORT_SYMBOL_GPL(__register_mtd_parser); |
714 | 736 | ||
715 | void deregister_mtd_parser(struct mtd_part_parser *p) | 737 | void deregister_mtd_parser(struct mtd_part_parser *p) |
716 | { | 738 | { |
@@ -734,7 +756,7 @@ static const char * const default_mtd_part_types[] = { | |||
734 | * parse_mtd_partitions - parse MTD partitions | 756 | * parse_mtd_partitions - parse MTD partitions |
735 | * @master: the master partition (describes whole MTD device) | 757 | * @master: the master partition (describes whole MTD device) |
736 | * @types: names of partition parsers to try or %NULL | 758 | * @types: names of partition parsers to try or %NULL |
737 | * @pparts: array of partitions found is returned here | 759 | * @pparts: info about partitions found is returned here |
738 | * @data: MTD partition parser-specific data | 760 | * @data: MTD partition parser-specific data |
739 | * | 761 | * |
740 | * This function tries to find partition on MTD device @master. It uses MTD | 762 | * This function tries to find partition on MTD device @master. It uses MTD |
@@ -746,12 +768,13 @@ static const char * const default_mtd_part_types[] = { | |||
746 | * | 768 | * |
747 | * This function may return: | 769 | * This function may return: |
748 | * o a negative error code in case of failure | 770 | * o a negative error code in case of failure |
749 | * o zero if no partitions were found | 771 | * o zero otherwise, and @pparts will describe the partitions, number of |
750 | * o a positive number of found partitions, in which case on exit @pparts will | 772 | * partitions, and the parser which parsed them. Caller must release |
751 | * point to an array containing this number of &struct mtd_info objects. | 773 | * resources with mtd_part_parser_cleanup() when finished with the returned |
774 | * data. | ||
752 | */ | 775 | */ |
753 | int parse_mtd_partitions(struct mtd_info *master, const char *const *types, | 776 | int parse_mtd_partitions(struct mtd_info *master, const char *const *types, |
754 | struct mtd_partition **pparts, | 777 | struct mtd_partitions *pparts, |
755 | struct mtd_part_parser_data *data) | 778 | struct mtd_part_parser_data *data) |
756 | { | 779 | { |
757 | struct mtd_part_parser *parser; | 780 | struct mtd_part_parser *parser; |
@@ -762,22 +785,24 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types, | |||
762 | 785 | ||
763 | for ( ; *types; types++) { | 786 | for ( ; *types; types++) { |
764 | pr_debug("%s: parsing partitions %s\n", master->name, *types); | 787 | pr_debug("%s: parsing partitions %s\n", master->name, *types); |
765 | parser = get_partition_parser(*types); | 788 | parser = mtd_part_parser_get(*types); |
766 | if (!parser && !request_module("%s", *types)) | 789 | if (!parser && !request_module("%s", *types)) |
767 | parser = get_partition_parser(*types); | 790 | parser = mtd_part_parser_get(*types); |
768 | pr_debug("%s: got parser %s\n", master->name, | 791 | pr_debug("%s: got parser %s\n", master->name, |
769 | parser ? parser->name : NULL); | 792 | parser ? parser->name : NULL); |
770 | if (!parser) | 793 | if (!parser) |
771 | continue; | 794 | continue; |
772 | ret = (*parser->parse_fn)(master, pparts, data); | 795 | ret = (*parser->parse_fn)(master, &pparts->parts, data); |
773 | pr_debug("%s: parser %s: %i\n", | 796 | pr_debug("%s: parser %s: %i\n", |
774 | master->name, parser->name, ret); | 797 | master->name, parser->name, ret); |
775 | put_partition_parser(parser); | ||
776 | if (ret > 0) { | 798 | if (ret > 0) { |
777 | printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n", | 799 | printk(KERN_NOTICE "%d %s partitions found on MTD device %s\n", |
778 | ret, parser->name, master->name); | 800 | ret, parser->name, master->name); |
779 | return ret; | 801 | pparts->nr_parts = ret; |
802 | pparts->parser = parser; | ||
803 | return 0; | ||
780 | } | 804 | } |
805 | mtd_part_parser_put(parser); | ||
781 | /* | 806 | /* |
782 | * Stash the first error we see; only report it if no parser | 807 | * Stash the first error we see; only report it if no parser |
783 | * succeeds | 808 | * succeeds |
@@ -788,6 +813,22 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types, | |||
788 | return err; | 813 | return err; |
789 | } | 814 | } |
790 | 815 | ||
816 | void mtd_part_parser_cleanup(struct mtd_partitions *parts) | ||
817 | { | ||
818 | const struct mtd_part_parser *parser; | ||
819 | |||
820 | if (!parts) | ||
821 | return; | ||
822 | |||
823 | parser = parts->parser; | ||
824 | if (parser) { | ||
825 | if (parser->cleanup) | ||
826 | parser->cleanup(parts->parts, parts->nr_parts); | ||
827 | |||
828 | mtd_part_parser_put(parser); | ||
829 | } | ||
830 | } | ||
831 | |||
791 | int mtd_is_partition(const struct mtd_info *mtd) | 832 | int mtd_is_partition(const struct mtd_info *mtd) |
792 | { | 833 | { |
793 | struct mtd_part *part; | 834 | struct mtd_part *part; |
@@ -811,6 +852,6 @@ uint64_t mtd_get_device_size(const struct mtd_info *mtd) | |||
811 | if (!mtd_is_partition(mtd)) | 852 | if (!mtd_is_partition(mtd)) |
812 | return mtd->size; | 853 | return mtd->size; |
813 | 854 | ||
814 | return PART(mtd)->master->size; | 855 | return mtd_to_part(mtd)->master->size; |
815 | } | 856 | } |
816 | EXPORT_SYMBOL_GPL(mtd_get_device_size); | 857 | EXPORT_SYMBOL_GPL(mtd_get_device_size); |
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 289664089cf3..20f01b3ec23d 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
@@ -55,7 +55,7 @@ config MTD_NAND_DENALI_PCI | |||
55 | config MTD_NAND_DENALI_DT | 55 | config MTD_NAND_DENALI_DT |
56 | tristate "Support Denali NAND controller as a DT device" | 56 | tristate "Support Denali NAND controller as a DT device" |
57 | select MTD_NAND_DENALI | 57 | select MTD_NAND_DENALI |
58 | depends on HAS_DMA && HAVE_CLK | 58 | depends on HAS_DMA && HAVE_CLK && OF |
59 | help | 59 | help |
60 | Enable the driver for NAND flash on platforms using a Denali NAND | 60 | Enable the driver for NAND flash on platforms using a Denali NAND |
61 | controller as a DT device. | 61 | controller as a DT device. |
@@ -480,7 +480,7 @@ config MTD_NAND_MXC | |||
480 | 480 | ||
481 | config MTD_NAND_SH_FLCTL | 481 | config MTD_NAND_SH_FLCTL |
482 | tristate "Support for NAND on Renesas SuperH FLCTL" | 482 | tristate "Support for NAND on Renesas SuperH FLCTL" |
483 | depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST | 483 | depends on SUPERH || COMPILE_TEST |
484 | depends on HAS_IOMEM | 484 | depends on HAS_IOMEM |
485 | depends on HAS_DMA | 485 | depends on HAS_DMA |
486 | help | 486 | help |
@@ -519,6 +519,13 @@ config MTD_NAND_JZ4740 | |||
519 | help | 519 | help |
520 | Enables support for NAND Flash on JZ4740 SoC based boards. | 520 | Enables support for NAND Flash on JZ4740 SoC based boards. |
521 | 521 | ||
522 | config MTD_NAND_JZ4780 | ||
523 | tristate "Support for NAND on JZ4780 SoC" | ||
524 | depends on MACH_JZ4780 && JZ4780_NEMC | ||
525 | help | ||
526 | Enables support for NAND Flash connected to the NEMC on JZ4780 SoC | ||
527 | based boards, using the BCH controller for hardware error correction. | ||
528 | |||
522 | config MTD_NAND_FSMC | 529 | config MTD_NAND_FSMC |
523 | tristate "Support for NAND on ST Micros FSMC" | 530 | tristate "Support for NAND on ST Micros FSMC" |
524 | depends on PLAT_SPEAR || ARCH_NOMADIK || ARCH_U8500 || MACH_U300 | 531 | depends on PLAT_SPEAR || ARCH_NOMADIK || ARCH_U8500 || MACH_U300 |
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 2c7f014b349e..9e3623308509 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile | |||
@@ -49,6 +49,7 @@ obj-$(CONFIG_MTD_NAND_MPC5121_NFC) += mpc5121_nfc.o | |||
49 | obj-$(CONFIG_MTD_NAND_VF610_NFC) += vf610_nfc.o | 49 | obj-$(CONFIG_MTD_NAND_VF610_NFC) += vf610_nfc.o |
50 | obj-$(CONFIG_MTD_NAND_RICOH) += r852.o | 50 | obj-$(CONFIG_MTD_NAND_RICOH) += r852.o |
51 | obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o | 51 | obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o |
52 | obj-$(CONFIG_MTD_NAND_JZ4780) += jz4780_nand.o jz4780_bch.o | ||
52 | obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/ | 53 | obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/ |
53 | obj-$(CONFIG_MTD_NAND_XWAY) += xway_nand.o | 54 | obj-$(CONFIG_MTD_NAND_XWAY) += xway_nand.o |
54 | obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash/ | 55 | obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash/ |
diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c index 842f8fe91b56..68b58c85789c 100644 --- a/drivers/mtd/nand/ams-delta.c +++ b/drivers/mtd/nand/ams-delta.c | |||
@@ -64,8 +64,8 @@ static struct mtd_partition partition_info[] = { | |||
64 | 64 | ||
65 | static void ams_delta_write_byte(struct mtd_info *mtd, u_char byte) | 65 | static void ams_delta_write_byte(struct mtd_info *mtd, u_char byte) |
66 | { | 66 | { |
67 | struct nand_chip *this = mtd->priv; | 67 | struct nand_chip *this = mtd_to_nand(mtd); |
68 | void __iomem *io_base = this->priv; | 68 | void __iomem *io_base = (void __iomem *)nand_get_controller_data(this); |
69 | 69 | ||
70 | writew(0, io_base + OMAP_MPUIO_IO_CNTL); | 70 | writew(0, io_base + OMAP_MPUIO_IO_CNTL); |
71 | writew(byte, this->IO_ADDR_W); | 71 | writew(byte, this->IO_ADDR_W); |
@@ -77,8 +77,8 @@ static void ams_delta_write_byte(struct mtd_info *mtd, u_char byte) | |||
77 | static u_char ams_delta_read_byte(struct mtd_info *mtd) | 77 | static u_char ams_delta_read_byte(struct mtd_info *mtd) |
78 | { | 78 | { |
79 | u_char res; | 79 | u_char res; |
80 | struct nand_chip *this = mtd->priv; | 80 | struct nand_chip *this = mtd_to_nand(mtd); |
81 | void __iomem *io_base = this->priv; | 81 | void __iomem *io_base = (void __iomem *)nand_get_controller_data(this); |
82 | 82 | ||
83 | gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_NRE, 0); | 83 | gpio_set_value(AMS_DELTA_GPIO_PIN_NAND_NRE, 0); |
84 | ndelay(40); | 84 | ndelay(40); |
@@ -183,22 +183,16 @@ static int ams_delta_init(struct platform_device *pdev) | |||
183 | return -ENXIO; | 183 | return -ENXIO; |
184 | 184 | ||
185 | /* Allocate memory for MTD device structure and private data */ | 185 | /* Allocate memory for MTD device structure and private data */ |
186 | ams_delta_mtd = kzalloc(sizeof(struct mtd_info) + | 186 | this = kzalloc(sizeof(struct nand_chip), GFP_KERNEL); |
187 | sizeof(struct nand_chip), GFP_KERNEL); | 187 | if (!this) { |
188 | if (!ams_delta_mtd) { | ||
189 | printk (KERN_WARNING "Unable to allocate E3 NAND MTD device structure.\n"); | 188 | printk (KERN_WARNING "Unable to allocate E3 NAND MTD device structure.\n"); |
190 | err = -ENOMEM; | 189 | err = -ENOMEM; |
191 | goto out; | 190 | goto out; |
192 | } | 191 | } |
193 | 192 | ||
193 | ams_delta_mtd = nand_to_mtd(this); | ||
194 | ams_delta_mtd->owner = THIS_MODULE; | 194 | ams_delta_mtd->owner = THIS_MODULE; |
195 | 195 | ||
196 | /* Get pointer to private data */ | ||
197 | this = (struct nand_chip *) (&ams_delta_mtd[1]); | ||
198 | |||
199 | /* Link the private data with the MTD structure */ | ||
200 | ams_delta_mtd->priv = this; | ||
201 | |||
202 | /* | 196 | /* |
203 | * Don't try to request the memory region from here, | 197 | * Don't try to request the memory region from here, |
204 | * it should have been already requested from the | 198 | * it should have been already requested from the |
@@ -212,7 +206,7 @@ static int ams_delta_init(struct platform_device *pdev) | |||
212 | goto out_free; | 206 | goto out_free; |
213 | } | 207 | } |
214 | 208 | ||
215 | this->priv = io_base; | 209 | nand_set_controller_data(this, (void *)io_base); |
216 | 210 | ||
217 | /* Set address of NAND IO lines */ | 211 | /* Set address of NAND IO lines */ |
218 | this->IO_ADDR_R = io_base + OMAP_MPUIO_INPUT_LATCH; | 212 | this->IO_ADDR_R = io_base + OMAP_MPUIO_INPUT_LATCH; |
@@ -256,7 +250,7 @@ out_gpio: | |||
256 | gpio_free(AMS_DELTA_GPIO_PIN_NAND_RB); | 250 | gpio_free(AMS_DELTA_GPIO_PIN_NAND_RB); |
257 | iounmap(io_base); | 251 | iounmap(io_base); |
258 | out_free: | 252 | out_free: |
259 | kfree(ams_delta_mtd); | 253 | kfree(this); |
260 | out: | 254 | out: |
261 | return err; | 255 | return err; |
262 | } | 256 | } |
@@ -276,7 +270,7 @@ static int ams_delta_cleanup(struct platform_device *pdev) | |||
276 | iounmap(io_base); | 270 | iounmap(io_base); |
277 | 271 | ||
278 | /* Free the MTD device structure */ | 272 | /* Free the MTD device structure */ |
279 | kfree(ams_delta_mtd); | 273 | kfree(mtd_to_nand(ams_delta_mtd)); |
280 | 274 | ||
281 | return 0; | 275 | return 0; |
282 | } | 276 | } |
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 583cdd9bb971..bddcf83d6859 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c | |||
@@ -116,7 +116,6 @@ static struct atmel_nfc nand_nfc; | |||
116 | 116 | ||
117 | struct atmel_nand_host { | 117 | struct atmel_nand_host { |
118 | struct nand_chip nand_chip; | 118 | struct nand_chip nand_chip; |
119 | struct mtd_info mtd; | ||
120 | void __iomem *io_base; | 119 | void __iomem *io_base; |
121 | dma_addr_t io_phys; | 120 | dma_addr_t io_phys; |
122 | struct atmel_nand_data board; | 121 | struct atmel_nand_data board; |
@@ -128,7 +127,7 @@ struct atmel_nand_host { | |||
128 | 127 | ||
129 | struct atmel_nfc *nfc; | 128 | struct atmel_nfc *nfc; |
130 | 129 | ||
131 | struct atmel_nand_caps *caps; | 130 | const struct atmel_nand_caps *caps; |
132 | bool has_pmecc; | 131 | bool has_pmecc; |
133 | u8 pmecc_corr_cap; | 132 | u8 pmecc_corr_cap; |
134 | u16 pmecc_sector_size; | 133 | u16 pmecc_sector_size; |
@@ -182,8 +181,8 @@ static void atmel_nand_disable(struct atmel_nand_host *host) | |||
182 | */ | 181 | */ |
183 | static void atmel_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 182 | static void atmel_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
184 | { | 183 | { |
185 | struct nand_chip *nand_chip = mtd->priv; | 184 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
186 | struct atmel_nand_host *host = nand_chip->priv; | 185 | struct atmel_nand_host *host = nand_get_controller_data(nand_chip); |
187 | 186 | ||
188 | if (ctrl & NAND_CTRL_CHANGE) { | 187 | if (ctrl & NAND_CTRL_CHANGE) { |
189 | if (ctrl & NAND_NCE) | 188 | if (ctrl & NAND_NCE) |
@@ -205,8 +204,8 @@ static void atmel_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl | |||
205 | */ | 204 | */ |
206 | static int atmel_nand_device_ready(struct mtd_info *mtd) | 205 | static int atmel_nand_device_ready(struct mtd_info *mtd) |
207 | { | 206 | { |
208 | struct nand_chip *nand_chip = mtd->priv; | 207 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
209 | struct atmel_nand_host *host = nand_chip->priv; | 208 | struct atmel_nand_host *host = nand_get_controller_data(nand_chip); |
210 | 209 | ||
211 | return gpio_get_value(host->board.rdy_pin) ^ | 210 | return gpio_get_value(host->board.rdy_pin) ^ |
212 | !!host->board.rdy_pin_active_low; | 211 | !!host->board.rdy_pin_active_low; |
@@ -215,8 +214,8 @@ static int atmel_nand_device_ready(struct mtd_info *mtd) | |||
215 | /* Set up for hardware ready pin and enable pin. */ | 214 | /* Set up for hardware ready pin and enable pin. */ |
216 | static int atmel_nand_set_enable_ready_pins(struct mtd_info *mtd) | 215 | static int atmel_nand_set_enable_ready_pins(struct mtd_info *mtd) |
217 | { | 216 | { |
218 | struct nand_chip *chip = mtd->priv; | 217 | struct nand_chip *chip = mtd_to_nand(mtd); |
219 | struct atmel_nand_host *host = chip->priv; | 218 | struct atmel_nand_host *host = nand_get_controller_data(chip); |
220 | int res = 0; | 219 | int res = 0; |
221 | 220 | ||
222 | if (gpio_is_valid(host->board.rdy_pin)) { | 221 | if (gpio_is_valid(host->board.rdy_pin)) { |
@@ -267,8 +266,8 @@ static int atmel_nand_set_enable_ready_pins(struct mtd_info *mtd) | |||
267 | */ | 266 | */ |
268 | static void atmel_read_buf8(struct mtd_info *mtd, u8 *buf, int len) | 267 | static void atmel_read_buf8(struct mtd_info *mtd, u8 *buf, int len) |
269 | { | 268 | { |
270 | struct nand_chip *nand_chip = mtd->priv; | 269 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
271 | struct atmel_nand_host *host = nand_chip->priv; | 270 | struct atmel_nand_host *host = nand_get_controller_data(nand_chip); |
272 | 271 | ||
273 | if (host->nfc && host->nfc->use_nfc_sram && host->nfc->data_in_sram) { | 272 | if (host->nfc && host->nfc->use_nfc_sram && host->nfc->data_in_sram) { |
274 | memcpy(buf, host->nfc->data_in_sram, len); | 273 | memcpy(buf, host->nfc->data_in_sram, len); |
@@ -280,8 +279,8 @@ static void atmel_read_buf8(struct mtd_info *mtd, u8 *buf, int len) | |||
280 | 279 | ||
281 | static void atmel_read_buf16(struct mtd_info *mtd, u8 *buf, int len) | 280 | static void atmel_read_buf16(struct mtd_info *mtd, u8 *buf, int len) |
282 | { | 281 | { |
283 | struct nand_chip *nand_chip = mtd->priv; | 282 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
284 | struct atmel_nand_host *host = nand_chip->priv; | 283 | struct atmel_nand_host *host = nand_get_controller_data(nand_chip); |
285 | 284 | ||
286 | if (host->nfc && host->nfc->use_nfc_sram && host->nfc->data_in_sram) { | 285 | if (host->nfc && host->nfc->use_nfc_sram && host->nfc->data_in_sram) { |
287 | memcpy(buf, host->nfc->data_in_sram, len); | 286 | memcpy(buf, host->nfc->data_in_sram, len); |
@@ -293,14 +292,14 @@ static void atmel_read_buf16(struct mtd_info *mtd, u8 *buf, int len) | |||
293 | 292 | ||
294 | static void atmel_write_buf8(struct mtd_info *mtd, const u8 *buf, int len) | 293 | static void atmel_write_buf8(struct mtd_info *mtd, const u8 *buf, int len) |
295 | { | 294 | { |
296 | struct nand_chip *nand_chip = mtd->priv; | 295 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
297 | 296 | ||
298 | __raw_writesb(nand_chip->IO_ADDR_W, buf, len); | 297 | __raw_writesb(nand_chip->IO_ADDR_W, buf, len); |
299 | } | 298 | } |
300 | 299 | ||
301 | static void atmel_write_buf16(struct mtd_info *mtd, const u8 *buf, int len) | 300 | static void atmel_write_buf16(struct mtd_info *mtd, const u8 *buf, int len) |
302 | { | 301 | { |
303 | struct nand_chip *nand_chip = mtd->priv; | 302 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
304 | 303 | ||
305 | __raw_writesw(nand_chip->IO_ADDR_W, buf, len / 2); | 304 | __raw_writesw(nand_chip->IO_ADDR_W, buf, len / 2); |
306 | } | 305 | } |
@@ -317,8 +316,10 @@ static int nfc_set_sram_bank(struct atmel_nand_host *host, unsigned int bank) | |||
317 | return -EINVAL; | 316 | return -EINVAL; |
318 | 317 | ||
319 | if (bank) { | 318 | if (bank) { |
319 | struct mtd_info *mtd = nand_to_mtd(&host->nand_chip); | ||
320 | |||
320 | /* Only for a 2k-page or lower flash, NFC can handle 2 banks */ | 321 | /* Only for a 2k-page or lower flash, NFC can handle 2 banks */ |
321 | if (host->mtd.writesize > 2048) | 322 | if (mtd->writesize > 2048) |
322 | return -EINVAL; | 323 | return -EINVAL; |
323 | nfc_writel(host->nfc->hsmc_regs, BANK, ATMEL_HSMC_NFC_BANK1); | 324 | nfc_writel(host->nfc->hsmc_regs, BANK, ATMEL_HSMC_NFC_BANK1); |
324 | } else { | 325 | } else { |
@@ -352,8 +353,8 @@ static int atmel_nand_dma_op(struct mtd_info *mtd, void *buf, int len, | |||
352 | dma_addr_t dma_src_addr, dma_dst_addr, phys_addr; | 353 | dma_addr_t dma_src_addr, dma_dst_addr, phys_addr; |
353 | struct dma_async_tx_descriptor *tx = NULL; | 354 | struct dma_async_tx_descriptor *tx = NULL; |
354 | dma_cookie_t cookie; | 355 | dma_cookie_t cookie; |
355 | struct nand_chip *chip = mtd->priv; | 356 | struct nand_chip *chip = mtd_to_nand(mtd); |
356 | struct atmel_nand_host *host = chip->priv; | 357 | struct atmel_nand_host *host = nand_get_controller_data(chip); |
357 | void *p = buf; | 358 | void *p = buf; |
358 | int err = -EIO; | 359 | int err = -EIO; |
359 | enum dma_data_direction dir = is_read ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | 360 | enum dma_data_direction dir = is_read ? DMA_FROM_DEVICE : DMA_TO_DEVICE; |
@@ -425,8 +426,8 @@ err_buf: | |||
425 | 426 | ||
426 | static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len) | 427 | static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len) |
427 | { | 428 | { |
428 | struct nand_chip *chip = mtd->priv; | 429 | struct nand_chip *chip = mtd_to_nand(mtd); |
429 | struct atmel_nand_host *host = chip->priv; | 430 | struct atmel_nand_host *host = nand_get_controller_data(chip); |
430 | 431 | ||
431 | if (use_dma && len > mtd->oobsize) | 432 | if (use_dma && len > mtd->oobsize) |
432 | /* only use DMA for bigger than oob size: better performances */ | 433 | /* only use DMA for bigger than oob size: better performances */ |
@@ -441,8 +442,8 @@ static void atmel_read_buf(struct mtd_info *mtd, u8 *buf, int len) | |||
441 | 442 | ||
442 | static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len) | 443 | static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len) |
443 | { | 444 | { |
444 | struct nand_chip *chip = mtd->priv; | 445 | struct nand_chip *chip = mtd_to_nand(mtd); |
445 | struct atmel_nand_host *host = chip->priv; | 446 | struct atmel_nand_host *host = nand_get_controller_data(chip); |
446 | 447 | ||
447 | if (use_dma && len > mtd->oobsize) | 448 | if (use_dma && len > mtd->oobsize) |
448 | /* only use DMA for bigger than oob size: better performances */ | 449 | /* only use DMA for bigger than oob size: better performances */ |
@@ -533,8 +534,8 @@ static int pmecc_data_alloc(struct atmel_nand_host *host) | |||
533 | 534 | ||
534 | static void pmecc_gen_syndrome(struct mtd_info *mtd, int sector) | 535 | static void pmecc_gen_syndrome(struct mtd_info *mtd, int sector) |
535 | { | 536 | { |
536 | struct nand_chip *nand_chip = mtd->priv; | 537 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
537 | struct atmel_nand_host *host = nand_chip->priv; | 538 | struct atmel_nand_host *host = nand_get_controller_data(nand_chip); |
538 | int i; | 539 | int i; |
539 | uint32_t value; | 540 | uint32_t value; |
540 | 541 | ||
@@ -550,8 +551,8 @@ static void pmecc_gen_syndrome(struct mtd_info *mtd, int sector) | |||
550 | 551 | ||
551 | static void pmecc_substitute(struct mtd_info *mtd) | 552 | static void pmecc_substitute(struct mtd_info *mtd) |
552 | { | 553 | { |
553 | struct nand_chip *nand_chip = mtd->priv; | 554 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
554 | struct atmel_nand_host *host = nand_chip->priv; | 555 | struct atmel_nand_host *host = nand_get_controller_data(nand_chip); |
555 | int16_t __iomem *alpha_to = host->pmecc_alpha_to; | 556 | int16_t __iomem *alpha_to = host->pmecc_alpha_to; |
556 | int16_t __iomem *index_of = host->pmecc_index_of; | 557 | int16_t __iomem *index_of = host->pmecc_index_of; |
557 | int16_t *partial_syn = host->pmecc_partial_syn; | 558 | int16_t *partial_syn = host->pmecc_partial_syn; |
@@ -592,8 +593,8 @@ static void pmecc_substitute(struct mtd_info *mtd) | |||
592 | 593 | ||
593 | static void pmecc_get_sigma(struct mtd_info *mtd) | 594 | static void pmecc_get_sigma(struct mtd_info *mtd) |
594 | { | 595 | { |
595 | struct nand_chip *nand_chip = mtd->priv; | 596 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
596 | struct atmel_nand_host *host = nand_chip->priv; | 597 | struct atmel_nand_host *host = nand_get_controller_data(nand_chip); |
597 | 598 | ||
598 | int16_t *lmu = host->pmecc_lmu; | 599 | int16_t *lmu = host->pmecc_lmu; |
599 | int16_t *si = host->pmecc_si; | 600 | int16_t *si = host->pmecc_si; |
@@ -750,8 +751,8 @@ static void pmecc_get_sigma(struct mtd_info *mtd) | |||
750 | 751 | ||
751 | static int pmecc_err_location(struct mtd_info *mtd) | 752 | static int pmecc_err_location(struct mtd_info *mtd) |
752 | { | 753 | { |
753 | struct nand_chip *nand_chip = mtd->priv; | 754 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
754 | struct atmel_nand_host *host = nand_chip->priv; | 755 | struct atmel_nand_host *host = nand_get_controller_data(nand_chip); |
755 | unsigned long end_time; | 756 | unsigned long end_time; |
756 | const int cap = host->pmecc_corr_cap; | 757 | const int cap = host->pmecc_corr_cap; |
757 | const int num = 2 * cap + 1; | 758 | const int num = 2 * cap + 1; |
@@ -802,8 +803,8 @@ static int pmecc_err_location(struct mtd_info *mtd) | |||
802 | static void pmecc_correct_data(struct mtd_info *mtd, uint8_t *buf, uint8_t *ecc, | 803 | static void pmecc_correct_data(struct mtd_info *mtd, uint8_t *buf, uint8_t *ecc, |
803 | int sector_num, int extra_bytes, int err_nbr) | 804 | int sector_num, int extra_bytes, int err_nbr) |
804 | { | 805 | { |
805 | struct nand_chip *nand_chip = mtd->priv; | 806 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
806 | struct atmel_nand_host *host = nand_chip->priv; | 807 | struct atmel_nand_host *host = nand_get_controller_data(nand_chip); |
807 | int i = 0; | 808 | int i = 0; |
808 | int byte_pos, bit_pos, sector_size, pos; | 809 | int byte_pos, bit_pos, sector_size, pos; |
809 | uint32_t tmp; | 810 | uint32_t tmp; |
@@ -848,8 +849,8 @@ static void pmecc_correct_data(struct mtd_info *mtd, uint8_t *buf, uint8_t *ecc, | |||
848 | static int pmecc_correction(struct mtd_info *mtd, u32 pmecc_stat, uint8_t *buf, | 849 | static int pmecc_correction(struct mtd_info *mtd, u32 pmecc_stat, uint8_t *buf, |
849 | u8 *ecc) | 850 | u8 *ecc) |
850 | { | 851 | { |
851 | struct nand_chip *nand_chip = mtd->priv; | 852 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
852 | struct atmel_nand_host *host = nand_chip->priv; | 853 | struct atmel_nand_host *host = nand_get_controller_data(nand_chip); |
853 | int i, err_nbr; | 854 | int i, err_nbr; |
854 | uint8_t *buf_pos; | 855 | uint8_t *buf_pos; |
855 | int max_bitflips = 0; | 856 | int max_bitflips = 0; |
@@ -919,7 +920,7 @@ static void pmecc_enable(struct atmel_nand_host *host, int ecc_op) | |||
919 | static int atmel_nand_pmecc_read_page(struct mtd_info *mtd, | 920 | static int atmel_nand_pmecc_read_page(struct mtd_info *mtd, |
920 | struct nand_chip *chip, uint8_t *buf, int oob_required, int page) | 921 | struct nand_chip *chip, uint8_t *buf, int oob_required, int page) |
921 | { | 922 | { |
922 | struct atmel_nand_host *host = chip->priv; | 923 | struct atmel_nand_host *host = nand_get_controller_data(chip); |
923 | int eccsize = chip->ecc.size * chip->ecc.steps; | 924 | int eccsize = chip->ecc.size * chip->ecc.steps; |
924 | uint8_t *oob = chip->oob_poi; | 925 | uint8_t *oob = chip->oob_poi; |
925 | uint32_t *eccpos = chip->ecc.layout->eccpos; | 926 | uint32_t *eccpos = chip->ecc.layout->eccpos; |
@@ -957,7 +958,7 @@ static int atmel_nand_pmecc_write_page(struct mtd_info *mtd, | |||
957 | struct nand_chip *chip, const uint8_t *buf, int oob_required, | 958 | struct nand_chip *chip, const uint8_t *buf, int oob_required, |
958 | int page) | 959 | int page) |
959 | { | 960 | { |
960 | struct atmel_nand_host *host = chip->priv; | 961 | struct atmel_nand_host *host = nand_get_controller_data(chip); |
961 | uint32_t *eccpos = chip->ecc.layout->eccpos; | 962 | uint32_t *eccpos = chip->ecc.layout->eccpos; |
962 | int i, j; | 963 | int i, j; |
963 | unsigned long end_time; | 964 | unsigned long end_time; |
@@ -992,8 +993,8 @@ static int atmel_nand_pmecc_write_page(struct mtd_info *mtd, | |||
992 | 993 | ||
993 | static void atmel_pmecc_core_init(struct mtd_info *mtd) | 994 | static void atmel_pmecc_core_init(struct mtd_info *mtd) |
994 | { | 995 | { |
995 | struct nand_chip *nand_chip = mtd->priv; | 996 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
996 | struct atmel_nand_host *host = nand_chip->priv; | 997 | struct atmel_nand_host *host = nand_get_controller_data(nand_chip); |
997 | uint32_t val = 0; | 998 | uint32_t val = 0; |
998 | struct nand_ecclayout *ecc_layout; | 999 | struct nand_ecclayout *ecc_layout; |
999 | 1000 | ||
@@ -1159,8 +1160,8 @@ static uint16_t *create_lookup_table(struct device *dev, int sector_size) | |||
1159 | static int atmel_pmecc_nand_init_params(struct platform_device *pdev, | 1160 | static int atmel_pmecc_nand_init_params(struct platform_device *pdev, |
1160 | struct atmel_nand_host *host) | 1161 | struct atmel_nand_host *host) |
1161 | { | 1162 | { |
1162 | struct mtd_info *mtd = &host->mtd; | ||
1163 | struct nand_chip *nand_chip = &host->nand_chip; | 1163 | struct nand_chip *nand_chip = &host->nand_chip; |
1164 | struct mtd_info *mtd = nand_to_mtd(nand_chip); | ||
1164 | struct resource *regs, *regs_pmerr, *regs_rom; | 1165 | struct resource *regs, *regs_pmerr, *regs_rom; |
1165 | uint16_t *galois_table; | 1166 | uint16_t *galois_table; |
1166 | int cap, sector_size, err_no; | 1167 | int cap, sector_size, err_no; |
@@ -1308,8 +1309,8 @@ err: | |||
1308 | static int atmel_nand_calculate(struct mtd_info *mtd, | 1309 | static int atmel_nand_calculate(struct mtd_info *mtd, |
1309 | const u_char *dat, unsigned char *ecc_code) | 1310 | const u_char *dat, unsigned char *ecc_code) |
1310 | { | 1311 | { |
1311 | struct nand_chip *nand_chip = mtd->priv; | 1312 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
1312 | struct atmel_nand_host *host = nand_chip->priv; | 1313 | struct atmel_nand_host *host = nand_get_controller_data(nand_chip); |
1313 | unsigned int ecc_value; | 1314 | unsigned int ecc_value; |
1314 | 1315 | ||
1315 | /* get the first 2 ECC bytes */ | 1316 | /* get the first 2 ECC bytes */ |
@@ -1355,7 +1356,7 @@ static int atmel_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1355 | * Workaround: Reset the parity registers before reading the | 1356 | * Workaround: Reset the parity registers before reading the |
1356 | * actual data. | 1357 | * actual data. |
1357 | */ | 1358 | */ |
1358 | struct atmel_nand_host *host = chip->priv; | 1359 | struct atmel_nand_host *host = nand_get_controller_data(chip); |
1359 | if (host->board.need_reset_workaround) | 1360 | if (host->board.need_reset_workaround) |
1360 | ecc_writel(host->ecc, CR, ATMEL_ECC_RST); | 1361 | ecc_writel(host->ecc, CR, ATMEL_ECC_RST); |
1361 | 1362 | ||
@@ -1412,8 +1413,8 @@ static int atmel_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1412 | static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat, | 1413 | static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat, |
1413 | u_char *read_ecc, u_char *isnull) | 1414 | u_char *read_ecc, u_char *isnull) |
1414 | { | 1415 | { |
1415 | struct nand_chip *nand_chip = mtd->priv; | 1416 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
1416 | struct atmel_nand_host *host = nand_chip->priv; | 1417 | struct atmel_nand_host *host = nand_get_controller_data(nand_chip); |
1417 | unsigned int ecc_status; | 1418 | unsigned int ecc_status; |
1418 | unsigned int ecc_word, ecc_bit; | 1419 | unsigned int ecc_word, ecc_bit; |
1419 | 1420 | ||
@@ -1444,7 +1445,7 @@ static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat, | |||
1444 | * We can't correct so many errors */ | 1445 | * We can't correct so many errors */ |
1445 | dev_dbg(host->dev, "atmel_nand : multiple errors detected." | 1446 | dev_dbg(host->dev, "atmel_nand : multiple errors detected." |
1446 | " Unable to correct.\n"); | 1447 | " Unable to correct.\n"); |
1447 | return -EIO; | 1448 | return -EBADMSG; |
1448 | } | 1449 | } |
1449 | 1450 | ||
1450 | /* if there's a single bit error : we can correct it */ | 1451 | /* if there's a single bit error : we can correct it */ |
@@ -1478,8 +1479,8 @@ static int atmel_nand_correct(struct mtd_info *mtd, u_char *dat, | |||
1478 | */ | 1479 | */ |
1479 | static void atmel_nand_hwctl(struct mtd_info *mtd, int mode) | 1480 | static void atmel_nand_hwctl(struct mtd_info *mtd, int mode) |
1480 | { | 1481 | { |
1481 | struct nand_chip *nand_chip = mtd->priv; | 1482 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
1482 | struct atmel_nand_host *host = nand_chip->priv; | 1483 | struct atmel_nand_host *host = nand_get_controller_data(nand_chip); |
1483 | 1484 | ||
1484 | if (host->board.need_reset_workaround) | 1485 | if (host->board.need_reset_workaround) |
1485 | ecc_writel(host->ecc, CR, ATMEL_ECC_RST); | 1486 | ecc_writel(host->ecc, CR, ATMEL_ECC_RST); |
@@ -1586,8 +1587,8 @@ static int atmel_of_init_port(struct atmel_nand_host *host, | |||
1586 | static int atmel_hw_nand_init_params(struct platform_device *pdev, | 1587 | static int atmel_hw_nand_init_params(struct platform_device *pdev, |
1587 | struct atmel_nand_host *host) | 1588 | struct atmel_nand_host *host) |
1588 | { | 1589 | { |
1589 | struct mtd_info *mtd = &host->mtd; | ||
1590 | struct nand_chip *nand_chip = &host->nand_chip; | 1590 | struct nand_chip *nand_chip = &host->nand_chip; |
1591 | struct mtd_info *mtd = nand_to_mtd(nand_chip); | ||
1591 | struct resource *regs; | 1592 | struct resource *regs; |
1592 | 1593 | ||
1593 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 1594 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
@@ -1771,8 +1772,8 @@ static int nfc_send_command(struct atmel_nand_host *host, | |||
1771 | static int nfc_device_ready(struct mtd_info *mtd) | 1772 | static int nfc_device_ready(struct mtd_info *mtd) |
1772 | { | 1773 | { |
1773 | u32 status, mask; | 1774 | u32 status, mask; |
1774 | struct nand_chip *nand_chip = mtd->priv; | 1775 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
1775 | struct atmel_nand_host *host = nand_chip->priv; | 1776 | struct atmel_nand_host *host = nand_get_controller_data(nand_chip); |
1776 | 1777 | ||
1777 | status = nfc_read_status(host); | 1778 | status = nfc_read_status(host); |
1778 | mask = nfc_readl(host->nfc->hsmc_regs, IMR); | 1779 | mask = nfc_readl(host->nfc->hsmc_regs, IMR); |
@@ -1787,8 +1788,8 @@ static int nfc_device_ready(struct mtd_info *mtd) | |||
1787 | 1788 | ||
1788 | static void nfc_select_chip(struct mtd_info *mtd, int chip) | 1789 | static void nfc_select_chip(struct mtd_info *mtd, int chip) |
1789 | { | 1790 | { |
1790 | struct nand_chip *nand_chip = mtd->priv; | 1791 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
1791 | struct atmel_nand_host *host = nand_chip->priv; | 1792 | struct atmel_nand_host *host = nand_get_controller_data(nand_chip); |
1792 | 1793 | ||
1793 | if (chip == -1) | 1794 | if (chip == -1) |
1794 | nfc_writel(host->nfc->hsmc_regs, CTRL, NFC_CTRL_DISABLE); | 1795 | nfc_writel(host->nfc->hsmc_regs, CTRL, NFC_CTRL_DISABLE); |
@@ -1799,7 +1800,7 @@ static void nfc_select_chip(struct mtd_info *mtd, int chip) | |||
1799 | static int nfc_make_addr(struct mtd_info *mtd, int command, int column, | 1800 | static int nfc_make_addr(struct mtd_info *mtd, int command, int column, |
1800 | int page_addr, unsigned int *addr1234, unsigned int *cycle0) | 1801 | int page_addr, unsigned int *addr1234, unsigned int *cycle0) |
1801 | { | 1802 | { |
1802 | struct nand_chip *chip = mtd->priv; | 1803 | struct nand_chip *chip = mtd_to_nand(mtd); |
1803 | 1804 | ||
1804 | int acycle = 0; | 1805 | int acycle = 0; |
1805 | unsigned char addr_bytes[8]; | 1806 | unsigned char addr_bytes[8]; |
@@ -1839,8 +1840,8 @@ static int nfc_make_addr(struct mtd_info *mtd, int command, int column, | |||
1839 | static void nfc_nand_command(struct mtd_info *mtd, unsigned int command, | 1840 | static void nfc_nand_command(struct mtd_info *mtd, unsigned int command, |
1840 | int column, int page_addr) | 1841 | int column, int page_addr) |
1841 | { | 1842 | { |
1842 | struct nand_chip *chip = mtd->priv; | 1843 | struct nand_chip *chip = mtd_to_nand(mtd); |
1843 | struct atmel_nand_host *host = chip->priv; | 1844 | struct atmel_nand_host *host = nand_get_controller_data(chip); |
1844 | unsigned long timeout; | 1845 | unsigned long timeout; |
1845 | unsigned int nfc_addr_cmd = 0; | 1846 | unsigned int nfc_addr_cmd = 0; |
1846 | 1847 | ||
@@ -1966,7 +1967,7 @@ static int nfc_sram_write_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1966 | { | 1967 | { |
1967 | int cfg, len; | 1968 | int cfg, len; |
1968 | int status = 0; | 1969 | int status = 0; |
1969 | struct atmel_nand_host *host = chip->priv; | 1970 | struct atmel_nand_host *host = nand_get_controller_data(chip); |
1970 | void *sram = host->nfc->sram_bank0 + nfc_get_sram_off(host); | 1971 | void *sram = host->nfc->sram_bank0 + nfc_get_sram_off(host); |
1971 | 1972 | ||
1972 | /* Subpage write is not supported */ | 1973 | /* Subpage write is not supported */ |
@@ -2026,8 +2027,8 @@ static int nfc_sram_write_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
2026 | 2027 | ||
2027 | static int nfc_sram_init(struct mtd_info *mtd) | 2028 | static int nfc_sram_init(struct mtd_info *mtd) |
2028 | { | 2029 | { |
2029 | struct nand_chip *chip = mtd->priv; | 2030 | struct nand_chip *chip = mtd_to_nand(mtd); |
2030 | struct atmel_nand_host *host = chip->priv; | 2031 | struct atmel_nand_host *host = nand_get_controller_data(chip); |
2031 | int res = 0; | 2032 | int res = 0; |
2032 | 2033 | ||
2033 | /* Initialize the NFC CFG register */ | 2034 | /* Initialize the NFC CFG register */ |
@@ -2093,7 +2094,6 @@ static int atmel_nand_probe(struct platform_device *pdev) | |||
2093 | struct mtd_info *mtd; | 2094 | struct mtd_info *mtd; |
2094 | struct nand_chip *nand_chip; | 2095 | struct nand_chip *nand_chip; |
2095 | struct resource *mem; | 2096 | struct resource *mem; |
2096 | struct mtd_part_parser_data ppdata = {}; | ||
2097 | int res, irq; | 2097 | int res, irq; |
2098 | 2098 | ||
2099 | /* Allocate memory for the device structure (and zero it) */ | 2099 | /* Allocate memory for the device structure (and zero it) */ |
@@ -2113,10 +2113,11 @@ static int atmel_nand_probe(struct platform_device *pdev) | |||
2113 | } | 2113 | } |
2114 | host->io_phys = (dma_addr_t)mem->start; | 2114 | host->io_phys = (dma_addr_t)mem->start; |
2115 | 2115 | ||
2116 | mtd = &host->mtd; | ||
2117 | nand_chip = &host->nand_chip; | 2116 | nand_chip = &host->nand_chip; |
2117 | mtd = nand_to_mtd(nand_chip); | ||
2118 | host->dev = &pdev->dev; | 2118 | host->dev = &pdev->dev; |
2119 | if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) { | 2119 | if (IS_ENABLED(CONFIG_OF) && pdev->dev.of_node) { |
2120 | nand_set_flash_node(nand_chip, pdev->dev.of_node); | ||
2120 | /* Only when CONFIG_OF is enabled of_node can be parsed */ | 2121 | /* Only when CONFIG_OF is enabled of_node can be parsed */ |
2121 | res = atmel_of_init_port(host, pdev->dev.of_node); | 2122 | res = atmel_of_init_port(host, pdev->dev.of_node); |
2122 | if (res) | 2123 | if (res) |
@@ -2126,8 +2127,8 @@ static int atmel_nand_probe(struct platform_device *pdev) | |||
2126 | sizeof(struct atmel_nand_data)); | 2127 | sizeof(struct atmel_nand_data)); |
2127 | } | 2128 | } |
2128 | 2129 | ||
2129 | nand_chip->priv = host; /* link the private data structures */ | 2130 | /* link the private data structures */ |
2130 | mtd->priv = nand_chip; | 2131 | nand_set_controller_data(nand_chip, host); |
2131 | mtd->dev.parent = &pdev->dev; | 2132 | mtd->dev.parent = &pdev->dev; |
2132 | 2133 | ||
2133 | /* Set address of NAND IO lines */ | 2134 | /* Set address of NAND IO lines */ |
@@ -2259,9 +2260,8 @@ static int atmel_nand_probe(struct platform_device *pdev) | |||
2259 | } | 2260 | } |
2260 | 2261 | ||
2261 | mtd->name = "atmel_nand"; | 2262 | mtd->name = "atmel_nand"; |
2262 | ppdata.of_node = pdev->dev.of_node; | 2263 | res = mtd_device_register(mtd, host->board.parts, |
2263 | res = mtd_device_parse_register(mtd, NULL, &ppdata, | 2264 | host->board.num_parts); |
2264 | host->board.parts, host->board.num_parts); | ||
2265 | if (!res) | 2265 | if (!res) |
2266 | return res; | 2266 | return res; |
2267 | 2267 | ||
@@ -2284,7 +2284,7 @@ err_nand_ioremap: | |||
2284 | static int atmel_nand_remove(struct platform_device *pdev) | 2284 | static int atmel_nand_remove(struct platform_device *pdev) |
2285 | { | 2285 | { |
2286 | struct atmel_nand_host *host = platform_get_drvdata(pdev); | 2286 | struct atmel_nand_host *host = platform_get_drvdata(pdev); |
2287 | struct mtd_info *mtd = &host->mtd; | 2287 | struct mtd_info *mtd = nand_to_mtd(&host->nand_chip); |
2288 | 2288 | ||
2289 | nand_release(mtd); | 2289 | nand_release(mtd); |
2290 | 2290 | ||
@@ -2304,11 +2304,11 @@ static int atmel_nand_remove(struct platform_device *pdev) | |||
2304 | return 0; | 2304 | return 0; |
2305 | } | 2305 | } |
2306 | 2306 | ||
2307 | static struct atmel_nand_caps at91rm9200_caps = { | 2307 | static const struct atmel_nand_caps at91rm9200_caps = { |
2308 | .pmecc_correct_erase_page = false, | 2308 | .pmecc_correct_erase_page = false, |
2309 | }; | 2309 | }; |
2310 | 2310 | ||
2311 | static struct atmel_nand_caps sama5d4_caps = { | 2311 | static const struct atmel_nand_caps sama5d4_caps = { |
2312 | .pmecc_correct_erase_page = true, | 2312 | .pmecc_correct_erase_page = true, |
2313 | }; | 2313 | }; |
2314 | 2314 | ||
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c index 08a130f63faf..341ea4904164 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/au1550nd.c | |||
@@ -23,7 +23,6 @@ | |||
23 | 23 | ||
24 | 24 | ||
25 | struct au1550nd_ctx { | 25 | struct au1550nd_ctx { |
26 | struct mtd_info info; | ||
27 | struct nand_chip chip; | 26 | struct nand_chip chip; |
28 | 27 | ||
29 | int cs; | 28 | int cs; |
@@ -39,7 +38,7 @@ struct au1550nd_ctx { | |||
39 | */ | 38 | */ |
40 | static u_char au_read_byte(struct mtd_info *mtd) | 39 | static u_char au_read_byte(struct mtd_info *mtd) |
41 | { | 40 | { |
42 | struct nand_chip *this = mtd->priv; | 41 | struct nand_chip *this = mtd_to_nand(mtd); |
43 | u_char ret = readb(this->IO_ADDR_R); | 42 | u_char ret = readb(this->IO_ADDR_R); |
44 | wmb(); /* drain writebuffer */ | 43 | wmb(); /* drain writebuffer */ |
45 | return ret; | 44 | return ret; |
@@ -54,7 +53,7 @@ static u_char au_read_byte(struct mtd_info *mtd) | |||
54 | */ | 53 | */ |
55 | static void au_write_byte(struct mtd_info *mtd, u_char byte) | 54 | static void au_write_byte(struct mtd_info *mtd, u_char byte) |
56 | { | 55 | { |
57 | struct nand_chip *this = mtd->priv; | 56 | struct nand_chip *this = mtd_to_nand(mtd); |
58 | writeb(byte, this->IO_ADDR_W); | 57 | writeb(byte, this->IO_ADDR_W); |
59 | wmb(); /* drain writebuffer */ | 58 | wmb(); /* drain writebuffer */ |
60 | } | 59 | } |
@@ -67,7 +66,7 @@ static void au_write_byte(struct mtd_info *mtd, u_char byte) | |||
67 | */ | 66 | */ |
68 | static u_char au_read_byte16(struct mtd_info *mtd) | 67 | static u_char au_read_byte16(struct mtd_info *mtd) |
69 | { | 68 | { |
70 | struct nand_chip *this = mtd->priv; | 69 | struct nand_chip *this = mtd_to_nand(mtd); |
71 | u_char ret = (u_char) cpu_to_le16(readw(this->IO_ADDR_R)); | 70 | u_char ret = (u_char) cpu_to_le16(readw(this->IO_ADDR_R)); |
72 | wmb(); /* drain writebuffer */ | 71 | wmb(); /* drain writebuffer */ |
73 | return ret; | 72 | return ret; |
@@ -82,7 +81,7 @@ static u_char au_read_byte16(struct mtd_info *mtd) | |||
82 | */ | 81 | */ |
83 | static void au_write_byte16(struct mtd_info *mtd, u_char byte) | 82 | static void au_write_byte16(struct mtd_info *mtd, u_char byte) |
84 | { | 83 | { |
85 | struct nand_chip *this = mtd->priv; | 84 | struct nand_chip *this = mtd_to_nand(mtd); |
86 | writew(le16_to_cpu((u16) byte), this->IO_ADDR_W); | 85 | writew(le16_to_cpu((u16) byte), this->IO_ADDR_W); |
87 | wmb(); /* drain writebuffer */ | 86 | wmb(); /* drain writebuffer */ |
88 | } | 87 | } |
@@ -95,7 +94,7 @@ static void au_write_byte16(struct mtd_info *mtd, u_char byte) | |||
95 | */ | 94 | */ |
96 | static u16 au_read_word(struct mtd_info *mtd) | 95 | static u16 au_read_word(struct mtd_info *mtd) |
97 | { | 96 | { |
98 | struct nand_chip *this = mtd->priv; | 97 | struct nand_chip *this = mtd_to_nand(mtd); |
99 | u16 ret = readw(this->IO_ADDR_R); | 98 | u16 ret = readw(this->IO_ADDR_R); |
100 | wmb(); /* drain writebuffer */ | 99 | wmb(); /* drain writebuffer */ |
101 | return ret; | 100 | return ret; |
@@ -112,7 +111,7 @@ static u16 au_read_word(struct mtd_info *mtd) | |||
112 | static void au_write_buf(struct mtd_info *mtd, const u_char *buf, int len) | 111 | static void au_write_buf(struct mtd_info *mtd, const u_char *buf, int len) |
113 | { | 112 | { |
114 | int i; | 113 | int i; |
115 | struct nand_chip *this = mtd->priv; | 114 | struct nand_chip *this = mtd_to_nand(mtd); |
116 | 115 | ||
117 | for (i = 0; i < len; i++) { | 116 | for (i = 0; i < len; i++) { |
118 | writeb(buf[i], this->IO_ADDR_W); | 117 | writeb(buf[i], this->IO_ADDR_W); |
@@ -131,7 +130,7 @@ static void au_write_buf(struct mtd_info *mtd, const u_char *buf, int len) | |||
131 | static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len) | 130 | static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len) |
132 | { | 131 | { |
133 | int i; | 132 | int i; |
134 | struct nand_chip *this = mtd->priv; | 133 | struct nand_chip *this = mtd_to_nand(mtd); |
135 | 134 | ||
136 | for (i = 0; i < len; i++) { | 135 | for (i = 0; i < len; i++) { |
137 | buf[i] = readb(this->IO_ADDR_R); | 136 | buf[i] = readb(this->IO_ADDR_R); |
@@ -150,7 +149,7 @@ static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len) | |||
150 | static void au_write_buf16(struct mtd_info *mtd, const u_char *buf, int len) | 149 | static void au_write_buf16(struct mtd_info *mtd, const u_char *buf, int len) |
151 | { | 150 | { |
152 | int i; | 151 | int i; |
153 | struct nand_chip *this = mtd->priv; | 152 | struct nand_chip *this = mtd_to_nand(mtd); |
154 | u16 *p = (u16 *) buf; | 153 | u16 *p = (u16 *) buf; |
155 | len >>= 1; | 154 | len >>= 1; |
156 | 155 | ||
@@ -172,7 +171,7 @@ static void au_write_buf16(struct mtd_info *mtd, const u_char *buf, int len) | |||
172 | static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len) | 171 | static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len) |
173 | { | 172 | { |
174 | int i; | 173 | int i; |
175 | struct nand_chip *this = mtd->priv; | 174 | struct nand_chip *this = mtd_to_nand(mtd); |
176 | u16 *p = (u16 *) buf; | 175 | u16 *p = (u16 *) buf; |
177 | len >>= 1; | 176 | len >>= 1; |
178 | 177 | ||
@@ -197,8 +196,9 @@ static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len) | |||
197 | 196 | ||
198 | static void au1550_hwcontrol(struct mtd_info *mtd, int cmd) | 197 | static void au1550_hwcontrol(struct mtd_info *mtd, int cmd) |
199 | { | 198 | { |
200 | struct au1550nd_ctx *ctx = container_of(mtd, struct au1550nd_ctx, info); | 199 | struct nand_chip *this = mtd_to_nand(mtd); |
201 | struct nand_chip *this = mtd->priv; | 200 | struct au1550nd_ctx *ctx = container_of(this, struct au1550nd_ctx, |
201 | chip); | ||
202 | 202 | ||
203 | switch (cmd) { | 203 | switch (cmd) { |
204 | 204 | ||
@@ -267,8 +267,9 @@ static void au1550_select_chip(struct mtd_info *mtd, int chip) | |||
267 | */ | 267 | */ |
268 | static void au1550_command(struct mtd_info *mtd, unsigned command, int column, int page_addr) | 268 | static void au1550_command(struct mtd_info *mtd, unsigned command, int column, int page_addr) |
269 | { | 269 | { |
270 | struct au1550nd_ctx *ctx = container_of(mtd, struct au1550nd_ctx, info); | 270 | struct nand_chip *this = mtd_to_nand(mtd); |
271 | struct nand_chip *this = mtd->priv; | 271 | struct au1550nd_ctx *ctx = container_of(this, struct au1550nd_ctx, |
272 | chip); | ||
272 | int ce_override = 0, i; | 273 | int ce_override = 0, i; |
273 | unsigned long flags = 0; | 274 | unsigned long flags = 0; |
274 | 275 | ||
@@ -405,6 +406,7 @@ static int au1550nd_probe(struct platform_device *pdev) | |||
405 | struct au1550nd_platdata *pd; | 406 | struct au1550nd_platdata *pd; |
406 | struct au1550nd_ctx *ctx; | 407 | struct au1550nd_ctx *ctx; |
407 | struct nand_chip *this; | 408 | struct nand_chip *this; |
409 | struct mtd_info *mtd; | ||
408 | struct resource *r; | 410 | struct resource *r; |
409 | int ret, cs; | 411 | int ret, cs; |
410 | 412 | ||
@@ -438,8 +440,8 @@ static int au1550nd_probe(struct platform_device *pdev) | |||
438 | } | 440 | } |
439 | 441 | ||
440 | this = &ctx->chip; | 442 | this = &ctx->chip; |
441 | ctx->info.priv = this; | 443 | mtd = nand_to_mtd(this); |
442 | ctx->info.dev.parent = &pdev->dev; | 444 | mtd->dev.parent = &pdev->dev; |
443 | 445 | ||
444 | /* figure out which CS# r->start belongs to */ | 446 | /* figure out which CS# r->start belongs to */ |
445 | cs = find_nand_cs(r->start); | 447 | cs = find_nand_cs(r->start); |
@@ -467,13 +469,13 @@ static int au1550nd_probe(struct platform_device *pdev) | |||
467 | this->write_buf = (pd->devwidth) ? au_write_buf16 : au_write_buf; | 469 | this->write_buf = (pd->devwidth) ? au_write_buf16 : au_write_buf; |
468 | this->read_buf = (pd->devwidth) ? au_read_buf16 : au_read_buf; | 470 | this->read_buf = (pd->devwidth) ? au_read_buf16 : au_read_buf; |
469 | 471 | ||
470 | ret = nand_scan(&ctx->info, 1); | 472 | ret = nand_scan(mtd, 1); |
471 | if (ret) { | 473 | if (ret) { |
472 | dev_err(&pdev->dev, "NAND scan failed with %d\n", ret); | 474 | dev_err(&pdev->dev, "NAND scan failed with %d\n", ret); |
473 | goto out3; | 475 | goto out3; |
474 | } | 476 | } |
475 | 477 | ||
476 | mtd_device_register(&ctx->info, pd->parts, pd->num_parts); | 478 | mtd_device_register(mtd, pd->parts, pd->num_parts); |
477 | 479 | ||
478 | platform_set_drvdata(pdev, ctx); | 480 | platform_set_drvdata(pdev, ctx); |
479 | 481 | ||
@@ -493,7 +495,7 @@ static int au1550nd_remove(struct platform_device *pdev) | |||
493 | struct au1550nd_ctx *ctx = platform_get_drvdata(pdev); | 495 | struct au1550nd_ctx *ctx = platform_get_drvdata(pdev); |
494 | struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 496 | struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
495 | 497 | ||
496 | nand_release(&ctx->info); | 498 | nand_release(nand_to_mtd(&ctx->chip)); |
497 | iounmap(ctx->base); | 499 | iounmap(ctx->base); |
498 | release_mem_region(r->start, 0x1000); | 500 | release_mem_region(r->start, 0x1000); |
499 | kfree(ctx); | 501 | kfree(ctx); |
diff --git a/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h b/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h index c005a62330b1..8ea75710a854 100644 --- a/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h +++ b/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h | |||
@@ -12,7 +12,6 @@ struct bcm47xxnflash { | |||
12 | struct bcma_drv_cc *cc; | 12 | struct bcma_drv_cc *cc; |
13 | 13 | ||
14 | struct nand_chip nand_chip; | 14 | struct nand_chip nand_chip; |
15 | struct mtd_info mtd; | ||
16 | 15 | ||
17 | unsigned curr_command; | 16 | unsigned curr_command; |
18 | int curr_page_addr; | 17 | int curr_page_addr; |
diff --git a/drivers/mtd/nand/bcm47xxnflash/main.c b/drivers/mtd/nand/bcm47xxnflash/main.c index 9ba0c0f2cd9b..fb31429b70a9 100644 --- a/drivers/mtd/nand/bcm47xxnflash/main.c +++ b/drivers/mtd/nand/bcm47xxnflash/main.c | |||
@@ -27,15 +27,16 @@ static int bcm47xxnflash_probe(struct platform_device *pdev) | |||
27 | { | 27 | { |
28 | struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev); | 28 | struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev); |
29 | struct bcm47xxnflash *b47n; | 29 | struct bcm47xxnflash *b47n; |
30 | struct mtd_info *mtd; | ||
30 | int err = 0; | 31 | int err = 0; |
31 | 32 | ||
32 | b47n = devm_kzalloc(&pdev->dev, sizeof(*b47n), GFP_KERNEL); | 33 | b47n = devm_kzalloc(&pdev->dev, sizeof(*b47n), GFP_KERNEL); |
33 | if (!b47n) | 34 | if (!b47n) |
34 | return -ENOMEM; | 35 | return -ENOMEM; |
35 | 36 | ||
36 | b47n->nand_chip.priv = b47n; | 37 | nand_set_controller_data(&b47n->nand_chip, b47n); |
37 | b47n->mtd.dev.parent = &pdev->dev; | 38 | mtd = nand_to_mtd(&b47n->nand_chip); |
38 | b47n->mtd.priv = &b47n->nand_chip; /* Required */ | 39 | mtd->dev.parent = &pdev->dev; |
39 | b47n->cc = container_of(nflash, struct bcma_drv_cc, nflash); | 40 | b47n->cc = container_of(nflash, struct bcma_drv_cc, nflash); |
40 | 41 | ||
41 | if (b47n->cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) { | 42 | if (b47n->cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) { |
@@ -49,7 +50,9 @@ static int bcm47xxnflash_probe(struct platform_device *pdev) | |||
49 | return err; | 50 | return err; |
50 | } | 51 | } |
51 | 52 | ||
52 | err = mtd_device_parse_register(&b47n->mtd, probes, NULL, NULL, 0); | 53 | platform_set_drvdata(pdev, b47n); |
54 | |||
55 | err = mtd_device_parse_register(mtd, probes, NULL, NULL, 0); | ||
53 | if (err) { | 56 | if (err) { |
54 | pr_err("Failed to register MTD device: %d\n", err); | 57 | pr_err("Failed to register MTD device: %d\n", err); |
55 | return err; | 58 | return err; |
@@ -60,10 +63,9 @@ static int bcm47xxnflash_probe(struct platform_device *pdev) | |||
60 | 63 | ||
61 | static int bcm47xxnflash_remove(struct platform_device *pdev) | 64 | static int bcm47xxnflash_remove(struct platform_device *pdev) |
62 | { | 65 | { |
63 | struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev); | 66 | struct bcm47xxnflash *nflash = platform_get_drvdata(pdev); |
64 | 67 | ||
65 | if (nflash->mtd) | 68 | nand_release(nand_to_mtd(&nflash->nand_chip)); |
66 | mtd_device_unregister(nflash->mtd); | ||
67 | 69 | ||
68 | return 0; | 70 | return 0; |
69 | } | 71 | } |
diff --git a/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c b/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c index 592befc7ffa1..f1da4ea88f2c 100644 --- a/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c +++ b/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c | |||
@@ -89,8 +89,8 @@ static int bcm47xxnflash_ops_bcm4706_poll(struct bcma_drv_cc *cc) | |||
89 | static void bcm47xxnflash_ops_bcm4706_read(struct mtd_info *mtd, uint8_t *buf, | 89 | static void bcm47xxnflash_ops_bcm4706_read(struct mtd_info *mtd, uint8_t *buf, |
90 | int len) | 90 | int len) |
91 | { | 91 | { |
92 | struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; | 92 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
93 | struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; | 93 | struct bcm47xxnflash *b47n = nand_get_controller_data(nand_chip); |
94 | 94 | ||
95 | u32 ctlcode; | 95 | u32 ctlcode; |
96 | u32 *dest = (u32 *)buf; | 96 | u32 *dest = (u32 *)buf; |
@@ -139,8 +139,8 @@ static void bcm47xxnflash_ops_bcm4706_read(struct mtd_info *mtd, uint8_t *buf, | |||
139 | static void bcm47xxnflash_ops_bcm4706_write(struct mtd_info *mtd, | 139 | static void bcm47xxnflash_ops_bcm4706_write(struct mtd_info *mtd, |
140 | const uint8_t *buf, int len) | 140 | const uint8_t *buf, int len) |
141 | { | 141 | { |
142 | struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; | 142 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
143 | struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; | 143 | struct bcm47xxnflash *b47n = nand_get_controller_data(nand_chip); |
144 | struct bcma_drv_cc *cc = b47n->cc; | 144 | struct bcma_drv_cc *cc = b47n->cc; |
145 | 145 | ||
146 | u32 ctlcode; | 146 | u32 ctlcode; |
@@ -173,8 +173,8 @@ static void bcm47xxnflash_ops_bcm4706_write(struct mtd_info *mtd, | |||
173 | static void bcm47xxnflash_ops_bcm4706_cmd_ctrl(struct mtd_info *mtd, int cmd, | 173 | static void bcm47xxnflash_ops_bcm4706_cmd_ctrl(struct mtd_info *mtd, int cmd, |
174 | unsigned int ctrl) | 174 | unsigned int ctrl) |
175 | { | 175 | { |
176 | struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; | 176 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
177 | struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; | 177 | struct bcm47xxnflash *b47n = nand_get_controller_data(nand_chip); |
178 | u32 code = 0; | 178 | u32 code = 0; |
179 | 179 | ||
180 | if (cmd == NAND_CMD_NONE) | 180 | if (cmd == NAND_CMD_NONE) |
@@ -199,8 +199,8 @@ static void bcm47xxnflash_ops_bcm4706_select_chip(struct mtd_info *mtd, | |||
199 | 199 | ||
200 | static int bcm47xxnflash_ops_bcm4706_dev_ready(struct mtd_info *mtd) | 200 | static int bcm47xxnflash_ops_bcm4706_dev_ready(struct mtd_info *mtd) |
201 | { | 201 | { |
202 | struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; | 202 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
203 | struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; | 203 | struct bcm47xxnflash *b47n = nand_get_controller_data(nand_chip); |
204 | 204 | ||
205 | return !!(bcma_cc_read32(b47n->cc, BCMA_CC_NFLASH_CTL) & NCTL_READY); | 205 | return !!(bcma_cc_read32(b47n->cc, BCMA_CC_NFLASH_CTL) & NCTL_READY); |
206 | } | 206 | } |
@@ -216,8 +216,8 @@ static void bcm47xxnflash_ops_bcm4706_cmdfunc(struct mtd_info *mtd, | |||
216 | unsigned command, int column, | 216 | unsigned command, int column, |
217 | int page_addr) | 217 | int page_addr) |
218 | { | 218 | { |
219 | struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; | 219 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
220 | struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; | 220 | struct bcm47xxnflash *b47n = nand_get_controller_data(nand_chip); |
221 | struct bcma_drv_cc *cc = b47n->cc; | 221 | struct bcma_drv_cc *cc = b47n->cc; |
222 | u32 ctlcode; | 222 | u32 ctlcode; |
223 | int i; | 223 | int i; |
@@ -312,8 +312,8 @@ static void bcm47xxnflash_ops_bcm4706_cmdfunc(struct mtd_info *mtd, | |||
312 | 312 | ||
313 | static u8 bcm47xxnflash_ops_bcm4706_read_byte(struct mtd_info *mtd) | 313 | static u8 bcm47xxnflash_ops_bcm4706_read_byte(struct mtd_info *mtd) |
314 | { | 314 | { |
315 | struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; | 315 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
316 | struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; | 316 | struct bcm47xxnflash *b47n = nand_get_controller_data(nand_chip); |
317 | struct bcma_drv_cc *cc = b47n->cc; | 317 | struct bcma_drv_cc *cc = b47n->cc; |
318 | u32 tmp = 0; | 318 | u32 tmp = 0; |
319 | 319 | ||
@@ -341,8 +341,8 @@ static u8 bcm47xxnflash_ops_bcm4706_read_byte(struct mtd_info *mtd) | |||
341 | static void bcm47xxnflash_ops_bcm4706_read_buf(struct mtd_info *mtd, | 341 | static void bcm47xxnflash_ops_bcm4706_read_buf(struct mtd_info *mtd, |
342 | uint8_t *buf, int len) | 342 | uint8_t *buf, int len) |
343 | { | 343 | { |
344 | struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; | 344 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
345 | struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; | 345 | struct bcm47xxnflash *b47n = nand_get_controller_data(nand_chip); |
346 | 346 | ||
347 | switch (b47n->curr_command) { | 347 | switch (b47n->curr_command) { |
348 | case NAND_CMD_READ0: | 348 | case NAND_CMD_READ0: |
@@ -357,8 +357,8 @@ static void bcm47xxnflash_ops_bcm4706_read_buf(struct mtd_info *mtd, | |||
357 | static void bcm47xxnflash_ops_bcm4706_write_buf(struct mtd_info *mtd, | 357 | static void bcm47xxnflash_ops_bcm4706_write_buf(struct mtd_info *mtd, |
358 | const uint8_t *buf, int len) | 358 | const uint8_t *buf, int len) |
359 | { | 359 | { |
360 | struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; | 360 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
361 | struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; | 361 | struct bcm47xxnflash *b47n = nand_get_controller_data(nand_chip); |
362 | 362 | ||
363 | switch (b47n->curr_command) { | 363 | switch (b47n->curr_command) { |
364 | case NAND_CMD_SEQIN: | 364 | case NAND_CMD_SEQIN: |
@@ -421,7 +421,7 @@ int bcm47xxnflash_ops_bcm4706_init(struct bcm47xxnflash *b47n) | |||
421 | (w4 << 24 | w3 << 18 | w2 << 12 | w1 << 6 | w0)); | 421 | (w4 << 24 | w3 << 18 | w2 << 12 | w1 << 6 | w0)); |
422 | 422 | ||
423 | /* Scan NAND */ | 423 | /* Scan NAND */ |
424 | err = nand_scan(&b47n->mtd, 1); | 424 | err = nand_scan(nand_to_mtd(&b47n->nand_chip), 1); |
425 | if (err) { | 425 | if (err) { |
426 | pr_err("Could not scan NAND flash: %d\n", err); | 426 | pr_err("Could not scan NAND flash: %d\n", err); |
427 | goto exit; | 427 | goto exit; |
diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c index 61bd2160717c..7f6b30e615b7 100644 --- a/drivers/mtd/nand/bf5xx_nand.c +++ b/drivers/mtd/nand/bf5xx_nand.c | |||
@@ -142,7 +142,6 @@ static struct nand_ecclayout bootrom_ecclayout = { | |||
142 | struct bf5xx_nand_info { | 142 | struct bf5xx_nand_info { |
143 | /* mtd info */ | 143 | /* mtd info */ |
144 | struct nand_hw_control controller; | 144 | struct nand_hw_control controller; |
145 | struct mtd_info mtd; | ||
146 | struct nand_chip chip; | 145 | struct nand_chip chip; |
147 | 146 | ||
148 | /* platform info */ | 147 | /* platform info */ |
@@ -160,7 +159,8 @@ struct bf5xx_nand_info { | |||
160 | */ | 159 | */ |
161 | static struct bf5xx_nand_info *mtd_to_nand_info(struct mtd_info *mtd) | 160 | static struct bf5xx_nand_info *mtd_to_nand_info(struct mtd_info *mtd) |
162 | { | 161 | { |
163 | return container_of(mtd, struct bf5xx_nand_info, mtd); | 162 | return container_of(mtd_to_nand(mtd), struct bf5xx_nand_info, |
163 | chip); | ||
164 | } | 164 | } |
165 | 165 | ||
166 | static struct bf5xx_nand_info *to_nand_info(struct platform_device *pdev) | 166 | static struct bf5xx_nand_info *to_nand_info(struct platform_device *pdev) |
@@ -252,7 +252,7 @@ static int bf5xx_nand_correct_data_256(struct mtd_info *mtd, u_char *dat, | |||
252 | */ | 252 | */ |
253 | if (hweight32(syndrome[0]) == 1) { | 253 | if (hweight32(syndrome[0]) == 1) { |
254 | dev_err(info->device, "ECC data was incorrect!\n"); | 254 | dev_err(info->device, "ECC data was incorrect!\n"); |
255 | return 1; | 255 | return -EBADMSG; |
256 | } | 256 | } |
257 | 257 | ||
258 | syndrome[1] = (calced & 0x7FF) ^ (stored & 0x7FF); | 258 | syndrome[1] = (calced & 0x7FF) ^ (stored & 0x7FF); |
@@ -285,7 +285,7 @@ static int bf5xx_nand_correct_data_256(struct mtd_info *mtd, u_char *dat, | |||
285 | data = data ^ (0x1 << failing_bit); | 285 | data = data ^ (0x1 << failing_bit); |
286 | *(dat + failing_byte) = data; | 286 | *(dat + failing_byte) = data; |
287 | 287 | ||
288 | return 0; | 288 | return 1; |
289 | } | 289 | } |
290 | 290 | ||
291 | /* | 291 | /* |
@@ -298,26 +298,34 @@ static int bf5xx_nand_correct_data_256(struct mtd_info *mtd, u_char *dat, | |||
298 | dev_err(info->device, | 298 | dev_err(info->device, |
299 | "Please discard data, mark bad block\n"); | 299 | "Please discard data, mark bad block\n"); |
300 | 300 | ||
301 | return 1; | 301 | return -EBADMSG; |
302 | } | 302 | } |
303 | 303 | ||
304 | static int bf5xx_nand_correct_data(struct mtd_info *mtd, u_char *dat, | 304 | static int bf5xx_nand_correct_data(struct mtd_info *mtd, u_char *dat, |
305 | u_char *read_ecc, u_char *calc_ecc) | 305 | u_char *read_ecc, u_char *calc_ecc) |
306 | { | 306 | { |
307 | struct nand_chip *chip = mtd->priv; | 307 | struct nand_chip *chip = mtd_to_nand(mtd); |
308 | int ret; | 308 | int ret, bitflips = 0; |
309 | 309 | ||
310 | ret = bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc); | 310 | ret = bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc); |
311 | if (ret < 0) | ||
312 | return ret; | ||
313 | |||
314 | bitflips = ret; | ||
311 | 315 | ||
312 | /* If ecc size is 512, correct second 256 bytes */ | 316 | /* If ecc size is 512, correct second 256 bytes */ |
313 | if (chip->ecc.size == 512) { | 317 | if (chip->ecc.size == 512) { |
314 | dat += 256; | 318 | dat += 256; |
315 | read_ecc += 3; | 319 | read_ecc += 3; |
316 | calc_ecc += 3; | 320 | calc_ecc += 3; |
317 | ret |= bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc); | 321 | ret = bf5xx_nand_correct_data_256(mtd, dat, read_ecc, calc_ecc); |
322 | if (ret < 0) | ||
323 | return ret; | ||
324 | |||
325 | bitflips += ret; | ||
318 | } | 326 | } |
319 | 327 | ||
320 | return ret; | 328 | return bitflips; |
321 | } | 329 | } |
322 | 330 | ||
323 | static void bf5xx_nand_enable_hwecc(struct mtd_info *mtd, int mode) | 331 | static void bf5xx_nand_enable_hwecc(struct mtd_info *mtd, int mode) |
@@ -329,7 +337,7 @@ static int bf5xx_nand_calculate_ecc(struct mtd_info *mtd, | |||
329 | const u_char *dat, u_char *ecc_code) | 337 | const u_char *dat, u_char *ecc_code) |
330 | { | 338 | { |
331 | struct bf5xx_nand_info *info = mtd_to_nand_info(mtd); | 339 | struct bf5xx_nand_info *info = mtd_to_nand_info(mtd); |
332 | struct nand_chip *chip = mtd->priv; | 340 | struct nand_chip *chip = mtd_to_nand(mtd); |
333 | u16 ecc0, ecc1; | 341 | u16 ecc0, ecc1; |
334 | u32 code[2]; | 342 | u32 code[2]; |
335 | u8 *p; | 343 | u8 *p; |
@@ -466,7 +474,7 @@ static void bf5xx_nand_dma_rw(struct mtd_info *mtd, | |||
466 | uint8_t *buf, int is_read) | 474 | uint8_t *buf, int is_read) |
467 | { | 475 | { |
468 | struct bf5xx_nand_info *info = mtd_to_nand_info(mtd); | 476 | struct bf5xx_nand_info *info = mtd_to_nand_info(mtd); |
469 | struct nand_chip *chip = mtd->priv; | 477 | struct nand_chip *chip = mtd_to_nand(mtd); |
470 | unsigned short val; | 478 | unsigned short val; |
471 | 479 | ||
472 | dev_dbg(info->device, " mtd->%p, buf->%p, is_read %d\n", | 480 | dev_dbg(info->device, " mtd->%p, buf->%p, is_read %d\n", |
@@ -532,7 +540,7 @@ static void bf5xx_nand_dma_read_buf(struct mtd_info *mtd, | |||
532 | uint8_t *buf, int len) | 540 | uint8_t *buf, int len) |
533 | { | 541 | { |
534 | struct bf5xx_nand_info *info = mtd_to_nand_info(mtd); | 542 | struct bf5xx_nand_info *info = mtd_to_nand_info(mtd); |
535 | struct nand_chip *chip = mtd->priv; | 543 | struct nand_chip *chip = mtd_to_nand(mtd); |
536 | 544 | ||
537 | dev_dbg(info->device, "mtd->%p, buf->%p, int %d\n", mtd, buf, len); | 545 | dev_dbg(info->device, "mtd->%p, buf->%p, int %d\n", mtd, buf, len); |
538 | 546 | ||
@@ -546,7 +554,7 @@ static void bf5xx_nand_dma_write_buf(struct mtd_info *mtd, | |||
546 | const uint8_t *buf, int len) | 554 | const uint8_t *buf, int len) |
547 | { | 555 | { |
548 | struct bf5xx_nand_info *info = mtd_to_nand_info(mtd); | 556 | struct bf5xx_nand_info *info = mtd_to_nand_info(mtd); |
549 | struct nand_chip *chip = mtd->priv; | 557 | struct nand_chip *chip = mtd_to_nand(mtd); |
550 | 558 | ||
551 | dev_dbg(info->device, "mtd->%p, buf->%p, len %d\n", mtd, buf, len); | 559 | dev_dbg(info->device, "mtd->%p, buf->%p, len %d\n", mtd, buf, len); |
552 | 560 | ||
@@ -660,7 +668,7 @@ static int bf5xx_nand_hw_init(struct bf5xx_nand_info *info) | |||
660 | */ | 668 | */ |
661 | static int bf5xx_nand_add_partition(struct bf5xx_nand_info *info) | 669 | static int bf5xx_nand_add_partition(struct bf5xx_nand_info *info) |
662 | { | 670 | { |
663 | struct mtd_info *mtd = &info->mtd; | 671 | struct mtd_info *mtd = nand_to_mtd(&info->chip); |
664 | struct mtd_partition *parts = info->platform->partitions; | 672 | struct mtd_partition *parts = info->platform->partitions; |
665 | int nr = info->platform->nr_partitions; | 673 | int nr = info->platform->nr_partitions; |
666 | 674 | ||
@@ -675,7 +683,7 @@ static int bf5xx_nand_remove(struct platform_device *pdev) | |||
675 | * and their partitions, then go through freeing the | 683 | * and their partitions, then go through freeing the |
676 | * resources used | 684 | * resources used |
677 | */ | 685 | */ |
678 | nand_release(&info->mtd); | 686 | nand_release(nand_to_mtd(&info->chip)); |
679 | 687 | ||
680 | peripheral_free_list(bfin_nfc_pin_req); | 688 | peripheral_free_list(bfin_nfc_pin_req); |
681 | bf5xx_nand_dma_remove(info); | 689 | bf5xx_nand_dma_remove(info); |
@@ -685,7 +693,7 @@ static int bf5xx_nand_remove(struct platform_device *pdev) | |||
685 | 693 | ||
686 | static int bf5xx_nand_scan(struct mtd_info *mtd) | 694 | static int bf5xx_nand_scan(struct mtd_info *mtd) |
687 | { | 695 | { |
688 | struct nand_chip *chip = mtd->priv; | 696 | struct nand_chip *chip = mtd_to_nand(mtd); |
689 | int ret; | 697 | int ret; |
690 | 698 | ||
691 | ret = nand_scan_ident(mtd, 1, NULL); | 699 | ret = nand_scan_ident(mtd, 1, NULL); |
@@ -756,6 +764,7 @@ static int bf5xx_nand_probe(struct platform_device *pdev) | |||
756 | 764 | ||
757 | /* initialise chip data struct */ | 765 | /* initialise chip data struct */ |
758 | chip = &info->chip; | 766 | chip = &info->chip; |
767 | mtd = nand_to_mtd(&info->chip); | ||
759 | 768 | ||
760 | if (plat->data_width) | 769 | if (plat->data_width) |
761 | chip->options |= NAND_BUSWIDTH_16; | 770 | chip->options |= NAND_BUSWIDTH_16; |
@@ -772,7 +781,7 @@ static int bf5xx_nand_probe(struct platform_device *pdev) | |||
772 | chip->cmd_ctrl = bf5xx_nand_hwcontrol; | 781 | chip->cmd_ctrl = bf5xx_nand_hwcontrol; |
773 | chip->dev_ready = bf5xx_nand_devready; | 782 | chip->dev_ready = bf5xx_nand_devready; |
774 | 783 | ||
775 | chip->priv = &info->mtd; | 784 | nand_set_controller_data(chip, mtd); |
776 | chip->controller = &info->controller; | 785 | chip->controller = &info->controller; |
777 | 786 | ||
778 | chip->IO_ADDR_R = (void __iomem *) NFC_READ; | 787 | chip->IO_ADDR_R = (void __iomem *) NFC_READ; |
@@ -781,8 +790,6 @@ static int bf5xx_nand_probe(struct platform_device *pdev) | |||
781 | chip->chip_delay = 0; | 790 | chip->chip_delay = 0; |
782 | 791 | ||
783 | /* initialise mtd info data struct */ | 792 | /* initialise mtd info data struct */ |
784 | mtd = &info->mtd; | ||
785 | mtd->priv = chip; | ||
786 | mtd->dev.parent = &pdev->dev; | 793 | mtd->dev.parent = &pdev->dev; |
787 | 794 | ||
788 | /* initialise the hardware */ | 795 | /* initialise the hardware */ |
diff --git a/drivers/mtd/nand/brcmnand/Makefile b/drivers/mtd/nand/brcmnand/Makefile index 3b1fbfd27d4f..b28ffb59eb43 100644 --- a/drivers/mtd/nand/brcmnand/Makefile +++ b/drivers/mtd/nand/brcmnand/Makefile | |||
@@ -2,5 +2,6 @@ | |||
2 | # more specific iproc_nand.o, for instance | 2 | # more specific iproc_nand.o, for instance |
3 | obj-$(CONFIG_MTD_NAND_BRCMNAND) += iproc_nand.o | 3 | obj-$(CONFIG_MTD_NAND_BRCMNAND) += iproc_nand.o |
4 | obj-$(CONFIG_MTD_NAND_BRCMNAND) += bcm63138_nand.o | 4 | obj-$(CONFIG_MTD_NAND_BRCMNAND) += bcm63138_nand.o |
5 | obj-$(CONFIG_MTD_NAND_BRCMNAND) += bcm6368_nand.o | ||
5 | obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmstb_nand.o | 6 | obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmstb_nand.o |
6 | obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand.o | 7 | obj-$(CONFIG_MTD_NAND_BRCMNAND) += brcmnand.o |
diff --git a/drivers/mtd/nand/brcmnand/bcm6368_nand.c b/drivers/mtd/nand/brcmnand/bcm6368_nand.c new file mode 100644 index 000000000000..34c91b0e1e69 --- /dev/null +++ b/drivers/mtd/nand/brcmnand/bcm6368_nand.c | |||
@@ -0,0 +1,142 @@ | |||
1 | /* | ||
2 | * Copyright 2015 Simon Arlott | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * Derived from bcm63138_nand.c: | ||
14 | * Copyright © 2015 Broadcom Corporation | ||
15 | * | ||
16 | * Derived from bcm963xx_4.12L.06B_consumer/shared/opensource/include/bcm963xx/63268_map_part.h: | ||
17 | * Copyright 2000-2010 Broadcom Corporation | ||
18 | * | ||
19 | * Derived from bcm963xx_4.12L.06B_consumer/shared/opensource/flash/nandflash.c: | ||
20 | * Copyright 2000-2010 Broadcom Corporation | ||
21 | */ | ||
22 | |||
23 | #include <linux/device.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <linux/ioport.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/of.h> | ||
28 | #include <linux/of_address.h> | ||
29 | #include <linux/platform_device.h> | ||
30 | #include <linux/slab.h> | ||
31 | |||
32 | #include "brcmnand.h" | ||
33 | |||
34 | struct bcm6368_nand_soc { | ||
35 | struct brcmnand_soc soc; | ||
36 | void __iomem *base; | ||
37 | }; | ||
38 | |||
39 | #define BCM6368_NAND_INT 0x00 | ||
40 | #define BCM6368_NAND_STATUS_SHIFT 0 | ||
41 | #define BCM6368_NAND_STATUS_MASK (0xfff << BCM6368_NAND_STATUS_SHIFT) | ||
42 | #define BCM6368_NAND_ENABLE_SHIFT 16 | ||
43 | #define BCM6368_NAND_ENABLE_MASK (0xffff << BCM6368_NAND_ENABLE_SHIFT) | ||
44 | #define BCM6368_NAND_BASE_ADDR0 0x04 | ||
45 | #define BCM6368_NAND_BASE_ADDR1 0x0c | ||
46 | |||
47 | enum { | ||
48 | BCM6368_NP_READ = BIT(0), | ||
49 | BCM6368_BLOCK_ERASE = BIT(1), | ||
50 | BCM6368_COPY_BACK = BIT(2), | ||
51 | BCM6368_PAGE_PGM = BIT(3), | ||
52 | BCM6368_CTRL_READY = BIT(4), | ||
53 | BCM6368_DEV_RBPIN = BIT(5), | ||
54 | BCM6368_ECC_ERR_UNC = BIT(6), | ||
55 | BCM6368_ECC_ERR_CORR = BIT(7), | ||
56 | }; | ||
57 | |||
58 | static bool bcm6368_nand_intc_ack(struct brcmnand_soc *soc) | ||
59 | { | ||
60 | struct bcm6368_nand_soc *priv = | ||
61 | container_of(soc, struct bcm6368_nand_soc, soc); | ||
62 | void __iomem *mmio = priv->base + BCM6368_NAND_INT; | ||
63 | u32 val = brcmnand_readl(mmio); | ||
64 | |||
65 | if (val & (BCM6368_CTRL_READY << BCM6368_NAND_STATUS_SHIFT)) { | ||
66 | /* Ack interrupt */ | ||
67 | val &= ~BCM6368_NAND_STATUS_MASK; | ||
68 | val |= BCM6368_CTRL_READY << BCM6368_NAND_STATUS_SHIFT; | ||
69 | brcmnand_writel(val, mmio); | ||
70 | return true; | ||
71 | } | ||
72 | |||
73 | return false; | ||
74 | } | ||
75 | |||
76 | static void bcm6368_nand_intc_set(struct brcmnand_soc *soc, bool en) | ||
77 | { | ||
78 | struct bcm6368_nand_soc *priv = | ||
79 | container_of(soc, struct bcm6368_nand_soc, soc); | ||
80 | void __iomem *mmio = priv->base + BCM6368_NAND_INT; | ||
81 | u32 val = brcmnand_readl(mmio); | ||
82 | |||
83 | /* Don't ack any interrupts */ | ||
84 | val &= ~BCM6368_NAND_STATUS_MASK; | ||
85 | |||
86 | if (en) | ||
87 | val |= BCM6368_CTRL_READY << BCM6368_NAND_ENABLE_SHIFT; | ||
88 | else | ||
89 | val &= ~(BCM6368_CTRL_READY << BCM6368_NAND_ENABLE_SHIFT); | ||
90 | |||
91 | brcmnand_writel(val, mmio); | ||
92 | } | ||
93 | |||
94 | static int bcm6368_nand_probe(struct platform_device *pdev) | ||
95 | { | ||
96 | struct device *dev = &pdev->dev; | ||
97 | struct bcm6368_nand_soc *priv; | ||
98 | struct brcmnand_soc *soc; | ||
99 | struct resource *res; | ||
100 | |||
101 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
102 | if (!priv) | ||
103 | return -ENOMEM; | ||
104 | soc = &priv->soc; | ||
105 | |||
106 | res = platform_get_resource_byname(pdev, | ||
107 | IORESOURCE_MEM, "nand-int-base"); | ||
108 | priv->base = devm_ioremap_resource(dev, res); | ||
109 | if (IS_ERR(priv->base)) | ||
110 | return PTR_ERR(priv->base); | ||
111 | |||
112 | soc->ctlrdy_ack = bcm6368_nand_intc_ack; | ||
113 | soc->ctlrdy_set_enabled = bcm6368_nand_intc_set; | ||
114 | |||
115 | /* Disable and ack all interrupts */ | ||
116 | brcmnand_writel(0, priv->base + BCM6368_NAND_INT); | ||
117 | brcmnand_writel(BCM6368_NAND_STATUS_MASK, | ||
118 | priv->base + BCM6368_NAND_INT); | ||
119 | |||
120 | return brcmnand_probe(pdev, soc); | ||
121 | } | ||
122 | |||
123 | static const struct of_device_id bcm6368_nand_of_match[] = { | ||
124 | { .compatible = "brcm,nand-bcm6368" }, | ||
125 | {}, | ||
126 | }; | ||
127 | MODULE_DEVICE_TABLE(of, bcm6368_nand_of_match); | ||
128 | |||
129 | static struct platform_driver bcm6368_nand_driver = { | ||
130 | .probe = bcm6368_nand_probe, | ||
131 | .remove = brcmnand_remove, | ||
132 | .driver = { | ||
133 | .name = "bcm6368_nand", | ||
134 | .pm = &brcmnand_pm_ops, | ||
135 | .of_match_table = bcm6368_nand_of_match, | ||
136 | } | ||
137 | }; | ||
138 | module_platform_driver(bcm6368_nand_driver); | ||
139 | |||
140 | MODULE_LICENSE("GPL"); | ||
141 | MODULE_AUTHOR("Simon Arlott"); | ||
142 | MODULE_DESCRIPTION("NAND driver for BCM6368"); | ||
diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c index 12c6190c6e33..844fc07d22cd 100644 --- a/drivers/mtd/nand/brcmnand/brcmnand.c +++ b/drivers/mtd/nand/brcmnand/brcmnand.c | |||
@@ -11,6 +11,7 @@ | |||
11 | * GNU General Public License for more details. | 11 | * GNU General Public License for more details. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/clk.h> | ||
14 | #include <linux/version.h> | 15 | #include <linux/version.h> |
15 | #include <linux/module.h> | 16 | #include <linux/module.h> |
16 | #include <linux/init.h> | 17 | #include <linux/init.h> |
@@ -122,6 +123,9 @@ struct brcmnand_controller { | |||
122 | /* Some SoCs provide custom interrupt status register(s) */ | 123 | /* Some SoCs provide custom interrupt status register(s) */ |
123 | struct brcmnand_soc *soc; | 124 | struct brcmnand_soc *soc; |
124 | 125 | ||
126 | /* Some SoCs have a gateable clock for the controller */ | ||
127 | struct clk *clk; | ||
128 | |||
125 | int cmd_pending; | 129 | int cmd_pending; |
126 | bool dma_pending; | 130 | bool dma_pending; |
127 | struct completion done; | 131 | struct completion done; |
@@ -134,7 +138,7 @@ struct brcmnand_controller { | |||
134 | dma_addr_t dma_pa; | 138 | dma_addr_t dma_pa; |
135 | 139 | ||
136 | /* in-memory cache of the FLASH_CACHE, used only for some commands */ | 140 | /* in-memory cache of the FLASH_CACHE, used only for some commands */ |
137 | u32 flash_cache[FC_WORDS]; | 141 | u8 flash_cache[FC_BYTES]; |
138 | 142 | ||
139 | /* Controller revision details */ | 143 | /* Controller revision details */ |
140 | const u16 *reg_offsets; | 144 | const u16 *reg_offsets; |
@@ -176,10 +180,8 @@ struct brcmnand_cfg { | |||
176 | 180 | ||
177 | struct brcmnand_host { | 181 | struct brcmnand_host { |
178 | struct list_head node; | 182 | struct list_head node; |
179 | struct device_node *of_node; | ||
180 | 183 | ||
181 | struct nand_chip chip; | 184 | struct nand_chip chip; |
182 | struct mtd_info mtd; | ||
183 | struct platform_device *pdev; | 185 | struct platform_device *pdev; |
184 | int cs; | 186 | int cs; |
185 | 187 | ||
@@ -874,8 +876,8 @@ static struct nand_ecclayout *brcmstb_choose_ecc_layout( | |||
874 | 876 | ||
875 | static void brcmnand_wp(struct mtd_info *mtd, int wp) | 877 | static void brcmnand_wp(struct mtd_info *mtd, int wp) |
876 | { | 878 | { |
877 | struct nand_chip *chip = mtd->priv; | 879 | struct nand_chip *chip = mtd_to_nand(mtd); |
878 | struct brcmnand_host *host = chip->priv; | 880 | struct brcmnand_host *host = nand_get_controller_data(chip); |
879 | struct brcmnand_controller *ctrl = host->ctrl; | 881 | struct brcmnand_controller *ctrl = host->ctrl; |
880 | 882 | ||
881 | if ((ctrl->features & BRCMNAND_HAS_WP) && wp_on == 1) { | 883 | if ((ctrl->features & BRCMNAND_HAS_WP) && wp_on == 1) { |
@@ -1040,8 +1042,8 @@ static void brcmnand_cmd_ctrl(struct mtd_info *mtd, int dat, | |||
1040 | 1042 | ||
1041 | static int brcmnand_waitfunc(struct mtd_info *mtd, struct nand_chip *this) | 1043 | static int brcmnand_waitfunc(struct mtd_info *mtd, struct nand_chip *this) |
1042 | { | 1044 | { |
1043 | struct nand_chip *chip = mtd->priv; | 1045 | struct nand_chip *chip = mtd_to_nand(mtd); |
1044 | struct brcmnand_host *host = chip->priv; | 1046 | struct brcmnand_host *host = nand_get_controller_data(chip); |
1045 | struct brcmnand_controller *ctrl = host->ctrl; | 1047 | struct brcmnand_controller *ctrl = host->ctrl; |
1046 | unsigned long timeo = msecs_to_jiffies(100); | 1048 | unsigned long timeo = msecs_to_jiffies(100); |
1047 | 1049 | ||
@@ -1075,7 +1077,7 @@ static int brcmnand_low_level_op(struct brcmnand_host *host, | |||
1075 | enum brcmnand_llop_type type, u32 data, | 1077 | enum brcmnand_llop_type type, u32 data, |
1076 | bool last_op) | 1078 | bool last_op) |
1077 | { | 1079 | { |
1078 | struct mtd_info *mtd = &host->mtd; | 1080 | struct mtd_info *mtd = nand_to_mtd(&host->chip); |
1079 | struct nand_chip *chip = &host->chip; | 1081 | struct nand_chip *chip = &host->chip; |
1080 | struct brcmnand_controller *ctrl = host->ctrl; | 1082 | struct brcmnand_controller *ctrl = host->ctrl; |
1081 | u32 tmp; | 1083 | u32 tmp; |
@@ -1114,8 +1116,8 @@ static int brcmnand_low_level_op(struct brcmnand_host *host, | |||
1114 | static void brcmnand_cmdfunc(struct mtd_info *mtd, unsigned command, | 1116 | static void brcmnand_cmdfunc(struct mtd_info *mtd, unsigned command, |
1115 | int column, int page_addr) | 1117 | int column, int page_addr) |
1116 | { | 1118 | { |
1117 | struct nand_chip *chip = mtd->priv; | 1119 | struct nand_chip *chip = mtd_to_nand(mtd); |
1118 | struct brcmnand_host *host = chip->priv; | 1120 | struct brcmnand_host *host = nand_get_controller_data(chip); |
1119 | struct brcmnand_controller *ctrl = host->ctrl; | 1121 | struct brcmnand_controller *ctrl = host->ctrl; |
1120 | u64 addr = (u64)page_addr << chip->page_shift; | 1122 | u64 addr = (u64)page_addr << chip->page_shift; |
1121 | int native_cmd = 0; | 1123 | int native_cmd = 0; |
@@ -1188,6 +1190,8 @@ static void brcmnand_cmdfunc(struct mtd_info *mtd, unsigned command, | |||
1188 | 1190 | ||
1189 | if (native_cmd == CMD_PARAMETER_READ || | 1191 | if (native_cmd == CMD_PARAMETER_READ || |
1190 | native_cmd == CMD_PARAMETER_CHANGE_COL) { | 1192 | native_cmd == CMD_PARAMETER_CHANGE_COL) { |
1193 | /* Copy flash cache word-wise */ | ||
1194 | u32 *flash_cache = (u32 *)ctrl->flash_cache; | ||
1191 | int i; | 1195 | int i; |
1192 | 1196 | ||
1193 | brcmnand_soc_data_bus_prepare(ctrl->soc); | 1197 | brcmnand_soc_data_bus_prepare(ctrl->soc); |
@@ -1197,7 +1201,11 @@ static void brcmnand_cmdfunc(struct mtd_info *mtd, unsigned command, | |||
1197 | * SECTOR_SIZE_1K may invalidate it | 1201 | * SECTOR_SIZE_1K may invalidate it |
1198 | */ | 1202 | */ |
1199 | for (i = 0; i < FC_WORDS; i++) | 1203 | for (i = 0; i < FC_WORDS; i++) |
1200 | ctrl->flash_cache[i] = brcmnand_read_fc(ctrl, i); | 1204 | /* |
1205 | * Flash cache is big endian for parameter pages, at | ||
1206 | * least on STB SoCs | ||
1207 | */ | ||
1208 | flash_cache[i] = be32_to_cpu(brcmnand_read_fc(ctrl, i)); | ||
1201 | 1209 | ||
1202 | brcmnand_soc_data_bus_unprepare(ctrl->soc); | 1210 | brcmnand_soc_data_bus_unprepare(ctrl->soc); |
1203 | 1211 | ||
@@ -1214,8 +1222,8 @@ static void brcmnand_cmdfunc(struct mtd_info *mtd, unsigned command, | |||
1214 | 1222 | ||
1215 | static uint8_t brcmnand_read_byte(struct mtd_info *mtd) | 1223 | static uint8_t brcmnand_read_byte(struct mtd_info *mtd) |
1216 | { | 1224 | { |
1217 | struct nand_chip *chip = mtd->priv; | 1225 | struct nand_chip *chip = mtd_to_nand(mtd); |
1218 | struct brcmnand_host *host = chip->priv; | 1226 | struct brcmnand_host *host = nand_get_controller_data(chip); |
1219 | struct brcmnand_controller *ctrl = host->ctrl; | 1227 | struct brcmnand_controller *ctrl = host->ctrl; |
1220 | uint8_t ret = 0; | 1228 | uint8_t ret = 0; |
1221 | int addr, offs; | 1229 | int addr, offs; |
@@ -1250,8 +1258,7 @@ static uint8_t brcmnand_read_byte(struct mtd_info *mtd) | |||
1250 | if (host->last_byte > 0 && offs == 0) | 1258 | if (host->last_byte > 0 && offs == 0) |
1251 | chip->cmdfunc(mtd, NAND_CMD_RNDOUT, addr, -1); | 1259 | chip->cmdfunc(mtd, NAND_CMD_RNDOUT, addr, -1); |
1252 | 1260 | ||
1253 | ret = ctrl->flash_cache[offs >> 2] >> | 1261 | ret = ctrl->flash_cache[offs]; |
1254 | (24 - ((offs & 0x03) << 3)); | ||
1255 | break; | 1262 | break; |
1256 | case NAND_CMD_GET_FEATURES: | 1263 | case NAND_CMD_GET_FEATURES: |
1257 | if (host->last_byte >= ONFI_SUBFEATURE_PARAM_LEN) { | 1264 | if (host->last_byte >= ONFI_SUBFEATURE_PARAM_LEN) { |
@@ -1282,8 +1289,8 @@ static void brcmnand_write_buf(struct mtd_info *mtd, const uint8_t *buf, | |||
1282 | int len) | 1289 | int len) |
1283 | { | 1290 | { |
1284 | int i; | 1291 | int i; |
1285 | struct nand_chip *chip = mtd->priv; | 1292 | struct nand_chip *chip = mtd_to_nand(mtd); |
1286 | struct brcmnand_host *host = chip->priv; | 1293 | struct brcmnand_host *host = nand_get_controller_data(chip); |
1287 | 1294 | ||
1288 | switch (host->last_cmd) { | 1295 | switch (host->last_cmd) { |
1289 | case NAND_CMD_SET_FEATURES: | 1296 | case NAND_CMD_SET_FEATURES: |
@@ -1393,13 +1400,15 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip, | |||
1393 | u64 addr, unsigned int trans, u32 *buf, | 1400 | u64 addr, unsigned int trans, u32 *buf, |
1394 | u8 *oob, u64 *err_addr) | 1401 | u8 *oob, u64 *err_addr) |
1395 | { | 1402 | { |
1396 | struct brcmnand_host *host = chip->priv; | 1403 | struct brcmnand_host *host = nand_get_controller_data(chip); |
1397 | struct brcmnand_controller *ctrl = host->ctrl; | 1404 | struct brcmnand_controller *ctrl = host->ctrl; |
1398 | int i, j, ret = 0; | 1405 | int i, j, ret = 0; |
1399 | 1406 | ||
1400 | /* Clear error addresses */ | 1407 | /* Clear error addresses */ |
1401 | brcmnand_write_reg(ctrl, BRCMNAND_UNCORR_ADDR, 0); | 1408 | brcmnand_write_reg(ctrl, BRCMNAND_UNCORR_ADDR, 0); |
1402 | brcmnand_write_reg(ctrl, BRCMNAND_CORR_ADDR, 0); | 1409 | brcmnand_write_reg(ctrl, BRCMNAND_CORR_ADDR, 0); |
1410 | brcmnand_write_reg(ctrl, BRCMNAND_UNCORR_EXT_ADDR, 0); | ||
1411 | brcmnand_write_reg(ctrl, BRCMNAND_CORR_EXT_ADDR, 0); | ||
1403 | 1412 | ||
1404 | brcmnand_write_reg(ctrl, BRCMNAND_CMD_EXT_ADDRESS, | 1413 | brcmnand_write_reg(ctrl, BRCMNAND_CMD_EXT_ADDRESS, |
1405 | (host->cs << 16) | ((addr >> 32) & 0xffff)); | 1414 | (host->cs << 16) | ((addr >> 32) & 0xffff)); |
@@ -1454,7 +1463,7 @@ static int brcmnand_read_by_pio(struct mtd_info *mtd, struct nand_chip *chip, | |||
1454 | static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip, | 1463 | static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip, |
1455 | u64 addr, unsigned int trans, u32 *buf, u8 *oob) | 1464 | u64 addr, unsigned int trans, u32 *buf, u8 *oob) |
1456 | { | 1465 | { |
1457 | struct brcmnand_host *host = chip->priv; | 1466 | struct brcmnand_host *host = nand_get_controller_data(chip); |
1458 | struct brcmnand_controller *ctrl = host->ctrl; | 1467 | struct brcmnand_controller *ctrl = host->ctrl; |
1459 | u64 err_addr = 0; | 1468 | u64 err_addr = 0; |
1460 | int err; | 1469 | int err; |
@@ -1504,7 +1513,7 @@ static int brcmnand_read(struct mtd_info *mtd, struct nand_chip *chip, | |||
1504 | static int brcmnand_read_page(struct mtd_info *mtd, struct nand_chip *chip, | 1513 | static int brcmnand_read_page(struct mtd_info *mtd, struct nand_chip *chip, |
1505 | uint8_t *buf, int oob_required, int page) | 1514 | uint8_t *buf, int oob_required, int page) |
1506 | { | 1515 | { |
1507 | struct brcmnand_host *host = chip->priv; | 1516 | struct brcmnand_host *host = nand_get_controller_data(chip); |
1508 | u8 *oob = oob_required ? (u8 *)chip->oob_poi : NULL; | 1517 | u8 *oob = oob_required ? (u8 *)chip->oob_poi : NULL; |
1509 | 1518 | ||
1510 | return brcmnand_read(mtd, chip, host->last_addr, | 1519 | return brcmnand_read(mtd, chip, host->last_addr, |
@@ -1514,7 +1523,7 @@ static int brcmnand_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1514 | static int brcmnand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, | 1523 | static int brcmnand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, |
1515 | uint8_t *buf, int oob_required, int page) | 1524 | uint8_t *buf, int oob_required, int page) |
1516 | { | 1525 | { |
1517 | struct brcmnand_host *host = chip->priv; | 1526 | struct brcmnand_host *host = nand_get_controller_data(chip); |
1518 | u8 *oob = oob_required ? (u8 *)chip->oob_poi : NULL; | 1527 | u8 *oob = oob_required ? (u8 *)chip->oob_poi : NULL; |
1519 | int ret; | 1528 | int ret; |
1520 | 1529 | ||
@@ -1536,7 +1545,7 @@ static int brcmnand_read_oob(struct mtd_info *mtd, struct nand_chip *chip, | |||
1536 | static int brcmnand_read_oob_raw(struct mtd_info *mtd, struct nand_chip *chip, | 1545 | static int brcmnand_read_oob_raw(struct mtd_info *mtd, struct nand_chip *chip, |
1537 | int page) | 1546 | int page) |
1538 | { | 1547 | { |
1539 | struct brcmnand_host *host = chip->priv; | 1548 | struct brcmnand_host *host = nand_get_controller_data(chip); |
1540 | 1549 | ||
1541 | brcmnand_set_ecc_enabled(host, 0); | 1550 | brcmnand_set_ecc_enabled(host, 0); |
1542 | brcmnand_read(mtd, chip, (u64)page << chip->page_shift, | 1551 | brcmnand_read(mtd, chip, (u64)page << chip->page_shift, |
@@ -1546,20 +1555,10 @@ static int brcmnand_read_oob_raw(struct mtd_info *mtd, struct nand_chip *chip, | |||
1546 | return 0; | 1555 | return 0; |
1547 | } | 1556 | } |
1548 | 1557 | ||
1549 | static int brcmnand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, | ||
1550 | uint32_t data_offs, uint32_t readlen, | ||
1551 | uint8_t *bufpoi, int page) | ||
1552 | { | ||
1553 | struct brcmnand_host *host = chip->priv; | ||
1554 | |||
1555 | return brcmnand_read(mtd, chip, host->last_addr + data_offs, | ||
1556 | readlen >> FC_SHIFT, (u32 *)bufpoi, NULL); | ||
1557 | } | ||
1558 | |||
1559 | static int brcmnand_write(struct mtd_info *mtd, struct nand_chip *chip, | 1558 | static int brcmnand_write(struct mtd_info *mtd, struct nand_chip *chip, |
1560 | u64 addr, const u32 *buf, u8 *oob) | 1559 | u64 addr, const u32 *buf, u8 *oob) |
1561 | { | 1560 | { |
1562 | struct brcmnand_host *host = chip->priv; | 1561 | struct brcmnand_host *host = nand_get_controller_data(chip); |
1563 | struct brcmnand_controller *ctrl = host->ctrl; | 1562 | struct brcmnand_controller *ctrl = host->ctrl; |
1564 | unsigned int i, j, trans = mtd->writesize >> FC_SHIFT; | 1563 | unsigned int i, j, trans = mtd->writesize >> FC_SHIFT; |
1565 | int status, ret = 0; | 1564 | int status, ret = 0; |
@@ -1630,7 +1629,7 @@ out: | |||
1630 | static int brcmnand_write_page(struct mtd_info *mtd, struct nand_chip *chip, | 1629 | static int brcmnand_write_page(struct mtd_info *mtd, struct nand_chip *chip, |
1631 | const uint8_t *buf, int oob_required, int page) | 1630 | const uint8_t *buf, int oob_required, int page) |
1632 | { | 1631 | { |
1633 | struct brcmnand_host *host = chip->priv; | 1632 | struct brcmnand_host *host = nand_get_controller_data(chip); |
1634 | void *oob = oob_required ? chip->oob_poi : NULL; | 1633 | void *oob = oob_required ? chip->oob_poi : NULL; |
1635 | 1634 | ||
1636 | brcmnand_write(mtd, chip, host->last_addr, (const u32 *)buf, oob); | 1635 | brcmnand_write(mtd, chip, host->last_addr, (const u32 *)buf, oob); |
@@ -1641,7 +1640,7 @@ static int brcmnand_write_page_raw(struct mtd_info *mtd, | |||
1641 | struct nand_chip *chip, const uint8_t *buf, | 1640 | struct nand_chip *chip, const uint8_t *buf, |
1642 | int oob_required, int page) | 1641 | int oob_required, int page) |
1643 | { | 1642 | { |
1644 | struct brcmnand_host *host = chip->priv; | 1643 | struct brcmnand_host *host = nand_get_controller_data(chip); |
1645 | void *oob = oob_required ? chip->oob_poi : NULL; | 1644 | void *oob = oob_required ? chip->oob_poi : NULL; |
1646 | 1645 | ||
1647 | brcmnand_set_ecc_enabled(host, 0); | 1646 | brcmnand_set_ecc_enabled(host, 0); |
@@ -1660,7 +1659,7 @@ static int brcmnand_write_oob(struct mtd_info *mtd, struct nand_chip *chip, | |||
1660 | static int brcmnand_write_oob_raw(struct mtd_info *mtd, struct nand_chip *chip, | 1659 | static int brcmnand_write_oob_raw(struct mtd_info *mtd, struct nand_chip *chip, |
1661 | int page) | 1660 | int page) |
1662 | { | 1661 | { |
1663 | struct brcmnand_host *host = chip->priv; | 1662 | struct brcmnand_host *host = nand_get_controller_data(chip); |
1664 | int ret; | 1663 | int ret; |
1665 | 1664 | ||
1666 | brcmnand_set_ecc_enabled(host, 0); | 1665 | brcmnand_set_ecc_enabled(host, 0); |
@@ -1806,7 +1805,7 @@ static inline int get_blk_adr_bytes(u64 size, u32 writesize) | |||
1806 | 1805 | ||
1807 | static int brcmnand_setup_dev(struct brcmnand_host *host) | 1806 | static int brcmnand_setup_dev(struct brcmnand_host *host) |
1808 | { | 1807 | { |
1809 | struct mtd_info *mtd = &host->mtd; | 1808 | struct mtd_info *mtd = nand_to_mtd(&host->chip); |
1810 | struct nand_chip *chip = &host->chip; | 1809 | struct nand_chip *chip = &host->chip; |
1811 | struct brcmnand_controller *ctrl = host->ctrl; | 1810 | struct brcmnand_controller *ctrl = host->ctrl; |
1812 | struct brcmnand_cfg *cfg = &host->hwcfg; | 1811 | struct brcmnand_cfg *cfg = &host->hwcfg; |
@@ -1816,7 +1815,7 @@ static int brcmnand_setup_dev(struct brcmnand_host *host) | |||
1816 | 1815 | ||
1817 | memset(cfg, 0, sizeof(*cfg)); | 1816 | memset(cfg, 0, sizeof(*cfg)); |
1818 | 1817 | ||
1819 | ret = of_property_read_u32(chip->flash_node, | 1818 | ret = of_property_read_u32(nand_get_flash_node(chip), |
1820 | "brcm,nand-oob-sector-size", | 1819 | "brcm,nand-oob-sector-size", |
1821 | &oob_sector); | 1820 | &oob_sector); |
1822 | if (ret) { | 1821 | if (ret) { |
@@ -1905,16 +1904,14 @@ static int brcmnand_setup_dev(struct brcmnand_host *host) | |||
1905 | return 0; | 1904 | return 0; |
1906 | } | 1905 | } |
1907 | 1906 | ||
1908 | static int brcmnand_init_cs(struct brcmnand_host *host) | 1907 | static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn) |
1909 | { | 1908 | { |
1910 | struct brcmnand_controller *ctrl = host->ctrl; | 1909 | struct brcmnand_controller *ctrl = host->ctrl; |
1911 | struct device_node *dn = host->of_node; | ||
1912 | struct platform_device *pdev = host->pdev; | 1910 | struct platform_device *pdev = host->pdev; |
1913 | struct mtd_info *mtd; | 1911 | struct mtd_info *mtd; |
1914 | struct nand_chip *chip; | 1912 | struct nand_chip *chip; |
1915 | int ret; | 1913 | int ret; |
1916 | u16 cfg_offs; | 1914 | u16 cfg_offs; |
1917 | struct mtd_part_parser_data ppdata = { .of_node = dn }; | ||
1918 | 1915 | ||
1919 | ret = of_property_read_u32(dn, "reg", &host->cs); | 1916 | ret = of_property_read_u32(dn, "reg", &host->cs); |
1920 | if (ret) { | 1917 | if (ret) { |
@@ -1922,12 +1919,11 @@ static int brcmnand_init_cs(struct brcmnand_host *host) | |||
1922 | return -ENXIO; | 1919 | return -ENXIO; |
1923 | } | 1920 | } |
1924 | 1921 | ||
1925 | mtd = &host->mtd; | 1922 | mtd = nand_to_mtd(&host->chip); |
1926 | chip = &host->chip; | 1923 | chip = &host->chip; |
1927 | 1924 | ||
1928 | chip->flash_node = dn; | 1925 | nand_set_flash_node(chip, dn); |
1929 | chip->priv = host; | 1926 | nand_set_controller_data(chip, host); |
1930 | mtd->priv = chip; | ||
1931 | mtd->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "brcmnand.%d", | 1927 | mtd->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "brcmnand.%d", |
1932 | host->cs); | 1928 | host->cs); |
1933 | mtd->owner = THIS_MODULE; | 1929 | mtd->owner = THIS_MODULE; |
@@ -1945,7 +1941,6 @@ static int brcmnand_init_cs(struct brcmnand_host *host) | |||
1945 | 1941 | ||
1946 | chip->ecc.mode = NAND_ECC_HW; | 1942 | chip->ecc.mode = NAND_ECC_HW; |
1947 | chip->ecc.read_page = brcmnand_read_page; | 1943 | chip->ecc.read_page = brcmnand_read_page; |
1948 | chip->ecc.read_subpage = brcmnand_read_subpage; | ||
1949 | chip->ecc.write_page = brcmnand_write_page; | 1944 | chip->ecc.write_page = brcmnand_write_page; |
1950 | chip->ecc.read_page_raw = brcmnand_read_page_raw; | 1945 | chip->ecc.read_page_raw = brcmnand_read_page_raw; |
1951 | chip->ecc.write_page_raw = brcmnand_write_page_raw; | 1946 | chip->ecc.write_page_raw = brcmnand_write_page_raw; |
@@ -1993,7 +1988,7 @@ static int brcmnand_init_cs(struct brcmnand_host *host) | |||
1993 | if (nand_scan_tail(mtd)) | 1988 | if (nand_scan_tail(mtd)) |
1994 | return -ENXIO; | 1989 | return -ENXIO; |
1995 | 1990 | ||
1996 | return mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); | 1991 | return mtd_device_register(mtd, NULL, 0); |
1997 | } | 1992 | } |
1998 | 1993 | ||
1999 | static void brcmnand_save_restore_cs_config(struct brcmnand_host *host, | 1994 | static void brcmnand_save_restore_cs_config(struct brcmnand_host *host, |
@@ -2067,8 +2062,8 @@ static int brcmnand_resume(struct device *dev) | |||
2067 | } | 2062 | } |
2068 | 2063 | ||
2069 | list_for_each_entry(host, &ctrl->host_list, node) { | 2064 | list_for_each_entry(host, &ctrl->host_list, node) { |
2070 | struct mtd_info *mtd = &host->mtd; | 2065 | struct nand_chip *chip = &host->chip; |
2071 | struct nand_chip *chip = mtd->priv; | 2066 | struct mtd_info *mtd = nand_to_mtd(chip); |
2072 | 2067 | ||
2073 | brcmnand_save_restore_cs_config(host, 1); | 2068 | brcmnand_save_restore_cs_config(host, 1); |
2074 | 2069 | ||
@@ -2134,10 +2129,24 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) | |||
2134 | if (IS_ERR(ctrl->nand_base)) | 2129 | if (IS_ERR(ctrl->nand_base)) |
2135 | return PTR_ERR(ctrl->nand_base); | 2130 | return PTR_ERR(ctrl->nand_base); |
2136 | 2131 | ||
2132 | /* Enable clock before using NAND registers */ | ||
2133 | ctrl->clk = devm_clk_get(dev, "nand"); | ||
2134 | if (!IS_ERR(ctrl->clk)) { | ||
2135 | ret = clk_prepare_enable(ctrl->clk); | ||
2136 | if (ret) | ||
2137 | return ret; | ||
2138 | } else { | ||
2139 | ret = PTR_ERR(ctrl->clk); | ||
2140 | if (ret == -EPROBE_DEFER) | ||
2141 | return ret; | ||
2142 | |||
2143 | ctrl->clk = NULL; | ||
2144 | } | ||
2145 | |||
2137 | /* Initialize NAND revision */ | 2146 | /* Initialize NAND revision */ |
2138 | ret = brcmnand_revision_init(ctrl); | 2147 | ret = brcmnand_revision_init(ctrl); |
2139 | if (ret) | 2148 | if (ret) |
2140 | return ret; | 2149 | goto err; |
2141 | 2150 | ||
2142 | /* | 2151 | /* |
2143 | * Most chips have this cache at a fixed offset within 'nand' block. | 2152 | * Most chips have this cache at a fixed offset within 'nand' block. |
@@ -2146,8 +2155,10 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) | |||
2146 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand-cache"); | 2155 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand-cache"); |
2147 | if (res) { | 2156 | if (res) { |
2148 | ctrl->nand_fc = devm_ioremap_resource(dev, res); | 2157 | ctrl->nand_fc = devm_ioremap_resource(dev, res); |
2149 | if (IS_ERR(ctrl->nand_fc)) | 2158 | if (IS_ERR(ctrl->nand_fc)) { |
2150 | return PTR_ERR(ctrl->nand_fc); | 2159 | ret = PTR_ERR(ctrl->nand_fc); |
2160 | goto err; | ||
2161 | } | ||
2151 | } else { | 2162 | } else { |
2152 | ctrl->nand_fc = ctrl->nand_base + | 2163 | ctrl->nand_fc = ctrl->nand_base + |
2153 | ctrl->reg_offsets[BRCMNAND_FC_BASE]; | 2164 | ctrl->reg_offsets[BRCMNAND_FC_BASE]; |
@@ -2157,8 +2168,10 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) | |||
2157 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "flash-dma"); | 2168 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "flash-dma"); |
2158 | if (res) { | 2169 | if (res) { |
2159 | ctrl->flash_dma_base = devm_ioremap_resource(dev, res); | 2170 | ctrl->flash_dma_base = devm_ioremap_resource(dev, res); |
2160 | if (IS_ERR(ctrl->flash_dma_base)) | 2171 | if (IS_ERR(ctrl->flash_dma_base)) { |
2161 | return PTR_ERR(ctrl->flash_dma_base); | 2172 | ret = PTR_ERR(ctrl->flash_dma_base); |
2173 | goto err; | ||
2174 | } | ||
2162 | 2175 | ||
2163 | flash_dma_writel(ctrl, FLASH_DMA_MODE, 1); /* linked-list */ | 2176 | flash_dma_writel(ctrl, FLASH_DMA_MODE, 1); /* linked-list */ |
2164 | flash_dma_writel(ctrl, FLASH_DMA_ERROR_STATUS, 0); | 2177 | flash_dma_writel(ctrl, FLASH_DMA_ERROR_STATUS, 0); |
@@ -2167,13 +2180,16 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) | |||
2167 | ctrl->dma_desc = dmam_alloc_coherent(dev, | 2180 | ctrl->dma_desc = dmam_alloc_coherent(dev, |
2168 | sizeof(*ctrl->dma_desc), | 2181 | sizeof(*ctrl->dma_desc), |
2169 | &ctrl->dma_pa, GFP_KERNEL); | 2182 | &ctrl->dma_pa, GFP_KERNEL); |
2170 | if (!ctrl->dma_desc) | 2183 | if (!ctrl->dma_desc) { |
2171 | return -ENOMEM; | 2184 | ret = -ENOMEM; |
2185 | goto err; | ||
2186 | } | ||
2172 | 2187 | ||
2173 | ctrl->dma_irq = platform_get_irq(pdev, 1); | 2188 | ctrl->dma_irq = platform_get_irq(pdev, 1); |
2174 | if ((int)ctrl->dma_irq < 0) { | 2189 | if ((int)ctrl->dma_irq < 0) { |
2175 | dev_err(dev, "missing FLASH_DMA IRQ\n"); | 2190 | dev_err(dev, "missing FLASH_DMA IRQ\n"); |
2176 | return -ENODEV; | 2191 | ret = -ENODEV; |
2192 | goto err; | ||
2177 | } | 2193 | } |
2178 | 2194 | ||
2179 | ret = devm_request_irq(dev, ctrl->dma_irq, | 2195 | ret = devm_request_irq(dev, ctrl->dma_irq, |
@@ -2182,7 +2198,7 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) | |||
2182 | if (ret < 0) { | 2198 | if (ret < 0) { |
2183 | dev_err(dev, "can't allocate IRQ %d: error %d\n", | 2199 | dev_err(dev, "can't allocate IRQ %d: error %d\n", |
2184 | ctrl->dma_irq, ret); | 2200 | ctrl->dma_irq, ret); |
2185 | return ret; | 2201 | goto err; |
2186 | } | 2202 | } |
2187 | 2203 | ||
2188 | dev_info(dev, "enabling FLASH_DMA\n"); | 2204 | dev_info(dev, "enabling FLASH_DMA\n"); |
@@ -2206,7 +2222,8 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) | |||
2206 | ctrl->irq = platform_get_irq(pdev, 0); | 2222 | ctrl->irq = platform_get_irq(pdev, 0); |
2207 | if ((int)ctrl->irq < 0) { | 2223 | if ((int)ctrl->irq < 0) { |
2208 | dev_err(dev, "no IRQ defined\n"); | 2224 | dev_err(dev, "no IRQ defined\n"); |
2209 | return -ENODEV; | 2225 | ret = -ENODEV; |
2226 | goto err; | ||
2210 | } | 2227 | } |
2211 | 2228 | ||
2212 | /* | 2229 | /* |
@@ -2230,7 +2247,7 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) | |||
2230 | if (ret < 0) { | 2247 | if (ret < 0) { |
2231 | dev_err(dev, "can't allocate IRQ %d: error %d\n", | 2248 | dev_err(dev, "can't allocate IRQ %d: error %d\n", |
2232 | ctrl->irq, ret); | 2249 | ctrl->irq, ret); |
2233 | return ret; | 2250 | goto err; |
2234 | } | 2251 | } |
2235 | 2252 | ||
2236 | for_each_available_child_of_node(dn, child) { | 2253 | for_each_available_child_of_node(dn, child) { |
@@ -2238,25 +2255,36 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc) | |||
2238 | struct brcmnand_host *host; | 2255 | struct brcmnand_host *host; |
2239 | 2256 | ||
2240 | host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); | 2257 | host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); |
2241 | if (!host) | 2258 | if (!host) { |
2242 | return -ENOMEM; | 2259 | of_node_put(child); |
2260 | ret = -ENOMEM; | ||
2261 | goto err; | ||
2262 | } | ||
2243 | host->pdev = pdev; | 2263 | host->pdev = pdev; |
2244 | host->ctrl = ctrl; | 2264 | host->ctrl = ctrl; |
2245 | host->of_node = child; | ||
2246 | 2265 | ||
2247 | ret = brcmnand_init_cs(host); | 2266 | ret = brcmnand_init_cs(host, child); |
2248 | if (ret) | 2267 | if (ret) { |
2268 | devm_kfree(dev, host); | ||
2249 | continue; /* Try all chip-selects */ | 2269 | continue; /* Try all chip-selects */ |
2270 | } | ||
2250 | 2271 | ||
2251 | list_add_tail(&host->node, &ctrl->host_list); | 2272 | list_add_tail(&host->node, &ctrl->host_list); |
2252 | } | 2273 | } |
2253 | } | 2274 | } |
2254 | 2275 | ||
2255 | /* No chip-selects could initialize properly */ | 2276 | /* No chip-selects could initialize properly */ |
2256 | if (list_empty(&ctrl->host_list)) | 2277 | if (list_empty(&ctrl->host_list)) { |
2257 | return -ENODEV; | 2278 | ret = -ENODEV; |
2279 | goto err; | ||
2280 | } | ||
2258 | 2281 | ||
2259 | return 0; | 2282 | return 0; |
2283 | |||
2284 | err: | ||
2285 | clk_disable_unprepare(ctrl->clk); | ||
2286 | return ret; | ||
2287 | |||
2260 | } | 2288 | } |
2261 | EXPORT_SYMBOL_GPL(brcmnand_probe); | 2289 | EXPORT_SYMBOL_GPL(brcmnand_probe); |
2262 | 2290 | ||
@@ -2266,7 +2294,9 @@ int brcmnand_remove(struct platform_device *pdev) | |||
2266 | struct brcmnand_host *host; | 2294 | struct brcmnand_host *host; |
2267 | 2295 | ||
2268 | list_for_each_entry(host, &ctrl->host_list, node) | 2296 | list_for_each_entry(host, &ctrl->host_list, node) |
2269 | nand_release(&host->mtd); | 2297 | nand_release(nand_to_mtd(&host->chip)); |
2298 | |||
2299 | clk_disable_unprepare(ctrl->clk); | ||
2270 | 2300 | ||
2271 | dev_set_drvdata(&pdev->dev, NULL); | 2301 | dev_set_drvdata(&pdev->dev, NULL); |
2272 | 2302 | ||
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index 9de78d2a2eb1..aa1a616b9fb6 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c | |||
@@ -101,7 +101,8 @@ static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; | |||
101 | 101 | ||
102 | static int cafe_device_ready(struct mtd_info *mtd) | 102 | static int cafe_device_ready(struct mtd_info *mtd) |
103 | { | 103 | { |
104 | struct cafe_priv *cafe = mtd->priv; | 104 | struct nand_chip *chip = mtd_to_nand(mtd); |
105 | struct cafe_priv *cafe = nand_get_controller_data(chip); | ||
105 | int result = !!(cafe_readl(cafe, NAND_STATUS) & 0x40000000); | 106 | int result = !!(cafe_readl(cafe, NAND_STATUS) & 0x40000000); |
106 | uint32_t irqs = cafe_readl(cafe, NAND_IRQ); | 107 | uint32_t irqs = cafe_readl(cafe, NAND_IRQ); |
107 | 108 | ||
@@ -117,7 +118,8 @@ static int cafe_device_ready(struct mtd_info *mtd) | |||
117 | 118 | ||
118 | static void cafe_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | 119 | static void cafe_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) |
119 | { | 120 | { |
120 | struct cafe_priv *cafe = mtd->priv; | 121 | struct nand_chip *chip = mtd_to_nand(mtd); |
122 | struct cafe_priv *cafe = nand_get_controller_data(chip); | ||
121 | 123 | ||
122 | if (usedma) | 124 | if (usedma) |
123 | memcpy(cafe->dmabuf + cafe->datalen, buf, len); | 125 | memcpy(cafe->dmabuf + cafe->datalen, buf, len); |
@@ -132,7 +134,8 @@ static void cafe_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | |||
132 | 134 | ||
133 | static void cafe_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | 135 | static void cafe_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) |
134 | { | 136 | { |
135 | struct cafe_priv *cafe = mtd->priv; | 137 | struct nand_chip *chip = mtd_to_nand(mtd); |
138 | struct cafe_priv *cafe = nand_get_controller_data(chip); | ||
136 | 139 | ||
137 | if (usedma) | 140 | if (usedma) |
138 | memcpy(buf, cafe->dmabuf + cafe->datalen, len); | 141 | memcpy(buf, cafe->dmabuf + cafe->datalen, len); |
@@ -146,7 +149,8 @@ static void cafe_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | |||
146 | 149 | ||
147 | static uint8_t cafe_read_byte(struct mtd_info *mtd) | 150 | static uint8_t cafe_read_byte(struct mtd_info *mtd) |
148 | { | 151 | { |
149 | struct cafe_priv *cafe = mtd->priv; | 152 | struct nand_chip *chip = mtd_to_nand(mtd); |
153 | struct cafe_priv *cafe = nand_get_controller_data(chip); | ||
150 | uint8_t d; | 154 | uint8_t d; |
151 | 155 | ||
152 | cafe_read_buf(mtd, &d, 1); | 156 | cafe_read_buf(mtd, &d, 1); |
@@ -158,7 +162,8 @@ static uint8_t cafe_read_byte(struct mtd_info *mtd) | |||
158 | static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command, | 162 | static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command, |
159 | int column, int page_addr) | 163 | int column, int page_addr) |
160 | { | 164 | { |
161 | struct cafe_priv *cafe = mtd->priv; | 165 | struct nand_chip *chip = mtd_to_nand(mtd); |
166 | struct cafe_priv *cafe = nand_get_controller_data(chip); | ||
162 | int adrbytes = 0; | 167 | int adrbytes = 0; |
163 | uint32_t ctl1; | 168 | uint32_t ctl1; |
164 | uint32_t doneint = 0x80000000; | 169 | uint32_t doneint = 0x80000000; |
@@ -313,7 +318,8 @@ static void cafe_nand_cmdfunc(struct mtd_info *mtd, unsigned command, | |||
313 | 318 | ||
314 | static void cafe_select_chip(struct mtd_info *mtd, int chipnr) | 319 | static void cafe_select_chip(struct mtd_info *mtd, int chipnr) |
315 | { | 320 | { |
316 | struct cafe_priv *cafe = mtd->priv; | 321 | struct nand_chip *chip = mtd_to_nand(mtd); |
322 | struct cafe_priv *cafe = nand_get_controller_data(chip); | ||
317 | 323 | ||
318 | cafe_dev_dbg(&cafe->pdev->dev, "select_chip %d\n", chipnr); | 324 | cafe_dev_dbg(&cafe->pdev->dev, "select_chip %d\n", chipnr); |
319 | 325 | ||
@@ -328,7 +334,8 @@ static void cafe_select_chip(struct mtd_info *mtd, int chipnr) | |||
328 | static irqreturn_t cafe_nand_interrupt(int irq, void *id) | 334 | static irqreturn_t cafe_nand_interrupt(int irq, void *id) |
329 | { | 335 | { |
330 | struct mtd_info *mtd = id; | 336 | struct mtd_info *mtd = id; |
331 | struct cafe_priv *cafe = mtd->priv; | 337 | struct nand_chip *chip = mtd_to_nand(mtd); |
338 | struct cafe_priv *cafe = nand_get_controller_data(chip); | ||
332 | uint32_t irqs = cafe_readl(cafe, NAND_IRQ); | 339 | uint32_t irqs = cafe_readl(cafe, NAND_IRQ); |
333 | cafe_writel(cafe, irqs & ~0x90000000, NAND_IRQ); | 340 | cafe_writel(cafe, irqs & ~0x90000000, NAND_IRQ); |
334 | if (!irqs) | 341 | if (!irqs) |
@@ -377,7 +384,7 @@ static int cafe_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip, | |||
377 | static int cafe_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip, | 384 | static int cafe_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip, |
378 | uint8_t *buf, int oob_required, int page) | 385 | uint8_t *buf, int oob_required, int page) |
379 | { | 386 | { |
380 | struct cafe_priv *cafe = mtd->priv; | 387 | struct cafe_priv *cafe = nand_get_controller_data(chip); |
381 | unsigned int max_bitflips = 0; | 388 | unsigned int max_bitflips = 0; |
382 | 389 | ||
383 | cafe_dev_dbg(&cafe->pdev->dev, "ECC result %08x SYN1,2 %08x\n", | 390 | cafe_dev_dbg(&cafe->pdev->dev, "ECC result %08x SYN1,2 %08x\n", |
@@ -519,7 +526,7 @@ static int cafe_nand_write_page_lowlevel(struct mtd_info *mtd, | |||
519 | const uint8_t *buf, int oob_required, | 526 | const uint8_t *buf, int oob_required, |
520 | int page) | 527 | int page) |
521 | { | 528 | { |
522 | struct cafe_priv *cafe = mtd->priv; | 529 | struct cafe_priv *cafe = nand_get_controller_data(chip); |
523 | 530 | ||
524 | chip->write_buf(mtd, buf, mtd->writesize); | 531 | chip->write_buf(mtd, buf, mtd->writesize); |
525 | chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); | 532 | chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); |
@@ -598,13 +605,13 @@ static int cafe_nand_probe(struct pci_dev *pdev, | |||
598 | 605 | ||
599 | pci_set_master(pdev); | 606 | pci_set_master(pdev); |
600 | 607 | ||
601 | mtd = kzalloc(sizeof(*mtd) + sizeof(struct cafe_priv), GFP_KERNEL); | 608 | cafe = kzalloc(sizeof(*cafe), GFP_KERNEL); |
602 | if (!mtd) | 609 | if (!cafe) |
603 | return -ENOMEM; | 610 | return -ENOMEM; |
604 | cafe = (void *)(&mtd[1]); | ||
605 | 611 | ||
612 | mtd = nand_to_mtd(&cafe->nand); | ||
606 | mtd->dev.parent = &pdev->dev; | 613 | mtd->dev.parent = &pdev->dev; |
607 | mtd->priv = cafe; | 614 | nand_set_controller_data(&cafe->nand, cafe); |
608 | 615 | ||
609 | cafe->pdev = pdev; | 616 | cafe->pdev = pdev; |
610 | cafe->mmio = pci_iomap(pdev, 0, 0); | 617 | cafe->mmio = pci_iomap(pdev, 0, 0); |
@@ -784,7 +791,7 @@ static int cafe_nand_probe(struct pci_dev *pdev, | |||
784 | out_ior: | 791 | out_ior: |
785 | pci_iounmap(pdev, cafe->mmio); | 792 | pci_iounmap(pdev, cafe->mmio); |
786 | out_free_mtd: | 793 | out_free_mtd: |
787 | kfree(mtd); | 794 | kfree(cafe); |
788 | out: | 795 | out: |
789 | return err; | 796 | return err; |
790 | } | 797 | } |
@@ -792,7 +799,8 @@ static int cafe_nand_probe(struct pci_dev *pdev, | |||
792 | static void cafe_nand_remove(struct pci_dev *pdev) | 799 | static void cafe_nand_remove(struct pci_dev *pdev) |
793 | { | 800 | { |
794 | struct mtd_info *mtd = pci_get_drvdata(pdev); | 801 | struct mtd_info *mtd = pci_get_drvdata(pdev); |
795 | struct cafe_priv *cafe = mtd->priv; | 802 | struct nand_chip *chip = mtd_to_nand(mtd); |
803 | struct cafe_priv *cafe = nand_get_controller_data(chip); | ||
796 | 804 | ||
797 | /* Disable NAND IRQ in global IRQ mask register */ | 805 | /* Disable NAND IRQ in global IRQ mask register */ |
798 | cafe_writel(cafe, ~1 & cafe_readl(cafe, GLOBAL_IRQ_MASK), GLOBAL_IRQ_MASK); | 806 | cafe_writel(cafe, ~1 & cafe_readl(cafe, GLOBAL_IRQ_MASK), GLOBAL_IRQ_MASK); |
@@ -804,7 +812,7 @@ static void cafe_nand_remove(struct pci_dev *pdev) | |||
804 | 2112 + sizeof(struct nand_buffers) + | 812 | 2112 + sizeof(struct nand_buffers) + |
805 | mtd->writesize + mtd->oobsize, | 813 | mtd->writesize + mtd->oobsize, |
806 | cafe->dmabuf, cafe->dmaaddr); | 814 | cafe->dmabuf, cafe->dmaaddr); |
807 | kfree(mtd); | 815 | kfree(cafe); |
808 | } | 816 | } |
809 | 817 | ||
810 | static const struct pci_device_id cafe_nand_tbl[] = { | 818 | static const struct pci_device_id cafe_nand_tbl[] = { |
@@ -819,7 +827,8 @@ static int cafe_nand_resume(struct pci_dev *pdev) | |||
819 | { | 827 | { |
820 | uint32_t ctrl; | 828 | uint32_t ctrl; |
821 | struct mtd_info *mtd = pci_get_drvdata(pdev); | 829 | struct mtd_info *mtd = pci_get_drvdata(pdev); |
822 | struct cafe_priv *cafe = mtd->priv; | 830 | struct nand_chip *chip = mtd_to_nand(mtd); |
831 | struct cafe_priv *cafe = nand_get_controller_data(chip); | ||
823 | 832 | ||
824 | /* Start off by resetting the NAND controller completely */ | 833 | /* Start off by resetting the NAND controller completely */ |
825 | cafe_writel(cafe, 1, NAND_RESET); | 834 | cafe_writel(cafe, 1, NAND_RESET); |
diff --git a/drivers/mtd/nand/cmx270_nand.c b/drivers/mtd/nand/cmx270_nand.c index 66ec95e6ca6c..6f97ebba52c4 100644 --- a/drivers/mtd/nand/cmx270_nand.c +++ b/drivers/mtd/nand/cmx270_nand.c | |||
@@ -53,7 +53,7 @@ static struct mtd_partition partition_info[] = { | |||
53 | 53 | ||
54 | static u_char cmx270_read_byte(struct mtd_info *mtd) | 54 | static u_char cmx270_read_byte(struct mtd_info *mtd) |
55 | { | 55 | { |
56 | struct nand_chip *this = mtd->priv; | 56 | struct nand_chip *this = mtd_to_nand(mtd); |
57 | 57 | ||
58 | return (readl(this->IO_ADDR_R) >> 16); | 58 | return (readl(this->IO_ADDR_R) >> 16); |
59 | } | 59 | } |
@@ -61,7 +61,7 @@ static u_char cmx270_read_byte(struct mtd_info *mtd) | |||
61 | static void cmx270_write_buf(struct mtd_info *mtd, const u_char *buf, int len) | 61 | static void cmx270_write_buf(struct mtd_info *mtd, const u_char *buf, int len) |
62 | { | 62 | { |
63 | int i; | 63 | int i; |
64 | struct nand_chip *this = mtd->priv; | 64 | struct nand_chip *this = mtd_to_nand(mtd); |
65 | 65 | ||
66 | for (i=0; i<len; i++) | 66 | for (i=0; i<len; i++) |
67 | writel((*buf++ << 16), this->IO_ADDR_W); | 67 | writel((*buf++ << 16), this->IO_ADDR_W); |
@@ -70,7 +70,7 @@ static void cmx270_write_buf(struct mtd_info *mtd, const u_char *buf, int len) | |||
70 | static void cmx270_read_buf(struct mtd_info *mtd, u_char *buf, int len) | 70 | static void cmx270_read_buf(struct mtd_info *mtd, u_char *buf, int len) |
71 | { | 71 | { |
72 | int i; | 72 | int i; |
73 | struct nand_chip *this = mtd->priv; | 73 | struct nand_chip *this = mtd_to_nand(mtd); |
74 | 74 | ||
75 | for (i=0; i<len; i++) | 75 | for (i=0; i<len; i++) |
76 | *buf++ = readl(this->IO_ADDR_R) >> 16; | 76 | *buf++ = readl(this->IO_ADDR_R) >> 16; |
@@ -94,7 +94,7 @@ static void nand_cs_off(void) | |||
94 | static void cmx270_hwcontrol(struct mtd_info *mtd, int dat, | 94 | static void cmx270_hwcontrol(struct mtd_info *mtd, int dat, |
95 | unsigned int ctrl) | 95 | unsigned int ctrl) |
96 | { | 96 | { |
97 | struct nand_chip* this = mtd->priv; | 97 | struct nand_chip *this = mtd_to_nand(mtd); |
98 | unsigned int nandaddr = (unsigned int)this->IO_ADDR_W; | 98 | unsigned int nandaddr = (unsigned int)this->IO_ADDR_W; |
99 | 99 | ||
100 | dsb(); | 100 | dsb(); |
@@ -160,10 +160,8 @@ static int __init cmx270_init(void) | |||
160 | gpio_direction_input(GPIO_NAND_RB); | 160 | gpio_direction_input(GPIO_NAND_RB); |
161 | 161 | ||
162 | /* Allocate memory for MTD device structure and private data */ | 162 | /* Allocate memory for MTD device structure and private data */ |
163 | cmx270_nand_mtd = kzalloc(sizeof(struct mtd_info) + | 163 | this = kzalloc(sizeof(struct nand_chip), GFP_KERNEL); |
164 | sizeof(struct nand_chip), | 164 | if (!this) { |
165 | GFP_KERNEL); | ||
166 | if (!cmx270_nand_mtd) { | ||
167 | ret = -ENOMEM; | 165 | ret = -ENOMEM; |
168 | goto err_kzalloc; | 166 | goto err_kzalloc; |
169 | } | 167 | } |
@@ -175,12 +173,10 @@ static int __init cmx270_init(void) | |||
175 | goto err_ioremap; | 173 | goto err_ioremap; |
176 | } | 174 | } |
177 | 175 | ||
178 | /* Get pointer to private data */ | 176 | cmx270_nand_mtd = nand_to_mtd(this); |
179 | this = (struct nand_chip *)(&cmx270_nand_mtd[1]); | ||
180 | 177 | ||
181 | /* Link the private data with the MTD structure */ | 178 | /* Link the private data with the MTD structure */ |
182 | cmx270_nand_mtd->owner = THIS_MODULE; | 179 | cmx270_nand_mtd->owner = THIS_MODULE; |
183 | cmx270_nand_mtd->priv = this; | ||
184 | 180 | ||
185 | /* insert callbacks */ | 181 | /* insert callbacks */ |
186 | this->IO_ADDR_R = cmx270_nand_io; | 182 | this->IO_ADDR_R = cmx270_nand_io; |
@@ -216,7 +212,7 @@ static int __init cmx270_init(void) | |||
216 | err_scan: | 212 | err_scan: |
217 | iounmap(cmx270_nand_io); | 213 | iounmap(cmx270_nand_io); |
218 | err_ioremap: | 214 | err_ioremap: |
219 | kfree(cmx270_nand_mtd); | 215 | kfree(this); |
220 | err_kzalloc: | 216 | err_kzalloc: |
221 | gpio_free(GPIO_NAND_RB); | 217 | gpio_free(GPIO_NAND_RB); |
222 | err_gpio_request: | 218 | err_gpio_request: |
@@ -240,8 +236,7 @@ static void __exit cmx270_cleanup(void) | |||
240 | 236 | ||
241 | iounmap(cmx270_nand_io); | 237 | iounmap(cmx270_nand_io); |
242 | 238 | ||
243 | /* Free the MTD device structure */ | 239 | kfree(mtd_to_nand(cmx270_nand_mtd)); |
244 | kfree (cmx270_nand_mtd); | ||
245 | } | 240 | } |
246 | module_exit(cmx270_cleanup); | 241 | module_exit(cmx270_cleanup); |
247 | 242 | ||
diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/cs553x_nand.c index aec6045058c7..a65e4e0f57a1 100644 --- a/drivers/mtd/nand/cs553x_nand.c +++ b/drivers/mtd/nand/cs553x_nand.c | |||
@@ -97,7 +97,7 @@ | |||
97 | 97 | ||
98 | static void cs553x_read_buf(struct mtd_info *mtd, u_char *buf, int len) | 98 | static void cs553x_read_buf(struct mtd_info *mtd, u_char *buf, int len) |
99 | { | 99 | { |
100 | struct nand_chip *this = mtd->priv; | 100 | struct nand_chip *this = mtd_to_nand(mtd); |
101 | 101 | ||
102 | while (unlikely(len > 0x800)) { | 102 | while (unlikely(len > 0x800)) { |
103 | memcpy_fromio(buf, this->IO_ADDR_R, 0x800); | 103 | memcpy_fromio(buf, this->IO_ADDR_R, 0x800); |
@@ -109,7 +109,7 @@ static void cs553x_read_buf(struct mtd_info *mtd, u_char *buf, int len) | |||
109 | 109 | ||
110 | static void cs553x_write_buf(struct mtd_info *mtd, const u_char *buf, int len) | 110 | static void cs553x_write_buf(struct mtd_info *mtd, const u_char *buf, int len) |
111 | { | 111 | { |
112 | struct nand_chip *this = mtd->priv; | 112 | struct nand_chip *this = mtd_to_nand(mtd); |
113 | 113 | ||
114 | while (unlikely(len > 0x800)) { | 114 | while (unlikely(len > 0x800)) { |
115 | memcpy_toio(this->IO_ADDR_R, buf, 0x800); | 115 | memcpy_toio(this->IO_ADDR_R, buf, 0x800); |
@@ -121,13 +121,13 @@ static void cs553x_write_buf(struct mtd_info *mtd, const u_char *buf, int len) | |||
121 | 121 | ||
122 | static unsigned char cs553x_read_byte(struct mtd_info *mtd) | 122 | static unsigned char cs553x_read_byte(struct mtd_info *mtd) |
123 | { | 123 | { |
124 | struct nand_chip *this = mtd->priv; | 124 | struct nand_chip *this = mtd_to_nand(mtd); |
125 | return readb(this->IO_ADDR_R); | 125 | return readb(this->IO_ADDR_R); |
126 | } | 126 | } |
127 | 127 | ||
128 | static void cs553x_write_byte(struct mtd_info *mtd, u_char byte) | 128 | static void cs553x_write_byte(struct mtd_info *mtd, u_char byte) |
129 | { | 129 | { |
130 | struct nand_chip *this = mtd->priv; | 130 | struct nand_chip *this = mtd_to_nand(mtd); |
131 | int i = 100000; | 131 | int i = 100000; |
132 | 132 | ||
133 | while (i && readb(this->IO_ADDR_R + MM_NAND_STS) & CS_NAND_CTLR_BUSY) { | 133 | while (i && readb(this->IO_ADDR_R + MM_NAND_STS) & CS_NAND_CTLR_BUSY) { |
@@ -140,7 +140,7 @@ static void cs553x_write_byte(struct mtd_info *mtd, u_char byte) | |||
140 | static void cs553x_hwcontrol(struct mtd_info *mtd, int cmd, | 140 | static void cs553x_hwcontrol(struct mtd_info *mtd, int cmd, |
141 | unsigned int ctrl) | 141 | unsigned int ctrl) |
142 | { | 142 | { |
143 | struct nand_chip *this = mtd->priv; | 143 | struct nand_chip *this = mtd_to_nand(mtd); |
144 | void __iomem *mmio_base = this->IO_ADDR_R; | 144 | void __iomem *mmio_base = this->IO_ADDR_R; |
145 | if (ctrl & NAND_CTRL_CHANGE) { | 145 | if (ctrl & NAND_CTRL_CHANGE) { |
146 | unsigned char ctl = (ctrl & ~NAND_CTRL_CHANGE ) ^ 0x01; | 146 | unsigned char ctl = (ctrl & ~NAND_CTRL_CHANGE ) ^ 0x01; |
@@ -152,7 +152,7 @@ static void cs553x_hwcontrol(struct mtd_info *mtd, int cmd, | |||
152 | 152 | ||
153 | static int cs553x_device_ready(struct mtd_info *mtd) | 153 | static int cs553x_device_ready(struct mtd_info *mtd) |
154 | { | 154 | { |
155 | struct nand_chip *this = mtd->priv; | 155 | struct nand_chip *this = mtd_to_nand(mtd); |
156 | void __iomem *mmio_base = this->IO_ADDR_R; | 156 | void __iomem *mmio_base = this->IO_ADDR_R; |
157 | unsigned char foo = readb(mmio_base + MM_NAND_STS); | 157 | unsigned char foo = readb(mmio_base + MM_NAND_STS); |
158 | 158 | ||
@@ -161,7 +161,7 @@ static int cs553x_device_ready(struct mtd_info *mtd) | |||
161 | 161 | ||
162 | static void cs_enable_hwecc(struct mtd_info *mtd, int mode) | 162 | static void cs_enable_hwecc(struct mtd_info *mtd, int mode) |
163 | { | 163 | { |
164 | struct nand_chip *this = mtd->priv; | 164 | struct nand_chip *this = mtd_to_nand(mtd); |
165 | void __iomem *mmio_base = this->IO_ADDR_R; | 165 | void __iomem *mmio_base = this->IO_ADDR_R; |
166 | 166 | ||
167 | writeb(0x07, mmio_base + MM_NAND_ECC_CTL); | 167 | writeb(0x07, mmio_base + MM_NAND_ECC_CTL); |
@@ -170,7 +170,7 @@ static void cs_enable_hwecc(struct mtd_info *mtd, int mode) | |||
170 | static int cs_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) | 170 | static int cs_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code) |
171 | { | 171 | { |
172 | uint32_t ecc; | 172 | uint32_t ecc; |
173 | struct nand_chip *this = mtd->priv; | 173 | struct nand_chip *this = mtd_to_nand(mtd); |
174 | void __iomem *mmio_base = this->IO_ADDR_R; | 174 | void __iomem *mmio_base = this->IO_ADDR_R; |
175 | 175 | ||
176 | ecc = readl(mmio_base + MM_NAND_STS); | 176 | ecc = readl(mmio_base + MM_NAND_STS); |
@@ -197,17 +197,15 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr) | |||
197 | } | 197 | } |
198 | 198 | ||
199 | /* Allocate memory for MTD device structure and private data */ | 199 | /* Allocate memory for MTD device structure and private data */ |
200 | new_mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); | 200 | this = kzalloc(sizeof(struct nand_chip), GFP_KERNEL); |
201 | if (!new_mtd) { | 201 | if (!this) { |
202 | err = -ENOMEM; | 202 | err = -ENOMEM; |
203 | goto out; | 203 | goto out; |
204 | } | 204 | } |
205 | 205 | ||
206 | /* Get pointer to private data */ | 206 | new_mtd = nand_to_mtd(this); |
207 | this = (struct nand_chip *)(&new_mtd[1]); | ||
208 | 207 | ||
209 | /* Link the private data with the MTD structure */ | 208 | /* Link the private data with the MTD structure */ |
210 | new_mtd->priv = this; | ||
211 | new_mtd->owner = THIS_MODULE; | 209 | new_mtd->owner = THIS_MODULE; |
212 | 210 | ||
213 | /* map physical address */ | 211 | /* map physical address */ |
@@ -257,7 +255,7 @@ out_free: | |||
257 | out_ior: | 255 | out_ior: |
258 | iounmap(this->IO_ADDR_R); | 256 | iounmap(this->IO_ADDR_R); |
259 | out_mtd: | 257 | out_mtd: |
260 | kfree(new_mtd); | 258 | kfree(this); |
261 | out: | 259 | out: |
262 | return err; | 260 | return err; |
263 | } | 261 | } |
@@ -337,19 +335,19 @@ static void __exit cs553x_cleanup(void) | |||
337 | if (!mtd) | 335 | if (!mtd) |
338 | continue; | 336 | continue; |
339 | 337 | ||
340 | this = cs553x_mtd[i]->priv; | 338 | this = mtd_to_nand(mtd); |
341 | mmio_base = this->IO_ADDR_R; | 339 | mmio_base = this->IO_ADDR_R; |
342 | 340 | ||
343 | /* Release resources, unregister device */ | 341 | /* Release resources, unregister device */ |
344 | nand_release(cs553x_mtd[i]); | 342 | nand_release(mtd); |
345 | kfree(cs553x_mtd[i]->name); | 343 | kfree(mtd->name); |
346 | cs553x_mtd[i] = NULL; | 344 | cs553x_mtd[i] = NULL; |
347 | 345 | ||
348 | /* unmap physical address */ | 346 | /* unmap physical address */ |
349 | iounmap(mmio_base); | 347 | iounmap(mmio_base); |
350 | 348 | ||
351 | /* Free the MTD device structure */ | 349 | /* Free the MTD device structure */ |
352 | kfree(mtd); | 350 | kfree(this); |
353 | } | 351 | } |
354 | } | 352 | } |
355 | 353 | ||
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index c72313d66cf6..8cb821b6686e 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c | |||
@@ -53,7 +53,6 @@ | |||
53 | * outputs in a "wire-AND" configuration, with no per-chip signals. | 53 | * outputs in a "wire-AND" configuration, with no per-chip signals. |
54 | */ | 54 | */ |
55 | struct davinci_nand_info { | 55 | struct davinci_nand_info { |
56 | struct mtd_info mtd; | ||
57 | struct nand_chip chip; | 56 | struct nand_chip chip; |
58 | struct nand_ecclayout ecclayout; | 57 | struct nand_ecclayout ecclayout; |
59 | 58 | ||
@@ -80,8 +79,10 @@ struct davinci_nand_info { | |||
80 | static DEFINE_SPINLOCK(davinci_nand_lock); | 79 | static DEFINE_SPINLOCK(davinci_nand_lock); |
81 | static bool ecc4_busy; | 80 | static bool ecc4_busy; |
82 | 81 | ||
83 | #define to_davinci_nand(m) container_of(m, struct davinci_nand_info, mtd) | 82 | static inline struct davinci_nand_info *to_davinci_nand(struct mtd_info *mtd) |
84 | 83 | { | |
84 | return container_of(mtd_to_nand(mtd), struct davinci_nand_info, chip); | ||
85 | } | ||
85 | 86 | ||
86 | static inline unsigned int davinci_nand_readl(struct davinci_nand_info *info, | 87 | static inline unsigned int davinci_nand_readl(struct davinci_nand_info *info, |
87 | int offset) | 88 | int offset) |
@@ -106,7 +107,7 @@ static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd, | |||
106 | { | 107 | { |
107 | struct davinci_nand_info *info = to_davinci_nand(mtd); | 108 | struct davinci_nand_info *info = to_davinci_nand(mtd); |
108 | uint32_t addr = info->current_cs; | 109 | uint32_t addr = info->current_cs; |
109 | struct nand_chip *nand = mtd->priv; | 110 | struct nand_chip *nand = mtd_to_nand(mtd); |
110 | 111 | ||
111 | /* Did the control lines change? */ | 112 | /* Did the control lines change? */ |
112 | if (ctrl & NAND_CTRL_CHANGE) { | 113 | if (ctrl & NAND_CTRL_CHANGE) { |
@@ -192,7 +193,7 @@ static int nand_davinci_calculate_1bit(struct mtd_info *mtd, | |||
192 | static int nand_davinci_correct_1bit(struct mtd_info *mtd, u_char *dat, | 193 | static int nand_davinci_correct_1bit(struct mtd_info *mtd, u_char *dat, |
193 | u_char *read_ecc, u_char *calc_ecc) | 194 | u_char *read_ecc, u_char *calc_ecc) |
194 | { | 195 | { |
195 | struct nand_chip *chip = mtd->priv; | 196 | struct nand_chip *chip = mtd_to_nand(mtd); |
196 | uint32_t eccNand = read_ecc[0] | (read_ecc[1] << 8) | | 197 | uint32_t eccNand = read_ecc[0] | (read_ecc[1] << 8) | |
197 | (read_ecc[2] << 16); | 198 | (read_ecc[2] << 16); |
198 | uint32_t eccCalc = calc_ecc[0] | (calc_ecc[1] << 8) | | 199 | uint32_t eccCalc = calc_ecc[0] | (calc_ecc[1] << 8) | |
@@ -206,7 +207,7 @@ static int nand_davinci_correct_1bit(struct mtd_info *mtd, u_char *dat, | |||
206 | dat[diff >> (12 + 3)] ^= BIT((diff >> 12) & 7); | 207 | dat[diff >> (12 + 3)] ^= BIT((diff >> 12) & 7); |
207 | return 1; | 208 | return 1; |
208 | } else { | 209 | } else { |
209 | return -1; | 210 | return -EBADMSG; |
210 | } | 211 | } |
211 | } else if (!(diff & (diff - 1))) { | 212 | } else if (!(diff & (diff - 1))) { |
212 | /* Single bit ECC error in the ECC itself, | 213 | /* Single bit ECC error in the ECC itself, |
@@ -214,7 +215,7 @@ static int nand_davinci_correct_1bit(struct mtd_info *mtd, u_char *dat, | |||
214 | return 1; | 215 | return 1; |
215 | } else { | 216 | } else { |
216 | /* Uncorrectable error */ | 217 | /* Uncorrectable error */ |
217 | return -1; | 218 | return -EBADMSG; |
218 | } | 219 | } |
219 | 220 | ||
220 | } | 221 | } |
@@ -316,14 +317,6 @@ static int nand_davinci_correct_4bit(struct mtd_info *mtd, | |||
316 | unsigned num_errors, corrected; | 317 | unsigned num_errors, corrected; |
317 | unsigned long timeo; | 318 | unsigned long timeo; |
318 | 319 | ||
319 | /* All bytes 0xff? It's an erased page; ignore its ECC. */ | ||
320 | for (i = 0; i < 10; i++) { | ||
321 | if (ecc_code[i] != 0xff) | ||
322 | goto compare; | ||
323 | } | ||
324 | return 0; | ||
325 | |||
326 | compare: | ||
327 | /* Unpack ten bytes into eight 10 bit values. We know we're | 320 | /* Unpack ten bytes into eight 10 bit values. We know we're |
328 | * little-endian, and use type punning for less shifting/masking. | 321 | * little-endian, and use type punning for less shifting/masking. |
329 | */ | 322 | */ |
@@ -390,7 +383,7 @@ compare: | |||
390 | return 0; | 383 | return 0; |
391 | case 1: /* five or more errors detected */ | 384 | case 1: /* five or more errors detected */ |
392 | davinci_nand_readl(info, NAND_ERR_ERRVAL1_OFFSET); | 385 | davinci_nand_readl(info, NAND_ERR_ERRVAL1_OFFSET); |
393 | return -EIO; | 386 | return -EBADMSG; |
394 | case 2: /* error addresses computed */ | 387 | case 2: /* error addresses computed */ |
395 | case 3: | 388 | case 3: |
396 | num_errors = 1 + ((fsr >> 16) & 0x03); | 389 | num_errors = 1 + ((fsr >> 16) & 0x03); |
@@ -447,7 +440,7 @@ correct: | |||
447 | */ | 440 | */ |
448 | static void nand_davinci_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | 441 | static void nand_davinci_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) |
449 | { | 442 | { |
450 | struct nand_chip *chip = mtd->priv; | 443 | struct nand_chip *chip = mtd_to_nand(mtd); |
451 | 444 | ||
452 | if ((0x03 & ((unsigned)buf)) == 0 && (0x03 & len) == 0) | 445 | if ((0x03 & ((unsigned)buf)) == 0 && (0x03 & len) == 0) |
453 | ioread32_rep(chip->IO_ADDR_R, buf, len >> 2); | 446 | ioread32_rep(chip->IO_ADDR_R, buf, len >> 2); |
@@ -460,7 +453,7 @@ static void nand_davinci_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | |||
460 | static void nand_davinci_write_buf(struct mtd_info *mtd, | 453 | static void nand_davinci_write_buf(struct mtd_info *mtd, |
461 | const uint8_t *buf, int len) | 454 | const uint8_t *buf, int len) |
462 | { | 455 | { |
463 | struct nand_chip *chip = mtd->priv; | 456 | struct nand_chip *chip = mtd_to_nand(mtd); |
464 | 457 | ||
465 | if ((0x03 & ((unsigned)buf)) == 0 && (0x03 & len) == 0) | 458 | if ((0x03 & ((unsigned)buf)) == 0 && (0x03 & len) == 0) |
466 | iowrite32_rep(chip->IO_ADDR_R, buf, len >> 2); | 459 | iowrite32_rep(chip->IO_ADDR_R, buf, len >> 2); |
@@ -636,6 +629,7 @@ static int nand_davinci_probe(struct platform_device *pdev) | |||
636 | int ret; | 629 | int ret; |
637 | uint32_t val; | 630 | uint32_t val; |
638 | nand_ecc_modes_t ecc_mode; | 631 | nand_ecc_modes_t ecc_mode; |
632 | struct mtd_info *mtd; | ||
639 | 633 | ||
640 | pdata = nand_davinci_get_pdata(pdev); | 634 | pdata = nand_davinci_get_pdata(pdev); |
641 | if (IS_ERR(pdata)) | 635 | if (IS_ERR(pdata)) |
@@ -682,8 +676,9 @@ static int nand_davinci_probe(struct platform_device *pdev) | |||
682 | info->base = base; | 676 | info->base = base; |
683 | info->vaddr = vaddr; | 677 | info->vaddr = vaddr; |
684 | 678 | ||
685 | info->mtd.priv = &info->chip; | 679 | mtd = nand_to_mtd(&info->chip); |
686 | info->mtd.dev.parent = &pdev->dev; | 680 | mtd->dev.parent = &pdev->dev; |
681 | nand_set_flash_node(&info->chip, pdev->dev.of_node); | ||
687 | 682 | ||
688 | info->chip.IO_ADDR_R = vaddr; | 683 | info->chip.IO_ADDR_R = vaddr; |
689 | info->chip.IO_ADDR_W = vaddr; | 684 | info->chip.IO_ADDR_W = vaddr; |
@@ -746,6 +741,7 @@ static int nand_davinci_probe(struct platform_device *pdev) | |||
746 | info->chip.ecc.correct = nand_davinci_correct_4bit; | 741 | info->chip.ecc.correct = nand_davinci_correct_4bit; |
747 | info->chip.ecc.hwctl = nand_davinci_hwctl_4bit; | 742 | info->chip.ecc.hwctl = nand_davinci_hwctl_4bit; |
748 | info->chip.ecc.bytes = 10; | 743 | info->chip.ecc.bytes = 10; |
744 | info->chip.ecc.options = NAND_ECC_GENERIC_ERASED_CHECK; | ||
749 | } else { | 745 | } else { |
750 | info->chip.ecc.calculate = nand_davinci_calculate_1bit; | 746 | info->chip.ecc.calculate = nand_davinci_calculate_1bit; |
751 | info->chip.ecc.correct = nand_davinci_correct_1bit; | 747 | info->chip.ecc.correct = nand_davinci_correct_1bit; |
@@ -784,7 +780,7 @@ static int nand_davinci_probe(struct platform_device *pdev) | |||
784 | spin_unlock_irq(&davinci_nand_lock); | 780 | spin_unlock_irq(&davinci_nand_lock); |
785 | 781 | ||
786 | /* Scan to find existence of the device(s) */ | 782 | /* Scan to find existence of the device(s) */ |
787 | ret = nand_scan_ident(&info->mtd, pdata->mask_chipsel ? 2 : 1, NULL); | 783 | ret = nand_scan_ident(mtd, pdata->mask_chipsel ? 2 : 1, NULL); |
788 | if (ret < 0) { | 784 | if (ret < 0) { |
789 | dev_dbg(&pdev->dev, "no NAND chip(s) found\n"); | 785 | dev_dbg(&pdev->dev, "no NAND chip(s) found\n"); |
790 | goto err; | 786 | goto err; |
@@ -796,9 +792,9 @@ static int nand_davinci_probe(struct platform_device *pdev) | |||
796 | * usable: 10 bytes are needed, not 6. | 792 | * usable: 10 bytes are needed, not 6. |
797 | */ | 793 | */ |
798 | if (pdata->ecc_bits == 4) { | 794 | if (pdata->ecc_bits == 4) { |
799 | int chunks = info->mtd.writesize / 512; | 795 | int chunks = mtd->writesize / 512; |
800 | 796 | ||
801 | if (!chunks || info->mtd.oobsize < 16) { | 797 | if (!chunks || mtd->oobsize < 16) { |
802 | dev_dbg(&pdev->dev, "too small\n"); | 798 | dev_dbg(&pdev->dev, "too small\n"); |
803 | ret = -EINVAL; | 799 | ret = -EINVAL; |
804 | goto err; | 800 | goto err; |
@@ -810,8 +806,7 @@ static int nand_davinci_probe(struct platform_device *pdev) | |||
810 | */ | 806 | */ |
811 | if (chunks == 1) { | 807 | if (chunks == 1) { |
812 | info->ecclayout = hwecc4_small; | 808 | info->ecclayout = hwecc4_small; |
813 | info->ecclayout.oobfree[1].length = | 809 | info->ecclayout.oobfree[1].length = mtd->oobsize - 16; |
814 | info->mtd.oobsize - 16; | ||
815 | goto syndrome_done; | 810 | goto syndrome_done; |
816 | } | 811 | } |
817 | if (chunks == 4) { | 812 | if (chunks == 4) { |
@@ -832,20 +827,15 @@ syndrome_done: | |||
832 | info->chip.ecc.layout = &info->ecclayout; | 827 | info->chip.ecc.layout = &info->ecclayout; |
833 | } | 828 | } |
834 | 829 | ||
835 | ret = nand_scan_tail(&info->mtd); | 830 | ret = nand_scan_tail(mtd); |
836 | if (ret < 0) | 831 | if (ret < 0) |
837 | goto err; | 832 | goto err; |
838 | 833 | ||
839 | if (pdata->parts) | 834 | if (pdata->parts) |
840 | ret = mtd_device_parse_register(&info->mtd, NULL, NULL, | 835 | ret = mtd_device_parse_register(mtd, NULL, NULL, |
841 | pdata->parts, pdata->nr_parts); | 836 | pdata->parts, pdata->nr_parts); |
842 | else { | 837 | else |
843 | struct mtd_part_parser_data ppdata; | 838 | ret = mtd_device_register(mtd, NULL, 0); |
844 | |||
845 | ppdata.of_node = pdev->dev.of_node; | ||
846 | ret = mtd_device_parse_register(&info->mtd, NULL, &ppdata, | ||
847 | NULL, 0); | ||
848 | } | ||
849 | if (ret < 0) | 839 | if (ret < 0) |
850 | goto err; | 840 | goto err; |
851 | 841 | ||
@@ -875,7 +865,7 @@ static int nand_davinci_remove(struct platform_device *pdev) | |||
875 | ecc4_busy = false; | 865 | ecc4_busy = false; |
876 | spin_unlock_irq(&davinci_nand_lock); | 866 | spin_unlock_irq(&davinci_nand_lock); |
877 | 867 | ||
878 | nand_release(&info->mtd); | 868 | nand_release(nand_to_mtd(&info->chip)); |
879 | 869 | ||
880 | clk_disable_unprepare(info->clk); | 870 | clk_disable_unprepare(info->clk); |
881 | 871 | ||
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index 67eb2be0db87..30bf5f690f78 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c | |||
@@ -75,7 +75,10 @@ MODULE_PARM_DESC(onfi_timing_mode, | |||
75 | * this macro allows us to convert from an MTD structure to our own | 75 | * this macro allows us to convert from an MTD structure to our own |
76 | * device context (denali) structure. | 76 | * device context (denali) structure. |
77 | */ | 77 | */ |
78 | #define mtd_to_denali(m) container_of(m, struct denali_nand_info, mtd) | 78 | static inline struct denali_nand_info *mtd_to_denali(struct mtd_info *mtd) |
79 | { | ||
80 | return container_of(mtd_to_nand(mtd), struct denali_nand_info, nand); | ||
81 | } | ||
79 | 82 | ||
80 | /* | 83 | /* |
81 | * These constants are defined by the driver to enable common driver | 84 | * These constants are defined by the driver to enable common driver |
@@ -986,6 +989,8 @@ static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf, | |||
986 | * than one NAND connected. | 989 | * than one NAND connected. |
987 | */ | 990 | */ |
988 | if (err_byte < ECC_SECTOR_SIZE) { | 991 | if (err_byte < ECC_SECTOR_SIZE) { |
992 | struct mtd_info *mtd = | ||
993 | nand_to_mtd(&denali->nand); | ||
989 | int offset; | 994 | int offset; |
990 | 995 | ||
991 | offset = (err_sector * | 996 | offset = (err_sector * |
@@ -995,7 +1000,7 @@ static bool handle_ecc(struct denali_nand_info *denali, uint8_t *buf, | |||
995 | err_device; | 1000 | err_device; |
996 | /* correct the ECC error */ | 1001 | /* correct the ECC error */ |
997 | buf[offset] ^= err_correction_value; | 1002 | buf[offset] ^= err_correction_value; |
998 | denali->mtd.ecc_stats.corrected++; | 1003 | mtd->ecc_stats.corrected++; |
999 | bitflips++; | 1004 | bitflips++; |
1000 | } | 1005 | } |
1001 | } else { | 1006 | } else { |
@@ -1062,7 +1067,7 @@ static int write_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1062 | { | 1067 | { |
1063 | struct denali_nand_info *denali = mtd_to_denali(mtd); | 1068 | struct denali_nand_info *denali = mtd_to_denali(mtd); |
1064 | dma_addr_t addr = denali->buf.dma_buf; | 1069 | dma_addr_t addr = denali->buf.dma_buf; |
1065 | size_t size = denali->mtd.writesize + denali->mtd.oobsize; | 1070 | size_t size = mtd->writesize + mtd->oobsize; |
1066 | uint32_t irq_status; | 1071 | uint32_t irq_status; |
1067 | uint32_t irq_mask = INTR_STATUS__DMA_CMD_COMP | | 1072 | uint32_t irq_mask = INTR_STATUS__DMA_CMD_COMP | |
1068 | INTR_STATUS__PROGRAM_FAIL; | 1073 | INTR_STATUS__PROGRAM_FAIL; |
@@ -1160,7 +1165,7 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1160 | struct denali_nand_info *denali = mtd_to_denali(mtd); | 1165 | struct denali_nand_info *denali = mtd_to_denali(mtd); |
1161 | 1166 | ||
1162 | dma_addr_t addr = denali->buf.dma_buf; | 1167 | dma_addr_t addr = denali->buf.dma_buf; |
1163 | size_t size = denali->mtd.writesize + denali->mtd.oobsize; | 1168 | size_t size = mtd->writesize + mtd->oobsize; |
1164 | 1169 | ||
1165 | uint32_t irq_status; | 1170 | uint32_t irq_status; |
1166 | uint32_t irq_mask = INTR_STATUS__ECC_TRANSACTION_DONE | | 1171 | uint32_t irq_mask = INTR_STATUS__ECC_TRANSACTION_DONE | |
@@ -1193,14 +1198,14 @@ static int denali_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1193 | denali_enable_dma(denali, false); | 1198 | denali_enable_dma(denali, false); |
1194 | 1199 | ||
1195 | if (check_erased_page) { | 1200 | if (check_erased_page) { |
1196 | read_oob_data(&denali->mtd, chip->oob_poi, denali->page); | 1201 | read_oob_data(mtd, chip->oob_poi, denali->page); |
1197 | 1202 | ||
1198 | /* check ECC failures that may have occurred on erased pages */ | 1203 | /* check ECC failures that may have occurred on erased pages */ |
1199 | if (check_erased_page) { | 1204 | if (check_erased_page) { |
1200 | if (!is_erased(buf, denali->mtd.writesize)) | 1205 | if (!is_erased(buf, mtd->writesize)) |
1201 | denali->mtd.ecc_stats.failed++; | 1206 | mtd->ecc_stats.failed++; |
1202 | if (!is_erased(buf, denali->mtd.oobsize)) | 1207 | if (!is_erased(buf, mtd->oobsize)) |
1203 | denali->mtd.ecc_stats.failed++; | 1208 | mtd->ecc_stats.failed++; |
1204 | } | 1209 | } |
1205 | } | 1210 | } |
1206 | return max_bitflips; | 1211 | return max_bitflips; |
@@ -1211,7 +1216,7 @@ static int denali_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, | |||
1211 | { | 1216 | { |
1212 | struct denali_nand_info *denali = mtd_to_denali(mtd); | 1217 | struct denali_nand_info *denali = mtd_to_denali(mtd); |
1213 | dma_addr_t addr = denali->buf.dma_buf; | 1218 | dma_addr_t addr = denali->buf.dma_buf; |
1214 | size_t size = denali->mtd.writesize + denali->mtd.oobsize; | 1219 | size_t size = mtd->writesize + mtd->oobsize; |
1215 | uint32_t irq_mask = INTR_STATUS__DMA_CMD_COMP; | 1220 | uint32_t irq_mask = INTR_STATUS__DMA_CMD_COMP; |
1216 | 1221 | ||
1217 | if (page != denali->page) { | 1222 | if (page != denali->page) { |
@@ -1428,6 +1433,7 @@ static void denali_drv_init(struct denali_nand_info *denali) | |||
1428 | 1433 | ||
1429 | int denali_init(struct denali_nand_info *denali) | 1434 | int denali_init(struct denali_nand_info *denali) |
1430 | { | 1435 | { |
1436 | struct mtd_info *mtd = nand_to_mtd(&denali->nand); | ||
1431 | int ret; | 1437 | int ret; |
1432 | 1438 | ||
1433 | if (denali->platform == INTEL_CE4100) { | 1439 | if (denali->platform == INTEL_CE4100) { |
@@ -1447,7 +1453,7 @@ int denali_init(struct denali_nand_info *denali) | |||
1447 | if (!denali->buf.buf) | 1453 | if (!denali->buf.buf) |
1448 | return -ENOMEM; | 1454 | return -ENOMEM; |
1449 | 1455 | ||
1450 | denali->mtd.dev.parent = denali->dev; | 1456 | mtd->dev.parent = denali->dev; |
1451 | denali_hw_init(denali); | 1457 | denali_hw_init(denali); |
1452 | denali_drv_init(denali); | 1458 | denali_drv_init(denali); |
1453 | 1459 | ||
@@ -1463,8 +1469,7 @@ int denali_init(struct denali_nand_info *denali) | |||
1463 | 1469 | ||
1464 | /* now that our ISR is registered, we can enable interrupts */ | 1470 | /* now that our ISR is registered, we can enable interrupts */ |
1465 | denali_set_intr_modes(denali, true); | 1471 | denali_set_intr_modes(denali, true); |
1466 | denali->mtd.name = "denali-nand"; | 1472 | mtd->name = "denali-nand"; |
1467 | denali->mtd.priv = &denali->nand; | ||
1468 | 1473 | ||
1469 | /* register the driver with the NAND core subsystem */ | 1474 | /* register the driver with the NAND core subsystem */ |
1470 | denali->nand.select_chip = denali_select_chip; | 1475 | denali->nand.select_chip = denali_select_chip; |
@@ -1477,7 +1482,7 @@ int denali_init(struct denali_nand_info *denali) | |||
1477 | * this is the first stage in a two step process to register | 1482 | * this is the first stage in a two step process to register |
1478 | * with the nand subsystem | 1483 | * with the nand subsystem |
1479 | */ | 1484 | */ |
1480 | if (nand_scan_ident(&denali->mtd, denali->max_banks, NULL)) { | 1485 | if (nand_scan_ident(mtd, denali->max_banks, NULL)) { |
1481 | ret = -ENXIO; | 1486 | ret = -ENXIO; |
1482 | goto failed_req_irq; | 1487 | goto failed_req_irq; |
1483 | } | 1488 | } |
@@ -1485,7 +1490,7 @@ int denali_init(struct denali_nand_info *denali) | |||
1485 | /* allocate the right size buffer now */ | 1490 | /* allocate the right size buffer now */ |
1486 | devm_kfree(denali->dev, denali->buf.buf); | 1491 | devm_kfree(denali->dev, denali->buf.buf); |
1487 | denali->buf.buf = devm_kzalloc(denali->dev, | 1492 | denali->buf.buf = devm_kzalloc(denali->dev, |
1488 | denali->mtd.writesize + denali->mtd.oobsize, | 1493 | mtd->writesize + mtd->oobsize, |
1489 | GFP_KERNEL); | 1494 | GFP_KERNEL); |
1490 | if (!denali->buf.buf) { | 1495 | if (!denali->buf.buf) { |
1491 | ret = -ENOMEM; | 1496 | ret = -ENOMEM; |
@@ -1500,7 +1505,7 @@ int denali_init(struct denali_nand_info *denali) | |||
1500 | } | 1505 | } |
1501 | 1506 | ||
1502 | denali->buf.dma_buf = dma_map_single(denali->dev, denali->buf.buf, | 1507 | denali->buf.dma_buf = dma_map_single(denali->dev, denali->buf.buf, |
1503 | denali->mtd.writesize + denali->mtd.oobsize, | 1508 | mtd->writesize + mtd->oobsize, |
1504 | DMA_BIDIRECTIONAL); | 1509 | DMA_BIDIRECTIONAL); |
1505 | if (dma_mapping_error(denali->dev, denali->buf.dma_buf)) { | 1510 | if (dma_mapping_error(denali->dev, denali->buf.dma_buf)) { |
1506 | dev_err(denali->dev, "Spectra: failed to map DMA buffer\n"); | 1511 | dev_err(denali->dev, "Spectra: failed to map DMA buffer\n"); |
@@ -1521,10 +1526,10 @@ int denali_init(struct denali_nand_info *denali) | |||
1521 | denali->nand.bbt_erase_shift += (denali->devnum - 1); | 1526 | denali->nand.bbt_erase_shift += (denali->devnum - 1); |
1522 | denali->nand.phys_erase_shift = denali->nand.bbt_erase_shift; | 1527 | denali->nand.phys_erase_shift = denali->nand.bbt_erase_shift; |
1523 | denali->nand.chip_shift += (denali->devnum - 1); | 1528 | denali->nand.chip_shift += (denali->devnum - 1); |
1524 | denali->mtd.writesize <<= (denali->devnum - 1); | 1529 | mtd->writesize <<= (denali->devnum - 1); |
1525 | denali->mtd.oobsize <<= (denali->devnum - 1); | 1530 | mtd->oobsize <<= (denali->devnum - 1); |
1526 | denali->mtd.erasesize <<= (denali->devnum - 1); | 1531 | mtd->erasesize <<= (denali->devnum - 1); |
1527 | denali->mtd.size = denali->nand.numchips * denali->nand.chipsize; | 1532 | mtd->size = denali->nand.numchips * denali->nand.chipsize; |
1528 | denali->bbtskipbytes *= denali->devnum; | 1533 | denali->bbtskipbytes *= denali->devnum; |
1529 | 1534 | ||
1530 | /* | 1535 | /* |
@@ -1551,16 +1556,16 @@ int denali_init(struct denali_nand_info *denali) | |||
1551 | * SLC if possible. | 1556 | * SLC if possible. |
1552 | * */ | 1557 | * */ |
1553 | if (!nand_is_slc(&denali->nand) && | 1558 | if (!nand_is_slc(&denali->nand) && |
1554 | (denali->mtd.oobsize > (denali->bbtskipbytes + | 1559 | (mtd->oobsize > (denali->bbtskipbytes + |
1555 | ECC_15BITS * (denali->mtd.writesize / | 1560 | ECC_15BITS * (mtd->writesize / |
1556 | ECC_SECTOR_SIZE)))) { | 1561 | ECC_SECTOR_SIZE)))) { |
1557 | /* if MLC OOB size is large enough, use 15bit ECC*/ | 1562 | /* if MLC OOB size is large enough, use 15bit ECC*/ |
1558 | denali->nand.ecc.strength = 15; | 1563 | denali->nand.ecc.strength = 15; |
1559 | denali->nand.ecc.layout = &nand_15bit_oob; | 1564 | denali->nand.ecc.layout = &nand_15bit_oob; |
1560 | denali->nand.ecc.bytes = ECC_15BITS; | 1565 | denali->nand.ecc.bytes = ECC_15BITS; |
1561 | iowrite32(15, denali->flash_reg + ECC_CORRECTION); | 1566 | iowrite32(15, denali->flash_reg + ECC_CORRECTION); |
1562 | } else if (denali->mtd.oobsize < (denali->bbtskipbytes + | 1567 | } else if (mtd->oobsize < (denali->bbtskipbytes + |
1563 | ECC_8BITS * (denali->mtd.writesize / | 1568 | ECC_8BITS * (mtd->writesize / |
1564 | ECC_SECTOR_SIZE))) { | 1569 | ECC_SECTOR_SIZE))) { |
1565 | pr_err("Your NAND chip OOB is not large enough to contain 8bit ECC correction codes"); | 1570 | pr_err("Your NAND chip OOB is not large enough to contain 8bit ECC correction codes"); |
1566 | goto failed_req_irq; | 1571 | goto failed_req_irq; |
@@ -1574,11 +1579,11 @@ int denali_init(struct denali_nand_info *denali) | |||
1574 | denali->nand.ecc.bytes *= denali->devnum; | 1579 | denali->nand.ecc.bytes *= denali->devnum; |
1575 | denali->nand.ecc.strength *= denali->devnum; | 1580 | denali->nand.ecc.strength *= denali->devnum; |
1576 | denali->nand.ecc.layout->eccbytes *= | 1581 | denali->nand.ecc.layout->eccbytes *= |
1577 | denali->mtd.writesize / ECC_SECTOR_SIZE; | 1582 | mtd->writesize / ECC_SECTOR_SIZE; |
1578 | denali->nand.ecc.layout->oobfree[0].offset = | 1583 | denali->nand.ecc.layout->oobfree[0].offset = |
1579 | denali->bbtskipbytes + denali->nand.ecc.layout->eccbytes; | 1584 | denali->bbtskipbytes + denali->nand.ecc.layout->eccbytes; |
1580 | denali->nand.ecc.layout->oobfree[0].length = | 1585 | denali->nand.ecc.layout->oobfree[0].length = |
1581 | denali->mtd.oobsize - denali->nand.ecc.layout->eccbytes - | 1586 | mtd->oobsize - denali->nand.ecc.layout->eccbytes - |
1582 | denali->bbtskipbytes; | 1587 | denali->bbtskipbytes; |
1583 | 1588 | ||
1584 | /* | 1589 | /* |
@@ -1586,7 +1591,7 @@ int denali_init(struct denali_nand_info *denali) | |||
1586 | * contained by each nand chip. blksperchip will help driver to | 1591 | * contained by each nand chip. blksperchip will help driver to |
1587 | * know how many blocks is taken by FW. | 1592 | * know how many blocks is taken by FW. |
1588 | */ | 1593 | */ |
1589 | denali->totalblks = denali->mtd.size >> denali->nand.phys_erase_shift; | 1594 | denali->totalblks = mtd->size >> denali->nand.phys_erase_shift; |
1590 | denali->blksperchip = denali->totalblks / denali->nand.numchips; | 1595 | denali->blksperchip = denali->totalblks / denali->nand.numchips; |
1591 | 1596 | ||
1592 | /* override the default read operations */ | 1597 | /* override the default read operations */ |
@@ -1599,12 +1604,12 @@ int denali_init(struct denali_nand_info *denali) | |||
1599 | denali->nand.ecc.write_oob = denali_write_oob; | 1604 | denali->nand.ecc.write_oob = denali_write_oob; |
1600 | denali->nand.erase = denali_erase; | 1605 | denali->nand.erase = denali_erase; |
1601 | 1606 | ||
1602 | if (nand_scan_tail(&denali->mtd)) { | 1607 | if (nand_scan_tail(mtd)) { |
1603 | ret = -ENXIO; | 1608 | ret = -ENXIO; |
1604 | goto failed_req_irq; | 1609 | goto failed_req_irq; |
1605 | } | 1610 | } |
1606 | 1611 | ||
1607 | ret = mtd_device_register(&denali->mtd, NULL, 0); | 1612 | ret = mtd_device_register(mtd, NULL, 0); |
1608 | if (ret) { | 1613 | if (ret) { |
1609 | dev_err(denali->dev, "Spectra: Failed to register MTD: %d\n", | 1614 | dev_err(denali->dev, "Spectra: Failed to register MTD: %d\n", |
1610 | ret); | 1615 | ret); |
@@ -1622,9 +1627,17 @@ EXPORT_SYMBOL(denali_init); | |||
1622 | /* driver exit point */ | 1627 | /* driver exit point */ |
1623 | void denali_remove(struct denali_nand_info *denali) | 1628 | void denali_remove(struct denali_nand_info *denali) |
1624 | { | 1629 | { |
1630 | struct mtd_info *mtd = nand_to_mtd(&denali->nand); | ||
1631 | /* | ||
1632 | * Pre-compute DMA buffer size to avoid any problems in case | ||
1633 | * nand_release() ever changes in a way that mtd->writesize and | ||
1634 | * mtd->oobsize are not reliable after this call. | ||
1635 | */ | ||
1636 | int bufsize = mtd->writesize + mtd->oobsize; | ||
1637 | |||
1638 | nand_release(mtd); | ||
1625 | denali_irq_cleanup(denali->irq, denali); | 1639 | denali_irq_cleanup(denali->irq, denali); |
1626 | dma_unmap_single(denali->dev, denali->buf.dma_buf, | 1640 | dma_unmap_single(denali->dev, denali->buf.dma_buf, bufsize, |
1627 | denali->mtd.writesize + denali->mtd.oobsize, | ||
1628 | DMA_BIDIRECTIONAL); | 1641 | DMA_BIDIRECTIONAL); |
1629 | } | 1642 | } |
1630 | EXPORT_SYMBOL(denali_remove); | 1643 | EXPORT_SYMBOL(denali_remove); |
diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h index 4b12cd302819..e7ab4866a5da 100644 --- a/drivers/mtd/nand/denali.h +++ b/drivers/mtd/nand/denali.h | |||
@@ -450,7 +450,6 @@ struct nand_buf { | |||
450 | #define DT 3 | 450 | #define DT 3 |
451 | 451 | ||
452 | struct denali_nand_info { | 452 | struct denali_nand_info { |
453 | struct mtd_info mtd; | ||
454 | struct nand_chip nand; | 453 | struct nand_chip nand; |
455 | int flash_bank; /* currently selected chip */ | 454 | int flash_bank; /* currently selected chip */ |
456 | int status; | 455 | int status; |
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index 0802158a3f75..f170f3c31b34 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c | |||
@@ -74,10 +74,6 @@ struct doc_priv { | |||
74 | int (*late_init)(struct mtd_info *mtd); | 74 | int (*late_init)(struct mtd_info *mtd); |
75 | }; | 75 | }; |
76 | 76 | ||
77 | /* This is the syndrome computed by the HW ecc generator upon reading an empty | ||
78 | page, one with all 0xff for data and stored ecc code. */ | ||
79 | static u_char empty_read_syndrome[6] = { 0x26, 0xff, 0x6d, 0x47, 0x73, 0x7a }; | ||
80 | |||
81 | /* This is the ecc value computed by the HW ecc generator upon writing an empty | 77 | /* This is the ecc value computed by the HW ecc generator upon writing an empty |
82 | page, one with all 0xff for data. */ | 78 | page, one with all 0xff for data. */ |
83 | static u_char empty_write_ecc[6] = { 0x4b, 0x00, 0xe2, 0x0e, 0x93, 0xf7 }; | 79 | static u_char empty_write_ecc[6] = { 0x4b, 0x00, 0xe2, 0x0e, 0x93, 0xf7 }; |
@@ -299,8 +295,8 @@ static inline int DoC_WaitReady(struct doc_priv *doc) | |||
299 | 295 | ||
300 | static void doc2000_write_byte(struct mtd_info *mtd, u_char datum) | 296 | static void doc2000_write_byte(struct mtd_info *mtd, u_char datum) |
301 | { | 297 | { |
302 | struct nand_chip *this = mtd->priv; | 298 | struct nand_chip *this = mtd_to_nand(mtd); |
303 | struct doc_priv *doc = this->priv; | 299 | struct doc_priv *doc = nand_get_controller_data(this); |
304 | void __iomem *docptr = doc->virtadr; | 300 | void __iomem *docptr = doc->virtadr; |
305 | 301 | ||
306 | if (debug) | 302 | if (debug) |
@@ -311,8 +307,8 @@ static void doc2000_write_byte(struct mtd_info *mtd, u_char datum) | |||
311 | 307 | ||
312 | static u_char doc2000_read_byte(struct mtd_info *mtd) | 308 | static u_char doc2000_read_byte(struct mtd_info *mtd) |
313 | { | 309 | { |
314 | struct nand_chip *this = mtd->priv; | 310 | struct nand_chip *this = mtd_to_nand(mtd); |
315 | struct doc_priv *doc = this->priv; | 311 | struct doc_priv *doc = nand_get_controller_data(this); |
316 | void __iomem *docptr = doc->virtadr; | 312 | void __iomem *docptr = doc->virtadr; |
317 | u_char ret; | 313 | u_char ret; |
318 | 314 | ||
@@ -326,8 +322,8 @@ static u_char doc2000_read_byte(struct mtd_info *mtd) | |||
326 | 322 | ||
327 | static void doc2000_writebuf(struct mtd_info *mtd, const u_char *buf, int len) | 323 | static void doc2000_writebuf(struct mtd_info *mtd, const u_char *buf, int len) |
328 | { | 324 | { |
329 | struct nand_chip *this = mtd->priv; | 325 | struct nand_chip *this = mtd_to_nand(mtd); |
330 | struct doc_priv *doc = this->priv; | 326 | struct doc_priv *doc = nand_get_controller_data(this); |
331 | void __iomem *docptr = doc->virtadr; | 327 | void __iomem *docptr = doc->virtadr; |
332 | int i; | 328 | int i; |
333 | if (debug) | 329 | if (debug) |
@@ -343,8 +339,8 @@ static void doc2000_writebuf(struct mtd_info *mtd, const u_char *buf, int len) | |||
343 | 339 | ||
344 | static void doc2000_readbuf(struct mtd_info *mtd, u_char *buf, int len) | 340 | static void doc2000_readbuf(struct mtd_info *mtd, u_char *buf, int len) |
345 | { | 341 | { |
346 | struct nand_chip *this = mtd->priv; | 342 | struct nand_chip *this = mtd_to_nand(mtd); |
347 | struct doc_priv *doc = this->priv; | 343 | struct doc_priv *doc = nand_get_controller_data(this); |
348 | void __iomem *docptr = doc->virtadr; | 344 | void __iomem *docptr = doc->virtadr; |
349 | int i; | 345 | int i; |
350 | 346 | ||
@@ -358,8 +354,8 @@ static void doc2000_readbuf(struct mtd_info *mtd, u_char *buf, int len) | |||
358 | 354 | ||
359 | static void doc2000_readbuf_dword(struct mtd_info *mtd, u_char *buf, int len) | 355 | static void doc2000_readbuf_dword(struct mtd_info *mtd, u_char *buf, int len) |
360 | { | 356 | { |
361 | struct nand_chip *this = mtd->priv; | 357 | struct nand_chip *this = mtd_to_nand(mtd); |
362 | struct doc_priv *doc = this->priv; | 358 | struct doc_priv *doc = nand_get_controller_data(this); |
363 | void __iomem *docptr = doc->virtadr; | 359 | void __iomem *docptr = doc->virtadr; |
364 | int i; | 360 | int i; |
365 | 361 | ||
@@ -379,8 +375,8 @@ static void doc2000_readbuf_dword(struct mtd_info *mtd, u_char *buf, int len) | |||
379 | 375 | ||
380 | static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr) | 376 | static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr) |
381 | { | 377 | { |
382 | struct nand_chip *this = mtd->priv; | 378 | struct nand_chip *this = mtd_to_nand(mtd); |
383 | struct doc_priv *doc = this->priv; | 379 | struct doc_priv *doc = nand_get_controller_data(this); |
384 | uint16_t ret; | 380 | uint16_t ret; |
385 | 381 | ||
386 | doc200x_select_chip(mtd, nr); | 382 | doc200x_select_chip(mtd, nr); |
@@ -425,8 +421,8 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr) | |||
425 | 421 | ||
426 | static void __init doc2000_count_chips(struct mtd_info *mtd) | 422 | static void __init doc2000_count_chips(struct mtd_info *mtd) |
427 | { | 423 | { |
428 | struct nand_chip *this = mtd->priv; | 424 | struct nand_chip *this = mtd_to_nand(mtd); |
429 | struct doc_priv *doc = this->priv; | 425 | struct doc_priv *doc = nand_get_controller_data(this); |
430 | uint16_t mfrid; | 426 | uint16_t mfrid; |
431 | int i; | 427 | int i; |
432 | 428 | ||
@@ -447,7 +443,7 @@ static void __init doc2000_count_chips(struct mtd_info *mtd) | |||
447 | 443 | ||
448 | static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this) | 444 | static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this) |
449 | { | 445 | { |
450 | struct doc_priv *doc = this->priv; | 446 | struct doc_priv *doc = nand_get_controller_data(this); |
451 | 447 | ||
452 | int status; | 448 | int status; |
453 | 449 | ||
@@ -461,8 +457,8 @@ static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this) | |||
461 | 457 | ||
462 | static void doc2001_write_byte(struct mtd_info *mtd, u_char datum) | 458 | static void doc2001_write_byte(struct mtd_info *mtd, u_char datum) |
463 | { | 459 | { |
464 | struct nand_chip *this = mtd->priv; | 460 | struct nand_chip *this = mtd_to_nand(mtd); |
465 | struct doc_priv *doc = this->priv; | 461 | struct doc_priv *doc = nand_get_controller_data(this); |
466 | void __iomem *docptr = doc->virtadr; | 462 | void __iomem *docptr = doc->virtadr; |
467 | 463 | ||
468 | WriteDOC(datum, docptr, CDSNSlowIO); | 464 | WriteDOC(datum, docptr, CDSNSlowIO); |
@@ -472,8 +468,8 @@ static void doc2001_write_byte(struct mtd_info *mtd, u_char datum) | |||
472 | 468 | ||
473 | static u_char doc2001_read_byte(struct mtd_info *mtd) | 469 | static u_char doc2001_read_byte(struct mtd_info *mtd) |
474 | { | 470 | { |
475 | struct nand_chip *this = mtd->priv; | 471 | struct nand_chip *this = mtd_to_nand(mtd); |
476 | struct doc_priv *doc = this->priv; | 472 | struct doc_priv *doc = nand_get_controller_data(this); |
477 | void __iomem *docptr = doc->virtadr; | 473 | void __iomem *docptr = doc->virtadr; |
478 | 474 | ||
479 | //ReadDOC(docptr, CDSNSlowIO); | 475 | //ReadDOC(docptr, CDSNSlowIO); |
@@ -486,8 +482,8 @@ static u_char doc2001_read_byte(struct mtd_info *mtd) | |||
486 | 482 | ||
487 | static void doc2001_writebuf(struct mtd_info *mtd, const u_char *buf, int len) | 483 | static void doc2001_writebuf(struct mtd_info *mtd, const u_char *buf, int len) |
488 | { | 484 | { |
489 | struct nand_chip *this = mtd->priv; | 485 | struct nand_chip *this = mtd_to_nand(mtd); |
490 | struct doc_priv *doc = this->priv; | 486 | struct doc_priv *doc = nand_get_controller_data(this); |
491 | void __iomem *docptr = doc->virtadr; | 487 | void __iomem *docptr = doc->virtadr; |
492 | int i; | 488 | int i; |
493 | 489 | ||
@@ -499,8 +495,8 @@ static void doc2001_writebuf(struct mtd_info *mtd, const u_char *buf, int len) | |||
499 | 495 | ||
500 | static void doc2001_readbuf(struct mtd_info *mtd, u_char *buf, int len) | 496 | static void doc2001_readbuf(struct mtd_info *mtd, u_char *buf, int len) |
501 | { | 497 | { |
502 | struct nand_chip *this = mtd->priv; | 498 | struct nand_chip *this = mtd_to_nand(mtd); |
503 | struct doc_priv *doc = this->priv; | 499 | struct doc_priv *doc = nand_get_controller_data(this); |
504 | void __iomem *docptr = doc->virtadr; | 500 | void __iomem *docptr = doc->virtadr; |
505 | int i; | 501 | int i; |
506 | 502 | ||
@@ -516,8 +512,8 @@ static void doc2001_readbuf(struct mtd_info *mtd, u_char *buf, int len) | |||
516 | 512 | ||
517 | static u_char doc2001plus_read_byte(struct mtd_info *mtd) | 513 | static u_char doc2001plus_read_byte(struct mtd_info *mtd) |
518 | { | 514 | { |
519 | struct nand_chip *this = mtd->priv; | 515 | struct nand_chip *this = mtd_to_nand(mtd); |
520 | struct doc_priv *doc = this->priv; | 516 | struct doc_priv *doc = nand_get_controller_data(this); |
521 | void __iomem *docptr = doc->virtadr; | 517 | void __iomem *docptr = doc->virtadr; |
522 | u_char ret; | 518 | u_char ret; |
523 | 519 | ||
@@ -531,8 +527,8 @@ static u_char doc2001plus_read_byte(struct mtd_info *mtd) | |||
531 | 527 | ||
532 | static void doc2001plus_writebuf(struct mtd_info *mtd, const u_char *buf, int len) | 528 | static void doc2001plus_writebuf(struct mtd_info *mtd, const u_char *buf, int len) |
533 | { | 529 | { |
534 | struct nand_chip *this = mtd->priv; | 530 | struct nand_chip *this = mtd_to_nand(mtd); |
535 | struct doc_priv *doc = this->priv; | 531 | struct doc_priv *doc = nand_get_controller_data(this); |
536 | void __iomem *docptr = doc->virtadr; | 532 | void __iomem *docptr = doc->virtadr; |
537 | int i; | 533 | int i; |
538 | 534 | ||
@@ -549,8 +545,8 @@ static void doc2001plus_writebuf(struct mtd_info *mtd, const u_char *buf, int le | |||
549 | 545 | ||
550 | static void doc2001plus_readbuf(struct mtd_info *mtd, u_char *buf, int len) | 546 | static void doc2001plus_readbuf(struct mtd_info *mtd, u_char *buf, int len) |
551 | { | 547 | { |
552 | struct nand_chip *this = mtd->priv; | 548 | struct nand_chip *this = mtd_to_nand(mtd); |
553 | struct doc_priv *doc = this->priv; | 549 | struct doc_priv *doc = nand_get_controller_data(this); |
554 | void __iomem *docptr = doc->virtadr; | 550 | void __iomem *docptr = doc->virtadr; |
555 | int i; | 551 | int i; |
556 | 552 | ||
@@ -580,8 +576,8 @@ static void doc2001plus_readbuf(struct mtd_info *mtd, u_char *buf, int len) | |||
580 | 576 | ||
581 | static void doc2001plus_select_chip(struct mtd_info *mtd, int chip) | 577 | static void doc2001plus_select_chip(struct mtd_info *mtd, int chip) |
582 | { | 578 | { |
583 | struct nand_chip *this = mtd->priv; | 579 | struct nand_chip *this = mtd_to_nand(mtd); |
584 | struct doc_priv *doc = this->priv; | 580 | struct doc_priv *doc = nand_get_controller_data(this); |
585 | void __iomem *docptr = doc->virtadr; | 581 | void __iomem *docptr = doc->virtadr; |
586 | int floor = 0; | 582 | int floor = 0; |
587 | 583 | ||
@@ -607,8 +603,8 @@ static void doc2001plus_select_chip(struct mtd_info *mtd, int chip) | |||
607 | 603 | ||
608 | static void doc200x_select_chip(struct mtd_info *mtd, int chip) | 604 | static void doc200x_select_chip(struct mtd_info *mtd, int chip) |
609 | { | 605 | { |
610 | struct nand_chip *this = mtd->priv; | 606 | struct nand_chip *this = mtd_to_nand(mtd); |
611 | struct doc_priv *doc = this->priv; | 607 | struct doc_priv *doc = nand_get_controller_data(this); |
612 | void __iomem *docptr = doc->virtadr; | 608 | void __iomem *docptr = doc->virtadr; |
613 | int floor = 0; | 609 | int floor = 0; |
614 | 610 | ||
@@ -638,8 +634,8 @@ static void doc200x_select_chip(struct mtd_info *mtd, int chip) | |||
638 | static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd, | 634 | static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd, |
639 | unsigned int ctrl) | 635 | unsigned int ctrl) |
640 | { | 636 | { |
641 | struct nand_chip *this = mtd->priv; | 637 | struct nand_chip *this = mtd_to_nand(mtd); |
642 | struct doc_priv *doc = this->priv; | 638 | struct doc_priv *doc = nand_get_controller_data(this); |
643 | void __iomem *docptr = doc->virtadr; | 639 | void __iomem *docptr = doc->virtadr; |
644 | 640 | ||
645 | if (ctrl & NAND_CTRL_CHANGE) { | 641 | if (ctrl & NAND_CTRL_CHANGE) { |
@@ -661,8 +657,8 @@ static void doc200x_hwcontrol(struct mtd_info *mtd, int cmd, | |||
661 | 657 | ||
662 | static void doc2001plus_command(struct mtd_info *mtd, unsigned command, int column, int page_addr) | 658 | static void doc2001plus_command(struct mtd_info *mtd, unsigned command, int column, int page_addr) |
663 | { | 659 | { |
664 | struct nand_chip *this = mtd->priv; | 660 | struct nand_chip *this = mtd_to_nand(mtd); |
665 | struct doc_priv *doc = this->priv; | 661 | struct doc_priv *doc = nand_get_controller_data(this); |
666 | void __iomem *docptr = doc->virtadr; | 662 | void __iomem *docptr = doc->virtadr; |
667 | 663 | ||
668 | /* | 664 | /* |
@@ -767,8 +763,8 @@ static void doc2001plus_command(struct mtd_info *mtd, unsigned command, int colu | |||
767 | 763 | ||
768 | static int doc200x_dev_ready(struct mtd_info *mtd) | 764 | static int doc200x_dev_ready(struct mtd_info *mtd) |
769 | { | 765 | { |
770 | struct nand_chip *this = mtd->priv; | 766 | struct nand_chip *this = mtd_to_nand(mtd); |
771 | struct doc_priv *doc = this->priv; | 767 | struct doc_priv *doc = nand_get_controller_data(this); |
772 | void __iomem *docptr = doc->virtadr; | 768 | void __iomem *docptr = doc->virtadr; |
773 | 769 | ||
774 | if (DoC_is_MillenniumPlus(doc)) { | 770 | if (DoC_is_MillenniumPlus(doc)) { |
@@ -807,8 +803,8 @@ static int doc200x_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) | |||
807 | 803 | ||
808 | static void doc200x_enable_hwecc(struct mtd_info *mtd, int mode) | 804 | static void doc200x_enable_hwecc(struct mtd_info *mtd, int mode) |
809 | { | 805 | { |
810 | struct nand_chip *this = mtd->priv; | 806 | struct nand_chip *this = mtd_to_nand(mtd); |
811 | struct doc_priv *doc = this->priv; | 807 | struct doc_priv *doc = nand_get_controller_data(this); |
812 | void __iomem *docptr = doc->virtadr; | 808 | void __iomem *docptr = doc->virtadr; |
813 | 809 | ||
814 | /* Prime the ECC engine */ | 810 | /* Prime the ECC engine */ |
@@ -826,8 +822,8 @@ static void doc200x_enable_hwecc(struct mtd_info *mtd, int mode) | |||
826 | 822 | ||
827 | static void doc2001plus_enable_hwecc(struct mtd_info *mtd, int mode) | 823 | static void doc2001plus_enable_hwecc(struct mtd_info *mtd, int mode) |
828 | { | 824 | { |
829 | struct nand_chip *this = mtd->priv; | 825 | struct nand_chip *this = mtd_to_nand(mtd); |
830 | struct doc_priv *doc = this->priv; | 826 | struct doc_priv *doc = nand_get_controller_data(this); |
831 | void __iomem *docptr = doc->virtadr; | 827 | void __iomem *docptr = doc->virtadr; |
832 | 828 | ||
833 | /* Prime the ECC engine */ | 829 | /* Prime the ECC engine */ |
@@ -846,8 +842,8 @@ static void doc2001plus_enable_hwecc(struct mtd_info *mtd, int mode) | |||
846 | /* This code is only called on write */ | 842 | /* This code is only called on write */ |
847 | static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat, unsigned char *ecc_code) | 843 | static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat, unsigned char *ecc_code) |
848 | { | 844 | { |
849 | struct nand_chip *this = mtd->priv; | 845 | struct nand_chip *this = mtd_to_nand(mtd); |
850 | struct doc_priv *doc = this->priv; | 846 | struct doc_priv *doc = nand_get_controller_data(this); |
851 | void __iomem *docptr = doc->virtadr; | 847 | void __iomem *docptr = doc->virtadr; |
852 | int i; | 848 | int i; |
853 | int emptymatch = 1; | 849 | int emptymatch = 1; |
@@ -907,12 +903,11 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, | |||
907 | u_char *read_ecc, u_char *isnull) | 903 | u_char *read_ecc, u_char *isnull) |
908 | { | 904 | { |
909 | int i, ret = 0; | 905 | int i, ret = 0; |
910 | struct nand_chip *this = mtd->priv; | 906 | struct nand_chip *this = mtd_to_nand(mtd); |
911 | struct doc_priv *doc = this->priv; | 907 | struct doc_priv *doc = nand_get_controller_data(this); |
912 | void __iomem *docptr = doc->virtadr; | 908 | void __iomem *docptr = doc->virtadr; |
913 | uint8_t calc_ecc[6]; | 909 | uint8_t calc_ecc[6]; |
914 | volatile u_char dummy; | 910 | volatile u_char dummy; |
915 | int emptymatch = 1; | ||
916 | 911 | ||
917 | /* flush the pipeline */ | 912 | /* flush the pipeline */ |
918 | if (DoC_is_2000(doc)) { | 913 | if (DoC_is_2000(doc)) { |
@@ -936,37 +931,9 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, | |||
936 | calc_ecc[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i); | 931 | calc_ecc[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i); |
937 | else | 932 | else |
938 | calc_ecc[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i); | 933 | calc_ecc[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i); |
939 | if (calc_ecc[i] != empty_read_syndrome[i]) | ||
940 | emptymatch = 0; | ||
941 | } | ||
942 | /* If emptymatch=1, the read syndrome is consistent with an | ||
943 | all-0xff data and stored ecc block. Check the stored ecc. */ | ||
944 | if (emptymatch) { | ||
945 | for (i = 0; i < 6; i++) { | ||
946 | if (read_ecc[i] == 0xff) | ||
947 | continue; | ||
948 | emptymatch = 0; | ||
949 | break; | ||
950 | } | ||
951 | } | 934 | } |
952 | /* If emptymatch still =1, check the data block. */ | 935 | |
953 | if (emptymatch) { | 936 | ret = doc_ecc_decode(rs_decoder, dat, calc_ecc); |
954 | /* Note: this somewhat expensive test should not be triggered | ||
955 | often. It could be optimized away by examining the data in | ||
956 | the readbuf routine, and remembering the result. */ | ||
957 | for (i = 0; i < 512; i++) { | ||
958 | if (dat[i] == 0xff) | ||
959 | continue; | ||
960 | emptymatch = 0; | ||
961 | break; | ||
962 | } | ||
963 | } | ||
964 | /* If emptymatch still =1, this is almost certainly a freshly- | ||
965 | erased block, in which case the ECC will not come out right. | ||
966 | We'll suppress the error and tell the caller everything's | ||
967 | OK. Because it is. */ | ||
968 | if (!emptymatch) | ||
969 | ret = doc_ecc_decode(rs_decoder, dat, calc_ecc); | ||
970 | if (ret > 0) | 937 | if (ret > 0) |
971 | printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret); | 938 | printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret); |
972 | } | 939 | } |
@@ -1007,8 +974,8 @@ static struct nand_ecclayout doc200x_oobinfo = { | |||
1007 | mh1_page in the DOC private structure. */ | 974 | mh1_page in the DOC private structure. */ |
1008 | static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, const char *id, int findmirror) | 975 | static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, const char *id, int findmirror) |
1009 | { | 976 | { |
1010 | struct nand_chip *this = mtd->priv; | 977 | struct nand_chip *this = mtd_to_nand(mtd); |
1011 | struct doc_priv *doc = this->priv; | 978 | struct doc_priv *doc = nand_get_controller_data(this); |
1012 | unsigned offs; | 979 | unsigned offs; |
1013 | int ret; | 980 | int ret; |
1014 | size_t retlen; | 981 | size_t retlen; |
@@ -1050,8 +1017,8 @@ static int __init find_media_headers(struct mtd_info *mtd, u_char *buf, const ch | |||
1050 | 1017 | ||
1051 | static inline int __init nftl_partscan(struct mtd_info *mtd, struct mtd_partition *parts) | 1018 | static inline int __init nftl_partscan(struct mtd_info *mtd, struct mtd_partition *parts) |
1052 | { | 1019 | { |
1053 | struct nand_chip *this = mtd->priv; | 1020 | struct nand_chip *this = mtd_to_nand(mtd); |
1054 | struct doc_priv *doc = this->priv; | 1021 | struct doc_priv *doc = nand_get_controller_data(this); |
1055 | int ret = 0; | 1022 | int ret = 0; |
1056 | u_char *buf; | 1023 | u_char *buf; |
1057 | struct NFTLMediaHeader *mh; | 1024 | struct NFTLMediaHeader *mh; |
@@ -1152,8 +1119,8 @@ static inline int __init nftl_partscan(struct mtd_info *mtd, struct mtd_partitio | |||
1152 | /* This is a stripped-down copy of the code in inftlmount.c */ | 1119 | /* This is a stripped-down copy of the code in inftlmount.c */ |
1153 | static inline int __init inftl_partscan(struct mtd_info *mtd, struct mtd_partition *parts) | 1120 | static inline int __init inftl_partscan(struct mtd_info *mtd, struct mtd_partition *parts) |
1154 | { | 1121 | { |
1155 | struct nand_chip *this = mtd->priv; | 1122 | struct nand_chip *this = mtd_to_nand(mtd); |
1156 | struct doc_priv *doc = this->priv; | 1123 | struct doc_priv *doc = nand_get_controller_data(this); |
1157 | int ret = 0; | 1124 | int ret = 0; |
1158 | u_char *buf; | 1125 | u_char *buf; |
1159 | struct INFTLMediaHeader *mh; | 1126 | struct INFTLMediaHeader *mh; |
@@ -1272,8 +1239,8 @@ static inline int __init inftl_partscan(struct mtd_info *mtd, struct mtd_partiti | |||
1272 | static int __init nftl_scan_bbt(struct mtd_info *mtd) | 1239 | static int __init nftl_scan_bbt(struct mtd_info *mtd) |
1273 | { | 1240 | { |
1274 | int ret, numparts; | 1241 | int ret, numparts; |
1275 | struct nand_chip *this = mtd->priv; | 1242 | struct nand_chip *this = mtd_to_nand(mtd); |
1276 | struct doc_priv *doc = this->priv; | 1243 | struct doc_priv *doc = nand_get_controller_data(this); |
1277 | struct mtd_partition parts[2]; | 1244 | struct mtd_partition parts[2]; |
1278 | 1245 | ||
1279 | memset((char *)parts, 0, sizeof(parts)); | 1246 | memset((char *)parts, 0, sizeof(parts)); |
@@ -1307,8 +1274,8 @@ static int __init nftl_scan_bbt(struct mtd_info *mtd) | |||
1307 | static int __init inftl_scan_bbt(struct mtd_info *mtd) | 1274 | static int __init inftl_scan_bbt(struct mtd_info *mtd) |
1308 | { | 1275 | { |
1309 | int ret, numparts; | 1276 | int ret, numparts; |
1310 | struct nand_chip *this = mtd->priv; | 1277 | struct nand_chip *this = mtd_to_nand(mtd); |
1311 | struct doc_priv *doc = this->priv; | 1278 | struct doc_priv *doc = nand_get_controller_data(this); |
1312 | struct mtd_partition parts[5]; | 1279 | struct mtd_partition parts[5]; |
1313 | 1280 | ||
1314 | if (this->numchips > doc->chips_per_floor) { | 1281 | if (this->numchips > doc->chips_per_floor) { |
@@ -1360,8 +1327,8 @@ static int __init inftl_scan_bbt(struct mtd_info *mtd) | |||
1360 | 1327 | ||
1361 | static inline int __init doc2000_init(struct mtd_info *mtd) | 1328 | static inline int __init doc2000_init(struct mtd_info *mtd) |
1362 | { | 1329 | { |
1363 | struct nand_chip *this = mtd->priv; | 1330 | struct nand_chip *this = mtd_to_nand(mtd); |
1364 | struct doc_priv *doc = this->priv; | 1331 | struct doc_priv *doc = nand_get_controller_data(this); |
1365 | 1332 | ||
1366 | this->read_byte = doc2000_read_byte; | 1333 | this->read_byte = doc2000_read_byte; |
1367 | this->write_buf = doc2000_writebuf; | 1334 | this->write_buf = doc2000_writebuf; |
@@ -1376,8 +1343,8 @@ static inline int __init doc2000_init(struct mtd_info *mtd) | |||
1376 | 1343 | ||
1377 | static inline int __init doc2001_init(struct mtd_info *mtd) | 1344 | static inline int __init doc2001_init(struct mtd_info *mtd) |
1378 | { | 1345 | { |
1379 | struct nand_chip *this = mtd->priv; | 1346 | struct nand_chip *this = mtd_to_nand(mtd); |
1380 | struct doc_priv *doc = this->priv; | 1347 | struct doc_priv *doc = nand_get_controller_data(this); |
1381 | 1348 | ||
1382 | this->read_byte = doc2001_read_byte; | 1349 | this->read_byte = doc2001_read_byte; |
1383 | this->write_buf = doc2001_writebuf; | 1350 | this->write_buf = doc2001_writebuf; |
@@ -1406,8 +1373,8 @@ static inline int __init doc2001_init(struct mtd_info *mtd) | |||
1406 | 1373 | ||
1407 | static inline int __init doc2001plus_init(struct mtd_info *mtd) | 1374 | static inline int __init doc2001plus_init(struct mtd_info *mtd) |
1408 | { | 1375 | { |
1409 | struct nand_chip *this = mtd->priv; | 1376 | struct nand_chip *this = mtd_to_nand(mtd); |
1410 | struct doc_priv *doc = this->priv; | 1377 | struct doc_priv *doc = nand_get_controller_data(this); |
1411 | 1378 | ||
1412 | this->read_byte = doc2001plus_read_byte; | 1379 | this->read_byte = doc2001plus_read_byte; |
1413 | this->write_buf = doc2001plus_writebuf; | 1380 | this->write_buf = doc2001plus_writebuf; |
@@ -1523,8 +1490,8 @@ static int __init doc_probe(unsigned long physadr) | |||
1523 | for (mtd = doclist; mtd; mtd = doc->nextdoc) { | 1490 | for (mtd = doclist; mtd; mtd = doc->nextdoc) { |
1524 | unsigned char oldval; | 1491 | unsigned char oldval; |
1525 | unsigned char newval; | 1492 | unsigned char newval; |
1526 | nand = mtd->priv; | 1493 | nand = mtd_to_nand(mtd); |
1527 | doc = nand->priv; | 1494 | doc = nand_get_controller_data(nand); |
1528 | /* Use the alias resolution register to determine if this is | 1495 | /* Use the alias resolution register to determine if this is |
1529 | in fact the same DOC aliased to a new address. If writes | 1496 | in fact the same DOC aliased to a new address. If writes |
1530 | to one chip's alias resolution register change the value on | 1497 | to one chip's alias resolution register change the value on |
@@ -1556,23 +1523,22 @@ static int __init doc_probe(unsigned long physadr) | |||
1556 | 1523 | ||
1557 | printk(KERN_NOTICE "DiskOnChip found at 0x%lx\n", physadr); | 1524 | printk(KERN_NOTICE "DiskOnChip found at 0x%lx\n", physadr); |
1558 | 1525 | ||
1559 | len = sizeof(struct mtd_info) + | 1526 | len = sizeof(struct nand_chip) + sizeof(struct doc_priv) + |
1560 | sizeof(struct nand_chip) + sizeof(struct doc_priv) + (2 * sizeof(struct nand_bbt_descr)); | 1527 | (2 * sizeof(struct nand_bbt_descr)); |
1561 | mtd = kzalloc(len, GFP_KERNEL); | 1528 | nand = kzalloc(len, GFP_KERNEL); |
1562 | if (!mtd) { | 1529 | if (!nand) { |
1563 | ret = -ENOMEM; | 1530 | ret = -ENOMEM; |
1564 | goto fail; | 1531 | goto fail; |
1565 | } | 1532 | } |
1566 | 1533 | ||
1567 | nand = (struct nand_chip *) (mtd + 1); | 1534 | mtd = nand_to_mtd(nand); |
1568 | doc = (struct doc_priv *) (nand + 1); | 1535 | doc = (struct doc_priv *) (nand + 1); |
1569 | nand->bbt_td = (struct nand_bbt_descr *) (doc + 1); | 1536 | nand->bbt_td = (struct nand_bbt_descr *) (doc + 1); |
1570 | nand->bbt_md = nand->bbt_td + 1; | 1537 | nand->bbt_md = nand->bbt_td + 1; |
1571 | 1538 | ||
1572 | mtd->priv = nand; | ||
1573 | mtd->owner = THIS_MODULE; | 1539 | mtd->owner = THIS_MODULE; |
1574 | 1540 | ||
1575 | nand->priv = doc; | 1541 | nand_set_controller_data(nand, doc); |
1576 | nand->select_chip = doc200x_select_chip; | 1542 | nand->select_chip = doc200x_select_chip; |
1577 | nand->cmd_ctrl = doc200x_hwcontrol; | 1543 | nand->cmd_ctrl = doc200x_hwcontrol; |
1578 | nand->dev_ready = doc200x_dev_ready; | 1544 | nand->dev_ready = doc200x_dev_ready; |
@@ -1587,6 +1553,7 @@ static int __init doc_probe(unsigned long physadr) | |||
1587 | nand->ecc.size = 512; | 1553 | nand->ecc.size = 512; |
1588 | nand->ecc.bytes = 6; | 1554 | nand->ecc.bytes = 6; |
1589 | nand->ecc.strength = 2; | 1555 | nand->ecc.strength = 2; |
1556 | nand->ecc.options = NAND_ECC_GENERIC_ERASED_CHECK; | ||
1590 | nand->bbt_options = NAND_BBT_USE_FLASH; | 1557 | nand->bbt_options = NAND_BBT_USE_FLASH; |
1591 | /* Skip the automatic BBT scan so we can run it manually */ | 1558 | /* Skip the automatic BBT scan so we can run it manually */ |
1592 | nand->options |= NAND_SKIP_BBTSCAN; | 1559 | nand->options |= NAND_SKIP_BBTSCAN; |
@@ -1615,7 +1582,7 @@ static int __init doc_probe(unsigned long physadr) | |||
1615 | haven't yet added it. This is handled without incident by | 1582 | haven't yet added it. This is handled without incident by |
1616 | mtd_device_unregister, as far as I can tell. */ | 1583 | mtd_device_unregister, as far as I can tell. */ |
1617 | nand_release(mtd); | 1584 | nand_release(mtd); |
1618 | kfree(mtd); | 1585 | kfree(nand); |
1619 | goto fail; | 1586 | goto fail; |
1620 | } | 1587 | } |
1621 | 1588 | ||
@@ -1643,14 +1610,14 @@ static void release_nanddoc(void) | |||
1643 | struct doc_priv *doc; | 1610 | struct doc_priv *doc; |
1644 | 1611 | ||
1645 | for (mtd = doclist; mtd; mtd = nextmtd) { | 1612 | for (mtd = doclist; mtd; mtd = nextmtd) { |
1646 | nand = mtd->priv; | 1613 | nand = mtd_to_nand(mtd); |
1647 | doc = nand->priv; | 1614 | doc = nand_get_controller_data(nand); |
1648 | 1615 | ||
1649 | nextmtd = doc->nextdoc; | 1616 | nextmtd = doc->nextdoc; |
1650 | nand_release(mtd); | 1617 | nand_release(mtd); |
1651 | iounmap(doc->virtadr); | 1618 | iounmap(doc->virtadr); |
1652 | release_mem_region(doc->physadr, DOC_IOREMAP_LEN); | 1619 | release_mem_region(doc->physadr, DOC_IOREMAP_LEN); |
1653 | kfree(mtd); | 1620 | kfree(nand); |
1654 | } | 1621 | } |
1655 | } | 1622 | } |
1656 | 1623 | ||
diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c index 408cf69b854b..df4165b02c62 100644 --- a/drivers/mtd/nand/docg4.c +++ b/drivers/mtd/nand/docg4.c | |||
@@ -242,7 +242,7 @@ static inline void write_nop(void __iomem *docptr) | |||
242 | static void docg4_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | 242 | static void docg4_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) |
243 | { | 243 | { |
244 | int i; | 244 | int i; |
245 | struct nand_chip *nand = mtd->priv; | 245 | struct nand_chip *nand = mtd_to_nand(mtd); |
246 | uint16_t *p = (uint16_t *) buf; | 246 | uint16_t *p = (uint16_t *) buf; |
247 | len >>= 1; | 247 | len >>= 1; |
248 | 248 | ||
@@ -253,7 +253,7 @@ static void docg4_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | |||
253 | static void docg4_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) | 253 | static void docg4_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) |
254 | { | 254 | { |
255 | int i; | 255 | int i; |
256 | struct nand_chip *nand = mtd->priv; | 256 | struct nand_chip *nand = mtd_to_nand(mtd); |
257 | uint16_t *p = (uint16_t *) buf; | 257 | uint16_t *p = (uint16_t *) buf; |
258 | len >>= 1; | 258 | len >>= 1; |
259 | 259 | ||
@@ -297,7 +297,7 @@ static int poll_status(struct docg4_priv *doc) | |||
297 | static int docg4_wait(struct mtd_info *mtd, struct nand_chip *nand) | 297 | static int docg4_wait(struct mtd_info *mtd, struct nand_chip *nand) |
298 | { | 298 | { |
299 | 299 | ||
300 | struct docg4_priv *doc = nand->priv; | 300 | struct docg4_priv *doc = nand_get_controller_data(nand); |
301 | int status = NAND_STATUS_WP; /* inverse logic?? */ | 301 | int status = NAND_STATUS_WP; /* inverse logic?? */ |
302 | dev_dbg(doc->dev, "%s...\n", __func__); | 302 | dev_dbg(doc->dev, "%s...\n", __func__); |
303 | 303 | ||
@@ -318,8 +318,8 @@ static void docg4_select_chip(struct mtd_info *mtd, int chip) | |||
318 | * Select among multiple cascaded chips ("floors"). Multiple floors are | 318 | * Select among multiple cascaded chips ("floors"). Multiple floors are |
319 | * not yet supported, so the only valid non-negative value is 0. | 319 | * not yet supported, so the only valid non-negative value is 0. |
320 | */ | 320 | */ |
321 | struct nand_chip *nand = mtd->priv; | 321 | struct nand_chip *nand = mtd_to_nand(mtd); |
322 | struct docg4_priv *doc = nand->priv; | 322 | struct docg4_priv *doc = nand_get_controller_data(nand); |
323 | void __iomem *docptr = doc->virtadr; | 323 | void __iomem *docptr = doc->virtadr; |
324 | 324 | ||
325 | dev_dbg(doc->dev, "%s: chip %d\n", __func__, chip); | 325 | dev_dbg(doc->dev, "%s: chip %d\n", __func__, chip); |
@@ -337,8 +337,8 @@ static void reset(struct mtd_info *mtd) | |||
337 | { | 337 | { |
338 | /* full device reset */ | 338 | /* full device reset */ |
339 | 339 | ||
340 | struct nand_chip *nand = mtd->priv; | 340 | struct nand_chip *nand = mtd_to_nand(mtd); |
341 | struct docg4_priv *doc = nand->priv; | 341 | struct docg4_priv *doc = nand_get_controller_data(nand); |
342 | void __iomem *docptr = doc->virtadr; | 342 | void __iomem *docptr = doc->virtadr; |
343 | 343 | ||
344 | writew(DOC_ASICMODE_RESET | DOC_ASICMODE_MDWREN, | 344 | writew(DOC_ASICMODE_RESET | DOC_ASICMODE_MDWREN, |
@@ -375,8 +375,8 @@ static int correct_data(struct mtd_info *mtd, uint8_t *buf, int page) | |||
375 | * Up to four bitflips can be corrected. | 375 | * Up to four bitflips can be corrected. |
376 | */ | 376 | */ |
377 | 377 | ||
378 | struct nand_chip *nand = mtd->priv; | 378 | struct nand_chip *nand = mtd_to_nand(mtd); |
379 | struct docg4_priv *doc = nand->priv; | 379 | struct docg4_priv *doc = nand_get_controller_data(nand); |
380 | void __iomem *docptr = doc->virtadr; | 380 | void __iomem *docptr = doc->virtadr; |
381 | int i, numerrs, errpos[4]; | 381 | int i, numerrs, errpos[4]; |
382 | const uint8_t blank_read_hwecc[8] = { | 382 | const uint8_t blank_read_hwecc[8] = { |
@@ -464,8 +464,8 @@ static int correct_data(struct mtd_info *mtd, uint8_t *buf, int page) | |||
464 | 464 | ||
465 | static uint8_t docg4_read_byte(struct mtd_info *mtd) | 465 | static uint8_t docg4_read_byte(struct mtd_info *mtd) |
466 | { | 466 | { |
467 | struct nand_chip *nand = mtd->priv; | 467 | struct nand_chip *nand = mtd_to_nand(mtd); |
468 | struct docg4_priv *doc = nand->priv; | 468 | struct docg4_priv *doc = nand_get_controller_data(nand); |
469 | 469 | ||
470 | dev_dbg(doc->dev, "%s\n", __func__); | 470 | dev_dbg(doc->dev, "%s\n", __func__); |
471 | 471 | ||
@@ -545,8 +545,8 @@ static int pageprog(struct mtd_info *mtd) | |||
545 | * internal buffer out to the flash array, or some such. | 545 | * internal buffer out to the flash array, or some such. |
546 | */ | 546 | */ |
547 | 547 | ||
548 | struct nand_chip *nand = mtd->priv; | 548 | struct nand_chip *nand = mtd_to_nand(mtd); |
549 | struct docg4_priv *doc = nand->priv; | 549 | struct docg4_priv *doc = nand_get_controller_data(nand); |
550 | void __iomem *docptr = doc->virtadr; | 550 | void __iomem *docptr = doc->virtadr; |
551 | int retval = 0; | 551 | int retval = 0; |
552 | 552 | ||
@@ -582,8 +582,8 @@ static void sequence_reset(struct mtd_info *mtd) | |||
582 | { | 582 | { |
583 | /* common starting sequence for all operations */ | 583 | /* common starting sequence for all operations */ |
584 | 584 | ||
585 | struct nand_chip *nand = mtd->priv; | 585 | struct nand_chip *nand = mtd_to_nand(mtd); |
586 | struct docg4_priv *doc = nand->priv; | 586 | struct docg4_priv *doc = nand_get_controller_data(nand); |
587 | void __iomem *docptr = doc->virtadr; | 587 | void __iomem *docptr = doc->virtadr; |
588 | 588 | ||
589 | writew(DOC_CTRL_UNKNOWN | DOC_CTRL_CE, docptr + DOC_FLASHCONTROL); | 589 | writew(DOC_CTRL_UNKNOWN | DOC_CTRL_CE, docptr + DOC_FLASHCONTROL); |
@@ -599,8 +599,8 @@ static void read_page_prologue(struct mtd_info *mtd, uint32_t docg4_addr) | |||
599 | { | 599 | { |
600 | /* first step in reading a page */ | 600 | /* first step in reading a page */ |
601 | 601 | ||
602 | struct nand_chip *nand = mtd->priv; | 602 | struct nand_chip *nand = mtd_to_nand(mtd); |
603 | struct docg4_priv *doc = nand->priv; | 603 | struct docg4_priv *doc = nand_get_controller_data(nand); |
604 | void __iomem *docptr = doc->virtadr; | 604 | void __iomem *docptr = doc->virtadr; |
605 | 605 | ||
606 | dev_dbg(doc->dev, | 606 | dev_dbg(doc->dev, |
@@ -626,8 +626,8 @@ static void write_page_prologue(struct mtd_info *mtd, uint32_t docg4_addr) | |||
626 | { | 626 | { |
627 | /* first step in writing a page */ | 627 | /* first step in writing a page */ |
628 | 628 | ||
629 | struct nand_chip *nand = mtd->priv; | 629 | struct nand_chip *nand = mtd_to_nand(mtd); |
630 | struct docg4_priv *doc = nand->priv; | 630 | struct docg4_priv *doc = nand_get_controller_data(nand); |
631 | void __iomem *docptr = doc->virtadr; | 631 | void __iomem *docptr = doc->virtadr; |
632 | 632 | ||
633 | dev_dbg(doc->dev, | 633 | dev_dbg(doc->dev, |
@@ -691,8 +691,8 @@ static void docg4_command(struct mtd_info *mtd, unsigned command, int column, | |||
691 | { | 691 | { |
692 | /* handle standard nand commands */ | 692 | /* handle standard nand commands */ |
693 | 693 | ||
694 | struct nand_chip *nand = mtd->priv; | 694 | struct nand_chip *nand = mtd_to_nand(mtd); |
695 | struct docg4_priv *doc = nand->priv; | 695 | struct docg4_priv *doc = nand_get_controller_data(nand); |
696 | uint32_t g4_addr = mtd_to_docg4_address(page_addr, column); | 696 | uint32_t g4_addr = mtd_to_docg4_address(page_addr, column); |
697 | 697 | ||
698 | dev_dbg(doc->dev, "%s %x, page_addr=%x, column=%x\n", | 698 | dev_dbg(doc->dev, "%s %x, page_addr=%x, column=%x\n", |
@@ -756,7 +756,7 @@ static void docg4_command(struct mtd_info *mtd, unsigned command, int column, | |||
756 | static int read_page(struct mtd_info *mtd, struct nand_chip *nand, | 756 | static int read_page(struct mtd_info *mtd, struct nand_chip *nand, |
757 | uint8_t *buf, int page, bool use_ecc) | 757 | uint8_t *buf, int page, bool use_ecc) |
758 | { | 758 | { |
759 | struct docg4_priv *doc = nand->priv; | 759 | struct docg4_priv *doc = nand_get_controller_data(nand); |
760 | void __iomem *docptr = doc->virtadr; | 760 | void __iomem *docptr = doc->virtadr; |
761 | uint16_t status, edc_err, *buf16; | 761 | uint16_t status, edc_err, *buf16; |
762 | int bits_corrected = 0; | 762 | int bits_corrected = 0; |
@@ -836,7 +836,7 @@ static int docg4_read_page(struct mtd_info *mtd, struct nand_chip *nand, | |||
836 | static int docg4_read_oob(struct mtd_info *mtd, struct nand_chip *nand, | 836 | static int docg4_read_oob(struct mtd_info *mtd, struct nand_chip *nand, |
837 | int page) | 837 | int page) |
838 | { | 838 | { |
839 | struct docg4_priv *doc = nand->priv; | 839 | struct docg4_priv *doc = nand_get_controller_data(nand); |
840 | void __iomem *docptr = doc->virtadr; | 840 | void __iomem *docptr = doc->virtadr; |
841 | uint16_t status; | 841 | uint16_t status; |
842 | 842 | ||
@@ -874,8 +874,8 @@ static int docg4_read_oob(struct mtd_info *mtd, struct nand_chip *nand, | |||
874 | 874 | ||
875 | static int docg4_erase_block(struct mtd_info *mtd, int page) | 875 | static int docg4_erase_block(struct mtd_info *mtd, int page) |
876 | { | 876 | { |
877 | struct nand_chip *nand = mtd->priv; | 877 | struct nand_chip *nand = mtd_to_nand(mtd); |
878 | struct docg4_priv *doc = nand->priv; | 878 | struct docg4_priv *doc = nand_get_controller_data(nand); |
879 | void __iomem *docptr = doc->virtadr; | 879 | void __iomem *docptr = doc->virtadr; |
880 | uint16_t g4_page; | 880 | uint16_t g4_page; |
881 | 881 | ||
@@ -923,7 +923,7 @@ static int docg4_erase_block(struct mtd_info *mtd, int page) | |||
923 | static int write_page(struct mtd_info *mtd, struct nand_chip *nand, | 923 | static int write_page(struct mtd_info *mtd, struct nand_chip *nand, |
924 | const uint8_t *buf, bool use_ecc) | 924 | const uint8_t *buf, bool use_ecc) |
925 | { | 925 | { |
926 | struct docg4_priv *doc = nand->priv; | 926 | struct docg4_priv *doc = nand_get_controller_data(nand); |
927 | void __iomem *docptr = doc->virtadr; | 927 | void __iomem *docptr = doc->virtadr; |
928 | uint8_t ecc_buf[8]; | 928 | uint8_t ecc_buf[8]; |
929 | 929 | ||
@@ -1003,7 +1003,7 @@ static int docg4_write_oob(struct mtd_info *mtd, struct nand_chip *nand, | |||
1003 | */ | 1003 | */ |
1004 | 1004 | ||
1005 | /* note that bytes 7..14 are hw generated hamming/ecc and overwritten */ | 1005 | /* note that bytes 7..14 are hw generated hamming/ecc and overwritten */ |
1006 | struct docg4_priv *doc = nand->priv; | 1006 | struct docg4_priv *doc = nand_get_controller_data(nand); |
1007 | doc->oob_page = page; | 1007 | doc->oob_page = page; |
1008 | memcpy(doc->oob_buf, nand->oob_poi, 16); | 1008 | memcpy(doc->oob_buf, nand->oob_poi, 16); |
1009 | return 0; | 1009 | return 0; |
@@ -1016,8 +1016,8 @@ static int __init read_factory_bbt(struct mtd_info *mtd) | |||
1016 | * update the memory-based bbt accordingly. | 1016 | * update the memory-based bbt accordingly. |
1017 | */ | 1017 | */ |
1018 | 1018 | ||
1019 | struct nand_chip *nand = mtd->priv; | 1019 | struct nand_chip *nand = mtd_to_nand(mtd); |
1020 | struct docg4_priv *doc = nand->priv; | 1020 | struct docg4_priv *doc = nand_get_controller_data(nand); |
1021 | uint32_t g4_addr = mtd_to_docg4_address(DOCG4_FACTORY_BBT_PAGE, 0); | 1021 | uint32_t g4_addr = mtd_to_docg4_address(DOCG4_FACTORY_BBT_PAGE, 0); |
1022 | uint8_t *buf; | 1022 | uint8_t *buf; |
1023 | int i, block; | 1023 | int i, block; |
@@ -1089,8 +1089,8 @@ static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs) | |||
1089 | 1089 | ||
1090 | int ret, i; | 1090 | int ret, i; |
1091 | uint8_t *buf; | 1091 | uint8_t *buf; |
1092 | struct nand_chip *nand = mtd->priv; | 1092 | struct nand_chip *nand = mtd_to_nand(mtd); |
1093 | struct docg4_priv *doc = nand->priv; | 1093 | struct docg4_priv *doc = nand_get_controller_data(nand); |
1094 | struct nand_bbt_descr *bbtd = nand->badblock_pattern; | 1094 | struct nand_bbt_descr *bbtd = nand->badblock_pattern; |
1095 | int page = (int)(ofs >> nand->page_shift); | 1095 | int page = (int)(ofs >> nand->page_shift); |
1096 | uint32_t g4_addr = mtd_to_docg4_address(page, 0); | 1096 | uint32_t g4_addr = mtd_to_docg4_address(page, 0); |
@@ -1202,8 +1202,8 @@ static void __init init_mtd_structs(struct mtd_info *mtd) | |||
1202 | * things as well, such as call nand_set_defaults(). | 1202 | * things as well, such as call nand_set_defaults(). |
1203 | */ | 1203 | */ |
1204 | 1204 | ||
1205 | struct nand_chip *nand = mtd->priv; | 1205 | struct nand_chip *nand = mtd_to_nand(mtd); |
1206 | struct docg4_priv *doc = nand->priv; | 1206 | struct docg4_priv *doc = nand_get_controller_data(nand); |
1207 | 1207 | ||
1208 | mtd->size = DOCG4_CHIP_SIZE; | 1208 | mtd->size = DOCG4_CHIP_SIZE; |
1209 | mtd->name = "Msys_Diskonchip_G4"; | 1209 | mtd->name = "Msys_Diskonchip_G4"; |
@@ -1261,8 +1261,8 @@ static void __init init_mtd_structs(struct mtd_info *mtd) | |||
1261 | 1261 | ||
1262 | static int __init read_id_reg(struct mtd_info *mtd) | 1262 | static int __init read_id_reg(struct mtd_info *mtd) |
1263 | { | 1263 | { |
1264 | struct nand_chip *nand = mtd->priv; | 1264 | struct nand_chip *nand = mtd_to_nand(mtd); |
1265 | struct docg4_priv *doc = nand->priv; | 1265 | struct docg4_priv *doc = nand_get_controller_data(nand); |
1266 | void __iomem *docptr = doc->virtadr; | 1266 | void __iomem *docptr = doc->virtadr; |
1267 | uint16_t id1, id2; | 1267 | uint16_t id1, id2; |
1268 | 1268 | ||
@@ -1305,17 +1305,16 @@ static int __init probe_docg4(struct platform_device *pdev) | |||
1305 | return -EIO; | 1305 | return -EIO; |
1306 | } | 1306 | } |
1307 | 1307 | ||
1308 | len = sizeof(struct mtd_info) + sizeof(struct nand_chip) + | 1308 | len = sizeof(struct nand_chip) + sizeof(struct docg4_priv); |
1309 | sizeof(struct docg4_priv); | 1309 | nand = kzalloc(len, GFP_KERNEL); |
1310 | mtd = kzalloc(len, GFP_KERNEL); | 1310 | if (nand == NULL) { |
1311 | if (mtd == NULL) { | ||
1312 | retval = -ENOMEM; | 1311 | retval = -ENOMEM; |
1313 | goto fail; | 1312 | goto fail_unmap; |
1314 | } | 1313 | } |
1315 | nand = (struct nand_chip *) (mtd + 1); | 1314 | |
1315 | mtd = nand_to_mtd(nand); | ||
1316 | doc = (struct docg4_priv *) (nand + 1); | 1316 | doc = (struct docg4_priv *) (nand + 1); |
1317 | mtd->priv = nand; | 1317 | nand_set_controller_data(nand, doc); |
1318 | nand->priv = doc; | ||
1319 | mtd->dev.parent = &pdev->dev; | 1318 | mtd->dev.parent = &pdev->dev; |
1320 | doc->virtadr = virtadr; | 1319 | doc->virtadr = virtadr; |
1321 | doc->dev = dev; | 1320 | doc->dev = dev; |
@@ -1353,16 +1352,13 @@ static int __init probe_docg4(struct platform_device *pdev) | |||
1353 | doc->mtd = mtd; | 1352 | doc->mtd = mtd; |
1354 | return 0; | 1353 | return 0; |
1355 | 1354 | ||
1356 | fail: | 1355 | fail: |
1356 | nand_release(mtd); /* deletes partitions and mtd devices */ | ||
1357 | free_bch(doc->bch); | ||
1358 | kfree(nand); | ||
1359 | |||
1360 | fail_unmap: | ||
1357 | iounmap(virtadr); | 1361 | iounmap(virtadr); |
1358 | if (mtd) { | ||
1359 | /* re-declarations avoid compiler warning */ | ||
1360 | struct nand_chip *nand = mtd->priv; | ||
1361 | struct docg4_priv *doc = nand->priv; | ||
1362 | nand_release(mtd); /* deletes partitions and mtd devices */ | ||
1363 | free_bch(doc->bch); | ||
1364 | kfree(mtd); | ||
1365 | } | ||
1366 | 1362 | ||
1367 | return retval; | 1363 | return retval; |
1368 | } | 1364 | } |
@@ -1372,7 +1368,7 @@ static int __exit cleanup_docg4(struct platform_device *pdev) | |||
1372 | struct docg4_priv *doc = platform_get_drvdata(pdev); | 1368 | struct docg4_priv *doc = platform_get_drvdata(pdev); |
1373 | nand_release(doc->mtd); | 1369 | nand_release(doc->mtd); |
1374 | free_bch(doc->bch); | 1370 | free_bch(doc->bch); |
1375 | kfree(doc->mtd); | 1371 | kfree(mtd_to_nand(doc->mtd)); |
1376 | iounmap(doc->virtadr); | 1372 | iounmap(doc->virtadr); |
1377 | return 0; | 1373 | return 0; |
1378 | } | 1374 | } |
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index dcb1f7f4873f..059d5f7ec124 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c | |||
@@ -48,7 +48,6 @@ | |||
48 | /* mtd information per set */ | 48 | /* mtd information per set */ |
49 | 49 | ||
50 | struct fsl_elbc_mtd { | 50 | struct fsl_elbc_mtd { |
51 | struct mtd_info mtd; | ||
52 | struct nand_chip chip; | 51 | struct nand_chip chip; |
53 | struct fsl_lbc_ctrl *ctrl; | 52 | struct fsl_lbc_ctrl *ctrl; |
54 | 53 | ||
@@ -144,8 +143,8 @@ static struct nand_bbt_descr bbt_mirror_descr = { | |||
144 | */ | 143 | */ |
145 | static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) | 144 | static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) |
146 | { | 145 | { |
147 | struct nand_chip *chip = mtd->priv; | 146 | struct nand_chip *chip = mtd_to_nand(mtd); |
148 | struct fsl_elbc_mtd *priv = chip->priv; | 147 | struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); |
149 | struct fsl_lbc_ctrl *ctrl = priv->ctrl; | 148 | struct fsl_lbc_ctrl *ctrl = priv->ctrl; |
150 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; | 149 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; |
151 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; | 150 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; |
@@ -195,8 +194,8 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) | |||
195 | */ | 194 | */ |
196 | static int fsl_elbc_run_command(struct mtd_info *mtd) | 195 | static int fsl_elbc_run_command(struct mtd_info *mtd) |
197 | { | 196 | { |
198 | struct nand_chip *chip = mtd->priv; | 197 | struct nand_chip *chip = mtd_to_nand(mtd); |
199 | struct fsl_elbc_mtd *priv = chip->priv; | 198 | struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); |
200 | struct fsl_lbc_ctrl *ctrl = priv->ctrl; | 199 | struct fsl_lbc_ctrl *ctrl = priv->ctrl; |
201 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; | 200 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; |
202 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; | 201 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; |
@@ -268,7 +267,7 @@ static int fsl_elbc_run_command(struct mtd_info *mtd) | |||
268 | 267 | ||
269 | static void fsl_elbc_do_read(struct nand_chip *chip, int oob) | 268 | static void fsl_elbc_do_read(struct nand_chip *chip, int oob) |
270 | { | 269 | { |
271 | struct fsl_elbc_mtd *priv = chip->priv; | 270 | struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); |
272 | struct fsl_lbc_ctrl *ctrl = priv->ctrl; | 271 | struct fsl_lbc_ctrl *ctrl = priv->ctrl; |
273 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; | 272 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; |
274 | 273 | ||
@@ -300,8 +299,8 @@ static void fsl_elbc_do_read(struct nand_chip *chip, int oob) | |||
300 | static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command, | 299 | static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command, |
301 | int column, int page_addr) | 300 | int column, int page_addr) |
302 | { | 301 | { |
303 | struct nand_chip *chip = mtd->priv; | 302 | struct nand_chip *chip = mtd_to_nand(mtd); |
304 | struct fsl_elbc_mtd *priv = chip->priv; | 303 | struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); |
305 | struct fsl_lbc_ctrl *ctrl = priv->ctrl; | 304 | struct fsl_lbc_ctrl *ctrl = priv->ctrl; |
306 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; | 305 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; |
307 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; | 306 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; |
@@ -525,8 +524,8 @@ static void fsl_elbc_select_chip(struct mtd_info *mtd, int chip) | |||
525 | */ | 524 | */ |
526 | static void fsl_elbc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) | 525 | static void fsl_elbc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) |
527 | { | 526 | { |
528 | struct nand_chip *chip = mtd->priv; | 527 | struct nand_chip *chip = mtd_to_nand(mtd); |
529 | struct fsl_elbc_mtd *priv = chip->priv; | 528 | struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); |
530 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; | 529 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; |
531 | unsigned int bufsize = mtd->writesize + mtd->oobsize; | 530 | unsigned int bufsize = mtd->writesize + mtd->oobsize; |
532 | 531 | ||
@@ -563,8 +562,8 @@ static void fsl_elbc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) | |||
563 | */ | 562 | */ |
564 | static u8 fsl_elbc_read_byte(struct mtd_info *mtd) | 563 | static u8 fsl_elbc_read_byte(struct mtd_info *mtd) |
565 | { | 564 | { |
566 | struct nand_chip *chip = mtd->priv; | 565 | struct nand_chip *chip = mtd_to_nand(mtd); |
567 | struct fsl_elbc_mtd *priv = chip->priv; | 566 | struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); |
568 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; | 567 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; |
569 | 568 | ||
570 | /* If there are still bytes in the FCM, then use the next byte. */ | 569 | /* If there are still bytes in the FCM, then use the next byte. */ |
@@ -580,8 +579,8 @@ static u8 fsl_elbc_read_byte(struct mtd_info *mtd) | |||
580 | */ | 579 | */ |
581 | static void fsl_elbc_read_buf(struct mtd_info *mtd, u8 *buf, int len) | 580 | static void fsl_elbc_read_buf(struct mtd_info *mtd, u8 *buf, int len) |
582 | { | 581 | { |
583 | struct nand_chip *chip = mtd->priv; | 582 | struct nand_chip *chip = mtd_to_nand(mtd); |
584 | struct fsl_elbc_mtd *priv = chip->priv; | 583 | struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); |
585 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; | 584 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; |
586 | int avail; | 585 | int avail; |
587 | 586 | ||
@@ -605,7 +604,7 @@ static void fsl_elbc_read_buf(struct mtd_info *mtd, u8 *buf, int len) | |||
605 | */ | 604 | */ |
606 | static int fsl_elbc_wait(struct mtd_info *mtd, struct nand_chip *chip) | 605 | static int fsl_elbc_wait(struct mtd_info *mtd, struct nand_chip *chip) |
607 | { | 606 | { |
608 | struct fsl_elbc_mtd *priv = chip->priv; | 607 | struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); |
609 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; | 608 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; |
610 | 609 | ||
611 | if (elbc_fcm_ctrl->status != LTESR_CC) | 610 | if (elbc_fcm_ctrl->status != LTESR_CC) |
@@ -619,8 +618,8 @@ static int fsl_elbc_wait(struct mtd_info *mtd, struct nand_chip *chip) | |||
619 | 618 | ||
620 | static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) | 619 | static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) |
621 | { | 620 | { |
622 | struct nand_chip *chip = mtd->priv; | 621 | struct nand_chip *chip = mtd_to_nand(mtd); |
623 | struct fsl_elbc_mtd *priv = chip->priv; | 622 | struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); |
624 | struct fsl_lbc_ctrl *ctrl = priv->ctrl; | 623 | struct fsl_lbc_ctrl *ctrl = priv->ctrl; |
625 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; | 624 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; |
626 | unsigned int al; | 625 | unsigned int al; |
@@ -697,7 +696,7 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) | |||
697 | static int fsl_elbc_read_page(struct mtd_info *mtd, struct nand_chip *chip, | 696 | static int fsl_elbc_read_page(struct mtd_info *mtd, struct nand_chip *chip, |
698 | uint8_t *buf, int oob_required, int page) | 697 | uint8_t *buf, int oob_required, int page) |
699 | { | 698 | { |
700 | struct fsl_elbc_mtd *priv = chip->priv; | 699 | struct fsl_elbc_mtd *priv = nand_get_controller_data(chip); |
701 | struct fsl_lbc_ctrl *ctrl = priv->ctrl; | 700 | struct fsl_lbc_ctrl *ctrl = priv->ctrl; |
702 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; | 701 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; |
703 | 702 | ||
@@ -742,12 +741,13 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv) | |||
742 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; | 741 | struct fsl_lbc_regs __iomem *lbc = ctrl->regs; |
743 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; | 742 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = ctrl->nand; |
744 | struct nand_chip *chip = &priv->chip; | 743 | struct nand_chip *chip = &priv->chip; |
744 | struct mtd_info *mtd = nand_to_mtd(chip); | ||
745 | 745 | ||
746 | dev_dbg(priv->dev, "eLBC Set Information for bank %d\n", priv->bank); | 746 | dev_dbg(priv->dev, "eLBC Set Information for bank %d\n", priv->bank); |
747 | 747 | ||
748 | /* Fill in fsl_elbc_mtd structure */ | 748 | /* Fill in fsl_elbc_mtd structure */ |
749 | priv->mtd.priv = chip; | 749 | mtd->dev.parent = priv->dev; |
750 | priv->mtd.dev.parent = priv->dev; | 750 | nand_set_flash_node(chip, priv->dev->of_node); |
751 | 751 | ||
752 | /* set timeout to maximum */ | 752 | /* set timeout to maximum */ |
753 | priv->fmr = 15 << FMR_CWTO_SHIFT; | 753 | priv->fmr = 15 << FMR_CWTO_SHIFT; |
@@ -770,7 +770,7 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv) | |||
770 | chip->bbt_options = NAND_BBT_USE_FLASH; | 770 | chip->bbt_options = NAND_BBT_USE_FLASH; |
771 | 771 | ||
772 | chip->controller = &elbc_fcm_ctrl->controller; | 772 | chip->controller = &elbc_fcm_ctrl->controller; |
773 | chip->priv = priv; | 773 | nand_set_controller_data(chip, priv); |
774 | 774 | ||
775 | chip->ecc.read_page = fsl_elbc_read_page; | 775 | chip->ecc.read_page = fsl_elbc_read_page; |
776 | chip->ecc.write_page = fsl_elbc_write_page; | 776 | chip->ecc.write_page = fsl_elbc_write_page; |
@@ -797,9 +797,11 @@ static int fsl_elbc_chip_init(struct fsl_elbc_mtd *priv) | |||
797 | static int fsl_elbc_chip_remove(struct fsl_elbc_mtd *priv) | 797 | static int fsl_elbc_chip_remove(struct fsl_elbc_mtd *priv) |
798 | { | 798 | { |
799 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; | 799 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; |
800 | nand_release(&priv->mtd); | 800 | struct mtd_info *mtd = nand_to_mtd(&priv->chip); |
801 | 801 | ||
802 | kfree(priv->mtd.name); | 802 | nand_release(mtd); |
803 | |||
804 | kfree(mtd->name); | ||
803 | 805 | ||
804 | if (priv->vbase) | 806 | if (priv->vbase) |
805 | iounmap(priv->vbase); | 807 | iounmap(priv->vbase); |
@@ -823,9 +825,8 @@ static int fsl_elbc_nand_probe(struct platform_device *pdev) | |||
823 | int bank; | 825 | int bank; |
824 | struct device *dev; | 826 | struct device *dev; |
825 | struct device_node *node = pdev->dev.of_node; | 827 | struct device_node *node = pdev->dev.of_node; |
826 | struct mtd_part_parser_data ppdata; | 828 | struct mtd_info *mtd; |
827 | 829 | ||
828 | ppdata.of_node = pdev->dev.of_node; | ||
829 | if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs) | 830 | if (!fsl_lbc_ctrl_dev || !fsl_lbc_ctrl_dev->regs) |
830 | return -ENODEV; | 831 | return -ENODEV; |
831 | lbc = fsl_lbc_ctrl_dev->regs; | 832 | lbc = fsl_lbc_ctrl_dev->regs; |
@@ -887,8 +888,9 @@ static int fsl_elbc_nand_probe(struct platform_device *pdev) | |||
887 | goto err; | 888 | goto err; |
888 | } | 889 | } |
889 | 890 | ||
890 | priv->mtd.name = kasprintf(GFP_KERNEL, "%llx.flash", (u64)res.start); | 891 | mtd = nand_to_mtd(&priv->chip); |
891 | if (!priv->mtd.name) { | 892 | mtd->name = kasprintf(GFP_KERNEL, "%llx.flash", (u64)res.start); |
893 | if (!nand_to_mtd(&priv->chip)->name) { | ||
892 | ret = -ENOMEM; | 894 | ret = -ENOMEM; |
893 | goto err; | 895 | goto err; |
894 | } | 896 | } |
@@ -897,21 +899,21 @@ static int fsl_elbc_nand_probe(struct platform_device *pdev) | |||
897 | if (ret) | 899 | if (ret) |
898 | goto err; | 900 | goto err; |
899 | 901 | ||
900 | ret = nand_scan_ident(&priv->mtd, 1, NULL); | 902 | ret = nand_scan_ident(mtd, 1, NULL); |
901 | if (ret) | 903 | if (ret) |
902 | goto err; | 904 | goto err; |
903 | 905 | ||
904 | ret = fsl_elbc_chip_init_tail(&priv->mtd); | 906 | ret = fsl_elbc_chip_init_tail(mtd); |
905 | if (ret) | 907 | if (ret) |
906 | goto err; | 908 | goto err; |
907 | 909 | ||
908 | ret = nand_scan_tail(&priv->mtd); | 910 | ret = nand_scan_tail(mtd); |
909 | if (ret) | 911 | if (ret) |
910 | goto err; | 912 | goto err; |
911 | 913 | ||
912 | /* First look for RedBoot table or partitions on the command | 914 | /* First look for RedBoot table or partitions on the command |
913 | * line, these take precedence over device tree information */ | 915 | * line, these take precedence over device tree information */ |
914 | mtd_device_parse_register(&priv->mtd, part_probe_types, &ppdata, | 916 | mtd_device_parse_register(mtd, part_probe_types, NULL, |
915 | NULL, 0); | 917 | NULL, 0); |
916 | 918 | ||
917 | printk(KERN_INFO "eLBC NAND device at 0x%llx, bank %d\n", | 919 | printk(KERN_INFO "eLBC NAND device at 0x%llx, bank %d\n", |
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index 7f4ac8c19001..43f5a3a4873f 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c | |||
@@ -40,7 +40,6 @@ struct fsl_ifc_ctrl; | |||
40 | 40 | ||
41 | /* mtd information per set */ | 41 | /* mtd information per set */ |
42 | struct fsl_ifc_mtd { | 42 | struct fsl_ifc_mtd { |
43 | struct mtd_info mtd; | ||
44 | struct nand_chip chip; | 43 | struct nand_chip chip; |
45 | struct fsl_ifc_ctrl *ctrl; | 44 | struct fsl_ifc_ctrl *ctrl; |
46 | 45 | ||
@@ -230,8 +229,8 @@ static struct nand_bbt_descr bbt_mirror_descr = { | |||
230 | */ | 229 | */ |
231 | static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) | 230 | static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) |
232 | { | 231 | { |
233 | struct nand_chip *chip = mtd->priv; | 232 | struct nand_chip *chip = mtd_to_nand(mtd); |
234 | struct fsl_ifc_mtd *priv = chip->priv; | 233 | struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); |
235 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; | 234 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; |
236 | struct fsl_ifc_regs __iomem *ifc = ctrl->regs; | 235 | struct fsl_ifc_regs __iomem *ifc = ctrl->regs; |
237 | int buf_num; | 236 | int buf_num; |
@@ -253,8 +252,8 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr, int oob) | |||
253 | 252 | ||
254 | static int is_blank(struct mtd_info *mtd, unsigned int bufnum) | 253 | static int is_blank(struct mtd_info *mtd, unsigned int bufnum) |
255 | { | 254 | { |
256 | struct nand_chip *chip = mtd->priv; | 255 | struct nand_chip *chip = mtd_to_nand(mtd); |
257 | struct fsl_ifc_mtd *priv = chip->priv; | 256 | struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); |
258 | u8 __iomem *addr = priv->vbase + bufnum * (mtd->writesize * 2); | 257 | u8 __iomem *addr = priv->vbase + bufnum * (mtd->writesize * 2); |
259 | u32 __iomem *mainarea = (u32 __iomem *)addr; | 258 | u32 __iomem *mainarea = (u32 __iomem *)addr; |
260 | u8 __iomem *oob = addr + mtd->writesize; | 259 | u8 __iomem *oob = addr + mtd->writesize; |
@@ -292,8 +291,8 @@ static int check_read_ecc(struct mtd_info *mtd, struct fsl_ifc_ctrl *ctrl, | |||
292 | */ | 291 | */ |
293 | static void fsl_ifc_run_command(struct mtd_info *mtd) | 292 | static void fsl_ifc_run_command(struct mtd_info *mtd) |
294 | { | 293 | { |
295 | struct nand_chip *chip = mtd->priv; | 294 | struct nand_chip *chip = mtd_to_nand(mtd); |
296 | struct fsl_ifc_mtd *priv = chip->priv; | 295 | struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); |
297 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; | 296 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; |
298 | struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl; | 297 | struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl; |
299 | struct fsl_ifc_regs __iomem *ifc = ctrl->regs; | 298 | struct fsl_ifc_regs __iomem *ifc = ctrl->regs; |
@@ -370,7 +369,7 @@ static void fsl_ifc_do_read(struct nand_chip *chip, | |||
370 | int oob, | 369 | int oob, |
371 | struct mtd_info *mtd) | 370 | struct mtd_info *mtd) |
372 | { | 371 | { |
373 | struct fsl_ifc_mtd *priv = chip->priv; | 372 | struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); |
374 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; | 373 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; |
375 | struct fsl_ifc_regs __iomem *ifc = ctrl->regs; | 374 | struct fsl_ifc_regs __iomem *ifc = ctrl->regs; |
376 | 375 | ||
@@ -409,8 +408,8 @@ static void fsl_ifc_do_read(struct nand_chip *chip, | |||
409 | /* cmdfunc send commands to the IFC NAND Machine */ | 408 | /* cmdfunc send commands to the IFC NAND Machine */ |
410 | static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command, | 409 | static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command, |
411 | int column, int page_addr) { | 410 | int column, int page_addr) { |
412 | struct nand_chip *chip = mtd->priv; | 411 | struct nand_chip *chip = mtd_to_nand(mtd); |
413 | struct fsl_ifc_mtd *priv = chip->priv; | 412 | struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); |
414 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; | 413 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; |
415 | struct fsl_ifc_regs __iomem *ifc = ctrl->regs; | 414 | struct fsl_ifc_regs __iomem *ifc = ctrl->regs; |
416 | 415 | ||
@@ -624,8 +623,8 @@ static void fsl_ifc_select_chip(struct mtd_info *mtd, int chip) | |||
624 | */ | 623 | */ |
625 | static void fsl_ifc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) | 624 | static void fsl_ifc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) |
626 | { | 625 | { |
627 | struct nand_chip *chip = mtd->priv; | 626 | struct nand_chip *chip = mtd_to_nand(mtd); |
628 | struct fsl_ifc_mtd *priv = chip->priv; | 627 | struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); |
629 | unsigned int bufsize = mtd->writesize + mtd->oobsize; | 628 | unsigned int bufsize = mtd->writesize + mtd->oobsize; |
630 | 629 | ||
631 | if (len <= 0) { | 630 | if (len <= 0) { |
@@ -650,8 +649,8 @@ static void fsl_ifc_write_buf(struct mtd_info *mtd, const u8 *buf, int len) | |||
650 | */ | 649 | */ |
651 | static uint8_t fsl_ifc_read_byte(struct mtd_info *mtd) | 650 | static uint8_t fsl_ifc_read_byte(struct mtd_info *mtd) |
652 | { | 651 | { |
653 | struct nand_chip *chip = mtd->priv; | 652 | struct nand_chip *chip = mtd_to_nand(mtd); |
654 | struct fsl_ifc_mtd *priv = chip->priv; | 653 | struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); |
655 | unsigned int offset; | 654 | unsigned int offset; |
656 | 655 | ||
657 | /* | 656 | /* |
@@ -673,8 +672,8 @@ static uint8_t fsl_ifc_read_byte(struct mtd_info *mtd) | |||
673 | */ | 672 | */ |
674 | static uint8_t fsl_ifc_read_byte16(struct mtd_info *mtd) | 673 | static uint8_t fsl_ifc_read_byte16(struct mtd_info *mtd) |
675 | { | 674 | { |
676 | struct nand_chip *chip = mtd->priv; | 675 | struct nand_chip *chip = mtd_to_nand(mtd); |
677 | struct fsl_ifc_mtd *priv = chip->priv; | 676 | struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); |
678 | uint16_t data; | 677 | uint16_t data; |
679 | 678 | ||
680 | /* | 679 | /* |
@@ -696,8 +695,8 @@ static uint8_t fsl_ifc_read_byte16(struct mtd_info *mtd) | |||
696 | */ | 695 | */ |
697 | static void fsl_ifc_read_buf(struct mtd_info *mtd, u8 *buf, int len) | 696 | static void fsl_ifc_read_buf(struct mtd_info *mtd, u8 *buf, int len) |
698 | { | 697 | { |
699 | struct nand_chip *chip = mtd->priv; | 698 | struct nand_chip *chip = mtd_to_nand(mtd); |
700 | struct fsl_ifc_mtd *priv = chip->priv; | 699 | struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); |
701 | int avail; | 700 | int avail; |
702 | 701 | ||
703 | if (len < 0) { | 702 | if (len < 0) { |
@@ -722,7 +721,7 @@ static void fsl_ifc_read_buf(struct mtd_info *mtd, u8 *buf, int len) | |||
722 | */ | 721 | */ |
723 | static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip) | 722 | static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip) |
724 | { | 723 | { |
725 | struct fsl_ifc_mtd *priv = chip->priv; | 724 | struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); |
726 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; | 725 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; |
727 | struct fsl_ifc_regs __iomem *ifc = ctrl->regs; | 726 | struct fsl_ifc_regs __iomem *ifc = ctrl->regs; |
728 | u32 nand_fsr; | 727 | u32 nand_fsr; |
@@ -751,7 +750,7 @@ static int fsl_ifc_wait(struct mtd_info *mtd, struct nand_chip *chip) | |||
751 | static int fsl_ifc_read_page(struct mtd_info *mtd, struct nand_chip *chip, | 750 | static int fsl_ifc_read_page(struct mtd_info *mtd, struct nand_chip *chip, |
752 | uint8_t *buf, int oob_required, int page) | 751 | uint8_t *buf, int oob_required, int page) |
753 | { | 752 | { |
754 | struct fsl_ifc_mtd *priv = chip->priv; | 753 | struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); |
755 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; | 754 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; |
756 | struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl; | 755 | struct fsl_ifc_nand_ctrl *nctrl = ifc_nand_ctrl; |
757 | 756 | ||
@@ -782,8 +781,8 @@ static int fsl_ifc_write_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
782 | 781 | ||
783 | static int fsl_ifc_chip_init_tail(struct mtd_info *mtd) | 782 | static int fsl_ifc_chip_init_tail(struct mtd_info *mtd) |
784 | { | 783 | { |
785 | struct nand_chip *chip = mtd->priv; | 784 | struct nand_chip *chip = mtd_to_nand(mtd); |
786 | struct fsl_ifc_mtd *priv = chip->priv; | 785 | struct fsl_ifc_mtd *priv = nand_get_controller_data(chip); |
787 | 786 | ||
788 | dev_dbg(priv->dev, "%s: nand->numchips = %d\n", __func__, | 787 | dev_dbg(priv->dev, "%s: nand->numchips = %d\n", __func__, |
789 | chip->numchips); | 788 | chip->numchips); |
@@ -877,12 +876,13 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv) | |||
877 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; | 876 | struct fsl_ifc_ctrl *ctrl = priv->ctrl; |
878 | struct fsl_ifc_regs __iomem *ifc = ctrl->regs; | 877 | struct fsl_ifc_regs __iomem *ifc = ctrl->regs; |
879 | struct nand_chip *chip = &priv->chip; | 878 | struct nand_chip *chip = &priv->chip; |
879 | struct mtd_info *mtd = nand_to_mtd(&priv->chip); | ||
880 | struct nand_ecclayout *layout; | 880 | struct nand_ecclayout *layout; |
881 | u32 csor; | 881 | u32 csor; |
882 | 882 | ||
883 | /* Fill in fsl_ifc_mtd structure */ | 883 | /* Fill in fsl_ifc_mtd structure */ |
884 | priv->mtd.priv = chip; | 884 | mtd->dev.parent = priv->dev; |
885 | priv->mtd.dev.parent = priv->dev; | 885 | nand_set_flash_node(chip, priv->dev->of_node); |
886 | 886 | ||
887 | /* fill in nand_chip structure */ | 887 | /* fill in nand_chip structure */ |
888 | /* set up function call table */ | 888 | /* set up function call table */ |
@@ -914,7 +914,7 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv) | |||
914 | } | 914 | } |
915 | 915 | ||
916 | chip->controller = &ifc_nand_ctrl->controller; | 916 | chip->controller = &ifc_nand_ctrl->controller; |
917 | chip->priv = priv; | 917 | nand_set_controller_data(chip, priv); |
918 | 918 | ||
919 | chip->ecc.read_page = fsl_ifc_read_page; | 919 | chip->ecc.read_page = fsl_ifc_read_page; |
920 | chip->ecc.write_page = fsl_ifc_write_page; | 920 | chip->ecc.write_page = fsl_ifc_write_page; |
@@ -993,9 +993,11 @@ static int fsl_ifc_chip_init(struct fsl_ifc_mtd *priv) | |||
993 | 993 | ||
994 | static int fsl_ifc_chip_remove(struct fsl_ifc_mtd *priv) | 994 | static int fsl_ifc_chip_remove(struct fsl_ifc_mtd *priv) |
995 | { | 995 | { |
996 | nand_release(&priv->mtd); | 996 | struct mtd_info *mtd = nand_to_mtd(&priv->chip); |
997 | 997 | ||
998 | kfree(priv->mtd.name); | 998 | nand_release(mtd); |
999 | |||
1000 | kfree(mtd->name); | ||
999 | 1001 | ||
1000 | if (priv->vbase) | 1002 | if (priv->vbase) |
1001 | iounmap(priv->vbase); | 1003 | iounmap(priv->vbase); |
@@ -1030,9 +1032,8 @@ static int fsl_ifc_nand_probe(struct platform_device *dev) | |||
1030 | int ret; | 1032 | int ret; |
1031 | int bank; | 1033 | int bank; |
1032 | struct device_node *node = dev->dev.of_node; | 1034 | struct device_node *node = dev->dev.of_node; |
1033 | struct mtd_part_parser_data ppdata; | 1035 | struct mtd_info *mtd; |
1034 | 1036 | ||
1035 | ppdata.of_node = dev->dev.of_node; | ||
1036 | if (!fsl_ifc_ctrl_dev || !fsl_ifc_ctrl_dev->regs) | 1037 | if (!fsl_ifc_ctrl_dev || !fsl_ifc_ctrl_dev->regs) |
1037 | return -ENODEV; | 1038 | return -ENODEV; |
1038 | ifc = fsl_ifc_ctrl_dev->regs; | 1039 | ifc = fsl_ifc_ctrl_dev->regs; |
@@ -1104,8 +1105,10 @@ static int fsl_ifc_nand_probe(struct platform_device *dev) | |||
1104 | IFC_NAND_EVTER_INTR_FTOERIR_EN | | 1105 | IFC_NAND_EVTER_INTR_FTOERIR_EN | |
1105 | IFC_NAND_EVTER_INTR_WPERIR_EN, | 1106 | IFC_NAND_EVTER_INTR_WPERIR_EN, |
1106 | &ifc->ifc_nand.nand_evter_intr_en); | 1107 | &ifc->ifc_nand.nand_evter_intr_en); |
1107 | priv->mtd.name = kasprintf(GFP_KERNEL, "%llx.flash", (u64)res.start); | 1108 | |
1108 | if (!priv->mtd.name) { | 1109 | mtd = nand_to_mtd(&priv->chip); |
1110 | mtd->name = kasprintf(GFP_KERNEL, "%llx.flash", (u64)res.start); | ||
1111 | if (!mtd->name) { | ||
1109 | ret = -ENOMEM; | 1112 | ret = -ENOMEM; |
1110 | goto err; | 1113 | goto err; |
1111 | } | 1114 | } |
@@ -1114,22 +1117,21 @@ static int fsl_ifc_nand_probe(struct platform_device *dev) | |||
1114 | if (ret) | 1117 | if (ret) |
1115 | goto err; | 1118 | goto err; |
1116 | 1119 | ||
1117 | ret = nand_scan_ident(&priv->mtd, 1, NULL); | 1120 | ret = nand_scan_ident(mtd, 1, NULL); |
1118 | if (ret) | 1121 | if (ret) |
1119 | goto err; | 1122 | goto err; |
1120 | 1123 | ||
1121 | ret = fsl_ifc_chip_init_tail(&priv->mtd); | 1124 | ret = fsl_ifc_chip_init_tail(mtd); |
1122 | if (ret) | 1125 | if (ret) |
1123 | goto err; | 1126 | goto err; |
1124 | 1127 | ||
1125 | ret = nand_scan_tail(&priv->mtd); | 1128 | ret = nand_scan_tail(mtd); |
1126 | if (ret) | 1129 | if (ret) |
1127 | goto err; | 1130 | goto err; |
1128 | 1131 | ||
1129 | /* First look for RedBoot table or partitions on the command | 1132 | /* First look for RedBoot table or partitions on the command |
1130 | * line, these take precedence over device tree information */ | 1133 | * line, these take precedence over device tree information */ |
1131 | mtd_device_parse_register(&priv->mtd, part_probe_types, &ppdata, | 1134 | mtd_device_parse_register(mtd, part_probe_types, NULL, NULL, 0); |
1132 | NULL, 0); | ||
1133 | 1135 | ||
1134 | dev_info(priv->dev, "IFC NAND device at 0x%llx, bank %d\n", | 1136 | dev_info(priv->dev, "IFC NAND device at 0x%llx, bank %d\n", |
1135 | (unsigned long long)res.start, priv->bank); | 1137 | (unsigned long long)res.start, priv->bank); |
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index d326369980c4..cafd12de7276 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c | |||
@@ -31,7 +31,6 @@ | |||
31 | 31 | ||
32 | struct fsl_upm_nand { | 32 | struct fsl_upm_nand { |
33 | struct device *dev; | 33 | struct device *dev; |
34 | struct mtd_info mtd; | ||
35 | struct nand_chip chip; | 34 | struct nand_chip chip; |
36 | int last_ctrl; | 35 | int last_ctrl; |
37 | struct mtd_partition *parts; | 36 | struct mtd_partition *parts; |
@@ -49,7 +48,8 @@ struct fsl_upm_nand { | |||
49 | 48 | ||
50 | static inline struct fsl_upm_nand *to_fsl_upm_nand(struct mtd_info *mtdinfo) | 49 | static inline struct fsl_upm_nand *to_fsl_upm_nand(struct mtd_info *mtdinfo) |
51 | { | 50 | { |
52 | return container_of(mtdinfo, struct fsl_upm_nand, mtd); | 51 | return container_of(mtd_to_nand(mtdinfo), struct fsl_upm_nand, |
52 | chip); | ||
53 | } | 53 | } |
54 | 54 | ||
55 | static int fun_chip_ready(struct mtd_info *mtd) | 55 | static int fun_chip_ready(struct mtd_info *mtd) |
@@ -66,9 +66,10 @@ static int fun_chip_ready(struct mtd_info *mtd) | |||
66 | static void fun_wait_rnb(struct fsl_upm_nand *fun) | 66 | static void fun_wait_rnb(struct fsl_upm_nand *fun) |
67 | { | 67 | { |
68 | if (fun->rnb_gpio[fun->mchip_number] >= 0) { | 68 | if (fun->rnb_gpio[fun->mchip_number] >= 0) { |
69 | struct mtd_info *mtd = nand_to_mtd(&fun->chip); | ||
69 | int cnt = 1000000; | 70 | int cnt = 1000000; |
70 | 71 | ||
71 | while (--cnt && !fun_chip_ready(&fun->mtd)) | 72 | while (--cnt && !fun_chip_ready(mtd)) |
72 | cpu_relax(); | 73 | cpu_relax(); |
73 | if (!cnt) | 74 | if (!cnt) |
74 | dev_err(fun->dev, "tired waiting for RNB\n"); | 75 | dev_err(fun->dev, "tired waiting for RNB\n"); |
@@ -79,7 +80,7 @@ static void fun_wait_rnb(struct fsl_upm_nand *fun) | |||
79 | 80 | ||
80 | static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 81 | static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
81 | { | 82 | { |
82 | struct nand_chip *chip = mtd->priv; | 83 | struct nand_chip *chip = mtd_to_nand(mtd); |
83 | struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd); | 84 | struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd); |
84 | u32 mar; | 85 | u32 mar; |
85 | 86 | ||
@@ -109,7 +110,7 @@ static void fun_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | |||
109 | 110 | ||
110 | static void fun_select_chip(struct mtd_info *mtd, int mchip_nr) | 111 | static void fun_select_chip(struct mtd_info *mtd, int mchip_nr) |
111 | { | 112 | { |
112 | struct nand_chip *chip = mtd->priv; | 113 | struct nand_chip *chip = mtd_to_nand(mtd); |
113 | struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd); | 114 | struct fsl_upm_nand *fun = to_fsl_upm_nand(mtd); |
114 | 115 | ||
115 | if (mchip_nr == -1) { | 116 | if (mchip_nr == -1) { |
@@ -157,9 +158,9 @@ static int fun_chip_init(struct fsl_upm_nand *fun, | |||
157 | const struct device_node *upm_np, | 158 | const struct device_node *upm_np, |
158 | const struct resource *io_res) | 159 | const struct resource *io_res) |
159 | { | 160 | { |
161 | struct mtd_info *mtd = nand_to_mtd(&fun->chip); | ||
160 | int ret; | 162 | int ret; |
161 | struct device_node *flash_np; | 163 | struct device_node *flash_np; |
162 | struct mtd_part_parser_data ppdata; | ||
163 | 164 | ||
164 | fun->chip.IO_ADDR_R = fun->io_base; | 165 | fun->chip.IO_ADDR_R = fun->io_base; |
165 | fun->chip.IO_ADDR_W = fun->io_base; | 166 | fun->chip.IO_ADDR_W = fun->io_base; |
@@ -175,30 +176,29 @@ static int fun_chip_init(struct fsl_upm_nand *fun, | |||
175 | if (fun->rnb_gpio[0] >= 0) | 176 | if (fun->rnb_gpio[0] >= 0) |
176 | fun->chip.dev_ready = fun_chip_ready; | 177 | fun->chip.dev_ready = fun_chip_ready; |
177 | 178 | ||
178 | fun->mtd.priv = &fun->chip; | 179 | mtd->dev.parent = fun->dev; |
179 | fun->mtd.dev.parent = fun->dev; | ||
180 | 180 | ||
181 | flash_np = of_get_next_child(upm_np, NULL); | 181 | flash_np = of_get_next_child(upm_np, NULL); |
182 | if (!flash_np) | 182 | if (!flash_np) |
183 | return -ENODEV; | 183 | return -ENODEV; |
184 | 184 | ||
185 | fun->mtd.name = kasprintf(GFP_KERNEL, "0x%llx.%s", (u64)io_res->start, | 185 | nand_set_flash_node(&fun->chip, flash_np); |
186 | flash_np->name); | 186 | mtd->name = kasprintf(GFP_KERNEL, "0x%llx.%s", (u64)io_res->start, |
187 | if (!fun->mtd.name) { | 187 | flash_np->name); |
188 | if (!mtd->name) { | ||
188 | ret = -ENOMEM; | 189 | ret = -ENOMEM; |
189 | goto err; | 190 | goto err; |
190 | } | 191 | } |
191 | 192 | ||
192 | ret = nand_scan(&fun->mtd, fun->mchip_count); | 193 | ret = nand_scan(mtd, fun->mchip_count); |
193 | if (ret) | 194 | if (ret) |
194 | goto err; | 195 | goto err; |
195 | 196 | ||
196 | ppdata.of_node = flash_np; | 197 | ret = mtd_device_register(mtd, NULL, 0); |
197 | ret = mtd_device_parse_register(&fun->mtd, NULL, &ppdata, NULL, 0); | ||
198 | err: | 198 | err: |
199 | of_node_put(flash_np); | 199 | of_node_put(flash_np); |
200 | if (ret) | 200 | if (ret) |
201 | kfree(fun->mtd.name); | 201 | kfree(mtd->name); |
202 | return ret; | 202 | return ret; |
203 | } | 203 | } |
204 | 204 | ||
@@ -322,10 +322,11 @@ err1: | |||
322 | static int fun_remove(struct platform_device *ofdev) | 322 | static int fun_remove(struct platform_device *ofdev) |
323 | { | 323 | { |
324 | struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev); | 324 | struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev); |
325 | struct mtd_info *mtd = nand_to_mtd(&fun->chip); | ||
325 | int i; | 326 | int i; |
326 | 327 | ||
327 | nand_release(&fun->mtd); | 328 | nand_release(mtd); |
328 | kfree(fun->mtd.name); | 329 | kfree(mtd->name); |
329 | 330 | ||
330 | for (i = 0; i < fun->mchip_count; i++) { | 331 | for (i = 0; i < fun->mchip_count; i++) { |
331 | if (fun->rnb_gpio[i] < 0) | 332 | if (fun->rnb_gpio[i] < 0) |
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 07af3dc7a4d2..1bdcd4fa26d4 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c | |||
@@ -299,7 +299,6 @@ static struct fsmc_eccplace fsmc_ecc4_sp_place = { | |||
299 | */ | 299 | */ |
300 | struct fsmc_nand_data { | 300 | struct fsmc_nand_data { |
301 | u32 pid; | 301 | u32 pid; |
302 | struct mtd_info mtd; | ||
303 | struct nand_chip nand; | 302 | struct nand_chip nand; |
304 | struct mtd_partition *partitions; | 303 | struct mtd_partition *partitions; |
305 | unsigned int nr_partitions; | 304 | unsigned int nr_partitions; |
@@ -326,13 +325,18 @@ struct fsmc_nand_data { | |||
326 | void (*select_chip)(uint32_t bank, uint32_t busw); | 325 | void (*select_chip)(uint32_t bank, uint32_t busw); |
327 | }; | 326 | }; |
328 | 327 | ||
328 | static inline struct fsmc_nand_data *mtd_to_fsmc(struct mtd_info *mtd) | ||
329 | { | ||
330 | return container_of(mtd_to_nand(mtd), struct fsmc_nand_data, nand); | ||
331 | } | ||
332 | |||
329 | /* Assert CS signal based on chipnr */ | 333 | /* Assert CS signal based on chipnr */ |
330 | static void fsmc_select_chip(struct mtd_info *mtd, int chipnr) | 334 | static void fsmc_select_chip(struct mtd_info *mtd, int chipnr) |
331 | { | 335 | { |
332 | struct nand_chip *chip = mtd->priv; | 336 | struct nand_chip *chip = mtd_to_nand(mtd); |
333 | struct fsmc_nand_data *host; | 337 | struct fsmc_nand_data *host; |
334 | 338 | ||
335 | host = container_of(mtd, struct fsmc_nand_data, mtd); | 339 | host = mtd_to_fsmc(mtd); |
336 | 340 | ||
337 | switch (chipnr) { | 341 | switch (chipnr) { |
338 | case -1: | 342 | case -1: |
@@ -358,9 +362,8 @@ static void fsmc_select_chip(struct mtd_info *mtd, int chipnr) | |||
358 | */ | 362 | */ |
359 | static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 363 | static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
360 | { | 364 | { |
361 | struct nand_chip *this = mtd->priv; | 365 | struct nand_chip *this = mtd_to_nand(mtd); |
362 | struct fsmc_nand_data *host = container_of(mtd, | 366 | struct fsmc_nand_data *host = mtd_to_fsmc(mtd); |
363 | struct fsmc_nand_data, mtd); | ||
364 | void __iomem *regs = host->regs_va; | 367 | void __iomem *regs = host->regs_va; |
365 | unsigned int bank = host->bank; | 368 | unsigned int bank = host->bank; |
366 | 369 | ||
@@ -445,8 +448,7 @@ static void fsmc_nand_setup(void __iomem *regs, uint32_t bank, | |||
445 | */ | 448 | */ |
446 | static void fsmc_enable_hwecc(struct mtd_info *mtd, int mode) | 449 | static void fsmc_enable_hwecc(struct mtd_info *mtd, int mode) |
447 | { | 450 | { |
448 | struct fsmc_nand_data *host = container_of(mtd, | 451 | struct fsmc_nand_data *host = mtd_to_fsmc(mtd); |
449 | struct fsmc_nand_data, mtd); | ||
450 | void __iomem *regs = host->regs_va; | 452 | void __iomem *regs = host->regs_va; |
451 | uint32_t bank = host->bank; | 453 | uint32_t bank = host->bank; |
452 | 454 | ||
@@ -466,8 +468,7 @@ static void fsmc_enable_hwecc(struct mtd_info *mtd, int mode) | |||
466 | static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data, | 468 | static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data, |
467 | uint8_t *ecc) | 469 | uint8_t *ecc) |
468 | { | 470 | { |
469 | struct fsmc_nand_data *host = container_of(mtd, | 471 | struct fsmc_nand_data *host = mtd_to_fsmc(mtd); |
470 | struct fsmc_nand_data, mtd); | ||
471 | void __iomem *regs = host->regs_va; | 472 | void __iomem *regs = host->regs_va; |
472 | uint32_t bank = host->bank; | 473 | uint32_t bank = host->bank; |
473 | uint32_t ecc_tmp; | 474 | uint32_t ecc_tmp; |
@@ -517,8 +518,7 @@ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data, | |||
517 | static int fsmc_read_hwecc_ecc1(struct mtd_info *mtd, const uint8_t *data, | 518 | static int fsmc_read_hwecc_ecc1(struct mtd_info *mtd, const uint8_t *data, |
518 | uint8_t *ecc) | 519 | uint8_t *ecc) |
519 | { | 520 | { |
520 | struct fsmc_nand_data *host = container_of(mtd, | 521 | struct fsmc_nand_data *host = mtd_to_fsmc(mtd); |
521 | struct fsmc_nand_data, mtd); | ||
522 | void __iomem *regs = host->regs_va; | 522 | void __iomem *regs = host->regs_va; |
523 | uint32_t bank = host->bank; | 523 | uint32_t bank = host->bank; |
524 | uint32_t ecc_tmp; | 524 | uint32_t ecc_tmp; |
@@ -629,7 +629,7 @@ unmap_dma: | |||
629 | static void fsmc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | 629 | static void fsmc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) |
630 | { | 630 | { |
631 | int i; | 631 | int i; |
632 | struct nand_chip *chip = mtd->priv; | 632 | struct nand_chip *chip = mtd_to_nand(mtd); |
633 | 633 | ||
634 | if (IS_ALIGNED((uint32_t)buf, sizeof(uint32_t)) && | 634 | if (IS_ALIGNED((uint32_t)buf, sizeof(uint32_t)) && |
635 | IS_ALIGNED(len, sizeof(uint32_t))) { | 635 | IS_ALIGNED(len, sizeof(uint32_t))) { |
@@ -652,7 +652,7 @@ static void fsmc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | |||
652 | static void fsmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | 652 | static void fsmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) |
653 | { | 653 | { |
654 | int i; | 654 | int i; |
655 | struct nand_chip *chip = mtd->priv; | 655 | struct nand_chip *chip = mtd_to_nand(mtd); |
656 | 656 | ||
657 | if (IS_ALIGNED((uint32_t)buf, sizeof(uint32_t)) && | 657 | if (IS_ALIGNED((uint32_t)buf, sizeof(uint32_t)) && |
658 | IS_ALIGNED(len, sizeof(uint32_t))) { | 658 | IS_ALIGNED(len, sizeof(uint32_t))) { |
@@ -674,9 +674,8 @@ static void fsmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | |||
674 | */ | 674 | */ |
675 | static void fsmc_read_buf_dma(struct mtd_info *mtd, uint8_t *buf, int len) | 675 | static void fsmc_read_buf_dma(struct mtd_info *mtd, uint8_t *buf, int len) |
676 | { | 676 | { |
677 | struct fsmc_nand_data *host; | 677 | struct fsmc_nand_data *host = mtd_to_fsmc(mtd); |
678 | 678 | ||
679 | host = container_of(mtd, struct fsmc_nand_data, mtd); | ||
680 | dma_xfer(host, buf, len, DMA_FROM_DEVICE); | 679 | dma_xfer(host, buf, len, DMA_FROM_DEVICE); |
681 | } | 680 | } |
682 | 681 | ||
@@ -689,9 +688,8 @@ static void fsmc_read_buf_dma(struct mtd_info *mtd, uint8_t *buf, int len) | |||
689 | static void fsmc_write_buf_dma(struct mtd_info *mtd, const uint8_t *buf, | 688 | static void fsmc_write_buf_dma(struct mtd_info *mtd, const uint8_t *buf, |
690 | int len) | 689 | int len) |
691 | { | 690 | { |
692 | struct fsmc_nand_data *host; | 691 | struct fsmc_nand_data *host = mtd_to_fsmc(mtd); |
693 | 692 | ||
694 | host = container_of(mtd, struct fsmc_nand_data, mtd); | ||
695 | dma_xfer(host, (void *)buf, len, DMA_TO_DEVICE); | 693 | dma_xfer(host, (void *)buf, len, DMA_TO_DEVICE); |
696 | } | 694 | } |
697 | 695 | ||
@@ -712,8 +710,7 @@ static void fsmc_write_buf_dma(struct mtd_info *mtd, const uint8_t *buf, | |||
712 | static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | 710 | static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, |
713 | uint8_t *buf, int oob_required, int page) | 711 | uint8_t *buf, int oob_required, int page) |
714 | { | 712 | { |
715 | struct fsmc_nand_data *host = container_of(mtd, | 713 | struct fsmc_nand_data *host = mtd_to_fsmc(mtd); |
716 | struct fsmc_nand_data, mtd); | ||
717 | struct fsmc_eccplace *ecc_place = host->ecc_place; | 714 | struct fsmc_eccplace *ecc_place = host->ecc_place; |
718 | int i, j, s, stat, eccsize = chip->ecc.size; | 715 | int i, j, s, stat, eccsize = chip->ecc.size; |
719 | int eccbytes = chip->ecc.bytes; | 716 | int eccbytes = chip->ecc.bytes; |
@@ -782,9 +779,8 @@ static int fsmc_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
782 | static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat, | 779 | static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat, |
783 | uint8_t *read_ecc, uint8_t *calc_ecc) | 780 | uint8_t *read_ecc, uint8_t *calc_ecc) |
784 | { | 781 | { |
785 | struct fsmc_nand_data *host = container_of(mtd, | 782 | struct nand_chip *chip = mtd_to_nand(mtd); |
786 | struct fsmc_nand_data, mtd); | 783 | struct fsmc_nand_data *host = mtd_to_fsmc(mtd); |
787 | struct nand_chip *chip = mtd->priv; | ||
788 | void __iomem *regs = host->regs_va; | 784 | void __iomem *regs = host->regs_va; |
789 | unsigned int bank = host->bank; | 785 | unsigned int bank = host->bank; |
790 | uint32_t err_idx[8]; | 786 | uint32_t err_idx[8]; |
@@ -926,7 +922,6 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
926 | { | 922 | { |
927 | struct fsmc_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); | 923 | struct fsmc_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); |
928 | struct device_node __maybe_unused *np = pdev->dev.of_node; | 924 | struct device_node __maybe_unused *np = pdev->dev.of_node; |
929 | struct mtd_part_parser_data ppdata = {}; | ||
930 | struct fsmc_nand_data *host; | 925 | struct fsmc_nand_data *host; |
931 | struct mtd_info *mtd; | 926 | struct mtd_info *mtd; |
932 | struct nand_chip *nand; | 927 | struct nand_chip *nand; |
@@ -1012,12 +1007,12 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
1012 | init_completion(&host->dma_access_complete); | 1007 | init_completion(&host->dma_access_complete); |
1013 | 1008 | ||
1014 | /* Link all private pointers */ | 1009 | /* Link all private pointers */ |
1015 | mtd = &host->mtd; | 1010 | mtd = nand_to_mtd(&host->nand); |
1016 | nand = &host->nand; | 1011 | nand = &host->nand; |
1017 | mtd->priv = nand; | 1012 | nand_set_controller_data(nand, host); |
1018 | nand->priv = host; | 1013 | nand_set_flash_node(nand, np); |
1019 | 1014 | ||
1020 | host->mtd.dev.parent = &pdev->dev; | 1015 | mtd->dev.parent = &pdev->dev; |
1021 | nand->IO_ADDR_R = host->data_va; | 1016 | nand->IO_ADDR_R = host->data_va; |
1022 | nand->IO_ADDR_W = host->data_va; | 1017 | nand->IO_ADDR_W = host->data_va; |
1023 | nand->cmd_ctrl = fsmc_cmd_ctrl; | 1018 | nand->cmd_ctrl = fsmc_cmd_ctrl; |
@@ -1033,7 +1028,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
1033 | nand->options = pdata->options; | 1028 | nand->options = pdata->options; |
1034 | nand->select_chip = fsmc_select_chip; | 1029 | nand->select_chip = fsmc_select_chip; |
1035 | nand->badblockbits = 7; | 1030 | nand->badblockbits = 7; |
1036 | nand->flash_node = np; | 1031 | nand_set_flash_node(nand, np); |
1037 | 1032 | ||
1038 | if (pdata->width == FSMC_NAND_BW16) | 1033 | if (pdata->width == FSMC_NAND_BW16) |
1039 | nand->options |= NAND_BUSWIDTH_16; | 1034 | nand->options |= NAND_BUSWIDTH_16; |
@@ -1080,14 +1075,14 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
1080 | /* | 1075 | /* |
1081 | * Scan to find existence of the device | 1076 | * Scan to find existence of the device |
1082 | */ | 1077 | */ |
1083 | if (nand_scan_ident(&host->mtd, 1, NULL)) { | 1078 | if (nand_scan_ident(mtd, 1, NULL)) { |
1084 | ret = -ENXIO; | 1079 | ret = -ENXIO; |
1085 | dev_err(&pdev->dev, "No NAND Device found!\n"); | 1080 | dev_err(&pdev->dev, "No NAND Device found!\n"); |
1086 | goto err_scan_ident; | 1081 | goto err_scan_ident; |
1087 | } | 1082 | } |
1088 | 1083 | ||
1089 | if (AMBA_REV_BITS(host->pid) >= 8) { | 1084 | if (AMBA_REV_BITS(host->pid) >= 8) { |
1090 | switch (host->mtd.oobsize) { | 1085 | switch (mtd->oobsize) { |
1091 | case 16: | 1086 | case 16: |
1092 | nand->ecc.layout = &fsmc_ecc4_16_layout; | 1087 | nand->ecc.layout = &fsmc_ecc4_16_layout; |
1093 | host->ecc_place = &fsmc_ecc4_sp_place; | 1088 | host->ecc_place = &fsmc_ecc4_sp_place; |
@@ -1138,7 +1133,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
1138 | * generated later in nand_bch_init() later. | 1133 | * generated later in nand_bch_init() later. |
1139 | */ | 1134 | */ |
1140 | if (nand->ecc.mode != NAND_ECC_SOFT_BCH) { | 1135 | if (nand->ecc.mode != NAND_ECC_SOFT_BCH) { |
1141 | switch (host->mtd.oobsize) { | 1136 | switch (mtd->oobsize) { |
1142 | case 16: | 1137 | case 16: |
1143 | nand->ecc.layout = &fsmc_ecc1_16_layout; | 1138 | nand->ecc.layout = &fsmc_ecc1_16_layout; |
1144 | break; | 1139 | break; |
@@ -1159,7 +1154,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
1159 | } | 1154 | } |
1160 | 1155 | ||
1161 | /* Second stage of scan to fill MTD data-structures */ | 1156 | /* Second stage of scan to fill MTD data-structures */ |
1162 | if (nand_scan_tail(&host->mtd)) { | 1157 | if (nand_scan_tail(mtd)) { |
1163 | ret = -ENXIO; | 1158 | ret = -ENXIO; |
1164 | goto err_probe; | 1159 | goto err_probe; |
1165 | } | 1160 | } |
@@ -1174,10 +1169,8 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
1174 | /* | 1169 | /* |
1175 | * Check for partition info passed | 1170 | * Check for partition info passed |
1176 | */ | 1171 | */ |
1177 | host->mtd.name = "nand"; | 1172 | mtd->name = "nand"; |
1178 | ppdata.of_node = np; | 1173 | ret = mtd_device_register(mtd, host->partitions, host->nr_partitions); |
1179 | ret = mtd_device_parse_register(&host->mtd, NULL, &ppdata, | ||
1180 | host->partitions, host->nr_partitions); | ||
1181 | if (ret) | 1174 | if (ret) |
1182 | goto err_probe; | 1175 | goto err_probe; |
1183 | 1176 | ||
@@ -1207,7 +1200,7 @@ static int fsmc_nand_remove(struct platform_device *pdev) | |||
1207 | struct fsmc_nand_data *host = platform_get_drvdata(pdev); | 1200 | struct fsmc_nand_data *host = platform_get_drvdata(pdev); |
1208 | 1201 | ||
1209 | if (host) { | 1202 | if (host) { |
1210 | nand_release(&host->mtd); | 1203 | nand_release(nand_to_mtd(&host->nand)); |
1211 | 1204 | ||
1212 | if (host->mode == USE_DMA_ACCESS) { | 1205 | if (host->mode == USE_DMA_ACCESS) { |
1213 | dma_release_channel(host->write_dma_chan); | 1206 | dma_release_channel(host->write_dma_chan); |
diff --git a/drivers/mtd/nand/gpio.c b/drivers/mtd/nand/gpio.c index 9ab97f934c37..ded658fc7d73 100644 --- a/drivers/mtd/nand/gpio.c +++ b/drivers/mtd/nand/gpio.c | |||
@@ -35,12 +35,14 @@ | |||
35 | 35 | ||
36 | struct gpiomtd { | 36 | struct gpiomtd { |
37 | void __iomem *io_sync; | 37 | void __iomem *io_sync; |
38 | struct mtd_info mtd_info; | ||
39 | struct nand_chip nand_chip; | 38 | struct nand_chip nand_chip; |
40 | struct gpio_nand_platdata plat; | 39 | struct gpio_nand_platdata plat; |
41 | }; | 40 | }; |
42 | 41 | ||
43 | #define gpio_nand_getpriv(x) container_of(x, struct gpiomtd, mtd_info) | 42 | static inline struct gpiomtd *gpio_nand_getpriv(struct mtd_info *mtd) |
43 | { | ||
44 | return container_of(mtd_to_nand(mtd), struct gpiomtd, nand_chip); | ||
45 | } | ||
44 | 46 | ||
45 | 47 | ||
46 | #ifdef CONFIG_ARM | 48 | #ifdef CONFIG_ARM |
@@ -195,7 +197,7 @@ static int gpio_nand_remove(struct platform_device *pdev) | |||
195 | { | 197 | { |
196 | struct gpiomtd *gpiomtd = platform_get_drvdata(pdev); | 198 | struct gpiomtd *gpiomtd = platform_get_drvdata(pdev); |
197 | 199 | ||
198 | nand_release(&gpiomtd->mtd_info); | 200 | nand_release(nand_to_mtd(&gpiomtd->nand_chip)); |
199 | 201 | ||
200 | if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) | 202 | if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) |
201 | gpio_set_value(gpiomtd->plat.gpio_nwp, 0); | 203 | gpio_set_value(gpiomtd->plat.gpio_nwp, 0); |
@@ -208,8 +210,8 @@ static int gpio_nand_probe(struct platform_device *pdev) | |||
208 | { | 210 | { |
209 | struct gpiomtd *gpiomtd; | 211 | struct gpiomtd *gpiomtd; |
210 | struct nand_chip *chip; | 212 | struct nand_chip *chip; |
213 | struct mtd_info *mtd; | ||
211 | struct resource *res; | 214 | struct resource *res; |
212 | struct mtd_part_parser_data ppdata = {}; | ||
213 | int ret = 0; | 215 | int ret = 0; |
214 | 216 | ||
215 | if (!pdev->dev.of_node && !dev_get_platdata(&pdev->dev)) | 217 | if (!pdev->dev.of_node && !dev_get_platdata(&pdev->dev)) |
@@ -268,33 +270,31 @@ static int gpio_nand_probe(struct platform_device *pdev) | |||
268 | chip->dev_ready = gpio_nand_devready; | 270 | chip->dev_ready = gpio_nand_devready; |
269 | } | 271 | } |
270 | 272 | ||
273 | nand_set_flash_node(chip, pdev->dev.of_node); | ||
271 | chip->IO_ADDR_W = chip->IO_ADDR_R; | 274 | chip->IO_ADDR_W = chip->IO_ADDR_R; |
272 | chip->ecc.mode = NAND_ECC_SOFT; | 275 | chip->ecc.mode = NAND_ECC_SOFT; |
273 | chip->options = gpiomtd->plat.options; | 276 | chip->options = gpiomtd->plat.options; |
274 | chip->chip_delay = gpiomtd->plat.chip_delay; | 277 | chip->chip_delay = gpiomtd->plat.chip_delay; |
275 | chip->cmd_ctrl = gpio_nand_cmd_ctrl; | 278 | chip->cmd_ctrl = gpio_nand_cmd_ctrl; |
276 | 279 | ||
277 | gpiomtd->mtd_info.priv = chip; | 280 | mtd = nand_to_mtd(chip); |
278 | gpiomtd->mtd_info.dev.parent = &pdev->dev; | 281 | mtd->dev.parent = &pdev->dev; |
279 | 282 | ||
280 | platform_set_drvdata(pdev, gpiomtd); | 283 | platform_set_drvdata(pdev, gpiomtd); |
281 | 284 | ||
282 | if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) | 285 | if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) |
283 | gpio_direction_output(gpiomtd->plat.gpio_nwp, 1); | 286 | gpio_direction_output(gpiomtd->plat.gpio_nwp, 1); |
284 | 287 | ||
285 | if (nand_scan(&gpiomtd->mtd_info, 1)) { | 288 | if (nand_scan(mtd, 1)) { |
286 | ret = -ENXIO; | 289 | ret = -ENXIO; |
287 | goto err_wp; | 290 | goto err_wp; |
288 | } | 291 | } |
289 | 292 | ||
290 | if (gpiomtd->plat.adjust_parts) | 293 | if (gpiomtd->plat.adjust_parts) |
291 | gpiomtd->plat.adjust_parts(&gpiomtd->plat, | 294 | gpiomtd->plat.adjust_parts(&gpiomtd->plat, mtd->size); |
292 | gpiomtd->mtd_info.size); | ||
293 | 295 | ||
294 | ppdata.of_node = pdev->dev.of_node; | 296 | ret = mtd_device_register(mtd, gpiomtd->plat.parts, |
295 | ret = mtd_device_parse_register(&gpiomtd->mtd_info, NULL, &ppdata, | 297 | gpiomtd->plat.num_parts); |
296 | gpiomtd->plat.parts, | ||
297 | gpiomtd->plat.num_parts); | ||
298 | if (!ret) | 298 | if (!ret) |
299 | return 0; | 299 | return 0; |
300 | 300 | ||
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c index 43fa16b5f510..0f68a99fc4ad 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c | |||
@@ -919,7 +919,7 @@ static int enable_edo_mode(struct gpmi_nand_data *this, int mode) | |||
919 | { | 919 | { |
920 | struct resources *r = &this->resources; | 920 | struct resources *r = &this->resources; |
921 | struct nand_chip *nand = &this->nand; | 921 | struct nand_chip *nand = &this->nand; |
922 | struct mtd_info *mtd = &this->mtd; | 922 | struct mtd_info *mtd = nand_to_mtd(nand); |
923 | uint8_t *feature; | 923 | uint8_t *feature; |
924 | unsigned long rate; | 924 | unsigned long rate; |
925 | int ret; | 925 | int ret; |
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index 2064adac1d17..235ddcb58f39 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c | |||
@@ -107,7 +107,7 @@ static irqreturn_t bch_irq(int irq, void *cookie) | |||
107 | static inline int get_ecc_strength(struct gpmi_nand_data *this) | 107 | static inline int get_ecc_strength(struct gpmi_nand_data *this) |
108 | { | 108 | { |
109 | struct bch_geometry *geo = &this->bch_geometry; | 109 | struct bch_geometry *geo = &this->bch_geometry; |
110 | struct mtd_info *mtd = &this->mtd; | 110 | struct mtd_info *mtd = nand_to_mtd(&this->nand); |
111 | int ecc_strength; | 111 | int ecc_strength; |
112 | 112 | ||
113 | ecc_strength = ((mtd->oobsize - geo->metadata_size) * 8) | 113 | ecc_strength = ((mtd->oobsize - geo->metadata_size) * 8) |
@@ -139,8 +139,8 @@ static inline bool gpmi_check_ecc(struct gpmi_nand_data *this) | |||
139 | static bool set_geometry_by_ecc_info(struct gpmi_nand_data *this) | 139 | static bool set_geometry_by_ecc_info(struct gpmi_nand_data *this) |
140 | { | 140 | { |
141 | struct bch_geometry *geo = &this->bch_geometry; | 141 | struct bch_geometry *geo = &this->bch_geometry; |
142 | struct mtd_info *mtd = &this->mtd; | 142 | struct nand_chip *chip = &this->nand; |
143 | struct nand_chip *chip = mtd->priv; | 143 | struct mtd_info *mtd = nand_to_mtd(chip); |
144 | struct nand_oobfree *of = gpmi_hw_ecclayout.oobfree; | 144 | struct nand_oobfree *of = gpmi_hw_ecclayout.oobfree; |
145 | unsigned int block_mark_bit_offset; | 145 | unsigned int block_mark_bit_offset; |
146 | 146 | ||
@@ -257,7 +257,7 @@ static bool set_geometry_by_ecc_info(struct gpmi_nand_data *this) | |||
257 | static int legacy_set_geometry(struct gpmi_nand_data *this) | 257 | static int legacy_set_geometry(struct gpmi_nand_data *this) |
258 | { | 258 | { |
259 | struct bch_geometry *geo = &this->bch_geometry; | 259 | struct bch_geometry *geo = &this->bch_geometry; |
260 | struct mtd_info *mtd = &this->mtd; | 260 | struct mtd_info *mtd = nand_to_mtd(&this->nand); |
261 | unsigned int metadata_size; | 261 | unsigned int metadata_size; |
262 | unsigned int status_size; | 262 | unsigned int status_size; |
263 | unsigned int block_mark_bit_offset; | 263 | unsigned int block_mark_bit_offset; |
@@ -804,7 +804,7 @@ static int gpmi_alloc_dma_buffer(struct gpmi_nand_data *this) | |||
804 | { | 804 | { |
805 | struct bch_geometry *geo = &this->bch_geometry; | 805 | struct bch_geometry *geo = &this->bch_geometry; |
806 | struct device *dev = this->dev; | 806 | struct device *dev = this->dev; |
807 | struct mtd_info *mtd = &this->mtd; | 807 | struct mtd_info *mtd = nand_to_mtd(&this->nand); |
808 | 808 | ||
809 | /* [1] Allocate a command buffer. PAGE_SIZE is enough. */ | 809 | /* [1] Allocate a command buffer. PAGE_SIZE is enough. */ |
810 | this->cmd_buffer = kzalloc(PAGE_SIZE, GFP_DMA | GFP_KERNEL); | 810 | this->cmd_buffer = kzalloc(PAGE_SIZE, GFP_DMA | GFP_KERNEL); |
@@ -856,8 +856,8 @@ error_alloc: | |||
856 | 856 | ||
857 | static void gpmi_cmd_ctrl(struct mtd_info *mtd, int data, unsigned int ctrl) | 857 | static void gpmi_cmd_ctrl(struct mtd_info *mtd, int data, unsigned int ctrl) |
858 | { | 858 | { |
859 | struct nand_chip *chip = mtd->priv; | 859 | struct nand_chip *chip = mtd_to_nand(mtd); |
860 | struct gpmi_nand_data *this = chip->priv; | 860 | struct gpmi_nand_data *this = nand_get_controller_data(chip); |
861 | int ret; | 861 | int ret; |
862 | 862 | ||
863 | /* | 863 | /* |
@@ -890,16 +890,16 @@ static void gpmi_cmd_ctrl(struct mtd_info *mtd, int data, unsigned int ctrl) | |||
890 | 890 | ||
891 | static int gpmi_dev_ready(struct mtd_info *mtd) | 891 | static int gpmi_dev_ready(struct mtd_info *mtd) |
892 | { | 892 | { |
893 | struct nand_chip *chip = mtd->priv; | 893 | struct nand_chip *chip = mtd_to_nand(mtd); |
894 | struct gpmi_nand_data *this = chip->priv; | 894 | struct gpmi_nand_data *this = nand_get_controller_data(chip); |
895 | 895 | ||
896 | return gpmi_is_ready(this, this->current_chip); | 896 | return gpmi_is_ready(this, this->current_chip); |
897 | } | 897 | } |
898 | 898 | ||
899 | static void gpmi_select_chip(struct mtd_info *mtd, int chipnr) | 899 | static void gpmi_select_chip(struct mtd_info *mtd, int chipnr) |
900 | { | 900 | { |
901 | struct nand_chip *chip = mtd->priv; | 901 | struct nand_chip *chip = mtd_to_nand(mtd); |
902 | struct gpmi_nand_data *this = chip->priv; | 902 | struct gpmi_nand_data *this = nand_get_controller_data(chip); |
903 | 903 | ||
904 | if ((this->current_chip < 0) && (chipnr >= 0)) | 904 | if ((this->current_chip < 0) && (chipnr >= 0)) |
905 | gpmi_begin(this); | 905 | gpmi_begin(this); |
@@ -911,8 +911,8 @@ static void gpmi_select_chip(struct mtd_info *mtd, int chipnr) | |||
911 | 911 | ||
912 | static void gpmi_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | 912 | static void gpmi_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) |
913 | { | 913 | { |
914 | struct nand_chip *chip = mtd->priv; | 914 | struct nand_chip *chip = mtd_to_nand(mtd); |
915 | struct gpmi_nand_data *this = chip->priv; | 915 | struct gpmi_nand_data *this = nand_get_controller_data(chip); |
916 | 916 | ||
917 | dev_dbg(this->dev, "len is %d\n", len); | 917 | dev_dbg(this->dev, "len is %d\n", len); |
918 | this->upper_buf = buf; | 918 | this->upper_buf = buf; |
@@ -923,8 +923,8 @@ static void gpmi_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | |||
923 | 923 | ||
924 | static void gpmi_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | 924 | static void gpmi_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) |
925 | { | 925 | { |
926 | struct nand_chip *chip = mtd->priv; | 926 | struct nand_chip *chip = mtd_to_nand(mtd); |
927 | struct gpmi_nand_data *this = chip->priv; | 927 | struct gpmi_nand_data *this = nand_get_controller_data(chip); |
928 | 928 | ||
929 | dev_dbg(this->dev, "len is %d\n", len); | 929 | dev_dbg(this->dev, "len is %d\n", len); |
930 | this->upper_buf = (uint8_t *)buf; | 930 | this->upper_buf = (uint8_t *)buf; |
@@ -935,8 +935,8 @@ static void gpmi_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | |||
935 | 935 | ||
936 | static uint8_t gpmi_read_byte(struct mtd_info *mtd) | 936 | static uint8_t gpmi_read_byte(struct mtd_info *mtd) |
937 | { | 937 | { |
938 | struct nand_chip *chip = mtd->priv; | 938 | struct nand_chip *chip = mtd_to_nand(mtd); |
939 | struct gpmi_nand_data *this = chip->priv; | 939 | struct gpmi_nand_data *this = nand_get_controller_data(chip); |
940 | uint8_t *buf = this->data_buffer_dma; | 940 | uint8_t *buf = this->data_buffer_dma; |
941 | 941 | ||
942 | gpmi_read_buf(mtd, buf, 1); | 942 | gpmi_read_buf(mtd, buf, 1); |
@@ -994,7 +994,7 @@ static void block_mark_swapping(struct gpmi_nand_data *this, | |||
994 | static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, | 994 | static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, |
995 | uint8_t *buf, int oob_required, int page) | 995 | uint8_t *buf, int oob_required, int page) |
996 | { | 996 | { |
997 | struct gpmi_nand_data *this = chip->priv; | 997 | struct gpmi_nand_data *this = nand_get_controller_data(chip); |
998 | struct bch_geometry *nfc_geo = &this->bch_geometry; | 998 | struct bch_geometry *nfc_geo = &this->bch_geometry; |
999 | void *payload_virt; | 999 | void *payload_virt; |
1000 | dma_addr_t payload_phys; | 1000 | dma_addr_t payload_phys; |
@@ -1074,7 +1074,7 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
1074 | static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, | 1074 | static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, |
1075 | uint32_t offs, uint32_t len, uint8_t *buf, int page) | 1075 | uint32_t offs, uint32_t len, uint8_t *buf, int page) |
1076 | { | 1076 | { |
1077 | struct gpmi_nand_data *this = chip->priv; | 1077 | struct gpmi_nand_data *this = nand_get_controller_data(chip); |
1078 | void __iomem *bch_regs = this->resources.bch_regs; | 1078 | void __iomem *bch_regs = this->resources.bch_regs; |
1079 | struct bch_geometry old_geo = this->bch_geometry; | 1079 | struct bch_geometry old_geo = this->bch_geometry; |
1080 | struct bch_geometry *geo = &this->bch_geometry; | 1080 | struct bch_geometry *geo = &this->bch_geometry; |
@@ -1162,7 +1162,7 @@ static int gpmi_ecc_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, | |||
1162 | static int gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip, | 1162 | static int gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip, |
1163 | const uint8_t *buf, int oob_required, int page) | 1163 | const uint8_t *buf, int oob_required, int page) |
1164 | { | 1164 | { |
1165 | struct gpmi_nand_data *this = chip->priv; | 1165 | struct gpmi_nand_data *this = nand_get_controller_data(chip); |
1166 | struct bch_geometry *nfc_geo = &this->bch_geometry; | 1166 | struct bch_geometry *nfc_geo = &this->bch_geometry; |
1167 | const void *payload_virt; | 1167 | const void *payload_virt; |
1168 | dma_addr_t payload_phys; | 1168 | dma_addr_t payload_phys; |
@@ -1298,7 +1298,7 @@ exit_auxiliary: | |||
1298 | static int gpmi_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *chip, | 1298 | static int gpmi_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *chip, |
1299 | int page) | 1299 | int page) |
1300 | { | 1300 | { |
1301 | struct gpmi_nand_data *this = chip->priv; | 1301 | struct gpmi_nand_data *this = nand_get_controller_data(chip); |
1302 | 1302 | ||
1303 | dev_dbg(this->dev, "page number is %d\n", page); | 1303 | dev_dbg(this->dev, "page number is %d\n", page); |
1304 | /* clear the OOB buffer */ | 1304 | /* clear the OOB buffer */ |
@@ -1359,7 +1359,7 @@ static int gpmi_ecc_read_page_raw(struct mtd_info *mtd, | |||
1359 | struct nand_chip *chip, uint8_t *buf, | 1359 | struct nand_chip *chip, uint8_t *buf, |
1360 | int oob_required, int page) | 1360 | int oob_required, int page) |
1361 | { | 1361 | { |
1362 | struct gpmi_nand_data *this = chip->priv; | 1362 | struct gpmi_nand_data *this = nand_get_controller_data(chip); |
1363 | struct bch_geometry *nfc_geo = &this->bch_geometry; | 1363 | struct bch_geometry *nfc_geo = &this->bch_geometry; |
1364 | int eccsize = nfc_geo->ecc_chunk_size; | 1364 | int eccsize = nfc_geo->ecc_chunk_size; |
1365 | int eccbits = nfc_geo->ecc_strength * nfc_geo->gf_len; | 1365 | int eccbits = nfc_geo->ecc_strength * nfc_geo->gf_len; |
@@ -1448,7 +1448,7 @@ static int gpmi_ecc_write_page_raw(struct mtd_info *mtd, | |||
1448 | const uint8_t *buf, | 1448 | const uint8_t *buf, |
1449 | int oob_required, int page) | 1449 | int oob_required, int page) |
1450 | { | 1450 | { |
1451 | struct gpmi_nand_data *this = chip->priv; | 1451 | struct gpmi_nand_data *this = nand_get_controller_data(chip); |
1452 | struct bch_geometry *nfc_geo = &this->bch_geometry; | 1452 | struct bch_geometry *nfc_geo = &this->bch_geometry; |
1453 | int eccsize = nfc_geo->ecc_chunk_size; | 1453 | int eccsize = nfc_geo->ecc_chunk_size; |
1454 | int eccbits = nfc_geo->ecc_strength * nfc_geo->gf_len; | 1454 | int eccbits = nfc_geo->ecc_strength * nfc_geo->gf_len; |
@@ -1538,8 +1538,8 @@ static int gpmi_ecc_write_oob_raw(struct mtd_info *mtd, struct nand_chip *chip, | |||
1538 | 1538 | ||
1539 | static int gpmi_block_markbad(struct mtd_info *mtd, loff_t ofs) | 1539 | static int gpmi_block_markbad(struct mtd_info *mtd, loff_t ofs) |
1540 | { | 1540 | { |
1541 | struct nand_chip *chip = mtd->priv; | 1541 | struct nand_chip *chip = mtd_to_nand(mtd); |
1542 | struct gpmi_nand_data *this = chip->priv; | 1542 | struct gpmi_nand_data *this = nand_get_controller_data(chip); |
1543 | int ret = 0; | 1543 | int ret = 0; |
1544 | uint8_t *block_mark; | 1544 | uint8_t *block_mark; |
1545 | int column, page, status, chipnr; | 1545 | int column, page, status, chipnr; |
@@ -1600,8 +1600,8 @@ static int mx23_check_transcription_stamp(struct gpmi_nand_data *this) | |||
1600 | { | 1600 | { |
1601 | struct boot_rom_geometry *rom_geo = &this->rom_geometry; | 1601 | struct boot_rom_geometry *rom_geo = &this->rom_geometry; |
1602 | struct device *dev = this->dev; | 1602 | struct device *dev = this->dev; |
1603 | struct mtd_info *mtd = &this->mtd; | ||
1604 | struct nand_chip *chip = &this->nand; | 1603 | struct nand_chip *chip = &this->nand; |
1604 | struct mtd_info *mtd = nand_to_mtd(chip); | ||
1605 | unsigned int search_area_size_in_strides; | 1605 | unsigned int search_area_size_in_strides; |
1606 | unsigned int stride; | 1606 | unsigned int stride; |
1607 | unsigned int page; | 1607 | unsigned int page; |
@@ -1655,8 +1655,8 @@ static int mx23_write_transcription_stamp(struct gpmi_nand_data *this) | |||
1655 | { | 1655 | { |
1656 | struct device *dev = this->dev; | 1656 | struct device *dev = this->dev; |
1657 | struct boot_rom_geometry *rom_geo = &this->rom_geometry; | 1657 | struct boot_rom_geometry *rom_geo = &this->rom_geometry; |
1658 | struct mtd_info *mtd = &this->mtd; | ||
1659 | struct nand_chip *chip = &this->nand; | 1658 | struct nand_chip *chip = &this->nand; |
1659 | struct mtd_info *mtd = nand_to_mtd(chip); | ||
1660 | unsigned int block_size_in_pages; | 1660 | unsigned int block_size_in_pages; |
1661 | unsigned int search_area_size_in_strides; | 1661 | unsigned int search_area_size_in_strides; |
1662 | unsigned int search_area_size_in_pages; | 1662 | unsigned int search_area_size_in_pages; |
@@ -1735,7 +1735,7 @@ static int mx23_boot_init(struct gpmi_nand_data *this) | |||
1735 | { | 1735 | { |
1736 | struct device *dev = this->dev; | 1736 | struct device *dev = this->dev; |
1737 | struct nand_chip *chip = &this->nand; | 1737 | struct nand_chip *chip = &this->nand; |
1738 | struct mtd_info *mtd = &this->mtd; | 1738 | struct mtd_info *mtd = nand_to_mtd(chip); |
1739 | unsigned int block_count; | 1739 | unsigned int block_count; |
1740 | unsigned int block; | 1740 | unsigned int block; |
1741 | int chipnr; | 1741 | int chipnr; |
@@ -1831,14 +1831,13 @@ static int gpmi_set_geometry(struct gpmi_nand_data *this) | |||
1831 | 1831 | ||
1832 | static void gpmi_nand_exit(struct gpmi_nand_data *this) | 1832 | static void gpmi_nand_exit(struct gpmi_nand_data *this) |
1833 | { | 1833 | { |
1834 | nand_release(&this->mtd); | 1834 | nand_release(nand_to_mtd(&this->nand)); |
1835 | gpmi_free_dma_buffer(this); | 1835 | gpmi_free_dma_buffer(this); |
1836 | } | 1836 | } |
1837 | 1837 | ||
1838 | static int gpmi_init_last(struct gpmi_nand_data *this) | 1838 | static int gpmi_init_last(struct gpmi_nand_data *this) |
1839 | { | 1839 | { |
1840 | struct mtd_info *mtd = &this->mtd; | 1840 | struct nand_chip *chip = &this->nand; |
1841 | struct nand_chip *chip = mtd->priv; | ||
1842 | struct nand_ecc_ctrl *ecc = &chip->ecc; | 1841 | struct nand_ecc_ctrl *ecc = &chip->ecc; |
1843 | struct bch_geometry *bch_geo = &this->bch_geometry; | 1842 | struct bch_geometry *bch_geo = &this->bch_geometry; |
1844 | int ret; | 1843 | int ret; |
@@ -1886,21 +1885,20 @@ static int gpmi_init_last(struct gpmi_nand_data *this) | |||
1886 | 1885 | ||
1887 | static int gpmi_nand_init(struct gpmi_nand_data *this) | 1886 | static int gpmi_nand_init(struct gpmi_nand_data *this) |
1888 | { | 1887 | { |
1889 | struct mtd_info *mtd = &this->mtd; | ||
1890 | struct nand_chip *chip = &this->nand; | 1888 | struct nand_chip *chip = &this->nand; |
1891 | struct mtd_part_parser_data ppdata = {}; | 1889 | struct mtd_info *mtd = nand_to_mtd(chip); |
1892 | int ret; | 1890 | int ret; |
1893 | 1891 | ||
1894 | /* init current chip */ | 1892 | /* init current chip */ |
1895 | this->current_chip = -1; | 1893 | this->current_chip = -1; |
1896 | 1894 | ||
1897 | /* init the MTD data structures */ | 1895 | /* init the MTD data structures */ |
1898 | mtd->priv = chip; | ||
1899 | mtd->name = "gpmi-nand"; | 1896 | mtd->name = "gpmi-nand"; |
1900 | mtd->dev.parent = this->dev; | 1897 | mtd->dev.parent = this->dev; |
1901 | 1898 | ||
1902 | /* init the nand_chip{}, we don't support a 16-bit NAND Flash bus. */ | 1899 | /* init the nand_chip{}, we don't support a 16-bit NAND Flash bus. */ |
1903 | chip->priv = this; | 1900 | nand_set_controller_data(chip, this); |
1901 | nand_set_flash_node(chip, this->pdev->dev.of_node); | ||
1904 | chip->select_chip = gpmi_select_chip; | 1902 | chip->select_chip = gpmi_select_chip; |
1905 | chip->cmd_ctrl = gpmi_cmd_ctrl; | 1903 | chip->cmd_ctrl = gpmi_cmd_ctrl; |
1906 | chip->dev_ready = gpmi_dev_ready; | 1904 | chip->dev_ready = gpmi_dev_ready; |
@@ -1954,8 +1952,7 @@ static int gpmi_nand_init(struct gpmi_nand_data *this) | |||
1954 | if (ret) | 1952 | if (ret) |
1955 | goto err_out; | 1953 | goto err_out; |
1956 | 1954 | ||
1957 | ppdata.of_node = this->pdev->dev.of_node; | 1955 | ret = mtd_device_register(mtd, NULL, 0); |
1958 | ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); | ||
1959 | if (ret) | 1956 | if (ret) |
1960 | goto err_out; | 1957 | goto err_out; |
1961 | return 0; | 1958 | return 0; |
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h index 544062f65020..4e49a1f5fa27 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h | |||
@@ -160,7 +160,6 @@ struct gpmi_nand_data { | |||
160 | 160 | ||
161 | /* MTD / NAND */ | 161 | /* MTD / NAND */ |
162 | struct nand_chip nand; | 162 | struct nand_chip nand; |
163 | struct mtd_info mtd; | ||
164 | 163 | ||
165 | /* General-use Variables */ | 164 | /* General-use Variables */ |
166 | int current_chip; | 165 | int current_chip; |
diff --git a/drivers/mtd/nand/hisi504_nand.c b/drivers/mtd/nand/hisi504_nand.c index 0cb2e886937d..f8d37f36a81c 100644 --- a/drivers/mtd/nand/hisi504_nand.c +++ b/drivers/mtd/nand/hisi504_nand.c | |||
@@ -134,7 +134,6 @@ | |||
134 | 134 | ||
135 | struct hinfc_host { | 135 | struct hinfc_host { |
136 | struct nand_chip chip; | 136 | struct nand_chip chip; |
137 | struct mtd_info mtd; | ||
138 | struct device *dev; | 137 | struct device *dev; |
139 | void __iomem *iobase; | 138 | void __iomem *iobase; |
140 | void __iomem *mmio; | 139 | void __iomem *mmio; |
@@ -189,8 +188,8 @@ static void wait_controller_finished(struct hinfc_host *host) | |||
189 | 188 | ||
190 | static void hisi_nfc_dma_transfer(struct hinfc_host *host, int todev) | 189 | static void hisi_nfc_dma_transfer(struct hinfc_host *host, int todev) |
191 | { | 190 | { |
192 | struct mtd_info *mtd = &host->mtd; | 191 | struct nand_chip *chip = &host->chip; |
193 | struct nand_chip *chip = mtd->priv; | 192 | struct mtd_info *mtd = nand_to_mtd(chip); |
194 | unsigned long val; | 193 | unsigned long val; |
195 | int ret; | 194 | int ret; |
196 | 195 | ||
@@ -262,7 +261,7 @@ static int hisi_nfc_send_cmd_pageprog(struct hinfc_host *host) | |||
262 | 261 | ||
263 | static int hisi_nfc_send_cmd_readstart(struct hinfc_host *host) | 262 | static int hisi_nfc_send_cmd_readstart(struct hinfc_host *host) |
264 | { | 263 | { |
265 | struct mtd_info *mtd = &host->mtd; | 264 | struct mtd_info *mtd = nand_to_mtd(&host->chip); |
266 | 265 | ||
267 | if ((host->addr_value[0] == host->cache_addr_value[0]) && | 266 | if ((host->addr_value[0] == host->cache_addr_value[0]) && |
268 | (host->addr_value[1] == host->cache_addr_value[1])) | 267 | (host->addr_value[1] == host->cache_addr_value[1])) |
@@ -357,8 +356,8 @@ static int hisi_nfc_send_cmd_reset(struct hinfc_host *host, int chipselect) | |||
357 | 356 | ||
358 | static void hisi_nfc_select_chip(struct mtd_info *mtd, int chipselect) | 357 | static void hisi_nfc_select_chip(struct mtd_info *mtd, int chipselect) |
359 | { | 358 | { |
360 | struct nand_chip *chip = mtd->priv; | 359 | struct nand_chip *chip = mtd_to_nand(mtd); |
361 | struct hinfc_host *host = chip->priv; | 360 | struct hinfc_host *host = nand_get_controller_data(chip); |
362 | 361 | ||
363 | if (chipselect < 0) | 362 | if (chipselect < 0) |
364 | return; | 363 | return; |
@@ -368,8 +367,8 @@ static void hisi_nfc_select_chip(struct mtd_info *mtd, int chipselect) | |||
368 | 367 | ||
369 | static uint8_t hisi_nfc_read_byte(struct mtd_info *mtd) | 368 | static uint8_t hisi_nfc_read_byte(struct mtd_info *mtd) |
370 | { | 369 | { |
371 | struct nand_chip *chip = mtd->priv; | 370 | struct nand_chip *chip = mtd_to_nand(mtd); |
372 | struct hinfc_host *host = chip->priv; | 371 | struct hinfc_host *host = nand_get_controller_data(chip); |
373 | 372 | ||
374 | if (host->command == NAND_CMD_STATUS) | 373 | if (host->command == NAND_CMD_STATUS) |
375 | return *(uint8_t *)(host->mmio); | 374 | return *(uint8_t *)(host->mmio); |
@@ -384,8 +383,8 @@ static uint8_t hisi_nfc_read_byte(struct mtd_info *mtd) | |||
384 | 383 | ||
385 | static u16 hisi_nfc_read_word(struct mtd_info *mtd) | 384 | static u16 hisi_nfc_read_word(struct mtd_info *mtd) |
386 | { | 385 | { |
387 | struct nand_chip *chip = mtd->priv; | 386 | struct nand_chip *chip = mtd_to_nand(mtd); |
388 | struct hinfc_host *host = chip->priv; | 387 | struct hinfc_host *host = nand_get_controller_data(chip); |
389 | 388 | ||
390 | host->offset += 2; | 389 | host->offset += 2; |
391 | return *(u16 *)(host->buffer + host->offset - 2); | 390 | return *(u16 *)(host->buffer + host->offset - 2); |
@@ -394,8 +393,8 @@ static u16 hisi_nfc_read_word(struct mtd_info *mtd) | |||
394 | static void | 393 | static void |
395 | hisi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | 394 | hisi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) |
396 | { | 395 | { |
397 | struct nand_chip *chip = mtd->priv; | 396 | struct nand_chip *chip = mtd_to_nand(mtd); |
398 | struct hinfc_host *host = chip->priv; | 397 | struct hinfc_host *host = nand_get_controller_data(chip); |
399 | 398 | ||
400 | memcpy(host->buffer + host->offset, buf, len); | 399 | memcpy(host->buffer + host->offset, buf, len); |
401 | host->offset += len; | 400 | host->offset += len; |
@@ -403,8 +402,8 @@ hisi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | |||
403 | 402 | ||
404 | static void hisi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | 403 | static void hisi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) |
405 | { | 404 | { |
406 | struct nand_chip *chip = mtd->priv; | 405 | struct nand_chip *chip = mtd_to_nand(mtd); |
407 | struct hinfc_host *host = chip->priv; | 406 | struct hinfc_host *host = nand_get_controller_data(chip); |
408 | 407 | ||
409 | memcpy(buf, host->buffer + host->offset, len); | 408 | memcpy(buf, host->buffer + host->offset, len); |
410 | host->offset += len; | 409 | host->offset += len; |
@@ -412,8 +411,8 @@ static void hisi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | |||
412 | 411 | ||
413 | static void set_addr(struct mtd_info *mtd, int column, int page_addr) | 412 | static void set_addr(struct mtd_info *mtd, int column, int page_addr) |
414 | { | 413 | { |
415 | struct nand_chip *chip = mtd->priv; | 414 | struct nand_chip *chip = mtd_to_nand(mtd); |
416 | struct hinfc_host *host = chip->priv; | 415 | struct hinfc_host *host = nand_get_controller_data(chip); |
417 | unsigned int command = host->command; | 416 | unsigned int command = host->command; |
418 | 417 | ||
419 | host->addr_cycle = 0; | 418 | host->addr_cycle = 0; |
@@ -448,8 +447,8 @@ static void set_addr(struct mtd_info *mtd, int column, int page_addr) | |||
448 | static void hisi_nfc_cmdfunc(struct mtd_info *mtd, unsigned command, int column, | 447 | static void hisi_nfc_cmdfunc(struct mtd_info *mtd, unsigned command, int column, |
449 | int page_addr) | 448 | int page_addr) |
450 | { | 449 | { |
451 | struct nand_chip *chip = mtd->priv; | 450 | struct nand_chip *chip = mtd_to_nand(mtd); |
452 | struct hinfc_host *host = chip->priv; | 451 | struct hinfc_host *host = nand_get_controller_data(chip); |
453 | int is_cache_invalid = 1; | 452 | int is_cache_invalid = 1; |
454 | unsigned int flag = 0; | 453 | unsigned int flag = 0; |
455 | 454 | ||
@@ -543,7 +542,7 @@ static irqreturn_t hinfc_irq_handle(int irq, void *devid) | |||
543 | static int hisi_nand_read_page_hwecc(struct mtd_info *mtd, | 542 | static int hisi_nand_read_page_hwecc(struct mtd_info *mtd, |
544 | struct nand_chip *chip, uint8_t *buf, int oob_required, int page) | 543 | struct nand_chip *chip, uint8_t *buf, int oob_required, int page) |
545 | { | 544 | { |
546 | struct hinfc_host *host = chip->priv; | 545 | struct hinfc_host *host = nand_get_controller_data(chip); |
547 | int max_bitflips = 0, stat = 0, stat_max = 0, status_ecc; | 546 | int max_bitflips = 0, stat = 0, stat_max = 0, status_ecc; |
548 | int stat_1, stat_2; | 547 | int stat_1, stat_2; |
549 | 548 | ||
@@ -575,7 +574,7 @@ static int hisi_nand_read_page_hwecc(struct mtd_info *mtd, | |||
575 | static int hisi_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip, | 574 | static int hisi_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip, |
576 | int page) | 575 | int page) |
577 | { | 576 | { |
578 | struct hinfc_host *host = chip->priv; | 577 | struct hinfc_host *host = nand_get_controller_data(chip); |
579 | 578 | ||
580 | chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page); | 579 | chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page); |
581 | chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); | 580 | chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); |
@@ -643,7 +642,7 @@ static int hisi_nfc_ecc_probe(struct hinfc_host *host) | |||
643 | int size, strength, ecc_bits; | 642 | int size, strength, ecc_bits; |
644 | struct device *dev = host->dev; | 643 | struct device *dev = host->dev; |
645 | struct nand_chip *chip = &host->chip; | 644 | struct nand_chip *chip = &host->chip; |
646 | struct mtd_info *mtd = &host->mtd; | 645 | struct mtd_info *mtd = nand_to_mtd(chip); |
647 | struct device_node *np = host->dev->of_node; | 646 | struct device_node *np = host->dev->of_node; |
648 | 647 | ||
649 | size = of_get_nand_ecc_step_size(np); | 648 | size = of_get_nand_ecc_step_size(np); |
@@ -704,7 +703,6 @@ static int hisi_nfc_probe(struct platform_device *pdev) | |||
704 | struct mtd_info *mtd; | 703 | struct mtd_info *mtd; |
705 | struct resource *res; | 704 | struct resource *res; |
706 | struct device_node *np = dev->of_node; | 705 | struct device_node *np = dev->of_node; |
707 | struct mtd_part_parser_data ppdata; | ||
708 | 706 | ||
709 | host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); | 707 | host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL); |
710 | if (!host) | 708 | if (!host) |
@@ -713,7 +711,7 @@ static int hisi_nfc_probe(struct platform_device *pdev) | |||
713 | 711 | ||
714 | platform_set_drvdata(pdev, host); | 712 | platform_set_drvdata(pdev, host); |
715 | chip = &host->chip; | 713 | chip = &host->chip; |
716 | mtd = &host->mtd; | 714 | mtd = nand_to_mtd(chip); |
717 | 715 | ||
718 | irq = platform_get_irq(pdev, 0); | 716 | irq = platform_get_irq(pdev, 0); |
719 | if (irq < 0) { | 717 | if (irq < 0) { |
@@ -737,11 +735,11 @@ static int hisi_nfc_probe(struct platform_device *pdev) | |||
737 | goto err_res; | 735 | goto err_res; |
738 | } | 736 | } |
739 | 737 | ||
740 | mtd->priv = chip; | ||
741 | mtd->name = "hisi_nand"; | 738 | mtd->name = "hisi_nand"; |
742 | mtd->dev.parent = &pdev->dev; | 739 | mtd->dev.parent = &pdev->dev; |
743 | 740 | ||
744 | chip->priv = host; | 741 | nand_set_controller_data(chip, host); |
742 | nand_set_flash_node(chip, np); | ||
745 | chip->cmdfunc = hisi_nfc_cmdfunc; | 743 | chip->cmdfunc = hisi_nfc_cmdfunc; |
746 | chip->select_chip = hisi_nfc_select_chip; | 744 | chip->select_chip = hisi_nfc_select_chip; |
747 | chip->read_byte = hisi_nfc_read_byte; | 745 | chip->read_byte = hisi_nfc_read_byte; |
@@ -805,8 +803,7 @@ static int hisi_nfc_probe(struct platform_device *pdev) | |||
805 | goto err_res; | 803 | goto err_res; |
806 | } | 804 | } |
807 | 805 | ||
808 | ppdata.of_node = np; | 806 | ret = mtd_device_register(mtd, NULL, 0); |
809 | ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); | ||
810 | if (ret) { | 807 | if (ret) { |
811 | dev_err(dev, "Err MTD partition=%d\n", ret); | 808 | dev_err(dev, "Err MTD partition=%d\n", ret); |
812 | goto err_mtd; | 809 | goto err_mtd; |
@@ -823,7 +820,7 @@ err_res: | |||
823 | static int hisi_nfc_remove(struct platform_device *pdev) | 820 | static int hisi_nfc_remove(struct platform_device *pdev) |
824 | { | 821 | { |
825 | struct hinfc_host *host = platform_get_drvdata(pdev); | 822 | struct hinfc_host *host = platform_get_drvdata(pdev); |
826 | struct mtd_info *mtd = &host->mtd; | 823 | struct mtd_info *mtd = nand_to_mtd(&host->chip); |
827 | 824 | ||
828 | nand_release(mtd); | 825 | nand_release(mtd); |
829 | 826 | ||
diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c index 5a99a93ed025..b19d2a9a5eb9 100644 --- a/drivers/mtd/nand/jz4740_nand.c +++ b/drivers/mtd/nand/jz4740_nand.c | |||
@@ -59,7 +59,6 @@ | |||
59 | #define JZ_NAND_MEM_ADDR_OFFSET 0x10000 | 59 | #define JZ_NAND_MEM_ADDR_OFFSET 0x10000 |
60 | 60 | ||
61 | struct jz_nand { | 61 | struct jz_nand { |
62 | struct mtd_info mtd; | ||
63 | struct nand_chip chip; | 62 | struct nand_chip chip; |
64 | void __iomem *base; | 63 | void __iomem *base; |
65 | struct resource *mem; | 64 | struct resource *mem; |
@@ -76,13 +75,13 @@ struct jz_nand { | |||
76 | 75 | ||
77 | static inline struct jz_nand *mtd_to_jz_nand(struct mtd_info *mtd) | 76 | static inline struct jz_nand *mtd_to_jz_nand(struct mtd_info *mtd) |
78 | { | 77 | { |
79 | return container_of(mtd, struct jz_nand, mtd); | 78 | return container_of(mtd_to_nand(mtd), struct jz_nand, chip); |
80 | } | 79 | } |
81 | 80 | ||
82 | static void jz_nand_select_chip(struct mtd_info *mtd, int chipnr) | 81 | static void jz_nand_select_chip(struct mtd_info *mtd, int chipnr) |
83 | { | 82 | { |
84 | struct jz_nand *nand = mtd_to_jz_nand(mtd); | 83 | struct jz_nand *nand = mtd_to_jz_nand(mtd); |
85 | struct nand_chip *chip = mtd->priv; | 84 | struct nand_chip *chip = mtd_to_nand(mtd); |
86 | uint32_t ctrl; | 85 | uint32_t ctrl; |
87 | int banknr; | 86 | int banknr; |
88 | 87 | ||
@@ -104,7 +103,7 @@ static void jz_nand_select_chip(struct mtd_info *mtd, int chipnr) | |||
104 | static void jz_nand_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl) | 103 | static void jz_nand_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl) |
105 | { | 104 | { |
106 | struct jz_nand *nand = mtd_to_jz_nand(mtd); | 105 | struct jz_nand *nand = mtd_to_jz_nand(mtd); |
107 | struct nand_chip *chip = mtd->priv; | 106 | struct nand_chip *chip = mtd_to_nand(mtd); |
108 | uint32_t reg; | 107 | uint32_t reg; |
109 | void __iomem *bank_base = nand->bank_base[nand->selected_bank]; | 108 | void __iomem *bank_base = nand->bank_base[nand->selected_bank]; |
110 | 109 | ||
@@ -225,24 +224,6 @@ static int jz_nand_correct_ecc_rs(struct mtd_info *mtd, uint8_t *dat, | |||
225 | uint32_t t; | 224 | uint32_t t; |
226 | unsigned int timeout = 1000; | 225 | unsigned int timeout = 1000; |
227 | 226 | ||
228 | t = read_ecc[0]; | ||
229 | |||
230 | if (t == 0xff) { | ||
231 | for (i = 1; i < 9; ++i) | ||
232 | t &= read_ecc[i]; | ||
233 | |||
234 | t &= dat[0]; | ||
235 | t &= dat[nand->chip.ecc.size / 2]; | ||
236 | t &= dat[nand->chip.ecc.size - 1]; | ||
237 | |||
238 | if (t == 0xff) { | ||
239 | for (i = 1; i < nand->chip.ecc.size - 1; ++i) | ||
240 | t &= dat[i]; | ||
241 | if (t == 0xff) | ||
242 | return 0; | ||
243 | } | ||
244 | } | ||
245 | |||
246 | for (i = 0; i < 9; ++i) | 227 | for (i = 0; i < 9; ++i) |
247 | writeb(read_ecc[i], nand->base + JZ_REG_NAND_PAR0 + i); | 228 | writeb(read_ecc[i], nand->base + JZ_REG_NAND_PAR0 + i); |
248 | 229 | ||
@@ -255,7 +236,7 @@ static int jz_nand_correct_ecc_rs(struct mtd_info *mtd, uint8_t *dat, | |||
255 | } while (!(status & JZ_NAND_STATUS_DEC_FINISH) && --timeout); | 236 | } while (!(status & JZ_NAND_STATUS_DEC_FINISH) && --timeout); |
256 | 237 | ||
257 | if (timeout == 0) | 238 | if (timeout == 0) |
258 | return -1; | 239 | return -ETIMEDOUT; |
259 | 240 | ||
260 | reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL); | 241 | reg = readl(nand->base + JZ_REG_NAND_ECC_CTRL); |
261 | reg &= ~JZ_NAND_ECC_CTRL_ENABLE; | 242 | reg &= ~JZ_NAND_ECC_CTRL_ENABLE; |
@@ -263,7 +244,7 @@ static int jz_nand_correct_ecc_rs(struct mtd_info *mtd, uint8_t *dat, | |||
263 | 244 | ||
264 | if (status & JZ_NAND_STATUS_ERROR) { | 245 | if (status & JZ_NAND_STATUS_ERROR) { |
265 | if (status & JZ_NAND_STATUS_UNCOR_ERROR) | 246 | if (status & JZ_NAND_STATUS_UNCOR_ERROR) |
266 | return -1; | 247 | return -EBADMSG; |
267 | 248 | ||
268 | error_count = (status & JZ_NAND_STATUS_ERR_COUNT) >> 29; | 249 | error_count = (status & JZ_NAND_STATUS_ERR_COUNT) >> 29; |
269 | 250 | ||
@@ -334,8 +315,8 @@ static int jz_nand_detect_bank(struct platform_device *pdev, | |||
334 | char gpio_name[9]; | 315 | char gpio_name[9]; |
335 | char res_name[6]; | 316 | char res_name[6]; |
336 | uint32_t ctrl; | 317 | uint32_t ctrl; |
337 | struct mtd_info *mtd = &nand->mtd; | ||
338 | struct nand_chip *chip = &nand->chip; | 318 | struct nand_chip *chip = &nand->chip; |
319 | struct mtd_info *mtd = nand_to_mtd(chip); | ||
339 | 320 | ||
340 | /* Request GPIO port. */ | 321 | /* Request GPIO port. */ |
341 | gpio = JZ_GPIO_MEM_CS0 + bank - 1; | 322 | gpio = JZ_GPIO_MEM_CS0 + bank - 1; |
@@ -432,9 +413,8 @@ static int jz_nand_probe(struct platform_device *pdev) | |||
432 | goto err_iounmap_mmio; | 413 | goto err_iounmap_mmio; |
433 | } | 414 | } |
434 | 415 | ||
435 | mtd = &nand->mtd; | ||
436 | chip = &nand->chip; | 416 | chip = &nand->chip; |
437 | mtd->priv = chip; | 417 | mtd = nand_to_mtd(chip); |
438 | mtd->dev.parent = &pdev->dev; | 418 | mtd->dev.parent = &pdev->dev; |
439 | mtd->name = "jz4740-nand"; | 419 | mtd->name = "jz4740-nand"; |
440 | 420 | ||
@@ -445,6 +425,7 @@ static int jz_nand_probe(struct platform_device *pdev) | |||
445 | chip->ecc.size = 512; | 425 | chip->ecc.size = 512; |
446 | chip->ecc.bytes = 9; | 426 | chip->ecc.bytes = 9; |
447 | chip->ecc.strength = 4; | 427 | chip->ecc.strength = 4; |
428 | chip->ecc.options = NAND_ECC_GENERIC_ERASED_CHECK; | ||
448 | 429 | ||
449 | if (pdata) | 430 | if (pdata) |
450 | chip->ecc.layout = pdata->ecc_layout; | 431 | chip->ecc.layout = pdata->ecc_layout; |
@@ -543,7 +524,7 @@ static int jz_nand_remove(struct platform_device *pdev) | |||
543 | struct jz_nand *nand = platform_get_drvdata(pdev); | 524 | struct jz_nand *nand = platform_get_drvdata(pdev); |
544 | size_t i; | 525 | size_t i; |
545 | 526 | ||
546 | nand_release(&nand->mtd); | 527 | nand_release(nand_to_mtd(&nand->chip)); |
547 | 528 | ||
548 | /* Deassert and disable all chips */ | 529 | /* Deassert and disable all chips */ |
549 | writel(0, nand->base + JZ_REG_NAND_CTRL); | 530 | writel(0, nand->base + JZ_REG_NAND_CTRL); |
diff --git a/drivers/mtd/nand/jz4780_bch.c b/drivers/mtd/nand/jz4780_bch.c new file mode 100644 index 000000000000..755499c6650e --- /dev/null +++ b/drivers/mtd/nand/jz4780_bch.c | |||
@@ -0,0 +1,381 @@ | |||
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 | #include <linux/bitops.h> | ||
13 | #include <linux/clk.h> | ||
14 | #include <linux/delay.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/iopoll.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/mutex.h> | ||
19 | #include <linux/of.h> | ||
20 | #include <linux/of_platform.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/sched.h> | ||
23 | #include <linux/slab.h> | ||
24 | |||
25 | #include "jz4780_bch.h" | ||
26 | |||
27 | #define BCH_BHCR 0x0 | ||
28 | #define BCH_BHCCR 0x8 | ||
29 | #define BCH_BHCNT 0xc | ||
30 | #define BCH_BHDR 0x10 | ||
31 | #define BCH_BHPAR0 0x14 | ||
32 | #define BCH_BHERR0 0x84 | ||
33 | #define BCH_BHINT 0x184 | ||
34 | #define BCH_BHINTES 0x188 | ||
35 | #define BCH_BHINTEC 0x18c | ||
36 | #define BCH_BHINTE 0x190 | ||
37 | |||
38 | #define BCH_BHCR_BSEL_SHIFT 4 | ||
39 | #define BCH_BHCR_BSEL_MASK (0x7f << BCH_BHCR_BSEL_SHIFT) | ||
40 | #define BCH_BHCR_ENCE BIT(2) | ||
41 | #define BCH_BHCR_INIT BIT(1) | ||
42 | #define BCH_BHCR_BCHE BIT(0) | ||
43 | |||
44 | #define BCH_BHCNT_PARITYSIZE_SHIFT 16 | ||
45 | #define BCH_BHCNT_PARITYSIZE_MASK (0x7f << BCH_BHCNT_PARITYSIZE_SHIFT) | ||
46 | #define BCH_BHCNT_BLOCKSIZE_SHIFT 0 | ||
47 | #define BCH_BHCNT_BLOCKSIZE_MASK (0x7ff << BCH_BHCNT_BLOCKSIZE_SHIFT) | ||
48 | |||
49 | #define BCH_BHERR_MASK_SHIFT 16 | ||
50 | #define BCH_BHERR_MASK_MASK (0xffff << BCH_BHERR_MASK_SHIFT) | ||
51 | #define BCH_BHERR_INDEX_SHIFT 0 | ||
52 | #define BCH_BHERR_INDEX_MASK (0x7ff << BCH_BHERR_INDEX_SHIFT) | ||
53 | |||
54 | #define BCH_BHINT_ERRC_SHIFT 24 | ||
55 | #define BCH_BHINT_ERRC_MASK (0x7f << BCH_BHINT_ERRC_SHIFT) | ||
56 | #define BCH_BHINT_TERRC_SHIFT 16 | ||
57 | #define BCH_BHINT_TERRC_MASK (0x7f << BCH_BHINT_TERRC_SHIFT) | ||
58 | #define BCH_BHINT_DECF BIT(3) | ||
59 | #define BCH_BHINT_ENCF BIT(2) | ||
60 | #define BCH_BHINT_UNCOR BIT(1) | ||
61 | #define BCH_BHINT_ERR BIT(0) | ||
62 | |||
63 | #define BCH_CLK_RATE (200 * 1000 * 1000) | ||
64 | |||
65 | /* Timeout for BCH calculation/correction. */ | ||
66 | #define BCH_TIMEOUT_US 100000 | ||
67 | |||
68 | struct jz4780_bch { | ||
69 | struct device *dev; | ||
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 | { | ||
78 | u32 reg; | ||
79 | |||
80 | /* Clear interrupt status. */ | ||
81 | writel(readl(bch->base + BCH_BHINT), bch->base + BCH_BHINT); | ||
82 | |||
83 | /* Set up BCH count register. */ | ||
84 | reg = params->size << BCH_BHCNT_BLOCKSIZE_SHIFT; | ||
85 | reg |= params->bytes << BCH_BHCNT_PARITYSIZE_SHIFT; | ||
86 | writel(reg, bch->base + BCH_BHCNT); | ||
87 | |||
88 | /* Initialise and enable BCH. */ | ||
89 | reg = BCH_BHCR_BCHE | BCH_BHCR_INIT; | ||
90 | reg |= params->strength << BCH_BHCR_BSEL_SHIFT; | ||
91 | if (encode) | ||
92 | reg |= BCH_BHCR_ENCE; | ||
93 | writel(reg, bch->base + BCH_BHCR); | ||
94 | } | ||
95 | |||
96 | static void jz4780_bch_disable(struct jz4780_bch *bch) | ||
97 | { | ||
98 | writel(readl(bch->base + BCH_BHINT), bch->base + BCH_BHINT); | ||
99 | writel(BCH_BHCR_BCHE, bch->base + BCH_BHCCR); | ||
100 | } | ||
101 | |||
102 | static void jz4780_bch_write_data(struct jz4780_bch *bch, const void *buf, | ||
103 | size_t size) | ||
104 | { | ||
105 | size_t size32 = size / sizeof(u32); | ||
106 | size_t size8 = size % sizeof(u32); | ||
107 | const u32 *src32; | ||
108 | const u8 *src8; | ||
109 | |||
110 | src32 = (const u32 *)buf; | ||
111 | while (size32--) | ||
112 | writel(*src32++, bch->base + BCH_BHDR); | ||
113 | |||
114 | src8 = (const u8 *)src32; | ||
115 | while (size8--) | ||
116 | writeb(*src8++, bch->base + BCH_BHDR); | ||
117 | } | ||
118 | |||
119 | static void jz4780_bch_read_parity(struct jz4780_bch *bch, void *buf, | ||
120 | size_t size) | ||
121 | { | ||
122 | size_t size32 = size / sizeof(u32); | ||
123 | size_t size8 = size % sizeof(u32); | ||
124 | u32 *dest32; | ||
125 | u8 *dest8; | ||
126 | u32 val, offset = 0; | ||
127 | |||
128 | dest32 = (u32 *)buf; | ||
129 | while (size32--) { | ||
130 | *dest32++ = readl(bch->base + BCH_BHPAR0 + offset); | ||
131 | offset += sizeof(u32); | ||
132 | } | ||
133 | |||
134 | dest8 = (u8 *)dest32; | ||
135 | val = readl(bch->base + BCH_BHPAR0 + offset); | ||
136 | switch (size8) { | ||
137 | case 3: | ||
138 | dest8[2] = (val >> 16) & 0xff; | ||
139 | case 2: | ||
140 | dest8[1] = (val >> 8) & 0xff; | ||
141 | case 1: | ||
142 | dest8[0] = val & 0xff; | ||
143 | break; | ||
144 | } | ||
145 | } | ||
146 | |||
147 | static bool jz4780_bch_wait_complete(struct jz4780_bch *bch, unsigned int irq, | ||
148 | u32 *status) | ||
149 | { | ||
150 | u32 reg; | ||
151 | int ret; | ||
152 | |||
153 | /* | ||
154 | * While we could use interrupts here and sleep until the operation | ||
155 | * completes, the controller works fairly quickly (usually a few | ||
156 | * microseconds) and so the overhead of sleeping until we get an | ||
157 | * interrupt quite noticeably decreases performance. | ||
158 | */ | ||
159 | ret = readl_poll_timeout(bch->base + BCH_BHINT, reg, | ||
160 | (reg & irq) == irq, 0, BCH_TIMEOUT_US); | ||
161 | if (ret) | ||
162 | return false; | ||
163 | |||
164 | if (status) | ||
165 | *status = reg; | ||
166 | |||
167 | writel(reg, bch->base + BCH_BHINT); | ||
168 | return true; | ||
169 | } | ||
170 | |||
171 | /** | ||
172 | * jz4780_bch_calculate() - calculate ECC for a data buffer | ||
173 | * @bch: BCH device. | ||
174 | * @params: BCH parameters. | ||
175 | * @buf: input buffer with raw data. | ||
176 | * @ecc_code: output buffer with ECC. | ||
177 | * | ||
178 | * Return: 0 on success, -ETIMEDOUT if timed out while waiting for BCH | ||
179 | * controller. | ||
180 | */ | ||
181 | int jz4780_bch_calculate(struct jz4780_bch *bch, struct jz4780_bch_params *params, | ||
182 | const u8 *buf, u8 *ecc_code) | ||
183 | { | ||
184 | int ret = 0; | ||
185 | |||
186 | mutex_lock(&bch->lock); | ||
187 | jz4780_bch_init(bch, params, true); | ||
188 | jz4780_bch_write_data(bch, buf, params->size); | ||
189 | |||
190 | if (jz4780_bch_wait_complete(bch, BCH_BHINT_ENCF, NULL)) { | ||
191 | jz4780_bch_read_parity(bch, ecc_code, params->bytes); | ||
192 | } else { | ||
193 | dev_err(bch->dev, "timed out while calculating ECC\n"); | ||
194 | ret = -ETIMEDOUT; | ||
195 | } | ||
196 | |||
197 | jz4780_bch_disable(bch); | ||
198 | mutex_unlock(&bch->lock); | ||
199 | return ret; | ||
200 | } | ||
201 | EXPORT_SYMBOL(jz4780_bch_calculate); | ||
202 | |||
203 | /** | ||
204 | * jz4780_bch_correct() - detect and correct bit errors | ||
205 | * @bch: BCH device. | ||
206 | * @params: BCH parameters. | ||
207 | * @buf: raw data read from the chip. | ||
208 | * @ecc_code: ECC read from the chip. | ||
209 | * | ||
210 | * Given the raw data and the ECC read from the NAND device, detects and | ||
211 | * corrects errors in the data. | ||
212 | * | ||
213 | * Return: the number of bit errors corrected, -EBADMSG if there are too many | ||
214 | * errors to correct or -ETIMEDOUT if we timed out waiting for the controller. | ||
215 | */ | ||
216 | int jz4780_bch_correct(struct jz4780_bch *bch, struct jz4780_bch_params *params, | ||
217 | u8 *buf, u8 *ecc_code) | ||
218 | { | ||
219 | u32 reg, mask, index; | ||
220 | int i, ret, count; | ||
221 | |||
222 | mutex_lock(&bch->lock); | ||
223 | |||
224 | jz4780_bch_init(bch, params, false); | ||
225 | jz4780_bch_write_data(bch, buf, params->size); | ||
226 | jz4780_bch_write_data(bch, ecc_code, params->bytes); | ||
227 | |||
228 | if (!jz4780_bch_wait_complete(bch, BCH_BHINT_DECF, ®)) { | ||
229 | dev_err(bch->dev, "timed out while correcting data\n"); | ||
230 | ret = -ETIMEDOUT; | ||
231 | goto out; | ||
232 | } | ||
233 | |||
234 | if (reg & BCH_BHINT_UNCOR) { | ||
235 | dev_warn(bch->dev, "uncorrectable ECC error\n"); | ||
236 | ret = -EBADMSG; | ||
237 | goto out; | ||
238 | } | ||
239 | |||
240 | /* Correct any detected errors. */ | ||
241 | if (reg & BCH_BHINT_ERR) { | ||
242 | count = (reg & BCH_BHINT_ERRC_MASK) >> BCH_BHINT_ERRC_SHIFT; | ||
243 | ret = (reg & BCH_BHINT_TERRC_MASK) >> BCH_BHINT_TERRC_SHIFT; | ||
244 | |||
245 | for (i = 0; i < count; i++) { | ||
246 | reg = readl(bch->base + BCH_BHERR0 + (i * 4)); | ||
247 | mask = (reg & BCH_BHERR_MASK_MASK) >> | ||
248 | BCH_BHERR_MASK_SHIFT; | ||
249 | index = (reg & BCH_BHERR_INDEX_MASK) >> | ||
250 | BCH_BHERR_INDEX_SHIFT; | ||
251 | buf[(index * 2) + 0] ^= mask; | ||
252 | buf[(index * 2) + 1] ^= mask >> 8; | ||
253 | } | ||
254 | } else { | ||
255 | ret = 0; | ||
256 | } | ||
257 | |||
258 | out: | ||
259 | jz4780_bch_disable(bch); | ||
260 | mutex_unlock(&bch->lock); | ||
261 | return ret; | ||
262 | } | ||
263 | EXPORT_SYMBOL(jz4780_bch_correct); | ||
264 | |||
265 | /** | ||
266 | * jz4780_bch_get() - get the BCH controller device | ||
267 | * @np: BCH device tree node. | ||
268 | * | ||
269 | * Gets the BCH controller device from the specified device tree node. The | ||
270 | * device must be released with jz4780_bch_release() when it is no longer being | ||
271 | * used. | ||
272 | * | ||
273 | * Return: a pointer to jz4780_bch, errors are encoded into the pointer. | ||
274 | * PTR_ERR(-EPROBE_DEFER) if the device hasn't been initialised yet. | ||
275 | */ | ||
276 | static struct jz4780_bch *jz4780_bch_get(struct device_node *np) | ||
277 | { | ||
278 | struct platform_device *pdev; | ||
279 | struct jz4780_bch *bch; | ||
280 | |||
281 | pdev = of_find_device_by_node(np); | ||
282 | if (!pdev || !platform_get_drvdata(pdev)) | ||
283 | return ERR_PTR(-EPROBE_DEFER); | ||
284 | |||
285 | get_device(&pdev->dev); | ||
286 | |||
287 | bch = platform_get_drvdata(pdev); | ||
288 | clk_prepare_enable(bch->clk); | ||
289 | |||
290 | bch->dev = &pdev->dev; | ||
291 | return bch; | ||
292 | } | ||
293 | |||
294 | /** | ||
295 | * of_jz4780_bch_get() - get the BCH controller from a DT node | ||
296 | * @of_node: the node that contains a bch-controller property. | ||
297 | * | ||
298 | * Get the bch-controller property from the given device tree | ||
299 | * node and pass it to jz4780_bch_get to do the work. | ||
300 | * | ||
301 | * Return: a pointer to jz4780_bch, errors are encoded into the pointer. | ||
302 | * PTR_ERR(-EPROBE_DEFER) if the device hasn't been initialised yet. | ||
303 | */ | ||
304 | struct jz4780_bch *of_jz4780_bch_get(struct device_node *of_node) | ||
305 | { | ||
306 | struct jz4780_bch *bch = NULL; | ||
307 | struct device_node *np; | ||
308 | |||
309 | np = of_parse_phandle(of_node, "ingenic,bch-controller", 0); | ||
310 | |||
311 | if (np) { | ||
312 | bch = jz4780_bch_get(np); | ||
313 | of_node_put(np); | ||
314 | } | ||
315 | return bch; | ||
316 | } | ||
317 | EXPORT_SYMBOL(of_jz4780_bch_get); | ||
318 | |||
319 | /** | ||
320 | * jz4780_bch_release() - release the BCH controller device | ||
321 | * @bch: BCH device. | ||
322 | */ | ||
323 | void jz4780_bch_release(struct jz4780_bch *bch) | ||
324 | { | ||
325 | clk_disable_unprepare(bch->clk); | ||
326 | put_device(bch->dev); | ||
327 | } | ||
328 | EXPORT_SYMBOL(jz4780_bch_release); | ||
329 | |||
330 | static int jz4780_bch_probe(struct platform_device *pdev) | ||
331 | { | ||
332 | struct device *dev = &pdev->dev; | ||
333 | struct jz4780_bch *bch; | ||
334 | struct resource *res; | ||
335 | |||
336 | bch = devm_kzalloc(dev, sizeof(*bch), GFP_KERNEL); | ||
337 | if (!bch) | ||
338 | return -ENOMEM; | ||
339 | |||
340 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
341 | bch->base = devm_ioremap_resource(dev, res); | ||
342 | if (IS_ERR(bch->base)) | ||
343 | return PTR_ERR(bch->base); | ||
344 | |||
345 | jz4780_bch_disable(bch); | ||
346 | |||
347 | bch->clk = devm_clk_get(dev, NULL); | ||
348 | if (IS_ERR(bch->clk)) { | ||
349 | dev_err(dev, "failed to get clock: %ld\n", PTR_ERR(bch->clk)); | ||
350 | return PTR_ERR(bch->clk); | ||
351 | } | ||
352 | |||
353 | clk_set_rate(bch->clk, BCH_CLK_RATE); | ||
354 | |||
355 | mutex_init(&bch->lock); | ||
356 | |||
357 | bch->dev = dev; | ||
358 | platform_set_drvdata(pdev, bch); | ||
359 | |||
360 | return 0; | ||
361 | } | ||
362 | |||
363 | static const struct of_device_id jz4780_bch_dt_match[] = { | ||
364 | { .compatible = "ingenic,jz4780-bch" }, | ||
365 | {}, | ||
366 | }; | ||
367 | MODULE_DEVICE_TABLE(of, jz4780_bch_dt_match); | ||
368 | |||
369 | static struct platform_driver jz4780_bch_driver = { | ||
370 | .probe = jz4780_bch_probe, | ||
371 | .driver = { | ||
372 | .name = "jz4780-bch", | ||
373 | .of_match_table = of_match_ptr(jz4780_bch_dt_match), | ||
374 | }, | ||
375 | }; | ||
376 | module_platform_driver(jz4780_bch_driver); | ||
377 | |||
378 | MODULE_AUTHOR("Alex Smith <alex@alex-smith.me.uk>"); | ||
379 | MODULE_AUTHOR("Harvey Hunt <harvey.hunt@imgtec.com>"); | ||
380 | MODULE_DESCRIPTION("Ingenic JZ4780 BCH error correction driver"); | ||
381 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mtd/nand/jz4780_bch.h b/drivers/mtd/nand/jz4780_bch.h new file mode 100644 index 000000000000..bf4718088a3a --- /dev/null +++ b/drivers/mtd/nand/jz4780_bch.h | |||
@@ -0,0 +1,43 @@ | |||
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/jz4780_nand.c b/drivers/mtd/nand/jz4780_nand.c new file mode 100644 index 000000000000..e1c016c9d32d --- /dev/null +++ b/drivers/mtd/nand/jz4780_nand.c | |||
@@ -0,0 +1,428 @@ | |||
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/of_mtd.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/mtd/mtd.h> | ||
24 | #include <linux/mtd/nand.h> | ||
25 | #include <linux/mtd/partitions.h> | ||
26 | |||
27 | #include <linux/jz4780-nemc.h> | ||
28 | |||
29 | #include "jz4780_bch.h" | ||
30 | |||
31 | #define DRV_NAME "jz4780-nand" | ||
32 | |||
33 | #define OFFSET_DATA 0x00000000 | ||
34 | #define OFFSET_CMD 0x00400000 | ||
35 | #define OFFSET_ADDR 0x00800000 | ||
36 | |||
37 | /* Command delay when there is no R/B pin. */ | ||
38 | #define RB_DELAY_US 100 | ||
39 | |||
40 | struct jz4780_nand_cs { | ||
41 | unsigned int bank; | ||
42 | void __iomem *base; | ||
43 | }; | ||
44 | |||
45 | struct jz4780_nand_controller { | ||
46 | struct device *dev; | ||
47 | struct jz4780_bch *bch; | ||
48 | struct nand_hw_control controller; | ||
49 | unsigned int num_banks; | ||
50 | struct list_head chips; | ||
51 | int selected; | ||
52 | struct jz4780_nand_cs cs[]; | ||
53 | }; | ||
54 | |||
55 | struct jz4780_nand_chip { | ||
56 | struct nand_chip chip; | ||
57 | struct list_head chip_list; | ||
58 | |||
59 | struct nand_ecclayout ecclayout; | ||
60 | |||
61 | struct gpio_desc *busy_gpio; | ||
62 | struct gpio_desc *wp_gpio; | ||
63 | unsigned int reading: 1; | ||
64 | }; | ||
65 | |||
66 | static inline struct jz4780_nand_chip *to_jz4780_nand_chip(struct mtd_info *mtd) | ||
67 | { | ||
68 | return container_of(mtd_to_nand(mtd), struct jz4780_nand_chip, chip); | ||
69 | } | ||
70 | |||
71 | static inline struct jz4780_nand_controller *to_jz4780_nand_controller(struct nand_hw_control *ctrl) | ||
72 | { | ||
73 | return container_of(ctrl, struct jz4780_nand_controller, controller); | ||
74 | } | ||
75 | |||
76 | static void jz4780_nand_select_chip(struct mtd_info *mtd, int chipnr) | ||
77 | { | ||
78 | struct jz4780_nand_chip *nand = to_jz4780_nand_chip(mtd); | ||
79 | struct jz4780_nand_controller *nfc = to_jz4780_nand_controller(nand->chip.controller); | ||
80 | struct jz4780_nand_cs *cs; | ||
81 | |||
82 | /* Ensure the currently selected chip is deasserted. */ | ||
83 | if (chipnr == -1 && nfc->selected >= 0) { | ||
84 | cs = &nfc->cs[nfc->selected]; | ||
85 | jz4780_nemc_assert(nfc->dev, cs->bank, false); | ||
86 | } | ||
87 | |||
88 | nfc->selected = chipnr; | ||
89 | } | ||
90 | |||
91 | static void jz4780_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, | ||
92 | unsigned int ctrl) | ||
93 | { | ||
94 | struct jz4780_nand_chip *nand = to_jz4780_nand_chip(mtd); | ||
95 | struct jz4780_nand_controller *nfc = to_jz4780_nand_controller(nand->chip.controller); | ||
96 | struct jz4780_nand_cs *cs; | ||
97 | |||
98 | if (WARN_ON(nfc->selected < 0)) | ||
99 | return; | ||
100 | |||
101 | cs = &nfc->cs[nfc->selected]; | ||
102 | |||
103 | jz4780_nemc_assert(nfc->dev, cs->bank, ctrl & NAND_NCE); | ||
104 | |||
105 | if (cmd == NAND_CMD_NONE) | ||
106 | return; | ||
107 | |||
108 | if (ctrl & NAND_ALE) | ||
109 | writeb(cmd, cs->base + OFFSET_ADDR); | ||
110 | else if (ctrl & NAND_CLE) | ||
111 | writeb(cmd, cs->base + OFFSET_CMD); | ||
112 | } | ||
113 | |||
114 | static int jz4780_nand_dev_ready(struct mtd_info *mtd) | ||
115 | { | ||
116 | struct jz4780_nand_chip *nand = to_jz4780_nand_chip(mtd); | ||
117 | |||
118 | return !gpiod_get_value_cansleep(nand->busy_gpio); | ||
119 | } | ||
120 | |||
121 | static void jz4780_nand_ecc_hwctl(struct mtd_info *mtd, int mode) | ||
122 | { | ||
123 | struct jz4780_nand_chip *nand = to_jz4780_nand_chip(mtd); | ||
124 | |||
125 | nand->reading = (mode == NAND_ECC_READ); | ||
126 | } | ||
127 | |||
128 | static int jz4780_nand_ecc_calculate(struct mtd_info *mtd, const u8 *dat, | ||
129 | u8 *ecc_code) | ||
130 | { | ||
131 | struct jz4780_nand_chip *nand = to_jz4780_nand_chip(mtd); | ||
132 | struct jz4780_nand_controller *nfc = to_jz4780_nand_controller(nand->chip.controller); | ||
133 | struct jz4780_bch_params params; | ||
134 | |||
135 | /* | ||
136 | * Don't need to generate the ECC when reading, BCH does it for us as | ||
137 | * part of decoding/correction. | ||
138 | */ | ||
139 | if (nand->reading) | ||
140 | return 0; | ||
141 | |||
142 | params.size = nand->chip.ecc.size; | ||
143 | params.bytes = nand->chip.ecc.bytes; | ||
144 | params.strength = nand->chip.ecc.strength; | ||
145 | |||
146 | return jz4780_bch_calculate(nfc->bch, ¶ms, dat, ecc_code); | ||
147 | } | ||
148 | |||
149 | static int jz4780_nand_ecc_correct(struct mtd_info *mtd, u8 *dat, | ||
150 | u8 *read_ecc, u8 *calc_ecc) | ||
151 | { | ||
152 | struct jz4780_nand_chip *nand = to_jz4780_nand_chip(mtd); | ||
153 | struct jz4780_nand_controller *nfc = to_jz4780_nand_controller(nand->chip.controller); | ||
154 | struct jz4780_bch_params params; | ||
155 | |||
156 | params.size = nand->chip.ecc.size; | ||
157 | params.bytes = nand->chip.ecc.bytes; | ||
158 | params.strength = nand->chip.ecc.strength; | ||
159 | |||
160 | return jz4780_bch_correct(nfc->bch, ¶ms, dat, read_ecc); | ||
161 | } | ||
162 | |||
163 | static int jz4780_nand_init_ecc(struct jz4780_nand_chip *nand, struct device *dev) | ||
164 | { | ||
165 | struct nand_chip *chip = &nand->chip; | ||
166 | struct mtd_info *mtd = nand_to_mtd(chip); | ||
167 | struct jz4780_nand_controller *nfc = to_jz4780_nand_controller(chip->controller); | ||
168 | struct nand_ecclayout *layout = &nand->ecclayout; | ||
169 | u32 start, i; | ||
170 | |||
171 | chip->ecc.bytes = fls((1 + 8) * chip->ecc.size) * | ||
172 | (chip->ecc.strength / 8); | ||
173 | |||
174 | switch (chip->ecc.mode) { | ||
175 | case NAND_ECC_HW: | ||
176 | if (!nfc->bch) { | ||
177 | dev_err(dev, "HW BCH selected, but BCH controller not found\n"); | ||
178 | return -ENODEV; | ||
179 | } | ||
180 | |||
181 | chip->ecc.hwctl = jz4780_nand_ecc_hwctl; | ||
182 | chip->ecc.calculate = jz4780_nand_ecc_calculate; | ||
183 | chip->ecc.correct = jz4780_nand_ecc_correct; | ||
184 | /* fall through */ | ||
185 | case NAND_ECC_SOFT: | ||
186 | case NAND_ECC_SOFT_BCH: | ||
187 | dev_info(dev, "using %s (strength %d, size %d, bytes %d)\n", | ||
188 | (nfc->bch) ? "hardware BCH" : "software ECC", | ||
189 | chip->ecc.strength, chip->ecc.size, chip->ecc.bytes); | ||
190 | break; | ||
191 | case NAND_ECC_NONE: | ||
192 | dev_info(dev, "not using ECC\n"); | ||
193 | break; | ||
194 | default: | ||
195 | dev_err(dev, "ECC mode %d not supported\n", chip->ecc.mode); | ||
196 | return -EINVAL; | ||
197 | } | ||
198 | |||
199 | /* The NAND core will generate the ECC layout for SW ECC */ | ||
200 | if (chip->ecc.mode != NAND_ECC_HW) | ||
201 | return 0; | ||
202 | |||
203 | /* Generate ECC layout. ECC codes are right aligned in the OOB area. */ | ||
204 | layout->eccbytes = mtd->writesize / chip->ecc.size * chip->ecc.bytes; | ||
205 | |||
206 | if (layout->eccbytes > mtd->oobsize - 2) { | ||
207 | dev_err(dev, | ||
208 | "invalid ECC config: required %d ECC bytes, but only %d are available", | ||
209 | layout->eccbytes, mtd->oobsize - 2); | ||
210 | return -EINVAL; | ||
211 | } | ||
212 | |||
213 | start = mtd->oobsize - layout->eccbytes; | ||
214 | for (i = 0; i < layout->eccbytes; i++) | ||
215 | layout->eccpos[i] = start + i; | ||
216 | |||
217 | layout->oobfree[0].offset = 2; | ||
218 | layout->oobfree[0].length = mtd->oobsize - layout->eccbytes - 2; | ||
219 | |||
220 | chip->ecc.layout = layout; | ||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | static int jz4780_nand_init_chip(struct platform_device *pdev, | ||
225 | struct jz4780_nand_controller *nfc, | ||
226 | struct device_node *np, | ||
227 | unsigned int chipnr) | ||
228 | { | ||
229 | struct device *dev = &pdev->dev; | ||
230 | struct jz4780_nand_chip *nand; | ||
231 | struct jz4780_nand_cs *cs; | ||
232 | struct resource *res; | ||
233 | struct nand_chip *chip; | ||
234 | struct mtd_info *mtd; | ||
235 | const __be32 *reg; | ||
236 | int ret = 0; | ||
237 | |||
238 | cs = &nfc->cs[chipnr]; | ||
239 | |||
240 | reg = of_get_property(np, "reg", NULL); | ||
241 | if (!reg) | ||
242 | return -EINVAL; | ||
243 | |||
244 | cs->bank = be32_to_cpu(*reg); | ||
245 | |||
246 | jz4780_nemc_set_type(nfc->dev, cs->bank, JZ4780_NEMC_BANK_NAND); | ||
247 | |||
248 | res = platform_get_resource(pdev, IORESOURCE_MEM, chipnr); | ||
249 | cs->base = devm_ioremap_resource(dev, res); | ||
250 | if (IS_ERR(cs->base)) | ||
251 | return PTR_ERR(cs->base); | ||
252 | |||
253 | nand = devm_kzalloc(dev, sizeof(*nand), GFP_KERNEL); | ||
254 | if (!nand) | ||
255 | return -ENOMEM; | ||
256 | |||
257 | nand->busy_gpio = devm_gpiod_get_optional(dev, "rb", GPIOD_IN); | ||
258 | |||
259 | if (IS_ERR(nand->busy_gpio)) { | ||
260 | ret = PTR_ERR(nand->busy_gpio); | ||
261 | dev_err(dev, "failed to request busy GPIO: %d\n", ret); | ||
262 | return ret; | ||
263 | } else if (nand->busy_gpio) { | ||
264 | nand->chip.dev_ready = jz4780_nand_dev_ready; | ||
265 | } | ||
266 | |||
267 | nand->wp_gpio = devm_gpiod_get_optional(dev, "wp", GPIOD_OUT_LOW); | ||
268 | |||
269 | if (IS_ERR(nand->wp_gpio)) { | ||
270 | ret = PTR_ERR(nand->wp_gpio); | ||
271 | dev_err(dev, "failed to request WP GPIO: %d\n", ret); | ||
272 | return ret; | ||
273 | } | ||
274 | |||
275 | chip = &nand->chip; | ||
276 | mtd = nand_to_mtd(chip); | ||
277 | mtd->name = devm_kasprintf(dev, GFP_KERNEL, "%s.%d", dev_name(dev), | ||
278 | cs->bank); | ||
279 | if (!mtd->name) | ||
280 | return -ENOMEM; | ||
281 | mtd->dev.parent = dev; | ||
282 | |||
283 | chip->IO_ADDR_R = cs->base + OFFSET_DATA; | ||
284 | chip->IO_ADDR_W = cs->base + OFFSET_DATA; | ||
285 | chip->chip_delay = RB_DELAY_US; | ||
286 | chip->options = NAND_NO_SUBPAGE_WRITE; | ||
287 | chip->select_chip = jz4780_nand_select_chip; | ||
288 | chip->cmd_ctrl = jz4780_nand_cmd_ctrl; | ||
289 | chip->ecc.mode = NAND_ECC_HW; | ||
290 | chip->controller = &nfc->controller; | ||
291 | nand_set_flash_node(chip, np); | ||
292 | |||
293 | ret = nand_scan_ident(mtd, 1, NULL); | ||
294 | if (ret) | ||
295 | return ret; | ||
296 | |||
297 | ret = jz4780_nand_init_ecc(nand, dev); | ||
298 | if (ret) | ||
299 | return ret; | ||
300 | |||
301 | ret = nand_scan_tail(mtd); | ||
302 | if (ret) | ||
303 | return ret; | ||
304 | |||
305 | ret = mtd_device_register(mtd, NULL, 0); | ||
306 | if (ret) { | ||
307 | nand_release(mtd); | ||
308 | return ret; | ||
309 | } | ||
310 | |||
311 | list_add_tail(&nand->chip_list, &nfc->chips); | ||
312 | |||
313 | return 0; | ||
314 | } | ||
315 | |||
316 | static void jz4780_nand_cleanup_chips(struct jz4780_nand_controller *nfc) | ||
317 | { | ||
318 | struct jz4780_nand_chip *chip; | ||
319 | |||
320 | while (!list_empty(&nfc->chips)) { | ||
321 | chip = list_first_entry(&nfc->chips, struct jz4780_nand_chip, chip_list); | ||
322 | nand_release(nand_to_mtd(&chip->chip)); | ||
323 | list_del(&chip->chip_list); | ||
324 | } | ||
325 | } | ||
326 | |||
327 | static int jz4780_nand_init_chips(struct jz4780_nand_controller *nfc, | ||
328 | struct platform_device *pdev) | ||
329 | { | ||
330 | struct device *dev = &pdev->dev; | ||
331 | struct device_node *np; | ||
332 | int i = 0; | ||
333 | int ret; | ||
334 | int num_chips = of_get_child_count(dev->of_node); | ||
335 | |||
336 | if (num_chips > nfc->num_banks) { | ||
337 | dev_err(dev, "found %d chips but only %d banks\n", num_chips, nfc->num_banks); | ||
338 | return -EINVAL; | ||
339 | } | ||
340 | |||
341 | for_each_child_of_node(dev->of_node, np) { | ||
342 | ret = jz4780_nand_init_chip(pdev, nfc, np, i); | ||
343 | if (ret) { | ||
344 | jz4780_nand_cleanup_chips(nfc); | ||
345 | return ret; | ||
346 | } | ||
347 | |||
348 | i++; | ||
349 | } | ||
350 | |||
351 | return 0; | ||
352 | } | ||
353 | |||
354 | static int jz4780_nand_probe(struct platform_device *pdev) | ||
355 | { | ||
356 | struct device *dev = &pdev->dev; | ||
357 | unsigned int num_banks; | ||
358 | struct jz4780_nand_controller *nfc; | ||
359 | int ret; | ||
360 | |||
361 | num_banks = jz4780_nemc_num_banks(dev); | ||
362 | if (num_banks == 0) { | ||
363 | dev_err(dev, "no banks found\n"); | ||
364 | return -ENODEV; | ||
365 | } | ||
366 | |||
367 | nfc = devm_kzalloc(dev, sizeof(*nfc) + (sizeof(nfc->cs[0]) * num_banks), GFP_KERNEL); | ||
368 | if (!nfc) | ||
369 | return -ENOMEM; | ||
370 | |||
371 | /* | ||
372 | * Check for BCH HW before we call nand_scan_ident, to prevent us from | ||
373 | * having to call it again if the BCH driver returns -EPROBE_DEFER. | ||
374 | */ | ||
375 | nfc->bch = of_jz4780_bch_get(dev->of_node); | ||
376 | if (IS_ERR(nfc->bch)) | ||
377 | return PTR_ERR(nfc->bch); | ||
378 | |||
379 | nfc->dev = dev; | ||
380 | nfc->num_banks = num_banks; | ||
381 | |||
382 | spin_lock_init(&nfc->controller.lock); | ||
383 | INIT_LIST_HEAD(&nfc->chips); | ||
384 | init_waitqueue_head(&nfc->controller.wq); | ||
385 | |||
386 | ret = jz4780_nand_init_chips(nfc, pdev); | ||
387 | if (ret) { | ||
388 | if (nfc->bch) | ||
389 | jz4780_bch_release(nfc->bch); | ||
390 | return ret; | ||
391 | } | ||
392 | |||
393 | platform_set_drvdata(pdev, nfc); | ||
394 | return 0; | ||
395 | } | ||
396 | |||
397 | static int jz4780_nand_remove(struct platform_device *pdev) | ||
398 | { | ||
399 | struct jz4780_nand_controller *nfc = platform_get_drvdata(pdev); | ||
400 | |||
401 | if (nfc->bch) | ||
402 | jz4780_bch_release(nfc->bch); | ||
403 | |||
404 | jz4780_nand_cleanup_chips(nfc); | ||
405 | |||
406 | return 0; | ||
407 | } | ||
408 | |||
409 | static const struct of_device_id jz4780_nand_dt_match[] = { | ||
410 | { .compatible = "ingenic,jz4780-nand" }, | ||
411 | {}, | ||
412 | }; | ||
413 | MODULE_DEVICE_TABLE(of, jz4780_nand_dt_match); | ||
414 | |||
415 | static struct platform_driver jz4780_nand_driver = { | ||
416 | .probe = jz4780_nand_probe, | ||
417 | .remove = jz4780_nand_remove, | ||
418 | .driver = { | ||
419 | .name = DRV_NAME, | ||
420 | .of_match_table = of_match_ptr(jz4780_nand_dt_match), | ||
421 | }, | ||
422 | }; | ||
423 | module_platform_driver(jz4780_nand_driver); | ||
424 | |||
425 | MODULE_AUTHOR("Alex Smith <alex@alex-smith.me.uk>"); | ||
426 | MODULE_AUTHOR("Harvey Hunt <harvey.hunt@imgtec.com>"); | ||
427 | MODULE_DESCRIPTION("Ingenic JZ4780 NAND driver"); | ||
428 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mtd/nand/lpc32xx_mlc.c b/drivers/mtd/nand/lpc32xx_mlc.c index 347510978484..9bc435d72a86 100644 --- a/drivers/mtd/nand/lpc32xx_mlc.c +++ b/drivers/mtd/nand/lpc32xx_mlc.c | |||
@@ -173,7 +173,6 @@ struct lpc32xx_nand_host { | |||
173 | struct nand_chip nand_chip; | 173 | struct nand_chip nand_chip; |
174 | struct lpc32xx_mlc_platform_data *pdata; | 174 | struct lpc32xx_mlc_platform_data *pdata; |
175 | struct clk *clk; | 175 | struct clk *clk; |
176 | struct mtd_info mtd; | ||
177 | void __iomem *io_base; | 176 | void __iomem *io_base; |
178 | int irq; | 177 | int irq; |
179 | struct lpc32xx_nand_cfg_mlc *ncfg; | 178 | struct lpc32xx_nand_cfg_mlc *ncfg; |
@@ -275,8 +274,8 @@ static void lpc32xx_nand_setup(struct lpc32xx_nand_host *host) | |||
275 | static void lpc32xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, | 274 | static void lpc32xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, |
276 | unsigned int ctrl) | 275 | unsigned int ctrl) |
277 | { | 276 | { |
278 | struct nand_chip *nand_chip = mtd->priv; | 277 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
279 | struct lpc32xx_nand_host *host = nand_chip->priv; | 278 | struct lpc32xx_nand_host *host = nand_get_controller_data(nand_chip); |
280 | 279 | ||
281 | if (cmd != NAND_CMD_NONE) { | 280 | if (cmd != NAND_CMD_NONE) { |
282 | if (ctrl & NAND_CLE) | 281 | if (ctrl & NAND_CLE) |
@@ -291,8 +290,8 @@ static void lpc32xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, | |||
291 | */ | 290 | */ |
292 | static int lpc32xx_nand_device_ready(struct mtd_info *mtd) | 291 | static int lpc32xx_nand_device_ready(struct mtd_info *mtd) |
293 | { | 292 | { |
294 | struct nand_chip *nand_chip = mtd->priv; | 293 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
295 | struct lpc32xx_nand_host *host = nand_chip->priv; | 294 | struct lpc32xx_nand_host *host = nand_get_controller_data(nand_chip); |
296 | 295 | ||
297 | if ((readb(MLC_ISR(host->io_base)) & | 296 | if ((readb(MLC_ISR(host->io_base)) & |
298 | (MLCISR_CONTROLLER_READY | MLCISR_NAND_READY)) == | 297 | (MLCISR_CONTROLLER_READY | MLCISR_NAND_READY)) == |
@@ -318,7 +317,7 @@ static irqreturn_t lpc3xxx_nand_irq(int irq, struct lpc32xx_nand_host *host) | |||
318 | 317 | ||
319 | static int lpc32xx_waitfunc_nand(struct mtd_info *mtd, struct nand_chip *chip) | 318 | static int lpc32xx_waitfunc_nand(struct mtd_info *mtd, struct nand_chip *chip) |
320 | { | 319 | { |
321 | struct lpc32xx_nand_host *host = chip->priv; | 320 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); |
322 | 321 | ||
323 | if (readb(MLC_ISR(host->io_base)) & MLCISR_NAND_READY) | 322 | if (readb(MLC_ISR(host->io_base)) & MLCISR_NAND_READY) |
324 | goto exit; | 323 | goto exit; |
@@ -338,7 +337,7 @@ exit: | |||
338 | static int lpc32xx_waitfunc_controller(struct mtd_info *mtd, | 337 | static int lpc32xx_waitfunc_controller(struct mtd_info *mtd, |
339 | struct nand_chip *chip) | 338 | struct nand_chip *chip) |
340 | { | 339 | { |
341 | struct lpc32xx_nand_host *host = chip->priv; | 340 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); |
342 | 341 | ||
343 | if (readb(MLC_ISR(host->io_base)) & MLCISR_CONTROLLER_READY) | 342 | if (readb(MLC_ISR(host->io_base)) & MLCISR_CONTROLLER_READY) |
344 | goto exit; | 343 | goto exit; |
@@ -389,8 +388,8 @@ static void lpc32xx_dma_complete_func(void *completion) | |||
389 | static int lpc32xx_xmit_dma(struct mtd_info *mtd, void *mem, int len, | 388 | static int lpc32xx_xmit_dma(struct mtd_info *mtd, void *mem, int len, |
390 | enum dma_transfer_direction dir) | 389 | enum dma_transfer_direction dir) |
391 | { | 390 | { |
392 | struct nand_chip *chip = mtd->priv; | 391 | struct nand_chip *chip = mtd_to_nand(mtd); |
393 | struct lpc32xx_nand_host *host = chip->priv; | 392 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); |
394 | struct dma_async_tx_descriptor *desc; | 393 | struct dma_async_tx_descriptor *desc; |
395 | int flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; | 394 | int flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; |
396 | int res; | 395 | int res; |
@@ -431,7 +430,7 @@ out1: | |||
431 | static int lpc32xx_read_page(struct mtd_info *mtd, struct nand_chip *chip, | 430 | static int lpc32xx_read_page(struct mtd_info *mtd, struct nand_chip *chip, |
432 | uint8_t *buf, int oob_required, int page) | 431 | uint8_t *buf, int oob_required, int page) |
433 | { | 432 | { |
434 | struct lpc32xx_nand_host *host = chip->priv; | 433 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); |
435 | int i, j; | 434 | int i, j; |
436 | uint8_t *oobbuf = chip->oob_poi; | 435 | uint8_t *oobbuf = chip->oob_poi; |
437 | uint32_t mlc_isr; | 436 | uint32_t mlc_isr; |
@@ -498,7 +497,7 @@ static int lpc32xx_write_page_lowlevel(struct mtd_info *mtd, | |||
498 | const uint8_t *buf, int oob_required, | 497 | const uint8_t *buf, int oob_required, |
499 | int page) | 498 | int page) |
500 | { | 499 | { |
501 | struct lpc32xx_nand_host *host = chip->priv; | 500 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); |
502 | const uint8_t *oobbuf = chip->oob_poi; | 501 | const uint8_t *oobbuf = chip->oob_poi; |
503 | uint8_t *dma_buf = (uint8_t *)buf; | 502 | uint8_t *dma_buf = (uint8_t *)buf; |
504 | int res; | 503 | int res; |
@@ -543,7 +542,7 @@ static int lpc32xx_write_page_lowlevel(struct mtd_info *mtd, | |||
543 | static int lpc32xx_read_oob(struct mtd_info *mtd, struct nand_chip *chip, | 542 | static int lpc32xx_read_oob(struct mtd_info *mtd, struct nand_chip *chip, |
544 | int page) | 543 | int page) |
545 | { | 544 | { |
546 | struct lpc32xx_nand_host *host = chip->priv; | 545 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); |
547 | 546 | ||
548 | /* Read whole page - necessary with MLC controller! */ | 547 | /* Read whole page - necessary with MLC controller! */ |
549 | lpc32xx_read_page(mtd, chip, host->dummy_buf, 1, page); | 548 | lpc32xx_read_page(mtd, chip, host->dummy_buf, 1, page); |
@@ -566,7 +565,7 @@ static void lpc32xx_ecc_enable(struct mtd_info *mtd, int mode) | |||
566 | 565 | ||
567 | static int lpc32xx_dma_setup(struct lpc32xx_nand_host *host) | 566 | static int lpc32xx_dma_setup(struct lpc32xx_nand_host *host) |
568 | { | 567 | { |
569 | struct mtd_info *mtd = &host->mtd; | 568 | struct mtd_info *mtd = nand_to_mtd(&host->nand_chip); |
570 | dma_cap_mask_t mask; | 569 | dma_cap_mask_t mask; |
571 | 570 | ||
572 | if (!host->pdata || !host->pdata->dma_filter) { | 571 | if (!host->pdata || !host->pdata->dma_filter) { |
@@ -647,7 +646,6 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
647 | struct nand_chip *nand_chip; | 646 | struct nand_chip *nand_chip; |
648 | struct resource *rc; | 647 | struct resource *rc; |
649 | int res; | 648 | int res; |
650 | struct mtd_part_parser_data ppdata = {}; | ||
651 | 649 | ||
652 | /* Allocate memory for the device structure (and zero it) */ | 650 | /* Allocate memory for the device structure (and zero it) */ |
653 | host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); | 651 | host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); |
@@ -661,8 +659,8 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
661 | 659 | ||
662 | host->io_base_phy = rc->start; | 660 | host->io_base_phy = rc->start; |
663 | 661 | ||
664 | mtd = &host->mtd; | ||
665 | nand_chip = &host->nand_chip; | 662 | nand_chip = &host->nand_chip; |
663 | mtd = nand_to_mtd(nand_chip); | ||
666 | if (pdev->dev.of_node) | 664 | if (pdev->dev.of_node) |
667 | host->ncfg = lpc32xx_parse_dt(&pdev->dev); | 665 | host->ncfg = lpc32xx_parse_dt(&pdev->dev); |
668 | if (!host->ncfg) { | 666 | if (!host->ncfg) { |
@@ -681,8 +679,9 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
681 | 679 | ||
682 | host->pdata = dev_get_platdata(&pdev->dev); | 680 | host->pdata = dev_get_platdata(&pdev->dev); |
683 | 681 | ||
684 | nand_chip->priv = host; /* link the private data structures */ | 682 | /* link the private data structures */ |
685 | mtd->priv = nand_chip; | 683 | nand_set_controller_data(nand_chip, host); |
684 | nand_set_flash_node(nand_chip, pdev->dev.of_node); | ||
686 | mtd->dev.parent = &pdev->dev; | 685 | mtd->dev.parent = &pdev->dev; |
687 | 686 | ||
688 | /* Get NAND clock */ | 687 | /* Get NAND clock */ |
@@ -786,9 +785,8 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
786 | 785 | ||
787 | mtd->name = DRV_NAME; | 786 | mtd->name = DRV_NAME; |
788 | 787 | ||
789 | ppdata.of_node = pdev->dev.of_node; | 788 | res = mtd_device_register(mtd, host->ncfg->parts, |
790 | res = mtd_device_parse_register(mtd, NULL, &ppdata, host->ncfg->parts, | 789 | host->ncfg->num_parts); |
791 | host->ncfg->num_parts); | ||
792 | if (!res) | 790 | if (!res) |
793 | return res; | 791 | return res; |
794 | 792 | ||
@@ -815,7 +813,7 @@ err_exit1: | |||
815 | static int lpc32xx_nand_remove(struct platform_device *pdev) | 813 | static int lpc32xx_nand_remove(struct platform_device *pdev) |
816 | { | 814 | { |
817 | struct lpc32xx_nand_host *host = platform_get_drvdata(pdev); | 815 | struct lpc32xx_nand_host *host = platform_get_drvdata(pdev); |
818 | struct mtd_info *mtd = &host->mtd; | 816 | struct mtd_info *mtd = nand_to_mtd(&host->nand_chip); |
819 | 817 | ||
820 | nand_release(mtd); | 818 | nand_release(mtd); |
821 | free_irq(host->irq, host); | 819 | free_irq(host->irq, host); |
diff --git a/drivers/mtd/nand/lpc32xx_slc.c b/drivers/mtd/nand/lpc32xx_slc.c index 4f3d4eb17da0..3b8f3735f3e8 100644 --- a/drivers/mtd/nand/lpc32xx_slc.c +++ b/drivers/mtd/nand/lpc32xx_slc.c | |||
@@ -204,7 +204,6 @@ struct lpc32xx_nand_host { | |||
204 | struct nand_chip nand_chip; | 204 | struct nand_chip nand_chip; |
205 | struct lpc32xx_slc_platform_data *pdata; | 205 | struct lpc32xx_slc_platform_data *pdata; |
206 | struct clk *clk; | 206 | struct clk *clk; |
207 | struct mtd_info mtd; | ||
208 | void __iomem *io_base; | 207 | void __iomem *io_base; |
209 | struct lpc32xx_nand_cfg_slc *ncfg; | 208 | struct lpc32xx_nand_cfg_slc *ncfg; |
210 | 209 | ||
@@ -260,8 +259,8 @@ static void lpc32xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, | |||
260 | unsigned int ctrl) | 259 | unsigned int ctrl) |
261 | { | 260 | { |
262 | uint32_t tmp; | 261 | uint32_t tmp; |
263 | struct nand_chip *chip = mtd->priv; | 262 | struct nand_chip *chip = mtd_to_nand(mtd); |
264 | struct lpc32xx_nand_host *host = chip->priv; | 263 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); |
265 | 264 | ||
266 | /* Does CE state need to be changed? */ | 265 | /* Does CE state need to be changed? */ |
267 | tmp = readl(SLC_CFG(host->io_base)); | 266 | tmp = readl(SLC_CFG(host->io_base)); |
@@ -284,8 +283,8 @@ static void lpc32xx_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, | |||
284 | */ | 283 | */ |
285 | static int lpc32xx_nand_device_ready(struct mtd_info *mtd) | 284 | static int lpc32xx_nand_device_ready(struct mtd_info *mtd) |
286 | { | 285 | { |
287 | struct nand_chip *chip = mtd->priv; | 286 | struct nand_chip *chip = mtd_to_nand(mtd); |
288 | struct lpc32xx_nand_host *host = chip->priv; | 287 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); |
289 | int rdy = 0; | 288 | int rdy = 0; |
290 | 289 | ||
291 | if ((readl(SLC_STAT(host->io_base)) & SLCSTAT_NAND_READY) != 0) | 290 | if ((readl(SLC_STAT(host->io_base)) & SLCSTAT_NAND_READY) != 0) |
@@ -339,8 +338,8 @@ static int lpc32xx_nand_ecc_calculate(struct mtd_info *mtd, | |||
339 | */ | 338 | */ |
340 | static uint8_t lpc32xx_nand_read_byte(struct mtd_info *mtd) | 339 | static uint8_t lpc32xx_nand_read_byte(struct mtd_info *mtd) |
341 | { | 340 | { |
342 | struct nand_chip *chip = mtd->priv; | 341 | struct nand_chip *chip = mtd_to_nand(mtd); |
343 | struct lpc32xx_nand_host *host = chip->priv; | 342 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); |
344 | 343 | ||
345 | return (uint8_t)readl(SLC_DATA(host->io_base)); | 344 | return (uint8_t)readl(SLC_DATA(host->io_base)); |
346 | } | 345 | } |
@@ -350,8 +349,8 @@ static uint8_t lpc32xx_nand_read_byte(struct mtd_info *mtd) | |||
350 | */ | 349 | */ |
351 | static void lpc32xx_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) | 350 | static void lpc32xx_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) |
352 | { | 351 | { |
353 | struct nand_chip *chip = mtd->priv; | 352 | struct nand_chip *chip = mtd_to_nand(mtd); |
354 | struct lpc32xx_nand_host *host = chip->priv; | 353 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); |
355 | 354 | ||
356 | /* Direct device read with no ECC */ | 355 | /* Direct device read with no ECC */ |
357 | while (len-- > 0) | 356 | while (len-- > 0) |
@@ -363,8 +362,8 @@ static void lpc32xx_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) | |||
363 | */ | 362 | */ |
364 | static void lpc32xx_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | 363 | static void lpc32xx_nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) |
365 | { | 364 | { |
366 | struct nand_chip *chip = mtd->priv; | 365 | struct nand_chip *chip = mtd_to_nand(mtd); |
367 | struct lpc32xx_nand_host *host = chip->priv; | 366 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); |
368 | 367 | ||
369 | /* Direct device write with no ECC */ | 368 | /* Direct device write with no ECC */ |
370 | while (len-- > 0) | 369 | while (len-- > 0) |
@@ -428,8 +427,8 @@ static void lpc32xx_dma_complete_func(void *completion) | |||
428 | static int lpc32xx_xmit_dma(struct mtd_info *mtd, dma_addr_t dma, | 427 | static int lpc32xx_xmit_dma(struct mtd_info *mtd, dma_addr_t dma, |
429 | void *mem, int len, enum dma_transfer_direction dir) | 428 | void *mem, int len, enum dma_transfer_direction dir) |
430 | { | 429 | { |
431 | struct nand_chip *chip = mtd->priv; | 430 | struct nand_chip *chip = mtd_to_nand(mtd); |
432 | struct lpc32xx_nand_host *host = chip->priv; | 431 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); |
433 | struct dma_async_tx_descriptor *desc; | 432 | struct dma_async_tx_descriptor *desc; |
434 | int flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; | 433 | int flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; |
435 | int res; | 434 | int res; |
@@ -488,8 +487,8 @@ out1: | |||
488 | static int lpc32xx_xfer(struct mtd_info *mtd, uint8_t *buf, int eccsubpages, | 487 | static int lpc32xx_xfer(struct mtd_info *mtd, uint8_t *buf, int eccsubpages, |
489 | int read) | 488 | int read) |
490 | { | 489 | { |
491 | struct nand_chip *chip = mtd->priv; | 490 | struct nand_chip *chip = mtd_to_nand(mtd); |
492 | struct lpc32xx_nand_host *host = chip->priv; | 491 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); |
493 | int i, status = 0; | 492 | int i, status = 0; |
494 | unsigned long timeout; | 493 | unsigned long timeout; |
495 | int res; | 494 | int res; |
@@ -604,7 +603,7 @@ static int lpc32xx_nand_read_page_syndrome(struct mtd_info *mtd, | |||
604 | struct nand_chip *chip, uint8_t *buf, | 603 | struct nand_chip *chip, uint8_t *buf, |
605 | int oob_required, int page) | 604 | int oob_required, int page) |
606 | { | 605 | { |
607 | struct lpc32xx_nand_host *host = chip->priv; | 606 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); |
608 | int stat, i, status; | 607 | int stat, i, status; |
609 | uint8_t *oobecc, tmpecc[LPC32XX_ECC_SAVE_SIZE]; | 608 | uint8_t *oobecc, tmpecc[LPC32XX_ECC_SAVE_SIZE]; |
610 | 609 | ||
@@ -666,7 +665,7 @@ static int lpc32xx_nand_write_page_syndrome(struct mtd_info *mtd, | |||
666 | const uint8_t *buf, | 665 | const uint8_t *buf, |
667 | int oob_required, int page) | 666 | int oob_required, int page) |
668 | { | 667 | { |
669 | struct lpc32xx_nand_host *host = chip->priv; | 668 | struct lpc32xx_nand_host *host = nand_get_controller_data(chip); |
670 | uint8_t *pb = chip->oob_poi + chip->ecc.layout->eccpos[0]; | 669 | uint8_t *pb = chip->oob_poi + chip->ecc.layout->eccpos[0]; |
671 | int error; | 670 | int error; |
672 | 671 | ||
@@ -703,7 +702,7 @@ static int lpc32xx_nand_write_page_raw_syndrome(struct mtd_info *mtd, | |||
703 | 702 | ||
704 | static int lpc32xx_nand_dma_setup(struct lpc32xx_nand_host *host) | 703 | static int lpc32xx_nand_dma_setup(struct lpc32xx_nand_host *host) |
705 | { | 704 | { |
706 | struct mtd_info *mtd = &host->mtd; | 705 | struct mtd_info *mtd = nand_to_mtd(&host->nand_chip); |
707 | dma_cap_mask_t mask; | 706 | dma_cap_mask_t mask; |
708 | 707 | ||
709 | if (!host->pdata || !host->pdata->dma_filter) { | 708 | if (!host->pdata || !host->pdata->dma_filter) { |
@@ -763,7 +762,6 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
763 | struct mtd_info *mtd; | 762 | struct mtd_info *mtd; |
764 | struct nand_chip *chip; | 763 | struct nand_chip *chip; |
765 | struct resource *rc; | 764 | struct resource *rc; |
766 | struct mtd_part_parser_data ppdata = {}; | ||
767 | int res; | 765 | int res; |
768 | 766 | ||
769 | rc = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 767 | rc = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -800,10 +798,10 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
800 | 798 | ||
801 | host->pdata = dev_get_platdata(&pdev->dev); | 799 | host->pdata = dev_get_platdata(&pdev->dev); |
802 | 800 | ||
803 | mtd = &host->mtd; | ||
804 | chip = &host->nand_chip; | 801 | chip = &host->nand_chip; |
805 | chip->priv = host; | 802 | mtd = nand_to_mtd(chip); |
806 | mtd->priv = chip; | 803 | nand_set_controller_data(chip, host); |
804 | nand_set_flash_node(chip, pdev->dev.of_node); | ||
807 | mtd->owner = THIS_MODULE; | 805 | mtd->owner = THIS_MODULE; |
808 | mtd->dev.parent = &pdev->dev; | 806 | mtd->dev.parent = &pdev->dev; |
809 | 807 | ||
@@ -908,9 +906,8 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
908 | } | 906 | } |
909 | 907 | ||
910 | mtd->name = "nxp_lpc3220_slc"; | 908 | mtd->name = "nxp_lpc3220_slc"; |
911 | ppdata.of_node = pdev->dev.of_node; | 909 | res = mtd_device_register(mtd, host->ncfg->parts, |
912 | res = mtd_device_parse_register(mtd, NULL, &ppdata, host->ncfg->parts, | 910 | host->ncfg->num_parts); |
913 | host->ncfg->num_parts); | ||
914 | if (!res) | 911 | if (!res) |
915 | return res; | 912 | return res; |
916 | 913 | ||
@@ -933,7 +930,7 @@ static int lpc32xx_nand_remove(struct platform_device *pdev) | |||
933 | { | 930 | { |
934 | uint32_t tmp; | 931 | uint32_t tmp; |
935 | struct lpc32xx_nand_host *host = platform_get_drvdata(pdev); | 932 | struct lpc32xx_nand_host *host = platform_get_drvdata(pdev); |
936 | struct mtd_info *mtd = &host->mtd; | 933 | struct mtd_info *mtd = nand_to_mtd(&host->nand_chip); |
937 | 934 | ||
938 | nand_release(mtd); | 935 | nand_release(mtd); |
939 | dma_release_channel(host->dma_chan); | 936 | dma_release_channel(host->dma_chan); |
diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c index d6bbde4a5331..6b93e899d4e9 100644 --- a/drivers/mtd/nand/mpc5121_nfc.c +++ b/drivers/mtd/nand/mpc5121_nfc.c | |||
@@ -118,7 +118,6 @@ | |||
118 | #define NFC_TIMEOUT (HZ / 10) /* 1/10 s */ | 118 | #define NFC_TIMEOUT (HZ / 10) /* 1/10 s */ |
119 | 119 | ||
120 | struct mpc5121_nfc_prv { | 120 | struct mpc5121_nfc_prv { |
121 | struct mtd_info mtd; | ||
122 | struct nand_chip chip; | 121 | struct nand_chip chip; |
123 | int irq; | 122 | int irq; |
124 | void __iomem *regs; | 123 | void __iomem *regs; |
@@ -135,8 +134,8 @@ static void mpc5121_nfc_done(struct mtd_info *mtd); | |||
135 | /* Read NFC register */ | 134 | /* Read NFC register */ |
136 | static inline u16 nfc_read(struct mtd_info *mtd, uint reg) | 135 | static inline u16 nfc_read(struct mtd_info *mtd, uint reg) |
137 | { | 136 | { |
138 | struct nand_chip *chip = mtd->priv; | 137 | struct nand_chip *chip = mtd_to_nand(mtd); |
139 | struct mpc5121_nfc_prv *prv = chip->priv; | 138 | struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip); |
140 | 139 | ||
141 | return in_be16(prv->regs + reg); | 140 | return in_be16(prv->regs + reg); |
142 | } | 141 | } |
@@ -144,8 +143,8 @@ static inline u16 nfc_read(struct mtd_info *mtd, uint reg) | |||
144 | /* Write NFC register */ | 143 | /* Write NFC register */ |
145 | static inline void nfc_write(struct mtd_info *mtd, uint reg, u16 val) | 144 | static inline void nfc_write(struct mtd_info *mtd, uint reg, u16 val) |
146 | { | 145 | { |
147 | struct nand_chip *chip = mtd->priv; | 146 | struct nand_chip *chip = mtd_to_nand(mtd); |
148 | struct mpc5121_nfc_prv *prv = chip->priv; | 147 | struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip); |
149 | 148 | ||
150 | out_be16(prv->regs + reg, val); | 149 | out_be16(prv->regs + reg, val); |
151 | } | 150 | } |
@@ -214,8 +213,8 @@ static inline void mpc5121_nfc_send_read_status(struct mtd_info *mtd) | |||
214 | static irqreturn_t mpc5121_nfc_irq(int irq, void *data) | 213 | static irqreturn_t mpc5121_nfc_irq(int irq, void *data) |
215 | { | 214 | { |
216 | struct mtd_info *mtd = data; | 215 | struct mtd_info *mtd = data; |
217 | struct nand_chip *chip = mtd->priv; | 216 | struct nand_chip *chip = mtd_to_nand(mtd); |
218 | struct mpc5121_nfc_prv *prv = chip->priv; | 217 | struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip); |
219 | 218 | ||
220 | nfc_set(mtd, NFC_CONFIG1, NFC_INT_MASK); | 219 | nfc_set(mtd, NFC_CONFIG1, NFC_INT_MASK); |
221 | wake_up(&prv->irq_waitq); | 220 | wake_up(&prv->irq_waitq); |
@@ -226,8 +225,8 @@ static irqreturn_t mpc5121_nfc_irq(int irq, void *data) | |||
226 | /* Wait for operation complete */ | 225 | /* Wait for operation complete */ |
227 | static void mpc5121_nfc_done(struct mtd_info *mtd) | 226 | static void mpc5121_nfc_done(struct mtd_info *mtd) |
228 | { | 227 | { |
229 | struct nand_chip *chip = mtd->priv; | 228 | struct nand_chip *chip = mtd_to_nand(mtd); |
230 | struct mpc5121_nfc_prv *prv = chip->priv; | 229 | struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip); |
231 | int rv; | 230 | int rv; |
232 | 231 | ||
233 | if ((nfc_read(mtd, NFC_CONFIG2) & NFC_INT) == 0) { | 232 | if ((nfc_read(mtd, NFC_CONFIG2) & NFC_INT) == 0) { |
@@ -246,7 +245,7 @@ static void mpc5121_nfc_done(struct mtd_info *mtd) | |||
246 | /* Do address cycle(s) */ | 245 | /* Do address cycle(s) */ |
247 | static void mpc5121_nfc_addr_cycle(struct mtd_info *mtd, int column, int page) | 246 | static void mpc5121_nfc_addr_cycle(struct mtd_info *mtd, int column, int page) |
248 | { | 247 | { |
249 | struct nand_chip *chip = mtd->priv; | 248 | struct nand_chip *chip = mtd_to_nand(mtd); |
250 | u32 pagemask = chip->pagemask; | 249 | u32 pagemask = chip->pagemask; |
251 | 250 | ||
252 | if (column != -1) { | 251 | if (column != -1) { |
@@ -281,8 +280,8 @@ static void mpc5121_nfc_select_chip(struct mtd_info *mtd, int chip) | |||
281 | /* Init external chip select logic on ADS5121 board */ | 280 | /* Init external chip select logic on ADS5121 board */ |
282 | static int ads5121_chipselect_init(struct mtd_info *mtd) | 281 | static int ads5121_chipselect_init(struct mtd_info *mtd) |
283 | { | 282 | { |
284 | struct nand_chip *chip = mtd->priv; | 283 | struct nand_chip *chip = mtd_to_nand(mtd); |
285 | struct mpc5121_nfc_prv *prv = chip->priv; | 284 | struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip); |
286 | struct device_node *dn; | 285 | struct device_node *dn; |
287 | 286 | ||
288 | dn = of_find_compatible_node(NULL, NULL, "fsl,mpc5121ads-cpld"); | 287 | dn = of_find_compatible_node(NULL, NULL, "fsl,mpc5121ads-cpld"); |
@@ -303,8 +302,8 @@ static int ads5121_chipselect_init(struct mtd_info *mtd) | |||
303 | /* Control chips select signal on ADS5121 board */ | 302 | /* Control chips select signal on ADS5121 board */ |
304 | static void ads5121_select_chip(struct mtd_info *mtd, int chip) | 303 | static void ads5121_select_chip(struct mtd_info *mtd, int chip) |
305 | { | 304 | { |
306 | struct nand_chip *nand = mtd->priv; | 305 | struct nand_chip *nand = mtd_to_nand(mtd); |
307 | struct mpc5121_nfc_prv *prv = nand->priv; | 306 | struct mpc5121_nfc_prv *prv = nand_get_controller_data(nand); |
308 | u8 v; | 307 | u8 v; |
309 | 308 | ||
310 | v = in_8(prv->csreg); | 309 | v = in_8(prv->csreg); |
@@ -333,8 +332,8 @@ static int mpc5121_nfc_dev_ready(struct mtd_info *mtd) | |||
333 | static void mpc5121_nfc_command(struct mtd_info *mtd, unsigned command, | 332 | static void mpc5121_nfc_command(struct mtd_info *mtd, unsigned command, |
334 | int column, int page) | 333 | int column, int page) |
335 | { | 334 | { |
336 | struct nand_chip *chip = mtd->priv; | 335 | struct nand_chip *chip = mtd_to_nand(mtd); |
337 | struct mpc5121_nfc_prv *prv = chip->priv; | 336 | struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip); |
338 | 337 | ||
339 | prv->column = (column >= 0) ? column : 0; | 338 | prv->column = (column >= 0) ? column : 0; |
340 | prv->spareonly = 0; | 339 | prv->spareonly = 0; |
@@ -406,8 +405,8 @@ static void mpc5121_nfc_command(struct mtd_info *mtd, unsigned command, | |||
406 | static void mpc5121_nfc_copy_spare(struct mtd_info *mtd, uint offset, | 405 | static void mpc5121_nfc_copy_spare(struct mtd_info *mtd, uint offset, |
407 | u8 *buffer, uint size, int wr) | 406 | u8 *buffer, uint size, int wr) |
408 | { | 407 | { |
409 | struct nand_chip *nand = mtd->priv; | 408 | struct nand_chip *nand = mtd_to_nand(mtd); |
410 | struct mpc5121_nfc_prv *prv = nand->priv; | 409 | struct mpc5121_nfc_prv *prv = nand_get_controller_data(nand); |
411 | uint o, s, sbsize, blksize; | 410 | uint o, s, sbsize, blksize; |
412 | 411 | ||
413 | /* | 412 | /* |
@@ -458,8 +457,8 @@ static void mpc5121_nfc_copy_spare(struct mtd_info *mtd, uint offset, | |||
458 | static void mpc5121_nfc_buf_copy(struct mtd_info *mtd, u_char *buf, int len, | 457 | static void mpc5121_nfc_buf_copy(struct mtd_info *mtd, u_char *buf, int len, |
459 | int wr) | 458 | int wr) |
460 | { | 459 | { |
461 | struct nand_chip *chip = mtd->priv; | 460 | struct nand_chip *chip = mtd_to_nand(mtd); |
462 | struct mpc5121_nfc_prv *prv = chip->priv; | 461 | struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip); |
463 | uint c = prv->column; | 462 | uint c = prv->column; |
464 | uint l; | 463 | uint l; |
465 | 464 | ||
@@ -536,8 +535,8 @@ static u16 mpc5121_nfc_read_word(struct mtd_info *mtd) | |||
536 | */ | 535 | */ |
537 | static int mpc5121_nfc_read_hw_config(struct mtd_info *mtd) | 536 | static int mpc5121_nfc_read_hw_config(struct mtd_info *mtd) |
538 | { | 537 | { |
539 | struct nand_chip *chip = mtd->priv; | 538 | struct nand_chip *chip = mtd_to_nand(mtd); |
540 | struct mpc5121_nfc_prv *prv = chip->priv; | 539 | struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip); |
541 | struct mpc512x_reset_module *rm; | 540 | struct mpc512x_reset_module *rm; |
542 | struct device_node *rmnode; | 541 | struct device_node *rmnode; |
543 | uint rcw_pagesize = 0; | 542 | uint rcw_pagesize = 0; |
@@ -615,8 +614,8 @@ out: | |||
615 | /* Free driver resources */ | 614 | /* Free driver resources */ |
616 | static void mpc5121_nfc_free(struct device *dev, struct mtd_info *mtd) | 615 | static void mpc5121_nfc_free(struct device *dev, struct mtd_info *mtd) |
617 | { | 616 | { |
618 | struct nand_chip *chip = mtd->priv; | 617 | struct nand_chip *chip = mtd_to_nand(mtd); |
619 | struct mpc5121_nfc_prv *prv = chip->priv; | 618 | struct mpc5121_nfc_prv *prv = nand_get_controller_data(chip); |
620 | 619 | ||
621 | if (prv->clk) | 620 | if (prv->clk) |
622 | clk_disable_unprepare(prv->clk); | 621 | clk_disable_unprepare(prv->clk); |
@@ -639,7 +638,6 @@ static int mpc5121_nfc_probe(struct platform_device *op) | |||
639 | int resettime = 0; | 638 | int resettime = 0; |
640 | int retval = 0; | 639 | int retval = 0; |
641 | int rev, len; | 640 | int rev, len; |
642 | struct mtd_part_parser_data ppdata; | ||
643 | 641 | ||
644 | /* | 642 | /* |
645 | * Check SoC revision. This driver supports only NFC | 643 | * Check SoC revision. This driver supports only NFC |
@@ -655,12 +653,12 @@ static int mpc5121_nfc_probe(struct platform_device *op) | |||
655 | if (!prv) | 653 | if (!prv) |
656 | return -ENOMEM; | 654 | return -ENOMEM; |
657 | 655 | ||
658 | mtd = &prv->mtd; | ||
659 | chip = &prv->chip; | 656 | chip = &prv->chip; |
657 | mtd = nand_to_mtd(chip); | ||
660 | 658 | ||
661 | mtd->priv = chip; | ||
662 | mtd->dev.parent = dev; | 659 | mtd->dev.parent = dev; |
663 | chip->priv = prv; | 660 | nand_set_controller_data(chip, prv); |
661 | nand_set_flash_node(chip, dn); | ||
664 | prv->dev = dev; | 662 | prv->dev = dev; |
665 | 663 | ||
666 | /* Read NFC configuration from Reset Config Word */ | 664 | /* Read NFC configuration from Reset Config Word */ |
@@ -703,7 +701,6 @@ static int mpc5121_nfc_probe(struct platform_device *op) | |||
703 | } | 701 | } |
704 | 702 | ||
705 | mtd->name = "MPC5121 NAND"; | 703 | mtd->name = "MPC5121 NAND"; |
706 | ppdata.of_node = dn; | ||
707 | chip->dev_ready = mpc5121_nfc_dev_ready; | 704 | chip->dev_ready = mpc5121_nfc_dev_ready; |
708 | chip->cmdfunc = mpc5121_nfc_command; | 705 | chip->cmdfunc = mpc5121_nfc_command; |
709 | chip->read_byte = mpc5121_nfc_read_byte; | 706 | chip->read_byte = mpc5121_nfc_read_byte; |
@@ -815,7 +812,7 @@ static int mpc5121_nfc_probe(struct platform_device *op) | |||
815 | dev_set_drvdata(dev, mtd); | 812 | dev_set_drvdata(dev, mtd); |
816 | 813 | ||
817 | /* Register device in MTD */ | 814 | /* Register device in MTD */ |
818 | retval = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); | 815 | retval = mtd_device_register(mtd, NULL, 0); |
819 | if (retval) { | 816 | if (retval) { |
820 | dev_err(dev, "Error adding MTD device!\n"); | 817 | dev_err(dev, "Error adding MTD device!\n"); |
821 | goto error; | 818 | goto error; |
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 136e73a3e07e..854c832597aa 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c | |||
@@ -173,7 +173,6 @@ struct mxc_nand_devtype_data { | |||
173 | }; | 173 | }; |
174 | 174 | ||
175 | struct mxc_nand_host { | 175 | struct mxc_nand_host { |
176 | struct mtd_info mtd; | ||
177 | struct nand_chip nand; | 176 | struct nand_chip nand; |
178 | struct device *dev; | 177 | struct device *dev; |
179 | 178 | ||
@@ -532,8 +531,8 @@ static void send_addr_v1_v2(struct mxc_nand_host *host, uint16_t addr, int islas | |||
532 | 531 | ||
533 | static void send_page_v3(struct mtd_info *mtd, unsigned int ops) | 532 | static void send_page_v3(struct mtd_info *mtd, unsigned int ops) |
534 | { | 533 | { |
535 | struct nand_chip *nand_chip = mtd->priv; | 534 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
536 | struct mxc_nand_host *host = nand_chip->priv; | 535 | struct mxc_nand_host *host = nand_get_controller_data(nand_chip); |
537 | uint32_t tmp; | 536 | uint32_t tmp; |
538 | 537 | ||
539 | tmp = readl(NFC_V3_CONFIG1); | 538 | tmp = readl(NFC_V3_CONFIG1); |
@@ -548,8 +547,8 @@ static void send_page_v3(struct mtd_info *mtd, unsigned int ops) | |||
548 | 547 | ||
549 | static void send_page_v2(struct mtd_info *mtd, unsigned int ops) | 548 | static void send_page_v2(struct mtd_info *mtd, unsigned int ops) |
550 | { | 549 | { |
551 | struct nand_chip *nand_chip = mtd->priv; | 550 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
552 | struct mxc_nand_host *host = nand_chip->priv; | 551 | struct mxc_nand_host *host = nand_get_controller_data(nand_chip); |
553 | 552 | ||
554 | /* NANDFC buffer 0 is used for page read/write */ | 553 | /* NANDFC buffer 0 is used for page read/write */ |
555 | writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR); | 554 | writew(host->active_cs << 4, NFC_V1_V2_BUF_ADDR); |
@@ -562,8 +561,8 @@ static void send_page_v2(struct mtd_info *mtd, unsigned int ops) | |||
562 | 561 | ||
563 | static void send_page_v1(struct mtd_info *mtd, unsigned int ops) | 562 | static void send_page_v1(struct mtd_info *mtd, unsigned int ops) |
564 | { | 563 | { |
565 | struct nand_chip *nand_chip = mtd->priv; | 564 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
566 | struct mxc_nand_host *host = nand_chip->priv; | 565 | struct mxc_nand_host *host = nand_get_controller_data(nand_chip); |
567 | int bufs, i; | 566 | int bufs, i; |
568 | 567 | ||
569 | if (mtd->writesize > 512) | 568 | if (mtd->writesize > 512) |
@@ -663,8 +662,8 @@ static void mxc_nand_enable_hwecc(struct mtd_info *mtd, int mode) | |||
663 | static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat, | 662 | static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat, |
664 | u_char *read_ecc, u_char *calc_ecc) | 663 | u_char *read_ecc, u_char *calc_ecc) |
665 | { | 664 | { |
666 | struct nand_chip *nand_chip = mtd->priv; | 665 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
667 | struct mxc_nand_host *host = nand_chip->priv; | 666 | struct mxc_nand_host *host = nand_get_controller_data(nand_chip); |
668 | 667 | ||
669 | /* | 668 | /* |
670 | * 1-Bit errors are automatically corrected in HW. No need for | 669 | * 1-Bit errors are automatically corrected in HW. No need for |
@@ -675,7 +674,7 @@ static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat, | |||
675 | 674 | ||
676 | if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) { | 675 | if (((ecc_status & 0x3) == 2) || ((ecc_status >> 2) == 2)) { |
677 | pr_debug("MXC_NAND: HWECC uncorrectable 2-bit ECC error\n"); | 676 | pr_debug("MXC_NAND: HWECC uncorrectable 2-bit ECC error\n"); |
678 | return -1; | 677 | return -EBADMSG; |
679 | } | 678 | } |
680 | 679 | ||
681 | return 0; | 680 | return 0; |
@@ -684,8 +683,8 @@ static int mxc_nand_correct_data_v1(struct mtd_info *mtd, u_char *dat, | |||
684 | static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat, | 683 | static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat, |
685 | u_char *read_ecc, u_char *calc_ecc) | 684 | u_char *read_ecc, u_char *calc_ecc) |
686 | { | 685 | { |
687 | struct nand_chip *nand_chip = mtd->priv; | 686 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
688 | struct mxc_nand_host *host = nand_chip->priv; | 687 | struct mxc_nand_host *host = nand_get_controller_data(nand_chip); |
689 | u32 ecc_stat, err; | 688 | u32 ecc_stat, err; |
690 | int no_subpages = 1; | 689 | int no_subpages = 1; |
691 | int ret = 0; | 690 | int ret = 0; |
@@ -702,7 +701,7 @@ static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat, | |||
702 | err = ecc_stat & ecc_bit_mask; | 701 | err = ecc_stat & ecc_bit_mask; |
703 | if (err > err_limit) { | 702 | if (err > err_limit) { |
704 | printk(KERN_WARNING "UnCorrectable RS-ECC Error\n"); | 703 | printk(KERN_WARNING "UnCorrectable RS-ECC Error\n"); |
705 | return -1; | 704 | return -EBADMSG; |
706 | } else { | 705 | } else { |
707 | ret += err; | 706 | ret += err; |
708 | } | 707 | } |
@@ -722,8 +721,8 @@ static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, | |||
722 | 721 | ||
723 | static u_char mxc_nand_read_byte(struct mtd_info *mtd) | 722 | static u_char mxc_nand_read_byte(struct mtd_info *mtd) |
724 | { | 723 | { |
725 | struct nand_chip *nand_chip = mtd->priv; | 724 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
726 | struct mxc_nand_host *host = nand_chip->priv; | 725 | struct mxc_nand_host *host = nand_get_controller_data(nand_chip); |
727 | uint8_t ret; | 726 | uint8_t ret; |
728 | 727 | ||
729 | /* Check for status request */ | 728 | /* Check for status request */ |
@@ -746,8 +745,8 @@ static u_char mxc_nand_read_byte(struct mtd_info *mtd) | |||
746 | 745 | ||
747 | static uint16_t mxc_nand_read_word(struct mtd_info *mtd) | 746 | static uint16_t mxc_nand_read_word(struct mtd_info *mtd) |
748 | { | 747 | { |
749 | struct nand_chip *nand_chip = mtd->priv; | 748 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
750 | struct mxc_nand_host *host = nand_chip->priv; | 749 | struct mxc_nand_host *host = nand_get_controller_data(nand_chip); |
751 | uint16_t ret; | 750 | uint16_t ret; |
752 | 751 | ||
753 | ret = *(uint16_t *)(host->data_buf + host->buf_start); | 752 | ret = *(uint16_t *)(host->data_buf + host->buf_start); |
@@ -762,8 +761,8 @@ static uint16_t mxc_nand_read_word(struct mtd_info *mtd) | |||
762 | static void mxc_nand_write_buf(struct mtd_info *mtd, | 761 | static void mxc_nand_write_buf(struct mtd_info *mtd, |
763 | const u_char *buf, int len) | 762 | const u_char *buf, int len) |
764 | { | 763 | { |
765 | struct nand_chip *nand_chip = mtd->priv; | 764 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
766 | struct mxc_nand_host *host = nand_chip->priv; | 765 | struct mxc_nand_host *host = nand_get_controller_data(nand_chip); |
767 | u16 col = host->buf_start; | 766 | u16 col = host->buf_start; |
768 | int n = mtd->oobsize + mtd->writesize - col; | 767 | int n = mtd->oobsize + mtd->writesize - col; |
769 | 768 | ||
@@ -780,8 +779,8 @@ static void mxc_nand_write_buf(struct mtd_info *mtd, | |||
780 | */ | 779 | */ |
781 | static void mxc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) | 780 | static void mxc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) |
782 | { | 781 | { |
783 | struct nand_chip *nand_chip = mtd->priv; | 782 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
784 | struct mxc_nand_host *host = nand_chip->priv; | 783 | struct mxc_nand_host *host = nand_get_controller_data(nand_chip); |
785 | u16 col = host->buf_start; | 784 | u16 col = host->buf_start; |
786 | int n = mtd->oobsize + mtd->writesize - col; | 785 | int n = mtd->oobsize + mtd->writesize - col; |
787 | 786 | ||
@@ -796,8 +795,8 @@ static void mxc_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) | |||
796 | * deselect of the NAND chip */ | 795 | * deselect of the NAND chip */ |
797 | static void mxc_nand_select_chip_v1_v3(struct mtd_info *mtd, int chip) | 796 | static void mxc_nand_select_chip_v1_v3(struct mtd_info *mtd, int chip) |
798 | { | 797 | { |
799 | struct nand_chip *nand_chip = mtd->priv; | 798 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
800 | struct mxc_nand_host *host = nand_chip->priv; | 799 | struct mxc_nand_host *host = nand_get_controller_data(nand_chip); |
801 | 800 | ||
802 | if (chip == -1) { | 801 | if (chip == -1) { |
803 | /* Disable the NFC clock */ | 802 | /* Disable the NFC clock */ |
@@ -817,8 +816,8 @@ static void mxc_nand_select_chip_v1_v3(struct mtd_info *mtd, int chip) | |||
817 | 816 | ||
818 | static void mxc_nand_select_chip_v2(struct mtd_info *mtd, int chip) | 817 | static void mxc_nand_select_chip_v2(struct mtd_info *mtd, int chip) |
819 | { | 818 | { |
820 | struct nand_chip *nand_chip = mtd->priv; | 819 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
821 | struct mxc_nand_host *host = nand_chip->priv; | 820 | struct mxc_nand_host *host = nand_get_controller_data(nand_chip); |
822 | 821 | ||
823 | if (chip == -1) { | 822 | if (chip == -1) { |
824 | /* Disable the NFC clock */ | 823 | /* Disable the NFC clock */ |
@@ -850,8 +849,8 @@ static void mxc_nand_select_chip_v2(struct mtd_info *mtd, int chip) | |||
850 | */ | 849 | */ |
851 | static void copy_spare(struct mtd_info *mtd, bool bfrom) | 850 | static void copy_spare(struct mtd_info *mtd, bool bfrom) |
852 | { | 851 | { |
853 | struct nand_chip *this = mtd->priv; | 852 | struct nand_chip *this = mtd_to_nand(mtd); |
854 | struct mxc_nand_host *host = this->priv; | 853 | struct mxc_nand_host *host = nand_get_controller_data(this); |
855 | u16 i, oob_chunk_size; | 854 | u16 i, oob_chunk_size; |
856 | u16 num_chunks = mtd->writesize / 512; | 855 | u16 num_chunks = mtd->writesize / 512; |
857 | 856 | ||
@@ -893,8 +892,8 @@ static void copy_spare(struct mtd_info *mtd, bool bfrom) | |||
893 | */ | 892 | */ |
894 | static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr) | 893 | static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr) |
895 | { | 894 | { |
896 | struct nand_chip *nand_chip = mtd->priv; | 895 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
897 | struct mxc_nand_host *host = nand_chip->priv; | 896 | struct mxc_nand_host *host = nand_get_controller_data(nand_chip); |
898 | 897 | ||
899 | /* Write out column address, if necessary */ | 898 | /* Write out column address, if necessary */ |
900 | if (column != -1) { | 899 | if (column != -1) { |
@@ -979,8 +978,8 @@ static void ecc_8bit_layout_4k(struct nand_ecclayout *layout) | |||
979 | 978 | ||
980 | static void preset_v1(struct mtd_info *mtd) | 979 | static void preset_v1(struct mtd_info *mtd) |
981 | { | 980 | { |
982 | struct nand_chip *nand_chip = mtd->priv; | 981 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
983 | struct mxc_nand_host *host = nand_chip->priv; | 982 | struct mxc_nand_host *host = nand_get_controller_data(nand_chip); |
984 | uint16_t config1 = 0; | 983 | uint16_t config1 = 0; |
985 | 984 | ||
986 | if (nand_chip->ecc.mode == NAND_ECC_HW && mtd->writesize) | 985 | if (nand_chip->ecc.mode == NAND_ECC_HW && mtd->writesize) |
@@ -1007,8 +1006,8 @@ static void preset_v1(struct mtd_info *mtd) | |||
1007 | 1006 | ||
1008 | static void preset_v2(struct mtd_info *mtd) | 1007 | static void preset_v2(struct mtd_info *mtd) |
1009 | { | 1008 | { |
1010 | struct nand_chip *nand_chip = mtd->priv; | 1009 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
1011 | struct mxc_nand_host *host = nand_chip->priv; | 1010 | struct mxc_nand_host *host = nand_get_controller_data(nand_chip); |
1012 | uint16_t config1 = 0; | 1011 | uint16_t config1 = 0; |
1013 | 1012 | ||
1014 | config1 |= NFC_V2_CONFIG1_FP_INT; | 1013 | config1 |= NFC_V2_CONFIG1_FP_INT; |
@@ -1053,8 +1052,8 @@ static void preset_v2(struct mtd_info *mtd) | |||
1053 | 1052 | ||
1054 | static void preset_v3(struct mtd_info *mtd) | 1053 | static void preset_v3(struct mtd_info *mtd) |
1055 | { | 1054 | { |
1056 | struct nand_chip *chip = mtd->priv; | 1055 | struct nand_chip *chip = mtd_to_nand(mtd); |
1057 | struct mxc_nand_host *host = chip->priv; | 1056 | struct mxc_nand_host *host = nand_get_controller_data(chip); |
1058 | uint32_t config2, config3; | 1057 | uint32_t config2, config3; |
1059 | int i, addr_phases; | 1058 | int i, addr_phases; |
1060 | 1059 | ||
@@ -1067,8 +1066,7 @@ static void preset_v3(struct mtd_info *mtd) | |||
1067 | 1066 | ||
1068 | /* Blocks to be unlocked */ | 1067 | /* Blocks to be unlocked */ |
1069 | for (i = 0; i < NAND_MAX_CHIPS; i++) | 1068 | for (i = 0; i < NAND_MAX_CHIPS; i++) |
1070 | writel(0x0 | (0xffff << 16), | 1069 | writel(0xffff << 16, NFC_V3_WRPROT_UNLOCK_BLK_ADD0 + (i << 2)); |
1071 | NFC_V3_WRPROT_UNLOCK_BLK_ADD0 + (i << 2)); | ||
1072 | 1070 | ||
1073 | writel(0, NFC_V3_IPC); | 1071 | writel(0, NFC_V3_IPC); |
1074 | 1072 | ||
@@ -1125,8 +1123,8 @@ static void preset_v3(struct mtd_info *mtd) | |||
1125 | static void mxc_nand_command(struct mtd_info *mtd, unsigned command, | 1123 | static void mxc_nand_command(struct mtd_info *mtd, unsigned command, |
1126 | int column, int page_addr) | 1124 | int column, int page_addr) |
1127 | { | 1125 | { |
1128 | struct nand_chip *nand_chip = mtd->priv; | 1126 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
1129 | struct mxc_nand_host *host = nand_chip->priv; | 1127 | struct mxc_nand_host *host = nand_get_controller_data(nand_chip); |
1130 | 1128 | ||
1131 | pr_debug("mxc_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n", | 1129 | pr_debug("mxc_nand_command (cmd = 0x%x, col = 0x%x, page = 0x%x)\n", |
1132 | command, column, page_addr); | 1130 | command, column, page_addr); |
@@ -1515,15 +1513,15 @@ static int mxcnd_probe(struct platform_device *pdev) | |||
1515 | host->dev = &pdev->dev; | 1513 | host->dev = &pdev->dev; |
1516 | /* structures must be linked */ | 1514 | /* structures must be linked */ |
1517 | this = &host->nand; | 1515 | this = &host->nand; |
1518 | mtd = &host->mtd; | 1516 | mtd = nand_to_mtd(this); |
1519 | mtd->priv = this; | ||
1520 | mtd->dev.parent = &pdev->dev; | 1517 | mtd->dev.parent = &pdev->dev; |
1521 | mtd->name = DRIVER_NAME; | 1518 | mtd->name = DRIVER_NAME; |
1522 | 1519 | ||
1523 | /* 50 us command delay time */ | 1520 | /* 50 us command delay time */ |
1524 | this->chip_delay = 5; | 1521 | this->chip_delay = 5; |
1525 | 1522 | ||
1526 | this->priv = host; | 1523 | nand_set_controller_data(this, host); |
1524 | nand_set_flash_node(this, pdev->dev.of_node), | ||
1527 | this->dev_ready = mxc_nand_dev_ready; | 1525 | this->dev_ready = mxc_nand_dev_ready; |
1528 | this->cmdfunc = mxc_nand_command; | 1526 | this->cmdfunc = mxc_nand_command; |
1529 | this->read_byte = mxc_nand_read_byte; | 1527 | this->read_byte = mxc_nand_read_byte; |
@@ -1683,9 +1681,7 @@ static int mxcnd_probe(struct platform_device *pdev) | |||
1683 | 1681 | ||
1684 | /* Register the partitions */ | 1682 | /* Register the partitions */ |
1685 | mtd_device_parse_register(mtd, part_probes, | 1683 | mtd_device_parse_register(mtd, part_probes, |
1686 | &(struct mtd_part_parser_data){ | 1684 | NULL, |
1687 | .of_node = pdev->dev.of_node, | ||
1688 | }, | ||
1689 | host->pdata.parts, | 1685 | host->pdata.parts, |
1690 | host->pdata.nr_parts); | 1686 | host->pdata.nr_parts); |
1691 | 1687 | ||
@@ -1704,7 +1700,7 @@ static int mxcnd_remove(struct platform_device *pdev) | |||
1704 | { | 1700 | { |
1705 | struct mxc_nand_host *host = platform_get_drvdata(pdev); | 1701 | struct mxc_nand_host *host = platform_get_drvdata(pdev); |
1706 | 1702 | ||
1707 | nand_release(&host->mtd); | 1703 | nand_release(nand_to_mtd(&host->nand)); |
1708 | if (host->clk_act) | 1704 | if (host->clk_act) |
1709 | clk_disable_unprepare(host->clk); | 1705 | clk_disable_unprepare(host->clk); |
1710 | 1706 | ||
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index ece544efccc3..f2c8ff398d6c 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
@@ -106,7 +106,7 @@ DEFINE_LED_TRIGGER(nand_led_trigger); | |||
106 | static int check_offs_len(struct mtd_info *mtd, | 106 | static int check_offs_len(struct mtd_info *mtd, |
107 | loff_t ofs, uint64_t len) | 107 | loff_t ofs, uint64_t len) |
108 | { | 108 | { |
109 | struct nand_chip *chip = mtd->priv; | 109 | struct nand_chip *chip = mtd_to_nand(mtd); |
110 | int ret = 0; | 110 | int ret = 0; |
111 | 111 | ||
112 | /* Start address must align on block boundary */ | 112 | /* Start address must align on block boundary */ |
@@ -132,7 +132,7 @@ static int check_offs_len(struct mtd_info *mtd, | |||
132 | */ | 132 | */ |
133 | static void nand_release_device(struct mtd_info *mtd) | 133 | static void nand_release_device(struct mtd_info *mtd) |
134 | { | 134 | { |
135 | struct nand_chip *chip = mtd->priv; | 135 | struct nand_chip *chip = mtd_to_nand(mtd); |
136 | 136 | ||
137 | /* Release the controller and the chip */ | 137 | /* Release the controller and the chip */ |
138 | spin_lock(&chip->controller->lock); | 138 | spin_lock(&chip->controller->lock); |
@@ -150,7 +150,7 @@ static void nand_release_device(struct mtd_info *mtd) | |||
150 | */ | 150 | */ |
151 | static uint8_t nand_read_byte(struct mtd_info *mtd) | 151 | static uint8_t nand_read_byte(struct mtd_info *mtd) |
152 | { | 152 | { |
153 | struct nand_chip *chip = mtd->priv; | 153 | struct nand_chip *chip = mtd_to_nand(mtd); |
154 | return readb(chip->IO_ADDR_R); | 154 | return readb(chip->IO_ADDR_R); |
155 | } | 155 | } |
156 | 156 | ||
@@ -163,7 +163,7 @@ static uint8_t nand_read_byte(struct mtd_info *mtd) | |||
163 | */ | 163 | */ |
164 | static uint8_t nand_read_byte16(struct mtd_info *mtd) | 164 | static uint8_t nand_read_byte16(struct mtd_info *mtd) |
165 | { | 165 | { |
166 | struct nand_chip *chip = mtd->priv; | 166 | struct nand_chip *chip = mtd_to_nand(mtd); |
167 | return (uint8_t) cpu_to_le16(readw(chip->IO_ADDR_R)); | 167 | return (uint8_t) cpu_to_le16(readw(chip->IO_ADDR_R)); |
168 | } | 168 | } |
169 | 169 | ||
@@ -175,7 +175,7 @@ static uint8_t nand_read_byte16(struct mtd_info *mtd) | |||
175 | */ | 175 | */ |
176 | static u16 nand_read_word(struct mtd_info *mtd) | 176 | static u16 nand_read_word(struct mtd_info *mtd) |
177 | { | 177 | { |
178 | struct nand_chip *chip = mtd->priv; | 178 | struct nand_chip *chip = mtd_to_nand(mtd); |
179 | return readw(chip->IO_ADDR_R); | 179 | return readw(chip->IO_ADDR_R); |
180 | } | 180 | } |
181 | 181 | ||
@@ -188,7 +188,7 @@ static u16 nand_read_word(struct mtd_info *mtd) | |||
188 | */ | 188 | */ |
189 | static void nand_select_chip(struct mtd_info *mtd, int chipnr) | 189 | static void nand_select_chip(struct mtd_info *mtd, int chipnr) |
190 | { | 190 | { |
191 | struct nand_chip *chip = mtd->priv; | 191 | struct nand_chip *chip = mtd_to_nand(mtd); |
192 | 192 | ||
193 | switch (chipnr) { | 193 | switch (chipnr) { |
194 | case -1: | 194 | case -1: |
@@ -211,7 +211,7 @@ static void nand_select_chip(struct mtd_info *mtd, int chipnr) | |||
211 | */ | 211 | */ |
212 | static void nand_write_byte(struct mtd_info *mtd, uint8_t byte) | 212 | static void nand_write_byte(struct mtd_info *mtd, uint8_t byte) |
213 | { | 213 | { |
214 | struct nand_chip *chip = mtd->priv; | 214 | struct nand_chip *chip = mtd_to_nand(mtd); |
215 | 215 | ||
216 | chip->write_buf(mtd, &byte, 1); | 216 | chip->write_buf(mtd, &byte, 1); |
217 | } | 217 | } |
@@ -225,7 +225,7 @@ static void nand_write_byte(struct mtd_info *mtd, uint8_t byte) | |||
225 | */ | 225 | */ |
226 | static void nand_write_byte16(struct mtd_info *mtd, uint8_t byte) | 226 | static void nand_write_byte16(struct mtd_info *mtd, uint8_t byte) |
227 | { | 227 | { |
228 | struct nand_chip *chip = mtd->priv; | 228 | struct nand_chip *chip = mtd_to_nand(mtd); |
229 | uint16_t word = byte; | 229 | uint16_t word = byte; |
230 | 230 | ||
231 | /* | 231 | /* |
@@ -257,7 +257,7 @@ static void nand_write_byte16(struct mtd_info *mtd, uint8_t byte) | |||
257 | */ | 257 | */ |
258 | static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | 258 | static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) |
259 | { | 259 | { |
260 | struct nand_chip *chip = mtd->priv; | 260 | struct nand_chip *chip = mtd_to_nand(mtd); |
261 | 261 | ||
262 | iowrite8_rep(chip->IO_ADDR_W, buf, len); | 262 | iowrite8_rep(chip->IO_ADDR_W, buf, len); |
263 | } | 263 | } |
@@ -272,7 +272,7 @@ static void nand_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | |||
272 | */ | 272 | */ |
273 | static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | 273 | static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) |
274 | { | 274 | { |
275 | struct nand_chip *chip = mtd->priv; | 275 | struct nand_chip *chip = mtd_to_nand(mtd); |
276 | 276 | ||
277 | ioread8_rep(chip->IO_ADDR_R, buf, len); | 277 | ioread8_rep(chip->IO_ADDR_R, buf, len); |
278 | } | 278 | } |
@@ -287,7 +287,7 @@ static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | |||
287 | */ | 287 | */ |
288 | static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) | 288 | static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) |
289 | { | 289 | { |
290 | struct nand_chip *chip = mtd->priv; | 290 | struct nand_chip *chip = mtd_to_nand(mtd); |
291 | u16 *p = (u16 *) buf; | 291 | u16 *p = (u16 *) buf; |
292 | 292 | ||
293 | iowrite16_rep(chip->IO_ADDR_W, p, len >> 1); | 293 | iowrite16_rep(chip->IO_ADDR_W, p, len >> 1); |
@@ -303,7 +303,7 @@ static void nand_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) | |||
303 | */ | 303 | */ |
304 | static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len) | 304 | static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len) |
305 | { | 305 | { |
306 | struct nand_chip *chip = mtd->priv; | 306 | struct nand_chip *chip = mtd_to_nand(mtd); |
307 | u16 *p = (u16 *) buf; | 307 | u16 *p = (u16 *) buf; |
308 | 308 | ||
309 | ioread16_rep(chip->IO_ADDR_R, p, len >> 1); | 309 | ioread16_rep(chip->IO_ADDR_R, p, len >> 1); |
@@ -320,7 +320,7 @@ static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len) | |||
320 | static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) | 320 | static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) |
321 | { | 321 | { |
322 | int page, chipnr, res = 0, i = 0; | 322 | int page, chipnr, res = 0, i = 0; |
323 | struct nand_chip *chip = mtd->priv; | 323 | struct nand_chip *chip = mtd_to_nand(mtd); |
324 | u16 bad; | 324 | u16 bad; |
325 | 325 | ||
326 | if (chip->bbt_options & NAND_BBT_SCANLASTPAGE) | 326 | if (chip->bbt_options & NAND_BBT_SCANLASTPAGE) |
@@ -380,7 +380,7 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) | |||
380 | */ | 380 | */ |
381 | static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) | 381 | static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) |
382 | { | 382 | { |
383 | struct nand_chip *chip = mtd->priv; | 383 | struct nand_chip *chip = mtd_to_nand(mtd); |
384 | struct mtd_oob_ops ops; | 384 | struct mtd_oob_ops ops; |
385 | uint8_t buf[2] = { 0, 0 }; | 385 | uint8_t buf[2] = { 0, 0 }; |
386 | int ret = 0, res, i = 0; | 386 | int ret = 0, res, i = 0; |
@@ -430,7 +430,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) | |||
430 | */ | 430 | */ |
431 | static int nand_block_markbad_lowlevel(struct mtd_info *mtd, loff_t ofs) | 431 | static int nand_block_markbad_lowlevel(struct mtd_info *mtd, loff_t ofs) |
432 | { | 432 | { |
433 | struct nand_chip *chip = mtd->priv; | 433 | struct nand_chip *chip = mtd_to_nand(mtd); |
434 | int res, ret = 0; | 434 | int res, ret = 0; |
435 | 435 | ||
436 | if (!(chip->bbt_options & NAND_BBT_NO_OOB_BBM)) { | 436 | if (!(chip->bbt_options & NAND_BBT_NO_OOB_BBM)) { |
@@ -471,7 +471,7 @@ static int nand_block_markbad_lowlevel(struct mtd_info *mtd, loff_t ofs) | |||
471 | */ | 471 | */ |
472 | static int nand_check_wp(struct mtd_info *mtd) | 472 | static int nand_check_wp(struct mtd_info *mtd) |
473 | { | 473 | { |
474 | struct nand_chip *chip = mtd->priv; | 474 | struct nand_chip *chip = mtd_to_nand(mtd); |
475 | 475 | ||
476 | /* Broken xD cards report WP despite being writable */ | 476 | /* Broken xD cards report WP despite being writable */ |
477 | if (chip->options & NAND_BROKEN_XD) | 477 | if (chip->options & NAND_BROKEN_XD) |
@@ -491,7 +491,7 @@ static int nand_check_wp(struct mtd_info *mtd) | |||
491 | */ | 491 | */ |
492 | static int nand_block_isreserved(struct mtd_info *mtd, loff_t ofs) | 492 | static int nand_block_isreserved(struct mtd_info *mtd, loff_t ofs) |
493 | { | 493 | { |
494 | struct nand_chip *chip = mtd->priv; | 494 | struct nand_chip *chip = mtd_to_nand(mtd); |
495 | 495 | ||
496 | if (!chip->bbt) | 496 | if (!chip->bbt) |
497 | return 0; | 497 | return 0; |
@@ -512,7 +512,7 @@ static int nand_block_isreserved(struct mtd_info *mtd, loff_t ofs) | |||
512 | static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, | 512 | static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, |
513 | int allowbbt) | 513 | int allowbbt) |
514 | { | 514 | { |
515 | struct nand_chip *chip = mtd->priv; | 515 | struct nand_chip *chip = mtd_to_nand(mtd); |
516 | 516 | ||
517 | if (!chip->bbt) | 517 | if (!chip->bbt) |
518 | return chip->block_bad(mtd, ofs, getchip); | 518 | return chip->block_bad(mtd, ofs, getchip); |
@@ -531,7 +531,7 @@ static int nand_block_checkbad(struct mtd_info *mtd, loff_t ofs, int getchip, | |||
531 | */ | 531 | */ |
532 | static void panic_nand_wait_ready(struct mtd_info *mtd, unsigned long timeo) | 532 | static void panic_nand_wait_ready(struct mtd_info *mtd, unsigned long timeo) |
533 | { | 533 | { |
534 | struct nand_chip *chip = mtd->priv; | 534 | struct nand_chip *chip = mtd_to_nand(mtd); |
535 | int i; | 535 | int i; |
536 | 536 | ||
537 | /* Wait for the device to get ready */ | 537 | /* Wait for the device to get ready */ |
@@ -551,7 +551,7 @@ static void panic_nand_wait_ready(struct mtd_info *mtd, unsigned long timeo) | |||
551 | */ | 551 | */ |
552 | void nand_wait_ready(struct mtd_info *mtd) | 552 | void nand_wait_ready(struct mtd_info *mtd) |
553 | { | 553 | { |
554 | struct nand_chip *chip = mtd->priv; | 554 | struct nand_chip *chip = mtd_to_nand(mtd); |
555 | unsigned long timeo = 400; | 555 | unsigned long timeo = 400; |
556 | 556 | ||
557 | if (in_interrupt() || oops_in_progress) | 557 | if (in_interrupt() || oops_in_progress) |
@@ -582,7 +582,7 @@ EXPORT_SYMBOL_GPL(nand_wait_ready); | |||
582 | */ | 582 | */ |
583 | static void nand_wait_status_ready(struct mtd_info *mtd, unsigned long timeo) | 583 | static void nand_wait_status_ready(struct mtd_info *mtd, unsigned long timeo) |
584 | { | 584 | { |
585 | register struct nand_chip *chip = mtd->priv; | 585 | register struct nand_chip *chip = mtd_to_nand(mtd); |
586 | 586 | ||
587 | timeo = jiffies + msecs_to_jiffies(timeo); | 587 | timeo = jiffies + msecs_to_jiffies(timeo); |
588 | do { | 588 | do { |
@@ -605,7 +605,7 @@ static void nand_wait_status_ready(struct mtd_info *mtd, unsigned long timeo) | |||
605 | static void nand_command(struct mtd_info *mtd, unsigned int command, | 605 | static void nand_command(struct mtd_info *mtd, unsigned int command, |
606 | int column, int page_addr) | 606 | int column, int page_addr) |
607 | { | 607 | { |
608 | register struct nand_chip *chip = mtd->priv; | 608 | register struct nand_chip *chip = mtd_to_nand(mtd); |
609 | int ctrl = NAND_CTRL_CLE | NAND_CTRL_CHANGE; | 609 | int ctrl = NAND_CTRL_CLE | NAND_CTRL_CHANGE; |
610 | 610 | ||
611 | /* Write out the command to the device */ | 611 | /* Write out the command to the device */ |
@@ -708,7 +708,7 @@ static void nand_command(struct mtd_info *mtd, unsigned int command, | |||
708 | static void nand_command_lp(struct mtd_info *mtd, unsigned int command, | 708 | static void nand_command_lp(struct mtd_info *mtd, unsigned int command, |
709 | int column, int page_addr) | 709 | int column, int page_addr) |
710 | { | 710 | { |
711 | register struct nand_chip *chip = mtd->priv; | 711 | register struct nand_chip *chip = mtd_to_nand(mtd); |
712 | 712 | ||
713 | /* Emulate NAND_CMD_READOOB */ | 713 | /* Emulate NAND_CMD_READOOB */ |
714 | if (command == NAND_CMD_READOOB) { | 714 | if (command == NAND_CMD_READOOB) { |
@@ -832,7 +832,7 @@ static void panic_nand_get_device(struct nand_chip *chip, | |||
832 | static int | 832 | static int |
833 | nand_get_device(struct mtd_info *mtd, int new_state) | 833 | nand_get_device(struct mtd_info *mtd, int new_state) |
834 | { | 834 | { |
835 | struct nand_chip *chip = mtd->priv; | 835 | struct nand_chip *chip = mtd_to_nand(mtd); |
836 | spinlock_t *lock = &chip->controller->lock; | 836 | spinlock_t *lock = &chip->controller->lock; |
837 | wait_queue_head_t *wq = &chip->controller->wq; | 837 | wait_queue_head_t *wq = &chip->controller->wq; |
838 | DECLARE_WAITQUEUE(wait, current); | 838 | DECLARE_WAITQUEUE(wait, current); |
@@ -952,7 +952,7 @@ static int __nand_unlock(struct mtd_info *mtd, loff_t ofs, | |||
952 | { | 952 | { |
953 | int ret = 0; | 953 | int ret = 0; |
954 | int status, page; | 954 | int status, page; |
955 | struct nand_chip *chip = mtd->priv; | 955 | struct nand_chip *chip = mtd_to_nand(mtd); |
956 | 956 | ||
957 | /* Submit address of first page to unlock */ | 957 | /* Submit address of first page to unlock */ |
958 | page = ofs >> chip->page_shift; | 958 | page = ofs >> chip->page_shift; |
@@ -987,7 +987,7 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) | |||
987 | { | 987 | { |
988 | int ret = 0; | 988 | int ret = 0; |
989 | int chipnr; | 989 | int chipnr; |
990 | struct nand_chip *chip = mtd->priv; | 990 | struct nand_chip *chip = mtd_to_nand(mtd); |
991 | 991 | ||
992 | pr_debug("%s: start = 0x%012llx, len = %llu\n", | 992 | pr_debug("%s: start = 0x%012llx, len = %llu\n", |
993 | __func__, (unsigned long long)ofs, len); | 993 | __func__, (unsigned long long)ofs, len); |
@@ -1050,7 +1050,7 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) | |||
1050 | { | 1050 | { |
1051 | int ret = 0; | 1051 | int ret = 0; |
1052 | int chipnr, status, page; | 1052 | int chipnr, status, page; |
1053 | struct nand_chip *chip = mtd->priv; | 1053 | struct nand_chip *chip = mtd_to_nand(mtd); |
1054 | 1054 | ||
1055 | pr_debug("%s: start = 0x%012llx, len = %llu\n", | 1055 | pr_debug("%s: start = 0x%012llx, len = %llu\n", |
1056 | __func__, (unsigned long long)ofs, len); | 1056 | __func__, (unsigned long long)ofs, len); |
@@ -1426,6 +1426,16 @@ static int nand_read_subpage(struct mtd_info *mtd, struct nand_chip *chip, | |||
1426 | 1426 | ||
1427 | stat = chip->ecc.correct(mtd, p, | 1427 | stat = chip->ecc.correct(mtd, p, |
1428 | &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]); | 1428 | &chip->buffers->ecccode[i], &chip->buffers->ecccalc[i]); |
1429 | if (stat == -EBADMSG && | ||
1430 | (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { | ||
1431 | /* check for empty pages with bitflips */ | ||
1432 | stat = nand_check_erased_ecc_chunk(p, chip->ecc.size, | ||
1433 | &chip->buffers->ecccode[i], | ||
1434 | chip->ecc.bytes, | ||
1435 | NULL, 0, | ||
1436 | chip->ecc.strength); | ||
1437 | } | ||
1438 | |||
1429 | if (stat < 0) { | 1439 | if (stat < 0) { |
1430 | mtd->ecc_stats.failed++; | 1440 | mtd->ecc_stats.failed++; |
1431 | } else { | 1441 | } else { |
@@ -1475,6 +1485,15 @@ static int nand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
1475 | int stat; | 1485 | int stat; |
1476 | 1486 | ||
1477 | stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); | 1487 | stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]); |
1488 | if (stat == -EBADMSG && | ||
1489 | (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { | ||
1490 | /* check for empty pages with bitflips */ | ||
1491 | stat = nand_check_erased_ecc_chunk(p, eccsize, | ||
1492 | &ecc_code[i], eccbytes, | ||
1493 | NULL, 0, | ||
1494 | chip->ecc.strength); | ||
1495 | } | ||
1496 | |||
1478 | if (stat < 0) { | 1497 | if (stat < 0) { |
1479 | mtd->ecc_stats.failed++; | 1498 | mtd->ecc_stats.failed++; |
1480 | } else { | 1499 | } else { |
@@ -1527,6 +1546,15 @@ static int nand_read_page_hwecc_oob_first(struct mtd_info *mtd, | |||
1527 | chip->ecc.calculate(mtd, p, &ecc_calc[i]); | 1546 | chip->ecc.calculate(mtd, p, &ecc_calc[i]); |
1528 | 1547 | ||
1529 | stat = chip->ecc.correct(mtd, p, &ecc_code[i], NULL); | 1548 | stat = chip->ecc.correct(mtd, p, &ecc_code[i], NULL); |
1549 | if (stat == -EBADMSG && | ||
1550 | (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { | ||
1551 | /* check for empty pages with bitflips */ | ||
1552 | stat = nand_check_erased_ecc_chunk(p, eccsize, | ||
1553 | &ecc_code[i], eccbytes, | ||
1554 | NULL, 0, | ||
1555 | chip->ecc.strength); | ||
1556 | } | ||
1557 | |||
1530 | if (stat < 0) { | 1558 | if (stat < 0) { |
1531 | mtd->ecc_stats.failed++; | 1559 | mtd->ecc_stats.failed++; |
1532 | } else { | 1560 | } else { |
@@ -1554,6 +1582,7 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip, | |||
1554 | int i, eccsize = chip->ecc.size; | 1582 | int i, eccsize = chip->ecc.size; |
1555 | int eccbytes = chip->ecc.bytes; | 1583 | int eccbytes = chip->ecc.bytes; |
1556 | int eccsteps = chip->ecc.steps; | 1584 | int eccsteps = chip->ecc.steps; |
1585 | int eccpadbytes = eccbytes + chip->ecc.prepad + chip->ecc.postpad; | ||
1557 | uint8_t *p = buf; | 1586 | uint8_t *p = buf; |
1558 | uint8_t *oob = chip->oob_poi; | 1587 | uint8_t *oob = chip->oob_poi; |
1559 | unsigned int max_bitflips = 0; | 1588 | unsigned int max_bitflips = 0; |
@@ -1573,19 +1602,29 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip, | |||
1573 | chip->read_buf(mtd, oob, eccbytes); | 1602 | chip->read_buf(mtd, oob, eccbytes); |
1574 | stat = chip->ecc.correct(mtd, p, oob, NULL); | 1603 | stat = chip->ecc.correct(mtd, p, oob, NULL); |
1575 | 1604 | ||
1576 | if (stat < 0) { | ||
1577 | mtd->ecc_stats.failed++; | ||
1578 | } else { | ||
1579 | mtd->ecc_stats.corrected += stat; | ||
1580 | max_bitflips = max_t(unsigned int, max_bitflips, stat); | ||
1581 | } | ||
1582 | |||
1583 | oob += eccbytes; | 1605 | oob += eccbytes; |
1584 | 1606 | ||
1585 | if (chip->ecc.postpad) { | 1607 | if (chip->ecc.postpad) { |
1586 | chip->read_buf(mtd, oob, chip->ecc.postpad); | 1608 | chip->read_buf(mtd, oob, chip->ecc.postpad); |
1587 | oob += chip->ecc.postpad; | 1609 | oob += chip->ecc.postpad; |
1588 | } | 1610 | } |
1611 | |||
1612 | if (stat == -EBADMSG && | ||
1613 | (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { | ||
1614 | /* check for empty pages with bitflips */ | ||
1615 | stat = nand_check_erased_ecc_chunk(p, chip->ecc.size, | ||
1616 | oob - eccpadbytes, | ||
1617 | eccpadbytes, | ||
1618 | NULL, 0, | ||
1619 | chip->ecc.strength); | ||
1620 | } | ||
1621 | |||
1622 | if (stat < 0) { | ||
1623 | mtd->ecc_stats.failed++; | ||
1624 | } else { | ||
1625 | mtd->ecc_stats.corrected += stat; | ||
1626 | max_bitflips = max_t(unsigned int, max_bitflips, stat); | ||
1627 | } | ||
1589 | } | 1628 | } |
1590 | 1629 | ||
1591 | /* Calculate remaining oob bytes */ | 1630 | /* Calculate remaining oob bytes */ |
@@ -1655,7 +1694,7 @@ static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob, | |||
1655 | */ | 1694 | */ |
1656 | static int nand_setup_read_retry(struct mtd_info *mtd, int retry_mode) | 1695 | static int nand_setup_read_retry(struct mtd_info *mtd, int retry_mode) |
1657 | { | 1696 | { |
1658 | struct nand_chip *chip = mtd->priv; | 1697 | struct nand_chip *chip = mtd_to_nand(mtd); |
1659 | 1698 | ||
1660 | pr_debug("setting READ RETRY mode %d\n", retry_mode); | 1699 | pr_debug("setting READ RETRY mode %d\n", retry_mode); |
1661 | 1700 | ||
@@ -1680,7 +1719,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
1680 | struct mtd_oob_ops *ops) | 1719 | struct mtd_oob_ops *ops) |
1681 | { | 1720 | { |
1682 | int chipnr, page, realpage, col, bytes, aligned, oob_required; | 1721 | int chipnr, page, realpage, col, bytes, aligned, oob_required; |
1683 | struct nand_chip *chip = mtd->priv; | 1722 | struct nand_chip *chip = mtd_to_nand(mtd); |
1684 | int ret = 0; | 1723 | int ret = 0; |
1685 | uint32_t readlen = ops->len; | 1724 | uint32_t readlen = ops->len; |
1686 | uint32_t oobreadlen = ops->ooblen; | 1725 | uint32_t oobreadlen = ops->ooblen; |
@@ -2024,7 +2063,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, | |||
2024 | struct mtd_oob_ops *ops) | 2063 | struct mtd_oob_ops *ops) |
2025 | { | 2064 | { |
2026 | int page, realpage, chipnr; | 2065 | int page, realpage, chipnr; |
2027 | struct nand_chip *chip = mtd->priv; | 2066 | struct nand_chip *chip = mtd_to_nand(mtd); |
2028 | struct mtd_ecc_stats stats; | 2067 | struct mtd_ecc_stats stats; |
2029 | int readlen = ops->ooblen; | 2068 | int readlen = ops->ooblen; |
2030 | int len; | 2069 | int len; |
@@ -2472,7 +2511,7 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
2472 | static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len, | 2511 | static uint8_t *nand_fill_oob(struct mtd_info *mtd, uint8_t *oob, size_t len, |
2473 | struct mtd_oob_ops *ops) | 2512 | struct mtd_oob_ops *ops) |
2474 | { | 2513 | { |
2475 | struct nand_chip *chip = mtd->priv; | 2514 | struct nand_chip *chip = mtd_to_nand(mtd); |
2476 | 2515 | ||
2477 | /* | 2516 | /* |
2478 | * Initialise to all 0xFF, to avoid the possibility of left over OOB | 2517 | * Initialise to all 0xFF, to avoid the possibility of left over OOB |
@@ -2532,7 +2571,7 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, | |||
2532 | struct mtd_oob_ops *ops) | 2571 | struct mtd_oob_ops *ops) |
2533 | { | 2572 | { |
2534 | int chipnr, realpage, page, blockmask, column; | 2573 | int chipnr, realpage, page, blockmask, column; |
2535 | struct nand_chip *chip = mtd->priv; | 2574 | struct nand_chip *chip = mtd_to_nand(mtd); |
2536 | uint32_t writelen = ops->len; | 2575 | uint32_t writelen = ops->len; |
2537 | 2576 | ||
2538 | uint32_t oobwritelen = ops->ooblen; | 2577 | uint32_t oobwritelen = ops->ooblen; |
@@ -2662,7 +2701,7 @@ err_out: | |||
2662 | static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len, | 2701 | static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len, |
2663 | size_t *retlen, const uint8_t *buf) | 2702 | size_t *retlen, const uint8_t *buf) |
2664 | { | 2703 | { |
2665 | struct nand_chip *chip = mtd->priv; | 2704 | struct nand_chip *chip = mtd_to_nand(mtd); |
2666 | struct mtd_oob_ops ops; | 2705 | struct mtd_oob_ops ops; |
2667 | int ret; | 2706 | int ret; |
2668 | 2707 | ||
@@ -2722,7 +2761,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, | |||
2722 | struct mtd_oob_ops *ops) | 2761 | struct mtd_oob_ops *ops) |
2723 | { | 2762 | { |
2724 | int chipnr, page, status, len; | 2763 | int chipnr, page, status, len; |
2725 | struct nand_chip *chip = mtd->priv; | 2764 | struct nand_chip *chip = mtd_to_nand(mtd); |
2726 | 2765 | ||
2727 | pr_debug("%s: to = 0x%08x, len = %i\n", | 2766 | pr_debug("%s: to = 0x%08x, len = %i\n", |
2728 | __func__, (unsigned int)to, (int)ops->ooblen); | 2767 | __func__, (unsigned int)to, (int)ops->ooblen); |
@@ -2847,7 +2886,7 @@ out: | |||
2847 | */ | 2886 | */ |
2848 | static int single_erase(struct mtd_info *mtd, int page) | 2887 | static int single_erase(struct mtd_info *mtd, int page) |
2849 | { | 2888 | { |
2850 | struct nand_chip *chip = mtd->priv; | 2889 | struct nand_chip *chip = mtd_to_nand(mtd); |
2851 | /* Send commands to erase a block */ | 2890 | /* Send commands to erase a block */ |
2852 | chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page); | 2891 | chip->cmdfunc(mtd, NAND_CMD_ERASE1, -1, page); |
2853 | chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1); | 2892 | chip->cmdfunc(mtd, NAND_CMD_ERASE2, -1, -1); |
@@ -2879,7 +2918,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, | |||
2879 | int allowbbt) | 2918 | int allowbbt) |
2880 | { | 2919 | { |
2881 | int page, status, pages_per_block, ret, chipnr; | 2920 | int page, status, pages_per_block, ret, chipnr; |
2882 | struct nand_chip *chip = mtd->priv; | 2921 | struct nand_chip *chip = mtd_to_nand(mtd); |
2883 | loff_t len; | 2922 | loff_t len; |
2884 | 2923 | ||
2885 | pr_debug("%s: start = 0x%012llx, len = %llu\n", | 2924 | pr_debug("%s: start = 0x%012llx, len = %llu\n", |
@@ -3094,7 +3133,7 @@ static int nand_suspend(struct mtd_info *mtd) | |||
3094 | */ | 3133 | */ |
3095 | static void nand_resume(struct mtd_info *mtd) | 3134 | static void nand_resume(struct mtd_info *mtd) |
3096 | { | 3135 | { |
3097 | struct nand_chip *chip = mtd->priv; | 3136 | struct nand_chip *chip = mtd_to_nand(mtd); |
3098 | 3137 | ||
3099 | if (chip->state == FL_PM_SUSPENDED) | 3138 | if (chip->state == FL_PM_SUSPENDED) |
3100 | nand_release_device(mtd); | 3139 | nand_release_device(mtd); |
@@ -3266,7 +3305,7 @@ ext_out: | |||
3266 | 3305 | ||
3267 | static int nand_setup_read_retry_micron(struct mtd_info *mtd, int retry_mode) | 3306 | static int nand_setup_read_retry_micron(struct mtd_info *mtd, int retry_mode) |
3268 | { | 3307 | { |
3269 | struct nand_chip *chip = mtd->priv; | 3308 | struct nand_chip *chip = mtd_to_nand(mtd); |
3270 | uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {retry_mode}; | 3309 | uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {retry_mode}; |
3271 | 3310 | ||
3272 | return chip->onfi_set_features(mtd, chip, ONFI_FEATURE_ADDR_READ_RETRY, | 3311 | return chip->onfi_set_features(mtd, chip, ONFI_FEATURE_ADDR_READ_RETRY, |
@@ -3937,11 +3976,14 @@ ident_done: | |||
3937 | return type; | 3976 | return type; |
3938 | } | 3977 | } |
3939 | 3978 | ||
3940 | static int nand_dt_init(struct mtd_info *mtd, struct nand_chip *chip, | 3979 | static int nand_dt_init(struct nand_chip *chip) |
3941 | struct device_node *dn) | ||
3942 | { | 3980 | { |
3981 | struct device_node *dn = nand_get_flash_node(chip); | ||
3943 | int ecc_mode, ecc_strength, ecc_step; | 3982 | int ecc_mode, ecc_strength, ecc_step; |
3944 | 3983 | ||
3984 | if (!dn) | ||
3985 | return 0; | ||
3986 | |||
3945 | if (of_get_nand_bus_width(dn) == 16) | 3987 | if (of_get_nand_bus_width(dn) == 16) |
3946 | chip->options |= NAND_BUSWIDTH_16; | 3988 | chip->options |= NAND_BUSWIDTH_16; |
3947 | 3989 | ||
@@ -3985,15 +4027,16 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, | |||
3985 | struct nand_flash_dev *table) | 4027 | struct nand_flash_dev *table) |
3986 | { | 4028 | { |
3987 | int i, nand_maf_id, nand_dev_id; | 4029 | int i, nand_maf_id, nand_dev_id; |
3988 | struct nand_chip *chip = mtd->priv; | 4030 | struct nand_chip *chip = mtd_to_nand(mtd); |
3989 | struct nand_flash_dev *type; | 4031 | struct nand_flash_dev *type; |
3990 | int ret; | 4032 | int ret; |
3991 | 4033 | ||
3992 | if (chip->flash_node) { | 4034 | ret = nand_dt_init(chip); |
3993 | ret = nand_dt_init(mtd, chip, chip->flash_node); | 4035 | if (ret) |
3994 | if (ret) | 4036 | return ret; |
3995 | return ret; | 4037 | |
3996 | } | 4038 | if (!mtd->name && mtd->dev.parent) |
4039 | mtd->name = dev_name(mtd->dev.parent); | ||
3997 | 4040 | ||
3998 | /* Set the default functions */ | 4041 | /* Set the default functions */ |
3999 | nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16); | 4042 | nand_set_defaults(chip, chip->options & NAND_BUSWIDTH_16); |
@@ -4053,7 +4096,7 @@ EXPORT_SYMBOL(nand_scan_ident); | |||
4053 | */ | 4096 | */ |
4054 | static bool nand_ecc_strength_good(struct mtd_info *mtd) | 4097 | static bool nand_ecc_strength_good(struct mtd_info *mtd) |
4055 | { | 4098 | { |
4056 | struct nand_chip *chip = mtd->priv; | 4099 | struct nand_chip *chip = mtd_to_nand(mtd); |
4057 | struct nand_ecc_ctrl *ecc = &chip->ecc; | 4100 | struct nand_ecc_ctrl *ecc = &chip->ecc; |
4058 | int corr, ds_corr; | 4101 | int corr, ds_corr; |
4059 | 4102 | ||
@@ -4082,7 +4125,7 @@ static bool nand_ecc_strength_good(struct mtd_info *mtd) | |||
4082 | int nand_scan_tail(struct mtd_info *mtd) | 4125 | int nand_scan_tail(struct mtd_info *mtd) |
4083 | { | 4126 | { |
4084 | int i; | 4127 | int i; |
4085 | struct nand_chip *chip = mtd->priv; | 4128 | struct nand_chip *chip = mtd_to_nand(mtd); |
4086 | struct nand_ecc_ctrl *ecc = &chip->ecc; | 4129 | struct nand_ecc_ctrl *ecc = &chip->ecc; |
4087 | struct nand_buffers *nbuf; | 4130 | struct nand_buffers *nbuf; |
4088 | 4131 | ||
@@ -4166,7 +4209,7 @@ int nand_scan_tail(struct mtd_info *mtd) | |||
4166 | ecc->write_oob = nand_write_oob_std; | 4209 | ecc->write_oob = nand_write_oob_std; |
4167 | if (!ecc->read_subpage) | 4210 | if (!ecc->read_subpage) |
4168 | ecc->read_subpage = nand_read_subpage; | 4211 | ecc->read_subpage = nand_read_subpage; |
4169 | if (!ecc->write_subpage) | 4212 | if (!ecc->write_subpage && ecc->hwctl && ecc->calculate) |
4170 | ecc->write_subpage = nand_write_subpage_hwecc; | 4213 | ecc->write_subpage = nand_write_subpage_hwecc; |
4171 | 4214 | ||
4172 | case NAND_ECC_HW_SYNDROME: | 4215 | case NAND_ECC_HW_SYNDROME: |
@@ -4426,7 +4469,7 @@ EXPORT_SYMBOL(nand_scan); | |||
4426 | */ | 4469 | */ |
4427 | void nand_release(struct mtd_info *mtd) | 4470 | void nand_release(struct mtd_info *mtd) |
4428 | { | 4471 | { |
4429 | struct nand_chip *chip = mtd->priv; | 4472 | struct nand_chip *chip = mtd_to_nand(mtd); |
4430 | 4473 | ||
4431 | if (chip->ecc.mode == NAND_ECC_SOFT_BCH) | 4474 | if (chip->ecc.mode == NAND_ECC_SOFT_BCH) |
4432 | nand_bch_free((struct nand_bch_control *)chip->ecc.priv); | 4475 | nand_bch_free((struct nand_bch_control *)chip->ecc.priv); |
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index b1d4f813aedc..4b6a7085b442 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c | |||
@@ -172,7 +172,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, | |||
172 | struct nand_bbt_descr *td, int offs) | 172 | struct nand_bbt_descr *td, int offs) |
173 | { | 173 | { |
174 | int res, ret = 0, i, j, act = 0; | 174 | int res, ret = 0, i, j, act = 0; |
175 | struct nand_chip *this = mtd->priv; | 175 | struct nand_chip *this = mtd_to_nand(mtd); |
176 | size_t retlen, len, totlen; | 176 | size_t retlen, len, totlen; |
177 | loff_t from; | 177 | loff_t from; |
178 | int bits = td->options & NAND_BBT_NRBITS_MSK; | 178 | int bits = td->options & NAND_BBT_NRBITS_MSK; |
@@ -263,7 +263,7 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, | |||
263 | */ | 263 | */ |
264 | static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip) | 264 | static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip) |
265 | { | 265 | { |
266 | struct nand_chip *this = mtd->priv; | 266 | struct nand_chip *this = mtd_to_nand(mtd); |
267 | int res = 0, i; | 267 | int res = 0, i; |
268 | 268 | ||
269 | if (td->options & NAND_BBT_PERCHIP) { | 269 | if (td->options & NAND_BBT_PERCHIP) { |
@@ -388,7 +388,7 @@ static u32 bbt_get_ver_offs(struct mtd_info *mtd, struct nand_bbt_descr *td) | |||
388 | static void read_abs_bbts(struct mtd_info *mtd, uint8_t *buf, | 388 | static void read_abs_bbts(struct mtd_info *mtd, uint8_t *buf, |
389 | struct nand_bbt_descr *td, struct nand_bbt_descr *md) | 389 | struct nand_bbt_descr *td, struct nand_bbt_descr *md) |
390 | { | 390 | { |
391 | struct nand_chip *this = mtd->priv; | 391 | struct nand_chip *this = mtd_to_nand(mtd); |
392 | 392 | ||
393 | /* Read the primary version, if available */ | 393 | /* Read the primary version, if available */ |
394 | if (td->options & NAND_BBT_VERSION) { | 394 | if (td->options & NAND_BBT_VERSION) { |
@@ -454,7 +454,7 @@ static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd, | |||
454 | static int create_bbt(struct mtd_info *mtd, uint8_t *buf, | 454 | static int create_bbt(struct mtd_info *mtd, uint8_t *buf, |
455 | struct nand_bbt_descr *bd, int chip) | 455 | struct nand_bbt_descr *bd, int chip) |
456 | { | 456 | { |
457 | struct nand_chip *this = mtd->priv; | 457 | struct nand_chip *this = mtd_to_nand(mtd); |
458 | int i, numblocks, numpages; | 458 | int i, numblocks, numpages; |
459 | int startblock; | 459 | int startblock; |
460 | loff_t from; | 460 | loff_t from; |
@@ -523,7 +523,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, | |||
523 | */ | 523 | */ |
524 | static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td) | 524 | static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td) |
525 | { | 525 | { |
526 | struct nand_chip *this = mtd->priv; | 526 | struct nand_chip *this = mtd_to_nand(mtd); |
527 | int i, chips; | 527 | int i, chips; |
528 | int startblock, block, dir; | 528 | int startblock, block, dir; |
529 | int scanlen = mtd->writesize + mtd->oobsize; | 529 | int scanlen = mtd->writesize + mtd->oobsize; |
@@ -618,7 +618,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, | |||
618 | struct nand_bbt_descr *td, struct nand_bbt_descr *md, | 618 | struct nand_bbt_descr *td, struct nand_bbt_descr *md, |
619 | int chipsel) | 619 | int chipsel) |
620 | { | 620 | { |
621 | struct nand_chip *this = mtd->priv; | 621 | struct nand_chip *this = mtd_to_nand(mtd); |
622 | struct erase_info einfo; | 622 | struct erase_info einfo; |
623 | int i, res, chip = 0; | 623 | int i, res, chip = 0; |
624 | int bits, startblock, dir, page, offs, numblocks, sft, sftmsk; | 624 | int bits, startblock, dir, page, offs, numblocks, sft, sftmsk; |
@@ -819,7 +819,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, | |||
819 | */ | 819 | */ |
820 | static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) | 820 | static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) |
821 | { | 821 | { |
822 | struct nand_chip *this = mtd->priv; | 822 | struct nand_chip *this = mtd_to_nand(mtd); |
823 | 823 | ||
824 | return create_bbt(mtd, this->buffers->databuf, bd, -1); | 824 | return create_bbt(mtd, this->buffers->databuf, bd, -1); |
825 | } | 825 | } |
@@ -838,7 +838,7 @@ static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *b | |||
838 | static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd) | 838 | static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd) |
839 | { | 839 | { |
840 | int i, chips, writeops, create, chipsel, res, res2; | 840 | int i, chips, writeops, create, chipsel, res, res2; |
841 | struct nand_chip *this = mtd->priv; | 841 | struct nand_chip *this = mtd_to_nand(mtd); |
842 | struct nand_bbt_descr *td = this->bbt_td; | 842 | struct nand_bbt_descr *td = this->bbt_td; |
843 | struct nand_bbt_descr *md = this->bbt_md; | 843 | struct nand_bbt_descr *md = this->bbt_md; |
844 | struct nand_bbt_descr *rd, *rd2; | 844 | struct nand_bbt_descr *rd, *rd2; |
@@ -962,7 +962,7 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc | |||
962 | */ | 962 | */ |
963 | static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td) | 963 | static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td) |
964 | { | 964 | { |
965 | struct nand_chip *this = mtd->priv; | 965 | struct nand_chip *this = mtd_to_nand(mtd); |
966 | int i, j, chips, block, nrblocks, update; | 966 | int i, j, chips, block, nrblocks, update; |
967 | uint8_t oldval; | 967 | uint8_t oldval; |
968 | 968 | ||
@@ -1022,7 +1022,7 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td) | |||
1022 | */ | 1022 | */ |
1023 | static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd) | 1023 | static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd) |
1024 | { | 1024 | { |
1025 | struct nand_chip *this = mtd->priv; | 1025 | struct nand_chip *this = mtd_to_nand(mtd); |
1026 | u32 pattern_len; | 1026 | u32 pattern_len; |
1027 | u32 bits; | 1027 | u32 bits; |
1028 | u32 table_size; | 1028 | u32 table_size; |
@@ -1074,7 +1074,7 @@ static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd) | |||
1074 | */ | 1074 | */ |
1075 | static int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) | 1075 | static int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) |
1076 | { | 1076 | { |
1077 | struct nand_chip *this = mtd->priv; | 1077 | struct nand_chip *this = mtd_to_nand(mtd); |
1078 | int len, res; | 1078 | int len, res; |
1079 | uint8_t *buf; | 1079 | uint8_t *buf; |
1080 | struct nand_bbt_descr *td = this->bbt_td; | 1080 | struct nand_bbt_descr *td = this->bbt_td; |
@@ -1147,7 +1147,7 @@ err: | |||
1147 | */ | 1147 | */ |
1148 | static int nand_update_bbt(struct mtd_info *mtd, loff_t offs) | 1148 | static int nand_update_bbt(struct mtd_info *mtd, loff_t offs) |
1149 | { | 1149 | { |
1150 | struct nand_chip *this = mtd->priv; | 1150 | struct nand_chip *this = mtd_to_nand(mtd); |
1151 | int len, res = 0; | 1151 | int len, res = 0; |
1152 | int chip, chipsel; | 1152 | int chip, chipsel; |
1153 | uint8_t *buf; | 1153 | uint8_t *buf; |
@@ -1281,7 +1281,7 @@ static int nand_create_badblock_pattern(struct nand_chip *this) | |||
1281 | */ | 1281 | */ |
1282 | int nand_default_bbt(struct mtd_info *mtd) | 1282 | int nand_default_bbt(struct mtd_info *mtd) |
1283 | { | 1283 | { |
1284 | struct nand_chip *this = mtd->priv; | 1284 | struct nand_chip *this = mtd_to_nand(mtd); |
1285 | int ret; | 1285 | int ret; |
1286 | 1286 | ||
1287 | /* Is a flash based bad block table requested? */ | 1287 | /* Is a flash based bad block table requested? */ |
@@ -1317,7 +1317,7 @@ int nand_default_bbt(struct mtd_info *mtd) | |||
1317 | */ | 1317 | */ |
1318 | int nand_isreserved_bbt(struct mtd_info *mtd, loff_t offs) | 1318 | int nand_isreserved_bbt(struct mtd_info *mtd, loff_t offs) |
1319 | { | 1319 | { |
1320 | struct nand_chip *this = mtd->priv; | 1320 | struct nand_chip *this = mtd_to_nand(mtd); |
1321 | int block; | 1321 | int block; |
1322 | 1322 | ||
1323 | block = (int)(offs >> this->bbt_erase_shift); | 1323 | block = (int)(offs >> this->bbt_erase_shift); |
@@ -1332,7 +1332,7 @@ int nand_isreserved_bbt(struct mtd_info *mtd, loff_t offs) | |||
1332 | */ | 1332 | */ |
1333 | int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt) | 1333 | int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt) |
1334 | { | 1334 | { |
1335 | struct nand_chip *this = mtd->priv; | 1335 | struct nand_chip *this = mtd_to_nand(mtd); |
1336 | int block, res; | 1336 | int block, res; |
1337 | 1337 | ||
1338 | block = (int)(offs >> this->bbt_erase_shift); | 1338 | block = (int)(offs >> this->bbt_erase_shift); |
@@ -1359,7 +1359,7 @@ int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt) | |||
1359 | */ | 1359 | */ |
1360 | int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs) | 1360 | int nand_markbad_bbt(struct mtd_info *mtd, loff_t offs) |
1361 | { | 1361 | { |
1362 | struct nand_chip *this = mtd->priv; | 1362 | struct nand_chip *this = mtd_to_nand(mtd); |
1363 | int block, ret = 0; | 1363 | int block, ret = 0; |
1364 | 1364 | ||
1365 | block = (int)(offs >> this->bbt_erase_shift); | 1365 | block = (int)(offs >> this->bbt_erase_shift); |
diff --git a/drivers/mtd/nand/nand_bch.c b/drivers/mtd/nand/nand_bch.c index 3803e0bba23b..a87c1b628dfc 100644 --- a/drivers/mtd/nand/nand_bch.c +++ b/drivers/mtd/nand/nand_bch.c | |||
@@ -52,7 +52,7 @@ struct nand_bch_control { | |||
52 | int nand_bch_calculate_ecc(struct mtd_info *mtd, const unsigned char *buf, | 52 | int nand_bch_calculate_ecc(struct mtd_info *mtd, const unsigned char *buf, |
53 | unsigned char *code) | 53 | unsigned char *code) |
54 | { | 54 | { |
55 | const struct nand_chip *chip = mtd->priv; | 55 | const struct nand_chip *chip = mtd_to_nand(mtd); |
56 | struct nand_bch_control *nbc = chip->ecc.priv; | 56 | struct nand_bch_control *nbc = chip->ecc.priv; |
57 | unsigned int i; | 57 | unsigned int i; |
58 | 58 | ||
@@ -79,7 +79,7 @@ EXPORT_SYMBOL(nand_bch_calculate_ecc); | |||
79 | int nand_bch_correct_data(struct mtd_info *mtd, unsigned char *buf, | 79 | int nand_bch_correct_data(struct mtd_info *mtd, unsigned char *buf, |
80 | unsigned char *read_ecc, unsigned char *calc_ecc) | 80 | unsigned char *read_ecc, unsigned char *calc_ecc) |
81 | { | 81 | { |
82 | const struct nand_chip *chip = mtd->priv; | 82 | const struct nand_chip *chip = mtd_to_nand(mtd); |
83 | struct nand_bch_control *nbc = chip->ecc.priv; | 83 | struct nand_bch_control *nbc = chip->ecc.priv; |
84 | unsigned int *errloc = nbc->errloc; | 84 | unsigned int *errloc = nbc->errloc; |
85 | int i, count; | 85 | int i, count; |
@@ -98,7 +98,7 @@ int nand_bch_correct_data(struct mtd_info *mtd, unsigned char *buf, | |||
98 | } | 98 | } |
99 | } else if (count < 0) { | 99 | } else if (count < 0) { |
100 | printk(KERN_ERR "ecc unrecoverable error\n"); | 100 | printk(KERN_ERR "ecc unrecoverable error\n"); |
101 | count = -1; | 101 | count = -EBADMSG; |
102 | } | 102 | } |
103 | return count; | 103 | return count; |
104 | } | 104 | } |
diff --git a/drivers/mtd/nand/nand_ecc.c b/drivers/mtd/nand/nand_ecc.c index 97c4c0216c90..d1770b066396 100644 --- a/drivers/mtd/nand/nand_ecc.c +++ b/drivers/mtd/nand/nand_ecc.c | |||
@@ -424,7 +424,7 @@ int nand_calculate_ecc(struct mtd_info *mtd, const unsigned char *buf, | |||
424 | unsigned char *code) | 424 | unsigned char *code) |
425 | { | 425 | { |
426 | __nand_calculate_ecc(buf, | 426 | __nand_calculate_ecc(buf, |
427 | ((struct nand_chip *)mtd->priv)->ecc.size, code); | 427 | mtd_to_nand(mtd)->ecc.size, code); |
428 | 428 | ||
429 | return 0; | 429 | return 0; |
430 | } | 430 | } |
@@ -507,7 +507,7 @@ int __nand_correct_data(unsigned char *buf, | |||
507 | return 1; /* error in ECC data; no action needed */ | 507 | return 1; /* error in ECC data; no action needed */ |
508 | 508 | ||
509 | pr_err("%s: uncorrectable ECC error\n", __func__); | 509 | pr_err("%s: uncorrectable ECC error\n", __func__); |
510 | return -1; | 510 | return -EBADMSG; |
511 | } | 511 | } |
512 | EXPORT_SYMBOL(__nand_correct_data); | 512 | EXPORT_SYMBOL(__nand_correct_data); |
513 | 513 | ||
@@ -524,7 +524,7 @@ int nand_correct_data(struct mtd_info *mtd, unsigned char *buf, | |||
524 | unsigned char *read_ecc, unsigned char *calc_ecc) | 524 | unsigned char *read_ecc, unsigned char *calc_ecc) |
525 | { | 525 | { |
526 | return __nand_correct_data(buf, read_ecc, calc_ecc, | 526 | return __nand_correct_data(buf, read_ecc, calc_ecc, |
527 | ((struct nand_chip *)mtd->priv)->ecc.size); | 527 | mtd_to_nand(mtd)->ecc.size); |
528 | } | 528 | } |
529 | EXPORT_SYMBOL(nand_correct_data); | 529 | EXPORT_SYMBOL(nand_correct_data); |
530 | 530 | ||
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index b16d70aafd9e..1fd519503bb1 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c | |||
@@ -666,8 +666,8 @@ static char *get_partition_name(int i) | |||
666 | */ | 666 | */ |
667 | static int init_nandsim(struct mtd_info *mtd) | 667 | static int init_nandsim(struct mtd_info *mtd) |
668 | { | 668 | { |
669 | struct nand_chip *chip = mtd->priv; | 669 | struct nand_chip *chip = mtd_to_nand(mtd); |
670 | struct nandsim *ns = chip->priv; | 670 | struct nandsim *ns = nand_get_controller_data(chip); |
671 | int i, ret = 0; | 671 | int i, ret = 0; |
672 | uint64_t remains; | 672 | uint64_t remains; |
673 | uint64_t next_offset; | 673 | uint64_t next_offset; |
@@ -1908,7 +1908,8 @@ static void switch_state(struct nandsim *ns) | |||
1908 | 1908 | ||
1909 | static u_char ns_nand_read_byte(struct mtd_info *mtd) | 1909 | static u_char ns_nand_read_byte(struct mtd_info *mtd) |
1910 | { | 1910 | { |
1911 | struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv; | 1911 | struct nand_chip *chip = mtd_to_nand(mtd); |
1912 | struct nandsim *ns = nand_get_controller_data(chip); | ||
1912 | u_char outb = 0x00; | 1913 | u_char outb = 0x00; |
1913 | 1914 | ||
1914 | /* Sanity and correctness checks */ | 1915 | /* Sanity and correctness checks */ |
@@ -1969,7 +1970,8 @@ static u_char ns_nand_read_byte(struct mtd_info *mtd) | |||
1969 | 1970 | ||
1970 | static void ns_nand_write_byte(struct mtd_info *mtd, u_char byte) | 1971 | static void ns_nand_write_byte(struct mtd_info *mtd, u_char byte) |
1971 | { | 1972 | { |
1972 | struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv; | 1973 | struct nand_chip *chip = mtd_to_nand(mtd); |
1974 | struct nandsim *ns = nand_get_controller_data(chip); | ||
1973 | 1975 | ||
1974 | /* Sanity and correctness checks */ | 1976 | /* Sanity and correctness checks */ |
1975 | if (!ns->lines.ce) { | 1977 | if (!ns->lines.ce) { |
@@ -2123,7 +2125,8 @@ static void ns_nand_write_byte(struct mtd_info *mtd, u_char byte) | |||
2123 | 2125 | ||
2124 | static void ns_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int bitmask) | 2126 | static void ns_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int bitmask) |
2125 | { | 2127 | { |
2126 | struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv; | 2128 | struct nand_chip *chip = mtd_to_nand(mtd); |
2129 | struct nandsim *ns = nand_get_controller_data(chip); | ||
2127 | 2130 | ||
2128 | ns->lines.cle = bitmask & NAND_CLE ? 1 : 0; | 2131 | ns->lines.cle = bitmask & NAND_CLE ? 1 : 0; |
2129 | ns->lines.ale = bitmask & NAND_ALE ? 1 : 0; | 2132 | ns->lines.ale = bitmask & NAND_ALE ? 1 : 0; |
@@ -2141,7 +2144,7 @@ static int ns_device_ready(struct mtd_info *mtd) | |||
2141 | 2144 | ||
2142 | static uint16_t ns_nand_read_word(struct mtd_info *mtd) | 2145 | static uint16_t ns_nand_read_word(struct mtd_info *mtd) |
2143 | { | 2146 | { |
2144 | struct nand_chip *chip = (struct nand_chip *)mtd->priv; | 2147 | struct nand_chip *chip = mtd_to_nand(mtd); |
2145 | 2148 | ||
2146 | NS_DBG("read_word\n"); | 2149 | NS_DBG("read_word\n"); |
2147 | 2150 | ||
@@ -2150,7 +2153,8 @@ static uint16_t ns_nand_read_word(struct mtd_info *mtd) | |||
2150 | 2153 | ||
2151 | static void ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) | 2154 | static void ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) |
2152 | { | 2155 | { |
2153 | struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv; | 2156 | struct nand_chip *chip = mtd_to_nand(mtd); |
2157 | struct nandsim *ns = nand_get_controller_data(chip); | ||
2154 | 2158 | ||
2155 | /* Check that chip is expecting data input */ | 2159 | /* Check that chip is expecting data input */ |
2156 | if (!(ns->state & STATE_DATAIN_MASK)) { | 2160 | if (!(ns->state & STATE_DATAIN_MASK)) { |
@@ -2177,7 +2181,8 @@ static void ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) | |||
2177 | 2181 | ||
2178 | static void ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) | 2182 | static void ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) |
2179 | { | 2183 | { |
2180 | struct nandsim *ns = ((struct nand_chip *)mtd->priv)->priv; | 2184 | struct nand_chip *chip = mtd_to_nand(mtd); |
2185 | struct nandsim *ns = nand_get_controller_data(chip); | ||
2181 | 2186 | ||
2182 | /* Sanity and correctness checks */ | 2187 | /* Sanity and correctness checks */ |
2183 | if (!ns->lines.ce) { | 2188 | if (!ns->lines.ce) { |
@@ -2198,7 +2203,7 @@ static void ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) | |||
2198 | int i; | 2203 | int i; |
2199 | 2204 | ||
2200 | for (i = 0; i < len; i++) | 2205 | for (i = 0; i < len; i++) |
2201 | buf[i] = ((struct nand_chip *)mtd->priv)->read_byte(mtd); | 2206 | buf[i] = mtd_to_nand(mtd)->read_byte(mtd); |
2202 | 2207 | ||
2203 | return; | 2208 | return; |
2204 | } | 2209 | } |
@@ -2236,16 +2241,15 @@ static int __init ns_init_module(void) | |||
2236 | } | 2241 | } |
2237 | 2242 | ||
2238 | /* Allocate and initialize mtd_info, nand_chip and nandsim structures */ | 2243 | /* Allocate and initialize mtd_info, nand_chip and nandsim structures */ |
2239 | nsmtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip) | 2244 | chip = kzalloc(sizeof(struct nand_chip) + sizeof(struct nandsim), |
2240 | + sizeof(struct nandsim), GFP_KERNEL); | 2245 | GFP_KERNEL); |
2241 | if (!nsmtd) { | 2246 | if (!chip) { |
2242 | NS_ERR("unable to allocate core structures.\n"); | 2247 | NS_ERR("unable to allocate core structures.\n"); |
2243 | return -ENOMEM; | 2248 | return -ENOMEM; |
2244 | } | 2249 | } |
2245 | chip = (struct nand_chip *)(nsmtd + 1); | 2250 | nsmtd = nand_to_mtd(chip); |
2246 | nsmtd->priv = (void *)chip; | ||
2247 | nand = (struct nandsim *)(chip + 1); | 2251 | nand = (struct nandsim *)(chip + 1); |
2248 | chip->priv = (void *)nand; | 2252 | nand_set_controller_data(chip, (void *)nand); |
2249 | 2253 | ||
2250 | /* | 2254 | /* |
2251 | * Register simulator's callbacks. | 2255 | * Register simulator's callbacks. |
@@ -2392,7 +2396,7 @@ err_exit: | |||
2392 | for (i = 0;i < ARRAY_SIZE(nand->partitions); ++i) | 2396 | for (i = 0;i < ARRAY_SIZE(nand->partitions); ++i) |
2393 | kfree(nand->partitions[i].name); | 2397 | kfree(nand->partitions[i].name); |
2394 | error: | 2398 | error: |
2395 | kfree(nsmtd); | 2399 | kfree(chip); |
2396 | free_lists(); | 2400 | free_lists(); |
2397 | 2401 | ||
2398 | return retval; | 2402 | return retval; |
@@ -2405,7 +2409,8 @@ module_init(ns_init_module); | |||
2405 | */ | 2409 | */ |
2406 | static void __exit ns_cleanup_module(void) | 2410 | static void __exit ns_cleanup_module(void) |
2407 | { | 2411 | { |
2408 | struct nandsim *ns = ((struct nand_chip *)nsmtd->priv)->priv; | 2412 | struct nand_chip *chip = mtd_to_nand(nsmtd); |
2413 | struct nandsim *ns = nand_get_controller_data(chip); | ||
2409 | int i; | 2414 | int i; |
2410 | 2415 | ||
2411 | nandsim_debugfs_remove(ns); | 2416 | nandsim_debugfs_remove(ns); |
@@ -2413,7 +2418,7 @@ static void __exit ns_cleanup_module(void) | |||
2413 | nand_release(nsmtd); /* Unregister driver */ | 2418 | nand_release(nsmtd); /* Unregister driver */ |
2414 | for (i = 0;i < ARRAY_SIZE(ns->partitions); ++i) | 2419 | for (i = 0;i < ARRAY_SIZE(ns->partitions); ++i) |
2415 | kfree(ns->partitions[i].name); | 2420 | kfree(ns->partitions[i].name); |
2416 | kfree(nsmtd); /* Free other structures */ | 2421 | kfree(mtd_to_nand(nsmtd)); /* Free other structures */ |
2417 | free_lists(); | 2422 | free_lists(); |
2418 | } | 2423 | } |
2419 | 2424 | ||
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index 4f0d62f9d22c..218c789ca7ab 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c | |||
@@ -37,7 +37,6 @@ | |||
37 | struct ndfc_controller { | 37 | struct ndfc_controller { |
38 | struct platform_device *ofdev; | 38 | struct platform_device *ofdev; |
39 | void __iomem *ndfcbase; | 39 | void __iomem *ndfcbase; |
40 | struct mtd_info mtd; | ||
41 | struct nand_chip chip; | 40 | struct nand_chip chip; |
42 | int chip_select; | 41 | int chip_select; |
43 | struct nand_hw_control ndfc_control; | 42 | struct nand_hw_control ndfc_control; |
@@ -48,8 +47,8 @@ static struct ndfc_controller ndfc_ctrl[NDFC_MAX_CS]; | |||
48 | static void ndfc_select_chip(struct mtd_info *mtd, int chip) | 47 | static void ndfc_select_chip(struct mtd_info *mtd, int chip) |
49 | { | 48 | { |
50 | uint32_t ccr; | 49 | uint32_t ccr; |
51 | struct nand_chip *nchip = mtd->priv; | 50 | struct nand_chip *nchip = mtd_to_nand(mtd); |
52 | struct ndfc_controller *ndfc = nchip->priv; | 51 | struct ndfc_controller *ndfc = nand_get_controller_data(nchip); |
53 | 52 | ||
54 | ccr = in_be32(ndfc->ndfcbase + NDFC_CCR); | 53 | ccr = in_be32(ndfc->ndfcbase + NDFC_CCR); |
55 | if (chip >= 0) { | 54 | if (chip >= 0) { |
@@ -62,8 +61,8 @@ static void ndfc_select_chip(struct mtd_info *mtd, int chip) | |||
62 | 61 | ||
63 | static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 62 | static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
64 | { | 63 | { |
65 | struct nand_chip *chip = mtd->priv; | 64 | struct nand_chip *chip = mtd_to_nand(mtd); |
66 | struct ndfc_controller *ndfc = chip->priv; | 65 | struct ndfc_controller *ndfc = nand_get_controller_data(chip); |
67 | 66 | ||
68 | if (cmd == NAND_CMD_NONE) | 67 | if (cmd == NAND_CMD_NONE) |
69 | return; | 68 | return; |
@@ -76,8 +75,8 @@ static void ndfc_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) | |||
76 | 75 | ||
77 | static int ndfc_ready(struct mtd_info *mtd) | 76 | static int ndfc_ready(struct mtd_info *mtd) |
78 | { | 77 | { |
79 | struct nand_chip *chip = mtd->priv; | 78 | struct nand_chip *chip = mtd_to_nand(mtd); |
80 | struct ndfc_controller *ndfc = chip->priv; | 79 | struct ndfc_controller *ndfc = nand_get_controller_data(chip); |
81 | 80 | ||
82 | return in_be32(ndfc->ndfcbase + NDFC_STAT) & NDFC_STAT_IS_READY; | 81 | return in_be32(ndfc->ndfcbase + NDFC_STAT) & NDFC_STAT_IS_READY; |
83 | } | 82 | } |
@@ -85,8 +84,8 @@ static int ndfc_ready(struct mtd_info *mtd) | |||
85 | static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode) | 84 | static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode) |
86 | { | 85 | { |
87 | uint32_t ccr; | 86 | uint32_t ccr; |
88 | struct nand_chip *chip = mtd->priv; | 87 | struct nand_chip *chip = mtd_to_nand(mtd); |
89 | struct ndfc_controller *ndfc = chip->priv; | 88 | struct ndfc_controller *ndfc = nand_get_controller_data(chip); |
90 | 89 | ||
91 | ccr = in_be32(ndfc->ndfcbase + NDFC_CCR); | 90 | ccr = in_be32(ndfc->ndfcbase + NDFC_CCR); |
92 | ccr |= NDFC_CCR_RESET_ECC; | 91 | ccr |= NDFC_CCR_RESET_ECC; |
@@ -97,8 +96,8 @@ static void ndfc_enable_hwecc(struct mtd_info *mtd, int mode) | |||
97 | static int ndfc_calculate_ecc(struct mtd_info *mtd, | 96 | static int ndfc_calculate_ecc(struct mtd_info *mtd, |
98 | const u_char *dat, u_char *ecc_code) | 97 | const u_char *dat, u_char *ecc_code) |
99 | { | 98 | { |
100 | struct nand_chip *chip = mtd->priv; | 99 | struct nand_chip *chip = mtd_to_nand(mtd); |
101 | struct ndfc_controller *ndfc = chip->priv; | 100 | struct ndfc_controller *ndfc = nand_get_controller_data(chip); |
102 | uint32_t ecc; | 101 | uint32_t ecc; |
103 | uint8_t *p = (uint8_t *)&ecc; | 102 | uint8_t *p = (uint8_t *)&ecc; |
104 | 103 | ||
@@ -121,8 +120,8 @@ static int ndfc_calculate_ecc(struct mtd_info *mtd, | |||
121 | */ | 120 | */ |
122 | static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | 121 | static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) |
123 | { | 122 | { |
124 | struct nand_chip *chip = mtd->priv; | 123 | struct nand_chip *chip = mtd_to_nand(mtd); |
125 | struct ndfc_controller *ndfc = chip->priv; | 124 | struct ndfc_controller *ndfc = nand_get_controller_data(chip); |
126 | uint32_t *p = (uint32_t *) buf; | 125 | uint32_t *p = (uint32_t *) buf; |
127 | 126 | ||
128 | for(;len > 0; len -= 4) | 127 | for(;len > 0; len -= 4) |
@@ -131,8 +130,8 @@ static void ndfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | |||
131 | 130 | ||
132 | static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | 131 | static void ndfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) |
133 | { | 132 | { |
134 | struct nand_chip *chip = mtd->priv; | 133 | struct nand_chip *chip = mtd_to_nand(mtd); |
135 | struct ndfc_controller *ndfc = chip->priv; | 134 | struct ndfc_controller *ndfc = nand_get_controller_data(chip); |
136 | uint32_t *p = (uint32_t *) buf; | 135 | uint32_t *p = (uint32_t *) buf; |
137 | 136 | ||
138 | for(;len > 0; len -= 4) | 137 | for(;len > 0; len -= 4) |
@@ -147,7 +146,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc, | |||
147 | { | 146 | { |
148 | struct device_node *flash_np; | 147 | struct device_node *flash_np; |
149 | struct nand_chip *chip = &ndfc->chip; | 148 | struct nand_chip *chip = &ndfc->chip; |
150 | struct mtd_part_parser_data ppdata; | 149 | struct mtd_info *mtd = nand_to_mtd(chip); |
151 | int ret; | 150 | int ret; |
152 | 151 | ||
153 | chip->IO_ADDR_R = ndfc->ndfcbase + NDFC_DATA; | 152 | chip->IO_ADDR_R = ndfc->ndfcbase + NDFC_DATA; |
@@ -166,33 +165,32 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc, | |||
166 | chip->ecc.size = 256; | 165 | chip->ecc.size = 256; |
167 | chip->ecc.bytes = 3; | 166 | chip->ecc.bytes = 3; |
168 | chip->ecc.strength = 1; | 167 | chip->ecc.strength = 1; |
169 | chip->priv = ndfc; | 168 | nand_set_controller_data(chip, ndfc); |
170 | 169 | ||
171 | ndfc->mtd.priv = chip; | 170 | mtd->dev.parent = &ndfc->ofdev->dev; |
172 | ndfc->mtd.dev.parent = &ndfc->ofdev->dev; | ||
173 | 171 | ||
174 | flash_np = of_get_next_child(node, NULL); | 172 | flash_np = of_get_next_child(node, NULL); |
175 | if (!flash_np) | 173 | if (!flash_np) |
176 | return -ENODEV; | 174 | return -ENODEV; |
175 | nand_set_flash_node(chip, flash_np); | ||
177 | 176 | ||
178 | ppdata.of_node = flash_np; | 177 | mtd->name = kasprintf(GFP_KERNEL, "%s.%s", dev_name(&ndfc->ofdev->dev), |
179 | ndfc->mtd.name = kasprintf(GFP_KERNEL, "%s.%s", | 178 | flash_np->name); |
180 | dev_name(&ndfc->ofdev->dev), flash_np->name); | 179 | if (!mtd->name) { |
181 | if (!ndfc->mtd.name) { | ||
182 | ret = -ENOMEM; | 180 | ret = -ENOMEM; |
183 | goto err; | 181 | goto err; |
184 | } | 182 | } |
185 | 183 | ||
186 | ret = nand_scan(&ndfc->mtd, 1); | 184 | ret = nand_scan(mtd, 1); |
187 | if (ret) | 185 | if (ret) |
188 | goto err; | 186 | goto err; |
189 | 187 | ||
190 | ret = mtd_device_parse_register(&ndfc->mtd, NULL, &ppdata, NULL, 0); | 188 | ret = mtd_device_register(mtd, NULL, 0); |
191 | 189 | ||
192 | err: | 190 | err: |
193 | of_node_put(flash_np); | 191 | of_node_put(flash_np); |
194 | if (ret) | 192 | if (ret) |
195 | kfree(ndfc->mtd.name); | 193 | kfree(mtd->name); |
196 | return ret; | 194 | return ret; |
197 | } | 195 | } |
198 | 196 | ||
@@ -259,9 +257,10 @@ static int ndfc_probe(struct platform_device *ofdev) | |||
259 | static int ndfc_remove(struct platform_device *ofdev) | 257 | static int ndfc_remove(struct platform_device *ofdev) |
260 | { | 258 | { |
261 | struct ndfc_controller *ndfc = dev_get_drvdata(&ofdev->dev); | 259 | struct ndfc_controller *ndfc = dev_get_drvdata(&ofdev->dev); |
260 | struct mtd_info *mtd = nand_to_mtd(&ndfc->chip); | ||
262 | 261 | ||
263 | nand_release(&ndfc->mtd); | 262 | nand_release(mtd); |
264 | kfree(ndfc->mtd.name); | 263 | kfree(mtd->name); |
265 | 264 | ||
266 | return 0; | 265 | return 0; |
267 | } | 266 | } |
diff --git a/drivers/mtd/nand/nuc900_nand.c b/drivers/mtd/nand/nuc900_nand.c index f0687f71fbd8..220ddfcf29f5 100644 --- a/drivers/mtd/nand/nuc900_nand.c +++ b/drivers/mtd/nand/nuc900_nand.c | |||
@@ -55,13 +55,17 @@ | |||
55 | __raw_writel((val), (dev)->reg + REG_SMADDR) | 55 | __raw_writel((val), (dev)->reg + REG_SMADDR) |
56 | 56 | ||
57 | struct nuc900_nand { | 57 | struct nuc900_nand { |
58 | struct mtd_info mtd; | ||
59 | struct nand_chip chip; | 58 | struct nand_chip chip; |
60 | void __iomem *reg; | 59 | void __iomem *reg; |
61 | struct clk *clk; | 60 | struct clk *clk; |
62 | spinlock_t lock; | 61 | spinlock_t lock; |
63 | }; | 62 | }; |
64 | 63 | ||
64 | static inline struct nuc900_nand *mtd_to_nuc900(struct mtd_info *mtd) | ||
65 | { | ||
66 | return container_of(mtd_to_nand(mtd), struct nuc900_nand, chip); | ||
67 | } | ||
68 | |||
65 | static const struct mtd_partition partitions[] = { | 69 | static const struct mtd_partition partitions[] = { |
66 | { | 70 | { |
67 | .name = "NAND FS 0", | 71 | .name = "NAND FS 0", |
@@ -78,9 +82,7 @@ static const struct mtd_partition partitions[] = { | |||
78 | static unsigned char nuc900_nand_read_byte(struct mtd_info *mtd) | 82 | static unsigned char nuc900_nand_read_byte(struct mtd_info *mtd) |
79 | { | 83 | { |
80 | unsigned char ret; | 84 | unsigned char ret; |
81 | struct nuc900_nand *nand; | 85 | struct nuc900_nand *nand = mtd_to_nuc900(mtd); |
82 | |||
83 | nand = container_of(mtd, struct nuc900_nand, mtd); | ||
84 | 86 | ||
85 | ret = (unsigned char)read_data_reg(nand); | 87 | ret = (unsigned char)read_data_reg(nand); |
86 | 88 | ||
@@ -91,9 +93,7 @@ static void nuc900_nand_read_buf(struct mtd_info *mtd, | |||
91 | unsigned char *buf, int len) | 93 | unsigned char *buf, int len) |
92 | { | 94 | { |
93 | int i; | 95 | int i; |
94 | struct nuc900_nand *nand; | 96 | struct nuc900_nand *nand = mtd_to_nuc900(mtd); |
95 | |||
96 | nand = container_of(mtd, struct nuc900_nand, mtd); | ||
97 | 97 | ||
98 | for (i = 0; i < len; i++) | 98 | for (i = 0; i < len; i++) |
99 | buf[i] = (unsigned char)read_data_reg(nand); | 99 | buf[i] = (unsigned char)read_data_reg(nand); |
@@ -103,9 +103,7 @@ static void nuc900_nand_write_buf(struct mtd_info *mtd, | |||
103 | const unsigned char *buf, int len) | 103 | const unsigned char *buf, int len) |
104 | { | 104 | { |
105 | int i; | 105 | int i; |
106 | struct nuc900_nand *nand; | 106 | struct nuc900_nand *nand = mtd_to_nuc900(mtd); |
107 | |||
108 | nand = container_of(mtd, struct nuc900_nand, mtd); | ||
109 | 107 | ||
110 | for (i = 0; i < len; i++) | 108 | for (i = 0; i < len; i++) |
111 | write_data_reg(nand, buf[i]); | 109 | write_data_reg(nand, buf[i]); |
@@ -124,11 +122,9 @@ static int nuc900_check_rb(struct nuc900_nand *nand) | |||
124 | 122 | ||
125 | static int nuc900_nand_devready(struct mtd_info *mtd) | 123 | static int nuc900_nand_devready(struct mtd_info *mtd) |
126 | { | 124 | { |
127 | struct nuc900_nand *nand; | 125 | struct nuc900_nand *nand = mtd_to_nuc900(mtd); |
128 | int ready; | 126 | int ready; |
129 | 127 | ||
130 | nand = container_of(mtd, struct nuc900_nand, mtd); | ||
131 | |||
132 | ready = (nuc900_check_rb(nand)) ? 1 : 0; | 128 | ready = (nuc900_check_rb(nand)) ? 1 : 0; |
133 | return ready; | 129 | return ready; |
134 | } | 130 | } |
@@ -136,10 +132,8 @@ static int nuc900_nand_devready(struct mtd_info *mtd) | |||
136 | static void nuc900_nand_command_lp(struct mtd_info *mtd, unsigned int command, | 132 | static void nuc900_nand_command_lp(struct mtd_info *mtd, unsigned int command, |
137 | int column, int page_addr) | 133 | int column, int page_addr) |
138 | { | 134 | { |
139 | register struct nand_chip *chip = mtd->priv; | 135 | register struct nand_chip *chip = mtd_to_nand(mtd); |
140 | struct nuc900_nand *nand; | 136 | struct nuc900_nand *nand = mtd_to_nuc900(mtd); |
141 | |||
142 | nand = container_of(mtd, struct nuc900_nand, mtd); | ||
143 | 137 | ||
144 | if (command == NAND_CMD_READOOB) { | 138 | if (command == NAND_CMD_READOOB) { |
145 | column += mtd->writesize; | 139 | column += mtd->writesize; |
@@ -241,6 +235,7 @@ static int nuc900_nand_probe(struct platform_device *pdev) | |||
241 | { | 235 | { |
242 | struct nuc900_nand *nuc900_nand; | 236 | struct nuc900_nand *nuc900_nand; |
243 | struct nand_chip *chip; | 237 | struct nand_chip *chip; |
238 | struct mtd_info *mtd; | ||
244 | struct resource *res; | 239 | struct resource *res; |
245 | 240 | ||
246 | nuc900_nand = devm_kzalloc(&pdev->dev, sizeof(struct nuc900_nand), | 241 | nuc900_nand = devm_kzalloc(&pdev->dev, sizeof(struct nuc900_nand), |
@@ -248,9 +243,9 @@ static int nuc900_nand_probe(struct platform_device *pdev) | |||
248 | if (!nuc900_nand) | 243 | if (!nuc900_nand) |
249 | return -ENOMEM; | 244 | return -ENOMEM; |
250 | chip = &(nuc900_nand->chip); | 245 | chip = &(nuc900_nand->chip); |
246 | mtd = nand_to_mtd(chip); | ||
251 | 247 | ||
252 | nuc900_nand->mtd.priv = chip; | 248 | mtd->dev.parent = &pdev->dev; |
253 | nuc900_nand->mtd.dev.parent = &pdev->dev; | ||
254 | spin_lock_init(&nuc900_nand->lock); | 249 | spin_lock_init(&nuc900_nand->lock); |
255 | 250 | ||
256 | nuc900_nand->clk = devm_clk_get(&pdev->dev, NULL); | 251 | nuc900_nand->clk = devm_clk_get(&pdev->dev, NULL); |
@@ -274,11 +269,10 @@ static int nuc900_nand_probe(struct platform_device *pdev) | |||
274 | 269 | ||
275 | nuc900_nand_enable(nuc900_nand); | 270 | nuc900_nand_enable(nuc900_nand); |
276 | 271 | ||
277 | if (nand_scan(&(nuc900_nand->mtd), 1)) | 272 | if (nand_scan(mtd, 1)) |
278 | return -ENXIO; | 273 | return -ENXIO; |
279 | 274 | ||
280 | mtd_device_register(&(nuc900_nand->mtd), partitions, | 275 | mtd_device_register(mtd, partitions, ARRAY_SIZE(partitions)); |
281 | ARRAY_SIZE(partitions)); | ||
282 | 276 | ||
283 | platform_set_drvdata(pdev, nuc900_nand); | 277 | platform_set_drvdata(pdev, nuc900_nand); |
284 | 278 | ||
@@ -289,7 +283,7 @@ static int nuc900_nand_remove(struct platform_device *pdev) | |||
289 | { | 283 | { |
290 | struct nuc900_nand *nuc900_nand = platform_get_drvdata(pdev); | 284 | struct nuc900_nand *nuc900_nand = platform_get_drvdata(pdev); |
291 | 285 | ||
292 | nand_release(&nuc900_nand->mtd); | 286 | nand_release(nand_to_mtd(&nuc900_nand->chip)); |
293 | clk_disable(nuc900_nand->clk); | 287 | clk_disable(nuc900_nand->clk); |
294 | 288 | ||
295 | return 0; | 289 | return 0; |
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 93f664cd1c90..c553f78ab83f 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
@@ -152,7 +152,6 @@ static struct nand_hw_control omap_gpmc_controller = { | |||
152 | 152 | ||
153 | struct omap_nand_info { | 153 | struct omap_nand_info { |
154 | struct omap_nand_platform_data *pdata; | 154 | struct omap_nand_platform_data *pdata; |
155 | struct mtd_info mtd; | ||
156 | struct nand_chip nand; | 155 | struct nand_chip nand; |
157 | struct platform_device *pdev; | 156 | struct platform_device *pdev; |
158 | 157 | ||
@@ -177,6 +176,11 @@ struct omap_nand_info { | |||
177 | struct device_node *of_node; | 176 | struct device_node *of_node; |
178 | }; | 177 | }; |
179 | 178 | ||
179 | static inline struct omap_nand_info *mtd_to_omap(struct mtd_info *mtd) | ||
180 | { | ||
181 | return container_of(mtd_to_nand(mtd), struct omap_nand_info, nand); | ||
182 | } | ||
183 | |||
180 | /** | 184 | /** |
181 | * omap_prefetch_enable - configures and starts prefetch transfer | 185 | * omap_prefetch_enable - configures and starts prefetch transfer |
182 | * @cs: cs (chip select) number | 186 | * @cs: cs (chip select) number |
@@ -247,8 +251,7 @@ static int omap_prefetch_reset(int cs, struct omap_nand_info *info) | |||
247 | */ | 251 | */ |
248 | static void omap_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 252 | static void omap_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
249 | { | 253 | { |
250 | struct omap_nand_info *info = container_of(mtd, | 254 | struct omap_nand_info *info = mtd_to_omap(mtd); |
251 | struct omap_nand_info, mtd); | ||
252 | 255 | ||
253 | if (cmd != NAND_CMD_NONE) { | 256 | if (cmd != NAND_CMD_NONE) { |
254 | if (ctrl & NAND_CLE) | 257 | if (ctrl & NAND_CLE) |
@@ -270,7 +273,7 @@ static void omap_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) | |||
270 | */ | 273 | */ |
271 | static void omap_read_buf8(struct mtd_info *mtd, u_char *buf, int len) | 274 | static void omap_read_buf8(struct mtd_info *mtd, u_char *buf, int len) |
272 | { | 275 | { |
273 | struct nand_chip *nand = mtd->priv; | 276 | struct nand_chip *nand = mtd_to_nand(mtd); |
274 | 277 | ||
275 | ioread8_rep(nand->IO_ADDR_R, buf, len); | 278 | ioread8_rep(nand->IO_ADDR_R, buf, len); |
276 | } | 279 | } |
@@ -283,8 +286,7 @@ static void omap_read_buf8(struct mtd_info *mtd, u_char *buf, int len) | |||
283 | */ | 286 | */ |
284 | static void omap_write_buf8(struct mtd_info *mtd, const u_char *buf, int len) | 287 | static void omap_write_buf8(struct mtd_info *mtd, const u_char *buf, int len) |
285 | { | 288 | { |
286 | struct omap_nand_info *info = container_of(mtd, | 289 | struct omap_nand_info *info = mtd_to_omap(mtd); |
287 | struct omap_nand_info, mtd); | ||
288 | u_char *p = (u_char *)buf; | 290 | u_char *p = (u_char *)buf; |
289 | u32 status = 0; | 291 | u32 status = 0; |
290 | 292 | ||
@@ -306,7 +308,7 @@ static void omap_write_buf8(struct mtd_info *mtd, const u_char *buf, int len) | |||
306 | */ | 308 | */ |
307 | static void omap_read_buf16(struct mtd_info *mtd, u_char *buf, int len) | 309 | static void omap_read_buf16(struct mtd_info *mtd, u_char *buf, int len) |
308 | { | 310 | { |
309 | struct nand_chip *nand = mtd->priv; | 311 | struct nand_chip *nand = mtd_to_nand(mtd); |
310 | 312 | ||
311 | ioread16_rep(nand->IO_ADDR_R, buf, len / 2); | 313 | ioread16_rep(nand->IO_ADDR_R, buf, len / 2); |
312 | } | 314 | } |
@@ -319,8 +321,7 @@ static void omap_read_buf16(struct mtd_info *mtd, u_char *buf, int len) | |||
319 | */ | 321 | */ |
320 | static void omap_write_buf16(struct mtd_info *mtd, const u_char * buf, int len) | 322 | static void omap_write_buf16(struct mtd_info *mtd, const u_char * buf, int len) |
321 | { | 323 | { |
322 | struct omap_nand_info *info = container_of(mtd, | 324 | struct omap_nand_info *info = mtd_to_omap(mtd); |
323 | struct omap_nand_info, mtd); | ||
324 | u16 *p = (u16 *) buf; | 325 | u16 *p = (u16 *) buf; |
325 | u32 status = 0; | 326 | u32 status = 0; |
326 | /* FIXME try bursts of writesw() or DMA ... */ | 327 | /* FIXME try bursts of writesw() or DMA ... */ |
@@ -344,8 +345,7 @@ static void omap_write_buf16(struct mtd_info *mtd, const u_char * buf, int len) | |||
344 | */ | 345 | */ |
345 | static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) | 346 | static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) |
346 | { | 347 | { |
347 | struct omap_nand_info *info = container_of(mtd, | 348 | struct omap_nand_info *info = mtd_to_omap(mtd); |
348 | struct omap_nand_info, mtd); | ||
349 | uint32_t r_count = 0; | 349 | uint32_t r_count = 0; |
350 | int ret = 0; | 350 | int ret = 0; |
351 | u32 *p = (u32 *)buf; | 351 | u32 *p = (u32 *)buf; |
@@ -392,8 +392,7 @@ static void omap_read_buf_pref(struct mtd_info *mtd, u_char *buf, int len) | |||
392 | static void omap_write_buf_pref(struct mtd_info *mtd, | 392 | static void omap_write_buf_pref(struct mtd_info *mtd, |
393 | const u_char *buf, int len) | 393 | const u_char *buf, int len) |
394 | { | 394 | { |
395 | struct omap_nand_info *info = container_of(mtd, | 395 | struct omap_nand_info *info = mtd_to_omap(mtd); |
396 | struct omap_nand_info, mtd); | ||
397 | uint32_t w_count = 0; | 396 | uint32_t w_count = 0; |
398 | int i = 0, ret = 0; | 397 | int i = 0, ret = 0; |
399 | u16 *p = (u16 *)buf; | 398 | u16 *p = (u16 *)buf; |
@@ -458,8 +457,7 @@ static void omap_nand_dma_callback(void *data) | |||
458 | static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, | 457 | static inline int omap_nand_dma_transfer(struct mtd_info *mtd, void *addr, |
459 | unsigned int len, int is_write) | 458 | unsigned int len, int is_write) |
460 | { | 459 | { |
461 | struct omap_nand_info *info = container_of(mtd, | 460 | struct omap_nand_info *info = mtd_to_omap(mtd); |
462 | struct omap_nand_info, mtd); | ||
463 | struct dma_async_tx_descriptor *tx; | 461 | struct dma_async_tx_descriptor *tx; |
464 | enum dma_data_direction dir = is_write ? DMA_TO_DEVICE : | 462 | enum dma_data_direction dir = is_write ? DMA_TO_DEVICE : |
465 | DMA_FROM_DEVICE; | 463 | DMA_FROM_DEVICE; |
@@ -623,8 +621,7 @@ done: | |||
623 | */ | 621 | */ |
624 | static void omap_read_buf_irq_pref(struct mtd_info *mtd, u_char *buf, int len) | 622 | static void omap_read_buf_irq_pref(struct mtd_info *mtd, u_char *buf, int len) |
625 | { | 623 | { |
626 | struct omap_nand_info *info = container_of(mtd, | 624 | struct omap_nand_info *info = mtd_to_omap(mtd); |
627 | struct omap_nand_info, mtd); | ||
628 | int ret = 0; | 625 | int ret = 0; |
629 | 626 | ||
630 | if (len <= mtd->oobsize) { | 627 | if (len <= mtd->oobsize) { |
@@ -671,8 +668,7 @@ out_copy: | |||
671 | static void omap_write_buf_irq_pref(struct mtd_info *mtd, | 668 | static void omap_write_buf_irq_pref(struct mtd_info *mtd, |
672 | const u_char *buf, int len) | 669 | const u_char *buf, int len) |
673 | { | 670 | { |
674 | struct omap_nand_info *info = container_of(mtd, | 671 | struct omap_nand_info *info = mtd_to_omap(mtd); |
675 | struct omap_nand_info, mtd); | ||
676 | int ret = 0; | 672 | int ret = 0; |
677 | unsigned long tim, limit; | 673 | unsigned long tim, limit; |
678 | u32 val; | 674 | u32 val; |
@@ -830,12 +826,12 @@ static int omap_compare_ecc(u8 *ecc_data1, /* read from NAND memory */ | |||
830 | case 1: | 826 | case 1: |
831 | /* Uncorrectable error */ | 827 | /* Uncorrectable error */ |
832 | pr_debug("ECC UNCORRECTED_ERROR 1\n"); | 828 | pr_debug("ECC UNCORRECTED_ERROR 1\n"); |
833 | return -1; | 829 | return -EBADMSG; |
834 | 830 | ||
835 | case 11: | 831 | case 11: |
836 | /* UN-Correctable error */ | 832 | /* UN-Correctable error */ |
837 | pr_debug("ECC UNCORRECTED_ERROR B\n"); | 833 | pr_debug("ECC UNCORRECTED_ERROR B\n"); |
838 | return -1; | 834 | return -EBADMSG; |
839 | 835 | ||
840 | case 12: | 836 | case 12: |
841 | /* Correctable error */ | 837 | /* Correctable error */ |
@@ -865,7 +861,7 @@ static int omap_compare_ecc(u8 *ecc_data1, /* read from NAND memory */ | |||
865 | return 0; | 861 | return 0; |
866 | } | 862 | } |
867 | pr_debug("UNCORRECTED_ERROR default\n"); | 863 | pr_debug("UNCORRECTED_ERROR default\n"); |
868 | return -1; | 864 | return -EBADMSG; |
869 | } | 865 | } |
870 | } | 866 | } |
871 | 867 | ||
@@ -886,8 +882,7 @@ static int omap_compare_ecc(u8 *ecc_data1, /* read from NAND memory */ | |||
886 | static int omap_correct_data(struct mtd_info *mtd, u_char *dat, | 882 | static int omap_correct_data(struct mtd_info *mtd, u_char *dat, |
887 | u_char *read_ecc, u_char *calc_ecc) | 883 | u_char *read_ecc, u_char *calc_ecc) |
888 | { | 884 | { |
889 | struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, | 885 | struct omap_nand_info *info = mtd_to_omap(mtd); |
890 | mtd); | ||
891 | int blockCnt = 0, i = 0, ret = 0; | 886 | int blockCnt = 0, i = 0, ret = 0; |
892 | int stat = 0; | 887 | int stat = 0; |
893 | 888 | ||
@@ -928,8 +923,7 @@ static int omap_correct_data(struct mtd_info *mtd, u_char *dat, | |||
928 | static int omap_calculate_ecc(struct mtd_info *mtd, const u_char *dat, | 923 | static int omap_calculate_ecc(struct mtd_info *mtd, const u_char *dat, |
929 | u_char *ecc_code) | 924 | u_char *ecc_code) |
930 | { | 925 | { |
931 | struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, | 926 | struct omap_nand_info *info = mtd_to_omap(mtd); |
932 | mtd); | ||
933 | u32 val; | 927 | u32 val; |
934 | 928 | ||
935 | val = readl(info->reg.gpmc_ecc_config); | 929 | val = readl(info->reg.gpmc_ecc_config); |
@@ -953,9 +947,8 @@ static int omap_calculate_ecc(struct mtd_info *mtd, const u_char *dat, | |||
953 | */ | 947 | */ |
954 | static void omap_enable_hwecc(struct mtd_info *mtd, int mode) | 948 | static void omap_enable_hwecc(struct mtd_info *mtd, int mode) |
955 | { | 949 | { |
956 | struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, | 950 | struct omap_nand_info *info = mtd_to_omap(mtd); |
957 | mtd); | 951 | struct nand_chip *chip = mtd_to_nand(mtd); |
958 | struct nand_chip *chip = mtd->priv; | ||
959 | unsigned int dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0; | 952 | unsigned int dev_width = (chip->options & NAND_BUSWIDTH_16) ? 1 : 0; |
960 | u32 val; | 953 | u32 val; |
961 | 954 | ||
@@ -1001,9 +994,8 @@ static void omap_enable_hwecc(struct mtd_info *mtd, int mode) | |||
1001 | */ | 994 | */ |
1002 | static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip) | 995 | static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip) |
1003 | { | 996 | { |
1004 | struct nand_chip *this = mtd->priv; | 997 | struct nand_chip *this = mtd_to_nand(mtd); |
1005 | struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, | 998 | struct omap_nand_info *info = mtd_to_omap(mtd); |
1006 | mtd); | ||
1007 | unsigned long timeo = jiffies; | 999 | unsigned long timeo = jiffies; |
1008 | int status, state = this->state; | 1000 | int status, state = this->state; |
1009 | 1001 | ||
@@ -1031,8 +1023,7 @@ static int omap_wait(struct mtd_info *mtd, struct nand_chip *chip) | |||
1031 | static int omap_dev_ready(struct mtd_info *mtd) | 1023 | static int omap_dev_ready(struct mtd_info *mtd) |
1032 | { | 1024 | { |
1033 | unsigned int val = 0; | 1025 | unsigned int val = 0; |
1034 | struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, | 1026 | struct omap_nand_info *info = mtd_to_omap(mtd); |
1035 | mtd); | ||
1036 | 1027 | ||
1037 | val = readl(info->reg.gpmc_status); | 1028 | val = readl(info->reg.gpmc_status); |
1038 | 1029 | ||
@@ -1058,10 +1049,9 @@ static void __maybe_unused omap_enable_hwecc_bch(struct mtd_info *mtd, int mode) | |||
1058 | { | 1049 | { |
1059 | unsigned int bch_type; | 1050 | unsigned int bch_type; |
1060 | unsigned int dev_width, nsectors; | 1051 | unsigned int dev_width, nsectors; |
1061 | struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, | 1052 | struct omap_nand_info *info = mtd_to_omap(mtd); |
1062 | mtd); | ||
1063 | enum omap_ecc ecc_opt = info->ecc_opt; | 1053 | enum omap_ecc ecc_opt = info->ecc_opt; |
1064 | struct nand_chip *chip = mtd->priv; | 1054 | struct nand_chip *chip = mtd_to_nand(mtd); |
1065 | u32 val, wr_mode; | 1055 | u32 val, wr_mode; |
1066 | unsigned int ecc_size1, ecc_size0; | 1056 | unsigned int ecc_size1, ecc_size0; |
1067 | 1057 | ||
@@ -1162,8 +1152,7 @@ static u8 bch8_polynomial[] = {0xef, 0x51, 0x2e, 0x09, 0xed, 0x93, 0x9a, 0xc2, | |||
1162 | static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd, | 1152 | static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd, |
1163 | const u_char *dat, u_char *ecc_calc) | 1153 | const u_char *dat, u_char *ecc_calc) |
1164 | { | 1154 | { |
1165 | struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, | 1155 | struct omap_nand_info *info = mtd_to_omap(mtd); |
1166 | mtd); | ||
1167 | int eccbytes = info->nand.ecc.bytes; | 1156 | int eccbytes = info->nand.ecc.bytes; |
1168 | struct gpmc_nand_regs *gpmc_regs = &info->reg; | 1157 | struct gpmc_nand_regs *gpmc_regs = &info->reg; |
1169 | u8 *ecc_code; | 1158 | u8 *ecc_code; |
@@ -1334,8 +1323,7 @@ static int erased_sector_bitflips(u_char *data, u_char *oob, | |||
1334 | static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data, | 1323 | static int omap_elm_correct_data(struct mtd_info *mtd, u_char *data, |
1335 | u_char *read_ecc, u_char *calc_ecc) | 1324 | u_char *read_ecc, u_char *calc_ecc) |
1336 | { | 1325 | { |
1337 | struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, | 1326 | struct omap_nand_info *info = mtd_to_omap(mtd); |
1338 | mtd); | ||
1339 | struct nand_ecc_ctrl *ecc = &info->nand.ecc; | 1327 | struct nand_ecc_ctrl *ecc = &info->nand.ecc; |
1340 | int eccsteps = info->nand.ecc.steps; | 1328 | int eccsteps = info->nand.ecc.steps; |
1341 | int i , j, stat = 0; | 1329 | int i , j, stat = 0; |
@@ -1663,7 +1651,6 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1663 | unsigned sig; | 1651 | unsigned sig; |
1664 | unsigned oob_index; | 1652 | unsigned oob_index; |
1665 | struct resource *res; | 1653 | struct resource *res; |
1666 | struct mtd_part_parser_data ppdata = {}; | ||
1667 | 1654 | ||
1668 | pdata = dev_get_platdata(&pdev->dev); | 1655 | pdata = dev_get_platdata(&pdev->dev); |
1669 | if (pdata == NULL) { | 1656 | if (pdata == NULL) { |
@@ -1683,11 +1670,11 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1683 | info->reg = pdata->reg; | 1670 | info->reg = pdata->reg; |
1684 | info->of_node = pdata->of_node; | 1671 | info->of_node = pdata->of_node; |
1685 | info->ecc_opt = pdata->ecc_opt; | 1672 | info->ecc_opt = pdata->ecc_opt; |
1686 | mtd = &info->mtd; | ||
1687 | mtd->priv = &info->nand; | ||
1688 | mtd->dev.parent = &pdev->dev; | ||
1689 | nand_chip = &info->nand; | 1673 | nand_chip = &info->nand; |
1674 | mtd = nand_to_mtd(nand_chip); | ||
1675 | mtd->dev.parent = &pdev->dev; | ||
1690 | nand_chip->ecc.priv = NULL; | 1676 | nand_chip->ecc.priv = NULL; |
1677 | nand_set_flash_node(nand_chip, pdata->of_node); | ||
1691 | 1678 | ||
1692 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1679 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1693 | nand_chip->IO_ADDR_R = devm_ioremap_resource(&pdev->dev, res); | 1680 | nand_chip->IO_ADDR_R = devm_ioremap_resource(&pdev->dev, res); |
@@ -1909,7 +1896,7 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1909 | ecclayout->eccpos[ecclayout->eccbytes - 1] + 1; | 1896 | ecclayout->eccpos[ecclayout->eccbytes - 1] + 1; |
1910 | 1897 | ||
1911 | err = elm_config(info->elm_dev, BCH4_ECC, | 1898 | err = elm_config(info->elm_dev, BCH4_ECC, |
1912 | info->mtd.writesize / nand_chip->ecc.size, | 1899 | mtd->writesize / nand_chip->ecc.size, |
1913 | nand_chip->ecc.size, nand_chip->ecc.bytes); | 1900 | nand_chip->ecc.size, nand_chip->ecc.bytes); |
1914 | if (err < 0) | 1901 | if (err < 0) |
1915 | goto return_error; | 1902 | goto return_error; |
@@ -1963,7 +1950,7 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1963 | nand_chip->ecc.write_page = omap_write_page_bch; | 1950 | nand_chip->ecc.write_page = omap_write_page_bch; |
1964 | 1951 | ||
1965 | err = elm_config(info->elm_dev, BCH8_ECC, | 1952 | err = elm_config(info->elm_dev, BCH8_ECC, |
1966 | info->mtd.writesize / nand_chip->ecc.size, | 1953 | mtd->writesize / nand_chip->ecc.size, |
1967 | nand_chip->ecc.size, nand_chip->ecc.bytes); | 1954 | nand_chip->ecc.size, nand_chip->ecc.bytes); |
1968 | if (err < 0) | 1955 | if (err < 0) |
1969 | goto return_error; | 1956 | goto return_error; |
@@ -1993,7 +1980,7 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
1993 | nand_chip->ecc.write_page = omap_write_page_bch; | 1980 | nand_chip->ecc.write_page = omap_write_page_bch; |
1994 | 1981 | ||
1995 | err = elm_config(info->elm_dev, BCH16_ECC, | 1982 | err = elm_config(info->elm_dev, BCH16_ECC, |
1996 | info->mtd.writesize / nand_chip->ecc.size, | 1983 | mtd->writesize / nand_chip->ecc.size, |
1997 | nand_chip->ecc.size, nand_chip->ecc.bytes); | 1984 | nand_chip->ecc.size, nand_chip->ecc.bytes); |
1998 | if (err < 0) | 1985 | if (err < 0) |
1999 | goto return_error; | 1986 | goto return_error; |
@@ -2037,9 +2024,7 @@ scan_tail: | |||
2037 | goto return_error; | 2024 | goto return_error; |
2038 | } | 2025 | } |
2039 | 2026 | ||
2040 | ppdata.of_node = pdata->of_node; | 2027 | mtd_device_register(mtd, pdata->parts, pdata->nr_parts); |
2041 | mtd_device_parse_register(mtd, NULL, &ppdata, pdata->parts, | ||
2042 | pdata->nr_parts); | ||
2043 | 2028 | ||
2044 | platform_set_drvdata(pdev, mtd); | 2029 | platform_set_drvdata(pdev, mtd); |
2045 | 2030 | ||
@@ -2058,9 +2043,8 @@ return_error: | |||
2058 | static int omap_nand_remove(struct platform_device *pdev) | 2043 | static int omap_nand_remove(struct platform_device *pdev) |
2059 | { | 2044 | { |
2060 | struct mtd_info *mtd = platform_get_drvdata(pdev); | 2045 | struct mtd_info *mtd = platform_get_drvdata(pdev); |
2061 | struct nand_chip *nand_chip = mtd->priv; | 2046 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
2062 | struct omap_nand_info *info = container_of(mtd, struct omap_nand_info, | 2047 | struct omap_nand_info *info = mtd_to_omap(mtd); |
2063 | mtd); | ||
2064 | if (nand_chip->ecc.priv) { | 2048 | if (nand_chip->ecc.priv) { |
2065 | nand_bch_free(nand_chip->ecc.priv); | 2049 | nand_bch_free(nand_chip->ecc.priv); |
2066 | nand_chip->ecc.priv = NULL; | 2050 | nand_chip->ecc.priv = NULL; |
diff --git a/drivers/mtd/nand/omap_elm.c b/drivers/mtd/nand/omap_elm.c index 235ec7992b4c..a3f32f939cc1 100644 --- a/drivers/mtd/nand/omap_elm.c +++ b/drivers/mtd/nand/omap_elm.c | |||
@@ -414,7 +414,7 @@ static int elm_probe(struct platform_device *pdev) | |||
414 | ret = devm_request_irq(&pdev->dev, irq->start, elm_isr, 0, | 414 | ret = devm_request_irq(&pdev->dev, irq->start, elm_isr, 0, |
415 | pdev->name, info); | 415 | pdev->name, info); |
416 | if (ret) { | 416 | if (ret) { |
417 | dev_err(&pdev->dev, "failure requesting irq %i\n", irq->start); | 417 | dev_err(&pdev->dev, "failure requesting %pr\n", irq); |
418 | return ret; | 418 | return ret; |
419 | } | 419 | } |
420 | 420 | ||
diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index ee83749fb1d3..d4614bfbfed6 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c | |||
@@ -25,8 +25,8 @@ | |||
25 | 25 | ||
26 | static void orion_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 26 | static void orion_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
27 | { | 27 | { |
28 | struct nand_chip *nc = mtd->priv; | 28 | struct nand_chip *nc = mtd_to_nand(mtd); |
29 | struct orion_nand_data *board = nc->priv; | 29 | struct orion_nand_data *board = nand_get_controller_data(nc); |
30 | u32 offs; | 30 | u32 offs; |
31 | 31 | ||
32 | if (cmd == NAND_CMD_NONE) | 32 | if (cmd == NAND_CMD_NONE) |
@@ -47,7 +47,7 @@ static void orion_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl | |||
47 | 47 | ||
48 | static void orion_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | 48 | static void orion_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) |
49 | { | 49 | { |
50 | struct nand_chip *chip = mtd->priv; | 50 | struct nand_chip *chip = mtd_to_nand(mtd); |
51 | void __iomem *io_base = chip->IO_ADDR_R; | 51 | void __iomem *io_base = chip->IO_ADDR_R; |
52 | uint64_t *buf64; | 52 | uint64_t *buf64; |
53 | int i = 0; | 53 | int i = 0; |
@@ -76,7 +76,6 @@ static void orion_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | |||
76 | static int __init orion_nand_probe(struct platform_device *pdev) | 76 | static int __init orion_nand_probe(struct platform_device *pdev) |
77 | { | 77 | { |
78 | struct mtd_info *mtd; | 78 | struct mtd_info *mtd; |
79 | struct mtd_part_parser_data ppdata = {}; | ||
80 | struct nand_chip *nc; | 79 | struct nand_chip *nc; |
81 | struct orion_nand_data *board; | 80 | struct orion_nand_data *board; |
82 | struct resource *res; | 81 | struct resource *res; |
@@ -86,11 +85,11 @@ static int __init orion_nand_probe(struct platform_device *pdev) | |||
86 | u32 val = 0; | 85 | u32 val = 0; |
87 | 86 | ||
88 | nc = devm_kzalloc(&pdev->dev, | 87 | nc = devm_kzalloc(&pdev->dev, |
89 | sizeof(struct nand_chip) + sizeof(struct mtd_info), | 88 | sizeof(struct nand_chip), |
90 | GFP_KERNEL); | 89 | GFP_KERNEL); |
91 | if (!nc) | 90 | if (!nc) |
92 | return -ENOMEM; | 91 | return -ENOMEM; |
93 | mtd = (struct mtd_info *)(nc + 1); | 92 | mtd = nand_to_mtd(nc); |
94 | 93 | ||
95 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 94 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
96 | io_base = devm_ioremap_resource(&pdev->dev, res); | 95 | io_base = devm_ioremap_resource(&pdev->dev, res); |
@@ -123,10 +122,10 @@ static int __init orion_nand_probe(struct platform_device *pdev) | |||
123 | board = dev_get_platdata(&pdev->dev); | 122 | board = dev_get_platdata(&pdev->dev); |
124 | } | 123 | } |
125 | 124 | ||
126 | mtd->priv = nc; | ||
127 | mtd->dev.parent = &pdev->dev; | 125 | mtd->dev.parent = &pdev->dev; |
128 | 126 | ||
129 | nc->priv = board; | 127 | nand_set_controller_data(nc, board); |
128 | nand_set_flash_node(nc, pdev->dev.of_node); | ||
130 | nc->IO_ADDR_R = nc->IO_ADDR_W = io_base; | 129 | nc->IO_ADDR_R = nc->IO_ADDR_W = io_base; |
131 | nc->cmd_ctrl = orion_nand_cmd_ctrl; | 130 | nc->cmd_ctrl = orion_nand_cmd_ctrl; |
132 | nc->read_buf = orion_nand_read_buf; | 131 | nc->read_buf = orion_nand_read_buf; |
@@ -161,9 +160,7 @@ static int __init orion_nand_probe(struct platform_device *pdev) | |||
161 | } | 160 | } |
162 | 161 | ||
163 | mtd->name = "orion_nand"; | 162 | mtd->name = "orion_nand"; |
164 | ppdata.of_node = pdev->dev.of_node; | 163 | ret = mtd_device_register(mtd, board->parts, board->nr_parts); |
165 | ret = mtd_device_parse_register(mtd, NULL, &ppdata, | ||
166 | board->parts, board->nr_parts); | ||
167 | if (ret) { | 164 | if (ret) { |
168 | nand_release(mtd); | 165 | nand_release(mtd); |
169 | goto no_dev; | 166 | goto no_dev; |
diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index 83cf021b9651..3ab53ca53cca 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c | |||
@@ -45,7 +45,7 @@ static const char driver_name[] = "pasemi-nand"; | |||
45 | 45 | ||
46 | static void pasemi_read_buf(struct mtd_info *mtd, u_char *buf, int len) | 46 | static void pasemi_read_buf(struct mtd_info *mtd, u_char *buf, int len) |
47 | { | 47 | { |
48 | struct nand_chip *chip = mtd->priv; | 48 | struct nand_chip *chip = mtd_to_nand(mtd); |
49 | 49 | ||
50 | while (len > 0x800) { | 50 | while (len > 0x800) { |
51 | memcpy_fromio(buf, chip->IO_ADDR_R, 0x800); | 51 | memcpy_fromio(buf, chip->IO_ADDR_R, 0x800); |
@@ -57,7 +57,7 @@ static void pasemi_read_buf(struct mtd_info *mtd, u_char *buf, int len) | |||
57 | 57 | ||
58 | static void pasemi_write_buf(struct mtd_info *mtd, const u_char *buf, int len) | 58 | static void pasemi_write_buf(struct mtd_info *mtd, const u_char *buf, int len) |
59 | { | 59 | { |
60 | struct nand_chip *chip = mtd->priv; | 60 | struct nand_chip *chip = mtd_to_nand(mtd); |
61 | 61 | ||
62 | while (len > 0x800) { | 62 | while (len > 0x800) { |
63 | memcpy_toio(chip->IO_ADDR_R, buf, 0x800); | 63 | memcpy_toio(chip->IO_ADDR_R, buf, 0x800); |
@@ -70,7 +70,7 @@ static void pasemi_write_buf(struct mtd_info *mtd, const u_char *buf, int len) | |||
70 | static void pasemi_hwcontrol(struct mtd_info *mtd, int cmd, | 70 | static void pasemi_hwcontrol(struct mtd_info *mtd, int cmd, |
71 | unsigned int ctrl) | 71 | unsigned int ctrl) |
72 | { | 72 | { |
73 | struct nand_chip *chip = mtd->priv; | 73 | struct nand_chip *chip = mtd_to_nand(mtd); |
74 | 74 | ||
75 | if (cmd == NAND_CMD_NONE) | 75 | if (cmd == NAND_CMD_NONE) |
76 | return; | 76 | return; |
@@ -110,20 +110,17 @@ static int pasemi_nand_probe(struct platform_device *ofdev) | |||
110 | pr_debug("pasemi_nand at %pR\n", &res); | 110 | pr_debug("pasemi_nand at %pR\n", &res); |
111 | 111 | ||
112 | /* Allocate memory for MTD device structure and private data */ | 112 | /* Allocate memory for MTD device structure and private data */ |
113 | pasemi_nand_mtd = kzalloc(sizeof(struct mtd_info) + | 113 | chip = kzalloc(sizeof(struct nand_chip), GFP_KERNEL); |
114 | sizeof(struct nand_chip), GFP_KERNEL); | 114 | if (!chip) { |
115 | if (!pasemi_nand_mtd) { | ||
116 | printk(KERN_WARNING | 115 | printk(KERN_WARNING |
117 | "Unable to allocate PASEMI NAND MTD device structure\n"); | 116 | "Unable to allocate PASEMI NAND MTD device structure\n"); |
118 | err = -ENOMEM; | 117 | err = -ENOMEM; |
119 | goto out; | 118 | goto out; |
120 | } | 119 | } |
121 | 120 | ||
122 | /* Get pointer to private data */ | 121 | pasemi_nand_mtd = nand_to_mtd(chip); |
123 | chip = (struct nand_chip *)&pasemi_nand_mtd[1]; | ||
124 | 122 | ||
125 | /* Link the private data with the MTD structure */ | 123 | /* Link the private data with the MTD structure */ |
126 | pasemi_nand_mtd->priv = chip; | ||
127 | pasemi_nand_mtd->dev.parent = &ofdev->dev; | 124 | pasemi_nand_mtd->dev.parent = &ofdev->dev; |
128 | 125 | ||
129 | chip->IO_ADDR_R = of_iomap(np, 0); | 126 | chip->IO_ADDR_R = of_iomap(np, 0); |
@@ -180,7 +177,7 @@ static int pasemi_nand_probe(struct platform_device *ofdev) | |||
180 | out_ior: | 177 | out_ior: |
181 | iounmap(chip->IO_ADDR_R); | 178 | iounmap(chip->IO_ADDR_R); |
182 | out_mtd: | 179 | out_mtd: |
183 | kfree(pasemi_nand_mtd); | 180 | kfree(chip); |
184 | out: | 181 | out: |
185 | return err; | 182 | return err; |
186 | } | 183 | } |
@@ -192,7 +189,7 @@ static int pasemi_nand_remove(struct platform_device *ofdev) | |||
192 | if (!pasemi_nand_mtd) | 189 | if (!pasemi_nand_mtd) |
193 | return 0; | 190 | return 0; |
194 | 191 | ||
195 | chip = pasemi_nand_mtd->priv; | 192 | chip = mtd_to_nand(pasemi_nand_mtd); |
196 | 193 | ||
197 | /* Release resources, unregister device */ | 194 | /* Release resources, unregister device */ |
198 | nand_release(pasemi_nand_mtd); | 195 | nand_release(pasemi_nand_mtd); |
@@ -202,7 +199,7 @@ static int pasemi_nand_remove(struct platform_device *ofdev) | |||
202 | iounmap(chip->IO_ADDR_R); | 199 | iounmap(chip->IO_ADDR_R); |
203 | 200 | ||
204 | /* Free the MTD device structure */ | 201 | /* Free the MTD device structure */ |
205 | kfree(pasemi_nand_mtd); | 202 | kfree(chip); |
206 | 203 | ||
207 | pasemi_nand_mtd = NULL; | 204 | pasemi_nand_mtd = NULL; |
208 | 205 | ||
diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c index 65b9dbbe6d6a..a0e26dea1424 100644 --- a/drivers/mtd/nand/plat_nand.c +++ b/drivers/mtd/nand/plat_nand.c | |||
@@ -20,7 +20,6 @@ | |||
20 | 20 | ||
21 | struct plat_nand_data { | 21 | struct plat_nand_data { |
22 | struct nand_chip chip; | 22 | struct nand_chip chip; |
23 | struct mtd_info mtd; | ||
24 | void __iomem *io_base; | 23 | void __iomem *io_base; |
25 | }; | 24 | }; |
26 | 25 | ||
@@ -30,8 +29,8 @@ struct plat_nand_data { | |||
30 | static int plat_nand_probe(struct platform_device *pdev) | 29 | static int plat_nand_probe(struct platform_device *pdev) |
31 | { | 30 | { |
32 | struct platform_nand_data *pdata = dev_get_platdata(&pdev->dev); | 31 | struct platform_nand_data *pdata = dev_get_platdata(&pdev->dev); |
33 | struct mtd_part_parser_data ppdata; | ||
34 | struct plat_nand_data *data; | 32 | struct plat_nand_data *data; |
33 | struct mtd_info *mtd; | ||
35 | struct resource *res; | 34 | struct resource *res; |
36 | const char **part_types; | 35 | const char **part_types; |
37 | int err = 0; | 36 | int err = 0; |
@@ -57,9 +56,9 @@ static int plat_nand_probe(struct platform_device *pdev) | |||
57 | if (IS_ERR(data->io_base)) | 56 | if (IS_ERR(data->io_base)) |
58 | return PTR_ERR(data->io_base); | 57 | return PTR_ERR(data->io_base); |
59 | 58 | ||
60 | data->chip.priv = &data; | 59 | nand_set_flash_node(&data->chip, pdev->dev.of_node); |
61 | data->mtd.priv = &data->chip; | 60 | mtd = nand_to_mtd(&data->chip); |
62 | data->mtd.dev.parent = &pdev->dev; | 61 | mtd->dev.parent = &pdev->dev; |
63 | 62 | ||
64 | data->chip.IO_ADDR_R = data->io_base; | 63 | data->chip.IO_ADDR_R = data->io_base; |
65 | data->chip.IO_ADDR_W = data->io_base; | 64 | data->chip.IO_ADDR_W = data->io_base; |
@@ -87,22 +86,21 @@ static int plat_nand_probe(struct platform_device *pdev) | |||
87 | } | 86 | } |
88 | 87 | ||
89 | /* Scan to find existence of the device */ | 88 | /* Scan to find existence of the device */ |
90 | if (nand_scan(&data->mtd, pdata->chip.nr_chips)) { | 89 | if (nand_scan(mtd, pdata->chip.nr_chips)) { |
91 | err = -ENXIO; | 90 | err = -ENXIO; |
92 | goto out; | 91 | goto out; |
93 | } | 92 | } |
94 | 93 | ||
95 | part_types = pdata->chip.part_probe_types; | 94 | part_types = pdata->chip.part_probe_types; |
96 | 95 | ||
97 | ppdata.of_node = pdev->dev.of_node; | 96 | err = mtd_device_parse_register(mtd, part_types, NULL, |
98 | err = mtd_device_parse_register(&data->mtd, part_types, &ppdata, | ||
99 | pdata->chip.partitions, | 97 | pdata->chip.partitions, |
100 | pdata->chip.nr_partitions); | 98 | pdata->chip.nr_partitions); |
101 | 99 | ||
102 | if (!err) | 100 | if (!err) |
103 | return err; | 101 | return err; |
104 | 102 | ||
105 | nand_release(&data->mtd); | 103 | nand_release(mtd); |
106 | out: | 104 | out: |
107 | if (pdata->ctrl.remove) | 105 | if (pdata->ctrl.remove) |
108 | pdata->ctrl.remove(pdev); | 106 | pdata->ctrl.remove(pdev); |
@@ -117,7 +115,7 @@ static int plat_nand_remove(struct platform_device *pdev) | |||
117 | struct plat_nand_data *data = platform_get_drvdata(pdev); | 115 | struct plat_nand_data *data = platform_get_drvdata(pdev); |
118 | struct platform_nand_data *pdata = dev_get_platdata(&pdev->dev); | 116 | struct platform_nand_data *pdata = dev_get_platdata(&pdev->dev); |
119 | 117 | ||
120 | nand_release(&data->mtd); | 118 | nand_release(nand_to_mtd(&data->chip)); |
121 | if (pdata->ctrl.remove) | 119 | if (pdata->ctrl.remove) |
122 | pdata->ctrl.remove(pdev); | 120 | pdata->ctrl.remove(pdev); |
123 | 121 | ||
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index e453ae9a17fa..86fc245dc71a 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c | |||
@@ -30,11 +30,6 @@ | |||
30 | #include <linux/of.h> | 30 | #include <linux/of.h> |
31 | #include <linux/of_device.h> | 31 | #include <linux/of_device.h> |
32 | #include <linux/of_mtd.h> | 32 | #include <linux/of_mtd.h> |
33 | |||
34 | #if defined(CONFIG_ARM) && (defined(CONFIG_ARCH_PXA) || defined(CONFIG_ARCH_MMP)) | ||
35 | #define ARCH_HAS_DMA | ||
36 | #endif | ||
37 | |||
38 | #include <linux/platform_data/mtd-nand-pxa3xx.h> | 33 | #include <linux/platform_data/mtd-nand-pxa3xx.h> |
39 | 34 | ||
40 | #define CHIP_DELAY_TIMEOUT msecs_to_jiffies(200) | 35 | #define CHIP_DELAY_TIMEOUT msecs_to_jiffies(200) |
@@ -172,7 +167,6 @@ enum pxa3xx_nand_variant { | |||
172 | 167 | ||
173 | struct pxa3xx_nand_host { | 168 | struct pxa3xx_nand_host { |
174 | struct nand_chip chip; | 169 | struct nand_chip chip; |
175 | struct mtd_info *mtd; | ||
176 | void *info_data; | 170 | void *info_data; |
177 | 171 | ||
178 | /* page size of attached chip */ | 172 | /* page size of attached chip */ |
@@ -455,14 +449,15 @@ static int pxa3xx_nand_init_timings_compat(struct pxa3xx_nand_host *host, | |||
455 | struct nand_chip *chip = &host->chip; | 449 | struct nand_chip *chip = &host->chip; |
456 | struct pxa3xx_nand_info *info = host->info_data; | 450 | struct pxa3xx_nand_info *info = host->info_data; |
457 | const struct pxa3xx_nand_flash *f = NULL; | 451 | const struct pxa3xx_nand_flash *f = NULL; |
452 | struct mtd_info *mtd = nand_to_mtd(&host->chip); | ||
458 | int i, id, ntypes; | 453 | int i, id, ntypes; |
459 | 454 | ||
460 | ntypes = ARRAY_SIZE(builtin_flash_types); | 455 | ntypes = ARRAY_SIZE(builtin_flash_types); |
461 | 456 | ||
462 | chip->cmdfunc(host->mtd, NAND_CMD_READID, 0x00, -1); | 457 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); |
463 | 458 | ||
464 | id = chip->read_byte(host->mtd); | 459 | id = chip->read_byte(mtd); |
465 | id |= chip->read_byte(host->mtd) << 0x8; | 460 | id |= chip->read_byte(mtd) << 0x8; |
466 | 461 | ||
467 | for (i = 0; i < ntypes; i++) { | 462 | for (i = 0; i < ntypes; i++) { |
468 | f = &builtin_flash_types[i]; | 463 | f = &builtin_flash_types[i]; |
@@ -895,7 +890,7 @@ static void set_command_address(struct pxa3xx_nand_info *info, | |||
895 | static void prepare_start_command(struct pxa3xx_nand_info *info, int command) | 890 | static void prepare_start_command(struct pxa3xx_nand_info *info, int command) |
896 | { | 891 | { |
897 | struct pxa3xx_nand_host *host = info->host[info->cs]; | 892 | struct pxa3xx_nand_host *host = info->host[info->cs]; |
898 | struct mtd_info *mtd = host->mtd; | 893 | struct mtd_info *mtd = nand_to_mtd(&host->chip); |
899 | 894 | ||
900 | /* reset data and oob column point to handle data */ | 895 | /* reset data and oob column point to handle data */ |
901 | info->buf_start = 0; | 896 | info->buf_start = 0; |
@@ -948,7 +943,7 @@ static int prepare_set_command(struct pxa3xx_nand_info *info, int command, | |||
948 | struct mtd_info *mtd; | 943 | struct mtd_info *mtd; |
949 | 944 | ||
950 | host = info->host[info->cs]; | 945 | host = info->host[info->cs]; |
951 | mtd = host->mtd; | 946 | mtd = nand_to_mtd(&host->chip); |
952 | addr_cycle = 0; | 947 | addr_cycle = 0; |
953 | exec_cmd = 1; | 948 | exec_cmd = 1; |
954 | 949 | ||
@@ -1118,7 +1113,8 @@ static int prepare_set_command(struct pxa3xx_nand_info *info, int command, | |||
1118 | static void nand_cmdfunc(struct mtd_info *mtd, unsigned command, | 1113 | static void nand_cmdfunc(struct mtd_info *mtd, unsigned command, |
1119 | int column, int page_addr) | 1114 | int column, int page_addr) |
1120 | { | 1115 | { |
1121 | struct pxa3xx_nand_host *host = mtd->priv; | 1116 | struct nand_chip *chip = mtd_to_nand(mtd); |
1117 | struct pxa3xx_nand_host *host = nand_get_controller_data(chip); | ||
1122 | struct pxa3xx_nand_info *info = host->info_data; | 1118 | struct pxa3xx_nand_info *info = host->info_data; |
1123 | int exec_cmd; | 1119 | int exec_cmd; |
1124 | 1120 | ||
@@ -1166,7 +1162,8 @@ static void nand_cmdfunc_extended(struct mtd_info *mtd, | |||
1166 | const unsigned command, | 1162 | const unsigned command, |
1167 | int column, int page_addr) | 1163 | int column, int page_addr) |
1168 | { | 1164 | { |
1169 | struct pxa3xx_nand_host *host = mtd->priv; | 1165 | struct nand_chip *chip = mtd_to_nand(mtd); |
1166 | struct pxa3xx_nand_host *host = nand_get_controller_data(chip); | ||
1170 | struct pxa3xx_nand_info *info = host->info_data; | 1167 | struct pxa3xx_nand_info *info = host->info_data; |
1171 | int exec_cmd, ext_cmd_type; | 1168 | int exec_cmd, ext_cmd_type; |
1172 | 1169 | ||
@@ -1286,7 +1283,7 @@ static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd, | |||
1286 | struct nand_chip *chip, uint8_t *buf, int oob_required, | 1283 | struct nand_chip *chip, uint8_t *buf, int oob_required, |
1287 | int page) | 1284 | int page) |
1288 | { | 1285 | { |
1289 | struct pxa3xx_nand_host *host = mtd->priv; | 1286 | struct pxa3xx_nand_host *host = nand_get_controller_data(chip); |
1290 | struct pxa3xx_nand_info *info = host->info_data; | 1287 | struct pxa3xx_nand_info *info = host->info_data; |
1291 | 1288 | ||
1292 | chip->read_buf(mtd, buf, mtd->writesize); | 1289 | chip->read_buf(mtd, buf, mtd->writesize); |
@@ -1312,7 +1309,8 @@ static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd, | |||
1312 | 1309 | ||
1313 | static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd) | 1310 | static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd) |
1314 | { | 1311 | { |
1315 | struct pxa3xx_nand_host *host = mtd->priv; | 1312 | struct nand_chip *chip = mtd_to_nand(mtd); |
1313 | struct pxa3xx_nand_host *host = nand_get_controller_data(chip); | ||
1316 | struct pxa3xx_nand_info *info = host->info_data; | 1314 | struct pxa3xx_nand_info *info = host->info_data; |
1317 | char retval = 0xFF; | 1315 | char retval = 0xFF; |
1318 | 1316 | ||
@@ -1325,7 +1323,8 @@ static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd) | |||
1325 | 1323 | ||
1326 | static u16 pxa3xx_nand_read_word(struct mtd_info *mtd) | 1324 | static u16 pxa3xx_nand_read_word(struct mtd_info *mtd) |
1327 | { | 1325 | { |
1328 | struct pxa3xx_nand_host *host = mtd->priv; | 1326 | struct nand_chip *chip = mtd_to_nand(mtd); |
1327 | struct pxa3xx_nand_host *host = nand_get_controller_data(chip); | ||
1329 | struct pxa3xx_nand_info *info = host->info_data; | 1328 | struct pxa3xx_nand_info *info = host->info_data; |
1330 | u16 retval = 0xFFFF; | 1329 | u16 retval = 0xFFFF; |
1331 | 1330 | ||
@@ -1338,7 +1337,8 @@ static u16 pxa3xx_nand_read_word(struct mtd_info *mtd) | |||
1338 | 1337 | ||
1339 | static void pxa3xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | 1338 | static void pxa3xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) |
1340 | { | 1339 | { |
1341 | struct pxa3xx_nand_host *host = mtd->priv; | 1340 | struct nand_chip *chip = mtd_to_nand(mtd); |
1341 | struct pxa3xx_nand_host *host = nand_get_controller_data(chip); | ||
1342 | struct pxa3xx_nand_info *info = host->info_data; | 1342 | struct pxa3xx_nand_info *info = host->info_data; |
1343 | int real_len = min_t(size_t, len, info->buf_count - info->buf_start); | 1343 | int real_len = min_t(size_t, len, info->buf_count - info->buf_start); |
1344 | 1344 | ||
@@ -1349,7 +1349,8 @@ static void pxa3xx_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | |||
1349 | static void pxa3xx_nand_write_buf(struct mtd_info *mtd, | 1349 | static void pxa3xx_nand_write_buf(struct mtd_info *mtd, |
1350 | const uint8_t *buf, int len) | 1350 | const uint8_t *buf, int len) |
1351 | { | 1351 | { |
1352 | struct pxa3xx_nand_host *host = mtd->priv; | 1352 | struct nand_chip *chip = mtd_to_nand(mtd); |
1353 | struct pxa3xx_nand_host *host = nand_get_controller_data(chip); | ||
1353 | struct pxa3xx_nand_info *info = host->info_data; | 1354 | struct pxa3xx_nand_info *info = host->info_data; |
1354 | int real_len = min_t(size_t, len, info->buf_count - info->buf_start); | 1355 | int real_len = min_t(size_t, len, info->buf_count - info->buf_start); |
1355 | 1356 | ||
@@ -1364,7 +1365,8 @@ static void pxa3xx_nand_select_chip(struct mtd_info *mtd, int chip) | |||
1364 | 1365 | ||
1365 | static int pxa3xx_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *this) | 1366 | static int pxa3xx_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *this) |
1366 | { | 1367 | { |
1367 | struct pxa3xx_nand_host *host = mtd->priv; | 1368 | struct nand_chip *chip = mtd_to_nand(mtd); |
1369 | struct pxa3xx_nand_host *host = nand_get_controller_data(chip); | ||
1368 | struct pxa3xx_nand_info *info = host->info_data; | 1370 | struct pxa3xx_nand_info *info = host->info_data; |
1369 | 1371 | ||
1370 | if (info->need_wait) { | 1372 | if (info->need_wait) { |
@@ -1387,37 +1389,53 @@ static int pxa3xx_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *this) | |||
1387 | return NAND_STATUS_READY; | 1389 | return NAND_STATUS_READY; |
1388 | } | 1390 | } |
1389 | 1391 | ||
1390 | static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info) | 1392 | static int pxa3xx_nand_config_ident(struct pxa3xx_nand_info *info) |
1391 | { | 1393 | { |
1394 | struct pxa3xx_nand_host *host = info->host[info->cs]; | ||
1392 | struct platform_device *pdev = info->pdev; | 1395 | struct platform_device *pdev = info->pdev; |
1393 | struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); | 1396 | struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); |
1394 | struct pxa3xx_nand_host *host = info->host[info->cs]; | 1397 | const struct nand_sdr_timings *timings; |
1395 | struct mtd_info *mtd = host->mtd; | ||
1396 | struct nand_chip *chip = mtd->priv; | ||
1397 | 1398 | ||
1398 | /* configure default flash values */ | 1399 | /* Configure default flash values */ |
1400 | info->chunk_size = PAGE_CHUNK_SIZE; | ||
1399 | info->reg_ndcr = 0x0; /* enable all interrupts */ | 1401 | info->reg_ndcr = 0x0; /* enable all interrupts */ |
1400 | info->reg_ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0; | 1402 | info->reg_ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0; |
1401 | info->reg_ndcr |= NDCR_RD_ID_CNT(READ_ID_BYTES); | 1403 | info->reg_ndcr |= NDCR_RD_ID_CNT(READ_ID_BYTES); |
1402 | info->reg_ndcr |= NDCR_SPARE_EN; /* enable spare by default */ | 1404 | info->reg_ndcr |= NDCR_SPARE_EN; |
1405 | |||
1406 | /* use the common timing to make a try */ | ||
1407 | timings = onfi_async_timing_mode_to_sdr_timings(0); | ||
1408 | if (IS_ERR(timings)) | ||
1409 | return PTR_ERR(timings); | ||
1410 | |||
1411 | pxa3xx_nand_set_sdr_timing(host, timings); | ||
1412 | return 0; | ||
1413 | } | ||
1414 | |||
1415 | static void pxa3xx_nand_config_tail(struct pxa3xx_nand_info *info) | ||
1416 | { | ||
1417 | struct pxa3xx_nand_host *host = info->host[info->cs]; | ||
1418 | struct nand_chip *chip = &host->chip; | ||
1419 | struct mtd_info *mtd = nand_to_mtd(chip); | ||
1420 | |||
1403 | info->reg_ndcr |= (host->col_addr_cycles == 2) ? NDCR_RA_START : 0; | 1421 | info->reg_ndcr |= (host->col_addr_cycles == 2) ? NDCR_RA_START : 0; |
1404 | info->reg_ndcr |= (chip->page_shift == 6) ? NDCR_PG_PER_BLK : 0; | 1422 | info->reg_ndcr |= (chip->page_shift == 6) ? NDCR_PG_PER_BLK : 0; |
1405 | info->reg_ndcr |= (mtd->writesize == 2048) ? NDCR_PAGE_SZ : 0; | 1423 | info->reg_ndcr |= (mtd->writesize == 2048) ? NDCR_PAGE_SZ : 0; |
1406 | |||
1407 | return 0; | ||
1408 | } | 1424 | } |
1409 | 1425 | ||
1410 | static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info) | 1426 | static void pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info) |
1411 | { | 1427 | { |
1428 | struct platform_device *pdev = info->pdev; | ||
1429 | struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); | ||
1412 | uint32_t ndcr = nand_readl(info, NDCR); | 1430 | uint32_t ndcr = nand_readl(info, NDCR); |
1413 | 1431 | ||
1414 | /* Set an initial chunk size */ | 1432 | /* Set an initial chunk size */ |
1415 | info->chunk_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512; | 1433 | info->chunk_size = ndcr & NDCR_PAGE_SZ ? 2048 : 512; |
1416 | info->reg_ndcr = ndcr & | 1434 | info->reg_ndcr = ndcr & |
1417 | ~(NDCR_INT_MASK | NDCR_ND_ARB_EN | NFCV1_NDCR_ARB_CNTL); | 1435 | ~(NDCR_INT_MASK | NDCR_ND_ARB_EN | NFCV1_NDCR_ARB_CNTL); |
1436 | info->reg_ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0; | ||
1418 | info->ndtr0cs0 = nand_readl(info, NDTR0CS0); | 1437 | info->ndtr0cs0 = nand_readl(info, NDTR0CS0); |
1419 | info->ndtr1cs0 = nand_readl(info, NDTR1CS0); | 1438 | info->ndtr1cs0 = nand_readl(info, NDTR1CS0); |
1420 | return 0; | ||
1421 | } | 1439 | } |
1422 | 1440 | ||
1423 | static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info) | 1441 | static int pxa3xx_nand_init_buff(struct pxa3xx_nand_info *info) |
@@ -1483,32 +1501,6 @@ static void pxa3xx_nand_free_buff(struct pxa3xx_nand_info *info) | |||
1483 | kfree(info->data_buff); | 1501 | kfree(info->data_buff); |
1484 | } | 1502 | } |
1485 | 1503 | ||
1486 | static int pxa3xx_nand_sensing(struct pxa3xx_nand_host *host) | ||
1487 | { | ||
1488 | struct pxa3xx_nand_info *info = host->info_data; | ||
1489 | struct mtd_info *mtd; | ||
1490 | struct nand_chip *chip; | ||
1491 | const struct nand_sdr_timings *timings; | ||
1492 | int ret; | ||
1493 | |||
1494 | mtd = info->host[info->cs]->mtd; | ||
1495 | chip = mtd->priv; | ||
1496 | |||
1497 | /* use the common timing to make a try */ | ||
1498 | timings = onfi_async_timing_mode_to_sdr_timings(0); | ||
1499 | if (IS_ERR(timings)) | ||
1500 | return PTR_ERR(timings); | ||
1501 | |||
1502 | pxa3xx_nand_set_sdr_timing(host, timings); | ||
1503 | |||
1504 | chip->cmdfunc(mtd, NAND_CMD_RESET, 0, 0); | ||
1505 | ret = chip->waitfunc(mtd, chip); | ||
1506 | if (ret & NAND_STATUS_FAIL) | ||
1507 | return -ENODEV; | ||
1508 | |||
1509 | return 0; | ||
1510 | } | ||
1511 | |||
1512 | static int pxa_ecc_init(struct pxa3xx_nand_info *info, | 1504 | static int pxa_ecc_init(struct pxa3xx_nand_info *info, |
1513 | struct nand_ecc_ctrl *ecc, | 1505 | struct nand_ecc_ctrl *ecc, |
1514 | int strength, int ecc_stepsize, int page_size) | 1506 | int strength, int ecc_stepsize, int page_size) |
@@ -1580,34 +1572,22 @@ static int pxa_ecc_init(struct pxa3xx_nand_info *info, | |||
1580 | 1572 | ||
1581 | static int pxa3xx_nand_scan(struct mtd_info *mtd) | 1573 | static int pxa3xx_nand_scan(struct mtd_info *mtd) |
1582 | { | 1574 | { |
1583 | struct pxa3xx_nand_host *host = mtd->priv; | 1575 | struct nand_chip *chip = mtd_to_nand(mtd); |
1576 | struct pxa3xx_nand_host *host = nand_get_controller_data(chip); | ||
1584 | struct pxa3xx_nand_info *info = host->info_data; | 1577 | struct pxa3xx_nand_info *info = host->info_data; |
1585 | struct platform_device *pdev = info->pdev; | 1578 | struct platform_device *pdev = info->pdev; |
1586 | struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); | 1579 | struct pxa3xx_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); |
1587 | struct nand_chip *chip = mtd->priv; | ||
1588 | int ret; | 1580 | int ret; |
1589 | uint16_t ecc_strength, ecc_step; | 1581 | uint16_t ecc_strength, ecc_step; |
1590 | 1582 | ||
1591 | if (pdata->keep_config && !pxa3xx_nand_detect_config(info)) | 1583 | if (pdata->keep_config) { |
1592 | goto KEEP_CONFIG; | 1584 | pxa3xx_nand_detect_config(info); |
1593 | 1585 | } else { | |
1594 | /* Set a default chunk size */ | 1586 | ret = pxa3xx_nand_config_ident(info); |
1595 | info->chunk_size = 512; | 1587 | if (ret) |
1596 | 1588 | return ret; | |
1597 | ret = pxa3xx_nand_config_flash(info); | ||
1598 | if (ret) | ||
1599 | return ret; | ||
1600 | |||
1601 | ret = pxa3xx_nand_sensing(host); | ||
1602 | if (ret) { | ||
1603 | dev_info(&info->pdev->dev, "There is no chip on cs %d!\n", | ||
1604 | info->cs); | ||
1605 | |||
1606 | return ret; | ||
1607 | } | 1589 | } |
1608 | 1590 | ||
1609 | KEEP_CONFIG: | ||
1610 | info->reg_ndcr |= (pdata->enable_arbiter) ? NDCR_ND_ARB_EN : 0; | ||
1611 | if (info->reg_ndcr & NDCR_DWIDTH_M) | 1591 | if (info->reg_ndcr & NDCR_DWIDTH_M) |
1612 | chip->options |= NAND_BUSWIDTH_16; | 1592 | chip->options |= NAND_BUSWIDTH_16; |
1613 | 1593 | ||
@@ -1692,11 +1672,16 @@ KEEP_CONFIG: | |||
1692 | host->row_addr_cycles = 3; | 1672 | host->row_addr_cycles = 3; |
1693 | else | 1673 | else |
1694 | host->row_addr_cycles = 2; | 1674 | host->row_addr_cycles = 2; |
1675 | |||
1676 | if (!pdata->keep_config) | ||
1677 | pxa3xx_nand_config_tail(info); | ||
1678 | |||
1695 | return nand_scan_tail(mtd); | 1679 | return nand_scan_tail(mtd); |
1696 | } | 1680 | } |
1697 | 1681 | ||
1698 | static int alloc_nand_resource(struct platform_device *pdev) | 1682 | static int alloc_nand_resource(struct platform_device *pdev) |
1699 | { | 1683 | { |
1684 | struct device_node *np = pdev->dev.of_node; | ||
1700 | struct pxa3xx_nand_platform_data *pdata; | 1685 | struct pxa3xx_nand_platform_data *pdata; |
1701 | struct pxa3xx_nand_info *info; | 1686 | struct pxa3xx_nand_info *info; |
1702 | struct pxa3xx_nand_host *host; | 1687 | struct pxa3xx_nand_host *host; |
@@ -1708,24 +1693,27 @@ static int alloc_nand_resource(struct platform_device *pdev) | |||
1708 | pdata = dev_get_platdata(&pdev->dev); | 1693 | pdata = dev_get_platdata(&pdev->dev); |
1709 | if (pdata->num_cs <= 0) | 1694 | if (pdata->num_cs <= 0) |
1710 | return -ENODEV; | 1695 | return -ENODEV; |
1711 | info = devm_kzalloc(&pdev->dev, sizeof(*info) + (sizeof(*mtd) + | 1696 | info = devm_kzalloc(&pdev->dev, |
1712 | sizeof(*host)) * pdata->num_cs, GFP_KERNEL); | 1697 | sizeof(*info) + sizeof(*host) * pdata->num_cs, |
1698 | GFP_KERNEL); | ||
1713 | if (!info) | 1699 | if (!info) |
1714 | return -ENOMEM; | 1700 | return -ENOMEM; |
1715 | 1701 | ||
1716 | info->pdev = pdev; | 1702 | info->pdev = pdev; |
1717 | info->variant = pxa3xx_nand_get_variant(pdev); | 1703 | info->variant = pxa3xx_nand_get_variant(pdev); |
1718 | for (cs = 0; cs < pdata->num_cs; cs++) { | 1704 | for (cs = 0; cs < pdata->num_cs; cs++) { |
1719 | mtd = (void *)&info[1] + (sizeof(*mtd) + sizeof(*host)) * cs; | 1705 | host = (void *)&info[1] + sizeof(*host) * cs; |
1720 | chip = (struct nand_chip *)(&mtd[1]); | 1706 | chip = &host->chip; |
1721 | host = (struct pxa3xx_nand_host *)chip; | 1707 | nand_set_controller_data(chip, host); |
1708 | mtd = nand_to_mtd(chip); | ||
1722 | info->host[cs] = host; | 1709 | info->host[cs] = host; |
1723 | host->mtd = mtd; | ||
1724 | host->cs = cs; | 1710 | host->cs = cs; |
1725 | host->info_data = info; | 1711 | host->info_data = info; |
1726 | mtd->priv = host; | ||
1727 | mtd->dev.parent = &pdev->dev; | 1712 | mtd->dev.parent = &pdev->dev; |
1713 | /* FIXME: all chips use the same device tree partitions */ | ||
1714 | nand_set_flash_node(chip, np); | ||
1728 | 1715 | ||
1716 | nand_set_controller_data(chip, host); | ||
1729 | chip->ecc.read_page = pxa3xx_nand_read_page_hwecc; | 1717 | chip->ecc.read_page = pxa3xx_nand_read_page_hwecc; |
1730 | chip->ecc.write_page = pxa3xx_nand_write_page_hwecc; | 1718 | chip->ecc.write_page = pxa3xx_nand_write_page_hwecc; |
1731 | chip->controller = &info->controller; | 1719 | chip->controller = &info->controller; |
@@ -1845,7 +1833,7 @@ static int pxa3xx_nand_remove(struct platform_device *pdev) | |||
1845 | clk_disable_unprepare(info->clk); | 1833 | clk_disable_unprepare(info->clk); |
1846 | 1834 | ||
1847 | for (cs = 0; cs < pdata->num_cs; cs++) | 1835 | for (cs = 0; cs < pdata->num_cs; cs++) |
1848 | nand_release(info->host[cs]->mtd); | 1836 | nand_release(nand_to_mtd(&info->host[cs]->chip)); |
1849 | return 0; | 1837 | return 0; |
1850 | } | 1838 | } |
1851 | 1839 | ||
@@ -1886,7 +1874,6 @@ static int pxa3xx_nand_probe_dt(struct platform_device *pdev) | |||
1886 | static int pxa3xx_nand_probe(struct platform_device *pdev) | 1874 | static int pxa3xx_nand_probe(struct platform_device *pdev) |
1887 | { | 1875 | { |
1888 | struct pxa3xx_nand_platform_data *pdata; | 1876 | struct pxa3xx_nand_platform_data *pdata; |
1889 | struct mtd_part_parser_data ppdata = {}; | ||
1890 | struct pxa3xx_nand_info *info; | 1877 | struct pxa3xx_nand_info *info; |
1891 | int ret, cs, probe_success, dma_available; | 1878 | int ret, cs, probe_success, dma_available; |
1892 | 1879 | ||
@@ -1917,7 +1904,7 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) | |||
1917 | info = platform_get_drvdata(pdev); | 1904 | info = platform_get_drvdata(pdev); |
1918 | probe_success = 0; | 1905 | probe_success = 0; |
1919 | for (cs = 0; cs < pdata->num_cs; cs++) { | 1906 | for (cs = 0; cs < pdata->num_cs; cs++) { |
1920 | struct mtd_info *mtd = info->host[cs]->mtd; | 1907 | struct mtd_info *mtd = nand_to_mtd(&info->host[cs]->chip); |
1921 | 1908 | ||
1922 | /* | 1909 | /* |
1923 | * The mtd name matches the one used in 'mtdparts' kernel | 1910 | * The mtd name matches the one used in 'mtdparts' kernel |
@@ -1933,10 +1920,8 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) | |||
1933 | continue; | 1920 | continue; |
1934 | } | 1921 | } |
1935 | 1922 | ||
1936 | ppdata.of_node = pdev->dev.of_node; | 1923 | ret = mtd_device_register(mtd, pdata->parts[cs], |
1937 | ret = mtd_device_parse_register(mtd, NULL, | 1924 | pdata->nr_parts[cs]); |
1938 | &ppdata, pdata->parts[cs], | ||
1939 | pdata->nr_parts[cs]); | ||
1940 | if (!ret) | 1925 | if (!ret) |
1941 | probe_success = 1; | 1926 | probe_success = 1; |
1942 | } | 1927 | } |
@@ -1959,12 +1944,18 @@ static int pxa3xx_nand_suspend(struct device *dev) | |||
1959 | return -EAGAIN; | 1944 | return -EAGAIN; |
1960 | } | 1945 | } |
1961 | 1946 | ||
1947 | clk_disable(info->clk); | ||
1962 | return 0; | 1948 | return 0; |
1963 | } | 1949 | } |
1964 | 1950 | ||
1965 | static int pxa3xx_nand_resume(struct device *dev) | 1951 | static int pxa3xx_nand_resume(struct device *dev) |
1966 | { | 1952 | { |
1967 | struct pxa3xx_nand_info *info = dev_get_drvdata(dev); | 1953 | struct pxa3xx_nand_info *info = dev_get_drvdata(dev); |
1954 | int ret; | ||
1955 | |||
1956 | ret = clk_enable(info->clk); | ||
1957 | if (ret < 0) | ||
1958 | return ret; | ||
1968 | 1959 | ||
1969 | /* We don't want to handle interrupt without calling mtd routine */ | 1960 | /* We don't want to handle interrupt without calling mtd routine */ |
1970 | disable_int(info, NDCR_INT_MASK); | 1961 | disable_int(info, NDCR_INT_MASK); |
diff --git a/drivers/mtd/nand/r852.c b/drivers/mtd/nand/r852.c index d8bb2be327f1..fc9287af4614 100644 --- a/drivers/mtd/nand/r852.c +++ b/drivers/mtd/nand/r852.c | |||
@@ -64,8 +64,8 @@ static inline void r852_write_reg_dword(struct r852_device *dev, | |||
64 | /* returns pointer to our private structure */ | 64 | /* returns pointer to our private structure */ |
65 | static inline struct r852_device *r852_get_dev(struct mtd_info *mtd) | 65 | static inline struct r852_device *r852_get_dev(struct mtd_info *mtd) |
66 | { | 66 | { |
67 | struct nand_chip *chip = mtd->priv; | 67 | struct nand_chip *chip = mtd_to_nand(mtd); |
68 | return chip->priv; | 68 | return nand_get_controller_data(chip); |
69 | } | 69 | } |
70 | 70 | ||
71 | 71 | ||
@@ -361,7 +361,7 @@ static void r852_cmdctl(struct mtd_info *mtd, int dat, unsigned int ctrl) | |||
361 | */ | 361 | */ |
362 | static int r852_wait(struct mtd_info *mtd, struct nand_chip *chip) | 362 | static int r852_wait(struct mtd_info *mtd, struct nand_chip *chip) |
363 | { | 363 | { |
364 | struct r852_device *dev = chip->priv; | 364 | struct r852_device *dev = nand_get_controller_data(chip); |
365 | 365 | ||
366 | unsigned long timeout; | 366 | unsigned long timeout; |
367 | int status; | 367 | int status; |
@@ -477,7 +477,7 @@ static int r852_ecc_correct(struct mtd_info *mtd, uint8_t *dat, | |||
477 | 477 | ||
478 | if (dev->dma_error) { | 478 | if (dev->dma_error) { |
479 | dev->dma_error = 0; | 479 | dev->dma_error = 0; |
480 | return -1; | 480 | return -EIO; |
481 | } | 481 | } |
482 | 482 | ||
483 | r852_write_reg(dev, R852_CTL, dev->ctlreg | R852_CTL_ECC_ACCESS); | 483 | r852_write_reg(dev, R852_CTL, dev->ctlreg | R852_CTL_ECC_ACCESS); |
@@ -491,7 +491,7 @@ static int r852_ecc_correct(struct mtd_info *mtd, uint8_t *dat, | |||
491 | /* ecc uncorrectable error */ | 491 | /* ecc uncorrectable error */ |
492 | if (ecc_status & R852_ECC_FAIL) { | 492 | if (ecc_status & R852_ECC_FAIL) { |
493 | dbg("ecc: unrecoverable error, in half %d", i); | 493 | dbg("ecc: unrecoverable error, in half %d", i); |
494 | error = -1; | 494 | error = -EBADMSG; |
495 | goto exit; | 495 | goto exit; |
496 | } | 496 | } |
497 | 497 | ||
@@ -634,25 +634,21 @@ static void r852_update_media_status(struct r852_device *dev) | |||
634 | */ | 634 | */ |
635 | static int r852_register_nand_device(struct r852_device *dev) | 635 | static int r852_register_nand_device(struct r852_device *dev) |
636 | { | 636 | { |
637 | dev->mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL); | 637 | struct mtd_info *mtd = nand_to_mtd(dev->chip); |
638 | |||
639 | if (!dev->mtd) | ||
640 | goto error1; | ||
641 | 638 | ||
642 | WARN_ON(dev->card_registred); | 639 | WARN_ON(dev->card_registred); |
643 | 640 | ||
644 | dev->mtd->priv = dev->chip; | 641 | mtd->dev.parent = &dev->pci_dev->dev; |
645 | dev->mtd->dev.parent = &dev->pci_dev->dev; | ||
646 | 642 | ||
647 | if (dev->readonly) | 643 | if (dev->readonly) |
648 | dev->chip->options |= NAND_ROM; | 644 | dev->chip->options |= NAND_ROM; |
649 | 645 | ||
650 | r852_engine_enable(dev); | 646 | r852_engine_enable(dev); |
651 | 647 | ||
652 | if (sm_register_device(dev->mtd, dev->sm)) | 648 | if (sm_register_device(mtd, dev->sm)) |
653 | goto error2; | 649 | goto error1; |
654 | 650 | ||
655 | if (device_create_file(&dev->mtd->dev, &dev_attr_media_type)) { | 651 | if (device_create_file(&mtd->dev, &dev_attr_media_type)) { |
656 | message("can't create media type sysfs attribute"); | 652 | message("can't create media type sysfs attribute"); |
657 | goto error3; | 653 | goto error3; |
658 | } | 654 | } |
@@ -660,9 +656,7 @@ static int r852_register_nand_device(struct r852_device *dev) | |||
660 | dev->card_registred = 1; | 656 | dev->card_registred = 1; |
661 | return 0; | 657 | return 0; |
662 | error3: | 658 | error3: |
663 | nand_release(dev->mtd); | 659 | nand_release(mtd); |
664 | error2: | ||
665 | kfree(dev->mtd); | ||
666 | error1: | 660 | error1: |
667 | /* Force card redetect */ | 661 | /* Force card redetect */ |
668 | dev->card_detected = 0; | 662 | dev->card_detected = 0; |
@@ -675,15 +669,15 @@ error1: | |||
675 | 669 | ||
676 | static void r852_unregister_nand_device(struct r852_device *dev) | 670 | static void r852_unregister_nand_device(struct r852_device *dev) |
677 | { | 671 | { |
672 | struct mtd_info *mtd = nand_to_mtd(dev->chip); | ||
673 | |||
678 | if (!dev->card_registred) | 674 | if (!dev->card_registred) |
679 | return; | 675 | return; |
680 | 676 | ||
681 | device_remove_file(&dev->mtd->dev, &dev_attr_media_type); | 677 | device_remove_file(&mtd->dev, &dev_attr_media_type); |
682 | nand_release(dev->mtd); | 678 | nand_release(mtd); |
683 | r852_engine_disable(dev); | 679 | r852_engine_disable(dev); |
684 | dev->card_registred = 0; | 680 | dev->card_registred = 0; |
685 | kfree(dev->mtd); | ||
686 | dev->mtd = NULL; | ||
687 | } | 681 | } |
688 | 682 | ||
689 | /* Card state updater */ | 683 | /* Card state updater */ |
@@ -885,7 +879,7 @@ static int r852_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) | |||
885 | if (!dev) | 879 | if (!dev) |
886 | goto error5; | 880 | goto error5; |
887 | 881 | ||
888 | chip->priv = dev; | 882 | nand_set_controller_data(chip, dev); |
889 | dev->chip = chip; | 883 | dev->chip = chip; |
890 | dev->pci_dev = pci_dev; | 884 | dev->pci_dev = pci_dev; |
891 | pci_set_drvdata(pci_dev, dev); | 885 | pci_set_drvdata(pci_dev, dev); |
@@ -980,7 +974,6 @@ static void r852_remove(struct pci_dev *pci_dev) | |||
980 | 974 | ||
981 | /* Stop interrupts */ | 975 | /* Stop interrupts */ |
982 | r852_disable_irqs(dev); | 976 | r852_disable_irqs(dev); |
983 | synchronize_irq(dev->irq); | ||
984 | free_irq(dev->irq, dev); | 977 | free_irq(dev->irq, dev); |
985 | 978 | ||
986 | /* Cleanup */ | 979 | /* Cleanup */ |
@@ -1032,6 +1025,7 @@ static int r852_suspend(struct device *device) | |||
1032 | static int r852_resume(struct device *device) | 1025 | static int r852_resume(struct device *device) |
1033 | { | 1026 | { |
1034 | struct r852_device *dev = pci_get_drvdata(to_pci_dev(device)); | 1027 | struct r852_device *dev = pci_get_drvdata(to_pci_dev(device)); |
1028 | struct mtd_info *mtd = nand_to_mtd(dev->chip); | ||
1035 | 1029 | ||
1036 | r852_disable_irqs(dev); | 1030 | r852_disable_irqs(dev); |
1037 | r852_card_update_present(dev); | 1031 | r852_card_update_present(dev); |
@@ -1051,9 +1045,9 @@ static int r852_resume(struct device *device) | |||
1051 | /* Otherwise, initialize the card */ | 1045 | /* Otherwise, initialize the card */ |
1052 | if (dev->card_registred) { | 1046 | if (dev->card_registred) { |
1053 | r852_engine_enable(dev); | 1047 | r852_engine_enable(dev); |
1054 | dev->chip->select_chip(dev->mtd, 0); | 1048 | dev->chip->select_chip(mtd, 0); |
1055 | dev->chip->cmdfunc(dev->mtd, NAND_CMD_RESET, -1, -1); | 1049 | dev->chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); |
1056 | dev->chip->select_chip(dev->mtd, -1); | 1050 | dev->chip->select_chip(mtd, -1); |
1057 | } | 1051 | } |
1058 | 1052 | ||
1059 | /* Program card detection IRQ */ | 1053 | /* Program card detection IRQ */ |
diff --git a/drivers/mtd/nand/r852.h b/drivers/mtd/nand/r852.h index e6a21d9d22c6..d042ddb71a8b 100644 --- a/drivers/mtd/nand/r852.h +++ b/drivers/mtd/nand/r852.h | |||
@@ -108,7 +108,6 @@ | |||
108 | 108 | ||
109 | struct r852_device { | 109 | struct r852_device { |
110 | void __iomem *mmio; /* mmio */ | 110 | void __iomem *mmio; /* mmio */ |
111 | struct mtd_info *mtd; /* mtd backpointer */ | ||
112 | struct nand_chip *chip; /* nand chip backpointer */ | 111 | struct nand_chip *chip; /* nand chip backpointer */ |
113 | struct pci_dev *pci_dev; /* pci backpointer */ | 112 | struct pci_dev *pci_dev; /* pci backpointer */ |
114 | 113 | ||
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 05105cadd0db..01ac74fa3b95 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c | |||
@@ -104,7 +104,6 @@ struct s3c2410_nand_info; | |||
104 | * @scan_res: The result from calling nand_scan_ident(). | 104 | * @scan_res: The result from calling nand_scan_ident(). |
105 | */ | 105 | */ |
106 | struct s3c2410_nand_mtd { | 106 | struct s3c2410_nand_mtd { |
107 | struct mtd_info mtd; | ||
108 | struct nand_chip chip; | 107 | struct nand_chip chip; |
109 | struct s3c2410_nand_set *set; | 108 | struct s3c2410_nand_set *set; |
110 | struct s3c2410_nand_info *info; | 109 | struct s3c2410_nand_info *info; |
@@ -168,7 +167,8 @@ struct s3c2410_nand_info { | |||
168 | 167 | ||
169 | static struct s3c2410_nand_mtd *s3c2410_nand_mtd_toours(struct mtd_info *mtd) | 168 | static struct s3c2410_nand_mtd *s3c2410_nand_mtd_toours(struct mtd_info *mtd) |
170 | { | 169 | { |
171 | return container_of(mtd, struct s3c2410_nand_mtd, mtd); | 170 | return container_of(mtd_to_nand(mtd), struct s3c2410_nand_mtd, |
171 | chip); | ||
172 | } | 172 | } |
173 | 173 | ||
174 | static struct s3c2410_nand_info *s3c2410_nand_mtd_toinfo(struct mtd_info *mtd) | 174 | static struct s3c2410_nand_info *s3c2410_nand_mtd_toinfo(struct mtd_info *mtd) |
@@ -382,10 +382,10 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) | |||
382 | { | 382 | { |
383 | struct s3c2410_nand_info *info; | 383 | struct s3c2410_nand_info *info; |
384 | struct s3c2410_nand_mtd *nmtd; | 384 | struct s3c2410_nand_mtd *nmtd; |
385 | struct nand_chip *this = mtd->priv; | 385 | struct nand_chip *this = mtd_to_nand(mtd); |
386 | unsigned long cur; | 386 | unsigned long cur; |
387 | 387 | ||
388 | nmtd = this->priv; | 388 | nmtd = nand_get_controller_data(this); |
389 | info = nmtd->info; | 389 | info = nmtd->info; |
390 | 390 | ||
391 | if (chip != -1) | 391 | if (chip != -1) |
@@ -634,7 +634,7 @@ static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, | |||
634 | 634 | ||
635 | static void s3c2410_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) | 635 | static void s3c2410_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) |
636 | { | 636 | { |
637 | struct nand_chip *this = mtd->priv; | 637 | struct nand_chip *this = mtd_to_nand(mtd); |
638 | readsb(this->IO_ADDR_R, buf, len); | 638 | readsb(this->IO_ADDR_R, buf, len); |
639 | } | 639 | } |
640 | 640 | ||
@@ -656,7 +656,7 @@ static void s3c2440_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) | |||
656 | static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf, | 656 | static void s3c2410_nand_write_buf(struct mtd_info *mtd, const u_char *buf, |
657 | int len) | 657 | int len) |
658 | { | 658 | { |
659 | struct nand_chip *this = mtd->priv; | 659 | struct nand_chip *this = mtd_to_nand(mtd); |
660 | writesb(this->IO_ADDR_W, buf, len); | 660 | writesb(this->IO_ADDR_W, buf, len); |
661 | } | 661 | } |
662 | 662 | ||
@@ -745,7 +745,7 @@ static int s3c24xx_nand_remove(struct platform_device *pdev) | |||
745 | 745 | ||
746 | for (mtdno = 0; mtdno < info->mtd_count; mtdno++, ptr++) { | 746 | for (mtdno = 0; mtdno < info->mtd_count; mtdno++, ptr++) { |
747 | pr_debug("releasing mtd %d (%p)\n", mtdno, ptr); | 747 | pr_debug("releasing mtd %d (%p)\n", mtdno, ptr); |
748 | nand_release(&ptr->mtd); | 748 | nand_release(nand_to_mtd(&ptr->chip)); |
749 | } | 749 | } |
750 | } | 750 | } |
751 | 751 | ||
@@ -762,9 +762,11 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info, | |||
762 | struct s3c2410_nand_set *set) | 762 | struct s3c2410_nand_set *set) |
763 | { | 763 | { |
764 | if (set) { | 764 | if (set) { |
765 | mtd->mtd.name = set->name; | 765 | struct mtd_info *mtdinfo = nand_to_mtd(&mtd->chip); |
766 | 766 | ||
767 | return mtd_device_parse_register(&mtd->mtd, NULL, NULL, | 767 | mtdinfo->name = set->name; |
768 | |||
769 | return mtd_device_parse_register(mtdinfo, NULL, NULL, | ||
768 | set->partitions, set->nr_partitions); | 770 | set->partitions, set->nr_partitions); |
769 | } | 771 | } |
770 | 772 | ||
@@ -792,7 +794,7 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, | |||
792 | chip->read_buf = s3c2410_nand_read_buf; | 794 | chip->read_buf = s3c2410_nand_read_buf; |
793 | chip->select_chip = s3c2410_nand_select_chip; | 795 | chip->select_chip = s3c2410_nand_select_chip; |
794 | chip->chip_delay = 50; | 796 | chip->chip_delay = 50; |
795 | chip->priv = nmtd; | 797 | nand_set_controller_data(chip, nmtd); |
796 | chip->options = set->options; | 798 | chip->options = set->options; |
797 | chip->controller = &info->controller; | 799 | chip->controller = &info->controller; |
798 | 800 | ||
@@ -831,7 +833,6 @@ static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, | |||
831 | chip->IO_ADDR_R = chip->IO_ADDR_W; | 833 | chip->IO_ADDR_R = chip->IO_ADDR_W; |
832 | 834 | ||
833 | nmtd->info = info; | 835 | nmtd->info = info; |
834 | nmtd->mtd.priv = chip; | ||
835 | nmtd->set = set; | 836 | nmtd->set = set; |
836 | 837 | ||
837 | #ifdef CONFIG_MTD_NAND_S3C2410_HWECC | 838 | #ifdef CONFIG_MTD_NAND_S3C2410_HWECC |
@@ -1012,19 +1013,21 @@ static int s3c24xx_nand_probe(struct platform_device *pdev) | |||
1012 | nmtd = info->mtds; | 1013 | nmtd = info->mtds; |
1013 | 1014 | ||
1014 | for (setno = 0; setno < nr_sets; setno++, nmtd++) { | 1015 | for (setno = 0; setno < nr_sets; setno++, nmtd++) { |
1016 | struct mtd_info *mtd = nand_to_mtd(&nmtd->chip); | ||
1017 | |||
1015 | pr_debug("initialising set %d (%p, info %p)\n", | 1018 | pr_debug("initialising set %d (%p, info %p)\n", |
1016 | setno, nmtd, info); | 1019 | setno, nmtd, info); |
1017 | 1020 | ||
1018 | nmtd->mtd.dev.parent = &pdev->dev; | 1021 | mtd->dev.parent = &pdev->dev; |
1019 | s3c2410_nand_init_chip(info, nmtd, sets); | 1022 | s3c2410_nand_init_chip(info, nmtd, sets); |
1020 | 1023 | ||
1021 | nmtd->scan_res = nand_scan_ident(&nmtd->mtd, | 1024 | nmtd->scan_res = nand_scan_ident(mtd, |
1022 | (sets) ? sets->nr_chips : 1, | 1025 | (sets) ? sets->nr_chips : 1, |
1023 | NULL); | 1026 | NULL); |
1024 | 1027 | ||
1025 | if (nmtd->scan_res == 0) { | 1028 | if (nmtd->scan_res == 0) { |
1026 | s3c2410_nand_update_chip(info, nmtd); | 1029 | s3c2410_nand_update_chip(info, nmtd); |
1027 | nand_scan_tail(&nmtd->mtd); | 1030 | nand_scan_tail(mtd); |
1028 | s3c2410_nand_add_partition(info, nmtd, sets); | 1031 | s3c2410_nand_add_partition(info, nmtd, sets); |
1029 | } | 1032 | } |
1030 | 1033 | ||
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c index bcba1a924c75..4814402902f9 100644 --- a/drivers/mtd/nand/sh_flctl.c +++ b/drivers/mtd/nand/sh_flctl.c | |||
@@ -160,7 +160,7 @@ static void flctl_setup_dma(struct sh_flctl *flctl) | |||
160 | 160 | ||
161 | memset(&cfg, 0, sizeof(cfg)); | 161 | memset(&cfg, 0, sizeof(cfg)); |
162 | cfg.direction = DMA_MEM_TO_DEV; | 162 | cfg.direction = DMA_MEM_TO_DEV; |
163 | cfg.dst_addr = (dma_addr_t)FLDTFIFO(flctl); | 163 | cfg.dst_addr = flctl->fifo; |
164 | cfg.src_addr = 0; | 164 | cfg.src_addr = 0; |
165 | ret = dmaengine_slave_config(flctl->chan_fifo0_tx, &cfg); | 165 | ret = dmaengine_slave_config(flctl->chan_fifo0_tx, &cfg); |
166 | if (ret < 0) | 166 | if (ret < 0) |
@@ -176,7 +176,7 @@ static void flctl_setup_dma(struct sh_flctl *flctl) | |||
176 | 176 | ||
177 | cfg.direction = DMA_DEV_TO_MEM; | 177 | cfg.direction = DMA_DEV_TO_MEM; |
178 | cfg.dst_addr = 0; | 178 | cfg.dst_addr = 0; |
179 | cfg.src_addr = (dma_addr_t)FLDTFIFO(flctl); | 179 | cfg.src_addr = flctl->fifo; |
180 | ret = dmaengine_slave_config(flctl->chan_fifo0_rx, &cfg); | 180 | ret = dmaengine_slave_config(flctl->chan_fifo0_rx, &cfg); |
181 | if (ret < 0) | 181 | if (ret < 0) |
182 | goto err; | 182 | goto err; |
@@ -607,13 +607,13 @@ static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr) | |||
607 | case FL_REPAIRABLE: | 607 | case FL_REPAIRABLE: |
608 | dev_info(&flctl->pdev->dev, | 608 | dev_info(&flctl->pdev->dev, |
609 | "applied ecc on page 0x%x", page_addr); | 609 | "applied ecc on page 0x%x", page_addr); |
610 | flctl->mtd.ecc_stats.corrected++; | 610 | mtd->ecc_stats.corrected++; |
611 | break; | 611 | break; |
612 | case FL_ERROR: | 612 | case FL_ERROR: |
613 | dev_warn(&flctl->pdev->dev, | 613 | dev_warn(&flctl->pdev->dev, |
614 | "page 0x%x contains corrupted data\n", | 614 | "page 0x%x contains corrupted data\n", |
615 | page_addr); | 615 | page_addr); |
616 | flctl->mtd.ecc_stats.failed++; | 616 | mtd->ecc_stats.failed++; |
617 | break; | 617 | break; |
618 | default: | 618 | default: |
619 | ; | 619 | ; |
@@ -1086,7 +1086,6 @@ static int flctl_probe(struct platform_device *pdev) | |||
1086 | struct sh_flctl_platform_data *pdata; | 1086 | struct sh_flctl_platform_data *pdata; |
1087 | int ret; | 1087 | int ret; |
1088 | int irq; | 1088 | int irq; |
1089 | struct mtd_part_parser_data ppdata = {}; | ||
1090 | 1089 | ||
1091 | flctl = devm_kzalloc(&pdev->dev, sizeof(struct sh_flctl), GFP_KERNEL); | 1090 | flctl = devm_kzalloc(&pdev->dev, sizeof(struct sh_flctl), GFP_KERNEL); |
1092 | if (!flctl) | 1091 | if (!flctl) |
@@ -1096,6 +1095,7 @@ static int flctl_probe(struct platform_device *pdev) | |||
1096 | flctl->reg = devm_ioremap_resource(&pdev->dev, res); | 1095 | flctl->reg = devm_ioremap_resource(&pdev->dev, res); |
1097 | if (IS_ERR(flctl->reg)) | 1096 | if (IS_ERR(flctl->reg)) |
1098 | return PTR_ERR(flctl->reg); | 1097 | return PTR_ERR(flctl->reg); |
1098 | flctl->fifo = res->start + 0x24; /* FLDTFIFO */ | ||
1099 | 1099 | ||
1100 | irq = platform_get_irq(pdev, 0); | 1100 | irq = platform_get_irq(pdev, 0); |
1101 | if (irq < 0) { | 1101 | if (irq < 0) { |
@@ -1121,9 +1121,9 @@ static int flctl_probe(struct platform_device *pdev) | |||
1121 | } | 1121 | } |
1122 | 1122 | ||
1123 | platform_set_drvdata(pdev, flctl); | 1123 | platform_set_drvdata(pdev, flctl); |
1124 | flctl_mtd = &flctl->mtd; | ||
1125 | nand = &flctl->chip; | 1124 | nand = &flctl->chip; |
1126 | flctl_mtd->priv = nand; | 1125 | flctl_mtd = nand_to_mtd(nand); |
1126 | nand_set_flash_node(nand, pdev->dev.of_node); | ||
1127 | flctl_mtd->dev.parent = &pdev->dev; | 1127 | flctl_mtd->dev.parent = &pdev->dev; |
1128 | flctl->pdev = pdev; | 1128 | flctl->pdev = pdev; |
1129 | flctl->hwecc = pdata->has_hwecc; | 1129 | flctl->hwecc = pdata->has_hwecc; |
@@ -1163,9 +1163,7 @@ static int flctl_probe(struct platform_device *pdev) | |||
1163 | if (ret) | 1163 | if (ret) |
1164 | goto err_chip; | 1164 | goto err_chip; |
1165 | 1165 | ||
1166 | ppdata.of_node = pdev->dev.of_node; | 1166 | ret = mtd_device_register(flctl_mtd, pdata->parts, pdata->nr_parts); |
1167 | ret = mtd_device_parse_register(flctl_mtd, NULL, &ppdata, pdata->parts, | ||
1168 | pdata->nr_parts); | ||
1169 | 1167 | ||
1170 | return 0; | 1168 | return 0; |
1171 | 1169 | ||
@@ -1180,7 +1178,7 @@ static int flctl_remove(struct platform_device *pdev) | |||
1180 | struct sh_flctl *flctl = platform_get_drvdata(pdev); | 1178 | struct sh_flctl *flctl = platform_get_drvdata(pdev); |
1181 | 1179 | ||
1182 | flctl_release_dma(flctl); | 1180 | flctl_release_dma(flctl); |
1183 | nand_release(&flctl->mtd); | 1181 | nand_release(nand_to_mtd(&flctl->chip)); |
1184 | pm_runtime_disable(&pdev->dev); | 1182 | pm_runtime_disable(&pdev->dev); |
1185 | 1183 | ||
1186 | return 0; | 1184 | return 0; |
diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c index 082b6009736d..b7d1b55a160b 100644 --- a/drivers/mtd/nand/sharpsl.c +++ b/drivers/mtd/nand/sharpsl.c | |||
@@ -29,13 +29,15 @@ | |||
29 | #include <asm/mach-types.h> | 29 | #include <asm/mach-types.h> |
30 | 30 | ||
31 | struct sharpsl_nand { | 31 | struct sharpsl_nand { |
32 | struct mtd_info mtd; | ||
33 | struct nand_chip chip; | 32 | struct nand_chip chip; |
34 | 33 | ||
35 | void __iomem *io; | 34 | void __iomem *io; |
36 | }; | 35 | }; |
37 | 36 | ||
38 | #define mtd_to_sharpsl(_mtd) container_of(_mtd, struct sharpsl_nand, mtd) | 37 | static inline struct sharpsl_nand *mtd_to_sharpsl(struct mtd_info *mtd) |
38 | { | ||
39 | return container_of(mtd_to_nand(mtd), struct sharpsl_nand, chip); | ||
40 | } | ||
39 | 41 | ||
40 | /* register offset */ | 42 | /* register offset */ |
41 | #define ECCLPLB 0x00 /* line parity 7 - 0 bit */ | 43 | #define ECCLPLB 0x00 /* line parity 7 - 0 bit */ |
@@ -66,7 +68,7 @@ static void sharpsl_nand_hwcontrol(struct mtd_info *mtd, int cmd, | |||
66 | unsigned int ctrl) | 68 | unsigned int ctrl) |
67 | { | 69 | { |
68 | struct sharpsl_nand *sharpsl = mtd_to_sharpsl(mtd); | 70 | struct sharpsl_nand *sharpsl = mtd_to_sharpsl(mtd); |
69 | struct nand_chip *chip = mtd->priv; | 71 | struct nand_chip *chip = mtd_to_nand(mtd); |
70 | 72 | ||
71 | if (ctrl & NAND_CTRL_CHANGE) { | 73 | if (ctrl & NAND_CTRL_CHANGE) { |
72 | unsigned char bits = ctrl & 0x07; | 74 | unsigned char bits = ctrl & 0x07; |
@@ -109,6 +111,7 @@ static int sharpsl_nand_calculate_ecc(struct mtd_info *mtd, const u_char * dat, | |||
109 | static int sharpsl_nand_probe(struct platform_device *pdev) | 111 | static int sharpsl_nand_probe(struct platform_device *pdev) |
110 | { | 112 | { |
111 | struct nand_chip *this; | 113 | struct nand_chip *this; |
114 | struct mtd_info *mtd; | ||
112 | struct resource *r; | 115 | struct resource *r; |
113 | int err = 0; | 116 | int err = 0; |
114 | struct sharpsl_nand *sharpsl; | 117 | struct sharpsl_nand *sharpsl; |
@@ -143,8 +146,8 @@ static int sharpsl_nand_probe(struct platform_device *pdev) | |||
143 | this = (struct nand_chip *)(&sharpsl->chip); | 146 | this = (struct nand_chip *)(&sharpsl->chip); |
144 | 147 | ||
145 | /* Link the private data with the MTD structure */ | 148 | /* Link the private data with the MTD structure */ |
146 | sharpsl->mtd.priv = this; | 149 | mtd = nand_to_mtd(this); |
147 | sharpsl->mtd.dev.parent = &pdev->dev; | 150 | mtd->dev.parent = &pdev->dev; |
148 | 151 | ||
149 | platform_set_drvdata(pdev, sharpsl); | 152 | platform_set_drvdata(pdev, sharpsl); |
150 | 153 | ||
@@ -173,14 +176,14 @@ static int sharpsl_nand_probe(struct platform_device *pdev) | |||
173 | this->ecc.correct = nand_correct_data; | 176 | this->ecc.correct = nand_correct_data; |
174 | 177 | ||
175 | /* Scan to find existence of the device */ | 178 | /* Scan to find existence of the device */ |
176 | err = nand_scan(&sharpsl->mtd, 1); | 179 | err = nand_scan(mtd, 1); |
177 | if (err) | 180 | if (err) |
178 | goto err_scan; | 181 | goto err_scan; |
179 | 182 | ||
180 | /* Register the partitions */ | 183 | /* Register the partitions */ |
181 | sharpsl->mtd.name = "sharpsl-nand"; | 184 | mtd->name = "sharpsl-nand"; |
182 | 185 | ||
183 | err = mtd_device_parse_register(&sharpsl->mtd, NULL, NULL, | 186 | err = mtd_device_parse_register(mtd, NULL, NULL, |
184 | data->partitions, data->nr_partitions); | 187 | data->partitions, data->nr_partitions); |
185 | if (err) | 188 | if (err) |
186 | goto err_add; | 189 | goto err_add; |
@@ -189,7 +192,7 @@ static int sharpsl_nand_probe(struct platform_device *pdev) | |||
189 | return 0; | 192 | return 0; |
190 | 193 | ||
191 | err_add: | 194 | err_add: |
192 | nand_release(&sharpsl->mtd); | 195 | nand_release(mtd); |
193 | 196 | ||
194 | err_scan: | 197 | err_scan: |
195 | iounmap(sharpsl->io); | 198 | iounmap(sharpsl->io); |
@@ -207,7 +210,7 @@ static int sharpsl_nand_remove(struct platform_device *pdev) | |||
207 | struct sharpsl_nand *sharpsl = platform_get_drvdata(pdev); | 210 | struct sharpsl_nand *sharpsl = platform_get_drvdata(pdev); |
208 | 211 | ||
209 | /* Release resources, unregister device */ | 212 | /* Release resources, unregister device */ |
210 | nand_release(&sharpsl->mtd); | 213 | nand_release(nand_to_mtd(&sharpsl->chip)); |
211 | 214 | ||
212 | iounmap(sharpsl->io); | 215 | iounmap(sharpsl->io); |
213 | 216 | ||
diff --git a/drivers/mtd/nand/sm_common.c b/drivers/mtd/nand/sm_common.c index e06b5e5d3287..c514740f9a83 100644 --- a/drivers/mtd/nand/sm_common.c +++ b/drivers/mtd/nand/sm_common.c | |||
@@ -102,7 +102,7 @@ static struct nand_flash_dev nand_xd_flash_ids[] = { | |||
102 | 102 | ||
103 | int sm_register_device(struct mtd_info *mtd, int smartmedia) | 103 | int sm_register_device(struct mtd_info *mtd, int smartmedia) |
104 | { | 104 | { |
105 | struct nand_chip *chip = mtd->priv; | 105 | struct nand_chip *chip = mtd_to_nand(mtd); |
106 | int ret; | 106 | int ret; |
107 | 107 | ||
108 | chip->options |= NAND_SKIP_BBTSCAN; | 108 | chip->options |= NAND_SKIP_BBTSCAN; |
diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c index b94f53427f0f..e3305f9dd6fb 100644 --- a/drivers/mtd/nand/socrates_nand.c +++ b/drivers/mtd/nand/socrates_nand.c | |||
@@ -30,7 +30,6 @@ | |||
30 | 30 | ||
31 | struct socrates_nand_host { | 31 | struct socrates_nand_host { |
32 | struct nand_chip nand_chip; | 32 | struct nand_chip nand_chip; |
33 | struct mtd_info mtd; | ||
34 | void __iomem *io_base; | 33 | void __iomem *io_base; |
35 | struct device *dev; | 34 | struct device *dev; |
36 | }; | 35 | }; |
@@ -45,8 +44,8 @@ static void socrates_nand_write_buf(struct mtd_info *mtd, | |||
45 | const uint8_t *buf, int len) | 44 | const uint8_t *buf, int len) |
46 | { | 45 | { |
47 | int i; | 46 | int i; |
48 | struct nand_chip *this = mtd->priv; | 47 | struct nand_chip *this = mtd_to_nand(mtd); |
49 | struct socrates_nand_host *host = this->priv; | 48 | struct socrates_nand_host *host = nand_get_controller_data(this); |
50 | 49 | ||
51 | for (i = 0; i < len; i++) { | 50 | for (i = 0; i < len; i++) { |
52 | out_be32(host->io_base, FPGA_NAND_ENABLE | | 51 | out_be32(host->io_base, FPGA_NAND_ENABLE | |
@@ -64,8 +63,8 @@ static void socrates_nand_write_buf(struct mtd_info *mtd, | |||
64 | static void socrates_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | 63 | static void socrates_nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) |
65 | { | 64 | { |
66 | int i; | 65 | int i; |
67 | struct nand_chip *this = mtd->priv; | 66 | struct nand_chip *this = mtd_to_nand(mtd); |
68 | struct socrates_nand_host *host = this->priv; | 67 | struct socrates_nand_host *host = nand_get_controller_data(this); |
69 | uint32_t val; | 68 | uint32_t val; |
70 | 69 | ||
71 | val = FPGA_NAND_ENABLE | FPGA_NAND_CMD_READ; | 70 | val = FPGA_NAND_ENABLE | FPGA_NAND_CMD_READ; |
@@ -105,8 +104,8 @@ static uint16_t socrates_nand_read_word(struct mtd_info *mtd) | |||
105 | static void socrates_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, | 104 | static void socrates_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, |
106 | unsigned int ctrl) | 105 | unsigned int ctrl) |
107 | { | 106 | { |
108 | struct nand_chip *nand_chip = mtd->priv; | 107 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
109 | struct socrates_nand_host *host = nand_chip->priv; | 108 | struct socrates_nand_host *host = nand_get_controller_data(nand_chip); |
110 | uint32_t val; | 109 | uint32_t val; |
111 | 110 | ||
112 | if (cmd == NAND_CMD_NONE) | 111 | if (cmd == NAND_CMD_NONE) |
@@ -130,8 +129,8 @@ static void socrates_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, | |||
130 | */ | 129 | */ |
131 | static int socrates_nand_device_ready(struct mtd_info *mtd) | 130 | static int socrates_nand_device_ready(struct mtd_info *mtd) |
132 | { | 131 | { |
133 | struct nand_chip *nand_chip = mtd->priv; | 132 | struct nand_chip *nand_chip = mtd_to_nand(mtd); |
134 | struct socrates_nand_host *host = nand_chip->priv; | 133 | struct socrates_nand_host *host = nand_get_controller_data(nand_chip); |
135 | 134 | ||
136 | if (in_be32(host->io_base) & FPGA_NAND_BUSY) | 135 | if (in_be32(host->io_base) & FPGA_NAND_BUSY) |
137 | return 0; /* busy */ | 136 | return 0; /* busy */ |
@@ -147,7 +146,6 @@ static int socrates_nand_probe(struct platform_device *ofdev) | |||
147 | struct mtd_info *mtd; | 146 | struct mtd_info *mtd; |
148 | struct nand_chip *nand_chip; | 147 | struct nand_chip *nand_chip; |
149 | int res; | 148 | int res; |
150 | struct mtd_part_parser_data ppdata; | ||
151 | 149 | ||
152 | /* Allocate memory for the device structure (and zero it) */ | 150 | /* Allocate memory for the device structure (and zero it) */ |
153 | host = devm_kzalloc(&ofdev->dev, sizeof(*host), GFP_KERNEL); | 151 | host = devm_kzalloc(&ofdev->dev, sizeof(*host), GFP_KERNEL); |
@@ -160,15 +158,15 @@ static int socrates_nand_probe(struct platform_device *ofdev) | |||
160 | return -EIO; | 158 | return -EIO; |
161 | } | 159 | } |
162 | 160 | ||
163 | mtd = &host->mtd; | ||
164 | nand_chip = &host->nand_chip; | 161 | nand_chip = &host->nand_chip; |
162 | mtd = nand_to_mtd(nand_chip); | ||
165 | host->dev = &ofdev->dev; | 163 | host->dev = &ofdev->dev; |
166 | 164 | ||
167 | nand_chip->priv = host; /* link the private data structures */ | 165 | /* link the private data structures */ |
168 | mtd->priv = nand_chip; | 166 | nand_set_controller_data(nand_chip, host); |
167 | nand_set_flash_node(nand_chip, ofdev->dev.of_node); | ||
169 | mtd->name = "socrates_nand"; | 168 | mtd->name = "socrates_nand"; |
170 | mtd->dev.parent = &ofdev->dev; | 169 | mtd->dev.parent = &ofdev->dev; |
171 | ppdata.of_node = ofdev->dev.of_node; | ||
172 | 170 | ||
173 | /*should never be accessed directly */ | 171 | /*should never be accessed directly */ |
174 | nand_chip->IO_ADDR_R = (void *)0xdeadbeef; | 172 | nand_chip->IO_ADDR_R = (void *)0xdeadbeef; |
@@ -200,7 +198,7 @@ static int socrates_nand_probe(struct platform_device *ofdev) | |||
200 | goto out; | 198 | goto out; |
201 | } | 199 | } |
202 | 200 | ||
203 | res = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); | 201 | res = mtd_device_register(mtd, NULL, 0); |
204 | if (!res) | 202 | if (!res) |
205 | return res; | 203 | return res; |
206 | 204 | ||
@@ -217,7 +215,7 @@ out: | |||
217 | static int socrates_nand_remove(struct platform_device *ofdev) | 215 | static int socrates_nand_remove(struct platform_device *ofdev) |
218 | { | 216 | { |
219 | struct socrates_nand_host *host = dev_get_drvdata(&ofdev->dev); | 217 | struct socrates_nand_host *host = dev_get_drvdata(&ofdev->dev); |
220 | struct mtd_info *mtd = &host->mtd; | 218 | struct mtd_info *mtd = nand_to_mtd(&host->nand_chip); |
221 | 219 | ||
222 | nand_release(mtd); | 220 | nand_release(mtd); |
223 | 221 | ||
diff --git a/drivers/mtd/nand/sunxi_nand.c b/drivers/mtd/nand/sunxi_nand.c index 824711845c44..51e10a35fe08 100644 --- a/drivers/mtd/nand/sunxi_nand.c +++ b/drivers/mtd/nand/sunxi_nand.c | |||
@@ -234,7 +234,6 @@ struct sunxi_nand_hw_ecc { | |||
234 | struct sunxi_nand_chip { | 234 | struct sunxi_nand_chip { |
235 | struct list_head node; | 235 | struct list_head node; |
236 | struct nand_chip nand; | 236 | struct nand_chip nand; |
237 | struct mtd_info mtd; | ||
238 | unsigned long clk_rate; | 237 | unsigned long clk_rate; |
239 | u32 timing_cfg; | 238 | u32 timing_cfg; |
240 | u32 timing_ctl; | 239 | u32 timing_ctl; |
@@ -350,7 +349,7 @@ static int sunxi_nfc_rst(struct sunxi_nfc *nfc) | |||
350 | 349 | ||
351 | static int sunxi_nfc_dev_ready(struct mtd_info *mtd) | 350 | static int sunxi_nfc_dev_ready(struct mtd_info *mtd) |
352 | { | 351 | { |
353 | struct nand_chip *nand = mtd->priv; | 352 | struct nand_chip *nand = mtd_to_nand(mtd); |
354 | struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); | 353 | struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); |
355 | struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); | 354 | struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); |
356 | struct sunxi_nand_rb *rb; | 355 | struct sunxi_nand_rb *rb; |
@@ -388,7 +387,7 @@ static int sunxi_nfc_dev_ready(struct mtd_info *mtd) | |||
388 | 387 | ||
389 | static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip) | 388 | static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip) |
390 | { | 389 | { |
391 | struct nand_chip *nand = mtd->priv; | 390 | struct nand_chip *nand = mtd_to_nand(mtd); |
392 | struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); | 391 | struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); |
393 | struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); | 392 | struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); |
394 | struct sunxi_nand_chip_sel *sel; | 393 | struct sunxi_nand_chip_sel *sel; |
@@ -433,7 +432,7 @@ static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip) | |||
433 | 432 | ||
434 | static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | 433 | static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) |
435 | { | 434 | { |
436 | struct nand_chip *nand = mtd->priv; | 435 | struct nand_chip *nand = mtd_to_nand(mtd); |
437 | struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); | 436 | struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); |
438 | struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); | 437 | struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); |
439 | int ret; | 438 | int ret; |
@@ -466,7 +465,7 @@ static void sunxi_nfc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | |||
466 | static void sunxi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, | 465 | static void sunxi_nfc_write_buf(struct mtd_info *mtd, const uint8_t *buf, |
467 | int len) | 466 | int len) |
468 | { | 467 | { |
469 | struct nand_chip *nand = mtd->priv; | 468 | struct nand_chip *nand = mtd_to_nand(mtd); |
470 | struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); | 469 | struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); |
471 | struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); | 470 | struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); |
472 | int ret; | 471 | int ret; |
@@ -507,7 +506,7 @@ static uint8_t sunxi_nfc_read_byte(struct mtd_info *mtd) | |||
507 | static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat, | 506 | static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat, |
508 | unsigned int ctrl) | 507 | unsigned int ctrl) |
509 | { | 508 | { |
510 | struct nand_chip *nand = mtd->priv; | 509 | struct nand_chip *nand = mtd_to_nand(mtd); |
511 | struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); | 510 | struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); |
512 | struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); | 511 | struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); |
513 | int ret; | 512 | int ret; |
@@ -541,7 +540,7 @@ static void sunxi_nfc_cmd_ctrl(struct mtd_info *mtd, int dat, | |||
541 | 540 | ||
542 | static void sunxi_nfc_hw_ecc_enable(struct mtd_info *mtd) | 541 | static void sunxi_nfc_hw_ecc_enable(struct mtd_info *mtd) |
543 | { | 542 | { |
544 | struct nand_chip *nand = mtd->priv; | 543 | struct nand_chip *nand = mtd_to_nand(mtd); |
545 | struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); | 544 | struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); |
546 | struct sunxi_nand_hw_ecc *data = nand->ecc.priv; | 545 | struct sunxi_nand_hw_ecc *data = nand->ecc.priv; |
547 | u32 ecc_ctl; | 546 | u32 ecc_ctl; |
@@ -556,7 +555,7 @@ static void sunxi_nfc_hw_ecc_enable(struct mtd_info *mtd) | |||
556 | 555 | ||
557 | static void sunxi_nfc_hw_ecc_disable(struct mtd_info *mtd) | 556 | static void sunxi_nfc_hw_ecc_disable(struct mtd_info *mtd) |
558 | { | 557 | { |
559 | struct nand_chip *nand = mtd->priv; | 558 | struct nand_chip *nand = mtd_to_nand(mtd); |
560 | struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); | 559 | struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); |
561 | 560 | ||
562 | writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_ECC_EN, | 561 | writel(readl(nfc->regs + NFC_REG_ECC_CTL) & ~NFC_ECC_EN, |
@@ -577,7 +576,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd, | |||
577 | int *cur_off, | 576 | int *cur_off, |
578 | unsigned int *max_bitflips) | 577 | unsigned int *max_bitflips) |
579 | { | 578 | { |
580 | struct nand_chip *nand = mtd->priv; | 579 | struct nand_chip *nand = mtd_to_nand(mtd); |
581 | struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); | 580 | struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); |
582 | struct nand_ecc_ctrl *ecc = &nand->ecc; | 581 | struct nand_ecc_ctrl *ecc = &nand->ecc; |
583 | u32 status; | 582 | u32 status; |
@@ -638,7 +637,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd, | |||
638 | static void sunxi_nfc_hw_ecc_read_extra_oob(struct mtd_info *mtd, | 637 | static void sunxi_nfc_hw_ecc_read_extra_oob(struct mtd_info *mtd, |
639 | u8 *oob, int *cur_off) | 638 | u8 *oob, int *cur_off) |
640 | { | 639 | { |
641 | struct nand_chip *nand = mtd->priv; | 640 | struct nand_chip *nand = mtd_to_nand(mtd); |
642 | struct nand_ecc_ctrl *ecc = &nand->ecc; | 641 | struct nand_ecc_ctrl *ecc = &nand->ecc; |
643 | int offset = ((ecc->bytes + 4) * ecc->steps); | 642 | int offset = ((ecc->bytes + 4) * ecc->steps); |
644 | int len = mtd->oobsize - offset; | 643 | int len = mtd->oobsize - offset; |
@@ -665,7 +664,7 @@ static int sunxi_nfc_hw_ecc_write_chunk(struct mtd_info *mtd, | |||
665 | const u8 *oob, int oob_off, | 664 | const u8 *oob, int oob_off, |
666 | int *cur_off) | 665 | int *cur_off) |
667 | { | 666 | { |
668 | struct nand_chip *nand = mtd->priv; | 667 | struct nand_chip *nand = mtd_to_nand(mtd); |
669 | struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); | 668 | struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); |
670 | struct nand_ecc_ctrl *ecc = &nand->ecc; | 669 | struct nand_ecc_ctrl *ecc = &nand->ecc; |
671 | int ret; | 670 | int ret; |
@@ -702,7 +701,7 @@ static int sunxi_nfc_hw_ecc_write_chunk(struct mtd_info *mtd, | |||
702 | static void sunxi_nfc_hw_ecc_write_extra_oob(struct mtd_info *mtd, | 701 | static void sunxi_nfc_hw_ecc_write_extra_oob(struct mtd_info *mtd, |
703 | u8 *oob, int *cur_off) | 702 | u8 *oob, int *cur_off) |
704 | { | 703 | { |
705 | struct nand_chip *nand = mtd->priv; | 704 | struct nand_chip *nand = mtd_to_nand(mtd); |
706 | struct nand_ecc_ctrl *ecc = &nand->ecc; | 705 | struct nand_ecc_ctrl *ecc = &nand->ecc; |
707 | int offset = ((ecc->bytes + 4) * ecc->steps); | 706 | int offset = ((ecc->bytes + 4) * ecc->steps); |
708 | int len = mtd->oobsize - offset; | 707 | int len = mtd->oobsize - offset; |
@@ -991,6 +990,7 @@ static int sunxi_nand_chip_set_timings(struct sunxi_nand_chip *chip, | |||
991 | static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip, | 990 | static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip, |
992 | struct device_node *np) | 991 | struct device_node *np) |
993 | { | 992 | { |
993 | struct mtd_info *mtd = nand_to_mtd(&chip->nand); | ||
994 | const struct nand_sdr_timings *timings; | 994 | const struct nand_sdr_timings *timings; |
995 | int ret; | 995 | int ret; |
996 | int mode; | 996 | int mode; |
@@ -1008,12 +1008,11 @@ static int sunxi_nand_chip_init_timings(struct sunxi_nand_chip *chip, | |||
1008 | 1008 | ||
1009 | feature[0] = mode; | 1009 | feature[0] = mode; |
1010 | for (i = 0; i < chip->nsels; i++) { | 1010 | for (i = 0; i < chip->nsels; i++) { |
1011 | chip->nand.select_chip(&chip->mtd, i); | 1011 | chip->nand.select_chip(mtd, i); |
1012 | ret = chip->nand.onfi_set_features(&chip->mtd, | 1012 | ret = chip->nand.onfi_set_features(mtd, &chip->nand, |
1013 | &chip->nand, | ||
1014 | ONFI_FEATURE_ADDR_TIMING_MODE, | 1013 | ONFI_FEATURE_ADDR_TIMING_MODE, |
1015 | feature); | 1014 | feature); |
1016 | chip->nand.select_chip(&chip->mtd, -1); | 1015 | chip->nand.select_chip(mtd, -1); |
1017 | if (ret) | 1016 | if (ret) |
1018 | return ret; | 1017 | return ret; |
1019 | } | 1018 | } |
@@ -1031,7 +1030,7 @@ static int sunxi_nand_hw_common_ecc_ctrl_init(struct mtd_info *mtd, | |||
1031 | struct device_node *np) | 1030 | struct device_node *np) |
1032 | { | 1031 | { |
1033 | static const u8 strengths[] = { 16, 24, 28, 32, 40, 48, 56, 60, 64 }; | 1032 | static const u8 strengths[] = { 16, 24, 28, 32, 40, 48, 56, 60, 64 }; |
1034 | struct nand_chip *nand = mtd->priv; | 1033 | struct nand_chip *nand = mtd_to_nand(mtd); |
1035 | struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); | 1034 | struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); |
1036 | struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); | 1035 | struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); |
1037 | struct sunxi_nand_hw_ecc *data; | 1036 | struct sunxi_nand_hw_ecc *data; |
@@ -1189,7 +1188,7 @@ static void sunxi_nand_ecc_cleanup(struct nand_ecc_ctrl *ecc) | |||
1189 | static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc, | 1188 | static int sunxi_nand_ecc_init(struct mtd_info *mtd, struct nand_ecc_ctrl *ecc, |
1190 | struct device_node *np) | 1189 | struct device_node *np) |
1191 | { | 1190 | { |
1192 | struct nand_chip *nand = mtd->priv; | 1191 | struct nand_chip *nand = mtd_to_nand(mtd); |
1193 | int ret; | 1192 | int ret; |
1194 | 1193 | ||
1195 | if (!ecc->size) { | 1194 | if (!ecc->size) { |
@@ -1232,7 +1231,6 @@ static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc, | |||
1232 | { | 1231 | { |
1233 | const struct nand_sdr_timings *timings; | 1232 | const struct nand_sdr_timings *timings; |
1234 | struct sunxi_nand_chip *chip; | 1233 | struct sunxi_nand_chip *chip; |
1235 | struct mtd_part_parser_data ppdata; | ||
1236 | struct mtd_info *mtd; | 1234 | struct mtd_info *mtd; |
1237 | struct nand_chip *nand; | 1235 | struct nand_chip *nand; |
1238 | int nsels; | 1236 | int nsels; |
@@ -1330,16 +1328,15 @@ static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc, | |||
1330 | * in the DT. | 1328 | * in the DT. |
1331 | */ | 1329 | */ |
1332 | nand->ecc.mode = NAND_ECC_HW; | 1330 | nand->ecc.mode = NAND_ECC_HW; |
1333 | nand->flash_node = np; | 1331 | nand_set_flash_node(nand, np); |
1334 | nand->select_chip = sunxi_nfc_select_chip; | 1332 | nand->select_chip = sunxi_nfc_select_chip; |
1335 | nand->cmd_ctrl = sunxi_nfc_cmd_ctrl; | 1333 | nand->cmd_ctrl = sunxi_nfc_cmd_ctrl; |
1336 | nand->read_buf = sunxi_nfc_read_buf; | 1334 | nand->read_buf = sunxi_nfc_read_buf; |
1337 | nand->write_buf = sunxi_nfc_write_buf; | 1335 | nand->write_buf = sunxi_nfc_write_buf; |
1338 | nand->read_byte = sunxi_nfc_read_byte; | 1336 | nand->read_byte = sunxi_nfc_read_byte; |
1339 | 1337 | ||
1340 | mtd = &chip->mtd; | 1338 | mtd = nand_to_mtd(nand); |
1341 | mtd->dev.parent = dev; | 1339 | mtd->dev.parent = dev; |
1342 | mtd->priv = nand; | ||
1343 | 1340 | ||
1344 | ret = nand_scan_ident(mtd, nsels, NULL); | 1341 | ret = nand_scan_ident(mtd, nsels, NULL); |
1345 | if (ret) | 1342 | if (ret) |
@@ -1366,8 +1363,7 @@ static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc, | |||
1366 | return ret; | 1363 | return ret; |
1367 | } | 1364 | } |
1368 | 1365 | ||
1369 | ppdata.of_node = np; | 1366 | ret = mtd_device_register(mtd, NULL, 0); |
1370 | ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); | ||
1371 | if (ret) { | 1367 | if (ret) { |
1372 | dev_err(dev, "failed to register mtd device: %d\n", ret); | 1368 | dev_err(dev, "failed to register mtd device: %d\n", ret); |
1373 | nand_release(mtd); | 1369 | nand_release(mtd); |
@@ -1393,8 +1389,10 @@ static int sunxi_nand_chips_init(struct device *dev, struct sunxi_nfc *nfc) | |||
1393 | 1389 | ||
1394 | for_each_child_of_node(np, nand_np) { | 1390 | for_each_child_of_node(np, nand_np) { |
1395 | ret = sunxi_nand_chip_init(dev, nfc, nand_np); | 1391 | ret = sunxi_nand_chip_init(dev, nfc, nand_np); |
1396 | if (ret) | 1392 | if (ret) { |
1393 | of_node_put(nand_np); | ||
1397 | return ret; | 1394 | return ret; |
1395 | } | ||
1398 | } | 1396 | } |
1399 | 1397 | ||
1400 | return 0; | 1398 | return 0; |
@@ -1407,7 +1405,7 @@ static void sunxi_nand_chips_cleanup(struct sunxi_nfc *nfc) | |||
1407 | while (!list_empty(&nfc->chips)) { | 1405 | while (!list_empty(&nfc->chips)) { |
1408 | chip = list_first_entry(&nfc->chips, struct sunxi_nand_chip, | 1406 | chip = list_first_entry(&nfc->chips, struct sunxi_nand_chip, |
1409 | node); | 1407 | node); |
1410 | nand_release(&chip->mtd); | 1408 | nand_release(nand_to_mtd(&chip->nand)); |
1411 | sunxi_nand_ecc_cleanup(&chip->nand.ecc); | 1409 | sunxi_nand_ecc_cleanup(&chip->nand.ecc); |
1412 | list_del(&chip->node); | 1410 | list_del(&chip->node); |
1413 | } | 1411 | } |
diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/tmio_nand.c index befddf0776e4..08b30549ec0a 100644 --- a/drivers/mtd/nand/tmio_nand.c +++ b/drivers/mtd/nand/tmio_nand.c | |||
@@ -103,7 +103,6 @@ | |||
103 | /*--------------------------------------------------------------------------*/ | 103 | /*--------------------------------------------------------------------------*/ |
104 | 104 | ||
105 | struct tmio_nand { | 105 | struct tmio_nand { |
106 | struct mtd_info mtd; | ||
107 | struct nand_chip chip; | 106 | struct nand_chip chip; |
108 | 107 | ||
109 | struct platform_device *dev; | 108 | struct platform_device *dev; |
@@ -119,7 +118,10 @@ struct tmio_nand { | |||
119 | unsigned read_good:1; | 118 | unsigned read_good:1; |
120 | }; | 119 | }; |
121 | 120 | ||
122 | #define mtd_to_tmio(m) container_of(m, struct tmio_nand, mtd) | 121 | static inline struct tmio_nand *mtd_to_tmio(struct mtd_info *mtd) |
122 | { | ||
123 | return container_of(mtd_to_nand(mtd), struct tmio_nand, chip); | ||
124 | } | ||
123 | 125 | ||
124 | 126 | ||
125 | /*--------------------------------------------------------------------------*/ | 127 | /*--------------------------------------------------------------------------*/ |
@@ -128,7 +130,7 @@ static void tmio_nand_hwcontrol(struct mtd_info *mtd, int cmd, | |||
128 | unsigned int ctrl) | 130 | unsigned int ctrl) |
129 | { | 131 | { |
130 | struct tmio_nand *tmio = mtd_to_tmio(mtd); | 132 | struct tmio_nand *tmio = mtd_to_tmio(mtd); |
131 | struct nand_chip *chip = mtd->priv; | 133 | struct nand_chip *chip = mtd_to_nand(mtd); |
132 | 134 | ||
133 | if (ctrl & NAND_CTRL_CHANGE) { | 135 | if (ctrl & NAND_CTRL_CHANGE) { |
134 | u8 mode; | 136 | u8 mode; |
@@ -378,9 +380,8 @@ static int tmio_probe(struct platform_device *dev) | |||
378 | tmio->dev = dev; | 380 | tmio->dev = dev; |
379 | 381 | ||
380 | platform_set_drvdata(dev, tmio); | 382 | platform_set_drvdata(dev, tmio); |
381 | mtd = &tmio->mtd; | ||
382 | nand_chip = &tmio->chip; | 383 | nand_chip = &tmio->chip; |
383 | mtd->priv = nand_chip; | 384 | mtd = nand_to_mtd(nand_chip); |
384 | mtd->name = "tmio-nand"; | 385 | mtd->name = "tmio-nand"; |
385 | mtd->dev.parent = &dev->dev; | 386 | mtd->dev.parent = &dev->dev; |
386 | 387 | ||
@@ -456,7 +457,7 @@ static int tmio_remove(struct platform_device *dev) | |||
456 | { | 457 | { |
457 | struct tmio_nand *tmio = platform_get_drvdata(dev); | 458 | struct tmio_nand *tmio = platform_get_drvdata(dev); |
458 | 459 | ||
459 | nand_release(&tmio->mtd); | 460 | nand_release(nand_to_mtd(&tmio->chip)); |
460 | tmio_hw_stop(dev, tmio); | 461 | tmio_hw_stop(dev, tmio); |
461 | return 0; | 462 | return 0; |
462 | } | 463 | } |
diff --git a/drivers/mtd/nand/txx9ndfmc.c b/drivers/mtd/nand/txx9ndfmc.c index 8572519b8441..04d63f56baa4 100644 --- a/drivers/mtd/nand/txx9ndfmc.c +++ b/drivers/mtd/nand/txx9ndfmc.c | |||
@@ -63,7 +63,6 @@ | |||
63 | struct txx9ndfmc_priv { | 63 | struct txx9ndfmc_priv { |
64 | struct platform_device *dev; | 64 | struct platform_device *dev; |
65 | struct nand_chip chip; | 65 | struct nand_chip chip; |
66 | struct mtd_info mtd; | ||
67 | int cs; | 66 | int cs; |
68 | const char *mtdname; | 67 | const char *mtdname; |
69 | }; | 68 | }; |
@@ -79,8 +78,8 @@ struct txx9ndfmc_drvdata { | |||
79 | 78 | ||
80 | static struct platform_device *mtd_to_platdev(struct mtd_info *mtd) | 79 | static struct platform_device *mtd_to_platdev(struct mtd_info *mtd) |
81 | { | 80 | { |
82 | struct nand_chip *chip = mtd->priv; | 81 | struct nand_chip *chip = mtd_to_nand(mtd); |
83 | struct txx9ndfmc_priv *txx9_priv = chip->priv; | 82 | struct txx9ndfmc_priv *txx9_priv = nand_get_controller_data(chip); |
84 | return txx9_priv->dev; | 83 | return txx9_priv->dev; |
85 | } | 84 | } |
86 | 85 | ||
@@ -135,8 +134,8 @@ static void txx9ndfmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | |||
135 | static void txx9ndfmc_cmd_ctrl(struct mtd_info *mtd, int cmd, | 134 | static void txx9ndfmc_cmd_ctrl(struct mtd_info *mtd, int cmd, |
136 | unsigned int ctrl) | 135 | unsigned int ctrl) |
137 | { | 136 | { |
138 | struct nand_chip *chip = mtd->priv; | 137 | struct nand_chip *chip = mtd_to_nand(mtd); |
139 | struct txx9ndfmc_priv *txx9_priv = chip->priv; | 138 | struct txx9ndfmc_priv *txx9_priv = nand_get_controller_data(chip); |
140 | struct platform_device *dev = txx9_priv->dev; | 139 | struct platform_device *dev = txx9_priv->dev; |
141 | struct txx9ndfmc_platform_data *plat = dev_get_platdata(&dev->dev); | 140 | struct txx9ndfmc_platform_data *plat = dev_get_platdata(&dev->dev); |
142 | 141 | ||
@@ -175,7 +174,7 @@ static int txx9ndfmc_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat, | |||
175 | uint8_t *ecc_code) | 174 | uint8_t *ecc_code) |
176 | { | 175 | { |
177 | struct platform_device *dev = mtd_to_platdev(mtd); | 176 | struct platform_device *dev = mtd_to_platdev(mtd); |
178 | struct nand_chip *chip = mtd->priv; | 177 | struct nand_chip *chip = mtd_to_nand(mtd); |
179 | int eccbytes; | 178 | int eccbytes; |
180 | u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR); | 179 | u32 mcr = txx9ndfmc_read(dev, TXX9_NDFMCR); |
181 | 180 | ||
@@ -195,7 +194,7 @@ static int txx9ndfmc_calculate_ecc(struct mtd_info *mtd, const uint8_t *dat, | |||
195 | static int txx9ndfmc_correct_data(struct mtd_info *mtd, unsigned char *buf, | 194 | static int txx9ndfmc_correct_data(struct mtd_info *mtd, unsigned char *buf, |
196 | unsigned char *read_ecc, unsigned char *calc_ecc) | 195 | unsigned char *read_ecc, unsigned char *calc_ecc) |
197 | { | 196 | { |
198 | struct nand_chip *chip = mtd->priv; | 197 | struct nand_chip *chip = mtd_to_nand(mtd); |
199 | int eccsize; | 198 | int eccsize; |
200 | int corrected = 0; | 199 | int corrected = 0; |
201 | int stat; | 200 | int stat; |
@@ -257,7 +256,7 @@ static void txx9ndfmc_initialize(struct platform_device *dev) | |||
257 | 256 | ||
258 | static int txx9ndfmc_nand_scan(struct mtd_info *mtd) | 257 | static int txx9ndfmc_nand_scan(struct mtd_info *mtd) |
259 | { | 258 | { |
260 | struct nand_chip *chip = mtd->priv; | 259 | struct nand_chip *chip = mtd_to_nand(mtd); |
261 | int ret; | 260 | int ret; |
262 | 261 | ||
263 | ret = nand_scan_ident(mtd, 1, NULL); | 262 | ret = nand_scan_ident(mtd, 1, NULL); |
@@ -322,11 +321,9 @@ static int __init txx9ndfmc_probe(struct platform_device *dev) | |||
322 | if (!txx9_priv) | 321 | if (!txx9_priv) |
323 | continue; | 322 | continue; |
324 | chip = &txx9_priv->chip; | 323 | chip = &txx9_priv->chip; |
325 | mtd = &txx9_priv->mtd; | 324 | mtd = nand_to_mtd(chip); |
326 | mtd->dev.parent = &dev->dev; | 325 | mtd->dev.parent = &dev->dev; |
327 | 326 | ||
328 | mtd->priv = chip; | ||
329 | |||
330 | chip->read_byte = txx9ndfmc_read_byte; | 327 | chip->read_byte = txx9ndfmc_read_byte; |
331 | chip->read_buf = txx9ndfmc_read_buf; | 328 | chip->read_buf = txx9ndfmc_read_buf; |
332 | chip->write_buf = txx9ndfmc_write_buf; | 329 | chip->write_buf = txx9ndfmc_write_buf; |
@@ -343,7 +340,7 @@ static int __init txx9ndfmc_probe(struct platform_device *dev) | |||
343 | chip->chip_delay = 100; | 340 | chip->chip_delay = 100; |
344 | chip->controller = &drvdata->hw_control; | 341 | chip->controller = &drvdata->hw_control; |
345 | 342 | ||
346 | chip->priv = txx9_priv; | 343 | nand_set_controller_data(chip, txx9_priv); |
347 | txx9_priv->dev = dev; | 344 | txx9_priv->dev = dev; |
348 | 345 | ||
349 | if (plat->ch_mask != 1) { | 346 | if (plat->ch_mask != 1) { |
@@ -391,8 +388,8 @@ static int __exit txx9ndfmc_remove(struct platform_device *dev) | |||
391 | 388 | ||
392 | if (!mtd) | 389 | if (!mtd) |
393 | continue; | 390 | continue; |
394 | chip = mtd->priv; | 391 | chip = mtd_to_nand(mtd); |
395 | txx9_priv = chip->priv; | 392 | txx9_priv = nand_get_controller_data(chip); |
396 | 393 | ||
397 | nand_release(mtd); | 394 | nand_release(mtd); |
398 | kfree(txx9_priv->mtdname); | 395 | kfree(txx9_priv->mtdname); |
diff --git a/drivers/mtd/nand/vf610_nfc.c b/drivers/mtd/nand/vf610_nfc.c index 8805d6325579..034420f313d5 100644 --- a/drivers/mtd/nand/vf610_nfc.c +++ b/drivers/mtd/nand/vf610_nfc.c | |||
@@ -156,7 +156,6 @@ enum vf610_nfc_variant { | |||
156 | }; | 156 | }; |
157 | 157 | ||
158 | struct vf610_nfc { | 158 | struct vf610_nfc { |
159 | struct mtd_info mtd; | ||
160 | struct nand_chip chip; | 159 | struct nand_chip chip; |
161 | struct device *dev; | 160 | struct device *dev; |
162 | void __iomem *regs; | 161 | void __iomem *regs; |
@@ -171,7 +170,10 @@ struct vf610_nfc { | |||
171 | u32 ecc_mode; | 170 | u32 ecc_mode; |
172 | }; | 171 | }; |
173 | 172 | ||
174 | #define mtd_to_nfc(_mtd) container_of(_mtd, struct vf610_nfc, mtd) | 173 | static inline struct vf610_nfc *mtd_to_nfc(struct mtd_info *mtd) |
174 | { | ||
175 | return container_of(mtd_to_nand(mtd), struct vf610_nfc, chip); | ||
176 | } | ||
175 | 177 | ||
176 | static struct nand_ecclayout vf610_nfc_ecc45 = { | 178 | static struct nand_ecclayout vf610_nfc_ecc45 = { |
177 | .eccbytes = 45, | 179 | .eccbytes = 45, |
@@ -674,10 +676,9 @@ static int vf610_nfc_probe(struct platform_device *pdev) | |||
674 | return -ENOMEM; | 676 | return -ENOMEM; |
675 | 677 | ||
676 | nfc->dev = &pdev->dev; | 678 | nfc->dev = &pdev->dev; |
677 | mtd = &nfc->mtd; | ||
678 | chip = &nfc->chip; | 679 | chip = &nfc->chip; |
680 | mtd = nand_to_mtd(chip); | ||
679 | 681 | ||
680 | mtd->priv = chip; | ||
681 | mtd->owner = THIS_MODULE; | 682 | mtd->owner = THIS_MODULE; |
682 | mtd->dev.parent = nfc->dev; | 683 | mtd->dev.parent = nfc->dev; |
683 | mtd->name = DRV_NAME; | 684 | mtd->name = DRV_NAME; |
@@ -707,18 +708,18 @@ static int vf610_nfc_probe(struct platform_device *pdev) | |||
707 | for_each_available_child_of_node(nfc->dev->of_node, child) { | 708 | for_each_available_child_of_node(nfc->dev->of_node, child) { |
708 | if (of_device_is_compatible(child, "fsl,vf610-nfc-nandcs")) { | 709 | if (of_device_is_compatible(child, "fsl,vf610-nfc-nandcs")) { |
709 | 710 | ||
710 | if (chip->flash_node) { | 711 | if (nand_get_flash_node(chip)) { |
711 | dev_err(nfc->dev, | 712 | dev_err(nfc->dev, |
712 | "Only one NAND chip supported!\n"); | 713 | "Only one NAND chip supported!\n"); |
713 | err = -EINVAL; | 714 | err = -EINVAL; |
714 | goto error; | 715 | goto error; |
715 | } | 716 | } |
716 | 717 | ||
717 | chip->flash_node = child; | 718 | nand_set_flash_node(chip, child); |
718 | } | 719 | } |
719 | } | 720 | } |
720 | 721 | ||
721 | if (!chip->flash_node) { | 722 | if (!nand_get_flash_node(chip)) { |
722 | dev_err(nfc->dev, "NAND chip sub-node missing!\n"); | 723 | dev_err(nfc->dev, "NAND chip sub-node missing!\n"); |
723 | err = -ENODEV; | 724 | err = -ENODEV; |
724 | goto err_clk; | 725 | goto err_clk; |
@@ -811,14 +812,10 @@ static int vf610_nfc_probe(struct platform_device *pdev) | |||
811 | platform_set_drvdata(pdev, mtd); | 812 | platform_set_drvdata(pdev, mtd); |
812 | 813 | ||
813 | /* Register device in MTD */ | 814 | /* Register device in MTD */ |
814 | return mtd_device_parse_register(mtd, NULL, | 815 | return mtd_device_register(mtd, NULL, 0); |
815 | &(struct mtd_part_parser_data){ | ||
816 | .of_node = chip->flash_node, | ||
817 | }, | ||
818 | NULL, 0); | ||
819 | 816 | ||
820 | error: | 817 | error: |
821 | of_node_put(chip->flash_node); | 818 | of_node_put(nand_get_flash_node(chip)); |
822 | err_clk: | 819 | err_clk: |
823 | clk_disable_unprepare(nfc->clk); | 820 | clk_disable_unprepare(nfc->clk); |
824 | return err; | 821 | return err; |
diff --git a/drivers/mtd/nand/xway_nand.c b/drivers/mtd/nand/xway_nand.c index 3b28db458ea0..0cf0ac07a8c2 100644 --- a/drivers/mtd/nand/xway_nand.c +++ b/drivers/mtd/nand/xway_nand.c | |||
@@ -89,7 +89,7 @@ static void xway_select_chip(struct mtd_info *mtd, int chip) | |||
89 | 89 | ||
90 | static void xway_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | 90 | static void xway_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) |
91 | { | 91 | { |
92 | struct nand_chip *this = mtd->priv; | 92 | struct nand_chip *this = mtd_to_nand(mtd); |
93 | unsigned long nandaddr = (unsigned long) this->IO_ADDR_W; | 93 | unsigned long nandaddr = (unsigned long) this->IO_ADDR_W; |
94 | unsigned long flags; | 94 | unsigned long flags; |
95 | 95 | ||
@@ -118,7 +118,7 @@ static int xway_dev_ready(struct mtd_info *mtd) | |||
118 | 118 | ||
119 | static unsigned char xway_read_byte(struct mtd_info *mtd) | 119 | static unsigned char xway_read_byte(struct mtd_info *mtd) |
120 | { | 120 | { |
121 | struct nand_chip *this = mtd->priv; | 121 | struct nand_chip *this = mtd_to_nand(mtd); |
122 | unsigned long nandaddr = (unsigned long) this->IO_ADDR_R; | 122 | unsigned long nandaddr = (unsigned long) this->IO_ADDR_R; |
123 | unsigned long flags; | 123 | unsigned long flags; |
124 | int ret; | 124 | int ret; |
diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c index 9ed6038e47d2..ede407d6e106 100644 --- a/drivers/mtd/ofpart.c +++ b/drivers/mtd/ofpart.c | |||
@@ -26,9 +26,10 @@ static bool node_has_compatible(struct device_node *pp) | |||
26 | } | 26 | } |
27 | 27 | ||
28 | static int parse_ofpart_partitions(struct mtd_info *master, | 28 | static int parse_ofpart_partitions(struct mtd_info *master, |
29 | struct mtd_partition **pparts, | 29 | const struct mtd_partition **pparts, |
30 | struct mtd_part_parser_data *data) | 30 | struct mtd_part_parser_data *data) |
31 | { | 31 | { |
32 | struct mtd_partition *parts; | ||
32 | struct device_node *mtd_node; | 33 | struct device_node *mtd_node; |
33 | struct device_node *ofpart_node; | 34 | struct device_node *ofpart_node; |
34 | const char *partname; | 35 | const char *partname; |
@@ -37,10 +38,8 @@ static int parse_ofpart_partitions(struct mtd_info *master, | |||
37 | bool dedicated = true; | 38 | bool dedicated = true; |
38 | 39 | ||
39 | 40 | ||
40 | if (!data) | 41 | /* Pull of_node from the master device node */ |
41 | return 0; | 42 | mtd_node = mtd_get_of_node(master); |
42 | |||
43 | mtd_node = data->of_node; | ||
44 | if (!mtd_node) | 43 | if (!mtd_node) |
45 | return 0; | 44 | return 0; |
46 | 45 | ||
@@ -72,8 +71,8 @@ static int parse_ofpart_partitions(struct mtd_info *master, | |||
72 | if (nr_parts == 0) | 71 | if (nr_parts == 0) |
73 | return 0; | 72 | return 0; |
74 | 73 | ||
75 | *pparts = kzalloc(nr_parts * sizeof(**pparts), GFP_KERNEL); | 74 | parts = kzalloc(nr_parts * sizeof(*parts), GFP_KERNEL); |
76 | if (!*pparts) | 75 | if (!parts) |
77 | return -ENOMEM; | 76 | return -ENOMEM; |
78 | 77 | ||
79 | i = 0; | 78 | i = 0; |
@@ -107,19 +106,19 @@ static int parse_ofpart_partitions(struct mtd_info *master, | |||
107 | goto ofpart_fail; | 106 | goto ofpart_fail; |
108 | } | 107 | } |
109 | 108 | ||
110 | (*pparts)[i].offset = of_read_number(reg, a_cells); | 109 | parts[i].offset = of_read_number(reg, a_cells); |
111 | (*pparts)[i].size = of_read_number(reg + a_cells, s_cells); | 110 | parts[i].size = of_read_number(reg + a_cells, s_cells); |
112 | 111 | ||
113 | partname = of_get_property(pp, "label", &len); | 112 | partname = of_get_property(pp, "label", &len); |
114 | if (!partname) | 113 | if (!partname) |
115 | partname = of_get_property(pp, "name", &len); | 114 | partname = of_get_property(pp, "name", &len); |
116 | (*pparts)[i].name = partname; | 115 | parts[i].name = partname; |
117 | 116 | ||
118 | if (of_get_property(pp, "read-only", &len)) | 117 | if (of_get_property(pp, "read-only", &len)) |
119 | (*pparts)[i].mask_flags |= MTD_WRITEABLE; | 118 | parts[i].mask_flags |= MTD_WRITEABLE; |
120 | 119 | ||
121 | if (of_get_property(pp, "lock", &len)) | 120 | if (of_get_property(pp, "lock", &len)) |
122 | (*pparts)[i].mask_flags |= MTD_POWERUP_LOCK; | 121 | parts[i].mask_flags |= MTD_POWERUP_LOCK; |
123 | 122 | ||
124 | i++; | 123 | i++; |
125 | } | 124 | } |
@@ -127,6 +126,7 @@ static int parse_ofpart_partitions(struct mtd_info *master, | |||
127 | if (!nr_parts) | 126 | if (!nr_parts) |
128 | goto ofpart_none; | 127 | goto ofpart_none; |
129 | 128 | ||
129 | *pparts = parts; | ||
130 | return nr_parts; | 130 | return nr_parts; |
131 | 131 | ||
132 | ofpart_fail: | 132 | ofpart_fail: |
@@ -135,21 +135,20 @@ ofpart_fail: | |||
135 | ret = -EINVAL; | 135 | ret = -EINVAL; |
136 | ofpart_none: | 136 | ofpart_none: |
137 | of_node_put(pp); | 137 | of_node_put(pp); |
138 | kfree(*pparts); | 138 | kfree(parts); |
139 | *pparts = NULL; | ||
140 | return ret; | 139 | return ret; |
141 | } | 140 | } |
142 | 141 | ||
143 | static struct mtd_part_parser ofpart_parser = { | 142 | static struct mtd_part_parser ofpart_parser = { |
144 | .owner = THIS_MODULE, | ||
145 | .parse_fn = parse_ofpart_partitions, | 143 | .parse_fn = parse_ofpart_partitions, |
146 | .name = "ofpart", | 144 | .name = "ofpart", |
147 | }; | 145 | }; |
148 | 146 | ||
149 | static int parse_ofoldpart_partitions(struct mtd_info *master, | 147 | static int parse_ofoldpart_partitions(struct mtd_info *master, |
150 | struct mtd_partition **pparts, | 148 | const struct mtd_partition **pparts, |
151 | struct mtd_part_parser_data *data) | 149 | struct mtd_part_parser_data *data) |
152 | { | 150 | { |
151 | struct mtd_partition *parts; | ||
153 | struct device_node *dp; | 152 | struct device_node *dp; |
154 | int i, plen, nr_parts; | 153 | int i, plen, nr_parts; |
155 | const struct { | 154 | const struct { |
@@ -157,10 +156,8 @@ static int parse_ofoldpart_partitions(struct mtd_info *master, | |||
157 | } *part; | 156 | } *part; |
158 | const char *names; | 157 | const char *names; |
159 | 158 | ||
160 | if (!data) | 159 | /* Pull of_node from the master device node */ |
161 | return 0; | 160 | dp = mtd_get_of_node(master); |
162 | |||
163 | dp = data->of_node; | ||
164 | if (!dp) | 161 | if (!dp) |
165 | return 0; | 162 | return 0; |
166 | 163 | ||
@@ -173,37 +170,37 @@ static int parse_ofoldpart_partitions(struct mtd_info *master, | |||
173 | 170 | ||
174 | nr_parts = plen / sizeof(part[0]); | 171 | nr_parts = plen / sizeof(part[0]); |
175 | 172 | ||
176 | *pparts = kzalloc(nr_parts * sizeof(*(*pparts)), GFP_KERNEL); | 173 | parts = kzalloc(nr_parts * sizeof(*parts), GFP_KERNEL); |
177 | if (!*pparts) | 174 | if (!parts) |
178 | return -ENOMEM; | 175 | return -ENOMEM; |
179 | 176 | ||
180 | names = of_get_property(dp, "partition-names", &plen); | 177 | names = of_get_property(dp, "partition-names", &plen); |
181 | 178 | ||
182 | for (i = 0; i < nr_parts; i++) { | 179 | for (i = 0; i < nr_parts; i++) { |
183 | (*pparts)[i].offset = be32_to_cpu(part->offset); | 180 | parts[i].offset = be32_to_cpu(part->offset); |
184 | (*pparts)[i].size = be32_to_cpu(part->len) & ~1; | 181 | parts[i].size = be32_to_cpu(part->len) & ~1; |
185 | /* bit 0 set signifies read only partition */ | 182 | /* bit 0 set signifies read only partition */ |
186 | if (be32_to_cpu(part->len) & 1) | 183 | if (be32_to_cpu(part->len) & 1) |
187 | (*pparts)[i].mask_flags = MTD_WRITEABLE; | 184 | parts[i].mask_flags = MTD_WRITEABLE; |
188 | 185 | ||
189 | if (names && (plen > 0)) { | 186 | if (names && (plen > 0)) { |
190 | int len = strlen(names) + 1; | 187 | int len = strlen(names) + 1; |
191 | 188 | ||
192 | (*pparts)[i].name = names; | 189 | parts[i].name = names; |
193 | plen -= len; | 190 | plen -= len; |
194 | names += len; | 191 | names += len; |
195 | } else { | 192 | } else { |
196 | (*pparts)[i].name = "unnamed"; | 193 | parts[i].name = "unnamed"; |
197 | } | 194 | } |
198 | 195 | ||
199 | part++; | 196 | part++; |
200 | } | 197 | } |
201 | 198 | ||
199 | *pparts = parts; | ||
202 | return nr_parts; | 200 | return nr_parts; |
203 | } | 201 | } |
204 | 202 | ||
205 | static struct mtd_part_parser ofoldpart_parser = { | 203 | static struct mtd_part_parser ofoldpart_parser = { |
206 | .owner = THIS_MODULE, | ||
207 | .parse_fn = parse_ofoldpart_partitions, | 204 | .parse_fn = parse_ofoldpart_partitions, |
208 | .name = "ofoldpart", | 205 | .name = "ofoldpart", |
209 | }; | 206 | }; |
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c index 3e0285696227..0aacf125938b 100644 --- a/drivers/mtd/onenand/omap2.c +++ b/drivers/mtd/onenand/omap2.c | |||
@@ -614,7 +614,6 @@ static int omap2_onenand_probe(struct platform_device *pdev) | |||
614 | struct onenand_chip *this; | 614 | struct onenand_chip *this; |
615 | int r; | 615 | int r; |
616 | struct resource *res; | 616 | struct resource *res; |
617 | struct mtd_part_parser_data ppdata = {}; | ||
618 | 617 | ||
619 | pdata = dev_get_platdata(&pdev->dev); | 618 | pdata = dev_get_platdata(&pdev->dev); |
620 | if (pdata == NULL) { | 619 | if (pdata == NULL) { |
@@ -713,6 +712,7 @@ static int omap2_onenand_probe(struct platform_device *pdev) | |||
713 | c->mtd.priv = &c->onenand; | 712 | c->mtd.priv = &c->onenand; |
714 | 713 | ||
715 | c->mtd.dev.parent = &pdev->dev; | 714 | c->mtd.dev.parent = &pdev->dev; |
715 | mtd_set_of_node(&c->mtd, pdata->of_node); | ||
716 | 716 | ||
717 | this = &c->onenand; | 717 | this = &c->onenand; |
718 | if (c->dma_channel >= 0) { | 718 | if (c->dma_channel >= 0) { |
@@ -743,10 +743,8 @@ static int omap2_onenand_probe(struct platform_device *pdev) | |||
743 | if ((r = onenand_scan(&c->mtd, 1)) < 0) | 743 | if ((r = onenand_scan(&c->mtd, 1)) < 0) |
744 | goto err_release_regulator; | 744 | goto err_release_regulator; |
745 | 745 | ||
746 | ppdata.of_node = pdata->of_node; | 746 | r = mtd_device_register(&c->mtd, pdata ? pdata->parts : NULL, |
747 | r = mtd_device_parse_register(&c->mtd, NULL, &ppdata, | 747 | pdata ? pdata->nr_parts : 0); |
748 | pdata ? pdata->parts : NULL, | ||
749 | pdata ? pdata->nr_parts : 0); | ||
750 | if (r) | 748 | if (r) |
751 | goto err_release_onenand; | 749 | goto err_release_onenand; |
752 | 750 | ||
diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c index 5da911ebdf49..7623ac5fc586 100644 --- a/drivers/mtd/redboot.c +++ b/drivers/mtd/redboot.c | |||
@@ -57,7 +57,7 @@ static inline int redboot_checksum(struct fis_image_desc *img) | |||
57 | } | 57 | } |
58 | 58 | ||
59 | static int parse_redboot_partitions(struct mtd_info *master, | 59 | static int parse_redboot_partitions(struct mtd_info *master, |
60 | struct mtd_partition **pparts, | 60 | const struct mtd_partition **pparts, |
61 | struct mtd_part_parser_data *data) | 61 | struct mtd_part_parser_data *data) |
62 | { | 62 | { |
63 | int nrparts = 0; | 63 | int nrparts = 0; |
@@ -290,28 +290,13 @@ static int parse_redboot_partitions(struct mtd_info *master, | |||
290 | } | 290 | } |
291 | 291 | ||
292 | static struct mtd_part_parser redboot_parser = { | 292 | static struct mtd_part_parser redboot_parser = { |
293 | .owner = THIS_MODULE, | ||
294 | .parse_fn = parse_redboot_partitions, | 293 | .parse_fn = parse_redboot_partitions, |
295 | .name = "RedBoot", | 294 | .name = "RedBoot", |
296 | }; | 295 | }; |
296 | module_mtd_part_parser(redboot_parser); | ||
297 | 297 | ||
298 | /* mtd parsers will request the module by parser name */ | 298 | /* mtd parsers will request the module by parser name */ |
299 | MODULE_ALIAS("RedBoot"); | 299 | MODULE_ALIAS("RedBoot"); |
300 | |||
301 | static int __init redboot_parser_init(void) | ||
302 | { | ||
303 | register_mtd_parser(&redboot_parser); | ||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | static void __exit redboot_parser_exit(void) | ||
308 | { | ||
309 | deregister_mtd_parser(&redboot_parser); | ||
310 | } | ||
311 | |||
312 | module_init(redboot_parser_init); | ||
313 | module_exit(redboot_parser_exit); | ||
314 | |||
315 | MODULE_LICENSE("GPL"); | 300 | MODULE_LICENSE("GPL"); |
316 | MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); | 301 | MODULE_AUTHOR("David Woodhouse <dwmw2@infradead.org>"); |
317 | MODULE_DESCRIPTION("Parsing code for RedBoot Flash Image System (FIS) tables"); | 302 | MODULE_DESCRIPTION("Parsing code for RedBoot Flash Image System (FIS) tables"); |
diff --git a/drivers/mtd/sm_ftl.c b/drivers/mtd/sm_ftl.c index c23184a47fc4..b096f8bb05ba 100644 --- a/drivers/mtd/sm_ftl.c +++ b/drivers/mtd/sm_ftl.c | |||
@@ -206,9 +206,10 @@ static loff_t sm_mkoffset(struct sm_ftl *ftl, int zone, int block, int boffset) | |||
206 | } | 206 | } |
207 | 207 | ||
208 | /* Breaks offset into parts */ | 208 | /* Breaks offset into parts */ |
209 | static void sm_break_offset(struct sm_ftl *ftl, loff_t offset, | 209 | static void sm_break_offset(struct sm_ftl *ftl, loff_t loffset, |
210 | int *zone, int *block, int *boffset) | 210 | int *zone, int *block, int *boffset) |
211 | { | 211 | { |
212 | u64 offset = loffset; | ||
212 | *boffset = do_div(offset, ftl->block_size); | 213 | *boffset = do_div(offset, ftl->block_size); |
213 | *block = do_div(offset, ftl->max_lba); | 214 | *block = do_div(offset, ftl->max_lba); |
214 | *zone = offset >= ftl->zone_count ? -1 : offset; | 215 | *zone = offset >= ftl->zone_count ? -1 : offset; |
diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig index 2fe2a7e90fa9..0dc927540b3d 100644 --- a/drivers/mtd/spi-nor/Kconfig +++ b/drivers/mtd/spi-nor/Kconfig | |||
@@ -7,6 +7,13 @@ menuconfig MTD_SPI_NOR | |||
7 | 7 | ||
8 | if MTD_SPI_NOR | 8 | if MTD_SPI_NOR |
9 | 9 | ||
10 | config MTD_MT81xx_NOR | ||
11 | tristate "Mediatek MT81xx SPI NOR flash controller" | ||
12 | help | ||
13 | This enables access to SPI NOR flash, using MT81xx SPI NOR flash | ||
14 | controller. This controller does not support generic SPI BUS, it only | ||
15 | supports SPI NOR Flash. | ||
16 | |||
10 | config MTD_SPI_NOR_USE_4K_SECTORS | 17 | config MTD_SPI_NOR_USE_4K_SECTORS |
11 | bool "Use small 4096 B erase sectors" | 18 | bool "Use small 4096 B erase sectors" |
12 | default y | 19 | default y |
diff --git a/drivers/mtd/spi-nor/Makefile b/drivers/mtd/spi-nor/Makefile index e53333ef8582..0bf3a7f81675 100644 --- a/drivers/mtd/spi-nor/Makefile +++ b/drivers/mtd/spi-nor/Makefile | |||
@@ -1,3 +1,4 @@ | |||
1 | obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o | 1 | obj-$(CONFIG_MTD_SPI_NOR) += spi-nor.o |
2 | obj-$(CONFIG_SPI_FSL_QUADSPI) += fsl-quadspi.o | 2 | obj-$(CONFIG_SPI_FSL_QUADSPI) += fsl-quadspi.o |
3 | obj-$(CONFIG_MTD_MT81xx_NOR) += mtk-quadspi.o | ||
3 | obj-$(CONFIG_SPI_NXP_SPIFI) += nxp-spifi.o | 4 | obj-$(CONFIG_SPI_NXP_SPIFI) += nxp-spifi.o |
diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c index 7b10ed413983..54640f1eb3a1 100644 --- a/drivers/mtd/spi-nor/fsl-quadspi.c +++ b/drivers/mtd/spi-nor/fsl-quadspi.c | |||
@@ -269,7 +269,7 @@ struct fsl_qspi { | |||
269 | struct clk *clk, *clk_en; | 269 | struct clk *clk, *clk_en; |
270 | struct device *dev; | 270 | struct device *dev; |
271 | struct completion c; | 271 | struct completion c; |
272 | struct fsl_qspi_devtype_data *devtype_data; | 272 | const struct fsl_qspi_devtype_data *devtype_data; |
273 | u32 nor_size; | 273 | u32 nor_size; |
274 | u32 nor_num; | 274 | u32 nor_num; |
275 | u32 clk_rate; | 275 | u32 clk_rate; |
@@ -927,15 +927,12 @@ static void fsl_qspi_unprep(struct spi_nor *nor, enum spi_nor_ops ops) | |||
927 | static int fsl_qspi_probe(struct platform_device *pdev) | 927 | static int fsl_qspi_probe(struct platform_device *pdev) |
928 | { | 928 | { |
929 | struct device_node *np = pdev->dev.of_node; | 929 | struct device_node *np = pdev->dev.of_node; |
930 | struct mtd_part_parser_data ppdata; | ||
931 | struct device *dev = &pdev->dev; | 930 | struct device *dev = &pdev->dev; |
932 | struct fsl_qspi *q; | 931 | struct fsl_qspi *q; |
933 | struct resource *res; | 932 | struct resource *res; |
934 | struct spi_nor *nor; | 933 | struct spi_nor *nor; |
935 | struct mtd_info *mtd; | 934 | struct mtd_info *mtd; |
936 | int ret, i = 0; | 935 | int ret, i = 0; |
937 | const struct of_device_id *of_id = | ||
938 | of_match_device(fsl_qspi_dt_ids, &pdev->dev); | ||
939 | 936 | ||
940 | q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL); | 937 | q = devm_kzalloc(dev, sizeof(*q), GFP_KERNEL); |
941 | if (!q) | 938 | if (!q) |
@@ -946,7 +943,9 @@ static int fsl_qspi_probe(struct platform_device *pdev) | |||
946 | return -ENODEV; | 943 | return -ENODEV; |
947 | 944 | ||
948 | q->dev = dev; | 945 | q->dev = dev; |
949 | q->devtype_data = (struct fsl_qspi_devtype_data *)of_id->data; | 946 | q->devtype_data = of_device_get_match_data(dev); |
947 | if (!q->devtype_data) | ||
948 | return -ENODEV; | ||
950 | platform_set_drvdata(pdev, q); | 949 | platform_set_drvdata(pdev, q); |
951 | 950 | ||
952 | /* find the resources */ | 951 | /* find the resources */ |
@@ -1013,7 +1012,7 @@ static int fsl_qspi_probe(struct platform_device *pdev) | |||
1013 | mtd = &nor->mtd; | 1012 | mtd = &nor->mtd; |
1014 | 1013 | ||
1015 | nor->dev = dev; | 1014 | nor->dev = dev; |
1016 | nor->flash_node = np; | 1015 | spi_nor_set_flash_node(nor, np); |
1017 | nor->priv = q; | 1016 | nor->priv = q; |
1018 | 1017 | ||
1019 | /* fill the hooks */ | 1018 | /* fill the hooks */ |
@@ -1038,8 +1037,7 @@ static int fsl_qspi_probe(struct platform_device *pdev) | |||
1038 | if (ret) | 1037 | if (ret) |
1039 | goto mutex_failed; | 1038 | goto mutex_failed; |
1040 | 1039 | ||
1041 | ppdata.of_node = np; | 1040 | ret = mtd_device_register(mtd, NULL, 0); |
1042 | ret = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); | ||
1043 | if (ret) | 1041 | if (ret) |
1044 | goto mutex_failed; | 1042 | goto mutex_failed; |
1045 | 1043 | ||
diff --git a/drivers/mtd/spi-nor/mtk-quadspi.c b/drivers/mtd/spi-nor/mtk-quadspi.c new file mode 100644 index 000000000000..d5f850d035bb --- /dev/null +++ b/drivers/mtd/spi-nor/mtk-quadspi.c | |||
@@ -0,0 +1,485 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2015 MediaTek Inc. | ||
3 | * Author: Bayi Cheng <bayi.cheng@mediatek.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | */ | ||
14 | |||
15 | #include <linux/clk.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/device.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <linux/iopoll.h> | ||
21 | #include <linux/ioport.h> | ||
22 | #include <linux/math64.h> | ||
23 | #include <linux/module.h> | ||
24 | #include <linux/mtd/mtd.h> | ||
25 | #include <linux/mutex.h> | ||
26 | #include <linux/of.h> | ||
27 | #include <linux/of_device.h> | ||
28 | #include <linux/pinctrl/consumer.h> | ||
29 | #include <linux/platform_device.h> | ||
30 | #include <linux/slab.h> | ||
31 | #include <linux/mtd/mtd.h> | ||
32 | #include <linux/mtd/partitions.h> | ||
33 | #include <linux/mtd/spi-nor.h> | ||
34 | |||
35 | #define MTK_NOR_CMD_REG 0x00 | ||
36 | #define MTK_NOR_CNT_REG 0x04 | ||
37 | #define MTK_NOR_RDSR_REG 0x08 | ||
38 | #define MTK_NOR_RDATA_REG 0x0c | ||
39 | #define MTK_NOR_RADR0_REG 0x10 | ||
40 | #define MTK_NOR_RADR1_REG 0x14 | ||
41 | #define MTK_NOR_RADR2_REG 0x18 | ||
42 | #define MTK_NOR_WDATA_REG 0x1c | ||
43 | #define MTK_NOR_PRGDATA0_REG 0x20 | ||
44 | #define MTK_NOR_PRGDATA1_REG 0x24 | ||
45 | #define MTK_NOR_PRGDATA2_REG 0x28 | ||
46 | #define MTK_NOR_PRGDATA3_REG 0x2c | ||
47 | #define MTK_NOR_PRGDATA4_REG 0x30 | ||
48 | #define MTK_NOR_PRGDATA5_REG 0x34 | ||
49 | #define MTK_NOR_SHREG0_REG 0x38 | ||
50 | #define MTK_NOR_SHREG1_REG 0x3c | ||
51 | #define MTK_NOR_SHREG2_REG 0x40 | ||
52 | #define MTK_NOR_SHREG3_REG 0x44 | ||
53 | #define MTK_NOR_SHREG4_REG 0x48 | ||
54 | #define MTK_NOR_SHREG5_REG 0x4c | ||
55 | #define MTK_NOR_SHREG6_REG 0x50 | ||
56 | #define MTK_NOR_SHREG7_REG 0x54 | ||
57 | #define MTK_NOR_SHREG8_REG 0x58 | ||
58 | #define MTK_NOR_SHREG9_REG 0x5c | ||
59 | #define MTK_NOR_CFG1_REG 0x60 | ||
60 | #define MTK_NOR_CFG2_REG 0x64 | ||
61 | #define MTK_NOR_CFG3_REG 0x68 | ||
62 | #define MTK_NOR_STATUS0_REG 0x70 | ||
63 | #define MTK_NOR_STATUS1_REG 0x74 | ||
64 | #define MTK_NOR_STATUS2_REG 0x78 | ||
65 | #define MTK_NOR_STATUS3_REG 0x7c | ||
66 | #define MTK_NOR_FLHCFG_REG 0x84 | ||
67 | #define MTK_NOR_TIME_REG 0x94 | ||
68 | #define MTK_NOR_PP_DATA_REG 0x98 | ||
69 | #define MTK_NOR_PREBUF_STUS_REG 0x9c | ||
70 | #define MTK_NOR_DELSEL0_REG 0xa0 | ||
71 | #define MTK_NOR_DELSEL1_REG 0xa4 | ||
72 | #define MTK_NOR_INTRSTUS_REG 0xa8 | ||
73 | #define MTK_NOR_INTREN_REG 0xac | ||
74 | #define MTK_NOR_CHKSUM_CTL_REG 0xb8 | ||
75 | #define MTK_NOR_CHKSUM_REG 0xbc | ||
76 | #define MTK_NOR_CMD2_REG 0xc0 | ||
77 | #define MTK_NOR_WRPROT_REG 0xc4 | ||
78 | #define MTK_NOR_RADR3_REG 0xc8 | ||
79 | #define MTK_NOR_DUAL_REG 0xcc | ||
80 | #define MTK_NOR_DELSEL2_REG 0xd0 | ||
81 | #define MTK_NOR_DELSEL3_REG 0xd4 | ||
82 | #define MTK_NOR_DELSEL4_REG 0xd8 | ||
83 | |||
84 | /* commands for mtk nor controller */ | ||
85 | #define MTK_NOR_READ_CMD 0x0 | ||
86 | #define MTK_NOR_RDSR_CMD 0x2 | ||
87 | #define MTK_NOR_PRG_CMD 0x4 | ||
88 | #define MTK_NOR_WR_CMD 0x10 | ||
89 | #define MTK_NOR_PIO_WR_CMD 0x90 | ||
90 | #define MTK_NOR_WRSR_CMD 0x20 | ||
91 | #define MTK_NOR_PIO_READ_CMD 0x81 | ||
92 | #define MTK_NOR_WR_BUF_ENABLE 0x1 | ||
93 | #define MTK_NOR_WR_BUF_DISABLE 0x0 | ||
94 | #define MTK_NOR_ENABLE_SF_CMD 0x30 | ||
95 | #define MTK_NOR_DUAD_ADDR_EN 0x8 | ||
96 | #define MTK_NOR_QUAD_READ_EN 0x4 | ||
97 | #define MTK_NOR_DUAL_ADDR_EN 0x2 | ||
98 | #define MTK_NOR_DUAL_READ_EN 0x1 | ||
99 | #define MTK_NOR_DUAL_DISABLE 0x0 | ||
100 | #define MTK_NOR_FAST_READ 0x1 | ||
101 | |||
102 | #define SFLASH_WRBUF_SIZE 128 | ||
103 | |||
104 | /* Can shift up to 48 bits (6 bytes) of TX/RX */ | ||
105 | #define MTK_NOR_MAX_RX_TX_SHIFT 6 | ||
106 | /* can shift up to 56 bits (7 bytes) transfer by MTK_NOR_PRG_CMD */ | ||
107 | #define MTK_NOR_MAX_SHIFT 7 | ||
108 | |||
109 | /* Helpers for accessing the program data / shift data registers */ | ||
110 | #define MTK_NOR_PRG_REG(n) (MTK_NOR_PRGDATA0_REG + 4 * (n)) | ||
111 | #define MTK_NOR_SHREG(n) (MTK_NOR_SHREG0_REG + 4 * (n)) | ||
112 | |||
113 | struct mt8173_nor { | ||
114 | struct spi_nor nor; | ||
115 | struct device *dev; | ||
116 | void __iomem *base; /* nor flash base address */ | ||
117 | struct clk *spi_clk; | ||
118 | struct clk *nor_clk; | ||
119 | }; | ||
120 | |||
121 | static void mt8173_nor_set_read_mode(struct mt8173_nor *mt8173_nor) | ||
122 | { | ||
123 | struct spi_nor *nor = &mt8173_nor->nor; | ||
124 | |||
125 | switch (nor->flash_read) { | ||
126 | case SPI_NOR_FAST: | ||
127 | writeb(nor->read_opcode, mt8173_nor->base + | ||
128 | MTK_NOR_PRGDATA3_REG); | ||
129 | writeb(MTK_NOR_FAST_READ, mt8173_nor->base + | ||
130 | MTK_NOR_CFG1_REG); | ||
131 | break; | ||
132 | case SPI_NOR_DUAL: | ||
133 | writeb(nor->read_opcode, mt8173_nor->base + | ||
134 | MTK_NOR_PRGDATA3_REG); | ||
135 | writeb(MTK_NOR_DUAL_READ_EN, mt8173_nor->base + | ||
136 | MTK_NOR_DUAL_REG); | ||
137 | break; | ||
138 | case SPI_NOR_QUAD: | ||
139 | writeb(nor->read_opcode, mt8173_nor->base + | ||
140 | MTK_NOR_PRGDATA4_REG); | ||
141 | writeb(MTK_NOR_QUAD_READ_EN, mt8173_nor->base + | ||
142 | MTK_NOR_DUAL_REG); | ||
143 | break; | ||
144 | default: | ||
145 | writeb(MTK_NOR_DUAL_DISABLE, mt8173_nor->base + | ||
146 | MTK_NOR_DUAL_REG); | ||
147 | break; | ||
148 | } | ||
149 | } | ||
150 | |||
151 | static int mt8173_nor_execute_cmd(struct mt8173_nor *mt8173_nor, u8 cmdval) | ||
152 | { | ||
153 | int reg; | ||
154 | u8 val = cmdval & 0x1f; | ||
155 | |||
156 | writeb(cmdval, mt8173_nor->base + MTK_NOR_CMD_REG); | ||
157 | return readl_poll_timeout(mt8173_nor->base + MTK_NOR_CMD_REG, reg, | ||
158 | !(reg & val), 100, 10000); | ||
159 | } | ||
160 | |||
161 | static int mt8173_nor_do_tx_rx(struct mt8173_nor *mt8173_nor, u8 op, | ||
162 | u8 *tx, int txlen, u8 *rx, int rxlen) | ||
163 | { | ||
164 | int len = 1 + txlen + rxlen; | ||
165 | int i, ret, idx; | ||
166 | |||
167 | if (len > MTK_NOR_MAX_SHIFT) | ||
168 | return -EINVAL; | ||
169 | |||
170 | writeb(len * 8, mt8173_nor->base + MTK_NOR_CNT_REG); | ||
171 | |||
172 | /* start at PRGDATA5, go down to PRGDATA0 */ | ||
173 | idx = MTK_NOR_MAX_RX_TX_SHIFT - 1; | ||
174 | |||
175 | /* opcode */ | ||
176 | writeb(op, mt8173_nor->base + MTK_NOR_PRG_REG(idx)); | ||
177 | idx--; | ||
178 | |||
179 | /* program TX data */ | ||
180 | for (i = 0; i < txlen; i++, idx--) | ||
181 | writeb(tx[i], mt8173_nor->base + MTK_NOR_PRG_REG(idx)); | ||
182 | |||
183 | /* clear out rest of TX registers */ | ||
184 | while (idx >= 0) { | ||
185 | writeb(0, mt8173_nor->base + MTK_NOR_PRG_REG(idx)); | ||
186 | idx--; | ||
187 | } | ||
188 | |||
189 | ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_PRG_CMD); | ||
190 | if (ret) | ||
191 | return ret; | ||
192 | |||
193 | /* restart at first RX byte */ | ||
194 | idx = rxlen - 1; | ||
195 | |||
196 | /* read out RX data */ | ||
197 | for (i = 0; i < rxlen; i++, idx--) | ||
198 | rx[i] = readb(mt8173_nor->base + MTK_NOR_SHREG(idx)); | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | /* Do a WRSR (Write Status Register) command */ | ||
204 | static int mt8173_nor_wr_sr(struct mt8173_nor *mt8173_nor, u8 sr) | ||
205 | { | ||
206 | writeb(sr, mt8173_nor->base + MTK_NOR_PRGDATA5_REG); | ||
207 | writeb(8, mt8173_nor->base + MTK_NOR_CNT_REG); | ||
208 | return mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_WRSR_CMD); | ||
209 | } | ||
210 | |||
211 | static int mt8173_nor_write_buffer_enable(struct mt8173_nor *mt8173_nor) | ||
212 | { | ||
213 | u8 reg; | ||
214 | |||
215 | /* the bit0 of MTK_NOR_CFG2_REG is pre-fetch buffer | ||
216 | * 0: pre-fetch buffer use for read | ||
217 | * 1: pre-fetch buffer use for page program | ||
218 | */ | ||
219 | writel(MTK_NOR_WR_BUF_ENABLE, mt8173_nor->base + MTK_NOR_CFG2_REG); | ||
220 | return readb_poll_timeout(mt8173_nor->base + MTK_NOR_CFG2_REG, reg, | ||
221 | 0x01 == (reg & 0x01), 100, 10000); | ||
222 | } | ||
223 | |||
224 | static int mt8173_nor_write_buffer_disable(struct mt8173_nor *mt8173_nor) | ||
225 | { | ||
226 | u8 reg; | ||
227 | |||
228 | writel(MTK_NOR_WR_BUF_DISABLE, mt8173_nor->base + MTK_NOR_CFG2_REG); | ||
229 | return readb_poll_timeout(mt8173_nor->base + MTK_NOR_CFG2_REG, reg, | ||
230 | MTK_NOR_WR_BUF_DISABLE == (reg & 0x1), 100, | ||
231 | 10000); | ||
232 | } | ||
233 | |||
234 | static void mt8173_nor_set_addr(struct mt8173_nor *mt8173_nor, u32 addr) | ||
235 | { | ||
236 | int i; | ||
237 | |||
238 | for (i = 0; i < 3; i++) { | ||
239 | writeb(addr & 0xff, mt8173_nor->base + MTK_NOR_RADR0_REG + i * 4); | ||
240 | addr >>= 8; | ||
241 | } | ||
242 | /* Last register is non-contiguous */ | ||
243 | writeb(addr & 0xff, mt8173_nor->base + MTK_NOR_RADR3_REG); | ||
244 | } | ||
245 | |||
246 | static int mt8173_nor_read(struct spi_nor *nor, loff_t from, size_t length, | ||
247 | size_t *retlen, u_char *buffer) | ||
248 | { | ||
249 | int i, ret; | ||
250 | int addr = (int)from; | ||
251 | u8 *buf = (u8 *)buffer; | ||
252 | struct mt8173_nor *mt8173_nor = nor->priv; | ||
253 | |||
254 | /* set mode for fast read mode ,dual mode or quad mode */ | ||
255 | mt8173_nor_set_read_mode(mt8173_nor); | ||
256 | mt8173_nor_set_addr(mt8173_nor, addr); | ||
257 | |||
258 | for (i = 0; i < length; i++, (*retlen)++) { | ||
259 | ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_PIO_READ_CMD); | ||
260 | if (ret < 0) | ||
261 | return ret; | ||
262 | buf[i] = readb(mt8173_nor->base + MTK_NOR_RDATA_REG); | ||
263 | } | ||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | static int mt8173_nor_write_single_byte(struct mt8173_nor *mt8173_nor, | ||
268 | int addr, int length, u8 *data) | ||
269 | { | ||
270 | int i, ret; | ||
271 | |||
272 | mt8173_nor_set_addr(mt8173_nor, addr); | ||
273 | |||
274 | for (i = 0; i < length; i++) { | ||
275 | writeb(*data++, mt8173_nor->base + MTK_NOR_WDATA_REG); | ||
276 | ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_PIO_WR_CMD); | ||
277 | if (ret < 0) | ||
278 | return ret; | ||
279 | } | ||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | static int mt8173_nor_write_buffer(struct mt8173_nor *mt8173_nor, int addr, | ||
284 | const u8 *buf) | ||
285 | { | ||
286 | int i, bufidx, data; | ||
287 | |||
288 | mt8173_nor_set_addr(mt8173_nor, addr); | ||
289 | |||
290 | bufidx = 0; | ||
291 | for (i = 0; i < SFLASH_WRBUF_SIZE; i += 4) { | ||
292 | data = buf[bufidx + 3]<<24 | buf[bufidx + 2]<<16 | | ||
293 | buf[bufidx + 1]<<8 | buf[bufidx]; | ||
294 | bufidx += 4; | ||
295 | writel(data, mt8173_nor->base + MTK_NOR_PP_DATA_REG); | ||
296 | } | ||
297 | return mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_WR_CMD); | ||
298 | } | ||
299 | |||
300 | static void mt8173_nor_write(struct spi_nor *nor, loff_t to, size_t len, | ||
301 | size_t *retlen, const u_char *buf) | ||
302 | { | ||
303 | int ret; | ||
304 | struct mt8173_nor *mt8173_nor = nor->priv; | ||
305 | |||
306 | ret = mt8173_nor_write_buffer_enable(mt8173_nor); | ||
307 | if (ret < 0) | ||
308 | dev_warn(mt8173_nor->dev, "write buffer enable failed!\n"); | ||
309 | |||
310 | while (len >= SFLASH_WRBUF_SIZE) { | ||
311 | ret = mt8173_nor_write_buffer(mt8173_nor, to, buf); | ||
312 | if (ret < 0) | ||
313 | dev_err(mt8173_nor->dev, "write buffer failed!\n"); | ||
314 | len -= SFLASH_WRBUF_SIZE; | ||
315 | to += SFLASH_WRBUF_SIZE; | ||
316 | buf += SFLASH_WRBUF_SIZE; | ||
317 | (*retlen) += SFLASH_WRBUF_SIZE; | ||
318 | } | ||
319 | ret = mt8173_nor_write_buffer_disable(mt8173_nor); | ||
320 | if (ret < 0) | ||
321 | dev_warn(mt8173_nor->dev, "write buffer disable failed!\n"); | ||
322 | |||
323 | if (len) { | ||
324 | ret = mt8173_nor_write_single_byte(mt8173_nor, to, (int)len, | ||
325 | (u8 *)buf); | ||
326 | if (ret < 0) | ||
327 | dev_err(mt8173_nor->dev, "write single byte failed!\n"); | ||
328 | (*retlen) += len; | ||
329 | } | ||
330 | } | ||
331 | |||
332 | static int mt8173_nor_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len) | ||
333 | { | ||
334 | int ret; | ||
335 | struct mt8173_nor *mt8173_nor = nor->priv; | ||
336 | |||
337 | switch (opcode) { | ||
338 | case SPINOR_OP_RDSR: | ||
339 | ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_RDSR_CMD); | ||
340 | if (ret < 0) | ||
341 | return ret; | ||
342 | if (len == 1) | ||
343 | *buf = readb(mt8173_nor->base + MTK_NOR_RDSR_REG); | ||
344 | else | ||
345 | dev_err(mt8173_nor->dev, "len should be 1 for read status!\n"); | ||
346 | break; | ||
347 | default: | ||
348 | ret = mt8173_nor_do_tx_rx(mt8173_nor, opcode, NULL, 0, buf, len); | ||
349 | break; | ||
350 | } | ||
351 | return ret; | ||
352 | } | ||
353 | |||
354 | static int mt8173_nor_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, | ||
355 | int len) | ||
356 | { | ||
357 | int ret; | ||
358 | struct mt8173_nor *mt8173_nor = nor->priv; | ||
359 | |||
360 | switch (opcode) { | ||
361 | case SPINOR_OP_WRSR: | ||
362 | /* We only handle 1 byte */ | ||
363 | ret = mt8173_nor_wr_sr(mt8173_nor, *buf); | ||
364 | break; | ||
365 | default: | ||
366 | ret = mt8173_nor_do_tx_rx(mt8173_nor, opcode, buf, len, NULL, 0); | ||
367 | if (ret) | ||
368 | dev_warn(mt8173_nor->dev, "write reg failure!\n"); | ||
369 | break; | ||
370 | } | ||
371 | return ret; | ||
372 | } | ||
373 | |||
374 | static int __init mtk_nor_init(struct mt8173_nor *mt8173_nor, | ||
375 | struct device_node *flash_node) | ||
376 | { | ||
377 | int ret; | ||
378 | struct spi_nor *nor; | ||
379 | |||
380 | /* initialize controller to accept commands */ | ||
381 | writel(MTK_NOR_ENABLE_SF_CMD, mt8173_nor->base + MTK_NOR_WRPROT_REG); | ||
382 | |||
383 | nor = &mt8173_nor->nor; | ||
384 | nor->dev = mt8173_nor->dev; | ||
385 | nor->priv = mt8173_nor; | ||
386 | spi_nor_set_flash_node(nor, flash_node); | ||
387 | |||
388 | /* fill the hooks to spi nor */ | ||
389 | nor->read = mt8173_nor_read; | ||
390 | nor->read_reg = mt8173_nor_read_reg; | ||
391 | nor->write = mt8173_nor_write; | ||
392 | nor->write_reg = mt8173_nor_write_reg; | ||
393 | nor->mtd.name = "mtk_nor"; | ||
394 | /* initialized with NULL */ | ||
395 | ret = spi_nor_scan(nor, NULL, SPI_NOR_DUAL); | ||
396 | if (ret) | ||
397 | return ret; | ||
398 | |||
399 | return mtd_device_register(&nor->mtd, NULL, 0); | ||
400 | } | ||
401 | |||
402 | static int mtk_nor_drv_probe(struct platform_device *pdev) | ||
403 | { | ||
404 | struct device_node *flash_np; | ||
405 | struct resource *res; | ||
406 | int ret; | ||
407 | struct mt8173_nor *mt8173_nor; | ||
408 | |||
409 | if (!pdev->dev.of_node) { | ||
410 | dev_err(&pdev->dev, "No DT found\n"); | ||
411 | return -EINVAL; | ||
412 | } | ||
413 | |||
414 | mt8173_nor = devm_kzalloc(&pdev->dev, sizeof(*mt8173_nor), GFP_KERNEL); | ||
415 | if (!mt8173_nor) | ||
416 | return -ENOMEM; | ||
417 | platform_set_drvdata(pdev, mt8173_nor); | ||
418 | |||
419 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
420 | mt8173_nor->base = devm_ioremap_resource(&pdev->dev, res); | ||
421 | if (IS_ERR(mt8173_nor->base)) | ||
422 | return PTR_ERR(mt8173_nor->base); | ||
423 | |||
424 | mt8173_nor->spi_clk = devm_clk_get(&pdev->dev, "spi"); | ||
425 | if (IS_ERR(mt8173_nor->spi_clk)) | ||
426 | return PTR_ERR(mt8173_nor->spi_clk); | ||
427 | |||
428 | mt8173_nor->nor_clk = devm_clk_get(&pdev->dev, "sf"); | ||
429 | if (IS_ERR(mt8173_nor->nor_clk)) | ||
430 | return PTR_ERR(mt8173_nor->nor_clk); | ||
431 | |||
432 | mt8173_nor->dev = &pdev->dev; | ||
433 | ret = clk_prepare_enable(mt8173_nor->spi_clk); | ||
434 | if (ret) | ||
435 | return ret; | ||
436 | |||
437 | ret = clk_prepare_enable(mt8173_nor->nor_clk); | ||
438 | if (ret) { | ||
439 | clk_disable_unprepare(mt8173_nor->spi_clk); | ||
440 | return ret; | ||
441 | } | ||
442 | /* only support one attached flash */ | ||
443 | flash_np = of_get_next_available_child(pdev->dev.of_node, NULL); | ||
444 | if (!flash_np) { | ||
445 | dev_err(&pdev->dev, "no SPI flash device to configure\n"); | ||
446 | ret = -ENODEV; | ||
447 | goto nor_free; | ||
448 | } | ||
449 | ret = mtk_nor_init(mt8173_nor, flash_np); | ||
450 | |||
451 | nor_free: | ||
452 | if (ret) { | ||
453 | clk_disable_unprepare(mt8173_nor->spi_clk); | ||
454 | clk_disable_unprepare(mt8173_nor->nor_clk); | ||
455 | } | ||
456 | return ret; | ||
457 | } | ||
458 | |||
459 | static int mtk_nor_drv_remove(struct platform_device *pdev) | ||
460 | { | ||
461 | struct mt8173_nor *mt8173_nor = platform_get_drvdata(pdev); | ||
462 | |||
463 | clk_disable_unprepare(mt8173_nor->spi_clk); | ||
464 | clk_disable_unprepare(mt8173_nor->nor_clk); | ||
465 | return 0; | ||
466 | } | ||
467 | |||
468 | static const struct of_device_id mtk_nor_of_ids[] = { | ||
469 | { .compatible = "mediatek,mt8173-nor"}, | ||
470 | { /* sentinel */ } | ||
471 | }; | ||
472 | MODULE_DEVICE_TABLE(of, mtk_nor_of_ids); | ||
473 | |||
474 | static struct platform_driver mtk_nor_driver = { | ||
475 | .probe = mtk_nor_drv_probe, | ||
476 | .remove = mtk_nor_drv_remove, | ||
477 | .driver = { | ||
478 | .name = "mtk-nor", | ||
479 | .of_match_table = mtk_nor_of_ids, | ||
480 | }, | ||
481 | }; | ||
482 | |||
483 | module_platform_driver(mtk_nor_driver); | ||
484 | MODULE_LICENSE("GPL v2"); | ||
485 | MODULE_DESCRIPTION("MediaTek SPI NOR Flash Driver"); | ||
diff --git a/drivers/mtd/spi-nor/nxp-spifi.c b/drivers/mtd/spi-nor/nxp-spifi.c index 9e82098ae644..ae428cb0e04b 100644 --- a/drivers/mtd/spi-nor/nxp-spifi.c +++ b/drivers/mtd/spi-nor/nxp-spifi.c | |||
@@ -271,7 +271,6 @@ static void nxp_spifi_dummy_id_read(struct spi_nor *nor) | |||
271 | static int nxp_spifi_setup_flash(struct nxp_spifi *spifi, | 271 | static int nxp_spifi_setup_flash(struct nxp_spifi *spifi, |
272 | struct device_node *np) | 272 | struct device_node *np) |
273 | { | 273 | { |
274 | struct mtd_part_parser_data ppdata; | ||
275 | enum read_mode flash_read; | 274 | enum read_mode flash_read; |
276 | u32 ctrl, property; | 275 | u32 ctrl, property; |
277 | u16 mode = 0; | 276 | u16 mode = 0; |
@@ -330,7 +329,7 @@ static int nxp_spifi_setup_flash(struct nxp_spifi *spifi, | |||
330 | writel(ctrl, spifi->io_base + SPIFI_CTRL); | 329 | writel(ctrl, spifi->io_base + SPIFI_CTRL); |
331 | 330 | ||
332 | spifi->nor.dev = spifi->dev; | 331 | spifi->nor.dev = spifi->dev; |
333 | spifi->nor.flash_node = np; | 332 | spi_nor_set_flash_node(&spifi->nor, np); |
334 | spifi->nor.priv = spifi; | 333 | spifi->nor.priv = spifi; |
335 | spifi->nor.read = nxp_spifi_read; | 334 | spifi->nor.read = nxp_spifi_read; |
336 | spifi->nor.write = nxp_spifi_write; | 335 | spifi->nor.write = nxp_spifi_write; |
@@ -361,8 +360,7 @@ static int nxp_spifi_setup_flash(struct nxp_spifi *spifi, | |||
361 | return ret; | 360 | return ret; |
362 | } | 361 | } |
363 | 362 | ||
364 | ppdata.of_node = np; | 363 | ret = mtd_device_register(&spifi->nor.mtd, NULL, 0); |
365 | ret = mtd_device_parse_register(&spifi->nor.mtd, NULL, &ppdata, NULL, 0); | ||
366 | if (ret) { | 364 | if (ret) { |
367 | dev_err(spifi->dev, "mtd device parse failed\n"); | 365 | dev_err(spifi->dev, "mtd device parse failed\n"); |
368 | return ret; | 366 | return ret; |
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 32477c4eb421..ed0c19c558b5 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #define CHIP_ERASE_2MB_READY_WAIT_JIFFIES (40UL * HZ) | 38 | #define CHIP_ERASE_2MB_READY_WAIT_JIFFIES (40UL * HZ) |
39 | 39 | ||
40 | #define SPI_NOR_MAX_ID_LEN 6 | 40 | #define SPI_NOR_MAX_ID_LEN 6 |
41 | #define SPI_NOR_MAX_ADDR_WIDTH 4 | ||
41 | 42 | ||
42 | struct flash_info { | 43 | struct flash_info { |
43 | char *name; | 44 | char *name; |
@@ -313,6 +314,29 @@ static void spi_nor_unlock_and_unprep(struct spi_nor *nor, enum spi_nor_ops ops) | |||
313 | } | 314 | } |
314 | 315 | ||
315 | /* | 316 | /* |
317 | * Initiate the erasure of a single sector | ||
318 | */ | ||
319 | static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr) | ||
320 | { | ||
321 | u8 buf[SPI_NOR_MAX_ADDR_WIDTH]; | ||
322 | int i; | ||
323 | |||
324 | if (nor->erase) | ||
325 | return nor->erase(nor, addr); | ||
326 | |||
327 | /* | ||
328 | * Default implementation, if driver doesn't have a specialized HW | ||
329 | * control | ||
330 | */ | ||
331 | for (i = nor->addr_width - 1; i >= 0; i--) { | ||
332 | buf[i] = addr & 0xff; | ||
333 | addr >>= 8; | ||
334 | } | ||
335 | |||
336 | return nor->write_reg(nor, nor->erase_opcode, buf, nor->addr_width); | ||
337 | } | ||
338 | |||
339 | /* | ||
316 | * Erase an address range on the nor chip. The address range may extend | 340 | * Erase an address range on the nor chip. The address range may extend |
317 | * one or more erase sectors. Return an error is there is a problem erasing. | 341 | * one or more erase sectors. Return an error is there is a problem erasing. |
318 | */ | 342 | */ |
@@ -371,10 +395,9 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
371 | while (len) { | 395 | while (len) { |
372 | write_enable(nor); | 396 | write_enable(nor); |
373 | 397 | ||
374 | if (nor->erase(nor, addr)) { | 398 | ret = spi_nor_erase_sector(nor, addr); |
375 | ret = -EIO; | 399 | if (ret) |
376 | goto erase_err; | 400 | goto erase_err; |
377 | } | ||
378 | 401 | ||
379 | addr += mtd->erasesize; | 402 | addr += mtd->erasesize; |
380 | len -= mtd->erasesize; | 403 | len -= mtd->erasesize; |
@@ -387,17 +410,13 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
387 | 410 | ||
388 | write_disable(nor); | 411 | write_disable(nor); |
389 | 412 | ||
413 | erase_err: | ||
390 | spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE); | 414 | spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE); |
391 | 415 | ||
392 | instr->state = MTD_ERASE_DONE; | 416 | instr->state = ret ? MTD_ERASE_FAILED : MTD_ERASE_DONE; |
393 | mtd_erase_callback(instr); | 417 | mtd_erase_callback(instr); |
394 | 418 | ||
395 | return ret; | 419 | return ret; |
396 | |||
397 | erase_err: | ||
398 | spi_nor_unlock_and_unprep(nor, SPI_NOR_OPS_ERASE); | ||
399 | instr->state = MTD_ERASE_FAILED; | ||
400 | return ret; | ||
401 | } | 420 | } |
402 | 421 | ||
403 | static void stm_get_locked_range(struct spi_nor *nor, u8 sr, loff_t *ofs, | 422 | static void stm_get_locked_range(struct spi_nor *nor, u8 sr, loff_t *ofs, |
@@ -459,11 +478,14 @@ static int stm_is_locked_sr(struct spi_nor *nor, loff_t ofs, uint64_t len, | |||
459 | static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) | 478 | static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) |
460 | { | 479 | { |
461 | struct mtd_info *mtd = &nor->mtd; | 480 | struct mtd_info *mtd = &nor->mtd; |
462 | u8 status_old, status_new; | 481 | int status_old, status_new; |
463 | u8 mask = SR_BP2 | SR_BP1 | SR_BP0; | 482 | u8 mask = SR_BP2 | SR_BP1 | SR_BP0; |
464 | u8 shift = ffs(mask) - 1, pow, val; | 483 | u8 shift = ffs(mask) - 1, pow, val; |
484 | int ret; | ||
465 | 485 | ||
466 | status_old = read_sr(nor); | 486 | status_old = read_sr(nor); |
487 | if (status_old < 0) | ||
488 | return status_old; | ||
467 | 489 | ||
468 | /* SPI NOR always locks to the end */ | 490 | /* SPI NOR always locks to the end */ |
469 | if (ofs + len != mtd->size) { | 491 | if (ofs + len != mtd->size) { |
@@ -498,7 +520,10 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) | |||
498 | return -EINVAL; | 520 | return -EINVAL; |
499 | 521 | ||
500 | write_enable(nor); | 522 | write_enable(nor); |
501 | return write_sr(nor, status_new); | 523 | ret = write_sr(nor, status_new); |
524 | if (ret) | ||
525 | return ret; | ||
526 | return spi_nor_wait_till_ready(nor); | ||
502 | } | 527 | } |
503 | 528 | ||
504 | /* | 529 | /* |
@@ -509,11 +534,14 @@ static int stm_lock(struct spi_nor *nor, loff_t ofs, uint64_t len) | |||
509 | static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) | 534 | static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) |
510 | { | 535 | { |
511 | struct mtd_info *mtd = &nor->mtd; | 536 | struct mtd_info *mtd = &nor->mtd; |
512 | uint8_t status_old, status_new; | 537 | int status_old, status_new; |
513 | u8 mask = SR_BP2 | SR_BP1 | SR_BP0; | 538 | u8 mask = SR_BP2 | SR_BP1 | SR_BP0; |
514 | u8 shift = ffs(mask) - 1, pow, val; | 539 | u8 shift = ffs(mask) - 1, pow, val; |
540 | int ret; | ||
515 | 541 | ||
516 | status_old = read_sr(nor); | 542 | status_old = read_sr(nor); |
543 | if (status_old < 0) | ||
544 | return status_old; | ||
517 | 545 | ||
518 | /* Cannot unlock; would unlock larger region than requested */ | 546 | /* Cannot unlock; would unlock larger region than requested */ |
519 | if (stm_is_locked_sr(nor, ofs - mtd->erasesize, mtd->erasesize, | 547 | if (stm_is_locked_sr(nor, ofs - mtd->erasesize, mtd->erasesize, |
@@ -546,7 +574,10 @@ static int stm_unlock(struct spi_nor *nor, loff_t ofs, uint64_t len) | |||
546 | return -EINVAL; | 574 | return -EINVAL; |
547 | 575 | ||
548 | write_enable(nor); | 576 | write_enable(nor); |
549 | return write_sr(nor, status_new); | 577 | ret = write_sr(nor, status_new); |
578 | if (ret) | ||
579 | return ret; | ||
580 | return spi_nor_wait_till_ready(nor); | ||
550 | } | 581 | } |
551 | 582 | ||
552 | /* | 583 | /* |
@@ -715,9 +746,9 @@ static const struct flash_info spi_nor_ids[] = { | |||
715 | { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) }, | 746 | { "mx25l4005a", INFO(0xc22013, 0, 64 * 1024, 8, SECT_4K) }, |
716 | { "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16, 0) }, | 747 | { "mx25l8005", INFO(0xc22014, 0, 64 * 1024, 16, 0) }, |
717 | { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, SECT_4K) }, | 748 | { "mx25l1606e", INFO(0xc22015, 0, 64 * 1024, 32, SECT_4K) }, |
718 | { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, 0) }, | 749 | { "mx25l3205d", INFO(0xc22016, 0, 64 * 1024, 64, SECT_4K) }, |
719 | { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) }, | 750 | { "mx25l3255e", INFO(0xc29e16, 0, 64 * 1024, 64, SECT_4K) }, |
720 | { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, 0) }, | 751 | { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, SECT_4K) }, |
721 | { "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) }, | 752 | { "mx25u6435f", INFO(0xc22537, 0, 64 * 1024, 128, SECT_4K) }, |
722 | { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, | 753 | { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, |
723 | { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, | 754 | { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, |
@@ -856,7 +887,7 @@ static const struct flash_info *spi_nor_read_id(struct spi_nor *nor) | |||
856 | 887 | ||
857 | tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN); | 888 | tmp = nor->read_reg(nor, SPINOR_OP_RDID, id, SPI_NOR_MAX_ID_LEN); |
858 | if (tmp < 0) { | 889 | if (tmp < 0) { |
859 | dev_dbg(nor->dev, " error %d reading JEDEC ID\n", tmp); | 890 | dev_dbg(nor->dev, "error %d reading JEDEC ID\n", tmp); |
860 | return ERR_PTR(tmp); | 891 | return ERR_PTR(tmp); |
861 | } | 892 | } |
862 | 893 | ||
@@ -867,7 +898,7 @@ static const struct flash_info *spi_nor_read_id(struct spi_nor *nor) | |||
867 | return &spi_nor_ids[tmp]; | 898 | return &spi_nor_ids[tmp]; |
868 | } | 899 | } |
869 | } | 900 | } |
870 | dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %2x, %2x\n", | 901 | dev_err(nor->dev, "unrecognized JEDEC id bytes: %02x, %02x, %02x\n", |
871 | id[0], id[1], id[2]); | 902 | id[0], id[1], id[2]); |
872 | return ERR_PTR(-ENODEV); | 903 | return ERR_PTR(-ENODEV); |
873 | } | 904 | } |
@@ -1013,6 +1044,8 @@ static int macronix_quad_enable(struct spi_nor *nor) | |||
1013 | int ret, val; | 1044 | int ret, val; |
1014 | 1045 | ||
1015 | val = read_sr(nor); | 1046 | val = read_sr(nor); |
1047 | if (val < 0) | ||
1048 | return val; | ||
1016 | write_enable(nor); | 1049 | write_enable(nor); |
1017 | 1050 | ||
1018 | write_sr(nor, val | SR_QUAD_EN_MX); | 1051 | write_sr(nor, val | SR_QUAD_EN_MX); |
@@ -1138,7 +1171,7 @@ static int set_quad_mode(struct spi_nor *nor, const struct flash_info *info) | |||
1138 | static int spi_nor_check(struct spi_nor *nor) | 1171 | static int spi_nor_check(struct spi_nor *nor) |
1139 | { | 1172 | { |
1140 | if (!nor->dev || !nor->read || !nor->write || | 1173 | if (!nor->dev || !nor->read || !nor->write || |
1141 | !nor->read_reg || !nor->write_reg || !nor->erase) { | 1174 | !nor->read_reg || !nor->write_reg) { |
1142 | pr_err("spi-nor: please fill all the necessary fields!\n"); | 1175 | pr_err("spi-nor: please fill all the necessary fields!\n"); |
1143 | return -EINVAL; | 1176 | return -EINVAL; |
1144 | } | 1177 | } |
@@ -1151,7 +1184,7 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) | |||
1151 | const struct flash_info *info = NULL; | 1184 | const struct flash_info *info = NULL; |
1152 | struct device *dev = nor->dev; | 1185 | struct device *dev = nor->dev; |
1153 | struct mtd_info *mtd = &nor->mtd; | 1186 | struct mtd_info *mtd = &nor->mtd; |
1154 | struct device_node *np = nor->flash_node; | 1187 | struct device_node *np = spi_nor_get_flash_node(nor); |
1155 | int ret; | 1188 | int ret; |
1156 | int i; | 1189 | int i; |
1157 | 1190 | ||
@@ -1338,6 +1371,12 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) | |||
1338 | nor->addr_width = 3; | 1371 | nor->addr_width = 3; |
1339 | } | 1372 | } |
1340 | 1373 | ||
1374 | if (nor->addr_width > SPI_NOR_MAX_ADDR_WIDTH) { | ||
1375 | dev_err(dev, "address width is too large: %u\n", | ||
1376 | nor->addr_width); | ||
1377 | return -EINVAL; | ||
1378 | } | ||
1379 | |||
1341 | nor->read_dummy = spi_nor_read_dummy_cycles(nor); | 1380 | nor->read_dummy = spi_nor_read_dummy_cycles(nor); |
1342 | 1381 | ||
1343 | dev_info(dev, "%s (%lld Kbytes)\n", info->name, | 1382 | dev_info(dev, "%s (%lld Kbytes)\n", info->name, |
diff --git a/drivers/mtd/tests/pagetest.c b/drivers/mtd/tests/pagetest.c index ba1890d5632c..ff1e0565b020 100644 --- a/drivers/mtd/tests/pagetest.c +++ b/drivers/mtd/tests/pagetest.c | |||
@@ -127,13 +127,12 @@ static int crosstest(void) | |||
127 | unsigned char *pp1, *pp2, *pp3, *pp4; | 127 | unsigned char *pp1, *pp2, *pp3, *pp4; |
128 | 128 | ||
129 | pr_info("crosstest\n"); | 129 | pr_info("crosstest\n"); |
130 | pp1 = kmalloc(pgsize * 4, GFP_KERNEL); | 130 | pp1 = kzalloc(pgsize * 4, GFP_KERNEL); |
131 | if (!pp1) | 131 | if (!pp1) |
132 | return -ENOMEM; | 132 | return -ENOMEM; |
133 | pp2 = pp1 + pgsize; | 133 | pp2 = pp1 + pgsize; |
134 | pp3 = pp2 + pgsize; | 134 | pp3 = pp2 + pgsize; |
135 | pp4 = pp3 + pgsize; | 135 | pp4 = pp3 + pgsize; |
136 | memset(pp1, 0, pgsize * 4); | ||
137 | 136 | ||
138 | addr0 = 0; | 137 | addr0 = 0; |
139 | for (i = 0; i < ebcnt && bbt[i]; ++i) | 138 | for (i = 0; i < ebcnt && bbt[i]; ++i) |
diff --git a/drivers/staging/mt29f_spinand/mt29f_spinand.c b/drivers/staging/mt29f_spinand/mt29f_spinand.c index 47bb56f1f8c0..197d1124733d 100644 --- a/drivers/staging/mt29f_spinand/mt29f_spinand.c +++ b/drivers/staging/mt29f_spinand/mt29f_spinand.c | |||
@@ -31,8 +31,8 @@ | |||
31 | 31 | ||
32 | static inline struct spinand_state *mtd_to_state(struct mtd_info *mtd) | 32 | static inline struct spinand_state *mtd_to_state(struct mtd_info *mtd) |
33 | { | 33 | { |
34 | struct nand_chip *chip = (struct nand_chip *)mtd->priv; | 34 | struct nand_chip *chip = mtd_to_nand(mtd); |
35 | struct spinand_info *info = (struct spinand_info *)chip->priv; | 35 | struct spinand_info *info = nand_get_controller_data(chip); |
36 | struct spinand_state *state = (struct spinand_state *)info->priv; | 36 | struct spinand_state *state = (struct spinand_state *)info->priv; |
37 | 37 | ||
38 | return state; | 38 | return state; |
@@ -633,7 +633,7 @@ static int spinand_read_page_hwecc(struct mtd_info *mtd, struct nand_chip *chip, | |||
633 | u8 *p = buf; | 633 | u8 *p = buf; |
634 | int eccsize = chip->ecc.size; | 634 | int eccsize = chip->ecc.size; |
635 | int eccsteps = chip->ecc.steps; | 635 | int eccsteps = chip->ecc.steps; |
636 | struct spinand_info *info = (struct spinand_info *)chip->priv; | 636 | struct spinand_info *info = nand_get_controller_data(chip); |
637 | 637 | ||
638 | enable_read_hw_ecc = 1; | 638 | enable_read_hw_ecc = 1; |
639 | 639 | ||
@@ -679,7 +679,7 @@ static u8 spinand_read_byte(struct mtd_info *mtd) | |||
679 | 679 | ||
680 | static int spinand_wait(struct mtd_info *mtd, struct nand_chip *chip) | 680 | static int spinand_wait(struct mtd_info *mtd, struct nand_chip *chip) |
681 | { | 681 | { |
682 | struct spinand_info *info = (struct spinand_info *)chip->priv; | 682 | struct spinand_info *info = nand_get_controller_data(chip); |
683 | 683 | ||
684 | unsigned long timeo = jiffies; | 684 | unsigned long timeo = jiffies; |
685 | int retval, state = chip->state; | 685 | int retval, state = chip->state; |
@@ -744,8 +744,8 @@ static void spinand_reset(struct spi_device *spi_nand) | |||
744 | static void spinand_cmdfunc(struct mtd_info *mtd, unsigned int command, | 744 | static void spinand_cmdfunc(struct mtd_info *mtd, unsigned int command, |
745 | int column, int page) | 745 | int column, int page) |
746 | { | 746 | { |
747 | struct nand_chip *chip = (struct nand_chip *)mtd->priv; | 747 | struct nand_chip *chip = mtd_to_nand(mtd); |
748 | struct spinand_info *info = (struct spinand_info *)chip->priv; | 748 | struct spinand_info *info = nand_get_controller_data(chip); |
749 | struct spinand_state *state = (struct spinand_state *)info->priv; | 749 | struct spinand_state *state = (struct spinand_state *)info->priv; |
750 | 750 | ||
751 | switch (command) { | 751 | switch (command) { |
@@ -850,7 +850,6 @@ static int spinand_probe(struct spi_device *spi_nand) | |||
850 | struct nand_chip *chip; | 850 | struct nand_chip *chip; |
851 | struct spinand_info *info; | 851 | struct spinand_info *info; |
852 | struct spinand_state *state; | 852 | struct spinand_state *state; |
853 | struct mtd_part_parser_data ppdata; | ||
854 | 853 | ||
855 | info = devm_kzalloc(&spi_nand->dev, sizeof(struct spinand_info), | 854 | info = devm_kzalloc(&spi_nand->dev, sizeof(struct spinand_info), |
856 | GFP_KERNEL); | 855 | GFP_KERNEL); |
@@ -894,7 +893,8 @@ static int spinand_probe(struct spi_device *spi_nand) | |||
894 | pr_info("%s: disable ecc failed!\n", __func__); | 893 | pr_info("%s: disable ecc failed!\n", __func__); |
895 | #endif | 894 | #endif |
896 | 895 | ||
897 | chip->priv = info; | 896 | nand_set_flash_node(chip, spi_nand->dev.of_node); |
897 | nand_set_controller_data(chip, info); | ||
898 | chip->read_buf = spinand_read_buf; | 898 | chip->read_buf = spinand_read_buf; |
899 | chip->write_buf = spinand_write_buf; | 899 | chip->write_buf = spinand_write_buf; |
900 | chip->read_byte = spinand_read_byte; | 900 | chip->read_byte = spinand_read_byte; |
@@ -903,21 +903,17 @@ static int spinand_probe(struct spi_device *spi_nand) | |||
903 | chip->options |= NAND_CACHEPRG; | 903 | chip->options |= NAND_CACHEPRG; |
904 | chip->select_chip = spinand_select_chip; | 904 | chip->select_chip = spinand_select_chip; |
905 | 905 | ||
906 | mtd = devm_kzalloc(&spi_nand->dev, sizeof(struct mtd_info), GFP_KERNEL); | 906 | mtd = nand_to_mtd(chip); |
907 | if (!mtd) | ||
908 | return -ENOMEM; | ||
909 | 907 | ||
910 | dev_set_drvdata(&spi_nand->dev, mtd); | 908 | dev_set_drvdata(&spi_nand->dev, mtd); |
911 | 909 | ||
912 | mtd->priv = chip; | ||
913 | mtd->dev.parent = &spi_nand->dev; | 910 | mtd->dev.parent = &spi_nand->dev; |
914 | mtd->oobsize = 64; | 911 | mtd->oobsize = 64; |
915 | 912 | ||
916 | if (nand_scan(mtd, 1)) | 913 | if (nand_scan(mtd, 1)) |
917 | return -ENXIO; | 914 | return -ENXIO; |
918 | 915 | ||
919 | ppdata.of_node = spi_nand->dev.of_node; | 916 | return mtd_device_register(mtd, NULL, 0); |
920 | return mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); | ||
921 | } | 917 | } |
922 | 918 | ||
923 | /* | 919 | /* |
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c index f3a4857ff071..5a3da3f52908 100644 --- a/fs/jffs2/wbuf.c +++ b/fs/jffs2/wbuf.c | |||
@@ -1153,7 +1153,7 @@ static struct jffs2_sb_info *work_to_sb(struct work_struct *work) | |||
1153 | { | 1153 | { |
1154 | struct delayed_work *dwork; | 1154 | struct delayed_work *dwork; |
1155 | 1155 | ||
1156 | dwork = container_of(work, struct delayed_work, work); | 1156 | dwork = to_delayed_work(work); |
1157 | return container_of(dwork, struct jffs2_sb_info, wbuf_dwork); | 1157 | return container_of(dwork, struct jffs2_sb_info, wbuf_dwork); |
1158 | } | 1158 | } |
1159 | 1159 | ||
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h index cf038431a5cc..db51a6ffb7d6 100644 --- a/include/linux/bcma/bcma_driver_chipcommon.h +++ b/include/linux/bcma/bcma_driver_chipcommon.h | |||
@@ -579,6 +579,8 @@ struct bcma_pflash { | |||
579 | }; | 579 | }; |
580 | 580 | ||
581 | #ifdef CONFIG_BCMA_SFLASH | 581 | #ifdef CONFIG_BCMA_SFLASH |
582 | struct mtd_info; | ||
583 | |||
582 | struct bcma_sflash { | 584 | struct bcma_sflash { |
583 | bool present; | 585 | bool present; |
584 | u32 window; | 586 | u32 window; |
@@ -592,13 +594,9 @@ struct bcma_sflash { | |||
592 | #endif | 594 | #endif |
593 | 595 | ||
594 | #ifdef CONFIG_BCMA_NFLASH | 596 | #ifdef CONFIG_BCMA_NFLASH |
595 | struct mtd_info; | ||
596 | |||
597 | struct bcma_nflash { | 597 | struct bcma_nflash { |
598 | bool present; | 598 | bool present; |
599 | bool boot; /* This is the flash the SoC boots from */ | 599 | bool boot; /* This is the flash the SoC boots from */ |
600 | |||
601 | struct mtd_info *mtd; | ||
602 | }; | 600 | }; |
603 | #endif | 601 | #endif |
604 | 602 | ||
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h index 366cf77953b5..58f3ba709ade 100644 --- a/include/linux/mtd/map.h +++ b/include/linux/mtd/map.h | |||
@@ -142,7 +142,9 @@ | |||
142 | #endif | 142 | #endif |
143 | 143 | ||
144 | #ifndef map_bankwidth | 144 | #ifndef map_bankwidth |
145 | #ifdef CONFIG_MTD | ||
145 | #warning "No CONFIG_MTD_MAP_BANK_WIDTH_xx selected. No NOR chip support can work" | 146 | #warning "No CONFIG_MTD_MAP_BANK_WIDTH_xx selected. No NOR chip support can work" |
147 | #endif | ||
146 | static inline int map_bankwidth(void *map) | 148 | static inline int map_bankwidth(void *map) |
147 | { | 149 | { |
148 | BUG(); | 150 | BUG(); |
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index f17fa75809aa..cc84923011c0 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h | |||
@@ -254,6 +254,17 @@ struct mtd_info { | |||
254 | int usecount; | 254 | int usecount; |
255 | }; | 255 | }; |
256 | 256 | ||
257 | static inline void mtd_set_of_node(struct mtd_info *mtd, | ||
258 | struct device_node *np) | ||
259 | { | ||
260 | mtd->dev.of_node = np; | ||
261 | } | ||
262 | |||
263 | static inline struct device_node *mtd_get_of_node(struct mtd_info *mtd) | ||
264 | { | ||
265 | return mtd->dev.of_node; | ||
266 | } | ||
267 | |||
257 | int mtd_erase(struct mtd_info *mtd, struct erase_info *instr); | 268 | int mtd_erase(struct mtd_info *mtd, struct erase_info *instr); |
258 | int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, | 269 | int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, |
259 | void **virt, resource_size_t *phys); | 270 | void **virt, resource_size_t *phys); |
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 5a9d1d4c2487..bdd68e22b5a5 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h | |||
@@ -129,6 +129,14 @@ typedef enum { | |||
129 | /* Enable Hardware ECC before syndrome is read back from flash */ | 129 | /* Enable Hardware ECC before syndrome is read back from flash */ |
130 | #define NAND_ECC_READSYN 2 | 130 | #define NAND_ECC_READSYN 2 |
131 | 131 | ||
132 | /* | ||
133 | * Enable generic NAND 'page erased' check. This check is only done when | ||
134 | * ecc.correct() returns -EBADMSG. | ||
135 | * Set this flag if your implementation does not fix bitflips in erased | ||
136 | * pages and you want to rely on the default implementation. | ||
137 | */ | ||
138 | #define NAND_ECC_GENERIC_ERASED_CHECK BIT(0) | ||
139 | |||
132 | /* Bit mask for flags passed to do_nand_read_ecc */ | 140 | /* Bit mask for flags passed to do_nand_read_ecc */ |
133 | #define NAND_GET_DEVICE 0x80 | 141 | #define NAND_GET_DEVICE 0x80 |
134 | 142 | ||
@@ -276,15 +284,15 @@ struct nand_onfi_params { | |||
276 | __le16 t_r; | 284 | __le16 t_r; |
277 | __le16 t_ccs; | 285 | __le16 t_ccs; |
278 | __le16 src_sync_timing_mode; | 286 | __le16 src_sync_timing_mode; |
279 | __le16 src_ssync_features; | 287 | u8 src_ssync_features; |
280 | __le16 clk_pin_capacitance_typ; | 288 | __le16 clk_pin_capacitance_typ; |
281 | __le16 io_pin_capacitance_typ; | 289 | __le16 io_pin_capacitance_typ; |
282 | __le16 input_pin_capacitance_typ; | 290 | __le16 input_pin_capacitance_typ; |
283 | u8 input_pin_capacitance_max; | 291 | u8 input_pin_capacitance_max; |
284 | u8 driver_strength_support; | 292 | u8 driver_strength_support; |
285 | __le16 t_int_r; | 293 | __le16 t_int_r; |
286 | __le16 t_ald; | 294 | __le16 t_adl; |
287 | u8 reserved4[7]; | 295 | u8 reserved4[8]; |
288 | 296 | ||
289 | /* vendor */ | 297 | /* vendor */ |
290 | __le16 vendor_revision; | 298 | __le16 vendor_revision; |
@@ -407,7 +415,7 @@ struct nand_jedec_params { | |||
407 | __le16 input_pin_capacitance_typ; | 415 | __le16 input_pin_capacitance_typ; |
408 | __le16 clk_pin_capacitance_typ; | 416 | __le16 clk_pin_capacitance_typ; |
409 | u8 driver_strength_support; | 417 | u8 driver_strength_support; |
410 | __le16 t_ald; | 418 | __le16 t_adl; |
411 | u8 reserved4[36]; | 419 | u8 reserved4[36]; |
412 | 420 | ||
413 | /* ECC and endurance block */ | 421 | /* ECC and endurance block */ |
@@ -451,12 +459,19 @@ struct nand_hw_control { | |||
451 | * @total: total number of ECC bytes per page | 459 | * @total: total number of ECC bytes per page |
452 | * @prepad: padding information for syndrome based ECC generators | 460 | * @prepad: padding information for syndrome based ECC generators |
453 | * @postpad: padding information for syndrome based ECC generators | 461 | * @postpad: padding information for syndrome based ECC generators |
462 | * @options: ECC specific options (see NAND_ECC_XXX flags defined above) | ||
454 | * @layout: ECC layout control struct pointer | 463 | * @layout: ECC layout control struct pointer |
455 | * @priv: pointer to private ECC control data | 464 | * @priv: pointer to private ECC control data |
456 | * @hwctl: function to control hardware ECC generator. Must only | 465 | * @hwctl: function to control hardware ECC generator. Must only |
457 | * be provided if an hardware ECC is available | 466 | * be provided if an hardware ECC is available |
458 | * @calculate: function for ECC calculation or readback from ECC hardware | 467 | * @calculate: function for ECC calculation or readback from ECC hardware |
459 | * @correct: function for ECC correction, matching to ECC generator (sw/hw) | 468 | * @correct: function for ECC correction, matching to ECC generator (sw/hw). |
469 | * Should return a positive number representing the number of | ||
470 | * corrected bitflips, -EBADMSG if the number of bitflips exceed | ||
471 | * ECC strength, or any other error code if the error is not | ||
472 | * directly related to correction. | ||
473 | * If -EBADMSG is returned the input buffers should be left | ||
474 | * untouched. | ||
460 | * @read_page_raw: function to read a raw page without ECC. This function | 475 | * @read_page_raw: function to read a raw page without ECC. This function |
461 | * should hide the specific layout used by the ECC | 476 | * should hide the specific layout used by the ECC |
462 | * controller and always return contiguous in-band and | 477 | * controller and always return contiguous in-band and |
@@ -494,6 +509,7 @@ struct nand_ecc_ctrl { | |||
494 | int strength; | 509 | int strength; |
495 | int prepad; | 510 | int prepad; |
496 | int postpad; | 511 | int postpad; |
512 | unsigned int options; | ||
497 | struct nand_ecclayout *layout; | 513 | struct nand_ecclayout *layout; |
498 | void *priv; | 514 | void *priv; |
499 | void (*hwctl)(struct mtd_info *mtd, int mode); | 515 | void (*hwctl)(struct mtd_info *mtd, int mode); |
@@ -540,11 +556,11 @@ struct nand_buffers { | |||
540 | 556 | ||
541 | /** | 557 | /** |
542 | * struct nand_chip - NAND Private Flash Chip Data | 558 | * struct nand_chip - NAND Private Flash Chip Data |
559 | * @mtd: MTD device registered to the MTD framework | ||
543 | * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the | 560 | * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the |
544 | * flash device | 561 | * flash device |
545 | * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the | 562 | * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the |
546 | * flash device. | 563 | * flash device. |
547 | * @flash_node: [BOARDSPECIFIC] device node describing this instance | ||
548 | * @read_byte: [REPLACEABLE] read one byte from the chip | 564 | * @read_byte: [REPLACEABLE] read one byte from the chip |
549 | * @read_word: [REPLACEABLE] read one word from the chip | 565 | * @read_word: [REPLACEABLE] read one word from the chip |
550 | * @write_byte: [REPLACEABLE] write a single byte to the chip on the | 566 | * @write_byte: [REPLACEABLE] write a single byte to the chip on the |
@@ -640,11 +656,10 @@ struct nand_buffers { | |||
640 | */ | 656 | */ |
641 | 657 | ||
642 | struct nand_chip { | 658 | struct nand_chip { |
659 | struct mtd_info mtd; | ||
643 | void __iomem *IO_ADDR_R; | 660 | void __iomem *IO_ADDR_R; |
644 | void __iomem *IO_ADDR_W; | 661 | void __iomem *IO_ADDR_W; |
645 | 662 | ||
646 | struct device_node *flash_node; | ||
647 | |||
648 | uint8_t (*read_byte)(struct mtd_info *mtd); | 663 | uint8_t (*read_byte)(struct mtd_info *mtd); |
649 | u16 (*read_word)(struct mtd_info *mtd); | 664 | u16 (*read_word)(struct mtd_info *mtd); |
650 | void (*write_byte)(struct mtd_info *mtd, uint8_t byte); | 665 | void (*write_byte)(struct mtd_info *mtd, uint8_t byte); |
@@ -719,6 +734,37 @@ struct nand_chip { | |||
719 | void *priv; | 734 | void *priv; |
720 | }; | 735 | }; |
721 | 736 | ||
737 | static inline void nand_set_flash_node(struct nand_chip *chip, | ||
738 | struct device_node *np) | ||
739 | { | ||
740 | mtd_set_of_node(&chip->mtd, np); | ||
741 | } | ||
742 | |||
743 | static inline struct device_node *nand_get_flash_node(struct nand_chip *chip) | ||
744 | { | ||
745 | return mtd_get_of_node(&chip->mtd); | ||
746 | } | ||
747 | |||
748 | static inline struct nand_chip *mtd_to_nand(struct mtd_info *mtd) | ||
749 | { | ||
750 | return container_of(mtd, struct nand_chip, mtd); | ||
751 | } | ||
752 | |||
753 | static inline struct mtd_info *nand_to_mtd(struct nand_chip *chip) | ||
754 | { | ||
755 | return &chip->mtd; | ||
756 | } | ||
757 | |||
758 | static inline void *nand_get_controller_data(struct nand_chip *chip) | ||
759 | { | ||
760 | return chip->priv; | ||
761 | } | ||
762 | |||
763 | static inline void nand_set_controller_data(struct nand_chip *chip, void *priv) | ||
764 | { | ||
765 | chip->priv = priv; | ||
766 | } | ||
767 | |||
722 | /* | 768 | /* |
723 | * NAND Flash Manufacturer ID Codes | 769 | * NAND Flash Manufacturer ID Codes |
724 | */ | 770 | */ |
@@ -907,15 +953,6 @@ struct platform_nand_data { | |||
907 | struct platform_nand_ctrl ctrl; | 953 | struct platform_nand_ctrl ctrl; |
908 | }; | 954 | }; |
909 | 955 | ||
910 | /* Some helpers to access the data structures */ | ||
911 | static inline | ||
912 | struct platform_nand_chip *get_platform_nandchip(struct mtd_info *mtd) | ||
913 | { | ||
914 | struct nand_chip *chip = mtd->priv; | ||
915 | |||
916 | return chip->priv; | ||
917 | } | ||
918 | |||
919 | /* return the supported features. */ | 956 | /* return the supported features. */ |
920 | static inline int onfi_feature(struct nand_chip *chip) | 957 | static inline int onfi_feature(struct nand_chip *chip) |
921 | { | 958 | { |
diff --git a/include/linux/mtd/nand_bch.h b/include/linux/mtd/nand_bch.h index 74acf5367556..fb0bc3420a10 100644 --- a/include/linux/mtd/nand_bch.h +++ b/include/linux/mtd/nand_bch.h | |||
@@ -55,7 +55,7 @@ static inline int | |||
55 | nand_bch_correct_data(struct mtd_info *mtd, unsigned char *buf, | 55 | nand_bch_correct_data(struct mtd_info *mtd, unsigned char *buf, |
56 | unsigned char *read_ecc, unsigned char *calc_ecc) | 56 | unsigned char *read_ecc, unsigned char *calc_ecc) |
57 | { | 57 | { |
58 | return -1; | 58 | return -ENOTSUPP; |
59 | } | 59 | } |
60 | 60 | ||
61 | static inline struct nand_bch_control * | 61 | static inline struct nand_bch_control * |
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index 6a35e6de5da1..70736e1e6c8f 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h | |||
@@ -41,7 +41,6 @@ struct mtd_partition { | |||
41 | uint64_t size; /* partition size */ | 41 | uint64_t size; /* partition size */ |
42 | uint64_t offset; /* offset within the master MTD space */ | 42 | uint64_t offset; /* offset within the master MTD space */ |
43 | uint32_t mask_flags; /* master MTD flags to mask out for this partition */ | 43 | uint32_t mask_flags; /* master MTD flags to mask out for this partition */ |
44 | struct nand_ecclayout *ecclayout; /* out of band layout for this partition (NAND only) */ | ||
45 | }; | 44 | }; |
46 | 45 | ||
47 | #define MTDPART_OFS_RETAIN (-3) | 46 | #define MTDPART_OFS_RETAIN (-3) |
@@ -56,11 +55,9 @@ struct device_node; | |||
56 | /** | 55 | /** |
57 | * struct mtd_part_parser_data - used to pass data to MTD partition parsers. | 56 | * struct mtd_part_parser_data - used to pass data to MTD partition parsers. |
58 | * @origin: for RedBoot, start address of MTD device | 57 | * @origin: for RedBoot, start address of MTD device |
59 | * @of_node: for OF parsers, device node containing partitioning information | ||
60 | */ | 58 | */ |
61 | struct mtd_part_parser_data { | 59 | struct mtd_part_parser_data { |
62 | unsigned long origin; | 60 | unsigned long origin; |
63 | struct device_node *of_node; | ||
64 | }; | 61 | }; |
65 | 62 | ||
66 | 63 | ||
@@ -72,13 +69,33 @@ struct mtd_part_parser { | |||
72 | struct list_head list; | 69 | struct list_head list; |
73 | struct module *owner; | 70 | struct module *owner; |
74 | const char *name; | 71 | const char *name; |
75 | int (*parse_fn)(struct mtd_info *, struct mtd_partition **, | 72 | int (*parse_fn)(struct mtd_info *, const struct mtd_partition **, |
76 | struct mtd_part_parser_data *); | 73 | struct mtd_part_parser_data *); |
74 | void (*cleanup)(const struct mtd_partition *pparts, int nr_parts); | ||
77 | }; | 75 | }; |
78 | 76 | ||
79 | extern void register_mtd_parser(struct mtd_part_parser *parser); | 77 | /* Container for passing around a set of parsed partitions */ |
78 | struct mtd_partitions { | ||
79 | const struct mtd_partition *parts; | ||
80 | int nr_parts; | ||
81 | const struct mtd_part_parser *parser; | ||
82 | }; | ||
83 | |||
84 | extern int __register_mtd_parser(struct mtd_part_parser *parser, | ||
85 | struct module *owner); | ||
86 | #define register_mtd_parser(parser) __register_mtd_parser(parser, THIS_MODULE) | ||
87 | |||
80 | extern void deregister_mtd_parser(struct mtd_part_parser *parser); | 88 | extern void deregister_mtd_parser(struct mtd_part_parser *parser); |
81 | 89 | ||
90 | /* | ||
91 | * module_mtd_part_parser() - Helper macro for MTD partition parsers that don't | ||
92 | * do anything special in module init/exit. Each driver may only use this macro | ||
93 | * once, and calling it replaces module_init() and module_exit(). | ||
94 | */ | ||
95 | #define module_mtd_part_parser(__mtd_part_parser) \ | ||
96 | module_driver(__mtd_part_parser, register_mtd_parser, \ | ||
97 | deregister_mtd_parser) | ||
98 | |||
82 | int mtd_is_partition(const struct mtd_info *mtd); | 99 | int mtd_is_partition(const struct mtd_info *mtd); |
83 | int mtd_add_partition(struct mtd_info *master, const char *name, | 100 | int mtd_add_partition(struct mtd_info *master, const char *name, |
84 | long long offset, long long length); | 101 | long long offset, long long length); |
diff --git a/include/linux/mtd/sh_flctl.h b/include/linux/mtd/sh_flctl.h index 1c28f8879b1c..2251add65fa7 100644 --- a/include/linux/mtd/sh_flctl.h +++ b/include/linux/mtd/sh_flctl.h | |||
@@ -143,11 +143,11 @@ enum flctl_ecc_res_t { | |||
143 | struct dma_chan; | 143 | struct dma_chan; |
144 | 144 | ||
145 | struct sh_flctl { | 145 | struct sh_flctl { |
146 | struct mtd_info mtd; | ||
147 | struct nand_chip chip; | 146 | struct nand_chip chip; |
148 | struct platform_device *pdev; | 147 | struct platform_device *pdev; |
149 | struct dev_pm_qos_request pm_qos; | 148 | struct dev_pm_qos_request pm_qos; |
150 | void __iomem *reg; | 149 | void __iomem *reg; |
150 | resource_size_t fifo; | ||
151 | 151 | ||
152 | uint8_t done_buff[2048 + 64]; /* max size 2048 + 64 */ | 152 | uint8_t done_buff[2048 + 64]; /* max size 2048 + 64 */ |
153 | int read_bytes; | 153 | int read_bytes; |
@@ -186,7 +186,7 @@ struct sh_flctl_platform_data { | |||
186 | 186 | ||
187 | static inline struct sh_flctl *mtd_to_flctl(struct mtd_info *mtdinfo) | 187 | static inline struct sh_flctl *mtd_to_flctl(struct mtd_info *mtdinfo) |
188 | { | 188 | { |
189 | return container_of(mtdinfo, struct sh_flctl, mtd); | 189 | return container_of(mtd_to_nand(mtdinfo), struct sh_flctl, chip); |
190 | } | 190 | } |
191 | 191 | ||
192 | #endif /* __SH_FLCTL_H__ */ | 192 | #endif /* __SH_FLCTL_H__ */ |
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index bc742dac7d3a..62356d50815b 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h | |||
@@ -12,6 +12,7 @@ | |||
12 | 12 | ||
13 | #include <linux/bitops.h> | 13 | #include <linux/bitops.h> |
14 | #include <linux/mtd/cfi.h> | 14 | #include <linux/mtd/cfi.h> |
15 | #include <linux/mtd/mtd.h> | ||
15 | 16 | ||
16 | /* | 17 | /* |
17 | * Manufacturer IDs | 18 | * Manufacturer IDs |
@@ -117,14 +118,11 @@ enum spi_nor_option_flags { | |||
117 | SNOR_F_USE_FSR = BIT(0), | 118 | SNOR_F_USE_FSR = BIT(0), |
118 | }; | 119 | }; |
119 | 120 | ||
120 | struct mtd_info; | ||
121 | |||
122 | /** | 121 | /** |
123 | * struct spi_nor - Structure for defining a the SPI NOR layer | 122 | * struct spi_nor - Structure for defining a the SPI NOR layer |
124 | * @mtd: point to a mtd_info structure | 123 | * @mtd: point to a mtd_info structure |
125 | * @lock: the lock for the read/write/erase/lock/unlock operations | 124 | * @lock: the lock for the read/write/erase/lock/unlock operations |
126 | * @dev: point to a spi device, or a spi nor controller device. | 125 | * @dev: point to a spi device, or a spi nor controller device. |
127 | * @flash_node: point to a device node describing this flash instance. | ||
128 | * @page_size: the page size of the SPI NOR | 126 | * @page_size: the page size of the SPI NOR |
129 | * @addr_width: number of address bytes | 127 | * @addr_width: number of address bytes |
130 | * @erase_opcode: the opcode for erasing a sector | 128 | * @erase_opcode: the opcode for erasing a sector |
@@ -144,7 +142,8 @@ struct mtd_info; | |||
144 | * @read: [DRIVER-SPECIFIC] read data from the SPI NOR | 142 | * @read: [DRIVER-SPECIFIC] read data from the SPI NOR |
145 | * @write: [DRIVER-SPECIFIC] write data to the SPI NOR | 143 | * @write: [DRIVER-SPECIFIC] write data to the SPI NOR |
146 | * @erase: [DRIVER-SPECIFIC] erase a sector of the SPI NOR | 144 | * @erase: [DRIVER-SPECIFIC] erase a sector of the SPI NOR |
147 | * at the offset @offs | 145 | * at the offset @offs; if not provided by the driver, |
146 | * spi-nor will send the erase opcode via write_reg() | ||
148 | * @flash_lock: [FLASH-SPECIFIC] lock a region of the SPI NOR | 147 | * @flash_lock: [FLASH-SPECIFIC] lock a region of the SPI NOR |
149 | * @flash_unlock: [FLASH-SPECIFIC] unlock a region of the SPI NOR | 148 | * @flash_unlock: [FLASH-SPECIFIC] unlock a region of the SPI NOR |
150 | * @flash_is_locked: [FLASH-SPECIFIC] check if a region of the SPI NOR is | 149 | * @flash_is_locked: [FLASH-SPECIFIC] check if a region of the SPI NOR is |
@@ -155,7 +154,6 @@ struct spi_nor { | |||
155 | struct mtd_info mtd; | 154 | struct mtd_info mtd; |
156 | struct mutex lock; | 155 | struct mutex lock; |
157 | struct device *dev; | 156 | struct device *dev; |
158 | struct device_node *flash_node; | ||
159 | u32 page_size; | 157 | u32 page_size; |
160 | u8 addr_width; | 158 | u8 addr_width; |
161 | u8 erase_opcode; | 159 | u8 erase_opcode; |
@@ -185,6 +183,17 @@ struct spi_nor { | |||
185 | void *priv; | 183 | void *priv; |
186 | }; | 184 | }; |
187 | 185 | ||
186 | static inline void spi_nor_set_flash_node(struct spi_nor *nor, | ||
187 | struct device_node *np) | ||
188 | { | ||
189 | mtd_set_of_node(&nor->mtd, np); | ||
190 | } | ||
191 | |||
192 | static inline struct device_node *spi_nor_get_flash_node(struct spi_nor *nor) | ||
193 | { | ||
194 | return mtd_get_of_node(&nor->mtd); | ||
195 | } | ||
196 | |||
188 | /** | 197 | /** |
189 | * spi_nor_scan() - scan the SPI NOR | 198 | * spi_nor_scan() - scan the SPI NOR |
190 | * @nor: the spi_nor structure | 199 | * @nor: the spi_nor structure |