diff options
121 files changed, 2544 insertions, 1833 deletions
diff --git a/Documentation/devicetree/bindings/arm/davinci/nand.txt b/Documentation/devicetree/bindings/arm/davinci/nand.txt index 49fc7ada929a..3545ea704b50 100644 --- a/Documentation/devicetree/bindings/arm/davinci/nand.txt +++ b/Documentation/devicetree/bindings/arm/davinci/nand.txt | |||
| @@ -23,6 +23,9 @@ Recommended properties : | |||
| 23 | - ti,davinci-nand-buswidth: buswidth 8 or 16 | 23 | - ti,davinci-nand-buswidth: buswidth 8 or 16 |
| 24 | - ti,davinci-nand-use-bbt: use flash based bad block table support. | 24 | - ti,davinci-nand-use-bbt: use flash based bad block table support. |
| 25 | 25 | ||
| 26 | nand device bindings may contain additional sub-nodes describing | ||
| 27 | partitions of the address space. See partition.txt for more detail. | ||
| 28 | |||
| 26 | Example(da850 EVM ): | 29 | Example(da850 EVM ): |
| 27 | nand_cs3@62000000 { | 30 | nand_cs3@62000000 { |
| 28 | compatible = "ti,davinci-nand"; | 31 | compatible = "ti,davinci-nand"; |
| @@ -35,4 +38,9 @@ nand_cs3@62000000 { | |||
| 35 | ti,davinci-ecc-mode = "hw"; | 38 | ti,davinci-ecc-mode = "hw"; |
| 36 | ti,davinci-ecc-bits = <4>; | 39 | ti,davinci-ecc-bits = <4>; |
| 37 | ti,davinci-nand-use-bbt; | 40 | ti,davinci-nand-use-bbt; |
| 41 | |||
| 42 | partition@180000 { | ||
| 43 | label = "ubifs"; | ||
| 44 | reg = <0x180000 0x7e80000>; | ||
| 45 | }; | ||
| 38 | }; | 46 | }; |
diff --git a/Documentation/devicetree/bindings/mtd/denali-nand.txt b/Documentation/devicetree/bindings/mtd/denali-nand.txt new file mode 100644 index 000000000000..b04d03a1d499 --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/denali-nand.txt | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | * Denali NAND controller | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible : should be "denali,denali-nand-dt" | ||
| 5 | - reg : should contain registers location and length for data and reg. | ||
| 6 | - reg-names: Should contain the reg names "nand_data" and "denali_reg" | ||
| 7 | - interrupts : The interrupt number. | ||
| 8 | - dm-mask : DMA bit mask | ||
| 9 | |||
| 10 | The device tree may optionally contain sub-nodes describing partitions of the | ||
| 11 | address space. See partition.txt for more detail. | ||
| 12 | |||
| 13 | Examples: | ||
| 14 | |||
| 15 | nand: nand@ff900000 { | ||
| 16 | #address-cells = <1>; | ||
| 17 | #size-cells = <1>; | ||
| 18 | compatible = "denali,denali-nand-dt"; | ||
| 19 | reg = <0xff900000 0x100000>, <0xffb80000 0x10000>; | ||
| 20 | reg-names = "nand_data", "denali_reg"; | ||
| 21 | interrupts = <0 144 4>; | ||
| 22 | dma-mask = <0xffffffff>; | ||
| 23 | }; | ||
diff --git a/Documentation/devicetree/bindings/mtd/flctl-nand.txt b/Documentation/devicetree/bindings/mtd/flctl-nand.txt new file mode 100644 index 000000000000..427f46dc60ad --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/flctl-nand.txt | |||
| @@ -0,0 +1,49 @@ | |||
| 1 | FLCTL NAND controller | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - compatible : "renesas,shmobile-flctl-sh7372" | ||
| 5 | - reg : Address range of the FLCTL | ||
| 6 | - interrupts : flste IRQ number | ||
| 7 | - nand-bus-width : bus width to NAND chip | ||
| 8 | |||
| 9 | Optional properties: | ||
| 10 | - dmas: DMA specifier(s) | ||
| 11 | - dma-names: name for each DMA specifier. Valid names are | ||
| 12 | "data_tx", "data_rx", "ecc_tx", "ecc_rx" | ||
| 13 | |||
| 14 | The DMA fields are not used yet in the driver but are listed here for | ||
| 15 | completing the bindings. | ||
| 16 | |||
| 17 | The device tree may optionally contain sub-nodes describing partitions of the | ||
| 18 | address space. See partition.txt for more detail. | ||
| 19 | |||
| 20 | Example: | ||
| 21 | |||
| 22 | flctl@e6a30000 { | ||
| 23 | #address-cells = <1>; | ||
| 24 | #size-cells = <1>; | ||
| 25 | compatible = "renesas,shmobile-flctl-sh7372"; | ||
| 26 | reg = <0xe6a30000 0x100>; | ||
| 27 | interrupts = <0x0d80>; | ||
| 28 | |||
| 29 | nand-bus-width = <16>; | ||
| 30 | |||
| 31 | dmas = <&dmac 1 /* data_tx */ | ||
| 32 | &dmac 2;> /* data_rx */ | ||
| 33 | dma-names = "data_tx", "data_rx"; | ||
| 34 | |||
| 35 | system@0 { | ||
| 36 | label = "system"; | ||
| 37 | reg = <0x0 0x8000000>; | ||
| 38 | }; | ||
| 39 | |||
| 40 | userdata@8000000 { | ||
| 41 | label = "userdata"; | ||
| 42 | reg = <0x8000000 0x10000000>; | ||
| 43 | }; | ||
| 44 | |||
| 45 | cache@18000000 { | ||
| 46 | label = "cache"; | ||
| 47 | reg = <0x18000000 0x8000000>; | ||
| 48 | }; | ||
| 49 | }; | ||
diff --git a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt index e2c663b354d2..e3ea32e7de3e 100644 --- a/Documentation/devicetree/bindings/mtd/fsmc-nand.txt +++ b/Documentation/devicetree/bindings/mtd/fsmc-nand.txt | |||
| @@ -3,9 +3,7 @@ | |||
| 3 | Required properties: | 3 | Required properties: |
| 4 | - compatible : "st,spear600-fsmc-nand" | 4 | - compatible : "st,spear600-fsmc-nand" |
| 5 | - reg : Address range of the mtd chip | 5 | - reg : Address range of the mtd chip |
| 6 | - reg-names: Should contain the reg names "fsmc_regs" and "nand_data" | 6 | - reg-names: Should contain the reg names "fsmc_regs", "nand_data", "nand_addr" and "nand_cmd" |
| 7 | - st,ale-off : Chip specific offset to ALE | ||
| 8 | - st,cle-off : Chip specific offset to CLE | ||
| 9 | 7 | ||
| 10 | Optional properties: | 8 | Optional properties: |
| 11 | - bank-width : Width (in bytes) of the device. If not present, the width | 9 | - bank-width : Width (in bytes) of the device. If not present, the width |
| @@ -19,10 +17,10 @@ Example: | |||
| 19 | #address-cells = <1>; | 17 | #address-cells = <1>; |
| 20 | #size-cells = <1>; | 18 | #size-cells = <1>; |
| 21 | reg = <0xd1800000 0x1000 /* FSMC Register */ | 19 | reg = <0xd1800000 0x1000 /* FSMC Register */ |
| 22 | 0xd2000000 0x4000>; /* NAND Base */ | 20 | 0xd2000000 0x0010 /* NAND Base DATA */ |
| 23 | reg-names = "fsmc_regs", "nand_data"; | 21 | 0xd2020000 0x0010 /* NAND Base ADDR */ |
| 24 | st,ale-off = <0x20000>; | 22 | 0xd2010000 0x0010>; /* NAND Base CMD */ |
| 25 | st,cle-off = <0x10000>; | 23 | reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd"; |
| 26 | 24 | ||
| 27 | bank-width = <1>; | 25 | bank-width = <1>; |
| 28 | nand-skip-bbtscan; | 26 | nand-skip-bbtscan; |
diff --git a/Documentation/devicetree/bindings/mtd/m25p80.txt b/Documentation/devicetree/bindings/mtd/m25p80.txt new file mode 100644 index 000000000000..6d3d57609470 --- /dev/null +++ b/Documentation/devicetree/bindings/mtd/m25p80.txt | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | * MTD SPI driver for ST M25Pxx (and similar) serial flash chips | ||
| 2 | |||
| 3 | Required properties: | ||
| 4 | - #address-cells, #size-cells : Must be present if the device has sub-nodes | ||
| 5 | representing partitions. | ||
| 6 | - compatible : Should be the manufacturer and the name of the chip. Bear in mind | ||
| 7 | the DT binding is not Linux-only, but in case of Linux, see the | ||
| 8 | "m25p_ids" table in drivers/mtd/devices/m25p80.c for the list of | ||
| 9 | supported chips. | ||
| 10 | - reg : Chip-Select number | ||
| 11 | - spi-max-frequency : Maximum frequency of the SPI bus the chip can operate at | ||
| 12 | |||
| 13 | Optional properties: | ||
| 14 | - m25p,fast-read : Use the "fast read" opcode to read data from the chip instead | ||
| 15 | of the usual "read" opcode. This opcode is not supported by | ||
| 16 | all chips and support for it can not be detected at runtime. | ||
| 17 | Refer to your chips' datasheet to check if this is supported | ||
| 18 | by your chip. | ||
| 19 | |||
| 20 | Example: | ||
| 21 | |||
| 22 | flash: m25p80@0 { | ||
| 23 | #address-cells = <1>; | ||
| 24 | #size-cells = <1>; | ||
| 25 | compatible = "spansion,m25p80"; | ||
| 26 | reg = <0>; | ||
| 27 | spi-max-frequency = <40000000>; | ||
| 28 | m25p,fast-read; | ||
| 29 | }; | ||
diff --git a/Documentation/devicetree/bindings/mtd/mtd-physmap.txt b/Documentation/devicetree/bindings/mtd/mtd-physmap.txt index 94de19b8f16b..dab7847fc800 100644 --- a/Documentation/devicetree/bindings/mtd/mtd-physmap.txt +++ b/Documentation/devicetree/bindings/mtd/mtd-physmap.txt | |||
| @@ -23,6 +23,9 @@ file systems on embedded devices. | |||
| 23 | unaligned accesses as implemented in the JFFS2 code via memcpy(). | 23 | unaligned accesses as implemented in the JFFS2 code via memcpy(). |
| 24 | By defining "no-unaligned-direct-access", the flash will not be | 24 | By defining "no-unaligned-direct-access", the flash will not be |
| 25 | exposed directly to the MTD users (e.g. JFFS2) any more. | 25 | exposed directly to the MTD users (e.g. JFFS2) any more. |
| 26 | - linux,mtd-name: allow to specify the mtd name for retro capability with | ||
| 27 | physmap-flash drivers as boot loader pass the mtd partition via the old | ||
| 28 | device name physmap-flash. | ||
| 26 | 29 | ||
| 27 | For JEDEC compatible devices, the following additional properties | 30 | For JEDEC compatible devices, the following additional properties |
| 28 | are defined: | 31 | are defined: |
diff --git a/arch/arm/boot/dts/spear13xx.dtsi b/arch/arm/boot/dts/spear13xx.dtsi index 009096d1d2c3..b4ca60f4eb42 100644 --- a/arch/arm/boot/dts/spear13xx.dtsi +++ b/arch/arm/boot/dts/spear13xx.dtsi | |||
| @@ -73,7 +73,7 @@ | |||
| 73 | 400000 | 73 | 400000 |
| 74 | 500000 | 74 | 500000 |
| 75 | 600000 >; | 75 | 600000 >; |
| 76 | status = "disable"; | 76 | status = "disabled"; |
| 77 | }; | 77 | }; |
| 78 | 78 | ||
| 79 | ahb { | 79 | ahb { |
| @@ -118,15 +118,15 @@ | |||
| 118 | compatible = "st,spear600-fsmc-nand"; | 118 | compatible = "st,spear600-fsmc-nand"; |
| 119 | #address-cells = <1>; | 119 | #address-cells = <1>; |
| 120 | #size-cells = <1>; | 120 | #size-cells = <1>; |
| 121 | reg = <0xb0000000 0x1000 /* FSMC Register */ | 121 | reg = <0xb0000000 0x1000 /* FSMC Register*/ |
| 122 | 0xb0800000 0x0010>; /* NAND Base */ | 122 | 0xb0800000 0x0010 /* NAND Base DATA */ |
| 123 | reg-names = "fsmc_regs", "nand_data"; | 123 | 0xb0820000 0x0010 /* NAND Base ADDR */ |
| 124 | 0xb0810000 0x0010>; /* NAND Base CMD */ | ||
| 125 | reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd"; | ||
| 124 | interrupts = <0 20 0x4 | 126 | interrupts = <0 20 0x4 |
| 125 | 0 21 0x4 | 127 | 0 21 0x4 |
| 126 | 0 22 0x4 | 128 | 0 22 0x4 |
| 127 | 0 23 0x4>; | 129 | 0 23 0x4>; |
| 128 | st,ale-off = <0x20000>; | ||
| 129 | st,cle-off = <0x10000>; | ||
| 130 | st,mode = <2>; | 130 | st,mode = <2>; |
| 131 | status = "disabled"; | 131 | status = "disabled"; |
| 132 | }; | 132 | }; |
| @@ -144,7 +144,7 @@ | |||
| 144 | compatible = "st,pcm-audio"; | 144 | compatible = "st,pcm-audio"; |
| 145 | #address-cells = <0>; | 145 | #address-cells = <0>; |
| 146 | #size-cells = <0>; | 146 | #size-cells = <0>; |
| 147 | status = "disable"; | 147 | status = "disabled"; |
| 148 | }; | 148 | }; |
| 149 | 149 | ||
| 150 | smi: flash@ea000000 { | 150 | smi: flash@ea000000 { |
diff --git a/arch/arm/boot/dts/spear300.dtsi b/arch/arm/boot/dts/spear300.dtsi index 090adc656015..f79b3dfaabe6 100644 --- a/arch/arm/boot/dts/spear300.dtsi +++ b/arch/arm/boot/dts/spear300.dtsi | |||
| @@ -38,10 +38,10 @@ | |||
| 38 | #address-cells = <1>; | 38 | #address-cells = <1>; |
| 39 | #size-cells = <1>; | 39 | #size-cells = <1>; |
| 40 | reg = <0x94000000 0x1000 /* FSMC Register */ | 40 | reg = <0x94000000 0x1000 /* FSMC Register */ |
| 41 | 0x80000000 0x0010>; /* NAND Base */ | 41 | 0x80000000 0x0010 /* NAND Base DATA */ |
| 42 | reg-names = "fsmc_regs", "nand_data"; | 42 | 0x80020000 0x0010 /* NAND Base ADDR */ |
| 43 | st,ale-off = <0x20000>; | 43 | 0x80010000 0x0010>; /* NAND Base CMD */ |
| 44 | st,cle-off = <0x10000>; | 44 | reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd"; |
| 45 | status = "disabled"; | 45 | status = "disabled"; |
| 46 | }; | 46 | }; |
| 47 | 47 | ||
diff --git a/arch/arm/boot/dts/spear310.dtsi b/arch/arm/boot/dts/spear310.dtsi index e814e5e97083..ab45b8c81982 100644 --- a/arch/arm/boot/dts/spear310.dtsi +++ b/arch/arm/boot/dts/spear310.dtsi | |||
| @@ -33,10 +33,10 @@ | |||
| 33 | #address-cells = <1>; | 33 | #address-cells = <1>; |
| 34 | #size-cells = <1>; | 34 | #size-cells = <1>; |
| 35 | reg = <0x44000000 0x1000 /* FSMC Register */ | 35 | reg = <0x44000000 0x1000 /* FSMC Register */ |
| 36 | 0x40000000 0x0010>; /* NAND Base */ | 36 | 0x40000000 0x0010 /* NAND Base DATA */ |
| 37 | reg-names = "fsmc_regs", "nand_data"; | 37 | 0x40020000 0x0010 /* NAND Base ADDR */ |
| 38 | st,ale-off = <0x10000>; | 38 | 0x40010000 0x0010>; /* NAND Base CMD */ |
| 39 | st,cle-off = <0x20000>; | 39 | reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd"; |
| 40 | status = "disabled"; | 40 | status = "disabled"; |
| 41 | }; | 41 | }; |
| 42 | 42 | ||
diff --git a/arch/arm/boot/dts/spear320.dtsi b/arch/arm/boot/dts/spear320.dtsi index c056a84deabf..caa5520b1fd4 100644 --- a/arch/arm/boot/dts/spear320.dtsi +++ b/arch/arm/boot/dts/spear320.dtsi | |||
| @@ -40,10 +40,10 @@ | |||
| 40 | #address-cells = <1>; | 40 | #address-cells = <1>; |
| 41 | #size-cells = <1>; | 41 | #size-cells = <1>; |
| 42 | reg = <0x4c000000 0x1000 /* FSMC Register */ | 42 | reg = <0x4c000000 0x1000 /* FSMC Register */ |
| 43 | 0x50000000 0x0010>; /* NAND Base */ | 43 | 0x50000000 0x0010 /* NAND Base DATA */ |
| 44 | reg-names = "fsmc_regs", "nand_data"; | 44 | 0x50020000 0x0010 /* NAND Base ADDR */ |
| 45 | st,ale-off = <0x20000>; | 45 | 0x50010000 0x0010>; /* NAND Base CMD */ |
| 46 | st,cle-off = <0x10000>; | 46 | reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd"; |
| 47 | status = "disabled"; | 47 | status = "disabled"; |
| 48 | }; | 48 | }; |
| 49 | 49 | ||
diff --git a/arch/arm/boot/dts/spear600.dtsi b/arch/arm/boot/dts/spear600.dtsi index e051dde5181f..19f99dc4115e 100644 --- a/arch/arm/boot/dts/spear600.dtsi +++ b/arch/arm/boot/dts/spear600.dtsi | |||
| @@ -76,10 +76,10 @@ | |||
| 76 | #address-cells = <1>; | 76 | #address-cells = <1>; |
| 77 | #size-cells = <1>; | 77 | #size-cells = <1>; |
| 78 | reg = <0xd1800000 0x1000 /* FSMC Register */ | 78 | reg = <0xd1800000 0x1000 /* FSMC Register */ |
| 79 | 0xd2000000 0x4000>; /* NAND Base */ | 79 | 0xd2000000 0x0010 /* NAND Base DATA */ |
| 80 | reg-names = "fsmc_regs", "nand_data"; | 80 | 0xd2020000 0x0010 /* NAND Base ADDR */ |
| 81 | st,ale-off = <0x20000>; | 81 | 0xd2010000 0x0010>; /* NAND Base CMD */ |
| 82 | st,cle-off = <0x10000>; | 82 | reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd"; |
| 83 | status = "disabled"; | 83 | status = "disabled"; |
| 84 | }; | 84 | }; |
| 85 | 85 | ||
diff --git a/arch/arm/configs/nhk8815_defconfig b/arch/arm/configs/nhk8815_defconfig index 240b25eea565..86cfd2959c47 100644 --- a/arch/arm/configs/nhk8815_defconfig +++ b/arch/arm/configs/nhk8815_defconfig | |||
| @@ -57,7 +57,7 @@ CONFIG_MTD_CHAR=y | |||
| 57 | CONFIG_MTD_BLOCK=y | 57 | CONFIG_MTD_BLOCK=y |
| 58 | CONFIG_MTD_NAND=y | 58 | CONFIG_MTD_NAND=y |
| 59 | CONFIG_MTD_NAND_ECC_SMC=y | 59 | CONFIG_MTD_NAND_ECC_SMC=y |
| 60 | CONFIG_MTD_NAND_NOMADIK=y | 60 | CONFIG_MTD_NAND_FSMC=y |
| 61 | CONFIG_MTD_ONENAND=y | 61 | CONFIG_MTD_ONENAND=y |
| 62 | CONFIG_MTD_ONENAND_VERIFY_WRITE=y | 62 | CONFIG_MTD_ONENAND_VERIFY_WRITE=y |
| 63 | CONFIG_MTD_ONENAND_GENERIC=y | 63 | CONFIG_MTD_ONENAND_GENERIC=y |
diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c index 5ccdf53c5a9d..98167a4319f7 100644 --- a/arch/arm/mach-nomadik/board-nhk8815.c +++ b/arch/arm/mach-nomadik/board-nhk8815.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/gpio.h> | 19 | #include <linux/gpio.h> |
| 20 | #include <linux/mtd/mtd.h> | 20 | #include <linux/mtd/mtd.h> |
| 21 | #include <linux/mtd/nand.h> | 21 | #include <linux/mtd/nand.h> |
| 22 | #include <linux/mtd/fsmc.h> | ||
| 22 | #include <linux/mtd/onenand.h> | 23 | #include <linux/mtd/onenand.h> |
| 23 | #include <linux/mtd/partitions.h> | 24 | #include <linux/mtd/partitions.h> |
| 24 | #include <linux/i2c.h> | 25 | #include <linux/i2c.h> |
| @@ -33,7 +34,6 @@ | |||
| 33 | #include <asm/mach/arch.h> | 34 | #include <asm/mach/arch.h> |
| 34 | #include <asm/mach/flash.h> | 35 | #include <asm/mach/flash.h> |
| 35 | #include <asm/mach/time.h> | 36 | #include <asm/mach/time.h> |
| 36 | #include <mach/fsmc.h> | ||
| 37 | #include <mach/irqs.h> | 37 | #include <mach/irqs.h> |
| 38 | 38 | ||
| 39 | #include "cpu-8815.h" | 39 | #include "cpu-8815.h" |
| @@ -42,39 +42,34 @@ | |||
| 42 | #define SRC_CR_INIT_MASK 0x00007fff | 42 | #define SRC_CR_INIT_MASK 0x00007fff |
| 43 | #define SRC_CR_INIT_VAL 0x2aaa8000 | 43 | #define SRC_CR_INIT_VAL 0x2aaa8000 |
| 44 | 44 | ||
| 45 | #define ALE_OFF 0x1000000 | ||
| 46 | #define CLE_OFF 0x800000 | ||
| 47 | |||
| 45 | /* These addresses span 16MB, so use three individual pages */ | 48 | /* These addresses span 16MB, so use three individual pages */ |
| 46 | static struct resource nhk8815_nand_resources[] = { | 49 | static struct resource nhk8815_nand_resources[] = { |
| 47 | { | 50 | { |
| 51 | .name = "nand_data", | ||
| 52 | .start = 0x40000000, | ||
| 53 | .end = 0x40000000 + SZ_16K - 1, | ||
| 54 | .flags = IORESOURCE_MEM, | ||
| 55 | }, { | ||
| 48 | .name = "nand_addr", | 56 | .name = "nand_addr", |
| 49 | .start = NAND_IO_ADDR, | 57 | .start = 0x40000000 + ALE_OFF, |
| 50 | .end = NAND_IO_ADDR + 0xfff, | 58 | .end = 0x40000000 +ALE_OFF + SZ_16K - 1, |
| 51 | .flags = IORESOURCE_MEM, | 59 | .flags = IORESOURCE_MEM, |
| 52 | }, { | 60 | }, { |
| 53 | .name = "nand_cmd", | 61 | .name = "nand_cmd", |
| 54 | .start = NAND_IO_CMD, | 62 | .start = 0x40000000 + CLE_OFF, |
| 55 | .end = NAND_IO_CMD + 0xfff, | 63 | .end = 0x40000000 + CLE_OFF + SZ_16K - 1, |
| 56 | .flags = IORESOURCE_MEM, | 64 | .flags = IORESOURCE_MEM, |
| 57 | }, { | 65 | }, { |
| 58 | .name = "nand_data", | 66 | .name = "fsmc_regs", |
| 59 | .start = NAND_IO_DATA, | 67 | .start = NOMADIK_FSMC_BASE, |
| 60 | .end = NAND_IO_DATA + 0xfff, | 68 | .end = NOMADIK_FSMC_BASE + SZ_4K - 1, |
| 61 | .flags = IORESOURCE_MEM, | 69 | .flags = IORESOURCE_MEM, |
| 62 | } | 70 | }, |
| 63 | }; | 71 | }; |
| 64 | 72 | ||
| 65 | static int nhk8815_nand_init(void) | ||
| 66 | { | ||
| 67 | /* FSMC setup for nand chip select (8-bit nand in 8815NHK) */ | ||
| 68 | writel(0x0000000E, FSMC_PCR(0)); | ||
| 69 | writel(0x000D0A00, FSMC_PMEM(0)); | ||
| 70 | writel(0x00100A00, FSMC_PATT(0)); | ||
| 71 | |||
| 72 | /* enable access to the chip select area */ | ||
| 73 | writel(readl(FSMC_PCR(0)) | 0x04, FSMC_PCR(0)); | ||
| 74 | |||
| 75 | return 0; | ||
| 76 | } | ||
| 77 | |||
| 78 | /* | 73 | /* |
| 79 | * These partitions are the same as those used in the 2.6.20 release | 74 | * These partitions are the same as those used in the 2.6.20 release |
| 80 | * shipped by the vendor; the first two partitions are mandated | 75 | * shipped by the vendor; the first two partitions are mandated |
| @@ -108,20 +103,28 @@ static struct mtd_partition nhk8815_partitions[] = { | |||
| 108 | } | 103 | } |
| 109 | }; | 104 | }; |
| 110 | 105 | ||
| 111 | static struct nomadik_nand_platform_data nhk8815_nand_data = { | 106 | static struct fsmc_nand_timings nhk8815_nand_timings = { |
| 112 | .parts = nhk8815_partitions, | 107 | .thiz = 0, |
| 113 | .nparts = ARRAY_SIZE(nhk8815_partitions), | 108 | .thold = 0x10, |
| 114 | .options = NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING, | 109 | .twait = 0x0A, |
| 115 | .init = nhk8815_nand_init, | 110 | .tset = 0, |
| 111 | }; | ||
| 112 | |||
| 113 | static struct fsmc_nand_platform_data nhk8815_nand_platform_data = { | ||
| 114 | .nand_timings = &nhk8815_nand_timings, | ||
| 115 | .partitions = nhk8815_partitions, | ||
| 116 | .nr_partitions = ARRAY_SIZE(nhk8815_partitions), | ||
| 117 | .width = FSMC_NAND_BW8, | ||
| 116 | }; | 118 | }; |
| 117 | 119 | ||
| 118 | static struct platform_device nhk8815_nand_device = { | 120 | static struct platform_device nhk8815_nand_device = { |
| 119 | .name = "nomadik_nand", | 121 | .name = "fsmc-nand", |
| 120 | .dev = { | 122 | .id = -1, |
| 121 | .platform_data = &nhk8815_nand_data, | 123 | .resource = nhk8815_nand_resources, |
| 124 | .num_resources = ARRAY_SIZE(nhk8815_nand_resources), | ||
| 125 | .dev = { | ||
| 126 | .platform_data = &nhk8815_nand_platform_data, | ||
| 122 | }, | 127 | }, |
| 123 | .resource = nhk8815_nand_resources, | ||
| 124 | .num_resources = ARRAY_SIZE(nhk8815_nand_resources), | ||
| 125 | }; | 128 | }; |
| 126 | 129 | ||
| 127 | /* These are the partitions for the OneNand device, different from above */ | 130 | /* These are the partitions for the OneNand device, different from above */ |
| @@ -176,6 +179,10 @@ static struct platform_device nhk8815_onenand_device = { | |||
| 176 | .num_resources = ARRAY_SIZE(nhk8815_onenand_resource), | 179 | .num_resources = ARRAY_SIZE(nhk8815_onenand_resource), |
| 177 | }; | 180 | }; |
| 178 | 181 | ||
| 182 | /* bus control reg. and bus timing reg. for CS0..CS3 */ | ||
| 183 | #define FSMC_BCR(x) (NOMADIK_FSMC_VA + (x << 3)) | ||
| 184 | #define FSMC_BTR(x) (NOMADIK_FSMC_VA + (x << 3) + 0x04) | ||
| 185 | |||
| 179 | static void __init nhk8815_onenand_init(void) | 186 | static void __init nhk8815_onenand_init(void) |
| 180 | { | 187 | { |
| 181 | #ifdef CONFIG_MTD_ONENAND | 188 | #ifdef CONFIG_MTD_ONENAND |
diff --git a/arch/arm/mach-nomadik/include/mach/fsmc.h b/arch/arm/mach-nomadik/include/mach/fsmc.h deleted file mode 100644 index 8c2c05183685..000000000000 --- a/arch/arm/mach-nomadik/include/mach/fsmc.h +++ /dev/null | |||
| @@ -1,29 +0,0 @@ | |||
| 1 | |||
| 2 | /* Definitions for the Nomadik FSMC "Flexible Static Memory controller" */ | ||
| 3 | |||
| 4 | #ifndef __ASM_ARCH_FSMC_H | ||
| 5 | #define __ASM_ARCH_FSMC_H | ||
| 6 | |||
| 7 | #include <mach/hardware.h> | ||
| 8 | /* | ||
| 9 | * Register list | ||
| 10 | */ | ||
| 11 | |||
| 12 | /* bus control reg. and bus timing reg. for CS0..CS3 */ | ||
| 13 | #define FSMC_BCR(x) (NOMADIK_FSMC_VA + (x << 3)) | ||
| 14 | #define FSMC_BTR(x) (NOMADIK_FSMC_VA + (x << 3) + 0x04) | ||
| 15 | |||
| 16 | /* PC-card and NAND: | ||
| 17 | * PCR = control register | ||
| 18 | * PMEM = memory timing | ||
| 19 | * PATT = attribute timing | ||
| 20 | * PIO = I/O timing | ||
| 21 | * PECCR = ECC result | ||
| 22 | */ | ||
| 23 | #define FSMC_PCR(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x00) | ||
| 24 | #define FSMC_PMEM(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x08) | ||
| 25 | #define FSMC_PATT(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x0c) | ||
| 26 | #define FSMC_PIO(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x10) | ||
| 27 | #define FSMC_PECCR(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x14) | ||
| 28 | |||
| 29 | #endif /* __ASM_ARCH_FSMC_H */ | ||
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index 12f3994c43db..8b204ae69002 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c | |||
| @@ -250,6 +250,18 @@ static struct resource rtc_resources[] = { | |||
| 250 | */ | 250 | */ |
| 251 | static struct resource fsmc_resources[] = { | 251 | static struct resource fsmc_resources[] = { |
| 252 | { | 252 | { |
| 253 | .name = "nand_addr", | ||
| 254 | .start = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_ALE, | ||
| 255 | .end = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_ALE + SZ_16K - 1, | ||
| 256 | .flags = IORESOURCE_MEM, | ||
| 257 | }, | ||
| 258 | { | ||
| 259 | .name = "nand_cmd", | ||
| 260 | .start = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_CLE, | ||
| 261 | .end = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_CLE + SZ_16K - 1, | ||
| 262 | .flags = IORESOURCE_MEM, | ||
| 263 | }, | ||
| 264 | { | ||
| 253 | .name = "nand_data", | 265 | .name = "nand_data", |
| 254 | .start = U300_NAND_CS0_PHYS_BASE, | 266 | .start = U300_NAND_CS0_PHYS_BASE, |
| 255 | .end = U300_NAND_CS0_PHYS_BASE + SZ_16K - 1, | 267 | .end = U300_NAND_CS0_PHYS_BASE + SZ_16K - 1, |
| @@ -1492,8 +1504,6 @@ static struct fsmc_nand_platform_data nand_platform_data = { | |||
| 1492 | .nr_partitions = ARRAY_SIZE(u300_partitions), | 1504 | .nr_partitions = ARRAY_SIZE(u300_partitions), |
| 1493 | .options = NAND_SKIP_BBTSCAN, | 1505 | .options = NAND_SKIP_BBTSCAN, |
| 1494 | .width = FSMC_NAND_BW8, | 1506 | .width = FSMC_NAND_BW8, |
| 1495 | .ale_off = PLAT_NAND_ALE, | ||
| 1496 | .cle_off = PLAT_NAND_CLE, | ||
| 1497 | }; | 1507 | }; |
| 1498 | 1508 | ||
| 1499 | static struct platform_device nand_device = { | 1509 | static struct platform_device nand_device = { |
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c index e162999bf916..c62c788b3289 100644 --- a/drivers/bcma/driver_chipcommon_pmu.c +++ b/drivers/bcma/driver_chipcommon_pmu.c | |||
| @@ -13,12 +13,13 @@ | |||
| 13 | #include <linux/export.h> | 13 | #include <linux/export.h> |
| 14 | #include <linux/bcma/bcma.h> | 14 | #include <linux/bcma/bcma.h> |
| 15 | 15 | ||
| 16 | static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset) | 16 | u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset) |
| 17 | { | 17 | { |
| 18 | bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset); | 18 | bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset); |
| 19 | bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR); | 19 | bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR); |
| 20 | return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA); | 20 | return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA); |
| 21 | } | 21 | } |
| 22 | EXPORT_SYMBOL_GPL(bcma_chipco_pll_read); | ||
| 22 | 23 | ||
| 23 | void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value) | 24 | void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value) |
| 24 | { | 25 | { |
diff --git a/drivers/clk/clk-nomadik.c b/drivers/clk/clk-nomadik.c index 517a8ff7121e..6b4c70f7d23d 100644 --- a/drivers/clk/clk-nomadik.c +++ b/drivers/clk/clk-nomadik.c | |||
| @@ -20,6 +20,7 @@ void __init nomadik_clk_init(void) | |||
| 20 | clk_register_clkdev(clk, NULL, "gpio.2"); | 20 | clk_register_clkdev(clk, NULL, "gpio.2"); |
| 21 | clk_register_clkdev(clk, NULL, "gpio.3"); | 21 | clk_register_clkdev(clk, NULL, "gpio.3"); |
| 22 | clk_register_clkdev(clk, NULL, "rng"); | 22 | clk_register_clkdev(clk, NULL, "rng"); |
| 23 | clk_register_clkdev(clk, NULL, "fsmc-nand"); | ||
| 23 | 24 | ||
| 24 | /* | 25 | /* |
| 25 | * The 2.4 MHz TIMCLK reference clock is active at boot time, this is | 26 | * The 2.4 MHz TIMCLK reference clock is active at boot time, this is |
diff --git a/drivers/mtd/ar7part.c b/drivers/mtd/ar7part.c index 945393129952..7c057a05adb6 100644 --- a/drivers/mtd/ar7part.c +++ b/drivers/mtd/ar7part.c | |||
| @@ -26,19 +26,16 @@ | |||
| 26 | #include <linux/mtd/mtd.h> | 26 | #include <linux/mtd/mtd.h> |
| 27 | #include <linux/mtd/partitions.h> | 27 | #include <linux/mtd/partitions.h> |
| 28 | #include <linux/bootmem.h> | 28 | #include <linux/bootmem.h> |
| 29 | #include <linux/magic.h> | ||
| 30 | #include <linux/module.h> | 29 | #include <linux/module.h> |
| 31 | 30 | ||
| 31 | #include <uapi/linux/magic.h> | ||
| 32 | |||
| 32 | #define AR7_PARTS 4 | 33 | #define AR7_PARTS 4 |
| 33 | #define ROOT_OFFSET 0xe0000 | 34 | #define ROOT_OFFSET 0xe0000 |
| 34 | 35 | ||
| 35 | #define LOADER_MAGIC1 le32_to_cpu(0xfeedfa42) | 36 | #define LOADER_MAGIC1 le32_to_cpu(0xfeedfa42) |
| 36 | #define LOADER_MAGIC2 le32_to_cpu(0xfeed1281) | 37 | #define LOADER_MAGIC2 le32_to_cpu(0xfeed1281) |
| 37 | 38 | ||
| 38 | #ifndef SQUASHFS_MAGIC | ||
| 39 | #define SQUASHFS_MAGIC 0x73717368 | ||
| 40 | #endif | ||
| 41 | |||
| 42 | struct ar7_bin_rec { | 39 | struct ar7_bin_rec { |
| 43 | unsigned int checksum; | 40 | unsigned int checksum; |
| 44 | unsigned int length; | 41 | unsigned int length; |
diff --git a/drivers/mtd/bcm63xxpart.c b/drivers/mtd/bcm63xxpart.c index 63d2a64331f7..6eeb84c81bc2 100644 --- a/drivers/mtd/bcm63xxpart.c +++ b/drivers/mtd/bcm63xxpart.c | |||
| @@ -37,8 +37,7 @@ | |||
| 37 | 37 | ||
| 38 | #define BCM63XX_EXTENDED_SIZE 0xBFC00000 /* Extended flash address */ | 38 | #define BCM63XX_EXTENDED_SIZE 0xBFC00000 /* Extended flash address */ |
| 39 | 39 | ||
| 40 | #define BCM63XX_MIN_CFE_SIZE 0x10000 /* always at least 64KiB */ | 40 | #define BCM63XX_CFE_BLOCK_SIZE 0x10000 /* always at least 64KiB */ |
| 41 | #define BCM63XX_MIN_NVRAM_SIZE 0x10000 /* always at least 64KiB */ | ||
| 42 | 41 | ||
| 43 | #define BCM63XX_CFE_MAGIC_OFFSET 0x4e0 | 42 | #define BCM63XX_CFE_MAGIC_OFFSET 0x4e0 |
| 44 | 43 | ||
| @@ -79,7 +78,7 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, | |||
| 79 | unsigned int rootfsaddr, kerneladdr, spareaddr; | 78 | unsigned int rootfsaddr, kerneladdr, spareaddr; |
| 80 | unsigned int rootfslen, kernellen, sparelen, totallen; | 79 | unsigned int rootfslen, kernellen, sparelen, totallen; |
| 81 | unsigned int cfelen, nvramlen; | 80 | unsigned int cfelen, nvramlen; |
| 82 | int namelen = 0; | 81 | unsigned int cfe_erasesize; |
| 83 | int i; | 82 | int i; |
| 84 | u32 computed_crc; | 83 | u32 computed_crc; |
| 85 | bool rootfs_first = false; | 84 | bool rootfs_first = false; |
| @@ -87,8 +86,11 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, | |||
| 87 | if (bcm63xx_detect_cfe(master)) | 86 | if (bcm63xx_detect_cfe(master)) |
| 88 | return -EINVAL; | 87 | return -EINVAL; |
| 89 | 88 | ||
| 90 | cfelen = max_t(uint32_t, master->erasesize, BCM63XX_MIN_CFE_SIZE); | 89 | cfe_erasesize = max_t(uint32_t, master->erasesize, |
| 91 | nvramlen = max_t(uint32_t, master->erasesize, BCM63XX_MIN_NVRAM_SIZE); | 90 | BCM63XX_CFE_BLOCK_SIZE); |
| 91 | |||
| 92 | cfelen = cfe_erasesize; | ||
| 93 | nvramlen = cfe_erasesize; | ||
| 92 | 94 | ||
| 93 | /* Allocate memory for buffer */ | 95 | /* Allocate memory for buffer */ |
| 94 | buf = vmalloc(sizeof(struct bcm_tag)); | 96 | buf = vmalloc(sizeof(struct bcm_tag)); |
| @@ -121,7 +123,6 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, | |||
| 121 | kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE; | 123 | kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE; |
| 122 | rootfsaddr = rootfsaddr - BCM63XX_EXTENDED_SIZE; | 124 | rootfsaddr = rootfsaddr - BCM63XX_EXTENDED_SIZE; |
| 123 | spareaddr = roundup(totallen, master->erasesize) + cfelen; | 125 | spareaddr = roundup(totallen, master->erasesize) + cfelen; |
| 124 | sparelen = master->size - spareaddr - nvramlen; | ||
| 125 | 126 | ||
| 126 | if (rootfsaddr < kerneladdr) { | 127 | if (rootfsaddr < kerneladdr) { |
| 127 | /* default Broadcom layout */ | 128 | /* default Broadcom layout */ |
| @@ -139,19 +140,15 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, | |||
| 139 | rootfslen = 0; | 140 | rootfslen = 0; |
| 140 | rootfsaddr = 0; | 141 | rootfsaddr = 0; |
| 141 | spareaddr = cfelen; | 142 | spareaddr = cfelen; |
| 142 | sparelen = master->size - cfelen - nvramlen; | ||
| 143 | } | 143 | } |
| 144 | sparelen = master->size - spareaddr - nvramlen; | ||
| 144 | 145 | ||
| 145 | /* Determine number of partitions */ | 146 | /* Determine number of partitions */ |
| 146 | namelen = 8; | 147 | if (rootfslen > 0) |
| 147 | if (rootfslen > 0) { | ||
| 148 | nrparts++; | 148 | nrparts++; |
| 149 | namelen += 6; | 149 | |
| 150 | } | 150 | if (kernellen > 0) |
| 151 | if (kernellen > 0) { | ||
| 152 | nrparts++; | 151 | nrparts++; |
| 153 | namelen += 6; | ||
| 154 | } | ||
| 155 | 152 | ||
| 156 | /* Ask kernel for more memory */ | 153 | /* Ask kernel for more memory */ |
| 157 | parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL); | 154 | parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL); |
| @@ -193,17 +190,16 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, | |||
| 193 | parts[curpart].name = "nvram"; | 190 | parts[curpart].name = "nvram"; |
| 194 | parts[curpart].offset = master->size - nvramlen; | 191 | parts[curpart].offset = master->size - nvramlen; |
| 195 | parts[curpart].size = nvramlen; | 192 | parts[curpart].size = nvramlen; |
| 193 | curpart++; | ||
| 196 | 194 | ||
| 197 | /* Global partition "linux" to make easy firmware upgrade */ | 195 | /* Global partition "linux" to make easy firmware upgrade */ |
| 198 | curpart++; | ||
| 199 | parts[curpart].name = "linux"; | 196 | parts[curpart].name = "linux"; |
| 200 | parts[curpart].offset = cfelen; | 197 | parts[curpart].offset = cfelen; |
| 201 | parts[curpart].size = master->size - cfelen - nvramlen; | 198 | parts[curpart].size = master->size - cfelen - nvramlen; |
| 202 | 199 | ||
| 203 | for (i = 0; i < nrparts; i++) | 200 | for (i = 0; i < nrparts; i++) |
| 204 | pr_info("Partition %d is %s offset %lx and length %lx\n", i, | 201 | pr_info("Partition %d is %s offset %llx and length %llx\n", i, |
| 205 | parts[i].name, (long unsigned int)(parts[i].offset), | 202 | parts[i].name, parts[i].offset, parts[i].size); |
| 206 | (long unsigned int)(parts[i].size)); | ||
| 207 | 203 | ||
| 208 | pr_info("Spare partition is offset %x and length %x\n", spareaddr, | 204 | pr_info("Spare partition is offset %x and length %x\n", spareaddr, |
| 209 | sparelen); | 205 | sparelen); |
diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 5ff5c4a16943..b86197286f24 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c | |||
| @@ -1536,8 +1536,20 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, | |||
| 1536 | UDELAY(map, chip, adr, 1); | 1536 | UDELAY(map, chip, adr, 1); |
| 1537 | } | 1537 | } |
| 1538 | 1538 | ||
| 1539 | /* reset on all failures. */ | 1539 | /* |
| 1540 | map_write( map, CMD(0xF0), chip->start ); | 1540 | * Recovery from write-buffer programming failures requires |
| 1541 | * the write-to-buffer-reset sequence. Since the last part | ||
| 1542 | * of the sequence also works as a normal reset, we can run | ||
| 1543 | * the same commands regardless of why we are here. | ||
| 1544 | * See e.g. | ||
| 1545 | * http://www.spansion.com/Support/Application%20Notes/MirrorBit_Write_Buffer_Prog_Page_Buffer_Read_AN.pdf | ||
| 1546 | */ | ||
| 1547 | cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, | ||
| 1548 | cfi->device_type, NULL); | ||
| 1549 | cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, | ||
| 1550 | cfi->device_type, NULL); | ||
| 1551 | cfi_send_gen_cmd(0xF0, cfi->addr_unlock1, chip->start, map, cfi, | ||
| 1552 | cfi->device_type, NULL); | ||
| 1541 | xip_enable(map, chip, adr); | 1553 | xip_enable(map, chip, adr); |
| 1542 | /* FIXME - should have reset delay before continuing */ | 1554 | /* FIXME - should have reset delay before continuing */ |
| 1543 | 1555 | ||
diff --git a/drivers/mtd/cmdlinepart.c b/drivers/mtd/cmdlinepart.c index aed1b8a63c9f..c533f27d863f 100644 --- a/drivers/mtd/cmdlinepart.c +++ b/drivers/mtd/cmdlinepart.c | |||
| @@ -56,8 +56,8 @@ | |||
| 56 | 56 | ||
| 57 | 57 | ||
| 58 | /* special size referring to all the remaining space in a partition */ | 58 | /* special size referring to all the remaining space in a partition */ |
| 59 | #define SIZE_REMAINING UINT_MAX | 59 | #define SIZE_REMAINING ULLONG_MAX |
| 60 | #define OFFSET_CONTINUOUS UINT_MAX | 60 | #define OFFSET_CONTINUOUS ULLONG_MAX |
| 61 | 61 | ||
| 62 | struct cmdline_mtd_partition { | 62 | struct cmdline_mtd_partition { |
| 63 | struct cmdline_mtd_partition *next; | 63 | struct cmdline_mtd_partition *next; |
| @@ -89,7 +89,7 @@ static struct mtd_partition * newpart(char *s, | |||
| 89 | int extra_mem_size) | 89 | int extra_mem_size) |
| 90 | { | 90 | { |
| 91 | struct mtd_partition *parts; | 91 | struct mtd_partition *parts; |
| 92 | unsigned long size, offset = OFFSET_CONTINUOUS; | 92 | unsigned long long size, offset = OFFSET_CONTINUOUS; |
| 93 | char *name; | 93 | char *name; |
| 94 | int name_len; | 94 | int name_len; |
| 95 | unsigned char *extra_mem; | 95 | unsigned char *extra_mem; |
| @@ -104,7 +104,8 @@ static struct mtd_partition * newpart(char *s, | |||
| 104 | } else { | 104 | } else { |
| 105 | size = memparse(s, &s); | 105 | size = memparse(s, &s); |
| 106 | if (size < PAGE_SIZE) { | 106 | if (size < PAGE_SIZE) { |
| 107 | printk(KERN_ERR ERRP "partition size too small (%lx)\n", size); | 107 | printk(KERN_ERR ERRP "partition size too small (%llx)\n", |
| 108 | size); | ||
| 108 | return ERR_PTR(-EINVAL); | 109 | return ERR_PTR(-EINVAL); |
| 109 | } | 110 | } |
| 110 | } | 111 | } |
| @@ -296,7 +297,7 @@ static int parse_cmdline_partitions(struct mtd_info *master, | |||
| 296 | struct mtd_partition **pparts, | 297 | struct mtd_partition **pparts, |
| 297 | struct mtd_part_parser_data *data) | 298 | struct mtd_part_parser_data *data) |
| 298 | { | 299 | { |
| 299 | unsigned long offset; | 300 | unsigned long long offset; |
| 300 | int i, err; | 301 | int i, err; |
| 301 | struct cmdline_mtd_partition *part; | 302 | struct cmdline_mtd_partition *part; |
| 302 | const char *mtd_id = master->name; | 303 | const char *mtd_id = master->name; |
| @@ -308,48 +309,52 @@ static int parse_cmdline_partitions(struct mtd_info *master, | |||
| 308 | return err; | 309 | return err; |
| 309 | } | 310 | } |
| 310 | 311 | ||
| 312 | /* | ||
| 313 | * Search for the partition definition matching master->name. | ||
| 314 | * If master->name is not set, stop at first partition definition. | ||
| 315 | */ | ||
| 311 | for (part = partitions; part; part = part->next) { | 316 | for (part = partitions; part; part = part->next) { |
| 312 | if ((!mtd_id) || (!strcmp(part->mtd_id, mtd_id))) { | 317 | if ((!mtd_id) || (!strcmp(part->mtd_id, mtd_id))) |
| 313 | for (i = 0, offset = 0; i < part->num_parts; i++) { | 318 | break; |
| 314 | if (part->parts[i].offset == OFFSET_CONTINUOUS) | 319 | } |
| 315 | part->parts[i].offset = offset; | 320 | |
| 316 | else | 321 | if (!part) |
| 317 | offset = part->parts[i].offset; | 322 | return 0; |
| 318 | 323 | ||
| 319 | if (part->parts[i].size == SIZE_REMAINING) | 324 | for (i = 0, offset = 0; i < part->num_parts; i++) { |
| 320 | part->parts[i].size = master->size - offset; | 325 | if (part->parts[i].offset == OFFSET_CONTINUOUS) |
| 321 | 326 | part->parts[i].offset = offset; | |
| 322 | if (part->parts[i].size == 0) { | 327 | else |
| 323 | printk(KERN_WARNING ERRP | 328 | offset = part->parts[i].offset; |
| 324 | "%s: skipping zero sized partition\n", | 329 | |
| 325 | part->mtd_id); | 330 | if (part->parts[i].size == SIZE_REMAINING) |
| 326 | part->num_parts--; | 331 | part->parts[i].size = master->size - offset; |
| 327 | memmove(&part->parts[i], | 332 | |
| 328 | &part->parts[i + 1], | 333 | if (part->parts[i].size == 0) { |
| 329 | sizeof(*part->parts) * (part->num_parts - i)); | 334 | printk(KERN_WARNING ERRP |
| 330 | continue; | 335 | "%s: skipping zero sized partition\n", |
| 331 | } | 336 | part->mtd_id); |
| 332 | 337 | part->num_parts--; | |
| 333 | if (offset + part->parts[i].size > master->size) { | 338 | memmove(&part->parts[i], &part->parts[i + 1], |
| 334 | printk(KERN_WARNING ERRP | 339 | sizeof(*part->parts) * (part->num_parts - i)); |
| 335 | "%s: partitioning exceeds flash size, truncating\n", | 340 | continue; |
| 336 | part->mtd_id); | ||
| 337 | part->parts[i].size = master->size - offset; | ||
| 338 | } | ||
| 339 | offset += part->parts[i].size; | ||
| 340 | } | ||
| 341 | |||
| 342 | *pparts = kmemdup(part->parts, | ||
| 343 | sizeof(*part->parts) * part->num_parts, | ||
| 344 | GFP_KERNEL); | ||
| 345 | if (!*pparts) | ||
| 346 | return -ENOMEM; | ||
| 347 | |||
| 348 | return part->num_parts; | ||
| 349 | } | 341 | } |
| 342 | |||
| 343 | if (offset + part->parts[i].size > master->size) { | ||
| 344 | printk(KERN_WARNING ERRP | ||
| 345 | "%s: partitioning exceeds flash size, truncating\n", | ||
| 346 | part->mtd_id); | ||
| 347 | part->parts[i].size = master->size - offset; | ||
| 348 | } | ||
| 349 | offset += part->parts[i].size; | ||
| 350 | } | 350 | } |
| 351 | 351 | ||
| 352 | return 0; | 352 | *pparts = kmemdup(part->parts, sizeof(*part->parts) * part->num_parts, |
| 353 | GFP_KERNEL); | ||
| 354 | if (!*pparts) | ||
| 355 | return -ENOMEM; | ||
| 356 | |||
| 357 | return part->num_parts; | ||
| 353 | } | 358 | } |
| 354 | 359 | ||
| 355 | 360 | ||
diff --git a/drivers/mtd/devices/bcm47xxsflash.c b/drivers/mtd/devices/bcm47xxsflash.c index 2dc5a6f3fd57..4714584aa993 100644 --- a/drivers/mtd/devices/bcm47xxsflash.c +++ b/drivers/mtd/devices/bcm47xxsflash.c | |||
| @@ -66,7 +66,7 @@ out: | |||
| 66 | return err; | 66 | return err; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | static int __devexit bcm47xxsflash_remove(struct platform_device *pdev) | 69 | static int bcm47xxsflash_remove(struct platform_device *pdev) |
| 70 | { | 70 | { |
| 71 | struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev); | 71 | struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev); |
| 72 | 72 | ||
| @@ -77,7 +77,7 @@ static int __devexit bcm47xxsflash_remove(struct platform_device *pdev) | |||
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | static struct platform_driver bcma_sflash_driver = { | 79 | static struct platform_driver bcma_sflash_driver = { |
| 80 | .remove = __devexit_p(bcm47xxsflash_remove), | 80 | .remove = bcm47xxsflash_remove, |
| 81 | .driver = { | 81 | .driver = { |
| 82 | .name = "bcma_sflash", | 82 | .name = "bcma_sflash", |
| 83 | .owner = THIS_MODULE, | 83 | .owner = THIS_MODULE, |
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index 681e2ee0f2d6..e081bfeaaf7d 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c | |||
| @@ -62,6 +62,7 @@ static int _block2mtd_erase(struct block2mtd_dev *dev, loff_t to, size_t len) | |||
| 62 | memset(page_address(page), 0xff, PAGE_SIZE); | 62 | memset(page_address(page), 0xff, PAGE_SIZE); |
| 63 | set_page_dirty(page); | 63 | set_page_dirty(page); |
| 64 | unlock_page(page); | 64 | unlock_page(page); |
| 65 | balance_dirty_pages_ratelimited(mapping); | ||
| 65 | break; | 66 | break; |
| 66 | } | 67 | } |
| 67 | 68 | ||
| @@ -152,6 +153,7 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf, | |||
| 152 | memcpy(page_address(page) + offset, buf, cpylen); | 153 | memcpy(page_address(page) + offset, buf, cpylen); |
| 153 | set_page_dirty(page); | 154 | set_page_dirty(page); |
| 154 | unlock_page(page); | 155 | unlock_page(page); |
| 156 | balance_dirty_pages_ratelimited(mapping); | ||
| 155 | } | 157 | } |
| 156 | page_cache_release(page); | 158 | page_cache_release(page); |
| 157 | 159 | ||
| @@ -433,7 +435,7 @@ static int __init block2mtd_init(void) | |||
| 433 | } | 435 | } |
| 434 | 436 | ||
| 435 | 437 | ||
| 436 | static void __devexit block2mtd_exit(void) | 438 | static void block2mtd_exit(void) |
| 437 | { | 439 | { |
| 438 | struct list_head *pos, *next; | 440 | struct list_head *pos, *next; |
| 439 | 441 | ||
diff --git a/drivers/mtd/devices/docg3.c b/drivers/mtd/devices/docg3.c index d34d83b8f9c2..8510ccb9c6f0 100644 --- a/drivers/mtd/devices/docg3.c +++ b/drivers/mtd/devices/docg3.c | |||
| @@ -1440,7 +1440,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, | |||
| 1440 | oobdelta = mtd->ecclayout->oobavail; | 1440 | oobdelta = mtd->ecclayout->oobavail; |
| 1441 | break; | 1441 | break; |
| 1442 | default: | 1442 | default: |
| 1443 | oobdelta = 0; | 1443 | return -EINVAL; |
| 1444 | } | 1444 | } |
| 1445 | if ((len % DOC_LAYOUT_PAGE_SIZE) || (ooblen % oobdelta) || | 1445 | if ((len % DOC_LAYOUT_PAGE_SIZE) || (ooblen % oobdelta) || |
| 1446 | (ofs % DOC_LAYOUT_PAGE_SIZE)) | 1446 | (ofs % DOC_LAYOUT_PAGE_SIZE)) |
diff --git a/drivers/mtd/devices/docprobe.c b/drivers/mtd/devices/docprobe.c index 706b847b46b3..88b3fd3e18a7 100644 --- a/drivers/mtd/devices/docprobe.c +++ b/drivers/mtd/devices/docprobe.c | |||
| @@ -70,8 +70,6 @@ static unsigned long __initdata doc_locations[] = { | |||
| 70 | 0xe0000, 0xe2000, 0xe4000, 0xe6000, | 70 | 0xe0000, 0xe2000, 0xe4000, 0xe6000, |
| 71 | 0xe8000, 0xea000, 0xec000, 0xee000, | 71 | 0xe8000, 0xea000, 0xec000, 0xee000, |
| 72 | #endif /* CONFIG_MTD_DOCPROBE_HIGH */ | 72 | #endif /* CONFIG_MTD_DOCPROBE_HIGH */ |
| 73 | #else | ||
| 74 | #warning Unknown architecture for DiskOnChip. No default probe locations defined | ||
| 75 | #endif | 73 | #endif |
| 76 | 0xffffffff }; | 74 | 0xffffffff }; |
| 77 | 75 | ||
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 03838bab1f59..4eeeb2d7f6ea 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c | |||
| @@ -73,14 +73,6 @@ | |||
| 73 | #define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */ | 73 | #define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */ |
| 74 | #define MAX_CMD_SIZE 5 | 74 | #define MAX_CMD_SIZE 5 |
| 75 | 75 | ||
| 76 | #ifdef CONFIG_M25PXX_USE_FAST_READ | ||
| 77 | #define OPCODE_READ OPCODE_FAST_READ | ||
| 78 | #define FAST_READ_DUMMY_BYTE 1 | ||
| 79 | #else | ||
| 80 | #define OPCODE_READ OPCODE_NORM_READ | ||
| 81 | #define FAST_READ_DUMMY_BYTE 0 | ||
| 82 | #endif | ||
| 83 | |||
| 84 | #define JEDEC_MFR(_jedec_id) ((_jedec_id) >> 16) | 76 | #define JEDEC_MFR(_jedec_id) ((_jedec_id) >> 16) |
| 85 | 77 | ||
| 86 | /****************************************************************************/ | 78 | /****************************************************************************/ |
| @@ -93,6 +85,7 @@ struct m25p { | |||
| 93 | u16 addr_width; | 85 | u16 addr_width; |
| 94 | u8 erase_opcode; | 86 | u8 erase_opcode; |
| 95 | u8 *command; | 87 | u8 *command; |
| 88 | bool fast_read; | ||
| 96 | }; | 89 | }; |
| 97 | 90 | ||
| 98 | static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd) | 91 | static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd) |
| @@ -168,6 +161,7 @@ static inline int set_4byte(struct m25p *flash, u32 jedec_id, int enable) | |||
| 168 | { | 161 | { |
| 169 | switch (JEDEC_MFR(jedec_id)) { | 162 | switch (JEDEC_MFR(jedec_id)) { |
| 170 | case CFI_MFR_MACRONIX: | 163 | case CFI_MFR_MACRONIX: |
| 164 | case 0xEF /* winbond */: | ||
| 171 | flash->command[0] = enable ? OPCODE_EN4B : OPCODE_EX4B; | 165 | flash->command[0] = enable ? OPCODE_EN4B : OPCODE_EX4B; |
| 172 | return spi_write(flash->spi, flash->command, 1); | 166 | return spi_write(flash->spi, flash->command, 1); |
| 173 | default: | 167 | default: |
| @@ -342,6 +336,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
| 342 | struct m25p *flash = mtd_to_m25p(mtd); | 336 | struct m25p *flash = mtd_to_m25p(mtd); |
| 343 | struct spi_transfer t[2]; | 337 | struct spi_transfer t[2]; |
| 344 | struct spi_message m; | 338 | struct spi_message m; |
| 339 | uint8_t opcode; | ||
| 345 | 340 | ||
| 346 | pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev), | 341 | pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev), |
| 347 | __func__, (u32)from, len); | 342 | __func__, (u32)from, len); |
| @@ -354,7 +349,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
| 354 | * Should add 1 byte DUMMY_BYTE. | 349 | * Should add 1 byte DUMMY_BYTE. |
| 355 | */ | 350 | */ |
| 356 | t[0].tx_buf = flash->command; | 351 | t[0].tx_buf = flash->command; |
| 357 | t[0].len = m25p_cmdsz(flash) + FAST_READ_DUMMY_BYTE; | 352 | t[0].len = m25p_cmdsz(flash) + (flash->fast_read ? 1 : 0); |
| 358 | spi_message_add_tail(&t[0], &m); | 353 | spi_message_add_tail(&t[0], &m); |
| 359 | 354 | ||
| 360 | t[1].rx_buf = buf; | 355 | t[1].rx_buf = buf; |
| @@ -376,12 +371,14 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, | |||
| 376 | */ | 371 | */ |
| 377 | 372 | ||
| 378 | /* Set up the write data buffer. */ | 373 | /* Set up the write data buffer. */ |
| 379 | flash->command[0] = OPCODE_READ; | 374 | opcode = flash->fast_read ? OPCODE_FAST_READ : OPCODE_NORM_READ; |
| 375 | flash->command[0] = opcode; | ||
| 380 | m25p_addr2cmd(flash, from, flash->command); | 376 | m25p_addr2cmd(flash, from, flash->command); |
| 381 | 377 | ||
| 382 | spi_sync(flash->spi, &m); | 378 | spi_sync(flash->spi, &m); |
| 383 | 379 | ||
| 384 | *retlen = m.actual_length - m25p_cmdsz(flash) - FAST_READ_DUMMY_BYTE; | 380 | *retlen = m.actual_length - m25p_cmdsz(flash) - |
| 381 | (flash->fast_read ? 1 : 0); | ||
| 385 | 382 | ||
| 386 | mutex_unlock(&flash->lock); | 383 | mutex_unlock(&flash->lock); |
| 387 | 384 | ||
| @@ -664,7 +661,8 @@ static const struct spi_device_id m25p_ids[] = { | |||
| 664 | { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, | 661 | { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, |
| 665 | 662 | ||
| 666 | /* Micron */ | 663 | /* Micron */ |
| 667 | { "n25q128", INFO(0x20ba18, 0, 64 * 1024, 256, 0) }, | 664 | { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, 0) }, |
| 665 | { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, 0) }, | ||
| 668 | { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) }, | 666 | { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) }, |
| 669 | 667 | ||
| 670 | /* Spansion -- single (large) sector size only, at least | 668 | /* Spansion -- single (large) sector size only, at least |
| @@ -745,6 +743,8 @@ static const struct spi_device_id m25p_ids[] = { | |||
| 745 | { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, | 743 | { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, |
| 746 | { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, | 744 | { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, |
| 747 | { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) }, | 745 | { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) }, |
| 746 | { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) }, | ||
| 747 | { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K) }, | ||
| 748 | 748 | ||
| 749 | /* Catalyst / On Semiconductor -- non-JEDEC */ | 749 | /* Catalyst / On Semiconductor -- non-JEDEC */ |
| 750 | { "cat25c11", CAT25_INFO( 16, 8, 16, 1) }, | 750 | { "cat25c11", CAT25_INFO( 16, 8, 16, 1) }, |
| @@ -756,7 +756,7 @@ static const struct spi_device_id m25p_ids[] = { | |||
| 756 | }; | 756 | }; |
| 757 | MODULE_DEVICE_TABLE(spi, m25p_ids); | 757 | MODULE_DEVICE_TABLE(spi, m25p_ids); |
| 758 | 758 | ||
| 759 | static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi) | 759 | static const struct spi_device_id *jedec_probe(struct spi_device *spi) |
| 760 | { | 760 | { |
| 761 | int tmp; | 761 | int tmp; |
| 762 | u8 code = OPCODE_RDID; | 762 | u8 code = OPCODE_RDID; |
| @@ -801,7 +801,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi) | |||
| 801 | * matches what the READ command supports, at least until this driver | 801 | * matches what the READ command supports, at least until this driver |
| 802 | * understands FAST_READ (for clocks over 25 MHz). | 802 | * understands FAST_READ (for clocks over 25 MHz). |
| 803 | */ | 803 | */ |
| 804 | static int __devinit m25p_probe(struct spi_device *spi) | 804 | static int m25p_probe(struct spi_device *spi) |
| 805 | { | 805 | { |
| 806 | const struct spi_device_id *id = spi_get_device_id(spi); | 806 | const struct spi_device_id *id = spi_get_device_id(spi); |
| 807 | struct flash_platform_data *data; | 807 | struct flash_platform_data *data; |
| @@ -809,9 +809,10 @@ static int __devinit m25p_probe(struct spi_device *spi) | |||
| 809 | struct flash_info *info; | 809 | struct flash_info *info; |
| 810 | unsigned i; | 810 | unsigned i; |
| 811 | struct mtd_part_parser_data ppdata; | 811 | struct mtd_part_parser_data ppdata; |
| 812 | struct device_node __maybe_unused *np = spi->dev.of_node; | ||
| 812 | 813 | ||
| 813 | #ifdef CONFIG_MTD_OF_PARTS | 814 | #ifdef CONFIG_MTD_OF_PARTS |
| 814 | if (!of_device_is_available(spi->dev.of_node)) | 815 | if (!of_device_is_available(np)) |
| 815 | return -ENODEV; | 816 | return -ENODEV; |
| 816 | #endif | 817 | #endif |
| 817 | 818 | ||
| @@ -863,7 +864,8 @@ static int __devinit m25p_probe(struct spi_device *spi) | |||
| 863 | flash = kzalloc(sizeof *flash, GFP_KERNEL); | 864 | flash = kzalloc(sizeof *flash, GFP_KERNEL); |
| 864 | if (!flash) | 865 | if (!flash) |
| 865 | return -ENOMEM; | 866 | return -ENOMEM; |
| 866 | flash->command = kmalloc(MAX_CMD_SIZE + FAST_READ_DUMMY_BYTE, GFP_KERNEL); | 867 | flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 : 0), |
| 868 | GFP_KERNEL); | ||
| 867 | if (!flash->command) { | 869 | if (!flash->command) { |
| 868 | kfree(flash); | 870 | kfree(flash); |
| 869 | return -ENOMEM; | 871 | return -ENOMEM; |
| @@ -920,6 +922,16 @@ static int __devinit m25p_probe(struct spi_device *spi) | |||
| 920 | flash->page_size = info->page_size; | 922 | flash->page_size = info->page_size; |
| 921 | flash->mtd.writebufsize = flash->page_size; | 923 | flash->mtd.writebufsize = flash->page_size; |
| 922 | 924 | ||
| 925 | flash->fast_read = false; | ||
| 926 | #ifdef CONFIG_OF | ||
| 927 | if (np && of_property_read_bool(np, "m25p,fast-read")) | ||
| 928 | flash->fast_read = true; | ||
| 929 | #endif | ||
| 930 | |||
| 931 | #ifdef CONFIG_M25PXX_USE_FAST_READ | ||
| 932 | flash->fast_read = true; | ||
| 933 | #endif | ||
| 934 | |||
| 923 | if (info->addr_width) | 935 | if (info->addr_width) |
| 924 | flash->addr_width = info->addr_width; | 936 | flash->addr_width = info->addr_width; |
| 925 | else { | 937 | else { |
| @@ -961,7 +973,7 @@ static int __devinit m25p_probe(struct spi_device *spi) | |||
| 961 | } | 973 | } |
| 962 | 974 | ||
| 963 | 975 | ||
| 964 | static int __devexit m25p_remove(struct spi_device *spi) | 976 | static int m25p_remove(struct spi_device *spi) |
| 965 | { | 977 | { |
| 966 | struct m25p *flash = dev_get_drvdata(&spi->dev); | 978 | struct m25p *flash = dev_get_drvdata(&spi->dev); |
| 967 | int status; | 979 | int status; |
| @@ -983,7 +995,7 @@ static struct spi_driver m25p80_driver = { | |||
| 983 | }, | 995 | }, |
| 984 | .id_table = m25p_ids, | 996 | .id_table = m25p_ids, |
| 985 | .probe = m25p_probe, | 997 | .probe = m25p_probe, |
| 986 | .remove = __devexit_p(m25p_remove), | 998 | .remove = m25p_remove, |
| 987 | 999 | ||
| 988 | /* REVISIT: many of these chips have deep power-down modes, which | 1000 | /* REVISIT: many of these chips have deep power-down modes, which |
| 989 | * should clearly be entered on suspend() to minimize power use. | 1001 | * should clearly be entered on suspend() to minimize power use. |
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index 928fb0e6d73a..ea7ea7b595d8 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c | |||
| @@ -618,7 +618,7 @@ static char *otp_setup(struct mtd_info *device, char revision) | |||
| 618 | /* | 618 | /* |
| 619 | * Register DataFlash device with MTD subsystem. | 619 | * Register DataFlash device with MTD subsystem. |
| 620 | */ | 620 | */ |
| 621 | static int __devinit | 621 | static int |
| 622 | add_dataflash_otp(struct spi_device *spi, char *name, | 622 | add_dataflash_otp(struct spi_device *spi, char *name, |
| 623 | int nr_pages, int pagesize, int pageoffset, char revision) | 623 | int nr_pages, int pagesize, int pageoffset, char revision) |
| 624 | { | 624 | { |
| @@ -679,7 +679,7 @@ add_dataflash_otp(struct spi_device *spi, char *name, | |||
| 679 | return err; | 679 | return err; |
| 680 | } | 680 | } |
| 681 | 681 | ||
| 682 | static inline int __devinit | 682 | static inline int |
| 683 | add_dataflash(struct spi_device *spi, char *name, | 683 | add_dataflash(struct spi_device *spi, char *name, |
| 684 | int nr_pages, int pagesize, int pageoffset) | 684 | int nr_pages, int pagesize, int pageoffset) |
| 685 | { | 685 | { |
| @@ -705,7 +705,7 @@ struct flash_info { | |||
| 705 | #define IS_POW2PS 0x0001 /* uses 2^N byte pages */ | 705 | #define IS_POW2PS 0x0001 /* uses 2^N byte pages */ |
| 706 | }; | 706 | }; |
| 707 | 707 | ||
| 708 | static struct flash_info __devinitdata dataflash_data [] = { | 708 | static struct flash_info dataflash_data[] = { |
| 709 | 709 | ||
| 710 | /* | 710 | /* |
| 711 | * NOTE: chips with SUP_POW2PS (rev D and up) need two entries, | 711 | * NOTE: chips with SUP_POW2PS (rev D and up) need two entries, |
| @@ -740,7 +740,7 @@ static struct flash_info __devinitdata dataflash_data [] = { | |||
| 740 | { "at45db642d", 0x1f2800, 8192, 1024, 10, SUP_POW2PS | IS_POW2PS}, | 740 | { "at45db642d", 0x1f2800, 8192, 1024, 10, SUP_POW2PS | IS_POW2PS}, |
| 741 | }; | 741 | }; |
| 742 | 742 | ||
| 743 | static struct flash_info *__devinit jedec_probe(struct spi_device *spi) | 743 | static struct flash_info *jedec_probe(struct spi_device *spi) |
| 744 | { | 744 | { |
| 745 | int tmp; | 745 | int tmp; |
| 746 | uint8_t code = OP_READ_ID; | 746 | uint8_t code = OP_READ_ID; |
| @@ -823,7 +823,7 @@ static struct flash_info *__devinit jedec_probe(struct spi_device *spi) | |||
| 823 | * AT45DB0642 64Mbit (8M) xx111xxx (0x3c) 8192 1056 11 | 823 | * AT45DB0642 64Mbit (8M) xx111xxx (0x3c) 8192 1056 11 |
| 824 | * AT45DB1282 128Mbit (16M) xx0100xx (0x10) 16384 1056 11 | 824 | * AT45DB1282 128Mbit (16M) xx0100xx (0x10) 16384 1056 11 |
| 825 | */ | 825 | */ |
| 826 | static int __devinit dataflash_probe(struct spi_device *spi) | 826 | static int dataflash_probe(struct spi_device *spi) |
| 827 | { | 827 | { |
| 828 | int status; | 828 | int status; |
| 829 | struct flash_info *info; | 829 | struct flash_info *info; |
| @@ -897,7 +897,7 @@ static int __devinit dataflash_probe(struct spi_device *spi) | |||
| 897 | return status; | 897 | return status; |
| 898 | } | 898 | } |
| 899 | 899 | ||
| 900 | static int __devexit dataflash_remove(struct spi_device *spi) | 900 | static int dataflash_remove(struct spi_device *spi) |
| 901 | { | 901 | { |
| 902 | struct dataflash *flash = dev_get_drvdata(&spi->dev); | 902 | struct dataflash *flash = dev_get_drvdata(&spi->dev); |
| 903 | int status; | 903 | int status; |
| @@ -920,7 +920,7 @@ static struct spi_driver dataflash_driver = { | |||
| 920 | }, | 920 | }, |
| 921 | 921 | ||
| 922 | .probe = dataflash_probe, | 922 | .probe = dataflash_probe, |
| 923 | .remove = __devexit_p(dataflash_remove), | 923 | .remove = dataflash_remove, |
| 924 | 924 | ||
| 925 | /* FIXME: investigate suspend and resume... */ | 925 | /* FIXME: investigate suspend and resume... */ |
| 926 | }; | 926 | }; |
diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c index dcc3c9511530..2d2c2a5d4d2a 100644 --- a/drivers/mtd/devices/spear_smi.c +++ b/drivers/mtd/devices/spear_smi.c | |||
| @@ -756,7 +756,7 @@ err_probe: | |||
| 756 | 756 | ||
| 757 | 757 | ||
| 758 | #ifdef CONFIG_OF | 758 | #ifdef CONFIG_OF |
| 759 | static int __devinit spear_smi_probe_config_dt(struct platform_device *pdev, | 759 | static int spear_smi_probe_config_dt(struct platform_device *pdev, |
| 760 | struct device_node *np) | 760 | struct device_node *np) |
| 761 | { | 761 | { |
| 762 | struct spear_smi_plat_data *pdata = dev_get_platdata(&pdev->dev); | 762 | struct spear_smi_plat_data *pdata = dev_get_platdata(&pdev->dev); |
| @@ -799,7 +799,7 @@ static int __devinit spear_smi_probe_config_dt(struct platform_device *pdev, | |||
| 799 | return 0; | 799 | return 0; |
| 800 | } | 800 | } |
| 801 | #else | 801 | #else |
| 802 | static int __devinit spear_smi_probe_config_dt(struct platform_device *pdev, | 802 | static int spear_smi_probe_config_dt(struct platform_device *pdev, |
| 803 | struct device_node *np) | 803 | struct device_node *np) |
| 804 | { | 804 | { |
| 805 | return -ENOSYS; | 805 | return -ENOSYS; |
| @@ -901,7 +901,7 @@ static int spear_smi_setup_banks(struct platform_device *pdev, | |||
| 901 | * and do proper init for any found one. | 901 | * and do proper init for any found one. |
| 902 | * Returns 0 on success, non zero otherwise | 902 | * Returns 0 on success, non zero otherwise |
| 903 | */ | 903 | */ |
| 904 | static int __devinit spear_smi_probe(struct platform_device *pdev) | 904 | static int spear_smi_probe(struct platform_device *pdev) |
| 905 | { | 905 | { |
| 906 | struct device_node *np = pdev->dev.of_node; | 906 | struct device_node *np = pdev->dev.of_node; |
| 907 | struct spear_smi_plat_data *pdata = NULL; | 907 | struct spear_smi_plat_data *pdata = NULL; |
| @@ -1016,7 +1016,7 @@ err: | |||
| 1016 | * | 1016 | * |
| 1017 | * free all allocations and delete the partitions. | 1017 | * free all allocations and delete the partitions. |
| 1018 | */ | 1018 | */ |
| 1019 | static int __devexit spear_smi_remove(struct platform_device *pdev) | 1019 | static int spear_smi_remove(struct platform_device *pdev) |
| 1020 | { | 1020 | { |
| 1021 | struct spear_smi *dev; | 1021 | struct spear_smi *dev; |
| 1022 | struct spear_snor_flash *flash; | 1022 | struct spear_snor_flash *flash; |
| @@ -1092,20 +1092,9 @@ static struct platform_driver spear_smi_driver = { | |||
| 1092 | #endif | 1092 | #endif |
| 1093 | }, | 1093 | }, |
| 1094 | .probe = spear_smi_probe, | 1094 | .probe = spear_smi_probe, |
| 1095 | .remove = __devexit_p(spear_smi_remove), | 1095 | .remove = spear_smi_remove, |
| 1096 | }; | 1096 | }; |
| 1097 | 1097 | module_platform_driver(spear_smi_driver); | |
| 1098 | static int spear_smi_init(void) | ||
| 1099 | { | ||
| 1100 | return platform_driver_register(&spear_smi_driver); | ||
| 1101 | } | ||
| 1102 | module_init(spear_smi_init); | ||
| 1103 | |||
| 1104 | static void spear_smi_exit(void) | ||
| 1105 | { | ||
| 1106 | platform_driver_unregister(&spear_smi_driver); | ||
| 1107 | } | ||
| 1108 | module_exit(spear_smi_exit); | ||
| 1109 | 1098 | ||
| 1110 | MODULE_LICENSE("GPL"); | 1099 | MODULE_LICENSE("GPL"); |
| 1111 | MODULE_AUTHOR("Ashish Priyadarshi, Shiraz Hashim <shiraz.hashim@st.com>"); | 1100 | MODULE_AUTHOR("Ashish Priyadarshi, Shiraz Hashim <shiraz.hashim@st.com>"); |
diff --git a/drivers/mtd/devices/sst25l.c b/drivers/mtd/devices/sst25l.c index ab8a2f4c8d60..8091b0163694 100644 --- a/drivers/mtd/devices/sst25l.c +++ b/drivers/mtd/devices/sst25l.c | |||
| @@ -64,7 +64,7 @@ struct flash_info { | |||
| 64 | 64 | ||
| 65 | #define to_sst25l_flash(x) container_of(x, struct sst25l_flash, mtd) | 65 | #define to_sst25l_flash(x) container_of(x, struct sst25l_flash, mtd) |
| 66 | 66 | ||
| 67 | static struct flash_info __devinitdata sst25l_flash_info[] = { | 67 | static struct flash_info sst25l_flash_info[] = { |
| 68 | {"sst25lf020a", 0xbf43, 256, 1024, 4096}, | 68 | {"sst25lf020a", 0xbf43, 256, 1024, 4096}, |
| 69 | {"sst25lf040a", 0xbf44, 256, 2048, 4096}, | 69 | {"sst25lf040a", 0xbf44, 256, 2048, 4096}, |
| 70 | }; | 70 | }; |
| @@ -313,7 +313,7 @@ out: | |||
| 313 | return ret; | 313 | return ret; |
| 314 | } | 314 | } |
| 315 | 315 | ||
| 316 | static struct flash_info *__devinit sst25l_match_device(struct spi_device *spi) | 316 | static struct flash_info *sst25l_match_device(struct spi_device *spi) |
| 317 | { | 317 | { |
| 318 | struct flash_info *flash_info = NULL; | 318 | struct flash_info *flash_info = NULL; |
| 319 | struct spi_message m; | 319 | struct spi_message m; |
| @@ -353,7 +353,7 @@ static struct flash_info *__devinit sst25l_match_device(struct spi_device *spi) | |||
| 353 | return flash_info; | 353 | return flash_info; |
| 354 | } | 354 | } |
| 355 | 355 | ||
| 356 | static int __devinit sst25l_probe(struct spi_device *spi) | 356 | static int sst25l_probe(struct spi_device *spi) |
| 357 | { | 357 | { |
| 358 | struct flash_info *flash_info; | 358 | struct flash_info *flash_info; |
| 359 | struct sst25l_flash *flash; | 359 | struct sst25l_flash *flash; |
| @@ -411,7 +411,7 @@ static int __devinit sst25l_probe(struct spi_device *spi) | |||
| 411 | return 0; | 411 | return 0; |
| 412 | } | 412 | } |
| 413 | 413 | ||
| 414 | static int __devexit sst25l_remove(struct spi_device *spi) | 414 | static int sst25l_remove(struct spi_device *spi) |
| 415 | { | 415 | { |
| 416 | struct sst25l_flash *flash = dev_get_drvdata(&spi->dev); | 416 | struct sst25l_flash *flash = dev_get_drvdata(&spi->dev); |
| 417 | int ret; | 417 | int ret; |
| @@ -428,7 +428,7 @@ static struct spi_driver sst25l_driver = { | |||
| 428 | .owner = THIS_MODULE, | 428 | .owner = THIS_MODULE, |
| 429 | }, | 429 | }, |
| 430 | .probe = sst25l_probe, | 430 | .probe = sst25l_probe, |
| 431 | .remove = __devexit_p(sst25l_remove), | 431 | .remove = sst25l_remove, |
| 432 | }; | 432 | }; |
| 433 | 433 | ||
| 434 | module_spi_driver(sst25l_driver); | 434 | module_spi_driver(sst25l_driver); |
diff --git a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig index df304868bebb..62ba82c396c2 100644 --- a/drivers/mtd/maps/Kconfig +++ b/drivers/mtd/maps/Kconfig | |||
| @@ -358,13 +358,6 @@ config MTD_IXP2000 | |||
| 358 | IXP2000 based board and would like to use the flash chips on it, | 358 | IXP2000 based board and would like to use the flash chips on it, |
| 359 | say 'Y'. | 359 | say 'Y'. |
| 360 | 360 | ||
| 361 | config MTD_FORTUNET | ||
| 362 | tristate "CFI Flash device mapped on the FortuNet board" | ||
| 363 | depends on MTD_CFI && SA1100_FORTUNET | ||
| 364 | help | ||
| 365 | This enables access to the Flash on the FortuNet board. If you | ||
| 366 | have such a board, say 'Y'. | ||
| 367 | |||
| 368 | config MTD_AUTCPU12 | 361 | config MTD_AUTCPU12 |
| 369 | bool "NV-RAM mapping AUTCPU12 board" | 362 | bool "NV-RAM mapping AUTCPU12 board" |
| 370 | depends on ARCH_AUTCPU12 | 363 | depends on ARCH_AUTCPU12 |
diff --git a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile index a0240edd1961..4ded28711bc1 100644 --- a/drivers/mtd/maps/Makefile +++ b/drivers/mtd/maps/Makefile | |||
| @@ -39,7 +39,6 @@ obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o | |||
| 39 | obj-$(CONFIG_MTD_PCI) += pci.o | 39 | obj-$(CONFIG_MTD_PCI) += pci.o |
| 40 | obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o | 40 | obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o |
| 41 | obj-$(CONFIG_MTD_IMPA7) += impa7.o | 41 | obj-$(CONFIG_MTD_IMPA7) += impa7.o |
| 42 | obj-$(CONFIG_MTD_FORTUNET) += fortunet.o | ||
| 43 | obj-$(CONFIG_MTD_UCLINUX) += uclinux.o | 42 | obj-$(CONFIG_MTD_UCLINUX) += uclinux.o |
| 44 | obj-$(CONFIG_MTD_NETtel) += nettel.o | 43 | obj-$(CONFIG_MTD_NETtel) += nettel.o |
| 45 | obj-$(CONFIG_MTD_SCB2_FLASH) += scb2_flash.o | 44 | obj-$(CONFIG_MTD_SCB2_FLASH) += scb2_flash.o |
diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c index e2875d6fe129..f7207b0a76dc 100644 --- a/drivers/mtd/maps/amd76xrom.c +++ b/drivers/mtd/maps/amd76xrom.c | |||
| @@ -100,8 +100,8 @@ static void amd76xrom_cleanup(struct amd76xrom_window *window) | |||
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | 102 | ||
| 103 | static int __devinit amd76xrom_init_one (struct pci_dev *pdev, | 103 | static int amd76xrom_init_one(struct pci_dev *pdev, |
| 104 | const struct pci_device_id *ent) | 104 | const struct pci_device_id *ent) |
| 105 | { | 105 | { |
| 106 | static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; | 106 | static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; |
| 107 | u8 byte; | 107 | u8 byte; |
| @@ -289,7 +289,7 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev, | |||
| 289 | } | 289 | } |
| 290 | 290 | ||
| 291 | 291 | ||
| 292 | static void __devexit amd76xrom_remove_one (struct pci_dev *pdev) | 292 | static void amd76xrom_remove_one(struct pci_dev *pdev) |
| 293 | { | 293 | { |
| 294 | struct amd76xrom_window *window = &amd76xrom_window; | 294 | struct amd76xrom_window *window = &amd76xrom_window; |
| 295 | 295 | ||
| @@ -347,4 +347,3 @@ module_exit(cleanup_amd76xrom); | |||
| 347 | MODULE_LICENSE("GPL"); | 347 | MODULE_LICENSE("GPL"); |
| 348 | MODULE_AUTHOR("Eric Biederman <ebiederman@lnxi.com>"); | 348 | MODULE_AUTHOR("Eric Biederman <ebiederman@lnxi.com>"); |
| 349 | MODULE_DESCRIPTION("MTD map driver for BIOS chips on the AMD76X southbridge"); | 349 | MODULE_DESCRIPTION("MTD map driver for BIOS chips on the AMD76X southbridge"); |
| 350 | |||
diff --git a/drivers/mtd/maps/autcpu12-nvram.c b/drivers/mtd/maps/autcpu12-nvram.c index 76fb594bb1d9..a2dc2ae4b24e 100644 --- a/drivers/mtd/maps/autcpu12-nvram.c +++ b/drivers/mtd/maps/autcpu12-nvram.c | |||
| @@ -33,7 +33,7 @@ struct autcpu12_nvram_priv { | |||
| 33 | struct map_info map; | 33 | struct map_info map; |
| 34 | }; | 34 | }; |
| 35 | 35 | ||
| 36 | static int __devinit autcpu12_nvram_probe(struct platform_device *pdev) | 36 | static int autcpu12_nvram_probe(struct platform_device *pdev) |
| 37 | { | 37 | { |
| 38 | map_word tmp, save0, save1; | 38 | map_word tmp, save0, save1; |
| 39 | struct resource *res; | 39 | struct resource *res; |
| @@ -105,7 +105,7 @@ static int __devinit autcpu12_nvram_probe(struct platform_device *pdev) | |||
| 105 | return -ENOMEM; | 105 | return -ENOMEM; |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | static int __devexit autcpu12_nvram_remove(struct platform_device *pdev) | 108 | static int autcpu12_nvram_remove(struct platform_device *pdev) |
| 109 | { | 109 | { |
| 110 | struct autcpu12_nvram_priv *priv = platform_get_drvdata(pdev); | 110 | struct autcpu12_nvram_priv *priv = platform_get_drvdata(pdev); |
| 111 | 111 | ||
| @@ -121,7 +121,7 @@ static struct platform_driver autcpu12_nvram_driver = { | |||
| 121 | .owner = THIS_MODULE, | 121 | .owner = THIS_MODULE, |
| 122 | }, | 122 | }, |
| 123 | .probe = autcpu12_nvram_probe, | 123 | .probe = autcpu12_nvram_probe, |
| 124 | .remove = __devexit_p(autcpu12_nvram_remove), | 124 | .remove = autcpu12_nvram_remove, |
| 125 | }; | 125 | }; |
| 126 | module_platform_driver(autcpu12_nvram_driver); | 126 | module_platform_driver(autcpu12_nvram_driver); |
| 127 | 127 | ||
diff --git a/drivers/mtd/maps/bfin-async-flash.c b/drivers/mtd/maps/bfin-async-flash.c index ef5cde84a8b3..f833edfaab79 100644 --- a/drivers/mtd/maps/bfin-async-flash.c +++ b/drivers/mtd/maps/bfin-async-flash.c | |||
| @@ -30,7 +30,8 @@ | |||
| 30 | #include <linux/io.h> | 30 | #include <linux/io.h> |
| 31 | #include <asm/unaligned.h> | 31 | #include <asm/unaligned.h> |
| 32 | 32 | ||
| 33 | #define pr_devinit(fmt, args...) ({ static const __devinitconst char __fmt[] = fmt; printk(__fmt, ## args); }) | 33 | #define pr_devinit(fmt, args...) \ |
| 34 | ({ static const char __fmt[] = fmt; printk(__fmt, ## args); }) | ||
| 34 | 35 | ||
| 35 | #define DRIVER_NAME "bfin-async-flash" | 36 | #define DRIVER_NAME "bfin-async-flash" |
| 36 | 37 | ||
| @@ -123,7 +124,7 @@ static void bfin_flash_copy_to(struct map_info *map, unsigned long to, const voi | |||
| 123 | 124 | ||
| 124 | static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; | 125 | static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; |
| 125 | 126 | ||
| 126 | static int __devinit bfin_flash_probe(struct platform_device *pdev) | 127 | static int bfin_flash_probe(struct platform_device *pdev) |
| 127 | { | 128 | { |
| 128 | int ret; | 129 | int ret; |
| 129 | struct physmap_flash_data *pdata = pdev->dev.platform_data; | 130 | struct physmap_flash_data *pdata = pdev->dev.platform_data; |
| @@ -172,7 +173,7 @@ static int __devinit bfin_flash_probe(struct platform_device *pdev) | |||
| 172 | return 0; | 173 | return 0; |
| 173 | } | 174 | } |
| 174 | 175 | ||
| 175 | static int __devexit bfin_flash_remove(struct platform_device *pdev) | 176 | static int bfin_flash_remove(struct platform_device *pdev) |
| 176 | { | 177 | { |
| 177 | struct async_state *state = platform_get_drvdata(pdev); | 178 | struct async_state *state = platform_get_drvdata(pdev); |
| 178 | gpio_free(state->enet_flash_pin); | 179 | gpio_free(state->enet_flash_pin); |
| @@ -184,7 +185,7 @@ static int __devexit bfin_flash_remove(struct platform_device *pdev) | |||
| 184 | 185 | ||
| 185 | static struct platform_driver bfin_flash_driver = { | 186 | static struct platform_driver bfin_flash_driver = { |
| 186 | .probe = bfin_flash_probe, | 187 | .probe = bfin_flash_probe, |
| 187 | .remove = __devexit_p(bfin_flash_remove), | 188 | .remove = bfin_flash_remove, |
| 188 | .driver = { | 189 | .driver = { |
| 189 | .name = DRIVER_NAME, | 190 | .name = DRIVER_NAME, |
| 190 | }, | 191 | }, |
diff --git a/drivers/mtd/maps/ck804xrom.c b/drivers/mtd/maps/ck804xrom.c index 3d0e762fa5f2..586a1c77e48a 100644 --- a/drivers/mtd/maps/ck804xrom.c +++ b/drivers/mtd/maps/ck804xrom.c | |||
| @@ -112,8 +112,8 @@ static void ck804xrom_cleanup(struct ck804xrom_window *window) | |||
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | 114 | ||
| 115 | static int __devinit ck804xrom_init_one (struct pci_dev *pdev, | 115 | static int ck804xrom_init_one(struct pci_dev *pdev, |
| 116 | const struct pci_device_id *ent) | 116 | const struct pci_device_id *ent) |
| 117 | { | 117 | { |
| 118 | static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; | 118 | static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; |
| 119 | u8 byte; | 119 | u8 byte; |
| @@ -320,7 +320,7 @@ static int __devinit ck804xrom_init_one (struct pci_dev *pdev, | |||
| 320 | } | 320 | } |
| 321 | 321 | ||
| 322 | 322 | ||
| 323 | static void __devexit ck804xrom_remove_one (struct pci_dev *pdev) | 323 | static void ck804xrom_remove_one(struct pci_dev *pdev) |
| 324 | { | 324 | { |
| 325 | struct ck804xrom_window *window = &ck804xrom_window; | 325 | struct ck804xrom_window *window = &ck804xrom_window; |
| 326 | 326 | ||
diff --git a/drivers/mtd/maps/esb2rom.c b/drivers/mtd/maps/esb2rom.c index 08322b1c3e81..ff8681a25831 100644 --- a/drivers/mtd/maps/esb2rom.c +++ b/drivers/mtd/maps/esb2rom.c | |||
| @@ -144,7 +144,7 @@ static void esb2rom_cleanup(struct esb2rom_window *window) | |||
| 144 | pci_dev_put(window->pdev); | 144 | pci_dev_put(window->pdev); |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | static int __devinit esb2rom_init_one(struct pci_dev *pdev, | 147 | static int esb2rom_init_one(struct pci_dev *pdev, |
| 148 | const struct pci_device_id *ent) | 148 | const struct pci_device_id *ent) |
| 149 | { | 149 | { |
| 150 | static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; | 150 | static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; |
| @@ -378,13 +378,13 @@ static int __devinit esb2rom_init_one(struct pci_dev *pdev, | |||
| 378 | return 0; | 378 | return 0; |
| 379 | } | 379 | } |
| 380 | 380 | ||
| 381 | static void __devexit esb2rom_remove_one (struct pci_dev *pdev) | 381 | static void esb2rom_remove_one(struct pci_dev *pdev) |
| 382 | { | 382 | { |
| 383 | struct esb2rom_window *window = &esb2rom_window; | 383 | struct esb2rom_window *window = &esb2rom_window; |
| 384 | esb2rom_cleanup(window); | 384 | esb2rom_cleanup(window); |
| 385 | } | 385 | } |
| 386 | 386 | ||
| 387 | static struct pci_device_id esb2rom_pci_tbl[] __devinitdata = { | 387 | static struct pci_device_id esb2rom_pci_tbl[] = { |
| 388 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, | 388 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, |
| 389 | PCI_ANY_ID, PCI_ANY_ID, }, | 389 | PCI_ANY_ID, PCI_ANY_ID, }, |
| 390 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, | 390 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, |
diff --git a/drivers/mtd/maps/fortunet.c b/drivers/mtd/maps/fortunet.c deleted file mode 100644 index 956e2e4f30ea..000000000000 --- a/drivers/mtd/maps/fortunet.c +++ /dev/null | |||
| @@ -1,277 +0,0 @@ | |||
| 1 | /* fortunet.c memory map | ||
| 2 | * | ||
| 3 | */ | ||
| 4 | |||
| 5 | #include <linux/module.h> | ||
| 6 | #include <linux/types.h> | ||
| 7 | #include <linux/kernel.h> | ||
| 8 | #include <linux/init.h> | ||
| 9 | #include <linux/string.h> | ||
| 10 | |||
| 11 | #include <linux/mtd/mtd.h> | ||
| 12 | #include <linux/mtd/map.h> | ||
| 13 | #include <linux/mtd/partitions.h> | ||
| 14 | |||
| 15 | #include <asm/io.h> | ||
| 16 | |||
| 17 | #define MAX_NUM_REGIONS 4 | ||
| 18 | #define MAX_NUM_PARTITIONS 8 | ||
| 19 | |||
| 20 | #define DEF_WINDOW_ADDR_PHY 0x00000000 | ||
| 21 | #define DEF_WINDOW_SIZE 0x00800000 // 8 Mega Bytes | ||
| 22 | |||
| 23 | #define MTD_FORTUNET_PK "MTD FortuNet: " | ||
| 24 | |||
| 25 | #define MAX_NAME_SIZE 128 | ||
| 26 | |||
| 27 | struct map_region | ||
| 28 | { | ||
| 29 | int window_addr_physical; | ||
| 30 | int altbankwidth; | ||
| 31 | struct map_info map_info; | ||
| 32 | struct mtd_info *mymtd; | ||
| 33 | struct mtd_partition parts[MAX_NUM_PARTITIONS]; | ||
| 34 | char map_name[MAX_NAME_SIZE]; | ||
| 35 | char parts_name[MAX_NUM_PARTITIONS][MAX_NAME_SIZE]; | ||
| 36 | }; | ||
| 37 | |||
| 38 | static struct map_region map_regions[MAX_NUM_REGIONS]; | ||
| 39 | static int map_regions_set[MAX_NUM_REGIONS] = {0,0,0,0}; | ||
| 40 | static int map_regions_parts[MAX_NUM_REGIONS] = {0,0,0,0}; | ||
| 41 | |||
| 42 | |||
| 43 | |||
| 44 | struct map_info default_map = { | ||
| 45 | .size = DEF_WINDOW_SIZE, | ||
| 46 | .bankwidth = 4, | ||
| 47 | }; | ||
| 48 | |||
| 49 | static char * __init get_string_option(char *dest,int dest_size,char *sor) | ||
| 50 | { | ||
| 51 | if(!dest_size) | ||
| 52 | return sor; | ||
| 53 | dest_size--; | ||
| 54 | while(*sor) | ||
| 55 | { | ||
| 56 | if(*sor==',') | ||
| 57 | { | ||
| 58 | sor++; | ||
| 59 | break; | ||
| 60 | } | ||
| 61 | else if(*sor=='\"') | ||
| 62 | { | ||
| 63 | sor++; | ||
| 64 | while(*sor) | ||
| 65 | { | ||
| 66 | if(*sor=='\"') | ||
| 67 | { | ||
| 68 | sor++; | ||
| 69 | break; | ||
| 70 | } | ||
| 71 | *dest = *sor; | ||
| 72 | dest++; | ||
| 73 | sor++; | ||
| 74 | dest_size--; | ||
| 75 | if(!dest_size) | ||
| 76 | { | ||
| 77 | *dest = 0; | ||
| 78 | return sor; | ||
| 79 | } | ||
| 80 | } | ||
| 81 | } | ||
| 82 | else | ||
| 83 | { | ||
| 84 | *dest = *sor; | ||
| 85 | dest++; | ||
| 86 | sor++; | ||
| 87 | dest_size--; | ||
| 88 | if(!dest_size) | ||
| 89 | { | ||
| 90 | *dest = 0; | ||
| 91 | return sor; | ||
| 92 | } | ||
| 93 | } | ||
| 94 | } | ||
| 95 | *dest = 0; | ||
| 96 | return sor; | ||
| 97 | } | ||
| 98 | |||
| 99 | static int __init MTD_New_Region(char *line) | ||
| 100 | { | ||
| 101 | char string[MAX_NAME_SIZE]; | ||
| 102 | int params[6]; | ||
| 103 | get_options (get_string_option(string,sizeof(string),line),6,params); | ||
| 104 | if(params[0]<1) | ||
| 105 | { | ||
| 106 | printk(MTD_FORTUNET_PK "Bad parameters for MTD Region " | ||
| 107 | " name,region-number[,base,size,bankwidth,altbankwidth]\n"); | ||
| 108 | return 1; | ||
| 109 | } | ||
| 110 | if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS)) | ||
| 111 | { | ||
| 112 | printk(MTD_FORTUNET_PK "Bad region index of %d only have 0..%u regions\n", | ||
| 113 | params[1],MAX_NUM_REGIONS-1); | ||
| 114 | return 1; | ||
| 115 | } | ||
| 116 | memset(&map_regions[params[1]],0,sizeof(map_regions[params[1]])); | ||
| 117 | memcpy(&map_regions[params[1]].map_info, | ||
| 118 | &default_map,sizeof(map_regions[params[1]].map_info)); | ||
| 119 | map_regions_set[params[1]] = 1; | ||
| 120 | map_regions[params[1]].window_addr_physical = DEF_WINDOW_ADDR_PHY; | ||
| 121 | map_regions[params[1]].altbankwidth = 2; | ||
| 122 | map_regions[params[1]].mymtd = NULL; | ||
| 123 | map_regions[params[1]].map_info.name = map_regions[params[1]].map_name; | ||
| 124 | strcpy(map_regions[params[1]].map_info.name,string); | ||
| 125 | if(params[0]>1) | ||
| 126 | { | ||
| 127 | map_regions[params[1]].window_addr_physical = params[2]; | ||
| 128 | } | ||
| 129 | if(params[0]>2) | ||
| 130 | { | ||
| 131 | map_regions[params[1]].map_info.size = params[3]; | ||
| 132 | } | ||
| 133 | if(params[0]>3) | ||
| 134 | { | ||
| 135 | map_regions[params[1]].map_info.bankwidth = params[4]; | ||
| 136 | } | ||
| 137 | if(params[0]>4) | ||
| 138 | { | ||
| 139 | map_regions[params[1]].altbankwidth = params[5]; | ||
| 140 | } | ||
| 141 | return 1; | ||
| 142 | } | ||
| 143 | |||
| 144 | static int __init MTD_New_Partition(char *line) | ||
| 145 | { | ||
| 146 | char string[MAX_NAME_SIZE]; | ||
| 147 | int params[4]; | ||
| 148 | get_options (get_string_option(string,sizeof(string),line),4,params); | ||
| 149 | if(params[0]<3) | ||
| 150 | { | ||
| 151 | printk(MTD_FORTUNET_PK "Bad parameters for MTD Partition " | ||
| 152 | " name,region-number,size,offset\n"); | ||
| 153 | return 1; | ||
| 154 | } | ||
| 155 | if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS)) | ||
| 156 | { | ||
| 157 | printk(MTD_FORTUNET_PK "Bad region index of %d only have 0..%u regions\n", | ||
| 158 | params[1],MAX_NUM_REGIONS-1); | ||
| 159 | return 1; | ||
| 160 | } | ||
| 161 | if(map_regions_parts[params[1]]>=MAX_NUM_PARTITIONS) | ||
| 162 | { | ||
| 163 | printk(MTD_FORTUNET_PK "Out of space for partition in this region\n"); | ||
| 164 | return 1; | ||
| 165 | } | ||
| 166 | map_regions[params[1]].parts[map_regions_parts[params[1]]].name = | ||
| 167 | map_regions[params[1]]. parts_name[map_regions_parts[params[1]]]; | ||
| 168 | strcpy(map_regions[params[1]].parts[map_regions_parts[params[1]]].name,string); | ||
| 169 | map_regions[params[1]].parts[map_regions_parts[params[1]]].size = | ||
| 170 | params[2]; | ||
| 171 | map_regions[params[1]].parts[map_regions_parts[params[1]]].offset = | ||
| 172 | params[3]; | ||
| 173 | map_regions[params[1]].parts[map_regions_parts[params[1]]].mask_flags = 0; | ||
| 174 | map_regions_parts[params[1]]++; | ||
| 175 | return 1; | ||
| 176 | } | ||
| 177 | |||
| 178 | __setup("MTD_Region=", MTD_New_Region); | ||
| 179 | __setup("MTD_Partition=", MTD_New_Partition); | ||
| 180 | |||
| 181 | /* Backwards-spelling-compatibility */ | ||
| 182 | __setup("MTD_Partion=", MTD_New_Partition); | ||
| 183 | |||
| 184 | static int __init init_fortunet(void) | ||
| 185 | { | ||
| 186 | int ix,iy; | ||
| 187 | for(iy=ix=0;ix<MAX_NUM_REGIONS;ix++) | ||
| 188 | { | ||
| 189 | if(map_regions_parts[ix]&&(!map_regions_set[ix])) | ||
| 190 | { | ||
| 191 | printk(MTD_FORTUNET_PK "Region %d is not setup (Setting to default)\n", | ||
| 192 | ix); | ||
| 193 | memset(&map_regions[ix],0,sizeof(map_regions[ix])); | ||
| 194 | memcpy(&map_regions[ix].map_info,&default_map, | ||
| 195 | sizeof(map_regions[ix].map_info)); | ||
| 196 | map_regions_set[ix] = 1; | ||
| 197 | map_regions[ix].window_addr_physical = DEF_WINDOW_ADDR_PHY; | ||
| 198 | map_regions[ix].altbankwidth = 2; | ||
| 199 | map_regions[ix].mymtd = NULL; | ||
| 200 | map_regions[ix].map_info.name = map_regions[ix].map_name; | ||
| 201 | strcpy(map_regions[ix].map_info.name,"FORTUNET"); | ||
| 202 | } | ||
| 203 | if(map_regions_set[ix]) | ||
| 204 | { | ||
| 205 | iy++; | ||
| 206 | printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash device at physically " | ||
| 207 | " address %x size %x\n", | ||
| 208 | map_regions[ix].map_info.name, | ||
| 209 | map_regions[ix].window_addr_physical, | ||
| 210 | map_regions[ix].map_info.size); | ||
| 211 | |||
| 212 | map_regions[ix].map_info.phys = map_regions[ix].window_addr_physical, | ||
| 213 | |||
| 214 | map_regions[ix].map_info.virt = | ||
| 215 | ioremap_nocache( | ||
| 216 | map_regions[ix].window_addr_physical, | ||
| 217 | map_regions[ix].map_info.size); | ||
| 218 | if(!map_regions[ix].map_info.virt) | ||
| 219 | { | ||
| 220 | int j = 0; | ||
| 221 | printk(MTD_FORTUNET_PK "%s flash failed to ioremap!\n", | ||
| 222 | map_regions[ix].map_info.name); | ||
| 223 | for (j = 0 ; j < ix; j++) | ||
| 224 | iounmap(map_regions[j].map_info.virt); | ||
| 225 | return -ENXIO; | ||
| 226 | } | ||
| 227 | simple_map_init(&map_regions[ix].map_info); | ||
| 228 | |||
| 229 | printk(KERN_NOTICE MTD_FORTUNET_PK "%s flash is virtually at: %x\n", | ||
| 230 | map_regions[ix].map_info.name, | ||
| 231 | map_regions[ix].map_info.virt); | ||
| 232 | map_regions[ix].mymtd = do_map_probe("cfi_probe", | ||
| 233 | &map_regions[ix].map_info); | ||
| 234 | if((!map_regions[ix].mymtd)&&( | ||
| 235 | map_regions[ix].altbankwidth!=map_regions[ix].map_info.bankwidth)) | ||
| 236 | { | ||
| 237 | printk(KERN_NOTICE MTD_FORTUNET_PK "Trying alternate bankwidth " | ||
| 238 | "for %s flash.\n", | ||
| 239 | map_regions[ix].map_info.name); | ||
| 240 | map_regions[ix].map_info.bankwidth = | ||
| 241 | map_regions[ix].altbankwidth; | ||
| 242 | map_regions[ix].mymtd = do_map_probe("cfi_probe", | ||
| 243 | &map_regions[ix].map_info); | ||
| 244 | } | ||
| 245 | map_regions[ix].mymtd->owner = THIS_MODULE; | ||
| 246 | mtd_device_register(map_regions[ix].mymtd, | ||
| 247 | map_regions[ix].parts, | ||
| 248 | map_regions_parts[ix]); | ||
| 249 | } | ||
| 250 | } | ||
| 251 | if(iy) | ||
| 252 | return 0; | ||
| 253 | return -ENXIO; | ||
| 254 | } | ||
| 255 | |||
| 256 | static void __exit cleanup_fortunet(void) | ||
| 257 | { | ||
| 258 | int ix; | ||
| 259 | for(ix=0;ix<MAX_NUM_REGIONS;ix++) | ||
| 260 | { | ||
| 261 | if(map_regions_set[ix]) | ||
| 262 | { | ||
| 263 | if( map_regions[ix].mymtd ) | ||
| 264 | { | ||
| 265 | mtd_device_unregister(map_regions[ix].mymtd); | ||
| 266 | map_destroy( map_regions[ix].mymtd ); | ||
| 267 | } | ||
| 268 | iounmap((void *)map_regions[ix].map_info.virt); | ||
| 269 | } | ||
| 270 | } | ||
| 271 | } | ||
| 272 | |||
| 273 | module_init(init_fortunet); | ||
| 274 | module_exit(cleanup_fortunet); | ||
| 275 | |||
| 276 | MODULE_AUTHOR("FortuNet, Inc."); | ||
| 277 | MODULE_DESCRIPTION("MTD map driver for FortuNet boards"); | ||
diff --git a/drivers/mtd/maps/gpio-addr-flash.c b/drivers/mtd/maps/gpio-addr-flash.c index e4de96ba52b3..7b643de2500b 100644 --- a/drivers/mtd/maps/gpio-addr-flash.c +++ b/drivers/mtd/maps/gpio-addr-flash.c | |||
| @@ -26,7 +26,8 @@ | |||
| 26 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
| 27 | #include <linux/types.h> | 27 | #include <linux/types.h> |
| 28 | 28 | ||
| 29 | #define pr_devinit(fmt, args...) ({ static const __devinitconst char __fmt[] = fmt; printk(__fmt, ## args); }) | 29 | #define pr_devinit(fmt, args...) \ |
| 30 | ({ static const char __fmt[] = fmt; printk(__fmt, ## args); }) | ||
| 30 | 31 | ||
| 31 | #define DRIVER_NAME "gpio-addr-flash" | 32 | #define DRIVER_NAME "gpio-addr-flash" |
| 32 | #define PFX DRIVER_NAME ": " | 33 | #define PFX DRIVER_NAME ": " |
| @@ -142,7 +143,8 @@ static void gf_write(struct map_info *map, map_word d1, unsigned long ofs) | |||
| 142 | * | 143 | * |
| 143 | * See gf_copy_from() caveat. | 144 | * See gf_copy_from() caveat. |
| 144 | */ | 145 | */ |
| 145 | static void gf_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) | 146 | static void gf_copy_to(struct map_info *map, unsigned long to, |
| 147 | const void *from, ssize_t len) | ||
| 146 | { | 148 | { |
| 147 | struct async_state *state = gf_map_info_to_state(map); | 149 | struct async_state *state = gf_map_info_to_state(map); |
| 148 | 150 | ||
| @@ -185,7 +187,7 @@ static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; | |||
| 185 | * ... | 187 | * ... |
| 186 | * }; | 188 | * }; |
| 187 | */ | 189 | */ |
| 188 | static int __devinit gpio_flash_probe(struct platform_device *pdev) | 190 | static int gpio_flash_probe(struct platform_device *pdev) |
| 189 | { | 191 | { |
| 190 | size_t i, arr_size; | 192 | size_t i, arr_size; |
| 191 | struct physmap_flash_data *pdata; | 193 | struct physmap_flash_data *pdata; |
| @@ -258,7 +260,7 @@ static int __devinit gpio_flash_probe(struct platform_device *pdev) | |||
| 258 | return 0; | 260 | return 0; |
| 259 | } | 261 | } |
| 260 | 262 | ||
| 261 | static int __devexit gpio_flash_remove(struct platform_device *pdev) | 263 | static int gpio_flash_remove(struct platform_device *pdev) |
| 262 | { | 264 | { |
| 263 | struct async_state *state = platform_get_drvdata(pdev); | 265 | struct async_state *state = platform_get_drvdata(pdev); |
| 264 | size_t i = 0; | 266 | size_t i = 0; |
| @@ -273,7 +275,7 @@ static int __devexit gpio_flash_remove(struct platform_device *pdev) | |||
| 273 | 275 | ||
| 274 | static struct platform_driver gpio_flash_driver = { | 276 | static struct platform_driver gpio_flash_driver = { |
| 275 | .probe = gpio_flash_probe, | 277 | .probe = gpio_flash_probe, |
| 276 | .remove = __devexit_p(gpio_flash_remove), | 278 | .remove = gpio_flash_remove, |
| 277 | .driver = { | 279 | .driver = { |
| 278 | .name = DRIVER_NAME, | 280 | .name = DRIVER_NAME, |
| 279 | }, | 281 | }, |
diff --git a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c index 6689dcb3124d..c7478e18f485 100644 --- a/drivers/mtd/maps/ichxrom.c +++ b/drivers/mtd/maps/ichxrom.c | |||
| @@ -84,8 +84,8 @@ static void ichxrom_cleanup(struct ichxrom_window *window) | |||
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | 86 | ||
| 87 | static int __devinit ichxrom_init_one (struct pci_dev *pdev, | 87 | static int ichxrom_init_one(struct pci_dev *pdev, |
| 88 | const struct pci_device_id *ent) | 88 | const struct pci_device_id *ent) |
| 89 | { | 89 | { |
| 90 | static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; | 90 | static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; |
| 91 | struct ichxrom_window *window = &ichxrom_window; | 91 | struct ichxrom_window *window = &ichxrom_window; |
| @@ -315,13 +315,13 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev, | |||
| 315 | } | 315 | } |
| 316 | 316 | ||
| 317 | 317 | ||
| 318 | static void __devexit ichxrom_remove_one (struct pci_dev *pdev) | 318 | static void ichxrom_remove_one(struct pci_dev *pdev) |
| 319 | { | 319 | { |
| 320 | struct ichxrom_window *window = &ichxrom_window; | 320 | struct ichxrom_window *window = &ichxrom_window; |
| 321 | ichxrom_cleanup(window); | 321 | ichxrom_cleanup(window); |
| 322 | } | 322 | } |
| 323 | 323 | ||
| 324 | static struct pci_device_id ichxrom_pci_tbl[] __devinitdata = { | 324 | static struct pci_device_id ichxrom_pci_tbl[] = { |
| 325 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, | 325 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, |
| 326 | PCI_ANY_ID, PCI_ANY_ID, }, | 326 | PCI_ANY_ID, PCI_ANY_ID, }, |
| 327 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, | 327 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, |
diff --git a/drivers/mtd/maps/intel_vr_nor.c b/drivers/mtd/maps/intel_vr_nor.c index 93f03175c82d..3ee2ad1dcbe7 100644 --- a/drivers/mtd/maps/intel_vr_nor.c +++ b/drivers/mtd/maps/intel_vr_nor.c | |||
| @@ -63,24 +63,24 @@ struct vr_nor_mtd { | |||
| 63 | #define TIMING_BYTE_EN (1 << 0) /* 8-bit vs 16-bit bus */ | 63 | #define TIMING_BYTE_EN (1 << 0) /* 8-bit vs 16-bit bus */ |
| 64 | #define TIMING_MASK 0x3FFF0000 | 64 | #define TIMING_MASK 0x3FFF0000 |
| 65 | 65 | ||
| 66 | static void __devexit vr_nor_destroy_partitions(struct vr_nor_mtd *p) | 66 | static void vr_nor_destroy_partitions(struct vr_nor_mtd *p) |
| 67 | { | 67 | { |
| 68 | mtd_device_unregister(p->info); | 68 | mtd_device_unregister(p->info); |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | static int __devinit vr_nor_init_partitions(struct vr_nor_mtd *p) | 71 | static int vr_nor_init_partitions(struct vr_nor_mtd *p) |
| 72 | { | 72 | { |
| 73 | /* register the flash bank */ | 73 | /* register the flash bank */ |
| 74 | /* partition the flash bank */ | 74 | /* partition the flash bank */ |
| 75 | return mtd_device_parse_register(p->info, NULL, NULL, NULL, 0); | 75 | return mtd_device_parse_register(p->info, NULL, NULL, NULL, 0); |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | static void __devexit vr_nor_destroy_mtd_setup(struct vr_nor_mtd *p) | 78 | static void vr_nor_destroy_mtd_setup(struct vr_nor_mtd *p) |
| 79 | { | 79 | { |
| 80 | map_destroy(p->info); | 80 | map_destroy(p->info); |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | static int __devinit vr_nor_mtd_setup(struct vr_nor_mtd *p) | 83 | static int vr_nor_mtd_setup(struct vr_nor_mtd *p) |
| 84 | { | 84 | { |
| 85 | static const char *probe_types[] = | 85 | static const char *probe_types[] = |
| 86 | { "cfi_probe", "jedec_probe", NULL }; | 86 | { "cfi_probe", "jedec_probe", NULL }; |
| @@ -96,7 +96,7 @@ static int __devinit vr_nor_mtd_setup(struct vr_nor_mtd *p) | |||
| 96 | return 0; | 96 | return 0; |
| 97 | } | 97 | } |
| 98 | 98 | ||
| 99 | static void __devexit vr_nor_destroy_maps(struct vr_nor_mtd *p) | 99 | static void vr_nor_destroy_maps(struct vr_nor_mtd *p) |
| 100 | { | 100 | { |
| 101 | unsigned int exp_timing_cs0; | 101 | unsigned int exp_timing_cs0; |
| 102 | 102 | ||
| @@ -116,7 +116,7 @@ static void __devexit vr_nor_destroy_maps(struct vr_nor_mtd *p) | |||
| 116 | * Initialize the map_info structure and map the flash. | 116 | * Initialize the map_info structure and map the flash. |
| 117 | * Returns 0 on success, nonzero otherwise. | 117 | * Returns 0 on success, nonzero otherwise. |
| 118 | */ | 118 | */ |
| 119 | static int __devinit vr_nor_init_maps(struct vr_nor_mtd *p) | 119 | static int vr_nor_init_maps(struct vr_nor_mtd *p) |
| 120 | { | 120 | { |
| 121 | unsigned long csr_phys, csr_len; | 121 | unsigned long csr_phys, csr_len; |
| 122 | unsigned long win_phys, win_len; | 122 | unsigned long win_phys, win_len; |
| @@ -176,7 +176,7 @@ static struct pci_device_id vr_nor_pci_ids[] = { | |||
| 176 | {0,} | 176 | {0,} |
| 177 | }; | 177 | }; |
| 178 | 178 | ||
| 179 | static void __devexit vr_nor_pci_remove(struct pci_dev *dev) | 179 | static void vr_nor_pci_remove(struct pci_dev *dev) |
| 180 | { | 180 | { |
| 181 | struct vr_nor_mtd *p = pci_get_drvdata(dev); | 181 | struct vr_nor_mtd *p = pci_get_drvdata(dev); |
| 182 | 182 | ||
| @@ -189,7 +189,7 @@ static void __devexit vr_nor_pci_remove(struct pci_dev *dev) | |||
| 189 | pci_disable_device(dev); | 189 | pci_disable_device(dev); |
| 190 | } | 190 | } |
| 191 | 191 | ||
| 192 | static int __devinit | 192 | static int |
| 193 | vr_nor_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | 193 | vr_nor_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) |
| 194 | { | 194 | { |
| 195 | struct vr_nor_mtd *p = NULL; | 195 | struct vr_nor_mtd *p = NULL; |
| @@ -256,7 +256,7 @@ vr_nor_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
| 256 | static struct pci_driver vr_nor_pci_driver = { | 256 | static struct pci_driver vr_nor_pci_driver = { |
| 257 | .name = DRV_NAME, | 257 | .name = DRV_NAME, |
| 258 | .probe = vr_nor_pci_probe, | 258 | .probe = vr_nor_pci_probe, |
| 259 | .remove = __devexit_p(vr_nor_pci_remove), | 259 | .remove = vr_nor_pci_remove, |
| 260 | .id_table = vr_nor_pci_ids, | 260 | .id_table = vr_nor_pci_ids, |
| 261 | }; | 261 | }; |
| 262 | 262 | ||
diff --git a/drivers/mtd/maps/lantiq-flash.c b/drivers/mtd/maps/lantiq-flash.c index c03456f17004..3c3c791eb96a 100644 --- a/drivers/mtd/maps/lantiq-flash.c +++ b/drivers/mtd/maps/lantiq-flash.c | |||
| @@ -45,7 +45,7 @@ struct ltq_mtd { | |||
| 45 | }; | 45 | }; |
| 46 | 46 | ||
| 47 | static const char ltq_map_name[] = "ltq_nor"; | 47 | static const char ltq_map_name[] = "ltq_nor"; |
| 48 | static const char *ltq_probe_types[] __devinitconst = { | 48 | static const char *ltq_probe_types[] = { |
| 49 | "cmdlinepart", "ofpart", NULL }; | 49 | "cmdlinepart", "ofpart", NULL }; |
| 50 | 50 | ||
| 51 | static map_word | 51 | static map_word |
| @@ -109,7 +109,7 @@ ltq_copy_to(struct map_info *map, unsigned long to, | |||
| 109 | spin_unlock_irqrestore(&ebu_lock, flags); | 109 | spin_unlock_irqrestore(&ebu_lock, flags); |
| 110 | } | 110 | } |
| 111 | 111 | ||
| 112 | static int __devinit | 112 | static int |
| 113 | ltq_mtd_probe(struct platform_device *pdev) | 113 | ltq_mtd_probe(struct platform_device *pdev) |
| 114 | { | 114 | { |
| 115 | struct mtd_part_parser_data ppdata; | 115 | struct mtd_part_parser_data ppdata; |
| @@ -185,7 +185,7 @@ err_out: | |||
| 185 | return err; | 185 | return err; |
| 186 | } | 186 | } |
| 187 | 187 | ||
| 188 | static int __devexit | 188 | static int |
| 189 | ltq_mtd_remove(struct platform_device *pdev) | 189 | ltq_mtd_remove(struct platform_device *pdev) |
| 190 | { | 190 | { |
| 191 | struct ltq_mtd *ltq_mtd = platform_get_drvdata(pdev); | 191 | struct ltq_mtd *ltq_mtd = platform_get_drvdata(pdev); |
| @@ -209,7 +209,7 @@ MODULE_DEVICE_TABLE(of, ltq_mtd_match); | |||
| 209 | 209 | ||
| 210 | static struct platform_driver ltq_mtd_driver = { | 210 | static struct platform_driver ltq_mtd_driver = { |
| 211 | .probe = ltq_mtd_probe, | 211 | .probe = ltq_mtd_probe, |
| 212 | .remove = __devexit_p(ltq_mtd_remove), | 212 | .remove = ltq_mtd_remove, |
| 213 | .driver = { | 213 | .driver = { |
| 214 | .name = "ltq-nor", | 214 | .name = "ltq-nor", |
| 215 | .owner = THIS_MODULE, | 215 | .owner = THIS_MODULE, |
diff --git a/drivers/mtd/maps/latch-addr-flash.c b/drivers/mtd/maps/latch-addr-flash.c index 3c7ad17fca78..ab0fead56b83 100644 --- a/drivers/mtd/maps/latch-addr-flash.c +++ b/drivers/mtd/maps/latch-addr-flash.c | |||
| @@ -125,7 +125,7 @@ static int latch_addr_flash_remove(struct platform_device *dev) | |||
| 125 | return 0; | 125 | return 0; |
| 126 | } | 126 | } |
| 127 | 127 | ||
| 128 | static int __devinit latch_addr_flash_probe(struct platform_device *dev) | 128 | static int latch_addr_flash_probe(struct platform_device *dev) |
| 129 | { | 129 | { |
| 130 | struct latch_addr_flash_data *latch_addr_data; | 130 | struct latch_addr_flash_data *latch_addr_data; |
| 131 | struct latch_addr_flash_info *info; | 131 | struct latch_addr_flash_info *info; |
| @@ -218,7 +218,7 @@ done: | |||
| 218 | 218 | ||
| 219 | static struct platform_driver latch_addr_flash_driver = { | 219 | static struct platform_driver latch_addr_flash_driver = { |
| 220 | .probe = latch_addr_flash_probe, | 220 | .probe = latch_addr_flash_probe, |
| 221 | .remove = __devexit_p(latch_addr_flash_remove), | 221 | .remove = latch_addr_flash_remove, |
| 222 | .driver = { | 222 | .driver = { |
| 223 | .name = DRIVER_NAME, | 223 | .name = DRIVER_NAME, |
| 224 | }, | 224 | }, |
diff --git a/drivers/mtd/maps/pci.c b/drivers/mtd/maps/pci.c index 1c30c1a307f4..ed82914966f5 100644 --- a/drivers/mtd/maps/pci.c +++ b/drivers/mtd/maps/pci.c | |||
| @@ -253,7 +253,7 @@ static struct pci_device_id mtd_pci_ids[] = { | |||
| 253 | * Generic code follows. | 253 | * Generic code follows. |
| 254 | */ | 254 | */ |
| 255 | 255 | ||
| 256 | static int __devinit | 256 | static int |
| 257 | mtd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | 257 | mtd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) |
| 258 | { | 258 | { |
| 259 | struct mtd_pci_info *info = (struct mtd_pci_info *)id->driver_data; | 259 | struct mtd_pci_info *info = (struct mtd_pci_info *)id->driver_data; |
| @@ -308,7 +308,7 @@ out: | |||
| 308 | return err; | 308 | return err; |
| 309 | } | 309 | } |
| 310 | 310 | ||
| 311 | static void __devexit | 311 | static void |
| 312 | mtd_pci_remove(struct pci_dev *dev) | 312 | mtd_pci_remove(struct pci_dev *dev) |
| 313 | { | 313 | { |
| 314 | struct mtd_info *mtd = pci_get_drvdata(dev); | 314 | struct mtd_info *mtd = pci_get_drvdata(dev); |
| @@ -326,7 +326,7 @@ mtd_pci_remove(struct pci_dev *dev) | |||
| 326 | static struct pci_driver mtd_pci_driver = { | 326 | static struct pci_driver mtd_pci_driver = { |
| 327 | .name = "MTD PCI", | 327 | .name = "MTD PCI", |
| 328 | .probe = mtd_pci_probe, | 328 | .probe = mtd_pci_probe, |
| 329 | .remove = __devexit_p(mtd_pci_remove), | 329 | .remove = mtd_pci_remove, |
| 330 | .id_table = mtd_pci_ids, | 330 | .id_table = mtd_pci_ids, |
| 331 | }; | 331 | }; |
| 332 | 332 | ||
diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index 6f19acadb06c..37cdc201652f 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c | |||
| @@ -77,7 +77,7 @@ static int of_flash_remove(struct platform_device *dev) | |||
| 77 | /* Helper function to handle probing of the obsolete "direct-mapped" | 77 | /* Helper function to handle probing of the obsolete "direct-mapped" |
| 78 | * compatible binding, which has an extra "probe-type" property | 78 | * compatible binding, which has an extra "probe-type" property |
| 79 | * describing the type of flash probe necessary. */ | 79 | * describing the type of flash probe necessary. */ |
| 80 | static struct mtd_info * __devinit obsolete_probe(struct platform_device *dev, | 80 | static struct mtd_info *obsolete_probe(struct platform_device *dev, |
| 81 | struct map_info *map) | 81 | struct map_info *map) |
| 82 | { | 82 | { |
| 83 | struct device_node *dp = dev->dev.of_node; | 83 | struct device_node *dp = dev->dev.of_node; |
| @@ -116,7 +116,7 @@ static struct mtd_info * __devinit obsolete_probe(struct platform_device *dev, | |||
| 116 | information. */ | 116 | information. */ |
| 117 | static const char *part_probe_types_def[] = { "cmdlinepart", "RedBoot", | 117 | static const char *part_probe_types_def[] = { "cmdlinepart", "RedBoot", |
| 118 | "ofpart", "ofoldpart", NULL }; | 118 | "ofpart", "ofoldpart", NULL }; |
| 119 | static const char ** __devinit of_get_probes(struct device_node *dp) | 119 | static const char **of_get_probes(struct device_node *dp) |
| 120 | { | 120 | { |
| 121 | const char *cp; | 121 | const char *cp; |
| 122 | int cplen; | 122 | int cplen; |
| @@ -145,14 +145,14 @@ static const char ** __devinit of_get_probes(struct device_node *dp) | |||
| 145 | return res; | 145 | return res; |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | static void __devinit of_free_probes(const char **probes) | 148 | static void of_free_probes(const char **probes) |
| 149 | { | 149 | { |
| 150 | if (probes != part_probe_types_def) | 150 | if (probes != part_probe_types_def) |
| 151 | kfree(probes); | 151 | kfree(probes); |
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | static struct of_device_id of_flash_match[]; | 154 | static struct of_device_id of_flash_match[]; |
| 155 | static int __devinit of_flash_probe(struct platform_device *dev) | 155 | static int of_flash_probe(struct platform_device *dev) |
| 156 | { | 156 | { |
| 157 | const char **part_probe_types; | 157 | const char **part_probe_types; |
| 158 | const struct of_device_id *match; | 158 | const struct of_device_id *match; |
| @@ -170,6 +170,7 @@ static int __devinit of_flash_probe(struct platform_device *dev) | |||
| 170 | resource_size_t res_size; | 170 | resource_size_t res_size; |
| 171 | struct mtd_part_parser_data ppdata; | 171 | struct mtd_part_parser_data ppdata; |
| 172 | bool map_indirect; | 172 | bool map_indirect; |
| 173 | const char *mtd_name; | ||
| 173 | 174 | ||
| 174 | match = of_match_device(of_flash_match, &dev->dev); | 175 | match = of_match_device(of_flash_match, &dev->dev); |
| 175 | if (!match) | 176 | if (!match) |
| @@ -178,6 +179,8 @@ static int __devinit of_flash_probe(struct platform_device *dev) | |||
| 178 | 179 | ||
| 179 | reg_tuple_size = (of_n_addr_cells(dp) + of_n_size_cells(dp)) * sizeof(u32); | 180 | reg_tuple_size = (of_n_addr_cells(dp) + of_n_size_cells(dp)) * sizeof(u32); |
| 180 | 181 | ||
| 182 | of_property_read_string(dp, "linux,mtd-name", &mtd_name); | ||
| 183 | |||
| 181 | /* | 184 | /* |
| 182 | * Get number of "reg" tuples. Scan for MTD devices on area's | 185 | * Get number of "reg" tuples. Scan for MTD devices on area's |
| 183 | * described by each "reg" region. This makes it possible (including | 186 | * described by each "reg" region. This makes it possible (including |
| @@ -234,7 +237,7 @@ static int __devinit of_flash_probe(struct platform_device *dev) | |||
| 234 | goto err_out; | 237 | goto err_out; |
| 235 | } | 238 | } |
| 236 | 239 | ||
| 237 | info->list[i].map.name = dev_name(&dev->dev); | 240 | info->list[i].map.name = mtd_name ?: dev_name(&dev->dev); |
| 238 | info->list[i].map.phys = res.start; | 241 | info->list[i].map.phys = res.start; |
| 239 | info->list[i].map.size = res_size; | 242 | info->list[i].map.size = res_size; |
| 240 | info->list[i].map.bankwidth = be32_to_cpup(width); | 243 | info->list[i].map.bankwidth = be32_to_cpup(width); |
| @@ -282,6 +285,7 @@ static int __devinit of_flash_probe(struct platform_device *dev) | |||
| 282 | } | 285 | } |
| 283 | 286 | ||
| 284 | err = 0; | 287 | err = 0; |
| 288 | info->cmtd = NULL; | ||
| 285 | if (info->list_size == 1) { | 289 | if (info->list_size == 1) { |
| 286 | info->cmtd = info->list[0].mtd; | 290 | info->cmtd = info->list[0].mtd; |
| 287 | } else if (info->list_size > 1) { | 291 | } else if (info->list_size > 1) { |
| @@ -290,9 +294,10 @@ static int __devinit of_flash_probe(struct platform_device *dev) | |||
| 290 | */ | 294 | */ |
| 291 | info->cmtd = mtd_concat_create(mtd_list, info->list_size, | 295 | info->cmtd = mtd_concat_create(mtd_list, info->list_size, |
| 292 | dev_name(&dev->dev)); | 296 | dev_name(&dev->dev)); |
| 293 | if (info->cmtd == NULL) | ||
| 294 | err = -ENXIO; | ||
| 295 | } | 297 | } |
| 298 | if (info->cmtd == NULL) | ||
| 299 | err = -ENXIO; | ||
| 300 | |||
| 296 | if (err) | 301 | if (err) |
| 297 | goto err_out; | 302 | goto err_out; |
| 298 | 303 | ||
diff --git a/drivers/mtd/maps/pismo.c b/drivers/mtd/maps/pismo.c index 65bd1cd4d627..afea93b515d5 100644 --- a/drivers/mtd/maps/pismo.c +++ b/drivers/mtd/maps/pismo.c | |||
| @@ -58,7 +58,7 @@ static void pismo_set_vpp(struct platform_device *pdev, int on) | |||
| 58 | pismo->vpp(pismo->vpp_data, on); | 58 | pismo->vpp(pismo->vpp_data, on); |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | static unsigned int __devinit pismo_width_to_bytes(unsigned int width) | 61 | static unsigned int pismo_width_to_bytes(unsigned int width) |
| 62 | { | 62 | { |
| 63 | width &= 15; | 63 | width &= 15; |
| 64 | if (width > 2) | 64 | if (width > 2) |
| @@ -66,7 +66,7 @@ static unsigned int __devinit pismo_width_to_bytes(unsigned int width) | |||
| 66 | return 1 << width; | 66 | return 1 << width; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | static int __devinit pismo_eeprom_read(struct i2c_client *client, void *buf, | 69 | static int pismo_eeprom_read(struct i2c_client *client, void *buf, |
| 70 | u8 addr, size_t size) | 70 | u8 addr, size_t size) |
| 71 | { | 71 | { |
| 72 | int ret; | 72 | int ret; |
| @@ -88,7 +88,7 @@ static int __devinit pismo_eeprom_read(struct i2c_client *client, void *buf, | |||
| 88 | return ret == ARRAY_SIZE(msg) ? size : -EIO; | 88 | return ret == ARRAY_SIZE(msg) ? size : -EIO; |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | static int __devinit pismo_add_device(struct pismo_data *pismo, int i, | 91 | static int pismo_add_device(struct pismo_data *pismo, int i, |
| 92 | struct pismo_mem *region, const char *name, void *pdata, size_t psize) | 92 | struct pismo_mem *region, const char *name, void *pdata, size_t psize) |
| 93 | { | 93 | { |
| 94 | struct platform_device *dev; | 94 | struct platform_device *dev; |
| @@ -129,7 +129,7 @@ static int __devinit pismo_add_device(struct pismo_data *pismo, int i, | |||
| 129 | return ret; | 129 | return ret; |
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | static int __devinit pismo_add_nor(struct pismo_data *pismo, int i, | 132 | static int pismo_add_nor(struct pismo_data *pismo, int i, |
| 133 | struct pismo_mem *region) | 133 | struct pismo_mem *region) |
| 134 | { | 134 | { |
| 135 | struct physmap_flash_data data = { | 135 | struct physmap_flash_data data = { |
| @@ -143,7 +143,7 @@ static int __devinit pismo_add_nor(struct pismo_data *pismo, int i, | |||
| 143 | &data, sizeof(data)); | 143 | &data, sizeof(data)); |
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | static int __devinit pismo_add_sram(struct pismo_data *pismo, int i, | 146 | static int pismo_add_sram(struct pismo_data *pismo, int i, |
| 147 | struct pismo_mem *region) | 147 | struct pismo_mem *region) |
| 148 | { | 148 | { |
| 149 | struct platdata_mtd_ram data = { | 149 | struct platdata_mtd_ram data = { |
| @@ -154,7 +154,7 @@ static int __devinit pismo_add_sram(struct pismo_data *pismo, int i, | |||
| 154 | &data, sizeof(data)); | 154 | &data, sizeof(data)); |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | static void __devinit pismo_add_one(struct pismo_data *pismo, int i, | 157 | static void pismo_add_one(struct pismo_data *pismo, int i, |
| 158 | const struct pismo_cs_block *cs, phys_addr_t base) | 158 | const struct pismo_cs_block *cs, phys_addr_t base) |
| 159 | { | 159 | { |
| 160 | struct device *dev = &pismo->client->dev; | 160 | struct device *dev = &pismo->client->dev; |
| @@ -197,7 +197,7 @@ static void __devinit pismo_add_one(struct pismo_data *pismo, int i, | |||
| 197 | } | 197 | } |
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | static int __devexit pismo_remove(struct i2c_client *client) | 200 | static int pismo_remove(struct i2c_client *client) |
| 201 | { | 201 | { |
| 202 | struct pismo_data *pismo = i2c_get_clientdata(client); | 202 | struct pismo_data *pismo = i2c_get_clientdata(client); |
| 203 | int i; | 203 | int i; |
| @@ -210,7 +210,7 @@ static int __devexit pismo_remove(struct i2c_client *client) | |||
| 210 | return 0; | 210 | return 0; |
| 211 | } | 211 | } |
| 212 | 212 | ||
| 213 | static int __devinit pismo_probe(struct i2c_client *client, | 213 | static int pismo_probe(struct i2c_client *client, |
| 214 | const struct i2c_device_id *id) | 214 | const struct i2c_device_id *id) |
| 215 | { | 215 | { |
| 216 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); | 216 | struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); |
| @@ -267,7 +267,7 @@ static struct i2c_driver pismo_driver = { | |||
| 267 | .owner = THIS_MODULE, | 267 | .owner = THIS_MODULE, |
| 268 | }, | 268 | }, |
| 269 | .probe = pismo_probe, | 269 | .probe = pismo_probe, |
| 270 | .remove = __devexit_p(pismo_remove), | 270 | .remove = pismo_remove, |
| 271 | .id_table = pismo_id, | 271 | .id_table = pismo_id, |
| 272 | }; | 272 | }; |
| 273 | 273 | ||
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c index 81884c277405..43e3dbb976d9 100644 --- a/drivers/mtd/maps/pxa2xx-flash.c +++ b/drivers/mtd/maps/pxa2xx-flash.c | |||
| @@ -49,7 +49,7 @@ struct pxa2xx_flash_info { | |||
| 49 | static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; | 49 | static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; |
| 50 | 50 | ||
| 51 | 51 | ||
| 52 | static int __devinit pxa2xx_flash_probe(struct platform_device *pdev) | 52 | static int pxa2xx_flash_probe(struct platform_device *pdev) |
| 53 | { | 53 | { |
| 54 | struct flash_platform_data *flash = pdev->dev.platform_data; | 54 | struct flash_platform_data *flash = pdev->dev.platform_data; |
| 55 | struct pxa2xx_flash_info *info; | 55 | struct pxa2xx_flash_info *info; |
| @@ -105,7 +105,7 @@ static int __devinit pxa2xx_flash_probe(struct platform_device *pdev) | |||
| 105 | return 0; | 105 | return 0; |
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | static int __devexit pxa2xx_flash_remove(struct platform_device *dev) | 108 | static int pxa2xx_flash_remove(struct platform_device *dev) |
| 109 | { | 109 | { |
| 110 | struct pxa2xx_flash_info *info = platform_get_drvdata(dev); | 110 | struct pxa2xx_flash_info *info = platform_get_drvdata(dev); |
| 111 | 111 | ||
| @@ -139,7 +139,7 @@ static struct platform_driver pxa2xx_flash_driver = { | |||
| 139 | .owner = THIS_MODULE, | 139 | .owner = THIS_MODULE, |
| 140 | }, | 140 | }, |
| 141 | .probe = pxa2xx_flash_probe, | 141 | .probe = pxa2xx_flash_probe, |
| 142 | .remove = __devexit_p(pxa2xx_flash_remove), | 142 | .remove = pxa2xx_flash_remove, |
| 143 | .shutdown = pxa2xx_flash_shutdown, | 143 | .shutdown = pxa2xx_flash_shutdown, |
| 144 | }; | 144 | }; |
| 145 | 145 | ||
diff --git a/drivers/mtd/maps/sa1100-flash.c b/drivers/mtd/maps/sa1100-flash.c index a675bdbcb0fe..f694417cf7e6 100644 --- a/drivers/mtd/maps/sa1100-flash.c +++ b/drivers/mtd/maps/sa1100-flash.c | |||
| @@ -149,8 +149,8 @@ static void sa1100_destroy(struct sa_info *info, struct flash_platform_data *pla | |||
| 149 | plat->exit(); | 149 | plat->exit(); |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | static struct sa_info *__devinit | 152 | static struct sa_info *sa1100_setup_mtd(struct platform_device *pdev, |
| 153 | sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat) | 153 | struct flash_platform_data *plat) |
| 154 | { | 154 | { |
| 155 | struct sa_info *info; | 155 | struct sa_info *info; |
| 156 | int nr, size, i, ret = 0; | 156 | int nr, size, i, ret = 0; |
| @@ -246,7 +246,7 @@ sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat) | |||
| 246 | 246 | ||
| 247 | static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; | 247 | static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; |
| 248 | 248 | ||
| 249 | static int __devinit sa1100_mtd_probe(struct platform_device *pdev) | 249 | static int sa1100_mtd_probe(struct platform_device *pdev) |
| 250 | { | 250 | { |
| 251 | struct flash_platform_data *plat = pdev->dev.platform_data; | 251 | struct flash_platform_data *plat = pdev->dev.platform_data; |
| 252 | struct sa_info *info; | 252 | struct sa_info *info; |
diff --git a/drivers/mtd/maps/scb2_flash.c b/drivers/mtd/maps/scb2_flash.c index 9dcbc684abdb..71796137e97b 100644 --- a/drivers/mtd/maps/scb2_flash.c +++ b/drivers/mtd/maps/scb2_flash.c | |||
| @@ -69,7 +69,7 @@ static struct map_info scb2_map = { | |||
| 69 | }; | 69 | }; |
| 70 | static int region_fail; | 70 | static int region_fail; |
| 71 | 71 | ||
| 72 | static int __devinit | 72 | static int |
| 73 | scb2_fixup_mtd(struct mtd_info *mtd) | 73 | scb2_fixup_mtd(struct mtd_info *mtd) |
| 74 | { | 74 | { |
| 75 | int i; | 75 | int i; |
| @@ -133,7 +133,7 @@ scb2_fixup_mtd(struct mtd_info *mtd) | |||
| 133 | /* CSB5's 'Function Control Register' has bits for decoding @ >= 0xffc00000 */ | 133 | /* CSB5's 'Function Control Register' has bits for decoding @ >= 0xffc00000 */ |
| 134 | #define CSB5_FCR 0x41 | 134 | #define CSB5_FCR 0x41 |
| 135 | #define CSB5_FCR_DECODE_ALL 0x0e | 135 | #define CSB5_FCR_DECODE_ALL 0x0e |
| 136 | static int __devinit | 136 | static int |
| 137 | scb2_flash_probe(struct pci_dev *dev, const struct pci_device_id *ent) | 137 | scb2_flash_probe(struct pci_dev *dev, const struct pci_device_id *ent) |
| 138 | { | 138 | { |
| 139 | u8 reg; | 139 | u8 reg; |
| @@ -197,7 +197,7 @@ scb2_flash_probe(struct pci_dev *dev, const struct pci_device_id *ent) | |||
| 197 | return 0; | 197 | return 0; |
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | static void __devexit | 200 | static void |
| 201 | scb2_flash_remove(struct pci_dev *dev) | 201 | scb2_flash_remove(struct pci_dev *dev) |
| 202 | { | 202 | { |
| 203 | if (!scb2_mtd) | 203 | if (!scb2_mtd) |
| @@ -231,7 +231,7 @@ static struct pci_driver scb2_flash_driver = { | |||
| 231 | .name = "Intel SCB2 BIOS Flash", | 231 | .name = "Intel SCB2 BIOS Flash", |
| 232 | .id_table = scb2_flash_pci_ids, | 232 | .id_table = scb2_flash_pci_ids, |
| 233 | .probe = scb2_flash_probe, | 233 | .probe = scb2_flash_probe, |
| 234 | .remove = __devexit_p(scb2_flash_remove), | 234 | .remove = scb2_flash_remove, |
| 235 | }; | 235 | }; |
| 236 | 236 | ||
| 237 | module_pci_driver(scb2_flash_driver); | 237 | module_pci_driver(scb2_flash_driver); |
diff --git a/drivers/mtd/maps/sun_uflash.c b/drivers/mtd/maps/sun_uflash.c index 175e537b444f..d467f3b11c96 100644 --- a/drivers/mtd/maps/sun_uflash.c +++ b/drivers/mtd/maps/sun_uflash.c | |||
| @@ -108,7 +108,7 @@ int uflash_devinit(struct platform_device *op, struct device_node *dp) | |||
| 108 | return 0; | 108 | return 0; |
| 109 | } | 109 | } |
| 110 | 110 | ||
| 111 | static int __devinit uflash_probe(struct platform_device *op) | 111 | static int uflash_probe(struct platform_device *op) |
| 112 | { | 112 | { |
| 113 | struct device_node *dp = op->dev.of_node; | 113 | struct device_node *dp = op->dev.of_node; |
| 114 | 114 | ||
| @@ -121,7 +121,7 @@ static int __devinit uflash_probe(struct platform_device *op) | |||
| 121 | return uflash_devinit(op, dp); | 121 | return uflash_devinit(op, dp); |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | static int __devexit uflash_remove(struct platform_device *op) | 124 | static int uflash_remove(struct platform_device *op) |
| 125 | { | 125 | { |
| 126 | struct uflash_dev *up = dev_get_drvdata(&op->dev); | 126 | struct uflash_dev *up = dev_get_drvdata(&op->dev); |
| 127 | 127 | ||
| @@ -155,7 +155,7 @@ static struct platform_driver uflash_driver = { | |||
| 155 | .of_match_table = uflash_match, | 155 | .of_match_table = uflash_match, |
| 156 | }, | 156 | }, |
| 157 | .probe = uflash_probe, | 157 | .probe = uflash_probe, |
| 158 | .remove = __devexit_p(uflash_remove), | 158 | .remove = uflash_remove, |
| 159 | }; | 159 | }; |
| 160 | 160 | ||
| 161 | module_platform_driver(uflash_driver); | 161 | module_platform_driver(uflash_driver); |
diff --git a/drivers/mtd/maps/vmu-flash.c b/drivers/mtd/maps/vmu-flash.c index 2e2b0945edc7..6b223cfe92b7 100644 --- a/drivers/mtd/maps/vmu-flash.c +++ b/drivers/mtd/maps/vmu-flash.c | |||
| @@ -596,7 +596,7 @@ fail_name: | |||
| 596 | } | 596 | } |
| 597 | 597 | ||
| 598 | /* Handles very basic info about the flash, queries for details */ | 598 | /* Handles very basic info about the flash, queries for details */ |
| 599 | static int __devinit vmu_connect(struct maple_device *mdev) | 599 | static int vmu_connect(struct maple_device *mdev) |
| 600 | { | 600 | { |
| 601 | unsigned long test_flash_data, basic_flash_data; | 601 | unsigned long test_flash_data, basic_flash_data; |
| 602 | int c, error; | 602 | int c, error; |
| @@ -690,7 +690,7 @@ fail_nomem: | |||
| 690 | return error; | 690 | return error; |
| 691 | } | 691 | } |
| 692 | 692 | ||
| 693 | static void __devexit vmu_disconnect(struct maple_device *mdev) | 693 | static void vmu_disconnect(struct maple_device *mdev) |
| 694 | { | 694 | { |
| 695 | struct memcard *card; | 695 | struct memcard *card; |
| 696 | struct mdev_part *mpart; | 696 | struct mdev_part *mpart; |
| @@ -772,7 +772,7 @@ static void vmu_file_error(struct maple_device *mdev, void *recvbuf) | |||
| 772 | } | 772 | } |
| 773 | 773 | ||
| 774 | 774 | ||
| 775 | static int __devinit probe_maple_vmu(struct device *dev) | 775 | static int probe_maple_vmu(struct device *dev) |
| 776 | { | 776 | { |
| 777 | int error; | 777 | int error; |
| 778 | struct maple_device *mdev = to_maple_dev(dev); | 778 | struct maple_device *mdev = to_maple_dev(dev); |
| @@ -789,7 +789,7 @@ static int __devinit probe_maple_vmu(struct device *dev) | |||
| 789 | return 0; | 789 | return 0; |
| 790 | } | 790 | } |
| 791 | 791 | ||
| 792 | static int __devexit remove_maple_vmu(struct device *dev) | 792 | static int remove_maple_vmu(struct device *dev) |
| 793 | { | 793 | { |
| 794 | struct maple_device *mdev = to_maple_dev(dev); | 794 | struct maple_device *mdev = to_maple_dev(dev); |
| 795 | 795 | ||
| @@ -802,7 +802,7 @@ static struct maple_driver vmu_flash_driver = { | |||
| 802 | .drv = { | 802 | .drv = { |
| 803 | .name = "Dreamcast_visual_memory", | 803 | .name = "Dreamcast_visual_memory", |
| 804 | .probe = probe_maple_vmu, | 804 | .probe = probe_maple_vmu, |
| 805 | .remove = __devexit_p(remove_maple_vmu), | 805 | .remove = remove_maple_vmu, |
| 806 | }, | 806 | }, |
| 807 | }; | 807 | }; |
| 808 | 808 | ||
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c index f1f06715d4e0..5ad39bb5ab4c 100644 --- a/drivers/mtd/mtd_blkdevs.c +++ b/drivers/mtd/mtd_blkdevs.c | |||
| @@ -32,7 +32,6 @@ | |||
| 32 | #include <linux/hdreg.h> | 32 | #include <linux/hdreg.h> |
| 33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
| 34 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
| 35 | #include <linux/kthread.h> | ||
| 36 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
| 37 | 36 | ||
| 38 | #include "mtdcore.h" | 37 | #include "mtdcore.h" |
| @@ -121,16 +120,14 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr, | |||
| 121 | 120 | ||
| 122 | int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev) | 121 | int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev) |
| 123 | { | 122 | { |
| 124 | if (kthread_should_stop()) | ||
| 125 | return 1; | ||
| 126 | |||
| 127 | return dev->bg_stop; | 123 | return dev->bg_stop; |
| 128 | } | 124 | } |
| 129 | EXPORT_SYMBOL_GPL(mtd_blktrans_cease_background); | 125 | EXPORT_SYMBOL_GPL(mtd_blktrans_cease_background); |
| 130 | 126 | ||
| 131 | static int mtd_blktrans_thread(void *arg) | 127 | static void mtd_blktrans_work(struct work_struct *work) |
| 132 | { | 128 | { |
| 133 | struct mtd_blktrans_dev *dev = arg; | 129 | struct mtd_blktrans_dev *dev = |
| 130 | container_of(work, struct mtd_blktrans_dev, work); | ||
| 134 | struct mtd_blktrans_ops *tr = dev->tr; | 131 | struct mtd_blktrans_ops *tr = dev->tr; |
| 135 | struct request_queue *rq = dev->rq; | 132 | struct request_queue *rq = dev->rq; |
| 136 | struct request *req = NULL; | 133 | struct request *req = NULL; |
| @@ -138,7 +135,7 @@ static int mtd_blktrans_thread(void *arg) | |||
| 138 | 135 | ||
| 139 | spin_lock_irq(rq->queue_lock); | 136 | spin_lock_irq(rq->queue_lock); |
| 140 | 137 | ||
| 141 | while (!kthread_should_stop()) { | 138 | while (1) { |
| 142 | int res; | 139 | int res; |
| 143 | 140 | ||
| 144 | dev->bg_stop = false; | 141 | dev->bg_stop = false; |
| @@ -156,15 +153,7 @@ static int mtd_blktrans_thread(void *arg) | |||
| 156 | background_done = !dev->bg_stop; | 153 | background_done = !dev->bg_stop; |
| 157 | continue; | 154 | continue; |
| 158 | } | 155 | } |
| 159 | set_current_state(TASK_INTERRUPTIBLE); | 156 | break; |
| 160 | |||
| 161 | if (kthread_should_stop()) | ||
| 162 | set_current_state(TASK_RUNNING); | ||
| 163 | |||
| 164 | spin_unlock_irq(rq->queue_lock); | ||
| 165 | schedule(); | ||
| 166 | spin_lock_irq(rq->queue_lock); | ||
| 167 | continue; | ||
| 168 | } | 157 | } |
| 169 | 158 | ||
| 170 | spin_unlock_irq(rq->queue_lock); | 159 | spin_unlock_irq(rq->queue_lock); |
| @@ -185,8 +174,6 @@ static int mtd_blktrans_thread(void *arg) | |||
| 185 | __blk_end_request_all(req, -EIO); | 174 | __blk_end_request_all(req, -EIO); |
| 186 | 175 | ||
| 187 | spin_unlock_irq(rq->queue_lock); | 176 | spin_unlock_irq(rq->queue_lock); |
| 188 | |||
| 189 | return 0; | ||
| 190 | } | 177 | } |
| 191 | 178 | ||
| 192 | static void mtd_blktrans_request(struct request_queue *rq) | 179 | static void mtd_blktrans_request(struct request_queue *rq) |
| @@ -199,10 +186,8 @@ static void mtd_blktrans_request(struct request_queue *rq) | |||
| 199 | if (!dev) | 186 | if (!dev) |
| 200 | while ((req = blk_fetch_request(rq)) != NULL) | 187 | while ((req = blk_fetch_request(rq)) != NULL) |
| 201 | __blk_end_request_all(req, -ENODEV); | 188 | __blk_end_request_all(req, -ENODEV); |
| 202 | else { | 189 | else |
| 203 | dev->bg_stop = true; | 190 | queue_work(dev->wq, &dev->work); |
| 204 | wake_up_process(dev->thread); | ||
| 205 | } | ||
| 206 | } | 191 | } |
| 207 | 192 | ||
| 208 | static int blktrans_open(struct block_device *bdev, fmode_t mode) | 193 | static int blktrans_open(struct block_device *bdev, fmode_t mode) |
| @@ -325,7 +310,7 @@ unlock: | |||
| 325 | return ret; | 310 | return ret; |
| 326 | } | 311 | } |
| 327 | 312 | ||
| 328 | static const struct block_device_operations mtd_blktrans_ops = { | 313 | static const struct block_device_operations mtd_block_ops = { |
| 329 | .owner = THIS_MODULE, | 314 | .owner = THIS_MODULE, |
| 330 | .open = blktrans_open, | 315 | .open = blktrans_open, |
| 331 | .release = blktrans_release, | 316 | .release = blktrans_release, |
| @@ -401,7 +386,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) | |||
| 401 | gd->private_data = new; | 386 | gd->private_data = new; |
| 402 | gd->major = tr->major; | 387 | gd->major = tr->major; |
| 403 | gd->first_minor = (new->devnum) << tr->part_bits; | 388 | gd->first_minor = (new->devnum) << tr->part_bits; |
| 404 | gd->fops = &mtd_blktrans_ops; | 389 | gd->fops = &mtd_block_ops; |
| 405 | 390 | ||
| 406 | if (tr->part_bits) | 391 | if (tr->part_bits) |
| 407 | if (new->devnum < 26) | 392 | if (new->devnum < 26) |
| @@ -437,14 +422,13 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) | |||
| 437 | 422 | ||
| 438 | gd->queue = new->rq; | 423 | gd->queue = new->rq; |
| 439 | 424 | ||
| 440 | /* Create processing thread */ | 425 | /* Create processing workqueue */ |
| 441 | /* TODO: workqueue ? */ | 426 | new->wq = alloc_workqueue("%s%d", 0, 0, |
| 442 | new->thread = kthread_run(mtd_blktrans_thread, new, | 427 | tr->name, new->mtd->index); |
| 443 | "%s%d", tr->name, new->mtd->index); | 428 | if (!new->wq) |
| 444 | if (IS_ERR(new->thread)) { | ||
| 445 | ret = PTR_ERR(new->thread); | ||
| 446 | goto error4; | 429 | goto error4; |
| 447 | } | 430 | INIT_WORK(&new->work, mtd_blktrans_work); |
| 431 | |||
| 448 | gd->driverfs_dev = &new->mtd->dev; | 432 | gd->driverfs_dev = &new->mtd->dev; |
| 449 | 433 | ||
| 450 | if (new->readonly) | 434 | if (new->readonly) |
| @@ -484,9 +468,8 @@ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old) | |||
| 484 | /* Stop new requests to arrive */ | 468 | /* Stop new requests to arrive */ |
| 485 | del_gendisk(old->disk); | 469 | del_gendisk(old->disk); |
| 486 | 470 | ||
| 487 | 471 | /* Stop workqueue. This will perform any pending request. */ | |
| 488 | /* Stop the thread */ | 472 | destroy_workqueue(old->wq); |
| 489 | kthread_stop(old->thread); | ||
| 490 | 473 | ||
| 491 | /* Kill current requests */ | 474 | /* Kill current requests */ |
| 492 | spin_lock_irqsave(&old->queue_lock, flags); | 475 | spin_lock_irqsave(&old->queue_lock, flags); |
diff --git a/drivers/mtd/mtdoops.c b/drivers/mtd/mtdoops.c index f5b3f91fa1cc..97bb8f6304d4 100644 --- a/drivers/mtd/mtdoops.c +++ b/drivers/mtd/mtdoops.c | |||
| @@ -271,7 +271,7 @@ static void find_next_position(struct mtdoops_context *cxt) | |||
| 271 | 271 | ||
| 272 | if (count[0] == 0xffffffff && count[1] == 0xffffffff) | 272 | if (count[0] == 0xffffffff && count[1] == 0xffffffff) |
| 273 | mark_page_unused(cxt, page); | 273 | mark_page_unused(cxt, page); |
| 274 | if (count[0] == 0xffffffff) | 274 | if (count[0] == 0xffffffff || count[1] != MTDOOPS_KERNMSG_MAGIC) |
| 275 | continue; | 275 | continue; |
| 276 | if (maxcount == 0xffffffff) { | 276 | if (maxcount == 0xffffffff) { |
| 277 | maxcount = count[0]; | 277 | maxcount = count[0]; |
| @@ -289,14 +289,13 @@ static void find_next_position(struct mtdoops_context *cxt) | |||
| 289 | } | 289 | } |
| 290 | } | 290 | } |
| 291 | if (maxcount == 0xffffffff) { | 291 | if (maxcount == 0xffffffff) { |
| 292 | cxt->nextpage = 0; | 292 | cxt->nextpage = cxt->oops_pages - 1; |
| 293 | cxt->nextcount = 1; | 293 | cxt->nextcount = 0; |
| 294 | schedule_work(&cxt->work_erase); | 294 | } |
| 295 | return; | 295 | else { |
| 296 | cxt->nextpage = maxpos; | ||
| 297 | cxt->nextcount = maxcount; | ||
| 296 | } | 298 | } |
| 297 | |||
| 298 | cxt->nextpage = maxpos; | ||
| 299 | cxt->nextcount = maxcount; | ||
| 300 | 299 | ||
| 301 | mtdoops_inc_counter(cxt); | 300 | mtdoops_inc_counter(cxt); |
| 302 | } | 301 | } |
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index dae191b3c081..5819eb575210 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
| @@ -50,16 +50,30 @@ config MTD_NAND_MUSEUM_IDS | |||
| 50 | of these chips were reused by later, larger chips. | 50 | of these chips were reused by later, larger chips. |
| 51 | 51 | ||
| 52 | config MTD_NAND_DENALI | 52 | config MTD_NAND_DENALI |
| 53 | depends on PCI | 53 | tristate "Support Denali NAND controller" |
| 54 | help | ||
| 55 | Enable support for the Denali NAND controller. This should be | ||
| 56 | combined with either the PCI or platform drivers to provide device | ||
| 57 | registration. | ||
| 58 | |||
| 59 | config MTD_NAND_DENALI_PCI | ||
| 54 | tristate "Support Denali NAND controller on Intel Moorestown" | 60 | tristate "Support Denali NAND controller on Intel Moorestown" |
| 61 | depends on PCI && MTD_NAND_DENALI | ||
| 55 | help | 62 | help |
| 56 | Enable the driver for NAND flash on Intel Moorestown, using the | 63 | Enable the driver for NAND flash on Intel Moorestown, using the |
| 57 | Denali NAND controller core. | 64 | Denali NAND controller core. |
| 58 | 65 | ||
| 66 | config MTD_NAND_DENALI_DT | ||
| 67 | tristate "Support Denali NAND controller as a DT device" | ||
| 68 | depends on HAVE_CLK && MTD_NAND_DENALI | ||
| 69 | help | ||
| 70 | Enable the driver for NAND flash on platforms using a Denali NAND | ||
| 71 | controller as a DT device. | ||
| 72 | |||
| 59 | config MTD_NAND_DENALI_SCRATCH_REG_ADDR | 73 | config MTD_NAND_DENALI_SCRATCH_REG_ADDR |
| 60 | hex "Denali NAND size scratch register address" | 74 | hex "Denali NAND size scratch register address" |
| 61 | default "0xFF108018" | 75 | default "0xFF108018" |
| 62 | depends on MTD_NAND_DENALI | 76 | depends on MTD_NAND_DENALI_PCI |
| 63 | help | 77 | help |
| 64 | Some platforms place the NAND chip size in a scratch register | 78 | Some platforms place the NAND chip size in a scratch register |
| 65 | because (some versions of) the driver aren't able to automatically | 79 | because (some versions of) the driver aren't able to automatically |
| @@ -433,6 +447,14 @@ config MTD_NAND_GPMI_NAND | |||
| 433 | block, such as SD card. So pay attention to it when you enable | 447 | block, such as SD card. So pay attention to it when you enable |
| 434 | the GPMI. | 448 | the GPMI. |
| 435 | 449 | ||
| 450 | config MTD_NAND_BCM47XXNFLASH | ||
| 451 | tristate "Support for NAND flash on BCM4706 BCMA bus" | ||
| 452 | depends on BCMA_NFLASH | ||
| 453 | help | ||
| 454 | BCMA bus can have various flash memories attached, they are | ||
| 455 | registered by bcma as platform devices. This enables driver for | ||
| 456 | NAND flash memories. For now only BCM4706 is supported. | ||
| 457 | |||
| 436 | config MTD_NAND_PLATFORM | 458 | config MTD_NAND_PLATFORM |
| 437 | tristate "Support for generic platform NAND driver" | 459 | tristate "Support for generic platform NAND driver" |
| 438 | depends on HAS_IOMEM | 460 | depends on HAS_IOMEM |
| @@ -499,12 +521,6 @@ config MTD_NAND_MXC | |||
| 499 | This enables the driver for the NAND flash controller on the | 521 | This enables the driver for the NAND flash controller on the |
| 500 | MXC processors. | 522 | MXC processors. |
| 501 | 523 | ||
| 502 | config MTD_NAND_NOMADIK | ||
| 503 | tristate "ST Nomadik 8815 NAND support" | ||
| 504 | depends on ARCH_NOMADIK | ||
| 505 | help | ||
| 506 | Driver for the NAND flash controller on the Nomadik, with ECC. | ||
| 507 | |||
| 508 | config MTD_NAND_SH_FLCTL | 524 | config MTD_NAND_SH_FLCTL |
| 509 | tristate "Support for NAND on Renesas SuperH FLCTL" | 525 | tristate "Support for NAND on Renesas SuperH FLCTL" |
| 510 | depends on SUPERH || ARCH_SHMOBILE | 526 | depends on SUPERH || ARCH_SHMOBILE |
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 6c7f2b3ca8ae..d76d91205691 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile | |||
| @@ -11,6 +11,8 @@ obj-$(CONFIG_MTD_SM_COMMON) += sm_common.o | |||
| 11 | obj-$(CONFIG_MTD_NAND_CAFE) += cafe_nand.o | 11 | obj-$(CONFIG_MTD_NAND_CAFE) += cafe_nand.o |
| 12 | obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o | 12 | obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o |
| 13 | obj-$(CONFIG_MTD_NAND_DENALI) += denali.o | 13 | obj-$(CONFIG_MTD_NAND_DENALI) += denali.o |
| 14 | obj-$(CONFIG_MTD_NAND_DENALI_PCI) += denali_pci.o | ||
| 15 | obj-$(CONFIG_MTD_NAND_DENALI_DT) += denali_dt.o | ||
| 14 | obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o | 16 | obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o |
| 15 | obj-$(CONFIG_MTD_NAND_BF5XX) += bf5xx_nand.o | 17 | obj-$(CONFIG_MTD_NAND_BF5XX) += bf5xx_nand.o |
| 16 | obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB) += ppchameleonevb.o | 18 | obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB) += ppchameleonevb.o |
| @@ -45,11 +47,11 @@ obj-$(CONFIG_MTD_NAND_MXC) += mxc_nand.o | |||
| 45 | obj-$(CONFIG_MTD_NAND_SOCRATES) += socrates_nand.o | 47 | obj-$(CONFIG_MTD_NAND_SOCRATES) += socrates_nand.o |
| 46 | obj-$(CONFIG_MTD_NAND_TXX9NDFMC) += txx9ndfmc.o | 48 | obj-$(CONFIG_MTD_NAND_TXX9NDFMC) += txx9ndfmc.o |
| 47 | obj-$(CONFIG_MTD_NAND_NUC900) += nuc900_nand.o | 49 | obj-$(CONFIG_MTD_NAND_NUC900) += nuc900_nand.o |
| 48 | obj-$(CONFIG_MTD_NAND_NOMADIK) += nomadik_nand.o | ||
| 49 | obj-$(CONFIG_MTD_NAND_MPC5121_NFC) += mpc5121_nfc.o | 50 | obj-$(CONFIG_MTD_NAND_MPC5121_NFC) += mpc5121_nfc.o |
| 50 | obj-$(CONFIG_MTD_NAND_RICOH) += r852.o | 51 | obj-$(CONFIG_MTD_NAND_RICOH) += r852.o |
| 51 | obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o | 52 | obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o |
| 52 | obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/ | 53 | obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/ |
| 53 | obj-$(CONFIG_MTD_NAND_XWAY) += xway_nand.o | 54 | obj-$(CONFIG_MTD_NAND_XWAY) += xway_nand.o |
| 55 | obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash/ | ||
| 54 | 56 | ||
| 55 | nand-objs := nand_base.o nand_bbt.o | 57 | nand-objs := nand_base.o nand_bbt.o |
diff --git a/drivers/mtd/nand/ams-delta.c b/drivers/mtd/nand/ams-delta.c index 9e7723aa7acc..f1d71cdc8aac 100644 --- a/drivers/mtd/nand/ams-delta.c +++ b/drivers/mtd/nand/ams-delta.c | |||
| @@ -173,7 +173,7 @@ static const struct gpio _mandatory_gpio[] = { | |||
| 173 | /* | 173 | /* |
| 174 | * Main initialization routine | 174 | * Main initialization routine |
| 175 | */ | 175 | */ |
| 176 | static int __devinit ams_delta_init(struct platform_device *pdev) | 176 | static int ams_delta_init(struct platform_device *pdev) |
| 177 | { | 177 | { |
| 178 | struct nand_chip *this; | 178 | struct nand_chip *this; |
| 179 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 179 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| @@ -270,7 +270,7 @@ out_free: | |||
| 270 | /* | 270 | /* |
| 271 | * Clean up routine | 271 | * Clean up routine |
| 272 | */ | 272 | */ |
| 273 | static int __devexit ams_delta_cleanup(struct platform_device *pdev) | 273 | static int ams_delta_cleanup(struct platform_device *pdev) |
| 274 | { | 274 | { |
| 275 | void __iomem *io_base = platform_get_drvdata(pdev); | 275 | void __iomem *io_base = platform_get_drvdata(pdev); |
| 276 | 276 | ||
| @@ -289,7 +289,7 @@ static int __devexit ams_delta_cleanup(struct platform_device *pdev) | |||
| 289 | 289 | ||
| 290 | static struct platform_driver ams_delta_nand_driver = { | 290 | static struct platform_driver ams_delta_nand_driver = { |
| 291 | .probe = ams_delta_init, | 291 | .probe = ams_delta_init, |
| 292 | .remove = __devexit_p(ams_delta_cleanup), | 292 | .remove = ams_delta_cleanup, |
| 293 | .driver = { | 293 | .driver = { |
| 294 | .name = "ams-delta-nand", | 294 | .name = "ams-delta-nand", |
| 295 | .owner = THIS_MODULE, | 295 | .owner = THIS_MODULE, |
diff --git a/drivers/mtd/nand/atmel_nand.c b/drivers/mtd/nand/atmel_nand.c index 92623ac2015a..90bdca61c797 100644 --- a/drivers/mtd/nand/atmel_nand.c +++ b/drivers/mtd/nand/atmel_nand.c | |||
| @@ -331,13 +331,13 @@ static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len) | |||
| 331 | * 12-bits 20-bytes 21-bytes | 331 | * 12-bits 20-bytes 21-bytes |
| 332 | * 24-bits 39-bytes 42-bytes | 332 | * 24-bits 39-bytes 42-bytes |
| 333 | */ | 333 | */ |
| 334 | static int __devinit pmecc_get_ecc_bytes(int cap, int sector_size) | 334 | static int pmecc_get_ecc_bytes(int cap, int sector_size) |
| 335 | { | 335 | { |
| 336 | int m = 12 + sector_size / 512; | 336 | int m = 12 + sector_size / 512; |
| 337 | return (m * cap + 7) / 8; | 337 | return (m * cap + 7) / 8; |
| 338 | } | 338 | } |
| 339 | 339 | ||
| 340 | static void __devinit pmecc_config_ecc_layout(struct nand_ecclayout *layout, | 340 | static void pmecc_config_ecc_layout(struct nand_ecclayout *layout, |
| 341 | int oobsize, int ecc_len) | 341 | int oobsize, int ecc_len) |
| 342 | { | 342 | { |
| 343 | int i; | 343 | int i; |
| @@ -353,7 +353,7 @@ static void __devinit pmecc_config_ecc_layout(struct nand_ecclayout *layout, | |||
| 353 | oobsize - ecc_len - layout->oobfree[0].offset; | 353 | oobsize - ecc_len - layout->oobfree[0].offset; |
| 354 | } | 354 | } |
| 355 | 355 | ||
| 356 | static void __devinit __iomem *pmecc_get_alpha_to(struct atmel_nand_host *host) | 356 | static void __iomem *pmecc_get_alpha_to(struct atmel_nand_host *host) |
| 357 | { | 357 | { |
| 358 | int table_size; | 358 | int table_size; |
| 359 | 359 | ||
| @@ -375,7 +375,7 @@ static void pmecc_data_free(struct atmel_nand_host *host) | |||
| 375 | kfree(host->pmecc_delta); | 375 | kfree(host->pmecc_delta); |
| 376 | } | 376 | } |
| 377 | 377 | ||
| 378 | static int __devinit pmecc_data_alloc(struct atmel_nand_host *host) | 378 | static int pmecc_data_alloc(struct atmel_nand_host *host) |
| 379 | { | 379 | { |
| 380 | const int cap = host->pmecc_corr_cap; | 380 | const int cap = host->pmecc_corr_cap; |
| 381 | 381 | ||
| @@ -724,6 +724,7 @@ static int pmecc_correction(struct mtd_info *mtd, u32 pmecc_stat, uint8_t *buf, | |||
| 724 | struct atmel_nand_host *host = nand_chip->priv; | 724 | struct atmel_nand_host *host = nand_chip->priv; |
| 725 | int i, err_nbr, eccbytes; | 725 | int i, err_nbr, eccbytes; |
| 726 | uint8_t *buf_pos; | 726 | uint8_t *buf_pos; |
| 727 | int total_err = 0; | ||
| 727 | 728 | ||
| 728 | eccbytes = nand_chip->ecc.bytes; | 729 | eccbytes = nand_chip->ecc.bytes; |
| 729 | for (i = 0; i < eccbytes; i++) | 730 | for (i = 0; i < eccbytes; i++) |
| @@ -751,12 +752,13 @@ normal_check: | |||
| 751 | pmecc_correct_data(mtd, buf_pos, ecc, i, | 752 | pmecc_correct_data(mtd, buf_pos, ecc, i, |
| 752 | host->pmecc_bytes_per_sector, err_nbr); | 753 | host->pmecc_bytes_per_sector, err_nbr); |
| 753 | mtd->ecc_stats.corrected += err_nbr; | 754 | mtd->ecc_stats.corrected += err_nbr; |
| 755 | total_err += err_nbr; | ||
| 754 | } | 756 | } |
| 755 | } | 757 | } |
| 756 | pmecc_stat >>= 1; | 758 | pmecc_stat >>= 1; |
| 757 | } | 759 | } |
| 758 | 760 | ||
| 759 | return 0; | 761 | return total_err; |
| 760 | } | 762 | } |
| 761 | 763 | ||
| 762 | static int atmel_nand_pmecc_read_page(struct mtd_info *mtd, | 764 | static int atmel_nand_pmecc_read_page(struct mtd_info *mtd, |
| @@ -768,6 +770,7 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd, | |||
| 768 | uint32_t *eccpos = chip->ecc.layout->eccpos; | 770 | uint32_t *eccpos = chip->ecc.layout->eccpos; |
| 769 | uint32_t stat; | 771 | uint32_t stat; |
| 770 | unsigned long end_time; | 772 | unsigned long end_time; |
| 773 | int bitflips = 0; | ||
| 771 | 774 | ||
| 772 | pmecc_writel(host->ecc, CTRL, PMECC_CTRL_RST); | 775 | pmecc_writel(host->ecc, CTRL, PMECC_CTRL_RST); |
| 773 | pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE); | 776 | pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE); |
| @@ -790,11 +793,14 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd, | |||
| 790 | } | 793 | } |
| 791 | 794 | ||
| 792 | stat = pmecc_readl_relaxed(host->ecc, ISR); | 795 | stat = pmecc_readl_relaxed(host->ecc, ISR); |
| 793 | if (stat != 0) | 796 | if (stat != 0) { |
| 794 | if (pmecc_correction(mtd, stat, buf, &oob[eccpos[0]]) != 0) | 797 | bitflips = pmecc_correction(mtd, stat, buf, &oob[eccpos[0]]); |
| 795 | return -EIO; | 798 | if (bitflips < 0) |
| 799 | /* uncorrectable errors */ | ||
| 800 | return 0; | ||
| 801 | } | ||
| 796 | 802 | ||
| 797 | return 0; | 803 | return bitflips; |
| 798 | } | 804 | } |
| 799 | 805 | ||
| 800 | static int atmel_nand_pmecc_write_page(struct mtd_info *mtd, | 806 | static int atmel_nand_pmecc_write_page(struct mtd_info *mtd, |
| @@ -1206,7 +1212,7 @@ static void atmel_nand_hwctl(struct mtd_info *mtd, int mode) | |||
| 1206 | } | 1212 | } |
| 1207 | 1213 | ||
| 1208 | #if defined(CONFIG_OF) | 1214 | #if defined(CONFIG_OF) |
| 1209 | static int __devinit atmel_of_init_port(struct atmel_nand_host *host, | 1215 | static int atmel_of_init_port(struct atmel_nand_host *host, |
| 1210 | struct device_node *np) | 1216 | struct device_node *np) |
| 1211 | { | 1217 | { |
| 1212 | u32 val, table_offset; | 1218 | u32 val, table_offset; |
| @@ -1293,7 +1299,7 @@ static int __devinit atmel_of_init_port(struct atmel_nand_host *host, | |||
| 1293 | return 0; | 1299 | return 0; |
| 1294 | } | 1300 | } |
| 1295 | #else | 1301 | #else |
| 1296 | static int __devinit atmel_of_init_port(struct atmel_nand_host *host, | 1302 | static int atmel_of_init_port(struct atmel_nand_host *host, |
| 1297 | struct device_node *np) | 1303 | struct device_node *np) |
| 1298 | { | 1304 | { |
| 1299 | return -EINVAL; | 1305 | return -EINVAL; |
diff --git a/drivers/mtd/nand/au1550nd.c b/drivers/mtd/nand/au1550nd.c index 5c47b200045a..217459d02b2f 100644 --- a/drivers/mtd/nand/au1550nd.c +++ b/drivers/mtd/nand/au1550nd.c | |||
| @@ -382,7 +382,7 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i | |||
| 382 | while(!this->dev_ready(mtd)); | 382 | while(!this->dev_ready(mtd)); |
| 383 | } | 383 | } |
| 384 | 384 | ||
| 385 | static int __devinit find_nand_cs(unsigned long nand_base) | 385 | static int find_nand_cs(unsigned long nand_base) |
| 386 | { | 386 | { |
| 387 | void __iomem *base = | 387 | void __iomem *base = |
| 388 | (void __iomem *)KSEG1ADDR(AU1000_STATIC_MEM_PHYS_ADDR); | 388 | (void __iomem *)KSEG1ADDR(AU1000_STATIC_MEM_PHYS_ADDR); |
| @@ -403,7 +403,7 @@ static int __devinit find_nand_cs(unsigned long nand_base) | |||
| 403 | return -ENODEV; | 403 | return -ENODEV; |
| 404 | } | 404 | } |
| 405 | 405 | ||
| 406 | static int __devinit au1550nd_probe(struct platform_device *pdev) | 406 | static int au1550nd_probe(struct platform_device *pdev) |
| 407 | { | 407 | { |
| 408 | struct au1550nd_platdata *pd; | 408 | struct au1550nd_platdata *pd; |
| 409 | struct au1550nd_ctx *ctx; | 409 | struct au1550nd_ctx *ctx; |
| @@ -491,7 +491,7 @@ out1: | |||
| 491 | return ret; | 491 | return ret; |
| 492 | } | 492 | } |
| 493 | 493 | ||
| 494 | static int __devexit au1550nd_remove(struct platform_device *pdev) | 494 | static int au1550nd_remove(struct platform_device *pdev) |
| 495 | { | 495 | { |
| 496 | struct au1550nd_ctx *ctx = platform_get_drvdata(pdev); | 496 | struct au1550nd_ctx *ctx = platform_get_drvdata(pdev); |
| 497 | struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 497 | struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| @@ -509,7 +509,7 @@ static struct platform_driver au1550nd_driver = { | |||
| 509 | .owner = THIS_MODULE, | 509 | .owner = THIS_MODULE, |
| 510 | }, | 510 | }, |
| 511 | .probe = au1550nd_probe, | 511 | .probe = au1550nd_probe, |
| 512 | .remove = __devexit_p(au1550nd_remove), | 512 | .remove = au1550nd_remove, |
| 513 | }; | 513 | }; |
| 514 | 514 | ||
| 515 | module_platform_driver(au1550nd_driver); | 515 | module_platform_driver(au1550nd_driver); |
diff --git a/drivers/mtd/nand/bcm47xxnflash/Makefile b/drivers/mtd/nand/bcm47xxnflash/Makefile new file mode 100644 index 000000000000..f05b119e134b --- /dev/null +++ b/drivers/mtd/nand/bcm47xxnflash/Makefile | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | bcm47xxnflash-y += main.o | ||
| 2 | bcm47xxnflash-y += ops_bcm4706.o | ||
| 3 | |||
| 4 | obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash.o | ||
diff --git a/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h b/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h new file mode 100644 index 000000000000..0bdb2ce4da75 --- /dev/null +++ b/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h | |||
| @@ -0,0 +1,22 @@ | |||
| 1 | #ifndef __BCM47XXNFLASH_H | ||
| 2 | #define __BCM47XXNFLASH_H | ||
| 3 | |||
| 4 | #include <linux/mtd/mtd.h> | ||
| 5 | #include <linux/mtd/nand.h> | ||
| 6 | |||
| 7 | struct bcm47xxnflash { | ||
| 8 | struct bcma_drv_cc *cc; | ||
| 9 | |||
| 10 | struct nand_chip nand_chip; | ||
| 11 | struct mtd_info mtd; | ||
| 12 | |||
| 13 | unsigned curr_command; | ||
| 14 | int curr_page_addr; | ||
| 15 | int curr_column; | ||
| 16 | |||
| 17 | u8 id_data[8]; | ||
| 18 | }; | ||
| 19 | |||
| 20 | int bcm47xxnflash_ops_bcm4706_init(struct bcm47xxnflash *b47n); | ||
| 21 | |||
| 22 | #endif /* BCM47XXNFLASH */ | ||
diff --git a/drivers/mtd/nand/bcm47xxnflash/main.c b/drivers/mtd/nand/bcm47xxnflash/main.c new file mode 100644 index 000000000000..2b8b05bec3dd --- /dev/null +++ b/drivers/mtd/nand/bcm47xxnflash/main.c | |||
| @@ -0,0 +1,108 @@ | |||
| 1 | /* | ||
| 2 | * BCM47XX NAND flash driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Rafał Miłecki <zajec5@gmail.com> | ||
| 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 | */ | ||
| 11 | |||
| 12 | #include <linux/module.h> | ||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/slab.h> | ||
| 15 | #include <linux/platform_device.h> | ||
| 16 | #include <linux/bcma/bcma.h> | ||
| 17 | |||
| 18 | #include "bcm47xxnflash.h" | ||
| 19 | |||
| 20 | MODULE_DESCRIPTION("NAND flash driver for BCMA bus"); | ||
| 21 | MODULE_LICENSE("GPL"); | ||
| 22 | MODULE_AUTHOR("Rafał Miłecki"); | ||
| 23 | |||
| 24 | static const char *probes[] = { "bcm47xxpart", NULL }; | ||
| 25 | |||
| 26 | static int bcm47xxnflash_probe(struct platform_device *pdev) | ||
| 27 | { | ||
| 28 | struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev); | ||
| 29 | struct bcm47xxnflash *b47n; | ||
| 30 | int err = 0; | ||
| 31 | |||
| 32 | b47n = kzalloc(sizeof(*b47n), GFP_KERNEL); | ||
| 33 | if (!b47n) { | ||
| 34 | err = -ENOMEM; | ||
| 35 | goto out; | ||
| 36 | } | ||
| 37 | |||
| 38 | b47n->nand_chip.priv = b47n; | ||
| 39 | b47n->mtd.owner = THIS_MODULE; | ||
| 40 | b47n->mtd.priv = &b47n->nand_chip; /* Required */ | ||
| 41 | b47n->cc = container_of(nflash, struct bcma_drv_cc, nflash); | ||
| 42 | |||
| 43 | if (b47n->cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) { | ||
| 44 | err = bcm47xxnflash_ops_bcm4706_init(b47n); | ||
| 45 | } else { | ||
| 46 | pr_err("Device not supported\n"); | ||
| 47 | err = -ENOTSUPP; | ||
| 48 | } | ||
| 49 | if (err) { | ||
| 50 | pr_err("Initialization failed: %d\n", err); | ||
| 51 | goto err_init; | ||
| 52 | } | ||
| 53 | |||
| 54 | err = mtd_device_parse_register(&b47n->mtd, probes, NULL, NULL, 0); | ||
| 55 | if (err) { | ||
| 56 | pr_err("Failed to register MTD device: %d\n", err); | ||
| 57 | goto err_dev_reg; | ||
| 58 | } | ||
| 59 | |||
| 60 | return 0; | ||
| 61 | |||
| 62 | err_dev_reg: | ||
| 63 | err_init: | ||
| 64 | kfree(b47n); | ||
| 65 | out: | ||
| 66 | return err; | ||
| 67 | } | ||
| 68 | |||
| 69 | static int __devexit bcm47xxnflash_remove(struct platform_device *pdev) | ||
| 70 | { | ||
| 71 | struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev); | ||
| 72 | |||
| 73 | if (nflash->mtd) | ||
| 74 | mtd_device_unregister(nflash->mtd); | ||
| 75 | |||
| 76 | return 0; | ||
| 77 | } | ||
| 78 | |||
| 79 | static struct platform_driver bcm47xxnflash_driver = { | ||
| 80 | .remove = __devexit_p(bcm47xxnflash_remove), | ||
| 81 | .driver = { | ||
| 82 | .name = "bcma_nflash", | ||
| 83 | .owner = THIS_MODULE, | ||
| 84 | }, | ||
| 85 | }; | ||
| 86 | |||
| 87 | static int __init bcm47xxnflash_init(void) | ||
| 88 | { | ||
| 89 | int err; | ||
| 90 | |||
| 91 | /* | ||
| 92 | * Platform device "bcma_nflash" exists on SoCs and is registered very | ||
| 93 | * early, it won't be added during runtime (use platform_driver_probe). | ||
| 94 | */ | ||
| 95 | err = platform_driver_probe(&bcm47xxnflash_driver, bcm47xxnflash_probe); | ||
| 96 | if (err) | ||
| 97 | pr_err("Failed to register serial flash driver: %d\n", err); | ||
| 98 | |||
| 99 | return err; | ||
| 100 | } | ||
| 101 | |||
| 102 | static void __exit bcm47xxnflash_exit(void) | ||
| 103 | { | ||
| 104 | platform_driver_unregister(&bcm47xxnflash_driver); | ||
| 105 | } | ||
| 106 | |||
| 107 | module_init(bcm47xxnflash_init); | ||
| 108 | module_exit(bcm47xxnflash_exit); | ||
diff --git a/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c b/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c new file mode 100644 index 000000000000..86c9a79b89b3 --- /dev/null +++ b/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c | |||
| @@ -0,0 +1,413 @@ | |||
| 1 | /* | ||
| 2 | * BCM47XX NAND flash driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2012 Rafał Miłecki <zajec5@gmail.com> | ||
| 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 | */ | ||
| 11 | |||
| 12 | #include <linux/module.h> | ||
| 13 | #include <linux/kernel.h> | ||
| 14 | #include <linux/slab.h> | ||
| 15 | #include <linux/bcma/bcma.h> | ||
| 16 | |||
| 17 | #include "bcm47xxnflash.h" | ||
| 18 | |||
| 19 | /* Broadcom uses 1'000'000 but it seems to be too many. Tests on WNDR4500 has | ||
| 20 | * shown 164 retries as maxiumum. */ | ||
| 21 | #define NFLASH_READY_RETRIES 1000 | ||
| 22 | |||
| 23 | #define NFLASH_SECTOR_SIZE 512 | ||
| 24 | |||
| 25 | #define NCTL_CMD0 0x00010000 | ||
| 26 | #define NCTL_CMD1W 0x00080000 | ||
| 27 | #define NCTL_READ 0x00100000 | ||
| 28 | #define NCTL_WRITE 0x00200000 | ||
| 29 | #define NCTL_SPECADDR 0x01000000 | ||
| 30 | #define NCTL_READY 0x04000000 | ||
| 31 | #define NCTL_ERR 0x08000000 | ||
| 32 | #define NCTL_CSA 0x40000000 | ||
| 33 | #define NCTL_START 0x80000000 | ||
| 34 | |||
| 35 | /************************************************** | ||
| 36 | * Various helpers | ||
| 37 | **************************************************/ | ||
| 38 | |||
| 39 | static inline u8 bcm47xxnflash_ops_bcm4706_ns_to_cycle(u16 ns, u16 clock) | ||
| 40 | { | ||
| 41 | return ((ns * 1000 * clock) / 1000000) + 1; | ||
| 42 | } | ||
| 43 | |||
| 44 | static int bcm47xxnflash_ops_bcm4706_ctl_cmd(struct bcma_drv_cc *cc, u32 code) | ||
| 45 | { | ||
| 46 | int i = 0; | ||
| 47 | |||
| 48 | bcma_cc_write32(cc, BCMA_CC_NFLASH_CTL, NCTL_START | code); | ||
| 49 | for (i = 0; i < NFLASH_READY_RETRIES; i++) { | ||
| 50 | if (!(bcma_cc_read32(cc, BCMA_CC_NFLASH_CTL) & NCTL_START)) { | ||
| 51 | i = 0; | ||
| 52 | break; | ||
| 53 | } | ||
| 54 | } | ||
| 55 | if (i) { | ||
| 56 | pr_err("NFLASH control command not ready!\n"); | ||
| 57 | return -EBUSY; | ||
| 58 | } | ||
| 59 | return 0; | ||
| 60 | } | ||
| 61 | |||
| 62 | static int bcm47xxnflash_ops_bcm4706_poll(struct bcma_drv_cc *cc) | ||
| 63 | { | ||
| 64 | int i; | ||
| 65 | |||
| 66 | for (i = 0; i < NFLASH_READY_RETRIES; i++) { | ||
| 67 | if (bcma_cc_read32(cc, BCMA_CC_NFLASH_CTL) & NCTL_READY) { | ||
| 68 | if (bcma_cc_read32(cc, BCMA_CC_NFLASH_CTL) & | ||
| 69 | BCMA_CC_NFLASH_CTL_ERR) { | ||
| 70 | pr_err("Error on polling\n"); | ||
| 71 | return -EBUSY; | ||
| 72 | } else { | ||
| 73 | return 0; | ||
| 74 | } | ||
| 75 | } | ||
| 76 | } | ||
| 77 | |||
| 78 | pr_err("Polling timeout!\n"); | ||
| 79 | return -EBUSY; | ||
| 80 | } | ||
| 81 | |||
| 82 | /************************************************** | ||
| 83 | * R/W | ||
| 84 | **************************************************/ | ||
| 85 | |||
| 86 | static void bcm47xxnflash_ops_bcm4706_read(struct mtd_info *mtd, uint8_t *buf, | ||
| 87 | int len) | ||
| 88 | { | ||
| 89 | struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; | ||
| 90 | struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; | ||
| 91 | |||
| 92 | u32 ctlcode; | ||
| 93 | u32 *dest = (u32 *)buf; | ||
| 94 | int i; | ||
| 95 | int toread; | ||
| 96 | |||
| 97 | BUG_ON(b47n->curr_page_addr & ~nand_chip->pagemask); | ||
| 98 | /* Don't validate column using nand_chip->page_shift, it may be bigger | ||
| 99 | * when accessing OOB */ | ||
| 100 | |||
| 101 | while (len) { | ||
| 102 | /* We can read maximum of 0x200 bytes at once */ | ||
| 103 | toread = min(len, 0x200); | ||
| 104 | |||
| 105 | /* Set page and column */ | ||
| 106 | bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_COL_ADDR, | ||
| 107 | b47n->curr_column); | ||
| 108 | bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_ROW_ADDR, | ||
| 109 | b47n->curr_page_addr); | ||
| 110 | |||
| 111 | /* Prepare to read */ | ||
| 112 | ctlcode = NCTL_CSA | NCTL_CMD1W | 0x00040000 | 0x00020000 | | ||
| 113 | NCTL_CMD0; | ||
| 114 | ctlcode |= NAND_CMD_READSTART << 8; | ||
| 115 | if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc, ctlcode)) | ||
| 116 | return; | ||
| 117 | if (bcm47xxnflash_ops_bcm4706_poll(b47n->cc)) | ||
| 118 | return; | ||
| 119 | |||
| 120 | /* Eventually read some data :) */ | ||
| 121 | for (i = 0; i < toread; i += 4, dest++) { | ||
| 122 | ctlcode = NCTL_CSA | 0x30000000 | NCTL_READ; | ||
| 123 | if (i == toread - 4) /* Last read goes without that */ | ||
| 124 | ctlcode &= ~NCTL_CSA; | ||
| 125 | if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc, | ||
| 126 | ctlcode)) | ||
| 127 | return; | ||
| 128 | *dest = bcma_cc_read32(b47n->cc, BCMA_CC_NFLASH_DATA); | ||
| 129 | } | ||
| 130 | |||
| 131 | b47n->curr_column += toread; | ||
| 132 | len -= toread; | ||
| 133 | } | ||
| 134 | } | ||
| 135 | |||
| 136 | static void bcm47xxnflash_ops_bcm4706_write(struct mtd_info *mtd, | ||
| 137 | const uint8_t *buf, int len) | ||
| 138 | { | ||
| 139 | struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; | ||
| 140 | struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; | ||
| 141 | struct bcma_drv_cc *cc = b47n->cc; | ||
| 142 | |||
| 143 | u32 ctlcode; | ||
| 144 | const u32 *data = (u32 *)buf; | ||
| 145 | int i; | ||
| 146 | |||
| 147 | BUG_ON(b47n->curr_page_addr & ~nand_chip->pagemask); | ||
| 148 | /* Don't validate column using nand_chip->page_shift, it may be bigger | ||
| 149 | * when accessing OOB */ | ||
| 150 | |||
| 151 | for (i = 0; i < len; i += 4, data++) { | ||
| 152 | bcma_cc_write32(cc, BCMA_CC_NFLASH_DATA, *data); | ||
| 153 | |||
| 154 | ctlcode = NCTL_CSA | 0x30000000 | NCTL_WRITE; | ||
| 155 | if (i == len - 4) /* Last read goes without that */ | ||
| 156 | ctlcode &= ~NCTL_CSA; | ||
| 157 | if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, ctlcode)) { | ||
| 158 | pr_err("%s ctl_cmd didn't work!\n", __func__); | ||
| 159 | return; | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 163 | b47n->curr_column += len; | ||
| 164 | } | ||
| 165 | |||
| 166 | /************************************************** | ||
| 167 | * NAND chip ops | ||
| 168 | **************************************************/ | ||
| 169 | |||
| 170 | /* Default nand_select_chip calls cmd_ctrl, which is not used in BCM4706 */ | ||
| 171 | static void bcm47xxnflash_ops_bcm4706_select_chip(struct mtd_info *mtd, | ||
| 172 | int chip) | ||
| 173 | { | ||
| 174 | return; | ||
| 175 | } | ||
| 176 | |||
| 177 | /* | ||
| 178 | * Default nand_command and nand_command_lp don't match BCM4706 hardware layout. | ||
| 179 | * For example, reading chip id is performed in a non-standard way. | ||
| 180 | * Setting column and page is also handled differently, we use a special | ||
| 181 | * registers of ChipCommon core. Hacking cmd_ctrl to understand and convert | ||
| 182 | * standard commands would be much more complicated. | ||
| 183 | */ | ||
| 184 | static void bcm47xxnflash_ops_bcm4706_cmdfunc(struct mtd_info *mtd, | ||
| 185 | unsigned command, int column, | ||
| 186 | int page_addr) | ||
| 187 | { | ||
| 188 | struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; | ||
| 189 | struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; | ||
| 190 | struct bcma_drv_cc *cc = b47n->cc; | ||
| 191 | u32 ctlcode; | ||
| 192 | int i; | ||
| 193 | |||
| 194 | if (column != -1) | ||
| 195 | b47n->curr_column = column; | ||
| 196 | if (page_addr != -1) | ||
| 197 | b47n->curr_page_addr = page_addr; | ||
| 198 | |||
| 199 | switch (command) { | ||
| 200 | case NAND_CMD_RESET: | ||
| 201 | pr_warn("Chip reset not implemented yet\n"); | ||
| 202 | break; | ||
| 203 | case NAND_CMD_READID: | ||
| 204 | ctlcode = NCTL_CSA | 0x01000000 | NCTL_CMD1W | NCTL_CMD0; | ||
| 205 | ctlcode |= NAND_CMD_READID; | ||
| 206 | if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc, ctlcode)) { | ||
| 207 | pr_err("READID error\n"); | ||
| 208 | break; | ||
| 209 | } | ||
| 210 | |||
| 211 | /* | ||
| 212 | * Reading is specific, last one has to go without NCTL_CSA | ||
| 213 | * bit. We don't know how many reads NAND subsystem is going | ||
| 214 | * to perform, so cache everything. | ||
| 215 | */ | ||
| 216 | for (i = 0; i < ARRAY_SIZE(b47n->id_data); i++) { | ||
| 217 | ctlcode = NCTL_CSA | NCTL_READ; | ||
| 218 | if (i == ARRAY_SIZE(b47n->id_data) - 1) | ||
| 219 | ctlcode &= ~NCTL_CSA; | ||
| 220 | if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc, | ||
| 221 | ctlcode)) { | ||
| 222 | pr_err("READID error\n"); | ||
| 223 | break; | ||
| 224 | } | ||
| 225 | b47n->id_data[i] = | ||
| 226 | bcma_cc_read32(b47n->cc, BCMA_CC_NFLASH_DATA) | ||
| 227 | & 0xFF; | ||
| 228 | } | ||
| 229 | |||
| 230 | break; | ||
| 231 | case NAND_CMD_STATUS: | ||
| 232 | ctlcode = NCTL_CSA | NCTL_CMD0 | NAND_CMD_STATUS; | ||
| 233 | if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, ctlcode)) | ||
| 234 | pr_err("STATUS command error\n"); | ||
| 235 | break; | ||
| 236 | case NAND_CMD_READ0: | ||
| 237 | break; | ||
| 238 | case NAND_CMD_READOOB: | ||
| 239 | if (page_addr != -1) | ||
| 240 | b47n->curr_column += mtd->writesize; | ||
| 241 | break; | ||
| 242 | case NAND_CMD_ERASE1: | ||
| 243 | bcma_cc_write32(cc, BCMA_CC_NFLASH_ROW_ADDR, | ||
| 244 | b47n->curr_page_addr); | ||
| 245 | ctlcode = 0x00040000 | NCTL_CMD1W | NCTL_CMD0 | | ||
| 246 | NAND_CMD_ERASE1 | (NAND_CMD_ERASE2 << 8); | ||
| 247 | if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, ctlcode)) | ||
| 248 | pr_err("ERASE1 failed\n"); | ||
| 249 | break; | ||
| 250 | case NAND_CMD_ERASE2: | ||
| 251 | break; | ||
| 252 | case NAND_CMD_SEQIN: | ||
| 253 | /* Set page and column */ | ||
| 254 | bcma_cc_write32(cc, BCMA_CC_NFLASH_COL_ADDR, | ||
| 255 | b47n->curr_column); | ||
| 256 | bcma_cc_write32(cc, BCMA_CC_NFLASH_ROW_ADDR, | ||
| 257 | b47n->curr_page_addr); | ||
| 258 | |||
| 259 | /* Prepare to write */ | ||
| 260 | ctlcode = 0x40000000 | 0x00040000 | 0x00020000 | 0x00010000; | ||
| 261 | ctlcode |= NAND_CMD_SEQIN; | ||
| 262 | if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, ctlcode)) | ||
| 263 | pr_err("SEQIN failed\n"); | ||
| 264 | break; | ||
| 265 | case NAND_CMD_PAGEPROG: | ||
| 266 | if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, 0x00010000 | | ||
| 267 | NAND_CMD_PAGEPROG)) | ||
| 268 | pr_err("PAGEPROG failed\n"); | ||
| 269 | if (bcm47xxnflash_ops_bcm4706_poll(cc)) | ||
| 270 | pr_err("PAGEPROG not ready\n"); | ||
| 271 | break; | ||
| 272 | default: | ||
| 273 | pr_err("Command 0x%X unsupported\n", command); | ||
| 274 | break; | ||
| 275 | } | ||
| 276 | b47n->curr_command = command; | ||
| 277 | } | ||
| 278 | |||
| 279 | static u8 bcm47xxnflash_ops_bcm4706_read_byte(struct mtd_info *mtd) | ||
| 280 | { | ||
| 281 | struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; | ||
| 282 | struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; | ||
| 283 | struct bcma_drv_cc *cc = b47n->cc; | ||
| 284 | u32 tmp = 0; | ||
| 285 | |||
| 286 | switch (b47n->curr_command) { | ||
| 287 | case NAND_CMD_READID: | ||
| 288 | if (b47n->curr_column >= ARRAY_SIZE(b47n->id_data)) { | ||
| 289 | pr_err("Requested invalid id_data: %d\n", | ||
| 290 | b47n->curr_column); | ||
| 291 | return 0; | ||
| 292 | } | ||
| 293 | return b47n->id_data[b47n->curr_column++]; | ||
| 294 | case NAND_CMD_STATUS: | ||
| 295 | if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, NCTL_READ)) | ||
| 296 | return 0; | ||
| 297 | return bcma_cc_read32(cc, BCMA_CC_NFLASH_DATA) & 0xff; | ||
| 298 | case NAND_CMD_READOOB: | ||
| 299 | bcm47xxnflash_ops_bcm4706_read(mtd, (u8 *)&tmp, 4); | ||
| 300 | return tmp & 0xFF; | ||
| 301 | } | ||
| 302 | |||
| 303 | pr_err("Invalid command for byte read: 0x%X\n", b47n->curr_command); | ||
| 304 | return 0; | ||
| 305 | } | ||
| 306 | |||
| 307 | static void bcm47xxnflash_ops_bcm4706_read_buf(struct mtd_info *mtd, | ||
| 308 | uint8_t *buf, int len) | ||
| 309 | { | ||
| 310 | struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; | ||
| 311 | struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; | ||
| 312 | |||
| 313 | switch (b47n->curr_command) { | ||
| 314 | case NAND_CMD_READ0: | ||
| 315 | case NAND_CMD_READOOB: | ||
| 316 | bcm47xxnflash_ops_bcm4706_read(mtd, buf, len); | ||
| 317 | return; | ||
| 318 | } | ||
| 319 | |||
| 320 | pr_err("Invalid command for buf read: 0x%X\n", b47n->curr_command); | ||
| 321 | } | ||
| 322 | |||
| 323 | static void bcm47xxnflash_ops_bcm4706_write_buf(struct mtd_info *mtd, | ||
| 324 | const uint8_t *buf, int len) | ||
| 325 | { | ||
| 326 | struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; | ||
| 327 | struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; | ||
| 328 | |||
| 329 | switch (b47n->curr_command) { | ||
| 330 | case NAND_CMD_SEQIN: | ||
| 331 | bcm47xxnflash_ops_bcm4706_write(mtd, buf, len); | ||
| 332 | return; | ||
| 333 | } | ||
| 334 | |||
| 335 | pr_err("Invalid command for buf write: 0x%X\n", b47n->curr_command); | ||
| 336 | } | ||
| 337 | |||
| 338 | /************************************************** | ||
| 339 | * Init | ||
| 340 | **************************************************/ | ||
| 341 | |||
| 342 | int bcm47xxnflash_ops_bcm4706_init(struct bcm47xxnflash *b47n) | ||
| 343 | { | ||
| 344 | int err; | ||
| 345 | u32 freq; | ||
| 346 | u16 clock; | ||
| 347 | u8 w0, w1, w2, w3, w4; | ||
| 348 | |||
| 349 | unsigned long chipsize; /* MiB */ | ||
| 350 | u8 tbits, col_bits, col_size, row_bits, row_bsize; | ||
| 351 | u32 val; | ||
| 352 | |||
| 353 | b47n->nand_chip.select_chip = bcm47xxnflash_ops_bcm4706_select_chip; | ||
| 354 | b47n->nand_chip.cmdfunc = bcm47xxnflash_ops_bcm4706_cmdfunc; | ||
| 355 | b47n->nand_chip.read_byte = bcm47xxnflash_ops_bcm4706_read_byte; | ||
| 356 | b47n->nand_chip.read_buf = bcm47xxnflash_ops_bcm4706_read_buf; | ||
| 357 | b47n->nand_chip.write_buf = bcm47xxnflash_ops_bcm4706_write_buf; | ||
| 358 | b47n->nand_chip.bbt_options = NAND_BBT_USE_FLASH; | ||
| 359 | b47n->nand_chip.ecc.mode = NAND_ECC_NONE; /* TODO: implement ECC */ | ||
| 360 | |||
| 361 | /* Enable NAND flash access */ | ||
| 362 | bcma_cc_set32(b47n->cc, BCMA_CC_4706_FLASHSCFG, | ||
| 363 | BCMA_CC_4706_FLASHSCFG_NF1); | ||
| 364 | |||
| 365 | /* Configure wait counters */ | ||
| 366 | if (b47n->cc->status & BCMA_CC_CHIPST_4706_PKG_OPTION) { | ||
| 367 | freq = 100000000; | ||
| 368 | } else { | ||
| 369 | freq = bcma_chipco_pll_read(b47n->cc, 4); | ||
| 370 | freq = (freq * 0xFFF) >> 3; | ||
| 371 | freq = (freq * 25000000) >> 3; | ||
| 372 | } | ||
| 373 | clock = freq / 1000000; | ||
| 374 | w0 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(15, clock); | ||
| 375 | w1 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(20, clock); | ||
| 376 | w2 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(10, clock); | ||
| 377 | w3 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(10, clock); | ||
| 378 | w4 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(100, clock); | ||
| 379 | bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_WAITCNT0, | ||
| 380 | (w4 << 24 | w3 << 18 | w2 << 12 | w1 << 6 | w0)); | ||
| 381 | |||
| 382 | /* Scan NAND */ | ||
| 383 | err = nand_scan(&b47n->mtd, 1); | ||
| 384 | if (err) { | ||
| 385 | pr_err("Could not scan NAND flash: %d\n", err); | ||
| 386 | goto exit; | ||
| 387 | } | ||
| 388 | |||
| 389 | /* Configure FLASH */ | ||
| 390 | chipsize = b47n->nand_chip.chipsize >> 20; | ||
| 391 | tbits = ffs(chipsize); /* find first bit set */ | ||
| 392 | if (!tbits || tbits != fls(chipsize)) { | ||
| 393 | pr_err("Invalid flash size: 0x%lX\n", chipsize); | ||
| 394 | err = -ENOTSUPP; | ||
| 395 | goto exit; | ||
| 396 | } | ||
| 397 | tbits += 19; /* Broadcom increases *index* by 20, we increase *pos* */ | ||
| 398 | |||
| 399 | col_bits = b47n->nand_chip.page_shift + 1; | ||
| 400 | col_size = (col_bits + 7) / 8; | ||
| 401 | |||
| 402 | row_bits = tbits - col_bits + 1; | ||
| 403 | row_bsize = (row_bits + 7) / 8; | ||
| 404 | |||
| 405 | val = ((row_bsize - 1) << 6) | ((col_size - 1) << 4) | 2; | ||
| 406 | bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_CONF, val); | ||
| 407 | |||
| 408 | exit: | ||
| 409 | if (err) | ||
| 410 | bcma_cc_mask32(b47n->cc, BCMA_CC_4706_FLASHSCFG, | ||
| 411 | ~BCMA_CC_4706_FLASHSCFG_NF1); | ||
| 412 | return err; | ||
| 413 | } | ||
diff --git a/drivers/mtd/nand/bf5xx_nand.c b/drivers/mtd/nand/bf5xx_nand.c index ab0caa74eb43..4271e948d1e2 100644 --- a/drivers/mtd/nand/bf5xx_nand.c +++ b/drivers/mtd/nand/bf5xx_nand.c | |||
| @@ -658,7 +658,7 @@ static int bf5xx_nand_hw_init(struct bf5xx_nand_info *info) | |||
| 658 | /* | 658 | /* |
| 659 | * Device management interface | 659 | * Device management interface |
| 660 | */ | 660 | */ |
| 661 | static int __devinit bf5xx_nand_add_partition(struct bf5xx_nand_info *info) | 661 | static int bf5xx_nand_add_partition(struct bf5xx_nand_info *info) |
| 662 | { | 662 | { |
| 663 | struct mtd_info *mtd = &info->mtd; | 663 | struct mtd_info *mtd = &info->mtd; |
| 664 | struct mtd_partition *parts = info->platform->partitions; | 664 | struct mtd_partition *parts = info->platform->partitions; |
| @@ -667,7 +667,7 @@ static int __devinit bf5xx_nand_add_partition(struct bf5xx_nand_info *info) | |||
| 667 | return mtd_device_register(mtd, parts, nr); | 667 | return mtd_device_register(mtd, parts, nr); |
| 668 | } | 668 | } |
| 669 | 669 | ||
| 670 | static int __devexit bf5xx_nand_remove(struct platform_device *pdev) | 670 | static int bf5xx_nand_remove(struct platform_device *pdev) |
| 671 | { | 671 | { |
| 672 | struct bf5xx_nand_info *info = to_nand_info(pdev); | 672 | struct bf5xx_nand_info *info = to_nand_info(pdev); |
| 673 | 673 | ||
| @@ -725,7 +725,7 @@ static int bf5xx_nand_scan(struct mtd_info *mtd) | |||
| 725 | * it can allocate all necessary resources then calls the | 725 | * it can allocate all necessary resources then calls the |
| 726 | * nand layer to look for devices | 726 | * nand layer to look for devices |
| 727 | */ | 727 | */ |
| 728 | static int __devinit bf5xx_nand_probe(struct platform_device *pdev) | 728 | static int bf5xx_nand_probe(struct platform_device *pdev) |
| 729 | { | 729 | { |
| 730 | struct bf5xx_nand_platform *plat = to_nand_plat(pdev); | 730 | struct bf5xx_nand_platform *plat = to_nand_plat(pdev); |
| 731 | struct bf5xx_nand_info *info = NULL; | 731 | struct bf5xx_nand_info *info = NULL; |
| @@ -865,7 +865,7 @@ static int bf5xx_nand_resume(struct platform_device *dev) | |||
| 865 | /* driver device registration */ | 865 | /* driver device registration */ |
| 866 | static struct platform_driver bf5xx_nand_driver = { | 866 | static struct platform_driver bf5xx_nand_driver = { |
| 867 | .probe = bf5xx_nand_probe, | 867 | .probe = bf5xx_nand_probe, |
| 868 | .remove = __devexit_p(bf5xx_nand_remove), | 868 | .remove = bf5xx_nand_remove, |
| 869 | .suspend = bf5xx_nand_suspend, | 869 | .suspend = bf5xx_nand_suspend, |
| 870 | .resume = bf5xx_nand_resume, | 870 | .resume = bf5xx_nand_resume, |
| 871 | .driver = { | 871 | .driver = { |
diff --git a/drivers/mtd/nand/cafe_nand.c b/drivers/mtd/nand/cafe_nand.c index 2bb7170502c2..010d61266536 100644 --- a/drivers/mtd/nand/cafe_nand.c +++ b/drivers/mtd/nand/cafe_nand.c | |||
| @@ -585,7 +585,7 @@ static int cafe_nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) | |||
| 585 | } | 585 | } |
| 586 | 586 | ||
| 587 | /* F_2[X]/(X**6+X+1) */ | 587 | /* F_2[X]/(X**6+X+1) */ |
| 588 | static unsigned short __devinit gf64_mul(u8 a, u8 b) | 588 | static unsigned short gf64_mul(u8 a, u8 b) |
| 589 | { | 589 | { |
| 590 | u8 c; | 590 | u8 c; |
| 591 | unsigned int i; | 591 | unsigned int i; |
| @@ -604,7 +604,7 @@ static unsigned short __devinit gf64_mul(u8 a, u8 b) | |||
| 604 | } | 604 | } |
| 605 | 605 | ||
| 606 | /* F_64[X]/(X**2+X+A**-1) with A the generator of F_64[X] */ | 606 | /* F_64[X]/(X**2+X+A**-1) with A the generator of F_64[X] */ |
| 607 | static u16 __devinit gf4096_mul(u16 a, u16 b) | 607 | static u16 gf4096_mul(u16 a, u16 b) |
| 608 | { | 608 | { |
| 609 | u8 ah, al, bh, bl, ch, cl; | 609 | u8 ah, al, bh, bl, ch, cl; |
| 610 | 610 | ||
| @@ -619,14 +619,14 @@ static u16 __devinit gf4096_mul(u16 a, u16 b) | |||
| 619 | return (ch << 6) ^ cl; | 619 | return (ch << 6) ^ cl; |
| 620 | } | 620 | } |
| 621 | 621 | ||
| 622 | static int __devinit cafe_mul(int x) | 622 | static int cafe_mul(int x) |
| 623 | { | 623 | { |
| 624 | if (x == 0) | 624 | if (x == 0) |
| 625 | return 1; | 625 | return 1; |
| 626 | return gf4096_mul(x, 0xe01); | 626 | return gf4096_mul(x, 0xe01); |
| 627 | } | 627 | } |
| 628 | 628 | ||
| 629 | static int __devinit cafe_nand_probe(struct pci_dev *pdev, | 629 | static int cafe_nand_probe(struct pci_dev *pdev, |
| 630 | const struct pci_device_id *ent) | 630 | const struct pci_device_id *ent) |
| 631 | { | 631 | { |
| 632 | struct mtd_info *mtd; | 632 | struct mtd_info *mtd; |
| @@ -821,7 +821,7 @@ static int __devinit cafe_nand_probe(struct pci_dev *pdev, | |||
| 821 | return err; | 821 | return err; |
| 822 | } | 822 | } |
| 823 | 823 | ||
| 824 | static void __devexit cafe_nand_remove(struct pci_dev *pdev) | 824 | static void cafe_nand_remove(struct pci_dev *pdev) |
| 825 | { | 825 | { |
| 826 | struct mtd_info *mtd = pci_get_drvdata(pdev); | 826 | struct mtd_info *mtd = pci_get_drvdata(pdev); |
| 827 | struct cafe_priv *cafe = mtd->priv; | 827 | struct cafe_priv *cafe = mtd->priv; |
| @@ -887,7 +887,7 @@ static struct pci_driver cafe_nand_pci_driver = { | |||
| 887 | .name = "CAFÉ NAND", | 887 | .name = "CAFÉ NAND", |
| 888 | .id_table = cafe_nand_tbl, | 888 | .id_table = cafe_nand_tbl, |
| 889 | .probe = cafe_nand_probe, | 889 | .probe = cafe_nand_probe, |
| 890 | .remove = __devexit_p(cafe_nand_remove), | 890 | .remove = cafe_nand_remove, |
| 891 | .resume = cafe_nand_resume, | 891 | .resume = cafe_nand_resume, |
| 892 | }; | 892 | }; |
| 893 | 893 | ||
diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/cs553x_nand.c index adb6c3ef37fb..2cdeab8bebc4 100644 --- a/drivers/mtd/nand/cs553x_nand.c +++ b/drivers/mtd/nand/cs553x_nand.c | |||
| @@ -237,6 +237,7 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr) | |||
| 237 | this->ecc.hwctl = cs_enable_hwecc; | 237 | this->ecc.hwctl = cs_enable_hwecc; |
| 238 | this->ecc.calculate = cs_calculate_ecc; | 238 | this->ecc.calculate = cs_calculate_ecc; |
| 239 | this->ecc.correct = nand_correct_data; | 239 | this->ecc.correct = nand_correct_data; |
| 240 | this->ecc.strength = 1; | ||
| 240 | 241 | ||
| 241 | /* Enable the following for a flash based bad block table */ | 242 | /* Enable the following for a flash based bad block table */ |
| 242 | this->bbt_options = NAND_BBT_USE_FLASH; | 243 | this->bbt_options = NAND_BBT_USE_FLASH; |
| @@ -247,8 +248,6 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr) | |||
| 247 | goto out_ior; | 248 | goto out_ior; |
| 248 | } | 249 | } |
| 249 | 250 | ||
| 250 | this->ecc.strength = 1; | ||
| 251 | |||
| 252 | new_mtd->name = kasprintf(GFP_KERNEL, "cs553x_nand_cs%d", cs); | 251 | new_mtd->name = kasprintf(GFP_KERNEL, "cs553x_nand_cs%d", cs); |
| 253 | 252 | ||
| 254 | cs553x_mtd[cs] = new_mtd; | 253 | cs553x_mtd[cs] = new_mtd; |
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index 945047ad0952..3502606f6480 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c | |||
| @@ -821,9 +821,16 @@ syndrome_done: | |||
| 821 | if (ret < 0) | 821 | if (ret < 0) |
| 822 | goto err_scan; | 822 | goto err_scan; |
| 823 | 823 | ||
| 824 | ret = mtd_device_parse_register(&info->mtd, NULL, NULL, pdata->parts, | 824 | if (pdata->parts) |
| 825 | pdata->nr_parts); | 825 | ret = mtd_device_parse_register(&info->mtd, NULL, NULL, |
| 826 | 826 | pdata->parts, pdata->nr_parts); | |
| 827 | else { | ||
| 828 | struct mtd_part_parser_data ppdata; | ||
| 829 | |||
| 830 | ppdata.of_node = pdev->dev.of_node; | ||
| 831 | ret = mtd_device_parse_register(&info->mtd, NULL, &ppdata, | ||
| 832 | NULL, 0); | ||
| 833 | } | ||
| 827 | if (ret < 0) | 834 | if (ret < 0) |
| 828 | goto err_scan; | 835 | goto err_scan; |
| 829 | 836 | ||
diff --git a/drivers/mtd/nand/denali.c b/drivers/mtd/nand/denali.c index e706a237170f..0c8bb6bf8424 100644 --- a/drivers/mtd/nand/denali.c +++ b/drivers/mtd/nand/denali.c | |||
| @@ -16,14 +16,12 @@ | |||
| 16 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | 16 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. |
| 17 | * | 17 | * |
| 18 | */ | 18 | */ |
| 19 | |||
| 20 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
| 21 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
| 22 | #include <linux/dma-mapping.h> | 21 | #include <linux/dma-mapping.h> |
| 23 | #include <linux/wait.h> | 22 | #include <linux/wait.h> |
| 24 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
| 25 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
| 26 | #include <linux/pci.h> | ||
| 27 | #include <linux/mtd/mtd.h> | 25 | #include <linux/mtd/mtd.h> |
| 28 | #include <linux/module.h> | 26 | #include <linux/module.h> |
| 29 | 27 | ||
| @@ -89,13 +87,6 @@ MODULE_PARM_DESC(onfi_timing_mode, "Overrides default ONFI setting." | |||
| 89 | * format the bank into the proper bits for the controller */ | 87 | * format the bank into the proper bits for the controller */ |
| 90 | #define BANK(x) ((x) << 24) | 88 | #define BANK(x) ((x) << 24) |
| 91 | 89 | ||
| 92 | /* List of platforms this NAND controller has be integrated into */ | ||
| 93 | static const struct pci_device_id denali_pci_ids[] = { | ||
| 94 | { PCI_VDEVICE(INTEL, 0x0701), INTEL_CE4100 }, | ||
| 95 | { PCI_VDEVICE(INTEL, 0x0809), INTEL_MRST }, | ||
| 96 | { /* end: all zeroes */ } | ||
| 97 | }; | ||
| 98 | |||
| 99 | /* forward declarations */ | 90 | /* forward declarations */ |
| 100 | static void clear_interrupts(struct denali_nand_info *denali); | 91 | static void clear_interrupts(struct denali_nand_info *denali); |
| 101 | static uint32_t wait_for_irq(struct denali_nand_info *denali, | 92 | static uint32_t wait_for_irq(struct denali_nand_info *denali, |
| @@ -699,7 +690,7 @@ static uint32_t wait_for_irq(struct denali_nand_info *denali, uint32_t irq_mask) | |||
| 699 | 690 | ||
| 700 | if (comp_res == 0) { | 691 | if (comp_res == 0) { |
| 701 | /* timeout */ | 692 | /* timeout */ |
| 702 | printk(KERN_ERR "timeout occurred, status = 0x%x, mask = 0x%x\n", | 693 | pr_err("timeout occurred, status = 0x%x, mask = 0x%x\n", |
| 703 | intr_status, irq_mask); | 694 | intr_status, irq_mask); |
| 704 | 695 | ||
| 705 | intr_status = 0; | 696 | intr_status = 0; |
| @@ -1305,8 +1296,7 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col, | |||
| 1305 | /* TODO: Read OOB data */ | 1296 | /* TODO: Read OOB data */ |
| 1306 | break; | 1297 | break; |
| 1307 | default: | 1298 | default: |
| 1308 | printk(KERN_ERR ": unsupported command" | 1299 | pr_err(": unsupported command received 0x%x\n", cmd); |
| 1309 | " received 0x%x\n", cmd); | ||
| 1310 | break; | 1300 | break; |
| 1311 | } | 1301 | } |
| 1312 | } | 1302 | } |
| @@ -1425,107 +1415,48 @@ void denali_drv_init(struct denali_nand_info *denali) | |||
| 1425 | denali->irq_status = 0; | 1415 | denali->irq_status = 0; |
| 1426 | } | 1416 | } |
| 1427 | 1417 | ||
| 1428 | /* driver entry point */ | 1418 | int denali_init(struct denali_nand_info *denali) |
| 1429 | static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | ||
| 1430 | { | 1419 | { |
| 1431 | int ret = -ENODEV; | 1420 | int ret; |
| 1432 | resource_size_t csr_base, mem_base; | ||
| 1433 | unsigned long csr_len, mem_len; | ||
| 1434 | struct denali_nand_info *denali; | ||
| 1435 | |||
| 1436 | denali = kzalloc(sizeof(*denali), GFP_KERNEL); | ||
| 1437 | if (!denali) | ||
| 1438 | return -ENOMEM; | ||
| 1439 | 1421 | ||
| 1440 | ret = pci_enable_device(dev); | 1422 | if (denali->platform == INTEL_CE4100) { |
| 1441 | if (ret) { | ||
| 1442 | printk(KERN_ERR "Spectra: pci_enable_device failed.\n"); | ||
| 1443 | goto failed_alloc_memery; | ||
| 1444 | } | ||
| 1445 | |||
| 1446 | if (id->driver_data == INTEL_CE4100) { | ||
| 1447 | /* Due to a silicon limitation, we can only support | 1423 | /* Due to a silicon limitation, we can only support |
| 1448 | * ONFI timing mode 1 and below. | 1424 | * ONFI timing mode 1 and below. |
| 1449 | */ | 1425 | */ |
| 1450 | if (onfi_timing_mode < -1 || onfi_timing_mode > 1) { | 1426 | if (onfi_timing_mode < -1 || onfi_timing_mode > 1) { |
| 1451 | printk(KERN_ERR "Intel CE4100 only supports" | 1427 | pr_err("Intel CE4100 only supports ONFI timing mode 1 or below\n"); |
| 1452 | " ONFI timing mode 1 or below\n"); | 1428 | return -EINVAL; |
| 1453 | ret = -EINVAL; | ||
| 1454 | goto failed_enable_dev; | ||
| 1455 | } | ||
| 1456 | denali->platform = INTEL_CE4100; | ||
| 1457 | mem_base = pci_resource_start(dev, 0); | ||
| 1458 | mem_len = pci_resource_len(dev, 1); | ||
| 1459 | csr_base = pci_resource_start(dev, 1); | ||
| 1460 | csr_len = pci_resource_len(dev, 1); | ||
| 1461 | } else { | ||
| 1462 | denali->platform = INTEL_MRST; | ||
| 1463 | csr_base = pci_resource_start(dev, 0); | ||
| 1464 | csr_len = pci_resource_len(dev, 0); | ||
| 1465 | mem_base = pci_resource_start(dev, 1); | ||
| 1466 | mem_len = pci_resource_len(dev, 1); | ||
| 1467 | if (!mem_len) { | ||
| 1468 | mem_base = csr_base + csr_len; | ||
| 1469 | mem_len = csr_len; | ||
| 1470 | } | 1429 | } |
| 1471 | } | 1430 | } |
| 1472 | 1431 | ||
| 1473 | /* Is 32-bit DMA supported? */ | 1432 | /* Is 32-bit DMA supported? */ |
| 1474 | ret = dma_set_mask(&dev->dev, DMA_BIT_MASK(32)); | 1433 | ret = dma_set_mask(denali->dev, DMA_BIT_MASK(32)); |
| 1475 | if (ret) { | 1434 | if (ret) { |
| 1476 | printk(KERN_ERR "Spectra: no usable DMA configuration\n"); | 1435 | pr_err("Spectra: no usable DMA configuration\n"); |
| 1477 | goto failed_enable_dev; | 1436 | return ret; |
| 1478 | } | 1437 | } |
| 1479 | denali->buf.dma_buf = dma_map_single(&dev->dev, denali->buf.buf, | 1438 | denali->buf.dma_buf = dma_map_single(denali->dev, denali->buf.buf, |
| 1480 | DENALI_BUF_SIZE, | 1439 | DENALI_BUF_SIZE, |
| 1481 | DMA_BIDIRECTIONAL); | 1440 | DMA_BIDIRECTIONAL); |
| 1482 | 1441 | ||
| 1483 | if (dma_mapping_error(&dev->dev, denali->buf.dma_buf)) { | 1442 | if (dma_mapping_error(denali->dev, denali->buf.dma_buf)) { |
| 1484 | dev_err(&dev->dev, "Spectra: failed to map DMA buffer\n"); | 1443 | dev_err(denali->dev, "Spectra: failed to map DMA buffer\n"); |
| 1485 | goto failed_enable_dev; | 1444 | return -EIO; |
| 1486 | } | ||
| 1487 | |||
| 1488 | pci_set_master(dev); | ||
| 1489 | denali->dev = &dev->dev; | ||
| 1490 | denali->mtd.dev.parent = &dev->dev; | ||
| 1491 | |||
| 1492 | ret = pci_request_regions(dev, DENALI_NAND_NAME); | ||
| 1493 | if (ret) { | ||
| 1494 | printk(KERN_ERR "Spectra: Unable to request memory regions\n"); | ||
| 1495 | goto failed_dma_map; | ||
| 1496 | } | ||
| 1497 | |||
| 1498 | denali->flash_reg = ioremap_nocache(csr_base, csr_len); | ||
| 1499 | if (!denali->flash_reg) { | ||
| 1500 | printk(KERN_ERR "Spectra: Unable to remap memory region\n"); | ||
| 1501 | ret = -ENOMEM; | ||
| 1502 | goto failed_req_regions; | ||
| 1503 | } | ||
| 1504 | |||
| 1505 | denali->flash_mem = ioremap_nocache(mem_base, mem_len); | ||
| 1506 | if (!denali->flash_mem) { | ||
| 1507 | printk(KERN_ERR "Spectra: ioremap_nocache failed!"); | ||
| 1508 | ret = -ENOMEM; | ||
| 1509 | goto failed_remap_reg; | ||
| 1510 | } | 1445 | } |
| 1511 | 1446 | denali->mtd.dev.parent = denali->dev; | |
| 1512 | denali_hw_init(denali); | 1447 | denali_hw_init(denali); |
| 1513 | denali_drv_init(denali); | 1448 | denali_drv_init(denali); |
| 1514 | 1449 | ||
| 1515 | /* denali_isr register is done after all the hardware | 1450 | /* denali_isr register is done after all the hardware |
| 1516 | * initilization is finished*/ | 1451 | * initilization is finished*/ |
| 1517 | if (request_irq(dev->irq, denali_isr, IRQF_SHARED, | 1452 | if (request_irq(denali->irq, denali_isr, IRQF_SHARED, |
| 1518 | DENALI_NAND_NAME, denali)) { | 1453 | DENALI_NAND_NAME, denali)) { |
| 1519 | printk(KERN_ERR "Spectra: Unable to allocate IRQ\n"); | 1454 | pr_err("Spectra: Unable to allocate IRQ\n"); |
| 1520 | ret = -ENODEV; | 1455 | return -ENODEV; |
| 1521 | goto failed_remap_mem; | ||
| 1522 | } | 1456 | } |
| 1523 | 1457 | ||
| 1524 | /* now that our ISR is registered, we can enable interrupts */ | 1458 | /* now that our ISR is registered, we can enable interrupts */ |
| 1525 | denali_set_intr_modes(denali, true); | 1459 | denali_set_intr_modes(denali, true); |
| 1526 | |||
| 1527 | pci_set_drvdata(dev, denali); | ||
| 1528 | |||
| 1529 | denali->mtd.name = "denali-nand"; | 1460 | denali->mtd.name = "denali-nand"; |
| 1530 | denali->mtd.owner = THIS_MODULE; | 1461 | denali->mtd.owner = THIS_MODULE; |
| 1531 | denali->mtd.priv = &denali->nand; | 1462 | denali->mtd.priv = &denali->nand; |
| @@ -1549,8 +1480,7 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
| 1549 | */ | 1480 | */ |
| 1550 | if (denali->mtd.writesize > NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE) { | 1481 | if (denali->mtd.writesize > NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE) { |
| 1551 | ret = -ENODEV; | 1482 | ret = -ENODEV; |
| 1552 | printk(KERN_ERR "Spectra: device size not supported by this " | 1483 | pr_err("Spectra: device size not supported by this version of MTD."); |
| 1553 | "version of MTD."); | ||
| 1554 | goto failed_req_irq; | 1484 | goto failed_req_irq; |
| 1555 | } | 1485 | } |
| 1556 | 1486 | ||
| @@ -1602,8 +1532,8 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
| 1602 | } else if (denali->mtd.oobsize < (denali->bbtskipbytes + | 1532 | } else if (denali->mtd.oobsize < (denali->bbtskipbytes + |
| 1603 | ECC_8BITS * (denali->mtd.writesize / | 1533 | ECC_8BITS * (denali->mtd.writesize / |
| 1604 | ECC_SECTOR_SIZE))) { | 1534 | ECC_SECTOR_SIZE))) { |
| 1605 | printk(KERN_ERR "Your NAND chip OOB is not large enough to" | 1535 | pr_err("Your NAND chip OOB is not large enough to \ |
| 1606 | " contain 8bit ECC correction codes"); | 1536 | contain 8bit ECC correction codes"); |
| 1607 | goto failed_req_irq; | 1537 | goto failed_req_irq; |
| 1608 | } else { | 1538 | } else { |
| 1609 | denali->nand.ecc.strength = 8; | 1539 | denali->nand.ecc.strength = 8; |
| @@ -1655,56 +1585,24 @@ static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
| 1655 | 1585 | ||
| 1656 | ret = mtd_device_register(&denali->mtd, NULL, 0); | 1586 | ret = mtd_device_register(&denali->mtd, NULL, 0); |
| 1657 | if (ret) { | 1587 | if (ret) { |
| 1658 | dev_err(&dev->dev, "Spectra: Failed to register MTD: %d\n", | 1588 | dev_err(denali->dev, "Spectra: Failed to register MTD: %d\n", |
| 1659 | ret); | 1589 | ret); |
| 1660 | goto failed_req_irq; | 1590 | goto failed_req_irq; |
| 1661 | } | 1591 | } |
| 1662 | return 0; | 1592 | return 0; |
| 1663 | 1593 | ||
| 1664 | failed_req_irq: | 1594 | failed_req_irq: |
| 1665 | denali_irq_cleanup(dev->irq, denali); | 1595 | denali_irq_cleanup(denali->irq, denali); |
| 1666 | failed_remap_mem: | 1596 | |
| 1667 | iounmap(denali->flash_mem); | ||
| 1668 | failed_remap_reg: | ||
| 1669 | iounmap(denali->flash_reg); | ||
| 1670 | failed_req_regions: | ||
| 1671 | pci_release_regions(dev); | ||
| 1672 | failed_dma_map: | ||
| 1673 | dma_unmap_single(&dev->dev, denali->buf.dma_buf, DENALI_BUF_SIZE, | ||
| 1674 | DMA_BIDIRECTIONAL); | ||
| 1675 | failed_enable_dev: | ||
| 1676 | pci_disable_device(dev); | ||
| 1677 | failed_alloc_memery: | ||
| 1678 | kfree(denali); | ||
| 1679 | return ret; | 1597 | return ret; |
| 1680 | } | 1598 | } |
| 1599 | EXPORT_SYMBOL(denali_init); | ||
| 1681 | 1600 | ||
| 1682 | /* driver exit point */ | 1601 | /* driver exit point */ |
| 1683 | static void denali_pci_remove(struct pci_dev *dev) | 1602 | void denali_remove(struct denali_nand_info *denali) |
| 1684 | { | 1603 | { |
| 1685 | struct denali_nand_info *denali = pci_get_drvdata(dev); | 1604 | denali_irq_cleanup(denali->irq, denali); |
| 1686 | 1605 | dma_unmap_single(denali->dev, denali->buf.dma_buf, DENALI_BUF_SIZE, | |
| 1687 | nand_release(&denali->mtd); | 1606 | DMA_BIDIRECTIONAL); |
| 1688 | |||
| 1689 | denali_irq_cleanup(dev->irq, denali); | ||
| 1690 | |||
| 1691 | iounmap(denali->flash_reg); | ||
| 1692 | iounmap(denali->flash_mem); | ||
| 1693 | pci_release_regions(dev); | ||
| 1694 | pci_disable_device(dev); | ||
| 1695 | dma_unmap_single(&dev->dev, denali->buf.dma_buf, DENALI_BUF_SIZE, | ||
| 1696 | DMA_BIDIRECTIONAL); | ||
| 1697 | pci_set_drvdata(dev, NULL); | ||
| 1698 | kfree(denali); | ||
| 1699 | } | 1607 | } |
| 1700 | 1608 | EXPORT_SYMBOL(denali_remove); | |
| 1701 | MODULE_DEVICE_TABLE(pci, denali_pci_ids); | ||
| 1702 | |||
| 1703 | static struct pci_driver denali_pci_driver = { | ||
| 1704 | .name = DENALI_NAND_NAME, | ||
| 1705 | .id_table = denali_pci_ids, | ||
| 1706 | .probe = denali_pci_probe, | ||
| 1707 | .remove = denali_pci_remove, | ||
| 1708 | }; | ||
| 1709 | |||
| 1710 | module_pci_driver(denali_pci_driver); | ||
diff --git a/drivers/mtd/nand/denali.h b/drivers/mtd/nand/denali.h index fabb9d56b39e..cec5712862c9 100644 --- a/drivers/mtd/nand/denali.h +++ b/drivers/mtd/nand/denali.h | |||
| @@ -466,6 +466,7 @@ struct nand_buf { | |||
| 466 | 466 | ||
| 467 | #define INTEL_CE4100 1 | 467 | #define INTEL_CE4100 1 |
| 468 | #define INTEL_MRST 2 | 468 | #define INTEL_MRST 2 |
| 469 | #define DT 3 | ||
| 469 | 470 | ||
| 470 | struct denali_nand_info { | 471 | struct denali_nand_info { |
| 471 | struct mtd_info mtd; | 472 | struct mtd_info mtd; |
| @@ -487,6 +488,7 @@ struct denali_nand_info { | |||
| 487 | uint32_t irq_status; | 488 | uint32_t irq_status; |
| 488 | int irq_debug_array[32]; | 489 | int irq_debug_array[32]; |
| 489 | int idx; | 490 | int idx; |
| 491 | int irq; | ||
| 490 | 492 | ||
| 491 | uint32_t devnum; /* represent how many nands connected */ | 493 | uint32_t devnum; /* represent how many nands connected */ |
| 492 | uint32_t fwblks; /* represent how many blocks FW used */ | 494 | uint32_t fwblks; /* represent how many blocks FW used */ |
| @@ -496,4 +498,7 @@ struct denali_nand_info { | |||
| 496 | uint32_t max_banks; | 498 | uint32_t max_banks; |
| 497 | }; | 499 | }; |
| 498 | 500 | ||
| 501 | extern int denali_init(struct denali_nand_info *denali); | ||
| 502 | extern void denali_remove(struct denali_nand_info *denali); | ||
| 503 | |||
| 499 | #endif /*_LLD_NAND_*/ | 504 | #endif /*_LLD_NAND_*/ |
diff --git a/drivers/mtd/nand/denali_dt.c b/drivers/mtd/nand/denali_dt.c new file mode 100644 index 000000000000..546f8cb5688d --- /dev/null +++ b/drivers/mtd/nand/denali_dt.c | |||
| @@ -0,0 +1,167 @@ | |||
| 1 | /* | ||
| 2 | * NAND Flash Controller Device Driver for DT | ||
| 3 | * | ||
| 4 | * Copyright © 2011, Picochip. | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify it | ||
| 7 | * under the terms and conditions of the GNU General Public License, | ||
| 8 | * version 2, as published by the Free Software Foundation. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 12 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 13 | * more details. | ||
| 14 | */ | ||
| 15 | #include <linux/clk.h> | ||
| 16 | #include <linux/err.h> | ||
| 17 | #include <linux/io.h> | ||
| 18 | #include <linux/ioport.h> | ||
| 19 | #include <linux/kernel.h> | ||
| 20 | #include <linux/module.h> | ||
| 21 | #include <linux/platform_device.h> | ||
| 22 | #include <linux/of.h> | ||
| 23 | #include <linux/of_device.h> | ||
| 24 | #include <linux/slab.h> | ||
| 25 | |||
| 26 | #include "denali.h" | ||
| 27 | |||
| 28 | struct denali_dt { | ||
| 29 | struct denali_nand_info denali; | ||
| 30 | struct clk *clk; | ||
| 31 | }; | ||
| 32 | |||
| 33 | static void __iomem *request_and_map(struct device *dev, | ||
| 34 | const struct resource *res) | ||
| 35 | { | ||
| 36 | void __iomem *ptr; | ||
| 37 | |||
| 38 | if (!devm_request_mem_region(dev, res->start, resource_size(res), | ||
| 39 | "denali-dt")) { | ||
| 40 | dev_err(dev, "unable to request %s\n", res->name); | ||
| 41 | return NULL; | ||
| 42 | } | ||
| 43 | |||
| 44 | ptr = devm_ioremap_nocache(dev, res->start, resource_size(res)); | ||
| 45 | if (!res) | ||
| 46 | dev_err(dev, "ioremap_nocache of %s failed!", res->name); | ||
| 47 | |||
| 48 | return ptr; | ||
| 49 | } | ||
| 50 | |||
| 51 | static const struct of_device_id denali_nand_dt_ids[] = { | ||
| 52 | { .compatible = "denali,denali-nand-dt" }, | ||
| 53 | { /* sentinel */ } | ||
| 54 | }; | ||
| 55 | |||
| 56 | MODULE_DEVICE_TABLE(of, denali_nand_dt_ids); | ||
| 57 | |||
| 58 | static u64 denali_dma_mask; | ||
| 59 | |||
| 60 | static int denali_dt_probe(struct platform_device *ofdev) | ||
| 61 | { | ||
| 62 | struct resource *denali_reg, *nand_data; | ||
| 63 | struct denali_dt *dt; | ||
| 64 | struct denali_nand_info *denali; | ||
| 65 | int ret; | ||
| 66 | const struct of_device_id *of_id; | ||
| 67 | |||
| 68 | of_id = of_match_device(denali_nand_dt_ids, &ofdev->dev); | ||
| 69 | if (of_id) { | ||
| 70 | ofdev->id_entry = of_id->data; | ||
| 71 | } else { | ||
| 72 | pr_err("Failed to find the right device id.\n"); | ||
| 73 | return -ENOMEM; | ||
| 74 | } | ||
| 75 | |||
| 76 | dt = devm_kzalloc(&ofdev->dev, sizeof(*dt), GFP_KERNEL); | ||
| 77 | if (!dt) | ||
| 78 | return -ENOMEM; | ||
| 79 | denali = &dt->denali; | ||
| 80 | |||
| 81 | denali_reg = platform_get_resource_byname(ofdev, IORESOURCE_MEM, "denali_reg"); | ||
| 82 | nand_data = platform_get_resource_byname(ofdev, IORESOURCE_MEM, "nand_data"); | ||
| 83 | if (!denali_reg || !nand_data) { | ||
| 84 | dev_err(&ofdev->dev, "resources not completely defined\n"); | ||
| 85 | return -EINVAL; | ||
| 86 | } | ||
| 87 | |||
| 88 | denali->platform = DT; | ||
| 89 | denali->dev = &ofdev->dev; | ||
| 90 | denali->irq = platform_get_irq(ofdev, 0); | ||
| 91 | if (denali->irq < 0) { | ||
| 92 | dev_err(&ofdev->dev, "no irq defined\n"); | ||
| 93 | return -ENXIO; | ||
| 94 | } | ||
| 95 | |||
| 96 | denali->flash_reg = request_and_map(&ofdev->dev, denali_reg); | ||
| 97 | if (!denali->flash_reg) | ||
| 98 | return -ENOMEM; | ||
| 99 | |||
| 100 | denali->flash_mem = request_and_map(&ofdev->dev, nand_data); | ||
| 101 | if (!denali->flash_mem) | ||
| 102 | return -ENOMEM; | ||
| 103 | |||
| 104 | if (!of_property_read_u32(ofdev->dev.of_node, | ||
| 105 | "dma-mask", (u32 *)&denali_dma_mask)) { | ||
| 106 | denali->dev->dma_mask = &denali_dma_mask; | ||
| 107 | } else { | ||
| 108 | denali->dev->dma_mask = NULL; | ||
| 109 | } | ||
| 110 | |||
| 111 | dt->clk = clk_get(&ofdev->dev, NULL); | ||
| 112 | if (IS_ERR(dt->clk)) { | ||
| 113 | dev_err(&ofdev->dev, "no clk available\n"); | ||
| 114 | return PTR_ERR(dt->clk); | ||
| 115 | } | ||
| 116 | clk_prepare_enable(dt->clk); | ||
| 117 | |||
| 118 | ret = denali_init(denali); | ||
| 119 | if (ret) | ||
| 120 | goto out_disable_clk; | ||
| 121 | |||
| 122 | platform_set_drvdata(ofdev, dt); | ||
| 123 | return 0; | ||
| 124 | |||
| 125 | out_disable_clk: | ||
| 126 | clk_disable_unprepare(dt->clk); | ||
| 127 | clk_put(dt->clk); | ||
| 128 | |||
| 129 | return ret; | ||
| 130 | } | ||
| 131 | |||
| 132 | static int denali_dt_remove(struct platform_device *ofdev) | ||
| 133 | { | ||
| 134 | struct denali_dt *dt = platform_get_drvdata(ofdev); | ||
| 135 | |||
| 136 | denali_remove(&dt->denali); | ||
| 137 | clk_disable(dt->clk); | ||
| 138 | clk_put(dt->clk); | ||
| 139 | |||
| 140 | return 0; | ||
| 141 | } | ||
| 142 | |||
| 143 | static struct platform_driver denali_dt_driver = { | ||
| 144 | .probe = denali_dt_probe, | ||
| 145 | .remove = denali_dt_remove, | ||
| 146 | .driver = { | ||
| 147 | .name = "denali-nand-dt", | ||
| 148 | .owner = THIS_MODULE, | ||
| 149 | .of_match_table = of_match_ptr(denali_nand_dt_ids), | ||
| 150 | }, | ||
| 151 | }; | ||
| 152 | |||
| 153 | static int __init denali_init_dt(void) | ||
| 154 | { | ||
| 155 | return platform_driver_register(&denali_dt_driver); | ||
| 156 | } | ||
| 157 | module_init(denali_init_dt); | ||
| 158 | |||
| 159 | static void __exit denali_exit_dt(void) | ||
| 160 | { | ||
| 161 | platform_driver_unregister(&denali_dt_driver); | ||
| 162 | } | ||
| 163 | module_exit(denali_exit_dt); | ||
| 164 | |||
| 165 | MODULE_LICENSE("GPL"); | ||
| 166 | MODULE_AUTHOR("Jamie Iles"); | ||
| 167 | MODULE_DESCRIPTION("DT driver for Denali NAND controller"); | ||
diff --git a/drivers/mtd/nand/denali_pci.c b/drivers/mtd/nand/denali_pci.c new file mode 100644 index 000000000000..e3e46623b2b4 --- /dev/null +++ b/drivers/mtd/nand/denali_pci.c | |||
| @@ -0,0 +1,144 @@ | |||
| 1 | /* | ||
| 2 | * NAND Flash Controller Device Driver | ||
| 3 | * Copyright © 2009-2010, Intel Corporation and its suppliers. | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms and conditions of the GNU General Public License, | ||
| 7 | * version 2, as published by the Free Software Foundation. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
| 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
| 12 | * more details. | ||
| 13 | */ | ||
| 14 | #include <linux/kernel.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/pci.h> | ||
| 17 | #include <linux/slab.h> | ||
| 18 | |||
| 19 | #include "denali.h" | ||
| 20 | |||
| 21 | #define DENALI_NAND_NAME "denali-nand-pci" | ||
| 22 | |||
| 23 | /* List of platforms this NAND controller has be integrated into */ | ||
| 24 | static DEFINE_PCI_DEVICE_TABLE(denali_pci_ids) = { | ||
| 25 | { PCI_VDEVICE(INTEL, 0x0701), INTEL_CE4100 }, | ||
| 26 | { PCI_VDEVICE(INTEL, 0x0809), INTEL_MRST }, | ||
| 27 | { /* end: all zeroes */ } | ||
| 28 | }; | ||
| 29 | MODULE_DEVICE_TABLE(pci, denali_pci_ids); | ||
| 30 | |||
| 31 | static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | ||
| 32 | { | ||
| 33 | int ret = -ENODEV; | ||
| 34 | resource_size_t csr_base, mem_base; | ||
| 35 | unsigned long csr_len, mem_len; | ||
| 36 | struct denali_nand_info *denali; | ||
| 37 | |||
| 38 | denali = kzalloc(sizeof(*denali), GFP_KERNEL); | ||
| 39 | if (!denali) | ||
| 40 | return -ENOMEM; | ||
| 41 | |||
| 42 | ret = pci_enable_device(dev); | ||
| 43 | if (ret) { | ||
| 44 | pr_err("Spectra: pci_enable_device failed.\n"); | ||
| 45 | goto failed_alloc_memery; | ||
| 46 | } | ||
| 47 | |||
| 48 | if (id->driver_data == INTEL_CE4100) { | ||
| 49 | denali->platform = INTEL_CE4100; | ||
| 50 | mem_base = pci_resource_start(dev, 0); | ||
| 51 | mem_len = pci_resource_len(dev, 1); | ||
| 52 | csr_base = pci_resource_start(dev, 1); | ||
| 53 | csr_len = pci_resource_len(dev, 1); | ||
| 54 | } else { | ||
| 55 | denali->platform = INTEL_MRST; | ||
| 56 | csr_base = pci_resource_start(dev, 0); | ||
| 57 | csr_len = pci_resource_len(dev, 0); | ||
| 58 | mem_base = pci_resource_start(dev, 1); | ||
| 59 | mem_len = pci_resource_len(dev, 1); | ||
| 60 | if (!mem_len) { | ||
| 61 | mem_base = csr_base + csr_len; | ||
| 62 | mem_len = csr_len; | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | pci_set_master(dev); | ||
| 67 | denali->dev = &dev->dev; | ||
| 68 | denali->irq = dev->irq; | ||
| 69 | |||
| 70 | ret = pci_request_regions(dev, DENALI_NAND_NAME); | ||
| 71 | if (ret) { | ||
| 72 | pr_err("Spectra: Unable to request memory regions\n"); | ||
| 73 | goto failed_enable_dev; | ||
| 74 | } | ||
| 75 | |||
| 76 | denali->flash_reg = ioremap_nocache(csr_base, csr_len); | ||
| 77 | if (!denali->flash_reg) { | ||
| 78 | pr_err("Spectra: Unable to remap memory region\n"); | ||
| 79 | ret = -ENOMEM; | ||
| 80 | goto failed_req_regions; | ||
| 81 | } | ||
| 82 | |||
| 83 | denali->flash_mem = ioremap_nocache(mem_base, mem_len); | ||
| 84 | if (!denali->flash_mem) { | ||
| 85 | pr_err("Spectra: ioremap_nocache failed!"); | ||
| 86 | ret = -ENOMEM; | ||
| 87 | goto failed_remap_reg; | ||
| 88 | } | ||
| 89 | |||
| 90 | ret = denali_init(denali); | ||
| 91 | if (ret) | ||
| 92 | goto failed_remap_mem; | ||
| 93 | |||
| 94 | pci_set_drvdata(dev, denali); | ||
| 95 | |||
| 96 | return 0; | ||
| 97 | |||
| 98 | failed_remap_mem: | ||
| 99 | iounmap(denali->flash_mem); | ||
| 100 | failed_remap_reg: | ||
| 101 | iounmap(denali->flash_reg); | ||
| 102 | failed_req_regions: | ||
| 103 | pci_release_regions(dev); | ||
| 104 | failed_enable_dev: | ||
| 105 | pci_disable_device(dev); | ||
| 106 | failed_alloc_memery: | ||
| 107 | kfree(denali); | ||
| 108 | |||
| 109 | return ret; | ||
| 110 | } | ||
| 111 | |||
| 112 | /* driver exit point */ | ||
| 113 | static void denali_pci_remove(struct pci_dev *dev) | ||
| 114 | { | ||
| 115 | struct denali_nand_info *denali = pci_get_drvdata(dev); | ||
| 116 | |||
| 117 | denali_remove(denali); | ||
| 118 | iounmap(denali->flash_reg); | ||
| 119 | iounmap(denali->flash_mem); | ||
| 120 | pci_release_regions(dev); | ||
| 121 | pci_disable_device(dev); | ||
| 122 | pci_set_drvdata(dev, NULL); | ||
| 123 | kfree(denali); | ||
| 124 | } | ||
| 125 | |||
| 126 | static struct pci_driver denali_pci_driver = { | ||
| 127 | .name = DENALI_NAND_NAME, | ||
| 128 | .id_table = denali_pci_ids, | ||
| 129 | .probe = denali_pci_probe, | ||
| 130 | .remove = denali_pci_remove, | ||
| 131 | }; | ||
| 132 | |||
| 133 | static int denali_init_pci(void) | ||
| 134 | { | ||
| 135 | pr_info("Spectra MTD driver built on %s @ %s\n", __DATE__, __TIME__); | ||
| 136 | return pci_register_driver(&denali_pci_driver); | ||
| 137 | } | ||
| 138 | module_init(denali_init_pci); | ||
| 139 | |||
| 140 | static void denali_exit_pci(void) | ||
| 141 | { | ||
| 142 | pci_unregister_driver(&denali_pci_driver); | ||
| 143 | } | ||
| 144 | module_exit(denali_exit_pci); | ||
diff --git a/drivers/mtd/nand/diskonchip.c b/drivers/mtd/nand/diskonchip.c index 256eb30f6180..81fa5784f98b 100644 --- a/drivers/mtd/nand/diskonchip.c +++ b/drivers/mtd/nand/diskonchip.c | |||
| @@ -53,8 +53,6 @@ static unsigned long __initdata doc_locations[] = { | |||
| 53 | 0xe0000, 0xe2000, 0xe4000, 0xe6000, | 53 | 0xe0000, 0xe2000, 0xe4000, 0xe6000, |
| 54 | 0xe8000, 0xea000, 0xec000, 0xee000, | 54 | 0xe8000, 0xea000, 0xec000, 0xee000, |
| 55 | #endif /* CONFIG_MTD_DOCPROBE_HIGH */ | 55 | #endif /* CONFIG_MTD_DOCPROBE_HIGH */ |
| 56 | #else | ||
| 57 | #warning Unknown architecture for DiskOnChip. No default probe locations defined | ||
| 58 | #endif | 56 | #endif |
| 59 | 0xffffffff }; | 57 | 0xffffffff }; |
| 60 | 58 | ||
diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c index 799da5d1c857..18fa4489e52e 100644 --- a/drivers/mtd/nand/docg4.c +++ b/drivers/mtd/nand/docg4.c | |||
| @@ -46,6 +46,25 @@ | |||
| 46 | #include <linux/bitrev.h> | 46 | #include <linux/bitrev.h> |
| 47 | 47 | ||
| 48 | /* | 48 | /* |
| 49 | * In "reliable mode" consecutive 2k pages are used in parallel (in some | ||
| 50 | * fashion) to store the same data. The data can be read back from the | ||
| 51 | * even-numbered pages in the normal manner; odd-numbered pages will appear to | ||
| 52 | * contain junk. Systems that boot from the docg4 typically write the secondary | ||
| 53 | * program loader (SPL) code in this mode. The SPL is loaded by the initial | ||
| 54 | * program loader (IPL, stored in the docg4's 2k NOR-like region that is mapped | ||
| 55 | * to the reset vector address). This module parameter enables you to use this | ||
| 56 | * driver to write the SPL. When in this mode, no more than 2k of data can be | ||
| 57 | * written at a time, because the addresses do not increment in the normal | ||
| 58 | * manner, and the starting offset must be within an even-numbered 2k region; | ||
| 59 | * i.e., invalid starting offsets are 0x800, 0xa00, 0xc00, 0xe00, 0x1800, | ||
| 60 | * 0x1a00, ... Reliable mode is a special case and should not be used unless | ||
| 61 | * you know what you're doing. | ||
| 62 | */ | ||
| 63 | static bool reliable_mode; | ||
| 64 | module_param(reliable_mode, bool, 0); | ||
| 65 | MODULE_PARM_DESC(reliable_mode, "pages are programmed in reliable mode"); | ||
| 66 | |||
| 67 | /* | ||
| 49 | * You'll want to ignore badblocks if you're reading a partition that contains | 68 | * You'll want to ignore badblocks if you're reading a partition that contains |
| 50 | * data written by the TrueFFS library (i.e., by PalmOS, Windows, etc), since | 69 | * data written by the TrueFFS library (i.e., by PalmOS, Windows, etc), since |
| 51 | * it does not use mtd nand's method for marking bad blocks (using oob area). | 70 | * it does not use mtd nand's method for marking bad blocks (using oob area). |
| @@ -113,6 +132,7 @@ struct docg4_priv { | |||
| 113 | #define DOCG4_SEQ_PAGEWRITE 0x16 | 132 | #define DOCG4_SEQ_PAGEWRITE 0x16 |
| 114 | #define DOCG4_SEQ_PAGEPROG 0x1e | 133 | #define DOCG4_SEQ_PAGEPROG 0x1e |
| 115 | #define DOCG4_SEQ_BLOCKERASE 0x24 | 134 | #define DOCG4_SEQ_BLOCKERASE 0x24 |
| 135 | #define DOCG4_SEQ_SETMODE 0x45 | ||
| 116 | 136 | ||
| 117 | /* DOC_FLASHCOMMAND register commands */ | 137 | /* DOC_FLASHCOMMAND register commands */ |
| 118 | #define DOCG4_CMD_PAGE_READ 0x00 | 138 | #define DOCG4_CMD_PAGE_READ 0x00 |
| @@ -122,6 +142,8 @@ struct docg4_priv { | |||
| 122 | #define DOC_CMD_PROG_BLOCK_ADDR 0x60 | 142 | #define DOC_CMD_PROG_BLOCK_ADDR 0x60 |
| 123 | #define DOCG4_CMD_PAGEWRITE 0x80 | 143 | #define DOCG4_CMD_PAGEWRITE 0x80 |
| 124 | #define DOC_CMD_PROG_CYCLE2 0x10 | 144 | #define DOC_CMD_PROG_CYCLE2 0x10 |
| 145 | #define DOCG4_CMD_FAST_MODE 0xa3 /* functionality guessed */ | ||
| 146 | #define DOC_CMD_RELIABLE_MODE 0x22 | ||
| 125 | #define DOC_CMD_RESET 0xff | 147 | #define DOC_CMD_RESET 0xff |
| 126 | 148 | ||
| 127 | /* DOC_POWERMODE register bits */ | 149 | /* DOC_POWERMODE register bits */ |
| @@ -190,17 +212,20 @@ struct docg4_priv { | |||
| 190 | #define DOCG4_T 4 /* BCH alg corrects up to 4 bit errors */ | 212 | #define DOCG4_T 4 /* BCH alg corrects up to 4 bit errors */ |
| 191 | 213 | ||
| 192 | #define DOCG4_FACTORY_BBT_PAGE 16 /* page where read-only factory bbt lives */ | 214 | #define DOCG4_FACTORY_BBT_PAGE 16 /* page where read-only factory bbt lives */ |
| 215 | #define DOCG4_REDUNDANT_BBT_PAGE 24 /* page where redundant factory bbt lives */ | ||
| 193 | 216 | ||
| 194 | /* | 217 | /* |
| 195 | * Oob bytes 0 - 6 are available to the user. | 218 | * Bytes 0, 1 are used as badblock marker. |
| 196 | * Byte 7 is hamming ecc for first 7 bytes. Bytes 8 - 14 are hw-generated ecc. | 219 | * Bytes 2 - 6 are available to the user. |
| 220 | * Byte 7 is hamming ecc for first 7 oob bytes only. | ||
| 221 | * Bytes 8 - 14 are hw-generated ecc covering entire page + oob bytes 0 - 14. | ||
| 197 | * Byte 15 (the last) is used by the driver as a "page written" flag. | 222 | * Byte 15 (the last) is used by the driver as a "page written" flag. |
| 198 | */ | 223 | */ |
| 199 | static struct nand_ecclayout docg4_oobinfo = { | 224 | static struct nand_ecclayout docg4_oobinfo = { |
| 200 | .eccbytes = 9, | 225 | .eccbytes = 9, |
| 201 | .eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15}, | 226 | .eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15}, |
| 202 | .oobavail = 7, | 227 | .oobavail = 5, |
| 203 | .oobfree = { {0, 7} } | 228 | .oobfree = { {.offset = 2, .length = 5} } |
| 204 | }; | 229 | }; |
| 205 | 230 | ||
| 206 | /* | 231 | /* |
| @@ -611,6 +636,14 @@ static void write_page_prologue(struct mtd_info *mtd, uint32_t docg4_addr) | |||
| 611 | dev_dbg(doc->dev, | 636 | dev_dbg(doc->dev, |
| 612 | "docg4: %s: g4 addr: %x\n", __func__, docg4_addr); | 637 | "docg4: %s: g4 addr: %x\n", __func__, docg4_addr); |
| 613 | sequence_reset(mtd); | 638 | sequence_reset(mtd); |
| 639 | |||
| 640 | if (unlikely(reliable_mode)) { | ||
| 641 | writew(DOCG4_SEQ_SETMODE, docptr + DOC_FLASHSEQUENCE); | ||
| 642 | writew(DOCG4_CMD_FAST_MODE, docptr + DOC_FLASHCOMMAND); | ||
| 643 | writew(DOC_CMD_RELIABLE_MODE, docptr + DOC_FLASHCOMMAND); | ||
| 644 | write_nop(docptr); | ||
| 645 | } | ||
| 646 | |||
| 614 | writew(DOCG4_SEQ_PAGEWRITE, docptr + DOC_FLASHSEQUENCE); | 647 | writew(DOCG4_SEQ_PAGEWRITE, docptr + DOC_FLASHSEQUENCE); |
| 615 | writew(DOCG4_CMD_PAGEWRITE, docptr + DOC_FLASHCOMMAND); | 648 | writew(DOCG4_CMD_PAGEWRITE, docptr + DOC_FLASHCOMMAND); |
| 616 | write_nop(docptr); | 649 | write_nop(docptr); |
| @@ -691,6 +724,15 @@ static void docg4_command(struct mtd_info *mtd, unsigned command, int column, | |||
| 691 | break; | 724 | break; |
| 692 | 725 | ||
| 693 | case NAND_CMD_SEQIN: | 726 | case NAND_CMD_SEQIN: |
| 727 | if (unlikely(reliable_mode)) { | ||
| 728 | uint16_t g4_page = g4_addr >> 16; | ||
| 729 | |||
| 730 | /* writes to odd-numbered 2k pages are invalid */ | ||
| 731 | if (g4_page & 0x01) | ||
| 732 | dev_warn(doc->dev, | ||
| 733 | "invalid reliable mode address\n"); | ||
| 734 | } | ||
| 735 | |||
| 694 | write_page_prologue(mtd, g4_addr); | 736 | write_page_prologue(mtd, g4_addr); |
| 695 | 737 | ||
| 696 | /* hack for deferred write of oob bytes */ | 738 | /* hack for deferred write of oob bytes */ |
| @@ -979,16 +1021,15 @@ static int __init read_factory_bbt(struct mtd_info *mtd) | |||
| 979 | struct docg4_priv *doc = nand->priv; | 1021 | struct docg4_priv *doc = nand->priv; |
| 980 | uint32_t g4_addr = mtd_to_docg4_address(DOCG4_FACTORY_BBT_PAGE, 0); | 1022 | uint32_t g4_addr = mtd_to_docg4_address(DOCG4_FACTORY_BBT_PAGE, 0); |
| 981 | uint8_t *buf; | 1023 | uint8_t *buf; |
| 982 | int i, block, status; | 1024 | int i, block; |
| 1025 | __u32 eccfailed_stats = mtd->ecc_stats.failed; | ||
| 983 | 1026 | ||
| 984 | buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL); | 1027 | buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL); |
| 985 | if (buf == NULL) | 1028 | if (buf == NULL) |
| 986 | return -ENOMEM; | 1029 | return -ENOMEM; |
| 987 | 1030 | ||
| 988 | read_page_prologue(mtd, g4_addr); | 1031 | read_page_prologue(mtd, g4_addr); |
| 989 | status = docg4_read_page(mtd, nand, buf, 0, DOCG4_FACTORY_BBT_PAGE); | 1032 | docg4_read_page(mtd, nand, buf, 0, DOCG4_FACTORY_BBT_PAGE); |
| 990 | if (status) | ||
| 991 | goto exit; | ||
| 992 | 1033 | ||
| 993 | /* | 1034 | /* |
| 994 | * If no memory-based bbt was created, exit. This will happen if module | 1035 | * If no memory-based bbt was created, exit. This will happen if module |
| @@ -1000,6 +1041,20 @@ static int __init read_factory_bbt(struct mtd_info *mtd) | |||
| 1000 | if (nand->bbt == NULL) /* no memory-based bbt */ | 1041 | if (nand->bbt == NULL) /* no memory-based bbt */ |
| 1001 | goto exit; | 1042 | goto exit; |
| 1002 | 1043 | ||
| 1044 | if (mtd->ecc_stats.failed > eccfailed_stats) { | ||
| 1045 | /* | ||
| 1046 | * Whoops, an ecc failure ocurred reading the factory bbt. | ||
| 1047 | * It is stored redundantly, so we get another chance. | ||
| 1048 | */ | ||
| 1049 | eccfailed_stats = mtd->ecc_stats.failed; | ||
| 1050 | docg4_read_page(mtd, nand, buf, 0, DOCG4_REDUNDANT_BBT_PAGE); | ||
| 1051 | if (mtd->ecc_stats.failed > eccfailed_stats) { | ||
| 1052 | dev_warn(doc->dev, | ||
| 1053 | "The factory bbt could not be read!\n"); | ||
| 1054 | goto exit; | ||
| 1055 | } | ||
| 1056 | } | ||
| 1057 | |||
| 1003 | /* | 1058 | /* |
| 1004 | * Parse factory bbt and update memory-based bbt. Factory bbt format is | 1059 | * Parse factory bbt and update memory-based bbt. Factory bbt format is |
| 1005 | * simple: one bit per block, block numbers increase left to right (msb | 1060 | * simple: one bit per block, block numbers increase left to right (msb |
| @@ -1019,7 +1074,7 @@ static int __init read_factory_bbt(struct mtd_info *mtd) | |||
| 1019 | } | 1074 | } |
| 1020 | exit: | 1075 | exit: |
| 1021 | kfree(buf); | 1076 | kfree(buf); |
| 1022 | return status; | 1077 | return 0; |
| 1023 | } | 1078 | } |
| 1024 | 1079 | ||
| 1025 | static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs) | 1080 | static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs) |
diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index cc1480a5e4c1..20657209a472 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c | |||
| @@ -109,20 +109,6 @@ static struct nand_ecclayout fsl_elbc_oob_lp_eccm1 = { | |||
| 109 | }; | 109 | }; |
| 110 | 110 | ||
| 111 | /* | 111 | /* |
| 112 | * fsl_elbc_oob_lp_eccm* specify that LP NAND's OOB free area starts at offset | ||
| 113 | * 1, so we have to adjust bad block pattern. This pattern should be used for | ||
| 114 | * x8 chips only. So far hardware does not support x16 chips anyway. | ||
| 115 | */ | ||
| 116 | static u8 scan_ff_pattern[] = { 0xff, }; | ||
| 117 | |||
| 118 | static struct nand_bbt_descr largepage_memorybased = { | ||
| 119 | .options = 0, | ||
| 120 | .offs = 0, | ||
| 121 | .len = 1, | ||
| 122 | .pattern = scan_ff_pattern, | ||
| 123 | }; | ||
| 124 | |||
| 125 | /* | ||
| 126 | * ELBC may use HW ECC, so that OOB offsets, that NAND core uses for bbt, | 112 | * ELBC may use HW ECC, so that OOB offsets, that NAND core uses for bbt, |
| 127 | * interfere with ECC positions, that's why we implement our own descriptors. | 113 | * interfere with ECC positions, that's why we implement our own descriptors. |
| 128 | * OOB {11, 5}, works for both SP and LP chips, with ECCM = 1 and ECCM = 0. | 114 | * OOB {11, 5}, works for both SP and LP chips, with ECCM = 1 and ECCM = 0. |
| @@ -699,7 +685,6 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) | |||
| 699 | chip->ecc.layout = (priv->fmr & FMR_ECCM) ? | 685 | chip->ecc.layout = (priv->fmr & FMR_ECCM) ? |
| 700 | &fsl_elbc_oob_lp_eccm1 : | 686 | &fsl_elbc_oob_lp_eccm1 : |
| 701 | &fsl_elbc_oob_lp_eccm0; | 687 | &fsl_elbc_oob_lp_eccm0; |
| 702 | chip->badblock_pattern = &largepage_memorybased; | ||
| 703 | } | 688 | } |
| 704 | } else { | 689 | } else { |
| 705 | dev_err(priv->dev, | 690 | dev_err(priv->dev, |
| @@ -814,7 +799,7 @@ static int fsl_elbc_chip_remove(struct fsl_elbc_mtd *priv) | |||
| 814 | 799 | ||
| 815 | static DEFINE_MUTEX(fsl_elbc_nand_mutex); | 800 | static DEFINE_MUTEX(fsl_elbc_nand_mutex); |
| 816 | 801 | ||
| 817 | static int __devinit fsl_elbc_nand_probe(struct platform_device *pdev) | 802 | static int fsl_elbc_nand_probe(struct platform_device *pdev) |
| 818 | { | 803 | { |
| 819 | struct fsl_lbc_regs __iomem *lbc; | 804 | struct fsl_lbc_regs __iomem *lbc; |
| 820 | struct fsl_elbc_mtd *priv; | 805 | struct fsl_elbc_mtd *priv; |
diff --git a/drivers/mtd/nand/fsl_ifc_nand.c b/drivers/mtd/nand/fsl_ifc_nand.c index 3551a99076ba..ad6222627fed 100644 --- a/drivers/mtd/nand/fsl_ifc_nand.c +++ b/drivers/mtd/nand/fsl_ifc_nand.c | |||
| @@ -389,7 +389,7 @@ static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command, | |||
| 389 | timing = IFC_FIR_OP_RBCD; | 389 | timing = IFC_FIR_OP_RBCD; |
| 390 | 390 | ||
| 391 | out_be32(&ifc->ifc_nand.nand_fir0, | 391 | out_be32(&ifc->ifc_nand.nand_fir0, |
| 392 | (IFC_FIR_OP_CMD0 << IFC_NAND_FIR0_OP0_SHIFT) | | 392 | (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | |
| 393 | (IFC_FIR_OP_UA << IFC_NAND_FIR0_OP1_SHIFT) | | 393 | (IFC_FIR_OP_UA << IFC_NAND_FIR0_OP1_SHIFT) | |
| 394 | (timing << IFC_NAND_FIR0_OP2_SHIFT)); | 394 | (timing << IFC_NAND_FIR0_OP2_SHIFT)); |
| 395 | out_be32(&ifc->ifc_nand.nand_fcr0, | 395 | out_be32(&ifc->ifc_nand.nand_fcr0, |
| @@ -754,7 +754,7 @@ static void fsl_ifc_sram_init(struct fsl_ifc_mtd *priv) | |||
| 754 | 754 | ||
| 755 | /* READID */ | 755 | /* READID */ |
| 756 | out_be32(&ifc->ifc_nand.nand_fir0, | 756 | out_be32(&ifc->ifc_nand.nand_fir0, |
| 757 | (IFC_FIR_OP_CMD0 << IFC_NAND_FIR0_OP0_SHIFT) | | 757 | (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | |
| 758 | (IFC_FIR_OP_UA << IFC_NAND_FIR0_OP1_SHIFT) | | 758 | (IFC_FIR_OP_UA << IFC_NAND_FIR0_OP1_SHIFT) | |
| 759 | (IFC_FIR_OP_RB << IFC_NAND_FIR0_OP2_SHIFT)); | 759 | (IFC_FIR_OP_RB << IFC_NAND_FIR0_OP2_SHIFT)); |
| 760 | out_be32(&ifc->ifc_nand.nand_fcr0, | 760 | out_be32(&ifc->ifc_nand.nand_fcr0, |
| @@ -922,7 +922,7 @@ static int match_bank(struct fsl_ifc_regs __iomem *ifc, int bank, | |||
| 922 | 922 | ||
| 923 | static DEFINE_MUTEX(fsl_ifc_nand_mutex); | 923 | static DEFINE_MUTEX(fsl_ifc_nand_mutex); |
| 924 | 924 | ||
| 925 | static int __devinit fsl_ifc_nand_probe(struct platform_device *dev) | 925 | static int fsl_ifc_nand_probe(struct platform_device *dev) |
| 926 | { | 926 | { |
| 927 | struct fsl_ifc_regs __iomem *ifc; | 927 | struct fsl_ifc_regs __iomem *ifc; |
| 928 | struct fsl_ifc_mtd *priv; | 928 | struct fsl_ifc_mtd *priv; |
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c index 45df542b9c61..5a8f5c4ce512 100644 --- a/drivers/mtd/nand/fsl_upm.c +++ b/drivers/mtd/nand/fsl_upm.c | |||
| @@ -152,7 +152,7 @@ static void fun_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | |||
| 152 | fun_wait_rnb(fun); | 152 | fun_wait_rnb(fun); |
| 153 | } | 153 | } |
| 154 | 154 | ||
| 155 | static int __devinit fun_chip_init(struct fsl_upm_nand *fun, | 155 | static int fun_chip_init(struct fsl_upm_nand *fun, |
| 156 | const struct device_node *upm_np, | 156 | const struct device_node *upm_np, |
| 157 | const struct resource *io_res) | 157 | const struct resource *io_res) |
| 158 | { | 158 | { |
| @@ -201,7 +201,7 @@ err: | |||
| 201 | return ret; | 201 | return ret; |
| 202 | } | 202 | } |
| 203 | 203 | ||
| 204 | static int __devinit fun_probe(struct platform_device *ofdev) | 204 | static int fun_probe(struct platform_device *ofdev) |
| 205 | { | 205 | { |
| 206 | struct fsl_upm_nand *fun; | 206 | struct fsl_upm_nand *fun; |
| 207 | struct resource io_res; | 207 | struct resource io_res; |
| @@ -318,7 +318,7 @@ err1: | |||
| 318 | return ret; | 318 | return ret; |
| 319 | } | 319 | } |
| 320 | 320 | ||
| 321 | static int __devexit fun_remove(struct platform_device *ofdev) | 321 | static int fun_remove(struct platform_device *ofdev) |
| 322 | { | 322 | { |
| 323 | struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev); | 323 | struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev); |
| 324 | int i; | 324 | int i; |
| @@ -350,7 +350,7 @@ static struct platform_driver of_fun_driver = { | |||
| 350 | .of_match_table = of_fun_match, | 350 | .of_match_table = of_fun_match, |
| 351 | }, | 351 | }, |
| 352 | .probe = fun_probe, | 352 | .probe = fun_probe, |
| 353 | .remove = __devexit_p(fun_remove), | 353 | .remove = fun_remove, |
| 354 | }; | 354 | }; |
| 355 | 355 | ||
| 356 | module_platform_driver(of_fun_driver); | 356 | module_platform_driver(of_fun_driver); |
diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 38d26240d8b1..1d7446434b0e 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c | |||
| @@ -361,7 +361,7 @@ static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | |||
| 361 | struct nand_chip *this = mtd->priv; | 361 | struct nand_chip *this = mtd->priv; |
| 362 | struct fsmc_nand_data *host = container_of(mtd, | 362 | struct fsmc_nand_data *host = container_of(mtd, |
| 363 | struct fsmc_nand_data, mtd); | 363 | struct fsmc_nand_data, mtd); |
| 364 | void *__iomem *regs = host->regs_va; | 364 | void __iomem *regs = host->regs_va; |
| 365 | unsigned int bank = host->bank; | 365 | unsigned int bank = host->bank; |
| 366 | 366 | ||
| 367 | if (ctrl & NAND_CTRL_CHANGE) { | 367 | if (ctrl & NAND_CTRL_CHANGE) { |
| @@ -383,13 +383,13 @@ static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | |||
| 383 | pc |= FSMC_ENABLE; | 383 | pc |= FSMC_ENABLE; |
| 384 | else | 384 | else |
| 385 | pc &= ~FSMC_ENABLE; | 385 | pc &= ~FSMC_ENABLE; |
| 386 | writel(pc, FSMC_NAND_REG(regs, bank, PC)); | 386 | writel_relaxed(pc, FSMC_NAND_REG(regs, bank, PC)); |
| 387 | } | 387 | } |
| 388 | 388 | ||
| 389 | mb(); | 389 | mb(); |
| 390 | 390 | ||
| 391 | if (cmd != NAND_CMD_NONE) | 391 | if (cmd != NAND_CMD_NONE) |
| 392 | writeb(cmd, this->IO_ADDR_W); | 392 | writeb_relaxed(cmd, this->IO_ADDR_W); |
| 393 | } | 393 | } |
| 394 | 394 | ||
| 395 | /* | 395 | /* |
| @@ -426,14 +426,18 @@ static void fsmc_nand_setup(void __iomem *regs, uint32_t bank, | |||
| 426 | tset = (tims->tset & FSMC_TSET_MASK) << FSMC_TSET_SHIFT; | 426 | tset = (tims->tset & FSMC_TSET_MASK) << FSMC_TSET_SHIFT; |
| 427 | 427 | ||
| 428 | if (busw) | 428 | if (busw) |
| 429 | writel(value | FSMC_DEVWID_16, FSMC_NAND_REG(regs, bank, PC)); | 429 | writel_relaxed(value | FSMC_DEVWID_16, |
| 430 | FSMC_NAND_REG(regs, bank, PC)); | ||
| 430 | else | 431 | else |
| 431 | writel(value | FSMC_DEVWID_8, FSMC_NAND_REG(regs, bank, PC)); | 432 | writel_relaxed(value | FSMC_DEVWID_8, |
| 433 | FSMC_NAND_REG(regs, bank, PC)); | ||
| 432 | 434 | ||
| 433 | writel(readl(FSMC_NAND_REG(regs, bank, PC)) | tclr | tar, | 435 | writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) | tclr | tar, |
| 434 | FSMC_NAND_REG(regs, bank, PC)); | 436 | FSMC_NAND_REG(regs, bank, PC)); |
| 435 | writel(thiz | thold | twait | tset, FSMC_NAND_REG(regs, bank, COMM)); | 437 | writel_relaxed(thiz | thold | twait | tset, |
| 436 | writel(thiz | thold | twait | tset, FSMC_NAND_REG(regs, bank, ATTRIB)); | 438 | FSMC_NAND_REG(regs, bank, COMM)); |
| 439 | writel_relaxed(thiz | thold | twait | tset, | ||
| 440 | FSMC_NAND_REG(regs, bank, ATTRIB)); | ||
| 437 | } | 441 | } |
| 438 | 442 | ||
| 439 | /* | 443 | /* |
| @@ -446,11 +450,11 @@ static void fsmc_enable_hwecc(struct mtd_info *mtd, int mode) | |||
| 446 | void __iomem *regs = host->regs_va; | 450 | void __iomem *regs = host->regs_va; |
| 447 | uint32_t bank = host->bank; | 451 | uint32_t bank = host->bank; |
| 448 | 452 | ||
| 449 | writel(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCPLEN_256, | 453 | writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCPLEN_256, |
| 450 | FSMC_NAND_REG(regs, bank, PC)); | 454 | FSMC_NAND_REG(regs, bank, PC)); |
| 451 | writel(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCEN, | 455 | writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCEN, |
| 452 | FSMC_NAND_REG(regs, bank, PC)); | 456 | FSMC_NAND_REG(regs, bank, PC)); |
| 453 | writel(readl(FSMC_NAND_REG(regs, bank, PC)) | FSMC_ECCEN, | 457 | writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) | FSMC_ECCEN, |
| 454 | FSMC_NAND_REG(regs, bank, PC)); | 458 | FSMC_NAND_REG(regs, bank, PC)); |
| 455 | } | 459 | } |
| 456 | 460 | ||
| @@ -470,7 +474,7 @@ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data, | |||
| 470 | unsigned long deadline = jiffies + FSMC_BUSY_WAIT_TIMEOUT; | 474 | unsigned long deadline = jiffies + FSMC_BUSY_WAIT_TIMEOUT; |
| 471 | 475 | ||
| 472 | do { | 476 | do { |
| 473 | if (readl(FSMC_NAND_REG(regs, bank, STS)) & FSMC_CODE_RDY) | 477 | if (readl_relaxed(FSMC_NAND_REG(regs, bank, STS)) & FSMC_CODE_RDY) |
| 474 | break; | 478 | break; |
| 475 | else | 479 | else |
| 476 | cond_resched(); | 480 | cond_resched(); |
| @@ -481,25 +485,25 @@ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data, | |||
| 481 | return -ETIMEDOUT; | 485 | return -ETIMEDOUT; |
| 482 | } | 486 | } |
| 483 | 487 | ||
| 484 | ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC1)); | 488 | ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1)); |
| 485 | ecc[0] = (uint8_t) (ecc_tmp >> 0); | 489 | ecc[0] = (uint8_t) (ecc_tmp >> 0); |
| 486 | ecc[1] = (uint8_t) (ecc_tmp >> 8); | 490 | ecc[1] = (uint8_t) (ecc_tmp >> 8); |
| 487 | ecc[2] = (uint8_t) (ecc_tmp >> 16); | 491 | ecc[2] = (uint8_t) (ecc_tmp >> 16); |
| 488 | ecc[3] = (uint8_t) (ecc_tmp >> 24); | 492 | ecc[3] = (uint8_t) (ecc_tmp >> 24); |
| 489 | 493 | ||
| 490 | ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC2)); | 494 | ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC2)); |
| 491 | ecc[4] = (uint8_t) (ecc_tmp >> 0); | 495 | ecc[4] = (uint8_t) (ecc_tmp >> 0); |
| 492 | ecc[5] = (uint8_t) (ecc_tmp >> 8); | 496 | ecc[5] = (uint8_t) (ecc_tmp >> 8); |
| 493 | ecc[6] = (uint8_t) (ecc_tmp >> 16); | 497 | ecc[6] = (uint8_t) (ecc_tmp >> 16); |
| 494 | ecc[7] = (uint8_t) (ecc_tmp >> 24); | 498 | ecc[7] = (uint8_t) (ecc_tmp >> 24); |
| 495 | 499 | ||
| 496 | ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC3)); | 500 | ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC3)); |
| 497 | ecc[8] = (uint8_t) (ecc_tmp >> 0); | 501 | ecc[8] = (uint8_t) (ecc_tmp >> 0); |
| 498 | ecc[9] = (uint8_t) (ecc_tmp >> 8); | 502 | ecc[9] = (uint8_t) (ecc_tmp >> 8); |
| 499 | ecc[10] = (uint8_t) (ecc_tmp >> 16); | 503 | ecc[10] = (uint8_t) (ecc_tmp >> 16); |
| 500 | ecc[11] = (uint8_t) (ecc_tmp >> 24); | 504 | ecc[11] = (uint8_t) (ecc_tmp >> 24); |
| 501 | 505 | ||
| 502 | ecc_tmp = readl(FSMC_NAND_REG(regs, bank, STS)); | 506 | ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, STS)); |
| 503 | ecc[12] = (uint8_t) (ecc_tmp >> 16); | 507 | ecc[12] = (uint8_t) (ecc_tmp >> 16); |
| 504 | 508 | ||
| 505 | return 0; | 509 | return 0; |
| @@ -519,7 +523,7 @@ static int fsmc_read_hwecc_ecc1(struct mtd_info *mtd, const uint8_t *data, | |||
| 519 | uint32_t bank = host->bank; | 523 | uint32_t bank = host->bank; |
| 520 | uint32_t ecc_tmp; | 524 | uint32_t ecc_tmp; |
| 521 | 525 | ||
| 522 | ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC1)); | 526 | ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1)); |
| 523 | ecc[0] = (uint8_t) (ecc_tmp >> 0); | 527 | ecc[0] = (uint8_t) (ecc_tmp >> 0); |
| 524 | ecc[1] = (uint8_t) (ecc_tmp >> 8); | 528 | ecc[1] = (uint8_t) (ecc_tmp >> 8); |
| 525 | ecc[2] = (uint8_t) (ecc_tmp >> 16); | 529 | ecc[2] = (uint8_t) (ecc_tmp >> 16); |
| @@ -601,7 +605,7 @@ static int dma_xfer(struct fsmc_nand_data *host, void *buffer, int len, | |||
| 601 | dma_async_issue_pending(chan); | 605 | dma_async_issue_pending(chan); |
| 602 | 606 | ||
| 603 | ret = | 607 | ret = |
| 604 | wait_for_completion_interruptible_timeout(&host->dma_access_complete, | 608 | wait_for_completion_timeout(&host->dma_access_complete, |
| 605 | msecs_to_jiffies(3000)); | 609 | msecs_to_jiffies(3000)); |
| 606 | if (ret <= 0) { | 610 | if (ret <= 0) { |
| 607 | chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); | 611 | chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); |
| @@ -628,10 +632,10 @@ static void fsmc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | |||
| 628 | uint32_t *p = (uint32_t *)buf; | 632 | uint32_t *p = (uint32_t *)buf; |
| 629 | len = len >> 2; | 633 | len = len >> 2; |
| 630 | for (i = 0; i < len; i++) | 634 | for (i = 0; i < len; i++) |
| 631 | writel(p[i], chip->IO_ADDR_W); | 635 | writel_relaxed(p[i], chip->IO_ADDR_W); |
| 632 | } else { | 636 | } else { |
| 633 | for (i = 0; i < len; i++) | 637 | for (i = 0; i < len; i++) |
| 634 | writeb(buf[i], chip->IO_ADDR_W); | 638 | writeb_relaxed(buf[i], chip->IO_ADDR_W); |
| 635 | } | 639 | } |
| 636 | } | 640 | } |
| 637 | 641 | ||
| @@ -651,10 +655,10 @@ static void fsmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | |||
| 651 | uint32_t *p = (uint32_t *)buf; | 655 | uint32_t *p = (uint32_t *)buf; |
| 652 | len = len >> 2; | 656 | len = len >> 2; |
| 653 | for (i = 0; i < len; i++) | 657 | for (i = 0; i < len; i++) |
| 654 | p[i] = readl(chip->IO_ADDR_R); | 658 | p[i] = readl_relaxed(chip->IO_ADDR_R); |
| 655 | } else { | 659 | } else { |
| 656 | for (i = 0; i < len; i++) | 660 | for (i = 0; i < len; i++) |
| 657 | buf[i] = readb(chip->IO_ADDR_R); | 661 | buf[i] = readb_relaxed(chip->IO_ADDR_R); |
| 658 | } | 662 | } |
| 659 | } | 663 | } |
| 660 | 664 | ||
| @@ -783,7 +787,7 @@ static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat, | |||
| 783 | uint32_t num_err, i; | 787 | uint32_t num_err, i; |
| 784 | uint32_t ecc1, ecc2, ecc3, ecc4; | 788 | uint32_t ecc1, ecc2, ecc3, ecc4; |
| 785 | 789 | ||
| 786 | num_err = (readl(FSMC_NAND_REG(regs, bank, STS)) >> 10) & 0xF; | 790 | num_err = (readl_relaxed(FSMC_NAND_REG(regs, bank, STS)) >> 10) & 0xF; |
| 787 | 791 | ||
| 788 | /* no bit flipping */ | 792 | /* no bit flipping */ |
| 789 | if (likely(num_err == 0)) | 793 | if (likely(num_err == 0)) |
| @@ -826,10 +830,10 @@ static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat, | |||
| 826 | * uint64_t array and error offset indexes are populated in err_idx | 830 | * uint64_t array and error offset indexes are populated in err_idx |
| 827 | * array | 831 | * array |
| 828 | */ | 832 | */ |
| 829 | ecc1 = readl(FSMC_NAND_REG(regs, bank, ECC1)); | 833 | ecc1 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1)); |
| 830 | ecc2 = readl(FSMC_NAND_REG(regs, bank, ECC2)); | 834 | ecc2 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC2)); |
| 831 | ecc3 = readl(FSMC_NAND_REG(regs, bank, ECC3)); | 835 | ecc3 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC3)); |
| 832 | ecc4 = readl(FSMC_NAND_REG(regs, bank, STS)); | 836 | ecc4 = readl_relaxed(FSMC_NAND_REG(regs, bank, STS)); |
| 833 | 837 | ||
| 834 | err_idx[0] = (ecc1 >> 0) & 0x1FFF; | 838 | err_idx[0] = (ecc1 >> 0) & 0x1FFF; |
| 835 | err_idx[1] = (ecc1 >> 13) & 0x1FFF; | 839 | err_idx[1] = (ecc1 >> 13) & 0x1FFF; |
| @@ -860,7 +864,7 @@ static bool filter(struct dma_chan *chan, void *slave) | |||
| 860 | } | 864 | } |
| 861 | 865 | ||
| 862 | #ifdef CONFIG_OF | 866 | #ifdef CONFIG_OF |
| 863 | static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev, | 867 | static int fsmc_nand_probe_config_dt(struct platform_device *pdev, |
| 864 | struct device_node *np) | 868 | struct device_node *np) |
| 865 | { | 869 | { |
| 866 | struct fsmc_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); | 870 | struct fsmc_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); |
| @@ -876,15 +880,13 @@ static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev, | |||
| 876 | return -EINVAL; | 880 | return -EINVAL; |
| 877 | } | 881 | } |
| 878 | } | 882 | } |
| 879 | of_property_read_u32(np, "st,ale-off", &pdata->ale_off); | ||
| 880 | of_property_read_u32(np, "st,cle-off", &pdata->cle_off); | ||
| 881 | if (of_get_property(np, "nand-skip-bbtscan", NULL)) | 883 | if (of_get_property(np, "nand-skip-bbtscan", NULL)) |
| 882 | pdata->options = NAND_SKIP_BBTSCAN; | 884 | pdata->options = NAND_SKIP_BBTSCAN; |
| 883 | 885 | ||
| 884 | return 0; | 886 | return 0; |
| 885 | } | 887 | } |
| 886 | #else | 888 | #else |
| 887 | static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev, | 889 | static int fsmc_nand_probe_config_dt(struct platform_device *pdev, |
| 888 | struct device_node *np) | 890 | struct device_node *np) |
| 889 | { | 891 | { |
| 890 | return -ENOSYS; | 892 | return -ENOSYS; |
| @@ -935,41 +937,28 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
| 935 | if (!res) | 937 | if (!res) |
| 936 | return -EINVAL; | 938 | return -EINVAL; |
| 937 | 939 | ||
| 938 | if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res), | 940 | host->data_va = devm_request_and_ioremap(&pdev->dev, res); |
| 939 | pdev->name)) { | ||
| 940 | dev_err(&pdev->dev, "Failed to get memory data resourse\n"); | ||
| 941 | return -ENOENT; | ||
| 942 | } | ||
| 943 | |||
| 944 | host->data_pa = (dma_addr_t)res->start; | ||
| 945 | host->data_va = devm_ioremap(&pdev->dev, res->start, | ||
| 946 | resource_size(res)); | ||
| 947 | if (!host->data_va) { | 941 | if (!host->data_va) { |
| 948 | dev_err(&pdev->dev, "data ioremap failed\n"); | 942 | dev_err(&pdev->dev, "data ioremap failed\n"); |
| 949 | return -ENOMEM; | 943 | return -ENOMEM; |
| 950 | } | 944 | } |
| 945 | host->data_pa = (dma_addr_t)res->start; | ||
| 951 | 946 | ||
| 952 | if (!devm_request_mem_region(&pdev->dev, res->start + pdata->ale_off, | 947 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_addr"); |
| 953 | resource_size(res), pdev->name)) { | 948 | if (!res) |
| 954 | dev_err(&pdev->dev, "Failed to get memory ale resourse\n"); | 949 | return -EINVAL; |
| 955 | return -ENOENT; | ||
| 956 | } | ||
| 957 | 950 | ||
| 958 | host->addr_va = devm_ioremap(&pdev->dev, res->start + pdata->ale_off, | 951 | host->addr_va = devm_request_and_ioremap(&pdev->dev, res); |
| 959 | resource_size(res)); | ||
| 960 | if (!host->addr_va) { | 952 | if (!host->addr_va) { |
| 961 | dev_err(&pdev->dev, "ale ioremap failed\n"); | 953 | dev_err(&pdev->dev, "ale ioremap failed\n"); |
| 962 | return -ENOMEM; | 954 | return -ENOMEM; |
| 963 | } | 955 | } |
| 964 | 956 | ||
| 965 | if (!devm_request_mem_region(&pdev->dev, res->start + pdata->cle_off, | 957 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_cmd"); |
| 966 | resource_size(res), pdev->name)) { | 958 | if (!res) |
| 967 | dev_err(&pdev->dev, "Failed to get memory cle resourse\n"); | 959 | return -EINVAL; |
| 968 | return -ENOENT; | ||
| 969 | } | ||
| 970 | 960 | ||
| 971 | host->cmd_va = devm_ioremap(&pdev->dev, res->start + pdata->cle_off, | 961 | host->cmd_va = devm_request_and_ioremap(&pdev->dev, res); |
| 972 | resource_size(res)); | ||
| 973 | if (!host->cmd_va) { | 962 | if (!host->cmd_va) { |
| 974 | dev_err(&pdev->dev, "ale ioremap failed\n"); | 963 | dev_err(&pdev->dev, "ale ioremap failed\n"); |
| 975 | return -ENOMEM; | 964 | return -ENOMEM; |
| @@ -979,14 +968,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) | |||
| 979 | if (!res) | 968 | if (!res) |
| 980 | return -EINVAL; | 969 | return -EINVAL; |
| 981 | 970 | ||
| 982 | if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res), | 971 | host->regs_va = devm_request_and_ioremap(&pdev->dev, res); |
| 983 | pdev->name)) { | ||
| 984 | dev_err(&pdev->dev, "Failed to get memory regs resourse\n"); | ||
| 985 | return -ENOENT; | ||
| 986 | } | ||
| 987 | |||
| 988 | host->regs_va = devm_ioremap(&pdev->dev, res->start, | ||
| 989 | resource_size(res)); | ||
| 990 | if (!host->regs_va) { | 972 | if (!host->regs_va) { |
| 991 | dev_err(&pdev->dev, "regs ioremap failed\n"); | 973 | dev_err(&pdev->dev, "regs ioremap failed\n"); |
| 992 | return -ENOMEM; | 974 | return -ENOMEM; |
diff --git a/drivers/mtd/nand/gpio.c b/drivers/mtd/nand/gpio.c index bc73bc5f2713..e789e3f51710 100644 --- a/drivers/mtd/nand/gpio.c +++ b/drivers/mtd/nand/gpio.c | |||
| @@ -90,14 +90,14 @@ static void gpio_nand_writebuf(struct mtd_info *mtd, const u_char *buf, int len) | |||
| 90 | { | 90 | { |
| 91 | struct nand_chip *this = mtd->priv; | 91 | struct nand_chip *this = mtd->priv; |
| 92 | 92 | ||
| 93 | writesb(this->IO_ADDR_W, buf, len); | 93 | iowrite8_rep(this->IO_ADDR_W, buf, len); |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | static void gpio_nand_readbuf(struct mtd_info *mtd, u_char *buf, int len) | 96 | static void gpio_nand_readbuf(struct mtd_info *mtd, u_char *buf, int len) |
| 97 | { | 97 | { |
| 98 | struct nand_chip *this = mtd->priv; | 98 | struct nand_chip *this = mtd->priv; |
| 99 | 99 | ||
| 100 | readsb(this->IO_ADDR_R, buf, len); | 100 | ioread8_rep(this->IO_ADDR_R, buf, len); |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | static void gpio_nand_writebuf16(struct mtd_info *mtd, const u_char *buf, | 103 | static void gpio_nand_writebuf16(struct mtd_info *mtd, const u_char *buf, |
| @@ -106,7 +106,7 @@ static void gpio_nand_writebuf16(struct mtd_info *mtd, const u_char *buf, | |||
| 106 | struct nand_chip *this = mtd->priv; | 106 | struct nand_chip *this = mtd->priv; |
| 107 | 107 | ||
| 108 | if (IS_ALIGNED((unsigned long)buf, 2)) { | 108 | if (IS_ALIGNED((unsigned long)buf, 2)) { |
| 109 | writesw(this->IO_ADDR_W, buf, len>>1); | 109 | iowrite16_rep(this->IO_ADDR_W, buf, len>>1); |
| 110 | } else { | 110 | } else { |
| 111 | int i; | 111 | int i; |
| 112 | unsigned short *ptr = (unsigned short *)buf; | 112 | unsigned short *ptr = (unsigned short *)buf; |
| @@ -121,7 +121,7 @@ static void gpio_nand_readbuf16(struct mtd_info *mtd, u_char *buf, int len) | |||
| 121 | struct nand_chip *this = mtd->priv; | 121 | struct nand_chip *this = mtd->priv; |
| 122 | 122 | ||
| 123 | if (IS_ALIGNED((unsigned long)buf, 2)) { | 123 | if (IS_ALIGNED((unsigned long)buf, 2)) { |
| 124 | readsw(this->IO_ADDR_R, buf, len>>1); | 124 | ioread16_rep(this->IO_ADDR_R, buf, len>>1); |
| 125 | } else { | 125 | } else { |
| 126 | int i; | 126 | int i; |
| 127 | unsigned short *ptr = (unsigned short *)buf; | 127 | unsigned short *ptr = (unsigned short *)buf; |
| @@ -134,7 +134,11 @@ static void gpio_nand_readbuf16(struct mtd_info *mtd, u_char *buf, int len) | |||
| 134 | static int gpio_nand_devready(struct mtd_info *mtd) | 134 | static int gpio_nand_devready(struct mtd_info *mtd) |
| 135 | { | 135 | { |
| 136 | struct gpiomtd *gpiomtd = gpio_nand_getpriv(mtd); | 136 | struct gpiomtd *gpiomtd = gpio_nand_getpriv(mtd); |
| 137 | return gpio_get_value(gpiomtd->plat.gpio_rdy); | 137 | |
| 138 | if (gpio_is_valid(gpiomtd->plat.gpio_rdy)) | ||
| 139 | return gpio_get_value(gpiomtd->plat.gpio_rdy); | ||
| 140 | |||
| 141 | return 1; | ||
| 138 | } | 142 | } |
| 139 | 143 | ||
| 140 | #ifdef CONFIG_OF | 144 | #ifdef CONFIG_OF |
| @@ -227,7 +231,7 @@ gpio_nand_get_io_sync(struct platform_device *pdev) | |||
| 227 | return platform_get_resource(pdev, IORESOURCE_MEM, 1); | 231 | return platform_get_resource(pdev, IORESOURCE_MEM, 1); |
| 228 | } | 232 | } |
| 229 | 233 | ||
| 230 | static int __devexit gpio_nand_remove(struct platform_device *dev) | 234 | static int gpio_nand_remove(struct platform_device *dev) |
| 231 | { | 235 | { |
| 232 | struct gpiomtd *gpiomtd = platform_get_drvdata(dev); | 236 | struct gpiomtd *gpiomtd = platform_get_drvdata(dev); |
| 233 | struct resource *res; | 237 | struct resource *res; |
| @@ -252,7 +256,8 @@ static int __devexit gpio_nand_remove(struct platform_device *dev) | |||
| 252 | gpio_free(gpiomtd->plat.gpio_nce); | 256 | gpio_free(gpiomtd->plat.gpio_nce); |
| 253 | if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) | 257 | if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) |
| 254 | gpio_free(gpiomtd->plat.gpio_nwp); | 258 | gpio_free(gpiomtd->plat.gpio_nwp); |
| 255 | gpio_free(gpiomtd->plat.gpio_rdy); | 259 | if (gpio_is_valid(gpiomtd->plat.gpio_rdy)) |
| 260 | gpio_free(gpiomtd->plat.gpio_rdy); | ||
| 256 | 261 | ||
| 257 | kfree(gpiomtd); | 262 | kfree(gpiomtd); |
| 258 | 263 | ||
| @@ -277,7 +282,7 @@ static void __iomem *request_and_remap(struct resource *res, size_t size, | |||
| 277 | return ptr; | 282 | return ptr; |
| 278 | } | 283 | } |
| 279 | 284 | ||
| 280 | static int __devinit gpio_nand_probe(struct platform_device *dev) | 285 | static int gpio_nand_probe(struct platform_device *dev) |
| 281 | { | 286 | { |
| 282 | struct gpiomtd *gpiomtd; | 287 | struct gpiomtd *gpiomtd; |
| 283 | struct nand_chip *this; | 288 | struct nand_chip *this; |
| @@ -336,10 +341,12 @@ static int __devinit gpio_nand_probe(struct platform_device *dev) | |||
| 336 | if (ret) | 341 | if (ret) |
| 337 | goto err_cle; | 342 | goto err_cle; |
| 338 | gpio_direction_output(gpiomtd->plat.gpio_cle, 0); | 343 | gpio_direction_output(gpiomtd->plat.gpio_cle, 0); |
| 339 | ret = gpio_request(gpiomtd->plat.gpio_rdy, "NAND RDY"); | 344 | if (gpio_is_valid(gpiomtd->plat.gpio_rdy)) { |
| 340 | if (ret) | 345 | ret = gpio_request(gpiomtd->plat.gpio_rdy, "NAND RDY"); |
| 341 | goto err_rdy; | 346 | if (ret) |
| 342 | gpio_direction_input(gpiomtd->plat.gpio_rdy); | 347 | goto err_rdy; |
| 348 | gpio_direction_input(gpiomtd->plat.gpio_rdy); | ||
| 349 | } | ||
| 343 | 350 | ||
| 344 | 351 | ||
| 345 | this->IO_ADDR_W = this->IO_ADDR_R; | 352 | this->IO_ADDR_W = this->IO_ADDR_R; |
| @@ -386,7 +393,8 @@ static int __devinit gpio_nand_probe(struct platform_device *dev) | |||
| 386 | err_wp: | 393 | err_wp: |
| 387 | if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) | 394 | if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) |
| 388 | gpio_set_value(gpiomtd->plat.gpio_nwp, 0); | 395 | gpio_set_value(gpiomtd->plat.gpio_nwp, 0); |
| 389 | gpio_free(gpiomtd->plat.gpio_rdy); | 396 | if (gpio_is_valid(gpiomtd->plat.gpio_rdy)) |
| 397 | gpio_free(gpiomtd->plat.gpio_rdy); | ||
| 390 | err_rdy: | 398 | err_rdy: |
| 391 | gpio_free(gpiomtd->plat.gpio_cle); | 399 | gpio_free(gpiomtd->plat.gpio_cle); |
| 392 | err_cle: | 400 | err_cle: |
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c index 3502accd4bc3..d84699c7968e 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c | |||
| @@ -18,7 +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 | #include <linux/mtd/gpmi-nand.h> | ||
| 22 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
| 23 | #include <linux/clk.h> | 22 | #include <linux/clk.h> |
| 24 | 23 | ||
| @@ -166,6 +165,15 @@ int gpmi_init(struct gpmi_nand_data *this) | |||
| 166 | if (ret) | 165 | if (ret) |
| 167 | goto err_out; | 166 | goto err_out; |
| 168 | 167 | ||
| 168 | /* | ||
| 169 | * Reset BCH here, too. We got failures otherwise :( | ||
| 170 | * See later BCH reset for explanation of MX23 handling | ||
| 171 | */ | ||
| 172 | ret = gpmi_reset_block(r->bch_regs, GPMI_IS_MX23(this)); | ||
| 173 | if (ret) | ||
| 174 | goto err_out; | ||
| 175 | |||
| 176 | |||
| 169 | /* Choose NAND mode. */ | 177 | /* Choose NAND mode. */ |
| 170 | writel(BM_GPMI_CTRL1_GPMI_MODE, r->gpmi_regs + HW_GPMI_CTRL1_CLR); | 178 | writel(BM_GPMI_CTRL1_GPMI_MODE, r->gpmi_regs + HW_GPMI_CTRL1_CLR); |
| 171 | 179 | ||
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index d79696b2f19b..5cd141f7bfc2 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c | |||
| @@ -25,7 +25,6 @@ | |||
| 25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
| 26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
| 27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| 28 | #include <linux/mtd/gpmi-nand.h> | ||
| 29 | #include <linux/mtd/partitions.h> | 28 | #include <linux/mtd/partitions.h> |
| 30 | #include <linux/pinctrl/consumer.h> | 29 | #include <linux/pinctrl/consumer.h> |
| 31 | #include <linux/of.h> | 30 | #include <linux/of.h> |
| @@ -33,6 +32,12 @@ | |||
| 33 | #include <linux/of_mtd.h> | 32 | #include <linux/of_mtd.h> |
| 34 | #include "gpmi-nand.h" | 33 | #include "gpmi-nand.h" |
| 35 | 34 | ||
| 35 | /* Resource names for the GPMI NAND driver. */ | ||
| 36 | #define GPMI_NAND_GPMI_REGS_ADDR_RES_NAME "gpmi-nand" | ||
| 37 | #define GPMI_NAND_BCH_REGS_ADDR_RES_NAME "bch" | ||
| 38 | #define GPMI_NAND_BCH_INTERRUPT_RES_NAME "bch" | ||
| 39 | #define GPMI_NAND_DMA_INTERRUPT_RES_NAME "gpmi-dma" | ||
| 40 | |||
| 36 | /* add our owner bbt descriptor */ | 41 | /* add our owner bbt descriptor */ |
| 37 | static uint8_t scan_ff_pattern[] = { 0xff }; | 42 | static uint8_t scan_ff_pattern[] = { 0xff }; |
| 38 | static struct nand_bbt_descr gpmi_bbt_descr = { | 43 | static struct nand_bbt_descr gpmi_bbt_descr = { |
| @@ -222,7 +227,7 @@ void prepare_data_dma(struct gpmi_nand_data *this, enum dma_data_direction dr) | |||
| 222 | 227 | ||
| 223 | ret = dma_map_sg(this->dev, sgl, 1, dr); | 228 | ret = dma_map_sg(this->dev, sgl, 1, dr); |
| 224 | if (ret == 0) | 229 | if (ret == 0) |
| 225 | pr_err("map failed.\n"); | 230 | pr_err("DMA mapping failed.\n"); |
| 226 | 231 | ||
| 227 | this->direct_dma_map_ok = false; | 232 | this->direct_dma_map_ok = false; |
| 228 | } | 233 | } |
| @@ -314,7 +319,7 @@ int start_dma_with_bch_irq(struct gpmi_nand_data *this, | |||
| 314 | return 0; | 319 | return 0; |
| 315 | } | 320 | } |
| 316 | 321 | ||
| 317 | static int __devinit | 322 | static int |
| 318 | acquire_register_block(struct gpmi_nand_data *this, const char *res_name) | 323 | acquire_register_block(struct gpmi_nand_data *this, const char *res_name) |
| 319 | { | 324 | { |
| 320 | struct platform_device *pdev = this->pdev; | 325 | struct platform_device *pdev = this->pdev; |
| @@ -355,7 +360,7 @@ static void release_register_block(struct gpmi_nand_data *this) | |||
| 355 | res->bch_regs = NULL; | 360 | res->bch_regs = NULL; |
| 356 | } | 361 | } |
| 357 | 362 | ||
| 358 | static int __devinit | 363 | static int |
| 359 | acquire_bch_irq(struct gpmi_nand_data *this, irq_handler_t irq_h) | 364 | acquire_bch_irq(struct gpmi_nand_data *this, irq_handler_t irq_h) |
| 360 | { | 365 | { |
| 361 | struct platform_device *pdev = this->pdev; | 366 | struct platform_device *pdev = this->pdev; |
| @@ -422,7 +427,7 @@ static void release_dma_channels(struct gpmi_nand_data *this) | |||
| 422 | } | 427 | } |
| 423 | } | 428 | } |
| 424 | 429 | ||
| 425 | static int __devinit acquire_dma_channels(struct gpmi_nand_data *this) | 430 | static int acquire_dma_channels(struct gpmi_nand_data *this) |
| 426 | { | 431 | { |
| 427 | struct platform_device *pdev = this->pdev; | 432 | struct platform_device *pdev = this->pdev; |
| 428 | struct resource *r_dma; | 433 | struct resource *r_dma; |
| @@ -456,7 +461,7 @@ static int __devinit acquire_dma_channels(struct gpmi_nand_data *this) | |||
| 456 | 461 | ||
| 457 | dma_chan = dma_request_channel(mask, gpmi_dma_filter, this); | 462 | dma_chan = dma_request_channel(mask, gpmi_dma_filter, this); |
| 458 | if (!dma_chan) { | 463 | if (!dma_chan) { |
| 459 | pr_err("dma_request_channel failed.\n"); | 464 | pr_err("Failed to request DMA channel.\n"); |
| 460 | goto acquire_err; | 465 | goto acquire_err; |
| 461 | } | 466 | } |
| 462 | 467 | ||
| @@ -487,7 +492,7 @@ static char *extra_clks_for_mx6q[GPMI_CLK_MAX] = { | |||
| 487 | "gpmi_apb", "gpmi_bch", "gpmi_bch_apb", "per1_bch", | 492 | "gpmi_apb", "gpmi_bch", "gpmi_bch_apb", "per1_bch", |
| 488 | }; | 493 | }; |
| 489 | 494 | ||
| 490 | static int __devinit gpmi_get_clks(struct gpmi_nand_data *this) | 495 | static int gpmi_get_clks(struct gpmi_nand_data *this) |
| 491 | { | 496 | { |
| 492 | struct resources *r = &this->resources; | 497 | struct resources *r = &this->resources; |
| 493 | char **extra_clks = NULL; | 498 | char **extra_clks = NULL; |
| @@ -533,7 +538,7 @@ err_clock: | |||
| 533 | return -ENOMEM; | 538 | return -ENOMEM; |
| 534 | } | 539 | } |
| 535 | 540 | ||
| 536 | static int __devinit acquire_resources(struct gpmi_nand_data *this) | 541 | static int acquire_resources(struct gpmi_nand_data *this) |
| 537 | { | 542 | { |
| 538 | struct pinctrl *pinctrl; | 543 | struct pinctrl *pinctrl; |
| 539 | int ret; | 544 | int ret; |
| @@ -583,7 +588,7 @@ static void release_resources(struct gpmi_nand_data *this) | |||
| 583 | release_dma_channels(this); | 588 | release_dma_channels(this); |
| 584 | } | 589 | } |
| 585 | 590 | ||
| 586 | static int __devinit init_hardware(struct gpmi_nand_data *this) | 591 | static int init_hardware(struct gpmi_nand_data *this) |
| 587 | { | 592 | { |
| 588 | int ret; | 593 | int ret; |
| 589 | 594 | ||
| @@ -625,7 +630,8 @@ static int read_page_prepare(struct gpmi_nand_data *this, | |||
| 625 | length, DMA_FROM_DEVICE); | 630 | length, DMA_FROM_DEVICE); |
| 626 | if (dma_mapping_error(dev, dest_phys)) { | 631 | if (dma_mapping_error(dev, dest_phys)) { |
| 627 | if (alt_size < length) { | 632 | if (alt_size < length) { |
| 628 | pr_err("Alternate buffer is too small\n"); | 633 | pr_err("%s, Alternate buffer is too small\n", |
| 634 | __func__); | ||
| 629 | return -ENOMEM; | 635 | return -ENOMEM; |
| 630 | } | 636 | } |
| 631 | goto map_failed; | 637 | goto map_failed; |
| @@ -675,7 +681,8 @@ static int send_page_prepare(struct gpmi_nand_data *this, | |||
| 675 | DMA_TO_DEVICE); | 681 | DMA_TO_DEVICE); |
| 676 | if (dma_mapping_error(dev, source_phys)) { | 682 | if (dma_mapping_error(dev, source_phys)) { |
| 677 | if (alt_size < length) { | 683 | if (alt_size < length) { |
| 678 | pr_err("Alternate buffer is too small\n"); | 684 | pr_err("%s, Alternate buffer is too small\n", |
| 685 | __func__); | ||
| 679 | return -ENOMEM; | 686 | return -ENOMEM; |
| 680 | } | 687 | } |
| 681 | goto map_failed; | 688 | goto map_failed; |
| @@ -763,7 +770,7 @@ static int gpmi_alloc_dma_buffer(struct gpmi_nand_data *this) | |||
| 763 | 770 | ||
| 764 | error_alloc: | 771 | error_alloc: |
| 765 | gpmi_free_dma_buffer(this); | 772 | gpmi_free_dma_buffer(this); |
| 766 | pr_err("allocate DMA buffer ret!!\n"); | 773 | pr_err("Error allocating DMA buffers!\n"); |
| 767 | return -ENOMEM; | 774 | return -ENOMEM; |
| 768 | } | 775 | } |
| 769 | 776 | ||
| @@ -1474,7 +1481,7 @@ static int gpmi_set_geometry(struct gpmi_nand_data *this) | |||
| 1474 | /* Set up the NFC geometry which is used by BCH. */ | 1481 | /* Set up the NFC geometry which is used by BCH. */ |
| 1475 | ret = bch_set_geometry(this); | 1482 | ret = bch_set_geometry(this); |
| 1476 | if (ret) { | 1483 | if (ret) { |
| 1477 | pr_err("set geometry ret : %d\n", ret); | 1484 | pr_err("Error setting BCH geometry : %d\n", ret); |
| 1478 | return ret; | 1485 | return ret; |
| 1479 | } | 1486 | } |
| 1480 | 1487 | ||
| @@ -1535,7 +1542,7 @@ static void gpmi_nfc_exit(struct gpmi_nand_data *this) | |||
| 1535 | gpmi_free_dma_buffer(this); | 1542 | gpmi_free_dma_buffer(this); |
| 1536 | } | 1543 | } |
| 1537 | 1544 | ||
| 1538 | static int __devinit gpmi_nfc_init(struct gpmi_nand_data *this) | 1545 | static int gpmi_nfc_init(struct gpmi_nand_data *this) |
| 1539 | { | 1546 | { |
| 1540 | struct mtd_info *mtd = &this->mtd; | 1547 | struct mtd_info *mtd = &this->mtd; |
| 1541 | struct nand_chip *chip = &this->nand; | 1548 | struct nand_chip *chip = &this->nand; |
| @@ -1618,7 +1625,7 @@ static const struct of_device_id gpmi_nand_id_table[] = { | |||
| 1618 | }; | 1625 | }; |
| 1619 | MODULE_DEVICE_TABLE(of, gpmi_nand_id_table); | 1626 | MODULE_DEVICE_TABLE(of, gpmi_nand_id_table); |
| 1620 | 1627 | ||
| 1621 | static int __devinit gpmi_nand_probe(struct platform_device *pdev) | 1628 | static int gpmi_nand_probe(struct platform_device *pdev) |
| 1622 | { | 1629 | { |
| 1623 | struct gpmi_nand_data *this; | 1630 | struct gpmi_nand_data *this; |
| 1624 | const struct of_device_id *of_id; | 1631 | const struct of_device_id *of_id; |
| @@ -1668,7 +1675,7 @@ exit_acquire_resources: | |||
| 1668 | return ret; | 1675 | return ret; |
| 1669 | } | 1676 | } |
| 1670 | 1677 | ||
| 1671 | static int __devexit gpmi_nand_remove(struct platform_device *pdev) | 1678 | static int gpmi_nand_remove(struct platform_device *pdev) |
| 1672 | { | 1679 | { |
| 1673 | struct gpmi_nand_data *this = platform_get_drvdata(pdev); | 1680 | struct gpmi_nand_data *this = platform_get_drvdata(pdev); |
| 1674 | 1681 | ||
| @@ -1685,7 +1692,7 @@ static struct platform_driver gpmi_nand_driver = { | |||
| 1685 | .of_match_table = gpmi_nand_id_table, | 1692 | .of_match_table = gpmi_nand_id_table, |
| 1686 | }, | 1693 | }, |
| 1687 | .probe = gpmi_nand_probe, | 1694 | .probe = gpmi_nand_probe, |
| 1688 | .remove = __devexit_p(gpmi_nand_remove), | 1695 | .remove = gpmi_nand_remove, |
| 1689 | .id_table = gpmi_ids, | 1696 | .id_table = gpmi_ids, |
| 1690 | }; | 1697 | }; |
| 1691 | module_platform_driver(gpmi_nand_driver); | 1698 | module_platform_driver(gpmi_nand_driver); |
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h index 7ac25c1e58f9..3d93a5e39090 100644 --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h | |||
| @@ -130,7 +130,6 @@ struct gpmi_nand_data { | |||
| 130 | /* System Interface */ | 130 | /* System Interface */ |
| 131 | struct device *dev; | 131 | struct device *dev; |
| 132 | struct platform_device *pdev; | 132 | struct platform_device *pdev; |
| 133 | struct gpmi_nand_platform_data *pdata; | ||
| 134 | 133 | ||
| 135 | /* Resources */ | 134 | /* Resources */ |
| 136 | struct resources resources; | 135 | struct resources resources; |
diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c index 100b6775e175..8d415f014e1d 100644 --- a/drivers/mtd/nand/jz4740_nand.c +++ b/drivers/mtd/nand/jz4740_nand.c | |||
| @@ -316,13 +316,17 @@ err: | |||
| 316 | return ret; | 316 | return ret; |
| 317 | } | 317 | } |
| 318 | 318 | ||
| 319 | static inline void jz_nand_iounmap_resource(struct resource *res, void __iomem *base) | 319 | static inline void jz_nand_iounmap_resource(struct resource *res, |
| 320 | void __iomem *base) | ||
| 320 | { | 321 | { |
| 321 | iounmap(base); | 322 | iounmap(base); |
| 322 | release_mem_region(res->start, resource_size(res)); | 323 | release_mem_region(res->start, resource_size(res)); |
| 323 | } | 324 | } |
| 324 | 325 | ||
| 325 | static int __devinit jz_nand_detect_bank(struct platform_device *pdev, struct jz_nand *nand, unsigned char bank, size_t chipnr, uint8_t *nand_maf_id, uint8_t *nand_dev_id) { | 326 | static int jz_nand_detect_bank(struct platform_device *pdev, |
| 327 | struct jz_nand *nand, unsigned char bank, | ||
| 328 | size_t chipnr, uint8_t *nand_maf_id, | ||
| 329 | uint8_t *nand_dev_id) { | ||
| 326 | int ret; | 330 | int ret; |
| 327 | int gpio; | 331 | int gpio; |
| 328 | char gpio_name[9]; | 332 | char gpio_name[9]; |
| @@ -400,7 +404,7 @@ notfound_gpio: | |||
| 400 | return ret; | 404 | return ret; |
| 401 | } | 405 | } |
| 402 | 406 | ||
| 403 | static int __devinit jz_nand_probe(struct platform_device *pdev) | 407 | static int jz_nand_probe(struct platform_device *pdev) |
| 404 | { | 408 | { |
| 405 | int ret; | 409 | int ret; |
| 406 | struct jz_nand *nand; | 410 | struct jz_nand *nand; |
| @@ -541,7 +545,7 @@ err_free: | |||
| 541 | return ret; | 545 | return ret; |
| 542 | } | 546 | } |
| 543 | 547 | ||
| 544 | static int __devexit jz_nand_remove(struct platform_device *pdev) | 548 | static int jz_nand_remove(struct platform_device *pdev) |
| 545 | { | 549 | { |
| 546 | struct jz_nand *nand = platform_get_drvdata(pdev); | 550 | struct jz_nand *nand = platform_get_drvdata(pdev); |
| 547 | struct jz_nand_platform_data *pdata = pdev->dev.platform_data; | 551 | struct jz_nand_platform_data *pdata = pdev->dev.platform_data; |
| @@ -573,7 +577,7 @@ static int __devexit jz_nand_remove(struct platform_device *pdev) | |||
| 573 | 577 | ||
| 574 | static struct platform_driver jz_nand_driver = { | 578 | static struct platform_driver jz_nand_driver = { |
| 575 | .probe = jz_nand_probe, | 579 | .probe = jz_nand_probe, |
| 576 | .remove = __devexit_p(jz_nand_remove), | 580 | .remove = jz_nand_remove, |
| 577 | .driver = { | 581 | .driver = { |
| 578 | .name = "jz4740-nand", | 582 | .name = "jz4740-nand", |
| 579 | .owner = THIS_MODULE, | 583 | .owner = THIS_MODULE, |
diff --git a/drivers/mtd/nand/lpc32xx_mlc.c b/drivers/mtd/nand/lpc32xx_mlc.c index c29b7ac1f6af..f182befa7360 100644 --- a/drivers/mtd/nand/lpc32xx_mlc.c +++ b/drivers/mtd/nand/lpc32xx_mlc.c | |||
| @@ -655,7 +655,7 @@ static struct lpc32xx_nand_cfg_mlc *lpc32xx_parse_dt(struct device *dev) | |||
| 655 | /* | 655 | /* |
| 656 | * Probe for NAND controller | 656 | * Probe for NAND controller |
| 657 | */ | 657 | */ |
| 658 | static int __devinit lpc32xx_nand_probe(struct platform_device *pdev) | 658 | static int lpc32xx_nand_probe(struct platform_device *pdev) |
| 659 | { | 659 | { |
| 660 | struct lpc32xx_nand_host *host; | 660 | struct lpc32xx_nand_host *host; |
| 661 | struct mtd_info *mtd; | 661 | struct mtd_info *mtd; |
| @@ -845,7 +845,7 @@ err_exit1: | |||
| 845 | /* | 845 | /* |
| 846 | * Remove NAND device | 846 | * Remove NAND device |
| 847 | */ | 847 | */ |
| 848 | static int __devexit lpc32xx_nand_remove(struct platform_device *pdev) | 848 | static int lpc32xx_nand_remove(struct platform_device *pdev) |
| 849 | { | 849 | { |
| 850 | struct lpc32xx_nand_host *host = platform_get_drvdata(pdev); | 850 | struct lpc32xx_nand_host *host = platform_get_drvdata(pdev); |
| 851 | struct mtd_info *mtd = &host->mtd; | 851 | struct mtd_info *mtd = &host->mtd; |
| @@ -907,7 +907,7 @@ MODULE_DEVICE_TABLE(of, lpc32xx_nand_match); | |||
| 907 | 907 | ||
| 908 | static struct platform_driver lpc32xx_nand_driver = { | 908 | static struct platform_driver lpc32xx_nand_driver = { |
| 909 | .probe = lpc32xx_nand_probe, | 909 | .probe = lpc32xx_nand_probe, |
| 910 | .remove = __devexit_p(lpc32xx_nand_remove), | 910 | .remove = lpc32xx_nand_remove, |
| 911 | .resume = lpc32xx_nand_resume, | 911 | .resume = lpc32xx_nand_resume, |
| 912 | .suspend = lpc32xx_nand_suspend, | 912 | .suspend = lpc32xx_nand_suspend, |
| 913 | .driver = { | 913 | .driver = { |
diff --git a/drivers/mtd/nand/lpc32xx_slc.c b/drivers/mtd/nand/lpc32xx_slc.c index 32409c45d479..030b78c62895 100644 --- a/drivers/mtd/nand/lpc32xx_slc.c +++ b/drivers/mtd/nand/lpc32xx_slc.c | |||
| @@ -755,7 +755,7 @@ static struct lpc32xx_nand_cfg_slc *lpc32xx_parse_dt(struct device *dev) | |||
| 755 | /* | 755 | /* |
| 756 | * Probe for NAND controller | 756 | * Probe for NAND controller |
| 757 | */ | 757 | */ |
| 758 | static int __devinit lpc32xx_nand_probe(struct platform_device *pdev) | 758 | static int lpc32xx_nand_probe(struct platform_device *pdev) |
| 759 | { | 759 | { |
| 760 | struct lpc32xx_nand_host *host; | 760 | struct lpc32xx_nand_host *host; |
| 761 | struct mtd_info *mtd; | 761 | struct mtd_info *mtd; |
| @@ -949,7 +949,7 @@ err_exit1: | |||
| 949 | /* | 949 | /* |
| 950 | * Remove NAND device. | 950 | * Remove NAND device. |
| 951 | */ | 951 | */ |
| 952 | static int __devexit lpc32xx_nand_remove(struct platform_device *pdev) | 952 | static int lpc32xx_nand_remove(struct platform_device *pdev) |
| 953 | { | 953 | { |
| 954 | uint32_t tmp; | 954 | uint32_t tmp; |
| 955 | struct lpc32xx_nand_host *host = platform_get_drvdata(pdev); | 955 | struct lpc32xx_nand_host *host = platform_get_drvdata(pdev); |
| @@ -1021,7 +1021,7 @@ MODULE_DEVICE_TABLE(of, lpc32xx_nand_match); | |||
| 1021 | 1021 | ||
| 1022 | static struct platform_driver lpc32xx_nand_driver = { | 1022 | static struct platform_driver lpc32xx_nand_driver = { |
| 1023 | .probe = lpc32xx_nand_probe, | 1023 | .probe = lpc32xx_nand_probe, |
| 1024 | .remove = __devexit_p(lpc32xx_nand_remove), | 1024 | .remove = lpc32xx_nand_remove, |
| 1025 | .resume = lpc32xx_nand_resume, | 1025 | .resume = lpc32xx_nand_resume, |
| 1026 | .suspend = lpc32xx_nand_suspend, | 1026 | .suspend = lpc32xx_nand_suspend, |
| 1027 | .driver = { | 1027 | .driver = { |
diff --git a/drivers/mtd/nand/mpc5121_nfc.c b/drivers/mtd/nand/mpc5121_nfc.c index f776c8577b8c..3c9cdcbc4cba 100644 --- a/drivers/mtd/nand/mpc5121_nfc.c +++ b/drivers/mtd/nand/mpc5121_nfc.c | |||
| @@ -626,7 +626,7 @@ static void mpc5121_nfc_free(struct device *dev, struct mtd_info *mtd) | |||
| 626 | iounmap(prv->csreg); | 626 | iounmap(prv->csreg); |
| 627 | } | 627 | } |
| 628 | 628 | ||
| 629 | static int __devinit mpc5121_nfc_probe(struct platform_device *op) | 629 | static int mpc5121_nfc_probe(struct platform_device *op) |
| 630 | { | 630 | { |
| 631 | struct device_node *rootnode, *dn = op->dev.of_node; | 631 | struct device_node *rootnode, *dn = op->dev.of_node; |
| 632 | struct device *dev = &op->dev; | 632 | struct device *dev = &op->dev; |
| @@ -827,7 +827,7 @@ error: | |||
| 827 | return retval; | 827 | return retval; |
| 828 | } | 828 | } |
| 829 | 829 | ||
| 830 | static int __devexit mpc5121_nfc_remove(struct platform_device *op) | 830 | static int mpc5121_nfc_remove(struct platform_device *op) |
| 831 | { | 831 | { |
| 832 | struct device *dev = &op->dev; | 832 | struct device *dev = &op->dev; |
| 833 | struct mtd_info *mtd = dev_get_drvdata(dev); | 833 | struct mtd_info *mtd = dev_get_drvdata(dev); |
| @@ -841,14 +841,14 @@ static int __devexit mpc5121_nfc_remove(struct platform_device *op) | |||
| 841 | return 0; | 841 | return 0; |
| 842 | } | 842 | } |
| 843 | 843 | ||
| 844 | static struct of_device_id mpc5121_nfc_match[] __devinitdata = { | 844 | static struct of_device_id mpc5121_nfc_match[] = { |
| 845 | { .compatible = "fsl,mpc5121-nfc", }, | 845 | { .compatible = "fsl,mpc5121-nfc", }, |
| 846 | {}, | 846 | {}, |
| 847 | }; | 847 | }; |
| 848 | 848 | ||
| 849 | static struct platform_driver mpc5121_nfc_driver = { | 849 | static struct platform_driver mpc5121_nfc_driver = { |
| 850 | .probe = mpc5121_nfc_probe, | 850 | .probe = mpc5121_nfc_probe, |
| 851 | .remove = __devexit_p(mpc5121_nfc_remove), | 851 | .remove = mpc5121_nfc_remove, |
| 852 | .driver = { | 852 | .driver = { |
| 853 | .name = DRV_NAME, | 853 | .name = DRV_NAME, |
| 854 | .owner = THIS_MODULE, | 854 | .owner = THIS_MODULE, |
diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 022dcdc256fb..45204e41a028 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c | |||
| @@ -266,7 +266,8 @@ static struct nand_ecclayout nandv2_hw_eccoob_4k = { | |||
| 266 | } | 266 | } |
| 267 | }; | 267 | }; |
| 268 | 268 | ||
| 269 | static const char *part_probes[] = { "RedBoot", "cmdlinepart", "ofpart", NULL }; | 269 | static const char const *part_probes[] = { |
| 270 | "cmdlinepart", "RedBoot", "ofpart", NULL }; | ||
| 270 | 271 | ||
| 271 | static void memcpy32_fromio(void *trg, const void __iomem *src, size_t size) | 272 | static void memcpy32_fromio(void *trg, const void __iomem *src, size_t size) |
| 272 | { | 273 | { |
| @@ -1378,7 +1379,7 @@ static int __init mxcnd_probe_dt(struct mxc_nand_host *host) | |||
| 1378 | } | 1379 | } |
| 1379 | #endif | 1380 | #endif |
| 1380 | 1381 | ||
| 1381 | static int __devinit mxcnd_probe(struct platform_device *pdev) | 1382 | static int mxcnd_probe(struct platform_device *pdev) |
| 1382 | { | 1383 | { |
| 1383 | struct nand_chip *this; | 1384 | struct nand_chip *this; |
| 1384 | struct mtd_info *mtd; | 1385 | struct mtd_info *mtd; |
| @@ -1556,12 +1557,13 @@ static int __devinit mxcnd_probe(struct platform_device *pdev) | |||
| 1556 | return 0; | 1557 | return 0; |
| 1557 | 1558 | ||
| 1558 | escan: | 1559 | escan: |
| 1559 | clk_disable_unprepare(host->clk); | 1560 | if (host->clk_act) |
| 1561 | clk_disable_unprepare(host->clk); | ||
| 1560 | 1562 | ||
| 1561 | return err; | 1563 | return err; |
| 1562 | } | 1564 | } |
| 1563 | 1565 | ||
| 1564 | static int __devexit mxcnd_remove(struct platform_device *pdev) | 1566 | static int mxcnd_remove(struct platform_device *pdev) |
| 1565 | { | 1567 | { |
| 1566 | struct mxc_nand_host *host = platform_get_drvdata(pdev); | 1568 | struct mxc_nand_host *host = platform_get_drvdata(pdev); |
| 1567 | 1569 | ||
| @@ -1580,7 +1582,7 @@ static struct platform_driver mxcnd_driver = { | |||
| 1580 | }, | 1582 | }, |
| 1581 | .id_table = mxcnd_devtype, | 1583 | .id_table = mxcnd_devtype, |
| 1582 | .probe = mxcnd_probe, | 1584 | .probe = mxcnd_probe, |
| 1583 | .remove = __devexit_p(mxcnd_remove), | 1585 | .remove = mxcnd_remove, |
| 1584 | }; | 1586 | }; |
| 1585 | module_platform_driver(mxcnd_driver); | 1587 | module_platform_driver(mxcnd_driver); |
| 1586 | 1588 | ||
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 1a03b7f673ce..8323ac991ad1 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c | |||
| @@ -93,8 +93,7 @@ static struct nand_ecclayout nand_oob_128 = { | |||
| 93 | .length = 78} } | 93 | .length = 78} } |
| 94 | }; | 94 | }; |
| 95 | 95 | ||
| 96 | static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, | 96 | static int nand_get_device(struct mtd_info *mtd, int new_state); |
| 97 | int new_state); | ||
| 98 | 97 | ||
| 99 | static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, | 98 | static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, |
| 100 | struct mtd_oob_ops *ops); | 99 | struct mtd_oob_ops *ops); |
| @@ -130,15 +129,12 @@ static int check_offs_len(struct mtd_info *mtd, | |||
| 130 | * nand_release_device - [GENERIC] release chip | 129 | * nand_release_device - [GENERIC] release chip |
| 131 | * @mtd: MTD device structure | 130 | * @mtd: MTD device structure |
| 132 | * | 131 | * |
| 133 | * Deselect, release chip lock and wake up anyone waiting on the device. | 132 | * Release chip lock and wake up anyone waiting on the device. |
| 134 | */ | 133 | */ |
| 135 | static void nand_release_device(struct mtd_info *mtd) | 134 | static void nand_release_device(struct mtd_info *mtd) |
| 136 | { | 135 | { |
| 137 | struct nand_chip *chip = mtd->priv; | 136 | struct nand_chip *chip = mtd->priv; |
| 138 | 137 | ||
| 139 | /* De-select the NAND device */ | ||
| 140 | chip->select_chip(mtd, -1); | ||
| 141 | |||
| 142 | /* Release the controller and the chip */ | 138 | /* Release the controller and the chip */ |
| 143 | spin_lock(&chip->controller->lock); | 139 | spin_lock(&chip->controller->lock); |
| 144 | chip->controller->active = NULL; | 140 | chip->controller->active = NULL; |
| @@ -160,7 +156,7 @@ static uint8_t nand_read_byte(struct mtd_info *mtd) | |||
| 160 | } | 156 | } |
| 161 | 157 | ||
| 162 | /** | 158 | /** |
| 163 | * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip | 159 | * nand_read_byte16 - [DEFAULT] read one byte endianness aware from the chip |
| 164 | * nand_read_byte16 - [DEFAULT] read one byte endianness aware from the chip | 160 | * nand_read_byte16 - [DEFAULT] read one byte endianness aware from the chip |
| 165 | * @mtd: MTD device structure | 161 | * @mtd: MTD device structure |
| 166 | * | 162 | * |
| @@ -303,7 +299,7 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) | |||
| 303 | if (getchip) { | 299 | if (getchip) { |
| 304 | chipnr = (int)(ofs >> chip->chip_shift); | 300 | chipnr = (int)(ofs >> chip->chip_shift); |
| 305 | 301 | ||
| 306 | nand_get_device(chip, mtd, FL_READING); | 302 | nand_get_device(mtd, FL_READING); |
| 307 | 303 | ||
| 308 | /* Select the NAND device */ | 304 | /* Select the NAND device */ |
| 309 | chip->select_chip(mtd, chipnr); | 305 | chip->select_chip(mtd, chipnr); |
| @@ -333,8 +329,10 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) | |||
| 333 | i++; | 329 | i++; |
| 334 | } while (!res && i < 2 && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE)); | 330 | } while (!res && i < 2 && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE)); |
| 335 | 331 | ||
| 336 | if (getchip) | 332 | if (getchip) { |
| 333 | chip->select_chip(mtd, -1); | ||
| 337 | nand_release_device(mtd); | 334 | nand_release_device(mtd); |
| 335 | } | ||
| 338 | 336 | ||
| 339 | return res; | 337 | return res; |
| 340 | } | 338 | } |
| @@ -383,7 +381,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) | |||
| 383 | struct mtd_oob_ops ops; | 381 | struct mtd_oob_ops ops; |
| 384 | loff_t wr_ofs = ofs; | 382 | loff_t wr_ofs = ofs; |
| 385 | 383 | ||
| 386 | nand_get_device(chip, mtd, FL_WRITING); | 384 | nand_get_device(mtd, FL_WRITING); |
| 387 | 385 | ||
| 388 | ops.datbuf = NULL; | 386 | ops.datbuf = NULL; |
| 389 | ops.oobbuf = buf; | 387 | ops.oobbuf = buf; |
| @@ -492,7 +490,7 @@ static void panic_nand_wait_ready(struct mtd_info *mtd, unsigned long timeo) | |||
| 492 | void nand_wait_ready(struct mtd_info *mtd) | 490 | void nand_wait_ready(struct mtd_info *mtd) |
| 493 | { | 491 | { |
| 494 | struct nand_chip *chip = mtd->priv; | 492 | struct nand_chip *chip = mtd->priv; |
| 495 | unsigned long timeo = jiffies + 2; | 493 | unsigned long timeo = jiffies + msecs_to_jiffies(20); |
| 496 | 494 | ||
| 497 | /* 400ms timeout */ | 495 | /* 400ms timeout */ |
| 498 | if (in_interrupt() || oops_in_progress) | 496 | if (in_interrupt() || oops_in_progress) |
| @@ -750,15 +748,15 @@ static void panic_nand_get_device(struct nand_chip *chip, | |||
| 750 | 748 | ||
| 751 | /** | 749 | /** |
| 752 | * nand_get_device - [GENERIC] Get chip for selected access | 750 | * nand_get_device - [GENERIC] Get chip for selected access |
| 753 | * @chip: the nand chip descriptor | ||
| 754 | * @mtd: MTD device structure | 751 | * @mtd: MTD device structure |
| 755 | * @new_state: the state which is requested | 752 | * @new_state: the state which is requested |
| 756 | * | 753 | * |
| 757 | * Get the device and lock it for exclusive access | 754 | * Get the device and lock it for exclusive access |
| 758 | */ | 755 | */ |
| 759 | static int | 756 | static int |
| 760 | nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state) | 757 | nand_get_device(struct mtd_info *mtd, int new_state) |
| 761 | { | 758 | { |
| 759 | struct nand_chip *chip = mtd->priv; | ||
| 762 | spinlock_t *lock = &chip->controller->lock; | 760 | spinlock_t *lock = &chip->controller->lock; |
| 763 | wait_queue_head_t *wq = &chip->controller->wq; | 761 | wait_queue_head_t *wq = &chip->controller->wq; |
| 764 | DECLARE_WAITQUEUE(wait, current); | 762 | DECLARE_WAITQUEUE(wait, current); |
| @@ -865,6 +863,8 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip) | |||
| 865 | led_trigger_event(nand_led_trigger, LED_OFF); | 863 | led_trigger_event(nand_led_trigger, LED_OFF); |
| 866 | 864 | ||
| 867 | status = (int)chip->read_byte(mtd); | 865 | status = (int)chip->read_byte(mtd); |
| 866 | /* This can happen if in case of timeout or buggy dev_ready */ | ||
| 867 | WARN_ON(!(status & NAND_STATUS_READY)); | ||
| 868 | return status; | 868 | return status; |
| 869 | } | 869 | } |
| 870 | 870 | ||
| @@ -899,7 +899,7 @@ static int __nand_unlock(struct mtd_info *mtd, loff_t ofs, | |||
| 899 | /* Call wait ready function */ | 899 | /* Call wait ready function */ |
| 900 | status = chip->waitfunc(mtd, chip); | 900 | status = chip->waitfunc(mtd, chip); |
| 901 | /* See if device thinks it succeeded */ | 901 | /* See if device thinks it succeeded */ |
| 902 | if (status & 0x01) { | 902 | if (status & NAND_STATUS_FAIL) { |
| 903 | pr_debug("%s: error status = 0x%08x\n", | 903 | pr_debug("%s: error status = 0x%08x\n", |
| 904 | __func__, status); | 904 | __func__, status); |
| 905 | ret = -EIO; | 905 | ret = -EIO; |
| @@ -932,7 +932,7 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) | |||
| 932 | if (ofs + len == mtd->size) | 932 | if (ofs + len == mtd->size) |
| 933 | len -= mtd->erasesize; | 933 | len -= mtd->erasesize; |
| 934 | 934 | ||
| 935 | nand_get_device(chip, mtd, FL_UNLOCKING); | 935 | nand_get_device(mtd, FL_UNLOCKING); |
| 936 | 936 | ||
| 937 | /* Shift to get chip number */ | 937 | /* Shift to get chip number */ |
| 938 | chipnr = ofs >> chip->chip_shift; | 938 | chipnr = ofs >> chip->chip_shift; |
| @@ -950,6 +950,7 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) | |||
| 950 | ret = __nand_unlock(mtd, ofs, len, 0); | 950 | ret = __nand_unlock(mtd, ofs, len, 0); |
| 951 | 951 | ||
| 952 | out: | 952 | out: |
| 953 | chip->select_chip(mtd, -1); | ||
| 953 | nand_release_device(mtd); | 954 | nand_release_device(mtd); |
| 954 | 955 | ||
| 955 | return ret; | 956 | return ret; |
| @@ -981,7 +982,7 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) | |||
| 981 | if (check_offs_len(mtd, ofs, len)) | 982 | if (check_offs_len(mtd, ofs, len)) |
| 982 | ret = -EINVAL; | 983 | ret = -EINVAL; |
| 983 | 984 | ||
| 984 | nand_get_device(chip, mtd, FL_LOCKING); | 985 | nand_get_device(mtd, FL_LOCKING); |
| 985 | 986 | ||
| 986 | /* Shift to get chip number */ | 987 | /* Shift to get chip number */ |
| 987 | chipnr = ofs >> chip->chip_shift; | 988 | chipnr = ofs >> chip->chip_shift; |
| @@ -1004,7 +1005,7 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) | |||
| 1004 | /* Call wait ready function */ | 1005 | /* Call wait ready function */ |
| 1005 | status = chip->waitfunc(mtd, chip); | 1006 | status = chip->waitfunc(mtd, chip); |
| 1006 | /* See if device thinks it succeeded */ | 1007 | /* See if device thinks it succeeded */ |
| 1007 | if (status & 0x01) { | 1008 | if (status & NAND_STATUS_FAIL) { |
| 1008 | pr_debug("%s: error status = 0x%08x\n", | 1009 | pr_debug("%s: error status = 0x%08x\n", |
| 1009 | __func__, status); | 1010 | __func__, status); |
| 1010 | ret = -EIO; | 1011 | ret = -EIO; |
| @@ -1014,6 +1015,7 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) | |||
| 1014 | ret = __nand_unlock(mtd, ofs, len, 0x1); | 1015 | ret = __nand_unlock(mtd, ofs, len, 0x1); |
| 1015 | 1016 | ||
| 1016 | out: | 1017 | out: |
| 1018 | chip->select_chip(mtd, -1); | ||
| 1017 | nand_release_device(mtd); | 1019 | nand_release_device(mtd); |
| 1018 | 1020 | ||
| 1019 | return ret; | 1021 | return ret; |
| @@ -1550,6 +1552,7 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
| 1550 | chip->select_chip(mtd, chipnr); | 1552 | chip->select_chip(mtd, chipnr); |
| 1551 | } | 1553 | } |
| 1552 | } | 1554 | } |
| 1555 | chip->select_chip(mtd, -1); | ||
| 1553 | 1556 | ||
| 1554 | ops->retlen = ops->len - (size_t) readlen; | 1557 | ops->retlen = ops->len - (size_t) readlen; |
| 1555 | if (oob) | 1558 | if (oob) |
| @@ -1577,11 +1580,10 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, | |||
| 1577 | static int nand_read(struct mtd_info *mtd, loff_t from, size_t len, | 1580 | static int nand_read(struct mtd_info *mtd, loff_t from, size_t len, |
| 1578 | size_t *retlen, uint8_t *buf) | 1581 | size_t *retlen, uint8_t *buf) |
| 1579 | { | 1582 | { |
| 1580 | struct nand_chip *chip = mtd->priv; | ||
| 1581 | struct mtd_oob_ops ops; | 1583 | struct mtd_oob_ops ops; |
| 1582 | int ret; | 1584 | int ret; |
| 1583 | 1585 | ||
| 1584 | nand_get_device(chip, mtd, FL_READING); | 1586 | nand_get_device(mtd, FL_READING); |
| 1585 | ops.len = len; | 1587 | ops.len = len; |
| 1586 | ops.datbuf = buf; | 1588 | ops.datbuf = buf; |
| 1587 | ops.oobbuf = NULL; | 1589 | ops.oobbuf = NULL; |
| @@ -1804,6 +1806,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, | |||
| 1804 | chip->select_chip(mtd, chipnr); | 1806 | chip->select_chip(mtd, chipnr); |
| 1805 | } | 1807 | } |
| 1806 | } | 1808 | } |
| 1809 | chip->select_chip(mtd, -1); | ||
| 1807 | 1810 | ||
| 1808 | ops->oobretlen = ops->ooblen - readlen; | 1811 | ops->oobretlen = ops->ooblen - readlen; |
| 1809 | 1812 | ||
| @@ -1827,7 +1830,6 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, | |||
| 1827 | static int nand_read_oob(struct mtd_info *mtd, loff_t from, | 1830 | static int nand_read_oob(struct mtd_info *mtd, loff_t from, |
| 1828 | struct mtd_oob_ops *ops) | 1831 | struct mtd_oob_ops *ops) |
| 1829 | { | 1832 | { |
| 1830 | struct nand_chip *chip = mtd->priv; | ||
| 1831 | int ret = -ENOTSUPP; | 1833 | int ret = -ENOTSUPP; |
| 1832 | 1834 | ||
| 1833 | ops->retlen = 0; | 1835 | ops->retlen = 0; |
| @@ -1839,7 +1841,7 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from, | |||
| 1839 | return -EINVAL; | 1841 | return -EINVAL; |
| 1840 | } | 1842 | } |
| 1841 | 1843 | ||
| 1842 | nand_get_device(chip, mtd, FL_READING); | 1844 | nand_get_device(mtd, FL_READING); |
| 1843 | 1845 | ||
| 1844 | switch (ops->mode) { | 1846 | switch (ops->mode) { |
| 1845 | case MTD_OPS_PLACE_OOB: | 1847 | case MTD_OPS_PLACE_OOB: |
| @@ -2186,8 +2188,10 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, | |||
| 2186 | chip->select_chip(mtd, chipnr); | 2188 | chip->select_chip(mtd, chipnr); |
| 2187 | 2189 | ||
| 2188 | /* Check, if it is write protected */ | 2190 | /* Check, if it is write protected */ |
| 2189 | if (nand_check_wp(mtd)) | 2191 | if (nand_check_wp(mtd)) { |
| 2190 | return -EIO; | 2192 | ret = -EIO; |
| 2193 | goto err_out; | ||
| 2194 | } | ||
| 2191 | 2195 | ||
| 2192 | realpage = (int)(to >> chip->page_shift); | 2196 | realpage = (int)(to >> chip->page_shift); |
| 2193 | page = realpage & chip->pagemask; | 2197 | page = realpage & chip->pagemask; |
| @@ -2199,8 +2203,10 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, | |||
| 2199 | chip->pagebuf = -1; | 2203 | chip->pagebuf = -1; |
| 2200 | 2204 | ||
| 2201 | /* Don't allow multipage oob writes with offset */ | 2205 | /* Don't allow multipage oob writes with offset */ |
| 2202 | if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen)) | 2206 | if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen)) { |
| 2203 | return -EINVAL; | 2207 | ret = -EINVAL; |
| 2208 | goto err_out; | ||
| 2209 | } | ||
| 2204 | 2210 | ||
| 2205 | while (1) { | 2211 | while (1) { |
| 2206 | int bytes = mtd->writesize; | 2212 | int bytes = mtd->writesize; |
| @@ -2251,6 +2257,9 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, | |||
| 2251 | ops->retlen = ops->len - writelen; | 2257 | ops->retlen = ops->len - writelen; |
| 2252 | if (unlikely(oob)) | 2258 | if (unlikely(oob)) |
| 2253 | ops->oobretlen = ops->ooblen; | 2259 | ops->oobretlen = ops->ooblen; |
| 2260 | |||
| 2261 | err_out: | ||
| 2262 | chip->select_chip(mtd, -1); | ||
| 2254 | return ret; | 2263 | return ret; |
| 2255 | } | 2264 | } |
| 2256 | 2265 | ||
| @@ -2302,11 +2311,10 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len, | |||
| 2302 | static int nand_write(struct mtd_info *mtd, loff_t to, size_t len, | 2311 | static int nand_write(struct mtd_info *mtd, loff_t to, size_t len, |
| 2303 | size_t *retlen, const uint8_t *buf) | 2312 | size_t *retlen, const uint8_t *buf) |
| 2304 | { | 2313 | { |
| 2305 | struct nand_chip *chip = mtd->priv; | ||
| 2306 | struct mtd_oob_ops ops; | 2314 | struct mtd_oob_ops ops; |
| 2307 | int ret; | 2315 | int ret; |
| 2308 | 2316 | ||
| 2309 | nand_get_device(chip, mtd, FL_WRITING); | 2317 | nand_get_device(mtd, FL_WRITING); |
| 2310 | ops.len = len; | 2318 | ops.len = len; |
| 2311 | ops.datbuf = (uint8_t *)buf; | 2319 | ops.datbuf = (uint8_t *)buf; |
| 2312 | ops.oobbuf = NULL; | 2320 | ops.oobbuf = NULL; |
| @@ -2377,8 +2385,10 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, | |||
| 2377 | chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); | 2385 | chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); |
| 2378 | 2386 | ||
| 2379 | /* Check, if it is write protected */ | 2387 | /* Check, if it is write protected */ |
| 2380 | if (nand_check_wp(mtd)) | 2388 | if (nand_check_wp(mtd)) { |
| 2389 | chip->select_chip(mtd, -1); | ||
| 2381 | return -EROFS; | 2390 | return -EROFS; |
| 2391 | } | ||
| 2382 | 2392 | ||
| 2383 | /* Invalidate the page cache, if we write to the cached page */ | 2393 | /* Invalidate the page cache, if we write to the cached page */ |
| 2384 | if (page == chip->pagebuf) | 2394 | if (page == chip->pagebuf) |
| @@ -2391,6 +2401,8 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, | |||
| 2391 | else | 2401 | else |
| 2392 | status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask); | 2402 | status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask); |
| 2393 | 2403 | ||
| 2404 | chip->select_chip(mtd, -1); | ||
| 2405 | |||
| 2394 | if (status) | 2406 | if (status) |
| 2395 | return status; | 2407 | return status; |
| 2396 | 2408 | ||
| @@ -2408,7 +2420,6 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, | |||
| 2408 | static int nand_write_oob(struct mtd_info *mtd, loff_t to, | 2420 | static int nand_write_oob(struct mtd_info *mtd, loff_t to, |
| 2409 | struct mtd_oob_ops *ops) | 2421 | struct mtd_oob_ops *ops) |
| 2410 | { | 2422 | { |
| 2411 | struct nand_chip *chip = mtd->priv; | ||
| 2412 | int ret = -ENOTSUPP; | 2423 | int ret = -ENOTSUPP; |
| 2413 | 2424 | ||
| 2414 | ops->retlen = 0; | 2425 | ops->retlen = 0; |
| @@ -2420,7 +2431,7 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to, | |||
| 2420 | return -EINVAL; | 2431 | return -EINVAL; |
| 2421 | } | 2432 | } |
| 2422 | 2433 | ||
| 2423 | nand_get_device(chip, mtd, FL_WRITING); | 2434 | nand_get_device(mtd, FL_WRITING); |
| 2424 | 2435 | ||
| 2425 | switch (ops->mode) { | 2436 | switch (ops->mode) { |
| 2426 | case MTD_OPS_PLACE_OOB: | 2437 | case MTD_OPS_PLACE_OOB: |
| @@ -2513,7 +2524,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, | |||
| 2513 | return -EINVAL; | 2524 | return -EINVAL; |
| 2514 | 2525 | ||
| 2515 | /* Grab the lock and see if the device is available */ | 2526 | /* Grab the lock and see if the device is available */ |
| 2516 | nand_get_device(chip, mtd, FL_ERASING); | 2527 | nand_get_device(mtd, FL_ERASING); |
| 2517 | 2528 | ||
| 2518 | /* Shift to get first page */ | 2529 | /* Shift to get first page */ |
| 2519 | page = (int)(instr->addr >> chip->page_shift); | 2530 | page = (int)(instr->addr >> chip->page_shift); |
| @@ -2623,6 +2634,7 @@ erase_exit: | |||
| 2623 | ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO; | 2634 | ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO; |
| 2624 | 2635 | ||
| 2625 | /* Deselect and wake up anyone waiting on the device */ | 2636 | /* Deselect and wake up anyone waiting on the device */ |
| 2637 | chip->select_chip(mtd, -1); | ||
| 2626 | nand_release_device(mtd); | 2638 | nand_release_device(mtd); |
| 2627 | 2639 | ||
| 2628 | /* Do call back function */ | 2640 | /* Do call back function */ |
| @@ -2658,12 +2670,10 @@ erase_exit: | |||
| 2658 | */ | 2670 | */ |
| 2659 | static void nand_sync(struct mtd_info *mtd) | 2671 | static void nand_sync(struct mtd_info *mtd) |
| 2660 | { | 2672 | { |
| 2661 | struct nand_chip *chip = mtd->priv; | ||
| 2662 | |||
| 2663 | pr_debug("%s: called\n", __func__); | 2673 | pr_debug("%s: called\n", __func__); |
| 2664 | 2674 | ||
| 2665 | /* Grab the lock and see if the device is available */ | 2675 | /* Grab the lock and see if the device is available */ |
| 2666 | nand_get_device(chip, mtd, FL_SYNCING); | 2676 | nand_get_device(mtd, FL_SYNCING); |
| 2667 | /* Release it and go back */ | 2677 | /* Release it and go back */ |
| 2668 | nand_release_device(mtd); | 2678 | nand_release_device(mtd); |
| 2669 | } | 2679 | } |
| @@ -2749,9 +2759,7 @@ static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 2749 | */ | 2759 | */ |
| 2750 | static int nand_suspend(struct mtd_info *mtd) | 2760 | static int nand_suspend(struct mtd_info *mtd) |
| 2751 | { | 2761 | { |
| 2752 | struct nand_chip *chip = mtd->priv; | 2762 | return nand_get_device(mtd, FL_PM_SUSPENDED); |
| 2753 | |||
| 2754 | return nand_get_device(chip, mtd, FL_PM_SUSPENDED); | ||
| 2755 | } | 2763 | } |
| 2756 | 2764 | ||
| 2757 | /** | 2765 | /** |
| @@ -2849,6 +2857,8 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 2849 | int i; | 2857 | int i; |
| 2850 | int val; | 2858 | int val; |
| 2851 | 2859 | ||
| 2860 | /* ONFI need to be probed in 8 bits mode */ | ||
| 2861 | WARN_ON(chip->options & NAND_BUSWIDTH_16); | ||
| 2852 | /* Try ONFI for unknown chip or LP */ | 2862 | /* Try ONFI for unknown chip or LP */ |
| 2853 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1); | 2863 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1); |
| 2854 | if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' || | 2864 | if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' || |
| @@ -2913,7 +2923,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, | |||
| 2913 | * | 2923 | * |
| 2914 | * Check if an ID string is repeated within a given sequence of bytes at | 2924 | * Check if an ID string is repeated within a given sequence of bytes at |
| 2915 | * specific repetition interval period (e.g., {0x20,0x01,0x7F,0x20} has a | 2925 | * specific repetition interval period (e.g., {0x20,0x01,0x7F,0x20} has a |
| 2916 | * period of 2). This is a helper function for nand_id_len(). Returns non-zero | 2926 | * period of 3). This is a helper function for nand_id_len(). Returns non-zero |
| 2917 | * if the repetition has a period of @period; otherwise, returns zero. | 2927 | * if the repetition has a period of @period; otherwise, returns zero. |
| 2918 | */ | 2928 | */ |
| 2919 | static int nand_id_has_period(u8 *id_data, int arrlen, int period) | 2929 | static int nand_id_has_period(u8 *id_data, int arrlen, int period) |
| @@ -3242,11 +3252,15 @@ ident_done: | |||
| 3242 | break; | 3252 | break; |
| 3243 | } | 3253 | } |
| 3244 | 3254 | ||
| 3245 | /* | 3255 | if (chip->options & NAND_BUSWIDTH_AUTO) { |
| 3246 | * Check, if buswidth is correct. Hardware drivers should set | 3256 | WARN_ON(chip->options & NAND_BUSWIDTH_16); |
| 3247 | * chip correct! | 3257 | chip->options |= busw; |
| 3248 | */ | 3258 | nand_set_defaults(chip, busw); |
| 3249 | if (busw != (chip->options & NAND_BUSWIDTH_16)) { | 3259 | } else if (busw != (chip->options & NAND_BUSWIDTH_16)) { |
| 3260 | /* | ||
| 3261 | * Check, if buswidth is correct. Hardware drivers should set | ||
| 3262 | * chip correct! | ||
| 3263 | */ | ||
| 3250 | pr_info("NAND device: Manufacturer ID:" | 3264 | pr_info("NAND device: Manufacturer ID:" |
| 3251 | " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, | 3265 | " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, |
| 3252 | *dev_id, nand_manuf_ids[maf_idx].name, mtd->name); | 3266 | *dev_id, nand_manuf_ids[maf_idx].name, mtd->name); |
| @@ -3285,10 +3299,10 @@ ident_done: | |||
| 3285 | chip->cmdfunc = nand_command_lp; | 3299 | chip->cmdfunc = nand_command_lp; |
| 3286 | 3300 | ||
| 3287 | pr_info("NAND device: Manufacturer ID: 0x%02x, Chip ID: 0x%02x (%s %s)," | 3301 | pr_info("NAND device: Manufacturer ID: 0x%02x, Chip ID: 0x%02x (%s %s)," |
| 3288 | " page size: %d, OOB size: %d\n", | 3302 | " %dMiB, page size: %d, OOB size: %d\n", |
| 3289 | *maf_id, *dev_id, nand_manuf_ids[maf_idx].name, | 3303 | *maf_id, *dev_id, nand_manuf_ids[maf_idx].name, |
| 3290 | chip->onfi_version ? chip->onfi_params.model : type->name, | 3304 | chip->onfi_version ? chip->onfi_params.model : type->name, |
| 3291 | mtd->writesize, mtd->oobsize); | 3305 | (int)(chip->chipsize >> 20), mtd->writesize, mtd->oobsize); |
| 3292 | 3306 | ||
| 3293 | return type; | 3307 | return type; |
| 3294 | } | 3308 | } |
| @@ -3327,6 +3341,8 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, | |||
| 3327 | return PTR_ERR(type); | 3341 | return PTR_ERR(type); |
| 3328 | } | 3342 | } |
| 3329 | 3343 | ||
| 3344 | chip->select_chip(mtd, -1); | ||
| 3345 | |||
| 3330 | /* Check for a chip array */ | 3346 | /* Check for a chip array */ |
| 3331 | for (i = 1; i < maxchips; i++) { | 3347 | for (i = 1; i < maxchips; i++) { |
| 3332 | chip->select_chip(mtd, i); | 3348 | chip->select_chip(mtd, i); |
| @@ -3336,8 +3352,11 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, | |||
| 3336 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); | 3352 | chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); |
| 3337 | /* Read manufacturer and device IDs */ | 3353 | /* Read manufacturer and device IDs */ |
| 3338 | if (nand_maf_id != chip->read_byte(mtd) || | 3354 | if (nand_maf_id != chip->read_byte(mtd) || |
| 3339 | nand_dev_id != chip->read_byte(mtd)) | 3355 | nand_dev_id != chip->read_byte(mtd)) { |
| 3356 | chip->select_chip(mtd, -1); | ||
| 3340 | break; | 3357 | break; |
| 3358 | } | ||
| 3359 | chip->select_chip(mtd, -1); | ||
| 3341 | } | 3360 | } |
| 3342 | if (i > 1) | 3361 | if (i > 1) |
| 3343 | pr_info("%d NAND chips detected\n", i); | 3362 | pr_info("%d NAND chips detected\n", i); |
| @@ -3596,9 +3615,6 @@ int nand_scan_tail(struct mtd_info *mtd) | |||
| 3596 | /* Initialize state */ | 3615 | /* Initialize state */ |
| 3597 | chip->state = FL_READY; | 3616 | chip->state = FL_READY; |
| 3598 | 3617 | ||
| 3599 | /* De-select the device */ | ||
| 3600 | chip->select_chip(mtd, -1); | ||
| 3601 | |||
| 3602 | /* Invalidate the pagebuffer reference */ | 3618 | /* Invalidate the pagebuffer reference */ |
| 3603 | chip->pagebuf = -1; | 3619 | chip->pagebuf = -1; |
| 3604 | 3620 | ||
diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index c3c13e64a2f0..818b65c85d12 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c | |||
| @@ -42,6 +42,8 @@ | |||
| 42 | #include <linux/sched.h> | 42 | #include <linux/sched.h> |
| 43 | #include <linux/fs.h> | 43 | #include <linux/fs.h> |
| 44 | #include <linux/pagemap.h> | 44 | #include <linux/pagemap.h> |
| 45 | #include <linux/seq_file.h> | ||
| 46 | #include <linux/debugfs.h> | ||
| 45 | 47 | ||
| 46 | /* Default simulator parameters values */ | 48 | /* Default simulator parameters values */ |
| 47 | #if !defined(CONFIG_NANDSIM_FIRST_ID_BYTE) || \ | 49 | #if !defined(CONFIG_NANDSIM_FIRST_ID_BYTE) || \ |
| @@ -105,7 +107,6 @@ static char *weakblocks = NULL; | |||
| 105 | static char *weakpages = NULL; | 107 | static char *weakpages = NULL; |
| 106 | static unsigned int bitflips = 0; | 108 | static unsigned int bitflips = 0; |
| 107 | static char *gravepages = NULL; | 109 | static char *gravepages = NULL; |
| 108 | static unsigned int rptwear = 0; | ||
| 109 | static unsigned int overridesize = 0; | 110 | static unsigned int overridesize = 0; |
| 110 | static char *cache_file = NULL; | 111 | static char *cache_file = NULL; |
| 111 | static unsigned int bbt; | 112 | static unsigned int bbt; |
| @@ -130,7 +131,6 @@ module_param(weakblocks, charp, 0400); | |||
| 130 | module_param(weakpages, charp, 0400); | 131 | module_param(weakpages, charp, 0400); |
| 131 | module_param(bitflips, uint, 0400); | 132 | module_param(bitflips, uint, 0400); |
| 132 | module_param(gravepages, charp, 0400); | 133 | module_param(gravepages, charp, 0400); |
| 133 | module_param(rptwear, uint, 0400); | ||
| 134 | module_param(overridesize, uint, 0400); | 134 | module_param(overridesize, uint, 0400); |
| 135 | module_param(cache_file, charp, 0400); | 135 | module_param(cache_file, charp, 0400); |
| 136 | module_param(bbt, uint, 0400); | 136 | module_param(bbt, uint, 0400); |
| @@ -162,7 +162,6 @@ MODULE_PARM_DESC(bitflips, "Maximum number of random bit flips per page (z | |||
| 162 | MODULE_PARM_DESC(gravepages, "Pages that lose data [: maximum reads (defaults to 3)]" | 162 | MODULE_PARM_DESC(gravepages, "Pages that lose data [: maximum reads (defaults to 3)]" |
| 163 | " separated by commas e.g. 1401:2 means page 1401" | 163 | " separated by commas e.g. 1401:2 means page 1401" |
| 164 | " can be read only twice before failing"); | 164 | " can be read only twice before failing"); |
| 165 | MODULE_PARM_DESC(rptwear, "Number of erases between reporting wear, if not zero"); | ||
| 166 | MODULE_PARM_DESC(overridesize, "Specifies the NAND Flash size overriding the ID bytes. " | 165 | MODULE_PARM_DESC(overridesize, "Specifies the NAND Flash size overriding the ID bytes. " |
| 167 | "The size is specified in erase blocks and as the exponent of a power of two" | 166 | "The size is specified in erase blocks and as the exponent of a power of two" |
| 168 | " e.g. 5 means a size of 32 erase blocks"); | 167 | " e.g. 5 means a size of 32 erase blocks"); |
| @@ -286,6 +285,11 @@ MODULE_PARM_DESC(bch, "Enable BCH ecc and set how many bits should " | |||
| 286 | /* Maximum page cache pages needed to read or write a NAND page to the cache_file */ | 285 | /* Maximum page cache pages needed to read or write a NAND page to the cache_file */ |
| 287 | #define NS_MAX_HELD_PAGES 16 | 286 | #define NS_MAX_HELD_PAGES 16 |
| 288 | 287 | ||
| 288 | struct nandsim_debug_info { | ||
| 289 | struct dentry *dfs_root; | ||
| 290 | struct dentry *dfs_wear_report; | ||
| 291 | }; | ||
| 292 | |||
| 289 | /* | 293 | /* |
| 290 | * A union to represent flash memory contents and flash buffer. | 294 | * A union to represent flash memory contents and flash buffer. |
| 291 | */ | 295 | */ |
| @@ -365,6 +369,8 @@ struct nandsim { | |||
| 365 | void *file_buf; | 369 | void *file_buf; |
| 366 | struct page *held_pages[NS_MAX_HELD_PAGES]; | 370 | struct page *held_pages[NS_MAX_HELD_PAGES]; |
| 367 | int held_cnt; | 371 | int held_cnt; |
| 372 | |||
| 373 | struct nandsim_debug_info dbg; | ||
| 368 | }; | 374 | }; |
| 369 | 375 | ||
| 370 | /* | 376 | /* |
| @@ -442,11 +448,123 @@ static LIST_HEAD(grave_pages); | |||
| 442 | static unsigned long *erase_block_wear = NULL; | 448 | static unsigned long *erase_block_wear = NULL; |
| 443 | static unsigned int wear_eb_count = 0; | 449 | static unsigned int wear_eb_count = 0; |
| 444 | static unsigned long total_wear = 0; | 450 | static unsigned long total_wear = 0; |
| 445 | static unsigned int rptwear_cnt = 0; | ||
| 446 | 451 | ||
| 447 | /* MTD structure for NAND controller */ | 452 | /* MTD structure for NAND controller */ |
| 448 | static struct mtd_info *nsmtd; | 453 | static struct mtd_info *nsmtd; |
| 449 | 454 | ||
| 455 | static int nandsim_debugfs_show(struct seq_file *m, void *private) | ||
| 456 | { | ||
| 457 | unsigned long wmin = -1, wmax = 0, avg; | ||
| 458 | unsigned long deciles[10], decile_max[10], tot = 0; | ||
| 459 | unsigned int i; | ||
| 460 | |||
| 461 | /* Calc wear stats */ | ||
| 462 | for (i = 0; i < wear_eb_count; ++i) { | ||
| 463 | unsigned long wear = erase_block_wear[i]; | ||
| 464 | if (wear < wmin) | ||
| 465 | wmin = wear; | ||
| 466 | if (wear > wmax) | ||
| 467 | wmax = wear; | ||
| 468 | tot += wear; | ||
| 469 | } | ||
| 470 | |||
| 471 | for (i = 0; i < 9; ++i) { | ||
| 472 | deciles[i] = 0; | ||
| 473 | decile_max[i] = (wmax * (i + 1) + 5) / 10; | ||
| 474 | } | ||
| 475 | deciles[9] = 0; | ||
| 476 | decile_max[9] = wmax; | ||
| 477 | for (i = 0; i < wear_eb_count; ++i) { | ||
| 478 | int d; | ||
| 479 | unsigned long wear = erase_block_wear[i]; | ||
| 480 | for (d = 0; d < 10; ++d) | ||
| 481 | if (wear <= decile_max[d]) { | ||
| 482 | deciles[d] += 1; | ||
| 483 | break; | ||
| 484 | } | ||
| 485 | } | ||
| 486 | avg = tot / wear_eb_count; | ||
| 487 | |||
| 488 | /* Output wear report */ | ||
| 489 | seq_printf(m, "Total numbers of erases: %lu\n", tot); | ||
| 490 | seq_printf(m, "Number of erase blocks: %u\n", wear_eb_count); | ||
| 491 | seq_printf(m, "Average number of erases: %lu\n", avg); | ||
| 492 | seq_printf(m, "Maximum number of erases: %lu\n", wmax); | ||
| 493 | seq_printf(m, "Minimum number of erases: %lu\n", wmin); | ||
| 494 | for (i = 0; i < 10; ++i) { | ||
| 495 | unsigned long from = (i ? decile_max[i - 1] + 1 : 0); | ||
| 496 | if (from > decile_max[i]) | ||
| 497 | continue; | ||
| 498 | seq_printf(m, "Number of ebs with erase counts from %lu to %lu : %lu\n", | ||
| 499 | from, | ||
| 500 | decile_max[i], | ||
| 501 | deciles[i]); | ||
| 502 | } | ||
| 503 | |||
| 504 | return 0; | ||
| 505 | } | ||
| 506 | |||
| 507 | static int nandsim_debugfs_open(struct inode *inode, struct file *file) | ||
| 508 | { | ||
| 509 | return single_open(file, nandsim_debugfs_show, inode->i_private); | ||
| 510 | } | ||
| 511 | |||
| 512 | static const struct file_operations dfs_fops = { | ||
| 513 | .open = nandsim_debugfs_open, | ||
| 514 | .read = seq_read, | ||
| 515 | .llseek = seq_lseek, | ||
| 516 | .release = single_release, | ||
| 517 | }; | ||
| 518 | |||
| 519 | /** | ||
| 520 | * nandsim_debugfs_create - initialize debugfs | ||
| 521 | * @dev: nandsim device description object | ||
| 522 | * | ||
| 523 | * This function creates all debugfs files for UBI device @ubi. Returns zero in | ||
| 524 | * case of success and a negative error code in case of failure. | ||
| 525 | */ | ||
| 526 | static int nandsim_debugfs_create(struct nandsim *dev) | ||
| 527 | { | ||
| 528 | struct nandsim_debug_info *dbg = &dev->dbg; | ||
| 529 | struct dentry *dent; | ||
| 530 | int err; | ||
| 531 | |||
| 532 | if (!IS_ENABLED(CONFIG_DEBUG_FS)) | ||
| 533 | return 0; | ||
| 534 | |||
| 535 | dent = debugfs_create_dir("nandsim", NULL); | ||
| 536 | if (IS_ERR_OR_NULL(dent)) { | ||
| 537 | int err = dent ? -ENODEV : PTR_ERR(dent); | ||
| 538 | |||
| 539 | NS_ERR("cannot create \"nandsim\" debugfs directory, err %d\n", | ||
| 540 | err); | ||
| 541 | return err; | ||
| 542 | } | ||
| 543 | dbg->dfs_root = dent; | ||
| 544 | |||
| 545 | dent = debugfs_create_file("wear_report", S_IRUSR, | ||
| 546 | dbg->dfs_root, dev, &dfs_fops); | ||
| 547 | if (IS_ERR_OR_NULL(dent)) | ||
| 548 | goto out_remove; | ||
| 549 | dbg->dfs_wear_report = dent; | ||
| 550 | |||
| 551 | return 0; | ||
| 552 | |||
| 553 | out_remove: | ||
| 554 | debugfs_remove_recursive(dbg->dfs_root); | ||
| 555 | err = dent ? PTR_ERR(dent) : -ENODEV; | ||
| 556 | return err; | ||
| 557 | } | ||
| 558 | |||
| 559 | /** | ||
| 560 | * nandsim_debugfs_remove - destroy all debugfs files | ||
| 561 | */ | ||
| 562 | static void nandsim_debugfs_remove(struct nandsim *ns) | ||
| 563 | { | ||
| 564 | if (IS_ENABLED(CONFIG_DEBUG_FS)) | ||
| 565 | debugfs_remove_recursive(ns->dbg.dfs_root); | ||
| 566 | } | ||
| 567 | |||
| 450 | /* | 568 | /* |
| 451 | * Allocate array of page pointers, create slab allocation for an array | 569 | * Allocate array of page pointers, create slab allocation for an array |
| 452 | * and initialize the array by NULL pointers. | 570 | * and initialize the array by NULL pointers. |
| @@ -911,8 +1029,6 @@ static int setup_wear_reporting(struct mtd_info *mtd) | |||
| 911 | { | 1029 | { |
| 912 | size_t mem; | 1030 | size_t mem; |
| 913 | 1031 | ||
| 914 | if (!rptwear) | ||
| 915 | return 0; | ||
| 916 | wear_eb_count = div_u64(mtd->size, mtd->erasesize); | 1032 | wear_eb_count = div_u64(mtd->size, mtd->erasesize); |
| 917 | mem = wear_eb_count * sizeof(unsigned long); | 1033 | mem = wear_eb_count * sizeof(unsigned long); |
| 918 | if (mem / sizeof(unsigned long) != wear_eb_count) { | 1034 | if (mem / sizeof(unsigned long) != wear_eb_count) { |
| @@ -929,64 +1045,18 @@ static int setup_wear_reporting(struct mtd_info *mtd) | |||
| 929 | 1045 | ||
| 930 | static void update_wear(unsigned int erase_block_no) | 1046 | static void update_wear(unsigned int erase_block_no) |
| 931 | { | 1047 | { |
| 932 | unsigned long wmin = -1, wmax = 0, avg; | ||
| 933 | unsigned long deciles[10], decile_max[10], tot = 0; | ||
| 934 | unsigned int i; | ||
| 935 | |||
| 936 | if (!erase_block_wear) | 1048 | if (!erase_block_wear) |
| 937 | return; | 1049 | return; |
| 938 | total_wear += 1; | 1050 | total_wear += 1; |
| 1051 | /* | ||
| 1052 | * TODO: Notify this through a debugfs entry, | ||
| 1053 | * instead of showing an error message. | ||
| 1054 | */ | ||
| 939 | if (total_wear == 0) | 1055 | if (total_wear == 0) |
| 940 | NS_ERR("Erase counter total overflow\n"); | 1056 | NS_ERR("Erase counter total overflow\n"); |
| 941 | erase_block_wear[erase_block_no] += 1; | 1057 | erase_block_wear[erase_block_no] += 1; |
| 942 | if (erase_block_wear[erase_block_no] == 0) | 1058 | if (erase_block_wear[erase_block_no] == 0) |
| 943 | NS_ERR("Erase counter overflow for erase block %u\n", erase_block_no); | 1059 | NS_ERR("Erase counter overflow for erase block %u\n", erase_block_no); |
| 944 | rptwear_cnt += 1; | ||
| 945 | if (rptwear_cnt < rptwear) | ||
| 946 | return; | ||
| 947 | rptwear_cnt = 0; | ||
| 948 | /* Calc wear stats */ | ||
| 949 | for (i = 0; i < wear_eb_count; ++i) { | ||
| 950 | unsigned long wear = erase_block_wear[i]; | ||
| 951 | if (wear < wmin) | ||
| 952 | wmin = wear; | ||
| 953 | if (wear > wmax) | ||
| 954 | wmax = wear; | ||
| 955 | tot += wear; | ||
| 956 | } | ||
| 957 | for (i = 0; i < 9; ++i) { | ||
| 958 | deciles[i] = 0; | ||
| 959 | decile_max[i] = (wmax * (i + 1) + 5) / 10; | ||
| 960 | } | ||
| 961 | deciles[9] = 0; | ||
| 962 | decile_max[9] = wmax; | ||
| 963 | for (i = 0; i < wear_eb_count; ++i) { | ||
| 964 | int d; | ||
| 965 | unsigned long wear = erase_block_wear[i]; | ||
| 966 | for (d = 0; d < 10; ++d) | ||
| 967 | if (wear <= decile_max[d]) { | ||
| 968 | deciles[d] += 1; | ||
| 969 | break; | ||
| 970 | } | ||
| 971 | } | ||
| 972 | avg = tot / wear_eb_count; | ||
| 973 | /* Output wear report */ | ||
| 974 | NS_INFO("*** Wear Report ***\n"); | ||
| 975 | NS_INFO("Total numbers of erases: %lu\n", tot); | ||
| 976 | NS_INFO("Number of erase blocks: %u\n", wear_eb_count); | ||
| 977 | NS_INFO("Average number of erases: %lu\n", avg); | ||
| 978 | NS_INFO("Maximum number of erases: %lu\n", wmax); | ||
| 979 | NS_INFO("Minimum number of erases: %lu\n", wmin); | ||
| 980 | for (i = 0; i < 10; ++i) { | ||
| 981 | unsigned long from = (i ? decile_max[i - 1] + 1 : 0); | ||
| 982 | if (from > decile_max[i]) | ||
| 983 | continue; | ||
| 984 | NS_INFO("Number of ebs with erase counts from %lu to %lu : %lu\n", | ||
| 985 | from, | ||
| 986 | decile_max[i], | ||
| 987 | deciles[i]); | ||
| 988 | } | ||
| 989 | NS_INFO("*** End of Wear Report ***\n"); | ||
| 990 | } | 1060 | } |
| 991 | 1061 | ||
| 992 | /* | 1062 | /* |
| @@ -2327,6 +2397,9 @@ static int __init ns_init_module(void) | |||
| 2327 | if ((retval = setup_wear_reporting(nsmtd)) != 0) | 2397 | if ((retval = setup_wear_reporting(nsmtd)) != 0) |
| 2328 | goto err_exit; | 2398 | goto err_exit; |
| 2329 | 2399 | ||
| 2400 | if ((retval = nandsim_debugfs_create(nand)) != 0) | ||
| 2401 | goto err_exit; | ||
| 2402 | |||
| 2330 | if ((retval = init_nandsim(nsmtd)) != 0) | 2403 | if ((retval = init_nandsim(nsmtd)) != 0) |
| 2331 | goto err_exit; | 2404 | goto err_exit; |
| 2332 | 2405 | ||
| @@ -2366,6 +2439,7 @@ static void __exit ns_cleanup_module(void) | |||
| 2366 | struct nandsim *ns = ((struct nand_chip *)nsmtd->priv)->priv; | 2439 | struct nandsim *ns = ((struct nand_chip *)nsmtd->priv)->priv; |
| 2367 | int i; | 2440 | int i; |
| 2368 | 2441 | ||
| 2442 | nandsim_debugfs_remove(ns); | ||
| 2369 | free_nandsim(ns); /* Free nandsim private resources */ | 2443 | free_nandsim(ns); /* Free nandsim private resources */ |
| 2370 | nand_release(nsmtd); /* Unregister driver */ | 2444 | nand_release(nsmtd); /* Unregister driver */ |
| 2371 | for (i = 0;i < ARRAY_SIZE(ns->partitions); ++i) | 2445 | for (i = 0;i < ARRAY_SIZE(ns->partitions); ++i) |
diff --git a/drivers/mtd/nand/ndfc.c b/drivers/mtd/nand/ndfc.c index 5fd3f010e3ae..8e148f1478fd 100644 --- a/drivers/mtd/nand/ndfc.c +++ b/drivers/mtd/nand/ndfc.c | |||
| @@ -197,7 +197,7 @@ err: | |||
| 197 | return ret; | 197 | return ret; |
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | static int __devinit ndfc_probe(struct platform_device *ofdev) | 200 | static int ndfc_probe(struct platform_device *ofdev) |
| 201 | { | 201 | { |
| 202 | struct ndfc_controller *ndfc; | 202 | struct ndfc_controller *ndfc; |
| 203 | const __be32 *reg; | 203 | const __be32 *reg; |
| @@ -256,7 +256,7 @@ static int __devinit ndfc_probe(struct platform_device *ofdev) | |||
| 256 | return 0; | 256 | return 0; |
| 257 | } | 257 | } |
| 258 | 258 | ||
| 259 | static int __devexit ndfc_remove(struct platform_device *ofdev) | 259 | static int ndfc_remove(struct platform_device *ofdev) |
| 260 | { | 260 | { |
| 261 | struct ndfc_controller *ndfc = dev_get_drvdata(&ofdev->dev); | 261 | struct ndfc_controller *ndfc = dev_get_drvdata(&ofdev->dev); |
| 262 | 262 | ||
| @@ -279,7 +279,7 @@ static struct platform_driver ndfc_driver = { | |||
| 279 | .of_match_table = ndfc_match, | 279 | .of_match_table = ndfc_match, |
| 280 | }, | 280 | }, |
| 281 | .probe = ndfc_probe, | 281 | .probe = ndfc_probe, |
| 282 | .remove = __devexit_p(ndfc_remove), | 282 | .remove = ndfc_remove, |
| 283 | }; | 283 | }; |
| 284 | 284 | ||
| 285 | module_platform_driver(ndfc_driver); | 285 | module_platform_driver(ndfc_driver); |
diff --git a/drivers/mtd/nand/nomadik_nand.c b/drivers/mtd/nand/nomadik_nand.c deleted file mode 100644 index 9ee0c4edfacf..000000000000 --- a/drivers/mtd/nand/nomadik_nand.c +++ /dev/null | |||
| @@ -1,235 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * drivers/mtd/nand/nomadik_nand.c | ||
| 3 | * | ||
| 4 | * Overview: | ||
| 5 | * Driver for on-board NAND flash on Nomadik Platforms | ||
| 6 | * | ||
| 7 | * Copyright © 2007 STMicroelectronics Pvt. Ltd. | ||
| 8 | * Author: Sachin Verma <sachin.verma@st.com> | ||
| 9 | * | ||
| 10 | * Copyright © 2009 Alessandro Rubini | ||
| 11 | * | ||
| 12 | * This program is free software; you can redistribute it and/or modify | ||
| 13 | * it under the terms of the GNU General Public License as published by | ||
| 14 | * the Free Software Foundation; either version 2 of the License, or | ||
| 15 | * (at your option) any later version. | ||
| 16 | * | ||
| 17 | * This program is distributed in the hope that it will be useful, | ||
| 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 20 | * GNU General Public License for more details. | ||
| 21 | * | ||
| 22 | */ | ||
| 23 | |||
| 24 | #include <linux/init.h> | ||
| 25 | #include <linux/module.h> | ||
| 26 | #include <linux/types.h> | ||
| 27 | #include <linux/mtd/mtd.h> | ||
| 28 | #include <linux/mtd/nand.h> | ||
| 29 | #include <linux/mtd/nand_ecc.h> | ||
| 30 | #include <linux/platform_device.h> | ||
| 31 | #include <linux/mtd/partitions.h> | ||
| 32 | #include <linux/io.h> | ||
| 33 | #include <linux/slab.h> | ||
| 34 | #include <linux/platform_data/mtd-nomadik-nand.h> | ||
| 35 | #include <mach/fsmc.h> | ||
| 36 | |||
| 37 | #include <mtd/mtd-abi.h> | ||
| 38 | |||
| 39 | struct nomadik_nand_host { | ||
| 40 | struct mtd_info mtd; | ||
| 41 | struct nand_chip nand; | ||
| 42 | void __iomem *data_va; | ||
| 43 | void __iomem *cmd_va; | ||
| 44 | void __iomem *addr_va; | ||
| 45 | struct nand_bbt_descr *bbt_desc; | ||
| 46 | }; | ||
| 47 | |||
| 48 | static struct nand_ecclayout nomadik_ecc_layout = { | ||
| 49 | .eccbytes = 3 * 4, | ||
| 50 | .eccpos = { /* each subpage has 16 bytes: pos 2,3,4 hosts ECC */ | ||
| 51 | 0x02, 0x03, 0x04, | ||
| 52 | 0x12, 0x13, 0x14, | ||
| 53 | 0x22, 0x23, 0x24, | ||
| 54 | 0x32, 0x33, 0x34}, | ||
| 55 | /* let's keep bytes 5,6,7 for us, just in case we change ECC algo */ | ||
| 56 | .oobfree = { {0x08, 0x08}, {0x18, 0x08}, {0x28, 0x08}, {0x38, 0x08} }, | ||
| 57 | }; | ||
| 58 | |||
| 59 | static void nomadik_ecc_control(struct mtd_info *mtd, int mode) | ||
| 60 | { | ||
| 61 | /* No need to enable hw ecc, it's on by default */ | ||
| 62 | } | ||
| 63 | |||
| 64 | static void nomadik_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) | ||
| 65 | { | ||
| 66 | struct nand_chip *nand = mtd->priv; | ||
| 67 | struct nomadik_nand_host *host = nand->priv; | ||
| 68 | |||
| 69 | if (cmd == NAND_CMD_NONE) | ||
| 70 | return; | ||
| 71 | |||
| 72 | if (ctrl & NAND_CLE) | ||
| 73 | writeb(cmd, host->cmd_va); | ||
| 74 | else | ||
| 75 | writeb(cmd, host->addr_va); | ||
| 76 | } | ||
| 77 | |||
| 78 | static int nomadik_nand_probe(struct platform_device *pdev) | ||
| 79 | { | ||
| 80 | struct nomadik_nand_platform_data *pdata = pdev->dev.platform_data; | ||
| 81 | struct nomadik_nand_host *host; | ||
| 82 | struct mtd_info *mtd; | ||
| 83 | struct nand_chip *nand; | ||
| 84 | struct resource *res; | ||
| 85 | int ret = 0; | ||
| 86 | |||
| 87 | /* Allocate memory for the device structure (and zero it) */ | ||
| 88 | host = kzalloc(sizeof(struct nomadik_nand_host), GFP_KERNEL); | ||
| 89 | if (!host) { | ||
| 90 | dev_err(&pdev->dev, "Failed to allocate device structure.\n"); | ||
| 91 | return -ENOMEM; | ||
| 92 | } | ||
| 93 | |||
| 94 | /* Call the client's init function, if any */ | ||
| 95 | if (pdata->init) | ||
| 96 | ret = pdata->init(); | ||
| 97 | if (ret < 0) { | ||
| 98 | dev_err(&pdev->dev, "Init function failed\n"); | ||
| 99 | goto err; | ||
| 100 | } | ||
| 101 | |||
| 102 | /* ioremap three regions */ | ||
| 103 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_addr"); | ||
| 104 | if (!res) { | ||
| 105 | ret = -EIO; | ||
| 106 | goto err_unmap; | ||
| 107 | } | ||
| 108 | host->addr_va = ioremap(res->start, resource_size(res)); | ||
| 109 | |||
| 110 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_data"); | ||
| 111 | if (!res) { | ||
| 112 | ret = -EIO; | ||
| 113 | goto err_unmap; | ||
| 114 | } | ||
| 115 | host->data_va = ioremap(res->start, resource_size(res)); | ||
| 116 | |||
| 117 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_cmd"); | ||
| 118 | if (!res) { | ||
| 119 | ret = -EIO; | ||
| 120 | goto err_unmap; | ||
| 121 | } | ||
| 122 | host->cmd_va = ioremap(res->start, resource_size(res)); | ||
| 123 | |||
| 124 | if (!host->addr_va || !host->data_va || !host->cmd_va) { | ||
| 125 | ret = -ENOMEM; | ||
| 126 | goto err_unmap; | ||
| 127 | } | ||
| 128 | |||
| 129 | /* Link all private pointers */ | ||
| 130 | mtd = &host->mtd; | ||
| 131 | nand = &host->nand; | ||
| 132 | mtd->priv = nand; | ||
| 133 | nand->priv = host; | ||
| 134 | |||
| 135 | host->mtd.owner = THIS_MODULE; | ||
| 136 | nand->IO_ADDR_R = host->data_va; | ||
| 137 | nand->IO_ADDR_W = host->data_va; | ||
| 138 | nand->cmd_ctrl = nomadik_cmd_ctrl; | ||
| 139 | |||
| 140 | /* | ||
| 141 | * This stanza declares ECC_HW but uses soft routines. It's because | ||
| 142 | * HW claims to make the calculation but not the correction. However, | ||
| 143 | * I haven't managed to get the desired data out of it until now. | ||
| 144 | */ | ||
| 145 | nand->ecc.mode = NAND_ECC_SOFT; | ||
| 146 | nand->ecc.layout = &nomadik_ecc_layout; | ||
| 147 | nand->ecc.hwctl = nomadik_ecc_control; | ||
| 148 | nand->ecc.size = 512; | ||
| 149 | nand->ecc.bytes = 3; | ||
| 150 | |||
| 151 | nand->options = pdata->options; | ||
| 152 | |||
| 153 | /* | ||
| 154 | * Scan to find existence of the device | ||
| 155 | */ | ||
| 156 | if (nand_scan(&host->mtd, 1)) { | ||
| 157 | ret = -ENXIO; | ||
| 158 | goto err_unmap; | ||
| 159 | } | ||
| 160 | |||
| 161 | mtd_device_register(&host->mtd, pdata->parts, pdata->nparts); | ||
| 162 | |||
| 163 | platform_set_drvdata(pdev, host); | ||
| 164 | return 0; | ||
| 165 | |||
| 166 | err_unmap: | ||
| 167 | if (host->cmd_va) | ||
| 168 | iounmap(host->cmd_va); | ||
| 169 | if (host->data_va) | ||
| 170 | iounmap(host->data_va); | ||
| 171 | if (host->addr_va) | ||
| 172 | iounmap(host->addr_va); | ||
| 173 | err: | ||
| 174 | kfree(host); | ||
| 175 | return ret; | ||
| 176 | } | ||
| 177 | |||
| 178 | /* | ||
| 179 | * Clean up routine | ||
| 180 | */ | ||
| 181 | static int nomadik_nand_remove(struct platform_device *pdev) | ||
| 182 | { | ||
| 183 | struct nomadik_nand_host *host = platform_get_drvdata(pdev); | ||
| 184 | struct nomadik_nand_platform_data *pdata = pdev->dev.platform_data; | ||
| 185 | |||
| 186 | if (pdata->exit) | ||
| 187 | pdata->exit(); | ||
| 188 | |||
| 189 | if (host) { | ||
| 190 | nand_release(&host->mtd); | ||
| 191 | iounmap(host->cmd_va); | ||
| 192 | iounmap(host->data_va); | ||
| 193 | iounmap(host->addr_va); | ||
| 194 | kfree(host); | ||
| 195 | } | ||
| 196 | return 0; | ||
| 197 | } | ||
| 198 | |||
| 199 | static int nomadik_nand_suspend(struct device *dev) | ||
| 200 | { | ||
| 201 | struct nomadik_nand_host *host = dev_get_drvdata(dev); | ||
| 202 | int ret = 0; | ||
| 203 | if (host) | ||
| 204 | ret = mtd_suspend(&host->mtd); | ||
| 205 | return ret; | ||
| 206 | } | ||
| 207 | |||
| 208 | static int nomadik_nand_resume(struct device *dev) | ||
| 209 | { | ||
| 210 | struct nomadik_nand_host *host = dev_get_drvdata(dev); | ||
| 211 | if (host) | ||
| 212 | mtd_resume(&host->mtd); | ||
| 213 | return 0; | ||
| 214 | } | ||
| 215 | |||
| 216 | static const struct dev_pm_ops nomadik_nand_pm_ops = { | ||
| 217 | .suspend = nomadik_nand_suspend, | ||
| 218 | .resume = nomadik_nand_resume, | ||
| 219 | }; | ||
| 220 | |||
| 221 | static struct platform_driver nomadik_nand_driver = { | ||
| 222 | .probe = nomadik_nand_probe, | ||
| 223 | .remove = nomadik_nand_remove, | ||
| 224 | .driver = { | ||
| 225 | .owner = THIS_MODULE, | ||
| 226 | .name = "nomadik_nand", | ||
| 227 | .pm = &nomadik_nand_pm_ops, | ||
| 228 | }, | ||
| 229 | }; | ||
| 230 | |||
| 231 | module_platform_driver(nomadik_nand_driver); | ||
| 232 | |||
| 233 | MODULE_LICENSE("GPL"); | ||
| 234 | MODULE_AUTHOR("ST Microelectronics (sachin.verma@st.com)"); | ||
| 235 | MODULE_DESCRIPTION("NAND driver for Nomadik Platform"); | ||
diff --git a/drivers/mtd/nand/nuc900_nand.c b/drivers/mtd/nand/nuc900_nand.c index 94dc46bc118c..a6191198d259 100644 --- a/drivers/mtd/nand/nuc900_nand.c +++ b/drivers/mtd/nand/nuc900_nand.c | |||
| @@ -246,7 +246,7 @@ static void nuc900_nand_enable(struct nuc900_nand *nand) | |||
| 246 | spin_unlock(&nand->lock); | 246 | spin_unlock(&nand->lock); |
| 247 | } | 247 | } |
| 248 | 248 | ||
| 249 | static int __devinit nuc900_nand_probe(struct platform_device *pdev) | 249 | static int nuc900_nand_probe(struct platform_device *pdev) |
| 250 | { | 250 | { |
| 251 | struct nuc900_nand *nuc900_nand; | 251 | struct nuc900_nand *nuc900_nand; |
| 252 | struct nand_chip *chip; | 252 | struct nand_chip *chip; |
| @@ -317,7 +317,7 @@ fail1: kfree(nuc900_nand); | |||
| 317 | return retval; | 317 | return retval; |
| 318 | } | 318 | } |
| 319 | 319 | ||
| 320 | static int __devexit nuc900_nand_remove(struct platform_device *pdev) | 320 | static int nuc900_nand_remove(struct platform_device *pdev) |
| 321 | { | 321 | { |
| 322 | struct nuc900_nand *nuc900_nand = platform_get_drvdata(pdev); | 322 | struct nuc900_nand *nuc900_nand = platform_get_drvdata(pdev); |
| 323 | struct resource *res; | 323 | struct resource *res; |
| @@ -340,7 +340,7 @@ static int __devexit nuc900_nand_remove(struct platform_device *pdev) | |||
| 340 | 340 | ||
| 341 | static struct platform_driver nuc900_nand_driver = { | 341 | static struct platform_driver nuc900_nand_driver = { |
| 342 | .probe = nuc900_nand_probe, | 342 | .probe = nuc900_nand_probe, |
| 343 | .remove = __devexit_p(nuc900_nand_remove), | 343 | .remove = nuc900_nand_remove, |
| 344 | .driver = { | 344 | .driver = { |
| 345 | .name = "nuc900-fmi", | 345 | .name = "nuc900-fmi", |
| 346 | .owner = THIS_MODULE, | 346 | .owner = THIS_MODULE, |
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index 1f34ba104ef4..0002d5e94f0d 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
| @@ -1323,7 +1323,7 @@ static void omap3_free_bch(struct mtd_info *mtd) | |||
| 1323 | } | 1323 | } |
| 1324 | #endif /* CONFIG_MTD_NAND_OMAP_BCH */ | 1324 | #endif /* CONFIG_MTD_NAND_OMAP_BCH */ |
| 1325 | 1325 | ||
| 1326 | static int __devinit omap_nand_probe(struct platform_device *pdev) | 1326 | static int omap_nand_probe(struct platform_device *pdev) |
| 1327 | { | 1327 | { |
| 1328 | struct omap_nand_info *info; | 1328 | struct omap_nand_info *info; |
| 1329 | struct omap_nand_platform_data *pdata; | 1329 | struct omap_nand_platform_data *pdata; |
diff --git a/drivers/mtd/nand/orion_nand.c b/drivers/mtd/nand/orion_nand.c index aefaf8cd31ef..cd72b9299f6b 100644 --- a/drivers/mtd/nand/orion_nand.c +++ b/drivers/mtd/nand/orion_nand.c | |||
| @@ -194,7 +194,7 @@ no_res: | |||
| 194 | return ret; | 194 | return ret; |
| 195 | } | 195 | } |
| 196 | 196 | ||
| 197 | static int __devexit orion_nand_remove(struct platform_device *pdev) | 197 | static int orion_nand_remove(struct platform_device *pdev) |
| 198 | { | 198 | { |
| 199 | struct mtd_info *mtd = platform_get_drvdata(pdev); | 199 | struct mtd_info *mtd = platform_get_drvdata(pdev); |
| 200 | struct nand_chip *nc = mtd->priv; | 200 | struct nand_chip *nc = mtd->priv; |
| @@ -223,7 +223,7 @@ static struct of_device_id orion_nand_of_match_table[] = { | |||
| 223 | #endif | 223 | #endif |
| 224 | 224 | ||
| 225 | static struct platform_driver orion_nand_driver = { | 225 | static struct platform_driver orion_nand_driver = { |
| 226 | .remove = __devexit_p(orion_nand_remove), | 226 | .remove = orion_nand_remove, |
| 227 | .driver = { | 227 | .driver = { |
| 228 | .name = "orion_nand", | 228 | .name = "orion_nand", |
| 229 | .owner = THIS_MODULE, | 229 | .owner = THIS_MODULE, |
diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index 1440e51cedcc..5a67082c07ee 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c | |||
| @@ -89,7 +89,7 @@ int pasemi_device_ready(struct mtd_info *mtd) | |||
| 89 | return !!(inl(lpcctl) & LBICTRL_LPCCTL_NR); | 89 | return !!(inl(lpcctl) & LBICTRL_LPCCTL_NR); |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | static int __devinit pasemi_nand_probe(struct platform_device *ofdev) | 92 | static int pasemi_nand_probe(struct platform_device *ofdev) |
| 93 | { | 93 | { |
| 94 | struct pci_dev *pdev; | 94 | struct pci_dev *pdev; |
| 95 | struct device_node *np = ofdev->dev.of_node; | 95 | struct device_node *np = ofdev->dev.of_node; |
| @@ -184,7 +184,7 @@ static int __devinit pasemi_nand_probe(struct platform_device *ofdev) | |||
| 184 | return err; | 184 | return err; |
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | static int __devexit pasemi_nand_remove(struct platform_device *ofdev) | 187 | static int pasemi_nand_remove(struct platform_device *ofdev) |
| 188 | { | 188 | { |
| 189 | struct nand_chip *chip; | 189 | struct nand_chip *chip; |
| 190 | 190 | ||
diff --git a/drivers/mtd/nand/plat_nand.c b/drivers/mtd/nand/plat_nand.c index a47ee68a0cfa..c004566a9ad2 100644 --- a/drivers/mtd/nand/plat_nand.c +++ b/drivers/mtd/nand/plat_nand.c | |||
| @@ -28,7 +28,7 @@ static const char *part_probe_types[] = { "cmdlinepart", NULL }; | |||
| 28 | /* | 28 | /* |
| 29 | * Probe for the NAND device. | 29 | * Probe for the NAND device. |
| 30 | */ | 30 | */ |
| 31 | static int __devinit plat_nand_probe(struct platform_device *pdev) | 31 | static int plat_nand_probe(struct platform_device *pdev) |
| 32 | { | 32 | { |
| 33 | struct platform_nand_data *pdata = pdev->dev.platform_data; | 33 | struct platform_nand_data *pdata = pdev->dev.platform_data; |
| 34 | struct mtd_part_parser_data ppdata; | 34 | struct mtd_part_parser_data ppdata; |
| @@ -134,7 +134,7 @@ out_free: | |||
| 134 | /* | 134 | /* |
| 135 | * Remove a NAND device. | 135 | * Remove a NAND device. |
| 136 | */ | 136 | */ |
| 137 | static int __devexit plat_nand_remove(struct platform_device *pdev) | 137 | static int plat_nand_remove(struct platform_device *pdev) |
| 138 | { | 138 | { |
| 139 | struct plat_nand_data *data = platform_get_drvdata(pdev); | 139 | struct plat_nand_data *data = platform_get_drvdata(pdev); |
| 140 | struct platform_nand_data *pdata = pdev->dev.platform_data; | 140 | struct platform_nand_data *pdata = pdev->dev.platform_data; |
| @@ -160,7 +160,7 @@ MODULE_DEVICE_TABLE(of, plat_nand_match); | |||
| 160 | 160 | ||
| 161 | static struct platform_driver plat_nand_driver = { | 161 | static struct platform_driver plat_nand_driver = { |
| 162 | .probe = plat_nand_probe, | 162 | .probe = plat_nand_probe, |
| 163 | .remove = __devexit_p(plat_nand_remove), | 163 | .remove = plat_nand_remove, |
| 164 | .driver = { | 164 | .driver = { |
| 165 | .name = "gen_nand", | 165 | .name = "gen_nand", |
| 166 | .owner = THIS_MODULE, | 166 | .owner = THIS_MODULE, |
diff --git a/drivers/mtd/nand/s3c2410.c b/drivers/mtd/nand/s3c2410.c index 79ded48e7427..df954b4dcba2 100644 --- a/drivers/mtd/nand/s3c2410.c +++ b/drivers/mtd/nand/s3c2410.c | |||
| @@ -730,11 +730,14 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info, | |||
| 730 | struct s3c2410_nand_mtd *mtd, | 730 | struct s3c2410_nand_mtd *mtd, |
| 731 | struct s3c2410_nand_set *set) | 731 | struct s3c2410_nand_set *set) |
| 732 | { | 732 | { |
| 733 | if (set) | 733 | if (set) { |
| 734 | mtd->mtd.name = set->name; | 734 | mtd->mtd.name = set->name; |
| 735 | 735 | ||
| 736 | return mtd_device_parse_register(&mtd->mtd, NULL, NULL, | 736 | return mtd_device_parse_register(&mtd->mtd, NULL, NULL, |
| 737 | set->partitions, set->nr_partitions); | 737 | set->partitions, set->nr_partitions); |
| 738 | } | ||
| 739 | |||
| 740 | return -ENODEV; | ||
| 738 | } | 741 | } |
| 739 | 742 | ||
| 740 | /** | 743 | /** |
diff --git a/drivers/mtd/nand/sh_flctl.c b/drivers/mtd/nand/sh_flctl.c index f48ac5d80bbf..57b3971c9c0a 100644 --- a/drivers/mtd/nand/sh_flctl.c +++ b/drivers/mtd/nand/sh_flctl.c | |||
| @@ -23,11 +23,18 @@ | |||
| 23 | 23 | ||
| 24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
| 25 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
| 26 | #include <linux/completion.h> | ||
| 26 | #include <linux/delay.h> | 27 | #include <linux/delay.h> |
| 28 | #include <linux/dmaengine.h> | ||
| 29 | #include <linux/dma-mapping.h> | ||
| 27 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
| 28 | #include <linux/io.h> | 31 | #include <linux/io.h> |
| 32 | #include <linux/of.h> | ||
| 33 | #include <linux/of_device.h> | ||
| 34 | #include <linux/of_mtd.h> | ||
| 29 | #include <linux/platform_device.h> | 35 | #include <linux/platform_device.h> |
| 30 | #include <linux/pm_runtime.h> | 36 | #include <linux/pm_runtime.h> |
| 37 | #include <linux/sh_dma.h> | ||
| 31 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
| 32 | #include <linux/string.h> | 39 | #include <linux/string.h> |
| 33 | 40 | ||
| @@ -106,6 +113,84 @@ static void wait_completion(struct sh_flctl *flctl) | |||
| 106 | writeb(0x0, FLTRCR(flctl)); | 113 | writeb(0x0, FLTRCR(flctl)); |
| 107 | } | 114 | } |
| 108 | 115 | ||
| 116 | static void flctl_dma_complete(void *param) | ||
| 117 | { | ||
| 118 | struct sh_flctl *flctl = param; | ||
| 119 | |||
| 120 | complete(&flctl->dma_complete); | ||
| 121 | } | ||
| 122 | |||
| 123 | static void flctl_release_dma(struct sh_flctl *flctl) | ||
| 124 | { | ||
| 125 | if (flctl->chan_fifo0_rx) { | ||
| 126 | dma_release_channel(flctl->chan_fifo0_rx); | ||
| 127 | flctl->chan_fifo0_rx = NULL; | ||
| 128 | } | ||
| 129 | if (flctl->chan_fifo0_tx) { | ||
| 130 | dma_release_channel(flctl->chan_fifo0_tx); | ||
| 131 | flctl->chan_fifo0_tx = NULL; | ||
| 132 | } | ||
| 133 | } | ||
| 134 | |||
| 135 | static void flctl_setup_dma(struct sh_flctl *flctl) | ||
| 136 | { | ||
| 137 | dma_cap_mask_t mask; | ||
| 138 | struct dma_slave_config cfg; | ||
| 139 | struct platform_device *pdev = flctl->pdev; | ||
| 140 | struct sh_flctl_platform_data *pdata = pdev->dev.platform_data; | ||
| 141 | int ret; | ||
| 142 | |||
| 143 | if (!pdata) | ||
| 144 | return; | ||
| 145 | |||
| 146 | if (pdata->slave_id_fifo0_tx <= 0 || pdata->slave_id_fifo0_rx <= 0) | ||
| 147 | return; | ||
| 148 | |||
| 149 | /* We can only either use DMA for both Tx and Rx or not use it at all */ | ||
| 150 | dma_cap_zero(mask); | ||
| 151 | dma_cap_set(DMA_SLAVE, mask); | ||
| 152 | |||
| 153 | flctl->chan_fifo0_tx = dma_request_channel(mask, shdma_chan_filter, | ||
| 154 | (void *)pdata->slave_id_fifo0_tx); | ||
| 155 | dev_dbg(&pdev->dev, "%s: TX: got channel %p\n", __func__, | ||
| 156 | flctl->chan_fifo0_tx); | ||
| 157 | |||
| 158 | if (!flctl->chan_fifo0_tx) | ||
| 159 | return; | ||
| 160 | |||
| 161 | memset(&cfg, 0, sizeof(cfg)); | ||
| 162 | cfg.slave_id = pdata->slave_id_fifo0_tx; | ||
| 163 | cfg.direction = DMA_MEM_TO_DEV; | ||
| 164 | cfg.dst_addr = (dma_addr_t)FLDTFIFO(flctl); | ||
| 165 | cfg.src_addr = 0; | ||
| 166 | ret = dmaengine_slave_config(flctl->chan_fifo0_tx, &cfg); | ||
| 167 | if (ret < 0) | ||
| 168 | goto err; | ||
| 169 | |||
| 170 | flctl->chan_fifo0_rx = dma_request_channel(mask, shdma_chan_filter, | ||
| 171 | (void *)pdata->slave_id_fifo0_rx); | ||
| 172 | dev_dbg(&pdev->dev, "%s: RX: got channel %p\n", __func__, | ||
| 173 | flctl->chan_fifo0_rx); | ||
| 174 | |||
| 175 | if (!flctl->chan_fifo0_rx) | ||
| 176 | goto err; | ||
| 177 | |||
| 178 | cfg.slave_id = pdata->slave_id_fifo0_rx; | ||
| 179 | cfg.direction = DMA_DEV_TO_MEM; | ||
| 180 | cfg.dst_addr = 0; | ||
| 181 | cfg.src_addr = (dma_addr_t)FLDTFIFO(flctl); | ||
| 182 | ret = dmaengine_slave_config(flctl->chan_fifo0_rx, &cfg); | ||
| 183 | if (ret < 0) | ||
| 184 | goto err; | ||
| 185 | |||
| 186 | init_completion(&flctl->dma_complete); | ||
| 187 | |||
| 188 | return; | ||
| 189 | |||
| 190 | err: | ||
| 191 | flctl_release_dma(flctl); | ||
| 192 | } | ||
| 193 | |||
| 109 | static void set_addr(struct mtd_info *mtd, int column, int page_addr) | 194 | static void set_addr(struct mtd_info *mtd, int column, int page_addr) |
| 110 | { | 195 | { |
| 111 | struct sh_flctl *flctl = mtd_to_flctl(mtd); | 196 | struct sh_flctl *flctl = mtd_to_flctl(mtd); |
| @@ -225,7 +310,7 @@ static enum flctl_ecc_res_t wait_recfifo_ready | |||
| 225 | 310 | ||
| 226 | for (i = 0; i < 3; i++) { | 311 | for (i = 0; i < 3; i++) { |
| 227 | uint8_t org; | 312 | uint8_t org; |
| 228 | int index; | 313 | unsigned int index; |
| 229 | 314 | ||
| 230 | data = readl(ecc_reg[i]); | 315 | data = readl(ecc_reg[i]); |
| 231 | 316 | ||
| @@ -261,6 +346,70 @@ static void wait_wecfifo_ready(struct sh_flctl *flctl) | |||
| 261 | timeout_error(flctl, __func__); | 346 | timeout_error(flctl, __func__); |
| 262 | } | 347 | } |
| 263 | 348 | ||
| 349 | static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf, | ||
| 350 | int len, enum dma_data_direction dir) | ||
| 351 | { | ||
| 352 | struct dma_async_tx_descriptor *desc = NULL; | ||
| 353 | struct dma_chan *chan; | ||
| 354 | enum dma_transfer_direction tr_dir; | ||
| 355 | dma_addr_t dma_addr; | ||
| 356 | dma_cookie_t cookie = -EINVAL; | ||
| 357 | uint32_t reg; | ||
| 358 | int ret; | ||
| 359 | |||
| 360 | if (dir == DMA_FROM_DEVICE) { | ||
| 361 | chan = flctl->chan_fifo0_rx; | ||
| 362 | tr_dir = DMA_DEV_TO_MEM; | ||
| 363 | } else { | ||
| 364 | chan = flctl->chan_fifo0_tx; | ||
| 365 | tr_dir = DMA_MEM_TO_DEV; | ||
| 366 | } | ||
| 367 | |||
| 368 | dma_addr = dma_map_single(chan->device->dev, buf, len, dir); | ||
| 369 | |||
| 370 | if (dma_addr) | ||
| 371 | desc = dmaengine_prep_slave_single(chan, dma_addr, len, | ||
| 372 | tr_dir, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); | ||
| 373 | |||
| 374 | if (desc) { | ||
| 375 | reg = readl(FLINTDMACR(flctl)); | ||
| 376 | reg |= DREQ0EN; | ||
| 377 | writel(reg, FLINTDMACR(flctl)); | ||
| 378 | |||
| 379 | desc->callback = flctl_dma_complete; | ||
| 380 | desc->callback_param = flctl; | ||
| 381 | cookie = dmaengine_submit(desc); | ||
| 382 | |||
| 383 | dma_async_issue_pending(chan); | ||
| 384 | } else { | ||
| 385 | /* DMA failed, fall back to PIO */ | ||
| 386 | flctl_release_dma(flctl); | ||
| 387 | dev_warn(&flctl->pdev->dev, | ||
| 388 | "DMA failed, falling back to PIO\n"); | ||
| 389 | ret = -EIO; | ||
| 390 | goto out; | ||
| 391 | } | ||
| 392 | |||
| 393 | ret = | ||
| 394 | wait_for_completion_timeout(&flctl->dma_complete, | ||
| 395 | msecs_to_jiffies(3000)); | ||
| 396 | |||
| 397 | if (ret <= 0) { | ||
| 398 | chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); | ||
| 399 | dev_err(&flctl->pdev->dev, "wait_for_completion_timeout\n"); | ||
| 400 | } | ||
| 401 | |||
| 402 | out: | ||
| 403 | reg = readl(FLINTDMACR(flctl)); | ||
| 404 | reg &= ~DREQ0EN; | ||
| 405 | writel(reg, FLINTDMACR(flctl)); | ||
| 406 | |||
| 407 | dma_unmap_single(chan->device->dev, dma_addr, len, dir); | ||
| 408 | |||
| 409 | /* ret > 0 is success */ | ||
| 410 | return ret; | ||
| 411 | } | ||
| 412 | |||
| 264 | static void read_datareg(struct sh_flctl *flctl, int offset) | 413 | static void read_datareg(struct sh_flctl *flctl, int offset) |
| 265 | { | 414 | { |
| 266 | unsigned long data; | 415 | unsigned long data; |
| @@ -279,11 +428,20 @@ static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset) | |||
| 279 | 428 | ||
| 280 | len_4align = (rlen + 3) / 4; | 429 | len_4align = (rlen + 3) / 4; |
| 281 | 430 | ||
| 431 | /* initiate DMA transfer */ | ||
| 432 | if (flctl->chan_fifo0_rx && rlen >= 32 && | ||
| 433 | flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_DEV_TO_MEM) > 0) | ||
| 434 | goto convert; /* DMA success */ | ||
| 435 | |||
| 436 | /* do polling transfer */ | ||
| 282 | for (i = 0; i < len_4align; i++) { | 437 | for (i = 0; i < len_4align; i++) { |
| 283 | wait_rfifo_ready(flctl); | 438 | wait_rfifo_ready(flctl); |
| 284 | buf[i] = readl(FLDTFIFO(flctl)); | 439 | buf[i] = readl(FLDTFIFO(flctl)); |
| 285 | buf[i] = be32_to_cpu(buf[i]); | ||
| 286 | } | 440 | } |
| 441 | |||
| 442 | convert: | ||
| 443 | for (i = 0; i < len_4align; i++) | ||
| 444 | buf[i] = be32_to_cpu(buf[i]); | ||
| 287 | } | 445 | } |
| 288 | 446 | ||
| 289 | static enum flctl_ecc_res_t read_ecfiforeg | 447 | static enum flctl_ecc_res_t read_ecfiforeg |
| @@ -305,28 +463,39 @@ static enum flctl_ecc_res_t read_ecfiforeg | |||
| 305 | return res; | 463 | return res; |
| 306 | } | 464 | } |
| 307 | 465 | ||
| 308 | static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset) | 466 | static void write_fiforeg(struct sh_flctl *flctl, int rlen, |
| 467 | unsigned int offset) | ||
| 309 | { | 468 | { |
| 310 | int i, len_4align; | 469 | int i, len_4align; |
| 311 | unsigned long *data = (unsigned long *)&flctl->done_buff[offset]; | 470 | unsigned long *buf = (unsigned long *)&flctl->done_buff[offset]; |
| 312 | void *fifo_addr = (void *)FLDTFIFO(flctl); | ||
| 313 | 471 | ||
| 314 | len_4align = (rlen + 3) / 4; | 472 | len_4align = (rlen + 3) / 4; |
| 315 | for (i = 0; i < len_4align; i++) { | 473 | for (i = 0; i < len_4align; i++) { |
| 316 | wait_wfifo_ready(flctl); | 474 | wait_wfifo_ready(flctl); |
| 317 | writel(cpu_to_be32(data[i]), fifo_addr); | 475 | writel(cpu_to_be32(buf[i]), FLDTFIFO(flctl)); |
| 318 | } | 476 | } |
| 319 | } | 477 | } |
| 320 | 478 | ||
| 321 | static void write_ec_fiforeg(struct sh_flctl *flctl, int rlen, int offset) | 479 | static void write_ec_fiforeg(struct sh_flctl *flctl, int rlen, |
| 480 | unsigned int offset) | ||
| 322 | { | 481 | { |
| 323 | int i, len_4align; | 482 | int i, len_4align; |
| 324 | unsigned long *data = (unsigned long *)&flctl->done_buff[offset]; | 483 | unsigned long *buf = (unsigned long *)&flctl->done_buff[offset]; |
| 325 | 484 | ||
| 326 | len_4align = (rlen + 3) / 4; | 485 | len_4align = (rlen + 3) / 4; |
| 486 | |||
| 487 | for (i = 0; i < len_4align; i++) | ||
| 488 | buf[i] = cpu_to_be32(buf[i]); | ||
| 489 | |||
| 490 | /* initiate DMA transfer */ | ||
| 491 | if (flctl->chan_fifo0_tx && rlen >= 32 && | ||
| 492 | flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_MEM_TO_DEV) > 0) | ||
| 493 | return; /* DMA success */ | ||
| 494 | |||
| 495 | /* do polling transfer */ | ||
| 327 | for (i = 0; i < len_4align; i++) { | 496 | for (i = 0; i < len_4align; i++) { |
| 328 | wait_wecfifo_ready(flctl); | 497 | wait_wecfifo_ready(flctl); |
| 329 | writel(cpu_to_be32(data[i]), FLECFIFO(flctl)); | 498 | writel(buf[i], FLECFIFO(flctl)); |
| 330 | } | 499 | } |
| 331 | } | 500 | } |
| 332 | 501 | ||
| @@ -750,41 +919,35 @@ static void flctl_select_chip(struct mtd_info *mtd, int chipnr) | |||
| 750 | static void flctl_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) | 919 | static void flctl_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) |
| 751 | { | 920 | { |
| 752 | struct sh_flctl *flctl = mtd_to_flctl(mtd); | 921 | struct sh_flctl *flctl = mtd_to_flctl(mtd); |
| 753 | int index = flctl->index; | ||
| 754 | 922 | ||
| 755 | memcpy(&flctl->done_buff[index], buf, len); | 923 | memcpy(&flctl->done_buff[flctl->index], buf, len); |
| 756 | flctl->index += len; | 924 | flctl->index += len; |
| 757 | } | 925 | } |
| 758 | 926 | ||
| 759 | static uint8_t flctl_read_byte(struct mtd_info *mtd) | 927 | static uint8_t flctl_read_byte(struct mtd_info *mtd) |
| 760 | { | 928 | { |
| 761 | struct sh_flctl *flctl = mtd_to_flctl(mtd); | 929 | struct sh_flctl *flctl = mtd_to_flctl(mtd); |
| 762 | int index = flctl->index; | ||
| 763 | uint8_t data; | 930 | uint8_t data; |
| 764 | 931 | ||
| 765 | data = flctl->done_buff[index]; | 932 | data = flctl->done_buff[flctl->index]; |
| 766 | flctl->index++; | 933 | flctl->index++; |
| 767 | return data; | 934 | return data; |
| 768 | } | 935 | } |
| 769 | 936 | ||
| 770 | static uint16_t flctl_read_word(struct mtd_info *mtd) | 937 | static uint16_t flctl_read_word(struct mtd_info *mtd) |
| 771 | { | 938 | { |
| 772 | struct sh_flctl *flctl = mtd_to_flctl(mtd); | 939 | struct sh_flctl *flctl = mtd_to_flctl(mtd); |
| 773 | int index = flctl->index; | 940 | uint16_t *buf = (uint16_t *)&flctl->done_buff[flctl->index]; |
| 774 | uint16_t data; | ||
| 775 | uint16_t *buf = (uint16_t *)&flctl->done_buff[index]; | ||
| 776 | 941 | ||
| 777 | data = *buf; | 942 | flctl->index += 2; |
| 778 | flctl->index += 2; | 943 | return *buf; |
| 779 | return data; | ||
| 780 | } | 944 | } |
| 781 | 945 | ||
| 782 | static void flctl_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) | 946 | static void flctl_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) |
| 783 | { | 947 | { |
| 784 | struct sh_flctl *flctl = mtd_to_flctl(mtd); | 948 | struct sh_flctl *flctl = mtd_to_flctl(mtd); |
| 785 | int index = flctl->index; | ||
| 786 | 949 | ||
| 787 | memcpy(buf, &flctl->done_buff[index], len); | 950 | memcpy(buf, &flctl->done_buff[flctl->index], len); |
| 788 | flctl->index += len; | 951 | flctl->index += len; |
| 789 | } | 952 | } |
| 790 | 953 | ||
| @@ -858,7 +1021,74 @@ static irqreturn_t flctl_handle_flste(int irq, void *dev_id) | |||
| 858 | return IRQ_HANDLED; | 1021 | return IRQ_HANDLED; |
| 859 | } | 1022 | } |
| 860 | 1023 | ||
| 861 | static int __devinit flctl_probe(struct platform_device *pdev) | 1024 | #ifdef CONFIG_OF |
| 1025 | struct flctl_soc_config { | ||
| 1026 | unsigned long flcmncr_val; | ||
| 1027 | unsigned has_hwecc:1; | ||
| 1028 | unsigned use_holden:1; | ||
| 1029 | }; | ||
| 1030 | |||
| 1031 | static struct flctl_soc_config flctl_sh7372_config = { | ||
| 1032 | .flcmncr_val = CLK_16B_12L_4H | TYPESEL_SET | SHBUSSEL, | ||
| 1033 | .has_hwecc = 1, | ||
| 1034 | .use_holden = 1, | ||
| 1035 | }; | ||
| 1036 | |||
| 1037 | static const struct of_device_id of_flctl_match[] = { | ||
| 1038 | { .compatible = "renesas,shmobile-flctl-sh7372", | ||
| 1039 | .data = &flctl_sh7372_config }, | ||
| 1040 | {}, | ||
| 1041 | }; | ||
| 1042 | MODULE_DEVICE_TABLE(of, of_flctl_match); | ||
| 1043 | |||
| 1044 | static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev) | ||
| 1045 | { | ||
| 1046 | const struct of_device_id *match; | ||
| 1047 | struct flctl_soc_config *config; | ||
| 1048 | struct sh_flctl_platform_data *pdata; | ||
| 1049 | struct device_node *dn = dev->of_node; | ||
| 1050 | int ret; | ||
| 1051 | |||
| 1052 | match = of_match_device(of_flctl_match, dev); | ||
| 1053 | if (match) | ||
| 1054 | config = (struct flctl_soc_config *)match->data; | ||
| 1055 | else { | ||
| 1056 | dev_err(dev, "%s: no OF configuration attached\n", __func__); | ||
| 1057 | return NULL; | ||
| 1058 | } | ||
| 1059 | |||
| 1060 | pdata = devm_kzalloc(dev, sizeof(struct sh_flctl_platform_data), | ||
| 1061 | GFP_KERNEL); | ||
| 1062 | if (!pdata) { | ||
| 1063 | dev_err(dev, "%s: failed to allocate config data\n", __func__); | ||
| 1064 | return NULL; | ||
| 1065 | } | ||
| 1066 | |||
| 1067 | /* set SoC specific options */ | ||
| 1068 | pdata->flcmncr_val = config->flcmncr_val; | ||
| 1069 | pdata->has_hwecc = config->has_hwecc; | ||
| 1070 | pdata->use_holden = config->use_holden; | ||
| 1071 | |||
| 1072 | /* parse user defined options */ | ||
| 1073 | ret = of_get_nand_bus_width(dn); | ||
| 1074 | if (ret == 16) | ||
| 1075 | pdata->flcmncr_val |= SEL_16BIT; | ||
| 1076 | else if (ret != 8) { | ||
| 1077 | dev_err(dev, "%s: invalid bus width\n", __func__); | ||
| 1078 | return NULL; | ||
| 1079 | } | ||
| 1080 | |||
| 1081 | return pdata; | ||
| 1082 | } | ||
| 1083 | #else /* CONFIG_OF */ | ||
| 1084 | #define of_flctl_match NULL | ||
| 1085 | static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev) | ||
| 1086 | { | ||
| 1087 | return NULL; | ||
| 1088 | } | ||
| 1089 | #endif /* CONFIG_OF */ | ||
| 1090 | |||
| 1091 | static int flctl_probe(struct platform_device *pdev) | ||
| 862 | { | 1092 | { |
| 863 | struct resource *res; | 1093 | struct resource *res; |
| 864 | struct sh_flctl *flctl; | 1094 | struct sh_flctl *flctl; |
| @@ -867,12 +1097,7 @@ static int __devinit flctl_probe(struct platform_device *pdev) | |||
| 867 | struct sh_flctl_platform_data *pdata; | 1097 | struct sh_flctl_platform_data *pdata; |
| 868 | int ret = -ENXIO; | 1098 | int ret = -ENXIO; |
| 869 | int irq; | 1099 | int irq; |
| 870 | 1100 | struct mtd_part_parser_data ppdata = {}; | |
| 871 | pdata = pdev->dev.platform_data; | ||
| 872 | if (pdata == NULL) { | ||
| 873 | dev_err(&pdev->dev, "no platform data defined\n"); | ||
| 874 | return -EINVAL; | ||
| 875 | } | ||
| 876 | 1101 | ||
| 877 | flctl = kzalloc(sizeof(struct sh_flctl), GFP_KERNEL); | 1102 | flctl = kzalloc(sizeof(struct sh_flctl), GFP_KERNEL); |
| 878 | if (!flctl) { | 1103 | if (!flctl) { |
| @@ -904,6 +1129,17 @@ static int __devinit flctl_probe(struct platform_device *pdev) | |||
| 904 | goto err_flste; | 1129 | goto err_flste; |
| 905 | } | 1130 | } |
| 906 | 1131 | ||
| 1132 | if (pdev->dev.of_node) | ||
| 1133 | pdata = flctl_parse_dt(&pdev->dev); | ||
| 1134 | else | ||
| 1135 | pdata = pdev->dev.platform_data; | ||
| 1136 | |||
| 1137 | if (!pdata) { | ||
| 1138 | dev_err(&pdev->dev, "no setup data defined\n"); | ||
| 1139 | ret = -EINVAL; | ||
| 1140 | goto err_pdata; | ||
| 1141 | } | ||
| 1142 | |||
| 907 | platform_set_drvdata(pdev, flctl); | 1143 | platform_set_drvdata(pdev, flctl); |
| 908 | flctl_mtd = &flctl->mtd; | 1144 | flctl_mtd = &flctl->mtd; |
| 909 | nand = &flctl->chip; | 1145 | nand = &flctl->chip; |
| @@ -932,6 +1168,8 @@ static int __devinit flctl_probe(struct platform_device *pdev) | |||
| 932 | pm_runtime_enable(&pdev->dev); | 1168 | pm_runtime_enable(&pdev->dev); |
| 933 | pm_runtime_resume(&pdev->dev); | 1169 | pm_runtime_resume(&pdev->dev); |
| 934 | 1170 | ||
| 1171 | flctl_setup_dma(flctl); | ||
| 1172 | |||
| 935 | ret = nand_scan_ident(flctl_mtd, 1, NULL); | 1173 | ret = nand_scan_ident(flctl_mtd, 1, NULL); |
| 936 | if (ret) | 1174 | if (ret) |
| 937 | goto err_chip; | 1175 | goto err_chip; |
| @@ -944,12 +1182,16 @@ static int __devinit flctl_probe(struct platform_device *pdev) | |||
| 944 | if (ret) | 1182 | if (ret) |
| 945 | goto err_chip; | 1183 | goto err_chip; |
| 946 | 1184 | ||
| 947 | mtd_device_register(flctl_mtd, pdata->parts, pdata->nr_parts); | 1185 | ppdata.of_node = pdev->dev.of_node; |
| 1186 | ret = mtd_device_parse_register(flctl_mtd, NULL, &ppdata, pdata->parts, | ||
| 1187 | pdata->nr_parts); | ||
| 948 | 1188 | ||
| 949 | return 0; | 1189 | return 0; |
| 950 | 1190 | ||
| 951 | err_chip: | 1191 | err_chip: |
| 1192 | flctl_release_dma(flctl); | ||
| 952 | pm_runtime_disable(&pdev->dev); | 1193 | pm_runtime_disable(&pdev->dev); |
| 1194 | err_pdata: | ||
| 953 | free_irq(irq, flctl); | 1195 | free_irq(irq, flctl); |
| 954 | err_flste: | 1196 | err_flste: |
| 955 | iounmap(flctl->reg); | 1197 | iounmap(flctl->reg); |
| @@ -958,10 +1200,11 @@ err_iomap: | |||
| 958 | return ret; | 1200 | return ret; |
| 959 | } | 1201 | } |
| 960 | 1202 | ||
| 961 | static int __devexit flctl_remove(struct platform_device *pdev) | 1203 | static int flctl_remove(struct platform_device *pdev) |
| 962 | { | 1204 | { |
| 963 | struct sh_flctl *flctl = platform_get_drvdata(pdev); | 1205 | struct sh_flctl *flctl = platform_get_drvdata(pdev); |
| 964 | 1206 | ||
| 1207 | flctl_release_dma(flctl); | ||
| 965 | nand_release(&flctl->mtd); | 1208 | nand_release(&flctl->mtd); |
| 966 | pm_runtime_disable(&pdev->dev); | 1209 | pm_runtime_disable(&pdev->dev); |
| 967 | free_irq(platform_get_irq(pdev, 0), flctl); | 1210 | free_irq(platform_get_irq(pdev, 0), flctl); |
| @@ -976,6 +1219,7 @@ static struct platform_driver flctl_driver = { | |||
| 976 | .driver = { | 1219 | .driver = { |
| 977 | .name = "sh_flctl", | 1220 | .name = "sh_flctl", |
| 978 | .owner = THIS_MODULE, | 1221 | .owner = THIS_MODULE, |
| 1222 | .of_match_table = of_flctl_match, | ||
| 979 | }, | 1223 | }, |
| 980 | }; | 1224 | }; |
| 981 | 1225 | ||
diff --git a/drivers/mtd/nand/sharpsl.c b/drivers/mtd/nand/sharpsl.c index 3421e3762a5a..127bc4271821 100644 --- a/drivers/mtd/nand/sharpsl.c +++ b/drivers/mtd/nand/sharpsl.c | |||
| @@ -106,7 +106,7 @@ static int sharpsl_nand_calculate_ecc(struct mtd_info *mtd, const u_char * dat, | |||
| 106 | /* | 106 | /* |
| 107 | * Main initialization routine | 107 | * Main initialization routine |
| 108 | */ | 108 | */ |
| 109 | static int __devinit sharpsl_nand_probe(struct platform_device *pdev) | 109 | static int sharpsl_nand_probe(struct platform_device *pdev) |
| 110 | { | 110 | { |
| 111 | struct nand_chip *this; | 111 | struct nand_chip *this; |
| 112 | struct resource *r; | 112 | struct resource *r; |
| @@ -205,7 +205,7 @@ err_get_res: | |||
| 205 | /* | 205 | /* |
| 206 | * Clean up routine | 206 | * Clean up routine |
| 207 | */ | 207 | */ |
| 208 | static int __devexit sharpsl_nand_remove(struct platform_device *pdev) | 208 | static int sharpsl_nand_remove(struct platform_device *pdev) |
| 209 | { | 209 | { |
| 210 | struct sharpsl_nand *sharpsl = platform_get_drvdata(pdev); | 210 | struct sharpsl_nand *sharpsl = platform_get_drvdata(pdev); |
| 211 | 211 | ||
| @@ -228,7 +228,7 @@ static struct platform_driver sharpsl_nand_driver = { | |||
| 228 | .owner = THIS_MODULE, | 228 | .owner = THIS_MODULE, |
| 229 | }, | 229 | }, |
| 230 | .probe = sharpsl_nand_probe, | 230 | .probe = sharpsl_nand_probe, |
| 231 | .remove = __devexit_p(sharpsl_nand_remove), | 231 | .remove = sharpsl_nand_remove, |
| 232 | }; | 232 | }; |
| 233 | 233 | ||
| 234 | module_platform_driver(sharpsl_nand_driver); | 234 | module_platform_driver(sharpsl_nand_driver); |
diff --git a/drivers/mtd/nand/socrates_nand.c b/drivers/mtd/nand/socrates_nand.c index f3f28fafbf7a..09dde7d27178 100644 --- a/drivers/mtd/nand/socrates_nand.c +++ b/drivers/mtd/nand/socrates_nand.c | |||
| @@ -140,7 +140,7 @@ static int socrates_nand_device_ready(struct mtd_info *mtd) | |||
| 140 | /* | 140 | /* |
| 141 | * Probe for the NAND device. | 141 | * Probe for the NAND device. |
| 142 | */ | 142 | */ |
| 143 | static int __devinit socrates_nand_probe(struct platform_device *ofdev) | 143 | static int socrates_nand_probe(struct platform_device *ofdev) |
| 144 | { | 144 | { |
| 145 | struct socrates_nand_host *host; | 145 | struct socrates_nand_host *host; |
| 146 | struct mtd_info *mtd; | 146 | struct mtd_info *mtd; |
| @@ -220,7 +220,7 @@ out: | |||
| 220 | /* | 220 | /* |
| 221 | * Remove a NAND device. | 221 | * Remove a NAND device. |
| 222 | */ | 222 | */ |
| 223 | static int __devexit socrates_nand_remove(struct platform_device *ofdev) | 223 | static int socrates_nand_remove(struct platform_device *ofdev) |
| 224 | { | 224 | { |
| 225 | struct socrates_nand_host *host = dev_get_drvdata(&ofdev->dev); | 225 | struct socrates_nand_host *host = dev_get_drvdata(&ofdev->dev); |
| 226 | struct mtd_info *mtd = &host->mtd; | 226 | struct mtd_info *mtd = &host->mtd; |
| @@ -251,7 +251,7 @@ static struct platform_driver socrates_nand_driver = { | |||
| 251 | .of_match_table = socrates_nand_match, | 251 | .of_match_table = socrates_nand_match, |
| 252 | }, | 252 | }, |
| 253 | .probe = socrates_nand_probe, | 253 | .probe = socrates_nand_probe, |
| 254 | .remove = __devexit_p(socrates_nand_remove), | 254 | .remove = socrates_nand_remove, |
| 255 | }; | 255 | }; |
| 256 | 256 | ||
| 257 | module_platform_driver(socrates_nand_driver); | 257 | module_platform_driver(socrates_nand_driver); |
diff --git a/drivers/mtd/ofpart.c b/drivers/mtd/ofpart.c index d9127e2ed808..dbd3aa574eaf 100644 --- a/drivers/mtd/ofpart.c +++ b/drivers/mtd/ofpart.c | |||
| @@ -71,7 +71,10 @@ static int parse_ofpart_partitions(struct mtd_info *master, | |||
| 71 | (*pparts)[i].name = (char *)partname; | 71 | (*pparts)[i].name = (char *)partname; |
| 72 | 72 | ||
| 73 | if (of_get_property(pp, "read-only", &len)) | 73 | if (of_get_property(pp, "read-only", &len)) |
| 74 | (*pparts)[i].mask_flags = MTD_WRITEABLE; | 74 | (*pparts)[i].mask_flags |= MTD_WRITEABLE; |
| 75 | |||
| 76 | if (of_get_property(pp, "lock", &len)) | ||
| 77 | (*pparts)[i].mask_flags |= MTD_POWERUP_LOCK; | ||
| 75 | 78 | ||
| 76 | i++; | 79 | i++; |
| 77 | } | 80 | } |
diff --git a/drivers/mtd/onenand/generic.c b/drivers/mtd/onenand/generic.c index 1c4f97c63e62..9f11562f849d 100644 --- a/drivers/mtd/onenand/generic.c +++ b/drivers/mtd/onenand/generic.c | |||
| @@ -35,7 +35,7 @@ struct onenand_info { | |||
| 35 | struct onenand_chip onenand; | 35 | struct onenand_chip onenand; |
| 36 | }; | 36 | }; |
| 37 | 37 | ||
| 38 | static int __devinit generic_onenand_probe(struct platform_device *pdev) | 38 | static int generic_onenand_probe(struct platform_device *pdev) |
| 39 | { | 39 | { |
| 40 | struct onenand_info *info; | 40 | struct onenand_info *info; |
| 41 | struct onenand_platform_data *pdata = pdev->dev.platform_data; | 41 | struct onenand_platform_data *pdata = pdev->dev.platform_data; |
| @@ -88,7 +88,7 @@ out_free_info: | |||
| 88 | return err; | 88 | return err; |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | static int __devexit generic_onenand_remove(struct platform_device *pdev) | 91 | static int generic_onenand_remove(struct platform_device *pdev) |
| 92 | { | 92 | { |
| 93 | struct onenand_info *info = platform_get_drvdata(pdev); | 93 | struct onenand_info *info = platform_get_drvdata(pdev); |
| 94 | struct resource *res = pdev->resource; | 94 | struct resource *res = pdev->resource; |
| @@ -112,7 +112,7 @@ static struct platform_driver generic_onenand_driver = { | |||
| 112 | .owner = THIS_MODULE, | 112 | .owner = THIS_MODULE, |
| 113 | }, | 113 | }, |
| 114 | .probe = generic_onenand_probe, | 114 | .probe = generic_onenand_probe, |
| 115 | .remove = __devexit_p(generic_onenand_remove), | 115 | .remove = generic_onenand_remove, |
| 116 | }; | 116 | }; |
| 117 | 117 | ||
| 118 | module_platform_driver(generic_onenand_driver); | 118 | module_platform_driver(generic_onenand_driver); |
diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c index 00cd3da29435..065f3fe02a2f 100644 --- a/drivers/mtd/onenand/omap2.c +++ b/drivers/mtd/onenand/omap2.c | |||
| @@ -630,7 +630,7 @@ static int omap2_onenand_disable(struct mtd_info *mtd) | |||
| 630 | return ret; | 630 | return ret; |
| 631 | } | 631 | } |
| 632 | 632 | ||
| 633 | static int __devinit omap2_onenand_probe(struct platform_device *pdev) | 633 | static int omap2_onenand_probe(struct platform_device *pdev) |
| 634 | { | 634 | { |
| 635 | struct omap_onenand_platform_data *pdata; | 635 | struct omap_onenand_platform_data *pdata; |
| 636 | struct omap2_onenand *c; | 636 | struct omap2_onenand *c; |
| @@ -799,7 +799,7 @@ err_kfree: | |||
| 799 | return r; | 799 | return r; |
| 800 | } | 800 | } |
| 801 | 801 | ||
| 802 | static int __devexit omap2_onenand_remove(struct platform_device *pdev) | 802 | static int omap2_onenand_remove(struct platform_device *pdev) |
| 803 | { | 803 | { |
| 804 | struct omap2_onenand *c = dev_get_drvdata(&pdev->dev); | 804 | struct omap2_onenand *c = dev_get_drvdata(&pdev->dev); |
| 805 | 805 | ||
| @@ -822,7 +822,7 @@ static int __devexit omap2_onenand_remove(struct platform_device *pdev) | |||
| 822 | 822 | ||
| 823 | static struct platform_driver omap2_onenand_driver = { | 823 | static struct platform_driver omap2_onenand_driver = { |
| 824 | .probe = omap2_onenand_probe, | 824 | .probe = omap2_onenand_probe, |
| 825 | .remove = __devexit_p(omap2_onenand_remove), | 825 | .remove = omap2_onenand_remove, |
| 826 | .shutdown = omap2_onenand_shutdown, | 826 | .shutdown = omap2_onenand_shutdown, |
| 827 | .driver = { | 827 | .driver = { |
| 828 | .name = DRIVER_NAME, | 828 | .name = DRIVER_NAME, |
diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/onenand/samsung.c index 8e4b3f2742ba..33f2a8fb8df9 100644 --- a/drivers/mtd/onenand/samsung.c +++ b/drivers/mtd/onenand/samsung.c | |||
| @@ -1053,7 +1053,7 @@ onenand_fail: | |||
| 1053 | return err; | 1053 | return err; |
| 1054 | } | 1054 | } |
| 1055 | 1055 | ||
| 1056 | static int __devexit s3c_onenand_remove(struct platform_device *pdev) | 1056 | static int s3c_onenand_remove(struct platform_device *pdev) |
| 1057 | { | 1057 | { |
| 1058 | struct mtd_info *mtd = platform_get_drvdata(pdev); | 1058 | struct mtd_info *mtd = platform_get_drvdata(pdev); |
| 1059 | 1059 | ||
| @@ -1130,7 +1130,7 @@ static struct platform_driver s3c_onenand_driver = { | |||
| 1130 | }, | 1130 | }, |
| 1131 | .id_table = s3c_onenand_driver_ids, | 1131 | .id_table = s3c_onenand_driver_ids, |
| 1132 | .probe = s3c_onenand_probe, | 1132 | .probe = s3c_onenand_probe, |
| 1133 | .remove = __devexit_p(s3c_onenand_remove), | 1133 | .remove = s3c_onenand_remove, |
| 1134 | }; | 1134 | }; |
| 1135 | 1135 | ||
| 1136 | module_platform_driver(s3c_onenand_driver); | 1136 | module_platform_driver(s3c_onenand_driver); |
diff --git a/drivers/mtd/tests/mtd_nandbiterrs.c b/drivers/mtd/tests/mtd_nandbiterrs.c index cc8d62cb280c..207bf9a9972f 100644 --- a/drivers/mtd/tests/mtd_nandbiterrs.c +++ b/drivers/mtd/tests/mtd_nandbiterrs.c | |||
| @@ -39,6 +39,9 @@ | |||
| 39 | * this program; see the file COPYING. If not, write to the Free Software | 39 | * this program; see the file COPYING. If not, write to the Free Software |
| 40 | * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 40 | * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| 41 | */ | 41 | */ |
| 42 | |||
| 43 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 44 | |||
| 42 | #include <linux/init.h> | 45 | #include <linux/init.h> |
| 43 | #include <linux/module.h> | 46 | #include <linux/module.h> |
| 44 | #include <linux/moduleparam.h> | 47 | #include <linux/moduleparam.h> |
| @@ -47,8 +50,6 @@ | |||
| 47 | #include <linux/mtd/nand.h> | 50 | #include <linux/mtd/nand.h> |
| 48 | #include <linux/slab.h> | 51 | #include <linux/slab.h> |
| 49 | 52 | ||
| 50 | #define msg(FMT, VA...) pr_info("mtd_nandbiterrs: "FMT, ##VA) | ||
| 51 | |||
| 52 | static int dev; | 53 | static int dev; |
| 53 | module_param(dev, int, S_IRUGO); | 54 | module_param(dev, int, S_IRUGO); |
| 54 | MODULE_PARM_DESC(dev, "MTD device number to use"); | 55 | MODULE_PARM_DESC(dev, "MTD device number to use"); |
| @@ -103,7 +104,7 @@ static int erase_block(void) | |||
| 103 | struct erase_info ei; | 104 | struct erase_info ei; |
| 104 | loff_t addr = eraseblock * mtd->erasesize; | 105 | loff_t addr = eraseblock * mtd->erasesize; |
| 105 | 106 | ||
| 106 | msg("erase_block\n"); | 107 | pr_info("erase_block\n"); |
| 107 | 108 | ||
| 108 | memset(&ei, 0, sizeof(struct erase_info)); | 109 | memset(&ei, 0, sizeof(struct erase_info)); |
| 109 | ei.mtd = mtd; | 110 | ei.mtd = mtd; |
| @@ -112,7 +113,7 @@ static int erase_block(void) | |||
| 112 | 113 | ||
| 113 | err = mtd_erase(mtd, &ei); | 114 | err = mtd_erase(mtd, &ei); |
| 114 | if (err || ei.state == MTD_ERASE_FAILED) { | 115 | if (err || ei.state == MTD_ERASE_FAILED) { |
| 115 | msg("error %d while erasing\n", err); | 116 | pr_err("error %d while erasing\n", err); |
| 116 | if (!err) | 117 | if (!err) |
| 117 | err = -EIO; | 118 | err = -EIO; |
| 118 | return err; | 119 | return err; |
| @@ -128,11 +129,11 @@ static int write_page(int log) | |||
| 128 | size_t written; | 129 | size_t written; |
| 129 | 130 | ||
| 130 | if (log) | 131 | if (log) |
| 131 | msg("write_page\n"); | 132 | pr_info("write_page\n"); |
| 132 | 133 | ||
| 133 | err = mtd_write(mtd, offset, mtd->writesize, &written, wbuffer); | 134 | err = mtd_write(mtd, offset, mtd->writesize, &written, wbuffer); |
| 134 | if (err || written != mtd->writesize) { | 135 | if (err || written != mtd->writesize) { |
| 135 | msg("error: write failed at %#llx\n", (long long)offset); | 136 | pr_err("error: write failed at %#llx\n", (long long)offset); |
| 136 | if (!err) | 137 | if (!err) |
| 137 | err = -EIO; | 138 | err = -EIO; |
| 138 | } | 139 | } |
| @@ -147,7 +148,7 @@ static int rewrite_page(int log) | |||
| 147 | struct mtd_oob_ops ops; | 148 | struct mtd_oob_ops ops; |
| 148 | 149 | ||
| 149 | if (log) | 150 | if (log) |
| 150 | msg("rewrite page\n"); | 151 | pr_info("rewrite page\n"); |
| 151 | 152 | ||
| 152 | ops.mode = MTD_OPS_RAW; /* No ECC */ | 153 | ops.mode = MTD_OPS_RAW; /* No ECC */ |
| 153 | ops.len = mtd->writesize; | 154 | ops.len = mtd->writesize; |
| @@ -160,7 +161,7 @@ static int rewrite_page(int log) | |||
| 160 | 161 | ||
| 161 | err = mtd_write_oob(mtd, offset, &ops); | 162 | err = mtd_write_oob(mtd, offset, &ops); |
| 162 | if (err || ops.retlen != mtd->writesize) { | 163 | if (err || ops.retlen != mtd->writesize) { |
| 163 | msg("error: write_oob failed (%d)\n", err); | 164 | pr_err("error: write_oob failed (%d)\n", err); |
| 164 | if (!err) | 165 | if (!err) |
| 165 | err = -EIO; | 166 | err = -EIO; |
| 166 | } | 167 | } |
| @@ -177,7 +178,7 @@ static int read_page(int log) | |||
| 177 | struct mtd_ecc_stats oldstats; | 178 | struct mtd_ecc_stats oldstats; |
| 178 | 179 | ||
| 179 | if (log) | 180 | if (log) |
| 180 | msg("read_page\n"); | 181 | pr_info("read_page\n"); |
| 181 | 182 | ||
| 182 | /* Saving last mtd stats */ | 183 | /* Saving last mtd stats */ |
| 183 | memcpy(&oldstats, &mtd->ecc_stats, sizeof(oldstats)); | 184 | memcpy(&oldstats, &mtd->ecc_stats, sizeof(oldstats)); |
| @@ -187,7 +188,7 @@ static int read_page(int log) | |||
| 187 | err = mtd->ecc_stats.corrected - oldstats.corrected; | 188 | err = mtd->ecc_stats.corrected - oldstats.corrected; |
| 188 | 189 | ||
| 189 | if (err < 0 || read != mtd->writesize) { | 190 | if (err < 0 || read != mtd->writesize) { |
| 190 | msg("error: read failed at %#llx\n", (long long)offset); | 191 | pr_err("error: read failed at %#llx\n", (long long)offset); |
| 191 | if (err >= 0) | 192 | if (err >= 0) |
| 192 | err = -EIO; | 193 | err = -EIO; |
| 193 | } | 194 | } |
| @@ -201,11 +202,11 @@ static int verify_page(int log) | |||
| 201 | unsigned i, errs = 0; | 202 | unsigned i, errs = 0; |
| 202 | 203 | ||
| 203 | if (log) | 204 | if (log) |
| 204 | msg("verify_page\n"); | 205 | pr_info("verify_page\n"); |
| 205 | 206 | ||
| 206 | for (i = 0; i < mtd->writesize; i++) { | 207 | for (i = 0; i < mtd->writesize; i++) { |
| 207 | if (rbuffer[i] != hash(i+seed)) { | 208 | if (rbuffer[i] != hash(i+seed)) { |
| 208 | msg("Error: page offset %u, expected %02x, got %02x\n", | 209 | pr_err("Error: page offset %u, expected %02x, got %02x\n", |
| 209 | i, hash(i+seed), rbuffer[i]); | 210 | i, hash(i+seed), rbuffer[i]); |
| 210 | errs++; | 211 | errs++; |
| 211 | } | 212 | } |
| @@ -230,13 +231,13 @@ static int insert_biterror(unsigned byte) | |||
| 230 | for (bit = 7; bit >= 0; bit--) { | 231 | for (bit = 7; bit >= 0; bit--) { |
| 231 | if (CBIT(wbuffer[byte], bit)) { | 232 | if (CBIT(wbuffer[byte], bit)) { |
| 232 | BCLR(wbuffer[byte], bit); | 233 | BCLR(wbuffer[byte], bit); |
| 233 | msg("Inserted biterror @ %u/%u\n", byte, bit); | 234 | pr_info("Inserted biterror @ %u/%u\n", byte, bit); |
| 234 | return 0; | 235 | return 0; |
| 235 | } | 236 | } |
| 236 | } | 237 | } |
| 237 | byte++; | 238 | byte++; |
| 238 | } | 239 | } |
| 239 | msg("biterror: Failed to find a '1' bit\n"); | 240 | pr_err("biterror: Failed to find a '1' bit\n"); |
| 240 | return -EIO; | 241 | return -EIO; |
| 241 | } | 242 | } |
| 242 | 243 | ||
| @@ -248,7 +249,7 @@ static int incremental_errors_test(void) | |||
| 248 | unsigned i; | 249 | unsigned i; |
| 249 | unsigned errs_per_subpage = 0; | 250 | unsigned errs_per_subpage = 0; |
| 250 | 251 | ||
| 251 | msg("incremental biterrors test\n"); | 252 | pr_info("incremental biterrors test\n"); |
| 252 | 253 | ||
| 253 | for (i = 0; i < mtd->writesize; i++) | 254 | for (i = 0; i < mtd->writesize; i++) |
| 254 | wbuffer[i] = hash(i+seed); | 255 | wbuffer[i] = hash(i+seed); |
| @@ -265,9 +266,9 @@ static int incremental_errors_test(void) | |||
| 265 | 266 | ||
| 266 | err = read_page(1); | 267 | err = read_page(1); |
| 267 | if (err > 0) | 268 | if (err > 0) |
| 268 | msg("Read reported %d corrected bit errors\n", err); | 269 | pr_info("Read reported %d corrected bit errors\n", err); |
| 269 | if (err < 0) { | 270 | if (err < 0) { |
| 270 | msg("After %d biterrors per subpage, read reported error %d\n", | 271 | pr_err("After %d biterrors per subpage, read reported error %d\n", |
| 271 | errs_per_subpage, err); | 272 | errs_per_subpage, err); |
| 272 | err = 0; | 273 | err = 0; |
| 273 | goto exit; | 274 | goto exit; |
| @@ -275,11 +276,11 @@ static int incremental_errors_test(void) | |||
| 275 | 276 | ||
| 276 | err = verify_page(1); | 277 | err = verify_page(1); |
| 277 | if (err) { | 278 | if (err) { |
| 278 | msg("ECC failure, read data is incorrect despite read success\n"); | 279 | pr_err("ECC failure, read data is incorrect despite read success\n"); |
| 279 | goto exit; | 280 | goto exit; |
| 280 | } | 281 | } |
| 281 | 282 | ||
| 282 | msg("Successfully corrected %d bit errors per subpage\n", | 283 | pr_info("Successfully corrected %d bit errors per subpage\n", |
| 283 | errs_per_subpage); | 284 | errs_per_subpage); |
| 284 | 285 | ||
| 285 | for (i = 0; i < subcount; i++) { | 286 | for (i = 0; i < subcount; i++) { |
| @@ -311,7 +312,7 @@ static int overwrite_test(void) | |||
| 311 | 312 | ||
| 312 | memset(bitstats, 0, sizeof(bitstats)); | 313 | memset(bitstats, 0, sizeof(bitstats)); |
| 313 | 314 | ||
| 314 | msg("overwrite biterrors test\n"); | 315 | pr_info("overwrite biterrors test\n"); |
| 315 | 316 | ||
| 316 | for (i = 0; i < mtd->writesize; i++) | 317 | for (i = 0; i < mtd->writesize; i++) |
| 317 | wbuffer[i] = hash(i+seed); | 318 | wbuffer[i] = hash(i+seed); |
| @@ -329,18 +330,18 @@ static int overwrite_test(void) | |||
| 329 | err = read_page(0); | 330 | err = read_page(0); |
| 330 | if (err >= 0) { | 331 | if (err >= 0) { |
| 331 | if (err >= MAXBITS) { | 332 | if (err >= MAXBITS) { |
| 332 | msg("Implausible number of bit errors corrected\n"); | 333 | pr_info("Implausible number of bit errors corrected\n"); |
| 333 | err = -EIO; | 334 | err = -EIO; |
| 334 | break; | 335 | break; |
| 335 | } | 336 | } |
| 336 | bitstats[err]++; | 337 | bitstats[err]++; |
| 337 | if (err > max_corrected) { | 338 | if (err > max_corrected) { |
| 338 | max_corrected = err; | 339 | max_corrected = err; |
| 339 | msg("Read reported %d corrected bit errors\n", | 340 | pr_info("Read reported %d corrected bit errors\n", |
| 340 | err); | 341 | err); |
| 341 | } | 342 | } |
| 342 | } else { /* err < 0 */ | 343 | } else { /* err < 0 */ |
| 343 | msg("Read reported error %d\n", err); | 344 | pr_info("Read reported error %d\n", err); |
| 344 | err = 0; | 345 | err = 0; |
| 345 | break; | 346 | break; |
| 346 | } | 347 | } |
| @@ -348,7 +349,7 @@ static int overwrite_test(void) | |||
| 348 | err = verify_page(0); | 349 | err = verify_page(0); |
| 349 | if (err) { | 350 | if (err) { |
| 350 | bitstats[max_corrected] = opno; | 351 | bitstats[max_corrected] = opno; |
| 351 | msg("ECC failure, read data is incorrect despite read success\n"); | 352 | pr_info("ECC failure, read data is incorrect despite read success\n"); |
| 352 | break; | 353 | break; |
| 353 | } | 354 | } |
| 354 | 355 | ||
| @@ -357,9 +358,9 @@ static int overwrite_test(void) | |||
| 357 | 358 | ||
| 358 | /* At this point bitstats[0] contains the number of ops with no bit | 359 | /* At this point bitstats[0] contains the number of ops with no bit |
| 359 | * errors, bitstats[1] the number of ops with 1 bit error, etc. */ | 360 | * errors, bitstats[1] the number of ops with 1 bit error, etc. */ |
| 360 | msg("Bit error histogram (%d operations total):\n", opno); | 361 | pr_info("Bit error histogram (%d operations total):\n", opno); |
| 361 | for (i = 0; i < max_corrected; i++) | 362 | for (i = 0; i < max_corrected; i++) |
| 362 | msg("Page reads with %3d corrected bit errors: %d\n", | 363 | pr_info("Page reads with %3d corrected bit errors: %d\n", |
| 363 | i, bitstats[i]); | 364 | i, bitstats[i]); |
| 364 | 365 | ||
| 365 | exit: | 366 | exit: |
| @@ -370,36 +371,36 @@ static int __init mtd_nandbiterrs_init(void) | |||
| 370 | { | 371 | { |
| 371 | int err = 0; | 372 | int err = 0; |
| 372 | 373 | ||
| 373 | msg("\n"); | 374 | printk("\n"); |
| 374 | msg("==================================================\n"); | 375 | printk(KERN_INFO "==================================================\n"); |
| 375 | msg("MTD device: %d\n", dev); | 376 | pr_info("MTD device: %d\n", dev); |
| 376 | 377 | ||
| 377 | mtd = get_mtd_device(NULL, dev); | 378 | mtd = get_mtd_device(NULL, dev); |
| 378 | if (IS_ERR(mtd)) { | 379 | if (IS_ERR(mtd)) { |
| 379 | err = PTR_ERR(mtd); | 380 | err = PTR_ERR(mtd); |
| 380 | msg("error: cannot get MTD device\n"); | 381 | pr_err("error: cannot get MTD device\n"); |
| 381 | goto exit_mtddev; | 382 | goto exit_mtddev; |
| 382 | } | 383 | } |
| 383 | 384 | ||
| 384 | if (mtd->type != MTD_NANDFLASH) { | 385 | if (mtd->type != MTD_NANDFLASH) { |
| 385 | msg("this test requires NAND flash\n"); | 386 | pr_info("this test requires NAND flash\n"); |
| 386 | err = -ENODEV; | 387 | err = -ENODEV; |
| 387 | goto exit_nand; | 388 | goto exit_nand; |
| 388 | } | 389 | } |
| 389 | 390 | ||
| 390 | msg("MTD device size %llu, eraseblock=%u, page=%u, oob=%u\n", | 391 | pr_info("MTD device size %llu, eraseblock=%u, page=%u, oob=%u\n", |
| 391 | (unsigned long long)mtd->size, mtd->erasesize, | 392 | (unsigned long long)mtd->size, mtd->erasesize, |
| 392 | mtd->writesize, mtd->oobsize); | 393 | mtd->writesize, mtd->oobsize); |
| 393 | 394 | ||
| 394 | subsize = mtd->writesize >> mtd->subpage_sft; | 395 | subsize = mtd->writesize >> mtd->subpage_sft; |
| 395 | subcount = mtd->writesize / subsize; | 396 | subcount = mtd->writesize / subsize; |
| 396 | 397 | ||
| 397 | msg("Device uses %d subpages of %d bytes\n", subcount, subsize); | 398 | pr_info("Device uses %d subpages of %d bytes\n", subcount, subsize); |
| 398 | 399 | ||
| 399 | offset = page_offset * mtd->writesize; | 400 | offset = page_offset * mtd->writesize; |
| 400 | eraseblock = mtd_div_by_eb(offset, mtd); | 401 | eraseblock = mtd_div_by_eb(offset, mtd); |
| 401 | 402 | ||
| 402 | msg("Using page=%u, offset=%llu, eraseblock=%u\n", | 403 | pr_info("Using page=%u, offset=%llu, eraseblock=%u\n", |
| 403 | page_offset, offset, eraseblock); | 404 | page_offset, offset, eraseblock); |
| 404 | 405 | ||
| 405 | wbuffer = kmalloc(mtd->writesize, GFP_KERNEL); | 406 | wbuffer = kmalloc(mtd->writesize, GFP_KERNEL); |
| @@ -432,8 +433,8 @@ static int __init mtd_nandbiterrs_init(void) | |||
| 432 | goto exit_error; | 433 | goto exit_error; |
| 433 | 434 | ||
| 434 | err = -EIO; | 435 | err = -EIO; |
| 435 | msg("finished successfully.\n"); | 436 | pr_info("finished successfully.\n"); |
| 436 | msg("==================================================\n"); | 437 | printk(KERN_INFO "==================================================\n"); |
| 437 | 438 | ||
| 438 | exit_error: | 439 | exit_error: |
| 439 | kfree(rbuffer); | 440 | kfree(rbuffer); |
diff --git a/drivers/mtd/tests/mtd_nandecctest.c b/drivers/mtd/tests/mtd_nandecctest.c index b437fa425077..1eee264509a8 100644 --- a/drivers/mtd/tests/mtd_nandecctest.c +++ b/drivers/mtd/tests/mtd_nandecctest.c | |||
| @@ -1,3 +1,5 @@ | |||
| 1 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 2 | |||
| 1 | #include <linux/kernel.h> | 3 | #include <linux/kernel.h> |
| 2 | #include <linux/module.h> | 4 | #include <linux/module.h> |
| 3 | #include <linux/list.h> | 5 | #include <linux/list.h> |
| @@ -264,13 +266,13 @@ static int nand_ecc_test_run(const size_t size) | |||
| 264 | correct_data, size); | 266 | correct_data, size); |
| 265 | 267 | ||
| 266 | if (err) { | 268 | if (err) { |
| 267 | pr_err("mtd_nandecctest: not ok - %s-%zd\n", | 269 | pr_err("not ok - %s-%zd\n", |
| 268 | nand_ecc_test[i].name, size); | 270 | nand_ecc_test[i].name, size); |
| 269 | dump_data_ecc(error_data, error_ecc, | 271 | dump_data_ecc(error_data, error_ecc, |
| 270 | correct_data, correct_ecc, size); | 272 | correct_data, correct_ecc, size); |
| 271 | break; | 273 | break; |
| 272 | } | 274 | } |
| 273 | pr_info("mtd_nandecctest: ok - %s-%zd\n", | 275 | pr_info("ok - %s-%zd\n", |
| 274 | nand_ecc_test[i].name, size); | 276 | nand_ecc_test[i].name, size); |
| 275 | } | 277 | } |
| 276 | error: | 278 | error: |
diff --git a/drivers/mtd/tests/mtd_oobtest.c b/drivers/mtd/tests/mtd_oobtest.c index ed9b62827f1b..e827fa8cd844 100644 --- a/drivers/mtd/tests/mtd_oobtest.c +++ b/drivers/mtd/tests/mtd_oobtest.c | |||
| @@ -19,6 +19,8 @@ | |||
| 19 | * Author: Adrian Hunter <ext-adrian.hunter@nokia.com> | 19 | * Author: Adrian Hunter <ext-adrian.hunter@nokia.com> |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 23 | |||
| 22 | #include <asm/div64.h> | 24 | #include <asm/div64.h> |
| 23 | #include <linux/init.h> | 25 | #include <linux/init.h> |
| 24 | #include <linux/module.h> | 26 | #include <linux/module.h> |
| @@ -28,8 +30,6 @@ | |||
| 28 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
| 29 | #include <linux/sched.h> | 31 | #include <linux/sched.h> |
| 30 | 32 | ||
| 31 | #define PRINT_PREF KERN_INFO "mtd_oobtest: " | ||
| 32 | |||
| 33 | static int dev = -EINVAL; | 33 | static int dev = -EINVAL; |
| 34 | module_param(dev, int, S_IRUGO); | 34 | module_param(dev, int, S_IRUGO); |
| 35 | MODULE_PARM_DESC(dev, "MTD device number to use"); | 35 | MODULE_PARM_DESC(dev, "MTD device number to use"); |
| @@ -80,13 +80,12 @@ static int erase_eraseblock(int ebnum) | |||
| 80 | 80 | ||
| 81 | err = mtd_erase(mtd, &ei); | 81 | err = mtd_erase(mtd, &ei); |
| 82 | if (err) { | 82 | if (err) { |
| 83 | printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum); | 83 | pr_err("error %d while erasing EB %d\n", err, ebnum); |
| 84 | return err; | 84 | return err; |
| 85 | } | 85 | } |
| 86 | 86 | ||
| 87 | if (ei.state == MTD_ERASE_FAILED) { | 87 | if (ei.state == MTD_ERASE_FAILED) { |
| 88 | printk(PRINT_PREF "some erase error occurred at EB %d\n", | 88 | pr_err("some erase error occurred at EB %d\n", ebnum); |
| 89 | ebnum); | ||
| 90 | return -EIO; | 89 | return -EIO; |
| 91 | } | 90 | } |
| 92 | 91 | ||
| @@ -98,7 +97,7 @@ static int erase_whole_device(void) | |||
| 98 | int err; | 97 | int err; |
| 99 | unsigned int i; | 98 | unsigned int i; |
| 100 | 99 | ||
| 101 | printk(PRINT_PREF "erasing whole device\n"); | 100 | pr_info("erasing whole device\n"); |
| 102 | for (i = 0; i < ebcnt; ++i) { | 101 | for (i = 0; i < ebcnt; ++i) { |
| 103 | if (bbt[i]) | 102 | if (bbt[i]) |
| 104 | continue; | 103 | continue; |
| @@ -107,7 +106,7 @@ static int erase_whole_device(void) | |||
| 107 | return err; | 106 | return err; |
| 108 | cond_resched(); | 107 | cond_resched(); |
| 109 | } | 108 | } |
| 110 | printk(PRINT_PREF "erased %u eraseblocks\n", i); | 109 | pr_info("erased %u eraseblocks\n", i); |
| 111 | return 0; | 110 | return 0; |
| 112 | } | 111 | } |
| 113 | 112 | ||
| @@ -141,9 +140,9 @@ static int write_eraseblock(int ebnum) | |||
| 141 | ops.oobbuf = writebuf; | 140 | ops.oobbuf = writebuf; |
| 142 | err = mtd_write_oob(mtd, addr, &ops); | 141 | err = mtd_write_oob(mtd, addr, &ops); |
| 143 | if (err || ops.oobretlen != use_len) { | 142 | if (err || ops.oobretlen != use_len) { |
| 144 | printk(PRINT_PREF "error: writeoob failed at %#llx\n", | 143 | pr_err("error: writeoob failed at %#llx\n", |
| 145 | (long long)addr); | 144 | (long long)addr); |
| 146 | printk(PRINT_PREF "error: use_len %d, use_offset %d\n", | 145 | pr_err("error: use_len %d, use_offset %d\n", |
| 147 | use_len, use_offset); | 146 | use_len, use_offset); |
| 148 | errcnt += 1; | 147 | errcnt += 1; |
| 149 | return err ? err : -1; | 148 | return err ? err : -1; |
| @@ -160,7 +159,7 @@ static int write_whole_device(void) | |||
| 160 | int err; | 159 | int err; |
| 161 | unsigned int i; | 160 | unsigned int i; |
| 162 | 161 | ||
| 163 | printk(PRINT_PREF "writing OOBs of whole device\n"); | 162 | pr_info("writing OOBs of whole device\n"); |
| 164 | for (i = 0; i < ebcnt; ++i) { | 163 | for (i = 0; i < ebcnt; ++i) { |
| 165 | if (bbt[i]) | 164 | if (bbt[i]) |
| 166 | continue; | 165 | continue; |
| @@ -168,10 +167,10 @@ static int write_whole_device(void) | |||
| 168 | if (err) | 167 | if (err) |
| 169 | return err; | 168 | return err; |
| 170 | if (i % 256 == 0) | 169 | if (i % 256 == 0) |
| 171 | printk(PRINT_PREF "written up to eraseblock %u\n", i); | 170 | pr_info("written up to eraseblock %u\n", i); |
| 172 | cond_resched(); | 171 | cond_resched(); |
| 173 | } | 172 | } |
| 174 | printk(PRINT_PREF "written %u eraseblocks\n", i); | 173 | pr_info("written %u eraseblocks\n", i); |
| 175 | return 0; | 174 | return 0; |
| 176 | } | 175 | } |
| 177 | 176 | ||
| @@ -194,17 +193,17 @@ static int verify_eraseblock(int ebnum) | |||
| 194 | ops.oobbuf = readbuf; | 193 | ops.oobbuf = readbuf; |
| 195 | err = mtd_read_oob(mtd, addr, &ops); | 194 | err = mtd_read_oob(mtd, addr, &ops); |
| 196 | if (err || ops.oobretlen != use_len) { | 195 | if (err || ops.oobretlen != use_len) { |
| 197 | printk(PRINT_PREF "error: readoob failed at %#llx\n", | 196 | pr_err("error: readoob failed at %#llx\n", |
| 198 | (long long)addr); | 197 | (long long)addr); |
| 199 | errcnt += 1; | 198 | errcnt += 1; |
| 200 | return err ? err : -1; | 199 | return err ? err : -1; |
| 201 | } | 200 | } |
| 202 | if (memcmp(readbuf, writebuf, use_len)) { | 201 | if (memcmp(readbuf, writebuf, use_len)) { |
| 203 | printk(PRINT_PREF "error: verify failed at %#llx\n", | 202 | pr_err("error: verify failed at %#llx\n", |
| 204 | (long long)addr); | 203 | (long long)addr); |
| 205 | errcnt += 1; | 204 | errcnt += 1; |
| 206 | if (errcnt > 1000) { | 205 | if (errcnt > 1000) { |
| 207 | printk(PRINT_PREF "error: too many errors\n"); | 206 | pr_err("error: too many errors\n"); |
| 208 | return -1; | 207 | return -1; |
| 209 | } | 208 | } |
| 210 | } | 209 | } |
| @@ -221,29 +220,28 @@ static int verify_eraseblock(int ebnum) | |||
| 221 | ops.oobbuf = readbuf; | 220 | ops.oobbuf = readbuf; |
| 222 | err = mtd_read_oob(mtd, addr, &ops); | 221 | err = mtd_read_oob(mtd, addr, &ops); |
| 223 | if (err || ops.oobretlen != mtd->ecclayout->oobavail) { | 222 | if (err || ops.oobretlen != mtd->ecclayout->oobavail) { |
| 224 | printk(PRINT_PREF "error: readoob failed at " | 223 | pr_err("error: readoob failed at %#llx\n", |
| 225 | "%#llx\n", (long long)addr); | 224 | (long long)addr); |
| 226 | errcnt += 1; | 225 | errcnt += 1; |
| 227 | return err ? err : -1; | 226 | return err ? err : -1; |
| 228 | } | 227 | } |
| 229 | if (memcmp(readbuf + use_offset, writebuf, use_len)) { | 228 | if (memcmp(readbuf + use_offset, writebuf, use_len)) { |
| 230 | printk(PRINT_PREF "error: verify failed at " | 229 | pr_err("error: verify failed at %#llx\n", |
| 231 | "%#llx\n", (long long)addr); | 230 | (long long)addr); |
| 232 | errcnt += 1; | 231 | errcnt += 1; |
| 233 | if (errcnt > 1000) { | 232 | if (errcnt > 1000) { |
| 234 | printk(PRINT_PREF "error: too many " | 233 | pr_err("error: too many errors\n"); |
| 235 | "errors\n"); | ||
| 236 | return -1; | 234 | return -1; |
| 237 | } | 235 | } |
| 238 | } | 236 | } |
| 239 | for (k = 0; k < use_offset; ++k) | 237 | for (k = 0; k < use_offset; ++k) |
| 240 | if (readbuf[k] != 0xff) { | 238 | if (readbuf[k] != 0xff) { |
| 241 | printk(PRINT_PREF "error: verify 0xff " | 239 | pr_err("error: verify 0xff " |
| 242 | "failed at %#llx\n", | 240 | "failed at %#llx\n", |
| 243 | (long long)addr); | 241 | (long long)addr); |
| 244 | errcnt += 1; | 242 | errcnt += 1; |
| 245 | if (errcnt > 1000) { | 243 | if (errcnt > 1000) { |
| 246 | printk(PRINT_PREF "error: too " | 244 | pr_err("error: too " |
| 247 | "many errors\n"); | 245 | "many errors\n"); |
| 248 | return -1; | 246 | return -1; |
| 249 | } | 247 | } |
| @@ -251,12 +249,12 @@ static int verify_eraseblock(int ebnum) | |||
| 251 | for (k = use_offset + use_len; | 249 | for (k = use_offset + use_len; |
| 252 | k < mtd->ecclayout->oobavail; ++k) | 250 | k < mtd->ecclayout->oobavail; ++k) |
| 253 | if (readbuf[k] != 0xff) { | 251 | if (readbuf[k] != 0xff) { |
| 254 | printk(PRINT_PREF "error: verify 0xff " | 252 | pr_err("error: verify 0xff " |
| 255 | "failed at %#llx\n", | 253 | "failed at %#llx\n", |
| 256 | (long long)addr); | 254 | (long long)addr); |
| 257 | errcnt += 1; | 255 | errcnt += 1; |
| 258 | if (errcnt > 1000) { | 256 | if (errcnt > 1000) { |
| 259 | printk(PRINT_PREF "error: too " | 257 | pr_err("error: too " |
| 260 | "many errors\n"); | 258 | "many errors\n"); |
| 261 | return -1; | 259 | return -1; |
| 262 | } | 260 | } |
| @@ -286,17 +284,17 @@ static int verify_eraseblock_in_one_go(int ebnum) | |||
| 286 | ops.oobbuf = readbuf; | 284 | ops.oobbuf = readbuf; |
| 287 | err = mtd_read_oob(mtd, addr, &ops); | 285 | err = mtd_read_oob(mtd, addr, &ops); |
| 288 | if (err || ops.oobretlen != len) { | 286 | if (err || ops.oobretlen != len) { |
| 289 | printk(PRINT_PREF "error: readoob failed at %#llx\n", | 287 | pr_err("error: readoob failed at %#llx\n", |
| 290 | (long long)addr); | 288 | (long long)addr); |
| 291 | errcnt += 1; | 289 | errcnt += 1; |
| 292 | return err ? err : -1; | 290 | return err ? err : -1; |
| 293 | } | 291 | } |
| 294 | if (memcmp(readbuf, writebuf, len)) { | 292 | if (memcmp(readbuf, writebuf, len)) { |
| 295 | printk(PRINT_PREF "error: verify failed at %#llx\n", | 293 | pr_err("error: verify failed at %#llx\n", |
| 296 | (long long)addr); | 294 | (long long)addr); |
| 297 | errcnt += 1; | 295 | errcnt += 1; |
| 298 | if (errcnt > 1000) { | 296 | if (errcnt > 1000) { |
| 299 | printk(PRINT_PREF "error: too many errors\n"); | 297 | pr_err("error: too many errors\n"); |
| 300 | return -1; | 298 | return -1; |
| 301 | } | 299 | } |
| 302 | } | 300 | } |
| @@ -309,7 +307,7 @@ static int verify_all_eraseblocks(void) | |||
| 309 | int err; | 307 | int err; |
| 310 | unsigned int i; | 308 | unsigned int i; |
| 311 | 309 | ||
| 312 | printk(PRINT_PREF "verifying all eraseblocks\n"); | 310 | pr_info("verifying all eraseblocks\n"); |
| 313 | for (i = 0; i < ebcnt; ++i) { | 311 | for (i = 0; i < ebcnt; ++i) { |
| 314 | if (bbt[i]) | 312 | if (bbt[i]) |
| 315 | continue; | 313 | continue; |
| @@ -317,10 +315,10 @@ static int verify_all_eraseblocks(void) | |||
| 317 | if (err) | 315 | if (err) |
| 318 | return err; | 316 | return err; |
| 319 | if (i % 256 == 0) | 317 | if (i % 256 == 0) |
| 320 | printk(PRINT_PREF "verified up to eraseblock %u\n", i); | 318 | pr_info("verified up to eraseblock %u\n", i); |
| 321 | cond_resched(); | 319 | cond_resched(); |
| 322 | } | 320 | } |
| 323 | printk(PRINT_PREF "verified %u eraseblocks\n", i); | 321 | pr_info("verified %u eraseblocks\n", i); |
| 324 | return 0; | 322 | return 0; |
| 325 | } | 323 | } |
| 326 | 324 | ||
| @@ -331,7 +329,7 @@ static int is_block_bad(int ebnum) | |||
| 331 | 329 | ||
| 332 | ret = mtd_block_isbad(mtd, addr); | 330 | ret = mtd_block_isbad(mtd, addr); |
| 333 | if (ret) | 331 | if (ret) |
| 334 | printk(PRINT_PREF "block %d is bad\n", ebnum); | 332 | pr_info("block %d is bad\n", ebnum); |
| 335 | return ret; | 333 | return ret; |
| 336 | } | 334 | } |
| 337 | 335 | ||
| @@ -341,18 +339,18 @@ static int scan_for_bad_eraseblocks(void) | |||
| 341 | 339 | ||
| 342 | bbt = kmalloc(ebcnt, GFP_KERNEL); | 340 | bbt = kmalloc(ebcnt, GFP_KERNEL); |
| 343 | if (!bbt) { | 341 | if (!bbt) { |
| 344 | printk(PRINT_PREF "error: cannot allocate memory\n"); | 342 | pr_err("error: cannot allocate memory\n"); |
| 345 | return -ENOMEM; | 343 | return -ENOMEM; |
| 346 | } | 344 | } |
| 347 | 345 | ||
| 348 | printk(PRINT_PREF "scanning for bad eraseblocks\n"); | 346 | pr_info("scanning for bad eraseblocks\n"); |
| 349 | for (i = 0; i < ebcnt; ++i) { | 347 | for (i = 0; i < ebcnt; ++i) { |
| 350 | bbt[i] = is_block_bad(i) ? 1 : 0; | 348 | bbt[i] = is_block_bad(i) ? 1 : 0; |
| 351 | if (bbt[i]) | 349 | if (bbt[i]) |
| 352 | bad += 1; | 350 | bad += 1; |
| 353 | cond_resched(); | 351 | cond_resched(); |
| 354 | } | 352 | } |
| 355 | printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad); | 353 | pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); |
| 356 | return 0; | 354 | return 0; |
| 357 | } | 355 | } |
| 358 | 356 | ||
| @@ -368,22 +366,22 @@ static int __init mtd_oobtest_init(void) | |||
| 368 | printk(KERN_INFO "=================================================\n"); | 366 | printk(KERN_INFO "=================================================\n"); |
| 369 | 367 | ||
| 370 | if (dev < 0) { | 368 | if (dev < 0) { |
| 371 | printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n"); | 369 | pr_info("Please specify a valid mtd-device via module parameter\n"); |
| 372 | printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n"); | 370 | pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); |
| 373 | return -EINVAL; | 371 | return -EINVAL; |
| 374 | } | 372 | } |
| 375 | 373 | ||
| 376 | printk(PRINT_PREF "MTD device: %d\n", dev); | 374 | pr_info("MTD device: %d\n", dev); |
| 377 | 375 | ||
| 378 | mtd = get_mtd_device(NULL, dev); | 376 | mtd = get_mtd_device(NULL, dev); |
| 379 | if (IS_ERR(mtd)) { | 377 | if (IS_ERR(mtd)) { |
| 380 | err = PTR_ERR(mtd); | 378 | err = PTR_ERR(mtd); |
| 381 | printk(PRINT_PREF "error: cannot get MTD device\n"); | 379 | pr_err("error: cannot get MTD device\n"); |
| 382 | return err; | 380 | return err; |
| 383 | } | 381 | } |
| 384 | 382 | ||
| 385 | if (mtd->type != MTD_NANDFLASH) { | 383 | if (mtd->type != MTD_NANDFLASH) { |
| 386 | printk(PRINT_PREF "this test requires NAND flash\n"); | 384 | pr_info("this test requires NAND flash\n"); |
| 387 | goto out; | 385 | goto out; |
| 388 | } | 386 | } |
| 389 | 387 | ||
| @@ -392,7 +390,7 @@ static int __init mtd_oobtest_init(void) | |||
| 392 | ebcnt = tmp; | 390 | ebcnt = tmp; |
| 393 | pgcnt = mtd->erasesize / mtd->writesize; | 391 | pgcnt = mtd->erasesize / mtd->writesize; |
| 394 | 392 | ||
| 395 | printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " | 393 | pr_info("MTD device size %llu, eraseblock size %u, " |
| 396 | "page size %u, count of eraseblocks %u, pages per " | 394 | "page size %u, count of eraseblocks %u, pages per " |
| 397 | "eraseblock %u, OOB size %u\n", | 395 | "eraseblock %u, OOB size %u\n", |
| 398 | (unsigned long long)mtd->size, mtd->erasesize, | 396 | (unsigned long long)mtd->size, mtd->erasesize, |
| @@ -401,12 +399,12 @@ static int __init mtd_oobtest_init(void) | |||
| 401 | err = -ENOMEM; | 399 | err = -ENOMEM; |
| 402 | readbuf = kmalloc(mtd->erasesize, GFP_KERNEL); | 400 | readbuf = kmalloc(mtd->erasesize, GFP_KERNEL); |
| 403 | if (!readbuf) { | 401 | if (!readbuf) { |
| 404 | printk(PRINT_PREF "error: cannot allocate memory\n"); | 402 | pr_err("error: cannot allocate memory\n"); |
| 405 | goto out; | 403 | goto out; |
| 406 | } | 404 | } |
| 407 | writebuf = kmalloc(mtd->erasesize, GFP_KERNEL); | 405 | writebuf = kmalloc(mtd->erasesize, GFP_KERNEL); |
| 408 | if (!writebuf) { | 406 | if (!writebuf) { |
| 409 | printk(PRINT_PREF "error: cannot allocate memory\n"); | 407 | pr_err("error: cannot allocate memory\n"); |
| 410 | goto out; | 408 | goto out; |
| 411 | } | 409 | } |
| 412 | 410 | ||
| @@ -420,7 +418,7 @@ static int __init mtd_oobtest_init(void) | |||
| 420 | vary_offset = 0; | 418 | vary_offset = 0; |
| 421 | 419 | ||
| 422 | /* First test: write all OOB, read it back and verify */ | 420 | /* First test: write all OOB, read it back and verify */ |
| 423 | printk(PRINT_PREF "test 1 of 5\n"); | 421 | pr_info("test 1 of 5\n"); |
| 424 | 422 | ||
| 425 | err = erase_whole_device(); | 423 | err = erase_whole_device(); |
| 426 | if (err) | 424 | if (err) |
| @@ -440,7 +438,7 @@ static int __init mtd_oobtest_init(void) | |||
| 440 | * Second test: write all OOB, a block at a time, read it back and | 438 | * Second test: write all OOB, a block at a time, read it back and |
| 441 | * verify. | 439 | * verify. |
| 442 | */ | 440 | */ |
| 443 | printk(PRINT_PREF "test 2 of 5\n"); | 441 | pr_info("test 2 of 5\n"); |
| 444 | 442 | ||
| 445 | err = erase_whole_device(); | 443 | err = erase_whole_device(); |
| 446 | if (err) | 444 | if (err) |
| @@ -453,7 +451,7 @@ static int __init mtd_oobtest_init(void) | |||
| 453 | 451 | ||
| 454 | /* Check all eraseblocks */ | 452 | /* Check all eraseblocks */ |
| 455 | simple_srand(3); | 453 | simple_srand(3); |
| 456 | printk(PRINT_PREF "verifying all eraseblocks\n"); | 454 | pr_info("verifying all eraseblocks\n"); |
| 457 | for (i = 0; i < ebcnt; ++i) { | 455 | for (i = 0; i < ebcnt; ++i) { |
| 458 | if (bbt[i]) | 456 | if (bbt[i]) |
| 459 | continue; | 457 | continue; |
| @@ -461,16 +459,16 @@ static int __init mtd_oobtest_init(void) | |||
| 461 | if (err) | 459 | if (err) |
| 462 | goto out; | 460 | goto out; |
| 463 | if (i % 256 == 0) | 461 | if (i % 256 == 0) |
| 464 | printk(PRINT_PREF "verified up to eraseblock %u\n", i); | 462 | pr_info("verified up to eraseblock %u\n", i); |
| 465 | cond_resched(); | 463 | cond_resched(); |
| 466 | } | 464 | } |
| 467 | printk(PRINT_PREF "verified %u eraseblocks\n", i); | 465 | pr_info("verified %u eraseblocks\n", i); |
| 468 | 466 | ||
| 469 | /* | 467 | /* |
| 470 | * Third test: write OOB at varying offsets and lengths, read it back | 468 | * Third test: write OOB at varying offsets and lengths, read it back |
| 471 | * and verify. | 469 | * and verify. |
| 472 | */ | 470 | */ |
| 473 | printk(PRINT_PREF "test 3 of 5\n"); | 471 | pr_info("test 3 of 5\n"); |
| 474 | 472 | ||
| 475 | err = erase_whole_device(); | 473 | err = erase_whole_device(); |
| 476 | if (err) | 474 | if (err) |
| @@ -503,7 +501,7 @@ static int __init mtd_oobtest_init(void) | |||
| 503 | vary_offset = 0; | 501 | vary_offset = 0; |
| 504 | 502 | ||
| 505 | /* Fourth test: try to write off end of device */ | 503 | /* Fourth test: try to write off end of device */ |
| 506 | printk(PRINT_PREF "test 4 of 5\n"); | 504 | pr_info("test 4 of 5\n"); |
| 507 | 505 | ||
| 508 | err = erase_whole_device(); | 506 | err = erase_whole_device(); |
| 509 | if (err) | 507 | if (err) |
| @@ -522,14 +520,14 @@ static int __init mtd_oobtest_init(void) | |||
| 522 | ops.ooboffs = mtd->ecclayout->oobavail; | 520 | ops.ooboffs = mtd->ecclayout->oobavail; |
| 523 | ops.datbuf = NULL; | 521 | ops.datbuf = NULL; |
| 524 | ops.oobbuf = writebuf; | 522 | ops.oobbuf = writebuf; |
| 525 | printk(PRINT_PREF "attempting to start write past end of OOB\n"); | 523 | pr_info("attempting to start write past end of OOB\n"); |
| 526 | printk(PRINT_PREF "an error is expected...\n"); | 524 | pr_info("an error is expected...\n"); |
| 527 | err = mtd_write_oob(mtd, addr0, &ops); | 525 | err = mtd_write_oob(mtd, addr0, &ops); |
| 528 | if (err) { | 526 | if (err) { |
| 529 | printk(PRINT_PREF "error occurred as expected\n"); | 527 | pr_info("error occurred as expected\n"); |
| 530 | err = 0; | 528 | err = 0; |
| 531 | } else { | 529 | } else { |
| 532 | printk(PRINT_PREF "error: can write past end of OOB\n"); | 530 | pr_err("error: can write past end of OOB\n"); |
| 533 | errcnt += 1; | 531 | errcnt += 1; |
| 534 | } | 532 | } |
| 535 | 533 | ||
| @@ -542,19 +540,19 @@ static int __init mtd_oobtest_init(void) | |||
| 542 | ops.ooboffs = mtd->ecclayout->oobavail; | 540 | ops.ooboffs = mtd->ecclayout->oobavail; |
| 543 | ops.datbuf = NULL; | 541 | ops.datbuf = NULL; |
| 544 | ops.oobbuf = readbuf; | 542 | ops.oobbuf = readbuf; |
| 545 | printk(PRINT_PREF "attempting to start read past end of OOB\n"); | 543 | pr_info("attempting to start read past end of OOB\n"); |
| 546 | printk(PRINT_PREF "an error is expected...\n"); | 544 | pr_info("an error is expected...\n"); |
| 547 | err = mtd_read_oob(mtd, addr0, &ops); | 545 | err = mtd_read_oob(mtd, addr0, &ops); |
| 548 | if (err) { | 546 | if (err) { |
| 549 | printk(PRINT_PREF "error occurred as expected\n"); | 547 | pr_info("error occurred as expected\n"); |
| 550 | err = 0; | 548 | err = 0; |
| 551 | } else { | 549 | } else { |
| 552 | printk(PRINT_PREF "error: can read past end of OOB\n"); | 550 | pr_err("error: can read past end of OOB\n"); |
| 553 | errcnt += 1; | 551 | errcnt += 1; |
| 554 | } | 552 | } |
| 555 | 553 | ||
| 556 | if (bbt[ebcnt - 1]) | 554 | if (bbt[ebcnt - 1]) |
| 557 | printk(PRINT_PREF "skipping end of device tests because last " | 555 | pr_info("skipping end of device tests because last " |
| 558 | "block is bad\n"); | 556 | "block is bad\n"); |
| 559 | else { | 557 | else { |
| 560 | /* Attempt to write off end of device */ | 558 | /* Attempt to write off end of device */ |
| @@ -566,14 +564,14 @@ static int __init mtd_oobtest_init(void) | |||
| 566 | ops.ooboffs = 0; | 564 | ops.ooboffs = 0; |
| 567 | ops.datbuf = NULL; | 565 | ops.datbuf = NULL; |
| 568 | ops.oobbuf = writebuf; | 566 | ops.oobbuf = writebuf; |
| 569 | printk(PRINT_PREF "attempting to write past end of device\n"); | 567 | pr_info("attempting to write past end of device\n"); |
| 570 | printk(PRINT_PREF "an error is expected...\n"); | 568 | pr_info("an error is expected...\n"); |
| 571 | err = mtd_write_oob(mtd, mtd->size - mtd->writesize, &ops); | 569 | err = mtd_write_oob(mtd, mtd->size - mtd->writesize, &ops); |
| 572 | if (err) { | 570 | if (err) { |
| 573 | printk(PRINT_PREF "error occurred as expected\n"); | 571 | pr_info("error occurred as expected\n"); |
| 574 | err = 0; | 572 | err = 0; |
| 575 | } else { | 573 | } else { |
| 576 | printk(PRINT_PREF "error: wrote past end of device\n"); | 574 | pr_err("error: wrote past end of device\n"); |
| 577 | errcnt += 1; | 575 | errcnt += 1; |
| 578 | } | 576 | } |
| 579 | 577 | ||
| @@ -586,14 +584,14 @@ static int __init mtd_oobtest_init(void) | |||
| 586 | ops.ooboffs = 0; | 584 | ops.ooboffs = 0; |
| 587 | ops.datbuf = NULL; | 585 | ops.datbuf = NULL; |
| 588 | ops.oobbuf = readbuf; | 586 | ops.oobbuf = readbuf; |
| 589 | printk(PRINT_PREF "attempting to read past end of device\n"); | 587 | pr_info("attempting to read past end of device\n"); |
| 590 | printk(PRINT_PREF "an error is expected...\n"); | 588 | pr_info("an error is expected...\n"); |
| 591 | err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops); | 589 | err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops); |
| 592 | if (err) { | 590 | if (err) { |
| 593 | printk(PRINT_PREF "error occurred as expected\n"); | 591 | pr_info("error occurred as expected\n"); |
| 594 | err = 0; | 592 | err = 0; |
| 595 | } else { | 593 | } else { |
| 596 | printk(PRINT_PREF "error: read past end of device\n"); | 594 | pr_err("error: read past end of device\n"); |
| 597 | errcnt += 1; | 595 | errcnt += 1; |
| 598 | } | 596 | } |
| 599 | 597 | ||
| @@ -610,14 +608,14 @@ static int __init mtd_oobtest_init(void) | |||
| 610 | ops.ooboffs = 1; | 608 | ops.ooboffs = 1; |
| 611 | ops.datbuf = NULL; | 609 | ops.datbuf = NULL; |
| 612 | ops.oobbuf = writebuf; | 610 | ops.oobbuf = writebuf; |
| 613 | printk(PRINT_PREF "attempting to write past end of device\n"); | 611 | pr_info("attempting to write past end of device\n"); |
| 614 | printk(PRINT_PREF "an error is expected...\n"); | 612 | pr_info("an error is expected...\n"); |
| 615 | err = mtd_write_oob(mtd, mtd->size - mtd->writesize, &ops); | 613 | err = mtd_write_oob(mtd, mtd->size - mtd->writesize, &ops); |
| 616 | if (err) { | 614 | if (err) { |
| 617 | printk(PRINT_PREF "error occurred as expected\n"); | 615 | pr_info("error occurred as expected\n"); |
| 618 | err = 0; | 616 | err = 0; |
| 619 | } else { | 617 | } else { |
| 620 | printk(PRINT_PREF "error: wrote past end of device\n"); | 618 | pr_err("error: wrote past end of device\n"); |
| 621 | errcnt += 1; | 619 | errcnt += 1; |
| 622 | } | 620 | } |
| 623 | 621 | ||
| @@ -630,20 +628,20 @@ static int __init mtd_oobtest_init(void) | |||
| 630 | ops.ooboffs = 1; | 628 | ops.ooboffs = 1; |
| 631 | ops.datbuf = NULL; | 629 | ops.datbuf = NULL; |
| 632 | ops.oobbuf = readbuf; | 630 | ops.oobbuf = readbuf; |
| 633 | printk(PRINT_PREF "attempting to read past end of device\n"); | 631 | pr_info("attempting to read past end of device\n"); |
| 634 | printk(PRINT_PREF "an error is expected...\n"); | 632 | pr_info("an error is expected...\n"); |
| 635 | err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops); | 633 | err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops); |
| 636 | if (err) { | 634 | if (err) { |
| 637 | printk(PRINT_PREF "error occurred as expected\n"); | 635 | pr_info("error occurred as expected\n"); |
| 638 | err = 0; | 636 | err = 0; |
| 639 | } else { | 637 | } else { |
| 640 | printk(PRINT_PREF "error: read past end of device\n"); | 638 | pr_err("error: read past end of device\n"); |
| 641 | errcnt += 1; | 639 | errcnt += 1; |
| 642 | } | 640 | } |
| 643 | } | 641 | } |
| 644 | 642 | ||
| 645 | /* Fifth test: write / read across block boundaries */ | 643 | /* Fifth test: write / read across block boundaries */ |
| 646 | printk(PRINT_PREF "test 5 of 5\n"); | 644 | pr_info("test 5 of 5\n"); |
| 647 | 645 | ||
| 648 | /* Erase all eraseblocks */ | 646 | /* Erase all eraseblocks */ |
| 649 | err = erase_whole_device(); | 647 | err = erase_whole_device(); |
| @@ -652,7 +650,7 @@ static int __init mtd_oobtest_init(void) | |||
| 652 | 650 | ||
| 653 | /* Write all eraseblocks */ | 651 | /* Write all eraseblocks */ |
| 654 | simple_srand(11); | 652 | simple_srand(11); |
| 655 | printk(PRINT_PREF "writing OOBs of whole device\n"); | 653 | pr_info("writing OOBs of whole device\n"); |
| 656 | for (i = 0; i < ebcnt - 1; ++i) { | 654 | for (i = 0; i < ebcnt - 1; ++i) { |
| 657 | int cnt = 2; | 655 | int cnt = 2; |
| 658 | int pg; | 656 | int pg; |
| @@ -674,17 +672,16 @@ static int __init mtd_oobtest_init(void) | |||
| 674 | if (err) | 672 | if (err) |
| 675 | goto out; | 673 | goto out; |
| 676 | if (i % 256 == 0) | 674 | if (i % 256 == 0) |
| 677 | printk(PRINT_PREF "written up to eraseblock " | 675 | pr_info("written up to eraseblock %u\n", i); |
| 678 | "%u\n", i); | ||
| 679 | cond_resched(); | 676 | cond_resched(); |
| 680 | addr += mtd->writesize; | 677 | addr += mtd->writesize; |
| 681 | } | 678 | } |
| 682 | } | 679 | } |
| 683 | printk(PRINT_PREF "written %u eraseblocks\n", i); | 680 | pr_info("written %u eraseblocks\n", i); |
| 684 | 681 | ||
| 685 | /* Check all eraseblocks */ | 682 | /* Check all eraseblocks */ |
| 686 | simple_srand(11); | 683 | simple_srand(11); |
| 687 | printk(PRINT_PREF "verifying all eraseblocks\n"); | 684 | pr_info("verifying all eraseblocks\n"); |
| 688 | for (i = 0; i < ebcnt - 1; ++i) { | 685 | for (i = 0; i < ebcnt - 1; ++i) { |
| 689 | if (bbt[i] || bbt[i + 1]) | 686 | if (bbt[i] || bbt[i + 1]) |
| 690 | continue; | 687 | continue; |
| @@ -702,28 +699,28 @@ static int __init mtd_oobtest_init(void) | |||
| 702 | if (err) | 699 | if (err) |
| 703 | goto out; | 700 | goto out; |
| 704 | if (memcmp(readbuf, writebuf, mtd->ecclayout->oobavail * 2)) { | 701 | if (memcmp(readbuf, writebuf, mtd->ecclayout->oobavail * 2)) { |
| 705 | printk(PRINT_PREF "error: verify failed at %#llx\n", | 702 | pr_err("error: verify failed at %#llx\n", |
| 706 | (long long)addr); | 703 | (long long)addr); |
| 707 | errcnt += 1; | 704 | errcnt += 1; |
| 708 | if (errcnt > 1000) { | 705 | if (errcnt > 1000) { |
| 709 | printk(PRINT_PREF "error: too many errors\n"); | 706 | pr_err("error: too many errors\n"); |
| 710 | goto out; | 707 | goto out; |
| 711 | } | 708 | } |
| 712 | } | 709 | } |
| 713 | if (i % 256 == 0) | 710 | if (i % 256 == 0) |
| 714 | printk(PRINT_PREF "verified up to eraseblock %u\n", i); | 711 | pr_info("verified up to eraseblock %u\n", i); |
| 715 | cond_resched(); | 712 | cond_resched(); |
| 716 | } | 713 | } |
| 717 | printk(PRINT_PREF "verified %u eraseblocks\n", i); | 714 | pr_info("verified %u eraseblocks\n", i); |
| 718 | 715 | ||
| 719 | printk(PRINT_PREF "finished with %d errors\n", errcnt); | 716 | pr_info("finished with %d errors\n", errcnt); |
| 720 | out: | 717 | out: |
| 721 | kfree(bbt); | 718 | kfree(bbt); |
| 722 | kfree(writebuf); | 719 | kfree(writebuf); |
| 723 | kfree(readbuf); | 720 | kfree(readbuf); |
| 724 | put_mtd_device(mtd); | 721 | put_mtd_device(mtd); |
| 725 | if (err) | 722 | if (err) |
| 726 | printk(PRINT_PREF "error %d occurred\n", err); | 723 | pr_info("error %d occurred\n", err); |
| 727 | printk(KERN_INFO "=================================================\n"); | 724 | printk(KERN_INFO "=================================================\n"); |
| 728 | return err; | 725 | return err; |
| 729 | } | 726 | } |
diff --git a/drivers/mtd/tests/mtd_pagetest.c b/drivers/mtd/tests/mtd_pagetest.c index 252ddb092fb2..f93a76f88113 100644 --- a/drivers/mtd/tests/mtd_pagetest.c +++ b/drivers/mtd/tests/mtd_pagetest.c | |||
| @@ -19,6 +19,8 @@ | |||
| 19 | * Author: Adrian Hunter <ext-adrian.hunter@nokia.com> | 19 | * Author: Adrian Hunter <ext-adrian.hunter@nokia.com> |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 23 | |||
| 22 | #include <asm/div64.h> | 24 | #include <asm/div64.h> |
| 23 | #include <linux/init.h> | 25 | #include <linux/init.h> |
| 24 | #include <linux/module.h> | 26 | #include <linux/module.h> |
| @@ -28,8 +30,6 @@ | |||
| 28 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
| 29 | #include <linux/sched.h> | 31 | #include <linux/sched.h> |
| 30 | 32 | ||
| 31 | #define PRINT_PREF KERN_INFO "mtd_pagetest: " | ||
| 32 | |||
| 33 | static int dev = -EINVAL; | 33 | static int dev = -EINVAL; |
| 34 | module_param(dev, int, S_IRUGO); | 34 | module_param(dev, int, S_IRUGO); |
| 35 | MODULE_PARM_DESC(dev, "MTD device number to use"); | 35 | MODULE_PARM_DESC(dev, "MTD device number to use"); |
| @@ -79,12 +79,12 @@ static int erase_eraseblock(int ebnum) | |||
| 79 | 79 | ||
| 80 | err = mtd_erase(mtd, &ei); | 80 | err = mtd_erase(mtd, &ei); |
| 81 | if (err) { | 81 | if (err) { |
| 82 | printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum); | 82 | pr_err("error %d while erasing EB %d\n", err, ebnum); |
| 83 | return err; | 83 | return err; |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | if (ei.state == MTD_ERASE_FAILED) { | 86 | if (ei.state == MTD_ERASE_FAILED) { |
| 87 | printk(PRINT_PREF "some erase error occurred at EB %d\n", | 87 | pr_err("some erase error occurred at EB %d\n", |
| 88 | ebnum); | 88 | ebnum); |
| 89 | return -EIO; | 89 | return -EIO; |
| 90 | } | 90 | } |
| @@ -102,7 +102,7 @@ static int write_eraseblock(int ebnum) | |||
| 102 | cond_resched(); | 102 | cond_resched(); |
| 103 | err = mtd_write(mtd, addr, mtd->erasesize, &written, writebuf); | 103 | err = mtd_write(mtd, addr, mtd->erasesize, &written, writebuf); |
| 104 | if (err || written != mtd->erasesize) | 104 | if (err || written != mtd->erasesize) |
| 105 | printk(PRINT_PREF "error: write failed at %#llx\n", | 105 | pr_err("error: write failed at %#llx\n", |
| 106 | (long long)addr); | 106 | (long long)addr); |
| 107 | 107 | ||
| 108 | return err; | 108 | return err; |
| @@ -131,7 +131,7 @@ static int verify_eraseblock(int ebnum) | |||
| 131 | if (mtd_is_bitflip(err)) | 131 | if (mtd_is_bitflip(err)) |
| 132 | err = 0; | 132 | err = 0; |
| 133 | if (err || read != bufsize) { | 133 | if (err || read != bufsize) { |
| 134 | printk(PRINT_PREF "error: read failed at %#llx\n", | 134 | pr_err("error: read failed at %#llx\n", |
| 135 | (long long)addr0); | 135 | (long long)addr0); |
| 136 | return err; | 136 | return err; |
| 137 | } | 137 | } |
| @@ -139,7 +139,7 @@ static int verify_eraseblock(int ebnum) | |||
| 139 | if (mtd_is_bitflip(err)) | 139 | if (mtd_is_bitflip(err)) |
| 140 | err = 0; | 140 | err = 0; |
| 141 | if (err || read != bufsize) { | 141 | if (err || read != bufsize) { |
| 142 | printk(PRINT_PREF "error: read failed at %#llx\n", | 142 | pr_err("error: read failed at %#llx\n", |
| 143 | (long long)(addrn - bufsize)); | 143 | (long long)(addrn - bufsize)); |
| 144 | return err; | 144 | return err; |
| 145 | } | 145 | } |
| @@ -148,12 +148,12 @@ static int verify_eraseblock(int ebnum) | |||
| 148 | if (mtd_is_bitflip(err)) | 148 | if (mtd_is_bitflip(err)) |
| 149 | err = 0; | 149 | err = 0; |
| 150 | if (err || read != bufsize) { | 150 | if (err || read != bufsize) { |
| 151 | printk(PRINT_PREF "error: read failed at %#llx\n", | 151 | pr_err("error: read failed at %#llx\n", |
| 152 | (long long)addr); | 152 | (long long)addr); |
| 153 | break; | 153 | break; |
| 154 | } | 154 | } |
| 155 | if (memcmp(twopages, writebuf + (j * pgsize), bufsize)) { | 155 | if (memcmp(twopages, writebuf + (j * pgsize), bufsize)) { |
| 156 | printk(PRINT_PREF "error: verify failed at %#llx\n", | 156 | pr_err("error: verify failed at %#llx\n", |
| 157 | (long long)addr); | 157 | (long long)addr); |
| 158 | errcnt += 1; | 158 | errcnt += 1; |
| 159 | } | 159 | } |
| @@ -166,7 +166,7 @@ static int verify_eraseblock(int ebnum) | |||
| 166 | if (mtd_is_bitflip(err)) | 166 | if (mtd_is_bitflip(err)) |
| 167 | err = 0; | 167 | err = 0; |
| 168 | if (err || read != bufsize) { | 168 | if (err || read != bufsize) { |
| 169 | printk(PRINT_PREF "error: read failed at %#llx\n", | 169 | pr_err("error: read failed at %#llx\n", |
| 170 | (long long)addr0); | 170 | (long long)addr0); |
| 171 | return err; | 171 | return err; |
| 172 | } | 172 | } |
| @@ -174,7 +174,7 @@ static int verify_eraseblock(int ebnum) | |||
| 174 | if (mtd_is_bitflip(err)) | 174 | if (mtd_is_bitflip(err)) |
| 175 | err = 0; | 175 | err = 0; |
| 176 | if (err || read != bufsize) { | 176 | if (err || read != bufsize) { |
| 177 | printk(PRINT_PREF "error: read failed at %#llx\n", | 177 | pr_err("error: read failed at %#llx\n", |
| 178 | (long long)(addrn - bufsize)); | 178 | (long long)(addrn - bufsize)); |
| 179 | return err; | 179 | return err; |
| 180 | } | 180 | } |
| @@ -183,14 +183,14 @@ static int verify_eraseblock(int ebnum) | |||
| 183 | if (mtd_is_bitflip(err)) | 183 | if (mtd_is_bitflip(err)) |
| 184 | err = 0; | 184 | err = 0; |
| 185 | if (err || read != bufsize) { | 185 | if (err || read != bufsize) { |
| 186 | printk(PRINT_PREF "error: read failed at %#llx\n", | 186 | pr_err("error: read failed at %#llx\n", |
| 187 | (long long)addr); | 187 | (long long)addr); |
| 188 | return err; | 188 | return err; |
| 189 | } | 189 | } |
| 190 | memcpy(boundary, writebuf + mtd->erasesize - pgsize, pgsize); | 190 | memcpy(boundary, writebuf + mtd->erasesize - pgsize, pgsize); |
| 191 | set_random_data(boundary + pgsize, pgsize); | 191 | set_random_data(boundary + pgsize, pgsize); |
| 192 | if (memcmp(twopages, boundary, bufsize)) { | 192 | if (memcmp(twopages, boundary, bufsize)) { |
| 193 | printk(PRINT_PREF "error: verify failed at %#llx\n", | 193 | pr_err("error: verify failed at %#llx\n", |
| 194 | (long long)addr); | 194 | (long long)addr); |
| 195 | errcnt += 1; | 195 | errcnt += 1; |
| 196 | } | 196 | } |
| @@ -206,10 +206,10 @@ static int crosstest(void) | |||
| 206 | loff_t addr, addr0, addrn; | 206 | loff_t addr, addr0, addrn; |
| 207 | unsigned char *pp1, *pp2, *pp3, *pp4; | 207 | unsigned char *pp1, *pp2, *pp3, *pp4; |
| 208 | 208 | ||
| 209 | printk(PRINT_PREF "crosstest\n"); | 209 | pr_info("crosstest\n"); |
| 210 | pp1 = kmalloc(pgsize * 4, GFP_KERNEL); | 210 | pp1 = kmalloc(pgsize * 4, GFP_KERNEL); |
| 211 | if (!pp1) { | 211 | if (!pp1) { |
| 212 | printk(PRINT_PREF "error: cannot allocate memory\n"); | 212 | pr_err("error: cannot allocate memory\n"); |
| 213 | return -ENOMEM; | 213 | return -ENOMEM; |
| 214 | } | 214 | } |
| 215 | pp2 = pp1 + pgsize; | 215 | pp2 = pp1 + pgsize; |
| @@ -231,7 +231,7 @@ static int crosstest(void) | |||
| 231 | if (mtd_is_bitflip(err)) | 231 | if (mtd_is_bitflip(err)) |
| 232 | err = 0; | 232 | err = 0; |
| 233 | if (err || read != pgsize) { | 233 | if (err || read != pgsize) { |
| 234 | printk(PRINT_PREF "error: read failed at %#llx\n", | 234 | pr_err("error: read failed at %#llx\n", |
| 235 | (long long)addr); | 235 | (long long)addr); |
| 236 | kfree(pp1); | 236 | kfree(pp1); |
| 237 | return err; | 237 | return err; |
| @@ -243,7 +243,7 @@ static int crosstest(void) | |||
| 243 | if (mtd_is_bitflip(err)) | 243 | if (mtd_is_bitflip(err)) |
| 244 | err = 0; | 244 | err = 0; |
| 245 | if (err || read != pgsize) { | 245 | if (err || read != pgsize) { |
| 246 | printk(PRINT_PREF "error: read failed at %#llx\n", | 246 | pr_err("error: read failed at %#llx\n", |
| 247 | (long long)addr); | 247 | (long long)addr); |
| 248 | kfree(pp1); | 248 | kfree(pp1); |
| 249 | return err; | 249 | return err; |
| @@ -251,12 +251,12 @@ static int crosstest(void) | |||
| 251 | 251 | ||
| 252 | /* Read first page to pp2 */ | 252 | /* Read first page to pp2 */ |
| 253 | addr = addr0; | 253 | addr = addr0; |
| 254 | printk(PRINT_PREF "reading page at %#llx\n", (long long)addr); | 254 | pr_info("reading page at %#llx\n", (long long)addr); |
| 255 | err = mtd_read(mtd, addr, pgsize, &read, pp2); | 255 | err = mtd_read(mtd, addr, pgsize, &read, pp2); |
| 256 | if (mtd_is_bitflip(err)) | 256 | if (mtd_is_bitflip(err)) |
| 257 | err = 0; | 257 | err = 0; |
| 258 | if (err || read != pgsize) { | 258 | if (err || read != pgsize) { |
| 259 | printk(PRINT_PREF "error: read failed at %#llx\n", | 259 | pr_err("error: read failed at %#llx\n", |
| 260 | (long long)addr); | 260 | (long long)addr); |
| 261 | kfree(pp1); | 261 | kfree(pp1); |
| 262 | return err; | 262 | return err; |
| @@ -264,12 +264,12 @@ static int crosstest(void) | |||
| 264 | 264 | ||
| 265 | /* Read last page to pp3 */ | 265 | /* Read last page to pp3 */ |
| 266 | addr = addrn - pgsize; | 266 | addr = addrn - pgsize; |
| 267 | printk(PRINT_PREF "reading page at %#llx\n", (long long)addr); | 267 | pr_info("reading page at %#llx\n", (long long)addr); |
| 268 | err = mtd_read(mtd, addr, pgsize, &read, pp3); | 268 | err = mtd_read(mtd, addr, pgsize, &read, pp3); |
| 269 | if (mtd_is_bitflip(err)) | 269 | if (mtd_is_bitflip(err)) |
| 270 | err = 0; | 270 | err = 0; |
| 271 | if (err || read != pgsize) { | 271 | if (err || read != pgsize) { |
| 272 | printk(PRINT_PREF "error: read failed at %#llx\n", | 272 | pr_err("error: read failed at %#llx\n", |
| 273 | (long long)addr); | 273 | (long long)addr); |
| 274 | kfree(pp1); | 274 | kfree(pp1); |
| 275 | return err; | 275 | return err; |
| @@ -277,25 +277,25 @@ static int crosstest(void) | |||
| 277 | 277 | ||
| 278 | /* Read first page again to pp4 */ | 278 | /* Read first page again to pp4 */ |
| 279 | addr = addr0; | 279 | addr = addr0; |
| 280 | printk(PRINT_PREF "reading page at %#llx\n", (long long)addr); | 280 | pr_info("reading page at %#llx\n", (long long)addr); |
| 281 | err = mtd_read(mtd, addr, pgsize, &read, pp4); | 281 | err = mtd_read(mtd, addr, pgsize, &read, pp4); |
| 282 | if (mtd_is_bitflip(err)) | 282 | if (mtd_is_bitflip(err)) |
| 283 | err = 0; | 283 | err = 0; |
| 284 | if (err || read != pgsize) { | 284 | if (err || read != pgsize) { |
| 285 | printk(PRINT_PREF "error: read failed at %#llx\n", | 285 | pr_err("error: read failed at %#llx\n", |
| 286 | (long long)addr); | 286 | (long long)addr); |
| 287 | kfree(pp1); | 287 | kfree(pp1); |
| 288 | return err; | 288 | return err; |
| 289 | } | 289 | } |
| 290 | 290 | ||
| 291 | /* pp2 and pp4 should be the same */ | 291 | /* pp2 and pp4 should be the same */ |
| 292 | printk(PRINT_PREF "verifying pages read at %#llx match\n", | 292 | pr_info("verifying pages read at %#llx match\n", |
| 293 | (long long)addr0); | 293 | (long long)addr0); |
| 294 | if (memcmp(pp2, pp4, pgsize)) { | 294 | if (memcmp(pp2, pp4, pgsize)) { |
| 295 | printk(PRINT_PREF "verify failed!\n"); | 295 | pr_err("verify failed!\n"); |
| 296 | errcnt += 1; | 296 | errcnt += 1; |
| 297 | } else if (!err) | 297 | } else if (!err) |
| 298 | printk(PRINT_PREF "crosstest ok\n"); | 298 | pr_info("crosstest ok\n"); |
| 299 | kfree(pp1); | 299 | kfree(pp1); |
| 300 | return err; | 300 | return err; |
| 301 | } | 301 | } |
| @@ -307,7 +307,7 @@ static int erasecrosstest(void) | |||
| 307 | loff_t addr0; | 307 | loff_t addr0; |
| 308 | char *readbuf = twopages; | 308 | char *readbuf = twopages; |
| 309 | 309 | ||
| 310 | printk(PRINT_PREF "erasecrosstest\n"); | 310 | pr_info("erasecrosstest\n"); |
| 311 | 311 | ||
| 312 | ebnum = 0; | 312 | ebnum = 0; |
| 313 | addr0 = 0; | 313 | addr0 = 0; |
| @@ -320,79 +320,79 @@ static int erasecrosstest(void) | |||
| 320 | while (ebnum2 && bbt[ebnum2]) | 320 | while (ebnum2 && bbt[ebnum2]) |
| 321 | ebnum2 -= 1; | 321 | ebnum2 -= 1; |
| 322 | 322 | ||
| 323 | printk(PRINT_PREF "erasing block %d\n", ebnum); | 323 | pr_info("erasing block %d\n", ebnum); |
| 324 | err = erase_eraseblock(ebnum); | 324 | err = erase_eraseblock(ebnum); |
| 325 | if (err) | 325 | if (err) |
| 326 | return err; | 326 | return err; |
| 327 | 327 | ||
| 328 | printk(PRINT_PREF "writing 1st page of block %d\n", ebnum); | 328 | pr_info("writing 1st page of block %d\n", ebnum); |
| 329 | set_random_data(writebuf, pgsize); | 329 | set_random_data(writebuf, pgsize); |
| 330 | strcpy(writebuf, "There is no data like this!"); | 330 | strcpy(writebuf, "There is no data like this!"); |
| 331 | err = mtd_write(mtd, addr0, pgsize, &written, writebuf); | 331 | err = mtd_write(mtd, addr0, pgsize, &written, writebuf); |
| 332 | if (err || written != pgsize) { | 332 | if (err || written != pgsize) { |
| 333 | printk(PRINT_PREF "error: write failed at %#llx\n", | 333 | pr_info("error: write failed at %#llx\n", |
| 334 | (long long)addr0); | 334 | (long long)addr0); |
| 335 | return err ? err : -1; | 335 | return err ? err : -1; |
| 336 | } | 336 | } |
| 337 | 337 | ||
| 338 | printk(PRINT_PREF "reading 1st page of block %d\n", ebnum); | 338 | pr_info("reading 1st page of block %d\n", ebnum); |
| 339 | memset(readbuf, 0, pgsize); | 339 | memset(readbuf, 0, pgsize); |
| 340 | err = mtd_read(mtd, addr0, pgsize, &read, readbuf); | 340 | err = mtd_read(mtd, addr0, pgsize, &read, readbuf); |
| 341 | if (mtd_is_bitflip(err)) | 341 | if (mtd_is_bitflip(err)) |
| 342 | err = 0; | 342 | err = 0; |
| 343 | if (err || read != pgsize) { | 343 | if (err || read != pgsize) { |
| 344 | printk(PRINT_PREF "error: read failed at %#llx\n", | 344 | pr_err("error: read failed at %#llx\n", |
| 345 | (long long)addr0); | 345 | (long long)addr0); |
| 346 | return err ? err : -1; | 346 | return err ? err : -1; |
| 347 | } | 347 | } |
| 348 | 348 | ||
| 349 | printk(PRINT_PREF "verifying 1st page of block %d\n", ebnum); | 349 | pr_info("verifying 1st page of block %d\n", ebnum); |
| 350 | if (memcmp(writebuf, readbuf, pgsize)) { | 350 | if (memcmp(writebuf, readbuf, pgsize)) { |
| 351 | printk(PRINT_PREF "verify failed!\n"); | 351 | pr_err("verify failed!\n"); |
| 352 | errcnt += 1; | 352 | errcnt += 1; |
| 353 | return -1; | 353 | return -1; |
| 354 | } | 354 | } |
| 355 | 355 | ||
| 356 | printk(PRINT_PREF "erasing block %d\n", ebnum); | 356 | pr_info("erasing block %d\n", ebnum); |
| 357 | err = erase_eraseblock(ebnum); | 357 | err = erase_eraseblock(ebnum); |
| 358 | if (err) | 358 | if (err) |
| 359 | return err; | 359 | return err; |
| 360 | 360 | ||
| 361 | printk(PRINT_PREF "writing 1st page of block %d\n", ebnum); | 361 | pr_info("writing 1st page of block %d\n", ebnum); |
| 362 | set_random_data(writebuf, pgsize); | 362 | set_random_data(writebuf, pgsize); |
| 363 | strcpy(writebuf, "There is no data like this!"); | 363 | strcpy(writebuf, "There is no data like this!"); |
| 364 | err = mtd_write(mtd, addr0, pgsize, &written, writebuf); | 364 | err = mtd_write(mtd, addr0, pgsize, &written, writebuf); |
| 365 | if (err || written != pgsize) { | 365 | if (err || written != pgsize) { |
| 366 | printk(PRINT_PREF "error: write failed at %#llx\n", | 366 | pr_err("error: write failed at %#llx\n", |
| 367 | (long long)addr0); | 367 | (long long)addr0); |
| 368 | return err ? err : -1; | 368 | return err ? err : -1; |
| 369 | } | 369 | } |
| 370 | 370 | ||
| 371 | printk(PRINT_PREF "erasing block %d\n", ebnum2); | 371 | pr_info("erasing block %d\n", ebnum2); |
| 372 | err = erase_eraseblock(ebnum2); | 372 | err = erase_eraseblock(ebnum2); |
| 373 | if (err) | 373 | if (err) |
| 374 | return err; | 374 | return err; |
| 375 | 375 | ||
| 376 | printk(PRINT_PREF "reading 1st page of block %d\n", ebnum); | 376 | pr_info("reading 1st page of block %d\n", ebnum); |
| 377 | memset(readbuf, 0, pgsize); | 377 | memset(readbuf, 0, pgsize); |
| 378 | err = mtd_read(mtd, addr0, pgsize, &read, readbuf); | 378 | err = mtd_read(mtd, addr0, pgsize, &read, readbuf); |
| 379 | if (mtd_is_bitflip(err)) | 379 | if (mtd_is_bitflip(err)) |
| 380 | err = 0; | 380 | err = 0; |
| 381 | if (err || read != pgsize) { | 381 | if (err || read != pgsize) { |
| 382 | printk(PRINT_PREF "error: read failed at %#llx\n", | 382 | pr_err("error: read failed at %#llx\n", |
| 383 | (long long)addr0); | 383 | (long long)addr0); |
| 384 | return err ? err : -1; | 384 | return err ? err : -1; |
| 385 | } | 385 | } |
| 386 | 386 | ||
| 387 | printk(PRINT_PREF "verifying 1st page of block %d\n", ebnum); | 387 | pr_info("verifying 1st page of block %d\n", ebnum); |
| 388 | if (memcmp(writebuf, readbuf, pgsize)) { | 388 | if (memcmp(writebuf, readbuf, pgsize)) { |
| 389 | printk(PRINT_PREF "verify failed!\n"); | 389 | pr_err("verify failed!\n"); |
| 390 | errcnt += 1; | 390 | errcnt += 1; |
| 391 | return -1; | 391 | return -1; |
| 392 | } | 392 | } |
| 393 | 393 | ||
| 394 | if (!err) | 394 | if (!err) |
| 395 | printk(PRINT_PREF "erasecrosstest ok\n"); | 395 | pr_info("erasecrosstest ok\n"); |
| 396 | return err; | 396 | return err; |
| 397 | } | 397 | } |
| 398 | 398 | ||
| @@ -402,7 +402,7 @@ static int erasetest(void) | |||
| 402 | int err = 0, i, ebnum, ok = 1; | 402 | int err = 0, i, ebnum, ok = 1; |
| 403 | loff_t addr0; | 403 | loff_t addr0; |
| 404 | 404 | ||
| 405 | printk(PRINT_PREF "erasetest\n"); | 405 | pr_info("erasetest\n"); |
| 406 | 406 | ||
| 407 | ebnum = 0; | 407 | ebnum = 0; |
| 408 | addr0 = 0; | 408 | addr0 = 0; |
| @@ -411,40 +411,40 @@ static int erasetest(void) | |||
| 411 | ebnum += 1; | 411 | ebnum += 1; |
| 412 | } | 412 | } |
| 413 | 413 | ||
| 414 | printk(PRINT_PREF "erasing block %d\n", ebnum); | 414 | pr_info("erasing block %d\n", ebnum); |
| 415 | err = erase_eraseblock(ebnum); | 415 | err = erase_eraseblock(ebnum); |
| 416 | if (err) | 416 | if (err) |
| 417 | return err; | 417 | return err; |
| 418 | 418 | ||
| 419 | printk(PRINT_PREF "writing 1st page of block %d\n", ebnum); | 419 | pr_info("writing 1st page of block %d\n", ebnum); |
| 420 | set_random_data(writebuf, pgsize); | 420 | set_random_data(writebuf, pgsize); |
| 421 | err = mtd_write(mtd, addr0, pgsize, &written, writebuf); | 421 | err = mtd_write(mtd, addr0, pgsize, &written, writebuf); |
| 422 | if (err || written != pgsize) { | 422 | if (err || written != pgsize) { |
| 423 | printk(PRINT_PREF "error: write failed at %#llx\n", | 423 | pr_err("error: write failed at %#llx\n", |
| 424 | (long long)addr0); | 424 | (long long)addr0); |
| 425 | return err ? err : -1; | 425 | return err ? err : -1; |
| 426 | } | 426 | } |
| 427 | 427 | ||
| 428 | printk(PRINT_PREF "erasing block %d\n", ebnum); | 428 | pr_info("erasing block %d\n", ebnum); |
| 429 | err = erase_eraseblock(ebnum); | 429 | err = erase_eraseblock(ebnum); |
| 430 | if (err) | 430 | if (err) |
| 431 | return err; | 431 | return err; |
| 432 | 432 | ||
| 433 | printk(PRINT_PREF "reading 1st page of block %d\n", ebnum); | 433 | pr_info("reading 1st page of block %d\n", ebnum); |
| 434 | err = mtd_read(mtd, addr0, pgsize, &read, twopages); | 434 | err = mtd_read(mtd, addr0, pgsize, &read, twopages); |
| 435 | if (mtd_is_bitflip(err)) | 435 | if (mtd_is_bitflip(err)) |
| 436 | err = 0; | 436 | err = 0; |
| 437 | if (err || read != pgsize) { | 437 | if (err || read != pgsize) { |
| 438 | printk(PRINT_PREF "error: read failed at %#llx\n", | 438 | pr_err("error: read failed at %#llx\n", |
| 439 | (long long)addr0); | 439 | (long long)addr0); |
| 440 | return err ? err : -1; | 440 | return err ? err : -1; |
| 441 | } | 441 | } |
| 442 | 442 | ||
| 443 | printk(PRINT_PREF "verifying 1st page of block %d is all 0xff\n", | 443 | pr_info("verifying 1st page of block %d is all 0xff\n", |
| 444 | ebnum); | 444 | ebnum); |
| 445 | for (i = 0; i < pgsize; ++i) | 445 | for (i = 0; i < pgsize; ++i) |
| 446 | if (twopages[i] != 0xff) { | 446 | if (twopages[i] != 0xff) { |
| 447 | printk(PRINT_PREF "verifying all 0xff failed at %d\n", | 447 | pr_err("verifying all 0xff failed at %d\n", |
| 448 | i); | 448 | i); |
| 449 | errcnt += 1; | 449 | errcnt += 1; |
| 450 | ok = 0; | 450 | ok = 0; |
| @@ -452,7 +452,7 @@ static int erasetest(void) | |||
| 452 | } | 452 | } |
| 453 | 453 | ||
| 454 | if (ok && !err) | 454 | if (ok && !err) |
| 455 | printk(PRINT_PREF "erasetest ok\n"); | 455 | pr_info("erasetest ok\n"); |
| 456 | 456 | ||
| 457 | return err; | 457 | return err; |
| 458 | } | 458 | } |
| @@ -464,7 +464,7 @@ static int is_block_bad(int ebnum) | |||
| 464 | 464 | ||
| 465 | ret = mtd_block_isbad(mtd, addr); | 465 | ret = mtd_block_isbad(mtd, addr); |
| 466 | if (ret) | 466 | if (ret) |
| 467 | printk(PRINT_PREF "block %d is bad\n", ebnum); | 467 | pr_info("block %d is bad\n", ebnum); |
| 468 | return ret; | 468 | return ret; |
| 469 | } | 469 | } |
| 470 | 470 | ||
| @@ -474,18 +474,18 @@ static int scan_for_bad_eraseblocks(void) | |||
| 474 | 474 | ||
| 475 | bbt = kzalloc(ebcnt, GFP_KERNEL); | 475 | bbt = kzalloc(ebcnt, GFP_KERNEL); |
| 476 | if (!bbt) { | 476 | if (!bbt) { |
| 477 | printk(PRINT_PREF "error: cannot allocate memory\n"); | 477 | pr_err("error: cannot allocate memory\n"); |
| 478 | return -ENOMEM; | 478 | return -ENOMEM; |
| 479 | } | 479 | } |
| 480 | 480 | ||
| 481 | printk(PRINT_PREF "scanning for bad eraseblocks\n"); | 481 | pr_info("scanning for bad eraseblocks\n"); |
| 482 | for (i = 0; i < ebcnt; ++i) { | 482 | for (i = 0; i < ebcnt; ++i) { |
| 483 | bbt[i] = is_block_bad(i) ? 1 : 0; | 483 | bbt[i] = is_block_bad(i) ? 1 : 0; |
| 484 | if (bbt[i]) | 484 | if (bbt[i]) |
| 485 | bad += 1; | 485 | bad += 1; |
| 486 | cond_resched(); | 486 | cond_resched(); |
| 487 | } | 487 | } |
| 488 | printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad); | 488 | pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); |
| 489 | return 0; | 489 | return 0; |
| 490 | } | 490 | } |
| 491 | 491 | ||
| @@ -499,22 +499,22 @@ static int __init mtd_pagetest_init(void) | |||
| 499 | printk(KERN_INFO "=================================================\n"); | 499 | printk(KERN_INFO "=================================================\n"); |
| 500 | 500 | ||
| 501 | if (dev < 0) { | 501 | if (dev < 0) { |
| 502 | printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n"); | 502 | pr_info("Please specify a valid mtd-device via module parameter\n"); |
| 503 | printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n"); | 503 | pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); |
| 504 | return -EINVAL; | 504 | return -EINVAL; |
| 505 | } | 505 | } |
| 506 | 506 | ||
| 507 | printk(PRINT_PREF "MTD device: %d\n", dev); | 507 | pr_info("MTD device: %d\n", dev); |
| 508 | 508 | ||
| 509 | mtd = get_mtd_device(NULL, dev); | 509 | mtd = get_mtd_device(NULL, dev); |
| 510 | if (IS_ERR(mtd)) { | 510 | if (IS_ERR(mtd)) { |
| 511 | err = PTR_ERR(mtd); | 511 | err = PTR_ERR(mtd); |
| 512 | printk(PRINT_PREF "error: cannot get MTD device\n"); | 512 | pr_err("error: cannot get MTD device\n"); |
| 513 | return err; | 513 | return err; |
| 514 | } | 514 | } |
| 515 | 515 | ||
| 516 | if (mtd->type != MTD_NANDFLASH) { | 516 | if (mtd->type != MTD_NANDFLASH) { |
| 517 | printk(PRINT_PREF "this test requires NAND flash\n"); | 517 | pr_info("this test requires NAND flash\n"); |
| 518 | goto out; | 518 | goto out; |
| 519 | } | 519 | } |
| 520 | 520 | ||
| @@ -524,7 +524,7 @@ static int __init mtd_pagetest_init(void) | |||
| 524 | pgcnt = mtd->erasesize / mtd->writesize; | 524 | pgcnt = mtd->erasesize / mtd->writesize; |
| 525 | pgsize = mtd->writesize; | 525 | pgsize = mtd->writesize; |
| 526 | 526 | ||
| 527 | printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " | 527 | pr_info("MTD device size %llu, eraseblock size %u, " |
| 528 | "page size %u, count of eraseblocks %u, pages per " | 528 | "page size %u, count of eraseblocks %u, pages per " |
| 529 | "eraseblock %u, OOB size %u\n", | 529 | "eraseblock %u, OOB size %u\n", |
| 530 | (unsigned long long)mtd->size, mtd->erasesize, | 530 | (unsigned long long)mtd->size, mtd->erasesize, |
| @@ -534,17 +534,17 @@ static int __init mtd_pagetest_init(void) | |||
| 534 | bufsize = pgsize * 2; | 534 | bufsize = pgsize * 2; |
| 535 | writebuf = kmalloc(mtd->erasesize, GFP_KERNEL); | 535 | writebuf = kmalloc(mtd->erasesize, GFP_KERNEL); |
| 536 | if (!writebuf) { | 536 | if (!writebuf) { |
| 537 | printk(PRINT_PREF "error: cannot allocate memory\n"); | 537 | pr_err("error: cannot allocate memory\n"); |
| 538 | goto out; | 538 | goto out; |
| 539 | } | 539 | } |
| 540 | twopages = kmalloc(bufsize, GFP_KERNEL); | 540 | twopages = kmalloc(bufsize, GFP_KERNEL); |
| 541 | if (!twopages) { | 541 | if (!twopages) { |
| 542 | printk(PRINT_PREF "error: cannot allocate memory\n"); | 542 | pr_err("error: cannot allocate memory\n"); |
| 543 | goto out; | 543 | goto out; |
| 544 | } | 544 | } |
| 545 | boundary = kmalloc(bufsize, GFP_KERNEL); | 545 | boundary = kmalloc(bufsize, GFP_KERNEL); |
| 546 | if (!boundary) { | 546 | if (!boundary) { |
| 547 | printk(PRINT_PREF "error: cannot allocate memory\n"); | 547 | pr_err("error: cannot allocate memory\n"); |
| 548 | goto out; | 548 | goto out; |
| 549 | } | 549 | } |
| 550 | 550 | ||
| @@ -553,7 +553,7 @@ static int __init mtd_pagetest_init(void) | |||
| 553 | goto out; | 553 | goto out; |
| 554 | 554 | ||
| 555 | /* Erase all eraseblocks */ | 555 | /* Erase all eraseblocks */ |
| 556 | printk(PRINT_PREF "erasing whole device\n"); | 556 | pr_info("erasing whole device\n"); |
| 557 | for (i = 0; i < ebcnt; ++i) { | 557 | for (i = 0; i < ebcnt; ++i) { |
| 558 | if (bbt[i]) | 558 | if (bbt[i]) |
| 559 | continue; | 559 | continue; |
| @@ -562,11 +562,11 @@ static int __init mtd_pagetest_init(void) | |||
| 562 | goto out; | 562 | goto out; |
| 563 | cond_resched(); | 563 | cond_resched(); |
| 564 | } | 564 | } |
| 565 | printk(PRINT_PREF "erased %u eraseblocks\n", i); | 565 | pr_info("erased %u eraseblocks\n", i); |
| 566 | 566 | ||
| 567 | /* Write all eraseblocks */ | 567 | /* Write all eraseblocks */ |
| 568 | simple_srand(1); | 568 | simple_srand(1); |
| 569 | printk(PRINT_PREF "writing whole device\n"); | 569 | pr_info("writing whole device\n"); |
| 570 | for (i = 0; i < ebcnt; ++i) { | 570 | for (i = 0; i < ebcnt; ++i) { |
| 571 | if (bbt[i]) | 571 | if (bbt[i]) |
| 572 | continue; | 572 | continue; |
| @@ -574,14 +574,14 @@ static int __init mtd_pagetest_init(void) | |||
| 574 | if (err) | 574 | if (err) |
| 575 | goto out; | 575 | goto out; |
| 576 | if (i % 256 == 0) | 576 | if (i % 256 == 0) |
| 577 | printk(PRINT_PREF "written up to eraseblock %u\n", i); | 577 | pr_info("written up to eraseblock %u\n", i); |
| 578 | cond_resched(); | 578 | cond_resched(); |
| 579 | } | 579 | } |
| 580 | printk(PRINT_PREF "written %u eraseblocks\n", i); | 580 | pr_info("written %u eraseblocks\n", i); |
| 581 | 581 | ||
| 582 | /* Check all eraseblocks */ | 582 | /* Check all eraseblocks */ |
| 583 | simple_srand(1); | 583 | simple_srand(1); |
| 584 | printk(PRINT_PREF "verifying all eraseblocks\n"); | 584 | pr_info("verifying all eraseblocks\n"); |
| 585 | for (i = 0; i < ebcnt; ++i) { | 585 | for (i = 0; i < ebcnt; ++i) { |
| 586 | if (bbt[i]) | 586 | if (bbt[i]) |
| 587 | continue; | 587 | continue; |
| @@ -589,10 +589,10 @@ static int __init mtd_pagetest_init(void) | |||
| 589 | if (err) | 589 | if (err) |
| 590 | goto out; | 590 | goto out; |
| 591 | if (i % 256 == 0) | 591 | if (i % 256 == 0) |
| 592 | printk(PRINT_PREF "verified up to eraseblock %u\n", i); | 592 | pr_info("verified up to eraseblock %u\n", i); |
| 593 | cond_resched(); | 593 | cond_resched(); |
| 594 | } | 594 | } |
| 595 | printk(PRINT_PREF "verified %u eraseblocks\n", i); | 595 | pr_info("verified %u eraseblocks\n", i); |
| 596 | 596 | ||
| 597 | err = crosstest(); | 597 | err = crosstest(); |
| 598 | if (err) | 598 | if (err) |
| @@ -606,7 +606,7 @@ static int __init mtd_pagetest_init(void) | |||
| 606 | if (err) | 606 | if (err) |
| 607 | goto out; | 607 | goto out; |
| 608 | 608 | ||
| 609 | printk(PRINT_PREF "finished with %d errors\n", errcnt); | 609 | pr_info("finished with %d errors\n", errcnt); |
| 610 | out: | 610 | out: |
| 611 | 611 | ||
| 612 | kfree(bbt); | 612 | kfree(bbt); |
| @@ -615,7 +615,7 @@ out: | |||
| 615 | kfree(writebuf); | 615 | kfree(writebuf); |
| 616 | put_mtd_device(mtd); | 616 | put_mtd_device(mtd); |
| 617 | if (err) | 617 | if (err) |
| 618 | printk(PRINT_PREF "error %d occurred\n", err); | 618 | pr_info("error %d occurred\n", err); |
| 619 | printk(KERN_INFO "=================================================\n"); | 619 | printk(KERN_INFO "=================================================\n"); |
| 620 | return err; | 620 | return err; |
| 621 | } | 621 | } |
diff --git a/drivers/mtd/tests/mtd_readtest.c b/drivers/mtd/tests/mtd_readtest.c index 121aba189cec..266de04b6d29 100644 --- a/drivers/mtd/tests/mtd_readtest.c +++ b/drivers/mtd/tests/mtd_readtest.c | |||
| @@ -19,6 +19,8 @@ | |||
| 19 | * Author: Adrian Hunter <ext-adrian.hunter@nokia.com> | 19 | * Author: Adrian Hunter <ext-adrian.hunter@nokia.com> |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 23 | |||
| 22 | #include <linux/init.h> | 24 | #include <linux/init.h> |
| 23 | #include <linux/module.h> | 25 | #include <linux/module.h> |
| 24 | #include <linux/moduleparam.h> | 26 | #include <linux/moduleparam.h> |
| @@ -27,8 +29,6 @@ | |||
| 27 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
| 28 | #include <linux/sched.h> | 30 | #include <linux/sched.h> |
| 29 | 31 | ||
| 30 | #define PRINT_PREF KERN_INFO "mtd_readtest: " | ||
| 31 | |||
| 32 | static int dev = -EINVAL; | 32 | static int dev = -EINVAL; |
| 33 | module_param(dev, int, S_IRUGO); | 33 | module_param(dev, int, S_IRUGO); |
| 34 | MODULE_PARM_DESC(dev, "MTD device number to use"); | 34 | MODULE_PARM_DESC(dev, "MTD device number to use"); |
| @@ -51,12 +51,12 @@ static int read_eraseblock_by_page(int ebnum) | |||
| 51 | void *oobbuf = iobuf1; | 51 | void *oobbuf = iobuf1; |
| 52 | 52 | ||
| 53 | for (i = 0; i < pgcnt; i++) { | 53 | for (i = 0; i < pgcnt; i++) { |
| 54 | memset(buf, 0 , pgcnt); | 54 | memset(buf, 0 , pgsize); |
| 55 | ret = mtd_read(mtd, addr, pgsize, &read, buf); | 55 | ret = mtd_read(mtd, addr, pgsize, &read, buf); |
| 56 | if (ret == -EUCLEAN) | 56 | if (ret == -EUCLEAN) |
| 57 | ret = 0; | 57 | ret = 0; |
| 58 | if (ret || read != pgsize) { | 58 | if (ret || read != pgsize) { |
| 59 | printk(PRINT_PREF "error: read failed at %#llx\n", | 59 | pr_err("error: read failed at %#llx\n", |
| 60 | (long long)addr); | 60 | (long long)addr); |
| 61 | if (!err) | 61 | if (!err) |
| 62 | err = ret; | 62 | err = ret; |
| @@ -77,7 +77,7 @@ static int read_eraseblock_by_page(int ebnum) | |||
| 77 | ret = mtd_read_oob(mtd, addr, &ops); | 77 | ret = mtd_read_oob(mtd, addr, &ops); |
| 78 | if ((ret && !mtd_is_bitflip(ret)) || | 78 | if ((ret && !mtd_is_bitflip(ret)) || |
| 79 | ops.oobretlen != mtd->oobsize) { | 79 | ops.oobretlen != mtd->oobsize) { |
| 80 | printk(PRINT_PREF "error: read oob failed at " | 80 | pr_err("error: read oob failed at " |
| 81 | "%#llx\n", (long long)addr); | 81 | "%#llx\n", (long long)addr); |
| 82 | if (!err) | 82 | if (!err) |
| 83 | err = ret; | 83 | err = ret; |
| @@ -99,7 +99,7 @@ static void dump_eraseblock(int ebnum) | |||
| 99 | char line[128]; | 99 | char line[128]; |
| 100 | int pg, oob; | 100 | int pg, oob; |
| 101 | 101 | ||
| 102 | printk(PRINT_PREF "dumping eraseblock %d\n", ebnum); | 102 | pr_info("dumping eraseblock %d\n", ebnum); |
| 103 | n = mtd->erasesize; | 103 | n = mtd->erasesize; |
| 104 | for (i = 0; i < n;) { | 104 | for (i = 0; i < n;) { |
| 105 | char *p = line; | 105 | char *p = line; |
| @@ -112,7 +112,7 @@ static void dump_eraseblock(int ebnum) | |||
| 112 | } | 112 | } |
| 113 | if (!mtd->oobsize) | 113 | if (!mtd->oobsize) |
| 114 | return; | 114 | return; |
| 115 | printk(PRINT_PREF "dumping oob from eraseblock %d\n", ebnum); | 115 | pr_info("dumping oob from eraseblock %d\n", ebnum); |
| 116 | n = mtd->oobsize; | 116 | n = mtd->oobsize; |
| 117 | for (pg = 0, i = 0; pg < pgcnt; pg++) | 117 | for (pg = 0, i = 0; pg < pgcnt; pg++) |
| 118 | for (oob = 0; oob < n;) { | 118 | for (oob = 0; oob < n;) { |
| @@ -134,7 +134,7 @@ static int is_block_bad(int ebnum) | |||
| 134 | 134 | ||
| 135 | ret = mtd_block_isbad(mtd, addr); | 135 | ret = mtd_block_isbad(mtd, addr); |
| 136 | if (ret) | 136 | if (ret) |
| 137 | printk(PRINT_PREF "block %d is bad\n", ebnum); | 137 | pr_info("block %d is bad\n", ebnum); |
| 138 | return ret; | 138 | return ret; |
| 139 | } | 139 | } |
| 140 | 140 | ||
| @@ -144,21 +144,21 @@ static int scan_for_bad_eraseblocks(void) | |||
| 144 | 144 | ||
| 145 | bbt = kzalloc(ebcnt, GFP_KERNEL); | 145 | bbt = kzalloc(ebcnt, GFP_KERNEL); |
| 146 | if (!bbt) { | 146 | if (!bbt) { |
| 147 | printk(PRINT_PREF "error: cannot allocate memory\n"); | 147 | pr_err("error: cannot allocate memory\n"); |
| 148 | return -ENOMEM; | 148 | return -ENOMEM; |
| 149 | } | 149 | } |
| 150 | 150 | ||
| 151 | if (!mtd_can_have_bb(mtd)) | 151 | if (!mtd_can_have_bb(mtd)) |
| 152 | return 0; | 152 | return 0; |
| 153 | 153 | ||
| 154 | printk(PRINT_PREF "scanning for bad eraseblocks\n"); | 154 | pr_info("scanning for bad eraseblocks\n"); |
| 155 | for (i = 0; i < ebcnt; ++i) { | 155 | for (i = 0; i < ebcnt; ++i) { |
| 156 | bbt[i] = is_block_bad(i) ? 1 : 0; | 156 | bbt[i] = is_block_bad(i) ? 1 : 0; |
| 157 | if (bbt[i]) | 157 | if (bbt[i]) |
| 158 | bad += 1; | 158 | bad += 1; |
| 159 | cond_resched(); | 159 | cond_resched(); |
| 160 | } | 160 | } |
| 161 | printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad); | 161 | pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); |
| 162 | return 0; | 162 | return 0; |
| 163 | } | 163 | } |
| 164 | 164 | ||
| @@ -171,21 +171,21 @@ static int __init mtd_readtest_init(void) | |||
| 171 | printk(KERN_INFO "=================================================\n"); | 171 | printk(KERN_INFO "=================================================\n"); |
| 172 | 172 | ||
| 173 | if (dev < 0) { | 173 | if (dev < 0) { |
| 174 | printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n"); | 174 | pr_info("Please specify a valid mtd-device via module parameter\n"); |
| 175 | return -EINVAL; | 175 | return -EINVAL; |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 178 | printk(PRINT_PREF "MTD device: %d\n", dev); | 178 | pr_info("MTD device: %d\n", dev); |
| 179 | 179 | ||
| 180 | mtd = get_mtd_device(NULL, dev); | 180 | mtd = get_mtd_device(NULL, dev); |
| 181 | if (IS_ERR(mtd)) { | 181 | if (IS_ERR(mtd)) { |
| 182 | err = PTR_ERR(mtd); | 182 | err = PTR_ERR(mtd); |
| 183 | printk(PRINT_PREF "error: Cannot get MTD device\n"); | 183 | pr_err("error: Cannot get MTD device\n"); |
| 184 | return err; | 184 | return err; |
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | if (mtd->writesize == 1) { | 187 | if (mtd->writesize == 1) { |
| 188 | printk(PRINT_PREF "not NAND flash, assume page size is 512 " | 188 | pr_info("not NAND flash, assume page size is 512 " |
| 189 | "bytes.\n"); | 189 | "bytes.\n"); |
| 190 | pgsize = 512; | 190 | pgsize = 512; |
| 191 | } else | 191 | } else |
| @@ -196,7 +196,7 @@ static int __init mtd_readtest_init(void) | |||
| 196 | ebcnt = tmp; | 196 | ebcnt = tmp; |
| 197 | pgcnt = mtd->erasesize / pgsize; | 197 | pgcnt = mtd->erasesize / pgsize; |
| 198 | 198 | ||
| 199 | printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " | 199 | pr_info("MTD device size %llu, eraseblock size %u, " |
| 200 | "page size %u, count of eraseblocks %u, pages per " | 200 | "page size %u, count of eraseblocks %u, pages per " |
| 201 | "eraseblock %u, OOB size %u\n", | 201 | "eraseblock %u, OOB size %u\n", |
| 202 | (unsigned long long)mtd->size, mtd->erasesize, | 202 | (unsigned long long)mtd->size, mtd->erasesize, |
| @@ -205,12 +205,12 @@ static int __init mtd_readtest_init(void) | |||
| 205 | err = -ENOMEM; | 205 | err = -ENOMEM; |
| 206 | iobuf = kmalloc(mtd->erasesize, GFP_KERNEL); | 206 | iobuf = kmalloc(mtd->erasesize, GFP_KERNEL); |
| 207 | if (!iobuf) { | 207 | if (!iobuf) { |
| 208 | printk(PRINT_PREF "error: cannot allocate memory\n"); | 208 | pr_err("error: cannot allocate memory\n"); |
| 209 | goto out; | 209 | goto out; |
| 210 | } | 210 | } |
| 211 | iobuf1 = kmalloc(mtd->erasesize, GFP_KERNEL); | 211 | iobuf1 = kmalloc(mtd->erasesize, GFP_KERNEL); |
| 212 | if (!iobuf1) { | 212 | if (!iobuf1) { |
| 213 | printk(PRINT_PREF "error: cannot allocate memory\n"); | 213 | pr_err("error: cannot allocate memory\n"); |
| 214 | goto out; | 214 | goto out; |
| 215 | } | 215 | } |
| 216 | 216 | ||
| @@ -219,7 +219,7 @@ static int __init mtd_readtest_init(void) | |||
| 219 | goto out; | 219 | goto out; |
| 220 | 220 | ||
| 221 | /* Read all eraseblocks 1 page at a time */ | 221 | /* Read all eraseblocks 1 page at a time */ |
| 222 | printk(PRINT_PREF "testing page read\n"); | 222 | pr_info("testing page read\n"); |
| 223 | for (i = 0; i < ebcnt; ++i) { | 223 | for (i = 0; i < ebcnt; ++i) { |
| 224 | int ret; | 224 | int ret; |
| 225 | 225 | ||
| @@ -235,9 +235,9 @@ static int __init mtd_readtest_init(void) | |||
| 235 | } | 235 | } |
| 236 | 236 | ||
| 237 | if (err) | 237 | if (err) |
| 238 | printk(PRINT_PREF "finished with errors\n"); | 238 | pr_info("finished with errors\n"); |
| 239 | else | 239 | else |
| 240 | printk(PRINT_PREF "finished\n"); | 240 | pr_info("finished\n"); |
| 241 | 241 | ||
| 242 | out: | 242 | out: |
| 243 | 243 | ||
| @@ -246,7 +246,7 @@ out: | |||
| 246 | kfree(bbt); | 246 | kfree(bbt); |
| 247 | put_mtd_device(mtd); | 247 | put_mtd_device(mtd); |
| 248 | if (err) | 248 | if (err) |
| 249 | printk(PRINT_PREF "error %d occurred\n", err); | 249 | pr_info("error %d occurred\n", err); |
| 250 | printk(KERN_INFO "=================================================\n"); | 250 | printk(KERN_INFO "=================================================\n"); |
| 251 | return err; | 251 | return err; |
| 252 | } | 252 | } |
diff --git a/drivers/mtd/tests/mtd_speedtest.c b/drivers/mtd/tests/mtd_speedtest.c index 42b0f7456fc4..596cbea8df4c 100644 --- a/drivers/mtd/tests/mtd_speedtest.c +++ b/drivers/mtd/tests/mtd_speedtest.c | |||
| @@ -19,6 +19,8 @@ | |||
| 19 | * Author: Adrian Hunter <adrian.hunter@nokia.com> | 19 | * Author: Adrian Hunter <adrian.hunter@nokia.com> |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 23 | |||
| 22 | #include <linux/init.h> | 24 | #include <linux/init.h> |
| 23 | #include <linux/module.h> | 25 | #include <linux/module.h> |
| 24 | #include <linux/moduleparam.h> | 26 | #include <linux/moduleparam.h> |
| @@ -28,8 +30,6 @@ | |||
| 28 | #include <linux/sched.h> | 30 | #include <linux/sched.h> |
| 29 | #include <linux/random.h> | 31 | #include <linux/random.h> |
| 30 | 32 | ||
| 31 | #define PRINT_PREF KERN_INFO "mtd_speedtest: " | ||
| 32 | |||
| 33 | static int dev = -EINVAL; | 33 | static int dev = -EINVAL; |
| 34 | module_param(dev, int, S_IRUGO); | 34 | module_param(dev, int, S_IRUGO); |
| 35 | MODULE_PARM_DESC(dev, "MTD device number to use"); | 35 | MODULE_PARM_DESC(dev, "MTD device number to use"); |
| @@ -70,12 +70,12 @@ static int erase_eraseblock(int ebnum) | |||
| 70 | 70 | ||
| 71 | err = mtd_erase(mtd, &ei); | 71 | err = mtd_erase(mtd, &ei); |
| 72 | if (err) { | 72 | if (err) { |
| 73 | printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum); | 73 | pr_err("error %d while erasing EB %d\n", err, ebnum); |
| 74 | return err; | 74 | return err; |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | if (ei.state == MTD_ERASE_FAILED) { | 77 | if (ei.state == MTD_ERASE_FAILED) { |
| 78 | printk(PRINT_PREF "some erase error occurred at EB %d\n", | 78 | pr_err("some erase error occurred at EB %d\n", |
| 79 | ebnum); | 79 | ebnum); |
| 80 | return -EIO; | 80 | return -EIO; |
| 81 | } | 81 | } |
| @@ -96,13 +96,13 @@ static int multiblock_erase(int ebnum, int blocks) | |||
| 96 | 96 | ||
| 97 | err = mtd_erase(mtd, &ei); | 97 | err = mtd_erase(mtd, &ei); |
| 98 | if (err) { | 98 | if (err) { |
| 99 | printk(PRINT_PREF "error %d while erasing EB %d, blocks %d\n", | 99 | pr_err("error %d while erasing EB %d, blocks %d\n", |
| 100 | err, ebnum, blocks); | 100 | err, ebnum, blocks); |
| 101 | return err; | 101 | return err; |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | if (ei.state == MTD_ERASE_FAILED) { | 104 | if (ei.state == MTD_ERASE_FAILED) { |
| 105 | printk(PRINT_PREF "some erase error occurred at EB %d," | 105 | pr_err("some erase error occurred at EB %d," |
| 106 | "blocks %d\n", ebnum, blocks); | 106 | "blocks %d\n", ebnum, blocks); |
| 107 | return -EIO; | 107 | return -EIO; |
| 108 | } | 108 | } |
| @@ -134,7 +134,7 @@ static int write_eraseblock(int ebnum) | |||
| 134 | 134 | ||
| 135 | err = mtd_write(mtd, addr, mtd->erasesize, &written, iobuf); | 135 | err = mtd_write(mtd, addr, mtd->erasesize, &written, iobuf); |
| 136 | if (err || written != mtd->erasesize) { | 136 | if (err || written != mtd->erasesize) { |
| 137 | printk(PRINT_PREF "error: write failed at %#llx\n", addr); | 137 | pr_err("error: write failed at %#llx\n", addr); |
| 138 | if (!err) | 138 | if (!err) |
| 139 | err = -EINVAL; | 139 | err = -EINVAL; |
| 140 | } | 140 | } |
| @@ -152,7 +152,7 @@ static int write_eraseblock_by_page(int ebnum) | |||
| 152 | for (i = 0; i < pgcnt; i++) { | 152 | for (i = 0; i < pgcnt; i++) { |
| 153 | err = mtd_write(mtd, addr, pgsize, &written, buf); | 153 | err = mtd_write(mtd, addr, pgsize, &written, buf); |
| 154 | if (err || written != pgsize) { | 154 | if (err || written != pgsize) { |
| 155 | printk(PRINT_PREF "error: write failed at %#llx\n", | 155 | pr_err("error: write failed at %#llx\n", |
| 156 | addr); | 156 | addr); |
| 157 | if (!err) | 157 | if (!err) |
| 158 | err = -EINVAL; | 158 | err = -EINVAL; |
| @@ -175,7 +175,7 @@ static int write_eraseblock_by_2pages(int ebnum) | |||
| 175 | for (i = 0; i < n; i++) { | 175 | for (i = 0; i < n; i++) { |
| 176 | err = mtd_write(mtd, addr, sz, &written, buf); | 176 | err = mtd_write(mtd, addr, sz, &written, buf); |
| 177 | if (err || written != sz) { | 177 | if (err || written != sz) { |
| 178 | printk(PRINT_PREF "error: write failed at %#llx\n", | 178 | pr_err("error: write failed at %#llx\n", |
| 179 | addr); | 179 | addr); |
| 180 | if (!err) | 180 | if (!err) |
| 181 | err = -EINVAL; | 181 | err = -EINVAL; |
| @@ -187,7 +187,7 @@ static int write_eraseblock_by_2pages(int ebnum) | |||
| 187 | if (pgcnt % 2) { | 187 | if (pgcnt % 2) { |
| 188 | err = mtd_write(mtd, addr, pgsize, &written, buf); | 188 | err = mtd_write(mtd, addr, pgsize, &written, buf); |
| 189 | if (err || written != pgsize) { | 189 | if (err || written != pgsize) { |
| 190 | printk(PRINT_PREF "error: write failed at %#llx\n", | 190 | pr_err("error: write failed at %#llx\n", |
| 191 | addr); | 191 | addr); |
| 192 | if (!err) | 192 | if (!err) |
| 193 | err = -EINVAL; | 193 | err = -EINVAL; |
| @@ -208,7 +208,7 @@ static int read_eraseblock(int ebnum) | |||
| 208 | if (mtd_is_bitflip(err)) | 208 | if (mtd_is_bitflip(err)) |
| 209 | err = 0; | 209 | err = 0; |
| 210 | if (err || read != mtd->erasesize) { | 210 | if (err || read != mtd->erasesize) { |
| 211 | printk(PRINT_PREF "error: read failed at %#llx\n", addr); | 211 | pr_err("error: read failed at %#llx\n", addr); |
| 212 | if (!err) | 212 | if (!err) |
| 213 | err = -EINVAL; | 213 | err = -EINVAL; |
| 214 | } | 214 | } |
| @@ -229,7 +229,7 @@ static int read_eraseblock_by_page(int ebnum) | |||
| 229 | if (mtd_is_bitflip(err)) | 229 | if (mtd_is_bitflip(err)) |
| 230 | err = 0; | 230 | err = 0; |
| 231 | if (err || read != pgsize) { | 231 | if (err || read != pgsize) { |
| 232 | printk(PRINT_PREF "error: read failed at %#llx\n", | 232 | pr_err("error: read failed at %#llx\n", |
| 233 | addr); | 233 | addr); |
| 234 | if (!err) | 234 | if (!err) |
| 235 | err = -EINVAL; | 235 | err = -EINVAL; |
| @@ -255,7 +255,7 @@ static int read_eraseblock_by_2pages(int ebnum) | |||
| 255 | if (mtd_is_bitflip(err)) | 255 | if (mtd_is_bitflip(err)) |
| 256 | err = 0; | 256 | err = 0; |
| 257 | if (err || read != sz) { | 257 | if (err || read != sz) { |
| 258 | printk(PRINT_PREF "error: read failed at %#llx\n", | 258 | pr_err("error: read failed at %#llx\n", |
| 259 | addr); | 259 | addr); |
| 260 | if (!err) | 260 | if (!err) |
| 261 | err = -EINVAL; | 261 | err = -EINVAL; |
| @@ -270,7 +270,7 @@ static int read_eraseblock_by_2pages(int ebnum) | |||
| 270 | if (mtd_is_bitflip(err)) | 270 | if (mtd_is_bitflip(err)) |
| 271 | err = 0; | 271 | err = 0; |
| 272 | if (err || read != pgsize) { | 272 | if (err || read != pgsize) { |
| 273 | printk(PRINT_PREF "error: read failed at %#llx\n", | 273 | pr_err("error: read failed at %#llx\n", |
| 274 | addr); | 274 | addr); |
| 275 | if (!err) | 275 | if (!err) |
| 276 | err = -EINVAL; | 276 | err = -EINVAL; |
| @@ -287,7 +287,7 @@ static int is_block_bad(int ebnum) | |||
| 287 | 287 | ||
| 288 | ret = mtd_block_isbad(mtd, addr); | 288 | ret = mtd_block_isbad(mtd, addr); |
| 289 | if (ret) | 289 | if (ret) |
| 290 | printk(PRINT_PREF "block %d is bad\n", ebnum); | 290 | pr_info("block %d is bad\n", ebnum); |
| 291 | return ret; | 291 | return ret; |
| 292 | } | 292 | } |
| 293 | 293 | ||
| @@ -321,21 +321,21 @@ static int scan_for_bad_eraseblocks(void) | |||
| 321 | 321 | ||
| 322 | bbt = kzalloc(ebcnt, GFP_KERNEL); | 322 | bbt = kzalloc(ebcnt, GFP_KERNEL); |
| 323 | if (!bbt) { | 323 | if (!bbt) { |
| 324 | printk(PRINT_PREF "error: cannot allocate memory\n"); | 324 | pr_err("error: cannot allocate memory\n"); |
| 325 | return -ENOMEM; | 325 | return -ENOMEM; |
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | if (!mtd_can_have_bb(mtd)) | 328 | if (!mtd_can_have_bb(mtd)) |
| 329 | goto out; | 329 | goto out; |
| 330 | 330 | ||
| 331 | printk(PRINT_PREF "scanning for bad eraseblocks\n"); | 331 | pr_info("scanning for bad eraseblocks\n"); |
| 332 | for (i = 0; i < ebcnt; ++i) { | 332 | for (i = 0; i < ebcnt; ++i) { |
| 333 | bbt[i] = is_block_bad(i) ? 1 : 0; | 333 | bbt[i] = is_block_bad(i) ? 1 : 0; |
| 334 | if (bbt[i]) | 334 | if (bbt[i]) |
| 335 | bad += 1; | 335 | bad += 1; |
| 336 | cond_resched(); | 336 | cond_resched(); |
| 337 | } | 337 | } |
| 338 | printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad); | 338 | pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); |
| 339 | out: | 339 | out: |
| 340 | goodebcnt = ebcnt - bad; | 340 | goodebcnt = ebcnt - bad; |
| 341 | return 0; | 341 | return 0; |
| @@ -351,25 +351,25 @@ static int __init mtd_speedtest_init(void) | |||
| 351 | printk(KERN_INFO "=================================================\n"); | 351 | printk(KERN_INFO "=================================================\n"); |
| 352 | 352 | ||
| 353 | if (dev < 0) { | 353 | if (dev < 0) { |
| 354 | printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n"); | 354 | pr_info("Please specify a valid mtd-device via module parameter\n"); |
| 355 | printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n"); | 355 | pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); |
| 356 | return -EINVAL; | 356 | return -EINVAL; |
| 357 | } | 357 | } |
| 358 | 358 | ||
| 359 | if (count) | 359 | if (count) |
| 360 | printk(PRINT_PREF "MTD device: %d count: %d\n", dev, count); | 360 | pr_info("MTD device: %d count: %d\n", dev, count); |
| 361 | else | 361 | else |
| 362 | printk(PRINT_PREF "MTD device: %d\n", dev); | 362 | pr_info("MTD device: %d\n", dev); |
| 363 | 363 | ||
| 364 | mtd = get_mtd_device(NULL, dev); | 364 | mtd = get_mtd_device(NULL, dev); |
| 365 | if (IS_ERR(mtd)) { | 365 | if (IS_ERR(mtd)) { |
| 366 | err = PTR_ERR(mtd); | 366 | err = PTR_ERR(mtd); |
| 367 | printk(PRINT_PREF "error: cannot get MTD device\n"); | 367 | pr_err("error: cannot get MTD device\n"); |
| 368 | return err; | 368 | return err; |
| 369 | } | 369 | } |
| 370 | 370 | ||
| 371 | if (mtd->writesize == 1) { | 371 | if (mtd->writesize == 1) { |
| 372 | printk(PRINT_PREF "not NAND flash, assume page size is 512 " | 372 | pr_info("not NAND flash, assume page size is 512 " |
| 373 | "bytes.\n"); | 373 | "bytes.\n"); |
| 374 | pgsize = 512; | 374 | pgsize = 512; |
| 375 | } else | 375 | } else |
| @@ -380,7 +380,7 @@ static int __init mtd_speedtest_init(void) | |||
| 380 | ebcnt = tmp; | 380 | ebcnt = tmp; |
| 381 | pgcnt = mtd->erasesize / pgsize; | 381 | pgcnt = mtd->erasesize / pgsize; |
| 382 | 382 | ||
| 383 | printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " | 383 | pr_info("MTD device size %llu, eraseblock size %u, " |
| 384 | "page size %u, count of eraseblocks %u, pages per " | 384 | "page size %u, count of eraseblocks %u, pages per " |
| 385 | "eraseblock %u, OOB size %u\n", | 385 | "eraseblock %u, OOB size %u\n", |
| 386 | (unsigned long long)mtd->size, mtd->erasesize, | 386 | (unsigned long long)mtd->size, mtd->erasesize, |
| @@ -392,7 +392,7 @@ static int __init mtd_speedtest_init(void) | |||
| 392 | err = -ENOMEM; | 392 | err = -ENOMEM; |
| 393 | iobuf = kmalloc(mtd->erasesize, GFP_KERNEL); | 393 | iobuf = kmalloc(mtd->erasesize, GFP_KERNEL); |
| 394 | if (!iobuf) { | 394 | if (!iobuf) { |
| 395 | printk(PRINT_PREF "error: cannot allocate memory\n"); | 395 | pr_err("error: cannot allocate memory\n"); |
| 396 | goto out; | 396 | goto out; |
| 397 | } | 397 | } |
| 398 | 398 | ||
| @@ -407,7 +407,7 @@ static int __init mtd_speedtest_init(void) | |||
| 407 | goto out; | 407 | goto out; |
| 408 | 408 | ||
| 409 | /* Write all eraseblocks, 1 eraseblock at a time */ | 409 | /* Write all eraseblocks, 1 eraseblock at a time */ |
| 410 | printk(PRINT_PREF "testing eraseblock write speed\n"); | 410 | pr_info("testing eraseblock write speed\n"); |
| 411 | start_timing(); | 411 | start_timing(); |
| 412 | for (i = 0; i < ebcnt; ++i) { | 412 | for (i = 0; i < ebcnt; ++i) { |
| 413 | if (bbt[i]) | 413 | if (bbt[i]) |
| @@ -419,10 +419,10 @@ static int __init mtd_speedtest_init(void) | |||
| 419 | } | 419 | } |
| 420 | stop_timing(); | 420 | stop_timing(); |
| 421 | speed = calc_speed(); | 421 | speed = calc_speed(); |
| 422 | printk(PRINT_PREF "eraseblock write speed is %ld KiB/s\n", speed); | 422 | pr_info("eraseblock write speed is %ld KiB/s\n", speed); |
| 423 | 423 | ||
| 424 | /* Read all eraseblocks, 1 eraseblock at a time */ | 424 | /* Read all eraseblocks, 1 eraseblock at a time */ |
| 425 | printk(PRINT_PREF "testing eraseblock read speed\n"); | 425 | pr_info("testing eraseblock read speed\n"); |
| 426 | start_timing(); | 426 | start_timing(); |
| 427 | for (i = 0; i < ebcnt; ++i) { | 427 | for (i = 0; i < ebcnt; ++i) { |
| 428 | if (bbt[i]) | 428 | if (bbt[i]) |
| @@ -434,14 +434,14 @@ static int __init mtd_speedtest_init(void) | |||
| 434 | } | 434 | } |
| 435 | stop_timing(); | 435 | stop_timing(); |
| 436 | speed = calc_speed(); | 436 | speed = calc_speed(); |
| 437 | printk(PRINT_PREF "eraseblock read speed is %ld KiB/s\n", speed); | 437 | pr_info("eraseblock read speed is %ld KiB/s\n", speed); |
| 438 | 438 | ||
| 439 | err = erase_whole_device(); | 439 | err = erase_whole_device(); |
| 440 | if (err) | 440 | if (err) |
| 441 | goto out; | 441 | goto out; |
| 442 | 442 | ||
| 443 | /* Write all eraseblocks, 1 page at a time */ | 443 | /* Write all eraseblocks, 1 page at a time */ |
| 444 | printk(PRINT_PREF "testing page write speed\n"); | 444 | pr_info("testing page write speed\n"); |
| 445 | start_timing(); | 445 | start_timing(); |
| 446 | for (i = 0; i < ebcnt; ++i) { | 446 | for (i = 0; i < ebcnt; ++i) { |
| 447 | if (bbt[i]) | 447 | if (bbt[i]) |
| @@ -453,10 +453,10 @@ static int __init mtd_speedtest_init(void) | |||
| 453 | } | 453 | } |
| 454 | stop_timing(); | 454 | stop_timing(); |
| 455 | speed = calc_speed(); | 455 | speed = calc_speed(); |
| 456 | printk(PRINT_PREF "page write speed is %ld KiB/s\n", speed); | 456 | pr_info("page write speed is %ld KiB/s\n", speed); |
| 457 | 457 | ||
| 458 | /* Read all eraseblocks, 1 page at a time */ | 458 | /* Read all eraseblocks, 1 page at a time */ |
| 459 | printk(PRINT_PREF "testing page read speed\n"); | 459 | pr_info("testing page read speed\n"); |
| 460 | start_timing(); | 460 | start_timing(); |
| 461 | for (i = 0; i < ebcnt; ++i) { | 461 | for (i = 0; i < ebcnt; ++i) { |
| 462 | if (bbt[i]) | 462 | if (bbt[i]) |
| @@ -468,14 +468,14 @@ static int __init mtd_speedtest_init(void) | |||
| 468 | } | 468 | } |
| 469 | stop_timing(); | 469 | stop_timing(); |
| 470 | speed = calc_speed(); | 470 | speed = calc_speed(); |
| 471 | printk(PRINT_PREF "page read speed is %ld KiB/s\n", speed); | 471 | pr_info("page read speed is %ld KiB/s\n", speed); |
| 472 | 472 | ||
| 473 | err = erase_whole_device(); | 473 | err = erase_whole_device(); |
| 474 | if (err) | 474 | if (err) |
| 475 | goto out; | 475 | goto out; |
| 476 | 476 | ||
| 477 | /* Write all eraseblocks, 2 pages at a time */ | 477 | /* Write all eraseblocks, 2 pages at a time */ |
| 478 | printk(PRINT_PREF "testing 2 page write speed\n"); | 478 | pr_info("testing 2 page write speed\n"); |
| 479 | start_timing(); | 479 | start_timing(); |
| 480 | for (i = 0; i < ebcnt; ++i) { | 480 | for (i = 0; i < ebcnt; ++i) { |
| 481 | if (bbt[i]) | 481 | if (bbt[i]) |
| @@ -487,10 +487,10 @@ static int __init mtd_speedtest_init(void) | |||
| 487 | } | 487 | } |
| 488 | stop_timing(); | 488 | stop_timing(); |
| 489 | speed = calc_speed(); | 489 | speed = calc_speed(); |
| 490 | printk(PRINT_PREF "2 page write speed is %ld KiB/s\n", speed); | 490 | pr_info("2 page write speed is %ld KiB/s\n", speed); |
| 491 | 491 | ||
| 492 | /* Read all eraseblocks, 2 pages at a time */ | 492 | /* Read all eraseblocks, 2 pages at a time */ |
| 493 | printk(PRINT_PREF "testing 2 page read speed\n"); | 493 | pr_info("testing 2 page read speed\n"); |
| 494 | start_timing(); | 494 | start_timing(); |
| 495 | for (i = 0; i < ebcnt; ++i) { | 495 | for (i = 0; i < ebcnt; ++i) { |
| 496 | if (bbt[i]) | 496 | if (bbt[i]) |
| @@ -502,10 +502,10 @@ static int __init mtd_speedtest_init(void) | |||
| 502 | } | 502 | } |
| 503 | stop_timing(); | 503 | stop_timing(); |
| 504 | speed = calc_speed(); | 504 | speed = calc_speed(); |
| 505 | printk(PRINT_PREF "2 page read speed is %ld KiB/s\n", speed); | 505 | pr_info("2 page read speed is %ld KiB/s\n", speed); |
| 506 | 506 | ||
| 507 | /* Erase all eraseblocks */ | 507 | /* Erase all eraseblocks */ |
| 508 | printk(PRINT_PREF "Testing erase speed\n"); | 508 | pr_info("Testing erase speed\n"); |
| 509 | start_timing(); | 509 | start_timing(); |
| 510 | for (i = 0; i < ebcnt; ++i) { | 510 | for (i = 0; i < ebcnt; ++i) { |
| 511 | if (bbt[i]) | 511 | if (bbt[i]) |
| @@ -517,12 +517,12 @@ static int __init mtd_speedtest_init(void) | |||
| 517 | } | 517 | } |
| 518 | stop_timing(); | 518 | stop_timing(); |
| 519 | speed = calc_speed(); | 519 | speed = calc_speed(); |
| 520 | printk(PRINT_PREF "erase speed is %ld KiB/s\n", speed); | 520 | pr_info("erase speed is %ld KiB/s\n", speed); |
| 521 | 521 | ||
| 522 | /* Multi-block erase all eraseblocks */ | 522 | /* Multi-block erase all eraseblocks */ |
| 523 | for (k = 1; k < 7; k++) { | 523 | for (k = 1; k < 7; k++) { |
| 524 | blocks = 1 << k; | 524 | blocks = 1 << k; |
| 525 | printk(PRINT_PREF "Testing %dx multi-block erase speed\n", | 525 | pr_info("Testing %dx multi-block erase speed\n", |
| 526 | blocks); | 526 | blocks); |
| 527 | start_timing(); | 527 | start_timing(); |
| 528 | for (i = 0; i < ebcnt; ) { | 528 | for (i = 0; i < ebcnt; ) { |
| @@ -541,16 +541,16 @@ static int __init mtd_speedtest_init(void) | |||
| 541 | } | 541 | } |
| 542 | stop_timing(); | 542 | stop_timing(); |
| 543 | speed = calc_speed(); | 543 | speed = calc_speed(); |
| 544 | printk(PRINT_PREF "%dx multi-block erase speed is %ld KiB/s\n", | 544 | pr_info("%dx multi-block erase speed is %ld KiB/s\n", |
| 545 | blocks, speed); | 545 | blocks, speed); |
| 546 | } | 546 | } |
| 547 | printk(PRINT_PREF "finished\n"); | 547 | pr_info("finished\n"); |
| 548 | out: | 548 | out: |
| 549 | kfree(iobuf); | 549 | kfree(iobuf); |
| 550 | kfree(bbt); | 550 | kfree(bbt); |
| 551 | put_mtd_device(mtd); | 551 | put_mtd_device(mtd); |
| 552 | if (err) | 552 | if (err) |
| 553 | printk(PRINT_PREF "error %d occurred\n", err); | 553 | pr_info("error %d occurred\n", err); |
| 554 | printk(KERN_INFO "=================================================\n"); | 554 | printk(KERN_INFO "=================================================\n"); |
| 555 | return err; | 555 | return err; |
| 556 | } | 556 | } |
diff --git a/drivers/mtd/tests/mtd_stresstest.c b/drivers/mtd/tests/mtd_stresstest.c index cb268cebf01a..3729f679ae5d 100644 --- a/drivers/mtd/tests/mtd_stresstest.c +++ b/drivers/mtd/tests/mtd_stresstest.c | |||
| @@ -19,6 +19,8 @@ | |||
| 19 | * Author: Adrian Hunter <ext-adrian.hunter@nokia.com> | 19 | * Author: Adrian Hunter <ext-adrian.hunter@nokia.com> |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 23 | |||
| 22 | #include <linux/init.h> | 24 | #include <linux/init.h> |
| 23 | #include <linux/module.h> | 25 | #include <linux/module.h> |
| 24 | #include <linux/moduleparam.h> | 26 | #include <linux/moduleparam.h> |
| @@ -29,8 +31,6 @@ | |||
| 29 | #include <linux/vmalloc.h> | 31 | #include <linux/vmalloc.h> |
| 30 | #include <linux/random.h> | 32 | #include <linux/random.h> |
| 31 | 33 | ||
| 32 | #define PRINT_PREF KERN_INFO "mtd_stresstest: " | ||
| 33 | |||
| 34 | static int dev = -EINVAL; | 34 | static int dev = -EINVAL; |
| 35 | module_param(dev, int, S_IRUGO); | 35 | module_param(dev, int, S_IRUGO); |
| 36 | MODULE_PARM_DESC(dev, "MTD device number to use"); | 36 | MODULE_PARM_DESC(dev, "MTD device number to use"); |
| @@ -94,12 +94,12 @@ static int erase_eraseblock(int ebnum) | |||
| 94 | 94 | ||
| 95 | err = mtd_erase(mtd, &ei); | 95 | err = mtd_erase(mtd, &ei); |
| 96 | if (unlikely(err)) { | 96 | if (unlikely(err)) { |
| 97 | printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum); | 97 | pr_err("error %d while erasing EB %d\n", err, ebnum); |
| 98 | return err; | 98 | return err; |
| 99 | } | 99 | } |
| 100 | 100 | ||
| 101 | if (unlikely(ei.state == MTD_ERASE_FAILED)) { | 101 | if (unlikely(ei.state == MTD_ERASE_FAILED)) { |
| 102 | printk(PRINT_PREF "some erase error occurred at EB %d\n", | 102 | pr_err("some erase error occurred at EB %d\n", |
| 103 | ebnum); | 103 | ebnum); |
| 104 | return -EIO; | 104 | return -EIO; |
| 105 | } | 105 | } |
| @@ -114,7 +114,7 @@ static int is_block_bad(int ebnum) | |||
| 114 | 114 | ||
| 115 | ret = mtd_block_isbad(mtd, addr); | 115 | ret = mtd_block_isbad(mtd, addr); |
| 116 | if (ret) | 116 | if (ret) |
| 117 | printk(PRINT_PREF "block %d is bad\n", ebnum); | 117 | pr_info("block %d is bad\n", ebnum); |
| 118 | return ret; | 118 | return ret; |
| 119 | } | 119 | } |
| 120 | 120 | ||
| @@ -137,7 +137,7 @@ static int do_read(void) | |||
| 137 | if (mtd_is_bitflip(err)) | 137 | if (mtd_is_bitflip(err)) |
| 138 | err = 0; | 138 | err = 0; |
| 139 | if (unlikely(err || read != len)) { | 139 | if (unlikely(err || read != len)) { |
| 140 | printk(PRINT_PREF "error: read failed at 0x%llx\n", | 140 | pr_err("error: read failed at 0x%llx\n", |
| 141 | (long long)addr); | 141 | (long long)addr); |
| 142 | if (!err) | 142 | if (!err) |
| 143 | err = -EINVAL; | 143 | err = -EINVAL; |
| @@ -174,7 +174,7 @@ static int do_write(void) | |||
| 174 | addr = eb * mtd->erasesize + offs; | 174 | addr = eb * mtd->erasesize + offs; |
| 175 | err = mtd_write(mtd, addr, len, &written, writebuf); | 175 | err = mtd_write(mtd, addr, len, &written, writebuf); |
| 176 | if (unlikely(err || written != len)) { | 176 | if (unlikely(err || written != len)) { |
| 177 | printk(PRINT_PREF "error: write failed at 0x%llx\n", | 177 | pr_err("error: write failed at 0x%llx\n", |
| 178 | (long long)addr); | 178 | (long long)addr); |
| 179 | if (!err) | 179 | if (!err) |
| 180 | err = -EINVAL; | 180 | err = -EINVAL; |
| @@ -203,21 +203,21 @@ static int scan_for_bad_eraseblocks(void) | |||
| 203 | 203 | ||
| 204 | bbt = kzalloc(ebcnt, GFP_KERNEL); | 204 | bbt = kzalloc(ebcnt, GFP_KERNEL); |
| 205 | if (!bbt) { | 205 | if (!bbt) { |
| 206 | printk(PRINT_PREF "error: cannot allocate memory\n"); | 206 | pr_err("error: cannot allocate memory\n"); |
| 207 | return -ENOMEM; | 207 | return -ENOMEM; |
| 208 | } | 208 | } |
| 209 | 209 | ||
| 210 | if (!mtd_can_have_bb(mtd)) | 210 | if (!mtd_can_have_bb(mtd)) |
| 211 | return 0; | 211 | return 0; |
| 212 | 212 | ||
| 213 | printk(PRINT_PREF "scanning for bad eraseblocks\n"); | 213 | pr_info("scanning for bad eraseblocks\n"); |
| 214 | for (i = 0; i < ebcnt; ++i) { | 214 | for (i = 0; i < ebcnt; ++i) { |
| 215 | bbt[i] = is_block_bad(i) ? 1 : 0; | 215 | bbt[i] = is_block_bad(i) ? 1 : 0; |
| 216 | if (bbt[i]) | 216 | if (bbt[i]) |
| 217 | bad += 1; | 217 | bad += 1; |
| 218 | cond_resched(); | 218 | cond_resched(); |
| 219 | } | 219 | } |
| 220 | printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad); | 220 | pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); |
| 221 | return 0; | 221 | return 0; |
| 222 | } | 222 | } |
| 223 | 223 | ||
| @@ -231,22 +231,22 @@ static int __init mtd_stresstest_init(void) | |||
| 231 | printk(KERN_INFO "=================================================\n"); | 231 | printk(KERN_INFO "=================================================\n"); |
| 232 | 232 | ||
| 233 | if (dev < 0) { | 233 | if (dev < 0) { |
| 234 | printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n"); | 234 | pr_info("Please specify a valid mtd-device via module parameter\n"); |
| 235 | printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n"); | 235 | pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); |
| 236 | return -EINVAL; | 236 | return -EINVAL; |
| 237 | } | 237 | } |
| 238 | 238 | ||
| 239 | printk(PRINT_PREF "MTD device: %d\n", dev); | 239 | pr_info("MTD device: %d\n", dev); |
| 240 | 240 | ||
| 241 | mtd = get_mtd_device(NULL, dev); | 241 | mtd = get_mtd_device(NULL, dev); |
| 242 | if (IS_ERR(mtd)) { | 242 | if (IS_ERR(mtd)) { |
| 243 | err = PTR_ERR(mtd); | 243 | err = PTR_ERR(mtd); |
| 244 | printk(PRINT_PREF "error: cannot get MTD device\n"); | 244 | pr_err("error: cannot get MTD device\n"); |
| 245 | return err; | 245 | return err; |
| 246 | } | 246 | } |
| 247 | 247 | ||
| 248 | if (mtd->writesize == 1) { | 248 | if (mtd->writesize == 1) { |
| 249 | printk(PRINT_PREF "not NAND flash, assume page size is 512 " | 249 | pr_info("not NAND flash, assume page size is 512 " |
| 250 | "bytes.\n"); | 250 | "bytes.\n"); |
| 251 | pgsize = 512; | 251 | pgsize = 512; |
| 252 | } else | 252 | } else |
| @@ -257,14 +257,14 @@ static int __init mtd_stresstest_init(void) | |||
| 257 | ebcnt = tmp; | 257 | ebcnt = tmp; |
| 258 | pgcnt = mtd->erasesize / pgsize; | 258 | pgcnt = mtd->erasesize / pgsize; |
| 259 | 259 | ||
| 260 | printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " | 260 | pr_info("MTD device size %llu, eraseblock size %u, " |
| 261 | "page size %u, count of eraseblocks %u, pages per " | 261 | "page size %u, count of eraseblocks %u, pages per " |
| 262 | "eraseblock %u, OOB size %u\n", | 262 | "eraseblock %u, OOB size %u\n", |
| 263 | (unsigned long long)mtd->size, mtd->erasesize, | 263 | (unsigned long long)mtd->size, mtd->erasesize, |
| 264 | pgsize, ebcnt, pgcnt, mtd->oobsize); | 264 | pgsize, ebcnt, pgcnt, mtd->oobsize); |
| 265 | 265 | ||
| 266 | if (ebcnt < 2) { | 266 | if (ebcnt < 2) { |
| 267 | printk(PRINT_PREF "error: need at least 2 eraseblocks\n"); | 267 | pr_err("error: need at least 2 eraseblocks\n"); |
| 268 | err = -ENOSPC; | 268 | err = -ENOSPC; |
| 269 | goto out_put_mtd; | 269 | goto out_put_mtd; |
| 270 | } | 270 | } |
| @@ -277,7 +277,7 @@ static int __init mtd_stresstest_init(void) | |||
| 277 | writebuf = vmalloc(bufsize); | 277 | writebuf = vmalloc(bufsize); |
| 278 | offsets = kmalloc(ebcnt * sizeof(int), GFP_KERNEL); | 278 | offsets = kmalloc(ebcnt * sizeof(int), GFP_KERNEL); |
| 279 | if (!readbuf || !writebuf || !offsets) { | 279 | if (!readbuf || !writebuf || !offsets) { |
| 280 | printk(PRINT_PREF "error: cannot allocate memory\n"); | 280 | pr_err("error: cannot allocate memory\n"); |
| 281 | goto out; | 281 | goto out; |
| 282 | } | 282 | } |
| 283 | for (i = 0; i < ebcnt; i++) | 283 | for (i = 0; i < ebcnt; i++) |
| @@ -290,16 +290,16 @@ static int __init mtd_stresstest_init(void) | |||
| 290 | goto out; | 290 | goto out; |
| 291 | 291 | ||
| 292 | /* Do operations */ | 292 | /* Do operations */ |
| 293 | printk(PRINT_PREF "doing operations\n"); | 293 | pr_info("doing operations\n"); |
| 294 | for (op = 0; op < count; op++) { | 294 | for (op = 0; op < count; op++) { |
| 295 | if ((op & 1023) == 0) | 295 | if ((op & 1023) == 0) |
| 296 | printk(PRINT_PREF "%d operations done\n", op); | 296 | pr_info("%d operations done\n", op); |
| 297 | err = do_operation(); | 297 | err = do_operation(); |
| 298 | if (err) | 298 | if (err) |
| 299 | goto out; | 299 | goto out; |
| 300 | cond_resched(); | 300 | cond_resched(); |
| 301 | } | 301 | } |
| 302 | printk(PRINT_PREF "finished, %d operations done\n", op); | 302 | pr_info("finished, %d operations done\n", op); |
| 303 | 303 | ||
| 304 | out: | 304 | out: |
| 305 | kfree(offsets); | 305 | kfree(offsets); |
| @@ -309,7 +309,7 @@ out: | |||
| 309 | out_put_mtd: | 309 | out_put_mtd: |
| 310 | put_mtd_device(mtd); | 310 | put_mtd_device(mtd); |
| 311 | if (err) | 311 | if (err) |
| 312 | printk(PRINT_PREF "error %d occurred\n", err); | 312 | pr_info("error %d occurred\n", err); |
| 313 | printk(KERN_INFO "=================================================\n"); | 313 | printk(KERN_INFO "=================================================\n"); |
| 314 | return err; | 314 | return err; |
| 315 | } | 315 | } |
diff --git a/drivers/mtd/tests/mtd_subpagetest.c b/drivers/mtd/tests/mtd_subpagetest.c index 9667bf535282..c880c2229c59 100644 --- a/drivers/mtd/tests/mtd_subpagetest.c +++ b/drivers/mtd/tests/mtd_subpagetest.c | |||
| @@ -19,6 +19,8 @@ | |||
| 19 | * | 19 | * |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 23 | |||
| 22 | #include <linux/init.h> | 24 | #include <linux/init.h> |
| 23 | #include <linux/module.h> | 25 | #include <linux/module.h> |
| 24 | #include <linux/moduleparam.h> | 26 | #include <linux/moduleparam.h> |
| @@ -27,8 +29,6 @@ | |||
| 27 | #include <linux/slab.h> | 29 | #include <linux/slab.h> |
| 28 | #include <linux/sched.h> | 30 | #include <linux/sched.h> |
| 29 | 31 | ||
| 30 | #define PRINT_PREF KERN_INFO "mtd_subpagetest: " | ||
| 31 | |||
| 32 | static int dev = -EINVAL; | 32 | static int dev = -EINVAL; |
| 33 | module_param(dev, int, S_IRUGO); | 33 | module_param(dev, int, S_IRUGO); |
| 34 | MODULE_PARM_DESC(dev, "MTD device number to use"); | 34 | MODULE_PARM_DESC(dev, "MTD device number to use"); |
| @@ -82,12 +82,12 @@ static int erase_eraseblock(int ebnum) | |||
| 82 | 82 | ||
| 83 | err = mtd_erase(mtd, &ei); | 83 | err = mtd_erase(mtd, &ei); |
| 84 | if (err) { | 84 | if (err) { |
| 85 | printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum); | 85 | pr_err("error %d while erasing EB %d\n", err, ebnum); |
| 86 | return err; | 86 | return err; |
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | if (ei.state == MTD_ERASE_FAILED) { | 89 | if (ei.state == MTD_ERASE_FAILED) { |
| 90 | printk(PRINT_PREF "some erase error occurred at EB %d\n", | 90 | pr_err("some erase error occurred at EB %d\n", |
| 91 | ebnum); | 91 | ebnum); |
| 92 | return -EIO; | 92 | return -EIO; |
| 93 | } | 93 | } |
| @@ -100,7 +100,7 @@ static int erase_whole_device(void) | |||
| 100 | int err; | 100 | int err; |
| 101 | unsigned int i; | 101 | unsigned int i; |
| 102 | 102 | ||
| 103 | printk(PRINT_PREF "erasing whole device\n"); | 103 | pr_info("erasing whole device\n"); |
| 104 | for (i = 0; i < ebcnt; ++i) { | 104 | for (i = 0; i < ebcnt; ++i) { |
| 105 | if (bbt[i]) | 105 | if (bbt[i]) |
| 106 | continue; | 106 | continue; |
| @@ -109,7 +109,7 @@ static int erase_whole_device(void) | |||
| 109 | return err; | 109 | return err; |
| 110 | cond_resched(); | 110 | cond_resched(); |
| 111 | } | 111 | } |
| 112 | printk(PRINT_PREF "erased %u eraseblocks\n", i); | 112 | pr_info("erased %u eraseblocks\n", i); |
| 113 | return 0; | 113 | return 0; |
| 114 | } | 114 | } |
| 115 | 115 | ||
| @@ -122,11 +122,11 @@ static int write_eraseblock(int ebnum) | |||
| 122 | set_random_data(writebuf, subpgsize); | 122 | set_random_data(writebuf, subpgsize); |
| 123 | err = mtd_write(mtd, addr, subpgsize, &written, writebuf); | 123 | err = mtd_write(mtd, addr, subpgsize, &written, writebuf); |
| 124 | if (unlikely(err || written != subpgsize)) { | 124 | if (unlikely(err || written != subpgsize)) { |
| 125 | printk(PRINT_PREF "error: write failed at %#llx\n", | 125 | pr_err("error: write failed at %#llx\n", |
| 126 | (long long)addr); | 126 | (long long)addr); |
| 127 | if (written != subpgsize) { | 127 | if (written != subpgsize) { |
| 128 | printk(PRINT_PREF " write size: %#x\n", subpgsize); | 128 | pr_err(" write size: %#x\n", subpgsize); |
| 129 | printk(PRINT_PREF " written: %#zx\n", written); | 129 | pr_err(" written: %#zx\n", written); |
| 130 | } | 130 | } |
| 131 | return err ? err : -1; | 131 | return err ? err : -1; |
| 132 | } | 132 | } |
| @@ -136,11 +136,11 @@ static int write_eraseblock(int ebnum) | |||
| 136 | set_random_data(writebuf, subpgsize); | 136 | set_random_data(writebuf, subpgsize); |
| 137 | err = mtd_write(mtd, addr, subpgsize, &written, writebuf); | 137 | err = mtd_write(mtd, addr, subpgsize, &written, writebuf); |
| 138 | if (unlikely(err || written != subpgsize)) { | 138 | if (unlikely(err || written != subpgsize)) { |
| 139 | printk(PRINT_PREF "error: write failed at %#llx\n", | 139 | pr_err("error: write failed at %#llx\n", |
| 140 | (long long)addr); | 140 | (long long)addr); |
| 141 | if (written != subpgsize) { | 141 | if (written != subpgsize) { |
| 142 | printk(PRINT_PREF " write size: %#x\n", subpgsize); | 142 | pr_err(" write size: %#x\n", subpgsize); |
| 143 | printk(PRINT_PREF " written: %#zx\n", written); | 143 | pr_err(" written: %#zx\n", written); |
| 144 | } | 144 | } |
| 145 | return err ? err : -1; | 145 | return err ? err : -1; |
| 146 | } | 146 | } |
| @@ -160,12 +160,12 @@ static int write_eraseblock2(int ebnum) | |||
| 160 | set_random_data(writebuf, subpgsize * k); | 160 | set_random_data(writebuf, subpgsize * k); |
| 161 | err = mtd_write(mtd, addr, subpgsize * k, &written, writebuf); | 161 | err = mtd_write(mtd, addr, subpgsize * k, &written, writebuf); |
| 162 | if (unlikely(err || written != subpgsize * k)) { | 162 | if (unlikely(err || written != subpgsize * k)) { |
| 163 | printk(PRINT_PREF "error: write failed at %#llx\n", | 163 | pr_err("error: write failed at %#llx\n", |
| 164 | (long long)addr); | 164 | (long long)addr); |
| 165 | if (written != subpgsize) { | 165 | if (written != subpgsize) { |
| 166 | printk(PRINT_PREF " write size: %#x\n", | 166 | pr_err(" write size: %#x\n", |
| 167 | subpgsize * k); | 167 | subpgsize * k); |
| 168 | printk(PRINT_PREF " written: %#08zx\n", | 168 | pr_err(" written: %#08zx\n", |
| 169 | written); | 169 | written); |
| 170 | } | 170 | } |
| 171 | return err ? err : -1; | 171 | return err ? err : -1; |
| @@ -198,23 +198,23 @@ static int verify_eraseblock(int ebnum) | |||
| 198 | err = mtd_read(mtd, addr, subpgsize, &read, readbuf); | 198 | err = mtd_read(mtd, addr, subpgsize, &read, readbuf); |
| 199 | if (unlikely(err || read != subpgsize)) { | 199 | if (unlikely(err || read != subpgsize)) { |
| 200 | if (mtd_is_bitflip(err) && read == subpgsize) { | 200 | if (mtd_is_bitflip(err) && read == subpgsize) { |
| 201 | printk(PRINT_PREF "ECC correction at %#llx\n", | 201 | pr_info("ECC correction at %#llx\n", |
| 202 | (long long)addr); | 202 | (long long)addr); |
| 203 | err = 0; | 203 | err = 0; |
| 204 | } else { | 204 | } else { |
| 205 | printk(PRINT_PREF "error: read failed at %#llx\n", | 205 | pr_err("error: read failed at %#llx\n", |
| 206 | (long long)addr); | 206 | (long long)addr); |
| 207 | return err ? err : -1; | 207 | return err ? err : -1; |
| 208 | } | 208 | } |
| 209 | } | 209 | } |
| 210 | if (unlikely(memcmp(readbuf, writebuf, subpgsize))) { | 210 | if (unlikely(memcmp(readbuf, writebuf, subpgsize))) { |
| 211 | printk(PRINT_PREF "error: verify failed at %#llx\n", | 211 | pr_err("error: verify failed at %#llx\n", |
| 212 | (long long)addr); | 212 | (long long)addr); |
| 213 | printk(PRINT_PREF "------------- written----------------\n"); | 213 | pr_info("------------- written----------------\n"); |
| 214 | print_subpage(writebuf); | 214 | print_subpage(writebuf); |
| 215 | printk(PRINT_PREF "------------- read ------------------\n"); | 215 | pr_info("------------- read ------------------\n"); |
| 216 | print_subpage(readbuf); | 216 | print_subpage(readbuf); |
| 217 | printk(PRINT_PREF "-------------------------------------\n"); | 217 | pr_info("-------------------------------------\n"); |
| 218 | errcnt += 1; | 218 | errcnt += 1; |
| 219 | } | 219 | } |
| 220 | 220 | ||
| @@ -225,23 +225,23 @@ static int verify_eraseblock(int ebnum) | |||
| 225 | err = mtd_read(mtd, addr, subpgsize, &read, readbuf); | 225 | err = mtd_read(mtd, addr, subpgsize, &read, readbuf); |
| 226 | if (unlikely(err || read != subpgsize)) { | 226 | if (unlikely(err || read != subpgsize)) { |
| 227 | if (mtd_is_bitflip(err) && read == subpgsize) { | 227 | if (mtd_is_bitflip(err) && read == subpgsize) { |
| 228 | printk(PRINT_PREF "ECC correction at %#llx\n", | 228 | pr_info("ECC correction at %#llx\n", |
| 229 | (long long)addr); | 229 | (long long)addr); |
| 230 | err = 0; | 230 | err = 0; |
| 231 | } else { | 231 | } else { |
| 232 | printk(PRINT_PREF "error: read failed at %#llx\n", | 232 | pr_err("error: read failed at %#llx\n", |
| 233 | (long long)addr); | 233 | (long long)addr); |
| 234 | return err ? err : -1; | 234 | return err ? err : -1; |
| 235 | } | 235 | } |
| 236 | } | 236 | } |
| 237 | if (unlikely(memcmp(readbuf, writebuf, subpgsize))) { | 237 | if (unlikely(memcmp(readbuf, writebuf, subpgsize))) { |
| 238 | printk(PRINT_PREF "error: verify failed at %#llx\n", | 238 | pr_info("error: verify failed at %#llx\n", |
| 239 | (long long)addr); | 239 | (long long)addr); |
| 240 | printk(PRINT_PREF "------------- written----------------\n"); | 240 | pr_info("------------- written----------------\n"); |
| 241 | print_subpage(writebuf); | 241 | print_subpage(writebuf); |
| 242 | printk(PRINT_PREF "------------- read ------------------\n"); | 242 | pr_info("------------- read ------------------\n"); |
| 243 | print_subpage(readbuf); | 243 | print_subpage(readbuf); |
| 244 | printk(PRINT_PREF "-------------------------------------\n"); | 244 | pr_info("-------------------------------------\n"); |
| 245 | errcnt += 1; | 245 | errcnt += 1; |
| 246 | } | 246 | } |
| 247 | 247 | ||
| @@ -262,17 +262,17 @@ static int verify_eraseblock2(int ebnum) | |||
| 262 | err = mtd_read(mtd, addr, subpgsize * k, &read, readbuf); | 262 | err = mtd_read(mtd, addr, subpgsize * k, &read, readbuf); |
| 263 | if (unlikely(err || read != subpgsize * k)) { | 263 | if (unlikely(err || read != subpgsize * k)) { |
| 264 | if (mtd_is_bitflip(err) && read == subpgsize * k) { | 264 | if (mtd_is_bitflip(err) && read == subpgsize * k) { |
| 265 | printk(PRINT_PREF "ECC correction at %#llx\n", | 265 | pr_info("ECC correction at %#llx\n", |
| 266 | (long long)addr); | 266 | (long long)addr); |
| 267 | err = 0; | 267 | err = 0; |
| 268 | } else { | 268 | } else { |
| 269 | printk(PRINT_PREF "error: read failed at " | 269 | pr_err("error: read failed at " |
| 270 | "%#llx\n", (long long)addr); | 270 | "%#llx\n", (long long)addr); |
| 271 | return err ? err : -1; | 271 | return err ? err : -1; |
| 272 | } | 272 | } |
| 273 | } | 273 | } |
| 274 | if (unlikely(memcmp(readbuf, writebuf, subpgsize * k))) { | 274 | if (unlikely(memcmp(readbuf, writebuf, subpgsize * k))) { |
| 275 | printk(PRINT_PREF "error: verify failed at %#llx\n", | 275 | pr_err("error: verify failed at %#llx\n", |
| 276 | (long long)addr); | 276 | (long long)addr); |
| 277 | errcnt += 1; | 277 | errcnt += 1; |
| 278 | } | 278 | } |
| @@ -295,17 +295,17 @@ static int verify_eraseblock_ff(int ebnum) | |||
| 295 | err = mtd_read(mtd, addr, subpgsize, &read, readbuf); | 295 | err = mtd_read(mtd, addr, subpgsize, &read, readbuf); |
| 296 | if (unlikely(err || read != subpgsize)) { | 296 | if (unlikely(err || read != subpgsize)) { |
| 297 | if (mtd_is_bitflip(err) && read == subpgsize) { | 297 | if (mtd_is_bitflip(err) && read == subpgsize) { |
| 298 | printk(PRINT_PREF "ECC correction at %#llx\n", | 298 | pr_info("ECC correction at %#llx\n", |
| 299 | (long long)addr); | 299 | (long long)addr); |
| 300 | err = 0; | 300 | err = 0; |
| 301 | } else { | 301 | } else { |
| 302 | printk(PRINT_PREF "error: read failed at " | 302 | pr_err("error: read failed at " |
| 303 | "%#llx\n", (long long)addr); | 303 | "%#llx\n", (long long)addr); |
| 304 | return err ? err : -1; | 304 | return err ? err : -1; |
| 305 | } | 305 | } |
| 306 | } | 306 | } |
| 307 | if (unlikely(memcmp(readbuf, writebuf, subpgsize))) { | 307 | if (unlikely(memcmp(readbuf, writebuf, subpgsize))) { |
| 308 | printk(PRINT_PREF "error: verify 0xff failed at " | 308 | pr_err("error: verify 0xff failed at " |
| 309 | "%#llx\n", (long long)addr); | 309 | "%#llx\n", (long long)addr); |
| 310 | errcnt += 1; | 310 | errcnt += 1; |
| 311 | } | 311 | } |
| @@ -320,7 +320,7 @@ static int verify_all_eraseblocks_ff(void) | |||
| 320 | int err; | 320 | int err; |
| 321 | unsigned int i; | 321 | unsigned int i; |
| 322 | 322 | ||
| 323 | printk(PRINT_PREF "verifying all eraseblocks for 0xff\n"); | 323 | pr_info("verifying all eraseblocks for 0xff\n"); |
| 324 | for (i = 0; i < ebcnt; ++i) { | 324 | for (i = 0; i < ebcnt; ++i) { |
| 325 | if (bbt[i]) | 325 | if (bbt[i]) |
| 326 | continue; | 326 | continue; |
| @@ -328,10 +328,10 @@ static int verify_all_eraseblocks_ff(void) | |||
| 328 | if (err) | 328 | if (err) |
| 329 | return err; | 329 | return err; |
| 330 | if (i % 256 == 0) | 330 | if (i % 256 == 0) |
| 331 | printk(PRINT_PREF "verified up to eraseblock %u\n", i); | 331 | pr_info("verified up to eraseblock %u\n", i); |
| 332 | cond_resched(); | 332 | cond_resched(); |
| 333 | } | 333 | } |
| 334 | printk(PRINT_PREF "verified %u eraseblocks\n", i); | 334 | pr_info("verified %u eraseblocks\n", i); |
| 335 | return 0; | 335 | return 0; |
| 336 | } | 336 | } |
| 337 | 337 | ||
| @@ -342,7 +342,7 @@ static int is_block_bad(int ebnum) | |||
| 342 | 342 | ||
| 343 | ret = mtd_block_isbad(mtd, addr); | 343 | ret = mtd_block_isbad(mtd, addr); |
| 344 | if (ret) | 344 | if (ret) |
| 345 | printk(PRINT_PREF "block %d is bad\n", ebnum); | 345 | pr_info("block %d is bad\n", ebnum); |
| 346 | return ret; | 346 | return ret; |
| 347 | } | 347 | } |
| 348 | 348 | ||
| @@ -352,18 +352,18 @@ static int scan_for_bad_eraseblocks(void) | |||
| 352 | 352 | ||
| 353 | bbt = kzalloc(ebcnt, GFP_KERNEL); | 353 | bbt = kzalloc(ebcnt, GFP_KERNEL); |
| 354 | if (!bbt) { | 354 | if (!bbt) { |
| 355 | printk(PRINT_PREF "error: cannot allocate memory\n"); | 355 | pr_err("error: cannot allocate memory\n"); |
| 356 | return -ENOMEM; | 356 | return -ENOMEM; |
| 357 | } | 357 | } |
| 358 | 358 | ||
| 359 | printk(PRINT_PREF "scanning for bad eraseblocks\n"); | 359 | pr_info("scanning for bad eraseblocks\n"); |
| 360 | for (i = 0; i < ebcnt; ++i) { | 360 | for (i = 0; i < ebcnt; ++i) { |
| 361 | bbt[i] = is_block_bad(i) ? 1 : 0; | 361 | bbt[i] = is_block_bad(i) ? 1 : 0; |
| 362 | if (bbt[i]) | 362 | if (bbt[i]) |
| 363 | bad += 1; | 363 | bad += 1; |
| 364 | cond_resched(); | 364 | cond_resched(); |
| 365 | } | 365 | } |
| 366 | printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad); | 366 | pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); |
| 367 | return 0; | 367 | return 0; |
| 368 | } | 368 | } |
| 369 | 369 | ||
| @@ -377,22 +377,22 @@ static int __init mtd_subpagetest_init(void) | |||
| 377 | printk(KERN_INFO "=================================================\n"); | 377 | printk(KERN_INFO "=================================================\n"); |
| 378 | 378 | ||
| 379 | if (dev < 0) { | 379 | if (dev < 0) { |
| 380 | printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n"); | 380 | pr_info("Please specify a valid mtd-device via module parameter\n"); |
| 381 | printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n"); | 381 | pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); |
| 382 | return -EINVAL; | 382 | return -EINVAL; |
| 383 | } | 383 | } |
| 384 | 384 | ||
| 385 | printk(PRINT_PREF "MTD device: %d\n", dev); | 385 | pr_info("MTD device: %d\n", dev); |
| 386 | 386 | ||
| 387 | mtd = get_mtd_device(NULL, dev); | 387 | mtd = get_mtd_device(NULL, dev); |
| 388 | if (IS_ERR(mtd)) { | 388 | if (IS_ERR(mtd)) { |
| 389 | err = PTR_ERR(mtd); | 389 | err = PTR_ERR(mtd); |
| 390 | printk(PRINT_PREF "error: cannot get MTD device\n"); | 390 | pr_err("error: cannot get MTD device\n"); |
| 391 | return err; | 391 | return err; |
| 392 | } | 392 | } |
| 393 | 393 | ||
| 394 | if (mtd->type != MTD_NANDFLASH) { | 394 | if (mtd->type != MTD_NANDFLASH) { |
| 395 | printk(PRINT_PREF "this test requires NAND flash\n"); | 395 | pr_info("this test requires NAND flash\n"); |
| 396 | goto out; | 396 | goto out; |
| 397 | } | 397 | } |
| 398 | 398 | ||
| @@ -402,7 +402,7 @@ static int __init mtd_subpagetest_init(void) | |||
| 402 | ebcnt = tmp; | 402 | ebcnt = tmp; |
| 403 | pgcnt = mtd->erasesize / mtd->writesize; | 403 | pgcnt = mtd->erasesize / mtd->writesize; |
| 404 | 404 | ||
| 405 | printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " | 405 | pr_info("MTD device size %llu, eraseblock size %u, " |
| 406 | "page size %u, subpage size %u, count of eraseblocks %u, " | 406 | "page size %u, subpage size %u, count of eraseblocks %u, " |
| 407 | "pages per eraseblock %u, OOB size %u\n", | 407 | "pages per eraseblock %u, OOB size %u\n", |
| 408 | (unsigned long long)mtd->size, mtd->erasesize, | 408 | (unsigned long long)mtd->size, mtd->erasesize, |
| @@ -412,12 +412,12 @@ static int __init mtd_subpagetest_init(void) | |||
| 412 | bufsize = subpgsize * 32; | 412 | bufsize = subpgsize * 32; |
| 413 | writebuf = kmalloc(bufsize, GFP_KERNEL); | 413 | writebuf = kmalloc(bufsize, GFP_KERNEL); |
| 414 | if (!writebuf) { | 414 | if (!writebuf) { |
| 415 | printk(PRINT_PREF "error: cannot allocate memory\n"); | 415 | pr_info("error: cannot allocate memory\n"); |
| 416 | goto out; | 416 | goto out; |
| 417 | } | 417 | } |
| 418 | readbuf = kmalloc(bufsize, GFP_KERNEL); | 418 | readbuf = kmalloc(bufsize, GFP_KERNEL); |
| 419 | if (!readbuf) { | 419 | if (!readbuf) { |
| 420 | printk(PRINT_PREF "error: cannot allocate memory\n"); | 420 | pr_info("error: cannot allocate memory\n"); |
| 421 | goto out; | 421 | goto out; |
| 422 | } | 422 | } |
| 423 | 423 | ||
| @@ -429,7 +429,7 @@ static int __init mtd_subpagetest_init(void) | |||
| 429 | if (err) | 429 | if (err) |
| 430 | goto out; | 430 | goto out; |
| 431 | 431 | ||
| 432 | printk(PRINT_PREF "writing whole device\n"); | 432 | pr_info("writing whole device\n"); |
| 433 | simple_srand(1); | 433 | simple_srand(1); |
| 434 | for (i = 0; i < ebcnt; ++i) { | 434 | for (i = 0; i < ebcnt; ++i) { |
| 435 | if (bbt[i]) | 435 | if (bbt[i]) |
| @@ -438,13 +438,13 @@ static int __init mtd_subpagetest_init(void) | |||
| 438 | if (unlikely(err)) | 438 | if (unlikely(err)) |
| 439 | goto out; | 439 | goto out; |
| 440 | if (i % 256 == 0) | 440 | if (i % 256 == 0) |
| 441 | printk(PRINT_PREF "written up to eraseblock %u\n", i); | 441 | pr_info("written up to eraseblock %u\n", i); |
| 442 | cond_resched(); | 442 | cond_resched(); |
| 443 | } | 443 | } |
| 444 | printk(PRINT_PREF "written %u eraseblocks\n", i); | 444 | pr_info("written %u eraseblocks\n", i); |
| 445 | 445 | ||
| 446 | simple_srand(1); | 446 | simple_srand(1); |
| 447 | printk(PRINT_PREF "verifying all eraseblocks\n"); | 447 | pr_info("verifying all eraseblocks\n"); |
| 448 | for (i = 0; i < ebcnt; ++i) { | 448 | for (i = 0; i < ebcnt; ++i) { |
| 449 | if (bbt[i]) | 449 | if (bbt[i]) |
| 450 | continue; | 450 | continue; |
| @@ -452,10 +452,10 @@ static int __init mtd_subpagetest_init(void) | |||
| 452 | if (unlikely(err)) | 452 | if (unlikely(err)) |
| 453 | goto out; | 453 | goto out; |
| 454 | if (i % 256 == 0) | 454 | if (i % 256 == 0) |
| 455 | printk(PRINT_PREF "verified up to eraseblock %u\n", i); | 455 | pr_info("verified up to eraseblock %u\n", i); |
| 456 | cond_resched(); | 456 | cond_resched(); |
| 457 | } | 457 | } |
| 458 | printk(PRINT_PREF "verified %u eraseblocks\n", i); | 458 | pr_info("verified %u eraseblocks\n", i); |
| 459 | 459 | ||
| 460 | err = erase_whole_device(); | 460 | err = erase_whole_device(); |
| 461 | if (err) | 461 | if (err) |
| @@ -467,7 +467,7 @@ static int __init mtd_subpagetest_init(void) | |||
| 467 | 467 | ||
| 468 | /* Write all eraseblocks */ | 468 | /* Write all eraseblocks */ |
| 469 | simple_srand(3); | 469 | simple_srand(3); |
| 470 | printk(PRINT_PREF "writing whole device\n"); | 470 | pr_info("writing whole device\n"); |
| 471 | for (i = 0; i < ebcnt; ++i) { | 471 | for (i = 0; i < ebcnt; ++i) { |
| 472 | if (bbt[i]) | 472 | if (bbt[i]) |
| 473 | continue; | 473 | continue; |
| @@ -475,14 +475,14 @@ static int __init mtd_subpagetest_init(void) | |||
| 475 | if (unlikely(err)) | 475 | if (unlikely(err)) |
| 476 | goto out; | 476 | goto out; |
| 477 | if (i % 256 == 0) | 477 | if (i % 256 == 0) |
| 478 | printk(PRINT_PREF "written up to eraseblock %u\n", i); | 478 | pr_info("written up to eraseblock %u\n", i); |
| 479 | cond_resched(); | 479 | cond_resched(); |
| 480 | } | 480 | } |
| 481 | printk(PRINT_PREF "written %u eraseblocks\n", i); | 481 | pr_info("written %u eraseblocks\n", i); |
| 482 | 482 | ||
| 483 | /* Check all eraseblocks */ | 483 | /* Check all eraseblocks */ |
| 484 | simple_srand(3); | 484 | simple_srand(3); |
| 485 | printk(PRINT_PREF "verifying all eraseblocks\n"); | 485 | pr_info("verifying all eraseblocks\n"); |
| 486 | for (i = 0; i < ebcnt; ++i) { | 486 | for (i = 0; i < ebcnt; ++i) { |
| 487 | if (bbt[i]) | 487 | if (bbt[i]) |
| 488 | continue; | 488 | continue; |
| @@ -490,10 +490,10 @@ static int __init mtd_subpagetest_init(void) | |||
| 490 | if (unlikely(err)) | 490 | if (unlikely(err)) |
| 491 | goto out; | 491 | goto out; |
| 492 | if (i % 256 == 0) | 492 | if (i % 256 == 0) |
| 493 | printk(PRINT_PREF "verified up to eraseblock %u\n", i); | 493 | pr_info("verified up to eraseblock %u\n", i); |
| 494 | cond_resched(); | 494 | cond_resched(); |
| 495 | } | 495 | } |
| 496 | printk(PRINT_PREF "verified %u eraseblocks\n", i); | 496 | pr_info("verified %u eraseblocks\n", i); |
| 497 | 497 | ||
| 498 | err = erase_whole_device(); | 498 | err = erase_whole_device(); |
| 499 | if (err) | 499 | if (err) |
| @@ -503,7 +503,7 @@ static int __init mtd_subpagetest_init(void) | |||
| 503 | if (err) | 503 | if (err) |
| 504 | goto out; | 504 | goto out; |
| 505 | 505 | ||
| 506 | printk(PRINT_PREF "finished with %d errors\n", errcnt); | 506 | pr_info("finished with %d errors\n", errcnt); |
| 507 | 507 | ||
| 508 | out: | 508 | out: |
| 509 | kfree(bbt); | 509 | kfree(bbt); |
| @@ -511,7 +511,7 @@ out: | |||
| 511 | kfree(writebuf); | 511 | kfree(writebuf); |
| 512 | put_mtd_device(mtd); | 512 | put_mtd_device(mtd); |
| 513 | if (err) | 513 | if (err) |
| 514 | printk(PRINT_PREF "error %d occurred\n", err); | 514 | pr_info("error %d occurred\n", err); |
| 515 | printk(KERN_INFO "=================================================\n"); | 515 | printk(KERN_INFO "=================================================\n"); |
| 516 | return err; | 516 | return err; |
| 517 | } | 517 | } |
diff --git a/drivers/mtd/tests/mtd_torturetest.c b/drivers/mtd/tests/mtd_torturetest.c index b65861bc7b8e..c4cde1e9eddb 100644 --- a/drivers/mtd/tests/mtd_torturetest.c +++ b/drivers/mtd/tests/mtd_torturetest.c | |||
| @@ -23,6 +23,8 @@ | |||
| 23 | * damage caused by this program. | 23 | * damage caused by this program. |
| 24 | */ | 24 | */ |
| 25 | 25 | ||
| 26 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
| 27 | |||
| 26 | #include <linux/init.h> | 28 | #include <linux/init.h> |
| 27 | #include <linux/module.h> | 29 | #include <linux/module.h> |
| 28 | #include <linux/moduleparam.h> | 30 | #include <linux/moduleparam.h> |
| @@ -31,7 +33,6 @@ | |||
| 31 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
| 32 | #include <linux/sched.h> | 34 | #include <linux/sched.h> |
| 33 | 35 | ||
| 34 | #define PRINT_PREF KERN_INFO "mtd_torturetest: " | ||
| 35 | #define RETRIES 3 | 36 | #define RETRIES 3 |
| 36 | 37 | ||
| 37 | static int eb = 8; | 38 | static int eb = 8; |
| @@ -107,12 +108,12 @@ static inline int erase_eraseblock(int ebnum) | |||
| 107 | 108 | ||
| 108 | err = mtd_erase(mtd, &ei); | 109 | err = mtd_erase(mtd, &ei); |
| 109 | if (err) { | 110 | if (err) { |
| 110 | printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum); | 111 | pr_err("error %d while erasing EB %d\n", err, ebnum); |
| 111 | return err; | 112 | return err; |
| 112 | } | 113 | } |
| 113 | 114 | ||
| 114 | if (ei.state == MTD_ERASE_FAILED) { | 115 | if (ei.state == MTD_ERASE_FAILED) { |
| 115 | printk(PRINT_PREF "some erase error occurred at EB %d\n", | 116 | pr_err("some erase error occurred at EB %d\n", |
| 116 | ebnum); | 117 | ebnum); |
| 117 | return -EIO; | 118 | return -EIO; |
| 118 | } | 119 | } |
| @@ -139,40 +140,40 @@ static inline int check_eraseblock(int ebnum, unsigned char *buf) | |||
| 139 | retry: | 140 | retry: |
| 140 | err = mtd_read(mtd, addr, len, &read, check_buf); | 141 | err = mtd_read(mtd, addr, len, &read, check_buf); |
| 141 | if (mtd_is_bitflip(err)) | 142 | if (mtd_is_bitflip(err)) |
| 142 | printk(PRINT_PREF "single bit flip occurred at EB %d " | 143 | pr_err("single bit flip occurred at EB %d " |
| 143 | "MTD reported that it was fixed.\n", ebnum); | 144 | "MTD reported that it was fixed.\n", ebnum); |
| 144 | else if (err) { | 145 | else if (err) { |
| 145 | printk(PRINT_PREF "error %d while reading EB %d, " | 146 | pr_err("error %d while reading EB %d, " |
| 146 | "read %zd\n", err, ebnum, read); | 147 | "read %zd\n", err, ebnum, read); |
| 147 | return err; | 148 | return err; |
| 148 | } | 149 | } |
| 149 | 150 | ||
| 150 | if (read != len) { | 151 | if (read != len) { |
| 151 | printk(PRINT_PREF "failed to read %zd bytes from EB %d, " | 152 | pr_err("failed to read %zd bytes from EB %d, " |
| 152 | "read only %zd, but no error reported\n", | 153 | "read only %zd, but no error reported\n", |
| 153 | len, ebnum, read); | 154 | len, ebnum, read); |
| 154 | return -EIO; | 155 | return -EIO; |
| 155 | } | 156 | } |
| 156 | 157 | ||
| 157 | if (memcmp(buf, check_buf, len)) { | 158 | if (memcmp(buf, check_buf, len)) { |
| 158 | printk(PRINT_PREF "read wrong data from EB %d\n", ebnum); | 159 | pr_err("read wrong data from EB %d\n", ebnum); |
| 159 | report_corrupt(check_buf, buf); | 160 | report_corrupt(check_buf, buf); |
| 160 | 161 | ||
| 161 | if (retries++ < RETRIES) { | 162 | if (retries++ < RETRIES) { |
| 162 | /* Try read again */ | 163 | /* Try read again */ |
| 163 | yield(); | 164 | yield(); |
| 164 | printk(PRINT_PREF "re-try reading data from EB %d\n", | 165 | pr_info("re-try reading data from EB %d\n", |
| 165 | ebnum); | 166 | ebnum); |
| 166 | goto retry; | 167 | goto retry; |
| 167 | } else { | 168 | } else { |
| 168 | printk(PRINT_PREF "retried %d times, still errors, " | 169 | pr_info("retried %d times, still errors, " |
| 169 | "give-up\n", RETRIES); | 170 | "give-up\n", RETRIES); |
| 170 | return -EINVAL; | 171 | return -EINVAL; |
| 171 | } | 172 | } |
| 172 | } | 173 | } |
| 173 | 174 | ||
| 174 | if (retries != 0) | 175 | if (retries != 0) |
| 175 | printk(PRINT_PREF "only attempt number %d was OK (!!!)\n", | 176 | pr_info("only attempt number %d was OK (!!!)\n", |
| 176 | retries); | 177 | retries); |
| 177 | 178 | ||
| 178 | return 0; | 179 | return 0; |
| @@ -191,12 +192,12 @@ static inline int write_pattern(int ebnum, void *buf) | |||
| 191 | } | 192 | } |
| 192 | err = mtd_write(mtd, addr, len, &written, buf); | 193 | err = mtd_write(mtd, addr, len, &written, buf); |
| 193 | if (err) { | 194 | if (err) { |
| 194 | printk(PRINT_PREF "error %d while writing EB %d, written %zd" | 195 | pr_err("error %d while writing EB %d, written %zd" |
| 195 | " bytes\n", err, ebnum, written); | 196 | " bytes\n", err, ebnum, written); |
| 196 | return err; | 197 | return err; |
| 197 | } | 198 | } |
| 198 | if (written != len) { | 199 | if (written != len) { |
| 199 | printk(PRINT_PREF "written only %zd bytes of %zd, but no error" | 200 | pr_info("written only %zd bytes of %zd, but no error" |
| 200 | " reported\n", written, len); | 201 | " reported\n", written, len); |
| 201 | return -EIO; | 202 | return -EIO; |
| 202 | } | 203 | } |
| @@ -211,64 +212,64 @@ static int __init tort_init(void) | |||
| 211 | 212 | ||
| 212 | printk(KERN_INFO "\n"); | 213 | printk(KERN_INFO "\n"); |
| 213 | printk(KERN_INFO "=================================================\n"); | 214 | printk(KERN_INFO "=================================================\n"); |
| 214 | printk(PRINT_PREF "Warning: this program is trying to wear out your " | 215 | pr_info("Warning: this program is trying to wear out your " |
| 215 | "flash, stop it if this is not wanted.\n"); | 216 | "flash, stop it if this is not wanted.\n"); |
| 216 | 217 | ||
| 217 | if (dev < 0) { | 218 | if (dev < 0) { |
| 218 | printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n"); | 219 | pr_info("Please specify a valid mtd-device via module parameter\n"); |
| 219 | printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n"); | 220 | pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); |
| 220 | return -EINVAL; | 221 | return -EINVAL; |
| 221 | } | 222 | } |
| 222 | 223 | ||
| 223 | printk(PRINT_PREF "MTD device: %d\n", dev); | 224 | pr_info("MTD device: %d\n", dev); |
| 224 | printk(PRINT_PREF "torture %d eraseblocks (%d-%d) of mtd%d\n", | 225 | pr_info("torture %d eraseblocks (%d-%d) of mtd%d\n", |
| 225 | ebcnt, eb, eb + ebcnt - 1, dev); | 226 | ebcnt, eb, eb + ebcnt - 1, dev); |
| 226 | if (pgcnt) | 227 | if (pgcnt) |
| 227 | printk(PRINT_PREF "torturing just %d pages per eraseblock\n", | 228 | pr_info("torturing just %d pages per eraseblock\n", |
| 228 | pgcnt); | 229 | pgcnt); |
| 229 | printk(PRINT_PREF "write verify %s\n", check ? "enabled" : "disabled"); | 230 | pr_info("write verify %s\n", check ? "enabled" : "disabled"); |
| 230 | 231 | ||
| 231 | mtd = get_mtd_device(NULL, dev); | 232 | mtd = get_mtd_device(NULL, dev); |
| 232 | if (IS_ERR(mtd)) { | 233 | if (IS_ERR(mtd)) { |
| 233 | err = PTR_ERR(mtd); | 234 | err = PTR_ERR(mtd); |
| 234 | printk(PRINT_PREF "error: cannot get MTD device\n"); | 235 | pr_err("error: cannot get MTD device\n"); |
| 235 | return err; | 236 | return err; |
| 236 | } | 237 | } |
| 237 | 238 | ||
| 238 | if (mtd->writesize == 1) { | 239 | if (mtd->writesize == 1) { |
| 239 | printk(PRINT_PREF "not NAND flash, assume page size is 512 " | 240 | pr_info("not NAND flash, assume page size is 512 " |
| 240 | "bytes.\n"); | 241 | "bytes.\n"); |
| 241 | pgsize = 512; | 242 | pgsize = 512; |
| 242 | } else | 243 | } else |
| 243 | pgsize = mtd->writesize; | 244 | pgsize = mtd->writesize; |
| 244 | 245 | ||
| 245 | if (pgcnt && (pgcnt > mtd->erasesize / pgsize || pgcnt < 0)) { | 246 | if (pgcnt && (pgcnt > mtd->erasesize / pgsize || pgcnt < 0)) { |
| 246 | printk(PRINT_PREF "error: invalid pgcnt value %d\n", pgcnt); | 247 | pr_err("error: invalid pgcnt value %d\n", pgcnt); |
| 247 | goto out_mtd; | 248 | goto out_mtd; |
| 248 | } | 249 | } |
| 249 | 250 | ||
| 250 | err = -ENOMEM; | 251 | err = -ENOMEM; |
| 251 | patt_5A5 = kmalloc(mtd->erasesize, GFP_KERNEL); | 252 | patt_5A5 = kmalloc(mtd->erasesize, GFP_KERNEL); |
| 252 | if (!patt_5A5) { | 253 | if (!patt_5A5) { |
| 253 | printk(PRINT_PREF "error: cannot allocate memory\n"); | 254 | pr_err("error: cannot allocate memory\n"); |
| 254 | goto out_mtd; | 255 | goto out_mtd; |
| 255 | } | 256 | } |
| 256 | 257 | ||
| 257 | patt_A5A = kmalloc(mtd->erasesize, GFP_KERNEL); | 258 | patt_A5A = kmalloc(mtd->erasesize, GFP_KERNEL); |
| 258 | if (!patt_A5A) { | 259 | if (!patt_A5A) { |
| 259 | printk(PRINT_PREF "error: cannot allocate memory\n"); | 260 | pr_err("error: cannot allocate memory\n"); |
| 260 | goto out_patt_5A5; | 261 | goto out_patt_5A5; |
| 261 | } | 262 | } |
| 262 | 263 | ||
| 263 | patt_FF = kmalloc(mtd->erasesize, GFP_KERNEL); | 264 | patt_FF = kmalloc(mtd->erasesize, GFP_KERNEL); |
| 264 | if (!patt_FF) { | 265 | if (!patt_FF) { |
| 265 | printk(PRINT_PREF "error: cannot allocate memory\n"); | 266 | pr_err("error: cannot allocate memory\n"); |
| 266 | goto out_patt_A5A; | 267 | goto out_patt_A5A; |
| 267 | } | 268 | } |
| 268 | 269 | ||
| 269 | check_buf = kmalloc(mtd->erasesize, GFP_KERNEL); | 270 | check_buf = kmalloc(mtd->erasesize, GFP_KERNEL); |
| 270 | if (!check_buf) { | 271 | if (!check_buf) { |
| 271 | printk(PRINT_PREF "error: cannot allocate memory\n"); | 272 | pr_err("error: cannot allocate memory\n"); |
| 272 | goto out_patt_FF; | 273 | goto out_patt_FF; |
| 273 | } | 274 | } |
| 274 | 275 | ||
| @@ -295,13 +296,13 @@ static int __init tort_init(void) | |||
| 295 | err = mtd_block_isbad(mtd, (loff_t)i * mtd->erasesize); | 296 | err = mtd_block_isbad(mtd, (loff_t)i * mtd->erasesize); |
| 296 | 297 | ||
| 297 | if (err < 0) { | 298 | if (err < 0) { |
| 298 | printk(PRINT_PREF "block_isbad() returned %d " | 299 | pr_info("block_isbad() returned %d " |
| 299 | "for EB %d\n", err, i); | 300 | "for EB %d\n", err, i); |
| 300 | goto out; | 301 | goto out; |
| 301 | } | 302 | } |
| 302 | 303 | ||
| 303 | if (err) { | 304 | if (err) { |
| 304 | printk("EB %d is bad. Skip it.\n", i); | 305 | pr_err("EB %d is bad. Skip it.\n", i); |
| 305 | bad_ebs[i - eb] = 1; | 306 | bad_ebs[i - eb] = 1; |
| 306 | } | 307 | } |
| 307 | } | 308 | } |
| @@ -329,7 +330,7 @@ static int __init tort_init(void) | |||
| 329 | continue; | 330 | continue; |
| 330 | err = check_eraseblock(i, patt_FF); | 331 | err = check_eraseblock(i, patt_FF); |
| 331 | if (err) { | 332 | if (err) { |
| 332 | printk(PRINT_PREF "verify failed" | 333 | pr_info("verify failed" |
| 333 | " for 0xFF... pattern\n"); | 334 | " for 0xFF... pattern\n"); |
| 334 | goto out; | 335 | goto out; |
| 335 | } | 336 | } |
| @@ -362,7 +363,7 @@ static int __init tort_init(void) | |||
| 362 | patt = patt_A5A; | 363 | patt = patt_A5A; |
| 363 | err = check_eraseblock(i, patt); | 364 | err = check_eraseblock(i, patt); |
| 364 | if (err) { | 365 | if (err) { |
| 365 | printk(PRINT_PREF "verify failed for %s" | 366 | pr_info("verify failed for %s" |
| 366 | " pattern\n", | 367 | " pattern\n", |
| 367 | ((eb + erase_cycles) & 1) ? | 368 | ((eb + erase_cycles) & 1) ? |
| 368 | "0x55AA55..." : "0xAA55AA..."); | 369 | "0x55AA55..." : "0xAA55AA..."); |
| @@ -380,7 +381,7 @@ static int __init tort_init(void) | |||
| 380 | stop_timing(); | 381 | stop_timing(); |
| 381 | ms = (finish.tv_sec - start.tv_sec) * 1000 + | 382 | ms = (finish.tv_sec - start.tv_sec) * 1000 + |
| 382 | (finish.tv_usec - start.tv_usec) / 1000; | 383 | (finish.tv_usec - start.tv_usec) / 1000; |
| 383 | printk(PRINT_PREF "%08u erase cycles done, took %lu " | 384 | pr_info("%08u erase cycles done, took %lu " |
| 384 | "milliseconds (%lu seconds)\n", | 385 | "milliseconds (%lu seconds)\n", |
| 385 | erase_cycles, ms, ms / 1000); | 386 | erase_cycles, ms, ms / 1000); |
| 386 | start_timing(); | 387 | start_timing(); |
| @@ -391,7 +392,7 @@ static int __init tort_init(void) | |||
| 391 | } | 392 | } |
| 392 | out: | 393 | out: |
| 393 | 394 | ||
| 394 | printk(PRINT_PREF "finished after %u erase cycles\n", | 395 | pr_info("finished after %u erase cycles\n", |
| 395 | erase_cycles); | 396 | erase_cycles); |
| 396 | kfree(check_buf); | 397 | kfree(check_buf); |
| 397 | out_patt_FF: | 398 | out_patt_FF: |
| @@ -403,7 +404,7 @@ out_patt_5A5: | |||
| 403 | out_mtd: | 404 | out_mtd: |
| 404 | put_mtd_device(mtd); | 405 | put_mtd_device(mtd); |
| 405 | if (err) | 406 | if (err) |
| 406 | printk(PRINT_PREF "error %d occurred during torturing\n", err); | 407 | pr_info("error %d occurred during torturing\n", err); |
| 407 | printk(KERN_INFO "=================================================\n"); | 408 | printk(KERN_INFO "=================================================\n"); |
| 408 | return err; | 409 | return err; |
| 409 | } | 410 | } |
| @@ -441,9 +442,9 @@ static void report_corrupt(unsigned char *read, unsigned char *written) | |||
| 441 | &bits) >= 0) | 442 | &bits) >= 0) |
| 442 | pages++; | 443 | pages++; |
| 443 | 444 | ||
| 444 | printk(PRINT_PREF "verify fails on %d pages, %d bytes/%d bits\n", | 445 | pr_info("verify fails on %d pages, %d bytes/%d bits\n", |
| 445 | pages, bytes, bits); | 446 | pages, bytes, bits); |
| 446 | printk(PRINT_PREF "The following is a list of all differences between" | 447 | pr_info("The following is a list of all differences between" |
| 447 | " what was read from flash and what was expected\n"); | 448 | " what was read from flash and what was expected\n"); |
| 448 | 449 | ||
| 449 | for (i = 0; i < check_len; i += pgsize) { | 450 | for (i = 0; i < check_len; i += pgsize) { |
| @@ -457,7 +458,7 @@ static void report_corrupt(unsigned char *read, unsigned char *written) | |||
| 457 | printk("-------------------------------------------------------" | 458 | printk("-------------------------------------------------------" |
| 458 | "----------------------------------\n"); | 459 | "----------------------------------\n"); |
| 459 | 460 | ||
| 460 | printk(PRINT_PREF "Page %zd has %d bytes/%d bits failing verify," | 461 | pr_info("Page %zd has %d bytes/%d bits failing verify," |
| 461 | " starting at offset 0x%x\n", | 462 | " starting at offset 0x%x\n", |
| 462 | (mtd->erasesize - check_len + i) / pgsize, | 463 | (mtd->erasesize - check_len + i) / pgsize, |
| 463 | bytes, bits, first); | 464 | bytes, bits, first); |
diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c index 0c96eb52c797..03310721712f 100644 --- a/fs/jffs2/nodemgmt.c +++ b/fs/jffs2/nodemgmt.c | |||
| @@ -417,14 +417,16 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, | |||
| 417 | spin_unlock(&c->erase_completion_lock); | 417 | spin_unlock(&c->erase_completion_lock); |
| 418 | 418 | ||
| 419 | ret = jffs2_prealloc_raw_node_refs(c, jeb, 1); | 419 | ret = jffs2_prealloc_raw_node_refs(c, jeb, 1); |
| 420 | if (ret) | 420 | |
| 421 | return ret; | ||
| 422 | /* Just lock it again and continue. Nothing much can change because | 421 | /* Just lock it again and continue. Nothing much can change because |
| 423 | we hold c->alloc_sem anyway. In fact, it's not entirely clear why | 422 | we hold c->alloc_sem anyway. In fact, it's not entirely clear why |
| 424 | we hold c->erase_completion_lock in the majority of this function... | 423 | we hold c->erase_completion_lock in the majority of this function... |
| 425 | but that's a question for another (more caffeine-rich) day. */ | 424 | but that's a question for another (more caffeine-rich) day. */ |
| 426 | spin_lock(&c->erase_completion_lock); | 425 | spin_lock(&c->erase_completion_lock); |
| 427 | 426 | ||
| 427 | if (ret) | ||
| 428 | return ret; | ||
| 429 | |||
| 428 | waste = jeb->free_size; | 430 | waste = jeb->free_size; |
| 429 | jffs2_link_node_ref(c, jeb, | 431 | jffs2_link_node_ref(c, jeb, |
| 430 | (jeb->offset + c->sector_size - waste) | REF_OBSOLETE, | 432 | (jeb->offset + c->sector_size - waste) | REF_OBSOLETE, |
diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h index 93b1e091b1e9..e0ce311011c0 100644 --- a/include/linux/bcma/bcma.h +++ b/include/linux/bcma/bcma.h | |||
| @@ -350,6 +350,7 @@ extern void bcma_core_set_clockmode(struct bcma_device *core, | |||
| 350 | enum bcma_clkmode clkmode); | 350 | enum bcma_clkmode clkmode); |
| 351 | extern void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status, | 351 | extern void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status, |
| 352 | bool on); | 352 | bool on); |
| 353 | extern u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset); | ||
| 353 | #define BCMA_DMA_TRANSLATION_MASK 0xC0000000 | 354 | #define BCMA_DMA_TRANSLATION_MASK 0xC0000000 |
| 354 | #define BCMA_DMA_TRANSLATION_NONE 0x00000000 | 355 | #define BCMA_DMA_TRANSLATION_NONE 0x00000000 |
| 355 | #define BCMA_DMA_TRANSLATION_DMA32_CMT 0x40000000 /* Client Mode Translation for 32-bit DMA */ | 356 | #define BCMA_DMA_TRANSLATION_DMA32_CMT 0x40000000 /* Client Mode Translation for 32-bit DMA */ |
diff --git a/include/linux/mtd/blktrans.h b/include/linux/mtd/blktrans.h index ed270bd2e4df..4eb0a50d0c55 100644 --- a/include/linux/mtd/blktrans.h +++ b/include/linux/mtd/blktrans.h | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
| 24 | #include <linux/kref.h> | 24 | #include <linux/kref.h> |
| 25 | #include <linux/sysfs.h> | 25 | #include <linux/sysfs.h> |
| 26 | #include <linux/workqueue.h> | ||
| 26 | 27 | ||
| 27 | struct hd_geometry; | 28 | struct hd_geometry; |
| 28 | struct mtd_info; | 29 | struct mtd_info; |
| @@ -43,7 +44,8 @@ struct mtd_blktrans_dev { | |||
| 43 | struct kref ref; | 44 | struct kref ref; |
| 44 | struct gendisk *disk; | 45 | struct gendisk *disk; |
| 45 | struct attribute_group *disk_attributes; | 46 | struct attribute_group *disk_attributes; |
| 46 | struct task_struct *thread; | 47 | struct workqueue_struct *wq; |
| 48 | struct work_struct work; | ||
| 47 | struct request_queue *rq; | 49 | struct request_queue *rq; |
| 48 | spinlock_t queue_lock; | 50 | spinlock_t queue_lock; |
| 49 | void *priv; | 51 | void *priv; |
diff --git a/include/linux/mtd/doc2000.h b/include/linux/mtd/doc2000.h index 0f6fea73a1f6..407d1e556c39 100644 --- a/include/linux/mtd/doc2000.h +++ b/include/linux/mtd/doc2000.h | |||
| @@ -92,12 +92,26 @@ | |||
| 92 | * Others use readb/writeb | 92 | * Others use readb/writeb |
| 93 | */ | 93 | */ |
| 94 | #if defined(__arm__) | 94 | #if defined(__arm__) |
| 95 | #define ReadDOC_(adr, reg) ((unsigned char)(*(volatile __u32 *)(((unsigned long)adr)+((reg)<<2)))) | 95 | static inline u8 ReadDOC_(u32 __iomem *addr, unsigned long reg) |
| 96 | #define WriteDOC_(d, adr, reg) do{ *(volatile __u32 *)(((unsigned long)adr)+((reg)<<2)) = (__u32)d; wmb();} while(0) | 96 | { |
| 97 | return __raw_readl(addr + reg); | ||
| 98 | } | ||
| 99 | static inline void WriteDOC_(u8 data, u32 __iomem *addr, unsigned long reg) | ||
| 100 | { | ||
| 101 | __raw_writel(data, addr + reg); | ||
| 102 | wmb(); | ||
| 103 | } | ||
| 97 | #define DOC_IOREMAP_LEN 0x8000 | 104 | #define DOC_IOREMAP_LEN 0x8000 |
| 98 | #elif defined(__ppc__) | 105 | #elif defined(__ppc__) |
| 99 | #define ReadDOC_(adr, reg) ((unsigned char)(*(volatile __u16 *)(((unsigned long)adr)+((reg)<<1)))) | 106 | static inline u8 ReadDOC_(u16 __iomem *addr, unsigned long reg) |
| 100 | #define WriteDOC_(d, adr, reg) do{ *(volatile __u16 *)(((unsigned long)adr)+((reg)<<1)) = (__u16)d; wmb();} while(0) | 107 | { |
| 108 | return __raw_readw(addr + reg); | ||
| 109 | } | ||
| 110 | static inline void WriteDOC_(u8 data, u16 __iomem *addr, unsigned long reg) | ||
| 111 | { | ||
| 112 | __raw_writew(data, addr + reg); | ||
| 113 | wmb(); | ||
| 114 | } | ||
| 101 | #define DOC_IOREMAP_LEN 0x4000 | 115 | #define DOC_IOREMAP_LEN 0x4000 |
| 102 | #else | 116 | #else |
| 103 | #define ReadDOC_(adr, reg) readb((void __iomem *)(adr) + (reg)) | 117 | #define ReadDOC_(adr, reg) readb((void __iomem *)(adr) + (reg)) |
diff --git a/include/linux/mtd/fsmc.h b/include/linux/mtd/fsmc.h index b20029221fb1..d6ed61ef451d 100644 --- a/include/linux/mtd/fsmc.h +++ b/include/linux/mtd/fsmc.h | |||
| @@ -155,9 +155,6 @@ struct fsmc_nand_platform_data { | |||
| 155 | unsigned int width; | 155 | unsigned int width; |
| 156 | unsigned int bank; | 156 | unsigned int bank; |
| 157 | 157 | ||
| 158 | /* CLE, ALE offsets */ | ||
| 159 | unsigned int cle_off; | ||
| 160 | unsigned int ale_off; | ||
| 161 | enum access_mode mode; | 158 | enum access_mode mode; |
| 162 | 159 | ||
| 163 | void (*select_bank)(uint32_t bank, uint32_t busw); | 160 | void (*select_bank)(uint32_t bank, uint32_t busw); |
diff --git a/include/linux/mtd/gpmi-nand.h b/include/linux/mtd/gpmi-nand.h deleted file mode 100644 index ed3c4e09f3d1..000000000000 --- a/include/linux/mtd/gpmi-nand.h +++ /dev/null | |||
| @@ -1,68 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify | ||
| 5 | * it under the terms of the GNU General Public License as published by | ||
| 6 | * the Free Software Foundation; either version 2 of the License, or | ||
| 7 | * (at your option) any later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, | ||
| 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 12 | * GNU General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License along | ||
| 15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #ifndef __MACH_MXS_GPMI_NAND_H__ | ||
| 20 | #define __MACH_MXS_GPMI_NAND_H__ | ||
| 21 | |||
| 22 | /* The size of the resources is fixed. */ | ||
| 23 | #define GPMI_NAND_RES_SIZE 6 | ||
| 24 | |||
| 25 | /* Resource names for the GPMI NAND driver. */ | ||
| 26 | #define GPMI_NAND_GPMI_REGS_ADDR_RES_NAME "gpmi-nand" | ||
| 27 | #define GPMI_NAND_GPMI_INTERRUPT_RES_NAME "GPMI NAND GPMI Interrupt" | ||
| 28 | #define GPMI_NAND_BCH_REGS_ADDR_RES_NAME "bch" | ||
| 29 | #define GPMI_NAND_BCH_INTERRUPT_RES_NAME "bch" | ||
| 30 | #define GPMI_NAND_DMA_CHANNELS_RES_NAME "GPMI NAND DMA Channels" | ||
| 31 | #define GPMI_NAND_DMA_INTERRUPT_RES_NAME "gpmi-dma" | ||
| 32 | |||
| 33 | /** | ||
| 34 | * struct gpmi_nand_platform_data - GPMI NAND driver platform data. | ||
| 35 | * | ||
| 36 | * This structure communicates platform-specific information to the GPMI NAND | ||
| 37 | * driver that can't be expressed as resources. | ||
| 38 | * | ||
| 39 | * @platform_init: A pointer to a function the driver will call to | ||
| 40 | * initialize the platform (e.g., set up the pin mux). | ||
| 41 | * @min_prop_delay_in_ns: Minimum propagation delay of GPMI signals to and | ||
| 42 | * from the NAND Flash device, in nanoseconds. | ||
| 43 | * @max_prop_delay_in_ns: Maximum propagation delay of GPMI signals to and | ||
| 44 | * from the NAND Flash device, in nanoseconds. | ||
| 45 | * @max_chip_count: The maximum number of chips for which the driver | ||
| 46 | * should configure the hardware. This value most | ||
| 47 | * likely reflects the number of pins that are | ||
| 48 | * connected to a NAND Flash device. If this is | ||
| 49 | * greater than the SoC hardware can support, the | ||
| 50 | * driver will print a message and fail to initialize. | ||
| 51 | * @partitions: An optional pointer to an array of partition | ||
| 52 | * descriptions. | ||
| 53 | * @partition_count: The number of elements in the partitions array. | ||
| 54 | */ | ||
| 55 | struct gpmi_nand_platform_data { | ||
| 56 | /* SoC hardware information. */ | ||
| 57 | int (*platform_init)(void); | ||
| 58 | |||
| 59 | /* NAND Flash information. */ | ||
| 60 | unsigned int min_prop_delay_in_ns; | ||
| 61 | unsigned int max_prop_delay_in_ns; | ||
| 62 | unsigned int max_chip_count; | ||
| 63 | |||
| 64 | /* Medium information. */ | ||
| 65 | struct mtd_partition *partitions; | ||
| 66 | unsigned partition_count; | ||
| 67 | }; | ||
| 68 | #endif | ||
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h index 3595a0236b0f..f6eb4332ac92 100644 --- a/include/linux/mtd/map.h +++ b/include/linux/mtd/map.h | |||
| @@ -328,7 +328,7 @@ static inline int map_word_bitsset(struct map_info *map, map_word val1, map_word | |||
| 328 | 328 | ||
| 329 | static inline map_word map_word_load(struct map_info *map, const void *ptr) | 329 | static inline map_word map_word_load(struct map_info *map, const void *ptr) |
| 330 | { | 330 | { |
| 331 | map_word r; | 331 | map_word r = {{0} }; |
| 332 | 332 | ||
| 333 | if (map_bankwidth_is_1(map)) | 333 | if (map_bankwidth_is_1(map)) |
| 334 | r.x[0] = *(unsigned char *)ptr; | 334 | r.x[0] = *(unsigned char *)ptr; |
| @@ -391,7 +391,7 @@ static inline map_word map_word_ff(struct map_info *map) | |||
| 391 | 391 | ||
| 392 | static inline map_word inline_map_read(struct map_info *map, unsigned long ofs) | 392 | static inline map_word inline_map_read(struct map_info *map, unsigned long ofs) |
| 393 | { | 393 | { |
| 394 | map_word r; | 394 | map_word uninitialized_var(r); |
| 395 | 395 | ||
| 396 | if (map_bankwidth_is_1(map)) | 396 | if (map_bankwidth_is_1(map)) |
| 397 | r.x[0] = __raw_readb(map->virt + ofs); | 397 | r.x[0] = __raw_readb(map->virt + ofs); |
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 81d61e704599..f9ac2897b86b 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h | |||
| @@ -98,7 +98,7 @@ struct mtd_oob_ops { | |||
| 98 | }; | 98 | }; |
| 99 | 99 | ||
| 100 | #define MTD_MAX_OOBFREE_ENTRIES_LARGE 32 | 100 | #define MTD_MAX_OOBFREE_ENTRIES_LARGE 32 |
| 101 | #define MTD_MAX_ECCPOS_ENTRIES_LARGE 448 | 101 | #define MTD_MAX_ECCPOS_ENTRIES_LARGE 640 |
| 102 | /* | 102 | /* |
| 103 | * Internal ECC layout control structure. For historical reasons, there is a | 103 | * Internal ECC layout control structure. For historical reasons, there is a |
| 104 | * similar, smaller struct nand_ecclayout_user (in mtd-abi.h) that is retained | 104 | * similar, smaller struct nand_ecclayout_user (in mtd-abi.h) that is retained |
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 24e915957e4f..7ccb3c59ed60 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h | |||
| @@ -219,6 +219,13 @@ typedef enum { | |||
| 219 | #define NAND_OWN_BUFFERS 0x00020000 | 219 | #define NAND_OWN_BUFFERS 0x00020000 |
| 220 | /* Chip may not exist, so silence any errors in scan */ | 220 | /* Chip may not exist, so silence any errors in scan */ |
| 221 | #define NAND_SCAN_SILENT_NODEV 0x00040000 | 221 | #define NAND_SCAN_SILENT_NODEV 0x00040000 |
| 222 | /* | ||
| 223 | * Autodetect nand buswidth with readid/onfi. | ||
| 224 | * This suppose the driver will configure the hardware in 8 bits mode | ||
| 225 | * when calling nand_scan_ident, and update its configuration | ||
| 226 | * before calling nand_scan_tail. | ||
| 227 | */ | ||
| 228 | #define NAND_BUSWIDTH_AUTO 0x00080000 | ||
| 222 | 229 | ||
| 223 | /* Options set by nand scan */ | 230 | /* Options set by nand scan */ |
| 224 | /* Nand scan has allocated controller struct */ | 231 | /* Nand scan has allocated controller struct */ |
| @@ -471,8 +478,8 @@ struct nand_buffers { | |||
| 471 | * non 0 if ONFI supported. | 478 | * non 0 if ONFI supported. |
| 472 | * @onfi_params: [INTERN] holds the ONFI page parameter when ONFI is | 479 | * @onfi_params: [INTERN] holds the ONFI page parameter when ONFI is |
| 473 | * supported, 0 otherwise. | 480 | * supported, 0 otherwise. |
| 474 | * @onfi_set_features [REPLACEABLE] set the features for ONFI nand | 481 | * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand |
| 475 | * @onfi_get_features [REPLACEABLE] get the features for ONFI nand | 482 | * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand |
| 476 | * @ecclayout: [REPLACEABLE] the default ECC placement scheme | 483 | * @ecclayout: [REPLACEABLE] the default ECC placement scheme |
| 477 | * @bbt: [INTERN] bad block table pointer | 484 | * @bbt: [INTERN] bad block table pointer |
| 478 | * @bbt_td: [REPLACEABLE] bad block table descriptor for flash | 485 | * @bbt_td: [REPLACEABLE] bad block table descriptor for flash |
diff --git a/include/linux/mtd/sh_flctl.h b/include/linux/mtd/sh_flctl.h index 01e4b15b280e..1c28f8879b1c 100644 --- a/include/linux/mtd/sh_flctl.h +++ b/include/linux/mtd/sh_flctl.h | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #ifndef __SH_FLCTL_H__ | 20 | #ifndef __SH_FLCTL_H__ |
| 21 | #define __SH_FLCTL_H__ | 21 | #define __SH_FLCTL_H__ |
| 22 | 22 | ||
| 23 | #include <linux/completion.h> | ||
| 23 | #include <linux/mtd/mtd.h> | 24 | #include <linux/mtd/mtd.h> |
| 24 | #include <linux/mtd/nand.h> | 25 | #include <linux/mtd/nand.h> |
| 25 | #include <linux/mtd/partitions.h> | 26 | #include <linux/mtd/partitions.h> |
| @@ -107,6 +108,7 @@ | |||
| 107 | #define ESTERINTE (0x1 << 24) /* ECC error interrupt enable */ | 108 | #define ESTERINTE (0x1 << 24) /* ECC error interrupt enable */ |
| 108 | #define AC1CLR (0x1 << 19) /* ECC FIFO clear */ | 109 | #define AC1CLR (0x1 << 19) /* ECC FIFO clear */ |
| 109 | #define AC0CLR (0x1 << 18) /* Data FIFO clear */ | 110 | #define AC0CLR (0x1 << 18) /* Data FIFO clear */ |
| 111 | #define DREQ0EN (0x1 << 16) /* FLDTFIFODMA Request Enable */ | ||
| 110 | #define ECERB (0x1 << 9) /* ECC error */ | 112 | #define ECERB (0x1 << 9) /* ECC error */ |
| 111 | #define STERB (0x1 << 8) /* Status error */ | 113 | #define STERB (0x1 << 8) /* Status error */ |
| 112 | #define STERINTE (0x1 << 4) /* Status error enable */ | 114 | #define STERINTE (0x1 << 4) /* Status error enable */ |
| @@ -138,6 +140,8 @@ enum flctl_ecc_res_t { | |||
| 138 | FL_TIMEOUT | 140 | FL_TIMEOUT |
| 139 | }; | 141 | }; |
| 140 | 142 | ||
| 143 | struct dma_chan; | ||
| 144 | |||
| 141 | struct sh_flctl { | 145 | struct sh_flctl { |
| 142 | struct mtd_info mtd; | 146 | struct mtd_info mtd; |
| 143 | struct nand_chip chip; | 147 | struct nand_chip chip; |
| @@ -147,7 +151,7 @@ struct sh_flctl { | |||
| 147 | 151 | ||
| 148 | uint8_t done_buff[2048 + 64]; /* max size 2048 + 64 */ | 152 | uint8_t done_buff[2048 + 64]; /* max size 2048 + 64 */ |
| 149 | int read_bytes; | 153 | int read_bytes; |
| 150 | int index; | 154 | unsigned int index; |
| 151 | int seqin_column; /* column in SEQIN cmd */ | 155 | int seqin_column; /* column in SEQIN cmd */ |
| 152 | int seqin_page_addr; /* page_addr in SEQIN cmd */ | 156 | int seqin_page_addr; /* page_addr in SEQIN cmd */ |
| 153 | uint32_t seqin_read_cmd; /* read cmd in SEQIN cmd */ | 157 | uint32_t seqin_read_cmd; /* read cmd in SEQIN cmd */ |
| @@ -161,6 +165,11 @@ struct sh_flctl { | |||
| 161 | unsigned hwecc:1; /* Hardware ECC (0 = disabled, 1 = enabled) */ | 165 | unsigned hwecc:1; /* Hardware ECC (0 = disabled, 1 = enabled) */ |
| 162 | unsigned holden:1; /* Hardware has FLHOLDCR and HOLDEN is set */ | 166 | unsigned holden:1; /* Hardware has FLHOLDCR and HOLDEN is set */ |
| 163 | unsigned qos_request:1; /* QoS request to prevent deep power shutdown */ | 167 | unsigned qos_request:1; /* QoS request to prevent deep power shutdown */ |
| 168 | |||
| 169 | /* DMA related objects */ | ||
| 170 | struct dma_chan *chan_fifo0_rx; | ||
| 171 | struct dma_chan *chan_fifo0_tx; | ||
| 172 | struct completion dma_complete; | ||
| 164 | }; | 173 | }; |
| 165 | 174 | ||
| 166 | struct sh_flctl_platform_data { | 175 | struct sh_flctl_platform_data { |
| @@ -170,6 +179,9 @@ struct sh_flctl_platform_data { | |||
| 170 | 179 | ||
| 171 | unsigned has_hwecc:1; | 180 | unsigned has_hwecc:1; |
| 172 | unsigned use_holden:1; | 181 | unsigned use_holden:1; |
| 182 | |||
| 183 | unsigned int slave_id_fifo0_tx; | ||
| 184 | unsigned int slave_id_fifo0_rx; | ||
| 173 | }; | 185 | }; |
| 174 | 186 | ||
| 175 | static inline struct sh_flctl *mtd_to_flctl(struct mtd_info *mtdinfo) | 187 | static inline struct sh_flctl *mtd_to_flctl(struct mtd_info *mtdinfo) |
diff --git a/include/linux/platform_data/mtd-nomadik-nand.h b/include/linux/platform_data/mtd-nomadik-nand.h deleted file mode 100644 index c3c8254c22a5..000000000000 --- a/include/linux/platform_data/mtd-nomadik-nand.h +++ /dev/null | |||
| @@ -1,16 +0,0 @@ | |||
| 1 | #ifndef __ASM_ARCH_NAND_H | ||
| 2 | #define __ASM_ARCH_NAND_H | ||
| 3 | |||
| 4 | struct nomadik_nand_platform_data { | ||
| 5 | struct mtd_partition *parts; | ||
| 6 | int nparts; | ||
| 7 | int options; | ||
| 8 | int (*init) (void); | ||
| 9 | int (*exit) (void); | ||
| 10 | }; | ||
| 11 | |||
| 12 | #define NAND_IO_DATA 0x40000000 | ||
| 13 | #define NAND_IO_CMD 0x40800000 | ||
| 14 | #define NAND_IO_ADDR 0x41000000 | ||
| 15 | |||
| 16 | #endif /* __ASM_ARCH_NAND_H */ | ||
