diff --git a/[refs] b/[refs] index 46ee7c952010..9f0988f75811 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: dcd6a97d1d821335051cbf35b1e2be54955d6276 +refs/heads/master: 80c2022e5645a1a789531d13010292c5c18bf1db diff --git a/trunk/Documentation/ABI/testing/ima_policy b/trunk/Documentation/ABI/testing/ima_policy index ec0a38ef3145..986946613542 100644 --- a/trunk/Documentation/ABI/testing/ima_policy +++ b/trunk/Documentation/ABI/testing/ima_policy @@ -23,7 +23,7 @@ Description: lsm: [[subj_user=] [subj_role=] [subj_type=] [obj_user=] [obj_role=] [obj_type=]] - base: func:= [BPRM_CHECK][FILE_MMAP][FILE_CHECK][MODULE_CHECK] + base: func:= [BPRM_CHECK][FILE_MMAP][FILE_CHECK] mask:= [MAY_READ] [MAY_WRITE] [MAY_APPEND] [MAY_EXEC] fsmagic:= hex value uid:= decimal value @@ -53,7 +53,6 @@ Description: measure func=BPRM_CHECK measure func=FILE_MMAP mask=MAY_EXEC measure func=FILE_CHECK mask=MAY_READ uid=0 - measure func=MODULE_CHECK uid=0 appraise fowner=0 The default policy measures all executables in bprm_check, diff --git a/trunk/Documentation/devicetree/bindings/arm/davinci/nand.txt b/trunk/Documentation/devicetree/bindings/arm/davinci/nand.txt index 3545ea704b50..49fc7ada929a 100644 --- a/trunk/Documentation/devicetree/bindings/arm/davinci/nand.txt +++ b/trunk/Documentation/devicetree/bindings/arm/davinci/nand.txt @@ -23,9 +23,6 @@ Recommended properties : - ti,davinci-nand-buswidth: buswidth 8 or 16 - ti,davinci-nand-use-bbt: use flash based bad block table support. -nand device bindings may contain additional sub-nodes describing -partitions of the address space. See partition.txt for more detail. - Example(da850 EVM ): nand_cs3@62000000 { compatible = "ti,davinci-nand"; @@ -38,9 +35,4 @@ nand_cs3@62000000 { ti,davinci-ecc-mode = "hw"; ti,davinci-ecc-bits = <4>; ti,davinci-nand-use-bbt; - - partition@180000 { - label = "ubifs"; - reg = <0x180000 0x7e80000>; - }; }; diff --git a/trunk/Documentation/devicetree/bindings/mtd/denali-nand.txt b/trunk/Documentation/devicetree/bindings/mtd/denali-nand.txt deleted file mode 100644 index b04d03a1d499..000000000000 --- a/trunk/Documentation/devicetree/bindings/mtd/denali-nand.txt +++ /dev/null @@ -1,23 +0,0 @@ -* Denali NAND controller - -Required properties: - - compatible : should be "denali,denali-nand-dt" - - reg : should contain registers location and length for data and reg. - - reg-names: Should contain the reg names "nand_data" and "denali_reg" - - interrupts : The interrupt number. - - dm-mask : DMA bit mask - -The device tree may optionally contain sub-nodes describing partitions of the -address space. See partition.txt for more detail. - -Examples: - -nand: nand@ff900000 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "denali,denali-nand-dt"; - reg = <0xff900000 0x100000>, <0xffb80000 0x10000>; - reg-names = "nand_data", "denali_reg"; - interrupts = <0 144 4>; - dma-mask = <0xffffffff>; -}; diff --git a/trunk/Documentation/devicetree/bindings/mtd/flctl-nand.txt b/trunk/Documentation/devicetree/bindings/mtd/flctl-nand.txt deleted file mode 100644 index 427f46dc60ad..000000000000 --- a/trunk/Documentation/devicetree/bindings/mtd/flctl-nand.txt +++ /dev/null @@ -1,49 +0,0 @@ -FLCTL NAND controller - -Required properties: -- compatible : "renesas,shmobile-flctl-sh7372" -- reg : Address range of the FLCTL -- interrupts : flste IRQ number -- nand-bus-width : bus width to NAND chip - -Optional properties: -- dmas: DMA specifier(s) -- dma-names: name for each DMA specifier. Valid names are - "data_tx", "data_rx", "ecc_tx", "ecc_rx" - -The DMA fields are not used yet in the driver but are listed here for -completing the bindings. - -The device tree may optionally contain sub-nodes describing partitions of the -address space. See partition.txt for more detail. - -Example: - - flctl@e6a30000 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "renesas,shmobile-flctl-sh7372"; - reg = <0xe6a30000 0x100>; - interrupts = <0x0d80>; - - nand-bus-width = <16>; - - dmas = <&dmac 1 /* data_tx */ - &dmac 2;> /* data_rx */ - dma-names = "data_tx", "data_rx"; - - system@0 { - label = "system"; - reg = <0x0 0x8000000>; - }; - - userdata@8000000 { - label = "userdata"; - reg = <0x8000000 0x10000000>; - }; - - cache@18000000 { - label = "cache"; - reg = <0x18000000 0x8000000>; - }; - }; diff --git a/trunk/Documentation/devicetree/bindings/mtd/fsmc-nand.txt b/trunk/Documentation/devicetree/bindings/mtd/fsmc-nand.txt index e3ea32e7de3e..e2c663b354d2 100644 --- a/trunk/Documentation/devicetree/bindings/mtd/fsmc-nand.txt +++ b/trunk/Documentation/devicetree/bindings/mtd/fsmc-nand.txt @@ -3,7 +3,9 @@ Required properties: - compatible : "st,spear600-fsmc-nand" - reg : Address range of the mtd chip -- reg-names: Should contain the reg names "fsmc_regs", "nand_data", "nand_addr" and "nand_cmd" +- reg-names: Should contain the reg names "fsmc_regs" and "nand_data" +- st,ale-off : Chip specific offset to ALE +- st,cle-off : Chip specific offset to CLE Optional properties: - bank-width : Width (in bytes) of the device. If not present, the width @@ -17,10 +19,10 @@ Example: #address-cells = <1>; #size-cells = <1>; reg = <0xd1800000 0x1000 /* FSMC Register */ - 0xd2000000 0x0010 /* NAND Base DATA */ - 0xd2020000 0x0010 /* NAND Base ADDR */ - 0xd2010000 0x0010>; /* NAND Base CMD */ - reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd"; + 0xd2000000 0x4000>; /* NAND Base */ + reg-names = "fsmc_regs", "nand_data"; + st,ale-off = <0x20000>; + st,cle-off = <0x10000>; bank-width = <1>; nand-skip-bbtscan; diff --git a/trunk/Documentation/devicetree/bindings/mtd/m25p80.txt b/trunk/Documentation/devicetree/bindings/mtd/m25p80.txt deleted file mode 100644 index 6d3d57609470..000000000000 --- a/trunk/Documentation/devicetree/bindings/mtd/m25p80.txt +++ /dev/null @@ -1,29 +0,0 @@ -* MTD SPI driver for ST M25Pxx (and similar) serial flash chips - -Required properties: -- #address-cells, #size-cells : Must be present if the device has sub-nodes - representing partitions. -- compatible : Should be the manufacturer and the name of the chip. Bear in mind - the DT binding is not Linux-only, but in case of Linux, see the - "m25p_ids" table in drivers/mtd/devices/m25p80.c for the list of - supported chips. -- reg : Chip-Select number -- spi-max-frequency : Maximum frequency of the SPI bus the chip can operate at - -Optional properties: -- m25p,fast-read : Use the "fast read" opcode to read data from the chip instead - of the usual "read" opcode. This opcode is not supported by - all chips and support for it can not be detected at runtime. - Refer to your chips' datasheet to check if this is supported - by your chip. - -Example: - - flash: m25p80@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "spansion,m25p80"; - reg = <0>; - spi-max-frequency = <40000000>; - m25p,fast-read; - }; diff --git a/trunk/Documentation/devicetree/bindings/mtd/mtd-physmap.txt b/trunk/Documentation/devicetree/bindings/mtd/mtd-physmap.txt index dab7847fc800..94de19b8f16b 100644 --- a/trunk/Documentation/devicetree/bindings/mtd/mtd-physmap.txt +++ b/trunk/Documentation/devicetree/bindings/mtd/mtd-physmap.txt @@ -23,9 +23,6 @@ file systems on embedded devices. unaligned accesses as implemented in the JFFS2 code via memcpy(). By defining "no-unaligned-direct-access", the flash will not be exposed directly to the MTD users (e.g. JFFS2) any more. - - linux,mtd-name: allow to specify the mtd name for retro capability with - physmap-flash drivers as boot loader pass the mtd partition via the old - device name physmap-flash. For JEDEC compatible devices, the following additional properties are defined: diff --git a/trunk/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt b/trunk/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt deleted file mode 100644 index 131e8c11d26f..000000000000 --- a/trunk/Documentation/devicetree/bindings/pwm/pwm-tiecap.txt +++ /dev/null @@ -1,23 +0,0 @@ -TI SOC ECAP based APWM controller - -Required properties: -- compatible: Must be "ti,am33xx-ecap" -- #pwm-cells: Should be 3. Number of cells being used to specify PWM property. - First cell specifies the per-chip index of the PWM to use, the second - cell is the period in nanoseconds and bit 0 in the third cell is used to - encode the polarity of PWM output. Set bit 0 of the third in PWM specifier - to 1 for inverse polarity & set to 0 for normal polarity. -- reg: physical base address and size of the registers map. - -Optional properties: -- ti,hwmods: Name of the hwmod associated to the ECAP: - "ecap", being the 0-based instance number from the HW spec - -Example: - -ecap0: ecap@0 { - compatible = "ti,am33xx-ecap"; - #pwm-cells = <3>; - reg = <0x48300100 0x80>; - ti,hwmods = "ecap0"; -}; diff --git a/trunk/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt b/trunk/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt deleted file mode 100644 index 4fc7079d822e..000000000000 --- a/trunk/Documentation/devicetree/bindings/pwm/pwm-tiehrpwm.txt +++ /dev/null @@ -1,23 +0,0 @@ -TI SOC EHRPWM based PWM controller - -Required properties: -- compatible : Must be "ti,am33xx-ehrpwm" -- #pwm-cells: Should be 3. Number of cells being used to specify PWM property. - First cell specifies the per-chip index of the PWM to use, the second - cell is the period in nanoseconds and bit 0 in the third cell is used to - encode the polarity of PWM output. Set bit 0 of the third in PWM specifier - to 1 for inverse polarity & set to 0 for normal polarity. -- reg: physical base address and size of the registers map. - -Optional properties: -- ti,hwmods: Name of the hwmod associated to the EHRPWM: - "ehrpwm", being the 0-based instance number from the HW spec - -Example: - -ehrpwm0: ehrpwm@0 { - compatible = "ti,am33xx-ehrpwm"; - #pwm-cells = <3>; - reg = <0x48300200 0x100>; - ti,hwmods = "ehrpwm0"; -}; diff --git a/trunk/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt b/trunk/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt deleted file mode 100644 index f7eae77f8354..000000000000 --- a/trunk/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt +++ /dev/null @@ -1,31 +0,0 @@ -TI SOC based PWM Subsystem - -Required properties: -- compatible: Must be "ti,am33xx-pwmss"; -- reg: physical base address and size of the registers map. -- address-cells: Specify the number of u32 entries needed in child nodes. - Should set to 1. -- size-cells: specify number of u32 entries needed to specify child nodes size - in reg property. Should set to 1. -- ranges: describes the address mapping of a memory-mapped bus. Should set to - physical address map of child's base address, physical address within - parent's address space and length of the address map. For am33xx, - 3 set of child register maps present, ECAP register space, EQEP - register space, EHRPWM register space. - -Also child nodes should also populated under PWMSS DT node. - -Example: -pwmss0: pwmss@48300000 { - compatible = "ti,am33xx-pwmss"; - reg = <0x48300000 0x10>; - ti,hwmods = "epwmss0"; - #address-cells = <1>; - #size-cells = <1>; - status = "disabled"; - ranges = <0x48300100 0x48300100 0x80 /* ECAP */ - 0x48300180 0x48300180 0x80 /* EQEP */ - 0x48300200 0x48300200 0x80>; /* EHRPWM */ - - /* child nodes go here */ -}; diff --git a/trunk/Documentation/devicetree/bindings/pwm/pwm.txt b/trunk/Documentation/devicetree/bindings/pwm/pwm.txt index 06e67247859a..73ec962bfe8c 100644 --- a/trunk/Documentation/devicetree/bindings/pwm/pwm.txt +++ b/trunk/Documentation/devicetree/bindings/pwm/pwm.txt @@ -37,21 +37,10 @@ device: pwm-names = "backlight"; }; -Note that in the example above, specifying the "pwm-names" is redundant -because the name "backlight" would be used as fallback anyway. - pwm-specifier typically encodes the chip-relative PWM number and the PWM -period in nanoseconds. - -Optionally, the pwm-specifier can encode a number of flags in a third cell: -- bit 0: PWM signal polarity (0: normal polarity, 1: inverse polarity) - -Example with optional PWM specifier for inverse polarity - - bl: backlight { - pwms = <&pwm 0 5000000 1>; - pwm-names = "backlight"; - }; +period in nanoseconds. Note that in the example above, specifying the +"pwm-names" is redundant because the name "backlight" would be used as +fallback anyway. 2) PWM controller nodes ----------------------- diff --git a/trunk/Documentation/devicetree/bindings/pwm/spear-pwm.txt b/trunk/Documentation/devicetree/bindings/pwm/spear-pwm.txt deleted file mode 100644 index 3ac779d83386..000000000000 --- a/trunk/Documentation/devicetree/bindings/pwm/spear-pwm.txt +++ /dev/null @@ -1,18 +0,0 @@ -== ST SPEAr SoC PWM controller == - -Required properties: -- compatible: should be one of: - - "st,spear320-pwm" - - "st,spear1340-pwm" -- reg: physical base address and length of the controller's registers -- #pwm-cells: number of cells used to specify PWM which is fixed to 2 on - SPEAr. The first cell specifies the per-chip index of the PWM to use and - the second cell is the period in nanoseconds. - -Example: - - pwm: pwm@a8000000 { - compatible ="st,spear320-pwm"; - reg = <0xa8000000 0x1000>; - #pwm-cells = <2>; - }; diff --git a/trunk/Documentation/devicetree/bindings/pwm/ti,twl-pwm.txt b/trunk/Documentation/devicetree/bindings/pwm/ti,twl-pwm.txt deleted file mode 100644 index 2943ee5fce00..000000000000 --- a/trunk/Documentation/devicetree/bindings/pwm/ti,twl-pwm.txt +++ /dev/null @@ -1,17 +0,0 @@ -Texas Instruments TWL series PWM drivers - -Supported PWMs: -On TWL4030 series: PWM1 and PWM2 -On TWL6030 series: PWM0 and PWM1 - -Required properties: -- compatible: "ti,twl4030-pwm" or "ti,twl6030-pwm" -- #pwm-cells: should be 2. The first cell specifies the per-chip index - of the PWM to use and the second cell is the period in nanoseconds. - -Example: - -twl_pwm: pwm { - compatible = "ti,twl6030-pwm"; - #pwm-cells = <2>; -}; diff --git a/trunk/Documentation/devicetree/bindings/pwm/ti,twl-pwmled.txt b/trunk/Documentation/devicetree/bindings/pwm/ti,twl-pwmled.txt deleted file mode 100644 index cb64f3acc10f..000000000000 --- a/trunk/Documentation/devicetree/bindings/pwm/ti,twl-pwmled.txt +++ /dev/null @@ -1,17 +0,0 @@ -Texas Instruments TWL series PWM drivers connected to LED terminals - -Supported PWMs: -On TWL4030 series: PWMA and PWMB (connected to LEDA and LEDB terminals) -On TWL6030 series: LED PWM (mainly used as charging indicator LED) - -Required properties: -- compatible: "ti,twl4030-pwmled" or "ti,twl6030-pwmled" -- #pwm-cells: should be 2. The first cell specifies the per-chip index - of the PWM to use and the second cell is the period in nanoseconds. - -Example: - -twl_pwmled: pwmled { - compatible = "ti,twl6030-pwmled"; - #pwm-cells = <2>; -}; diff --git a/trunk/Documentation/devicetree/bindings/pwm/vt8500-pwm.txt b/trunk/Documentation/devicetree/bindings/pwm/vt8500-pwm.txt deleted file mode 100644 index bcc63678a9a5..000000000000 --- a/trunk/Documentation/devicetree/bindings/pwm/vt8500-pwm.txt +++ /dev/null @@ -1,17 +0,0 @@ -VIA/Wondermedia VT8500/WM8xxx series SoC PWM controller - -Required properties: -- compatible: should be "via,vt8500-pwm" -- reg: physical base address and length of the controller's registers -- #pwm-cells: should be 2. The first cell specifies the per-chip index - of the PWM to use and the second cell is the period in nanoseconds. -- clocks: phandle to the PWM source clock - -Example: - -pwm1: pwm@d8220000 { - #pwm-cells = <2>; - compatible = "via,vt8500-pwm"; - reg = <0xd8220000 0x1000>; - clocks = <&clkpwm>; -}; diff --git a/trunk/Documentation/x86/boot.txt b/trunk/Documentation/x86/boot.txt index 406d82d5d2bb..f15cb74c4f78 100644 --- a/trunk/Documentation/x86/boot.txt +++ b/trunk/Documentation/x86/boot.txt @@ -373,7 +373,7 @@ Protocol: 2.00+ 1 Loadlin 2 bootsect-loader (0x20, all other values reserved) 3 Syslinux - 4 Etherboot/gPXE/iPXE + 4 Etherboot/gPXE 5 ELILO 7 GRUB 8 U-Boot @@ -381,7 +381,6 @@ Protocol: 2.00+ A Gujin B Qemu C Arcturus Networks uCbootloader - D kexec-tools E Extended (see ext_loader_type) F Special (0xFF = undefined) 10 Reserved diff --git a/trunk/Documentation/xtensa/atomctl.txt b/trunk/Documentation/xtensa/atomctl.txt deleted file mode 100644 index 10a8d1ff35ec..000000000000 --- a/trunk/Documentation/xtensa/atomctl.txt +++ /dev/null @@ -1,44 +0,0 @@ -We Have Atomic Operation Control (ATOMCTL) Register. -This register determines the effect of using a S32C1I instruction -with various combinations of: - - 1. With and without an Coherent Cache Controller which - can do Atomic Transactions to the memory internally. - - 2. With and without An Intelligent Memory Controller which - can do Atomic Transactions itself. - -The Core comes up with a default value of for the three types of cache ops: - - 0x28: (WB: Internal, WT: Internal, BY:Exception) - -On the FPGA Cards we typically simulate an Intelligent Memory controller -which can implement RCW transactions. For FPGA cards with an External -Memory controller we let it to the atomic operations internally while -doing a Cached (WB) transaction and use the Memory RCW for un-cached -operations. - -For systems without an coherent cache controller, non-MX, we always -use the memory controllers RCW, thought non-MX controlers likely -support the Internal Operation. - -CUSTOMER-WARNING: - Virtually all customers buy their memory controllers from vendors that - don't support atomic RCW memory transactions and will likely want to - configure this register to not use RCW. - -Developers might find using RCW in Bypass mode convenient when testing -with the cache being bypassed; for example studying cache alias problems. - -See Section 4.3.12.4 of ISA; Bits: - - WB WT BY - 5 4 | 3 2 | 1 0 - 2 Bit - Field - Values WB - Write Back WT - Write Thru BY - Bypass ---------- --------------- ----------------- ---------------- - 0 Exception Exception Exception - 1 RCW Transaction RCW Transaction RCW Transaction - 2 Internal Operation Exception Reserved - 3 Reserved Reserved Reserved diff --git a/trunk/Makefile b/trunk/Makefile index 6f07f4a28b47..540f7b240c77 100644 --- a/trunk/Makefile +++ b/trunk/Makefile @@ -981,12 +981,6 @@ _modinst_post: _modinst_ $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.fwinst obj=firmware __fw_modinst $(call cmd,depmod) -ifeq ($(CONFIG_MODULE_SIG), y) -PHONY += modules_sign -modules_sign: - $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modsign -endif - else # CONFIG_MODULES # Modules not configured diff --git a/trunk/arch/Kconfig b/trunk/arch/Kconfig index 8e9e3246b2b4..54ffd0f9df21 100644 --- a/trunk/arch/Kconfig +++ b/trunk/arch/Kconfig @@ -113,25 +113,6 @@ config HAVE_EFFICIENT_UNALIGNED_ACCESS See Documentation/unaligned-memory-access.txt for more information on the topic of unaligned memory accesses. -config ARCH_USE_BUILTIN_BSWAP - bool - help - Modern versions of GCC (since 4.4) have builtin functions - for handling byte-swapping. Using these, instead of the old - inline assembler that the architecture code provides in the - __arch_bswapXX() macros, allows the compiler to see what's - happening and offers more opportunity for optimisation. In - particular, the compiler will be able to combine the byteswap - with a nearby load or store and use load-and-swap or - store-and-swap instructions if the architecture has them. It - should almost *never* result in code which is worse than the - hand-coded assembler in . But just in case it - does, the use of the builtins is optional. - - Any architecture with load-and-swap or store-and-swap - instructions should set this. And it shouldn't hurt to set it - on architectures that don't have such instructions. - config HAVE_SYSCALL_WRAPPERS bool diff --git a/trunk/arch/arm/boot/dts/spear13xx.dtsi b/trunk/arch/arm/boot/dts/spear13xx.dtsi index b4ca60f4eb42..009096d1d2c3 100644 --- a/trunk/arch/arm/boot/dts/spear13xx.dtsi +++ b/trunk/arch/arm/boot/dts/spear13xx.dtsi @@ -73,7 +73,7 @@ 400000 500000 600000 >; - status = "disabled"; + status = "disable"; }; ahb { @@ -118,15 +118,15 @@ compatible = "st,spear600-fsmc-nand"; #address-cells = <1>; #size-cells = <1>; - reg = <0xb0000000 0x1000 /* FSMC Register*/ - 0xb0800000 0x0010 /* NAND Base DATA */ - 0xb0820000 0x0010 /* NAND Base ADDR */ - 0xb0810000 0x0010>; /* NAND Base CMD */ - reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd"; + reg = <0xb0000000 0x1000 /* FSMC Register */ + 0xb0800000 0x0010>; /* NAND Base */ + reg-names = "fsmc_regs", "nand_data"; interrupts = <0 20 0x4 0 21 0x4 0 22 0x4 0 23 0x4>; + st,ale-off = <0x20000>; + st,cle-off = <0x10000>; st,mode = <2>; status = "disabled"; }; @@ -144,7 +144,7 @@ compatible = "st,pcm-audio"; #address-cells = <0>; #size-cells = <0>; - status = "disabled"; + status = "disable"; }; smi: flash@ea000000 { diff --git a/trunk/arch/arm/boot/dts/spear300.dtsi b/trunk/arch/arm/boot/dts/spear300.dtsi index f79b3dfaabe6..090adc656015 100644 --- a/trunk/arch/arm/boot/dts/spear300.dtsi +++ b/trunk/arch/arm/boot/dts/spear300.dtsi @@ -38,10 +38,10 @@ #address-cells = <1>; #size-cells = <1>; reg = <0x94000000 0x1000 /* FSMC Register */ - 0x80000000 0x0010 /* NAND Base DATA */ - 0x80020000 0x0010 /* NAND Base ADDR */ - 0x80010000 0x0010>; /* NAND Base CMD */ - reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd"; + 0x80000000 0x0010>; /* NAND Base */ + reg-names = "fsmc_regs", "nand_data"; + st,ale-off = <0x20000>; + st,cle-off = <0x10000>; status = "disabled"; }; diff --git a/trunk/arch/arm/boot/dts/spear310.dtsi b/trunk/arch/arm/boot/dts/spear310.dtsi index ab45b8c81982..e814e5e97083 100644 --- a/trunk/arch/arm/boot/dts/spear310.dtsi +++ b/trunk/arch/arm/boot/dts/spear310.dtsi @@ -33,10 +33,10 @@ #address-cells = <1>; #size-cells = <1>; reg = <0x44000000 0x1000 /* FSMC Register */ - 0x40000000 0x0010 /* NAND Base DATA */ - 0x40020000 0x0010 /* NAND Base ADDR */ - 0x40010000 0x0010>; /* NAND Base CMD */ - reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd"; + 0x40000000 0x0010>; /* NAND Base */ + reg-names = "fsmc_regs", "nand_data"; + st,ale-off = <0x10000>; + st,cle-off = <0x20000>; status = "disabled"; }; diff --git a/trunk/arch/arm/boot/dts/spear320.dtsi b/trunk/arch/arm/boot/dts/spear320.dtsi index caa5520b1fd4..c056a84deabf 100644 --- a/trunk/arch/arm/boot/dts/spear320.dtsi +++ b/trunk/arch/arm/boot/dts/spear320.dtsi @@ -40,10 +40,10 @@ #address-cells = <1>; #size-cells = <1>; reg = <0x4c000000 0x1000 /* FSMC Register */ - 0x50000000 0x0010 /* NAND Base DATA */ - 0x50020000 0x0010 /* NAND Base ADDR */ - 0x50010000 0x0010>; /* NAND Base CMD */ - reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd"; + 0x50000000 0x0010>; /* NAND Base */ + reg-names = "fsmc_regs", "nand_data"; + st,ale-off = <0x20000>; + st,cle-off = <0x10000>; status = "disabled"; }; diff --git a/trunk/arch/arm/boot/dts/spear600.dtsi b/trunk/arch/arm/boot/dts/spear600.dtsi index 19f99dc4115e..e051dde5181f 100644 --- a/trunk/arch/arm/boot/dts/spear600.dtsi +++ b/trunk/arch/arm/boot/dts/spear600.dtsi @@ -76,10 +76,10 @@ #address-cells = <1>; #size-cells = <1>; reg = <0xd1800000 0x1000 /* FSMC Register */ - 0xd2000000 0x0010 /* NAND Base DATA */ - 0xd2020000 0x0010 /* NAND Base ADDR */ - 0xd2010000 0x0010>; /* NAND Base CMD */ - reg-names = "fsmc_regs", "nand_data", "nand_addr", "nand_cmd"; + 0xd2000000 0x4000>; /* NAND Base */ + reg-names = "fsmc_regs", "nand_data"; + st,ale-off = <0x20000>; + st,cle-off = <0x10000>; status = "disabled"; }; diff --git a/trunk/arch/arm/configs/nhk8815_defconfig b/trunk/arch/arm/configs/nhk8815_defconfig index 86cfd2959c47..240b25eea565 100644 --- a/trunk/arch/arm/configs/nhk8815_defconfig +++ b/trunk/arch/arm/configs/nhk8815_defconfig @@ -57,7 +57,7 @@ CONFIG_MTD_CHAR=y CONFIG_MTD_BLOCK=y CONFIG_MTD_NAND=y CONFIG_MTD_NAND_ECC_SMC=y -CONFIG_MTD_NAND_FSMC=y +CONFIG_MTD_NAND_NOMADIK=y CONFIG_MTD_ONENAND=y CONFIG_MTD_ONENAND_VERIFY_WRITE=y CONFIG_MTD_ONENAND_GENERIC=y diff --git a/trunk/arch/arm/include/uapi/asm/unistd.h b/trunk/arch/arm/include/uapi/asm/unistd.h index 4da7cde70b5d..ac03bdb4ae44 100644 --- a/trunk/arch/arm/include/uapi/asm/unistd.h +++ b/trunk/arch/arm/include/uapi/asm/unistd.h @@ -405,7 +405,6 @@ #define __NR_process_vm_readv (__NR_SYSCALL_BASE+376) #define __NR_process_vm_writev (__NR_SYSCALL_BASE+377) /* 378 for kcmp */ -#define __NR_finit_module (__NR_SYSCALL_BASE+379) /* * This may need to be greater than __NR_last_syscall+1 in order to diff --git a/trunk/arch/arm/kernel/calls.S b/trunk/arch/arm/kernel/calls.S index a4fda4e7a372..5935b6a02e6e 100644 --- a/trunk/arch/arm/kernel/calls.S +++ b/trunk/arch/arm/kernel/calls.S @@ -388,7 +388,6 @@ CALL(sys_process_vm_readv) CALL(sys_process_vm_writev) CALL(sys_ni_syscall) /* reserved for sys_kcmp */ - CALL(sys_finit_module) #ifndef syscalls_counted .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls #define syscalls_counted diff --git a/trunk/arch/arm/mach-nomadik/board-nhk8815.c b/trunk/arch/arm/mach-nomadik/board-nhk8815.c index 98167a4319f7..5ccdf53c5a9d 100644 --- a/trunk/arch/arm/mach-nomadik/board-nhk8815.c +++ b/trunk/arch/arm/mach-nomadik/board-nhk8815.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -34,6 +33,7 @@ #include #include #include +#include #include #include "cpu-8815.h" @@ -42,34 +42,39 @@ #define SRC_CR_INIT_MASK 0x00007fff #define SRC_CR_INIT_VAL 0x2aaa8000 -#define ALE_OFF 0x1000000 -#define CLE_OFF 0x800000 - /* These addresses span 16MB, so use three individual pages */ static struct resource nhk8815_nand_resources[] = { { - .name = "nand_data", - .start = 0x40000000, - .end = 0x40000000 + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, { .name = "nand_addr", - .start = 0x40000000 + ALE_OFF, - .end = 0x40000000 +ALE_OFF + SZ_16K - 1, + .start = NAND_IO_ADDR, + .end = NAND_IO_ADDR + 0xfff, .flags = IORESOURCE_MEM, }, { .name = "nand_cmd", - .start = 0x40000000 + CLE_OFF, - .end = 0x40000000 + CLE_OFF + SZ_16K - 1, + .start = NAND_IO_CMD, + .end = NAND_IO_CMD + 0xfff, .flags = IORESOURCE_MEM, }, { - .name = "fsmc_regs", - .start = NOMADIK_FSMC_BASE, - .end = NOMADIK_FSMC_BASE + SZ_4K - 1, + .name = "nand_data", + .start = NAND_IO_DATA, + .end = NAND_IO_DATA + 0xfff, .flags = IORESOURCE_MEM, - }, + } }; +static int nhk8815_nand_init(void) +{ + /* FSMC setup for nand chip select (8-bit nand in 8815NHK) */ + writel(0x0000000E, FSMC_PCR(0)); + writel(0x000D0A00, FSMC_PMEM(0)); + writel(0x00100A00, FSMC_PATT(0)); + + /* enable access to the chip select area */ + writel(readl(FSMC_PCR(0)) | 0x04, FSMC_PCR(0)); + + return 0; +} + /* * These partitions are the same as those used in the 2.6.20 release * shipped by the vendor; the first two partitions are mandated @@ -103,28 +108,20 @@ static struct mtd_partition nhk8815_partitions[] = { } }; -static struct fsmc_nand_timings nhk8815_nand_timings = { - .thiz = 0, - .thold = 0x10, - .twait = 0x0A, - .tset = 0, -}; - -static struct fsmc_nand_platform_data nhk8815_nand_platform_data = { - .nand_timings = &nhk8815_nand_timings, - .partitions = nhk8815_partitions, - .nr_partitions = ARRAY_SIZE(nhk8815_partitions), - .width = FSMC_NAND_BW8, +static struct nomadik_nand_platform_data nhk8815_nand_data = { + .parts = nhk8815_partitions, + .nparts = ARRAY_SIZE(nhk8815_partitions), + .options = NAND_COPYBACK | NAND_CACHEPRG | NAND_NO_PADDING, + .init = nhk8815_nand_init, }; static struct platform_device nhk8815_nand_device = { - .name = "fsmc-nand", - .id = -1, - .resource = nhk8815_nand_resources, - .num_resources = ARRAY_SIZE(nhk8815_nand_resources), - .dev = { - .platform_data = &nhk8815_nand_platform_data, + .name = "nomadik_nand", + .dev = { + .platform_data = &nhk8815_nand_data, }, + .resource = nhk8815_nand_resources, + .num_resources = ARRAY_SIZE(nhk8815_nand_resources), }; /* These are the partitions for the OneNand device, different from above */ @@ -179,10 +176,6 @@ static struct platform_device nhk8815_onenand_device = { .num_resources = ARRAY_SIZE(nhk8815_onenand_resource), }; -/* bus control reg. and bus timing reg. for CS0..CS3 */ -#define FSMC_BCR(x) (NOMADIK_FSMC_VA + (x << 3)) -#define FSMC_BTR(x) (NOMADIK_FSMC_VA + (x << 3) + 0x04) - static void __init nhk8815_onenand_init(void) { #ifdef CONFIG_MTD_ONENAND diff --git a/trunk/arch/arm/mach-nomadik/include/mach/fsmc.h b/trunk/arch/arm/mach-nomadik/include/mach/fsmc.h new file mode 100644 index 000000000000..8c2c05183685 --- /dev/null +++ b/trunk/arch/arm/mach-nomadik/include/mach/fsmc.h @@ -0,0 +1,29 @@ + +/* Definitions for the Nomadik FSMC "Flexible Static Memory controller" */ + +#ifndef __ASM_ARCH_FSMC_H +#define __ASM_ARCH_FSMC_H + +#include +/* + * Register list + */ + +/* bus control reg. and bus timing reg. for CS0..CS3 */ +#define FSMC_BCR(x) (NOMADIK_FSMC_VA + (x << 3)) +#define FSMC_BTR(x) (NOMADIK_FSMC_VA + (x << 3) + 0x04) + +/* PC-card and NAND: + * PCR = control register + * PMEM = memory timing + * PATT = attribute timing + * PIO = I/O timing + * PECCR = ECC result + */ +#define FSMC_PCR(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x00) +#define FSMC_PMEM(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x08) +#define FSMC_PATT(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x0c) +#define FSMC_PIO(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x10) +#define FSMC_PECCR(x) (NOMADIK_FSMC_VA + ((2 + x) << 5) + 0x14) + +#endif /* __ASM_ARCH_FSMC_H */ diff --git a/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c b/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c index cf07e289b4ea..60529e0b3d67 100644 --- a/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/trunk/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -256,11 +256,6 @@ static struct spi_board_info rx51_peripherals_spi_board_info[] __initdata = { }, }; -static struct platform_device rx51_battery_device = { - .name = "rx51-battery", - .id = -1, -}; - static void rx51_charger_set_power(bool on) { gpio_set_value(RX51_USB_TRANSCEIVER_RST_GPIO, on); @@ -282,7 +277,6 @@ static void __init rx51_charger_init(void) WARN_ON(gpio_request_one(RX51_USB_TRANSCEIVER_RST_GPIO, GPIOF_OUT_INIT_HIGH, "isp1704_reset")); - platform_device_register(&rx51_battery_device); platform_device_register(&rx51_charger_device); } diff --git a/trunk/arch/arm/mach-u300/core.c b/trunk/arch/arm/mach-u300/core.c index 8b204ae69002..12f3994c43db 100644 --- a/trunk/arch/arm/mach-u300/core.c +++ b/trunk/arch/arm/mach-u300/core.c @@ -249,18 +249,6 @@ static struct resource rtc_resources[] = { * but these are not yet used by the driver. */ static struct resource fsmc_resources[] = { - { - .name = "nand_addr", - .start = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_ALE, - .end = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_ALE + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, - { - .name = "nand_cmd", - .start = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_CLE, - .end = U300_NAND_CS0_PHYS_BASE + PLAT_NAND_CLE + SZ_16K - 1, - .flags = IORESOURCE_MEM, - }, { .name = "nand_data", .start = U300_NAND_CS0_PHYS_BASE, @@ -1504,6 +1492,8 @@ static struct fsmc_nand_platform_data nand_platform_data = { .nr_partitions = ARRAY_SIZE(u300_partitions), .options = NAND_SKIP_BBTSCAN, .width = FSMC_NAND_BW8, + .ale_off = PLAT_NAND_ALE, + .cle_off = PLAT_NAND_CLE, }; static struct platform_device nand_device = { diff --git a/trunk/arch/cris/kernel/module.c b/trunk/arch/cris/kernel/module.c index 51123f985eb5..37400f5869e6 100644 --- a/trunk/arch/cris/kernel/module.c +++ b/trunk/arch/cris/kernel/module.c @@ -32,6 +32,8 @@ #ifdef CONFIG_ETRAX_KMALLOCED_MODULES void *module_alloc(unsigned long size) { + if (size == 0) + return NULL; return kmalloc(size, GFP_KERNEL); } diff --git a/trunk/arch/parisc/kernel/module.c b/trunk/arch/parisc/kernel/module.c index 2a625fb063e1..5e34ccf39a49 100644 --- a/trunk/arch/parisc/kernel/module.c +++ b/trunk/arch/parisc/kernel/module.c @@ -214,6 +214,8 @@ static inline int reassemble_22(int as22) void *module_alloc(unsigned long size) { + if (size == 0) + return NULL; /* using RWX means less protection for modules, but it's * easier than trying to map the text, data, init_text and * init_data correctly */ diff --git a/trunk/arch/powerpc/include/asm/systbl.h b/trunk/arch/powerpc/include/asm/systbl.h index 97909d3b1d7b..cec8aae5cbf8 100644 --- a/trunk/arch/powerpc/include/asm/systbl.h +++ b/trunk/arch/powerpc/include/asm/systbl.h @@ -356,4 +356,3 @@ COMPAT_SYS_SPU(sendmmsg) SYSCALL_SPU(setns) COMPAT_SYS(process_vm_readv) COMPAT_SYS(process_vm_writev) -SYSCALL(finit_module) diff --git a/trunk/arch/powerpc/include/asm/unistd.h b/trunk/arch/powerpc/include/asm/unistd.h index 29365e15ed7c..bcbbe413c606 100644 --- a/trunk/arch/powerpc/include/asm/unistd.h +++ b/trunk/arch/powerpc/include/asm/unistd.h @@ -12,7 +12,7 @@ #include -#define __NR_syscalls 354 +#define __NR_syscalls 353 #define __NR__exit __NR_exit #define NR_syscalls __NR_syscalls diff --git a/trunk/arch/powerpc/include/uapi/asm/unistd.h b/trunk/arch/powerpc/include/uapi/asm/unistd.h index 8c478c6c6b1e..380b5d37a904 100644 --- a/trunk/arch/powerpc/include/uapi/asm/unistd.h +++ b/trunk/arch/powerpc/include/uapi/asm/unistd.h @@ -375,7 +375,6 @@ #define __NR_setns 350 #define __NR_process_vm_readv 351 #define __NR_process_vm_writev 352 -#define __NR_finit_module 353 #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */ diff --git a/trunk/arch/sparc/kernel/module.c b/trunk/arch/sparc/kernel/module.c index 4435488ebe25..f1ddc0d23679 100644 --- a/trunk/arch/sparc/kernel/module.c +++ b/trunk/arch/sparc/kernel/module.c @@ -43,6 +43,10 @@ void *module_alloc(unsigned long size) { void *ret; + /* We handle the zero case fine, unlike vmalloc */ + if (size == 0) + return NULL; + ret = module_map(size); if (ret) memset(ret, 0, size); diff --git a/trunk/arch/tile/kernel/module.c b/trunk/arch/tile/kernel/module.c index 4918d91bc3a6..243ffebe38d6 100644 --- a/trunk/arch/tile/kernel/module.c +++ b/trunk/arch/tile/kernel/module.c @@ -42,6 +42,8 @@ void *module_alloc(unsigned long size) int i = 0; int npages; + if (size == 0) + return NULL; npages = (size + PAGE_SIZE - 1) / PAGE_SIZE; pages = kmalloc(npages * sizeof(struct page *), GFP_KERNEL); if (pages == NULL) diff --git a/trunk/arch/unicore32/kernel/module.c b/trunk/arch/unicore32/kernel/module.c index 16bd1495b934..8fbe8577f5e6 100644 --- a/trunk/arch/unicore32/kernel/module.c +++ b/trunk/arch/unicore32/kernel/module.c @@ -27,6 +27,9 @@ void *module_alloc(unsigned long size) struct vm_struct *area; size = PAGE_ALIGN(size); + if (!size) + return NULL; + area = __get_vm_area(size, VM_ALLOC, MODULES_VADDR, MODULES_END); if (!area) return NULL; diff --git a/trunk/arch/x86/kernel/cpu/proc.c b/trunk/arch/x86/kernel/cpu/proc.c index 3286a92e662a..fbd895562292 100644 --- a/trunk/arch/x86/kernel/cpu/proc.c +++ b/trunk/arch/x86/kernel/cpu/proc.c @@ -26,6 +26,11 @@ static void show_cpuinfo_core(struct seq_file *m, struct cpuinfo_x86 *c, #ifdef CONFIG_X86_32 static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c) { + /* + * We use exception 16 if we have hardware math and we've either seen + * it or the CPU claims it is internal + */ + int fpu_exception = c->hard_math && (ignore_fpu_irq || cpu_has_fpu); seq_printf(m, "fdiv_bug\t: %s\n" "hlt_bug\t\t: %s\n" @@ -40,7 +45,7 @@ static void show_cpuinfo_misc(struct seq_file *m, struct cpuinfo_x86 *c) c->f00f_bug ? "yes" : "no", c->coma_bug ? "yes" : "no", c->hard_math ? "yes" : "no", - c->hard_math ? "yes" : "no", + fpu_exception ? "yes" : "no", c->cpuid_level, c->wp_works_ok ? "yes" : "no"); } diff --git a/trunk/arch/x86/kernel/irqinit.c b/trunk/arch/x86/kernel/irqinit.c index 7dc4e459c2b3..6e03b0d69138 100644 --- a/trunk/arch/x86/kernel/irqinit.c +++ b/trunk/arch/x86/kernel/irqinit.c @@ -42,6 +42,39 @@ * (these are usually mapped into the 0x30-0xff vector range) */ +#ifdef CONFIG_X86_32 +/* + * Note that on a 486, we don't want to do a SIGFPE on an irq13 + * as the irq is unreliable, and exception 16 works correctly + * (ie as explained in the intel literature). On a 386, you + * can't use exception 16 due to bad IBM design, so we have to + * rely on the less exact irq13. + * + * Careful.. Not only is IRQ13 unreliable, but it is also + * leads to races. IBM designers who came up with it should + * be shot. + */ + +static irqreturn_t math_error_irq(int cpl, void *dev_id) +{ + outb(0, 0xF0); + if (ignore_fpu_irq || !boot_cpu_data.hard_math) + return IRQ_NONE; + math_error(get_irq_regs(), 0, X86_TRAP_MF); + return IRQ_HANDLED; +} + +/* + * New motherboards sometimes make IRQ 13 be a PCI interrupt, + * so allow interrupt sharing. + */ +static struct irqaction fpu_irq = { + .handler = math_error_irq, + .name = "fpu", + .flags = IRQF_NO_THREAD, +}; +#endif + /* * IRQ2 is cascade interrupt to second interrupt controller */ @@ -209,6 +242,13 @@ void __init native_init_IRQ(void) setup_irq(2, &irq2); #ifdef CONFIG_X86_32 + /* + * External FPU? Set up irq13 if so, for + * original braindamaged IBM FERR coupling. + */ + if (boot_cpu_data.hard_math && !cpu_has_fpu) + setup_irq(FPU_IRQ, &fpu_irq); + irq_ctx_init(smp_processor_id()); #endif } diff --git a/trunk/arch/x86/kernel/traps.c b/trunk/arch/x86/kernel/traps.c index ecffca11f4e9..eb8586693e0b 100644 --- a/trunk/arch/x86/kernel/traps.c +++ b/trunk/arch/x86/kernel/traps.c @@ -69,6 +69,9 @@ asmlinkage int system_call(void); +/* Do we ignore FPU interrupts ? */ +char ignore_fpu_irq; + /* * The IDT has to be page-aligned to simplify the Pentium * F0 0F bug workaround. @@ -561,6 +564,9 @@ void math_error(struct pt_regs *regs, int error_code, int trapnr) dotraplinkage void do_coprocessor_error(struct pt_regs *regs, long error_code) { +#ifdef CONFIG_X86_32 + ignore_fpu_irq = 1; +#endif exception_enter(regs); math_error(regs, error_code, X86_TRAP_MF); exception_exit(regs); diff --git a/trunk/arch/x86/syscalls/syscall_32.tbl b/trunk/arch/x86/syscalls/syscall_32.tbl index 05f404f53f59..ee3c220ee500 100644 --- a/trunk/arch/x86/syscalls/syscall_32.tbl +++ b/trunk/arch/x86/syscalls/syscall_32.tbl @@ -356,4 +356,3 @@ 347 i386 process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv 348 i386 process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev 349 i386 kcmp sys_kcmp -350 i386 finit_module sys_finit_module diff --git a/trunk/arch/x86/syscalls/syscall_64.tbl b/trunk/arch/x86/syscalls/syscall_64.tbl index 7c58c84b7bc8..a582bfed95bb 100644 --- a/trunk/arch/x86/syscalls/syscall_64.tbl +++ b/trunk/arch/x86/syscalls/syscall_64.tbl @@ -319,7 +319,6 @@ 310 64 process_vm_readv sys_process_vm_readv 311 64 process_vm_writev sys_process_vm_writev 312 common kcmp sys_kcmp -313 common finit_module sys_finit_module # # x32-specific system call numbers start at 512 to avoid cache impact diff --git a/trunk/arch/xtensa/Kconfig b/trunk/arch/xtensa/Kconfig index 73d34e77c39c..2481f267be29 100644 --- a/trunk/arch/xtensa/Kconfig +++ b/trunk/arch/xtensa/Kconfig @@ -17,7 +17,6 @@ config XTENSA select GENERIC_KERNEL_EXECVE select ARCH_WANT_OPTIONAL_GPIOLIB select CLONE_BACKWARDS - select IRQ_DOMAIN help Xtensa processors are 32-bit RISC machines designed by Tensilica primarily for embedded systems. These processors are both @@ -151,15 +150,6 @@ config XTENSA_PLATFORM_S6105 select SERIAL_CONSOLE select NO_IOPORT -config XTENSA_PLATFORM_XTFPGA - bool "XTFPGA" - select SERIAL_CONSOLE - select ETHOC - select XTENSA_CALIBRATE_CCOUNT - help - XTFPGA is the name of Tensilica board family (LX60, LX110, LX200, ML605). - This hardware is capable of running a full Linux distribution. - endchoice @@ -187,17 +177,6 @@ config CMDLINE time by entering them here. As a minimum, you should specify the memory size and the root device (e.g., mem=64M root=/dev/nfs). -config USE_OF - bool "Flattened Device Tree support" - select OF - select OF_EARLY_FLATTREE - help - Include support for flattened device tree machine descriptions. - -config BUILTIN_DTB - string "DTB to build into the kernel image" - depends on OF - source "mm/Kconfig" source "drivers/pcmcia/Kconfig" diff --git a/trunk/arch/xtensa/Kconfig.debug b/trunk/arch/xtensa/Kconfig.debug index a34010e0e51c..11c585295dd7 100644 --- a/trunk/arch/xtensa/Kconfig.debug +++ b/trunk/arch/xtensa/Kconfig.debug @@ -2,26 +2,6 @@ menu "Kernel hacking" source "lib/Kconfig.debug" -config LD_NO_RELAX - bool "Disable linker relaxation" - default n - help - Enable this function to disable link-time optimizations. - The default linker behavior is to combine identical literal - values to reduce code size and remove unnecessary overhead from - assembler-generated 'longcall' sequences. - Enabling this option improves the link time but increases the - code size, and possibly execution time. - -config S32C1I_SELFTEST - bool "Perform S32C1I instruction self-test at boot" - default y - help - Enable this option to test S32C1I instruction behavior at boot. - Correct operation of this instruction requires some cooperation from hardware - external to the processor (such as bus bridge, bus fabric, or memory controller). - It is easy to make wrong hardware configuration, this test should catch it early. +endmenu - Say 'N' on stable hardware. -endmenu diff --git a/trunk/arch/xtensa/Makefile b/trunk/arch/xtensa/Makefile index 0aa72702f179..bb5ba61723f7 100644 --- a/trunk/arch/xtensa/Makefile +++ b/trunk/arch/xtensa/Makefile @@ -38,7 +38,6 @@ endif platform-$(CONFIG_XTENSA_PLATFORM_XT2000) := xt2000 platform-$(CONFIG_XTENSA_PLATFORM_ISS) := iss platform-$(CONFIG_XTENSA_PLATFORM_S6105) := s6105 -platform-$(CONFIG_XTENSA_PLATFORM_XTFPGA) := xtfpga PLATFORM = $(platform-y) export PLATFORM @@ -50,17 +49,6 @@ KBUILD_CFLAGS += -pipe -mlongcalls KBUILD_CFLAGS += $(call cc-option,-mforce-no-pic,) -ifneq ($(CONFIG_LD_NO_RELAX),) -LDFLAGS := --no-relax -endif - -ifeq ($(shell echo -e __XTENSA_EB__ | $(CC) -E - | grep -v "\#"),1) -CHECKFLAGS += -D__XTENSA_EB__ -endif -ifeq ($(shell echo -e __XTENSA_EL__ | $(CC) -E - | grep -v "\#"),1) -CHECKFLAGS += -D__XTENSA_EL__ -endif - vardirs := $(patsubst %,arch/xtensa/variants/%/,$(variant-y)) plfdirs := $(patsubst %,arch/xtensa/platforms/%/,$(platform-y)) @@ -87,10 +75,6 @@ core-y += $(buildvar) $(buildplf) libs-y += arch/xtensa/lib/ $(LIBGCC) -ifneq ($(CONFIG_BUILTIN_DTB),"") -core-$(CONFIG_OF) += arch/xtensa/boot/ -endif - boot := arch/xtensa/boot all: zImage @@ -100,9 +84,7 @@ bzImage : zImage zImage: vmlinux $(Q)$(MAKE) $(build)=$(boot) $@ -%.dtb: - $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ - define archhelp @echo '* zImage - Compressed kernel image (arch/xtensa/boot/images/zImage.*)' endef + diff --git a/trunk/arch/xtensa/boot/Makefile b/trunk/arch/xtensa/boot/Makefile index 818647e815d7..4018f8994196 100644 --- a/trunk/arch/xtensa/boot/Makefile +++ b/trunk/arch/xtensa/boot/Makefile @@ -22,35 +22,12 @@ subdir-y := lib # Subdirs for the boot loader(s) bootdir-$(CONFIG_XTENSA_PLATFORM_ISS) += boot-elf -bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf boot-uboot -bootdir-$(CONFIG_XTENSA_PLATFORM_XTFPGA) += boot-redboot boot-elf boot-uboot +bootdir-$(CONFIG_XTENSA_PLATFORM_XT2000) += boot-redboot boot-elf -BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB)).dtb.o -ifneq ($(CONFIG_BUILTIN_DTB),"") -obj-$(CONFIG_OF) += $(BUILTIN_DTB) -endif - -# Rule to build device tree blobs -$(obj)/%.dtb: $(src)/dts/%.dts FORCE - $(call if_changed_dep,dtc) - -clean-files := *.dtb.S - zImage Image: $(bootdir-y) $(bootdir-y): $(addprefix $(obj)/,$(subdir-y)) \ $(addprefix $(obj)/,$(host-progs)) $(Q)$(MAKE) $(build)=$(obj)/$@ $(MAKECMDGOALS) -OBJCOPYFLAGS = --strip-all -R .comment -R .note.gnu.build-id -O binary - -vmlinux.bin: vmlinux FORCE - $(call if_changed,objcopy) - -vmlinux.bin.gz: vmlinux.bin FORCE - $(call if_changed,gzip) - -boot-elf: vmlinux.bin -boot-redboot: vmlinux.bin.gz -boot-uboot: vmlinux.bin.gz diff --git a/trunk/arch/xtensa/boot/boot-elf/Makefile b/trunk/arch/xtensa/boot/boot-elf/Makefile index 1fe01b78c124..f10992b89027 100644 --- a/trunk/arch/xtensa/boot/boot-elf/Makefile +++ b/trunk/arch/xtensa/boot/boot-elf/Makefile @@ -4,6 +4,9 @@ # for more details. # +GZIP = gzip +GZIP_FLAGS = -v9fc + ifeq ($(BIG_ENDIAN),1) OBJCOPY_ARGS := -O elf32-xtensa-be else @@ -17,17 +20,18 @@ boot-y := bootstrap.o OBJS := $(addprefix $(obj)/,$(boot-y)) -$(obj)/Image.o: vmlinux.bin $(OBJS) - $(Q)$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ - --add-section image=vmlinux.bin \ +vmlinux.tmp: vmlinux + $(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \ + $^ $@ + +Image: vmlinux.tmp $(OBJS) arch/$(ARCH)/boot/boot-elf/boot.lds + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section image=vmlinux.tmp \ --set-section-flags image=contents,alloc,load,load,data \ - $(OBJS) $@ + $(OBJS) $@.tmp + $(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \ + -T arch/$(ARCH)/boot/boot-elf/boot.lds \ + -o arch/$(ARCH)/boot/$@.elf $@.tmp -$(obj)/../Image.elf: $(obj)/Image.o $(obj)/boot.lds - $(Q)$(LD) $(LDFLAGS) $(LDFLAGS_vmlinux) \ - -T $(obj)/boot.lds \ - --build-id=none \ - -o $@ $(obj)/Image.o - $(Q)$(kecho) ' Kernel: $@ is ready' +zImage: Image -zImage: $(obj)/../Image.elf diff --git a/trunk/arch/xtensa/boot/boot-redboot/Makefile b/trunk/arch/xtensa/boot/boot-redboot/Makefile index 8be8b9436981..25a78c6b1530 100644 --- a/trunk/arch/xtensa/boot/boot-redboot/Makefile +++ b/trunk/arch/xtensa/boot/boot-redboot/Makefile @@ -4,6 +4,8 @@ # for more details. # +GZIP = gzip +GZIP_FLAGS = -v9fc ifeq ($(BIG_ENDIAN),1) OBJCOPY_ARGS := -O elf32-xtensa-be else @@ -19,17 +21,17 @@ LIBS := arch/xtensa/boot/lib/lib.a arch/xtensa/lib/lib.a LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name) -$(obj)/zImage.o: vmlinux.bin.gz $(OBJS) - $(Q)$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ - --add-section image=vmlinux.bin.gz \ - --set-section-flags image=contents,alloc,load,load,data \ - $(OBJS) $@ - -$(obj)/zImage.elf: $(obj)/zImage.o $(LIBS) - $(Q)$(LD) $(LD_ARGS) -o $@ $^ -L/xtensa-elf/lib $(LIBGCC) +vmlinux.tmp: vmlinux + $(OBJCOPY) --strip-all -R .comment -R .note.gnu.build-id -O binary \ + $^ $@ -$(obj)/../zImage.redboot: $(obj)/zImage.elf - $(Q)$(OBJCOPY) -S -O binary $< $@ - $(Q)$(kecho) ' Kernel: $@ is ready' +vmlinux.tmp.gz: vmlinux.tmp + $(GZIP) $(GZIP_FLAGS) $^ > $@ -zImage: $(obj)/../zImage.redboot +zImage: vmlinux.tmp.gz $(OBJS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section image=vmlinux.tmp.gz \ + --set-section-flags image=contents,alloc,load,load,data \ + $(OBJS) $@.tmp + $(LD) $(LD_ARGS) -o $@.elf $@.tmp $(LIBS) -L/xtensa-elf/lib $(LIBGCC) + $(OBJCOPY) -S -O binary $@.elf arch/$(ARCH)/boot/$@.redboot diff --git a/trunk/arch/xtensa/boot/boot-uboot/Makefile b/trunk/arch/xtensa/boot/boot-uboot/Makefile deleted file mode 100644 index bfbf8af582f1..000000000000 --- a/trunk/arch/xtensa/boot/boot-uboot/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# - -UIMAGE_LOADADDR = 0xd0001000 -UIMAGE_COMPRESSION = gzip - -$(obj)/../uImage: vmlinux.bin.gz FORCE - $(call if_changed,uimage) - $(Q)$(kecho) ' Kernel: $@ is ready' - -zImage: $(obj)/../uImage diff --git a/trunk/arch/xtensa/boot/dts/lx60.dts b/trunk/arch/xtensa/boot/dts/lx60.dts deleted file mode 100644 index 2eab3658e1bd..000000000000 --- a/trunk/arch/xtensa/boot/dts/lx60.dts +++ /dev/null @@ -1,11 +0,0 @@ -/dts-v1/; -/include/ "xtfpga.dtsi" -/include/ "xtfpga-flash-4m.dtsi" - -/ { - compatible = "xtensa,lx60"; - memory@0 { - device_type = "memory"; - reg = <0x00000000 0x04000000>; - }; -}; diff --git a/trunk/arch/xtensa/boot/dts/ml605.dts b/trunk/arch/xtensa/boot/dts/ml605.dts deleted file mode 100644 index 6ed51d6554e6..000000000000 --- a/trunk/arch/xtensa/boot/dts/ml605.dts +++ /dev/null @@ -1,11 +0,0 @@ -/dts-v1/; -/include/ "xtfpga.dtsi" -/include/ "xtfpga-flash-16m.dtsi" - -/ { - compatible = "xtensa,ml605"; - memory@0 { - device_type = "memory"; - reg = <0x00000000 0x08000000>; - }; -}; diff --git a/trunk/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi b/trunk/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi deleted file mode 100644 index e5703c7beeb6..000000000000 --- a/trunk/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi +++ /dev/null @@ -1,26 +0,0 @@ -/ { - flash: flash@f8000000 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "cfi-flash"; - reg = <0xf8000000 0x01000000>; - bank-width = <2>; - device-width = <2>; - partition@0x0 { - label = "boot loader area"; - reg = <0x00000000 0x00400000>; - }; - partition@0x400000 { - label = "kernel image"; - reg = <0x00400000 0x00600000>; - }; - partition@0xa00000 { - label = "data"; - reg = <0x00a00000 0x005e0000>; - }; - partition@0xfe0000 { - label = "boot environment"; - reg = <0x00fe0000 0x00020000>; - }; - }; -}; diff --git a/trunk/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi b/trunk/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi deleted file mode 100644 index 6f9c10d6b689..000000000000 --- a/trunk/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi +++ /dev/null @@ -1,18 +0,0 @@ -/ { - flash: flash@f8000000 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "cfi-flash"; - reg = <0xf8000000 0x00400000>; - bank-width = <2>; - device-width = <2>; - partition@0x0 { - label = "boot loader area"; - reg = <0x00000000 0x003f0000>; - }; - partition@0x3f0000 { - label = "boot environment"; - reg = <0x003f0000 0x00010000>; - }; - }; -}; diff --git a/trunk/arch/xtensa/boot/dts/xtfpga.dtsi b/trunk/arch/xtensa/boot/dts/xtfpga.dtsi deleted file mode 100644 index 7eda6ecf7eef..000000000000 --- a/trunk/arch/xtensa/boot/dts/xtfpga.dtsi +++ /dev/null @@ -1,56 +0,0 @@ -/ { - compatible = "xtensa,xtfpga"; - #address-cells = <1>; - #size-cells = <1>; - interrupt-parent = <&pic>; - - chosen { - bootargs = "earlycon=uart8250,mmio32,0xfd050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug"; - }; - - memory@0 { - device_type = "memory"; - reg = <0x00000000 0x06000000>; - }; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - cpu@0 { - compatible = "xtensa,cpu"; - reg = <0>; - /* Filled in by platform_setup from FPGA register - * clock-frequency = <100000000>; - */ - }; - }; - - pic: pic { - compatible = "xtensa,pic"; - /* one cell: internal irq number, - * two cells: second cell == 0: internal irq number - * second cell == 1: external irq number - */ - #interrupt-cells = <2>; - interrupt-controller; - }; - - serial0: serial@fd050020 { - device_type = "serial"; - compatible = "ns16550a"; - no-loopback-test; - reg = <0xfd050020 0x20>; - reg-shift = <2>; - interrupts = <0 1>; /* external irq 0 */ - /* Filled in by platform_setup from FPGA register - * clock-frequency = <100000000>; - */ - }; - - enet0: ethoc@fd030000 { - compatible = "opencores,ethoc"; - reg = <0xfd030000 0x4000 0xfd800000 0x4000>; - interrupts = <1 1>; /* external irq 1 */ - local-mac-address = [00 50 c2 13 6f 00]; - }; -}; diff --git a/trunk/arch/xtensa/include/asm/atomic.h b/trunk/arch/xtensa/include/asm/atomic.h index c3f289174c10..24f50cada70c 100644 --- a/trunk/arch/xtensa/include/asm/atomic.h +++ b/trunk/arch/xtensa/include/asm/atomic.h @@ -66,35 +66,19 @@ */ static inline void atomic_add(int i, atomic_t * v) { -#if XCHAL_HAVE_S32C1I - unsigned long tmp; - int result; - - __asm__ __volatile__( - "1: l32i %1, %3, 0\n" - " wsr %1, scompare1\n" - " add %0, %1, %2\n" - " s32c1i %0, %3, 0\n" - " bne %0, %1, 1b\n" - : "=&a" (result), "=&a" (tmp) - : "a" (i), "a" (v) - : "memory" - ); -#else - unsigned int vval; - - __asm__ __volatile__( - " rsil a15, "__stringify(LOCKLEVEL)"\n" - " l32i %0, %2, 0\n" - " add %0, %0, %1\n" - " s32i %0, %2, 0\n" - " wsr a15, ps\n" - " rsync\n" - : "=&a" (vval) - : "a" (i), "a" (v) - : "a15", "memory" - ); -#endif + unsigned int vval; + + __asm__ __volatile__( + "rsil a15, "__stringify(LOCKLEVEL)"\n\t" + "l32i %0, %2, 0 \n\t" + "add %0, %0, %1 \n\t" + "s32i %0, %2, 0 \n\t" + "wsr a15, ps \n\t" + "rsync \n" + : "=&a" (vval) + : "a" (i), "a" (v) + : "a15", "memory" + ); } /** @@ -106,35 +90,19 @@ static inline void atomic_add(int i, atomic_t * v) */ static inline void atomic_sub(int i, atomic_t *v) { -#if XCHAL_HAVE_S32C1I - unsigned long tmp; - int result; - - __asm__ __volatile__( - "1: l32i %1, %3, 0\n" - " wsr %1, scompare1\n" - " sub %0, %1, %2\n" - " s32c1i %0, %3, 0\n" - " bne %0, %1, 1b\n" - : "=&a" (result), "=&a" (tmp) - : "a" (i), "a" (v) - : "memory" - ); -#else - unsigned int vval; - - __asm__ __volatile__( - " rsil a15, "__stringify(LOCKLEVEL)"\n" - " l32i %0, %2, 0\n" - " sub %0, %0, %1\n" - " s32i %0, %2, 0\n" - " wsr a15, ps\n" - " rsync\n" - : "=&a" (vval) - : "a" (i), "a" (v) - : "a15", "memory" - ); -#endif + unsigned int vval; + + __asm__ __volatile__( + "rsil a15, "__stringify(LOCKLEVEL)"\n\t" + "l32i %0, %2, 0 \n\t" + "sub %0, %0, %1 \n\t" + "s32i %0, %2, 0 \n\t" + "wsr a15, ps \n\t" + "rsync \n" + : "=&a" (vval) + : "a" (i), "a" (v) + : "a15", "memory" + ); } /* @@ -143,78 +111,40 @@ static inline void atomic_sub(int i, atomic_t *v) static inline int atomic_add_return(int i, atomic_t * v) { -#if XCHAL_HAVE_S32C1I - unsigned long tmp; - int result; - - __asm__ __volatile__( - "1: l32i %1, %3, 0\n" - " wsr %1, scompare1\n" - " add %0, %1, %2\n" - " s32c1i %0, %3, 0\n" - " bne %0, %1, 1b\n" - " add %0, %0, %2\n" - : "=&a" (result), "=&a" (tmp) - : "a" (i), "a" (v) - : "memory" - ); - - return result; -#else - unsigned int vval; - - __asm__ __volatile__( - " rsil a15,"__stringify(LOCKLEVEL)"\n" - " l32i %0, %2, 0\n" - " add %0, %0, %1\n" - " s32i %0, %2, 0\n" - " wsr a15, ps\n" - " rsync\n" - : "=&a" (vval) - : "a" (i), "a" (v) - : "a15", "memory" - ); - - return vval; -#endif + unsigned int vval; + + __asm__ __volatile__( + "rsil a15,"__stringify(LOCKLEVEL)"\n\t" + "l32i %0, %2, 0 \n\t" + "add %0, %0, %1 \n\t" + "s32i %0, %2, 0 \n\t" + "wsr a15, ps \n\t" + "rsync \n" + : "=&a" (vval) + : "a" (i), "a" (v) + : "a15", "memory" + ); + + return vval; } static inline int atomic_sub_return(int i, atomic_t * v) { -#if XCHAL_HAVE_S32C1I - unsigned long tmp; - int result; - - __asm__ __volatile__( - "1: l32i %1, %3, 0\n" - " wsr %1, scompare1\n" - " sub %0, %1, %2\n" - " s32c1i %0, %3, 0\n" - " bne %0, %1, 1b\n" - " sub %0, %0, %2\n" - : "=&a" (result), "=&a" (tmp) - : "a" (i), "a" (v) - : "memory" - ); - - return result; -#else - unsigned int vval; - - __asm__ __volatile__( - " rsil a15,"__stringify(LOCKLEVEL)"\n" - " l32i %0, %2, 0\n" - " sub %0, %0, %1\n" - " s32i %0, %2, 0\n" - " wsr a15, ps\n" - " rsync\n" - : "=&a" (vval) - : "a" (i), "a" (v) - : "a15", "memory" - ); - - return vval; -#endif + unsigned int vval; + + __asm__ __volatile__( + "rsil a15,"__stringify(LOCKLEVEL)"\n\t" + "l32i %0, %2, 0 \n\t" + "sub %0, %0, %1 \n\t" + "s32i %0, %2, 0 \n\t" + "wsr a15, ps \n\t" + "rsync \n" + : "=&a" (vval) + : "a" (i), "a" (v) + : "a15", "memory" + ); + + return vval; } /** @@ -321,70 +251,38 @@ static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) static inline void atomic_clear_mask(unsigned int mask, atomic_t *v) { -#if XCHAL_HAVE_S32C1I - unsigned long tmp; - int result; - - __asm__ __volatile__( - "1: l32i %1, %3, 0\n" - " wsr %1, scompare1\n" - " and %0, %1, %2\n" - " s32c1i %0, %3, 0\n" - " bne %0, %1, 1b\n" - : "=&a" (result), "=&a" (tmp) - : "a" (~mask), "a" (v) - : "memory" - ); -#else - unsigned int all_f = -1; - unsigned int vval; - - __asm__ __volatile__( - " rsil a15,"__stringify(LOCKLEVEL)"\n" - " l32i %0, %2, 0\n" - " xor %1, %4, %3\n" - " and %0, %0, %4\n" - " s32i %0, %2, 0\n" - " wsr a15, ps\n" - " rsync\n" - : "=&a" (vval), "=a" (mask) - : "a" (v), "a" (all_f), "1" (mask) - : "a15", "memory" - ); -#endif + unsigned int all_f = -1; + unsigned int vval; + + __asm__ __volatile__( + "rsil a15,"__stringify(LOCKLEVEL)"\n\t" + "l32i %0, %2, 0 \n\t" + "xor %1, %4, %3 \n\t" + "and %0, %0, %4 \n\t" + "s32i %0, %2, 0 \n\t" + "wsr a15, ps \n\t" + "rsync \n" + : "=&a" (vval), "=a" (mask) + : "a" (v), "a" (all_f), "1" (mask) + : "a15", "memory" + ); } static inline void atomic_set_mask(unsigned int mask, atomic_t *v) { -#if XCHAL_HAVE_S32C1I - unsigned long tmp; - int result; - - __asm__ __volatile__( - "1: l32i %1, %3, 0\n" - " wsr %1, scompare1\n" - " or %0, %1, %2\n" - " s32c1i %0, %3, 0\n" - " bne %0, %1, 1b\n" - : "=&a" (result), "=&a" (tmp) - : "a" (mask), "a" (v) - : "memory" - ); -#else - unsigned int vval; - - __asm__ __volatile__( - " rsil a15,"__stringify(LOCKLEVEL)"\n" - " l32i %0, %2, 0\n" - " or %0, %0, %1\n" - " s32i %0, %2, 0\n" - " wsr a15, ps\n" - " rsync\n" - : "=&a" (vval) - : "a" (mask), "a" (v) - : "a15", "memory" - ); -#endif + unsigned int vval; + + __asm__ __volatile__( + "rsil a15,"__stringify(LOCKLEVEL)"\n\t" + "l32i %0, %2, 0 \n\t" + "or %0, %0, %1 \n\t" + "s32i %0, %2, 0 \n\t" + "wsr a15, ps \n\t" + "rsync \n" + : "=&a" (vval) + : "a" (mask), "a" (v) + : "a15", "memory" + ); } /* Atomic operations are already serializing */ @@ -396,3 +294,4 @@ static inline void atomic_set_mask(unsigned int mask, atomic_t *v) #endif /* __KERNEL__ */ #endif /* _XTENSA_ATOMIC_H */ + diff --git a/trunk/arch/xtensa/include/asm/barrier.h b/trunk/arch/xtensa/include/asm/barrier.h index ef021677d536..55707a8009d3 100644 --- a/trunk/arch/xtensa/include/asm/barrier.h +++ b/trunk/arch/xtensa/include/asm/barrier.h @@ -3,7 +3,7 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001 - 2012 Tensilica Inc. + * Copyright (C) 2001 - 2005 Tensilica Inc. */ #ifndef _XTENSA_SYSTEM_H @@ -12,8 +12,8 @@ #define smp_read_barrier_depends() do { } while(0) #define read_barrier_depends() do { } while(0) -#define mb() ({ __asm__ __volatile__("memw" : : : "memory"); }) -#define rmb() barrier() +#define mb() barrier() +#define rmb() mb() #define wmb() mb() #ifdef CONFIG_SMP diff --git a/trunk/arch/xtensa/include/asm/bitops.h b/trunk/arch/xtensa/include/asm/bitops.h index 84afe58d5d37..5270197ddd36 100644 --- a/trunk/arch/xtensa/include/asm/bitops.h +++ b/trunk/arch/xtensa/include/asm/bitops.h @@ -29,6 +29,7 @@ #define smp_mb__before_clear_bit() barrier() #define smp_mb__after_clear_bit() barrier() +#include #include #if XCHAL_HAVE_NSA @@ -103,132 +104,6 @@ static inline unsigned long __fls(unsigned long word) #endif #include - -#if XCHAL_HAVE_S32C1I - -static inline void set_bit(unsigned int bit, volatile unsigned long *p) -{ - unsigned long tmp, value; - unsigned long mask = 1UL << (bit & 31); - - p += bit >> 5; - - __asm__ __volatile__( - "1: l32i %1, %3, 0\n" - " wsr %1, scompare1\n" - " or %0, %1, %2\n" - " s32c1i %0, %3, 0\n" - " bne %0, %1, 1b\n" - : "=&a" (tmp), "=&a" (value) - : "a" (mask), "a" (p) - : "memory"); -} - -static inline void clear_bit(unsigned int bit, volatile unsigned long *p) -{ - unsigned long tmp, value; - unsigned long mask = 1UL << (bit & 31); - - p += bit >> 5; - - __asm__ __volatile__( - "1: l32i %1, %3, 0\n" - " wsr %1, scompare1\n" - " and %0, %1, %2\n" - " s32c1i %0, %3, 0\n" - " bne %0, %1, 1b\n" - : "=&a" (tmp), "=&a" (value) - : "a" (~mask), "a" (p) - : "memory"); -} - -static inline void change_bit(unsigned int bit, volatile unsigned long *p) -{ - unsigned long tmp, value; - unsigned long mask = 1UL << (bit & 31); - - p += bit >> 5; - - __asm__ __volatile__( - "1: l32i %1, %3, 0\n" - " wsr %1, scompare1\n" - " xor %0, %1, %2\n" - " s32c1i %0, %3, 0\n" - " bne %0, %1, 1b\n" - : "=&a" (tmp), "=&a" (value) - : "a" (mask), "a" (p) - : "memory"); -} - -static inline int -test_and_set_bit(unsigned int bit, volatile unsigned long *p) -{ - unsigned long tmp, value; - unsigned long mask = 1UL << (bit & 31); - - p += bit >> 5; - - __asm__ __volatile__( - "1: l32i %1, %3, 0\n" - " wsr %1, scompare1\n" - " or %0, %1, %2\n" - " s32c1i %0, %3, 0\n" - " bne %0, %1, 1b\n" - : "=&a" (tmp), "=&a" (value) - : "a" (mask), "a" (p) - : "memory"); - - return tmp & mask; -} - -static inline int -test_and_clear_bit(unsigned int bit, volatile unsigned long *p) -{ - unsigned long tmp, value; - unsigned long mask = 1UL << (bit & 31); - - p += bit >> 5; - - __asm__ __volatile__( - "1: l32i %1, %3, 0\n" - " wsr %1, scompare1\n" - " and %0, %1, %2\n" - " s32c1i %0, %3, 0\n" - " bne %0, %1, 1b\n" - : "=&a" (tmp), "=&a" (value) - : "a" (~mask), "a" (p) - : "memory"); - - return tmp & mask; -} - -static inline int -test_and_change_bit(unsigned int bit, volatile unsigned long *p) -{ - unsigned long tmp, value; - unsigned long mask = 1UL << (bit & 31); - - p += bit >> 5; - - __asm__ __volatile__( - "1: l32i %1, %3, 0\n" - " wsr %1, scompare1\n" - " xor %0, %1, %2\n" - " s32c1i %0, %3, 0\n" - " bne %0, %1, 1b\n" - : "=&a" (tmp), "=&a" (value) - : "a" (mask), "a" (p) - : "memory"); - - return tmp & mask; -} - -#else - -#include - -#endif /* XCHAL_HAVE_S32C1I */ - #include #include diff --git a/trunk/arch/xtensa/include/asm/bootparam.h b/trunk/arch/xtensa/include/asm/bootparam.h index 0c25799facab..9983f2c1b7ee 100644 --- a/trunk/arch/xtensa/include/asm/bootparam.h +++ b/trunk/arch/xtensa/include/asm/bootparam.h @@ -22,7 +22,6 @@ #define BP_TAG_MEMORY 0x1003 /* memory addr and size (bp_meminfo) */ #define BP_TAG_SERIAL_BAUSRATE 0x1004 /* baud rate of current console. */ #define BP_TAG_SERIAL_PORT 0x1005 /* serial device of current console */ -#define BP_TAG_FDT 0x1006 /* flat device tree addr */ #define BP_TAG_FIRST 0x7B0B /* first tag with a version number */ #define BP_TAG_LAST 0x7E0B /* last tag */ @@ -32,15 +31,15 @@ /* All records are aligned to 4 bytes */ typedef struct bp_tag { - unsigned short id; /* tag id */ - unsigned short size; /* size of this record excluding the structure*/ - unsigned long data[0]; /* data */ + unsigned short id; /* tag id */ + unsigned short size; /* size of this record excluding the structure*/ + unsigned long data[0]; /* data */ } bp_tag_t; typedef struct meminfo { - unsigned long type; - unsigned long start; - unsigned long end; + unsigned long type; + unsigned long start; + unsigned long end; } meminfo_t; #define SYSMEM_BANKS_MAX 5 @@ -49,11 +48,14 @@ typedef struct meminfo { #define MEMORY_TYPE_NONE 0x2000 typedef struct sysmem_info { - int nr_banks; - meminfo_t bank[SYSMEM_BANKS_MAX]; + int nr_banks; + meminfo_t bank[SYSMEM_BANKS_MAX]; } sysmem_info_t; extern sysmem_info_t sysmem; #endif #endif + + + diff --git a/trunk/arch/xtensa/include/asm/cacheasm.h b/trunk/arch/xtensa/include/asm/cacheasm.h index 60e18773ecb8..2c20a58f94cd 100644 --- a/trunk/arch/xtensa/include/asm/cacheasm.h +++ b/trunk/arch/xtensa/include/asm/cacheasm.h @@ -174,3 +174,4 @@ __loop_cache_page \ar \as ihi XCHAL_ICACHE_LINEWIDTH .endm + diff --git a/trunk/arch/xtensa/include/asm/cacheflush.h b/trunk/arch/xtensa/include/asm/cacheflush.h index 127cd48883c4..569fec4f9a20 100644 --- a/trunk/arch/xtensa/include/asm/cacheflush.h +++ b/trunk/arch/xtensa/include/asm/cacheflush.h @@ -104,8 +104,7 @@ static inline void __invalidate_icache_page_alias(unsigned long virt, #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 extern void flush_dcache_page(struct page*); extern void flush_cache_range(struct vm_area_struct*, ulong, ulong); -extern void flush_cache_page(struct vm_area_struct*, - unsigned long, unsigned long); +extern void flush_cache_page(struct vm_area_struct*, unsigned long, unsigned long); #else diff --git a/trunk/arch/xtensa/include/asm/checksum.h b/trunk/arch/xtensa/include/asm/checksum.h index aed7ad68ca46..e4d831a30772 100644 --- a/trunk/arch/xtensa/include/asm/checksum.h +++ b/trunk/arch/xtensa/include/asm/checksum.h @@ -36,9 +36,8 @@ asmlinkage __wsum csum_partial(const void *buff, int len, __wsum sum); * better 64-bit) boundary */ -asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst, - int len, __wsum sum, - int *src_err_ptr, int *dst_err_ptr); +asmlinkage __wsum csum_partial_copy_generic(const void *src, void *dst, int len, __wsum sum, + int *src_err_ptr, int *dst_err_ptr); /* * Note: when you get a NULL pointer exception here this means someone @@ -55,7 +54,7 @@ __wsum csum_partial_copy_nocheck(const void *src, void *dst, static inline __wsum csum_partial_copy_from_user(const void __user *src, void *dst, - int len, __wsum sum, int *err_ptr) + int len, __wsum sum, int *err_ptr) { return csum_partial_copy_generic((__force const void *)src, dst, len, sum, err_ptr, NULL); @@ -113,8 +112,7 @@ static __inline__ __sum16 ip_fast_csum(const void *iph, unsigned int ihl) /* Since the input registers which are loaded with iph and ihl are modified, we must also specify them as outputs, or gcc will assume they contain their original values. */ - : "=r" (sum), "=r" (iph), "=r" (ihl), "=&r" (tmp), - "=&r" (endaddr) + : "=r" (sum), "=r" (iph), "=r" (ihl), "=&r" (tmp), "=&r" (endaddr) : "1" (iph), "2" (ihl) : "memory"); @@ -170,7 +168,7 @@ static __inline__ __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, static __inline__ __sum16 ip_compute_csum(const void *buff, int len) { - return csum_fold (csum_partial(buff, len, 0)); + return csum_fold (csum_partial(buff, len, 0)); } #define _HAVE_ARCH_IPV6_CSUM @@ -240,12 +238,11 @@ static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr, * Copy and checksum to user */ #define HAVE_CSUM_COPY_USER -static __inline__ __wsum csum_and_copy_to_user(const void *src, - void __user *dst, int len, - __wsum sum, int *err_ptr) +static __inline__ __wsum csum_and_copy_to_user(const void *src, void __user *dst, + int len, __wsum sum, int *err_ptr) { if (access_ok(VERIFY_WRITE, dst, len)) - return csum_partial_copy_generic(src,dst,len,sum,NULL,err_ptr); + return csum_partial_copy_generic(src, dst, len, sum, NULL, err_ptr); if (len) *err_ptr = -EFAULT; diff --git a/trunk/arch/xtensa/include/asm/cmpxchg.h b/trunk/arch/xtensa/include/asm/cmpxchg.h index d9ab131bc1aa..64dad04a9d27 100644 --- a/trunk/arch/xtensa/include/asm/cmpxchg.h +++ b/trunk/arch/xtensa/include/asm/cmpxchg.h @@ -22,30 +22,17 @@ static inline unsigned long __cmpxchg_u32(volatile int *p, int old, int new) { -#if XCHAL_HAVE_S32C1I - __asm__ __volatile__( - " wsr %2, scompare1\n" - " s32c1i %0, %1, 0\n" - : "+a" (new) - : "a" (p), "a" (old) - : "memory" - ); - - return new; -#else - __asm__ __volatile__( - " rsil a15, "__stringify(LOCKLEVEL)"\n" - " l32i %0, %1, 0\n" - " bne %0, %2, 1f\n" - " s32i %3, %1, 0\n" - "1:\n" - " wsr a15, ps\n" - " rsync\n" - : "=&a" (old) - : "a" (p), "a" (old), "r" (new) - : "a15", "memory"); - return old; -#endif + __asm__ __volatile__("rsil a15, "__stringify(LOCKLEVEL)"\n\t" + "l32i %0, %1, 0 \n\t" + "bne %0, %2, 1f \n\t" + "s32i %3, %1, 0 \n\t" + "1: \n\t" + "wsr a15, ps \n\t" + "rsync \n\t" + : "=&a" (old) + : "a" (p), "a" (old), "r" (new) + : "a15", "memory"); + return old; } /* This function doesn't exist, so you'll get a linker error * if something tries to do an invalid cmpxchg(). */ @@ -106,36 +93,19 @@ static inline unsigned long __cmpxchg_local(volatile void *ptr, static inline unsigned long xchg_u32(volatile int * m, unsigned long val) { -#if XCHAL_HAVE_S32C1I - unsigned long tmp, result; - __asm__ __volatile__( - "1: l32i %1, %2, 0\n" - " mov %0, %3\n" - " wsr %1, scompare1\n" - " s32c1i %0, %2, 0\n" - " bne %0, %1, 1b\n" - : "=&a" (result), "=&a" (tmp) - : "a" (m), "a" (val) - : "memory" - ); - return result; -#else - unsigned long tmp; - __asm__ __volatile__( - " rsil a15, "__stringify(LOCKLEVEL)"\n" - " l32i %0, %1, 0\n" - " s32i %2, %1, 0\n" - " wsr a15, ps\n" - " rsync\n" - : "=&a" (tmp) - : "a" (m), "a" (val) - : "a15", "memory"); - return tmp; -#endif + unsigned long tmp; + __asm__ __volatile__("rsil a15, "__stringify(LOCKLEVEL)"\n\t" + "l32i %0, %1, 0 \n\t" + "s32i %2, %1, 0 \n\t" + "wsr a15, ps \n\t" + "rsync \n\t" + : "=&a" (tmp) + : "a" (m), "a" (val) + : "a15", "memory"); + return tmp; } -#define xchg(ptr,x) \ - ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) +#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) /* * This only works if the compiler isn't horribly bad at optimizing. diff --git a/trunk/arch/xtensa/include/asm/current.h b/trunk/arch/xtensa/include/asm/current.h index 47e46dcf5d49..8d1eb5d78649 100644 --- a/trunk/arch/xtensa/include/asm/current.h +++ b/trunk/arch/xtensa/include/asm/current.h @@ -30,7 +30,7 @@ static inline struct task_struct *get_current(void) #define GET_CURRENT(reg,sp) \ GET_THREAD_INFO(reg,sp); \ - l32i reg, reg, TI_TASK \ + l32i reg, reg, TI_TASK \ #endif diff --git a/trunk/arch/xtensa/include/asm/delay.h b/trunk/arch/xtensa/include/asm/delay.h index 61fc5faeb46c..58c0a4fd4003 100644 --- a/trunk/arch/xtensa/include/asm/delay.h +++ b/trunk/arch/xtensa/include/asm/delay.h @@ -19,9 +19,9 @@ extern unsigned long loops_per_jiffy; static inline void __delay(unsigned long loops) { - /* 2 cycles per loop. */ - __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 2, 1b" - : "=r" (loops) : "0" (loops)); + /* 2 cycles per loop. */ + __asm__ __volatile__ ("1: addi %0, %0, -2; bgeui %0, 2, 1b" + : "=r" (loops) : "0" (loops)); } static __inline__ u32 xtensa_get_ccount(void) @@ -46,3 +46,4 @@ static __inline__ void udelay (unsigned long usecs) } #endif + diff --git a/trunk/arch/xtensa/include/asm/dma-mapping.h b/trunk/arch/xtensa/include/asm/dma-mapping.h index 4acb5feba1fb..492c95790ad5 100644 --- a/trunk/arch/xtensa/include/asm/dma-mapping.h +++ b/trunk/arch/xtensa/include/asm/dma-mapping.h @@ -16,8 +16,6 @@ #include #include -#define DMA_ERROR_CODE (~(dma_addr_t)0x0) - /* * DMA-consistent mapping functions. */ @@ -100,8 +98,8 @@ dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size, } static inline void -dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, - size_t size, enum dma_data_direction direction) +dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size, + enum dma_data_direction direction) { consistent_sync((void *)bus_to_virt(dma_handle), size, direction); } diff --git a/trunk/arch/xtensa/include/asm/elf.h b/trunk/arch/xtensa/include/asm/elf.h index 264d5fa450d8..5293312bc6a4 100644 --- a/trunk/arch/xtensa/include/asm/elf.h +++ b/trunk/arch/xtensa/include/asm/elf.h @@ -168,11 +168,11 @@ extern void xtensa_elf_core_copy_regs (xtensa_gregset_t *, struct pt_regs *); */ #define ELF_PLAT_INIT(_r, load_addr) \ - do { _r->areg[0]=0; /*_r->areg[1]=0;*/ _r->areg[2]=0; _r->areg[3]=0; \ - _r->areg[4]=0; _r->areg[5]=0; _r->areg[6]=0; _r->areg[7]=0; \ - _r->areg[8]=0; _r->areg[9]=0; _r->areg[10]=0; _r->areg[11]=0; \ - _r->areg[12]=0; _r->areg[13]=0; _r->areg[14]=0; _r->areg[15]=0; \ - } while (0) + do { _r->areg[0]=0; /*_r->areg[1]=0;*/ _r->areg[2]=0; _r->areg[3]=0; \ + _r->areg[4]=0; _r->areg[5]=0; _r->areg[6]=0; _r->areg[7]=0; \ + _r->areg[8]=0; _r->areg[9]=0; _r->areg[10]=0; _r->areg[11]=0; \ + _r->areg[12]=0; _r->areg[13]=0; _r->areg[14]=0; _r->areg[15]=0; \ + } while (0) typedef struct { xtregs_opt_t opt; diff --git a/trunk/arch/xtensa/include/asm/highmem.h b/trunk/arch/xtensa/include/asm/highmem.h index 80be15124697..0a046ca5a687 100644 --- a/trunk/arch/xtensa/include/asm/highmem.h +++ b/trunk/arch/xtensa/include/asm/highmem.h @@ -14,3 +14,4 @@ extern void flush_cache_kmaps(void); #endif + diff --git a/trunk/arch/xtensa/include/asm/initialize_mmu.h b/trunk/arch/xtensa/include/asm/initialize_mmu.h deleted file mode 100644 index e1f8ba4061ed..000000000000 --- a/trunk/arch/xtensa/include/asm/initialize_mmu.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * arch/xtensa/include/asm/initialize_mmu.h - * - * Initializes MMU: - * - * For the new V3 MMU we remap the TLB from virtual == physical - * to the standard Linux mapping used in earlier MMU's. - * - * The the MMU we also support a new configuration register that - * specifies how the S32C1I instruction operates with the cache - * controller. - * - * This file is subject to the terms and conditions of the GNU General - * Public License. See the file "COPYING" in the main directory of - * this archive for more details. - * - * Copyright (C) 2008 - 2012 Tensilica, Inc. - * - * Marc Gauthier - * Pete Delaney - */ - -#ifndef _XTENSA_INITIALIZE_MMU_H -#define _XTENSA_INITIALIZE_MMU_H - -#ifdef __ASSEMBLY__ - -#define XTENSA_HWVERSION_RC_2009_0 230000 - - .macro initialize_mmu - -#if XCHAL_HAVE_S32C1I && (XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RC_2009_0) -/* - * We Have Atomic Operation Control (ATOMCTL) Register; Initialize it. - * For details see Documentation/xtensa/atomctl.txt - */ -#if XCHAL_DCACHE_IS_COHERENT - movi a3, 0x25 /* For SMP/MX -- internal for writeback, - * RCW otherwise - */ -#else - movi a3, 0x29 /* non-MX -- Most cores use Std Memory - * Controlers which usually can't use RCW - */ -#endif - wsr a3, atomctl -#endif /* XCHAL_HAVE_S32C1I && - * (XCHAL_HW_MIN_VERSION >= XTENSA_HWVERSION_RC_2009_0) - */ - - .endm - -#endif /*__ASSEMBLY__*/ - -#endif /* _XTENSA_INITIALIZE_MMU_H */ diff --git a/trunk/arch/xtensa/include/asm/mmu_context.h b/trunk/arch/xtensa/include/asm/mmu_context.h index d43525a286bb..feb10af96519 100644 --- a/trunk/arch/xtensa/include/asm/mmu_context.h +++ b/trunk/arch/xtensa/include/asm/mmu_context.h @@ -107,7 +107,7 @@ activate_mm(struct mm_struct *prev, struct mm_struct *next) static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, - struct task_struct *tsk) + struct task_struct *tsk) { unsigned long asid = asid_cache; diff --git a/trunk/arch/xtensa/include/asm/nommu_context.h b/trunk/arch/xtensa/include/asm/nommu_context.h index 3407cf7989b7..599e7a2e729d 100644 --- a/trunk/arch/xtensa/include/asm/nommu_context.h +++ b/trunk/arch/xtensa/include/asm/nommu_context.h @@ -2,7 +2,7 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) { } -static inline int init_new_context(struct task_struct *tsk,struct mm_struct *mm) +static inline int init_new_context(struct task_struct *tsk, struct mm_struct *mm) { return 0; } diff --git a/trunk/arch/xtensa/include/asm/page.h b/trunk/arch/xtensa/include/asm/page.h index 47f582333f6b..7a5591a71f85 100644 --- a/trunk/arch/xtensa/include/asm/page.h +++ b/trunk/arch/xtensa/include/asm/page.h @@ -29,19 +29,19 @@ * PAGE_SHIFT determines the page size */ -#define PAGE_SHIFT 12 -#define PAGE_SIZE (__XTENSA_UL_CONST(1) << PAGE_SHIFT) -#define PAGE_MASK (~(PAGE_SIZE-1)) +#define PAGE_SHIFT 12 +#define PAGE_SIZE (__XTENSA_UL_CONST(1) << PAGE_SHIFT) +#define PAGE_MASK (~(PAGE_SIZE-1)) #ifdef CONFIG_MMU -#define PAGE_OFFSET XCHAL_KSEG_CACHED_VADDR -#define MAX_MEM_PFN XCHAL_KSEG_SIZE +#define PAGE_OFFSET XCHAL_KSEG_CACHED_VADDR +#define MAX_MEM_PFN XCHAL_KSEG_SIZE #else -#define PAGE_OFFSET 0 -#define MAX_MEM_PFN (PLATFORM_DEFAULT_MEM_START + PLATFORM_DEFAULT_MEM_SIZE) +#define PAGE_OFFSET 0 +#define MAX_MEM_PFN (PLATFORM_DEFAULT_MEM_START + PLATFORM_DEFAULT_MEM_SIZE) #endif -#define PGTABLE_START 0x80000000 +#define PGTABLE_START 0x80000000 /* * Cache aliasing: @@ -161,9 +161,7 @@ extern void copy_user_page(void*, void*, unsigned long, struct page*); #define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) #define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) -#define pfn_valid(pfn) \ - ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr) - +#define pfn_valid(pfn) ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr) #ifdef CONFIG_DISCONTIGMEM # error CONFIG_DISCONTIGMEM not supported #endif diff --git a/trunk/arch/xtensa/include/asm/pci-bridge.h b/trunk/arch/xtensa/include/asm/pci-bridge.h index 0b68c76ec1e6..00fcbd7c534a 100644 --- a/trunk/arch/xtensa/include/asm/pci-bridge.h +++ b/trunk/arch/xtensa/include/asm/pci-bridge.h @@ -35,7 +35,7 @@ struct pci_space { struct pci_controller { int index; /* used for pci_controller_num */ struct pci_controller *next; - struct pci_bus *bus; + struct pci_bus *bus; void *arch_data; int first_busno; diff --git a/trunk/arch/xtensa/include/asm/pci.h b/trunk/arch/xtensa/include/asm/pci.h index 614be031a79a..05244f07dd31 100644 --- a/trunk/arch/xtensa/include/asm/pci.h +++ b/trunk/arch/xtensa/include/asm/pci.h @@ -53,7 +53,7 @@ struct pci_dev; /* Map a range of PCI memory or I/O space for a device into user space */ int pci_mmap_page_range(struct pci_dev *pdev, struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine); + enum pci_mmap_state mmap_state, int write_combine); /* Tell drivers/pci/proc.c that we have pci_mmap_page_range() */ #define HAVE_PCI_MMAP 1 diff --git a/trunk/arch/xtensa/include/asm/pgalloc.h b/trunk/arch/xtensa/include/asm/pgalloc.h index cf914c8c249a..40cf9bceda2c 100644 --- a/trunk/arch/xtensa/include/asm/pgalloc.h +++ b/trunk/arch/xtensa/include/asm/pgalloc.h @@ -42,7 +42,7 @@ static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd) extern struct kmem_cache *pgtable_cache; -static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, +static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { return kmem_cache_alloc(pgtable_cache, GFP_KERNEL|__GFP_REPEAT); diff --git a/trunk/arch/xtensa/include/asm/pgtable.h b/trunk/arch/xtensa/include/asm/pgtable.h index c90ea5bfa1b4..b03c043ce75b 100644 --- a/trunk/arch/xtensa/include/asm/pgtable.h +++ b/trunk/arch/xtensa/include/asm/pgtable.h @@ -284,7 +284,7 @@ struct vm_area_struct; static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, - pte_t *ptep) + pte_t *ptep) { pte_t pte = *ptep; if (!pte_young(pte)) @@ -304,8 +304,8 @@ ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { - pte_t pte = *ptep; - update_pte(ptep, pte_wrprotect(pte)); + pte_t pte = *ptep; + update_pte(ptep, pte_wrprotect(pte)); } /* to find an entry in a kernel page-table-directory */ @@ -399,7 +399,7 @@ extern void update_mmu_cache(struct vm_area_struct * vma, */ #define io_remap_pfn_range(vma,from,pfn,size,prot) \ - remap_pfn_range(vma, from, pfn, size, prot) + remap_pfn_range(vma, from, pfn, size, prot) typedef pte_t *pte_addr_t; diff --git a/trunk/arch/xtensa/include/asm/platform.h b/trunk/arch/xtensa/include/asm/platform.h index ec098b68fb9a..7d936e58e9be 100644 --- a/trunk/arch/xtensa/include/asm/platform.h +++ b/trunk/arch/xtensa/include/asm/platform.h @@ -75,3 +75,4 @@ extern int platform_pcibios_fixup (void); extern void platform_calibrate_ccount (void); #endif /* _XTENSA_PLATFORM_H */ + diff --git a/trunk/arch/xtensa/include/asm/processor.h b/trunk/arch/xtensa/include/asm/processor.h index e5fb6b0abdf4..2d630e7399ca 100644 --- a/trunk/arch/xtensa/include/asm/processor.h +++ b/trunk/arch/xtensa/include/asm/processor.h @@ -89,7 +89,7 @@ #define MAKE_PC_FROM_RA(ra,sp) (((ra) & 0x3fffffff) | ((sp) & 0xc0000000)) typedef struct { - unsigned long seg; + unsigned long seg; } mm_segment_t; struct thread_struct { @@ -145,10 +145,10 @@ struct thread_struct { * set_thread_state in signal.c depends on it. */ #define USER_PS_VALUE ((1 << PS_WOE_BIT) | \ - (1 << PS_CALLINC_SHIFT) | \ - (USER_RING << PS_RING_SHIFT) | \ - (1 << PS_UM_BIT) | \ - (1 << PS_EXCM_BIT)) + (1 << PS_CALLINC_SHIFT) | \ + (USER_RING << PS_RING_SHIFT) | \ + (1 << PS_UM_BIT) | \ + (1 << PS_EXCM_BIT)) /* Clearing a0 terminates the backtrace. */ #define start_thread(regs, new_pc, new_sp) \ diff --git a/trunk/arch/xtensa/include/asm/prom.h b/trunk/arch/xtensa/include/asm/prom.h deleted file mode 100644 index f3d7cd2c0de7..000000000000 --- a/trunk/arch/xtensa/include/asm/prom.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _XTENSA_ASM_PROM_H -#define _XTENSA_ASM_PROM_H - -#define HAVE_ARCH_DEVTREE_FIXUPS - -#endif /* _XTENSA_ASM_PROM_H */ diff --git a/trunk/arch/xtensa/include/asm/ptrace.h b/trunk/arch/xtensa/include/asm/ptrace.h index 58bf6fd3f913..da21c17f23aa 100644 --- a/trunk/arch/xtensa/include/asm/ptrace.h +++ b/trunk/arch/xtensa/include/asm/ptrace.h @@ -37,7 +37,7 @@ struct pt_regs { unsigned long windowstart; /* 52 */ unsigned long syscall; /* 56 */ unsigned long icountlevel; /* 60 */ - unsigned long scompare1; /* 64 */ + int reserved[1]; /* 64 */ /* Additional configurable registers that are used by the compiler. */ xtregs_opt_t xtregs_opt; @@ -55,7 +55,7 @@ struct pt_regs { # define arch_has_single_step() (1) # define task_pt_regs(tsk) ((struct pt_regs*) \ - (task_stack_page(tsk) + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4) - 1) + (task_stack_page(tsk) + KERNEL_STACK_SIZE - (XCHAL_NUM_AREGS-16)*4) - 1) # define user_mode(regs) (((regs)->ps & 0x00000020)!=0) # define instruction_pointer(regs) ((regs)->pc) diff --git a/trunk/arch/xtensa/include/asm/regs.h b/trunk/arch/xtensa/include/asm/regs.h index 76096a4e5b8d..8a8aa61ccc8d 100644 --- a/trunk/arch/xtensa/include/asm/regs.h +++ b/trunk/arch/xtensa/include/asm/regs.h @@ -52,10 +52,6 @@ #define EXCCAUSE_SPECULATION 7 #define EXCCAUSE_PRIVILEGED 8 #define EXCCAUSE_UNALIGNED 9 -#define EXCCAUSE_INSTR_DATA_ERROR 12 -#define EXCCAUSE_LOAD_STORE_DATA_ERROR 13 -#define EXCCAUSE_INSTR_ADDR_ERROR 14 -#define EXCCAUSE_LOAD_STORE_ADDR_ERROR 15 #define EXCCAUSE_ITLB_MISS 16 #define EXCCAUSE_ITLB_MULTIHIT 17 #define EXCCAUSE_ITLB_PRIVILEGE 18 @@ -109,3 +105,4 @@ #define DEBUGCAUSE_ICOUNT_BIT 0 /* ICOUNT would incr. to zero */ #endif /* _XTENSA_SPECREG_H */ + diff --git a/trunk/arch/xtensa/include/asm/spinlock.h b/trunk/arch/xtensa/include/asm/spinlock.h index 03975906b36f..8ff23649581b 100644 --- a/trunk/arch/xtensa/include/asm/spinlock.h +++ b/trunk/arch/xtensa/include/asm/spinlock.h @@ -11,192 +11,6 @@ #ifndef _XTENSA_SPINLOCK_H #define _XTENSA_SPINLOCK_H -/* - * spinlock - * - * There is at most one owner of a spinlock. There are not different - * types of spinlock owners like there are for rwlocks (see below). - * - * When trying to obtain a spinlock, the function "spins" forever, or busy- - * waits, until the lock is obtained. When spinning, presumably some other - * owner will soon give up the spinlock making it available to others. Use - * the trylock functions to avoid spinning forever. - * - * possible values: - * - * 0 nobody owns the spinlock - * 1 somebody owns the spinlock - */ - -#define __raw_spin_is_locked(x) ((x)->slock != 0) -#define __raw_spin_unlock_wait(lock) \ - do { while (__raw_spin_is_locked(lock)) cpu_relax(); } while (0) - -#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) - -static inline void __raw_spin_lock(raw_spinlock_t *lock) -{ - unsigned long tmp; - - __asm__ __volatile__( - " movi %0, 0\n" - " wsr %0, scompare1\n" - "1: movi %0, 1\n" - " s32c1i %0, %1, 0\n" - " bnez %0, 1b\n" - : "=&a" (tmp) - : "a" (&lock->slock) - : "memory"); -} - -/* Returns 1 if the lock is obtained, 0 otherwise. */ - -static inline int __raw_spin_trylock(raw_spinlock_t *lock) -{ - unsigned long tmp; - - __asm__ __volatile__( - " movi %0, 0\n" - " wsr %0, scompare1\n" - " movi %0, 1\n" - " s32c1i %0, %1, 0\n" - : "=&a" (tmp) - : "a" (&lock->slock) - : "memory"); - - return tmp == 0 ? 1 : 0; -} - -static inline void __raw_spin_unlock(raw_spinlock_t *lock) -{ - unsigned long tmp; - - __asm__ __volatile__( - " movi %0, 0\n" - " s32ri %0, %1, 0\n" - : "=&a" (tmp) - : "a" (&lock->slock) - : "memory"); -} - -/* - * rwlock - * - * Read-write locks are really a more flexible spinlock. They allow - * multiple readers but only one writer. Write ownership is exclusive - * (i.e., all other readers and writers are blocked from ownership while - * there is a write owner). These rwlocks are unfair to writers. Writers - * can be starved for an indefinite time by readers. - * - * possible values: - * - * 0 nobody owns the rwlock - * >0 one or more readers own the rwlock - * (the positive value is the actual number of readers) - * 0x80000000 one writer owns the rwlock, no other writers, no readers - */ - -#define __raw_write_can_lock(x) ((x)->lock == 0) - -static inline void __raw_write_lock(raw_rwlock_t *rw) -{ - unsigned long tmp; - - __asm__ __volatile__( - " movi %0, 0\n" - " wsr %0, scompare1\n" - "1: movi %0, 1\n" - " slli %0, %0, 31\n" - " s32c1i %0, %1, 0\n" - " bnez %0, 1b\n" - : "=&a" (tmp) - : "a" (&rw->lock) - : "memory"); -} - -/* Returns 1 if the lock is obtained, 0 otherwise. */ - -static inline int __raw_write_trylock(raw_rwlock_t *rw) -{ - unsigned long tmp; - - __asm__ __volatile__( - " movi %0, 0\n" - " wsr %0, scompare1\n" - " movi %0, 1\n" - " slli %0, %0, 31\n" - " s32c1i %0, %1, 0\n" - : "=&a" (tmp) - : "a" (&rw->lock) - : "memory"); - - return tmp == 0 ? 1 : 0; -} - -static inline void __raw_write_unlock(raw_rwlock_t *rw) -{ - unsigned long tmp; - - __asm__ __volatile__( - " movi %0, 0\n" - " s32ri %0, %1, 0\n" - : "=&a" (tmp) - : "a" (&rw->lock) - : "memory"); -} - -static inline void __raw_read_lock(raw_rwlock_t *rw) -{ - unsigned long tmp; - unsigned long result; - - __asm__ __volatile__( - "1: l32i %1, %2, 0\n" - " bltz %1, 1b\n" - " wsr %1, scompare1\n" - " addi %0, %1, 1\n" - " s32c1i %0, %2, 0\n" - " bne %0, %1, 1b\n" - : "=&a" (result), "=&a" (tmp) - : "a" (&rw->lock) - : "memory"); -} - -/* Returns 1 if the lock is obtained, 0 otherwise. */ - -static inline int __raw_read_trylock(raw_rwlock_t *rw) -{ - unsigned long result; - unsigned long tmp; - - __asm__ __volatile__( - " l32i %1, %2, 0\n" - " addi %0, %1, 1\n" - " bltz %0, 1f\n" - " wsr %1, scompare1\n" - " s32c1i %0, %2, 0\n" - " sub %0, %0, %1\n" - "1:\n" - : "=&a" (result), "=&a" (tmp) - : "a" (&rw->lock) - : "memory"); - - return result == 0; -} - -static inline void __raw_read_unlock(raw_rwlock_t *rw) -{ - unsigned long tmp1, tmp2; - - __asm__ __volatile__( - "1: l32i %1, %2, 0\n" - " addi %0, %1, -1\n" - " wsr %1, scompare1\n" - " s32c1i %0, %2, 0\n" - " bne %0, %1, 1b\n" - : "=&a" (tmp1), "=&a" (tmp2) - : "a" (&rw->lock) - : "memory"); -} +#include #endif /* _XTENSA_SPINLOCK_H */ diff --git a/trunk/arch/xtensa/include/asm/syscall.h b/trunk/arch/xtensa/include/asm/syscall.h index 8d5e47fad095..b00c928d4cce 100644 --- a/trunk/arch/xtensa/include/asm/syscall.h +++ b/trunk/arch/xtensa/include/asm/syscall.h @@ -25,10 +25,9 @@ asmlinkage long xtensa_fadvise64_64(int, int, /* Should probably move to linux/syscalls.h */ struct pollfd; asmlinkage long sys_pselect6(int n, fd_set __user *inp, fd_set __user *outp, - fd_set __user *exp, struct timespec __user *tsp, - void __user *sig); + fd_set __user *exp, struct timespec __user *tsp, void __user *sig); asmlinkage long sys_ppoll(struct pollfd __user *ufds, unsigned int nfds, - struct timespec __user *tsp, - const sigset_t __user *sigmask, - size_t sigsetsize); -asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize); + struct timespec __user *tsp, const sigset_t __user *sigmask, + size_t sigsetsize); +asmlinkage long sys_rt_sigsuspend(sigset_t __user *unewset, + size_t sigsetsize); diff --git a/trunk/arch/xtensa/include/asm/traps.h b/trunk/arch/xtensa/include/asm/traps.h deleted file mode 100644 index 54f70440185e..000000000000 --- a/trunk/arch/xtensa/include/asm/traps.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * arch/xtensa/include/asm/traps.h - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 Tensilica Inc. - */ -#ifndef _XTENSA_TRAPS_H -#define _XTENSA_TRAPS_H - -#include - -/* - * handler must be either of the following: - * void (*)(struct pt_regs *regs); - * void (*)(struct pt_regs *regs, unsigned long exccause); - */ -extern void * __init trap_set_handler(int cause, void *handler); -extern void do_unhandled(struct pt_regs *regs, unsigned long exccause); - -#endif /* _XTENSA_TRAPS_H */ diff --git a/trunk/arch/xtensa/include/asm/uaccess.h b/trunk/arch/xtensa/include/asm/uaccess.h index fd686dc45d1a..6e4bb3b791ab 100644 --- a/trunk/arch/xtensa/include/asm/uaccess.h +++ b/trunk/arch/xtensa/include/asm/uaccess.h @@ -180,8 +180,7 @@ #define segment_eq(a,b) ((a).seg == (b).seg) #define __kernel_ok (segment_eq(get_fs(), KERNEL_DS)) -#define __user_ok(addr,size) \ - (((size) <= TASK_SIZE)&&((addr) <= TASK_SIZE-(size))) +#define __user_ok(addr,size) (((size) <= TASK_SIZE)&&((addr) <= TASK_SIZE-(size))) #define __access_ok(addr,size) (__kernel_ok || __user_ok((addr),(size))) #define access_ok(type,addr,size) __access_ok((unsigned long)(addr),(size)) @@ -235,10 +234,10 @@ do { \ int __cb; \ retval = 0; \ switch (size) { \ - case 1: __put_user_asm(x,ptr,retval,1,"s8i",__cb); break; \ - case 2: __put_user_asm(x,ptr,retval,2,"s16i",__cb); break; \ - case 4: __put_user_asm(x,ptr,retval,4,"s32i",__cb); break; \ - case 8: { \ + case 1: __put_user_asm(x,ptr,retval,1,"s8i",__cb); break; \ + case 2: __put_user_asm(x,ptr,retval,2,"s16i",__cb); break; \ + case 4: __put_user_asm(x,ptr,retval,4,"s32i",__cb); break; \ + case 8: { \ __typeof__(*ptr) __v64 = x; \ retval = __copy_to_user(ptr,&__v64,8); \ break; \ @@ -292,7 +291,7 @@ do { \ * __check_align_* macros still work. */ #define __put_user_asm(x, addr, err, align, insn, cb) \ -__asm__ __volatile__( \ + __asm__ __volatile__( \ __check_align_##align \ "1: "insn" %2, %3, 0 \n" \ "2: \n" \ @@ -302,8 +301,8 @@ __asm__ __volatile__( \ " .long 2b \n" \ "5: \n" \ " l32r %1, 4b \n" \ - " movi %0, %4 \n" \ - " jx %1 \n" \ + " movi %0, %4 \n" \ + " jx %1 \n" \ " .previous \n" \ " .section __ex_table,\"a\" \n" \ " .long 1b, 5b \n" \ @@ -335,13 +334,13 @@ extern long __get_user_bad(void); do { \ int __cb; \ retval = 0; \ - switch (size) { \ - case 1: __get_user_asm(x,ptr,retval,1,"l8ui",__cb); break; \ - case 2: __get_user_asm(x,ptr,retval,2,"l16ui",__cb); break; \ - case 4: __get_user_asm(x,ptr,retval,4,"l32i",__cb); break; \ - case 8: retval = __copy_from_user(&x,ptr,8); break; \ - default: (x) = __get_user_bad(); \ - } \ + switch (size) { \ + case 1: __get_user_asm(x,ptr,retval,1,"l8ui",__cb); break; \ + case 2: __get_user_asm(x,ptr,retval,2,"l16ui",__cb); break; \ + case 4: __get_user_asm(x,ptr,retval,4,"l32i",__cb); break; \ + case 8: retval = __copy_from_user(&x,ptr,8); break; \ + default: (x) = __get_user_bad(); \ + } \ } while (0) @@ -350,7 +349,7 @@ do { \ * __check_align_* macros still work. */ #define __get_user_asm(x, addr, err, align, insn, cb) \ -__asm__ __volatile__( \ + __asm__ __volatile__( \ __check_align_##align \ "1: "insn" %2, %3, 0 \n" \ "2: \n" \ @@ -361,8 +360,8 @@ __asm__ __volatile__( \ "5: \n" \ " l32r %1, 4b \n" \ " movi %2, 0 \n" \ - " movi %0, %4 \n" \ - " jx %1 \n" \ + " movi %0, %4 \n" \ + " jx %1 \n" \ " .previous \n" \ " .section __ex_table,\"a\" \n" \ " .long 1b, 5b \n" \ @@ -422,10 +421,8 @@ __generic_copy_from_user(void *to, const void *from, unsigned long n) #define copy_to_user(to,from,n) __generic_copy_to_user((to),(from),(n)) #define copy_from_user(to,from,n) __generic_copy_from_user((to),(from),(n)) -#define __copy_to_user(to,from,n) \ - __generic_copy_to_user_nocheck((to),(from),(n)) -#define __copy_from_user(to,from,n) \ - __generic_copy_from_user_nocheck((to),(from),(n)) +#define __copy_to_user(to,from,n) __generic_copy_to_user_nocheck((to),(from),(n)) +#define __copy_from_user(to,from,n) __generic_copy_from_user_nocheck((to),(from),(n)) #define __copy_to_user_inatomic __copy_to_user #define __copy_from_user_inatomic __copy_from_user diff --git a/trunk/arch/xtensa/kernel/Makefile b/trunk/arch/xtensa/kernel/Makefile index c3a59d992ac0..f36cef5a62ff 100644 --- a/trunk/arch/xtensa/kernel/Makefile +++ b/trunk/arch/xtensa/kernel/Makefile @@ -23,13 +23,13 @@ obj-$(CONFIG_MODULES) += xtensa_ksyms.o module.o # # Replicate rules in scripts/Makefile.build -sed-y = -e 's/\*(\(\.[a-z]*it\|\.ref\|\)\.text)/*(\1.literal \1.text)/g' \ - -e 's/\.text\.unlikely/.literal.unlikely .text.unlikely/g' \ +sed-y = -e 's/\*(\(\.[a-z]*it\|\.ref\|\)\.text)/*(\1.literal \1.text)/g' \ + -e 's/\.text\.unlikely/.literal.unlikely .text.unlikely/g' \ -e 's/\*(\(\.text\.[a-z]*\))/*(\1.literal \1)/g' quiet_cmd__cpp_lds_S = LDS $@ -cmd__cpp_lds_S = $(CPP) $(cpp_flags) -P -C -Uxtensa -D__ASSEMBLY__ $< \ - | sed $(sed-y) >$@ + cmd__cpp_lds_S = $(CPP) $(cpp_flags) -P -C -Uxtensa -D__ASSEMBLY__ $< \ + | sed $(sed-y) >$@ $(obj)/vmlinux.lds: $(src)/vmlinux.lds.S FORCE $(call if_changed_dep,_cpp_lds_S) diff --git a/trunk/arch/xtensa/kernel/align.S b/trunk/arch/xtensa/kernel/align.S index aa2e87b8566a..934ae58e2c79 100644 --- a/trunk/arch/xtensa/kernel/align.S +++ b/trunk/arch/xtensa/kernel/align.S @@ -442,7 +442,7 @@ ENTRY(fast_unaligned) mov a1, a2 rsr a0, ps - bbsi.l a2, PS_UM_BIT, 1f # jump if user mode + bbsi.l a2, PS_UM_BIT, 1f # jump if user mode movi a0, _kernel_exception jx a0 @@ -450,6 +450,6 @@ ENTRY(fast_unaligned) 1: movi a0, _user_exception jx a0 -ENDPROC(fast_unaligned) #endif /* XCHAL_UNALIGNED_LOAD_EXCEPTION || XCHAL_UNALIGNED_STORE_EXCEPTION */ + diff --git a/trunk/arch/xtensa/kernel/asm-offsets.c b/trunk/arch/xtensa/kernel/asm-offsets.c index 0701fad170db..7dc3f9157185 100644 --- a/trunk/arch/xtensa/kernel/asm-offsets.c +++ b/trunk/arch/xtensa/kernel/asm-offsets.c @@ -41,7 +41,6 @@ int main(void) DEFINE(PT_SAR, offsetof (struct pt_regs, sar)); DEFINE(PT_ICOUNTLEVEL, offsetof (struct pt_regs, icountlevel)); DEFINE(PT_SYSCALL, offsetof (struct pt_regs, syscall)); - DEFINE(PT_SCOMPARE1, offsetof(struct pt_regs, scompare1)); DEFINE(PT_AREG, offsetof (struct pt_regs, areg[0])); DEFINE(PT_AREG0, offsetof (struct pt_regs, areg[0])); DEFINE(PT_AREG1, offsetof (struct pt_regs, areg[1])); @@ -92,8 +91,7 @@ int main(void) #endif DEFINE(THREAD_XTREGS_USER, offsetof (struct thread_info, xtregs_user)); DEFINE(XTREGS_USER_SIZE, sizeof(xtregs_user_t)); - DEFINE(THREAD_CURRENT_DS, offsetof (struct task_struct, \ - thread.current_ds)); + DEFINE(THREAD_CURRENT_DS, offsetof (struct task_struct, thread.current_ds)); /* struct mm_struct */ DEFINE(MM_USERS, offsetof(struct mm_struct, mm_users)); @@ -110,3 +108,4 @@ int main(void) return 0; } + diff --git a/trunk/arch/xtensa/kernel/coprocessor.S b/trunk/arch/xtensa/kernel/coprocessor.S index 647657484866..54c3be313bfa 100644 --- a/trunk/arch/xtensa/kernel/coprocessor.S +++ b/trunk/arch/xtensa/kernel/coprocessor.S @@ -43,13 +43,10 @@ /* IO protection is currently unsupported. */ ENTRY(fast_io_protect) - wsr a0, excsave1 movi a0, unrecoverable_exception callx0 a0 -ENDPROC(fast_io_protect) - #if XTENSA_HAVE_COPROCESSORS /* @@ -142,7 +139,6 @@ ENDPROC(fast_io_protect) */ ENTRY(coprocessor_save) - entry a1, 32 s32i a0, a1, 0 movi a0, .Lsave_cp_regs_jump_table @@ -154,10 +150,7 @@ ENTRY(coprocessor_save) 1: l32i a0, a1, 0 retw -ENDPROC(coprocessor_save) - ENTRY(coprocessor_load) - entry a1, 32 s32i a0, a1, 0 movi a0, .Lload_cp_regs_jump_table @@ -169,10 +162,8 @@ ENTRY(coprocessor_load) 1: l32i a0, a1, 0 retw -ENDPROC(coprocessor_load) - /* - * coprocessor_flush(struct task_info*, index) + * coprocessor_flush(struct task_info*, index) * a2 a3 * coprocessor_restore(struct task_info*, index) * a2 a3 @@ -187,7 +178,6 @@ ENDPROC(coprocessor_load) ENTRY(coprocessor_flush) - entry a1, 32 s32i a0, a1, 0 movi a0, .Lsave_cp_regs_jump_table @@ -201,8 +191,6 @@ ENTRY(coprocessor_flush) 1: l32i a0, a1, 0 retw -ENDPROC(coprocessor_flush) - ENTRY(coprocessor_restore) entry a1, 32 s32i a0, a1, 0 @@ -217,8 +205,6 @@ ENTRY(coprocessor_restore) 1: l32i a0, a1, 0 retw -ENDPROC(coprocessor_restore) - /* * Entry condition: * @@ -234,12 +220,10 @@ ENDPROC(coprocessor_restore) */ ENTRY(fast_coprocessor_double) - wsr a0, excsave1 movi a0, unrecoverable_exception callx0 a0 -ENDPROC(fast_coprocessor_double) ENTRY(fast_coprocessor) @@ -343,14 +327,9 @@ ENTRY(fast_coprocessor) rfe -ENDPROC(fast_coprocessor) - .data - ENTRY(coprocessor_owner) - .fill XCHAL_CP_MAX, 4, 0 -END(coprocessor_owner) - #endif /* XTENSA_HAVE_COPROCESSORS */ + diff --git a/trunk/arch/xtensa/kernel/entry.S b/trunk/arch/xtensa/kernel/entry.S index 3777fec85e7c..90bfc1dbc13d 100644 --- a/trunk/arch/xtensa/kernel/entry.S +++ b/trunk/arch/xtensa/kernel/entry.S @@ -219,7 +219,6 @@ _user_exception: j common_exception -ENDPROC(user_exception) /* * First-level exit handler for kernel exceptions @@ -372,13 +371,6 @@ common_exception: s32i a2, a1, PT_LBEG s32i a3, a1, PT_LEND - /* Save SCOMPARE1 */ - -#if XCHAL_HAVE_S32C1I - rsr a2, scompare1 - s32i a2, a1, PT_SCOMPARE1 -#endif - /* Save optional registers. */ save_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT @@ -440,12 +432,6 @@ common_exception_return: load_xtregs_opt a1 a2 a4 a5 a6 a7 PT_XTREGS_OPT - /* Restore SCOMPARE1 */ - -#if XCHAL_HAVE_S32C1I - l32i a2, a1, PT_SCOMPARE1 - wsr a2, scompare1 -#endif wsr a3, ps /* disable interrupts */ _bbci.l a3, PS_UM_BIT, kernel_exception_exit @@ -655,8 +641,6 @@ common_exception_exit: l32i a1, a1, PT_AREG1 rfde -ENDPROC(kernel_exception) - /* * Debug exception handler. * @@ -717,7 +701,6 @@ ENTRY(debug_exception) /* Debug exception while in exception mode. */ 1: j 1b // FIXME!! -ENDPROC(debug_exception) /* * We get here in case of an unrecoverable exception. @@ -768,7 +751,6 @@ ENTRY(unrecoverable_exception) 1: j 1b -ENDPROC(unrecoverable_exception) /* -------------------------- FAST EXCEPTION HANDLERS ----------------------- */ @@ -874,7 +856,7 @@ ENTRY(fast_alloca) _bnei a0, 1, 1f # no 'movsp a1, ax': jump - /* Move the save area. This implies the use of the L32E + /* Move the save area. This implies the use of the L32E * and S32E instructions, because this move must be done with * the user's PS.RING privilege levels, not with ring 0 * (kernel's) privileges currently active with PS.EXCM @@ -947,7 +929,6 @@ ENTRY(fast_alloca) l32i a2, a2, PT_AREG2 rfe -ENDPROC(fast_alloca) /* * fast system calls. @@ -985,8 +966,6 @@ ENTRY(fast_syscall_kernel) j kernel_exception -ENDPROC(fast_syscall_kernel) - ENTRY(fast_syscall_user) /* Skip syscall. */ @@ -1004,21 +983,19 @@ ENTRY(fast_syscall_user) j user_exception -ENDPROC(fast_syscall_user) - ENTRY(fast_syscall_unrecoverable) - /* Restore all states. */ + /* Restore all states. */ + + l32i a0, a2, PT_AREG0 # restore a0 + xsr a2, depc # restore a2, depc + rsr a3, excsave1 - l32i a0, a2, PT_AREG0 # restore a0 - xsr a2, depc # restore a2, depc - rsr a3, excsave1 + wsr a0, excsave1 + movi a0, unrecoverable_exception + callx0 a0 - wsr a0, excsave1 - movi a0, unrecoverable_exception - callx0 a0 -ENDPROC(fast_syscall_unrecoverable) /* * sysxtensa syscall handler @@ -1124,7 +1101,7 @@ CATCH movi a2, -EINVAL rfe -ENDPROC(fast_syscall_xtensa) + /* fast_syscall_spill_registers. @@ -1183,8 +1160,6 @@ ENTRY(fast_syscall_spill_registers) movi a2, 0 rfe -ENDPROC(fast_syscall_spill_registers) - /* Fixup handler. * * We get here if the spill routine causes an exception, e.g. tlb miss. @@ -1253,9 +1228,9 @@ fast_syscall_spill_registers_fixup: movi a3, exc_table rsr a0, exccause - addx4 a0, a0, a3 # find entry in table - l32i a0, a0, EXC_TABLE_FAST_USER # load handler - jx a0 + addx4 a0, a0, a3 # find entry in table + l32i a0, a0, EXC_TABLE_FAST_USER # load handler + jx a0 fast_syscall_spill_registers_fixup_return: @@ -1457,7 +1432,7 @@ ENTRY(_spill_registers) rsr a0, ps _bbci.l a0, PS_UM_BIT, 1f - /* User space: Setup a dummy frame and kill application. + /* User space: Setup a dummy frame and kill application. * Note: We assume EXC_TABLE_KSTK contains a valid stack pointer. */ @@ -1489,8 +1464,6 @@ ENTRY(_spill_registers) callx0 a0 # should not return 1: j 1b -ENDPROC(_spill_registers) - #ifdef CONFIG_MMU /* * We should never get here. Bail out! @@ -1502,8 +1475,6 @@ ENTRY(fast_second_level_miss_double_kernel) callx0 a0 # should not return 1: j 1b -ENDPROC(fast_second_level_miss_double_kernel) - /* First-level entry handler for user, kernel, and double 2nd-level * TLB miss exceptions. Note that for now, user and kernel miss * exceptions share the same entry point and are handled identically. @@ -1711,7 +1682,6 @@ ENTRY(fast_second_level_miss) j _kernel_exception 1: j _user_exception -ENDPROC(fast_second_level_miss) /* * StoreProhibitedException @@ -1807,9 +1777,6 @@ ENTRY(fast_store_prohibited) bbsi.l a2, PS_UM_BIT, 1f j _kernel_exception 1: j _user_exception - -ENDPROC(fast_store_prohibited) - #endif /* CONFIG_MMU */ /* @@ -1820,7 +1787,6 @@ ENDPROC(fast_store_prohibited) */ ENTRY(system_call) - entry a1, 32 /* regs->syscall = regs->areg[2] */ @@ -1865,8 +1831,6 @@ ENTRY(system_call) callx4 a4 retw -ENDPROC(system_call) - /* * Task switch. @@ -1935,7 +1899,6 @@ ENTRY(_switch_to) retw -ENDPROC(_switch_to) ENTRY(ret_from_fork) @@ -1951,8 +1914,6 @@ ENTRY(ret_from_fork) j common_exception_return -ENDPROC(ret_from_fork) - /* * Kernel thread creation helper * On entry, set up by copy_thread: a2 = thread_fn, a3 = thread_fn arg diff --git a/trunk/arch/xtensa/kernel/head.S b/trunk/arch/xtensa/kernel/head.S index 91d9095284de..bdc50788f35e 100644 --- a/trunk/arch/xtensa/kernel/head.S +++ b/trunk/arch/xtensa/kernel/head.S @@ -18,7 +18,6 @@ #include #include #include -#include #include #include @@ -48,19 +47,16 @@ */ __HEAD -ENTRY(_start) - - _j 2f + .globl _start +_start: _j 2f .align 4 1: .word _startup 2: l32r a0, 1b jx a0 -ENDPROC(_start) - .section .init.text, "ax" - -ENTRY(_startup) + .align 4 +_startup: /* Disable interrupts and exceptions. */ @@ -111,7 +107,7 @@ ENTRY(_startup) /* Disable all timers. */ .set _index, 0 - .rept XCHAL_NUM_TIMERS + .rept XCHAL_NUM_TIMERS - 1 wsr a0, SREG_CCOMPARE + _index .set _index, _index + 1 .endr @@ -124,7 +120,7 @@ ENTRY(_startup) /* Disable coprocessors. */ -#if XCHAL_HAVE_CP +#if XCHAL_CP_NUM > 0 wsr a0, cpenable #endif @@ -156,8 +152,6 @@ ENTRY(_startup) isync - initialize_mmu - /* Unpack data sections * * The linker script used to build the Linux kernel image @@ -236,7 +230,6 @@ ENTRY(_startup) should_never_return: j should_never_return -ENDPROC(_startup) /* * BSS section @@ -246,8 +239,6 @@ __PAGE_ALIGNED_BSS #ifdef CONFIG_MMU ENTRY(swapper_pg_dir) .fill PAGE_SIZE, 1, 0 -END(swapper_pg_dir) #endif ENTRY(empty_zero_page) .fill PAGE_SIZE, 1, 0 -END(empty_zero_page) diff --git a/trunk/arch/xtensa/kernel/irq.c b/trunk/arch/xtensa/kernel/irq.c index 6f4f9749cff7..a6ce3e563739 100644 --- a/trunk/arch/xtensa/kernel/irq.c +++ b/trunk/arch/xtensa/kernel/irq.c @@ -18,8 +18,6 @@ #include #include #include -#include -#include #include #include @@ -28,22 +26,19 @@ static unsigned int cached_irq_mask; atomic_t irq_err_count; -static struct irq_domain *root_domain; - /* * do_IRQ handles all normal device IRQ's (the special * SMP cross-CPU interrupts have their own specific * handlers). */ -asmlinkage void do_IRQ(int hwirq, struct pt_regs *regs) +asmlinkage void do_IRQ(int irq, struct pt_regs *regs) { struct pt_regs *old_regs = set_irq_regs(regs); - int irq = irq_find_mapping(root_domain, hwirq); - if (hwirq >= NR_IRQS) { + if (irq >= NR_IRQS) { printk(KERN_EMERG "%s: cannot handle IRQ %d\n", - __func__, hwirq); + __func__, irq); } irq_enter(); @@ -76,39 +71,40 @@ int arch_show_interrupts(struct seq_file *p, int prec) static void xtensa_irq_mask(struct irq_data *d) { - cached_irq_mask &= ~(1 << d->hwirq); + cached_irq_mask &= ~(1 << d->irq); set_sr (cached_irq_mask, intenable); } static void xtensa_irq_unmask(struct irq_data *d) { - cached_irq_mask |= 1 << d->hwirq; + cached_irq_mask |= 1 << d->irq; set_sr (cached_irq_mask, intenable); } static void xtensa_irq_enable(struct irq_data *d) { - variant_irq_enable(d->hwirq); + variant_irq_enable(d->irq); xtensa_irq_unmask(d); } static void xtensa_irq_disable(struct irq_data *d) { xtensa_irq_mask(d); - variant_irq_disable(d->hwirq); + variant_irq_disable(d->irq); } static void xtensa_irq_ack(struct irq_data *d) { - set_sr(1 << d->hwirq, intclear); + set_sr(1 << d->irq, intclear); } static int xtensa_irq_retrigger(struct irq_data *d) { - set_sr(1 << d->hwirq, intset); + set_sr (1 << d->irq, INTSET); return 1; } + static struct irq_chip xtensa_irq_chip = { .name = "xtensa", .irq_enable = xtensa_irq_enable, @@ -119,99 +115,37 @@ static struct irq_chip xtensa_irq_chip = { .irq_retrigger = xtensa_irq_retrigger, }; -static int xtensa_irq_map(struct irq_domain *d, unsigned int irq, - irq_hw_number_t hw) +void __init init_IRQ(void) { - u32 mask = 1 << hw; - - if (mask & XCHAL_INTTYPE_MASK_SOFTWARE) { - irq_set_chip_and_handler_name(irq, &xtensa_irq_chip, - handle_simple_irq, "level"); - irq_set_status_flags(irq, IRQ_LEVEL); - } else if (mask & XCHAL_INTTYPE_MASK_EXTERN_EDGE) { - irq_set_chip_and_handler_name(irq, &xtensa_irq_chip, - handle_edge_irq, "edge"); - irq_clear_status_flags(irq, IRQ_LEVEL); - } else if (mask & XCHAL_INTTYPE_MASK_EXTERN_LEVEL) { - irq_set_chip_and_handler_name(irq, &xtensa_irq_chip, - handle_level_irq, "level"); - irq_set_status_flags(irq, IRQ_LEVEL); - } else if (mask & XCHAL_INTTYPE_MASK_TIMER) { - irq_set_chip_and_handler_name(irq, &xtensa_irq_chip, - handle_edge_irq, "edge"); - irq_clear_status_flags(irq, IRQ_LEVEL); - } else {/* XCHAL_INTTYPE_MASK_WRITE_ERROR */ - /* XCHAL_INTTYPE_MASK_NMI */ - - irq_set_chip_and_handler_name(irq, &xtensa_irq_chip, - handle_level_irq, "level"); - irq_set_status_flags(irq, IRQ_LEVEL); - } - return 0; -} + int index; -static unsigned map_ext_irq(unsigned ext_irq) -{ - unsigned mask = XCHAL_INTTYPE_MASK_EXTERN_EDGE | - XCHAL_INTTYPE_MASK_EXTERN_LEVEL; - unsigned i; + for (index = 0; index < XTENSA_NR_IRQS; index++) { + int mask = 1 << index; - for (i = 0; mask; ++i, mask >>= 1) { - if ((mask & 1) && ext_irq-- == 0) - return i; - } - return XCHAL_NUM_INTERRUPTS; -} + if (mask & XCHAL_INTTYPE_MASK_SOFTWARE) + irq_set_chip_and_handler(index, &xtensa_irq_chip, + handle_simple_irq); -/* - * Device Tree IRQ specifier translation function which works with one or - * two cell bindings. First cell value maps directly to the hwirq number. - * Second cell if present specifies whether hwirq number is external (1) or - * internal (0). - */ -int xtensa_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr, - const u32 *intspec, unsigned int intsize, - unsigned long *out_hwirq, unsigned int *out_type) -{ - if (WARN_ON(intsize < 1 || intsize > 2)) - return -EINVAL; - if (intsize == 2 && intspec[1] == 1) { - unsigned int_irq = map_ext_irq(intspec[0]); - if (int_irq < XCHAL_NUM_INTERRUPTS) - *out_hwirq = int_irq; - else - return -EINVAL; - } else { - *out_hwirq = intspec[0]; - } - *out_type = IRQ_TYPE_NONE; - return 0; -} + else if (mask & XCHAL_INTTYPE_MASK_EXTERN_EDGE) + irq_set_chip_and_handler(index, &xtensa_irq_chip, + handle_edge_irq); -static const struct irq_domain_ops xtensa_irq_domain_ops = { - .xlate = xtensa_irq_domain_xlate, - .map = xtensa_irq_map, -}; + else if (mask & XCHAL_INTTYPE_MASK_EXTERN_LEVEL) + irq_set_chip_and_handler(index, &xtensa_irq_chip, + handle_level_irq); -void __init init_IRQ(void) -{ - struct device_node *intc = NULL; + else if (mask & XCHAL_INTTYPE_MASK_TIMER) + irq_set_chip_and_handler(index, &xtensa_irq_chip, + handle_edge_irq); + + else /* XCHAL_INTTYPE_MASK_WRITE_ERROR */ + /* XCHAL_INTTYPE_MASK_NMI */ + + irq_set_chip_and_handler(index, &xtensa_irq_chip, + handle_level_irq); + } cached_irq_mask = 0; - set_sr(~0, intclear); - -#ifdef CONFIG_OF - /* The interrupt controller device node is mandatory */ - intc = of_find_compatible_node(NULL, NULL, "xtensa,pic"); - BUG_ON(!intc); - - root_domain = irq_domain_add_linear(intc, NR_IRQS, - &xtensa_irq_domain_ops, NULL); -#else - root_domain = irq_domain_add_legacy(intc, NR_IRQS, 0, 0, - &xtensa_irq_domain_ops, NULL); -#endif - irq_set_default_host(root_domain); variant_init_irq(); } diff --git a/trunk/arch/xtensa/kernel/module.c b/trunk/arch/xtensa/kernel/module.c index b715237bae61..451dda928c93 100644 --- a/trunk/arch/xtensa/kernel/module.c +++ b/trunk/arch/xtensa/kernel/module.c @@ -53,7 +53,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, struct module *mod) { unsigned int i; - Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr; + Elf32_Rela *rela = (void *)sechdrs[relsec].sh_addr; Elf32_Sym *sym; unsigned char *location; uint32_t value; diff --git a/trunk/arch/xtensa/kernel/platform.c b/trunk/arch/xtensa/kernel/platform.c index 44bf21c3769a..97230e46cbe7 100644 --- a/trunk/arch/xtensa/kernel/platform.c +++ b/trunk/arch/xtensa/kernel/platform.c @@ -44,3 +44,4 @@ _F(void, calibrate_ccount, (void), ccount_per_jiffy = 10 * (1000000UL/HZ); }); #endif + diff --git a/trunk/arch/xtensa/kernel/process.c b/trunk/arch/xtensa/kernel/process.c index 0dd5784416d3..1accf28da5f5 100644 --- a/trunk/arch/xtensa/kernel/process.c +++ b/trunk/arch/xtensa/kernel/process.c @@ -108,7 +108,7 @@ void coprocessor_flush_all(struct thread_info *ti) void cpu_idle(void) { - local_irq_enable(); + local_irq_enable(); /* endless idle loop with no priority at all */ while (1) { diff --git a/trunk/arch/xtensa/kernel/ptrace.c b/trunk/arch/xtensa/kernel/ptrace.c index 61fb2e9e9035..33eea4c16f12 100644 --- a/trunk/arch/xtensa/kernel/ptrace.c +++ b/trunk/arch/xtensa/kernel/ptrace.c @@ -154,7 +154,7 @@ int ptrace_setxregs(struct task_struct *child, void __user *uregs) coprocessor_flush_all(ti); coprocessor_release_all(ti); - ret |= __copy_from_user(&ti->xtregs_cp, &xtregs->cp0, + ret |= __copy_from_user(&ti->xtregs_cp, &xtregs->cp0, sizeof(xtregs_coprocessor_t)); #endif ret |= __copy_from_user(®s->xtregs_opt, &xtregs->opt, @@ -343,3 +343,4 @@ void do_syscall_trace_leave(struct pt_regs *regs) && (current->ptrace & PT_PTRACED)) do_syscall_trace(); } + diff --git a/trunk/arch/xtensa/kernel/setup.c b/trunk/arch/xtensa/kernel/setup.c index 24c1a57abb40..b237988ba6d7 100644 --- a/trunk/arch/xtensa/kernel/setup.c +++ b/trunk/arch/xtensa/kernel/setup.c @@ -22,11 +22,6 @@ #include #include -#ifdef CONFIG_OF -#include -#include -#endif - #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) # include #endif @@ -47,7 +42,6 @@ #include #include #include -#include #include @@ -70,11 +64,6 @@ int initrd_is_mapped = 0; extern int initrd_below_start_ok; #endif -#ifdef CONFIG_OF -extern u32 __dtb_start[]; -void *dtb_start = __dtb_start; -#endif - unsigned char aux_device_present; extern unsigned long loops_per_jiffy; @@ -94,8 +83,6 @@ extern void init_mmu(void); static inline void init_mmu(void) { } #endif -extern int mem_reserve(unsigned long, unsigned long, int); -extern void bootmem_init(void); extern void zones_init(void); /* @@ -117,33 +104,28 @@ typedef struct tagtable { /* parse current tag */ -static int __init add_sysmem_bank(unsigned long type, unsigned long start, - unsigned long end) +static int __init parse_tag_mem(const bp_tag_t *tag) { + meminfo_t *mi = (meminfo_t*)(tag->data); + + if (mi->type != MEMORY_TYPE_CONVENTIONAL) + return -1; + if (sysmem.nr_banks >= SYSMEM_BANKS_MAX) { printk(KERN_WARNING - "Ignoring memory bank 0x%08lx size %ldKB\n", - start, end - start); + "Ignoring memory bank 0x%08lx size %ldKB\n", + (unsigned long)mi->start, + (unsigned long)mi->end - (unsigned long)mi->start); return -EINVAL; } - sysmem.bank[sysmem.nr_banks].type = type; - sysmem.bank[sysmem.nr_banks].start = PAGE_ALIGN(start); - sysmem.bank[sysmem.nr_banks].end = end & PAGE_MASK; + sysmem.bank[sysmem.nr_banks].type = mi->type; + sysmem.bank[sysmem.nr_banks].start = PAGE_ALIGN(mi->start); + sysmem.bank[sysmem.nr_banks].end = mi->end & PAGE_MASK; sysmem.nr_banks++; return 0; } -static int __init parse_tag_mem(const bp_tag_t *tag) -{ - meminfo_t *mi = (meminfo_t *)(tag->data); - - if (mi->type != MEMORY_TYPE_CONVENTIONAL) - return -1; - - return add_sysmem_bank(mi->type, mi->start, mi->end); -} - __tagtable(BP_TAG_MEMORY, parse_tag_mem); #ifdef CONFIG_BLK_DEV_INITRD @@ -160,31 +142,12 @@ static int __init parse_tag_initrd(const bp_tag_t* tag) __tagtable(BP_TAG_INITRD, parse_tag_initrd); -#ifdef CONFIG_OF - -static int __init parse_tag_fdt(const bp_tag_t *tag) -{ - dtb_start = (void *)(tag->data[0]); - return 0; -} - -__tagtable(BP_TAG_FDT, parse_tag_fdt); - -void __init early_init_dt_setup_initrd_arch(unsigned long start, - unsigned long end) -{ - initrd_start = (void *)__va(start); - initrd_end = (void *)__va(end); - initrd_below_start_ok = 1; -} - -#endif /* CONFIG_OF */ - #endif /* CONFIG_BLK_DEV_INITRD */ static int __init parse_tag_cmdline(const bp_tag_t* tag) { - strlcpy(command_line, (char *)(tag->data), COMMAND_LINE_SIZE); + strncpy(command_line, (char*)(tag->data), COMMAND_LINE_SIZE); + command_line[COMMAND_LINE_SIZE - 1] = '\0'; return 0; } @@ -222,58 +185,6 @@ static int __init parse_bootparam(const bp_tag_t* tag) return 0; } -#ifdef CONFIG_OF - -void __init early_init_dt_add_memory_arch(u64 base, u64 size) -{ - size &= PAGE_MASK; - add_sysmem_bank(MEMORY_TYPE_CONVENTIONAL, base, base + size); -} - -void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) -{ - return __alloc_bootmem(size, align, 0); -} - -void __init early_init_devtree(void *params) -{ - /* Setup flat device-tree pointer */ - initial_boot_params = params; - - /* Retrieve various informations from the /chosen node of the - * device-tree, including the platform type, initrd location and - * size, TCE reserve, and more ... - */ - if (!command_line[0]) - of_scan_flat_dt(early_init_dt_scan_chosen, command_line); - - /* Scan memory nodes and rebuild MEMBLOCKs */ - of_scan_flat_dt(early_init_dt_scan_root, NULL); - if (sysmem.nr_banks == 0) - of_scan_flat_dt(early_init_dt_scan_memory, NULL); -} - -static void __init copy_devtree(void) -{ - void *alloc = early_init_dt_alloc_memory_arch( - be32_to_cpu(initial_boot_params->totalsize), 0); - if (alloc) { - memcpy(alloc, initial_boot_params, - be32_to_cpu(initial_boot_params->totalsize)); - initial_boot_params = alloc; - } -} - -static int __init xtensa_device_probe(void) -{ - of_platform_populate(NULL, NULL, NULL, NULL); - return 0; -} - -device_initcall(xtensa_device_probe); - -#endif /* CONFIG_OF */ - /* * Initialize architecture. (Early stage) */ @@ -282,14 +193,14 @@ void __init init_arch(bp_tag_t *bp_start) { sysmem.nr_banks = 0; - /* Parse boot parameters */ +#ifdef CONFIG_CMDLINE_BOOL + strcpy(command_line, default_command_line); +#endif - if (bp_start) - parse_bootparam(bp_start); + /* Parse boot parameters */ -#ifdef CONFIG_OF - early_init_devtree(dtb_start); -#endif + if (bp_start) + parse_bootparam(bp_start); if (sysmem.nr_banks == 0) { sysmem.nr_banks = 1; @@ -298,11 +209,6 @@ void __init init_arch(bp_tag_t *bp_start) + PLATFORM_DEFAULT_MEM_SIZE; } -#ifdef CONFIG_CMDLINE_BOOL - if (!command_line[0]) - strlcpy(command_line, default_command_line, COMMAND_LINE_SIZE); -#endif - /* Early hook for platforms */ platform_init(bp_start); @@ -329,129 +235,14 @@ extern char _UserExceptionVector_text_end; extern char _DoubleExceptionVector_literal_start; extern char _DoubleExceptionVector_text_end; - -#ifdef CONFIG_S32C1I_SELFTEST -#if XCHAL_HAVE_S32C1I - -static int __initdata rcw_word, rcw_probe_pc, rcw_exc; - -/* - * Basic atomic compare-and-swap, that records PC of S32C1I for probing. - * - * If *v == cmp, set *v = set. Return previous *v. - */ -static inline int probed_compare_swap(int *v, int cmp, int set) -{ - int tmp; - - __asm__ __volatile__( - " movi %1, 1f\n" - " s32i %1, %4, 0\n" - " wsr %2, scompare1\n" - "1: s32c1i %0, %3, 0\n" - : "=a" (set), "=&a" (tmp) - : "a" (cmp), "a" (v), "a" (&rcw_probe_pc), "0" (set) - : "memory" - ); - return set; -} - -/* Handle probed exception */ - -void __init do_probed_exception(struct pt_regs *regs, unsigned long exccause) -{ - if (regs->pc == rcw_probe_pc) { /* exception on s32c1i ? */ - regs->pc += 3; /* skip the s32c1i instruction */ - rcw_exc = exccause; - } else { - do_unhandled(regs, exccause); - } -} - -/* Simple test of S32C1I (soc bringup assist) */ - -void __init check_s32c1i(void) -{ - int n, cause1, cause2; - void *handbus, *handdata, *handaddr; /* temporarily saved handlers */ - - rcw_probe_pc = 0; - handbus = trap_set_handler(EXCCAUSE_LOAD_STORE_ERROR, - do_probed_exception); - handdata = trap_set_handler(EXCCAUSE_LOAD_STORE_DATA_ERROR, - do_probed_exception); - handaddr = trap_set_handler(EXCCAUSE_LOAD_STORE_ADDR_ERROR, - do_probed_exception); - - /* First try an S32C1I that does not store: */ - rcw_exc = 0; - rcw_word = 1; - n = probed_compare_swap(&rcw_word, 0, 2); - cause1 = rcw_exc; - - /* took exception? */ - if (cause1 != 0) { - /* unclean exception? */ - if (n != 2 || rcw_word != 1) - panic("S32C1I exception error"); - } else if (rcw_word != 1 || n != 1) { - panic("S32C1I compare error"); - } - - /* Then an S32C1I that stores: */ - rcw_exc = 0; - rcw_word = 0x1234567; - n = probed_compare_swap(&rcw_word, 0x1234567, 0xabcde); - cause2 = rcw_exc; - - if (cause2 != 0) { - /* unclean exception? */ - if (n != 0xabcde || rcw_word != 0x1234567) - panic("S32C1I exception error (b)"); - } else if (rcw_word != 0xabcde || n != 0x1234567) { - panic("S32C1I store error"); - } - - /* Verify consistency of exceptions: */ - if (cause1 || cause2) { - pr_warn("S32C1I took exception %d, %d\n", cause1, cause2); - /* If emulation of S32C1I upon bus error gets implemented, - we can get rid of this panic for single core (not SMP) */ - panic("S32C1I exceptions not currently supported"); - } - if (cause1 != cause2) - panic("inconsistent S32C1I exceptions"); - - trap_set_handler(EXCCAUSE_LOAD_STORE_ERROR, handbus); - trap_set_handler(EXCCAUSE_LOAD_STORE_DATA_ERROR, handdata); - trap_set_handler(EXCCAUSE_LOAD_STORE_ADDR_ERROR, handaddr); -} - -#else /* XCHAL_HAVE_S32C1I */ - -/* This condition should not occur with a commercially deployed processor. - Display reminder for early engr test or demo chips / FPGA bitstreams */ -void __init check_s32c1i(void) -{ - pr_warn("Processor configuration lacks atomic compare-and-swap support!\n"); -} - -#endif /* XCHAL_HAVE_S32C1I */ -#else /* CONFIG_S32C1I_SELFTEST */ - -void __init check_s32c1i(void) -{ -} - -#endif /* CONFIG_S32C1I_SELFTEST */ - - void __init setup_arch(char **cmdline_p) { - strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); - *cmdline_p = command_line; + extern int mem_reserve(unsigned long, unsigned long, int); + extern void bootmem_init(void); - check_s32c1i(); + memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); + boot_command_line[COMMAND_LINE_SIZE-1] = '\0'; + *cmdline_p = command_line; /* Reserve some memory regions */ @@ -460,7 +251,7 @@ void __init setup_arch(char **cmdline_p) initrd_is_mapped = mem_reserve(__pa(initrd_start), __pa(initrd_end), 0); initrd_below_start_ok = 1; - } else { + } else { initrd_start = 0; } #endif @@ -484,13 +275,9 @@ void __init setup_arch(char **cmdline_p) bootmem_init(); -#ifdef CONFIG_OF - copy_devtree(); - unflatten_device_tree(); -#endif - platform_setup(cmdline_p); + paging_init(); zones_init(); @@ -539,7 +326,7 @@ c_show(struct seq_file *f, void *slot) "core ID\t\t: " XCHAL_CORE_ID "\n" "build ID\t: 0x%x\n" "byte order\t: %s\n" - "cpu MHz\t\t: %lu.%02lu\n" + "cpu MHz\t\t: %lu.%02lu\n" "bogomips\t: %lu.%02lu\n", XCHAL_BUILD_UNIQUE_ID, XCHAL_HAVE_BE ? "big" : "little", @@ -593,9 +380,6 @@ c_show(struct seq_file *f, void *slot) #endif #if XCHAL_HAVE_FP "fpu " -#endif -#if XCHAL_HAVE_S32C1I - "s32c1i " #endif "\n"); @@ -628,7 +412,7 @@ c_show(struct seq_file *f, void *slot) "icache size\t: %d\n" "icache flags\t: " #if XCHAL_ICACHE_LINE_LOCKABLE - "lock " + "lock" #endif "\n" "dcache line size: %d\n" @@ -636,10 +420,10 @@ c_show(struct seq_file *f, void *slot) "dcache size\t: %d\n" "dcache flags\t: " #if XCHAL_DCACHE_IS_WRITEBACK - "writeback " + "writeback" #endif #if XCHAL_DCACHE_LINE_LOCKABLE - "lock " + "lock" #endif "\n", XCHAL_ICACHE_LINESIZE, @@ -681,3 +465,4 @@ const struct seq_operations cpuinfo_op = }; #endif /* CONFIG_PROC_FS */ + diff --git a/trunk/arch/xtensa/kernel/signal.c b/trunk/arch/xtensa/kernel/signal.c index de34d6be91cd..63c566f627bc 100644 --- a/trunk/arch/xtensa/kernel/signal.c +++ b/trunk/arch/xtensa/kernel/signal.c @@ -212,7 +212,7 @@ restore_sigcontext(struct pt_regs *regs, struct rt_sigframe __user *frame) if (err) return err; - /* The signal handler may have used coprocessors in which + /* The signal handler may have used coprocessors in which * case they are still enabled. We disable them to force a * reloading of the original task's CP state by the lazy * context-switching mechanisms of CP exception handling. @@ -396,7 +396,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info, */ /* Set up registers for signal handler */ - start_thread(regs, (unsigned long) ka->sa.sa_handler, + start_thread(regs, (unsigned long) ka->sa.sa_handler, (unsigned long) frame); /* Set up a stack frame for a call4 @@ -424,9 +424,9 @@ static int setup_frame(int sig, struct k_sigaction *ka, siginfo_t *info, return -EFAULT; } -asmlinkage long xtensa_sigaltstack(const stack_t __user *uss, +asmlinkage long xtensa_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, - long a2, long a3, long a4, long a5, + long a2, long a3, long a4, long a5, struct pt_regs *regs) { return do_sigaltstack(uss, uoss, regs->areg[1]); diff --git a/trunk/arch/xtensa/kernel/syscall.c b/trunk/arch/xtensa/kernel/syscall.c index 54fa8425cee2..5702065f472a 100644 --- a/trunk/arch/xtensa/kernel/syscall.c +++ b/trunk/arch/xtensa/kernel/syscall.c @@ -52,3 +52,4 @@ asmlinkage long xtensa_fadvise64_64(int fd, int advice, { return sys_fadvise64_64(fd, offset, len, advice); } + diff --git a/trunk/arch/xtensa/kernel/time.c b/trunk/arch/xtensa/kernel/time.c index ffb474104311..ac62f9cf1e10 100644 --- a/trunk/arch/xtensa/kernel/time.c +++ b/trunk/arch/xtensa/kernel/time.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -32,7 +31,7 @@ unsigned long ccount_per_jiffy; /* per 1/HZ */ unsigned long nsec_per_ccount; /* nsec per ccount increment */ #endif -static cycle_t ccount_read(struct clocksource *cs) +static cycle_t ccount_read(void) { return (cycle_t)get_ccount(); } @@ -53,7 +52,6 @@ static struct irqaction timer_irqaction = { void __init time_init(void) { - unsigned int irq; #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT printk("Calibrating CPU frequency "); platform_calibrate_ccount(); @@ -64,8 +62,7 @@ void __init time_init(void) /* Initialize the linux timer interrupt. */ - irq = irq_create_mapping(NULL, LINUX_TIMER_INT); - setup_irq(irq, &timer_irqaction); + setup_irq(LINUX_TIMER_INT, &timer_irqaction); set_linux_timer(get_ccount() + CCOUNT_PER_JIFFY); } diff --git a/trunk/arch/xtensa/kernel/traps.c b/trunk/arch/xtensa/kernel/traps.c index 01e0111bf787..5caf2b64d43a 100644 --- a/trunk/arch/xtensa/kernel/traps.c +++ b/trunk/arch/xtensa/kernel/traps.c @@ -293,17 +293,6 @@ do_debug(struct pt_regs *regs) } -/* Set exception C handler - for temporary use when probing exceptions */ - -void * __init trap_set_handler(int cause, void *handler) -{ - unsigned long *entry = &exc_table[EXC_TABLE_DEFAULT / 4 + cause]; - void *previous = (void *)*entry; - *entry = (unsigned long)handler; - return previous; -} - - /* * Initialize dispatch tables. * @@ -408,8 +397,7 @@ static inline void spill_registers(void) "wsr a13, sar\n\t" "wsr a14, ps\n\t" :: "a" (&a0), "a" (&ps) - : "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15", - "memory"); + : "a2", "a3", "a4", "a7", "a11", "a12", "a13", "a14", "a15", "memory"); } void show_trace(struct task_struct *task, unsigned long *sp) @@ -464,7 +452,7 @@ void show_stack(struct task_struct *task, unsigned long *sp) if (!sp) sp = stack_pointer(task); - stack = sp; + stack = sp; printk("\nStack: "); @@ -535,3 +523,5 @@ void die(const char * str, struct pt_regs * regs, long err) do_exit(err); } + + diff --git a/trunk/arch/xtensa/kernel/vectors.S b/trunk/arch/xtensa/kernel/vectors.S index 68df35f66ce3..4462c1e595c2 100644 --- a/trunk/arch/xtensa/kernel/vectors.S +++ b/trunk/arch/xtensa/kernel/vectors.S @@ -79,8 +79,6 @@ ENTRY(_UserExceptionVector) l32i a0, a0, EXC_TABLE_FAST_USER # load handler jx a0 -ENDPROC(_UserExceptionVector) - /* * Kernel exception vector. (Exceptions with PS.UM == 0, PS.EXCM == 0) * @@ -105,7 +103,6 @@ ENTRY(_KernelExceptionVector) l32i a0, a0, EXC_TABLE_FAST_KERNEL # load handler address jx a0 -ENDPROC(_KernelExceptionVector) /* * Double exception vector (Exceptions with PS.EXCM == 1) @@ -228,13 +225,7 @@ ENTRY(_DoubleExceptionVector) /* Window overflow/underflow exception. Get stack pointer. */ mov a3, a2 - /* This explicit literal and the following references to it are made - * in order to fit DoubleExceptionVector.literals into the available - * 16-byte gap before DoubleExceptionVector.text in the absence of - * link time relaxation. See kernel/vmlinux.lds.S - */ - .literal .Lexc_table, exc_table - l32r a2, .Lexc_table + movi a2, exc_table l32i a2, a2, EXC_TABLE_KSTK /* Check for overflow/underflow exception, jump if overflow. */ @@ -264,7 +255,7 @@ ENTRY(_DoubleExceptionVector) s32i a0, a2, PT_AREG0 wsr a3, excsave1 # save a3 - l32r a3, .Lexc_table + movi a3, exc_table rsr a0, exccause s32i a0, a2, PT_DEPC # mark it as a regular exception @@ -276,7 +267,7 @@ ENTRY(_DoubleExceptionVector) /* a0: depc, a1: a1, a2: a2, a3: trashed, depc: a0, excsave1: a3 */ - l32r a3, .Lexc_table + movi a3, exc_table s32i a2, a3, EXC_TABLE_DOUBLE_SAVE # temporary variable /* Enter critical section. */ @@ -305,7 +296,7 @@ ENTRY(_DoubleExceptionVector) /* a0: avail, a1: a1, a2: kstk, a3: avail, depc: a2, excsave: a3 */ - l32r a3, .Lexc_table + movi a3, exc_table rsr a0, exccause addx4 a0, a0, a3 l32i a0, a0, EXC_TABLE_FAST_USER @@ -347,7 +338,6 @@ ENTRY(_DoubleExceptionVector) .end literal_prefix -ENDPROC(_DoubleExceptionVector) /* * Debug interrupt vector @@ -359,11 +349,9 @@ ENDPROC(_DoubleExceptionVector) .section .DebugInterruptVector.text, "ax" ENTRY(_DebugInterruptVector) - xsr a0, SREG_EXCSAVE + XCHAL_DEBUGLEVEL jx a0 -ENDPROC(_DebugInterruptVector) /* Window overflow and underflow handlers. @@ -375,43 +363,38 @@ ENDPROC(_DebugInterruptVector) * we try to access any page that would cause a page fault early. */ -#define ENTRY_ALIGN64(name) \ - .globl name; \ - .align 64; \ - name: - .section .WindowVectors.text, "ax" /* 4-Register Window Overflow Vector (Handler) */ -ENTRY_ALIGN64(_WindowOverflow4) - + .align 64 +.global _WindowOverflow4 +_WindowOverflow4: s32e a0, a5, -16 s32e a1, a5, -12 s32e a2, a5, -8 s32e a3, a5, -4 rfwo -ENDPROC(_WindowOverflow4) - /* 4-Register Window Underflow Vector (Handler) */ -ENTRY_ALIGN64(_WindowUnderflow4) - + .align 64 +.global _WindowUnderflow4 +_WindowUnderflow4: l32e a0, a5, -16 l32e a1, a5, -12 l32e a2, a5, -8 l32e a3, a5, -4 rfwu -ENDPROC(_WindowUnderflow4) /* 8-Register Window Overflow Vector (Handler) */ -ENTRY_ALIGN64(_WindowOverflow8) - + .align 64 +.global _WindowOverflow8 +_WindowOverflow8: s32e a0, a9, -16 l32e a0, a1, -12 s32e a2, a9, -8 @@ -423,12 +406,11 @@ ENTRY_ALIGN64(_WindowOverflow8) s32e a7, a0, -20 rfwo -ENDPROC(_WindowOverflow8) - /* 8-Register Window Underflow Vector (Handler) */ -ENTRY_ALIGN64(_WindowUnderflow8) - + .align 64 +.global _WindowUnderflow8 +_WindowUnderflow8: l32e a1, a9, -12 l32e a0, a9, -16 l32e a7, a1, -12 @@ -440,12 +422,12 @@ ENTRY_ALIGN64(_WindowUnderflow8) l32e a7, a7, -20 rfwu -ENDPROC(_WindowUnderflow8) /* 12-Register Window Overflow Vector (Handler) */ -ENTRY_ALIGN64(_WindowOverflow12) - + .align 64 +.global _WindowOverflow12 +_WindowOverflow12: s32e a0, a13, -16 l32e a0, a1, -12 s32e a1, a13, -12 @@ -461,12 +443,11 @@ ENTRY_ALIGN64(_WindowOverflow12) s32e a11, a0, -20 rfwo -ENDPROC(_WindowOverflow12) - /* 12-Register Window Underflow Vector (Handler) */ -ENTRY_ALIGN64(_WindowUnderflow12) - + .align 64 +.global _WindowUnderflow12 +_WindowUnderflow12: l32e a1, a13, -12 l32e a0, a13, -16 l32e a11, a1, -12 @@ -482,6 +463,6 @@ ENTRY_ALIGN64(_WindowUnderflow12) l32e a11, a11, -20 rfwu -ENDPROC(_WindowUnderflow12) - .text + + diff --git a/trunk/arch/xtensa/lib/checksum.S b/trunk/arch/xtensa/lib/checksum.S index 4eb573d2720e..df397f932d0e 100644 --- a/trunk/arch/xtensa/lib/checksum.S +++ b/trunk/arch/xtensa/lib/checksum.S @@ -41,11 +41,10 @@ .text ENTRY(csum_partial) - - /* - * Experiments with Ethernet and SLIP connections show that buf - * is aligned on either a 2-byte or 4-byte boundary. - */ + /* + * Experiments with Ethernet and SLIP connections show that buf + * is aligned on either a 2-byte or 4-byte boundary. + */ entry sp, 32 extui a5, a2, 0, 2 bnez a5, 8f /* branch if 2-byte aligned */ @@ -171,7 +170,7 @@ ENTRY(csum_partial) 3: j 5b /* branch to handle the remaining byte */ -ENDPROC(csum_partial) + /* * Copy from ds while checksumming, otherwise like csum_partial @@ -212,7 +211,6 @@ unsigned int csum_partial_copy_generic (const char *src, char *dst, int len, */ ENTRY(csum_partial_copy_generic) - entry sp, 32 mov a12, a3 mov a11, a4 @@ -369,8 +367,6 @@ DST( s8i a8, a3, 1 ) 6: j 4b /* process the possible trailing odd byte */ -ENDPROC(csum_partial_copy_generic) - # Exception handler: .section .fixup, "ax" @@ -410,3 +406,4 @@ ENDPROC(csum_partial_copy_generic) retw .previous + diff --git a/trunk/arch/xtensa/lib/memcopy.S b/trunk/arch/xtensa/lib/memcopy.S index b1c219acabe7..c48b80acb5f0 100644 --- a/trunk/arch/xtensa/lib/memcopy.S +++ b/trunk/arch/xtensa/lib/memcopy.S @@ -210,10 +210,8 @@ memcpy: _beqz a4, .Ldone # avoid loading anything for zero-length copies # copy 16 bytes per iteration for word-aligned dst and unaligned src ssa8 a3 # set shift amount from byte offset - -/* set to 1 when running on ISS (simulator) with the - lint or ferret client, or 0 to save a few cycles */ -#define SIM_CHECKS_ALIGNMENT 1 +#define SIM_CHECKS_ALIGNMENT 1 /* set to 1 when running on ISS (simulator) with the + lint or ferret client, or 0 to save a few cycles */ #if XCHAL_UNALIGNED_LOAD_EXCEPTION || SIM_CHECKS_ALIGNMENT and a11, a3, a8 # save unalignment offset for below sub a3, a3, a11 # align a3 diff --git a/trunk/arch/xtensa/lib/pci-auto.c b/trunk/arch/xtensa/lib/pci-auto.c index 34d05abbd921..a71733ae1193 100644 --- a/trunk/arch/xtensa/lib/pci-auto.c +++ b/trunk/arch/xtensa/lib/pci-auto.c @@ -241,8 +241,8 @@ int __init pciauto_bus_scan(struct pci_controller *pci_ctrl, int current_bus) unsigned char header_type; struct pci_dev *dev = &pciauto_dev; - pciauto_dev.bus = &pciauto_bus; - pciauto_dev.sysdata = pci_ctrl; + pciauto_dev.bus = &pciauto_bus; + pciauto_dev.sysdata = pci_ctrl; pciauto_bus.ops = pci_ctrl->ops; /* @@ -345,3 +345,8 @@ int __init pciauto_bus_scan(struct pci_controller *pci_ctrl, int current_bus) } return sub_bus; } + + + + + diff --git a/trunk/arch/xtensa/lib/strncpy_user.S b/trunk/arch/xtensa/lib/strncpy_user.S index 1ad0ecf45368..9f603cdaaa68 100644 --- a/trunk/arch/xtensa/lib/strncpy_user.S +++ b/trunk/arch/xtensa/lib/strncpy_user.S @@ -166,7 +166,7 @@ __strncpy_user: retw .Lz1: # byte 1 is zero #ifdef __XTENSA_EB__ - extui a9, a9, 16, 16 + extui a9, a9, 16, 16 #endif /* __XTENSA_EB__ */ EX(s16i, a9, a11, 0, fixup_s) addi a11, a11, 1 # advance dst pointer @@ -174,7 +174,7 @@ __strncpy_user: retw .Lz2: # byte 2 is zero #ifdef __XTENSA_EB__ - extui a9, a9, 16, 16 + extui a9, a9, 16, 16 #endif /* __XTENSA_EB__ */ EX(s16i, a9, a11, 0, fixup_s) movi a9, 0 diff --git a/trunk/arch/xtensa/lib/strnlen_user.S b/trunk/arch/xtensa/lib/strnlen_user.S index 4c03b1e581e9..23f2a89816a1 100644 --- a/trunk/arch/xtensa/lib/strnlen_user.S +++ b/trunk/arch/xtensa/lib/strnlen_user.S @@ -145,3 +145,4 @@ __strnlen_user: lenfixup: movi a2, 0 retw + diff --git a/trunk/arch/xtensa/lib/usercopy.S b/trunk/arch/xtensa/lib/usercopy.S index ace1892a875e..46d60314bb16 100644 --- a/trunk/arch/xtensa/lib/usercopy.S +++ b/trunk/arch/xtensa/lib/usercopy.S @@ -318,3 +318,4 @@ l_fixup: /* Ignore memset return value in a6. */ /* a2 still contains bytes not copied. */ retw + diff --git a/trunk/arch/xtensa/mm/cache.c b/trunk/arch/xtensa/mm/cache.c index 81edeab82d17..85df4655d326 100644 --- a/trunk/arch/xtensa/mm/cache.c +++ b/trunk/arch/xtensa/mm/cache.c @@ -118,7 +118,7 @@ void flush_dcache_page(struct page *page) * For now, flush the whole cache. FIXME?? */ -void flush_cache_range(struct vm_area_struct* vma, +void flush_cache_range(struct vm_area_struct* vma, unsigned long start, unsigned long end) { __flush_invalidate_dcache_all(); @@ -133,7 +133,7 @@ void flush_cache_range(struct vm_area_struct* vma, */ void flush_cache_page(struct vm_area_struct* vma, unsigned long address, - unsigned long pfn) + unsigned long pfn) { /* Note that we have to use the 'alias' address to avoid multi-hit */ @@ -166,14 +166,14 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep) if (!PageReserved(page) && test_bit(PG_arch_1, &page->flags)) { + unsigned long vaddr = TLBTEMP_BASE_1 + (addr & DCACHE_ALIAS_MASK); unsigned long paddr = (unsigned long) page_address(page); unsigned long phys = page_to_phys(page); - unsigned long tmp = TLBTEMP_BASE_1 + (addr & DCACHE_ALIAS_MASK); __flush_invalidate_dcache_page(paddr); - __flush_invalidate_dcache_page_alias(tmp, phys); - __invalidate_icache_page_alias(tmp, phys); + __flush_invalidate_dcache_page_alias(vaddr, phys); + __invalidate_icache_page_alias(vaddr, phys); clear_bit(PG_arch_1, &page->flags); } @@ -195,7 +195,7 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep) #if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK -void copy_to_user_page(struct vm_area_struct *vma, struct page *page, +void copy_to_user_page(struct vm_area_struct *vma, struct page *page, unsigned long vaddr, void *dst, const void *src, unsigned long len) { @@ -205,8 +205,8 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page, /* Flush and invalidate user page if aliased. */ if (alias) { - unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); - __flush_invalidate_dcache_page_alias(t, phys); + unsigned long temp = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); + __flush_invalidate_dcache_page_alias(temp, phys); } /* Copy data */ @@ -219,11 +219,12 @@ void copy_to_user_page(struct vm_area_struct *vma, struct page *page, */ if (alias) { - unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); + unsigned long temp = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); __flush_invalidate_dcache_range((unsigned long) dst, len); - if ((vma->vm_flags & VM_EXEC) != 0) - __invalidate_icache_page_alias(t, phys); + if ((vma->vm_flags & VM_EXEC) != 0) { + __invalidate_icache_page_alias(temp, phys); + } } else if ((vma->vm_flags & VM_EXEC) != 0) { __flush_dcache_range((unsigned long)dst,len); @@ -244,8 +245,8 @@ extern void copy_from_user_page(struct vm_area_struct *vma, struct page *page, */ if (alias) { - unsigned long t = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); - __flush_invalidate_dcache_page_alias(t, phys); + unsigned long temp = TLBTEMP_BASE_1 + (vaddr & DCACHE_ALIAS_MASK); + __flush_invalidate_dcache_page_alias(temp, phys); } memcpy(dst, src, len); diff --git a/trunk/arch/xtensa/mm/fault.c b/trunk/arch/xtensa/mm/fault.c index 4b7bc8db170f..245b08f7eaf4 100644 --- a/trunk/arch/xtensa/mm/fault.c +++ b/trunk/arch/xtensa/mm/fault.c @@ -254,3 +254,4 @@ bad_page_fault(struct pt_regs *regs, unsigned long address, int sig) die("Oops", regs, sig); do_exit(sig); } + diff --git a/trunk/arch/xtensa/mm/init.c b/trunk/arch/xtensa/mm/init.c index 7a5156ffebb6..db955179da2d 100644 --- a/trunk/arch/xtensa/mm/init.c +++ b/trunk/arch/xtensa/mm/init.c @@ -75,15 +75,15 @@ int __init mem_reserve(unsigned long start, unsigned long end, int must_exist) sysmem.nr_banks++; } sysmem.bank[i].end = start; - - } else if (end < sysmem.bank[i].end) { - sysmem.bank[i].start = end; - } else { - /* remove entry */ - sysmem.nr_banks--; - sysmem.bank[i].start = sysmem.bank[sysmem.nr_banks].start; - sysmem.bank[i].end = sysmem.bank[sysmem.nr_banks].end; + if (end < sysmem.bank[i].end) + sysmem.bank[i].start = end; + else { + /* remove entry */ + sysmem.nr_banks--; + sysmem.bank[i].start = sysmem.bank[sysmem.nr_banks].start; + sysmem.bank[i].end = sysmem.bank[sysmem.nr_banks].end; + } } return -1; } diff --git a/trunk/arch/xtensa/mm/misc.S b/trunk/arch/xtensa/mm/misc.S index d97ed1ba7b0a..b048406d8756 100644 --- a/trunk/arch/xtensa/mm/misc.S +++ b/trunk/arch/xtensa/mm/misc.S @@ -29,7 +29,6 @@ */ ENTRY(clear_page) - entry a1, 16 movi a3, 0 @@ -46,8 +45,6 @@ ENTRY(clear_page) retw -ENDPROC(clear_page) - /* * copy_page and copy_user_page are the same for non-cache-aliased configs. * @@ -56,7 +53,6 @@ ENDPROC(clear_page) */ ENTRY(copy_page) - entry a1, 16 __loopi a2, a4, PAGE_SIZE, 32 @@ -88,8 +84,6 @@ ENTRY(copy_page) retw -ENDPROC(copy_page) - #ifdef CONFIG_MMU /* * If we have to deal with cache aliasing, we use temporary memory mappings @@ -115,7 +109,6 @@ ENTRY(__tlbtemp_mapping_start) */ ENTRY(clear_user_page) - entry a1, 32 /* Mark page dirty and determine alias. */ @@ -171,8 +164,6 @@ ENTRY(clear_user_page) retw -ENDPROC(clear_user_page) - /* * copy_page_user (void *to, void *from, unsigned long vaddr, struct page *page) * a2 a3 a4 a5 @@ -180,7 +171,7 @@ ENDPROC(clear_user_page) ENTRY(copy_user_page) - entry a1, 32 + entry a1, 32 /* Mark page dirty and determine alias for destination. */ @@ -271,8 +262,6 @@ ENTRY(copy_user_page) retw -ENDPROC(copy_user_page) - #endif #if (DCACHE_WAY_SIZE > PAGE_SIZE) @@ -283,7 +272,6 @@ ENDPROC(copy_user_page) */ ENTRY(__flush_invalidate_dcache_page_alias) - entry sp, 16 movi a7, 0 # required for exception handler @@ -299,7 +287,6 @@ ENTRY(__flush_invalidate_dcache_page_alias) retw -ENDPROC(__flush_invalidate_dcache_page_alias) #endif ENTRY(__tlbtemp_mapping_itlb) @@ -307,7 +294,6 @@ ENTRY(__tlbtemp_mapping_itlb) #if (ICACHE_WAY_SIZE > PAGE_SIZE) ENTRY(__invalidate_icache_page_alias) - entry sp, 16 addi a6, a3, (PAGE_KERNEL_EXEC | _PAGE_HW_WRITE) @@ -321,14 +307,11 @@ ENTRY(__invalidate_icache_page_alias) isync retw -ENDPROC(__invalidate_icache_page_alias) - #endif /* End of special treatment in tlb miss exception */ ENTRY(__tlbtemp_mapping_end) - #endif /* CONFIG_MMU /* @@ -336,7 +319,6 @@ ENTRY(__tlbtemp_mapping_end) */ ENTRY(__invalidate_icache_page) - entry sp, 16 ___invalidate_icache_page a2 a3 @@ -344,14 +326,11 @@ ENTRY(__invalidate_icache_page) retw -ENDPROC(__invalidate_icache_page) - /* * void __invalidate_dcache_page(ulong start) */ ENTRY(__invalidate_dcache_page) - entry sp, 16 ___invalidate_dcache_page a2 a3 @@ -359,14 +338,11 @@ ENTRY(__invalidate_dcache_page) retw -ENDPROC(__invalidate_dcache_page) - /* * void __flush_invalidate_dcache_page(ulong start) */ ENTRY(__flush_invalidate_dcache_page) - entry sp, 16 ___flush_invalidate_dcache_page a2 a3 @@ -374,14 +350,11 @@ ENTRY(__flush_invalidate_dcache_page) dsync retw -ENDPROC(__flush_invalidate_dcache_page) - /* * void __flush_dcache_page(ulong start) */ ENTRY(__flush_dcache_page) - entry sp, 16 ___flush_dcache_page a2 a3 @@ -389,14 +362,11 @@ ENTRY(__flush_dcache_page) dsync retw -ENDPROC(__flush_dcache_page) - /* * void __invalidate_icache_range(ulong start, ulong size) */ ENTRY(__invalidate_icache_range) - entry sp, 16 ___invalidate_icache_range a2 a3 a4 @@ -404,14 +374,11 @@ ENTRY(__invalidate_icache_range) retw -ENDPROC(__invalidate_icache_range) - /* * void __flush_invalidate_dcache_range(ulong start, ulong size) */ ENTRY(__flush_invalidate_dcache_range) - entry sp, 16 ___flush_invalidate_dcache_range a2 a3 a4 @@ -419,14 +386,11 @@ ENTRY(__flush_invalidate_dcache_range) retw -ENDPROC(__flush_invalidate_dcache_range) - /* * void _flush_dcache_range(ulong start, ulong size) */ ENTRY(__flush_dcache_range) - entry sp, 16 ___flush_dcache_range a2 a3 a4 @@ -434,28 +398,22 @@ ENTRY(__flush_dcache_range) retw -ENDPROC(__flush_dcache_range) - /* * void _invalidate_dcache_range(ulong start, ulong size) */ ENTRY(__invalidate_dcache_range) - entry sp, 16 ___invalidate_dcache_range a2 a3 a4 retw -ENDPROC(__invalidate_dcache_range) - /* * void _invalidate_icache_all(void) */ ENTRY(__invalidate_icache_all) - entry sp, 16 ___invalidate_icache_all a2 a3 @@ -463,14 +421,11 @@ ENTRY(__invalidate_icache_all) retw -ENDPROC(__invalidate_icache_all) - /* * void _flush_invalidate_dcache_all(void) */ ENTRY(__flush_invalidate_dcache_all) - entry sp, 16 ___flush_invalidate_dcache_all a2 a3 @@ -478,14 +433,11 @@ ENTRY(__flush_invalidate_dcache_all) retw -ENDPROC(__flush_invalidate_dcache_all) - /* * void _invalidate_dcache_all(void) */ ENTRY(__invalidate_dcache_all) - entry sp, 16 ___invalidate_dcache_all a2 a3 @@ -493,4 +445,3 @@ ENTRY(__invalidate_dcache_all) retw -ENDPROC(__invalidate_dcache_all) diff --git a/trunk/arch/xtensa/mm/mmu.c b/trunk/arch/xtensa/mm/mmu.c index 0f77f9d3bb8b..ca81654f3ec2 100644 --- a/trunk/arch/xtensa/mm/mmu.c +++ b/trunk/arch/xtensa/mm/mmu.c @@ -37,7 +37,7 @@ void __init init_mmu(void) /* Set rasid register to a known value. */ - set_rasid_register(ASID_INSERT(ASID_USER_FIRST)); + set_rasid_register(ASID_USER_FIRST); /* Set PTEVADDR special register to the start of the page * table, which is in kernel mappable space (ie. not diff --git a/trunk/arch/xtensa/mm/tlb.c b/trunk/arch/xtensa/mm/tlb.c index 5411aa67c68e..e2700b21395b 100644 --- a/trunk/arch/xtensa/mm/tlb.c +++ b/trunk/arch/xtensa/mm/tlb.c @@ -63,7 +63,7 @@ void flush_tlb_all (void) void flush_tlb_mm(struct mm_struct *mm) { if (mm == current->active_mm) { - unsigned long flags; + int flags; local_save_flags(flags); __get_new_mmu_context(mm); __load_mmu_context(mm); @@ -82,7 +82,7 @@ void flush_tlb_mm(struct mm_struct *mm) #endif void flush_tlb_range (struct vm_area_struct *vma, - unsigned long start, unsigned long end) + unsigned long start, unsigned long end) { struct mm_struct *mm = vma->vm_mm; unsigned long flags; @@ -100,7 +100,7 @@ void flush_tlb_range (struct vm_area_struct *vma, int oldpid = get_rasid_register(); set_rasid_register (ASID_INSERT(mm->context)); start &= PAGE_MASK; - if (vma->vm_flags & VM_EXEC) + if (vma->vm_flags & VM_EXEC) while(start < end) { invalidate_itlb_mapping(start); invalidate_dtlb_mapping(start); @@ -130,7 +130,7 @@ void flush_tlb_page (struct vm_area_struct *vma, unsigned long page) local_save_flags(flags); - oldpid = get_rasid_register(); + oldpid = get_rasid_register(); if (vma->vm_flags & VM_EXEC) invalidate_itlb_mapping(page); @@ -140,3 +140,4 @@ void flush_tlb_page (struct vm_area_struct *vma, unsigned long page) local_irq_restore(flags); } + diff --git a/trunk/arch/xtensa/platforms/iss/include/platform/serial.h b/trunk/arch/xtensa/platforms/iss/include/platform/serial.h index 16aec542d435..e69de29bb2d1 100644 --- a/trunk/arch/xtensa/platforms/iss/include/platform/serial.h +++ b/trunk/arch/xtensa/platforms/iss/include/platform/serial.h @@ -1,15 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2012 Tensilica Inc. - */ - -#ifndef __ASM_XTENSA_ISS_SERIAL_H -#define __ASM_XTENSA_ISS_SERIAL_H - -/* Have no meaning on ISS, but needed for 8250_early.c */ -#define BASE_BAUD 0 - -#endif /* __ASM_XTENSA_ISS_SERIAL_H */ diff --git a/trunk/arch/xtensa/platforms/iss/include/platform/simcall.h b/trunk/arch/xtensa/platforms/iss/include/platform/simcall.h index b5a4edf02d76..bd78192e2fc9 100644 --- a/trunk/arch/xtensa/platforms/iss/include/platform/simcall.h +++ b/trunk/arch/xtensa/platforms/iss/include/platform/simcall.h @@ -74,12 +74,13 @@ static inline int __simc(int a, int b, int c, int d, int e, int f) "mov %1, a3\n" : "=a" (ret), "=a" (errno), "+r"(a1), "+r"(b1) : "r"(c1), "r"(d1), "r"(e1), "r"(f1) - : "memory"); + : ); return ret; } static inline int simc_open(const char *file, int flags, int mode) { + wmb(); return __simc(SYS_open, (int) file, flags, mode, 0, 0); } @@ -90,16 +91,19 @@ static inline int simc_close(int fd) static inline int simc_ioctl(int fd, int request, void *arg) { + wmb(); return __simc(SYS_ioctl, fd, request, (int) arg, 0, 0); } static inline int simc_read(int fd, void *buf, size_t count) { + rmb(); return __simc(SYS_read, fd, (int) buf, count, 0, 0); } static inline int simc_write(int fd, const void *buf, size_t count) { + wmb(); return __simc(SYS_write, fd, (int) buf, count, 0, 0); } @@ -107,6 +111,7 @@ static inline int simc_poll(int fd) { struct timeval tv = { .tv_sec = 0, .tv_usec = 0 }; + wmb(); return __simc(SYS_select_one, fd, XTISS_SELECT_ONE_READ, (int)&tv, 0, 0); } diff --git a/trunk/arch/xtensa/platforms/xtfpga/Makefile b/trunk/arch/xtensa/platforms/xtfpga/Makefile deleted file mode 100644 index b9ae206340cd..000000000000 --- a/trunk/arch/xtensa/platforms/xtfpga/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -# Makefile for the Tensilica xtavnet Emulation Board -# -# Note! Dependencies are done automagically by 'make dep', which also -# removes any old dependencies. DON'T put your own dependencies here -# unless it's something special (ie not a .c file). -# -# Note 2! The CFLAGS definitions are in the main makefile... - -obj-y = setup.o lcd.o diff --git a/trunk/arch/xtensa/platforms/xtfpga/include/platform/hardware.h b/trunk/arch/xtensa/platforms/xtfpga/include/platform/hardware.h deleted file mode 100644 index 4416773cbde5..000000000000 --- a/trunk/arch/xtensa/platforms/xtfpga/include/platform/hardware.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * arch/xtensa/platform/xtavnet/include/platform/hardware.h - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2006 Tensilica Inc. - */ - -/* - * This file contains the hardware configuration of the XTAVNET boards. - */ - -#ifndef __XTENSA_XTAVNET_HARDWARE_H -#define __XTENSA_XTAVNET_HARDWARE_H - -/* By default NO_IRQ is defined to 0 in Linux, but we use the - interrupt 0 for UART... */ -#define NO_IRQ -1 - -/* Memory configuration. */ - -#define PLATFORM_DEFAULT_MEM_START 0x00000000 -#define PLATFORM_DEFAULT_MEM_SIZE 0x04000000 - -/* Interrupt configuration. */ - -#define PLATFORM_NR_IRQS 10 - -/* Default assignment of LX60 devices to external interrupts. */ - -#ifdef CONFIG_ARCH_HAS_SMP -#define DUART16552_INTNUM XCHAL_EXTINT3_NUM -#define OETH_IRQ XCHAL_EXTINT4_NUM -#else -#define DUART16552_INTNUM XCHAL_EXTINT0_NUM -#define OETH_IRQ XCHAL_EXTINT1_NUM -#endif - -/* - * Device addresses and parameters. - */ - -/* UART */ -#define DUART16552_PADDR (XCHAL_KIO_PADDR + 0x0D050020) -/* LCD instruction and data addresses. */ -#define LCD_INSTR_ADDR ((char *)IOADDR(0x0D040000)) -#define LCD_DATA_ADDR ((char *)IOADDR(0x0D040004)) - -/* Misc. */ -#define XTFPGA_FPGAREGS_VADDR IOADDR(0x0D020000) -/* Clock frequency in Hz (read-only): */ -#define XTFPGA_CLKFRQ_VADDR (XTFPGA_FPGAREGS_VADDR + 0x04) -/* Setting of 8 DIP switches: */ -#define DIP_SWITCHES_VADDR (XTFPGA_FPGAREGS_VADDR + 0x0C) -/* Software reset (write 0xdead): */ -#define XTFPGA_SWRST_VADDR (XTFPGA_FPGAREGS_VADDR + 0x10) - -/* OpenCores Ethernet controller: */ - /* regs + RX/TX descriptors */ -#define OETH_REGS_PADDR (XCHAL_KIO_PADDR + 0x0D030000) -#define OETH_REGS_SIZE 0x1000 -#define OETH_SRAMBUFF_PADDR (XCHAL_KIO_PADDR + 0x0D800000) - - /* 5*rx buffs + 5*tx buffs */ -#define OETH_SRAMBUFF_SIZE (5 * 0x600 + 5 * 0x600) - -#endif /* __XTENSA_XTAVNET_HARDWARE_H */ diff --git a/trunk/arch/xtensa/platforms/xtfpga/include/platform/lcd.h b/trunk/arch/xtensa/platforms/xtfpga/include/platform/lcd.h deleted file mode 100644 index 0e435645af5a..000000000000 --- a/trunk/arch/xtensa/platforms/xtfpga/include/platform/lcd.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * arch/xtensa/platform/xtavnet/include/platform/lcd.h - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2001, 2006 Tensilica Inc. - */ - -#ifndef __XTENSA_XTAVNET_LCD_H -#define __XTENSA_XTAVNET_LCD_H - -/* Display string STR at position POS on the LCD. */ -void lcd_disp_at_pos(char *str, unsigned char pos); - -/* Shift the contents of the LCD display left or right. */ -void lcd_shiftleft(void); -void lcd_shiftright(void); -#endif diff --git a/trunk/arch/xtensa/platforms/xtfpga/include/platform/serial.h b/trunk/arch/xtensa/platforms/xtfpga/include/platform/serial.h deleted file mode 100644 index 14d8f7beebfd..000000000000 --- a/trunk/arch/xtensa/platforms/xtfpga/include/platform/serial.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * arch/xtensa/platform/xtavnet/include/platform/serial.h - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2001, 2006 Tensilica Inc. - */ - -#ifndef __ASM_XTENSA_XTAVNET_SERIAL_H -#define __ASM_XTENSA_XTAVNET_SERIAL_H - -#include - -#define BASE_BAUD (*(long *)XTFPGA_CLKFRQ_VADDR / 16) - -#endif /* __ASM_XTENSA_XTAVNET_SERIAL_H */ diff --git a/trunk/arch/xtensa/platforms/xtfpga/lcd.c b/trunk/arch/xtensa/platforms/xtfpga/lcd.c deleted file mode 100644 index 2872301598df..000000000000 --- a/trunk/arch/xtensa/platforms/xtfpga/lcd.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Driver for the LCD display on the Tensilica LX60 Board. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2001, 2006 Tensilica Inc. - */ - -/* - * - * FIXME: this code is from the examples from the LX60 user guide. - * - * The lcd_pause function does busy waiting, which is probably not - * great. Maybe the code could be changed to use kernel timers, or - * change the hardware to not need to wait. - */ - -#include -#include - -#include -#include -#include - -#define LCD_PAUSE_ITERATIONS 4000 -#define LCD_CLEAR 0x1 -#define LCD_DISPLAY_ON 0xc - -/* 8bit and 2 lines display */ -#define LCD_DISPLAY_MODE8BIT 0x38 -#define LCD_DISPLAY_POS 0x80 -#define LCD_SHIFT_LEFT 0x18 -#define LCD_SHIFT_RIGHT 0x1c - -static int __init lcd_init(void) -{ - *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT; - mdelay(5); - *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT; - udelay(200); - *LCD_INSTR_ADDR = LCD_DISPLAY_MODE8BIT; - udelay(50); - *LCD_INSTR_ADDR = LCD_DISPLAY_ON; - udelay(50); - *LCD_INSTR_ADDR = LCD_CLEAR; - mdelay(10); - lcd_disp_at_pos("XTENSA LINUX", 0); - return 0; -} - -void lcd_disp_at_pos(char *str, unsigned char pos) -{ - *LCD_INSTR_ADDR = LCD_DISPLAY_POS | pos; - udelay(100); - while (*str != 0) { - *LCD_DATA_ADDR = *str; - udelay(200); - str++; - } -} - -void lcd_shiftleft(void) -{ - *LCD_INSTR_ADDR = LCD_SHIFT_LEFT; - udelay(50); -} - -void lcd_shiftright(void) -{ - *LCD_INSTR_ADDR = LCD_SHIFT_RIGHT; - udelay(50); -} - -arch_initcall(lcd_init); diff --git a/trunk/arch/xtensa/platforms/xtfpga/setup.c b/trunk/arch/xtensa/platforms/xtfpga/setup.c deleted file mode 100644 index 4b9951a4569d..000000000000 --- a/trunk/arch/xtensa/platforms/xtfpga/setup.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * - * arch/xtensa/platform/xtavnet/setup.c - * - * ... - * - * Authors: Chris Zankel - * Joe Taylor - * - * Copyright 2001 - 2006 Tensilica Inc. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -void platform_halt(void) -{ - lcd_disp_at_pos(" HALT ", 0); - local_irq_disable(); - while (1) - cpu_relax(); -} - -void platform_power_off(void) -{ - lcd_disp_at_pos("POWEROFF", 0); - local_irq_disable(); - while (1) - cpu_relax(); -} - -void platform_restart(void) -{ - /* Flush and reset the mmu, simulate a processor reset, and - * jump to the reset vector. */ - - - __asm__ __volatile__ ("movi a2, 15\n\t" - "wsr a2, icountlevel\n\t" - "movi a2, 0\n\t" - "wsr a2, icount\n\t" - "wsr a2, ibreakenable\n\t" - "wsr a2, lcount\n\t" - "movi a2, 0x1f\n\t" - "wsr a2, ps\n\t" - "isync\n\t" - "jx %0\n\t" - : - : "a" (XCHAL_RESET_VECTOR_VADDR) - : "a2" - ); - - /* control never gets here */ -} - -void __init platform_setup(char **cmdline) -{ -} - -#ifdef CONFIG_OF - -static void __init update_clock_frequency(struct device_node *node) -{ - struct property *newfreq; - u32 freq; - - if (!of_property_read_u32(node, "clock-frequency", &freq) && freq != 0) - return; - - newfreq = kzalloc(sizeof(*newfreq) + sizeof(u32), GFP_KERNEL); - if (!newfreq) - return; - newfreq->value = newfreq + 1; - newfreq->length = sizeof(freq); - newfreq->name = kstrdup("clock-frequency", GFP_KERNEL); - if (!newfreq->name) { - kfree(newfreq); - return; - } - - *(u32 *)newfreq->value = cpu_to_be32(*(u32 *)XTFPGA_CLKFRQ_VADDR); - prom_update_property(node, newfreq); -} - -#define MAC_LEN 6 -static void __init update_local_mac(struct device_node *node) -{ - struct property *newmac; - const u8* macaddr; - int prop_len; - - macaddr = of_get_property(node, "local-mac-address", &prop_len); - if (macaddr == NULL || prop_len != MAC_LEN) - return; - - newmac = kzalloc(sizeof(*newmac) + MAC_LEN, GFP_KERNEL); - if (newmac == NULL) - return; - - newmac->value = newmac + 1; - newmac->length = MAC_LEN; - newmac->name = kstrdup("local-mac-address", GFP_KERNEL); - if (newmac->name == NULL) { - kfree(newmac); - return; - } - - memcpy(newmac->value, macaddr, MAC_LEN); - ((u8*)newmac->value)[5] = (*(u32*)DIP_SWITCHES_VADDR) & 0x3f; - prom_update_property(node, newmac); -} - -static int __init machine_setup(void) -{ - struct device_node *serial; - struct device_node *eth = NULL; - - for_each_compatible_node(serial, NULL, "ns16550a") - update_clock_frequency(serial); - - if ((eth = of_find_compatible_node(eth, NULL, "opencores,ethoc"))) - update_local_mac(eth); - return 0; -} -arch_initcall(machine_setup); - -#endif - -/* early initialization */ - -void __init platform_init(bp_tag_t *first) -{ -} - -/* Heartbeat. */ - -void platform_heartbeat(void) -{ -} - -#ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT - -void platform_calibrate_ccount(void) -{ - long clk_freq = 0; -#ifdef CONFIG_OF - struct device_node *cpu = - of_find_compatible_node(NULL, NULL, "xtensa,cpu"); - if (cpu) { - u32 freq; - update_clock_frequency(cpu); - if (!of_property_read_u32(cpu, "clock-frequency", &freq)) - clk_freq = freq; - } -#endif - if (!clk_freq) - clk_freq = *(long *)XTFPGA_CLKFRQ_VADDR; - - ccount_per_jiffy = clk_freq / HZ; - nsec_per_ccount = 1000000000UL / clk_freq; -} - -#endif - -#ifndef CONFIG_OF - -#include -#include -#include - -/*---------------------------------------------------------------------------- - * Ethernet -- OpenCores Ethernet MAC (ethoc driver) - */ - -static struct resource ethoc_res[] __initdata = { - [0] = { /* register space */ - .start = OETH_REGS_PADDR, - .end = OETH_REGS_PADDR + OETH_REGS_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - [1] = { /* buffer space */ - .start = OETH_SRAMBUFF_PADDR, - .end = OETH_SRAMBUFF_PADDR + OETH_SRAMBUFF_SIZE - 1, - .flags = IORESOURCE_MEM, - }, - [2] = { /* IRQ number */ - .start = OETH_IRQ, - .end = OETH_IRQ, - .flags = IORESOURCE_IRQ, - }, -}; - -static struct ethoc_platform_data ethoc_pdata __initdata = { - /* - * The MAC address for these boards is 00:50:c2:13:6f:xx. - * The last byte (here as zero) is read from the DIP switches on the - * board. - */ - .hwaddr = { 0x00, 0x50, 0xc2, 0x13, 0x6f, 0 }, - .phy_id = -1, -}; - -static struct platform_device ethoc_device __initdata = { - .name = "ethoc", - .id = -1, - .num_resources = ARRAY_SIZE(ethoc_res), - .resource = ethoc_res, - .dev = { - .platform_data = ðoc_pdata, - }, -}; - -/*---------------------------------------------------------------------------- - * UART - */ - -static struct resource serial_resource __initdata = { - .start = DUART16552_PADDR, - .end = DUART16552_PADDR + 0x1f, - .flags = IORESOURCE_MEM, -}; - -static struct plat_serial8250_port serial_platform_data[] __initdata = { - [0] = { - .mapbase = DUART16552_PADDR, - .irq = DUART16552_INTNUM, - .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | - UPF_IOREMAP, - .iotype = UPIO_MEM32, - .regshift = 2, - .uartclk = 0, /* set in xtavnet_init() */ - }, - { }, -}; - -static struct platform_device xtavnet_uart __initdata = { - .name = "serial8250", - .id = PLAT8250_DEV_PLATFORM, - .dev = { - .platform_data = serial_platform_data, - }, - .num_resources = 1, - .resource = &serial_resource, -}; - -/* platform devices */ -static struct platform_device *platform_devices[] __initdata = { - ðoc_device, - &xtavnet_uart, -}; - - -static int __init xtavnet_init(void) -{ - /* Ethernet MAC address. */ - ethoc_pdata.hwaddr[5] = *(u32 *)DIP_SWITCHES_VADDR; - - /* Clock rate varies among FPGA bitstreams; board specific FPGA register - * reports the actual clock rate. - */ - serial_platform_data[0].uartclk = *(long *)XTFPGA_CLKFRQ_VADDR; - - - /* register platform devices */ - platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); - - /* ETHOC driver is a bit quiet; at least display Ethernet MAC, so user - * knows whether they set it correctly on the DIP switches. - */ - pr_info("XTFPGA: Ethernet MAC %pM\n", ethoc_pdata.hwaddr); - - return 0; -} - -/* - * Register to be done during do_initcalls(). - */ -arch_initcall(xtavnet_init); - -#endif /* CONFIG_OF */ diff --git a/trunk/arch/xtensa/variants/s6000/gpio.c b/trunk/arch/xtensa/variants/s6000/gpio.c index da9e85c13b08..b89541ba39ab 100644 --- a/trunk/arch/xtensa/variants/s6000/gpio.c +++ b/trunk/arch/xtensa/variants/s6000/gpio.c @@ -164,7 +164,7 @@ static void demux_irqs(unsigned int irq, struct irq_desc *desc) int cirq; chip->irq_mask(&desc->irq_data); - chip->irq_ack(&desc->irq_data); + chip->irq_ack(&desc->irq_data)); pending = readb(S6_REG_GPIO + S6_GPIO_BANK(0) + S6_GPIO_MIS) & *mask; cirq = IRQ_BASE - 1; while (pending) { @@ -173,7 +173,7 @@ static void demux_irqs(unsigned int irq, struct irq_desc *desc) pending >>= n; generic_handle_irq(cirq); } - chip->irq_unmask(&desc->irq_data); + chip->irq_unmask(&desc->irq_data)); } extern const signed char *platform_irq_mappings[XTENSA_NR_IRQS]; diff --git a/trunk/drivers/bcma/driver_chipcommon_pmu.c b/trunk/drivers/bcma/driver_chipcommon_pmu.c index c62c788b3289..e162999bf916 100644 --- a/trunk/drivers/bcma/driver_chipcommon_pmu.c +++ b/trunk/drivers/bcma/driver_chipcommon_pmu.c @@ -13,13 +13,12 @@ #include #include -u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset) +static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset) { bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset); bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR); return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA); } -EXPORT_SYMBOL_GPL(bcma_chipco_pll_read); void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value) { diff --git a/trunk/drivers/char/random.c b/trunk/drivers/char/random.c index 85e81ec1451e..b86eae9b77df 100644 --- a/trunk/drivers/char/random.c +++ b/trunk/drivers/char/random.c @@ -399,6 +399,7 @@ static DECLARE_WAIT_QUEUE_HEAD(random_read_wait); static DECLARE_WAIT_QUEUE_HEAD(random_write_wait); static struct fasync_struct *fasync; +#if 0 static bool debug; module_param(debug, bool, 0644); #define DEBUG_ENT(fmt, arg...) do { \ @@ -409,6 +410,9 @@ module_param(debug, bool, 0644); blocking_pool.entropy_count,\ nonblocking_pool.entropy_count,\ ## arg); } while (0) +#else +#define DEBUG_ENT(fmt, arg...) do {} while (0) +#endif /********************************************************************** * @@ -433,7 +437,6 @@ struct entropy_store { int entropy_count; int entropy_total; unsigned int initialized:1; - bool last_data_init; __u8 last_data[EXTRACT_SIZE]; }; @@ -826,7 +829,7 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes) bytes = min_t(int, bytes, sizeof(tmp)); DEBUG_ENT("going to reseed %s with %d bits " - "(%zu of %d requested)\n", + "(%d of %d requested)\n", r->name, bytes * 8, nbytes * 8, r->entropy_count); bytes = extract_entropy(r->pull, tmp, bytes, @@ -857,7 +860,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, spin_lock_irqsave(&r->lock, flags); BUG_ON(r->entropy_count > r->poolinfo->POOLBITS); - DEBUG_ENT("trying to extract %zu bits from %s\n", + DEBUG_ENT("trying to extract %d bits from %s\n", nbytes * 8, r->name); /* Can we pull enough? */ @@ -879,7 +882,7 @@ static size_t account(struct entropy_store *r, size_t nbytes, int min, } } - DEBUG_ENT("debiting %zu entropy credits from %s%s\n", + DEBUG_ENT("debiting %d entropy credits from %s%s\n", nbytes * 8, r->name, r->limit ? "" : " (unlimited)"); spin_unlock_irqrestore(&r->lock, flags); @@ -954,10 +957,6 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, ssize_t ret = 0, i; __u8 tmp[EXTRACT_SIZE]; - /* if last_data isn't primed, we need EXTRACT_SIZE extra bytes */ - if (fips_enabled && !r->last_data_init) - nbytes += EXTRACT_SIZE; - trace_extract_entropy(r->name, nbytes, r->entropy_count, _RET_IP_); xfer_secondary_pool(r, nbytes); nbytes = account(r, nbytes, min, reserved); @@ -968,17 +967,6 @@ static ssize_t extract_entropy(struct entropy_store *r, void *buf, if (fips_enabled) { unsigned long flags; - - /* prime last_data value if need be, per fips 140-2 */ - if (!r->last_data_init) { - spin_lock_irqsave(&r->lock, flags); - memcpy(r->last_data, tmp, EXTRACT_SIZE); - r->last_data_init = true; - nbytes -= EXTRACT_SIZE; - spin_unlock_irqrestore(&r->lock, flags); - extract_buf(r, tmp); - } - spin_lock_irqsave(&r->lock, flags); if (!memcmp(tmp, r->last_data, EXTRACT_SIZE)) panic("Hardware RNG duplicated output!\n"); @@ -1098,7 +1086,6 @@ static void init_std_data(struct entropy_store *r) r->entropy_count = 0; r->entropy_total = 0; - r->last_data_init = false; mix_pool_bytes(r, &now, sizeof(now), NULL); for (i = r->poolinfo->POOLBYTES; i > 0; i -= sizeof(rv)) { if (!arch_get_random_long(&rv)) @@ -1155,16 +1142,11 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) if (n > SEC_XFER_SIZE) n = SEC_XFER_SIZE; - DEBUG_ENT("reading %zu bits\n", n*8); + DEBUG_ENT("reading %d bits\n", n*8); n = extract_entropy_user(&blocking_pool, buf, n); - if (n < 0) { - retval = n; - break; - } - - DEBUG_ENT("read got %zd bits (%zd still needed)\n", + DEBUG_ENT("read got %d bits (%d still needed)\n", n*8, (nbytes-n)*8); if (n == 0) { @@ -1189,6 +1171,10 @@ random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) continue; } + if (n < 0) { + retval = n; + break; + } count += n; buf += n; nbytes -= n; diff --git a/trunk/drivers/clk/clk-nomadik.c b/trunk/drivers/clk/clk-nomadik.c index 6b4c70f7d23d..517a8ff7121e 100644 --- a/trunk/drivers/clk/clk-nomadik.c +++ b/trunk/drivers/clk/clk-nomadik.c @@ -20,7 +20,6 @@ void __init nomadik_clk_init(void) clk_register_clkdev(clk, NULL, "gpio.2"); clk_register_clkdev(clk, NULL, "gpio.3"); clk_register_clkdev(clk, NULL, "rng"); - clk_register_clkdev(clk, NULL, "fsmc-nand"); /* * The 2.4 MHz TIMCLK reference clock is active at boot time, this is diff --git a/trunk/drivers/gpu/drm/ttm/ttm_bo.c b/trunk/drivers/gpu/drm/ttm/ttm_bo.c index 33d20be87db5..a9151337d5b9 100644 --- a/trunk/drivers/gpu/drm/ttm/ttm_bo.c +++ b/trunk/drivers/gpu/drm/ttm/ttm_bo.c @@ -579,7 +579,7 @@ static int ttm_bo_cleanup_refs_and_unlock(struct ttm_buffer_object *bo, * at this point the buffer should be dead, so * no new sync objects can be attached. */ - sync_obj = driver->sync_obj_ref(bo->sync_obj); + sync_obj = driver->sync_obj_ref(&bo->sync_obj); spin_unlock(&bdev->fence_lock); atomic_set(&bo->reserved, 0); diff --git a/trunk/drivers/input/serio/i8042-x86ia64io.h b/trunk/drivers/input/serio/i8042-x86ia64io.h index 5f306f79da0c..d6cc77a53c7e 100644 --- a/trunk/drivers/input/serio/i8042-x86ia64io.h +++ b/trunk/drivers/input/serio/i8042-x86ia64io.h @@ -921,7 +921,6 @@ static int __init i8042_platform_init(void) int retval; #ifdef CONFIG_X86 - u8 a20_on = 0xdf; /* Just return if pre-detection shows no i8042 controller exist */ if (!x86_platform.i8042_detect()) return -ENODEV; @@ -961,14 +960,6 @@ static int __init i8042_platform_init(void) if (dmi_check_system(i8042_dmi_dritek_table)) i8042_dritek = true; - - /* - * A20 was already enabled during early kernel init. But some buggy - * BIOSes (in MSI Laptops) require A20 to be enabled using 8042 to - * resume from S3. So we do it here and hope that nothing breaks. - */ - i8042_command(&a20_on, 0x10d1); - i8042_command(NULL, 0x00ff); /* Null command for SMM firmware */ #endif /* CONFIG_X86 */ return retval; diff --git a/trunk/drivers/mtd/ar7part.c b/trunk/drivers/mtd/ar7part.c index 7c057a05adb6..945393129952 100644 --- a/trunk/drivers/mtd/ar7part.c +++ b/trunk/drivers/mtd/ar7part.c @@ -26,16 +26,19 @@ #include #include #include +#include #include -#include - #define AR7_PARTS 4 #define ROOT_OFFSET 0xe0000 #define LOADER_MAGIC1 le32_to_cpu(0xfeedfa42) #define LOADER_MAGIC2 le32_to_cpu(0xfeed1281) +#ifndef SQUASHFS_MAGIC +#define SQUASHFS_MAGIC 0x73717368 +#endif + struct ar7_bin_rec { unsigned int checksum; unsigned int length; diff --git a/trunk/drivers/mtd/bcm63xxpart.c b/trunk/drivers/mtd/bcm63xxpart.c index 6eeb84c81bc2..63d2a64331f7 100644 --- a/trunk/drivers/mtd/bcm63xxpart.c +++ b/trunk/drivers/mtd/bcm63xxpart.c @@ -37,7 +37,8 @@ #define BCM63XX_EXTENDED_SIZE 0xBFC00000 /* Extended flash address */ -#define BCM63XX_CFE_BLOCK_SIZE 0x10000 /* always at least 64KiB */ +#define BCM63XX_MIN_CFE_SIZE 0x10000 /* always at least 64KiB */ +#define BCM63XX_MIN_NVRAM_SIZE 0x10000 /* always at least 64KiB */ #define BCM63XX_CFE_MAGIC_OFFSET 0x4e0 @@ -78,7 +79,7 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, unsigned int rootfsaddr, kerneladdr, spareaddr; unsigned int rootfslen, kernellen, sparelen, totallen; unsigned int cfelen, nvramlen; - unsigned int cfe_erasesize; + int namelen = 0; int i; u32 computed_crc; bool rootfs_first = false; @@ -86,11 +87,8 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, if (bcm63xx_detect_cfe(master)) return -EINVAL; - cfe_erasesize = max_t(uint32_t, master->erasesize, - BCM63XX_CFE_BLOCK_SIZE); - - cfelen = cfe_erasesize; - nvramlen = cfe_erasesize; + cfelen = max_t(uint32_t, master->erasesize, BCM63XX_MIN_CFE_SIZE); + nvramlen = max_t(uint32_t, master->erasesize, BCM63XX_MIN_NVRAM_SIZE); /* Allocate memory for buffer */ buf = vmalloc(sizeof(struct bcm_tag)); @@ -123,6 +121,7 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, kerneladdr = kerneladdr - BCM63XX_EXTENDED_SIZE; rootfsaddr = rootfsaddr - BCM63XX_EXTENDED_SIZE; spareaddr = roundup(totallen, master->erasesize) + cfelen; + sparelen = master->size - spareaddr - nvramlen; if (rootfsaddr < kerneladdr) { /* default Broadcom layout */ @@ -140,15 +139,19 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, rootfslen = 0; rootfsaddr = 0; spareaddr = cfelen; + sparelen = master->size - cfelen - nvramlen; } - sparelen = master->size - spareaddr - nvramlen; /* Determine number of partitions */ - if (rootfslen > 0) + namelen = 8; + if (rootfslen > 0) { nrparts++; - - if (kernellen > 0) + namelen += 6; + } + if (kernellen > 0) { nrparts++; + namelen += 6; + } /* Ask kernel for more memory */ parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL); @@ -190,16 +193,17 @@ static int bcm63xx_parse_cfe_partitions(struct mtd_info *master, parts[curpart].name = "nvram"; parts[curpart].offset = master->size - nvramlen; parts[curpart].size = nvramlen; - curpart++; /* Global partition "linux" to make easy firmware upgrade */ + curpart++; parts[curpart].name = "linux"; parts[curpart].offset = cfelen; parts[curpart].size = master->size - cfelen - nvramlen; for (i = 0; i < nrparts; i++) - pr_info("Partition %d is %s offset %llx and length %llx\n", i, - parts[i].name, parts[i].offset, parts[i].size); + pr_info("Partition %d is %s offset %lx and length %lx\n", i, + parts[i].name, (long unsigned int)(parts[i].offset), + (long unsigned int)(parts[i].size)); pr_info("Spare partition is offset %x and length %x\n", spareaddr, sparelen); diff --git a/trunk/drivers/mtd/chips/cfi_cmdset_0002.c b/trunk/drivers/mtd/chips/cfi_cmdset_0002.c index b86197286f24..5ff5c4a16943 100644 --- a/trunk/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/trunk/drivers/mtd/chips/cfi_cmdset_0002.c @@ -1536,20 +1536,8 @@ static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip, UDELAY(map, chip, adr, 1); } - /* - * Recovery from write-buffer programming failures requires - * the write-to-buffer-reset sequence. Since the last part - * of the sequence also works as a normal reset, we can run - * the same commands regardless of why we are here. - * See e.g. - * http://www.spansion.com/Support/Application%20Notes/MirrorBit_Write_Buffer_Prog_Page_Buffer_Read_AN.pdf - */ - cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi, - cfi->device_type, NULL); - cfi_send_gen_cmd(0x55, cfi->addr_unlock2, chip->start, map, cfi, - cfi->device_type, NULL); - cfi_send_gen_cmd(0xF0, cfi->addr_unlock1, chip->start, map, cfi, - cfi->device_type, NULL); + /* reset on all failures. */ + map_write( map, CMD(0xF0), chip->start ); xip_enable(map, chip, adr); /* FIXME - should have reset delay before continuing */ diff --git a/trunk/drivers/mtd/cmdlinepart.c b/trunk/drivers/mtd/cmdlinepart.c index c533f27d863f..aed1b8a63c9f 100644 --- a/trunk/drivers/mtd/cmdlinepart.c +++ b/trunk/drivers/mtd/cmdlinepart.c @@ -56,8 +56,8 @@ /* special size referring to all the remaining space in a partition */ -#define SIZE_REMAINING ULLONG_MAX -#define OFFSET_CONTINUOUS ULLONG_MAX +#define SIZE_REMAINING UINT_MAX +#define OFFSET_CONTINUOUS UINT_MAX struct cmdline_mtd_partition { struct cmdline_mtd_partition *next; @@ -89,7 +89,7 @@ static struct mtd_partition * newpart(char *s, int extra_mem_size) { struct mtd_partition *parts; - unsigned long long size, offset = OFFSET_CONTINUOUS; + unsigned long size, offset = OFFSET_CONTINUOUS; char *name; int name_len; unsigned char *extra_mem; @@ -104,8 +104,7 @@ static struct mtd_partition * newpart(char *s, } else { size = memparse(s, &s); if (size < PAGE_SIZE) { - printk(KERN_ERR ERRP "partition size too small (%llx)\n", - size); + printk(KERN_ERR ERRP "partition size too small (%lx)\n", size); return ERR_PTR(-EINVAL); } } @@ -297,7 +296,7 @@ static int parse_cmdline_partitions(struct mtd_info *master, struct mtd_partition **pparts, struct mtd_part_parser_data *data) { - unsigned long long offset; + unsigned long offset; int i, err; struct cmdline_mtd_partition *part; const char *mtd_id = master->name; @@ -309,52 +308,48 @@ static int parse_cmdline_partitions(struct mtd_info *master, return err; } - /* - * Search for the partition definition matching master->name. - * If master->name is not set, stop at first partition definition. - */ for (part = partitions; part; part = part->next) { - if ((!mtd_id) || (!strcmp(part->mtd_id, mtd_id))) - break; - } - - if (!part) - return 0; - - for (i = 0, offset = 0; i < part->num_parts; i++) { - if (part->parts[i].offset == OFFSET_CONTINUOUS) - part->parts[i].offset = offset; - else - offset = part->parts[i].offset; - - if (part->parts[i].size == SIZE_REMAINING) - part->parts[i].size = master->size - offset; - - if (part->parts[i].size == 0) { - printk(KERN_WARNING ERRP - "%s: skipping zero sized partition\n", - part->mtd_id); - part->num_parts--; - memmove(&part->parts[i], &part->parts[i + 1], - sizeof(*part->parts) * (part->num_parts - i)); - continue; + if ((!mtd_id) || (!strcmp(part->mtd_id, mtd_id))) { + for (i = 0, offset = 0; i < part->num_parts; i++) { + if (part->parts[i].offset == OFFSET_CONTINUOUS) + part->parts[i].offset = offset; + else + offset = part->parts[i].offset; + + if (part->parts[i].size == SIZE_REMAINING) + part->parts[i].size = master->size - offset; + + if (part->parts[i].size == 0) { + printk(KERN_WARNING ERRP + "%s: skipping zero sized partition\n", + part->mtd_id); + part->num_parts--; + memmove(&part->parts[i], + &part->parts[i + 1], + sizeof(*part->parts) * (part->num_parts - i)); + continue; + } + + if (offset + part->parts[i].size > master->size) { + printk(KERN_WARNING ERRP + "%s: partitioning exceeds flash size, truncating\n", + part->mtd_id); + part->parts[i].size = master->size - offset; + } + offset += part->parts[i].size; + } + + *pparts = kmemdup(part->parts, + sizeof(*part->parts) * part->num_parts, + GFP_KERNEL); + if (!*pparts) + return -ENOMEM; + + return part->num_parts; } - - if (offset + part->parts[i].size > master->size) { - printk(KERN_WARNING ERRP - "%s: partitioning exceeds flash size, truncating\n", - part->mtd_id); - part->parts[i].size = master->size - offset; - } - offset += part->parts[i].size; } - *pparts = kmemdup(part->parts, sizeof(*part->parts) * part->num_parts, - GFP_KERNEL); - if (!*pparts) - return -ENOMEM; - - return part->num_parts; + return 0; } diff --git a/trunk/drivers/mtd/devices/bcm47xxsflash.c b/trunk/drivers/mtd/devices/bcm47xxsflash.c index 4714584aa993..2dc5a6f3fd57 100644 --- a/trunk/drivers/mtd/devices/bcm47xxsflash.c +++ b/trunk/drivers/mtd/devices/bcm47xxsflash.c @@ -66,7 +66,7 @@ static int bcm47xxsflash_probe(struct platform_device *pdev) return err; } -static int bcm47xxsflash_remove(struct platform_device *pdev) +static int __devexit bcm47xxsflash_remove(struct platform_device *pdev) { struct bcma_sflash *sflash = dev_get_platdata(&pdev->dev); @@ -77,7 +77,7 @@ static int bcm47xxsflash_remove(struct platform_device *pdev) } static struct platform_driver bcma_sflash_driver = { - .remove = bcm47xxsflash_remove, + .remove = __devexit_p(bcm47xxsflash_remove), .driver = { .name = "bcma_sflash", .owner = THIS_MODULE, diff --git a/trunk/drivers/mtd/devices/block2mtd.c b/trunk/drivers/mtd/devices/block2mtd.c index e081bfeaaf7d..681e2ee0f2d6 100644 --- a/trunk/drivers/mtd/devices/block2mtd.c +++ b/trunk/drivers/mtd/devices/block2mtd.c @@ -62,7 +62,6 @@ static int _block2mtd_erase(struct block2mtd_dev *dev, loff_t to, size_t len) memset(page_address(page), 0xff, PAGE_SIZE); set_page_dirty(page); unlock_page(page); - balance_dirty_pages_ratelimited(mapping); break; } @@ -153,7 +152,6 @@ static int _block2mtd_write(struct block2mtd_dev *dev, const u_char *buf, memcpy(page_address(page) + offset, buf, cpylen); set_page_dirty(page); unlock_page(page); - balance_dirty_pages_ratelimited(mapping); } page_cache_release(page); @@ -435,7 +433,7 @@ static int __init block2mtd_init(void) } -static void block2mtd_exit(void) +static void __devexit block2mtd_exit(void) { struct list_head *pos, *next; diff --git a/trunk/drivers/mtd/devices/docg3.c b/trunk/drivers/mtd/devices/docg3.c index 8510ccb9c6f0..d34d83b8f9c2 100644 --- a/trunk/drivers/mtd/devices/docg3.c +++ b/trunk/drivers/mtd/devices/docg3.c @@ -1440,7 +1440,7 @@ static int doc_write_oob(struct mtd_info *mtd, loff_t ofs, oobdelta = mtd->ecclayout->oobavail; break; default: - return -EINVAL; + oobdelta = 0; } if ((len % DOC_LAYOUT_PAGE_SIZE) || (ooblen % oobdelta) || (ofs % DOC_LAYOUT_PAGE_SIZE)) diff --git a/trunk/drivers/mtd/devices/docprobe.c b/trunk/drivers/mtd/devices/docprobe.c index 88b3fd3e18a7..706b847b46b3 100644 --- a/trunk/drivers/mtd/devices/docprobe.c +++ b/trunk/drivers/mtd/devices/docprobe.c @@ -70,6 +70,8 @@ static unsigned long __initdata doc_locations[] = { 0xe0000, 0xe2000, 0xe4000, 0xe6000, 0xe8000, 0xea000, 0xec000, 0xee000, #endif /* CONFIG_MTD_DOCPROBE_HIGH */ +#else +#warning Unknown architecture for DiskOnChip. No default probe locations defined #endif 0xffffffff }; diff --git a/trunk/drivers/mtd/devices/m25p80.c b/trunk/drivers/mtd/devices/m25p80.c index 4eeeb2d7f6ea..03838bab1f59 100644 --- a/trunk/drivers/mtd/devices/m25p80.c +++ b/trunk/drivers/mtd/devices/m25p80.c @@ -73,6 +73,14 @@ #define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */ #define MAX_CMD_SIZE 5 +#ifdef CONFIG_M25PXX_USE_FAST_READ +#define OPCODE_READ OPCODE_FAST_READ +#define FAST_READ_DUMMY_BYTE 1 +#else +#define OPCODE_READ OPCODE_NORM_READ +#define FAST_READ_DUMMY_BYTE 0 +#endif + #define JEDEC_MFR(_jedec_id) ((_jedec_id) >> 16) /****************************************************************************/ @@ -85,7 +93,6 @@ struct m25p { u16 addr_width; u8 erase_opcode; u8 *command; - bool fast_read; }; static inline struct m25p *mtd_to_m25p(struct mtd_info *mtd) @@ -161,7 +168,6 @@ static inline int set_4byte(struct m25p *flash, u32 jedec_id, int enable) { switch (JEDEC_MFR(jedec_id)) { case CFI_MFR_MACRONIX: - case 0xEF /* winbond */: flash->command[0] = enable ? OPCODE_EN4B : OPCODE_EX4B; return spi_write(flash->spi, flash->command, 1); default: @@ -336,7 +342,6 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, struct m25p *flash = mtd_to_m25p(mtd); struct spi_transfer t[2]; struct spi_message m; - uint8_t opcode; pr_debug("%s: %s from 0x%08x, len %zd\n", dev_name(&flash->spi->dev), __func__, (u32)from, len); @@ -349,7 +354,7 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, * Should add 1 byte DUMMY_BYTE. */ t[0].tx_buf = flash->command; - t[0].len = m25p_cmdsz(flash) + (flash->fast_read ? 1 : 0); + t[0].len = m25p_cmdsz(flash) + FAST_READ_DUMMY_BYTE; spi_message_add_tail(&t[0], &m); t[1].rx_buf = buf; @@ -371,14 +376,12 @@ static int m25p80_read(struct mtd_info *mtd, loff_t from, size_t len, */ /* Set up the write data buffer. */ - opcode = flash->fast_read ? OPCODE_FAST_READ : OPCODE_NORM_READ; - flash->command[0] = opcode; + flash->command[0] = OPCODE_READ; m25p_addr2cmd(flash, from, flash->command); spi_sync(flash->spi, &m); - *retlen = m.actual_length - m25p_cmdsz(flash) - - (flash->fast_read ? 1 : 0); + *retlen = m.actual_length - m25p_cmdsz(flash) - FAST_READ_DUMMY_BYTE; mutex_unlock(&flash->lock); @@ -661,8 +664,7 @@ static const struct spi_device_id m25p_ids[] = { { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, /* Micron */ - { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, 0) }, - { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, 0) }, + { "n25q128", INFO(0x20ba18, 0, 64 * 1024, 256, 0) }, { "n25q256a", INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K) }, /* Spansion -- single (large) sector size only, at least @@ -743,8 +745,6 @@ static const struct spi_device_id m25p_ids[] = { { "w25x64", INFO(0xef3017, 0, 64 * 1024, 128, SECT_4K) }, { "w25q64", INFO(0xef4017, 0, 64 * 1024, 128, SECT_4K) }, { "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) }, - { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) }, - { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K) }, /* Catalyst / On Semiconductor -- non-JEDEC */ { "cat25c11", CAT25_INFO( 16, 8, 16, 1) }, @@ -756,7 +756,7 @@ static const struct spi_device_id m25p_ids[] = { }; MODULE_DEVICE_TABLE(spi, m25p_ids); -static const struct spi_device_id *jedec_probe(struct spi_device *spi) +static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi) { int tmp; u8 code = OPCODE_RDID; @@ -801,7 +801,7 @@ static const struct spi_device_id *jedec_probe(struct spi_device *spi) * matches what the READ command supports, at least until this driver * understands FAST_READ (for clocks over 25 MHz). */ -static int m25p_probe(struct spi_device *spi) +static int __devinit m25p_probe(struct spi_device *spi) { const struct spi_device_id *id = spi_get_device_id(spi); struct flash_platform_data *data; @@ -809,10 +809,9 @@ static int m25p_probe(struct spi_device *spi) struct flash_info *info; unsigned i; struct mtd_part_parser_data ppdata; - struct device_node __maybe_unused *np = spi->dev.of_node; #ifdef CONFIG_MTD_OF_PARTS - if (!of_device_is_available(np)) + if (!of_device_is_available(spi->dev.of_node)) return -ENODEV; #endif @@ -864,8 +863,7 @@ static int m25p_probe(struct spi_device *spi) flash = kzalloc(sizeof *flash, GFP_KERNEL); if (!flash) return -ENOMEM; - flash->command = kmalloc(MAX_CMD_SIZE + (flash->fast_read ? 1 : 0), - GFP_KERNEL); + flash->command = kmalloc(MAX_CMD_SIZE + FAST_READ_DUMMY_BYTE, GFP_KERNEL); if (!flash->command) { kfree(flash); return -ENOMEM; @@ -922,16 +920,6 @@ static int m25p_probe(struct spi_device *spi) flash->page_size = info->page_size; flash->mtd.writebufsize = flash->page_size; - flash->fast_read = false; -#ifdef CONFIG_OF - if (np && of_property_read_bool(np, "m25p,fast-read")) - flash->fast_read = true; -#endif - -#ifdef CONFIG_M25PXX_USE_FAST_READ - flash->fast_read = true; -#endif - if (info->addr_width) flash->addr_width = info->addr_width; else { @@ -973,7 +961,7 @@ static int m25p_probe(struct spi_device *spi) } -static int m25p_remove(struct spi_device *spi) +static int __devexit m25p_remove(struct spi_device *spi) { struct m25p *flash = dev_get_drvdata(&spi->dev); int status; @@ -995,7 +983,7 @@ static struct spi_driver m25p80_driver = { }, .id_table = m25p_ids, .probe = m25p_probe, - .remove = m25p_remove, + .remove = __devexit_p(m25p_remove), /* REVISIT: many of these chips have deep power-down modes, which * should clearly be entered on suspend() to minimize power use. diff --git a/trunk/drivers/mtd/devices/mtd_dataflash.c b/trunk/drivers/mtd/devices/mtd_dataflash.c index ea7ea7b595d8..928fb0e6d73a 100644 --- a/trunk/drivers/mtd/devices/mtd_dataflash.c +++ b/trunk/drivers/mtd/devices/mtd_dataflash.c @@ -618,7 +618,7 @@ static char *otp_setup(struct mtd_info *device, char revision) /* * Register DataFlash device with MTD subsystem. */ -static int +static int __devinit add_dataflash_otp(struct spi_device *spi, char *name, int nr_pages, int pagesize, int pageoffset, char revision) { @@ -679,7 +679,7 @@ add_dataflash_otp(struct spi_device *spi, char *name, return err; } -static inline int +static inline int __devinit add_dataflash(struct spi_device *spi, char *name, int nr_pages, int pagesize, int pageoffset) { @@ -705,7 +705,7 @@ struct flash_info { #define IS_POW2PS 0x0001 /* uses 2^N byte pages */ }; -static struct flash_info dataflash_data[] = { +static struct flash_info __devinitdata dataflash_data [] = { /* * NOTE: chips with SUP_POW2PS (rev D and up) need two entries, @@ -740,7 +740,7 @@ static struct flash_info dataflash_data[] = { { "at45db642d", 0x1f2800, 8192, 1024, 10, SUP_POW2PS | IS_POW2PS}, }; -static struct flash_info *jedec_probe(struct spi_device *spi) +static struct flash_info *__devinit jedec_probe(struct spi_device *spi) { int tmp; uint8_t code = OP_READ_ID; @@ -823,7 +823,7 @@ static struct flash_info *jedec_probe(struct spi_device *spi) * AT45DB0642 64Mbit (8M) xx111xxx (0x3c) 8192 1056 11 * AT45DB1282 128Mbit (16M) xx0100xx (0x10) 16384 1056 11 */ -static int dataflash_probe(struct spi_device *spi) +static int __devinit dataflash_probe(struct spi_device *spi) { int status; struct flash_info *info; @@ -897,7 +897,7 @@ static int dataflash_probe(struct spi_device *spi) return status; } -static int dataflash_remove(struct spi_device *spi) +static int __devexit dataflash_remove(struct spi_device *spi) { struct dataflash *flash = dev_get_drvdata(&spi->dev); int status; @@ -920,7 +920,7 @@ static struct spi_driver dataflash_driver = { }, .probe = dataflash_probe, - .remove = dataflash_remove, + .remove = __devexit_p(dataflash_remove), /* FIXME: investigate suspend and resume... */ }; diff --git a/trunk/drivers/mtd/devices/spear_smi.c b/trunk/drivers/mtd/devices/spear_smi.c index 2d2c2a5d4d2a..dcc3c9511530 100644 --- a/trunk/drivers/mtd/devices/spear_smi.c +++ b/trunk/drivers/mtd/devices/spear_smi.c @@ -756,7 +756,7 @@ static int spear_smi_probe_flash(struct spear_smi *dev, u32 bank) #ifdef CONFIG_OF -static int spear_smi_probe_config_dt(struct platform_device *pdev, +static int __devinit spear_smi_probe_config_dt(struct platform_device *pdev, struct device_node *np) { struct spear_smi_plat_data *pdata = dev_get_platdata(&pdev->dev); @@ -799,7 +799,7 @@ static int spear_smi_probe_config_dt(struct platform_device *pdev, return 0; } #else -static int spear_smi_probe_config_dt(struct platform_device *pdev, +static int __devinit spear_smi_probe_config_dt(struct platform_device *pdev, struct device_node *np) { return -ENOSYS; @@ -901,7 +901,7 @@ static int spear_smi_setup_banks(struct platform_device *pdev, * and do proper init for any found one. * Returns 0 on success, non zero otherwise */ -static int spear_smi_probe(struct platform_device *pdev) +static int __devinit spear_smi_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; struct spear_smi_plat_data *pdata = NULL; @@ -1016,7 +1016,7 @@ static int spear_smi_probe(struct platform_device *pdev) * * free all allocations and delete the partitions. */ -static int spear_smi_remove(struct platform_device *pdev) +static int __devexit spear_smi_remove(struct platform_device *pdev) { struct spear_smi *dev; struct spear_snor_flash *flash; @@ -1092,9 +1092,20 @@ static struct platform_driver spear_smi_driver = { #endif }, .probe = spear_smi_probe, - .remove = spear_smi_remove, + .remove = __devexit_p(spear_smi_remove), }; -module_platform_driver(spear_smi_driver); + +static int spear_smi_init(void) +{ + return platform_driver_register(&spear_smi_driver); +} +module_init(spear_smi_init); + +static void spear_smi_exit(void) +{ + platform_driver_unregister(&spear_smi_driver); +} +module_exit(spear_smi_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Ashish Priyadarshi, Shiraz Hashim "); diff --git a/trunk/drivers/mtd/devices/sst25l.c b/trunk/drivers/mtd/devices/sst25l.c index 8091b0163694..ab8a2f4c8d60 100644 --- a/trunk/drivers/mtd/devices/sst25l.c +++ b/trunk/drivers/mtd/devices/sst25l.c @@ -64,7 +64,7 @@ struct flash_info { #define to_sst25l_flash(x) container_of(x, struct sst25l_flash, mtd) -static struct flash_info sst25l_flash_info[] = { +static struct flash_info __devinitdata sst25l_flash_info[] = { {"sst25lf020a", 0xbf43, 256, 1024, 4096}, {"sst25lf040a", 0xbf44, 256, 2048, 4096}, }; @@ -313,7 +313,7 @@ static int sst25l_write(struct mtd_info *mtd, loff_t to, size_t len, return ret; } -static struct flash_info *sst25l_match_device(struct spi_device *spi) +static struct flash_info *__devinit sst25l_match_device(struct spi_device *spi) { struct flash_info *flash_info = NULL; struct spi_message m; @@ -353,7 +353,7 @@ static struct flash_info *sst25l_match_device(struct spi_device *spi) return flash_info; } -static int sst25l_probe(struct spi_device *spi) +static int __devinit sst25l_probe(struct spi_device *spi) { struct flash_info *flash_info; struct sst25l_flash *flash; @@ -411,7 +411,7 @@ static int sst25l_probe(struct spi_device *spi) return 0; } -static int sst25l_remove(struct spi_device *spi) +static int __devexit sst25l_remove(struct spi_device *spi) { struct sst25l_flash *flash = dev_get_drvdata(&spi->dev); int ret; @@ -428,7 +428,7 @@ static struct spi_driver sst25l_driver = { .owner = THIS_MODULE, }, .probe = sst25l_probe, - .remove = sst25l_remove, + .remove = __devexit_p(sst25l_remove), }; module_spi_driver(sst25l_driver); diff --git a/trunk/drivers/mtd/maps/Kconfig b/trunk/drivers/mtd/maps/Kconfig index 62ba82c396c2..df304868bebb 100644 --- a/trunk/drivers/mtd/maps/Kconfig +++ b/trunk/drivers/mtd/maps/Kconfig @@ -358,6 +358,13 @@ config MTD_IXP2000 IXP2000 based board and would like to use the flash chips on it, say 'Y'. +config MTD_FORTUNET + tristate "CFI Flash device mapped on the FortuNet board" + depends on MTD_CFI && SA1100_FORTUNET + help + This enables access to the Flash on the FortuNet board. If you + have such a board, say 'Y'. + config MTD_AUTCPU12 bool "NV-RAM mapping AUTCPU12 board" depends on ARCH_AUTCPU12 diff --git a/trunk/drivers/mtd/maps/Makefile b/trunk/drivers/mtd/maps/Makefile index 4ded28711bc1..a0240edd1961 100644 --- a/trunk/drivers/mtd/maps/Makefile +++ b/trunk/drivers/mtd/maps/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_MTD_SOLUTIONENGINE)+= solutionengine.o obj-$(CONFIG_MTD_PCI) += pci.o obj-$(CONFIG_MTD_AUTCPU12) += autcpu12-nvram.o obj-$(CONFIG_MTD_IMPA7) += impa7.o +obj-$(CONFIG_MTD_FORTUNET) += fortunet.o obj-$(CONFIG_MTD_UCLINUX) += uclinux.o obj-$(CONFIG_MTD_NETtel) += nettel.o obj-$(CONFIG_MTD_SCB2_FLASH) += scb2_flash.o diff --git a/trunk/drivers/mtd/maps/amd76xrom.c b/trunk/drivers/mtd/maps/amd76xrom.c index f7207b0a76dc..e2875d6fe129 100644 --- a/trunk/drivers/mtd/maps/amd76xrom.c +++ b/trunk/drivers/mtd/maps/amd76xrom.c @@ -100,8 +100,8 @@ static void amd76xrom_cleanup(struct amd76xrom_window *window) } -static int amd76xrom_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) +static int __devinit amd76xrom_init_one (struct pci_dev *pdev, + const struct pci_device_id *ent) { static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; u8 byte; @@ -289,7 +289,7 @@ static int amd76xrom_init_one(struct pci_dev *pdev, } -static void amd76xrom_remove_one(struct pci_dev *pdev) +static void __devexit amd76xrom_remove_one (struct pci_dev *pdev) { struct amd76xrom_window *window = &amd76xrom_window; @@ -347,3 +347,4 @@ module_exit(cleanup_amd76xrom); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Eric Biederman "); MODULE_DESCRIPTION("MTD map driver for BIOS chips on the AMD76X southbridge"); + diff --git a/trunk/drivers/mtd/maps/autcpu12-nvram.c b/trunk/drivers/mtd/maps/autcpu12-nvram.c index a2dc2ae4b24e..76fb594bb1d9 100644 --- a/trunk/drivers/mtd/maps/autcpu12-nvram.c +++ b/trunk/drivers/mtd/maps/autcpu12-nvram.c @@ -33,7 +33,7 @@ struct autcpu12_nvram_priv { struct map_info map; }; -static int autcpu12_nvram_probe(struct platform_device *pdev) +static int __devinit autcpu12_nvram_probe(struct platform_device *pdev) { map_word tmp, save0, save1; struct resource *res; @@ -105,7 +105,7 @@ static int autcpu12_nvram_probe(struct platform_device *pdev) return -ENOMEM; } -static int autcpu12_nvram_remove(struct platform_device *pdev) +static int __devexit autcpu12_nvram_remove(struct platform_device *pdev) { struct autcpu12_nvram_priv *priv = platform_get_drvdata(pdev); @@ -121,7 +121,7 @@ static struct platform_driver autcpu12_nvram_driver = { .owner = THIS_MODULE, }, .probe = autcpu12_nvram_probe, - .remove = autcpu12_nvram_remove, + .remove = __devexit_p(autcpu12_nvram_remove), }; module_platform_driver(autcpu12_nvram_driver); diff --git a/trunk/drivers/mtd/maps/bfin-async-flash.c b/trunk/drivers/mtd/maps/bfin-async-flash.c index f833edfaab79..ef5cde84a8b3 100644 --- a/trunk/drivers/mtd/maps/bfin-async-flash.c +++ b/trunk/drivers/mtd/maps/bfin-async-flash.c @@ -30,8 +30,7 @@ #include #include -#define pr_devinit(fmt, args...) \ - ({ static const char __fmt[] = fmt; printk(__fmt, ## args); }) +#define pr_devinit(fmt, args...) ({ static const __devinitconst char __fmt[] = fmt; printk(__fmt, ## args); }) #define DRIVER_NAME "bfin-async-flash" @@ -124,7 +123,7 @@ static void bfin_flash_copy_to(struct map_info *map, unsigned long to, const voi static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; -static int bfin_flash_probe(struct platform_device *pdev) +static int __devinit bfin_flash_probe(struct platform_device *pdev) { int ret; struct physmap_flash_data *pdata = pdev->dev.platform_data; @@ -173,7 +172,7 @@ static int bfin_flash_probe(struct platform_device *pdev) return 0; } -static int bfin_flash_remove(struct platform_device *pdev) +static int __devexit bfin_flash_remove(struct platform_device *pdev) { struct async_state *state = platform_get_drvdata(pdev); gpio_free(state->enet_flash_pin); @@ -185,7 +184,7 @@ static int bfin_flash_remove(struct platform_device *pdev) static struct platform_driver bfin_flash_driver = { .probe = bfin_flash_probe, - .remove = bfin_flash_remove, + .remove = __devexit_p(bfin_flash_remove), .driver = { .name = DRIVER_NAME, }, diff --git a/trunk/drivers/mtd/maps/ck804xrom.c b/trunk/drivers/mtd/maps/ck804xrom.c index 586a1c77e48a..3d0e762fa5f2 100644 --- a/trunk/drivers/mtd/maps/ck804xrom.c +++ b/trunk/drivers/mtd/maps/ck804xrom.c @@ -112,8 +112,8 @@ static void ck804xrom_cleanup(struct ck804xrom_window *window) } -static int ck804xrom_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) +static int __devinit ck804xrom_init_one (struct pci_dev *pdev, + const struct pci_device_id *ent) { static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; u8 byte; @@ -320,7 +320,7 @@ static int ck804xrom_init_one(struct pci_dev *pdev, } -static void ck804xrom_remove_one(struct pci_dev *pdev) +static void __devexit ck804xrom_remove_one (struct pci_dev *pdev) { struct ck804xrom_window *window = &ck804xrom_window; diff --git a/trunk/drivers/mtd/maps/esb2rom.c b/trunk/drivers/mtd/maps/esb2rom.c index ff8681a25831..08322b1c3e81 100644 --- a/trunk/drivers/mtd/maps/esb2rom.c +++ b/trunk/drivers/mtd/maps/esb2rom.c @@ -144,7 +144,7 @@ static void esb2rom_cleanup(struct esb2rom_window *window) pci_dev_put(window->pdev); } -static int esb2rom_init_one(struct pci_dev *pdev, +static int __devinit esb2rom_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; @@ -378,13 +378,13 @@ static int esb2rom_init_one(struct pci_dev *pdev, return 0; } -static void esb2rom_remove_one(struct pci_dev *pdev) +static void __devexit esb2rom_remove_one (struct pci_dev *pdev) { struct esb2rom_window *window = &esb2rom_window; esb2rom_cleanup(window); } -static struct pci_device_id esb2rom_pci_tbl[] = { +static struct pci_device_id esb2rom_pci_tbl[] __devinitdata = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, diff --git a/trunk/drivers/mtd/maps/fortunet.c b/trunk/drivers/mtd/maps/fortunet.c new file mode 100644 index 000000000000..956e2e4f30ea --- /dev/null +++ b/trunk/drivers/mtd/maps/fortunet.c @@ -0,0 +1,277 @@ +/* fortunet.c memory map + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#define MAX_NUM_REGIONS 4 +#define MAX_NUM_PARTITIONS 8 + +#define DEF_WINDOW_ADDR_PHY 0x00000000 +#define DEF_WINDOW_SIZE 0x00800000 // 8 Mega Bytes + +#define MTD_FORTUNET_PK "MTD FortuNet: " + +#define MAX_NAME_SIZE 128 + +struct map_region +{ + int window_addr_physical; + int altbankwidth; + struct map_info map_info; + struct mtd_info *mymtd; + struct mtd_partition parts[MAX_NUM_PARTITIONS]; + char map_name[MAX_NAME_SIZE]; + char parts_name[MAX_NUM_PARTITIONS][MAX_NAME_SIZE]; +}; + +static struct map_region map_regions[MAX_NUM_REGIONS]; +static int map_regions_set[MAX_NUM_REGIONS] = {0,0,0,0}; +static int map_regions_parts[MAX_NUM_REGIONS] = {0,0,0,0}; + + + +struct map_info default_map = { + .size = DEF_WINDOW_SIZE, + .bankwidth = 4, +}; + +static char * __init get_string_option(char *dest,int dest_size,char *sor) +{ + if(!dest_size) + return sor; + dest_size--; + while(*sor) + { + if(*sor==',') + { + sor++; + break; + } + else if(*sor=='\"') + { + sor++; + while(*sor) + { + if(*sor=='\"') + { + sor++; + break; + } + *dest = *sor; + dest++; + sor++; + dest_size--; + if(!dest_size) + { + *dest = 0; + return sor; + } + } + } + else + { + *dest = *sor; + dest++; + sor++; + dest_size--; + if(!dest_size) + { + *dest = 0; + return sor; + } + } + } + *dest = 0; + return sor; +} + +static int __init MTD_New_Region(char *line) +{ + char string[MAX_NAME_SIZE]; + int params[6]; + get_options (get_string_option(string,sizeof(string),line),6,params); + if(params[0]<1) + { + printk(MTD_FORTUNET_PK "Bad parameters for MTD Region " + " name,region-number[,base,size,bankwidth,altbankwidth]\n"); + return 1; + } + if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS)) + { + printk(MTD_FORTUNET_PK "Bad region index of %d only have 0..%u regions\n", + params[1],MAX_NUM_REGIONS-1); + return 1; + } + memset(&map_regions[params[1]],0,sizeof(map_regions[params[1]])); + memcpy(&map_regions[params[1]].map_info, + &default_map,sizeof(map_regions[params[1]].map_info)); + map_regions_set[params[1]] = 1; + map_regions[params[1]].window_addr_physical = DEF_WINDOW_ADDR_PHY; + map_regions[params[1]].altbankwidth = 2; + map_regions[params[1]].mymtd = NULL; + map_regions[params[1]].map_info.name = map_regions[params[1]].map_name; + strcpy(map_regions[params[1]].map_info.name,string); + if(params[0]>1) + { + map_regions[params[1]].window_addr_physical = params[2]; + } + if(params[0]>2) + { + map_regions[params[1]].map_info.size = params[3]; + } + if(params[0]>3) + { + map_regions[params[1]].map_info.bankwidth = params[4]; + } + if(params[0]>4) + { + map_regions[params[1]].altbankwidth = params[5]; + } + return 1; +} + +static int __init MTD_New_Partition(char *line) +{ + char string[MAX_NAME_SIZE]; + int params[4]; + get_options (get_string_option(string,sizeof(string),line),4,params); + if(params[0]<3) + { + printk(MTD_FORTUNET_PK "Bad parameters for MTD Partition " + " name,region-number,size,offset\n"); + return 1; + } + if((params[1]<0)||(params[1]>=MAX_NUM_REGIONS)) + { + printk(MTD_FORTUNET_PK "Bad region index of %d only have 0..%u regions\n", + params[1],MAX_NUM_REGIONS-1); + return 1; + } + if(map_regions_parts[params[1]]>=MAX_NUM_PARTITIONS) + { + printk(MTD_FORTUNET_PK "Out of space for partition in this region\n"); + return 1; + } + map_regions[params[1]].parts[map_regions_parts[params[1]]].name = + map_regions[params[1]]. parts_name[map_regions_parts[params[1]]]; + strcpy(map_regions[params[1]].parts[map_regions_parts[params[1]]].name,string); + map_regions[params[1]].parts[map_regions_parts[params[1]]].size = + params[2]; + map_regions[params[1]].parts[map_regions_parts[params[1]]].offset = + params[3]; + map_regions[params[1]].parts[map_regions_parts[params[1]]].mask_flags = 0; + map_regions_parts[params[1]]++; + return 1; +} + +__setup("MTD_Region=", MTD_New_Region); +__setup("MTD_Partition=", MTD_New_Partition); + +/* Backwards-spelling-compatibility */ +__setup("MTD_Partion=", MTD_New_Partition); + +static int __init init_fortunet(void) +{ + int ix,iy; + for(iy=ix=0;ixowner = THIS_MODULE; + mtd_device_register(map_regions[ix].mymtd, + map_regions[ix].parts, + map_regions_parts[ix]); + } + } + if(iy) + return 0; + return -ENXIO; +} + +static void __exit cleanup_fortunet(void) +{ + int ix; + for(ix=0;ix #include -#define pr_devinit(fmt, args...) \ - ({ static const char __fmt[] = fmt; printk(__fmt, ## args); }) +#define pr_devinit(fmt, args...) ({ static const __devinitconst char __fmt[] = fmt; printk(__fmt, ## args); }) #define DRIVER_NAME "gpio-addr-flash" #define PFX DRIVER_NAME ": " @@ -143,8 +142,7 @@ static void gf_write(struct map_info *map, map_word d1, unsigned long ofs) * * See gf_copy_from() caveat. */ -static void gf_copy_to(struct map_info *map, unsigned long to, - const void *from, ssize_t len) +static void gf_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) { struct async_state *state = gf_map_info_to_state(map); @@ -187,7 +185,7 @@ static const char *part_probe_types[] = { "cmdlinepart", "RedBoot", NULL }; * ... * }; */ -static int gpio_flash_probe(struct platform_device *pdev) +static int __devinit gpio_flash_probe(struct platform_device *pdev) { size_t i, arr_size; struct physmap_flash_data *pdata; @@ -260,7 +258,7 @@ static int gpio_flash_probe(struct platform_device *pdev) return 0; } -static int gpio_flash_remove(struct platform_device *pdev) +static int __devexit gpio_flash_remove(struct platform_device *pdev) { struct async_state *state = platform_get_drvdata(pdev); size_t i = 0; @@ -275,7 +273,7 @@ static int gpio_flash_remove(struct platform_device *pdev) static struct platform_driver gpio_flash_driver = { .probe = gpio_flash_probe, - .remove = gpio_flash_remove, + .remove = __devexit_p(gpio_flash_remove), .driver = { .name = DRIVER_NAME, }, diff --git a/trunk/drivers/mtd/maps/ichxrom.c b/trunk/drivers/mtd/maps/ichxrom.c index c7478e18f485..6689dcb3124d 100644 --- a/trunk/drivers/mtd/maps/ichxrom.c +++ b/trunk/drivers/mtd/maps/ichxrom.c @@ -84,8 +84,8 @@ static void ichxrom_cleanup(struct ichxrom_window *window) } -static int ichxrom_init_one(struct pci_dev *pdev, - const struct pci_device_id *ent) +static int __devinit ichxrom_init_one (struct pci_dev *pdev, + const struct pci_device_id *ent) { static char *rom_probe_types[] = { "cfi_probe", "jedec_probe", NULL }; struct ichxrom_window *window = &ichxrom_window; @@ -315,13 +315,13 @@ static int ichxrom_init_one(struct pci_dev *pdev, } -static void ichxrom_remove_one(struct pci_dev *pdev) +static void __devexit ichxrom_remove_one (struct pci_dev *pdev) { struct ichxrom_window *window = &ichxrom_window; ichxrom_cleanup(window); } -static struct pci_device_id ichxrom_pci_tbl[] = { +static struct pci_device_id ichxrom_pci_tbl[] __devinitdata = { { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, PCI_ANY_ID, PCI_ANY_ID, }, { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, diff --git a/trunk/drivers/mtd/maps/intel_vr_nor.c b/trunk/drivers/mtd/maps/intel_vr_nor.c index 3ee2ad1dcbe7..93f03175c82d 100644 --- a/trunk/drivers/mtd/maps/intel_vr_nor.c +++ b/trunk/drivers/mtd/maps/intel_vr_nor.c @@ -63,24 +63,24 @@ struct vr_nor_mtd { #define TIMING_BYTE_EN (1 << 0) /* 8-bit vs 16-bit bus */ #define TIMING_MASK 0x3FFF0000 -static void vr_nor_destroy_partitions(struct vr_nor_mtd *p) +static void __devexit vr_nor_destroy_partitions(struct vr_nor_mtd *p) { mtd_device_unregister(p->info); } -static int vr_nor_init_partitions(struct vr_nor_mtd *p) +static int __devinit vr_nor_init_partitions(struct vr_nor_mtd *p) { /* register the flash bank */ /* partition the flash bank */ return mtd_device_parse_register(p->info, NULL, NULL, NULL, 0); } -static void vr_nor_destroy_mtd_setup(struct vr_nor_mtd *p) +static void __devexit vr_nor_destroy_mtd_setup(struct vr_nor_mtd *p) { map_destroy(p->info); } -static int vr_nor_mtd_setup(struct vr_nor_mtd *p) +static int __devinit vr_nor_mtd_setup(struct vr_nor_mtd *p) { static const char *probe_types[] = { "cfi_probe", "jedec_probe", NULL }; @@ -96,7 +96,7 @@ static int vr_nor_mtd_setup(struct vr_nor_mtd *p) return 0; } -static void vr_nor_destroy_maps(struct vr_nor_mtd *p) +static void __devexit vr_nor_destroy_maps(struct vr_nor_mtd *p) { unsigned int exp_timing_cs0; @@ -116,7 +116,7 @@ static void vr_nor_destroy_maps(struct vr_nor_mtd *p) * Initialize the map_info structure and map the flash. * Returns 0 on success, nonzero otherwise. */ -static int vr_nor_init_maps(struct vr_nor_mtd *p) +static int __devinit vr_nor_init_maps(struct vr_nor_mtd *p) { unsigned long csr_phys, csr_len; unsigned long win_phys, win_len; @@ -176,7 +176,7 @@ static struct pci_device_id vr_nor_pci_ids[] = { {0,} }; -static void vr_nor_pci_remove(struct pci_dev *dev) +static void __devexit vr_nor_pci_remove(struct pci_dev *dev) { struct vr_nor_mtd *p = pci_get_drvdata(dev); @@ -189,7 +189,7 @@ static void vr_nor_pci_remove(struct pci_dev *dev) pci_disable_device(dev); } -static int +static int __devinit vr_nor_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) { struct vr_nor_mtd *p = NULL; @@ -256,7 +256,7 @@ vr_nor_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) static struct pci_driver vr_nor_pci_driver = { .name = DRV_NAME, .probe = vr_nor_pci_probe, - .remove = vr_nor_pci_remove, + .remove = __devexit_p(vr_nor_pci_remove), .id_table = vr_nor_pci_ids, }; diff --git a/trunk/drivers/mtd/maps/lantiq-flash.c b/trunk/drivers/mtd/maps/lantiq-flash.c index 3c3c791eb96a..c03456f17004 100644 --- a/trunk/drivers/mtd/maps/lantiq-flash.c +++ b/trunk/drivers/mtd/maps/lantiq-flash.c @@ -45,7 +45,7 @@ struct ltq_mtd { }; static const char ltq_map_name[] = "ltq_nor"; -static const char *ltq_probe_types[] = { +static const char *ltq_probe_types[] __devinitconst = { "cmdlinepart", "ofpart", NULL }; static map_word @@ -109,7 +109,7 @@ ltq_copy_to(struct map_info *map, unsigned long to, spin_unlock_irqrestore(&ebu_lock, flags); } -static int +static int __devinit ltq_mtd_probe(struct platform_device *pdev) { struct mtd_part_parser_data ppdata; @@ -185,7 +185,7 @@ ltq_mtd_probe(struct platform_device *pdev) return err; } -static int +static int __devexit ltq_mtd_remove(struct platform_device *pdev) { struct ltq_mtd *ltq_mtd = platform_get_drvdata(pdev); @@ -209,7 +209,7 @@ MODULE_DEVICE_TABLE(of, ltq_mtd_match); static struct platform_driver ltq_mtd_driver = { .probe = ltq_mtd_probe, - .remove = ltq_mtd_remove, + .remove = __devexit_p(ltq_mtd_remove), .driver = { .name = "ltq-nor", .owner = THIS_MODULE, diff --git a/trunk/drivers/mtd/maps/latch-addr-flash.c b/trunk/drivers/mtd/maps/latch-addr-flash.c index ab0fead56b83..3c7ad17fca78 100644 --- a/trunk/drivers/mtd/maps/latch-addr-flash.c +++ b/trunk/drivers/mtd/maps/latch-addr-flash.c @@ -125,7 +125,7 @@ static int latch_addr_flash_remove(struct platform_device *dev) return 0; } -static int latch_addr_flash_probe(struct platform_device *dev) +static int __devinit latch_addr_flash_probe(struct platform_device *dev) { struct latch_addr_flash_data *latch_addr_data; struct latch_addr_flash_info *info; @@ -218,7 +218,7 @@ static int latch_addr_flash_probe(struct platform_device *dev) static struct platform_driver latch_addr_flash_driver = { .probe = latch_addr_flash_probe, - .remove = latch_addr_flash_remove, + .remove = __devexit_p(latch_addr_flash_remove), .driver = { .name = DRIVER_NAME, }, diff --git a/trunk/drivers/mtd/maps/pci.c b/trunk/drivers/mtd/maps/pci.c index ed82914966f5..1c30c1a307f4 100644 --- a/trunk/drivers/mtd/maps/pci.c +++ b/trunk/drivers/mtd/maps/pci.c @@ -253,7 +253,7 @@ static struct pci_device_id mtd_pci_ids[] = { * Generic code follows. */ -static int +static int __devinit mtd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) { struct mtd_pci_info *info = (struct mtd_pci_info *)id->driver_data; @@ -308,7 +308,7 @@ mtd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) return err; } -static void +static void __devexit mtd_pci_remove(struct pci_dev *dev) { struct mtd_info *mtd = pci_get_drvdata(dev); @@ -326,7 +326,7 @@ mtd_pci_remove(struct pci_dev *dev) static struct pci_driver mtd_pci_driver = { .name = "MTD PCI", .probe = mtd_pci_probe, - .remove = mtd_pci_remove, + .remove = __devexit_p(mtd_pci_remove), .id_table = mtd_pci_ids, }; diff --git a/trunk/drivers/mtd/maps/physmap_of.c b/trunk/drivers/mtd/maps/physmap_of.c index 37cdc201652f..6f19acadb06c 100644 --- a/trunk/drivers/mtd/maps/physmap_of.c +++ b/trunk/drivers/mtd/maps/physmap_of.c @@ -77,7 +77,7 @@ static int of_flash_remove(struct platform_device *dev) /* Helper function to handle probing of the obsolete "direct-mapped" * compatible binding, which has an extra "probe-type" property * describing the type of flash probe necessary. */ -static struct mtd_info *obsolete_probe(struct platform_device *dev, +static struct mtd_info * __devinit obsolete_probe(struct platform_device *dev, struct map_info *map) { struct device_node *dp = dev->dev.of_node; @@ -116,7 +116,7 @@ static struct mtd_info *obsolete_probe(struct platform_device *dev, information. */ static const char *part_probe_types_def[] = { "cmdlinepart", "RedBoot", "ofpart", "ofoldpart", NULL }; -static const char **of_get_probes(struct device_node *dp) +static const char ** __devinit of_get_probes(struct device_node *dp) { const char *cp; int cplen; @@ -145,14 +145,14 @@ static const char **of_get_probes(struct device_node *dp) return res; } -static void of_free_probes(const char **probes) +static void __devinit of_free_probes(const char **probes) { if (probes != part_probe_types_def) kfree(probes); } static struct of_device_id of_flash_match[]; -static int of_flash_probe(struct platform_device *dev) +static int __devinit of_flash_probe(struct platform_device *dev) { const char **part_probe_types; const struct of_device_id *match; @@ -170,7 +170,6 @@ static int of_flash_probe(struct platform_device *dev) resource_size_t res_size; struct mtd_part_parser_data ppdata; bool map_indirect; - const char *mtd_name; match = of_match_device(of_flash_match, &dev->dev); if (!match) @@ -179,8 +178,6 @@ static int of_flash_probe(struct platform_device *dev) reg_tuple_size = (of_n_addr_cells(dp) + of_n_size_cells(dp)) * sizeof(u32); - of_property_read_string(dp, "linux,mtd-name", &mtd_name); - /* * Get number of "reg" tuples. Scan for MTD devices on area's * described by each "reg" region. This makes it possible (including @@ -237,7 +234,7 @@ static int of_flash_probe(struct platform_device *dev) goto err_out; } - info->list[i].map.name = mtd_name ?: dev_name(&dev->dev); + info->list[i].map.name = dev_name(&dev->dev); info->list[i].map.phys = res.start; info->list[i].map.size = res_size; info->list[i].map.bankwidth = be32_to_cpup(width); @@ -285,7 +282,6 @@ static int of_flash_probe(struct platform_device *dev) } err = 0; - info->cmtd = NULL; if (info->list_size == 1) { info->cmtd = info->list[0].mtd; } else if (info->list_size > 1) { @@ -294,10 +290,9 @@ static int of_flash_probe(struct platform_device *dev) */ info->cmtd = mtd_concat_create(mtd_list, info->list_size, dev_name(&dev->dev)); + if (info->cmtd == NULL) + err = -ENXIO; } - if (info->cmtd == NULL) - err = -ENXIO; - if (err) goto err_out; diff --git a/trunk/drivers/mtd/maps/pismo.c b/trunk/drivers/mtd/maps/pismo.c index afea93b515d5..65bd1cd4d627 100644 --- a/trunk/drivers/mtd/maps/pismo.c +++ b/trunk/drivers/mtd/maps/pismo.c @@ -58,7 +58,7 @@ static void pismo_set_vpp(struct platform_device *pdev, int on) pismo->vpp(pismo->vpp_data, on); } -static unsigned int pismo_width_to_bytes(unsigned int width) +static unsigned int __devinit pismo_width_to_bytes(unsigned int width) { width &= 15; if (width > 2) @@ -66,7 +66,7 @@ static unsigned int pismo_width_to_bytes(unsigned int width) return 1 << width; } -static int pismo_eeprom_read(struct i2c_client *client, void *buf, +static int __devinit pismo_eeprom_read(struct i2c_client *client, void *buf, u8 addr, size_t size) { int ret; @@ -88,7 +88,7 @@ static int pismo_eeprom_read(struct i2c_client *client, void *buf, return ret == ARRAY_SIZE(msg) ? size : -EIO; } -static int pismo_add_device(struct pismo_data *pismo, int i, +static int __devinit pismo_add_device(struct pismo_data *pismo, int i, struct pismo_mem *region, const char *name, void *pdata, size_t psize) { struct platform_device *dev; @@ -129,7 +129,7 @@ static int pismo_add_device(struct pismo_data *pismo, int i, return ret; } -static int pismo_add_nor(struct pismo_data *pismo, int i, +static int __devinit pismo_add_nor(struct pismo_data *pismo, int i, struct pismo_mem *region) { struct physmap_flash_data data = { @@ -143,7 +143,7 @@ static int pismo_add_nor(struct pismo_data *pismo, int i, &data, sizeof(data)); } -static int pismo_add_sram(struct pismo_data *pismo, int i, +static int __devinit pismo_add_sram(struct pismo_data *pismo, int i, struct pismo_mem *region) { struct platdata_mtd_ram data = { @@ -154,7 +154,7 @@ static int pismo_add_sram(struct pismo_data *pismo, int i, &data, sizeof(data)); } -static void pismo_add_one(struct pismo_data *pismo, int i, +static void __devinit pismo_add_one(struct pismo_data *pismo, int i, const struct pismo_cs_block *cs, phys_addr_t base) { struct device *dev = &pismo->client->dev; @@ -197,7 +197,7 @@ static void pismo_add_one(struct pismo_data *pismo, int i, } } -static int pismo_remove(struct i2c_client *client) +static int __devexit pismo_remove(struct i2c_client *client) { struct pismo_data *pismo = i2c_get_clientdata(client); int i; @@ -210,7 +210,7 @@ static int pismo_remove(struct i2c_client *client) return 0; } -static int pismo_probe(struct i2c_client *client, +static int __devinit pismo_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); @@ -267,7 +267,7 @@ static struct i2c_driver pismo_driver = { .owner = THIS_MODULE, }, .probe = pismo_probe, - .remove = pismo_remove, + .remove = __devexit_p(pismo_remove), .id_table = pismo_id, }; diff --git a/trunk/drivers/mtd/maps/pxa2xx-flash.c b/trunk/drivers/mtd/maps/pxa2xx-flash.c index 43e3dbb976d9..81884c277405 100644 --- a/trunk/drivers/mtd/maps/pxa2xx-flash.c +++ b/trunk/drivers/mtd/maps/pxa2xx-flash.c @@ -49,7 +49,7 @@ struct pxa2xx_flash_info { static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; -static int pxa2xx_flash_probe(struct platform_device *pdev) +static int __devinit pxa2xx_flash_probe(struct platform_device *pdev) { struct flash_platform_data *flash = pdev->dev.platform_data; struct pxa2xx_flash_info *info; @@ -105,7 +105,7 @@ static int pxa2xx_flash_probe(struct platform_device *pdev) return 0; } -static int pxa2xx_flash_remove(struct platform_device *dev) +static int __devexit pxa2xx_flash_remove(struct platform_device *dev) { struct pxa2xx_flash_info *info = platform_get_drvdata(dev); @@ -139,7 +139,7 @@ static struct platform_driver pxa2xx_flash_driver = { .owner = THIS_MODULE, }, .probe = pxa2xx_flash_probe, - .remove = pxa2xx_flash_remove, + .remove = __devexit_p(pxa2xx_flash_remove), .shutdown = pxa2xx_flash_shutdown, }; diff --git a/trunk/drivers/mtd/maps/sa1100-flash.c b/trunk/drivers/mtd/maps/sa1100-flash.c index f694417cf7e6..a675bdbcb0fe 100644 --- a/trunk/drivers/mtd/maps/sa1100-flash.c +++ b/trunk/drivers/mtd/maps/sa1100-flash.c @@ -149,8 +149,8 @@ static void sa1100_destroy(struct sa_info *info, struct flash_platform_data *pla plat->exit(); } -static struct sa_info *sa1100_setup_mtd(struct platform_device *pdev, - struct flash_platform_data *plat) +static struct sa_info *__devinit +sa1100_setup_mtd(struct platform_device *pdev, struct flash_platform_data *plat) { struct sa_info *info; int nr, size, i, ret = 0; @@ -246,7 +246,7 @@ static struct sa_info *sa1100_setup_mtd(struct platform_device *pdev, static const char *part_probes[] = { "cmdlinepart", "RedBoot", NULL }; -static int sa1100_mtd_probe(struct platform_device *pdev) +static int __devinit sa1100_mtd_probe(struct platform_device *pdev) { struct flash_platform_data *plat = pdev->dev.platform_data; struct sa_info *info; diff --git a/trunk/drivers/mtd/maps/scb2_flash.c b/trunk/drivers/mtd/maps/scb2_flash.c index 71796137e97b..9dcbc684abdb 100644 --- a/trunk/drivers/mtd/maps/scb2_flash.c +++ b/trunk/drivers/mtd/maps/scb2_flash.c @@ -69,7 +69,7 @@ static struct map_info scb2_map = { }; static int region_fail; -static int +static int __devinit scb2_fixup_mtd(struct mtd_info *mtd) { int i; @@ -133,7 +133,7 @@ scb2_fixup_mtd(struct mtd_info *mtd) /* CSB5's 'Function Control Register' has bits for decoding @ >= 0xffc00000 */ #define CSB5_FCR 0x41 #define CSB5_FCR_DECODE_ALL 0x0e -static int +static int __devinit scb2_flash_probe(struct pci_dev *dev, const struct pci_device_id *ent) { u8 reg; @@ -197,7 +197,7 @@ scb2_flash_probe(struct pci_dev *dev, const struct pci_device_id *ent) return 0; } -static void +static void __devexit scb2_flash_remove(struct pci_dev *dev) { if (!scb2_mtd) @@ -231,7 +231,7 @@ static struct pci_driver scb2_flash_driver = { .name = "Intel SCB2 BIOS Flash", .id_table = scb2_flash_pci_ids, .probe = scb2_flash_probe, - .remove = scb2_flash_remove, + .remove = __devexit_p(scb2_flash_remove), }; module_pci_driver(scb2_flash_driver); diff --git a/trunk/drivers/mtd/maps/sun_uflash.c b/trunk/drivers/mtd/maps/sun_uflash.c index d467f3b11c96..175e537b444f 100644 --- a/trunk/drivers/mtd/maps/sun_uflash.c +++ b/trunk/drivers/mtd/maps/sun_uflash.c @@ -108,7 +108,7 @@ int uflash_devinit(struct platform_device *op, struct device_node *dp) return 0; } -static int uflash_probe(struct platform_device *op) +static int __devinit uflash_probe(struct platform_device *op) { struct device_node *dp = op->dev.of_node; @@ -121,7 +121,7 @@ static int uflash_probe(struct platform_device *op) return uflash_devinit(op, dp); } -static int uflash_remove(struct platform_device *op) +static int __devexit uflash_remove(struct platform_device *op) { struct uflash_dev *up = dev_get_drvdata(&op->dev); @@ -155,7 +155,7 @@ static struct platform_driver uflash_driver = { .of_match_table = uflash_match, }, .probe = uflash_probe, - .remove = uflash_remove, + .remove = __devexit_p(uflash_remove), }; module_platform_driver(uflash_driver); diff --git a/trunk/drivers/mtd/maps/vmu-flash.c b/trunk/drivers/mtd/maps/vmu-flash.c index 6b223cfe92b7..2e2b0945edc7 100644 --- a/trunk/drivers/mtd/maps/vmu-flash.c +++ b/trunk/drivers/mtd/maps/vmu-flash.c @@ -596,7 +596,7 @@ static void vmu_queryblocks(struct mapleq *mq) } /* Handles very basic info about the flash, queries for details */ -static int vmu_connect(struct maple_device *mdev) +static int __devinit vmu_connect(struct maple_device *mdev) { unsigned long test_flash_data, basic_flash_data; int c, error; @@ -690,7 +690,7 @@ static int vmu_connect(struct maple_device *mdev) return error; } -static void vmu_disconnect(struct maple_device *mdev) +static void __devexit vmu_disconnect(struct maple_device *mdev) { struct memcard *card; struct mdev_part *mpart; @@ -772,7 +772,7 @@ static void vmu_file_error(struct maple_device *mdev, void *recvbuf) } -static int probe_maple_vmu(struct device *dev) +static int __devinit probe_maple_vmu(struct device *dev) { int error; struct maple_device *mdev = to_maple_dev(dev); @@ -789,7 +789,7 @@ static int probe_maple_vmu(struct device *dev) return 0; } -static int remove_maple_vmu(struct device *dev) +static int __devexit remove_maple_vmu(struct device *dev) { struct maple_device *mdev = to_maple_dev(dev); @@ -802,7 +802,7 @@ static struct maple_driver vmu_flash_driver = { .drv = { .name = "Dreamcast_visual_memory", .probe = probe_maple_vmu, - .remove = remove_maple_vmu, + .remove = __devexit_p(remove_maple_vmu), }, }; diff --git a/trunk/drivers/mtd/mtd_blkdevs.c b/trunk/drivers/mtd/mtd_blkdevs.c index 5ad39bb5ab4c..f1f06715d4e0 100644 --- a/trunk/drivers/mtd/mtd_blkdevs.c +++ b/trunk/drivers/mtd/mtd_blkdevs.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include "mtdcore.h" @@ -120,14 +121,16 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr, int mtd_blktrans_cease_background(struct mtd_blktrans_dev *dev) { + if (kthread_should_stop()) + return 1; + return dev->bg_stop; } EXPORT_SYMBOL_GPL(mtd_blktrans_cease_background); -static void mtd_blktrans_work(struct work_struct *work) +static int mtd_blktrans_thread(void *arg) { - struct mtd_blktrans_dev *dev = - container_of(work, struct mtd_blktrans_dev, work); + struct mtd_blktrans_dev *dev = arg; struct mtd_blktrans_ops *tr = dev->tr; struct request_queue *rq = dev->rq; struct request *req = NULL; @@ -135,7 +138,7 @@ static void mtd_blktrans_work(struct work_struct *work) spin_lock_irq(rq->queue_lock); - while (1) { + while (!kthread_should_stop()) { int res; dev->bg_stop = false; @@ -153,7 +156,15 @@ static void mtd_blktrans_work(struct work_struct *work) background_done = !dev->bg_stop; continue; } - break; + set_current_state(TASK_INTERRUPTIBLE); + + if (kthread_should_stop()) + set_current_state(TASK_RUNNING); + + spin_unlock_irq(rq->queue_lock); + schedule(); + spin_lock_irq(rq->queue_lock); + continue; } spin_unlock_irq(rq->queue_lock); @@ -174,6 +185,8 @@ static void mtd_blktrans_work(struct work_struct *work) __blk_end_request_all(req, -EIO); spin_unlock_irq(rq->queue_lock); + + return 0; } static void mtd_blktrans_request(struct request_queue *rq) @@ -186,8 +199,10 @@ static void mtd_blktrans_request(struct request_queue *rq) if (!dev) while ((req = blk_fetch_request(rq)) != NULL) __blk_end_request_all(req, -ENODEV); - else - queue_work(dev->wq, &dev->work); + else { + dev->bg_stop = true; + wake_up_process(dev->thread); + } } static int blktrans_open(struct block_device *bdev, fmode_t mode) @@ -310,7 +325,7 @@ static int blktrans_ioctl(struct block_device *bdev, fmode_t mode, return ret; } -static const struct block_device_operations mtd_block_ops = { +static const struct block_device_operations mtd_blktrans_ops = { .owner = THIS_MODULE, .open = blktrans_open, .release = blktrans_release, @@ -386,7 +401,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) gd->private_data = new; gd->major = tr->major; gd->first_minor = (new->devnum) << tr->part_bits; - gd->fops = &mtd_block_ops; + gd->fops = &mtd_blktrans_ops; if (tr->part_bits) if (new->devnum < 26) @@ -422,13 +437,14 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new) gd->queue = new->rq; - /* Create processing workqueue */ - new->wq = alloc_workqueue("%s%d", 0, 0, - tr->name, new->mtd->index); - if (!new->wq) + /* Create processing thread */ + /* TODO: workqueue ? */ + new->thread = kthread_run(mtd_blktrans_thread, new, + "%s%d", tr->name, new->mtd->index); + if (IS_ERR(new->thread)) { + ret = PTR_ERR(new->thread); goto error4; - INIT_WORK(&new->work, mtd_blktrans_work); - + } gd->driverfs_dev = &new->mtd->dev; if (new->readonly) @@ -468,8 +484,9 @@ int del_mtd_blktrans_dev(struct mtd_blktrans_dev *old) /* Stop new requests to arrive */ del_gendisk(old->disk); - /* Stop workqueue. This will perform any pending request. */ - destroy_workqueue(old->wq); + + /* Stop the thread */ + kthread_stop(old->thread); /* Kill current requests */ spin_lock_irqsave(&old->queue_lock, flags); diff --git a/trunk/drivers/mtd/mtdoops.c b/trunk/drivers/mtd/mtdoops.c index 97bb8f6304d4..f5b3f91fa1cc 100644 --- a/trunk/drivers/mtd/mtdoops.c +++ b/trunk/drivers/mtd/mtdoops.c @@ -271,7 +271,7 @@ static void find_next_position(struct mtdoops_context *cxt) if (count[0] == 0xffffffff && count[1] == 0xffffffff) mark_page_unused(cxt, page); - if (count[0] == 0xffffffff || count[1] != MTDOOPS_KERNMSG_MAGIC) + if (count[0] == 0xffffffff) continue; if (maxcount == 0xffffffff) { maxcount = count[0]; @@ -289,14 +289,15 @@ static void find_next_position(struct mtdoops_context *cxt) } } if (maxcount == 0xffffffff) { - cxt->nextpage = cxt->oops_pages - 1; - cxt->nextcount = 0; - } - else { - cxt->nextpage = maxpos; - cxt->nextcount = maxcount; + cxt->nextpage = 0; + cxt->nextcount = 1; + schedule_work(&cxt->work_erase); + return; } + cxt->nextpage = maxpos; + cxt->nextcount = maxcount; + mtdoops_inc_counter(cxt); } diff --git a/trunk/drivers/mtd/nand/Kconfig b/trunk/drivers/mtd/nand/Kconfig index 5819eb575210..dae191b3c081 100644 --- a/trunk/drivers/mtd/nand/Kconfig +++ b/trunk/drivers/mtd/nand/Kconfig @@ -50,30 +50,16 @@ config MTD_NAND_MUSEUM_IDS of these chips were reused by later, larger chips. config MTD_NAND_DENALI - tristate "Support Denali NAND controller" - help - Enable support for the Denali NAND controller. This should be - combined with either the PCI or platform drivers to provide device - registration. - -config MTD_NAND_DENALI_PCI + depends on PCI tristate "Support Denali NAND controller on Intel Moorestown" - depends on PCI && MTD_NAND_DENALI help Enable the driver for NAND flash on Intel Moorestown, using the Denali NAND controller core. - -config MTD_NAND_DENALI_DT - tristate "Support Denali NAND controller as a DT device" - depends on HAVE_CLK && MTD_NAND_DENALI - help - Enable the driver for NAND flash on platforms using a Denali NAND - controller as a DT device. - + config MTD_NAND_DENALI_SCRATCH_REG_ADDR hex "Denali NAND size scratch register address" default "0xFF108018" - depends on MTD_NAND_DENALI_PCI + depends on MTD_NAND_DENALI help Some platforms place the NAND chip size in a scratch register because (some versions of) the driver aren't able to automatically @@ -447,14 +433,6 @@ config MTD_NAND_GPMI_NAND block, such as SD card. So pay attention to it when you enable the GPMI. -config MTD_NAND_BCM47XXNFLASH - tristate "Support for NAND flash on BCM4706 BCMA bus" - depends on BCMA_NFLASH - help - BCMA bus can have various flash memories attached, they are - registered by bcma as platform devices. This enables driver for - NAND flash memories. For now only BCM4706 is supported. - config MTD_NAND_PLATFORM tristate "Support for generic platform NAND driver" depends on HAS_IOMEM @@ -521,6 +499,12 @@ config MTD_NAND_MXC This enables the driver for the NAND flash controller on the MXC processors. +config MTD_NAND_NOMADIK + tristate "ST Nomadik 8815 NAND support" + depends on ARCH_NOMADIK + help + Driver for the NAND flash controller on the Nomadik, with ECC. + config MTD_NAND_SH_FLCTL tristate "Support for NAND on Renesas SuperH FLCTL" depends on SUPERH || ARCH_SHMOBILE diff --git a/trunk/drivers/mtd/nand/Makefile b/trunk/drivers/mtd/nand/Makefile index d76d91205691..6c7f2b3ca8ae 100644 --- a/trunk/drivers/mtd/nand/Makefile +++ b/trunk/drivers/mtd/nand/Makefile @@ -11,8 +11,6 @@ obj-$(CONFIG_MTD_SM_COMMON) += sm_common.o obj-$(CONFIG_MTD_NAND_CAFE) += cafe_nand.o obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-delta.o obj-$(CONFIG_MTD_NAND_DENALI) += denali.o -obj-$(CONFIG_MTD_NAND_DENALI_PCI) += denali_pci.o -obj-$(CONFIG_MTD_NAND_DENALI_DT) += denali_dt.o obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o obj-$(CONFIG_MTD_NAND_BF5XX) += bf5xx_nand.o obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB) += ppchameleonevb.o @@ -47,11 +45,11 @@ obj-$(CONFIG_MTD_NAND_MXC) += mxc_nand.o obj-$(CONFIG_MTD_NAND_SOCRATES) += socrates_nand.o obj-$(CONFIG_MTD_NAND_TXX9NDFMC) += txx9ndfmc.o obj-$(CONFIG_MTD_NAND_NUC900) += nuc900_nand.o +obj-$(CONFIG_MTD_NAND_NOMADIK) += nomadik_nand.o obj-$(CONFIG_MTD_NAND_MPC5121_NFC) += mpc5121_nfc.o obj-$(CONFIG_MTD_NAND_RICOH) += r852.o obj-$(CONFIG_MTD_NAND_JZ4740) += jz4740_nand.o obj-$(CONFIG_MTD_NAND_GPMI_NAND) += gpmi-nand/ obj-$(CONFIG_MTD_NAND_XWAY) += xway_nand.o -obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash/ nand-objs := nand_base.o nand_bbt.o diff --git a/trunk/drivers/mtd/nand/ams-delta.c b/trunk/drivers/mtd/nand/ams-delta.c index f1d71cdc8aac..9e7723aa7acc 100644 --- a/trunk/drivers/mtd/nand/ams-delta.c +++ b/trunk/drivers/mtd/nand/ams-delta.c @@ -173,7 +173,7 @@ static const struct gpio _mandatory_gpio[] = { /* * Main initialization routine */ -static int ams_delta_init(struct platform_device *pdev) +static int __devinit ams_delta_init(struct platform_device *pdev) { struct nand_chip *this; struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -270,7 +270,7 @@ static int ams_delta_init(struct platform_device *pdev) /* * Clean up routine */ -static int ams_delta_cleanup(struct platform_device *pdev) +static int __devexit ams_delta_cleanup(struct platform_device *pdev) { void __iomem *io_base = platform_get_drvdata(pdev); @@ -289,7 +289,7 @@ static int ams_delta_cleanup(struct platform_device *pdev) static struct platform_driver ams_delta_nand_driver = { .probe = ams_delta_init, - .remove = ams_delta_cleanup, + .remove = __devexit_p(ams_delta_cleanup), .driver = { .name = "ams-delta-nand", .owner = THIS_MODULE, diff --git a/trunk/drivers/mtd/nand/atmel_nand.c b/trunk/drivers/mtd/nand/atmel_nand.c index 90bdca61c797..92623ac2015a 100644 --- a/trunk/drivers/mtd/nand/atmel_nand.c +++ b/trunk/drivers/mtd/nand/atmel_nand.c @@ -331,13 +331,13 @@ static void atmel_write_buf(struct mtd_info *mtd, const u8 *buf, int len) * 12-bits 20-bytes 21-bytes * 24-bits 39-bytes 42-bytes */ -static int pmecc_get_ecc_bytes(int cap, int sector_size) +static int __devinit pmecc_get_ecc_bytes(int cap, int sector_size) { int m = 12 + sector_size / 512; return (m * cap + 7) / 8; } -static void pmecc_config_ecc_layout(struct nand_ecclayout *layout, +static void __devinit pmecc_config_ecc_layout(struct nand_ecclayout *layout, int oobsize, int ecc_len) { int i; @@ -353,7 +353,7 @@ static void pmecc_config_ecc_layout(struct nand_ecclayout *layout, oobsize - ecc_len - layout->oobfree[0].offset; } -static void __iomem *pmecc_get_alpha_to(struct atmel_nand_host *host) +static void __devinit __iomem *pmecc_get_alpha_to(struct atmel_nand_host *host) { int table_size; @@ -375,7 +375,7 @@ static void pmecc_data_free(struct atmel_nand_host *host) kfree(host->pmecc_delta); } -static int pmecc_data_alloc(struct atmel_nand_host *host) +static int __devinit pmecc_data_alloc(struct atmel_nand_host *host) { const int cap = host->pmecc_corr_cap; @@ -724,7 +724,6 @@ static int pmecc_correction(struct mtd_info *mtd, u32 pmecc_stat, uint8_t *buf, struct atmel_nand_host *host = nand_chip->priv; int i, err_nbr, eccbytes; uint8_t *buf_pos; - int total_err = 0; eccbytes = nand_chip->ecc.bytes; for (i = 0; i < eccbytes; i++) @@ -752,13 +751,12 @@ static int pmecc_correction(struct mtd_info *mtd, u32 pmecc_stat, uint8_t *buf, pmecc_correct_data(mtd, buf_pos, ecc, i, host->pmecc_bytes_per_sector, err_nbr); mtd->ecc_stats.corrected += err_nbr; - total_err += err_nbr; } } pmecc_stat >>= 1; } - return total_err; + return 0; } static int atmel_nand_pmecc_read_page(struct mtd_info *mtd, @@ -770,7 +768,6 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd, uint32_t *eccpos = chip->ecc.layout->eccpos; uint32_t stat; unsigned long end_time; - int bitflips = 0; pmecc_writel(host->ecc, CTRL, PMECC_CTRL_RST); pmecc_writel(host->ecc, CTRL, PMECC_CTRL_DISABLE); @@ -793,14 +790,11 @@ static int atmel_nand_pmecc_read_page(struct mtd_info *mtd, } stat = pmecc_readl_relaxed(host->ecc, ISR); - if (stat != 0) { - bitflips = pmecc_correction(mtd, stat, buf, &oob[eccpos[0]]); - if (bitflips < 0) - /* uncorrectable errors */ - return 0; - } + if (stat != 0) + if (pmecc_correction(mtd, stat, buf, &oob[eccpos[0]]) != 0) + return -EIO; - return bitflips; + return 0; } static int atmel_nand_pmecc_write_page(struct mtd_info *mtd, @@ -1212,7 +1206,7 @@ static void atmel_nand_hwctl(struct mtd_info *mtd, int mode) } #if defined(CONFIG_OF) -static int atmel_of_init_port(struct atmel_nand_host *host, +static int __devinit atmel_of_init_port(struct atmel_nand_host *host, struct device_node *np) { u32 val, table_offset; @@ -1299,7 +1293,7 @@ static int atmel_of_init_port(struct atmel_nand_host *host, return 0; } #else -static int atmel_of_init_port(struct atmel_nand_host *host, +static int __devinit atmel_of_init_port(struct atmel_nand_host *host, struct device_node *np) { return -EINVAL; diff --git a/trunk/drivers/mtd/nand/au1550nd.c b/trunk/drivers/mtd/nand/au1550nd.c index 217459d02b2f..5c47b200045a 100644 --- a/trunk/drivers/mtd/nand/au1550nd.c +++ b/trunk/drivers/mtd/nand/au1550nd.c @@ -382,7 +382,7 @@ static void au1550_command(struct mtd_info *mtd, unsigned command, int column, i while(!this->dev_ready(mtd)); } -static int find_nand_cs(unsigned long nand_base) +static int __devinit find_nand_cs(unsigned long nand_base) { void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_STATIC_MEM_PHYS_ADDR); @@ -403,7 +403,7 @@ static int find_nand_cs(unsigned long nand_base) return -ENODEV; } -static int au1550nd_probe(struct platform_device *pdev) +static int __devinit au1550nd_probe(struct platform_device *pdev) { struct au1550nd_platdata *pd; struct au1550nd_ctx *ctx; @@ -491,7 +491,7 @@ static int au1550nd_probe(struct platform_device *pdev) return ret; } -static int au1550nd_remove(struct platform_device *pdev) +static int __devexit au1550nd_remove(struct platform_device *pdev) { struct au1550nd_ctx *ctx = platform_get_drvdata(pdev); struct resource *r = platform_get_resource(pdev, IORESOURCE_MEM, 0); @@ -509,7 +509,7 @@ static struct platform_driver au1550nd_driver = { .owner = THIS_MODULE, }, .probe = au1550nd_probe, - .remove = au1550nd_remove, + .remove = __devexit_p(au1550nd_remove), }; module_platform_driver(au1550nd_driver); diff --git a/trunk/drivers/mtd/nand/bcm47xxnflash/Makefile b/trunk/drivers/mtd/nand/bcm47xxnflash/Makefile deleted file mode 100644 index f05b119e134b..000000000000 --- a/trunk/drivers/mtd/nand/bcm47xxnflash/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -bcm47xxnflash-y += main.o -bcm47xxnflash-y += ops_bcm4706.o - -obj-$(CONFIG_MTD_NAND_BCM47XXNFLASH) += bcm47xxnflash.o diff --git a/trunk/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h b/trunk/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h deleted file mode 100644 index 0bdb2ce4da75..000000000000 --- a/trunk/drivers/mtd/nand/bcm47xxnflash/bcm47xxnflash.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef __BCM47XXNFLASH_H -#define __BCM47XXNFLASH_H - -#include -#include - -struct bcm47xxnflash { - struct bcma_drv_cc *cc; - - struct nand_chip nand_chip; - struct mtd_info mtd; - - unsigned curr_command; - int curr_page_addr; - int curr_column; - - u8 id_data[8]; -}; - -int bcm47xxnflash_ops_bcm4706_init(struct bcm47xxnflash *b47n); - -#endif /* BCM47XXNFLASH */ diff --git a/trunk/drivers/mtd/nand/bcm47xxnflash/main.c b/trunk/drivers/mtd/nand/bcm47xxnflash/main.c deleted file mode 100644 index 2b8b05bec3dd..000000000000 --- a/trunk/drivers/mtd/nand/bcm47xxnflash/main.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * BCM47XX NAND flash driver - * - * Copyright (C) 2012 RafaÅ‚ MiÅ‚ecki - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include -#include - -#include "bcm47xxnflash.h" - -MODULE_DESCRIPTION("NAND flash driver for BCMA bus"); -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("RafaÅ‚ MiÅ‚ecki"); - -static const char *probes[] = { "bcm47xxpart", NULL }; - -static int bcm47xxnflash_probe(struct platform_device *pdev) -{ - struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev); - struct bcm47xxnflash *b47n; - int err = 0; - - b47n = kzalloc(sizeof(*b47n), GFP_KERNEL); - if (!b47n) { - err = -ENOMEM; - goto out; - } - - b47n->nand_chip.priv = b47n; - b47n->mtd.owner = THIS_MODULE; - b47n->mtd.priv = &b47n->nand_chip; /* Required */ - b47n->cc = container_of(nflash, struct bcma_drv_cc, nflash); - - if (b47n->cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) { - err = bcm47xxnflash_ops_bcm4706_init(b47n); - } else { - pr_err("Device not supported\n"); - err = -ENOTSUPP; - } - if (err) { - pr_err("Initialization failed: %d\n", err); - goto err_init; - } - - err = mtd_device_parse_register(&b47n->mtd, probes, NULL, NULL, 0); - if (err) { - pr_err("Failed to register MTD device: %d\n", err); - goto err_dev_reg; - } - - return 0; - -err_dev_reg: -err_init: - kfree(b47n); -out: - return err; -} - -static int __devexit bcm47xxnflash_remove(struct platform_device *pdev) -{ - struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev); - - if (nflash->mtd) - mtd_device_unregister(nflash->mtd); - - return 0; -} - -static struct platform_driver bcm47xxnflash_driver = { - .remove = __devexit_p(bcm47xxnflash_remove), - .driver = { - .name = "bcma_nflash", - .owner = THIS_MODULE, - }, -}; - -static int __init bcm47xxnflash_init(void) -{ - int err; - - /* - * Platform device "bcma_nflash" exists on SoCs and is registered very - * early, it won't be added during runtime (use platform_driver_probe). - */ - err = platform_driver_probe(&bcm47xxnflash_driver, bcm47xxnflash_probe); - if (err) - pr_err("Failed to register serial flash driver: %d\n", err); - - return err; -} - -static void __exit bcm47xxnflash_exit(void) -{ - platform_driver_unregister(&bcm47xxnflash_driver); -} - -module_init(bcm47xxnflash_init); -module_exit(bcm47xxnflash_exit); diff --git a/trunk/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c b/trunk/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c deleted file mode 100644 index 86c9a79b89b3..000000000000 --- a/trunk/drivers/mtd/nand/bcm47xxnflash/ops_bcm4706.c +++ /dev/null @@ -1,413 +0,0 @@ -/* - * BCM47XX NAND flash driver - * - * Copyright (C) 2012 RafaÅ‚ MiÅ‚ecki - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - */ - -#include -#include -#include -#include - -#include "bcm47xxnflash.h" - -/* Broadcom uses 1'000'000 but it seems to be too many. Tests on WNDR4500 has - * shown 164 retries as maxiumum. */ -#define NFLASH_READY_RETRIES 1000 - -#define NFLASH_SECTOR_SIZE 512 - -#define NCTL_CMD0 0x00010000 -#define NCTL_CMD1W 0x00080000 -#define NCTL_READ 0x00100000 -#define NCTL_WRITE 0x00200000 -#define NCTL_SPECADDR 0x01000000 -#define NCTL_READY 0x04000000 -#define NCTL_ERR 0x08000000 -#define NCTL_CSA 0x40000000 -#define NCTL_START 0x80000000 - -/************************************************** - * Various helpers - **************************************************/ - -static inline u8 bcm47xxnflash_ops_bcm4706_ns_to_cycle(u16 ns, u16 clock) -{ - return ((ns * 1000 * clock) / 1000000) + 1; -} - -static int bcm47xxnflash_ops_bcm4706_ctl_cmd(struct bcma_drv_cc *cc, u32 code) -{ - int i = 0; - - bcma_cc_write32(cc, BCMA_CC_NFLASH_CTL, NCTL_START | code); - for (i = 0; i < NFLASH_READY_RETRIES; i++) { - if (!(bcma_cc_read32(cc, BCMA_CC_NFLASH_CTL) & NCTL_START)) { - i = 0; - break; - } - } - if (i) { - pr_err("NFLASH control command not ready!\n"); - return -EBUSY; - } - return 0; -} - -static int bcm47xxnflash_ops_bcm4706_poll(struct bcma_drv_cc *cc) -{ - int i; - - for (i = 0; i < NFLASH_READY_RETRIES; i++) { - if (bcma_cc_read32(cc, BCMA_CC_NFLASH_CTL) & NCTL_READY) { - if (bcma_cc_read32(cc, BCMA_CC_NFLASH_CTL) & - BCMA_CC_NFLASH_CTL_ERR) { - pr_err("Error on polling\n"); - return -EBUSY; - } else { - return 0; - } - } - } - - pr_err("Polling timeout!\n"); - return -EBUSY; -} - -/************************************************** - * R/W - **************************************************/ - -static void bcm47xxnflash_ops_bcm4706_read(struct mtd_info *mtd, uint8_t *buf, - int len) -{ - struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; - struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; - - u32 ctlcode; - u32 *dest = (u32 *)buf; - int i; - int toread; - - BUG_ON(b47n->curr_page_addr & ~nand_chip->pagemask); - /* Don't validate column using nand_chip->page_shift, it may be bigger - * when accessing OOB */ - - while (len) { - /* We can read maximum of 0x200 bytes at once */ - toread = min(len, 0x200); - - /* Set page and column */ - bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_COL_ADDR, - b47n->curr_column); - bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_ROW_ADDR, - b47n->curr_page_addr); - - /* Prepare to read */ - ctlcode = NCTL_CSA | NCTL_CMD1W | 0x00040000 | 0x00020000 | - NCTL_CMD0; - ctlcode |= NAND_CMD_READSTART << 8; - if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc, ctlcode)) - return; - if (bcm47xxnflash_ops_bcm4706_poll(b47n->cc)) - return; - - /* Eventually read some data :) */ - for (i = 0; i < toread; i += 4, dest++) { - ctlcode = NCTL_CSA | 0x30000000 | NCTL_READ; - if (i == toread - 4) /* Last read goes without that */ - ctlcode &= ~NCTL_CSA; - if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc, - ctlcode)) - return; - *dest = bcma_cc_read32(b47n->cc, BCMA_CC_NFLASH_DATA); - } - - b47n->curr_column += toread; - len -= toread; - } -} - -static void bcm47xxnflash_ops_bcm4706_write(struct mtd_info *mtd, - const uint8_t *buf, int len) -{ - struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; - struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; - struct bcma_drv_cc *cc = b47n->cc; - - u32 ctlcode; - const u32 *data = (u32 *)buf; - int i; - - BUG_ON(b47n->curr_page_addr & ~nand_chip->pagemask); - /* Don't validate column using nand_chip->page_shift, it may be bigger - * when accessing OOB */ - - for (i = 0; i < len; i += 4, data++) { - bcma_cc_write32(cc, BCMA_CC_NFLASH_DATA, *data); - - ctlcode = NCTL_CSA | 0x30000000 | NCTL_WRITE; - if (i == len - 4) /* Last read goes without that */ - ctlcode &= ~NCTL_CSA; - if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, ctlcode)) { - pr_err("%s ctl_cmd didn't work!\n", __func__); - return; - } - } - - b47n->curr_column += len; -} - -/************************************************** - * NAND chip ops - **************************************************/ - -/* Default nand_select_chip calls cmd_ctrl, which is not used in BCM4706 */ -static void bcm47xxnflash_ops_bcm4706_select_chip(struct mtd_info *mtd, - int chip) -{ - return; -} - -/* - * Default nand_command and nand_command_lp don't match BCM4706 hardware layout. - * For example, reading chip id is performed in a non-standard way. - * Setting column and page is also handled differently, we use a special - * registers of ChipCommon core. Hacking cmd_ctrl to understand and convert - * standard commands would be much more complicated. - */ -static void bcm47xxnflash_ops_bcm4706_cmdfunc(struct mtd_info *mtd, - unsigned command, int column, - int page_addr) -{ - struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; - struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; - struct bcma_drv_cc *cc = b47n->cc; - u32 ctlcode; - int i; - - if (column != -1) - b47n->curr_column = column; - if (page_addr != -1) - b47n->curr_page_addr = page_addr; - - switch (command) { - case NAND_CMD_RESET: - pr_warn("Chip reset not implemented yet\n"); - break; - case NAND_CMD_READID: - ctlcode = NCTL_CSA | 0x01000000 | NCTL_CMD1W | NCTL_CMD0; - ctlcode |= NAND_CMD_READID; - if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc, ctlcode)) { - pr_err("READID error\n"); - break; - } - - /* - * Reading is specific, last one has to go without NCTL_CSA - * bit. We don't know how many reads NAND subsystem is going - * to perform, so cache everything. - */ - for (i = 0; i < ARRAY_SIZE(b47n->id_data); i++) { - ctlcode = NCTL_CSA | NCTL_READ; - if (i == ARRAY_SIZE(b47n->id_data) - 1) - ctlcode &= ~NCTL_CSA; - if (bcm47xxnflash_ops_bcm4706_ctl_cmd(b47n->cc, - ctlcode)) { - pr_err("READID error\n"); - break; - } - b47n->id_data[i] = - bcma_cc_read32(b47n->cc, BCMA_CC_NFLASH_DATA) - & 0xFF; - } - - break; - case NAND_CMD_STATUS: - ctlcode = NCTL_CSA | NCTL_CMD0 | NAND_CMD_STATUS; - if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, ctlcode)) - pr_err("STATUS command error\n"); - break; - case NAND_CMD_READ0: - break; - case NAND_CMD_READOOB: - if (page_addr != -1) - b47n->curr_column += mtd->writesize; - break; - case NAND_CMD_ERASE1: - bcma_cc_write32(cc, BCMA_CC_NFLASH_ROW_ADDR, - b47n->curr_page_addr); - ctlcode = 0x00040000 | NCTL_CMD1W | NCTL_CMD0 | - NAND_CMD_ERASE1 | (NAND_CMD_ERASE2 << 8); - if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, ctlcode)) - pr_err("ERASE1 failed\n"); - break; - case NAND_CMD_ERASE2: - break; - case NAND_CMD_SEQIN: - /* Set page and column */ - bcma_cc_write32(cc, BCMA_CC_NFLASH_COL_ADDR, - b47n->curr_column); - bcma_cc_write32(cc, BCMA_CC_NFLASH_ROW_ADDR, - b47n->curr_page_addr); - - /* Prepare to write */ - ctlcode = 0x40000000 | 0x00040000 | 0x00020000 | 0x00010000; - ctlcode |= NAND_CMD_SEQIN; - if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, ctlcode)) - pr_err("SEQIN failed\n"); - break; - case NAND_CMD_PAGEPROG: - if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, 0x00010000 | - NAND_CMD_PAGEPROG)) - pr_err("PAGEPROG failed\n"); - if (bcm47xxnflash_ops_bcm4706_poll(cc)) - pr_err("PAGEPROG not ready\n"); - break; - default: - pr_err("Command 0x%X unsupported\n", command); - break; - } - b47n->curr_command = command; -} - -static u8 bcm47xxnflash_ops_bcm4706_read_byte(struct mtd_info *mtd) -{ - struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; - struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; - struct bcma_drv_cc *cc = b47n->cc; - u32 tmp = 0; - - switch (b47n->curr_command) { - case NAND_CMD_READID: - if (b47n->curr_column >= ARRAY_SIZE(b47n->id_data)) { - pr_err("Requested invalid id_data: %d\n", - b47n->curr_column); - return 0; - } - return b47n->id_data[b47n->curr_column++]; - case NAND_CMD_STATUS: - if (bcm47xxnflash_ops_bcm4706_ctl_cmd(cc, NCTL_READ)) - return 0; - return bcma_cc_read32(cc, BCMA_CC_NFLASH_DATA) & 0xff; - case NAND_CMD_READOOB: - bcm47xxnflash_ops_bcm4706_read(mtd, (u8 *)&tmp, 4); - return tmp & 0xFF; - } - - pr_err("Invalid command for byte read: 0x%X\n", b47n->curr_command); - return 0; -} - -static void bcm47xxnflash_ops_bcm4706_read_buf(struct mtd_info *mtd, - uint8_t *buf, int len) -{ - struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; - struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; - - switch (b47n->curr_command) { - case NAND_CMD_READ0: - case NAND_CMD_READOOB: - bcm47xxnflash_ops_bcm4706_read(mtd, buf, len); - return; - } - - pr_err("Invalid command for buf read: 0x%X\n", b47n->curr_command); -} - -static void bcm47xxnflash_ops_bcm4706_write_buf(struct mtd_info *mtd, - const uint8_t *buf, int len) -{ - struct nand_chip *nand_chip = (struct nand_chip *)mtd->priv; - struct bcm47xxnflash *b47n = (struct bcm47xxnflash *)nand_chip->priv; - - switch (b47n->curr_command) { - case NAND_CMD_SEQIN: - bcm47xxnflash_ops_bcm4706_write(mtd, buf, len); - return; - } - - pr_err("Invalid command for buf write: 0x%X\n", b47n->curr_command); -} - -/************************************************** - * Init - **************************************************/ - -int bcm47xxnflash_ops_bcm4706_init(struct bcm47xxnflash *b47n) -{ - int err; - u32 freq; - u16 clock; - u8 w0, w1, w2, w3, w4; - - unsigned long chipsize; /* MiB */ - u8 tbits, col_bits, col_size, row_bits, row_bsize; - u32 val; - - b47n->nand_chip.select_chip = bcm47xxnflash_ops_bcm4706_select_chip; - b47n->nand_chip.cmdfunc = bcm47xxnflash_ops_bcm4706_cmdfunc; - b47n->nand_chip.read_byte = bcm47xxnflash_ops_bcm4706_read_byte; - b47n->nand_chip.read_buf = bcm47xxnflash_ops_bcm4706_read_buf; - b47n->nand_chip.write_buf = bcm47xxnflash_ops_bcm4706_write_buf; - b47n->nand_chip.bbt_options = NAND_BBT_USE_FLASH; - b47n->nand_chip.ecc.mode = NAND_ECC_NONE; /* TODO: implement ECC */ - - /* Enable NAND flash access */ - bcma_cc_set32(b47n->cc, BCMA_CC_4706_FLASHSCFG, - BCMA_CC_4706_FLASHSCFG_NF1); - - /* Configure wait counters */ - if (b47n->cc->status & BCMA_CC_CHIPST_4706_PKG_OPTION) { - freq = 100000000; - } else { - freq = bcma_chipco_pll_read(b47n->cc, 4); - freq = (freq * 0xFFF) >> 3; - freq = (freq * 25000000) >> 3; - } - clock = freq / 1000000; - w0 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(15, clock); - w1 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(20, clock); - w2 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(10, clock); - w3 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(10, clock); - w4 = bcm47xxnflash_ops_bcm4706_ns_to_cycle(100, clock); - bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_WAITCNT0, - (w4 << 24 | w3 << 18 | w2 << 12 | w1 << 6 | w0)); - - /* Scan NAND */ - err = nand_scan(&b47n->mtd, 1); - if (err) { - pr_err("Could not scan NAND flash: %d\n", err); - goto exit; - } - - /* Configure FLASH */ - chipsize = b47n->nand_chip.chipsize >> 20; - tbits = ffs(chipsize); /* find first bit set */ - if (!tbits || tbits != fls(chipsize)) { - pr_err("Invalid flash size: 0x%lX\n", chipsize); - err = -ENOTSUPP; - goto exit; - } - tbits += 19; /* Broadcom increases *index* by 20, we increase *pos* */ - - col_bits = b47n->nand_chip.page_shift + 1; - col_size = (col_bits + 7) / 8; - - row_bits = tbits - col_bits + 1; - row_bsize = (row_bits + 7) / 8; - - val = ((row_bsize - 1) << 6) | ((col_size - 1) << 4) | 2; - bcma_cc_write32(b47n->cc, BCMA_CC_NFLASH_CONF, val); - -exit: - if (err) - bcma_cc_mask32(b47n->cc, BCMA_CC_4706_FLASHSCFG, - ~BCMA_CC_4706_FLASHSCFG_NF1); - return err; -} diff --git a/trunk/drivers/mtd/nand/bf5xx_nand.c b/trunk/drivers/mtd/nand/bf5xx_nand.c index 4271e948d1e2..ab0caa74eb43 100644 --- a/trunk/drivers/mtd/nand/bf5xx_nand.c +++ b/trunk/drivers/mtd/nand/bf5xx_nand.c @@ -658,7 +658,7 @@ static int bf5xx_nand_hw_init(struct bf5xx_nand_info *info) /* * Device management interface */ -static int bf5xx_nand_add_partition(struct bf5xx_nand_info *info) +static int __devinit bf5xx_nand_add_partition(struct bf5xx_nand_info *info) { struct mtd_info *mtd = &info->mtd; struct mtd_partition *parts = info->platform->partitions; @@ -667,7 +667,7 @@ static int bf5xx_nand_add_partition(struct bf5xx_nand_info *info) return mtd_device_register(mtd, parts, nr); } -static int bf5xx_nand_remove(struct platform_device *pdev) +static int __devexit bf5xx_nand_remove(struct platform_device *pdev) { struct bf5xx_nand_info *info = to_nand_info(pdev); @@ -725,7 +725,7 @@ static int bf5xx_nand_scan(struct mtd_info *mtd) * it can allocate all necessary resources then calls the * nand layer to look for devices */ -static int bf5xx_nand_probe(struct platform_device *pdev) +static int __devinit bf5xx_nand_probe(struct platform_device *pdev) { struct bf5xx_nand_platform *plat = to_nand_plat(pdev); struct bf5xx_nand_info *info = NULL; @@ -865,7 +865,7 @@ static int bf5xx_nand_resume(struct platform_device *dev) /* driver device registration */ static struct platform_driver bf5xx_nand_driver = { .probe = bf5xx_nand_probe, - .remove = bf5xx_nand_remove, + .remove = __devexit_p(bf5xx_nand_remove), .suspend = bf5xx_nand_suspend, .resume = bf5xx_nand_resume, .driver = { diff --git a/trunk/drivers/mtd/nand/cafe_nand.c b/trunk/drivers/mtd/nand/cafe_nand.c index 010d61266536..2bb7170502c2 100644 --- a/trunk/drivers/mtd/nand/cafe_nand.c +++ b/trunk/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) } /* F_2[X]/(X**6+X+1) */ -static unsigned short gf64_mul(u8 a, u8 b) +static unsigned short __devinit gf64_mul(u8 a, u8 b) { u8 c; unsigned int i; @@ -604,7 +604,7 @@ static unsigned short gf64_mul(u8 a, u8 b) } /* F_64[X]/(X**2+X+A**-1) with A the generator of F_64[X] */ -static u16 gf4096_mul(u16 a, u16 b) +static u16 __devinit gf4096_mul(u16 a, u16 b) { u8 ah, al, bh, bl, ch, cl; @@ -619,14 +619,14 @@ static u16 gf4096_mul(u16 a, u16 b) return (ch << 6) ^ cl; } -static int cafe_mul(int x) +static int __devinit cafe_mul(int x) { if (x == 0) return 1; return gf4096_mul(x, 0xe01); } -static int cafe_nand_probe(struct pci_dev *pdev, +static int __devinit cafe_nand_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { struct mtd_info *mtd; @@ -821,7 +821,7 @@ static int cafe_nand_probe(struct pci_dev *pdev, return err; } -static void cafe_nand_remove(struct pci_dev *pdev) +static void __devexit cafe_nand_remove(struct pci_dev *pdev) { struct mtd_info *mtd = pci_get_drvdata(pdev); struct cafe_priv *cafe = mtd->priv; @@ -887,7 +887,7 @@ static struct pci_driver cafe_nand_pci_driver = { .name = "CAFÉ NAND", .id_table = cafe_nand_tbl, .probe = cafe_nand_probe, - .remove = cafe_nand_remove, + .remove = __devexit_p(cafe_nand_remove), .resume = cafe_nand_resume, }; diff --git a/trunk/drivers/mtd/nand/cs553x_nand.c b/trunk/drivers/mtd/nand/cs553x_nand.c index 2cdeab8bebc4..adb6c3ef37fb 100644 --- a/trunk/drivers/mtd/nand/cs553x_nand.c +++ b/trunk/drivers/mtd/nand/cs553x_nand.c @@ -237,7 +237,6 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr) this->ecc.hwctl = cs_enable_hwecc; this->ecc.calculate = cs_calculate_ecc; this->ecc.correct = nand_correct_data; - this->ecc.strength = 1; /* Enable the following for a flash based bad block table */ this->bbt_options = NAND_BBT_USE_FLASH; @@ -248,6 +247,8 @@ static int __init cs553x_init_one(int cs, int mmio, unsigned long adr) goto out_ior; } + this->ecc.strength = 1; + new_mtd->name = kasprintf(GFP_KERNEL, "cs553x_nand_cs%d", cs); cs553x_mtd[cs] = new_mtd; diff --git a/trunk/drivers/mtd/nand/davinci_nand.c b/trunk/drivers/mtd/nand/davinci_nand.c index 3502606f6480..945047ad0952 100644 --- a/trunk/drivers/mtd/nand/davinci_nand.c +++ b/trunk/drivers/mtd/nand/davinci_nand.c @@ -821,16 +821,9 @@ static int __init nand_davinci_probe(struct platform_device *pdev) if (ret < 0) goto err_scan; - if (pdata->parts) - ret = mtd_device_parse_register(&info->mtd, NULL, NULL, - pdata->parts, pdata->nr_parts); - else { - struct mtd_part_parser_data ppdata; - - ppdata.of_node = pdev->dev.of_node; - ret = mtd_device_parse_register(&info->mtd, NULL, &ppdata, - NULL, 0); - } + ret = mtd_device_parse_register(&info->mtd, NULL, NULL, pdata->parts, + pdata->nr_parts); + if (ret < 0) goto err_scan; diff --git a/trunk/drivers/mtd/nand/denali.c b/trunk/drivers/mtd/nand/denali.c index 0c8bb6bf8424..e706a237170f 100644 --- a/trunk/drivers/mtd/nand/denali.c +++ b/trunk/drivers/mtd/nand/denali.c @@ -16,12 +16,14 @@ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. * */ + #include #include #include #include #include #include +#include #include #include @@ -87,6 +89,13 @@ MODULE_PARM_DESC(onfi_timing_mode, "Overrides default ONFI setting." * format the bank into the proper bits for the controller */ #define BANK(x) ((x) << 24) +/* List of platforms this NAND controller has be integrated into */ +static const struct pci_device_id denali_pci_ids[] = { + { PCI_VDEVICE(INTEL, 0x0701), INTEL_CE4100 }, + { PCI_VDEVICE(INTEL, 0x0809), INTEL_MRST }, + { /* end: all zeroes */ } +}; + /* forward declarations */ static void clear_interrupts(struct denali_nand_info *denali); static uint32_t wait_for_irq(struct denali_nand_info *denali, @@ -690,7 +699,7 @@ static uint32_t wait_for_irq(struct denali_nand_info *denali, uint32_t irq_mask) if (comp_res == 0) { /* timeout */ - pr_err("timeout occurred, status = 0x%x, mask = 0x%x\n", + printk(KERN_ERR "timeout occurred, status = 0x%x, mask = 0x%x\n", intr_status, irq_mask); intr_status = 0; @@ -1296,7 +1305,8 @@ static void denali_cmdfunc(struct mtd_info *mtd, unsigned int cmd, int col, /* TODO: Read OOB data */ break; default: - pr_err(": unsupported command received 0x%x\n", cmd); + printk(KERN_ERR ": unsupported command" + " received 0x%x\n", cmd); break; } } @@ -1415,48 +1425,107 @@ void denali_drv_init(struct denali_nand_info *denali) denali->irq_status = 0; } -int denali_init(struct denali_nand_info *denali) +/* driver entry point */ +static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) { - int ret; + int ret = -ENODEV; + resource_size_t csr_base, mem_base; + unsigned long csr_len, mem_len; + struct denali_nand_info *denali; - if (denali->platform == INTEL_CE4100) { + denali = kzalloc(sizeof(*denali), GFP_KERNEL); + if (!denali) + return -ENOMEM; + + ret = pci_enable_device(dev); + if (ret) { + printk(KERN_ERR "Spectra: pci_enable_device failed.\n"); + goto failed_alloc_memery; + } + + if (id->driver_data == INTEL_CE4100) { /* Due to a silicon limitation, we can only support * ONFI timing mode 1 and below. */ if (onfi_timing_mode < -1 || onfi_timing_mode > 1) { - pr_err("Intel CE4100 only supports ONFI timing mode 1 or below\n"); - return -EINVAL; + printk(KERN_ERR "Intel CE4100 only supports" + " ONFI timing mode 1 or below\n"); + ret = -EINVAL; + goto failed_enable_dev; + } + denali->platform = INTEL_CE4100; + mem_base = pci_resource_start(dev, 0); + mem_len = pci_resource_len(dev, 1); + csr_base = pci_resource_start(dev, 1); + csr_len = pci_resource_len(dev, 1); + } else { + denali->platform = INTEL_MRST; + csr_base = pci_resource_start(dev, 0); + csr_len = pci_resource_len(dev, 0); + mem_base = pci_resource_start(dev, 1); + mem_len = pci_resource_len(dev, 1); + if (!mem_len) { + mem_base = csr_base + csr_len; + mem_len = csr_len; } } /* Is 32-bit DMA supported? */ - ret = dma_set_mask(denali->dev, DMA_BIT_MASK(32)); + ret = dma_set_mask(&dev->dev, DMA_BIT_MASK(32)); if (ret) { - pr_err("Spectra: no usable DMA configuration\n"); - return ret; + printk(KERN_ERR "Spectra: no usable DMA configuration\n"); + goto failed_enable_dev; } - denali->buf.dma_buf = dma_map_single(denali->dev, denali->buf.buf, + denali->buf.dma_buf = dma_map_single(&dev->dev, denali->buf.buf, DENALI_BUF_SIZE, DMA_BIDIRECTIONAL); - if (dma_mapping_error(denali->dev, denali->buf.dma_buf)) { - dev_err(denali->dev, "Spectra: failed to map DMA buffer\n"); - return -EIO; + if (dma_mapping_error(&dev->dev, denali->buf.dma_buf)) { + dev_err(&dev->dev, "Spectra: failed to map DMA buffer\n"); + goto failed_enable_dev; + } + + pci_set_master(dev); + denali->dev = &dev->dev; + denali->mtd.dev.parent = &dev->dev; + + ret = pci_request_regions(dev, DENALI_NAND_NAME); + if (ret) { + printk(KERN_ERR "Spectra: Unable to request memory regions\n"); + goto failed_dma_map; + } + + denali->flash_reg = ioremap_nocache(csr_base, csr_len); + if (!denali->flash_reg) { + printk(KERN_ERR "Spectra: Unable to remap memory region\n"); + ret = -ENOMEM; + goto failed_req_regions; + } + + denali->flash_mem = ioremap_nocache(mem_base, mem_len); + if (!denali->flash_mem) { + printk(KERN_ERR "Spectra: ioremap_nocache failed!"); + ret = -ENOMEM; + goto failed_remap_reg; } - denali->mtd.dev.parent = denali->dev; + denali_hw_init(denali); denali_drv_init(denali); /* denali_isr register is done after all the hardware * initilization is finished*/ - if (request_irq(denali->irq, denali_isr, IRQF_SHARED, + if (request_irq(dev->irq, denali_isr, IRQF_SHARED, DENALI_NAND_NAME, denali)) { - pr_err("Spectra: Unable to allocate IRQ\n"); - return -ENODEV; + printk(KERN_ERR "Spectra: Unable to allocate IRQ\n"); + ret = -ENODEV; + goto failed_remap_mem; } /* now that our ISR is registered, we can enable interrupts */ denali_set_intr_modes(denali, true); + + pci_set_drvdata(dev, denali); + denali->mtd.name = "denali-nand"; denali->mtd.owner = THIS_MODULE; denali->mtd.priv = &denali->nand; @@ -1480,7 +1549,8 @@ int denali_init(struct denali_nand_info *denali) */ if (denali->mtd.writesize > NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE) { ret = -ENODEV; - pr_err("Spectra: device size not supported by this version of MTD."); + printk(KERN_ERR "Spectra: device size not supported by this " + "version of MTD."); goto failed_req_irq; } @@ -1532,8 +1602,8 @@ int denali_init(struct denali_nand_info *denali) } else if (denali->mtd.oobsize < (denali->bbtskipbytes + ECC_8BITS * (denali->mtd.writesize / ECC_SECTOR_SIZE))) { - pr_err("Your NAND chip OOB is not large enough to \ - contain 8bit ECC correction codes"); + printk(KERN_ERR "Your NAND chip OOB is not large enough to" + " contain 8bit ECC correction codes"); goto failed_req_irq; } else { denali->nand.ecc.strength = 8; @@ -1585,24 +1655,56 @@ int denali_init(struct denali_nand_info *denali) ret = mtd_device_register(&denali->mtd, NULL, 0); if (ret) { - dev_err(denali->dev, "Spectra: Failed to register MTD: %d\n", + dev_err(&dev->dev, "Spectra: Failed to register MTD: %d\n", ret); goto failed_req_irq; } return 0; failed_req_irq: - denali_irq_cleanup(denali->irq, denali); - + denali_irq_cleanup(dev->irq, denali); +failed_remap_mem: + iounmap(denali->flash_mem); +failed_remap_reg: + iounmap(denali->flash_reg); +failed_req_regions: + pci_release_regions(dev); +failed_dma_map: + dma_unmap_single(&dev->dev, denali->buf.dma_buf, DENALI_BUF_SIZE, + DMA_BIDIRECTIONAL); +failed_enable_dev: + pci_disable_device(dev); +failed_alloc_memery: + kfree(denali); return ret; } -EXPORT_SYMBOL(denali_init); /* driver exit point */ -void denali_remove(struct denali_nand_info *denali) +static void denali_pci_remove(struct pci_dev *dev) { - denali_irq_cleanup(denali->irq, denali); - dma_unmap_single(denali->dev, denali->buf.dma_buf, DENALI_BUF_SIZE, - DMA_BIDIRECTIONAL); + struct denali_nand_info *denali = pci_get_drvdata(dev); + + nand_release(&denali->mtd); + + denali_irq_cleanup(dev->irq, denali); + + iounmap(denali->flash_reg); + iounmap(denali->flash_mem); + pci_release_regions(dev); + pci_disable_device(dev); + dma_unmap_single(&dev->dev, denali->buf.dma_buf, DENALI_BUF_SIZE, + DMA_BIDIRECTIONAL); + pci_set_drvdata(dev, NULL); + kfree(denali); } -EXPORT_SYMBOL(denali_remove); + +MODULE_DEVICE_TABLE(pci, denali_pci_ids); + +static struct pci_driver denali_pci_driver = { + .name = DENALI_NAND_NAME, + .id_table = denali_pci_ids, + .probe = denali_pci_probe, + .remove = denali_pci_remove, +}; + +module_pci_driver(denali_pci_driver); diff --git a/trunk/drivers/mtd/nand/denali.h b/trunk/drivers/mtd/nand/denali.h index cec5712862c9..fabb9d56b39e 100644 --- a/trunk/drivers/mtd/nand/denali.h +++ b/trunk/drivers/mtd/nand/denali.h @@ -466,7 +466,6 @@ struct nand_buf { #define INTEL_CE4100 1 #define INTEL_MRST 2 -#define DT 3 struct denali_nand_info { struct mtd_info mtd; @@ -488,7 +487,6 @@ struct denali_nand_info { uint32_t irq_status; int irq_debug_array[32]; int idx; - int irq; uint32_t devnum; /* represent how many nands connected */ uint32_t fwblks; /* represent how many blocks FW used */ @@ -498,7 +496,4 @@ struct denali_nand_info { uint32_t max_banks; }; -extern int denali_init(struct denali_nand_info *denali); -extern void denali_remove(struct denali_nand_info *denali); - #endif /*_LLD_NAND_*/ diff --git a/trunk/drivers/mtd/nand/denali_dt.c b/trunk/drivers/mtd/nand/denali_dt.c deleted file mode 100644 index 546f8cb5688d..000000000000 --- a/trunk/drivers/mtd/nand/denali_dt.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * NAND Flash Controller Device Driver for DT - * - * Copyright © 2011, Picochip. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "denali.h" - -struct denali_dt { - struct denali_nand_info denali; - struct clk *clk; -}; - -static void __iomem *request_and_map(struct device *dev, - const struct resource *res) -{ - void __iomem *ptr; - - if (!devm_request_mem_region(dev, res->start, resource_size(res), - "denali-dt")) { - dev_err(dev, "unable to request %s\n", res->name); - return NULL; - } - - ptr = devm_ioremap_nocache(dev, res->start, resource_size(res)); - if (!res) - dev_err(dev, "ioremap_nocache of %s failed!", res->name); - - return ptr; -} - -static const struct of_device_id denali_nand_dt_ids[] = { - { .compatible = "denali,denali-nand-dt" }, - { /* sentinel */ } - }; - -MODULE_DEVICE_TABLE(of, denali_nand_dt_ids); - -static u64 denali_dma_mask; - -static int denali_dt_probe(struct platform_device *ofdev) -{ - struct resource *denali_reg, *nand_data; - struct denali_dt *dt; - struct denali_nand_info *denali; - int ret; - const struct of_device_id *of_id; - - of_id = of_match_device(denali_nand_dt_ids, &ofdev->dev); - if (of_id) { - ofdev->id_entry = of_id->data; - } else { - pr_err("Failed to find the right device id.\n"); - return -ENOMEM; - } - - dt = devm_kzalloc(&ofdev->dev, sizeof(*dt), GFP_KERNEL); - if (!dt) - return -ENOMEM; - denali = &dt->denali; - - denali_reg = platform_get_resource_byname(ofdev, IORESOURCE_MEM, "denali_reg"); - nand_data = platform_get_resource_byname(ofdev, IORESOURCE_MEM, "nand_data"); - if (!denali_reg || !nand_data) { - dev_err(&ofdev->dev, "resources not completely defined\n"); - return -EINVAL; - } - - denali->platform = DT; - denali->dev = &ofdev->dev; - denali->irq = platform_get_irq(ofdev, 0); - if (denali->irq < 0) { - dev_err(&ofdev->dev, "no irq defined\n"); - return -ENXIO; - } - - denali->flash_reg = request_and_map(&ofdev->dev, denali_reg); - if (!denali->flash_reg) - return -ENOMEM; - - denali->flash_mem = request_and_map(&ofdev->dev, nand_data); - if (!denali->flash_mem) - return -ENOMEM; - - if (!of_property_read_u32(ofdev->dev.of_node, - "dma-mask", (u32 *)&denali_dma_mask)) { - denali->dev->dma_mask = &denali_dma_mask; - } else { - denali->dev->dma_mask = NULL; - } - - dt->clk = clk_get(&ofdev->dev, NULL); - if (IS_ERR(dt->clk)) { - dev_err(&ofdev->dev, "no clk available\n"); - return PTR_ERR(dt->clk); - } - clk_prepare_enable(dt->clk); - - ret = denali_init(denali); - if (ret) - goto out_disable_clk; - - platform_set_drvdata(ofdev, dt); - return 0; - -out_disable_clk: - clk_disable_unprepare(dt->clk); - clk_put(dt->clk); - - return ret; -} - -static int denali_dt_remove(struct platform_device *ofdev) -{ - struct denali_dt *dt = platform_get_drvdata(ofdev); - - denali_remove(&dt->denali); - clk_disable(dt->clk); - clk_put(dt->clk); - - return 0; -} - -static struct platform_driver denali_dt_driver = { - .probe = denali_dt_probe, - .remove = denali_dt_remove, - .driver = { - .name = "denali-nand-dt", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(denali_nand_dt_ids), - }, -}; - -static int __init denali_init_dt(void) -{ - return platform_driver_register(&denali_dt_driver); -} -module_init(denali_init_dt); - -static void __exit denali_exit_dt(void) -{ - platform_driver_unregister(&denali_dt_driver); -} -module_exit(denali_exit_dt); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Jamie Iles"); -MODULE_DESCRIPTION("DT driver for Denali NAND controller"); diff --git a/trunk/drivers/mtd/nand/denali_pci.c b/trunk/drivers/mtd/nand/denali_pci.c deleted file mode 100644 index e3e46623b2b4..000000000000 --- a/trunk/drivers/mtd/nand/denali_pci.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * NAND Flash Controller Device Driver - * Copyright © 2009-2010, Intel Corporation and its suppliers. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - */ -#include -#include -#include -#include - -#include "denali.h" - -#define DENALI_NAND_NAME "denali-nand-pci" - -/* List of platforms this NAND controller has be integrated into */ -static DEFINE_PCI_DEVICE_TABLE(denali_pci_ids) = { - { PCI_VDEVICE(INTEL, 0x0701), INTEL_CE4100 }, - { PCI_VDEVICE(INTEL, 0x0809), INTEL_MRST }, - { /* end: all zeroes */ } -}; -MODULE_DEVICE_TABLE(pci, denali_pci_ids); - -static int denali_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) -{ - int ret = -ENODEV; - resource_size_t csr_base, mem_base; - unsigned long csr_len, mem_len; - struct denali_nand_info *denali; - - denali = kzalloc(sizeof(*denali), GFP_KERNEL); - if (!denali) - return -ENOMEM; - - ret = pci_enable_device(dev); - if (ret) { - pr_err("Spectra: pci_enable_device failed.\n"); - goto failed_alloc_memery; - } - - if (id->driver_data == INTEL_CE4100) { - denali->platform = INTEL_CE4100; - mem_base = pci_resource_start(dev, 0); - mem_len = pci_resource_len(dev, 1); - csr_base = pci_resource_start(dev, 1); - csr_len = pci_resource_len(dev, 1); - } else { - denali->platform = INTEL_MRST; - csr_base = pci_resource_start(dev, 0); - csr_len = pci_resource_len(dev, 0); - mem_base = pci_resource_start(dev, 1); - mem_len = pci_resource_len(dev, 1); - if (!mem_len) { - mem_base = csr_base + csr_len; - mem_len = csr_len; - } - } - - pci_set_master(dev); - denali->dev = &dev->dev; - denali->irq = dev->irq; - - ret = pci_request_regions(dev, DENALI_NAND_NAME); - if (ret) { - pr_err("Spectra: Unable to request memory regions\n"); - goto failed_enable_dev; - } - - denali->flash_reg = ioremap_nocache(csr_base, csr_len); - if (!denali->flash_reg) { - pr_err("Spectra: Unable to remap memory region\n"); - ret = -ENOMEM; - goto failed_req_regions; - } - - denali->flash_mem = ioremap_nocache(mem_base, mem_len); - if (!denali->flash_mem) { - pr_err("Spectra: ioremap_nocache failed!"); - ret = -ENOMEM; - goto failed_remap_reg; - } - - ret = denali_init(denali); - if (ret) - goto failed_remap_mem; - - pci_set_drvdata(dev, denali); - - return 0; - -failed_remap_mem: - iounmap(denali->flash_mem); -failed_remap_reg: - iounmap(denali->flash_reg); -failed_req_regions: - pci_release_regions(dev); -failed_enable_dev: - pci_disable_device(dev); -failed_alloc_memery: - kfree(denali); - - return ret; -} - -/* driver exit point */ -static void denali_pci_remove(struct pci_dev *dev) -{ - struct denali_nand_info *denali = pci_get_drvdata(dev); - - denali_remove(denali); - iounmap(denali->flash_reg); - iounmap(denali->flash_mem); - pci_release_regions(dev); - pci_disable_device(dev); - pci_set_drvdata(dev, NULL); - kfree(denali); -} - -static struct pci_driver denali_pci_driver = { - .name = DENALI_NAND_NAME, - .id_table = denali_pci_ids, - .probe = denali_pci_probe, - .remove = denali_pci_remove, -}; - -static int denali_init_pci(void) -{ - pr_info("Spectra MTD driver built on %s @ %s\n", __DATE__, __TIME__); - return pci_register_driver(&denali_pci_driver); -} -module_init(denali_init_pci); - -static void denali_exit_pci(void) -{ - pci_unregister_driver(&denali_pci_driver); -} -module_exit(denali_exit_pci); diff --git a/trunk/drivers/mtd/nand/diskonchip.c b/trunk/drivers/mtd/nand/diskonchip.c index 81fa5784f98b..256eb30f6180 100644 --- a/trunk/drivers/mtd/nand/diskonchip.c +++ b/trunk/drivers/mtd/nand/diskonchip.c @@ -53,6 +53,8 @@ static unsigned long __initdata doc_locations[] = { 0xe0000, 0xe2000, 0xe4000, 0xe6000, 0xe8000, 0xea000, 0xec000, 0xee000, #endif /* CONFIG_MTD_DOCPROBE_HIGH */ +#else +#warning Unknown architecture for DiskOnChip. No default probe locations defined #endif 0xffffffff }; diff --git a/trunk/drivers/mtd/nand/docg4.c b/trunk/drivers/mtd/nand/docg4.c index 18fa4489e52e..799da5d1c857 100644 --- a/trunk/drivers/mtd/nand/docg4.c +++ b/trunk/drivers/mtd/nand/docg4.c @@ -45,25 +45,6 @@ #include #include -/* - * In "reliable mode" consecutive 2k pages are used in parallel (in some - * fashion) to store the same data. The data can be read back from the - * even-numbered pages in the normal manner; odd-numbered pages will appear to - * contain junk. Systems that boot from the docg4 typically write the secondary - * program loader (SPL) code in this mode. The SPL is loaded by the initial - * program loader (IPL, stored in the docg4's 2k NOR-like region that is mapped - * to the reset vector address). This module parameter enables you to use this - * driver to write the SPL. When in this mode, no more than 2k of data can be - * written at a time, because the addresses do not increment in the normal - * manner, and the starting offset must be within an even-numbered 2k region; - * i.e., invalid starting offsets are 0x800, 0xa00, 0xc00, 0xe00, 0x1800, - * 0x1a00, ... Reliable mode is a special case and should not be used unless - * you know what you're doing. - */ -static bool reliable_mode; -module_param(reliable_mode, bool, 0); -MODULE_PARM_DESC(reliable_mode, "pages are programmed in reliable mode"); - /* * You'll want to ignore badblocks if you're reading a partition that contains * data written by the TrueFFS library (i.e., by PalmOS, Windows, etc), since @@ -132,7 +113,6 @@ struct docg4_priv { #define DOCG4_SEQ_PAGEWRITE 0x16 #define DOCG4_SEQ_PAGEPROG 0x1e #define DOCG4_SEQ_BLOCKERASE 0x24 -#define DOCG4_SEQ_SETMODE 0x45 /* DOC_FLASHCOMMAND register commands */ #define DOCG4_CMD_PAGE_READ 0x00 @@ -142,8 +122,6 @@ struct docg4_priv { #define DOC_CMD_PROG_BLOCK_ADDR 0x60 #define DOCG4_CMD_PAGEWRITE 0x80 #define DOC_CMD_PROG_CYCLE2 0x10 -#define DOCG4_CMD_FAST_MODE 0xa3 /* functionality guessed */ -#define DOC_CMD_RELIABLE_MODE 0x22 #define DOC_CMD_RESET 0xff /* DOC_POWERMODE register bits */ @@ -212,20 +190,17 @@ struct docg4_priv { #define DOCG4_T 4 /* BCH alg corrects up to 4 bit errors */ #define DOCG4_FACTORY_BBT_PAGE 16 /* page where read-only factory bbt lives */ -#define DOCG4_REDUNDANT_BBT_PAGE 24 /* page where redundant factory bbt lives */ /* - * Bytes 0, 1 are used as badblock marker. - * Bytes 2 - 6 are available to the user. - * Byte 7 is hamming ecc for first 7 oob bytes only. - * Bytes 8 - 14 are hw-generated ecc covering entire page + oob bytes 0 - 14. + * Oob bytes 0 - 6 are available to the user. + * Byte 7 is hamming ecc for first 7 bytes. Bytes 8 - 14 are hw-generated ecc. * Byte 15 (the last) is used by the driver as a "page written" flag. */ static struct nand_ecclayout docg4_oobinfo = { .eccbytes = 9, .eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15}, - .oobavail = 5, - .oobfree = { {.offset = 2, .length = 5} } + .oobavail = 7, + .oobfree = { {0, 7} } }; /* @@ -636,14 +611,6 @@ static void write_page_prologue(struct mtd_info *mtd, uint32_t docg4_addr) dev_dbg(doc->dev, "docg4: %s: g4 addr: %x\n", __func__, docg4_addr); sequence_reset(mtd); - - if (unlikely(reliable_mode)) { - writew(DOCG4_SEQ_SETMODE, docptr + DOC_FLASHSEQUENCE); - writew(DOCG4_CMD_FAST_MODE, docptr + DOC_FLASHCOMMAND); - writew(DOC_CMD_RELIABLE_MODE, docptr + DOC_FLASHCOMMAND); - write_nop(docptr); - } - writew(DOCG4_SEQ_PAGEWRITE, docptr + DOC_FLASHSEQUENCE); writew(DOCG4_CMD_PAGEWRITE, docptr + DOC_FLASHCOMMAND); write_nop(docptr); @@ -724,15 +691,6 @@ static void docg4_command(struct mtd_info *mtd, unsigned command, int column, break; case NAND_CMD_SEQIN: - if (unlikely(reliable_mode)) { - uint16_t g4_page = g4_addr >> 16; - - /* writes to odd-numbered 2k pages are invalid */ - if (g4_page & 0x01) - dev_warn(doc->dev, - "invalid reliable mode address\n"); - } - write_page_prologue(mtd, g4_addr); /* hack for deferred write of oob bytes */ @@ -1021,15 +979,16 @@ static int __init read_factory_bbt(struct mtd_info *mtd) struct docg4_priv *doc = nand->priv; uint32_t g4_addr = mtd_to_docg4_address(DOCG4_FACTORY_BBT_PAGE, 0); uint8_t *buf; - int i, block; - __u32 eccfailed_stats = mtd->ecc_stats.failed; + int i, block, status; buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL); if (buf == NULL) return -ENOMEM; read_page_prologue(mtd, g4_addr); - docg4_read_page(mtd, nand, buf, 0, DOCG4_FACTORY_BBT_PAGE); + status = docg4_read_page(mtd, nand, buf, 0, DOCG4_FACTORY_BBT_PAGE); + if (status) + goto exit; /* * If no memory-based bbt was created, exit. This will happen if module @@ -1041,20 +1000,6 @@ static int __init read_factory_bbt(struct mtd_info *mtd) if (nand->bbt == NULL) /* no memory-based bbt */ goto exit; - if (mtd->ecc_stats.failed > eccfailed_stats) { - /* - * Whoops, an ecc failure ocurred reading the factory bbt. - * It is stored redundantly, so we get another chance. - */ - eccfailed_stats = mtd->ecc_stats.failed; - docg4_read_page(mtd, nand, buf, 0, DOCG4_REDUNDANT_BBT_PAGE); - if (mtd->ecc_stats.failed > eccfailed_stats) { - dev_warn(doc->dev, - "The factory bbt could not be read!\n"); - goto exit; - } - } - /* * Parse factory bbt and update memory-based bbt. Factory bbt format is * simple: one bit per block, block numbers increase left to right (msb @@ -1074,7 +1019,7 @@ static int __init read_factory_bbt(struct mtd_info *mtd) } exit: kfree(buf); - return 0; + return status; } static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs) diff --git a/trunk/drivers/mtd/nand/fsl_elbc_nand.c b/trunk/drivers/mtd/nand/fsl_elbc_nand.c index 20657209a472..cc1480a5e4c1 100644 --- a/trunk/drivers/mtd/nand/fsl_elbc_nand.c +++ b/trunk/drivers/mtd/nand/fsl_elbc_nand.c @@ -108,6 +108,20 @@ static struct nand_ecclayout fsl_elbc_oob_lp_eccm1 = { .oobfree = { {1, 7}, {11, 13}, {27, 13}, {43, 13}, {59, 5} }, }; +/* + * fsl_elbc_oob_lp_eccm* specify that LP NAND's OOB free area starts at offset + * 1, so we have to adjust bad block pattern. This pattern should be used for + * x8 chips only. So far hardware does not support x16 chips anyway. + */ +static u8 scan_ff_pattern[] = { 0xff, }; + +static struct nand_bbt_descr largepage_memorybased = { + .options = 0, + .offs = 0, + .len = 1, + .pattern = scan_ff_pattern, +}; + /* * ELBC may use HW ECC, so that OOB offsets, that NAND core uses for bbt, * interfere with ECC positions, that's why we implement our own descriptors. @@ -685,6 +699,7 @@ static int fsl_elbc_chip_init_tail(struct mtd_info *mtd) chip->ecc.layout = (priv->fmr & FMR_ECCM) ? &fsl_elbc_oob_lp_eccm1 : &fsl_elbc_oob_lp_eccm0; + chip->badblock_pattern = &largepage_memorybased; } } else { dev_err(priv->dev, @@ -799,7 +814,7 @@ static int fsl_elbc_chip_remove(struct fsl_elbc_mtd *priv) static DEFINE_MUTEX(fsl_elbc_nand_mutex); -static int fsl_elbc_nand_probe(struct platform_device *pdev) +static int __devinit fsl_elbc_nand_probe(struct platform_device *pdev) { struct fsl_lbc_regs __iomem *lbc; struct fsl_elbc_mtd *priv; diff --git a/trunk/drivers/mtd/nand/fsl_ifc_nand.c b/trunk/drivers/mtd/nand/fsl_ifc_nand.c index ad6222627fed..3551a99076ba 100644 --- a/trunk/drivers/mtd/nand/fsl_ifc_nand.c +++ b/trunk/drivers/mtd/nand/fsl_ifc_nand.c @@ -389,7 +389,7 @@ static void fsl_ifc_cmdfunc(struct mtd_info *mtd, unsigned int command, timing = IFC_FIR_OP_RBCD; out_be32(&ifc->ifc_nand.nand_fir0, - (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | + (IFC_FIR_OP_CMD0 << IFC_NAND_FIR0_OP0_SHIFT) | (IFC_FIR_OP_UA << IFC_NAND_FIR0_OP1_SHIFT) | (timing << IFC_NAND_FIR0_OP2_SHIFT)); out_be32(&ifc->ifc_nand.nand_fcr0, @@ -754,7 +754,7 @@ static void fsl_ifc_sram_init(struct fsl_ifc_mtd *priv) /* READID */ out_be32(&ifc->ifc_nand.nand_fir0, - (IFC_FIR_OP_CW0 << IFC_NAND_FIR0_OP0_SHIFT) | + (IFC_FIR_OP_CMD0 << IFC_NAND_FIR0_OP0_SHIFT) | (IFC_FIR_OP_UA << IFC_NAND_FIR0_OP1_SHIFT) | (IFC_FIR_OP_RB << IFC_NAND_FIR0_OP2_SHIFT)); out_be32(&ifc->ifc_nand.nand_fcr0, @@ -922,7 +922,7 @@ static int match_bank(struct fsl_ifc_regs __iomem *ifc, int bank, static DEFINE_MUTEX(fsl_ifc_nand_mutex); -static int fsl_ifc_nand_probe(struct platform_device *dev) +static int __devinit fsl_ifc_nand_probe(struct platform_device *dev) { struct fsl_ifc_regs __iomem *ifc; struct fsl_ifc_mtd *priv; diff --git a/trunk/drivers/mtd/nand/fsl_upm.c b/trunk/drivers/mtd/nand/fsl_upm.c index 5a8f5c4ce512..45df542b9c61 100644 --- a/trunk/drivers/mtd/nand/fsl_upm.c +++ b/trunk/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) fun_wait_rnb(fun); } -static int fun_chip_init(struct fsl_upm_nand *fun, +static int __devinit fun_chip_init(struct fsl_upm_nand *fun, const struct device_node *upm_np, const struct resource *io_res) { @@ -201,7 +201,7 @@ static int fun_chip_init(struct fsl_upm_nand *fun, return ret; } -static int fun_probe(struct platform_device *ofdev) +static int __devinit fun_probe(struct platform_device *ofdev) { struct fsl_upm_nand *fun; struct resource io_res; @@ -318,7 +318,7 @@ static int fun_probe(struct platform_device *ofdev) return ret; } -static int fun_remove(struct platform_device *ofdev) +static int __devexit fun_remove(struct platform_device *ofdev) { struct fsl_upm_nand *fun = dev_get_drvdata(&ofdev->dev); int i; @@ -350,7 +350,7 @@ static struct platform_driver of_fun_driver = { .of_match_table = of_fun_match, }, .probe = fun_probe, - .remove = fun_remove, + .remove = __devexit_p(fun_remove), }; module_platform_driver(of_fun_driver); diff --git a/trunk/drivers/mtd/nand/fsmc_nand.c b/trunk/drivers/mtd/nand/fsmc_nand.c index 1d7446434b0e..38d26240d8b1 100644 --- a/trunk/drivers/mtd/nand/fsmc_nand.c +++ b/trunk/drivers/mtd/nand/fsmc_nand.c @@ -361,7 +361,7 @@ static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) struct nand_chip *this = mtd->priv; struct fsmc_nand_data *host = container_of(mtd, struct fsmc_nand_data, mtd); - void __iomem *regs = host->regs_va; + void *__iomem *regs = host->regs_va; unsigned int bank = host->bank; if (ctrl & NAND_CTRL_CHANGE) { @@ -383,13 +383,13 @@ static void fsmc_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) pc |= FSMC_ENABLE; else pc &= ~FSMC_ENABLE; - writel_relaxed(pc, FSMC_NAND_REG(regs, bank, PC)); + writel(pc, FSMC_NAND_REG(regs, bank, PC)); } mb(); if (cmd != NAND_CMD_NONE) - writeb_relaxed(cmd, this->IO_ADDR_W); + writeb(cmd, this->IO_ADDR_W); } /* @@ -426,18 +426,14 @@ static void fsmc_nand_setup(void __iomem *regs, uint32_t bank, tset = (tims->tset & FSMC_TSET_MASK) << FSMC_TSET_SHIFT; if (busw) - writel_relaxed(value | FSMC_DEVWID_16, - FSMC_NAND_REG(regs, bank, PC)); + writel(value | FSMC_DEVWID_16, FSMC_NAND_REG(regs, bank, PC)); else - writel_relaxed(value | FSMC_DEVWID_8, - FSMC_NAND_REG(regs, bank, PC)); + writel(value | FSMC_DEVWID_8, FSMC_NAND_REG(regs, bank, PC)); - writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) | tclr | tar, + writel(readl(FSMC_NAND_REG(regs, bank, PC)) | tclr | tar, FSMC_NAND_REG(regs, bank, PC)); - writel_relaxed(thiz | thold | twait | tset, - FSMC_NAND_REG(regs, bank, COMM)); - writel_relaxed(thiz | thold | twait | tset, - FSMC_NAND_REG(regs, bank, ATTRIB)); + writel(thiz | thold | twait | tset, FSMC_NAND_REG(regs, bank, COMM)); + writel(thiz | thold | twait | tset, FSMC_NAND_REG(regs, bank, ATTRIB)); } /* @@ -450,11 +446,11 @@ static void fsmc_enable_hwecc(struct mtd_info *mtd, int mode) void __iomem *regs = host->regs_va; uint32_t bank = host->bank; - writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCPLEN_256, + writel(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCPLEN_256, FSMC_NAND_REG(regs, bank, PC)); - writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCEN, + writel(readl(FSMC_NAND_REG(regs, bank, PC)) & ~FSMC_ECCEN, FSMC_NAND_REG(regs, bank, PC)); - writel_relaxed(readl(FSMC_NAND_REG(regs, bank, PC)) | FSMC_ECCEN, + writel(readl(FSMC_NAND_REG(regs, bank, PC)) | FSMC_ECCEN, FSMC_NAND_REG(regs, bank, PC)); } @@ -474,7 +470,7 @@ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data, unsigned long deadline = jiffies + FSMC_BUSY_WAIT_TIMEOUT; do { - if (readl_relaxed(FSMC_NAND_REG(regs, bank, STS)) & FSMC_CODE_RDY) + if (readl(FSMC_NAND_REG(regs, bank, STS)) & FSMC_CODE_RDY) break; else cond_resched(); @@ -485,25 +481,25 @@ static int fsmc_read_hwecc_ecc4(struct mtd_info *mtd, const uint8_t *data, return -ETIMEDOUT; } - ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1)); + ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC1)); ecc[0] = (uint8_t) (ecc_tmp >> 0); ecc[1] = (uint8_t) (ecc_tmp >> 8); ecc[2] = (uint8_t) (ecc_tmp >> 16); ecc[3] = (uint8_t) (ecc_tmp >> 24); - ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC2)); + ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC2)); ecc[4] = (uint8_t) (ecc_tmp >> 0); ecc[5] = (uint8_t) (ecc_tmp >> 8); ecc[6] = (uint8_t) (ecc_tmp >> 16); ecc[7] = (uint8_t) (ecc_tmp >> 24); - ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC3)); + ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC3)); ecc[8] = (uint8_t) (ecc_tmp >> 0); ecc[9] = (uint8_t) (ecc_tmp >> 8); ecc[10] = (uint8_t) (ecc_tmp >> 16); ecc[11] = (uint8_t) (ecc_tmp >> 24); - ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, STS)); + ecc_tmp = readl(FSMC_NAND_REG(regs, bank, STS)); ecc[12] = (uint8_t) (ecc_tmp >> 16); return 0; @@ -523,7 +519,7 @@ static int fsmc_read_hwecc_ecc1(struct mtd_info *mtd, const uint8_t *data, uint32_t bank = host->bank; uint32_t ecc_tmp; - ecc_tmp = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1)); + ecc_tmp = readl(FSMC_NAND_REG(regs, bank, ECC1)); ecc[0] = (uint8_t) (ecc_tmp >> 0); ecc[1] = (uint8_t) (ecc_tmp >> 8); ecc[2] = (uint8_t) (ecc_tmp >> 16); @@ -605,7 +601,7 @@ static int dma_xfer(struct fsmc_nand_data *host, void *buffer, int len, dma_async_issue_pending(chan); ret = - wait_for_completion_timeout(&host->dma_access_complete, + wait_for_completion_interruptible_timeout(&host->dma_access_complete, msecs_to_jiffies(3000)); if (ret <= 0) { chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); @@ -632,10 +628,10 @@ static void fsmc_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) uint32_t *p = (uint32_t *)buf; len = len >> 2; for (i = 0; i < len; i++) - writel_relaxed(p[i], chip->IO_ADDR_W); + writel(p[i], chip->IO_ADDR_W); } else { for (i = 0; i < len; i++) - writeb_relaxed(buf[i], chip->IO_ADDR_W); + writeb(buf[i], chip->IO_ADDR_W); } } @@ -655,10 +651,10 @@ static void fsmc_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) uint32_t *p = (uint32_t *)buf; len = len >> 2; for (i = 0; i < len; i++) - p[i] = readl_relaxed(chip->IO_ADDR_R); + p[i] = readl(chip->IO_ADDR_R); } else { for (i = 0; i < len; i++) - buf[i] = readb_relaxed(chip->IO_ADDR_R); + buf[i] = readb(chip->IO_ADDR_R); } } @@ -787,7 +783,7 @@ static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat, uint32_t num_err, i; uint32_t ecc1, ecc2, ecc3, ecc4; - num_err = (readl_relaxed(FSMC_NAND_REG(regs, bank, STS)) >> 10) & 0xF; + num_err = (readl(FSMC_NAND_REG(regs, bank, STS)) >> 10) & 0xF; /* no bit flipping */ if (likely(num_err == 0)) @@ -830,10 +826,10 @@ static int fsmc_bch8_correct_data(struct mtd_info *mtd, uint8_t *dat, * uint64_t array and error offset indexes are populated in err_idx * array */ - ecc1 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC1)); - ecc2 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC2)); - ecc3 = readl_relaxed(FSMC_NAND_REG(regs, bank, ECC3)); - ecc4 = readl_relaxed(FSMC_NAND_REG(regs, bank, STS)); + ecc1 = readl(FSMC_NAND_REG(regs, bank, ECC1)); + ecc2 = readl(FSMC_NAND_REG(regs, bank, ECC2)); + ecc3 = readl(FSMC_NAND_REG(regs, bank, ECC3)); + ecc4 = readl(FSMC_NAND_REG(regs, bank, STS)); err_idx[0] = (ecc1 >> 0) & 0x1FFF; err_idx[1] = (ecc1 >> 13) & 0x1FFF; @@ -864,7 +860,7 @@ static bool filter(struct dma_chan *chan, void *slave) } #ifdef CONFIG_OF -static int fsmc_nand_probe_config_dt(struct platform_device *pdev, +static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev, struct device_node *np) { struct fsmc_nand_platform_data *pdata = dev_get_platdata(&pdev->dev); @@ -880,13 +876,15 @@ static int fsmc_nand_probe_config_dt(struct platform_device *pdev, return -EINVAL; } } + of_property_read_u32(np, "st,ale-off", &pdata->ale_off); + of_property_read_u32(np, "st,cle-off", &pdata->cle_off); if (of_get_property(np, "nand-skip-bbtscan", NULL)) pdata->options = NAND_SKIP_BBTSCAN; return 0; } #else -static int fsmc_nand_probe_config_dt(struct platform_device *pdev, +static int __devinit fsmc_nand_probe_config_dt(struct platform_device *pdev, struct device_node *np) { return -ENOSYS; @@ -937,28 +935,41 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) if (!res) return -EINVAL; - host->data_va = devm_request_and_ioremap(&pdev->dev, res); + if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res), + pdev->name)) { + dev_err(&pdev->dev, "Failed to get memory data resourse\n"); + return -ENOENT; + } + + host->data_pa = (dma_addr_t)res->start; + host->data_va = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); if (!host->data_va) { dev_err(&pdev->dev, "data ioremap failed\n"); return -ENOMEM; } - host->data_pa = (dma_addr_t)res->start; - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_addr"); - if (!res) - return -EINVAL; + if (!devm_request_mem_region(&pdev->dev, res->start + pdata->ale_off, + resource_size(res), pdev->name)) { + dev_err(&pdev->dev, "Failed to get memory ale resourse\n"); + return -ENOENT; + } - host->addr_va = devm_request_and_ioremap(&pdev->dev, res); + host->addr_va = devm_ioremap(&pdev->dev, res->start + pdata->ale_off, + resource_size(res)); if (!host->addr_va) { dev_err(&pdev->dev, "ale ioremap failed\n"); return -ENOMEM; } - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_cmd"); - if (!res) - return -EINVAL; + if (!devm_request_mem_region(&pdev->dev, res->start + pdata->cle_off, + resource_size(res), pdev->name)) { + dev_err(&pdev->dev, "Failed to get memory cle resourse\n"); + return -ENOENT; + } - host->cmd_va = devm_request_and_ioremap(&pdev->dev, res); + host->cmd_va = devm_ioremap(&pdev->dev, res->start + pdata->cle_off, + resource_size(res)); if (!host->cmd_va) { dev_err(&pdev->dev, "ale ioremap failed\n"); return -ENOMEM; @@ -968,7 +979,14 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) if (!res) return -EINVAL; - host->regs_va = devm_request_and_ioremap(&pdev->dev, res); + if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res), + pdev->name)) { + dev_err(&pdev->dev, "Failed to get memory regs resourse\n"); + return -ENOENT; + } + + host->regs_va = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); if (!host->regs_va) { dev_err(&pdev->dev, "regs ioremap failed\n"); return -ENOMEM; diff --git a/trunk/drivers/mtd/nand/gpio.c b/trunk/drivers/mtd/nand/gpio.c index e789e3f51710..bc73bc5f2713 100644 --- a/trunk/drivers/mtd/nand/gpio.c +++ b/trunk/drivers/mtd/nand/gpio.c @@ -90,14 +90,14 @@ static void gpio_nand_writebuf(struct mtd_info *mtd, const u_char *buf, int len) { struct nand_chip *this = mtd->priv; - iowrite8_rep(this->IO_ADDR_W, buf, len); + writesb(this->IO_ADDR_W, buf, len); } static void gpio_nand_readbuf(struct mtd_info *mtd, u_char *buf, int len) { struct nand_chip *this = mtd->priv; - ioread8_rep(this->IO_ADDR_R, buf, len); + readsb(this->IO_ADDR_R, buf, len); } 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, struct nand_chip *this = mtd->priv; if (IS_ALIGNED((unsigned long)buf, 2)) { - iowrite16_rep(this->IO_ADDR_W, buf, len>>1); + writesw(this->IO_ADDR_W, buf, len>>1); } else { int i; unsigned short *ptr = (unsigned short *)buf; @@ -121,7 +121,7 @@ static void gpio_nand_readbuf16(struct mtd_info *mtd, u_char *buf, int len) struct nand_chip *this = mtd->priv; if (IS_ALIGNED((unsigned long)buf, 2)) { - ioread16_rep(this->IO_ADDR_R, buf, len>>1); + readsw(this->IO_ADDR_R, buf, len>>1); } else { int i; unsigned short *ptr = (unsigned short *)buf; @@ -134,11 +134,7 @@ static void gpio_nand_readbuf16(struct mtd_info *mtd, u_char *buf, int len) static int gpio_nand_devready(struct mtd_info *mtd) { struct gpiomtd *gpiomtd = gpio_nand_getpriv(mtd); - - if (gpio_is_valid(gpiomtd->plat.gpio_rdy)) - return gpio_get_value(gpiomtd->plat.gpio_rdy); - - return 1; + return gpio_get_value(gpiomtd->plat.gpio_rdy); } #ifdef CONFIG_OF @@ -231,7 +227,7 @@ gpio_nand_get_io_sync(struct platform_device *pdev) return platform_get_resource(pdev, IORESOURCE_MEM, 1); } -static int gpio_nand_remove(struct platform_device *dev) +static int __devexit gpio_nand_remove(struct platform_device *dev) { struct gpiomtd *gpiomtd = platform_get_drvdata(dev); struct resource *res; @@ -256,8 +252,7 @@ static int gpio_nand_remove(struct platform_device *dev) gpio_free(gpiomtd->plat.gpio_nce); if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) gpio_free(gpiomtd->plat.gpio_nwp); - if (gpio_is_valid(gpiomtd->plat.gpio_rdy)) - gpio_free(gpiomtd->plat.gpio_rdy); + gpio_free(gpiomtd->plat.gpio_rdy); kfree(gpiomtd); @@ -282,7 +277,7 @@ static void __iomem *request_and_remap(struct resource *res, size_t size, return ptr; } -static int gpio_nand_probe(struct platform_device *dev) +static int __devinit gpio_nand_probe(struct platform_device *dev) { struct gpiomtd *gpiomtd; struct nand_chip *this; @@ -341,12 +336,10 @@ static int gpio_nand_probe(struct platform_device *dev) if (ret) goto err_cle; gpio_direction_output(gpiomtd->plat.gpio_cle, 0); - if (gpio_is_valid(gpiomtd->plat.gpio_rdy)) { - ret = gpio_request(gpiomtd->plat.gpio_rdy, "NAND RDY"); - if (ret) - goto err_rdy; - gpio_direction_input(gpiomtd->plat.gpio_rdy); - } + ret = gpio_request(gpiomtd->plat.gpio_rdy, "NAND RDY"); + if (ret) + goto err_rdy; + gpio_direction_input(gpiomtd->plat.gpio_rdy); this->IO_ADDR_W = this->IO_ADDR_R; @@ -393,8 +386,7 @@ static int gpio_nand_probe(struct platform_device *dev) err_wp: if (gpio_is_valid(gpiomtd->plat.gpio_nwp)) gpio_set_value(gpiomtd->plat.gpio_nwp, 0); - if (gpio_is_valid(gpiomtd->plat.gpio_rdy)) - gpio_free(gpiomtd->plat.gpio_rdy); + gpio_free(gpiomtd->plat.gpio_rdy); err_rdy: gpio_free(gpiomtd->plat.gpio_cle); err_cle: diff --git a/trunk/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/trunk/drivers/mtd/nand/gpmi-nand/gpmi-lib.c index d84699c7968e..3502accd4bc3 100644 --- a/trunk/drivers/mtd/nand/gpmi-nand/gpmi-lib.c +++ b/trunk/drivers/mtd/nand/gpmi-nand/gpmi-lib.c @@ -18,6 +18,7 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include #include #include @@ -165,15 +166,6 @@ int gpmi_init(struct gpmi_nand_data *this) if (ret) goto err_out; - /* - * Reset BCH here, too. We got failures otherwise :( - * See later BCH reset for explanation of MX23 handling - */ - ret = gpmi_reset_block(r->bch_regs, GPMI_IS_MX23(this)); - if (ret) - goto err_out; - - /* Choose NAND mode. */ writel(BM_GPMI_CTRL1_GPMI_MODE, r->gpmi_regs + HW_GPMI_CTRL1_CLR); diff --git a/trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.c index 5cd141f7bfc2..d79696b2f19b 100644 --- a/trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.c +++ b/trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -32,12 +33,6 @@ #include #include "gpmi-nand.h" -/* Resource names for the GPMI NAND driver. */ -#define GPMI_NAND_GPMI_REGS_ADDR_RES_NAME "gpmi-nand" -#define GPMI_NAND_BCH_REGS_ADDR_RES_NAME "bch" -#define GPMI_NAND_BCH_INTERRUPT_RES_NAME "bch" -#define GPMI_NAND_DMA_INTERRUPT_RES_NAME "gpmi-dma" - /* add our owner bbt descriptor */ static uint8_t scan_ff_pattern[] = { 0xff }; static struct nand_bbt_descr gpmi_bbt_descr = { @@ -227,7 +222,7 @@ void prepare_data_dma(struct gpmi_nand_data *this, enum dma_data_direction dr) ret = dma_map_sg(this->dev, sgl, 1, dr); if (ret == 0) - pr_err("DMA mapping failed.\n"); + pr_err("map failed.\n"); this->direct_dma_map_ok = false; } @@ -319,7 +314,7 @@ int start_dma_with_bch_irq(struct gpmi_nand_data *this, return 0; } -static int +static int __devinit acquire_register_block(struct gpmi_nand_data *this, const char *res_name) { struct platform_device *pdev = this->pdev; @@ -360,7 +355,7 @@ static void release_register_block(struct gpmi_nand_data *this) res->bch_regs = NULL; } -static int +static int __devinit acquire_bch_irq(struct gpmi_nand_data *this, irq_handler_t irq_h) { struct platform_device *pdev = this->pdev; @@ -427,7 +422,7 @@ static void release_dma_channels(struct gpmi_nand_data *this) } } -static int acquire_dma_channels(struct gpmi_nand_data *this) +static int __devinit acquire_dma_channels(struct gpmi_nand_data *this) { struct platform_device *pdev = this->pdev; struct resource *r_dma; @@ -461,7 +456,7 @@ static int acquire_dma_channels(struct gpmi_nand_data *this) dma_chan = dma_request_channel(mask, gpmi_dma_filter, this); if (!dma_chan) { - pr_err("Failed to request DMA channel.\n"); + pr_err("dma_request_channel failed.\n"); goto acquire_err; } @@ -492,7 +487,7 @@ static char *extra_clks_for_mx6q[GPMI_CLK_MAX] = { "gpmi_apb", "gpmi_bch", "gpmi_bch_apb", "per1_bch", }; -static int gpmi_get_clks(struct gpmi_nand_data *this) +static int __devinit gpmi_get_clks(struct gpmi_nand_data *this) { struct resources *r = &this->resources; char **extra_clks = NULL; @@ -538,7 +533,7 @@ static int gpmi_get_clks(struct gpmi_nand_data *this) return -ENOMEM; } -static int acquire_resources(struct gpmi_nand_data *this) +static int __devinit acquire_resources(struct gpmi_nand_data *this) { struct pinctrl *pinctrl; int ret; @@ -588,7 +583,7 @@ static void release_resources(struct gpmi_nand_data *this) release_dma_channels(this); } -static int init_hardware(struct gpmi_nand_data *this) +static int __devinit init_hardware(struct gpmi_nand_data *this) { int ret; @@ -630,8 +625,7 @@ static int read_page_prepare(struct gpmi_nand_data *this, length, DMA_FROM_DEVICE); if (dma_mapping_error(dev, dest_phys)) { if (alt_size < length) { - pr_err("%s, Alternate buffer is too small\n", - __func__); + pr_err("Alternate buffer is too small\n"); return -ENOMEM; } goto map_failed; @@ -681,8 +675,7 @@ static int send_page_prepare(struct gpmi_nand_data *this, DMA_TO_DEVICE); if (dma_mapping_error(dev, source_phys)) { if (alt_size < length) { - pr_err("%s, Alternate buffer is too small\n", - __func__); + pr_err("Alternate buffer is too small\n"); return -ENOMEM; } goto map_failed; @@ -770,7 +763,7 @@ static int gpmi_alloc_dma_buffer(struct gpmi_nand_data *this) error_alloc: gpmi_free_dma_buffer(this); - pr_err("Error allocating DMA buffers!\n"); + pr_err("allocate DMA buffer ret!!\n"); return -ENOMEM; } @@ -1481,7 +1474,7 @@ static int gpmi_set_geometry(struct gpmi_nand_data *this) /* Set up the NFC geometry which is used by BCH. */ ret = bch_set_geometry(this); if (ret) { - pr_err("Error setting BCH geometry : %d\n", ret); + pr_err("set geometry ret : %d\n", ret); return ret; } @@ -1542,7 +1535,7 @@ static void gpmi_nfc_exit(struct gpmi_nand_data *this) gpmi_free_dma_buffer(this); } -static int gpmi_nfc_init(struct gpmi_nand_data *this) +static int __devinit gpmi_nfc_init(struct gpmi_nand_data *this) { struct mtd_info *mtd = &this->mtd; struct nand_chip *chip = &this->nand; @@ -1625,7 +1618,7 @@ static const struct of_device_id gpmi_nand_id_table[] = { }; MODULE_DEVICE_TABLE(of, gpmi_nand_id_table); -static int gpmi_nand_probe(struct platform_device *pdev) +static int __devinit gpmi_nand_probe(struct platform_device *pdev) { struct gpmi_nand_data *this; const struct of_device_id *of_id; @@ -1675,7 +1668,7 @@ static int gpmi_nand_probe(struct platform_device *pdev) return ret; } -static int gpmi_nand_remove(struct platform_device *pdev) +static int __devexit gpmi_nand_remove(struct platform_device *pdev) { struct gpmi_nand_data *this = platform_get_drvdata(pdev); @@ -1692,7 +1685,7 @@ static struct platform_driver gpmi_nand_driver = { .of_match_table = gpmi_nand_id_table, }, .probe = gpmi_nand_probe, - .remove = gpmi_nand_remove, + .remove = __devexit_p(gpmi_nand_remove), .id_table = gpmi_ids, }; module_platform_driver(gpmi_nand_driver); diff --git a/trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.h index 3d93a5e39090..7ac25c1e58f9 100644 --- a/trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.h +++ b/trunk/drivers/mtd/nand/gpmi-nand/gpmi-nand.h @@ -130,6 +130,7 @@ struct gpmi_nand_data { /* System Interface */ struct device *dev; struct platform_device *pdev; + struct gpmi_nand_platform_data *pdata; /* Resources */ struct resources resources; diff --git a/trunk/drivers/mtd/nand/jz4740_nand.c b/trunk/drivers/mtd/nand/jz4740_nand.c index 8d415f014e1d..100b6775e175 100644 --- a/trunk/drivers/mtd/nand/jz4740_nand.c +++ b/trunk/drivers/mtd/nand/jz4740_nand.c @@ -316,17 +316,13 @@ static int jz_nand_ioremap_resource(struct platform_device *pdev, return ret; } -static inline void jz_nand_iounmap_resource(struct resource *res, - void __iomem *base) +static inline void jz_nand_iounmap_resource(struct resource *res, void __iomem *base) { iounmap(base); release_mem_region(res->start, resource_size(res)); } -static int 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) { +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) { int ret; int gpio; char gpio_name[9]; @@ -404,7 +400,7 @@ static int jz_nand_detect_bank(struct platform_device *pdev, return ret; } -static int jz_nand_probe(struct platform_device *pdev) +static int __devinit jz_nand_probe(struct platform_device *pdev) { int ret; struct jz_nand *nand; @@ -545,7 +541,7 @@ static int jz_nand_probe(struct platform_device *pdev) return ret; } -static int jz_nand_remove(struct platform_device *pdev) +static int __devexit jz_nand_remove(struct platform_device *pdev) { struct jz_nand *nand = platform_get_drvdata(pdev); struct jz_nand_platform_data *pdata = pdev->dev.platform_data; @@ -577,7 +573,7 @@ static int jz_nand_remove(struct platform_device *pdev) static struct platform_driver jz_nand_driver = { .probe = jz_nand_probe, - .remove = jz_nand_remove, + .remove = __devexit_p(jz_nand_remove), .driver = { .name = "jz4740-nand", .owner = THIS_MODULE, diff --git a/trunk/drivers/mtd/nand/lpc32xx_mlc.c b/trunk/drivers/mtd/nand/lpc32xx_mlc.c index f182befa7360..c29b7ac1f6af 100644 --- a/trunk/drivers/mtd/nand/lpc32xx_mlc.c +++ b/trunk/drivers/mtd/nand/lpc32xx_mlc.c @@ -655,7 +655,7 @@ static struct lpc32xx_nand_cfg_mlc *lpc32xx_parse_dt(struct device *dev) /* * Probe for NAND controller */ -static int lpc32xx_nand_probe(struct platform_device *pdev) +static int __devinit lpc32xx_nand_probe(struct platform_device *pdev) { struct lpc32xx_nand_host *host; struct mtd_info *mtd; @@ -845,7 +845,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) /* * Remove NAND device */ -static int lpc32xx_nand_remove(struct platform_device *pdev) +static int __devexit lpc32xx_nand_remove(struct platform_device *pdev) { struct lpc32xx_nand_host *host = platform_get_drvdata(pdev); struct mtd_info *mtd = &host->mtd; @@ -907,7 +907,7 @@ MODULE_DEVICE_TABLE(of, lpc32xx_nand_match); static struct platform_driver lpc32xx_nand_driver = { .probe = lpc32xx_nand_probe, - .remove = lpc32xx_nand_remove, + .remove = __devexit_p(lpc32xx_nand_remove), .resume = lpc32xx_nand_resume, .suspend = lpc32xx_nand_suspend, .driver = { diff --git a/trunk/drivers/mtd/nand/lpc32xx_slc.c b/trunk/drivers/mtd/nand/lpc32xx_slc.c index 030b78c62895..32409c45d479 100644 --- a/trunk/drivers/mtd/nand/lpc32xx_slc.c +++ b/trunk/drivers/mtd/nand/lpc32xx_slc.c @@ -755,7 +755,7 @@ static struct lpc32xx_nand_cfg_slc *lpc32xx_parse_dt(struct device *dev) /* * Probe for NAND controller */ -static int lpc32xx_nand_probe(struct platform_device *pdev) +static int __devinit lpc32xx_nand_probe(struct platform_device *pdev) { struct lpc32xx_nand_host *host; struct mtd_info *mtd; @@ -949,7 +949,7 @@ static int lpc32xx_nand_probe(struct platform_device *pdev) /* * Remove NAND device. */ -static int lpc32xx_nand_remove(struct platform_device *pdev) +static int __devexit lpc32xx_nand_remove(struct platform_device *pdev) { uint32_t tmp; struct lpc32xx_nand_host *host = platform_get_drvdata(pdev); @@ -1021,7 +1021,7 @@ MODULE_DEVICE_TABLE(of, lpc32xx_nand_match); static struct platform_driver lpc32xx_nand_driver = { .probe = lpc32xx_nand_probe, - .remove = lpc32xx_nand_remove, + .remove = __devexit_p(lpc32xx_nand_remove), .resume = lpc32xx_nand_resume, .suspend = lpc32xx_nand_suspend, .driver = { diff --git a/trunk/drivers/mtd/nand/mpc5121_nfc.c b/trunk/drivers/mtd/nand/mpc5121_nfc.c index 3c9cdcbc4cba..f776c8577b8c 100644 --- a/trunk/drivers/mtd/nand/mpc5121_nfc.c +++ b/trunk/drivers/mtd/nand/mpc5121_nfc.c @@ -626,7 +626,7 @@ static void mpc5121_nfc_free(struct device *dev, struct mtd_info *mtd) iounmap(prv->csreg); } -static int mpc5121_nfc_probe(struct platform_device *op) +static int __devinit mpc5121_nfc_probe(struct platform_device *op) { struct device_node *rootnode, *dn = op->dev.of_node; struct device *dev = &op->dev; @@ -827,7 +827,7 @@ static int mpc5121_nfc_probe(struct platform_device *op) return retval; } -static int mpc5121_nfc_remove(struct platform_device *op) +static int __devexit mpc5121_nfc_remove(struct platform_device *op) { struct device *dev = &op->dev; struct mtd_info *mtd = dev_get_drvdata(dev); @@ -841,14 +841,14 @@ static int mpc5121_nfc_remove(struct platform_device *op) return 0; } -static struct of_device_id mpc5121_nfc_match[] = { +static struct of_device_id mpc5121_nfc_match[] __devinitdata = { { .compatible = "fsl,mpc5121-nfc", }, {}, }; static struct platform_driver mpc5121_nfc_driver = { .probe = mpc5121_nfc_probe, - .remove = mpc5121_nfc_remove, + .remove = __devexit_p(mpc5121_nfc_remove), .driver = { .name = DRV_NAME, .owner = THIS_MODULE, diff --git a/trunk/drivers/mtd/nand/mxc_nand.c b/trunk/drivers/mtd/nand/mxc_nand.c index 45204e41a028..022dcdc256fb 100644 --- a/trunk/drivers/mtd/nand/mxc_nand.c +++ b/trunk/drivers/mtd/nand/mxc_nand.c @@ -266,8 +266,7 @@ static struct nand_ecclayout nandv2_hw_eccoob_4k = { } }; -static const char const *part_probes[] = { - "cmdlinepart", "RedBoot", "ofpart", NULL }; +static const char *part_probes[] = { "RedBoot", "cmdlinepart", "ofpart", NULL }; static void memcpy32_fromio(void *trg, const void __iomem *src, size_t size) { @@ -1379,7 +1378,7 @@ static int __init mxcnd_probe_dt(struct mxc_nand_host *host) } #endif -static int mxcnd_probe(struct platform_device *pdev) +static int __devinit mxcnd_probe(struct platform_device *pdev) { struct nand_chip *this; struct mtd_info *mtd; @@ -1557,13 +1556,12 @@ static int mxcnd_probe(struct platform_device *pdev) return 0; escan: - if (host->clk_act) - clk_disable_unprepare(host->clk); + clk_disable_unprepare(host->clk); return err; } -static int mxcnd_remove(struct platform_device *pdev) +static int __devexit mxcnd_remove(struct platform_device *pdev) { struct mxc_nand_host *host = platform_get_drvdata(pdev); @@ -1582,7 +1580,7 @@ static struct platform_driver mxcnd_driver = { }, .id_table = mxcnd_devtype, .probe = mxcnd_probe, - .remove = mxcnd_remove, + .remove = __devexit_p(mxcnd_remove), }; module_platform_driver(mxcnd_driver); diff --git a/trunk/drivers/mtd/nand/nand_base.c b/trunk/drivers/mtd/nand/nand_base.c index 8323ac991ad1..1a03b7f673ce 100644 --- a/trunk/drivers/mtd/nand/nand_base.c +++ b/trunk/drivers/mtd/nand/nand_base.c @@ -93,7 +93,8 @@ static struct nand_ecclayout nand_oob_128 = { .length = 78} } }; -static int nand_get_device(struct mtd_info *mtd, int new_state); +static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, + int new_state); static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops); @@ -129,12 +130,15 @@ static int check_offs_len(struct mtd_info *mtd, * nand_release_device - [GENERIC] release chip * @mtd: MTD device structure * - * Release chip lock and wake up anyone waiting on the device. + * Deselect, release chip lock and wake up anyone waiting on the device. */ static void nand_release_device(struct mtd_info *mtd) { struct nand_chip *chip = mtd->priv; + /* De-select the NAND device */ + chip->select_chip(mtd, -1); + /* Release the controller and the chip */ spin_lock(&chip->controller->lock); chip->controller->active = NULL; @@ -156,7 +160,7 @@ static uint8_t nand_read_byte(struct mtd_info *mtd) } /** - * nand_read_byte16 - [DEFAULT] read one byte endianness aware from the chip + * nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip * nand_read_byte16 - [DEFAULT] read one byte endianness aware from the chip * @mtd: MTD device structure * @@ -299,7 +303,7 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) if (getchip) { chipnr = (int)(ofs >> chip->chip_shift); - nand_get_device(mtd, FL_READING); + nand_get_device(chip, mtd, FL_READING); /* Select the NAND device */ chip->select_chip(mtd, chipnr); @@ -329,10 +333,8 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip) i++; } while (!res && i < 2 && (chip->bbt_options & NAND_BBT_SCAN2NDPAGE)); - if (getchip) { - chip->select_chip(mtd, -1); + if (getchip) nand_release_device(mtd); - } return res; } @@ -381,7 +383,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs) struct mtd_oob_ops ops; loff_t wr_ofs = ofs; - nand_get_device(mtd, FL_WRITING); + nand_get_device(chip, mtd, FL_WRITING); ops.datbuf = NULL; ops.oobbuf = buf; @@ -490,7 +492,7 @@ static void panic_nand_wait_ready(struct mtd_info *mtd, unsigned long timeo) void nand_wait_ready(struct mtd_info *mtd) { struct nand_chip *chip = mtd->priv; - unsigned long timeo = jiffies + msecs_to_jiffies(20); + unsigned long timeo = jiffies + 2; /* 400ms timeout */ if (in_interrupt() || oops_in_progress) @@ -748,15 +750,15 @@ static void panic_nand_get_device(struct nand_chip *chip, /** * nand_get_device - [GENERIC] Get chip for selected access + * @chip: the nand chip descriptor * @mtd: MTD device structure * @new_state: the state which is requested * * Get the device and lock it for exclusive access */ static int -nand_get_device(struct mtd_info *mtd, int new_state) +nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, int new_state) { - struct nand_chip *chip = mtd->priv; spinlock_t *lock = &chip->controller->lock; wait_queue_head_t *wq = &chip->controller->wq; DECLARE_WAITQUEUE(wait, current); @@ -863,8 +865,6 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip) led_trigger_event(nand_led_trigger, LED_OFF); status = (int)chip->read_byte(mtd); - /* This can happen if in case of timeout or buggy dev_ready */ - WARN_ON(!(status & NAND_STATUS_READY)); return status; } @@ -899,7 +899,7 @@ static int __nand_unlock(struct mtd_info *mtd, loff_t ofs, /* Call wait ready function */ status = chip->waitfunc(mtd, chip); /* See if device thinks it succeeded */ - if (status & NAND_STATUS_FAIL) { + if (status & 0x01) { pr_debug("%s: error status = 0x%08x\n", __func__, status); ret = -EIO; @@ -932,7 +932,7 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) if (ofs + len == mtd->size) len -= mtd->erasesize; - nand_get_device(mtd, FL_UNLOCKING); + nand_get_device(chip, mtd, FL_UNLOCKING); /* Shift to get chip number */ chipnr = ofs >> chip->chip_shift; @@ -950,7 +950,6 @@ int nand_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) ret = __nand_unlock(mtd, ofs, len, 0); out: - chip->select_chip(mtd, -1); nand_release_device(mtd); return ret; @@ -982,7 +981,7 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) if (check_offs_len(mtd, ofs, len)) ret = -EINVAL; - nand_get_device(mtd, FL_LOCKING); + nand_get_device(chip, mtd, FL_LOCKING); /* Shift to get chip number */ chipnr = ofs >> chip->chip_shift; @@ -1005,7 +1004,7 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) /* Call wait ready function */ status = chip->waitfunc(mtd, chip); /* See if device thinks it succeeded */ - if (status & NAND_STATUS_FAIL) { + if (status & 0x01) { pr_debug("%s: error status = 0x%08x\n", __func__, status); ret = -EIO; @@ -1015,7 +1014,6 @@ int nand_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) ret = __nand_unlock(mtd, ofs, len, 0x1); out: - chip->select_chip(mtd, -1); nand_release_device(mtd); return ret; @@ -1552,7 +1550,6 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, chip->select_chip(mtd, chipnr); } } - chip->select_chip(mtd, -1); ops->retlen = ops->len - (size_t) readlen; if (oob) @@ -1580,10 +1577,11 @@ static int nand_do_read_ops(struct mtd_info *mtd, loff_t from, static int nand_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, uint8_t *buf) { + struct nand_chip *chip = mtd->priv; struct mtd_oob_ops ops; int ret; - nand_get_device(mtd, FL_READING); + nand_get_device(chip, mtd, FL_READING); ops.len = len; ops.datbuf = buf; ops.oobbuf = NULL; @@ -1806,7 +1804,6 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, chip->select_chip(mtd, chipnr); } } - chip->select_chip(mtd, -1); ops->oobretlen = ops->ooblen - readlen; @@ -1830,6 +1827,7 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, static int nand_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) { + struct nand_chip *chip = mtd->priv; int ret = -ENOTSUPP; ops->retlen = 0; @@ -1841,7 +1839,7 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from, return -EINVAL; } - nand_get_device(mtd, FL_READING); + nand_get_device(chip, mtd, FL_READING); switch (ops->mode) { case MTD_OPS_PLACE_OOB: @@ -2188,10 +2186,8 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, chip->select_chip(mtd, chipnr); /* Check, if it is write protected */ - if (nand_check_wp(mtd)) { - ret = -EIO; - goto err_out; - } + if (nand_check_wp(mtd)) + return -EIO; realpage = (int)(to >> chip->page_shift); page = realpage & chip->pagemask; @@ -2203,10 +2199,8 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, chip->pagebuf = -1; /* Don't allow multipage oob writes with offset */ - if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen)) { - ret = -EINVAL; - goto err_out; - } + if (oob && ops->ooboffs && (ops->ooboffs + ops->ooblen > oobmaxlen)) + return -EINVAL; while (1) { int bytes = mtd->writesize; @@ -2257,9 +2251,6 @@ static int nand_do_write_ops(struct mtd_info *mtd, loff_t to, ops->retlen = ops->len - writelen; if (unlikely(oob)) ops->oobretlen = ops->ooblen; - -err_out: - chip->select_chip(mtd, -1); return ret; } @@ -2311,10 +2302,11 @@ static int panic_nand_write(struct mtd_info *mtd, loff_t to, size_t len, static int nand_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const uint8_t *buf) { + struct nand_chip *chip = mtd->priv; struct mtd_oob_ops ops; int ret; - nand_get_device(mtd, FL_WRITING); + nand_get_device(chip, mtd, FL_WRITING); ops.len = len; ops.datbuf = (uint8_t *)buf; ops.oobbuf = NULL; @@ -2385,10 +2377,8 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1); /* Check, if it is write protected */ - if (nand_check_wp(mtd)) { - chip->select_chip(mtd, -1); + if (nand_check_wp(mtd)) return -EROFS; - } /* Invalidate the page cache, if we write to the cached page */ if (page == chip->pagebuf) @@ -2401,8 +2391,6 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, else status = chip->ecc.write_oob(mtd, chip, page & chip->pagemask); - chip->select_chip(mtd, -1); - if (status) return status; @@ -2420,6 +2408,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, static int nand_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops) { + struct nand_chip *chip = mtd->priv; int ret = -ENOTSUPP; ops->retlen = 0; @@ -2431,7 +2420,7 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to, return -EINVAL; } - nand_get_device(mtd, FL_WRITING); + nand_get_device(chip, mtd, FL_WRITING); switch (ops->mode) { case MTD_OPS_PLACE_OOB: @@ -2524,7 +2513,7 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, return -EINVAL; /* Grab the lock and see if the device is available */ - nand_get_device(mtd, FL_ERASING); + nand_get_device(chip, mtd, FL_ERASING); /* Shift to get first page */ page = (int)(instr->addr >> chip->page_shift); @@ -2634,7 +2623,6 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, ret = instr->state == MTD_ERASE_DONE ? 0 : -EIO; /* Deselect and wake up anyone waiting on the device */ - chip->select_chip(mtd, -1); nand_release_device(mtd); /* Do call back function */ @@ -2670,10 +2658,12 @@ int nand_erase_nand(struct mtd_info *mtd, struct erase_info *instr, */ static void nand_sync(struct mtd_info *mtd) { + struct nand_chip *chip = mtd->priv; + pr_debug("%s: called\n", __func__); /* Grab the lock and see if the device is available */ - nand_get_device(mtd, FL_SYNCING); + nand_get_device(chip, mtd, FL_SYNCING); /* Release it and go back */ nand_release_device(mtd); } @@ -2759,7 +2749,9 @@ static int nand_onfi_get_features(struct mtd_info *mtd, struct nand_chip *chip, */ static int nand_suspend(struct mtd_info *mtd) { - return nand_get_device(mtd, FL_PM_SUSPENDED); + struct nand_chip *chip = mtd->priv; + + return nand_get_device(chip, mtd, FL_PM_SUSPENDED); } /** @@ -2857,8 +2849,6 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, int i; int val; - /* ONFI need to be probed in 8 bits mode */ - WARN_ON(chip->options & NAND_BUSWIDTH_16); /* Try ONFI for unknown chip or LP */ chip->cmdfunc(mtd, NAND_CMD_READID, 0x20, -1); if (chip->read_byte(mtd) != 'O' || chip->read_byte(mtd) != 'N' || @@ -2923,7 +2913,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, * * Check if an ID string is repeated within a given sequence of bytes at * specific repetition interval period (e.g., {0x20,0x01,0x7F,0x20} has a - * period of 3). This is a helper function for nand_id_len(). Returns non-zero + * period of 2). This is a helper function for nand_id_len(). Returns non-zero * if the repetition has a period of @period; otherwise, returns zero. */ static int nand_id_has_period(u8 *id_data, int arrlen, int period) @@ -3252,15 +3242,11 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, break; } - if (chip->options & NAND_BUSWIDTH_AUTO) { - WARN_ON(chip->options & NAND_BUSWIDTH_16); - chip->options |= busw; - nand_set_defaults(chip, busw); - } else if (busw != (chip->options & NAND_BUSWIDTH_16)) { - /* - * Check, if buswidth is correct. Hardware drivers should set - * chip correct! - */ + /* + * Check, if buswidth is correct. Hardware drivers should set + * chip correct! + */ + if (busw != (chip->options & NAND_BUSWIDTH_16)) { pr_info("NAND device: Manufacturer ID:" " 0x%02x, Chip ID: 0x%02x (%s %s)\n", *maf_id, *dev_id, nand_manuf_ids[maf_idx].name, mtd->name); @@ -3299,10 +3285,10 @@ static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd, chip->cmdfunc = nand_command_lp; pr_info("NAND device: Manufacturer ID: 0x%02x, Chip ID: 0x%02x (%s %s)," - " %dMiB, page size: %d, OOB size: %d\n", + " page size: %d, OOB size: %d\n", *maf_id, *dev_id, nand_manuf_ids[maf_idx].name, chip->onfi_version ? chip->onfi_params.model : type->name, - (int)(chip->chipsize >> 20), mtd->writesize, mtd->oobsize); + mtd->writesize, mtd->oobsize); return type; } @@ -3341,8 +3327,6 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, return PTR_ERR(type); } - chip->select_chip(mtd, -1); - /* Check for a chip array */ for (i = 1; i < maxchips; i++) { chip->select_chip(mtd, i); @@ -3352,11 +3336,8 @@ int nand_scan_ident(struct mtd_info *mtd, int maxchips, chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1); /* Read manufacturer and device IDs */ if (nand_maf_id != chip->read_byte(mtd) || - nand_dev_id != chip->read_byte(mtd)) { - chip->select_chip(mtd, -1); + nand_dev_id != chip->read_byte(mtd)) break; - } - chip->select_chip(mtd, -1); } if (i > 1) pr_info("%d NAND chips detected\n", i); @@ -3615,6 +3596,9 @@ int nand_scan_tail(struct mtd_info *mtd) /* Initialize state */ chip->state = FL_READY; + /* De-select the device */ + chip->select_chip(mtd, -1); + /* Invalidate the pagebuffer reference */ chip->pagebuf = -1; diff --git a/trunk/drivers/mtd/nand/nandsim.c b/trunk/drivers/mtd/nand/nandsim.c index 818b65c85d12..c3c13e64a2f0 100644 --- a/trunk/drivers/mtd/nand/nandsim.c +++ b/trunk/drivers/mtd/nand/nandsim.c @@ -42,8 +42,6 @@ #include #include #include -#include -#include /* Default simulator parameters values */ #if !defined(CONFIG_NANDSIM_FIRST_ID_BYTE) || \ @@ -107,6 +105,7 @@ static char *weakblocks = NULL; static char *weakpages = NULL; static unsigned int bitflips = 0; static char *gravepages = NULL; +static unsigned int rptwear = 0; static unsigned int overridesize = 0; static char *cache_file = NULL; static unsigned int bbt; @@ -131,6 +130,7 @@ module_param(weakblocks, charp, 0400); module_param(weakpages, charp, 0400); module_param(bitflips, uint, 0400); module_param(gravepages, charp, 0400); +module_param(rptwear, uint, 0400); module_param(overridesize, uint, 0400); module_param(cache_file, charp, 0400); module_param(bbt, uint, 0400); @@ -162,6 +162,7 @@ MODULE_PARM_DESC(bitflips, "Maximum number of random bit flips per page (z MODULE_PARM_DESC(gravepages, "Pages that lose data [: maximum reads (defaults to 3)]" " separated by commas e.g. 1401:2 means page 1401" " can be read only twice before failing"); +MODULE_PARM_DESC(rptwear, "Number of erases between reporting wear, if not zero"); MODULE_PARM_DESC(overridesize, "Specifies the NAND Flash size overriding the ID bytes. " "The size is specified in erase blocks and as the exponent of a power of two" " e.g. 5 means a size of 32 erase blocks"); @@ -285,11 +286,6 @@ MODULE_PARM_DESC(bch, "Enable BCH ecc and set how many bits should " /* Maximum page cache pages needed to read or write a NAND page to the cache_file */ #define NS_MAX_HELD_PAGES 16 -struct nandsim_debug_info { - struct dentry *dfs_root; - struct dentry *dfs_wear_report; -}; - /* * A union to represent flash memory contents and flash buffer. */ @@ -369,8 +365,6 @@ struct nandsim { void *file_buf; struct page *held_pages[NS_MAX_HELD_PAGES]; int held_cnt; - - struct nandsim_debug_info dbg; }; /* @@ -448,123 +442,11 @@ static LIST_HEAD(grave_pages); static unsigned long *erase_block_wear = NULL; static unsigned int wear_eb_count = 0; static unsigned long total_wear = 0; +static unsigned int rptwear_cnt = 0; /* MTD structure for NAND controller */ static struct mtd_info *nsmtd; -static int nandsim_debugfs_show(struct seq_file *m, void *private) -{ - unsigned long wmin = -1, wmax = 0, avg; - unsigned long deciles[10], decile_max[10], tot = 0; - unsigned int i; - - /* Calc wear stats */ - for (i = 0; i < wear_eb_count; ++i) { - unsigned long wear = erase_block_wear[i]; - if (wear < wmin) - wmin = wear; - if (wear > wmax) - wmax = wear; - tot += wear; - } - - for (i = 0; i < 9; ++i) { - deciles[i] = 0; - decile_max[i] = (wmax * (i + 1) + 5) / 10; - } - deciles[9] = 0; - decile_max[9] = wmax; - for (i = 0; i < wear_eb_count; ++i) { - int d; - unsigned long wear = erase_block_wear[i]; - for (d = 0; d < 10; ++d) - if (wear <= decile_max[d]) { - deciles[d] += 1; - break; - } - } - avg = tot / wear_eb_count; - - /* Output wear report */ - seq_printf(m, "Total numbers of erases: %lu\n", tot); - seq_printf(m, "Number of erase blocks: %u\n", wear_eb_count); - seq_printf(m, "Average number of erases: %lu\n", avg); - seq_printf(m, "Maximum number of erases: %lu\n", wmax); - seq_printf(m, "Minimum number of erases: %lu\n", wmin); - for (i = 0; i < 10; ++i) { - unsigned long from = (i ? decile_max[i - 1] + 1 : 0); - if (from > decile_max[i]) - continue; - seq_printf(m, "Number of ebs with erase counts from %lu to %lu : %lu\n", - from, - decile_max[i], - deciles[i]); - } - - return 0; -} - -static int nandsim_debugfs_open(struct inode *inode, struct file *file) -{ - return single_open(file, nandsim_debugfs_show, inode->i_private); -} - -static const struct file_operations dfs_fops = { - .open = nandsim_debugfs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -/** - * nandsim_debugfs_create - initialize debugfs - * @dev: nandsim device description object - * - * This function creates all debugfs files for UBI device @ubi. Returns zero in - * case of success and a negative error code in case of failure. - */ -static int nandsim_debugfs_create(struct nandsim *dev) -{ - struct nandsim_debug_info *dbg = &dev->dbg; - struct dentry *dent; - int err; - - if (!IS_ENABLED(CONFIG_DEBUG_FS)) - return 0; - - dent = debugfs_create_dir("nandsim", NULL); - if (IS_ERR_OR_NULL(dent)) { - int err = dent ? -ENODEV : PTR_ERR(dent); - - NS_ERR("cannot create \"nandsim\" debugfs directory, err %d\n", - err); - return err; - } - dbg->dfs_root = dent; - - dent = debugfs_create_file("wear_report", S_IRUSR, - dbg->dfs_root, dev, &dfs_fops); - if (IS_ERR_OR_NULL(dent)) - goto out_remove; - dbg->dfs_wear_report = dent; - - return 0; - -out_remove: - debugfs_remove_recursive(dbg->dfs_root); - err = dent ? PTR_ERR(dent) : -ENODEV; - return err; -} - -/** - * nandsim_debugfs_remove - destroy all debugfs files - */ -static void nandsim_debugfs_remove(struct nandsim *ns) -{ - if (IS_ENABLED(CONFIG_DEBUG_FS)) - debugfs_remove_recursive(ns->dbg.dfs_root); -} - /* * Allocate array of page pointers, create slab allocation for an array * and initialize the array by NULL pointers. @@ -1029,6 +911,8 @@ static int setup_wear_reporting(struct mtd_info *mtd) { size_t mem; + if (!rptwear) + return 0; wear_eb_count = div_u64(mtd->size, mtd->erasesize); mem = wear_eb_count * sizeof(unsigned long); if (mem / sizeof(unsigned long) != wear_eb_count) { @@ -1045,18 +929,64 @@ static int setup_wear_reporting(struct mtd_info *mtd) static void update_wear(unsigned int erase_block_no) { + unsigned long wmin = -1, wmax = 0, avg; + unsigned long deciles[10], decile_max[10], tot = 0; + unsigned int i; + if (!erase_block_wear) return; total_wear += 1; - /* - * TODO: Notify this through a debugfs entry, - * instead of showing an error message. - */ if (total_wear == 0) NS_ERR("Erase counter total overflow\n"); erase_block_wear[erase_block_no] += 1; if (erase_block_wear[erase_block_no] == 0) NS_ERR("Erase counter overflow for erase block %u\n", erase_block_no); + rptwear_cnt += 1; + if (rptwear_cnt < rptwear) + return; + rptwear_cnt = 0; + /* Calc wear stats */ + for (i = 0; i < wear_eb_count; ++i) { + unsigned long wear = erase_block_wear[i]; + if (wear < wmin) + wmin = wear; + if (wear > wmax) + wmax = wear; + tot += wear; + } + for (i = 0; i < 9; ++i) { + deciles[i] = 0; + decile_max[i] = (wmax * (i + 1) + 5) / 10; + } + deciles[9] = 0; + decile_max[9] = wmax; + for (i = 0; i < wear_eb_count; ++i) { + int d; + unsigned long wear = erase_block_wear[i]; + for (d = 0; d < 10; ++d) + if (wear <= decile_max[d]) { + deciles[d] += 1; + break; + } + } + avg = tot / wear_eb_count; + /* Output wear report */ + NS_INFO("*** Wear Report ***\n"); + NS_INFO("Total numbers of erases: %lu\n", tot); + NS_INFO("Number of erase blocks: %u\n", wear_eb_count); + NS_INFO("Average number of erases: %lu\n", avg); + NS_INFO("Maximum number of erases: %lu\n", wmax); + NS_INFO("Minimum number of erases: %lu\n", wmin); + for (i = 0; i < 10; ++i) { + unsigned long from = (i ? decile_max[i - 1] + 1 : 0); + if (from > decile_max[i]) + continue; + NS_INFO("Number of ebs with erase counts from %lu to %lu : %lu\n", + from, + decile_max[i], + deciles[i]); + } + NS_INFO("*** End of Wear Report ***\n"); } /* @@ -2397,9 +2327,6 @@ static int __init ns_init_module(void) if ((retval = setup_wear_reporting(nsmtd)) != 0) goto err_exit; - if ((retval = nandsim_debugfs_create(nand)) != 0) - goto err_exit; - if ((retval = init_nandsim(nsmtd)) != 0) goto err_exit; @@ -2439,7 +2366,6 @@ static void __exit ns_cleanup_module(void) struct nandsim *ns = ((struct nand_chip *)nsmtd->priv)->priv; int i; - nandsim_debugfs_remove(ns); free_nandsim(ns); /* Free nandsim private resources */ nand_release(nsmtd); /* Unregister driver */ for (i = 0;i < ARRAY_SIZE(ns->partitions); ++i) diff --git a/trunk/drivers/mtd/nand/ndfc.c b/trunk/drivers/mtd/nand/ndfc.c index 8e148f1478fd..5fd3f010e3ae 100644 --- a/trunk/drivers/mtd/nand/ndfc.c +++ b/trunk/drivers/mtd/nand/ndfc.c @@ -197,7 +197,7 @@ static int ndfc_chip_init(struct ndfc_controller *ndfc, return ret; } -static int ndfc_probe(struct platform_device *ofdev) +static int __devinit ndfc_probe(struct platform_device *ofdev) { struct ndfc_controller *ndfc; const __be32 *reg; @@ -256,7 +256,7 @@ static int ndfc_probe(struct platform_device *ofdev) return 0; } -static int ndfc_remove(struct platform_device *ofdev) +static int __devexit ndfc_remove(struct platform_device *ofdev) { struct ndfc_controller *ndfc = dev_get_drvdata(&ofdev->dev); @@ -279,7 +279,7 @@ static struct platform_driver ndfc_driver = { .of_match_table = ndfc_match, }, .probe = ndfc_probe, - .remove = ndfc_remove, + .remove = __devexit_p(ndfc_remove), }; module_platform_driver(ndfc_driver); diff --git a/trunk/drivers/mtd/nand/nomadik_nand.c b/trunk/drivers/mtd/nand/nomadik_nand.c new file mode 100644 index 000000000000..9ee0c4edfacf --- /dev/null +++ b/trunk/drivers/mtd/nand/nomadik_nand.c @@ -0,0 +1,235 @@ +/* + * drivers/mtd/nand/nomadik_nand.c + * + * Overview: + * Driver for on-board NAND flash on Nomadik Platforms + * + * Copyright © 2007 STMicroelectronics Pvt. Ltd. + * Author: Sachin Verma + * + * Copyright © 2009 Alessandro Rubini + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +struct nomadik_nand_host { + struct mtd_info mtd; + struct nand_chip nand; + void __iomem *data_va; + void __iomem *cmd_va; + void __iomem *addr_va; + struct nand_bbt_descr *bbt_desc; +}; + +static struct nand_ecclayout nomadik_ecc_layout = { + .eccbytes = 3 * 4, + .eccpos = { /* each subpage has 16 bytes: pos 2,3,4 hosts ECC */ + 0x02, 0x03, 0x04, + 0x12, 0x13, 0x14, + 0x22, 0x23, 0x24, + 0x32, 0x33, 0x34}, + /* let's keep bytes 5,6,7 for us, just in case we change ECC algo */ + .oobfree = { {0x08, 0x08}, {0x18, 0x08}, {0x28, 0x08}, {0x38, 0x08} }, +}; + +static void nomadik_ecc_control(struct mtd_info *mtd, int mode) +{ + /* No need to enable hw ecc, it's on by default */ +} + +static void nomadik_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) +{ + struct nand_chip *nand = mtd->priv; + struct nomadik_nand_host *host = nand->priv; + + if (cmd == NAND_CMD_NONE) + return; + + if (ctrl & NAND_CLE) + writeb(cmd, host->cmd_va); + else + writeb(cmd, host->addr_va); +} + +static int nomadik_nand_probe(struct platform_device *pdev) +{ + struct nomadik_nand_platform_data *pdata = pdev->dev.platform_data; + struct nomadik_nand_host *host; + struct mtd_info *mtd; + struct nand_chip *nand; + struct resource *res; + int ret = 0; + + /* Allocate memory for the device structure (and zero it) */ + host = kzalloc(sizeof(struct nomadik_nand_host), GFP_KERNEL); + if (!host) { + dev_err(&pdev->dev, "Failed to allocate device structure.\n"); + return -ENOMEM; + } + + /* Call the client's init function, if any */ + if (pdata->init) + ret = pdata->init(); + if (ret < 0) { + dev_err(&pdev->dev, "Init function failed\n"); + goto err; + } + + /* ioremap three regions */ + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_addr"); + if (!res) { + ret = -EIO; + goto err_unmap; + } + host->addr_va = ioremap(res->start, resource_size(res)); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_data"); + if (!res) { + ret = -EIO; + goto err_unmap; + } + host->data_va = ioremap(res->start, resource_size(res)); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_cmd"); + if (!res) { + ret = -EIO; + goto err_unmap; + } + host->cmd_va = ioremap(res->start, resource_size(res)); + + if (!host->addr_va || !host->data_va || !host->cmd_va) { + ret = -ENOMEM; + goto err_unmap; + } + + /* Link all private pointers */ + mtd = &host->mtd; + nand = &host->nand; + mtd->priv = nand; + nand->priv = host; + + host->mtd.owner = THIS_MODULE; + nand->IO_ADDR_R = host->data_va; + nand->IO_ADDR_W = host->data_va; + nand->cmd_ctrl = nomadik_cmd_ctrl; + + /* + * This stanza declares ECC_HW but uses soft routines. It's because + * HW claims to make the calculation but not the correction. However, + * I haven't managed to get the desired data out of it until now. + */ + nand->ecc.mode = NAND_ECC_SOFT; + nand->ecc.layout = &nomadik_ecc_layout; + nand->ecc.hwctl = nomadik_ecc_control; + nand->ecc.size = 512; + nand->ecc.bytes = 3; + + nand->options = pdata->options; + + /* + * Scan to find existence of the device + */ + if (nand_scan(&host->mtd, 1)) { + ret = -ENXIO; + goto err_unmap; + } + + mtd_device_register(&host->mtd, pdata->parts, pdata->nparts); + + platform_set_drvdata(pdev, host); + return 0; + + err_unmap: + if (host->cmd_va) + iounmap(host->cmd_va); + if (host->data_va) + iounmap(host->data_va); + if (host->addr_va) + iounmap(host->addr_va); + err: + kfree(host); + return ret; +} + +/* + * Clean up routine + */ +static int nomadik_nand_remove(struct platform_device *pdev) +{ + struct nomadik_nand_host *host = platform_get_drvdata(pdev); + struct nomadik_nand_platform_data *pdata = pdev->dev.platform_data; + + if (pdata->exit) + pdata->exit(); + + if (host) { + nand_release(&host->mtd); + iounmap(host->cmd_va); + iounmap(host->data_va); + iounmap(host->addr_va); + kfree(host); + } + return 0; +} + +static int nomadik_nand_suspend(struct device *dev) +{ + struct nomadik_nand_host *host = dev_get_drvdata(dev); + int ret = 0; + if (host) + ret = mtd_suspend(&host->mtd); + return ret; +} + +static int nomadik_nand_resume(struct device *dev) +{ + struct nomadik_nand_host *host = dev_get_drvdata(dev); + if (host) + mtd_resume(&host->mtd); + return 0; +} + +static const struct dev_pm_ops nomadik_nand_pm_ops = { + .suspend = nomadik_nand_suspend, + .resume = nomadik_nand_resume, +}; + +static struct platform_driver nomadik_nand_driver = { + .probe = nomadik_nand_probe, + .remove = nomadik_nand_remove, + .driver = { + .owner = THIS_MODULE, + .name = "nomadik_nand", + .pm = &nomadik_nand_pm_ops, + }, +}; + +module_platform_driver(nomadik_nand_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("ST Microelectronics (sachin.verma@st.com)"); +MODULE_DESCRIPTION("NAND driver for Nomadik Platform"); diff --git a/trunk/drivers/mtd/nand/nuc900_nand.c b/trunk/drivers/mtd/nand/nuc900_nand.c index a6191198d259..94dc46bc118c 100644 --- a/trunk/drivers/mtd/nand/nuc900_nand.c +++ b/trunk/drivers/mtd/nand/nuc900_nand.c @@ -246,7 +246,7 @@ static void nuc900_nand_enable(struct nuc900_nand *nand) spin_unlock(&nand->lock); } -static int nuc900_nand_probe(struct platform_device *pdev) +static int __devinit nuc900_nand_probe(struct platform_device *pdev) { struct nuc900_nand *nuc900_nand; struct nand_chip *chip; @@ -317,7 +317,7 @@ fail1: kfree(nuc900_nand); return retval; } -static int nuc900_nand_remove(struct platform_device *pdev) +static int __devexit nuc900_nand_remove(struct platform_device *pdev) { struct nuc900_nand *nuc900_nand = platform_get_drvdata(pdev); struct resource *res; @@ -340,7 +340,7 @@ static int nuc900_nand_remove(struct platform_device *pdev) static struct platform_driver nuc900_nand_driver = { .probe = nuc900_nand_probe, - .remove = nuc900_nand_remove, + .remove = __devexit_p(nuc900_nand_remove), .driver = { .name = "nuc900-fmi", .owner = THIS_MODULE, diff --git a/trunk/drivers/mtd/nand/omap2.c b/trunk/drivers/mtd/nand/omap2.c index 0002d5e94f0d..1f34ba104ef4 100644 --- a/trunk/drivers/mtd/nand/omap2.c +++ b/trunk/drivers/mtd/nand/omap2.c @@ -1323,7 +1323,7 @@ static void omap3_free_bch(struct mtd_info *mtd) } #endif /* CONFIG_MTD_NAND_OMAP_BCH */ -static int omap_nand_probe(struct platform_device *pdev) +static int __devinit omap_nand_probe(struct platform_device *pdev) { struct omap_nand_info *info; struct omap_nand_platform_data *pdata; diff --git a/trunk/drivers/mtd/nand/orion_nand.c b/trunk/drivers/mtd/nand/orion_nand.c index cd72b9299f6b..aefaf8cd31ef 100644 --- a/trunk/drivers/mtd/nand/orion_nand.c +++ b/trunk/drivers/mtd/nand/orion_nand.c @@ -194,7 +194,7 @@ static int __init orion_nand_probe(struct platform_device *pdev) return ret; } -static int orion_nand_remove(struct platform_device *pdev) +static int __devexit orion_nand_remove(struct platform_device *pdev) { struct mtd_info *mtd = platform_get_drvdata(pdev); struct nand_chip *nc = mtd->priv; @@ -223,7 +223,7 @@ static struct of_device_id orion_nand_of_match_table[] = { #endif static struct platform_driver orion_nand_driver = { - .remove = orion_nand_remove, + .remove = __devexit_p(orion_nand_remove), .driver = { .name = "orion_nand", .owner = THIS_MODULE, diff --git a/trunk/drivers/mtd/nand/pasemi_nand.c b/trunk/drivers/mtd/nand/pasemi_nand.c index 5a67082c07ee..1440e51cedcc 100644 --- a/trunk/drivers/mtd/nand/pasemi_nand.c +++ b/trunk/drivers/mtd/nand/pasemi_nand.c @@ -89,7 +89,7 @@ int pasemi_device_ready(struct mtd_info *mtd) return !!(inl(lpcctl) & LBICTRL_LPCCTL_NR); } -static int pasemi_nand_probe(struct platform_device *ofdev) +static int __devinit pasemi_nand_probe(struct platform_device *ofdev) { struct pci_dev *pdev; struct device_node *np = ofdev->dev.of_node; @@ -184,7 +184,7 @@ static int pasemi_nand_probe(struct platform_device *ofdev) return err; } -static int pasemi_nand_remove(struct platform_device *ofdev) +static int __devexit pasemi_nand_remove(struct platform_device *ofdev) { struct nand_chip *chip; diff --git a/trunk/drivers/mtd/nand/plat_nand.c b/trunk/drivers/mtd/nand/plat_nand.c index c004566a9ad2..a47ee68a0cfa 100644 --- a/trunk/drivers/mtd/nand/plat_nand.c +++ b/trunk/drivers/mtd/nand/plat_nand.c @@ -28,7 +28,7 @@ static const char *part_probe_types[] = { "cmdlinepart", NULL }; /* * Probe for the NAND device. */ -static int plat_nand_probe(struct platform_device *pdev) +static int __devinit plat_nand_probe(struct platform_device *pdev) { struct platform_nand_data *pdata = pdev->dev.platform_data; struct mtd_part_parser_data ppdata; @@ -134,7 +134,7 @@ static int plat_nand_probe(struct platform_device *pdev) /* * Remove a NAND device. */ -static int plat_nand_remove(struct platform_device *pdev) +static int __devexit plat_nand_remove(struct platform_device *pdev) { struct plat_nand_data *data = platform_get_drvdata(pdev); struct platform_nand_data *pdata = pdev->dev.platform_data; @@ -160,7 +160,7 @@ MODULE_DEVICE_TABLE(of, plat_nand_match); static struct platform_driver plat_nand_driver = { .probe = plat_nand_probe, - .remove = plat_nand_remove, + .remove = __devexit_p(plat_nand_remove), .driver = { .name = "gen_nand", .owner = THIS_MODULE, diff --git a/trunk/drivers/mtd/nand/s3c2410.c b/trunk/drivers/mtd/nand/s3c2410.c index df954b4dcba2..79ded48e7427 100644 --- a/trunk/drivers/mtd/nand/s3c2410.c +++ b/trunk/drivers/mtd/nand/s3c2410.c @@ -730,14 +730,11 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info, struct s3c2410_nand_mtd *mtd, struct s3c2410_nand_set *set) { - if (set) { + if (set) mtd->mtd.name = set->name; - return mtd_device_parse_register(&mtd->mtd, NULL, NULL, + return mtd_device_parse_register(&mtd->mtd, NULL, NULL, set->partitions, set->nr_partitions); - } - - return -ENODEV; } /** diff --git a/trunk/drivers/mtd/nand/sh_flctl.c b/trunk/drivers/mtd/nand/sh_flctl.c index 57b3971c9c0a..f48ac5d80bbf 100644 --- a/trunk/drivers/mtd/nand/sh_flctl.c +++ b/trunk/drivers/mtd/nand/sh_flctl.c @@ -23,18 +23,11 @@ #include #include -#include #include -#include -#include #include #include -#include -#include -#include #include #include -#include #include #include @@ -113,84 +106,6 @@ static void wait_completion(struct sh_flctl *flctl) writeb(0x0, FLTRCR(flctl)); } -static void flctl_dma_complete(void *param) -{ - struct sh_flctl *flctl = param; - - complete(&flctl->dma_complete); -} - -static void flctl_release_dma(struct sh_flctl *flctl) -{ - if (flctl->chan_fifo0_rx) { - dma_release_channel(flctl->chan_fifo0_rx); - flctl->chan_fifo0_rx = NULL; - } - if (flctl->chan_fifo0_tx) { - dma_release_channel(flctl->chan_fifo0_tx); - flctl->chan_fifo0_tx = NULL; - } -} - -static void flctl_setup_dma(struct sh_flctl *flctl) -{ - dma_cap_mask_t mask; - struct dma_slave_config cfg; - struct platform_device *pdev = flctl->pdev; - struct sh_flctl_platform_data *pdata = pdev->dev.platform_data; - int ret; - - if (!pdata) - return; - - if (pdata->slave_id_fifo0_tx <= 0 || pdata->slave_id_fifo0_rx <= 0) - return; - - /* We can only either use DMA for both Tx and Rx or not use it at all */ - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - - flctl->chan_fifo0_tx = dma_request_channel(mask, shdma_chan_filter, - (void *)pdata->slave_id_fifo0_tx); - dev_dbg(&pdev->dev, "%s: TX: got channel %p\n", __func__, - flctl->chan_fifo0_tx); - - if (!flctl->chan_fifo0_tx) - return; - - memset(&cfg, 0, sizeof(cfg)); - cfg.slave_id = pdata->slave_id_fifo0_tx; - cfg.direction = DMA_MEM_TO_DEV; - cfg.dst_addr = (dma_addr_t)FLDTFIFO(flctl); - cfg.src_addr = 0; - ret = dmaengine_slave_config(flctl->chan_fifo0_tx, &cfg); - if (ret < 0) - goto err; - - flctl->chan_fifo0_rx = dma_request_channel(mask, shdma_chan_filter, - (void *)pdata->slave_id_fifo0_rx); - dev_dbg(&pdev->dev, "%s: RX: got channel %p\n", __func__, - flctl->chan_fifo0_rx); - - if (!flctl->chan_fifo0_rx) - goto err; - - cfg.slave_id = pdata->slave_id_fifo0_rx; - cfg.direction = DMA_DEV_TO_MEM; - cfg.dst_addr = 0; - cfg.src_addr = (dma_addr_t)FLDTFIFO(flctl); - ret = dmaengine_slave_config(flctl->chan_fifo0_rx, &cfg); - if (ret < 0) - goto err; - - init_completion(&flctl->dma_complete); - - return; - -err: - flctl_release_dma(flctl); -} - static void set_addr(struct mtd_info *mtd, int column, int page_addr) { struct sh_flctl *flctl = mtd_to_flctl(mtd); @@ -310,7 +225,7 @@ static enum flctl_ecc_res_t wait_recfifo_ready for (i = 0; i < 3; i++) { uint8_t org; - unsigned int index; + int index; data = readl(ecc_reg[i]); @@ -346,70 +261,6 @@ static void wait_wecfifo_ready(struct sh_flctl *flctl) timeout_error(flctl, __func__); } -static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf, - int len, enum dma_data_direction dir) -{ - struct dma_async_tx_descriptor *desc = NULL; - struct dma_chan *chan; - enum dma_transfer_direction tr_dir; - dma_addr_t dma_addr; - dma_cookie_t cookie = -EINVAL; - uint32_t reg; - int ret; - - if (dir == DMA_FROM_DEVICE) { - chan = flctl->chan_fifo0_rx; - tr_dir = DMA_DEV_TO_MEM; - } else { - chan = flctl->chan_fifo0_tx; - tr_dir = DMA_MEM_TO_DEV; - } - - dma_addr = dma_map_single(chan->device->dev, buf, len, dir); - - if (dma_addr) - desc = dmaengine_prep_slave_single(chan, dma_addr, len, - tr_dir, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - - if (desc) { - reg = readl(FLINTDMACR(flctl)); - reg |= DREQ0EN; - writel(reg, FLINTDMACR(flctl)); - - desc->callback = flctl_dma_complete; - desc->callback_param = flctl; - cookie = dmaengine_submit(desc); - - dma_async_issue_pending(chan); - } else { - /* DMA failed, fall back to PIO */ - flctl_release_dma(flctl); - dev_warn(&flctl->pdev->dev, - "DMA failed, falling back to PIO\n"); - ret = -EIO; - goto out; - } - - ret = - wait_for_completion_timeout(&flctl->dma_complete, - msecs_to_jiffies(3000)); - - if (ret <= 0) { - chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); - dev_err(&flctl->pdev->dev, "wait_for_completion_timeout\n"); - } - -out: - reg = readl(FLINTDMACR(flctl)); - reg &= ~DREQ0EN; - writel(reg, FLINTDMACR(flctl)); - - dma_unmap_single(chan->device->dev, dma_addr, len, dir); - - /* ret > 0 is success */ - return ret; -} - static void read_datareg(struct sh_flctl *flctl, int offset) { unsigned long data; @@ -428,20 +279,11 @@ static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset) len_4align = (rlen + 3) / 4; - /* initiate DMA transfer */ - if (flctl->chan_fifo0_rx && rlen >= 32 && - flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_DEV_TO_MEM) > 0) - goto convert; /* DMA success */ - - /* do polling transfer */ for (i = 0; i < len_4align; i++) { wait_rfifo_ready(flctl); buf[i] = readl(FLDTFIFO(flctl)); - } - -convert: - for (i = 0; i < len_4align; i++) buf[i] = be32_to_cpu(buf[i]); + } } static enum flctl_ecc_res_t read_ecfiforeg @@ -463,39 +305,28 @@ static enum flctl_ecc_res_t read_ecfiforeg return res; } -static void write_fiforeg(struct sh_flctl *flctl, int rlen, - unsigned int offset) +static void write_fiforeg(struct sh_flctl *flctl, int rlen, int offset) { int i, len_4align; - unsigned long *buf = (unsigned long *)&flctl->done_buff[offset]; + unsigned long *data = (unsigned long *)&flctl->done_buff[offset]; + void *fifo_addr = (void *)FLDTFIFO(flctl); len_4align = (rlen + 3) / 4; for (i = 0; i < len_4align; i++) { wait_wfifo_ready(flctl); - writel(cpu_to_be32(buf[i]), FLDTFIFO(flctl)); + writel(cpu_to_be32(data[i]), fifo_addr); } } -static void write_ec_fiforeg(struct sh_flctl *flctl, int rlen, - unsigned int offset) +static void write_ec_fiforeg(struct sh_flctl *flctl, int rlen, int offset) { int i, len_4align; - unsigned long *buf = (unsigned long *)&flctl->done_buff[offset]; + unsigned long *data = (unsigned long *)&flctl->done_buff[offset]; len_4align = (rlen + 3) / 4; - - for (i = 0; i < len_4align; i++) - buf[i] = cpu_to_be32(buf[i]); - - /* initiate DMA transfer */ - if (flctl->chan_fifo0_tx && rlen >= 32 && - flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_MEM_TO_DEV) > 0) - return; /* DMA success */ - - /* do polling transfer */ for (i = 0; i < len_4align; i++) { wait_wecfifo_ready(flctl); - writel(buf[i], FLECFIFO(flctl)); + writel(cpu_to_be32(data[i]), FLECFIFO(flctl)); } } @@ -919,35 +750,41 @@ static void flctl_select_chip(struct mtd_info *mtd, int chipnr) static void flctl_write_buf(struct mtd_info *mtd, const uint8_t *buf, int len) { struct sh_flctl *flctl = mtd_to_flctl(mtd); + int index = flctl->index; - memcpy(&flctl->done_buff[flctl->index], buf, len); + memcpy(&flctl->done_buff[index], buf, len); flctl->index += len; } static uint8_t flctl_read_byte(struct mtd_info *mtd) { struct sh_flctl *flctl = mtd_to_flctl(mtd); + int index = flctl->index; uint8_t data; - data = flctl->done_buff[flctl->index]; + data = flctl->done_buff[index]; flctl->index++; return data; } static uint16_t flctl_read_word(struct mtd_info *mtd) { - struct sh_flctl *flctl = mtd_to_flctl(mtd); - uint16_t *buf = (uint16_t *)&flctl->done_buff[flctl->index]; + struct sh_flctl *flctl = mtd_to_flctl(mtd); + int index = flctl->index; + uint16_t data; + uint16_t *buf = (uint16_t *)&flctl->done_buff[index]; - flctl->index += 2; - return *buf; + data = *buf; + flctl->index += 2; + return data; } static void flctl_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) { struct sh_flctl *flctl = mtd_to_flctl(mtd); + int index = flctl->index; - memcpy(buf, &flctl->done_buff[flctl->index], len); + memcpy(buf, &flctl->done_buff[index], len); flctl->index += len; } @@ -1021,74 +858,7 @@ static irqreturn_t flctl_handle_flste(int irq, void *dev_id) return IRQ_HANDLED; } -#ifdef CONFIG_OF -struct flctl_soc_config { - unsigned long flcmncr_val; - unsigned has_hwecc:1; - unsigned use_holden:1; -}; - -static struct flctl_soc_config flctl_sh7372_config = { - .flcmncr_val = CLK_16B_12L_4H | TYPESEL_SET | SHBUSSEL, - .has_hwecc = 1, - .use_holden = 1, -}; - -static const struct of_device_id of_flctl_match[] = { - { .compatible = "renesas,shmobile-flctl-sh7372", - .data = &flctl_sh7372_config }, - {}, -}; -MODULE_DEVICE_TABLE(of, of_flctl_match); - -static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev) -{ - const struct of_device_id *match; - struct flctl_soc_config *config; - struct sh_flctl_platform_data *pdata; - struct device_node *dn = dev->of_node; - int ret; - - match = of_match_device(of_flctl_match, dev); - if (match) - config = (struct flctl_soc_config *)match->data; - else { - dev_err(dev, "%s: no OF configuration attached\n", __func__); - return NULL; - } - - pdata = devm_kzalloc(dev, sizeof(struct sh_flctl_platform_data), - GFP_KERNEL); - if (!pdata) { - dev_err(dev, "%s: failed to allocate config data\n", __func__); - return NULL; - } - - /* set SoC specific options */ - pdata->flcmncr_val = config->flcmncr_val; - pdata->has_hwecc = config->has_hwecc; - pdata->use_holden = config->use_holden; - - /* parse user defined options */ - ret = of_get_nand_bus_width(dn); - if (ret == 16) - pdata->flcmncr_val |= SEL_16BIT; - else if (ret != 8) { - dev_err(dev, "%s: invalid bus width\n", __func__); - return NULL; - } - - return pdata; -} -#else /* CONFIG_OF */ -#define of_flctl_match NULL -static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev) -{ - return NULL; -} -#endif /* CONFIG_OF */ - -static int flctl_probe(struct platform_device *pdev) +static int __devinit flctl_probe(struct platform_device *pdev) { struct resource *res; struct sh_flctl *flctl; @@ -1097,7 +867,12 @@ static int flctl_probe(struct platform_device *pdev) struct sh_flctl_platform_data *pdata; int ret = -ENXIO; int irq; - struct mtd_part_parser_data ppdata = {}; + + pdata = pdev->dev.platform_data; + if (pdata == NULL) { + dev_err(&pdev->dev, "no platform data defined\n"); + return -EINVAL; + } flctl = kzalloc(sizeof(struct sh_flctl), GFP_KERNEL); if (!flctl) { @@ -1129,17 +904,6 @@ static int flctl_probe(struct platform_device *pdev) goto err_flste; } - if (pdev->dev.of_node) - pdata = flctl_parse_dt(&pdev->dev); - else - pdata = pdev->dev.platform_data; - - if (!pdata) { - dev_err(&pdev->dev, "no setup data defined\n"); - ret = -EINVAL; - goto err_pdata; - } - platform_set_drvdata(pdev, flctl); flctl_mtd = &flctl->mtd; nand = &flctl->chip; @@ -1168,8 +932,6 @@ static int flctl_probe(struct platform_device *pdev) pm_runtime_enable(&pdev->dev); pm_runtime_resume(&pdev->dev); - flctl_setup_dma(flctl); - ret = nand_scan_ident(flctl_mtd, 1, NULL); if (ret) goto err_chip; @@ -1182,16 +944,12 @@ static int flctl_probe(struct platform_device *pdev) if (ret) goto err_chip; - ppdata.of_node = pdev->dev.of_node; - ret = mtd_device_parse_register(flctl_mtd, NULL, &ppdata, pdata->parts, - pdata->nr_parts); + mtd_device_register(flctl_mtd, pdata->parts, pdata->nr_parts); return 0; err_chip: - flctl_release_dma(flctl); pm_runtime_disable(&pdev->dev); -err_pdata: free_irq(irq, flctl); err_flste: iounmap(flctl->reg); @@ -1200,11 +958,10 @@ static int flctl_probe(struct platform_device *pdev) return ret; } -static int flctl_remove(struct platform_device *pdev) +static int __devexit flctl_remove(struct platform_device *pdev) { struct sh_flctl *flctl = platform_get_drvdata(pdev); - flctl_release_dma(flctl); nand_release(&flctl->mtd); pm_runtime_disable(&pdev->dev); free_irq(platform_get_irq(pdev, 0), flctl); @@ -1219,7 +976,6 @@ static struct platform_driver flctl_driver = { .driver = { .name = "sh_flctl", .owner = THIS_MODULE, - .of_match_table = of_flctl_match, }, }; diff --git a/trunk/drivers/mtd/nand/sharpsl.c b/trunk/drivers/mtd/nand/sharpsl.c index 127bc4271821..3421e3762a5a 100644 --- a/trunk/drivers/mtd/nand/sharpsl.c +++ b/trunk/drivers/mtd/nand/sharpsl.c @@ -106,7 +106,7 @@ static int sharpsl_nand_calculate_ecc(struct mtd_info *mtd, const u_char * dat, /* * Main initialization routine */ -static int sharpsl_nand_probe(struct platform_device *pdev) +static int __devinit sharpsl_nand_probe(struct platform_device *pdev) { struct nand_chip *this; struct resource *r; @@ -205,7 +205,7 @@ static int sharpsl_nand_probe(struct platform_device *pdev) /* * Clean up routine */ -static int sharpsl_nand_remove(struct platform_device *pdev) +static int __devexit sharpsl_nand_remove(struct platform_device *pdev) { struct sharpsl_nand *sharpsl = platform_get_drvdata(pdev); @@ -228,7 +228,7 @@ static struct platform_driver sharpsl_nand_driver = { .owner = THIS_MODULE, }, .probe = sharpsl_nand_probe, - .remove = sharpsl_nand_remove, + .remove = __devexit_p(sharpsl_nand_remove), }; module_platform_driver(sharpsl_nand_driver); diff --git a/trunk/drivers/mtd/nand/socrates_nand.c b/trunk/drivers/mtd/nand/socrates_nand.c index 09dde7d27178..f3f28fafbf7a 100644 --- a/trunk/drivers/mtd/nand/socrates_nand.c +++ b/trunk/drivers/mtd/nand/socrates_nand.c @@ -140,7 +140,7 @@ static int socrates_nand_device_ready(struct mtd_info *mtd) /* * Probe for the NAND device. */ -static int socrates_nand_probe(struct platform_device *ofdev) +static int __devinit socrates_nand_probe(struct platform_device *ofdev) { struct socrates_nand_host *host; struct mtd_info *mtd; @@ -220,7 +220,7 @@ static int socrates_nand_probe(struct platform_device *ofdev) /* * Remove a NAND device. */ -static int socrates_nand_remove(struct platform_device *ofdev) +static int __devexit socrates_nand_remove(struct platform_device *ofdev) { struct socrates_nand_host *host = dev_get_drvdata(&ofdev->dev); struct mtd_info *mtd = &host->mtd; @@ -251,7 +251,7 @@ static struct platform_driver socrates_nand_driver = { .of_match_table = socrates_nand_match, }, .probe = socrates_nand_probe, - .remove = socrates_nand_remove, + .remove = __devexit_p(socrates_nand_remove), }; module_platform_driver(socrates_nand_driver); diff --git a/trunk/drivers/mtd/ofpart.c b/trunk/drivers/mtd/ofpart.c index dbd3aa574eaf..d9127e2ed808 100644 --- a/trunk/drivers/mtd/ofpart.c +++ b/trunk/drivers/mtd/ofpart.c @@ -71,10 +71,7 @@ static int parse_ofpart_partitions(struct mtd_info *master, (*pparts)[i].name = (char *)partname; if (of_get_property(pp, "read-only", &len)) - (*pparts)[i].mask_flags |= MTD_WRITEABLE; - - if (of_get_property(pp, "lock", &len)) - (*pparts)[i].mask_flags |= MTD_POWERUP_LOCK; + (*pparts)[i].mask_flags = MTD_WRITEABLE; i++; } diff --git a/trunk/drivers/mtd/onenand/generic.c b/trunk/drivers/mtd/onenand/generic.c index 9f11562f849d..1c4f97c63e62 100644 --- a/trunk/drivers/mtd/onenand/generic.c +++ b/trunk/drivers/mtd/onenand/generic.c @@ -35,7 +35,7 @@ struct onenand_info { struct onenand_chip onenand; }; -static int generic_onenand_probe(struct platform_device *pdev) +static int __devinit generic_onenand_probe(struct platform_device *pdev) { struct onenand_info *info; struct onenand_platform_data *pdata = pdev->dev.platform_data; @@ -88,7 +88,7 @@ static int generic_onenand_probe(struct platform_device *pdev) return err; } -static int generic_onenand_remove(struct platform_device *pdev) +static int __devexit generic_onenand_remove(struct platform_device *pdev) { struct onenand_info *info = platform_get_drvdata(pdev); struct resource *res = pdev->resource; @@ -112,7 +112,7 @@ static struct platform_driver generic_onenand_driver = { .owner = THIS_MODULE, }, .probe = generic_onenand_probe, - .remove = generic_onenand_remove, + .remove = __devexit_p(generic_onenand_remove), }; module_platform_driver(generic_onenand_driver); diff --git a/trunk/drivers/mtd/onenand/omap2.c b/trunk/drivers/mtd/onenand/omap2.c index 065f3fe02a2f..00cd3da29435 100644 --- a/trunk/drivers/mtd/onenand/omap2.c +++ b/trunk/drivers/mtd/onenand/omap2.c @@ -630,7 +630,7 @@ static int omap2_onenand_disable(struct mtd_info *mtd) return ret; } -static int omap2_onenand_probe(struct platform_device *pdev) +static int __devinit omap2_onenand_probe(struct platform_device *pdev) { struct omap_onenand_platform_data *pdata; struct omap2_onenand *c; @@ -799,7 +799,7 @@ static int omap2_onenand_probe(struct platform_device *pdev) return r; } -static int omap2_onenand_remove(struct platform_device *pdev) +static int __devexit omap2_onenand_remove(struct platform_device *pdev) { struct omap2_onenand *c = dev_get_drvdata(&pdev->dev); @@ -822,7 +822,7 @@ static int omap2_onenand_remove(struct platform_device *pdev) static struct platform_driver omap2_onenand_driver = { .probe = omap2_onenand_probe, - .remove = omap2_onenand_remove, + .remove = __devexit_p(omap2_onenand_remove), .shutdown = omap2_onenand_shutdown, .driver = { .name = DRIVER_NAME, diff --git a/trunk/drivers/mtd/onenand/samsung.c b/trunk/drivers/mtd/onenand/samsung.c index 33f2a8fb8df9..8e4b3f2742ba 100644 --- a/trunk/drivers/mtd/onenand/samsung.c +++ b/trunk/drivers/mtd/onenand/samsung.c @@ -1053,7 +1053,7 @@ static int s3c_onenand_probe(struct platform_device *pdev) return err; } -static int s3c_onenand_remove(struct platform_device *pdev) +static int __devexit s3c_onenand_remove(struct platform_device *pdev) { struct mtd_info *mtd = platform_get_drvdata(pdev); @@ -1130,7 +1130,7 @@ static struct platform_driver s3c_onenand_driver = { }, .id_table = s3c_onenand_driver_ids, .probe = s3c_onenand_probe, - .remove = s3c_onenand_remove, + .remove = __devexit_p(s3c_onenand_remove), }; module_platform_driver(s3c_onenand_driver); diff --git a/trunk/drivers/mtd/tests/mtd_nandbiterrs.c b/trunk/drivers/mtd/tests/mtd_nandbiterrs.c index 207bf9a9972f..cc8d62cb280c 100644 --- a/trunk/drivers/mtd/tests/mtd_nandbiterrs.c +++ b/trunk/drivers/mtd/tests/mtd_nandbiterrs.c @@ -39,9 +39,6 @@ * this program; see the file COPYING. If not, write to the Free Software * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -50,6 +47,8 @@ #include #include +#define msg(FMT, VA...) pr_info("mtd_nandbiterrs: "FMT, ##VA) + static int dev; module_param(dev, int, S_IRUGO); MODULE_PARM_DESC(dev, "MTD device number to use"); @@ -104,7 +103,7 @@ static int erase_block(void) struct erase_info ei; loff_t addr = eraseblock * mtd->erasesize; - pr_info("erase_block\n"); + msg("erase_block\n"); memset(&ei, 0, sizeof(struct erase_info)); ei.mtd = mtd; @@ -113,7 +112,7 @@ static int erase_block(void) err = mtd_erase(mtd, &ei); if (err || ei.state == MTD_ERASE_FAILED) { - pr_err("error %d while erasing\n", err); + msg("error %d while erasing\n", err); if (!err) err = -EIO; return err; @@ -129,11 +128,11 @@ static int write_page(int log) size_t written; if (log) - pr_info("write_page\n"); + msg("write_page\n"); err = mtd_write(mtd, offset, mtd->writesize, &written, wbuffer); if (err || written != mtd->writesize) { - pr_err("error: write failed at %#llx\n", (long long)offset); + msg("error: write failed at %#llx\n", (long long)offset); if (!err) err = -EIO; } @@ -148,7 +147,7 @@ static int rewrite_page(int log) struct mtd_oob_ops ops; if (log) - pr_info("rewrite page\n"); + msg("rewrite page\n"); ops.mode = MTD_OPS_RAW; /* No ECC */ ops.len = mtd->writesize; @@ -161,7 +160,7 @@ static int rewrite_page(int log) err = mtd_write_oob(mtd, offset, &ops); if (err || ops.retlen != mtd->writesize) { - pr_err("error: write_oob failed (%d)\n", err); + msg("error: write_oob failed (%d)\n", err); if (!err) err = -EIO; } @@ -178,7 +177,7 @@ static int read_page(int log) struct mtd_ecc_stats oldstats; if (log) - pr_info("read_page\n"); + msg("read_page\n"); /* Saving last mtd stats */ memcpy(&oldstats, &mtd->ecc_stats, sizeof(oldstats)); @@ -188,7 +187,7 @@ static int read_page(int log) err = mtd->ecc_stats.corrected - oldstats.corrected; if (err < 0 || read != mtd->writesize) { - pr_err("error: read failed at %#llx\n", (long long)offset); + msg("error: read failed at %#llx\n", (long long)offset); if (err >= 0) err = -EIO; } @@ -202,11 +201,11 @@ static int verify_page(int log) unsigned i, errs = 0; if (log) - pr_info("verify_page\n"); + msg("verify_page\n"); for (i = 0; i < mtd->writesize; i++) { if (rbuffer[i] != hash(i+seed)) { - pr_err("Error: page offset %u, expected %02x, got %02x\n", + msg("Error: page offset %u, expected %02x, got %02x\n", i, hash(i+seed), rbuffer[i]); errs++; } @@ -231,13 +230,13 @@ static int insert_biterror(unsigned byte) for (bit = 7; bit >= 0; bit--) { if (CBIT(wbuffer[byte], bit)) { BCLR(wbuffer[byte], bit); - pr_info("Inserted biterror @ %u/%u\n", byte, bit); + msg("Inserted biterror @ %u/%u\n", byte, bit); return 0; } } byte++; } - pr_err("biterror: Failed to find a '1' bit\n"); + msg("biterror: Failed to find a '1' bit\n"); return -EIO; } @@ -249,7 +248,7 @@ static int incremental_errors_test(void) unsigned i; unsigned errs_per_subpage = 0; - pr_info("incremental biterrors test\n"); + msg("incremental biterrors test\n"); for (i = 0; i < mtd->writesize; i++) wbuffer[i] = hash(i+seed); @@ -266,9 +265,9 @@ static int incremental_errors_test(void) err = read_page(1); if (err > 0) - pr_info("Read reported %d corrected bit errors\n", err); + msg("Read reported %d corrected bit errors\n", err); if (err < 0) { - pr_err("After %d biterrors per subpage, read reported error %d\n", + msg("After %d biterrors per subpage, read reported error %d\n", errs_per_subpage, err); err = 0; goto exit; @@ -276,11 +275,11 @@ static int incremental_errors_test(void) err = verify_page(1); if (err) { - pr_err("ECC failure, read data is incorrect despite read success\n"); + msg("ECC failure, read data is incorrect despite read success\n"); goto exit; } - pr_info("Successfully corrected %d bit errors per subpage\n", + msg("Successfully corrected %d bit errors per subpage\n", errs_per_subpage); for (i = 0; i < subcount; i++) { @@ -312,7 +311,7 @@ static int overwrite_test(void) memset(bitstats, 0, sizeof(bitstats)); - pr_info("overwrite biterrors test\n"); + msg("overwrite biterrors test\n"); for (i = 0; i < mtd->writesize; i++) wbuffer[i] = hash(i+seed); @@ -330,18 +329,18 @@ static int overwrite_test(void) err = read_page(0); if (err >= 0) { if (err >= MAXBITS) { - pr_info("Implausible number of bit errors corrected\n"); + msg("Implausible number of bit errors corrected\n"); err = -EIO; break; } bitstats[err]++; if (err > max_corrected) { max_corrected = err; - pr_info("Read reported %d corrected bit errors\n", + msg("Read reported %d corrected bit errors\n", err); } } else { /* err < 0 */ - pr_info("Read reported error %d\n", err); + msg("Read reported error %d\n", err); err = 0; break; } @@ -349,7 +348,7 @@ static int overwrite_test(void) err = verify_page(0); if (err) { bitstats[max_corrected] = opno; - pr_info("ECC failure, read data is incorrect despite read success\n"); + msg("ECC failure, read data is incorrect despite read success\n"); break; } @@ -358,9 +357,9 @@ static int overwrite_test(void) /* At this point bitstats[0] contains the number of ops with no bit * errors, bitstats[1] the number of ops with 1 bit error, etc. */ - pr_info("Bit error histogram (%d operations total):\n", opno); + msg("Bit error histogram (%d operations total):\n", opno); for (i = 0; i < max_corrected; i++) - pr_info("Page reads with %3d corrected bit errors: %d\n", + msg("Page reads with %3d corrected bit errors: %d\n", i, bitstats[i]); exit: @@ -371,36 +370,36 @@ static int __init mtd_nandbiterrs_init(void) { int err = 0; - printk("\n"); - printk(KERN_INFO "==================================================\n"); - pr_info("MTD device: %d\n", dev); + msg("\n"); + msg("==================================================\n"); + msg("MTD device: %d\n", dev); mtd = get_mtd_device(NULL, dev); if (IS_ERR(mtd)) { err = PTR_ERR(mtd); - pr_err("error: cannot get MTD device\n"); + msg("error: cannot get MTD device\n"); goto exit_mtddev; } if (mtd->type != MTD_NANDFLASH) { - pr_info("this test requires NAND flash\n"); + msg("this test requires NAND flash\n"); err = -ENODEV; goto exit_nand; } - pr_info("MTD device size %llu, eraseblock=%u, page=%u, oob=%u\n", + msg("MTD device size %llu, eraseblock=%u, page=%u, oob=%u\n", (unsigned long long)mtd->size, mtd->erasesize, mtd->writesize, mtd->oobsize); subsize = mtd->writesize >> mtd->subpage_sft; subcount = mtd->writesize / subsize; - pr_info("Device uses %d subpages of %d bytes\n", subcount, subsize); + msg("Device uses %d subpages of %d bytes\n", subcount, subsize); offset = page_offset * mtd->writesize; eraseblock = mtd_div_by_eb(offset, mtd); - pr_info("Using page=%u, offset=%llu, eraseblock=%u\n", + msg("Using page=%u, offset=%llu, eraseblock=%u\n", page_offset, offset, eraseblock); wbuffer = kmalloc(mtd->writesize, GFP_KERNEL); @@ -433,8 +432,8 @@ static int __init mtd_nandbiterrs_init(void) goto exit_error; err = -EIO; - pr_info("finished successfully.\n"); - printk(KERN_INFO "==================================================\n"); + msg("finished successfully.\n"); + msg("==================================================\n"); exit_error: kfree(rbuffer); diff --git a/trunk/drivers/mtd/tests/mtd_nandecctest.c b/trunk/drivers/mtd/tests/mtd_nandecctest.c index 1eee264509a8..b437fa425077 100644 --- a/trunk/drivers/mtd/tests/mtd_nandecctest.c +++ b/trunk/drivers/mtd/tests/mtd_nandecctest.c @@ -1,5 +1,3 @@ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -266,13 +264,13 @@ static int nand_ecc_test_run(const size_t size) correct_data, size); if (err) { - pr_err("not ok - %s-%zd\n", + pr_err("mtd_nandecctest: not ok - %s-%zd\n", nand_ecc_test[i].name, size); dump_data_ecc(error_data, error_ecc, correct_data, correct_ecc, size); break; } - pr_info("ok - %s-%zd\n", + pr_info("mtd_nandecctest: ok - %s-%zd\n", nand_ecc_test[i].name, size); } error: diff --git a/trunk/drivers/mtd/tests/mtd_oobtest.c b/trunk/drivers/mtd/tests/mtd_oobtest.c index e827fa8cd844..ed9b62827f1b 100644 --- a/trunk/drivers/mtd/tests/mtd_oobtest.c +++ b/trunk/drivers/mtd/tests/mtd_oobtest.c @@ -19,8 +19,6 @@ * Author: Adrian Hunter */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -30,6 +28,8 @@ #include #include +#define PRINT_PREF KERN_INFO "mtd_oobtest: " + static int dev = -EINVAL; module_param(dev, int, S_IRUGO); MODULE_PARM_DESC(dev, "MTD device number to use"); @@ -80,12 +80,13 @@ static int erase_eraseblock(int ebnum) err = mtd_erase(mtd, &ei); if (err) { - pr_err("error %d while erasing EB %d\n", err, ebnum); + printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum); return err; } if (ei.state == MTD_ERASE_FAILED) { - pr_err("some erase error occurred at EB %d\n", ebnum); + printk(PRINT_PREF "some erase error occurred at EB %d\n", + ebnum); return -EIO; } @@ -97,7 +98,7 @@ static int erase_whole_device(void) int err; unsigned int i; - pr_info("erasing whole device\n"); + printk(PRINT_PREF "erasing whole device\n"); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; @@ -106,7 +107,7 @@ static int erase_whole_device(void) return err; cond_resched(); } - pr_info("erased %u eraseblocks\n", i); + printk(PRINT_PREF "erased %u eraseblocks\n", i); return 0; } @@ -140,9 +141,9 @@ static int write_eraseblock(int ebnum) ops.oobbuf = writebuf; err = mtd_write_oob(mtd, addr, &ops); if (err || ops.oobretlen != use_len) { - pr_err("error: writeoob failed at %#llx\n", + printk(PRINT_PREF "error: writeoob failed at %#llx\n", (long long)addr); - pr_err("error: use_len %d, use_offset %d\n", + printk(PRINT_PREF "error: use_len %d, use_offset %d\n", use_len, use_offset); errcnt += 1; return err ? err : -1; @@ -159,7 +160,7 @@ static int write_whole_device(void) int err; unsigned int i; - pr_info("writing OOBs of whole device\n"); + printk(PRINT_PREF "writing OOBs of whole device\n"); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; @@ -167,10 +168,10 @@ static int write_whole_device(void) if (err) return err; if (i % 256 == 0) - pr_info("written up to eraseblock %u\n", i); + printk(PRINT_PREF "written up to eraseblock %u\n", i); cond_resched(); } - pr_info("written %u eraseblocks\n", i); + printk(PRINT_PREF "written %u eraseblocks\n", i); return 0; } @@ -193,17 +194,17 @@ static int verify_eraseblock(int ebnum) ops.oobbuf = readbuf; err = mtd_read_oob(mtd, addr, &ops); if (err || ops.oobretlen != use_len) { - pr_err("error: readoob failed at %#llx\n", + printk(PRINT_PREF "error: readoob failed at %#llx\n", (long long)addr); errcnt += 1; return err ? err : -1; } if (memcmp(readbuf, writebuf, use_len)) { - pr_err("error: verify failed at %#llx\n", + printk(PRINT_PREF "error: verify failed at %#llx\n", (long long)addr); errcnt += 1; if (errcnt > 1000) { - pr_err("error: too many errors\n"); + printk(PRINT_PREF "error: too many errors\n"); return -1; } } @@ -220,28 +221,29 @@ static int verify_eraseblock(int ebnum) ops.oobbuf = readbuf; err = mtd_read_oob(mtd, addr, &ops); if (err || ops.oobretlen != mtd->ecclayout->oobavail) { - pr_err("error: readoob failed at %#llx\n", - (long long)addr); + printk(PRINT_PREF "error: readoob failed at " + "%#llx\n", (long long)addr); errcnt += 1; return err ? err : -1; } if (memcmp(readbuf + use_offset, writebuf, use_len)) { - pr_err("error: verify failed at %#llx\n", - (long long)addr); + printk(PRINT_PREF "error: verify failed at " + "%#llx\n", (long long)addr); errcnt += 1; if (errcnt > 1000) { - pr_err("error: too many errors\n"); + printk(PRINT_PREF "error: too many " + "errors\n"); return -1; } } for (k = 0; k < use_offset; ++k) if (readbuf[k] != 0xff) { - pr_err("error: verify 0xff " + printk(PRINT_PREF "error: verify 0xff " "failed at %#llx\n", (long long)addr); errcnt += 1; if (errcnt > 1000) { - pr_err("error: too " + printk(PRINT_PREF "error: too " "many errors\n"); return -1; } @@ -249,12 +251,12 @@ static int verify_eraseblock(int ebnum) for (k = use_offset + use_len; k < mtd->ecclayout->oobavail; ++k) if (readbuf[k] != 0xff) { - pr_err("error: verify 0xff " + printk(PRINT_PREF "error: verify 0xff " "failed at %#llx\n", (long long)addr); errcnt += 1; if (errcnt > 1000) { - pr_err("error: too " + printk(PRINT_PREF "error: too " "many errors\n"); return -1; } @@ -284,17 +286,17 @@ static int verify_eraseblock_in_one_go(int ebnum) ops.oobbuf = readbuf; err = mtd_read_oob(mtd, addr, &ops); if (err || ops.oobretlen != len) { - pr_err("error: readoob failed at %#llx\n", + printk(PRINT_PREF "error: readoob failed at %#llx\n", (long long)addr); errcnt += 1; return err ? err : -1; } if (memcmp(readbuf, writebuf, len)) { - pr_err("error: verify failed at %#llx\n", + printk(PRINT_PREF "error: verify failed at %#llx\n", (long long)addr); errcnt += 1; if (errcnt > 1000) { - pr_err("error: too many errors\n"); + printk(PRINT_PREF "error: too many errors\n"); return -1; } } @@ -307,7 +309,7 @@ static int verify_all_eraseblocks(void) int err; unsigned int i; - pr_info("verifying all eraseblocks\n"); + printk(PRINT_PREF "verifying all eraseblocks\n"); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; @@ -315,10 +317,10 @@ static int verify_all_eraseblocks(void) if (err) return err; if (i % 256 == 0) - pr_info("verified up to eraseblock %u\n", i); + printk(PRINT_PREF "verified up to eraseblock %u\n", i); cond_resched(); } - pr_info("verified %u eraseblocks\n", i); + printk(PRINT_PREF "verified %u eraseblocks\n", i); return 0; } @@ -329,7 +331,7 @@ static int is_block_bad(int ebnum) ret = mtd_block_isbad(mtd, addr); if (ret) - pr_info("block %d is bad\n", ebnum); + printk(PRINT_PREF "block %d is bad\n", ebnum); return ret; } @@ -339,18 +341,18 @@ static int scan_for_bad_eraseblocks(void) bbt = kmalloc(ebcnt, GFP_KERNEL); if (!bbt) { - pr_err("error: cannot allocate memory\n"); + printk(PRINT_PREF "error: cannot allocate memory\n"); return -ENOMEM; } - pr_info("scanning for bad eraseblocks\n"); + printk(PRINT_PREF "scanning for bad eraseblocks\n"); for (i = 0; i < ebcnt; ++i) { bbt[i] = is_block_bad(i) ? 1 : 0; if (bbt[i]) bad += 1; cond_resched(); } - pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); + printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad); return 0; } @@ -366,22 +368,22 @@ static int __init mtd_oobtest_init(void) printk(KERN_INFO "=================================================\n"); if (dev < 0) { - pr_info("Please specify a valid mtd-device via module parameter\n"); - pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); + printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n"); + printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n"); return -EINVAL; } - pr_info("MTD device: %d\n", dev); + printk(PRINT_PREF "MTD device: %d\n", dev); mtd = get_mtd_device(NULL, dev); if (IS_ERR(mtd)) { err = PTR_ERR(mtd); - pr_err("error: cannot get MTD device\n"); + printk(PRINT_PREF "error: cannot get MTD device\n"); return err; } if (mtd->type != MTD_NANDFLASH) { - pr_info("this test requires NAND flash\n"); + printk(PRINT_PREF "this test requires NAND flash\n"); goto out; } @@ -390,7 +392,7 @@ static int __init mtd_oobtest_init(void) ebcnt = tmp; pgcnt = mtd->erasesize / mtd->writesize; - pr_info("MTD device size %llu, eraseblock size %u, " + printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " "page size %u, count of eraseblocks %u, pages per " "eraseblock %u, OOB size %u\n", (unsigned long long)mtd->size, mtd->erasesize, @@ -399,12 +401,12 @@ static int __init mtd_oobtest_init(void) err = -ENOMEM; readbuf = kmalloc(mtd->erasesize, GFP_KERNEL); if (!readbuf) { - pr_err("error: cannot allocate memory\n"); + printk(PRINT_PREF "error: cannot allocate memory\n"); goto out; } writebuf = kmalloc(mtd->erasesize, GFP_KERNEL); if (!writebuf) { - pr_err("error: cannot allocate memory\n"); + printk(PRINT_PREF "error: cannot allocate memory\n"); goto out; } @@ -418,7 +420,7 @@ static int __init mtd_oobtest_init(void) vary_offset = 0; /* First test: write all OOB, read it back and verify */ - pr_info("test 1 of 5\n"); + printk(PRINT_PREF "test 1 of 5\n"); err = erase_whole_device(); if (err) @@ -438,7 +440,7 @@ static int __init mtd_oobtest_init(void) * Second test: write all OOB, a block at a time, read it back and * verify. */ - pr_info("test 2 of 5\n"); + printk(PRINT_PREF "test 2 of 5\n"); err = erase_whole_device(); if (err) @@ -451,7 +453,7 @@ static int __init mtd_oobtest_init(void) /* Check all eraseblocks */ simple_srand(3); - pr_info("verifying all eraseblocks\n"); + printk(PRINT_PREF "verifying all eraseblocks\n"); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; @@ -459,16 +461,16 @@ static int __init mtd_oobtest_init(void) if (err) goto out; if (i % 256 == 0) - pr_info("verified up to eraseblock %u\n", i); + printk(PRINT_PREF "verified up to eraseblock %u\n", i); cond_resched(); } - pr_info("verified %u eraseblocks\n", i); + printk(PRINT_PREF "verified %u eraseblocks\n", i); /* * Third test: write OOB at varying offsets and lengths, read it back * and verify. */ - pr_info("test 3 of 5\n"); + printk(PRINT_PREF "test 3 of 5\n"); err = erase_whole_device(); if (err) @@ -501,7 +503,7 @@ static int __init mtd_oobtest_init(void) vary_offset = 0; /* Fourth test: try to write off end of device */ - pr_info("test 4 of 5\n"); + printk(PRINT_PREF "test 4 of 5\n"); err = erase_whole_device(); if (err) @@ -520,14 +522,14 @@ static int __init mtd_oobtest_init(void) ops.ooboffs = mtd->ecclayout->oobavail; ops.datbuf = NULL; ops.oobbuf = writebuf; - pr_info("attempting to start write past end of OOB\n"); - pr_info("an error is expected...\n"); + printk(PRINT_PREF "attempting to start write past end of OOB\n"); + printk(PRINT_PREF "an error is expected...\n"); err = mtd_write_oob(mtd, addr0, &ops); if (err) { - pr_info("error occurred as expected\n"); + printk(PRINT_PREF "error occurred as expected\n"); err = 0; } else { - pr_err("error: can write past end of OOB\n"); + printk(PRINT_PREF "error: can write past end of OOB\n"); errcnt += 1; } @@ -540,19 +542,19 @@ static int __init mtd_oobtest_init(void) ops.ooboffs = mtd->ecclayout->oobavail; ops.datbuf = NULL; ops.oobbuf = readbuf; - pr_info("attempting to start read past end of OOB\n"); - pr_info("an error is expected...\n"); + printk(PRINT_PREF "attempting to start read past end of OOB\n"); + printk(PRINT_PREF "an error is expected...\n"); err = mtd_read_oob(mtd, addr0, &ops); if (err) { - pr_info("error occurred as expected\n"); + printk(PRINT_PREF "error occurred as expected\n"); err = 0; } else { - pr_err("error: can read past end of OOB\n"); + printk(PRINT_PREF "error: can read past end of OOB\n"); errcnt += 1; } if (bbt[ebcnt - 1]) - pr_info("skipping end of device tests because last " + printk(PRINT_PREF "skipping end of device tests because last " "block is bad\n"); else { /* Attempt to write off end of device */ @@ -564,14 +566,14 @@ static int __init mtd_oobtest_init(void) ops.ooboffs = 0; ops.datbuf = NULL; ops.oobbuf = writebuf; - pr_info("attempting to write past end of device\n"); - pr_info("an error is expected...\n"); + printk(PRINT_PREF "attempting to write past end of device\n"); + printk(PRINT_PREF "an error is expected...\n"); err = mtd_write_oob(mtd, mtd->size - mtd->writesize, &ops); if (err) { - pr_info("error occurred as expected\n"); + printk(PRINT_PREF "error occurred as expected\n"); err = 0; } else { - pr_err("error: wrote past end of device\n"); + printk(PRINT_PREF "error: wrote past end of device\n"); errcnt += 1; } @@ -584,14 +586,14 @@ static int __init mtd_oobtest_init(void) ops.ooboffs = 0; ops.datbuf = NULL; ops.oobbuf = readbuf; - pr_info("attempting to read past end of device\n"); - pr_info("an error is expected...\n"); + printk(PRINT_PREF "attempting to read past end of device\n"); + printk(PRINT_PREF "an error is expected...\n"); err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops); if (err) { - pr_info("error occurred as expected\n"); + printk(PRINT_PREF "error occurred as expected\n"); err = 0; } else { - pr_err("error: read past end of device\n"); + printk(PRINT_PREF "error: read past end of device\n"); errcnt += 1; } @@ -608,14 +610,14 @@ static int __init mtd_oobtest_init(void) ops.ooboffs = 1; ops.datbuf = NULL; ops.oobbuf = writebuf; - pr_info("attempting to write past end of device\n"); - pr_info("an error is expected...\n"); + printk(PRINT_PREF "attempting to write past end of device\n"); + printk(PRINT_PREF "an error is expected...\n"); err = mtd_write_oob(mtd, mtd->size - mtd->writesize, &ops); if (err) { - pr_info("error occurred as expected\n"); + printk(PRINT_PREF "error occurred as expected\n"); err = 0; } else { - pr_err("error: wrote past end of device\n"); + printk(PRINT_PREF "error: wrote past end of device\n"); errcnt += 1; } @@ -628,20 +630,20 @@ static int __init mtd_oobtest_init(void) ops.ooboffs = 1; ops.datbuf = NULL; ops.oobbuf = readbuf; - pr_info("attempting to read past end of device\n"); - pr_info("an error is expected...\n"); + printk(PRINT_PREF "attempting to read past end of device\n"); + printk(PRINT_PREF "an error is expected...\n"); err = mtd_read_oob(mtd, mtd->size - mtd->writesize, &ops); if (err) { - pr_info("error occurred as expected\n"); + printk(PRINT_PREF "error occurred as expected\n"); err = 0; } else { - pr_err("error: read past end of device\n"); + printk(PRINT_PREF "error: read past end of device\n"); errcnt += 1; } } /* Fifth test: write / read across block boundaries */ - pr_info("test 5 of 5\n"); + printk(PRINT_PREF "test 5 of 5\n"); /* Erase all eraseblocks */ err = erase_whole_device(); @@ -650,7 +652,7 @@ static int __init mtd_oobtest_init(void) /* Write all eraseblocks */ simple_srand(11); - pr_info("writing OOBs of whole device\n"); + printk(PRINT_PREF "writing OOBs of whole device\n"); for (i = 0; i < ebcnt - 1; ++i) { int cnt = 2; int pg; @@ -672,16 +674,17 @@ static int __init mtd_oobtest_init(void) if (err) goto out; if (i % 256 == 0) - pr_info("written up to eraseblock %u\n", i); + printk(PRINT_PREF "written up to eraseblock " + "%u\n", i); cond_resched(); addr += mtd->writesize; } } - pr_info("written %u eraseblocks\n", i); + printk(PRINT_PREF "written %u eraseblocks\n", i); /* Check all eraseblocks */ simple_srand(11); - pr_info("verifying all eraseblocks\n"); + printk(PRINT_PREF "verifying all eraseblocks\n"); for (i = 0; i < ebcnt - 1; ++i) { if (bbt[i] || bbt[i + 1]) continue; @@ -699,28 +702,28 @@ static int __init mtd_oobtest_init(void) if (err) goto out; if (memcmp(readbuf, writebuf, mtd->ecclayout->oobavail * 2)) { - pr_err("error: verify failed at %#llx\n", + printk(PRINT_PREF "error: verify failed at %#llx\n", (long long)addr); errcnt += 1; if (errcnt > 1000) { - pr_err("error: too many errors\n"); + printk(PRINT_PREF "error: too many errors\n"); goto out; } } if (i % 256 == 0) - pr_info("verified up to eraseblock %u\n", i); + printk(PRINT_PREF "verified up to eraseblock %u\n", i); cond_resched(); } - pr_info("verified %u eraseblocks\n", i); + printk(PRINT_PREF "verified %u eraseblocks\n", i); - pr_info("finished with %d errors\n", errcnt); + printk(PRINT_PREF "finished with %d errors\n", errcnt); out: kfree(bbt); kfree(writebuf); kfree(readbuf); put_mtd_device(mtd); if (err) - pr_info("error %d occurred\n", err); + printk(PRINT_PREF "error %d occurred\n", err); printk(KERN_INFO "=================================================\n"); return err; } diff --git a/trunk/drivers/mtd/tests/mtd_pagetest.c b/trunk/drivers/mtd/tests/mtd_pagetest.c index f93a76f88113..252ddb092fb2 100644 --- a/trunk/drivers/mtd/tests/mtd_pagetest.c +++ b/trunk/drivers/mtd/tests/mtd_pagetest.c @@ -19,8 +19,6 @@ * Author: Adrian Hunter */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -30,6 +28,8 @@ #include #include +#define PRINT_PREF KERN_INFO "mtd_pagetest: " + static int dev = -EINVAL; module_param(dev, int, S_IRUGO); MODULE_PARM_DESC(dev, "MTD device number to use"); @@ -79,12 +79,12 @@ static int erase_eraseblock(int ebnum) err = mtd_erase(mtd, &ei); if (err) { - pr_err("error %d while erasing EB %d\n", err, ebnum); + printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum); return err; } if (ei.state == MTD_ERASE_FAILED) { - pr_err("some erase error occurred at EB %d\n", + printk(PRINT_PREF "some erase error occurred at EB %d\n", ebnum); return -EIO; } @@ -102,7 +102,7 @@ static int write_eraseblock(int ebnum) cond_resched(); err = mtd_write(mtd, addr, mtd->erasesize, &written, writebuf); if (err || written != mtd->erasesize) - pr_err("error: write failed at %#llx\n", + printk(PRINT_PREF "error: write failed at %#llx\n", (long long)addr); return err; @@ -131,7 +131,7 @@ static int verify_eraseblock(int ebnum) if (mtd_is_bitflip(err)) err = 0; if (err || read != bufsize) { - pr_err("error: read failed at %#llx\n", + printk(PRINT_PREF "error: read failed at %#llx\n", (long long)addr0); return err; } @@ -139,7 +139,7 @@ static int verify_eraseblock(int ebnum) if (mtd_is_bitflip(err)) err = 0; if (err || read != bufsize) { - pr_err("error: read failed at %#llx\n", + printk(PRINT_PREF "error: read failed at %#llx\n", (long long)(addrn - bufsize)); return err; } @@ -148,12 +148,12 @@ static int verify_eraseblock(int ebnum) if (mtd_is_bitflip(err)) err = 0; if (err || read != bufsize) { - pr_err("error: read failed at %#llx\n", + printk(PRINT_PREF "error: read failed at %#llx\n", (long long)addr); break; } if (memcmp(twopages, writebuf + (j * pgsize), bufsize)) { - pr_err("error: verify failed at %#llx\n", + printk(PRINT_PREF "error: verify failed at %#llx\n", (long long)addr); errcnt += 1; } @@ -166,7 +166,7 @@ static int verify_eraseblock(int ebnum) if (mtd_is_bitflip(err)) err = 0; if (err || read != bufsize) { - pr_err("error: read failed at %#llx\n", + printk(PRINT_PREF "error: read failed at %#llx\n", (long long)addr0); return err; } @@ -174,7 +174,7 @@ static int verify_eraseblock(int ebnum) if (mtd_is_bitflip(err)) err = 0; if (err || read != bufsize) { - pr_err("error: read failed at %#llx\n", + printk(PRINT_PREF "error: read failed at %#llx\n", (long long)(addrn - bufsize)); return err; } @@ -183,14 +183,14 @@ static int verify_eraseblock(int ebnum) if (mtd_is_bitflip(err)) err = 0; if (err || read != bufsize) { - pr_err("error: read failed at %#llx\n", + printk(PRINT_PREF "error: read failed at %#llx\n", (long long)addr); return err; } memcpy(boundary, writebuf + mtd->erasesize - pgsize, pgsize); set_random_data(boundary + pgsize, pgsize); if (memcmp(twopages, boundary, bufsize)) { - pr_err("error: verify failed at %#llx\n", + printk(PRINT_PREF "error: verify failed at %#llx\n", (long long)addr); errcnt += 1; } @@ -206,10 +206,10 @@ static int crosstest(void) loff_t addr, addr0, addrn; unsigned char *pp1, *pp2, *pp3, *pp4; - pr_info("crosstest\n"); + printk(PRINT_PREF "crosstest\n"); pp1 = kmalloc(pgsize * 4, GFP_KERNEL); if (!pp1) { - pr_err("error: cannot allocate memory\n"); + printk(PRINT_PREF "error: cannot allocate memory\n"); return -ENOMEM; } pp2 = pp1 + pgsize; @@ -231,7 +231,7 @@ static int crosstest(void) if (mtd_is_bitflip(err)) err = 0; if (err || read != pgsize) { - pr_err("error: read failed at %#llx\n", + printk(PRINT_PREF "error: read failed at %#llx\n", (long long)addr); kfree(pp1); return err; @@ -243,7 +243,7 @@ static int crosstest(void) if (mtd_is_bitflip(err)) err = 0; if (err || read != pgsize) { - pr_err("error: read failed at %#llx\n", + printk(PRINT_PREF "error: read failed at %#llx\n", (long long)addr); kfree(pp1); return err; @@ -251,12 +251,12 @@ static int crosstest(void) /* Read first page to pp2 */ addr = addr0; - pr_info("reading page at %#llx\n", (long long)addr); + printk(PRINT_PREF "reading page at %#llx\n", (long long)addr); err = mtd_read(mtd, addr, pgsize, &read, pp2); if (mtd_is_bitflip(err)) err = 0; if (err || read != pgsize) { - pr_err("error: read failed at %#llx\n", + printk(PRINT_PREF "error: read failed at %#llx\n", (long long)addr); kfree(pp1); return err; @@ -264,12 +264,12 @@ static int crosstest(void) /* Read last page to pp3 */ addr = addrn - pgsize; - pr_info("reading page at %#llx\n", (long long)addr); + printk(PRINT_PREF "reading page at %#llx\n", (long long)addr); err = mtd_read(mtd, addr, pgsize, &read, pp3); if (mtd_is_bitflip(err)) err = 0; if (err || read != pgsize) { - pr_err("error: read failed at %#llx\n", + printk(PRINT_PREF "error: read failed at %#llx\n", (long long)addr); kfree(pp1); return err; @@ -277,25 +277,25 @@ static int crosstest(void) /* Read first page again to pp4 */ addr = addr0; - pr_info("reading page at %#llx\n", (long long)addr); + printk(PRINT_PREF "reading page at %#llx\n", (long long)addr); err = mtd_read(mtd, addr, pgsize, &read, pp4); if (mtd_is_bitflip(err)) err = 0; if (err || read != pgsize) { - pr_err("error: read failed at %#llx\n", + printk(PRINT_PREF "error: read failed at %#llx\n", (long long)addr); kfree(pp1); return err; } /* pp2 and pp4 should be the same */ - pr_info("verifying pages read at %#llx match\n", + printk(PRINT_PREF "verifying pages read at %#llx match\n", (long long)addr0); if (memcmp(pp2, pp4, pgsize)) { - pr_err("verify failed!\n"); + printk(PRINT_PREF "verify failed!\n"); errcnt += 1; } else if (!err) - pr_info("crosstest ok\n"); + printk(PRINT_PREF "crosstest ok\n"); kfree(pp1); return err; } @@ -307,7 +307,7 @@ static int erasecrosstest(void) loff_t addr0; char *readbuf = twopages; - pr_info("erasecrosstest\n"); + printk(PRINT_PREF "erasecrosstest\n"); ebnum = 0; addr0 = 0; @@ -320,79 +320,79 @@ static int erasecrosstest(void) while (ebnum2 && bbt[ebnum2]) ebnum2 -= 1; - pr_info("erasing block %d\n", ebnum); + printk(PRINT_PREF "erasing block %d\n", ebnum); err = erase_eraseblock(ebnum); if (err) return err; - pr_info("writing 1st page of block %d\n", ebnum); + printk(PRINT_PREF "writing 1st page of block %d\n", ebnum); set_random_data(writebuf, pgsize); strcpy(writebuf, "There is no data like this!"); err = mtd_write(mtd, addr0, pgsize, &written, writebuf); if (err || written != pgsize) { - pr_info("error: write failed at %#llx\n", + printk(PRINT_PREF "error: write failed at %#llx\n", (long long)addr0); return err ? err : -1; } - pr_info("reading 1st page of block %d\n", ebnum); + printk(PRINT_PREF "reading 1st page of block %d\n", ebnum); memset(readbuf, 0, pgsize); err = mtd_read(mtd, addr0, pgsize, &read, readbuf); if (mtd_is_bitflip(err)) err = 0; if (err || read != pgsize) { - pr_err("error: read failed at %#llx\n", + printk(PRINT_PREF "error: read failed at %#llx\n", (long long)addr0); return err ? err : -1; } - pr_info("verifying 1st page of block %d\n", ebnum); + printk(PRINT_PREF "verifying 1st page of block %d\n", ebnum); if (memcmp(writebuf, readbuf, pgsize)) { - pr_err("verify failed!\n"); + printk(PRINT_PREF "verify failed!\n"); errcnt += 1; return -1; } - pr_info("erasing block %d\n", ebnum); + printk(PRINT_PREF "erasing block %d\n", ebnum); err = erase_eraseblock(ebnum); if (err) return err; - pr_info("writing 1st page of block %d\n", ebnum); + printk(PRINT_PREF "writing 1st page of block %d\n", ebnum); set_random_data(writebuf, pgsize); strcpy(writebuf, "There is no data like this!"); err = mtd_write(mtd, addr0, pgsize, &written, writebuf); if (err || written != pgsize) { - pr_err("error: write failed at %#llx\n", + printk(PRINT_PREF "error: write failed at %#llx\n", (long long)addr0); return err ? err : -1; } - pr_info("erasing block %d\n", ebnum2); + printk(PRINT_PREF "erasing block %d\n", ebnum2); err = erase_eraseblock(ebnum2); if (err) return err; - pr_info("reading 1st page of block %d\n", ebnum); + printk(PRINT_PREF "reading 1st page of block %d\n", ebnum); memset(readbuf, 0, pgsize); err = mtd_read(mtd, addr0, pgsize, &read, readbuf); if (mtd_is_bitflip(err)) err = 0; if (err || read != pgsize) { - pr_err("error: read failed at %#llx\n", + printk(PRINT_PREF "error: read failed at %#llx\n", (long long)addr0); return err ? err : -1; } - pr_info("verifying 1st page of block %d\n", ebnum); + printk(PRINT_PREF "verifying 1st page of block %d\n", ebnum); if (memcmp(writebuf, readbuf, pgsize)) { - pr_err("verify failed!\n"); + printk(PRINT_PREF "verify failed!\n"); errcnt += 1; return -1; } if (!err) - pr_info("erasecrosstest ok\n"); + printk(PRINT_PREF "erasecrosstest ok\n"); return err; } @@ -402,7 +402,7 @@ static int erasetest(void) int err = 0, i, ebnum, ok = 1; loff_t addr0; - pr_info("erasetest\n"); + printk(PRINT_PREF "erasetest\n"); ebnum = 0; addr0 = 0; @@ -411,40 +411,40 @@ static int erasetest(void) ebnum += 1; } - pr_info("erasing block %d\n", ebnum); + printk(PRINT_PREF "erasing block %d\n", ebnum); err = erase_eraseblock(ebnum); if (err) return err; - pr_info("writing 1st page of block %d\n", ebnum); + printk(PRINT_PREF "writing 1st page of block %d\n", ebnum); set_random_data(writebuf, pgsize); err = mtd_write(mtd, addr0, pgsize, &written, writebuf); if (err || written != pgsize) { - pr_err("error: write failed at %#llx\n", + printk(PRINT_PREF "error: write failed at %#llx\n", (long long)addr0); return err ? err : -1; } - pr_info("erasing block %d\n", ebnum); + printk(PRINT_PREF "erasing block %d\n", ebnum); err = erase_eraseblock(ebnum); if (err) return err; - pr_info("reading 1st page of block %d\n", ebnum); + printk(PRINT_PREF "reading 1st page of block %d\n", ebnum); err = mtd_read(mtd, addr0, pgsize, &read, twopages); if (mtd_is_bitflip(err)) err = 0; if (err || read != pgsize) { - pr_err("error: read failed at %#llx\n", + printk(PRINT_PREF "error: read failed at %#llx\n", (long long)addr0); return err ? err : -1; } - pr_info("verifying 1st page of block %d is all 0xff\n", + printk(PRINT_PREF "verifying 1st page of block %d is all 0xff\n", ebnum); for (i = 0; i < pgsize; ++i) if (twopages[i] != 0xff) { - pr_err("verifying all 0xff failed at %d\n", + printk(PRINT_PREF "verifying all 0xff failed at %d\n", i); errcnt += 1; ok = 0; @@ -452,7 +452,7 @@ static int erasetest(void) } if (ok && !err) - pr_info("erasetest ok\n"); + printk(PRINT_PREF "erasetest ok\n"); return err; } @@ -464,7 +464,7 @@ static int is_block_bad(int ebnum) ret = mtd_block_isbad(mtd, addr); if (ret) - pr_info("block %d is bad\n", ebnum); + printk(PRINT_PREF "block %d is bad\n", ebnum); return ret; } @@ -474,18 +474,18 @@ static int scan_for_bad_eraseblocks(void) bbt = kzalloc(ebcnt, GFP_KERNEL); if (!bbt) { - pr_err("error: cannot allocate memory\n"); + printk(PRINT_PREF "error: cannot allocate memory\n"); return -ENOMEM; } - pr_info("scanning for bad eraseblocks\n"); + printk(PRINT_PREF "scanning for bad eraseblocks\n"); for (i = 0; i < ebcnt; ++i) { bbt[i] = is_block_bad(i) ? 1 : 0; if (bbt[i]) bad += 1; cond_resched(); } - pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); + printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad); return 0; } @@ -499,22 +499,22 @@ static int __init mtd_pagetest_init(void) printk(KERN_INFO "=================================================\n"); if (dev < 0) { - pr_info("Please specify a valid mtd-device via module parameter\n"); - pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); + printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n"); + printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n"); return -EINVAL; } - pr_info("MTD device: %d\n", dev); + printk(PRINT_PREF "MTD device: %d\n", dev); mtd = get_mtd_device(NULL, dev); if (IS_ERR(mtd)) { err = PTR_ERR(mtd); - pr_err("error: cannot get MTD device\n"); + printk(PRINT_PREF "error: cannot get MTD device\n"); return err; } if (mtd->type != MTD_NANDFLASH) { - pr_info("this test requires NAND flash\n"); + printk(PRINT_PREF "this test requires NAND flash\n"); goto out; } @@ -524,7 +524,7 @@ static int __init mtd_pagetest_init(void) pgcnt = mtd->erasesize / mtd->writesize; pgsize = mtd->writesize; - pr_info("MTD device size %llu, eraseblock size %u, " + printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " "page size %u, count of eraseblocks %u, pages per " "eraseblock %u, OOB size %u\n", (unsigned long long)mtd->size, mtd->erasesize, @@ -534,17 +534,17 @@ static int __init mtd_pagetest_init(void) bufsize = pgsize * 2; writebuf = kmalloc(mtd->erasesize, GFP_KERNEL); if (!writebuf) { - pr_err("error: cannot allocate memory\n"); + printk(PRINT_PREF "error: cannot allocate memory\n"); goto out; } twopages = kmalloc(bufsize, GFP_KERNEL); if (!twopages) { - pr_err("error: cannot allocate memory\n"); + printk(PRINT_PREF "error: cannot allocate memory\n"); goto out; } boundary = kmalloc(bufsize, GFP_KERNEL); if (!boundary) { - pr_err("error: cannot allocate memory\n"); + printk(PRINT_PREF "error: cannot allocate memory\n"); goto out; } @@ -553,7 +553,7 @@ static int __init mtd_pagetest_init(void) goto out; /* Erase all eraseblocks */ - pr_info("erasing whole device\n"); + printk(PRINT_PREF "erasing whole device\n"); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; @@ -562,11 +562,11 @@ static int __init mtd_pagetest_init(void) goto out; cond_resched(); } - pr_info("erased %u eraseblocks\n", i); + printk(PRINT_PREF "erased %u eraseblocks\n", i); /* Write all eraseblocks */ simple_srand(1); - pr_info("writing whole device\n"); + printk(PRINT_PREF "writing whole device\n"); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; @@ -574,14 +574,14 @@ static int __init mtd_pagetest_init(void) if (err) goto out; if (i % 256 == 0) - pr_info("written up to eraseblock %u\n", i); + printk(PRINT_PREF "written up to eraseblock %u\n", i); cond_resched(); } - pr_info("written %u eraseblocks\n", i); + printk(PRINT_PREF "written %u eraseblocks\n", i); /* Check all eraseblocks */ simple_srand(1); - pr_info("verifying all eraseblocks\n"); + printk(PRINT_PREF "verifying all eraseblocks\n"); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; @@ -589,10 +589,10 @@ static int __init mtd_pagetest_init(void) if (err) goto out; if (i % 256 == 0) - pr_info("verified up to eraseblock %u\n", i); + printk(PRINT_PREF "verified up to eraseblock %u\n", i); cond_resched(); } - pr_info("verified %u eraseblocks\n", i); + printk(PRINT_PREF "verified %u eraseblocks\n", i); err = crosstest(); if (err) @@ -606,7 +606,7 @@ static int __init mtd_pagetest_init(void) if (err) goto out; - pr_info("finished with %d errors\n", errcnt); + printk(PRINT_PREF "finished with %d errors\n", errcnt); out: kfree(bbt); @@ -615,7 +615,7 @@ static int __init mtd_pagetest_init(void) kfree(writebuf); put_mtd_device(mtd); if (err) - pr_info("error %d occurred\n", err); + printk(PRINT_PREF "error %d occurred\n", err); printk(KERN_INFO "=================================================\n"); return err; } diff --git a/trunk/drivers/mtd/tests/mtd_readtest.c b/trunk/drivers/mtd/tests/mtd_readtest.c index 266de04b6d29..121aba189cec 100644 --- a/trunk/drivers/mtd/tests/mtd_readtest.c +++ b/trunk/drivers/mtd/tests/mtd_readtest.c @@ -19,8 +19,6 @@ * Author: Adrian Hunter */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -29,6 +27,8 @@ #include #include +#define PRINT_PREF KERN_INFO "mtd_readtest: " + static int dev = -EINVAL; module_param(dev, int, S_IRUGO); MODULE_PARM_DESC(dev, "MTD device number to use"); @@ -51,12 +51,12 @@ static int read_eraseblock_by_page(int ebnum) void *oobbuf = iobuf1; for (i = 0; i < pgcnt; i++) { - memset(buf, 0 , pgsize); + memset(buf, 0 , pgcnt); ret = mtd_read(mtd, addr, pgsize, &read, buf); if (ret == -EUCLEAN) ret = 0; if (ret || read != pgsize) { - pr_err("error: read failed at %#llx\n", + printk(PRINT_PREF "error: read failed at %#llx\n", (long long)addr); if (!err) err = ret; @@ -77,7 +77,7 @@ static int read_eraseblock_by_page(int ebnum) ret = mtd_read_oob(mtd, addr, &ops); if ((ret && !mtd_is_bitflip(ret)) || ops.oobretlen != mtd->oobsize) { - pr_err("error: read oob failed at " + printk(PRINT_PREF "error: read oob failed at " "%#llx\n", (long long)addr); if (!err) err = ret; @@ -99,7 +99,7 @@ static void dump_eraseblock(int ebnum) char line[128]; int pg, oob; - pr_info("dumping eraseblock %d\n", ebnum); + printk(PRINT_PREF "dumping eraseblock %d\n", ebnum); n = mtd->erasesize; for (i = 0; i < n;) { char *p = line; @@ -112,7 +112,7 @@ static void dump_eraseblock(int ebnum) } if (!mtd->oobsize) return; - pr_info("dumping oob from eraseblock %d\n", ebnum); + printk(PRINT_PREF "dumping oob from eraseblock %d\n", ebnum); n = mtd->oobsize; for (pg = 0, i = 0; pg < pgcnt; pg++) for (oob = 0; oob < n;) { @@ -134,7 +134,7 @@ static int is_block_bad(int ebnum) ret = mtd_block_isbad(mtd, addr); if (ret) - pr_info("block %d is bad\n", ebnum); + printk(PRINT_PREF "block %d is bad\n", ebnum); return ret; } @@ -144,21 +144,21 @@ static int scan_for_bad_eraseblocks(void) bbt = kzalloc(ebcnt, GFP_KERNEL); if (!bbt) { - pr_err("error: cannot allocate memory\n"); + printk(PRINT_PREF "error: cannot allocate memory\n"); return -ENOMEM; } if (!mtd_can_have_bb(mtd)) return 0; - pr_info("scanning for bad eraseblocks\n"); + printk(PRINT_PREF "scanning for bad eraseblocks\n"); for (i = 0; i < ebcnt; ++i) { bbt[i] = is_block_bad(i) ? 1 : 0; if (bbt[i]) bad += 1; cond_resched(); } - pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); + printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad); return 0; } @@ -171,21 +171,21 @@ static int __init mtd_readtest_init(void) printk(KERN_INFO "=================================================\n"); if (dev < 0) { - pr_info("Please specify a valid mtd-device via module parameter\n"); + printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n"); return -EINVAL; } - pr_info("MTD device: %d\n", dev); + printk(PRINT_PREF "MTD device: %d\n", dev); mtd = get_mtd_device(NULL, dev); if (IS_ERR(mtd)) { err = PTR_ERR(mtd); - pr_err("error: Cannot get MTD device\n"); + printk(PRINT_PREF "error: Cannot get MTD device\n"); return err; } if (mtd->writesize == 1) { - pr_info("not NAND flash, assume page size is 512 " + printk(PRINT_PREF "not NAND flash, assume page size is 512 " "bytes.\n"); pgsize = 512; } else @@ -196,7 +196,7 @@ static int __init mtd_readtest_init(void) ebcnt = tmp; pgcnt = mtd->erasesize / pgsize; - pr_info("MTD device size %llu, eraseblock size %u, " + printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " "page size %u, count of eraseblocks %u, pages per " "eraseblock %u, OOB size %u\n", (unsigned long long)mtd->size, mtd->erasesize, @@ -205,12 +205,12 @@ static int __init mtd_readtest_init(void) err = -ENOMEM; iobuf = kmalloc(mtd->erasesize, GFP_KERNEL); if (!iobuf) { - pr_err("error: cannot allocate memory\n"); + printk(PRINT_PREF "error: cannot allocate memory\n"); goto out; } iobuf1 = kmalloc(mtd->erasesize, GFP_KERNEL); if (!iobuf1) { - pr_err("error: cannot allocate memory\n"); + printk(PRINT_PREF "error: cannot allocate memory\n"); goto out; } @@ -219,7 +219,7 @@ static int __init mtd_readtest_init(void) goto out; /* Read all eraseblocks 1 page at a time */ - pr_info("testing page read\n"); + printk(PRINT_PREF "testing page read\n"); for (i = 0; i < ebcnt; ++i) { int ret; @@ -235,9 +235,9 @@ static int __init mtd_readtest_init(void) } if (err) - pr_info("finished with errors\n"); + printk(PRINT_PREF "finished with errors\n"); else - pr_info("finished\n"); + printk(PRINT_PREF "finished\n"); out: @@ -246,7 +246,7 @@ static int __init mtd_readtest_init(void) kfree(bbt); put_mtd_device(mtd); if (err) - pr_info("error %d occurred\n", err); + printk(PRINT_PREF "error %d occurred\n", err); printk(KERN_INFO "=================================================\n"); return err; } diff --git a/trunk/drivers/mtd/tests/mtd_speedtest.c b/trunk/drivers/mtd/tests/mtd_speedtest.c index 596cbea8df4c..42b0f7456fc4 100644 --- a/trunk/drivers/mtd/tests/mtd_speedtest.c +++ b/trunk/drivers/mtd/tests/mtd_speedtest.c @@ -19,8 +19,6 @@ * Author: Adrian Hunter */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -30,6 +28,8 @@ #include #include +#define PRINT_PREF KERN_INFO "mtd_speedtest: " + static int dev = -EINVAL; module_param(dev, int, S_IRUGO); MODULE_PARM_DESC(dev, "MTD device number to use"); @@ -70,12 +70,12 @@ static int erase_eraseblock(int ebnum) err = mtd_erase(mtd, &ei); if (err) { - pr_err("error %d while erasing EB %d\n", err, ebnum); + printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum); return err; } if (ei.state == MTD_ERASE_FAILED) { - pr_err("some erase error occurred at EB %d\n", + printk(PRINT_PREF "some erase error occurred at EB %d\n", ebnum); return -EIO; } @@ -96,13 +96,13 @@ static int multiblock_erase(int ebnum, int blocks) err = mtd_erase(mtd, &ei); if (err) { - pr_err("error %d while erasing EB %d, blocks %d\n", + printk(PRINT_PREF "error %d while erasing EB %d, blocks %d\n", err, ebnum, blocks); return err; } if (ei.state == MTD_ERASE_FAILED) { - pr_err("some erase error occurred at EB %d," + printk(PRINT_PREF "some erase error occurred at EB %d," "blocks %d\n", ebnum, blocks); return -EIO; } @@ -134,7 +134,7 @@ static int write_eraseblock(int ebnum) err = mtd_write(mtd, addr, mtd->erasesize, &written, iobuf); if (err || written != mtd->erasesize) { - pr_err("error: write failed at %#llx\n", addr); + printk(PRINT_PREF "error: write failed at %#llx\n", addr); if (!err) err = -EINVAL; } @@ -152,7 +152,7 @@ static int write_eraseblock_by_page(int ebnum) for (i = 0; i < pgcnt; i++) { err = mtd_write(mtd, addr, pgsize, &written, buf); if (err || written != pgsize) { - pr_err("error: write failed at %#llx\n", + printk(PRINT_PREF "error: write failed at %#llx\n", addr); if (!err) err = -EINVAL; @@ -175,7 +175,7 @@ static int write_eraseblock_by_2pages(int ebnum) for (i = 0; i < n; i++) { err = mtd_write(mtd, addr, sz, &written, buf); if (err || written != sz) { - pr_err("error: write failed at %#llx\n", + printk(PRINT_PREF "error: write failed at %#llx\n", addr); if (!err) err = -EINVAL; @@ -187,7 +187,7 @@ static int write_eraseblock_by_2pages(int ebnum) if (pgcnt % 2) { err = mtd_write(mtd, addr, pgsize, &written, buf); if (err || written != pgsize) { - pr_err("error: write failed at %#llx\n", + printk(PRINT_PREF "error: write failed at %#llx\n", addr); if (!err) err = -EINVAL; @@ -208,7 +208,7 @@ static int read_eraseblock(int ebnum) if (mtd_is_bitflip(err)) err = 0; if (err || read != mtd->erasesize) { - pr_err("error: read failed at %#llx\n", addr); + printk(PRINT_PREF "error: read failed at %#llx\n", addr); if (!err) err = -EINVAL; } @@ -229,7 +229,7 @@ static int read_eraseblock_by_page(int ebnum) if (mtd_is_bitflip(err)) err = 0; if (err || read != pgsize) { - pr_err("error: read failed at %#llx\n", + printk(PRINT_PREF "error: read failed at %#llx\n", addr); if (!err) err = -EINVAL; @@ -255,7 +255,7 @@ static int read_eraseblock_by_2pages(int ebnum) if (mtd_is_bitflip(err)) err = 0; if (err || read != sz) { - pr_err("error: read failed at %#llx\n", + printk(PRINT_PREF "error: read failed at %#llx\n", addr); if (!err) err = -EINVAL; @@ -270,7 +270,7 @@ static int read_eraseblock_by_2pages(int ebnum) if (mtd_is_bitflip(err)) err = 0; if (err || read != pgsize) { - pr_err("error: read failed at %#llx\n", + printk(PRINT_PREF "error: read failed at %#llx\n", addr); if (!err) err = -EINVAL; @@ -287,7 +287,7 @@ static int is_block_bad(int ebnum) ret = mtd_block_isbad(mtd, addr); if (ret) - pr_info("block %d is bad\n", ebnum); + printk(PRINT_PREF "block %d is bad\n", ebnum); return ret; } @@ -321,21 +321,21 @@ static int scan_for_bad_eraseblocks(void) bbt = kzalloc(ebcnt, GFP_KERNEL); if (!bbt) { - pr_err("error: cannot allocate memory\n"); + printk(PRINT_PREF "error: cannot allocate memory\n"); return -ENOMEM; } if (!mtd_can_have_bb(mtd)) goto out; - pr_info("scanning for bad eraseblocks\n"); + printk(PRINT_PREF "scanning for bad eraseblocks\n"); for (i = 0; i < ebcnt; ++i) { bbt[i] = is_block_bad(i) ? 1 : 0; if (bbt[i]) bad += 1; cond_resched(); } - pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); + printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad); out: goodebcnt = ebcnt - bad; return 0; @@ -351,25 +351,25 @@ static int __init mtd_speedtest_init(void) printk(KERN_INFO "=================================================\n"); if (dev < 0) { - pr_info("Please specify a valid mtd-device via module parameter\n"); - pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); + printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n"); + printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n"); return -EINVAL; } if (count) - pr_info("MTD device: %d count: %d\n", dev, count); + printk(PRINT_PREF "MTD device: %d count: %d\n", dev, count); else - pr_info("MTD device: %d\n", dev); + printk(PRINT_PREF "MTD device: %d\n", dev); mtd = get_mtd_device(NULL, dev); if (IS_ERR(mtd)) { err = PTR_ERR(mtd); - pr_err("error: cannot get MTD device\n"); + printk(PRINT_PREF "error: cannot get MTD device\n"); return err; } if (mtd->writesize == 1) { - pr_info("not NAND flash, assume page size is 512 " + printk(PRINT_PREF "not NAND flash, assume page size is 512 " "bytes.\n"); pgsize = 512; } else @@ -380,7 +380,7 @@ static int __init mtd_speedtest_init(void) ebcnt = tmp; pgcnt = mtd->erasesize / pgsize; - pr_info("MTD device size %llu, eraseblock size %u, " + printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " "page size %u, count of eraseblocks %u, pages per " "eraseblock %u, OOB size %u\n", (unsigned long long)mtd->size, mtd->erasesize, @@ -392,7 +392,7 @@ static int __init mtd_speedtest_init(void) err = -ENOMEM; iobuf = kmalloc(mtd->erasesize, GFP_KERNEL); if (!iobuf) { - pr_err("error: cannot allocate memory\n"); + printk(PRINT_PREF "error: cannot allocate memory\n"); goto out; } @@ -407,7 +407,7 @@ static int __init mtd_speedtest_init(void) goto out; /* Write all eraseblocks, 1 eraseblock at a time */ - pr_info("testing eraseblock write speed\n"); + printk(PRINT_PREF "testing eraseblock write speed\n"); start_timing(); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) @@ -419,10 +419,10 @@ static int __init mtd_speedtest_init(void) } stop_timing(); speed = calc_speed(); - pr_info("eraseblock write speed is %ld KiB/s\n", speed); + printk(PRINT_PREF "eraseblock write speed is %ld KiB/s\n", speed); /* Read all eraseblocks, 1 eraseblock at a time */ - pr_info("testing eraseblock read speed\n"); + printk(PRINT_PREF "testing eraseblock read speed\n"); start_timing(); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) @@ -434,14 +434,14 @@ static int __init mtd_speedtest_init(void) } stop_timing(); speed = calc_speed(); - pr_info("eraseblock read speed is %ld KiB/s\n", speed); + printk(PRINT_PREF "eraseblock read speed is %ld KiB/s\n", speed); err = erase_whole_device(); if (err) goto out; /* Write all eraseblocks, 1 page at a time */ - pr_info("testing page write speed\n"); + printk(PRINT_PREF "testing page write speed\n"); start_timing(); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) @@ -453,10 +453,10 @@ static int __init mtd_speedtest_init(void) } stop_timing(); speed = calc_speed(); - pr_info("page write speed is %ld KiB/s\n", speed); + printk(PRINT_PREF "page write speed is %ld KiB/s\n", speed); /* Read all eraseblocks, 1 page at a time */ - pr_info("testing page read speed\n"); + printk(PRINT_PREF "testing page read speed\n"); start_timing(); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) @@ -468,14 +468,14 @@ static int __init mtd_speedtest_init(void) } stop_timing(); speed = calc_speed(); - pr_info("page read speed is %ld KiB/s\n", speed); + printk(PRINT_PREF "page read speed is %ld KiB/s\n", speed); err = erase_whole_device(); if (err) goto out; /* Write all eraseblocks, 2 pages at a time */ - pr_info("testing 2 page write speed\n"); + printk(PRINT_PREF "testing 2 page write speed\n"); start_timing(); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) @@ -487,10 +487,10 @@ static int __init mtd_speedtest_init(void) } stop_timing(); speed = calc_speed(); - pr_info("2 page write speed is %ld KiB/s\n", speed); + printk(PRINT_PREF "2 page write speed is %ld KiB/s\n", speed); /* Read all eraseblocks, 2 pages at a time */ - pr_info("testing 2 page read speed\n"); + printk(PRINT_PREF "testing 2 page read speed\n"); start_timing(); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) @@ -502,10 +502,10 @@ static int __init mtd_speedtest_init(void) } stop_timing(); speed = calc_speed(); - pr_info("2 page read speed is %ld KiB/s\n", speed); + printk(PRINT_PREF "2 page read speed is %ld KiB/s\n", speed); /* Erase all eraseblocks */ - pr_info("Testing erase speed\n"); + printk(PRINT_PREF "Testing erase speed\n"); start_timing(); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) @@ -517,12 +517,12 @@ static int __init mtd_speedtest_init(void) } stop_timing(); speed = calc_speed(); - pr_info("erase speed is %ld KiB/s\n", speed); + printk(PRINT_PREF "erase speed is %ld KiB/s\n", speed); /* Multi-block erase all eraseblocks */ for (k = 1; k < 7; k++) { blocks = 1 << k; - pr_info("Testing %dx multi-block erase speed\n", + printk(PRINT_PREF "Testing %dx multi-block erase speed\n", blocks); start_timing(); for (i = 0; i < ebcnt; ) { @@ -541,16 +541,16 @@ static int __init mtd_speedtest_init(void) } stop_timing(); speed = calc_speed(); - pr_info("%dx multi-block erase speed is %ld KiB/s\n", + printk(PRINT_PREF "%dx multi-block erase speed is %ld KiB/s\n", blocks, speed); } - pr_info("finished\n"); + printk(PRINT_PREF "finished\n"); out: kfree(iobuf); kfree(bbt); put_mtd_device(mtd); if (err) - pr_info("error %d occurred\n", err); + printk(PRINT_PREF "error %d occurred\n", err); printk(KERN_INFO "=================================================\n"); return err; } diff --git a/trunk/drivers/mtd/tests/mtd_stresstest.c b/trunk/drivers/mtd/tests/mtd_stresstest.c index 3729f679ae5d..cb268cebf01a 100644 --- a/trunk/drivers/mtd/tests/mtd_stresstest.c +++ b/trunk/drivers/mtd/tests/mtd_stresstest.c @@ -19,8 +19,6 @@ * Author: Adrian Hunter */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -31,6 +29,8 @@ #include #include +#define PRINT_PREF KERN_INFO "mtd_stresstest: " + static int dev = -EINVAL; module_param(dev, int, S_IRUGO); MODULE_PARM_DESC(dev, "MTD device number to use"); @@ -94,12 +94,12 @@ static int erase_eraseblock(int ebnum) err = mtd_erase(mtd, &ei); if (unlikely(err)) { - pr_err("error %d while erasing EB %d\n", err, ebnum); + printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum); return err; } if (unlikely(ei.state == MTD_ERASE_FAILED)) { - pr_err("some erase error occurred at EB %d\n", + printk(PRINT_PREF "some erase error occurred at EB %d\n", ebnum); return -EIO; } @@ -114,7 +114,7 @@ static int is_block_bad(int ebnum) ret = mtd_block_isbad(mtd, addr); if (ret) - pr_info("block %d is bad\n", ebnum); + printk(PRINT_PREF "block %d is bad\n", ebnum); return ret; } @@ -137,7 +137,7 @@ static int do_read(void) if (mtd_is_bitflip(err)) err = 0; if (unlikely(err || read != len)) { - pr_err("error: read failed at 0x%llx\n", + printk(PRINT_PREF "error: read failed at 0x%llx\n", (long long)addr); if (!err) err = -EINVAL; @@ -174,7 +174,7 @@ static int do_write(void) addr = eb * mtd->erasesize + offs; err = mtd_write(mtd, addr, len, &written, writebuf); if (unlikely(err || written != len)) { - pr_err("error: write failed at 0x%llx\n", + printk(PRINT_PREF "error: write failed at 0x%llx\n", (long long)addr); if (!err) err = -EINVAL; @@ -203,21 +203,21 @@ static int scan_for_bad_eraseblocks(void) bbt = kzalloc(ebcnt, GFP_KERNEL); if (!bbt) { - pr_err("error: cannot allocate memory\n"); + printk(PRINT_PREF "error: cannot allocate memory\n"); return -ENOMEM; } if (!mtd_can_have_bb(mtd)) return 0; - pr_info("scanning for bad eraseblocks\n"); + printk(PRINT_PREF "scanning for bad eraseblocks\n"); for (i = 0; i < ebcnt; ++i) { bbt[i] = is_block_bad(i) ? 1 : 0; if (bbt[i]) bad += 1; cond_resched(); } - pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); + printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad); return 0; } @@ -231,22 +231,22 @@ static int __init mtd_stresstest_init(void) printk(KERN_INFO "=================================================\n"); if (dev < 0) { - pr_info("Please specify a valid mtd-device via module parameter\n"); - pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); + printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n"); + printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n"); return -EINVAL; } - pr_info("MTD device: %d\n", dev); + printk(PRINT_PREF "MTD device: %d\n", dev); mtd = get_mtd_device(NULL, dev); if (IS_ERR(mtd)) { err = PTR_ERR(mtd); - pr_err("error: cannot get MTD device\n"); + printk(PRINT_PREF "error: cannot get MTD device\n"); return err; } if (mtd->writesize == 1) { - pr_info("not NAND flash, assume page size is 512 " + printk(PRINT_PREF "not NAND flash, assume page size is 512 " "bytes.\n"); pgsize = 512; } else @@ -257,14 +257,14 @@ static int __init mtd_stresstest_init(void) ebcnt = tmp; pgcnt = mtd->erasesize / pgsize; - pr_info("MTD device size %llu, eraseblock size %u, " + printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " "page size %u, count of eraseblocks %u, pages per " "eraseblock %u, OOB size %u\n", (unsigned long long)mtd->size, mtd->erasesize, pgsize, ebcnt, pgcnt, mtd->oobsize); if (ebcnt < 2) { - pr_err("error: need at least 2 eraseblocks\n"); + printk(PRINT_PREF "error: need at least 2 eraseblocks\n"); err = -ENOSPC; goto out_put_mtd; } @@ -277,7 +277,7 @@ static int __init mtd_stresstest_init(void) writebuf = vmalloc(bufsize); offsets = kmalloc(ebcnt * sizeof(int), GFP_KERNEL); if (!readbuf || !writebuf || !offsets) { - pr_err("error: cannot allocate memory\n"); + printk(PRINT_PREF "error: cannot allocate memory\n"); goto out; } for (i = 0; i < ebcnt; i++) @@ -290,16 +290,16 @@ static int __init mtd_stresstest_init(void) goto out; /* Do operations */ - pr_info("doing operations\n"); + printk(PRINT_PREF "doing operations\n"); for (op = 0; op < count; op++) { if ((op & 1023) == 0) - pr_info("%d operations done\n", op); + printk(PRINT_PREF "%d operations done\n", op); err = do_operation(); if (err) goto out; cond_resched(); } - pr_info("finished, %d operations done\n", op); + printk(PRINT_PREF "finished, %d operations done\n", op); out: kfree(offsets); @@ -309,7 +309,7 @@ static int __init mtd_stresstest_init(void) out_put_mtd: put_mtd_device(mtd); if (err) - pr_info("error %d occurred\n", err); + printk(PRINT_PREF "error %d occurred\n", err); printk(KERN_INFO "=================================================\n"); return err; } diff --git a/trunk/drivers/mtd/tests/mtd_subpagetest.c b/trunk/drivers/mtd/tests/mtd_subpagetest.c index c880c2229c59..9667bf535282 100644 --- a/trunk/drivers/mtd/tests/mtd_subpagetest.c +++ b/trunk/drivers/mtd/tests/mtd_subpagetest.c @@ -19,8 +19,6 @@ * */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -29,6 +27,8 @@ #include #include +#define PRINT_PREF KERN_INFO "mtd_subpagetest: " + static int dev = -EINVAL; module_param(dev, int, S_IRUGO); MODULE_PARM_DESC(dev, "MTD device number to use"); @@ -82,12 +82,12 @@ static int erase_eraseblock(int ebnum) err = mtd_erase(mtd, &ei); if (err) { - pr_err("error %d while erasing EB %d\n", err, ebnum); + printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum); return err; } if (ei.state == MTD_ERASE_FAILED) { - pr_err("some erase error occurred at EB %d\n", + printk(PRINT_PREF "some erase error occurred at EB %d\n", ebnum); return -EIO; } @@ -100,7 +100,7 @@ static int erase_whole_device(void) int err; unsigned int i; - pr_info("erasing whole device\n"); + printk(PRINT_PREF "erasing whole device\n"); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; @@ -109,7 +109,7 @@ static int erase_whole_device(void) return err; cond_resched(); } - pr_info("erased %u eraseblocks\n", i); + printk(PRINT_PREF "erased %u eraseblocks\n", i); return 0; } @@ -122,11 +122,11 @@ static int write_eraseblock(int ebnum) set_random_data(writebuf, subpgsize); err = mtd_write(mtd, addr, subpgsize, &written, writebuf); if (unlikely(err || written != subpgsize)) { - pr_err("error: write failed at %#llx\n", + printk(PRINT_PREF "error: write failed at %#llx\n", (long long)addr); if (written != subpgsize) { - pr_err(" write size: %#x\n", subpgsize); - pr_err(" written: %#zx\n", written); + printk(PRINT_PREF " write size: %#x\n", subpgsize); + printk(PRINT_PREF " written: %#zx\n", written); } return err ? err : -1; } @@ -136,11 +136,11 @@ static int write_eraseblock(int ebnum) set_random_data(writebuf, subpgsize); err = mtd_write(mtd, addr, subpgsize, &written, writebuf); if (unlikely(err || written != subpgsize)) { - pr_err("error: write failed at %#llx\n", + printk(PRINT_PREF "error: write failed at %#llx\n", (long long)addr); if (written != subpgsize) { - pr_err(" write size: %#x\n", subpgsize); - pr_err(" written: %#zx\n", written); + printk(PRINT_PREF " write size: %#x\n", subpgsize); + printk(PRINT_PREF " written: %#zx\n", written); } return err ? err : -1; } @@ -160,12 +160,12 @@ static int write_eraseblock2(int ebnum) set_random_data(writebuf, subpgsize * k); err = mtd_write(mtd, addr, subpgsize * k, &written, writebuf); if (unlikely(err || written != subpgsize * k)) { - pr_err("error: write failed at %#llx\n", + printk(PRINT_PREF "error: write failed at %#llx\n", (long long)addr); if (written != subpgsize) { - pr_err(" write size: %#x\n", + printk(PRINT_PREF " write size: %#x\n", subpgsize * k); - pr_err(" written: %#08zx\n", + printk(PRINT_PREF " written: %#08zx\n", written); } return err ? err : -1; @@ -198,23 +198,23 @@ static int verify_eraseblock(int ebnum) err = mtd_read(mtd, addr, subpgsize, &read, readbuf); if (unlikely(err || read != subpgsize)) { if (mtd_is_bitflip(err) && read == subpgsize) { - pr_info("ECC correction at %#llx\n", + printk(PRINT_PREF "ECC correction at %#llx\n", (long long)addr); err = 0; } else { - pr_err("error: read failed at %#llx\n", + printk(PRINT_PREF "error: read failed at %#llx\n", (long long)addr); return err ? err : -1; } } if (unlikely(memcmp(readbuf, writebuf, subpgsize))) { - pr_err("error: verify failed at %#llx\n", + printk(PRINT_PREF "error: verify failed at %#llx\n", (long long)addr); - pr_info("------------- written----------------\n"); + printk(PRINT_PREF "------------- written----------------\n"); print_subpage(writebuf); - pr_info("------------- read ------------------\n"); + printk(PRINT_PREF "------------- read ------------------\n"); print_subpage(readbuf); - pr_info("-------------------------------------\n"); + printk(PRINT_PREF "-------------------------------------\n"); errcnt += 1; } @@ -225,23 +225,23 @@ static int verify_eraseblock(int ebnum) err = mtd_read(mtd, addr, subpgsize, &read, readbuf); if (unlikely(err || read != subpgsize)) { if (mtd_is_bitflip(err) && read == subpgsize) { - pr_info("ECC correction at %#llx\n", + printk(PRINT_PREF "ECC correction at %#llx\n", (long long)addr); err = 0; } else { - pr_err("error: read failed at %#llx\n", + printk(PRINT_PREF "error: read failed at %#llx\n", (long long)addr); return err ? err : -1; } } if (unlikely(memcmp(readbuf, writebuf, subpgsize))) { - pr_info("error: verify failed at %#llx\n", + printk(PRINT_PREF "error: verify failed at %#llx\n", (long long)addr); - pr_info("------------- written----------------\n"); + printk(PRINT_PREF "------------- written----------------\n"); print_subpage(writebuf); - pr_info("------------- read ------------------\n"); + printk(PRINT_PREF "------------- read ------------------\n"); print_subpage(readbuf); - pr_info("-------------------------------------\n"); + printk(PRINT_PREF "-------------------------------------\n"); errcnt += 1; } @@ -262,17 +262,17 @@ static int verify_eraseblock2(int ebnum) err = mtd_read(mtd, addr, subpgsize * k, &read, readbuf); if (unlikely(err || read != subpgsize * k)) { if (mtd_is_bitflip(err) && read == subpgsize * k) { - pr_info("ECC correction at %#llx\n", + printk(PRINT_PREF "ECC correction at %#llx\n", (long long)addr); err = 0; } else { - pr_err("error: read failed at " + printk(PRINT_PREF "error: read failed at " "%#llx\n", (long long)addr); return err ? err : -1; } } if (unlikely(memcmp(readbuf, writebuf, subpgsize * k))) { - pr_err("error: verify failed at %#llx\n", + printk(PRINT_PREF "error: verify failed at %#llx\n", (long long)addr); errcnt += 1; } @@ -295,17 +295,17 @@ static int verify_eraseblock_ff(int ebnum) err = mtd_read(mtd, addr, subpgsize, &read, readbuf); if (unlikely(err || read != subpgsize)) { if (mtd_is_bitflip(err) && read == subpgsize) { - pr_info("ECC correction at %#llx\n", + printk(PRINT_PREF "ECC correction at %#llx\n", (long long)addr); err = 0; } else { - pr_err("error: read failed at " + printk(PRINT_PREF "error: read failed at " "%#llx\n", (long long)addr); return err ? err : -1; } } if (unlikely(memcmp(readbuf, writebuf, subpgsize))) { - pr_err("error: verify 0xff failed at " + printk(PRINT_PREF "error: verify 0xff failed at " "%#llx\n", (long long)addr); errcnt += 1; } @@ -320,7 +320,7 @@ static int verify_all_eraseblocks_ff(void) int err; unsigned int i; - pr_info("verifying all eraseblocks for 0xff\n"); + printk(PRINT_PREF "verifying all eraseblocks for 0xff\n"); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; @@ -328,10 +328,10 @@ static int verify_all_eraseblocks_ff(void) if (err) return err; if (i % 256 == 0) - pr_info("verified up to eraseblock %u\n", i); + printk(PRINT_PREF "verified up to eraseblock %u\n", i); cond_resched(); } - pr_info("verified %u eraseblocks\n", i); + printk(PRINT_PREF "verified %u eraseblocks\n", i); return 0; } @@ -342,7 +342,7 @@ static int is_block_bad(int ebnum) ret = mtd_block_isbad(mtd, addr); if (ret) - pr_info("block %d is bad\n", ebnum); + printk(PRINT_PREF "block %d is bad\n", ebnum); return ret; } @@ -352,18 +352,18 @@ static int scan_for_bad_eraseblocks(void) bbt = kzalloc(ebcnt, GFP_KERNEL); if (!bbt) { - pr_err("error: cannot allocate memory\n"); + printk(PRINT_PREF "error: cannot allocate memory\n"); return -ENOMEM; } - pr_info("scanning for bad eraseblocks\n"); + printk(PRINT_PREF "scanning for bad eraseblocks\n"); for (i = 0; i < ebcnt; ++i) { bbt[i] = is_block_bad(i) ? 1 : 0; if (bbt[i]) bad += 1; cond_resched(); } - pr_info("scanned %d eraseblocks, %d are bad\n", i, bad); + printk(PRINT_PREF "scanned %d eraseblocks, %d are bad\n", i, bad); return 0; } @@ -377,22 +377,22 @@ static int __init mtd_subpagetest_init(void) printk(KERN_INFO "=================================================\n"); if (dev < 0) { - pr_info("Please specify a valid mtd-device via module parameter\n"); - pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); + printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n"); + printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n"); return -EINVAL; } - pr_info("MTD device: %d\n", dev); + printk(PRINT_PREF "MTD device: %d\n", dev); mtd = get_mtd_device(NULL, dev); if (IS_ERR(mtd)) { err = PTR_ERR(mtd); - pr_err("error: cannot get MTD device\n"); + printk(PRINT_PREF "error: cannot get MTD device\n"); return err; } if (mtd->type != MTD_NANDFLASH) { - pr_info("this test requires NAND flash\n"); + printk(PRINT_PREF "this test requires NAND flash\n"); goto out; } @@ -402,7 +402,7 @@ static int __init mtd_subpagetest_init(void) ebcnt = tmp; pgcnt = mtd->erasesize / mtd->writesize; - pr_info("MTD device size %llu, eraseblock size %u, " + printk(PRINT_PREF "MTD device size %llu, eraseblock size %u, " "page size %u, subpage size %u, count of eraseblocks %u, " "pages per eraseblock %u, OOB size %u\n", (unsigned long long)mtd->size, mtd->erasesize, @@ -412,12 +412,12 @@ static int __init mtd_subpagetest_init(void) bufsize = subpgsize * 32; writebuf = kmalloc(bufsize, GFP_KERNEL); if (!writebuf) { - pr_info("error: cannot allocate memory\n"); + printk(PRINT_PREF "error: cannot allocate memory\n"); goto out; } readbuf = kmalloc(bufsize, GFP_KERNEL); if (!readbuf) { - pr_info("error: cannot allocate memory\n"); + printk(PRINT_PREF "error: cannot allocate memory\n"); goto out; } @@ -429,7 +429,7 @@ static int __init mtd_subpagetest_init(void) if (err) goto out; - pr_info("writing whole device\n"); + printk(PRINT_PREF "writing whole device\n"); simple_srand(1); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) @@ -438,13 +438,13 @@ static int __init mtd_subpagetest_init(void) if (unlikely(err)) goto out; if (i % 256 == 0) - pr_info("written up to eraseblock %u\n", i); + printk(PRINT_PREF "written up to eraseblock %u\n", i); cond_resched(); } - pr_info("written %u eraseblocks\n", i); + printk(PRINT_PREF "written %u eraseblocks\n", i); simple_srand(1); - pr_info("verifying all eraseblocks\n"); + printk(PRINT_PREF "verifying all eraseblocks\n"); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; @@ -452,10 +452,10 @@ static int __init mtd_subpagetest_init(void) if (unlikely(err)) goto out; if (i % 256 == 0) - pr_info("verified up to eraseblock %u\n", i); + printk(PRINT_PREF "verified up to eraseblock %u\n", i); cond_resched(); } - pr_info("verified %u eraseblocks\n", i); + printk(PRINT_PREF "verified %u eraseblocks\n", i); err = erase_whole_device(); if (err) @@ -467,7 +467,7 @@ static int __init mtd_subpagetest_init(void) /* Write all eraseblocks */ simple_srand(3); - pr_info("writing whole device\n"); + printk(PRINT_PREF "writing whole device\n"); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; @@ -475,14 +475,14 @@ static int __init mtd_subpagetest_init(void) if (unlikely(err)) goto out; if (i % 256 == 0) - pr_info("written up to eraseblock %u\n", i); + printk(PRINT_PREF "written up to eraseblock %u\n", i); cond_resched(); } - pr_info("written %u eraseblocks\n", i); + printk(PRINT_PREF "written %u eraseblocks\n", i); /* Check all eraseblocks */ simple_srand(3); - pr_info("verifying all eraseblocks\n"); + printk(PRINT_PREF "verifying all eraseblocks\n"); for (i = 0; i < ebcnt; ++i) { if (bbt[i]) continue; @@ -490,10 +490,10 @@ static int __init mtd_subpagetest_init(void) if (unlikely(err)) goto out; if (i % 256 == 0) - pr_info("verified up to eraseblock %u\n", i); + printk(PRINT_PREF "verified up to eraseblock %u\n", i); cond_resched(); } - pr_info("verified %u eraseblocks\n", i); + printk(PRINT_PREF "verified %u eraseblocks\n", i); err = erase_whole_device(); if (err) @@ -503,7 +503,7 @@ static int __init mtd_subpagetest_init(void) if (err) goto out; - pr_info("finished with %d errors\n", errcnt); + printk(PRINT_PREF "finished with %d errors\n", errcnt); out: kfree(bbt); @@ -511,7 +511,7 @@ static int __init mtd_subpagetest_init(void) kfree(writebuf); put_mtd_device(mtd); if (err) - pr_info("error %d occurred\n", err); + printk(PRINT_PREF "error %d occurred\n", err); printk(KERN_INFO "=================================================\n"); return err; } diff --git a/trunk/drivers/mtd/tests/mtd_torturetest.c b/trunk/drivers/mtd/tests/mtd_torturetest.c index c4cde1e9eddb..b65861bc7b8e 100644 --- a/trunk/drivers/mtd/tests/mtd_torturetest.c +++ b/trunk/drivers/mtd/tests/mtd_torturetest.c @@ -23,8 +23,6 @@ * damage caused by this program. */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include #include #include @@ -33,6 +31,7 @@ #include #include +#define PRINT_PREF KERN_INFO "mtd_torturetest: " #define RETRIES 3 static int eb = 8; @@ -108,12 +107,12 @@ static inline int erase_eraseblock(int ebnum) err = mtd_erase(mtd, &ei); if (err) { - pr_err("error %d while erasing EB %d\n", err, ebnum); + printk(PRINT_PREF "error %d while erasing EB %d\n", err, ebnum); return err; } if (ei.state == MTD_ERASE_FAILED) { - pr_err("some erase error occurred at EB %d\n", + printk(PRINT_PREF "some erase error occurred at EB %d\n", ebnum); return -EIO; } @@ -140,40 +139,40 @@ static inline int check_eraseblock(int ebnum, unsigned char *buf) retry: err = mtd_read(mtd, addr, len, &read, check_buf); if (mtd_is_bitflip(err)) - pr_err("single bit flip occurred at EB %d " + printk(PRINT_PREF "single bit flip occurred at EB %d " "MTD reported that it was fixed.\n", ebnum); else if (err) { - pr_err("error %d while reading EB %d, " + printk(PRINT_PREF "error %d while reading EB %d, " "read %zd\n", err, ebnum, read); return err; } if (read != len) { - pr_err("failed to read %zd bytes from EB %d, " + printk(PRINT_PREF "failed to read %zd bytes from EB %d, " "read only %zd, but no error reported\n", len, ebnum, read); return -EIO; } if (memcmp(buf, check_buf, len)) { - pr_err("read wrong data from EB %d\n", ebnum); + printk(PRINT_PREF "read wrong data from EB %d\n", ebnum); report_corrupt(check_buf, buf); if (retries++ < RETRIES) { /* Try read again */ yield(); - pr_info("re-try reading data from EB %d\n", + printk(PRINT_PREF "re-try reading data from EB %d\n", ebnum); goto retry; } else { - pr_info("retried %d times, still errors, " + printk(PRINT_PREF "retried %d times, still errors, " "give-up\n", RETRIES); return -EINVAL; } } if (retries != 0) - pr_info("only attempt number %d was OK (!!!)\n", + printk(PRINT_PREF "only attempt number %d was OK (!!!)\n", retries); return 0; @@ -192,12 +191,12 @@ static inline int write_pattern(int ebnum, void *buf) } err = mtd_write(mtd, addr, len, &written, buf); if (err) { - pr_err("error %d while writing EB %d, written %zd" + printk(PRINT_PREF "error %d while writing EB %d, written %zd" " bytes\n", err, ebnum, written); return err; } if (written != len) { - pr_info("written only %zd bytes of %zd, but no error" + printk(PRINT_PREF "written only %zd bytes of %zd, but no error" " reported\n", written, len); return -EIO; } @@ -212,64 +211,64 @@ static int __init tort_init(void) printk(KERN_INFO "\n"); printk(KERN_INFO "=================================================\n"); - pr_info("Warning: this program is trying to wear out your " + printk(PRINT_PREF "Warning: this program is trying to wear out your " "flash, stop it if this is not wanted.\n"); if (dev < 0) { - pr_info("Please specify a valid mtd-device via module parameter\n"); - pr_crit("CAREFUL: This test wipes all data on the specified MTD device!\n"); + printk(PRINT_PREF "Please specify a valid mtd-device via module paramter\n"); + printk(KERN_CRIT "CAREFUL: This test wipes all data on the specified MTD device!\n"); return -EINVAL; } - pr_info("MTD device: %d\n", dev); - pr_info("torture %d eraseblocks (%d-%d) of mtd%d\n", + printk(PRINT_PREF "MTD device: %d\n", dev); + printk(PRINT_PREF "torture %d eraseblocks (%d-%d) of mtd%d\n", ebcnt, eb, eb + ebcnt - 1, dev); if (pgcnt) - pr_info("torturing just %d pages per eraseblock\n", + printk(PRINT_PREF "torturing just %d pages per eraseblock\n", pgcnt); - pr_info("write verify %s\n", check ? "enabled" : "disabled"); + printk(PRINT_PREF "write verify %s\n", check ? "enabled" : "disabled"); mtd = get_mtd_device(NULL, dev); if (IS_ERR(mtd)) { err = PTR_ERR(mtd); - pr_err("error: cannot get MTD device\n"); + printk(PRINT_PREF "error: cannot get MTD device\n"); return err; } if (mtd->writesize == 1) { - pr_info("not NAND flash, assume page size is 512 " + printk(PRINT_PREF "not NAND flash, assume page size is 512 " "bytes.\n"); pgsize = 512; } else pgsize = mtd->writesize; if (pgcnt && (pgcnt > mtd->erasesize / pgsize || pgcnt < 0)) { - pr_err("error: invalid pgcnt value %d\n", pgcnt); + printk(PRINT_PREF "error: invalid pgcnt value %d\n", pgcnt); goto out_mtd; } err = -ENOMEM; patt_5A5 = kmalloc(mtd->erasesize, GFP_KERNEL); if (!patt_5A5) { - pr_err("error: cannot allocate memory\n"); + printk(PRINT_PREF "error: cannot allocate memory\n"); goto out_mtd; } patt_A5A = kmalloc(mtd->erasesize, GFP_KERNEL); if (!patt_A5A) { - pr_err("error: cannot allocate memory\n"); + printk(PRINT_PREF "error: cannot allocate memory\n"); goto out_patt_5A5; } patt_FF = kmalloc(mtd->erasesize, GFP_KERNEL); if (!patt_FF) { - pr_err("error: cannot allocate memory\n"); + printk(PRINT_PREF "error: cannot allocate memory\n"); goto out_patt_A5A; } check_buf = kmalloc(mtd->erasesize, GFP_KERNEL); if (!check_buf) { - pr_err("error: cannot allocate memory\n"); + printk(PRINT_PREF "error: cannot allocate memory\n"); goto out_patt_FF; } @@ -296,13 +295,13 @@ static int __init tort_init(void) err = mtd_block_isbad(mtd, (loff_t)i * mtd->erasesize); if (err < 0) { - pr_info("block_isbad() returned %d " + printk(PRINT_PREF "block_isbad() returned %d " "for EB %d\n", err, i); goto out; } if (err) { - pr_err("EB %d is bad. Skip it.\n", i); + printk("EB %d is bad. Skip it.\n", i); bad_ebs[i - eb] = 1; } } @@ -330,7 +329,7 @@ static int __init tort_init(void) continue; err = check_eraseblock(i, patt_FF); if (err) { - pr_info("verify failed" + printk(PRINT_PREF "verify failed" " for 0xFF... pattern\n"); goto out; } @@ -363,7 +362,7 @@ static int __init tort_init(void) patt = patt_A5A; err = check_eraseblock(i, patt); if (err) { - pr_info("verify failed for %s" + printk(PRINT_PREF "verify failed for %s" " pattern\n", ((eb + erase_cycles) & 1) ? "0x55AA55..." : "0xAA55AA..."); @@ -381,7 +380,7 @@ static int __init tort_init(void) stop_timing(); ms = (finish.tv_sec - start.tv_sec) * 1000 + (finish.tv_usec - start.tv_usec) / 1000; - pr_info("%08u erase cycles done, took %lu " + printk(PRINT_PREF "%08u erase cycles done, took %lu " "milliseconds (%lu seconds)\n", erase_cycles, ms, ms / 1000); start_timing(); @@ -392,7 +391,7 @@ static int __init tort_init(void) } out: - pr_info("finished after %u erase cycles\n", + printk(PRINT_PREF "finished after %u erase cycles\n", erase_cycles); kfree(check_buf); out_patt_FF: @@ -404,7 +403,7 @@ static int __init tort_init(void) out_mtd: put_mtd_device(mtd); if (err) - pr_info("error %d occurred during torturing\n", err); + printk(PRINT_PREF "error %d occurred during torturing\n", err); printk(KERN_INFO "=================================================\n"); return err; } @@ -442,9 +441,9 @@ static void report_corrupt(unsigned char *read, unsigned char *written) &bits) >= 0) pages++; - pr_info("verify fails on %d pages, %d bytes/%d bits\n", + printk(PRINT_PREF "verify fails on %d pages, %d bytes/%d bits\n", pages, bytes, bits); - pr_info("The following is a list of all differences between" + printk(PRINT_PREF "The following is a list of all differences between" " what was read from flash and what was expected\n"); for (i = 0; i < check_len; i += pgsize) { @@ -458,7 +457,7 @@ static void report_corrupt(unsigned char *read, unsigned char *written) printk("-------------------------------------------------------" "----------------------------------\n"); - pr_info("Page %zd has %d bytes/%d bits failing verify," + printk(PRINT_PREF "Page %zd has %d bytes/%d bits failing verify," " starting at offset 0x%x\n", (mtd->erasesize - check_len + i) / pgsize, bytes, bits, first); diff --git a/trunk/drivers/of/base.c b/trunk/drivers/of/base.c index db8d211a0d05..2390ddb22d60 100644 --- a/trunk/drivers/of/base.c +++ b/trunk/drivers/of/base.c @@ -629,7 +629,7 @@ struct device_node *of_find_matching_node_and_match(struct device_node *from, read_unlock(&devtree_lock); return np; } -EXPORT_SYMBOL(of_find_matching_node); +EXPORT_SYMBOL(of_find_matching_node_and_match); /** * of_modalias_node - Lookup appropriate modalias for a device node diff --git a/trunk/drivers/power/charger-manager.c b/trunk/drivers/power/charger-manager.c index 6ba047f5ac2c..adb3a4b59cb3 100644 --- a/trunk/drivers/power/charger-manager.c +++ b/trunk/drivers/power/charger-manager.c @@ -239,37 +239,44 @@ static bool is_full_charged(struct charger_manager *cm) int uV; /* If there is no battery, it cannot be charged */ - if (!is_batt_present(cm)) - return false; - - if (cm->fuel_gauge && desc->fullbatt_full_capacity > 0) { + if (!is_batt_present(cm)) { val.intval = 0; + goto out; + } + if (cm->fuel_gauge && desc->fullbatt_full_capacity > 0) { /* Not full if capacity of fuel gauge isn't full */ ret = cm->fuel_gauge->get_property(cm->fuel_gauge, POWER_SUPPLY_PROP_CHARGE_FULL, &val); - if (!ret && val.intval > desc->fullbatt_full_capacity) - return true; + if (!ret && val.intval > desc->fullbatt_full_capacity) { + val.intval = 1; + goto out; + } } /* Full, if it's over the fullbatt voltage */ if (desc->fullbatt_uV > 0) { ret = get_batt_uV(cm, &uV); - if (!ret && uV >= desc->fullbatt_uV) - return true; + if (!ret && uV >= desc->fullbatt_uV) { + val.intval = 1; + goto out; + } } /* Full, if the capacity is more than fullbatt_soc */ if (cm->fuel_gauge && desc->fullbatt_soc > 0) { - val.intval = 0; - ret = cm->fuel_gauge->get_property(cm->fuel_gauge, POWER_SUPPLY_PROP_CAPACITY, &val); - if (!ret && val.intval >= desc->fullbatt_soc) - return true; + if (!ret && val.intval >= desc->fullbatt_soc) { + val.intval = 1; + goto out; + } } - return false; + val.intval = 0; + +out: + return val.intval ? true : false; } /** @@ -482,9 +489,8 @@ static void fullbatt_vchk(struct work_struct *work) return; } - diff = desc->fullbatt_uV - batt_uV; - if (diff < 0) - return; + diff = desc->fullbatt_uV; + diff -= batt_uV; dev_info(cm->dev, "VBATT dropped %duV after full-batt.\n", diff); diff --git a/trunk/drivers/pwm/Kconfig b/trunk/drivers/pwm/Kconfig index e513cd998170..ed81720e7b2b 100644 --- a/trunk/drivers/pwm/Kconfig +++ b/trunk/drivers/pwm/Kconfig @@ -112,17 +112,6 @@ config PWM_SAMSUNG To compile this driver as a module, choose M here: the module will be called pwm-samsung. -config PWM_SPEAR - tristate "STMicroelectronics SPEAr PWM support" - depends on PLAT_SPEAR - depends on OF - help - Generic PWM framework driver for the PWM controller on ST - SPEAr SoCs. - - To compile this driver as a module, choose M here: the module - will be called pwm-spear. - config PWM_TEGRA tristate "NVIDIA Tegra PWM support" depends on ARCH_TEGRA @@ -136,7 +125,6 @@ config PWM_TEGRA config PWM_TIECAP tristate "ECAP PWM support" depends on SOC_AM33XX - select PWM_TIPWMSS help PWM driver support for the ECAP APWM controller found on AM33XX TI SOC @@ -147,7 +135,6 @@ config PWM_TIECAP config PWM_TIEHRPWM tristate "EHRPWM PWM support" depends on SOC_AM33XX - select PWM_TIPWMSS help PWM driver support for the EHRPWM controller found on AM33XX TI SOC @@ -155,32 +142,14 @@ config PWM_TIEHRPWM To compile this driver as a module, choose M here: the module will be called pwm-tiehrpwm. -config PWM_TIPWMSS - bool - depends on SOC_AM33XX && (PWM_TIEHRPWM || PWM_TIECAP) - help - PWM Subsystem driver support for AM33xx SOC. - - PWM submodules require PWM config space access from submodule - drivers and require common parent driver support. - -config PWM_TWL - tristate "TWL4030/6030 PWM support" - depends on TWL4030_CORE - help - Generic PWM framework driver for TWL4030/6030. - - To compile this driver as a module, choose M here: the module - will be called pwm-twl. - -config PWM_TWL_LED - tristate "TWL4030/6030 PWM support for LED drivers" +config PWM_TWL6030 + tristate "TWL6030 PWM support" depends on TWL4030_CORE help - Generic PWM framework driver for TWL4030/6030 LED terminals. + Generic PWM framework driver for TWL6030. To compile this driver as a module, choose M here: the module - will be called pwm-twl-led. + will be called pwm-twl6030. config PWM_VT8500 tristate "vt8500 pwm support" diff --git a/trunk/drivers/pwm/Makefile b/trunk/drivers/pwm/Makefile index 62a2963cfe58..acfe4821c58b 100644 --- a/trunk/drivers/pwm/Makefile +++ b/trunk/drivers/pwm/Makefile @@ -8,11 +8,8 @@ obj-$(CONFIG_PWM_MXS) += pwm-mxs.o obj-$(CONFIG_PWM_PUV3) += pwm-puv3.o obj-$(CONFIG_PWM_PXA) += pwm-pxa.o obj-$(CONFIG_PWM_SAMSUNG) += pwm-samsung.o -obj-$(CONFIG_PWM_SPEAR) += pwm-spear.o obj-$(CONFIG_PWM_TEGRA) += pwm-tegra.o obj-$(CONFIG_PWM_TIECAP) += pwm-tiecap.o obj-$(CONFIG_PWM_TIEHRPWM) += pwm-tiehrpwm.o -obj-$(CONFIG_PWM_TIPWMSS) += pwm-tipwmss.o -obj-$(CONFIG_PWM_TWL) += pwm-twl.o -obj-$(CONFIG_PWM_TWL_LED) += pwm-twl-led.o +obj-$(CONFIG_PWM_TWL6030) += pwm-twl6030.o obj-$(CONFIG_PWM_VT8500) += pwm-vt8500.o diff --git a/trunk/drivers/pwm/core.c b/trunk/drivers/pwm/core.c index 903138b18842..f5acdaa52707 100644 --- a/trunk/drivers/pwm/core.c +++ b/trunk/drivers/pwm/core.c @@ -32,9 +32,6 @@ #define MAX_PWMS 1024 -/* flags in the third cell of the DT PWM specifier */ -#define PWM_SPEC_POLARITY (1 << 0) - static DEFINE_MUTEX(pwm_lookup_lock); static LIST_HEAD(pwm_lookup_list); static DEFINE_MUTEX(pwm_lock); @@ -132,32 +129,6 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label) return 0; } -struct pwm_device * -of_pwm_xlate_with_flags(struct pwm_chip *pc, const struct of_phandle_args *args) -{ - struct pwm_device *pwm; - - if (pc->of_pwm_n_cells < 3) - return ERR_PTR(-EINVAL); - - if (args->args[0] >= pc->npwm) - return ERR_PTR(-EINVAL); - - pwm = pwm_request_from_chip(pc, args->args[0], NULL); - if (IS_ERR(pwm)) - return pwm; - - pwm_set_period(pwm, args->args[1]); - - if (args->args[2] & PWM_SPEC_POLARITY) - pwm_set_polarity(pwm, PWM_POLARITY_INVERSED); - else - pwm_set_polarity(pwm, PWM_POLARITY_NORMAL); - - return pwm; -} -EXPORT_SYMBOL_GPL(of_pwm_xlate_with_flags); - static struct pwm_device * of_pwm_simple_xlate(struct pwm_chip *pc, const struct of_phandle_args *args) { diff --git a/trunk/drivers/pwm/pwm-imx.c b/trunk/drivers/pwm/pwm-imx.c index 65a86bdeabed..8f26e9fcea97 100644 --- a/trunk/drivers/pwm/pwm-imx.c +++ b/trunk/drivers/pwm/pwm-imx.c @@ -235,7 +235,7 @@ static int imx_pwm_probe(struct platform_device *pdev) { const struct of_device_id *of_id = of_match_device(imx_pwm_dt_ids, &pdev->dev); - const struct imx_pwm_data *data; + struct imx_pwm_data *data; struct imx_chip *imx; struct resource *r; int ret = 0; diff --git a/trunk/drivers/pwm/pwm-lpc32xx.c b/trunk/drivers/pwm/pwm-lpc32xx.c index 14106440294f..015a82235620 100644 --- a/trunk/drivers/pwm/pwm-lpc32xx.c +++ b/trunk/drivers/pwm/pwm-lpc32xx.c @@ -49,24 +49,9 @@ static int lpc32xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, c = 0; /* 0 set division by 256 */ period_cycles = c; - /* The duty-cycle value is as follows: - * - * DUTY-CYCLE HIGH LEVEL - * 1 99.9% - * 25 90.0% - * 128 50.0% - * 220 10.0% - * 255 0.1% - * 0 0.0% - * - * In other words, the register value is duty-cycle % 256 with - * duty-cycle in the range 1-256. - */ c = 256 * duty_ns; do_div(c, period_ns); - if (c > 255) - c = 255; - duty_cycles = 256 - c; + duty_cycles = c; writel(PWM_ENABLE | PWM_RELOADV(period_cycles) | PWM_DUTY(duty_cycles), lpc32xx->base + (pwm->hwpwm << 2)); @@ -121,7 +106,6 @@ static int lpc32xx_pwm_probe(struct platform_device *pdev) lpc32xx->chip.dev = &pdev->dev; lpc32xx->chip.ops = &lpc32xx_pwm_ops; lpc32xx->chip.npwm = 2; - lpc32xx->chip.base = -1; ret = pwmchip_add(&lpc32xx->chip); if (ret < 0) { @@ -137,11 +121,8 @@ static int lpc32xx_pwm_probe(struct platform_device *pdev) static int lpc32xx_pwm_remove(struct platform_device *pdev) { struct lpc32xx_pwm_chip *lpc32xx = platform_get_drvdata(pdev); - unsigned int i; - - for (i = 0; i < lpc32xx->chip.npwm; i++) - pwm_disable(&lpc32xx->chip.pwms[i]); + clk_disable(lpc32xx->clk); return pwmchip_remove(&lpc32xx->chip); } diff --git a/trunk/drivers/pwm/pwm-samsung.c b/trunk/drivers/pwm/pwm-samsung.c index 5207e6cd8648..e9b15d099c03 100644 --- a/trunk/drivers/pwm/pwm-samsung.c +++ b/trunk/drivers/pwm/pwm-samsung.c @@ -222,7 +222,6 @@ static int s3c_pwm_probe(struct platform_device *pdev) /* calculate base of control bits in TCON */ s3c->tcon_base = id == 0 ? 0 : (id * 4) + 4; - s3c->pwm_id = id; s3c->chip.dev = &pdev->dev; s3c->chip.ops = &s3c_pwm_ops; s3c->chip.base = -1; diff --git a/trunk/drivers/pwm/pwm-spear.c b/trunk/drivers/pwm/pwm-spear.c deleted file mode 100644 index 83b21d9d5cf9..000000000000 --- a/trunk/drivers/pwm/pwm-spear.c +++ /dev/null @@ -1,276 +0,0 @@ -/* - * ST Microelectronics SPEAr Pulse Width Modulator driver - * - * Copyright (C) 2012 ST Microelectronics - * Shiraz Hashim - * - * This file is licensed under the terms of the GNU General Public - * License version 2. This program is licensed "as is" without any - * warranty of any kind, whether express or implied. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define NUM_PWM 4 - -/* PWM registers and bits definitions */ -#define PWMCR 0x00 /* Control Register */ -#define PWMCR_PWM_ENABLE 0x1 -#define PWMCR_PRESCALE_SHIFT 2 -#define PWMCR_MIN_PRESCALE 0x00 -#define PWMCR_MAX_PRESCALE 0x3FFF - -#define PWMDCR 0x04 /* Duty Cycle Register */ -#define PWMDCR_MIN_DUTY 0x0001 -#define PWMDCR_MAX_DUTY 0xFFFF - -#define PWMPCR 0x08 /* Period Register */ -#define PWMPCR_MIN_PERIOD 0x0001 -#define PWMPCR_MAX_PERIOD 0xFFFF - -/* Following only available on 13xx SoCs */ -#define PWMMCR 0x3C /* Master Control Register */ -#define PWMMCR_PWM_ENABLE 0x1 - -/** - * struct spear_pwm_chip - struct representing pwm chip - * - * @mmio_base: base address of pwm chip - * @clk: pointer to clk structure of pwm chip - * @chip: linux pwm chip representation - * @dev: pointer to device structure of pwm chip - */ -struct spear_pwm_chip { - void __iomem *mmio_base; - struct clk *clk; - struct pwm_chip chip; - struct device *dev; -}; - -static inline struct spear_pwm_chip *to_spear_pwm_chip(struct pwm_chip *chip) -{ - return container_of(chip, struct spear_pwm_chip, chip); -} - -static inline u32 spear_pwm_readl(struct spear_pwm_chip *chip, unsigned int num, - unsigned long offset) -{ - return readl_relaxed(chip->mmio_base + (num << 4) + offset); -} - -static inline void spear_pwm_writel(struct spear_pwm_chip *chip, - unsigned int num, unsigned long offset, - unsigned long val) -{ - writel_relaxed(val, chip->mmio_base + (num << 4) + offset); -} - -static int spear_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, - int duty_ns, int period_ns) -{ - struct spear_pwm_chip *pc = to_spear_pwm_chip(chip); - u64 val, div, clk_rate; - unsigned long prescale = PWMCR_MIN_PRESCALE, pv, dc; - int ret; - - /* - * Find pv, dc and prescale to suit duty_ns and period_ns. This is done - * according to formulas described below: - * - * period_ns = 10^9 * (PRESCALE + 1) * PV / PWM_CLK_RATE - * duty_ns = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE - * - * PV = (PWM_CLK_RATE * period_ns) / (10^9 * (PRESCALE + 1)) - * DC = (PWM_CLK_RATE * duty_ns) / (10^9 * (PRESCALE + 1)) - */ - clk_rate = clk_get_rate(pc->clk); - while (1) { - div = 1000000000; - div *= 1 + prescale; - val = clk_rate * period_ns; - pv = div64_u64(val, div); - val = clk_rate * duty_ns; - dc = div64_u64(val, div); - - /* if duty_ns and period_ns are not achievable then return */ - if (pv < PWMPCR_MIN_PERIOD || dc < PWMDCR_MIN_DUTY) - return -EINVAL; - - /* - * if pv and dc have crossed their upper limit, then increase - * prescale and recalculate pv and dc. - */ - if (pv > PWMPCR_MAX_PERIOD || dc > PWMDCR_MAX_DUTY) { - if (++prescale > PWMCR_MAX_PRESCALE) - return -EINVAL; - continue; - } - break; - } - - /* - * NOTE: the clock to PWM has to be enabled first before writing to the - * registers. - */ - ret = clk_enable(pc->clk); - if (ret) - return ret; - - spear_pwm_writel(pc, pwm->hwpwm, PWMCR, - prescale << PWMCR_PRESCALE_SHIFT); - spear_pwm_writel(pc, pwm->hwpwm, PWMDCR, dc); - spear_pwm_writel(pc, pwm->hwpwm, PWMPCR, pv); - clk_disable(pc->clk); - - return 0; -} - -static int spear_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) -{ - struct spear_pwm_chip *pc = to_spear_pwm_chip(chip); - int rc = 0; - u32 val; - - rc = clk_enable(pc->clk); - if (!rc) - return rc; - - val = spear_pwm_readl(pc, pwm->hwpwm, PWMCR); - val |= PWMCR_PWM_ENABLE; - spear_pwm_writel(pc, pwm->hwpwm, PWMCR, val); - - return 0; -} - -static void spear_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) -{ - struct spear_pwm_chip *pc = to_spear_pwm_chip(chip); - u32 val; - - val = spear_pwm_readl(pc, pwm->hwpwm, PWMCR); - val &= ~PWMCR_PWM_ENABLE; - spear_pwm_writel(pc, pwm->hwpwm, PWMCR, val); - - clk_disable(pc->clk); -} - -static const struct pwm_ops spear_pwm_ops = { - .config = spear_pwm_config, - .enable = spear_pwm_enable, - .disable = spear_pwm_disable, - .owner = THIS_MODULE, -}; - -static int spear_pwm_probe(struct platform_device *pdev) -{ - struct device_node *np = pdev->dev.of_node; - struct spear_pwm_chip *pc; - struct resource *r; - int ret; - u32 val; - - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!r) { - dev_err(&pdev->dev, "no memory resources defined\n"); - return -ENODEV; - } - - pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); - if (!pc) { - dev_err(&pdev->dev, "failed to allocate memory\n"); - return -ENOMEM; - } - - pc->mmio_base = devm_request_and_ioremap(&pdev->dev, r); - if (!pc->mmio_base) - return -EADDRNOTAVAIL; - - pc->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(pc->clk)) - return PTR_ERR(pc->clk); - - pc->dev = &pdev->dev; - platform_set_drvdata(pdev, pc); - - pc->chip.dev = &pdev->dev; - pc->chip.ops = &spear_pwm_ops; - pc->chip.base = -1; - pc->chip.npwm = NUM_PWM; - - ret = clk_prepare(pc->clk); - if (!ret) - return ret; - - if (of_device_is_compatible(np, "st,spear1340-pwm")) { - ret = clk_enable(pc->clk); - if (!ret) { - clk_unprepare(pc->clk); - return ret; - } - /* - * Following enables PWM chip, channels would still be - * enabled individually through their control register - */ - val = readl_relaxed(pc->mmio_base + PWMMCR); - val |= PWMMCR_PWM_ENABLE; - writel_relaxed(val, pc->mmio_base + PWMMCR); - - clk_disable(pc->clk); - } - - ret = pwmchip_add(&pc->chip); - if (!ret) { - clk_unprepare(pc->clk); - dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); - } - - return ret; -} - -static int spear_pwm_remove(struct platform_device *pdev) -{ - struct spear_pwm_chip *pc = platform_get_drvdata(pdev); - int i; - - for (i = 0; i < NUM_PWM; i++) - pwm_disable(&pc->chip.pwms[i]); - - /* clk was prepared in probe, hence unprepare it here */ - clk_unprepare(pc->clk); - return pwmchip_remove(&pc->chip); -} - -static struct of_device_id spear_pwm_of_match[] = { - { .compatible = "st,spear320-pwm" }, - { .compatible = "st,spear1340-pwm" }, - { } -}; - -MODULE_DEVICE_TABLE(of, spear_pwm_of_match); - -static struct platform_driver spear_pwm_driver = { - .driver = { - .name = "spear-pwm", - .of_match_table = spear_pwm_of_match, - }, - .probe = spear_pwm_probe, - .remove = spear_pwm_remove, -}; - -module_platform_driver(spear_pwm_driver); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Shiraz Hashim "); -MODULE_AUTHOR("Viresh Kumar "); -MODULE_ALIAS("platform:spear-pwm"); diff --git a/trunk/drivers/pwm/pwm-tiecap.c b/trunk/drivers/pwm/pwm-tiecap.c index 5cf016dd9822..87c091b245cc 100644 --- a/trunk/drivers/pwm/pwm-tiecap.c +++ b/trunk/drivers/pwm/pwm-tiecap.c @@ -25,10 +25,6 @@ #include #include #include -#include -#include - -#include "pwm-tipwmss.h" /* ECAP registers and bits definitions */ #define CAP1 0x08 @@ -188,24 +184,12 @@ static const struct pwm_ops ecap_pwm_ops = { .owner = THIS_MODULE, }; -static const struct of_device_id ecap_of_match[] = { - { .compatible = "ti,am33xx-ecap" }, - {}, -}; -MODULE_DEVICE_TABLE(of, ecap_of_match); - static int ecap_pwm_probe(struct platform_device *pdev) { int ret; struct resource *r; struct clk *clk; struct ecap_pwm_chip *pc; - u16 status; - struct pinctrl *pinctrl; - - pinctrl = devm_pinctrl_get_select_default(&pdev->dev); - if (IS_ERR(pinctrl)) - dev_warn(&pdev->dev, "unable to select pin group\n"); pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); if (!pc) { @@ -227,8 +211,6 @@ static int ecap_pwm_probe(struct platform_device *pdev) pc->chip.dev = &pdev->dev; pc->chip.ops = &ecap_pwm_ops; - pc->chip.of_xlate = of_pwm_xlate_with_flags; - pc->chip.of_pwm_n_cells = 3; pc->chip.base = -1; pc->chip.npwm = 1; @@ -249,40 +231,14 @@ static int ecap_pwm_probe(struct platform_device *pdev) } pm_runtime_enable(&pdev->dev); - pm_runtime_get_sync(&pdev->dev); - - status = pwmss_submodule_state_change(pdev->dev.parent, - PWMSS_ECAPCLK_EN); - if (!(status & PWMSS_ECAPCLK_EN_ACK)) { - dev_err(&pdev->dev, "PWMSS config space clock enable failed\n"); - ret = -EINVAL; - goto pwmss_clk_failure; - } - - pm_runtime_put_sync(&pdev->dev); - platform_set_drvdata(pdev, pc); return 0; - -pwmss_clk_failure: - pm_runtime_put_sync(&pdev->dev); - pm_runtime_disable(&pdev->dev); - pwmchip_remove(&pc->chip); - return ret; } static int ecap_pwm_remove(struct platform_device *pdev) { struct ecap_pwm_chip *pc = platform_get_drvdata(pdev); - pm_runtime_get_sync(&pdev->dev); - /* - * Due to hardware misbehaviour, acknowledge of the stop_req - * is missing. Hence checking of the status bit skipped. - */ - pwmss_submodule_state_change(pdev->dev.parent, PWMSS_ECAPCLK_STOP_REQ); - pm_runtime_put_sync(&pdev->dev); - pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); return pwmchip_remove(&pc->chip); @@ -290,9 +246,7 @@ static int ecap_pwm_remove(struct platform_device *pdev) static struct platform_driver ecap_pwm_driver = { .driver = { - .name = "ecap", - .owner = THIS_MODULE, - .of_match_table = ecap_of_match, + .name = "ecap", }, .probe = ecap_pwm_probe, .remove = ecap_pwm_remove, diff --git a/trunk/drivers/pwm/pwm-tiehrpwm.c b/trunk/drivers/pwm/pwm-tiehrpwm.c index 72a6dd40c9ec..9ffd389d0c8b 100644 --- a/trunk/drivers/pwm/pwm-tiehrpwm.c +++ b/trunk/drivers/pwm/pwm-tiehrpwm.c @@ -25,10 +25,6 @@ #include #include #include -#include -#include - -#include "pwm-tipwmss.h" /* EHRPWM registers and bits definitions */ @@ -119,7 +115,6 @@ struct ehrpwm_pwm_chip { void __iomem *mmio_base; unsigned long period_cycles[NUM_PWM_CHANNEL]; enum pwm_polarity polarity[NUM_PWM_CHANNEL]; - struct clk *tbclk; }; static inline struct ehrpwm_pwm_chip *to_ehrpwm_pwm_chip(struct pwm_chip *chip) @@ -340,9 +335,6 @@ static int ehrpwm_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) /* Channels polarity can be configured from action qualifier module */ configure_polarity(pc, pwm->hwpwm); - /* Enable TBCLK before enabling PWM device */ - clk_enable(pc->tbclk); - /* Enable time counter for free_run */ ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_RUN_MASK, TBCTL_FREE_RUN); return 0; @@ -371,9 +363,6 @@ static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) ehrpwm_modify(pc->mmio_base, AQCSFRC, aqcsfrc_mask, aqcsfrc_val); - /* Disabling TBCLK on PWM disable */ - clk_disable(pc->tbclk); - /* Stop Time base counter */ ehrpwm_modify(pc->mmio_base, TBCTL, TBCTL_RUN_MASK, TBCTL_STOP_NEXT); @@ -403,24 +392,12 @@ static const struct pwm_ops ehrpwm_pwm_ops = { .owner = THIS_MODULE, }; -static const struct of_device_id ehrpwm_of_match[] = { - { .compatible = "ti,am33xx-ehrpwm" }, - {}, -}; -MODULE_DEVICE_TABLE(of, ehrpwm_of_match); - static int ehrpwm_pwm_probe(struct platform_device *pdev) { int ret; struct resource *r; struct clk *clk; struct ehrpwm_pwm_chip *pc; - u16 status; - struct pinctrl *pinctrl; - - pinctrl = devm_pinctrl_get_select_default(&pdev->dev); - if (IS_ERR(pinctrl)) - dev_warn(&pdev->dev, "unable to select pin group\n"); pc = devm_kzalloc(&pdev->dev, sizeof(*pc), GFP_KERNEL); if (!pc) { @@ -442,8 +419,6 @@ static int ehrpwm_pwm_probe(struct platform_device *pdev) pc->chip.dev = &pdev->dev; pc->chip.ops = &ehrpwm_pwm_ops; - pc->chip.of_xlate = of_pwm_xlate_with_flags; - pc->chip.of_pwm_n_cells = 3; pc->chip.base = -1; pc->chip.npwm = NUM_PWM_CHANNEL; @@ -457,13 +432,6 @@ static int ehrpwm_pwm_probe(struct platform_device *pdev) if (!pc->mmio_base) return -EADDRNOTAVAIL; - /* Acquire tbclk for Time Base EHRPWM submodule */ - pc->tbclk = devm_clk_get(&pdev->dev, "tbclk"); - if (IS_ERR(pc->tbclk)) { - dev_err(&pdev->dev, "Failed to get tbclk\n"); - return PTR_ERR(pc->tbclk); - } - ret = pwmchip_add(&pc->chip); if (ret < 0) { dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); @@ -471,40 +439,14 @@ static int ehrpwm_pwm_probe(struct platform_device *pdev) } pm_runtime_enable(&pdev->dev); - pm_runtime_get_sync(&pdev->dev); - - status = pwmss_submodule_state_change(pdev->dev.parent, - PWMSS_EPWMCLK_EN); - if (!(status & PWMSS_EPWMCLK_EN_ACK)) { - dev_err(&pdev->dev, "PWMSS config space clock enable failed\n"); - ret = -EINVAL; - goto pwmss_clk_failure; - } - - pm_runtime_put_sync(&pdev->dev); - platform_set_drvdata(pdev, pc); return 0; - -pwmss_clk_failure: - pm_runtime_put_sync(&pdev->dev); - pm_runtime_disable(&pdev->dev); - pwmchip_remove(&pc->chip); - return ret; } static int ehrpwm_pwm_remove(struct platform_device *pdev) { struct ehrpwm_pwm_chip *pc = platform_get_drvdata(pdev); - pm_runtime_get_sync(&pdev->dev); - /* - * Due to hardware misbehaviour, acknowledge of the stop_req - * is missing. Hence checking of the status bit skipped. - */ - pwmss_submodule_state_change(pdev->dev.parent, PWMSS_EPWMCLK_STOP_REQ); - pm_runtime_put_sync(&pdev->dev); - pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); return pwmchip_remove(&pc->chip); @@ -512,9 +454,7 @@ static int ehrpwm_pwm_remove(struct platform_device *pdev) static struct platform_driver ehrpwm_pwm_driver = { .driver = { - .name = "ehrpwm", - .owner = THIS_MODULE, - .of_match_table = ehrpwm_of_match, + .name = "ehrpwm", }, .probe = ehrpwm_pwm_probe, .remove = ehrpwm_pwm_remove, diff --git a/trunk/drivers/pwm/pwm-tipwmss.c b/trunk/drivers/pwm/pwm-tipwmss.c deleted file mode 100644 index 3448a1c88590..000000000000 --- a/trunk/drivers/pwm/pwm-tipwmss.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * TI PWM Subsystem driver - * - * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#include -#include -#include -#include -#include -#include - -#include "pwm-tipwmss.h" - -#define PWMSS_CLKCONFIG 0x8 /* Clock gating reg */ -#define PWMSS_CLKSTATUS 0xc /* Clock gating status reg */ - -struct pwmss_info { - void __iomem *mmio_base; - struct mutex pwmss_lock; - u16 pwmss_clkconfig; -}; - -u16 pwmss_submodule_state_change(struct device *dev, int set) -{ - struct pwmss_info *info = dev_get_drvdata(dev); - u16 val; - - mutex_lock(&info->pwmss_lock); - val = readw(info->mmio_base + PWMSS_CLKCONFIG); - val |= set; - writew(val , info->mmio_base + PWMSS_CLKCONFIG); - mutex_unlock(&info->pwmss_lock); - - return readw(info->mmio_base + PWMSS_CLKSTATUS); -} -EXPORT_SYMBOL(pwmss_submodule_state_change); - -static const struct of_device_id pwmss_of_match[] = { - { .compatible = "ti,am33xx-pwmss" }, - {}, -}; -MODULE_DEVICE_TABLE(of, pwmss_of_match); - -static int pwmss_probe(struct platform_device *pdev) -{ - int ret; - struct resource *r; - struct pwmss_info *info; - struct device_node *node = pdev->dev.of_node; - - info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); - if (!info) { - dev_err(&pdev->dev, "failed to allocate memory\n"); - return -ENOMEM; - } - - mutex_init(&info->pwmss_lock); - - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!r) { - dev_err(&pdev->dev, "no memory resource defined\n"); - return -ENODEV; - } - - info->mmio_base = devm_request_and_ioremap(&pdev->dev, r); - if (!info->mmio_base) - return -EADDRNOTAVAIL; - - pm_runtime_enable(&pdev->dev); - pm_runtime_get_sync(&pdev->dev); - platform_set_drvdata(pdev, info); - - /* Populate all the child nodes here... */ - ret = of_platform_populate(node, NULL, NULL, &pdev->dev); - if (ret) - dev_err(&pdev->dev, "no child node found\n"); - - return ret; -} - -static int pwmss_remove(struct platform_device *pdev) -{ - struct pwmss_info *info = platform_get_drvdata(pdev); - - pm_runtime_put_sync(&pdev->dev); - pm_runtime_disable(&pdev->dev); - mutex_destroy(&info->pwmss_lock); - return 0; -} - -static int pwmss_suspend(struct device *dev) -{ - struct pwmss_info *info = dev_get_drvdata(dev); - - info->pwmss_clkconfig = readw(info->mmio_base + PWMSS_CLKCONFIG); - pm_runtime_put_sync(dev); - return 0; -} - -static int pwmss_resume(struct device *dev) -{ - struct pwmss_info *info = dev_get_drvdata(dev); - - pm_runtime_get_sync(dev); - writew(info->pwmss_clkconfig, info->mmio_base + PWMSS_CLKCONFIG); - return 0; -} - -static SIMPLE_DEV_PM_OPS(pwmss_pm_ops, pwmss_suspend, pwmss_resume); - -static struct platform_driver pwmss_driver = { - .driver = { - .name = "pwmss", - .owner = THIS_MODULE, - .pm = &pwmss_pm_ops, - .of_match_table = pwmss_of_match, - }, - .probe = pwmss_probe, - .remove = pwmss_remove, -}; - -module_platform_driver(pwmss_driver); - -MODULE_DESCRIPTION("PWM Subsystem driver"); -MODULE_AUTHOR("Texas Instruments"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/pwm/pwm-tipwmss.h b/trunk/drivers/pwm/pwm-tipwmss.h deleted file mode 100644 index 11f76a1e266b..000000000000 --- a/trunk/drivers/pwm/pwm-tipwmss.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * TI PWM Subsystem driver - * - * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ - -#ifndef __TIPWMSS_H -#define __TIPWMSS_H - -#ifdef CONFIG_PWM_TIPWMSS -/* PWM substem clock gating */ -#define PWMSS_ECAPCLK_EN BIT(0) -#define PWMSS_ECAPCLK_STOP_REQ BIT(1) -#define PWMSS_EPWMCLK_EN BIT(8) -#define PWMSS_EPWMCLK_STOP_REQ BIT(9) - -#define PWMSS_ECAPCLK_EN_ACK BIT(0) -#define PWMSS_EPWMCLK_EN_ACK BIT(8) - -extern u16 pwmss_submodule_state_change(struct device *dev, int set); -#else -static inline u16 pwmss_submodule_state_change(struct device *dev, int set) -{ - /* return success status value */ - return 0xFFFF; -} -#endif -#endif /* __TIPWMSS_H */ diff --git a/trunk/drivers/pwm/pwm-twl-led.c b/trunk/drivers/pwm/pwm-twl-led.c deleted file mode 100644 index 9dfa0f3eca30..000000000000 --- a/trunk/drivers/pwm/pwm-twl-led.c +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Driver for TWL4030/6030 Pulse Width Modulator used as LED driver - * - * Copyright (C) 2012 Texas Instruments - * Author: Peter Ujfalusi - * - * This driver is a complete rewrite of the former pwm-twl6030.c authorded by: - * Hemanth V - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ - -#include -#include -#include -#include -#include - -/* - * This driver handles the PWM driven LED terminals of TWL4030 and TWL6030. - * To generate the signal on TWL4030: - * - LEDA uses PWMA - * - LEDB uses PWMB - * TWL6030 has one LED pin with dedicated LEDPWM - */ - -#define TWL4030_LED_MAX 0x7f -#define TWL6030_LED_MAX 0xff - -/* Registers, bits and macro for TWL4030 */ -#define TWL4030_LEDEN_REG 0x00 -#define TWL4030_PWMA_REG 0x01 - -#define TWL4030_LEDXON (1 << 0) -#define TWL4030_LEDXPWM (1 << 4) -#define TWL4030_LED_PINS (TWL4030_LEDXON | TWL4030_LEDXPWM) -#define TWL4030_LED_TOGGLE(led, x) ((x) << (led)) - -/* Register, bits and macro for TWL6030 */ -#define TWL6030_LED_PWM_CTRL1 0xf4 -#define TWL6030_LED_PWM_CTRL2 0xf5 - -#define TWL6040_LED_MODE_HW 0x00 -#define TWL6040_LED_MODE_ON 0x01 -#define TWL6040_LED_MODE_OFF 0x02 -#define TWL6040_LED_MODE_MASK 0x03 - -struct twl_pwmled_chip { - struct pwm_chip chip; - struct mutex mutex; -}; - -static inline struct twl_pwmled_chip *to_twl(struct pwm_chip *chip) -{ - return container_of(chip, struct twl_pwmled_chip, chip); -} - -static int twl4030_pwmled_config(struct pwm_chip *chip, struct pwm_device *pwm, - int duty_ns, int period_ns) -{ - int duty_cycle = DIV_ROUND_UP(duty_ns * TWL4030_LED_MAX, period_ns) + 1; - u8 pwm_config[2] = { 1, 0 }; - int base, ret; - - /* - * To configure the duty period: - * On-cycle is set to 1 (the minimum allowed value) - * The off time of 0 is not configurable, so the mapping is: - * 0 -> off cycle = 2, - * 1 -> off cycle = 2, - * 2 -> off cycle = 3, - * 126 - > off cycle 127, - * 127 - > off cycle 1 - * When on cycle == off cycle the PWM will be always on - */ - if (duty_cycle == 1) - duty_cycle = 2; - else if (duty_cycle > TWL4030_LED_MAX) - duty_cycle = 1; - - base = pwm->hwpwm * 2 + TWL4030_PWMA_REG; - - pwm_config[1] = duty_cycle; - - ret = twl_i2c_write(TWL4030_MODULE_LED, pwm_config, base, 2); - if (ret < 0) - dev_err(chip->dev, "%s: Failed to configure PWM\n", pwm->label); - - return ret; -} - -static int twl4030_pwmled_enable(struct pwm_chip *chip, struct pwm_device *pwm) -{ - struct twl_pwmled_chip *twl = to_twl(chip); - int ret; - u8 val; - - mutex_lock(&twl->mutex); - ret = twl_i2c_read_u8(TWL4030_MODULE_LED, &val, TWL4030_LEDEN_REG); - if (ret < 0) { - dev_err(chip->dev, "%s: Failed to read LEDEN\n", pwm->label); - goto out; - } - - val |= TWL4030_LED_TOGGLE(pwm->hwpwm, TWL4030_LED_PINS); - - ret = twl_i2c_write_u8(TWL4030_MODULE_LED, val, TWL4030_LEDEN_REG); - if (ret < 0) - dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label); - -out: - mutex_unlock(&twl->mutex); - return ret; -} - -static void twl4030_pwmled_disable(struct pwm_chip *chip, - struct pwm_device *pwm) -{ - struct twl_pwmled_chip *twl = to_twl(chip); - int ret; - u8 val; - - mutex_lock(&twl->mutex); - ret = twl_i2c_read_u8(TWL4030_MODULE_LED, &val, TWL4030_LEDEN_REG); - if (ret < 0) { - dev_err(chip->dev, "%s: Failed to read LEDEN\n", pwm->label); - goto out; - } - - val &= ~TWL4030_LED_TOGGLE(pwm->hwpwm, TWL4030_LED_PINS); - - ret = twl_i2c_write_u8(TWL4030_MODULE_LED, val, TWL4030_LEDEN_REG); - if (ret < 0) - dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label); - -out: - mutex_unlock(&twl->mutex); -} - -static int twl6030_pwmled_config(struct pwm_chip *chip, struct pwm_device *pwm, - int duty_ns, int period_ns) -{ - int duty_cycle = (duty_ns * TWL6030_LED_MAX) / period_ns; - u8 on_time; - int ret; - - on_time = duty_cycle & 0xff; - - ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, on_time, - TWL6030_LED_PWM_CTRL1); - if (ret < 0) - dev_err(chip->dev, "%s: Failed to configure PWM\n", pwm->label); - - return ret; -} - -static int twl6030_pwmled_enable(struct pwm_chip *chip, struct pwm_device *pwm) -{ - struct twl_pwmled_chip *twl = to_twl(chip); - int ret; - u8 val; - - mutex_lock(&twl->mutex); - ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, TWL6030_LED_PWM_CTRL2); - if (ret < 0) { - dev_err(chip->dev, "%s: Failed to read PWM_CTRL2\n", - pwm->label); - goto out; - } - - val &= ~TWL6040_LED_MODE_MASK; - val |= TWL6040_LED_MODE_ON; - - ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_LED_PWM_CTRL2); - if (ret < 0) - dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label); - -out: - mutex_unlock(&twl->mutex); - return ret; -} - -static void twl6030_pwmled_disable(struct pwm_chip *chip, - struct pwm_device *pwm) -{ - struct twl_pwmled_chip *twl = to_twl(chip); - int ret; - u8 val; - - mutex_lock(&twl->mutex); - ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, TWL6030_LED_PWM_CTRL2); - if (ret < 0) { - dev_err(chip->dev, "%s: Failed to read PWM_CTRL2\n", - pwm->label); - goto out; - } - - val &= ~TWL6040_LED_MODE_MASK; - val |= TWL6040_LED_MODE_OFF; - - ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_LED_PWM_CTRL2); - if (ret < 0) - dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label); - -out: - mutex_unlock(&twl->mutex); -} - -static int twl6030_pwmled_request(struct pwm_chip *chip, struct pwm_device *pwm) -{ - struct twl_pwmled_chip *twl = to_twl(chip); - int ret; - u8 val; - - mutex_lock(&twl->mutex); - ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, TWL6030_LED_PWM_CTRL2); - if (ret < 0) { - dev_err(chip->dev, "%s: Failed to read PWM_CTRL2\n", - pwm->label); - goto out; - } - - val &= ~TWL6040_LED_MODE_MASK; - val |= TWL6040_LED_MODE_OFF; - - ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_LED_PWM_CTRL2); - if (ret < 0) - dev_err(chip->dev, "%s: Failed to request PWM\n", pwm->label); - -out: - mutex_unlock(&twl->mutex); - return ret; -} - -static void twl6030_pwmled_free(struct pwm_chip *chip, struct pwm_device *pwm) -{ - struct twl_pwmled_chip *twl = to_twl(chip); - int ret; - u8 val; - - mutex_lock(&twl->mutex); - ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, TWL6030_LED_PWM_CTRL2); - if (ret < 0) { - dev_err(chip->dev, "%s: Failed to read PWM_CTRL2\n", - pwm->label); - goto out; - } - - val &= ~TWL6040_LED_MODE_MASK; - val |= TWL6040_LED_MODE_HW; - - ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_LED_PWM_CTRL2); - if (ret < 0) - dev_err(chip->dev, "%s: Failed to free PWM\n", pwm->label); - -out: - mutex_unlock(&twl->mutex); -} - -static const struct pwm_ops twl4030_pwmled_ops = { - .enable = twl4030_pwmled_enable, - .disable = twl4030_pwmled_disable, - .config = twl4030_pwmled_config, -}; - -static const struct pwm_ops twl6030_pwmled_ops = { - .enable = twl6030_pwmled_enable, - .disable = twl6030_pwmled_disable, - .config = twl6030_pwmled_config, - .request = twl6030_pwmled_request, - .free = twl6030_pwmled_free, -}; - -static int twl_pwmled_probe(struct platform_device *pdev) -{ - struct twl_pwmled_chip *twl; - int ret; - - twl = devm_kzalloc(&pdev->dev, sizeof(*twl), GFP_KERNEL); - if (!twl) - return -ENOMEM; - - if (twl_class_is_4030()) { - twl->chip.ops = &twl4030_pwmled_ops; - twl->chip.npwm = 2; - } else { - twl->chip.ops = &twl6030_pwmled_ops; - twl->chip.npwm = 1; - } - - twl->chip.dev = &pdev->dev; - twl->chip.base = -1; - - mutex_init(&twl->mutex); - - ret = pwmchip_add(&twl->chip); - if (ret < 0) - return ret; - - platform_set_drvdata(pdev, twl); - - return 0; -} - -static int twl_pwmled_remove(struct platform_device *pdev) -{ - struct twl_pwmled_chip *twl = platform_get_drvdata(pdev); - - return pwmchip_remove(&twl->chip); -} - -#ifdef CONFIG_OF -static struct of_device_id twl_pwmled_of_match[] = { - { .compatible = "ti,twl4030-pwmled" }, - { .compatible = "ti,twl6030-pwmled" }, - { }, -}; -MODULE_DEVICE_TABLE(of, twl_pwmled_of_match); -#endif - -static struct platform_driver twl_pwmled_driver = { - .driver = { - .name = "twl-pwmled", - .of_match_table = of_match_ptr(twl_pwmled_of_match), - }, - .probe = twl_pwmled_probe, - .remove = twl_pwmled_remove, -}; -module_platform_driver(twl_pwmled_driver); - -MODULE_AUTHOR("Peter Ujfalusi "); -MODULE_DESCRIPTION("PWM driver for TWL4030 and TWL6030 LED outputs"); -MODULE_ALIAS("platform:twl-pwmled"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/pwm/pwm-twl.c b/trunk/drivers/pwm/pwm-twl.c deleted file mode 100644 index e65db95d5e59..000000000000 --- a/trunk/drivers/pwm/pwm-twl.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Driver for TWL4030/6030 Generic Pulse Width Modulator - * - * Copyright (C) 2012 Texas Instruments - * Author: Peter Ujfalusi - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see . - */ - -#include -#include -#include -#include -#include - -/* - * This driver handles the PWMs of TWL4030 and TWL6030. - * The TRM names for the PWMs on TWL4030 are: PWM0, PWM1 - * TWL6030 also have two PWMs named in the TRM as PWM1, PWM2 - */ - -#define TWL_PWM_MAX 0x7f - -/* Registers, bits and macro for TWL4030 */ -#define TWL4030_GPBR1_REG 0x0c -#define TWL4030_PMBR1_REG 0x0d - -/* GPBR1 register bits */ -#define TWL4030_PWMXCLK_ENABLE (1 << 0) -#define TWL4030_PWMX_ENABLE (1 << 2) -#define TWL4030_PWMX_BITS (TWL4030_PWMX_ENABLE | TWL4030_PWMXCLK_ENABLE) -#define TWL4030_PWM_TOGGLE(pwm, x) ((x) << (pwm)) - -/* PMBR1 register bits */ -#define TWL4030_GPIO6_PWM0_MUTE_MASK (0x03 << 2) -#define TWL4030_GPIO6_PWM0_MUTE_PWM0 (0x01 << 2) -#define TWL4030_GPIO7_VIBRASYNC_PWM1_MASK (0x03 << 4) -#define TWL4030_GPIO7_VIBRASYNC_PWM1_PWM1 (0x03 << 4) - -/* Register, bits and macro for TWL6030 */ -#define TWL6030_TOGGLE3_REG 0x92 - -#define TWL6030_PWMXR (1 << 0) -#define TWL6030_PWMXS (1 << 1) -#define TWL6030_PWMXEN (1 << 2) -#define TWL6030_PWM_TOGGLE(pwm, x) ((x) << (pwm * 3)) - -struct twl_pwm_chip { - struct pwm_chip chip; - struct mutex mutex; - u8 twl6030_toggle3; - u8 twl4030_pwm_mux; -}; - -static inline struct twl_pwm_chip *to_twl(struct pwm_chip *chip) -{ - return container_of(chip, struct twl_pwm_chip, chip); -} - -static int twl_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, - int duty_ns, int period_ns) -{ - int duty_cycle = DIV_ROUND_UP(duty_ns * TWL_PWM_MAX, period_ns) + 1; - u8 pwm_config[2] = { 1, 0 }; - int base, ret; - - /* - * To configure the duty period: - * On-cycle is set to 1 (the minimum allowed value) - * The off time of 0 is not configurable, so the mapping is: - * 0 -> off cycle = 2, - * 1 -> off cycle = 2, - * 2 -> off cycle = 3, - * 126 - > off cycle 127, - * 127 - > off cycle 1 - * When on cycle == off cycle the PWM will be always on - */ - if (duty_cycle == 1) - duty_cycle = 2; - else if (duty_cycle > TWL_PWM_MAX) - duty_cycle = 1; - - base = pwm->hwpwm * 3; - - pwm_config[1] = duty_cycle; - - ret = twl_i2c_write(TWL_MODULE_PWM, pwm_config, base, 2); - if (ret < 0) - dev_err(chip->dev, "%s: Failed to configure PWM\n", pwm->label); - - return ret; -} - -static int twl4030_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) -{ - struct twl_pwm_chip *twl = to_twl(chip); - int ret; - u8 val; - - mutex_lock(&twl->mutex); - ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &val, TWL4030_GPBR1_REG); - if (ret < 0) { - dev_err(chip->dev, "%s: Failed to read GPBR1\n", pwm->label); - goto out; - } - - val |= TWL4030_PWM_TOGGLE(pwm->hwpwm, TWL4030_PWMXCLK_ENABLE); - - ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_GPBR1_REG); - if (ret < 0) - dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label); - - val |= TWL4030_PWM_TOGGLE(pwm->hwpwm, TWL4030_PWMX_ENABLE); - - ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_GPBR1_REG); - if (ret < 0) - dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label); - -out: - mutex_unlock(&twl->mutex); - return ret; -} - -static void twl4030_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) -{ - struct twl_pwm_chip *twl = to_twl(chip); - int ret; - u8 val; - - mutex_lock(&twl->mutex); - ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &val, TWL4030_GPBR1_REG); - if (ret < 0) { - dev_err(chip->dev, "%s: Failed to read GPBR1\n", pwm->label); - goto out; - } - - val &= ~TWL4030_PWM_TOGGLE(pwm->hwpwm, TWL4030_PWMX_ENABLE); - - ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_GPBR1_REG); - if (ret < 0) - dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label); - - val &= ~TWL4030_PWM_TOGGLE(pwm->hwpwm, TWL4030_PWMXCLK_ENABLE); - - ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_GPBR1_REG); - if (ret < 0) - dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label); - -out: - mutex_unlock(&twl->mutex); -} - -static int twl4030_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) -{ - struct twl_pwm_chip *twl = to_twl(chip); - int ret; - u8 val, mask, bits; - - if (pwm->hwpwm == 1) { - mask = TWL4030_GPIO7_VIBRASYNC_PWM1_MASK; - bits = TWL4030_GPIO7_VIBRASYNC_PWM1_PWM1; - } else { - mask = TWL4030_GPIO6_PWM0_MUTE_MASK; - bits = TWL4030_GPIO6_PWM0_MUTE_PWM0; - } - - mutex_lock(&twl->mutex); - ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &val, TWL4030_PMBR1_REG); - if (ret < 0) { - dev_err(chip->dev, "%s: Failed to read PMBR1\n", pwm->label); - goto out; - } - - /* Save the current MUX configuration for the PWM */ - twl->twl4030_pwm_mux &= ~mask; - twl->twl4030_pwm_mux |= (val & mask); - - /* Select PWM functionality */ - val &= ~mask; - val |= bits; - - ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_PMBR1_REG); - if (ret < 0) - dev_err(chip->dev, "%s: Failed to request PWM\n", pwm->label); - -out: - mutex_unlock(&twl->mutex); - return ret; -} - -static void twl4030_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) -{ - struct twl_pwm_chip *twl = container_of(chip, struct twl_pwm_chip, - chip); - int ret; - u8 val, mask; - - if (pwm->hwpwm == 1) - mask = TWL4030_GPIO7_VIBRASYNC_PWM1_MASK; - else - mask = TWL4030_GPIO6_PWM0_MUTE_MASK; - - mutex_lock(&twl->mutex); - ret = twl_i2c_read_u8(TWL4030_MODULE_INTBR, &val, TWL4030_PMBR1_REG); - if (ret < 0) { - dev_err(chip->dev, "%s: Failed to read PMBR1\n", pwm->label); - goto out; - } - - /* Restore the MUX configuration for the PWM */ - val &= ~mask; - val |= (twl->twl4030_pwm_mux & mask); - - ret = twl_i2c_write_u8(TWL4030_MODULE_INTBR, val, TWL4030_PMBR1_REG); - if (ret < 0) - dev_err(chip->dev, "%s: Failed to free PWM\n", pwm->label); - -out: - mutex_unlock(&twl->mutex); -} - -static int twl6030_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) -{ - struct twl_pwm_chip *twl = container_of(chip, struct twl_pwm_chip, - chip); - int ret; - u8 val; - - mutex_lock(&twl->mutex); - val = twl->twl6030_toggle3; - val |= TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXS | TWL6030_PWMXEN); - val &= ~TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXR); - - ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG); - if (ret < 0) { - dev_err(chip->dev, "%s: Failed to enable PWM\n", pwm->label); - goto out; - } - - twl->twl6030_toggle3 = val; -out: - mutex_unlock(&twl->mutex); - return 0; -} - -static void twl6030_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) -{ - struct twl_pwm_chip *twl = container_of(chip, struct twl_pwm_chip, - chip); - int ret; - u8 val; - - mutex_lock(&twl->mutex); - val = twl->twl6030_toggle3; - val |= TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXR); - val &= ~TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXS | TWL6030_PWMXEN); - - ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG); - if (ret < 0) { - dev_err(chip->dev, "%s: Failed to read TOGGLE3\n", pwm->label); - goto out; - } - - val |= TWL6030_PWM_TOGGLE(pwm->hwpwm, TWL6030_PWMXS | TWL6030_PWMXEN); - - ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, TWL6030_TOGGLE3_REG); - if (ret < 0) { - dev_err(chip->dev, "%s: Failed to disable PWM\n", pwm->label); - goto out; - } - - twl->twl6030_toggle3 = val; -out: - mutex_unlock(&twl->mutex); -} - -static const struct pwm_ops twl4030_pwm_ops = { - .config = twl_pwm_config, - .enable = twl4030_pwm_enable, - .disable = twl4030_pwm_disable, - .request = twl4030_pwm_request, - .free = twl4030_pwm_free, -}; - -static const struct pwm_ops twl6030_pwm_ops = { - .config = twl_pwm_config, - .enable = twl6030_pwm_enable, - .disable = twl6030_pwm_disable, -}; - -static int twl_pwm_probe(struct platform_device *pdev) -{ - struct twl_pwm_chip *twl; - int ret; - - twl = devm_kzalloc(&pdev->dev, sizeof(*twl), GFP_KERNEL); - if (!twl) - return -ENOMEM; - - if (twl_class_is_4030()) - twl->chip.ops = &twl4030_pwm_ops; - else - twl->chip.ops = &twl6030_pwm_ops; - - twl->chip.dev = &pdev->dev; - twl->chip.base = -1; - twl->chip.npwm = 2; - - mutex_init(&twl->mutex); - - ret = pwmchip_add(&twl->chip); - if (ret < 0) - return ret; - - platform_set_drvdata(pdev, twl); - - return 0; -} - -static int twl_pwm_remove(struct platform_device *pdev) -{ - struct twl_pwm_chip *twl = platform_get_drvdata(pdev); - - return pwmchip_remove(&twl->chip); -} - -#ifdef CONFIG_OF -static struct of_device_id twl_pwm_of_match[] = { - { .compatible = "ti,twl4030-pwm" }, - { .compatible = "ti,twl6030-pwm" }, - { }, -}; -MODULE_DEVICE_TABLE(of, twl_pwm_of_match); -#endif - -static struct platform_driver twl_pwm_driver = { - .driver = { - .name = "twl-pwm", - .of_match_table = of_match_ptr(twl_pwm_of_match), - }, - .probe = twl_pwm_probe, - .remove = twl_pwm_remove, -}; -module_platform_driver(twl_pwm_driver); - -MODULE_AUTHOR("Peter Ujfalusi "); -MODULE_DESCRIPTION("PWM driver for TWL4030 and TWL6030"); -MODULE_ALIAS("platform:twl-pwm"); -MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/pwm/pwm-twl6030.c b/trunk/drivers/pwm/pwm-twl6030.c new file mode 100644 index 000000000000..378a7e286366 --- /dev/null +++ b/trunk/drivers/pwm/pwm-twl6030.c @@ -0,0 +1,184 @@ +/* + * twl6030_pwm.c + * Driver for PHOENIX (TWL6030) Pulse Width Modulator + * + * Copyright (C) 2010 Texas Instruments + * Author: Hemanth V + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include +#include +#include +#include +#include + +#define LED_PWM_CTRL1 0xF4 +#define LED_PWM_CTRL2 0xF5 + +/* Max value for CTRL1 register */ +#define PWM_CTRL1_MAX 255 + +/* Pull down disable */ +#define PWM_CTRL2_DIS_PD (1 << 6) + +/* Current control 2.5 milli Amps */ +#define PWM_CTRL2_CURR_02 (2 << 4) + +/* LED supply source */ +#define PWM_CTRL2_SRC_VAC (1 << 2) + +/* LED modes */ +#define PWM_CTRL2_MODE_HW (0 << 0) +#define PWM_CTRL2_MODE_SW (1 << 0) +#define PWM_CTRL2_MODE_DIS (2 << 0) + +#define PWM_CTRL2_MODE_MASK 0x3 + +struct twl6030_pwm_chip { + struct pwm_chip chip; +}; + +static int twl6030_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm) +{ + int ret; + u8 val; + + /* Configure PWM */ + val = PWM_CTRL2_DIS_PD | PWM_CTRL2_CURR_02 | PWM_CTRL2_SRC_VAC | + PWM_CTRL2_MODE_HW; + + ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2); + if (ret < 0) { + dev_err(chip->dev, "%s: Failed to configure PWM, Error %d\n", + pwm->label, ret); + return ret; + } + + return 0; +} + +static int twl6030_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, + int duty_ns, int period_ns) +{ + u8 duty_cycle = (duty_ns * PWM_CTRL1_MAX) / period_ns; + int ret; + + ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, duty_cycle, LED_PWM_CTRL1); + if (ret < 0) { + pr_err("%s: Failed to configure PWM, Error %d\n", + pwm->label, ret); + return ret; + } + + return 0; +} + +static int twl6030_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) +{ + int ret; + u8 val; + + ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, LED_PWM_CTRL2); + if (ret < 0) { + dev_err(chip->dev, "%s: Failed to enable PWM, Error %d\n", + pwm->label, ret); + return ret; + } + + /* Change mode to software control */ + val &= ~PWM_CTRL2_MODE_MASK; + val |= PWM_CTRL2_MODE_SW; + + ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2); + if (ret < 0) { + dev_err(chip->dev, "%s: Failed to enable PWM, Error %d\n", + pwm->label, ret); + return ret; + } + + twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, LED_PWM_CTRL2); + return 0; +} + +static void twl6030_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) +{ + int ret; + u8 val; + + ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, LED_PWM_CTRL2); + if (ret < 0) { + dev_err(chip->dev, "%s: Failed to disable PWM, Error %d\n", + pwm->label, ret); + return; + } + + val &= ~PWM_CTRL2_MODE_MASK; + val |= PWM_CTRL2_MODE_HW; + + ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2); + if (ret < 0) { + dev_err(chip->dev, "%s: Failed to disable PWM, Error %d\n", + pwm->label, ret); + } +} + +static const struct pwm_ops twl6030_pwm_ops = { + .request = twl6030_pwm_request, + .config = twl6030_pwm_config, + .enable = twl6030_pwm_enable, + .disable = twl6030_pwm_disable, +}; + +static int twl6030_pwm_probe(struct platform_device *pdev) +{ + struct twl6030_pwm_chip *twl6030; + int ret; + + twl6030 = devm_kzalloc(&pdev->dev, sizeof(*twl6030), GFP_KERNEL); + if (!twl6030) + return -ENOMEM; + + twl6030->chip.dev = &pdev->dev; + twl6030->chip.ops = &twl6030_pwm_ops; + twl6030->chip.base = -1; + twl6030->chip.npwm = 1; + + ret = pwmchip_add(&twl6030->chip); + if (ret < 0) + return ret; + + platform_set_drvdata(pdev, twl6030); + + return 0; +} + +static int twl6030_pwm_remove(struct platform_device *pdev) +{ + struct twl6030_pwm_chip *twl6030 = platform_get_drvdata(pdev); + + return pwmchip_remove(&twl6030->chip); +} + +static struct platform_driver twl6030_pwm_driver = { + .driver = { + .name = "twl6030-pwm", + }, + .probe = twl6030_pwm_probe, + .remove = twl6030_pwm_remove, +}; +module_platform_driver(twl6030_pwm_driver); + +MODULE_ALIAS("platform:twl6030-pwm"); +MODULE_LICENSE("GPL"); diff --git a/trunk/drivers/pwm/pwm-vt8500.c b/trunk/drivers/pwm/pwm-vt8500.c index b0ba2d403439..ad14389b7144 100644 --- a/trunk/drivers/pwm/pwm-vt8500.c +++ b/trunk/drivers/pwm/pwm-vt8500.c @@ -1,8 +1,7 @@ /* * drivers/pwm/pwm-vt8500.c * - * Copyright (C) 2012 Tony Prisk - * Copyright (C) 2010 Alexey Charkov + * Copyright (C) 2010 Alexey Charkov * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -22,24 +21,14 @@ #include #include #include -#include #include -#include -#include -#include - -/* - * SoC architecture allocates register space for 4 PWMs but only - * 2 are currently implemented. - */ -#define VT8500_NR_PWMS 2 +#define VT8500_NR_PWMS 4 struct vt8500_chip { struct pwm_chip chip; void __iomem *base; - struct clk *clk; }; #define to_vt8500_chip(chip) container_of(chip, struct vt8500_chip, chip) @@ -62,15 +51,8 @@ static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, struct vt8500_chip *vt8500 = to_vt8500_chip(chip); unsigned long long c; unsigned long period_cycles, prescale, pv, dc; - int err; - err = clk_enable(vt8500->clk); - if (err < 0) { - dev_err(chip->dev, "failed to enable clock\n"); - return err; - } - - c = clk_get_rate(vt8500->clk); + c = 25000000/2; /* wild guess --- need to implement clocks */ c = c * period_ns; do_div(c, 1000000000); period_cycles = c; @@ -82,10 +64,8 @@ static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, if (pv > 4095) pv = 4095; - if (prescale > 1023) { - clk_disable(vt8500->clk); + if (prescale > 1023) return -EINVAL; - } c = (unsigned long long)pv * duty_ns; do_div(c, period_ns); @@ -100,21 +80,13 @@ static int vt8500_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, pwm_busy_wait(vt8500->base + 0x40 + pwm->hwpwm, (1 << 3)); writel(dc, vt8500->base + 0xc + (pwm->hwpwm << 4)); - clk_disable(vt8500->clk); return 0; } static int vt8500_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) { - int err; struct vt8500_chip *vt8500 = to_vt8500_chip(chip); - err = clk_enable(vt8500->clk); - if (err < 0) { - dev_err(chip->dev, "failed to enable clock\n"); - return err; - } - pwm_busy_wait(vt8500->base + 0x40 + pwm->hwpwm, (1 << 0)); writel(5, vt8500->base + (pwm->hwpwm << 4)); return 0; @@ -126,8 +98,6 @@ static void vt8500_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) pwm_busy_wait(vt8500->base + 0x40 + pwm->hwpwm, (1 << 0)); writel(0, vt8500->base + (pwm->hwpwm << 4)); - - clk_disable(vt8500->clk); } static struct pwm_ops vt8500_pwm_ops = { @@ -137,24 +107,12 @@ static struct pwm_ops vt8500_pwm_ops = { .owner = THIS_MODULE, }; -static const struct of_device_id vt8500_pwm_dt_ids[] = { - { .compatible = "via,vt8500-pwm", }, - { /* Sentinel */ } -}; -MODULE_DEVICE_TABLE(of, vt8500_pwm_dt_ids); - -static int vt8500_pwm_probe(struct platform_device *pdev) +static int __devinit pwm_probe(struct platform_device *pdev) { struct vt8500_chip *chip; struct resource *r; - struct device_node *np = pdev->dev.of_node; int ret; - if (!np) { - dev_err(&pdev->dev, "invalid devicetree node\n"); - return -EINVAL; - } - chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); if (chip == NULL) { dev_err(&pdev->dev, "failed to allocate memory\n"); @@ -166,12 +124,6 @@ static int vt8500_pwm_probe(struct platform_device *pdev) chip->chip.base = -1; chip->chip.npwm = VT8500_NR_PWMS; - chip->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(chip->clk)) { - dev_err(&pdev->dev, "clock source not specified\n"); - return PTR_ERR(chip->clk); - } - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (r == NULL) { dev_err(&pdev->dev, "no memory resource defined\n"); @@ -179,26 +131,18 @@ static int vt8500_pwm_probe(struct platform_device *pdev) } chip->base = devm_request_and_ioremap(&pdev->dev, r); - if (!chip->base) + if (chip->base == NULL) return -EADDRNOTAVAIL; - ret = clk_prepare(chip->clk); - if (ret < 0) { - dev_err(&pdev->dev, "failed to prepare clock\n"); - return ret; - } - ret = pwmchip_add(&chip->chip); - if (ret < 0) { - dev_err(&pdev->dev, "failed to add PWM chip\n"); + if (ret < 0) return ret; - } platform_set_drvdata(pdev, chip); return ret; } -static int vt8500_pwm_remove(struct platform_device *pdev) +static int __devexit pwm_remove(struct platform_device *pdev) { struct vt8500_chip *chip; @@ -206,22 +150,28 @@ static int vt8500_pwm_remove(struct platform_device *pdev) if (chip == NULL) return -ENODEV; - clk_unprepare(chip->clk); - return pwmchip_remove(&chip->chip); } -static struct platform_driver vt8500_pwm_driver = { - .probe = vt8500_pwm_probe, - .remove = vt8500_pwm_remove, +static struct platform_driver pwm_driver = { .driver = { .name = "vt8500-pwm", .owner = THIS_MODULE, - .of_match_table = vt8500_pwm_dt_ids, }, + .probe = pwm_probe, + .remove = __devexit_p(pwm_remove), }; -module_platform_driver(vt8500_pwm_driver); -MODULE_DESCRIPTION("VT8500 PWM Driver"); -MODULE_AUTHOR("Tony Prisk "); -MODULE_LICENSE("GPL v2"); +static int __init pwm_init(void) +{ + return platform_driver_register(&pwm_driver); +} +arch_initcall(pwm_init); + +static void __exit pwm_exit(void) +{ + platform_driver_unregister(&pwm_driver); +} +module_exit(pwm_exit); + +MODULE_LICENSE("GPL"); diff --git a/trunk/fs/jffs2/nodemgmt.c b/trunk/fs/jffs2/nodemgmt.c index 03310721712f..0c96eb52c797 100644 --- a/trunk/fs/jffs2/nodemgmt.c +++ b/trunk/fs/jffs2/nodemgmt.c @@ -417,16 +417,14 @@ static int jffs2_do_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, spin_unlock(&c->erase_completion_lock); ret = jffs2_prealloc_raw_node_refs(c, jeb, 1); - + if (ret) + return ret; /* Just lock it again and continue. Nothing much can change because we hold c->alloc_sem anyway. In fact, it's not entirely clear why we hold c->erase_completion_lock in the majority of this function... but that's a question for another (more caffeine-rich) day. */ spin_lock(&c->erase_completion_lock); - if (ret) - return ret; - waste = jeb->free_size; jffs2_link_node_ref(c, jeb, (jeb->offset + c->sector_size - waste) | REF_OBSOLETE, diff --git a/trunk/include/linux/asn1.h b/trunk/include/linux/asn1.h index eed6982860ba..5c3f4e4b9a23 100644 --- a/trunk/include/linux/asn1.h +++ b/trunk/include/linux/asn1.h @@ -64,6 +64,4 @@ enum asn1_tag { ASN1_LONG_TAG = 31 /* Long form tag */ }; -#define ASN1_INDEFINITE_LENGTH 0x80 - #endif /* _LINUX_ASN1_H */ diff --git a/trunk/include/linux/bcma/bcma.h b/trunk/include/linux/bcma/bcma.h index e0ce311011c0..93b1e091b1e9 100644 --- a/trunk/include/linux/bcma/bcma.h +++ b/trunk/include/linux/bcma/bcma.h @@ -350,7 +350,6 @@ extern void bcma_core_set_clockmode(struct bcma_device *core, enum bcma_clkmode clkmode); extern void bcma_core_pll_ctl(struct bcma_device *core, u32 req, u32 status, bool on); -extern u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset); #define BCMA_DMA_TRANSLATION_MASK 0xC0000000 #define BCMA_DMA_TRANSLATION_NONE 0x00000000 #define BCMA_DMA_TRANSLATION_DMA32_CMT 0x40000000 /* Client Mode Translation for 32-bit DMA */ diff --git a/trunk/include/linux/blkdev.h b/trunk/include/linux/blkdev.h index f94bc83011ed..acb4f7bbbd32 100644 --- a/trunk/include/linux/blkdev.h +++ b/trunk/include/linux/blkdev.h @@ -1188,25 +1188,14 @@ static inline int queue_discard_alignment(struct request_queue *q) static inline int queue_limit_discard_alignment(struct queue_limits *lim, sector_t sector) { - unsigned int alignment, granularity, offset; + sector_t alignment = sector << 9; + alignment = sector_div(alignment, lim->discard_granularity); if (!lim->max_discard_sectors) return 0; - /* Why are these in bytes, not sectors? */ - alignment = lim->discard_alignment >> 9; - granularity = lim->discard_granularity >> 9; - if (!granularity) - return 0; - - /* Offset of the partition start in 'granularity' sectors */ - offset = sector_div(sector, granularity); - - /* And why do we do this modulus *again* in blkdev_issue_discard()? */ - offset = (granularity + alignment - offset) % granularity; - - /* Turn it back into bytes, gaah */ - return offset << 9; + alignment = lim->discard_granularity + lim->discard_alignment - alignment; + return sector_div(alignment, lim->discard_granularity); } static inline int bdev_discard_alignment(struct block_device *bdev) diff --git a/trunk/include/linux/compiler-gcc4.h b/trunk/include/linux/compiler-gcc4.h index 662fd1b4c42a..412bc6c2b023 100644 --- a/trunk/include/linux/compiler-gcc4.h +++ b/trunk/include/linux/compiler-gcc4.h @@ -31,8 +31,6 @@ #define __linktime_error(message) __attribute__((__error__(message))) -#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__) - #if __GNUC_MINOR__ >= 5 /* * Mark a position in code as unreachable. This can be used to @@ -65,13 +63,3 @@ #define __compiletime_warning(message) __attribute__((warning(message))) #define __compiletime_error(message) __attribute__((error(message))) #endif - -#ifdef CONFIG_ARCH_USE_BUILTIN_BSWAP -#if __GNUC_MINOR__ >= 4 -#define __HAVE_BUILTIN_BSWAP32__ -#define __HAVE_BUILTIN_BSWAP64__ -#endif -#if __GNUC_MINOR__ >= 8 || (defined(__powerpc__) && __GNUC_MINOR__ >= 6) -#define __HAVE_BUILTIN_BSWAP16__ -#endif -#endif diff --git a/trunk/include/linux/compiler-intel.h b/trunk/include/linux/compiler-intel.h index 973ce10c40b6..d8e636e5607d 100644 --- a/trunk/include/linux/compiler-intel.h +++ b/trunk/include/linux/compiler-intel.h @@ -29,10 +29,3 @@ #endif #define uninitialized_var(x) x - -#ifndef __HAVE_BUILTIN_BSWAP16__ -/* icc has this, but it's called _bswap16 */ -#define __HAVE_BUILTIN_BSWAP16__ -#define __builtin_bswap16 _bswap16 -#endif - diff --git a/trunk/include/linux/compiler.h b/trunk/include/linux/compiler.h index dd852b73b286..b121554f1fe2 100644 --- a/trunk/include/linux/compiler.h +++ b/trunk/include/linux/compiler.h @@ -44,10 +44,6 @@ extern void __chk_io_ptr(const volatile void __iomem *); # define __rcu #endif -/* Indirect macros required for expanded argument pasting, eg. __LINE__. */ -#define ___PASTE(a,b) a##b -#define __PASTE(a,b) ___PASTE(a,b) - #ifdef __KERNEL__ #ifdef __GNUC__ @@ -170,11 +166,6 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect); (typeof(ptr)) (__ptr + (off)); }) #endif -/* Not-quite-unique ID. */ -#ifndef __UNIQUE_ID -# define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __LINE__) -#endif - #endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ diff --git a/trunk/include/linux/ima.h b/trunk/include/linux/ima.h index 86c361e947b9..2c7223d7e73b 100644 --- a/trunk/include/linux/ima.h +++ b/trunk/include/linux/ima.h @@ -18,7 +18,6 @@ extern int ima_bprm_check(struct linux_binprm *bprm); extern int ima_file_check(struct file *file, int mask); extern void ima_file_free(struct file *file); extern int ima_file_mmap(struct file *file, unsigned long prot); -extern int ima_module_check(struct file *file); #else static inline int ima_bprm_check(struct linux_binprm *bprm) @@ -41,11 +40,6 @@ static inline int ima_file_mmap(struct file *file, unsigned long prot) return 0; } -static inline int ima_module_check(struct file *file) -{ - return 0; -} - #endif /* CONFIG_IMA_H */ #ifdef CONFIG_IMA_APPRAISE diff --git a/trunk/include/linux/moduleparam.h b/trunk/include/linux/moduleparam.h index 137b4198fc03..d6a58065c09c 100644 --- a/trunk/include/linux/moduleparam.h +++ b/trunk/include/linux/moduleparam.h @@ -16,15 +16,17 @@ /* Chosen so that structs with an unsigned long line up. */ #define MAX_PARAM_PREFIX_LEN (64 - sizeof(unsigned long)) +#define ___module_cat(a,b) __mod_ ## a ## b +#define __module_cat(a,b) ___module_cat(a,b) #ifdef MODULE #define __MODULE_INFO(tag, name, info) \ -static const char __UNIQUE_ID(name)[] \ +static const char __module_cat(name,__LINE__)[] \ __used __attribute__((section(".modinfo"), unused, aligned(1))) \ = __stringify(tag) "=" info #else /* !MODULE */ /* This struct is here for syntactic coherency, it is not used */ #define __MODULE_INFO(tag, name, info) \ - struct __UNIQUE_ID(name) {} + struct __module_cat(name,__LINE__) {} #endif #define __MODULE_PARM_TYPE(name, _type) \ __MODULE_INFO(parmtype, name##type, #name ":" _type) diff --git a/trunk/include/linux/mtd/blktrans.h b/trunk/include/linux/mtd/blktrans.h index 4eb0a50d0c55..ed270bd2e4df 100644 --- a/trunk/include/linux/mtd/blktrans.h +++ b/trunk/include/linux/mtd/blktrans.h @@ -23,7 +23,6 @@ #include #include #include -#include struct hd_geometry; struct mtd_info; @@ -44,8 +43,7 @@ struct mtd_blktrans_dev { struct kref ref; struct gendisk *disk; struct attribute_group *disk_attributes; - struct workqueue_struct *wq; - struct work_struct work; + struct task_struct *thread; struct request_queue *rq; spinlock_t queue_lock; void *priv; diff --git a/trunk/include/linux/mtd/doc2000.h b/trunk/include/linux/mtd/doc2000.h index 407d1e556c39..0f6fea73a1f6 100644 --- a/trunk/include/linux/mtd/doc2000.h +++ b/trunk/include/linux/mtd/doc2000.h @@ -92,26 +92,12 @@ * Others use readb/writeb */ #if defined(__arm__) -static inline u8 ReadDOC_(u32 __iomem *addr, unsigned long reg) -{ - return __raw_readl(addr + reg); -} -static inline void WriteDOC_(u8 data, u32 __iomem *addr, unsigned long reg) -{ - __raw_writel(data, addr + reg); - wmb(); -} +#define ReadDOC_(adr, reg) ((unsigned char)(*(volatile __u32 *)(((unsigned long)adr)+((reg)<<2)))) +#define WriteDOC_(d, adr, reg) do{ *(volatile __u32 *)(((unsigned long)adr)+((reg)<<2)) = (__u32)d; wmb();} while(0) #define DOC_IOREMAP_LEN 0x8000 #elif defined(__ppc__) -static inline u8 ReadDOC_(u16 __iomem *addr, unsigned long reg) -{ - return __raw_readw(addr + reg); -} -static inline void WriteDOC_(u8 data, u16 __iomem *addr, unsigned long reg) -{ - __raw_writew(data, addr + reg); - wmb(); -} +#define ReadDOC_(adr, reg) ((unsigned char)(*(volatile __u16 *)(((unsigned long)adr)+((reg)<<1)))) +#define WriteDOC_(d, adr, reg) do{ *(volatile __u16 *)(((unsigned long)adr)+((reg)<<1)) = (__u16)d; wmb();} while(0) #define DOC_IOREMAP_LEN 0x4000 #else #define ReadDOC_(adr, reg) readb((void __iomem *)(adr) + (reg)) diff --git a/trunk/include/linux/mtd/fsmc.h b/trunk/include/linux/mtd/fsmc.h index d6ed61ef451d..b20029221fb1 100644 --- a/trunk/include/linux/mtd/fsmc.h +++ b/trunk/include/linux/mtd/fsmc.h @@ -155,6 +155,9 @@ struct fsmc_nand_platform_data { unsigned int width; unsigned int bank; + /* CLE, ALE offsets */ + unsigned int cle_off; + unsigned int ale_off; enum access_mode mode; void (*select_bank)(uint32_t bank, uint32_t busw); diff --git a/trunk/include/linux/mtd/gpmi-nand.h b/trunk/include/linux/mtd/gpmi-nand.h new file mode 100644 index 000000000000..ed3c4e09f3d1 --- /dev/null +++ b/trunk/include/linux/mtd/gpmi-nand.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __MACH_MXS_GPMI_NAND_H__ +#define __MACH_MXS_GPMI_NAND_H__ + +/* The size of the resources is fixed. */ +#define GPMI_NAND_RES_SIZE 6 + +/* Resource names for the GPMI NAND driver. */ +#define GPMI_NAND_GPMI_REGS_ADDR_RES_NAME "gpmi-nand" +#define GPMI_NAND_GPMI_INTERRUPT_RES_NAME "GPMI NAND GPMI Interrupt" +#define GPMI_NAND_BCH_REGS_ADDR_RES_NAME "bch" +#define GPMI_NAND_BCH_INTERRUPT_RES_NAME "bch" +#define GPMI_NAND_DMA_CHANNELS_RES_NAME "GPMI NAND DMA Channels" +#define GPMI_NAND_DMA_INTERRUPT_RES_NAME "gpmi-dma" + +/** + * struct gpmi_nand_platform_data - GPMI NAND driver platform data. + * + * This structure communicates platform-specific information to the GPMI NAND + * driver that can't be expressed as resources. + * + * @platform_init: A pointer to a function the driver will call to + * initialize the platform (e.g., set up the pin mux). + * @min_prop_delay_in_ns: Minimum propagation delay of GPMI signals to and + * from the NAND Flash device, in nanoseconds. + * @max_prop_delay_in_ns: Maximum propagation delay of GPMI signals to and + * from the NAND Flash device, in nanoseconds. + * @max_chip_count: The maximum number of chips for which the driver + * should configure the hardware. This value most + * likely reflects the number of pins that are + * connected to a NAND Flash device. If this is + * greater than the SoC hardware can support, the + * driver will print a message and fail to initialize. + * @partitions: An optional pointer to an array of partition + * descriptions. + * @partition_count: The number of elements in the partitions array. + */ +struct gpmi_nand_platform_data { + /* SoC hardware information. */ + int (*platform_init)(void); + + /* NAND Flash information. */ + unsigned int min_prop_delay_in_ns; + unsigned int max_prop_delay_in_ns; + unsigned int max_chip_count; + + /* Medium information. */ + struct mtd_partition *partitions; + unsigned partition_count; +}; +#endif diff --git a/trunk/include/linux/mtd/map.h b/trunk/include/linux/mtd/map.h index f6eb4332ac92..3595a0236b0f 100644 --- a/trunk/include/linux/mtd/map.h +++ b/trunk/include/linux/mtd/map.h @@ -328,7 +328,7 @@ static inline int map_word_bitsset(struct map_info *map, map_word val1, map_word static inline map_word map_word_load(struct map_info *map, const void *ptr) { - map_word r = {{0} }; + map_word r; if (map_bankwidth_is_1(map)) r.x[0] = *(unsigned char *)ptr; @@ -391,7 +391,7 @@ static inline map_word map_word_ff(struct map_info *map) static inline map_word inline_map_read(struct map_info *map, unsigned long ofs) { - map_word uninitialized_var(r); + map_word r; if (map_bankwidth_is_1(map)) r.x[0] = __raw_readb(map->virt + ofs); diff --git a/trunk/include/linux/mtd/mtd.h b/trunk/include/linux/mtd/mtd.h index f9ac2897b86b..81d61e704599 100644 --- a/trunk/include/linux/mtd/mtd.h +++ b/trunk/include/linux/mtd/mtd.h @@ -98,7 +98,7 @@ struct mtd_oob_ops { }; #define MTD_MAX_OOBFREE_ENTRIES_LARGE 32 -#define MTD_MAX_ECCPOS_ENTRIES_LARGE 640 +#define MTD_MAX_ECCPOS_ENTRIES_LARGE 448 /* * Internal ECC layout control structure. For historical reasons, there is a * similar, smaller struct nand_ecclayout_user (in mtd-abi.h) that is retained diff --git a/trunk/include/linux/mtd/nand.h b/trunk/include/linux/mtd/nand.h index 7ccb3c59ed60..24e915957e4f 100644 --- a/trunk/include/linux/mtd/nand.h +++ b/trunk/include/linux/mtd/nand.h @@ -219,13 +219,6 @@ typedef enum { #define NAND_OWN_BUFFERS 0x00020000 /* Chip may not exist, so silence any errors in scan */ #define NAND_SCAN_SILENT_NODEV 0x00040000 -/* - * Autodetect nand buswidth with readid/onfi. - * This suppose the driver will configure the hardware in 8 bits mode - * when calling nand_scan_ident, and update its configuration - * before calling nand_scan_tail. - */ -#define NAND_BUSWIDTH_AUTO 0x00080000 /* Options set by nand scan */ /* Nand scan has allocated controller struct */ @@ -478,8 +471,8 @@ struct nand_buffers { * non 0 if ONFI supported. * @onfi_params: [INTERN] holds the ONFI page parameter when ONFI is * supported, 0 otherwise. - * @onfi_set_features: [REPLACEABLE] set the features for ONFI nand - * @onfi_get_features: [REPLACEABLE] get the features for ONFI nand + * @onfi_set_features [REPLACEABLE] set the features for ONFI nand + * @onfi_get_features [REPLACEABLE] get the features for ONFI nand * @ecclayout: [REPLACEABLE] the default ECC placement scheme * @bbt: [INTERN] bad block table pointer * @bbt_td: [REPLACEABLE] bad block table descriptor for flash diff --git a/trunk/include/linux/mtd/sh_flctl.h b/trunk/include/linux/mtd/sh_flctl.h index 1c28f8879b1c..01e4b15b280e 100644 --- a/trunk/include/linux/mtd/sh_flctl.h +++ b/trunk/include/linux/mtd/sh_flctl.h @@ -20,7 +20,6 @@ #ifndef __SH_FLCTL_H__ #define __SH_FLCTL_H__ -#include #include #include #include @@ -108,7 +107,6 @@ #define ESTERINTE (0x1 << 24) /* ECC error interrupt enable */ #define AC1CLR (0x1 << 19) /* ECC FIFO clear */ #define AC0CLR (0x1 << 18) /* Data FIFO clear */ -#define DREQ0EN (0x1 << 16) /* FLDTFIFODMA Request Enable */ #define ECERB (0x1 << 9) /* ECC error */ #define STERB (0x1 << 8) /* Status error */ #define STERINTE (0x1 << 4) /* Status error enable */ @@ -140,8 +138,6 @@ enum flctl_ecc_res_t { FL_TIMEOUT }; -struct dma_chan; - struct sh_flctl { struct mtd_info mtd; struct nand_chip chip; @@ -151,7 +147,7 @@ struct sh_flctl { uint8_t done_buff[2048 + 64]; /* max size 2048 + 64 */ int read_bytes; - unsigned int index; + int index; int seqin_column; /* column in SEQIN cmd */ int seqin_page_addr; /* page_addr in SEQIN cmd */ uint32_t seqin_read_cmd; /* read cmd in SEQIN cmd */ @@ -165,11 +161,6 @@ struct sh_flctl { unsigned hwecc:1; /* Hardware ECC (0 = disabled, 1 = enabled) */ unsigned holden:1; /* Hardware has FLHOLDCR and HOLDEN is set */ unsigned qos_request:1; /* QoS request to prevent deep power shutdown */ - - /* DMA related objects */ - struct dma_chan *chan_fifo0_rx; - struct dma_chan *chan_fifo0_tx; - struct completion dma_complete; }; struct sh_flctl_platform_data { @@ -179,9 +170,6 @@ struct sh_flctl_platform_data { unsigned has_hwecc:1; unsigned use_holden:1; - - unsigned int slave_id_fifo0_tx; - unsigned int slave_id_fifo0_rx; }; static inline struct sh_flctl *mtd_to_flctl(struct mtd_info *mtdinfo) diff --git a/trunk/include/linux/platform_data/mtd-nomadik-nand.h b/trunk/include/linux/platform_data/mtd-nomadik-nand.h new file mode 100644 index 000000000000..c3c8254c22a5 --- /dev/null +++ b/trunk/include/linux/platform_data/mtd-nomadik-nand.h @@ -0,0 +1,16 @@ +#ifndef __ASM_ARCH_NAND_H +#define __ASM_ARCH_NAND_H + +struct nomadik_nand_platform_data { + struct mtd_partition *parts; + int nparts; + int options; + int (*init) (void); + int (*exit) (void); +}; + +#define NAND_IO_DATA 0x40000000 +#define NAND_IO_CMD 0x40800000 +#define NAND_IO_ADDR 0x41000000 + +#endif /* __ASM_ARCH_NAND_H */ diff --git a/trunk/include/linux/pwm.h b/trunk/include/linux/pwm.h index 6d661f32e0e4..112b31436848 100644 --- a/trunk/include/linux/pwm.h +++ b/trunk/include/linux/pwm.h @@ -171,9 +171,6 @@ struct pwm_device *pwm_request_from_chip(struct pwm_chip *chip, unsigned int index, const char *label); -struct pwm_device *of_pwm_xlate_with_flags(struct pwm_chip *pc, - const struct of_phandle_args *args); - struct pwm_device *pwm_get(struct device *dev, const char *consumer); void pwm_put(struct pwm_device *pwm); diff --git a/trunk/include/linux/security.h b/trunk/include/linux/security.h index 0f6afc657f77..05e88bdcf7d9 100644 --- a/trunk/include/linux/security.h +++ b/trunk/include/linux/security.h @@ -694,12 +694,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) * userspace to load a kernel module with the given name. * @kmod_name name of the module requested by the kernel * Return 0 if successful. - * @kernel_module_from_file: - * Load a kernel module from userspace. - * @file contains the file structure pointing to the file containing - * the kernel module to load. If the module is being loaded from a blob, - * this argument will be NULL. - * Return 0 if permission is granted. * @task_fix_setuid: * Update the module's state after setting one or more of the user * identity attributes of the current process. The @flags parameter @@ -1514,7 +1508,6 @@ struct security_operations { int (*kernel_act_as)(struct cred *new, u32 secid); int (*kernel_create_files_as)(struct cred *new, struct inode *inode); int (*kernel_module_request)(char *kmod_name); - int (*kernel_module_from_file)(struct file *file); int (*task_fix_setuid) (struct cred *new, const struct cred *old, int flags); int (*task_setpgid) (struct task_struct *p, pid_t pgid); @@ -1772,7 +1765,6 @@ void security_transfer_creds(struct cred *new, const struct cred *old); int security_kernel_act_as(struct cred *new, u32 secid); int security_kernel_create_files_as(struct cred *new, struct inode *inode); int security_kernel_module_request(char *kmod_name); -int security_kernel_module_from_file(struct file *file); int security_task_fix_setuid(struct cred *new, const struct cred *old, int flags); int security_task_setpgid(struct task_struct *p, pid_t pgid); @@ -2286,11 +2278,6 @@ static inline int security_kernel_module_request(char *kmod_name) return 0; } -static inline int security_kernel_module_from_file(struct file *file) -{ - return 0; -} - static inline int security_task_fix_setuid(struct cred *new, const struct cred *old, int flags) diff --git a/trunk/include/linux/syscalls.h b/trunk/include/linux/syscalls.h index 6caee34bf8a2..36c3b07c5119 100644 --- a/trunk/include/linux/syscalls.h +++ b/trunk/include/linux/syscalls.h @@ -880,5 +880,4 @@ asmlinkage long sys_process_vm_writev(pid_t pid, asmlinkage long sys_kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2); -asmlinkage long sys_finit_module(int fd, const char __user *uargs, int flags); #endif diff --git a/trunk/include/uapi/asm-generic/unistd.h b/trunk/include/uapi/asm-generic/unistd.h index 2c531f478410..6e595ba545f4 100644 --- a/trunk/include/uapi/asm-generic/unistd.h +++ b/trunk/include/uapi/asm-generic/unistd.h @@ -690,11 +690,9 @@ __SC_COMP(__NR_process_vm_writev, sys_process_vm_writev, \ compat_sys_process_vm_writev) #define __NR_kcmp 272 __SYSCALL(__NR_kcmp, sys_kcmp) -#define __NR_finit_module 273 -__SYSCALL(__NR_finit_module, sys_finit_module) #undef __NR_syscalls -#define __NR_syscalls 274 +#define __NR_syscalls 273 /* * All syscalls below here should go away really, diff --git a/trunk/include/uapi/linux/module.h b/trunk/include/uapi/linux/module.h deleted file mode 100644 index 38da4258b12f..000000000000 --- a/trunk/include/uapi/linux/module.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _UAPI_LINUX_MODULE_H -#define _UAPI_LINUX_MODULE_H - -/* Flags for sys_finit_module: */ -#define MODULE_INIT_IGNORE_MODVERSIONS 1 -#define MODULE_INIT_IGNORE_VERMAGIC 2 - -#endif /* _UAPI_LINUX_MODULE_H */ diff --git a/trunk/include/uapi/linux/swab.h b/trunk/include/uapi/linux/swab.h index 0e011eb91b5d..e811474724c2 100644 --- a/trunk/include/uapi/linux/swab.h +++ b/trunk/include/uapi/linux/swab.h @@ -45,9 +45,7 @@ static inline __attribute_const__ __u16 __fswab16(__u16 val) { -#ifdef __HAVE_BUILTIN_BSWAP16__ - return __builtin_bswap16(val); -#elif defined (__arch_swab16) +#ifdef __arch_swab16 return __arch_swab16(val); #else return ___constant_swab16(val); @@ -56,9 +54,7 @@ static inline __attribute_const__ __u16 __fswab16(__u16 val) static inline __attribute_const__ __u32 __fswab32(__u32 val) { -#ifdef __HAVE_BUILTIN_BSWAP32__ - return __builtin_bswap32(val); -#elif defined(__arch_swab32) +#ifdef __arch_swab32 return __arch_swab32(val); #else return ___constant_swab32(val); @@ -67,9 +63,7 @@ static inline __attribute_const__ __u32 __fswab32(__u32 val) static inline __attribute_const__ __u64 __fswab64(__u64 val) { -#ifdef __HAVE_BUILTIN_BSWAP64__ - return __builtin_bswap64(val); -#elif defined (__arch_swab64) +#ifdef __arch_swab64 return __arch_swab64(val); #elif defined(__SWAB_64_THRU_32__) __u32 h = val >> 32; diff --git a/trunk/kernel/Makefile b/trunk/kernel/Makefile index 6c072b6da239..ac0d533eb7de 100644 --- a/trunk/kernel/Makefile +++ b/trunk/kernel/Makefile @@ -54,7 +54,7 @@ obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o obj-$(CONFIG_PROVE_LOCKING) += spinlock.o obj-$(CONFIG_UID16) += uid16.o obj-$(CONFIG_MODULES) += module.o -obj-$(CONFIG_MODULE_SIG) += module_signing.o modsign_pubkey.o modsign_certificate.o +obj-$(CONFIG_MODULE_SIG) += module_signing.o modsign_pubkey.o obj-$(CONFIG_KALLSYMS) += kallsyms.o obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o obj-$(CONFIG_KEXEC) += kexec.o @@ -137,14 +137,10 @@ ifeq ($(CONFIG_MODULE_SIG),y) # # Pull the signing certificate and any extra certificates into the kernel # - -quiet_cmd_touch = TOUCH $@ - cmd_touch = touch $@ - extra_certificates: - $(call cmd,touch) + touch $@ -kernel/modsign_certificate.o: signing_key.x509 extra_certificates +kernel/modsign_pubkey.o: signing_key.x509 extra_certificates ############################################################################### # diff --git a/trunk/kernel/modsign_certificate.S b/trunk/kernel/modsign_certificate.S deleted file mode 100644 index 246b4c6e6135..000000000000 --- a/trunk/kernel/modsign_certificate.S +++ /dev/null @@ -1,19 +0,0 @@ -/* SYMBOL_PREFIX defined on commandline from CONFIG_SYMBOL_PREFIX */ -#ifndef SYMBOL_PREFIX -#define ASM_SYMBOL(sym) sym -#else -#define PASTE2(x,y) x##y -#define PASTE(x,y) PASTE2(x,y) -#define ASM_SYMBOL(sym) PASTE(SYMBOL_PREFIX, sym) -#endif - -#define GLOBAL(name) \ - .globl ASM_SYMBOL(name); \ - ASM_SYMBOL(name): - - .section ".init.data","aw" - -GLOBAL(modsign_certificate_list) - .incbin "signing_key.x509" - .incbin "extra_certificates" -GLOBAL(modsign_certificate_list_end) diff --git a/trunk/kernel/modsign_pubkey.c b/trunk/kernel/modsign_pubkey.c index 045504fffbb2..767e559dfb10 100644 --- a/trunk/kernel/modsign_pubkey.c +++ b/trunk/kernel/modsign_pubkey.c @@ -20,6 +20,12 @@ struct key *modsign_keyring; extern __initdata const u8 modsign_certificate_list[]; extern __initdata const u8 modsign_certificate_list_end[]; +asm(".section .init.data,\"aw\"\n" + SYMBOL_PREFIX "modsign_certificate_list:\n" + ".incbin \"signing_key.x509\"\n" + ".incbin \"extra_certificates\"\n" + SYMBOL_PREFIX "modsign_certificate_list_end:" + ); /* * We need to make sure ccache doesn't cache the .o file as it doesn't notice diff --git a/trunk/kernel/module.c b/trunk/kernel/module.c index 250092c1d57d..808bd62e1723 100644 --- a/trunk/kernel/module.c +++ b/trunk/kernel/module.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include @@ -29,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -61,7 +59,6 @@ #include #include #include -#include #include "module-internal.h" #define CREATE_TRACE_POINTS @@ -2282,7 +2279,7 @@ static void layout_symtab(struct module *mod, struct load_info *info) Elf_Shdr *symsect = info->sechdrs + info->index.sym; Elf_Shdr *strsect = info->sechdrs + info->index.str; const Elf_Sym *src; - unsigned int i, nsrc, ndst, strtab_size = 0; + unsigned int i, nsrc, ndst, strtab_size; /* Put symbol section at end of init part of module. */ symsect->sh_flags |= SHF_ALLOC; @@ -2293,6 +2290,9 @@ static void layout_symtab(struct module *mod, struct load_info *info) src = (void *)info->hdr + symsect->sh_offset; nsrc = symsect->sh_size / sizeof(*src); + /* strtab always starts with a nul, so offset 0 is the empty string. */ + strtab_size = 1; + /* Compute total space required for the core symbols' strtab. */ for (ndst = i = 0; i < nsrc; i++) { if (i == 0 || @@ -2334,6 +2334,7 @@ static void add_kallsyms(struct module *mod, const struct load_info *info) mod->core_symtab = dst = mod->module_core + info->symoffs; mod->core_strtab = s = mod->module_core + info->stroffs; src = mod->symtab; + *s++ = 0; for (ndst = i = 0; i < mod->num_symtab; i++) { if (i == 0 || is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) { @@ -2374,7 +2375,7 @@ static void dynamic_debug_remove(struct _ddebug *debug) void * __weak module_alloc(unsigned long size) { - return vmalloc_exec(size); + return size == 0 ? NULL : vmalloc_exec(size); } static void *module_alloc_update_bounds(unsigned long size) @@ -2421,17 +2422,18 @@ static inline void kmemleak_load_module(const struct module *mod, #endif #ifdef CONFIG_MODULE_SIG -static int module_sig_check(struct load_info *info) +static int module_sig_check(struct load_info *info, + const void *mod, unsigned long *_len) { int err = -ENOKEY; - const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1; - const void *mod = info->hdr; + unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1; + unsigned long len = *_len; - if (info->len > markerlen && - memcmp(mod + info->len - markerlen, MODULE_SIG_STRING, markerlen) == 0) { + if (len > markerlen && + memcmp(mod + len - markerlen, MODULE_SIG_STRING, markerlen) == 0) { /* We truncate the module to discard the signature */ - info->len -= markerlen; - err = mod_verify_sig(mod, &info->len); + *_len -= markerlen; + err = mod_verify_sig(mod, _len); } if (!err) { @@ -2449,107 +2451,59 @@ static int module_sig_check(struct load_info *info) return err; } #else /* !CONFIG_MODULE_SIG */ -static int module_sig_check(struct load_info *info) +static int module_sig_check(struct load_info *info, + void *mod, unsigned long *len) { return 0; } #endif /* !CONFIG_MODULE_SIG */ -/* Sanity checks against invalid binaries, wrong arch, weird elf version. */ -static int elf_header_check(struct load_info *info) -{ - if (info->len < sizeof(*(info->hdr))) - return -ENOEXEC; - - if (memcmp(info->hdr->e_ident, ELFMAG, SELFMAG) != 0 - || info->hdr->e_type != ET_REL - || !elf_check_arch(info->hdr) - || info->hdr->e_shentsize != sizeof(Elf_Shdr)) - return -ENOEXEC; - - if (info->hdr->e_shoff >= info->len - || (info->hdr->e_shnum * sizeof(Elf_Shdr) > - info->len - info->hdr->e_shoff)) - return -ENOEXEC; - - return 0; -} - -/* Sets info->hdr and info->len. */ -static int copy_module_from_user(const void __user *umod, unsigned long len, - struct load_info *info) +/* Sets info->hdr, info->len and info->sig_ok. */ +static int copy_and_check(struct load_info *info, + const void __user *umod, unsigned long len, + const char __user *uargs) { int err; + Elf_Ehdr *hdr; - info->len = len; - if (info->len < sizeof(*(info->hdr))) + if (len < sizeof(*hdr)) return -ENOEXEC; - err = security_kernel_module_from_file(NULL); - if (err) - return err; - /* Suck in entire file: we'll want most of it. */ - info->hdr = vmalloc(info->len); - if (!info->hdr) + if ((hdr = vmalloc(len)) == NULL) return -ENOMEM; - if (copy_from_user(info->hdr, umod, info->len) != 0) { - vfree(info->hdr); - return -EFAULT; + if (copy_from_user(hdr, umod, len) != 0) { + err = -EFAULT; + goto free_hdr; } - return 0; -} - -/* Sets info->hdr and info->len. */ -static int copy_module_from_fd(int fd, struct load_info *info) -{ - struct file *file; - int err; - struct kstat stat; - loff_t pos; - ssize_t bytes = 0; - - file = fget(fd); - if (!file) - return -ENOEXEC; - - err = security_kernel_module_from_file(file); + err = module_sig_check(info, hdr, &len); if (err) - goto out; + goto free_hdr; - err = vfs_getattr(file->f_vfsmnt, file->f_dentry, &stat); - if (err) - goto out; - - if (stat.size > INT_MAX) { - err = -EFBIG; - goto out; - } - info->hdr = vmalloc(stat.size); - if (!info->hdr) { - err = -ENOMEM; - goto out; + /* Sanity checks against insmoding binaries or wrong arch, + weird elf version */ + if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0 + || hdr->e_type != ET_REL + || !elf_check_arch(hdr) + || hdr->e_shentsize != sizeof(Elf_Shdr)) { + err = -ENOEXEC; + goto free_hdr; } - pos = 0; - while (pos < stat.size) { - bytes = kernel_read(file, pos, (char *)(info->hdr) + pos, - stat.size - pos); - if (bytes < 0) { - vfree(info->hdr); - err = bytes; - goto out; - } - if (bytes == 0) - break; - pos += bytes; + if (hdr->e_shoff >= len || + hdr->e_shnum * sizeof(Elf_Shdr) > len - hdr->e_shoff) { + err = -ENOEXEC; + goto free_hdr; } - info->len = pos; -out: - fput(file); + info->hdr = hdr; + info->len = len; + return 0; + +free_hdr: + vfree(hdr); return err; } @@ -2558,7 +2512,7 @@ static void free_copy(struct load_info *info) vfree(info->hdr); } -static int rewrite_section_headers(struct load_info *info, int flags) +static int rewrite_section_headers(struct load_info *info) { unsigned int i; @@ -2586,10 +2540,7 @@ static int rewrite_section_headers(struct load_info *info, int flags) } /* Track but don't keep modinfo and version sections. */ - if (flags & MODULE_INIT_IGNORE_MODVERSIONS) - info->index.vers = 0; /* Pretend no __versions section! */ - else - info->index.vers = find_sec(info, "__versions"); + info->index.vers = find_sec(info, "__versions"); info->index.info = find_sec(info, ".modinfo"); info->sechdrs[info->index.info].sh_flags &= ~(unsigned long)SHF_ALLOC; info->sechdrs[info->index.vers].sh_flags &= ~(unsigned long)SHF_ALLOC; @@ -2604,7 +2555,7 @@ static int rewrite_section_headers(struct load_info *info, int flags) * Return the temporary module pointer (we'll replace it with the final * one when we move the module sections around). */ -static struct module *setup_load_info(struct load_info *info, int flags) +static struct module *setup_load_info(struct load_info *info) { unsigned int i; int err; @@ -2615,7 +2566,7 @@ static struct module *setup_load_info(struct load_info *info, int flags) info->secstrings = (void *)info->hdr + info->sechdrs[info->hdr->e_shstrndx].sh_offset; - err = rewrite_section_headers(info, flags); + err = rewrite_section_headers(info); if (err) return ERR_PTR(err); @@ -2653,14 +2604,11 @@ static struct module *setup_load_info(struct load_info *info, int flags) return mod; } -static int check_modinfo(struct module *mod, struct load_info *info, int flags) +static int check_modinfo(struct module *mod, struct load_info *info) { const char *modmagic = get_modinfo(info, "vermagic"); int err; - if (flags & MODULE_INIT_IGNORE_VERMAGIC) - modmagic = NULL; - /* This is allowed: modprobe --force will invalidate it. */ if (!modmagic) { err = try_to_force_load(mod, "bad vermagic"); @@ -2790,23 +2738,20 @@ static int move_module(struct module *mod, struct load_info *info) memset(ptr, 0, mod->core_size); mod->module_core = ptr; - if (mod->init_size) { - ptr = module_alloc_update_bounds(mod->init_size); - /* - * The pointer to this block is stored in the module structure - * which is inside the block. This block doesn't need to be - * scanned as it contains data and code that will be freed - * after the module is initialized. - */ - kmemleak_ignore(ptr); - if (!ptr) { - module_free(mod, mod->module_core); - return -ENOMEM; - } - memset(ptr, 0, mod->init_size); - mod->module_init = ptr; - } else - mod->module_init = NULL; + ptr = module_alloc_update_bounds(mod->init_size); + /* + * The pointer to this block is stored in the module structure + * which is inside the block. This block doesn't need to be + * scanned as it contains data and code that will be freed + * after the module is initialized. + */ + kmemleak_ignore(ptr); + if (!ptr && mod->init_size) { + module_free(mod, mod->module_core); + return -ENOMEM; + } + memset(ptr, 0, mod->init_size); + mod->module_init = ptr; /* Transfer each section which specifies SHF_ALLOC */ pr_debug("final section addresses:\n"); @@ -2899,18 +2844,18 @@ int __weak module_frob_arch_sections(Elf_Ehdr *hdr, return 0; } -static struct module *layout_and_allocate(struct load_info *info, int flags) +static struct module *layout_and_allocate(struct load_info *info) { /* Module within temporary copy. */ struct module *mod; Elf_Shdr *pcpusec; int err; - mod = setup_load_info(info, flags); + mod = setup_load_info(info); if (IS_ERR(mod)) return mod; - err = check_modinfo(mod, info, flags); + err = check_modinfo(mod, info); if (err) return ERR_PTR(err); @@ -2997,124 +2942,33 @@ static bool finished_loading(const char *name) return ret; } -/* Call module constructors. */ -static void do_mod_ctors(struct module *mod) -{ -#ifdef CONFIG_CONSTRUCTORS - unsigned long i; - - for (i = 0; i < mod->num_ctors; i++) - mod->ctors[i](); -#endif -} - -/* This is where the real work happens */ -static int do_init_module(struct module *mod) -{ - int ret = 0; - - blocking_notifier_call_chain(&module_notify_list, - MODULE_STATE_COMING, mod); - - /* Set RO and NX regions for core */ - set_section_ro_nx(mod->module_core, - mod->core_text_size, - mod->core_ro_size, - mod->core_size); - - /* Set RO and NX regions for init */ - set_section_ro_nx(mod->module_init, - mod->init_text_size, - mod->init_ro_size, - mod->init_size); - - do_mod_ctors(mod); - /* Start the module */ - if (mod->init != NULL) - ret = do_one_initcall(mod->init); - if (ret < 0) { - /* Init routine failed: abort. Try to protect us from - buggy refcounters. */ - mod->state = MODULE_STATE_GOING; - synchronize_sched(); - module_put(mod); - blocking_notifier_call_chain(&module_notify_list, - MODULE_STATE_GOING, mod); - free_module(mod); - wake_up_all(&module_wq); - return ret; - } - if (ret > 0) { - printk(KERN_WARNING -"%s: '%s'->init suspiciously returned %d, it should follow 0/-E convention\n" -"%s: loading module anyway...\n", - __func__, mod->name, ret, - __func__); - dump_stack(); - } - - /* Now it's a first class citizen! */ - mod->state = MODULE_STATE_LIVE; - blocking_notifier_call_chain(&module_notify_list, - MODULE_STATE_LIVE, mod); - - /* We need to finish all async code before the module init sequence is done */ - async_synchronize_full(); - - mutex_lock(&module_mutex); - /* Drop initial reference. */ - module_put(mod); - trim_init_extable(mod); -#ifdef CONFIG_KALLSYMS - mod->num_symtab = mod->core_num_syms; - mod->symtab = mod->core_symtab; - mod->strtab = mod->core_strtab; -#endif - unset_module_init_ro_nx(mod); - module_free(mod, mod->module_init); - mod->module_init = NULL; - mod->init_size = 0; - mod->init_ro_size = 0; - mod->init_text_size = 0; - mutex_unlock(&module_mutex); - wake_up_all(&module_wq); - - return 0; -} - -static int may_init_module(void) -{ - if (!capable(CAP_SYS_MODULE) || modules_disabled) - return -EPERM; - - return 0; -} - /* Allocate and load the module: note that size of section 0 is always zero, and we rely on this for optional sections. */ -static int load_module(struct load_info *info, const char __user *uargs, - int flags) +static struct module *load_module(void __user *umod, + unsigned long len, + const char __user *uargs) { + struct load_info info = { NULL, }; struct module *mod, *old; long err; - err = module_sig_check(info); - if (err) - goto free_copy; + pr_debug("load_module: umod=%p, len=%lu, uargs=%p\n", + umod, len, uargs); - err = elf_header_check(info); + /* Copy in the blobs from userspace, check they are vaguely sane. */ + err = copy_and_check(&info, umod, len, uargs); if (err) - goto free_copy; + return ERR_PTR(err); /* Figure out module layout, and allocate all the memory. */ - mod = layout_and_allocate(info, flags); + mod = layout_and_allocate(&info); if (IS_ERR(mod)) { err = PTR_ERR(mod); goto free_copy; } #ifdef CONFIG_MODULE_SIG - mod->sig_ok = info->sig_ok; + mod->sig_ok = info.sig_ok; if (!mod->sig_ok) add_taint_module(mod, TAINT_FORCED_MODULE); #endif @@ -3126,25 +2980,25 @@ static int load_module(struct load_info *info, const char __user *uargs, /* Now we've got everything in the final locations, we can * find optional sections. */ - find_module_sections(mod, info); + find_module_sections(mod, &info); err = check_module_license_and_versions(mod); if (err) goto free_unload; /* Set up MODINFO_ATTR fields */ - setup_modinfo(mod, info); + setup_modinfo(mod, &info); /* Fix up syms, so that st_value is a pointer to location. */ - err = simplify_symbols(mod, info); + err = simplify_symbols(mod, &info); if (err < 0) goto free_modinfo; - err = apply_relocations(mod, info); + err = apply_relocations(mod, &info); if (err < 0) goto free_modinfo; - err = post_relocation(mod, info); + err = post_relocation(mod, &info); if (err < 0) goto free_modinfo; @@ -3184,14 +3038,14 @@ static int load_module(struct load_info *info, const char __user *uargs, } /* This has to be done once we're sure module name is unique. */ - dynamic_debug_setup(info->debug, info->num_debug); + dynamic_debug_setup(info.debug, info.num_debug); /* Find duplicate symbols */ err = verify_export_symbols(mod); if (err < 0) goto ddebug; - module_bug_finalize(info->hdr, info->sechdrs, mod); + module_bug_finalize(info.hdr, info.sechdrs, mod); list_add_rcu(&mod->list, &modules); mutex_unlock(&module_mutex); @@ -3202,17 +3056,16 @@ static int load_module(struct load_info *info, const char __user *uargs, goto unlink; /* Link in to syfs. */ - err = mod_sysfs_setup(mod, info, mod->kp, mod->num_kp); + err = mod_sysfs_setup(mod, &info, mod->kp, mod->num_kp); if (err < 0) goto unlink; /* Get rid of temporary copy. */ - free_copy(info); + free_copy(&info); /* Done! */ trace_module_load(mod); - - return do_init_module(mod); + return mod; unlink: mutex_lock(&module_mutex); @@ -3221,7 +3074,7 @@ static int load_module(struct load_info *info, const char __user *uargs, module_bug_cleanup(mod); wake_up_all(&module_wq); ddebug: - dynamic_debug_remove(info->debug); + dynamic_debug_remove(info.debug); unlock: mutex_unlock(&module_mutex); synchronize_sched(); @@ -3233,52 +3086,106 @@ static int load_module(struct load_info *info, const char __user *uargs, free_unload: module_unload_free(mod); free_module: - module_deallocate(mod, info); + module_deallocate(mod, &info); free_copy: - free_copy(info); - return err; + free_copy(&info); + return ERR_PTR(err); +} + +/* Call module constructors. */ +static void do_mod_ctors(struct module *mod) +{ +#ifdef CONFIG_CONSTRUCTORS + unsigned long i; + + for (i = 0; i < mod->num_ctors; i++) + mod->ctors[i](); +#endif } +/* This is where the real work happens */ SYSCALL_DEFINE3(init_module, void __user *, umod, unsigned long, len, const char __user *, uargs) { - int err; - struct load_info info = { }; + struct module *mod; + int ret = 0; - err = may_init_module(); - if (err) - return err; + /* Must have permission */ + if (!capable(CAP_SYS_MODULE) || modules_disabled) + return -EPERM; - pr_debug("init_module: umod=%p, len=%lu, uargs=%p\n", - umod, len, uargs); + /* Do all the hard work */ + mod = load_module(umod, len, uargs); + if (IS_ERR(mod)) + return PTR_ERR(mod); - err = copy_module_from_user(umod, len, &info); - if (err) - return err; + blocking_notifier_call_chain(&module_notify_list, + MODULE_STATE_COMING, mod); - return load_module(&info, uargs, 0); -} + /* Set RO and NX regions for core */ + set_section_ro_nx(mod->module_core, + mod->core_text_size, + mod->core_ro_size, + mod->core_size); -SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags) -{ - int err; - struct load_info info = { }; + /* Set RO and NX regions for init */ + set_section_ro_nx(mod->module_init, + mod->init_text_size, + mod->init_ro_size, + mod->init_size); - err = may_init_module(); - if (err) - return err; + do_mod_ctors(mod); + /* Start the module */ + if (mod->init != NULL) + ret = do_one_initcall(mod->init); + if (ret < 0) { + /* Init routine failed: abort. Try to protect us from + buggy refcounters. */ + mod->state = MODULE_STATE_GOING; + synchronize_sched(); + module_put(mod); + blocking_notifier_call_chain(&module_notify_list, + MODULE_STATE_GOING, mod); + free_module(mod); + wake_up_all(&module_wq); + return ret; + } + if (ret > 0) { + printk(KERN_WARNING +"%s: '%s'->init suspiciously returned %d, it should follow 0/-E convention\n" +"%s: loading module anyway...\n", + __func__, mod->name, ret, + __func__); + dump_stack(); + } - pr_debug("finit_module: fd=%d, uargs=%p, flags=%i\n", fd, uargs, flags); + /* Now it's a first class citizen! */ + mod->state = MODULE_STATE_LIVE; + blocking_notifier_call_chain(&module_notify_list, + MODULE_STATE_LIVE, mod); - if (flags & ~(MODULE_INIT_IGNORE_MODVERSIONS - |MODULE_INIT_IGNORE_VERMAGIC)) - return -EINVAL; + /* We need to finish all async code before the module init sequence is done */ + async_synchronize_full(); - err = copy_module_from_fd(fd, &info); - if (err) - return err; + mutex_lock(&module_mutex); + /* Drop initial reference. */ + module_put(mod); + trim_init_extable(mod); +#ifdef CONFIG_KALLSYMS + mod->num_symtab = mod->core_num_syms; + mod->symtab = mod->core_symtab; + mod->strtab = mod->core_strtab; +#endif + unset_module_init_ro_nx(mod); + module_free(mod, mod->module_init); + mod->module_init = NULL; + mod->init_size = 0; + mod->init_ro_size = 0; + mod->init_text_size = 0; + mutex_unlock(&module_mutex); + wake_up_all(&module_wq); - return load_module(&info, uargs, flags); + return 0; } static inline int within(unsigned long addr, void *start, unsigned long size) diff --git a/trunk/kernel/posix-cpu-timers.c b/trunk/kernel/posix-cpu-timers.c index a278cad1d5d6..d73840271dce 100644 --- a/trunk/kernel/posix-cpu-timers.c +++ b/trunk/kernel/posix-cpu-timers.c @@ -9,7 +9,6 @@ #include #include #include -#include /* * Called after updating RLIMIT_CPU to run cpu timer and update @@ -471,8 +470,6 @@ static void cleanup_timers(struct list_head *head, */ void posix_cpu_timers_exit(struct task_struct *tsk) { - add_device_randomness((const void*) &tsk->se.sum_exec_runtime, - sizeof(unsigned long long)); cleanup_timers(tsk->cpu_timers, tsk->utime, tsk->stime, tsk->se.sum_exec_runtime); diff --git a/trunk/kernel/sys_ni.c b/trunk/kernel/sys_ni.c index 395084d4ce16..dbff751e4086 100644 --- a/trunk/kernel/sys_ni.c +++ b/trunk/kernel/sys_ni.c @@ -25,7 +25,6 @@ cond_syscall(sys_swapoff); cond_syscall(sys_kexec_load); cond_syscall(compat_sys_kexec_load); cond_syscall(sys_init_module); -cond_syscall(sys_finit_module); cond_syscall(sys_delete_module); cond_syscall(sys_socketpair); cond_syscall(sys_bind); diff --git a/trunk/kernel/watchdog.c b/trunk/kernel/watchdog.c index 75a2ab3d0b02..997c6a16ec22 100644 --- a/trunk/kernel/watchdog.c +++ b/trunk/kernel/watchdog.c @@ -344,10 +344,6 @@ static void watchdog_enable(unsigned int cpu) { struct hrtimer *hrtimer = &__raw_get_cpu_var(watchdog_hrtimer); - /* kick off the timer for the hardlockup detector */ - hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - hrtimer->function = watchdog_timer_fn; - if (!watchdog_enabled) { kthread_park(current); return; @@ -356,6 +352,10 @@ static void watchdog_enable(unsigned int cpu) /* Enable the perf event */ watchdog_nmi_enable(cpu); + /* kick off the timer for the hardlockup detector */ + hrtimer_init(hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + hrtimer->function = watchdog_timer_fn; + /* done here because hrtimer_start can only pin to smp_processor_id() */ hrtimer_start(hrtimer, ns_to_ktime(sample_period), HRTIMER_MODE_REL_PINNED); @@ -369,6 +369,9 @@ static void watchdog_disable(unsigned int cpu) { struct hrtimer *hrtimer = &__raw_get_cpu_var(watchdog_hrtimer); + if (!watchdog_enabled) + return; + watchdog_set_prio(SCHED_NORMAL, 0); hrtimer_cancel(hrtimer); /* disable the perf event */ diff --git a/trunk/lib/asn1_decoder.c b/trunk/lib/asn1_decoder.c index 11b9b01fda6b..5293d2433029 100644 --- a/trunk/lib/asn1_decoder.c +++ b/trunk/lib/asn1_decoder.c @@ -81,7 +81,7 @@ static int asn1_find_indefinite_length(const unsigned char *data, size_t datalen goto next_tag; } - if (unlikely((tag & 0x1f) == ASN1_LONG_TAG)) { + if (unlikely((tag & 0x1f) == 0x1f)) { do { if (unlikely(datalen - dp < 2)) goto data_overrun_error; @@ -96,7 +96,7 @@ static int asn1_find_indefinite_length(const unsigned char *data, size_t datalen goto next_tag; } - if (unlikely(len == ASN1_INDEFINITE_LENGTH)) { + if (unlikely(len == 0x80)) { /* Indefinite length */ if (unlikely((tag & ASN1_CONS_BIT) == ASN1_PRIM << 5)) goto indefinite_len_primitive; @@ -222,7 +222,7 @@ int asn1_ber_decoder(const struct asn1_decoder *decoder, if (unlikely(dp >= datalen - 1)) goto data_overrun_error; tag = data[dp++]; - if (unlikely((tag & 0x1f) == ASN1_LONG_TAG)) + if (unlikely((tag & 0x1f) == 0x1f)) goto long_tag_not_supported; if (op & ASN1_OP_MATCH__ANY) { @@ -254,7 +254,7 @@ int asn1_ber_decoder(const struct asn1_decoder *decoder, len = data[dp++]; if (len > 0x7f) { - if (unlikely(len == ASN1_INDEFINITE_LENGTH)) { + if (unlikely(len == 0x80)) { /* Indefinite length */ if (unlikely(!(tag & ASN1_CONS_BIT))) goto indefinite_len_primitive; diff --git a/trunk/scripts/Makefile.modsign b/trunk/scripts/Makefile.modsign deleted file mode 100644 index abfda626dbad..000000000000 --- a/trunk/scripts/Makefile.modsign +++ /dev/null @@ -1,32 +0,0 @@ -# ========================================================================== -# Signing modules -# ========================================================================== - -PHONY := __modsign -__modsign: - -include scripts/Kbuild.include - -__modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod))) -modules := $(patsubst %.o,%.ko,$(wildcard $(__modules:.ko=.o))) - -PHONY += $(modules) -__modsign: $(modules) - @: - -quiet_cmd_sign_ko = SIGN [M] $(2)/$(notdir $@) - cmd_sign_ko = $(mod_sign_cmd) $(2)/$(notdir $@) - -# Modules built outside the kernel source tree go into extra by default -INSTALL_MOD_DIR ?= extra -ext-mod-dir = $(INSTALL_MOD_DIR)$(subst $(patsubst %/,%,$(KBUILD_EXTMOD)),,$(@D)) - -modinst_dir = $(if $(KBUILD_EXTMOD),$(ext-mod-dir),kernel/$(@D)) - -$(modules): - $(call cmd,sign_ko,$(MODLIB)/$(modinst_dir)) - -# Declare the contents of the .PHONY variable as phony. We keep that -# information in a variable se we can use it in if_changed and friends. - -.PHONY: $(PHONY) diff --git a/trunk/security/capability.c b/trunk/security/capability.c index 0fe5a026aef8..b14a30c234b8 100644 --- a/trunk/security/capability.c +++ b/trunk/security/capability.c @@ -395,11 +395,6 @@ static int cap_kernel_module_request(char *kmod_name) return 0; } -static int cap_kernel_module_from_file(struct file *file) -{ - return 0; -} - static int cap_task_setpgid(struct task_struct *p, pid_t pgid) { return 0; @@ -972,7 +967,6 @@ void __init security_fixup_ops(struct security_operations *ops) set_to_cap_if_null(ops, kernel_act_as); set_to_cap_if_null(ops, kernel_create_files_as); set_to_cap_if_null(ops, kernel_module_request); - set_to_cap_if_null(ops, kernel_module_from_file); set_to_cap_if_null(ops, task_fix_setuid); set_to_cap_if_null(ops, task_setpgid); set_to_cap_if_null(ops, task_getpgid); diff --git a/trunk/security/integrity/ima/ima.h b/trunk/security/integrity/ima/ima.h index 3b2adb794f15..6ee8826662cc 100644 --- a/trunk/security/integrity/ima/ima.h +++ b/trunk/security/integrity/ima/ima.h @@ -127,7 +127,7 @@ struct integrity_iint_cache *integrity_iint_insert(struct inode *inode); struct integrity_iint_cache *integrity_iint_find(struct inode *inode); /* IMA policy related functions */ -enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK, MODULE_CHECK, POST_SETATTR }; +enum ima_hooks { FILE_CHECK = 1, FILE_MMAP, BPRM_CHECK, POST_SETATTR }; int ima_match_policy(struct inode *inode, enum ima_hooks func, int mask, int flags); diff --git a/trunk/security/integrity/ima/ima_api.c b/trunk/security/integrity/ima/ima_api.c index 0cea3db21657..b356884fb3ef 100644 --- a/trunk/security/integrity/ima/ima_api.c +++ b/trunk/security/integrity/ima/ima_api.c @@ -100,12 +100,12 @@ void ima_add_violation(struct inode *inode, const unsigned char *filename, * ima_get_action - appraise & measure decision based on policy. * @inode: pointer to inode to measure * @mask: contains the permission mask (MAY_READ, MAY_WRITE, MAY_EXECUTE) - * @function: calling function (FILE_CHECK, BPRM_CHECK, FILE_MMAP, MODULE_CHECK) + * @function: calling function (FILE_CHECK, BPRM_CHECK, FILE_MMAP) * * The policy is defined in terms of keypairs: * subj=, obj=, type=, func=, mask=, fsmagic= * subj,obj, and type: are LSM specific. - * func: FILE_CHECK | BPRM_CHECK | FILE_MMAP | MODULE_CHECK + * func: FILE_CHECK | BPRM_CHECK | FILE_MMAP * mask: contains the permission mask * fsmagic: hex value * diff --git a/trunk/security/integrity/ima/ima_main.c b/trunk/security/integrity/ima/ima_main.c index 45de18e9a6f2..73c9a268253e 100644 --- a/trunk/security/integrity/ima/ima_main.c +++ b/trunk/security/integrity/ima/ima_main.c @@ -280,27 +280,6 @@ int ima_file_check(struct file *file, int mask) } EXPORT_SYMBOL_GPL(ima_file_check); -/** - * ima_module_check - based on policy, collect/store/appraise measurement. - * @file: pointer to the file to be measured/appraised - * - * Measure/appraise kernel modules based on policy. - * - * Always return 0 and audit dentry_open failures. - * Return code is based upon measurement appraisal. - */ -int ima_module_check(struct file *file) -{ - int rc; - - if (!file) - rc = INTEGRITY_UNKNOWN; - else - rc = process_measurement(file, file->f_dentry->d_name.name, - MAY_EXEC, MODULE_CHECK); - return (ima_appraise & IMA_APPRAISE_ENFORCE) ? rc : 0; -} - static int __init init_ima(void) { int error; diff --git a/trunk/security/integrity/ima/ima_policy.c b/trunk/security/integrity/ima/ima_policy.c index af7d182d5a46..c7dacd2eab7a 100644 --- a/trunk/security/integrity/ima/ima_policy.c +++ b/trunk/security/integrity/ima/ima_policy.c @@ -80,7 +80,6 @@ static struct ima_rule_entry default_rules[] = { .flags = IMA_FUNC | IMA_MASK}, {.action = MEASURE,.func = FILE_CHECK,.mask = MAY_READ,.uid = GLOBAL_ROOT_UID, .flags = IMA_FUNC | IMA_MASK | IMA_UID}, - {.action = MEASURE,.func = MODULE_CHECK, .flags = IMA_FUNC}, }; static struct ima_rule_entry default_appraise_rules[] = { @@ -402,8 +401,6 @@ static int ima_parse_rule(char *rule, struct ima_rule_entry *entry) /* PATH_CHECK is for backwards compat */ else if (strcmp(args[0].from, "PATH_CHECK") == 0) entry->func = FILE_CHECK; - else if (strcmp(args[0].from, "MODULE_CHECK") == 0) - entry->func = MODULE_CHECK; else if (strcmp(args[0].from, "FILE_MMAP") == 0) entry->func = FILE_MMAP; else if (strcmp(args[0].from, "BPRM_CHECK") == 0) diff --git a/trunk/security/security.c b/trunk/security/security.c index daa97f4ac9d1..8dcd4ae10a5f 100644 --- a/trunk/security/security.c +++ b/trunk/security/security.c @@ -820,16 +820,6 @@ int security_kernel_module_request(char *kmod_name) return security_ops->kernel_module_request(kmod_name); } -int security_kernel_module_from_file(struct file *file) -{ - int ret; - - ret = security_ops->kernel_module_from_file(file); - if (ret) - return ret; - return ima_module_check(file); -} - int security_task_fix_setuid(struct cred *new, const struct cred *old, int flags) {