diff options
Diffstat (limited to 'arch/arm')
103 files changed, 1791 insertions, 1285 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 2f88d8d9770..117e81b1200 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -16,6 +16,7 @@ config ARM  	select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL  	select HAVE_ARCH_KGDB  	select HAVE_ARCH_TRACEHOOK +	select HAVE_SYSCALL_TRACEPOINTS  	select HAVE_KPROBES if !XIP_KERNEL  	select HAVE_KRETPROBES if (HAVE_KPROBES)  	select HAVE_FUNCTION_TRACER if (!XIP_KERNEL) @@ -1413,6 +1414,16 @@ config PL310_ERRATA_769419  	  on systems with an outer cache, the store buffer is drained  	  explicitly. +config ARM_ERRATA_775420 +       bool "ARM errata: A data cache maintenance operation which aborts, might lead to deadlock" +       depends on CPU_V7 +       help +	 This option enables the workaround for the 775420 Cortex-A9 (r2p2, +	 r2p6,r2p8,r2p10,r3p0) erratum. In case a date cache maintenance +	 operation aborts with MMU exception, it might cause the processor +	 to deadlock. This workaround puts DSB before executing ISB if +	 an abort may occur on cache maintenance. +  endmenu  source "arch/arm/common/Kconfig" @@ -1849,8 +1860,8 @@ config ALIGNMENT_TRAP  	  configuration it is safe to say N, otherwise say Y.  config UACCESS_WITH_MEMCPY -	bool "Use kernel mem{cpy,set}() for {copy_to,clear}_user() (EXPERIMENTAL)" -	depends on MMU && EXPERIMENTAL +	bool "Use kernel mem{cpy,set}() for {copy_to,clear}_user()" +	depends on MMU  	default y if CPU_FEROCEON  	help  	  Implement faster copy_to_user and clear_user methods for CPU @@ -1891,12 +1902,6 @@ config CC_STACKPROTECTOR  	  neutralized via a kernel panic.  	  This feature requires gcc version 4.2 or above. -config DEPRECATED_PARAM_STRUCT -	bool "Provide old way to pass kernel parameters" -	help -	  This was deprecated in 2001 and announced to live on for 5 years. -	  Some old boot loaders still use this way. -  endmenu  menu "Boot options" @@ -1909,6 +1914,23 @@ config USE_OF  	help  	  Include support for flattened device tree machine descriptions. +config ATAGS +	bool "Support for the traditional ATAGS boot data passing" if USE_OF +	default y +	help +	  This is the traditional way of passing data to the kernel at boot +	  time. If you are solely relying on the flattened device tree (or +	  the ARM_ATAG_DTB_COMPAT option) then you may unselect this option +	  to remove ATAGS support from your kernel binary.  If unsure, +	  leave this to y. + +config DEPRECATED_PARAM_STRUCT +	bool "Provide old way to pass kernel parameters" +	depends on ATAGS +	help +	  This was deprecated in 2001 and announced to live on for 5 years. +	  Some old boot loaders still use this way. +  # Compressed boot loader in ROM.  Yes, we really want to ask about  # TEXT and BSS so we preserve their values in the config files.  config ZBOOT_ROM_TEXT @@ -2035,6 +2057,7 @@ config CMDLINE  choice  	prompt "Kernel command line type" if CMDLINE != ""  	default CMDLINE_FROM_BOOTLOADER +	depends on ATAGS  config CMDLINE_FROM_BOOTLOADER  	bool "Use bootloader kernel arguments if available" @@ -2104,7 +2127,7 @@ config KEXEC  config ATAGS_PROC  	bool "Export atags in procfs" -	depends on KEXEC +	depends on ATAGS && KEXEC  	default y  	help  	  Should the atags used to boot the kernel be exported in an "atags" diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index f15f82bf3a5..e968a52e488 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -356,15 +356,15 @@ choice  		  is nothing connected to read from the DCC.  	config DEBUG_SEMIHOSTING -		bool "Kernel low-level debug output via semihosting I" +		bool "Kernel low-level debug output via semihosting I/O"  		help  		  Semihosting enables code running on an ARM target to use  		  the I/O facilities on a host debugger/emulator through a -		  simple SVC calls. The host debugger or emulator must have +		  simple SVC call. The host debugger or emulator must have  		  semihosting enabled for the special svc call to be trapped  		  otherwise the kernel will crash. -		  This is known to work with OpenOCD, as wellas +		  This is known to work with OpenOCD, as well as  		  ARM's Fast Models, or any other controlling environment  		  that implements semihosting. diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 30eae87ead6..361936a3d19 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -268,7 +268,12 @@ else  KBUILD_IMAGE := zImage  endif -all:	$(KBUILD_IMAGE) +# Build the DT binary blobs if we have OF configured +ifeq ($(CONFIG_USE_OF),y) +KBUILD_DTBS := dtbs +endif + +all:	$(KBUILD_IMAGE) $(KBUILD_DTBS)  boot := arch/arm/boot @@ -284,10 +289,10 @@ zImage Image xipImage bootpImage uImage: vmlinux  zinstall uinstall install: vmlinux  	$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $@ -%.dtb: +%.dtb: scripts  	$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@ -dtbs: +dtbs: scripts  	$(Q)$(MAKE) $(build)=$(boot) MACHINE=$(MACHINE) $(boot)/$@  # We use MRPROPER_FILES and CLEAN_FILES now @@ -306,7 +311,7 @@ define archhelp    echo  '  uImage        - U-Boot wrapped zImage'    echo  '  bootpImage    - Combined zImage and initial RAM disk'     echo  '                  (supply initrd image via make variable INITRD=<path>)' -  echo  '  dtbs          - Build device tree blobs for enabled boards' +  echo  '* dtbs          - Build device tree blobs for enabled boards'    echo  '  install       - Install uncompressed kernel'    echo  '  zinstall      - Install compressed kernel'    echo  '  uinstall      - Install U-Boot wrapped compressed kernel' diff --git a/arch/arm/boot/compressed/decompress.c b/arch/arm/boot/compressed/decompress.c index f41b38cafce..9deb56a702c 100644 --- a/arch/arm/boot/compressed/decompress.c +++ b/arch/arm/boot/compressed/decompress.c @@ -32,6 +32,9 @@ extern void error(char *);  #  define Tracecv(c,x)  #endif +/* Not needed, but used in some headers pulled in by decompressors */ +extern char * strstr(const char * s1, const char *s2); +  #ifdef CONFIG_KERNEL_GZIP  #include "../../../../lib/decompress_inflate.c"  #endif diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index b8c64b80baf..bc67cbff394 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -653,16 +653,21 @@ __armv7_mmu_cache_on:  		mcrne	p15, 0, r0, c8, c7, 0	@ flush I,D TLBs  #endif  		mrc	p15, 0, r0, c1, c0, 0	@ read control reg +		bic	r0, r0, #1 << 28	@ clear SCTLR.TRE  		orr	r0, r0, #0x5000		@ I-cache enable, RR cache replacement  		orr	r0, r0, #0x003c		@ write buffer  #ifdef CONFIG_MMU  #ifdef CONFIG_CPU_ENDIAN_BE8  		orr	r0, r0, #1 << 25	@ big-endian page tables  #endif +		mrcne   p15, 0, r6, c2, c0, 2   @ read ttb control reg  		orrne	r0, r0, #1		@ MMU enabled  		movne	r1, #0xfffffffd		@ domain 0 = client +		bic     r6, r6, #1 << 31        @ 32-bit translation system +		bic     r6, r6, #3 << 0         @ use only ttbr0  		mcrne	p15, 0, r3, c2, c0, 0	@ load page table pointer  		mcrne	p15, 0, r1, c3, c0, 0	@ load domain access control +		mcrne   p15, 0, r6, c2, c0, 2   @ load ttb control  #endif  		mcr	p15, 0, r0, c7, c5, 4	@ ISB  		mcr	p15, 0, r0, c1, c0, 0	@ load control register diff --git a/arch/arm/boot/dts/at91sam9260.dtsi b/arch/arm/boot/dts/at91sam9260.dtsi index 66389c1c6f6..7c95f76398d 100644 --- a/arch/arm/boot/dts/at91sam9260.dtsi +++ b/arch/arm/boot/dts/at91sam9260.dtsi @@ -104,6 +104,7 @@  				#gpio-cells = <2>;  				gpio-controller;  				interrupt-controller; +				#interrupt-cells = <2>;  			};  			pioB: gpio@fffff600 { @@ -113,6 +114,7 @@  				#gpio-cells = <2>;  				gpio-controller;  				interrupt-controller; +				#interrupt-cells = <2>;  			};  			pioC: gpio@fffff800 { @@ -122,6 +124,7 @@  				#gpio-cells = <2>;  				gpio-controller;  				interrupt-controller; +				#interrupt-cells = <2>;  			};  			dbgu: serial@fffff200 { diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi index b460d6ce9eb..195019b7ca0 100644 --- a/arch/arm/boot/dts/at91sam9263.dtsi +++ b/arch/arm/boot/dts/at91sam9263.dtsi @@ -95,6 +95,7 @@  				#gpio-cells = <2>;  				gpio-controller;  				interrupt-controller; +				#interrupt-cells = <2>;  			};  			pioB: gpio@fffff400 { @@ -104,6 +105,7 @@  				#gpio-cells = <2>;  				gpio-controller;  				interrupt-controller; +				#interrupt-cells = <2>;  			};  			pioC: gpio@fffff600 { @@ -113,6 +115,7 @@  				#gpio-cells = <2>;  				gpio-controller;  				interrupt-controller; +				#interrupt-cells = <2>;  			};  			pioD: gpio@fffff800 { @@ -122,6 +125,7 @@  				#gpio-cells = <2>;  				gpio-controller;  				interrupt-controller; +				#interrupt-cells = <2>;  			};  			pioE: gpio@fffffa00 { @@ -131,6 +135,7 @@  				#gpio-cells = <2>;  				gpio-controller;  				interrupt-controller; +				#interrupt-cells = <2>;  			};  			dbgu: serial@ffffee00 { diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi index bafa8806fc1..63751b1e744 100644 --- a/arch/arm/boot/dts/at91sam9g45.dtsi +++ b/arch/arm/boot/dts/at91sam9g45.dtsi @@ -113,6 +113,7 @@  				#gpio-cells = <2>;  				gpio-controller;  				interrupt-controller; +				#interrupt-cells = <2>;  			};  			pioB: gpio@fffff400 { @@ -122,6 +123,7 @@  				#gpio-cells = <2>;  				gpio-controller;  				interrupt-controller; +				#interrupt-cells = <2>;  			};  			pioC: gpio@fffff600 { @@ -131,6 +133,7 @@  				#gpio-cells = <2>;  				gpio-controller;  				interrupt-controller; +				#interrupt-cells = <2>;  			};  			pioD: gpio@fffff800 { @@ -140,6 +143,7 @@  				#gpio-cells = <2>;  				gpio-controller;  				interrupt-controller; +				#interrupt-cells = <2>;  			};  			pioE: gpio@fffffa00 { @@ -149,6 +153,7 @@  				#gpio-cells = <2>;  				gpio-controller;  				interrupt-controller; +				#interrupt-cells = <2>;  			};  			dbgu: serial@ffffee00 { diff --git a/arch/arm/boot/dts/at91sam9n12.dtsi b/arch/arm/boot/dts/at91sam9n12.dtsi index bfac0dfc332..ef9336ae961 100644 --- a/arch/arm/boot/dts/at91sam9n12.dtsi +++ b/arch/arm/boot/dts/at91sam9n12.dtsi @@ -107,6 +107,7 @@  				#gpio-cells = <2>;  				gpio-controller;  				interrupt-controller; +				#interrupt-cells = <2>;  			};  			pioB: gpio@fffff600 { @@ -116,6 +117,7 @@  				#gpio-cells = <2>;  				gpio-controller;  				interrupt-controller; +				#interrupt-cells = <2>;  			};  			pioC: gpio@fffff800 { @@ -125,6 +127,7 @@  				#gpio-cells = <2>;  				gpio-controller;  				interrupt-controller; +				#interrupt-cells = <2>;  			};  			pioD: gpio@fffffa00 { @@ -134,6 +137,7 @@  				#gpio-cells = <2>;  				gpio-controller;  				interrupt-controller; +				#interrupt-cells = <2>;  			};  			dbgu: serial@fffff200 { diff --git a/arch/arm/boot/dts/at91sam9x5.dtsi b/arch/arm/boot/dts/at91sam9x5.dtsi index 4a18c393b13..8a387a8d61b 100644 --- a/arch/arm/boot/dts/at91sam9x5.dtsi +++ b/arch/arm/boot/dts/at91sam9x5.dtsi @@ -115,6 +115,7 @@  				#gpio-cells = <2>;  				gpio-controller;  				interrupt-controller; +				#interrupt-cells = <2>;  			};  			pioB: gpio@fffff600 { @@ -124,6 +125,7 @@  				#gpio-cells = <2>;  				gpio-controller;  				interrupt-controller; +				#interrupt-cells = <2>;  			};  			pioC: gpio@fffff800 { @@ -133,6 +135,7 @@  				#gpio-cells = <2>;  				gpio-controller;  				interrupt-controller; +				#interrupt-cells = <2>;  			};  			pioD: gpio@fffffa00 { @@ -142,6 +145,7 @@  				#gpio-cells = <2>;  				gpio-controller;  				interrupt-controller; +				#interrupt-cells = <2>;  			};  			dbgu: serial@fffff200 { diff --git a/arch/arm/boot/dts/integrator.dtsi b/arch/arm/boot/dts/integrator.dtsi new file mode 100644 index 00000000000..813b91d7bea --- /dev/null +++ b/arch/arm/boot/dts/integrator.dtsi @@ -0,0 +1,76 @@ +/* + * SoC core Device Tree for the ARM Integrator platforms + */ + +/include/ "skeleton.dtsi" + +/ { +	timer@13000000 { +		reg = <0x13000000 0x100>; +		interrupt-parent = <&pic>; +		interrupts = <5>; +	}; + +	timer@13000100 { +		reg = <0x13000100 0x100>; +		interrupt-parent = <&pic>; +		interrupts = <6>; +	}; + +	timer@13000200 { +		reg = <0x13000200 0x100>; +		interrupt-parent = <&pic>; +		interrupts = <7>; +	}; + +	pic@14000000 { +		compatible = "arm,versatile-fpga-irq"; +		#interrupt-cells = <1>; +		interrupt-controller; +		reg = <0x14000000 0x100>; +		clear-mask = <0xffffffff>; +	}; + +	flash@24000000 { +		compatible = "cfi-flash"; +		reg = <0x24000000 0x02000000>; +	}; + +	fpga { +		compatible = "arm,amba-bus", "simple-bus"; +		#address-cells = <1>; +		#size-cells = <1>; +		ranges; +		interrupt-parent = <&pic>; + +		/* +		 * These PrimeCells are in the same locations and using the +		 * same interrupts in all Integrators, however the silicon +		 * version deployed is different. +		 */ +		rtc@15000000 { +			reg = <0x15000000 0x1000>; +			interrupts = <8>; +		}; + +		uart@16000000 { +			reg = <0x16000000 0x1000>; +			interrupts = <1>; +		}; + +		uart@17000000 { +			reg = <0x17000000 0x1000>; +			interrupts = <2>; +		}; + +		kmi@18000000 { +			reg = <0x18000000 0x1000>; +			interrupts = <3>; +		}; + +		kmi@19000000 { +			reg = <0x19000000 0x1000>; +			interrupts = <4>; +		}; +	}; +}; diff --git a/arch/arm/boot/dts/integratorap.dts b/arch/arm/boot/dts/integratorap.dts new file mode 100644 index 00000000000..61767757b50 --- /dev/null +++ b/arch/arm/boot/dts/integratorap.dts @@ -0,0 +1,68 @@ +/* + * Device Tree for the ARM Integrator/AP platform + */ + +/dts-v1/; +/include/ "integrator.dtsi" + +/ { +	model = "ARM Integrator/AP"; +	compatible = "arm,integrator-ap"; + +	aliases { +		arm,timer-primary = &timer2; +		arm,timer-secondary = &timer1; +	}; + +	chosen { +		bootargs = "root=/dev/ram0 console=ttyAM0,38400n8 earlyprintk"; +	}; + +	timer0: timer@13000000 { +		compatible = "arm,integrator-timer"; +	}; + +	timer1: timer@13000100 { +		compatible = "arm,integrator-timer"; +	}; + +	timer2: timer@13000200 { +		compatible = "arm,integrator-timer"; +	}; + +	pic: pic@14000000 { +		valid-mask = <0x003fffff>; +	}; + +	fpga { +		/* +		 * The Integator/AP predates the idea to have magic numbers +		 * identifying the PrimeCell in hardware, thus we have to +		 * supply these from the device tree. +		 */ +		rtc: rtc@15000000 { +			compatible = "arm,pl030", "arm,primecell"; +			arm,primecell-periphid = <0x00041030>; +		}; + +		uart0: uart@16000000 { +			compatible = "arm,pl010", "arm,primecell"; +			arm,primecell-periphid = <0x00041010>; +		}; + +		uart1: uart@17000000 { +			compatible = "arm,pl010", "arm,primecell"; +			arm,primecell-periphid = <0x00041010>; +		}; + +		kmi0: kmi@18000000 { +			compatible = "arm,pl050", "arm,primecell"; +			arm,primecell-periphid = <0x00041050>; +		}; + +		kmi1: kmi@19000000 { +			compatible = "arm,pl050", "arm,primecell"; +			arm,primecell-periphid = <0x00041050>; +		}; +	}; +}; diff --git a/arch/arm/boot/dts/integratorcp.dts b/arch/arm/boot/dts/integratorcp.dts new file mode 100644 index 00000000000..2dd5e4e4848 --- /dev/null +++ b/arch/arm/boot/dts/integratorcp.dts @@ -0,0 +1,110 @@ +/* + * Device Tree for the ARM Integrator/CP platform + */ + +/dts-v1/; +/include/ "integrator.dtsi" + +/ { +	model = "ARM Integrator/CP"; +	compatible = "arm,integrator-cp"; + +	aliases { +		arm,timer-primary = &timer2; +		arm,timer-secondary = &timer1; +	}; + +	chosen { +		bootargs = "root=/dev/ram0 console=ttyAMA0,38400n8 earlyprintk"; +	}; + +	timer0: timer@13000000 { +		compatible = "arm,sp804", "arm,primecell"; +	}; + +	timer1: timer@13000100 { +		compatible = "arm,sp804", "arm,primecell"; +	}; + +	timer2: timer@13000200 { +		compatible = "arm,sp804", "arm,primecell"; +	}; + +	pic: pic@14000000 { +		valid-mask = <0x1fc003ff>; +	}; + +	cic: cic@10000040 { +		compatible = "arm,versatile-fpga-irq"; +		#interrupt-cells = <1>; +		interrupt-controller; +		reg = <0x10000040 0x100>; +		clear-mask = <0xffffffff>; +		valid-mask = <0x00000007>; +	}; + +	sic: sic@ca000000 { +		compatible = "arm,versatile-fpga-irq"; +		#interrupt-cells = <1>; +		interrupt-controller; +		reg = <0xca000000 0x100>; +		clear-mask = <0x00000fff>; +		valid-mask = <0x00000fff>; +	}; + +	ethernet@c8000000 { +		compatible = "smsc,lan91c111"; +		reg = <0xc8000000 0x10>; +		interrupt-parent = <&pic>; +		interrupts = <27>; +	}; + +	fpga { +		/* +		 * These PrimeCells are at the same location and using +		 * the same interrupts in all Integrators, but in the CP +		 * slightly newer versions are deployed. +		 */ +		rtc@15000000 { +			compatible = "arm,pl031", "arm,primecell"; +		}; + +		uart@16000000 { +			compatible = "arm,pl011", "arm,primecell"; +		}; + +		uart@17000000 { +			compatible = "arm,pl011", "arm,primecell"; +		}; + +		kmi@18000000 { +			compatible = "arm,pl050", "arm,primecell"; +		}; + +		kmi@19000000 { +			compatible = "arm,pl050", "arm,primecell"; +		}; + +		/* +		 * These PrimeCells are only available on the Integrator/CP +		 */ +		mmc@1c000000 { +			compatible = "arm,pl180", "arm,primecell"; +			reg = <0x1c000000 0x1000>; +			interrupts = <23 24>; +			max-frequency = <515633>; +		}; + +		aaci@1d000000 { +			compatible = "arm,pl041", "arm,primecell"; +			reg = <0x1d000000 0x1000>; +			interrupts = <25>; +		}; + +		clcd@c0000000 { +			compatible = "arm,pl110", "arm,primecell"; +			reg = <0xC0000000 0x1000>; +			interrupts = <22>; +		}; +	}; +}; diff --git a/arch/arm/include/asm/Kbuild b/arch/arm/include/asm/Kbuild index 960abceb8e1..8a7196ca510 100644 --- a/arch/arm/include/asm/Kbuild +++ b/arch/arm/include/asm/Kbuild @@ -5,16 +5,33 @@ header-y += hwcap.h  generic-y += auxvec.h  generic-y += bitsperlong.h  generic-y += cputime.h +generic-y += current.h  generic-y += emergency-restart.h  generic-y += errno.h +generic-y += exec.h  generic-y += ioctl.h +generic-y += ipcbuf.h  generic-y += irq_regs.h  generic-y += kdebug.h  generic-y += local.h  generic-y += local64.h +generic-y += msgbuf.h +generic-y += param.h +generic-y += parport.h  generic-y += percpu.h  generic-y += poll.h  generic-y += resource.h  generic-y += sections.h +generic-y += segment.h +generic-y += sembuf.h +generic-y += serial.h +generic-y += shmbuf.h  generic-y += siginfo.h  generic-y += sizes.h +generic-y += socket.h +generic-y += sockios.h +generic-y += termbits.h +generic-y += termios.h +generic-y += timex.h +generic-y += types.h +generic-y += unaligned.h diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h index 03fb93621d0..5c8b3bf4d82 100644 --- a/arch/arm/include/asm/assembler.h +++ b/arch/arm/include/asm/assembler.h @@ -320,4 +320,12 @@  	.size \name , . - \name  	.endm +	.macro check_uaccess, addr:req, size:req, limit:req, tmp:req, bad:req +#ifndef CONFIG_CPU_USE_DOMAINS +	adds	\tmp, \addr, #\size - 1 +	sbcccs	\tmp, \tmp, \limit +	bcs	\bad +#endif +	.endm +  #endif /* __ASM_ASSEMBLER_H__ */ diff --git a/arch/arm/include/asm/current.h b/arch/arm/include/asm/current.h deleted file mode 100644 index 75d21e2a3ff..00000000000 --- a/arch/arm/include/asm/current.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _ASMARM_CURRENT_H -#define _ASMARM_CURRENT_H - -#include <linux/thread_info.h> - -static inline struct task_struct *get_current(void) __attribute_const__; - -static inline struct task_struct *get_current(void) -{ -	return current_thread_info()->task; -} - -#define current (get_current()) - -#endif /* _ASMARM_CURRENT_H */ diff --git a/arch/arm/include/asm/exec.h b/arch/arm/include/asm/exec.h deleted file mode 100644 index 7c4fbef72b3..00000000000 --- a/arch/arm/include/asm/exec.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef __ASM_ARM_EXEC_H -#define __ASM_ARM_EXEC_H - -#define arch_align_stack(x) (x) - -#endif /* __ASM_ARM_EXEC_H */ diff --git a/arch/arm/include/asm/glue-cache.h b/arch/arm/include/asm/glue-cache.h index 7e30874377e..4f8d2c0dc44 100644 --- a/arch/arm/include/asm/glue-cache.h +++ b/arch/arm/include/asm/glue-cache.h @@ -110,19 +110,19 @@  #endif  #if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_V6K) -//# ifdef _CACHE +# ifdef _CACHE  #  define MULTI_CACHE 1 -//# else -//#  define _CACHE v6 -//# endif +# else +#  define _CACHE v6 +# endif  #endif  #if defined(CONFIG_CPU_V7) -//# ifdef _CACHE +# ifdef _CACHE  #  define MULTI_CACHE 1 -//# else -//#  define _CACHE v7 -//# endif +# else +#  define _CACHE v7 +# endif  #endif  #if !defined(_CACHE) && !defined(MULTI_CACHE) diff --git a/arch/arm/include/asm/hardirq.h b/arch/arm/include/asm/hardirq.h index 436e60b2cf7..2740c2a2df6 100644 --- a/arch/arm/include/asm/hardirq.h +++ b/arch/arm/include/asm/hardirq.h @@ -5,7 +5,7 @@  #include <linux/threads.h>  #include <asm/irq.h> -#define NR_IPI	5 +#define NR_IPI	6  typedef struct {  	unsigned int __softirq_pending; diff --git a/arch/arm/include/asm/hardware/linkup-l1110.h b/arch/arm/include/asm/hardware/linkup-l1110.h deleted file mode 100644 index 7ec91168a57..00000000000 --- a/arch/arm/include/asm/hardware/linkup-l1110.h +++ /dev/null @@ -1,48 +0,0 @@ -/* -* -* Definitions for H3600 Handheld Computer -* -* Copyright 2001 Compaq Computer Corporation. -* -* Use consistent with the GNU GPL is permitted, -* provided that this copyright notice is -* preserved in its entirety in all copies and derived works. -* -* COMPAQ COMPUTER CORPORATION MAKES NO WARRANTIES, EXPRESSED OR IMPLIED, -* AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS -* FITNESS FOR ANY PARTICULAR PURPOSE. -* -* Author: Jamey Hicks. -* -*/ - -/* LinkUp Systems PCCard/CompactFlash Interface for SA-1100 */ - -/* PC Card Status Register */ -#define LINKUP_PRS_S1	(1 << 0) /* voltage control bits S1-S4 */ -#define LINKUP_PRS_S2	(1 << 1) -#define LINKUP_PRS_S3	(1 << 2) -#define LINKUP_PRS_S4	(1 << 3) -#define LINKUP_PRS_BVD1	(1 << 4) -#define LINKUP_PRS_BVD2	(1 << 5) -#define LINKUP_PRS_VS1	(1 << 6) -#define LINKUP_PRS_VS2	(1 << 7) -#define LINKUP_PRS_RDY	(1 << 8) -#define LINKUP_PRS_CD1	(1 << 9) -#define LINKUP_PRS_CD2	(1 << 10) - -/* PC Card Command Register */ -#define LINKUP_PRC_S1	(1 << 0) -#define LINKUP_PRC_S2	(1 << 1) -#define LINKUP_PRC_S3	(1 << 2) -#define LINKUP_PRC_S4	(1 << 3) -#define LINKUP_PRC_RESET (1 << 4) -#define LINKUP_PRC_APOE	(1 << 5) /* Auto Power Off Enable: clears S1-S4 when either nCD goes high */ -#define LINKUP_PRC_CFE	(1 << 6) /* CompactFlash mode Enable: addresses A[10:0] only, A[25:11] high */ -#define LINKUP_PRC_SOE	(1 << 7) /* signal output driver enable */ -#define LINKUP_PRC_SSP	(1 << 8) /* sock select polarity: 0 for socket 0, 1 for socket 1 */ -#define LINKUP_PRC_MBZ	(1 << 15) /* must be zero */ - -struct linkup_l1110 { -	volatile short prc; -}; diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h index 815c669fec0..09c4628efbe 100644 --- a/arch/arm/include/asm/io.h +++ b/arch/arm/include/asm/io.h @@ -47,13 +47,68 @@ extern void __raw_readsb(const void __iomem *addr, void *data, int bytelen);  extern void __raw_readsw(const void __iomem *addr, void *data, int wordlen);  extern void __raw_readsl(const void __iomem *addr, void *data, int longlen); -#define __raw_writeb(v,a)	((void)(__chk_io_ptr(a), *(volatile unsigned char __force  *)(a) = (v))) -#define __raw_writew(v,a)	((void)(__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v))) -#define __raw_writel(v,a)	((void)(__chk_io_ptr(a), *(volatile unsigned int __force   *)(a) = (v))) +#if __LINUX_ARM_ARCH__ < 6 +/* + * Half-word accesses are problematic with RiscPC due to limitations of + * the bus. Rather than special-case the machine, just let the compiler + * generate the access for CPUs prior to ARMv6. + */ +#define __raw_readw(a)         (__chk_io_ptr(a), *(volatile unsigned short __force *)(a)) +#define __raw_writew(v,a)      ((void)(__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v))) +#else +/* + * When running under a hypervisor, we want to avoid I/O accesses with + * writeback addressing modes as these incur a significant performance + * overhead (the address generation must be emulated in software). + */ +static inline void __raw_writew(u16 val, volatile void __iomem *addr) +{ +	asm volatile("strh %1, %0" +		     : "+Qo" (*(volatile u16 __force *)addr) +		     : "r" (val)); +} + +static inline u16 __raw_readw(const volatile void __iomem *addr) +{ +	u16 val; +	asm volatile("ldrh %1, %0" +		     : "+Qo" (*(volatile u16 __force *)addr), +		       "=r" (val)); +	return val; +} +#endif -#define __raw_readb(a)		(__chk_io_ptr(a), *(volatile unsigned char __force  *)(a)) -#define __raw_readw(a)		(__chk_io_ptr(a), *(volatile unsigned short __force *)(a)) -#define __raw_readl(a)		(__chk_io_ptr(a), *(volatile unsigned int __force   *)(a)) +static inline void __raw_writeb(u8 val, volatile void __iomem *addr) +{ +	asm volatile("strb %1, %0" +		     : "+Qo" (*(volatile u8 __force *)addr) +		     : "r" (val)); +} + +static inline void __raw_writel(u32 val, volatile void __iomem *addr) +{ +	asm volatile("str %1, %0" +		     : "+Qo" (*(volatile u32 __force *)addr) +		     : "r" (val)); +} + +static inline u8 __raw_readb(const volatile void __iomem *addr) +{ +	u8 val; +	asm volatile("ldrb %1, %0" +		     : "+Qo" (*(volatile u8 __force *)addr), +		       "=r" (val)); +	return val; +} + +static inline u32 __raw_readl(const volatile void __iomem *addr) +{ +	u32 val; +	asm volatile("ldr %1, %0" +		     : "+Qo" (*(volatile u32 __force *)addr), +		       "=r" (val)); +	return val; +}  /*   * Architecture ioremap implementation. diff --git a/arch/arm/include/asm/ipcbuf.h b/arch/arm/include/asm/ipcbuf.h deleted file mode 100644 index 84c7e51cb6d..00000000000 --- a/arch/arm/include/asm/ipcbuf.h +++ /dev/null @@ -1 +0,0 @@ -#include <asm-generic/ipcbuf.h> diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index e965f1b560f..5f6ddcc5645 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h @@ -187,6 +187,7 @@ static inline unsigned long __phys_to_virt(unsigned long x)  #define __phys_to_virt(x)	((x) - PHYS_OFFSET + PAGE_OFFSET)  #endif  #endif +#endif /* __ASSEMBLY__ */  #ifndef PHYS_OFFSET  #ifdef PLAT_PHYS_OFFSET @@ -196,6 +197,8 @@ static inline unsigned long __phys_to_virt(unsigned long x)  #endif  #endif +#ifndef __ASSEMBLY__ +  /*   * PFNs are used to describe any physical page; this means   * PFN 0 == physical address 0. diff --git a/arch/arm/include/asm/msgbuf.h b/arch/arm/include/asm/msgbuf.h deleted file mode 100644 index 33b35b946ea..00000000000 --- a/arch/arm/include/asm/msgbuf.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef _ASMARM_MSGBUF_H -#define _ASMARM_MSGBUF_H - -/*  - * The msqid64_ds structure for arm architecture. - * Note extra padding because this structure is passed back and forth - * between kernel and user space. - * - * Pad space is left for: - * - 64-bit time_t to solve y2038 problem - * - 2 miscellaneous 32-bit values - */ - -struct msqid64_ds { -	struct ipc64_perm msg_perm; -	__kernel_time_t msg_stime;	/* last msgsnd time */ -	unsigned long	__unused1; -	__kernel_time_t msg_rtime;	/* last msgrcv time */ -	unsigned long	__unused2; -	__kernel_time_t msg_ctime;	/* last change time */ -	unsigned long	__unused3; -	unsigned long  msg_cbytes;	/* current number of bytes on queue */ -	unsigned long  msg_qnum;	/* number of messages in queue */ -	unsigned long  msg_qbytes;	/* max number of bytes on queue */ -	__kernel_pid_t msg_lspid;	/* pid of last msgsnd */ -	__kernel_pid_t msg_lrpid;	/* last receive pid */ -	unsigned long  __unused4; -	unsigned long  __unused5; -}; - -#endif /* _ASMARM_MSGBUF_H */ diff --git a/arch/arm/include/asm/mutex.h b/arch/arm/include/asm/mutex.h index b1479fd04a9..87c044910fe 100644 --- a/arch/arm/include/asm/mutex.h +++ b/arch/arm/include/asm/mutex.h @@ -9,8 +9,13 @@  #define _ASM_MUTEX_H  /*   * On pre-ARMv6 hardware this results in a swp-based implementation, - * which is the most efficient. For ARMv6+, we emit a pair of exclusive - * accesses instead. + * which is the most efficient. For ARMv6+, we have exclusive memory + * accessors and use atomic_dec to avoid the extra xchg operations + * on the locking slowpaths.   */ +#if __LINUX_ARM_ARCH__ < 6  #include <asm-generic/mutex-xchg.h> +#else +#include <asm-generic/mutex-dec.h>  #endif +#endif	/* _ASM_MUTEX_H */ diff --git a/arch/arm/include/asm/opcodes-virt.h b/arch/arm/include/asm/opcodes-virt.h new file mode 100644 index 00000000000..b85665a96f8 --- /dev/null +++ b/arch/arm/include/asm/opcodes-virt.h @@ -0,0 +1,29 @@ +/* + * opcodes-virt.h: Opcode definitions for the ARM virtualization extensions + * Copyright (C) 2012  Linaro Limited + * + * 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 __ASM_ARM_OPCODES_VIRT_H +#define __ASM_ARM_OPCODES_VIRT_H + +#include <asm/opcodes.h> + +#define __HVC(imm16) __inst_arm_thumb32(				\ +	0xE1400070 | (((imm16) & 0xFFF0) << 4) | ((imm16) & 0x000F),	\ +	0xF7E08000 | (((imm16) & 0xF000) << 4) | ((imm16) & 0x0FFF)	\ +) + +#endif /* ! __ASM_ARM_OPCODES_VIRT_H */ diff --git a/arch/arm/include/asm/opcodes.h b/arch/arm/include/asm/opcodes.h index 19c48deda70..74e211a6fb2 100644 --- a/arch/arm/include/asm/opcodes.h +++ b/arch/arm/include/asm/opcodes.h @@ -19,6 +19,33 @@ extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr);  /* + * Assembler opcode byteswap helpers. + * These are only intended for use by this header: don't use them directly, + * because they will be suboptimal in most cases. + */ +#define ___asm_opcode_swab32(x) (	\ +	  (((x) << 24) & 0xFF000000)	\ +	| (((x) <<  8) & 0x00FF0000)	\ +	| (((x) >>  8) & 0x0000FF00)	\ +	| (((x) >> 24) & 0x000000FF)	\ +) +#define ___asm_opcode_swab16(x) (	\ +	  (((x) << 8) & 0xFF00)		\ +	| (((x) >> 8) & 0x00FF)		\ +) +#define ___asm_opcode_swahb32(x) (	\ +	  (((x) << 8) & 0xFF00FF00)	\ +	| (((x) >> 8) & 0x00FF00FF)	\ +) +#define ___asm_opcode_swahw32(x) (	\ +	  (((x) << 16) & 0xFFFF0000)	\ +	| (((x) >> 16) & 0x0000FFFF)	\ +) +#define ___asm_opcode_identity32(x) ((x) & 0xFFFFFFFF) +#define ___asm_opcode_identity16(x) ((x) & 0xFFFF) + + +/*   * Opcode byteswap helpers   *   * These macros help with converting instructions between a canonical integer @@ -41,39 +68,163 @@ extern asmlinkage unsigned int arm_check_condition(u32 opcode, u32 psr);   * Note that values in the range 0x0000E800..0xE7FFFFFF intentionally do not   * represent any valid Thumb-2 instruction.  For this range,   * __opcode_is_thumb32() and __opcode_is_thumb16() will both be false. + * + * The ___asm variants are intended only for use by this header, in situations + * involving inline assembler.  For .S files, the normal __opcode_*() macros + * should do the right thing.   */ +#ifdef __ASSEMBLY__ -#ifndef __ASSEMBLY__ +#define ___opcode_swab32(x) ___asm_opcode_swab32(x) +#define ___opcode_swab16(x) ___asm_opcode_swab16(x) +#define ___opcode_swahb32(x) ___asm_opcode_swahb32(x) +#define ___opcode_swahw32(x) ___asm_opcode_swahw32(x) +#define ___opcode_identity32(x) ___asm_opcode_identity32(x) +#define ___opcode_identity16(x) ___asm_opcode_identity16(x) + +#else /* ! __ASSEMBLY__ */  #include <linux/types.h>  #include <linux/swab.h> +#define ___opcode_swab32(x) swab32(x) +#define ___opcode_swab16(x) swab16(x) +#define ___opcode_swahb32(x) swahb32(x) +#define ___opcode_swahw32(x) swahw32(x) +#define ___opcode_identity32(x) ((u32)(x)) +#define ___opcode_identity16(x) ((u16)(x)) + +#endif /* ! __ASSEMBLY__ */ + +  #ifdef CONFIG_CPU_ENDIAN_BE8 -#define __opcode_to_mem_arm(x) swab32(x) -#define __opcode_to_mem_thumb16(x) swab16(x) -#define __opcode_to_mem_thumb32(x) swahb32(x) -#else -#define __opcode_to_mem_arm(x) ((u32)(x)) -#define __opcode_to_mem_thumb16(x) ((u16)(x)) -#define __opcode_to_mem_thumb32(x) swahw32(x) + +#define __opcode_to_mem_arm(x) ___opcode_swab32(x) +#define __opcode_to_mem_thumb16(x) ___opcode_swab16(x) +#define __opcode_to_mem_thumb32(x) ___opcode_swahb32(x) +#define ___asm_opcode_to_mem_arm(x) ___asm_opcode_swab32(x) +#define ___asm_opcode_to_mem_thumb16(x) ___asm_opcode_swab16(x) +#define ___asm_opcode_to_mem_thumb32(x) ___asm_opcode_swahb32(x) + +#else /* ! CONFIG_CPU_ENDIAN_BE8 */ + +#define __opcode_to_mem_arm(x) ___opcode_identity32(x) +#define __opcode_to_mem_thumb16(x) ___opcode_identity16(x) +#define ___asm_opcode_to_mem_arm(x) ___asm_opcode_identity32(x) +#define ___asm_opcode_to_mem_thumb16(x) ___asm_opcode_identity16(x) +#ifndef CONFIG_CPU_ENDIAN_BE32 +/* + * On BE32 systems, using 32-bit accesses to store Thumb instructions will not + * work in all cases, due to alignment constraints.  For now, a correct + * version is not provided for BE32. + */ +#define __opcode_to_mem_thumb32(x) ___opcode_swahw32(x) +#define ___asm_opcode_to_mem_thumb32(x) ___asm_opcode_swahw32(x)  #endif +#endif /* ! CONFIG_CPU_ENDIAN_BE8 */ +  #define __mem_to_opcode_arm(x) __opcode_to_mem_arm(x)  #define __mem_to_opcode_thumb16(x) __opcode_to_mem_thumb16(x) +#ifndef CONFIG_CPU_ENDIAN_BE32  #define __mem_to_opcode_thumb32(x) __opcode_to_mem_thumb32(x) +#endif  /* Operations specific to Thumb opcodes */  /* Instruction size checks: */ -#define __opcode_is_thumb32(x) ((u32)(x) >= 0xE8000000UL) -#define __opcode_is_thumb16(x) ((u32)(x) < 0xE800UL) +#define __opcode_is_thumb32(x) (		\ +	   ((x) & 0xF8000000) == 0xE8000000	\ +	|| ((x) & 0xF0000000) == 0xF0000000	\ +) +#define __opcode_is_thumb16(x) (					\ +	   ((x) & 0xFFFF0000) == 0					\ +	&& !(((x) & 0xF800) == 0xE800 || ((x) & 0xF000) == 0xF000)	\ +)  /* Operations to construct or split 32-bit Thumb instructions: */ -#define __opcode_thumb32_first(x) ((u16)((x) >> 16)) -#define __opcode_thumb32_second(x) ((u16)(x)) -#define __opcode_thumb32_compose(first, second) \ -	(((u32)(u16)(first) << 16) | (u32)(u16)(second)) +#define __opcode_thumb32_first(x) (___opcode_identity16((x) >> 16)) +#define __opcode_thumb32_second(x) (___opcode_identity16(x)) +#define __opcode_thumb32_compose(first, second) (			\ +	  (___opcode_identity32(___opcode_identity16(first)) << 16)	\ +	| ___opcode_identity32(___opcode_identity16(second))		\ +) +#define ___asm_opcode_thumb32_first(x) (___asm_opcode_identity16((x) >> 16)) +#define ___asm_opcode_thumb32_second(x) (___asm_opcode_identity16(x)) +#define ___asm_opcode_thumb32_compose(first, second) (			    \ +	  (___asm_opcode_identity32(___asm_opcode_identity16(first)) << 16) \ +	| ___asm_opcode_identity32(___asm_opcode_identity16(second))	    \ +) -#endif /* __ASSEMBLY__ */ +/* + * Opcode injection helpers + * + * In rare cases it is necessary to assemble an opcode which the + * assembler does not support directly, or which would normally be + * rejected because of the CFLAGS or AFLAGS used to build the affected + * file. + * + * Before using these macros, consider carefully whether it is feasible + * instead to change the build flags for your file, or whether it really + * makes sense to support old assembler versions when building that + * particular kernel feature. + * + * The macros defined here should only be used where there is no viable + * alternative. + * + * + * __inst_arm(x): emit the specified ARM opcode + * __inst_thumb16(x): emit the specified 16-bit Thumb opcode + * __inst_thumb32(x): emit the specified 32-bit Thumb opcode + * + * __inst_arm_thumb16(arm, thumb): emit either the specified arm or + *	16-bit Thumb opcode, depending on whether an ARM or Thumb-2 + *	kernel is being built + * + * __inst_arm_thumb32(arm, thumb): emit either the specified arm or + *	32-bit Thumb opcode, depending on whether an ARM or Thumb-2 + *	kernel is being built + * + * + * Note that using these macros directly is poor practice.  Instead, you + * should use them to define human-readable wrapper macros to encode the + * instructions that you care about.  In code which might run on ARMv7 or + * above, you can usually use the __inst_arm_thumb{16,32} macros to + * specify the ARM and Thumb alternatives at the same time.  This ensures + * that the correct opcode gets emitted depending on the instruction set + * used for the kernel build. + * + * Look at opcodes-virt.h for an example of how to use these macros. + */ +#include <linux/stringify.h> + +#define __inst_arm(x) ___inst_arm(___asm_opcode_to_mem_arm(x)) +#define __inst_thumb32(x) ___inst_thumb32(				\ +	___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_first(x)),	\ +	___asm_opcode_to_mem_thumb16(___asm_opcode_thumb32_second(x))	\ +) +#define __inst_thumb16(x) ___inst_thumb16(___asm_opcode_to_mem_thumb16(x)) + +#ifdef CONFIG_THUMB2_KERNEL +#define __inst_arm_thumb16(arm_opcode, thumb_opcode) \ +	__inst_thumb16(thumb_opcode) +#define __inst_arm_thumb32(arm_opcode, thumb_opcode) \ +	__inst_thumb32(thumb_opcode) +#else +#define __inst_arm_thumb16(arm_opcode, thumb_opcode) __inst_arm(arm_opcode) +#define __inst_arm_thumb32(arm_opcode, thumb_opcode) __inst_arm(arm_opcode) +#endif + +/* Helpers for the helpers.  Don't use these directly. */ +#ifdef __ASSEMBLY__ +#define ___inst_arm(x) .long x +#define ___inst_thumb16(x) .short x +#define ___inst_thumb32(first, second) .short first, second +#else +#define ___inst_arm(x) ".long " __stringify(x) "\n\t" +#define ___inst_thumb16(x) ".short " __stringify(x) "\n\t" +#define ___inst_thumb32(first, second) \ +	".short " __stringify(first) ", " __stringify(second) "\n\t" +#endif  #endif /* __ASM_ARM_OPCODES_H */ diff --git a/arch/arm/include/asm/param.h b/arch/arm/include/asm/param.h deleted file mode 100644 index 8b24bf94c06..00000000000 --- a/arch/arm/include/asm/param.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - *  arch/arm/include/asm/param.h - * - *  Copyright (C) 1995-1999 Russell King - * - * 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. - */ -#ifndef __ASM_PARAM_H -#define __ASM_PARAM_H - -#ifdef __KERNEL__ -# define HZ		CONFIG_HZ	/* Internal kernel timer frequency */ -# define USER_HZ	100		/* User interfaces are in "ticks" */ -# define CLOCKS_PER_SEC	(USER_HZ)	/* like times() */ -#else -# define HZ		100 -#endif - -#define EXEC_PAGESIZE	4096 - -#ifndef NOGROUP -#define NOGROUP         (-1) -#endif - -/* max length of hostname */ -#define MAXHOSTNAMELEN  64 - -#endif - diff --git a/arch/arm/include/asm/parport.h b/arch/arm/include/asm/parport.h deleted file mode 100644 index 26e94b09035..00000000000 --- a/arch/arm/include/asm/parport.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - *  arch/arm/include/asm/parport.h: ARM-specific parport initialisation - * - *  Copyright (C) 1999, 2000  Tim Waugh <tim@cyberelk.demon.co.uk> - * - * This file should only be included by drivers/parport/parport_pc.c. - */ - -#ifndef __ASMARM_PARPORT_H -#define __ASMARM_PARPORT_H - -static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma); -static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) -{ -	return parport_pc_find_isa_ports (autoirq, autodma); -} - -#endif /* !(_ASMARM_PARPORT_H) */ diff --git a/arch/arm/include/asm/segment.h b/arch/arm/include/asm/segment.h deleted file mode 100644 index 9e24c21f630..00000000000 --- a/arch/arm/include/asm/segment.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __ASM_ARM_SEGMENT_H -#define __ASM_ARM_SEGMENT_H - -#define __KERNEL_CS   0x0 -#define __KERNEL_DS   0x0 - -#define __USER_CS     0x1 -#define __USER_DS     0x1 - -#endif /* __ASM_ARM_SEGMENT_H */ - diff --git a/arch/arm/include/asm/sembuf.h b/arch/arm/include/asm/sembuf.h deleted file mode 100644 index 1c028395428..00000000000 --- a/arch/arm/include/asm/sembuf.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _ASMARM_SEMBUF_H -#define _ASMARM_SEMBUF_H - -/*  - * The semid64_ds structure for arm architecture. - * Note extra padding because this structure is passed back and forth - * between kernel and user space. - * - * Pad space is left for: - * - 64-bit time_t to solve y2038 problem - * - 2 miscellaneous 32-bit values - */ - -struct semid64_ds { -	struct ipc64_perm sem_perm;		/* permissions .. see ipc.h */ -	__kernel_time_t	sem_otime;		/* last semop time */ -	unsigned long	__unused1; -	__kernel_time_t	sem_ctime;		/* last change time */ -	unsigned long	__unused2; -	unsigned long	sem_nsems;		/* no. of semaphores in array */ -	unsigned long	__unused3; -	unsigned long	__unused4; -}; - -#endif /* _ASMARM_SEMBUF_H */ diff --git a/arch/arm/include/asm/serial.h b/arch/arm/include/asm/serial.h deleted file mode 100644 index ebb049091e2..00000000000 --- a/arch/arm/include/asm/serial.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - *  arch/arm/include/asm/serial.h - * - *  Copyright (C) 1996 Russell King. - * - * 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. - * - *  Changelog: - *   15-10-1996	RMK	Created - */ - -#ifndef __ASM_SERIAL_H -#define __ASM_SERIAL_H - -#define BASE_BAUD	(1843200 / 16) - -#endif diff --git a/arch/arm/include/asm/shmbuf.h b/arch/arm/include/asm/shmbuf.h deleted file mode 100644 index 2e5c67ba1c9..00000000000 --- a/arch/arm/include/asm/shmbuf.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef _ASMARM_SHMBUF_H -#define _ASMARM_SHMBUF_H - -/*  - * The shmid64_ds structure for arm architecture. - * Note extra padding because this structure is passed back and forth - * between kernel and user space. - * - * Pad space is left for: - * - 64-bit time_t to solve y2038 problem - * - 2 miscellaneous 32-bit values - */ - -struct shmid64_ds { -	struct ipc64_perm	shm_perm;	/* operation perms */ -	size_t			shm_segsz;	/* size of segment (bytes) */ -	__kernel_time_t		shm_atime;	/* last attach time */ -	unsigned long		__unused1; -	__kernel_time_t		shm_dtime;	/* last detach time */ -	unsigned long		__unused2; -	__kernel_time_t		shm_ctime;	/* last change time */ -	unsigned long		__unused3; -	__kernel_pid_t		shm_cpid;	/* pid of creator */ -	__kernel_pid_t		shm_lpid;	/* pid of last operator */ -	unsigned long		shm_nattch;	/* no. of current attaches */ -	unsigned long		__unused4; -	unsigned long		__unused5; -}; - -struct shminfo64 { -	unsigned long	shmmax; -	unsigned long	shmmin; -	unsigned long	shmmni; -	unsigned long	shmseg; -	unsigned long	shmall; -	unsigned long	__unused1; -	unsigned long	__unused2; -	unsigned long	__unused3; -	unsigned long	__unused4; -}; - -#endif /* _ASMARM_SHMBUF_H */ diff --git a/arch/arm/include/asm/socket.h b/arch/arm/include/asm/socket.h deleted file mode 100644 index 6433cadb6ed..00000000000 --- a/arch/arm/include/asm/socket.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef _ASMARM_SOCKET_H -#define _ASMARM_SOCKET_H - -#include <asm/sockios.h> - -/* For setsockopt(2) */ -#define SOL_SOCKET	1 - -#define SO_DEBUG	1 -#define SO_REUSEADDR	2 -#define SO_TYPE		3 -#define SO_ERROR	4 -#define SO_DONTROUTE	5 -#define SO_BROADCAST	6 -#define SO_SNDBUF	7 -#define SO_RCVBUF	8 -#define SO_SNDBUFFORCE	32 -#define SO_RCVBUFFORCE	33 -#define SO_KEEPALIVE	9 -#define SO_OOBINLINE	10 -#define SO_NO_CHECK	11 -#define SO_PRIORITY	12 -#define SO_LINGER	13 -#define SO_BSDCOMPAT	14 -/* To add :#define SO_REUSEPORT 15 */ -#define SO_PASSCRED	16 -#define SO_PEERCRED	17 -#define SO_RCVLOWAT	18 -#define SO_SNDLOWAT	19 -#define SO_RCVTIMEO	20 -#define SO_SNDTIMEO	21 - -/* Security levels - as per NRL IPv6 - don't actually do anything */ -#define SO_SECURITY_AUTHENTICATION		22 -#define SO_SECURITY_ENCRYPTION_TRANSPORT	23 -#define SO_SECURITY_ENCRYPTION_NETWORK		24 - -#define SO_BINDTODEVICE 25 - -/* Socket filtering */ -#define SO_ATTACH_FILTER        26 -#define SO_DETACH_FILTER        27 - -#define SO_PEERNAME             28 -#define SO_TIMESTAMP		29 -#define SCM_TIMESTAMP		SO_TIMESTAMP - -#define SO_ACCEPTCONN		30 - -#define SO_PEERSEC		31 -#define SO_PASSSEC		34 -#define SO_TIMESTAMPNS		35 -#define SCM_TIMESTAMPNS		SO_TIMESTAMPNS - -#define SO_MARK			36 - -#define SO_TIMESTAMPING		37 -#define SCM_TIMESTAMPING	SO_TIMESTAMPING - -#define SO_PROTOCOL		38 -#define SO_DOMAIN		39 - -#define SO_RXQ_OVFL             40 - -#define SO_WIFI_STATUS		41 -#define SCM_WIFI_STATUS		SO_WIFI_STATUS -#define SO_PEEK_OFF		42 - -/* Instruct lower device to use last 4-bytes of skb data as FCS */ -#define SO_NOFCS		43 - -#endif /* _ASM_SOCKET_H */ diff --git a/arch/arm/include/asm/sockios.h b/arch/arm/include/asm/sockios.h deleted file mode 100644 index a2588a2512d..00000000000 --- a/arch/arm/include/asm/sockios.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef __ARCH_ARM_SOCKIOS_H -#define __ARCH_ARM_SOCKIOS_H - -/* Socket-level I/O control calls. */ -#define FIOSETOWN 	0x8901 -#define SIOCSPGRP	0x8902 -#define FIOGETOWN	0x8903 -#define SIOCGPGRP	0x8904 -#define SIOCATMARK	0x8905 -#define SIOCGSTAMP	0x8906		/* Get stamp (timeval) */ -#define SIOCGSTAMPNS	0x8907		/* Get stamp (timespec) */ - -#endif diff --git a/arch/arm/include/asm/syscall.h b/arch/arm/include/asm/syscall.h index c334a23ddf7..47486a41c56 100644 --- a/arch/arm/include/asm/syscall.h +++ b/arch/arm/include/asm/syscall.h @@ -9,6 +9,10 @@  #include <linux/err.h> +#include <asm/unistd.h> + +#define NR_syscalls (__NR_syscalls) +  extern const unsigned long sys_call_table[];  static inline int syscall_get_nr(struct task_struct *task, diff --git a/arch/arm/include/asm/termbits.h b/arch/arm/include/asm/termbits.h deleted file mode 100644 index 704135d28d1..00000000000 --- a/arch/arm/include/asm/termbits.h +++ /dev/null @@ -1,198 +0,0 @@ -#ifndef __ASM_ARM_TERMBITS_H -#define __ASM_ARM_TERMBITS_H - -typedef unsigned char	cc_t; -typedef unsigned int	speed_t; -typedef unsigned int	tcflag_t; - -#define NCCS 19 -struct termios { -	tcflag_t c_iflag;		/* input mode flags */ -	tcflag_t c_oflag;		/* output mode flags */ -	tcflag_t c_cflag;		/* control mode flags */ -	tcflag_t c_lflag;		/* local mode flags */ -	cc_t c_line;			/* line discipline */ -	cc_t c_cc[NCCS];		/* control characters */ -}; - -struct termios2 { -	tcflag_t c_iflag;		/* input mode flags */ -	tcflag_t c_oflag;		/* output mode flags */ -	tcflag_t c_cflag;		/* control mode flags */ -	tcflag_t c_lflag;		/* local mode flags */ -	cc_t c_line;			/* line discipline */ -	cc_t c_cc[NCCS];		/* control characters */ -	speed_t c_ispeed;		/* input speed */ -	speed_t c_ospeed;		/* output speed */ -}; - -struct ktermios { -	tcflag_t c_iflag;		/* input mode flags */ -	tcflag_t c_oflag;		/* output mode flags */ -	tcflag_t c_cflag;		/* control mode flags */ -	tcflag_t c_lflag;		/* local mode flags */ -	cc_t c_line;			/* line discipline */ -	cc_t c_cc[NCCS];		/* control characters */ -	speed_t c_ispeed;		/* input speed */ -	speed_t c_ospeed;		/* output speed */ -}; - - -/* c_cc characters */ -#define VINTR 0 -#define VQUIT 1 -#define VERASE 2 -#define VKILL 3 -#define VEOF 4 -#define VTIME 5 -#define VMIN 6 -#define VSWTC 7 -#define VSTART 8 -#define VSTOP 9 -#define VSUSP 10 -#define VEOL 11 -#define VREPRINT 12 -#define VDISCARD 13 -#define VWERASE 14 -#define VLNEXT 15 -#define VEOL2 16 - -/* c_iflag bits */ -#define IGNBRK	0000001 -#define BRKINT	0000002 -#define IGNPAR	0000004 -#define PARMRK	0000010 -#define INPCK	0000020 -#define ISTRIP	0000040 -#define INLCR	0000100 -#define IGNCR	0000200 -#define ICRNL	0000400 -#define IUCLC	0001000 -#define IXON	0002000 -#define IXANY	0004000 -#define IXOFF	0010000 -#define IMAXBEL	0020000 -#define IUTF8	0040000 - -/* c_oflag bits */ -#define OPOST	0000001 -#define OLCUC	0000002 -#define ONLCR	0000004 -#define OCRNL	0000010 -#define ONOCR	0000020 -#define ONLRET	0000040 -#define OFILL	0000100 -#define OFDEL	0000200 -#define NLDLY	0000400 -#define   NL0	0000000 -#define   NL1	0000400 -#define CRDLY	0003000 -#define   CR0	0000000 -#define   CR1	0001000 -#define   CR2	0002000 -#define   CR3	0003000 -#define TABDLY	0014000 -#define   TAB0	0000000 -#define   TAB1	0004000 -#define   TAB2	0010000 -#define   TAB3	0014000 -#define   XTABS	0014000 -#define BSDLY	0020000 -#define   BS0	0000000 -#define   BS1	0020000 -#define VTDLY	0040000 -#define   VT0	0000000 -#define   VT1	0040000 -#define FFDLY	0100000 -#define   FF0	0000000 -#define   FF1	0100000 - -/* c_cflag bit meaning */ -#define CBAUD	0010017 -#define  B0	0000000		/* hang up */ -#define  B50	0000001 -#define  B75	0000002 -#define  B110	0000003 -#define  B134	0000004 -#define  B150	0000005 -#define  B200	0000006 -#define  B300	0000007 -#define  B600	0000010 -#define  B1200	0000011 -#define  B1800	0000012 -#define  B2400	0000013 -#define  B4800	0000014 -#define  B9600	0000015 -#define  B19200	0000016 -#define  B38400	0000017 -#define EXTA B19200 -#define EXTB B38400 -#define CSIZE	0000060 -#define   CS5	0000000 -#define   CS6	0000020 -#define   CS7	0000040 -#define   CS8	0000060 -#define CSTOPB	0000100 -#define CREAD	0000200 -#define PARENB	0000400 -#define PARODD	0001000 -#define HUPCL	0002000 -#define CLOCAL	0004000 -#define CBAUDEX 0010000 -#define    BOTHER 0010000 -#define    B57600 0010001 -#define   B115200 0010002 -#define   B230400 0010003 -#define   B460800 0010004 -#define   B500000 0010005 -#define   B576000 0010006 -#define   B921600 0010007 -#define  B1000000 0010010 -#define  B1152000 0010011 -#define  B1500000 0010012 -#define  B2000000 0010013 -#define  B2500000 0010014 -#define  B3000000 0010015 -#define  B3500000 0010016 -#define  B4000000 0010017 -#define CIBAUD	  002003600000		/* input baud rate */ -#define CMSPAR    010000000000		/* mark or space (stick) parity */ -#define CRTSCTS	  020000000000		/* flow control */ - -#define IBSHIFT	   16 - -/* c_lflag bits */ -#define ISIG	0000001 -#define ICANON	0000002 -#define XCASE	0000004 -#define ECHO	0000010 -#define ECHOE	0000020 -#define ECHOK	0000040 -#define ECHONL	0000100 -#define NOFLSH	0000200 -#define TOSTOP	0000400 -#define ECHOCTL	0001000 -#define ECHOPRT	0002000 -#define ECHOKE	0004000 -#define FLUSHO	0010000 -#define PENDIN	0040000 -#define IEXTEN	0100000 -#define EXTPROC	0200000 - -/* tcflow() and TCXONC use these */ -#define	TCOOFF		0 -#define	TCOON		1 -#define	TCIOFF		2 -#define	TCION		3 - -/* tcflush() and TCFLSH use these */ -#define	TCIFLUSH	0 -#define	TCOFLUSH	1 -#define	TCIOFLUSH	2 - -/* tcsetattr uses these */ -#define	TCSANOW		0 -#define	TCSADRAIN	1 -#define	TCSAFLUSH	2 - -#endif	/* __ASM_ARM_TERMBITS_H */ diff --git a/arch/arm/include/asm/termios.h b/arch/arm/include/asm/termios.h deleted file mode 100644 index 293e3f1bc3f..00000000000 --- a/arch/arm/include/asm/termios.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef __ASM_ARM_TERMIOS_H -#define __ASM_ARM_TERMIOS_H - -#include <asm/termbits.h> -#include <asm/ioctls.h> - -struct winsize { -	unsigned short ws_row; -	unsigned short ws_col; -	unsigned short ws_xpixel; -	unsigned short ws_ypixel; -}; - -#define NCC 8 -struct termio { -	unsigned short c_iflag;		/* input mode flags */ -	unsigned short c_oflag;		/* output mode flags */ -	unsigned short c_cflag;		/* control mode flags */ -	unsigned short c_lflag;		/* local mode flags */ -	unsigned char c_line;		/* line discipline */ -	unsigned char c_cc[NCC];	/* control characters */ -}; - -#ifdef __KERNEL__ -/*	intr=^C		quit=^|		erase=del	kill=^U -	eof=^D		vtime=\0	vmin=\1		sxtc=\0 -	start=^Q	stop=^S		susp=^Z		eol=\0 -	reprint=^R	discard=^U	werase=^W	lnext=^V -	eol2=\0 -*/ -#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" -#endif - -/* modem lines */ -#define TIOCM_LE	0x001 -#define TIOCM_DTR	0x002 -#define TIOCM_RTS	0x004 -#define TIOCM_ST	0x008 -#define TIOCM_SR	0x010 -#define TIOCM_CTS	0x020 -#define TIOCM_CAR	0x040 -#define TIOCM_RNG	0x080 -#define TIOCM_DSR	0x100 -#define TIOCM_CD	TIOCM_CAR -#define TIOCM_RI	TIOCM_RNG -#define TIOCM_OUT1	0x2000 -#define TIOCM_OUT2	0x4000 -#define TIOCM_LOOP	0x8000 - -/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ - -#ifdef __KERNEL__ - -/* - * Translate a "termio" structure into a "termios". Ugh. - */ -#define SET_LOW_TERMIOS_BITS(termios, termio, x) {		\ -	unsigned short __tmp;					\ -	get_user(__tmp,&(termio)->x);				\ -	*(unsigned short *) &(termios)->x = __tmp;		\ -} - -#define user_termio_to_kernel_termios(termios, termio) \ -({ \ -	SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \ -	SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \ -	SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \ -	SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \ -	copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ -}) - -/* - * Translate a "termios" structure into a "termio". Ugh. - */ -#define kernel_termios_to_user_termio(termio, termios) \ -({ \ -	put_user((termios)->c_iflag, &(termio)->c_iflag); \ -	put_user((termios)->c_oflag, &(termio)->c_oflag); \ -	put_user((termios)->c_cflag, &(termio)->c_cflag); \ -	put_user((termios)->c_lflag, &(termio)->c_lflag); \ -	put_user((termios)->c_line,  &(termio)->c_line); \ -	copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ -}) - -#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2)) -#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2)) -#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios)) -#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios)) - -#endif	/* __KERNEL__ */ - -#endif	/* __ASM_ARM_TERMIOS_H */ diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h index af7b0bda335..f71cdab18b8 100644 --- a/arch/arm/include/asm/thread_info.h +++ b/arch/arm/include/asm/thread_info.h @@ -59,7 +59,9 @@ struct thread_info {  	__u32			syscall;	/* syscall number */  	__u8			used_cp[16];	/* thread used copro */  	unsigned long		tp_value; +#ifdef CONFIG_CRUNCH  	struct crunch_state	crunchstate; +#endif  	union fp_state		fpstate __attribute__((aligned(8)));  	union vfp_state		vfpstate;  #ifdef CONFIG_ARM_THUMBEE @@ -148,6 +150,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,  #define TIF_NOTIFY_RESUME	2	/* callback before returning to user */  #define TIF_SYSCALL_TRACE	8  #define TIF_SYSCALL_AUDIT	9 +#define TIF_SYSCALL_TRACEPOINT	10  #define TIF_POLLING_NRFLAG	16  #define TIF_USING_IWMMXT	17  #define TIF_MEMDIE		18	/* is terminating due to OOM killer */ @@ -160,12 +163,13 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,  #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME)  #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)  #define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT) +#define _TIF_SYSCALL_TRACEPOINT	(1 << TIF_SYSCALL_TRACEPOINT)  #define _TIF_POLLING_NRFLAG	(1 << TIF_POLLING_NRFLAG)  #define _TIF_USING_IWMMXT	(1 << TIF_USING_IWMMXT)  #define _TIF_SECCOMP		(1 << TIF_SECCOMP)  /* Checks for any syscall work in entry-common.S */ -#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT) +#define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SYSCALL_TRACEPOINT)  /*   * Change these and you break ASM code in entry-common.S diff --git a/arch/arm/include/asm/timex.h b/arch/arm/include/asm/timex.h index ce119442277..5e711722ebf 100644 --- a/arch/arm/include/asm/timex.h +++ b/arch/arm/include/asm/timex.h @@ -15,12 +15,10 @@  #include <asm/arch_timer.h>  #include <mach/timex.h> -typedef unsigned long cycles_t; -  #ifdef ARCH_HAS_READ_CURRENT_TIMER  #define get_cycles()	({ cycles_t c; read_current_timer(&c) ? 0 : c; }) -#else -#define get_cycles()	(0)  #endif +#include <asm-generic/timex.h> +  #endif diff --git a/arch/arm/include/asm/tlb.h b/arch/arm/include/asm/tlb.h index 314d4664eae..99a19512ee2 100644 --- a/arch/arm/include/asm/tlb.h +++ b/arch/arm/include/asm/tlb.h @@ -199,6 +199,9 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,  {  	pgtable_page_dtor(pte); +#ifdef CONFIG_ARM_LPAE +	tlb_add_flush(tlb, addr); +#else  	/*  	 * With the classic ARM MMU, a pte page has two corresponding pmd  	 * entries, each covering 1MB. @@ -206,6 +209,7 @@ static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,  	addr &= PMD_MASK;  	tlb_add_flush(tlb, addr + SZ_1M - PAGE_SIZE);  	tlb_add_flush(tlb, addr + SZ_1M); +#endif  	tlb_remove_page(tlb, pte);  } diff --git a/arch/arm/include/asm/types.h b/arch/arm/include/asm/types.h deleted file mode 100644 index 28beab917ff..00000000000 --- a/arch/arm/include/asm/types.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __ASM_ARM_TYPES_H -#define __ASM_ARM_TYPES_H - -#include <asm-generic/int-ll64.h> - -/* - * These aren't exported outside the kernel to avoid name space clashes - */ -#ifdef __KERNEL__ - -#define BITS_PER_LONG 32 - -#endif /* __KERNEL__ */ - -#endif - diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h index 479a6352e0b..77bd79f2ffd 100644 --- a/arch/arm/include/asm/uaccess.h +++ b/arch/arm/include/asm/uaccess.h @@ -101,28 +101,39 @@ extern int __get_user_1(void *);  extern int __get_user_2(void *);  extern int __get_user_4(void *); -#define __get_user_x(__r2,__p,__e,__s,__i...)				\ +#define __GUP_CLOBBER_1	"lr", "cc" +#ifdef CONFIG_CPU_USE_DOMAINS +#define __GUP_CLOBBER_2	"ip", "lr", "cc" +#else +#define __GUP_CLOBBER_2 "lr", "cc" +#endif +#define __GUP_CLOBBER_4	"lr", "cc" + +#define __get_user_x(__r2,__p,__e,__l,__s)				\  	   __asm__ __volatile__ (					\  		__asmeq("%0", "r0") __asmeq("%1", "r2")			\ +		__asmeq("%3", "r1")					\  		"bl	__get_user_" #__s				\  		: "=&r" (__e), "=r" (__r2)				\ -		: "0" (__p)						\ -		: __i, "cc") +		: "0" (__p), "r" (__l)					\ +		: __GUP_CLOBBER_##__s) -#define get_user(x,p)							\ +#define __get_user_check(x,p)							\  	({								\ +		unsigned long __limit = current_thread_info()->addr_limit - 1; \  		register const typeof(*(p)) __user *__p asm("r0") = (p);\  		register unsigned long __r2 asm("r2");			\ +		register unsigned long __l asm("r1") = __limit;		\  		register int __e asm("r0");				\  		switch (sizeof(*(__p))) {				\  		case 1:							\ -			__get_user_x(__r2, __p, __e, 1, "lr");		\ -	       		break;						\ +			__get_user_x(__r2, __p, __e, __l, 1);		\ +			break;						\  		case 2:							\ -			__get_user_x(__r2, __p, __e, 2, "r3", "lr");	\ +			__get_user_x(__r2, __p, __e, __l, 2);		\  			break;						\  		case 4:							\ -	       		__get_user_x(__r2, __p, __e, 4, "lr");		\ +			__get_user_x(__r2, __p, __e, __l, 4);		\  			break;						\  		default: __e = __get_user_bad(); break;			\  		}							\ @@ -130,42 +141,57 @@ extern int __get_user_4(void *);  		__e;							\  	}) +#define get_user(x,p)							\ +	({								\ +		might_fault();						\ +		__get_user_check(x,p);					\ +	 }) +  extern int __put_user_1(void *, unsigned int);  extern int __put_user_2(void *, unsigned int);  extern int __put_user_4(void *, unsigned int);  extern int __put_user_8(void *, unsigned long long); -#define __put_user_x(__r2,__p,__e,__s)					\ +#define __put_user_x(__r2,__p,__e,__l,__s)				\  	   __asm__ __volatile__ (					\  		__asmeq("%0", "r0") __asmeq("%2", "r2")			\ +		__asmeq("%3", "r1")					\  		"bl	__put_user_" #__s				\  		: "=&r" (__e)						\ -		: "0" (__p), "r" (__r2)					\ +		: "0" (__p), "r" (__r2), "r" (__l)			\  		: "ip", "lr", "cc") -#define put_user(x,p)							\ +#define __put_user_check(x,p)							\  	({								\ +		unsigned long __limit = current_thread_info()->addr_limit - 1; \  		register const typeof(*(p)) __r2 asm("r2") = (x);	\  		register const typeof(*(p)) __user *__p asm("r0") = (p);\ +		register unsigned long __l asm("r1") = __limit;		\  		register int __e asm("r0");				\  		switch (sizeof(*(__p))) {				\  		case 1:							\ -			__put_user_x(__r2, __p, __e, 1);		\ +			__put_user_x(__r2, __p, __e, __l, 1);		\  			break;						\  		case 2:							\ -			__put_user_x(__r2, __p, __e, 2);		\ +			__put_user_x(__r2, __p, __e, __l, 2);		\  			break;						\  		case 4:							\ -			__put_user_x(__r2, __p, __e, 4);		\ +			__put_user_x(__r2, __p, __e, __l, 4);		\  			break;						\  		case 8:							\ -			__put_user_x(__r2, __p, __e, 8);		\ +			__put_user_x(__r2, __p, __e, __l, 8);		\  			break;						\  		default: __e = __put_user_bad(); break;			\  		}							\  		__e;							\  	}) +#define put_user(x,p)							\ +	({								\ +		might_fault();						\ +		__put_user_check(x,p);					\ +	 }) +  #else /* CONFIG_MMU */  /* @@ -219,6 +245,7 @@ do {									\  	unsigned long __gu_addr = (unsigned long)(ptr);			\  	unsigned long __gu_val;						\  	__chk_user_ptr(ptr);						\ +	might_fault();							\  	switch (sizeof(*(ptr))) {					\  	case 1:	__get_user_asm_byte(__gu_val,__gu_addr,err);	break;	\  	case 2:	__get_user_asm_half(__gu_val,__gu_addr,err);	break;	\ @@ -300,6 +327,7 @@ do {									\  	unsigned long __pu_addr = (unsigned long)(ptr);			\  	__typeof__(*(ptr)) __pu_val = (x);				\  	__chk_user_ptr(ptr);						\ +	might_fault();							\  	switch (sizeof(*(ptr))) {					\  	case 1: __put_user_asm_byte(__pu_val,__pu_addr,err);	break;	\  	case 2: __put_user_asm_half(__pu_val,__pu_addr,err);	break;	\ diff --git a/arch/arm/include/asm/unaligned.h b/arch/arm/include/asm/unaligned.h deleted file mode 100644 index 44593a89490..00000000000 --- a/arch/arm/include/asm/unaligned.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _ASM_ARM_UNALIGNED_H -#define _ASM_ARM_UNALIGNED_H - -#include <linux/unaligned/le_byteshift.h> -#include <linux/unaligned/be_byteshift.h> -#include <linux/unaligned/generic.h> - -/* - * Select endianness - */ -#ifndef __ARMEB__ -#define get_unaligned	__get_unaligned_le -#define put_unaligned	__put_unaligned_le -#else -#define get_unaligned	__get_unaligned_be -#define put_unaligned	__put_unaligned_be -#endif - -#endif /* _ASM_ARM_UNALIGNED_H */ diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h index 0cab47d4a83..d9ff5cc3a50 100644 --- a/arch/arm/include/asm/unistd.h +++ b/arch/arm/include/asm/unistd.h @@ -404,6 +404,15 @@  #define __NR_setns			(__NR_SYSCALL_BASE+375)  #define __NR_process_vm_readv		(__NR_SYSCALL_BASE+376)  #define __NR_process_vm_writev		(__NR_SYSCALL_BASE+377) +					/* 378 for kcmp */ + +/* + * This may need to be greater than __NR_last_syscall+1 in order to + * account for the padding in the syscall table + */ +#ifdef __KERNEL__ +#define __NR_syscalls  (380) +#endif /* __KERNEL__ */  /*   * The following SWIs are ARM private. @@ -483,6 +492,7 @@   */  #define __IGNORE_fadvise64_64  #define __IGNORE_migrate_pages +#define __IGNORE_kcmp  #endif /* __KERNEL__ */  #endif /* __ASM_ARM_UNISTD_H */ diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 7ad2d5cf700..79e346a5d78 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -19,7 +19,9 @@ obj-y		:= elf.o entry-armv.o entry-common.o irq.o opcodes.o \  		   process.o ptrace.o return_address.o sched_clock.o \  		   setup.o signal.o stacktrace.o sys_arm.o time.o traps.o -obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += compat.o +obj-$(CONFIG_ATAGS)		+= atags_parse.o +obj-$(CONFIG_ATAGS_PROC)	+= atags_proc.o +obj-$(CONFIG_DEPRECATED_PARAM_STRUCT) += atags_compat.o  obj-$(CONFIG_LEDS)		+= leds.o  obj-$(CONFIG_OC_ETM)		+= etm.o @@ -52,7 +54,6 @@ test-kprobes-objs		+= kprobes-test-thumb.o  else  test-kprobes-objs		+= kprobes-test-arm.o  endif -obj-$(CONFIG_ATAGS_PROC)	+= atags.o  obj-$(CONFIG_OABI_COMPAT)	+= sys_oabi-compat.o  obj-$(CONFIG_ARM_THUMBEE)	+= thumbee.o  obj-$(CONFIG_KGDB)		+= kgdb.o diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c index 1429d8989fb..c985b481192 100644 --- a/arch/arm/kernel/asm-offsets.c +++ b/arch/arm/kernel/asm-offsets.c @@ -59,10 +59,12 @@ int main(void)    DEFINE(TI_USED_CP,		offsetof(struct thread_info, used_cp));    DEFINE(TI_TP_VALUE,		offsetof(struct thread_info, tp_value));    DEFINE(TI_FPSTATE,		offsetof(struct thread_info, fpstate)); +#ifdef CONFIG_VFP    DEFINE(TI_VFPSTATE,		offsetof(struct thread_info, vfpstate));  #ifdef CONFIG_SMP    DEFINE(VFP_CPU,		offsetof(union vfp_state, hard.cpu));  #endif +#endif  #ifdef CONFIG_ARM_THUMBEE    DEFINE(TI_THUMBEE_STATE,	offsetof(struct thread_info, thumbee_state));  #endif diff --git a/arch/arm/kernel/atags.h b/arch/arm/kernel/atags.h index e5f028d214a..9edc9692332 100644 --- a/arch/arm/kernel/atags.h +++ b/arch/arm/kernel/atags.h @@ -3,3 +3,17 @@ extern void save_atags(struct tag *tags);  #else  static inline void save_atags(struct tag *tags) { }  #endif + +void convert_to_tag_list(struct tag *tags); + +#ifdef CONFIG_ATAGS +struct machine_desc *setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr); +#else +static inline struct machine_desc * +setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr) +{ +	early_print("no ATAGS support: can't continue\n"); +	while (true); +	unreachable(); +} +#endif diff --git a/arch/arm/kernel/compat.c b/arch/arm/kernel/atags_compat.c index 925652318b8..5236ad38f41 100644 --- a/arch/arm/kernel/compat.c +++ b/arch/arm/kernel/atags_compat.c @@ -1,5 +1,5 @@  /* - *  linux/arch/arm/kernel/compat.c + *  linux/arch/arm/kernel/atags_compat.c   *   *  Copyright (C) 2001 Russell King   * @@ -26,7 +26,7 @@  #include <asm/mach/arch.h> -#include "compat.h" +#include "atags.h"  /*   * Usage: diff --git a/arch/arm/kernel/atags_parse.c b/arch/arm/kernel/atags_parse.c new file mode 100644 index 00000000000..14512e6931d --- /dev/null +++ b/arch/arm/kernel/atags_parse.c @@ -0,0 +1,238 @@ +/* + * Tag parsing. + * + * Copyright (C) 1995-2001 Russell King + * + * 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 is the traditional way of passing data to the kernel at boot time.  Rather + * than passing a fixed inflexible structure to the kernel, we pass a list + * of variable-sized tags to the kernel.  The first tag must be a ATAG_CORE + * tag for the list to be recognised (to distinguish the tagged list from + * a param_struct).  The list is terminated with a zero-length tag (this tag + * is not parsed in any way). + */ + +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/fs.h> +#include <linux/root_dev.h> +#include <linux/screen_info.h> + +#include <asm/setup.h> +#include <asm/system_info.h> +#include <asm/page.h> +#include <asm/mach/arch.h> + +#include "atags.h" + +static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; + +#ifndef MEM_SIZE +#define MEM_SIZE	(16*1024*1024) +#endif + +static struct { +	struct tag_header hdr1; +	struct tag_core   core; +	struct tag_header hdr2; +	struct tag_mem32  mem; +	struct tag_header hdr3; +} default_tags __initdata = { +	{ tag_size(tag_core), ATAG_CORE }, +	{ 1, PAGE_SIZE, 0xff }, +	{ tag_size(tag_mem32), ATAG_MEM }, +	{ MEM_SIZE }, +	{ 0, ATAG_NONE } +}; + +static int __init parse_tag_core(const struct tag *tag) +{ +	if (tag->hdr.size > 2) { +		if ((tag->u.core.flags & 1) == 0) +			root_mountflags &= ~MS_RDONLY; +		ROOT_DEV = old_decode_dev(tag->u.core.rootdev); +	} +	return 0; +} + +__tagtable(ATAG_CORE, parse_tag_core); + +static int __init parse_tag_mem32(const struct tag *tag) +{ +	return arm_add_memory(tag->u.mem.start, tag->u.mem.size); +} + +__tagtable(ATAG_MEM, parse_tag_mem32); + +#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) +static int __init parse_tag_videotext(const struct tag *tag) +{ +	screen_info.orig_x            = tag->u.videotext.x; +	screen_info.orig_y            = tag->u.videotext.y; +	screen_info.orig_video_page   = tag->u.videotext.video_page; +	screen_info.orig_video_mode   = tag->u.videotext.video_mode; +	screen_info.orig_video_cols   = tag->u.videotext.video_cols; +	screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx; +	screen_info.orig_video_lines  = tag->u.videotext.video_lines; +	screen_info.orig_video_isVGA  = tag->u.videotext.video_isvga; +	screen_info.orig_video_points = tag->u.videotext.video_points; +	return 0; +} + +__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext); +#endif + +#ifdef CONFIG_BLK_DEV_RAM +static int __init parse_tag_ramdisk(const struct tag *tag) +{ +	extern int rd_size, rd_image_start, rd_prompt, rd_doload; + +	rd_image_start = tag->u.ramdisk.start; +	rd_doload = (tag->u.ramdisk.flags & 1) == 0; +	rd_prompt = (tag->u.ramdisk.flags & 2) == 0; + +	if (tag->u.ramdisk.size) +		rd_size = tag->u.ramdisk.size; + +	return 0; +} + +__tagtable(ATAG_RAMDISK, parse_tag_ramdisk); +#endif + +static int __init parse_tag_serialnr(const struct tag *tag) +{ +	system_serial_low = tag->u.serialnr.low; +	system_serial_high = tag->u.serialnr.high; +	return 0; +} + +__tagtable(ATAG_SERIAL, parse_tag_serialnr); + +static int __init parse_tag_revision(const struct tag *tag) +{ +	system_rev = tag->u.revision.rev; +	return 0; +} + +__tagtable(ATAG_REVISION, parse_tag_revision); + +static int __init parse_tag_cmdline(const struct tag *tag) +{ +#if defined(CONFIG_CMDLINE_EXTEND) +	strlcat(default_command_line, " ", COMMAND_LINE_SIZE); +	strlcat(default_command_line, tag->u.cmdline.cmdline, +		COMMAND_LINE_SIZE); +#elif defined(CONFIG_CMDLINE_FORCE) +	pr_warning("Ignoring tag cmdline (using the default kernel command line)\n"); +#else +	strlcpy(default_command_line, tag->u.cmdline.cmdline, +		COMMAND_LINE_SIZE); +#endif +	return 0; +} + +__tagtable(ATAG_CMDLINE, parse_tag_cmdline); + +/* + * Scan the tag table for this tag, and call its parse function. + * The tag table is built by the linker from all the __tagtable + * declarations. + */ +static int __init parse_tag(const struct tag *tag) +{ +	extern struct tagtable __tagtable_begin, __tagtable_end; +	struct tagtable *t; + +	for (t = &__tagtable_begin; t < &__tagtable_end; t++) +		if (tag->hdr.tag == t->tag) { +			t->parse(tag); +			break; +		} + +	return t < &__tagtable_end; +} + +/* + * Parse all tags in the list, checking both the global and architecture + * specific tag tables. + */ +static void __init parse_tags(const struct tag *t) +{ +	for (; t->hdr.size; t = tag_next(t)) +		if (!parse_tag(t)) +			printk(KERN_WARNING +				"Ignoring unrecognised tag 0x%08x\n", +				t->hdr.tag); +} + +static void __init squash_mem_tags(struct tag *tag) +{ +	for (; tag->hdr.size; tag = tag_next(tag)) +		if (tag->hdr.tag == ATAG_MEM) +			tag->hdr.tag = ATAG_NONE; +} + +struct machine_desc * __init setup_machine_tags(phys_addr_t __atags_pointer, +						unsigned int machine_nr) +{ +	struct tag *tags = (struct tag *)&default_tags; +	struct machine_desc *mdesc = NULL, *p; +	char *from = default_command_line; + +	default_tags.mem.start = PHYS_OFFSET; + +	/* +	 * locate machine in the list of supported machines. +	 */ +	for_each_machine_desc(p) +		if (machine_nr == p->nr) { +			printk("Machine: %s\n", p->name); +			mdesc = p; +			break; +		} + +	if (!mdesc) { +		early_print("\nError: unrecognized/unsupported machine ID" +			    " (r1 = 0x%08x).\n\n", machine_nr); +		dump_machine_table(); /* does not return */ +	} + +	if (__atags_pointer) +		tags = phys_to_virt(__atags_pointer); +	else if (mdesc->atag_offset) +		tags = (void *)(PAGE_OFFSET + mdesc->atag_offset); + +#if defined(CONFIG_DEPRECATED_PARAM_STRUCT) +	/* +	 * If we have the old style parameters, convert them to +	 * a tag list. +	 */ +	if (tags->hdr.tag != ATAG_CORE) +		convert_to_tag_list(tags); +#endif +	if (tags->hdr.tag != ATAG_CORE) { +		early_print("Warning: Neither atags nor dtb found\n"); +		tags = (struct tag *)&default_tags; +	} + +	if (mdesc->fixup) +		mdesc->fixup(tags, &from, &meminfo); + +	if (tags->hdr.tag == ATAG_CORE) { +		if (meminfo.nr_banks != 0) +			squash_mem_tags(tags); +		save_atags(tags); +		parse_tags(tags); +	} + +	/* parse_early_param needs a boot_command_line */ +	strlcpy(boot_command_line, from, COMMAND_LINE_SIZE); + +	return mdesc; +} diff --git a/arch/arm/kernel/atags.c b/arch/arm/kernel/atags_proc.c index 42a1a1415fa..42a1a1415fa 100644 --- a/arch/arm/kernel/atags.c +++ b/arch/arm/kernel/atags_proc.c diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S index 463ff4a0ec8..e337879595e 100644 --- a/arch/arm/kernel/calls.S +++ b/arch/arm/kernel/calls.S @@ -387,6 +387,7 @@  /* 375 */	CALL(sys_setns)  		CALL(sys_process_vm_readv)  		CALL(sys_process_vm_writev) +		CALL(sys_ni_syscall)	/* reserved for sys_kcmp */  #ifndef syscalls_counted  .equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls  #define syscalls_counted diff --git a/arch/arm/kernel/compat.h b/arch/arm/kernel/compat.h deleted file mode 100644 index 39264ab1b9c..00000000000 --- a/arch/arm/kernel/compat.h +++ /dev/null @@ -1,11 +0,0 @@ -/* - *  linux/arch/arm/kernel/compat.h - * - *  Copyright (C) 2001 Russell King - * - * 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. -*/ - -extern void convert_to_tag_list(struct tag *tags); diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 978eac57e04..f45987037bf 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S @@ -94,6 +94,15 @@ ENDPROC(ret_from_fork)  	.equ NR_syscalls,0  #define CALL(x) .equ NR_syscalls,NR_syscalls+1  #include "calls.S" + +/* + * Ensure that the system call table is equal to __NR_syscalls, + * which is the value the rest of the system sees + */ +.ifne NR_syscalls - __NR_syscalls +.error "__NR_syscalls is not equal to the size of the syscall table" +.endif +  #undef CALL  #define CALL(x) .long x diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index ba386bd9410..281bf330124 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c @@ -159,6 +159,12 @@ static int debug_arch_supported(void)  		arch >= ARM_DEBUG_ARCH_V7_1;  } +/* Can we determine the watchpoint access type from the fsr? */ +static int debug_exception_updates_fsr(void) +{ +	return 0; +} +  /* Determine number of WRP registers available. */  static int get_num_wrp_resources(void)  { @@ -604,13 +610,14 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)  		/* Aligned */  		break;  	case 1: -		/* Allow single byte watchpoint. */ -		if (info->ctrl.len == ARM_BREAKPOINT_LEN_1) -			break;  	case 2:  		/* Allow halfword watchpoints and breakpoints. */  		if (info->ctrl.len == ARM_BREAKPOINT_LEN_2)  			break; +	case 3: +		/* Allow single byte watchpoint. */ +		if (info->ctrl.len == ARM_BREAKPOINT_LEN_1) +			break;  	default:  		ret = -EINVAL;  		goto out; @@ -619,18 +626,35 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)  	info->address &= ~alignment_mask;  	info->ctrl.len <<= offset; -	/* -	 * Currently we rely on an overflow handler to take -	 * care of single-stepping the breakpoint when it fires. -	 * In the case of userspace breakpoints on a core with V7 debug, -	 * we can use the mismatch feature as a poor-man's hardware -	 * single-step, but this only works for per-task breakpoints. -	 */ -	if (!bp->overflow_handler && (arch_check_bp_in_kernelspace(bp) || -	    !core_has_mismatch_brps() || !bp->hw.bp_target)) { -		pr_warning("overflow handler required but none found\n"); -		ret = -EINVAL; +	if (!bp->overflow_handler) { +		/* +		 * Mismatch breakpoints are required for single-stepping +		 * breakpoints. +		 */ +		if (!core_has_mismatch_brps()) +			return -EINVAL; + +		/* We don't allow mismatch breakpoints in kernel space. */ +		if (arch_check_bp_in_kernelspace(bp)) +			return -EPERM; + +		/* +		 * Per-cpu breakpoints are not supported by our stepping +		 * mechanism. +		 */ +		if (!bp->hw.bp_target) +			return -EINVAL; + +		/* +		 * We only support specific access types if the fsr +		 * reports them. +		 */ +		if (!debug_exception_updates_fsr() && +		    (info->ctrl.type == ARM_BREAKPOINT_LOAD || +		     info->ctrl.type == ARM_BREAKPOINT_STORE)) +			return -EINVAL;  	} +  out:  	return ret;  } @@ -706,10 +730,12 @@ static void watchpoint_handler(unsigned long addr, unsigned int fsr,  				goto unlock;  			/* Check that the access type matches. */ -			access = (fsr & ARM_FSR_ACCESS_MASK) ? HW_BREAKPOINT_W : -				 HW_BREAKPOINT_R; -			if (!(access & hw_breakpoint_type(wp))) -				goto unlock; +			if (debug_exception_updates_fsr()) { +				access = (fsr & ARM_FSR_ACCESS_MASK) ? +					  HW_BREAKPOINT_W : HW_BREAKPOINT_R; +				if (!(access & hw_breakpoint_type(wp))) +					goto unlock; +			}  			/* We have a winner. */  			info->trigger = addr; diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c index dfcdb9f7c12..e29c3337ca8 100644 --- a/arch/arm/kernel/machine_kexec.c +++ b/arch/arm/kernel/machine_kexec.c @@ -8,7 +8,9 @@  #include <linux/reboot.h>  #include <linux/io.h>  #include <linux/irq.h> +#include <linux/memblock.h>  #include <asm/pgtable.h> +#include <linux/of_fdt.h>  #include <asm/pgalloc.h>  #include <asm/mmu_context.h>  #include <asm/cacheflush.h> @@ -32,6 +34,29 @@ static atomic_t waiting_for_crash_ipi;  int machine_kexec_prepare(struct kimage *image)  { +	struct kexec_segment *current_segment; +	__be32 header; +	int i, err; + +	/* +	 * No segment at default ATAGs address. try to locate +	 * a dtb using magic. +	 */ +	for (i = 0; i < image->nr_segments; i++) { +		current_segment = &image->segment[i]; + +		err = memblock_is_region_memory(current_segment->mem, +						current_segment->memsz); +		if (err) +			return - EINVAL; + +		err = get_user(header, (__be32*)current_segment->buf); +		if (err) +			return err; + +		if (be32_to_cpu(header) == OF_DT_HEADER) +			kexec_boot_atags = current_segment->mem; +	}  	return 0;  } @@ -122,7 +147,9 @@ void machine_kexec(struct kimage *image)  	kexec_start_address = image->start;  	kexec_indirection_page = page_list;  	kexec_mach_type = machine_arch_type; -	kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET; +	if (!kexec_boot_atags) +		kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET; +  	/* copy our kernel relocation code to the control code page */  	memcpy(reboot_code_buffer, diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 3e0fc5f7ed4..739db3a1b2d 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -30,6 +30,9 @@  #include <asm/pgtable.h>  #include <asm/traps.h> +#define CREATE_TRACE_POINTS +#include <trace/events/syscalls.h> +  #define REG_PC	15  #define REG_PSR	16  /* @@ -918,11 +921,11 @@ static int ptrace_syscall_trace(struct pt_regs *regs, int scno,  {  	unsigned long ip; +	current_thread_info()->syscall = scno; +  	if (!test_thread_flag(TIF_SYSCALL_TRACE))  		return scno; -	current_thread_info()->syscall = scno; -  	/*  	 * IP is used to denote syscall entry/exit:  	 * IP = 0 -> entry, =1 -> exit @@ -941,15 +944,19 @@ static int ptrace_syscall_trace(struct pt_regs *regs, int scno,  asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)  { -	int ret = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_ENTER); +	scno = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_ENTER); +	if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) +		trace_sys_enter(regs, scno);  	audit_syscall_entry(AUDIT_ARCH_ARM, scno, regs->ARM_r0, regs->ARM_r1,  			    regs->ARM_r2, regs->ARM_r3); -	return ret; +	return scno;  }  asmlinkage int syscall_trace_exit(struct pt_regs *regs, int scno)  { -	int ret = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_EXIT); +	scno = ptrace_syscall_trace(regs, scno, PTRACE_SYSCALL_EXIT); +	if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) +		trace_sys_exit(regs, scno);  	audit_syscall_exit(regs); -	return ret; +	return scno;  } diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c index f4515393248..e21bac20d90 100644 --- a/arch/arm/kernel/sched_clock.c +++ b/arch/arm/kernel/sched_clock.c @@ -9,6 +9,7 @@  #include <linux/init.h>  #include <linux/jiffies.h>  #include <linux/kernel.h> +#include <linux/moduleparam.h>  #include <linux/sched.h>  #include <linux/syscore_ops.h>  #include <linux/timer.h> @@ -27,6 +28,9 @@ struct clock_data {  static void sched_clock_poll(unsigned long wrap_ticks);  static DEFINE_TIMER(sched_clock_timer, sched_clock_poll, 0, 0); +static int irqtime = -1; + +core_param(irqtime, irqtime, int, 0400);  static struct clock_data cd = {  	.mult	= NSEC_PER_SEC / HZ, @@ -157,6 +161,10 @@ void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate)  	 */  	cd.epoch_ns = 0; +	/* Enable IRQ time accounting if we have a fast enough sched_clock */ +	if (irqtime > 0 || (irqtime == -1 && rate >= 1000000)) +		enable_sched_clock_irqtime(); +  	pr_debug("Registered %pF as sched_clock source\n", read);  } diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index a81dcecc734..0785472460a 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -21,11 +21,9 @@  #include <linux/init.h>  #include <linux/kexec.h>  #include <linux/of_fdt.h> -#include <linux/root_dev.h>  #include <linux/cpu.h>  #include <linux/interrupt.h>  #include <linux/smp.h> -#include <linux/fs.h>  #include <linux/proc_fs.h>  #include <linux/memblock.h>  #include <linux/bug.h> @@ -56,15 +54,9 @@  #include <asm/unwind.h>  #include <asm/memblock.h> -#if defined(CONFIG_DEPRECATED_PARAM_STRUCT) -#include "compat.h" -#endif  #include "atags.h"  #include "tcm.h" -#ifndef MEM_SIZE -#define MEM_SIZE	(16*1024*1024) -#endif  #if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE)  char fpe_type[8]; @@ -145,7 +137,6 @@ static const char *machine_name;  static char __initdata cmd_line[COMMAND_LINE_SIZE];  struct machine_desc *machine_desc __initdata; -static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;  static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };  #define ENDIANNESS ((char)endian_test.l) @@ -583,21 +574,6 @@ static int __init early_mem(char *p)  }  early_param("mem", early_mem); -static void __init -setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz) -{ -#ifdef CONFIG_BLK_DEV_RAM -	extern int rd_size, rd_image_start, rd_prompt, rd_doload; - -	rd_image_start = image_start; -	rd_prompt = prompt; -	rd_doload = doload; - -	if (rd_sz) -		rd_size = rd_sz; -#endif -} -  static void __init request_standard_resources(struct machine_desc *mdesc)  {  	struct memblock_region *region; @@ -643,35 +619,6 @@ static void __init request_standard_resources(struct machine_desc *mdesc)  		request_resource(&ioport_resource, &lp2);  } -/* - *  Tag parsing. - * - * This is the new way of passing data to the kernel at boot time.  Rather - * than passing a fixed inflexible structure to the kernel, we pass a list - * of variable-sized tags to the kernel.  The first tag must be a ATAG_CORE - * tag for the list to be recognised (to distinguish the tagged list from - * a param_struct).  The list is terminated with a zero-length tag (this tag - * is not parsed in any way). - */ -static int __init parse_tag_core(const struct tag *tag) -{ -	if (tag->hdr.size > 2) { -		if ((tag->u.core.flags & 1) == 0) -			root_mountflags &= ~MS_RDONLY; -		ROOT_DEV = old_decode_dev(tag->u.core.rootdev); -	} -	return 0; -} - -__tagtable(ATAG_CORE, parse_tag_core); - -static int __init parse_tag_mem32(const struct tag *tag) -{ -	return arm_add_memory(tag->u.mem.start, tag->u.mem.size); -} - -__tagtable(ATAG_MEM, parse_tag_mem32); -  #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)  struct screen_info screen_info = {   .orig_video_lines	= 30, @@ -681,117 +628,8 @@ struct screen_info screen_info = {   .orig_video_isVGA	= 1,   .orig_video_points	= 8  }; - -static int __init parse_tag_videotext(const struct tag *tag) -{ -	screen_info.orig_x            = tag->u.videotext.x; -	screen_info.orig_y            = tag->u.videotext.y; -	screen_info.orig_video_page   = tag->u.videotext.video_page; -	screen_info.orig_video_mode   = tag->u.videotext.video_mode; -	screen_info.orig_video_cols   = tag->u.videotext.video_cols; -	screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx; -	screen_info.orig_video_lines  = tag->u.videotext.video_lines; -	screen_info.orig_video_isVGA  = tag->u.videotext.video_isvga; -	screen_info.orig_video_points = tag->u.videotext.video_points; -	return 0; -} - -__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);  #endif -static int __init parse_tag_ramdisk(const struct tag *tag) -{ -	setup_ramdisk((tag->u.ramdisk.flags & 1) == 0, -		      (tag->u.ramdisk.flags & 2) == 0, -		      tag->u.ramdisk.start, tag->u.ramdisk.size); -	return 0; -} - -__tagtable(ATAG_RAMDISK, parse_tag_ramdisk); - -static int __init parse_tag_serialnr(const struct tag *tag) -{ -	system_serial_low = tag->u.serialnr.low; -	system_serial_high = tag->u.serialnr.high; -	return 0; -} - -__tagtable(ATAG_SERIAL, parse_tag_serialnr); - -static int __init parse_tag_revision(const struct tag *tag) -{ -	system_rev = tag->u.revision.rev; -	return 0; -} - -__tagtable(ATAG_REVISION, parse_tag_revision); - -static int __init parse_tag_cmdline(const struct tag *tag) -{ -#if defined(CONFIG_CMDLINE_EXTEND) -	strlcat(default_command_line, " ", COMMAND_LINE_SIZE); -	strlcat(default_command_line, tag->u.cmdline.cmdline, -		COMMAND_LINE_SIZE); -#elif defined(CONFIG_CMDLINE_FORCE) -	pr_warning("Ignoring tag cmdline (using the default kernel command line)\n"); -#else -	strlcpy(default_command_line, tag->u.cmdline.cmdline, -		COMMAND_LINE_SIZE); -#endif -	return 0; -} - -__tagtable(ATAG_CMDLINE, parse_tag_cmdline); - -/* - * Scan the tag table for this tag, and call its parse function. - * The tag table is built by the linker from all the __tagtable - * declarations. - */ -static int __init parse_tag(const struct tag *tag) -{ -	extern struct tagtable __tagtable_begin, __tagtable_end; -	struct tagtable *t; - -	for (t = &__tagtable_begin; t < &__tagtable_end; t++) -		if (tag->hdr.tag == t->tag) { -			t->parse(tag); -			break; -		} - -	return t < &__tagtable_end; -} - -/* - * Parse all tags in the list, checking both the global and architecture - * specific tag tables. - */ -static void __init parse_tags(const struct tag *t) -{ -	for (; t->hdr.size; t = tag_next(t)) -		if (!parse_tag(t)) -			printk(KERN_WARNING -				"Ignoring unrecognised tag 0x%08x\n", -				t->hdr.tag); -} - -/* - * This holds our defaults. - */ -static struct init_tags { -	struct tag_header hdr1; -	struct tag_core   core; -	struct tag_header hdr2; -	struct tag_mem32  mem; -	struct tag_header hdr3; -} init_tags __initdata = { -	{ tag_size(tag_core), ATAG_CORE }, -	{ 1, PAGE_SIZE, 0xff }, -	{ tag_size(tag_mem32), ATAG_MEM }, -	{ MEM_SIZE }, -	{ 0, ATAG_NONE } -}; -  static int __init customize_machine(void)  {  	/* customizes platform devices, or adds new ones */ @@ -858,78 +696,6 @@ static void __init reserve_crashkernel(void)  static inline void reserve_crashkernel(void) {}  #endif /* CONFIG_KEXEC */ -static void __init squash_mem_tags(struct tag *tag) -{ -	for (; tag->hdr.size; tag = tag_next(tag)) -		if (tag->hdr.tag == ATAG_MEM) -			tag->hdr.tag = ATAG_NONE; -} - -static struct machine_desc * __init setup_machine_tags(unsigned int nr) -{ -	struct tag *tags = (struct tag *)&init_tags; -	struct machine_desc *mdesc = NULL, *p; -	char *from = default_command_line; - -	init_tags.mem.start = PHYS_OFFSET; - -	/* -	 * locate machine in the list of supported machines. -	 */ -	for_each_machine_desc(p) -		if (nr == p->nr) { -			printk("Machine: %s\n", p->name); -			mdesc = p; -			break; -		} - -	if (!mdesc) { -		early_print("\nError: unrecognized/unsupported machine ID" -			" (r1 = 0x%08x).\n\n", nr); -		dump_machine_table(); /* does not return */ -	} - -	if (__atags_pointer) -		tags = phys_to_virt(__atags_pointer); -	else if (mdesc->atag_offset) -		tags = (void *)(PAGE_OFFSET + mdesc->atag_offset); - -#if defined(CONFIG_DEPRECATED_PARAM_STRUCT) -	/* -	 * If we have the old style parameters, convert them to -	 * a tag list. -	 */ -	if (tags->hdr.tag != ATAG_CORE) -		convert_to_tag_list(tags); -#endif - -	if (tags->hdr.tag != ATAG_CORE) { -#if defined(CONFIG_OF) -		/* -		 * If CONFIG_OF is set, then assume this is a reasonably -		 * modern system that should pass boot parameters -		 */ -		early_print("Warning: Neither atags nor dtb found\n"); -#endif -		tags = (struct tag *)&init_tags; -	} - -	if (mdesc->fixup) -		mdesc->fixup(tags, &from, &meminfo); - -	if (tags->hdr.tag == ATAG_CORE) { -		if (meminfo.nr_banks != 0) -			squash_mem_tags(tags); -		save_atags(tags); -		parse_tags(tags); -	} - -	/* parse_early_param needs a boot_command_line */ -	strlcpy(boot_command_line, from, COMMAND_LINE_SIZE); - -	return mdesc; -} -  static int __init meminfo_cmp(const void *_a, const void *_b)  {  	const struct membank *a = _a, *b = _b; @@ -944,7 +710,7 @@ void __init setup_arch(char **cmdline_p)  	setup_processor();  	mdesc = setup_machine_fdt(__atags_pointer);  	if (!mdesc) -		mdesc = setup_machine_tags(machine_arch_type); +		mdesc = setup_machine_tags(__atags_pointer, machine_arch_type);  	machine_desc = mdesc;  	machine_name = mdesc->name; diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index ebd8ad274d7..d98c37e97d9 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c @@ -51,7 +51,8 @@  struct secondary_data secondary_data;  enum ipi_msg_type { -	IPI_TIMER = 2, +	IPI_WAKEUP, +	IPI_TIMER,  	IPI_RESCHEDULE,  	IPI_CALL_FUNC,  	IPI_CALL_FUNC_SINGLE, @@ -347,7 +348,8 @@ void arch_send_call_function_single_ipi(int cpu)  }  static const char *ipi_types[NR_IPI] = { -#define S(x,s)	[x - IPI_TIMER] = s +#define S(x,s)	[x] = s +	S(IPI_WAKEUP, "CPU wakeup interrupts"),  	S(IPI_TIMER, "Timer broadcast interrupts"),  	S(IPI_RESCHEDULE, "Rescheduling interrupts"),  	S(IPI_CALL_FUNC, "Function call interrupts"), @@ -500,10 +502,13 @@ void handle_IPI(int ipinr, struct pt_regs *regs)  	unsigned int cpu = smp_processor_id();  	struct pt_regs *old_regs = set_irq_regs(regs); -	if (ipinr >= IPI_TIMER && ipinr < IPI_TIMER + NR_IPI) -		__inc_irq_stat(cpu, ipi_irqs[ipinr - IPI_TIMER]); +	if (ipinr < NR_IPI) +		__inc_irq_stat(cpu, ipi_irqs[ipinr]);  	switch (ipinr) { +	case IPI_WAKEUP: +		break; +  	case IPI_TIMER:  		irq_enter();  		ipi_timer(); diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index fef42b21cec..e1f906989bb 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c @@ -11,7 +11,6 @@  #include <linux/init.h>  #include <linux/kernel.h>  #include <linux/clk.h> -#include <linux/cpufreq.h>  #include <linux/delay.h>  #include <linux/device.h>  #include <linux/err.h> @@ -96,7 +95,52 @@ static void twd_timer_stop(struct clock_event_device *clk)  	disable_percpu_irq(clk->irq);  } -#ifdef CONFIG_CPU_FREQ +#ifdef CONFIG_COMMON_CLK + +/* + * Updates clockevent frequency when the cpu frequency changes. + * Called on the cpu that is changing frequency with interrupts disabled. + */ +static void twd_update_frequency(void *new_rate) +{ +	twd_timer_rate = *((unsigned long *) new_rate); + +	clockevents_update_freq(*__this_cpu_ptr(twd_evt), twd_timer_rate); +} + +static int twd_rate_change(struct notifier_block *nb, +	unsigned long flags, void *data) +{ +	struct clk_notifier_data *cnd = data; + +	/* +	 * The twd clock events must be reprogrammed to account for the new +	 * frequency.  The timer is local to a cpu, so cross-call to the +	 * changing cpu. +	 */ +	if (flags == POST_RATE_CHANGE) +		smp_call_function(twd_update_frequency, +				  (void *)&cnd->new_rate, 1); + +	return NOTIFY_OK; +} + +static struct notifier_block twd_clk_nb = { +	.notifier_call = twd_rate_change, +}; + +static int twd_clk_init(void) +{ +	if (twd_evt && *__this_cpu_ptr(twd_evt) && !IS_ERR(twd_clk)) +		return clk_notifier_register(twd_clk, &twd_clk_nb); + +	return 0; +} +core_initcall(twd_clk_init); + +#elif defined (CONFIG_CPU_FREQ) + +#include <linux/cpufreq.h>  /*   * Updates clockevent frequency when the cpu frequency changes. diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index f7945218b8c..b0179b89a04 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -420,20 +420,23 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)  #endif  			instr = *(u32 *) pc;  	} else if (thumb_mode(regs)) { -		get_user(instr, (u16 __user *)pc); +		if (get_user(instr, (u16 __user *)pc)) +			goto die_sig;  		if (is_wide_instruction(instr)) {  			unsigned int instr2; -			get_user(instr2, (u16 __user *)pc+1); +			if (get_user(instr2, (u16 __user *)pc+1)) +				goto die_sig;  			instr <<= 16;  			instr |= instr2;  		} -	} else { -		get_user(instr, (u32 __user *)pc); +	} else if (get_user(instr, (u32 __user *)pc)) { +		goto die_sig;  	}  	if (call_undef_hook(regs, instr) == 0)  		return; +die_sig:  #ifdef CONFIG_DEBUG_USER  	if (user_debug & UDBG_UNDEFINED) {  		printk(KERN_INFO "%s (%d): undefined instruction: pc=%p\n", diff --git a/arch/arm/lib/delay.c b/arch/arm/lib/delay.c index d6dacc69254..395d5fbb8fa 100644 --- a/arch/arm/lib/delay.c +++ b/arch/arm/lib/delay.c @@ -59,6 +59,7 @@ void __init init_current_timer_delay(unsigned long freq)  {  	pr_info("Switching to timer-based delay loop\n");  	lpj_fine			= freq / HZ; +	loops_per_jiffy			= lpj_fine;  	arm_delay_ops.delay		= __timer_delay;  	arm_delay_ops.const_udelay	= __timer_const_udelay;  	arm_delay_ops.udelay		= __timer_udelay; diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S index 11093a7c3e3..9b06bb41fca 100644 --- a/arch/arm/lib/getuser.S +++ b/arch/arm/lib/getuser.S @@ -16,8 +16,9 @@   * __get_user_X   *   * Inputs:	r0 contains the address + *		r1 contains the address limit, which must be preserved   * Outputs:	r0 is the error code - *		r2, r3 contains the zero-extended value + *		r2 contains the zero-extended value   *		lr corrupted   *   * No other registers must be altered.  (see <asm/uaccess.h> @@ -27,33 +28,39 @@   * Note also that it is intended that __get_user_bad is not global.   */  #include <linux/linkage.h> +#include <asm/assembler.h>  #include <asm/errno.h>  #include <asm/domain.h>  ENTRY(__get_user_1) +	check_uaccess r0, 1, r1, r2, __get_user_bad  1: TUSER(ldrb)	r2, [r0]  	mov	r0, #0  	mov	pc, lr  ENDPROC(__get_user_1)  ENTRY(__get_user_2) -#ifdef CONFIG_THUMB2_KERNEL -2: TUSER(ldrb)	r2, [r0] -3: TUSER(ldrb)	r3, [r0, #1] +	check_uaccess r0, 2, r1, r2, __get_user_bad +#ifdef CONFIG_CPU_USE_DOMAINS +rb	.req	ip +2:	ldrbt	r2, [r0], #1 +3:	ldrbt	rb, [r0], #0  #else -2: TUSER(ldrb)	r2, [r0], #1 -3: TUSER(ldrb)	r3, [r0] +rb	.req	r0 +2:	ldrb	r2, [r0] +3:	ldrb	rb, [r0, #1]  #endif  #ifndef __ARMEB__ -	orr	r2, r2, r3, lsl #8 +	orr	r2, r2, rb, lsl #8  #else -	orr	r2, r3, r2, lsl #8 +	orr	r2, rb, r2, lsl #8  #endif  	mov	r0, #0  	mov	pc, lr  ENDPROC(__get_user_2)  ENTRY(__get_user_4) +	check_uaccess r0, 4, r1, r2, __get_user_bad  4: TUSER(ldr)	r2, [r0]  	mov	r0, #0  	mov	pc, lr diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S index 7db25990c58..3d73dcb959b 100644 --- a/arch/arm/lib/putuser.S +++ b/arch/arm/lib/putuser.S @@ -16,6 +16,7 @@   * __put_user_X   *   * Inputs:	r0 contains the address + *		r1 contains the address limit, which must be preserved   *		r2, r3 contains the value   * Outputs:	r0 is the error code   *		lr corrupted @@ -27,16 +28,19 @@   * Note also that it is intended that __put_user_bad is not global.   */  #include <linux/linkage.h> +#include <asm/assembler.h>  #include <asm/errno.h>  #include <asm/domain.h>  ENTRY(__put_user_1) +	check_uaccess r0, 1, r1, ip, __put_user_bad  1: TUSER(strb)	r2, [r0]  	mov	r0, #0  	mov	pc, lr  ENDPROC(__put_user_1)  ENTRY(__put_user_2) +	check_uaccess r0, 2, r1, ip, __put_user_bad  	mov	ip, r2, lsr #8  #ifdef CONFIG_THUMB2_KERNEL  #ifndef __ARMEB__ @@ -60,12 +64,14 @@ ENTRY(__put_user_2)  ENDPROC(__put_user_2)  ENTRY(__put_user_4) +	check_uaccess r0, 4, r1, ip, __put_user_bad  4: TUSER(str)	r2, [r0]  	mov	r0, #0  	mov	pc, lr  ENDPROC(__put_user_4)  ENTRY(__put_user_8) +	check_uaccess r0, 8, r1, ip, __put_user_bad  #ifdef CONFIG_THUMB2_KERNEL  5: TUSER(str)	r2, [r0]  6: TUSER(str)	r3, [r0, #4] diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index 36c3984aaa4..090e32b0cd5 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c @@ -139,7 +139,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)  		__raw_writel(virt_to_phys(exynos4_secondary_startup),  			CPU1_BOOT_REG); -		gic_raise_softirq(cpumask_of(cpu), 1); +		gic_raise_softirq(cpumask_of(cpu), 0);  		if (pen_release == -1)  			break; diff --git a/arch/arm/mach-imx/clk-imx25.c b/arch/arm/mach-imx/clk-imx25.c index fdd8cc87c9f..d20d4795f4e 100644 --- a/arch/arm/mach-imx/clk-imx25.c +++ b/arch/arm/mach-imx/clk-imx25.c @@ -222,10 +222,8 @@ int __init mx25_clocks_init(void)  	clk_register_clkdev(clk[lcdc_ipg], "ipg", "imx-fb.0");  	clk_register_clkdev(clk[lcdc_ahb], "ahb", "imx-fb.0");  	clk_register_clkdev(clk[wdt_ipg], NULL, "imx2-wdt.0"); -	clk_register_clkdev(clk[ssi1_ipg_per], "per", "imx-ssi.0"); -	clk_register_clkdev(clk[ssi1_ipg], "ipg", "imx-ssi.0"); -	clk_register_clkdev(clk[ssi2_ipg_per], "per", "imx-ssi.1"); -	clk_register_clkdev(clk[ssi2_ipg], "ipg", "imx-ssi.1"); +	clk_register_clkdev(clk[ssi1_ipg], NULL, "imx-ssi.0"); +	clk_register_clkdev(clk[ssi2_ipg], NULL, "imx-ssi.1");  	clk_register_clkdev(clk[esdhc1_ipg_per], "per", "sdhci-esdhc-imx25.0");  	clk_register_clkdev(clk[esdhc1_ipg], "ipg", "sdhci-esdhc-imx25.0");  	clk_register_clkdev(clk[esdhc1_ahb], "ahb", "sdhci-esdhc-imx25.0"); @@ -243,6 +241,6 @@ int __init mx25_clocks_init(void)  	clk_register_clkdev(clk[sdma_ahb], "ahb", "imx35-sdma");  	clk_register_clkdev(clk[iim_ipg], "iim", NULL); -	mxc_timer_init(MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54); +	mxc_timer_init(MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), MX25_INT_GPT1);  	return 0;  } diff --git a/arch/arm/mach-imx/clk-imx35.c b/arch/arm/mach-imx/clk-imx35.c index c6422fb10ba..65fb8bcd86c 100644 --- a/arch/arm/mach-imx/clk-imx35.c +++ b/arch/arm/mach-imx/clk-imx35.c @@ -230,10 +230,8 @@ int __init mx35_clocks_init()  	clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb");  	clk_register_clkdev(clk[owire_gate], NULL, "mxc_w1");  	clk_register_clkdev(clk[sdma_gate], NULL, "imx35-sdma"); -	clk_register_clkdev(clk[ipg], "ipg", "imx-ssi.0"); -	clk_register_clkdev(clk[ssi1_div_post], "per", "imx-ssi.0"); -	clk_register_clkdev(clk[ipg], "ipg", "imx-ssi.1"); -	clk_register_clkdev(clk[ssi2_div_post], "per", "imx-ssi.1"); +	clk_register_clkdev(clk[ssi1_gate], NULL, "imx-ssi.0"); +	clk_register_clkdev(clk[ssi2_gate], NULL, "imx-ssi.1");  	/* i.mx35 has the i.mx21 type uart */  	clk_register_clkdev(clk[uart1_gate], "per", "imx21-uart.0");  	clk_register_clkdev(clk[ipg], "ipg", "imx21-uart.0"); diff --git a/arch/arm/mach-imx/mach-armadillo5x0.c b/arch/arm/mach-imx/mach-armadillo5x0.c index 2c6ab3273f9..5985ed1b8c9 100644 --- a/arch/arm/mach-imx/mach-armadillo5x0.c +++ b/arch/arm/mach-imx/mach-armadillo5x0.c @@ -526,7 +526,8 @@ static void __init armadillo5x0_init(void)  	imx31_add_mxc_nand(&armadillo5x0_nand_board_info);  	/* set NAND page size to 2k if not configured via boot mode pins */ -	__raw_writel(__raw_readl(MXC_CCM_RCSR) | (1 << 30), MXC_CCM_RCSR); +	__raw_writel(__raw_readl(mx3_ccm_base + MXC_CCM_RCSR) | +					(1 << 30), mx3_ccm_base + MXC_CCM_RCSR);  	/* RTC */  	/* Get RTC IRQ and register the chip */ diff --git a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c index f264ddddd47..5823a2e6512 100644 --- a/arch/arm/mach-imx/mach-imx27_visstrim_m10.c +++ b/arch/arm/mach-imx/mach-imx27_visstrim_m10.c @@ -32,13 +32,13 @@  #include <linux/delay.h>  #include <linux/dma-mapping.h>  #include <linux/leds.h> -#include <linux/memblock.h>  #include <media/soc_camera.h>  #include <sound/tlv320aic32x4.h>  #include <asm/mach-types.h>  #include <asm/mach/arch.h>  #include <asm/mach/time.h>  #include <asm/system_info.h> +#include <asm/memblock.h>  #include <mach/common.h>  #include <mach/hardware.h>  #include <mach/iomux-mx27.h> @@ -233,10 +233,8 @@ static void __init visstrim_camera_init(void)  static void __init visstrim_reserve(void)  {  	/* reserve 4 MiB for mx2-camera */ -	mx2_camera_base = memblock_alloc(MX2_CAMERA_BUF_SIZE, +	mx2_camera_base = memblock_steal(MX2_CAMERA_BUF_SIZE,  			MX2_CAMERA_BUF_SIZE); -	memblock_free(mx2_camera_base, MX2_CAMERA_BUF_SIZE); -	memblock_remove(mx2_camera_base, MX2_CAMERA_BUF_SIZE);  }  /* GPIOs used as events for applications */ diff --git a/arch/arm/mach-integrator/common.h b/arch/arm/mach-integrator/common.h index 899561d8db2..c3ff21b5ea2 100644 --- a/arch/arm/mach-integrator/common.h +++ b/arch/arm/mach-integrator/common.h @@ -1,3 +1,6 @@ +#include <linux/amba/serial.h> +extern struct amba_pl010_data integrator_uart_data;  void integrator_init_early(void); +int integrator_init(bool is_cp);  void integrator_reserve(void);  void integrator_restart(char, const char *); diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index 3fa6c51390d..1772c024e78 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c @@ -33,7 +33,9 @@  #include <asm/mach/time.h>  #include <asm/pgtable.h> -static struct amba_pl010_data integrator_uart_data; +#include "common.h" + +#ifdef CONFIG_ATAGS  #define INTEGRATOR_RTC_IRQ	{ IRQ_RTCINT }  #define INTEGRATOR_UART0_IRQ	{ IRQ_UARTINT0 } @@ -61,7 +63,7 @@ static struct amba_device *amba_devs[] __initdata = {  	&kmi1_device,  }; -static int __init integrator_init(void) +int __init integrator_init(bool is_cp)  {  	int i; @@ -70,7 +72,7 @@ static int __init integrator_init(void)  	 * hard-code them. The Integator/CP and forward have proper cell IDs.  	 * Else we leave them undefined to the bus driver can autoprobe them.  	 */ -	if (machine_is_integrator()) { +	if (!is_cp) {  		rtc_device.periphid	= 0x00041030;  		uart0_device.periphid	= 0x00041010;  		uart1_device.periphid	= 0x00041010; @@ -86,7 +88,7 @@ static int __init integrator_init(void)  	return 0;  } -arch_initcall(integrator_init); +#endif  /*   * On the Integrator platform, the port RTS and DTR are provided by @@ -101,11 +103,14 @@ arch_initcall(integrator_init);  static void integrator_uart_set_mctrl(struct amba_device *dev, void __iomem *base, unsigned int mctrl)  {  	unsigned int ctrls = 0, ctrlc = 0, rts_mask, dtr_mask; +	u32 phybase = dev->res.start; -	if (dev == &uart0_device) { +	if (phybase == INTEGRATOR_UART0_BASE) { +		/* UART0 */  		rts_mask = 1 << 4;  		dtr_mask = 1 << 5;  	} else { +		/* UART1 */  		rts_mask = 1 << 6;  		dtr_mask = 1 << 7;  	} @@ -124,7 +129,7 @@ static void integrator_uart_set_mctrl(struct amba_device *dev, void __iomem *bas  	__raw_writel(ctrlc, SC_CTRLC);  } -static struct amba_pl010_data integrator_uart_data = { +struct amba_pl010_data integrator_uart_data = {  	.set_mctrl = integrator_uart_set_mctrl,  }; diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 3b2267529f5..ff1255ae712 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c @@ -34,6 +34,9 @@  #include <linux/mtd/physmap.h>  #include <linux/clk.h>  #include <linux/platform_data/clk-integrator.h> +#include <linux/of_irq.h> +#include <linux/of_address.h> +#include <linux/of_platform.h>  #include <video/vga.h>  #include <mach/hardware.h> @@ -161,23 +164,6 @@ static void __init ap_map_io(void)  	vga_base = PCI_MEMORY_VADDR;  } -#define INTEGRATOR_SC_VALID_INT	0x003fffff - -static void __init ap_init_irq(void) -{ -	/* Disable all interrupts initially. */ -	/* Do the core module ones */ -	writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); - -	/* do the header card stuff next */ -	writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); -	writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); - -	fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START, -		-1, INTEGRATOR_SC_VALID_INT, NULL); -	integrator_clk_init(false); -} -  #ifdef CONFIG_PM  static unsigned long ic_irq_enable; @@ -270,50 +256,6 @@ static struct physmap_flash_data ap_flash_data = {  	.set_vpp	= ap_flash_set_vpp,  }; -static struct resource cfi_flash_resource = { -	.start		= INTEGRATOR_FLASH_BASE, -	.end		= INTEGRATOR_FLASH_BASE + INTEGRATOR_FLASH_SIZE - 1, -	.flags		= IORESOURCE_MEM, -}; - -static struct platform_device cfi_flash_device = { -	.name		= "physmap-flash", -	.id		= 0, -	.dev		= { -		.platform_data	= &ap_flash_data, -	}, -	.num_resources	= 1, -	.resource	= &cfi_flash_resource, -}; - -static void __init ap_init(void) -{ -	unsigned long sc_dec; -	int i; - -	platform_device_register(&cfi_flash_device); - -	sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET); -	for (i = 0; i < 4; i++) { -		struct lm_device *lmdev; - -		if ((sc_dec & (16 << i)) == 0) -			continue; - -		lmdev = kzalloc(sizeof(struct lm_device), GFP_KERNEL); -		if (!lmdev) -			continue; - -		lmdev->resource.start = 0xc0000000 + 0x10000000 * i; -		lmdev->resource.end = lmdev->resource.start + 0x0fffffff; -		lmdev->resource.flags = IORESOURCE_MEM; -		lmdev->irq = IRQ_AP_EXPINT0 + i; -		lmdev->id = i; - -		lm_device_register(lmdev); -	} -} -  /*   * Where is the timer (VA)?   */ @@ -328,9 +270,9 @@ static u32 notrace integrator_read_sched_clock(void)  	return -readl((void __iomem *) TIMER2_VA_BASE + TIMER_VALUE);  } -static void integrator_clocksource_init(unsigned long inrate) +static void integrator_clocksource_init(unsigned long inrate, +					void __iomem *base)  { -	void __iomem *base = (void __iomem *)TIMER2_VA_BASE;  	u32 ctrl = TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC;  	unsigned long rate = inrate; @@ -347,7 +289,7 @@ static void integrator_clocksource_init(unsigned long inrate)  	setup_sched_clock(integrator_read_sched_clock, 16, rate);  } -static void __iomem * const clkevt_base = (void __iomem *)TIMER1_VA_BASE; +static void __iomem * clkevt_base;  /*   * IRQ handler for the timer @@ -419,11 +361,13 @@ static struct irqaction integrator_timer_irq = {  	.dev_id		= &integrator_clockevent,  }; -static void integrator_clockevent_init(unsigned long inrate) +static void integrator_clockevent_init(unsigned long inrate, +				void __iomem *base, int irq)  {  	unsigned long rate = inrate;  	unsigned int ctrl = 0; +	clkevt_base = base;  	/* Calculate and program a divisor */  	if (rate > 0x100000 * HZ) {  		rate /= 256; @@ -435,7 +379,7 @@ static void integrator_clockevent_init(unsigned long inrate)  	timer_reload = rate / HZ;  	writel(ctrl, clkevt_base + TIMER_CTRL); -	setup_irq(IRQ_TIMERINT1, &integrator_timer_irq); +	setup_irq(irq, &integrator_timer_irq);  	clockevents_config_and_register(&integrator_clockevent,  					rate,  					1, @@ -446,9 +390,153 @@ void __init ap_init_early(void)  {  } +#ifdef CONFIG_OF + +static void __init ap_init_timer_of(void) +{ +	struct device_node *node; +	const char *path; +	void __iomem *base; +	int err; +	int irq; +	struct clk *clk; +	unsigned long rate; + +	clk = clk_get_sys("ap_timer", NULL); +	BUG_ON(IS_ERR(clk)); +	clk_prepare_enable(clk); +	rate = clk_get_rate(clk); + +	err = of_property_read_string(of_aliases, +				"arm,timer-primary", &path); +	if (WARN_ON(err)) +		return; +	node = of_find_node_by_path(path); +	base = of_iomap(node, 0); +	if (WARN_ON(!base)) +		return; +	writel(0, base + TIMER_CTRL); +	integrator_clocksource_init(rate, base); + +	err = of_property_read_string(of_aliases, +				"arm,timer-secondary", &path); +	if (WARN_ON(err)) +		return; +	node = of_find_node_by_path(path); +	base = of_iomap(node, 0); +	if (WARN_ON(!base)) +		return; +	irq = irq_of_parse_and_map(node, 0); +	writel(0, base + TIMER_CTRL); +	integrator_clockevent_init(rate, base, irq); +} + +static struct sys_timer ap_of_timer = { +	.init		= ap_init_timer_of, +}; + +static const struct of_device_id fpga_irq_of_match[] __initconst = { +	{ .compatible = "arm,versatile-fpga-irq", .data = fpga_irq_of_init, }, +	{ /* Sentinel */ } +}; + +static void __init ap_init_irq_of(void) +{ +	/* disable core module IRQs */ +	writel(0xffffffffU, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); +	of_irq_init(fpga_irq_of_match); +	integrator_clk_init(false); +} + +/* For the Device Tree, add in the UART callbacks as AUXDATA */ +static struct of_dev_auxdata ap_auxdata_lookup[] __initdata = { +	OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_RTC_BASE, +		"rtc", NULL), +	OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART0_BASE, +		"uart0", &integrator_uart_data), +	OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART1_BASE, +		"uart1", &integrator_uart_data), +	OF_DEV_AUXDATA("arm,primecell", KMI0_BASE, +		"kmi0", NULL), +	OF_DEV_AUXDATA("arm,primecell", KMI1_BASE, +		"kmi1", NULL), +	OF_DEV_AUXDATA("cfi-flash", INTEGRATOR_FLASH_BASE, +		"physmap-flash", &ap_flash_data), +	{ /* sentinel */ }, +}; + +static void __init ap_init_of(void) +{ +	unsigned long sc_dec; +	int i; + +	of_platform_populate(NULL, of_default_bus_match_table, +			ap_auxdata_lookup, NULL); + +	sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET); +	for (i = 0; i < 4; i++) { +		struct lm_device *lmdev; + +		if ((sc_dec & (16 << i)) == 0) +			continue; + +		lmdev = kzalloc(sizeof(struct lm_device), GFP_KERNEL); +		if (!lmdev) +			continue; + +		lmdev->resource.start = 0xc0000000 + 0x10000000 * i; +		lmdev->resource.end = lmdev->resource.start + 0x0fffffff; +		lmdev->resource.flags = IORESOURCE_MEM; +		lmdev->irq = IRQ_AP_EXPINT0 + i; +		lmdev->id = i; + +		lm_device_register(lmdev); +	} +} + +static const char * ap_dt_board_compat[] = { +	"arm,integrator-ap", +	NULL, +}; + +DT_MACHINE_START(INTEGRATOR_AP_DT, "ARM Integrator/AP (Device Tree)") +	.reserve	= integrator_reserve, +	.map_io		= ap_map_io, +	.nr_irqs	= NR_IRQS_INTEGRATOR_AP, +	.init_early	= ap_init_early, +	.init_irq	= ap_init_irq_of, +	.handle_irq	= fpga_handle_irq, +	.timer		= &ap_of_timer, +	.init_machine	= ap_init_of, +	.restart	= integrator_restart, +	.dt_compat      = ap_dt_board_compat, +MACHINE_END + +#endif + +#ifdef CONFIG_ATAGS +  /* - * Set up timer(s). + * This is where non-devicetree initialization code is collected and stashed + * for eventual deletion.   */ + +static struct resource cfi_flash_resource = { +	.start		= INTEGRATOR_FLASH_BASE, +	.end		= INTEGRATOR_FLASH_BASE + INTEGRATOR_FLASH_SIZE - 1, +	.flags		= IORESOURCE_MEM, +}; + +static struct platform_device cfi_flash_device = { +	.name		= "physmap-flash", +	.id		= 0, +	.dev		= { +		.platform_data	= &ap_flash_data, +	}, +	.num_resources	= 1, +	.resource	= &cfi_flash_resource, +}; +  static void __init ap_init_timer(void)  {  	struct clk *clk; @@ -463,14 +551,62 @@ static void __init ap_init_timer(void)  	writel(0, TIMER1_VA_BASE + TIMER_CTRL);  	writel(0, TIMER2_VA_BASE + TIMER_CTRL); -	integrator_clocksource_init(rate); -	integrator_clockevent_init(rate); +	integrator_clocksource_init(rate, (void __iomem *)TIMER2_VA_BASE); +	integrator_clockevent_init(rate, (void __iomem *)TIMER1_VA_BASE, +				IRQ_TIMERINT1);  }  static struct sys_timer ap_timer = {  	.init		= ap_init_timer,  }; +#define INTEGRATOR_SC_VALID_INT	0x003fffff + +static void __init ap_init_irq(void) +{ +	/* Disable all interrupts initially. */ +	/* Do the core module ones */ +	writel(-1, VA_CMIC_BASE + IRQ_ENABLE_CLEAR); + +	/* do the header card stuff next */ +	writel(-1, VA_IC_BASE + IRQ_ENABLE_CLEAR); +	writel(-1, VA_IC_BASE + FIQ_ENABLE_CLEAR); + +	fpga_irq_init(VA_IC_BASE, "SC", IRQ_PIC_START, +		-1, INTEGRATOR_SC_VALID_INT, NULL); +	integrator_clk_init(false); +} + +static void __init ap_init(void) +{ +	unsigned long sc_dec; +	int i; + +	platform_device_register(&cfi_flash_device); + +	sc_dec = readl(VA_SC_BASE + INTEGRATOR_SC_DEC_OFFSET); +	for (i = 0; i < 4; i++) { +		struct lm_device *lmdev; + +		if ((sc_dec & (16 << i)) == 0) +			continue; + +		lmdev = kzalloc(sizeof(struct lm_device), GFP_KERNEL); +		if (!lmdev) +			continue; + +		lmdev->resource.start = 0xc0000000 + 0x10000000 * i; +		lmdev->resource.end = lmdev->resource.start + 0x0fffffff; +		lmdev->resource.flags = IORESOURCE_MEM; +		lmdev->irq = IRQ_AP_EXPINT0 + i; +		lmdev->id = i; + +		lm_device_register(lmdev); +	} + +	integrator_init(false); +} +  MACHINE_START(INTEGRATOR, "ARM-Integrator")  	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */  	.atag_offset	= 0x100, @@ -484,3 +620,5 @@ MACHINE_START(INTEGRATOR, "ARM-Integrator")  	.init_machine	= ap_init,  	.restart	= integrator_restart,  MACHINE_END + +#endif diff --git a/arch/arm/mach-integrator/integrator_cp.c b/arch/arm/mach-integrator/integrator_cp.c index 82d5c837cc7..f51363e2d6f 100644 --- a/arch/arm/mach-integrator/integrator_cp.c +++ b/arch/arm/mach-integrator/integrator_cp.c @@ -23,6 +23,9 @@  #include <linux/gfp.h>  #include <linux/mtd/physmap.h>  #include <linux/platform_data/clk-integrator.h> +#include <linux/of_irq.h> +#include <linux/of_address.h> +#include <linux/of_platform.h>  #include <mach/hardware.h>  #include <mach/platform.h> @@ -49,16 +52,9 @@  #include "common.h"  #define INTCP_PA_FLASH_BASE		0x24000000 -#define INTCP_FLASH_SIZE		SZ_32M  #define INTCP_PA_CLCD_BASE		0xc0000000 -#define INTCP_VA_CIC_BASE		__io_address(INTEGRATOR_HDR_BASE + 0x40) -#define INTCP_VA_PIC_BASE		__io_address(INTEGRATOR_IC_BASE) -#define INTCP_VA_SIC_BASE		__io_address(INTEGRATOR_CP_SIC_BASE) - -#define INTCP_ETH_SIZE			0x10 -  #define INTCP_VA_CTRL_BASE		IO_ADDRESS(INTEGRATOR_CP_CTL_BASE)  #define INTCP_FLASHPROG			0x04  #define CINTEGRATOR_FLASHPROG_FLVPPEN	(1 << 0) @@ -143,37 +139,6 @@ static void __init intcp_map_io(void)  	iotable_init(intcp_io_desc, ARRAY_SIZE(intcp_io_desc));  } -static void __init intcp_init_irq(void) -{ -	u32 pic_mask, cic_mask, sic_mask; - -	/* These masks are for the HW IRQ registers */ -	pic_mask = ~((~0u) << (11 - IRQ_PIC_START)); -	pic_mask |= (~((~0u) << (29 - 22))) << 22; -	cic_mask = ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START)); -	sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START)); - -	/* -	 * Disable all interrupt sources -	 */ -	writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR); -	writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR); -	writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR); -	writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR); -	writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR); -	writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR); - -	fpga_irq_init(INTCP_VA_PIC_BASE, "PIC", IRQ_PIC_START, -		      -1, pic_mask, NULL); - -	fpga_irq_init(INTCP_VA_CIC_BASE, "CIC", IRQ_CIC_START, -		      -1, cic_mask, NULL); - -	fpga_irq_init(INTCP_VA_SIC_BASE, "SIC", IRQ_SIC_START, -		      IRQ_CP_CPPLDINT, sic_mask, NULL); -	integrator_clk_init(true); -} -  /*   * Flash handling.   */ @@ -216,47 +181,6 @@ static struct physmap_flash_data intcp_flash_data = {  	.set_vpp	= intcp_flash_set_vpp,  }; -static struct resource intcp_flash_resource = { -	.start		= INTCP_PA_FLASH_BASE, -	.end		= INTCP_PA_FLASH_BASE + INTCP_FLASH_SIZE - 1, -	.flags		= IORESOURCE_MEM, -}; - -static struct platform_device intcp_flash_device = { -	.name		= "physmap-flash", -	.id		= 0, -	.dev		= { -		.platform_data	= &intcp_flash_data, -	}, -	.num_resources	= 1, -	.resource	= &intcp_flash_resource, -}; - -static struct resource smc91x_resources[] = { -	[0] = { -		.start	= INTEGRATOR_CP_ETH_BASE, -		.end	= INTEGRATOR_CP_ETH_BASE + INTCP_ETH_SIZE - 1, -		.flags	= IORESOURCE_MEM, -	}, -	[1] = { -		.start	= IRQ_CP_ETHINT, -		.end	= IRQ_CP_ETHINT, -		.flags	= IORESOURCE_IRQ, -	}, -}; - -static struct platform_device smc91x_device = { -	.name		= "smc91x", -	.id		= 0, -	.num_resources	= ARRAY_SIZE(smc91x_resources), -	.resource	= smc91x_resources, -}; - -static struct platform_device *intcp_devs[] __initdata = { -	&intcp_flash_device, -	&smc91x_device, -}; -  /*   * It seems that the card insertion interrupt remains active after   * we've acknowledged it.  We therefore ignore the interrupt, and @@ -278,16 +202,6 @@ static struct mmci_platform_data mmc_data = {  	.gpio_cd	= -1,  }; -#define INTEGRATOR_CP_MMC_IRQS	{ IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 } -#define INTEGRATOR_CP_AACI_IRQS	{ IRQ_CP_AACIINT } - -static AMBA_APB_DEVICE(mmc, "mmci", 0, INTEGRATOR_CP_MMC_BASE, -	INTEGRATOR_CP_MMC_IRQS, &mmc_data); - -static AMBA_APB_DEVICE(aaci, "aaci", 0, INTEGRATOR_CP_AACI_BASE, -	INTEGRATOR_CP_AACI_IRQS, NULL); - -  /*   * CLCD support   */ @@ -338,15 +252,6 @@ static struct clcd_board clcd_data = {  	.remove		= versatile_clcd_remove_dma,  }; -static AMBA_AHB_DEVICE(clcd, "clcd", 0, INTCP_PA_CLCD_BASE, -	{ IRQ_CP_CLCDCINT }, &clcd_data); - -static struct amba_device *amba_devs[] __initdata = { -	&mmc_device, -	&aaci_device, -	&clcd_device, -}; -  #define REFCOUNTER (__io_address(INTEGRATOR_HDR_BASE) + 0x28)  static void __init intcp_init_early(void) @@ -356,16 +261,193 @@ static void __init intcp_init_early(void)  #endif  } -static void __init intcp_init(void) +static void __init intcp_timer_init_of(void)  { -	int i; +	struct device_node *node; +	const char *path; +	void __iomem *base; +	int err; +	int irq; -	platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs)); +	err = of_property_read_string(of_aliases, +				"arm,timer-primary", &path); +	if (WARN_ON(err)) +		return; +	node = of_find_node_by_path(path); +	base = of_iomap(node, 0); +	if (WARN_ON(!base)) +		return; +	writel(0, base + TIMER_CTRL); +	sp804_clocksource_init(base, node->name); -	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { -		struct amba_device *d = amba_devs[i]; -		amba_device_register(d, &iomem_resource); -	} +	err = of_property_read_string(of_aliases, +				"arm,timer-secondary", &path); +	if (WARN_ON(err)) +		return; +	node = of_find_node_by_path(path); +	base = of_iomap(node, 0); +	if (WARN_ON(!base)) +		return; +	irq = irq_of_parse_and_map(node, 0); +	writel(0, base + TIMER_CTRL); +	sp804_clockevents_init(base, irq, node->name); +} + +static struct sys_timer cp_of_timer = { +	.init		= intcp_timer_init_of, +}; + +#ifdef CONFIG_OF + +static const struct of_device_id fpga_irq_of_match[] __initconst = { +	{ .compatible = "arm,versatile-fpga-irq", .data = fpga_irq_of_init, }, +	{ /* Sentinel */ } +}; + +static void __init intcp_init_irq_of(void) +{ +	of_irq_init(fpga_irq_of_match); +	integrator_clk_init(true); +} + +/* + * For the Device Tree, add in the UART, MMC and CLCD specifics as AUXDATA + * and enforce the bus names since these are used for clock lookups. + */ +static struct of_dev_auxdata intcp_auxdata_lookup[] __initdata = { +	OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_RTC_BASE, +		"rtc", NULL), +	OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART0_BASE, +		"uart0", &integrator_uart_data), +	OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_UART1_BASE, +		"uart1", &integrator_uart_data), +	OF_DEV_AUXDATA("arm,primecell", KMI0_BASE, +		"kmi0", NULL), +	OF_DEV_AUXDATA("arm,primecell", KMI1_BASE, +		"kmi1", NULL), +	OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_CP_MMC_BASE, +		"mmci", &mmc_data), +	OF_DEV_AUXDATA("arm,primecell", INTEGRATOR_CP_AACI_BASE, +		"aaci", &mmc_data), +	OF_DEV_AUXDATA("arm,primecell", INTCP_PA_CLCD_BASE, +		"clcd", &clcd_data), +	OF_DEV_AUXDATA("cfi-flash", INTCP_PA_FLASH_BASE, +		"physmap-flash", &intcp_flash_data), +	{ /* sentinel */ }, +}; + +static void __init intcp_init_of(void) +{ +	of_platform_populate(NULL, of_default_bus_match_table, +			intcp_auxdata_lookup, NULL); +} + +static const char * intcp_dt_board_compat[] = { +	"arm,integrator-cp", +	NULL, +}; + +DT_MACHINE_START(INTEGRATOR_CP_DT, "ARM Integrator/CP (Device Tree)") +	.reserve	= integrator_reserve, +	.map_io		= intcp_map_io, +	.nr_irqs	= NR_IRQS_INTEGRATOR_CP, +	.init_early	= intcp_init_early, +	.init_irq	= intcp_init_irq_of, +	.handle_irq	= fpga_handle_irq, +	.timer		= &cp_of_timer, +	.init_machine	= intcp_init_of, +	.restart	= integrator_restart, +	.dt_compat      = intcp_dt_board_compat, +MACHINE_END + +#endif + +#ifdef CONFIG_ATAGS + +/* + * This is where non-devicetree initialization code is collected and stashed + * for eventual deletion. + */ + +#define INTCP_FLASH_SIZE		SZ_32M + +static struct resource intcp_flash_resource = { +	.start		= INTCP_PA_FLASH_BASE, +	.end		= INTCP_PA_FLASH_BASE + INTCP_FLASH_SIZE - 1, +	.flags		= IORESOURCE_MEM, +}; + +static struct platform_device intcp_flash_device = { +	.name		= "physmap-flash", +	.id		= 0, +	.dev		= { +		.platform_data	= &intcp_flash_data, +	}, +	.num_resources	= 1, +	.resource	= &intcp_flash_resource, +}; + +#define INTCP_ETH_SIZE			0x10 + +static struct resource smc91x_resources[] = { +	[0] = { +		.start	= INTEGRATOR_CP_ETH_BASE, +		.end	= INTEGRATOR_CP_ETH_BASE + INTCP_ETH_SIZE - 1, +		.flags	= IORESOURCE_MEM, +	}, +	[1] = { +		.start	= IRQ_CP_ETHINT, +		.end	= IRQ_CP_ETHINT, +		.flags	= IORESOURCE_IRQ, +	}, +}; + +static struct platform_device smc91x_device = { +	.name		= "smc91x", +	.id		= 0, +	.num_resources	= ARRAY_SIZE(smc91x_resources), +	.resource	= smc91x_resources, +}; + +static struct platform_device *intcp_devs[] __initdata = { +	&intcp_flash_device, +	&smc91x_device, +}; + +#define INTCP_VA_CIC_BASE		__io_address(INTEGRATOR_HDR_BASE + 0x40) +#define INTCP_VA_PIC_BASE		__io_address(INTEGRATOR_IC_BASE) +#define INTCP_VA_SIC_BASE		__io_address(INTEGRATOR_CP_SIC_BASE) + +static void __init intcp_init_irq(void) +{ +	u32 pic_mask, cic_mask, sic_mask; + +	/* These masks are for the HW IRQ registers */ +	pic_mask = ~((~0u) << (11 - IRQ_PIC_START)); +	pic_mask |= (~((~0u) << (29 - 22))) << 22; +	cic_mask = ~((~0u) << (1 + IRQ_CIC_END - IRQ_CIC_START)); +	sic_mask = ~((~0u) << (1 + IRQ_SIC_END - IRQ_SIC_START)); + +	/* +	 * Disable all interrupt sources +	 */ +	writel(0xffffffff, INTCP_VA_PIC_BASE + IRQ_ENABLE_CLEAR); +	writel(0xffffffff, INTCP_VA_PIC_BASE + FIQ_ENABLE_CLEAR); +	writel(0xffffffff, INTCP_VA_CIC_BASE + IRQ_ENABLE_CLEAR); +	writel(0xffffffff, INTCP_VA_CIC_BASE + FIQ_ENABLE_CLEAR); +	writel(sic_mask, INTCP_VA_SIC_BASE + IRQ_ENABLE_CLEAR); +	writel(sic_mask, INTCP_VA_SIC_BASE + FIQ_ENABLE_CLEAR); + +	fpga_irq_init(INTCP_VA_PIC_BASE, "PIC", IRQ_PIC_START, +		      -1, pic_mask, NULL); + +	fpga_irq_init(INTCP_VA_CIC_BASE, "CIC", IRQ_CIC_START, +		      -1, cic_mask, NULL); + +	fpga_irq_init(INTCP_VA_SIC_BASE, "SIC", IRQ_SIC_START, +		      IRQ_CP_CPPLDINT, sic_mask, NULL); + +	integrator_clk_init(true);  }  #define TIMER0_VA_BASE __io_address(INTEGRATOR_TIMER0_BASE) @@ -386,6 +468,37 @@ static struct sys_timer cp_timer = {  	.init		= intcp_timer_init,  }; +#define INTEGRATOR_CP_MMC_IRQS	{ IRQ_CP_MMCIINT0, IRQ_CP_MMCIINT1 } +#define INTEGRATOR_CP_AACI_IRQS	{ IRQ_CP_AACIINT } + +static AMBA_APB_DEVICE(mmc, "mmci", 0, INTEGRATOR_CP_MMC_BASE, +	INTEGRATOR_CP_MMC_IRQS, &mmc_data); + +static AMBA_APB_DEVICE(aaci, "aaci", 0, INTEGRATOR_CP_AACI_BASE, +	INTEGRATOR_CP_AACI_IRQS, NULL); + +static AMBA_AHB_DEVICE(clcd, "clcd", 0, INTCP_PA_CLCD_BASE, +	{ IRQ_CP_CLCDCINT }, &clcd_data); + +static struct amba_device *amba_devs[] __initdata = { +	&mmc_device, +	&aaci_device, +	&clcd_device, +}; + +static void __init intcp_init(void) +{ +	int i; + +	platform_add_devices(intcp_devs, ARRAY_SIZE(intcp_devs)); + +	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { +		struct amba_device *d = amba_devs[i]; +		amba_device_register(d, &iomem_resource); +	} +	integrator_init(true); +} +  MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")  	/* Maintainer: ARM Ltd/Deep Blue Solutions Ltd */  	.atag_offset	= 0x100, @@ -399,3 +512,5 @@ MACHINE_START(CINTEGRATOR, "ARM-IntegratorCP")  	.init_machine	= intcp_init,  	.restart	= integrator_restart,  MACHINE_END + +#endif diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c index 8dabfe81d07..ff886e01a0b 100644 --- a/arch/arm/mach-mxs/mach-mxs.c +++ b/arch/arm/mach-mxs/mach-mxs.c @@ -261,7 +261,7 @@ static void __init apx4devkit_init(void)  	enable_clk_enet_out();  	if (IS_BUILTIN(CONFIG_PHYLIB)) -		phy_register_fixup_for_uid(PHY_ID_KS8051, MICREL_PHY_ID_MASK, +		phy_register_fixup_for_uid(PHY_ID_KSZ8051, MICREL_PHY_ID_MASK,  					   apx4devkit_phy_fixup);  	mxsfb_pdata.mode_list = apx4devkit_video_modes; diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index fcd4e85c4dd..346fd26f3aa 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -232,10 +232,11 @@ config MACH_OMAP3_PANDORA  	select OMAP_PACKAGE_CBB  	select REGULATOR_FIXED_VOLTAGE if REGULATOR -config MACH_OMAP3_TOUCHBOOK +config MACH_TOUCHBOOK  	bool "OMAP3 Touch Book"  	depends on ARCH_OMAP3  	default y +	select OMAP_PACKAGE_CBB  config MACH_OMAP_3430SDP  	bool "OMAP 3430 SDP board" diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index f6a24b3f9c4..34c2c7f59f0 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -255,7 +255,7 @@ obj-$(CONFIG_MACH_OMAP_3630SDP)		+= board-zoom-display.o  obj-$(CONFIG_MACH_CM_T35)		+= board-cm-t35.o  obj-$(CONFIG_MACH_CM_T3517)		+= board-cm-t3517.o  obj-$(CONFIG_MACH_IGEP0020)		+= board-igep0020.o -obj-$(CONFIG_MACH_OMAP3_TOUCHBOOK)	+= board-omap3touchbook.o +obj-$(CONFIG_MACH_TOUCHBOOK)		+= board-omap3touchbook.o  obj-$(CONFIG_MACH_OMAP_4430SDP)		+= board-4430sdp.o  obj-$(CONFIG_MACH_OMAP4_PANDA)		+= board-omap4panda.o diff --git a/arch/arm/mach-omap2/clock33xx_data.c b/arch/arm/mach-omap2/clock33xx_data.c index 25bbcc7ca4d..ae27de8899a 100644 --- a/arch/arm/mach-omap2/clock33xx_data.c +++ b/arch/arm/mach-omap2/clock33xx_data.c @@ -1036,13 +1036,13 @@ static struct omap_clk am33xx_clks[] = {  	CLK(NULL,	"mmu_fck",		&mmu_fck,	CK_AM33XX),  	CLK(NULL,	"smartreflex0_fck",	&smartreflex0_fck,	CK_AM33XX),  	CLK(NULL,	"smartreflex1_fck",	&smartreflex1_fck,	CK_AM33XX), -	CLK(NULL,	"gpt1_fck",		&timer1_fck,	CK_AM33XX), -	CLK(NULL,	"gpt2_fck",		&timer2_fck,	CK_AM33XX), -	CLK(NULL,	"gpt3_fck",		&timer3_fck,	CK_AM33XX), -	CLK(NULL,	"gpt4_fck",		&timer4_fck,	CK_AM33XX), -	CLK(NULL,	"gpt5_fck",		&timer5_fck,	CK_AM33XX), -	CLK(NULL,	"gpt6_fck",		&timer6_fck,	CK_AM33XX), -	CLK(NULL,	"gpt7_fck",		&timer7_fck,	CK_AM33XX), +	CLK(NULL,	"timer1_fck",		&timer1_fck,	CK_AM33XX), +	CLK(NULL,	"timer2_fck",		&timer2_fck,	CK_AM33XX), +	CLK(NULL,	"timer3_fck",		&timer3_fck,	CK_AM33XX), +	CLK(NULL,	"timer4_fck",		&timer4_fck,	CK_AM33XX), +	CLK(NULL,	"timer5_fck",		&timer5_fck,	CK_AM33XX), +	CLK(NULL,	"timer6_fck",		&timer6_fck,	CK_AM33XX), +	CLK(NULL,	"timer7_fck",		&timer7_fck,	CK_AM33XX),  	CLK(NULL,	"usbotg_fck",		&usbotg_fck,	CK_AM33XX),  	CLK(NULL,	"ieee5000_fck",		&ieee5000_fck,	CK_AM33XX),  	CLK(NULL,	"wdt1_fck",		&wdt1_fck,	CK_AM33XX), diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c index a0d68dbecfa..f99e65cfb86 100644 --- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c +++ b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c @@ -241,6 +241,52 @@ static void omap3_clkdm_deny_idle(struct clockdomain *clkdm)  		_clkdm_del_autodeps(clkdm);  } +static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm) +{ +	bool hwsup = false; + +	if (!clkdm->clktrctrl_mask) +		return 0; + +	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, +				clkdm->clktrctrl_mask); + +	if (hwsup) { +		/* Disable HW transitions when we are changing deps */ +		_disable_hwsup(clkdm); +		_clkdm_add_autodeps(clkdm); +		_enable_hwsup(clkdm); +	} else { +		if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) +			omap3_clkdm_wakeup(clkdm); +	} + +	return 0; +} + +static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm) +{ +	bool hwsup = false; + +	if (!clkdm->clktrctrl_mask) +		return 0; + +	hwsup = omap2_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, +				clkdm->clktrctrl_mask); + +	if (hwsup) { +		/* Disable HW transitions when we are changing deps */ +		_disable_hwsup(clkdm); +		_clkdm_del_autodeps(clkdm); +		_enable_hwsup(clkdm); +	} else { +		if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP) +			omap3_clkdm_sleep(clkdm); +	} + +	return 0; +} +  struct clkdm_ops omap2_clkdm_operations = {  	.clkdm_add_wkdep	= omap2_clkdm_add_wkdep,  	.clkdm_del_wkdep	= omap2_clkdm_del_wkdep, @@ -267,6 +313,6 @@ struct clkdm_ops omap3_clkdm_operations = {  	.clkdm_wakeup		= omap3_clkdm_wakeup,  	.clkdm_allow_idle	= omap3_clkdm_allow_idle,  	.clkdm_deny_idle	= omap3_clkdm_deny_idle, -	.clkdm_clk_enable	= omap2_clkdm_clk_enable, -	.clkdm_clk_disable	= omap2_clkdm_clk_disable, +	.clkdm_clk_enable	= omap3xxx_clkdm_clk_enable, +	.clkdm_clk_disable	= omap3xxx_clkdm_clk_disable,  }; diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h index 766338fe4d3..975f6bda0e0 100644 --- a/arch/arm/mach-omap2/cm-regbits-34xx.h +++ b/arch/arm/mach-omap2/cm-regbits-34xx.h @@ -67,6 +67,7 @@  #define OMAP3430_EN_IVA2_DPLL_MASK			(0x7 << 0)  /* CM_IDLEST_IVA2 */ +#define OMAP3430_ST_IVA2_SHIFT				0  #define OMAP3430_ST_IVA2_MASK				(1 << 0)  /* CM_IDLEST_PLL_IVA2 */ diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index 05fdebfaa19..330d4c6e746 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -46,7 +46,7 @@  static void __iomem *wakeupgen_base;  static void __iomem *sar_base;  static DEFINE_SPINLOCK(wakeupgen_lock); -static unsigned int irq_target_cpu[NR_IRQS]; +static unsigned int irq_target_cpu[MAX_IRQS];  static unsigned int irq_banks = MAX_NR_REG_BANKS;  static unsigned int max_irqs = MAX_IRQS;  static unsigned int omap_secure_apis; diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 6ca8e519968..37afbd173c2 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -1889,6 +1889,7 @@ static int _enable(struct omap_hwmod *oh)  			_enable_sysc(oh);  		}  	} else { +		_omap4_disable_module(oh);  		_disable_clocks(oh);  		pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n",  			 oh->name, r); diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index c9e38200216..ce7e6068768 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -100,9 +100,9 @@ static struct omap_hwmod omap3xxx_mpu_hwmod = {  /* IVA2 (IVA2) */  static struct omap_hwmod_rst_info omap3xxx_iva_resets[] = { -	{ .name = "logic", .rst_shift = 0 }, -	{ .name = "seq0", .rst_shift = 1 }, -	{ .name = "seq1", .rst_shift = 2 }, +	{ .name = "logic", .rst_shift = 0, .st_shift = 8 }, +	{ .name = "seq0", .rst_shift = 1, .st_shift = 9 }, +	{ .name = "seq1", .rst_shift = 2, .st_shift = 10 },  };  static struct omap_hwmod omap3xxx_iva_hwmod = { @@ -112,6 +112,15 @@ static struct omap_hwmod omap3xxx_iva_hwmod = {  	.rst_lines	= omap3xxx_iva_resets,  	.rst_lines_cnt	= ARRAY_SIZE(omap3xxx_iva_resets),  	.main_clk	= "iva2_ck", +	.prcm = { +		.omap2 = { +			.module_offs = OMAP3430_IVA2_MOD, +			.prcm_reg_id = 1, +			.module_bit = OMAP3430_CM_FCLKEN_IVA2_EN_IVA2_SHIFT, +			.idlest_reg_id = 1, +			.idlest_idle_bit = OMAP3430_ST_IVA2_SHIFT, +		} +	},  };  /* timer class */ diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 242aee498ce..afb60917a94 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -4210,7 +4210,7 @@ static struct omap_hwmod_ocp_if omap44xx_dsp__iva = {  };  /* dsp -> sl2if */ -static struct omap_hwmod_ocp_if omap44xx_dsp__sl2if = { +static struct omap_hwmod_ocp_if __maybe_unused omap44xx_dsp__sl2if = {  	.master		= &omap44xx_dsp_hwmod,  	.slave		= &omap44xx_sl2if_hwmod,  	.clk		= "dpll_iva_m5x2_ck", @@ -4828,7 +4828,7 @@ static struct omap_hwmod_ocp_if omap44xx_l3_main_2__iss = {  };  /* iva -> sl2if */ -static struct omap_hwmod_ocp_if omap44xx_iva__sl2if = { +static struct omap_hwmod_ocp_if __maybe_unused omap44xx_iva__sl2if = {  	.master		= &omap44xx_iva_hwmod,  	.slave		= &omap44xx_sl2if_hwmod,  	.clk		= "dpll_iva_m5x2_ck", @@ -5362,7 +5362,7 @@ static struct omap_hwmod_ocp_if omap44xx_l4_wkup__scrm = {  };  /* l3_main_2 -> sl2if */ -static struct omap_hwmod_ocp_if omap44xx_l3_main_2__sl2if = { +static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l3_main_2__sl2if = {  	.master		= &omap44xx_l3_main_2_hwmod,  	.slave		= &omap44xx_sl2if_hwmod,  	.clk		= "l3_div_ck", @@ -6032,7 +6032,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {  	&omap44xx_l4_abe__dmic,  	&omap44xx_l4_abe__dmic_dma,  	&omap44xx_dsp__iva, -	&omap44xx_dsp__sl2if, +	/* &omap44xx_dsp__sl2if, */  	&omap44xx_l4_cfg__dsp,  	&omap44xx_l3_main_2__dss,  	&omap44xx_l4_per__dss, @@ -6068,7 +6068,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {  	&omap44xx_l4_per__i2c4,  	&omap44xx_l3_main_2__ipu,  	&omap44xx_l3_main_2__iss, -	&omap44xx_iva__sl2if, +	/* &omap44xx_iva__sl2if, */  	&omap44xx_l3_main_2__iva,  	&omap44xx_l4_wkup__kbd,  	&omap44xx_l4_cfg__mailbox, @@ -6099,7 +6099,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {  	&omap44xx_l4_cfg__cm_core,  	&omap44xx_l4_wkup__prm,  	&omap44xx_l4_wkup__scrm, -	&omap44xx_l3_main_2__sl2if, +	/* &omap44xx_l3_main_2__sl2if, */  	&omap44xx_l4_abe__slimbus1,  	&omap44xx_l4_abe__slimbus1_dma,  	&omap44xx_l4_per__slimbus2, diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 2ff6d41ec6c..2ba4f57dda8 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -260,6 +260,7 @@ static u32 notrace dmtimer_read_sched_clock(void)  	return 0;  } +#ifdef CONFIG_OMAP_32K_TIMER  /* Setup free-running counter for clocksource */  static int __init omap2_sync32k_clocksource_init(void)  { @@ -299,6 +300,12 @@ static int __init omap2_sync32k_clocksource_init(void)  	return ret;  } +#else +static inline int omap2_sync32k_clocksource_init(void) +{ +	return -ENODEV; +} +#endif  static void __init omap2_gptimer_clocksource_init(int gptimer_id,  						const char *fck_source) diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c index 410291c6766..a6cd14ab1e4 100644 --- a/arch/arm/mach-orion5x/common.c +++ b/arch/arm/mach-orion5x/common.c @@ -204,6 +204,13 @@ void __init orion5x_wdt_init(void)  void __init orion5x_init_early(void)  {  	orion_time_set_base(TIMER_VIRT_BASE); + +	/* +	 * Some Orion5x devices allocate their coherent buffers from atomic +	 * context. Increase size of atomic coherent pool to make sure such +	 * the allocations won't fail. +	 */ +	init_dma_coherent_pool_size(SZ_1M);  }  int orion5x_tclk; diff --git a/arch/arm/mach-sa1100/include/mach/SA-1111.h b/arch/arm/mach-sa1100/include/mach/SA-1111.h deleted file mode 100644 index c38f60915cb..00000000000 --- a/arch/arm/mach-sa1100/include/mach/SA-1111.h +++ /dev/null @@ -1,5 +0,0 @@ -/* - * Moved to new location - */ -#warning using old SA-1111.h - update to <asm/hardware/sa1111.h> -#include <asm/hardware/sa1111.h> diff --git a/arch/arm/mach-sa1100/include/mach/lart.h b/arch/arm/mach-sa1100/include/mach/lart.h deleted file mode 100644 index 8a5482d908d..00000000000 --- a/arch/arm/mach-sa1100/include/mach/lart.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _INCLUDE_LART_H -#define _INCLUDE_LART_H - -#define LART_GPIO_ETH0			GPIO_GPIO0 -#define LART_IRQ_ETH0			IRQ_GPIO0 - -#define LART_GPIO_IDE			GPIO_GPIO1 -#define LART_IRQ_IDE			IRQ_GPIO1 - -#define LART_GPIO_UCB1200		GPIO_GPIO18 -#define LART_IRQ_UCB1200		IRQ_GPIO18 - -#endif diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c index 53b7ea92c32..3b8a0171c3c 100644 --- a/arch/arm/mach-shmobile/board-kzm9g.c +++ b/arch/arm/mach-shmobile/board-kzm9g.c @@ -346,11 +346,11 @@ static struct resource sh_mmcif_resources[] = {  		.flags	= IORESOURCE_MEM,  	},  	[1] = { -		.start	= gic_spi(141), +		.start	= gic_spi(140),  		.flags	= IORESOURCE_IRQ,  	},  	[2] = { -		.start	= gic_spi(140), +		.start	= gic_spi(141),  		.flags	= IORESOURCE_IRQ,  	},  }; diff --git a/arch/arm/mach-shmobile/smp-emev2.c b/arch/arm/mach-shmobile/smp-emev2.c index 6a35c4a31e6..030558f474a 100644 --- a/arch/arm/mach-shmobile/smp-emev2.c +++ b/arch/arm/mach-shmobile/smp-emev2.c @@ -82,7 +82,7 @@ int __cpuinit emev2_boot_secondary(unsigned int cpu)  	/* Tell ROM loader about our vector (in headsmp.S) */  	emev2_set_boot_vector(__pa(shmobile_secondary_vector)); -	gic_raise_softirq(cpumask_of(cpu), 1); +	gic_raise_softirq(cpumask_of(cpu), 0);  	return 0;  } diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index 9107231aacc..b9f60ebe3bc 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -699,7 +699,6 @@ do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs,  	unsigned long instr = *pinstr;  	u16 tinst1 = (instr >> 16) & 0xffff;  	u16 tinst2 = instr & 0xffff; -	poffset->un = 0;  	switch (tinst1 & 0xffe0) {  	/* A6.3.5 Load/Store multiple */ @@ -854,9 +853,10 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)  		break;  	case 0x08000000:	/* ldm or stm, or thumb-2 32bit instruction */ -		if (thumb2_32b) +		if (thumb2_32b) { +			offset.un = 0;  			handler = do_alignment_t32_to_handler(&instr, regs, &offset); -		else +		} else  			handler = do_alignment_ldmstm;  		break; diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index 39e3fb3db80..3b172275262 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S @@ -211,6 +211,9 @@ ENTRY(v7_coherent_user_range)   * isn't mapped, fail with -EFAULT.   */  9001: +#ifdef CONFIG_ARM_ERRATA_775420 +	dsb +#endif  	mov	r0, #-EFAULT  	mov	pc, lr   UNWIND(.fnend		) diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c index 119bc52ab93..4e07eec1270 100644 --- a/arch/arm/mm/context.c +++ b/arch/arm/mm/context.c @@ -63,10 +63,11 @@ static int contextidr_notifier(struct notifier_block *unused, unsigned long cmd,  	pid = task_pid_nr(thread->task) << ASID_BITS;  	asm volatile(  	"	mrc	p15, 0, %0, c13, c0, 1\n" -	"	bfi	%1, %0, #0, %2\n" -	"	mcr	p15, 0, %1, c13, c0, 1\n" +	"	and	%0, %0, %2\n" +	"	orr	%0, %0, %1\n" +	"	mcr	p15, 0, %0, c13, c0, 1\n"  	: "=r" (contextidr), "+r" (pid) -	: "I" (ASID_BITS)); +	: "I" (~ASID_MASK));  	isb();  	return NOTIFY_OK; diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 051204fc461..13f555d6249 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -346,6 +346,8 @@ static int __init atomic_pool_init(void)  		       (unsigned)pool->size / 1024);  		return 0;  	} + +	kfree(pages);  no_pages:  	kfree(bitmap);  no_bitmap: @@ -489,7 +491,7 @@ static bool __in_atomic_pool(void *start, size_t size)  	void *pool_start = pool->vaddr;  	void *pool_end = pool->vaddr + pool->size; -	if (start < pool_start || start > pool_end) +	if (start < pool_start || start >= pool_end)  		return false;  	if (end <= pool_end) diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index 9aec41fa80a..ad722f1208a 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c @@ -324,7 +324,7 @@ phys_addr_t __init arm_memblock_steal(phys_addr_t size, phys_addr_t align)  	BUG_ON(!arm_memblock_steal_permitted); -	phys = memblock_alloc(size, align); +	phys = memblock_alloc_base(size, align, MEMBLOCK_ALLOC_ANYWHERE);  	memblock_free(phys, size);  	memblock_remove(phys, size); diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index 566750fa57d..491f6b3336f 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c @@ -247,6 +247,7 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn,   	if (!area)   		return NULL;   	addr = (unsigned long)area->addr; +	area->phys_addr = __pfn_to_phys(pfn);  #if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE)  	if (DOMAIN_IO == 0 && diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index 6776160618e..a8ee92da354 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h @@ -55,6 +55,9 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page  /* permanent static mappings from iotable_init() */  #define VM_ARM_STATIC_MAPPING	0x40000000 +/* empty mapping */ +#define VM_ARM_EMPTY_MAPPING	0x20000000 +  /* mapping type (attributes) for permanent static mappings */  #define VM_ARM_MTYPE(mt)		((mt) << 20)  #define VM_ARM_MTYPE_MASK	(0x1f << 20) diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 4c2d0451e84..c2fa21d0103 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c @@ -807,7 +807,7 @@ static void __init pmd_empty_section_gap(unsigned long addr)  	vm = early_alloc_aligned(sizeof(*vm), __alignof__(*vm));  	vm->addr = (void *)addr;  	vm->size = SECTION_SIZE; -	vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING; +	vm->flags = VM_IOREMAP | VM_ARM_EMPTY_MAPPING;  	vm->caller = pmd_empty_section_gap;  	vm_area_add_early(vm);  } @@ -820,7 +820,7 @@ static void __init fill_pmd_gaps(void)  	/* we're still single threaded hence no lock needed here */  	for (vm = vmlist; vm; vm = vm->next) { -		if (!(vm->flags & VM_ARM_STATIC_MAPPING)) +		if (!(vm->flags & (VM_ARM_STATIC_MAPPING | VM_ARM_EMPTY_MAPPING)))  			continue;  		addr = (unsigned long)vm->addr;  		if (addr < next) @@ -961,8 +961,8 @@ void __init sanity_check_meminfo(void)  		 * Check whether this memory bank would partially overlap  		 * the vmalloc area.  		 */ -		if (__va(bank->start + bank->size) > vmalloc_min || -		    __va(bank->start + bank->size) < __va(bank->start)) { +		if (__va(bank->start + bank->size - 1) >= vmalloc_min || +		    __va(bank->start + bank->size - 1) <= __va(bank->start)) {  			unsigned long newsize = vmalloc_min - __va(bank->start);  			printk(KERN_NOTICE "Truncating RAM at %.8llx-%.8llx "  			       "to -%.8llx (vmalloc region overlap).\n", diff --git a/arch/arm/plat-mxc/include/mach/mx25.h b/arch/arm/plat-mxc/include/mach/mx25.h index 627d94f1b01..ec466400a20 100644 --- a/arch/arm/plat-mxc/include/mach/mx25.h +++ b/arch/arm/plat-mxc/include/mach/mx25.h @@ -98,6 +98,7 @@  #define MX25_INT_UART1		(NR_IRQS_LEGACY + 45)  #define MX25_INT_GPIO2		(NR_IRQS_LEGACY + 51)  #define MX25_INT_GPIO1		(NR_IRQS_LEGACY + 52) +#define MX25_INT_GPT1		(NR_IRQS_LEGACY + 54)  #define MX25_INT_FEC		(NR_IRQS_LEGACY + 57)  #define MX25_DMA_REQ_SSI2_RX1	22 diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 766181cb5c9..024f3b08db2 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c @@ -68,6 +68,7 @@  static unsigned long omap_sram_start;  static void __iomem *omap_sram_base; +static unsigned long omap_sram_skip;  static unsigned long omap_sram_size;  static void __iomem *omap_sram_ceil; @@ -106,6 +107,7 @@ static int is_sram_locked(void)   */  static void __init omap_detect_sram(void)  { +	omap_sram_skip = SRAM_BOOTLOADER_SZ;  	if (cpu_class_is_omap2()) {  		if (is_sram_locked()) {  			if (cpu_is_omap34xx()) { @@ -113,6 +115,7 @@ static void __init omap_detect_sram(void)  				if ((omap_type() == OMAP2_DEVICE_TYPE_EMU) ||  				    (omap_type() == OMAP2_DEVICE_TYPE_SEC)) {  					omap_sram_size = 0x7000; /* 28K */ +					omap_sram_skip += SZ_16K;  				} else {  					omap_sram_size = 0x8000; /* 32K */  				} @@ -175,8 +178,10 @@ static void __init omap_map_sram(void)  		return;  #ifdef CONFIG_OMAP4_ERRATA_I688 +	if (cpu_is_omap44xx()) {  		omap_sram_start += PAGE_SIZE;  		omap_sram_size -= SZ_16K; +	}  #endif  	if (cpu_is_omap34xx()) {  		/* @@ -203,8 +208,8 @@ static void __init omap_map_sram(void)  	 * Looks like we need to preserve some bootloader code at the  	 * beginning of SRAM for jumping to flash for reboot to work...  	 */ -	memset_io(omap_sram_base + SRAM_BOOTLOADER_SZ, 0, -		  omap_sram_size - SRAM_BOOTLOADER_SZ); +	memset_io(omap_sram_base + omap_sram_skip, 0, +		  omap_sram_size - omap_sram_skip);  }  /* @@ -218,7 +223,7 @@ void *omap_sram_push_address(unsigned long size)  {  	unsigned long available, new_ceil = (unsigned long)omap_sram_ceil; -	available = omap_sram_ceil - (omap_sram_base + SRAM_BOOTLOADER_SZ); +	available = omap_sram_ceil - (omap_sram_base + omap_sram_skip);  	if (size > available) {  		pr_err("Not enough space in SRAM\n"); diff --git a/arch/arm/plat-samsung/clock.c b/arch/arm/plat-samsung/clock.c index 65c5eca475e..d1116e2dfbe 100644 --- a/arch/arm/plat-samsung/clock.c +++ b/arch/arm/plat-samsung/clock.c @@ -144,6 +144,7 @@ long clk_round_rate(struct clk *clk, unsigned long rate)  int clk_set_rate(struct clk *clk, unsigned long rate)  { +	unsigned long flags;  	int ret;  	if (IS_ERR(clk)) @@ -159,9 +160,9 @@ int clk_set_rate(struct clk *clk, unsigned long rate)  	if (clk->ops == NULL || clk->ops->set_rate == NULL)  		return -EINVAL; -	spin_lock(&clocks_lock); +	spin_lock_irqsave(&clocks_lock, flags);  	ret = (clk->ops->set_rate)(clk, rate); -	spin_unlock(&clocks_lock); +	spin_unlock_irqrestore(&clocks_lock, flags);  	return ret;  } @@ -173,17 +174,18 @@ struct clk *clk_get_parent(struct clk *clk)  int clk_set_parent(struct clk *clk, struct clk *parent)  { +	unsigned long flags;  	int ret = 0;  	if (IS_ERR(clk))  		return -EINVAL; -	spin_lock(&clocks_lock); +	spin_lock_irqsave(&clocks_lock, flags);  	if (clk->ops && clk->ops->set_parent)  		ret = (clk->ops->set_parent)(clk, parent); -	spin_unlock(&clocks_lock); +	spin_unlock_irqrestore(&clocks_lock, flags);  	return ret;  } diff --git a/arch/arm/plat-versatile/fpga-irq.c b/arch/arm/plat-versatile/fpga-irq.c index 6e70d03824a..091ae103004 100644 --- a/arch/arm/plat-versatile/fpga-irq.c +++ b/arch/arm/plat-versatile/fpga-irq.c @@ -5,6 +5,8 @@  #include <linux/io.h>  #include <linux/irqdomain.h>  #include <linux/module.h> +#include <linux/of.h> +#include <linux/of_address.h>  #include <asm/exception.h>  #include <asm/mach/irq.h> @@ -14,11 +16,17 @@  #define IRQ_RAW_STATUS		0x04  #define IRQ_ENABLE_SET		0x08  #define IRQ_ENABLE_CLEAR	0x0c +#define INT_SOFT_SET		0x10 +#define INT_SOFT_CLEAR		0x14 +#define FIQ_STATUS		0x20 +#define FIQ_RAW_STATUS		0x24 +#define FIQ_ENABLE		0x28 +#define FIQ_ENABLE_SET		0x28 +#define FIQ_ENABLE_CLEAR	0x2C  /**   * struct fpga_irq_data - irq data container for the FPGA IRQ controller   * @base: memory offset in virtual memory - * @irq_start: first IRQ number handled by this instance   * @chip: chip container for this instance   * @domain: IRQ domain for this instance   * @valid: mask for valid IRQs on this controller @@ -26,7 +34,6 @@   */  struct fpga_irq_data {  	void __iomem *base; -	unsigned int irq_start;  	struct irq_chip chip;  	u32 valid;  	struct irq_domain *domain; @@ -125,34 +132,79 @@ static struct irq_domain_ops fpga_irqdomain_ops = {  	.xlate = irq_domain_xlate_onetwocell,  }; -void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start, -			  int parent_irq, u32 valid, struct device_node *node) -{ +static __init struct fpga_irq_data * +fpga_irq_prep_struct(void __iomem *base, const char *name, u32 valid) {  	struct fpga_irq_data *f;  	if (fpga_irq_id >= ARRAY_SIZE(fpga_irq_devices)) {  		printk(KERN_ERR "%s: too few FPGA IRQ controllers, increase CONFIG_PLAT_VERSATILE_FPGA_IRQ_NR\n", __func__); -		return; +		return NULL;  	} -  	f = &fpga_irq_devices[fpga_irq_id];  	f->base = base; -	f->irq_start = irq_start;  	f->chip.name = name;  	f->chip.irq_ack = fpga_irq_mask;  	f->chip.irq_mask = fpga_irq_mask;  	f->chip.irq_unmask = fpga_irq_unmask;  	f->valid = valid; +	fpga_irq_id++; + +	return f; +} + +void __init fpga_irq_init(void __iomem *base, const char *name, int irq_start, +			  int parent_irq, u32 valid, struct device_node *node) +{ +	struct fpga_irq_data *f; + +	f = fpga_irq_prep_struct(base, name, valid); +	if (!f) +		return;  	if (parent_irq != -1) {  		irq_set_handler_data(parent_irq, f);  		irq_set_chained_handler(parent_irq, fpga_irq_handle);  	} -	f->domain = irq_domain_add_legacy(node, fls(valid), f->irq_start, 0, +	f->domain = irq_domain_add_legacy(node, fls(valid), irq_start, 0,  					  &fpga_irqdomain_ops, f);  	pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n",  		fpga_irq_id, name, base, f->used_irqs); +} -	fpga_irq_id++; +#ifdef CONFIG_OF +int __init fpga_irq_of_init(struct device_node *node, +			    struct device_node *parent) +{ +	struct fpga_irq_data *f; +	void __iomem *base; +	u32 clear_mask; +	u32 valid_mask; + +	if (WARN_ON(!node)) +		return -ENODEV; + +	base = of_iomap(node, 0); +	WARN(!base, "unable to map fpga irq registers\n"); + +	if (of_property_read_u32(node, "clear-mask", &clear_mask)) +		clear_mask = 0; + +	if (of_property_read_u32(node, "valid-mask", &valid_mask)) +		valid_mask = 0; + +	f = fpga_irq_prep_struct(base, node->name, valid_mask); +	if (!f) +		return -ENOMEM; + +	writel(clear_mask, base + IRQ_ENABLE_CLEAR); +	writel(clear_mask, base + FIQ_ENABLE_CLEAR); + +	f->domain = irq_domain_add_linear(node, fls(valid_mask), &fpga_irqdomain_ops, f); +	f->used_irqs = hweight32(valid_mask); + +	pr_info("FPGA IRQ chip %d \"%s\" @ %p, %u irqs\n", +		fpga_irq_id, node->name, base, f->used_irqs); +	return 0;  } +#endif diff --git a/arch/arm/plat-versatile/include/plat/fpga-irq.h b/arch/arm/plat-versatile/include/plat/fpga-irq.h index 91bcfb67551..1fac9651d3c 100644 --- a/arch/arm/plat-versatile/include/plat/fpga-irq.h +++ b/arch/arm/plat-versatile/include/plat/fpga-irq.h @@ -7,5 +7,7 @@ struct pt_regs;  void fpga_handle_irq(struct pt_regs *regs);  void fpga_irq_init(void __iomem *, const char *, int, int, u32,  		struct device_node *node); +int fpga_irq_of_init(struct device_node *node, +		     struct device_node *parent);  #endif  |