diff options
76 files changed, 1688 insertions, 1043 deletions
diff --git a/Documentation/devicetree/bindings/arm/davinci/nand.txt b/Documentation/devicetree/bindings/arm/davinci/nand.txt deleted file mode 100644 index 3545ea704b50..000000000000 --- a/Documentation/devicetree/bindings/arm/davinci/nand.txt +++ /dev/null | |||
| @@ -1,46 +0,0 @@ | |||
| 1 | * Texas Instruments Davinci NAND | ||
| 2 | |||
| 3 | This file provides information, what the device node for the | ||
| 4 | davinci nand interface contain. | ||
| 5 | |||
| 6 | Required properties: | ||
| 7 | - compatible: "ti,davinci-nand"; | ||
| 8 | - reg : contain 2 offset/length values: | ||
| 9 | - offset and length for the access window | ||
| 10 | - offset and length for accessing the aemif control registers | ||
| 11 | - ti,davinci-chipselect: Indicates on the davinci_nand driver which | ||
| 12 | chipselect is used for accessing the nand. | ||
| 13 | |||
| 14 | Recommended properties : | ||
| 15 | - ti,davinci-mask-ale: mask for ale | ||
| 16 | - ti,davinci-mask-cle: mask for cle | ||
| 17 | - ti,davinci-mask-chipsel: mask for chipselect | ||
| 18 | - ti,davinci-ecc-mode: ECC mode valid values for davinci driver: | ||
| 19 | - "none" | ||
| 20 | - "soft" | ||
| 21 | - "hw" | ||
| 22 | - ti,davinci-ecc-bits: used ECC bits, currently supported 1 or 4. | ||
| 23 | - ti,davinci-nand-buswidth: buswidth 8 or 16 | ||
| 24 | - ti,davinci-nand-use-bbt: use flash based bad block table support. | ||
| 25 | |||
| 26 | nand device bindings may contain additional sub-nodes describing | ||
| 27 | partitions of the address space. See partition.txt for more detail. | ||
| 28 | |||
| 29 | Example(da850 EVM ): | ||
| 30 | nand_cs3@62000000 { | ||
| 31 | compatible = "ti,davinci-nand"; | ||
| 32 | reg = <0x62000000 0x807ff | ||
| 33 | 0x68000000 0x8000>; | ||
| 34 | ti,davinci-chipselect = <1>; | ||
| 35 | ti,davinci-mask-ale = <0>; | ||
| 36 | ti,davinci-mask-cle = <0>; | ||
| 37 | ti,davinci-mask-chipsel = <0>; | ||
| 38 | ti,davinci-ecc-mode = "hw"; | ||
| 39 | ti,davinci-ecc-bits = <4>; | ||
| 40 | ti,davinci-nand-use-bbt; | ||
| 41 | |||
| 42 | partition@180000 { | ||
| 43 | label = "ubifs"; | ||
| 44 | reg = <0x180000 0x7e80000>; | ||
| 45 | }; | ||
| 46 | }; | ||
diff --git a/Documentation/devicetree/bindings/mtd/davinci-nand.txt b/Documentation/devicetree/bindings/mtd/davinci-nand.txt new file mode 100644 index 000000000000..cfb18abe6001 --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/davinci-nand.txt | |||
| @@ -0,0 +1,94 @@ | |||
| 1 | Device tree bindings for Texas instruments Davinci/Keystone NAND controller | ||
| 2 | |||
| 3 | This file provides information, what the device node for the davinci/keystone | ||
| 4 | NAND interface contains. | ||
| 5 | |||
| 6 | Documentation: | ||
| 7 | Davinci DM646x - http://www.ti.com/lit/ug/sprueq7c/sprueq7c.pdf | ||
| 8 | Kestone - http://www.ti.com/lit/ug/sprugz3a/sprugz3a.pdf | ||
| 9 | |||
| 10 | Required properties: | ||
| 11 | |||
| 12 | - compatible: "ti,davinci-nand" | ||
| 13 | "ti,keystone-nand" | ||
| 14 | |||
| 15 | - reg: Contains 2 offset/length values: | ||
| 16 | - offset and length for the access window. | ||
| 17 | - offset and length for accessing the AEMIF | ||
| 18 | control registers. | ||
| 19 | |||
| 20 | - ti,davinci-chipselect: number of chipselect. Indicates on the | ||
| 21 | davinci_nand driver which chipselect is used | ||
| 22 | for accessing the nand. | ||
| 23 | Can be in the range [0-3]. | ||
| 24 | |||
| 25 | Recommended properties : | ||
| 26 | |||
| 27 | - ti,davinci-mask-ale: mask for ALE. Needed for executing address | ||
| 28 | phase. These offset will be added to the base | ||
| 29 | address for the chip select space the NAND Flash | ||
| 30 | device is connected to. | ||
| 31 | If not set equal to 0x08. | ||
| 32 | |||
| 33 | - ti,davinci-mask-cle: mask for CLE. Needed for executing command | ||
| 34 | phase. These offset will be added to the base | ||
| 35 | address for the chip select space the NAND Flash | ||
| 36 | device is connected to. | ||
| 37 | If not set equal to 0x10. | ||
| 38 | |||
| 39 | - ti,davinci-mask-chipsel: mask for chipselect address. Needed to mask | ||
| 40 | addresses for given chipselect. | ||
| 41 | |||
| 42 | - nand-ecc-mode: operation mode of the NAND ecc mode. ECC mode | ||
| 43 | valid values for davinci driver: | ||
| 44 | - "none" | ||
| 45 | - "soft" | ||
| 46 | - "hw" | ||
| 47 | |||
| 48 | - ti,davinci-ecc-bits: used ECC bits, currently supported 1 or 4. | ||
| 49 | |||
| 50 | - nand-bus-width: buswidth 8 or 16. If not present 8. | ||
| 51 | |||
| 52 | - nand-on-flash-bbt: use flash based bad block table support. OOB | ||
| 53 | identifier is saved in OOB area. If not present | ||
| 54 | false. | ||
| 55 | |||
| 56 | Deprecated properties: | ||
| 57 | |||
| 58 | - ti,davinci-ecc-mode: operation mode of the NAND ecc mode. ECC mode | ||
| 59 | valid values for davinci driver: | ||
| 60 | - "none" | ||
| 61 | - "soft" | ||
| 62 | - "hw" | ||
| 63 | |||
| 64 | - ti,davinci-nand-buswidth: buswidth 8 or 16. If not present 8. | ||
| 65 | |||
| 66 | - ti,davinci-nand-use-bbt: use flash based bad block table support. OOB | ||
| 67 | identifier is saved in OOB area. If not present | ||
| 68 | false. | ||
| 69 | |||
| 70 | Nand device bindings may contain additional sub-nodes describing partitions of | ||
| 71 | the address space. See partition.txt for more detail. The NAND Flash timing | ||
| 72 | values must be programmed in the chip select’s node of AEMIF | ||
| 73 | memory-controller (see Documentation/devicetree/bindings/memory-controllers/ | ||
| 74 | davinci-aemif.txt). | ||
| 75 | |||
| 76 | Example(da850 EVM ): | ||
| 77 | |||
| 78 | nand_cs3@62000000 { | ||
| 79 | compatible = "ti,davinci-nand"; | ||
| 80 | reg = <0x62000000 0x807ff | ||
| 81 | 0x68000000 0x8000>; | ||
| 82 | ti,davinci-chipselect = <1>; | ||
| 83 | ti,davinci-mask-ale = <0>; | ||
| 84 | ti,davinci-mask-cle = <0>; | ||
| 85 | ti,davinci-mask-chipsel = <0>; | ||
| 86 | nand-ecc-mode = "hw"; | ||
| 87 | ti,davinci-ecc-bits = <4>; | ||
| 88 | nand-on-flash-bbt; | ||
| 89 | |||
| 90 | partition@180000 { | ||
| 91 | label = "ubifs"; | ||
| 92 | reg = <0x180000 0x7e80000>; | ||
| 93 | }; | ||
| 94 | }; | ||
diff --git a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt index 551b2a179d01..458d59634688 100644 --- a/Documentation/devicetree/bindings/mtd/gpmi-nand.txt +++ b/Documentation/devicetree/bindings/mtd/gpmi-nand.txt | |||
| @@ -17,6 +17,14 @@ Required properties: | |||
| 17 | Optional properties: | 17 | Optional properties: |
| 18 | - nand-on-flash-bbt: boolean to enable on flash bbt option if not | 18 | - nand-on-flash-bbt: boolean to enable on flash bbt option if not |
| 19 | present false | 19 | present false |
| 20 | - fsl,use-minimum-ecc: Protect this NAND flash with the minimum ECC | ||
| 21 | strength required. The required ECC strength is | ||
| 22 | automatically discoverable for some flash | ||
| 23 | (e.g., according to the ONFI standard). | ||
| 24 | However, note that if this strength is not | ||
| 25 | discoverable or this property is not enabled, | ||
| 26 | the software may chooses an implementation-defined | ||
| 27 | ECC scheme. | ||
| 20 | 28 | ||
| 21 | The device tree may optionally contain sub-nodes describing partitions of the | 29 | The device tree may optionally contain sub-nodes describing partitions of the |
| 22 | address space. See partition.txt for more detail. | 30 | address space. See partition.txt for more detail. |
diff --git a/Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt b/Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt index f1421e2bbab7..86e0a5601ff5 100644 --- a/Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt +++ b/Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt | |||
| @@ -2,7 +2,9 @@ PXA3xx NAND DT bindings | |||
| 2 | 2 | ||
| 3 | Required properties: | 3 | Required properties: |
| 4 | 4 | ||
| 5 | - compatible: Should be "marvell,pxa3xx-nand" | 5 | - compatible: Should be set to one of the following: |
| 6 | marvell,pxa3xx-nand | ||
| 7 | marvell,armada370-nand | ||
| 6 | - reg: The register base for the controller | 8 | - reg: The register base for the controller |
| 7 | - interrupts: The interrupt to map | 9 | - interrupts: The interrupt to map |
| 8 | - #address-cells: Set to <1> if the node includes partitions | 10 | - #address-cells: Set to <1> if the node includes partitions |
| @@ -13,6 +15,8 @@ Optional properties: | |||
| 13 | - marvell,nand-keep-config: Set to keep the NAND controller config as set | 15 | - marvell,nand-keep-config: Set to keep the NAND controller config as set |
| 14 | by the bootloader | 16 | by the bootloader |
| 15 | - num-cs: Number of chipselect lines to usw | 17 | - num-cs: Number of chipselect lines to usw |
| 18 | - nand-on-flash-bbt: boolean to enable on flash bbt option if | ||
| 19 | not present false | ||
| 16 | 20 | ||
| 17 | Example: | 21 | Example: |
| 18 | 22 | ||
diff --git a/Documentation/mtd/nand/pxa3xx-nand.txt b/Documentation/mtd/nand/pxa3xx-nand.txt new file mode 100644 index 000000000000..840fd41c181b --- /dev/null +++ b/Documentation/mtd/nand/pxa3xx-nand.txt | |||
| @@ -0,0 +1,113 @@ | |||
| 1 | |||
| 2 | About this document | ||
| 3 | =================== | ||
| 4 | |||
| 5 | Some notes about Marvell's NAND controller available in PXA and Armada 370/XP | ||
| 6 | SoC (aka NFCv1 and NFCv2), with an emphasis on the latter. | ||
| 7 | |||
| 8 | NFCv2 controller background | ||
| 9 | =========================== | ||
| 10 | |||
| 11 | The controller has a 2176 bytes FIFO buffer. Therefore, in order to support | ||
| 12 | larger pages, I/O operations on 4 KiB and 8 KiB pages is done with a set of | ||
| 13 | chunked transfers. | ||
| 14 | |||
| 15 | For instance, if we choose a 2048 data chunk and set "BCH" ECC (see below) | ||
| 16 | we'll have this layout in the pages: | ||
| 17 | |||
| 18 | ------------------------------------------------------------------------------ | ||
| 19 | | 2048B data | 32B spare | 30B ECC || 2048B data | 32B spare | 30B ECC | ... | | ||
| 20 | ------------------------------------------------------------------------------ | ||
| 21 | |||
| 22 | The driver reads the data and spare portions independently and builds an internal | ||
| 23 | buffer with this layout (in the 4 KiB page case): | ||
| 24 | |||
| 25 | ------------------------------------------ | ||
| 26 | | 4096B data | 64B spare | | ||
| 27 | ------------------------------------------ | ||
| 28 | |||
| 29 | Also, for the READOOB command the driver disables the ECC and reads a 'spare + ECC' | ||
| 30 | OOB, one per chunk read. | ||
| 31 | |||
| 32 | ------------------------------------------------------------------- | ||
| 33 | | 4096B data | 32B spare | 30B ECC | 32B spare | 30B ECC | | ||
| 34 | ------------------------------------------------------------------- | ||
| 35 | |||
| 36 | So, in order to achieve reading (for instance), we issue several READ0 commands | ||
| 37 | (with some additional controller-specific magic) and read two chunks of 2080B | ||
| 38 | (2048 data + 32 spare) each. | ||
| 39 | The driver accommodates this data to expose the NAND core a contiguous buffer | ||
| 40 | (4096 data + spare) or (4096 + spare + ECC + spare + ECC). | ||
| 41 | |||
| 42 | ECC | ||
| 43 | === | ||
| 44 | |||
| 45 | The controller has built-in hardware ECC capabilities. In addition it is | ||
| 46 | configurable between two modes: 1) Hamming, 2) BCH. | ||
| 47 | |||
| 48 | Note that the actual BCH mode: BCH-4 or BCH-8 will depend on the way | ||
| 49 | the controller is configured to transfer the data. | ||
| 50 | |||
| 51 | In the BCH mode the ECC code will be calculated for each transfered chunk | ||
| 52 | and expected to be located (when reading/programming) right after the spare | ||
| 53 | bytes as the figure above shows. | ||
| 54 | |||
| 55 | So, repeating the above scheme, a 2048B data chunk will be followed by 32B | ||
| 56 | spare, and then the ECC controller will read/write the ECC code (30B in | ||
| 57 | this case): | ||
| 58 | |||
| 59 | ------------------------------------ | ||
| 60 | | 2048B data | 32B spare | 30B ECC | | ||
| 61 | ------------------------------------ | ||
| 62 | |||
| 63 | If the ECC mode is 'BCH' then the ECC is *always* 30 bytes long. | ||
| 64 | If the ECC mode is 'Hamming' the ECC is 6 bytes long, for each 512B block. | ||
| 65 | So in Hamming mode, a 2048B page will have a 24B ECC. | ||
| 66 | |||
| 67 | Despite all of the above, the controller requires the driver to only read or | ||
| 68 | write in multiples of 8-bytes, because the data buffer is 64-bits. | ||
| 69 | |||
| 70 | OOB | ||
| 71 | === | ||
| 72 | |||
| 73 | Because of the above scheme, and because the "spare" OOB is really located in | ||
| 74 | the middle of a page, spare OOB cannot be read or write independently of the | ||
| 75 | data area. In other words, in order to read the OOB (aka READOOB), the entire | ||
| 76 | page (aka READ0) has to be read. | ||
| 77 | |||
| 78 | In the same sense, in order to write to the spare OOB the driver has to write | ||
| 79 | an *entire* page. | ||
| 80 | |||
| 81 | Factory bad blocks handling | ||
| 82 | =========================== | ||
| 83 | |||
| 84 | Given the ECC BCH requires to layout the device's pages in a split | ||
| 85 | data/OOB/data/OOB way, the controller has a view of the flash page that's | ||
| 86 | different from the specified (aka the manufacturer's) view. In other words, | ||
| 87 | |||
| 88 | Factory view: | ||
| 89 | |||
| 90 | ----------------------------------------------- | ||
| 91 | | Data |x OOB | | ||
| 92 | ----------------------------------------------- | ||
| 93 | |||
| 94 | Driver's view: | ||
| 95 | |||
| 96 | ----------------------------------------------- | ||
| 97 | | Data | OOB | Data x | OOB | | ||
| 98 | ----------------------------------------------- | ||
| 99 | |||
| 100 | It can be seen from the above, that the factory bad block marker must be | ||
| 101 | searched within the 'data' region, and not in the usual OOB region. | ||
| 102 | |||
| 103 | In addition, this means under regular usage the driver will write such | ||
| 104 | position (since it belongs to the data region) and every used block is | ||
| 105 | likely to be marked as bad. | ||
| 106 | |||
| 107 | For this reason, marking the block as bad in the OOB is explicitly | ||
| 108 | disabled by using the NAND_BBT_NO_OOB_BBM option in the driver. The rationale | ||
| 109 | for this is that there's no point in marking a block as bad, because good | ||
| 110 | blocks are also 'marked as bad' (in the OOB BBM sense) under normal usage. | ||
| 111 | |||
| 112 | Instead, the driver relies on the bad block table alone, and should only perform | ||
| 113 | the bad block scan on the very first time (when the device hasn't been used). | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 9bf651c57806..6d73831cfdee 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -5622,10 +5622,11 @@ F: mm/page_cgroup.c | |||
| 5622 | 5622 | ||
| 5623 | MEMORY TECHNOLOGY DEVICES (MTD) | 5623 | MEMORY TECHNOLOGY DEVICES (MTD) |
| 5624 | M: David Woodhouse <dwmw2@infradead.org> | 5624 | M: David Woodhouse <dwmw2@infradead.org> |
| 5625 | M: Brian Norris <computersforpeace@gmail.com> | ||
| 5625 | L: linux-mtd@lists.infradead.org | 5626 | L: linux-mtd@lists.infradead.org |
| 5626 | W: http://www.linux-mtd.infradead.org/ | 5627 | W: http://www.linux-mtd.infradead.org/ |
| 5627 | Q: http://patchwork.ozlabs.org/project/linux-mtd/list/ | 5628 | Q: http://patchwork.ozlabs.org/project/linux-mtd/list/ |
| 5628 | T: git git://git.infradead.org/mtd-2.6.git | 5629 | T: git git://git.infradead.org/linux-mtd.git |
| 5629 | S: Maintained | 5630 | S: Maintained |
| 5630 | F: drivers/mtd/ | 5631 | F: drivers/mtd/ |
| 5631 | F: include/linux/mtd/ | 5632 | F: include/linux/mtd/ |
| @@ -6942,6 +6943,12 @@ F: include/sound/pxa2xx-lib.h | |||
| 6942 | F: sound/arm/pxa* | 6943 | F: sound/arm/pxa* |
| 6943 | F: sound/soc/pxa/ | 6944 | F: sound/soc/pxa/ |
| 6944 | 6945 | ||
| 6946 | PXA3xx NAND FLASH DRIVER | ||
| 6947 | M: Ezequiel Garcia <ezequiel.garcia@free-electrons.com> | ||
| 6948 | L: linux-mtd@lists.infradead.org | ||
| 6949 | S: Maintained | ||
| 6950 | F: drivers/mtd/nand/pxa3xx-nand.c | ||
| 6951 | |||
| 6945 | MMP SUPPORT | 6952 | MMP SUPPORT |
| 6946 | M: Eric Miao <eric.y.miao@gmail.com> | 6953 | M: Eric Miao <eric.y.miao@gmail.com> |
| 6947 | M: Haojian Zhuang <haojian.zhuang@gmail.com> | 6954 | M: Haojian Zhuang <haojian.zhuang@gmail.com> |
diff --git a/arch/arm/plat-samsung/include/plat/regs-nand.h b/arch/arm/plat-samsung/include/plat/regs-nand.h deleted file mode 100644 index 238efea7b9e4..000000000000 --- a/arch/arm/plat-samsung/include/plat/regs-nand.h +++ /dev/null | |||
| @@ -1,123 +0,0 @@ | |||
| 1 | /* arch/arm/mach-s3c2410/include/mach/regs-nand.h | ||
| 2 | * | ||
| 3 | * Copyright (c) 2004-2005 Simtec Electronics <linux@simtec.co.uk> | ||
| 4 | * http://www.simtec.co.uk/products/SWLINUX/ | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License version 2 as | ||
| 8 | * published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * S3C2410 NAND register definitions | ||
| 11 | */ | ||
| 12 | |||
| 13 | #ifndef __ASM_ARM_REGS_NAND | ||
| 14 | #define __ASM_ARM_REGS_NAND | ||
| 15 | |||
| 16 | |||
| 17 | #define S3C2410_NFREG(x) (x) | ||
| 18 | |||
| 19 | #define S3C2410_NFCONF S3C2410_NFREG(0x00) | ||
| 20 | #define S3C2410_NFCMD S3C2410_NFREG(0x04) | ||
| 21 | #define S3C2410_NFADDR S3C2410_NFREG(0x08) | ||
| 22 | #define S3C2410_NFDATA S3C2410_NFREG(0x0C) | ||
| 23 | #define S3C2410_NFSTAT S3C2410_NFREG(0x10) | ||
| 24 | #define S3C2410_NFECC S3C2410_NFREG(0x14) | ||
| 25 | |||
| 26 | #define S3C2440_NFCONT S3C2410_NFREG(0x04) | ||
| 27 | #define S3C2440_NFCMD S3C2410_NFREG(0x08) | ||
| 28 | #define S3C2440_NFADDR S3C2410_NFREG(0x0C) | ||
| 29 | #define S3C2440_NFDATA S3C2410_NFREG(0x10) | ||
| 30 | #define S3C2440_NFECCD0 S3C2410_NFREG(0x14) | ||
| 31 | #define S3C2440_NFECCD1 S3C2410_NFREG(0x18) | ||
| 32 | #define S3C2440_NFECCD S3C2410_NFREG(0x1C) | ||
| 33 | #define S3C2440_NFSTAT S3C2410_NFREG(0x20) | ||
| 34 | #define S3C2440_NFESTAT0 S3C2410_NFREG(0x24) | ||
| 35 | #define S3C2440_NFESTAT1 S3C2410_NFREG(0x28) | ||
| 36 | #define S3C2440_NFMECC0 S3C2410_NFREG(0x2C) | ||
| 37 | #define S3C2440_NFMECC1 S3C2410_NFREG(0x30) | ||
| 38 | #define S3C2440_NFSECC S3C2410_NFREG(0x34) | ||
| 39 | #define S3C2440_NFSBLK S3C2410_NFREG(0x38) | ||
| 40 | #define S3C2440_NFEBLK S3C2410_NFREG(0x3C) | ||
| 41 | |||
| 42 | #define S3C2412_NFSBLK S3C2410_NFREG(0x20) | ||
| 43 | #define S3C2412_NFEBLK S3C2410_NFREG(0x24) | ||
| 44 | #define S3C2412_NFSTAT S3C2410_NFREG(0x28) | ||
| 45 | #define S3C2412_NFMECC_ERR0 S3C2410_NFREG(0x2C) | ||
| 46 | #define S3C2412_NFMECC_ERR1 S3C2410_NFREG(0x30) | ||
| 47 | #define S3C2412_NFMECC0 S3C2410_NFREG(0x34) | ||
| 48 | #define S3C2412_NFMECC1 S3C2410_NFREG(0x38) | ||
| 49 | #define S3C2412_NFSECC S3C2410_NFREG(0x3C) | ||
| 50 | |||
| 51 | #define S3C2410_NFCONF_EN (1<<15) | ||
| 52 | #define S3C2410_NFCONF_512BYTE (1<<14) | ||
| 53 | #define S3C2410_NFCONF_4STEP (1<<13) | ||
| 54 | #define S3C2410_NFCONF_INITECC (1<<12) | ||
| 55 | #define S3C2410_NFCONF_nFCE (1<<11) | ||
| 56 | #define S3C2410_NFCONF_TACLS(x) ((x)<<8) | ||
| 57 | #define S3C2410_NFCONF_TWRPH0(x) ((x)<<4) | ||
| 58 | #define S3C2410_NFCONF_TWRPH1(x) ((x)<<0) | ||
| 59 | |||
| 60 | #define S3C2410_NFSTAT_BUSY (1<<0) | ||
| 61 | |||
| 62 | #define S3C2440_NFCONF_BUSWIDTH_8 (0<<0) | ||
| 63 | #define S3C2440_NFCONF_BUSWIDTH_16 (1<<0) | ||
| 64 | #define S3C2440_NFCONF_ADVFLASH (1<<3) | ||
| 65 | #define S3C2440_NFCONF_TACLS(x) ((x)<<12) | ||
| 66 | #define S3C2440_NFCONF_TWRPH0(x) ((x)<<8) | ||
| 67 | #define S3C2440_NFCONF_TWRPH1(x) ((x)<<4) | ||
| 68 | |||
| 69 | #define S3C2440_NFCONT_LOCKTIGHT (1<<13) | ||
| 70 | #define S3C2440_NFCONT_SOFTLOCK (1<<12) | ||
| 71 | #define S3C2440_NFCONT_ILLEGALACC_EN (1<<10) | ||
| 72 | #define S3C2440_NFCONT_RNBINT_EN (1<<9) | ||
| 73 | #define S3C2440_NFCONT_RN_FALLING (1<<8) | ||
| 74 | #define S3C2440_NFCONT_SPARE_ECCLOCK (1<<6) | ||
| 75 | #define S3C2440_NFCONT_MAIN_ECCLOCK (1<<5) | ||
| 76 | #define S3C2440_NFCONT_INITECC (1<<4) | ||
| 77 | #define S3C2440_NFCONT_nFCE (1<<1) | ||
| 78 | #define S3C2440_NFCONT_ENABLE (1<<0) | ||
| 79 | |||
| 80 | #define S3C2440_NFSTAT_READY (1<<0) | ||
| 81 | #define S3C2440_NFSTAT_nCE (1<<1) | ||
| 82 | #define S3C2440_NFSTAT_RnB_CHANGE (1<<2) | ||
| 83 | #define S3C2440_NFSTAT_ILLEGAL_ACCESS (1<<3) | ||
| 84 | |||
| 85 | #define S3C2412_NFCONF_NANDBOOT (1<<31) | ||
| 86 | #define S3C2412_NFCONF_ECCCLKCON (1<<30) | ||
| 87 | #define S3C2412_NFCONF_ECC_MLC (1<<24) | ||
| 88 | #define S3C2412_NFCONF_TACLS_MASK (7<<12) /* 1 extra bit of Tacls */ | ||
| 89 | |||
| 90 | #define S3C2412_NFCONT_ECC4_DIRWR (1<<18) | ||
| 91 | #define S3C2412_NFCONT_LOCKTIGHT (1<<17) | ||
| 92 | #define S3C2412_NFCONT_SOFTLOCK (1<<16) | ||
| 93 | #define S3C2412_NFCONT_ECC4_ENCINT (1<<13) | ||
| 94 | #define S3C2412_NFCONT_ECC4_DECINT (1<<12) | ||
| 95 | #define S3C2412_NFCONT_MAIN_ECC_LOCK (1<<7) | ||
| 96 | #define S3C2412_NFCONT_INIT_MAIN_ECC (1<<5) | ||
| 97 | #define S3C2412_NFCONT_nFCE1 (1<<2) | ||
| 98 | #define S3C2412_NFCONT_nFCE0 (1<<1) | ||
| 99 | |||
| 100 | #define S3C2412_NFSTAT_ECC_ENCDONE (1<<7) | ||
| 101 | #define S3C2412_NFSTAT_ECC_DECDONE (1<<6) | ||
| 102 | #define S3C2412_NFSTAT_ILLEGAL_ACCESS (1<<5) | ||
| 103 | #define S3C2412_NFSTAT_RnB_CHANGE (1<<4) | ||
| 104 | #define S3C2412_NFSTAT_nFCE1 (1<<3) | ||
| 105 | #define S3C2412_NFSTAT_nFCE0 (1<<2) | ||
| 106 | #define S3C2412_NFSTAT_Res1 (1<<1) | ||
| 107 | #define S3C2412_NFSTAT_READY (1<<0) | ||
| 108 | |||
| 109 | #define S3C2412_NFECCERR_SERRDATA(x) (((x) >> 21) & 0xf) | ||
| 110 | #define S3C2412_NFECCERR_SERRBIT(x) (((x) >> 18) & 0x7) | ||
| 111 | #define S3C2412_NFECCERR_MERRDATA(x) (((x) >> 7) & 0x3ff) | ||
| 112 | #define S3C2412_NFECCERR_MERRBIT(x) (((x) >> 4) & 0x7) | ||
| 113 | #define S3C2412_NFECCERR_SPARE_ERR(x) (((x) >> 2) & 0x3) | ||
| 114 | #define S3C2412_NFECCERR_MAIN_ERR(x) (((x) >> 2) & 0x3) | ||
| 115 | #define S3C2412_NFECCERR_NONE (0) | ||
| 116 | #define S3C2412_NFECCERR_1BIT (1) | ||
| 117 | #define S3C2412_NFECCERR_MULTIBIT (2) | ||
| 118 | #define S3C2412_NFECCERR_ECCAREA (3) | ||
| 119 | |||
| 120 | |||
| 121 | |||
| 122 | #endif /* __ASM_ARM_REGS_NAND */ | ||
| 123 | |||
diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 5fab4e6e8301..5ebcda39f554 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig | |||
| @@ -157,10 +157,11 @@ config MTD_BCM47XX_PARTS | |||
| 157 | 157 | ||
| 158 | comment "User Modules And Translation Layers" | 158 | comment "User Modules And Translation Layers" |
| 159 | 159 | ||
| 160 | # | ||
| 161 | # MTD block device support is select'ed if needed | ||
| 162 | # | ||
| 160 | config MTD_BLKDEVS | 163 | config MTD_BLKDEVS |
| 161 | tristate "Common interface to block layer for MTD 'translation layers'" | 164 | tristate |
| 162 | depends on BLOCK | ||
| 163 | default n | ||
| 164 | 165 | ||
| 165 | config MTD_BLOCK | 166 | config MTD_BLOCK |
| 166 | tristate "Caching block device access to MTD devices" | 167 | tristate "Caching block device access to MTD devices" |
diff --git a/drivers/mtd/afs.c b/drivers/mtd/afs.c index 5a3942bf109c..96a33e3f7b00 100644 --- a/drivers/mtd/afs.c +++ b/drivers/mtd/afs.c | |||
| @@ -264,7 +264,8 @@ static struct mtd_part_parser afs_parser = { | |||
| 264 | 264 | ||
| 265 | static int __init afs_parser_init(void) | 265 | static int __init afs_parser_init(void) |
| 266 | { | 266 | { |
| 267 | return register_mtd_parser(&afs_parser); | 267 | register_mtd_parser(&afs_parser); |
| 268 | return 0; | ||
| 268 | } | 269 | } |
| 269 | 270 | ||
| 270 | static void __exit afs_parser_exit(void) | 271 | static void __exit afs_parser_exit(void) |
diff --git a/drivers/mtd/ar7part.c b/drivers/mtd/ar7part.c index ddc0a4287a4b..7c9172ad2621 100644 --- a/drivers/mtd/ar7part.c +++ b/drivers/mtd/ar7part.c | |||
| @@ -139,7 +139,8 @@ static struct mtd_part_parser ar7_parser = { | |||
| 139 | 139 | ||
| 140 | static int __init ar7_parser_init(void) | 140 | static int __init ar7_parser_init(void) |
| 141 | { | 141 | { |
| 142 | return register_mtd_parser(&ar7_parser); | 142 | register_mtd_parser(&ar7_parser); |
| 143 | return 0; | ||
| 143 | } | 144 | } |
| 144 | 145 | ||
| 145 | static void __exit ar7_parser_exit(void) | 146 | static void __exit ar7_parser_exit(void) |
diff --git a/drivers/mtd/bcm47xxpart.c b/drivers/mtd/bcm47xxpart.c index 7a6384b0962a..de1eb92e42f5 100644 --- a/drivers/mtd/bcm47xxpart.c +++ b/drivers/mtd/bcm47xxpart.c | |||
| @@ -23,10 +23,12 @@ | |||
| 23 | * Amount of bytes we read when analyzing each block of flash memory. | 23 | * Amount of bytes we read when analyzing each block of flash memory. |
| 24 | * Set it big enough to allow detecting partition and reading important data. | 24 | * Set it big enough to allow detecting partition and reading important data. |
| 25 | */ | 25 | */ |
| 26 | #define BCM47XXPART_BYTES_TO_READ 0x404 | 26 | #define BCM47XXPART_BYTES_TO_READ 0x4e8 |
| 27 | 27 | ||
| 28 | /* Magics */ | 28 | /* Magics */ |
| 29 | #define BOARD_DATA_MAGIC 0x5246504D /* MPFR */ | 29 | #define BOARD_DATA_MAGIC 0x5246504D /* MPFR */ |
| 30 | #define BOARD_DATA_MAGIC2 0xBD0D0BBD | ||
| 31 | #define CFE_MAGIC 0x43464531 /* 1EFC */ | ||
| 30 | #define FACTORY_MAGIC 0x59544346 /* FCTY */ | 32 | #define FACTORY_MAGIC 0x59544346 /* FCTY */ |
| 31 | #define POT_MAGIC1 0x54544f50 /* POTT */ | 33 | #define POT_MAGIC1 0x54544f50 /* POTT */ |
| 32 | #define POT_MAGIC2 0x504f /* OP */ | 34 | #define POT_MAGIC2 0x504f /* OP */ |
| @@ -102,8 +104,9 @@ static int bcm47xxpart_parse(struct mtd_info *master, | |||
| 102 | continue; | 104 | continue; |
| 103 | } | 105 | } |
| 104 | 106 | ||
| 105 | /* CFE has small NVRAM at 0x400 */ | 107 | /* Magic or small NVRAM at 0x400 */ |
| 106 | if (buf[0x400 / 4] == NVRAM_HEADER) { | 108 | if ((buf[0x4e0 / 4] == CFE_MAGIC && buf[0x4e4 / 4] == CFE_MAGIC) || |
| 109 | (buf[0x400 / 4] == NVRAM_HEADER)) { | ||
| 107 | bcm47xxpart_add_part(&parts[curr_part++], "boot", | 110 | bcm47xxpart_add_part(&parts[curr_part++], "boot", |
| 108 | offset, MTD_WRITEABLE); | 111 | offset, MTD_WRITEABLE); |
| 109 | continue; | 112 | continue; |
| @@ -190,6 +193,21 @@ static int bcm47xxpart_parse(struct mtd_info *master, | |||
| 190 | offset, 0); | 193 | offset, 0); |
| 191 | continue; | 194 | continue; |
| 192 | } | 195 | } |
| 196 | |||
| 197 | /* Read middle of the block */ | ||
| 198 | if (mtd_read(master, offset + 0x8000, 0x4, | ||
| 199 | &bytes_read, (uint8_t *)buf) < 0) { | ||
| 200 | pr_err("mtd_read error while parsing (offset: 0x%X)!\n", | ||
| 201 | offset); | ||
| 202 | continue; | ||
| 203 | } | ||
| 204 | |||
| 205 | /* Some devices (ex. WNDR3700v3) don't have a standard 'MPFR' */ | ||
| 206 | if (buf[0x000 / 4] == BOARD_DATA_MAGIC2) { | ||
| 207 | bcm47xxpart_add_part(&parts[curr_part++], "board_data", | ||
| 208 | offset, MTD_WRITEABLE); | ||
| 209 | continue; | ||
| 210 | } | ||
| 193 | } | 211 | } |
| 194 | 212 | ||
| 195 | /* Look for NVRAM at the end of the last block. */ | 213 | /* Look for NVRAM at the end of the last block. */ |
| @@ -243,7 +261,8 @@ static struct mtd_part_parser bcm47xxpart_mtd_parser = { | |||
| 243 | 261 | ||
| 244 | static int __init bcm47xxpart_init(void) | 262 | static int __init bcm47xxpart_init(void) |
| 245 | { | 263 | { |
| 246 | return register_mtd_parser(&bcm47xxpart_mtd_parser); | 264 | register_mtd_parser(&bcm47xxpart_mtd_parser); |
| 265 | return 0; | ||
| 247 | } | 266 | } |
| 248 | 267 | ||
| 249 | static void __exit bcm47xxpart_exit(void) | 268 | static void __exit bcm47xxpart_exit(void) |
diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c index 5c813907661c..b2443f7031c9 100644 --- a/drivers/mtd/bcm63xxpart.c +++ b/drivers/mtd/bcm63xxpart.c | |||
| @@ -221,7 +221,8 @@ static struct mtd_part_parser bcm63xx_cfe_parser = { | |||
| 221 | 221 | ||
| 222 | static int __init bcm63xx_cfe_parser_init(void) | 222 | static int __init bcm63xx_cfe_parser_init(void) |
| 223 | { | 223 | { |
| 224 | return register_mtd_parser(&bcm63xx_cfe_parser); | 224 | register_mtd_parser(&bcm63xx_cfe_parser); |
| 225 | return 0; | ||
| 225 | } | 226 | } |
| 226 | 227 | ||
| 227 | static void __exit bcm63xx_cfe_parser_exit(void) | 228 | static void __exit bcm63xx_cfe_parser_exit(void) |
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c index 721caebbc5cc..3e829b37af8d 100644 --- a/drivers/mtd/cmdlinepart.c +++ b/drivers/mtd/cmdlinepart.c | |||
| @@ -395,7 +395,8 @@ static int __init cmdline_parser_init(void) | |||
| 395 | { | 395 | { |
| 396 | if (mtdparts) | 396 | if (mtdparts) |
| 397 | mtdpart_setup(mtdparts); | 397 | mtdpart_setup(mtdparts); |
| 398 | return register_mtd_parser(&cmdline_parser); | 398 | register_mtd_parser(&cmdline_parser); |
| 399 | return 0; | ||
| 399 | } | 400 | } |
| 400 | 401 | ||
| 401 | static void __exit cmdline_parser_exit(void) | 402 | static void __exit cmdline_parser_exit(void) |
diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index 4f091c1a9981..dd5e1018d37b 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c | |||
| @@ -2047,21 +2047,21 @@ static int __init docg3_probe(struct platform_device *pdev) | |||
| 2047 | ress = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2047 | ress = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 2048 | if (!ress) { | 2048 | if (!ress) { |
| 2049 | dev_err(dev, "No I/O memory resource defined\n"); | 2049 | dev_err(dev, "No I/O memory resource defined\n"); |
| 2050 | goto noress; | 2050 | return ret; |
| 2051 | } | 2051 | } |
| 2052 | base = ioremap(ress->start, DOC_IOSPACE_SIZE); | 2052 | base = devm_ioremap(dev, ress->start, DOC_IOSPACE_SIZE); |
| 2053 | 2053 | ||
| 2054 | ret = -ENOMEM; | 2054 | ret = -ENOMEM; |
| 2055 | cascade = kzalloc(sizeof(*cascade) * DOC_MAX_NBFLOORS, | 2055 | cascade = devm_kzalloc(dev, sizeof(*cascade) * DOC_MAX_NBFLOORS, |
| 2056 | GFP_KERNEL); | 2056 | GFP_KERNEL); |
| 2057 | if (!cascade) | 2057 | if (!cascade) |
| 2058 | goto nomem1; | 2058 | return ret; |
| 2059 | cascade->base = base; | 2059 | cascade->base = base; |
| 2060 | mutex_init(&cascade->lock); | 2060 | mutex_init(&cascade->lock); |
| 2061 | cascade->bch = init_bch(DOC_ECC_BCH_M, DOC_ECC_BCH_T, | 2061 | cascade->bch = init_bch(DOC_ECC_BCH_M, DOC_ECC_BCH_T, |
| 2062 | DOC_ECC_BCH_PRIMPOLY); | 2062 | DOC_ECC_BCH_PRIMPOLY); |
| 2063 | if (!cascade->bch) | 2063 | if (!cascade->bch) |
| 2064 | goto nomem2; | 2064 | return ret; |
| 2065 | 2065 | ||
| 2066 | for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) { | 2066 | for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) { |
| 2067 | mtd = doc_probe_device(cascade, floor, dev); | 2067 | mtd = doc_probe_device(cascade, floor, dev); |
| @@ -2101,11 +2101,6 @@ err_probe: | |||
| 2101 | for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) | 2101 | for (floor = 0; floor < DOC_MAX_NBFLOORS; floor++) |
| 2102 | if (cascade->floors[floor]) | 2102 | if (cascade->floors[floor]) |
| 2103 | doc_release_device(cascade->floors[floor]); | 2103 | doc_release_device(cascade->floors[floor]); |
| 2104 | nomem2: | ||
| 2105 | kfree(cascade); | ||
| 2106 | nomem1: | ||
| 2107 | iounmap(base); | ||
| 2108 | noress: | ||
| 2109 | return ret; | 2104 | return ret; |
| 2110 | } | 2105 | } |
| 2111 | 2106 | ||
| @@ -2119,7 +2114,6 @@ static int __exit docg3_release(struct platform_device *pdev) | |||
| 2119 | { | 2114 | { |
| 2120 | struct docg3_cascade *cascade = platform_get_drvdata(pdev); | 2115 | struct docg3_cascade *cascade = platform_get_drvdata(pdev); |
| 2121 | struct docg3 *docg3 = cascade->floors[0]->priv; | 2116 | struct docg3 *docg3 = cascade->floors[0]->priv; |
| 2122 | void __iomem *base = cascade->base; | ||
| 2123 | int floor; | 2117 | int floor; |
| 2124 | 2118 | ||
| 2125 | doc_unregister_sysfs(pdev, cascade); | 2119 | doc_unregister_sysfs(pdev, cascade); |
| @@ -2129,8 +2123,6 @@ static int __exit docg3_release(struct platform_device *pdev) | |||
| 2129 | doc_release_device(cascade->floors[floor]); | 2123 | doc_release_device(cascade->floors[floor]); |
| 2130 | 2124 | ||
| 2131 | free_bch(docg3->cascade->bch); | 2125 | free_bch(docg3->cascade->bch); |
| 2132 | kfree(cascade); | ||
| 2133 | iounmap(base); | ||
| 2134 | return 0; | 2126 | return 0; |
| 2135 | } | 2127 | } |
| 2136 | 2128 | ||
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 7eda71dbc183..ad1913909702 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | #define OPCODE_WRSR 0x01 /* Write status register 1 byte */ | 41 | #define OPCODE_WRSR 0x01 /* Write status register 1 byte */ |
| 42 | #define OPCODE_NORM_READ 0x03 /* Read data bytes (low frequency) */ | 42 | #define OPCODE_NORM_READ 0x03 /* Read data bytes (low frequency) */ |
| 43 | #define OPCODE_FAST_READ 0x0b /* Read data bytes (high frequency) */ | 43 | #define OPCODE_FAST_READ 0x0b /* Read data bytes (high frequency) */ |
| 44 | #define OPCODE_QUAD_READ 0x6b /* Read data bytes */ | ||
| 44 | #define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */ | 45 | #define OPCODE_PP 0x02 /* Page program (up to 256 bytes) */ |
| 45 | #define OPCODE_BE_4K 0x20 /* Erase 4KiB block */ | 46 | #define OPCODE_BE_4K 0x20 /* Erase 4KiB block */ |
| 46 | #define OPCODE_BE_4K_PMC 0xd7 /* Erase 4KiB block on PMC chips */ | 47 | #define OPCODE_BE_4K_PMC 0xd7 /* Erase 4KiB block on PMC chips */ |
| @@ -48,10 +49,12 @@ | |||
| 48 | #define OPCODE_CHIP_ERASE 0xc7 /* Erase whole flash chip */ | 49 | #define OPCODE_CHIP_ERASE 0xc7 /* Erase whole flash chip */ |
| 49 | #define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */ | 50 | #define OPCODE_SE 0xd8 /* Sector erase (usually 64KiB) */ |
| 50 | #define OPCODE_RDID 0x9f /* Read JEDEC ID */ | 51 | #define OPCODE_RDID 0x9f /* Read JEDEC ID */ |
| 52 | #define OPCODE_RDCR 0x35 /* Read configuration register */ | ||
| 51 | 53 | ||
| 52 | /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */ | 54 | /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */ |
| 53 | #define OPCODE_NORM_READ_4B 0x13 /* Read data bytes (low frequency) */ | 55 | #define OPCODE_NORM_READ_4B 0x13 /* Read data bytes (low frequency) */ |
| 54 | #define OPCODE_FAST_READ_4B 0x0c /* Read data bytes (high frequency) */ | 56 | #define OPCODE_FAST_READ_4B 0x0c /* Read data bytes (high frequency) */ |
| 57 | #define OPCODE_QUAD_READ_4B 0x6c /* Read data bytes */ | ||
| 55 | #define OPCODE_PP_4B 0x12 /* Page program (up to 256 bytes) */ | 58 | #define OPCODE_PP_4B 0x12 /* Page program (up to 256 bytes) */ |
| 56 | #define OPCODE_SE_4B 0xdc /* Sector erase (usually 64KiB) */ | 59 | #define OPCODE_SE_4B 0xdc /* Sector erase (usually 64KiB) */ |
| 57 | 60 | ||
| @@ -76,6 +79,11 @@ | |||
| 76 | #define SR_BP2 0x10 /* Block protect 2 */ | 79 | #define SR_BP2 0x10 /* Block protect 2 */ |
| 77 | #define SR_SRWD 0x80 /* SR write protect */ | 80 | #define SR_SRWD 0x80 /* SR write protect */ |
| 78 | 81 | ||
| 82 | #define SR_QUAD_EN_MX 0x40 /* Macronix Quad I/O */ | ||
| 83 | |||
| 84 | /* Configuration Register bits. */ | ||
| 85 | #define CR_QUAD_EN_SPAN 0x2 /* Spansion Quad I/O */ | ||
| 86 | |||
| 79 | /* Define max times to check status register before we give up. */ | 87 | /* Define max times to check status register before we give up. */ |
| 80 | #define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */ | 88 | #define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */ |
| 81 | #define MAX_CMD_SIZE 6 | 89 | #define MAX_CMD_SIZE 6 |
| @@ -84,6 +92,12 @@ | |||
| 84 | 92 | ||
| 85 | /****************************************************************************/ | 93 | /****************************************************************************/ |
| 86 | 94 | ||
| 95 | enum read_type { | ||
| 96 | M25P80_NORMAL = 0, | ||
| 97 | M25P80_FAST, | ||
| 98 | M25P80_QUAD, | ||
| 99 | }; | ||
| 100 | |||
| 87 | struct m25p { | 101 | struct m25p { |
| 88 | struct spi_device *spi; | 102 | struct spi_device *spi; |
| 89 | struct mutex lock; | 103 | struct mutex lock; |
| @@ -94,7 +108,7 @@ struct m25p { | |||
| 94 | u8 read_opcode; | 108 | u8 read_opcode; |
| 95 | u8 program_opcode; | 109 | u8 program_opcode; |
| 96 | u8 *command; | 110 | u8 *command; |
| 97 | bool fast_read; | 111 | enum read_type flash_read; |
| 98 | }; | 112 | }; |
| 99 | 113 | ||
| 100 | static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd) | 114 | static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd) |
| @@ -131,6 +145,26 @@ static int read_sr(struct m25p *flash) | |||
| 131 | } | 145 | } |
| 132 | 146 | ||
| 133 | /* | 147 | /* |
| 148 | * Read configuration register, returning its value in the | ||
| 149 | * location. Return the configuration register value. | ||
| 150 | * Returns negative if error occured. | ||
| 151 | */ | ||
| 152 | static int read_cr(struct m25p *flash) | ||
| 153 | { | ||
| 154 | u8 code = OPCODE_RDCR; | ||
| 155 | int ret; | ||
| 156 | u8 val; | ||
| 157 | |||
| 158 | ret = spi_write_then_read(flash->spi, &code, 1, &val, 1); | ||
| 159 | if (ret < 0) { | ||
| 160 | dev_err(&flash->spi->dev, "error %d reading CR\n", ret); | ||
| 161 | return ret; | ||
| 162 | } | ||
| 163 | |||
| 164 | return val; | ||
| 165 | } | ||
| 166 | |||
| 167 | /* | ||
| 134 | * Write status register 1 byte | 168 | * Write status register 1 byte |
| 135 | * Returns negative if error occurred. | 169 | * Returns negative if error occurred. |
| 136 | */ | 170 | */ |
| @@ -220,6 +254,93 @@ static int wait_till_ready(struct m25p *flash) | |||
| 220 | } | 254 | } |
| 221 | 255 | ||
| 222 | /* | 256 | /* |
| 257 | * Write status Register and configuration register with 2 bytes | ||
| 258 | * The first byte will be written to the status register, while the | ||
| 259 | * second byte will be written to the configuration register. | ||
| 260 | * Return negative if error occured. | ||
| 261 | */ | ||
| 262 | static int write_sr_cr(struct m25p *flash, u16 val) | ||
| 263 | { | ||
| 264 | flash->command[0] = OPCODE_WRSR; | ||
| 265 | flash->command[1] = val & 0xff; | ||
| 266 | flash->command[2] = (val >> 8); | ||
| 267 | |||
| 268 | return spi_write(flash->spi, flash->command, 3); | ||
| 269 | } | ||
| 270 | |||
| 271 | static int macronix_quad_enable(struct m25p *flash) | ||
| 272 | { | ||
| 273 | int ret, val; | ||
| 274 | u8 cmd[2]; | ||
| 275 | cmd[0] = OPCODE_WRSR; | ||
| 276 | |||
| 277 | val = read_sr(flash); | ||
| 278 | cmd[1] = val | SR_QUAD_EN_MX; | ||
| 279 | write_enable(flash); | ||
| 280 | |||
| 281 | spi_write(flash->spi, &cmd, 2); | ||
| 282 | |||
| 283 | if (wait_till_ready(flash)) | ||
| 284 | return 1; | ||
| 285 | |||
| 286 | ret = read_sr(flash); | ||
| 287 | if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) { | ||
| 288 | dev_err(&flash->spi->dev, "Macronix Quad bit not set\n"); | ||
| 289 | return -EINVAL; | ||
| 290 | } | ||
| 291 | |||
| 292 | return 0; | ||
| 293 | } | ||
| 294 | |||
| 295 | static int spansion_quad_enable(struct m25p *flash) | ||
| 296 | { | ||
| 297 | int ret; | ||
| 298 | int quad_en = CR_QUAD_EN_SPAN << 8; | ||
| 299 | |||
| 300 | write_enable(flash); | ||
| 301 | |||
| 302 | ret = write_sr_cr(flash, quad_en); | ||
| 303 | if (ret < 0) { | ||
| 304 | dev_err(&flash->spi->dev, | ||
| 305 | "error while writing configuration register\n"); | ||
| 306 | return -EINVAL; | ||
| 307 | } | ||
| 308 | |||
| 309 | /* read back and check it */ | ||
| 310 | ret = read_cr(flash); | ||
| 311 | if (!(ret > 0 && (ret & CR_QUAD_EN_SPAN))) { | ||
| 312 | dev_err(&flash->spi->dev, "Spansion Quad bit not set\n"); | ||
| 313 | return -EINVAL; | ||
| 314 | } | ||
| 315 | |||
| 316 | return 0; | ||
| 317 | } | ||
| 318 | |||
| 319 | static int set_quad_mode(struct m25p *flash, u32 jedec_id) | ||
| 320 | { | ||
| 321 | int status; | ||
| 322 | |||
| 323 | switch (JEDEC_MFR(jedec_id)) { | ||
| 324 | case CFI_MFR_MACRONIX: | ||
| 325 | status = macronix_quad_enable(flash); | ||
| 326 | if (status) { | ||
| 327 | dev_err(&flash->spi->dev, | ||
| 328 | "Macronix quad-read not enabled\n"); | ||
| 329 | return -EINVAL; | ||
| 330 | } | ||
| 331 | return status; | ||
| 332 | default: | ||
| 333 | status = spansion_quad_enable(flash); | ||
| 334 | if (status) { | ||
| 335 | dev_err(&flash->spi->dev, | ||
| 336 | "Spansion quad-read not enabled\n"); | ||
| 337 | return -EINVAL; | ||
| 338 | } | ||
| 339 | return status; | ||
| 340 | } | ||
| 341 | } | ||
| 342 | |||
| 343 | /* | ||
| 223 | * Erase the whole flash memory | 344 | * Erase the whole flash memory |
| 224 | * | 345 | * |
| 225 | * Returns 0 if successful, non-zero otherwise. | 346 | * Returns 0 if successful, non-zero otherwise. |
| @@ -350,6 +471,35 @@ static int m25p80_erase(struct mtd_info *mtd, struct erase_info *instr) | |||
| 350 | } | 471 | } |
| 351 | 472 | ||
| 352 | /* | 473 | /* |
| 474 | * Dummy Cycle calculation for different type of read. | ||
| 475 | * It can be used to support more commands with | ||
| 476 | * different dummy cycle requirements. | ||
| 477 | */ | ||
| 478 | static inline int m25p80_dummy_cycles_read(struct m25p *flash) | ||
| 479 | { | ||
| 480 | switch (flash->flash_read) { | ||
| 481 | case M25P80_FAST: | ||
| 482 | case M25P80_QUAD: | ||
| 483 | return 1; | ||
| 484 | case M25P80_NORMAL: | ||
| 485 | return 0; | ||
| 486 | default: | ||
| 487 | dev_err(&flash->spi->dev, "No valid read type supported\n"); | ||
| 488 | return -1; | ||
| 489 | } | ||
| 490 | } | ||
| 491 | |||
| 492 | static inline unsigned int m25p80_rx_nbits(const struct m25p *flash) | ||
| 493 | { | ||
| 494 | switch (flash->flash_read) { | ||
| 495 | case M25P80_QUAD: | ||
| 496 | return 4; | ||
| 497 | default: | ||
| 498 | return 0; | ||
| 499 | } | ||
| 500 | } | ||
| 501 | |||
| 502 | /* | ||
| 353 | * Read an address range from the flash chip. The address range | 503 | * Read an address range from the flash chip. The address range |
| 354 | * may be any size provided it is within the physical boundaries. | 504 | * may be any size provided it is within the physical boundaries. |
| 355 | */ | 505 | */ |
| @@ -360,6 +510,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
| 360 | struct spi_transfer t[2]; | 510 | struct spi_transfer t[2]; |
| 361 | struct spi_message m; | 511 | struct spi_message m; |
| 362 | uint8_t opcode; | 512 | uint8_t opcode; |
| 513 | int dummy; | ||
| 363 | 514 | ||
| 364 | pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev), | 515 | pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev), |
| 365 | __func__, (u32)from, len); | 516 | __func__, (u32)from, len); |
| @@ -367,11 +518,18 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
| 367 | spi_message_init(&m); | 518 | spi_message_init(&m); |
| 368 | memset(t, 0, (sizeof t)); | 519 | memset(t, 0, (sizeof t)); |
| 369 | 520 | ||
| 521 | dummy = m25p80_dummy_cycles_read(flash); | ||
| 522 | if (dummy < 0) { | ||
| 523 | dev_err(&flash->spi->dev, "No valid read command supported\n"); | ||
| 524 | return -EINVAL; | ||
| 525 | } | ||
| 526 | |||
| 370 | t[0].tx_buf = flash->command; | 527 | t[0].tx_buf = flash->command; |
| 371 | t[0].len = m25p_cmdsz(flash) + (flash->fast_read ? 1 : 0); | 528 | t[0].len = m25p_cmdsz(flash) + dummy; |
| 372 | spi_message_add_tail(&t[0], &m); | 529 | spi_message_add_tail(&t[0], &m); |
| 373 | 530 | ||
| 374 | t[1].rx_buf = buf; | 531 | t[1].rx_buf = buf; |
| 532 | t[1].rx_nbits = m25p80_rx_nbits(flash); | ||
| 375 | t[1].len = len; | 533 | t[1].len = len; |
| 376 | spi_message_add_tail(&t[1], &m); | 534 | spi_message_add_tail(&t[1], &m); |
| 377 | 535 | ||
| @@ -391,8 +549,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
| 391 | 549 | ||
| 392 | spi_sync(flash->spi, &m); | 550 | spi_sync(flash->spi, &m); |
| 393 | 551 | ||
| 394 | *retlen = m.actual_length - m25p_cmdsz(flash) - | 552 | *retlen = m.actual_length - m25p_cmdsz(flash) - dummy; |
| 395 | (flash->fast_read ? 1 : 0); | ||
| 396 | 553 | ||
| 397 | mutex_unlock(&flash->lock); | 554 | mutex_unlock(&flash->lock); |
| 398 | 555 | ||
| @@ -698,6 +855,7 @@ struct flash_info { | |||
| 698 | #define SST_WRITE 0x04 /* use SST byte programming */ | 855 | #define SST_WRITE 0x04 /* use SST byte programming */ |
| 699 | #define M25P_NO_FR 0x08 /* Can't do fastread */ | 856 | #define M25P_NO_FR 0x08 /* Can't do fastread */ |
| 700 | #define SECT_4K_PMC 0x10 /* OPCODE_BE_4K_PMC works uniformly */ | 857 | #define SECT_4K_PMC 0x10 /* OPCODE_BE_4K_PMC works uniformly */ |
| 858 | #define M25P80_QUAD_READ 0x20 /* Flash supports Quad Read */ | ||
| 701 | }; | 859 | }; |
| 702 | 860 | ||
| 703 | #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ | 861 | #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags) \ |
| @@ -775,7 +933,7 @@ static const struct spi_device_id m25p_ids[] = { | |||
| 775 | { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, | 933 | { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, |
| 776 | { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) }, | 934 | { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) }, |
| 777 | { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, | 935 | { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, |
| 778 | { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, 0) }, | 936 | { "mx66l51235l", INFO(0xc2201a, 0, 64 * 1024, 1024, M25P80_QUAD_READ) }, |
| 779 | 937 | ||
| 780 | /* Micron */ | 938 | /* Micron */ |
| 781 | { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, 0) }, | 939 | { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, 0) }, |
| @@ -795,8 +953,8 @@ static const struct spi_device_id m25p_ids[] = { | |||
| 795 | { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, 0) }, | 953 | { "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64, 0) }, |
| 796 | { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, 0) }, | 954 | { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, 0) }, |
| 797 | { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) }, | 955 | { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) }, |
| 798 | { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, 0) }, | 956 | { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, M25P80_QUAD_READ) }, |
| 799 | { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, 0) }, | 957 | { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, M25P80_QUAD_READ) }, |
| 800 | { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, | 958 | { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, |
| 801 | { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, | 959 | { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, |
| 802 | { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) }, | 960 | { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) }, |
| @@ -851,6 +1009,7 @@ static const struct spi_device_id m25p_ids[] = { | |||
| 851 | { "m25pe80", INFO(0x208014, 0, 64 * 1024, 16, 0) }, | 1009 | { "m25pe80", INFO(0x208014, 0, 64 * 1024, 16, 0) }, |
| 852 | { "m25pe16", INFO(0x208015, 0, 64 * 1024, 32, SECT_4K) }, | 1010 | { "m25pe16", INFO(0x208015, 0, 64 * 1024, 32, SECT_4K) }, |
| 853 | 1011 | ||
| 1012 | { "m25px16", INFO(0x207115, 0, 64 * 1024, 32, SECT_4K) }, | ||
| 854 | { "m25px32", INFO(0x207116, 0, 64 * 1024, 64, SECT_4K) }, | 1013 | { "m25px32", INFO(0x207116, 0, 64 * 1024, 64, SECT_4K) }, |
| 855 | { "m25px32-s0", INFO(0x207316, 0, 64 * 1024, 64, SECT_4K) }, | 1014 | { "m25px32-s0", INFO(0x207316, 0, 64 * 1024, 64, SECT_4K) }, |
| 856 | { "m25px32-s1", INFO(0x206316, 0, 64 * 1024, 64, SECT_4K) }, | 1015 | { "m25px32-s1", INFO(0x206316, 0, 64 * 1024, 64, SECT_4K) }, |
| @@ -937,6 +1096,7 @@ static int m25p_probe(struct spi_device *spi) | |||
| 937 | unsigned i; | 1096 | unsigned i; |
| 938 | struct mtd_part_parser_data ppdata; | 1097 | struct mtd_part_parser_data ppdata; |
| 939 | struct device_node *np = spi->dev.of_node; | 1098 | struct device_node *np = spi->dev.of_node; |
| 1099 | int ret; | ||
| 940 | 1100 | ||
| 941 | /* Platform data helps sort out which chip type we have, as | 1101 | /* Platform data helps sort out which chip type we have, as |
| 942 | * well as how this board partitions it. If we don't have | 1102 | * well as how this board partitions it. If we don't have |
| @@ -1051,22 +1211,46 @@ static int m25p_probe(struct spi_device *spi) | |||
| 1051 | flash->page_size = info->page_size; | 1211 | flash->page_size = info->page_size; |
| 1052 | flash->mtd.writebufsize = flash->page_size; | 1212 | flash->mtd.writebufsize = flash->page_size; |
| 1053 | 1213 | ||
| 1054 | if (np) | 1214 | if (np) { |
| 1055 | /* If we were instantiated by DT, use it */ | 1215 | /* If we were instantiated by DT, use it */ |
| 1056 | flash->fast_read = of_property_read_bool(np, "m25p,fast-read"); | 1216 | if (of_property_read_bool(np, "m25p,fast-read")) |
| 1057 | else | 1217 | flash->flash_read = M25P80_FAST; |
| 1218 | else | ||
| 1219 | flash->flash_read = M25P80_NORMAL; | ||
| 1220 | } else { | ||
| 1058 | /* If we weren't instantiated by DT, default to fast-read */ | 1221 | /* If we weren't instantiated by DT, default to fast-read */ |
| 1059 | flash->fast_read = true; | 1222 | flash->flash_read = M25P80_FAST; |
| 1223 | } | ||
| 1060 | 1224 | ||
| 1061 | /* Some devices cannot do fast-read, no matter what DT tells us */ | 1225 | /* Some devices cannot do fast-read, no matter what DT tells us */ |
| 1062 | if (info->flags & M25P_NO_FR) | 1226 | if (info->flags & M25P_NO_FR) |
| 1063 | flash->fast_read = false; | 1227 | flash->flash_read = M25P80_NORMAL; |
| 1228 | |||
| 1229 | /* Quad-read mode takes precedence over fast/normal */ | ||
| 1230 | if (spi->mode & SPI_RX_QUAD && info->flags & M25P80_QUAD_READ) { | ||
| 1231 | ret = set_quad_mode(flash, info->jedec_id); | ||
| 1232 | if (ret) { | ||
| 1233 | dev_err(&flash->spi->dev, "quad mode not supported\n"); | ||
| 1234 | return ret; | ||
| 1235 | } | ||
| 1236 | flash->flash_read = M25P80_QUAD; | ||
| 1237 | } | ||
| 1064 | 1238 | ||
| 1065 | /* Default commands */ | 1239 | /* Default commands */ |
| 1066 | if (flash->fast_read) | 1240 | switch (flash->flash_read) { |
| 1241 | case M25P80_QUAD: | ||
| 1242 | flash->read_opcode = OPCODE_QUAD_READ; | ||
| 1243 | break; | ||
| 1244 | case M25P80_FAST: | ||
| 1067 | flash->read_opcode = OPCODE_FAST_READ; | 1245 | flash->read_opcode = OPCODE_FAST_READ; |
| 1068 | else | 1246 | break; |
| 1247 | case M25P80_NORMAL: | ||
| 1069 | flash->read_opcode = OPCODE_NORM_READ; | 1248 | flash->read_opcode = OPCODE_NORM_READ; |
| 1249 | break; | ||
| 1250 | default: | ||
| 1251 | dev_err(&flash->spi->dev, "No Read opcode defined\n"); | ||
| 1252 | return -EINVAL; | ||
| 1253 | } | ||
| 1070 | 1254 | ||
| 1071 | flash->program_opcode = OPCODE_PP; | 1255 | flash->program_opcode = OPCODE_PP; |
| 1072 | 1256 | ||
| @@ -1077,9 +1261,17 @@ static int m25p_probe(struct spi_device *spi) | |||
| 1077 | flash->addr_width = 4; | 1261 | flash->addr_width = 4; |
| 1078 | if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) { | 1262 | if (JEDEC_MFR(info->jedec_id) == CFI_MFR_AMD) { |
| 1079 | /* Dedicated 4-byte command set */ | 1263 | /* Dedicated 4-byte command set */ |
| 1080 | flash->read_opcode = flash->fast_read ? | 1264 | switch (flash->flash_read) { |
| 1081 | OPCODE_FAST_READ_4B : | 1265 | case M25P80_QUAD: |
| 1082 | OPCODE_NORM_READ_4B; | 1266 | flash->read_opcode = OPCODE_QUAD_READ_4B; |
| 1267 | break; | ||
| 1268 | case M25P80_FAST: | ||
| 1269 | flash->read_opcode = OPCODE_FAST_READ_4B; | ||
| 1270 | break; | ||
| 1271 | case M25P80_NORMAL: | ||
| 1272 | flash->read_opcode = OPCODE_NORM_READ_4B; | ||
| 1273 | break; | ||
| 1274 | } | ||
| 1083 | flash->program_opcode = OPCODE_PP_4B; | 1275 | flash->program_opcode = OPCODE_PP_4B; |
| 1084 | /* No small sector erase for 4-byte command set */ | 1276 | /* No small sector erase for 4-byte command set */ |
| 1085 | flash->erase_opcode = OPCODE_SE_4B; | 1277 | flash->erase_opcode = OPCODE_SE_4B; |
diff --git a/drivers/mtd/devices/ms02-nv.c b/drivers/mtd/devices/ms02-nv.c index 182849d39c61..5c8b322ba904 100644 --- a/drivers/mtd/devices/ms02-nv.c +++ b/drivers/mtd/devices/ms02-nv.c | |||
| @@ -205,7 +205,7 @@ static int __init ms02nv_init_one(ulong addr) | |||
| 205 | mtd->type = MTD_RAM; | 205 | mtd->type = MTD_RAM; |
| 206 | mtd->flags = MTD_CAP_RAM; | 206 | mtd->flags = MTD_CAP_RAM; |
| 207 | mtd->size = fixsize; | 207 | mtd->size = fixsize; |
| 208 | mtd->name = (char *)ms02nv_name; | 208 | mtd->name = ms02nv_name; |
| 209 | mtd->owner = THIS_MODULE; | 209 | mtd->owner = THIS_MODULE; |
| 210 | mtd->_read = ms02nv_read; | 210 | mtd->_read = ms02nv_read; |
| 211 | mtd->_write = ms02nv_write; | 211 | mtd->_write = ms02nv_write; |
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index 4a47b0266d4e..624069de4f28 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c | |||
| @@ -669,7 +669,6 @@ static int add_dataflash_otp(struct spi_device *spi, char *name, int nr_pages, | |||
| 669 | if (!err) | 669 | if (!err) |
| 670 | return 0; | 670 | return 0; |
| 671 | 671 | ||
| 672 | spi_set_drvdata(spi, NULL); | ||
| 673 | kfree(priv); | 672 | kfree(priv); |
| 674 | return err; | 673 | return err; |
| 675 | } | 674 | } |
| @@ -899,10 +898,8 @@ static int dataflash_remove(struct spi_device *spi) | |||
| 899 | pr_debug("%s: remove\n", dev_name(&spi->dev)); | 898 | pr_debug("%s: remove\n", dev_name(&spi->dev)); |
| 900 | 899 | ||
| 901 | status = mtd_device_unregister(&flash->mtd); | 900 | status = mtd_device_unregister(&flash->mtd); |
| 902 | if (status == 0) { | 901 | if (status == 0) |
| 903 | spi_set_drvdata(spi, NULL); | ||
| 904 | kfree(flash); | 902 | kfree(flash); |
| 905 | } | ||
| 906 | return status; | 903 | return status; |
| 907 | } | 904 | } |
| 908 | 905 | ||
diff --git a/drivers/mtd/devices/mtdram.c b/drivers/mtd/devices/mtdram.c index ec59d65897fb..8e285089229c 100644 --- a/drivers/mtd/devices/mtdram.c +++ b/drivers/mtd/devices/mtdram.c | |||
| @@ -92,7 +92,7 @@ static void __exit cleanup_mtdram(void) | |||
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | int mtdram_init_device(struct mtd_info *mtd, void *mapped_address, | 94 | int mtdram_init_device(struct mtd_info *mtd, void *mapped_address, |
| 95 | unsigned long size, char *name) | 95 | unsigned long size, const char *name) |
| 96 | { | 96 | { |
| 97 | memset(mtd, 0, sizeof(*mtd)); | 97 | memset(mtd, 0, sizeof(*mtd)); |
| 98 | 98 | ||
diff --git a/drivers/mtd/lpddr/lpddr_cmds.c b/drivers/mtd/lpddr/lpddr_cmds.c index 2ef19aa0086b..d38b6460d505 100644 --- a/drivers/mtd/lpddr/lpddr_cmds.c +++ b/drivers/mtd/lpddr/lpddr_cmds.c | |||
| @@ -388,7 +388,7 @@ static void put_chip(struct map_info *map, struct flchip *chip) | |||
| 388 | wake_up(&chip->wq); | 388 | wake_up(&chip->wq); |
| 389 | } | 389 | } |
| 390 | 390 | ||
| 391 | int do_write_buffer(struct map_info *map, struct flchip *chip, | 391 | static int do_write_buffer(struct map_info *map, struct flchip *chip, |
| 392 | unsigned long adr, const struct kvec **pvec, | 392 | unsigned long adr, const struct kvec **pvec, |
| 393 | unsigned long *pvec_seek, int len) | 393 | unsigned long *pvec_seek, int len) |
| 394 | { | 394 | { |
| @@ -469,7 +469,7 @@ int do_write_buffer(struct map_info *map, struct flchip *chip, | |||
| 469 | return ret; | 469 | return ret; |
| 470 | } | 470 | } |
| 471 | 471 | ||
| 472 | int do_erase_oneblock(struct mtd_info *mtd, loff_t adr) | 472 | static int do_erase_oneblock(struct mtd_info *mtd, loff_t adr) |
| 473 | { | 473 | { |
| 474 | struct map_info *map = mtd->priv; | 474 | struct map_info *map = mtd->priv; |
| 475 | struct lpddr_private *lpddr = map->fldrv_priv; | 475 | struct lpddr_private *lpddr = map->fldrv_priv; |
| @@ -748,34 +748,6 @@ static int lpddr_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) | |||
| 748 | return do_xxlock(mtd, ofs, len, DO_XXLOCK_UNLOCK); | 748 | return do_xxlock(mtd, ofs, len, DO_XXLOCK_UNLOCK); |
| 749 | } | 749 | } |
| 750 | 750 | ||
| 751 | int word_program(struct map_info *map, loff_t adr, uint32_t curval) | ||
| 752 | { | ||
| 753 | int ret; | ||
| 754 | struct lpddr_private *lpddr = map->fldrv_priv; | ||
| 755 | int chipnum = adr >> lpddr->chipshift; | ||
| 756 | struct flchip *chip = &lpddr->chips[chipnum]; | ||
| 757 | |||
| 758 | mutex_lock(&chip->mutex); | ||
| 759 | ret = get_chip(map, chip, FL_WRITING); | ||
| 760 | if (ret) { | ||
| 761 | mutex_unlock(&chip->mutex); | ||
| 762 | return ret; | ||
| 763 | } | ||
| 764 | |||
| 765 | send_pfow_command(map, LPDDR_WORD_PROGRAM, adr, 0x00, (map_word *)&curval); | ||
| 766 | |||
| 767 | ret = wait_for_ready(map, chip, (1<<lpddr->qinfo->SingleWordProgTime)); | ||
| 768 | if (ret) { | ||
| 769 | printk(KERN_WARNING"%s word_program error at: %llx; val: %x\n", | ||
| 770 | map->name, adr, curval); | ||
| 771 | goto out; | ||
| 772 | } | ||
| 773 | |||
| 774 | out: put_chip(map, chip); | ||
| 775 | mutex_unlock(&chip->mutex); | ||
| 776 | return ret; | ||
| 777 | } | ||
| 778 | |||
| 779 | MODULE_LICENSE("GPL"); | 751 | MODULE_LICENSE("GPL"); |
| 780 | MODULE_AUTHOR("Alexey Korolev <akorolev@infradead.org>"); | 752 | MODULE_AUTHOR("Alexey Korolev <akorolev@infradead.org>"); |
| 781 | MODULE_DESCRIPTION("MTD driver for LPDDR flash chips"); | 753 | MODULE_DESCRIPTION("MTD driver for LPDDR flash chips"); |
diff --git a/drivers/mtd/maps/ixp4xx.c b/drivers/mtd/maps/ixp4xx.c index 10debfea81e7..d6b2451eab1d 100644 --- a/drivers/mtd/maps/ixp4xx.c +++ b/drivers/mtd/maps/ixp4xx.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | * | 13 | * |
| 14 | */ | 14 | */ |
| 15 | 15 | ||
| 16 | #include <linux/err.h> | ||
| 16 | #include <linux/module.h> | 17 | #include <linux/module.h> |
| 17 | #include <linux/types.h> | 18 | #include <linux/types.h> |
| 18 | #include <linux/init.h> | 19 | #include <linux/init.h> |
| @@ -162,13 +163,6 @@ static int ixp4xx_flash_remove(struct platform_device *dev) | |||
| 162 | mtd_device_unregister(info->mtd); | 163 | mtd_device_unregister(info->mtd); |
| 163 | map_destroy(info->mtd); | 164 | map_destroy(info->mtd); |
| 164 | } | 165 | } |
| 165 | if (info->map.virt) | ||
| 166 | iounmap(info->map.virt); | ||
| 167 | |||
| 168 | if (info->res) { | ||
| 169 | release_resource(info->res); | ||
| 170 | kfree(info->res); | ||
| 171 | } | ||
| 172 | 166 | ||
| 173 | if (plat->exit) | 167 | if (plat->exit) |
| 174 | plat->exit(); | 168 | plat->exit(); |
| @@ -194,7 +188,8 @@ static int ixp4xx_flash_probe(struct platform_device *dev) | |||
| 194 | return err; | 188 | return err; |
| 195 | } | 189 | } |
| 196 | 190 | ||
| 197 | info = kzalloc(sizeof(struct ixp4xx_flash_info), GFP_KERNEL); | 191 | info = devm_kzalloc(&dev->dev, sizeof(struct ixp4xx_flash_info), |
| 192 | GFP_KERNEL); | ||
| 198 | if(!info) { | 193 | if(!info) { |
| 199 | err = -ENOMEM; | 194 | err = -ENOMEM; |
| 200 | goto Error; | 195 | goto Error; |
| @@ -220,20 +215,9 @@ static int ixp4xx_flash_probe(struct platform_device *dev) | |||
| 220 | info->map.write = ixp4xx_probe_write16; | 215 | info->map.write = ixp4xx_probe_write16; |
| 221 | info->map.copy_from = ixp4xx_copy_from; | 216 | info->map.copy_from = ixp4xx_copy_from; |
| 222 | 217 | ||
| 223 | info->res = request_mem_region(dev->resource->start, | 218 | info->map.virt = devm_ioremap_resource(&dev->dev, dev->resource); |
| 224 | resource_size(dev->resource), | 219 | if (IS_ERR(info->map.virt)) { |
| 225 | "IXP4XXFlash"); | 220 | err = PTR_ERR(info->map.virt); |
| 226 | if (!info->res) { | ||
| 227 | printk(KERN_ERR "IXP4XXFlash: Could not reserve memory region\n"); | ||
| 228 | err = -ENOMEM; | ||
| 229 | goto Error; | ||
| 230 | } | ||
| 231 | |||
| 232 | info->map.virt = ioremap(dev->resource->start, | ||
| 233 | resource_size(dev->resource)); | ||
| 234 | if (!info->map.virt) { | ||
| 235 | printk(KERN_ERR "IXP4XXFlash: Failed to ioremap region\n"); | ||
| 236 | err = -EIO; | ||
| 237 | goto Error; | 221 | goto Error; |
| 238 | } | 222 | } |
| 239 | 223 | ||
diff --git a/drivers/mtd/maps/lantiq-flash.c b/drivers/mtd/maps/lantiq-flash.c index d7ac65d1d569..93c507a6f862 100644 --- a/drivers/mtd/maps/lantiq-flash.c +++ b/drivers/mtd/maps/lantiq-flash.c | |||
| @@ -123,24 +123,28 @@ ltq_mtd_probe(struct platform_device *pdev) | |||
| 123 | return -ENODEV; | 123 | return -ENODEV; |
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | ltq_mtd = kzalloc(sizeof(struct ltq_mtd), GFP_KERNEL); | 126 | ltq_mtd = devm_kzalloc(&pdev->dev, sizeof(struct ltq_mtd), GFP_KERNEL); |
| 127 | if (!ltq_mtd) | ||
| 128 | return -ENOMEM; | ||
| 129 | |||
| 127 | platform_set_drvdata(pdev, ltq_mtd); | 130 | platform_set_drvdata(pdev, ltq_mtd); |
| 128 | 131 | ||
| 129 | ltq_mtd->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 132 | ltq_mtd->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 130 | if (!ltq_mtd->res) { | 133 | if (!ltq_mtd->res) { |
| 131 | dev_err(&pdev->dev, "failed to get memory resource\n"); | 134 | dev_err(&pdev->dev, "failed to get memory resource\n"); |
| 132 | err = -ENOENT; | 135 | return -ENOENT; |
| 133 | goto err_out; | ||
| 134 | } | 136 | } |
| 135 | 137 | ||
| 136 | ltq_mtd->map = kzalloc(sizeof(struct map_info), GFP_KERNEL); | 138 | ltq_mtd->map = devm_kzalloc(&pdev->dev, sizeof(struct map_info), |
| 139 | GFP_KERNEL); | ||
| 140 | if (!ltq_mtd->map) | ||
| 141 | return -ENOMEM; | ||
| 142 | |||
| 137 | ltq_mtd->map->phys = ltq_mtd->res->start; | 143 | ltq_mtd->map->phys = ltq_mtd->res->start; |
| 138 | ltq_mtd->map->size = resource_size(ltq_mtd->res); | 144 | ltq_mtd->map->size = resource_size(ltq_mtd->res); |
| 139 | ltq_mtd->map->virt = devm_ioremap_resource(&pdev->dev, ltq_mtd->res); | 145 | ltq_mtd->map->virt = devm_ioremap_resource(&pdev->dev, ltq_mtd->res); |
| 140 | if (IS_ERR(ltq_mtd->map->virt)) { | 146 | if (IS_ERR(ltq_mtd->map->virt)) |
| 141 | err = PTR_ERR(ltq_mtd->map->virt); | 147 | return PTR_ERR(ltq_mtd->map->virt); |
| 142 | goto err_out; | ||
| 143 | } | ||
| 144 | 148 | ||
| 145 | ltq_mtd->map->name = ltq_map_name; | 149 | ltq_mtd->map->name = ltq_map_name; |
| 146 | ltq_mtd->map->bankwidth = 2; | 150 | ltq_mtd->map->bankwidth = 2; |
| @@ -155,8 +159,7 @@ ltq_mtd_probe(struct platform_device *pdev) | |||
| 155 | 159 | ||
| 156 | if (!ltq_mtd->mtd) { | 160 | if (!ltq_mtd->mtd) { |
| 157 | dev_err(&pdev->dev, "probing failed\n"); | 161 | dev_err(&pdev->dev, "probing failed\n"); |
| 158 | err = -ENXIO; | 162 | return -ENXIO; |
| 159 | goto err_free; | ||
| 160 | } | 163 | } |
| 161 | 164 | ||
| 162 | ltq_mtd->mtd->owner = THIS_MODULE; | 165 | ltq_mtd->mtd->owner = THIS_MODULE; |
| @@ -177,10 +180,6 @@ ltq_mtd_probe(struct platform_device *pdev) | |||
| 177 | 180 | ||
| 178 | err_destroy: | 181 | err_destroy: |
| 179 | map_destroy(ltq_mtd->mtd); | 182 | map_destroy(ltq_mtd->mtd); |
| 180 | err_free: | ||
| 181 | kfree(ltq_mtd->map); | ||
| 182 | err_out: | ||
| 183 | kfree(ltq_mtd); | ||
| 184 | return err; | 183 | return err; |
| 185 | } | 184 | } |
| 186 | 185 | ||
| @@ -189,13 +188,9 @@ ltq_mtd_remove(struct platform_device *pdev) | |||
| 189 | { | 188 | { |
| 190 | struct ltq_mtd *ltq_mtd = platform_get_drvdata(pdev); | 189 | struct ltq_mtd *ltq_mtd = platform_get_drvdata(pdev); |
| 191 | 190 | ||
| 192 | if (ltq_mtd) { | 191 | if (ltq_mtd && ltq_mtd->mtd) { |
| 193 | if (ltq_mtd->mtd) { | 192 | mtd_device_unregister(ltq_mtd->mtd); |
| 194 | mtd_device_unregister(ltq_mtd->mtd); | 193 | map_destroy(ltq_mtd->mtd); |
| 195 | map_destroy(ltq_mtd->mtd); | ||
| 196 | } | ||
| 197 | kfree(ltq_mtd->map); | ||
| 198 | kfree(ltq_mtd); | ||
| 199 | } | 194 | } |
| 200 | return 0; | 195 | return 0; |
| 201 | } | 196 | } |
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c index 0f55589a56b8..9aad854fe912 100644 --- a/drivers/mtd/maps/pxa2xx-flash.c +++ b/drivers/mtd/maps/pxa2xx-flash.c | |||
| @@ -61,7 +61,7 @@ static int pxa2xx_flash_probe(struct platform_device *pdev) | |||
| 61 | if (!info) | 61 | if (!info) |
| 62 | return -ENOMEM; | 62 | return -ENOMEM; |
| 63 | 63 | ||
| 64 | info->map.name = (char *) flash->name; | 64 | info->map.name = flash->name; |
| 65 | info->map.bankwidth = flash->width; | 65 | info->map.bankwidth = flash->width; |
| 66 | info->map.phys = res->start; | 66 | info->map.phys = res->start; |
| 67 | info->map.size = resource_size(res); | 67 | info->map.size = resource_size(res); |
diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c index d467f3b11c96..39cc4181f025 100644 --- a/drivers/mtd/maps/sun_uflash.c +++ b/drivers/mtd/maps/sun_uflash.c | |||
| @@ -75,7 +75,7 @@ int uflash_devinit(struct platform_device *op, struct device_node *dp) | |||
| 75 | 75 | ||
| 76 | up->name = of_get_property(dp, "model", NULL); | 76 | up->name = of_get_property(dp, "model", NULL); |
| 77 | if (up->name && 0 < strlen(up->name)) | 77 | if (up->name && 0 < strlen(up->name)) |
| 78 | up->map.name = (char *)up->name; | 78 | up->map.name = up->name; |
| 79 | 79 | ||
| 80 | up->map.phys = op->resource[0].start; | 80 | up->map.phys = op->resource[0].start; |
| 81 | 81 | ||
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 92311a56939f..34c0b16aed5c 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c | |||
| @@ -313,15 +313,7 @@ static struct attribute *mtd_attrs[] = { | |||
| 313 | &dev_attr_bitflip_threshold.attr, | 313 | &dev_attr_bitflip_threshold.attr, |
| 314 | NULL, | 314 | NULL, |
| 315 | }; | 315 | }; |
| 316 | 316 | ATTRIBUTE_GROUPS(mtd); | |
| 317 | static struct attribute_group mtd_group = { | ||
| 318 | .attrs = mtd_attrs, | ||
| 319 | }; | ||
| 320 | |||
| 321 | static const struct attribute_group *mtd_groups[] = { | ||
| 322 | &mtd_group, | ||
| 323 | NULL, | ||
| 324 | }; | ||
| 325 | 317 | ||
| 326 | static struct device_type mtd_devtype = { | 318 | static struct device_type mtd_devtype = { |
| 327 | .name = "mtd", | 319 | .name = "mtd", |
diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 6e732c3820c1..3c7d6d7623c1 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c | |||
| @@ -534,7 +534,7 @@ out_register: | |||
| 534 | return slave; | 534 | return slave; |
| 535 | } | 535 | } |
| 536 | 536 | ||
| 537 | int mtd_add_partition(struct mtd_info *master, char *name, | 537 | int mtd_add_partition(struct mtd_info *master, const char *name, |
| 538 | long long offset, long long length) | 538 | long long offset, long long length) |
| 539 | { | 539 | { |
| 540 | struct mtd_partition part; | 540 | struct mtd_partition part; |
| @@ -672,22 +672,19 @@ static struct mtd_part_parser *get_partition_parser(const char *name) | |||
| 672 | 672 | ||
| 673 | #define put_partition_parser(p) do { module_put((p)->owner); } while (0) | 673 | #define put_partition_parser(p) do { module_put((p)->owner); } while (0) |
| 674 | 674 | ||
| 675 | int register_mtd_parser(struct mtd_part_parser *p) | 675 | void register_mtd_parser(struct mtd_part_parser *p) |
| 676 | { | 676 | { |
| 677 | spin_lock(&part_parser_lock); | 677 | spin_lock(&part_parser_lock); |
| 678 | list_add(&p->list, &part_parsers); | 678 | list_add(&p->list, &part_parsers); |
| 679 | spin_unlock(&part_parser_lock); | 679 | spin_unlock(&part_parser_lock); |
| 680 | |||
| 681 | return 0; | ||
| 682 | } | 680 | } |
| 683 | EXPORT_SYMBOL_GPL(register_mtd_parser); | 681 | EXPORT_SYMBOL_GPL(register_mtd_parser); |
| 684 | 682 | ||
| 685 | int deregister_mtd_parser(struct mtd_part_parser *p) | 683 | void deregister_mtd_parser(struct mtd_part_parser *p) |
| 686 | { | 684 | { |
| 687 | spin_lock(&part_parser_lock); | 685 | spin_lock(&part_parser_lock); |
| 688 | list_del(&p->list); | 686 | list_del(&p->list); |
| 689 | spin_unlock(&part_parser_lock); | 687 | spin_unlock(&part_parser_lock); |
| 690 | return 0; | ||
| 691 | } | 688 | } |
| 692 | EXPORT_SYMBOL_GPL(deregister_mtd_parser); | 689 | EXPORT_SYMBOL_GPL(deregister_mtd_parser); |
| 693 | 690 | ||
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 93ae6a6d94f7..90ff447bf043 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
| @@ -95,7 +95,7 @@ config MTD_NAND_OMAP2 | |||
| 95 | platforms. | 95 | platforms. |
| 96 | 96 | ||
| 97 | config MTD_NAND_OMAP_BCH | 97 | config MTD_NAND_OMAP_BCH |
| 98 | depends on MTD_NAND && MTD_NAND_OMAP2 && ARCH_OMAP3 | 98 | depends on MTD_NAND_OMAP2 |
| 99 | tristate "Support hardware based BCH error correction" | 99 | tristate "Support hardware based BCH error correction" |
| 100 | default n | 100 | default n |
| 101 | select BCH | 101 | select BCH |
| @@ -326,11 +326,11 @@ config MTD_NAND_ATMEL | |||
| 326 | on Atmel AT91 and AVR32 processors. | 326 | on Atmel AT91 and AVR32 processors. |
| 327 | 327 | ||
| 328 | config MTD_NAND_PXA3xx | 328 | config MTD_NAND_PXA3xx |
| 329 | tristate "Support for NAND flash devices on PXA3xx" | 329 | tristate "NAND support on PXA3xx and Armada 370/XP" |
| 330 | depends on PXA3xx || ARCH_MMP || PLAT_ORION | 330 | depends on PXA3xx || ARCH_MMP || PLAT_ORION |
| 331 | help | 331 | help |
| 332 | This enables the driver for the NAND flash device found on | 332 | This enables the driver for the NAND flash device found on |
| 333 | PXA3xx processors | 333 | PXA3xx processors (NFCv1) and also on Armada 370/XP (NFCv2). |
| 334 | 334 | ||
| 335 | config MTD_NAND_SLC_LPC32XX | 335 | config MTD_NAND_SLC_LPC32XX |
| 336 | tristate "NXP LPC32xx SLC Controller" | 336 | tristate "NXP LPC32xx SLC Controller" |
| @@ -458,17 +458,17 @@ config MTD_NAND_MXC | |||
| 458 | 458 | ||
| 459 | config MTD_NAND_SH_FLCTL | 459 | config MTD_NAND_SH_FLCTL |
| 460 | tristate "Support for NAND on Renesas SuperH FLCTL" | 460 | tristate "Support for NAND on Renesas SuperH FLCTL" |
| 461 | depends on SUPERH || ARCH_SHMOBILE | 461 | depends on SUPERH || ARCH_SHMOBILE || COMPILE_TEST |
| 462 | help | 462 | help |
| 463 | Several Renesas SuperH CPU has FLCTL. This option enables support | 463 | Several Renesas SuperH CPU has FLCTL. This option enables support |
| 464 | for NAND Flash using FLCTL. | 464 | for NAND Flash using FLCTL. |
| 465 | 465 | ||
| 466 | config MTD_NAND_DAVINCI | 466 | config MTD_NAND_DAVINCI |
| 467 | tristate "Support NAND on DaVinci SoC" | 467 | tristate "Support NAND on DaVinci/Keystone SoC" |
| 468 | depends on ARCH_DAVINCI | 468 | depends on ARCH_DAVINCI || (ARCH_KEYSTONE && TI_AEMIF) |
| 469 | help | 469 | help |
| 470 | Enable the driver for NAND flash chips on Texas Instruments | 470 | Enable the driver for NAND flash chips on Texas Instruments |
| 471 | DaVinci processors. | 471 | DaVinci/Keystone processors. |
| 472 | 472 | ||
| 473 | config MTD_NAND_TXX9NDFMC | 473 | config MTD_NAND_TXX9NDFMC |
| 474 | tristate "NAND Flash support for TXx9 SoC" | 474 | tristate "NAND Flash support for TXx9 SoC" |
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 59f08c44abdb..c36e9b84487c 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c | |||
| @@ -1961,10 +1961,8 @@ static int atmel_nand_probe(struct platform_device *pdev) | |||
| 1961 | 1961 | ||
| 1962 | /* Allocate memory for the device structure (and zero it) */ | 1962 | /* Allocate memory for the device structure (and zero it) */ |
| 1963 | host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); | 1963 | host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); |
| 1964 | if (!host) { | 1964 | if (!host) |
| 1965 | printk(KERN_ERR "atmel_nand: failed to allocate device structure.\n"); | ||
| 1966 | return -ENOMEM; | 1965 | return -ENOMEM; |
| 1967 | } | ||
| 1968 | 1966 | ||
| 1969 | res = platform_driver_register(&atmel_nand_nfc_driver); | 1967 | res = platform_driver_register(&atmel_nand_nfc_driver); |
| 1970 | if (res) | 1968 | if (res) |
| @@ -2062,14 +2060,14 @@ static int atmel_nand_probe(struct platform_device *pdev) | |||
| 2062 | } | 2060 | } |
| 2063 | 2061 | ||
| 2064 | if (gpio_get_value(host->board.det_pin)) { | 2062 | if (gpio_get_value(host->board.det_pin)) { |
| 2065 | printk(KERN_INFO "No SmartMedia card inserted.\n"); | 2063 | dev_info(&pdev->dev, "No SmartMedia card inserted.\n"); |
| 2066 | res = -ENXIO; | 2064 | res = -ENXIO; |
| 2067 | goto err_no_card; | 2065 | goto err_no_card; |
| 2068 | } | 2066 | } |
| 2069 | } | 2067 | } |
| 2070 | 2068 | ||
| 2071 | if (host->board.on_flash_bbt || on_flash_bbt) { | 2069 | if (host->board.on_flash_bbt || on_flash_bbt) { |
| 2072 | printk(KERN_INFO "atmel_nand: Use On Flash BBT\n"); | 2070 | dev_info(&pdev->dev, "Use On Flash BBT\n"); |
| 2073 | nand_chip->bbt_options |= NAND_BBT_USE_FLASH; | 2071 | nand_chip->bbt_options |= NAND_BBT_USE_FLASH; |
| 2074 | } | 2072 | } |
| 2075 | 2073 | ||
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c index ae8dd7c41039..2880d888cfc5 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/au1550nd.c | |||
| @@ -418,10 +418,8 @@ static int au1550nd_probe(struct platform_device *pdev) | |||
| 418 | } | 418 | } |
| 419 | 419 | ||
| 420 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | 420 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); |
| 421 | if (!ctx) { | 421 | if (!ctx) |
| 422 | dev_err(&pdev->dev, "no memory for NAND context\n"); | ||
| 423 | return -ENOMEM; | 422 | return -ENOMEM; |
| 424 | } | ||
| 425 | 423 | ||
| 426 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 424 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 427 | if (!r) { | 425 | if (!r) { |
| @@ -480,6 +478,8 @@ static int au1550nd_probe(struct platform_device *pdev) | |||
| 480 | 478 | ||
| 481 | mtd_device_register(&ctx->info, pd->parts, pd->num_parts); | 479 | mtd_device_register(&ctx->info, pd->parts, pd->num_parts); |
| 482 | 480 | ||
| 481 | platform_set_drvdata(pdev, ctx); | ||
| 482 | |||
| 483 | return 0; | 483 | return 0; |
| 484 | 484 | ||
| 485 | out3: | 485 | out3: |
diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c index 2c42e125720f..94f55dbde995 100644 --- a/drivers/mtd/nand/bf5xx_nand.c +++ b/drivers/mtd/nand/bf5xx_nand.c | |||
| @@ -745,7 +745,6 @@ static int bf5xx_nand_probe(struct platform_device *pdev) | |||
| 745 | 745 | ||
| 746 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 746 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
| 747 | if (info == NULL) { | 747 | if (info == NULL) { |
| 748 | dev_err(&pdev->dev, "no memory for flash info\n"); | ||
| 749 | err = -ENOMEM; | 748 | err = -ENOMEM; |
| 750 | goto out_err_kzalloc; | 749 | goto out_err_kzalloc; |
| 751 | } | 750 | } |
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index c34985a55101..f2f64addb5e8 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c | |||
| @@ -640,10 +640,8 @@ static int cafe_nand_probe(struct pci_dev *pdev, | |||
| 640 | pci_set_master(pdev); | 640 | pci_set_master(pdev); |
| 641 | 641 | ||
| 642 | mtd = kzalloc(sizeof(*mtd) + sizeof(struct cafe_priv), GFP_KERNEL); | 642 | mtd = kzalloc(sizeof(*mtd) + sizeof(struct cafe_priv), GFP_KERNEL); |
| 643 | if (!mtd) { | 643 | if (!mtd) |
| 644 | dev_warn(&pdev->dev, "failed to alloc mtd_info\n"); | ||
| 645 | return -ENOMEM; | 644 | return -ENOMEM; |
| 646 | } | ||
| 647 | cafe = (void *)(&mtd[1]); | 645 | cafe = (void *)(&mtd[1]); |
| 648 | 646 | ||
| 649 | mtd->dev.parent = &pdev->dev; | 647 | mtd->dev.parent = &pdev->dev; |
diff --git a/drivers/mtd/nand/cmx270_nand.c b/drivers/mtd/nand/cmx270_nand.c index 39b2ef848811..66ec95e6ca6c 100644 --- a/drivers/mtd/nand/cmx270_nand.c +++ b/drivers/mtd/nand/cmx270_nand.c | |||
| @@ -164,7 +164,6 @@ static int __init cmx270_init(void) | |||
| 164 | sizeof(struct nand_chip), | 164 | sizeof(struct nand_chip), |
| 165 | GFP_KERNEL); | 165 | GFP_KERNEL); |
| 166 | if (!cmx270_nand_mtd) { | 166 | if (!cmx270_nand_mtd) { |
| 167 | pr_debug("Unable to allocate CM-X270 NAND MTD device structure.\n"); | ||
| 168 | ret = -ENOMEM; | 167 | ret = -ENOMEM; |
| 169 | goto err_kzalloc; | 168 | goto err_kzalloc; |
| 170 | } | 169 | } |
diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/cs553x_nand.c index d469a9a1dea0..88109d375ae7 100644 --- a/drivers/mtd/nand/cs553x_nand.c +++ b/drivers/mtd/nand/cs553x_nand.c | |||
| @@ -199,7 +199,6 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr) | |||
| 199 | /* Allocate memory for MTD device structure and private data */ | 199 | /* Allocate memory for MTD device structure and private data */ |
| 200 | new_mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); | 200 | new_mtd = kzalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip), GFP_KERNEL); |
| 201 | if (!new_mtd) { | 201 | if (!new_mtd) { |
| 202 | printk(KERN_WARNING "Unable to allocate CS553X NAND MTD device structure.\n"); | ||
| 203 | err = -ENOMEM; | 202 | err = -ENOMEM; |
| 204 | goto out; | 203 | goto out; |
| 205 | } | 204 | } |
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index b77a01efb483..a4989ec6292e 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c | |||
| @@ -35,6 +35,7 @@ | |||
| 35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
| 36 | #include <linux/of_device.h> | 36 | #include <linux/of_device.h> |
| 37 | #include <linux/of.h> | 37 | #include <linux/of.h> |
| 38 | #include <linux/of_mtd.h> | ||
| 38 | 39 | ||
| 39 | #include <linux/platform_data/mtd-davinci.h> | 40 | #include <linux/platform_data/mtd-davinci.h> |
| 40 | #include <linux/platform_data/mtd-davinci-aemif.h> | 41 | #include <linux/platform_data/mtd-davinci-aemif.h> |
| @@ -487,7 +488,7 @@ static int nand_davinci_dev_ready(struct mtd_info *mtd) | |||
| 487 | * ten ECC bytes plus the manufacturer's bad block marker byte, and | 488 | * ten ECC bytes plus the manufacturer's bad block marker byte, and |
| 488 | * and not overlapping the default BBT markers. | 489 | * and not overlapping the default BBT markers. |
| 489 | */ | 490 | */ |
| 490 | static struct nand_ecclayout hwecc4_small __initconst = { | 491 | static struct nand_ecclayout hwecc4_small = { |
| 491 | .eccbytes = 10, | 492 | .eccbytes = 10, |
| 492 | .eccpos = { 0, 1, 2, 3, 4, | 493 | .eccpos = { 0, 1, 2, 3, 4, |
| 493 | /* offset 5 holds the badblock marker */ | 494 | /* offset 5 holds the badblock marker */ |
| @@ -503,7 +504,7 @@ static struct nand_ecclayout hwecc4_small __initconst = { | |||
| 503 | * storing ten ECC bytes plus the manufacturer's bad block marker byte, | 504 | * storing ten ECC bytes plus the manufacturer's bad block marker byte, |
| 504 | * and not overlapping the default BBT markers. | 505 | * and not overlapping the default BBT markers. |
| 505 | */ | 506 | */ |
| 506 | static struct nand_ecclayout hwecc4_2048 __initconst = { | 507 | static struct nand_ecclayout hwecc4_2048 = { |
| 507 | .eccbytes = 40, | 508 | .eccbytes = 40, |
| 508 | .eccpos = { | 509 | .eccpos = { |
| 509 | /* at the end of spare sector */ | 510 | /* at the end of spare sector */ |
| @@ -534,17 +535,19 @@ static struct davinci_nand_pdata | |||
| 534 | struct davinci_nand_pdata *pdata; | 535 | struct davinci_nand_pdata *pdata; |
| 535 | const char *mode; | 536 | const char *mode; |
| 536 | u32 prop; | 537 | u32 prop; |
| 537 | int len; | ||
| 538 | 538 | ||
| 539 | pdata = devm_kzalloc(&pdev->dev, | 539 | pdata = devm_kzalloc(&pdev->dev, |
| 540 | sizeof(struct davinci_nand_pdata), | 540 | sizeof(struct davinci_nand_pdata), |
| 541 | GFP_KERNEL); | 541 | GFP_KERNEL); |
| 542 | pdev->dev.platform_data = pdata; | 542 | pdev->dev.platform_data = pdata; |
| 543 | if (!pdata) | 543 | if (!pdata) |
| 544 | return NULL; | 544 | return ERR_PTR(-ENOMEM); |
| 545 | if (!of_property_read_u32(pdev->dev.of_node, | 545 | if (!of_property_read_u32(pdev->dev.of_node, |
| 546 | "ti,davinci-chipselect", &prop)) | 546 | "ti,davinci-chipselect", &prop)) |
| 547 | pdev->id = prop; | 547 | pdev->id = prop; |
| 548 | else | ||
| 549 | return ERR_PTR(-EINVAL); | ||
| 550 | |||
| 548 | if (!of_property_read_u32(pdev->dev.of_node, | 551 | if (!of_property_read_u32(pdev->dev.of_node, |
| 549 | "ti,davinci-mask-ale", &prop)) | 552 | "ti,davinci-mask-ale", &prop)) |
| 550 | pdata->mask_ale = prop; | 553 | pdata->mask_ale = prop; |
| @@ -555,6 +558,8 @@ static struct davinci_nand_pdata | |||
| 555 | "ti,davinci-mask-chipsel", &prop)) | 558 | "ti,davinci-mask-chipsel", &prop)) |
| 556 | pdata->mask_chipsel = prop; | 559 | pdata->mask_chipsel = prop; |
| 557 | if (!of_property_read_string(pdev->dev.of_node, | 560 | if (!of_property_read_string(pdev->dev.of_node, |
| 561 | "nand-ecc-mode", &mode) || | ||
| 562 | !of_property_read_string(pdev->dev.of_node, | ||
| 558 | "ti,davinci-ecc-mode", &mode)) { | 563 | "ti,davinci-ecc-mode", &mode)) { |
| 559 | if (!strncmp("none", mode, 4)) | 564 | if (!strncmp("none", mode, 4)) |
| 560 | pdata->ecc_mode = NAND_ECC_NONE; | 565 | pdata->ecc_mode = NAND_ECC_NONE; |
| @@ -566,12 +571,16 @@ static struct davinci_nand_pdata | |||
| 566 | if (!of_property_read_u32(pdev->dev.of_node, | 571 | if (!of_property_read_u32(pdev->dev.of_node, |
| 567 | "ti,davinci-ecc-bits", &prop)) | 572 | "ti,davinci-ecc-bits", &prop)) |
| 568 | pdata->ecc_bits = prop; | 573 | pdata->ecc_bits = prop; |
| 569 | if (!of_property_read_u32(pdev->dev.of_node, | 574 | |
| 575 | prop = of_get_nand_bus_width(pdev->dev.of_node); | ||
| 576 | if (0 < prop || !of_property_read_u32(pdev->dev.of_node, | ||
| 570 | "ti,davinci-nand-buswidth", &prop)) | 577 | "ti,davinci-nand-buswidth", &prop)) |
| 571 | if (prop == 16) | 578 | if (prop == 16) |
| 572 | pdata->options |= NAND_BUSWIDTH_16; | 579 | pdata->options |= NAND_BUSWIDTH_16; |
| 573 | if (of_find_property(pdev->dev.of_node, | 580 | if (of_property_read_bool(pdev->dev.of_node, |
| 574 | "ti,davinci-nand-use-bbt", &len)) | 581 | "nand-on-flash-bbt") || |
| 582 | of_property_read_bool(pdev->dev.of_node, | ||
| 583 | "ti,davinci-nand-use-bbt")) | ||
| 575 | pdata->bbt_options = NAND_BBT_USE_FLASH; | 584 | pdata->bbt_options = NAND_BBT_USE_FLASH; |
| 576 | } | 585 | } |
| 577 | 586 | ||
| @@ -585,7 +594,7 @@ static struct davinci_nand_pdata | |||
| 585 | } | 594 | } |
| 586 | #endif | 595 | #endif |
| 587 | 596 | ||
| 588 | static int __init nand_davinci_probe(struct platform_device *pdev) | 597 | static int nand_davinci_probe(struct platform_device *pdev) |
| 589 | { | 598 | { |
| 590 | struct davinci_nand_pdata *pdata; | 599 | struct davinci_nand_pdata *pdata; |
| 591 | struct davinci_nand_info *info; | 600 | struct davinci_nand_info *info; |
| @@ -598,6 +607,9 @@ static int __init nand_davinci_probe(struct platform_device *pdev) | |||
| 598 | nand_ecc_modes_t ecc_mode; | 607 | nand_ecc_modes_t ecc_mode; |
| 599 | 608 | ||
| 600 | pdata = nand_davinci_get_pdata(pdev); | 609 | pdata = nand_davinci_get_pdata(pdev); |
| 610 | if (IS_ERR(pdata)) | ||
| 611 | return PTR_ERR(pdata); | ||
| 612 | |||
| 601 | /* insist on board-specific configuration */ | 613 | /* insist on board-specific configuration */ |
| 602 | if (!pdata) | 614 | if (!pdata) |
| 603 | return -ENODEV; | 615 | return -ENODEV; |
| @@ -607,11 +619,8 @@ static int __init nand_davinci_probe(struct platform_device *pdev) | |||
| 607 | return -ENODEV; | 619 | return -ENODEV; |
| 608 | 620 | ||
| 609 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); | 621 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); |
| 610 | if (!info) { | 622 | if (!info) |
| 611 | dev_err(&pdev->dev, "unable to allocate memory\n"); | 623 | return -ENOMEM; |
| 612 | ret = -ENOMEM; | ||
| 613 | goto err_nomem; | ||
| 614 | } | ||
| 615 | 624 | ||
| 616 | platform_set_drvdata(pdev, info); | 625 | platform_set_drvdata(pdev, info); |
| 617 | 626 | ||
| @@ -619,19 +628,23 @@ static int __init nand_davinci_probe(struct platform_device *pdev) | |||
| 619 | res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 628 | res2 = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
| 620 | if (!res1 || !res2) { | 629 | if (!res1 || !res2) { |
| 621 | dev_err(&pdev->dev, "resource missing\n"); | 630 | dev_err(&pdev->dev, "resource missing\n"); |
| 622 | ret = -EINVAL; | 631 | return -EINVAL; |
| 623 | goto err_nomem; | ||
| 624 | } | 632 | } |
| 625 | 633 | ||
| 626 | vaddr = devm_ioremap_resource(&pdev->dev, res1); | 634 | vaddr = devm_ioremap_resource(&pdev->dev, res1); |
| 627 | if (IS_ERR(vaddr)) { | 635 | if (IS_ERR(vaddr)) |
| 628 | ret = PTR_ERR(vaddr); | 636 | return PTR_ERR(vaddr); |
| 629 | goto err_ioremap; | 637 | |
| 630 | } | 638 | /* |
| 631 | base = devm_ioremap_resource(&pdev->dev, res2); | 639 | * This registers range is used to setup NAND settings. In case with |
| 632 | if (IS_ERR(base)) { | 640 | * TI AEMIF driver, the same memory address range is requested already |
| 633 | ret = PTR_ERR(base); | 641 | * by AEMIF, so we cannot request it twice, just ioremap. |
| 634 | goto err_ioremap; | 642 | * The AEMIF and NAND drivers not use the same registers in this range. |
| 643 | */ | ||
| 644 | base = devm_ioremap(&pdev->dev, res2->start, resource_size(res2)); | ||
| 645 | if (!base) { | ||
| 646 | dev_err(&pdev->dev, "ioremap failed for resource %pR\n", res2); | ||
| 647 | return -EADDRNOTAVAIL; | ||
| 635 | } | 648 | } |
| 636 | 649 | ||
| 637 | info->dev = &pdev->dev; | 650 | info->dev = &pdev->dev; |
| @@ -699,7 +712,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev) | |||
| 699 | spin_unlock_irq(&davinci_nand_lock); | 712 | spin_unlock_irq(&davinci_nand_lock); |
| 700 | 713 | ||
| 701 | if (ret == -EBUSY) | 714 | if (ret == -EBUSY) |
| 702 | goto err_ecc; | 715 | return ret; |
| 703 | 716 | ||
| 704 | info->chip.ecc.calculate = nand_davinci_calculate_4bit; | 717 | info->chip.ecc.calculate = nand_davinci_calculate_4bit; |
| 705 | info->chip.ecc.correct = nand_davinci_correct_4bit; | 718 | info->chip.ecc.correct = nand_davinci_correct_4bit; |
| @@ -715,8 +728,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev) | |||
| 715 | info->chip.ecc.strength = pdata->ecc_bits; | 728 | info->chip.ecc.strength = pdata->ecc_bits; |
| 716 | break; | 729 | break; |
| 717 | default: | 730 | default: |
| 718 | ret = -EINVAL; | 731 | return -EINVAL; |
| 719 | goto err_ecc; | ||
| 720 | } | 732 | } |
| 721 | info->chip.ecc.mode = ecc_mode; | 733 | info->chip.ecc.mode = ecc_mode; |
| 722 | 734 | ||
| @@ -724,7 +736,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev) | |||
| 724 | if (IS_ERR(info->clk)) { | 736 | if (IS_ERR(info->clk)) { |
| 725 | ret = PTR_ERR(info->clk); | 737 | ret = PTR_ERR(info->clk); |
| 726 | dev_dbg(&pdev->dev, "unable to get AEMIF clock, err %d\n", ret); | 738 | dev_dbg(&pdev->dev, "unable to get AEMIF clock, err %d\n", ret); |
| 727 | goto err_clk; | 739 | return ret; |
| 728 | } | 740 | } |
| 729 | 741 | ||
| 730 | ret = clk_prepare_enable(info->clk); | 742 | ret = clk_prepare_enable(info->clk); |
| @@ -753,7 +765,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev) | |||
| 753 | info->core_chipsel); | 765 | info->core_chipsel); |
| 754 | if (ret < 0) { | 766 | if (ret < 0) { |
| 755 | dev_dbg(&pdev->dev, "NAND timing values setup fail\n"); | 767 | dev_dbg(&pdev->dev, "NAND timing values setup fail\n"); |
| 756 | goto err_timing; | 768 | goto err; |
| 757 | } | 769 | } |
| 758 | 770 | ||
| 759 | spin_lock_irq(&davinci_nand_lock); | 771 | spin_lock_irq(&davinci_nand_lock); |
| @@ -769,7 +781,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev) | |||
| 769 | ret = nand_scan_ident(&info->mtd, pdata->mask_chipsel ? 2 : 1, NULL); | 781 | ret = nand_scan_ident(&info->mtd, pdata->mask_chipsel ? 2 : 1, NULL); |
| 770 | if (ret < 0) { | 782 | if (ret < 0) { |
| 771 | dev_dbg(&pdev->dev, "no NAND chip(s) found\n"); | 783 | dev_dbg(&pdev->dev, "no NAND chip(s) found\n"); |
| 772 | goto err_scan; | 784 | goto err; |
| 773 | } | 785 | } |
| 774 | 786 | ||
| 775 | /* Update ECC layout if needed ... for 1-bit HW ECC, the default | 787 | /* Update ECC layout if needed ... for 1-bit HW ECC, the default |
| @@ -783,7 +795,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev) | |||
| 783 | if (!chunks || info->mtd.oobsize < 16) { | 795 | if (!chunks || info->mtd.oobsize < 16) { |
| 784 | dev_dbg(&pdev->dev, "too small\n"); | 796 | dev_dbg(&pdev->dev, "too small\n"); |
| 785 | ret = -EINVAL; | 797 | ret = -EINVAL; |
| 786 | goto err_scan; | 798 | goto err; |
| 787 | } | 799 | } |
| 788 | 800 | ||
| 789 | /* For small page chips, preserve the manufacturer's | 801 | /* For small page chips, preserve the manufacturer's |
| @@ -814,7 +826,7 @@ static int __init nand_davinci_probe(struct platform_device *pdev) | |||
| 814 | dev_warn(&pdev->dev, "no 4-bit ECC support yet " | 826 | dev_warn(&pdev->dev, "no 4-bit ECC support yet " |
| 815 | "for 4KiB-page NAND\n"); | 827 | "for 4KiB-page NAND\n"); |
| 816 | ret = -EIO; | 828 | ret = -EIO; |
| 817 | goto err_scan; | 829 | goto err; |
| 818 | 830 | ||
| 819 | syndrome_done: | 831 | syndrome_done: |
| 820 | info->chip.ecc.layout = &info->ecclayout; | 832 | info->chip.ecc.layout = &info->ecclayout; |
| @@ -822,7 +834,7 @@ syndrome_done: | |||
| 822 | 834 | ||
| 823 | ret = nand_scan_tail(&info->mtd); | 835 | ret = nand_scan_tail(&info->mtd); |
| 824 | if (ret < 0) | 836 | if (ret < 0) |
| 825 | goto err_scan; | 837 | goto err; |
| 826 | 838 | ||
| 827 | if (pdata->parts) | 839 | if (pdata->parts) |
| 828 | ret = mtd_device_parse_register(&info->mtd, NULL, NULL, | 840 | ret = mtd_device_parse_register(&info->mtd, NULL, NULL, |
| @@ -835,7 +847,7 @@ syndrome_done: | |||
| 835 | NULL, 0); | 847 | NULL, 0); |
| 836 | } | 848 | } |
| 837 | if (ret < 0) | 849 | if (ret < 0) |
| 838 | goto err_scan; | 850 | goto err; |
| 839 | 851 | ||
| 840 | val = davinci_nand_readl(info, NRCSR_OFFSET); | 852 | val = davinci_nand_readl(info, NRCSR_OFFSET); |
| 841 | dev_info(&pdev->dev, "controller rev. %d.%d\n", | 853 | dev_info(&pdev->dev, "controller rev. %d.%d\n", |
| @@ -843,8 +855,7 @@ syndrome_done: | |||
| 843 | 855 | ||
| 844 | return 0; | 856 | return 0; |
| 845 | 857 | ||
| 846 | err_scan: | 858 | err: |
| 847 | err_timing: | ||
| 848 | clk_disable_unprepare(info->clk); | 859 | clk_disable_unprepare(info->clk); |
| 849 | 860 | ||
| 850 | err_clk_enable: | 861 | err_clk_enable: |
| @@ -852,15 +863,10 @@ err_clk_enable: | |||
| 852 | if (ecc_mode == NAND_ECC_HW_SYNDROME) | 863 | if (ecc_mode == NAND_ECC_HW_SYNDROME) |
| 853 | ecc4_busy = false; | 864 | ecc4_busy = false; |
| 854 | spin_unlock_irq(&davinci_nand_lock); | 865 | spin_unlock_irq(&davinci_nand_lock); |
| 855 | |||
| 856 | err_ecc: | ||
| 857 | err_clk: | ||
| 858 | err_ioremap: | ||
| 859 | err_nomem: | ||
| 860 | return ret; | 866 | return ret; |
| 861 | } | 867 | } |
| 862 | 868 | ||
| 863 | static int __exit nand_davinci_remove(struct platform_device *pdev) | 869 | static int nand_davinci_remove(struct platform_device *pdev) |
| 864 | { | 870 | { |
| 865 | struct davinci_nand_info *info = platform_get_drvdata(pdev); | 871 | struct davinci_nand_info *info = platform_get_drvdata(pdev); |
| 866 | 872 | ||
| @@ -877,7 +883,8 @@ static int __exit nand_davinci_remove(struct platform_device *pdev) | |||
| 877 | } | 883 | } |
| 878 | 884 | ||
| 879 | static struct platform_driver nand_davinci_driver = { | 885 | static struct platform_driver nand_davinci_driver = { |
| 880 | .remove = __exit_p(nand_davinci_remove), | 886 | .probe = nand_davinci_probe, |
| 887 | .remove = nand_davinci_remove, | ||
| 881 | .driver = { | 888 | .driver = { |
| 882 | .name = "davinci_nand", | 889 | .name = "davinci_nand", |
| 883 | .owner = THIS_MODULE, | 890 | .owner = THIS_MODULE, |
| @@ -886,7 +893,7 @@ static struct platform_driver nand_davinci_driver = { | |||
| 886 | }; | 893 | }; |
| 887 | MODULE_ALIAS("platform:davinci_nand"); | 894 | MODULE_ALIAS("platform:davinci_nand"); |
| 888 | 895 | ||
| 889 | module_platform_driver_probe(nand_davinci_driver, nand_davinci_probe); | 896 | module_platform_driver(nand_davinci_driver); |
| 890 | 897 | ||
| 891 | MODULE_LICENSE("GPL"); | 898 | MODULE_LICENSE("GPL"); |
| 892 | MODULE_AUTHOR("Texas Instruments"); | 899 | MODULE_AUTHOR("Texas Instruments"); |
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index 370b9dd7a278..c07cd573ad3a 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c | |||
| @@ -125,7 +125,6 @@ static void reset_buf(struct denali_nand_info *denali) | |||
| 125 | 125 | ||
| 126 | static void write_byte_to_buf(struct denali_nand_info *denali, uint8_t byte) | 126 | static void write_byte_to_buf(struct denali_nand_info *denali, uint8_t byte) |
| 127 | { | 127 | { |
| 128 | BUG_ON(denali->buf.tail >= sizeof(denali->buf.buf)); | ||
| 129 | denali->buf.buf[denali->buf.tail++] = byte; | 128 | denali->buf.buf[denali->buf.tail++] = byte; |
| 130 | } | 129 | } |
| 131 | 130 | ||
| @@ -897,7 +896,7 @@ static void read_oob_data(struct mtd_info *mtd, uint8_t *buf, int page) | |||
| 897 | /* this function examines buffers to see if they contain data that | 896 | /* this function examines buffers to see if they contain data that |
| 898 | * indicate that the buffer is part of an erased region of flash. | 897 | * indicate that the buffer is part of an erased region of flash. |
| 899 | */ | 898 | */ |
| 900 | bool is_erased(uint8_t *buf, int len) | 899 | static bool is_erased(uint8_t *buf, int len) |
| 901 | { | 900 | { |
| 902 | int i = 0; | 901 | int i = 0; |
| 903 | for (i = 0; i < len; i++) | 902 | for (i = 0; i < len; i++) |
| @@ -1429,20 +1428,12 @@ int denali_init(struct denali_nand_info *denali) | |||
| 1429 | } | 1428 | } |
| 1430 | } | 1429 | } |
| 1431 | 1430 | ||
| 1432 | /* Is 32-bit DMA supported? */ | 1431 | /* allocate a temporary buffer for nand_scan_ident() */ |
| 1433 | ret = dma_set_mask(denali->dev, DMA_BIT_MASK(32)); | 1432 | denali->buf.buf = devm_kzalloc(denali->dev, PAGE_SIZE, |
| 1434 | if (ret) { | 1433 | GFP_DMA | GFP_KERNEL); |
| 1435 | pr_err("Spectra: no usable DMA configuration\n"); | 1434 | if (!denali->buf.buf) |
| 1436 | return ret; | 1435 | return -ENOMEM; |
| 1437 | } | ||
| 1438 | denali->buf.dma_buf = dma_map_single(denali->dev, denali->buf.buf, | ||
| 1439 | DENALI_BUF_SIZE, | ||
| 1440 | DMA_BIDIRECTIONAL); | ||
| 1441 | 1436 | ||
| 1442 | if (dma_mapping_error(denali->dev, denali->buf.dma_buf)) { | ||
| 1443 | dev_err(denali->dev, "Spectra: failed to map DMA buffer\n"); | ||
| 1444 | return -EIO; | ||
| 1445 | } | ||
| 1446 | denali->mtd.dev.parent = denali->dev; | 1437 | denali->mtd.dev.parent = denali->dev; |
| 1447 | denali_hw_init(denali); | 1438 | denali_hw_init(denali); |
| 1448 | denali_drv_init(denali); | 1439 | denali_drv_init(denali); |
| @@ -1475,12 +1466,29 @@ int denali_init(struct denali_nand_info *denali) | |||
| 1475 | goto failed_req_irq; | 1466 | goto failed_req_irq; |
| 1476 | } | 1467 | } |
| 1477 | 1468 | ||
| 1478 | /* MTD supported page sizes vary by kernel. We validate our | 1469 | /* allocate the right size buffer now */ |
| 1479 | * kernel supports the device here. | 1470 | devm_kfree(denali->dev, denali->buf.buf); |
| 1480 | */ | 1471 | denali->buf.buf = devm_kzalloc(denali->dev, |
| 1481 | if (denali->mtd.writesize > NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE) { | 1472 | denali->mtd.writesize + denali->mtd.oobsize, |
| 1482 | ret = -ENODEV; | 1473 | GFP_KERNEL); |
| 1483 | pr_err("Spectra: device size not supported by this version of MTD."); | 1474 | if (!denali->buf.buf) { |
| 1475 | ret = -ENOMEM; | ||
| 1476 | goto failed_req_irq; | ||
| 1477 | } | ||
| 1478 | |||
| 1479 | /* Is 32-bit DMA supported? */ | ||
| 1480 | ret = dma_set_mask(denali->dev, DMA_BIT_MASK(32)); | ||
| 1481 | if (ret) { | ||
| 1482 | pr_err("Spectra: no usable DMA configuration\n"); | ||
| 1483 | goto failed_req_irq; | ||
| 1484 | } | ||
| 1485 | |||
| 1486 | denali->buf.dma_buf = dma_map_single(denali->dev, denali->buf.buf, | ||
| 1487 | denali->mtd.writesize + denali->mtd.oobsize, | ||
| 1488 | DMA_BIDIRECTIONAL); | ||
| 1489 | if (dma_mapping_error(denali->dev, denali->buf.dma_buf)) { | ||
| 1490 | dev_err(denali->dev, "Spectra: failed to map DMA buffer\n"); | ||
| 1491 | ret = -EIO; | ||
| 1484 | goto failed_req_irq; | 1492 | goto failed_req_irq; |
| 1485 | } | 1493 | } |
| 1486 | 1494 | ||
| @@ -1602,7 +1610,8 @@ EXPORT_SYMBOL(denali_init); | |||
| 1602 | void denali_remove(struct denali_nand_info *denali) | 1610 | void denali_remove(struct denali_nand_info *denali) |
| 1603 | { | 1611 | { |
| 1604 | denali_irq_cleanup(denali->irq, denali); | 1612 | denali_irq_cleanup(denali->irq, denali); |
| 1605 | dma_unmap_single(denali->dev, denali->buf.dma_buf, DENALI_BUF_SIZE, | 1613 | dma_unmap_single(denali->dev, denali->buf.dma_buf, |
| 1614 | denali->mtd.writesize + denali->mtd.oobsize, | ||
| 1606 | DMA_BIDIRECTIONAL); | 1615 | DMA_BIDIRECTIONAL); |
| 1607 | } | 1616 | } |
| 1608 | EXPORT_SYMBOL(denali_remove); | 1617 | EXPORT_SYMBOL(denali_remove); |
diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h index cec5712862c9..966817462421 100644 --- a/drivers/mtd/nand/denali.h +++ b/drivers/mtd/nand/denali.h | |||
| @@ -455,12 +455,10 @@ | |||
| 455 | 455 | ||
| 456 | #define ECC_SECTOR_SIZE 512 | 456 | #define ECC_SECTOR_SIZE 512 |
| 457 | 457 | ||
| 458 | #define DENALI_BUF_SIZE (NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE) | ||
| 459 | |||
| 460 | struct nand_buf { | 458 | struct nand_buf { |
| 461 | int head; | 459 | int head; |
| 462 | int tail; | 460 | int tail; |
| 463 | uint8_t buf[DENALI_BUF_SIZE]; | 461 | uint8_t *buf; |
| 464 | dma_addr_t dma_buf; | 462 | dma_addr_t dma_buf; |
| 465 | }; | 463 | }; |
| 466 | 464 | ||
diff --git a/drivers/mtd/nand/denali_dt.c b/drivers/mtd/nand/denali_dt.c index 92530244e2cb..babb02c4b220 100644 --- a/drivers/mtd/nand/denali_dt.c +++ b/drivers/mtd/nand/denali_dt.c | |||
| @@ -108,7 +108,7 @@ static int denali_dt_probe(struct platform_device *ofdev) | |||
| 108 | denali->dev->dma_mask = NULL; | 108 | denali->dev->dma_mask = NULL; |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | dt->clk = clk_get(&ofdev->dev, NULL); | 111 | dt->clk = devm_clk_get(&ofdev->dev, NULL); |
| 112 | if (IS_ERR(dt->clk)) { | 112 | if (IS_ERR(dt->clk)) { |
| 113 | dev_err(&ofdev->dev, "no clk available\n"); | 113 | dev_err(&ofdev->dev, "no clk available\n"); |
| 114 | return PTR_ERR(dt->clk); | 114 | return PTR_ERR(dt->clk); |
| @@ -124,7 +124,6 @@ static int denali_dt_probe(struct platform_device *ofdev) | |||
| 124 | 124 | ||
| 125 | out_disable_clk: | 125 | out_disable_clk: |
| 126 | clk_disable_unprepare(dt->clk); | 126 | clk_disable_unprepare(dt->clk); |
| 127 | clk_put(dt->clk); | ||
| 128 | 127 | ||
| 129 | return ret; | 128 | return ret; |
| 130 | } | 129 | } |
| @@ -135,7 +134,6 @@ static int denali_dt_remove(struct platform_device *ofdev) | |||
| 135 | 134 | ||
| 136 | denali_remove(&dt->denali); | 135 | denali_remove(&dt->denali); |
| 137 | clk_disable(dt->clk); | 136 | clk_disable(dt->clk); |
| 138 | clk_put(dt->clk); | ||
| 139 | 137 | ||
| 140 | return 0; | 138 | return 0; |
| 141 | } | 139 | } |
diff --git a/drivers/mtd/nand/denali_pci.c b/drivers/mtd/nand/denali_pci.c index 033f177a6369..6e2f387b823f 100644 --- a/drivers/mtd/nand/denali_pci.c +++ b/drivers/mtd/nand/denali_pci.c | |||
| @@ -21,7 +21,7 @@ | |||
| 21 | #define DENALI_NAND_NAME "denali-nand-pci" | 21 | #define DENALI_NAND_NAME "denali-nand-pci" |
| 22 | 22 | ||
| 23 | /* List of platforms this NAND controller has be integrated into */ | 23 | /* List of platforms this NAND controller has be integrated into */ |
| 24 | static DEFINE_PCI_DEVICE_TABLE(denali_pci_ids) = { | 24 | static const struct pci_device_id denali_pci_ids[] = { |
| 25 | { PCI_VDEVICE(INTEL, 0x0701), INTEL_CE4100 }, | 25 | { PCI_VDEVICE(INTEL, 0x0701), INTEL_CE4100 }, |
| 26 | { PCI_VDEVICE(INTEL, 0x0809), INTEL_MRST }, | 26 | { PCI_VDEVICE(INTEL, 0x0809), INTEL_MRST }, |
| 27 | { /* end: all zeroes */ } | 27 | { /* end: all zeroes */ } |
| @@ -131,7 +131,6 @@ static struct pci_driver denali_pci_driver = { | |||
| 131 | 131 | ||
| 132 | static int denali_init_pci(void) | 132 | static int denali_init_pci(void) |
| 133 | { | 133 | { |
| 134 | pr_info("Spectra MTD driver built on %s @ %s\n", __DATE__, __TIME__); | ||
| 135 | return pci_register_driver(&denali_pci_driver); | 134 | return pci_register_driver(&denali_pci_driver); |
| 136 | } | 135 | } |
| 137 | module_init(denali_init_pci); | 136 | module_init(denali_init_pci); |
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index b68a4959f700..fec31d71b84e 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c | |||
| @@ -1058,7 +1058,6 @@ static inline int __init nftl_partscan(struct mtd_info *mtd, struct mtd_partitio | |||
| 1058 | 1058 | ||
| 1059 | buf = kmalloc(mtd->writesize, GFP_KERNEL); | 1059 | buf = kmalloc(mtd->writesize, GFP_KERNEL); |
| 1060 | if (!buf) { | 1060 | if (!buf) { |
| 1061 | printk(KERN_ERR "DiskOnChip mediaheader kmalloc failed!\n"); | ||
| 1062 | return 0; | 1061 | return 0; |
| 1063 | } | 1062 | } |
| 1064 | if (!(numheaders = find_media_headers(mtd, buf, "ANAND", 1))) | 1063 | if (!(numheaders = find_media_headers(mtd, buf, "ANAND", 1))) |
| @@ -1166,7 +1165,6 @@ static inline int __init inftl_partscan(struct mtd_info *mtd, struct mtd_partiti | |||
| 1166 | 1165 | ||
| 1167 | buf = kmalloc(mtd->writesize, GFP_KERNEL); | 1166 | buf = kmalloc(mtd->writesize, GFP_KERNEL); |
| 1168 | if (!buf) { | 1167 | if (!buf) { |
| 1169 | printk(KERN_ERR "DiskOnChip mediaheader kmalloc failed!\n"); | ||
| 1170 | return 0; | 1168 | return 0; |
| 1171 | } | 1169 | } |
| 1172 | 1170 | ||
| @@ -1440,10 +1438,13 @@ static int __init doc_probe(unsigned long physadr) | |||
| 1440 | int reg, len, numchips; | 1438 | int reg, len, numchips; |
| 1441 | int ret = 0; | 1439 | int ret = 0; |
| 1442 | 1440 | ||
| 1441 | if (!request_mem_region(physadr, DOC_IOREMAP_LEN, NULL)) | ||
| 1442 | return -EBUSY; | ||
| 1443 | virtadr = ioremap(physadr, DOC_IOREMAP_LEN); | 1443 | virtadr = ioremap(physadr, DOC_IOREMAP_LEN); |
| 1444 | if (!virtadr) { | 1444 | if (!virtadr) { |
| 1445 | printk(KERN_ERR "Diskonchip ioremap failed: 0x%x bytes at 0x%lx\n", DOC_IOREMAP_LEN, physadr); | 1445 | printk(KERN_ERR "Diskonchip ioremap failed: 0x%x bytes at 0x%lx\n", DOC_IOREMAP_LEN, physadr); |
| 1446 | return -EIO; | 1446 | ret = -EIO; |
| 1447 | goto error_ioremap; | ||
| 1447 | } | 1448 | } |
| 1448 | 1449 | ||
| 1449 | /* It's not possible to cleanly detect the DiskOnChip - the | 1450 | /* It's not possible to cleanly detect the DiskOnChip - the |
| @@ -1561,7 +1562,6 @@ static int __init doc_probe(unsigned long physadr) | |||
| 1561 | sizeof(struct nand_chip) + sizeof(struct doc_priv) + (2 * sizeof(struct nand_bbt_descr)); | 1562 | sizeof(struct nand_chip) + sizeof(struct doc_priv) + (2 * sizeof(struct nand_bbt_descr)); |
| 1562 | mtd = kzalloc(len, GFP_KERNEL); | 1563 | mtd = kzalloc(len, GFP_KERNEL); |
| 1563 | if (!mtd) { | 1564 | if (!mtd) { |
| 1564 | printk(KERN_ERR "DiskOnChip kmalloc (%d bytes) failed!\n", len); | ||
| 1565 | ret = -ENOMEM; | 1565 | ret = -ENOMEM; |
| 1566 | goto fail; | 1566 | goto fail; |
| 1567 | } | 1567 | } |
| @@ -1629,6 +1629,10 @@ static int __init doc_probe(unsigned long physadr) | |||
| 1629 | WriteDOC(save_control, virtadr, DOCControl); | 1629 | WriteDOC(save_control, virtadr, DOCControl); |
| 1630 | fail: | 1630 | fail: |
| 1631 | iounmap(virtadr); | 1631 | iounmap(virtadr); |
| 1632 | |||
| 1633 | error_ioremap: | ||
| 1634 | release_mem_region(physadr, DOC_IOREMAP_LEN); | ||
| 1635 | |||
| 1632 | return ret; | 1636 | return ret; |
| 1633 | } | 1637 | } |
| 1634 | 1638 | ||
| @@ -1645,6 +1649,7 @@ static void release_nanddoc(void) | |||
| 1645 | nextmtd = doc->nextdoc; | 1649 | nextmtd = doc->nextdoc; |
| 1646 | nand_release(mtd); | 1650 | nand_release(mtd); |
| 1647 | iounmap(doc->virtadr); | 1651 | iounmap(doc->virtadr); |
| 1652 | release_mem_region(doc->physadr, DOC_IOREMAP_LEN); | ||
| 1648 | kfree(mtd); | 1653 | kfree(mtd); |
| 1649 | } | 1654 | } |
| 1650 | } | 1655 | } |
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index c966fc7474ce..bcf60800c3ce 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c | |||
| @@ -847,7 +847,6 @@ static int fsl_elbc_nand_probe(struct platform_device *pdev) | |||
| 847 | if (!fsl_lbc_ctrl_dev->nand) { | 847 | if (!fsl_lbc_ctrl_dev->nand) { |
| 848 | elbc_fcm_ctrl = kzalloc(sizeof(*elbc_fcm_ctrl), GFP_KERNEL); | 848 | elbc_fcm_ctrl = kzalloc(sizeof(*elbc_fcm_ctrl), GFP_KERNEL); |
| 849 | if (!elbc_fcm_ctrl) { | 849 | if (!elbc_fcm_ctrl) { |
| 850 | dev_err(dev, "failed to allocate memory\n"); | ||
| 851 | mutex_unlock(&fsl_elbc_nand_mutex); | 850 | mutex_unlock(&fsl_elbc_nand_mutex); |
| 852 | ret = -ENOMEM; | 851 | ret = -ENOMEM; |
| 853 | goto err; | 852 | goto err; |
| @@ -875,7 +874,7 @@ static int fsl_elbc_nand_probe(struct platform_device *pdev) | |||
| 875 | goto err; | 874 | goto err; |
| 876 | } | 875 | } |
| 877 | 876 | ||
| 878 | priv->mtd.name = kasprintf(GFP_KERNEL, "%x.flash", (unsigned)res.start); | 877 | priv->mtd.name = kasprintf(GFP_KERNEL, "%llx.flash", (u64)res.start); |
| 879 | if (!priv->mtd.name) { | 878 | if (!priv->mtd.name) { |
| 880 | ret = -ENOMEM; | 879 | ret = -ENOMEM; |
| 881 | goto err; | 880 | goto err; |
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index 43355779cff5..90ca7e75d6f0 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c | |||
| @@ -1060,7 +1060,6 @@ static int fsl_ifc_nand_probe(struct platform_device *dev) | |||
| 1060 | if (!fsl_ifc_ctrl_dev->nand) { | 1060 | if (!fsl_ifc_ctrl_dev->nand) { |
| 1061 | ifc_nand_ctrl = kzalloc(sizeof(*ifc_nand_ctrl), GFP_KERNEL); | 1061 | ifc_nand_ctrl = kzalloc(sizeof(*ifc_nand_ctrl), GFP_KERNEL); |
| 1062 | if (!ifc_nand_ctrl) { | 1062 | if (!ifc_nand_ctrl) { |
| 1063 | dev_err(&dev->dev, "failed to allocate memory\n"); | ||
| 1064 | mutex_unlock(&fsl_ifc_nand_mutex); | 1063 | mutex_unlock(&fsl_ifc_nand_mutex); |
| 1065 | return -ENOMEM; | 1064 | return -ENOMEM; |
| 1066 | } | 1065 | } |
| @@ -1101,7 +1100,7 @@ static int fsl_ifc_nand_probe(struct platform_device *dev) | |||
| 1101 | IFC_NAND_EVTER_INTR_FTOERIR_EN | | 1100 | IFC_NAND_EVTER_INTR_FTOERIR_EN | |
| 1102 | IFC_NAND_EVTER_INTR_WPERIR_EN, | 1101 | IFC_NAND_EVTER_INTR_WPERIR_EN, |
| 1103 | &ifc->ifc_nand.nand_evter_intr_en); | 1102 | &ifc->ifc_nand.nand_evter_intr_en); |
| 1104 | priv->mtd.name = kasprintf(GFP_KERNEL, "%x.flash", (unsigned)res.start); | 1103 | priv->mtd.name = kasprintf(GFP_KERNEL, "%llx.flash", (u64)res.start); |
| 1105 | if (!priv->mtd.name) { | 1104 | if (!priv->mtd.name) { |
| 1106 | ret = -ENOMEM; | 1105 | ret = -ENOMEM; |
| 1107 | goto err; | 1106 | goto err; |
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 8b2752263db9..1550692973dc 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c | |||
| @@ -889,10 +889,8 @@ static int fsmc_nand_probe_config_dt(struct platform_device *pdev, | |||
| 889 | 889 | ||
| 890 | pdata->nand_timings = devm_kzalloc(&pdev->dev, | 890 | pdata->nand_timings = devm_kzalloc(&pdev->dev, |
| 891 | sizeof(*pdata->nand_timings), GFP_KERNEL); | 891 | sizeof(*pdata->nand_timings), GFP_KERNEL); |
| 892 | if (!pdata->nand_timings) { | 892 | if (!pdata->nand_timings) |
| 893 | dev_err(&pdev->dev, "no memory for nand_timing\n"); | ||
| 894 | return -ENOMEM; | 893 | return -ENOMEM; |
| 895 | } | ||
| 896 | of_property_read_u8_array(np, "timings", (u8 *)pdata->nand_timings, | 894 | of_property_read_u8_array(np, "timings", (u8 *)pdata->nand_timings, |
| 897 | sizeof(*pdata->nand_timings)); | 895 | sizeof(*pdata->nand_timings)); |
| 898 | 896 | ||
| @@ -950,10 +948,8 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
| 950 | 948 | ||
| 951 | /* Allocate memory for the device structure (and zero it) */ | 949 | /* Allocate memory for the device structure (and zero it) */ |
| 952 | host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); | 950 | host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); |
| 953 | if (!host) { | 951 | if (!host) |
| 954 | dev_err(&pdev->dev, "failed to allocate device structure\n"); | ||
| 955 | return -ENOMEM; | 952 | return -ENOMEM; |
| 956 | } | ||
| 957 | 953 | ||
| 958 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_data"); | 954 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_data"); |
| 959 | host->data_va = devm_ioremap_resource(&pdev->dev, res); | 955 | host->data_va = devm_ioremap_resource(&pdev->dev, res); |
| @@ -1108,8 +1104,8 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
| 1108 | host->ecc_place = &fsmc_ecc4_lp_place; | 1104 | host->ecc_place = &fsmc_ecc4_lp_place; |
| 1109 | break; | 1105 | break; |
| 1110 | default: | 1106 | default: |
| 1111 | printk(KERN_WARNING "No oob scheme defined for " | 1107 | dev_warn(&pdev->dev, "No oob scheme defined for oobsize %d\n", |
| 1112 | "oobsize %d\n", mtd->oobsize); | 1108 | mtd->oobsize); |
| 1113 | BUG(); | 1109 | BUG(); |
| 1114 | } | 1110 | } |
| 1115 | } else { | 1111 | } else { |
| @@ -1124,8 +1120,8 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
| 1124 | nand->ecc.layout = &fsmc_ecc1_128_layout; | 1120 | nand->ecc.layout = &fsmc_ecc1_128_layout; |
| 1125 | break; | 1121 | break; |
| 1126 | default: | 1122 | default: |
| 1127 | printk(KERN_WARNING "No oob scheme defined for " | 1123 | dev_warn(&pdev->dev, "No oob scheme defined for oobsize %d\n", |
| 1128 | "oobsize %d\n", mtd->oobsize); | 1124 | mtd->oobsize); |
| 1129 | BUG(); | 1125 | BUG(); |
| 1130 | } | 1126 | } |
| 1131 | } | 1127 | } |
diff --git a/drivers/mtd/nand/gpio.c b/drivers/mtd/nand/gpio.c index e826f898241f..8e6148aa4539 100644 --- a/drivers/mtd/nand/gpio.c +++ b/drivers/mtd/nand/gpio.c | |||
| @@ -132,13 +132,17 @@ static int gpio_nand_get_config_of(const struct device *dev, | |||
| 132 | 132 | ||
| 133 | static struct resource *gpio_nand_get_io_sync_of(struct platform_device *pdev) | 133 | static struct resource *gpio_nand_get_io_sync_of(struct platform_device *pdev) |
| 134 | { | 134 | { |
| 135 | struct resource *r = devm_kzalloc(&pdev->dev, sizeof(*r), GFP_KERNEL); | 135 | struct resource *r; |
| 136 | u64 addr; | 136 | u64 addr; |
| 137 | 137 | ||
| 138 | if (!r || of_property_read_u64(pdev->dev.of_node, | 138 | if (of_property_read_u64(pdev->dev.of_node, |
| 139 | "gpio-control-nand,io-sync-reg", &addr)) | 139 | "gpio-control-nand,io-sync-reg", &addr)) |
| 140 | return NULL; | 140 | return NULL; |
| 141 | 141 | ||
| 142 | r = devm_kzalloc(&pdev->dev, sizeof(*r), GFP_KERNEL); | ||
| 143 | if (!r) | ||
| 144 | return NULL; | ||
| 145 | |||
| 142 | r->start = addr; | 146 | r->start = addr; |
| 143 | r->end = r->start + 0x3; | 147 | r->end = r->start + 0x3; |
| 144 | r->flags = IORESOURCE_MEM; | 148 | r->flags = IORESOURCE_MEM; |
| @@ -211,10 +215,8 @@ static int gpio_nand_probe(struct platform_device *pdev) | |||
| 211 | return -EINVAL; | 215 | return -EINVAL; |
| 212 | 216 | ||
| 213 | gpiomtd = devm_kzalloc(&pdev->dev, sizeof(*gpiomtd), GFP_KERNEL); | 217 | gpiomtd = devm_kzalloc(&pdev->dev, sizeof(*gpiomtd), GFP_KERNEL); |
| 214 | if (!gpiomtd) { | 218 | if (!gpiomtd) |
| 215 | dev_err(&pdev->dev, "failed to create NAND MTD\n"); | ||
| 216 | return -ENOMEM; | 219 | return -ENOMEM; |
| 217 | } | ||
| 218 | 220 | ||
| 219 | chip = &gpiomtd->nand_chip; | 221 | chip = &gpiomtd->nand_chip; |
| 220 | 222 | ||
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c index aaced29727fb..dd1df605a1d6 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | */ | 20 | */ |
| 21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
| 22 | #include <linux/clk.h> | 22 | #include <linux/clk.h> |
| 23 | #include <linux/slab.h> | ||
| 23 | 24 | ||
| 24 | #include "gpmi-nand.h" | 25 | #include "gpmi-nand.h" |
| 25 | #include "gpmi-regs.h" | 26 | #include "gpmi-regs.h" |
| @@ -207,30 +208,41 @@ void gpmi_dump_info(struct gpmi_nand_data *this) | |||
| 207 | u32 reg; | 208 | u32 reg; |
| 208 | int i; | 209 | int i; |
| 209 | 210 | ||
| 210 | pr_err("Show GPMI registers :\n"); | 211 | dev_err(this->dev, "Show GPMI registers :\n"); |
| 211 | for (i = 0; i <= HW_GPMI_DEBUG / 0x10 + 1; i++) { | 212 | for (i = 0; i <= HW_GPMI_DEBUG / 0x10 + 1; i++) { |
| 212 | reg = readl(r->gpmi_regs + i * 0x10); | 213 | reg = readl(r->gpmi_regs + i * 0x10); |
| 213 | pr_err("offset 0x%.3x : 0x%.8x\n", i * 0x10, reg); | 214 | dev_err(this->dev, "offset 0x%.3x : 0x%.8x\n", i * 0x10, reg); |
| 214 | } | 215 | } |
| 215 | 216 | ||
| 216 | /* start to print out the BCH info */ | 217 | /* start to print out the BCH info */ |
| 217 | pr_err("Show BCH registers :\n"); | 218 | dev_err(this->dev, "Show BCH registers :\n"); |
| 218 | for (i = 0; i <= HW_BCH_VERSION / 0x10 + 1; i++) { | 219 | for (i = 0; i <= HW_BCH_VERSION / 0x10 + 1; i++) { |
| 219 | reg = readl(r->bch_regs + i * 0x10); | 220 | reg = readl(r->bch_regs + i * 0x10); |
| 220 | pr_err("offset 0x%.3x : 0x%.8x\n", i * 0x10, reg); | 221 | dev_err(this->dev, "offset 0x%.3x : 0x%.8x\n", i * 0x10, reg); |
| 221 | } | 222 | } |
| 222 | pr_err("BCH Geometry :\n"); | 223 | dev_err(this->dev, "BCH Geometry :\n" |
| 223 | pr_err("GF length : %u\n", geo->gf_len); | 224 | "GF length : %u\n" |
| 224 | pr_err("ECC Strength : %u\n", geo->ecc_strength); | 225 | "ECC Strength : %u\n" |
| 225 | pr_err("Page Size in Bytes : %u\n", geo->page_size); | 226 | "Page Size in Bytes : %u\n" |
| 226 | pr_err("Metadata Size in Bytes : %u\n", geo->metadata_size); | 227 | "Metadata Size in Bytes : %u\n" |
| 227 | pr_err("ECC Chunk Size in Bytes: %u\n", geo->ecc_chunk_size); | 228 | "ECC Chunk Size in Bytes: %u\n" |
| 228 | pr_err("ECC Chunk Count : %u\n", geo->ecc_chunk_count); | 229 | "ECC Chunk Count : %u\n" |
| 229 | pr_err("Payload Size in Bytes : %u\n", geo->payload_size); | 230 | "Payload Size in Bytes : %u\n" |
| 230 | pr_err("Auxiliary Size in Bytes: %u\n", geo->auxiliary_size); | 231 | "Auxiliary Size in Bytes: %u\n" |
| 231 | pr_err("Auxiliary Status Offset: %u\n", geo->auxiliary_status_offset); | 232 | "Auxiliary Status Offset: %u\n" |
| 232 | pr_err("Block Mark Byte Offset : %u\n", geo->block_mark_byte_offset); | 233 | "Block Mark Byte Offset : %u\n" |
| 233 | pr_err("Block Mark Bit Offset : %u\n", geo->block_mark_bit_offset); | 234 | "Block Mark Bit Offset : %u\n", |
| 235 | geo->gf_len, | ||
| 236 | geo->ecc_strength, | ||
| 237 | geo->page_size, | ||
| 238 | geo->metadata_size, | ||
| 239 | geo->ecc_chunk_size, | ||
| 240 | geo->ecc_chunk_count, | ||
| 241 | geo->payload_size, | ||
| 242 | geo->auxiliary_size, | ||
| 243 | geo->auxiliary_status_offset, | ||
| 244 | geo->block_mark_byte_offset, | ||
| 245 | geo->block_mark_bit_offset); | ||
| 234 | } | 246 | } |
| 235 | 247 | ||
| 236 | /* Configures the geometry for BCH. */ | 248 | /* Configures the geometry for BCH. */ |
| @@ -265,8 +277,8 @@ int bch_set_geometry(struct gpmi_nand_data *this) | |||
| 265 | * chip, otherwise it will lock up. So we skip resetting BCH on the MX23. | 277 | * chip, otherwise it will lock up. So we skip resetting BCH on the MX23. |
| 266 | * On the other hand, the MX28 needs the reset, because one case has been | 278 | * On the other hand, the MX28 needs the reset, because one case has been |
| 267 | * seen where the BCH produced ECC errors constantly after 10000 | 279 | * seen where the BCH produced ECC errors constantly after 10000 |
| 268 | * consecutive reboots. The latter case has not been seen on the MX23 yet, | 280 | * consecutive reboots. The latter case has not been seen on the MX23 |
| 269 | * still we don't know if it could happen there as well. | 281 | * yet, still we don't know if it could happen there as well. |
| 270 | */ | 282 | */ |
| 271 | ret = gpmi_reset_block(r->bch_regs, GPMI_IS_MX23(this)); | 283 | ret = gpmi_reset_block(r->bch_regs, GPMI_IS_MX23(this)); |
| 272 | if (ret) | 284 | if (ret) |
| @@ -353,7 +365,7 @@ static int gpmi_nfc_compute_hardware_timing(struct gpmi_nand_data *this, | |||
| 353 | improved_timing_is_available = | 365 | improved_timing_is_available = |
| 354 | (target.tREA_in_ns >= 0) && | 366 | (target.tREA_in_ns >= 0) && |
| 355 | (target.tRLOH_in_ns >= 0) && | 367 | (target.tRLOH_in_ns >= 0) && |
| 356 | (target.tRHOH_in_ns >= 0) ; | 368 | (target.tRHOH_in_ns >= 0); |
| 357 | 369 | ||
| 358 | /* Inspect the clock. */ | 370 | /* Inspect the clock. */ |
| 359 | nfc->clock_frequency_in_hz = clk_get_rate(r->clock[0]); | 371 | nfc->clock_frequency_in_hz = clk_get_rate(r->clock[0]); |
| @@ -911,10 +923,14 @@ static int enable_edo_mode(struct gpmi_nand_data *this, int mode) | |||
| 911 | struct resources *r = &this->resources; | 923 | struct resources *r = &this->resources; |
| 912 | struct nand_chip *nand = &this->nand; | 924 | struct nand_chip *nand = &this->nand; |
| 913 | struct mtd_info *mtd = &this->mtd; | 925 | struct mtd_info *mtd = &this->mtd; |
| 914 | uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {}; | 926 | uint8_t *feature; |
| 915 | unsigned long rate; | 927 | unsigned long rate; |
| 916 | int ret; | 928 | int ret; |
| 917 | 929 | ||
| 930 | feature = kzalloc(ONFI_SUBFEATURE_PARAM_LEN, GFP_KERNEL); | ||
| 931 | if (!feature) | ||
| 932 | return -ENOMEM; | ||
| 933 | |||
| 918 | nand->select_chip(mtd, 0); | 934 | nand->select_chip(mtd, 0); |
| 919 | 935 | ||
| 920 | /* [1] send SET FEATURE commond to NAND */ | 936 | /* [1] send SET FEATURE commond to NAND */ |
| @@ -942,11 +958,13 @@ static int enable_edo_mode(struct gpmi_nand_data *this, int mode) | |||
| 942 | 958 | ||
| 943 | this->flags |= GPMI_ASYNC_EDO_ENABLED; | 959 | this->flags |= GPMI_ASYNC_EDO_ENABLED; |
| 944 | this->timing_mode = mode; | 960 | this->timing_mode = mode; |
| 961 | kfree(feature); | ||
| 945 | dev_info(this->dev, "enable the asynchronous EDO mode %d\n", mode); | 962 | dev_info(this->dev, "enable the asynchronous EDO mode %d\n", mode); |
| 946 | return 0; | 963 | return 0; |
| 947 | 964 | ||
| 948 | err_out: | 965 | err_out: |
| 949 | nand->select_chip(mtd, -1); | 966 | nand->select_chip(mtd, -1); |
| 967 | kfree(feature); | ||
| 950 | dev_err(this->dev, "mode:%d ,failed in set feature.\n", mode); | 968 | dev_err(this->dev, "mode:%d ,failed in set feature.\n", mode); |
| 951 | return -EINVAL; | 969 | return -EINVAL; |
| 952 | } | 970 | } |
| @@ -986,7 +1004,7 @@ void gpmi_begin(struct gpmi_nand_data *this) | |||
| 986 | /* Enable the clock. */ | 1004 | /* Enable the clock. */ |
| 987 | ret = gpmi_enable_clk(this); | 1005 | ret = gpmi_enable_clk(this); |
| 988 | if (ret) { | 1006 | if (ret) { |
| 989 | pr_err("We failed in enable the clk\n"); | 1007 | dev_err(this->dev, "We failed in enable the clk\n"); |
| 990 | goto err_out; | 1008 | goto err_out; |
| 991 | } | 1009 | } |
| 992 | 1010 | ||
| @@ -1003,7 +1021,7 @@ void gpmi_begin(struct gpmi_nand_data *this) | |||
| 1003 | /* [1] Set HW_GPMI_TIMING0 */ | 1021 | /* [1] Set HW_GPMI_TIMING0 */ |
| 1004 | reg = BF_GPMI_TIMING0_ADDRESS_SETUP(hw.address_setup_in_cycles) | | 1022 | reg = BF_GPMI_TIMING0_ADDRESS_SETUP(hw.address_setup_in_cycles) | |
| 1005 | BF_GPMI_TIMING0_DATA_HOLD(hw.data_hold_in_cycles) | | 1023 | BF_GPMI_TIMING0_DATA_HOLD(hw.data_hold_in_cycles) | |
| 1006 | BF_GPMI_TIMING0_DATA_SETUP(hw.data_setup_in_cycles) ; | 1024 | BF_GPMI_TIMING0_DATA_SETUP(hw.data_setup_in_cycles); |
| 1007 | 1025 | ||
| 1008 | writel(reg, gpmi_regs + HW_GPMI_TIMING0); | 1026 | writel(reg, gpmi_regs + HW_GPMI_TIMING0); |
| 1009 | 1027 | ||
| @@ -1090,7 +1108,7 @@ int gpmi_is_ready(struct gpmi_nand_data *this, unsigned chip) | |||
| 1090 | mask = MX28_BF_GPMI_STAT_READY_BUSY(1 << chip); | 1108 | mask = MX28_BF_GPMI_STAT_READY_BUSY(1 << chip); |
| 1091 | reg = readl(r->gpmi_regs + HW_GPMI_STAT); | 1109 | reg = readl(r->gpmi_regs + HW_GPMI_STAT); |
| 1092 | } else | 1110 | } else |
| 1093 | pr_err("unknow arch.\n"); | 1111 | dev_err(this->dev, "unknow arch.\n"); |
| 1094 | return reg & mask; | 1112 | return reg & mask; |
| 1095 | } | 1113 | } |
| 1096 | 1114 | ||
| @@ -1121,10 +1139,8 @@ int gpmi_send_command(struct gpmi_nand_data *this) | |||
| 1121 | desc = dmaengine_prep_slave_sg(channel, | 1139 | desc = dmaengine_prep_slave_sg(channel, |
| 1122 | (struct scatterlist *)pio, | 1140 | (struct scatterlist *)pio, |
| 1123 | ARRAY_SIZE(pio), DMA_TRANS_NONE, 0); | 1141 | ARRAY_SIZE(pio), DMA_TRANS_NONE, 0); |
| 1124 | if (!desc) { | 1142 | if (!desc) |
| 1125 | pr_err("step 1 error\n"); | 1143 | return -EINVAL; |
| 1126 | return -1; | ||
| 1127 | } | ||
| 1128 | 1144 | ||
| 1129 | /* [2] send out the COMMAND + ADDRESS string stored in @buffer */ | 1145 | /* [2] send out the COMMAND + ADDRESS string stored in @buffer */ |
| 1130 | sgl = &this->cmd_sgl; | 1146 | sgl = &this->cmd_sgl; |
| @@ -1134,11 +1150,8 @@ int gpmi_send_command(struct gpmi_nand_data *this) | |||
| 1134 | desc = dmaengine_prep_slave_sg(channel, | 1150 | desc = dmaengine_prep_slave_sg(channel, |
| 1135 | sgl, 1, DMA_MEM_TO_DEV, | 1151 | sgl, 1, DMA_MEM_TO_DEV, |
| 1136 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 1152 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
| 1137 | 1153 | if (!desc) | |
| 1138 | if (!desc) { | 1154 | return -EINVAL; |
| 1139 | pr_err("step 2 error\n"); | ||
| 1140 | return -1; | ||
| 1141 | } | ||
| 1142 | 1155 | ||
| 1143 | /* [3] submit the DMA */ | 1156 | /* [3] submit the DMA */ |
| 1144 | set_dma_type(this, DMA_FOR_COMMAND); | 1157 | set_dma_type(this, DMA_FOR_COMMAND); |
| @@ -1167,20 +1180,17 @@ int gpmi_send_data(struct gpmi_nand_data *this) | |||
| 1167 | pio[1] = 0; | 1180 | pio[1] = 0; |
| 1168 | desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)pio, | 1181 | desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)pio, |
| 1169 | ARRAY_SIZE(pio), DMA_TRANS_NONE, 0); | 1182 | ARRAY_SIZE(pio), DMA_TRANS_NONE, 0); |
| 1170 | if (!desc) { | 1183 | if (!desc) |
| 1171 | pr_err("step 1 error\n"); | 1184 | return -EINVAL; |
| 1172 | return -1; | ||
| 1173 | } | ||
| 1174 | 1185 | ||
| 1175 | /* [2] send DMA request */ | 1186 | /* [2] send DMA request */ |
| 1176 | prepare_data_dma(this, DMA_TO_DEVICE); | 1187 | prepare_data_dma(this, DMA_TO_DEVICE); |
| 1177 | desc = dmaengine_prep_slave_sg(channel, &this->data_sgl, | 1188 | desc = dmaengine_prep_slave_sg(channel, &this->data_sgl, |
| 1178 | 1, DMA_MEM_TO_DEV, | 1189 | 1, DMA_MEM_TO_DEV, |
| 1179 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 1190 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
| 1180 | if (!desc) { | 1191 | if (!desc) |
| 1181 | pr_err("step 2 error\n"); | 1192 | return -EINVAL; |
| 1182 | return -1; | 1193 | |
| 1183 | } | ||
| 1184 | /* [3] submit the DMA */ | 1194 | /* [3] submit the DMA */ |
| 1185 | set_dma_type(this, DMA_FOR_WRITE_DATA); | 1195 | set_dma_type(this, DMA_FOR_WRITE_DATA); |
| 1186 | return start_dma_without_bch_irq(this, desc); | 1196 | return start_dma_without_bch_irq(this, desc); |
| @@ -1204,20 +1214,16 @@ int gpmi_read_data(struct gpmi_nand_data *this) | |||
| 1204 | desc = dmaengine_prep_slave_sg(channel, | 1214 | desc = dmaengine_prep_slave_sg(channel, |
| 1205 | (struct scatterlist *)pio, | 1215 | (struct scatterlist *)pio, |
| 1206 | ARRAY_SIZE(pio), DMA_TRANS_NONE, 0); | 1216 | ARRAY_SIZE(pio), DMA_TRANS_NONE, 0); |
| 1207 | if (!desc) { | 1217 | if (!desc) |
| 1208 | pr_err("step 1 error\n"); | 1218 | return -EINVAL; |
| 1209 | return -1; | ||
| 1210 | } | ||
| 1211 | 1219 | ||
| 1212 | /* [2] : send DMA request */ | 1220 | /* [2] : send DMA request */ |
| 1213 | prepare_data_dma(this, DMA_FROM_DEVICE); | 1221 | prepare_data_dma(this, DMA_FROM_DEVICE); |
| 1214 | desc = dmaengine_prep_slave_sg(channel, &this->data_sgl, | 1222 | desc = dmaengine_prep_slave_sg(channel, &this->data_sgl, |
| 1215 | 1, DMA_DEV_TO_MEM, | 1223 | 1, DMA_DEV_TO_MEM, |
| 1216 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 1224 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
| 1217 | if (!desc) { | 1225 | if (!desc) |
| 1218 | pr_err("step 2 error\n"); | 1226 | return -EINVAL; |
| 1219 | return -1; | ||
| 1220 | } | ||
| 1221 | 1227 | ||
| 1222 | /* [3] : submit the DMA */ | 1228 | /* [3] : submit the DMA */ |
| 1223 | set_dma_type(this, DMA_FOR_READ_DATA); | 1229 | set_dma_type(this, DMA_FOR_READ_DATA); |
| @@ -1262,10 +1268,9 @@ int gpmi_send_page(struct gpmi_nand_data *this, | |||
| 1262 | (struct scatterlist *)pio, | 1268 | (struct scatterlist *)pio, |
| 1263 | ARRAY_SIZE(pio), DMA_TRANS_NONE, | 1269 | ARRAY_SIZE(pio), DMA_TRANS_NONE, |
| 1264 | DMA_CTRL_ACK); | 1270 | DMA_CTRL_ACK); |
| 1265 | if (!desc) { | 1271 | if (!desc) |
| 1266 | pr_err("step 2 error\n"); | 1272 | return -EINVAL; |
| 1267 | return -1; | 1273 | |
| 1268 | } | ||
| 1269 | set_dma_type(this, DMA_FOR_WRITE_ECC_PAGE); | 1274 | set_dma_type(this, DMA_FOR_WRITE_ECC_PAGE); |
| 1270 | return start_dma_with_bch_irq(this, desc); | 1275 | return start_dma_with_bch_irq(this, desc); |
| 1271 | } | 1276 | } |
| @@ -1297,10 +1302,8 @@ int gpmi_read_page(struct gpmi_nand_data *this, | |||
| 1297 | desc = dmaengine_prep_slave_sg(channel, | 1302 | desc = dmaengine_prep_slave_sg(channel, |
| 1298 | (struct scatterlist *)pio, 2, | 1303 | (struct scatterlist *)pio, 2, |
| 1299 | DMA_TRANS_NONE, 0); | 1304 | DMA_TRANS_NONE, 0); |
| 1300 | if (!desc) { | 1305 | if (!desc) |
| 1301 | pr_err("step 1 error\n"); | 1306 | return -EINVAL; |
| 1302 | return -1; | ||
| 1303 | } | ||
| 1304 | 1307 | ||
| 1305 | /* [2] Enable the BCH block and read. */ | 1308 | /* [2] Enable the BCH block and read. */ |
| 1306 | command_mode = BV_GPMI_CTRL0_COMMAND_MODE__READ; | 1309 | command_mode = BV_GPMI_CTRL0_COMMAND_MODE__READ; |
| @@ -1327,10 +1330,8 @@ int gpmi_read_page(struct gpmi_nand_data *this, | |||
| 1327 | (struct scatterlist *)pio, | 1330 | (struct scatterlist *)pio, |
| 1328 | ARRAY_SIZE(pio), DMA_TRANS_NONE, | 1331 | ARRAY_SIZE(pio), DMA_TRANS_NONE, |
| 1329 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 1332 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
| 1330 | if (!desc) { | 1333 | if (!desc) |
| 1331 | pr_err("step 2 error\n"); | 1334 | return -EINVAL; |
| 1332 | return -1; | ||
| 1333 | } | ||
| 1334 | 1335 | ||
| 1335 | /* [3] Disable the BCH block */ | 1336 | /* [3] Disable the BCH block */ |
| 1336 | command_mode = BV_GPMI_CTRL0_COMMAND_MODE__WAIT_FOR_READY; | 1337 | command_mode = BV_GPMI_CTRL0_COMMAND_MODE__WAIT_FOR_READY; |
| @@ -1348,10 +1349,8 @@ int gpmi_read_page(struct gpmi_nand_data *this, | |||
| 1348 | (struct scatterlist *)pio, 3, | 1349 | (struct scatterlist *)pio, 3, |
| 1349 | DMA_TRANS_NONE, | 1350 | DMA_TRANS_NONE, |
| 1350 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | 1351 | DMA_PREP_INTERRUPT | DMA_CTRL_ACK); |
| 1351 | if (!desc) { | 1352 | if (!desc) |
| 1352 | pr_err("step 3 error\n"); | 1353 | return -EINVAL; |
| 1353 | return -1; | ||
| 1354 | } | ||
| 1355 | 1354 | ||
| 1356 | /* [4] submit the DMA */ | 1355 | /* [4] submit the DMA */ |
| 1357 | set_dma_type(this, DMA_FOR_READ_ECC_PAGE); | 1356 | set_dma_type(this, DMA_FOR_READ_ECC_PAGE); |
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index dabbc14db563..ca6369fe91ff 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c | |||
| @@ -18,9 +18,6 @@ | |||
| 18 | * with this program; if not, write to the Free Software Foundation, Inc., | 18 | * with this program; if not, write to the Free Software Foundation, Inc., |
| 19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | 19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
| 20 | */ | 20 | */ |
| 21 | |||
| 22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 23 | |||
| 24 | #include <linux/clk.h> | 21 | #include <linux/clk.h> |
| 25 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
| 26 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
| @@ -352,6 +349,9 @@ static int legacy_set_geometry(struct gpmi_nand_data *this) | |||
| 352 | 349 | ||
| 353 | int common_nfc_set_geometry(struct gpmi_nand_data *this) | 350 | int common_nfc_set_geometry(struct gpmi_nand_data *this) |
| 354 | { | 351 | { |
| 352 | if (of_property_read_bool(this->dev->of_node, "fsl,use-minimum-ecc") | ||
| 353 | && set_geometry_by_ecc_info(this)) | ||
| 354 | return 0; | ||
| 355 | return legacy_set_geometry(this); | 355 | return legacy_set_geometry(this); |
| 356 | } | 356 | } |
| 357 | 357 | ||
| @@ -367,25 +367,28 @@ void prepare_data_dma(struct gpmi_nand_data *this, enum dma_data_direction dr) | |||
| 367 | struct scatterlist *sgl = &this->data_sgl; | 367 | struct scatterlist *sgl = &this->data_sgl; |
| 368 | int ret; | 368 | int ret; |
| 369 | 369 | ||
| 370 | this->direct_dma_map_ok = true; | ||
| 371 | |||
| 372 | /* first try to map the upper buffer directly */ | 370 | /* first try to map the upper buffer directly */ |
| 373 | sg_init_one(sgl, this->upper_buf, this->upper_len); | 371 | if (virt_addr_valid(this->upper_buf) && |
| 374 | ret = dma_map_sg(this->dev, sgl, 1, dr); | 372 | !object_is_on_stack(this->upper_buf)) { |
| 375 | if (ret == 0) { | 373 | sg_init_one(sgl, this->upper_buf, this->upper_len); |
| 376 | /* We have to use our own DMA buffer. */ | ||
| 377 | sg_init_one(sgl, this->data_buffer_dma, PAGE_SIZE); | ||
| 378 | |||
| 379 | if (dr == DMA_TO_DEVICE) | ||
| 380 | memcpy(this->data_buffer_dma, this->upper_buf, | ||
| 381 | this->upper_len); | ||
| 382 | |||
| 383 | ret = dma_map_sg(this->dev, sgl, 1, dr); | 374 | ret = dma_map_sg(this->dev, sgl, 1, dr); |
| 384 | if (ret == 0) | 375 | if (ret == 0) |
| 385 | pr_err("DMA mapping failed.\n"); | 376 | goto map_fail; |
| 386 | 377 | ||
| 387 | this->direct_dma_map_ok = false; | 378 | this->direct_dma_map_ok = true; |
| 379 | return; | ||
| 388 | } | 380 | } |
| 381 | |||
| 382 | map_fail: | ||
| 383 | /* We have to use our own DMA buffer. */ | ||
| 384 | sg_init_one(sgl, this->data_buffer_dma, this->upper_len); | ||
| 385 | |||
| 386 | if (dr == DMA_TO_DEVICE) | ||
| 387 | memcpy(this->data_buffer_dma, this->upper_buf, this->upper_len); | ||
| 388 | |||
| 389 | dma_map_sg(this->dev, sgl, 1, dr); | ||
| 390 | |||
| 391 | this->direct_dma_map_ok = false; | ||
| 389 | } | 392 | } |
| 390 | 393 | ||
| 391 | /* This will be called after the DMA operation is finished. */ | 394 | /* This will be called after the DMA operation is finished. */ |
| @@ -416,7 +419,7 @@ static void dma_irq_callback(void *param) | |||
| 416 | break; | 419 | break; |
| 417 | 420 | ||
| 418 | default: | 421 | default: |
| 419 | pr_err("in wrong DMA operation.\n"); | 422 | dev_err(this->dev, "in wrong DMA operation.\n"); |
| 420 | } | 423 | } |
| 421 | 424 | ||
| 422 | complete(dma_c); | 425 | complete(dma_c); |
| @@ -438,7 +441,8 @@ int start_dma_without_bch_irq(struct gpmi_nand_data *this, | |||
| 438 | /* Wait for the interrupt from the DMA block. */ | 441 | /* Wait for the interrupt from the DMA block. */ |
| 439 | err = wait_for_completion_timeout(dma_c, msecs_to_jiffies(1000)); | 442 | err = wait_for_completion_timeout(dma_c, msecs_to_jiffies(1000)); |
| 440 | if (!err) { | 443 | if (!err) { |
| 441 | pr_err("DMA timeout, last DMA :%d\n", this->last_dma_type); | 444 | dev_err(this->dev, "DMA timeout, last DMA :%d\n", |
| 445 | this->last_dma_type); | ||
| 442 | gpmi_dump_info(this); | 446 | gpmi_dump_info(this); |
| 443 | return -ETIMEDOUT; | 447 | return -ETIMEDOUT; |
| 444 | } | 448 | } |
| @@ -467,7 +471,8 @@ int start_dma_with_bch_irq(struct gpmi_nand_data *this, | |||
| 467 | /* Wait for the interrupt from the BCH block. */ | 471 | /* Wait for the interrupt from the BCH block. */ |
| 468 | err = wait_for_completion_timeout(bch_c, msecs_to_jiffies(1000)); | 472 | err = wait_for_completion_timeout(bch_c, msecs_to_jiffies(1000)); |
| 469 | if (!err) { | 473 | if (!err) { |
| 470 | pr_err("BCH timeout, last DMA :%d\n", this->last_dma_type); | 474 | dev_err(this->dev, "BCH timeout, last DMA :%d\n", |
| 475 | this->last_dma_type); | ||
| 471 | gpmi_dump_info(this); | 476 | gpmi_dump_info(this); |
| 472 | return -ETIMEDOUT; | 477 | return -ETIMEDOUT; |
| 473 | } | 478 | } |
| @@ -483,70 +488,38 @@ static int acquire_register_block(struct gpmi_nand_data *this, | |||
| 483 | void __iomem *p; | 488 | void __iomem *p; |
| 484 | 489 | ||
| 485 | r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name); | 490 | r = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name); |
| 486 | if (!r) { | 491 | p = devm_ioremap_resource(&pdev->dev, r); |
| 487 | pr_err("Can't get resource for %s\n", res_name); | 492 | if (IS_ERR(p)) |
| 488 | return -ENODEV; | 493 | return PTR_ERR(p); |
| 489 | } | ||
| 490 | |||
| 491 | p = ioremap(r->start, resource_size(r)); | ||
| 492 | if (!p) { | ||
| 493 | pr_err("Can't remap %s\n", res_name); | ||
| 494 | return -ENOMEM; | ||
| 495 | } | ||
| 496 | 494 | ||
| 497 | if (!strcmp(res_name, GPMI_NAND_GPMI_REGS_ADDR_RES_NAME)) | 495 | if (!strcmp(res_name, GPMI_NAND_GPMI_REGS_ADDR_RES_NAME)) |
| 498 | res->gpmi_regs = p; | 496 | res->gpmi_regs = p; |
| 499 | else if (!strcmp(res_name, GPMI_NAND_BCH_REGS_ADDR_RES_NAME)) | 497 | else if (!strcmp(res_name, GPMI_NAND_BCH_REGS_ADDR_RES_NAME)) |
| 500 | res->bch_regs = p; | 498 | res->bch_regs = p; |
| 501 | else | 499 | else |
| 502 | pr_err("unknown resource name : %s\n", res_name); | 500 | dev_err(this->dev, "unknown resource name : %s\n", res_name); |
| 503 | 501 | ||
| 504 | return 0; | 502 | return 0; |
| 505 | } | 503 | } |
| 506 | 504 | ||
| 507 | static void release_register_block(struct gpmi_nand_data *this) | ||
| 508 | { | ||
| 509 | struct resources *res = &this->resources; | ||
| 510 | if (res->gpmi_regs) | ||
| 511 | iounmap(res->gpmi_regs); | ||
| 512 | if (res->bch_regs) | ||
| 513 | iounmap(res->bch_regs); | ||
| 514 | res->gpmi_regs = NULL; | ||
| 515 | res->bch_regs = NULL; | ||
| 516 | } | ||
| 517 | |||
| 518 | static int acquire_bch_irq(struct gpmi_nand_data *this, irq_handler_t irq_h) | 505 | static int acquire_bch_irq(struct gpmi_nand_data *this, irq_handler_t irq_h) |
| 519 | { | 506 | { |
| 520 | struct platform_device *pdev = this->pdev; | 507 | struct platform_device *pdev = this->pdev; |
| 521 | struct resources *res = &this->resources; | ||
| 522 | const char *res_name = GPMI_NAND_BCH_INTERRUPT_RES_NAME; | 508 | const char *res_name = GPMI_NAND_BCH_INTERRUPT_RES_NAME; |
| 523 | struct resource *r; | 509 | struct resource *r; |
| 524 | int err; | 510 | int err; |
| 525 | 511 | ||
| 526 | r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, res_name); | 512 | r = platform_get_resource_byname(pdev, IORESOURCE_IRQ, res_name); |
| 527 | if (!r) { | 513 | if (!r) { |
| 528 | pr_err("Can't get resource for %s\n", res_name); | 514 | dev_err(this->dev, "Can't get resource for %s\n", res_name); |
| 529 | return -ENODEV; | 515 | return -ENODEV; |
| 530 | } | 516 | } |
| 531 | 517 | ||
| 532 | err = request_irq(r->start, irq_h, 0, res_name, this); | 518 | err = devm_request_irq(this->dev, r->start, irq_h, 0, res_name, this); |
| 533 | if (err) { | 519 | if (err) |
| 534 | pr_err("Can't own %s\n", res_name); | 520 | dev_err(this->dev, "error requesting BCH IRQ\n"); |
| 535 | return err; | ||
| 536 | } | ||
| 537 | |||
| 538 | res->bch_low_interrupt = r->start; | ||
| 539 | res->bch_high_interrupt = r->end; | ||
| 540 | return 0; | ||
| 541 | } | ||
| 542 | |||
| 543 | static void release_bch_irq(struct gpmi_nand_data *this) | ||
| 544 | { | ||
| 545 | struct resources *res = &this->resources; | ||
| 546 | int i = res->bch_low_interrupt; | ||
| 547 | 521 | ||
| 548 | for (; i <= res->bch_high_interrupt; i++) | 522 | return err; |
| 549 | free_irq(i, this); | ||
| 550 | } | 523 | } |
| 551 | 524 | ||
| 552 | static void release_dma_channels(struct gpmi_nand_data *this) | 525 | static void release_dma_channels(struct gpmi_nand_data *this) |
| @@ -567,7 +540,7 @@ static int acquire_dma_channels(struct gpmi_nand_data *this) | |||
| 567 | /* request dma channel */ | 540 | /* request dma channel */ |
| 568 | dma_chan = dma_request_slave_channel(&pdev->dev, "rx-tx"); | 541 | dma_chan = dma_request_slave_channel(&pdev->dev, "rx-tx"); |
| 569 | if (!dma_chan) { | 542 | if (!dma_chan) { |
| 570 | pr_err("Failed to request DMA channel.\n"); | 543 | dev_err(this->dev, "Failed to request DMA channel.\n"); |
| 571 | goto acquire_err; | 544 | goto acquire_err; |
| 572 | } | 545 | } |
| 573 | 546 | ||
| @@ -579,21 +552,6 @@ acquire_err: | |||
| 579 | return -EINVAL; | 552 | return -EINVAL; |
| 580 | } | 553 | } |
| 581 | 554 | ||
| 582 | static void gpmi_put_clks(struct gpmi_nand_data *this) | ||
| 583 | { | ||
| 584 | struct resources *r = &this->resources; | ||
| 585 | struct clk *clk; | ||
| 586 | int i; | ||
| 587 | |||
| 588 | for (i = 0; i < GPMI_CLK_MAX; i++) { | ||
| 589 | clk = r->clock[i]; | ||
| 590 | if (clk) { | ||
| 591 | clk_put(clk); | ||
| 592 | r->clock[i] = NULL; | ||
| 593 | } | ||
| 594 | } | ||
| 595 | } | ||
| 596 | |||
| 597 | static char *extra_clks_for_mx6q[GPMI_CLK_MAX] = { | 555 | static char *extra_clks_for_mx6q[GPMI_CLK_MAX] = { |
| 598 | "gpmi_apb", "gpmi_bch", "gpmi_bch_apb", "per1_bch", | 556 | "gpmi_apb", "gpmi_bch", "gpmi_bch_apb", "per1_bch", |
| 599 | }; | 557 | }; |
| @@ -606,7 +564,7 @@ static int gpmi_get_clks(struct gpmi_nand_data *this) | |||
| 606 | int err, i; | 564 | int err, i; |
| 607 | 565 | ||
| 608 | /* The main clock is stored in the first. */ | 566 | /* The main clock is stored in the first. */ |
| 609 | r->clock[0] = clk_get(this->dev, "gpmi_io"); | 567 | r->clock[0] = devm_clk_get(this->dev, "gpmi_io"); |
| 610 | if (IS_ERR(r->clock[0])) { | 568 | if (IS_ERR(r->clock[0])) { |
| 611 | err = PTR_ERR(r->clock[0]); | 569 | err = PTR_ERR(r->clock[0]); |
| 612 | goto err_clock; | 570 | goto err_clock; |
| @@ -622,7 +580,7 @@ static int gpmi_get_clks(struct gpmi_nand_data *this) | |||
| 622 | if (extra_clks[i - 1] == NULL) | 580 | if (extra_clks[i - 1] == NULL) |
| 623 | break; | 581 | break; |
| 624 | 582 | ||
| 625 | clk = clk_get(this->dev, extra_clks[i - 1]); | 583 | clk = devm_clk_get(this->dev, extra_clks[i - 1]); |
| 626 | if (IS_ERR(clk)) { | 584 | if (IS_ERR(clk)) { |
| 627 | err = PTR_ERR(clk); | 585 | err = PTR_ERR(clk); |
| 628 | goto err_clock; | 586 | goto err_clock; |
| @@ -644,7 +602,6 @@ static int gpmi_get_clks(struct gpmi_nand_data *this) | |||
| 644 | 602 | ||
| 645 | err_clock: | 603 | err_clock: |
| 646 | dev_dbg(this->dev, "failed in finding the clocks.\n"); | 604 | dev_dbg(this->dev, "failed in finding the clocks.\n"); |
| 647 | gpmi_put_clks(this); | ||
| 648 | return err; | 605 | return err; |
| 649 | } | 606 | } |
| 650 | 607 | ||
| @@ -666,7 +623,7 @@ static int acquire_resources(struct gpmi_nand_data *this) | |||
| 666 | 623 | ||
| 667 | ret = acquire_dma_channels(this); | 624 | ret = acquire_dma_channels(this); |
| 668 | if (ret) | 625 | if (ret) |
| 669 | goto exit_dma_channels; | 626 | goto exit_regs; |
| 670 | 627 | ||
| 671 | ret = gpmi_get_clks(this); | 628 | ret = gpmi_get_clks(this); |
| 672 | if (ret) | 629 | if (ret) |
| @@ -675,18 +632,12 @@ static int acquire_resources(struct gpmi_nand_data *this) | |||
| 675 | 632 | ||
| 676 | exit_clock: | 633 | exit_clock: |
| 677 | release_dma_channels(this); | 634 | release_dma_channels(this); |
| 678 | exit_dma_channels: | ||
| 679 | release_bch_irq(this); | ||
| 680 | exit_regs: | 635 | exit_regs: |
| 681 | release_register_block(this); | ||
| 682 | return ret; | 636 | return ret; |
| 683 | } | 637 | } |
| 684 | 638 | ||
| 685 | static void release_resources(struct gpmi_nand_data *this) | 639 | static void release_resources(struct gpmi_nand_data *this) |
| 686 | { | 640 | { |
| 687 | gpmi_put_clks(this); | ||
| 688 | release_register_block(this); | ||
| 689 | release_bch_irq(this); | ||
| 690 | release_dma_channels(this); | 641 | release_dma_channels(this); |
| 691 | } | 642 | } |
| 692 | 643 | ||
| @@ -732,8 +683,7 @@ static int read_page_prepare(struct gpmi_nand_data *this, | |||
| 732 | length, DMA_FROM_DEVICE); | 683 | length, DMA_FROM_DEVICE); |
| 733 | if (dma_mapping_error(dev, dest_phys)) { | 684 | if (dma_mapping_error(dev, dest_phys)) { |
| 734 | if (alt_size < length) { | 685 | if (alt_size < length) { |
| 735 | pr_err("%s, Alternate buffer is too small\n", | 686 | dev_err(dev, "Alternate buffer is too small\n"); |
| 736 | __func__); | ||
| 737 | return -ENOMEM; | 687 | return -ENOMEM; |
| 738 | } | 688 | } |
| 739 | goto map_failed; | 689 | goto map_failed; |
| @@ -783,8 +733,7 @@ static int send_page_prepare(struct gpmi_nand_data *this, | |||
| 783 | DMA_TO_DEVICE); | 733 | DMA_TO_DEVICE); |
| 784 | if (dma_mapping_error(dev, source_phys)) { | 734 | if (dma_mapping_error(dev, source_phys)) { |
| 785 | if (alt_size < length) { | 735 | if (alt_size < length) { |
| 786 | pr_err("%s, Alternate buffer is too small\n", | 736 | dev_err(dev, "Alternate buffer is too small\n"); |
| 787 | __func__); | ||
| 788 | return -ENOMEM; | 737 | return -ENOMEM; |
| 789 | } | 738 | } |
| 790 | goto map_failed; | 739 | goto map_failed; |
| @@ -837,14 +786,23 @@ static int gpmi_alloc_dma_buffer(struct gpmi_nand_data *this) | |||
| 837 | { | 786 | { |
| 838 | struct bch_geometry *geo = &this->bch_geometry; | 787 | struct bch_geometry *geo = &this->bch_geometry; |
| 839 | struct device *dev = this->dev; | 788 | struct device *dev = this->dev; |
| 789 | struct mtd_info *mtd = &this->mtd; | ||
| 840 | 790 | ||
| 841 | /* [1] Allocate a command buffer. PAGE_SIZE is enough. */ | 791 | /* [1] Allocate a command buffer. PAGE_SIZE is enough. */ |
| 842 | this->cmd_buffer = kzalloc(PAGE_SIZE, GFP_DMA | GFP_KERNEL); | 792 | this->cmd_buffer = kzalloc(PAGE_SIZE, GFP_DMA | GFP_KERNEL); |
| 843 | if (this->cmd_buffer == NULL) | 793 | if (this->cmd_buffer == NULL) |
| 844 | goto error_alloc; | 794 | goto error_alloc; |
| 845 | 795 | ||
| 846 | /* [2] Allocate a read/write data buffer. PAGE_SIZE is enough. */ | 796 | /* |
| 847 | this->data_buffer_dma = kzalloc(PAGE_SIZE, GFP_DMA | GFP_KERNEL); | 797 | * [2] Allocate a read/write data buffer. |
| 798 | * The gpmi_alloc_dma_buffer can be called twice. | ||
| 799 | * We allocate a PAGE_SIZE length buffer if gpmi_alloc_dma_buffer | ||
| 800 | * is called before the nand_scan_ident; and we allocate a buffer | ||
| 801 | * of the real NAND page size when the gpmi_alloc_dma_buffer is | ||
| 802 | * called after the nand_scan_ident. | ||
| 803 | */ | ||
| 804 | this->data_buffer_dma = kzalloc(mtd->writesize ?: PAGE_SIZE, | ||
| 805 | GFP_DMA | GFP_KERNEL); | ||
| 848 | if (this->data_buffer_dma == NULL) | 806 | if (this->data_buffer_dma == NULL) |
| 849 | goto error_alloc; | 807 | goto error_alloc; |
| 850 | 808 | ||
| @@ -872,7 +830,6 @@ static int gpmi_alloc_dma_buffer(struct gpmi_nand_data *this) | |||
| 872 | 830 | ||
| 873 | error_alloc: | 831 | error_alloc: |
| 874 | gpmi_free_dma_buffer(this); | 832 | gpmi_free_dma_buffer(this); |
| 875 | pr_err("Error allocating DMA buffers!\n"); | ||
| 876 | return -ENOMEM; | 833 | return -ENOMEM; |
| 877 | } | 834 | } |
| 878 | 835 | ||
| @@ -904,7 +861,8 @@ static void gpmi_cmd_ctrl(struct mtd_info *mtd, int data, unsigned int ctrl) | |||
| 904 | 861 | ||
| 905 | ret = gpmi_send_command(this); | 862 | ret = gpmi_send_command(this); |
| 906 | if (ret) | 863 | if (ret) |
| 907 | pr_err("Chip: %u, Error %d\n", this->current_chip, ret); | 864 | dev_err(this->dev, "Chip: %u, Error %d\n", |
| 865 | this->current_chip, ret); | ||
| 908 | 866 | ||
| 909 | this->command_length = 0; | 867 | this->command_length = 0; |
| 910 | } | 868 | } |
| @@ -935,7 +893,7 @@ static void gpmi_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | |||
| 935 | struct nand_chip *chip = mtd->priv; | 893 | struct nand_chip *chip = mtd->priv; |
| 936 | struct gpmi_nand_data *this = chip->priv; | 894 | struct gpmi_nand_data *this = chip->priv; |
| 937 | 895 | ||
| 938 | pr_debug("len is %d\n", len); | 896 | dev_dbg(this->dev, "len is %d\n", len); |
| 939 | this->upper_buf = buf; | 897 | this->upper_buf = buf; |
| 940 | this->upper_len = len; | 898 | this->upper_len = len; |
| 941 | 899 | ||
| @@ -947,7 +905,7 @@ static void gpmi_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | |||
| 947 | struct nand_chip *chip = mtd->priv; | 905 | struct nand_chip *chip = mtd->priv; |
| 948 | struct gpmi_nand_data *this = chip->priv; | 906 | struct gpmi_nand_data *this = chip->priv; |
| 949 | 907 | ||
| 950 | pr_debug("len is %d\n", len); | 908 | dev_dbg(this->dev, "len is %d\n", len); |
| 951 | this->upper_buf = (uint8_t *)buf; | 909 | this->upper_buf = (uint8_t *)buf; |
| 952 | this->upper_len = len; | 910 | this->upper_len = len; |
| 953 | 911 | ||
| @@ -1026,13 +984,13 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 1026 | unsigned int max_bitflips = 0; | 984 | unsigned int max_bitflips = 0; |
| 1027 | int ret; | 985 | int ret; |
| 1028 | 986 | ||
| 1029 | pr_debug("page number is : %d\n", page); | 987 | dev_dbg(this->dev, "page number is : %d\n", page); |
| 1030 | ret = read_page_prepare(this, buf, mtd->writesize, | 988 | ret = read_page_prepare(this, buf, mtd->writesize, |
| 1031 | this->payload_virt, this->payload_phys, | 989 | this->payload_virt, this->payload_phys, |
| 1032 | nfc_geo->payload_size, | 990 | nfc_geo->payload_size, |
| 1033 | &payload_virt, &payload_phys); | 991 | &payload_virt, &payload_phys); |
| 1034 | if (ret) { | 992 | if (ret) { |
| 1035 | pr_err("Inadequate DMA buffer\n"); | 993 | dev_err(this->dev, "Inadequate DMA buffer\n"); |
| 1036 | ret = -ENOMEM; | 994 | ret = -ENOMEM; |
| 1037 | return ret; | 995 | return ret; |
| 1038 | } | 996 | } |
| @@ -1046,7 +1004,7 @@ static int gpmi_ecc_read_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 1046 | nfc_geo->payload_size, | 1004 | nfc_geo->payload_size, |
| 1047 | payload_virt, payload_phys); | 1005 | payload_virt, payload_phys); |
| 1048 | if (ret) { | 1006 | if (ret) { |
| 1049 | pr_err("Error in ECC-based read: %d\n", ret); | 1007 | dev_err(this->dev, "Error in ECC-based read: %d\n", ret); |
| 1050 | return ret; | 1008 | return ret; |
| 1051 | } | 1009 | } |
| 1052 | 1010 | ||
| @@ -1102,7 +1060,7 @@ static int gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 1102 | dma_addr_t auxiliary_phys; | 1060 | dma_addr_t auxiliary_phys; |
| 1103 | int ret; | 1061 | int ret; |
| 1104 | 1062 | ||
| 1105 | pr_debug("ecc write page.\n"); | 1063 | dev_dbg(this->dev, "ecc write page.\n"); |
| 1106 | if (this->swap_block_mark) { | 1064 | if (this->swap_block_mark) { |
| 1107 | /* | 1065 | /* |
| 1108 | * If control arrives here, we're doing block mark swapping. | 1066 | * If control arrives here, we're doing block mark swapping. |
| @@ -1132,7 +1090,7 @@ static int gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 1132 | nfc_geo->payload_size, | 1090 | nfc_geo->payload_size, |
| 1133 | &payload_virt, &payload_phys); | 1091 | &payload_virt, &payload_phys); |
| 1134 | if (ret) { | 1092 | if (ret) { |
| 1135 | pr_err("Inadequate payload DMA buffer\n"); | 1093 | dev_err(this->dev, "Inadequate payload DMA buffer\n"); |
| 1136 | return 0; | 1094 | return 0; |
| 1137 | } | 1095 | } |
| 1138 | 1096 | ||
| @@ -1142,7 +1100,7 @@ static int gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 1142 | nfc_geo->auxiliary_size, | 1100 | nfc_geo->auxiliary_size, |
| 1143 | &auxiliary_virt, &auxiliary_phys); | 1101 | &auxiliary_virt, &auxiliary_phys); |
| 1144 | if (ret) { | 1102 | if (ret) { |
| 1145 | pr_err("Inadequate auxiliary DMA buffer\n"); | 1103 | dev_err(this->dev, "Inadequate auxiliary DMA buffer\n"); |
| 1146 | goto exit_auxiliary; | 1104 | goto exit_auxiliary; |
| 1147 | } | 1105 | } |
| 1148 | } | 1106 | } |
| @@ -1150,7 +1108,7 @@ static int gpmi_ecc_write_page(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 1150 | /* Ask the NFC. */ | 1108 | /* Ask the NFC. */ |
| 1151 | ret = gpmi_send_page(this, payload_phys, auxiliary_phys); | 1109 | ret = gpmi_send_page(this, payload_phys, auxiliary_phys); |
| 1152 | if (ret) | 1110 | if (ret) |
| 1153 | pr_err("Error in ECC-based write: %d\n", ret); | 1111 | dev_err(this->dev, "Error in ECC-based write: %d\n", ret); |
| 1154 | 1112 | ||
| 1155 | if (!this->swap_block_mark) { | 1113 | if (!this->swap_block_mark) { |
| 1156 | send_page_end(this, chip->oob_poi, mtd->oobsize, | 1114 | send_page_end(this, chip->oob_poi, mtd->oobsize, |
| @@ -1240,7 +1198,7 @@ static int gpmi_ecc_read_oob(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 1240 | { | 1198 | { |
| 1241 | struct gpmi_nand_data *this = chip->priv; | 1199 | struct gpmi_nand_data *this = chip->priv; |
| 1242 | 1200 | ||
| 1243 | pr_debug("page number is %d\n", page); | 1201 | dev_dbg(this->dev, "page number is %d\n", page); |
| 1244 | /* clear the OOB buffer */ | 1202 | /* clear the OOB buffer */ |
| 1245 | memset(chip->oob_poi, ~0, mtd->oobsize); | 1203 | memset(chip->oob_poi, ~0, mtd->oobsize); |
| 1246 | 1204 | ||
| @@ -1453,7 +1411,6 @@ static int mx23_write_transcription_stamp(struct gpmi_nand_data *this) | |||
| 1453 | 1411 | ||
| 1454 | /* Write the NCB fingerprint into the page buffer. */ | 1412 | /* Write the NCB fingerprint into the page buffer. */ |
| 1455 | memset(buffer, ~0, mtd->writesize); | 1413 | memset(buffer, ~0, mtd->writesize); |
| 1456 | memset(chip->oob_poi, ~0, mtd->oobsize); | ||
| 1457 | memcpy(buffer + 12, fingerprint, strlen(fingerprint)); | 1414 | memcpy(buffer + 12, fingerprint, strlen(fingerprint)); |
| 1458 | 1415 | ||
| 1459 | /* Loop through the first search area, writing NCB fingerprints. */ | 1416 | /* Loop through the first search area, writing NCB fingerprints. */ |
| @@ -1568,7 +1525,7 @@ static int gpmi_set_geometry(struct gpmi_nand_data *this) | |||
| 1568 | /* Set up the NFC geometry which is used by BCH. */ | 1525 | /* Set up the NFC geometry which is used by BCH. */ |
| 1569 | ret = bch_set_geometry(this); | 1526 | ret = bch_set_geometry(this); |
| 1570 | if (ret) { | 1527 | if (ret) { |
| 1571 | pr_err("Error setting BCH geometry : %d\n", ret); | 1528 | dev_err(this->dev, "Error setting BCH geometry : %d\n", ret); |
| 1572 | return ret; | 1529 | return ret; |
| 1573 | } | 1530 | } |
| 1574 | 1531 | ||
| @@ -1576,20 +1533,7 @@ static int gpmi_set_geometry(struct gpmi_nand_data *this) | |||
| 1576 | return gpmi_alloc_dma_buffer(this); | 1533 | return gpmi_alloc_dma_buffer(this); |
| 1577 | } | 1534 | } |
| 1578 | 1535 | ||
| 1579 | static int gpmi_pre_bbt_scan(struct gpmi_nand_data *this) | 1536 | static void gpmi_nand_exit(struct gpmi_nand_data *this) |
| 1580 | { | ||
| 1581 | /* Set up swap_block_mark, must be set before the gpmi_set_geometry() */ | ||
| 1582 | if (GPMI_IS_MX23(this)) | ||
| 1583 | this->swap_block_mark = false; | ||
| 1584 | else | ||
| 1585 | this->swap_block_mark = true; | ||
| 1586 | |||
| 1587 | /* Set up the medium geometry */ | ||
| 1588 | return gpmi_set_geometry(this); | ||
| 1589 | |||
| 1590 | } | ||
| 1591 | |||
| 1592 | static void gpmi_nfc_exit(struct gpmi_nand_data *this) | ||
| 1593 | { | 1537 | { |
| 1594 | nand_release(&this->mtd); | 1538 | nand_release(&this->mtd); |
| 1595 | gpmi_free_dma_buffer(this); | 1539 | gpmi_free_dma_buffer(this); |
| @@ -1603,8 +1547,11 @@ static int gpmi_init_last(struct gpmi_nand_data *this) | |||
| 1603 | struct bch_geometry *bch_geo = &this->bch_geometry; | 1547 | struct bch_geometry *bch_geo = &this->bch_geometry; |
| 1604 | int ret; | 1548 | int ret; |
| 1605 | 1549 | ||
| 1606 | /* Prepare for the BBT scan. */ | 1550 | /* Set up swap_block_mark, must be set before the gpmi_set_geometry() */ |
| 1607 | ret = gpmi_pre_bbt_scan(this); | 1551 | this->swap_block_mark = !GPMI_IS_MX23(this); |
| 1552 | |||
| 1553 | /* Set up the medium geometry */ | ||
| 1554 | ret = gpmi_set_geometry(this); | ||
| 1608 | if (ret) | 1555 | if (ret) |
| 1609 | return ret; | 1556 | return ret; |
| 1610 | 1557 | ||
| @@ -1629,7 +1576,7 @@ static int gpmi_init_last(struct gpmi_nand_data *this) | |||
| 1629 | return 0; | 1576 | return 0; |
| 1630 | } | 1577 | } |
| 1631 | 1578 | ||
| 1632 | static int gpmi_nfc_init(struct gpmi_nand_data *this) | 1579 | static int gpmi_nand_init(struct gpmi_nand_data *this) |
| 1633 | { | 1580 | { |
| 1634 | struct mtd_info *mtd = &this->mtd; | 1581 | struct mtd_info *mtd = &this->mtd; |
| 1635 | struct nand_chip *chip = &this->nand; | 1582 | struct nand_chip *chip = &this->nand; |
| @@ -1693,7 +1640,7 @@ static int gpmi_nfc_init(struct gpmi_nand_data *this) | |||
| 1693 | return 0; | 1640 | return 0; |
| 1694 | 1641 | ||
| 1695 | err_out: | 1642 | err_out: |
| 1696 | gpmi_nfc_exit(this); | 1643 | gpmi_nand_exit(this); |
| 1697 | return ret; | 1644 | return ret; |
| 1698 | } | 1645 | } |
| 1699 | 1646 | ||
| @@ -1728,15 +1675,13 @@ static int gpmi_nand_probe(struct platform_device *pdev) | |||
| 1728 | if (of_id) { | 1675 | if (of_id) { |
| 1729 | pdev->id_entry = of_id->data; | 1676 | pdev->id_entry = of_id->data; |
| 1730 | } else { | 1677 | } else { |
| 1731 | pr_err("Failed to find the right device id.\n"); | 1678 | dev_err(&pdev->dev, "Failed to find the right device id.\n"); |
| 1732 | return -ENODEV; | 1679 | return -ENODEV; |
| 1733 | } | 1680 | } |
| 1734 | 1681 | ||
| 1735 | this = devm_kzalloc(&pdev->dev, sizeof(*this), GFP_KERNEL); | 1682 | this = devm_kzalloc(&pdev->dev, sizeof(*this), GFP_KERNEL); |
| 1736 | if (!this) { | 1683 | if (!this) |
| 1737 | pr_err("Failed to allocate per-device memory\n"); | ||
| 1738 | return -ENOMEM; | 1684 | return -ENOMEM; |
| 1739 | } | ||
| 1740 | 1685 | ||
| 1741 | platform_set_drvdata(pdev, this); | 1686 | platform_set_drvdata(pdev, this); |
| 1742 | this->pdev = pdev; | 1687 | this->pdev = pdev; |
| @@ -1750,7 +1695,7 @@ static int gpmi_nand_probe(struct platform_device *pdev) | |||
| 1750 | if (ret) | 1695 | if (ret) |
| 1751 | goto exit_nfc_init; | 1696 | goto exit_nfc_init; |
| 1752 | 1697 | ||
| 1753 | ret = gpmi_nfc_init(this); | 1698 | ret = gpmi_nand_init(this); |
| 1754 | if (ret) | 1699 | if (ret) |
| 1755 | goto exit_nfc_init; | 1700 | goto exit_nfc_init; |
| 1756 | 1701 | ||
| @@ -1770,7 +1715,7 @@ static int gpmi_nand_remove(struct platform_device *pdev) | |||
| 1770 | { | 1715 | { |
| 1771 | struct gpmi_nand_data *this = platform_get_drvdata(pdev); | 1716 | struct gpmi_nand_data *this = platform_get_drvdata(pdev); |
| 1772 | 1717 | ||
| 1773 | gpmi_nfc_exit(this); | 1718 | gpmi_nand_exit(this); |
| 1774 | release_resources(this); | 1719 | release_resources(this); |
| 1775 | return 0; | 1720 | return 0; |
| 1776 | } | 1721 | } |
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h index a7685e3a8748..4c801fa18725 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h | |||
| @@ -26,8 +26,6 @@ | |||
| 26 | struct resources { | 26 | struct resources { |
| 27 | void __iomem *gpmi_regs; | 27 | void __iomem *gpmi_regs; |
| 28 | void __iomem *bch_regs; | 28 | void __iomem *bch_regs; |
| 29 | unsigned int bch_low_interrupt; | ||
| 30 | unsigned int bch_high_interrupt; | ||
| 31 | unsigned int dma_low_channel; | 29 | unsigned int dma_low_channel; |
| 32 | unsigned int dma_high_channel; | 30 | unsigned int dma_high_channel; |
| 33 | struct clk *clock[GPMI_CLK_MAX]; | 31 | struct clk *clock[GPMI_CLK_MAX]; |
diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c index a264b888c66c..a2c804de156b 100644 --- a/drivers/mtd/nand/jz4740_nand.c +++ b/drivers/mtd/nand/jz4740_nand.c | |||
| @@ -416,10 +416,8 @@ static int jz_nand_probe(struct platform_device *pdev) | |||
| 416 | uint8_t nand_maf_id = 0, nand_dev_id = 0; | 416 | uint8_t nand_maf_id = 0, nand_dev_id = 0; |
| 417 | 417 | ||
| 418 | nand = kzalloc(sizeof(*nand), GFP_KERNEL); | 418 | nand = kzalloc(sizeof(*nand), GFP_KERNEL); |
| 419 | if (!nand) { | 419 | if (!nand) |
| 420 | dev_err(&pdev->dev, "Failed to allocate device structure.\n"); | ||
| 421 | return -ENOMEM; | 420 | return -ENOMEM; |
| 422 | } | ||
| 423 | 421 | ||
| 424 | ret = jz_nand_ioremap_resource(pdev, "mmio", &nand->mem, &nand->base); | 422 | ret = jz_nand_ioremap_resource(pdev, "mmio", &nand->mem, &nand->base); |
| 425 | if (ret) | 423 | if (ret) |
diff --git a/drivers/mtd/nand/lpc32xx_mlc.c b/drivers/mtd/nand/lpc32xx_mlc.c index 327d96c03505..687478c9f09c 100644 --- a/drivers/mtd/nand/lpc32xx_mlc.c +++ b/drivers/mtd/nand/lpc32xx_mlc.c | |||
| @@ -539,20 +539,6 @@ static int lpc32xx_write_page_lowlevel(struct mtd_info *mtd, | |||
| 539 | return 0; | 539 | return 0; |
| 540 | } | 540 | } |
| 541 | 541 | ||
| 542 | static int lpc32xx_write_page(struct mtd_info *mtd, struct nand_chip *chip, | ||
| 543 | uint32_t offset, int data_len, const uint8_t *buf, | ||
| 544 | int oob_required, int page, int cached, int raw) | ||
| 545 | { | ||
| 546 | int res; | ||
| 547 | |||
| 548 | chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page); | ||
| 549 | res = lpc32xx_write_page_lowlevel(mtd, chip, buf, oob_required); | ||
| 550 | chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); | ||
| 551 | lpc32xx_waitfunc(mtd, chip); | ||
| 552 | |||
| 553 | return res; | ||
| 554 | } | ||
| 555 | |||
| 556 | static int lpc32xx_read_oob(struct mtd_info *mtd, struct nand_chip *chip, | 542 | static int lpc32xx_read_oob(struct mtd_info *mtd, struct nand_chip *chip, |
| 557 | int page) | 543 | int page) |
| 558 | { | 544 | { |
| @@ -627,10 +613,8 @@ static struct lpc32xx_nand_cfg_mlc *lpc32xx_parse_dt(struct device *dev) | |||
| 627 | struct device_node *np = dev->of_node; | 613 | struct device_node *np = dev->of_node; |
| 628 | 614 | ||
| 629 | ncfg = devm_kzalloc(dev, sizeof(*ncfg), GFP_KERNEL); | 615 | ncfg = devm_kzalloc(dev, sizeof(*ncfg), GFP_KERNEL); |
| 630 | if (!ncfg) { | 616 | if (!ncfg) |
| 631 | dev_err(dev, "could not allocate memory for platform data\n"); | ||
| 632 | return NULL; | 617 | return NULL; |
| 633 | } | ||
| 634 | 618 | ||
| 635 | of_property_read_u32(np, "nxp,tcea-delay", &ncfg->tcea_delay); | 619 | of_property_read_u32(np, "nxp,tcea-delay", &ncfg->tcea_delay); |
| 636 | of_property_read_u32(np, "nxp,busy-delay", &ncfg->busy_delay); | 620 | of_property_read_u32(np, "nxp,busy-delay", &ncfg->busy_delay); |
| @@ -666,10 +650,8 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
| 666 | 650 | ||
| 667 | /* Allocate memory for the device structure (and zero it) */ | 651 | /* Allocate memory for the device structure (and zero it) */ |
| 668 | host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); | 652 | host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); |
| 669 | if (!host) { | 653 | if (!host) |
| 670 | dev_err(&pdev->dev, "failed to allocate device structure.\n"); | ||
| 671 | return -ENOMEM; | 654 | return -ENOMEM; |
| 672 | } | ||
| 673 | 655 | ||
| 674 | rc = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 656 | rc = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 675 | host->io_base = devm_ioremap_resource(&pdev->dev, rc); | 657 | host->io_base = devm_ioremap_resource(&pdev->dev, rc); |
| @@ -732,9 +714,9 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
| 732 | nand_chip->ecc.write_oob = lpc32xx_write_oob; | 714 | nand_chip->ecc.write_oob = lpc32xx_write_oob; |
| 733 | nand_chip->ecc.read_oob = lpc32xx_read_oob; | 715 | nand_chip->ecc.read_oob = lpc32xx_read_oob; |
| 734 | nand_chip->ecc.strength = 4; | 716 | nand_chip->ecc.strength = 4; |
| 735 | nand_chip->write_page = lpc32xx_write_page; | ||
| 736 | nand_chip->waitfunc = lpc32xx_waitfunc; | 717 | nand_chip->waitfunc = lpc32xx_waitfunc; |
| 737 | 718 | ||
| 719 | nand_chip->options = NAND_NO_SUBPAGE_WRITE; | ||
| 738 | nand_chip->bbt_options = NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB; | 720 | nand_chip->bbt_options = NAND_BBT_USE_FLASH | NAND_BBT_NO_OOB; |
| 739 | nand_chip->bbt_td = &lpc32xx_nand_bbt; | 721 | nand_chip->bbt_td = &lpc32xx_nand_bbt; |
| 740 | nand_chip->bbt_md = &lpc32xx_nand_bbt_mirror; | 722 | nand_chip->bbt_md = &lpc32xx_nand_bbt_mirror; |
| @@ -764,14 +746,12 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
| 764 | 746 | ||
| 765 | host->dma_buf = devm_kzalloc(&pdev->dev, mtd->writesize, GFP_KERNEL); | 747 | host->dma_buf = devm_kzalloc(&pdev->dev, mtd->writesize, GFP_KERNEL); |
| 766 | if (!host->dma_buf) { | 748 | if (!host->dma_buf) { |
| 767 | dev_err(&pdev->dev, "Error allocating dma_buf memory\n"); | ||
| 768 | res = -ENOMEM; | 749 | res = -ENOMEM; |
| 769 | goto err_exit3; | 750 | goto err_exit3; |
| 770 | } | 751 | } |
| 771 | 752 | ||
| 772 | host->dummy_buf = devm_kzalloc(&pdev->dev, mtd->writesize, GFP_KERNEL); | 753 | host->dummy_buf = devm_kzalloc(&pdev->dev, mtd->writesize, GFP_KERNEL); |
| 773 | if (!host->dummy_buf) { | 754 | if (!host->dummy_buf) { |
| 774 | dev_err(&pdev->dev, "Error allocating dummy_buf memory\n"); | ||
| 775 | res = -ENOMEM; | 755 | res = -ENOMEM; |
| 776 | goto err_exit3; | 756 | goto err_exit3; |
| 777 | } | 757 | } |
diff --git a/drivers/mtd/nand/lpc32xx_slc.c b/drivers/mtd/nand/lpc32xx_slc.c index 23e6974ccd20..53a6742e3da3 100644 --- a/drivers/mtd/nand/lpc32xx_slc.c +++ b/drivers/mtd/nand/lpc32xx_slc.c | |||
| @@ -725,10 +725,8 @@ static struct lpc32xx_nand_cfg_slc *lpc32xx_parse_dt(struct device *dev) | |||
| 725 | struct device_node *np = dev->of_node; | 725 | struct device_node *np = dev->of_node; |
| 726 | 726 | ||
| 727 | ncfg = devm_kzalloc(dev, sizeof(*ncfg), GFP_KERNEL); | 727 | ncfg = devm_kzalloc(dev, sizeof(*ncfg), GFP_KERNEL); |
| 728 | if (!ncfg) { | 728 | if (!ncfg) |
| 729 | dev_err(dev, "could not allocate memory for NAND config\n"); | ||
| 730 | return NULL; | 729 | return NULL; |
| 731 | } | ||
| 732 | 730 | ||
| 733 | of_property_read_u32(np, "nxp,wdr-clks", &ncfg->wdr_clks); | 731 | of_property_read_u32(np, "nxp,wdr-clks", &ncfg->wdr_clks); |
| 734 | of_property_read_u32(np, "nxp,wwidth", &ncfg->wwidth); | 732 | of_property_read_u32(np, "nxp,wwidth", &ncfg->wwidth); |
| @@ -772,10 +770,8 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
| 772 | 770 | ||
| 773 | /* Allocate memory for the device structure (and zero it) */ | 771 | /* Allocate memory for the device structure (and zero it) */ |
| 774 | host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); | 772 | host = devm_kzalloc(&pdev->dev, sizeof(*host), GFP_KERNEL); |
| 775 | if (!host) { | 773 | if (!host) |
| 776 | dev_err(&pdev->dev, "failed to allocate device structure\n"); | ||
| 777 | return -ENOMEM; | 774 | return -ENOMEM; |
| 778 | } | ||
| 779 | host->io_base_dma = rc->start; | 775 | host->io_base_dma = rc->start; |
| 780 | 776 | ||
| 781 | host->io_base = devm_ioremap_resource(&pdev->dev, rc); | 777 | host->io_base = devm_ioremap_resource(&pdev->dev, rc); |
| @@ -791,8 +787,8 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
| 791 | } | 787 | } |
| 792 | if (host->ncfg->wp_gpio == -EPROBE_DEFER) | 788 | if (host->ncfg->wp_gpio == -EPROBE_DEFER) |
| 793 | return -EPROBE_DEFER; | 789 | return -EPROBE_DEFER; |
| 794 | if (gpio_is_valid(host->ncfg->wp_gpio) && | 790 | if (gpio_is_valid(host->ncfg->wp_gpio) && devm_gpio_request(&pdev->dev, |
| 795 | gpio_request(host->ncfg->wp_gpio, "NAND WP")) { | 791 | host->ncfg->wp_gpio, "NAND WP")) { |
| 796 | dev_err(&pdev->dev, "GPIO not available\n"); | 792 | dev_err(&pdev->dev, "GPIO not available\n"); |
| 797 | return -EBUSY; | 793 | return -EBUSY; |
| 798 | } | 794 | } |
| @@ -808,7 +804,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
| 808 | mtd->dev.parent = &pdev->dev; | 804 | mtd->dev.parent = &pdev->dev; |
| 809 | 805 | ||
| 810 | /* Get NAND clock */ | 806 | /* Get NAND clock */ |
| 811 | host->clk = clk_get(&pdev->dev, NULL); | 807 | host->clk = devm_clk_get(&pdev->dev, NULL); |
| 812 | if (IS_ERR(host->clk)) { | 808 | if (IS_ERR(host->clk)) { |
| 813 | dev_err(&pdev->dev, "Clock failure\n"); | 809 | dev_err(&pdev->dev, "Clock failure\n"); |
| 814 | res = -ENOENT; | 810 | res = -ENOENT; |
| @@ -858,7 +854,6 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) | |||
| 858 | host->data_buf = devm_kzalloc(&pdev->dev, host->dma_buf_len, | 854 | host->data_buf = devm_kzalloc(&pdev->dev, host->dma_buf_len, |
| 859 | GFP_KERNEL); | 855 | GFP_KERNEL); |
| 860 | if (host->data_buf == NULL) { | 856 | if (host->data_buf == NULL) { |
| 861 | dev_err(&pdev->dev, "Error allocating memory\n"); | ||
| 862 | res = -ENOMEM; | 857 | res = -ENOMEM; |
| 863 | goto err_exit2; | 858 | goto err_exit2; |
| 864 | } | 859 | } |
| @@ -927,10 +922,8 @@ err_exit3: | |||
| 927 | dma_release_channel(host->dma_chan); | 922 | dma_release_channel(host->dma_chan); |
| 928 | err_exit2: | 923 | err_exit2: |
| 929 | clk_disable(host->clk); | 924 | clk_disable(host->clk); |
| 930 | clk_put(host->clk); | ||
| 931 | err_exit1: | 925 | err_exit1: |
| 932 | lpc32xx_wp_enable(host); | 926 | lpc32xx_wp_enable(host); |
| 933 | gpio_free(host->ncfg->wp_gpio); | ||
| 934 | 927 | ||
| 935 | return res; | 928 | return res; |
| 936 | } | 929 | } |
| @@ -953,9 +946,7 @@ static int lpc32xx_nand_remove(struct platform_device *pdev) | |||
| 953 | writel(tmp, SLC_CTRL(host->io_base)); | 946 | writel(tmp, SLC_CTRL(host->io_base)); |
| 954 | 947 | ||
| 955 | clk_disable(host->clk); | 948 | clk_disable(host->clk); |
| 956 | clk_put(host->clk); | ||
| 957 | lpc32xx_wp_enable(host); | 949 | lpc32xx_wp_enable(host); |
| 958 | gpio_free(host->ncfg->wp_gpio); | ||
| 959 | 950 | ||
| 960 | return 0; | 951 | return 0; |
| 961 | } | 952 | } |
diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c index 439bc3896418..61e2abc216ad 100644 --- a/drivers/mtd/nand/mpc5121_nfc.c +++ b/drivers/mtd/nand/mpc5121_nfc.c | |||
| @@ -653,10 +653,8 @@ static int mpc5121_nfc_probe(struct platform_device *op) | |||
| 653 | } | 653 | } |
| 654 | 654 | ||
| 655 | prv = devm_kzalloc(dev, sizeof(*prv), GFP_KERNEL); | 655 | prv = devm_kzalloc(dev, sizeof(*prv), GFP_KERNEL); |
| 656 | if (!prv) { | 656 | if (!prv) |
| 657 | dev_err(dev, "Memory exhausted!\n"); | ||
| 658 | return -ENOMEM; | 657 | return -ENOMEM; |
| 659 | } | ||
| 660 | 658 | ||
| 661 | mtd = &prv->mtd; | 659 | mtd = &prv->mtd; |
| 662 | chip = &prv->chip; | 660 | chip = &prv->chip; |
| @@ -786,7 +784,6 @@ static int mpc5121_nfc_probe(struct platform_device *op) | |||
| 786 | /* Detect NAND chips */ | 784 | /* Detect NAND chips */ |
| 787 | if (nand_scan(mtd, be32_to_cpup(chips_no))) { | 785 | if (nand_scan(mtd, be32_to_cpup(chips_no))) { |
| 788 | dev_err(dev, "NAND Flash not found !\n"); | 786 | dev_err(dev, "NAND Flash not found !\n"); |
| 789 | devm_free_irq(dev, prv->irq, mtd); | ||
| 790 | retval = -ENXIO; | 787 | retval = -ENXIO; |
| 791 | goto error; | 788 | goto error; |
| 792 | } | 789 | } |
| @@ -811,7 +808,6 @@ static int mpc5121_nfc_probe(struct platform_device *op) | |||
| 811 | 808 | ||
| 812 | default: | 809 | default: |
| 813 | dev_err(dev, "Unsupported NAND flash!\n"); | 810 | dev_err(dev, "Unsupported NAND flash!\n"); |
| 814 | devm_free_irq(dev, prv->irq, mtd); | ||
| 815 | retval = -ENXIO; | 811 | retval = -ENXIO; |
| 816 | goto error; | 812 | goto error; |
| 817 | } | 813 | } |
| @@ -822,7 +818,6 @@ static int mpc5121_nfc_probe(struct platform_device *op) | |||
| 822 | retval = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); | 818 | retval = mtd_device_parse_register(mtd, NULL, &ppdata, NULL, 0); |
| 823 | if (retval) { | 819 | if (retval) { |
| 824 | dev_err(dev, "Error adding MTD device!\n"); | 820 | dev_err(dev, "Error adding MTD device!\n"); |
| 825 | devm_free_irq(dev, prv->irq, mtd); | ||
| 826 | goto error; | 821 | goto error; |
| 827 | } | 822 | } |
| 828 | 823 | ||
| @@ -836,11 +831,8 @@ static int mpc5121_nfc_remove(struct platform_device *op) | |||
| 836 | { | 831 | { |
| 837 | struct device *dev = &op->dev; | 832 | struct device *dev = &op->dev; |
| 838 | struct mtd_info *mtd = dev_get_drvdata(dev); | 833 | struct mtd_info *mtd = dev_get_drvdata(dev); |
| 839 | struct nand_chip *chip = mtd->priv; | ||
| 840 | struct mpc5121_nfc_prv *prv = chip->priv; | ||
| 841 | 834 | ||
| 842 | nand_release(mtd); | 835 | nand_release(mtd); |
| 843 | devm_free_irq(dev, prv->irq, mtd); | ||
| 844 | mpc5121_nfc_free(dev, mtd); | 836 | mpc5121_nfc_free(dev, mtd); |
| 845 | 837 | ||
| 846 | return 0; | 838 | return 0; |
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 9dfdb06c508b..e9a4835c4dd9 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c | |||
| @@ -677,7 +677,6 @@ static int mxc_nand_correct_data_v2_v3(struct mtd_info *mtd, u_char *dat, | |||
| 677 | ecc_stat >>= 4; | 677 | ecc_stat >>= 4; |
| 678 | } while (--no_subpages); | 678 | } while (--no_subpages); |
| 679 | 679 | ||
| 680 | mtd->ecc_stats.corrected += ret; | ||
| 681 | pr_debug("%d Symbol Correctable RS-ECC Error\n", ret); | 680 | pr_debug("%d Symbol Correctable RS-ECC Error\n", ret); |
| 682 | 681 | ||
| 683 | return ret; | 682 | return ret; |
| @@ -1400,12 +1399,15 @@ static int mxcnd_probe(struct platform_device *pdev) | |||
| 1400 | int err = 0; | 1399 | int err = 0; |
| 1401 | 1400 | ||
| 1402 | /* Allocate memory for MTD device structure and private data */ | 1401 | /* Allocate memory for MTD device structure and private data */ |
| 1403 | host = devm_kzalloc(&pdev->dev, sizeof(struct mxc_nand_host) + | 1402 | host = devm_kzalloc(&pdev->dev, sizeof(struct mxc_nand_host), |
| 1404 | NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE, GFP_KERNEL); | 1403 | GFP_KERNEL); |
| 1405 | if (!host) | 1404 | if (!host) |
| 1406 | return -ENOMEM; | 1405 | return -ENOMEM; |
| 1407 | 1406 | ||
| 1408 | host->data_buf = (uint8_t *)(host + 1); | 1407 | /* allocate a temporary buffer for the nand_scan_ident() */ |
| 1408 | host->data_buf = devm_kzalloc(&pdev->dev, PAGE_SIZE, GFP_KERNEL); | ||
| 1409 | if (!host->data_buf) | ||
| 1410 | return -ENOMEM; | ||
| 1409 | 1411 | ||
| 1410 | host->dev = &pdev->dev; | 1412 | host->dev = &pdev->dev; |
| 1411 | /* structures must be linked */ | 1413 | /* structures must be linked */ |
| @@ -1512,7 +1514,9 @@ static int mxcnd_probe(struct platform_device *pdev) | |||
| 1512 | if (err) | 1514 | if (err) |
| 1513 | return err; | 1515 | return err; |
| 1514 | 1516 | ||
| 1515 | clk_prepare_enable(host->clk); | 1517 | err = clk_prepare_enable(host->clk); |
| 1518 | if (err) | ||
| 1519 | return err; | ||
| 1516 | host->clk_act = 1; | 1520 | host->clk_act = 1; |
| 1517 | 1521 | ||
| 1518 | /* | 1522 | /* |
| @@ -1531,6 +1535,15 @@ static int mxcnd_probe(struct platform_device *pdev) | |||
| 1531 | goto escan; | 1535 | goto escan; |
| 1532 | } | 1536 | } |
| 1533 | 1537 | ||
| 1538 | /* allocate the right size buffer now */ | ||
| 1539 | devm_kfree(&pdev->dev, (void *)host->data_buf); | ||
| 1540 | host->data_buf = devm_kzalloc(&pdev->dev, mtd->writesize + mtd->oobsize, | ||
| 1541 | GFP_KERNEL); | ||
| 1542 | if (!host->data_buf) { | ||
| 1543 | err = -ENOMEM; | ||
| 1544 | goto escan; | ||
| 1545 | } | ||
| 1546 | |||
| 1534 | /* Call preset again, with correct writesize this time */ | 1547 | /* Call preset again, with correct writesize this time */ |
| 1535 | host->devtype_data->preset(mtd); | 1548 | host->devtype_data->preset(mtd); |
| 1536 | 1549 | ||
| @@ -1576,6 +1589,8 @@ static int mxcnd_remove(struct platform_device *pdev) | |||
| 1576 | struct mxc_nand_host *host = platform_get_drvdata(pdev); | 1589 | struct mxc_nand_host *host = platform_get_drvdata(pdev); |
| 1577 | 1590 | ||
| 1578 | nand_release(&host->mtd); | 1591 | nand_release(&host->mtd); |
| 1592 | if (host->clk_act) | ||
| 1593 | clk_disable_unprepare(host->clk); | ||
| 1579 | 1594 | ||
| 1580 | return 0; | 1595 | return 0; |
| 1581 | } | 1596 | } |
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index bd39f7b67906..59eba5d2c685 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
| @@ -29,6 +29,8 @@ | |||
| 29 | * | 29 | * |
| 30 | */ | 30 | */ |
| 31 | 31 | ||
| 32 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 33 | |||
| 32 | #include <linux/module.h> | 34 | #include <linux/module.h> |
| 33 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
| 34 | #include <linux/errno.h> | 36 | #include <linux/errno.h> |
| @@ -202,6 +204,51 @@ static void nand_select_chip(struct mtd_info *mtd, int chipnr) | |||
| 202 | } | 204 | } |
| 203 | 205 | ||
| 204 | /** | 206 | /** |
| 207 | * nand_write_byte - [DEFAULT] write single byte to chip | ||
| 208 | * @mtd: MTD device structure | ||
| 209 | * @byte: value to write | ||
| 210 | * | ||
| 211 | * Default function to write a byte to I/O[7:0] | ||
| 212 | */ | ||
| 213 | static void nand_write_byte(struct mtd_info *mtd, uint8_t byte) | ||
| 214 | { | ||
| 215 | struct nand_chip *chip = mtd->priv; | ||
| 216 | |||
| 217 | chip->write_buf(mtd, &byte, 1); | ||
| 218 | } | ||
| 219 | |||
| 220 | /** | ||
| 221 | * nand_write_byte16 - [DEFAULT] write single byte to a chip with width 16 | ||
| 222 | * @mtd: MTD device structure | ||
| 223 | * @byte: value to write | ||
| 224 | * | ||
| 225 | * Default function to write a byte to I/O[7:0] on a 16-bit wide chip. | ||
| 226 | */ | ||
| 227 | static void nand_write_byte16(struct mtd_info *mtd, uint8_t byte) | ||
| 228 | { | ||
| 229 | struct nand_chip *chip = mtd->priv; | ||
| 230 | uint16_t word = byte; | ||
| 231 | |||
| 232 | /* | ||
| 233 | * It's not entirely clear what should happen to I/O[15:8] when writing | ||
| 234 | * a byte. The ONFi spec (Revision 3.1; 2012-09-19, Section 2.16) reads: | ||
| 235 | * | ||
| 236 | * When the host supports a 16-bit bus width, only data is | ||
| 237 | * transferred at the 16-bit width. All address and command line | ||
| 238 | * transfers shall use only the lower 8-bits of the data bus. During | ||
| 239 | * command transfers, the host may place any value on the upper | ||
| 240 | * 8-bits of the data bus. During address transfers, the host shall | ||
| 241 | * set the upper 8-bits of the data bus to 00h. | ||
| 242 | * | ||
| 243 | * One user of the write_byte callback is nand_onfi_set_features. The | ||
| 244 | * four parameters are specified to be written to I/O[7:0], but this is | ||
| 245 | * neither an address nor a command transfer. Let's assume a 0 on the | ||
| 246 | * upper I/O lines is OK. | ||
| 247 | */ | ||
| 248 | chip->write_buf(mtd, (uint8_t *)&word, 2); | ||
| 249 | } | ||
| 250 | |||
| 251 | /** | ||
| 205 | * nand_write_buf - [DEFAULT] write buffer to chip | 252 | * nand_write_buf - [DEFAULT] write buffer to chip |
| 206 | * @mtd: MTD device structure | 253 | * @mtd: MTD device structure |
| 207 | * @buf: data buffer | 254 | * @buf: data buffer |
| @@ -1408,6 +1455,30 @@ static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob, | |||
| 1408 | } | 1455 | } |
| 1409 | 1456 | ||
| 1410 | /** | 1457 | /** |
| 1458 | * nand_setup_read_retry - [INTERN] Set the READ RETRY mode | ||
| 1459 | * @mtd: MTD device structure | ||
| 1460 | * @retry_mode: the retry mode to use | ||
| 1461 | * | ||
| 1462 | * Some vendors supply a special command to shift the Vt threshold, to be used | ||
| 1463 | * when there are too many bitflips in a page (i.e., ECC error). After setting | ||
| 1464 | * a new threshold, the host should retry reading the page. | ||
| 1465 | */ | ||
| 1466 | static int nand_setup_read_retry(struct mtd_info *mtd, int retry_mode) | ||
| 1467 | { | ||
| 1468 | struct nand_chip *chip = mtd->priv; | ||
| 1469 | |||
| 1470 | pr_debug("setting READ RETRY mode %d\n", retry_mode); | ||
| 1471 | |||
| 1472 | if (retry_mode >= chip->read_retries) | ||
| 1473 | return -EINVAL; | ||
| 1474 | |||
| 1475 | if (!chip->setup_read_retry) | ||
| 1476 | return -EOPNOTSUPP; | ||
| 1477 | |||
| 1478 | return chip->setup_read_retry(mtd, retry_mode); | ||
| 1479 | } | ||
| 1480 | |||
| 1481 | /** | ||
| 1411 | * nand_do_read_ops - [INTERN] Read data with ECC | 1482 | * nand_do_read_ops - [INTERN] Read data with ECC |
| 1412 | * @mtd: MTD device structure | 1483 | * @mtd: MTD device structure |
| 1413 | * @from: offset to read from | 1484 | * @from: offset to read from |
| @@ -1420,7 +1491,6 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
| 1420 | { | 1491 | { |
| 1421 | int chipnr, page, realpage, col, bytes, aligned, oob_required; | 1492 | int chipnr, page, realpage, col, bytes, aligned, oob_required; |
| 1422 | struct nand_chip *chip = mtd->priv; | 1493 | struct nand_chip *chip = mtd->priv; |
| 1423 | struct mtd_ecc_stats stats; | ||
| 1424 | int ret = 0; | 1494 | int ret = 0; |
| 1425 | uint32_t readlen = ops->len; | 1495 | uint32_t readlen = ops->len; |
| 1426 | uint32_t oobreadlen = ops->ooblen; | 1496 | uint32_t oobreadlen = ops->ooblen; |
| @@ -1429,8 +1499,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
| 1429 | 1499 | ||
| 1430 | uint8_t *bufpoi, *oob, *buf; | 1500 | uint8_t *bufpoi, *oob, *buf; |
| 1431 | unsigned int max_bitflips = 0; | 1501 | unsigned int max_bitflips = 0; |
| 1432 | 1502 | int retry_mode = 0; | |
| 1433 | stats = mtd->ecc_stats; | 1503 | bool ecc_fail = false; |
| 1434 | 1504 | ||
| 1435 | chipnr = (int)(from >> chip->chip_shift); | 1505 | chipnr = (int)(from >> chip->chip_shift); |
| 1436 | chip->select_chip(mtd, chipnr); | 1506 | chip->select_chip(mtd, chipnr); |
| @@ -1445,6 +1515,8 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
| 1445 | oob_required = oob ? 1 : 0; | 1515 | oob_required = oob ? 1 : 0; |
| 1446 | 1516 | ||
| 1447 | while (1) { | 1517 | while (1) { |
| 1518 | unsigned int ecc_failures = mtd->ecc_stats.failed; | ||
| 1519 | |||
| 1448 | bytes = min(mtd->writesize - col, readlen); | 1520 | bytes = min(mtd->writesize - col, readlen); |
| 1449 | aligned = (bytes == mtd->writesize); | 1521 | aligned = (bytes == mtd->writesize); |
| 1450 | 1522 | ||
| @@ -1452,6 +1524,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
| 1452 | if (realpage != chip->pagebuf || oob) { | 1524 | if (realpage != chip->pagebuf || oob) { |
| 1453 | bufpoi = aligned ? buf : chip->buffers->databuf; | 1525 | bufpoi = aligned ? buf : chip->buffers->databuf; |
| 1454 | 1526 | ||
| 1527 | read_retry: | ||
| 1455 | chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); | 1528 | chip->cmdfunc(mtd, NAND_CMD_READ0, 0x00, page); |
| 1456 | 1529 | ||
| 1457 | /* | 1530 | /* |
| @@ -1481,7 +1554,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
| 1481 | /* Transfer not aligned data */ | 1554 | /* Transfer not aligned data */ |
| 1482 | if (!aligned) { | 1555 | if (!aligned) { |
| 1483 | if (!NAND_HAS_SUBPAGE_READ(chip) && !oob && | 1556 | if (!NAND_HAS_SUBPAGE_READ(chip) && !oob && |
| 1484 | !(mtd->ecc_stats.failed - stats.failed) && | 1557 | !(mtd->ecc_stats.failed - ecc_failures) && |
| 1485 | (ops->mode != MTD_OPS_RAW)) { | 1558 | (ops->mode != MTD_OPS_RAW)) { |
| 1486 | chip->pagebuf = realpage; | 1559 | chip->pagebuf = realpage; |
| 1487 | chip->pagebuf_bitflips = ret; | 1560 | chip->pagebuf_bitflips = ret; |
| @@ -1492,8 +1565,6 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
| 1492 | memcpy(buf, chip->buffers->databuf + col, bytes); | 1565 | memcpy(buf, chip->buffers->databuf + col, bytes); |
| 1493 | } | 1566 | } |
| 1494 | 1567 | ||
| 1495 | buf += bytes; | ||
| 1496 | |||
| 1497 | if (unlikely(oob)) { | 1568 | if (unlikely(oob)) { |
| 1498 | int toread = min(oobreadlen, max_oobsize); | 1569 | int toread = min(oobreadlen, max_oobsize); |
| 1499 | 1570 | ||
| @@ -1511,6 +1582,25 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
| 1511 | else | 1582 | else |
| 1512 | nand_wait_ready(mtd); | 1583 | nand_wait_ready(mtd); |
| 1513 | } | 1584 | } |
| 1585 | |||
| 1586 | if (mtd->ecc_stats.failed - ecc_failures) { | ||
| 1587 | if (retry_mode + 1 <= chip->read_retries) { | ||
| 1588 | retry_mode++; | ||
| 1589 | ret = nand_setup_read_retry(mtd, | ||
| 1590 | retry_mode); | ||
| 1591 | if (ret < 0) | ||
| 1592 | break; | ||
| 1593 | |||
| 1594 | /* Reset failures; retry */ | ||
| 1595 | mtd->ecc_stats.failed = ecc_failures; | ||
| 1596 | goto read_retry; | ||
| 1597 | } else { | ||
| 1598 | /* No more retry modes; real failure */ | ||
| 1599 | ecc_fail = true; | ||
| 1600 | } | ||
| 1601 | } | ||
| 1602 | |||
| 1603 | buf += bytes; | ||
| 1514 | } else { | 1604 | } else { |
| 1515 | memcpy(buf, chip->buffers->databuf + col, bytes); | 1605 | memcpy(buf, chip->buffers->databuf + col, bytes); |
| 1516 | buf += bytes; | 1606 | buf += bytes; |
| @@ -1520,6 +1610,14 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
| 1520 | 1610 | ||
| 1521 | readlen -= bytes; | 1611 | readlen -= bytes; |
| 1522 | 1612 | ||
| 1613 | /* Reset to retry mode 0 */ | ||
| 1614 | if (retry_mode) { | ||
| 1615 | ret = nand_setup_read_retry(mtd, 0); | ||
| 1616 | if (ret < 0) | ||
| 1617 | break; | ||
| 1618 | retry_mode = 0; | ||
| 1619 | } | ||
| 1620 | |||
| 1523 | if (!readlen) | 1621 | if (!readlen) |
| 1524 | break; | 1622 | break; |
| 1525 | 1623 | ||
| @@ -1545,7 +1643,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
| 1545 | if (ret < 0) | 1643 | if (ret < 0) |
| 1546 | return ret; | 1644 | return ret; |
| 1547 | 1645 | ||
| 1548 | if (mtd->ecc_stats.failed - stats.failed) | 1646 | if (ecc_fail) |
| 1549 | return -EBADMSG; | 1647 | return -EBADMSG; |
| 1550 | 1648 | ||
| 1551 | return max_bitflips; | 1649 | return max_bitflips; |
| @@ -2716,6 +2814,7 @@ static int nand_onfi_set_features(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 2716 | int addr, uint8_t *subfeature_param) | 2814 | int addr, uint8_t *subfeature_param) |
| 2717 | { | 2815 | { |
| 2718 | int status; | 2816 | int status; |
| 2817 | int i; | ||
| 2719 | 2818 | ||
| 2720 | if (!chip->onfi_version || | 2819 | if (!chip->onfi_version || |
| 2721 | !(le16_to_cpu(chip->onfi_params.opt_cmd) | 2820 | !(le16_to_cpu(chip->onfi_params.opt_cmd) |
| @@ -2723,7 +2822,9 @@ static int nand_onfi_set_features(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 2723 | return -EINVAL; | 2822 | return -EINVAL; |
| 2724 | 2823 | ||
| 2725 | chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES, addr, -1); | 2824 | chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES, addr, -1); |
| 2726 | chip->write_buf(mtd, subfeature_param, ONFI_SUBFEATURE_PARAM_LEN); | 2825 | for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i) |
| 2826 | chip->write_byte(mtd, subfeature_param[i]); | ||
| 2827 | |||
| 2727 | status = chip->waitfunc(mtd, chip); | 2828 | status = chip->waitfunc(mtd, chip); |
| 2728 | if (status & NAND_STATUS_FAIL) | 2829 | if (status & NAND_STATUS_FAIL) |
| 2729 | return -EIO; | 2830 | return -EIO; |
| @@ -2740,6 +2841,8 @@ static int nand_onfi_set_features(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 2740 | static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip, | 2841 | static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip, |
| 2741 | int addr, uint8_t *subfeature_param) | 2842 | int addr, uint8_t *subfeature_param) |
| 2742 | { | 2843 | { |
| 2844 | int i; | ||
| 2845 | |||
| 2743 | if (!chip->onfi_version || | 2846 | if (!chip->onfi_version || |
| 2744 | !(le16_to_cpu(chip->onfi_params.opt_cmd) | 2847 | !(le16_to_cpu(chip->onfi_params.opt_cmd) |
| 2745 | & ONFI_OPT_CMD_SET_GET_FEATURES)) | 2848 | & ONFI_OPT_CMD_SET_GET_FEATURES)) |
| @@ -2749,7 +2852,8 @@ static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 2749 | memset(subfeature_param, 0, ONFI_SUBFEATURE_PARAM_LEN); | 2852 | memset(subfeature_param, 0, ONFI_SUBFEATURE_PARAM_LEN); |
| 2750 | 2853 | ||
| 2751 | chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES, addr, -1); | 2854 | chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES, addr, -1); |
| 2752 | chip->read_buf(mtd, subfeature_param, ONFI_SUBFEATURE_PARAM_LEN); | 2855 | for (i = 0; i < ONFI_SUBFEATURE_PARAM_LEN; ++i) |
| 2856 | *subfeature_param++ = chip->read_byte(mtd); | ||
| 2753 | return 0; | 2857 | return 0; |
| 2754 | } | 2858 | } |
| 2755 | 2859 | ||
| @@ -2812,6 +2916,8 @@ static void nand_set_defaults(struct nand_chip *chip, int busw) | |||
| 2812 | chip->block_markbad = nand_default_block_markbad; | 2916 | chip->block_markbad = nand_default_block_markbad; |
| 2813 | if (!chip->write_buf || chip->write_buf == nand_write_buf) | 2917 | if (!chip->write_buf || chip->write_buf == nand_write_buf) |
| 2814 | chip->write_buf = busw ? nand_write_buf16 : nand_write_buf; | 2918 | chip->write_buf = busw ? nand_write_buf16 : nand_write_buf; |
| 2919 | if (!chip->write_byte || chip->write_byte == nand_write_byte) | ||
| 2920 | chip->write_byte = busw ? nand_write_byte16 : nand_write_byte; | ||
| 2815 | if (!chip->read_buf || chip->read_buf == nand_read_buf) | 2921 | if (!chip->read_buf || chip->read_buf == nand_read_buf) |
| 2816 | chip->read_buf = busw ? nand_read_buf16 : nand_read_buf; | 2922 | chip->read_buf = busw ? nand_read_buf16 : nand_read_buf; |
| 2817 | if (!chip->scan_bbt) | 2923 | if (!chip->scan_bbt) |
| @@ -2926,6 +3032,30 @@ ext_out: | |||
| 2926 | return ret; | 3032 | return ret; |
| 2927 | } | 3033 | } |
| 2928 | 3034 | ||
| 3035 | static int nand_setup_read_retry_micron(struct mtd_info *mtd, int retry_mode) | ||
| 3036 | { | ||
| 3037 | struct nand_chip *chip = mtd->priv; | ||
| 3038 | uint8_t feature[ONFI_SUBFEATURE_PARAM_LEN] = {retry_mode}; | ||
| 3039 | |||
| 3040 | return chip->onfi_set_features(mtd, chip, ONFI_FEATURE_ADDR_READ_RETRY, | ||
| 3041 | feature); | ||
| 3042 | } | ||
| 3043 | |||
| 3044 | /* | ||
| 3045 | * Configure chip properties from Micron vendor-specific ONFI table | ||
| 3046 | */ | ||
| 3047 | static void nand_onfi_detect_micron(struct nand_chip *chip, | ||
| 3048 | struct nand_onfi_params *p) | ||
| 3049 | { | ||
| 3050 | struct nand_onfi_vendor_micron *micron = (void *)p->vendor; | ||
| 3051 | |||
| 3052 | if (le16_to_cpu(p->vendor_revision) < 1) | ||
| 3053 | return; | ||
| 3054 | |||
| 3055 | chip->read_retries = micron->read_retry_options; | ||
| 3056 | chip->setup_read_retry = nand_setup_read_retry_micron; | ||
| 3057 | } | ||
| 3058 | |||
| 2929 | /* | 3059 | /* |
| 2930 | * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise. | 3060 | * Check if the NAND chip is ONFI compliant, returns 1 if it is, 0 otherwise. |
| 2931 | */ | 3061 | */ |
| @@ -2979,7 +3109,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 2979 | chip->onfi_version = 10; | 3109 | chip->onfi_version = 10; |
| 2980 | 3110 | ||
| 2981 | if (!chip->onfi_version) { | 3111 | if (!chip->onfi_version) { |
| 2982 | pr_info("%s: unsupported ONFI version: %d\n", __func__, val); | 3112 | pr_info("unsupported ONFI version: %d\n", val); |
| 2983 | return 0; | 3113 | return 0; |
| 2984 | } | 3114 | } |
| 2985 | 3115 | ||
| @@ -3032,6 +3162,9 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 3032 | pr_warn("Could not retrieve ONFI ECC requirements\n"); | 3162 | pr_warn("Could not retrieve ONFI ECC requirements\n"); |
| 3033 | } | 3163 | } |
| 3034 | 3164 | ||
| 3165 | if (p->jedec_id == NAND_MFR_MICRON) | ||
| 3166 | nand_onfi_detect_micron(chip, p); | ||
| 3167 | |||
| 3035 | return 1; | 3168 | return 1; |
| 3036 | } | 3169 | } |
| 3037 | 3170 | ||
| @@ -3152,9 +3285,12 @@ static void nand_decode_ext_id(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 3152 | mtd->oobsize = 512; | 3285 | mtd->oobsize = 512; |
| 3153 | break; | 3286 | break; |
| 3154 | case 6: | 3287 | case 6: |
| 3155 | default: /* Other cases are "reserved" (unknown) */ | ||
| 3156 | mtd->oobsize = 640; | 3288 | mtd->oobsize = 640; |
| 3157 | break; | 3289 | break; |
| 3290 | case 7: | ||
| 3291 | default: /* Other cases are "reserved" (unknown) */ | ||
| 3292 | mtd->oobsize = 1024; | ||
| 3293 | break; | ||
| 3158 | } | 3294 | } |
| 3159 | extid >>= 2; | 3295 | extid >>= 2; |
| 3160 | /* Calc blocksize */ | 3296 | /* Calc blocksize */ |
| @@ -3325,6 +3461,9 @@ static bool find_full_id_nand(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 3325 | 3461 | ||
| 3326 | *busw = type->options & NAND_BUSWIDTH_16; | 3462 | *busw = type->options & NAND_BUSWIDTH_16; |
| 3327 | 3463 | ||
| 3464 | if (!mtd->name) | ||
| 3465 | mtd->name = type->name; | ||
| 3466 | |||
| 3328 | return true; | 3467 | return true; |
| 3329 | } | 3468 | } |
| 3330 | return false; | 3469 | return false; |
| @@ -3372,8 +3511,7 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, | |||
| 3372 | id_data[i] = chip->read_byte(mtd); | 3511 | id_data[i] = chip->read_byte(mtd); |
| 3373 | 3512 | ||
| 3374 | if (id_data[0] != *maf_id || id_data[1] != *dev_id) { | 3513 | if (id_data[0] != *maf_id || id_data[1] != *dev_id) { |
| 3375 | pr_info("%s: second ID read did not match " | 3514 | pr_info("second ID read did not match %02x,%02x against %02x,%02x\n", |
| 3376 | "%02x,%02x against %02x,%02x\n", __func__, | ||
| 3377 | *maf_id, *dev_id, id_data[0], id_data[1]); | 3515 | *maf_id, *dev_id, id_data[0], id_data[1]); |
| 3378 | return ERR_PTR(-ENODEV); | 3516 | return ERR_PTR(-ENODEV); |
| 3379 | } | 3517 | } |
| @@ -3440,10 +3578,10 @@ ident_done: | |||
| 3440 | * Check, if buswidth is correct. Hardware drivers should set | 3578 | * Check, if buswidth is correct. Hardware drivers should set |
| 3441 | * chip correct! | 3579 | * chip correct! |
| 3442 | */ | 3580 | */ |
| 3443 | pr_info("NAND device: Manufacturer ID:" | 3581 | pr_info("device found, Manufacturer ID: 0x%02x, Chip ID: 0x%02x\n", |
| 3444 | " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, | 3582 | *maf_id, *dev_id); |
| 3445 | *dev_id, nand_manuf_ids[maf_idx].name, mtd->name); | 3583 | pr_info("%s %s\n", nand_manuf_ids[maf_idx].name, mtd->name); |
| 3446 | pr_warn("NAND bus width %d instead %d bit\n", | 3584 | pr_warn("bus width %d instead %d bit\n", |
| 3447 | (chip->options & NAND_BUSWIDTH_16) ? 16 : 8, | 3585 | (chip->options & NAND_BUSWIDTH_16) ? 16 : 8, |
| 3448 | busw ? 16 : 8); | 3586 | busw ? 16 : 8); |
| 3449 | return ERR_PTR(-EINVAL); | 3587 | return ERR_PTR(-EINVAL); |
| @@ -3472,14 +3610,13 @@ ident_done: | |||
| 3472 | if (mtd->writesize > 512 && chip->cmdfunc == nand_command) | 3610 | if (mtd->writesize > 512 && chip->cmdfunc == nand_command) |
| 3473 | chip->cmdfunc = nand_command_lp; | 3611 | chip->cmdfunc = nand_command_lp; |
| 3474 | 3612 | ||
| 3475 | pr_info("NAND device: Manufacturer ID: 0x%02x, Chip ID: 0x%02x (%s %s)\n", | 3613 | pr_info("device found, Manufacturer ID: 0x%02x, Chip ID: 0x%02x\n", |
| 3476 | *maf_id, *dev_id, nand_manuf_ids[maf_idx].name, | 3614 | *maf_id, *dev_id); |
| 3615 | pr_info("%s %s\n", nand_manuf_ids[maf_idx].name, | ||
| 3477 | chip->onfi_version ? chip->onfi_params.model : type->name); | 3616 | chip->onfi_version ? chip->onfi_params.model : type->name); |
| 3478 | 3617 | pr_info("%dMiB, %s, page size: %d, OOB size: %d\n", | |
| 3479 | pr_info("NAND device: %dMiB, %s, page size: %d, OOB size: %d\n", | ||
| 3480 | (int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC", | 3618 | (int)(chip->chipsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC", |
| 3481 | mtd->writesize, mtd->oobsize); | 3619 | mtd->writesize, mtd->oobsize); |
| 3482 | |||
| 3483 | return type; | 3620 | return type; |
| 3484 | } | 3621 | } |
| 3485 | 3622 | ||
| @@ -3535,7 +3672,7 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, | |||
| 3535 | chip->select_chip(mtd, -1); | 3672 | chip->select_chip(mtd, -1); |
| 3536 | } | 3673 | } |
| 3537 | if (i > 1) | 3674 | if (i > 1) |
| 3538 | pr_info("%d NAND chips detected\n", i); | 3675 | pr_info("%d chips detected\n", i); |
| 3539 | 3676 | ||
| 3540 | /* Store the number of chips and calc total size for mtd */ | 3677 | /* Store the number of chips and calc total size for mtd */ |
| 3541 | chip->numchips = i; | 3678 | chip->numchips = i; |
diff --git a/drivers/mtd/nand/nand_ids.c b/drivers/mtd/nand/nand_ids.c index a87b0a3afa35..daa2faacd7d0 100644 --- a/drivers/mtd/nand/nand_ids.c +++ b/drivers/mtd/nand/nand_ids.c | |||
| @@ -169,6 +169,8 @@ struct nand_manufacturers nand_manuf_ids[] = { | |||
| 169 | {NAND_MFR_AMD, "AMD/Spansion"}, | 169 | {NAND_MFR_AMD, "AMD/Spansion"}, |
| 170 | {NAND_MFR_MACRONIX, "Macronix"}, | 170 | {NAND_MFR_MACRONIX, "Macronix"}, |
| 171 | {NAND_MFR_EON, "Eon"}, | 171 | {NAND_MFR_EON, "Eon"}, |
| 172 | {NAND_MFR_SANDISK, "SanDisk"}, | ||
| 173 | {NAND_MFR_INTEL, "Intel"}, | ||
| 172 | {0x0, "Unknown"} | 174 | {0x0, "Unknown"} |
| 173 | }; | 175 | }; |
| 174 | 176 | ||
diff --git a/drivers/mtd/nand/nuc900_nand.c b/drivers/mtd/nand/nuc900_nand.c index 52115151e4a7..9ee09a8177c6 100644 --- a/drivers/mtd/nand/nuc900_nand.c +++ b/drivers/mtd/nand/nuc900_nand.c | |||
| @@ -241,12 +241,10 @@ static int nuc900_nand_probe(struct platform_device *pdev) | |||
| 241 | { | 241 | { |
| 242 | struct nuc900_nand *nuc900_nand; | 242 | struct nuc900_nand *nuc900_nand; |
| 243 | struct nand_chip *chip; | 243 | struct nand_chip *chip; |
| 244 | int retval; | ||
| 245 | struct resource *res; | 244 | struct resource *res; |
| 246 | 245 | ||
| 247 | retval = 0; | 246 | nuc900_nand = devm_kzalloc(&pdev->dev, sizeof(struct nuc900_nand), |
| 248 | 247 | GFP_KERNEL); | |
| 249 | nuc900_nand = kzalloc(sizeof(struct nuc900_nand), GFP_KERNEL); | ||
| 250 | if (!nuc900_nand) | 248 | if (!nuc900_nand) |
| 251 | return -ENOMEM; | 249 | return -ENOMEM; |
| 252 | chip = &(nuc900_nand->chip); | 250 | chip = &(nuc900_nand->chip); |
| @@ -255,11 +253,9 @@ static int nuc900_nand_probe(struct platform_device *pdev) | |||
| 255 | nuc900_nand->mtd.owner = THIS_MODULE; | 253 | nuc900_nand->mtd.owner = THIS_MODULE; |
| 256 | spin_lock_init(&nuc900_nand->lock); | 254 | spin_lock_init(&nuc900_nand->lock); |
| 257 | 255 | ||
| 258 | nuc900_nand->clk = clk_get(&pdev->dev, NULL); | 256 | nuc900_nand->clk = devm_clk_get(&pdev->dev, NULL); |
| 259 | if (IS_ERR(nuc900_nand->clk)) { | 257 | if (IS_ERR(nuc900_nand->clk)) |
| 260 | retval = -ENOENT; | 258 | return -ENOENT; |
| 261 | goto fail1; | ||
| 262 | } | ||
| 263 | clk_enable(nuc900_nand->clk); | 259 | clk_enable(nuc900_nand->clk); |
| 264 | 260 | ||
| 265 | chip->cmdfunc = nuc900_nand_command_lp; | 261 | chip->cmdfunc = nuc900_nand_command_lp; |
| @@ -272,57 +268,29 @@ static int nuc900_nand_probe(struct platform_device *pdev) | |||
| 272 | chip->ecc.mode = NAND_ECC_SOFT; | 268 | chip->ecc.mode = NAND_ECC_SOFT; |
| 273 | 269 | ||
| 274 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 270 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 275 | if (!res) { | 271 | nuc900_nand->reg = devm_ioremap_resource(&pdev->dev, res); |
| 276 | retval = -ENXIO; | 272 | if (IS_ERR(nuc900_nand->reg)) |
| 277 | goto fail1; | 273 | return PTR_ERR(nuc900_nand->reg); |
| 278 | } | ||
| 279 | |||
| 280 | if (!request_mem_region(res->start, resource_size(res), pdev->name)) { | ||
| 281 | retval = -EBUSY; | ||
| 282 | goto fail1; | ||
| 283 | } | ||
| 284 | |||
| 285 | nuc900_nand->reg = ioremap(res->start, resource_size(res)); | ||
| 286 | if (!nuc900_nand->reg) { | ||
| 287 | retval = -ENOMEM; | ||
| 288 | goto fail2; | ||
| 289 | } | ||
| 290 | 274 | ||
| 291 | nuc900_nand_enable(nuc900_nand); | 275 | nuc900_nand_enable(nuc900_nand); |
| 292 | 276 | ||
| 293 | if (nand_scan(&(nuc900_nand->mtd), 1)) { | 277 | if (nand_scan(&(nuc900_nand->mtd), 1)) |
| 294 | retval = -ENXIO; | 278 | return -ENXIO; |
| 295 | goto fail3; | ||
| 296 | } | ||
| 297 | 279 | ||
| 298 | mtd_device_register(&(nuc900_nand->mtd), partitions, | 280 | mtd_device_register(&(nuc900_nand->mtd), partitions, |
| 299 | ARRAY_SIZE(partitions)); | 281 | ARRAY_SIZE(partitions)); |
| 300 | 282 | ||
| 301 | platform_set_drvdata(pdev, nuc900_nand); | 283 | platform_set_drvdata(pdev, nuc900_nand); |
| 302 | 284 | ||
| 303 | return retval; | 285 | return 0; |
| 304 | |||
| 305 | fail3: iounmap(nuc900_nand->reg); | ||
| 306 | fail2: release_mem_region(res->start, resource_size(res)); | ||
| 307 | fail1: kfree(nuc900_nand); | ||
| 308 | return retval; | ||
| 309 | } | 286 | } |
| 310 | 287 | ||
| 311 | static int nuc900_nand_remove(struct platform_device *pdev) | 288 | static int nuc900_nand_remove(struct platform_device *pdev) |
| 312 | { | 289 | { |
| 313 | struct nuc900_nand *nuc900_nand = platform_get_drvdata(pdev); | 290 | struct nuc900_nand *nuc900_nand = platform_get_drvdata(pdev); |
| 314 | struct resource *res; | ||
| 315 | 291 | ||
| 316 | nand_release(&nuc900_nand->mtd); | 292 | nand_release(&nuc900_nand->mtd); |
| 317 | iounmap(nuc900_nand->reg); | ||
| 318 | |||
| 319 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 320 | release_mem_region(res->start, resource_size(res)); | ||
| 321 | |||
| 322 | clk_disable(nuc900_nand->clk); | 293 | clk_disable(nuc900_nand->clk); |
| 323 | clk_put(nuc900_nand->clk); | ||
| 324 | |||
| 325 | kfree(nuc900_nand); | ||
| 326 | 294 | ||
| 327 | return 0; | 295 | return 0; |
| 328 | } | 296 | } |
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index f77725009907..ef4190a02b7b 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
| @@ -1730,13 +1730,7 @@ static int omap_nand_probe(struct platform_device *pdev) | |||
| 1730 | break; | 1730 | break; |
| 1731 | 1731 | ||
| 1732 | case NAND_OMAP_POLLED: | 1732 | case NAND_OMAP_POLLED: |
| 1733 | if (nand_chip->options & NAND_BUSWIDTH_16) { | 1733 | /* Use nand_base defaults for {read,write}_buf */ |
| 1734 | nand_chip->read_buf = omap_read_buf16; | ||
| 1735 | nand_chip->write_buf = omap_write_buf16; | ||
| 1736 | } else { | ||
| 1737 | nand_chip->read_buf = omap_read_buf8; | ||
| 1738 | nand_chip->write_buf = omap_write_buf8; | ||
| 1739 | } | ||
| 1740 | break; | 1734 | break; |
| 1741 | 1735 | ||
| 1742 | case NAND_OMAP_PREFETCH_DMA: | 1736 | case NAND_OMAP_PREFETCH_DMA: |
diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index a393a5b6ce1e..dd7fe817eafb 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c | |||
| @@ -87,7 +87,6 @@ static int __init orion_nand_probe(struct platform_device *pdev) | |||
| 87 | 87 | ||
| 88 | nc = kzalloc(sizeof(struct nand_chip) + sizeof(struct mtd_info), GFP_KERNEL); | 88 | nc = kzalloc(sizeof(struct nand_chip) + sizeof(struct mtd_info), GFP_KERNEL); |
| 89 | if (!nc) { | 89 | if (!nc) { |
| 90 | printk(KERN_ERR "orion_nand: failed to allocate device structure.\n"); | ||
| 91 | ret = -ENOMEM; | 90 | ret = -ENOMEM; |
| 92 | goto no_res; | 91 | goto no_res; |
| 93 | } | 92 | } |
| @@ -101,7 +100,7 @@ static int __init orion_nand_probe(struct platform_device *pdev) | |||
| 101 | 100 | ||
| 102 | io_base = ioremap(res->start, resource_size(res)); | 101 | io_base = ioremap(res->start, resource_size(res)); |
| 103 | if (!io_base) { | 102 | if (!io_base) { |
| 104 | printk(KERN_ERR "orion_nand: ioremap failed\n"); | 103 | dev_err(&pdev->dev, "ioremap failed\n"); |
| 105 | ret = -EIO; | 104 | ret = -EIO; |
| 106 | goto no_res; | 105 | goto no_res; |
| 107 | } | 106 | } |
| @@ -110,7 +109,6 @@ static int __init orion_nand_probe(struct platform_device *pdev) | |||
| 110 | board = devm_kzalloc(&pdev->dev, sizeof(struct orion_nand_data), | 109 | board = devm_kzalloc(&pdev->dev, sizeof(struct orion_nand_data), |
| 111 | GFP_KERNEL); | 110 | GFP_KERNEL); |
| 112 | if (!board) { | 111 | if (!board) { |
| 113 | printk(KERN_ERR "orion_nand: failed to allocate board structure.\n"); | ||
| 114 | ret = -ENOMEM; | 112 | ret = -ENOMEM; |
| 115 | goto no_res; | 113 | goto no_res; |
| 116 | } | 114 | } |
diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index 4d174366a0f0..90f871acb0ef 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c | |||
| @@ -223,7 +223,7 @@ MODULE_DEVICE_TABLE(of, pasemi_nand_match); | |||
| 223 | static struct platform_driver pasemi_nand_driver = | 223 | static struct platform_driver pasemi_nand_driver = |
| 224 | { | 224 | { |
| 225 | .driver = { | 225 | .driver = { |
| 226 | .name = (char*)driver_name, | 226 | .name = driver_name, |
| 227 | .owner = THIS_MODULE, | 227 | .owner = THIS_MODULE, |
| 228 | .of_match_table = pasemi_nand_match, | 228 | .of_match_table = pasemi_nand_match, |
| 229 | }, | 229 | }, |
diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c index cad4cdc9df39..0b068a5c0bff 100644 --- a/drivers/mtd/nand/plat_nand.c +++ b/drivers/mtd/nand/plat_nand.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | * | 9 | * |
| 10 | */ | 10 | */ |
| 11 | 11 | ||
| 12 | #include <linux/err.h> | ||
| 12 | #include <linux/io.h> | 13 | #include <linux/io.h> |
| 13 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 14 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
| @@ -47,30 +48,16 @@ static int plat_nand_probe(struct platform_device *pdev) | |||
| 47 | return -EINVAL; | 48 | return -EINVAL; |
| 48 | } | 49 | } |
| 49 | 50 | ||
| 50 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 51 | if (!res) | ||
| 52 | return -ENXIO; | ||
| 53 | |||
| 54 | /* Allocate memory for the device structure (and zero it) */ | 51 | /* Allocate memory for the device structure (and zero it) */ |
| 55 | data = kzalloc(sizeof(struct plat_nand_data), GFP_KERNEL); | 52 | data = devm_kzalloc(&pdev->dev, sizeof(struct plat_nand_data), |
| 56 | if (!data) { | 53 | GFP_KERNEL); |
| 57 | dev_err(&pdev->dev, "failed to allocate device structure.\n"); | 54 | if (!data) |
| 58 | return -ENOMEM; | 55 | return -ENOMEM; |
| 59 | } | ||
| 60 | |||
| 61 | if (!request_mem_region(res->start, resource_size(res), | ||
| 62 | dev_name(&pdev->dev))) { | ||
| 63 | dev_err(&pdev->dev, "request_mem_region failed\n"); | ||
| 64 | err = -EBUSY; | ||
| 65 | goto out_free; | ||
| 66 | } | ||
| 67 | 56 | ||
| 68 | data->io_base = ioremap(res->start, resource_size(res)); | 57 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 69 | if (data->io_base == NULL) { | 58 | data->io_base = devm_ioremap_resource(&pdev->dev, res); |
| 70 | dev_err(&pdev->dev, "ioremap failed\n"); | 59 | if (IS_ERR(data->io_base)) |
| 71 | err = -EIO; | 60 | return PTR_ERR(data->io_base); |
| 72 | goto out_release_io; | ||
| 73 | } | ||
| 74 | 61 | ||
| 75 | data->chip.priv = &data; | 62 | data->chip.priv = &data; |
| 76 | data->mtd.priv = &data->chip; | 63 | data->mtd.priv = &data->chip; |
| @@ -122,11 +109,6 @@ static int plat_nand_probe(struct platform_device *pdev) | |||
| 122 | out: | 109 | out: |
| 123 | if (pdata->ctrl.remove) | 110 | if (pdata->ctrl.remove) |
| 124 | pdata->ctrl.remove(pdev); | 111 | pdata->ctrl.remove(pdev); |
| 125 | iounmap(data->io_base); | ||
| 126 | out_release_io: | ||
| 127 | release_mem_region(res->start, resource_size(res)); | ||
| 128 | out_free: | ||
| 129 | kfree(data); | ||
| 130 | return err; | 112 | return err; |
| 131 | } | 113 | } |
| 132 | 114 | ||
| @@ -137,16 +119,10 @@ static int plat_nand_remove(struct platform_device *pdev) | |||
| 137 | { | 119 | { |
| 138 | struct plat_nand_data *data = platform_get_drvdata(pdev); | 120 | struct plat_nand_data *data = platform_get_drvdata(pdev); |
| 139 | struct platform_nand_data *pdata = dev_get_platdata(&pdev->dev); | 121 | struct platform_nand_data *pdata = dev_get_platdata(&pdev->dev); |
| 140 | struct resource *res; | ||
| 141 | |||
| 142 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 143 | 122 | ||
| 144 | nand_release(&data->mtd); | 123 | nand_release(&data->mtd); |
| 145 | if (pdata->ctrl.remove) | 124 | if (pdata->ctrl.remove) |
| 146 | pdata->ctrl.remove(pdev); | 125 | pdata->ctrl.remove(pdev); |
| 147 | iounmap(data->io_base); | ||
| 148 | release_mem_region(res->start, resource_size(res)); | ||
| 149 | kfree(data); | ||
| 150 | 126 | ||
| 151 | return 0; | 127 | return 0; |
| 152 | } | 128 | } |
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c index 4b3aaa898a8b..2a7a0b27ac38 100644 --- a/drivers/mtd/nand/pxa3xx_nand.c +++ b/drivers/mtd/nand/pxa3xx_nand.c | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
| 9 | * published by the Free Software Foundation. | 9 | * published by the Free Software Foundation. |
| 10 | * | ||
| 11 | * See Documentation/mtd/nand/pxa3xx-nand.txt for more details. | ||
| 10 | */ | 12 | */ |
| 11 | 13 | ||
| 12 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
| @@ -24,6 +26,7 @@ | |||
| 24 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
| 25 | #include <linux/of.h> | 27 | #include <linux/of.h> |
| 26 | #include <linux/of_device.h> | 28 | #include <linux/of_device.h> |
| 29 | #include <linux/of_mtd.h> | ||
| 27 | 30 | ||
| 28 | #if defined(CONFIG_ARCH_PXA) || defined(CONFIG_ARCH_MMP) | 31 | #if defined(CONFIG_ARCH_PXA) || defined(CONFIG_ARCH_MMP) |
| 29 | #define ARCH_HAS_DMA | 32 | #define ARCH_HAS_DMA |
| @@ -35,6 +38,7 @@ | |||
| 35 | 38 | ||
| 36 | #include <linux/platform_data/mtd-nand-pxa3xx.h> | 39 | #include <linux/platform_data/mtd-nand-pxa3xx.h> |
| 37 | 40 | ||
| 41 | #define NAND_DEV_READY_TIMEOUT 50 | ||
| 38 | #define CHIP_DELAY_TIMEOUT (2 * HZ/10) | 42 | #define CHIP_DELAY_TIMEOUT (2 * HZ/10) |
| 39 | #define NAND_STOP_DELAY (2 * HZ/50) | 43 | #define NAND_STOP_DELAY (2 * HZ/50) |
| 40 | #define PAGE_CHUNK_SIZE (2048) | 44 | #define PAGE_CHUNK_SIZE (2048) |
| @@ -54,6 +58,7 @@ | |||
| 54 | #define NDPCR (0x18) /* Page Count Register */ | 58 | #define NDPCR (0x18) /* Page Count Register */ |
| 55 | #define NDBDR0 (0x1C) /* Bad Block Register 0 */ | 59 | #define NDBDR0 (0x1C) /* Bad Block Register 0 */ |
| 56 | #define NDBDR1 (0x20) /* Bad Block Register 1 */ | 60 | #define NDBDR1 (0x20) /* Bad Block Register 1 */ |
| 61 | #define NDECCCTRL (0x28) /* ECC control */ | ||
| 57 | #define NDDB (0x40) /* Data Buffer */ | 62 | #define NDDB (0x40) /* Data Buffer */ |
| 58 | #define NDCB0 (0x48) /* Command Buffer0 */ | 63 | #define NDCB0 (0x48) /* Command Buffer0 */ |
| 59 | #define NDCB1 (0x4C) /* Command Buffer1 */ | 64 | #define NDCB1 (0x4C) /* Command Buffer1 */ |
| @@ -80,6 +85,9 @@ | |||
| 80 | #define NDCR_INT_MASK (0xFFF) | 85 | #define NDCR_INT_MASK (0xFFF) |
| 81 | 86 | ||
| 82 | #define NDSR_MASK (0xfff) | 87 | #define NDSR_MASK (0xfff) |
| 88 | #define NDSR_ERR_CNT_OFF (16) | ||
| 89 | #define NDSR_ERR_CNT_MASK (0x1f) | ||
| 90 | #define NDSR_ERR_CNT(sr) ((sr >> NDSR_ERR_CNT_OFF) & NDSR_ERR_CNT_MASK) | ||
| 83 | #define NDSR_RDY (0x1 << 12) | 91 | #define NDSR_RDY (0x1 << 12) |
| 84 | #define NDSR_FLASH_RDY (0x1 << 11) | 92 | #define NDSR_FLASH_RDY (0x1 << 11) |
| 85 | #define NDSR_CS0_PAGED (0x1 << 10) | 93 | #define NDSR_CS0_PAGED (0x1 << 10) |
| @@ -88,8 +96,8 @@ | |||
| 88 | #define NDSR_CS1_CMDD (0x1 << 7) | 96 | #define NDSR_CS1_CMDD (0x1 << 7) |
| 89 | #define NDSR_CS0_BBD (0x1 << 6) | 97 | #define NDSR_CS0_BBD (0x1 << 6) |
| 90 | #define NDSR_CS1_BBD (0x1 << 5) | 98 | #define NDSR_CS1_BBD (0x1 << 5) |
| 91 | #define NDSR_DBERR (0x1 << 4) | 99 | #define NDSR_UNCORERR (0x1 << 4) |
| 92 | #define NDSR_SBERR (0x1 << 3) | 100 | #define NDSR_CORERR (0x1 << 3) |
| 93 | #define NDSR_WRDREQ (0x1 << 2) | 101 | #define NDSR_WRDREQ (0x1 << 2) |
| 94 | #define NDSR_RDDREQ (0x1 << 1) | 102 | #define NDSR_RDDREQ (0x1 << 1) |
| 95 | #define NDSR_WRCMDREQ (0x1) | 103 | #define NDSR_WRCMDREQ (0x1) |
| @@ -98,6 +106,8 @@ | |||
| 98 | #define NDCB0_ST_ROW_EN (0x1 << 26) | 106 | #define NDCB0_ST_ROW_EN (0x1 << 26) |
| 99 | #define NDCB0_AUTO_RS (0x1 << 25) | 107 | #define NDCB0_AUTO_RS (0x1 << 25) |
| 100 | #define NDCB0_CSEL (0x1 << 24) | 108 | #define NDCB0_CSEL (0x1 << 24) |
| 109 | #define NDCB0_EXT_CMD_TYPE_MASK (0x7 << 29) | ||
| 110 | #define NDCB0_EXT_CMD_TYPE(x) (((x) << 29) & NDCB0_EXT_CMD_TYPE_MASK) | ||
| 101 | #define NDCB0_CMD_TYPE_MASK (0x7 << 21) | 111 | #define NDCB0_CMD_TYPE_MASK (0x7 << 21) |
| 102 | #define NDCB0_CMD_TYPE(x) (((x) << 21) & NDCB0_CMD_TYPE_MASK) | 112 | #define NDCB0_CMD_TYPE(x) (((x) << 21) & NDCB0_CMD_TYPE_MASK) |
| 103 | #define NDCB0_NC (0x1 << 20) | 113 | #define NDCB0_NC (0x1 << 20) |
| @@ -108,6 +118,14 @@ | |||
| 108 | #define NDCB0_CMD1_MASK (0xff) | 118 | #define NDCB0_CMD1_MASK (0xff) |
| 109 | #define NDCB0_ADDR_CYC_SHIFT (16) | 119 | #define NDCB0_ADDR_CYC_SHIFT (16) |
| 110 | 120 | ||
| 121 | #define EXT_CMD_TYPE_DISPATCH 6 /* Command dispatch */ | ||
| 122 | #define EXT_CMD_TYPE_NAKED_RW 5 /* Naked read or Naked write */ | ||
| 123 | #define EXT_CMD_TYPE_READ 4 /* Read */ | ||
| 124 | #define EXT_CMD_TYPE_DISP_WR 4 /* Command dispatch with write */ | ||
| 125 | #define EXT_CMD_TYPE_FINAL 3 /* Final command */ | ||
| 126 | #define EXT_CMD_TYPE_LAST_RW 1 /* Last naked read/write */ | ||
| 127 | #define EXT_CMD_TYPE_MONO 0 /* Monolithic read/write */ | ||
| 128 | |||
| 111 | /* macros for registers read/write */ | 129 | /* macros for registers read/write */ |
| 112 | #define nand_writel(info, off, val) \ | 130 | #define nand_writel(info, off, val) \ |
| 113 | __raw_writel((val), (info)->mmio_base + (off)) | 131 | __raw_writel((val), (info)->mmio_base + (off)) |
| @@ -120,9 +138,9 @@ enum { | |||
| 120 | ERR_NONE = 0, | 138 | ERR_NONE = 0, |
| 121 | ERR_DMABUSERR = -1, | 139 | ERR_DMABUSERR = -1, |
| 122 | ERR_SENDCMD = -2, | 140 | ERR_SENDCMD = -2, |
| 123 | ERR_DBERR = -3, | 141 | ERR_UNCORERR = -3, |
| 124 | ERR_BBERR = -4, | 142 | ERR_BBERR = -4, |
| 125 | ERR_SBERR = -5, | 143 | ERR_CORERR = -5, |
| 126 | }; | 144 | }; |
| 127 | 145 | ||
| 128 | enum { | 146 | enum { |
| @@ -149,7 +167,6 @@ struct pxa3xx_nand_host { | |||
| 149 | void *info_data; | 167 | void *info_data; |
| 150 | 168 | ||
| 151 | /* page size of attached chip */ | 169 | /* page size of attached chip */ |
| 152 | unsigned int page_size; | ||
| 153 | int use_ecc; | 170 | int use_ecc; |
| 154 | int cs; | 171 | int cs; |
| 155 | 172 | ||
| @@ -167,11 +184,13 @@ struct pxa3xx_nand_info { | |||
| 167 | struct clk *clk; | 184 | struct clk *clk; |
| 168 | void __iomem *mmio_base; | 185 | void __iomem *mmio_base; |
| 169 | unsigned long mmio_phys; | 186 | unsigned long mmio_phys; |
| 170 | struct completion cmd_complete; | 187 | struct completion cmd_complete, dev_ready; |
| 171 | 188 | ||
| 172 | unsigned int buf_start; | 189 | unsigned int buf_start; |
| 173 | unsigned int buf_count; | 190 | unsigned int buf_count; |
| 174 | unsigned int buf_size; | 191 | unsigned int buf_size; |
| 192 | unsigned int data_buff_pos; | ||
| 193 | unsigned int oob_buff_pos; | ||
| 175 | 194 | ||
| 176 | /* DMA information */ | 195 | /* DMA information */ |
| 177 | int drcmr_dat; | 196 | int drcmr_dat; |
| @@ -195,13 +214,18 @@ struct pxa3xx_nand_info { | |||
| 195 | 214 | ||
| 196 | int cs; | 215 | int cs; |
| 197 | int use_ecc; /* use HW ECC ? */ | 216 | int use_ecc; /* use HW ECC ? */ |
| 217 | int ecc_bch; /* using BCH ECC? */ | ||
| 198 | int use_dma; /* use DMA ? */ | 218 | int use_dma; /* use DMA ? */ |
| 199 | int use_spare; /* use spare ? */ | 219 | int use_spare; /* use spare ? */ |
| 200 | int is_ready; | 220 | int need_wait; |
| 201 | 221 | ||
| 202 | unsigned int page_size; /* page size of attached chip */ | 222 | unsigned int data_size; /* data to be read from FIFO */ |
| 203 | unsigned int data_size; /* data size in FIFO */ | 223 | unsigned int chunk_size; /* split commands chunk size */ |
| 204 | unsigned int oob_size; | 224 | unsigned int oob_size; |
| 225 | unsigned int spare_size; | ||
| 226 | unsigned int ecc_size; | ||
| 227 | unsigned int ecc_err_cnt; | ||
| 228 | unsigned int max_bitflips; | ||
| 205 | int retcode; | 229 | int retcode; |
| 206 | 230 | ||
| 207 | /* cached register value */ | 231 | /* cached register value */ |
| @@ -239,6 +263,64 @@ static struct pxa3xx_nand_flash builtin_flash_types[] = { | |||
| 239 | { "256MiB 16-bit", 0xba20, 64, 2048, 16, 16, 2048, &timing[3] }, | 263 | { "256MiB 16-bit", 0xba20, 64, 2048, 16, 16, 2048, &timing[3] }, |
| 240 | }; | 264 | }; |
| 241 | 265 | ||
| 266 | static u8 bbt_pattern[] = {'M', 'V', 'B', 'b', 't', '0' }; | ||
| 267 | static u8 bbt_mirror_pattern[] = {'1', 't', 'b', 'B', 'V', 'M' }; | ||
| 268 | |||
| 269 | static struct nand_bbt_descr bbt_main_descr = { | ||
| 270 | .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | ||
| 271 | | NAND_BBT_2BIT | NAND_BBT_VERSION, | ||
| 272 | .offs = 8, | ||
| 273 | .len = 6, | ||
| 274 | .veroffs = 14, | ||
| 275 | .maxblocks = 8, /* Last 8 blocks in each chip */ | ||
| 276 | .pattern = bbt_pattern | ||
| 277 | }; | ||
| 278 | |||
| 279 | static struct nand_bbt_descr bbt_mirror_descr = { | ||
| 280 | .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE | ||
| 281 | | NAND_BBT_2BIT | NAND_BBT_VERSION, | ||
| 282 | .offs = 8, | ||
| 283 | .len = 6, | ||
| 284 | .veroffs = 14, | ||
| 285 | .maxblocks = 8, /* Last 8 blocks in each chip */ | ||
| 286 | .pattern = bbt_mirror_pattern | ||
| 287 | }; | ||
| 288 | |||
| 289 | static struct nand_ecclayout ecc_layout_2KB_bch4bit = { | ||
| 290 | .eccbytes = 32, | ||
| 291 | .eccpos = { | ||
| 292 | 32, 33, 34, 35, 36, 37, 38, 39, | ||
| 293 | 40, 41, 42, 43, 44, 45, 46, 47, | ||
| 294 | 48, 49, 50, 51, 52, 53, 54, 55, | ||
| 295 | 56, 57, 58, 59, 60, 61, 62, 63}, | ||
| 296 | .oobfree = { {2, 30} } | ||
| 297 | }; | ||
| 298 | |||
| 299 | static struct nand_ecclayout ecc_layout_4KB_bch4bit = { | ||
| 300 | .eccbytes = 64, | ||
| 301 | .eccpos = { | ||
| 302 | 32, 33, 34, 35, 36, 37, 38, 39, | ||
| 303 | 40, 41, 42, 43, 44, 45, 46, 47, | ||
| 304 | 48, 49, 50, 51, 52, 53, 54, 55, | ||
| 305 | 56, 57, 58, 59, 60, 61, 62, 63, | ||
| 306 | 96, 97, 98, 99, 100, 101, 102, 103, | ||
| 307 | 104, 105, 106, 107, 108, 109, 110, 111, | ||
| 308 | 112, 113, 114, 115, 116, 117, 118, 119, | ||
| 309 | 120, 121, 122, 123, 124, 125, 126, 127}, | ||
| 310 | /* Bootrom looks in bytes 0 & 5 for bad blocks */ | ||
| 311 | .oobfree = { {6, 26}, { 64, 32} } | ||
| 312 | }; | ||
| 313 | |||
| 314 | static struct nand_ecclayout ecc_layout_4KB_bch8bit = { | ||
| 315 | .eccbytes = 128, | ||
| 316 | .eccpos = { | ||
| 317 | 32, 33, 34, 35, 36, 37, 38, 39, | ||
| 318 | 40, 41, 42, 43, 44, 45, 46, 47, | ||
| 319 | 48, 49, 50, 51, 52, 53, 54, 55, | ||
| 320 | 56, 57, 58, 59, 60, 61, 62, 63}, | ||
| 321 | .oobfree = { } | ||
| 322 | }; | ||
| 323 | |||
| 242 | /* Define a default flash type setting serve as flash detecting only */ | 324 | /* Define a default flash type setting serve as flash detecting only */ |
| 243 | #define DEFAULT_FLASH_TYPE (&builtin_flash_types[0]) | 325 | #define DEFAULT_FLASH_TYPE (&builtin_flash_types[0]) |
| 244 | 326 | ||
| @@ -256,6 +338,29 @@ static struct pxa3xx_nand_flash builtin_flash_types[] = { | |||
| 256 | /* convert nano-seconds to nand flash controller clock cycles */ | 338 | /* convert nano-seconds to nand flash controller clock cycles */ |
| 257 | #define ns2cycle(ns, clk) (int)((ns) * (clk / 1000000) / 1000) | 339 | #define ns2cycle(ns, clk) (int)((ns) * (clk / 1000000) / 1000) |
| 258 | 340 | ||
| 341 | static struct of_device_id pxa3xx_nand_dt_ids[] = { | ||
| 342 | { | ||
| 343 | .compatible = "marvell,pxa3xx-nand", | ||
| 344 | .data = (void *)PXA3XX_NAND_VARIANT_PXA, | ||
| 345 | }, | ||
| 346 | { | ||
| 347 | .compatible = "marvell,armada370-nand", | ||
| 348 | .data = (void *)PXA3XX_NAND_VARIANT_ARMADA370, | ||
| 349 | }, | ||
| 350 | {} | ||
| 351 | }; | ||
| 352 | MODULE_DEVICE_TABLE(of, pxa3xx_nand_dt_ids); | ||
| 353 | |||
| 354 | static enum pxa3xx_nand_variant | ||
| 355 | pxa3xx_nand_get_variant(struct platform_device *pdev) | ||
| 356 | { | ||
| 357 | const struct of_device_id *of_id = | ||
| 358 | of_match_device(pxa3xx_nand_dt_ids, &pdev->dev); | ||
| 359 | if (!of_id) | ||
| 360 | return PXA3XX_NAND_VARIANT_PXA; | ||
| 361 | return (enum pxa3xx_nand_variant)of_id->data; | ||
| 362 | } | ||
| 363 | |||
| 259 | static void pxa3xx_nand_set_timing(struct pxa3xx_nand_host *host, | 364 | static void pxa3xx_nand_set_timing(struct pxa3xx_nand_host *host, |
| 260 | const struct pxa3xx_nand_timing *t) | 365 | const struct pxa3xx_nand_timing *t) |
| 261 | { | 366 | { |
| @@ -280,25 +385,23 @@ static void pxa3xx_nand_set_timing(struct pxa3xx_nand_host *host, | |||
| 280 | nand_writel(info, NDTR1CS0, ndtr1); | 385 | nand_writel(info, NDTR1CS0, ndtr1); |
| 281 | } | 386 | } |
| 282 | 387 | ||
| 283 | static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info) | 388 | /* |
| 389 | * Set the data and OOB size, depending on the selected | ||
| 390 | * spare and ECC configuration. | ||
| 391 | * Only applicable to READ0, READOOB and PAGEPROG commands. | ||
| 392 | */ | ||
| 393 | static void pxa3xx_set_datasize(struct pxa3xx_nand_info *info, | ||
| 394 | struct mtd_info *mtd) | ||
| 284 | { | 395 | { |
| 285 | struct pxa3xx_nand_host *host = info->host[info->cs]; | ||
| 286 | int oob_enable = info->reg_ndcr & NDCR_SPARE_EN; | 396 | int oob_enable = info->reg_ndcr & NDCR_SPARE_EN; |
| 287 | 397 | ||
| 288 | info->data_size = host->page_size; | 398 | info->data_size = mtd->writesize; |
| 289 | if (!oob_enable) { | 399 | if (!oob_enable) |
| 290 | info->oob_size = 0; | ||
| 291 | return; | 400 | return; |
| 292 | } | ||
| 293 | 401 | ||
| 294 | switch (host->page_size) { | 402 | info->oob_size = info->spare_size; |
| 295 | case 2048: | 403 | if (!info->use_ecc) |
| 296 | info->oob_size = (info->use_ecc) ? 40 : 64; | 404 | info->oob_size += info->ecc_size; |
| 297 | break; | ||
| 298 | case 512: | ||
| 299 | info->oob_size = (info->use_ecc) ? 8 : 16; | ||
| 300 | break; | ||
| 301 | } | ||
| 302 | } | 405 | } |
| 303 | 406 | ||
| 304 | /** | 407 | /** |
| @@ -313,10 +416,15 @@ static void pxa3xx_nand_start(struct pxa3xx_nand_info *info) | |||
| 313 | 416 | ||
| 314 | ndcr = info->reg_ndcr; | 417 | ndcr = info->reg_ndcr; |
| 315 | 418 | ||
| 316 | if (info->use_ecc) | 419 | if (info->use_ecc) { |
| 317 | ndcr |= NDCR_ECC_EN; | 420 | ndcr |= NDCR_ECC_EN; |
| 318 | else | 421 | if (info->ecc_bch) |
| 422 | nand_writel(info, NDECCCTRL, 0x1); | ||
| 423 | } else { | ||
| 319 | ndcr &= ~NDCR_ECC_EN; | 424 | ndcr &= ~NDCR_ECC_EN; |
| 425 | if (info->ecc_bch) | ||
| 426 | nand_writel(info, NDECCCTRL, 0x0); | ||
| 427 | } | ||
| 320 | 428 | ||
| 321 | if (info->use_dma) | 429 | if (info->use_dma) |
| 322 | ndcr |= NDCR_DMA_EN; | 430 | ndcr |= NDCR_DMA_EN; |
| @@ -375,26 +483,39 @@ static void disable_int(struct pxa3xx_nand_info *info, uint32_t int_mask) | |||
| 375 | 483 | ||
| 376 | static void handle_data_pio(struct pxa3xx_nand_info *info) | 484 | static void handle_data_pio(struct pxa3xx_nand_info *info) |
| 377 | { | 485 | { |
| 486 | unsigned int do_bytes = min(info->data_size, info->chunk_size); | ||
| 487 | |||
| 378 | switch (info->state) { | 488 | switch (info->state) { |
| 379 | case STATE_PIO_WRITING: | 489 | case STATE_PIO_WRITING: |
| 380 | __raw_writesl(info->mmio_base + NDDB, info->data_buff, | 490 | __raw_writesl(info->mmio_base + NDDB, |
| 381 | DIV_ROUND_UP(info->data_size, 4)); | 491 | info->data_buff + info->data_buff_pos, |
| 492 | DIV_ROUND_UP(do_bytes, 4)); | ||
| 493 | |||
| 382 | if (info->oob_size > 0) | 494 | if (info->oob_size > 0) |
| 383 | __raw_writesl(info->mmio_base + NDDB, info->oob_buff, | 495 | __raw_writesl(info->mmio_base + NDDB, |
| 384 | DIV_ROUND_UP(info->oob_size, 4)); | 496 | info->oob_buff + info->oob_buff_pos, |
| 497 | DIV_ROUND_UP(info->oob_size, 4)); | ||
| 385 | break; | 498 | break; |
| 386 | case STATE_PIO_READING: | 499 | case STATE_PIO_READING: |
| 387 | __raw_readsl(info->mmio_base + NDDB, info->data_buff, | 500 | __raw_readsl(info->mmio_base + NDDB, |
| 388 | DIV_ROUND_UP(info->data_size, 4)); | 501 | info->data_buff + info->data_buff_pos, |
| 502 | DIV_ROUND_UP(do_bytes, 4)); | ||
| 503 | |||
| 389 | if (info->oob_size > 0) | 504 | if (info->oob_size > 0) |
| 390 | __raw_readsl(info->mmio_base + NDDB, info->oob_buff, | 505 | __raw_readsl(info->mmio_base + NDDB, |
| 391 | DIV_ROUND_UP(info->oob_size, 4)); | 506 | info->oob_buff + info->oob_buff_pos, |
| 507 | DIV_ROUND_UP(info->oob_size, 4)); | ||
| 392 | break; | 508 | break; |
| 393 | default: | 509 | default: |
| 394 | dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__, | 510 | dev_err(&info->pdev->dev, "%s: invalid state %d\n", __func__, |
| 395 | info->state); | 511 | info->state); |
| 396 | BUG(); | 512 | BUG(); |
| 397 | } | 513 | } |
| 514 | |||
| 515 | /* Update buffer pointers for multi-page read/write */ | ||
| 516 | info->data_buff_pos += do_bytes; | ||
| 517 | info->oob_buff_pos += info->oob_size; | ||
| 518 | info->data_size -= do_bytes; | ||
| 398 | } | 519 | } |
| 399 | 520 | ||
| 400 | #ifdef ARCH_HAS_DMA | 521 | #ifdef ARCH_HAS_DMA |
| @@ -452,7 +573,7 @@ static void start_data_dma(struct pxa3xx_nand_info *info) | |||
| 452 | static irqreturn_t pxa3xx_nand_irq(int irq, void *devid) | 573 | static irqreturn_t pxa3xx_nand_irq(int irq, void *devid) |
| 453 | { | 574 | { |
| 454 | struct pxa3xx_nand_info *info = devid; | 575 | struct pxa3xx_nand_info *info = devid; |
| 455 | unsigned int status, is_completed = 0; | 576 | unsigned int status, is_completed = 0, is_ready = 0; |
| 456 | unsigned int ready, cmd_done; | 577 | unsigned int ready, cmd_done; |
| 457 | 578 | ||
| 458 | if (info->cs == 0) { | 579 | if (info->cs == 0) { |
| @@ -465,10 +586,25 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid) | |||
| 465 | 586 | ||
| 466 | status = nand_readl(info, NDSR); | 587 | status = nand_readl(info, NDSR); |
| 467 | 588 | ||
| 468 | if (status & NDSR_DBERR) | 589 | if (status & NDSR_UNCORERR) |
| 469 | info->retcode = ERR_DBERR; | 590 | info->retcode = ERR_UNCORERR; |
| 470 | if (status & NDSR_SBERR) | 591 | if (status & NDSR_CORERR) { |
| 471 | info->retcode = ERR_SBERR; | 592 | info->retcode = ERR_CORERR; |
| 593 | if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370 && | ||
| 594 | info->ecc_bch) | ||
| 595 | info->ecc_err_cnt = NDSR_ERR_CNT(status); | ||
| 596 | else | ||
| 597 | info->ecc_err_cnt = 1; | ||
| 598 | |||
| 599 | /* | ||
| 600 | * Each chunk composing a page is corrected independently, | ||
| 601 | * and we need to store maximum number of corrected bitflips | ||
| 602 | * to return it to the MTD layer in ecc.read_page(). | ||
| 603 | */ | ||
| 604 | info->max_bitflips = max_t(unsigned int, | ||
| 605 | info->max_bitflips, | ||
| 606 | info->ecc_err_cnt); | ||
| 607 | } | ||
| 472 | if (status & (NDSR_RDDREQ | NDSR_WRDREQ)) { | 608 | if (status & (NDSR_RDDREQ | NDSR_WRDREQ)) { |
| 473 | /* whether use dma to transfer data */ | 609 | /* whether use dma to transfer data */ |
| 474 | if (info->use_dma) { | 610 | if (info->use_dma) { |
| @@ -488,8 +624,8 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid) | |||
| 488 | is_completed = 1; | 624 | is_completed = 1; |
| 489 | } | 625 | } |
| 490 | if (status & ready) { | 626 | if (status & ready) { |
| 491 | info->is_ready = 1; | ||
| 492 | info->state = STATE_READY; | 627 | info->state = STATE_READY; |
| 628 | is_ready = 1; | ||
| 493 | } | 629 | } |
| 494 | 630 | ||
| 495 | if (status & NDSR_WRCMDREQ) { | 631 | if (status & NDSR_WRCMDREQ) { |
| @@ -518,6 +654,8 @@ static irqreturn_t pxa3xx_nand_irq(int irq, void *devid) | |||
| 518 | nand_writel(info, NDSR, status); | 654 | nand_writel(info, NDSR, status); |
| 519 | if (is_completed) | 655 | if (is_completed) |
| 520 | complete(&info->cmd_complete); | 656 | complete(&info->cmd_complete); |
| 657 | if (is_ready) | ||
| 658 | complete(&info->dev_ready); | ||
| 521 | NORMAL_IRQ_EXIT: | 659 | NORMAL_IRQ_EXIT: |
| 522 | return IRQ_HANDLED; | 660 | return IRQ_HANDLED; |
| 523 | } | 661 | } |
| @@ -530,51 +668,94 @@ static inline int is_buf_blank(uint8_t *buf, size_t len) | |||
| 530 | return 1; | 668 | return 1; |
| 531 | } | 669 | } |
| 532 | 670 | ||
| 533 | static int prepare_command_pool(struct pxa3xx_nand_info *info, int command, | 671 | static void set_command_address(struct pxa3xx_nand_info *info, |
| 534 | uint16_t column, int page_addr) | 672 | unsigned int page_size, uint16_t column, int page_addr) |
| 535 | { | 673 | { |
| 536 | int addr_cycle, exec_cmd; | 674 | /* small page addr setting */ |
| 537 | struct pxa3xx_nand_host *host; | 675 | if (page_size < PAGE_CHUNK_SIZE) { |
| 538 | struct mtd_info *mtd; | 676 | info->ndcb1 = ((page_addr & 0xFFFFFF) << 8) |
| 677 | | (column & 0xFF); | ||
| 539 | 678 | ||
| 540 | host = info->host[info->cs]; | 679 | info->ndcb2 = 0; |
| 541 | mtd = host->mtd; | 680 | } else { |
| 542 | addr_cycle = 0; | 681 | info->ndcb1 = ((page_addr & 0xFFFF) << 16) |
| 543 | exec_cmd = 1; | 682 | | (column & 0xFFFF); |
| 683 | |||
| 684 | if (page_addr & 0xFF0000) | ||
| 685 | info->ndcb2 = (page_addr & 0xFF0000) >> 16; | ||
| 686 | else | ||
| 687 | info->ndcb2 = 0; | ||
| 688 | } | ||
| 689 | } | ||
| 690 | |||
| 691 | static void prepare_start_command(struct pxa3xx_nand_info *info, int command) | ||
| 692 | { | ||
| 693 | struct pxa3xx_nand_host *host = info->host[info->cs]; | ||
| 694 | struct mtd_info *mtd = host->mtd; | ||
| 544 | 695 | ||
| 545 | /* reset data and oob column point to handle data */ | 696 | /* reset data and oob column point to handle data */ |
| 546 | info->buf_start = 0; | 697 | info->buf_start = 0; |
| 547 | info->buf_count = 0; | 698 | info->buf_count = 0; |
| 548 | info->oob_size = 0; | 699 | info->oob_size = 0; |
| 700 | info->data_buff_pos = 0; | ||
| 701 | info->oob_buff_pos = 0; | ||
| 549 | info->use_ecc = 0; | 702 | info->use_ecc = 0; |
| 550 | info->use_spare = 1; | 703 | info->use_spare = 1; |
| 551 | info->is_ready = 0; | ||
| 552 | info->retcode = ERR_NONE; | 704 | info->retcode = ERR_NONE; |
| 553 | if (info->cs != 0) | 705 | info->ecc_err_cnt = 0; |
| 554 | info->ndcb0 = NDCB0_CSEL; | 706 | info->ndcb3 = 0; |
| 555 | else | 707 | info->need_wait = 0; |
| 556 | info->ndcb0 = 0; | ||
| 557 | 708 | ||
| 558 | switch (command) { | 709 | switch (command) { |
| 559 | case NAND_CMD_READ0: | 710 | case NAND_CMD_READ0: |
| 560 | case NAND_CMD_PAGEPROG: | 711 | case NAND_CMD_PAGEPROG: |
| 561 | info->use_ecc = 1; | 712 | info->use_ecc = 1; |
| 562 | case NAND_CMD_READOOB: | 713 | case NAND_CMD_READOOB: |
| 563 | pxa3xx_set_datasize(info); | 714 | pxa3xx_set_datasize(info, mtd); |
| 564 | break; | 715 | break; |
| 565 | case NAND_CMD_PARAM: | 716 | case NAND_CMD_PARAM: |
| 566 | info->use_spare = 0; | 717 | info->use_spare = 0; |
| 567 | break; | 718 | break; |
| 568 | case NAND_CMD_SEQIN: | ||
| 569 | exec_cmd = 0; | ||
| 570 | break; | ||
| 571 | default: | 719 | default: |
| 572 | info->ndcb1 = 0; | 720 | info->ndcb1 = 0; |
| 573 | info->ndcb2 = 0; | 721 | info->ndcb2 = 0; |
| 574 | info->ndcb3 = 0; | ||
| 575 | break; | 722 | break; |
| 576 | } | 723 | } |
| 577 | 724 | ||
| 725 | /* | ||
| 726 | * If we are about to issue a read command, or about to set | ||
| 727 | * the write address, then clean the data buffer. | ||
| 728 | */ | ||
| 729 | if (command == NAND_CMD_READ0 || | ||
| 730 | command == NAND_CMD_READOOB || | ||
| 731 | command == NAND_CMD_SEQIN) { | ||
| 732 | |||
| 733 | info->buf_count = mtd->writesize + mtd->oobsize; | ||
| 734 | memset(info->data_buff, 0xFF, info->buf_count); | ||
| 735 | } | ||
| 736 | |||
| 737 | } | ||
| 738 | |||
| 739 | static int prepare_set_command(struct pxa3xx_nand_info *info, int command, | ||
| 740 | int ext_cmd_type, uint16_t column, int page_addr) | ||
| 741 | { | ||
| 742 | int addr_cycle, exec_cmd; | ||
| 743 | struct pxa3xx_nand_host *host; | ||
| 744 | struct mtd_info *mtd; | ||
| 745 | |||
| 746 | host = info->host[info->cs]; | ||
| 747 | mtd = host->mtd; | ||
| 748 | addr_cycle = 0; | ||
| 749 | exec_cmd = 1; | ||
| 750 | |||
| 751 | if (info->cs != 0) | ||
| 752 | info->ndcb0 = NDCB0_CSEL; | ||
| 753 | else | ||
| 754 | info->ndcb0 = 0; | ||
| 755 | |||
| 756 | if (command == NAND_CMD_SEQIN) | ||
| 757 | exec_cmd = 0; | ||
| 758 | |||
| 578 | addr_cycle = NDCB0_ADDR_CYC(host->row_addr_cycles | 759 | addr_cycle = NDCB0_ADDR_CYC(host->row_addr_cycles |
| 579 | + host->col_addr_cycles); | 760 | + host->col_addr_cycles); |
| 580 | 761 | ||
| @@ -589,30 +770,42 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command, | |||
| 589 | if (command == NAND_CMD_READOOB) | 770 | if (command == NAND_CMD_READOOB) |
| 590 | info->buf_start += mtd->writesize; | 771 | info->buf_start += mtd->writesize; |
| 591 | 772 | ||
| 592 | /* Second command setting for large pages */ | 773 | /* |
| 593 | if (host->page_size >= PAGE_CHUNK_SIZE) | 774 | * Multiple page read needs an 'extended command type' field, |
| 775 | * which is either naked-read or last-read according to the | ||
| 776 | * state. | ||
| 777 | */ | ||
| 778 | if (mtd->writesize == PAGE_CHUNK_SIZE) { | ||
| 594 | info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8); | 779 | info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8); |
| 780 | } else if (mtd->writesize > PAGE_CHUNK_SIZE) { | ||
| 781 | info->ndcb0 |= NDCB0_DBC | (NAND_CMD_READSTART << 8) | ||
| 782 | | NDCB0_LEN_OVRD | ||
| 783 | | NDCB0_EXT_CMD_TYPE(ext_cmd_type); | ||
| 784 | info->ndcb3 = info->chunk_size + | ||
| 785 | info->oob_size; | ||
| 786 | } | ||
| 787 | |||
| 788 | set_command_address(info, mtd->writesize, column, page_addr); | ||
| 789 | break; | ||
| 595 | 790 | ||
| 596 | case NAND_CMD_SEQIN: | 791 | case NAND_CMD_SEQIN: |
| 597 | /* small page addr setting */ | ||
| 598 | if (unlikely(host->page_size < PAGE_CHUNK_SIZE)) { | ||
| 599 | info->ndcb1 = ((page_addr & 0xFFFFFF) << 8) | ||
| 600 | | (column & 0xFF); | ||
| 601 | 792 | ||
| 602 | info->ndcb2 = 0; | 793 | info->buf_start = column; |
| 603 | } else { | 794 | set_command_address(info, mtd->writesize, 0, page_addr); |
| 604 | info->ndcb1 = ((page_addr & 0xFFFF) << 16) | ||
| 605 | | (column & 0xFFFF); | ||
| 606 | 795 | ||
| 607 | if (page_addr & 0xFF0000) | 796 | /* |
| 608 | info->ndcb2 = (page_addr & 0xFF0000) >> 16; | 797 | * Multiple page programming needs to execute the initial |
| 609 | else | 798 | * SEQIN command that sets the page address. |
| 610 | info->ndcb2 = 0; | 799 | */ |
| 800 | if (mtd->writesize > PAGE_CHUNK_SIZE) { | ||
| 801 | info->ndcb0 |= NDCB0_CMD_TYPE(0x1) | ||
| 802 | | NDCB0_EXT_CMD_TYPE(ext_cmd_type) | ||
| 803 | | addr_cycle | ||
| 804 | | command; | ||
| 805 | /* No data transfer in this case */ | ||
| 806 | info->data_size = 0; | ||
| 807 | exec_cmd = 1; | ||
| 611 | } | 808 | } |
| 612 | |||
| 613 | info->buf_count = mtd->writesize + mtd->oobsize; | ||
| 614 | memset(info->data_buff, 0xFF, info->buf_count); | ||
| 615 | |||
| 616 | break; | 809 | break; |
| 617 | 810 | ||
| 618 | case NAND_CMD_PAGEPROG: | 811 | case NAND_CMD_PAGEPROG: |
| @@ -622,13 +815,40 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command, | |||
| 622 | break; | 815 | break; |
| 623 | } | 816 | } |
| 624 | 817 | ||
| 625 | info->ndcb0 |= NDCB0_CMD_TYPE(0x1) | 818 | /* Second command setting for large pages */ |
| 626 | | NDCB0_AUTO_RS | 819 | if (mtd->writesize > PAGE_CHUNK_SIZE) { |
| 627 | | NDCB0_ST_ROW_EN | 820 | /* |
| 628 | | NDCB0_DBC | 821 | * Multiple page write uses the 'extended command' |
| 629 | | (NAND_CMD_PAGEPROG << 8) | 822 | * field. This can be used to issue a command dispatch |
| 630 | | NAND_CMD_SEQIN | 823 | * or a naked-write depending on the current stage. |
| 631 | | addr_cycle; | 824 | */ |
| 825 | info->ndcb0 |= NDCB0_CMD_TYPE(0x1) | ||
| 826 | | NDCB0_LEN_OVRD | ||
| 827 | | NDCB0_EXT_CMD_TYPE(ext_cmd_type); | ||
| 828 | info->ndcb3 = info->chunk_size + | ||
| 829 | info->oob_size; | ||
| 830 | |||
| 831 | /* | ||
| 832 | * This is the command dispatch that completes a chunked | ||
| 833 | * page program operation. | ||
| 834 | */ | ||
| 835 | if (info->data_size == 0) { | ||
| 836 | info->ndcb0 = NDCB0_CMD_TYPE(0x1) | ||
| 837 | | NDCB0_EXT_CMD_TYPE(ext_cmd_type) | ||
| 838 | | command; | ||
| 839 | info->ndcb1 = 0; | ||
| 840 | info->ndcb2 = 0; | ||
| 841 | info->ndcb3 = 0; | ||
| 842 | } | ||
| 843 | } else { | ||
| 844 | info->ndcb0 |= NDCB0_CMD_TYPE(0x1) | ||
| 845 | | NDCB0_AUTO_RS | ||
| 846 | | NDCB0_ST_ROW_EN | ||
| 847 | | NDCB0_DBC | ||
| 848 | | (NAND_CMD_PAGEPROG << 8) | ||
| 849 | | NAND_CMD_SEQIN | ||
| 850 | | addr_cycle; | ||
| 851 | } | ||
| 632 | break; | 852 | break; |
| 633 | 853 | ||
| 634 | case NAND_CMD_PARAM: | 854 | case NAND_CMD_PARAM: |
| @@ -691,8 +911,8 @@ static int prepare_command_pool(struct pxa3xx_nand_info *info, int command, | |||
| 691 | return exec_cmd; | 911 | return exec_cmd; |
| 692 | } | 912 | } |
| 693 | 913 | ||
| 694 | static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command, | 914 | static void nand_cmdfunc(struct mtd_info *mtd, unsigned command, |
| 695 | int column, int page_addr) | 915 | int column, int page_addr) |
| 696 | { | 916 | { |
| 697 | struct pxa3xx_nand_host *host = mtd->priv; | 917 | struct pxa3xx_nand_host *host = mtd->priv; |
| 698 | struct pxa3xx_nand_info *info = host->info_data; | 918 | struct pxa3xx_nand_info *info = host->info_data; |
| @@ -717,10 +937,15 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command, | |||
| 717 | nand_writel(info, NDTR1CS0, info->ndtr1cs0); | 937 | nand_writel(info, NDTR1CS0, info->ndtr1cs0); |
| 718 | } | 938 | } |
| 719 | 939 | ||
| 940 | prepare_start_command(info, command); | ||
| 941 | |||
| 720 | info->state = STATE_PREPARED; | 942 | info->state = STATE_PREPARED; |
| 721 | exec_cmd = prepare_command_pool(info, command, column, page_addr); | 943 | exec_cmd = prepare_set_command(info, command, 0, column, page_addr); |
| 944 | |||
| 722 | if (exec_cmd) { | 945 | if (exec_cmd) { |
| 723 | init_completion(&info->cmd_complete); | 946 | init_completion(&info->cmd_complete); |
| 947 | init_completion(&info->dev_ready); | ||
| 948 | info->need_wait = 1; | ||
| 724 | pxa3xx_nand_start(info); | 949 | pxa3xx_nand_start(info); |
| 725 | 950 | ||
| 726 | ret = wait_for_completion_timeout(&info->cmd_complete, | 951 | ret = wait_for_completion_timeout(&info->cmd_complete, |
| @@ -734,6 +959,117 @@ static void pxa3xx_nand_cmdfunc(struct mtd_info *mtd, unsigned command, | |||
| 734 | info->state = STATE_IDLE; | 959 | info->state = STATE_IDLE; |
| 735 | } | 960 | } |
| 736 | 961 | ||
| 962 | static void nand_cmdfunc_extended(struct mtd_info *mtd, | ||
| 963 | const unsigned command, | ||
| 964 | int column, int page_addr) | ||
| 965 | { | ||
| 966 | struct pxa3xx_nand_host *host = mtd->priv; | ||
| 967 | struct pxa3xx_nand_info *info = host->info_data; | ||
| 968 | int ret, exec_cmd, ext_cmd_type; | ||
| 969 | |||
| 970 | /* | ||
| 971 | * if this is a x16 device then convert the input | ||
| 972 | * "byte" address into a "word" address appropriate | ||
| 973 | * for indexing a word-oriented device | ||
| 974 | */ | ||
| 975 | if (info->reg_ndcr & NDCR_DWIDTH_M) | ||
| 976 | column /= 2; | ||
| 977 | |||
| 978 | /* | ||
| 979 | * There may be different NAND chip hooked to | ||
| 980 | * different chip select, so check whether | ||
| 981 | * chip select has been changed, if yes, reset the timing | ||
| 982 | */ | ||
| 983 | if (info->cs != host->cs) { | ||
| 984 | info->cs = host->cs; | ||
| 985 | nand_writel(info, NDTR0CS0, info->ndtr0cs0); | ||
| 986 | nand_writel(info, NDTR1CS0, info->ndtr1cs0); | ||
| 987 | } | ||
| 988 | |||
| 989 | /* Select the extended command for the first command */ | ||
| 990 | switch (command) { | ||
| 991 | case NAND_CMD_READ0: | ||
| 992 | case NAND_CMD_READOOB: | ||
| 993 | ext_cmd_type = EXT_CMD_TYPE_MONO; | ||
| 994 | break; | ||
| 995 | case NAND_CMD_SEQIN: | ||
| 996 | ext_cmd_type = EXT_CMD_TYPE_DISPATCH; | ||
| 997 | break; | ||
| 998 | case NAND_CMD_PAGEPROG: | ||
| 999 | ext_cmd_type = EXT_CMD_TYPE_NAKED_RW; | ||
| 1000 | break; | ||
| 1001 | default: | ||
| 1002 | ext_cmd_type = 0; | ||
| 1003 | break; | ||
| 1004 | } | ||
| 1005 | |||
| 1006 | prepare_start_command(info, command); | ||
| 1007 | |||
| 1008 | /* | ||
| 1009 | * Prepare the "is ready" completion before starting a command | ||
| 1010 | * transaction sequence. If the command is not executed the | ||
| 1011 | * completion will be completed, see below. | ||
| 1012 | * | ||
| 1013 | * We can do that inside the loop because the command variable | ||
| 1014 | * is invariant and thus so is the exec_cmd. | ||
| 1015 | */ | ||
| 1016 | info->need_wait = 1; | ||
| 1017 | init_completion(&info->dev_ready); | ||
| 1018 | do { | ||
| 1019 | info->state = STATE_PREPARED; | ||
| 1020 | exec_cmd = prepare_set_command(info, command, ext_cmd_type, | ||
| 1021 | column, page_addr); | ||
| 1022 | if (!exec_cmd) { | ||
| 1023 | info->need_wait = 0; | ||
| 1024 | complete(&info->dev_ready); | ||
| 1025 | break; | ||
| 1026 | } | ||
| 1027 | |||
| 1028 | init_completion(&info->cmd_complete); | ||
| 1029 | pxa3xx_nand_start(info); | ||
| 1030 | |||
| 1031 | ret = wait_for_completion_timeout(&info->cmd_complete, | ||
| 1032 | CHIP_DELAY_TIMEOUT); | ||
| 1033 | if (!ret) { | ||
| 1034 | dev_err(&info->pdev->dev, "Wait time out!!!\n"); | ||
| 1035 | /* Stop State Machine for next command cycle */ | ||
| 1036 | pxa3xx_nand_stop(info); | ||
| 1037 | break; | ||
| 1038 | } | ||
| 1039 | |||
| 1040 | /* Check if the sequence is complete */ | ||
| 1041 | if (info->data_size == 0 && command != NAND_CMD_PAGEPROG) | ||
| 1042 | break; | ||
| 1043 | |||
| 1044 | /* | ||
| 1045 | * After a splitted program command sequence has issued | ||
| 1046 | * the command dispatch, the command sequence is complete. | ||
| 1047 | */ | ||
| 1048 | if (info->data_size == 0 && | ||
| 1049 | command == NAND_CMD_PAGEPROG && | ||
| 1050 | ext_cmd_type == EXT_CMD_TYPE_DISPATCH) | ||
| 1051 | break; | ||
| 1052 | |||
| 1053 | if (command == NAND_CMD_READ0 || command == NAND_CMD_READOOB) { | ||
| 1054 | /* Last read: issue a 'last naked read' */ | ||
| 1055 | if (info->data_size == info->chunk_size) | ||
| 1056 | ext_cmd_type = EXT_CMD_TYPE_LAST_RW; | ||
| 1057 | else | ||
| 1058 | ext_cmd_type = EXT_CMD_TYPE_NAKED_RW; | ||
| 1059 | |||
| 1060 | /* | ||
| 1061 | * If a splitted program command has no more data to transfer, | ||
| 1062 | * the command dispatch must be issued to complete. | ||
| 1063 | */ | ||
| 1064 | } else if (command == NAND_CMD_PAGEPROG && | ||
| 1065 | info->data_size == 0) { | ||
| 1066 | ext_cmd_type = EXT_CMD_TYPE_DISPATCH; | ||
| 1067 | } | ||
| 1068 | } while (1); | ||
| 1069 | |||
| 1070 | info->state = STATE_IDLE; | ||
| 1071 | } | ||
| 1072 | |||
| 737 | static int pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd, | 1073 | static int pxa3xx_nand_write_page_hwecc(struct mtd_info *mtd, |
| 738 | struct nand_chip *chip, const uint8_t *buf, int oob_required) | 1074 | struct nand_chip *chip, const uint8_t *buf, int oob_required) |
| 739 | { | 1075 | { |
| @@ -753,20 +1089,14 @@ static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd, | |||
| 753 | chip->read_buf(mtd, buf, mtd->writesize); | 1089 | chip->read_buf(mtd, buf, mtd->writesize); |
| 754 | chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); | 1090 | chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); |
| 755 | 1091 | ||
| 756 | if (info->retcode == ERR_SBERR) { | 1092 | if (info->retcode == ERR_CORERR && info->use_ecc) { |
| 757 | switch (info->use_ecc) { | 1093 | mtd->ecc_stats.corrected += info->ecc_err_cnt; |
| 758 | case 1: | 1094 | |
| 759 | mtd->ecc_stats.corrected++; | 1095 | } else if (info->retcode == ERR_UNCORERR) { |
| 760 | break; | ||
| 761 | case 0: | ||
| 762 | default: | ||
| 763 | break; | ||
| 764 | } | ||
| 765 | } else if (info->retcode == ERR_DBERR) { | ||
| 766 | /* | 1096 | /* |
| 767 | * for blank page (all 0xff), HW will calculate its ECC as | 1097 | * for blank page (all 0xff), HW will calculate its ECC as |
| 768 | * 0, which is different from the ECC information within | 1098 | * 0, which is different from the ECC information within |
| 769 | * OOB, ignore such double bit errors | 1099 | * OOB, ignore such uncorrectable errors |
| 770 | */ | 1100 | */ |
| 771 | if (is_buf_blank(buf, mtd->writesize)) | 1101 | if (is_buf_blank(buf, mtd->writesize)) |
| 772 | info->retcode = ERR_NONE; | 1102 | info->retcode = ERR_NONE; |
| @@ -774,7 +1104,7 @@ static int pxa3xx_nand_read_page_hwecc(struct mtd_info *mtd, | |||
| 774 | mtd->ecc_stats.failed++; | 1104 | mtd->ecc_stats.failed++; |
| 775 | } | 1105 | } |
| 776 | 1106 | ||
| 777 | return 0; | 1107 | return info->max_bitflips; |
| 778 | } | 1108 | } |
| 779 | 1109 | ||
| 780 | static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd) | 1110 | static uint8_t pxa3xx_nand_read_byte(struct mtd_info *mtd) |
| @@ -833,21 +1163,27 @@ static int pxa3xx_nand_waitfunc(struct mtd_info *mtd, struct nand_chip *this) | |||
| 833 | { | 1163 | { |
| 834 | struct pxa3xx_nand_host *host = mtd->priv; | 1164 | struct pxa3xx_nand_host *host = mtd->priv; |
| 835 | struct pxa3xx_nand_info *info = host->info_data; | 1165 | struct pxa3xx_nand_info *info = host->info_data; |
| 1166 | int ret; | ||
| 1167 | |||
| 1168 | if (info->need_wait) { | ||
| 1169 | ret = wait_for_completion_timeout(&info->dev_ready, | ||
| 1170 | CHIP_DELAY_TIMEOUT); | ||
| 1171 | info->need_wait = 0; | ||
| 1172 | if (!ret) { | ||
| 1173 | dev_err(&info->pdev->dev, "Ready time out!!!\n"); | ||
| 1174 | return NAND_STATUS_FAIL; | ||
| 1175 | } | ||
| 1176 | } | ||
| 836 | 1177 | ||
| 837 | /* pxa3xx_nand_send_command has waited for command complete */ | 1178 | /* pxa3xx_nand_send_command has waited for command complete */ |
| 838 | if (this->state == FL_WRITING || this->state == FL_ERASING) { | 1179 | if (this->state == FL_WRITING || this->state == FL_ERASING) { |
| 839 | if (info->retcode == ERR_NONE) | 1180 | if (info->retcode == ERR_NONE) |
| 840 | return 0; | 1181 | return 0; |
| 841 | else { | 1182 | else |
| 842 | /* | 1183 | return NAND_STATUS_FAIL; |
| 843 | * any error make it return 0x01 which will tell | ||
| 844 | * the caller the erase and write fail | ||
| 845 | */ | ||
| 846 | return 0x01; | ||
| 847 | } | ||
| 848 | } | 1184 | } |
| 849 | 1185 | ||
| 850 | return 0; | 1186 | return NAND_STATUS_READY; |
| 851 | } | 1187 | } |
| 852 | 1188 | ||
| 853 | static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info, | 1189 | static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info, |
| @@ -869,7 +1205,6 @@ static int pxa3xx_nand_config_flash(struct pxa3xx_nand_info *info, | |||
| 869 | } | 1205 | } |
| 870 | 1206 | ||
| 871 | /* calculate flash information */ | 1207 | /* calculate flash information */ |
| 872 | host->page_size = f->page_size; | ||
| 873 | host->read_id_bytes = (f->page_size == 2048) ? 4 : 2; | 1208 | host->read_id_bytes = (f->page_size == 2048) ? 4 : 2; |
| 874 | 1209 | ||
| 875 | /* calculate addressing information */ | 1210 | /* calculate addressing information */ |
| @@ -906,13 +1241,15 @@ static int pxa3xx_nand_detect_config(struct pxa3xx_nand_info *info) | |||
| 906 | uint32_t ndcr = nand_readl(info, NDCR); | 1241 | uint32_t ndcr = nand_readl(info, NDCR); |
| 907 | 1242 | ||
| 908 | if (ndcr & NDCR_PAGE_SZ) { | 1243 | if (ndcr & NDCR_PAGE_SZ) { |
| 909 | host->page_size = 2048; | 1244 | /* Controller's FIFO size */ |
| 1245 | info->chunk_size = 2048; | ||
| 910 | host->read_id_bytes = 4; | 1246 | host->read_id_bytes = 4; |
| 911 | } else { | 1247 | } else { |
| 912 | host->page_size = 512; | 1248 | info->chunk_size = 512; |
| 913 | host->read_id_bytes = 2; | 1249 | host->read_id_bytes = 2; |
| 914 | } | 1250 | } |
| 915 | 1251 | ||
| 1252 | /* Set an initial chunk size */ | ||
| 916 | info->reg_ndcr = ndcr & ~NDCR_INT_MASK; | 1253 | info->reg_ndcr = ndcr & ~NDCR_INT_MASK; |
| 917 | info->ndtr0cs0 = nand_readl(info, NDTR0CS0); | 1254 | info->ndtr0cs0 = nand_readl(info, NDTR0CS0); |
| 918 | info->ndtr1cs0 = nand_readl(info, NDTR1CS0); | 1255 | info->ndtr1cs0 = nand_readl(info, NDTR1CS0); |
| @@ -988,18 +1325,89 @@ static void pxa3xx_nand_free_buff(struct pxa3xx_nand_info *info) | |||
| 988 | static int pxa3xx_nand_sensing(struct pxa3xx_nand_info *info) | 1325 | static int pxa3xx_nand_sensing(struct pxa3xx_nand_info *info) |
| 989 | { | 1326 | { |
| 990 | struct mtd_info *mtd; | 1327 | struct mtd_info *mtd; |
| 1328 | struct nand_chip *chip; | ||
| 991 | int ret; | 1329 | int ret; |
| 1330 | |||
| 992 | mtd = info->host[info->cs]->mtd; | 1331 | mtd = info->host[info->cs]->mtd; |
| 1332 | chip = mtd->priv; | ||
| 1333 | |||
| 993 | /* use the common timing to make a try */ | 1334 | /* use the common timing to make a try */ |
| 994 | ret = pxa3xx_nand_config_flash(info, &builtin_flash_types[0]); | 1335 | ret = pxa3xx_nand_config_flash(info, &builtin_flash_types[0]); |
| 995 | if (ret) | 1336 | if (ret) |
| 996 | return ret; | 1337 | return ret; |
| 997 | 1338 | ||
| 998 | pxa3xx_nand_cmdfunc(mtd, NAND_CMD_RESET, 0, 0); | 1339 | chip->cmdfunc(mtd, NAND_CMD_RESET, 0, 0); |
| 999 | if (info->is_ready) | 1340 | ret = chip->waitfunc(mtd, chip); |
| 1000 | return 0; | 1341 | if (ret & NAND_STATUS_FAIL) |
| 1342 | return -ENODEV; | ||
| 1343 | |||
| 1344 | return 0; | ||
| 1345 | } | ||
| 1001 | 1346 | ||
| 1002 | return -ENODEV; | 1347 | static int pxa_ecc_init(struct pxa3xx_nand_info *info, |
| 1348 | struct nand_ecc_ctrl *ecc, | ||
| 1349 | int strength, int ecc_stepsize, int page_size) | ||
| 1350 | { | ||
| 1351 | if (strength == 1 && ecc_stepsize == 512 && page_size == 2048) { | ||
| 1352 | info->chunk_size = 2048; | ||
| 1353 | info->spare_size = 40; | ||
| 1354 | info->ecc_size = 24; | ||
| 1355 | ecc->mode = NAND_ECC_HW; | ||
| 1356 | ecc->size = 512; | ||
| 1357 | ecc->strength = 1; | ||
| 1358 | return 1; | ||
| 1359 | |||
| 1360 | } else if (strength == 1 && ecc_stepsize == 512 && page_size == 512) { | ||
| 1361 | info->chunk_size = 512; | ||
| 1362 | info->spare_size = 8; | ||
| 1363 | info->ecc_size = 8; | ||
| 1364 | ecc->mode = NAND_ECC_HW; | ||
| 1365 | ecc->size = 512; | ||
| 1366 | ecc->strength = 1; | ||
| 1367 | return 1; | ||
| 1368 | |||
| 1369 | /* | ||
| 1370 | * Required ECC: 4-bit correction per 512 bytes | ||
| 1371 | * Select: 16-bit correction per 2048 bytes | ||
| 1372 | */ | ||
| 1373 | } else if (strength == 4 && ecc_stepsize == 512 && page_size == 2048) { | ||
| 1374 | info->ecc_bch = 1; | ||
| 1375 | info->chunk_size = 2048; | ||
| 1376 | info->spare_size = 32; | ||
| 1377 | info->ecc_size = 32; | ||
| 1378 | ecc->mode = NAND_ECC_HW; | ||
| 1379 | ecc->size = info->chunk_size; | ||
| 1380 | ecc->layout = &ecc_layout_2KB_bch4bit; | ||
| 1381 | ecc->strength = 16; | ||
| 1382 | return 1; | ||
| 1383 | |||
| 1384 | } else if (strength == 4 && ecc_stepsize == 512 && page_size == 4096) { | ||
| 1385 | info->ecc_bch = 1; | ||
| 1386 | info->chunk_size = 2048; | ||
| 1387 | info->spare_size = 32; | ||
| 1388 | info->ecc_size = 32; | ||
| 1389 | ecc->mode = NAND_ECC_HW; | ||
| 1390 | ecc->size = info->chunk_size; | ||
| 1391 | ecc->layout = &ecc_layout_4KB_bch4bit; | ||
| 1392 | ecc->strength = 16; | ||
| 1393 | return 1; | ||
| 1394 | |||
| 1395 | /* | ||
| 1396 | * Required ECC: 8-bit correction per 512 bytes | ||
| 1397 | * Select: 16-bit correction per 1024 bytes | ||
| 1398 | */ | ||
| 1399 | } else if (strength == 8 && ecc_stepsize == 512 && page_size == 4096) { | ||
| 1400 | info->ecc_bch = 1; | ||
| 1401 | info->chunk_size = 1024; | ||
| 1402 | info->spare_size = 0; | ||
| 1403 | info->ecc_size = 32; | ||
| 1404 | ecc->mode = NAND_ECC_HW; | ||
| 1405 | ecc->size = info->chunk_size; | ||
| 1406 | ecc->layout = &ecc_layout_4KB_bch8bit; | ||
| 1407 | ecc->strength = 16; | ||
| 1408 | return 1; | ||
| 1409 | } | ||
| 1410 | return 0; | ||
| 1003 | } | 1411 | } |
| 1004 | 1412 | ||
| 1005 | static int pxa3xx_nand_scan(struct mtd_info *mtd) | 1413 | static int pxa3xx_nand_scan(struct mtd_info *mtd) |
| @@ -1014,6 +1422,7 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) | |||
| 1014 | uint32_t id = -1; | 1422 | uint32_t id = -1; |
| 1015 | uint64_t chipsize; | 1423 | uint64_t chipsize; |
| 1016 | int i, ret, num; | 1424 | int i, ret, num; |
| 1425 | uint16_t ecc_strength, ecc_step; | ||
| 1017 | 1426 | ||
| 1018 | if (pdata->keep_config && !pxa3xx_nand_detect_config(info)) | 1427 | if (pdata->keep_config && !pxa3xx_nand_detect_config(info)) |
| 1019 | goto KEEP_CONFIG; | 1428 | goto KEEP_CONFIG; |
| @@ -1072,15 +1481,60 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd) | |||
| 1072 | pxa3xx_flash_ids[1].name = NULL; | 1481 | pxa3xx_flash_ids[1].name = NULL; |
| 1073 | def = pxa3xx_flash_ids; | 1482 | def = pxa3xx_flash_ids; |
| 1074 | KEEP_CONFIG: | 1483 | KEEP_CONFIG: |
| 1075 | chip->ecc.mode = NAND_ECC_HW; | ||
| 1076 | chip->ecc.size = host->page_size; | ||
| 1077 | chip->ecc.strength = 1; | ||
| 1078 | |||
| 1079 | if (info->reg_ndcr & NDCR_DWIDTH_M) | 1484 | if (info->reg_ndcr & NDCR_DWIDTH_M) |
| 1080 | chip->options |= NAND_BUSWIDTH_16; | 1485 | chip->options |= NAND_BUSWIDTH_16; |
| 1081 | 1486 | ||
| 1487 | /* Device detection must be done with ECC disabled */ | ||
| 1488 | if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370) | ||
| 1489 | nand_writel(info, NDECCCTRL, 0x0); | ||
| 1490 | |||
| 1082 | if (nand_scan_ident(mtd, 1, def)) | 1491 | if (nand_scan_ident(mtd, 1, def)) |
| 1083 | return -ENODEV; | 1492 | return -ENODEV; |
| 1493 | |||
| 1494 | if (pdata->flash_bbt) { | ||
| 1495 | /* | ||
| 1496 | * We'll use a bad block table stored in-flash and don't | ||
| 1497 | * allow writing the bad block marker to the flash. | ||
| 1498 | */ | ||
| 1499 | chip->bbt_options |= NAND_BBT_USE_FLASH | | ||
| 1500 | NAND_BBT_NO_OOB_BBM; | ||
| 1501 | chip->bbt_td = &bbt_main_descr; | ||
| 1502 | chip->bbt_md = &bbt_mirror_descr; | ||
| 1503 | } | ||
| 1504 | |||
| 1505 | /* | ||
| 1506 | * If the page size is bigger than the FIFO size, let's check | ||
| 1507 | * we are given the right variant and then switch to the extended | ||
| 1508 | * (aka splitted) command handling, | ||
| 1509 | */ | ||
| 1510 | if (mtd->writesize > PAGE_CHUNK_SIZE) { | ||
| 1511 | if (info->variant == PXA3XX_NAND_VARIANT_ARMADA370) { | ||
| 1512 | chip->cmdfunc = nand_cmdfunc_extended; | ||
| 1513 | } else { | ||
| 1514 | dev_err(&info->pdev->dev, | ||
| 1515 | "unsupported page size on this variant\n"); | ||
| 1516 | return -ENODEV; | ||
| 1517 | } | ||
| 1518 | } | ||
| 1519 | |||
| 1520 | ecc_strength = chip->ecc_strength_ds; | ||
| 1521 | ecc_step = chip->ecc_step_ds; | ||
| 1522 | |||
| 1523 | /* Set default ECC strength requirements on non-ONFI devices */ | ||
| 1524 | if (ecc_strength < 1 && ecc_step < 1) { | ||
| 1525 | ecc_strength = 1; | ||
| 1526 | ecc_step = 512; | ||
| 1527 | } | ||
| 1528 | |||
| 1529 | ret = pxa_ecc_init(info, &chip->ecc, ecc_strength, | ||
| 1530 | ecc_step, mtd->writesize); | ||
| 1531 | if (!ret) { | ||
| 1532 | dev_err(&info->pdev->dev, | ||
| 1533 | "ECC strength %d at page size %d is not supported\n", | ||
| 1534 | chip->ecc_strength_ds, mtd->writesize); | ||
| 1535 | return -ENODEV; | ||
| 1536 | } | ||
| 1537 | |||
| 1084 | /* calculate addressing information */ | 1538 | /* calculate addressing information */ |
| 1085 | if (mtd->writesize >= 2048) | 1539 | if (mtd->writesize >= 2048) |
| 1086 | host->col_addr_cycles = 2; | 1540 | host->col_addr_cycles = 2; |
| @@ -1121,6 +1575,7 @@ static int alloc_nand_resource(struct platform_device *pdev) | |||
| 1121 | return -ENOMEM; | 1575 | return -ENOMEM; |
| 1122 | 1576 | ||
| 1123 | info->pdev = pdev; | 1577 | info->pdev = pdev; |
| 1578 | info->variant = pxa3xx_nand_get_variant(pdev); | ||
| 1124 | for (cs = 0; cs < pdata->num_cs; cs++) { | 1579 | for (cs = 0; cs < pdata->num_cs; cs++) { |
| 1125 | mtd = (struct mtd_info *)((unsigned int)&info[1] + | 1580 | mtd = (struct mtd_info *)((unsigned int)&info[1] + |
| 1126 | (sizeof(*mtd) + sizeof(*host)) * cs); | 1581 | (sizeof(*mtd) + sizeof(*host)) * cs); |
| @@ -1138,11 +1593,12 @@ static int alloc_nand_resource(struct platform_device *pdev) | |||
| 1138 | chip->controller = &info->controller; | 1593 | chip->controller = &info->controller; |
| 1139 | chip->waitfunc = pxa3xx_nand_waitfunc; | 1594 | chip->waitfunc = pxa3xx_nand_waitfunc; |
| 1140 | chip->select_chip = pxa3xx_nand_select_chip; | 1595 | chip->select_chip = pxa3xx_nand_select_chip; |
| 1141 | chip->cmdfunc = pxa3xx_nand_cmdfunc; | ||
| 1142 | chip->read_word = pxa3xx_nand_read_word; | 1596 | chip->read_word = pxa3xx_nand_read_word; |
| 1143 | chip->read_byte = pxa3xx_nand_read_byte; | 1597 | chip->read_byte = pxa3xx_nand_read_byte; |
| 1144 | chip->read_buf = pxa3xx_nand_read_buf; | 1598 | chip->read_buf = pxa3xx_nand_read_buf; |
| 1145 | chip->write_buf = pxa3xx_nand_write_buf; | 1599 | chip->write_buf = pxa3xx_nand_write_buf; |
| 1600 | chip->options |= NAND_NO_SUBPAGE_WRITE; | ||
| 1601 | chip->cmdfunc = nand_cmdfunc; | ||
| 1146 | } | 1602 | } |
| 1147 | 1603 | ||
| 1148 | spin_lock_init(&chip->controller->lock); | 1604 | spin_lock_init(&chip->controller->lock); |
| @@ -1254,25 +1710,6 @@ static int pxa3xx_nand_remove(struct platform_device *pdev) | |||
| 1254 | return 0; | 1710 | return 0; |
| 1255 | } | 1711 | } |
| 1256 | 1712 | ||
| 1257 | static struct of_device_id pxa3xx_nand_dt_ids[] = { | ||
| 1258 | { | ||
| 1259 | .compatible = "marvell,pxa3xx-nand", | ||
| 1260 | .data = (void *)PXA3XX_NAND_VARIANT_PXA, | ||
| 1261 | }, | ||
| 1262 | {} | ||
| 1263 | }; | ||
| 1264 | MODULE_DEVICE_TABLE(of, pxa3xx_nand_dt_ids); | ||
| 1265 | |||
| 1266 | static enum pxa3xx_nand_variant | ||
| 1267 | pxa3xx_nand_get_variant(struct platform_device *pdev) | ||
| 1268 | { | ||
| 1269 | const struct of_device_id *of_id = | ||
| 1270 | of_match_device(pxa3xx_nand_dt_ids, &pdev->dev); | ||
| 1271 | if (!of_id) | ||
| 1272 | return PXA3XX_NAND_VARIANT_PXA; | ||
| 1273 | return (enum pxa3xx_nand_variant)of_id->data; | ||
| 1274 | } | ||
| 1275 | |||
| 1276 | static int pxa3xx_nand_probe_dt(struct platform_device *pdev) | 1713 | static int pxa3xx_nand_probe_dt(struct platform_device *pdev) |
| 1277 | { | 1714 | { |
| 1278 | struct pxa3xx_nand_platform_data *pdata; | 1715 | struct pxa3xx_nand_platform_data *pdata; |
| @@ -1292,6 +1729,7 @@ static int pxa3xx_nand_probe_dt(struct platform_device *pdev) | |||
| 1292 | if (of_get_property(np, "marvell,nand-keep-config", NULL)) | 1729 | if (of_get_property(np, "marvell,nand-keep-config", NULL)) |
| 1293 | pdata->keep_config = 1; | 1730 | pdata->keep_config = 1; |
| 1294 | of_property_read_u32(np, "num-cs", &pdata->num_cs); | 1731 | of_property_read_u32(np, "num-cs", &pdata->num_cs); |
| 1732 | pdata->flash_bbt = of_get_nand_on_flash_bbt(np); | ||
| 1295 | 1733 | ||
| 1296 | pdev->dev.platform_data = pdata; | 1734 | pdev->dev.platform_data = pdata; |
| 1297 | 1735 | ||
| @@ -1329,7 +1767,6 @@ static int pxa3xx_nand_probe(struct platform_device *pdev) | |||
| 1329 | } | 1767 | } |
| 1330 | 1768 | ||
| 1331 | info = platform_get_drvdata(pdev); | 1769 | info = platform_get_drvdata(pdev); |
| 1332 | info->variant = pxa3xx_nand_get_variant(pdev); | ||
| 1333 | probe_success = 0; | 1770 | probe_success = 0; |
| 1334 | for (cs = 0; cs < pdata->num_cs; cs++) { | 1771 | for (cs = 0; cs < pdata->num_cs; cs++) { |
| 1335 | struct mtd_info *mtd = info->host[cs]->mtd; | 1772 | struct mtd_info *mtd = info->host[cs]->mtd; |
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index d65cbe903d40..f0918e7411d9 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c | |||
| @@ -46,9 +46,43 @@ | |||
| 46 | #include <linux/mtd/nand_ecc.h> | 46 | #include <linux/mtd/nand_ecc.h> |
| 47 | #include <linux/mtd/partitions.h> | 47 | #include <linux/mtd/partitions.h> |
| 48 | 48 | ||
| 49 | #include <plat/regs-nand.h> | ||
| 50 | #include <linux/platform_data/mtd-nand-s3c2410.h> | 49 | #include <linux/platform_data/mtd-nand-s3c2410.h> |
| 51 | 50 | ||
| 51 | #define S3C2410_NFREG(x) (x) | ||
| 52 | |||
| 53 | #define S3C2410_NFCONF S3C2410_NFREG(0x00) | ||
| 54 | #define S3C2410_NFCMD S3C2410_NFREG(0x04) | ||
| 55 | #define S3C2410_NFADDR S3C2410_NFREG(0x08) | ||
| 56 | #define S3C2410_NFDATA S3C2410_NFREG(0x0C) | ||
| 57 | #define S3C2410_NFSTAT S3C2410_NFREG(0x10) | ||
| 58 | #define S3C2410_NFECC S3C2410_NFREG(0x14) | ||
| 59 | #define S3C2440_NFCONT S3C2410_NFREG(0x04) | ||
| 60 | #define S3C2440_NFCMD S3C2410_NFREG(0x08) | ||
| 61 | #define S3C2440_NFADDR S3C2410_NFREG(0x0C) | ||
| 62 | #define S3C2440_NFDATA S3C2410_NFREG(0x10) | ||
| 63 | #define S3C2440_NFSTAT S3C2410_NFREG(0x20) | ||
| 64 | #define S3C2440_NFMECC0 S3C2410_NFREG(0x2C) | ||
| 65 | #define S3C2412_NFSTAT S3C2410_NFREG(0x28) | ||
| 66 | #define S3C2412_NFMECC0 S3C2410_NFREG(0x34) | ||
| 67 | #define S3C2410_NFCONF_EN (1<<15) | ||
| 68 | #define S3C2410_NFCONF_INITECC (1<<12) | ||
| 69 | #define S3C2410_NFCONF_nFCE (1<<11) | ||
| 70 | #define S3C2410_NFCONF_TACLS(x) ((x)<<8) | ||
| 71 | #define S3C2410_NFCONF_TWRPH0(x) ((x)<<4) | ||
| 72 | #define S3C2410_NFCONF_TWRPH1(x) ((x)<<0) | ||
| 73 | #define S3C2410_NFSTAT_BUSY (1<<0) | ||
| 74 | #define S3C2440_NFCONF_TACLS(x) ((x)<<12) | ||
| 75 | #define S3C2440_NFCONF_TWRPH0(x) ((x)<<8) | ||
| 76 | #define S3C2440_NFCONF_TWRPH1(x) ((x)<<4) | ||
| 77 | #define S3C2440_NFCONT_INITECC (1<<4) | ||
| 78 | #define S3C2440_NFCONT_nFCE (1<<1) | ||
| 79 | #define S3C2440_NFCONT_ENABLE (1<<0) | ||
| 80 | #define S3C2440_NFSTAT_READY (1<<0) | ||
| 81 | #define S3C2412_NFCONF_NANDBOOT (1<<31) | ||
| 82 | #define S3C2412_NFCONT_INIT_MAIN_ECC (1<<5) | ||
| 83 | #define S3C2412_NFCONT_nFCE0 (1<<1) | ||
| 84 | #define S3C2412_NFSTAT_READY (1<<0) | ||
| 85 | |||
| 52 | /* new oob placement block for use with hardware ecc generation | 86 | /* new oob placement block for use with hardware ecc generation |
| 53 | */ | 87 | */ |
| 54 | 88 | ||
| @@ -919,7 +953,6 @@ static int s3c24xx_nand_probe(struct platform_device *pdev) | |||
| 919 | 953 | ||
| 920 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); | 954 | info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); |
| 921 | if (info == NULL) { | 955 | if (info == NULL) { |
| 922 | dev_err(&pdev->dev, "no memory for flash info\n"); | ||
| 923 | err = -ENOMEM; | 956 | err = -ENOMEM; |
| 924 | goto exit_error; | 957 | goto exit_error; |
| 925 | } | 958 | } |
| @@ -974,7 +1007,6 @@ static int s3c24xx_nand_probe(struct platform_device *pdev) | |||
| 974 | size = nr_sets * sizeof(*info->mtds); | 1007 | size = nr_sets * sizeof(*info->mtds); |
| 975 | info->mtds = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); | 1008 | info->mtds = devm_kzalloc(&pdev->dev, size, GFP_KERNEL); |
| 976 | if (info->mtds == NULL) { | 1009 | if (info->mtds == NULL) { |
| 977 | dev_err(&pdev->dev, "failed to allocate mtd storage\n"); | ||
| 978 | err = -ENOMEM; | 1010 | err = -ENOMEM; |
| 979 | goto exit_error; | 1011 | goto exit_error; |
| 980 | } | 1012 | } |
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c index a3c84ebbe392..d72783dd7b96 100644 --- a/drivers/mtd/nand/sh_flctl.c +++ b/drivers/mtd/nand/sh_flctl.c | |||
| @@ -151,7 +151,7 @@ static void flctl_setup_dma(struct sh_flctl *flctl) | |||
| 151 | dma_cap_set(DMA_SLAVE, mask); | 151 | dma_cap_set(DMA_SLAVE, mask); |
| 152 | 152 | ||
| 153 | flctl->chan_fifo0_tx = dma_request_channel(mask, shdma_chan_filter, | 153 | flctl->chan_fifo0_tx = dma_request_channel(mask, shdma_chan_filter, |
| 154 | (void *)pdata->slave_id_fifo0_tx); | 154 | (void *)(uintptr_t)pdata->slave_id_fifo0_tx); |
| 155 | dev_dbg(&pdev->dev, "%s: TX: got channel %p\n", __func__, | 155 | dev_dbg(&pdev->dev, "%s: TX: got channel %p\n", __func__, |
| 156 | flctl->chan_fifo0_tx); | 156 | flctl->chan_fifo0_tx); |
| 157 | 157 | ||
| @@ -168,7 +168,7 @@ static void flctl_setup_dma(struct sh_flctl *flctl) | |||
| 168 | goto err; | 168 | goto err; |
| 169 | 169 | ||
| 170 | flctl->chan_fifo0_rx = dma_request_channel(mask, shdma_chan_filter, | 170 | flctl->chan_fifo0_rx = dma_request_channel(mask, shdma_chan_filter, |
| 171 | (void *)pdata->slave_id_fifo0_rx); | 171 | (void *)(uintptr_t)pdata->slave_id_fifo0_rx); |
| 172 | dev_dbg(&pdev->dev, "%s: RX: got channel %p\n", __func__, | 172 | dev_dbg(&pdev->dev, "%s: RX: got channel %p\n", __func__, |
| 173 | flctl->chan_fifo0_rx); | 173 | flctl->chan_fifo0_rx); |
| 174 | 174 | ||
| @@ -1021,7 +1021,6 @@ static irqreturn_t flctl_handle_flste(int irq, void *dev_id) | |||
| 1021 | return IRQ_HANDLED; | 1021 | return IRQ_HANDLED; |
| 1022 | } | 1022 | } |
| 1023 | 1023 | ||
| 1024 | #ifdef CONFIG_OF | ||
| 1025 | struct flctl_soc_config { | 1024 | struct flctl_soc_config { |
| 1026 | unsigned long flcmncr_val; | 1025 | unsigned long flcmncr_val; |
| 1027 | unsigned has_hwecc:1; | 1026 | unsigned has_hwecc:1; |
| @@ -1059,10 +1058,8 @@ static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev) | |||
| 1059 | 1058 | ||
| 1060 | pdata = devm_kzalloc(dev, sizeof(struct sh_flctl_platform_data), | 1059 | pdata = devm_kzalloc(dev, sizeof(struct sh_flctl_platform_data), |
| 1061 | GFP_KERNEL); | 1060 | GFP_KERNEL); |
| 1062 | if (!pdata) { | 1061 | if (!pdata) |
| 1063 | dev_err(dev, "%s: failed to allocate config data\n", __func__); | ||
| 1064 | return NULL; | 1062 | return NULL; |
| 1065 | } | ||
| 1066 | 1063 | ||
| 1067 | /* set SoC specific options */ | 1064 | /* set SoC specific options */ |
| 1068 | pdata->flcmncr_val = config->flcmncr_val; | 1065 | pdata->flcmncr_val = config->flcmncr_val; |
| @@ -1080,12 +1077,6 @@ static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev) | |||
| 1080 | 1077 | ||
| 1081 | return pdata; | 1078 | return pdata; |
| 1082 | } | 1079 | } |
| 1083 | #else /* CONFIG_OF */ | ||
| 1084 | static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev) | ||
| 1085 | { | ||
| 1086 | return NULL; | ||
| 1087 | } | ||
| 1088 | #endif /* CONFIG_OF */ | ||
| 1089 | 1080 | ||
| 1090 | static int flctl_probe(struct platform_device *pdev) | 1081 | static int flctl_probe(struct platform_device *pdev) |
| 1091 | { | 1082 | { |
| @@ -1094,38 +1085,30 @@ static int flctl_probe(struct platform_device *pdev) | |||
| 1094 | struct mtd_info *flctl_mtd; | 1085 | struct mtd_info *flctl_mtd; |
| 1095 | struct nand_chip *nand; | 1086 | struct nand_chip *nand; |
| 1096 | struct sh_flctl_platform_data *pdata; | 1087 | struct sh_flctl_platform_data *pdata; |
| 1097 | int ret = -ENXIO; | 1088 | int ret; |
| 1098 | int irq; | 1089 | int irq; |
| 1099 | struct mtd_part_parser_data ppdata = {}; | 1090 | struct mtd_part_parser_data ppdata = {}; |
| 1100 | 1091 | ||
| 1101 | flctl = kzalloc(sizeof(struct sh_flctl), GFP_KERNEL); | 1092 | flctl = devm_kzalloc(&pdev->dev, sizeof(struct sh_flctl), GFP_KERNEL); |
| 1102 | if (!flctl) { | 1093 | if (!flctl) |
| 1103 | dev_err(&pdev->dev, "failed to allocate driver data\n"); | ||
| 1104 | return -ENOMEM; | 1094 | return -ENOMEM; |
| 1105 | } | ||
| 1106 | 1095 | ||
| 1107 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1096 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 1108 | if (!res) { | 1097 | flctl->reg = devm_ioremap_resource(&pdev->dev, res); |
| 1109 | dev_err(&pdev->dev, "failed to get I/O memory\n"); | 1098 | if (IS_ERR(flctl->reg)) |
| 1110 | goto err_iomap; | 1099 | return PTR_ERR(flctl->reg); |
| 1111 | } | ||
| 1112 | |||
| 1113 | flctl->reg = ioremap(res->start, resource_size(res)); | ||
| 1114 | if (flctl->reg == NULL) { | ||
| 1115 | dev_err(&pdev->dev, "failed to remap I/O memory\n"); | ||
| 1116 | goto err_iomap; | ||
| 1117 | } | ||
| 1118 | 1100 | ||
| 1119 | irq = platform_get_irq(pdev, 0); | 1101 | irq = platform_get_irq(pdev, 0); |
| 1120 | if (irq < 0) { | 1102 | if (irq < 0) { |
| 1121 | dev_err(&pdev->dev, "failed to get flste irq data\n"); | 1103 | dev_err(&pdev->dev, "failed to get flste irq data\n"); |
| 1122 | goto err_flste; | 1104 | return -ENXIO; |
| 1123 | } | 1105 | } |
| 1124 | 1106 | ||
| 1125 | ret = request_irq(irq, flctl_handle_flste, IRQF_SHARED, "flste", flctl); | 1107 | ret = devm_request_irq(&pdev->dev, irq, flctl_handle_flste, IRQF_SHARED, |
| 1108 | "flste", flctl); | ||
| 1126 | if (ret) { | 1109 | if (ret) { |
| 1127 | dev_err(&pdev->dev, "request interrupt failed.\n"); | 1110 | dev_err(&pdev->dev, "request interrupt failed.\n"); |
| 1128 | goto err_flste; | 1111 | return ret; |
| 1129 | } | 1112 | } |
| 1130 | 1113 | ||
| 1131 | if (pdev->dev.of_node) | 1114 | if (pdev->dev.of_node) |
| @@ -1135,8 +1118,7 @@ static int flctl_probe(struct platform_device *pdev) | |||
| 1135 | 1118 | ||
| 1136 | if (!pdata) { | 1119 | if (!pdata) { |
| 1137 | dev_err(&pdev->dev, "no setup data defined\n"); | 1120 | dev_err(&pdev->dev, "no setup data defined\n"); |
| 1138 | ret = -EINVAL; | 1121 | return -EINVAL; |
| 1139 | goto err_pdata; | ||
| 1140 | } | 1122 | } |
| 1141 | 1123 | ||
| 1142 | platform_set_drvdata(pdev, flctl); | 1124 | platform_set_drvdata(pdev, flctl); |
| @@ -1190,12 +1172,6 @@ static int flctl_probe(struct platform_device *pdev) | |||
| 1190 | err_chip: | 1172 | err_chip: |
| 1191 | flctl_release_dma(flctl); | 1173 | flctl_release_dma(flctl); |
| 1192 | pm_runtime_disable(&pdev->dev); | 1174 | pm_runtime_disable(&pdev->dev); |
| 1193 | err_pdata: | ||
| 1194 | free_irq(irq, flctl); | ||
| 1195 | err_flste: | ||
| 1196 | iounmap(flctl->reg); | ||
| 1197 | err_iomap: | ||
| 1198 | kfree(flctl); | ||
| 1199 | return ret; | 1175 | return ret; |
| 1200 | } | 1176 | } |
| 1201 | 1177 | ||
| @@ -1206,9 +1182,6 @@ static int flctl_remove(struct platform_device *pdev) | |||
| 1206 | flctl_release_dma(flctl); | 1182 | flctl_release_dma(flctl); |
| 1207 | nand_release(&flctl->mtd); | 1183 | nand_release(&flctl->mtd); |
| 1208 | pm_runtime_disable(&pdev->dev); | 1184 | pm_runtime_disable(&pdev->dev); |
| 1209 | free_irq(platform_get_irq(pdev, 0), flctl); | ||
| 1210 | iounmap(flctl->reg); | ||
| 1211 | kfree(flctl); | ||
| 1212 | 1185 | ||
| 1213 | return 0; | 1186 | return 0; |
| 1214 | } | 1187 | } |
diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c index 87908d760feb..e81059b58382 100644 --- a/drivers/mtd/nand/sharpsl.c +++ b/drivers/mtd/nand/sharpsl.c | |||
| @@ -121,10 +121,8 @@ static int sharpsl_nand_probe(struct platform_device *pdev) | |||
| 121 | 121 | ||
| 122 | /* Allocate memory for MTD device structure and private data */ | 122 | /* Allocate memory for MTD device structure and private data */ |
| 123 | sharpsl = kzalloc(sizeof(struct sharpsl_nand), GFP_KERNEL); | 123 | sharpsl = kzalloc(sizeof(struct sharpsl_nand), GFP_KERNEL); |
| 124 | if (!sharpsl) { | 124 | if (!sharpsl) |
| 125 | printk("Unable to allocate SharpSL NAND MTD device structure.\n"); | ||
| 126 | return -ENOMEM; | 125 | return -ENOMEM; |
| 127 | } | ||
| 128 | 126 | ||
| 129 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 127 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 130 | if (!r) { | 128 | if (!r) { |
| @@ -136,7 +134,7 @@ static int sharpsl_nand_probe(struct platform_device *pdev) | |||
| 136 | /* map physical address */ | 134 | /* map physical address */ |
| 137 | sharpsl->io = ioremap(r->start, resource_size(r)); | 135 | sharpsl->io = ioremap(r->start, resource_size(r)); |
| 138 | if (!sharpsl->io) { | 136 | if (!sharpsl->io) { |
| 139 | printk("ioremap to access Sharp SL NAND chip failed\n"); | 137 | dev_err(&pdev->dev, "ioremap to access Sharp SL NAND chip failed\n"); |
| 140 | err = -EIO; | 138 | err = -EIO; |
| 141 | goto err_ioremap; | 139 | goto err_ioremap; |
| 142 | } | 140 | } |
diff --git a/drivers/mtd/nand/tmio_nand.c b/drivers/mtd/nand/tmio_nand.c index a3747c914d57..fb8fd35fa668 100644 --- a/drivers/mtd/nand/tmio_nand.c +++ b/drivers/mtd/nand/tmio_nand.c | |||
| @@ -371,11 +371,9 @@ static int tmio_probe(struct platform_device *dev) | |||
| 371 | if (data == NULL) | 371 | if (data == NULL) |
| 372 | dev_warn(&dev->dev, "NULL platform data!\n"); | 372 | dev_warn(&dev->dev, "NULL platform data!\n"); |
| 373 | 373 | ||
| 374 | tmio = kzalloc(sizeof *tmio, GFP_KERNEL); | 374 | tmio = devm_kzalloc(&dev->dev, sizeof(*tmio), GFP_KERNEL); |
| 375 | if (!tmio) { | 375 | if (!tmio) |
| 376 | retval = -ENOMEM; | 376 | return -ENOMEM; |
| 377 | goto err_kzalloc; | ||
| 378 | } | ||
| 379 | 377 | ||
| 380 | tmio->dev = dev; | 378 | tmio->dev = dev; |
| 381 | 379 | ||
| @@ -385,22 +383,18 @@ static int tmio_probe(struct platform_device *dev) | |||
| 385 | mtd->priv = nand_chip; | 383 | mtd->priv = nand_chip; |
| 386 | mtd->name = "tmio-nand"; | 384 | mtd->name = "tmio-nand"; |
| 387 | 385 | ||
| 388 | tmio->ccr = ioremap(ccr->start, resource_size(ccr)); | 386 | tmio->ccr = devm_ioremap(&dev->dev, ccr->start, resource_size(ccr)); |
| 389 | if (!tmio->ccr) { | 387 | if (!tmio->ccr) |
| 390 | retval = -EIO; | 388 | return -EIO; |
| 391 | goto err_iomap_ccr; | ||
| 392 | } | ||
| 393 | 389 | ||
| 394 | tmio->fcr_base = fcr->start & 0xfffff; | 390 | tmio->fcr_base = fcr->start & 0xfffff; |
| 395 | tmio->fcr = ioremap(fcr->start, resource_size(fcr)); | 391 | tmio->fcr = devm_ioremap(&dev->dev, fcr->start, resource_size(fcr)); |
| 396 | if (!tmio->fcr) { | 392 | if (!tmio->fcr) |
| 397 | retval = -EIO; | 393 | return -EIO; |
| 398 | goto err_iomap_fcr; | ||
| 399 | } | ||
| 400 | 394 | ||
| 401 | retval = tmio_hw_init(dev, tmio); | 395 | retval = tmio_hw_init(dev, tmio); |
| 402 | if (retval) | 396 | if (retval) |
| 403 | goto err_hwinit; | 397 | return retval; |
| 404 | 398 | ||
| 405 | /* Set address of NAND IO lines */ | 399 | /* Set address of NAND IO lines */ |
| 406 | nand_chip->IO_ADDR_R = tmio->fcr; | 400 | nand_chip->IO_ADDR_R = tmio->fcr; |
| @@ -428,7 +422,8 @@ static int tmio_probe(struct platform_device *dev) | |||
| 428 | /* 15 us command delay time */ | 422 | /* 15 us command delay time */ |
| 429 | nand_chip->chip_delay = 15; | 423 | nand_chip->chip_delay = 15; |
| 430 | 424 | ||
| 431 | retval = request_irq(irq, &tmio_irq, 0, dev_name(&dev->dev), tmio); | 425 | retval = devm_request_irq(&dev->dev, irq, &tmio_irq, 0, |
| 426 | dev_name(&dev->dev), tmio); | ||
| 432 | if (retval) { | 427 | if (retval) { |
| 433 | dev_err(&dev->dev, "request_irq error %d\n", retval); | 428 | dev_err(&dev->dev, "request_irq error %d\n", retval); |
| 434 | goto err_irq; | 429 | goto err_irq; |
| @@ -440,7 +435,7 @@ static int tmio_probe(struct platform_device *dev) | |||
| 440 | /* Scan to find existence of the device */ | 435 | /* Scan to find existence of the device */ |
| 441 | if (nand_scan(mtd, 1)) { | 436 | if (nand_scan(mtd, 1)) { |
| 442 | retval = -ENODEV; | 437 | retval = -ENODEV; |
| 443 | goto err_scan; | 438 | goto err_irq; |
| 444 | } | 439 | } |
| 445 | /* Register the partitions */ | 440 | /* Register the partitions */ |
| 446 | retval = mtd_device_parse_register(mtd, NULL, NULL, | 441 | retval = mtd_device_parse_register(mtd, NULL, NULL, |
| @@ -451,18 +446,8 @@ static int tmio_probe(struct platform_device *dev) | |||
| 451 | 446 | ||
| 452 | nand_release(mtd); | 447 | nand_release(mtd); |
| 453 | 448 | ||
| 454 | err_scan: | ||
| 455 | if (tmio->irq) | ||
| 456 | free_irq(tmio->irq, tmio); | ||
| 457 | err_irq: | 449 | err_irq: |
| 458 | tmio_hw_stop(dev, tmio); | 450 | tmio_hw_stop(dev, tmio); |
| 459 | err_hwinit: | ||
| 460 | iounmap(tmio->fcr); | ||
| 461 | err_iomap_fcr: | ||
| 462 | iounmap(tmio->ccr); | ||
| 463 | err_iomap_ccr: | ||
| 464 | kfree(tmio); | ||
| 465 | err_kzalloc: | ||
| 466 | return retval; | 451 | return retval; |
| 467 | } | 452 | } |
| 468 | 453 | ||
| @@ -471,12 +456,7 @@ static int tmio_remove(struct platform_device *dev) | |||
| 471 | struct tmio_nand *tmio = platform_get_drvdata(dev); | 456 | struct tmio_nand *tmio = platform_get_drvdata(dev); |
| 472 | 457 | ||
| 473 | nand_release(&tmio->mtd); | 458 | nand_release(&tmio->mtd); |
| 474 | if (tmio->irq) | ||
| 475 | free_irq(tmio->irq, tmio); | ||
| 476 | tmio_hw_stop(dev, tmio); | 459 | tmio_hw_stop(dev, tmio); |
| 477 | iounmap(tmio->fcr); | ||
| 478 | iounmap(tmio->ccr); | ||
| 479 | kfree(tmio); | ||
| 480 | return 0; | 460 | return 0; |
| 481 | } | 461 | } |
| 482 | 462 | ||
diff --git a/drivers/mtd/nand/txx9ndfmc.c b/drivers/mtd/nand/txx9ndfmc.c index 235714a421dd..c1622a5ba814 100644 --- a/drivers/mtd/nand/txx9ndfmc.c +++ b/drivers/mtd/nand/txx9ndfmc.c | |||
| @@ -319,11 +319,8 @@ static int __init txx9ndfmc_probe(struct platform_device *dev) | |||
| 319 | continue; | 319 | continue; |
| 320 | txx9_priv = kzalloc(sizeof(struct txx9ndfmc_priv), | 320 | txx9_priv = kzalloc(sizeof(struct txx9ndfmc_priv), |
| 321 | GFP_KERNEL); | 321 | GFP_KERNEL); |
| 322 | if (!txx9_priv) { | 322 | if (!txx9_priv) |
| 323 | dev_err(&dev->dev, "Unable to allocate " | ||
| 324 | "TXx9 NDFMC MTD device structure.\n"); | ||
| 325 | continue; | 323 | continue; |
| 326 | } | ||
| 327 | chip = &txx9_priv->chip; | 324 | chip = &txx9_priv->chip; |
| 328 | mtd = &txx9_priv->mtd; | 325 | mtd = &txx9_priv->mtd; |
| 329 | mtd->owner = THIS_MODULE; | 326 | mtd->owner = THIS_MODULE; |
diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c index d64f8c30945f..aa26c32e1bc2 100644 --- a/drivers/mtd/ofpart.c +++ b/drivers/mtd/ofpart.c | |||
| @@ -81,7 +81,7 @@ static int parse_ofpart_partitions(struct mtd_info *master, | |||
| 81 | partname = of_get_property(pp, "label", &len); | 81 | partname = of_get_property(pp, "label", &len); |
| 82 | if (!partname) | 82 | if (!partname) |
| 83 | partname = of_get_property(pp, "name", &len); | 83 | partname = of_get_property(pp, "name", &len); |
| 84 | (*pparts)[i].name = (char *)partname; | 84 | (*pparts)[i].name = partname; |
| 85 | 85 | ||
| 86 | if (of_get_property(pp, "read-only", &len)) | 86 | if (of_get_property(pp, "read-only", &len)) |
| 87 | (*pparts)[i].mask_flags |= MTD_WRITEABLE; | 87 | (*pparts)[i].mask_flags |= MTD_WRITEABLE; |
| @@ -152,7 +152,7 @@ static int parse_ofoldpart_partitions(struct mtd_info *master, | |||
| 152 | if (names && (plen > 0)) { | 152 | if (names && (plen > 0)) { |
| 153 | int len = strlen(names) + 1; | 153 | int len = strlen(names) + 1; |
| 154 | 154 | ||
| 155 | (*pparts)[i].name = (char *)names; | 155 | (*pparts)[i].name = names; |
| 156 | plen -= len; | 156 | plen -= len; |
| 157 | names += len; | 157 | names += len; |
| 158 | } else { | 158 | } else { |
| @@ -173,18 +173,9 @@ static struct mtd_part_parser ofoldpart_parser = { | |||
| 173 | 173 | ||
| 174 | static int __init ofpart_parser_init(void) | 174 | static int __init ofpart_parser_init(void) |
| 175 | { | 175 | { |
| 176 | int rc; | 176 | register_mtd_parser(&ofpart_parser); |
| 177 | rc = register_mtd_parser(&ofpart_parser); | 177 | register_mtd_parser(&ofoldpart_parser); |
| 178 | if (rc) | 178 | return 0; |
| 179 | goto out; | ||
| 180 | |||
| 181 | rc = register_mtd_parser(&ofoldpart_parser); | ||
| 182 | if (!rc) | ||
| 183 | return 0; | ||
| 184 | |||
| 185 | deregister_mtd_parser(&ofoldpart_parser); | ||
| 186 | out: | ||
| 187 | return rc; | ||
| 188 | } | 179 | } |
| 189 | 180 | ||
| 190 | static void __exit ofpart_parser_exit(void) | 181 | static void __exit ofpart_parser_exit(void) |
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c index 63699fffc96d..8e1919b6f074 100644 --- a/drivers/mtd/onenand/generic.c +++ b/drivers/mtd/onenand/generic.c | |||
| @@ -58,7 +58,7 @@ static int generic_onenand_probe(struct platform_device *pdev) | |||
| 58 | goto out_release_mem_region; | 58 | goto out_release_mem_region; |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | info->onenand.mmcontrol = pdata ? pdata->mmcontrol : 0; | 61 | info->onenand.mmcontrol = pdata ? pdata->mmcontrol : NULL; |
| 62 | info->onenand.irq = platform_get_irq(pdev, 0); | 62 | info->onenand.irq = platform_get_irq(pdev, 0); |
| 63 | 63 | ||
| 64 | info->mtd.name = dev_name(&pdev->dev); | 64 | info->mtd.name = dev_name(&pdev->dev); |
diff --git a/drivers/mtd/redboot.c b/drivers/mtd/redboot.c index 580035c803d6..5da911ebdf49 100644 --- a/drivers/mtd/redboot.c +++ b/drivers/mtd/redboot.c | |||
| @@ -300,7 +300,8 @@ MODULE_ALIAS("RedBoot"); | |||
| 300 | 300 | ||
| 301 | static int __init redboot_parser_init(void) | 301 | static int __init redboot_parser_init(void) |
| 302 | { | 302 | { |
| 303 | return register_mtd_parser(&redboot_parser); | 303 | register_mtd_parser(&redboot_parser); |
| 304 | return 0; | ||
| 304 | } | 305 | } |
| 305 | 306 | ||
| 306 | static void __exit redboot_parser_exit(void) | 307 | static void __exit redboot_parser_exit(void) |
diff --git a/drivers/mtd/tests/mtd_nandecctest.c b/drivers/mtd/tests/mtd_nandecctest.c index 70106607c247..e579f9027c47 100644 --- a/drivers/mtd/tests/mtd_nandecctest.c +++ b/drivers/mtd/tests/mtd_nandecctest.c | |||
| @@ -19,7 +19,7 @@ | |||
| 19 | * or detected. | 19 | * or detected. |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #if defined(CONFIG_MTD_NAND) || defined(CONFIG_MTD_NAND_MODULE) | 22 | #if IS_ENABLED(CONFIG_MTD_NAND) |
| 23 | 23 | ||
| 24 | struct nand_ecc_test { | 24 | struct nand_ecc_test { |
| 25 | const char *name; | 25 | const char *name; |
diff --git a/fs/jffs2/malloc.c b/fs/jffs2/malloc.c index 4f47aa24b556..b8fd651307a4 100644 --- a/fs/jffs2/malloc.c +++ b/fs/jffs2/malloc.c | |||
| @@ -288,6 +288,8 @@ struct jffs2_xattr_datum *jffs2_alloc_xattr_datum(void) | |||
| 288 | struct jffs2_xattr_datum *xd; | 288 | struct jffs2_xattr_datum *xd; |
| 289 | xd = kmem_cache_zalloc(xattr_datum_cache, GFP_KERNEL); | 289 | xd = kmem_cache_zalloc(xattr_datum_cache, GFP_KERNEL); |
| 290 | dbg_memalloc("%p\n", xd); | 290 | dbg_memalloc("%p\n", xd); |
| 291 | if (!xd) | ||
| 292 | return NULL; | ||
| 291 | 293 | ||
| 292 | xd->class = RAWNODE_CLASS_XATTR_DATUM; | 294 | xd->class = RAWNODE_CLASS_XATTR_DATUM; |
| 293 | xd->node = (void *)xd; | 295 | xd->node = (void *)xd; |
| @@ -306,6 +308,8 @@ struct jffs2_xattr_ref *jffs2_alloc_xattr_ref(void) | |||
| 306 | struct jffs2_xattr_ref *ref; | 308 | struct jffs2_xattr_ref *ref; |
| 307 | ref = kmem_cache_zalloc(xattr_ref_cache, GFP_KERNEL); | 309 | ref = kmem_cache_zalloc(xattr_ref_cache, GFP_KERNEL); |
| 308 | dbg_memalloc("%p\n", ref); | 310 | dbg_memalloc("%p\n", ref); |
| 311 | if (!ref) | ||
| 312 | return NULL; | ||
| 309 | 313 | ||
| 310 | ref->class = RAWNODE_CLASS_XATTR_REF; | 314 | ref->class = RAWNODE_CLASS_XATTR_REF; |
| 311 | ref->node = (void *)ref; | 315 | ref->node = (void *)ref; |
diff --git a/include/linux/mtd/mtdram.h b/include/linux/mtd/mtdram.h index 68891313875d..628a6a21ddf0 100644 --- a/include/linux/mtd/mtdram.h +++ b/include/linux/mtd/mtdram.h | |||
| @@ -3,6 +3,6 @@ | |||
| 3 | 3 | ||
| 4 | #include <linux/mtd/mtd.h> | 4 | #include <linux/mtd/mtd.h> |
| 5 | int mtdram_init_device(struct mtd_info *mtd, void *mapped_address, | 5 | int mtdram_init_device(struct mtd_info *mtd, void *mapped_address, |
| 6 | unsigned long size, char *name); | 6 | unsigned long size, const char *name); |
| 7 | 7 | ||
| 8 | #endif /* __MTD_MTDRAM_H__ */ | 8 | #endif /* __MTD_MTDRAM_H__ */ |
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 9e6c8f9f306e..32f8612469d8 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h | |||
| @@ -219,6 +219,9 @@ struct nand_chip; | |||
| 219 | /* ONFI feature address */ | 219 | /* ONFI feature address */ |
| 220 | #define ONFI_FEATURE_ADDR_TIMING_MODE 0x1 | 220 | #define ONFI_FEATURE_ADDR_TIMING_MODE 0x1 |
| 221 | 221 | ||
| 222 | /* Vendor-specific feature address (Micron) */ | ||
| 223 | #define ONFI_FEATURE_ADDR_READ_RETRY 0x89 | ||
| 224 | |||
| 222 | /* ONFI subfeature parameters length */ | 225 | /* ONFI subfeature parameters length */ |
| 223 | #define ONFI_SUBFEATURE_PARAM_LEN 4 | 226 | #define ONFI_SUBFEATURE_PARAM_LEN 4 |
| 224 | 227 | ||
| @@ -279,16 +282,17 @@ struct nand_onfi_params { | |||
| 279 | __le16 io_pin_capacitance_typ; | 282 | __le16 io_pin_capacitance_typ; |
| 280 | __le16 input_pin_capacitance_typ; | 283 | __le16 input_pin_capacitance_typ; |
| 281 | u8 input_pin_capacitance_max; | 284 | u8 input_pin_capacitance_max; |
| 282 | u8 driver_strenght_support; | 285 | u8 driver_strength_support; |
| 283 | __le16 t_int_r; | 286 | __le16 t_int_r; |
| 284 | __le16 t_ald; | 287 | __le16 t_ald; |
| 285 | u8 reserved4[7]; | 288 | u8 reserved4[7]; |
| 286 | 289 | ||
| 287 | /* vendor */ | 290 | /* vendor */ |
| 288 | u8 reserved5[90]; | 291 | __le16 vendor_revision; |
| 292 | u8 vendor[88]; | ||
| 289 | 293 | ||
| 290 | __le16 crc; | 294 | __le16 crc; |
| 291 | } __attribute__((packed)); | 295 | } __packed; |
| 292 | 296 | ||
| 293 | #define ONFI_CRC_BASE 0x4F4E | 297 | #define ONFI_CRC_BASE 0x4F4E |
| 294 | 298 | ||
| @@ -326,6 +330,26 @@ struct onfi_ext_param_page { | |||
| 326 | */ | 330 | */ |
| 327 | } __packed; | 331 | } __packed; |
| 328 | 332 | ||
| 333 | struct nand_onfi_vendor_micron { | ||
| 334 | u8 two_plane_read; | ||
| 335 | u8 read_cache; | ||
| 336 | u8 read_unique_id; | ||
| 337 | u8 dq_imped; | ||
| 338 | u8 dq_imped_num_settings; | ||
| 339 | u8 dq_imped_feat_addr; | ||
| 340 | u8 rb_pulldown_strength; | ||
| 341 | u8 rb_pulldown_strength_feat_addr; | ||
| 342 | u8 rb_pulldown_strength_num_settings; | ||
| 343 | u8 otp_mode; | ||
| 344 | u8 otp_page_start; | ||
| 345 | u8 otp_data_prot_addr; | ||
| 346 | u8 otp_num_pages; | ||
| 347 | u8 otp_feat_addr; | ||
| 348 | u8 read_retry_options; | ||
| 349 | u8 reserved[72]; | ||
| 350 | u8 param_revision; | ||
| 351 | } __packed; | ||
| 352 | |||
| 329 | /** | 353 | /** |
| 330 | * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independent devices | 354 | * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independent devices |
| 331 | * @lock: protection lock | 355 | * @lock: protection lock |
| @@ -432,6 +456,8 @@ struct nand_buffers { | |||
| 432 | * flash device. | 456 | * flash device. |
| 433 | * @read_byte: [REPLACEABLE] read one byte from the chip | 457 | * @read_byte: [REPLACEABLE] read one byte from the chip |
| 434 | * @read_word: [REPLACEABLE] read one word from the chip | 458 | * @read_word: [REPLACEABLE] read one word from the chip |
| 459 | * @write_byte: [REPLACEABLE] write a single byte to the chip on the | ||
| 460 | * low 8 I/O lines | ||
| 435 | * @write_buf: [REPLACEABLE] write data from the buffer to the chip | 461 | * @write_buf: [REPLACEABLE] write data from the buffer to the chip |
| 436 | * @read_buf: [REPLACEABLE] read data from the chip into the buffer | 462 | * @read_buf: [REPLACEABLE] read data from the chip into the buffer |
| 437 | * @select_chip: [REPLACEABLE] select chip nr | 463 | * @select_chip: [REPLACEABLE] select chip nr |
| @@ -451,6 +477,8 @@ struct nand_buffers { | |||
| 451 | * commands to the chip. | 477 | * commands to the chip. |
| 452 | * @waitfunc: [REPLACEABLE] hardwarespecific function for wait on | 478 | * @waitfunc: [REPLACEABLE] hardwarespecific function for wait on |
| 453 | * ready. | 479 | * ready. |
| 480 | * @setup_read_retry: [FLASHSPECIFIC] flash (vendor) specific function for | ||
| 481 | * setting the read-retry mode. Mostly needed for MLC NAND. | ||
| 454 | * @ecc: [BOARDSPECIFIC] ECC control structure | 482 | * @ecc: [BOARDSPECIFIC] ECC control structure |
| 455 | * @buffers: buffer structure for read/write | 483 | * @buffers: buffer structure for read/write |
| 456 | * @hwcontrol: platform-specific hardware control structure | 484 | * @hwcontrol: platform-specific hardware control structure |
| @@ -497,6 +525,7 @@ struct nand_buffers { | |||
| 497 | * non 0 if ONFI supported. | 525 | * non 0 if ONFI supported. |
| 498 | * @onfi_params: [INTERN] holds the ONFI page parameter when ONFI is | 526 | * @onfi_params: [INTERN] holds the ONFI page parameter when ONFI is |
| 499 | * supported, 0 otherwise. | 527 | * supported, 0 otherwise. |
| 528 | * @read_retries: [INTERN] the number of read retry modes supported | ||
| 500 | * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand | 529 | * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand |
| 501 | * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand | 530 | * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand |
| 502 | * @bbt: [INTERN] bad block table pointer | 531 | * @bbt: [INTERN] bad block table pointer |
| @@ -521,6 +550,7 @@ struct nand_chip { | |||
| 521 | 550 | ||
| 522 | uint8_t (*read_byte)(struct mtd_info *mtd); | 551 | uint8_t (*read_byte)(struct mtd_info *mtd); |
| 523 | u16 (*read_word)(struct mtd_info *mtd); | 552 | u16 (*read_word)(struct mtd_info *mtd); |
| 553 | void (*write_byte)(struct mtd_info *mtd, uint8_t byte); | ||
| 524 | void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len); | 554 | void (*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len); |
| 525 | void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len); | 555 | void (*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len); |
| 526 | void (*select_chip)(struct mtd_info *mtd, int chip); | 556 | void (*select_chip)(struct mtd_info *mtd, int chip); |
| @@ -544,6 +574,7 @@ struct nand_chip { | |||
| 544 | int feature_addr, uint8_t *subfeature_para); | 574 | int feature_addr, uint8_t *subfeature_para); |
| 545 | int (*onfi_get_features)(struct mtd_info *mtd, struct nand_chip *chip, | 575 | int (*onfi_get_features)(struct mtd_info *mtd, struct nand_chip *chip, |
| 546 | int feature_addr, uint8_t *subfeature_para); | 576 | int feature_addr, uint8_t *subfeature_para); |
| 577 | int (*setup_read_retry)(struct mtd_info *mtd, int retry_mode); | ||
| 547 | 578 | ||
| 548 | int chip_delay; | 579 | int chip_delay; |
| 549 | unsigned int options; | 580 | unsigned int options; |
| @@ -568,6 +599,8 @@ struct nand_chip { | |||
| 568 | int onfi_version; | 599 | int onfi_version; |
| 569 | struct nand_onfi_params onfi_params; | 600 | struct nand_onfi_params onfi_params; |
| 570 | 601 | ||
| 602 | int read_retries; | ||
| 603 | |||
| 571 | flstate_t state; | 604 | flstate_t state; |
| 572 | 605 | ||
| 573 | uint8_t *oob_poi; | 606 | uint8_t *oob_poi; |
| @@ -600,6 +633,8 @@ struct nand_chip { | |||
| 600 | #define NAND_MFR_AMD 0x01 | 633 | #define NAND_MFR_AMD 0x01 |
| 601 | #define NAND_MFR_MACRONIX 0xc2 | 634 | #define NAND_MFR_MACRONIX 0xc2 |
| 602 | #define NAND_MFR_EON 0x92 | 635 | #define NAND_MFR_EON 0x92 |
| 636 | #define NAND_MFR_SANDISK 0x45 | ||
| 637 | #define NAND_MFR_INTEL 0x89 | ||
| 603 | 638 | ||
| 604 | /* The maximum expected count of bytes in the NAND ID sequence */ | 639 | /* The maximum expected count of bytes in the NAND ID sequence */ |
| 605 | #define NAND_MAX_ID_LEN 8 | 640 | #define NAND_MAX_ID_LEN 8 |
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index 1f8d24bdafda..6a35e6de5da1 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h | |||
| @@ -37,7 +37,7 @@ | |||
| 37 | */ | 37 | */ |
| 38 | 38 | ||
| 39 | struct mtd_partition { | 39 | struct mtd_partition { |
| 40 | char *name; /* identifier string */ | 40 | const char *name; /* identifier string */ |
| 41 | uint64_t size; /* partition size */ | 41 | uint64_t size; /* partition size */ |
| 42 | uint64_t offset; /* offset within the master MTD space */ | 42 | uint64_t offset; /* offset within the master MTD space */ |
| 43 | uint32_t mask_flags; /* master MTD flags to mask out for this partition */ | 43 | uint32_t mask_flags; /* master MTD flags to mask out for this partition */ |
| @@ -76,11 +76,11 @@ struct mtd_part_parser { | |||
| 76 | struct mtd_part_parser_data *); | 76 | struct mtd_part_parser_data *); |
| 77 | }; | 77 | }; |
| 78 | 78 | ||
| 79 | extern int register_mtd_parser(struct mtd_part_parser *parser); | 79 | extern void register_mtd_parser(struct mtd_part_parser *parser); |
| 80 | extern int deregister_mtd_parser(struct mtd_part_parser *parser); | 80 | extern void deregister_mtd_parser(struct mtd_part_parser *parser); |
| 81 | 81 | ||
| 82 | int mtd_is_partition(const struct mtd_info *mtd); | 82 | int mtd_is_partition(const struct mtd_info *mtd); |
| 83 | int mtd_add_partition(struct mtd_info *master, char *name, | 83 | int mtd_add_partition(struct mtd_info *master, const char *name, |
| 84 | long long offset, long long length); | 84 | long long offset, long long length); |
| 85 | int mtd_del_partition(struct mtd_info *master, int partno); | 85 | int mtd_del_partition(struct mtd_info *master, int partno); |
| 86 | uint64_t mtd_get_device_size(const struct mtd_info *mtd); | 86 | uint64_t mtd_get_device_size(const struct mtd_info *mtd); |
diff --git a/include/linux/of_mtd.h b/include/linux/of_mtd.h index 6f10e938ff7e..cb32d9c1e8dc 100644 --- a/include/linux/of_mtd.h +++ b/include/linux/of_mtd.h | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #ifndef __LINUX_OF_MTD_H | 9 | #ifndef __LINUX_OF_MTD_H |
| 10 | #define __LINUX_OF_NET_H | 10 | #define __LINUX_OF_MTD_H |
| 11 | 11 | ||
| 12 | #ifdef CONFIG_OF_MTD | 12 | #ifdef CONFIG_OF_MTD |
| 13 | 13 | ||
diff --git a/include/linux/platform_data/mtd-nand-omap2.h b/include/linux/platform_data/mtd-nand-omap2.h index 4da5bfa2147f..3e9dd6676b97 100644 --- a/include/linux/platform_data/mtd-nand-omap2.h +++ b/include/linux/platform_data/mtd-nand-omap2.h | |||
| @@ -1,6 +1,4 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * arch/arm/plat-omap/include/mach/nand.h | ||
| 3 | * | ||
| 4 | * Copyright (C) 2006 Micron Technology Inc. | 2 | * Copyright (C) 2006 Micron Technology Inc. |
| 5 | * | 3 | * |
| 6 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
diff --git a/include/linux/platform_data/mtd-nand-pxa3xx.h b/include/linux/platform_data/mtd-nand-pxa3xx.h index ffb801998e5d..a94147124929 100644 --- a/include/linux/platform_data/mtd-nand-pxa3xx.h +++ b/include/linux/platform_data/mtd-nand-pxa3xx.h | |||
| @@ -55,6 +55,9 @@ struct pxa3xx_nand_platform_data { | |||
| 55 | /* indicate how many chip selects will be used */ | 55 | /* indicate how many chip selects will be used */ |
| 56 | int num_cs; | 56 | int num_cs; |
| 57 | 57 | ||
| 58 | /* use an flash-based bad block table */ | ||
| 59 | bool flash_bbt; | ||
| 60 | |||
| 58 | const struct mtd_partition *parts[NUM_CHIP_SELECT]; | 61 | const struct mtd_partition *parts[NUM_CHIP_SELECT]; |
| 59 | unsigned int nr_parts[NUM_CHIP_SELECT]; | 62 | unsigned int nr_parts[NUM_CHIP_SELECT]; |
| 60 | 63 | ||
diff --git a/include/linux/platform_data/mtd-onenand-omap2.h b/include/linux/platform_data/mtd-onenand-omap2.h index e9a9fb188f97..56ff0e6f5ad1 100644 --- a/include/linux/platform_data/mtd-onenand-omap2.h +++ b/include/linux/platform_data/mtd-onenand-omap2.h | |||
| @@ -1,6 +1,4 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * arch/arm/plat-omap/include/mach/onenand.h | ||
| 3 | * | ||
| 4 | * Copyright (C) 2006 Nokia Corporation | 2 | * Copyright (C) 2006 Nokia Corporation |
| 5 | * Author: Juha Yrjola | 3 | * Author: Juha Yrjola |
| 6 | * | 4 | * |
diff --git a/include/linux/platform_data/mtd-orion_nand.h b/include/linux/platform_data/mtd-orion_nand.h index 9f3c180834d1..a7ce77c7c1a8 100644 --- a/include/linux/platform_data/mtd-orion_nand.h +++ b/include/linux/platform_data/mtd-orion_nand.h | |||
| @@ -1,13 +1,11 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * arch/arm/plat-orion/include/plat/orion_nand.h | ||
| 3 | * | ||
| 4 | * This file is licensed under the terms of the GNU General Public | 2 | * This file is licensed under the terms of the GNU General Public |
| 5 | * License version 2. This program is licensed "as is" without any | 3 | * License version 2. This program is licensed "as is" without any |
| 6 | * warranty of any kind, whether express or implied. | 4 | * warranty of any kind, whether express or implied. |
| 7 | */ | 5 | */ |
| 8 | 6 | ||
| 9 | #ifndef __PLAT_ORION_NAND_H | 7 | #ifndef __MTD_ORION_NAND_H |
| 10 | #define __PLAT_ORION_NAND_H | 8 | #define __MTD_ORION_NAND_H |
| 11 | 9 | ||
| 12 | /* | 10 | /* |
| 13 | * Device bus NAND private data | 11 | * Device bus NAND private data |
