diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-08 13:39:20 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-08 13:39:20 -0400 |
commit | f4e70c2e5f1406e715f6359ae341e76e5004fb98 (patch) | |
tree | 79622d866d0cb8bdb494718e11d458770aee9713 | |
parent | ea125dedbc14b305307889c40d74d564c4419851 (diff) | |
parent | b771327a4530e7ff05ae173d4903cd70357bb803 (diff) |
Merge tag 'mtd/for-4.18' of git://git.infradead.org/linux-mtd
Pull MTD updates from Boris Brezillon:
"Core changes:
- Add a sysfs attribute to expose available OOB size
Driver changes:
- Remove HAS_DMA dependency on various drivers
- Use dev_get_drvdata() instead of platform_get_drvdata() in docg3
- Replace msleep by usleep_range() in the dataflash driver
- Avoid VLA usage in nftl layers
- Remove useless .owner assignment in pismo
- Fix various issues in the CFI driver
- Improve TRX partition handling expose a DT compat for this part
parser
- Clarify OFFSET_CONTINUOUS meaning
NAND core changes:
- Add Miquel as a NAND maintainer
- Add access mode to the nand_page_io_req struct
- Fix kernel-doc in rawnand.h
- Support bit-wise majority to recover from corrupted ONFI parameter
pages
- Stop checking FAIL bit after a SET_FEATURES, as documented in the
ONFI spec
Raw NAND Driver changes:
- Fix and cleanup the error path of many NAND controller drivers
- GPMI:
+ Cleanup/simplification of a few aspects in the driver
+ Take ECC setup specified in the DT into account
- sunxi: remove support for GPIO-based R/B polling
- MTK:
+ Use of_device_get_match_data() instead of of_match_device()
+ Add an entry in MAINTAINERS for this driver
+ Fix nand-ecc-step-size and nand-ecc-strength description in the
DT bindings doc
- fsl_ifc: fix ->cmdfunc() to read more than one ONFI parameter page
OneNAND driver changes:
- samsung: use dev_get_drvdata() instead of platform_get_drvdata()
SPI NOR core changes:
- Add support for a bunch of SPI NOR chips
- Clear EAR reg when switching to 3-byte addressing mode on Winbond
chips
SPI NOR controller driver changes:
- cadence: Add DMA support for direct mode reads
- hisi: Prefix a few functions with hisi_
- intel:
+ Mark the driver as "dangerous" in Kconfig
+ Fix atomic sequence handling
+ Pass a 40us delay (instead of 0us) to readl_poll_timeout()
- fsl:
+ fix a typo in a function name
+ add support for IP variants embedded in the ls2080a and ls1080a
SoCs
- stm32: request exclusive control of the reset line"
* tag 'mtd/for-4.18' of git://git.infradead.org/linux-mtd: (66 commits)
mtd: nand: Pass mode information to nand_page_io_req
mtd: cfi_cmdset_0002: Change erase one block to enable XIP once
mtd: cfi_cmdset_0002: Change erase functions to check chip good only
mtd: cfi_cmdset_0002: Change erase functions to retry for error
mtd: cfi_cmdset_0002: Change definition naming to retry write operation
mtd: cfi_cmdset_0002: Change write buffer to check correct value
mtd: cmdlinepart: Update comment for introduction of OFFSET_CONTINUOUS
mtd: bcm47xxpart: add of_match_table with a new DT binding
dt-bindings: mtd: document Broadcom's BCM47xx partitions
mtd: spi-nor: Add support for EN25QH32
mtd: spi-nor: Add support for is25wp series chips
mtd: spi-nor: Add Winbond w25q32jv support
mtd: spi-nor: fsl-quadspi: add support for ls2080a/ls1080a
mtd: spi-nor: stm32-quadspi: explicitly request exclusive reset control
mtd: spi-nor: intel: provide a range for poll_timout
mtd: spi-nor: fsl-quadspi: fix api naming typo _init_ahb_read
mtd: spi-nor: intel-spi: Explicitly mark the driver as dangerous in Kconfig
mtd: spi-nor: intel-spi: Fix atomic sequence handling
mtd: rawnand: Do not check FAIL bit when executing a SET_FEATURES op
mtd: rawnand: use bit-wise majority to recover the ONFI param page
...
46 files changed, 773 insertions, 536 deletions
diff --git a/Documentation/ABI/testing/sysfs-class-mtd b/Documentation/ABI/testing/sysfs-class-mtd index f34e592301d1..3bc7c0a95c92 100644 --- a/Documentation/ABI/testing/sysfs-class-mtd +++ b/Documentation/ABI/testing/sysfs-class-mtd | |||
@@ -232,3 +232,11 @@ Description: | |||
232 | of the parent (another partition or a flash device) in bytes. | 232 | of the parent (another partition or a flash device) in bytes. |
233 | This attribute is absent on flash devices, so it can be used | 233 | This attribute is absent on flash devices, so it can be used |
234 | to distinguish them from partitions. | 234 | to distinguish them from partitions. |
235 | |||
236 | What: /sys/class/mtd/mtdX/oobavail | ||
237 | Date: April 2018 | ||
238 | KernelVersion: 4.16 | ||
239 | Contact: linux-mtd@lists.infradead.org | ||
240 | Description: | ||
241 | Number of bytes available for a client to place data into | ||
242 | the out of band area. | ||
diff --git a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt index b289ef3c1b7e..393588385c6e 100644 --- a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt +++ b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt | |||
@@ -47,6 +47,11 @@ Optional properties: | |||
47 | partitions written from Linux with this feature | 47 | partitions written from Linux with this feature |
48 | turned on may not be accessible by the BootROM | 48 | turned on may not be accessible by the BootROM |
49 | code. | 49 | code. |
50 | - nand-ecc-strength: integer representing the number of bits to correct | ||
51 | per ECC step. Needs to be a multiple of 2. | ||
52 | - nand-ecc-step-size: integer representing the number of data bytes | ||
53 | that are covered by a single ECC step. The driver | ||
54 | supports 512 and 1024. | ||
50 | 55 | ||
51 | The device tree may optionally contain sub-nodes describing partitions of the | 56 | The device tree may optionally contain sub-nodes describing partitions of the |
52 | address space. See partition.txt for more detail. | 57 | address space. See partition.txt for more detail. |
diff --git a/Documentation/devicetree/bindings/mtd/mtk-nand.txt b/Documentation/devicetree/bindings/mtd/mtk-nand.txt index c5ba6a4ba1f2..4d3ec5e4ff8a 100644 --- a/Documentation/devicetree/bindings/mtd/mtk-nand.txt +++ b/Documentation/devicetree/bindings/mtd/mtk-nand.txt | |||
@@ -48,14 +48,19 @@ Optional: | |||
48 | - nand-on-flash-bbt: Store BBT on NAND Flash. | 48 | - nand-on-flash-bbt: Store BBT on NAND Flash. |
49 | - nand-ecc-mode: the NAND ecc mode (check driver for supported modes) | 49 | - nand-ecc-mode: the NAND ecc mode (check driver for supported modes) |
50 | - nand-ecc-step-size: Number of data bytes covered by a single ECC step. | 50 | - nand-ecc-step-size: Number of data bytes covered by a single ECC step. |
51 | valid values: 512 and 1024. | 51 | valid values: |
52 | 512 and 1024 on mt2701 and mt2712. | ||
53 | 512 only on mt7622. | ||
52 | 1024 is recommended for large page NANDs. | 54 | 1024 is recommended for large page NANDs. |
53 | - nand-ecc-strength: Number of bits to correct per ECC step. | 55 | - nand-ecc-strength: Number of bits to correct per ECC step. |
54 | The valid values that the controller supports are: 4, 6, | 56 | The valid values that each controller supports: |
55 | 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, 32, 36, 40, 44, | 57 | mt2701: 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, |
56 | 48, 52, 56, 60. | 58 | 32, 36, 40, 44, 48, 52, 56, 60. |
59 | mt2712: 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 28, | ||
60 | 32, 36, 40, 44, 48, 52, 56, 60, 68, 72, 80. | ||
61 | mt7622: 4, 6, 8, 10, 12, 14, 16. | ||
57 | The strength should be calculated as follows: | 62 | The strength should be calculated as follows: |
58 | E = (S - F) * 8 / 14 | 63 | E = (S - F) * 8 / B |
59 | S = O / (P / Q) | 64 | S = O / (P / Q) |
60 | E : nand-ecc-strength. | 65 | E : nand-ecc-strength. |
61 | S : spare size per sector. | 66 | S : spare size per sector. |
@@ -64,6 +69,15 @@ Optional: | |||
64 | O : oob size. | 69 | O : oob size. |
65 | P : page size. | 70 | P : page size. |
66 | Q : nand-ecc-step-size. | 71 | Q : nand-ecc-step-size. |
72 | B : number of parity bits needed to correct | ||
73 | 1 bitflip. | ||
74 | According to MTK NAND controller design, | ||
75 | this number depends on max ecc step size | ||
76 | that MTK NAND controller supports. | ||
77 | If max ecc step size supported is 1024, | ||
78 | then it should be always 14. And if max | ||
79 | ecc step size is 512, then it should be | ||
80 | always 13. | ||
67 | If the result does not match any one of the listed | 81 | If the result does not match any one of the listed |
68 | choices above, please select the smaller valid value from | 82 | choices above, please select the smaller valid value from |
69 | the list. | 83 | the list. |
diff --git a/Documentation/devicetree/bindings/mtd/partition.txt b/Documentation/devicetree/bindings/mtd/partition.txt index 36f3b769a626..a8f382642ba9 100644 --- a/Documentation/devicetree/bindings/mtd/partition.txt +++ b/Documentation/devicetree/bindings/mtd/partition.txt | |||
@@ -14,7 +14,7 @@ method is used for a given flash device. To describe the method there should be | |||
14 | a subnode of the flash device that is named 'partitions'. It must have a | 14 | a subnode of the flash device that is named 'partitions'. It must have a |
15 | 'compatible' property, which is used to identify the method to use. | 15 | 'compatible' property, which is used to identify the method to use. |
16 | 16 | ||
17 | We currently only document a binding for fixed layouts. | 17 | Available bindings are listed in the "partitions" subdirectory. |
18 | 18 | ||
19 | 19 | ||
20 | Fixed Partitions | 20 | Fixed Partitions |
diff --git a/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm947xx-cfe-partitions.txt b/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm947xx-cfe-partitions.txt new file mode 100644 index 000000000000..1d61a029395e --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/partitions/brcm,bcm947xx-cfe-partitions.txt | |||
@@ -0,0 +1,42 @@ | |||
1 | Broadcom BCM47xx Partitions | ||
2 | =========================== | ||
3 | |||
4 | Broadcom is one of hardware manufacturers providing SoCs (BCM47xx) used in | ||
5 | home routers. Their BCM947xx boards using CFE bootloader have several partitions | ||
6 | without any on-flash partition table. On some devices their sizes and/or | ||
7 | meanings can also vary so fixed partitioning can't be used. | ||
8 | |||
9 | Discovering partitions on these devices is possible thanks to having a special | ||
10 | header and/or magic signature at the beginning of each of them. They are also | ||
11 | block aligned which is important for determinig a size. | ||
12 | |||
13 | Most of partitions use ASCII text based magic for determining a type. More | ||
14 | complex partitions (like TRX with its HDR0 magic) may include extra header | ||
15 | containing some details, including a length. | ||
16 | |||
17 | A list of supported partitions includes: | ||
18 | 1) Bootloader with Broadcom's CFE (Common Firmware Environment) | ||
19 | 2) NVRAM with configuration/calibration data | ||
20 | 3) Device manufacturer's data with some default values (e.g. SSIDs) | ||
21 | 4) TRX firmware container which can hold up to 4 subpartitions | ||
22 | 5) Backup TRX firmware used after failed upgrade | ||
23 | |||
24 | As mentioned earlier, role of some partitions may depend on extra configuration. | ||
25 | For example both: main firmware and backup firmware use the same TRX format with | ||
26 | the same header. To distinguish currently used firmware a CFE's environment | ||
27 | variable "bootpartition" is used. | ||
28 | |||
29 | |||
30 | Devices using Broadcom partitions described above should should have flash node | ||
31 | with a subnode named "partitions" using following properties: | ||
32 | |||
33 | Required properties: | ||
34 | - compatible : (required) must be "brcm,bcm947xx-cfe-partitions" | ||
35 | |||
36 | Example: | ||
37 | |||
38 | flash@0 { | ||
39 | partitions { | ||
40 | compatible = "brcm,bcm947xx-cfe-partitions"; | ||
41 | }; | ||
42 | }; | ||
diff --git a/Documentation/devicetree/bindings/mtd/sunxi-nand.txt b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt index 0734f03bf3d3..dcd5a5d80dc0 100644 --- a/Documentation/devicetree/bindings/mtd/sunxi-nand.txt +++ b/Documentation/devicetree/bindings/mtd/sunxi-nand.txt | |||
@@ -22,8 +22,6 @@ Optional properties: | |||
22 | - reset : phandle + reset specifier pair | 22 | - reset : phandle + reset specifier pair |
23 | - reset-names : must contain "ahb" | 23 | - reset-names : must contain "ahb" |
24 | - allwinner,rb : shall contain the native Ready/Busy ids. | 24 | - allwinner,rb : shall contain the native Ready/Busy ids. |
25 | or | ||
26 | - rb-gpios : shall contain the gpios used as R/B pins. | ||
27 | - nand-ecc-mode : one of the supported ECC modes ("hw", "soft", "soft_bch" or | 25 | - nand-ecc-mode : one of the supported ECC modes ("hw", "soft", "soft_bch" or |
28 | "none") | 26 | "none") |
29 | 27 | ||
diff --git a/MAINTAINERS b/MAINTAINERS index c9ac159fb023..3838c94a0d47 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -9022,6 +9022,13 @@ L: linux-wireless@vger.kernel.org | |||
9022 | S: Maintained | 9022 | S: Maintained |
9023 | F: drivers/net/wireless/mediatek/mt7601u/ | 9023 | F: drivers/net/wireless/mediatek/mt7601u/ |
9024 | 9024 | ||
9025 | MEDIATEK NAND CONTROLLER DRIVER | ||
9026 | M: Xiaolei Li <xiaolei.li@mediatek.com> | ||
9027 | L: linux-mtd@lists.infradead.org | ||
9028 | S: Maintained | ||
9029 | F: drivers/mtd/nand/raw/mtk_* | ||
9030 | F: Documentation/devicetree/bindings/mtd/mtk-nand.txt | ||
9031 | |||
9025 | MEDIATEK RANDOM NUMBER GENERATOR SUPPORT | 9032 | MEDIATEK RANDOM NUMBER GENERATOR SUPPORT |
9026 | M: Sean Wang <sean.wang@mediatek.com> | 9033 | M: Sean Wang <sean.wang@mediatek.com> |
9027 | S: Maintained | 9034 | S: Maintained |
@@ -9666,6 +9673,7 @@ F: drivers/net/ethernet/myricom/myri10ge/ | |||
9666 | 9673 | ||
9667 | NAND FLASH SUBSYSTEM | 9674 | NAND FLASH SUBSYSTEM |
9668 | M: Boris Brezillon <boris.brezillon@bootlin.com> | 9675 | M: Boris Brezillon <boris.brezillon@bootlin.com> |
9676 | M: Miquel Raynal <miquel.raynal@bootlin.com> | ||
9669 | R: Richard Weinberger <richard@nod.at> | 9677 | R: Richard Weinberger <richard@nod.at> |
9670 | L: linux-mtd@lists.infradead.org | 9678 | L: linux-mtd@lists.infradead.org |
9671 | W: http://www.linux-mtd.infradead.org/ | 9679 | W: http://www.linux-mtd.infradead.org/ |
diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c index fe2581d9d882..0f93d2239352 100644 --- a/drivers/mtd/bcm47xxpart.c +++ b/drivers/mtd/bcm47xxpart.c | |||
@@ -186,6 +186,8 @@ static int bcm47xxpart_parse(struct mtd_info *master, | |||
186 | /* TRX */ | 186 | /* TRX */ |
187 | if (buf[0x000 / 4] == TRX_MAGIC) { | 187 | if (buf[0x000 / 4] == TRX_MAGIC) { |
188 | struct trx_header *trx; | 188 | struct trx_header *trx; |
189 | uint32_t last_subpart; | ||
190 | uint32_t trx_size; | ||
189 | 191 | ||
190 | if (trx_num >= ARRAY_SIZE(trx_parts)) | 192 | if (trx_num >= ARRAY_SIZE(trx_parts)) |
191 | pr_warn("No enough space to store another TRX found at 0x%X\n", | 193 | pr_warn("No enough space to store another TRX found at 0x%X\n", |
@@ -195,11 +197,23 @@ static int bcm47xxpart_parse(struct mtd_info *master, | |||
195 | bcm47xxpart_add_part(&parts[curr_part++], "firmware", | 197 | bcm47xxpart_add_part(&parts[curr_part++], "firmware", |
196 | offset, 0); | 198 | offset, 0); |
197 | 199 | ||
198 | /* Jump to the end of TRX */ | 200 | /* |
201 | * Try to find TRX size. The "length" field isn't fully | ||
202 | * reliable as it could be decreased to make CRC32 cover | ||
203 | * only part of TRX data. It's commonly used as checksum | ||
204 | * can't cover e.g. ever-changing rootfs partition. | ||
205 | * Use offsets as helpers for assuming min TRX size. | ||
206 | */ | ||
199 | trx = (struct trx_header *)buf; | 207 | trx = (struct trx_header *)buf; |
200 | offset = roundup(offset + trx->length, blocksize); | 208 | last_subpart = max3(trx->offset[0], trx->offset[1], |
201 | /* Next loop iteration will increase the offset */ | 209 | trx->offset[2]); |
202 | offset -= blocksize; | 210 | trx_size = max(trx->length, last_subpart + blocksize); |
211 | |||
212 | /* | ||
213 | * Skip the TRX data. Decrease offset by block size as | ||
214 | * the next loop iteration will increase it. | ||
215 | */ | ||
216 | offset += roundup(trx_size, blocksize) - blocksize; | ||
203 | continue; | 217 | continue; |
204 | } | 218 | } |
205 | 219 | ||
@@ -290,9 +304,16 @@ static int bcm47xxpart_parse(struct mtd_info *master, | |||
290 | return curr_part; | 304 | return curr_part; |
291 | }; | 305 | }; |
292 | 306 | ||
307 | static const struct of_device_id bcm47xxpart_of_match_table[] = { | ||
308 | { .compatible = "brcm,bcm947xx-cfe-partitions" }, | ||
309 | {}, | ||
310 | }; | ||
311 | MODULE_DEVICE_TABLE(of, bcm47xxpart_of_match_table); | ||
312 | |||
293 | static struct mtd_part_parser bcm47xxpart_mtd_parser = { | 313 | static struct mtd_part_parser bcm47xxpart_mtd_parser = { |
294 | .parse_fn = bcm47xxpart_parse, | 314 | .parse_fn = bcm47xxpart_parse, |
295 | .name = "bcm47xxpart", | 315 | .name = "bcm47xxpart", |
316 | .of_match_table = bcm47xxpart_of_match_table, | ||
296 | }; | 317 | }; |
297 | module_mtd_part_parser(bcm47xxpart_mtd_parser); | 318 | module_mtd_part_parser(bcm47xxpart_mtd_parser); |
298 | 319 | ||
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 692902df2598..7c889eca9ab0 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c | |||
@@ -42,10 +42,10 @@ | |||
42 | #define AMD_BOOTLOC_BUG | 42 | #define AMD_BOOTLOC_BUG |
43 | #define FORCE_WORD_WRITE 0 | 43 | #define FORCE_WORD_WRITE 0 |
44 | 44 | ||
45 | #define MAX_WORD_RETRIES 3 | 45 | #define MAX_RETRIES 3 |
46 | 46 | ||
47 | #define SST49LF004B 0x0060 | 47 | #define SST49LF004B 0x0060 |
48 | #define SST49LF040B 0x0050 | 48 | #define SST49LF040B 0x0050 |
49 | #define SST49LF008A 0x005a | 49 | #define SST49LF008A 0x005a |
50 | #define AT49BV6416 0x00d6 | 50 | #define AT49BV6416 0x00d6 |
51 | 51 | ||
@@ -207,7 +207,7 @@ static void fixup_use_write_buffers(struct mtd_info *mtd) | |||
207 | struct map_info *map = mtd->priv; | 207 | struct map_info *map = mtd->priv; |
208 | struct cfi_private *cfi = map->fldrv_priv; | 208 | struct cfi_private *cfi = map->fldrv_priv; |
209 | if (cfi->cfiq->BufWriteTimeoutTyp) { | 209 | if (cfi->cfiq->BufWriteTimeoutTyp) { |
210 | pr_debug("Using buffer write method\n" ); | 210 | pr_debug("Using buffer write method\n"); |
211 | mtd->_write = cfi_amdstd_write_buffers; | 211 | mtd->_write = cfi_amdstd_write_buffers; |
212 | } | 212 | } |
213 | } | 213 | } |
@@ -1563,7 +1563,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip, | |||
1563 | * depending of the conditions. The ' + 1' is to avoid having a | 1563 | * depending of the conditions. The ' + 1' is to avoid having a |
1564 | * timeout of 0 jiffies if HZ is smaller than 1000. | 1564 | * timeout of 0 jiffies if HZ is smaller than 1000. |
1565 | */ | 1565 | */ |
1566 | unsigned long uWriteTimeout = ( HZ / 1000 ) + 1; | 1566 | unsigned long uWriteTimeout = (HZ / 1000) + 1; |
1567 | int ret = 0; | 1567 | int ret = 0; |
1568 | map_word oldd; | 1568 | map_word oldd; |
1569 | int retry_cnt = 0; | 1569 | int retry_cnt = 0; |
@@ -1578,7 +1578,7 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip, | |||
1578 | } | 1578 | } |
1579 | 1579 | ||
1580 | pr_debug("MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n", | 1580 | pr_debug("MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n", |
1581 | __func__, adr, datum.x[0] ); | 1581 | __func__, adr, datum.x[0]); |
1582 | 1582 | ||
1583 | if (mode == FL_OTP_WRITE) | 1583 | if (mode == FL_OTP_WRITE) |
1584 | otp_enter(map, chip, adr, map_bankwidth(map)); | 1584 | otp_enter(map, chip, adr, map_bankwidth(map)); |
@@ -1644,10 +1644,10 @@ static int __xipram do_write_oneword(struct map_info *map, struct flchip *chip, | |||
1644 | /* Did we succeed? */ | 1644 | /* Did we succeed? */ |
1645 | if (!chip_good(map, adr, datum)) { | 1645 | if (!chip_good(map, adr, datum)) { |
1646 | /* reset on all failures. */ | 1646 | /* reset on all failures. */ |
1647 | map_write( map, CMD(0xF0), chip->start ); | 1647 | map_write(map, CMD(0xF0), chip->start); |
1648 | /* FIXME - should have reset delay before continuing */ | 1648 | /* FIXME - should have reset delay before continuing */ |
1649 | 1649 | ||
1650 | if (++retry_cnt <= MAX_WORD_RETRIES) | 1650 | if (++retry_cnt <= MAX_RETRIES) |
1651 | goto retry; | 1651 | goto retry; |
1652 | 1652 | ||
1653 | ret = -EIO; | 1653 | ret = -EIO; |
@@ -1822,7 +1822,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, | |||
1822 | datum = map_word_load(map, buf); | 1822 | datum = map_word_load(map, buf); |
1823 | 1823 | ||
1824 | pr_debug("MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n", | 1824 | pr_debug("MTD %s(): WRITE 0x%.8lx(0x%.8lx)\n", |
1825 | __func__, adr, datum.x[0] ); | 1825 | __func__, adr, datum.x[0]); |
1826 | 1826 | ||
1827 | XIP_INVAL_CACHED_RANGE(map, adr, len); | 1827 | XIP_INVAL_CACHED_RANGE(map, adr, len); |
1828 | ENABLE_VPP(map); | 1828 | ENABLE_VPP(map); |
@@ -1880,7 +1880,7 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, | |||
1880 | if (time_after(jiffies, timeo) && !chip_ready(map, adr)) | 1880 | if (time_after(jiffies, timeo) && !chip_ready(map, adr)) |
1881 | break; | 1881 | break; |
1882 | 1882 | ||
1883 | if (chip_ready(map, adr)) { | 1883 | if (chip_good(map, adr, datum)) { |
1884 | xip_enable(map, chip, adr); | 1884 | xip_enable(map, chip, adr); |
1885 | goto op_done; | 1885 | goto op_done; |
1886 | } | 1886 | } |
@@ -2106,7 +2106,7 @@ retry: | |||
2106 | map_write(map, CMD(0xF0), chip->start); | 2106 | map_write(map, CMD(0xF0), chip->start); |
2107 | /* FIXME - should have reset delay before continuing */ | 2107 | /* FIXME - should have reset delay before continuing */ |
2108 | 2108 | ||
2109 | if (++retry_cnt <= MAX_WORD_RETRIES) | 2109 | if (++retry_cnt <= MAX_RETRIES) |
2110 | goto retry; | 2110 | goto retry; |
2111 | 2111 | ||
2112 | ret = -EIO; | 2112 | ret = -EIO; |
@@ -2241,6 +2241,7 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip) | |||
2241 | unsigned long int adr; | 2241 | unsigned long int adr; |
2242 | DECLARE_WAITQUEUE(wait, current); | 2242 | DECLARE_WAITQUEUE(wait, current); |
2243 | int ret = 0; | 2243 | int ret = 0; |
2244 | int retry_cnt = 0; | ||
2244 | 2245 | ||
2245 | adr = cfi->addr_unlock1; | 2246 | adr = cfi->addr_unlock1; |
2246 | 2247 | ||
@@ -2252,12 +2253,13 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip) | |||
2252 | } | 2253 | } |
2253 | 2254 | ||
2254 | pr_debug("MTD %s(): ERASE 0x%.8lx\n", | 2255 | pr_debug("MTD %s(): ERASE 0x%.8lx\n", |
2255 | __func__, chip->start ); | 2256 | __func__, chip->start); |
2256 | 2257 | ||
2257 | XIP_INVAL_CACHED_RANGE(map, adr, map->size); | 2258 | XIP_INVAL_CACHED_RANGE(map, adr, map->size); |
2258 | ENABLE_VPP(map); | 2259 | ENABLE_VPP(map); |
2259 | xip_disable(map, chip, adr); | 2260 | xip_disable(map, chip, adr); |
2260 | 2261 | ||
2262 | retry: | ||
2261 | cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); | 2263 | cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); |
2262 | cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); | 2264 | cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); |
2263 | cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); | 2265 | cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); |
@@ -2294,12 +2296,13 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip) | |||
2294 | chip->erase_suspended = 0; | 2296 | chip->erase_suspended = 0; |
2295 | } | 2297 | } |
2296 | 2298 | ||
2297 | if (chip_ready(map, adr)) | 2299 | if (chip_good(map, adr, map_word_ff(map))) |
2298 | break; | 2300 | break; |
2299 | 2301 | ||
2300 | if (time_after(jiffies, timeo)) { | 2302 | if (time_after(jiffies, timeo)) { |
2301 | printk(KERN_WARNING "MTD %s(): software timeout\n", | 2303 | printk(KERN_WARNING "MTD %s(): software timeout\n", |
2302 | __func__ ); | 2304 | __func__); |
2305 | ret = -EIO; | ||
2303 | break; | 2306 | break; |
2304 | } | 2307 | } |
2305 | 2308 | ||
@@ -2307,12 +2310,15 @@ static int __xipram do_erase_chip(struct map_info *map, struct flchip *chip) | |||
2307 | UDELAY(map, chip, adr, 1000000/HZ); | 2310 | UDELAY(map, chip, adr, 1000000/HZ); |
2308 | } | 2311 | } |
2309 | /* Did we succeed? */ | 2312 | /* Did we succeed? */ |
2310 | if (!chip_good(map, adr, map_word_ff(map))) { | 2313 | if (ret) { |
2311 | /* reset on all failures. */ | 2314 | /* reset on all failures. */ |
2312 | map_write( map, CMD(0xF0), chip->start ); | 2315 | map_write(map, CMD(0xF0), chip->start); |
2313 | /* FIXME - should have reset delay before continuing */ | 2316 | /* FIXME - should have reset delay before continuing */ |
2314 | 2317 | ||
2315 | ret = -EIO; | 2318 | if (++retry_cnt <= MAX_RETRIES) { |
2319 | ret = 0; | ||
2320 | goto retry; | ||
2321 | } | ||
2316 | } | 2322 | } |
2317 | 2323 | ||
2318 | chip->state = FL_READY; | 2324 | chip->state = FL_READY; |
@@ -2331,6 +2337,7 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, | |||
2331 | unsigned long timeo = jiffies + HZ; | 2337 | unsigned long timeo = jiffies + HZ; |
2332 | DECLARE_WAITQUEUE(wait, current); | 2338 | DECLARE_WAITQUEUE(wait, current); |
2333 | int ret = 0; | 2339 | int ret = 0; |
2340 | int retry_cnt = 0; | ||
2334 | 2341 | ||
2335 | adr += chip->start; | 2342 | adr += chip->start; |
2336 | 2343 | ||
@@ -2342,12 +2349,13 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, | |||
2342 | } | 2349 | } |
2343 | 2350 | ||
2344 | pr_debug("MTD %s(): ERASE 0x%.8lx\n", | 2351 | pr_debug("MTD %s(): ERASE 0x%.8lx\n", |
2345 | __func__, adr ); | 2352 | __func__, adr); |
2346 | 2353 | ||
2347 | XIP_INVAL_CACHED_RANGE(map, adr, len); | 2354 | XIP_INVAL_CACHED_RANGE(map, adr, len); |
2348 | ENABLE_VPP(map); | 2355 | ENABLE_VPP(map); |
2349 | xip_disable(map, chip, adr); | 2356 | xip_disable(map, chip, adr); |
2350 | 2357 | ||
2358 | retry: | ||
2351 | cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); | 2359 | cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); |
2352 | cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); | 2360 | cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, cfi->device_type, NULL); |
2353 | cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); | 2361 | cfi_send_gen_cmd(0x80, cfi->addr_unlock1, chip->start, map, cfi, cfi->device_type, NULL); |
@@ -2384,15 +2392,13 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, | |||
2384 | chip->erase_suspended = 0; | 2392 | chip->erase_suspended = 0; |
2385 | } | 2393 | } |
2386 | 2394 | ||
2387 | if (chip_ready(map, adr)) { | 2395 | if (chip_good(map, adr, map_word_ff(map))) |
2388 | xip_enable(map, chip, adr); | ||
2389 | break; | 2396 | break; |
2390 | } | ||
2391 | 2397 | ||
2392 | if (time_after(jiffies, timeo)) { | 2398 | if (time_after(jiffies, timeo)) { |
2393 | xip_enable(map, chip, adr); | ||
2394 | printk(KERN_WARNING "MTD %s(): software timeout\n", | 2399 | printk(KERN_WARNING "MTD %s(): software timeout\n", |
2395 | __func__ ); | 2400 | __func__); |
2401 | ret = -EIO; | ||
2396 | break; | 2402 | break; |
2397 | } | 2403 | } |
2398 | 2404 | ||
@@ -2400,15 +2406,19 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, | |||
2400 | UDELAY(map, chip, adr, 1000000/HZ); | 2406 | UDELAY(map, chip, adr, 1000000/HZ); |
2401 | } | 2407 | } |
2402 | /* Did we succeed? */ | 2408 | /* Did we succeed? */ |
2403 | if (!chip_good(map, adr, map_word_ff(map))) { | 2409 | if (ret) { |
2404 | /* reset on all failures. */ | 2410 | /* reset on all failures. */ |
2405 | map_write( map, CMD(0xF0), chip->start ); | 2411 | map_write(map, CMD(0xF0), chip->start); |
2406 | /* FIXME - should have reset delay before continuing */ | 2412 | /* FIXME - should have reset delay before continuing */ |
2407 | 2413 | ||
2408 | ret = -EIO; | 2414 | if (++retry_cnt <= MAX_RETRIES) { |
2415 | ret = 0; | ||
2416 | goto retry; | ||
2417 | } | ||
2409 | } | 2418 | } |
2410 | 2419 | ||
2411 | chip->state = FL_READY; | 2420 | chip->state = FL_READY; |
2421 | xip_enable(map, chip, adr); | ||
2412 | DISABLE_VPP(map); | 2422 | DISABLE_VPP(map); |
2413 | put_chip(map, chip, adr); | 2423 | put_chip(map, chip, adr); |
2414 | mutex_unlock(&chip->mutex); | 2424 | mutex_unlock(&chip->mutex); |
diff --git a/drivers/mtd/chips/cfi_probe.c b/drivers/mtd/chips/cfi_probe.c index e8d0164498b0..cf426956454c 100644 --- a/drivers/mtd/chips/cfi_probe.c +++ b/drivers/mtd/chips/cfi_probe.c | |||
@@ -63,6 +63,30 @@ do { \ | |||
63 | 63 | ||
64 | #endif | 64 | #endif |
65 | 65 | ||
66 | /* | ||
67 | * This fixup occurs immediately after reading the CFI structure and can affect | ||
68 | * the number of chips detected, unlike cfi_fixup, which occurs after an | ||
69 | * mtd_info structure has been created for the chip. | ||
70 | */ | ||
71 | struct cfi_early_fixup { | ||
72 | uint16_t mfr; | ||
73 | uint16_t id; | ||
74 | void (*fixup)(struct cfi_private *cfi); | ||
75 | }; | ||
76 | |||
77 | static void cfi_early_fixup(struct cfi_private *cfi, | ||
78 | const struct cfi_early_fixup *fixups) | ||
79 | { | ||
80 | const struct cfi_early_fixup *f; | ||
81 | |||
82 | for (f = fixups; f->fixup; f++) { | ||
83 | if (((f->mfr == CFI_MFR_ANY) || (f->mfr == cfi->mfr)) && | ||
84 | ((f->id == CFI_ID_ANY) || (f->id == cfi->id))) { | ||
85 | f->fixup(cfi); | ||
86 | } | ||
87 | } | ||
88 | } | ||
89 | |||
66 | /* check for QRY. | 90 | /* check for QRY. |
67 | in: interleave,type,mode | 91 | in: interleave,type,mode |
68 | ret: table index, <0 for error | 92 | ret: table index, <0 for error |
@@ -151,6 +175,22 @@ static int __xipram cfi_probe_chip(struct map_info *map, __u32 base, | |||
151 | return 1; | 175 | return 1; |
152 | } | 176 | } |
153 | 177 | ||
178 | static void fixup_s70gl02gs_chips(struct cfi_private *cfi) | ||
179 | { | ||
180 | /* | ||
181 | * S70GL02GS flash reports a single 256 MiB chip, but is really made up | ||
182 | * of two 128 MiB chips with 1024 sectors each. | ||
183 | */ | ||
184 | cfi->cfiq->DevSize = 27; | ||
185 | cfi->cfiq->EraseRegionInfo[0] = 0x20003ff; | ||
186 | pr_warn("Bad S70GL02GS CFI data; adjust to detect 2 chips\n"); | ||
187 | } | ||
188 | |||
189 | static const struct cfi_early_fixup cfi_early_fixup_table[] = { | ||
190 | { CFI_MFR_AMD, 0x4801, fixup_s70gl02gs_chips }, | ||
191 | { }, | ||
192 | }; | ||
193 | |||
154 | static int __xipram cfi_chip_setup(struct map_info *map, | 194 | static int __xipram cfi_chip_setup(struct map_info *map, |
155 | struct cfi_private *cfi) | 195 | struct cfi_private *cfi) |
156 | { | 196 | { |
@@ -235,6 +275,8 @@ static int __xipram cfi_chip_setup(struct map_info *map, | |||
235 | cfi_qry_mode_off(base, map, cfi); | 275 | cfi_qry_mode_off(base, map, cfi); |
236 | xip_allowed(base, map); | 276 | xip_allowed(base, map); |
237 | 277 | ||
278 | cfi_early_fixup(cfi, cfi_early_fixup_table); | ||
279 | |||
238 | printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank. Manufacturer ID %#08x Chip ID %#08x\n", | 280 | printk(KERN_INFO "%s: Found %d x%d devices at 0x%x in %d-bit bank. Manufacturer ID %#08x Chip ID %#08x\n", |
239 | map->name, cfi->interleave, cfi->device_type*8, base, | 281 | map->name, cfi->interleave, cfi->device_type*8, base, |
240 | map->bankwidth*8, cfi->mfr, cfi->id); | 282 | map->bankwidth*8, cfi->mfr, cfi->id); |
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c index fbd5affc0acf..3ea44cff9b75 100644 --- a/drivers/mtd/cmdlinepart.c +++ b/drivers/mtd/cmdlinepart.c | |||
@@ -190,7 +190,10 @@ static struct mtd_partition * newpart(char *s, | |||
190 | extra_mem = (unsigned char *)(parts + *num_parts); | 190 | extra_mem = (unsigned char *)(parts + *num_parts); |
191 | } | 191 | } |
192 | 192 | ||
193 | /* enter this partition (offset will be calculated later if it is zero at this point) */ | 193 | /* |
194 | * enter this partition (offset will be calculated later if it is | ||
195 | * OFFSET_CONTINUOUS at this point) | ||
196 | */ | ||
194 | parts[this_part].size = size; | 197 | parts[this_part].size = size; |
195 | parts[this_part].offset = offset; | 198 | parts[this_part].offset = offset; |
196 | parts[this_part].mask_flags = mask_flags; | 199 | parts[this_part].mask_flags = mask_flags; |
diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index c594fe5eac08..802d8f159e90 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c | |||
@@ -1470,8 +1470,7 @@ static struct docg3 *sysfs_dev2docg3(struct device *dev, | |||
1470 | struct device_attribute *attr) | 1470 | struct device_attribute *attr) |
1471 | { | 1471 | { |
1472 | int floor; | 1472 | int floor; |
1473 | struct platform_device *pdev = to_platform_device(dev); | 1473 | struct mtd_info **docg3_floors = dev_get_drvdata(dev); |
1474 | struct mtd_info **docg3_floors = platform_get_drvdata(pdev); | ||
1475 | 1474 | ||
1476 | floor = attr->attr.name[1] - '0'; | 1475 | floor = attr->attr.name[1] - '0'; |
1477 | if (floor < 0 || floor >= DOC_MAX_NBFLOORS) | 1476 | if (floor < 0 || floor >= DOC_MAX_NBFLOORS) |
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index aaaeaae01e1d..3a6f450d1093 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c | |||
@@ -140,7 +140,7 @@ static int dataflash_waitready(struct spi_device *spi) | |||
140 | if (status & (1 << 7)) /* RDY/nBSY */ | 140 | if (status & (1 << 7)) /* RDY/nBSY */ |
141 | return status; | 141 | return status; |
142 | 142 | ||
143 | msleep(3); | 143 | usleep_range(3000, 4000); |
144 | } | 144 | } |
145 | } | 145 | } |
146 | 146 | ||
diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c index aab4f68bd36f..2d598412972d 100644 --- a/drivers/mtd/inftlmount.c +++ b/drivers/mtd/inftlmount.c | |||
@@ -334,28 +334,37 @@ static int memcmpb(void *a, int c, int n) | |||
334 | static int check_free_sectors(struct INFTLrecord *inftl, unsigned int address, | 334 | static int check_free_sectors(struct INFTLrecord *inftl, unsigned int address, |
335 | int len, int check_oob) | 335 | int len, int check_oob) |
336 | { | 336 | { |
337 | u8 buf[SECTORSIZE + inftl->mbd.mtd->oobsize]; | ||
338 | struct mtd_info *mtd = inftl->mbd.mtd; | 337 | struct mtd_info *mtd = inftl->mbd.mtd; |
339 | size_t retlen; | 338 | size_t retlen; |
340 | int i; | 339 | int i, ret; |
340 | u8 *buf; | ||
341 | |||
342 | buf = kmalloc(SECTORSIZE + mtd->oobsize, GFP_KERNEL); | ||
343 | if (!buf) | ||
344 | return -1; | ||
341 | 345 | ||
346 | ret = -1; | ||
342 | for (i = 0; i < len; i += SECTORSIZE) { | 347 | for (i = 0; i < len; i += SECTORSIZE) { |
343 | if (mtd_read(mtd, address, SECTORSIZE, &retlen, buf)) | 348 | if (mtd_read(mtd, address, SECTORSIZE, &retlen, buf)) |
344 | return -1; | 349 | goto out; |
345 | if (memcmpb(buf, 0xff, SECTORSIZE) != 0) | 350 | if (memcmpb(buf, 0xff, SECTORSIZE) != 0) |
346 | return -1; | 351 | goto out; |
347 | 352 | ||
348 | if (check_oob) { | 353 | if (check_oob) { |
349 | if(inftl_read_oob(mtd, address, mtd->oobsize, | 354 | if(inftl_read_oob(mtd, address, mtd->oobsize, |
350 | &retlen, &buf[SECTORSIZE]) < 0) | 355 | &retlen, &buf[SECTORSIZE]) < 0) |
351 | return -1; | 356 | goto out; |
352 | if (memcmpb(buf + SECTORSIZE, 0xff, mtd->oobsize) != 0) | 357 | if (memcmpb(buf + SECTORSIZE, 0xff, mtd->oobsize) != 0) |
353 | return -1; | 358 | goto out; |
354 | } | 359 | } |
355 | address += SECTORSIZE; | 360 | address += SECTORSIZE; |
356 | } | 361 | } |
357 | 362 | ||
358 | return 0; | 363 | ret = 0; |
364 | |||
365 | out: | ||
366 | kfree(buf); | ||
367 | return ret; | ||
359 | } | 368 | } |
360 | 369 | ||
361 | /* | 370 | /* |
diff --git a/drivers/mtd/maps/pismo.c b/drivers/mtd/maps/pismo.c index dc6df9abea0b..c065d7995c0a 100644 --- a/drivers/mtd/maps/pismo.c +++ b/drivers/mtd/maps/pismo.c | |||
@@ -265,7 +265,6 @@ MODULE_DEVICE_TABLE(i2c, pismo_id); | |||
265 | static struct i2c_driver pismo_driver = { | 265 | static struct i2c_driver pismo_driver = { |
266 | .driver = { | 266 | .driver = { |
267 | .name = "pismo", | 267 | .name = "pismo", |
268 | .owner = THIS_MODULE, | ||
269 | }, | 268 | }, |
270 | .probe = pismo_probe, | 269 | .probe = pismo_probe, |
271 | .remove = pismo_remove, | 270 | .remove = pismo_remove, |
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 64a1fcaafd9a..42395df06be9 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c | |||
@@ -210,6 +210,15 @@ static ssize_t mtd_oobsize_show(struct device *dev, | |||
210 | } | 210 | } |
211 | static DEVICE_ATTR(oobsize, S_IRUGO, mtd_oobsize_show, NULL); | 211 | static DEVICE_ATTR(oobsize, S_IRUGO, mtd_oobsize_show, NULL); |
212 | 212 | ||
213 | static ssize_t mtd_oobavail_show(struct device *dev, | ||
214 | struct device_attribute *attr, char *buf) | ||
215 | { | ||
216 | struct mtd_info *mtd = dev_get_drvdata(dev); | ||
217 | |||
218 | return snprintf(buf, PAGE_SIZE, "%u\n", mtd->oobavail); | ||
219 | } | ||
220 | static DEVICE_ATTR(oobavail, S_IRUGO, mtd_oobavail_show, NULL); | ||
221 | |||
213 | static ssize_t mtd_numeraseregions_show(struct device *dev, | 222 | static ssize_t mtd_numeraseregions_show(struct device *dev, |
214 | struct device_attribute *attr, char *buf) | 223 | struct device_attribute *attr, char *buf) |
215 | { | 224 | { |
@@ -327,6 +336,7 @@ static struct attribute *mtd_attrs[] = { | |||
327 | &dev_attr_writesize.attr, | 336 | &dev_attr_writesize.attr, |
328 | &dev_attr_subpagesize.attr, | 337 | &dev_attr_subpagesize.attr, |
329 | &dev_attr_oobsize.attr, | 338 | &dev_attr_oobsize.attr, |
339 | &dev_attr_oobavail.attr, | ||
330 | &dev_attr_numeraseregions.attr, | 340 | &dev_attr_numeraseregions.attr, |
331 | &dev_attr_name.attr, | 341 | &dev_attr_name.attr, |
332 | &dev_attr_ecc_strength.attr, | 342 | &dev_attr_ecc_strength.attr, |
@@ -690,7 +700,6 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, | |||
690 | const struct mtd_partition *parts, | 700 | const struct mtd_partition *parts, |
691 | int nr_parts) | 701 | int nr_parts) |
692 | { | 702 | { |
693 | struct mtd_partitions parsed = { }; | ||
694 | int ret; | 703 | int ret; |
695 | 704 | ||
696 | mtd_set_dev_defaults(mtd); | 705 | mtd_set_dev_defaults(mtd); |
@@ -702,13 +711,10 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, | |||
702 | } | 711 | } |
703 | 712 | ||
704 | /* Prefer parsed partitions over driver-provided fallback */ | 713 | /* Prefer parsed partitions over driver-provided fallback */ |
705 | ret = parse_mtd_partitions(mtd, types, &parsed, parser_data); | 714 | ret = parse_mtd_partitions(mtd, types, parser_data); |
706 | if (!ret && parsed.nr_parts) { | 715 | if (ret > 0) |
707 | parts = parsed.parts; | 716 | ret = 0; |
708 | nr_parts = parsed.nr_parts; | 717 | else if (nr_parts) |
709 | } | ||
710 | |||
711 | if (nr_parts) | ||
712 | ret = add_mtd_partitions(mtd, parts, nr_parts); | 718 | ret = add_mtd_partitions(mtd, parts, nr_parts); |
713 | else if (!device_is_registered(&mtd->dev)) | 719 | else if (!device_is_registered(&mtd->dev)) |
714 | ret = add_mtd_device(mtd); | 720 | ret = add_mtd_device(mtd); |
@@ -734,8 +740,6 @@ int mtd_device_parse_register(struct mtd_info *mtd, const char * const *types, | |||
734 | } | 740 | } |
735 | 741 | ||
736 | out: | 742 | out: |
737 | /* Cleanup any parsed partitions */ | ||
738 | mtd_part_parser_cleanup(&parsed); | ||
739 | if (ret && device_is_registered(&mtd->dev)) | 743 | if (ret && device_is_registered(&mtd->dev)) |
740 | del_mtd_device(mtd); | 744 | del_mtd_device(mtd); |
741 | 745 | ||
diff --git a/drivers/mtd/mtdcore.h b/drivers/mtd/mtdcore.h index 37accfd0400e..9887bda317cd 100644 --- a/drivers/mtd/mtdcore.h +++ b/drivers/mtd/mtdcore.h | |||
@@ -15,7 +15,6 @@ int del_mtd_partitions(struct mtd_info *); | |||
15 | struct mtd_partitions; | 15 | struct mtd_partitions; |
16 | 16 | ||
17 | int parse_mtd_partitions(struct mtd_info *master, const char * const *types, | 17 | int parse_mtd_partitions(struct mtd_info *master, const char * const *types, |
18 | struct mtd_partitions *pparts, | ||
19 | struct mtd_part_parser_data *data); | 18 | struct mtd_part_parser_data *data); |
20 | 19 | ||
21 | void mtd_part_parser_cleanup(struct mtd_partitions *parts); | 20 | void mtd_part_parser_cleanup(struct mtd_partitions *parts); |
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 023516a63276..f8d3a015cdad 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c | |||
@@ -335,20 +335,7 @@ static inline void free_partition(struct mtd_part *p) | |||
335 | */ | 335 | */ |
336 | static int mtd_parse_part(struct mtd_part *slave, const char *const *types) | 336 | static int mtd_parse_part(struct mtd_part *slave, const char *const *types) |
337 | { | 337 | { |
338 | struct mtd_partitions parsed; | 338 | return parse_mtd_partitions(&slave->mtd, types, NULL); |
339 | int err; | ||
340 | |||
341 | err = parse_mtd_partitions(&slave->mtd, types, &parsed, NULL); | ||
342 | if (err) | ||
343 | return err; | ||
344 | else if (!parsed.nr_parts) | ||
345 | return -ENOENT; | ||
346 | |||
347 | err = add_mtd_partitions(&slave->mtd, parsed.parts, parsed.nr_parts); | ||
348 | |||
349 | mtd_part_parser_cleanup(&parsed); | ||
350 | |||
351 | return err; | ||
352 | } | 339 | } |
353 | 340 | ||
354 | static struct mtd_part *allocate_partition(struct mtd_info *parent, | 341 | static struct mtd_part *allocate_partition(struct mtd_info *parent, |
@@ -933,30 +920,27 @@ static int mtd_part_of_parse(struct mtd_info *master, | |||
933 | } | 920 | } |
934 | 921 | ||
935 | /** | 922 | /** |
936 | * parse_mtd_partitions - parse MTD partitions | 923 | * parse_mtd_partitions - parse and register MTD partitions |
924 | * | ||
937 | * @master: the master partition (describes whole MTD device) | 925 | * @master: the master partition (describes whole MTD device) |
938 | * @types: names of partition parsers to try or %NULL | 926 | * @types: names of partition parsers to try or %NULL |
939 | * @pparts: info about partitions found is returned here | ||
940 | * @data: MTD partition parser-specific data | 927 | * @data: MTD partition parser-specific data |
941 | * | 928 | * |
942 | * This function tries to find partition on MTD device @master. It uses MTD | 929 | * This function tries to find & register partitions on MTD device @master. It |
943 | * partition parsers, specified in @types. However, if @types is %NULL, then | 930 | * uses MTD partition parsers, specified in @types. However, if @types is %NULL, |
944 | * the default list of parsers is used. The default list contains only the | 931 | * then the default list of parsers is used. The default list contains only the |
945 | * "cmdlinepart" and "ofpart" parsers ATM. | 932 | * "cmdlinepart" and "ofpart" parsers ATM. |
946 | * Note: If there are more then one parser in @types, the kernel only takes the | 933 | * Note: If there are more then one parser in @types, the kernel only takes the |
947 | * partitions parsed out by the first parser. | 934 | * partitions parsed out by the first parser. |
948 | * | 935 | * |
949 | * This function may return: | 936 | * This function may return: |
950 | * o a negative error code in case of failure | 937 | * o a negative error code in case of failure |
951 | * o zero otherwise, and @pparts will describe the partitions, number of | 938 | * o number of found partitions otherwise |
952 | * partitions, and the parser which parsed them. Caller must release | ||
953 | * resources with mtd_part_parser_cleanup() when finished with the returned | ||
954 | * data. | ||
955 | */ | 939 | */ |
956 | int parse_mtd_partitions(struct mtd_info *master, const char *const *types, | 940 | int parse_mtd_partitions(struct mtd_info *master, const char *const *types, |
957 | struct mtd_partitions *pparts, | ||
958 | struct mtd_part_parser_data *data) | 941 | struct mtd_part_parser_data *data) |
959 | { | 942 | { |
943 | struct mtd_partitions pparts = { }; | ||
960 | struct mtd_part_parser *parser; | 944 | struct mtd_part_parser *parser; |
961 | int ret, err = 0; | 945 | int ret, err = 0; |
962 | 946 | ||
@@ -970,7 +954,7 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types, | |||
970 | * handled in a separated function. | 954 | * handled in a separated function. |
971 | */ | 955 | */ |
972 | if (!strcmp(*types, "ofpart")) { | 956 | if (!strcmp(*types, "ofpart")) { |
973 | ret = mtd_part_of_parse(master, pparts); | 957 | ret = mtd_part_of_parse(master, &pparts); |
974 | } else { | 958 | } else { |
975 | pr_debug("%s: parsing partitions %s\n", master->name, | 959 | pr_debug("%s: parsing partitions %s\n", master->name, |
976 | *types); | 960 | *types); |
@@ -981,13 +965,17 @@ int parse_mtd_partitions(struct mtd_info *master, const char *const *types, | |||
981 | parser ? parser->name : NULL); | 965 | parser ? parser->name : NULL); |
982 | if (!parser) | 966 | if (!parser) |
983 | continue; | 967 | continue; |
984 | ret = mtd_part_do_parse(parser, master, pparts, data); | 968 | ret = mtd_part_do_parse(parser, master, &pparts, data); |
985 | if (ret <= 0) | 969 | if (ret <= 0) |
986 | mtd_part_parser_put(parser); | 970 | mtd_part_parser_put(parser); |
987 | } | 971 | } |
988 | /* Found partitions! */ | 972 | /* Found partitions! */ |
989 | if (ret > 0) | 973 | if (ret > 0) { |
990 | return 0; | 974 | err = add_mtd_partitions(master, pparts.parts, |
975 | pparts.nr_parts); | ||
976 | mtd_part_parser_cleanup(&pparts); | ||
977 | return err ? err : pparts.nr_parts; | ||
978 | } | ||
991 | /* | 979 | /* |
992 | * Stash the first error we see; only report it if no parser | 980 | * Stash the first error we see; only report it if no parser |
993 | * succeeds | 981 | * succeeds |
diff --git a/drivers/mtd/nand/onenand/samsung.c b/drivers/mtd/nand/onenand/samsung.c index 2e9d076e445a..4cce4c0311ca 100644 --- a/drivers/mtd/nand/onenand/samsung.c +++ b/drivers/mtd/nand/onenand/samsung.c | |||
@@ -958,8 +958,7 @@ static int s3c_onenand_remove(struct platform_device *pdev) | |||
958 | 958 | ||
959 | static int s3c_pm_ops_suspend(struct device *dev) | 959 | static int s3c_pm_ops_suspend(struct device *dev) |
960 | { | 960 | { |
961 | struct platform_device *pdev = to_platform_device(dev); | 961 | struct mtd_info *mtd = dev_get_drvdata(dev); |
962 | struct mtd_info *mtd = platform_get_drvdata(pdev); | ||
963 | struct onenand_chip *this = mtd->priv; | 962 | struct onenand_chip *this = mtd->priv; |
964 | 963 | ||
965 | this->wait(mtd, FL_PM_SUSPENDED); | 964 | this->wait(mtd, FL_PM_SUSPENDED); |
@@ -968,8 +967,7 @@ static int s3c_pm_ops_suspend(struct device *dev) | |||
968 | 967 | ||
969 | static int s3c_pm_ops_resume(struct device *dev) | 968 | static int s3c_pm_ops_resume(struct device *dev) |
970 | { | 969 | { |
971 | struct platform_device *pdev = to_platform_device(dev); | 970 | struct mtd_info *mtd = dev_get_drvdata(dev); |
972 | struct mtd_info *mtd = platform_get_drvdata(pdev); | ||
973 | struct onenand_chip *this = mtd->priv; | 971 | struct onenand_chip *this = mtd->priv; |
974 | 972 | ||
975 | this->unlock_all(mtd); | 973 | this->unlock_all(mtd); |
diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index 19a2b283fbbe..6871ff0fd300 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig | |||
@@ -46,7 +46,7 @@ config MTD_NAND_DENALI | |||
46 | config MTD_NAND_DENALI_PCI | 46 | config MTD_NAND_DENALI_PCI |
47 | tristate "Support Denali NAND controller on Intel Moorestown" | 47 | tristate "Support Denali NAND controller on Intel Moorestown" |
48 | select MTD_NAND_DENALI | 48 | select MTD_NAND_DENALI |
49 | depends on HAS_DMA && PCI | 49 | depends on PCI |
50 | help | 50 | help |
51 | Enable the driver for NAND flash on Intel Moorestown, using the | 51 | Enable the driver for NAND flash on Intel Moorestown, using the |
52 | Denali NAND controller core. | 52 | Denali NAND controller core. |
@@ -152,7 +152,6 @@ config MTD_NAND_S3C2410_CLKSTOP | |||
152 | config MTD_NAND_TANGO | 152 | config MTD_NAND_TANGO |
153 | tristate "NAND Flash support for Tango chips" | 153 | tristate "NAND Flash support for Tango chips" |
154 | depends on ARCH_TANGO || COMPILE_TEST | 154 | depends on ARCH_TANGO || COMPILE_TEST |
155 | depends on HAS_DMA | ||
156 | help | 155 | help |
157 | Enables the NAND Flash controller on Tango chips. | 156 | Enables the NAND Flash controller on Tango chips. |
158 | 157 | ||
@@ -285,7 +284,7 @@ config MTD_NAND_MARVELL | |||
285 | tristate "NAND controller support on Marvell boards" | 284 | tristate "NAND controller support on Marvell boards" |
286 | depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU || \ | 285 | depends on PXA3xx || ARCH_MMP || PLAT_ORION || ARCH_MVEBU || \ |
287 | COMPILE_TEST | 286 | COMPILE_TEST |
288 | depends on HAS_IOMEM && HAS_DMA | 287 | depends on HAS_IOMEM |
289 | help | 288 | help |
290 | This enables the NAND flash controller driver for Marvell boards, | 289 | This enables the NAND flash controller driver for Marvell boards, |
291 | including: | 290 | including: |
@@ -447,7 +446,6 @@ config MTD_NAND_SH_FLCTL | |||
447 | tristate "Support for NAND on Renesas SuperH FLCTL" | 446 | tristate "Support for NAND on Renesas SuperH FLCTL" |
448 | depends on SUPERH || COMPILE_TEST | 447 | depends on SUPERH || COMPILE_TEST |
449 | depends on HAS_IOMEM | 448 | depends on HAS_IOMEM |
450 | depends on HAS_DMA | ||
451 | help | 449 | help |
452 | Several Renesas SuperH CPU has FLCTL. This option enables support | 450 | Several Renesas SuperH CPU has FLCTL. This option enables support |
453 | for NAND Flash using FLCTL. | 451 | for NAND Flash using FLCTL. |
@@ -515,7 +513,6 @@ config MTD_NAND_SUNXI | |||
515 | config MTD_NAND_HISI504 | 513 | config MTD_NAND_HISI504 |
516 | tristate "Support for NAND controller on Hisilicon SoC Hip04" | 514 | tristate "Support for NAND controller on Hisilicon SoC Hip04" |
517 | depends on ARCH_HISI || COMPILE_TEST | 515 | depends on ARCH_HISI || COMPILE_TEST |
518 | depends on HAS_DMA | ||
519 | help | 516 | help |
520 | Enables support for NAND controller on Hisilicon SoC Hip04. | 517 | Enables support for NAND controller on Hisilicon SoC Hip04. |
521 | 518 | ||
@@ -529,7 +526,6 @@ config MTD_NAND_QCOM | |||
529 | config MTD_NAND_MTK | 526 | config MTD_NAND_MTK |
530 | tristate "Support for NAND controller on MTK SoCs" | 527 | tristate "Support for NAND controller on MTK SoCs" |
531 | depends on ARCH_MEDIATEK || COMPILE_TEST | 528 | depends on ARCH_MEDIATEK || COMPILE_TEST |
532 | depends on HAS_DMA | ||
533 | help | 529 | help |
534 | Enables support for NAND controller on MTK SoCs. | 530 | Enables support for NAND controller on MTK SoCs. |
535 | This controller is found on mt27xx, mt81xx, mt65xx SoCs. | 531 | This controller is found on mt27xx, mt81xx, mt65xx SoCs. |
diff --git a/drivers/mtd/nand/raw/davinci_nand.c b/drivers/mtd/nand/raw/davinci_nand.c index 0f09518d980f..7255a0d94374 100644 --- a/drivers/mtd/nand/raw/davinci_nand.c +++ b/drivers/mtd/nand/raw/davinci_nand.c | |||
@@ -27,7 +27,6 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
29 | #include <linux/err.h> | 29 | #include <linux/err.h> |
30 | #include <linux/clk.h> | ||
31 | #include <linux/io.h> | 30 | #include <linux/io.h> |
32 | #include <linux/mtd/rawnand.h> | 31 | #include <linux/mtd/rawnand.h> |
33 | #include <linux/mtd/partitions.h> | 32 | #include <linux/mtd/partitions.h> |
@@ -55,7 +54,6 @@ struct davinci_nand_info { | |||
55 | struct nand_chip chip; | 54 | struct nand_chip chip; |
56 | 55 | ||
57 | struct device *dev; | 56 | struct device *dev; |
58 | struct clk *clk; | ||
59 | 57 | ||
60 | bool is_readmode; | 58 | bool is_readmode; |
61 | 59 | ||
@@ -703,22 +701,6 @@ static int nand_davinci_probe(struct platform_device *pdev) | |||
703 | /* Use board-specific ECC config */ | 701 | /* Use board-specific ECC config */ |
704 | info->chip.ecc.mode = pdata->ecc_mode; | 702 | info->chip.ecc.mode = pdata->ecc_mode; |
705 | 703 | ||
706 | ret = -EINVAL; | ||
707 | |||
708 | info->clk = devm_clk_get(&pdev->dev, "aemif"); | ||
709 | if (IS_ERR(info->clk)) { | ||
710 | ret = PTR_ERR(info->clk); | ||
711 | dev_dbg(&pdev->dev, "unable to get AEMIF clock, err %d\n", ret); | ||
712 | return ret; | ||
713 | } | ||
714 | |||
715 | ret = clk_prepare_enable(info->clk); | ||
716 | if (ret < 0) { | ||
717 | dev_dbg(&pdev->dev, "unable to enable AEMIF clock, err %d\n", | ||
718 | ret); | ||
719 | goto err_clk_enable; | ||
720 | } | ||
721 | |||
722 | spin_lock_irq(&davinci_nand_lock); | 704 | spin_lock_irq(&davinci_nand_lock); |
723 | 705 | ||
724 | /* put CSxNAND into NAND mode */ | 706 | /* put CSxNAND into NAND mode */ |
@@ -732,7 +714,7 @@ static int nand_davinci_probe(struct platform_device *pdev) | |||
732 | ret = nand_scan_ident(mtd, pdata->mask_chipsel ? 2 : 1, NULL); | 714 | ret = nand_scan_ident(mtd, pdata->mask_chipsel ? 2 : 1, NULL); |
733 | if (ret < 0) { | 715 | if (ret < 0) { |
734 | dev_dbg(&pdev->dev, "no NAND chip(s) found\n"); | 716 | dev_dbg(&pdev->dev, "no NAND chip(s) found\n"); |
735 | goto err; | 717 | return ret; |
736 | } | 718 | } |
737 | 719 | ||
738 | switch (info->chip.ecc.mode) { | 720 | switch (info->chip.ecc.mode) { |
@@ -838,9 +820,6 @@ err_cleanup_nand: | |||
838 | nand_cleanup(&info->chip); | 820 | nand_cleanup(&info->chip); |
839 | 821 | ||
840 | err: | 822 | err: |
841 | clk_disable_unprepare(info->clk); | ||
842 | |||
843 | err_clk_enable: | ||
844 | spin_lock_irq(&davinci_nand_lock); | 823 | spin_lock_irq(&davinci_nand_lock); |
845 | if (info->chip.ecc.mode == NAND_ECC_HW_SYNDROME) | 824 | if (info->chip.ecc.mode == NAND_ECC_HW_SYNDROME) |
846 | ecc4_busy = false; | 825 | ecc4_busy = false; |
@@ -859,8 +838,6 @@ static int nand_davinci_remove(struct platform_device *pdev) | |||
859 | 838 | ||
860 | nand_release(nand_to_mtd(&info->chip)); | 839 | nand_release(nand_to_mtd(&info->chip)); |
861 | 840 | ||
862 | clk_disable_unprepare(info->clk); | ||
863 | |||
864 | return 0; | 841 | return 0; |
865 | } | 842 | } |
866 | 843 | ||
diff --git a/drivers/mtd/nand/raw/diskonchip.c b/drivers/mtd/nand/raw/diskonchip.c index 2b7b2b982b77..8d10061abb4b 100644 --- a/drivers/mtd/nand/raw/diskonchip.c +++ b/drivers/mtd/nand/raw/diskonchip.c | |||
@@ -1480,12 +1480,12 @@ static int __init doc_probe(unsigned long physadr) | |||
1480 | WriteDOC(tmp, virtadr, Mplus_DOCControl); | 1480 | WriteDOC(tmp, virtadr, Mplus_DOCControl); |
1481 | WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm); | 1481 | WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm); |
1482 | 1482 | ||
1483 | mdelay(1); | 1483 | usleep_range(1000, 2000); |
1484 | /* Enable the Millennium Plus ASIC */ | 1484 | /* Enable the Millennium Plus ASIC */ |
1485 | tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | DOC_MODE_BDECT; | 1485 | tmp = DOC_MODE_NORMAL | DOC_MODE_MDWREN | DOC_MODE_RST_LAT | DOC_MODE_BDECT; |
1486 | WriteDOC(tmp, virtadr, Mplus_DOCControl); | 1486 | WriteDOC(tmp, virtadr, Mplus_DOCControl); |
1487 | WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm); | 1487 | WriteDOC(~tmp, virtadr, Mplus_CtrlConfirm); |
1488 | mdelay(1); | 1488 | usleep_range(1000, 2000); |
1489 | 1489 | ||
1490 | ChipID = ReadDOC(virtadr, ChipID); | 1490 | ChipID = ReadDOC(virtadr, ChipID); |
1491 | 1491 | ||
diff --git a/drivers/mtd/nand/raw/fsl_elbc_nand.c b/drivers/mtd/nand/raw/fsl_elbc_nand.c index d28df991c73c..51f0b340bc0d 100644 --- a/drivers/mtd/nand/raw/fsl_elbc_nand.c +++ b/drivers/mtd/nand/raw/fsl_elbc_nand.c | |||
@@ -813,8 +813,6 @@ static int fsl_elbc_chip_remove(struct fsl_elbc_mtd *priv) | |||
813 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; | 813 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = priv->ctrl->nand; |
814 | struct mtd_info *mtd = nand_to_mtd(&priv->chip); | 814 | struct mtd_info *mtd = nand_to_mtd(&priv->chip); |
815 | 815 | ||
816 | nand_release(mtd); | ||
817 | |||
818 | kfree(mtd->name); | 816 | kfree(mtd->name); |
819 | 817 | ||
820 | if (priv->vbase) | 818 | if (priv->vbase) |
@@ -926,15 +924,20 @@ static int fsl_elbc_nand_probe(struct platform_device *pdev) | |||
926 | 924 | ||
927 | /* First look for RedBoot table or partitions on the command | 925 | /* First look for RedBoot table or partitions on the command |
928 | * line, these take precedence over device tree information */ | 926 | * line, these take precedence over device tree information */ |
929 | mtd_device_parse_register(mtd, part_probe_types, NULL, | 927 | ret = mtd_device_parse_register(mtd, part_probe_types, NULL, NULL, 0); |
930 | NULL, 0); | 928 | if (ret) |
929 | goto cleanup_nand; | ||
931 | 930 | ||
932 | pr_info("eLBC NAND device at 0x%llx, bank %d\n", | 931 | pr_info("eLBC NAND device at 0x%llx, bank %d\n", |
933 | (unsigned long long)res.start, priv->bank); | 932 | (unsigned long long)res.start, priv->bank); |
933 | |||
934 | return 0; | 934 | return 0; |
935 | 935 | ||
936 | cleanup_nand: | ||
937 | nand_cleanup(&priv->chip); | ||
936 | err: | 938 | err: |
937 | fsl_elbc_chip_remove(priv); | 939 | fsl_elbc_chip_remove(priv); |
940 | |||
938 | return ret; | 941 | return ret; |
939 | } | 942 | } |
940 | 943 | ||
@@ -942,7 +945,9 @@ static int fsl_elbc_nand_remove(struct platform_device *pdev) | |||
942 | { | 945 | { |
943 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = fsl_lbc_ctrl_dev->nand; | 946 | struct fsl_elbc_fcm_ctrl *elbc_fcm_ctrl = fsl_lbc_ctrl_dev->nand; |
944 | struct fsl_elbc_mtd *priv = dev_get_drvdata(&pdev->dev); | 947 | struct fsl_elbc_mtd *priv = dev_get_drvdata(&pdev->dev); |
948 | struct mtd_info *mtd = nand_to_mtd(&priv->chip); | ||
945 | 949 | ||
950 | nand_release(mtd); | ||
946 | fsl_elbc_chip_remove(priv); | 951 | fsl_elbc_chip_remove(priv); |
947 | 952 | ||
948 | mutex_lock(&fsl_elbc_nand_mutex); | 953 | mutex_lock(&fsl_elbc_nand_mutex); |
diff --git a/drivers/mtd/nand/raw/fsl_ifc_nand.c b/drivers/mtd/nand/raw/fsl_ifc_nand.c index 61aae0224078..382b67e97174 100644 --- a/drivers/mtd/nand/raw/fsl_ifc_nand.c +++ b/drivers/mtd/nand/raw/fsl_ifc_nand.c | |||
@@ -342,9 +342,16 @@ static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command, | |||
342 | 342 | ||
343 | case NAND_CMD_READID: | 343 | case NAND_CMD_READID: |
344 | case NAND_CMD_PARAM: { | 344 | case NAND_CMD_PARAM: { |
345 | /* | ||
346 | * For READID, read 8 bytes that are currently used. | ||
347 | * For PARAM, read all 3 copies of 256-bytes pages. | ||
348 | */ | ||
349 | int len = 8; | ||
345 | int timing = IFC_FIR_OP_RB; | 350 | int timing = IFC_FIR_OP_RB; |
346 | if (command == NAND_CMD_PARAM) | 351 | if (command == NAND_CMD_PARAM) { |
347 | timing = IFC_FIR_OP_RBCD; | 352 | timing = IFC_FIR_OP_RBCD; |
353 | len = 256 * 3; | ||
354 | } | ||
348 | 355 | ||
349 | ifc_out32((IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | | 356 | ifc_out32((IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | |
350 | (IFC_FIR_OP_UA << IFC_NAND_FIR0_OP1_SHIFT) | | 357 | (IFC_FIR_OP_UA << IFC_NAND_FIR0_OP1_SHIFT) | |
@@ -354,12 +361,8 @@ static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command, | |||
354 | &ifc->ifc_nand.nand_fcr0); | 361 | &ifc->ifc_nand.nand_fcr0); |
355 | ifc_out32(column, &ifc->ifc_nand.row3); | 362 | ifc_out32(column, &ifc->ifc_nand.row3); |
356 | 363 | ||
357 | /* | 364 | ifc_out32(len, &ifc->ifc_nand.nand_fbcr); |
358 | * although currently it's 8 bytes for READID, we always read | 365 | ifc_nand_ctrl->read_bytes = len; |
359 | * the maximum 256 bytes(for PARAM) | ||
360 | */ | ||
361 | ifc_out32(256, &ifc->ifc_nand.nand_fbcr); | ||
362 | ifc_nand_ctrl->read_bytes = 256; | ||
363 | 366 | ||
364 | set_addr(mtd, 0, 0, 0); | 367 | set_addr(mtd, 0, 0, 0); |
365 | fsl_ifc_run_command(mtd); | 368 | fsl_ifc_run_command(mtd); |
@@ -924,8 +927,6 @@ static int fsl_ifc_chip_remove(struct fsl_ifc_mtd *priv) | |||
924 | { | 927 | { |
925 | struct mtd_info *mtd = nand_to_mtd(&priv->chip); | 928 | struct mtd_info *mtd = nand_to_mtd(&priv->chip); |
926 | 929 | ||
927 | nand_release(mtd); | ||
928 | |||
929 | kfree(mtd->name); | 930 | kfree(mtd->name); |
930 | 931 | ||
931 | if (priv->vbase) | 932 | if (priv->vbase) |
@@ -1059,21 +1060,29 @@ static int fsl_ifc_nand_probe(struct platform_device *dev) | |||
1059 | 1060 | ||
1060 | /* First look for RedBoot table or partitions on the command | 1061 | /* First look for RedBoot table or partitions on the command |
1061 | * line, these take precedence over device tree information */ | 1062 | * line, these take precedence over device tree information */ |
1062 | mtd_device_parse_register(mtd, part_probe_types, NULL, NULL, 0); | 1063 | ret = mtd_device_parse_register(mtd, part_probe_types, NULL, NULL, 0); |
1064 | if (ret) | ||
1065 | goto cleanup_nand; | ||
1063 | 1066 | ||
1064 | dev_info(priv->dev, "IFC NAND device at 0x%llx, bank %d\n", | 1067 | dev_info(priv->dev, "IFC NAND device at 0x%llx, bank %d\n", |
1065 | (unsigned long long)res.start, priv->bank); | 1068 | (unsigned long long)res.start, priv->bank); |
1069 | |||
1066 | return 0; | 1070 | return 0; |
1067 | 1071 | ||
1072 | cleanup_nand: | ||
1073 | nand_cleanup(&priv->chip); | ||
1068 | err: | 1074 | err: |
1069 | fsl_ifc_chip_remove(priv); | 1075 | fsl_ifc_chip_remove(priv); |
1076 | |||
1070 | return ret; | 1077 | return ret; |
1071 | } | 1078 | } |
1072 | 1079 | ||
1073 | static int fsl_ifc_nand_remove(struct platform_device *dev) | 1080 | static int fsl_ifc_nand_remove(struct platform_device *dev) |
1074 | { | 1081 | { |
1075 | struct fsl_ifc_mtd *priv = dev_get_drvdata(&dev->dev); | 1082 | struct fsl_ifc_mtd *priv = dev_get_drvdata(&dev->dev); |
1083 | struct mtd_info *mtd = nand_to_mtd(&priv->chip); | ||
1076 | 1084 | ||
1085 | nand_release(mtd); | ||
1077 | fsl_ifc_chip_remove(priv); | 1086 | fsl_ifc_chip_remove(priv); |
1078 | 1087 | ||
1079 | mutex_lock(&fsl_ifc_nand_mutex); | 1088 | mutex_lock(&fsl_ifc_nand_mutex); |
diff --git a/drivers/mtd/nand/raw/fsmc_nand.c b/drivers/mtd/nand/raw/fsmc_nand.c index 28c48dcc514e..f4a5a317d4ae 100644 --- a/drivers/mtd/nand/raw/fsmc_nand.c +++ b/drivers/mtd/nand/raw/fsmc_nand.c | |||
@@ -1022,12 +1022,12 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
1022 | host->read_dma_chan = dma_request_channel(mask, filter, NULL); | 1022 | host->read_dma_chan = dma_request_channel(mask, filter, NULL); |
1023 | if (!host->read_dma_chan) { | 1023 | if (!host->read_dma_chan) { |
1024 | dev_err(&pdev->dev, "Unable to get read dma channel\n"); | 1024 | dev_err(&pdev->dev, "Unable to get read dma channel\n"); |
1025 | goto err_req_read_chnl; | 1025 | goto disable_clk; |
1026 | } | 1026 | } |
1027 | host->write_dma_chan = dma_request_channel(mask, filter, NULL); | 1027 | host->write_dma_chan = dma_request_channel(mask, filter, NULL); |
1028 | if (!host->write_dma_chan) { | 1028 | if (!host->write_dma_chan) { |
1029 | dev_err(&pdev->dev, "Unable to get write dma channel\n"); | 1029 | dev_err(&pdev->dev, "Unable to get write dma channel\n"); |
1030 | goto err_req_write_chnl; | 1030 | goto release_dma_read_chan; |
1031 | } | 1031 | } |
1032 | } | 1032 | } |
1033 | 1033 | ||
@@ -1050,7 +1050,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
1050 | ret = nand_scan_ident(mtd, 1, NULL); | 1050 | ret = nand_scan_ident(mtd, 1, NULL); |
1051 | if (ret) { | 1051 | if (ret) { |
1052 | dev_err(&pdev->dev, "No NAND Device found!\n"); | 1052 | dev_err(&pdev->dev, "No NAND Device found!\n"); |
1053 | goto err_scan_ident; | 1053 | goto release_dma_write_chan; |
1054 | } | 1054 | } |
1055 | 1055 | ||
1056 | if (AMBA_REV_BITS(host->pid) >= 8) { | 1056 | if (AMBA_REV_BITS(host->pid) >= 8) { |
@@ -1065,7 +1065,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
1065 | dev_warn(&pdev->dev, "No oob scheme defined for oobsize %d\n", | 1065 | dev_warn(&pdev->dev, "No oob scheme defined for oobsize %d\n", |
1066 | mtd->oobsize); | 1066 | mtd->oobsize); |
1067 | ret = -EINVAL; | 1067 | ret = -EINVAL; |
1068 | goto err_probe; | 1068 | goto release_dma_write_chan; |
1069 | } | 1069 | } |
1070 | 1070 | ||
1071 | mtd_set_ooblayout(mtd, &fsmc_ecc4_ooblayout_ops); | 1071 | mtd_set_ooblayout(mtd, &fsmc_ecc4_ooblayout_ops); |
@@ -1090,7 +1090,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
1090 | 1090 | ||
1091 | default: | 1091 | default: |
1092 | dev_err(&pdev->dev, "Unsupported ECC mode!\n"); | 1092 | dev_err(&pdev->dev, "Unsupported ECC mode!\n"); |
1093 | goto err_probe; | 1093 | goto release_dma_write_chan; |
1094 | } | 1094 | } |
1095 | 1095 | ||
1096 | /* | 1096 | /* |
@@ -1110,7 +1110,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
1110 | "No oob scheme defined for oobsize %d\n", | 1110 | "No oob scheme defined for oobsize %d\n", |
1111 | mtd->oobsize); | 1111 | mtd->oobsize); |
1112 | ret = -EINVAL; | 1112 | ret = -EINVAL; |
1113 | goto err_probe; | 1113 | goto release_dma_write_chan; |
1114 | } | 1114 | } |
1115 | } | 1115 | } |
1116 | } | 1116 | } |
@@ -1118,26 +1118,29 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
1118 | /* Second stage of scan to fill MTD data-structures */ | 1118 | /* Second stage of scan to fill MTD data-structures */ |
1119 | ret = nand_scan_tail(mtd); | 1119 | ret = nand_scan_tail(mtd); |
1120 | if (ret) | 1120 | if (ret) |
1121 | goto err_probe; | 1121 | goto release_dma_write_chan; |
1122 | 1122 | ||
1123 | mtd->name = "nand"; | 1123 | mtd->name = "nand"; |
1124 | ret = mtd_device_register(mtd, NULL, 0); | 1124 | ret = mtd_device_register(mtd, NULL, 0); |
1125 | if (ret) | 1125 | if (ret) |
1126 | goto err_probe; | 1126 | goto cleanup_nand; |
1127 | 1127 | ||
1128 | platform_set_drvdata(pdev, host); | 1128 | platform_set_drvdata(pdev, host); |
1129 | dev_info(&pdev->dev, "FSMC NAND driver registration successful\n"); | 1129 | dev_info(&pdev->dev, "FSMC NAND driver registration successful\n"); |
1130 | |||
1130 | return 0; | 1131 | return 0; |
1131 | 1132 | ||
1132 | err_probe: | 1133 | cleanup_nand: |
1133 | err_scan_ident: | 1134 | nand_cleanup(nand); |
1135 | release_dma_write_chan: | ||
1134 | if (host->mode == USE_DMA_ACCESS) | 1136 | if (host->mode == USE_DMA_ACCESS) |
1135 | dma_release_channel(host->write_dma_chan); | 1137 | dma_release_channel(host->write_dma_chan); |
1136 | err_req_write_chnl: | 1138 | release_dma_read_chan: |
1137 | if (host->mode == USE_DMA_ACCESS) | 1139 | if (host->mode == USE_DMA_ACCESS) |
1138 | dma_release_channel(host->read_dma_chan); | 1140 | dma_release_channel(host->read_dma_chan); |
1139 | err_req_read_chnl: | 1141 | disable_clk: |
1140 | clk_disable_unprepare(host->clk); | 1142 | clk_disable_unprepare(host->clk); |
1143 | |||
1141 | return ret; | 1144 | return ret; |
1142 | } | 1145 | } |
1143 | 1146 | ||
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c index e94556705dc7..83697b8df871 100644 --- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-lib.c | |||
@@ -258,8 +258,9 @@ int bch_set_geometry(struct gpmi_nand_data *this) | |||
258 | unsigned int gf_len; | 258 | unsigned int gf_len; |
259 | int ret; | 259 | int ret; |
260 | 260 | ||
261 | if (common_nfc_set_geometry(this)) | 261 | ret = common_nfc_set_geometry(this); |
262 | return !0; | 262 | if (ret) |
263 | return ret; | ||
263 | 264 | ||
264 | block_count = bch_geo->ecc_chunk_count - 1; | 265 | block_count = bch_geo->ecc_chunk_count - 1; |
265 | block_size = bch_geo->ecc_chunk_size; | 266 | block_size = bch_geo->ecc_chunk_size; |
@@ -544,19 +545,13 @@ int gpmi_is_ready(struct gpmi_nand_data *this, unsigned chip) | |||
544 | return reg & mask; | 545 | return reg & mask; |
545 | } | 546 | } |
546 | 547 | ||
547 | static inline void set_dma_type(struct gpmi_nand_data *this, | ||
548 | enum dma_ops_type type) | ||
549 | { | ||
550 | this->last_dma_type = this->dma_type; | ||
551 | this->dma_type = type; | ||
552 | } | ||
553 | |||
554 | int gpmi_send_command(struct gpmi_nand_data *this) | 548 | int gpmi_send_command(struct gpmi_nand_data *this) |
555 | { | 549 | { |
556 | struct dma_chan *channel = get_dma_chan(this); | 550 | struct dma_chan *channel = get_dma_chan(this); |
557 | struct dma_async_tx_descriptor *desc; | 551 | struct dma_async_tx_descriptor *desc; |
558 | struct scatterlist *sgl; | 552 | struct scatterlist *sgl; |
559 | int chip = this->current_chip; | 553 | int chip = this->current_chip; |
554 | int ret; | ||
560 | u32 pio[3]; | 555 | u32 pio[3]; |
561 | 556 | ||
562 | /* [1] send out the PIO words */ | 557 | /* [1] send out the PIO words */ |
@@ -586,15 +581,19 @@ int gpmi_send_command(struct gpmi_nand_data *this) | |||
586 | return -EINVAL; | 581 | return -EINVAL; |
587 | 582 | ||
588 | /* [3] submit the DMA */ | 583 | /* [3] submit the DMA */ |
589 | set_dma_type(this, DMA_FOR_COMMAND); | 584 | ret = start_dma_without_bch_irq(this, desc); |
590 | return start_dma_without_bch_irq(this, desc); | 585 | |
586 | dma_unmap_sg(this->dev, sgl, 1, DMA_TO_DEVICE); | ||
587 | |||
588 | return ret; | ||
591 | } | 589 | } |
592 | 590 | ||
593 | int gpmi_send_data(struct gpmi_nand_data *this) | 591 | int gpmi_send_data(struct gpmi_nand_data *this, const void *buf, int len) |
594 | { | 592 | { |
595 | struct dma_async_tx_descriptor *desc; | 593 | struct dma_async_tx_descriptor *desc; |
596 | struct dma_chan *channel = get_dma_chan(this); | 594 | struct dma_chan *channel = get_dma_chan(this); |
597 | int chip = this->current_chip; | 595 | int chip = this->current_chip; |
596 | int ret; | ||
598 | uint32_t command_mode; | 597 | uint32_t command_mode; |
599 | uint32_t address; | 598 | uint32_t address; |
600 | u32 pio[2]; | 599 | u32 pio[2]; |
@@ -608,7 +607,7 @@ int gpmi_send_data(struct gpmi_nand_data *this) | |||
608 | | BF_GPMI_CTRL0_CS(chip, this) | 607 | | BF_GPMI_CTRL0_CS(chip, this) |
609 | | BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this) | 608 | | BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this) |
610 | | BF_GPMI_CTRL0_ADDRESS(address) | 609 | | BF_GPMI_CTRL0_ADDRESS(address) |
611 | | BF_GPMI_CTRL0_XFER_COUNT(this->upper_len); | 610 | | BF_GPMI_CTRL0_XFER_COUNT(len); |
612 | pio[1] = 0; | 611 | pio[1] = 0; |
613 | desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)pio, | 612 | desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)pio, |
614 | ARRAY_SIZE(pio), DMA_TRANS_NONE, 0); | 613 | ARRAY_SIZE(pio), DMA_TRANS_NONE, 0); |
@@ -616,7 +615,7 @@ int gpmi_send_data(struct gpmi_nand_data *this) | |||
616 | return -EINVAL; | 615 | return -EINVAL; |
617 | 616 | ||
618 | /* [2] send DMA request */ | 617 | /* [2] send DMA request */ |
619 | prepare_data_dma(this, DMA_TO_DEVICE); | 618 | prepare_data_dma(this, buf, len, DMA_TO_DEVICE); |
620 | desc = dmaengine_prep_slave_sg(channel, &this->data_sgl, | 619 | desc = dmaengine_prep_slave_sg(channel, &this->data_sgl, |
621 | 1, DMA_MEM_TO_DEV, | 620 | 1, DMA_MEM_TO_DEV, |
622 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 621 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
@@ -624,16 +623,21 @@ int gpmi_send_data(struct gpmi_nand_data *this) | |||
624 | return -EINVAL; | 623 | return -EINVAL; |
625 | 624 | ||
626 | /* [3] submit the DMA */ | 625 | /* [3] submit the DMA */ |
627 | set_dma_type(this, DMA_FOR_WRITE_DATA); | 626 | ret = start_dma_without_bch_irq(this, desc); |
628 | return start_dma_without_bch_irq(this, desc); | 627 | |
628 | dma_unmap_sg(this->dev, &this->data_sgl, 1, DMA_TO_DEVICE); | ||
629 | |||
630 | return ret; | ||
629 | } | 631 | } |
630 | 632 | ||
631 | int gpmi_read_data(struct gpmi_nand_data *this) | 633 | int gpmi_read_data(struct gpmi_nand_data *this, void *buf, int len) |
632 | { | 634 | { |
633 | struct dma_async_tx_descriptor *desc; | 635 | struct dma_async_tx_descriptor *desc; |
634 | struct dma_chan *channel = get_dma_chan(this); | 636 | struct dma_chan *channel = get_dma_chan(this); |
635 | int chip = this->current_chip; | 637 | int chip = this->current_chip; |
638 | int ret; | ||
636 | u32 pio[2]; | 639 | u32 pio[2]; |
640 | bool direct; | ||
637 | 641 | ||
638 | /* [1] : send PIO */ | 642 | /* [1] : send PIO */ |
639 | pio[0] = BF_GPMI_CTRL0_COMMAND_MODE(BV_GPMI_CTRL0_COMMAND_MODE__READ) | 643 | pio[0] = BF_GPMI_CTRL0_COMMAND_MODE(BV_GPMI_CTRL0_COMMAND_MODE__READ) |
@@ -641,7 +645,7 @@ int gpmi_read_data(struct gpmi_nand_data *this) | |||
641 | | BF_GPMI_CTRL0_CS(chip, this) | 645 | | BF_GPMI_CTRL0_CS(chip, this) |
642 | | BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this) | 646 | | BF_GPMI_CTRL0_LOCK_CS(LOCK_CS_ENABLE, this) |
643 | | BF_GPMI_CTRL0_ADDRESS(BV_GPMI_CTRL0_ADDRESS__NAND_DATA) | 647 | | BF_GPMI_CTRL0_ADDRESS(BV_GPMI_CTRL0_ADDRESS__NAND_DATA) |
644 | | BF_GPMI_CTRL0_XFER_COUNT(this->upper_len); | 648 | | BF_GPMI_CTRL0_XFER_COUNT(len); |
645 | pio[1] = 0; | 649 | pio[1] = 0; |
646 | desc = dmaengine_prep_slave_sg(channel, | 650 | desc = dmaengine_prep_slave_sg(channel, |
647 | (struct scatterlist *)pio, | 651 | (struct scatterlist *)pio, |
@@ -650,7 +654,7 @@ int gpmi_read_data(struct gpmi_nand_data *this) | |||
650 | return -EINVAL; | 654 | return -EINVAL; |
651 | 655 | ||
652 | /* [2] : send DMA request */ | 656 | /* [2] : send DMA request */ |
653 | prepare_data_dma(this, DMA_FROM_DEVICE); | 657 | direct = prepare_data_dma(this, buf, len, DMA_FROM_DEVICE); |
654 | desc = dmaengine_prep_slave_sg(channel, &this->data_sgl, | 658 | desc = dmaengine_prep_slave_sg(channel, &this->data_sgl, |
655 | 1, DMA_DEV_TO_MEM, | 659 | 1, DMA_DEV_TO_MEM, |
656 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 660 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
@@ -658,8 +662,14 @@ int gpmi_read_data(struct gpmi_nand_data *this) | |||
658 | return -EINVAL; | 662 | return -EINVAL; |
659 | 663 | ||
660 | /* [3] : submit the DMA */ | 664 | /* [3] : submit the DMA */ |
661 | set_dma_type(this, DMA_FOR_READ_DATA); | 665 | |
662 | return start_dma_without_bch_irq(this, desc); | 666 | ret = start_dma_without_bch_irq(this, desc); |
667 | |||
668 | dma_unmap_sg(this->dev, &this->data_sgl, 1, DMA_FROM_DEVICE); | ||
669 | if (!direct) | ||
670 | memcpy(buf, this->data_buffer_dma, len); | ||
671 | |||
672 | return ret; | ||
663 | } | 673 | } |
664 | 674 | ||
665 | int gpmi_send_page(struct gpmi_nand_data *this, | 675 | int gpmi_send_page(struct gpmi_nand_data *this, |
@@ -703,7 +713,6 @@ int gpmi_send_page(struct gpmi_nand_data *this, | |||
703 | if (!desc) | 713 | if (!desc) |
704 | return -EINVAL; | 714 | return -EINVAL; |
705 | 715 | ||
706 | set_dma_type(this, DMA_FOR_WRITE_ECC_PAGE); | ||
707 | return start_dma_with_bch_irq(this, desc); | 716 | return start_dma_with_bch_irq(this, desc); |
708 | } | 717 | } |
709 | 718 | ||
@@ -785,7 +794,6 @@ int gpmi_read_page(struct gpmi_nand_data *this, | |||
785 | return -EINVAL; | 794 | return -EINVAL; |
786 | 795 | ||
787 | /* [4] submit the DMA */ | 796 | /* [4] submit the DMA */ |
788 | set_dma_type(this, DMA_FOR_READ_ECC_PAGE); | ||
789 | return start_dma_with_bch_irq(this, desc); | 797 | return start_dma_with_bch_irq(this, desc); |
790 | } | 798 | } |
791 | 799 | ||
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c index c2597c8107a0..f6aa358a3452 100644 --- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | |||
@@ -198,17 +198,16 @@ static inline bool gpmi_check_ecc(struct gpmi_nand_data *this) | |||
198 | * | 198 | * |
199 | * We may have available oob space in this case. | 199 | * We may have available oob space in this case. |
200 | */ | 200 | */ |
201 | static int set_geometry_by_ecc_info(struct gpmi_nand_data *this) | 201 | static int set_geometry_by_ecc_info(struct gpmi_nand_data *this, |
202 | unsigned int ecc_strength, | ||
203 | unsigned int ecc_step) | ||
202 | { | 204 | { |
203 | struct bch_geometry *geo = &this->bch_geometry; | 205 | struct bch_geometry *geo = &this->bch_geometry; |
204 | struct nand_chip *chip = &this->nand; | 206 | struct nand_chip *chip = &this->nand; |
205 | struct mtd_info *mtd = nand_to_mtd(chip); | 207 | struct mtd_info *mtd = nand_to_mtd(chip); |
206 | unsigned int block_mark_bit_offset; | 208 | unsigned int block_mark_bit_offset; |
207 | 209 | ||
208 | if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0)) | 210 | switch (ecc_step) { |
209 | return -EINVAL; | ||
210 | |||
211 | switch (chip->ecc_step_ds) { | ||
212 | case SZ_512: | 211 | case SZ_512: |
213 | geo->gf_len = 13; | 212 | geo->gf_len = 13; |
214 | break; | 213 | break; |
@@ -221,8 +220,8 @@ static int set_geometry_by_ecc_info(struct gpmi_nand_data *this) | |||
221 | chip->ecc_strength_ds, chip->ecc_step_ds); | 220 | chip->ecc_strength_ds, chip->ecc_step_ds); |
222 | return -EINVAL; | 221 | return -EINVAL; |
223 | } | 222 | } |
224 | geo->ecc_chunk_size = chip->ecc_step_ds; | 223 | geo->ecc_chunk_size = ecc_step; |
225 | geo->ecc_strength = round_up(chip->ecc_strength_ds, 2); | 224 | geo->ecc_strength = round_up(ecc_strength, 2); |
226 | if (!gpmi_check_ecc(this)) | 225 | if (!gpmi_check_ecc(this)) |
227 | return -EINVAL; | 226 | return -EINVAL; |
228 | 227 | ||
@@ -230,7 +229,7 @@ static int set_geometry_by_ecc_info(struct gpmi_nand_data *this) | |||
230 | if (geo->ecc_chunk_size < mtd->oobsize) { | 229 | if (geo->ecc_chunk_size < mtd->oobsize) { |
231 | dev_err(this->dev, | 230 | dev_err(this->dev, |
232 | "unsupported nand chip. ecc size: %d, oob size : %d\n", | 231 | "unsupported nand chip. ecc size: %d, oob size : %d\n", |
233 | chip->ecc_step_ds, mtd->oobsize); | 232 | ecc_step, mtd->oobsize); |
234 | return -EINVAL; | 233 | return -EINVAL; |
235 | } | 234 | } |
236 | 235 | ||
@@ -423,9 +422,20 @@ static int legacy_set_geometry(struct gpmi_nand_data *this) | |||
423 | 422 | ||
424 | int common_nfc_set_geometry(struct gpmi_nand_data *this) | 423 | int common_nfc_set_geometry(struct gpmi_nand_data *this) |
425 | { | 424 | { |
425 | struct nand_chip *chip = &this->nand; | ||
426 | |||
427 | if (chip->ecc.strength > 0 && chip->ecc.size > 0) | ||
428 | return set_geometry_by_ecc_info(this, chip->ecc.strength, | ||
429 | chip->ecc.size); | ||
430 | |||
426 | if ((of_property_read_bool(this->dev->of_node, "fsl,use-minimum-ecc")) | 431 | if ((of_property_read_bool(this->dev->of_node, "fsl,use-minimum-ecc")) |
427 | || legacy_set_geometry(this)) | 432 | || legacy_set_geometry(this)) { |
428 | return set_geometry_by_ecc_info(this); | 433 | if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0)) |
434 | return -EINVAL; | ||
435 | |||
436 | return set_geometry_by_ecc_info(this, chip->ecc_strength_ds, | ||
437 | chip->ecc_step_ds); | ||
438 | } | ||
429 | 439 | ||
430 | return 0; | 440 | return 0; |
431 | } | 441 | } |
@@ -437,33 +447,32 @@ struct dma_chan *get_dma_chan(struct gpmi_nand_data *this) | |||
437 | } | 447 | } |
438 | 448 | ||
439 | /* Can we use the upper's buffer directly for DMA? */ | 449 | /* Can we use the upper's buffer directly for DMA? */ |
440 | void prepare_data_dma(struct gpmi_nand_data *this, enum dma_data_direction dr) | 450 | bool prepare_data_dma(struct gpmi_nand_data *this, const void *buf, int len, |
451 | enum dma_data_direction dr) | ||
441 | { | 452 | { |
442 | struct scatterlist *sgl = &this->data_sgl; | 453 | struct scatterlist *sgl = &this->data_sgl; |
443 | int ret; | 454 | int ret; |
444 | 455 | ||
445 | /* first try to map the upper buffer directly */ | 456 | /* first try to map the upper buffer directly */ |
446 | if (virt_addr_valid(this->upper_buf) && | 457 | if (virt_addr_valid(buf) && !object_is_on_stack(buf)) { |
447 | !object_is_on_stack(this->upper_buf)) { | 458 | sg_init_one(sgl, buf, len); |
448 | sg_init_one(sgl, this->upper_buf, this->upper_len); | ||
449 | ret = dma_map_sg(this->dev, sgl, 1, dr); | 459 | ret = dma_map_sg(this->dev, sgl, 1, dr); |
450 | if (ret == 0) | 460 | if (ret == 0) |
451 | goto map_fail; | 461 | goto map_fail; |
452 | 462 | ||
453 | this->direct_dma_map_ok = true; | 463 | return true; |
454 | return; | ||
455 | } | 464 | } |
456 | 465 | ||
457 | map_fail: | 466 | map_fail: |
458 | /* We have to use our own DMA buffer. */ | 467 | /* We have to use our own DMA buffer. */ |
459 | sg_init_one(sgl, this->data_buffer_dma, this->upper_len); | 468 | sg_init_one(sgl, this->data_buffer_dma, len); |
460 | 469 | ||
461 | if (dr == DMA_TO_DEVICE) | 470 | if (dr == DMA_TO_DEVICE) |
462 | memcpy(this->data_buffer_dma, this->upper_buf, this->upper_len); | 471 | memcpy(this->data_buffer_dma, buf, len); |
463 | 472 | ||
464 | dma_map_sg(this->dev, sgl, 1, dr); | 473 | dma_map_sg(this->dev, sgl, 1, dr); |
465 | 474 | ||
466 | this->direct_dma_map_ok = false; | 475 | return false; |
467 | } | 476 | } |
468 | 477 | ||
469 | /* This will be called after the DMA operation is finished. */ | 478 | /* This will be called after the DMA operation is finished. */ |
@@ -472,31 +481,6 @@ static void dma_irq_callback(void *param) | |||
472 | struct gpmi_nand_data *this = param; | 481 | struct gpmi_nand_data *this = param; |
473 | struct completion *dma_c = &this->dma_done; | 482 | struct completion *dma_c = &this->dma_done; |
474 | 483 | ||
475 | switch (this->dma_type) { | ||
476 | case DMA_FOR_COMMAND: | ||
477 | dma_unmap_sg(this->dev, &this->cmd_sgl, 1, DMA_TO_DEVICE); | ||
478 | break; | ||
479 | |||
480 | case DMA_FOR_READ_DATA: | ||
481 | dma_unmap_sg(this->dev, &this->data_sgl, 1, DMA_FROM_DEVICE); | ||
482 | if (this->direct_dma_map_ok == false) | ||
483 | memcpy(this->upper_buf, this->data_buffer_dma, | ||
484 | this->upper_len); | ||
485 | break; | ||
486 | |||
487 | case DMA_FOR_WRITE_DATA: | ||
488 | dma_unmap_sg(this->dev, &this->data_sgl, 1, DMA_TO_DEVICE); | ||
489 | break; | ||
490 | |||
491 | case DMA_FOR_READ_ECC_PAGE: | ||
492 | case DMA_FOR_WRITE_ECC_PAGE: | ||
493 | /* We have to wait the BCH interrupt to finish. */ | ||
494 | break; | ||
495 | |||
496 | default: | ||
497 | dev_err(this->dev, "in wrong DMA operation.\n"); | ||
498 | } | ||
499 | |||
500 | complete(dma_c); | 484 | complete(dma_c); |
501 | } | 485 | } |
502 | 486 | ||
@@ -516,8 +500,7 @@ int start_dma_without_bch_irq(struct gpmi_nand_data *this, | |||
516 | /* Wait for the interrupt from the DMA block. */ | 500 | /* Wait for the interrupt from the DMA block. */ |
517 | timeout = wait_for_completion_timeout(dma_c, msecs_to_jiffies(1000)); | 501 | timeout = wait_for_completion_timeout(dma_c, msecs_to_jiffies(1000)); |
518 | if (!timeout) { | 502 | if (!timeout) { |
519 | dev_err(this->dev, "DMA timeout, last DMA :%d\n", | 503 | dev_err(this->dev, "DMA timeout, last DMA\n"); |
520 | this->last_dma_type); | ||
521 | gpmi_dump_info(this); | 504 | gpmi_dump_info(this); |
522 | return -ETIMEDOUT; | 505 | return -ETIMEDOUT; |
523 | } | 506 | } |
@@ -546,8 +529,7 @@ int start_dma_with_bch_irq(struct gpmi_nand_data *this, | |||
546 | /* Wait for the interrupt from the BCH block. */ | 529 | /* Wait for the interrupt from the BCH block. */ |
547 | timeout = wait_for_completion_timeout(bch_c, msecs_to_jiffies(1000)); | 530 | timeout = wait_for_completion_timeout(bch_c, msecs_to_jiffies(1000)); |
548 | if (!timeout) { | 531 | if (!timeout) { |
549 | dev_err(this->dev, "BCH timeout, last DMA :%d\n", | 532 | dev_err(this->dev, "BCH timeout\n"); |
550 | this->last_dma_type); | ||
551 | gpmi_dump_info(this); | 533 | gpmi_dump_info(this); |
552 | return -ETIMEDOUT; | 534 | return -ETIMEDOUT; |
553 | } | 535 | } |
@@ -695,56 +677,6 @@ static void release_resources(struct gpmi_nand_data *this) | |||
695 | release_dma_channels(this); | 677 | release_dma_channels(this); |
696 | } | 678 | } |
697 | 679 | ||
698 | static int read_page_prepare(struct gpmi_nand_data *this, | ||
699 | void *destination, unsigned length, | ||
700 | void *alt_virt, dma_addr_t alt_phys, unsigned alt_size, | ||
701 | void **use_virt, dma_addr_t *use_phys) | ||
702 | { | ||
703 | struct device *dev = this->dev; | ||
704 | |||
705 | if (virt_addr_valid(destination)) { | ||
706 | dma_addr_t dest_phys; | ||
707 | |||
708 | dest_phys = dma_map_single(dev, destination, | ||
709 | length, DMA_FROM_DEVICE); | ||
710 | if (dma_mapping_error(dev, dest_phys)) { | ||
711 | if (alt_size < length) { | ||
712 | dev_err(dev, "Alternate buffer is too small\n"); | ||
713 | return -ENOMEM; | ||
714 | } | ||
715 | goto map_failed; | ||
716 | } | ||
717 | *use_virt = destination; | ||
718 | *use_phys = dest_phys; | ||
719 | this->direct_dma_map_ok = true; | ||
720 | return 0; | ||
721 | } | ||
722 | |||
723 | map_failed: | ||
724 | *use_virt = alt_virt; | ||
725 | *use_phys = alt_phys; | ||
726 | this->direct_dma_map_ok = false; | ||
727 | return 0; | ||
728 | } | ||
729 | |||
730 | static inline void read_page_end(struct gpmi_nand_data *this, | ||
731 | void *destination, unsigned length, | ||
732 | void *alt_virt, dma_addr_t alt_phys, unsigned alt_size, | ||
733 | void *used_virt, dma_addr_t used_phys) | ||
734 | { | ||
735 | if (this->direct_dma_map_ok) | ||
736 | dma_unmap_single(this->dev, used_phys, length, DMA_FROM_DEVICE); | ||
737 | } | ||
738 | |||
739 | static inline void read_page_swap_end(struct gpmi_nand_data *this, | ||
740 | void *destination, unsigned length, | ||
741 | void *alt_virt, dma_addr_t alt_phys, unsigned alt_size, | ||
742 | void *used_virt, dma_addr_t used_phys) | ||
743 | { | ||
744 | if (!this->direct_dma_map_ok) | ||
745 | memcpy(destination, alt_virt, length); | ||
746 | } | ||
747 | |||
748 | static int send_page_prepare(struct gpmi_nand_data *this, | 680 | static int send_page_prepare(struct gpmi_nand_data *this, |
749 | const void *source, unsigned length, | 681 | const void *source, unsigned length, |
750 | void *alt_virt, dma_addr_t alt_phys, unsigned alt_size, | 682 | void *alt_virt, dma_addr_t alt_phys, unsigned alt_size, |
@@ -946,10 +878,8 @@ static void gpmi_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | |||
946 | struct gpmi_nand_data *this = nand_get_controller_data(chip); | 878 | struct gpmi_nand_data *this = nand_get_controller_data(chip); |
947 | 879 | ||
948 | dev_dbg(this->dev, "len is %d\n", len); | 880 | dev_dbg(this->dev, "len is %d\n", len); |
949 | this->upper_buf = buf; | ||
950 | this->upper_len = len; | ||
951 | 881 | ||
952 | gpmi_read_data(this); | 882 | gpmi_read_data(this, buf, len); |
953 | } | 883 | } |
954 | 884 | ||
955 | static void gpmi_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | 885 | static void gpmi_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) |
@@ -958,10 +888,8 @@ static void gpmi_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | |||
958 | struct gpmi_nand_data *this = nand_get_controller_data(chip); | 888 | struct gpmi_nand_data *this = nand_get_controller_data(chip); |
959 | 889 | ||
960 | dev_dbg(this->dev, "len is %d\n", len); | 890 | dev_dbg(this->dev, "len is %d\n", len); |
961 | this->upper_buf = (uint8_t *)buf; | ||
962 | this->upper_len = len; | ||
963 | 891 | ||
964 | gpmi_send_data(this); | 892 | gpmi_send_data(this, buf, len); |
965 | } | 893 | } |
966 | 894 | ||
967 | static uint8_t gpmi_read_byte(struct mtd_info *mtd) | 895 | static uint8_t gpmi_read_byte(struct mtd_info *mtd) |
@@ -1031,44 +959,46 @@ static int gpmi_ecc_read_page_data(struct nand_chip *chip, | |||
1031 | struct mtd_info *mtd = nand_to_mtd(chip); | 959 | struct mtd_info *mtd = nand_to_mtd(chip); |
1032 | void *payload_virt; | 960 | void *payload_virt; |
1033 | dma_addr_t payload_phys; | 961 | dma_addr_t payload_phys; |
1034 | void *auxiliary_virt; | ||
1035 | dma_addr_t auxiliary_phys; | ||
1036 | unsigned int i; | 962 | unsigned int i; |
1037 | unsigned char *status; | 963 | unsigned char *status; |
1038 | unsigned int max_bitflips = 0; | 964 | unsigned int max_bitflips = 0; |
1039 | int ret; | 965 | int ret; |
966 | bool direct = false; | ||
1040 | 967 | ||
1041 | dev_dbg(this->dev, "page number is : %d\n", page); | 968 | dev_dbg(this->dev, "page number is : %d\n", page); |
1042 | ret = read_page_prepare(this, buf, nfc_geo->payload_size, | 969 | |
1043 | this->payload_virt, this->payload_phys, | 970 | payload_virt = this->payload_virt; |
1044 | nfc_geo->payload_size, | 971 | payload_phys = this->payload_phys; |
1045 | &payload_virt, &payload_phys); | 972 | |
1046 | if (ret) { | 973 | if (virt_addr_valid(buf)) { |
1047 | dev_err(this->dev, "Inadequate DMA buffer\n"); | 974 | dma_addr_t dest_phys; |
1048 | ret = -ENOMEM; | 975 | |
1049 | return ret; | 976 | dest_phys = dma_map_single(this->dev, buf, nfc_geo->payload_size, |
977 | DMA_FROM_DEVICE); | ||
978 | if (!dma_mapping_error(this->dev, dest_phys)) { | ||
979 | payload_virt = buf; | ||
980 | payload_phys = dest_phys; | ||
981 | direct = true; | ||
982 | } | ||
1050 | } | 983 | } |
1051 | auxiliary_virt = this->auxiliary_virt; | ||
1052 | auxiliary_phys = this->auxiliary_phys; | ||
1053 | 984 | ||
1054 | /* go! */ | 985 | /* go! */ |
1055 | ret = gpmi_read_page(this, payload_phys, auxiliary_phys); | 986 | ret = gpmi_read_page(this, payload_phys, this->auxiliary_phys); |
1056 | read_page_end(this, buf, nfc_geo->payload_size, | 987 | |
1057 | this->payload_virt, this->payload_phys, | 988 | if (direct) |
1058 | nfc_geo->payload_size, | 989 | dma_unmap_single(this->dev, payload_phys, nfc_geo->payload_size, |
1059 | payload_virt, payload_phys); | 990 | DMA_FROM_DEVICE); |
991 | |||
1060 | if (ret) { | 992 | if (ret) { |
1061 | dev_err(this->dev, "Error in ECC-based read: %d\n", ret); | 993 | dev_err(this->dev, "Error in ECC-based read: %d\n", ret); |
1062 | return ret; | 994 | return ret; |
1063 | } | 995 | } |
1064 | 996 | ||
1065 | /* Loop over status bytes, accumulating ECC status. */ | 997 | /* Loop over status bytes, accumulating ECC status. */ |
1066 | status = auxiliary_virt + nfc_geo->auxiliary_status_offset; | 998 | status = this->auxiliary_virt + nfc_geo->auxiliary_status_offset; |
1067 | 999 | ||
1068 | read_page_swap_end(this, buf, nfc_geo->payload_size, | 1000 | if (!direct) |
1069 | this->payload_virt, this->payload_phys, | 1001 | memcpy(buf, this->payload_virt, nfc_geo->payload_size); |
1070 | nfc_geo->payload_size, | ||
1071 | payload_virt, payload_phys); | ||
1072 | 1002 | ||
1073 | for (i = 0; i < nfc_geo->ecc_chunk_count; i++, status++) { | 1003 | for (i = 0; i < nfc_geo->ecc_chunk_count; i++, status++) { |
1074 | if ((*status == STATUS_GOOD) || (*status == STATUS_ERASED)) | 1004 | if ((*status == STATUS_GOOD) || (*status == STATUS_ERASED)) |
@@ -1123,7 +1053,7 @@ static int gpmi_ecc_read_page_data(struct nand_chip *chip, | |||
1123 | buf + i * nfc_geo->ecc_chunk_size, | 1053 | buf + i * nfc_geo->ecc_chunk_size, |
1124 | nfc_geo->ecc_chunk_size, | 1054 | nfc_geo->ecc_chunk_size, |
1125 | eccbuf, eccbytes, | 1055 | eccbuf, eccbytes, |
1126 | auxiliary_virt, | 1056 | this->auxiliary_virt, |
1127 | nfc_geo->metadata_size, | 1057 | nfc_geo->metadata_size, |
1128 | nfc_geo->ecc_strength); | 1058 | nfc_geo->ecc_strength); |
1129 | } else { | 1059 | } else { |
@@ -1151,7 +1081,7 @@ static int gpmi_ecc_read_page_data(struct nand_chip *chip, | |||
1151 | } | 1081 | } |
1152 | 1082 | ||
1153 | /* handle the block mark swapping */ | 1083 | /* handle the block mark swapping */ |
1154 | block_mark_swapping(this, buf, auxiliary_virt); | 1084 | block_mark_swapping(this, buf, this->auxiliary_virt); |
1155 | 1085 | ||
1156 | if (oob_required) { | 1086 | if (oob_required) { |
1157 | /* | 1087 | /* |
@@ -1165,7 +1095,7 @@ static int gpmi_ecc_read_page_data(struct nand_chip *chip, | |||
1165 | * the block mark. | 1095 | * the block mark. |
1166 | */ | 1096 | */ |
1167 | memset(chip->oob_poi, ~0, mtd->oobsize); | 1097 | memset(chip->oob_poi, ~0, mtd->oobsize); |
1168 | chip->oob_poi[0] = ((uint8_t *) auxiliary_virt)[0]; | 1098 | chip->oob_poi[0] = ((uint8_t *)this->auxiliary_virt)[0]; |
1169 | } | 1099 | } |
1170 | 1100 | ||
1171 | return max_bitflips; | 1101 | return max_bitflips; |
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h index 62fde59b995f..6aa10d6962d6 100644 --- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.h | |||
@@ -77,15 +77,6 @@ struct boot_rom_geometry { | |||
77 | unsigned int search_area_stride_exponent; | 77 | unsigned int search_area_stride_exponent; |
78 | }; | 78 | }; |
79 | 79 | ||
80 | /* DMA operations types */ | ||
81 | enum dma_ops_type { | ||
82 | DMA_FOR_COMMAND = 1, | ||
83 | DMA_FOR_READ_DATA, | ||
84 | DMA_FOR_WRITE_DATA, | ||
85 | DMA_FOR_READ_ECC_PAGE, | ||
86 | DMA_FOR_WRITE_ECC_PAGE | ||
87 | }; | ||
88 | |||
89 | enum gpmi_type { | 80 | enum gpmi_type { |
90 | IS_MX23, | 81 | IS_MX23, |
91 | IS_MX28, | 82 | IS_MX28, |
@@ -150,13 +141,6 @@ struct gpmi_nand_data { | |||
150 | int current_chip; | 141 | int current_chip; |
151 | unsigned int command_length; | 142 | unsigned int command_length; |
152 | 143 | ||
153 | /* passed from upper layer */ | ||
154 | uint8_t *upper_buf; | ||
155 | int upper_len; | ||
156 | |||
157 | /* for DMA operations */ | ||
158 | bool direct_dma_map_ok; | ||
159 | |||
160 | struct scatterlist cmd_sgl; | 144 | struct scatterlist cmd_sgl; |
161 | char *cmd_buffer; | 145 | char *cmd_buffer; |
162 | 146 | ||
@@ -178,8 +162,6 @@ struct gpmi_nand_data { | |||
178 | /* DMA channels */ | 162 | /* DMA channels */ |
179 | #define DMA_CHANS 8 | 163 | #define DMA_CHANS 8 |
180 | struct dma_chan *dma_chans[DMA_CHANS]; | 164 | struct dma_chan *dma_chans[DMA_CHANS]; |
181 | enum dma_ops_type last_dma_type; | ||
182 | enum dma_ops_type dma_type; | ||
183 | struct completion dma_done; | 165 | struct completion dma_done; |
184 | 166 | ||
185 | /* private */ | 167 | /* private */ |
@@ -189,7 +171,7 @@ struct gpmi_nand_data { | |||
189 | /* Common Services */ | 171 | /* Common Services */ |
190 | int common_nfc_set_geometry(struct gpmi_nand_data *); | 172 | int common_nfc_set_geometry(struct gpmi_nand_data *); |
191 | struct dma_chan *get_dma_chan(struct gpmi_nand_data *); | 173 | struct dma_chan *get_dma_chan(struct gpmi_nand_data *); |
192 | void prepare_data_dma(struct gpmi_nand_data *, | 174 | bool prepare_data_dma(struct gpmi_nand_data *, const void *buf, int len, |
193 | enum dma_data_direction dr); | 175 | enum dma_data_direction dr); |
194 | int start_dma_without_bch_irq(struct gpmi_nand_data *, | 176 | int start_dma_without_bch_irq(struct gpmi_nand_data *, |
195 | struct dma_async_tx_descriptor *); | 177 | struct dma_async_tx_descriptor *); |
@@ -208,8 +190,9 @@ int gpmi_disable_clk(struct gpmi_nand_data *this); | |||
208 | int gpmi_setup_data_interface(struct mtd_info *mtd, int chipnr, | 190 | int gpmi_setup_data_interface(struct mtd_info *mtd, int chipnr, |
209 | const struct nand_data_interface *conf); | 191 | const struct nand_data_interface *conf); |
210 | void gpmi_nfc_apply_timings(struct gpmi_nand_data *this); | 192 | void gpmi_nfc_apply_timings(struct gpmi_nand_data *this); |
211 | int gpmi_read_data(struct gpmi_nand_data *); | 193 | int gpmi_read_data(struct gpmi_nand_data *, void *buf, int len); |
212 | int gpmi_send_data(struct gpmi_nand_data *); | 194 | int gpmi_send_data(struct gpmi_nand_data *, const void *buf, int len); |
195 | |||
213 | int gpmi_send_page(struct gpmi_nand_data *, | 196 | int gpmi_send_page(struct gpmi_nand_data *, |
214 | dma_addr_t payload, dma_addr_t auxiliary); | 197 | dma_addr_t payload, dma_addr_t auxiliary); |
215 | int gpmi_read_page(struct gpmi_nand_data *, | 198 | int gpmi_read_page(struct gpmi_nand_data *, |
diff --git a/drivers/mtd/nand/raw/hisi504_nand.c b/drivers/mtd/nand/raw/hisi504_nand.c index 27558a67fa41..a1e009c8e556 100644 --- a/drivers/mtd/nand/raw/hisi504_nand.c +++ b/drivers/mtd/nand/raw/hisi504_nand.c | |||
@@ -731,23 +731,19 @@ static int hisi_nfc_probe(struct platform_device *pdev) | |||
731 | irq = platform_get_irq(pdev, 0); | 731 | irq = platform_get_irq(pdev, 0); |
732 | if (irq < 0) { | 732 | if (irq < 0) { |
733 | dev_err(dev, "no IRQ resource defined\n"); | 733 | dev_err(dev, "no IRQ resource defined\n"); |
734 | ret = -ENXIO; | 734 | return -ENXIO; |
735 | goto err_res; | ||
736 | } | 735 | } |
737 | 736 | ||
738 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 737 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
739 | host->iobase = devm_ioremap_resource(dev, res); | 738 | host->iobase = devm_ioremap_resource(dev, res); |
740 | if (IS_ERR(host->iobase)) { | 739 | if (IS_ERR(host->iobase)) |
741 | ret = PTR_ERR(host->iobase); | 740 | return PTR_ERR(host->iobase); |
742 | goto err_res; | ||
743 | } | ||
744 | 741 | ||
745 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 742 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
746 | host->mmio = devm_ioremap_resource(dev, res); | 743 | host->mmio = devm_ioremap_resource(dev, res); |
747 | if (IS_ERR(host->mmio)) { | 744 | if (IS_ERR(host->mmio)) { |
748 | ret = PTR_ERR(host->mmio); | ||
749 | dev_err(dev, "devm_ioremap_resource[1] fail\n"); | 745 | dev_err(dev, "devm_ioremap_resource[1] fail\n"); |
750 | goto err_res; | 746 | return PTR_ERR(host->mmio); |
751 | } | 747 | } |
752 | 748 | ||
753 | mtd->name = "hisi_nand"; | 749 | mtd->name = "hisi_nand"; |
@@ -770,19 +766,17 @@ static int hisi_nfc_probe(struct platform_device *pdev) | |||
770 | ret = devm_request_irq(dev, irq, hinfc_irq_handle, 0x0, "nandc", host); | 766 | ret = devm_request_irq(dev, irq, hinfc_irq_handle, 0x0, "nandc", host); |
771 | if (ret) { | 767 | if (ret) { |
772 | dev_err(dev, "failed to request IRQ\n"); | 768 | dev_err(dev, "failed to request IRQ\n"); |
773 | goto err_res; | 769 | return ret; |
774 | } | 770 | } |
775 | 771 | ||
776 | ret = nand_scan_ident(mtd, max_chips, NULL); | 772 | ret = nand_scan_ident(mtd, max_chips, NULL); |
777 | if (ret) | 773 | if (ret) |
778 | goto err_res; | 774 | return ret; |
779 | 775 | ||
780 | host->buffer = dmam_alloc_coherent(dev, mtd->writesize + mtd->oobsize, | 776 | host->buffer = dmam_alloc_coherent(dev, mtd->writesize + mtd->oobsize, |
781 | &host->dma_buffer, GFP_KERNEL); | 777 | &host->dma_buffer, GFP_KERNEL); |
782 | if (!host->buffer) { | 778 | if (!host->buffer) |
783 | ret = -ENOMEM; | 779 | return -ENOMEM; |
784 | goto err_res; | ||
785 | } | ||
786 | 780 | ||
787 | host->dma_oob = host->dma_buffer + mtd->writesize; | 781 | host->dma_oob = host->dma_buffer + mtd->writesize; |
788 | memset(host->buffer, 0xff, mtd->writesize + mtd->oobsize); | 782 | memset(host->buffer, 0xff, mtd->writesize + mtd->oobsize); |
@@ -798,8 +792,7 @@ static int hisi_nfc_probe(struct platform_device *pdev) | |||
798 | */ | 792 | */ |
799 | default: | 793 | default: |
800 | dev_err(dev, "NON-2KB page size nand flash\n"); | 794 | dev_err(dev, "NON-2KB page size nand flash\n"); |
801 | ret = -EINVAL; | 795 | return -EINVAL; |
802 | goto err_res; | ||
803 | } | 796 | } |
804 | hinfc_write(host, flag, HINFC504_CON); | 797 | hinfc_write(host, flag, HINFC504_CON); |
805 | 798 | ||
@@ -809,21 +802,17 @@ static int hisi_nfc_probe(struct platform_device *pdev) | |||
809 | ret = nand_scan_tail(mtd); | 802 | ret = nand_scan_tail(mtd); |
810 | if (ret) { | 803 | if (ret) { |
811 | dev_err(dev, "nand_scan_tail failed: %d\n", ret); | 804 | dev_err(dev, "nand_scan_tail failed: %d\n", ret); |
812 | goto err_res; | 805 | return ret; |
813 | } | 806 | } |
814 | 807 | ||
815 | ret = mtd_device_register(mtd, NULL, 0); | 808 | ret = mtd_device_register(mtd, NULL, 0); |
816 | if (ret) { | 809 | if (ret) { |
817 | dev_err(dev, "Err MTD partition=%d\n", ret); | 810 | dev_err(dev, "Err MTD partition=%d\n", ret); |
818 | goto err_mtd; | 811 | nand_cleanup(chip); |
812 | return ret; | ||
819 | } | 813 | } |
820 | 814 | ||
821 | return 0; | 815 | return 0; |
822 | |||
823 | err_mtd: | ||
824 | nand_release(mtd); | ||
825 | err_res: | ||
826 | return ret; | ||
827 | } | 816 | } |
828 | 817 | ||
829 | static int hisi_nfc_remove(struct platform_device *pdev) | 818 | static int hisi_nfc_remove(struct platform_device *pdev) |
diff --git a/drivers/mtd/nand/raw/lpc32xx_mlc.c b/drivers/mtd/nand/raw/lpc32xx_mlc.c index e357948a7505..052d123a8304 100644 --- a/drivers/mtd/nand/raw/lpc32xx_mlc.c +++ b/drivers/mtd/nand/raw/lpc32xx_mlc.c | |||
@@ -673,7 +673,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
673 | host->io_base = devm_ioremap_resource(&pdev->dev, rc); | 673 | host->io_base = devm_ioremap_resource(&pdev->dev, rc); |
674 | if (IS_ERR(host->io_base)) | 674 | if (IS_ERR(host->io_base)) |
675 | return PTR_ERR(host->io_base); | 675 | return PTR_ERR(host->io_base); |
676 | 676 | ||
677 | host->io_base_phy = rc->start; | 677 | host->io_base_phy = rc->start; |
678 | 678 | ||
679 | nand_chip = &host->nand_chip; | 679 | nand_chip = &host->nand_chip; |
@@ -706,11 +706,11 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
706 | if (IS_ERR(host->clk)) { | 706 | if (IS_ERR(host->clk)) { |
707 | dev_err(&pdev->dev, "Clock initialization failure\n"); | 707 | dev_err(&pdev->dev, "Clock initialization failure\n"); |
708 | res = -ENOENT; | 708 | res = -ENOENT; |
709 | goto err_exit1; | 709 | goto free_gpio; |
710 | } | 710 | } |
711 | res = clk_prepare_enable(host->clk); | 711 | res = clk_prepare_enable(host->clk); |
712 | if (res) | 712 | if (res) |
713 | goto err_put_clk; | 713 | goto put_clk; |
714 | 714 | ||
715 | nand_chip->cmd_ctrl = lpc32xx_nand_cmd_ctrl; | 715 | nand_chip->cmd_ctrl = lpc32xx_nand_cmd_ctrl; |
716 | nand_chip->dev_ready = lpc32xx_nand_device_ready; | 716 | nand_chip->dev_ready = lpc32xx_nand_device_ready; |
@@ -744,7 +744,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
744 | res = lpc32xx_dma_setup(host); | 744 | res = lpc32xx_dma_setup(host); |
745 | if (res) { | 745 | if (res) { |
746 | res = -EIO; | 746 | res = -EIO; |
747 | goto err_exit2; | 747 | goto unprepare_clk; |
748 | } | 748 | } |
749 | } | 749 | } |
750 | 750 | ||
@@ -754,18 +754,18 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
754 | */ | 754 | */ |
755 | res = nand_scan_ident(mtd, 1, NULL); | 755 | res = nand_scan_ident(mtd, 1, NULL); |
756 | if (res) | 756 | if (res) |
757 | goto err_exit3; | 757 | goto release_dma_chan; |
758 | 758 | ||
759 | host->dma_buf = devm_kzalloc(&pdev->dev, mtd->writesize, GFP_KERNEL); | 759 | host->dma_buf = devm_kzalloc(&pdev->dev, mtd->writesize, GFP_KERNEL); |
760 | if (!host->dma_buf) { | 760 | if (!host->dma_buf) { |
761 | res = -ENOMEM; | 761 | res = -ENOMEM; |
762 | goto err_exit3; | 762 | goto release_dma_chan; |
763 | } | 763 | } |
764 | 764 | ||
765 | host->dummy_buf = devm_kzalloc(&pdev->dev, mtd->writesize, GFP_KERNEL); | 765 | host->dummy_buf = devm_kzalloc(&pdev->dev, mtd->writesize, GFP_KERNEL); |
766 | if (!host->dummy_buf) { | 766 | if (!host->dummy_buf) { |
767 | res = -ENOMEM; | 767 | res = -ENOMEM; |
768 | goto err_exit3; | 768 | goto release_dma_chan; |
769 | } | 769 | } |
770 | 770 | ||
771 | nand_chip->ecc.mode = NAND_ECC_HW; | 771 | nand_chip->ecc.mode = NAND_ECC_HW; |
@@ -783,14 +783,14 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
783 | if (host->irq < 0) { | 783 | if (host->irq < 0) { |
784 | dev_err(&pdev->dev, "failed to get platform irq\n"); | 784 | dev_err(&pdev->dev, "failed to get platform irq\n"); |
785 | res = -EINVAL; | 785 | res = -EINVAL; |
786 | goto err_exit3; | 786 | goto release_dma_chan; |
787 | } | 787 | } |
788 | 788 | ||
789 | if (request_irq(host->irq, (irq_handler_t)&lpc3xxx_nand_irq, | 789 | if (request_irq(host->irq, (irq_handler_t)&lpc3xxx_nand_irq, |
790 | IRQF_TRIGGER_HIGH, DRV_NAME, host)) { | 790 | IRQF_TRIGGER_HIGH, DRV_NAME, host)) { |
791 | dev_err(&pdev->dev, "Error requesting NAND IRQ\n"); | 791 | dev_err(&pdev->dev, "Error requesting NAND IRQ\n"); |
792 | res = -ENXIO; | 792 | res = -ENXIO; |
793 | goto err_exit3; | 793 | goto release_dma_chan; |
794 | } | 794 | } |
795 | 795 | ||
796 | /* | 796 | /* |
@@ -799,27 +799,29 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
799 | */ | 799 | */ |
800 | res = nand_scan_tail(mtd); | 800 | res = nand_scan_tail(mtd); |
801 | if (res) | 801 | if (res) |
802 | goto err_exit4; | 802 | goto free_irq; |
803 | 803 | ||
804 | mtd->name = DRV_NAME; | 804 | mtd->name = DRV_NAME; |
805 | 805 | ||
806 | res = mtd_device_register(mtd, host->ncfg->parts, | 806 | res = mtd_device_register(mtd, host->ncfg->parts, |
807 | host->ncfg->num_parts); | 807 | host->ncfg->num_parts); |
808 | if (!res) | 808 | if (res) |
809 | return res; | 809 | goto cleanup_nand; |
810 | 810 | ||
811 | nand_release(mtd); | 811 | return 0; |
812 | 812 | ||
813 | err_exit4: | 813 | cleanup_nand: |
814 | nand_cleanup(nand_chip); | ||
815 | free_irq: | ||
814 | free_irq(host->irq, host); | 816 | free_irq(host->irq, host); |
815 | err_exit3: | 817 | release_dma_chan: |
816 | if (use_dma) | 818 | if (use_dma) |
817 | dma_release_channel(host->dma_chan); | 819 | dma_release_channel(host->dma_chan); |
818 | err_exit2: | 820 | unprepare_clk: |
819 | clk_disable_unprepare(host->clk); | 821 | clk_disable_unprepare(host->clk); |
820 | err_put_clk: | 822 | put_clk: |
821 | clk_put(host->clk); | 823 | clk_put(host->clk); |
822 | err_exit1: | 824 | free_gpio: |
823 | lpc32xx_wp_enable(host); | 825 | lpc32xx_wp_enable(host); |
824 | gpio_free(host->ncfg->wp_gpio); | 826 | gpio_free(host->ncfg->wp_gpio); |
825 | 827 | ||
diff --git a/drivers/mtd/nand/raw/lpc32xx_slc.c b/drivers/mtd/nand/raw/lpc32xx_slc.c index 5f7cc6da0a7f..42820aa1abab 100644 --- a/drivers/mtd/nand/raw/lpc32xx_slc.c +++ b/drivers/mtd/nand/raw/lpc32xx_slc.c | |||
@@ -831,11 +831,11 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
831 | if (IS_ERR(host->clk)) { | 831 | if (IS_ERR(host->clk)) { |
832 | dev_err(&pdev->dev, "Clock failure\n"); | 832 | dev_err(&pdev->dev, "Clock failure\n"); |
833 | res = -ENOENT; | 833 | res = -ENOENT; |
834 | goto err_exit1; | 834 | goto enable_wp; |
835 | } | 835 | } |
836 | res = clk_prepare_enable(host->clk); | 836 | res = clk_prepare_enable(host->clk); |
837 | if (res) | 837 | if (res) |
838 | goto err_exit1; | 838 | goto enable_wp; |
839 | 839 | ||
840 | /* Set NAND IO addresses and command/ready functions */ | 840 | /* Set NAND IO addresses and command/ready functions */ |
841 | chip->IO_ADDR_R = SLC_DATA(host->io_base); | 841 | chip->IO_ADDR_R = SLC_DATA(host->io_base); |
@@ -874,19 +874,19 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
874 | GFP_KERNEL); | 874 | GFP_KERNEL); |
875 | if (host->data_buf == NULL) { | 875 | if (host->data_buf == NULL) { |
876 | res = -ENOMEM; | 876 | res = -ENOMEM; |
877 | goto err_exit2; | 877 | goto unprepare_clk; |
878 | } | 878 | } |
879 | 879 | ||
880 | res = lpc32xx_nand_dma_setup(host); | 880 | res = lpc32xx_nand_dma_setup(host); |
881 | if (res) { | 881 | if (res) { |
882 | res = -EIO; | 882 | res = -EIO; |
883 | goto err_exit2; | 883 | goto unprepare_clk; |
884 | } | 884 | } |
885 | 885 | ||
886 | /* Find NAND device */ | 886 | /* Find NAND device */ |
887 | res = nand_scan_ident(mtd, 1, NULL); | 887 | res = nand_scan_ident(mtd, 1, NULL); |
888 | if (res) | 888 | if (res) |
889 | goto err_exit3; | 889 | goto release_dma; |
890 | 890 | ||
891 | /* OOB and ECC CPU and DMA work areas */ | 891 | /* OOB and ECC CPU and DMA work areas */ |
892 | host->ecc_buf = (uint32_t *)(host->data_buf + LPC32XX_DMA_DATA_SIZE); | 892 | host->ecc_buf = (uint32_t *)(host->data_buf + LPC32XX_DMA_DATA_SIZE); |
@@ -920,21 +920,23 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
920 | */ | 920 | */ |
921 | res = nand_scan_tail(mtd); | 921 | res = nand_scan_tail(mtd); |
922 | if (res) | 922 | if (res) |
923 | goto err_exit3; | 923 | goto release_dma; |
924 | 924 | ||
925 | mtd->name = "nxp_lpc3220_slc"; | 925 | mtd->name = "nxp_lpc3220_slc"; |
926 | res = mtd_device_register(mtd, host->ncfg->parts, | 926 | res = mtd_device_register(mtd, host->ncfg->parts, |
927 | host->ncfg->num_parts); | 927 | host->ncfg->num_parts); |
928 | if (!res) | 928 | if (res) |
929 | return res; | 929 | goto cleanup_nand; |
930 | 930 | ||
931 | nand_release(mtd); | 931 | return 0; |
932 | 932 | ||
933 | err_exit3: | 933 | cleanup_nand: |
934 | nand_cleanup(chip); | ||
935 | release_dma: | ||
934 | dma_release_channel(host->dma_chan); | 936 | dma_release_channel(host->dma_chan); |
935 | err_exit2: | 937 | unprepare_clk: |
936 | clk_disable_unprepare(host->clk); | 938 | clk_disable_unprepare(host->clk); |
937 | err_exit1: | 939 | enable_wp: |
938 | lpc32xx_wp_enable(host); | 940 | lpc32xx_wp_enable(host); |
939 | 941 | ||
940 | return res; | 942 | return res; |
diff --git a/drivers/mtd/nand/raw/mtk_ecc.c b/drivers/mtd/nand/raw/mtk_ecc.c index 40d86a861a70..6432bd70c3b3 100644 --- a/drivers/mtd/nand/raw/mtk_ecc.c +++ b/drivers/mtd/nand/raw/mtk_ecc.c | |||
@@ -500,7 +500,6 @@ static int mtk_ecc_probe(struct platform_device *pdev) | |||
500 | struct device *dev = &pdev->dev; | 500 | struct device *dev = &pdev->dev; |
501 | struct mtk_ecc *ecc; | 501 | struct mtk_ecc *ecc; |
502 | struct resource *res; | 502 | struct resource *res; |
503 | const struct of_device_id *of_ecc_id = NULL; | ||
504 | u32 max_eccdata_size; | 503 | u32 max_eccdata_size; |
505 | int irq, ret; | 504 | int irq, ret; |
506 | 505 | ||
@@ -508,11 +507,7 @@ static int mtk_ecc_probe(struct platform_device *pdev) | |||
508 | if (!ecc) | 507 | if (!ecc) |
509 | return -ENOMEM; | 508 | return -ENOMEM; |
510 | 509 | ||
511 | of_ecc_id = of_match_device(mtk_ecc_dt_match, &pdev->dev); | 510 | ecc->caps = of_device_get_match_data(dev); |
512 | if (!of_ecc_id) | ||
513 | return -ENODEV; | ||
514 | |||
515 | ecc->caps = of_ecc_id->data; | ||
516 | 511 | ||
517 | max_eccdata_size = ecc->caps->num_ecc_strength - 1; | 512 | max_eccdata_size = ecc->caps->num_ecc_strength - 1; |
518 | max_eccdata_size = ecc->caps->ecc_strength[max_eccdata_size]; | 513 | max_eccdata_size = ecc->caps->ecc_strength[max_eccdata_size]; |
diff --git a/drivers/mtd/nand/raw/mtk_nand.c b/drivers/mtd/nand/raw/mtk_nand.c index 6977da3a26aa..75c845adb050 100644 --- a/drivers/mtd/nand/raw/mtk_nand.c +++ b/drivers/mtd/nand/raw/mtk_nand.c | |||
@@ -1434,7 +1434,6 @@ static int mtk_nfc_probe(struct platform_device *pdev) | |||
1434 | struct device_node *np = dev->of_node; | 1434 | struct device_node *np = dev->of_node; |
1435 | struct mtk_nfc *nfc; | 1435 | struct mtk_nfc *nfc; |
1436 | struct resource *res; | 1436 | struct resource *res; |
1437 | const struct of_device_id *of_nfc_id = NULL; | ||
1438 | int ret, irq; | 1437 | int ret, irq; |
1439 | 1438 | ||
1440 | nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL); | 1439 | nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL); |
@@ -1452,6 +1451,7 @@ static int mtk_nfc_probe(struct platform_device *pdev) | |||
1452 | else if (!nfc->ecc) | 1451 | else if (!nfc->ecc) |
1453 | return -ENODEV; | 1452 | return -ENODEV; |
1454 | 1453 | ||
1454 | nfc->caps = of_device_get_match_data(dev); | ||
1455 | nfc->dev = dev; | 1455 | nfc->dev = dev; |
1456 | 1456 | ||
1457 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1457 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -1498,14 +1498,6 @@ static int mtk_nfc_probe(struct platform_device *pdev) | |||
1498 | goto clk_disable; | 1498 | goto clk_disable; |
1499 | } | 1499 | } |
1500 | 1500 | ||
1501 | of_nfc_id = of_match_device(mtk_nfc_id_table, &pdev->dev); | ||
1502 | if (!of_nfc_id) { | ||
1503 | ret = -ENODEV; | ||
1504 | goto clk_disable; | ||
1505 | } | ||
1506 | |||
1507 | nfc->caps = of_nfc_id->data; | ||
1508 | |||
1509 | platform_set_drvdata(pdev, nfc); | 1501 | platform_set_drvdata(pdev, nfc); |
1510 | 1502 | ||
1511 | ret = mtk_nfc_nand_chips_init(dev, nfc); | 1503 | ret = mtk_nfc_nand_chips_init(dev, nfc); |
diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c index f28c3a555861..10c4f9919850 100644 --- a/drivers/mtd/nand/raw/nand_base.c +++ b/drivers/mtd/nand/raw/nand_base.c | |||
@@ -2174,7 +2174,6 @@ static int nand_set_features_op(struct nand_chip *chip, u8 feature, | |||
2174 | struct mtd_info *mtd = nand_to_mtd(chip); | 2174 | struct mtd_info *mtd = nand_to_mtd(chip); |
2175 | const u8 *params = data; | 2175 | const u8 *params = data; |
2176 | int i, ret; | 2176 | int i, ret; |
2177 | u8 status; | ||
2178 | 2177 | ||
2179 | if (chip->exec_op) { | 2178 | if (chip->exec_op) { |
2180 | const struct nand_sdr_timings *sdr = | 2179 | const struct nand_sdr_timings *sdr = |
@@ -2188,26 +2187,18 @@ static int nand_set_features_op(struct nand_chip *chip, u8 feature, | |||
2188 | }; | 2187 | }; |
2189 | struct nand_operation op = NAND_OPERATION(instrs); | 2188 | struct nand_operation op = NAND_OPERATION(instrs); |
2190 | 2189 | ||
2191 | ret = nand_exec_op(chip, &op); | 2190 | return nand_exec_op(chip, &op); |
2192 | if (ret) | 2191 | } |
2193 | return ret; | ||
2194 | |||
2195 | ret = nand_status_op(chip, &status); | ||
2196 | if (ret) | ||
2197 | return ret; | ||
2198 | } else { | ||
2199 | chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES, feature, -1); | ||
2200 | for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i) | ||
2201 | chip->write_byte(mtd, params[i]); | ||
2202 | 2192 | ||
2203 | ret = chip->waitfunc(mtd, chip); | 2193 | chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES, feature, -1); |
2204 | if (ret < 0) | 2194 | for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i) |
2205 | return ret; | 2195 | chip->write_byte(mtd, params[i]); |
2206 | 2196 | ||
2207 | status = ret; | 2197 | ret = chip->waitfunc(mtd, chip); |
2208 | } | 2198 | if (ret < 0) |
2199 | return ret; | ||
2209 | 2200 | ||
2210 | if (status & NAND_STATUS_FAIL) | 2201 | if (ret & NAND_STATUS_FAIL) |
2211 | return -EIO; | 2202 | return -EIO; |
2212 | 2203 | ||
2213 | return 0; | 2204 | return 0; |
@@ -5092,6 +5083,37 @@ ext_out: | |||
5092 | } | 5083 | } |
5093 | 5084 | ||
5094 | /* | 5085 | /* |
5086 | * Recover data with bit-wise majority | ||
5087 | */ | ||
5088 | static void nand_bit_wise_majority(const void **srcbufs, | ||
5089 | unsigned int nsrcbufs, | ||
5090 | void *dstbuf, | ||
5091 | unsigned int bufsize) | ||
5092 | { | ||
5093 | int i, j, k; | ||
5094 | |||
5095 | for (i = 0; i < bufsize; i++) { | ||
5096 | u8 val = 0; | ||
5097 | |||
5098 | for (j = 0; j < 8; j++) { | ||
5099 | unsigned int cnt = 0; | ||
5100 | |||
5101 | for (k = 0; k < nsrcbufs; k++) { | ||
5102 | const u8 *srcbuf = srcbufs[k]; | ||
5103 | |||
5104 | if (srcbuf[i] & BIT(j)) | ||
5105 | cnt++; | ||
5106 | } | ||
5107 | |||
5108 | if (cnt > nsrcbufs / 2) | ||
5109 | val |= BIT(j); | ||
5110 | } | ||
5111 | |||
5112 | ((u8 *)dstbuf)[i] = val; | ||
5113 | } | ||
5114 | } | ||
5115 | |||
5116 | /* | ||
5095 | * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise. | 5117 | * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise. |
5096 | */ | 5118 | */ |
5097 | static int nand_flash_detect_onfi(struct nand_chip *chip) | 5119 | static int nand_flash_detect_onfi(struct nand_chip *chip) |
@@ -5107,7 +5129,7 @@ static int nand_flash_detect_onfi(struct nand_chip *chip) | |||
5107 | return 0; | 5129 | return 0; |
5108 | 5130 | ||
5109 | /* ONFI chip: allocate a buffer to hold its parameter page */ | 5131 | /* ONFI chip: allocate a buffer to hold its parameter page */ |
5110 | p = kzalloc(sizeof(*p), GFP_KERNEL); | 5132 | p = kzalloc((sizeof(*p) * 3), GFP_KERNEL); |
5111 | if (!p) | 5133 | if (!p) |
5112 | return -ENOMEM; | 5134 | return -ENOMEM; |
5113 | 5135 | ||
@@ -5118,21 +5140,32 @@ static int nand_flash_detect_onfi(struct nand_chip *chip) | |||
5118 | } | 5140 | } |
5119 | 5141 | ||
5120 | for (i = 0; i < 3; i++) { | 5142 | for (i = 0; i < 3; i++) { |
5121 | ret = nand_read_data_op(chip, p, sizeof(*p), true); | 5143 | ret = nand_read_data_op(chip, &p[i], sizeof(*p), true); |
5122 | if (ret) { | 5144 | if (ret) { |
5123 | ret = 0; | 5145 | ret = 0; |
5124 | goto free_onfi_param_page; | 5146 | goto free_onfi_param_page; |
5125 | } | 5147 | } |
5126 | 5148 | ||
5127 | if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 254) == | 5149 | if (onfi_crc16(ONFI_CRC_BASE, (u8 *)&p[i], 254) == |
5128 | le16_to_cpu(p->crc)) { | 5150 | le16_to_cpu(p->crc)) { |
5151 | if (i) | ||
5152 | memcpy(p, &p[i], sizeof(*p)); | ||
5129 | break; | 5153 | break; |
5130 | } | 5154 | } |
5131 | } | 5155 | } |
5132 | 5156 | ||
5133 | if (i == 3) { | 5157 | if (i == 3) { |
5134 | pr_err("Could not find valid ONFI parameter page; aborting\n"); | 5158 | const void *srcbufs[3] = {p, p + 1, p + 2}; |
5135 | goto free_onfi_param_page; | 5159 | |
5160 | pr_warn("Could not find a valid ONFI parameter page, trying bit-wise majority to recover it\n"); | ||
5161 | nand_bit_wise_majority(srcbufs, ARRAY_SIZE(srcbufs), p, | ||
5162 | sizeof(*p)); | ||
5163 | |||
5164 | if (onfi_crc16(ONFI_CRC_BASE, (u8 *)p, 254) != | ||
5165 | le16_to_cpu(p->crc)) { | ||
5166 | pr_err("ONFI parameter recovery failed, aborting\n"); | ||
5167 | goto free_onfi_param_page; | ||
5168 | } | ||
5136 | } | 5169 | } |
5137 | 5170 | ||
5138 | /* Check version */ | 5171 | /* Check version */ |
@@ -6635,24 +6668,26 @@ EXPORT_SYMBOL(nand_scan_tail); | |||
6635 | #endif | 6668 | #endif |
6636 | 6669 | ||
6637 | /** | 6670 | /** |
6638 | * nand_scan - [NAND Interface] Scan for the NAND device | 6671 | * nand_scan_with_ids - [NAND Interface] Scan for the NAND device |
6639 | * @mtd: MTD device structure | 6672 | * @mtd: MTD device structure |
6640 | * @maxchips: number of chips to scan for | 6673 | * @maxchips: number of chips to scan for |
6674 | * @ids: optional flash IDs table | ||
6641 | * | 6675 | * |
6642 | * This fills out all the uninitialized function pointers with the defaults. | 6676 | * This fills out all the uninitialized function pointers with the defaults. |
6643 | * The flash ID is read and the mtd/chip structures are filled with the | 6677 | * The flash ID is read and the mtd/chip structures are filled with the |
6644 | * appropriate values. | 6678 | * appropriate values. |
6645 | */ | 6679 | */ |
6646 | int nand_scan(struct mtd_info *mtd, int maxchips) | 6680 | int nand_scan_with_ids(struct mtd_info *mtd, int maxchips, |
6681 | struct nand_flash_dev *ids) | ||
6647 | { | 6682 | { |
6648 | int ret; | 6683 | int ret; |
6649 | 6684 | ||
6650 | ret = nand_scan_ident(mtd, maxchips, NULL); | 6685 | ret = nand_scan_ident(mtd, maxchips, ids); |
6651 | if (!ret) | 6686 | if (!ret) |
6652 | ret = nand_scan_tail(mtd); | 6687 | ret = nand_scan_tail(mtd); |
6653 | return ret; | 6688 | return ret; |
6654 | } | 6689 | } |
6655 | EXPORT_SYMBOL(nand_scan); | 6690 | EXPORT_SYMBOL(nand_scan_with_ids); |
6656 | 6691 | ||
6657 | /** | 6692 | /** |
6658 | * nand_cleanup - [NAND Interface] Free resources held by the NAND device | 6693 | * nand_cleanup - [NAND Interface] Free resources held by the NAND device |
diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index aad42812a353..d831a141a196 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c | |||
@@ -166,48 +166,15 @@ | |||
166 | #define NFC_MAX_CS 7 | 166 | #define NFC_MAX_CS 7 |
167 | 167 | ||
168 | /* | 168 | /* |
169 | * Ready/Busy detection type: describes the Ready/Busy detection modes | ||
170 | * | ||
171 | * @RB_NONE: no external detection available, rely on STATUS command | ||
172 | * and software timeouts | ||
173 | * @RB_NATIVE: use sunxi NAND controller Ready/Busy support. The Ready/Busy | ||
174 | * pin of the NAND flash chip must be connected to one of the | ||
175 | * native NAND R/B pins (those which can be muxed to the NAND | ||
176 | * Controller) | ||
177 | * @RB_GPIO: use a simple GPIO to handle Ready/Busy status. The Ready/Busy | ||
178 | * pin of the NAND flash chip must be connected to a GPIO capable | ||
179 | * pin. | ||
180 | */ | ||
181 | enum sunxi_nand_rb_type { | ||
182 | RB_NONE, | ||
183 | RB_NATIVE, | ||
184 | RB_GPIO, | ||
185 | }; | ||
186 | |||
187 | /* | ||
188 | * Ready/Busy structure: stores information related to Ready/Busy detection | ||
189 | * | ||
190 | * @type: the Ready/Busy detection mode | ||
191 | * @info: information related to the R/B detection mode. Either a gpio | ||
192 | * id or a native R/B id (those supported by the NAND controller). | ||
193 | */ | ||
194 | struct sunxi_nand_rb { | ||
195 | enum sunxi_nand_rb_type type; | ||
196 | union { | ||
197 | int gpio; | ||
198 | int nativeid; | ||
199 | } info; | ||
200 | }; | ||
201 | |||
202 | /* | ||
203 | * Chip Select structure: stores information related to NAND Chip Select | 169 | * Chip Select structure: stores information related to NAND Chip Select |
204 | * | 170 | * |
205 | * @cs: the NAND CS id used to communicate with a NAND Chip | 171 | * @cs: the NAND CS id used to communicate with a NAND Chip |
206 | * @rb: the Ready/Busy description | 172 | * @rb: the Ready/Busy pin ID. -1 means no R/B pin connected to the |
173 | * NFC | ||
207 | */ | 174 | */ |
208 | struct sunxi_nand_chip_sel { | 175 | struct sunxi_nand_chip_sel { |
209 | u8 cs; | 176 | u8 cs; |
210 | struct sunxi_nand_rb rb; | 177 | s8 rb; |
211 | }; | 178 | }; |
212 | 179 | ||
213 | /* | 180 | /* |
@@ -440,30 +407,19 @@ static int sunxi_nfc_dev_ready(struct mtd_info *mtd) | |||
440 | struct nand_chip *nand = mtd_to_nand(mtd); | 407 | struct nand_chip *nand = mtd_to_nand(mtd); |
441 | struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); | 408 | struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); |
442 | struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); | 409 | struct sunxi_nfc *nfc = to_sunxi_nfc(sunxi_nand->nand.controller); |
443 | struct sunxi_nand_rb *rb; | 410 | u32 mask; |
444 | int ret; | ||
445 | 411 | ||
446 | if (sunxi_nand->selected < 0) | 412 | if (sunxi_nand->selected < 0) |
447 | return 0; | 413 | return 0; |
448 | 414 | ||
449 | rb = &sunxi_nand->sels[sunxi_nand->selected].rb; | 415 | if (sunxi_nand->sels[sunxi_nand->selected].rb < 0) { |
450 | |||
451 | switch (rb->type) { | ||
452 | case RB_NATIVE: | ||
453 | ret = !!(readl(nfc->regs + NFC_REG_ST) & | ||
454 | NFC_RB_STATE(rb->info.nativeid)); | ||
455 | break; | ||
456 | case RB_GPIO: | ||
457 | ret = gpio_get_value(rb->info.gpio); | ||
458 | break; | ||
459 | case RB_NONE: | ||
460 | default: | ||
461 | ret = 0; | ||
462 | dev_err(nfc->dev, "cannot check R/B NAND status!\n"); | 416 | dev_err(nfc->dev, "cannot check R/B NAND status!\n"); |
463 | break; | 417 | return 0; |
464 | } | 418 | } |
465 | 419 | ||
466 | return ret; | 420 | mask = NFC_RB_STATE(sunxi_nand->sels[sunxi_nand->selected].rb); |
421 | |||
422 | return !!(readl(nfc->regs + NFC_REG_ST) & mask); | ||
467 | } | 423 | } |
468 | 424 | ||
469 | static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip) | 425 | static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip) |
@@ -488,12 +444,11 @@ static void sunxi_nfc_select_chip(struct mtd_info *mtd, int chip) | |||
488 | 444 | ||
489 | ctl |= NFC_CE_SEL(sel->cs) | NFC_EN | | 445 | ctl |= NFC_CE_SEL(sel->cs) | NFC_EN | |
490 | NFC_PAGE_SHIFT(nand->page_shift); | 446 | NFC_PAGE_SHIFT(nand->page_shift); |
491 | if (sel->rb.type == RB_NONE) { | 447 | if (sel->rb < 0) { |
492 | nand->dev_ready = NULL; | 448 | nand->dev_ready = NULL; |
493 | } else { | 449 | } else { |
494 | nand->dev_ready = sunxi_nfc_dev_ready; | 450 | nand->dev_ready = sunxi_nfc_dev_ready; |
495 | if (sel->rb.type == RB_NATIVE) | 451 | ctl |= NFC_RB_SEL(sel->rb); |
496 | ctl |= NFC_RB_SEL(sel->rb.info.nativeid); | ||
497 | } | 452 | } |
498 | 453 | ||
499 | writel(mtd->writesize, nfc->regs + NFC_REG_SPARE_AREA); | 454 | writel(mtd->writesize, nfc->regs + NFC_REG_SPARE_AREA); |
@@ -1946,26 +1901,10 @@ static int sunxi_nand_chip_init(struct device *dev, struct sunxi_nfc *nfc, | |||
1946 | chip->sels[i].cs = tmp; | 1901 | chip->sels[i].cs = tmp; |
1947 | 1902 | ||
1948 | if (!of_property_read_u32_index(np, "allwinner,rb", i, &tmp) && | 1903 | if (!of_property_read_u32_index(np, "allwinner,rb", i, &tmp) && |
1949 | tmp < 2) { | 1904 | tmp < 2) |
1950 | chip->sels[i].rb.type = RB_NATIVE; | 1905 | chip->sels[i].rb = tmp; |
1951 | chip->sels[i].rb.info.nativeid = tmp; | 1906 | else |
1952 | } else { | 1907 | chip->sels[i].rb = -1; |
1953 | ret = of_get_named_gpio(np, "rb-gpios", i); | ||
1954 | if (ret >= 0) { | ||
1955 | tmp = ret; | ||
1956 | chip->sels[i].rb.type = RB_GPIO; | ||
1957 | chip->sels[i].rb.info.gpio = tmp; | ||
1958 | ret = devm_gpio_request(dev, tmp, "nand-rb"); | ||
1959 | if (ret) | ||
1960 | return ret; | ||
1961 | |||
1962 | ret = gpio_direction_input(tmp); | ||
1963 | if (ret) | ||
1964 | return ret; | ||
1965 | } else { | ||
1966 | chip->sels[i].rb.type = RB_NONE; | ||
1967 | } | ||
1968 | } | ||
1969 | } | 1908 | } |
1970 | 1909 | ||
1971 | nand = &chip->nand; | 1910 | nand = &chip->nand; |
diff --git a/drivers/mtd/nftlmount.c b/drivers/mtd/nftlmount.c index a6fbfa4e5799..6281da3dadac 100644 --- a/drivers/mtd/nftlmount.c +++ b/drivers/mtd/nftlmount.c | |||
@@ -272,28 +272,37 @@ static int memcmpb(void *a, int c, int n) | |||
272 | static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int len, | 272 | static int check_free_sectors(struct NFTLrecord *nftl, unsigned int address, int len, |
273 | int check_oob) | 273 | int check_oob) |
274 | { | 274 | { |
275 | u8 buf[SECTORSIZE + nftl->mbd.mtd->oobsize]; | ||
276 | struct mtd_info *mtd = nftl->mbd.mtd; | 275 | struct mtd_info *mtd = nftl->mbd.mtd; |
277 | size_t retlen; | 276 | size_t retlen; |
278 | int i; | 277 | int i, ret; |
278 | u8 *buf; | ||
279 | |||
280 | buf = kmalloc(SECTORSIZE + mtd->oobsize, GFP_KERNEL); | ||
281 | if (!buf) | ||
282 | return -1; | ||
279 | 283 | ||
284 | ret = -1; | ||
280 | for (i = 0; i < len; i += SECTORSIZE) { | 285 | for (i = 0; i < len; i += SECTORSIZE) { |
281 | if (mtd_read(mtd, address, SECTORSIZE, &retlen, buf)) | 286 | if (mtd_read(mtd, address, SECTORSIZE, &retlen, buf)) |
282 | return -1; | 287 | goto out; |
283 | if (memcmpb(buf, 0xff, SECTORSIZE) != 0) | 288 | if (memcmpb(buf, 0xff, SECTORSIZE) != 0) |
284 | return -1; | 289 | goto out; |
285 | 290 | ||
286 | if (check_oob) { | 291 | if (check_oob) { |
287 | if(nftl_read_oob(mtd, address, mtd->oobsize, | 292 | if(nftl_read_oob(mtd, address, mtd->oobsize, |
288 | &retlen, &buf[SECTORSIZE]) < 0) | 293 | &retlen, &buf[SECTORSIZE]) < 0) |
289 | return -1; | 294 | goto out; |
290 | if (memcmpb(buf + SECTORSIZE, 0xff, mtd->oobsize) != 0) | 295 | if (memcmpb(buf + SECTORSIZE, 0xff, mtd->oobsize) != 0) |
291 | return -1; | 296 | goto out; |
292 | } | 297 | } |
293 | address += SECTORSIZE; | 298 | address += SECTORSIZE; |
294 | } | 299 | } |
295 | 300 | ||
296 | return 0; | 301 | ret = 0; |
302 | |||
303 | out: | ||
304 | kfree(buf); | ||
305 | return ret; | ||
297 | } | 306 | } |
298 | 307 | ||
299 | /* NFTL_format: format a Erase Unit by erasing ALL Erase Zones in the Erase Unit and | 308 | /* NFTL_format: format a Erase Unit by erasing ALL Erase Zones in the Erase Unit and |
diff --git a/drivers/mtd/spi-nor/Kconfig b/drivers/mtd/spi-nor/Kconfig index 89da88e59121..6cc9c929ff57 100644 --- a/drivers/mtd/spi-nor/Kconfig +++ b/drivers/mtd/spi-nor/Kconfig | |||
@@ -71,7 +71,7 @@ config SPI_FSL_QUADSPI | |||
71 | config SPI_HISI_SFC | 71 | config SPI_HISI_SFC |
72 | tristate "Hisilicon SPI-NOR Flash Controller(SFC)" | 72 | tristate "Hisilicon SPI-NOR Flash Controller(SFC)" |
73 | depends on ARCH_HISI || COMPILE_TEST | 73 | depends on ARCH_HISI || COMPILE_TEST |
74 | depends on HAS_IOMEM && HAS_DMA | 74 | depends on HAS_IOMEM |
75 | help | 75 | help |
76 | This enables support for hisilicon SPI-NOR flash controller. | 76 | This enables support for hisilicon SPI-NOR flash controller. |
77 | 77 | ||
@@ -90,7 +90,7 @@ config SPI_INTEL_SPI | |||
90 | tristate | 90 | tristate |
91 | 91 | ||
92 | config SPI_INTEL_SPI_PCI | 92 | config SPI_INTEL_SPI_PCI |
93 | tristate "Intel PCH/PCU SPI flash PCI driver" | 93 | tristate "Intel PCH/PCU SPI flash PCI driver (DANGEROUS)" |
94 | depends on X86 && PCI | 94 | depends on X86 && PCI |
95 | select SPI_INTEL_SPI | 95 | select SPI_INTEL_SPI |
96 | help | 96 | help |
@@ -106,7 +106,7 @@ config SPI_INTEL_SPI_PCI | |||
106 | will be called intel-spi-pci. | 106 | will be called intel-spi-pci. |
107 | 107 | ||
108 | config SPI_INTEL_SPI_PLATFORM | 108 | config SPI_INTEL_SPI_PLATFORM |
109 | tristate "Intel PCH/PCU SPI flash platform driver" | 109 | tristate "Intel PCH/PCU SPI flash platform driver (DANGEROUS)" |
110 | depends on X86 | 110 | depends on X86 |
111 | select SPI_INTEL_SPI | 111 | select SPI_INTEL_SPI |
112 | help | 112 | help |
diff --git a/drivers/mtd/spi-nor/cadence-quadspi.c b/drivers/mtd/spi-nor/cadence-quadspi.c index 5872f31eaa60..c3f7aaa5d18f 100644 --- a/drivers/mtd/spi-nor/cadence-quadspi.c +++ b/drivers/mtd/spi-nor/cadence-quadspi.c | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
19 | #include <linux/completion.h> | 19 | #include <linux/completion.h> |
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/dma-mapping.h> | ||
22 | #include <linux/dmaengine.h> | ||
21 | #include <linux/err.h> | 23 | #include <linux/err.h> |
22 | #include <linux/errno.h> | 24 | #include <linux/errno.h> |
23 | #include <linux/interrupt.h> | 25 | #include <linux/interrupt.h> |
@@ -73,6 +75,10 @@ struct cqspi_st { | |||
73 | struct completion transfer_complete; | 75 | struct completion transfer_complete; |
74 | struct mutex bus_mutex; | 76 | struct mutex bus_mutex; |
75 | 77 | ||
78 | struct dma_chan *rx_chan; | ||
79 | struct completion rx_dma_complete; | ||
80 | dma_addr_t mmap_phys_base; | ||
81 | |||
76 | int current_cs; | 82 | int current_cs; |
77 | int current_page_size; | 83 | int current_page_size; |
78 | int current_erase_size; | 84 | int current_erase_size; |
@@ -930,11 +936,75 @@ static ssize_t cqspi_write(struct spi_nor *nor, loff_t to, | |||
930 | return len; | 936 | return len; |
931 | } | 937 | } |
932 | 938 | ||
939 | static void cqspi_rx_dma_callback(void *param) | ||
940 | { | ||
941 | struct cqspi_st *cqspi = param; | ||
942 | |||
943 | complete(&cqspi->rx_dma_complete); | ||
944 | } | ||
945 | |||
946 | static int cqspi_direct_read_execute(struct spi_nor *nor, u_char *buf, | ||
947 | loff_t from, size_t len) | ||
948 | { | ||
949 | struct cqspi_flash_pdata *f_pdata = nor->priv; | ||
950 | struct cqspi_st *cqspi = f_pdata->cqspi; | ||
951 | enum dma_ctrl_flags flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; | ||
952 | dma_addr_t dma_src = (dma_addr_t)cqspi->mmap_phys_base + from; | ||
953 | int ret = 0; | ||
954 | struct dma_async_tx_descriptor *tx; | ||
955 | dma_cookie_t cookie; | ||
956 | dma_addr_t dma_dst; | ||
957 | |||
958 | if (!cqspi->rx_chan || !virt_addr_valid(buf)) { | ||
959 | memcpy_fromio(buf, cqspi->ahb_base + from, len); | ||
960 | return 0; | ||
961 | } | ||
962 | |||
963 | dma_dst = dma_map_single(nor->dev, buf, len, DMA_DEV_TO_MEM); | ||
964 | if (dma_mapping_error(nor->dev, dma_dst)) { | ||
965 | dev_err(nor->dev, "dma mapping failed\n"); | ||
966 | return -ENOMEM; | ||
967 | } | ||
968 | tx = dmaengine_prep_dma_memcpy(cqspi->rx_chan, dma_dst, dma_src, | ||
969 | len, flags); | ||
970 | if (!tx) { | ||
971 | dev_err(nor->dev, "device_prep_dma_memcpy error\n"); | ||
972 | ret = -EIO; | ||
973 | goto err_unmap; | ||
974 | } | ||
975 | |||
976 | tx->callback = cqspi_rx_dma_callback; | ||
977 | tx->callback_param = cqspi; | ||
978 | cookie = tx->tx_submit(tx); | ||
979 | reinit_completion(&cqspi->rx_dma_complete); | ||
980 | |||
981 | ret = dma_submit_error(cookie); | ||
982 | if (ret) { | ||
983 | dev_err(nor->dev, "dma_submit_error %d\n", cookie); | ||
984 | ret = -EIO; | ||
985 | goto err_unmap; | ||
986 | } | ||
987 | |||
988 | dma_async_issue_pending(cqspi->rx_chan); | ||
989 | ret = wait_for_completion_timeout(&cqspi->rx_dma_complete, | ||
990 | msecs_to_jiffies(len)); | ||
991 | if (ret <= 0) { | ||
992 | dmaengine_terminate_sync(cqspi->rx_chan); | ||
993 | dev_err(nor->dev, "DMA wait_for_completion_timeout\n"); | ||
994 | ret = -ETIMEDOUT; | ||
995 | goto err_unmap; | ||
996 | } | ||
997 | |||
998 | err_unmap: | ||
999 | dma_unmap_single(nor->dev, dma_dst, len, DMA_DEV_TO_MEM); | ||
1000 | |||
1001 | return 0; | ||
1002 | } | ||
1003 | |||
933 | static ssize_t cqspi_read(struct spi_nor *nor, loff_t from, | 1004 | static ssize_t cqspi_read(struct spi_nor *nor, loff_t from, |
934 | size_t len, u_char *buf) | 1005 | size_t len, u_char *buf) |
935 | { | 1006 | { |
936 | struct cqspi_flash_pdata *f_pdata = nor->priv; | 1007 | struct cqspi_flash_pdata *f_pdata = nor->priv; |
937 | struct cqspi_st *cqspi = f_pdata->cqspi; | ||
938 | int ret; | 1008 | int ret; |
939 | 1009 | ||
940 | ret = cqspi_set_protocol(nor, 1); | 1010 | ret = cqspi_set_protocol(nor, 1); |
@@ -946,7 +1016,7 @@ static ssize_t cqspi_read(struct spi_nor *nor, loff_t from, | |||
946 | return ret; | 1016 | return ret; |
947 | 1017 | ||
948 | if (f_pdata->use_direct_mode) | 1018 | if (f_pdata->use_direct_mode) |
949 | memcpy_fromio(buf, cqspi->ahb_base + from, len); | 1019 | ret = cqspi_direct_read_execute(nor, buf, from, len); |
950 | else | 1020 | else |
951 | ret = cqspi_indirect_read_execute(nor, buf, from, len); | 1021 | ret = cqspi_indirect_read_execute(nor, buf, from, len); |
952 | if (ret) | 1022 | if (ret) |
@@ -1115,6 +1185,21 @@ static void cqspi_controller_init(struct cqspi_st *cqspi) | |||
1115 | cqspi_controller_enable(cqspi, 1); | 1185 | cqspi_controller_enable(cqspi, 1); |
1116 | } | 1186 | } |
1117 | 1187 | ||
1188 | static void cqspi_request_mmap_dma(struct cqspi_st *cqspi) | ||
1189 | { | ||
1190 | dma_cap_mask_t mask; | ||
1191 | |||
1192 | dma_cap_zero(mask); | ||
1193 | dma_cap_set(DMA_MEMCPY, mask); | ||
1194 | |||
1195 | cqspi->rx_chan = dma_request_chan_by_mask(&mask); | ||
1196 | if (IS_ERR(cqspi->rx_chan)) { | ||
1197 | dev_err(&cqspi->pdev->dev, "No Rx DMA available\n"); | ||
1198 | cqspi->rx_chan = NULL; | ||
1199 | } | ||
1200 | init_completion(&cqspi->rx_dma_complete); | ||
1201 | } | ||
1202 | |||
1118 | static int cqspi_setup_flash(struct cqspi_st *cqspi, struct device_node *np) | 1203 | static int cqspi_setup_flash(struct cqspi_st *cqspi, struct device_node *np) |
1119 | { | 1204 | { |
1120 | const struct spi_nor_hwcaps hwcaps = { | 1205 | const struct spi_nor_hwcaps hwcaps = { |
@@ -1192,6 +1277,9 @@ static int cqspi_setup_flash(struct cqspi_st *cqspi, struct device_node *np) | |||
1192 | f_pdata->use_direct_mode = true; | 1277 | f_pdata->use_direct_mode = true; |
1193 | dev_dbg(nor->dev, "using direct mode for %s\n", | 1278 | dev_dbg(nor->dev, "using direct mode for %s\n", |
1194 | mtd->name); | 1279 | mtd->name); |
1280 | |||
1281 | if (!cqspi->rx_chan) | ||
1282 | cqspi_request_mmap_dma(cqspi); | ||
1195 | } | 1283 | } |
1196 | } | 1284 | } |
1197 | 1285 | ||
@@ -1252,6 +1340,7 @@ static int cqspi_probe(struct platform_device *pdev) | |||
1252 | dev_err(dev, "Cannot remap AHB address.\n"); | 1340 | dev_err(dev, "Cannot remap AHB address.\n"); |
1253 | return PTR_ERR(cqspi->ahb_base); | 1341 | return PTR_ERR(cqspi->ahb_base); |
1254 | } | 1342 | } |
1343 | cqspi->mmap_phys_base = (dma_addr_t)res_ahb->start; | ||
1255 | cqspi->ahb_size = resource_size(res_ahb); | 1344 | cqspi->ahb_size = resource_size(res_ahb); |
1256 | 1345 | ||
1257 | init_completion(&cqspi->transfer_complete); | 1346 | init_completion(&cqspi->transfer_complete); |
@@ -1322,6 +1411,9 @@ static int cqspi_remove(struct platform_device *pdev) | |||
1322 | 1411 | ||
1323 | cqspi_controller_enable(cqspi, 0); | 1412 | cqspi_controller_enable(cqspi, 0); |
1324 | 1413 | ||
1414 | if (cqspi->rx_chan) | ||
1415 | dma_release_channel(cqspi->rx_chan); | ||
1416 | |||
1325 | clk_disable_unprepare(cqspi->clk); | 1417 | clk_disable_unprepare(cqspi->clk); |
1326 | 1418 | ||
1327 | pm_runtime_put_sync(&pdev->dev); | 1419 | pm_runtime_put_sync(&pdev->dev); |
diff --git a/drivers/mtd/spi-nor/fsl-quadspi.c b/drivers/mtd/spi-nor/fsl-quadspi.c index 3e3c0bbc45c0..7d9620c7ff6c 100644 --- a/drivers/mtd/spi-nor/fsl-quadspi.c +++ b/drivers/mtd/spi-nor/fsl-quadspi.c | |||
@@ -214,6 +214,7 @@ enum fsl_qspi_devtype { | |||
214 | FSL_QUADSPI_IMX7D, | 214 | FSL_QUADSPI_IMX7D, |
215 | FSL_QUADSPI_IMX6UL, | 215 | FSL_QUADSPI_IMX6UL, |
216 | FSL_QUADSPI_LS1021A, | 216 | FSL_QUADSPI_LS1021A, |
217 | FSL_QUADSPI_LS2080A, | ||
217 | }; | 218 | }; |
218 | 219 | ||
219 | struct fsl_qspi_devtype_data { | 220 | struct fsl_qspi_devtype_data { |
@@ -267,6 +268,15 @@ static struct fsl_qspi_devtype_data ls1021a_data = { | |||
267 | .driver_data = 0, | 268 | .driver_data = 0, |
268 | }; | 269 | }; |
269 | 270 | ||
271 | static const struct fsl_qspi_devtype_data ls2080a_data = { | ||
272 | .devtype = FSL_QUADSPI_LS2080A, | ||
273 | .rxfifo = 128, | ||
274 | .txfifo = 64, | ||
275 | .ahb_buf_size = 1024, | ||
276 | .driver_data = QUADSPI_QUIRK_TKT253890, | ||
277 | }; | ||
278 | |||
279 | |||
270 | #define FSL_QSPI_MAX_CHIP 4 | 280 | #define FSL_QSPI_MAX_CHIP 4 |
271 | struct fsl_qspi { | 281 | struct fsl_qspi { |
272 | struct spi_nor nor[FSL_QSPI_MAX_CHIP]; | 282 | struct spi_nor nor[FSL_QSPI_MAX_CHIP]; |
@@ -661,7 +671,7 @@ static void fsl_qspi_set_map_addr(struct fsl_qspi *q) | |||
661 | * causes the controller to clear the buffer, and use the sequence pointed | 671 | * causes the controller to clear the buffer, and use the sequence pointed |
662 | * by the QUADSPI_BFGENCR[SEQID] to initiate a read from the flash. | 672 | * by the QUADSPI_BFGENCR[SEQID] to initiate a read from the flash. |
663 | */ | 673 | */ |
664 | static void fsl_qspi_init_abh_read(struct fsl_qspi *q) | 674 | static void fsl_qspi_init_ahb_read(struct fsl_qspi *q) |
665 | { | 675 | { |
666 | void __iomem *base = q->iobase; | 676 | void __iomem *base = q->iobase; |
667 | int seqid; | 677 | int seqid; |
@@ -795,7 +805,7 @@ static int fsl_qspi_nor_setup_last(struct fsl_qspi *q) | |||
795 | fsl_qspi_init_lut(q); | 805 | fsl_qspi_init_lut(q); |
796 | 806 | ||
797 | /* Init for AHB read */ | 807 | /* Init for AHB read */ |
798 | fsl_qspi_init_abh_read(q); | 808 | fsl_qspi_init_ahb_read(q); |
799 | 809 | ||
800 | return 0; | 810 | return 0; |
801 | } | 811 | } |
@@ -806,6 +816,7 @@ static const struct of_device_id fsl_qspi_dt_ids[] = { | |||
806 | { .compatible = "fsl,imx7d-qspi", .data = &imx7d_data, }, | 816 | { .compatible = "fsl,imx7d-qspi", .data = &imx7d_data, }, |
807 | { .compatible = "fsl,imx6ul-qspi", .data = &imx6ul_data, }, | 817 | { .compatible = "fsl,imx6ul-qspi", .data = &imx6ul_data, }, |
808 | { .compatible = "fsl,ls1021a-qspi", .data = (void *)&ls1021a_data, }, | 818 | { .compatible = "fsl,ls1021a-qspi", .data = (void *)&ls1021a_data, }, |
819 | { .compatible = "fsl,ls2080a-qspi", .data = &ls2080a_data, }, | ||
809 | { /* sentinel */ } | 820 | { /* sentinel */ } |
810 | }; | 821 | }; |
811 | MODULE_DEVICE_TABLE(of, fsl_qspi_dt_ids); | 822 | MODULE_DEVICE_TABLE(of, fsl_qspi_dt_ids); |
diff --git a/drivers/mtd/spi-nor/hisi-sfc.c b/drivers/mtd/spi-nor/hisi-sfc.c index 04f9fb5cd9b6..dea7b0c4b339 100644 --- a/drivers/mtd/spi-nor/hisi-sfc.c +++ b/drivers/mtd/spi-nor/hisi-sfc.c | |||
@@ -112,7 +112,7 @@ struct hifmc_host { | |||
112 | u32 num_chip; | 112 | u32 num_chip; |
113 | }; | 113 | }; |
114 | 114 | ||
115 | static inline int wait_op_finish(struct hifmc_host *host) | 115 | static inline int hisi_spi_nor_wait_op_finish(struct hifmc_host *host) |
116 | { | 116 | { |
117 | u32 reg; | 117 | u32 reg; |
118 | 118 | ||
@@ -120,7 +120,7 @@ static inline int wait_op_finish(struct hifmc_host *host) | |||
120 | (reg & FMC_INT_OP_DONE), 0, FMC_WAIT_TIMEOUT); | 120 | (reg & FMC_INT_OP_DONE), 0, FMC_WAIT_TIMEOUT); |
121 | } | 121 | } |
122 | 122 | ||
123 | static int get_if_type(enum spi_nor_protocol proto) | 123 | static int hisi_spi_nor_get_if_type(enum spi_nor_protocol proto) |
124 | { | 124 | { |
125 | enum hifmc_iftype if_type; | 125 | enum hifmc_iftype if_type; |
126 | 126 | ||
@@ -208,7 +208,7 @@ static int hisi_spi_nor_op_reg(struct spi_nor *nor, | |||
208 | reg = FMC_OP_CMD1_EN | FMC_OP_REG_OP_START | optype; | 208 | reg = FMC_OP_CMD1_EN | FMC_OP_REG_OP_START | optype; |
209 | writel(reg, host->regbase + FMC_OP); | 209 | writel(reg, host->regbase + FMC_OP); |
210 | 210 | ||
211 | return wait_op_finish(host); | 211 | return hisi_spi_nor_wait_op_finish(host); |
212 | } | 212 | } |
213 | 213 | ||
214 | static int hisi_spi_nor_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, | 214 | static int hisi_spi_nor_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf, |
@@ -259,9 +259,9 @@ static int hisi_spi_nor_dma_transfer(struct spi_nor *nor, loff_t start_off, | |||
259 | 259 | ||
260 | reg = OP_CFG_FM_CS(priv->chipselect); | 260 | reg = OP_CFG_FM_CS(priv->chipselect); |
261 | if (op_type == FMC_OP_READ) | 261 | if (op_type == FMC_OP_READ) |
262 | if_type = get_if_type(nor->read_proto); | 262 | if_type = hisi_spi_nor_get_if_type(nor->read_proto); |
263 | else | 263 | else |
264 | if_type = get_if_type(nor->write_proto); | 264 | if_type = hisi_spi_nor_get_if_type(nor->write_proto); |
265 | reg |= OP_CFG_MEM_IF_TYPE(if_type); | 265 | reg |= OP_CFG_MEM_IF_TYPE(if_type); |
266 | if (op_type == FMC_OP_READ) | 266 | if (op_type == FMC_OP_READ) |
267 | reg |= OP_CFG_DUMMY_NUM(nor->read_dummy >> 3); | 267 | reg |= OP_CFG_DUMMY_NUM(nor->read_dummy >> 3); |
@@ -274,7 +274,7 @@ static int hisi_spi_nor_dma_transfer(struct spi_nor *nor, loff_t start_off, | |||
274 | : OP_CTRL_WR_OPCODE(nor->program_opcode); | 274 | : OP_CTRL_WR_OPCODE(nor->program_opcode); |
275 | writel(reg, host->regbase + FMC_OP_DMA); | 275 | writel(reg, host->regbase + FMC_OP_DMA); |
276 | 276 | ||
277 | return wait_op_finish(host); | 277 | return hisi_spi_nor_wait_op_finish(host); |
278 | } | 278 | } |
279 | 279 | ||
280 | static ssize_t hisi_spi_nor_read(struct spi_nor *nor, loff_t from, size_t len, | 280 | static ssize_t hisi_spi_nor_read(struct spi_nor *nor, loff_t from, size_t len, |
diff --git a/drivers/mtd/spi-nor/intel-spi.c b/drivers/mtd/spi-nor/intel-spi.c index 699951523179..d2cbfc27826e 100644 --- a/drivers/mtd/spi-nor/intel-spi.c +++ b/drivers/mtd/spi-nor/intel-spi.c | |||
@@ -136,6 +136,7 @@ | |||
136 | * @swseq_reg: Use SW sequencer in register reads/writes | 136 | * @swseq_reg: Use SW sequencer in register reads/writes |
137 | * @swseq_erase: Use SW sequencer in erase operation | 137 | * @swseq_erase: Use SW sequencer in erase operation |
138 | * @erase_64k: 64k erase supported | 138 | * @erase_64k: 64k erase supported |
139 | * @atomic_preopcode: Holds preopcode when atomic sequence is requested | ||
139 | * @opcodes: Opcodes which are supported. This are programmed by BIOS | 140 | * @opcodes: Opcodes which are supported. This are programmed by BIOS |
140 | * before it locks down the controller. | 141 | * before it locks down the controller. |
141 | */ | 142 | */ |
@@ -153,6 +154,7 @@ struct intel_spi { | |||
153 | bool swseq_reg; | 154 | bool swseq_reg; |
154 | bool swseq_erase; | 155 | bool swseq_erase; |
155 | bool erase_64k; | 156 | bool erase_64k; |
157 | u8 atomic_preopcode; | ||
156 | u8 opcodes[8]; | 158 | u8 opcodes[8]; |
157 | }; | 159 | }; |
158 | 160 | ||
@@ -285,7 +287,7 @@ static int intel_spi_wait_hw_busy(struct intel_spi *ispi) | |||
285 | u32 val; | 287 | u32 val; |
286 | 288 | ||
287 | return readl_poll_timeout(ispi->base + HSFSTS_CTL, val, | 289 | return readl_poll_timeout(ispi->base + HSFSTS_CTL, val, |
288 | !(val & HSFSTS_CTL_SCIP), 0, | 290 | !(val & HSFSTS_CTL_SCIP), 40, |
289 | INTEL_SPI_TIMEOUT * 1000); | 291 | INTEL_SPI_TIMEOUT * 1000); |
290 | } | 292 | } |
291 | 293 | ||
@@ -294,7 +296,7 @@ static int intel_spi_wait_sw_busy(struct intel_spi *ispi) | |||
294 | u32 val; | 296 | u32 val; |
295 | 297 | ||
296 | return readl_poll_timeout(ispi->sregs + SSFSTS_CTL, val, | 298 | return readl_poll_timeout(ispi->sregs + SSFSTS_CTL, val, |
297 | !(val & SSFSTS_CTL_SCIP), 0, | 299 | !(val & SSFSTS_CTL_SCIP), 40, |
298 | INTEL_SPI_TIMEOUT * 1000); | 300 | INTEL_SPI_TIMEOUT * 1000); |
299 | } | 301 | } |
300 | 302 | ||
@@ -474,7 +476,7 @@ static int intel_spi_sw_cycle(struct intel_spi *ispi, u8 opcode, int len, | |||
474 | int optype) | 476 | int optype) |
475 | { | 477 | { |
476 | u32 val = 0, status; | 478 | u32 val = 0, status; |
477 | u16 preop; | 479 | u8 atomic_preopcode; |
478 | int ret; | 480 | int ret; |
479 | 481 | ||
480 | ret = intel_spi_opcode_index(ispi, opcode, optype); | 482 | ret = intel_spi_opcode_index(ispi, opcode, optype); |
@@ -484,17 +486,42 @@ static int intel_spi_sw_cycle(struct intel_spi *ispi, u8 opcode, int len, | |||
484 | if (len > INTEL_SPI_FIFO_SZ) | 486 | if (len > INTEL_SPI_FIFO_SZ) |
485 | return -EINVAL; | 487 | return -EINVAL; |
486 | 488 | ||
489 | /* | ||
490 | * Always clear it after each SW sequencer operation regardless | ||
491 | * of whether it is successful or not. | ||
492 | */ | ||
493 | atomic_preopcode = ispi->atomic_preopcode; | ||
494 | ispi->atomic_preopcode = 0; | ||
495 | |||
487 | /* Only mark 'Data Cycle' bit when there is data to be transferred */ | 496 | /* Only mark 'Data Cycle' bit when there is data to be transferred */ |
488 | if (len > 0) | 497 | if (len > 0) |
489 | val = ((len - 1) << SSFSTS_CTL_DBC_SHIFT) | SSFSTS_CTL_DS; | 498 | val = ((len - 1) << SSFSTS_CTL_DBC_SHIFT) | SSFSTS_CTL_DS; |
490 | val |= ret << SSFSTS_CTL_COP_SHIFT; | 499 | val |= ret << SSFSTS_CTL_COP_SHIFT; |
491 | val |= SSFSTS_CTL_FCERR | SSFSTS_CTL_FDONE; | 500 | val |= SSFSTS_CTL_FCERR | SSFSTS_CTL_FDONE; |
492 | val |= SSFSTS_CTL_SCGO; | 501 | val |= SSFSTS_CTL_SCGO; |
493 | preop = readw(ispi->sregs + PREOP_OPTYPE); | 502 | if (atomic_preopcode) { |
494 | if (preop) { | 503 | u16 preop; |
495 | val |= SSFSTS_CTL_ACS; | 504 | |
496 | if (preop >> 8) | 505 | switch (optype) { |
497 | val |= SSFSTS_CTL_SPOP; | 506 | case OPTYPE_WRITE_NO_ADDR: |
507 | case OPTYPE_WRITE_WITH_ADDR: | ||
508 | /* Pick matching preopcode for the atomic sequence */ | ||
509 | preop = readw(ispi->sregs + PREOP_OPTYPE); | ||
510 | if ((preop & 0xff) == atomic_preopcode) | ||
511 | ; /* Do nothing */ | ||
512 | else if ((preop >> 8) == atomic_preopcode) | ||
513 | val |= SSFSTS_CTL_SPOP; | ||
514 | else | ||
515 | return -EINVAL; | ||
516 | |||
517 | /* Enable atomic sequence */ | ||
518 | val |= SSFSTS_CTL_ACS; | ||
519 | break; | ||
520 | |||
521 | default: | ||
522 | return -EINVAL; | ||
523 | } | ||
524 | |||
498 | } | 525 | } |
499 | writel(val, ispi->sregs + SSFSTS_CTL); | 526 | writel(val, ispi->sregs + SSFSTS_CTL); |
500 | 527 | ||
@@ -538,13 +565,31 @@ static int intel_spi_write_reg(struct spi_nor *nor, u8 opcode, u8 *buf, int len) | |||
538 | 565 | ||
539 | /* | 566 | /* |
540 | * This is handled with atomic operation and preop code in Intel | 567 | * This is handled with atomic operation and preop code in Intel |
541 | * controller so skip it here now. If the controller is not locked, | 568 | * controller so we only verify that it is available. If the |
542 | * program the opcode to the PREOP register for later use. | 569 | * controller is not locked, program the opcode to the PREOP |
570 | * register for later use. | ||
571 | * | ||
572 | * When hardware sequencer is used there is no need to program | ||
573 | * any opcodes (it handles them automatically as part of a command). | ||
543 | */ | 574 | */ |
544 | if (opcode == SPINOR_OP_WREN) { | 575 | if (opcode == SPINOR_OP_WREN) { |
545 | if (!ispi->locked) | 576 | u16 preop; |
577 | |||
578 | if (!ispi->swseq_reg) | ||
579 | return 0; | ||
580 | |||
581 | preop = readw(ispi->sregs + PREOP_OPTYPE); | ||
582 | if ((preop & 0xff) != opcode && (preop >> 8) != opcode) { | ||
583 | if (ispi->locked) | ||
584 | return -EINVAL; | ||
546 | writel(opcode, ispi->sregs + PREOP_OPTYPE); | 585 | writel(opcode, ispi->sregs + PREOP_OPTYPE); |
586 | } | ||
547 | 587 | ||
588 | /* | ||
589 | * This enables atomic sequence on next SW sycle. Will | ||
590 | * be cleared after next operation. | ||
591 | */ | ||
592 | ispi->atomic_preopcode = opcode; | ||
548 | return 0; | 593 | return 0; |
549 | } | 594 | } |
550 | 595 | ||
@@ -569,6 +614,13 @@ static ssize_t intel_spi_read(struct spi_nor *nor, loff_t from, size_t len, | |||
569 | u32 val, status; | 614 | u32 val, status; |
570 | ssize_t ret; | 615 | ssize_t ret; |
571 | 616 | ||
617 | /* | ||
618 | * Atomic sequence is not expected with HW sequencer reads. Make | ||
619 | * sure it is cleared regardless. | ||
620 | */ | ||
621 | if (WARN_ON_ONCE(ispi->atomic_preopcode)) | ||
622 | ispi->atomic_preopcode = 0; | ||
623 | |||
572 | switch (nor->read_opcode) { | 624 | switch (nor->read_opcode) { |
573 | case SPINOR_OP_READ: | 625 | case SPINOR_OP_READ: |
574 | case SPINOR_OP_READ_FAST: | 626 | case SPINOR_OP_READ_FAST: |
@@ -627,6 +679,9 @@ static ssize_t intel_spi_write(struct spi_nor *nor, loff_t to, size_t len, | |||
627 | u32 val, status; | 679 | u32 val, status; |
628 | ssize_t ret; | 680 | ssize_t ret; |
629 | 681 | ||
682 | /* Not needed with HW sequencer write, make sure it is cleared */ | ||
683 | ispi->atomic_preopcode = 0; | ||
684 | |||
630 | while (len > 0) { | 685 | while (len > 0) { |
631 | block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ); | 686 | block_size = min_t(size_t, len, INTEL_SPI_FIFO_SZ); |
632 | 687 | ||
@@ -707,6 +762,9 @@ static int intel_spi_erase(struct spi_nor *nor, loff_t offs) | |||
707 | return 0; | 762 | return 0; |
708 | } | 763 | } |
709 | 764 | ||
765 | /* Not needed with HW sequencer erase, make sure it is cleared */ | ||
766 | ispi->atomic_preopcode = 0; | ||
767 | |||
710 | while (len > 0) { | 768 | while (len > 0) { |
711 | writel(offs, ispi->base + FADDR); | 769 | writel(offs, ispi->base + FADDR); |
712 | 770 | ||
diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 5bfa36e95f35..d9c368c44194 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c | |||
@@ -284,6 +284,20 @@ static inline int set_4byte(struct spi_nor *nor, const struct flash_info *info, | |||
284 | if (need_wren) | 284 | if (need_wren) |
285 | write_disable(nor); | 285 | write_disable(nor); |
286 | 286 | ||
287 | if (!status && !enable && | ||
288 | JEDEC_MFR(info) == SNOR_MFR_WINBOND) { | ||
289 | /* | ||
290 | * On Winbond W25Q256FV, leaving 4byte mode causes | ||
291 | * the Extended Address Register to be set to 1, so all | ||
292 | * 3-byte-address reads come from the second 16M. | ||
293 | * We must clear the register to enable normal behavior. | ||
294 | */ | ||
295 | write_enable(nor); | ||
296 | nor->cmd_buf[0] = 0; | ||
297 | nor->write_reg(nor, SPINOR_OP_WREAR, nor->cmd_buf, 1); | ||
298 | write_disable(nor); | ||
299 | } | ||
300 | |||
287 | return status; | 301 | return status; |
288 | default: | 302 | default: |
289 | /* Spansion style */ | 303 | /* Spansion style */ |
@@ -980,6 +994,7 @@ static const struct flash_info spi_nor_ids[] = { | |||
980 | { "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, 0) }, | 994 | { "en25q32b", INFO(0x1c3016, 0, 64 * 1024, 64, 0) }, |
981 | { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) }, | 995 | { "en25p64", INFO(0x1c2017, 0, 64 * 1024, 128, 0) }, |
982 | { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) }, | 996 | { "en25q64", INFO(0x1c3017, 0, 64 * 1024, 128, SECT_4K) }, |
997 | { "en25qh32", INFO(0x1c7016, 0, 64 * 1024, 64, 0) }, | ||
983 | { "en25qh128", INFO(0x1c7018, 0, 64 * 1024, 256, 0) }, | 998 | { "en25qh128", INFO(0x1c7018, 0, 64 * 1024, 256, 0) }, |
984 | { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) }, | 999 | { "en25qh256", INFO(0x1c7019, 0, 64 * 1024, 512, 0) }, |
985 | { "en25s64", INFO(0x1c3817, 0, 64 * 1024, 128, SECT_4K) }, | 1000 | { "en25s64", INFO(0x1c3817, 0, 64 * 1024, 128, SECT_4K) }, |
@@ -1049,6 +1064,14 @@ static const struct flash_info spi_nor_ids[] = { | |||
1049 | SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, | 1064 | SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, |
1050 | { "is25lp128", INFO(0x9d6018, 0, 64 * 1024, 256, | 1065 | { "is25lp128", INFO(0x9d6018, 0, 64 * 1024, 256, |
1051 | SECT_4K | SPI_NOR_DUAL_READ) }, | 1066 | SECT_4K | SPI_NOR_DUAL_READ) }, |
1067 | { "is25lp256", INFO(0x9d6019, 0, 64 * 1024, 512, | ||
1068 | SECT_4K | SPI_NOR_DUAL_READ) }, | ||
1069 | { "is25wp032", INFO(0x9d7016, 0, 64 * 1024, 64, | ||
1070 | SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, | ||
1071 | { "is25wp064", INFO(0x9d7017, 0, 64 * 1024, 128, | ||
1072 | SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, | ||
1073 | { "is25wp128", INFO(0x9d7018, 0, 64 * 1024, 256, | ||
1074 | SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, | ||
1052 | 1075 | ||
1053 | /* Macronix */ | 1076 | /* Macronix */ |
1054 | { "mx25l512e", INFO(0xc22010, 0, 64 * 1024, 1, SECT_4K) }, | 1077 | { "mx25l512e", INFO(0xc22010, 0, 64 * 1024, 1, SECT_4K) }, |
@@ -1087,6 +1110,7 @@ static const struct flash_info spi_nor_ids[] = { | |||
1087 | { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, | 1110 | { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, |
1088 | { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) }, | 1111 | { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) }, |
1089 | { "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) }, | 1112 | { "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) }, |
1113 | { "mt25qu02g", INFO(0x20bb22, 0, 64 * 1024, 4096, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ | NO_CHIP_ERASE) }, | ||
1090 | 1114 | ||
1091 | /* PMC */ | 1115 | /* PMC */ |
1092 | { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) }, | 1116 | { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) }, |
@@ -1198,6 +1222,11 @@ static const struct flash_info spi_nor_ids[] = { | |||
1198 | SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | | 1222 | SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | |
1199 | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) | 1223 | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) |
1200 | }, | 1224 | }, |
1225 | { | ||
1226 | "w25q32jv", INFO(0xef7016, 0, 64 * 1024, 64, | ||
1227 | SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | | ||
1228 | SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) | ||
1229 | }, | ||
1201 | { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, | 1230 | { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, |
1202 | { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, | 1231 | { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, |
1203 | { | 1232 | { |
@@ -1230,6 +1259,10 @@ static const struct flash_info spi_nor_ids[] = { | |||
1230 | { "3S400AN", S3AN_INFO(0x1f2400, 256, 264) }, | 1259 | { "3S400AN", S3AN_INFO(0x1f2400, 256, 264) }, |
1231 | { "3S700AN", S3AN_INFO(0x1f2500, 512, 264) }, | 1260 | { "3S700AN", S3AN_INFO(0x1f2500, 512, 264) }, |
1232 | { "3S1400AN", S3AN_INFO(0x1f2600, 512, 528) }, | 1261 | { "3S1400AN", S3AN_INFO(0x1f2600, 512, 528) }, |
1262 | |||
1263 | /* XMC (Wuhan Xinxin Semiconductor Manufacturing Corp.) */ | ||
1264 | { "XM25QH64A", INFO(0x207017, 0, 64 * 1024, 128, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, | ||
1265 | { "XM25QH128A", INFO(0x207018, 0, 64 * 1024, 256, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, | ||
1233 | { }, | 1266 | { }, |
1234 | }; | 1267 | }; |
1235 | 1268 | ||
diff --git a/drivers/mtd/spi-nor/stm32-quadspi.c b/drivers/mtd/spi-nor/stm32-quadspi.c index b3c7f6addba7..72553506a00b 100644 --- a/drivers/mtd/spi-nor/stm32-quadspi.c +++ b/drivers/mtd/spi-nor/stm32-quadspi.c | |||
@@ -656,7 +656,7 @@ static int stm32_qspi_probe(struct platform_device *pdev) | |||
656 | return ret; | 656 | return ret; |
657 | } | 657 | } |
658 | 658 | ||
659 | rstc = devm_reset_control_get(dev, NULL); | 659 | rstc = devm_reset_control_get_exclusive(dev, NULL); |
660 | if (!IS_ERR(rstc)) { | 660 | if (!IS_ERR(rstc)) { |
661 | reset_control_assert(rstc); | 661 | reset_control_assert(rstc); |
662 | udelay(2); | 662 | udelay(2); |
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 792ea5c26329..abe975c87b90 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h | |||
@@ -86,6 +86,7 @@ struct nand_pos { | |||
86 | * @ooboffs: the OOB offset within the page | 86 | * @ooboffs: the OOB offset within the page |
87 | * @ooblen: the number of OOB bytes to read from/write to this page | 87 | * @ooblen: the number of OOB bytes to read from/write to this page |
88 | * @oobbuf: buffer to store OOB data in or get OOB data from | 88 | * @oobbuf: buffer to store OOB data in or get OOB data from |
89 | * @mode: one of the %MTD_OPS_XXX mode | ||
89 | * | 90 | * |
90 | * This object is used to pass per-page I/O requests to NAND sub-layers. This | 91 | * This object is used to pass per-page I/O requests to NAND sub-layers. This |
91 | * way all useful information are already formatted in a useful way and | 92 | * way all useful information are already formatted in a useful way and |
@@ -106,6 +107,7 @@ struct nand_page_io_req { | |||
106 | const void *out; | 107 | const void *out; |
107 | void *in; | 108 | void *in; |
108 | } oobbuf; | 109 | } oobbuf; |
110 | int mode; | ||
109 | }; | 111 | }; |
110 | 112 | ||
111 | /** | 113 | /** |
@@ -599,6 +601,7 @@ static inline void nanddev_io_iter_init(struct nand_device *nand, | |||
599 | { | 601 | { |
600 | struct mtd_info *mtd = nanddev_to_mtd(nand); | 602 | struct mtd_info *mtd = nanddev_to_mtd(nand); |
601 | 603 | ||
604 | iter->req.mode = req->mode; | ||
602 | iter->req.dataoffs = nanddev_offs_to_pos(nand, offs, &iter->req.pos); | 605 | iter->req.dataoffs = nanddev_offs_to_pos(nand, offs, &iter->req.pos); |
603 | iter->req.ooboffs = req->ooboffs; | 606 | iter->req.ooboffs = req->ooboffs; |
604 | iter->oobbytes_per_page = mtd_oobavail(mtd, req); | 607 | iter->oobbytes_per_page = mtd_oobavail(mtd, req); |
diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h index 17c919436f48..3e8ec3b8a39c 100644 --- a/include/linux/mtd/rawnand.h +++ b/include/linux/mtd/rawnand.h | |||
@@ -28,7 +28,14 @@ struct nand_flash_dev; | |||
28 | struct device_node; | 28 | struct device_node; |
29 | 29 | ||
30 | /* Scan and identify a NAND device */ | 30 | /* Scan and identify a NAND device */ |
31 | int nand_scan(struct mtd_info *mtd, int max_chips); | 31 | int nand_scan_with_ids(struct mtd_info *mtd, int max_chips, |
32 | struct nand_flash_dev *ids); | ||
33 | |||
34 | static inline int nand_scan(struct mtd_info *mtd, int max_chips) | ||
35 | { | ||
36 | return nand_scan_with_ids(mtd, max_chips, NULL); | ||
37 | } | ||
38 | |||
32 | /* | 39 | /* |
33 | * Separate phases of nand_scan(), allowing board driver to intervene | 40 | * Separate phases of nand_scan(), allowing board driver to intervene |
34 | * and override command or ECC setup according to flash type. | 41 | * and override command or ECC setup according to flash type. |
@@ -740,8 +747,9 @@ enum nand_data_interface_type { | |||
740 | 747 | ||
741 | /** | 748 | /** |
742 | * struct nand_data_interface - NAND interface timing | 749 | * struct nand_data_interface - NAND interface timing |
743 | * @type: type of the timing | 750 | * @type: type of the timing |
744 | * @timings: The timing, type according to @type | 751 | * @timings: The timing, type according to @type |
752 | * @timings.sdr: Use it when @type is %NAND_SDR_IFACE. | ||
745 | */ | 753 | */ |
746 | struct nand_data_interface { | 754 | struct nand_data_interface { |
747 | enum nand_data_interface_type type; | 755 | enum nand_data_interface_type type; |
@@ -798,8 +806,9 @@ struct nand_op_addr_instr { | |||
798 | /** | 806 | /** |
799 | * struct nand_op_data_instr - Definition of a data instruction | 807 | * struct nand_op_data_instr - Definition of a data instruction |
800 | * @len: number of data bytes to move | 808 | * @len: number of data bytes to move |
801 | * @in: buffer to fill when reading from the NAND chip | 809 | * @buf: buffer to fill |
802 | * @out: buffer to read from when writing to the NAND chip | 810 | * @buf.in: buffer to fill when reading from the NAND chip |
811 | * @buf.out: buffer to read from when writing to the NAND chip | ||
803 | * @force_8bit: force 8-bit access | 812 | * @force_8bit: force 8-bit access |
804 | * | 813 | * |
805 | * Please note that "in" and "out" are inverted from the ONFI specification | 814 | * Please note that "in" and "out" are inverted from the ONFI specification |
@@ -842,9 +851,13 @@ enum nand_op_instr_type { | |||
842 | /** | 851 | /** |
843 | * struct nand_op_instr - Instruction object | 852 | * struct nand_op_instr - Instruction object |
844 | * @type: the instruction type | 853 | * @type: the instruction type |
845 | * @cmd/@addr/@data/@waitrdy: extra data associated to the instruction. | 854 | * @ctx: extra data associated to the instruction. You'll have to use the |
846 | * You'll have to use the appropriate element | 855 | * appropriate element depending on @type |
847 | * depending on @type | 856 | * @ctx.cmd: use it if @type is %NAND_OP_CMD_INSTR |
857 | * @ctx.addr: use it if @type is %NAND_OP_ADDR_INSTR | ||
858 | * @ctx.data: use it if @type is %NAND_OP_DATA_IN_INSTR | ||
859 | * or %NAND_OP_DATA_OUT_INSTR | ||
860 | * @ctx.waitrdy: use it if @type is %NAND_OP_WAITRDY_INSTR | ||
848 | * @delay_ns: delay the controller should apply after the instruction has been | 861 | * @delay_ns: delay the controller should apply after the instruction has been |
849 | * issued on the bus. Most modern controllers have internal timings | 862 | * issued on the bus. Most modern controllers have internal timings |
850 | * control logic, and in this case, the controller driver can ignore | 863 | * control logic, and in this case, the controller driver can ignore |
@@ -1003,7 +1016,9 @@ struct nand_op_parser_data_constraints { | |||
1003 | * struct nand_op_parser_pattern_elem - One element of a pattern | 1016 | * struct nand_op_parser_pattern_elem - One element of a pattern |
1004 | * @type: the instructuction type | 1017 | * @type: the instructuction type |
1005 | * @optional: whether this element of the pattern is optional or mandatory | 1018 | * @optional: whether this element of the pattern is optional or mandatory |
1006 | * @addr/@data: address or data constraint (number of cycles or data length) | 1019 | * @ctx: address or data constraint |
1020 | * @ctx.addr: address constraint (number of cycles) | ||
1021 | * @ctx.data: data constraint (data length) | ||
1007 | */ | 1022 | */ |
1008 | struct nand_op_parser_pattern_elem { | 1023 | struct nand_op_parser_pattern_elem { |
1009 | enum nand_op_instr_type type; | 1024 | enum nand_op_instr_type type; |
@@ -1230,6 +1245,8 @@ int nand_op_parser_exec_op(struct nand_chip *chip, | |||
1230 | * devices. | 1245 | * devices. |
1231 | * @priv: [OPTIONAL] pointer to private chip data | 1246 | * @priv: [OPTIONAL] pointer to private chip data |
1232 | * @manufacturer: [INTERN] Contains manufacturer information | 1247 | * @manufacturer: [INTERN] Contains manufacturer information |
1248 | * @manufacturer.desc: [INTERN] Contains manufacturer's description | ||
1249 | * @manufacturer.priv: [INTERN] Contains manufacturer private information | ||
1233 | */ | 1250 | */ |
1234 | 1251 | ||
1235 | struct nand_chip { | 1252 | struct nand_chip { |
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index de36969eb359..e60da0d34cc1 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h | |||
@@ -62,6 +62,8 @@ | |||
62 | #define SPINOR_OP_RDCR 0x35 /* Read configuration register */ | 62 | #define SPINOR_OP_RDCR 0x35 /* Read configuration register */ |
63 | #define SPINOR_OP_RDFSR 0x70 /* Read flag status register */ | 63 | #define SPINOR_OP_RDFSR 0x70 /* Read flag status register */ |
64 | #define SPINOR_OP_CLFSR 0x50 /* Clear flag status register */ | 64 | #define SPINOR_OP_CLFSR 0x50 /* Clear flag status register */ |
65 | #define SPINOR_OP_RDEAR 0xc8 /* Read Extended Address Register */ | ||
66 | #define SPINOR_OP_WREAR 0xc5 /* Write Extended Address Register */ | ||
65 | 67 | ||
66 | /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */ | 68 | /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */ |
67 | #define SPINOR_OP_READ_4B 0x13 /* Read data bytes (low frequency) */ | 69 | #define SPINOR_OP_READ_4B 0x13 /* Read data bytes (low frequency) */ |